From 46c47d4677a1eb17828ea121e0e97e90eee34639 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 1 Mar 2011 18:42:07 +0000 Subject: [PATCH 0001/1484] Add the experimental sqlite3_preupdate_hook() API. FossilOrigin-Name: 6145d7b89f83500318713779c60f79a7ab2098ba --- install-sh | 0 manifest | 57 +++++----- manifest.uuid | 2 +- src/delete.c | 13 ++- src/insert.c | 14 ++- src/main.c | 19 ++++ src/sqlite.h.in | 24 ++++ src/sqliteInt.h | 7 ++ src/tclsqlite.c | 184 +++++++++++++++++++++++++----- src/update.c | 13 ++- src/vdbe.c | 90 ++++++++++----- src/vdbeInt.h | 13 +++ src/vdbeapi.c | 115 ++++++++++++++++--- src/vdbeaux.c | 34 +++++- test/hook.test | 267 ++++++++++++++++++++++++++++++++++++++++++++ test/progress.test | 0 test/tclsqlite.test | 2 +- tool/mkopts.tcl | 0 18 files changed, 737 insertions(+), 117 deletions(-) mode change 100755 => 100644 install-sh mode change 100644 => 100755 test/progress.test mode change 100644 => 100755 tool/mkopts.tcl diff --git a/install-sh b/install-sh old mode 100755 new mode 100644 diff --git a/manifest b/manifest index 1d2716b2db..2608f60580 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,5 @@ ------BEGIN PGP SIGNED MESSAGE----- -Hash: SHA1 - -C Comment\sout\ssome\scode\sin\sos_unix.c\sthat\sonly\sruns\son\sMacOSX\swith\nSQLITE_ENABLE_LOCKING_STYLE. -D 2011-02-25T03:25:07.454 +C Add\sthe\sexperimental\ssqlite3_preupdate_hook()\sAPI. +D 2011-03-01T18:42:07 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -101,7 +98,7 @@ F ext/rtree/rtree_util.tcl 06aab2ed5b826545bf215fff90ecb9255a8647ea F ext/rtree/sqlite3rtree.h 1af0899c63a688e272d69d8e746f24e76f10a3f0 F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 -F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x +F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F main.mk 54190fab7cdba523e311c274c95ea480f32abfb5 F mkdll.sh 7d09b23c05d56532e9d44a50868eb4b12ff4f74a @@ -131,7 +128,7 @@ F src/callback.c a1d1b1c9c85415dff013af033e2fed9c8382d33b F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 7deec4534f3b5a0c3b4a4cbadf809d321f64f9c4 F src/date.c 1548fdac51377e4e7833251de878b4058c148e1b -F src/delete.c 7ed8a8c8b5f748ece92df173d7e0f7810c899ebd +F src/delete.c 3c0925e958a77804a004222baa1a2a8ad855306b F src/expr.c 8e2c607b3be87a35c75a1f5dac50c10666b083c0 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 17950a28f28b23e8ad3feaac5fc88c324d2f600a @@ -140,12 +137,12 @@ F src/global.c 02335177cf6946fe5525c6f0755cf181140debf3 F src/hash.c 458488dcc159c301b8e7686280ab209f1fb915af F src/hash.h 2894c932d84d9f892d4b4023a75e501f83050970 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 -F src/insert.c a4995747c062256582a90b4f87f716e11b067050 +F src/insert.c c56a64b1488921794c3855d54acfe4674c7cea0c F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f F src/lempar.c 7f026423f4d71d989e719a743f98a1cbd4e6d99e F src/loadext.c 8af9fcc75708d60b88636ccba38b4a7b3c155c3e -F src/main.c 93d0d967d6898fc0408ece248342342e312aa753 +F src/main.c 9ab948225b8c362cdd6902c447abbf218607e0f3 F src/malloc.c 92d59a007d7a42857d4e9454aa25b6b703286be1 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 00bd8265c81abb665c48fea1e0c234eb3b922206 @@ -180,13 +177,13 @@ F src/resolve.c 1c0f32b64f8e3f555fe1f732f9d6f501a7f05706 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 F src/select.c d24406c45dd2442eb2eeaac413439066b149c944 F src/shell.c 649c51979812f77f97507024a4cea480c6862b8b -F src/sqlite.h.in ccb23cc9378874c7c72682b739f311474a80848d +F src/sqlite.h.in 3a8a9f25a45735879cec195a2c129b48e34ebf8e F src/sqlite3ext.h c90bd5507099f62043832d73f6425d8d5c5da754 -F src/sqliteInt.h 4290fff17fabc6e07fc4338233df0e39e6350ca1 +F src/sqliteInt.h 3a262a299fa5b1f6916157ec2302e8987e50bac9 F src/sqliteLimit.h a17dcd3fb775d63b64a43a55c54cb282f9726f44 F src/status.c 4997380fbb915426fef9e500b4872e79c99267fc F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e -F src/tclsqlite.c 879bf8a23d99fc0e99d9177fe1b48896bc796d65 +F src/tclsqlite.c 20a3bf120f3bba1914f0e5132dbe937dee135f36 F src/test1.c 9020310c7617234b33fd1c3064f89524db25f290 F src/test2.c 80d323d11e909cf0eb1b6fbb4ac22276483bcf31 F src/test3.c 056093cfef69ff4227a6bdb9108564dc7f45e4bc @@ -228,15 +225,15 @@ F src/test_vfs.c 2ed8853c1e51ac6f9ea091f7ce4e0d618bba8b86 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/tokenize.c 604607d6813e9551cf5189d899e0a25c12681080 F src/trigger.c b8bedb9c0084ceb51a40f54fcca2ce048c8de852 -F src/update.c 227e6cd512108b84f69421fc6c7aa1b83d60d6e0 +F src/update.c 1b9a82ede7df15e76ed86c6a3cbe4ce0f21eaa9b F src/utf.c 1baeeac91707a4df97ccc6141ec0f808278af685 F src/util.c ab1c92426494f499f42b9e307537b03e923d75c1 F src/vacuum.c 924bd1bcee2dfb05376f79845bd3b4cec7b54b2f -F src/vdbe.c 34305497d81daafdb1e500bfaa21d044c64503de +F src/vdbe.c 4330cc94597b9c95853c5e8ff87776f1e6ceaa3f F src/vdbe.h 4de0efb4b0fdaaa900cf419b35c458933ef1c6d2 -F src/vdbeInt.h 6e6f28e9bccc6c703dca1372fd661c57b5c15fb0 -F src/vdbeapi.c 8e9324fd35eb70d0b5904bd1af40f2598744dc4d -F src/vdbeaux.c 5936a596324ad9f9aba02bdee8c8080d2a3264e1 +F src/vdbeInt.h 41b8e337332f279228196039ab86acd353ad0c6c +F src/vdbeapi.c c407f3f0e21d5de68b1269bfa12315ef7ed6e3fd +F src/vdbeaux.c 874e16966eb6e58183ee2746abb4e4c5238f2350 F src/vdbeblob.c 18955f0ee6b133cd08e1592010cb9a6b11e9984c F src/vdbemem.c 0fa2ed786cd207d5b988afef3562a8e663a75b50 F src/vdbetrace.c 3ba13bc32bdf16d2bdea523245fd16736bed67b5 @@ -474,7 +471,7 @@ F test/fuzz2.test 207d0f9d06db3eaf47a6b7bfc835b8e2fc397167 F test/fuzz3.test aec64345184d1662bd30e6a17851ff659d596dc5 F test/fuzz_common.tcl a87dfbb88c2a6b08a38e9a070dabd129e617b45b F test/fuzz_malloc.test dd7001ac86d09c154a7dff064f4739c60e2b312c -F test/hook.test f04c3412463f8ec117c1c704c74ca0f627ce733a +F test/hook.test 5fd01c30f47896d88bed8a09bf7773cff218e8ff F test/icu.test 70df4faca133254c042d02ae342c0a141f2663f4 F test/in.test 19b642bb134308980a92249750ea4ce3f6c75c2d F test/in2.test 5d4c61d17493c832f7d2d32bef785119e87bde75 @@ -600,7 +597,7 @@ F test/permutations.test 5b2a4cb756ffb2407cb4743163668d1d769febb6 F test/pragma.test fdfc09067ea104a0c247a1a79d8093b56656f850 F test/pragma2.test 5364893491b9231dd170e3459bfc2e2342658b47 F test/printf.test 05970cde31b1a9f54bd75af60597be75a5c54fea -F test/progress.test 5b075c3c790c7b2a61419bc199db87aaf48b8301 +F test/progress.test 5b075c3c790c7b2a61419bc199db87aaf48b8301 x F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc F test/quick.test 1681febc928d686362d50057c642f77a02c62e57 F test/quota.test ddafe133653093eb9a99ccd6264884ae43f9c9b8 @@ -670,7 +667,7 @@ F test/superlock.test 5d7a4954b0059c903f82c7b67867bc5451a7c082 F test/sync.test ded6b39d8d8ca3c0c5518516c6371b3316d3e3a3 F test/table.test 04ba066432430657712d167ebf28080fe878d305 F test/tableapi.test 7262a8cbaa9965d429f1cbd2747edc185fa56516 -F test/tclsqlite.test 8c154101e704170c2be10f137a5499ac2c6da8d3 +F test/tclsqlite.test 1ce9b6340d6d412420634e129a2e3722c651056a F test/tempdb.test 19d0f66e2e3eeffd68661a11c83ba5e6ace9128c F test/temptable.test f42121a0d29a62f00f93274464164177ab1cc24a F test/temptrigger.test b0273db072ce5f37cf19140ceb1f0d524bbe9f05 @@ -887,7 +884,7 @@ F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5 F tool/lemon.c dfd81a51b6e27e469ba21d01a75ddf092d429027 F tool/lempar.c 01ca97f87610d1dac6d8cd96ab109ab1130e76dc F tool/mkkeywordhash.c d2e6b4a5965e23afb80fbe74bb54648cd371f309 -F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e +F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e x F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 F tool/mksqlite3c.tcl cf44512a48112b1ba09590548660a5a6877afdb3 F tool/mksqlite3h.tcl d76c226a5e8e1f3b5f6593bcabe5e98b3b1ec9ff @@ -912,14 +909,10 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P af4756184a255f5d8a5cd276bf9f2fc3b38d9169 -R 86eab7753acb1a027109135cae01654a -U drh -Z 475e4dbe6e8fc13f5f8796d1c18d588c ------BEGIN PGP SIGNATURE----- -Version: GnuPG v1.4.6 (GNU/Linux) - -iD8DBQFNZyEhoxKgR168RlERAohiAKCDC55xIULyuJJBl/uNZNCMqVF+ZgCeK05+ -18x49YRlHX+qQrvL/cMA0OY= -=QUmN ------END PGP SIGNATURE----- +P 4e50b0362ab6604a4b6c9f4ad849ec1733d6ce1a +R 0e3c3fa7441b432fef74ccddd445caf6 +T *branch * experimental +T *sym-experimental * +T -sym-trunk * +U dan +Z 1b63beda3df1a2343540c0064b366df4 diff --git a/manifest.uuid b/manifest.uuid index a2c2d650a2..c59fca196c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4e50b0362ab6604a4b6c9f4ad849ec1733d6ce1a \ No newline at end of file +6145d7b89f83500318713779c60f79a7ab2098ba \ No newline at end of file diff --git a/src/delete.c b/src/delete.c index bd7ac3d1f3..c7a686a8bd 100644 --- a/src/delete.c +++ b/src/delete.c @@ -531,13 +531,18 @@ void sqlite3GenerateRowDelete( /* Delete the index and table entries. Skip this step if pTab is really ** a view (in which case the only effect of the DELETE statement is to - ** fire the INSTEAD OF triggers). */ + ** fire the INSTEAD OF triggers). + ** + ** If variable 'count' is non-zero, then this OP_Delete instruction should + ** invoke the update-hook. The pre-update-hook, on the other hand should + ** be invoked unless table pTab is a system table. The difference is that + ** the update-hook is not invoked for rows removed by REPLACE, but the + ** pre-update-hook is. + */ if( pTab->pSelect==0 ){ sqlite3GenerateRowIndexDelete(pParse, pTab, iCur, 0); sqlite3VdbeAddOp2(v, OP_Delete, iCur, (count?OPFLAG_NCHANGE:0)); - if( count ){ - sqlite3VdbeChangeP4(v, -1, pTab->zName, P4_STATIC); - } + sqlite3VdbeChangeP4(v, -1, pTab->zName, P4_STATIC); } /* Do any ON CASCADE, SET NULL or SET DEFAULT operations required to diff --git a/src/insert.c b/src/insert.c index adf6ef2ed4..98f00bfe3d 100644 --- a/src/insert.c +++ b/src/insert.c @@ -1287,9 +1287,17 @@ void sqlite3GenerateConstraintChecks( sqlite3GenerateRowDelete( pParse, pTab, baseCur, regRowid, 0, pTrigger, OE_Replace ); - }else if( pTab->pIndex ){ - sqlite3MultiWrite(pParse); - sqlite3GenerateRowIndexDelete(pParse, pTab, baseCur, 0); + }else{ + /* This OP_Delete opcode fires the pre-update-hook only. It does + ** not modify the b-tree. It is more efficient to let the coming + ** OP_Insert replace the existing entry than it is to delete the + ** existing entry and then insert a new one. */ + sqlite3VdbeAddOp2(v, OP_Delete, baseCur, OPFLAG_ISNOOP); + sqlite3VdbeChangeP4(v, -1, pTab->zName, P4_STATIC); + if( pTab->pIndex ){ + sqlite3MultiWrite(pParse); + sqlite3GenerateRowIndexDelete(pParse, pTab, baseCur, 0); + } } seenReplace = 1; break; diff --git a/src/main.c b/src/main.c index 833b9812b0..3976f7ebc3 100644 --- a/src/main.c +++ b/src/main.c @@ -1271,6 +1271,25 @@ void *sqlite3_rollback_hook( return pRet; } +/* +** Register a callback to be invoked each time a row is updated, +** inserted or deleted using this database connection. +*/ +void *sqlite3_preupdate_hook( + sqlite3 *db, /* Attach the hook to this database */ + void(*xCallback)( /* Callback function */ + void*,sqlite3*,int,char const*,char const*,sqlite3_int64,sqlite3_int64), + void *pArg /* First callback argument */ +){ + void *pRet; + sqlite3_mutex_enter(db->mutex); + pRet = db->pPreUpdateArg; + db->xPreUpdateCallback = xCallback; + db->pPreUpdateArg = pArg; + sqlite3_mutex_leave(db->mutex); + return pRet; +} + #ifndef SQLITE_OMIT_WAL /* ** The sqlite3_wal_hook() callback registered by sqlite3_wal_autocheckpoint(). diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 3400c6c916..413031ecfa 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -6344,6 +6344,30 @@ int sqlite3_wal_checkpoint_v2( #define SQLITE_CHECKPOINT_FULL 1 #define SQLITE_CHECKPOINT_RESTART 2 +void *sqlite3_preupdate_hook( + sqlite3 *db, + void(*xPreUpdate)( + void *pCtx, /* Copy of third arg to preupdate_hook() */ + sqlite3 *db, /* Database handle */ + int op, /* SQLITE_UPDATE, DELETE or INSERT */ + char const *zDb, /* Database name */ + char const *zName, /* Table name */ + sqlite3_int64 iKey1, /* Rowid of row about to be deleted/updated */ + sqlite3_int64 iKey2 /* New rowid value (for a rowid UPDATE) */ + ), + void* +); + +/* +** The following APIs may only be used from within a pre-update callback. More +** specifically, the preupdate_old() API may only be used from within an +** SQLITE_UPDATE or SQLITE_DELETE pre-update callback. The preupdate_modified() +** API may only be used from within an SQLITE_UPDATE pre-update callback. +*/ +int sqlite3_preupdate_old(sqlite3 *, int, sqlite3_value **); +int sqlite3_preupdate_modified(sqlite3 *, int, int *); +int sqlite3_preupdate_count(sqlite3 *); + /* ** Undo the hack that converts floating point types to integer for diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 2987dcd483..2541936848 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -619,6 +619,7 @@ typedef struct LookasideSlot LookasideSlot; typedef struct Module Module; typedef struct NameContext NameContext; typedef struct Parse Parse; +typedef struct PreUpdate PreUpdate; typedef struct RowSet RowSet; typedef struct Savepoint Savepoint; typedef struct Select Select; @@ -827,6 +828,11 @@ struct sqlite3 { void (*xRollbackCallback)(void*); /* Invoked at every commit. */ void *pUpdateArg; void (*xUpdateCallback)(void*,int, const char*,const char*,sqlite_int64); + void *pPreUpdateArg; /* First argument to xPreUpdateCallback */ + void (*xPreUpdateCallback)( /* Registered using sqlite3_preupdate_hook() */ + void*,sqlite3*,int,char const*,char const*,sqlite3_int64,sqlite3_int64 + ); + PreUpdate *pPreUpdate; /* Context for active pre-update callback */ #ifndef SQLITE_OMIT_WAL int (*xWalCallback)(void *, sqlite3 *, const char *, int); void *pWalArg; @@ -2254,6 +2260,7 @@ struct AuthContext { #define OPFLAG_APPEND 0x08 /* This is likely to be an append */ #define OPFLAG_USESEEKRESULT 0x10 /* Try to avoid a seek in BtreeInsert() */ #define OPFLAG_CLEARCACHE 0x20 /* Clear pseudo-table cache in OP_Column */ +#define OPFLAG_ISNOOP 0x40 /* OP_Delete does pre-update-hook only */ /* * Each trigger present in the database schema is stored as an instance of diff --git a/src/tclsqlite.c b/src/tclsqlite.c index 57f38d78d1..91c6094fa9 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -122,6 +122,7 @@ struct SqliteDb { char *zNull; /* Text to substitute for an SQL NULL value */ SqlFunc *pFunc; /* List of SQL functions */ Tcl_Obj *pUpdateHook; /* Update hook script (if any) */ + Tcl_Obj *pPreUpdateHook; /* Pre-update hook script (if any) */ Tcl_Obj *pRollbackHook; /* Rollback hook script (if any) */ Tcl_Obj *pWalHook; /* WAL hook script (if any) */ Tcl_Obj *pUnlockNotify; /* Unlock notify script (if any) */ @@ -483,6 +484,9 @@ static void DbDeleteCmd(void *db){ if( pDb->pUpdateHook ){ Tcl_DecrRefCount(pDb->pUpdateHook); } + if( pDb->pPreUpdateHook ){ + Tcl_DecrRefCount(pDb->pPreUpdateHook); + } if( pDb->pRollbackHook ){ Tcl_DecrRefCount(pDb->pRollbackHook); } @@ -649,6 +653,40 @@ static void DbUnlockNotify(void **apArg, int nArg){ } #endif +/* +** Pre-update hook callback. +*/ +static void DbPreUpdateHandler( + void *p, + sqlite3 *db, + int op, + const char *zDb, + const char *zTbl, + sqlite_int64 iKey1, + sqlite_int64 iKey2 +){ + SqliteDb *pDb = (SqliteDb *)p; + Tcl_Obj *pCmd; + static const char *azStr[] = {"DELETE", "INSERT", "UPDATE"}; + + assert( (SQLITE_DELETE-1)/9 == 0 ); + assert( (SQLITE_INSERT-1)/9 == 1 ); + assert( (SQLITE_UPDATE-1)/9 == 2 ); + assert( pDb->pPreUpdateHook ); + assert( db==pDb->db ); + assert( op==SQLITE_INSERT || op==SQLITE_UPDATE || op==SQLITE_DELETE ); + + pCmd = Tcl_DuplicateObj(pDb->pPreUpdateHook); + Tcl_IncrRefCount(pCmd); + Tcl_ListObjAppendElement(0, pCmd, Tcl_NewStringObj(azStr[(op-1)/9], -1)); + Tcl_ListObjAppendElement(0, pCmd, Tcl_NewStringObj(zDb, -1)); + Tcl_ListObjAppendElement(0, pCmd, Tcl_NewStringObj(zTbl, -1)); + Tcl_ListObjAppendElement(0, pCmd, Tcl_NewWideIntObj(iKey1)); + Tcl_ListObjAppendElement(0, pCmd, Tcl_NewWideIntObj(iKey2)); + Tcl_EvalObjEx(pDb->interp, pCmd, TCL_EVAL_DIRECT); + Tcl_DecrRefCount(pCmd); +} + static void DbUpdateHandler( void *p, int op, @@ -658,14 +696,18 @@ static void DbUpdateHandler( ){ SqliteDb *pDb = (SqliteDb *)p; Tcl_Obj *pCmd; + static const char *azStr[] = {"DELETE", "INSERT", "UPDATE"}; + + assert( (SQLITE_DELETE-1)/9 == 0 ); + assert( (SQLITE_INSERT-1)/9 == 1 ); + assert( (SQLITE_UPDATE-1)/9 == 2 ); assert( pDb->pUpdateHook ); assert( op==SQLITE_INSERT || op==SQLITE_UPDATE || op==SQLITE_DELETE ); pCmd = Tcl_DuplicateObj(pDb->pUpdateHook); Tcl_IncrRefCount(pCmd); - Tcl_ListObjAppendElement(0, pCmd, Tcl_NewStringObj( - ( (op==SQLITE_INSERT)?"INSERT":(op==SQLITE_UPDATE)?"UPDATE":"DELETE"), -1)); + Tcl_ListObjAppendElement(0, pCmd, Tcl_NewStringObj(azStr[(op-1)/9], -1)); Tcl_ListObjAppendElement(0, pCmd, Tcl_NewStringObj(zDb, -1)); Tcl_ListObjAppendElement(0, pCmd, Tcl_NewStringObj(zTbl, -1)); Tcl_ListObjAppendElement(0, pCmd, Tcl_NewWideIntObj(rowid)); @@ -1550,6 +1592,44 @@ static int DbEvalNextCmd( return rc; } +/* +** This function is used by the implementations of the following database +** handle sub-commands: +** +** $db update_hook ?SCRIPT? +** $db wal_hook ?SCRIPT? +** $db commit_hook ?SCRIPT? +** $db preupdate hook ?SCRIPT? +*/ +static void DbHookCmd( + Tcl_Interp *interp, /* Tcl interpreter */ + SqliteDb *pDb, /* Database handle */ + Tcl_Obj *pArg, /* SCRIPT argument (or NULL) */ + Tcl_Obj **ppHook /* Pointer to member of SqliteDb */ +){ + sqlite3 *db = pDb->db; + + if( *ppHook ){ + Tcl_SetObjResult(interp, *ppHook); + if( pArg ){ + Tcl_DecrRefCount(*ppHook); + *ppHook = 0; + } + } + if( pArg ){ + assert( !(*ppHook) ); + if( Tcl_GetCharLength(pArg)>0 ){ + *ppHook = pArg; + Tcl_IncrRefCount(*ppHook); + } + } + + sqlite3_preupdate_hook(db, (pDb->pPreUpdateHook?DbPreUpdateHandler:0), pDb); + sqlite3_update_hook(db, (pDb->pUpdateHook?DbUpdateHandler:0), pDb); + sqlite3_rollback_hook(db, (pDb->pRollbackHook?DbRollbackHandler:0), pDb); + sqlite3_wal_hook(db, (pDb->pWalHook?DbWalHandler:0), pDb); +} + /* ** The "sqlite" command below creates a new Tcl command for each ** connection it opens to an SQLite database. This routine is invoked @@ -1575,6 +1655,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ "errorcode", "eval", "exists", "function", "incrblob", "interrupt", "last_insert_rowid", "nullvalue", "onecolumn", + "preupdate", "profile", "progress", "rekey", "restore", "rollback_hook", "status", "timeout", "total_changes", "trace", @@ -1589,6 +1670,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ DB_ERRORCODE, DB_EVAL, DB_EXISTS, DB_FUNCTION, DB_INCRBLOB, DB_INTERRUPT, DB_LAST_INSERT_ROWID, DB_NULLVALUE, DB_ONECOLUMN, + DB_PREUPDATE, DB_PROFILE, DB_PROGRESS, DB_REKEY, DB_RESTORE, DB_ROLLBACK_HOOK, DB_STATUS, DB_TIMEOUT, DB_TOTAL_CHANGES, DB_TRACE, @@ -2763,6 +2845,71 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ break; } + case DB_PREUPDATE: { + static const char *azSub[] = {"count", "hook", "modified", "old", 0}; + enum DbPreupdateSubCmd { + PRE_COUNT, PRE_HOOK, PRE_MODIFIED, PRE_OLD + }; + int iSub; + + if( objc<3 ){ + Tcl_WrongNumArgs(interp, 2, objv, "SUB-COMMAND ?ARGS?"); + } + if( Tcl_GetIndexFromObj(interp, objv[2], azSub, "sub-command", 0, &iSub) ){ + return TCL_ERROR; + } + + switch( (enum DbPreupdateSubCmd)iSub ){ + case PRE_COUNT: { + int nCol = sqlite3_preupdate_count(pDb->db); + Tcl_SetObjResult(interp, Tcl_NewIntObj(nCol)); + break; + } + + case PRE_HOOK: { + if( objc>4 ){ + Tcl_WrongNumArgs(interp, 2, objv, "hook ?SCRIPT?"); + return TCL_ERROR; + } + DbHookCmd(interp, pDb, (objc==4 ? objv[3] : 0), &pDb->pPreUpdateHook); + break; + } + + case PRE_MODIFIED: + case PRE_OLD: { + int iIdx; + if( objc!=4 ){ + Tcl_WrongNumArgs(interp, 3, objv, "INDEX"); + return TCL_ERROR; + } + if( Tcl_GetIntFromObj(interp, objv[3], &iIdx) ){ + return TCL_ERROR; + } + + if( iSub==PRE_MODIFIED ){ + int iRes; + rc = sqlite3_preupdate_modified(pDb->db, iIdx, &iRes); + if( rc==SQLITE_OK ) Tcl_SetObjResult(interp, Tcl_NewIntObj(iRes)); + }else{ + sqlite3_value *pValue; + assert( iSub==PRE_OLD ); + rc = sqlite3_preupdate_old(pDb->db, iIdx, &pValue); + if( rc==SQLITE_OK ){ + Tcl_Obj *pObj = Tcl_NewStringObj(sqlite3_value_text(pValue), -1); + Tcl_SetObjResult(interp, pObj); + } + } + + if( rc!=SQLITE_OK ){ + Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), 0); + return TCL_ERROR; + } + } + } + + break; + } + /* ** $db wal_hook ?script? ** $db update_hook ?script? @@ -2771,42 +2918,21 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ case DB_WAL_HOOK: case DB_UPDATE_HOOK: case DB_ROLLBACK_HOOK: { + sqlite3 *db = pDb->db; /* set ppHook to point at pUpdateHook or pRollbackHook, depending on ** whether [$db update_hook] or [$db rollback_hook] was invoked. */ Tcl_Obj **ppHook; - if( choice==DB_UPDATE_HOOK ){ - ppHook = &pDb->pUpdateHook; - }else if( choice==DB_WAL_HOOK ){ - ppHook = &pDb->pWalHook; - }else{ - ppHook = &pDb->pRollbackHook; - } - - if( objc!=2 && objc!=3 ){ + if( choice==DB_WAL_HOOK ) ppHook = &pDb->pWalHook; + if( choice==DB_UPDATE_HOOK ) ppHook = &pDb->pUpdateHook; + if( choice==DB_ROLLBACK_HOOK ) ppHook = &pDb->pRollbackHook; + if( objc>3 ){ Tcl_WrongNumArgs(interp, 2, objv, "?SCRIPT?"); return TCL_ERROR; } - if( *ppHook ){ - Tcl_SetObjResult(interp, *ppHook); - if( objc==3 ){ - Tcl_DecrRefCount(*ppHook); - *ppHook = 0; - } - } - if( objc==3 ){ - assert( !(*ppHook) ); - if( Tcl_GetCharLength(objv[2])>0 ){ - *ppHook = objv[2]; - Tcl_IncrRefCount(*ppHook); - } - } - - sqlite3_update_hook(pDb->db, (pDb->pUpdateHook?DbUpdateHandler:0), pDb); - sqlite3_rollback_hook(pDb->db,(pDb->pRollbackHook?DbRollbackHandler:0),pDb); - sqlite3_wal_hook(pDb->db,(pDb->pWalHook?DbWalHandler:0),pDb); + DbHookCmd(interp, pDb, (objc==3 ? objv[2] : 0), ppHook); break; } diff --git a/src/update.c b/src/update.c index 8bf58d7666..ea8f95ad56 100644 --- a/src/update.c +++ b/src/update.c @@ -490,9 +490,16 @@ void sqlite3Update( j1 = sqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, regOldRowid); sqlite3GenerateRowIndexDelete(pParse, pTab, iCur, aRegIdx); - /* If changing the record number, delete the old record. */ - if( hasFK || chngRowid ){ - sqlite3VdbeAddOp2(v, OP_Delete, iCur, 0); + /* If changing the rowid value, or if there are foreign key constraints + ** to process, delete the old record. Otherwise, add a noop OP_Delete + ** to invoke the pre-update hook. + */ + sqlite3VdbeAddOp3(v, OP_Delete, iCur, + OPFLAG_ISUPDATE | ((hasFK || chngRowid) ? 0 : OPFLAG_ISNOOP), + regNewRowid + ); + if( !pParse->nested ){ + sqlite3VdbeChangeP4(v, -1, pTab->zName, P4_STATIC); } sqlite3VdbeJumpHere(v, j1); diff --git a/src/vdbe.c b/src/vdbe.c index 00ed1438b5..c5492eedc8 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -3868,6 +3868,24 @@ case OP_InsertInt: { iKey = pOp->p3; } + if( pOp->p4.z && (db->xPreUpdateCallback || db->xUpdateCallback) ){ + assert( pC->isTable ); + assert( pC->iDb>=0 ); + zDb = db->aDb[pC->iDb].zName; + zTbl = pOp->p4.z; + op = ((pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT); + } + + /* Invoke the pre-update hook, if any */ + if( db->xPreUpdateCallback + && pOp->p4.z + && (!(pOp->p5 & OPFLAG_ISUPDATE) || pC->rowidIsValid==0) + ){ + sqlite3VdbePreUpdateHook(p, pC, + pC->rowidIsValid ? op : SQLITE_INSERT, zDb, zTbl, iKey, iKey + ); + } + if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++; if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = iKey; if( pData->flags & MEM_Null ){ @@ -3893,17 +3911,12 @@ case OP_InsertInt: { /* Invoke the update-hook if required. */ if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z ){ - zDb = db->aDb[pC->iDb].zName; - zTbl = pOp->p4.z; - op = ((pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT); - assert( pC->isTable ); db->xUpdateCallback(db->pUpdateArg, op, zDb, zTbl, iKey); - assert( pC->iDb>=0 ); } break; } -/* Opcode: Delete P1 P2 * P4 * +/* Opcode: Delete P1 P2 P3 P4 * ** ** Delete the record at which the P1 cursor is currently pointing. ** @@ -3918,30 +3931,31 @@ case OP_InsertInt: { ** P1 must not be pseudo-table. It has to be a real table with ** multiple rows. ** -** If P4 is not NULL, then it is the name of the table that P1 is -** pointing to. The update hook will be invoked, if it exists. -** If P4 is not NULL then the P1 cursor must have been positioned -** using OP_NotFound prior to invoking this opcode. +** If P4 is not NULL then, either the update or pre-update hook, or both, +** may be invoked. The P1 cursor must have been positioned using OP_NotFound +** prior to invoking this opcode in this case. Specifically, if one is +** configured, the pre-update hook is invoked if P4 is not NULL. The +** update-hook is invoked if one is configured, P4 is not NULL, and the +** OPFLAG_NCHANGE flag is set in P2. +** +** If the OPFLAG_ISUPDATE flag is set in P2, then P3 contains the address +** of the memory cell that contains the value that the rowid of the row will +** be set to by the update. */ case OP_Delete: { i64 iKey; VdbeCursor *pC; + const char *zDb; + const char *zTbl; + int opflags; + opflags = pOp->p2; iKey = 0; assert( pOp->p1>=0 && pOp->p1nCursor ); pC = p->apCsr[pOp->p1]; assert( pC!=0 ); assert( pC->pCursor!=0 ); /* Only valid for real tables, no pseudotables */ - /* If the update-hook will be invoked, set iKey to the rowid of the - ** row being deleted. - */ - if( db->xUpdateCallback && pOp->p4.z ){ - assert( pC->isTable ); - assert( pC->rowidIsValid ); /* lastRowid set by previous OP_NotFound */ - iKey = pC->lastRowid; - } - /* The OP_Delete opcode always follows an OP_NotExists or OP_Last or ** OP_Column on the same table without any intervening operations that ** might move or invalidate the cursor. Hence cursor pC is always pointing @@ -3953,18 +3967,42 @@ case OP_Delete: { rc = sqlite3VdbeCursorMoveto(pC); if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error; + /* If the update-hook or pre-update-hook will be invoked, set iKey to + ** the rowid of the row being deleted. Set zDb and zTab as well. + */ + if( pOp->p4.z && (db->xPreUpdateCallback || db->xUpdateCallback) ){ + assert( pC->iDb>=0 ); + assert( pC->isTable ); + assert( pC->rowidIsValid ); /* lastRowid set by previous OP_NotFound */ + iKey = pC->lastRowid; + zDb = db->aDb[pC->iDb].zName; + zTbl = pOp->p4.z; + } + + /* Invoke the pre-update-hook if required. */ + if( db->xPreUpdateCallback && pOp->p4.z ){ + assert( !(opflags & OPFLAG_ISUPDATE) || (aMem[pOp->p3].flags & MEM_Int) ); + sqlite3VdbePreUpdateHook(p, pC, + (opflags & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_DELETE, + zDb, zTbl, iKey, + (opflags & OPFLAG_ISUPDATE) ? aMem[pOp->p3].u.i : iKey + ); + } + + if( opflags & OPFLAG_ISNOOP ) break; + sqlite3BtreeSetCachedRowid(pC->pCursor, 0); rc = sqlite3BtreeDelete(pC->pCursor); pC->cacheStatus = CACHE_STALE; - /* Invoke the update-hook if required. */ - if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z ){ - const char *zDb = db->aDb[pC->iDb].zName; - const char *zTbl = pOp->p4.z; - db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE, zDb, zTbl, iKey); - assert( pC->iDb>=0 ); + /* Update the change-counter and invoke the update-hook if required. */ + if( opflags & OPFLAG_NCHANGE ){ + p->nChange++; + assert( pOp->p4.z ); + if( rc==SQLITE_OK && db->xUpdateCallback ){ + db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE, zDb, zTbl, iKey); + } } - if( pOp->p2 & OPFLAG_NCHANGE ) p->nChange++; break; } /* Opcode: ResetCount * * * * * diff --git a/src/vdbeInt.h b/src/vdbeInt.h index b42729d236..a764d23665 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -331,6 +331,17 @@ struct Vdbe { #define VDBE_MAGIC_HALT 0x519c2973 /* VDBE has completed execution */ #define VDBE_MAGIC_DEAD 0xb606c3c8 /* The VDBE has been deallocated */ +/* +** Structure used to store the context required by the +** sqlite3_preupdate_*() API functions. +*/ +struct PreUpdate { + VdbeCursor *pCsr; /* Cursor to read old values from */ + int op; /* One of SQLITE_INSERT, UPDATE, DELETE */ + u8 *aRecord; /* old.* database record */ + UnpackedRecord *pUnpacked; /* Unpacked version of aRecord[] */ +}; + /* ** Function prototypes */ @@ -387,6 +398,8 @@ int sqlite3VdbeCloseStatement(Vdbe *, int); void sqlite3VdbeFrameDelete(VdbeFrame*); int sqlite3VdbeFrameRestore(VdbeFrame *); void sqlite3VdbeMemStoreType(Mem *pMem); +void sqlite3VdbePreUpdateHook( + Vdbe *, VdbeCursor *, int, const char*, const char*, i64, i64); #ifdef SQLITE_DEBUG void sqlite3VdbeMemPrepareToChange(Vdbe*,Mem*); diff --git a/src/vdbeapi.c b/src/vdbeapi.c index 5578b868e1..8b1f2e21bb 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -673,6 +673,26 @@ int sqlite3_data_count(sqlite3_stmt *pStmt){ return pVm->nResColumn; } +/* +** Return a pointer to static memory containing an SQL NULL value. +*/ +static const Mem *columnNullValue(void){ + /* Even though the Mem structure contains an element + ** of type i64, on certain architecture (x86) with certain compiler + ** switches (-Os), gcc may align this Mem object on a 4-byte boundary + ** instead of an 8-byte one. This all works fine, except that when + ** running with SQLITE_DEBUG defined the SQLite code sometimes assert()s + ** that a Mem structure is located on an 8-byte boundary. To prevent + ** this assert() from failing, when building with SQLITE_DEBUG defined + ** using gcc, force nullMem to be 8-byte aligned using the magical + ** __attribute__((aligned(8))) macro. */ + static const Mem nullMem +#if defined(SQLITE_DEBUG) && defined(__GNUC__) + __attribute__((aligned(8))) +#endif + = {0, "", (double)0, {0}, 0, MEM_Null, SQLITE_NULL, 0, 0, 0 }; + return &nullMem; +} /* ** Check to see if column iCol of the given statement is valid. If @@ -692,27 +712,13 @@ static Mem *columnMem(sqlite3_stmt *pStmt, int i){ pOut = &pVm->pResultSet[i]; }else{ /* If the value passed as the second argument is out of range, return - ** a pointer to the following static Mem object which contains the - ** value SQL NULL. Even though the Mem structure contains an element - ** of type i64, on certain architecture (x86) with certain compiler - ** switches (-Os), gcc may align this Mem object on a 4-byte boundary - ** instead of an 8-byte one. This all works fine, except that when - ** running with SQLITE_DEBUG defined the SQLite code sometimes assert()s - ** that a Mem structure is located on an 8-byte boundary. To prevent - ** this assert() from failing, when building with SQLITE_DEBUG defined - ** using gcc, force nullMem to be 8-byte aligned using the magical - ** __attribute__((aligned(8))) macro. */ - static const Mem nullMem -#if defined(SQLITE_DEBUG) && defined(__GNUC__) - __attribute__((aligned(8))) -#endif - = {0, "", (double)0, {0}, 0, MEM_Null, SQLITE_NULL, 0, 0, 0 }; - + ** a pointer to a static Mem object that contains the value SQL NULL. + */ if( pVm && ALWAYS(pVm->db) ){ sqlite3_mutex_enter(pVm->db->mutex); sqlite3Error(pVm->db, SQLITE_RANGE, 0); } - pOut = (Mem*)&nullMem; + pOut = (Mem*)columnNullValue(); } return pOut; } @@ -1322,3 +1328,78 @@ int sqlite3_stmt_status(sqlite3_stmt *pStmt, int op, int resetFlag){ if( resetFlag ) pVdbe->aCounter[op-1] = 0; return v; } + +int sqlite3_preupdate_old(sqlite3 *db, int iIdx, sqlite3_value **ppValue){ + PreUpdate *p = db->pPreUpdate; + int rc = SQLITE_OK; + + if( !p || p->op==SQLITE_INSERT ){ + rc = SQLITE_MISUSE_BKPT; + goto preupdate_old_out; + } + if( iIdx>=p->pCsr->nField || iIdx<0 ){ + rc = SQLITE_RANGE; + goto preupdate_old_out; + } + + if( p->pUnpacked==0 ){ + KeyInfo keyinfo; + u32 nRecord; + u8 *aRecord; + + memset(&keyinfo, 0, sizeof(KeyInfo)); + keyinfo.db = db; + keyinfo.enc = ENC(db); + keyinfo.nField = p->pCsr->nField; + + rc = sqlite3BtreeDataSize(p->pCsr->pCursor, &nRecord); + if( rc!=SQLITE_OK ) goto preupdate_old_out; + aRecord = sqlite3DbMallocRaw(db, nRecord); + if( !aRecord ) goto preupdate_old_out; + rc = sqlite3BtreeData(p->pCsr->pCursor, 0, nRecord, aRecord); + if( rc!=SQLITE_OK ){ + sqlite3DbFree(db, aRecord); + goto preupdate_old_out; + } + + p->pUnpacked = sqlite3VdbeRecordUnpack(&keyinfo, nRecord, aRecord, 0, 0); + p->aRecord = aRecord; + } + + if( iIdx>=p->pUnpacked->nField ){ + *ppValue = (sqlite3_value *)columnNullValue(); + }else{ + *ppValue = &p->pUnpacked->aMem[iIdx]; + sqlite3VdbeMemStoreType(*ppValue); + } + + preupdate_old_out: + sqlite3Error(db, rc, 0); + return sqlite3ApiExit(db, rc); +} + +int sqlite3_preupdate_count(sqlite3 *db){ + PreUpdate *p = db->pPreUpdate; + return (p ? p->pCsr->nField : 0); +} + +int sqlite3_preupdate_modified(sqlite3 *db, int iIdx, int *pbMod){ + PreUpdate *p = db->pPreUpdate; + int rc = SQLITE_OK; + + if( !p || p->op!=SQLITE_UPDATE ){ + rc = SQLITE_MISUSE_BKPT; + goto preupdate_mod_out; + } + if( iIdx>=p->pCsr->nField || iIdx<0 ){ + rc = SQLITE_RANGE; + goto preupdate_mod_out; + } + *pbMod = 1; + + preupdate_mod_out: + sqlite3Error(db, rc, 0); + return sqlite3ApiExit(db, rc); +} + + diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 64ff489919..31cf669144 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -2830,7 +2830,7 @@ void sqlite3VdbeDeleteUnpackedRecord(UnpackedRecord *p){ ** strings and blobs static. And none of the elements are ** ever transformed, so there is never anything to delete. */ - if( NEVER(pMem->zMalloc) ) sqlite3VdbeMemRelease(pMem); + if( pMem->zMalloc ) sqlite3VdbeMemRelease(pMem); } if( p->flags & UNPACKED_NEED_FREE ){ sqlite3DbFree(p->pKeyInfo->db, p); @@ -3162,3 +3162,35 @@ void sqlite3VdbeSetVarmask(Vdbe *v, int iVar){ v->expmask |= ((u32)1 << (iVar-1)); } } + +/* +** Invoke the pre-update hook. If this is an UPDATE or DELETE pre-update call, +** then cursor passed as the second argument should point to the row about +** to be update or deleted. If the application calls sqlite3_preupdate_old(), +** the required value will be read from the row the cursor points to. +*/ +void sqlite3VdbePreUpdateHook( + Vdbe *v, /* Vdbe pre-update hook is invoked by */ + VdbeCursor *pCsr, /* Cursor to grab old.* values from */ + int op, /* SQLITE_INSERT, UPDATE or DELETE */ + const char *zDb, /* Database name */ + const char *zTbl, /* Table name */ + i64 iKey1, /* Initial key value */ + i64 iKey2 /* Final key value */ +){ + sqlite3 *db = v->db; + + PreUpdate preupdate; + memset(&preupdate, 0, sizeof(PreUpdate)); + + preupdate.pCsr = pCsr; + preupdate.op = op; + db->pPreUpdate = &preupdate; + db->xPreUpdateCallback(db->pPreUpdateArg, db, op, zDb, zTbl, iKey1, iKey2); + db->pPreUpdate = 0; + sqlite3DbFree(db, preupdate.aRecord); + if( preupdate.pUnpacked ){ + sqlite3VdbeDeleteUnpackedRecord(preupdate.pUnpacked); + } +} + diff --git a/test/hook.test b/test/hook.test index 6496d41e13..827ce08b3d 100644 --- a/test/hook.test +++ b/test/hook.test @@ -21,6 +21,7 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl +set ::testprefix hook do_test hook-1.2 { db commit_hook @@ -361,4 +362,270 @@ do_test hook-6.2 { } {COMMIT ROLLBACK} unset ::hooks +#---------------------------------------------------------------------------- +# The following tests - hook-7.* - test the pre-update hook. +# +# 7.1.1 - INSERT statement. +# 7.1.2 - INSERT INTO ... SELECT statement. +# 7.1.3 - REPLACE INTO ... (rowid conflict) +# 7.1.4 - REPLACE INTO ... (other index conflicts) +# 7.1.5 - REPLACE INTO ... (both rowid and other index conflicts) +# +# 7.2.1 - DELETE statement. +# 7.2.2 - DELETE statement that uses the truncate optimization. +# +# 7.3.1 - UPDATE statement. +# 7.3.2 - UPDATE statement that modifies the rowid. +# 7.3.3 - UPDATE OR REPLACE ... (rowid conflict). +# 7.3.4 - UPDATE OR REPLACE ... (other index conflicts) +# 7.3.4 - UPDATE OR REPLACE ... (both rowid and other index conflicts) +# +# 7.4.1 - Test that the pre-update-hook is invoked only once if a row being +# deleted is removed by a BEFORE trigger. +# +# 7.4.2 - Test that the pre-update-hook is invoked if a BEFORE trigger +# removes a row being updated. In this case the update hook should +# be invoked with SQLITE_INSERT as the opcode when inserting the +# new version of the row. +# +# TODO: Short records (those created before a column is added to a table +# using ALTER TABLE) +# + +proc do_preupdate_test {tn sql x} { + set X [list] + foreach elem $x {lappend X $elem} + uplevel do_test $tn [list " + set ::preupdate \[list\] + execsql { $sql } + set ::preupdate + "] [list $X] +} + +proc preupdate_hook {args} { + set type [lindex $args 0] + eval lappend ::preupdate $args + if {$type != "SQLITE_INSERT"} { + for {set i 0} {$i < [db preupdate count]} {incr i} { + lappend ::preupdate [db preupdate old $i] + } + } +} + +db close +forcedelete test.db +sqlite3 db test.db +db preupdate hook preupdate_hook + +# Set up a schema to use for tests 7.1.* to 7.3.*. +do_execsql_test 7.0 { + CREATE TABLE t1(a, b); + CREATE TABLE t2(x, y); + CREATE TABLE t3(i, j, UNIQUE(i)); + + INSERT INTO t2 VALUES('a', 'b'); + INSERT INTO t2 VALUES('c', 'd'); + + INSERT INTO t3 VALUES(4, 16); + INSERT INTO t3 VALUES(5, 25); + INSERT INTO t3 VALUES(6, 36); +} + +do_preupdate_test 7.1.1 { + INSERT INTO t1 VALUES('x', 'y') +} {INSERT main t1 1 1} + +# 7.1.2.1 does not use the xfer optimization. 7.1.2.2 does. +do_preupdate_test 7.1.2.1 { + INSERT INTO t1 SELECT y, x FROM t2; +} {INSERT main t1 2 2 INSERT main t1 3 3} +do_preupdate_test 7.1.2.2 { + INSERT INTO t1 SELECT * FROM t2; +} {INSERT main t1 4 4 INSERT main t1 5 5} + +do_preupdate_test 7.1.3 { + REPLACE INTO t1(rowid, a, b) VALUES(1, 1, 1); +} { + DELETE main t1 1 1 x y + INSERT main t1 1 1 +} + +do_preupdate_test 7.1.4 { + REPLACE INTO t3 VALUES(4, NULL); +} { + DELETE main t3 1 1 4 16 + INSERT main t3 4 4 +} + +do_preupdate_test 7.1.5 { + REPLACE INTO t3(rowid, i, j) VALUES(2, 6, NULL); +} { + DELETE main t3 2 2 5 25 + DELETE main t3 3 3 6 36 + INSERT main t3 2 2 +} + +do_execsql_test 7.2.0 { SELECT rowid FROM t1 } {1 2 3 4 5} + +do_preupdate_test 7.2.1 { + DELETE FROM t1 WHERE rowid = 3 +} { + DELETE main t1 3 3 d c +} +do_preupdate_test 7.2.2 { + DELETE FROM t1 +} { + DELETE main t3 1 1 1 1 + DELETE main t3 2 2 b a + DELETE main t3 4 4 a b + DELETE main t3 5 5 c d +} + +do_execsql_test 7.3.0 { + DELETE FROM t1; + DELETE FROM t2; + DELETE FROM t3; + + INSERT INTO t2 VALUES('a', 'b'); + INSERT INTO t2 VALUES('c', 'd'); + + INSERT INTO t3 VALUES(4, 16); + INSERT INTO t3 VALUES(5, 25); + INSERT INTO t3 VALUES(6, 36); +} + +do_preupdate_test 7.3.1 { + UPDATE t2 SET y = y||y; +} { + UPDATE main t2 1 1 a b + UPDATE main t2 2 2 c d +} + +do_preupdate_test 7.3.2 { + UPDATE t2 SET rowid = rowid-1; +} { + UPDATE main t2 1 0 a bb + UPDATE main t2 2 1 c dd +} + +do_preupdate_test 7.3.3 { + UPDATE OR REPLACE t2 SET rowid = 1 WHERE x = 'a' +} { + DELETE main t2 1 1 c dd + UPDATE main t2 0 1 a bb +} + +do_preupdate_test 7.3.4.1 { + UPDATE OR REPLACE t3 SET i = 5 WHERE i = 6 +} { + DELETE main t3 2 2 5 25 + UPDATE main t3 3 3 6 36 +} + +do_execsql_test 7.3.4.2 { + INSERT INTO t3 VALUES(10, 100); + SELECT rowid, * FROM t3; +} {1 4 16 3 5 36 4 10 100} + +do_preupdate_test 7.3.5 { + UPDATE OR REPLACE t3 SET rowid = 1, i = 5 WHERE j = 100; +} { + DELETE main t3 1 1 4 16 + DELETE main t3 3 3 5 36 + UPDATE main t3 4 1 10 100 +} + +do_execsql_test 7.4.1.0 { + CREATE TABLE t4(a, b); + INSERT INTO t4 VALUES('a', 1); + INSERT INTO t4 VALUES('b', 2); + INSERT INTO t4 VALUES('c', 3); + + CREATE TRIGGER t4t BEFORE DELETE ON t4 BEGIN + DELETE FROM t4 WHERE b = 1; + END; +} + +do_preupdate_test 7.4.1.1 { + DELETE FROM t4 WHERE b = 3 +} { + DELETE main t4 1 1 a 1 + DELETE main t4 3 3 c 3 +} + +do_execsql_test 7.4.1.2 { + INSERT INTO t4(rowid, a, b) VALUES(1, 'a', 1); + INSERT INTO t4(rowid, a, b) VALUES(3, 'c', 3); +} +do_preupdate_test 7.4.1.3 { + DELETE FROM t4 WHERE b = 1 +} { + DELETE main t4 1 1 a 1 +} + +do_execsql_test 7.4.2.0 { + CREATE TABLE t5(a, b); + INSERT INTO t5 VALUES('a', 1); + INSERT INTO t5 VALUES('b', 2); + INSERT INTO t5 VALUES('c', 3); + + CREATE TRIGGER t5t BEFORE UPDATE ON t5 BEGIN + DELETE FROM t5 WHERE b = 1; + END; +} +do_preupdate_test 7.4.2.1 { + UPDATE t5 SET b = 4 WHERE a = 'c' +} { + DELETE main t5 1 1 a 1 + UPDATE main t5 3 3 c 3 +} + +do_execsql_test 7.4.2.2 { + INSERT INTO t5(rowid, a, b) VALUES(1, 'a', 1); +} + +do_preupdate_test 7.4.2.3 { + UPDATE t5 SET b = 5 WHERE a = 'a' +} { + DELETE main t5 1 1 a 1 +} + +do_execsql_test 7.5.1.0 { + CREATE TABLE t7(a, b); + INSERT INTO t7 VALUES('one', 'two'); + INSERT INTO t7 VALUES('three', 'four'); + ALTER TABLE t7 ADD COLUMN c DEFAULT NULL; +} + +do_preupdate_test 7.5.1.1 { + DELETE FROM t7 WHERE a = 'one' +} { + DELETE main t7 1 1 one two {} +} + +do_preupdate_test 7.5.1.2 { + UPDATE t7 SET b = 'five' +} { + UPDATE main t7 2 2 three four {} +} + +do_execsql_test 7.5.2.0 { + CREATE TABLE t8(a, b); + INSERT INTO t8 VALUES('one', 'two'); + INSERT INTO t8 VALUES('three', 'four'); + ALTER TABLE t8 ADD COLUMN c DEFAULT 'xxx'; +} + +do_preupdate_test 7.5.2.1 { + DELETE FROM t8 WHERE a = 'one' +} { + DELETE main t8 1 1 one two xxx +} + +do_preupdate_test 7.5.2.2 { + UPDATE t8 SET b = 'five' +} { + UPDATE main t8 2 2 three four xxx +} + finish_test diff --git a/test/progress.test b/test/progress.test old mode 100644 new mode 100755 diff --git a/test/tclsqlite.test b/test/tclsqlite.test index 8db04ebfa4..c9d562beb5 100644 --- a/test/tclsqlite.test +++ b/test/tclsqlite.test @@ -35,7 +35,7 @@ do_test tcl-1.1 { do_test tcl-1.2 { set v [catch {db bogus} msg] lappend v $msg -} {1 {bad option "bogus": must be authorizer, backup, busy, cache, changes, close, collate, collation_needed, commit_hook, complete, copy, enable_load_extension, errorcode, eval, exists, function, incrblob, interrupt, last_insert_rowid, nullvalue, onecolumn, profile, progress, rekey, restore, rollback_hook, status, timeout, total_changes, trace, transaction, unlock_notify, update_hook, version, or wal_hook}} +} {1 {bad option "bogus": must be authorizer, backup, busy, cache, changes, close, collate, collation_needed, commit_hook, complete, copy, enable_load_extension, errorcode, eval, exists, function, incrblob, interrupt, last_insert_rowid, nullvalue, onecolumn, preupdate, profile, progress, rekey, restore, rollback_hook, status, timeout, total_changes, trace, transaction, unlock_notify, update_hook, version, or wal_hook}} do_test tcl-1.2.1 { set v [catch {db cache bogus} msg] lappend v $msg diff --git a/tool/mkopts.tcl b/tool/mkopts.tcl old mode 100644 new mode 100755 From 21e8d0126d3d89af3a979ebdac85a6837b5b5ef9 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 3 Mar 2011 20:05:59 +0000 Subject: [PATCH 0002/1484] Add the experimental sqlite3_transaction_hook() API. FossilOrigin-Name: 093d8cd8e2f3a6af5d40cf810e396f4919eb5cef --- manifest | 31 +++++----- manifest.uuid | 2 +- src/main.c | 42 ++++++++++++++ src/sqlite.h.in | 27 ++++++--- src/sqliteInt.h | 4 ++ src/tclsqlite.c | 37 +++++++++++- src/vdbe.c | 13 +++++ src/vdbeapi.c | 10 +++- src/vdbeaux.c | 9 +++ test/hook.test | 137 +++++++++++++++++++++++++++++++++++++++++++- test/tclsqlite.test | 2 +- 11 files changed, 282 insertions(+), 32 deletions(-) diff --git a/manifest b/manifest index 2608f60580..132ab8f068 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sexperimental\ssqlite3_preupdate_hook()\sAPI. -D 2011-03-01T18:42:07 +C Add\sthe\sexperimental\ssqlite3_transaction_hook()\sAPI. +D 2011-03-03T20:06:00 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -142,7 +142,7 @@ F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f F src/lempar.c 7f026423f4d71d989e719a743f98a1cbd4e6d99e F src/loadext.c 8af9fcc75708d60b88636ccba38b4a7b3c155c3e -F src/main.c 9ab948225b8c362cdd6902c447abbf218607e0f3 +F src/main.c 1a5cafdc1bee11f4322c837487bf6fa8e54b2f50 F src/malloc.c 92d59a007d7a42857d4e9454aa25b6b703286be1 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 00bd8265c81abb665c48fea1e0c234eb3b922206 @@ -177,13 +177,13 @@ F src/resolve.c 1c0f32b64f8e3f555fe1f732f9d6f501a7f05706 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 F src/select.c d24406c45dd2442eb2eeaac413439066b149c944 F src/shell.c 649c51979812f77f97507024a4cea480c6862b8b -F src/sqlite.h.in 3a8a9f25a45735879cec195a2c129b48e34ebf8e +F src/sqlite.h.in 992688609e9a0274b56c156d4800be96364b3590 F src/sqlite3ext.h c90bd5507099f62043832d73f6425d8d5c5da754 -F src/sqliteInt.h 3a262a299fa5b1f6916157ec2302e8987e50bac9 +F src/sqliteInt.h 85e635183013e806069320ffa6080a77183f9225 F src/sqliteLimit.h a17dcd3fb775d63b64a43a55c54cb282f9726f44 F src/status.c 4997380fbb915426fef9e500b4872e79c99267fc F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e -F src/tclsqlite.c 20a3bf120f3bba1914f0e5132dbe937dee135f36 +F src/tclsqlite.c 64aeb4109ee2b38fd820b8e8de45b02377fcddc0 F src/test1.c 9020310c7617234b33fd1c3064f89524db25f290 F src/test2.c 80d323d11e909cf0eb1b6fbb4ac22276483bcf31 F src/test3.c 056093cfef69ff4227a6bdb9108564dc7f45e4bc @@ -229,11 +229,11 @@ F src/update.c 1b9a82ede7df15e76ed86c6a3cbe4ce0f21eaa9b F src/utf.c 1baeeac91707a4df97ccc6141ec0f808278af685 F src/util.c ab1c92426494f499f42b9e307537b03e923d75c1 F src/vacuum.c 924bd1bcee2dfb05376f79845bd3b4cec7b54b2f -F src/vdbe.c 4330cc94597b9c95853c5e8ff87776f1e6ceaa3f +F src/vdbe.c 2c523bc17f915329f3db3745fc76ed9bfc5c26bb F src/vdbe.h 4de0efb4b0fdaaa900cf419b35c458933ef1c6d2 F src/vdbeInt.h 41b8e337332f279228196039ab86acd353ad0c6c -F src/vdbeapi.c c407f3f0e21d5de68b1269bfa12315ef7ed6e3fd -F src/vdbeaux.c 874e16966eb6e58183ee2746abb4e4c5238f2350 +F src/vdbeapi.c ea741433042d95c392b29397ac6c2b08f6106317 +F src/vdbeaux.c cc817d8597307a2be361c24f3b436a7e41fa67dc F src/vdbeblob.c 18955f0ee6b133cd08e1592010cb9a6b11e9984c F src/vdbemem.c 0fa2ed786cd207d5b988afef3562a8e663a75b50 F src/vdbetrace.c 3ba13bc32bdf16d2bdea523245fd16736bed67b5 @@ -471,7 +471,7 @@ F test/fuzz2.test 207d0f9d06db3eaf47a6b7bfc835b8e2fc397167 F test/fuzz3.test aec64345184d1662bd30e6a17851ff659d596dc5 F test/fuzz_common.tcl a87dfbb88c2a6b08a38e9a070dabd129e617b45b F test/fuzz_malloc.test dd7001ac86d09c154a7dff064f4739c60e2b312c -F test/hook.test 5fd01c30f47896d88bed8a09bf7773cff218e8ff +F test/hook.test a90748e44c7ca53da46f857616fc7ce18bf7be13 F test/icu.test 70df4faca133254c042d02ae342c0a141f2663f4 F test/in.test 19b642bb134308980a92249750ea4ce3f6c75c2d F test/in2.test 5d4c61d17493c832f7d2d32bef785119e87bde75 @@ -667,7 +667,7 @@ F test/superlock.test 5d7a4954b0059c903f82c7b67867bc5451a7c082 F test/sync.test ded6b39d8d8ca3c0c5518516c6371b3316d3e3a3 F test/table.test 04ba066432430657712d167ebf28080fe878d305 F test/tableapi.test 7262a8cbaa9965d429f1cbd2747edc185fa56516 -F test/tclsqlite.test 1ce9b6340d6d412420634e129a2e3722c651056a +F test/tclsqlite.test 550f2268281d186b767b3ee14dd0be5f9e3ff25d F test/tempdb.test 19d0f66e2e3eeffd68661a11c83ba5e6ace9128c F test/temptable.test f42121a0d29a62f00f93274464164177ab1cc24a F test/temptrigger.test b0273db072ce5f37cf19140ceb1f0d524bbe9f05 @@ -909,10 +909,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 4e50b0362ab6604a4b6c9f4ad849ec1733d6ce1a -R 0e3c3fa7441b432fef74ccddd445caf6 -T *branch * experimental -T *sym-experimental * -T -sym-trunk * +P 6145d7b89f83500318713779c60f79a7ab2098ba +R 2617e052d0e8716cc0b428f99022eddb U dan -Z 1b63beda3df1a2343540c0064b366df4 +Z 24e44e929785c6b1d1f35eb2447fe0e7 diff --git a/manifest.uuid b/manifest.uuid index c59fca196c..e0c1dabe5a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6145d7b89f83500318713779c60f79a7ab2098ba \ No newline at end of file +093d8cd8e2f3a6af5d40cf810e396f4919eb5cef \ No newline at end of file diff --git a/src/main.c b/src/main.c index 3976f7ebc3..a8ac80039e 100644 --- a/src/main.c +++ b/src/main.c @@ -764,6 +764,26 @@ int sqlite3_close(sqlite3 *db){ return SQLITE_OK; } + +/* +** Invoke the transaction-hook. +*/ +void sqlite3TransactionHook(sqlite3 *db, int op, int iLevel){ + assert( op==SQLITE_BEGIN || op==SQLITE_COMMIT || op==SQLITE_ROLLBACK ); + assert( op==SQLITE_BEGIN || iLeveliOpenTrans || iLevel==0 ); + assert( op==SQLITE_BEGIN || iLeveliOpenTrans || db->iOpenTrans==0 ); + assert( op!=SQLITE_BEGIN || iLevel==db->iOpenTrans || iLevel==0 ); + assert( op!=SQLITE_BEGIN || iLevel==db->iOpenTrans || db->iOpenTrans==1 ); + + if( op==SQLITE_BEGIN && iLevel!=db->iOpenTrans ) return; + if( op!=SQLITE_BEGIN && iLevel>=db->iOpenTrans ) return; + + if( db->xTransCallback ){ + db->xTransCallback(db->pTransArg, op, iLevel); + } + db->iOpenTrans = iLevel + (op==SQLITE_BEGIN); +} + /* ** Rollback all database files. */ @@ -796,6 +816,10 @@ void sqlite3RollbackAll(sqlite3 *db){ if( db->xRollbackCallback && (inTrans || !db->autoCommit) ){ db->xRollbackCallback(db->pRollbackArg); } + + /* If a transaction-hook is configured, invoke it now to report on + ** the rollback operation. */ + sqlite3TransactionHook(db, SQLITE_ROLLBACK, 0); } /* @@ -1290,6 +1314,24 @@ void *sqlite3_preupdate_hook( return pRet; } +/* +** Register a callback to be invoked each time a transaction or savepoint +** is opened, committed or rolled back. +*/ +void *sqlite3_transaction_hook( + sqlite3 *db, /* Database handle */ + void(*xCallback)(void *, int, int), /* Callback function */ + void *pArg /* First callback argument */ +){ + void *pRet; + sqlite3_mutex_enter(db->mutex); + pRet = db->pTransArg; + db->xTransCallback = xCallback; + db->pTransArg = pArg; + sqlite3_mutex_leave(db->mutex); + return pRet; +} + #ifndef SQLITE_OMIT_WAL /* ** The sqlite3_wal_hook() callback registered by sqlite3_wal_autocheckpoint(). diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 413031ecfa..137be57b89 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -6344,7 +6344,15 @@ int sqlite3_wal_checkpoint_v2( #define SQLITE_CHECKPOINT_FULL 1 #define SQLITE_CHECKPOINT_RESTART 2 -void *sqlite3_preupdate_hook( + +/* +** CAPI3REF: The pre-update hook. +** +** The preupdate_old() API may only be used from within an SQLITE_UPDATE or +** SQLITE_DELETE pre-update callback. The preupdate_modified() API may only +** be used from within an SQLITE_UPDATE pre-update callback. +*/ +SQLITE_EXPERIMENTAL void *sqlite3_preupdate_hook( sqlite3 *db, void(*xPreUpdate)( void *pCtx, /* Copy of third arg to preupdate_hook() */ @@ -6357,16 +6365,19 @@ void *sqlite3_preupdate_hook( ), void* ); +SQLITE_EXPERIMENTAL int sqlite3_preupdate_old(sqlite3 *, int, sqlite3_value **); +SQLITE_EXPERIMENTAL int sqlite3_preupdate_modified(sqlite3 *, int, int *); +SQLITE_EXPERIMENTAL int sqlite3_preupdate_count(sqlite3 *); /* -** The following APIs may only be used from within a pre-update callback. More -** specifically, the preupdate_old() API may only be used from within an -** SQLITE_UPDATE or SQLITE_DELETE pre-update callback. The preupdate_modified() -** API may only be used from within an SQLITE_UPDATE pre-update callback. +** CAPI3REF: The transaction hook. */ -int sqlite3_preupdate_old(sqlite3 *, int, sqlite3_value **); -int sqlite3_preupdate_modified(sqlite3 *, int, int *); -int sqlite3_preupdate_count(sqlite3 *); +SQLITE_EXPERIMENTAL +void *sqlite3_transaction_hook(sqlite3 *, void(*)(void *, int, int), void *); + +#define SQLITE_BEGIN 1 +#define SQLITE_COMMIT 2 +#define SQLITE_ROLLBACK 3 /* diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 2541936848..1414fb68b5 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -833,6 +833,9 @@ struct sqlite3 { void*,sqlite3*,int,char const*,char const*,sqlite3_int64,sqlite3_int64 ); PreUpdate *pPreUpdate; /* Context for active pre-update callback */ + void *pTransArg; /* First argument to xTransCallback */ + void (*xTransCallback)(void*,int,int); + int iOpenTrans; /* Open transaction (xTransCallback) plus 1 */ #ifndef SQLITE_OMIT_WAL int (*xWalCallback)(void *, sqlite3 *, const char *, int); void *pWalArg; @@ -2748,6 +2751,7 @@ void sqlite3PrngSaveState(void); void sqlite3PrngRestoreState(void); void sqlite3PrngResetState(void); void sqlite3RollbackAll(sqlite3*); +void sqlite3TransactionHook(sqlite3 *, int, int); void sqlite3CodeVerifySchema(Parse*, int); void sqlite3BeginTransaction(Parse*, int); void sqlite3CommitTransaction(Parse*); diff --git a/src/tclsqlite.c b/src/tclsqlite.c index 91c6094fa9..c7e6fda068 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -124,6 +124,7 @@ struct SqliteDb { Tcl_Obj *pUpdateHook; /* Update hook script (if any) */ Tcl_Obj *pPreUpdateHook; /* Pre-update hook script (if any) */ Tcl_Obj *pRollbackHook; /* Rollback hook script (if any) */ + Tcl_Obj *pTransHook; /* Transaction hook script (if any) */ Tcl_Obj *pWalHook; /* WAL hook script (if any) */ Tcl_Obj *pUnlockNotify; /* Unlock notify script (if any) */ SqlCollate *pCollate; /* List of SQL collation functions */ @@ -597,6 +598,30 @@ static void DbRollbackHandler(void *clientData){ } } +/* +** sqlite3_transaction_hook() callback. +*/ +static void DbTransHandler(void *clientData, int op, int iLevel){ + static const char *azStr[] = { "BEGIN", "COMMIT", "ROLLBACK" }; + SqliteDb *pDb = (SqliteDb*)clientData; + Tcl_Interp *interp = pDb->interp; + Tcl_Obj *pScript; + + assert(pDb->pTransHook); + assert( SQLITE_BEGIN==1 ); + assert( SQLITE_COMMIT==2 ); + assert( SQLITE_ROLLBACK==3 ); + + pScript = Tcl_DuplicateObj(pDb->pTransHook); + Tcl_IncrRefCount(pScript); + Tcl_ListObjAppendElement(interp, pScript, Tcl_NewStringObj(azStr[op-1], -1)); + Tcl_ListObjAppendElement(interp, pScript, Tcl_NewIntObj(iLevel)); + if( TCL_OK!=Tcl_EvalObjEx(interp, pScript, 0) ){ + Tcl_BackgroundError(interp); + } + Tcl_DecrRefCount(pScript); +} + /* ** This procedure handles wal_hook callbacks. */ @@ -1628,6 +1653,7 @@ static void DbHookCmd( sqlite3_update_hook(db, (pDb->pUpdateHook?DbUpdateHandler:0), pDb); sqlite3_rollback_hook(db, (pDb->pRollbackHook?DbRollbackHandler:0), pDb); sqlite3_wal_hook(db, (pDb->pWalHook?DbWalHandler:0), pDb); + sqlite3_transaction_hook(db, (pDb->pTransHook?DbTransHandler:0), pDb); } /* @@ -1659,7 +1685,8 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ "profile", "progress", "rekey", "restore", "rollback_hook", "status", "timeout", "total_changes", "trace", - "transaction", "unlock_notify", "update_hook", + "transaction", "transaction_hook", + "unlock_notify", "update_hook", "version", "wal_hook", 0 }; enum DB_enum { @@ -1674,7 +1701,8 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ DB_PROFILE, DB_PROGRESS, DB_REKEY, DB_RESTORE, DB_ROLLBACK_HOOK, DB_STATUS, DB_TIMEOUT, DB_TOTAL_CHANGES, DB_TRACE, - DB_TRANSACTION, DB_UNLOCK_NOTIFY, DB_UPDATE_HOOK, + DB_TRANSACTION, DB_TRANSACTION_HOOK, + DB_UNLOCK_NOTIFY, DB_UPDATE_HOOK, DB_VERSION, DB_WAL_HOOK }; /* don't leave trailing commas on DB_enum, it confuses the AIX xlc compiler */ @@ -2914,10 +2942,12 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ ** $db wal_hook ?script? ** $db update_hook ?script? ** $db rollback_hook ?script? + ** $db transaction_hook ?script? */ case DB_WAL_HOOK: case DB_UPDATE_HOOK: - case DB_ROLLBACK_HOOK: { + case DB_ROLLBACK_HOOK: + case DB_TRANSACTION_HOOK: { sqlite3 *db = pDb->db; /* set ppHook to point at pUpdateHook or pRollbackHook, depending on @@ -2927,6 +2957,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ if( choice==DB_WAL_HOOK ) ppHook = &pDb->pWalHook; if( choice==DB_UPDATE_HOOK ) ppHook = &pDb->pUpdateHook; if( choice==DB_ROLLBACK_HOOK ) ppHook = &pDb->pRollbackHook; + if( choice==DB_TRANSACTION_HOOK ) ppHook = &pDb->pTransHook; if( objc>3 ){ Tcl_WrongNumArgs(interp, 2, objv, "?SCRIPT?"); return TCL_ERROR; diff --git a/src/vdbe.c b/src/vdbe.c index c5492eedc8..252c53cb63 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2568,6 +2568,8 @@ case OP_Savepoint: { }else{ db->nSavepoint++; } + + sqlite3TransactionHook(db, SQLITE_BEGIN, db->nSavepoint); /* Link the new savepoint into the database handle's list. */ pNew->pNext = db->pSavepoint; @@ -2635,6 +2637,13 @@ case OP_Savepoint: { sqlite3ResetInternalSchema(db, 0); db->flags = (db->flags | SQLITE_InternChanges); } + + assert( SAVEPOINT_ROLLBACK+1==SQLITE_ROLLBACK ); + assert( SAVEPOINT_RELEASE+1==SQLITE_COMMIT ); + sqlite3TransactionHook(db, p1+1, iSavepoint+1); + if( p1==SAVEPOINT_ROLLBACK ){ + sqlite3TransactionHook(db, SQLITE_BEGIN, iSavepoint+1); + } } /* Regardless of whether this is a RELEASE or ROLLBACK, destroy all @@ -2710,6 +2719,9 @@ case OP_AutoCommit: { }else if( (rc = sqlite3VdbeCheckFk(p, 1))!=SQLITE_OK ){ goto vdbe_return; }else{ + if( desiredAutoCommit==0 ){ + sqlite3TransactionHook(db, SQLITE_BEGIN, 0); + } db->autoCommit = (u8)desiredAutoCommit; if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){ p->pc = pc; @@ -2796,6 +2808,7 @@ case OP_Transaction: { p->iStatement = db->nSavepoint + db->nStatement; } rc = sqlite3BtreeBeginStmt(pBt, p->iStatement); + sqlite3TransactionHook(db, SQLITE_BEGIN, p->iStatement); /* Store the current value of the database handles deferred constraint ** counter. If the statement transaction needs to be rolled back, diff --git a/src/vdbeapi.c b/src/vdbeapi.c index 8b1f2e21bb..cefca02a24 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -401,7 +401,15 @@ static int sqlite3Step(Vdbe *p){ #endif db->activeVdbeCnt++; - if( p->readOnly==0 ) db->writeVdbeCnt++; + if( p->readOnly==0 ){ + /* If this statement will open an implicit transaction, invoke the + ** transaction-hook here. */ + if( db->autoCommit && db->writeVdbeCnt==0 ){ + assert( db->nSavepoint==0 ); + sqlite3TransactionHook(db, SQLITE_BEGIN, 0); + } + db->writeVdbeCnt++; + } p->pc = 0; } #ifndef SQLITE_OMIT_EXPLAIN diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 31cf669144..937c2a1998 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -1845,6 +1845,12 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){ } #endif + /* If a transaction-hook is configured, invoke it now to report on the + ** successful commit operation. */ + if( rc==SQLITE_OK ){ + sqlite3TransactionHook(db, SQLITE_COMMIT, 0); + } + return rc; } @@ -1946,6 +1952,9 @@ int sqlite3VdbeCloseStatement(Vdbe *p, int eOp){ } } db->nStatement--; + assert( SAVEPOINT_ROLLBACK+1==SQLITE_ROLLBACK ); + assert( SAVEPOINT_RELEASE+1==SQLITE_COMMIT ); + sqlite3TransactionHook(db, eOp+1, p->iStatement); p->iStatement = 0; /* If the statement transaction is being rolled back, also restore the diff --git a/test/hook.test b/test/hook.test index 827ce08b3d..b2e0988828 100644 --- a/test/hook.test +++ b/test/hook.test @@ -616,16 +616,151 @@ do_execsql_test 7.5.2.0 { ALTER TABLE t8 ADD COLUMN c DEFAULT 'xxx'; } +# At time of writing, these two are broken. They demonstraight that the +# sqlite3_preupdate_old() method does not handle the case where ALTER TABLE +# has been used to add a column with a default value other than NULL. +# do_preupdate_test 7.5.2.1 { DELETE FROM t8 WHERE a = 'one' } { DELETE main t8 1 1 one two xxx } - do_preupdate_test 7.5.2.2 { UPDATE t8 SET b = 'five' } { UPDATE main t8 2 2 three four xxx } +#---------------------------------------------------------------------------- +# The following tests - hook-8.* - test the transaction hook. +# +db close +forcedelete test.db +sqlite3 db test.db + +proc transaction_hook {op iLevel} { + lappend ::transaction_hook $op $iLevel +} +db transaction_hook transaction_hook + +proc do_transaction_test {tn sql x} { + set X [list] + foreach elem $x {lappend X $elem} + + uplevel do_test $tn [list " + set ::transaction_hook \[list\] + catchsql { $sql } + set ::transaction_hook + "] [list $X] +} + +do_transaction_test 8.1.1 "CREATE TABLE t1(x)" {BEGIN 0 COMMIT 0} +do_transaction_test 8.1.2 "BEGIN" {BEGIN 0} +do_transaction_test 8.1.3 "COMMIT" {COMMIT 0} +do_transaction_test 8.1.4 "BEGIN ; ROLLBACK" {BEGIN 0 ROLLBACK 0} + +do_execsql_test 8.2.0 { + CREATE TABLE t2(a PRIMARY KEY, b); + INSERT INTO t2 VALUES(1, 'one'); + INSERT INTO t2 VALUES(2, 'two'); + INSERT INTO t2 VALUES(3, 'three'); +} +do_transaction_test 8.2.1 { + INSERT INTO t2 VALUES(2, 'xxx') +} {BEGIN 0 ROLLBACK 0} + +do_transaction_test 8.2.2 { + BEGIN; INSERT INTO t2 SELECT a-2, b FROM t2; +} {BEGIN 0 BEGIN 1 ROLLBACK 1} + +do_transaction_test 8.2.3 { + INSERT OR ROLLBACK INTO t2 SELECT a-2, b FROM t2; +} {ROLLBACK 0} + +do_transaction_test 8.2.4 { + BEGIN; INSERT INTO t2 SELECT a+3, b FROM t2; +} {BEGIN 0 BEGIN 1 COMMIT 1} + +do_transaction_test 8.2.5 "COMMIT" {COMMIT 0} + +do_transaction_test 8.3.1 {SELECT * FROM t2} {} + +do_transaction_test 8.4.1 { + SAVEPOINT top; + RELEASE top; +} {BEGIN 0 COMMIT 0} + +do_transaction_test 8.4.2 { + SAVEPOINT top; + ROLLBACK TO top; + RELEASE top; +} {BEGIN 0 ROLLBACK 0 BEGIN 0 COMMIT 0} + +do_transaction_test 8.4.3 { + SAVEPOINT zero; + SAVEPOINT one; + SAVEPOINT two; + SAVEPOINT three; + ROLLBACK TO zero; + SAVEPOINT one; + SAVEPOINT two; + SAVEPOINT three; + ROLLBACK TO one; + SAVEPOINT two; + RELEASE zero; + + SAVEPOINT zero; + SAVEPOINT one; + SAVEPOINT two; + RELEASE two; + SAVEPOINT two; + SAVEPOINT three; + RELEASE one; + ROLLBACK TO zero; + RELEASE zero; +} { + BEGIN 0 BEGIN 1 BEGIN 2 BEGIN 3 ROLLBACK 0 BEGIN 0 + BEGIN 1 BEGIN 2 BEGIN 3 ROLLBACK 1 BEGIN 1 BEGIN 2 + COMMIT 0 + + BEGIN 0 BEGIN 1 BEGIN 2 COMMIT 2 BEGIN 2 BEGIN 3 COMMIT 1 + ROLLBACK 0 BEGIN 0 COMMIT 0 +} + +do_transaction_test 8.4.4 { + BEGIN; + SAVEPOINT zero; + SAVEPOINT one; + SAVEPOINT two; + SAVEPOINT three; + ROLLBACK TO zero; + SAVEPOINT one; + SAVEPOINT two; + SAVEPOINT three; + ROLLBACK TO one; + SAVEPOINT two; + RELEASE zero; + + SAVEPOINT zero; + SAVEPOINT one; + SAVEPOINT two; + RELEASE two; + SAVEPOINT two; + SAVEPOINT three; + RELEASE one; + ROLLBACK TO zero; + RELEASE zero; + COMMIT; +} { + BEGIN 0 + BEGIN 1 BEGIN 2 BEGIN 3 BEGIN 4 ROLLBACK 1 BEGIN 1 + BEGIN 2 BEGIN 3 BEGIN 4 ROLLBACK 2 BEGIN 2 BEGIN 3 + COMMIT 1 + + BEGIN 1 BEGIN 2 BEGIN 3 COMMIT 3 BEGIN 3 BEGIN 4 COMMIT 2 + ROLLBACK 1 BEGIN 1 COMMIT 1 + COMMIT 0 +} + finish_test + diff --git a/test/tclsqlite.test b/test/tclsqlite.test index c9d562beb5..efc3e53ab6 100644 --- a/test/tclsqlite.test +++ b/test/tclsqlite.test @@ -35,7 +35,7 @@ do_test tcl-1.1 { do_test tcl-1.2 { set v [catch {db bogus} msg] lappend v $msg -} {1 {bad option "bogus": must be authorizer, backup, busy, cache, changes, close, collate, collation_needed, commit_hook, complete, copy, enable_load_extension, errorcode, eval, exists, function, incrblob, interrupt, last_insert_rowid, nullvalue, onecolumn, preupdate, profile, progress, rekey, restore, rollback_hook, status, timeout, total_changes, trace, transaction, unlock_notify, update_hook, version, or wal_hook}} +} {1 {bad option "bogus": must be authorizer, backup, busy, cache, changes, close, collate, collation_needed, commit_hook, complete, copy, enable_load_extension, errorcode, eval, exists, function, incrblob, interrupt, last_insert_rowid, nullvalue, onecolumn, preupdate, profile, progress, rekey, restore, rollback_hook, status, timeout, total_changes, trace, transaction, transaction_hook, unlock_notify, update_hook, version, or wal_hook}} do_test tcl-1.2.1 { set v [catch {db cache bogus} msg] lappend v $msg From 4fccf43aaede1a7f2a7b82f9a6a7bb310c2fc132 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 8 Mar 2011 19:22:50 +0000 Subject: [PATCH 0003/1484] Add start of sessions feature. FossilOrigin-Name: 269a81a37d7dbdcdec3c2322074916af0fbac91c --- ext/session/sqlite3session.c | 993 +++++++++++++++++++++++++++++++++++ ext/session/sqlite3session.h | 125 +++++ ext/session/test_session.c | 258 +++++++++ main.mk | 7 +- manifest | 24 +- manifest.uuid | 2 +- src/tclsqlite.c | 6 + src/vdbeInt.h | 1 + src/vdbeapi.c | 8 +- src/vdbeaux.c | 3 + test/session1.test | 118 +++++ 11 files changed, 1525 insertions(+), 20 deletions(-) create mode 100644 ext/session/sqlite3session.c create mode 100644 ext/session/sqlite3session.h create mode 100644 ext/session/test_session.c create mode 100644 test/session1.test diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c new file mode 100644 index 0000000000..eb024775fd --- /dev/null +++ b/ext/session/sqlite3session.c @@ -0,0 +1,993 @@ + +#ifdef SQLITE_ENABLE_SESSION + +#include "sqlite3session.h" +#include +#include + +#include "sqliteInt.h" +#include "vdbeInt.h" + +typedef struct RowChange RowChange; +typedef struct SessionTable SessionTable; +typedef struct SessionChange SessionChange; + +#if 0 +#ifndef SQLITE_AMALGAMATION +typedef unsigned char u8; +typedef unsigned long u32; +typedef sqlite3_uint64 u64; +#endif +#endif + +struct sqlite3_session { + sqlite3 *db; /* Database handle session is attached to */ + char *zDb; /* Name of database session is attached to */ + int rc; /* Non-zero if an error has occurred */ + sqlite3_session *pNext; /* Next session object on same db. */ + SessionTable *pTable; /* List of attached tables */ +}; + +/* +** Each session object maintains a set of the following structures, one +** for each table the session object is monitoring. The structures are +** stored in a linked list starting at sqlite3_session.pTable. +** +** The keys of the SessionTable.aChange[] hash table are all rows that have +** been modified in any way since the session object was attached to the +** table. +** +** The data associated with each hash-table entry is a structure containing +** a subset of the initial values that the modified row contained at the +** start of the session. Or no initial values if the row was inserted. +*/ +struct SessionTable { + SessionTable *pNext; + char *zName; /* Local name of table */ + int nCol; /* Number of columns in table zName */ + + /* Hash table of modified rows */ + int nEntry; /* NUmber of entries in hash table */ + int nChange; /* Size of apChange[] array */ + SessionChange **apChange; /* Hash table buckets */ +}; + +/* +** RECORD FORMAT: +** +** The following record format is similar to (but not compatible with) that +** used in SQLite database files. This format is used as part of the +** change-set binary format, and so must be architecture independent. +** +** Unlike the SQLite database record format, each field is self-contained - +** there is no separation of header and data. Each field begins with a +** single byte describing its type, as follows: +** +** 0x00: Undefined value. +** 0x01: Integer value. +** 0x02: Real value. +** 0x03: Text value. +** 0x04: Blob value. +** 0x05: SQL NULL value. +** +** Note that the above match the definitions of SQLITE_INTEGER, SQLITE_TEXT +** and so on in sqlite3.h. For undefined and NULL values, the field consists +** only of the single type byte. For other types of values, the type byte +** is followed by: +** +** Text values: +** A varint containing the number of bytes in the value (encoded using +** UTF-8). Followed by a buffer containing the UTF-8 representation +** of the text value. There is no nul terminator. +** +** Blob values: +** A varint containing the number of bytes in the value, followed by +** a buffer containing the value itself. +** +** Integer values: +** An 8-byte big-endian integer value. +** +** Real values: +** An 8-byte big-endian IEEE 754-2008 real value. +** +** Varint values are encoded in the same way as varints in the SQLite +** record format. +** +** CHANGESET FORMAT: +** +** A changeset is a collection of DELETE, UPDATE and INSERT operations on +** one or more tables. Operations on a single table are grouped together, +** but may occur in any order (i.e. deletes, updates and inserts are all +** mixed together). +** +** Each group of changes begins with a table header: +** +** 1 byte: Constant 0x54 (capital 'T') +** Varint: Big-endian integer set to the number of columns in the table. +** N bytes: Unqualified table name (encoded using UTF-8). Nul-terminated. +** +** Followed by one or more changes to the table. +** +** 1 byte: Either SQLITE_INSERT, UPDATE or DELETE. +** old.* record: (delete and update only) +** new.* record: (insert and update only) +*/ + +/* +** For each row modified during a session, there exists a single instance of +** this structure stored in a SessionTable.aChange[] hash table. +*/ +struct SessionChange { + sqlite3_int64 iKey; /* Key value */ + int nRecord; /* Number of bytes in buffer aRecord[] */ + u8 *aRecord; /* Buffer containing old.* record */ + SessionChange *pNext; /* For hash-table collisions */ +}; + + +static int sessionVarintPut(u8 *aBuf, u32 iVal){ + if( (iVal & ~0x7F)==0 ){ + if( aBuf ){ + aBuf[0] = (u8)iVal; + } + return 1; + } + if( (iVal & ~0x3FFF)==0 ){ + if( aBuf ){ + aBuf[0] = ((iVal >> 7) & 0x7F) | 0x80; + aBuf[1] = iVal & 0x7F; + } + return 2; + } + if( aBuf ){ + aBuf[0] = ((iVal >> 28) & 0x7F) | 0x80; + aBuf[1] = ((iVal >> 21) & 0x7F) | 0x80; + aBuf[2] = ((iVal >> 14) & 0x7F) | 0x80; + aBuf[3] = ((iVal >> 7) & 0x7F) | 0x80; + aBuf[4] = iVal & 0x7F; + } + return 5; +} + +static int sessionVarintGet(u8 *aBuf, int *piVal){ + int ret; + u64 v; + ret = (int)sqlite3GetVarint(aBuf, &v); + *piVal = (int)v; + return ret; +} + +static sqlite3_int64 sessionGetI64(u8 *aRec){ + return (((sqlite3_int64)aRec[0]) << 56) + + (((sqlite3_int64)aRec[1]) << 48) + + (((sqlite3_int64)aRec[2]) << 40) + + (((sqlite3_int64)aRec[3]) << 32) + + (((sqlite3_int64)aRec[4]) << 24) + + (((sqlite3_int64)aRec[5]) << 16) + + (((sqlite3_int64)aRec[6]) << 8) + + (((sqlite3_int64)aRec[7]) << 0); +} + +/* +** This function is used to serialize the contents of value pValue (see +** comment titled "RECORD FORMAT" above). +** +** If it is non-NULL, the serialized form of the value is written to +** buffer aBuf. *pnWrite is set to the number of bytes written before +** returning. Or, if aBuf is NULL, the only thing this function does is +** set *pnWrite. +** +** If no error occurs, SQLITE_OK is returned. Or, if an OOM error occurs +** within a call to sqlite3_value_text() (may fail if the db is utf-16)) +** SQLITE_NOMEM is returned. +*/ +static int sessionSerializeValue( + u8 *aBuf, /* If non-NULL, write serialized value here */ + sqlite3_value *pValue, /* Value to serialize */ + int *pnWrite /* IN/OUT: Increment by bytes written */ +){ + int eType; + int nByte; + + eType = sqlite3_value_type(pValue); + if( aBuf ) aBuf[0] = eType; + + switch( eType ){ + case SQLITE_NULL: + nByte = 1; + break; + + case SQLITE_INTEGER: + case SQLITE_FLOAT: + if( aBuf ){ + /* TODO: SQLite does something special to deal with mixed-endian + ** floating point values (e.g. ARM7). This code probably should + ** too. */ + u64 i; + if( eType==SQLITE_INTEGER ){ + i = (u64)sqlite3_value_int64(pValue); + }else{ + double r; + assert( sizeof(double)==8 && sizeof(u64)==8 ); + r = sqlite3_value_double(pValue); + memcpy(&i, &r, 8); + } + aBuf[1] = (i>>56) & 0xFF; + aBuf[2] = (i>>48) & 0xFF; + aBuf[3] = (i>>40) & 0xFF; + aBuf[4] = (i>>32) & 0xFF; + aBuf[5] = (i>>24) & 0xFF; + aBuf[6] = (i>>16) & 0xFF; + aBuf[7] = (i>> 8) & 0xFF; + aBuf[8] = (i>> 0) & 0xFF; + } + nByte = 9; + break; + + case SQLITE_TEXT: + case SQLITE_BLOB: { + int n = sqlite3_value_bytes(pValue); + int nVarint = sessionVarintPut(0, n); + if( aBuf ){ + sessionVarintPut(&aBuf[1], n); + memcpy(&aBuf[nVarint + 1], eType==SQLITE_TEXT ? + sqlite3_value_text(pValue) : sqlite3_value_blob(pValue), n + ); + } + + nByte = 1 + nVarint + n; + break; + } + } + + *pnWrite += nByte; + return SQLITE_OK; +} + +/* +** Return the hash of iKey, assuming there are nBucket hash buckets in +** the hash table. +*/ +static int sessionKeyhash(int nBucket, sqlite3_int64 iKey){ + return (iKey % nBucket); +} + +/* +** If required, grow the hash table used to store changes on table pTab +** (part of the session pSession). If a fatal OOM error occurs, set the +** session object to failed and return SQLITE_ERROR. Otherwise, return +** SQLITE_OK. +** +** It is possible that a non-fatal OOM error occurs in this function. In +** that case the hash-table does not grow, but SQLITE_OK is returned anyway. +** Growing the hash table in this case is a performance optimization only, +** it is not required for correct operation. +*/ +static int sessionGrowHash(sqlite3_session *pSession, SessionTable *pTab){ + if( pTab->nChange==0 || pTab->nEntry>=(pTab->nChange/2) ){ + int i; + SessionChange **apNew; + int nNew = (pTab->nChange ? pTab->nChange : 128) * 2; + + apNew = (SessionChange **)sqlite3_malloc(sizeof(SessionChange *) * nNew); + if( apNew==0 ){ + if( pTab->nChange==0 ){ + pSession->rc = SQLITE_NOMEM; + return SQLITE_ERROR; + } + return SQLITE_OK; + } + memset(apNew, 0, sizeof(SessionChange *) * nNew); + + for(i=0; inChange; i++){ + SessionChange *p; + SessionChange *pNext; + for(p=pTab->apChange[i]; p; p=pNext){ + int iHash = sessionKeyhash(nNew, p->iKey); + pNext = p->pNext; + p->pNext = apNew[iHash]; + apNew[iHash] = p; + } + } + + sqlite3_free(pTab->apChange); + pTab->nChange = nNew; + pTab->apChange = apNew; + } + + return SQLITE_OK; +} + +static int sessionInitTable(sqlite3_session *pSession, SessionTable *pTab){ + if( pTab->nCol==0 ){ + pTab->nCol = sqlite3_preupdate_count(pSession->db); + } + + if( pTab->nCol!=sqlite3_preupdate_count(pSession->db) ){ + pSession->rc = SQLITE_SCHEMA; + return SQLITE_ERROR; + } + + return SQLITE_OK; +} + +/* +** The 'pre-update' hook registered by this module with SQLite databases. +*/ +static void xPreUpdate( + void *pCtx, /* Copy of third arg to preupdate_hook() */ + sqlite3 *db, /* Database handle */ + int op, /* SQLITE_UPDATE, DELETE or INSERT */ + char const *zDb, /* Database name */ + char const *zName, /* Table name */ + sqlite3_int64 iKey1, /* Rowid of row about to be deleted/updated */ + sqlite3_int64 iKey2 /* New rowid value (for a rowid UPDATE) */ +){ + sqlite3_session *pSession; + int nDb = strlen(zDb); + int nName = strlen(zDb); + + for(pSession=(sqlite3_session *)pCtx; pSession; pSession=pSession->pNext){ + SessionTable *pTab; + if( pSession->rc ) continue; + if( sqlite3_strnicmp(zDb, pSession->zDb, nDb+1) ) continue; + for(pTab=pSession->pTable; pTab; pTab=pTab->pNext){ + if( 0==sqlite3_strnicmp(pTab->zName, zName, nName+1) ){ + SessionChange *pChange; + SessionChange *pC; + int iHash; + int rc = SQLITE_OK; + + /* Load table details if required */ + if( sessionInitTable(pSession, pTab) ) return; + + /* Grow the hash table if required */ + if( sessionGrowHash(pSession, pTab) ) return; + + /* Search the hash table for an existing entry for rowid=iKey2. If + ** one is found, store a pointer to it in pChange and unlink it from + ** the hash table. Otherwise, set pChange to NULL. + */ + iHash = sessionKeyhash(pTab->nChange, iKey2); + for(pC=pTab->apChange[iHash]; pC; pC=pC->pNext){ + if( pC->iKey==iKey2 ) break; + } + if( pC ) continue; + + pTab->nEntry++; + + /* Create a new change object containing all the old values (if + ** this is an SQLITE_UPDATE or SQLITE_DELETE), or no record at + ** all (if this is an INSERT). */ + if( op==SQLITE_INSERT ){ + pChange = (SessionChange *)sqlite3_malloc(sizeof(SessionChange)); + if( pChange ){ + memset(pChange, 0, sizeof(SessionChange)); + } + }else{ + int nByte; /* Number of bytes to allocate */ + int i; /* Used to iterate through columns */ + sqlite3_value *pValue; + + /* Figure out how large an allocation is required */ + nByte = sizeof(SessionChange); + for(i=0; inCol && rc==SQLITE_OK; i++){ + rc = sqlite3_preupdate_old(pSession->db, i, &pValue); + if( rc==SQLITE_OK ){ + rc = sessionSerializeValue(0, pValue, &nByte); + } + } + + /* Allocate the change object */ + pChange = (SessionChange *)sqlite3_malloc(nByte); + if( !pChange ){ + rc = SQLITE_NOMEM; + }else{ + memset(pChange, 0, sizeof(SessionChange)); + pChange->aRecord = (u8 *)&pChange[1]; + } + + /* Populate the change object */ + nByte = 0; + for(i=0; inCol && rc==SQLITE_OK; i++){ + rc = sqlite3_preupdate_old(pSession->db, i, &pValue); + if( rc==SQLITE_OK ){ + rc = sessionSerializeValue( + &pChange->aRecord[nByte], pValue, &nByte); + } + } + pChange->nRecord = nByte; + } + + /* If an error has occurred, mark the session object as failed. */ + if( rc!=SQLITE_OK ){ + sqlite3_free(pChange); + pSession->rc = rc; + return; + } + + /* Add the change back to the hash-table */ + pChange->iKey = iKey2; + pChange->pNext = pTab->apChange[iHash]; + pTab->apChange[iHash] = pChange; + } + break; + } + } +} + +/* +** Create a session object. This session object will record changes to +** database zDb attached to connection db. +*/ +int sqlite3session_create( + sqlite3 *db, /* Database handle */ + const char *zDb, /* Name of db (e.g. "main") */ + sqlite3_session **ppSession /* OUT: New session object */ +){ + sqlite3_session *pNew; + sqlite3_session *pOld; + int nDb = strlen(zDb); /* Length of zDb in bytes */ + + *ppSession = 0; + + /* Allocate and populate the new session object. */ + pNew = (sqlite3_session *)sqlite3_malloc(sizeof(sqlite3_session) + nDb + 1); + if( !pNew ) return SQLITE_NOMEM; + memset(pNew, 0, sizeof(sqlite3_session)); + pNew->db = db; + pNew->zDb = (char *)&pNew[1]; + memcpy(pNew->zDb, zDb, nDb+1); + + /* Add the new session object to the linked list of session objects + ** attached to database handle $db. Do this under the cover of the db + ** handle mutex. */ + sqlite3_mutex_enter(sqlite3_db_mutex(db)); + pOld = (sqlite3_session*)sqlite3_preupdate_hook(db, xPreUpdate, (void*)pNew); + pNew->pNext = pOld; + sqlite3_mutex_leave(sqlite3_db_mutex(db)); + + *ppSession = pNew; + return SQLITE_OK; +} + +/* +** Delete a session object previously allocated using sqlite3session_create(). +*/ +void sqlite3session_delete(sqlite3_session *pSession){ + sqlite3 *db = pSession->db; + sqlite3_session *pHead; + sqlite3_session **pp; + + sqlite3_mutex_enter(sqlite3_db_mutex(db)); + pHead = (sqlite3_session*)sqlite3_preupdate_hook(db, 0, 0); + for(pp=&pHead; (*pp)!=pSession; pp=&((*pp)->pNext)); + *pp = (*pp)->pNext; + if( pHead ) sqlite3_preupdate_hook(db, xPreUpdate, (void *)pHead); + sqlite3_mutex_leave(sqlite3_db_mutex(db)); + + while( pSession->pTable ){ + int i; + SessionTable *pTab = pSession->pTable; + pSession->pTable = pTab->pNext; + for(i=0; inChange; i++){ + SessionChange *p; + SessionChange *pNext; + for(p=pTab->apChange[i]; p; p=pNext){ + pNext = p->pNext; + sqlite3_free(p); + } + } + sqlite3_free(pTab->apChange); + sqlite3_free(pTab); + } + + sqlite3_free(pSession); +} + +/* +** Attach a table to a session. All subsequent changes made to the table +** while the session object is enabled will be recorded. +** +** Only tables that have a PRIMARY KEY defined may be attached. It does +** not matter if the PRIMARY KEY is an "INTEGER PRIMARY KEY" (rowid alias) +** or not. +*/ +int sqlite3session_attach( + sqlite3_session *pSession, /* Session object */ + const char *zName /* Table name */ +){ + SessionTable *pTab; + int nName; + + /* First search for an existing entry. If one is found, this call is + ** a no-op. Return early. */ + nName = strlen(zName); + for(pTab=pSession->pTable; pTab; pTab=pTab->pNext){ + if( 0==sqlite3_strnicmp(pTab->zName, zName, nName+1) ){ + return SQLITE_OK; + } + } + + /* Allocate new SessionTable object. */ + pTab = (SessionTable *)sqlite3_malloc(sizeof(SessionTable) + nName + 1); + if( !pTab ) return SQLITE_NOMEM; + + /* Populate the new SessionTable object and link it into the list. */ + memset(pTab, 0, sizeof(SessionTable)); + pTab->zName = (char *)&pTab[1]; + memcpy(pTab->zName, zName, nName+1); + pTab->pNext = pSession->pTable; + pSession->pTable = pTab; + + return SQLITE_OK; +} + +typedef struct SessionBuffer SessionBuffer; +struct SessionBuffer { + u8 *aBuf; /* Pointer to changeset buffer */ + int nBuf; /* Size of buffer aBuf */ + int nAlloc; /* Size of allocation containing aBuf */ +}; + +static int sessionBufferGrow(SessionBuffer *p, int nByte, int *pRc){ + if( p->nAlloc-p->nBufnAlloc ? p->nAlloc : 128; + do { + nNew = nNew*2; + }while( nNew<(p->nAlloc+nByte) ); + + aNew = (u8 *)sqlite3_realloc(p->aBuf, nNew); + if( 0==aNew ){ + *pRc = SQLITE_NOMEM; + return 1; + } + p->aBuf = aNew; + p->nAlloc = nNew; + } + return 0; +} + +static void sessionAppendByte(SessionBuffer *p, u8 v, int *pRc){ + if( *pRc==SQLITE_OK && 0==sessionBufferGrow(p, 1, pRc) ){ + p->aBuf[p->nBuf++] = v; + } +} + +static void sessionAppendVarint(SessionBuffer *p, sqlite3_int64 v, int *pRc){ + if( *pRc==SQLITE_OK && 0==sessionBufferGrow(p, 9, pRc) ){ + p->nBuf += sessionVarintPut(&p->aBuf[p->nBuf], v); + } +} + +static void sessionAppendBlob( + SessionBuffer *p, + const u8 *aBlob, + int nBlob, + int *pRc +){ + if( *pRc==SQLITE_OK && 0==sessionBufferGrow(p, nBlob, pRc) ){ + memcpy(&p->aBuf[p->nBuf], aBlob, nBlob); + p->nBuf += nBlob; + } +} + +static void sessionAppendCol( + SessionBuffer *p, + sqlite3_stmt *pStmt, + int iCol, + int *pRc +){ + if( *pRc==SQLITE_OK ){ + int eType = sqlite3_column_type(pStmt, iCol); + sessionAppendByte(p, (u8)eType, pRc); + if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){ + sqlite3_int64 i; + u8 aBuf[8]; + if( eType==SQLITE_INTEGER ){ + i = sqlite3_column_int64(pStmt, iCol); + }else{ + double r = sqlite3_column_double(pStmt, iCol); + memcpy(&i, &r, 8); + } + aBuf[0] = (i>>56) & 0xFF; + aBuf[1] = (i>>48) & 0xFF; + aBuf[2] = (i>>40) & 0xFF; + aBuf[3] = (i>>32) & 0xFF; + aBuf[4] = (i>>24) & 0xFF; + aBuf[5] = (i>>16) & 0xFF; + aBuf[6] = (i>> 8) & 0xFF; + aBuf[7] = (i>> 0) & 0xFF; + sessionAppendBlob(p, aBuf, 8, pRc); + } + if( eType==SQLITE_BLOB || eType==SQLITE_TEXT ){ + int nByte = sqlite3_column_bytes(pStmt, iCol); + sessionAppendVarint(p, nByte, pRc); + sessionAppendBlob(p, eType==SQLITE_BLOB ? + sqlite3_column_blob(pStmt, iCol) : sqlite3_column_text(pStmt, iCol), + nByte, pRc + ); + } + } +} + +static void sessionAppendUpdate( + sqlite3_stmt *pStmt, + SessionBuffer *pBuf, + SessionChange *p, + int *pRc +){ + if( *pRc==SQLITE_OK ){ + SessionBuffer buf2 = {0, 0, 0}; + int bNoop = 1; + int i; + u8 *pCsr = p->aRecord; + sessionAppendByte(pBuf, SQLITE_UPDATE, pRc); + for(i=0; inBuf -= (1 + sqlite3_column_count(pStmt)); + }else{ + sessionAppendBlob(pBuf, buf2.aBuf, buf2.nBuf, pRc); + sqlite3_free(buf2.aBuf); + } + } + + +} + +/* +** Obtain a changeset object containing all changes recorded by the +** session object passed as the first argument. +** +** It is the responsibility of the caller to eventually free the buffer +** using sqlite3_free(). +*/ +int sqlite3session_changeset( + sqlite3_session *pSession, /* Session object */ + int *pnChangeset, /* OUT: Size of buffer at *ppChangeset */ + void **ppChangeset /* OUT: Buffer containing changeset */ +){ + sqlite3 *db = pSession->db; + SessionTable *pTab; + SessionBuffer buf = {0, 0, 0}; + int rc; + + *pnChangeset = 0; + *ppChangeset = 0; + rc = pSession->rc; + + for(pTab=pSession->pTable; rc==SQLITE_OK && pTab; pTab=pTab->pNext){ + if( pTab->nEntry ){ + int i; + sqlite3_stmt *pStmt = 0; + int bNoop = 1; + int nRewind = buf.nBuf; + + /* Write a table header */ + sessionAppendByte(&buf, 'T', &rc); + sessionAppendVarint(&buf, pTab->nCol, &rc); + sessionAppendBlob(&buf, (u8 *)pTab->zName, strlen(pTab->zName)+1, &rc); + + /* Build and compile a statement to execute: */ + if( rc==SQLITE_OK ){ + char *zSql = sqlite3_mprintf("SELECT * FROM %Q.%Q WHERE _rowid_ = ?", + pSession->zDb, pTab->zName + ); + if( !zSql ){ + rc = SQLITE_NOMEM; + }else{ + rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); + } + sqlite3_free(zSql); + } + + if( rc==SQLITE_OK && pTab->nCol!=sqlite3_column_count(pStmt) ){ + rc = SQLITE_SCHEMA; + } + + for(i=0; inChange; i++){ + SessionChange *p; + for(p=pTab->apChange[i]; rc==SQLITE_OK && p; p=p->pNext){ + sqlite3_bind_int64(pStmt, 1, p->iKey); + if( sqlite3_step(pStmt)==SQLITE_ROW ){ + int iCol; + if( p->aRecord ){ + sessionAppendUpdate(pStmt, &buf, p, &rc); + }else{ + sessionAppendByte(&buf, SQLITE_INSERT, &rc); + for(iCol=0; iColnCol; iCol++){ + sessionAppendCol(&buf, pStmt, iCol, &rc); + } + } + bNoop = 0; + }else if( p->aRecord ){ + /* A DELETE change */ + sessionAppendByte(&buf, SQLITE_DELETE, &rc); + sessionAppendBlob(&buf, p->aRecord, p->nRecord, &rc); + bNoop = 0; + } + rc = sqlite3_reset(pStmt); + } + } + + sqlite3_finalize(pStmt); + + if( bNoop ){ + buf.nBuf = nRewind; + } + } + } + + if( rc==SQLITE_OK ){ + *pnChangeset = buf.nBuf; + *ppChangeset = buf.aBuf; + }else{ + sqlite3_free(buf.aBuf); + } + + return rc; +} + +int sqlite3session_enable(sqlite3_session *pSession, int bEnable){ + return bEnable; +} + +/************************************************************************/ +/************************************************************************/ +/************************************************************************/ + +struct sqlite3_changeset_iter { + u8 *aChangeset; /* Pointer to buffer containing changeset */ + int nChangeset; /* Number of bytes in aChangeset */ + u8 *pNext; /* Pointer to next change within aChangeset */ + int rc; + + char *zTab; /* Current table */ + int nCol; /* Number of columns in zTab */ + int op; /* Current operation */ + sqlite3_value **apValue; /* old.* and new.* values */ +}; + +/* +** Create an iterator used to iterate through the contents of a changeset. +*/ +int sqlite3changeset_start( + sqlite3_changeset_iter **ppIter, + int nChangeset, + void *pChangeset +){ + sqlite3_changeset_iter *pRet; /* Iterator to return */ + int nByte; /* Number of bytes to allocate for iterator */ + + *ppIter = 0; + + nByte = sizeof(sqlite3_changeset_iter); + pRet = (sqlite3_changeset_iter *)sqlite3_malloc(nByte); + if( !pRet ) return SQLITE_NOMEM; + memset(pRet, 0, sizeof(sqlite3_changeset_iter)); + + pRet->aChangeset = (u8 *)pChangeset; + pRet->nChangeset = nChangeset; + pRet->pNext = pRet->aChangeset; + + *ppIter = pRet; + return SQLITE_OK; +} + +static int sessionReadRecord( + u8 **paChange, /* IN/OUT: Pointer to binary record */ + int nCol, /* Number of values in record */ + sqlite3_value **apOut /* Write values to this array */ +){ + int i; + u8 *aRec = *paChange; + + for(i=0; irc!=SQLITE_OK ) return p->rc; + + if( p->apValue ){ + for(i=0; inCol*2; i++){ + sqlite3ValueFree(p->apValue[i]); + } + memset(p->apValue, 0, sizeof(sqlite3_value*)*p->nCol*2); + } + + /* If the iterator is already at the end of the changeset, return DONE. */ + if( p->pNext>=&p->aChangeset[p->nChangeset] ){ + return SQLITE_DONE; + } + aChange = p->pNext; + + c = *(aChange++); + if( c=='T' ){ + int nByte; /* Bytes to allocate for apValue */ + aChange += sessionVarintGet(aChange, &p->nCol); + p->zTab = (char *)aChange; + aChange += (strlen((char *)aChange) + 1); + p->op = *(aChange++); + sqlite3_free(p->apValue); + nByte = sizeof(sqlite3_value *) * p->nCol * 2; + p->apValue = (sqlite3_value **)sqlite3_malloc(nByte); + if( !p->apValue ){ + return (p->rc = SQLITE_NOMEM); + } + memset(p->apValue, 0, sizeof(sqlite3_value*)*p->nCol*2); + }else{ + p->op = c; + } + if( p->op!=SQLITE_UPDATE && p->op!=SQLITE_DELETE && p->op!=SQLITE_INSERT ){ + return (p->rc = SQLITE_CORRUPT); + } + + /* If this is an UPDATE or DELETE, read the old.* record. */ + if( p->op!=SQLITE_INSERT ){ + p->rc = sessionReadRecord(&aChange, p->nCol, p->apValue); + if( p->rc!=SQLITE_OK ) return p->rc; + } + + /* If this is an INSERT or UPDATE, read the new.* record. */ + if( p->op!=SQLITE_DELETE ){ + p->rc = sessionReadRecord(&aChange, p->nCol, &p->apValue[p->nCol]); + if( p->rc!=SQLITE_OK ) return p->rc; + } + + p->pNext = aChange; + return SQLITE_ROW; +} + +/* +** The following three functions extract information on the current change +** from a changeset iterator. They may only be called after changeset_next() +** has returned SQLITE_ROW. +*/ +int sqlite3changeset_op( + sqlite3_changeset_iter *pIter, + const char **pzTab, /* OUT: Pointer to table name */ + int *pnCol, /* OUT: Number of columns in table */ + int *pOp /* OUT: SQLITE_INSERT, DELETE or UPDATE */ +){ + *pOp = pIter->op; + *pnCol = pIter->nCol; + *pzTab = pIter->zTab; + return SQLITE_OK; +} + +int sqlite3changeset_old( + sqlite3_changeset_iter *pIter, + int iVal, + sqlite3_value **ppValue /* OUT: Old value (or NULL pointer) */ +){ + if( iVal<0 || iVal>=pIter->nCol ){ + return SQLITE_RANGE; + } + *ppValue = pIter->apValue[iVal]; + return SQLITE_OK; +} + +int sqlite3changeset_new( + sqlite3_changeset_iter *pIter, + int iVal, + sqlite3_value **ppValue /* OUT: New value (or NULL pointer) */ +){ + if( iVal<0 || iVal>=pIter->nCol ){ + return SQLITE_RANGE; + } + *ppValue = pIter->apValue[pIter->nCol+iVal]; + return SQLITE_OK; +} + +/* +** Finalize an iterator allocated with sqlite3changeset_start(). +** +** This function may not be called on iterators passed to a conflict handler +** callback by changeset_apply(). +*/ +int sqlite3changeset_finalize(sqlite3_changeset_iter *p){ + int i; + int rc = p->rc; + for(i=0; inCol*2; i++) sqlite3ValueFree(p->apValue[i]); + sqlite3_free(p->apValue); + sqlite3_free(p); + return rc; +} + +#endif /* #ifdef SQLITE_ENABLE_SESSION */ diff --git a/ext/session/sqlite3session.h b/ext/session/sqlite3session.h new file mode 100644 index 0000000000..a62b8b654e --- /dev/null +++ b/ext/session/sqlite3session.h @@ -0,0 +1,125 @@ + +#ifndef __SQLITESESSION_H_ +#define __SQLITESESSION_H_ 1 + +/* +** Make sure we can call this stuff from C++. +*/ +#ifdef __cplusplus +extern "C" { +#endif + +#include "sqlite3.h" + +typedef struct sqlite3_session sqlite3_session; +typedef struct sqlite3_changeset_iter sqlite3_changeset_iter; + +/* +** Create a session object. This session object will record changes to +** database zDb attached to connection db. +*/ +int sqlite3session_create( + sqlite3 *db, /* Database handle */ + const char *zDb, /* Name of db (e.g. "main") */ + sqlite3_session **ppSession /* OUT: New session object */ +); + +/* +** Enable or disable the recording of changes by a session object. When +** enabled, a session object records changes made to the database. When +** disabled - it does not. A newly created session object is enabled. +** +** Passing zero to this function disables the session. Passing a value +** greater than zero enables it. Passing a value less than zero is a +** no-op, and may be used to query the current state of the session. +** +** The return value indicates the final state of the session object: 0 if +** the session is disabled, or 1 if it is enabled. +*/ +int sqlite3session_enable(sqlite3_session *pSession, int bEnable); + +/* +** Attach a table to a session. All subsequent changes made to the table +** while the session object is enabled will be recorded. +** +** Only tables that have a PRIMARY KEY defined may be attached. It does +** not matter if the PRIMARY KEY is an "INTEGER PRIMARY KEY" (rowid alias) +** or not. +*/ +int sqlite3session_attach( + sqlite3_session *pSession, /* Session object */ + const char *zTab /* Table name */ +); + +/* +** Obtain a changeset object containing all changes recorded by the +** session object passed as the first argument. +** +** It is the responsibility of the caller to eventually free the buffer +** using sqlite3_free(). +*/ +int sqlite3session_changeset( + sqlite3_session *pSession, /* Session object */ + int *pnChangeset, /* OUT: Size of buffer at *ppChangeset */ + void **ppChangeset /* OUT: Buffer containing changeset */ +); + +/* +** Delete a session object previously allocated using sqlite3session_create(). +*/ +void sqlite3session_delete(sqlite3_session *pSession); + + +/* +** Create an iterator used to iterate through the contents of a changeset. +*/ +int sqlite3changeset_start( + sqlite3_changeset_iter **ppIter, + int nChangeset, + void *pChangeset +); + +/* +** Advance an iterator created by sqlite3changeset_start() to the next +** change in the changeset. This function may return SQLITE_ROW, SQLITE_DONE +** or SQLITE_CORRUPT. +** +** This function may not be called on iterators passed to a conflict handler +** callback by changeset_apply(). +*/ +int sqlite3changeset_next(sqlite3_changeset_iter *pIter); + +/* +** The following three functions extract information on the current change +** from a changeset iterator. They may only be called after changeset_next() +** has returned SQLITE_ROW. +*/ +int sqlite3changeset_op( + sqlite3_changeset_iter *pIter, /* Iterator object */ + const char **pzTab, /* OUT: Pointer to table name */ + int *pnCol, /* OUT: Number of columns in table */ + int *pOp /* OUT: SQLITE_INSERT, DELETE or UPDATE */ +); + +int sqlite3changeset_old( + sqlite3_changeset_iter *pIter, + int iVal, + sqlite3_value **ppValue /* OUT: Old value (or NULL pointer) */ +); + +int sqlite3changeset_new( + sqlite3_changeset_iter *pIter, + int iVal, + sqlite3_value **ppValue /* OUT: New value (or NULL pointer) */ +); + +/* +** Finalize an iterator allocated with sqlite3changeset_start(). +** +** This function may not be called on iterators passed to a conflict handler +** callback by changeset_apply(). +*/ +int sqlite3changeset_finalize(sqlite3_changeset_iter *pIter); + +#endif + diff --git a/ext/session/test_session.c b/ext/session/test_session.c new file mode 100644 index 0000000000..9c37fdb285 --- /dev/null +++ b/ext/session/test_session.c @@ -0,0 +1,258 @@ + +#if defined(SQLITE_TEST) && defined(SQLITE_ENABLE_SESSION) + +#include "sqlite3session.h" +#include +#include +#include + +static int test_session_error(Tcl_Interp *interp, int rc){ + extern const char *sqlite3TestErrorName(int); + Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3TestErrorName(rc), -1)); + return TCL_ERROR; +} + +/* +** Tclcmd: $session attach TABLE +** $session changeset +** $session delete +** $session enable BOOL +*/ +static int test_session_cmd( + void *clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + sqlite3_session *pSession = (sqlite3_session *)clientData; + struct SessionSubcmd { + const char *zSub; + int nArg; + const char *zMsg; + int iSub; + } aSub[] = { + { "attach", 1, "TABLE", }, /* 0 */ + { "changeset", 0, "", }, /* 1 */ + { "delete", 0, "", }, /* 2 */ + { "enable", 1, "", }, /* 3 */ + { 0 } + }; + int iSub; + int rc; + + if( objc<2 ){ + Tcl_WrongNumArgs(interp, 1, objv, "SUBCOMMAND ..."); + return TCL_ERROR; + } + rc = Tcl_GetIndexFromObjStruct(interp, + objv[1], aSub, sizeof(aSub[0]), "sub-command", 0, &iSub + ); + if( rc!=TCL_OK ) return rc; + if( objc!=2+aSub[iSub].nArg ){ + Tcl_WrongNumArgs(interp, 2, objv, aSub[iSub].zMsg); + return TCL_ERROR; + } + + switch( iSub ){ + case 0: /* attach */ + rc = sqlite3session_attach(pSession, Tcl_GetString(objv[2])); + if( rc!=SQLITE_OK ){ + return test_session_error(interp, rc); + } + break; + + case 1: { /* changeset */ + int nChange; + void *pChange; + rc = sqlite3session_changeset(pSession, &nChange, &pChange); + if( rc==SQLITE_OK ){ + Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(pChange, nChange)); + sqlite3_free(pChange); + }else{ + return test_session_error(interp, rc); + } + break; + } + + case 2: /* delete */ + Tcl_DeleteCommand(interp, Tcl_GetString(objv[0])); + break; + + case 3: { /* enable */ + int val; + if( Tcl_GetBooleanFromObj(interp, objv[2], &val) ) return TCL_ERROR; + val = sqlite3session_enable(pSession, val); + Tcl_SetObjResult(interp, Tcl_NewBooleanObj(val)); + break; + } + } + + return TCL_OK; +} + +static void test_session_del(void *clientData){ + sqlite3_session *pSession = (sqlite3_session *)clientData; + sqlite3session_delete(pSession); +} + +/* +** Tclcmd: sqlite3session CMD DB-HANDLE DB-NAME +*/ +static int test_sqlite3session( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + sqlite3 *db; + Tcl_CmdInfo info; + int rc; /* sqlite3session_create() return code */ + sqlite3_session *pSession; /* New session object */ + + if( objc!=4 ){ + Tcl_WrongNumArgs(interp, 1, objv, "CMD DB-HANDLE DB-NAME"); + return TCL_ERROR; + } + + if( 0==Tcl_GetCommandInfo(interp, Tcl_GetString(objv[2]), &info) ){ + Tcl_AppendResult(interp, "no such handle: ", Tcl_GetString(objv[2]), 0); + return TCL_ERROR; + } + db = *(sqlite3 **)info.objClientData; + + rc = sqlite3session_create(db, Tcl_GetString(objv[3]), &pSession); + if( rc!=SQLITE_OK ){ + return test_session_error(interp, rc); + } + + Tcl_CreateObjCommand( + interp, Tcl_GetString(objv[1]), test_session_cmd, (ClientData)pSession, + test_session_del + ); + Tcl_SetObjResult(interp, objv[1]); + return TCL_OK; +} + +static void test_append_value(Tcl_Obj *pList, sqlite3_value *pVal){ + if( pVal==0 ){ + Tcl_ListObjAppendElement(0, pList, Tcl_NewObj()); + Tcl_ListObjAppendElement(0, pList, Tcl_NewObj()); + }else{ + Tcl_Obj *pObj; + switch( sqlite3_value_type(pVal) ){ + case SQLITE_NULL: + Tcl_ListObjAppendElement(0, pList, Tcl_NewStringObj("n", 1)); + pObj = Tcl_NewObj(); + break; + case SQLITE_INTEGER: + Tcl_ListObjAppendElement(0, pList, Tcl_NewStringObj("i", 1)); + pObj = Tcl_NewWideIntObj(sqlite3_value_int64(pVal)); + break; + case SQLITE_FLOAT: + Tcl_ListObjAppendElement(0, pList, Tcl_NewStringObj("f", 1)); + pObj = Tcl_NewDoubleObj(sqlite3_value_double(pVal)); + break; + case SQLITE_TEXT: + Tcl_ListObjAppendElement(0, pList, Tcl_NewStringObj("t", 1)); + pObj = Tcl_NewStringObj((char *)sqlite3_value_text(pVal), -1); + break; + case SQLITE_BLOB: + Tcl_ListObjAppendElement(0, pList, Tcl_NewStringObj("b", 1)); + pObj = Tcl_NewByteArrayObj( + sqlite3_value_blob(pVal), + sqlite3_value_bytes(pVal) + ); + break; + } + Tcl_ListObjAppendElement(0, pList, pObj); + } +} + +/* +** sqlite3session_foreach VARNAME CHANGESET SCRIPT +*/ +static int test_sqlite3session_foreach( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + void *pChangeSet; + int nChangeSet; + sqlite3_changeset_iter *pIter; + int rc; + + if( objc!=4 ){ + Tcl_WrongNumArgs(interp, 1, objv, "VARNAME CHANGESET SCRIPT"); + return TCL_ERROR; + } + + pChangeSet = (void *)Tcl_GetByteArrayFromObj(objv[2], &nChangeSet); + rc = sqlite3changeset_start(&pIter, nChangeSet, pChangeSet); + if( rc!=SQLITE_OK ){ + return test_session_error(interp, rc); + } + + while( SQLITE_ROW==sqlite3changeset_next(pIter) ){ + int nCol; /* Number of columns in table */ + int op; /* SQLITE_INSERT, UPDATE or DELETE */ + const char *zTab; /* Name of table change applies to */ + Tcl_Obj *pVar; /* Tcl value to set $VARNAME to */ + Tcl_Obj *pOld; /* Vector of old.* values */ + Tcl_Obj *pNew; /* Vector of new.* values */ + + sqlite3changeset_op(pIter, &zTab, &nCol, &op); + pVar = Tcl_NewObj(); + Tcl_ListObjAppendElement(0, pVar, Tcl_NewStringObj( + op==SQLITE_INSERT ? "INSERT" : + op==SQLITE_UPDATE ? "UPDATE" : + "DELETE", -1 + )); + Tcl_ListObjAppendElement(0, pVar, Tcl_NewStringObj(zTab, -1)); + + pOld = Tcl_NewObj(); + if( op!=SQLITE_INSERT ){ + int i; + for(i=0; ipUnpacked==0 ){ - KeyInfo keyinfo; u32 nRecord; u8 *aRecord; - memset(&keyinfo, 0, sizeof(KeyInfo)); - keyinfo.db = db; - keyinfo.enc = ENC(db); - keyinfo.nField = p->pCsr->nField; - rc = sqlite3BtreeDataSize(p->pCsr->pCursor, &nRecord); if( rc!=SQLITE_OK ) goto preupdate_old_out; aRecord = sqlite3DbMallocRaw(db, nRecord); @@ -1370,7 +1364,7 @@ int sqlite3_preupdate_old(sqlite3 *db, int iIdx, sqlite3_value **ppValue){ goto preupdate_old_out; } - p->pUnpacked = sqlite3VdbeRecordUnpack(&keyinfo, nRecord, aRecord, 0, 0); + p->pUnpacked = sqlite3VdbeRecordUnpack(&p->keyinfo, nRecord, aRecord, 0, 0); p->aRecord = aRecord; } diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 937c2a1998..cb6aefac08 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -3194,6 +3194,9 @@ void sqlite3VdbePreUpdateHook( preupdate.pCsr = pCsr; preupdate.op = op; + preupdate.keyinfo.db = db; + preupdate.keyinfo.enc = ENC(db); + preupdate.keyinfo.nField = pCsr->nField; db->pPreUpdate = &preupdate; db->xPreUpdateCallback(db->pPreUpdateArg, db, op, zDb, zTbl, iKey1, iKey2); db->pPreUpdate = 0; diff --git a/test/session1.test b/test/session1.test new file mode 100644 index 0000000000..0cb225a2fd --- /dev/null +++ b/test/session1.test @@ -0,0 +1,118 @@ +# 2011 March 07 +# +# 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 regression tests for SQLite library. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set ::testprefix session1 + +do_execsql_test 1.0 { + CREATE TABLE t1(x, y); + INSERT INTO t1 VALUES('abc', 'def'); +} + +do_test 1.1 { sqlite3session S db main } {S} +do_test 1.2 { S delete } {} +do_test 1.3 { sqlite3session S db main } {S} +do_test 1.4 { S attach t1 } {} +do_test 1.5 { S delete } {} +do_test 1.6 { sqlite3session S db main } {S} +do_test 1.7 { S attach t1 ; S attach t2 ; S attach t3 } {} +do_test 1.8 { S attach t1 ; S attach t2 ; S attach t3 } {} +do_test 1.9 { S delete } {} +do_test 1.10 { + sqlite3session S db main + S attach t1 + execsql { INSERT INTO t1 VALUES('ghi', 'jkl') } +} {} +do_test 1.11 { S delete } {} +do_test 1.12 { + sqlite3session S db main + S attach t1 + execsql { INSERT INTO t1 VALUES('mno', 'pqr') } + execsql { UPDATE t1 SET x = 111 WHERE rowid = 1 } + execsql { DELETE FROM t1 WHERE rowid = 2 } +} {} +do_test 1.13 { + S changeset + S delete +} {} + +proc do_changeset_test {tn session res} { + set r [list] + foreach x $res {lappend r $x} + uplevel do_test $tn [list [subst -nocommands { + set x [list] + sqlite3session_foreach c [$session changeset] { lappend x [set c] } + set x + }]] [list $r] +} + +do_test 2.1.1 { + execsql { DELETE FROM t1 } + sqlite3session S db main + S attach t1 + execsql { INSERT INTO t1 VALUES(1, 'Sukhothai') } + execsql { INSERT INTO t1 VALUES(2, 'Ayutthaya') } + execsql { INSERT INTO t1 VALUES(3, 'Thonburi') } +} {} +do_changeset_test 2.1.2 S { + {INSERT t1 {} {i 1 t Sukhothai}} + {INSERT t1 {} {i 2 t Ayutthaya}} + {INSERT t1 {} {i 3 t Thonburi}} +} +do_test 2.1.3 { S delete } {} + +do_test 2.2.1 { + sqlite3session S db main + S attach t1 + execsql { DELETE FROM t1 WHERE 1 } +} {} +do_changeset_test 2.2.2 S { + {DELETE t1 {i 1 t Sukhothai} {}} + {DELETE t1 {i 2 t Ayutthaya} {}} + {DELETE t1 {i 3 t Thonburi} {}} +} +do_test 2.2.3 { S delete } {} + +do_test 2.3.1 { + sqlite3session S db main + execsql { INSERT INTO t1 VALUES(1, 'Sukhothai') } + execsql { INSERT INTO t1 VALUES(2, 'Ayutthaya') } + execsql { INSERT INTO t1 VALUES(3, 'Thonburi') } + S attach t1 + execsql { + UPDATE t1 SET x = 10 WHERE x = 1; + UPDATE t1 SET y = 'Surin' WHERE x = 2; + UPDATE t1 SET x = 20, y = 'Thapae' WHERE x = 3; + } +} {} + +do_changeset_test 2.3.2 S { + {UPDATE t1 {i 1 {} {}} {i 10 {} {}}} + {UPDATE t1 {{} {} t Ayutthaya} {{} {} t Surin}} + {UPDATE t1 {i 3 t Thonburi} {i 20 t Thapae}} +} +do_test 2.3.3 { S delete } {} + +do_test 2.4.1 { + sqlite3session S db main + S attach t1 + execsql { INSERT INTO t1 VALUES(100, 'Bangkok') } + execsql { DELETE FROM t1 WHERE x = 100 } +} {} + +breakpoint +do_changeset_test 2.4.2 S {} +do_test 2.4.3 { S delete } {} + +finish_test From 91ddd5595b0a7aaf0183765a705f29a95c6cfb2d Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 9 Mar 2011 11:17:05 +0000 Subject: [PATCH 0004/1484] Add a function to the session extension invert a changeset. FossilOrigin-Name: 75d5dff725dbb66d67d56ad042926f1daae56dbe --- ext/session/sqlite3session.c | 108 +++++++++++++++++++++++++++++++---- ext/session/sqlite3session.h | 9 +++ ext/session/test_session.c | 32 +++++++++++ manifest | 18 +++--- manifest.uuid | 2 +- test/session1.test | 64 +++++++++++++++------ 6 files changed, 195 insertions(+), 38 deletions(-) diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index eb024775fd..0b6a985279 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -839,28 +839,34 @@ static int sessionReadRecord( for(i=0; i Date: Fri, 11 Mar 2011 19:05:52 +0000 Subject: [PATCH 0005/1484] Add the sqlite3changeset_apply() function. Does not yet handle all cases. FossilOrigin-Name: 2b19be7bf753c7dd12e1c3b384981a3ea1bc8145 --- ext/session/sqlite3session.c | 606 ++++++++++++++++++++++++++++++++++- ext/session/sqlite3session.h | 45 +++ ext/session/test_session.c | 137 ++++++++ manifest | 18 +- manifest.uuid | 2 +- test/session1.test | 132 ++++++++ 6 files changed, 924 insertions(+), 16 deletions(-) diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index 0b6a985279..86778d65f0 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -573,6 +573,47 @@ static void sessionAppendBlob( } } +static void sessionAppendStr( + SessionBuffer *p, + const char *zStr, + int *pRc +){ + int nStr = strlen(zStr); + if( *pRc==SQLITE_OK && 0==sessionBufferGrow(p, nStr, pRc) ){ + memcpy(&p->aBuf[p->nBuf], zStr, nStr); + p->nBuf += nStr; + } +} + +static void sessionAppendInteger( + SessionBuffer *p, + int iVal, + int *pRc +){ + char aBuf[24]; + sqlite3_snprintf(sizeof(aBuf)-1, aBuf, "%d", iVal); + sessionAppendStr(p, aBuf, pRc); +} + +static void sessionAppendIdent( + SessionBuffer *p, + const char *zStr, + int *pRc +){ + int nStr = strlen(zStr)*2 + 2 + 1; + if( *pRc==SQLITE_OK && 0==sessionBufferGrow(p, nStr, pRc) ){ + char *zOut = (char *)&p->aBuf[p->nBuf]; + const char *zIn = zStr; + *zOut++ = '"'; + while( *zIn ){ + if( *zIn=='"' ) *zOut++ = '"'; + *zOut++ = *(zIn++); + } + *zOut++ = '"'; + p->nBuf = ((u8 *)zOut - p->aBuf); + } +} + static void sessionAppendCol( SessionBuffer *p, sqlite3_stmt *pStmt, @@ -616,6 +657,7 @@ static void sessionAppendUpdate( sqlite3_stmt *pStmt, SessionBuffer *pBuf, SessionChange *p, + u8 *abPK, int *pRc ){ if( *pRc==SQLITE_OK ){ @@ -667,6 +709,9 @@ static void sessionAppendUpdate( nCopy = nAdvance; } } + if( abPK[i] ){ + nCopy = nAdvance; + } if( nCopy==0 ){ sessionAppendByte(pBuf, 0, pRc); @@ -686,8 +731,98 @@ static void sessionAppendUpdate( sqlite3_free(buf2.aBuf); } } +} +static int sessionTableInfo( + sqlite3 *db, /* Database connection */ + const char *zThis, /* Table name */ + int nCol, /* Expected number of columns */ + const char **pzTab, /* OUT: Copy of zThis */ + const char ***pazCol, /* OUT: Array of column names for table */ + u8 **pabPK /* OUT: Array of booleans - true for PK col */ +){ + char *zPragma; + sqlite3_stmt *pStmt; + int rc; + int nByte; + int nDbCol = 0; + int nThis; + int i; + u8 *pAlloc; + u8 *pFree = 0; + char **azCol; + u8 *abPK; + + nThis = strlen(zThis); + zPragma = sqlite3_mprintf("PRAGMA main.table_info('%q')", zThis); + if( !zPragma ) return SQLITE_NOMEM; + + rc = sqlite3_prepare_v2(db, zPragma, -1, &pStmt, 0); + sqlite3_free(zPragma); + if( rc!=SQLITE_OK ) return rc; + + nByte = nThis + 1; + while( SQLITE_ROW==sqlite3_step(pStmt) ){ + nByte += sqlite3_column_bytes(pStmt, 1); + nDbCol++; + } + rc = sqlite3_reset(pStmt); + + if( nDbCol!=nCol ){ + rc = SQLITE_SCHEMA; + } + if( rc==SQLITE_OK ){ + nByte += nDbCol * (sizeof(const char *) + sizeof(u8) + 1); + pAlloc = sqlite3_malloc(nByte); + if( pAlloc==0 ){ + rc = SQLITE_NOMEM; + } + } + if( rc==SQLITE_OK ){ + pFree = pAlloc; + if( pazCol ){ + azCol = (char **)pAlloc; + pAlloc = (u8 *)&azCol[nCol]; + } + if( pabPK ){ + abPK = (u8 *)pAlloc; + pAlloc = &abPK[nCol]; + } + if( pzTab ){ + memcpy(pAlloc, zThis, nThis+1); + *pzTab = (char *)pAlloc; + pAlloc += nThis+1; + } + + i = 0; + while( SQLITE_ROW==sqlite3_step(pStmt) ){ + int nName = sqlite3_column_bytes(pStmt, 1); + const unsigned char *zName = sqlite3_column_text(pStmt, 1); + if( zName==0 ) break; + if( pazCol ){ + memcpy(pAlloc, zName, nName+1); + azCol[i] = (char *)pAlloc; + pAlloc += nName+1; + } + if( pabPK ) abPK[i] = sqlite3_column_int(pStmt, 5); + i++; + } + rc = sqlite3_reset(pStmt); + + } + if( rc==SQLITE_OK ){ + if( pazCol ) *pazCol = (const char **)azCol; + if( pabPK ) *pabPK = abPK; + }else{ + if( pazCol ) *pazCol = 0; + if( pabPK ) *pabPK = 0; + if( pzTab ) *pzTab = 0; + sqlite3_free(pFree); + } + + sqlite3_finalize(pStmt); + return rc; } /* @@ -717,6 +852,7 @@ int sqlite3session_changeset( sqlite3_stmt *pStmt = 0; int bNoop = 1; int nRewind = buf.nBuf; + u8 *abPK = 0; /* Write a table header */ sessionAppendByte(&buf, 'T', &rc); @@ -740,6 +876,10 @@ int sqlite3session_changeset( rc = SQLITE_SCHEMA; } + if( rc==SQLITE_OK ){ + rc = sessionTableInfo(db, pTab->zName, pTab->nCol, 0, 0, &abPK); + } + for(i=0; inChange; i++){ SessionChange *p; for(p=pTab->apChange[i]; rc==SQLITE_OK && p; p=p->pNext){ @@ -747,7 +887,7 @@ int sqlite3session_changeset( if( sqlite3_step(pStmt)==SQLITE_ROW ){ int iCol; if( p->aRecord ){ - sessionAppendUpdate(pStmt, &buf, p, &rc); + sessionAppendUpdate(pStmt, &buf, p, abPK, &rc); }else{ sessionAppendByte(&buf, SQLITE_INSERT, &rc); for(iCol=0; iColnCol; iCol++){ @@ -766,6 +906,7 @@ int sqlite3session_changeset( } sqlite3_finalize(pStmt); + sqlite3_free(abPK); if( bNoop ){ buf.nBuf = nRewind; @@ -797,6 +938,7 @@ struct sqlite3_changeset_iter { u8 *pNext; /* Pointer to next change within aChangeset */ int rc; + sqlite3_stmt *pConflict; /* Conflicting row, if any */ char *zTab; /* Current table */ int nCol; /* Number of columns in zTab */ int op; /* Current operation */ @@ -947,9 +1089,9 @@ int sqlite3changeset_next(sqlite3_changeset_iter *p){ */ int sqlite3changeset_op( sqlite3_changeset_iter *pIter, - const char **pzTab, /* OUT: Pointer to table name */ - int *pnCol, /* OUT: Number of columns in table */ - int *pOp /* OUT: SQLITE_INSERT, DELETE or UPDATE */ + const char **pzTab, /* OUT: Pointer to table name */ + int *pnCol, /* OUT: Number of columns in table */ + int *pOp /* OUT: SQLITE_INSERT, DELETE or UPDATE */ ){ *pOp = pIter->op; *pnCol = pIter->nCol; @@ -960,8 +1102,11 @@ int sqlite3changeset_op( int sqlite3changeset_old( sqlite3_changeset_iter *pIter, int iVal, - sqlite3_value **ppValue /* OUT: Old value (or NULL pointer) */ + sqlite3_value **ppValue /* OUT: Old value (or NULL pointer) */ ){ + if( pIter->op!=SQLITE_UPDATE && pIter->op!=SQLITE_DELETE ){ + return SQLITE_MISUSE; + } if( iVal<0 || iVal>=pIter->nCol ){ return SQLITE_RANGE; } @@ -972,8 +1117,11 @@ int sqlite3changeset_old( int sqlite3changeset_new( sqlite3_changeset_iter *pIter, int iVal, - sqlite3_value **ppValue /* OUT: New value (or NULL pointer) */ + sqlite3_value **ppValue /* OUT: New value (or NULL pointer) */ ){ + if( pIter->op!=SQLITE_UPDATE && pIter->op!=SQLITE_INSERT ){ + return SQLITE_MISUSE; + } if( iVal<0 || iVal>=pIter->nCol ){ return SQLITE_RANGE; } @@ -981,6 +1129,21 @@ int sqlite3changeset_new( return SQLITE_OK; } +int sqlite3changeset_conflict( + sqlite3_changeset_iter *pIter, + int iVal, + sqlite3_value **ppValue /* OUT: Value from conflicting row */ +){ + if( !pIter->pConflict ){ + return SQLITE_MISUSE; + } + if( iVal<0 || iVal>=sqlite3_column_count(pIter->pConflict) ){ + return SQLITE_RANGE; + } + *ppValue = sqlite3_column_value(pIter->pConflict, iVal); + return SQLITE_OK; +} + /* ** Finalize an iterator allocated with sqlite3changeset_start(). ** @@ -1073,5 +1236,436 @@ int sqlite3changeset_invert( return SQLITE_OK; } +static void sessionUpdateDeleteWhere( + SessionBuffer *pBuf, /* Buffer to append to */ + int nCol, /* Number of entries in azCol and abPK */ + const char **azCol, /* Column names */ + u8 *abPK, /* True for PK columns */ + int *pRc /* IN/OUT: Error code */ +){ + if( *pRc==SQLITE_OK ){ + int i; + const char *zSep = ""; + + sessionAppendStr(pBuf, " WHERE ", pRc); + + for(i=0; ipConflict = pSelect; + res = xConflict(pCtx, SQLITE_CHANGESET_DATA, pIter); + pIter->pConflict = 0; + sqlite3_reset(pSelect); + }else{ + rc = sqlite3_reset(pSelect); + if( rc==SQLITE_OK ){ + res = xConflict(pCtx, SQLITE_CHANGESET_NOTFOUND, pIter); + } + } + + }else if( rc==SQLITE_CONSTRAINT ){ + res = xConflict(pCtx, SQLITE_CHANGESET_CONSTRAINT, pIter); + rc = SQLITE_OK; + } + + if( rc!=SQLITE_OK ) break; + + }else if( op==SQLITE_UPDATE ){ + int i; + int res; + rc = sessionUpdateRow(db, zTab, nCol, azCol, abPK, &pUpdate); + for(i=0; rc==SQLITE_OK && ipConflict = pSelect; + res = xConflict(pCtx, SQLITE_CHANGESET_DATA, pIter); + pIter->pConflict = 0; + sqlite3_reset(pSelect); + }else{ + rc = sqlite3_reset(pSelect); + if( rc==SQLITE_OK ){ + res = xConflict(pCtx, SQLITE_CHANGESET_NOTFOUND, pIter); + } + } + }else if( rc==SQLITE_CONSTRAINT ){ + assert(0); + } + + }else{ + int i; + assert( op==SQLITE_INSERT ); + if( pInsert==0 ){ + SessionBuffer buf = {0, 0, 0}; + sessionAppendStr(&buf, "INSERT INTO main.", &rc); + sessionAppendIdent(&buf, zTab, &rc); + sessionAppendStr(&buf, " VALUES(?", &rc); + for(i=1; ipConflict = pSelect; + res = xConflict(pCtx, SQLITE_CHANGESET_CONFLICT, pIter); + pIter->pConflict = 0; + sqlite3_reset(pSelect); + }else{ + rc = sqlite3_reset(pSelect); + if( rc==SQLITE_OK ){ + res = xConflict(pCtx, SQLITE_CHANGESET_CONSTRAINT, pIter); + } + } + } + } + } + rc2 = sqlite3changeset_finalize(pIter); + if( rc==SQLITE_DONE ) rc = rc2; + + if( rc==SQLITE_OK ){ + rc = sqlite3_exec(db, "RELEASE changeset_apply", 0, 0, 0); + }else{ + sqlite3_exec(db, "ROLLBACK TO changeset_apply", 0, 0, 0); + sqlite3_exec(db, "RELEASE changeset_apply", 0, 0, 0); + } + + sqlite3_finalize(pInsert); + sqlite3_finalize(pDelete); + sqlite3_finalize(pUpdate); + sqlite3_finalize(pSelect); + sqlite3_free(azCol); + return rc; +} #endif /* #ifdef SQLITE_ENABLE_SESSION */ diff --git a/ext/session/sqlite3session.h b/ext/session/sqlite3session.h index fe6ca2075b..8c3a708ce8 100644 --- a/ext/session/sqlite3session.h +++ b/ext/session/sqlite3session.h @@ -112,6 +112,21 @@ int sqlite3changeset_new( int iVal, sqlite3_value **ppValue /* OUT: New value (or NULL pointer) */ ); +/* +** This function is only usable with sqlite3_changeset_iter objects passed +** to the xConflict callback by sqlite3changeset_apply(). It cannot be used +** with iterators created using sqlite3changeset_start(). +** +** It is used to access the "conflicting row" information available to the +** conflict handler if the second argument is either SQLITE_CHANGESET_DATA +** or SQLITE_CHANGESET_CONFLICT. +*/ +int sqlite3changeset_conflict( + sqlite3_changeset_iter *pIter, + int iVal, + sqlite3_value **ppValue /* OUT: Value from conflicting row */ +); + /* ** Finalize an iterator allocated with sqlite3changeset_start(). @@ -129,6 +144,36 @@ int sqlite3changeset_invert( int *pnOut, void **ppOut /* OUT: Inverse of input */ ); +/* +** Apply a changeset to a database. +** +** It is safe to execute SQL statements, including those that write to the +** table that the callback related to, from within the xConflict callback. +** This can be used to further customize the applications conflict +** resolution strategy. +*/ +int sqlite3changeset_apply( + sqlite3 *db, + int nChangeset, + void *pChangeset, + int(*xConflict)( + void *pCtx, /* Copy of fifth arg to _apply() */ + int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */ + sqlite3_changeset_iter *p /* Handle describing change and conflict */ + ), + void *pCtx +); + +/* Values passed as the second argument to a conflict-handler */ +#define SQLITE_CHANGESET_DATA 1 +#define SQLITE_CHANGESET_NOTFOUND 2 +#define SQLITE_CHANGESET_CONFLICT 3 +#define SQLITE_CHANGESET_CONSTRAINT 4 + +/* Valid return values from a conflict-handler */ +#define SQLITE_CHANGESET_OMIT 0 +#define SQLITE_CHANGESET_REPLACE 1 +#define SQLITE_CHANGESET_ABORT 2 #endif diff --git a/ext/session/test_session.c b/ext/session/test_session.c index 1e8a9eccf6..a805280787 100644 --- a/ext/session/test_session.c +++ b/ext/session/test_session.c @@ -168,6 +168,139 @@ static void test_append_value(Tcl_Obj *pList, sqlite3_value *pVal){ } } +typedef struct TestConflictHandler TestConflictHandler; +struct TestConflictHandler { + Tcl_Interp *interp; + Tcl_Obj *pScript; +}; + +static int test_conflict_handler( + void *pCtx, /* Pointer to TestConflictHandler structure */ + int eConf, /* DATA, MISSING, CONFLICT, CONSTRAINT */ + sqlite3_changeset_iter *pIter /* Handle describing change and conflict */ +){ + TestConflictHandler *p = (TestConflictHandler *)pCtx; + Tcl_Obj *pEval; + Tcl_Interp *interp = p->interp; + + int op; /* SQLITE_UPDATE, DELETE or INSERT */ + const char *zTab; /* Name of table conflict is on */ + int nCol; /* Number of columns in table zTab */ + + pEval = Tcl_DuplicateObj(p->pScript); + Tcl_IncrRefCount(pEval); + + sqlite3changeset_op(pIter, &zTab, &nCol, &op); + + /* Append the operation type. */ + Tcl_ListObjAppendElement(0, pEval, Tcl_NewStringObj( + op==SQLITE_INSERT ? "INSERT" : + op==SQLITE_UPDATE ? "UPDATE" : + "DELETE", -1 + )); + + /* Append the table name. */ + Tcl_ListObjAppendElement(0, pEval, Tcl_NewStringObj(zTab, -1)); + + /* Append the conflict type. */ + switch( eConf ){ + case SQLITE_CHANGESET_DATA: + Tcl_ListObjAppendElement(interp, pEval,Tcl_NewStringObj("DATA",-1)); + break; + case SQLITE_CHANGESET_NOTFOUND: + Tcl_ListObjAppendElement(interp, pEval,Tcl_NewStringObj("NOTFOUND",-1)); + break; + case SQLITE_CHANGESET_CONFLICT: + Tcl_ListObjAppendElement(interp, pEval,Tcl_NewStringObj("CONFLICT",-1)); + break; + case SQLITE_CHANGESET_CONSTRAINT: + Tcl_ListObjAppendElement(interp, pEval,Tcl_NewStringObj("CONSTRAINT",-1)); + break; + } + + /* If this is not an INSERT, append the old row */ + if( op!=SQLITE_INSERT ){ + int i; + Tcl_Obj *pOld = Tcl_NewObj(); + for(i=0; i Date: Sat, 12 Mar 2011 17:22:46 +0000 Subject: [PATCH 0006/1484] Fix some issues with UPDATE changes in the session module. FossilOrigin-Name: 57862efe718fdc93401998f9058511292a0e1a50 --- ext/session/sqlite3session.c | 134 +++++++++++++++++++++++++---------- manifest | 14 ++-- manifest.uuid | 2 +- test/session1.test | 21 ++++-- 4 files changed, 120 insertions(+), 51 deletions(-) diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index 86778d65f0..2ff0bc56fe 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -667,14 +667,14 @@ static void sessionAppendUpdate( u8 *pCsr = p->aRecord; sessionAppendByte(pBuf, SQLITE_UPDATE, pRc); for(i=0; ipConflict = pSelect; + res = xConflict(pCtx, SQLITE_CHANGESET_CONFLICT, pIter); + pIter->pConflict = 0; + sqlite3_reset(pSelect); + }else{ + /* No other row with the new.* primary key. */ + rc = sqlite3_reset(pSelect); + if( rc==SQLITE_OK ){ + res = xConflict(pCtx, SQLITE_CHANGESET_CONSTRAINT, pIter); + } + } + + return rc; +} + int sqlite3changeset_apply( sqlite3 *db, int nChangeset, @@ -1479,6 +1527,8 @@ int sqlite3changeset_apply( sqlite3_stmt *pSelect = 0; /* SELECT statement */ rc = sqlite3_exec(db, "SAVEPOINT changeset_apply", 0, 0, 0); + if( rc!=SQLITE_OK ) return rc; + sqlite3changeset_start(&pIter, nChangeset, pChangeset); while( SQLITE_ROW==sqlite3changeset_next(pIter) ){ int op; @@ -1494,6 +1544,13 @@ int sqlite3changeset_apply( sqlite3_finalize(pInsert); sqlite3_finalize(pSelect); pSelect = pUpdate = pInsert = pDelete = 0; + + if( (rc = sessionSelectRow(db, zTab, nCol, azCol, abPK, &pSelect)) + || (rc = sessionUpdateRow(db, zTab, nCol, azCol, abPK, &pUpdate)) + || (rc = sessionDeleteRow(db, zTab, nCol, azCol, abPK, &pDelete)) + ){ + break; + } } if( op==SQLITE_DELETE ){ @@ -1559,7 +1616,7 @@ int sqlite3changeset_apply( if( rc==SQLITE_OK ){ if( pOld ) sqlite3_bind_value(pUpdate, i*3+1, pOld); sqlite3_bind_int(pUpdate, i*3+2, !!pNew); - if( pNew ) sqlite3_bind_value(pUpdate, i*3+3, pOld); + if( pNew ) sqlite3_bind_value(pUpdate, i*3+3, pNew); } } if( rc==SQLITE_OK ) rc = sqlite3_bind_int(pUpdate, nCol*3+1, 0); @@ -1592,7 +1649,32 @@ int sqlite3changeset_apply( } } }else if( rc==SQLITE_CONSTRAINT ){ - assert(0); + /* This may be a CONSTRAINT or CONFLICT error. It is a CONFLICT if + ** the only problem is a duplicate PRIMARY KEY, or a CONSTRAINT + ** otherwise. */ + int bPKChange = 0; + + /* Check if the PK has been modified. */ + rc = SQLITE_OK; + for(i=0; ipConflict = pSelect; - res = xConflict(pCtx, SQLITE_CHANGESET_CONFLICT, pIter); - pIter->pConflict = 0; - sqlite3_reset(pSelect); - }else{ - rc = sqlite3_reset(pSelect); - if( rc==SQLITE_OK ){ - res = xConflict(pCtx, SQLITE_CHANGESET_CONSTRAINT, pIter); - } - } + rc = sessionConstraintConflict( + db, pIter, abPK, pSelect, xConflict, pCtx + ); } } } diff --git a/manifest b/manifest index b3938bacd9..38e0a86e95 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\ssqlite3changeset_apply()\sfunction.\sDoes\snot\syet\shandle\sall\scases. -D 2011-03-11T19:05:52 +C Fix\ssome\sissues\swith\sUPDATE\schanges\sin\sthe\ssession\smodule. +D 2011-03-12T17:22:46 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -98,7 +98,7 @@ F ext/rtree/rtree_util.tcl 06aab2ed5b826545bf215fff90ecb9255a8647ea F ext/rtree/sqlite3rtree.h 1af0899c63a688e272d69d8e746f24e76f10a3f0 F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 -F ext/session/sqlite3session.c 724a064f0d9a909c12dfb668b42ce007378f352e +F ext/session/sqlite3session.c af63d87b8787c19b4a4b681f77331a9cc13d67af F ext/session/sqlite3session.h 3246613b20857e58f7419e4e26dbe9161677aff0 F ext/session/test_session.c 1b4f278d0ae164e2d02c11f5e1f2df3a2567ba41 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 @@ -639,7 +639,7 @@ F test/selectA.test 06d1032fa9009314c95394f2ca2e60d9f7ae8532 F test/selectB.test f305cc6660804cb239aab4e2f26b0e288b59958b F test/selectC.test f9bf1bc4581b5b8158caa6e4e4f682acb379fb25 F test/server1.test f5b790d4c0498179151ca8a7715a65a7802c859c -F test/session1.test 6a2e0db809e44879cec5314a6fd238ad768d9723 +F test/session1.test 6ec522f3491fbdbf8a5b6c27f50b9e35f24e3dba F test/shared.test b9114eaea7e748a3a4c8ff7b9ca806c8f95cef3e F test/shared2.test 7f6ad2d857d0f4e5d6a0b9a897b5e56a6b6ea18c F test/shared3.test d69bdd5f156580876c5345652d21dc2092e85962 @@ -913,7 +913,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 75d5dff725dbb66d67d56ad042926f1daae56dbe -R 7203b6a6763bad83d70ecbe2db2167c5 +P 2b19be7bf753c7dd12e1c3b384981a3ea1bc8145 +R 222ffce3b378b2ba18950183bb251367 U dan -Z 77d8992b93ad5a2a0231fb47a635b3cb +Z b642b18410bb67d03067201d5612ecd6 diff --git a/manifest.uuid b/manifest.uuid index f741e56cff..b6d1059b89 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2b19be7bf753c7dd12e1c3b384981a3ea1bc8145 \ No newline at end of file +57862efe718fdc93401998f9058511292a0e1a50 \ No newline at end of file diff --git a/test/session1.test b/test/session1.test index 737d796ba3..5706b77bc5 100644 --- a/test/session1.test +++ b/test/session1.test @@ -259,22 +259,29 @@ do_execsql_test 3.3.1 { CREATE TABLE t4(a, b, c, PRIMARY KEY(b, c)); INSERT INTO t4 VALUES(1, 2, 3); INSERT INTO t4 VALUES(4, 5, 6); + INSERT INTO t4 VALUES(7, 8, 9); + INSERT INTO t4 VALUES(10, 11, 12); } do_db2_test 3.3.2 { - CREATE TABLE t4(a, b, c, PRIMARY KEY(b, c)); + CREATE TABLE t4(a NOT NULL, b, c, PRIMARY KEY(b, c)); INSERT INTO t4 VALUES(0, 2, 3); INSERT INTO t4 VALUES(4, 5, 7); + INSERT INTO t4 VALUES(7, 8, 9); + INSERT INTO t4 VALUES(10, 11, 12); } - -do_conflict_test 3.2.3 -tables t4 -sql { +do_conflict_test 3.3.3 -tables t4 -sql { UPDATE t4 SET a = -1 WHERE b = 2; + UPDATE t4 SET a = -1 WHERE b = 5; + UPDATE t4 SET a = NULL WHERE c = 9; + UPDATE t4 SET a = 'x' WHERE b = 11; } -conflicts { - {UPDATE t4 DATA {i 1 i 2 i 3} {i -1 i 2 i 3} {i 0 i 2 i 3}} + {UPDATE t4 DATA {i 1 i 2 i 3} {i -1 {} {} {} {}} {i 0 i 2 i 3}} + {UPDATE t4 NOTFOUND {i 4 i 5 i 6} {i -1 {} {} {} {}}} + {UPDATE t4 CONSTRAINT {i 7 i 8 i 9} {n {} {} {} {} {}}} } -do_db2_test 3.3.4 { - SELECT * FROM t4 -} {0 2 3 4 5 7} +do_db2_test 3.3.4 { SELECT * FROM t4 } {0 2 3 4 5 7 7 8 9 x 11 12} +do_execsql_test 3.3.5 { SELECT * FROM t4 } {-1 2 3 -1 5 6 {} 8 9 x 11 12} catch { db2 close } From 0c698471d1e3b4205826f2790f1a857d90841f8a Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 14 Mar 2011 19:49:23 +0000 Subject: [PATCH 0007/1484] Fix handling of return values from the conflict handler. Document the conflict handler arguments and return codes in sqlite3session.h. FossilOrigin-Name: cbbb274e500237dbf7155a51d4f9c17583d704ea --- ext/session/sqlite3session.c | 677 ++++++++++++++++++++--------------- ext/session/sqlite3session.h | 66 +++- ext/session/test_session.c | 32 +- manifest | 18 +- manifest.uuid | 2 +- test/session1.test | 127 ++++++- 6 files changed, 610 insertions(+), 312 deletions(-) diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index 2ff0bc56fe..ae3139badc 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -1279,6 +1279,19 @@ static void sessionUpdateDeleteWhere( } } + +typedef struct SessionApplyCtx SessionApplyCtx; +struct SessionApplyCtx { + sqlite3 *db; + sqlite3_stmt *pDelete; /* DELETE statement */ + sqlite3_stmt *pUpdate; /* DELETE statement */ + sqlite3_stmt *pInsert; /* INSERT statement */ + sqlite3_stmt *pSelect; /* SELECT statement */ + int nCol; /* Size of azCol[] and abPK[] arrays */ + const char **azCol; /* Array of column names */ + u8 *abPK; /* Boolean array - true if column is in PK */ +}; + /* ** Formulate a statement to DELETE a row from database db. Assuming a table ** structure like this: @@ -1296,25 +1309,19 @@ static void sessionUpdateDeleteWhere( static int sessionDeleteRow( sqlite3 *db, /* Database handle */ const char *zTab, /* Table name */ - int nCol, /* Number of entries in azCol and abPK */ - const char **azCol, /* Column names */ - u8 *abPK, /* True for PK columns */ - sqlite3_stmt **ppStmt /* OUT: Compiled SELECT statement. */ + SessionApplyCtx *p /* Session changeset-apply context */ ){ int rc = SQLITE_OK; - if( *ppStmt==0 ){ - SessionBuffer buf = {0, 0, 0}; + SessionBuffer buf = {0, 0, 0}; - sessionAppendStr(&buf, "DELETE FROM ", &rc); - sessionAppendIdent(&buf, zTab, &rc); + sessionAppendStr(&buf, "DELETE FROM ", &rc); + sessionAppendIdent(&buf, zTab, &rc); + sessionUpdateDeleteWhere(&buf, p->nCol, p->azCol, p->abPK, &rc); - sessionUpdateDeleteWhere(&buf, nCol, azCol, abPK, &rc); - - if( rc==SQLITE_OK ){ - rc = sqlite3_prepare_v2(db, (char *)buf.aBuf, buf.nBuf, ppStmt, 0); - } - sqlite3_free(buf.aBuf); + if( rc==SQLITE_OK ){ + rc = sqlite3_prepare_v2(db, (char *)buf.aBuf, buf.nBuf, &p->pDelete, 0); } + sqlite3_free(buf.aBuf); return rc; } @@ -1351,149 +1358,344 @@ static int sessionDeleteRow( static int sessionUpdateRow( sqlite3 *db, /* Database handle */ const char *zTab, /* Table name */ - int nCol, /* Number of entries in azCol and abPK */ - const char **azCol, /* Column names */ - u8 *abPK, /* True for PK columns */ - sqlite3_stmt **ppStmt /* OUT: Compiled SELECT statement. */ + SessionApplyCtx *p /* Session changeset-apply context */ ){ int rc = SQLITE_OK; - if( *ppStmt==0 ){ - int i; - const char *zSep = ""; - SessionBuffer buf = {0, 0, 0}; + int i; + const char *zSep = ""; + SessionBuffer buf = {0, 0, 0}; - /* Append "UPDATE tbl SET " */ - sessionAppendStr(&buf, "UPDATE ", &rc); - sessionAppendIdent(&buf, zTab, &rc); - sessionAppendStr(&buf, " SET ", &rc); + /* Append "UPDATE tbl SET " */ + sessionAppendStr(&buf, "UPDATE ", &rc); + sessionAppendIdent(&buf, zTab, &rc); + sessionAppendStr(&buf, " SET ", &rc); - /* Append the assignments */ - for(i=0; inCol; i++){ + sessionAppendStr(&buf, zSep, &rc); + sessionAppendIdent(&buf, p->azCol[i], &rc); + sessionAppendStr(&buf, " = CASE WHEN ?", &rc); + sessionAppendInteger(&buf, i*3+2, &rc); + sessionAppendStr(&buf, " THEN ?", &rc); + sessionAppendInteger(&buf, i*3+3, &rc); + sessionAppendStr(&buf, " ELSE ", &rc); + sessionAppendIdent(&buf, p->azCol[i], &rc); + sessionAppendStr(&buf, " END", &rc); + zSep = ", "; } + /* Append the PK part of the WHERE clause */ + sessionAppendStr(&buf, " WHERE ", &rc); + for(i=0; inCol; i++){ + if( p->abPK[i] ){ + sessionAppendIdent(&buf, p->azCol[i], &rc); + sessionAppendStr(&buf, " = ?", &rc); + sessionAppendInteger(&buf, i*3+1, &rc); + sessionAppendStr(&buf, " AND ", &rc); + } + } + + /* Append the non-PK part of the WHERE clause */ + sessionAppendStr(&buf, " (?", &rc); + sessionAppendInteger(&buf, p->nCol*3+1, &rc); + sessionAppendStr(&buf, " OR 1", &rc); + for(i=0; inCol; i++){ + if( !p->abPK[i] ){ + sessionAppendStr(&buf, " AND (?", &rc); + sessionAppendInteger(&buf, i*3+2, &rc); + sessionAppendStr(&buf, "=0 OR ", &rc); + sessionAppendIdent(&buf, p->azCol[i], &rc); + sessionAppendStr(&buf, " IS ?", &rc); + sessionAppendInteger(&buf, i*3+1, &rc); + sessionAppendStr(&buf, ")", &rc); + } + } + sessionAppendStr(&buf, ")", &rc); + + if( rc==SQLITE_OK ){ + rc = sqlite3_prepare_v2(db, (char *)buf.aBuf, buf.nBuf, &p->pUpdate, 0); + } + sqlite3_free(buf.aBuf); + return rc; } static int sessionSelectRow( sqlite3 *db, /* Database handle */ const char *zTab, /* Table name */ - int nCol, /* Number of entries in azCol and abPK */ - const char **azCol, /* Column names */ - u8 *abPK, /* True for PK columns */ - sqlite3_stmt **ppStmt /* OUT: Compiled SELECT statement. */ + SessionApplyCtx *p /* Session changeset-apply context */ ){ int rc = SQLITE_OK; - if( *ppStmt==0 ){ - int i; - const char *zSep = ""; - SessionBuffer buf = {0, 0, 0}; - - sessionAppendStr(&buf, "SELECT * FROM ", &rc); - sessionAppendIdent(&buf, zTab, &rc); - sessionAppendStr(&buf, " WHERE ", &rc); - - for(i=0; inCol; i++){ + if( p->abPK[i] ){ + sessionAppendStr(&buf, zSep, &rc); + sessionAppendIdent(&buf, p->azCol[i], &rc); + sessionAppendStr(&buf, " = ?", &rc); + sessionAppendInteger(&buf, i+1, &rc); + zSep = " AND "; } - - if( rc==SQLITE_OK ){ - rc = sqlite3_prepare_v2(db, (char *)buf.aBuf, buf.nBuf, ppStmt, 0); - } - sqlite3_free(buf.aBuf); } + if( rc==SQLITE_OK ){ + rc = sqlite3_prepare_v2(db, (char *)buf.aBuf, buf.nBuf, &p->pSelect, 0); + } + sqlite3_free(buf.aBuf); return rc; } -static int sessionConstraintConflict( +static int sessionInsertRow( + sqlite3 *db, /* Database handle */ + const char *zTab, /* Table name */ + SessionApplyCtx *p /* Session changeset-apply context */ +){ + int rc = SQLITE_OK; + int i; + SessionBuffer buf = {0, 0, 0}; + + sessionAppendStr(&buf, "INSERT INTO main.", &rc); + sessionAppendIdent(&buf, zTab, &rc); + sessionAppendStr(&buf, " VALUES(?", &rc); + for(i=1; inCol; i++){ + sessionAppendStr(&buf, ", ?", &rc); + } + sessionAppendStr(&buf, ")", &rc); + + if( rc==SQLITE_OK ){ + rc = sqlite3_prepare_v2(db, (char *)buf.aBuf, buf.nBuf, &p->pInsert, 0); + } + sqlite3_free(buf.aBuf); + return rc; +} + +static int sessionSeekToRow( sqlite3 *db, /* Database handle */ sqlite3_changeset_iter *pIter, /* Changeset iterator */ u8 *abPK, /* Primary key flags array */ - sqlite3_stmt *pSelect, /* SELECT statement from sessionSelectRow() */ - int(*xConflict)(void *, int, sqlite3_changeset_iter*), - void *pCtx + sqlite3_stmt *pSelect /* SELECT statement from sessionSelectRow() */ ){ - int res; - int rc; + int rc = SQLITE_OK; + int i; int nCol; int op; const char *zDummy; sqlite3changeset_op(pIter, &zDummy, &nCol, &op); - assert( op==SQLITE_UPDATE || op==SQLITE_INSERT ); - /* Bind the new.* PRIMARY KEY values to the SELECT statement. */ - for(i=0; idb, pIter, p->abPK, p->pSelect); + }else{ + rc = SQLITE_DONE; + } + + if( rc==SQLITE_ROW ){ /* There exists another row with the new.* primary key. */ - pIter->pConflict = pSelect; - res = xConflict(pCtx, SQLITE_CHANGESET_CONFLICT, pIter); + pIter->pConflict = p->pSelect; + res = xConflict(pCtx, eType, pIter); pIter->pConflict = 0; - sqlite3_reset(pSelect); + rc = sqlite3_reset(p->pSelect); }else{ /* No other row with the new.* primary key. */ - rc = sqlite3_reset(pSelect); + rc = sqlite3_reset(p->pSelect); if( rc==SQLITE_OK ){ - res = xConflict(pCtx, SQLITE_CHANGESET_CONSTRAINT, pIter); + res = xConflict(pCtx, eType+1, pIter); + if( res==SQLITE_CHANGESET_REPLACE ) rc = SQLITE_MISUSE; + } + } + + if( rc==SQLITE_OK ){ + switch( res ){ + case SQLITE_CHANGESET_REPLACE: + if( pbReplace ) *pbReplace = 1; + break; + + case SQLITE_CHANGESET_OMIT: + break; + + case SQLITE_CHANGESET_ABORT: + rc = SQLITE_ABORT; + break; + + default: + rc = SQLITE_MISUSE; + break; + } + } + + return rc; +} + +static int sessionApplyOneOp( + sqlite3_changeset_iter *pIter, + SessionApplyCtx *p, + int(*xConflict)(void *, int, sqlite3_changeset_iter *), + void *pCtx, + int *pbReplace, + int *pbRetry +){ + const char *zDummy; + int op; + int nCol; + int rc = SQLITE_OK; + + assert( p->pDelete && p->pUpdate && p->pInsert && p->pSelect ); + assert( p->azCol && p->abPK ); + assert( !pbReplace || *pbReplace==0 ); + + sqlite3changeset_op(pIter, &zDummy, &nCol, &op); + + if( op==SQLITE_DELETE ){ + int i; + + /* Bind values to the DELETE statement. */ + for(i=0; rc==SQLITE_OK && ipDelete, i+1, pVal); + } + } + if( rc==SQLITE_OK ) rc = sqlite3_bind_int(p->pDelete, nCol+1, pbRetry==0); + if( rc!=SQLITE_OK ) return rc; + + sqlite3_step(p->pDelete); + rc = sqlite3_reset(p->pDelete); + if( rc==SQLITE_OK && sqlite3_changes(p->db)==0 ){ + rc = sessionConflictHandler( + SQLITE_CHANGESET_DATA, p, pIter, xConflict, pCtx, pbRetry + ); + }else if( rc==SQLITE_CONSTRAINT ){ + rc = sessionConflictHandler( + SQLITE_CHANGESET_CONFLICT, p, pIter, xConflict, pCtx, 0 + ); + } + + }else if( op==SQLITE_UPDATE ){ + int i; + + /* Bind values to the UPDATE statement. */ + for(i=0; rc==SQLITE_OK && ipUpdate, i*3+1, pOld); + sqlite3_bind_int(p->pUpdate, i*3+2, !!pNew); + if( pNew ) sqlite3_bind_value(p->pUpdate, i*3+3, pNew); + } + } + if( rc==SQLITE_OK ) rc = sqlite3_bind_int(p->pUpdate, nCol*3+1, pbRetry==0); + if( rc!=SQLITE_OK ) return rc; + + /* Attempt the UPDATE. In the case of a NOTFOUND or DATA conflict, + ** the result will be SQLITE_OK with 0 rows modified. */ + sqlite3_step(p->pUpdate); + rc = sqlite3_reset(p->pUpdate); + + if( rc==SQLITE_OK && sqlite3_changes(p->db)==0 ){ + /* A NOTFOUND or DATA error. Search the table to see if it contains + ** a row with a matching primary key. If so, this is a DATA conflict. + ** Otherwise, if there is no primary key match, it is a NOTFOUND. */ + + rc = sessionConflictHandler( + SQLITE_CHANGESET_DATA, p, pIter, xConflict, pCtx, pbRetry + ); + + }else if( rc==SQLITE_CONSTRAINT ){ + /* This may be a CONSTRAINT or CONFLICT error. It is a CONFLICT if + ** the only problem is a duplicate PRIMARY KEY, or a CONSTRAINT + ** otherwise. */ + int bPKChange = 0; + + /* Check if the PK has been modified. */ + rc = SQLITE_OK; + for(i=0; iabPK[i] ){ + sqlite3_value *pNew; + rc = sqlite3changeset_new(pIter, i, &pNew); + if( rc==SQLITE_OK && pNew ){ + bPKChange = 1; + break; + } + } + } + + rc = sessionConflictHandler(SQLITE_CHANGESET_CONFLICT, + p, pIter, xConflict, pCtx, (bPKChange ? pbReplace : 0) + ); + } + + }else{ + int i; + assert( op==SQLITE_INSERT ); + for(i=0; rc==SQLITE_OK && ipInsert, i+1, pVal); + } + } + if( rc!=SQLITE_OK ) return rc; + + sqlite3_step(p->pInsert); + rc = sqlite3_reset(p->pInsert); + if( rc==SQLITE_CONSTRAINT && xConflict ){ + rc = sessionConflictHandler( + SQLITE_CHANGESET_CONFLICT, p, pIter, xConflict, pCtx, pbReplace + ); } } @@ -1511,209 +1713,90 @@ int sqlite3changeset_apply( ), void *pCtx ){ - sqlite3_changeset_iter *pIter; + sqlite3_changeset_iter *pIter = 0; int rc; int rc2; const char *zTab = 0; /* Name of current table */ int nTab = 0; /* Result of strlen(zTab) */ - int nCol = 0; /* Number of columns in table zTab */ - const char **azCol = 0; /* Array of column names */ - u8 *abPK = 0; /* Boolean array - true if column is in PK */ - sqlite3_stmt *pDelete = 0; /* DELETE statement */ - sqlite3_stmt *pUpdate = 0; /* DELETE statement */ - sqlite3_stmt *pInsert = 0; /* INSERT statement */ - sqlite3_stmt *pSelect = 0; /* SELECT statement */ - - rc = sqlite3_exec(db, "SAVEPOINT changeset_apply", 0, 0, 0); - if( rc!=SQLITE_OK ) return rc; + SessionApplyCtx sApply; + memset(&sApply, 0, sizeof(sApply)); sqlite3changeset_start(&pIter, nChangeset, pChangeset); - while( SQLITE_ROW==sqlite3changeset_next(pIter) ){ + + rc = sqlite3_exec(db, "SAVEPOINT changeset_apply", 0, 0, 0); + while( rc==SQLITE_OK && SQLITE_ROW==sqlite3changeset_next(pIter) ){ + int nCol; int op; - const char *zThis; - sqlite3changeset_op(pIter, &zThis, &nCol, &op); - if( zTab==0 || sqlite3_strnicmp(zThis, zTab, nTab+1) ){ - sqlite3_free(azCol); - rc = sessionTableInfo(db, zThis, nCol, &zTab, &azCol, &abPK); - nTab = strlen(zTab); + int bReplace = 0; + int bRetry = 0; + const char *zNew; + sqlite3changeset_op(pIter, &zNew, &nCol, &op); - sqlite3_finalize(pDelete); - sqlite3_finalize(pUpdate); - sqlite3_finalize(pInsert); - sqlite3_finalize(pSelect); - pSelect = pUpdate = pInsert = pDelete = 0; + if( zTab==0 || sqlite3_strnicmp(zNew, zTab, nTab+1) ){ + sqlite3_free(sApply.azCol); + sqlite3_finalize(sApply.pDelete); + sqlite3_finalize(sApply.pUpdate); + sqlite3_finalize(sApply.pInsert); + sqlite3_finalize(sApply.pSelect); + memset(&sApply, 0, sizeof(sApply)); + sApply.db = db; + sApply.nCol = nCol; - if( (rc = sessionSelectRow(db, zTab, nCol, azCol, abPK, &pSelect)) - || (rc = sessionUpdateRow(db, zTab, nCol, azCol, abPK, &pUpdate)) - || (rc = sessionDeleteRow(db, zTab, nCol, azCol, abPK, &pDelete)) + rc = sessionTableInfo(db, zNew, nCol, &zTab, &sApply.azCol, &sApply.abPK); + + if( rc!=SQLITE_OK + || (rc = sessionSelectRow(db, zTab, &sApply)) + || (rc = sessionUpdateRow(db, zTab, &sApply)) + || (rc = sessionDeleteRow(db, zTab, &sApply)) + || (rc = sessionInsertRow(db, zTab, &sApply)) ){ break; } + + nTab = strlen(zTab); } - if( op==SQLITE_DELETE ){ - int res; - int i; - rc = sessionDeleteRow(db, zTab, nCol, azCol, abPK, &pDelete); - for(i=0; rc==SQLITE_OK && ipConflict = pSelect; - res = xConflict(pCtx, SQLITE_CHANGESET_DATA, pIter); - pIter->pConflict = 0; - sqlite3_reset(pSelect); - }else{ - rc = sqlite3_reset(pSelect); - if( rc==SQLITE_OK ){ - res = xConflict(pCtx, SQLITE_CHANGESET_NOTFOUND, pIter); - } - } - - }else if( rc==SQLITE_CONSTRAINT ){ - res = xConflict(pCtx, SQLITE_CHANGESET_CONSTRAINT, pIter); - rc = SQLITE_OK; - } - - if( rc!=SQLITE_OK ) break; - - }else if( op==SQLITE_UPDATE ){ - int i; - int res; - rc = sessionUpdateRow(db, zTab, nCol, azCol, abPK, &pUpdate); - for(i=0; rc==SQLITE_OK && ipConflict = pSelect; - res = xConflict(pCtx, SQLITE_CHANGESET_DATA, pIter); - pIter->pConflict = 0; - sqlite3_reset(pSelect); - }else{ - rc = sqlite3_reset(pSelect); - if( rc==SQLITE_OK ){ - res = xConflict(pCtx, SQLITE_CHANGESET_NOTFOUND, pIter); - } - } - }else if( rc==SQLITE_CONSTRAINT ){ - /* This may be a CONSTRAINT or CONFLICT error. It is a CONFLICT if - ** the only problem is a duplicate PRIMARY KEY, or a CONSTRAINT - ** otherwise. */ - int bPKChange = 0; - - /* Check if the PK has been modified. */ - rc = SQLITE_OK; - for(i=0; iinterp; + int ret = 0; /* Return value */ int op; /* SQLITE_UPDATE, DELETE or INSERT */ const char *zTab; /* Name of table conflict is on */ @@ -257,9 +269,27 @@ static int test_conflict_handler( if( TCL_OK!=Tcl_EvalObjEx(interp, pEval, TCL_EVAL_GLOBAL) ){ Tcl_BackgroundError(interp); + }else{ + Tcl_Obj *pRes = Tcl_GetObjResult(interp); + if( test_obj_eq_string(pRes, "OMIT") || test_obj_eq_string(pRes, "") ){ + ret = SQLITE_CHANGESET_OMIT; + }else if( test_obj_eq_string(pRes, "REPLACE") ){ + ret = SQLITE_CHANGESET_REPLACE; + }else if( test_obj_eq_string(pRes, "ABORT") ){ + ret = SQLITE_CHANGESET_ABORT; + }else{ + Tcl_IncrRefCount(pRes); + Tcl_ResetResult(interp); + Tcl_AppendResult(interp, "unrecognized conflict handler return: \"", + Tcl_GetString(pRes), "\"", 0 + ); + Tcl_DecrRefCount(pRes); + Tcl_BackgroundError(interp); + } } + Tcl_DecrRefCount(pEval); - return SQLITE_CHANGESET_OMIT; + return ret; } /* diff --git a/manifest b/manifest index 38e0a86e95..89b9043680 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\ssome\sissues\swith\sUPDATE\schanges\sin\sthe\ssession\smodule. -D 2011-03-12T17:22:46 +C Fix\shandling\sof\sreturn\svalues\sfrom\sthe\sconflict\shandler.\sDocument\sthe\sconflict\shandler\sarguments\sand\sreturn\scodes\sin\ssqlite3session.h. +D 2011-03-14T19:49:23 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -98,9 +98,9 @@ F ext/rtree/rtree_util.tcl 06aab2ed5b826545bf215fff90ecb9255a8647ea F ext/rtree/sqlite3rtree.h 1af0899c63a688e272d69d8e746f24e76f10a3f0 F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 -F ext/session/sqlite3session.c af63d87b8787c19b4a4b681f77331a9cc13d67af -F ext/session/sqlite3session.h 3246613b20857e58f7419e4e26dbe9161677aff0 -F ext/session/test_session.c 1b4f278d0ae164e2d02c11f5e1f2df3a2567ba41 +F ext/session/sqlite3session.c 111a988b4734b7419f23bb07e45bf5e991510270 +F ext/session/sqlite3session.h 55ca208bddbc1284c83427f423748eb720f5c68f +F ext/session/test_session.c 2559ef68e421c7fb83e2c19ef08a17343b70d535 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F main.mk ae0868e05c76eaa8a0ae3d6927a949b1c8e810d7 @@ -639,7 +639,7 @@ F test/selectA.test 06d1032fa9009314c95394f2ca2e60d9f7ae8532 F test/selectB.test f305cc6660804cb239aab4e2f26b0e288b59958b F test/selectC.test f9bf1bc4581b5b8158caa6e4e4f682acb379fb25 F test/server1.test f5b790d4c0498179151ca8a7715a65a7802c859c -F test/session1.test 6ec522f3491fbdbf8a5b6c27f50b9e35f24e3dba +F test/session1.test edbd6078b86b3f6337d779552671125fbd885e19 F test/shared.test b9114eaea7e748a3a4c8ff7b9ca806c8f95cef3e F test/shared2.test 7f6ad2d857d0f4e5d6a0b9a897b5e56a6b6ea18c F test/shared3.test d69bdd5f156580876c5345652d21dc2092e85962 @@ -913,7 +913,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 2b19be7bf753c7dd12e1c3b384981a3ea1bc8145 -R 222ffce3b378b2ba18950183bb251367 +P 57862efe718fdc93401998f9058511292a0e1a50 +R 17f2f6e54c1cfa1876ed6a58e92b5c4b U dan -Z b642b18410bb67d03067201d5612ecd6 +Z e9add8546b195a8b303123ffee5a5609 diff --git a/manifest.uuid b/manifest.uuid index b6d1059b89..f68965ee4d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -57862efe718fdc93401998f9058511292a0e1a50 \ No newline at end of file +cbbb274e500237dbf7155a51d4f9c17583d704ea \ No newline at end of file diff --git a/test/session1.test b/test/session1.test index 5706b77bc5..46b9d3442d 100644 --- a/test/session1.test +++ b/test/session1.test @@ -148,7 +148,9 @@ do_changeset_invert_test 2.4.3 S {} do_test 2.4.4 { S delete } {} #------------------------------------------------------------------------- -# Test the application of simple changesets. +# Test the application of simple changesets. These tests also test that +# the conflict callback is invoked correctly. For these tests, the +# conflict callback always returns OMIT. # db close forcedelete test.db test.db2 @@ -160,6 +162,8 @@ proc xConflict {args} { return "" } +proc bgerror {args} { set ::background_error $args } + proc do_conflict_test {tn args} { set O(-tables) [list] set O(-sql) [list] @@ -183,6 +187,9 @@ proc do_conflict_test {tn args} { lappend conflicts $c } + after 1 {set go 1} + vwait go + uplevel do_test $tn [list { set ::xConflict }] [list $conflicts] S delete } @@ -279,10 +286,126 @@ do_conflict_test 3.3.3 -tables t4 -sql { {UPDATE t4 NOTFOUND {i 4 i 5 i 6} {i -1 {} {} {} {}}} {UPDATE t4 CONSTRAINT {i 7 i 8 i 9} {n {} {} {} {} {}}} } - do_db2_test 3.3.4 { SELECT * FROM t4 } {0 2 3 4 5 7 7 8 9 x 11 12} do_execsql_test 3.3.5 { SELECT * FROM t4 } {-1 2 3 -1 5 6 {} 8 9 x 11 12} +#------------------------------------------------------------------------- +# This next block of tests verifies that values returned by the conflict +# handler are intepreted correctly. The following cases are tested: +# +# Test case Operation Conflict Return Code +# UPDATE DATA OMIT +# UPDATE DATA REPLACE +# + +proc test_reset {} { + db close + db2 close + forcedelete test.db test.db2 + sqlite3 db test.db + sqlite3 db2 test.db2 +} + +proc xConflict {args} { + lappend ::xConflict $args + return $::conflict_return +} + +foreach {tn conflict_return after} { + 1 OMIT {1 2 value1 4 5 7 7 8 9 10 x x} + 2 REPLACE {1 2 value1 4 5 value2 10 8 9} +} { + test_reset + + do_test 4.$tn.1 { + foreach db {db db2} { + execsql { + CREATE TABLE t1(a, b, c, PRIMARY KEY(a)); + INSERT INTO t1 VALUES(1, 2, 3); + INSERT INTO t1 VALUES(4, 5, 6); + INSERT INTO t1 VALUES(7, 8, 9); + } $db + } + execsql { + REPLACE INTO t1 VALUES(4, 5, 7); + REPLACE INTO t1 VALUES(10, 'x', 'x'); + } db2 + } {} + + do_conflict_test 4.$tn.2 -tables t1 -sql { + UPDATE t1 SET c = 'value1' WHERE a = 1; -- no conflict + UPDATE t1 SET c = 'value2' WHERE a = 4; -- DATA conflict + UPDATE t1 SET a = 10 WHERE a = 7; -- CONFLICT conflict + } -conflicts { + {UPDATE t1 DATA {i 4 {} {} i 6} {{} {} {} {} t value2} {i 4 i 5 i 7}} + {UPDATE t1 CONFLICT {i 7 {} {} {} {}} {i 10 {} {} {} {}} {i 10 t x t x}} + } + + do_db2_test 4.$tn.3 "SELECT * FROM t1 ORDER BY a" $after +} + +foreach {tn conflict_return} { + 1 OMIT + 2 REPLACE +} { + test_reset + + do_test 5.$tn.1 { + # Create an identical schema in both databases. + set schema { + CREATE TABLE "'foolish name'"(x, y, z, PRIMARY KEY(x, y)); + } + execsql $schema db + execsql $schema db2 + + # Add some rows to [db2]. These rows will cause conflicts later + # on when the changeset from [db] is applied to it. + execsql { + INSERT INTO "'foolish name'" VALUES('one', 'one', 'ii'); + INSERT INTO "'foolish name'" VALUES('one', 'two', 'i'); + INSERT INTO "'foolish name'" VALUES('two', 'two', 'ii'); + } db2 + + } {} + + do_conflict_test 5.$tn.2 -tables {{'foolish name'}} -sql { + INSERT INTO "'foolish name'" VALUES('one', 'two', 2); + } -conflicts { + {INSERT {'foolish name'} CONFLICT {t one t two i 2} {t one t two t i}} + } + + set res(REPLACE) {one one ii one two 2 two two ii} + set res(OMIT) {one one ii one two i two two ii} + do_db2_test 5.$tn.3 { + SELECT * FROM "'foolish name'" ORDER BY x, y + } $res($conflict_return) + + + do_test 5.$tn.1 { + set schema { + CREATE TABLE d1("z""z" PRIMARY KEY, y); + INSERT INTO d1 VALUES(1, 'one'); + INSERT INTO d1 VALUES(2, 'two'); + } + execsql $schema db + execsql $schema db2 + + execsql { + UPDATE d1 SET y = 'TWO' WHERE "z""z" = 2; + } db2 + + } {} + + do_conflict_test 5.$tn.2 -tables d1 -sql { + DELETE FROM d1 WHERE "z""z" = 2; + } -conflicts { + {DELETE d1 DATA {i 2 t two} {i 2 t TWO}} + } + + set res(REPLACE) {1 one} + set res(OMIT) {1 one 2 TWO} + do_db2_test 5.$tn.3 "SELECT * FROM d1" $res($conflict_return) +} catch { db2 close } finish_test From 296c76589fb6e535994c49ad7df0783431e28318 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 15 Mar 2011 16:37:27 +0000 Subject: [PATCH 0008/1484] Fix some bugs and other code issues in the session module. FossilOrigin-Name: f2930840e4af3d7d9cb199d316502932fcbbb867 --- ext/session/sqlite3session.c | 731 ++++++++++++++++++++++++----------- ext/session/sqlite3session.h | 38 +- manifest | 16 +- manifest.uuid | 2 +- test/session1.test | 35 +- 5 files changed, 570 insertions(+), 252 deletions(-) diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index ae3139badc..d454d4d345 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -11,23 +11,35 @@ typedef struct RowChange RowChange; typedef struct SessionTable SessionTable; typedef struct SessionChange SessionChange; +typedef struct SessionBuffer SessionBuffer; -#if 0 -#ifndef SQLITE_AMALGAMATION -typedef unsigned char u8; -typedef unsigned long u32; -typedef sqlite3_uint64 u64; -#endif -#endif - +/* +** Session handle structure. +*/ struct sqlite3_session { sqlite3 *db; /* Database handle session is attached to */ char *zDb; /* Name of database session is attached to */ + int bEnable; /* True if currently recording */ int rc; /* Non-zero if an error has occurred */ sqlite3_session *pNext; /* Next session object on same db. */ SessionTable *pTable; /* List of attached tables */ }; +/* +** Structure for changeset iterators. +*/ +struct sqlite3_changeset_iter { + u8 *aChangeset; /* Pointer to buffer containing changeset */ + int nChangeset; /* Number of bytes in aChangeset */ + u8 *pNext; /* Pointer to next change within aChangeset */ + int rc; /* Iterator error code */ + sqlite3_stmt *pConflict; /* Points to conflicting row, if any */ + char *zTab; /* Current table */ + int nCol; /* Number of columns in zTab */ + int op; /* Current operation */ + sqlite3_value **apValue; /* old.* and new.* values */ +}; + /* ** Each session object maintains a set of the following structures, one ** for each table the session object is monitoring. The structures are @@ -45,9 +57,7 @@ struct SessionTable { SessionTable *pNext; char *zName; /* Local name of table */ int nCol; /* Number of columns in table zName */ - - /* Hash table of modified rows */ - int nEntry; /* NUmber of entries in hash table */ + int nEntry; /* Total number of entries in hash table */ int nChange; /* Size of apChange[] array */ SessionChange **apChange; /* Hash table buckets */ }; @@ -124,39 +134,42 @@ struct SessionChange { SessionChange *pNext; /* For hash-table collisions */ }; +/* +** Instances of this structure are used to build strings or binary records. +*/ +struct SessionBuffer { + u8 *aBuf; /* Pointer to changeset buffer */ + int nBuf; /* Size of buffer aBuf */ + int nAlloc; /* Size of allocation containing aBuf */ +}; -static int sessionVarintPut(u8 *aBuf, u32 iVal){ - if( (iVal & ~0x7F)==0 ){ - if( aBuf ){ - aBuf[0] = (u8)iVal; - } - return 1; - } - if( (iVal & ~0x3FFF)==0 ){ - if( aBuf ){ - aBuf[0] = ((iVal >> 7) & 0x7F) | 0x80; - aBuf[1] = iVal & 0x7F; - } - return 2; - } - if( aBuf ){ - aBuf[0] = ((iVal >> 28) & 0x7F) | 0x80; - aBuf[1] = ((iVal >> 21) & 0x7F) | 0x80; - aBuf[2] = ((iVal >> 14) & 0x7F) | 0x80; - aBuf[3] = ((iVal >> 7) & 0x7F) | 0x80; - aBuf[4] = iVal & 0x7F; - } - return 5; +/* +** Write a varint with value iVal into the buffer at aBuf. Return the +** number of bytes written. +*/ +static int sessionVarintPut(u8 *aBuf, int iVal){ + return putVarint32(aBuf, iVal); } +/* +** Return the number of bytes required to store value iVal as a varint. +*/ +static int sessionVarintLen(int iVal){ + return sqlite3VarintLen(iVal); +} + +/* +** Read a varint value from aBuf[] into *piVal. Return the number of +** bytes read. +*/ static int sessionVarintGet(u8 *aBuf, int *piVal){ - int ret; - u64 v; - ret = (int)sqlite3GetVarint(aBuf, &v); - *piVal = (int)v; - return ret; + return getVarint32(aBuf, *piVal); } +/* +** Read a 64-bit big-endian integer value from buffer aRec[]. Return +** the value read. +*/ static sqlite3_int64 sessionGetI64(u8 *aRec){ return (((sqlite3_int64)aRec[0]) << 56) + (((sqlite3_int64)aRec[1]) << 48) @@ -168,6 +181,20 @@ static sqlite3_int64 sessionGetI64(u8 *aRec){ + (((sqlite3_int64)aRec[7]) << 0); } +/* +** Write a 64-bit big-endian integer value to the buffer aBuf[]. +*/ +static void sessionPutI64(u8 *aBuf, sqlite3_int64 i){ + aBuf[0] = (i>>56) & 0xFF; + aBuf[1] = (i>>48) & 0xFF; + aBuf[2] = (i>>40) & 0xFF; + aBuf[3] = (i>>32) & 0xFF; + aBuf[4] = (i>>24) & 0xFF; + aBuf[5] = (i>>16) & 0xFF; + aBuf[6] = (i>> 8) & 0xFF; + aBuf[7] = (i>> 0) & 0xFF; +} + /* ** This function is used to serialize the contents of value pValue (see ** comment titled "RECORD FORMAT" above). @@ -186,8 +213,8 @@ static int sessionSerializeValue( sqlite3_value *pValue, /* Value to serialize */ int *pnWrite /* IN/OUT: Increment by bytes written */ ){ - int eType; - int nByte; + int eType; /* Value type (SQLITE_NULL, TEXT etc.) */ + int nByte; /* Size of serialized value in bytes */ eType = sqlite3_value_type(pValue); if( aBuf ) aBuf[0] = eType; @@ -212,14 +239,7 @@ static int sessionSerializeValue( r = sqlite3_value_double(pValue); memcpy(&i, &r, 8); } - aBuf[1] = (i>>56) & 0xFF; - aBuf[2] = (i>>48) & 0xFF; - aBuf[3] = (i>>40) & 0xFF; - aBuf[4] = (i>>32) & 0xFF; - aBuf[5] = (i>>24) & 0xFF; - aBuf[6] = (i>>16) & 0xFF; - aBuf[7] = (i>> 8) & 0xFF; - aBuf[8] = (i>> 0) & 0xFF; + sessionPutI64(&aBuf[1], i); } nByte = 9; break; @@ -227,7 +247,7 @@ static int sessionSerializeValue( case SQLITE_TEXT: case SQLITE_BLOB: { int n = sqlite3_value_bytes(pValue); - int nVarint = sessionVarintPut(0, n); + int nVarint = sessionVarintLen(n); if( aBuf ){ sessionVarintPut(&aBuf[1], n); memcpy(&aBuf[nVarint + 1], eType==SQLITE_TEXT ? @@ -298,16 +318,29 @@ static int sessionGrowHash(sqlite3_session *pSession, SessionTable *pTab){ return SQLITE_OK; } +/* +** This function is only called from within a pre-update handler for a +** write to table pTab, part of session pSession. If this is the first +** write to this table, set the SessionTable.nCol variable to the number +** of columns in the table. +** +** Otherwise, if this is not the first time this table has been written +** to, check that the number of columns in the table has not changed. If +** it has not, return zero. +** +** If the number of columns in the table has changed since the last write +** was recorded, set the session error-code to SQLITE_SCHEMA and return +** non-zero. Users are not allowed to change the number of columns in a table +** for which changes are being recorded by the session module. If they do so, +** it is an error. +*/ static int sessionInitTable(sqlite3_session *pSession, SessionTable *pTab){ if( pTab->nCol==0 ){ pTab->nCol = sqlite3_preupdate_count(pSession->db); - } - - if( pTab->nCol!=sqlite3_preupdate_count(pSession->db) ){ + }else if( pTab->nCol!=sqlite3_preupdate_count(pSession->db) ){ pSession->rc = SQLITE_SCHEMA; return SQLITE_ERROR; } - return SQLITE_OK; } @@ -329,8 +362,15 @@ static void xPreUpdate( for(pSession=(sqlite3_session *)pCtx; pSession; pSession=pSession->pNext){ SessionTable *pTab; + + /* If this session is already in the error-state, or if it is attached + ** to a different database ("main", "temp" etc.), or if it is not + ** currently enabled, there is nothing to do. Skip to the next session + ** object attached to this database. */ + if( pSession->bEnable==0 ) continue; if( pSession->rc ) continue; if( sqlite3_strnicmp(zDb, pSession->zDb, nDb+1) ) continue; + for(pTab=pSession->pTable; pTab; pTab=pTab->pNext){ if( 0==sqlite3_strnicmp(pTab->zName, zName, nName+1) ){ SessionChange *pChange; @@ -365,16 +405,16 @@ static void xPreUpdate( memset(pChange, 0, sizeof(SessionChange)); } }else{ - int nByte; /* Number of bytes to allocate */ - int i; /* Used to iterate through columns */ - sqlite3_value *pValue; + int nByte; /* Number of bytes to allocate */ + int i; /* Used to iterate through columns */ /* Figure out how large an allocation is required */ nByte = sizeof(SessionChange); for(i=0; inCol && rc==SQLITE_OK; i++){ - rc = sqlite3_preupdate_old(pSession->db, i, &pValue); + sqlite3_value *p; /* old.* value */ + rc = sqlite3_preupdate_old(pSession->db, i, &p); if( rc==SQLITE_OK ){ - rc = sessionSerializeValue(0, pValue, &nByte); + rc = sessionSerializeValue(0, p, &nByte); } } @@ -390,10 +430,10 @@ static void xPreUpdate( /* Populate the change object */ nByte = 0; for(i=0; inCol && rc==SQLITE_OK; i++){ - rc = sqlite3_preupdate_old(pSession->db, i, &pValue); + sqlite3_value *p; /* old.* value */ + rc = sqlite3_preupdate_old(pSession->db, i, &p); if( rc==SQLITE_OK ){ - rc = sessionSerializeValue( - &pChange->aRecord[nByte], pValue, &nByte); + rc = sessionSerializeValue(&pChange->aRecord[nByte], p, &nByte); } } pChange->nRecord = nByte; @@ -410,8 +450,8 @@ static void xPreUpdate( pChange->iKey = iKey2; pChange->pNext = pTab->apChange[iHash]; pTab->apChange[iHash] = pChange; + break; } - break; } } } @@ -425,10 +465,11 @@ int sqlite3session_create( const char *zDb, /* Name of db (e.g. "main") */ sqlite3_session **ppSession /* OUT: New session object */ ){ - sqlite3_session *pNew; - sqlite3_session *pOld; + sqlite3_session *pNew; /* Newly allocated session object */ + sqlite3_session *pOld; /* Session object already attached to db */ int nDb = strlen(zDb); /* Length of zDb in bytes */ + /* Zero the output value in case an error occurs. */ *ppSession = 0; /* Allocate and populate the new session object. */ @@ -437,6 +478,7 @@ int sqlite3session_create( memset(pNew, 0, sizeof(sqlite3_session)); pNew->db = db; pNew->zDb = (char *)&pNew[1]; + pNew->bEnable = 1; memcpy(pNew->zDb, zDb, nDb+1); /* Add the new session object to the linked list of session objects @@ -459,6 +501,8 @@ void sqlite3session_delete(sqlite3_session *pSession){ sqlite3_session *pHead; sqlite3_session **pp; + /* Unlink the session from the linked list of sessions attached to the + ** database handle. Hold the db mutex while doing so. */ sqlite3_mutex_enter(sqlite3_db_mutex(db)); pHead = (sqlite3_session*)sqlite3_preupdate_hook(db, 0, 0); for(pp=&pHead; (*pp)!=pSession; pp=&((*pp)->pNext)); @@ -466,6 +510,8 @@ void sqlite3session_delete(sqlite3_session *pSession){ if( pHead ) sqlite3_preupdate_hook(db, xPreUpdate, (void *)pHead); sqlite3_mutex_leave(sqlite3_db_mutex(db)); + /* Delete all attached table objects. And the contents of their + ** associated hash-tables. */ while( pSession->pTable ){ int i; SessionTable *pTab = pSession->pTable; @@ -482,6 +528,7 @@ void sqlite3session_delete(sqlite3_session *pSession){ sqlite3_free(pTab); } + /* Free the session object itself. */ sqlite3_free(pSession); } @@ -497,8 +544,8 @@ int sqlite3session_attach( sqlite3_session *pSession, /* Session object */ const char *zName /* Table name */ ){ - SessionTable *pTab; - int nName; + SessionTable *pTab; /* New table object (if required) */ + int nName; /* Number of bytes in string zName */ /* First search for an existing entry. If one is found, this call is ** a no-op. Return early. */ @@ -523,13 +570,13 @@ int sqlite3session_attach( return SQLITE_OK; } -typedef struct SessionBuffer SessionBuffer; -struct SessionBuffer { - u8 *aBuf; /* Pointer to changeset buffer */ - int nBuf; /* Size of buffer aBuf */ - int nAlloc; /* Size of allocation containing aBuf */ -}; - +/* +** Ensure that there is room in the buffer to append nByte bytes of data. +** If not, use sqlite3_realloc() to grow the buffer so that there is. +** +** If successful, return zero. Otherwise, if an OOM condition is encountered, +** set *pRc to SQLITE_NOMEM and return non-zero. +*/ static int sessionBufferGrow(SessionBuffer *p, int nByte, int *pRc){ if( p->nAlloc-p->nBufaBuf[p->nBuf++] = v; } } +/* +** This function is a no-op if *pRc is other than SQLITE_OK when it is +** called. Otherwise, append a single varint to the buffer. +** +** If an OOM condition is encountered, set *pRc to SQLITE_NOMEM before +** returning. +*/ static void sessionAppendVarint(SessionBuffer *p, sqlite3_int64 v, int *pRc){ if( *pRc==SQLITE_OK && 0==sessionBufferGrow(p, 9, pRc) ){ p->nBuf += sessionVarintPut(&p->aBuf[p->nBuf], v); } } +/* +** This function is a no-op if *pRc is other than SQLITE_OK when it is +** called. Otherwise, append a blob of data to the buffer. +** +** If an OOM condition is encountered, set *pRc to SQLITE_NOMEM before +** returning. +*/ static void sessionAppendBlob( SessionBuffer *p, const u8 *aBlob, @@ -573,6 +641,14 @@ static void sessionAppendBlob( } } +/* +** This function is a no-op if *pRc is other than SQLITE_OK when it is +** called. Otherwise, append a string to the buffer. All bytes in the string +** up to (but not including) the nul-terminator are written to the buffer. +** +** If an OOM condition is encountered, set *pRc to SQLITE_NOMEM before +** returning. +*/ static void sessionAppendStr( SessionBuffer *p, const char *zStr, @@ -585,20 +661,37 @@ static void sessionAppendStr( } } +/* +** This function is a no-op if *pRc is other than SQLITE_OK when it is +** called. Otherwise, append the string representation of integer iVal +** to the buffer. No nul-terminator is written. +** +** If an OOM condition is encountered, set *pRc to SQLITE_NOMEM before +** returning. +*/ static void sessionAppendInteger( - SessionBuffer *p, - int iVal, - int *pRc + SessionBuffer *p, /* Buffer to append to */ + int iVal, /* Value to write the string rep. of */ + int *pRc /* IN/OUT: Error code */ ){ char aBuf[24]; sqlite3_snprintf(sizeof(aBuf)-1, aBuf, "%d", iVal); sessionAppendStr(p, aBuf, pRc); } +/* +** This function is a no-op if *pRc is other than SQLITE_OK when it is +** called. Otherwise, append the string zStr enclosed in quotes (") and +** with any embedded quote characters escaped to the buffer. No +** nul-terminator byte is written. +** +** If an OOM condition is encountered, set *pRc to SQLITE_NOMEM before +** returning. +*/ static void sessionAppendIdent( - SessionBuffer *p, - const char *zStr, - int *pRc + SessionBuffer *p, /* Buffer to a append to */ + const char *zStr, /* String to quote, escape and append */ + int *pRc /* IN/OUT: Error code */ ){ int nStr = strlen(zStr)*2 + 2 + 1; if( *pRc==SQLITE_OK && 0==sessionBufferGrow(p, nStr, pRc) ){ @@ -614,11 +707,17 @@ static void sessionAppendIdent( } } +/* +** This function is a no-op if *pRc is other than SQLITE_OK when it is +** called. Otherwse, it appends the serialized version of the value stored +** in column iCol of the row that SQL statement pStmt currently points +** to to the buffer. +*/ static void sessionAppendCol( - SessionBuffer *p, - sqlite3_stmt *pStmt, - int iCol, - int *pRc + SessionBuffer *p, /* Buffer to append to */ + sqlite3_stmt *pStmt, /* Handle pointing to row containing value */ + int iCol, /* Column to read value from */ + int *pRc /* IN/OUT: Error code */ ){ if( *pRc==SQLITE_OK ){ int eType = sqlite3_column_type(pStmt, iCol); @@ -632,14 +731,7 @@ static void sessionAppendCol( double r = sqlite3_column_double(pStmt, iCol); memcpy(&i, &r, 8); } - aBuf[0] = (i>>56) & 0xFF; - aBuf[1] = (i>>48) & 0xFF; - aBuf[2] = (i>>40) & 0xFF; - aBuf[3] = (i>>32) & 0xFF; - aBuf[4] = (i>>24) & 0xFF; - aBuf[5] = (i>>16) & 0xFF; - aBuf[6] = (i>> 8) & 0xFF; - aBuf[7] = (i>> 0) & 0xFF; + sessionPutI64(aBuf, i); sessionAppendBlob(p, aBuf, 8, pRc); } if( eType==SQLITE_BLOB || eType==SQLITE_TEXT ){ @@ -653,18 +745,43 @@ static void sessionAppendCol( } } +/* +** This function is a no-op if *pRc is other than SQLITE_OK when it is +** called. +** +** Otherwse, if *pRc is SQLITE_OK, then it appends an update change to +** the buffer (see the comments under "CHANGESET FORMAT" at the top of the +** file). An update change consists of: +** +** 1 byte: SQLITE_UPDATE (0x17) +** n bytes: old.* record (see RECORD FORMAT) +** m bytes: new.* record (see RECORD FORMAT) +** +** The SessionChange object passed as the third argument contains the +** values that were stored in the row when the session began (the old.* +** values). The statement handle passed as the second argument points +** at the current version of the row (the new.* values). +** +** If all of the old.* values are equal to their corresponding new.* value +** (i.e. nothing has changed), then no data at all is appended to the buffer. +** +** Otherwise, the old.* record contains all primary key values and the +** original values of any fields that have been modified. The new.* record +** contains the new values of only those fields that have been modified. +*/ static void sessionAppendUpdate( - sqlite3_stmt *pStmt, - SessionBuffer *pBuf, - SessionChange *p, - u8 *abPK, - int *pRc + SessionBuffer *pBuf, /* Buffer to append to */ + sqlite3_stmt *pStmt, /* Statement handle pointing at new row */ + SessionChange *p, /* Object containing old values */ + u8 *abPK, /* Boolean array - true for PK columns */ + int *pRc /* IN/OUT: Error code */ ){ if( *pRc==SQLITE_OK ){ - SessionBuffer buf2 = {0, 0, 0}; - int bNoop = 1; - int i; - u8 *pCsr = p->aRecord; + SessionBuffer buf2 = {0,0,0}; /* Buffer to accumulate new.* record in */ + int bNoop = 1; /* Set to zero if any values are modified */ + int i; /* Used to iterate through columns */ + u8 *pCsr = p->aRecord; /* Used to iterate through old.* values */ + sessionAppendByte(pBuf, SQLITE_UPDATE, pRc); for(i=0; idb; - SessionTable *pTab; - SessionBuffer buf = {0, 0, 0}; - int rc; + sqlite3 *db = pSession->db; /* Source database handle */ + SessionTable *pTab; /* Used to iterate through attached tables */ + SessionBuffer buf = {0,0,0}; /* Buffer in which to accumlate changeset */ + int rc; /* Return code */ + /* Zero the output variables in case an error occurs. If this session + ** object is already in the error state (sqlite3_session.rc != SQLITE_OK), + ** this call will be a no-op. */ *pnChangeset = 0; *ppChangeset = 0; rc = pSession->rc; @@ -879,7 +1031,8 @@ int sqlite3session_changeset( } if( rc==SQLITE_OK ){ - rc = sessionTableInfo(db, pTab->zName, pTab->nCol, 0, 0, &abPK); + rc = sessionTableInfo( + db, pSession->zDb, pTab->zName, pTab->nCol, 0, 0, &abPK); } for(i=0; inChange; i++){ @@ -889,7 +1042,7 @@ int sqlite3session_changeset( if( sqlite3_step(pStmt)==SQLITE_ROW ){ int iCol; if( p->aRecord ){ - sessionAppendUpdate(pStmt, &buf, p, abPK, &rc); + sessionAppendUpdate(&buf, pStmt, p, abPK, &rc); }else{ sessionAppendByte(&buf, SQLITE_INSERT, &rc); for(iCol=0; iColnCol; iCol++){ @@ -922,67 +1075,78 @@ int sqlite3session_changeset( }else{ sqlite3_free(buf.aBuf); } - return rc; } +/* +** Enable or disable the session object passed as the first argument. +*/ int sqlite3session_enable(sqlite3_session *pSession, int bEnable){ - return bEnable; + if( bEnable>=0 ){ + pSession->bEnable = bEnable; + } + return pSession->bEnable; } -/************************************************************************/ -/************************************************************************/ -/************************************************************************/ - -struct sqlite3_changeset_iter { - u8 *aChangeset; /* Pointer to buffer containing changeset */ - int nChangeset; /* Number of bytes in aChangeset */ - u8 *pNext; /* Pointer to next change within aChangeset */ - int rc; - - sqlite3_stmt *pConflict; /* Conflicting row, if any */ - char *zTab; /* Current table */ - int nCol; /* Number of columns in zTab */ - int op; /* Current operation */ - sqlite3_value **apValue; /* old.* and new.* values */ -}; - /* ** Create an iterator used to iterate through the contents of a changeset. */ int sqlite3changeset_start( - sqlite3_changeset_iter **ppIter, - int nChangeset, - void *pChangeset + sqlite3_changeset_iter **pp, /* OUT: Changeset iterator handle */ + int nChangeset, /* Size of buffer pChangeset in bytes */ + void *pChangeset /* Pointer to buffer containing changeset */ ){ sqlite3_changeset_iter *pRet; /* Iterator to return */ int nByte; /* Number of bytes to allocate for iterator */ - *ppIter = 0; + /* Zero the output variable in case an error occurs. */ + *pp = 0; + /* Allocate and initialize the iterator structure. */ nByte = sizeof(sqlite3_changeset_iter); pRet = (sqlite3_changeset_iter *)sqlite3_malloc(nByte); if( !pRet ) return SQLITE_NOMEM; memset(pRet, 0, sizeof(sqlite3_changeset_iter)); - pRet->aChangeset = (u8 *)pChangeset; pRet->nChangeset = nChangeset; pRet->pNext = pRet->aChangeset; - *ppIter = pRet; + /* Populate the output variable and return success. */ + *pp = pRet; return SQLITE_OK; } +/* +** Deserialize a single record from a buffer in memory. See "RECORD FORMAT" +** for details. +** +** When this function is called, *paChange points to the start of the record +** to deserialize. Assuming no error occurs, *paChange is set to point to +** one byte after the end of the same record before this function returns. +** +** If successful, each element of the apOut[] array (allocated by the caller) +** is set to point to an sqlite3_value object containing the value read +** from the corresponding position in the record. If that value is not +** included in the record (i.e. because the record is part of an UPDATE change +** and the field was not modified), the corresponding element of apOut[] is +** set to NULL. +** +** It is the responsibility of the caller to free all sqlite_value structures +** using sqlite3_free(). +** +** If an error occurs, an SQLite error code (e.g. SQLITE_NOMEM) is returned. +** The apOut[] array may have been partially populated in this case. +*/ static int sessionReadRecord( u8 **paChange, /* IN/OUT: Pointer to binary record */ int nCol, /* Number of values in record */ sqlite3_value **apOut /* Write values to this array */ ){ - int i; - u8 *aRec = *paChange; + int i; /* Used to iterate through columns */ + u8 *aRec = *paChange; /* Cursor for the serialized record */ for(i=0; irc!=SQLITE_OK ) return p->rc; + /* Free the current contents of p->apValue[]. */ if( p->apValue ){ for(i=0; inCol*2; i++){ sqlite3ValueFree(p->apValue[i]); @@ -1090,7 +1256,7 @@ int sqlite3changeset_next(sqlite3_changeset_iter *p){ ** has returned SQLITE_ROW. */ int sqlite3changeset_op( - sqlite3_changeset_iter *pIter, + sqlite3_changeset_iter *pIter, /* Iterator handle */ const char **pzTab, /* OUT: Pointer to table name */ int *pnCol, /* OUT: Number of columns in table */ int *pOp /* OUT: SQLITE_INSERT, DELETE or UPDATE */ @@ -1101,9 +1267,22 @@ int sqlite3changeset_op( return SQLITE_OK; } +/* +** This function may only be called while the iterator is pointing to an +** SQLITE_UPDATE or SQLITE_DELETE change (see sqlite3changeset_op()). +** Otherwise, SQLITE_MISUSE is returned. +** +** It sets *ppValue to point to an sqlite3_value structure containing the +** iVal'th value in the old.* record. Or, if that particular value is not +** included in the record (because the change is an UPDATE and the field +** was not modified and is not a PK column), set *ppValue to NULL. +** +** If value iVal is out-of-range, SQLITE_RANGE is returned and *ppValue is +** not modified. Otherwise, SQLITE_OK. +*/ int sqlite3changeset_old( - sqlite3_changeset_iter *pIter, - int iVal, + sqlite3_changeset_iter *pIter, /* Changeset iterator */ + int iVal, /* Index of old.* value to retrieve */ sqlite3_value **ppValue /* OUT: Old value (or NULL pointer) */ ){ if( pIter->op!=SQLITE_UPDATE && pIter->op!=SQLITE_DELETE ){ @@ -1116,9 +1295,22 @@ int sqlite3changeset_old( return SQLITE_OK; } +/* +** This function may only be called while the iterator is pointing to an +** SQLITE_UPDATE or SQLITE_INSERT change (see sqlite3changeset_op()). +** Otherwise, SQLITE_MISUSE is returned. +** +** It sets *ppValue to point to an sqlite3_value structure containing the +** iVal'th value in the new.* record. Or, if that particular value is not +** included in the record (because the change is an UPDATE and the field +** was not modified), set *ppValue to NULL. +** +** If value iVal is out-of-range, SQLITE_RANGE is returned and *ppValue is +** not modified. Otherwise, SQLITE_OK. +*/ int sqlite3changeset_new( - sqlite3_changeset_iter *pIter, - int iVal, + sqlite3_changeset_iter *pIter, /* Changeset iterator */ + int iVal, /* Index of new.* value to retrieve */ sqlite3_value **ppValue /* OUT: New value (or NULL pointer) */ ){ if( pIter->op!=SQLITE_UPDATE && pIter->op!=SQLITE_INSERT ){ @@ -1131,9 +1323,20 @@ int sqlite3changeset_new( return SQLITE_OK; } +/* +** This function may only be called with a changeset iterator that has been +** passed to an SQLITE_CHANGESET_DATA or SQLITE_CHANGESET_CONFLICT +** conflict-handler function. Otherwise, SQLITE_MISUSE is returned. +** +** If successful, *ppValue is set to point to an sqlite3_value structure +** containing the iVal'th value of the conflicting record. +** +** If value iVal is out-of-range or some other error occurs, an SQLite error +** code is returned. Otherwise, SQLITE_OK. +*/ int sqlite3changeset_conflict( - sqlite3_changeset_iter *pIter, - int iVal, + sqlite3_changeset_iter *pIter, /* Changeset iterator */ + int iVal, /* Index of conflict record value to fetch */ sqlite3_value **ppValue /* OUT: Value from conflicting row */ ){ if( !pIter->pConflict ){ @@ -1153,8 +1356,8 @@ int sqlite3changeset_conflict( ** callback by changeset_apply(). */ int sqlite3changeset_finalize(sqlite3_changeset_iter *p){ - int i; - int rc = p->rc; + int i; /* Used to iterate through p->apValue[] */ + int rc = p->rc; /* Return code */ for(i=0; inCol*2; i++) sqlite3ValueFree(p->apValue[i]); sqlite3_free(p->apValue); sqlite3_free(p); @@ -1238,48 +1441,6 @@ int sqlite3changeset_invert( return SQLITE_OK; } -static void sessionUpdateDeleteWhere( - SessionBuffer *pBuf, /* Buffer to append to */ - int nCol, /* Number of entries in azCol and abPK */ - const char **azCol, /* Column names */ - u8 *abPK, /* True for PK columns */ - int *pRc /* IN/OUT: Error code */ -){ - if( *pRc==SQLITE_OK ){ - int i; - const char *zSep = ""; - - sessionAppendStr(pBuf, " WHERE ", pRc); - - for(i=0; inCol, p->azCol, p->abPK, &rc); + sessionAppendStr(&buf, " WHERE ", &rc); + + for(i=0; inCol; i++){ + if( p->abPK[i] ){ + sessionAppendStr(&buf, zSep, &rc); + sessionAppendIdent(&buf, p->azCol[i], &rc); + sessionAppendStr(&buf, " = ?", &rc); + sessionAppendInteger(&buf, i+1, &rc); + zSep = "AND "; + } + } + + sessionAppendStr(&buf, " AND (?", &rc); + sessionAppendInteger(&buf, p->nCol+1, &rc); + sessionAppendStr(&buf, " OR ", &rc); + + zSep = ""; + for(i=0; inCol; i++){ + if( !p->abPK[i] ){ + sessionAppendStr(&buf, zSep, &rc); + sessionAppendIdent(&buf, p->azCol[i], &rc); + sessionAppendStr(&buf, " IS ?", &rc); + sessionAppendInteger(&buf, i+1, &rc); + zSep = "AND "; + } + } + sessionAppendStr(&buf, ")", &rc); if( rc==SQLITE_OK ){ rc = sqlite3_prepare_v2(db, (char *)buf.aBuf, buf.nBuf, &p->pDelete, 0); @@ -1354,6 +1546,8 @@ static int sessionDeleteRow( ** conflict-handler is invoked with CHANGESET_DATA and returns ** CHANGESET_REPLACE. This is variable "?(nCol*3+1)". ** +** If successful, SQLITE_OK is returned and SessionApplyCtx.pUpdate is left +** pointing to the prepared version of the SQL statement. */ static int sessionUpdateRow( sqlite3 *db, /* Database handle */ @@ -1420,6 +1614,19 @@ static int sessionUpdateRow( return rc; } +/* +** Formulate and prepare an SQL statement to query table zTab by primary +** key. Assuming the following table structure: +** +** CREATE TABLE x(a, b, c, d, PRIMARY KEY(a, c)); +** +** The SELECT statement looks like this: +** +** SELECT * FROM x WHERE a = ?1 AND c = ?3 +** +** If successful, SQLITE_OK is returned and SessionApplyCtx.pSelect is left +** pointing to the prepared version of the SQL statement. +*/ static int sessionSelectRow( sqlite3 *db, /* Database handle */ const char *zTab, /* Table name */ @@ -1449,6 +1656,15 @@ static int sessionSelectRow( return rc; } +/* +** Formulate and prepare an INSERT statement to add a record to table zTab. +** For example: +** +** INSERT INTO main."zTab" VALUES(?1, ?2, ?3 ...); +** +** If successful, SQLITE_OK is returned and SessionApplyCtx.pInsert is left +** pointing to the prepared version of the SQL statement. +*/ static int sessionInsertRow( sqlite3 *db, /* Database handle */ const char *zTab, /* Table name */ @@ -1473,18 +1689,32 @@ static int sessionInsertRow( return rc; } +/* +** SQL statement pSelect is as generated by the sessionSelectRow() function. +** This function binds the primary key values from the change that changeset +** iterator pIter points to to the SELECT and attempts to seek to the table +** entry. If a row is found, the SELECT statement left pointing at the row +** and SQLITE_ROW is returned. Otherwise, if no row is found and no error +** has occured, the statement is reset and SQLITE_OK is returned. If an +** error occurs, an SQLite error code is returned. +** +** If the iterator currently points to an INSERT record, bind values from the +** new.* record to the SELECT statement. Or, if it points to a DELETE, bind +** values from the old.* record. If the changeset iterator points to an +** UPDATE, bind values from the new.* record, but use old.* values in place +** of any undefined new.* values. +*/ static int sessionSeekToRow( sqlite3 *db, /* Database handle */ sqlite3_changeset_iter *pIter, /* Changeset iterator */ u8 *abPK, /* Primary key flags array */ sqlite3_stmt *pSelect /* SELECT statement from sessionSelectRow() */ ){ - int rc = SQLITE_OK; - - int i; - int nCol; - int op; - const char *zDummy; + int rc = SQLITE_OK; /* Return code */ + int i; /* Used to iterate through table columns */ + int nCol; /* Number of columns in table */ + int op; /* Changset operation (SQLITE_UPDATE etc.) */ + const char *zDummy; /* Unused */ sqlite3changeset_op(pIter, &zDummy, &nCol, &op); @@ -1511,15 +1741,50 @@ static int sessionSeekToRow( return rc; } +/* +** Invoke the conflict handler for the change that the changeset iterator +** currently points to. +** +** Argument eType must be either CHANGESET_DATA or CHANGESET_CONFLICT. +** If argument pbReplace is NULL, then the type of conflict handler invoked +** depends solely on eType, as follows: +** +** eType value Value passed to xConflict +** ------------------------------------------------- +** CHANGESET_DATA CHANGESET_NOTFOUND +** CHANGESET_CONFLICT CHANGESET_CONSTRAINT +** +** Or, if pbReplace is not NULL, then an attempt is made to find an existing +** record with the same primary key as the record about to be deleted, updated +** or inserted. If such a record can be found, it is available to the conflict +** handler as the "conflicting" record. In this case the type of conflict +** handler invoked is as follows: +** +** eType value PK Record found? Value passed to xConflict +** ---------------------------------------------------------------- +** CHANGESET_DATA Yes CHANGESET_DATA +** CHANGESET_DATA No CHANGESET_NOTFOUND +** CHANGESET_CONFLICT Yes CHANGESET_CONFLICT +** CHANGESET_CONFLICT No CHANGESET_CONSTRAINT +** +** If pbReplace is not NULL, and a record with a matching PK is found, and +** the conflict handler function returns SQLITE_CHANGESET_REPLACE, *pbReplace +** is set to non-zero before returning SQLITE_OK. +** +** If the conflict handler returns SQLITE_CHANGESET_ABORT, SQLITE_ABORT is +** returned. Or, if the conflict handler returns an invalid value, +** SQLITE_MISUSE. If the conflict handler returns SQLITE_CHANGESET_OMIT, +** this function returns SQLITE_OK. +*/ static int sessionConflictHandler( - int eType, - SessionApplyCtx *p, + int eType, /* Either CHANGESET_DATA or CONFLICT */ + SessionApplyCtx *p, /* changeset_apply() context */ sqlite3_changeset_iter *pIter, /* Changeset iterator */ int(*xConflict)(void *, int, sqlite3_changeset_iter*), - void *pCtx, - int *pbReplace + void *pCtx, /* First argument for conflict handler */ + int *pbReplace /* OUT: Set to true if PK row is found */ ){ - int res; + int res; /* Value returned by conflict handler */ int rc; int nCol; int op; @@ -1575,13 +1840,37 @@ static int sessionConflictHandler( return rc; } +/* +** Attempt to apply the change that the iterator passed as the first argument +** currently points to to the database. If a conflict is encountered, invoke +** the conflict handler callback. +** +** If argument pbRetry is NULL, then ignore any CHANGESET_DATA conflict. If +** one is encountered, update or delete the row with the matching primary key +** instead. Or, if pbRetry is not NULL and a CHANGESET_DATA conflict occurs, +** invoke the conflict handler. If it returns CHANGESET_REPLACE, set *pbRetry +** to true before returning. In this case the caller will invoke this function +** again, this time with pbRetry set to NULL. +** +** If argument pbReplace is NULL and a CHANGESET_CONFLICT conflict is +** encountered invoke the conflict handler with CHANGESET_CONSTRAINT instead. +** Or, if pbReplace is not NULL, invoke it with CHANGESET_CONFLICT. If such +** an invocation returns SQLITE_CHANGESET_REPLACE, set *pbReplace to true +** before retrying. In this case the caller attempts to remove the conflicting +** row before invoking this function again, this time with pbReplace set +** to NULL. +** +** If any conflict handler returns SQLITE_CHANGESET_ABORT, this function +** returns SQLITE_ABORT. Otherwise, if no error occurs, SQLITE_OK is +** returned. +*/ static int sessionApplyOneOp( - sqlite3_changeset_iter *pIter, - SessionApplyCtx *p, + sqlite3_changeset_iter *pIter, /* Changeset iterator */ + SessionApplyCtx *p, /* changeset_apply() context */ int(*xConflict)(void *, int, sqlite3_changeset_iter *), - void *pCtx, - int *pbReplace, - int *pbRetry + void *pCtx, /* First argument for the conflict handler */ + int *pbReplace, /* OUT: True to remove PK row and retry */ + int *pbRetry /* OUT: True to retry. */ ){ const char *zDummy; int op; @@ -1702,27 +1991,29 @@ static int sessionApplyOneOp( return rc; } +/* +** Apply the changeset passed via pChangeset/nChangeset to the main database +** attached to handle "db". Invoke the supplied conflict handler callback +** to resolve any conflicts encountered while applying the change. +*/ int sqlite3changeset_apply( - sqlite3 *db, - int nChangeset, - void *pChangeset, + sqlite3 *db, /* Apply change to "main" db of this handle */ + int nChangeset, /* Size of changeset in bytes */ + void *pChangeset, /* Changeset blob */ int(*xConflict)( void *pCtx, /* Copy of fifth arg to _apply() */ int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */ sqlite3_changeset_iter *p /* Handle describing change and conflict */ ), - void *pCtx + void *pCtx /* First argument passed to xConflict */ ){ - sqlite3_changeset_iter *pIter = 0; - int rc; - int rc2; - + sqlite3_changeset_iter *pIter; /* Iterator to skip through changeset */ + int rc; /* Return code */ const char *zTab = 0; /* Name of current table */ int nTab = 0; /* Result of strlen(zTab) */ + SessionApplyCtx sApply; /* changeset_apply() context object */ - SessionApplyCtx sApply; memset(&sApply, 0, sizeof(sApply)); - sqlite3changeset_start(&pIter, nChangeset, pChangeset); rc = sqlite3_exec(db, "SAVEPOINT changeset_apply", 0, 0, 0); @@ -1744,7 +2035,8 @@ int sqlite3changeset_apply( sApply.db = db; sApply.nCol = nCol; - rc = sessionTableInfo(db, zNew, nCol, &zTab, &sApply.azCol, &sApply.abPK); + rc = sessionTableInfo( + db, "main", zNew, nCol, &zTab, &sApply.azCol, &sApply.abPK); if( rc!=SQLITE_OK || (rc = sessionSelectRow(db, zTab, &sApply)) @@ -1795,8 +2087,11 @@ int sqlite3changeset_apply( } } - rc2 = sqlite3changeset_finalize(pIter); - if( rc==SQLITE_OK ) rc = rc2; + if( rc==SQLITE_OK ){ + rc = sqlite3changeset_finalize(pIter); + }else{ + sqlite3changeset_finalize(pIter); + } if( rc==SQLITE_OK ){ rc = sqlite3_exec(db, "RELEASE changeset_apply", 0, 0, 0); diff --git a/ext/session/sqlite3session.h b/ext/session/sqlite3session.h index a034dca9ec..c4053e3dbe 100644 --- a/ext/session/sqlite3session.h +++ b/ext/session/sqlite3session.h @@ -69,7 +69,6 @@ int sqlite3session_changeset( */ void sqlite3session_delete(sqlite3_session *pSession); - /* ** Create an iterator used to iterate through the contents of a changeset. */ @@ -95,23 +94,22 @@ int sqlite3changeset_next(sqlite3_changeset_iter *pIter); ** has returned SQLITE_ROW. */ int sqlite3changeset_op( - sqlite3_changeset_iter *pIter, /* Iterator object */ - const char **pzTab, /* OUT: Pointer to table name */ - int *pnCol, /* OUT: Number of columns in table */ - int *pOp /* OUT: SQLITE_INSERT, DELETE or UPDATE */ + sqlite3_changeset_iter *pIter, /* Iterator object */ + const char **pzTab, /* OUT: Pointer to table name */ + int *pnCol, /* OUT: Number of columns in table */ + int *pOp /* OUT: SQLITE_INSERT, DELETE or UPDATE */ ); - int sqlite3changeset_old( - sqlite3_changeset_iter *pIter, - int iVal, - sqlite3_value **ppValue /* OUT: Old value (or NULL pointer) */ + sqlite3_changeset_iter *pIter, /* Changeset iterator */ + int iVal, /* Column number */ + sqlite3_value **ppValue /* OUT: Old value (or NULL pointer) */ +); +int sqlite3changeset_new( + sqlite3_changeset_iter *pIter, /* Changeset iterator */ + int iVal, /* Column number */ + sqlite3_value **ppValue /* OUT: New value (or NULL pointer) */ ); -int sqlite3changeset_new( - sqlite3_changeset_iter *pIter, - int iVal, - sqlite3_value **ppValue /* OUT: New value (or NULL pointer) */ -); /* ** This function is only usable with sqlite3_changeset_iter objects passed ** to the xConflict callback by sqlite3changeset_apply(). It cannot be used @@ -122,8 +120,8 @@ int sqlite3changeset_new( ** or SQLITE_CHANGESET_CONFLICT. */ int sqlite3changeset_conflict( - sqlite3_changeset_iter *pIter, - int iVal, + sqlite3_changeset_iter *pIter, /* Changeset iterator */ + int iVal, /* Column number */ sqlite3_value **ppValue /* OUT: Value from conflicting row */ ); @@ -153,15 +151,15 @@ int sqlite3changeset_invert( ** resolution strategy. */ int sqlite3changeset_apply( - sqlite3 *db, - int nChangeset, - void *pChangeset, + sqlite3 *db, /* Apply change to "main" db of this handle */ + int nChangeset, /* Size of changeset in bytes */ + void *pChangeset, /* Changeset blob */ int(*xConflict)( void *pCtx, /* Copy of fifth arg to _apply() */ int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */ sqlite3_changeset_iter *p /* Handle describing change and conflict */ ), - void *pCtx + void *pCtx /* First argument passed to xConflict */ ); /* diff --git a/manifest b/manifest index 89b9043680..7e8b8c7747 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\shandling\sof\sreturn\svalues\sfrom\sthe\sconflict\shandler.\sDocument\sthe\sconflict\shandler\sarguments\sand\sreturn\scodes\sin\ssqlite3session.h. -D 2011-03-14T19:49:23 +C Fix\ssome\sbugs\sand\sother\scode\sissues\sin\sthe\ssession\smodule. +D 2011-03-15T16:37:28 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -98,8 +98,8 @@ F ext/rtree/rtree_util.tcl 06aab2ed5b826545bf215fff90ecb9255a8647ea F ext/rtree/sqlite3rtree.h 1af0899c63a688e272d69d8e746f24e76f10a3f0 F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 -F ext/session/sqlite3session.c 111a988b4734b7419f23bb07e45bf5e991510270 -F ext/session/sqlite3session.h 55ca208bddbc1284c83427f423748eb720f5c68f +F ext/session/sqlite3session.c 9b8d123418c024f6851163375fca99042757772f +F ext/session/sqlite3session.h 01aac9a1185b7db6716217f3aa3f7a835ab864b9 F ext/session/test_session.c 2559ef68e421c7fb83e2c19ef08a17343b70d535 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 @@ -639,7 +639,7 @@ F test/selectA.test 06d1032fa9009314c95394f2ca2e60d9f7ae8532 F test/selectB.test f305cc6660804cb239aab4e2f26b0e288b59958b F test/selectC.test f9bf1bc4581b5b8158caa6e4e4f682acb379fb25 F test/server1.test f5b790d4c0498179151ca8a7715a65a7802c859c -F test/session1.test edbd6078b86b3f6337d779552671125fbd885e19 +F test/session1.test 1e85c2eedb14587dff41901faa5a66c117fe0405 F test/shared.test b9114eaea7e748a3a4c8ff7b9ca806c8f95cef3e F test/shared2.test 7f6ad2d857d0f4e5d6a0b9a897b5e56a6b6ea18c F test/shared3.test d69bdd5f156580876c5345652d21dc2092e85962 @@ -913,7 +913,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 57862efe718fdc93401998f9058511292a0e1a50 -R 17f2f6e54c1cfa1876ed6a58e92b5c4b +P cbbb274e500237dbf7155a51d4f9c17583d704ea +R c267abdc5c97771dbd3d62995c13d672 U dan -Z e9add8546b195a8b303123ffee5a5609 +Z 5fed91a90fa4060d0a5ac8127dba8c51 diff --git a/manifest.uuid b/manifest.uuid index f68965ee4d..79ca836129 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cbbb274e500237dbf7155a51d4f9c17583d704ea \ No newline at end of file +f2930840e4af3d7d9cb199d316502932fcbbb867 \ No newline at end of file diff --git a/test/session1.test b/test/session1.test index 46b9d3442d..ca8d9a78f1 100644 --- a/test/session1.test +++ b/test/session1.test @@ -291,11 +291,7 @@ do_execsql_test 3.3.5 { SELECT * FROM t4 } {-1 2 3 -1 5 6 {} 8 9 x 11 12} #------------------------------------------------------------------------- # This next block of tests verifies that values returned by the conflict -# handler are intepreted correctly. The following cases are tested: -# -# Test case Operation Conflict Return Code -# UPDATE DATA OMIT -# UPDATE DATA REPLACE +# handler are intepreted correctly. # proc test_reset {} { @@ -407,6 +403,35 @@ foreach {tn conflict_return} { do_db2_test 5.$tn.3 "SELECT * FROM d1" $res($conflict_return) } +#------------------------------------------------------------------------- +# Test that two tables can be monitored by a single session object. +# +test_reset +set schema { + CREATE TABLE t1(a COLLATE nocase PRIMARY KEY, b); + CREATE TABLE t2(a, b PRIMARY KEY); +} +do_test 6.0 { + execsql $schema db + execsql $schema db2 + execsql { + INSERT INTO t1 VALUES('a', 'b'); + INSERT INTO t2 VALUES('a', 'b'); + } db2 +} {} + +set conflict_return "" +do_conflict_test 6.1 -tables {t1 t2} -sql { + INSERT INTO t1 VALUES('1', '2'); + INSERT INTO t1 VALUES('A', 'B'); + INSERT INTO t2 VALUES('A', 'B'); +} -conflicts { + {INSERT t1 CONFLICT {t A t B} {t a t b}} +} + +do_db2_test 6.2 "SELECT * FROM t1" {a b 1 2} +do_db2_test 6.3 "SELECT * FROM t2" {a b A B} + catch { db2 close } finish_test From 6566ebe1b630c04d66dc92e709674786f81ba191 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 16 Mar 2011 09:49:14 +0000 Subject: [PATCH 0009/1484] Remove the sqlite3_transaction_hook() API. FossilOrigin-Name: b0015a1cfe63c924ee5f250aa08460522882009b --- manifest | 28 +++++----- manifest.uuid | 2 +- src/main.c | 42 -------------- src/sqlite.h.in | 11 ---- src/sqliteInt.h | 3 - src/tclsqlite.c | 37 +------------ src/vdbe.c | 13 ----- src/vdbeapi.c | 10 +--- src/vdbeaux.c | 9 --- test/hook.test | 131 -------------------------------------------- test/tclsqlite.test | 2 +- 11 files changed, 20 insertions(+), 268 deletions(-) diff --git a/manifest b/manifest index 7e8b8c7747..4061dea410 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\ssome\sbugs\sand\sother\scode\sissues\sin\sthe\ssession\smodule. -D 2011-03-15T16:37:28 +C Remove\sthe\ssqlite3_transaction_hook()\sAPI. +D 2011-03-16T09:49:15 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -145,7 +145,7 @@ F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f F src/lempar.c 7f026423f4d71d989e719a743f98a1cbd4e6d99e F src/loadext.c 8af9fcc75708d60b88636ccba38b4a7b3c155c3e -F src/main.c 1a5cafdc1bee11f4322c837487bf6fa8e54b2f50 +F src/main.c 9ab948225b8c362cdd6902c447abbf218607e0f3 F src/malloc.c 92d59a007d7a42857d4e9454aa25b6b703286be1 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 00bd8265c81abb665c48fea1e0c234eb3b922206 @@ -180,13 +180,13 @@ F src/resolve.c 1c0f32b64f8e3f555fe1f732f9d6f501a7f05706 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 F src/select.c d24406c45dd2442eb2eeaac413439066b149c944 F src/shell.c 649c51979812f77f97507024a4cea480c6862b8b -F src/sqlite.h.in 992688609e9a0274b56c156d4800be96364b3590 +F src/sqlite.h.in 8da2897e3c9b251b29aa48d11bfb1f30f1de0733 F src/sqlite3ext.h c90bd5507099f62043832d73f6425d8d5c5da754 -F src/sqliteInt.h 85e635183013e806069320ffa6080a77183f9225 +F src/sqliteInt.h db209477de559911d7f14c1d208cbf2bc46e9224 F src/sqliteLimit.h a17dcd3fb775d63b64a43a55c54cb282f9726f44 F src/status.c 4997380fbb915426fef9e500b4872e79c99267fc F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e -F src/tclsqlite.c b124fb73120d1bc4b78ae8153bce71dbd2d93db5 +F src/tclsqlite.c 0aa7e768b3bd72bf4c4b0312c9a84d6cdedb7638 F src/test1.c 9020310c7617234b33fd1c3064f89524db25f290 F src/test2.c 80d323d11e909cf0eb1b6fbb4ac22276483bcf31 F src/test3.c 056093cfef69ff4227a6bdb9108564dc7f45e4bc @@ -232,11 +232,11 @@ F src/update.c 1b9a82ede7df15e76ed86c6a3cbe4ce0f21eaa9b F src/utf.c 1baeeac91707a4df97ccc6141ec0f808278af685 F src/util.c ab1c92426494f499f42b9e307537b03e923d75c1 F src/vacuum.c 924bd1bcee2dfb05376f79845bd3b4cec7b54b2f -F src/vdbe.c 2c523bc17f915329f3db3745fc76ed9bfc5c26bb +F src/vdbe.c 117644088f89c40b01c917d06f7b2ed706ca125f F src/vdbe.h 4de0efb4b0fdaaa900cf419b35c458933ef1c6d2 F src/vdbeInt.h 9dd04435bd5a68e30cd07e7a91c17b062bf1c23d -F src/vdbeapi.c 750dcdea999762adbac6eddde5bd790803911edf -F src/vdbeaux.c 9ba08ed7de89e923ba6b95a5a75a460e6507a81f +F src/vdbeapi.c 256029b0a2ed2373ebbcce7a497b3a702a52689b +F src/vdbeaux.c f789da7d55231d779c26deaf5a1e6ccb3e550c09 F src/vdbeblob.c 18955f0ee6b133cd08e1592010cb9a6b11e9984c F src/vdbemem.c 0fa2ed786cd207d5b988afef3562a8e663a75b50 F src/vdbetrace.c 3ba13bc32bdf16d2bdea523245fd16736bed67b5 @@ -474,7 +474,7 @@ F test/fuzz2.test 207d0f9d06db3eaf47a6b7bfc835b8e2fc397167 F test/fuzz3.test aec64345184d1662bd30e6a17851ff659d596dc5 F test/fuzz_common.tcl a87dfbb88c2a6b08a38e9a070dabd129e617b45b F test/fuzz_malloc.test dd7001ac86d09c154a7dff064f4739c60e2b312c -F test/hook.test a90748e44c7ca53da46f857616fc7ce18bf7be13 +F test/hook.test 85059721ef537317af679aca5435f94ab316d074 F test/icu.test 70df4faca133254c042d02ae342c0a141f2663f4 F test/in.test 19b642bb134308980a92249750ea4ce3f6c75c2d F test/in2.test 5d4c61d17493c832f7d2d32bef785119e87bde75 @@ -671,7 +671,7 @@ F test/superlock.test 5d7a4954b0059c903f82c7b67867bc5451a7c082 F test/sync.test ded6b39d8d8ca3c0c5518516c6371b3316d3e3a3 F test/table.test 04ba066432430657712d167ebf28080fe878d305 F test/tableapi.test 7262a8cbaa9965d429f1cbd2747edc185fa56516 -F test/tclsqlite.test 550f2268281d186b767b3ee14dd0be5f9e3ff25d +F test/tclsqlite.test 1ce9b6340d6d412420634e129a2e3722c651056a F test/tempdb.test 19d0f66e2e3eeffd68661a11c83ba5e6ace9128c F test/temptable.test f42121a0d29a62f00f93274464164177ab1cc24a F test/temptrigger.test b0273db072ce5f37cf19140ceb1f0d524bbe9f05 @@ -913,7 +913,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P cbbb274e500237dbf7155a51d4f9c17583d704ea -R c267abdc5c97771dbd3d62995c13d672 +P f2930840e4af3d7d9cb199d316502932fcbbb867 +R fadac1472cdeb40a0e5c985ec43cbe17 U dan -Z 5fed91a90fa4060d0a5ac8127dba8c51 +Z 22d8aae45d188380f4801c8d2b2db4e1 diff --git a/manifest.uuid b/manifest.uuid index 79ca836129..2664939330 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f2930840e4af3d7d9cb199d316502932fcbbb867 \ No newline at end of file +b0015a1cfe63c924ee5f250aa08460522882009b \ No newline at end of file diff --git a/src/main.c b/src/main.c index a8ac80039e..3976f7ebc3 100644 --- a/src/main.c +++ b/src/main.c @@ -764,26 +764,6 @@ int sqlite3_close(sqlite3 *db){ return SQLITE_OK; } - -/* -** Invoke the transaction-hook. -*/ -void sqlite3TransactionHook(sqlite3 *db, int op, int iLevel){ - assert( op==SQLITE_BEGIN || op==SQLITE_COMMIT || op==SQLITE_ROLLBACK ); - assert( op==SQLITE_BEGIN || iLeveliOpenTrans || iLevel==0 ); - assert( op==SQLITE_BEGIN || iLeveliOpenTrans || db->iOpenTrans==0 ); - assert( op!=SQLITE_BEGIN || iLevel==db->iOpenTrans || iLevel==0 ); - assert( op!=SQLITE_BEGIN || iLevel==db->iOpenTrans || db->iOpenTrans==1 ); - - if( op==SQLITE_BEGIN && iLevel!=db->iOpenTrans ) return; - if( op!=SQLITE_BEGIN && iLevel>=db->iOpenTrans ) return; - - if( db->xTransCallback ){ - db->xTransCallback(db->pTransArg, op, iLevel); - } - db->iOpenTrans = iLevel + (op==SQLITE_BEGIN); -} - /* ** Rollback all database files. */ @@ -816,10 +796,6 @@ void sqlite3RollbackAll(sqlite3 *db){ if( db->xRollbackCallback && (inTrans || !db->autoCommit) ){ db->xRollbackCallback(db->pRollbackArg); } - - /* If a transaction-hook is configured, invoke it now to report on - ** the rollback operation. */ - sqlite3TransactionHook(db, SQLITE_ROLLBACK, 0); } /* @@ -1314,24 +1290,6 @@ void *sqlite3_preupdate_hook( return pRet; } -/* -** Register a callback to be invoked each time a transaction or savepoint -** is opened, committed or rolled back. -*/ -void *sqlite3_transaction_hook( - sqlite3 *db, /* Database handle */ - void(*xCallback)(void *, int, int), /* Callback function */ - void *pArg /* First callback argument */ -){ - void *pRet; - sqlite3_mutex_enter(db->mutex); - pRet = db->pTransArg; - db->xTransCallback = xCallback; - db->pTransArg = pArg; - sqlite3_mutex_leave(db->mutex); - return pRet; -} - #ifndef SQLITE_OMIT_WAL /* ** The sqlite3_wal_hook() callback registered by sqlite3_wal_autocheckpoint(). diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 137be57b89..d3c9ac5f24 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -6369,17 +6369,6 @@ SQLITE_EXPERIMENTAL int sqlite3_preupdate_old(sqlite3 *, int, sqlite3_value **); SQLITE_EXPERIMENTAL int sqlite3_preupdate_modified(sqlite3 *, int, int *); SQLITE_EXPERIMENTAL int sqlite3_preupdate_count(sqlite3 *); -/* -** CAPI3REF: The transaction hook. -*/ -SQLITE_EXPERIMENTAL -void *sqlite3_transaction_hook(sqlite3 *, void(*)(void *, int, int), void *); - -#define SQLITE_BEGIN 1 -#define SQLITE_COMMIT 2 -#define SQLITE_ROLLBACK 3 - - /* ** Undo the hack that converts floating point types to integer for ** builds on processors without floating point support. diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 1414fb68b5..2582d7c990 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -833,9 +833,6 @@ struct sqlite3 { void*,sqlite3*,int,char const*,char const*,sqlite3_int64,sqlite3_int64 ); PreUpdate *pPreUpdate; /* Context for active pre-update callback */ - void *pTransArg; /* First argument to xTransCallback */ - void (*xTransCallback)(void*,int,int); - int iOpenTrans; /* Open transaction (xTransCallback) plus 1 */ #ifndef SQLITE_OMIT_WAL int (*xWalCallback)(void *, sqlite3 *, const char *, int); void *pWalArg; diff --git a/src/tclsqlite.c b/src/tclsqlite.c index 1743b40cf6..b5ac5faf88 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -124,7 +124,6 @@ struct SqliteDb { Tcl_Obj *pUpdateHook; /* Update hook script (if any) */ Tcl_Obj *pPreUpdateHook; /* Pre-update hook script (if any) */ Tcl_Obj *pRollbackHook; /* Rollback hook script (if any) */ - Tcl_Obj *pTransHook; /* Transaction hook script (if any) */ Tcl_Obj *pWalHook; /* WAL hook script (if any) */ Tcl_Obj *pUnlockNotify; /* Unlock notify script (if any) */ SqlCollate *pCollate; /* List of SQL collation functions */ @@ -598,30 +597,6 @@ static void DbRollbackHandler(void *clientData){ } } -/* -** sqlite3_transaction_hook() callback. -*/ -static void DbTransHandler(void *clientData, int op, int iLevel){ - static const char *azStr[] = { "BEGIN", "COMMIT", "ROLLBACK" }; - SqliteDb *pDb = (SqliteDb*)clientData; - Tcl_Interp *interp = pDb->interp; - Tcl_Obj *pScript; - - assert(pDb->pTransHook); - assert( SQLITE_BEGIN==1 ); - assert( SQLITE_COMMIT==2 ); - assert( SQLITE_ROLLBACK==3 ); - - pScript = Tcl_DuplicateObj(pDb->pTransHook); - Tcl_IncrRefCount(pScript); - Tcl_ListObjAppendElement(interp, pScript, Tcl_NewStringObj(azStr[op-1], -1)); - Tcl_ListObjAppendElement(interp, pScript, Tcl_NewIntObj(iLevel)); - if( TCL_OK!=Tcl_EvalObjEx(interp, pScript, 0) ){ - Tcl_BackgroundError(interp); - } - Tcl_DecrRefCount(pScript); -} - /* ** This procedure handles wal_hook callbacks. */ @@ -1653,7 +1628,6 @@ static void DbHookCmd( sqlite3_update_hook(db, (pDb->pUpdateHook?DbUpdateHandler:0), pDb); sqlite3_rollback_hook(db, (pDb->pRollbackHook?DbRollbackHandler:0), pDb); sqlite3_wal_hook(db, (pDb->pWalHook?DbWalHandler:0), pDb); - sqlite3_transaction_hook(db, (pDb->pTransHook?DbTransHandler:0), pDb); } /* @@ -1685,8 +1659,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ "profile", "progress", "rekey", "restore", "rollback_hook", "status", "timeout", "total_changes", "trace", - "transaction", "transaction_hook", - "unlock_notify", "update_hook", + "transaction", "unlock_notify", "update_hook", "version", "wal_hook", 0 }; enum DB_enum { @@ -1701,8 +1674,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ DB_PROFILE, DB_PROGRESS, DB_REKEY, DB_RESTORE, DB_ROLLBACK_HOOK, DB_STATUS, DB_TIMEOUT, DB_TOTAL_CHANGES, DB_TRACE, - DB_TRANSACTION, DB_TRANSACTION_HOOK, - DB_UNLOCK_NOTIFY, DB_UPDATE_HOOK, + DB_TRANSACTION, DB_UNLOCK_NOTIFY, DB_UPDATE_HOOK, DB_VERSION, DB_WAL_HOOK }; /* don't leave trailing commas on DB_enum, it confuses the AIX xlc compiler */ @@ -2942,12 +2914,10 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ ** $db wal_hook ?script? ** $db update_hook ?script? ** $db rollback_hook ?script? - ** $db transaction_hook ?script? */ case DB_WAL_HOOK: case DB_UPDATE_HOOK: - case DB_ROLLBACK_HOOK: - case DB_TRANSACTION_HOOK: { + case DB_ROLLBACK_HOOK: { sqlite3 *db = pDb->db; /* set ppHook to point at pUpdateHook or pRollbackHook, depending on @@ -2957,7 +2927,6 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ if( choice==DB_WAL_HOOK ) ppHook = &pDb->pWalHook; if( choice==DB_UPDATE_HOOK ) ppHook = &pDb->pUpdateHook; if( choice==DB_ROLLBACK_HOOK ) ppHook = &pDb->pRollbackHook; - if( choice==DB_TRANSACTION_HOOK ) ppHook = &pDb->pTransHook; if( objc>3 ){ Tcl_WrongNumArgs(interp, 2, objv, "?SCRIPT?"); return TCL_ERROR; diff --git a/src/vdbe.c b/src/vdbe.c index 252c53cb63..041e93025b 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2569,8 +2569,6 @@ case OP_Savepoint: { db->nSavepoint++; } - sqlite3TransactionHook(db, SQLITE_BEGIN, db->nSavepoint); - /* Link the new savepoint into the database handle's list. */ pNew->pNext = db->pSavepoint; db->pSavepoint = pNew; @@ -2637,13 +2635,6 @@ case OP_Savepoint: { sqlite3ResetInternalSchema(db, 0); db->flags = (db->flags | SQLITE_InternChanges); } - - assert( SAVEPOINT_ROLLBACK+1==SQLITE_ROLLBACK ); - assert( SAVEPOINT_RELEASE+1==SQLITE_COMMIT ); - sqlite3TransactionHook(db, p1+1, iSavepoint+1); - if( p1==SAVEPOINT_ROLLBACK ){ - sqlite3TransactionHook(db, SQLITE_BEGIN, iSavepoint+1); - } } /* Regardless of whether this is a RELEASE or ROLLBACK, destroy all @@ -2719,9 +2710,6 @@ case OP_AutoCommit: { }else if( (rc = sqlite3VdbeCheckFk(p, 1))!=SQLITE_OK ){ goto vdbe_return; }else{ - if( desiredAutoCommit==0 ){ - sqlite3TransactionHook(db, SQLITE_BEGIN, 0); - } db->autoCommit = (u8)desiredAutoCommit; if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){ p->pc = pc; @@ -2808,7 +2796,6 @@ case OP_Transaction: { p->iStatement = db->nSavepoint + db->nStatement; } rc = sqlite3BtreeBeginStmt(pBt, p->iStatement); - sqlite3TransactionHook(db, SQLITE_BEGIN, p->iStatement); /* Store the current value of the database handles deferred constraint ** counter. If the statement transaction needs to be rolled back, diff --git a/src/vdbeapi.c b/src/vdbeapi.c index d3bd6478cf..0d5fd94021 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -401,15 +401,7 @@ static int sqlite3Step(Vdbe *p){ #endif db->activeVdbeCnt++; - if( p->readOnly==0 ){ - /* If this statement will open an implicit transaction, invoke the - ** transaction-hook here. */ - if( db->autoCommit && db->writeVdbeCnt==0 ){ - assert( db->nSavepoint==0 ); - sqlite3TransactionHook(db, SQLITE_BEGIN, 0); - } - db->writeVdbeCnt++; - } + if( p->readOnly==0 ) db->writeVdbeCnt++; p->pc = 0; } #ifndef SQLITE_OMIT_EXPLAIN diff --git a/src/vdbeaux.c b/src/vdbeaux.c index cb6aefac08..1c870c2404 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -1845,12 +1845,6 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){ } #endif - /* If a transaction-hook is configured, invoke it now to report on the - ** successful commit operation. */ - if( rc==SQLITE_OK ){ - sqlite3TransactionHook(db, SQLITE_COMMIT, 0); - } - return rc; } @@ -1952,9 +1946,6 @@ int sqlite3VdbeCloseStatement(Vdbe *p, int eOp){ } } db->nStatement--; - assert( SAVEPOINT_ROLLBACK+1==SQLITE_ROLLBACK ); - assert( SAVEPOINT_RELEASE+1==SQLITE_COMMIT ); - sqlite3TransactionHook(db, eOp+1, p->iStatement); p->iStatement = 0; /* If the statement transaction is being rolled back, also restore the diff --git a/test/hook.test b/test/hook.test index b2e0988828..0ba4b19e40 100644 --- a/test/hook.test +++ b/test/hook.test @@ -631,136 +631,5 @@ do_preupdate_test 7.5.2.2 { UPDATE main t8 2 2 three four xxx } -#---------------------------------------------------------------------------- -# The following tests - hook-8.* - test the transaction hook. -# -db close -forcedelete test.db -sqlite3 db test.db - -proc transaction_hook {op iLevel} { - lappend ::transaction_hook $op $iLevel -} -db transaction_hook transaction_hook - -proc do_transaction_test {tn sql x} { - set X [list] - foreach elem $x {lappend X $elem} - - uplevel do_test $tn [list " - set ::transaction_hook \[list\] - catchsql { $sql } - set ::transaction_hook - "] [list $X] -} - -do_transaction_test 8.1.1 "CREATE TABLE t1(x)" {BEGIN 0 COMMIT 0} -do_transaction_test 8.1.2 "BEGIN" {BEGIN 0} -do_transaction_test 8.1.3 "COMMIT" {COMMIT 0} -do_transaction_test 8.1.4 "BEGIN ; ROLLBACK" {BEGIN 0 ROLLBACK 0} - -do_execsql_test 8.2.0 { - CREATE TABLE t2(a PRIMARY KEY, b); - INSERT INTO t2 VALUES(1, 'one'); - INSERT INTO t2 VALUES(2, 'two'); - INSERT INTO t2 VALUES(3, 'three'); -} -do_transaction_test 8.2.1 { - INSERT INTO t2 VALUES(2, 'xxx') -} {BEGIN 0 ROLLBACK 0} - -do_transaction_test 8.2.2 { - BEGIN; INSERT INTO t2 SELECT a-2, b FROM t2; -} {BEGIN 0 BEGIN 1 ROLLBACK 1} - -do_transaction_test 8.2.3 { - INSERT OR ROLLBACK INTO t2 SELECT a-2, b FROM t2; -} {ROLLBACK 0} - -do_transaction_test 8.2.4 { - BEGIN; INSERT INTO t2 SELECT a+3, b FROM t2; -} {BEGIN 0 BEGIN 1 COMMIT 1} - -do_transaction_test 8.2.5 "COMMIT" {COMMIT 0} - -do_transaction_test 8.3.1 {SELECT * FROM t2} {} - -do_transaction_test 8.4.1 { - SAVEPOINT top; - RELEASE top; -} {BEGIN 0 COMMIT 0} - -do_transaction_test 8.4.2 { - SAVEPOINT top; - ROLLBACK TO top; - RELEASE top; -} {BEGIN 0 ROLLBACK 0 BEGIN 0 COMMIT 0} - -do_transaction_test 8.4.3 { - SAVEPOINT zero; - SAVEPOINT one; - SAVEPOINT two; - SAVEPOINT three; - ROLLBACK TO zero; - SAVEPOINT one; - SAVEPOINT two; - SAVEPOINT three; - ROLLBACK TO one; - SAVEPOINT two; - RELEASE zero; - - SAVEPOINT zero; - SAVEPOINT one; - SAVEPOINT two; - RELEASE two; - SAVEPOINT two; - SAVEPOINT three; - RELEASE one; - ROLLBACK TO zero; - RELEASE zero; -} { - BEGIN 0 BEGIN 1 BEGIN 2 BEGIN 3 ROLLBACK 0 BEGIN 0 - BEGIN 1 BEGIN 2 BEGIN 3 ROLLBACK 1 BEGIN 1 BEGIN 2 - COMMIT 0 - - BEGIN 0 BEGIN 1 BEGIN 2 COMMIT 2 BEGIN 2 BEGIN 3 COMMIT 1 - ROLLBACK 0 BEGIN 0 COMMIT 0 -} - -do_transaction_test 8.4.4 { - BEGIN; - SAVEPOINT zero; - SAVEPOINT one; - SAVEPOINT two; - SAVEPOINT three; - ROLLBACK TO zero; - SAVEPOINT one; - SAVEPOINT two; - SAVEPOINT three; - ROLLBACK TO one; - SAVEPOINT two; - RELEASE zero; - - SAVEPOINT zero; - SAVEPOINT one; - SAVEPOINT two; - RELEASE two; - SAVEPOINT two; - SAVEPOINT three; - RELEASE one; - ROLLBACK TO zero; - RELEASE zero; - COMMIT; -} { - BEGIN 0 - BEGIN 1 BEGIN 2 BEGIN 3 BEGIN 4 ROLLBACK 1 BEGIN 1 - BEGIN 2 BEGIN 3 BEGIN 4 ROLLBACK 2 BEGIN 2 BEGIN 3 - COMMIT 1 - - BEGIN 1 BEGIN 2 BEGIN 3 COMMIT 3 BEGIN 3 BEGIN 4 COMMIT 2 - ROLLBACK 1 BEGIN 1 COMMIT 1 - COMMIT 0 -} - finish_test diff --git a/test/tclsqlite.test b/test/tclsqlite.test index efc3e53ab6..c9d562beb5 100644 --- a/test/tclsqlite.test +++ b/test/tclsqlite.test @@ -35,7 +35,7 @@ do_test tcl-1.1 { do_test tcl-1.2 { set v [catch {db bogus} msg] lappend v $msg -} {1 {bad option "bogus": must be authorizer, backup, busy, cache, changes, close, collate, collation_needed, commit_hook, complete, copy, enable_load_extension, errorcode, eval, exists, function, incrblob, interrupt, last_insert_rowid, nullvalue, onecolumn, preupdate, profile, progress, rekey, restore, rollback_hook, status, timeout, total_changes, trace, transaction, transaction_hook, unlock_notify, update_hook, version, or wal_hook}} +} {1 {bad option "bogus": must be authorizer, backup, busy, cache, changes, close, collate, collation_needed, commit_hook, complete, copy, enable_load_extension, errorcode, eval, exists, function, incrblob, interrupt, last_insert_rowid, nullvalue, onecolumn, preupdate, profile, progress, rekey, restore, rollback_hook, status, timeout, total_changes, trace, transaction, unlock_notify, update_hook, version, or wal_hook}} do_test tcl-1.2.1 { set v [catch {db cache bogus} msg] lappend v $msg From 37db03bf73f9692fdd86388d677668c09be128d7 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 16 Mar 2011 19:59:18 +0000 Subject: [PATCH 0010/1484] Add the sqlite3_preupdate_new() API, for retrieving the new.* values from within a pre-update callback. FossilOrigin-Name: 526545c49f64d9063d1b888cfc14ece62fa3c13c --- ext/session/sqlite3session.h | 58 +++++++++++++++++++++++------ manifest | 28 +++++++------- manifest.uuid | 2 +- src/sqlite.h.in | 2 +- src/tclsqlite.c | 27 ++++++-------- src/update.c | 6 +++ src/vdbe.c | 6 +-- src/vdbeInt.h | 6 ++- src/vdbeapi.c | 71 +++++++++++++++++++++++++++++++++--- src/vdbeaux.c | 21 ++++++++++- test/hook.test | 40 +++++++++++--------- 11 files changed, 196 insertions(+), 71 deletions(-) diff --git a/ext/session/sqlite3session.h b/ext/session/sqlite3session.h index c4053e3dbe..573b2ff3fc 100644 --- a/ext/session/sqlite3session.h +++ b/ext/session/sqlite3session.h @@ -15,8 +15,32 @@ typedef struct sqlite3_session sqlite3_session; typedef struct sqlite3_changeset_iter sqlite3_changeset_iter; /* -** Create a session object. This session object will record changes to -** database zDb attached to connection db. +** Create a new session object attached to database handle db. If successful, +** a pointer to the new object is written to *ppSession and SQLITE_OK is +** returned. If an error occurs, *ppSession is set to NULL and an SQLite +** error code (e.g. [SQLITE_NOMEM]) is returned. +** +** It is possible to create multiple session objects attached to a single +** database handle. +** +** Session objects created using this function should be deleted using the +** [sqlite3session_delete()] function before the database handle that they +** are attached to is itself closed. If the database handle is closed before +** the session object is deleted, then the results of calling any session +** module function, including [sqlite3session_delete()] on the session object +** are undefined. +** +** Because the session module uses the [sqlite3_preupdate_hook()] API, it +** is not possible for an application to register a pre-update hook on a +** database handle that has one or more session objects attached. Nor is +** it possible to create a session object attached to a database handle for +** which a pre-update hook is already defined. The results of attempting +** either of these things are undefined. +** +** The session object will be used to create changesets for tables in +** database zDb, where zDb is either "main", or "temp", or the name of an +** attached database. It is not an error if database zDb does not exist +** to the database when the session object is created. */ int sqlite3session_create( sqlite3 *db, /* Database handle */ @@ -24,6 +48,18 @@ int sqlite3session_create( sqlite3_session **ppSession /* OUT: New session object */ ); +/* +** Delete a session object previously allocated using +** [sqlite3session_create()]. Once a session object has been deleted, the +** results of attempting to use pSession with any other session module +** function are undefined. +** +** Session objects must be deleted before the database handle to which they +** are attached is closed. Refer to the documentation for +** [sqlite3session_create()] for details. +*/ +void sqlite3session_delete(sqlite3_session *pSession); + /* ** Enable or disable the recording of changes by a session object. When ** enabled, a session object records changes made to the database. When @@ -52,11 +88,16 @@ int sqlite3session_attach( ); /* -** Obtain a changeset object containing all changes recorded by the -** session object passed as the first argument. +** Obtain a changeset containing changes to the tables attached to the +** session object passed as the first argument. If successful, +** set *ppChangeset to point to a buffer containing the changeset +** and *pnChangeset to the size of the changeset in bytes before returning +** SQLITE_OK. If an error occurs, set both *ppChangeset and *pnChangeset to +** zero and return an SQLite error code. ** -** It is the responsibility of the caller to eventually free the buffer -** using sqlite3_free(). +** Following a successful call to this function, it is the responsibility of +** the caller to eventually free the buffer that *ppChangeset points to using +** [sqlite3_free()]. */ int sqlite3session_changeset( sqlite3_session *pSession, /* Session object */ @@ -64,11 +105,6 @@ int sqlite3session_changeset( void **ppChangeset /* OUT: Buffer containing changeset */ ); -/* -** Delete a session object previously allocated using sqlite3session_create(). -*/ -void sqlite3session_delete(sqlite3_session *pSession); - /* ** Create an iterator used to iterate through the contents of a changeset. */ diff --git a/manifest b/manifest index 4061dea410..796df369be 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sthe\ssqlite3_transaction_hook()\sAPI. -D 2011-03-16T09:49:15 +C Add\sthe\ssqlite3_preupdate_new()\sAPI,\sfor\sretrieving\sthe\snew.*\svalues\sfrom\swithin\sa\spre-update\scallback. +D 2011-03-16T19:59:19 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -99,7 +99,7 @@ F ext/rtree/sqlite3rtree.h 1af0899c63a688e272d69d8e746f24e76f10a3f0 F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 F ext/session/sqlite3session.c 9b8d123418c024f6851163375fca99042757772f -F ext/session/sqlite3session.h 01aac9a1185b7db6716217f3aa3f7a835ab864b9 +F ext/session/sqlite3session.h 63045871564085669b5cb1fb92e6efc2e1b1120a F ext/session/test_session.c 2559ef68e421c7fb83e2c19ef08a17343b70d535 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 @@ -180,13 +180,13 @@ F src/resolve.c 1c0f32b64f8e3f555fe1f732f9d6f501a7f05706 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 F src/select.c d24406c45dd2442eb2eeaac413439066b149c944 F src/shell.c 649c51979812f77f97507024a4cea480c6862b8b -F src/sqlite.h.in 8da2897e3c9b251b29aa48d11bfb1f30f1de0733 +F src/sqlite.h.in 992c54d9bd451a041fb0b74fb5cd3b14db98e544 F src/sqlite3ext.h c90bd5507099f62043832d73f6425d8d5c5da754 F src/sqliteInt.h db209477de559911d7f14c1d208cbf2bc46e9224 F src/sqliteLimit.h a17dcd3fb775d63b64a43a55c54cb282f9726f44 F src/status.c 4997380fbb915426fef9e500b4872e79c99267fc F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e -F src/tclsqlite.c 0aa7e768b3bd72bf4c4b0312c9a84d6cdedb7638 +F src/tclsqlite.c fc0321c62a3c3929b9b0659b94b7d37bac84e769 F src/test1.c 9020310c7617234b33fd1c3064f89524db25f290 F src/test2.c 80d323d11e909cf0eb1b6fbb4ac22276483bcf31 F src/test3.c 056093cfef69ff4227a6bdb9108564dc7f45e4bc @@ -228,15 +228,15 @@ F src/test_vfs.c 2ed8853c1e51ac6f9ea091f7ce4e0d618bba8b86 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/tokenize.c 604607d6813e9551cf5189d899e0a25c12681080 F src/trigger.c b8bedb9c0084ceb51a40f54fcca2ce048c8de852 -F src/update.c 1b9a82ede7df15e76ed86c6a3cbe4ce0f21eaa9b +F src/update.c 18a862e3e08377a5afb26d6f16182a8f700a1ca7 F src/utf.c 1baeeac91707a4df97ccc6141ec0f808278af685 F src/util.c ab1c92426494f499f42b9e307537b03e923d75c1 F src/vacuum.c 924bd1bcee2dfb05376f79845bd3b4cec7b54b2f -F src/vdbe.c 117644088f89c40b01c917d06f7b2ed706ca125f +F src/vdbe.c fbf11bd681fd2313aaf59fb2fd7f02cd8324a88a F src/vdbe.h 4de0efb4b0fdaaa900cf419b35c458933ef1c6d2 -F src/vdbeInt.h 9dd04435bd5a68e30cd07e7a91c17b062bf1c23d -F src/vdbeapi.c 256029b0a2ed2373ebbcce7a497b3a702a52689b -F src/vdbeaux.c f789da7d55231d779c26deaf5a1e6ccb3e550c09 +F src/vdbeInt.h 20d13da932eed0667a2e2383a9cb0f80099a5fd3 +F src/vdbeapi.c 3066456f64fb10c9c5151c684b5f5e8d67a5f4f2 +F src/vdbeaux.c 896844f9bf663202b3afa8c139e2caddcf855765 F src/vdbeblob.c 18955f0ee6b133cd08e1592010cb9a6b11e9984c F src/vdbemem.c 0fa2ed786cd207d5b988afef3562a8e663a75b50 F src/vdbetrace.c 3ba13bc32bdf16d2bdea523245fd16736bed67b5 @@ -474,7 +474,7 @@ F test/fuzz2.test 207d0f9d06db3eaf47a6b7bfc835b8e2fc397167 F test/fuzz3.test aec64345184d1662bd30e6a17851ff659d596dc5 F test/fuzz_common.tcl a87dfbb88c2a6b08a38e9a070dabd129e617b45b F test/fuzz_malloc.test dd7001ac86d09c154a7dff064f4739c60e2b312c -F test/hook.test 85059721ef537317af679aca5435f94ab316d074 +F test/hook.test d0a277022888caf75ae1d4ec79917668f2f0f2e6 F test/icu.test 70df4faca133254c042d02ae342c0a141f2663f4 F test/in.test 19b642bb134308980a92249750ea4ce3f6c75c2d F test/in2.test 5d4c61d17493c832f7d2d32bef785119e87bde75 @@ -913,7 +913,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P f2930840e4af3d7d9cb199d316502932fcbbb867 -R fadac1472cdeb40a0e5c985ec43cbe17 +P b0015a1cfe63c924ee5f250aa08460522882009b +R 4b62a15aa3feb03b0e54e624839e53a1 U dan -Z 22d8aae45d188380f4801c8d2b2db4e1 +Z 0b4af75dcf5347bcbba47251e978ee95 diff --git a/manifest.uuid b/manifest.uuid index 2664939330..69c5255486 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b0015a1cfe63c924ee5f250aa08460522882009b \ No newline at end of file +526545c49f64d9063d1b888cfc14ece62fa3c13c \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index d3c9ac5f24..0f920bd6dd 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -6366,8 +6366,8 @@ SQLITE_EXPERIMENTAL void *sqlite3_preupdate_hook( void* ); SQLITE_EXPERIMENTAL int sqlite3_preupdate_old(sqlite3 *, int, sqlite3_value **); -SQLITE_EXPERIMENTAL int sqlite3_preupdate_modified(sqlite3 *, int, int *); SQLITE_EXPERIMENTAL int sqlite3_preupdate_count(sqlite3 *); +SQLITE_EXPERIMENTAL int sqlite3_preupdate_new(sqlite3 *, int, sqlite3_value **); /* ** Undo the hack that converts floating point types to integer for diff --git a/src/tclsqlite.c b/src/tclsqlite.c index b5ac5faf88..b3f98126c0 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -2846,9 +2846,9 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ } case DB_PREUPDATE: { - static const char *azSub[] = {"count", "hook", "modified", "old", 0}; + static const char *azSub[] = {"count", "hook", "new", "old", 0}; enum DbPreupdateSubCmd { - PRE_COUNT, PRE_HOOK, PRE_MODIFIED, PRE_OLD + PRE_COUNT, PRE_HOOK, PRE_NEW, PRE_OLD }; int iSub; @@ -2875,9 +2875,10 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ break; } - case PRE_MODIFIED: + case PRE_NEW: case PRE_OLD: { int iIdx; + sqlite3_value *pValue; if( objc!=4 ){ Tcl_WrongNumArgs(interp, 3, objv, "INDEX"); return TCL_ERROR; @@ -2886,21 +2887,17 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ return TCL_ERROR; } - if( iSub==PRE_MODIFIED ){ - int iRes; - rc = sqlite3_preupdate_modified(pDb->db, iIdx, &iRes); - if( rc==SQLITE_OK ) Tcl_SetObjResult(interp, Tcl_NewIntObj(iRes)); - }else{ - sqlite3_value *pValue; - assert( iSub==PRE_OLD ); + if( iSub==PRE_OLD ){ rc = sqlite3_preupdate_old(pDb->db, iIdx, &pValue); - if( rc==SQLITE_OK ){ - Tcl_Obj *pObj = Tcl_NewStringObj(sqlite3_value_text(pValue), -1); - Tcl_SetObjResult(interp, pObj); - } + }else{ + assert( iSub==PRE_NEW ); + rc = sqlite3_preupdate_new(pDb->db, iIdx, &pValue); } - if( rc!=SQLITE_OK ){ + if( rc==SQLITE_OK ){ + Tcl_Obj *pObj = Tcl_NewStringObj(sqlite3_value_text(pValue), -1); + Tcl_SetObjResult(interp, pObj); + }else{ Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), 0); return TCL_ERROR; } diff --git a/src/update.c b/src/update.c index ea8f95ad56..4bf4a880b1 100644 --- a/src/update.c +++ b/src/update.c @@ -493,7 +493,13 @@ void sqlite3Update( /* If changing the rowid value, or if there are foreign key constraints ** to process, delete the old record. Otherwise, add a noop OP_Delete ** to invoke the pre-update hook. + ** + ** That (regNew==regnewRowid+1) is true is also important for the + ** pre-update hook. If hte caller invokes preupdate_new(), the returned + ** value is copied from memory cell (regNewRowid+1+iCol), where iCol + ** is the column index supplied by the user. */ + assert( regNew==regNewRowid+1 ); sqlite3VdbeAddOp3(v, OP_Delete, iCur, OPFLAG_ISUPDATE | ((hasFK || chngRowid) ? 0 : OPFLAG_ISNOOP), regNewRowid diff --git a/src/vdbe.c b/src/vdbe.c index 041e93025b..1ef59d0a39 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -3881,9 +3881,7 @@ case OP_InsertInt: { && pOp->p4.z && (!(pOp->p5 & OPFLAG_ISUPDATE) || pC->rowidIsValid==0) ){ - sqlite3VdbePreUpdateHook(p, pC, - pC->rowidIsValid ? op : SQLITE_INSERT, zDb, zTbl, iKey, iKey - ); + sqlite3VdbePreUpdateHook(p, pC, SQLITE_INSERT, zDb, zTbl, iKey, pOp->p2); } if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++; @@ -3985,7 +3983,7 @@ case OP_Delete: { sqlite3VdbePreUpdateHook(p, pC, (opflags & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_DELETE, zDb, zTbl, iKey, - (opflags & OPFLAG_ISUPDATE) ? aMem[pOp->p3].u.i : iKey + pOp->p3 ); } diff --git a/src/vdbeInt.h b/src/vdbeInt.h index 0b4178aacd..447e025e94 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -336,11 +336,15 @@ struct Vdbe { ** sqlite3_preupdate_*() API functions. */ struct PreUpdate { + Vdbe *v; VdbeCursor *pCsr; /* Cursor to read old values from */ int op; /* One of SQLITE_INSERT, UPDATE, DELETE */ u8 *aRecord; /* old.* database record */ KeyInfo keyinfo; UnpackedRecord *pUnpacked; /* Unpacked version of aRecord[] */ + UnpackedRecord *pNewUnpacked; /* Unpacked version of new.* record */ + int iNewReg; /* Register for new.* values */ + Mem *aNew; /* Array of new.* values */ }; /* @@ -400,7 +404,7 @@ void sqlite3VdbeFrameDelete(VdbeFrame*); int sqlite3VdbeFrameRestore(VdbeFrame *); void sqlite3VdbeMemStoreType(Mem *pMem); void sqlite3VdbePreUpdateHook( - Vdbe *, VdbeCursor *, int, const char*, const char*, i64, i64); + Vdbe *, VdbeCursor *, int, const char*, const char*, i64, int); #ifdef SQLITE_DEBUG void sqlite3VdbeMemPrepareToChange(Vdbe*,Mem*); diff --git a/src/vdbeapi.c b/src/vdbeapi.c index 0d5fd94021..66f8c0857f 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -1329,10 +1329,16 @@ int sqlite3_stmt_status(sqlite3_stmt *pStmt, int op, int resetFlag){ return v; } +/* +** This function is called from within a pre-update callback to retrieve +** a field of the row currently being updated or deleted. +*/ int sqlite3_preupdate_old(sqlite3 *db, int iIdx, sqlite3_value **ppValue){ PreUpdate *p = db->pPreUpdate; int rc = SQLITE_OK; + /* Test that this call is being made from within an SQLITE_DELETE or + ** SQLITE_UPDATE pre-update callback, and that iIdx is within range. */ if( !p || p->op==SQLITE_INSERT ){ rc = SQLITE_MISUSE_BKPT; goto preupdate_old_out; @@ -1342,6 +1348,7 @@ int sqlite3_preupdate_old(sqlite3 *db, int iIdx, sqlite3_value **ppValue){ goto preupdate_old_out; } + /* If the old.* record has not yet been loaded into memory, do so now. */ if( p->pUnpacked==0 ){ u32 nRecord; u8 *aRecord; @@ -1372,26 +1379,78 @@ int sqlite3_preupdate_old(sqlite3 *db, int iIdx, sqlite3_value **ppValue){ return sqlite3ApiExit(db, rc); } +/* +** This function is called from within a pre-update callback to retrieve +** the number of columns in the row being updated, deleted or inserted. +*/ int sqlite3_preupdate_count(sqlite3 *db){ PreUpdate *p = db->pPreUpdate; return (p ? p->pCsr->nField : 0); } -int sqlite3_preupdate_modified(sqlite3 *db, int iIdx, int *pbMod){ +/* +** This function is called from within a pre-update callback to retrieve +** a field of the row currently being updated or inserted. +*/ +int sqlite3_preupdate_new(sqlite3 *db, int iIdx, sqlite3_value **ppValue){ PreUpdate *p = db->pPreUpdate; int rc = SQLITE_OK; + Mem *pMem; - if( !p || p->op!=SQLITE_UPDATE ){ + if( !p || p->op==SQLITE_DELETE ){ rc = SQLITE_MISUSE_BKPT; - goto preupdate_mod_out; + goto preupdate_new_out; } if( iIdx>=p->pCsr->nField || iIdx<0 ){ rc = SQLITE_RANGE; - goto preupdate_mod_out; + goto preupdate_new_out; } - *pbMod = 1; - preupdate_mod_out: + if( p->op==SQLITE_INSERT ){ + /* For an INSERT, memory cell p->iNewReg contains the serialized record + ** that is being inserted. Deserialize it. */ + UnpackedRecord *pUnpack = p->pNewUnpacked; + if( !pUnpack ){ + Mem *pData = &p->v->aMem[p->iNewReg]; + rc = sqlite3VdbeMemExpandBlob(pData); + if( rc!=SQLITE_OK ) goto preupdate_new_out; + pUnpack = sqlite3VdbeRecordUnpack(&p->keyinfo, pData->n, pData->z, 0, 0); + if( !pUnpack ){ + rc = SQLITE_NOMEM; + goto preupdate_new_out; + } + p->pNewUnpacked = pUnpack; + } + if( iIdx>=pUnpack->nField ){ + pMem = (sqlite3_value *)columnNullValue(); + }else{ + pMem = &pUnpack->aMem[iIdx]; + sqlite3VdbeMemStoreType(pMem); + } + }else{ + /* For an UPDATE, memory cell (p->iNewReg+1+iIdx) contains the required + ** value. Make a copy of the cell contents and return a pointer to it. + ** It is not safe to return a pointer to the memory cell itself as the + ** caller may modify the value text encoding. + */ + assert( p->op==SQLITE_UPDATE ); + if( !p->aNew ){ + p->aNew = (Mem *)sqlite3DbMallocZero(db, sizeof(Mem) * p->pCsr->nField); + if( !p->aNew ){ + rc = SQLITE_NOMEM; + goto preupdate_new_out; + } + } + pMem = &p->aNew[iIdx]; + if( pMem->flags==0 ){ + rc = sqlite3VdbeMemCopy(pMem, &p->v->aMem[p->iNewReg+1+iIdx]); + if( rc!=SQLITE_OK ) goto preupdate_new_out; + sqlite3VdbeMemStoreType(pMem); + } + } + *ppValue = pMem; + + preupdate_new_out: sqlite3Error(db, rc, 0); return sqlite3ApiExit(db, rc); } diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 1c870c2404..9749251585 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -3176,15 +3176,24 @@ void sqlite3VdbePreUpdateHook( const char *zDb, /* Database name */ const char *zTbl, /* Table name */ i64 iKey1, /* Initial key value */ - i64 iKey2 /* Final key value */ + int iReg /* Register for new.* record */ ){ sqlite3 *db = v->db; + i64 iKey2; PreUpdate preupdate; memset(&preupdate, 0, sizeof(PreUpdate)); + if( op==SQLITE_UPDATE ){ + iKey2 = v->aMem[iReg].u.i; + }else{ + iKey2 = iKey1; + } + + preupdate.v = v; preupdate.pCsr = pCsr; preupdate.op = op; + preupdate.iNewReg = iReg; preupdate.keyinfo.db = db; preupdate.keyinfo.enc = ENC(db); preupdate.keyinfo.nField = pCsr->nField; @@ -3195,5 +3204,15 @@ void sqlite3VdbePreUpdateHook( if( preupdate.pUnpacked ){ sqlite3VdbeDeleteUnpackedRecord(preupdate.pUnpacked); } + if( preupdate.pNewUnpacked ){ + sqlite3VdbeDeleteUnpackedRecord(preupdate.pNewUnpacked); + } + if( preupdate.aNew ){ + int i; + for(i=0; inField; i++){ + sqlite3VdbeMemRelease(&preupdate.aNew[i]); + } + sqlite3_free(preupdate.aNew); + } } diff --git a/test/hook.test b/test/hook.test index 0ba4b19e40..001e8ddf4a 100644 --- a/test/hook.test +++ b/test/hook.test @@ -405,11 +405,17 @@ proc do_preupdate_test {tn sql x} { proc preupdate_hook {args} { set type [lindex $args 0] eval lappend ::preupdate $args - if {$type != "SQLITE_INSERT"} { + if {$type != "INSERT"} { for {set i 0} {$i < [db preupdate count]} {incr i} { lappend ::preupdate [db preupdate old $i] } } + if {$type != "DELETE"} { + for {set i 0} {$i < [db preupdate count]} {incr i} { + set rc [catch { db preupdate new $i } v] + lappend ::preupdate $v + } + } } db close @@ -433,28 +439,28 @@ do_execsql_test 7.0 { do_preupdate_test 7.1.1 { INSERT INTO t1 VALUES('x', 'y') -} {INSERT main t1 1 1} +} {INSERT main t1 1 1 x y} # 7.1.2.1 does not use the xfer optimization. 7.1.2.2 does. do_preupdate_test 7.1.2.1 { INSERT INTO t1 SELECT y, x FROM t2; -} {INSERT main t1 2 2 INSERT main t1 3 3} +} {INSERT main t1 2 2 b a INSERT main t1 3 3 d c} do_preupdate_test 7.1.2.2 { INSERT INTO t1 SELECT * FROM t2; -} {INSERT main t1 4 4 INSERT main t1 5 5} +} {INSERT main t1 4 4 a b INSERT main t1 5 5 c d} do_preupdate_test 7.1.3 { REPLACE INTO t1(rowid, a, b) VALUES(1, 1, 1); } { DELETE main t1 1 1 x y - INSERT main t1 1 1 + INSERT main t1 1 1 1 1 } do_preupdate_test 7.1.4 { REPLACE INTO t3 VALUES(4, NULL); } { DELETE main t3 1 1 4 16 - INSERT main t3 4 4 + INSERT main t3 4 4 4 {} } do_preupdate_test 7.1.5 { @@ -462,7 +468,7 @@ do_preupdate_test 7.1.5 { } { DELETE main t3 2 2 5 25 DELETE main t3 3 3 6 36 - INSERT main t3 2 2 + INSERT main t3 2 2 6 {} } do_execsql_test 7.2.0 { SELECT rowid FROM t1 } {1 2 3 4 5} @@ -497,29 +503,29 @@ do_execsql_test 7.3.0 { do_preupdate_test 7.3.1 { UPDATE t2 SET y = y||y; } { - UPDATE main t2 1 1 a b - UPDATE main t2 2 2 c d + UPDATE main t2 1 1 a b a bb + UPDATE main t2 2 2 c d c dd } do_preupdate_test 7.3.2 { UPDATE t2 SET rowid = rowid-1; } { - UPDATE main t2 1 0 a bb - UPDATE main t2 2 1 c dd + UPDATE main t2 1 0 a bb a bb + UPDATE main t2 2 1 c dd c dd } do_preupdate_test 7.3.3 { UPDATE OR REPLACE t2 SET rowid = 1 WHERE x = 'a' } { DELETE main t2 1 1 c dd - UPDATE main t2 0 1 a bb + UPDATE main t2 0 1 a bb a bb } do_preupdate_test 7.3.4.1 { UPDATE OR REPLACE t3 SET i = 5 WHERE i = 6 } { DELETE main t3 2 2 5 25 - UPDATE main t3 3 3 6 36 + UPDATE main t3 3 3 6 36 5 36 } do_execsql_test 7.3.4.2 { @@ -532,7 +538,7 @@ do_preupdate_test 7.3.5 { } { DELETE main t3 1 1 4 16 DELETE main t3 3 3 5 36 - UPDATE main t3 4 1 10 100 + UPDATE main t3 4 1 10 100 5 100 } do_execsql_test 7.4.1.0 { @@ -577,7 +583,7 @@ do_preupdate_test 7.4.2.1 { UPDATE t5 SET b = 4 WHERE a = 'c' } { DELETE main t5 1 1 a 1 - UPDATE main t5 3 3 c 3 + UPDATE main t5 3 3 c 3 c 4 } do_execsql_test 7.4.2.2 { @@ -606,7 +612,7 @@ do_preupdate_test 7.5.1.1 { do_preupdate_test 7.5.1.2 { UPDATE t7 SET b = 'five' } { - UPDATE main t7 2 2 three four {} + UPDATE main t7 2 2 three four {} three five {} } do_execsql_test 7.5.2.0 { @@ -628,7 +634,7 @@ do_preupdate_test 7.5.2.1 { do_preupdate_test 7.5.2.2 { UPDATE t8 SET b = 'five' } { - UPDATE main t8 2 2 three four xxx + UPDATE main t8 2 2 three four xxx three five xxx } finish_test From e8d5648e168300c5ed3f0cf89158a55474f7520e Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 17 Mar 2011 19:20:27 +0000 Subject: [PATCH 0011/1484] Change to the session module to use user-defined primary keys instead of rowids when collecting changes. FossilOrigin-Name: 6614cfcb9c41da71ddec3c44a3de0d4d849e1cdd --- ext/session/sqlite3session.c | 775 +++++++++++++++++++++++------------ manifest | 14 +- manifest.uuid | 2 +- test/session1.test | 37 +- 4 files changed, 548 insertions(+), 280 deletions(-) diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index d454d4d345..296875052e 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -8,7 +8,6 @@ #include "sqliteInt.h" #include "vdbeInt.h" -typedef struct RowChange RowChange; typedef struct SessionTable SessionTable; typedef struct SessionChange SessionChange; typedef struct SessionBuffer SessionBuffer; @@ -57,6 +56,8 @@ struct SessionTable { SessionTable *pNext; char *zName; /* Local name of table */ int nCol; /* Number of columns in table zName */ + const char **azCol; /* Column names */ + u8 *abPK; /* Array of primary key flags */ int nEntry; /* Total number of entries in hash table */ int nChange; /* Size of apChange[] array */ SessionChange **apChange; /* Hash table buckets */ @@ -128,7 +129,7 @@ struct SessionTable { ** this structure stored in a SessionTable.aChange[] hash table. */ struct SessionChange { - sqlite3_int64 iKey; /* Key value */ + int bInsert; /* True if row was inserted this session */ int nRecord; /* Number of bytes in buffer aRecord[] */ u8 *aRecord; /* Buffer containing old.* record */ SessionChange *pNext; /* For hash-table collisions */ @@ -264,12 +265,188 @@ static int sessionSerializeValue( return SQLITE_OK; } +#define HASH_APPEND(hash, add) ((hash) << 3) ^ (hash) ^ (int)(add) +static int sessionHashAppendI64(int h, i64 i){ + h = HASH_APPEND(h, i & 0xFFFFFFFF); + return HASH_APPEND(h, (i>>32)&0xFFFFFFFF); +} +static int sessionHashAppendBlob(int h, int n, const u8 *z){ + int i; + for(i=0; inCol==sqlite3_preupdate_count(db) ); + for(i=0; inCol; i++){ + if( pTab->abPK[i] ){ + int rc; + int eType; + sqlite3_value *pVal; + + if( bNew ){ + rc = sqlite3_preupdate_new(db, i, &pVal); + }else{ + rc = sqlite3_preupdate_old(db, i, &pVal); + } + + eType = sqlite3_value_type(pVal); + h = HASH_APPEND(h, eType); + switch( eType ){ + case SQLITE_INTEGER: + case SQLITE_FLOAT: { + i64 iVal; + if( eType==SQLITE_INTEGER ){ + iVal = sqlite3_value_int64(pVal); + }else{ + double rVal = sqlite3_value_double(pVal); + assert( sizeof(iVal)==8 && sizeof(rVal)==8 ); + memcpy(&iVal, &rVal, 8); + } + h = sessionHashAppendI64(h, iVal); + break; + } + + case SQLITE_TEXT: + case SQLITE_BLOB: { + int n = sqlite3_value_bytes(pVal); + const u8 *z = eType==SQLITE_TEXT ? + sqlite3_value_text(pVal) : sqlite3_value_blob(pVal); + h = sessionHashAppendBlob(h, n, z); + break; + } + } + } + } + + *piHash = (h % pTab->nChange); + return SQLITE_OK; +} + +static int sessionChangeHash( + sqlite3 *db, + SessionTable *pTab, + SessionChange *pChange, + int nBucket +){ + int h = 0; + int i; + u8 *a = pChange->aRecord; + + for(i=0; inCol; i++){ + int eType = *a++; + int isPK = pTab->abPK[i]; + + if( isPK ) h = HASH_APPEND(h, eType); + switch( eType ){ + case SQLITE_INTEGER: + case SQLITE_FLOAT: { + if( isPK ){ + i64 iVal = sessionGetI64(a); + h = sessionHashAppendI64(h, iVal); + } + a += 8; + break; + } + case SQLITE_TEXT: + case SQLITE_BLOB: { + int n; + a += sessionVarintGet(a, &n); + if( isPK ){ + h = sessionHashAppendBlob(h, n, a); + } + a += n; + break; + } + } + } + return (h % nBucket); +} + +static int sessionPreupdateEqual( + sqlite3 *db, + SessionTable *pTab, + SessionChange *pChange, + int bNew, + int *pbEqual +){ + int i; + u8 *a = pChange->aRecord; + + *pbEqual = 0; + + for(i=0; inCol; i++){ + int eType = *a++; + if( !pTab->abPK[i] ){ + switch( eType ){ + case SQLITE_INTEGER: + case SQLITE_FLOAT: + a += 8; + break; + + case SQLITE_TEXT: + case SQLITE_BLOB: { + int n; + a += sessionVarintGet(a, &n); + a += n; + break; + } + } + }else{ + sqlite3_value *pVal; + int rc; + if( bNew ){ + rc = sqlite3_preupdate_new(db, i, &pVal); + }else{ + rc = sqlite3_preupdate_old(db, i, &pVal); + } + if( rc!=SQLITE_OK || sqlite3_value_type(pVal)!=eType ) return rc; + + switch( eType ){ + case SQLITE_INTEGER: + case SQLITE_FLOAT: { + i64 iVal = sessionGetI64(a); + a += 8; + if( eType==SQLITE_INTEGER ){ + if( sqlite3_value_int64(pVal)!=iVal ) return SQLITE_OK; + }else{ + double rVal; + assert( sizeof(iVal)==8 && sizeof(rVal)==8 ); + memcpy(&rVal, &iVal, 8); + if( sqlite3_value_double(pVal)!=rVal ) return SQLITE_OK; + } + break; + } + case SQLITE_TEXT: + case SQLITE_BLOB: { + int n; + const u8 *z; + a += sessionVarintGet(a, &n); + if( sqlite3_value_bytes(pVal)!=n ) return SQLITE_OK; + z = eType==SQLITE_TEXT ? + sqlite3_value_text(pVal) : sqlite3_value_blob(pVal); + if( memcmp(a, z, n) ) return SQLITE_OK; + a += n; + break; + } + } + } + } + + *pbEqual = 1; + return SQLITE_OK; } /* @@ -303,7 +480,7 @@ static int sessionGrowHash(sqlite3_session *pSession, SessionTable *pTab){ SessionChange *p; SessionChange *pNext; for(p=pTab->apChange[i]; p; p=pNext){ - int iHash = sessionKeyhash(nNew, p->iKey); + int iHash = sessionChangeHash(pSession->db, pTab, p, nNew); pNext = p->pNext; p->pNext = apNew[iHash]; apNew[iHash] = p; @@ -318,6 +495,130 @@ static int sessionGrowHash(sqlite3_session *pSession, SessionTable *pTab){ return SQLITE_OK; } +/* +** This function queries the database for the names of the columns of table +** zThis, in schema zDb. It is expected that the table has nCol columns. If +** not, SQLITE_SCHEMA is returned and none of the output variables are +** populated. +** +** Otherwise, if it is not NULL, variable *pzTab is set to point to a +** nul-terminated copy of the table name. *pazCol (if not NULL) is set to +** point to an array of pointers to column names. And *pabPK (again, if not +** NULL) is set to point to an array of booleans - true if the corresponding +** column is part of the primary key. +** +** For example, if the table is declared as: +** +** CREATE TABLE tbl1(w, x, y, z, PRIMARY KEY(w, z)); +** +** Then the three output variables are populated as follows: +** +** *pzTab = "tbl1" +** *pazCol = {"w", "x", "y", "z"} +** *pabPK = {1, 0, 0, 1} +** +** All returned buffers are part of the same single allocation, which must +** be freed using sqlite3_free() by the caller. If pazCol was not NULL, then +** pointer *pazCol should be freed to release all memory. Otherwise, pointer +** *pabPK. It is illegal for both pazCol and pabPK to be NULL. +*/ +static int sessionTableInfo( + sqlite3 *db, /* Database connection */ + const char *zDb, /* Name of attached database (e.g. "main") */ + const char *zThis, /* Table name */ + int nCol, /* Expected number of columns */ + const char **pzTab, /* OUT: Copy of zThis */ + const char ***pazCol, /* OUT: Array of column names for table */ + u8 **pabPK /* OUT: Array of booleans - true for PK col */ +){ + char *zPragma; + sqlite3_stmt *pStmt; + int rc; + int nByte; + int nDbCol = 0; + int nThis; + int i; + u8 *pAlloc; + u8 *pFree = 0; + char **azCol; + u8 *abPK; + + assert( pazCol || pabPK ); + + nThis = strlen(zThis); + zPragma = sqlite3_mprintf("PRAGMA '%q'.table_info('%q')", zDb, zThis); + if( !zPragma ) return SQLITE_NOMEM; + + rc = sqlite3_prepare_v2(db, zPragma, -1, &pStmt, 0); + sqlite3_free(zPragma); + if( rc!=SQLITE_OK ) return rc; + + nByte = nThis + 1; + while( SQLITE_ROW==sqlite3_step(pStmt) ){ + nByte += sqlite3_column_bytes(pStmt, 1); + nDbCol++; + } + rc = sqlite3_reset(pStmt); + + if( nDbCol!=nCol ){ + rc = SQLITE_SCHEMA; + } + if( rc==SQLITE_OK ){ + nByte += nDbCol * (sizeof(const char *) + sizeof(u8) + 1); + pAlloc = sqlite3_malloc(nByte); + if( pAlloc==0 ){ + rc = SQLITE_NOMEM; + } + } + if( rc==SQLITE_OK ){ + pFree = pAlloc; + if( pazCol ){ + azCol = (char **)pAlloc; + pAlloc = (u8 *)&azCol[nCol]; + } + if( pabPK ){ + abPK = (u8 *)pAlloc; + pAlloc = &abPK[nCol]; + } + if( pzTab ){ + memcpy(pAlloc, zThis, nThis+1); + *pzTab = (char *)pAlloc; + pAlloc += nThis+1; + } + + i = 0; + while( SQLITE_ROW==sqlite3_step(pStmt) ){ + int nName = sqlite3_column_bytes(pStmt, 1); + const unsigned char *zName = sqlite3_column_text(pStmt, 1); + if( zName==0 ) break; + if( pazCol ){ + memcpy(pAlloc, zName, nName+1); + azCol[i] = (char *)pAlloc; + pAlloc += nName+1; + } + if( pabPK ) abPK[i] = sqlite3_column_int(pStmt, 5); + i++; + } + rc = sqlite3_reset(pStmt); + + } + + /* If successful, populate the output variables. Otherwise, zero them and + ** free any allocation made. An error code will be returned in this case. + */ + if( rc==SQLITE_OK ){ + if( pazCol ) *pazCol = (const char **)azCol; + if( pabPK ) *pabPK = abPK; + }else{ + if( pazCol ) *pazCol = 0; + if( pabPK ) *pabPK = 0; + if( pzTab ) *pzTab = 0; + sqlite3_free(pFree); + } + sqlite3_finalize(pStmt); + return rc; +} + /* ** This function is only called from within a pre-update handler for a ** write to table pTab, part of session pSession. If this is the first @@ -336,12 +637,104 @@ static int sessionGrowHash(sqlite3_session *pSession, SessionTable *pTab){ */ static int sessionInitTable(sqlite3_session *pSession, SessionTable *pTab){ if( pTab->nCol==0 ){ + assert( pTab->azCol==0 || pTab->abPK==0 ); pTab->nCol = sqlite3_preupdate_count(pSession->db); + pSession->rc = sessionTableInfo(pSession->db, pSession->zDb, + pTab->zName, pTab->nCol, 0, &pTab->azCol, &pTab->abPK + ); }else if( pTab->nCol!=sqlite3_preupdate_count(pSession->db) ){ pSession->rc = SQLITE_SCHEMA; - return SQLITE_ERROR; } - return SQLITE_OK; + return pSession->rc; +} + +static void sessionPreupdateOneChange( + int op, + sqlite3_session *pSession, + SessionTable *pTab +){ + sqlite3 *db = pSession->db; + SessionChange *pChange; + SessionChange *pC; + int iHash; + int rc = SQLITE_OK; + + if( pSession->rc ) return; + + /* Load table details if required */ + if( sessionInitTable(pSession, pTab) ) return; + + /* Grow the hash table if required */ + if( sessionGrowHash(pSession, pTab) ) return; + + /* Search the hash table for an existing entry for rowid=iKey2. If + ** one is found, store a pointer to it in pChange and unlink it from + ** the hash table. Otherwise, set pChange to NULL. + */ + rc = sessionPreupdateHash(db, pTab, op==SQLITE_INSERT, &iHash); + for(pC=pTab->apChange[iHash]; rc==SQLITE_OK && pC; pC=pC->pNext){ + int bEqual; + rc = sessionPreupdateEqual(db, pTab, pC, op==SQLITE_INSERT, &bEqual); + if( bEqual ) break; + } + if( pC==0 ){ + /* Create a new change object containing all the old values (if + ** this is an SQLITE_UPDATE or SQLITE_DELETE), or just the PK + ** values (if this is an INSERT). */ + int nByte; /* Number of bytes to allocate */ + int i; /* Used to iterate through columns */ + + pTab->nEntry++; + + /* Figure out how large an allocation is required */ + nByte = sizeof(SessionChange); + for(i=0; inCol && rc==SQLITE_OK; i++){ + sqlite3_value *p = 0; + if( op!=SQLITE_INSERT ){ + rc = sqlite3_preupdate_old(pSession->db, i, &p); + }else if( 1 || pTab->abPK[i] ){ + rc = sqlite3_preupdate_new(pSession->db, i, &p); + } + if( p && rc==SQLITE_OK ){ + rc = sessionSerializeValue(0, p, &nByte); + } + } + + /* Allocate the change object */ + pChange = (SessionChange *)sqlite3_malloc(nByte); + if( !pChange ){ + rc = SQLITE_NOMEM; + }else{ + memset(pChange, 0, sizeof(SessionChange)); + pChange->aRecord = (u8 *)&pChange[1]; + } + + /* Populate the change object */ + nByte = 0; + for(i=0; inCol && rc==SQLITE_OK; i++){ + sqlite3_value *p = 0; + if( op!=SQLITE_INSERT ){ + rc = sqlite3_preupdate_old(pSession->db, i, &p); + }else if( 1 || pTab->abPK[i] ){ + rc = sqlite3_preupdate_new(pSession->db, i, &p); + } + if( p && rc==SQLITE_OK ){ + rc = sessionSerializeValue(&pChange->aRecord[nByte], p, &nByte); + } + } + pChange->nRecord = nByte; + + /* If an error has occurred, mark the session object as failed. */ + if( rc!=SQLITE_OK ){ + sqlite3_free(pChange); + pSession->rc = rc; + }else{ + /* Add the change back to the hash-table */ + pChange->bInsert = (op==SQLITE_INSERT); + pChange->pNext = pTab->apChange[iHash]; + pTab->apChange[iHash] = pChange; + } + } } /* @@ -363,93 +756,19 @@ static void xPreUpdate( for(pSession=(sqlite3_session *)pCtx; pSession; pSession=pSession->pNext){ SessionTable *pTab; - /* If this session is already in the error-state, or if it is attached - ** to a different database ("main", "temp" etc.), or if it is not - ** currently enabled, there is nothing to do. Skip to the next session - ** object attached to this database. */ + /* If this session is attached to a different database ("main", "temp" + ** etc.), or if it is not currently enabled, there is nothing to do. Skip + ** to the next session object attached to this database. */ if( pSession->bEnable==0 ) continue; if( pSession->rc ) continue; if( sqlite3_strnicmp(zDb, pSession->zDb, nDb+1) ) continue; for(pTab=pSession->pTable; pTab; pTab=pTab->pNext){ if( 0==sqlite3_strnicmp(pTab->zName, zName, nName+1) ){ - SessionChange *pChange; - SessionChange *pC; - int iHash; - int rc = SQLITE_OK; - - /* Load table details if required */ - if( sessionInitTable(pSession, pTab) ) return; - - /* Grow the hash table if required */ - if( sessionGrowHash(pSession, pTab) ) return; - - /* Search the hash table for an existing entry for rowid=iKey2. If - ** one is found, store a pointer to it in pChange and unlink it from - ** the hash table. Otherwise, set pChange to NULL. - */ - iHash = sessionKeyhash(pTab->nChange, iKey2); - for(pC=pTab->apChange[iHash]; pC; pC=pC->pNext){ - if( pC->iKey==iKey2 ) break; + sessionPreupdateOneChange(op, pSession, pTab); + if( op==SQLITE_UPDATE ){ + sessionPreupdateOneChange(SQLITE_INSERT, pSession, pTab); } - if( pC ) continue; - - pTab->nEntry++; - - /* Create a new change object containing all the old values (if - ** this is an SQLITE_UPDATE or SQLITE_DELETE), or no record at - ** all (if this is an INSERT). */ - if( op==SQLITE_INSERT ){ - pChange = (SessionChange *)sqlite3_malloc(sizeof(SessionChange)); - if( pChange ){ - memset(pChange, 0, sizeof(SessionChange)); - } - }else{ - int nByte; /* Number of bytes to allocate */ - int i; /* Used to iterate through columns */ - - /* Figure out how large an allocation is required */ - nByte = sizeof(SessionChange); - for(i=0; inCol && rc==SQLITE_OK; i++){ - sqlite3_value *p; /* old.* value */ - rc = sqlite3_preupdate_old(pSession->db, i, &p); - if( rc==SQLITE_OK ){ - rc = sessionSerializeValue(0, p, &nByte); - } - } - - /* Allocate the change object */ - pChange = (SessionChange *)sqlite3_malloc(nByte); - if( !pChange ){ - rc = SQLITE_NOMEM; - }else{ - memset(pChange, 0, sizeof(SessionChange)); - pChange->aRecord = (u8 *)&pChange[1]; - } - - /* Populate the change object */ - nByte = 0; - for(i=0; inCol && rc==SQLITE_OK; i++){ - sqlite3_value *p; /* old.* value */ - rc = sqlite3_preupdate_old(pSession->db, i, &p); - if( rc==SQLITE_OK ){ - rc = sessionSerializeValue(&pChange->aRecord[nByte], p, &nByte); - } - } - pChange->nRecord = nByte; - } - - /* If an error has occurred, mark the session object as failed. */ - if( rc!=SQLITE_OK ){ - sqlite3_free(pChange); - pSession->rc = rc; - return; - } - - /* Add the change back to the hash-table */ - pChange->iKey = iKey2; - pChange->pNext = pTab->apChange[iHash]; - pTab->apChange[iHash] = pChange; break; } } @@ -524,6 +843,7 @@ void sqlite3session_delete(sqlite3_session *pSession){ sqlite3_free(p); } } + sqlite3_free(pTab->azCol); sqlite3_free(pTab->apChange); sqlite3_free(pTab); } @@ -852,127 +1172,99 @@ static void sessionAppendUpdate( } } -/* -** This function queries the database for the names of the columns of table -** zThis, in schema zDb. It is expected that the table has nCol columns. If -** not, SQLITE_SCHEMA is returned and none of the output variables are -** populated. -** -** Otherwise, if it is not NULL, variable *pzTab is set to point to a -** nul-terminated copy of the table name. *pazCol (if not NULL) is set to -** point to an array of pointers to column names. And *pabPK (again, if not -** NULL) is set to point to an array of booleans - true if the corresponding -** column is part of the primary key. -** -** For example, if the table is declared as: -** -** CREATE TABLE tbl1(w, x, y, z, PRIMARY KEY(w, z)); -** -** Then the three output variables are populated as follows: -** -** *pzTab = "tbl1" -** *pazCol = {"w", "x", "y", "z"} -** *pabPK = {1, 0, 0, 1} -** -** All returned buffers are part of the same single allocation, which must -** be freed using sqlite3_free() by the caller. If pazCol was not NULL, then -** pointer *pazCol should be freed to release all memory. Otherwise, pointer -** *pabPK. It is illegal for both pazCol and pabPK to be NULL. -*/ -static int sessionTableInfo( - sqlite3 *db, /* Database connection */ - const char *zDb, /* Name of attached database (e.g. "main") */ - const char *zThis, /* Table name */ - int nCol, /* Expected number of columns */ - const char **pzTab, /* OUT: Copy of zThis */ - const char ***pazCol, /* OUT: Array of column names for table */ - u8 **pabPK /* OUT: Array of booleans - true for PK col */ +static int sessionSelectStmt( + sqlite3 *db, /* Database handle */ + const char *zTab, /* Table name */ + int nCol, + const char **azCol, + u8 *abPK, + sqlite3_stmt **ppStmt ){ - char *zPragma; - sqlite3_stmt *pStmt; - int rc; - int nByte; - int nDbCol = 0; - int nThis; + int rc = SQLITE_OK; int i; - u8 *pAlloc; - u8 *pFree = 0; - char **azCol; - u8 *abPK; + const char *zSep = ""; + SessionBuffer buf = {0, 0, 0}; - assert( pazCol || pabPK ); - - nThis = strlen(zThis); - zPragma = sqlite3_mprintf("PRAGMA '%q'.table_info('%q')", zDb, zThis); - if( !zPragma ) return SQLITE_NOMEM; - - rc = sqlite3_prepare_v2(db, zPragma, -1, &pStmt, 0); - sqlite3_free(zPragma); - if( rc!=SQLITE_OK ) return rc; - - nByte = nThis + 1; - while( SQLITE_ROW==sqlite3_step(pStmt) ){ - nByte += sqlite3_column_bytes(pStmt, 1); - nDbCol++; - } - rc = sqlite3_reset(pStmt); - - if( nDbCol!=nCol ){ - rc = SQLITE_SCHEMA; - } - if( rc==SQLITE_OK ){ - nByte += nDbCol * (sizeof(const char *) + sizeof(u8) + 1); - pAlloc = sqlite3_malloc(nByte); - if( pAlloc==0 ){ - rc = SQLITE_NOMEM; + sessionAppendStr(&buf, "SELECT * FROM ", &rc); + sessionAppendIdent(&buf, zTab, &rc); + sessionAppendStr(&buf, " WHERE ", &rc); + for(i=0; ipTable; rc==SQLITE_OK && pTab; pTab=pTab->pNext){ if( pTab->nEntry ){ + int nCol = pTab->nCol; /* Local copy of member variable */ + u8 *abPK = pTab->abPK; /* Local copy of member variable */ int i; sqlite3_stmt *pStmt = 0; int bNoop = 1; int nRewind = buf.nBuf; - u8 *abPK = 0; /* Write a table header */ sessionAppendByte(&buf, 'T', &rc); - sessionAppendVarint(&buf, pTab->nCol, &rc); + sessionAppendVarint(&buf, nCol, &rc); sessionAppendBlob(&buf, (u8 *)pTab->zName, strlen(pTab->zName)+1, &rc); /* Build and compile a statement to execute: */ if( rc==SQLITE_OK ){ - char *zSql = sqlite3_mprintf("SELECT * FROM %Q.%Q WHERE _rowid_ = ?", - pSession->zDb, pTab->zName - ); - if( !zSql ){ - rc = SQLITE_NOMEM; - }else{ - rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); - } - sqlite3_free(zSql); + rc = sessionSelectStmt(db, pTab->zName, nCol, pTab->azCol, abPK,&pStmt); } - if( rc==SQLITE_OK && pTab->nCol!=sqlite3_column_count(pStmt) ){ + if( rc==SQLITE_OK && nCol!=sqlite3_column_count(pStmt) ){ rc = SQLITE_SCHEMA; } - if( rc==SQLITE_OK ){ - rc = sessionTableInfo( - db, pSession->zDb, pTab->zName, pTab->nCol, 0, 0, &abPK); - } - for(i=0; inChange; i++){ - SessionChange *p; + SessionChange *p; /* Used to iterate through changes */ + for(p=pTab->apChange[i]; rc==SQLITE_OK && p; p=p->pNext){ - sqlite3_bind_int64(pStmt, 1, p->iKey); - if( sqlite3_step(pStmt)==SQLITE_ROW ){ - int iCol; - if( p->aRecord ){ - sessionAppendUpdate(&buf, pStmt, p, abPK, &rc); - }else{ - sessionAppendByte(&buf, SQLITE_INSERT, &rc); - for(iCol=0; iColnCol; iCol++){ - sessionAppendCol(&buf, pStmt, iCol, &rc); + rc = sessionSelectBind(pStmt, nCol, abPK, p->aRecord, p->nRecord); + if( rc==SQLITE_OK ){ + if( sqlite3_step(pStmt)==SQLITE_ROW ){ + int iCol; + if( p->bInsert ){ + sessionAppendByte(&buf, SQLITE_INSERT, &rc); + for(iCol=0; iColbInsert ){ + /* A DELETE change */ + sessionAppendByte(&buf, SQLITE_DELETE, &rc); + sessionAppendBlob(&buf, p->aRecord, p->nRecord, &rc); + bNoop = 0; } - bNoop = 0; - }else if( p->aRecord ){ - /* A DELETE change */ - sessionAppendByte(&buf, SQLITE_DELETE, &rc); - sessionAppendBlob(&buf, p->aRecord, p->nRecord, &rc); - bNoop = 0; + rc = sqlite3_reset(pStmt); } - rc = sqlite3_reset(pStmt); } } sqlite3_finalize(pStmt); - sqlite3_free(abPK); if( bNoop ){ buf.nBuf = nRewind; @@ -1632,28 +1914,7 @@ static int sessionSelectRow( const char *zTab, /* Table name */ SessionApplyCtx *p /* Session changeset-apply context */ ){ - int rc = SQLITE_OK; - int i; - const char *zSep = ""; - SessionBuffer buf = {0, 0, 0}; - - sessionAppendStr(&buf, "SELECT * FROM ", &rc); - sessionAppendIdent(&buf, zTab, &rc); - sessionAppendStr(&buf, " WHERE ", &rc); - for(i=0; inCol; i++){ - if( p->abPK[i] ){ - sessionAppendStr(&buf, zSep, &rc); - sessionAppendIdent(&buf, p->azCol[i], &rc); - sessionAppendStr(&buf, " = ?", &rc); - sessionAppendInteger(&buf, i+1, &rc); - zSep = " AND "; - } - } - if( rc==SQLITE_OK ){ - rc = sqlite3_prepare_v2(db, (char *)buf.aBuf, buf.nBuf, &p->pSelect, 0); - } - sqlite3_free(buf.aBuf); - return rc; + return sessionSelectStmt(db, zTab, p->nCol, p->azCol, p->abPK, &p->pSelect); } /* diff --git a/manifest b/manifest index 796df369be..2ab7a1eec9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\ssqlite3_preupdate_new()\sAPI,\sfor\sretrieving\sthe\snew.*\svalues\sfrom\swithin\sa\spre-update\scallback. -D 2011-03-16T19:59:19 +C Change\sto\sthe\ssession\smodule\sto\suse\suser-defined\sprimary\skeys\sinstead\sof\srowids\swhen\scollecting\schanges. +D 2011-03-17T19:20:27 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -98,7 +98,7 @@ F ext/rtree/rtree_util.tcl 06aab2ed5b826545bf215fff90ecb9255a8647ea F ext/rtree/sqlite3rtree.h 1af0899c63a688e272d69d8e746f24e76f10a3f0 F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 -F ext/session/sqlite3session.c 9b8d123418c024f6851163375fca99042757772f +F ext/session/sqlite3session.c 4183792547af5b5d3ec1c8a3f858beb172682503 F ext/session/sqlite3session.h 63045871564085669b5cb1fb92e6efc2e1b1120a F ext/session/test_session.c 2559ef68e421c7fb83e2c19ef08a17343b70d535 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 @@ -639,7 +639,7 @@ F test/selectA.test 06d1032fa9009314c95394f2ca2e60d9f7ae8532 F test/selectB.test f305cc6660804cb239aab4e2f26b0e288b59958b F test/selectC.test f9bf1bc4581b5b8158caa6e4e4f682acb379fb25 F test/server1.test f5b790d4c0498179151ca8a7715a65a7802c859c -F test/session1.test 1e85c2eedb14587dff41901faa5a66c117fe0405 +F test/session1.test c6851e2e1066269cad5370566ce5494c7dbdfa7e F test/shared.test b9114eaea7e748a3a4c8ff7b9ca806c8f95cef3e F test/shared2.test 7f6ad2d857d0f4e5d6a0b9a897b5e56a6b6ea18c F test/shared3.test d69bdd5f156580876c5345652d21dc2092e85962 @@ -913,7 +913,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P b0015a1cfe63c924ee5f250aa08460522882009b -R 4b62a15aa3feb03b0e54e624839e53a1 +P 526545c49f64d9063d1b888cfc14ece62fa3c13c +R cab2f9d8485568249e1bae732085445e U dan -Z 0b4af75dcf5347bcbba47251e978ee95 +Z 0451d1109f54d52c16342adf23f8ece9 diff --git a/manifest.uuid b/manifest.uuid index 69c5255486..412c6f3bf5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -526545c49f64d9063d1b888cfc14ece62fa3c13c \ No newline at end of file +6614cfcb9c41da71ddec3c44a3de0d4d849e1cdd \ No newline at end of file diff --git a/test/session1.test b/test/session1.test index ca8d9a78f1..872bee416f 100644 --- a/test/session1.test +++ b/test/session1.test @@ -37,7 +37,7 @@ proc do_changeset_invert_test {tn session res} { } do_execsql_test 1.0 { - CREATE TABLE t1(x, y); + CREATE TABLE t1(x PRIMARY KEY, y); INSERT INTO t1 VALUES('abc', 'def'); } @@ -113,6 +113,7 @@ do_changeset_invert_test 2.2.3 S { do_test 2.2.4 { S delete } {} do_test 2.3.1 { + execsql { DELETE FROM t1 } sqlite3session S db main execsql { INSERT INTO t1 VALUES(1, 'Sukhothai') } execsql { INSERT INTO t1 VALUES(2, 'Ayutthaya') } @@ -126,14 +127,19 @@ do_test 2.3.1 { } {} do_changeset_test 2.3.2 S { - {UPDATE t1 {i 1 {} {}} {i 10 {} {}}} - {UPDATE t1 {{} {} t Ayutthaya} {{} {} t Surin}} - {UPDATE t1 {i 3 t Thonburi} {i 20 t Thapae}} + {INSERT t1 {} {i 10 t Sukhothai}} + {DELETE t1 {i 1 t Sukhothai} {}} + {UPDATE t1 {i 2 t Ayutthaya} {{} {} t Surin}} + {DELETE t1 {i 3 t Thonburi} {}} + {INSERT t1 {} {i 20 t Thapae}} } + do_changeset_invert_test 2.3.3 S { - {UPDATE t1 {i 10 {} {}} {i 1 {} {}}} - {UPDATE t1 {{} {} t Surin} {{} {} t Ayutthaya}} - {UPDATE t1 {i 20 t Thapae} {i 3 t Thonburi}} + {DELETE t1 {i 10 t Sukhothai} {}} + {INSERT t1 {} {i 1 t Sukhothai}} + {UPDATE t1 {{} {} t Surin} {i 2 t Ayutthaya}} + {INSERT t1 {} {i 3 t Thonburi}} + {DELETE t1 {i 20 t Thapae} {}} } do_test 2.3.4 { S delete } {} @@ -209,7 +215,7 @@ do_test 3.1.0 { } db } {} do_db2_test 3.1.1 "INSERT INTO t1 VALUES(6, 'VI')" -do_conflict_test 3.2.2 -tables t1 -sql { +do_conflict_test 3.1.2 -tables t1 -sql { INSERT INTO t1 VALUES(3, 'three'); INSERT INTO t1 VALUES(4, 'four'); INSERT INTO t1 VALUES(5, 'five'); @@ -217,13 +223,14 @@ do_conflict_test 3.2.2 -tables t1 -sql { INSERT INTO t1 VALUES(7, 'seven'); INSERT INTO t1 VALUES(8, NULL); } -conflicts { - {INSERT t1 CONFLICT {i 6 t six} {i 6 t VI}} {INSERT t1 CONSTRAINT {i 8 n {}}} + {INSERT t1 CONFLICT {i 6 t six} {i 6 t VI}} } -do_db2_test 3.1.2 "SELECT * FROM t1" { + +do_db2_test 3.1.3 "SELECT * FROM t1" { 6 VI 3 three 4 four 5 five 7 seven } -do_execsql_test 3.1.3 "SELECT * FROM t1" { +do_execsql_test 3.1.4 "SELECT * FROM t1" { 1 one 2 two 3 three 4 four 5 five 6 six 7 seven 8 {} } @@ -282,9 +289,9 @@ do_conflict_test 3.3.3 -tables t4 -sql { UPDATE t4 SET a = NULL WHERE c = 9; UPDATE t4 SET a = 'x' WHERE b = 11; } -conflicts { + {UPDATE t4 CONSTRAINT {i 7 i 8 i 9} {n {} {} {} {} {}}} {UPDATE t4 DATA {i 1 i 2 i 3} {i -1 {} {} {} {}} {i 0 i 2 i 3}} {UPDATE t4 NOTFOUND {i 4 i 5 i 6} {i -1 {} {} {} {}}} - {UPDATE t4 CONSTRAINT {i 7 i 8 i 9} {n {} {} {} {} {}}} } do_db2_test 3.3.4 { SELECT * FROM t4 } {0 2 3 4 5 7 7 8 9 x 11 12} do_execsql_test 3.3.5 { SELECT * FROM t4 } {-1 2 3 -1 5 6 {} 8 9 x 11 12} @@ -308,8 +315,8 @@ proc xConflict {args} { } foreach {tn conflict_return after} { - 1 OMIT {1 2 value1 4 5 7 7 8 9 10 x x} - 2 REPLACE {1 2 value1 4 5 value2 10 8 9} + 1 OMIT {1 2 value1 4 5 7 10 x x} + 2 REPLACE {1 2 value1 4 5 value2 10 8 9} } { test_reset @@ -333,8 +340,8 @@ foreach {tn conflict_return after} { UPDATE t1 SET c = 'value2' WHERE a = 4; -- DATA conflict UPDATE t1 SET a = 10 WHERE a = 7; -- CONFLICT conflict } -conflicts { + {INSERT t1 CONFLICT {i 10 i 8 i 9} {i 10 t x t x}} {UPDATE t1 DATA {i 4 {} {} i 6} {{} {} {} {} t value2} {i 4 i 5 i 7}} - {UPDATE t1 CONFLICT {i 7 {} {} {} {}} {i 10 {} {} {} {}} {i 10 t x t x}} } do_db2_test 4.$tn.3 "SELECT * FROM t1 ORDER BY a" $after From c21111daffd0cba6c099c91242052c047f3b54b2 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 18 Mar 2011 13:05:15 +0000 Subject: [PATCH 0012/1484] Update comments in sqlite3session.h. More to come. FossilOrigin-Name: e73e9082f3b14088752717193a10dd7657deb8af --- ext/session/sqlite3session.h | 252 +++++++++++++++++++++++++++++++---- install-sh | 0 manifest | 30 ++--- manifest.uuid | 2 +- test/progress.test | 0 tool/mkopts.tcl | 0 6 files changed, 239 insertions(+), 45 deletions(-) mode change 100755 => 100644 install-sh mode change 100644 => 100755 test/progress.test mode change 100644 => 100755 tool/mkopts.tcl diff --git a/ext/session/sqlite3session.h b/ext/session/sqlite3session.h index 573b2ff3fc..9cf7cda488 100644 --- a/ext/session/sqlite3session.h +++ b/ext/session/sqlite3session.h @@ -18,7 +18,7 @@ typedef struct sqlite3_changeset_iter sqlite3_changeset_iter; ** Create a new session object attached to database handle db. If successful, ** a pointer to the new object is written to *ppSession and SQLITE_OK is ** returned. If an error occurs, *ppSession is set to NULL and an SQLite -** error code (e.g. [SQLITE_NOMEM]) is returned. +** error code (e.g. SQLITE_NOMEM) is returned. ** ** It is possible to create multiple session objects attached to a single ** database handle. @@ -64,6 +64,9 @@ void sqlite3session_delete(sqlite3_session *pSession); ** Enable or disable the recording of changes by a session object. When ** enabled, a session object records changes made to the database. When ** disabled - it does not. A newly created session object is enabled. +** Refer to the documentation for [sqlite3session_changeset()] for further +** details regarding how enabling and disabling a session object affects +** the eventual changesets. ** ** Passing zero to this function disables the session. Passing a value ** greater than zero enables it. Passing a value less than zero is a @@ -76,11 +79,21 @@ int sqlite3session_enable(sqlite3_session *pSession, int bEnable); /* ** Attach a table to a session. All subsequent changes made to the table -** while the session object is enabled will be recorded. +** while the session object is enabled will be recorded. See documentation +** for [sqlite3session_changeset()] for further details. ** -** Only tables that have a PRIMARY KEY defined may be attached. It does -** not matter if the PRIMARY KEY is an "INTEGER PRIMARY KEY" (rowid alias) -** or not. +** Changes can only be recorded for tables that have a PRIMARY KEY explicitly +** defined as part of their CREATE TABLE statement. It does not matter if the +** PRIMARY KEY is an "INTEGER PRIMARY KEY" (rowid alias) or not. The PRIMARY +** KEY may consist of a single column, or may be a composite key. +** +** It is not an error if the named table does not exist in the database. Nor +** is it an error if the named table does not have a PRIMARY KEY. However, +** no changes will be recorded in either of these scenarios. +** +** SQLITE_OK is returned if the table is successfully attached to the session +** object. Or, if an error occurs, an SQLite error code (e.g. SQLITE_NOMEM) +** is returned. */ int sqlite3session_attach( sqlite3_session *pSession, /* Session object */ @@ -95,9 +108,77 @@ int sqlite3session_attach( ** SQLITE_OK. If an error occurs, set both *ppChangeset and *pnChangeset to ** zero and return an SQLite error code. ** +** A changeset consists of zero or more INSERT, UPDATE and/or DELETE changes, +** each representing a change to a single row of an attached table. An INSERT +** change contains the values of each field of a new database row. A DELETE +** contains the original values of each field of a deleted database row. An +** UPDATE change contains the original values of each field of an updated +** database row along with the updated values for each updated non-primary-key +** column. It is not possible for an UPDATE change to represent a change that +** modifies the values of primary key columns. If such a change is made, it +** is represented in a changeset as a DELETE followed by an INSERT. +** +** The contents of a changeset may be traversed using an iterator created +** using the [sqlite3changeset_start()] API. A changeset may be applied to +** a database with a compatible schema using the [sqlite3changset_apply()] +** API. +** ** Following a successful call to this function, it is the responsibility of ** the caller to eventually free the buffer that *ppChangeset points to using ** [sqlite3_free()]. +** +**

Changeset Generation

+** +** Once a table has been attached to a session object, the session object +** records the primary key values of all new rows inserted into the table. +** It also records the original primary key and other column values of any +** deleted or updated rows. For each unique primary key value, data is only +** recorded once - the first time a row with said primary key is inserted, +** updated or deleted in the lifetime of the session. +** +** The session object therefore accumulates two types of records - those +** that consist of primary key values only (created when the user inserts +** a new record) and those that consist of the primary key values and the +** original values of other table columns (created when the users deletes +** or updates a record). +** +** When this function is called, the requested changeset is created using +** both the accumulated records and the current contents of the database +** file. Specifically: +** +**
    +**
  • For each record generated by an insert, the database is queried +** for a row with a matching primary key. If one is found, an INSERT +** change is added to the changeset. If no such row is found, no change +** is added to the changeset. +** +**
  • For each record generated by an update or delete, the database is +** queried for a row with a matching primary key. If such a row is +** found and one or more of the non-primary key fields have been +** modified from their original values, an UPDATE change is added to +** the changeset. Or, if no such row is found in the table, a DELETE +** change is added to the changeset. If there is a row with a matching +** primary key in the database, but all fields contain their original +** values, no change is added to the changeset. +**
+** +** This means, amongst other things, that if a row is inserted and then later +** deleted while a session object is active, neither the insert or the delete +** will be present in the changeset. Or if a row is deleted and then later a +** row with the same primary key values inserted while a session object is +** active, the resulting changeset will contain an UPDATE change instead of +** a DELETE and an INSERT. +** +** When a session object is disabled (see the [sqlite3session_enable()] API), +** it does not accumulate records when rows are inserted, updated or deleted. +** This may appear to have some counter-intuitive effects if a single row +** is written to more than once during a session. For example, if a row +** is inserted while a session object is enabled, then later deleted while +** the same session object is disabled, no INSERT record will appear in the +** changeset, even though the delete took place while the session was disabled. +** Or, if one field of a row is updated while a session is disabled, and +** another field of the same row is updated while the session is enabled, the +** resulting changeset will contain an UPDATE change that updates both fields. */ int sqlite3session_changeset( sqlite3_session *pSession, /* Session object */ @@ -107,27 +188,73 @@ int sqlite3session_changeset( /* ** Create an iterator used to iterate through the contents of a changeset. +** If successful, *pp is set to point to the iterator handle and SQLITE_OK +** is returned. Otherwise, if an error occurs, *pp is set to zero and an +** SQLite error code is returned. +** +** The following functions can be used to advance and query a changeset +** iterator created by this function: +** +**
    +**
  • [sqlite3changeset_next()] +**
  • [sqlite3changeset_op()] +**
  • [sqlite3changeset_new()] +**
  • [sqlite3changeset_old()] +**
+** +** It is the responsibility of the caller to eventually destroy the iterator +** by passing it to [sqlite3changeset_finalize()]. The buffer containing the +** changeset (pChangeset) must remain valid until after the iterator is +** destroyed. */ int sqlite3changeset_start( - sqlite3_changeset_iter **ppIter, - int nChangeset, - void *pChangeset + sqlite3_changeset_iter **pp, /* OUT: New changeset iterator handle */ + int nChangeset, /* Size of changeset blob in bytes */ + void *pChangeset /* Pointer to blob containing changeset */ ); /* -** Advance an iterator created by sqlite3changeset_start() to the next -** change in the changeset. This function may return SQLITE_ROW, SQLITE_DONE -** or SQLITE_CORRUPT. +** This function may only be used with iterators created by function +** [sqlite3changeset_start()]. If it is called on an iterator passed to +** a conflict-handler callback by [sqlite3changeset_apply()], SQLITE_MISUSE +** is returned and the call has no effect. ** -** This function may not be called on iterators passed to a conflict handler -** callback by changeset_apply(). +** Immediately after an iterator is created by sqlite3changeset_start(), it +** does not point to any change in the changeset. Assuming the changeset +** is not empty, the first call to this function advances the iterator to +** point to the first change in the changeset. Each subsequent call advances +** the iterator to point to the next change in the changeset (if any). If +** no error occurs and the iterator points to a valid change after a call +** to sqlite3changeset_next() has advanced it, SQLITE_ROW is returned. +** Otherwise, if all changes in the changeset have already been visited, +** SQLITE_DONE is returned. +** +** If an error occurs, an SQLite error code is returned. Possible error +** codes include SQLITE_CORRUPT (if the changeset buffer is corrupt) or +** SQLITE_NOMEM. */ int sqlite3changeset_next(sqlite3_changeset_iter *pIter); /* -** The following three functions extract information on the current change -** from a changeset iterator. They may only be called after changeset_next() -** has returned SQLITE_ROW. +** The pIter argument passed to this function may either be an iterator +** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator +** created by [sqlite3changeset_start()]. In the latter case, the most recent +** call to [sqlite3changeset_next()] must have returned SQLITE_ROW. If this +** is not the case, this function returns SQLITE_MISUSE. +** +** If argument pzTab is not NULL, then *pzTab is set to point to a +** nul-terminated utf-8 encoded string containing the name of the table +** affected by the current change. The buffer remains valid until either +** sqlite3changeset_next() is called on the iterator or until the +** conflict-handler function returns. If pnCol is not NULL, then *pnCol is +** set to the number of columns in the table affected by the change. Finally, +** if pOp is not NULL, then *pOp is set to one of SQLITE_INSERT, SQLITE_DELETE +** or SQLITE_UPDATE, depending on the type of change that the iterator +** currently points to. +** +** If no error occurs, SQLITE_OK is returned. If an error does occur, an +** SQLite error code is returned. The values of the output variables may not +** be trusted in this case. */ int sqlite3changeset_op( sqlite3_changeset_iter *pIter, /* Iterator object */ @@ -135,11 +262,60 @@ int sqlite3changeset_op( int *pnCol, /* OUT: Number of columns in table */ int *pOp /* OUT: SQLITE_INSERT, DELETE or UPDATE */ ); + +/* +** The pIter argument passed to this function may either be an iterator +** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator +** created by [sqlite3changeset_start()]. In the latter case, the most recent +** call to [sqlite3changeset_next()] must have returned SQLITE_ROW. +** Furthermore, it may only be called if the type of change that the iterator +** currently points to is either SQLITE_DELETE or SQLITE_UPDATE. Otherwise, +** this function returns SQLITE_MISUSE and sets *ppValue to NULL. +** +** Argument iVal must be greater than or equal to 0, and less than the number +** of columns in the table affected by the current change. Otherwise, +** SQLITE_RANGE is returned and *ppValue is set to NULL. +** +** If successful, this function sets *ppValue to point to a protected +** sqlite3_value object containing the iVal'th value from the vector of +** original row values stored as part of the UPDATE or DELETE change and +** returns SQLITE_OK. The name of the function comes from the fact that this +** is similar to the "old.*" columns available to update or delete triggers. +** +** If some other error occurs (e.g. an OOM condition), an SQLite error code +** is returned and *ppValue is set to NULL. +*/ int sqlite3changeset_old( sqlite3_changeset_iter *pIter, /* Changeset iterator */ int iVal, /* Column number */ sqlite3_value **ppValue /* OUT: Old value (or NULL pointer) */ ); + +/* +** The pIter argument passed to this function may either be an iterator +** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator +** created by [sqlite3changeset_start()]. In the latter case, the most recent +** call to [sqlite3changeset_next()] must have returned SQLITE_ROW. +** Furthermore, it may only be called if the type of change that the iterator +** currently points to is either SQLITE_UPDATE or SQLITE_INSERT. Otherwise, +** this function returns SQLITE_MISUSE and sets *ppValue to NULL. +** +** Argument iVal must be greater than or equal to 0, and less than the number +** of columns in the table affected by the current change. Otherwise, +** SQLITE_RANGE is returned and *ppValue is set to NULL. +** +** If successful, this function sets *ppValue to point to a protected +** sqlite3_value object containing the iVal'th value from the vector of +** new row values stored as part of the UPDATE or INSERT change and +** returns SQLITE_OK. If the change is an UPDATE and does not include +** a new value for the requested column, *ppValue is set to NULL and +** SQLITE_OK returned. The name of the function comes from the fact that +** this is similar to the "new.*" columns available to update or delete +** triggers. +** +** If some other error occurs (e.g. an OOM condition), an SQLite error code +** is returned and *ppValue is set to NULL. +*/ int sqlite3changeset_new( sqlite3_changeset_iter *pIter, /* Changeset iterator */ int iVal, /* Column number */ @@ -147,13 +323,23 @@ int sqlite3changeset_new( ); /* -** This function is only usable with sqlite3_changeset_iter objects passed -** to the xConflict callback by sqlite3changeset_apply(). It cannot be used -** with iterators created using sqlite3changeset_start(). +** This function should only be used with iterator objects passed to a +** conflict-handler callback by [sqlite3changeset_apply()] with either +** SQLITE_CHANGESET_DATA or SQLITE_CHANGESET_CONFLICT. If this function +** is called on any other iterator, SQLITE_MISUSE is returned and *ppValue +** is set to NULL. ** -** It is used to access the "conflicting row" information available to the -** conflict handler if the second argument is either SQLITE_CHANGESET_DATA -** or SQLITE_CHANGESET_CONFLICT. +** Argument iVal must be greater than or equal to 0, and less than the number +** of columns in the table affected by the current change. Otherwise, +** SQLITE_RANGE is returned and *ppValue is set to NULL. +** +** If successful, this function sets *ppValue to point to a protected +** sqlite3_value object containing the iVal'th value from the +** "conflicting row" associated with the current conflict-handler callback +** and returns SQLITE_OK. +** +** If some other error occurs (e.g. an OOM condition), an SQLite error code +** is returned and *ppValue is set to NULL. */ int sqlite3changeset_conflict( sqlite3_changeset_iter *pIter, /* Changeset iterator */ @@ -165,8 +351,26 @@ int sqlite3changeset_conflict( /* ** Finalize an iterator allocated with sqlite3changeset_start(). ** -** This function may not be called on iterators passed to a conflict handler -** callback by changeset_apply(). +** This function should only be called on iterators created using the +** [sqlite3changeset_start()] function. If an application calls this +** function with an iterator passed to a conflict-handler by +** [sqlite3changeset_apply()], SQLITE_MISUSE is immediately returned and the +** call has no effect. +** +** If an error was encountered within a call to an sqlite3changeset_xxx() +** function (for example an SQLITE_CORRUPT in sqlite3changeset_next() or an +** SQLITE_NOMEM in sqlite3changeset_new()) then an error code corresponding +** to that error is returned by this function. Otherwise, SQLITE_OK is +** returned. This is to allow the following pattern (pseudo-code): +** +** sqlite3changeset_start(); +** while( SQLITE_ROW==sqlite3changeset_next() ){ +** // Do something with change. +** } +** rc = sqlite3changeset_finalize(); +** if( rc!=SQLITE_OK ){ +** // An error has occurred +** } */ int sqlite3changeset_finalize(sqlite3_changeset_iter *pIter); diff --git a/install-sh b/install-sh old mode 100755 new mode 100644 diff --git a/manifest b/manifest index 212e1e9851..a137b38bb3 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,5 @@ ------BEGIN PGP SIGNED MESSAGE----- -Hash: SHA1 - -C Merge\sall\sthe\slatest\strunk\senhancements\sinto\sthe\ssessions\sbranch. -D 2011-03-18T12:35:36.113 +C Update\scomments\sin\ssqlite3session.h.\sMore\sto\scome. +D 2011-03-18T13:05:15 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -103,9 +100,9 @@ F ext/rtree/sqlite3rtree.h 1af0899c63a688e272d69d8e746f24e76f10a3f0 F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 F ext/session/sqlite3session.c 4183792547af5b5d3ec1c8a3f858beb172682503 -F ext/session/sqlite3session.h 63045871564085669b5cb1fb92e6efc2e1b1120a +F ext/session/sqlite3session.h 3e342facbb95589dfba34545df383df68cc44ebf F ext/session/test_session.c 2559ef68e421c7fb83e2c19ef08a17343b70d535 -F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x +F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F main.mk ae0868e05c76eaa8a0ae3d6927a949b1c8e810d7 F mkdll.sh 7d09b23c05d56532e9d44a50868eb4b12ff4f74a @@ -608,7 +605,7 @@ F test/permutations.test 5b2a4cb756ffb2407cb4743163668d1d769febb6 F test/pragma.test fdfc09067ea104a0c247a1a79d8093b56656f850 F test/pragma2.test 5364893491b9231dd170e3459bfc2e2342658b47 F test/printf.test 05970cde31b1a9f54bd75af60597be75a5c54fea -F test/progress.test 5b075c3c790c7b2a61419bc199db87aaf48b8301 +F test/progress.test 5b075c3c790c7b2a61419bc199db87aaf48b8301 x F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc F test/quick.test 1681febc928d686362d50057c642f77a02c62e57 F test/quota.test ddafe133653093eb9a99ccd6264884ae43f9c9b8 @@ -896,7 +893,7 @@ F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5 F tool/lemon.c dfd81a51b6e27e469ba21d01a75ddf092d429027 F tool/lempar.c 01ca97f87610d1dac6d8cd96ab109ab1130e76dc F tool/mkkeywordhash.c d2e6b4a5965e23afb80fbe74bb54648cd371f309 -F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e +F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e x F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 F tool/mksqlite3c.tcl cf44512a48112b1ba09590548660a5a6877afdb3 F tool/mksqlite3h.tcl d76c226a5e8e1f3b5f6593bcabe5e98b3b1ec9ff @@ -921,14 +918,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 6614cfcb9c41da71ddec3c44a3de0d4d849e1cdd 54bacb95dd6e2d6ac4971391a40484ccb9126d29 -R e54868c8ee7f58a0691b9e0694987cf6 -U drh -Z 8149dc4ff84780eb7c2d29113d1dc5ec ------BEGIN PGP SIGNATURE----- -Version: GnuPG v1.4.6 (GNU/Linux) - -iD8DBQFNg1GboxKgR168RlERAptpAJ4+cfNBHl8w0y578KOanLZsuj14mgCffUXp -W65/Ci2dAe+flL3fcPt3X+4= -=uYuP ------END PGP SIGNATURE----- +P 94fd5bb6da5ef4d850c2ed4ad38afabc5569dae6 +R eb9573de7a3fa964ba524a7a8e9a976a +U dan +Z f742ca024227ec41f9ba4edac43a23a5 diff --git a/manifest.uuid b/manifest.uuid index 2d0f8d52c6..d587d908a1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -94fd5bb6da5ef4d850c2ed4ad38afabc5569dae6 \ No newline at end of file +e73e9082f3b14088752717193a10dd7657deb8af \ No newline at end of file diff --git a/test/progress.test b/test/progress.test old mode 100644 new mode 100755 diff --git a/tool/mkopts.tcl b/tool/mkopts.tcl old mode 100644 new mode 100755 From ea022cffdd9e81e9bf52761e923e0e95a32624bc Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 18 Mar 2011 15:13:31 +0000 Subject: [PATCH 0013/1484] Fix a memory allocation issues in the preupdate hook so that the hook.test script runs clean in valgrind. FossilOrigin-Name: bd94f4c8b1c4590c437030f0122015f1a37e2582 --- install-sh | 0 manifest | 30 ++++++++++++++++++++---------- manifest.uuid | 2 +- src/vdbeaux.c | 5 ++--- test/progress.test | 0 tool/mkopts.tcl | 0 6 files changed, 23 insertions(+), 14 deletions(-) mode change 100644 => 100755 install-sh mode change 100755 => 100644 test/progress.test mode change 100755 => 100644 tool/mkopts.tcl diff --git a/install-sh b/install-sh old mode 100644 new mode 100755 diff --git a/manifest b/manifest index a137b38bb3..47e7037226 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,8 @@ -C Update\scomments\sin\ssqlite3session.h.\sMore\sto\scome. -D 2011-03-18T13:05:15 +-----BEGIN PGP SIGNED MESSAGE----- +Hash: SHA1 + +C Fix\sa\smemory\sallocation\sissues\sin\sthe\spreupdate\shook\sso\sthat\sthe\shook.test\nscript\sruns\sclean\sin\svalgrind. +D 2011-03-18T15:13:31.545 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -102,7 +105,7 @@ F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 F ext/session/sqlite3session.c 4183792547af5b5d3ec1c8a3f858beb172682503 F ext/session/sqlite3session.h 3e342facbb95589dfba34545df383df68cc44ebf F ext/session/test_session.c 2559ef68e421c7fb83e2c19ef08a17343b70d535 -F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 +F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F main.mk ae0868e05c76eaa8a0ae3d6927a949b1c8e810d7 F mkdll.sh 7d09b23c05d56532e9d44a50868eb4b12ff4f74a @@ -238,7 +241,7 @@ F src/vdbe.c 94cd191b1b20b0124e09b056bbce3d09f79821b3 F src/vdbe.h 4de0efb4b0fdaaa900cf419b35c458933ef1c6d2 F src/vdbeInt.h 20d13da932eed0667a2e2383a9cb0f80099a5fd3 F src/vdbeapi.c 988ee9420acf8c130d644e6d7282893efe927bbd -F src/vdbeaux.c ce48afec3f218b755f7b0ef1bef54a4be44cd833 +F src/vdbeaux.c bb194e1250a0e35e3a5e17e51631da858e23930a F src/vdbeblob.c 18955f0ee6b133cd08e1592010cb9a6b11e9984c F src/vdbemem.c 0498796b6ffbe45e32960d6a1f5adfb6e419883b F src/vdbetrace.c 3ba13bc32bdf16d2bdea523245fd16736bed67b5 @@ -605,7 +608,7 @@ F test/permutations.test 5b2a4cb756ffb2407cb4743163668d1d769febb6 F test/pragma.test fdfc09067ea104a0c247a1a79d8093b56656f850 F test/pragma2.test 5364893491b9231dd170e3459bfc2e2342658b47 F test/printf.test 05970cde31b1a9f54bd75af60597be75a5c54fea -F test/progress.test 5b075c3c790c7b2a61419bc199db87aaf48b8301 x +F test/progress.test 5b075c3c790c7b2a61419bc199db87aaf48b8301 F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc F test/quick.test 1681febc928d686362d50057c642f77a02c62e57 F test/quota.test ddafe133653093eb9a99ccd6264884ae43f9c9b8 @@ -893,7 +896,7 @@ F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5 F tool/lemon.c dfd81a51b6e27e469ba21d01a75ddf092d429027 F tool/lempar.c 01ca97f87610d1dac6d8cd96ab109ab1130e76dc F tool/mkkeywordhash.c d2e6b4a5965e23afb80fbe74bb54648cd371f309 -F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e x +F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 F tool/mksqlite3c.tcl cf44512a48112b1ba09590548660a5a6877afdb3 F tool/mksqlite3h.tcl d76c226a5e8e1f3b5f6593bcabe5e98b3b1ec9ff @@ -918,7 +921,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 94fd5bb6da5ef4d850c2ed4ad38afabc5569dae6 -R eb9573de7a3fa964ba524a7a8e9a976a -U dan -Z f742ca024227ec41f9ba4edac43a23a5 +P e73e9082f3b14088752717193a10dd7657deb8af +R 150a0d4d8ebf26c7dc0eae89afa852c9 +U drh +Z f580a5a873ab613c2a5bfc6ce81e4e03 +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v1.4.6 (GNU/Linux) + +iD8DBQFNg3aeoxKgR168RlERAnluAJ9mJTScCzmLzWj8hzyPNreCvcU53ACcDZ+U +AOCmfmp9NGd52IWhvYcR1co= +=4fKC +-----END PGP SIGNATURE----- diff --git a/manifest.uuid b/manifest.uuid index d587d908a1..8974aa69db 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e73e9082f3b14088752717193a10dd7657deb8af \ No newline at end of file +bd94f4c8b1c4590c437030f0122015f1a37e2582 \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 97026b89fd..094c4d3a7b 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -2812,7 +2812,7 @@ UnpackedRecord *sqlite3VdbeRecordUnpack( pMem->enc = pKeyInfo->enc; pMem->db = pKeyInfo->db; pMem->flags = 0; - pMem->zMalloc = 0; + pMem->zMalloc = pMem->z = 0; d += sqlite3VdbeSerialGet(&aKey[d], serial_type, pMem); pMem++; u++; @@ -3219,7 +3219,6 @@ void sqlite3VdbePreUpdateHook( for(i=0; inField; i++){ sqlite3VdbeMemRelease(&preupdate.aNew[i]); } - sqlite3_free(preupdate.aNew); + sqlite3DbFree(db, preupdate.aNew); } } - diff --git a/test/progress.test b/test/progress.test old mode 100755 new mode 100644 diff --git a/tool/mkopts.tcl b/tool/mkopts.tcl old mode 100755 new mode 100644 From 2635a3be20c3800ebea63b6f04c3d377d2caff2c Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 18 Mar 2011 16:13:53 +0000 Subject: [PATCH 0014/1484] Further improvements to documentation in sqlite3session.h. FossilOrigin-Name: 07019bb9e8d8f2445d1e0342f74ab520e9804cb5 --- ext/session/sqlite3session.h | 163 +++++++++++++++++++++++++++++++---- install-sh | 0 manifest | 30 +++---- manifest.uuid | 2 +- test/progress.test | 0 tool/mkopts.tcl | 0 6 files changed, 159 insertions(+), 36 deletions(-) mode change 100755 => 100644 install-sh mode change 100644 => 100755 test/progress.test mode change 100644 => 100755 tool/mkopts.tcl diff --git a/ext/session/sqlite3session.h b/ext/session/sqlite3session.h index 9cf7cda488..dd0e114f73 100644 --- a/ext/session/sqlite3session.h +++ b/ext/session/sqlite3session.h @@ -375,7 +375,24 @@ int sqlite3changeset_conflict( int sqlite3changeset_finalize(sqlite3_changeset_iter *pIter); /* -** Invert a changeset object. +** This function is used to "invert" a changeset object. Applying an inverted +** changeset to a database reverses the effects of applying the uninverted +** changeset. Specifically: +** +**
    +**
  • Each DELETE change is changed to an INSERT, and +**
  • Each INSERT change is changed to a DELETE, and +**
  • For each UPDATE change, the old.* and new.* values are exchanged. +**
+** +** If successful, a pointer to a buffer containing the inverted changeset +** is stored in *ppOut, the size of the same buffer is stored in *pnOut, and +** SQLITE_OK is returned. If an error occurs, both *pnOut and *ppOut are +** zeroed and an SQLite error code returned. +** +** It is the responsibility of the caller to eventually call sqlite3_free() +** on the *ppOut pointer to free the buffer allocation following a successful +** call to this function. */ int sqlite3changeset_invert( int nIn, void *pIn, /* Input changeset */ @@ -383,12 +400,124 @@ int sqlite3changeset_invert( ); /* -** Apply a changeset to a database. +** Apply a changeset to a database. This function attempts to update the +** "main" database attached to handle db with the changes found in the +** changeset passed via the second and third arguments. +** +** For each change in the changeset, this function tests that the target +** database contains a compatible table. A table is considered compatible +** if all of the following are true: +** +**
    +**
  • The table has the same name as the name recorded in the +** changeset, and +**
  • The table has the same number of columns as recorded in the +** changeset, and +**
  • The table has primary key columns in the same position as +** recorded in the changeset. +**
+** +** If there is no compatible table, it is not an error, but the change is +** not applied. A warning message is issued via the sqlite3_log() mechanism +** with the error code SQLITE_SCHEMA. At most one such warning is issued for +** each table in the changeset. +** +** Otherwise, if there is a compatible table, an attempt is made to modify +** the table contents according to the UPDATE, INSERT or DELETE change. +** If a change cannot be applied cleanly, the conflict handler function +** passed as the fourth argument to sqlite3changeset_apply() may be invoked. +** A description of exactly when the conflict handler is invoked for each +** type of change is below. +** +** Each time the conflict handler function is invoked, it must return one +** of [SQLITE_CHANGESET_OMIT], [SQLITE_CHANGESET_ABORT] or +** [SQLITE_CHANGESET_REPLACE]. SQLITE_CHANGESET_REPLACE may only be returned +** if the second argument passed to the conflict handler is either +** SQLITE_CHANGESET_DATA or SQLITE_CHANGESET_CONFLICT. If the conflict-handler +** returns an illegal value, any changes already made are rolled back and +** the call to sqlite3changeset_apply() returns SQLITE_MISUSE. Different +** actions are taken by sqlite3changeset_apply() depending on the value +** returned by each invocation of the conflict-handler function. Refer to +** the documentation for the three +** [SQLITE_CHANGESET_OMIT|available return values] for details. +** +**
+**
DELETE Changes
+** For each DELETE change, this function checks if the target database +** contains a row with the same primary key value (or values) as the +** original row values stored in the changeset. If it does, and the values +** stored in all non-primary key columns also match the values stored in +** the changeset the row is deleted from the target database. +** +** If a row with matching primary key values is found, but one or more of +** the non-primary key fields contains a value different from the original +** row value stored in the changeset, the conflict-handler function is +** invoked with [SQLITE_CHANGESET_DATA] as the second argument. +** +** If no row with matching primary key values is found in the database, +** the conflict-handler function is invoked with [SQLITE_CHANGESET_NOTFOUND] +** passed as the second argument. +** +** If the DELETE operation is attempted, but SQLite returns SQLITE_CONSTRAINT +** (which can only happen if a foreign key constraint is violated), the +** conflict-handler function is invoked with [SQLITE_CHANGESET_CONSTRAINT] +** passed as the second argument. This includes the case where the DELETE +** operation is attempted because an earlier call to the conflict handler +** function returned [SQLITE_CHANGESET_REPLACE]. +** +**
INSERT Changes
+** For each INSERT change, an attempt is made to insert the new row into +** the database. +** +** If the attempt to insert the row fails because the database already +** contains a row with the same primary key values, the conflict handler +** function is invoked with the second argument set to +** [SQLITE_CHANGESET_CONFLICT]. +** +** If the attempt to insert the row fails because of some other constraint +** violation (e.g. NOT NULL or UNIQUE), the conflict handler function is +** invoked with the second argument set to [SQLITE_CHANGESET_CONSTRAINT]. +** This includes the case where the INSERT operation is re-attempted because +** an earlier call to the conflict handler function returned +** [SQLITE_CHANGESET_REPLACE]. +** +**
UPDATE Changes
+** For each DELETE change, this function checks if the target database +** contains a row with the same primary key value (or values) as the +** original row values stored in the changeset. If it does, and the values +** stored in all non-primary key columns also match the values stored in +** the changeset the row is updated within the target database. +** +** If a row with matching primary key values is found, but one or more of +** the non-primary key fields contains a value different from an original +** row value stored in the changeset, the conflict-handler function is +** invoked with [SQLITE_CHANGESET_DATA] as the second argument. Since +** UPDATE changes only contain values for non-primary key fields that are +** to be modified, only those fields need to match the original values to +** avoid the SQLITE_CHANGESET_DATA conflict-handler callback. +** +** If no row with matching primary key values is found in the database, +** the conflict-handler function is invoked with [SQLITE_CHANGESET_NOTFOUND] +** passed as the second argument. +** +** If the UPDATE operation is attempted, but SQLite returns +** SQLITE_CONSTRAINT, the conflict-handler function is invoked with +** [SQLITE_CHANGESET_CONSTRAINT] passed as the second argument. +** This includes the case where the UPDATE operation is attempted after +** an earlier call to the conflict handler function returned +** [SQLITE_CHANGESET_REPLACE]. +**
** ** It is safe to execute SQL statements, including those that write to the ** table that the callback related to, from within the xConflict callback. ** This can be used to further customize the applications conflict ** resolution strategy. +** +** All changes made by this function are enclosed in a savepoint transaction. +** If any other error (aside from a constraint failure when attempting to +** write to the target database) occurs, then the savepoint transaction is +** rolled back, restoring the target database to its original state, and an +** SQLite error code returned. */ int sqlite3changeset_apply( sqlite3 *db, /* Apply change to "main" db of this handle */ @@ -403,9 +532,10 @@ int sqlite3changeset_apply( ); /* -** Values passed as the second argument to a conflict-handler. +** Values that may be passed as the second argument to a conflict-handler. ** -** SQLITE_CHANGESET_DATA: +**
+**
SQLITE_CHANGESET_DATA
** The conflict handler is invoked with CHANGESET_DATA as the second argument ** when processing a DELETE or UPDATE change if a row with the required ** PRIMARY KEY fields is present in the database, but one or more other @@ -415,7 +545,7 @@ int sqlite3changeset_apply( ** The conflicting row, in this case, is the database row with the matching ** primary key. ** -** SQLITE_CHANGESET_NOTFOUND: +**
SQLITE_CHANGESET_NOTFOUND
** The conflict handler is invoked with CHANGESET_NOTFOUND as the second ** argument when processing a DELETE or UPDATE change if a row with the ** required PRIMARY KEY fields is not present in the database. @@ -423,21 +553,22 @@ int sqlite3changeset_apply( ** There is no conflicting row in this case. The results of invoking the ** sqlite3changeset_conflict() API are undefined. ** -** SQLITE_CHANGESET_CONFLICT: +**
SQLITE_CHANGESET_CONFLICT
** CHANGESET_CONFLICT is passed as the second argument to the conflict -** handler while processing an UPDATE or an INSERT if the operation would -** result in duplicate primary key values. +** handler while processing an INSERT change if the operation would result +** in duplicate primary key values. ** ** The conflicting row in this case is the database row with the matching ** primary key. ** -** SQLITE_CHANGESET_CONSTRAINT: +**
SQLITE_CHANGESET_CONSTRAINT
** If any other constraint violation occurs while applying a change (i.e. ** a FOREIGN KEY, UNIQUE, CHECK or NOT NULL constraint), the conflict ** handler is invoked with CHANGESET_CONSTRAINT as the second argument. ** ** There is no conflicting row in this case. The results of invoking the ** sqlite3changeset_conflict() API are undefined. +**
*/ #define SQLITE_CHANGESET_DATA 1 #define SQLITE_CHANGESET_NOTFOUND 2 @@ -447,12 +578,13 @@ int sqlite3changeset_apply( /* ** Valid return values from a conflict-handler. ** -** SQLITE_CHANGESET_OMIT: +**
+**
SQLITE_CHANGESET_OMIT
** If a conflict handler returns this value no special action is taken. The -** change is not applied. The session module continues to the next change -** in the changeset. +** change that caused the conflict is not applied. The session module +** continues to the next change in the changeset. ** -** SQLITE_CHANGESET_REPLACE: +**
SQLITE_CHANGESET_REPLACE
** This value may only be returned if the second argument to the conflict ** handler was SQLITE_CHANGESET_DATA or SQLITE_CHANGESET_CONFLICT. If this ** is not the case, any changes applied so far are rolled back and the @@ -467,9 +599,10 @@ int sqlite3changeset_apply( ** second attempt to apply the change is made. If this second attempt fails, ** the original row is restored to the database before continuing. ** -** SQLITE_CHANGESET_ABORT: +**
SQLITE_CHANGESET_ABORT
** If this value is returned, any changes applied so far are rolled back -** and the call to sqlite3changeset_apply() returns SQLITE_MISUSE. +** and the call to sqlite3changeset_apply() returns SQLITE_ABORT. +**
*/ #define SQLITE_CHANGESET_OMIT 0 #define SQLITE_CHANGESET_REPLACE 1 diff --git a/install-sh b/install-sh old mode 100755 new mode 100644 diff --git a/manifest b/manifest index 47e7037226..f680f79bca 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,5 @@ ------BEGIN PGP SIGNED MESSAGE----- -Hash: SHA1 - -C Fix\sa\smemory\sallocation\sissues\sin\sthe\spreupdate\shook\sso\sthat\sthe\shook.test\nscript\sruns\sclean\sin\svalgrind. -D 2011-03-18T15:13:31.545 +C Further\simprovements\sto\sdocumentation\sin\ssqlite3session.h. +D 2011-03-18T16:13:53 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -103,9 +100,9 @@ F ext/rtree/sqlite3rtree.h 1af0899c63a688e272d69d8e746f24e76f10a3f0 F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 F ext/session/sqlite3session.c 4183792547af5b5d3ec1c8a3f858beb172682503 -F ext/session/sqlite3session.h 3e342facbb95589dfba34545df383df68cc44ebf +F ext/session/sqlite3session.h 9551c002efd5fde07c52994c6b592308e0df2d6a F ext/session/test_session.c 2559ef68e421c7fb83e2c19ef08a17343b70d535 -F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x +F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F main.mk ae0868e05c76eaa8a0ae3d6927a949b1c8e810d7 F mkdll.sh 7d09b23c05d56532e9d44a50868eb4b12ff4f74a @@ -608,7 +605,7 @@ F test/permutations.test 5b2a4cb756ffb2407cb4743163668d1d769febb6 F test/pragma.test fdfc09067ea104a0c247a1a79d8093b56656f850 F test/pragma2.test 5364893491b9231dd170e3459bfc2e2342658b47 F test/printf.test 05970cde31b1a9f54bd75af60597be75a5c54fea -F test/progress.test 5b075c3c790c7b2a61419bc199db87aaf48b8301 +F test/progress.test 5b075c3c790c7b2a61419bc199db87aaf48b8301 x F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc F test/quick.test 1681febc928d686362d50057c642f77a02c62e57 F test/quota.test ddafe133653093eb9a99ccd6264884ae43f9c9b8 @@ -896,7 +893,7 @@ F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5 F tool/lemon.c dfd81a51b6e27e469ba21d01a75ddf092d429027 F tool/lempar.c 01ca97f87610d1dac6d8cd96ab109ab1130e76dc F tool/mkkeywordhash.c d2e6b4a5965e23afb80fbe74bb54648cd371f309 -F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e +F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e x F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 F tool/mksqlite3c.tcl cf44512a48112b1ba09590548660a5a6877afdb3 F tool/mksqlite3h.tcl d76c226a5e8e1f3b5f6593bcabe5e98b3b1ec9ff @@ -921,14 +918,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P e73e9082f3b14088752717193a10dd7657deb8af -R 150a0d4d8ebf26c7dc0eae89afa852c9 -U drh -Z f580a5a873ab613c2a5bfc6ce81e4e03 ------BEGIN PGP SIGNATURE----- -Version: GnuPG v1.4.6 (GNU/Linux) - -iD8DBQFNg3aeoxKgR168RlERAnluAJ9mJTScCzmLzWj8hzyPNreCvcU53ACcDZ+U -AOCmfmp9NGd52IWhvYcR1co= -=4fKC ------END PGP SIGNATURE----- +P bd94f4c8b1c4590c437030f0122015f1a37e2582 +R fb83d41281a4d5ba8505f15c6f6b6372 +U dan +Z ff00d37e3af9047c8539a141cf64a629 diff --git a/manifest.uuid b/manifest.uuid index 8974aa69db..c2dbebadb1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bd94f4c8b1c4590c437030f0122015f1a37e2582 \ No newline at end of file +07019bb9e8d8f2445d1e0342f74ab520e9804cb5 \ No newline at end of file diff --git a/test/progress.test b/test/progress.test old mode 100644 new mode 100755 diff --git a/tool/mkopts.tcl b/tool/mkopts.tcl old mode 100644 new mode 100755 From 304637c026622adf6354f295e7c298ad7c04ae68 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 18 Mar 2011 16:47:27 +0000 Subject: [PATCH 0015/1484] Fixes for compiler warnings. Minor code cleanup. FossilOrigin-Name: 9604d13001e0a195718c7f03fc0e73e352226caa --- install-sh | 0 manifest | 36 +++++++++++++++++++++++------------- manifest.uuid | 2 +- src/sqliteInt.h | 1 - src/tclsqlite.c | 34 +++++++++++++++++++--------------- src/vdbeapi.c | 3 +-- src/vdbeaux.c | 5 +++-- test/progress.test | 0 tool/mkopts.tcl | 0 9 files changed, 47 insertions(+), 34 deletions(-) mode change 100644 => 100755 install-sh mode change 100755 => 100644 test/progress.test mode change 100755 => 100644 tool/mkopts.tcl diff --git a/install-sh b/install-sh old mode 100644 new mode 100755 diff --git a/manifest b/manifest index f680f79bca..ad7e4b5e21 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,8 @@ -C Further\simprovements\sto\sdocumentation\sin\ssqlite3session.h. -D 2011-03-18T16:13:53 +-----BEGIN PGP SIGNED MESSAGE----- +Hash: SHA1 + +C Fixes\sfor\scompiler\swarnings.\s\sMinor\scode\scleanup. +D 2011-03-18T16:47:27.202 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -102,7 +105,7 @@ F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 F ext/session/sqlite3session.c 4183792547af5b5d3ec1c8a3f858beb172682503 F ext/session/sqlite3session.h 9551c002efd5fde07c52994c6b592308e0df2d6a F ext/session/test_session.c 2559ef68e421c7fb83e2c19ef08a17343b70d535 -F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 +F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F main.mk ae0868e05c76eaa8a0ae3d6927a949b1c8e810d7 F mkdll.sh 7d09b23c05d56532e9d44a50868eb4b12ff4f74a @@ -183,11 +186,11 @@ F src/select.c d24406c45dd2442eb2eeaac413439066b149c944 F src/shell.c 4a5e0ad845475c84881f0b25b1abba2ddaab0a72 F src/sqlite.h.in 208dc372c9b8d89ca962babcb7cb0c1b16d32bc4 F src/sqlite3ext.h c90bd5507099f62043832d73f6425d8d5c5da754 -F src/sqliteInt.h d65b832eb82bd3f04cd27a750698c7f4b3d9273a +F src/sqliteInt.h e427f9cff8fcf85ea23f95eb8b70e4b588d24212 F src/sqliteLimit.h a17dcd3fb775d63b64a43a55c54cb282f9726f44 F src/status.c 4997380fbb915426fef9e500b4872e79c99267fc F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e -F src/tclsqlite.c fc0321c62a3c3929b9b0659b94b7d37bac84e769 +F src/tclsqlite.c 520e124994e68fd8804ade95b5d3e2e791d0958d F src/test1.c 9020310c7617234b33fd1c3064f89524db25f290 F src/test2.c 80d323d11e909cf0eb1b6fbb4ac22276483bcf31 F src/test3.c 056093cfef69ff4227a6bdb9108564dc7f45e4bc @@ -237,8 +240,8 @@ F src/vacuum.c 924bd1bcee2dfb05376f79845bd3b4cec7b54b2f F src/vdbe.c 94cd191b1b20b0124e09b056bbce3d09f79821b3 F src/vdbe.h 4de0efb4b0fdaaa900cf419b35c458933ef1c6d2 F src/vdbeInt.h 20d13da932eed0667a2e2383a9cb0f80099a5fd3 -F src/vdbeapi.c 988ee9420acf8c130d644e6d7282893efe927bbd -F src/vdbeaux.c bb194e1250a0e35e3a5e17e51631da858e23930a +F src/vdbeapi.c 0e53620e9a4889257eece201d517163d3093ee41 +F src/vdbeaux.c 9807ae2e6974172b1d7b077327f862f6bd4dda2a F src/vdbeblob.c 18955f0ee6b133cd08e1592010cb9a6b11e9984c F src/vdbemem.c 0498796b6ffbe45e32960d6a1f5adfb6e419883b F src/vdbetrace.c 3ba13bc32bdf16d2bdea523245fd16736bed67b5 @@ -605,7 +608,7 @@ F test/permutations.test 5b2a4cb756ffb2407cb4743163668d1d769febb6 F test/pragma.test fdfc09067ea104a0c247a1a79d8093b56656f850 F test/pragma2.test 5364893491b9231dd170e3459bfc2e2342658b47 F test/printf.test 05970cde31b1a9f54bd75af60597be75a5c54fea -F test/progress.test 5b075c3c790c7b2a61419bc199db87aaf48b8301 x +F test/progress.test 5b075c3c790c7b2a61419bc199db87aaf48b8301 F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc F test/quick.test 1681febc928d686362d50057c642f77a02c62e57 F test/quota.test ddafe133653093eb9a99ccd6264884ae43f9c9b8 @@ -893,7 +896,7 @@ F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5 F tool/lemon.c dfd81a51b6e27e469ba21d01a75ddf092d429027 F tool/lempar.c 01ca97f87610d1dac6d8cd96ab109ab1130e76dc F tool/mkkeywordhash.c d2e6b4a5965e23afb80fbe74bb54648cd371f309 -F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e x +F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 F tool/mksqlite3c.tcl cf44512a48112b1ba09590548660a5a6877afdb3 F tool/mksqlite3h.tcl d76c226a5e8e1f3b5f6593bcabe5e98b3b1ec9ff @@ -918,7 +921,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P bd94f4c8b1c4590c437030f0122015f1a37e2582 -R fb83d41281a4d5ba8505f15c6f6b6372 -U dan -Z ff00d37e3af9047c8539a141cf64a629 +P 07019bb9e8d8f2445d1e0342f74ab520e9804cb5 +R e362c18925cab750a71fcf91528dddfb +U drh +Z 33df56341351167813c56b1a83010bf4 +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v1.4.6 (GNU/Linux) + +iD8DBQFNg4yioxKgR168RlERAsv6AJ9WZ1HLGm+YuNBznpVVZgVxxs49RwCdFrGC +OY796dAcZJ0MQ5I3+TprmmI= +=87W+ +-----END PGP SIGNATURE----- diff --git a/manifest.uuid b/manifest.uuid index c2dbebadb1..fe2f62ed4f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -07019bb9e8d8f2445d1e0342f74ab520e9804cb5 \ No newline at end of file +9604d13001e0a195718c7f03fc0e73e352226caa \ No newline at end of file diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 9fa4161d2e..cf35f54635 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2748,7 +2748,6 @@ void sqlite3PrngSaveState(void); void sqlite3PrngRestoreState(void); void sqlite3PrngResetState(void); void sqlite3RollbackAll(sqlite3*); -void sqlite3TransactionHook(sqlite3 *, int, int); void sqlite3CodeVerifySchema(Parse*, int); void sqlite3BeginTransaction(Parse*, int); void sqlite3CommitTransaction(Parse*); diff --git a/src/tclsqlite.c b/src/tclsqlite.c index b3f98126c0..092295a2d1 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -1655,12 +1655,12 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ "errorcode", "eval", "exists", "function", "incrblob", "interrupt", "last_insert_rowid", "nullvalue", "onecolumn", - "preupdate", - "profile", "progress", "rekey", - "restore", "rollback_hook", "status", - "timeout", "total_changes", "trace", - "transaction", "unlock_notify", "update_hook", - "version", "wal_hook", 0 + "preupdate", "profile", "progress", + "rekey", "restore", "rollback_hook", + "status", "timeout", "total_changes", + "trace", "transaction", "unlock_notify", + "update_hook", "version", "wal_hook", + 0 }; enum DB_enum { DB_AUTHORIZER, DB_BACKUP, DB_BUSY, @@ -1670,12 +1670,11 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ DB_ERRORCODE, DB_EVAL, DB_EXISTS, DB_FUNCTION, DB_INCRBLOB, DB_INTERRUPT, DB_LAST_INSERT_ROWID, DB_NULLVALUE, DB_ONECOLUMN, - DB_PREUPDATE, - DB_PROFILE, DB_PROGRESS, DB_REKEY, - DB_RESTORE, DB_ROLLBACK_HOOK, DB_STATUS, - DB_TIMEOUT, DB_TOTAL_CHANGES, DB_TRACE, - DB_TRANSACTION, DB_UNLOCK_NOTIFY, DB_UPDATE_HOOK, - DB_VERSION, DB_WAL_HOOK + DB_PREUPDATE, DB_PROFILE, DB_PROGRESS, + DB_REKEY, DB_RESTORE, DB_ROLLBACK_HOOK, + DB_STATUS, DB_TIMEOUT, DB_TOTAL_CHANGES, + DB_TRACE, DB_TRANSACTION, DB_UNLOCK_NOTIFY, + DB_UPDATE_HOOK, DB_VERSION, DB_WAL_HOOK, }; /* don't leave trailing commas on DB_enum, it confuses the AIX xlc compiler */ @@ -2845,6 +2844,12 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ break; } + /* + ** $db preupdate_hook count + ** $db preupdate_hook hook ?SCRIPT? + ** $db preupdate_hook new INDEX + ** $db preupdate_hook old INDEX + */ case DB_PREUPDATE: { static const char *azSub[] = {"count", "hook", "new", "old", 0}; enum DbPreupdateSubCmd { @@ -2895,7 +2900,8 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ } if( rc==SQLITE_OK ){ - Tcl_Obj *pObj = Tcl_NewStringObj(sqlite3_value_text(pValue), -1); + Tcl_Obj *pObj; + pObj = Tcl_NewStringObj((char*)sqlite3_value_text(pValue), -1); Tcl_SetObjResult(interp, pObj); }else{ Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), 0); @@ -2915,8 +2921,6 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ case DB_WAL_HOOK: case DB_UPDATE_HOOK: case DB_ROLLBACK_HOOK: { - sqlite3 *db = pDb->db; - /* set ppHook to point at pUpdateHook or pRollbackHook, depending on ** whether [$db update_hook] or [$db rollback_hook] was invoked. */ diff --git a/src/vdbeapi.c b/src/vdbeapi.c index 64cd2191c8..4fde5893b6 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -1439,6 +1439,7 @@ int sqlite3_preupdate_new(sqlite3 *db, int iIdx, sqlite3_value **ppValue){ goto preupdate_new_out; } } + assert( iIdx>=0 && iIdxpCsr->nField ); pMem = &p->aNew[iIdx]; if( pMem->flags==0 ){ rc = sqlite3VdbeMemCopy(pMem, &p->v->aMem[p->iNewReg+1+iIdx]); @@ -1452,5 +1453,3 @@ int sqlite3_preupdate_new(sqlite3 *db, int iIdx, sqlite3_value **ppValue){ sqlite3Error(db, rc, 0); return sqlite3ApiExit(db, rc); } - - diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 094c4d3a7b..368330720d 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -2813,6 +2813,7 @@ UnpackedRecord *sqlite3VdbeRecordUnpack( pMem->db = pKeyInfo->db; pMem->flags = 0; pMem->zMalloc = pMem->z = 0; + pMem->z = 0; d += sqlite3VdbeSerialGet(&aKey[d], serial_type, pMem); pMem++; u++; @@ -3187,10 +3188,10 @@ void sqlite3VdbePreUpdateHook( ){ sqlite3 *db = v->db; i64 iKey2; - PreUpdate preupdate; - memset(&preupdate, 0, sizeof(PreUpdate)); + assert( db->pPreUpdate==0 ); + memset(&preupdate, 0, sizeof(PreUpdate)); if( op==SQLITE_UPDATE ){ iKey2 = v->aMem[iReg].u.i; }else{ diff --git a/test/progress.test b/test/progress.test old mode 100755 new mode 100644 diff --git a/tool/mkopts.tcl b/tool/mkopts.tcl old mode 100755 new mode 100644 From 4c22025225fdef09f13b27fd5d364cd612136066 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 18 Mar 2011 18:03:13 +0000 Subject: [PATCH 0016/1484] Hold the database mutex for the duration of an sqlite3changeset_apply() call. Also for the duration of all sqlite3session_xxx() calls. FossilOrigin-Name: c615c38c3283e21c33550c093099a793761123a7 --- ext/session/sqlite3session.c | 50 ++++++++++++++++++++++++------------ install-sh | 0 manifest | 30 ++++++++-------------- manifest.uuid | 2 +- test/progress.test | 0 tool/mkopts.tcl | 0 6 files changed, 45 insertions(+), 37 deletions(-) mode change 100755 => 100644 install-sh mode change 100644 => 100755 test/progress.test mode change 100644 => 100755 tool/mkopts.tcl diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index 296875052e..64114718de 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -752,7 +752,9 @@ static void xPreUpdate( sqlite3_session *pSession; int nDb = strlen(zDb); int nName = strlen(zDb); - + + assert( sqlite3_mutex_held(db->mutex) ); + for(pSession=(sqlite3_session *)pCtx; pSession; pSession=pSession->pNext){ SessionTable *pTab; @@ -866,28 +868,34 @@ int sqlite3session_attach( ){ SessionTable *pTab; /* New table object (if required) */ int nName; /* Number of bytes in string zName */ + int rc = SQLITE_OK; + + sqlite3_mutex_enter(sqlite3_db_mutex(pSession->db)); /* First search for an existing entry. If one is found, this call is ** a no-op. Return early. */ nName = strlen(zName); for(pTab=pSession->pTable; pTab; pTab=pTab->pNext){ - if( 0==sqlite3_strnicmp(pTab->zName, zName, nName+1) ){ - return SQLITE_OK; + if( 0==sqlite3_strnicmp(pTab->zName, zName, nName+1) ) break; + } + + if( !pTab ){ + /* Allocate new SessionTable object. */ + pTab = (SessionTable *)sqlite3_malloc(sizeof(SessionTable) + nName + 1); + if( !pTab ){ + rc = SQLITE_NOMEM; + }else{ + /* Populate the new SessionTable object and link it into the list. */ + memset(pTab, 0, sizeof(SessionTable)); + pTab->zName = (char *)&pTab[1]; + memcpy(pTab->zName, zName, nName+1); + pTab->pNext = pSession->pTable; + pSession->pTable = pTab; } } - /* Allocate new SessionTable object. */ - pTab = (SessionTable *)sqlite3_malloc(sizeof(SessionTable) + nName + 1); - if( !pTab ) return SQLITE_NOMEM; - - /* Populate the new SessionTable object and link it into the list. */ - memset(pTab, 0, sizeof(SessionTable)); - pTab->zName = (char *)&pTab[1]; - memcpy(pTab->zName, zName, nName+1); - pTab->pNext = pSession->pTable; - pSession->pTable = pTab; - - return SQLITE_OK; + sqlite3_mutex_leave(sqlite3_db_mutex(pSession->db)); + return rc; } /* @@ -1285,6 +1293,8 @@ int sqlite3session_changeset( SessionBuffer buf = {0,0,0}; /* Buffer in which to accumlate changeset */ int rc; /* Return code */ + sqlite3_mutex_enter(sqlite3_db_mutex(db)); + /* Zero the output variables in case an error occurs. If this session ** object is already in the error state (sqlite3_session.rc != SQLITE_OK), ** this call will be a no-op. */ @@ -1357,6 +1367,8 @@ int sqlite3session_changeset( }else{ sqlite3_free(buf.aBuf); } + + sqlite3_mutex_leave(sqlite3_db_mutex(db)); return rc; } @@ -1364,10 +1376,14 @@ int sqlite3session_changeset( ** Enable or disable the session object passed as the first argument. */ int sqlite3session_enable(sqlite3_session *pSession, int bEnable){ + int ret; + sqlite3_mutex_enter(sqlite3_db_mutex(pSession->db)); if( bEnable>=0 ){ pSession->bEnable = bEnable; } - return pSession->bEnable; + ret = pSession->bEnable; + sqlite3_mutex_leave(sqlite3_db_mutex(pSession->db)); + return ret; } /* @@ -2277,6 +2293,7 @@ int sqlite3changeset_apply( memset(&sApply, 0, sizeof(sApply)); sqlite3changeset_start(&pIter, nChangeset, pChangeset); + sqlite3_mutex_enter(sqlite3_db_mutex(db)); rc = sqlite3_exec(db, "SAVEPOINT changeset_apply", 0, 0, 0); while( rc==SQLITE_OK && SQLITE_ROW==sqlite3changeset_next(pIter) ){ int nCol; @@ -2366,6 +2383,7 @@ int sqlite3changeset_apply( sqlite3_finalize(sApply.pUpdate); sqlite3_finalize(sApply.pSelect); sqlite3_free(sApply.azCol); + sqlite3_mutex_leave(sqlite3_db_mutex(db)); return rc; } diff --git a/install-sh b/install-sh old mode 100755 new mode 100644 diff --git a/manifest b/manifest index ad7e4b5e21..0bcad83403 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,5 @@ ------BEGIN PGP SIGNED MESSAGE----- -Hash: SHA1 - -C Fixes\sfor\scompiler\swarnings.\s\sMinor\scode\scleanup. -D 2011-03-18T16:47:27.202 +C Hold\sthe\sdatabase\smutex\sfor\sthe\sduration\sof\san\ssqlite3changeset_apply()\scall.\sAlso\sfor\sthe\sduration\sof\sall\ssqlite3session_xxx()\scalls. +D 2011-03-18T18:03:14 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -102,10 +99,10 @@ F ext/rtree/rtree_util.tcl 06aab2ed5b826545bf215fff90ecb9255a8647ea F ext/rtree/sqlite3rtree.h 1af0899c63a688e272d69d8e746f24e76f10a3f0 F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 -F ext/session/sqlite3session.c 4183792547af5b5d3ec1c8a3f858beb172682503 +F ext/session/sqlite3session.c d4ba709d457a7b184a72ccd3ab07e5a1e9dd9196 F ext/session/sqlite3session.h 9551c002efd5fde07c52994c6b592308e0df2d6a F ext/session/test_session.c 2559ef68e421c7fb83e2c19ef08a17343b70d535 -F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x +F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F main.mk ae0868e05c76eaa8a0ae3d6927a949b1c8e810d7 F mkdll.sh 7d09b23c05d56532e9d44a50868eb4b12ff4f74a @@ -608,7 +605,7 @@ F test/permutations.test 5b2a4cb756ffb2407cb4743163668d1d769febb6 F test/pragma.test fdfc09067ea104a0c247a1a79d8093b56656f850 F test/pragma2.test 5364893491b9231dd170e3459bfc2e2342658b47 F test/printf.test 05970cde31b1a9f54bd75af60597be75a5c54fea -F test/progress.test 5b075c3c790c7b2a61419bc199db87aaf48b8301 +F test/progress.test 5b075c3c790c7b2a61419bc199db87aaf48b8301 x F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc F test/quick.test 1681febc928d686362d50057c642f77a02c62e57 F test/quota.test ddafe133653093eb9a99ccd6264884ae43f9c9b8 @@ -896,7 +893,7 @@ F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5 F tool/lemon.c dfd81a51b6e27e469ba21d01a75ddf092d429027 F tool/lempar.c 01ca97f87610d1dac6d8cd96ab109ab1130e76dc F tool/mkkeywordhash.c d2e6b4a5965e23afb80fbe74bb54648cd371f309 -F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e +F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e x F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 F tool/mksqlite3c.tcl cf44512a48112b1ba09590548660a5a6877afdb3 F tool/mksqlite3h.tcl d76c226a5e8e1f3b5f6593bcabe5e98b3b1ec9ff @@ -921,14 +918,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 07019bb9e8d8f2445d1e0342f74ab520e9804cb5 -R e362c18925cab750a71fcf91528dddfb -U drh -Z 33df56341351167813c56b1a83010bf4 ------BEGIN PGP SIGNATURE----- -Version: GnuPG v1.4.6 (GNU/Linux) - -iD8DBQFNg4yioxKgR168RlERAsv6AJ9WZ1HLGm+YuNBznpVVZgVxxs49RwCdFrGC -OY796dAcZJ0MQ5I3+TprmmI= -=87W+ ------END PGP SIGNATURE----- +P 9604d13001e0a195718c7f03fc0e73e352226caa +R 54e501f64ecb85ba88c3d3201e5dcd9b +U dan +Z 255e99dc78fad5aee707e21b8ff77ea9 diff --git a/manifest.uuid b/manifest.uuid index fe2f62ed4f..235b1b6cb5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9604d13001e0a195718c7f03fc0e73e352226caa \ No newline at end of file +c615c38c3283e21c33550c093099a793761123a7 \ No newline at end of file diff --git a/test/progress.test b/test/progress.test old mode 100644 new mode 100755 diff --git a/tool/mkopts.tcl b/tool/mkopts.tcl old mode 100644 new mode 100755 From 319eeb7b33eb9380924475f799ec66773c7ea953 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 19 Mar 2011 08:38:50 +0000 Subject: [PATCH 0017/1484] Fix a problem with INTEGER PRIMARY KEY columns and the pre-update hook. FossilOrigin-Name: 24d4d5dd007197a141555bcca6f2ac9ab47cde80 --- install-sh | 0 manifest | 46 ++++++++++++++++++---------------------------- manifest.uuid | 2 +- src/delete.c | 2 +- src/insert.c | 6 +++--- src/update.c | 2 +- src/vdbe.c | 40 +++++++++++++++++++++------------------- src/vdbe.h | 2 ++ src/vdbeInt.h | 5 ++++- src/vdbeapi.c | 14 ++++++++++++-- src/vdbeaux.c | 7 ++++++- test/hook.test | 17 ++++++++++++++++- test/progress.test | 0 tool/mkopts.tcl | 0 14 files changed, 85 insertions(+), 58 deletions(-) mode change 100755 => 100644 install-sh mode change 100644 => 100755 test/progress.test mode change 100644 => 100755 tool/mkopts.tcl diff --git a/install-sh b/install-sh old mode 100755 new mode 100644 diff --git a/manifest b/manifest index a02bffa46b..fffd7c5851 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,5 @@ ------BEGIN PGP SIGNED MESSAGE----- -Hash: SHA1 - -C Merge\sthe\sfix\sto\sticket\s[f7b4edece25c99485]\sinto\sthe\ssessions\sbranch. -D 2011-03-19T02:37:38.712 +C Fix\sa\sproblem\swith\sINTEGER\sPRIMARY\sKEY\scolumns\sand\sthe\spre-update\shook. +D 2011-03-19T08:38:50 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -105,7 +102,7 @@ F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 F ext/session/sqlite3session.c d4ba709d457a7b184a72ccd3ab07e5a1e9dd9196 F ext/session/sqlite3session.h 9551c002efd5fde07c52994c6b592308e0df2d6a F ext/session/test_session.c 2559ef68e421c7fb83e2c19ef08a17343b70d535 -F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x +F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F main.mk ae0868e05c76eaa8a0ae3d6927a949b1c8e810d7 F mkdll.sh 7d09b23c05d56532e9d44a50868eb4b12ff4f74a @@ -135,7 +132,7 @@ F src/callback.c 5069f224882cbdccd559f591271d28d7f37745bc F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 52ff72f966cee3087e0138a3ec69371c22be3c01 F src/date.c 1548fdac51377e4e7833251de878b4058c148e1b -F src/delete.c 3c0925e958a77804a004222baa1a2a8ad855306b +F src/delete.c 122c1a767883c439ad6393d32920152ecb560429 F src/expr.c 00817c672af554321fd67c44325afd7cef0e4648 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 418b840007c873975fd0d071746d952f8bca20ce @@ -144,7 +141,7 @@ F src/global.c 02335177cf6946fe5525c6f0755cf181140debf3 F src/hash.c 458488dcc159c301b8e7686280ab209f1fb915af F src/hash.h 2894c932d84d9f892d4b4023a75e501f83050970 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 -F src/insert.c b0d4150ae6d6fae7c3e8b69b65bcf37988d80ac0 +F src/insert.c c46747b4bdde2ae4c2815526a151fefb66ba64a6 F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f F src/lempar.c 7f026423f4d71d989e719a743f98a1cbd4e6d99e @@ -233,15 +230,15 @@ F src/test_vfstrace.c f5c3b3b893d81a580d0f577e6d9bcfc1fd496136 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/tokenize.c 604607d6813e9551cf5189d899e0a25c12681080 F src/trigger.c 95d2ff4b2996fabe886c9764b5978980e29f4afa -F src/update.c aa39db6c39a1e234e8badf49768e1389dbb34650 +F src/update.c ca6d4ad2d87e743d22c47f1a6715cc5abf5cda05 F src/utf.c 1baeeac91707a4df97ccc6141ec0f808278af685 F src/util.c cd997077bad039efc0597eb027c929658f93c018 F src/vacuum.c 924bd1bcee2dfb05376f79845bd3b4cec7b54b2f -F src/vdbe.c 3f6d91163b5b7b3d2609bf5f21461d902989cdc5 -F src/vdbe.h 4de0efb4b0fdaaa900cf419b35c458933ef1c6d2 -F src/vdbeInt.h 20d13da932eed0667a2e2383a9cb0f80099a5fd3 -F src/vdbeapi.c 0e53620e9a4889257eece201d517163d3093ee41 -F src/vdbeaux.c 9807ae2e6974172b1d7b077327f862f6bd4dda2a +F src/vdbe.c c90edafd941481506f001b17cd8523683fdac853 +F src/vdbe.h edef9c4f0be83e1f1dccd049da37b40e021b63d9 +F src/vdbeInt.h 2cf77c1d151a4a54facd596d52be6d60c1cb26e8 +F src/vdbeapi.c c4692c74b31f4abe638fbcbae3944c52b54e2c36 +F src/vdbeaux.c 0216b2c37509a44c3833b297765bee7bdd04fa2f F src/vdbeblob.c c3ccb7c8732858c680f442932e66ad06bb036562 F src/vdbemem.c 0498796b6ffbe45e32960d6a1f5adfb6e419883b F src/vdbetrace.c 3ba13bc32bdf16d2bdea523245fd16736bed67b5 @@ -480,7 +477,7 @@ F test/fuzz2.test 207d0f9d06db3eaf47a6b7bfc835b8e2fc397167 F test/fuzz3.test aec64345184d1662bd30e6a17851ff659d596dc5 F test/fuzz_common.tcl a87dfbb88c2a6b08a38e9a070dabd129e617b45b F test/fuzz_malloc.test dd7001ac86d09c154a7dff064f4739c60e2b312c -F test/hook.test d0a277022888caf75ae1d4ec79917668f2f0f2e6 +F test/hook.test d054aad1a3772dd9045510382875468a9dcae15f F test/icu.test 70df4faca133254c042d02ae342c0a141f2663f4 F test/in.test 19b642bb134308980a92249750ea4ce3f6c75c2d F test/in2.test 5d4c61d17493c832f7d2d32bef785119e87bde75 @@ -608,7 +605,7 @@ F test/permutations.test 5b2a4cb756ffb2407cb4743163668d1d769febb6 F test/pragma.test fdfc09067ea104a0c247a1a79d8093b56656f850 F test/pragma2.test 5364893491b9231dd170e3459bfc2e2342658b47 F test/printf.test 05970cde31b1a9f54bd75af60597be75a5c54fea -F test/progress.test 5b075c3c790c7b2a61419bc199db87aaf48b8301 +F test/progress.test 5b075c3c790c7b2a61419bc199db87aaf48b8301 x F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc F test/quick.test 1681febc928d686362d50057c642f77a02c62e57 F test/quota.test ddafe133653093eb9a99ccd6264884ae43f9c9b8 @@ -897,7 +894,7 @@ F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5 F tool/lemon.c dfd81a51b6e27e469ba21d01a75ddf092d429027 F tool/lempar.c 01ca97f87610d1dac6d8cd96ab109ab1130e76dc F tool/mkkeywordhash.c d2e6b4a5965e23afb80fbe74bb54648cd371f309 -F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e +F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e x F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 F tool/mksqlite3c.tcl cf44512a48112b1ba09590548660a5a6877afdb3 F tool/mksqlite3h.tcl d76c226a5e8e1f3b5f6593bcabe5e98b3b1ec9ff @@ -922,14 +919,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P c615c38c3283e21c33550c093099a793761123a7 eedbcf0a0ba91bb8b9cd3d115081ba297e9959fe -R d0ca47f6483ae12a6d0c994e1006aea9 -U drh -Z 5fff78b74e6c376b68b45fceb2b4a735 ------BEGIN PGP SIGNATURE----- -Version: GnuPG v1.4.6 (GNU/Linux) - -iD8DBQFNhBb2oxKgR168RlERAgoXAKCNG+a12IdNjhU70FvIK6nf6CqkoQCfbtYL -k5XHY8ri1b+IAtTgBjHO+hs= -=5lEb ------END PGP SIGNATURE----- +P 1b736ac2934f2361dee5062e9033cbf26b41fc3a +R 162f72638a0f38fbe0fc1273d5b87dc2 +U dan +Z 3b532fd3ba73ffa805a9d5e7143aadc5 diff --git a/manifest.uuid b/manifest.uuid index a441a6b6ae..e62b7f494c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1b736ac2934f2361dee5062e9033cbf26b41fc3a \ No newline at end of file +24d4d5dd007197a141555bcca6f2ac9ab47cde80 \ No newline at end of file diff --git a/src/delete.c b/src/delete.c index c7a686a8bd..3075df05fc 100644 --- a/src/delete.c +++ b/src/delete.c @@ -542,7 +542,7 @@ void sqlite3GenerateRowDelete( if( pTab->pSelect==0 ){ sqlite3GenerateRowIndexDelete(pParse, pTab, iCur, 0); sqlite3VdbeAddOp2(v, OP_Delete, iCur, (count?OPFLAG_NCHANGE:0)); - sqlite3VdbeChangeP4(v, -1, pTab->zName, P4_STATIC); + sqlite3VdbeChangeP4(v, -1, pTab, P4_TABLE); } /* Do any ON CASCADE, SET NULL or SET DEFAULT operations required to diff --git a/src/insert.c b/src/insert.c index 85b19ae3f7..cf48d0ffe7 100644 --- a/src/insert.c +++ b/src/insert.c @@ -1291,7 +1291,7 @@ void sqlite3GenerateConstraintChecks( ** OP_Insert replace the existing entry than it is to delete the ** existing entry and then insert a new one. */ sqlite3VdbeAddOp2(v, OP_Delete, baseCur, OPFLAG_ISNOOP); - sqlite3VdbeChangeP4(v, -1, pTab->zName, P4_STATIC); + sqlite3VdbeChangeP4(v, -1, (char *)pTab, P4_TABLE); if( pTab->pIndex ){ sqlite3MultiWrite(pParse); sqlite3GenerateRowIndexDelete(pParse, pTab, baseCur, 0); @@ -1481,7 +1481,7 @@ void sqlite3CompleteInsertion( } sqlite3VdbeAddOp3(v, OP_Insert, baseCur, regRec, regRowid); if( !pParse->nested ){ - sqlite3VdbeChangeP4(v, -1, pTab->zName, P4_STATIC); + sqlite3VdbeChangeP4(v, -1, (char *)pTab, P4_TABLE); } sqlite3VdbeChangeP5(v, pik_flags); } @@ -1803,7 +1803,7 @@ static int xferOptimization( sqlite3VdbeAddOp2(v, OP_RowData, iSrc, regData); sqlite3VdbeAddOp3(v, OP_Insert, iDest, regData, regRowid); sqlite3VdbeChangeP5(v, OPFLAG_NCHANGE|OPFLAG_LASTROWID|OPFLAG_APPEND); - sqlite3VdbeChangeP4(v, -1, pDest->zName, 0); + sqlite3VdbeChangeP4(v, -1, (char *)pDest, P4_TABLE); sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1); for(pDestIdx=pDest->pIndex; pDestIdx; pDestIdx=pDestIdx->pNext){ for(pSrcIdx=pSrc->pIndex; ALWAYS(pSrcIdx); pSrcIdx=pSrcIdx->pNext){ diff --git a/src/update.c b/src/update.c index 2c9f246d77..b67c76f5fe 100644 --- a/src/update.c +++ b/src/update.c @@ -503,7 +503,7 @@ void sqlite3Update( regNewRowid ); if( !pParse->nested ){ - sqlite3VdbeChangeP4(v, -1, pTab->zName, P4_STATIC); + sqlite3VdbeChangeP4(v, -1, pTab, P4_TABLE); } sqlite3VdbeJumpHere(v, j1); diff --git a/src/vdbe.c b/src/vdbe.c index d6cdaaafca..de979b1cbb 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -3838,9 +3838,9 @@ case OP_NewRowid: { /* out2-prerelease */ ** is part of an INSERT operation. The difference is only important to ** the update hook. ** -** Parameter P4 may point to a string containing the table-name, or -** may be NULL. If it is not NULL, then the update-hook -** (sqlite3.xUpdateCallback) is invoked following a successful insert. +** Parameter P4 may point to a Table structure, or may be NULL. If it is +** not NULL, then the update-hook (sqlite3.xUpdateCallback) is invoked +** following a successful insert. ** ** (WARNING/TODO: If P1 is a pseudo-cursor and P2 is dynamically ** allocated, then ownership of P2 is transferred to the pseudo-cursor @@ -3865,7 +3865,7 @@ case OP_InsertInt: { int nZero; /* Number of zero-bytes to append */ int seekResult; /* Result of prior seek or 0 if no USESEEKRESULT flag */ const char *zDb; /* database name - used by the update hook */ - const char *zTbl; /* Table name - used by the opdate hook */ + Table *pTab; /* Table structure - used by update and pre-update hooks */ int op; /* Opcode for update hook: SQLITE_UPDATE or SQLITE_INSERT */ pData = &aMem[pOp->p2]; @@ -3876,6 +3876,7 @@ case OP_InsertInt: { assert( pC->pCursor!=0 ); assert( pC->pseudoTableReg==0 ); assert( pC->isTable ); + assert( pOp->p4type==P4_TABLE || pOp->p4type==P4_NOTUSED ); REGISTER_TRACE(pOp->p2, pData); if( pOp->opcode==OP_Insert ){ @@ -3889,20 +3890,20 @@ case OP_InsertInt: { iKey = pOp->p3; } - if( pOp->p4.z && (db->xPreUpdateCallback || db->xUpdateCallback) ){ + if( pOp->p4type==P4_TABLE && (db->xPreUpdateCallback||db->xUpdateCallback) ){ assert( pC->isTable ); assert( pC->iDb>=0 ); zDb = db->aDb[pC->iDb].zName; - zTbl = pOp->p4.z; + pTab = pOp->p4.pTab; op = ((pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT); } /* Invoke the pre-update hook, if any */ if( db->xPreUpdateCallback - && pOp->p4.z + && pOp->p4type==P4_TABLE && (!(pOp->p5 & OPFLAG_ISUPDATE) || pC->rowidIsValid==0) ){ - sqlite3VdbePreUpdateHook(p, pC, SQLITE_INSERT, zDb, zTbl, iKey, pOp->p2); + sqlite3VdbePreUpdateHook(p, pC, SQLITE_INSERT, zDb, pTab, iKey, pOp->p2); } if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++; @@ -3930,7 +3931,7 @@ case OP_InsertInt: { /* Invoke the update-hook if required. */ if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z ){ - db->xUpdateCallback(db->pUpdateArg, op, zDb, zTbl, iKey); + db->xUpdateCallback(db->pUpdateArg, op, zDb, pTab->zName, iKey); } break; } @@ -3950,12 +3951,12 @@ case OP_InsertInt: { ** P1 must not be pseudo-table. It has to be a real table with ** multiple rows. ** -** If P4 is not NULL then, either the update or pre-update hook, or both, -** may be invoked. The P1 cursor must have been positioned using OP_NotFound -** prior to invoking this opcode in this case. Specifically, if one is -** configured, the pre-update hook is invoked if P4 is not NULL. The -** update-hook is invoked if one is configured, P4 is not NULL, and the -** OPFLAG_NCHANGE flag is set in P2. +** If P4 is not NULL then it points to a Table struture. In this case either +** the update or pre-update hook, or both, may be invoked. The P1 cursor must +** have been positioned using OP_NotFound prior to invoking this opcode in +** this case. Specifically, if one is configured, the pre-update hook is +** invoked if P4 is not NULL. The update-hook is invoked if one is configured, +** P4 is not NULL, and the OPFLAG_NCHANGE flag is set in P2. ** ** If the OPFLAG_ISUPDATE flag is set in P2, then P3 contains the address ** of the memory cell that contains the value that the rowid of the row will @@ -3965,7 +3966,7 @@ case OP_Delete: { i64 iKey; VdbeCursor *pC; const char *zDb; - const char *zTbl; + Table *pTab; int opflags; opflags = pOp->p2; @@ -3974,6 +3975,7 @@ case OP_Delete: { pC = p->apCsr[pOp->p1]; assert( pC!=0 ); assert( pC->pCursor!=0 ); /* Only valid for real tables, no pseudotables */ + assert( pOp->p4type==P4_TABLE || pOp->p4type==P4_NOTUSED ); /* The OP_Delete opcode always follows an OP_NotExists or OP_Last or ** OP_Column on the same table without any intervening operations that @@ -3995,7 +3997,7 @@ case OP_Delete: { assert( pC->rowidIsValid ); /* lastRowid set by previous OP_NotFound */ iKey = pC->lastRowid; zDb = db->aDb[pC->iDb].zName; - zTbl = pOp->p4.z; + pTab = pOp->p4.pTab; } /* Invoke the pre-update-hook if required. */ @@ -4003,7 +4005,7 @@ case OP_Delete: { assert( !(opflags & OPFLAG_ISUPDATE) || (aMem[pOp->p3].flags & MEM_Int) ); sqlite3VdbePreUpdateHook(p, pC, (opflags & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_DELETE, - zDb, zTbl, iKey, + zDb, pTab, iKey, pOp->p3 ); } @@ -4019,7 +4021,7 @@ case OP_Delete: { p->nChange++; assert( pOp->p4.z ); if( rc==SQLITE_OK && db->xUpdateCallback ){ - db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE, zDb, zTbl, iKey); + db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE, zDb, pTab->zName,iKey); } } break; diff --git a/src/vdbe.h b/src/vdbe.h index 71c871d52f..2a6fe95fd4 100644 --- a/src/vdbe.h +++ b/src/vdbe.h @@ -61,6 +61,7 @@ struct VdbeOp { KeyInfo *pKeyInfo; /* Used when p4type is P4_KEYINFO */ int *ai; /* Used when p4type is P4_INTARRAY */ SubProgram *pProgram; /* Used when p4type is P4_SUBPROGRAM */ + Table *pTab; /* Used when p4type is P4_TABLE */ } p4; #ifdef SQLITE_DEBUG char *zComment; /* Comment to improve readability */ @@ -116,6 +117,7 @@ typedef struct VdbeOpList VdbeOpList; #define P4_INT32 (-14) /* P4 is a 32-bit signed integer */ #define P4_INTARRAY (-15) /* P4 is a vector of 32-bit integers */ #define P4_SUBPROGRAM (-18) /* P4 is a pointer to a SubProgram structure */ +#define P4_TABLE (-19) /* P4 is a pointer to a Table structure */ /* When adding a P4 argument using P4_KEYINFO, a copy of the KeyInfo structure ** is made. That copy is freed when the Vdbe is finalized. But if the diff --git a/src/vdbeInt.h b/src/vdbeInt.h index 447e025e94..cac88af71e 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -344,6 +344,9 @@ struct PreUpdate { UnpackedRecord *pUnpacked; /* Unpacked version of aRecord[] */ UnpackedRecord *pNewUnpacked; /* Unpacked version of new.* record */ int iNewReg; /* Register for new.* values */ + i64 iKey1; /* First key value passed to hook */ + i64 iKey2; /* Second key value passed to hook */ + int iPKey; /* If not negative index of IPK column */ Mem *aNew; /* Array of new.* values */ }; @@ -404,7 +407,7 @@ void sqlite3VdbeFrameDelete(VdbeFrame*); int sqlite3VdbeFrameRestore(VdbeFrame *); void sqlite3VdbeMemStoreType(Mem *pMem); void sqlite3VdbePreUpdateHook( - Vdbe *, VdbeCursor *, int, const char*, const char*, i64, int); + Vdbe *, VdbeCursor *, int, const char*, Table *, i64, int); #ifdef SQLITE_DEBUG void sqlite3VdbeMemPrepareToChange(Vdbe*,Mem*); diff --git a/src/vdbeapi.c b/src/vdbeapi.c index 4fde5893b6..284e565e13 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -1369,6 +1369,9 @@ int sqlite3_preupdate_old(sqlite3 *db, int iIdx, sqlite3_value **ppValue){ *ppValue = (sqlite3_value *)columnNullValue(); }else{ *ppValue = &p->pUnpacked->aMem[iIdx]; + if( iIdx==p->iPKey ){ + sqlite3VdbeMemSetInt64(*ppValue, p->iKey1); + } sqlite3VdbeMemStoreType(*ppValue); } @@ -1423,6 +1426,9 @@ int sqlite3_preupdate_new(sqlite3 *db, int iIdx, sqlite3_value **ppValue){ pMem = (sqlite3_value *)columnNullValue(); }else{ pMem = &pUnpack->aMem[iIdx]; + if( iIdx==p->iPKey ){ + sqlite3VdbeMemSetInt64(pMem, p->iKey2); + } sqlite3VdbeMemStoreType(pMem); } }else{ @@ -1442,8 +1448,12 @@ int sqlite3_preupdate_new(sqlite3 *db, int iIdx, sqlite3_value **ppValue){ assert( iIdx>=0 && iIdxpCsr->nField ); pMem = &p->aNew[iIdx]; if( pMem->flags==0 ){ - rc = sqlite3VdbeMemCopy(pMem, &p->v->aMem[p->iNewReg+1+iIdx]); - if( rc!=SQLITE_OK ) goto preupdate_new_out; + if( iIdx==p->iPKey ){ + sqlite3VdbeMemSetInt64(pMem, p->iKey2); + }else{ + rc = sqlite3VdbeMemCopy(pMem, &p->v->aMem[p->iNewReg+1+iIdx]); + if( rc!=SQLITE_OK ) goto preupdate_new_out; + } sqlite3VdbeMemStoreType(pMem); } } diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 368330720d..a2526ace20 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -3182,13 +3182,14 @@ void sqlite3VdbePreUpdateHook( VdbeCursor *pCsr, /* Cursor to grab old.* values from */ int op, /* SQLITE_INSERT, UPDATE or DELETE */ const char *zDb, /* Database name */ - const char *zTbl, /* Table name */ + Table *pTab, /* Modified table */ i64 iKey1, /* Initial key value */ int iReg /* Register for new.* record */ ){ sqlite3 *db = v->db; i64 iKey2; PreUpdate preupdate; + const char *zTbl = pTab->zName; assert( db->pPreUpdate==0 ); memset(&preupdate, 0, sizeof(PreUpdate)); @@ -3205,6 +3206,10 @@ void sqlite3VdbePreUpdateHook( preupdate.keyinfo.db = db; preupdate.keyinfo.enc = ENC(db); preupdate.keyinfo.nField = pCsr->nField; + preupdate.iKey1 = iKey1; + preupdate.iKey2 = iKey2; + preupdate.iPKey = pTab->iPKey; + db->pPreUpdate = &preupdate; db->xPreUpdateCallback(db->pPreUpdateArg, db, op, zDb, zTbl, iKey1, iKey2); db->pPreUpdate = 0; diff --git a/test/hook.test b/test/hook.test index 001e8ddf4a..9ceedbb75d 100644 --- a/test/hook.test +++ b/test/hook.test @@ -622,7 +622,7 @@ do_execsql_test 7.5.2.0 { ALTER TABLE t8 ADD COLUMN c DEFAULT 'xxx'; } -# At time of writing, these two are broken. They demonstraight that the +# At time of writing, these two are broken. They demonstrate that the # sqlite3_preupdate_old() method does not handle the case where ALTER TABLE # has been used to add a column with a default value other than NULL. # @@ -637,5 +637,20 @@ do_preupdate_test 7.5.2.2 { UPDATE main t8 2 2 three four xxx three five xxx } +# This block of tests verifies that IPK values are correctly reported +# by the sqlite3_preupdate_old() and sqlite3_preupdate_new() functions. +# +do_execsql_test 7.6.1 { CREATE TABLE t9(a, b INTEGER PRIMARY KEY, c) } +do_preupdate_test 7.6.2 { + INSERT INTO t9 VALUES(1, 2, 3); + UPDATE t9 SET b = b+1, c = c+1; + DELETE FROM t9 WHERE a = 1; +} { + INSERT main t9 2 2 1 2 3 + UPDATE main t9 2 3 1 2 3 1 3 4 + DELETE main t9 3 3 1 3 4 +} + + finish_test diff --git a/test/progress.test b/test/progress.test old mode 100644 new mode 100755 diff --git a/tool/mkopts.tcl b/tool/mkopts.tcl old mode 100644 new mode 100755 From 7cf7df7d35579c9575ded280577b8337efd9c1c5 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 19 Mar 2011 15:37:02 +0000 Subject: [PATCH 0018/1484] Fix some bugs in sqlite3changeset_apply(). FossilOrigin-Name: 7250318dda542c5bbf28852c1f1d0f3c52ae8f96 --- ext/session/session2.test | 138 +++++++++++++++++++++++++++++++++++ ext/session/sqlite3session.c | 34 +++++---- manifest | 18 +++-- manifest.uuid | 2 +- src/test_config.c | 6 ++ test/permutations.test | 9 ++- test/session.test | 18 +++++ 7 files changed, 201 insertions(+), 24 deletions(-) create mode 100644 ext/session/session2.test create mode 100644 test/session.test diff --git a/ext/session/session2.test b/ext/session/session2.test new file mode 100644 index 0000000000..21a457fde9 --- /dev/null +++ b/ext/session/session2.test @@ -0,0 +1,138 @@ +# 2011 Mar 16 +# +# 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. +# +#*********************************************************************** +# +# The focus of this file is testing the session module. +# + +if {![info exists testdir]} { + set testdir [file join [file dirname [info script]] .. .. test] +} +source [file join [file dirname [info script]] session_common.tcl] +source $testdir/tester.tcl + +set testprefix session2 + +proc test_reset {} { + catch { db close } + catch { db2 close } + forcedelete test.db test.db2 + sqlite3 db test.db + sqlite3 db2 test.db2 +} + +proc do_common_sql {sql} { + execsql $sql db + execsql $sql db2 +} +proc xConflict args { return "OMIT" } + +proc do_then_apply_sql {sql} { + sqlite3session S db main + db eval {SELECT name FROM sqlite_master WHERE type = 'table'} { + S attach $name + } + + db eval $sql + sqlite3changeset_apply db2 [S changeset] xConflict + S delete +} + +proc do_iterator_test {tn tbl_list sql res} { + sqlite3session S db main + foreach t $tbl_list {S attach $t} + execsql $sql + + set r [list] + foreach v $res { lappend r $v } + + set x [list] + sqlite3session_foreach c [S changeset] { lappend x $c } + uplevel do_test $tn [list [list set {} $x]] [list $r] + + S delete +} + +# Compare the contents of all tables in [db1] and [db2]. Throw an error if +# they are not identical, or return an empty string if they are. +# +proc compare_db {db1 db2} { + + set sql {SELECT name FROM sqlite_master WHERE type = 'table' ORDER BY name} + set lot1 [$db1 eval $sql] + set lot2 [$db2 eval $sql] + + if {$lot1 != $lot2} { error "databases contain different tables" } + + foreach tbl $lot1 { + set col1 [list] + set col2 [list] + + $db1 eval "PRAGMA table_info = $tbl" { lappend col1 $name } + $db2 eval "PRAGMA table_info = $tbl" { lappend col2 $name } + if {$col1 != $col2} { error "table $tbl schema mismatch" } + + set sql "SELECT * FROM $tbl ORDER BY [join $col1 ,]" + set data1 [$db1 eval $sql] + set data2 [$db2 eval $sql] + if {$data1 != $data2} { error "table $tbl data mismatch" } + } + + return "" +} + +########################################################################## +# End of proc definitions. Start of tests. +########################################################################## + +test_reset +do_execsql_test 1.0 { + CREATE TABLE t1(a PRIMARY KEY, b); + INSERT INTO t1 VALUES('i', 'one'); +} +do_iterator_test 1.1 t1 { + DELETE FROM t1 WHERE a = 'i'; + INSERT INTO t1 VALUES('ii', 'two'); +} { + {DELETE t1 {t i t one} {}} + {INSERT t1 {} {t ii t two}} +} + +test_reset +do_common_sql { + CREATE TABLE t1(a PRIMARY KEY, b); + CREATE TABLE t2(a, b INTEGER PRIMARY KEY); + CREATE TABLE t3(a, b, c, PRIMARY KEY(a, b)); +} + +foreach {tn sql} { + 1 { INSERT INTO t1 VALUES(1, 2) } + 2 { + INSERT INTO t2 VALUES(1, NULL); + INSERT INTO t2 VALUES(2, NULL); + INSERT INTO t2 VALUES(3, NULL); + DELETE FROM t2 WHERE a = 2; + INSERT INTO t2 VALUES(4, NULL); + UPDATE t2 SET b=0 WHERE b=1; + } + 3 { INSERT INTO t3 SELECT *, NULL FROM t2 } + 4 { + INSERT INTO t3 SELECT a||a, b||b, NULL FROM t3; + DELETE FROM t3 WHERE rowid%2; + } + 5 { UPDATE t3 SET c = a||b } + 6 { UPDATE t1 SET a = 32 } +} { + do_then_apply_sql $sql + do_test $tn { compare_db db db2 } {} +} + +finish_test + diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index 64114718de..411e082377 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -1777,6 +1777,7 @@ static int sessionDeleteRow( const char *zSep = ""; int rc = SQLITE_OK; SessionBuffer buf = {0, 0, 0}; + int nPk = 0; sessionAppendStr(&buf, "DELETE FROM ", &rc); sessionAppendIdent(&buf, zTab, &rc); @@ -1784,29 +1785,32 @@ static int sessionDeleteRow( for(i=0; inCol; i++){ if( p->abPK[i] ){ + nPk++; sessionAppendStr(&buf, zSep, &rc); sessionAppendIdent(&buf, p->azCol[i], &rc); sessionAppendStr(&buf, " = ?", &rc); sessionAppendInteger(&buf, i+1, &rc); - zSep = "AND "; + zSep = " AND "; } } - sessionAppendStr(&buf, " AND (?", &rc); - sessionAppendInteger(&buf, p->nCol+1, &rc); - sessionAppendStr(&buf, " OR ", &rc); + if( nPknCol ){ + sessionAppendStr(&buf, " AND (?", &rc); + sessionAppendInteger(&buf, p->nCol+1, &rc); + sessionAppendStr(&buf, " OR ", &rc); - zSep = ""; - for(i=0; inCol; i++){ - if( !p->abPK[i] ){ - sessionAppendStr(&buf, zSep, &rc); - sessionAppendIdent(&buf, p->azCol[i], &rc); - sessionAppendStr(&buf, " IS ?", &rc); - sessionAppendInteger(&buf, i+1, &rc); - zSep = "AND "; + zSep = ""; + for(i=0; inCol; i++){ + if( !p->abPK[i] ){ + sessionAppendStr(&buf, zSep, &rc); + sessionAppendIdent(&buf, p->azCol[i], &rc); + sessionAppendStr(&buf, " IS ?", &rc); + sessionAppendInteger(&buf, i+1, &rc); + zSep = "AND "; + } } + sessionAppendStr(&buf, ")", &rc); } - sessionAppendStr(&buf, ")", &rc); if( rc==SQLITE_OK ){ rc = sqlite3_prepare_v2(db, (char *)buf.aBuf, buf.nBuf, &p->pDelete, 0); @@ -2171,7 +2175,9 @@ static int sessionApplyOneOp( rc = sqlite3_bind_value(p->pDelete, i+1, pVal); } } - if( rc==SQLITE_OK ) rc = sqlite3_bind_int(p->pDelete, nCol+1, pbRetry==0); + if( rc==SQLITE_OK && sqlite3_bind_parameter_count(p->pDelete)>nCol ){ + rc = sqlite3_bind_int(p->pDelete, nCol+1, pbRetry==0); + } if( rc!=SQLITE_OK ) return rc; sqlite3_step(p->pDelete); diff --git a/manifest b/manifest index fffd7c5851..15369f40cd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\swith\sINTEGER\sPRIMARY\sKEY\scolumns\sand\sthe\spre-update\shook. -D 2011-03-19T08:38:50 +C Fix\ssome\sbugs\sin\ssqlite3changeset_apply(). +D 2011-03-19T15:37:02 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -99,7 +99,8 @@ F ext/rtree/rtree_util.tcl 06aab2ed5b826545bf215fff90ecb9255a8647ea F ext/rtree/sqlite3rtree.h 1af0899c63a688e272d69d8e746f24e76f10a3f0 F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 -F ext/session/sqlite3session.c d4ba709d457a7b184a72ccd3ab07e5a1e9dd9196 +F ext/session/session2.test 72f5926805b46a9a5f240db856dab0e5f59fc693 +F ext/session/sqlite3session.c 6518a335592f4b118d9e6b9ed9dcbe27b0ebcda7 F ext/session/sqlite3session.h 9551c002efd5fde07c52994c6b592308e0df2d6a F ext/session/test_session.c 2559ef68e421c7fb83e2c19ef08a17343b70d535 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 @@ -201,7 +202,7 @@ F src/test_async.c 0612a752896fad42d55c3999a5122af10dcf22ad F src/test_autoext.c 30e7bd98ab6d70a62bb9ba572e4c7df347fe645e F src/test_backup.c c129c91127e9b46e335715ae2e75756e25ba27de F src/test_btree.c 47cd771250f09cdc6e12dda5bc71bc0b3abc96e2 -F src/test_config.c 62f0f8f934b1d5c7e4cd4f506ae453a1117b47d7 +F src/test_config.c e9a4ce02dec5bcced1c13e0cf8b72edfd5903d74 F src/test_demovfs.c 0aed671636735116fc872c5b03706fd5612488b5 F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc F src/test_func.c cbdec5cededa0761daedde5baf06004a9bf416b5 @@ -601,7 +602,7 @@ F test/pageropt.test 8146bf448cf09e87bb1867c2217b921fb5857806 F test/pagesize.test 76aa9f23ecb0741a4ed9d2e16c5fa82671f28efb F test/pcache.test 065aa286e722ab24f2e51792c1f093bf60656b16 F test/pcache2.test 0d85f2ab6963aee28c671d4c71bec038c00a1d16 -F test/permutations.test 5b2a4cb756ffb2407cb4743163668d1d769febb6 +F test/permutations.test 1e35edce72e6d9e2e392420caed18652a97b1a95 F test/pragma.test fdfc09067ea104a0c247a1a79d8093b56656f850 F test/pragma2.test 5364893491b9231dd170e3459bfc2e2342658b47 F test/printf.test 05970cde31b1a9f54bd75af60597be75a5c54fea @@ -644,6 +645,7 @@ F test/selectA.test 06d1032fa9009314c95394f2ca2e60d9f7ae8532 F test/selectB.test f305cc6660804cb239aab4e2f26b0e288b59958b F test/selectC.test f9bf1bc4581b5b8158caa6e4e4f682acb379fb25 F test/server1.test f5b790d4c0498179151ca8a7715a65a7802c859c +F test/session.test c1a17c11ef7d01c24fe2b9f7871190d949a8e718 F test/session1.test c6851e2e1066269cad5370566ce5494c7dbdfa7e F test/shared.test b9114eaea7e748a3a4c8ff7b9ca806c8f95cef3e F test/shared2.test 7f6ad2d857d0f4e5d6a0b9a897b5e56a6b6ea18c @@ -919,7 +921,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 1b736ac2934f2361dee5062e9033cbf26b41fc3a -R 162f72638a0f38fbe0fc1273d5b87dc2 +P 24d4d5dd007197a141555bcca6f2ac9ab47cde80 +R 985767b788ac43658b5fdac318a5d51e U dan -Z 3b532fd3ba73ffa805a9d5e7143aadc5 +Z e6cf037758a8ddd02cc6b33f9980e9f6 diff --git a/manifest.uuid b/manifest.uuid index e62b7f494c..75eb322606 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -24d4d5dd007197a141555bcca6f2ac9ab47cde80 \ No newline at end of file +7250318dda542c5bbf28852c1f1d0f3c52ae8f96 \ No newline at end of file diff --git a/src/test_config.c b/src/test_config.c index 6eee524c09..24ddbaa027 100644 --- a/src/test_config.c +++ b/src/test_config.c @@ -404,6 +404,12 @@ Tcl_SetVar2(interp, "sqlite_options", "long_double", Tcl_SetVar2(interp, "sqlite_options", "schema_version", "1", TCL_GLOBAL_ONLY); #endif +#ifdef SQLITE_ENABLE_SESSION + Tcl_SetVar2(interp, "sqlite_options", "session", "1", TCL_GLOBAL_ONLY); +#else + Tcl_SetVar2(interp, "sqlite_options", "session", "0", TCL_GLOBAL_ONLY); +#endif + #ifdef SQLITE_ENABLE_STAT2 Tcl_SetVar2(interp, "sqlite_options", "stat2", "1", TCL_GLOBAL_ONLY); #else diff --git a/test/permutations.test b/test/permutations.test index 9c48d9aa2a..7e336b16aa 100644 --- a/test/permutations.test +++ b/test/permutations.test @@ -89,6 +89,9 @@ foreach f [glob $testdir/*.test] { lappend alltests [file tail $f] } foreach f [glob -nocomplain $testdir/../ext/rtree/*.test] { lappend alltests $f } +foreach f [glob -nocomplain $testdir/../ext/session/*.test] { + lappend alltests $f +} if {$::tcl_platform(platform)!="unix"} { set alltests [test_set $alltests -exclude crash.test crash2.test] @@ -96,7 +99,7 @@ if {$::tcl_platform(platform)!="unix"} { set alltests [test_set $alltests -exclude { all.test async.test quick.test veryquick.test memleak.test permutations.test soak.test fts3.test - mallocAll.test rtree.test + mallocAll.test rtree.test session.test }] set allquicktests [test_set $alltests -exclude { @@ -762,6 +765,10 @@ test_suite "rtree" -description { All R-tree related tests. Provides coverage of source file rtree.c. } -files [glob -nocomplain $::testdir/../ext/rtree/*.test] +test_suite "session" -description { + All session module related tests. +} -files [glob -nocomplain $::testdir/../ext/session/*.test] + test_suite "no_optimization" -description { Run test scripts with optimizations disabled using the sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS) interface. diff --git a/test/session.test b/test/session.test new file mode 100644 index 0000000000..bf159c3b22 --- /dev/null +++ b/test/session.test @@ -0,0 +1,18 @@ +# 2008 June 23 +# +# 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 runs all rtree related tests. +# + +set testdir [file dirname $argv0] +source $testdir/permutations.test + +ifcapable session { + run_test_suite session +} + +finish_test From 4131639c6362eb0dc26ea486edb7b6be74011a1b Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 19 Mar 2011 16:26:11 +0000 Subject: [PATCH 0019/1484] Fix a problem with resizing a hash table in sqlite3session.c. FossilOrigin-Name: 6e5907e14d3316d56313243c4f8ce8f14d0858fc --- ext/session/session2.test | 21 +++++++++++++++++++ ext/session/sqlite3session.c | 40 +++++++++++++++++++++--------------- manifest | 14 ++++++------- manifest.uuid | 2 +- 4 files changed, 53 insertions(+), 24 deletions(-) diff --git a/ext/session/session2.test b/ext/session/session2.test index 21a457fde9..ee5cbd2daf 100644 --- a/ext/session/session2.test +++ b/ext/session/session2.test @@ -114,6 +114,7 @@ do_common_sql { foreach {tn sql} { 1 { INSERT INTO t1 VALUES(1, 2) } + 2 { INSERT INTO t2 VALUES(1, NULL); INSERT INTO t2 VALUES(2, NULL); @@ -122,13 +123,33 @@ foreach {tn sql} { INSERT INTO t2 VALUES(4, NULL); UPDATE t2 SET b=0 WHERE b=1; } + 3 { INSERT INTO t3 SELECT *, NULL FROM t2 } + 4 { INSERT INTO t3 SELECT a||a, b||b, NULL FROM t3; DELETE FROM t3 WHERE rowid%2; } + 5 { UPDATE t3 SET c = a||b } + 6 { UPDATE t1 SET a = 32 } + + 7 { + INSERT INTO t1 SELECT randomblob(32), randomblob(32) FROM t1; -- 2 + INSERT INTO t1 SELECT randomblob(32), randomblob(32) FROM t1; -- 4 + INSERT INTO t1 SELECT randomblob(32), randomblob(32) FROM t1; -- 8 + INSERT INTO t1 SELECT randomblob(32), randomblob(32) FROM t1; -- 16 + INSERT INTO t1 SELECT randomblob(32), randomblob(32) FROM t1; -- 32 + INSERT INTO t1 SELECT randomblob(32), randomblob(32) FROM t1; -- 64 + INSERT INTO t1 SELECT randomblob(32), randomblob(32) FROM t1; -- 128 + INSERT INTO t1 SELECT randomblob(32), randomblob(32) FROM t1; -- 256 + INSERT INTO t1 SELECT randomblob(32), randomblob(32) FROM t1; -- 512 + INSERT INTO t1 SELECT randomblob(32), randomblob(32) FROM t1; -- 1024 + INSERT INTO t1 SELECT randomblob(32), randomblob(32) FROM t1; -- 2048 + DELETE FROM t1 WHERE (rowid%3)==0; + } + } { do_then_apply_sql $sql do_test $tn { compare_db db db2 } {} diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index 411e082377..a76d2d29f3 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -265,29 +265,31 @@ static int sessionSerializeValue( return SQLITE_OK; } -#define HASH_APPEND(hash, add) ((hash) << 3) ^ (hash) ^ (int)(add) -static int sessionHashAppendI64(int h, i64 i){ +#define HASH_APPEND(hash, add) ((hash) << 3) ^ (hash) ^ (unsigned int)(add) +static unsigned int sessionHashAppendI64(unsigned int h, i64 i){ h = HASH_APPEND(h, i & 0xFFFFFFFF); return HASH_APPEND(h, (i>>32)&0xFFFFFFFF); } -static int sessionHashAppendBlob(int h, int n, const u8 *z){ +static unsigned int sessionHashAppendBlob(unsigned int h, int n, const u8 *z){ int i; for(i=0; inBucket. */ -static int sessionPreupdateHash( +static unsigned int sessionPreupdateHash( sqlite3 *db, /* Database handle */ SessionTable *pTab, /* Session table handle */ int bNew, /* True to hash the new.* PK */ int *piHash /* OUT: Hash value */ ){ - int h = 0; - int i; + unsigned int h = 0; /* Hash value to return */ + int i; /* Used to iterate through columns */ assert( pTab->nCol==sqlite3_preupdate_count(db) ); for(i=0; inCol; i++){ @@ -335,15 +337,21 @@ static int sessionPreupdateHash( return SQLITE_OK; } -static int sessionChangeHash( - sqlite3 *db, - SessionTable *pTab, - SessionChange *pChange, - int nBucket +/* +** Based on the primary key values stored in change pChange, calculate a +** hash key, assuming the has table has nBucket buckets. The hash keys +** calculated by this function are compatible with those calculated by +** sessionPreupdateHash(). +*/ +static unsigned int sessionChangeHash( + sqlite3 *db, /* Database handle */ + SessionTable *pTab, /* Table handle */ + SessionChange *pChange, /* Change handle */ + int nBucket /* Assume this many buckets in hash table */ ){ - int h = 0; - int i; - u8 *a = pChange->aRecord; + unsigned int h = 0; /* Value to return */ + int i; /* Used to iterate through columns */ + u8 *a = pChange->aRecord; /* Used to iterate through change record */ for(i=0; inCol; i++){ int eType = *a++; diff --git a/manifest b/manifest index 15369f40cd..3aa28c08c6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\ssome\sbugs\sin\ssqlite3changeset_apply(). -D 2011-03-19T15:37:02 +C Fix\sa\sproblem\swith\sresizing\sa\shash\stable\sin\ssqlite3session.c. +D 2011-03-19T16:26:12 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -99,8 +99,8 @@ F ext/rtree/rtree_util.tcl 06aab2ed5b826545bf215fff90ecb9255a8647ea F ext/rtree/sqlite3rtree.h 1af0899c63a688e272d69d8e746f24e76f10a3f0 F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 -F ext/session/session2.test 72f5926805b46a9a5f240db856dab0e5f59fc693 -F ext/session/sqlite3session.c 6518a335592f4b118d9e6b9ed9dcbe27b0ebcda7 +F ext/session/session2.test 61c7ee56d158ab614b058b860508c85db2985810 +F ext/session/sqlite3session.c 55ec4205c7a12e417c38743d81e229a31a0f7e25 F ext/session/sqlite3session.h 9551c002efd5fde07c52994c6b592308e0df2d6a F ext/session/test_session.c 2559ef68e421c7fb83e2c19ef08a17343b70d535 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 @@ -921,7 +921,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 24d4d5dd007197a141555bcca6f2ac9ab47cde80 -R 985767b788ac43658b5fdac318a5d51e +P 7250318dda542c5bbf28852c1f1d0f3c52ae8f96 +R fb3197b98aa7c2cdada7337c44e7d717 U dan -Z e6cf037758a8ddd02cc6b33f9980e9f6 +Z 1901f146e1ed8385b77ee721ba556bd6 diff --git a/manifest.uuid b/manifest.uuid index 75eb322606..cb8c1bd8be 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7250318dda542c5bbf28852c1f1d0f3c52ae8f96 \ No newline at end of file +6e5907e14d3316d56313243c4f8ce8f14d0858fc \ No newline at end of file From 4565faa990e0e4b0ed3704ff689fd19d6dcaa74f Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 19 Mar 2011 17:07:57 +0000 Subject: [PATCH 0020/1484] Move session1.test from test/ to ext/session/. FossilOrigin-Name: c4436a936ab302aec3b7f41a4552f69ad5815744 --- {test => ext/session}/session1.test | 8 ++++++-- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 13 insertions(+), 9 deletions(-) rename {test => ext/session}/session1.test (98%) diff --git a/test/session1.test b/ext/session/session1.test similarity index 98% rename from test/session1.test rename to ext/session/session1.test index 872bee416f..fd09b47cc5 100644 --- a/test/session1.test +++ b/ext/session/session1.test @@ -11,9 +11,13 @@ # This file implements regression tests for SQLite library. # -set testdir [file dirname $argv0] +if {![info exists testdir]} { + set testdir [file join [file dirname [info script]] .. .. test] +} +source [file join [file dirname [info script]] session_common.tcl] source $testdir/tester.tcl -set ::testprefix session1 + +set testprefix session1 proc do_changeset_test {tn session res} { set r [list] diff --git a/manifest b/manifest index 3aa28c08c6..7ea0d559c0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\swith\sresizing\sa\shash\stable\sin\ssqlite3session.c. -D 2011-03-19T16:26:12 +C Move\ssession1.test\sfrom\stest/\sto\sext/session/. +D 2011-03-19T17:07:58 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -99,6 +99,7 @@ F ext/rtree/rtree_util.tcl 06aab2ed5b826545bf215fff90ecb9255a8647ea F ext/rtree/sqlite3rtree.h 1af0899c63a688e272d69d8e746f24e76f10a3f0 F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 +F ext/session/session1.test 3f982c74ee4ba97069917cc35aae25b4ed858e6a w test/session1.test F ext/session/session2.test 61c7ee56d158ab614b058b860508c85db2985810 F ext/session/sqlite3session.c 55ec4205c7a12e417c38743d81e229a31a0f7e25 F ext/session/sqlite3session.h 9551c002efd5fde07c52994c6b592308e0df2d6a @@ -646,7 +647,6 @@ F test/selectB.test f305cc6660804cb239aab4e2f26b0e288b59958b F test/selectC.test f9bf1bc4581b5b8158caa6e4e4f682acb379fb25 F test/server1.test f5b790d4c0498179151ca8a7715a65a7802c859c F test/session.test c1a17c11ef7d01c24fe2b9f7871190d949a8e718 -F test/session1.test c6851e2e1066269cad5370566ce5494c7dbdfa7e F test/shared.test b9114eaea7e748a3a4c8ff7b9ca806c8f95cef3e F test/shared2.test 7f6ad2d857d0f4e5d6a0b9a897b5e56a6b6ea18c F test/shared3.test d69bdd5f156580876c5345652d21dc2092e85962 @@ -921,7 +921,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 7250318dda542c5bbf28852c1f1d0f3c52ae8f96 -R fb3197b98aa7c2cdada7337c44e7d717 +P 6e5907e14d3316d56313243c4f8ce8f14d0858fc +R 611730f89810ada9d2f188c5b6da861b U dan -Z 1901f146e1ed8385b77ee721ba556bd6 +Z a6a229bf3ddc4c217d0e04afae66c6a2 diff --git a/manifest.uuid b/manifest.uuid index cb8c1bd8be..5208758a65 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6e5907e14d3316d56313243c4f8ce8f14d0858fc \ No newline at end of file +c4436a936ab302aec3b7f41a4552f69ad5815744 \ No newline at end of file From 1f34f8cc719478a2225fc9dc8f0a42ba08bdabe6 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 19 Mar 2011 18:46:15 +0000 Subject: [PATCH 0021/1484] Fix a bug in changeset generation code. FossilOrigin-Name: 825df75ba453c853953e17ec29653e11c46f92bb --- ext/session/session2.test | 21 +++++++++++++++++++++ ext/session/sqlite3session.c | 34 +++++++++++++++++----------------- manifest | 16 ++++++++-------- manifest.uuid | 2 +- 4 files changed, 47 insertions(+), 26 deletions(-) diff --git a/ext/session/session2.test b/ext/session/session2.test index ee5cbd2daf..6436a2724b 100644 --- a/ext/session/session2.test +++ b/ext/session/session2.test @@ -112,6 +112,11 @@ do_common_sql { CREATE TABLE t3(a, b, c, PRIMARY KEY(a, b)); } +# Execute each of the following blocks of SQL on database [db1]. Collect +# changes using a session object. Apply the resulting changeset to +# database [db2]. Then check that the contents of the two databases are +# identical. +# foreach {tn sql} { 1 { INSERT INTO t1 VALUES(1, 2) } @@ -150,7 +155,23 @@ foreach {tn sql} { DELETE FROM t1 WHERE (rowid%3)==0; } + 8 { + BEGIN; + INSERT INTO t1 SELECT randomblob(32), randomblob(32) FROM t1; + ROLLBACK; + } + 9 { + BEGIN; + UPDATE t1 SET b = 'xxx'; + ROLLBACK; + } + 10 { + BEGIN; + DELETE FROM t1 WHERE 1; + ROLLBACK; + } } { +if {$tn==9} breakpoint do_then_apply_sql $sql do_test $tn { compare_db db db2 } {} } diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index a76d2d29f3..c234f8ce3b 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -1115,6 +1115,7 @@ static void sessionAppendUpdate( if( *pRc==SQLITE_OK ){ SessionBuffer buf2 = {0,0,0}; /* Buffer to accumulate new.* record in */ int bNoop = 1; /* Set to zero if any values are modified */ + int nRewind = pBuf->nBuf; /* Set to zero if any values are modified */ int i; /* Used to iterate through columns */ u8 *pCsr = p->aRecord; /* Used to iterate through old.* values */ @@ -1180,11 +1181,11 @@ static void sessionAppendUpdate( } if( bNoop ){ - pBuf->nBuf -= (1 + sqlite3_column_count(pStmt)); + pBuf->nBuf = nRewind; }else{ sessionAppendBlob(pBuf, buf2.aBuf, buf2.nBuf, pRc); - sqlite3_free(buf2.aBuf); } + sqlite3_free(buf2.aBuf); } } @@ -1314,10 +1315,10 @@ int sqlite3session_changeset( if( pTab->nEntry ){ int nCol = pTab->nCol; /* Local copy of member variable */ u8 *abPK = pTab->abPK; /* Local copy of member variable */ - int i; - sqlite3_stmt *pStmt = 0; - int bNoop = 1; - int nRewind = buf.nBuf; + int i; /* Used to iterate through hash buckets */ + sqlite3_stmt *pSel = 0; /* SELECT statement to query table pTab */ + int nRewind = buf.nBuf; /* Initial size of write buffer */ + int nNoop; /* Size of buffer after writing tbl header */ /* Write a table header */ sessionAppendByte(&buf, 'T', &rc); @@ -1326,44 +1327,43 @@ int sqlite3session_changeset( /* Build and compile a statement to execute: */ if( rc==SQLITE_OK ){ - rc = sessionSelectStmt(db, pTab->zName, nCol, pTab->azCol, abPK,&pStmt); + rc = sessionSelectStmt(db, pTab->zName, nCol, pTab->azCol, abPK, &pSel); } - if( rc==SQLITE_OK && nCol!=sqlite3_column_count(pStmt) ){ + if( rc==SQLITE_OK && nCol!=sqlite3_column_count(pSel) ){ rc = SQLITE_SCHEMA; } + nNoop = buf.nBuf; for(i=0; inChange; i++){ SessionChange *p; /* Used to iterate through changes */ for(p=pTab->apChange[i]; rc==SQLITE_OK && p; p=p->pNext){ - rc = sessionSelectBind(pStmt, nCol, abPK, p->aRecord, p->nRecord); + rc = sessionSelectBind(pSel, nCol, abPK, p->aRecord, p->nRecord); if( rc==SQLITE_OK ){ - if( sqlite3_step(pStmt)==SQLITE_ROW ){ + if( sqlite3_step(pSel)==SQLITE_ROW ){ int iCol; if( p->bInsert ){ sessionAppendByte(&buf, SQLITE_INSERT, &rc); for(iCol=0; iColbInsert ){ /* A DELETE change */ sessionAppendByte(&buf, SQLITE_DELETE, &rc); sessionAppendBlob(&buf, p->aRecord, p->nRecord, &rc); - bNoop = 0; } - rc = sqlite3_reset(pStmt); + rc = sqlite3_reset(pSel); } } } - sqlite3_finalize(pStmt); + sqlite3_finalize(pSel); - if( bNoop ){ + if( buf.nBuf==nNoop ){ buf.nBuf = nRewind; } } diff --git a/manifest b/manifest index 7ea0d559c0..44b5abf093 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Move\ssession1.test\sfrom\stest/\sto\sext/session/. -D 2011-03-19T17:07:58 +C Fix\sa\sbug\sin\schangeset\sgeneration\scode. +D 2011-03-19T18:46:16 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -99,9 +99,9 @@ F ext/rtree/rtree_util.tcl 06aab2ed5b826545bf215fff90ecb9255a8647ea F ext/rtree/sqlite3rtree.h 1af0899c63a688e272d69d8e746f24e76f10a3f0 F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 -F ext/session/session1.test 3f982c74ee4ba97069917cc35aae25b4ed858e6a w test/session1.test -F ext/session/session2.test 61c7ee56d158ab614b058b860508c85db2985810 -F ext/session/sqlite3session.c 55ec4205c7a12e417c38743d81e229a31a0f7e25 +F ext/session/session1.test 3f982c74ee4ba97069917cc35aae25b4ed858e6a +F ext/session/session2.test 09cbe57d949a315c68fb59822314990fd0e2af33 +F ext/session/sqlite3session.c 4cb15010040b093e452e6de52e8b5a9161032ebf F ext/session/sqlite3session.h 9551c002efd5fde07c52994c6b592308e0df2d6a F ext/session/test_session.c 2559ef68e421c7fb83e2c19ef08a17343b70d535 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 @@ -921,7 +921,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 6e5907e14d3316d56313243c4f8ce8f14d0858fc -R 611730f89810ada9d2f188c5b6da861b +P c4436a936ab302aec3b7f41a4552f69ad5815744 +R 633c4c2a52a8f04fd2ba1fea02dc8ad5 U dan -Z a6a229bf3ddc4c217d0e04afae66c6a2 +Z 046a676deaa5ff1f82305a84f859a0a7 diff --git a/manifest.uuid b/manifest.uuid index 5208758a65..40658a2e58 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c4436a936ab302aec3b7f41a4552f69ad5815744 \ No newline at end of file +825df75ba453c853953e17ec29653e11c46f92bb \ No newline at end of file From d7fb7d24c6b4f56026fb69663d30a7b3e6ba581d Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 19 Mar 2011 19:19:26 +0000 Subject: [PATCH 0022/1484] Fix a problem involving session objects and attached databases. FossilOrigin-Name: ad91d30073a8faa7eb064dd2e1cc4d2297d7b3f8 --- ext/session/session2.test | 97 ++++++++++++++++++++++++++++++++++-- ext/session/sqlite3session.c | 12 +++-- manifest | 14 +++--- manifest.uuid | 2 +- 4 files changed, 109 insertions(+), 16 deletions(-) diff --git a/ext/session/session2.test b/ext/session/session2.test index 6436a2724b..453dc627a2 100644 --- a/ext/session/session2.test +++ b/ext/session/session2.test @@ -34,9 +34,10 @@ proc do_common_sql {sql} { } proc xConflict args { return "OMIT" } -proc do_then_apply_sql {sql} { - sqlite3session S db main - db eval {SELECT name FROM sqlite_master WHERE type = 'table'} { +proc do_then_apply_sql {sql {dbname main}} { + + sqlite3session S db $dbname + db eval "SELECT name FROM $dbname.sqlite_master WHERE type = 'table'" { S attach $name } @@ -171,10 +172,96 @@ foreach {tn sql} { ROLLBACK; } } { -if {$tn==9} breakpoint do_then_apply_sql $sql - do_test $tn { compare_db db db2 } {} + do_test 1.$tn { compare_db db db2 } {} } +# The following block of tests is similar to the last, except that the +# session object is recording changes made to an attached database. The +# main database contains a table of the same name as the table being +# modified within the attached db. +# +test_reset +forcedelete test.db3 +sqlite3 db3 test.db3 +do_test 2.0 { + execsql { + ATTACH 'test.db3' AS 'aux'; + CREATE TABLE t1(a, b PRIMARY KEY); + CREATE TABLE t2(x, y, z); + CREATE TABLE t3(a); + + CREATE TABLE aux.t1(a PRIMARY KEY, b); + CREATE TABLE aux.t2(a, b INTEGER PRIMARY KEY); + CREATE TABLE aux.t3(a, b, c, PRIMARY KEY(a, b)); + } + execsql { + CREATE TABLE t1(a PRIMARY KEY, b); + CREATE TABLE t2(a, b INTEGER PRIMARY KEY); + CREATE TABLE t3(a, b, c, PRIMARY KEY(a, b)); + } db2 +} {} + +foreach {tn sql} { + 1 { INSERT INTO aux.t1 VALUES(1, 2) } + + 2 { + INSERT INTO aux.t2 VALUES(1, NULL); + INSERT INTO aux.t2 VALUES(2, NULL); + INSERT INTO aux.t2 VALUES(3, NULL); + DELETE FROM aux.t2 WHERE a = 2; + INSERT INTO aux.t2 VALUES(4, NULL); + UPDATE aux.t2 SET b=0 WHERE b=1; + } + + 3 { INSERT INTO aux.t3 SELECT *, NULL FROM aux.t2 } + + 4 { + INSERT INTO aux.t3 SELECT a||a, b||b, NULL FROM aux.t3; + DELETE FROM aux.t3 WHERE rowid%2; + } + + 5 { UPDATE aux.t3 SET c = a||b } + + 6 { UPDATE aux.t1 SET a = 32 } + + 7 { + INSERT INTO aux.t1 SELECT randomblob(32), randomblob(32) FROM aux.t1; + INSERT INTO aux.t1 SELECT randomblob(32), randomblob(32) FROM aux.t1; + INSERT INTO aux.t1 SELECT randomblob(32), randomblob(32) FROM aux.t1; + INSERT INTO aux.t1 SELECT randomblob(32), randomblob(32) FROM aux.t1; + INSERT INTO aux.t1 SELECT randomblob(32), randomblob(32) FROM aux.t1; + INSERT INTO aux.t1 SELECT randomblob(32), randomblob(32) FROM aux.t1; + INSERT INTO aux.t1 SELECT randomblob(32), randomblob(32) FROM aux.t1; + INSERT INTO aux.t1 SELECT randomblob(32), randomblob(32) FROM aux.t1; + INSERT INTO aux.t1 SELECT randomblob(32), randomblob(32) FROM aux.t1; + INSERT INTO aux.t1 SELECT randomblob(32), randomblob(32) FROM aux.t1; + INSERT INTO aux.t1 SELECT randomblob(32), randomblob(32) FROM aux.t1; + DELETE FROM aux.t1 WHERE (rowid%3)==0; + } + + 8 { + BEGIN; + INSERT INTO aux.t1 SELECT randomblob(32), randomblob(32) FROM aux.t1; + ROLLBACK; + } + 9 { + BEGIN; + UPDATE aux.t1 SET b = 'xxx'; + ROLLBACK; + } + 10 { + BEGIN; + DELETE FROM aux.t1 WHERE 1; + ROLLBACK; + } +} { + do_then_apply_sql $sql aux + do_test 2.$tn { compare_db db3 db2 } {} +} + + +catch {db3 close} + finish_test diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index c234f8ce3b..d934fad6a7 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -1191,6 +1191,7 @@ static void sessionAppendUpdate( static int sessionSelectStmt( sqlite3 *db, /* Database handle */ + const char *zDb, /* Database name */ const char *zTab, /* Table name */ int nCol, const char **azCol, @@ -1203,6 +1204,8 @@ static int sessionSelectStmt( SessionBuffer buf = {0, 0, 0}; sessionAppendStr(&buf, "SELECT * FROM ", &rc); + sessionAppendIdent(&buf, zDb, &rc); + sessionAppendStr(&buf, ".", &rc); sessionAppendIdent(&buf, zTab, &rc); sessionAppendStr(&buf, " WHERE ", &rc); for(i=0; ipTable; rc==SQLITE_OK && pTab; pTab=pTab->pNext){ if( pTab->nEntry ){ + const char *zName = pTab->zName; int nCol = pTab->nCol; /* Local copy of member variable */ u8 *abPK = pTab->abPK; /* Local copy of member variable */ int i; /* Used to iterate through hash buckets */ @@ -1323,11 +1327,12 @@ int sqlite3session_changeset( /* Write a table header */ sessionAppendByte(&buf, 'T', &rc); sessionAppendVarint(&buf, nCol, &rc); - sessionAppendBlob(&buf, (u8 *)pTab->zName, strlen(pTab->zName)+1, &rc); + sessionAppendBlob(&buf, (u8 *)zName, strlen(zName)+1, &rc); /* Build and compile a statement to execute: */ if( rc==SQLITE_OK ){ - rc = sessionSelectStmt(db, pTab->zName, nCol, pTab->azCol, abPK, &pSel); + rc = sessionSelectStmt( + db, pSession->zDb, zName, nCol, pTab->azCol, abPK, &pSel); } if( rc==SQLITE_OK && nCol!=sqlite3_column_count(pSel) ){ @@ -1942,7 +1947,8 @@ static int sessionSelectRow( const char *zTab, /* Table name */ SessionApplyCtx *p /* Session changeset-apply context */ ){ - return sessionSelectStmt(db, zTab, p->nCol, p->azCol, p->abPK, &p->pSelect); + return sessionSelectStmt( + db, "main", zTab, p->nCol, p->azCol, p->abPK, &p->pSelect); } /* diff --git a/manifest b/manifest index 44b5abf093..bf593dda01 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sbug\sin\schangeset\sgeneration\scode. -D 2011-03-19T18:46:16 +C Fix\sa\sproblem\sinvolving\ssession\sobjects\sand\sattached\sdatabases. +D 2011-03-19T19:19:26 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -100,8 +100,8 @@ F ext/rtree/sqlite3rtree.h 1af0899c63a688e272d69d8e746f24e76f10a3f0 F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 F ext/session/session1.test 3f982c74ee4ba97069917cc35aae25b4ed858e6a -F ext/session/session2.test 09cbe57d949a315c68fb59822314990fd0e2af33 -F ext/session/sqlite3session.c 4cb15010040b093e452e6de52e8b5a9161032ebf +F ext/session/session2.test 96ff08995ab9935d1992ac554a240052883a0ebc +F ext/session/sqlite3session.c d211ce2e95483dfc144494f6c67879d85dddabfa F ext/session/sqlite3session.h 9551c002efd5fde07c52994c6b592308e0df2d6a F ext/session/test_session.c 2559ef68e421c7fb83e2c19ef08a17343b70d535 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 @@ -921,7 +921,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P c4436a936ab302aec3b7f41a4552f69ad5815744 -R 633c4c2a52a8f04fd2ba1fea02dc8ad5 +P 825df75ba453c853953e17ec29653e11c46f92bb +R 1e82a0bf18f9b8bb4d549f268721a5ef U dan -Z 046a676deaa5ff1f82305a84f859a0a7 +Z 935cff1eff2f640f29c72314cdd47105 diff --git a/manifest.uuid b/manifest.uuid index 40658a2e58..966ef9d6fc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -825df75ba453c853953e17ec29653e11c46f92bb \ No newline at end of file +ad91d30073a8faa7eb064dd2e1cc4d2297d7b3f8 \ No newline at end of file From a2df3d9f95e02214f2bc27faa999f442e3c2c3da Mon Sep 17 00:00:00 2001 From: dan Date: Sun, 20 Mar 2011 11:20:41 +0000 Subject: [PATCH 0023/1484] Documentation format updates to sqlite3session.h. FossilOrigin-Name: f227f60210fba3930f3050aebb1facee8bac9c0b --- ext/session/sqlite3session.h | 50 ++++++++++++++++++++++++++++++++---- manifest | 12 ++++----- manifest.uuid | 2 +- 3 files changed, 52 insertions(+), 12 deletions(-) diff --git a/ext/session/sqlite3session.h b/ext/session/sqlite3session.h index dd0e114f73..2ddad6a8a3 100644 --- a/ext/session/sqlite3session.h +++ b/ext/session/sqlite3session.h @@ -11,10 +11,19 @@ extern "C" { #include "sqlite3.h" +/* +** CAPI3REF: Session Object Handle +*/ typedef struct sqlite3_session sqlite3_session; + +/* +** CAPI3REF: Changeset Iterator Handle +*/ typedef struct sqlite3_changeset_iter sqlite3_changeset_iter; /* +** CAPI3REF: Create A New Session Object +** ** Create a new session object attached to database handle db. If successful, ** a pointer to the new object is written to *ppSession and SQLITE_OK is ** returned. If an error occurs, *ppSession is set to NULL and an SQLite @@ -49,6 +58,8 @@ int sqlite3session_create( ); /* +** CAPI3REF: Delete A Session Object +** ** Delete a session object previously allocated using ** [sqlite3session_create()]. Once a session object has been deleted, the ** results of attempting to use pSession with any other session module @@ -61,6 +72,8 @@ int sqlite3session_create( void sqlite3session_delete(sqlite3_session *pSession); /* +** CAPI3REF: Enable Or Disable A Session Object +** ** Enable or disable the recording of changes by a session object. When ** enabled, a session object records changes made to the database. When ** disabled - it does not. A newly created session object is enabled. @@ -78,6 +91,8 @@ void sqlite3session_delete(sqlite3_session *pSession); int sqlite3session_enable(sqlite3_session *pSession, int bEnable); /* +** CAPI3REF: Attach a Table to a Session Object +** ** Attach a table to a session. All subsequent changes made to the table ** while the session object is enabled will be recorded. See documentation ** for [sqlite3session_changeset()] for further details. @@ -101,6 +116,8 @@ int sqlite3session_attach( ); /* +** CAPI3REF: Generate A Changeset From A Session Object +** ** Obtain a changeset containing changes to the tables attached to the ** session object passed as the first argument. If successful, ** set *ppChangeset to point to a buffer containing the changeset @@ -120,14 +137,14 @@ int sqlite3session_attach( ** ** The contents of a changeset may be traversed using an iterator created ** using the [sqlite3changeset_start()] API. A changeset may be applied to -** a database with a compatible schema using the [sqlite3changset_apply()] +** a database with a compatible schema using the [sqlite3changeset_apply()] ** API. ** ** Following a successful call to this function, it is the responsibility of ** the caller to eventually free the buffer that *ppChangeset points to using ** [sqlite3_free()]. ** -**

Changeset Generation

+**

Changeset Generation

** ** Once a table has been attached to a session object, the session object ** records the primary key values of all new rows inserted into the table. @@ -187,6 +204,8 @@ int sqlite3session_changeset( ); /* +** CAPI3REF: Create An Iterator To Traverse A Changeset +** ** Create an iterator used to iterate through the contents of a changeset. ** If successful, *pp is set to point to the iterator handle and SQLITE_OK ** is returned. Otherwise, if an error occurs, *pp is set to zero and an @@ -214,6 +233,8 @@ int sqlite3changeset_start( ); /* +** CAPI3REF: Advance A Changeset Iterator +** ** This function may only be used with iterators created by function ** [sqlite3changeset_start()]. If it is called on an iterator passed to ** a conflict-handler callback by [sqlite3changeset_apply()], SQLITE_MISUSE @@ -236,6 +257,8 @@ int sqlite3changeset_start( int sqlite3changeset_next(sqlite3_changeset_iter *pIter); /* +** CAPI3REF: Obtain The Current Operation From A Changeset Iterator +** ** The pIter argument passed to this function may either be an iterator ** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator ** created by [sqlite3changeset_start()]. In the latter case, the most recent @@ -264,6 +287,8 @@ int sqlite3changeset_op( ); /* +** CAPI3REF: Obtain old.* Values From A Changeset Iterator +** ** The pIter argument passed to this function may either be an iterator ** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator ** created by [sqlite3changeset_start()]. In the latter case, the most recent @@ -292,6 +317,8 @@ int sqlite3changeset_old( ); /* +** CAPI3REF: Obtain new.* Values From A Changeset Iterator +** ** The pIter argument passed to this function may either be an iterator ** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator ** created by [sqlite3changeset_start()]. In the latter case, the most recent @@ -323,6 +350,8 @@ int sqlite3changeset_new( ); /* +** CAPI3REF: Obtain Conflicting Row Values From A Changeset Iterator +** ** This function should only be used with iterator objects passed to a ** conflict-handler callback by [sqlite3changeset_apply()] with either ** SQLITE_CHANGESET_DATA or SQLITE_CHANGESET_CONFLICT. If this function @@ -349,7 +378,10 @@ int sqlite3changeset_conflict( /* -** Finalize an iterator allocated with sqlite3changeset_start(). +** CAPI3REF: Finalize a Changeset Iterator +** +** This function is used to finalize an iterator allocated with +** sqlite3changeset_start(). ** ** This function should only be called on iterators created using the ** [sqlite3changeset_start()] function. If an application calls this @@ -375,6 +407,8 @@ int sqlite3changeset_conflict( int sqlite3changeset_finalize(sqlite3_changeset_iter *pIter); /* +** CAPI3REF: Invert A Changeset +** ** This function is used to "invert" a changeset object. Applying an inverted ** changeset to a database reverses the effects of applying the uninverted ** changeset. Specifically: @@ -400,6 +434,8 @@ int sqlite3changeset_invert( ); /* +** CAPI3REF: Apply A Changeset To A Database +** ** Apply a changeset to a database. This function attempts to update the ** "main" database attached to handle db with the changes found in the ** changeset passed via the second and third arguments. @@ -482,7 +518,7 @@ int sqlite3changeset_invert( ** [SQLITE_CHANGESET_REPLACE]. ** **
UPDATE Changes
-** For each DELETE change, this function checks if the target database +** For each UPDATE change, this function checks if the target database ** contains a row with the same primary key value (or values) as the ** original row values stored in the changeset. If it does, and the values ** stored in all non-primary key columns also match the values stored in @@ -532,6 +568,8 @@ int sqlite3changeset_apply( ); /* +** CAPI3REF: Constants Passed to The Conflict Handler +** ** Values that may be passed as the second argument to a conflict-handler. ** **
@@ -576,7 +614,9 @@ int sqlite3changeset_apply( #define SQLITE_CHANGESET_CONSTRAINT 4 /* -** Valid return values from a conflict-handler. +** CAPI3REF: Constants Returned By The Conflict Handler +** +** A conflict handler callback must return one of the following three values. ** **
**
SQLITE_CHANGESET_OMIT
diff --git a/manifest b/manifest index bf593dda01..7a06b76e97 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\sinvolving\ssession\sobjects\sand\sattached\sdatabases. -D 2011-03-19T19:19:26 +C Documentation\sformat\supdates\sto\ssqlite3session.h. +D 2011-03-20T11:20:41 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -102,7 +102,7 @@ F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 F ext/session/session1.test 3f982c74ee4ba97069917cc35aae25b4ed858e6a F ext/session/session2.test 96ff08995ab9935d1992ac554a240052883a0ebc F ext/session/sqlite3session.c d211ce2e95483dfc144494f6c67879d85dddabfa -F ext/session/sqlite3session.h 9551c002efd5fde07c52994c6b592308e0df2d6a +F ext/session/sqlite3session.h 3b99c2498ca86c8d45b29d3956225e09faabc414 F ext/session/test_session.c 2559ef68e421c7fb83e2c19ef08a17343b70d535 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 @@ -921,7 +921,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 825df75ba453c853953e17ec29653e11c46f92bb -R 1e82a0bf18f9b8bb4d549f268721a5ef +P ad91d30073a8faa7eb064dd2e1cc4d2297d7b3f8 +R b83a18c2f45208301f57e8f22417178c U dan -Z 935cff1eff2f640f29c72314cdd47105 +Z e800e514ce176ffa56c1f9535016cce8 diff --git a/manifest.uuid b/manifest.uuid index 966ef9d6fc..c0fb35d699 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ad91d30073a8faa7eb064dd2e1cc4d2297d7b3f8 \ No newline at end of file +f227f60210fba3930f3050aebb1facee8bac9c0b \ No newline at end of file From 77e65004737c9c974838729e6de5c4ae52f1853c Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 21 Mar 2011 07:23:09 +0000 Subject: [PATCH 0024/1484] Fix some typos in sqlite3session.h. FossilOrigin-Name: 0853e530cc8d96f025f5160540e8ab3243dea11b --- ext/session/sqlite3session.h | 36 ++++++++++++++++++------------------ manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 25 insertions(+), 25 deletions(-) diff --git a/ext/session/sqlite3session.h b/ext/session/sqlite3session.h index 2ddad6a8a3..2819bfece6 100644 --- a/ext/session/sqlite3session.h +++ b/ext/session/sqlite3session.h @@ -262,8 +262,8 @@ int sqlite3changeset_next(sqlite3_changeset_iter *pIter); ** The pIter argument passed to this function may either be an iterator ** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator ** created by [sqlite3changeset_start()]. In the latter case, the most recent -** call to [sqlite3changeset_next()] must have returned SQLITE_ROW. If this -** is not the case, this function returns SQLITE_MISUSE. +** call to [sqlite3changeset_next()] must have returned [SQLITE_ROW]. If this +** is not the case, this function returns [SQLITE_MISUSE]. ** ** If argument pzTab is not NULL, then *pzTab is set to point to a ** nul-terminated utf-8 encoded string containing the name of the table @@ -271,9 +271,9 @@ int sqlite3changeset_next(sqlite3_changeset_iter *pIter); ** sqlite3changeset_next() is called on the iterator or until the ** conflict-handler function returns. If pnCol is not NULL, then *pnCol is ** set to the number of columns in the table affected by the change. Finally, -** if pOp is not NULL, then *pOp is set to one of SQLITE_INSERT, SQLITE_DELETE -** or SQLITE_UPDATE, depending on the type of change that the iterator -** currently points to. +** if pOp is not NULL, then *pOp is set to one of [SQLITE_INSERT], +** [SQLITE_DELETE] or [SQLITE_UPDATE], depending on the type of change that +** the iterator currently points to. ** ** If no error occurs, SQLITE_OK is returned. If an error does occur, an ** SQLite error code is returned. The values of the output variables may not @@ -294,12 +294,12 @@ int sqlite3changeset_op( ** created by [sqlite3changeset_start()]. In the latter case, the most recent ** call to [sqlite3changeset_next()] must have returned SQLITE_ROW. ** Furthermore, it may only be called if the type of change that the iterator -** currently points to is either SQLITE_DELETE or SQLITE_UPDATE. Otherwise, -** this function returns SQLITE_MISUSE and sets *ppValue to NULL. +** currently points to is either [SQLITE_DELETE] or [SQLITE_UPDATE]. Otherwise, +** this function returns [SQLITE_MISUSE] and sets *ppValue to NULL. ** ** Argument iVal must be greater than or equal to 0, and less than the number ** of columns in the table affected by the current change. Otherwise, -** SQLITE_RANGE is returned and *ppValue is set to NULL. +** [SQLITE_RANGE] is returned and *ppValue is set to NULL. ** ** If successful, this function sets *ppValue to point to a protected ** sqlite3_value object containing the iVal'th value from the vector of @@ -324,12 +324,12 @@ int sqlite3changeset_old( ** created by [sqlite3changeset_start()]. In the latter case, the most recent ** call to [sqlite3changeset_next()] must have returned SQLITE_ROW. ** Furthermore, it may only be called if the type of change that the iterator -** currently points to is either SQLITE_UPDATE or SQLITE_INSERT. Otherwise, -** this function returns SQLITE_MISUSE and sets *ppValue to NULL. +** currently points to is either [SQLITE_UPDATE] or [SQLITE_INSERT]. Otherwise, +** this function returns [SQLITE_MISUSE] and sets *ppValue to NULL. ** ** Argument iVal must be greater than or equal to 0, and less than the number ** of columns in the table affected by the current change. Otherwise, -** SQLITE_RANGE is returned and *ppValue is set to NULL. +** [SQLITE_RANGE] is returned and *ppValue is set to NULL. ** ** If successful, this function sets *ppValue to point to a protected ** sqlite3_value object containing the iVal'th value from the vector of @@ -354,13 +354,13 @@ int sqlite3changeset_new( ** ** This function should only be used with iterator objects passed to a ** conflict-handler callback by [sqlite3changeset_apply()] with either -** SQLITE_CHANGESET_DATA or SQLITE_CHANGESET_CONFLICT. If this function -** is called on any other iterator, SQLITE_MISUSE is returned and *ppValue +** [SQLITE_CHANGESET_DATA] or [SQLITE_CHANGESET_CONFLICT]. If this function +** is called on any other iterator, [SQLITE_MISUSE] is returned and *ppValue ** is set to NULL. ** ** Argument iVal must be greater than or equal to 0, and less than the number ** of columns in the table affected by the current change. Otherwise, -** SQLITE_RANGE is returned and *ppValue is set to NULL. +** [SQLITE_RANGE] is returned and *ppValue is set to NULL. ** ** If successful, this function sets *ppValue to point to a protected ** sqlite3_value object containing the iVal'th value from the @@ -381,17 +381,17 @@ int sqlite3changeset_conflict( ** CAPI3REF: Finalize a Changeset Iterator ** ** This function is used to finalize an iterator allocated with -** sqlite3changeset_start(). +** [sqlite3changeset_start()]. ** ** This function should only be called on iterators created using the ** [sqlite3changeset_start()] function. If an application calls this ** function with an iterator passed to a conflict-handler by -** [sqlite3changeset_apply()], SQLITE_MISUSE is immediately returned and the +** [sqlite3changeset_apply()], [SQLITE_MISUSE] is immediately returned and the ** call has no effect. ** ** If an error was encountered within a call to an sqlite3changeset_xxx() -** function (for example an SQLITE_CORRUPT in sqlite3changeset_next() or an -** SQLITE_NOMEM in sqlite3changeset_new()) then an error code corresponding +** function (for example an [SQLITE_CORRUPT] in [sqlite3changeset_next()] or an +** [SQLITE_NOMEM] in [sqlite3changeset_new()]) then an error code corresponding ** to that error is returned by this function. Otherwise, SQLITE_OK is ** returned. This is to allow the following pattern (pseudo-code): ** diff --git a/manifest b/manifest index 7a06b76e97..b318127f95 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Documentation\sformat\supdates\sto\ssqlite3session.h. -D 2011-03-20T11:20:41 +C Fix\ssome\stypos\sin\ssqlite3session.h. +D 2011-03-21T07:23:09 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -102,7 +102,7 @@ F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 F ext/session/session1.test 3f982c74ee4ba97069917cc35aae25b4ed858e6a F ext/session/session2.test 96ff08995ab9935d1992ac554a240052883a0ebc F ext/session/sqlite3session.c d211ce2e95483dfc144494f6c67879d85dddabfa -F ext/session/sqlite3session.h 3b99c2498ca86c8d45b29d3956225e09faabc414 +F ext/session/sqlite3session.h b77b014793162a77ac16507d720fe085cc15d06c F ext/session/test_session.c 2559ef68e421c7fb83e2c19ef08a17343b70d535 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 @@ -921,7 +921,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P ad91d30073a8faa7eb064dd2e1cc4d2297d7b3f8 -R b83a18c2f45208301f57e8f22417178c +P f227f60210fba3930f3050aebb1facee8bac9c0b +R 1d7fc8f92183ec1b52bc0fb00c30936f U dan -Z e800e514ce176ffa56c1f9535016cce8 +Z c7cce5161a77eeb6aa8085cb909dead1 diff --git a/manifest.uuid b/manifest.uuid index c0fb35d699..781e099e42 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f227f60210fba3930f3050aebb1facee8bac9c0b \ No newline at end of file +0853e530cc8d96f025f5160540e8ab3243dea11b \ No newline at end of file From 4e895da185c5571094cbdc45a76f62abb631c65d Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 21 Mar 2011 11:03:24 +0000 Subject: [PATCH 0025/1484] Fix session module problems with real (floating point) values. FossilOrigin-Name: a192d04f4e3a9e4960a4d96d1d3ee8635bc1034d --- ext/session/session2.test | 14 ++++++++++++++ ext/session/sqlite3session.c | 8 ++++---- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 26 insertions(+), 12 deletions(-) diff --git a/ext/session/session2.test b/ext/session/session2.test index 453dc627a2..5411563f2e 100644 --- a/ext/session/session2.test +++ b/ext/session/session2.test @@ -105,6 +105,11 @@ do_iterator_test 1.1 t1 { {DELETE t1 {t i t one} {}} {INSERT t1 {} {t ii t two}} } +do_iterator_test 1.1 t1 { + INSERT INTO t1 VALUES(1.5, 99.9) +} { + {INSERT t1 {} {f 1.5 f 99.9}} +} test_reset do_common_sql { @@ -202,7 +207,10 @@ do_test 2.0 { } db2 } {} +proc xTrace {args} { puts $args } + foreach {tn sql} { + 1 { INSERT INTO aux.t1 VALUES(1, 2) } 2 { @@ -255,6 +263,12 @@ foreach {tn sql} { DELETE FROM aux.t1 WHERE 1; ROLLBACK; } + 11 { + INSERT INTO aux.t1 VALUES(randomblob(21000), randomblob(0)); + INSERT INTO aux.t1 VALUES(1.5, 1.5); + INSERT INTO aux.t1 VALUES(4.56, -99.999999999999999999999); + } + } { do_then_apply_sql $sql aux do_test 2.$tn { compare_db db3 db2 } {} diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index d934fad6a7..676ea3b44c 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -245,10 +245,10 @@ static int sessionSerializeValue( nByte = 9; break; - case SQLITE_TEXT: - case SQLITE_BLOB: { + default: { int n = sqlite3_value_bytes(pValue); int nVarint = sessionVarintLen(n); + assert( eType==SQLITE_TEXT || eType==SQLITE_BLOB ); if( aBuf ){ sessionVarintPut(&aBuf[1], n); memcpy(&aBuf[nVarint + 1], eType==SQLITE_TEXT ? @@ -1257,7 +1257,7 @@ static int sessionSelectBind( double rVal; i64 iVal = sessionGetI64(a); memcpy(&rVal, &iVal, 8); - rc = sqlite3_bind_int64(pSelect, i+1, rVal); + rc = sqlite3_bind_double(pSelect, i+1, rVal); } a += 8; break; @@ -1481,7 +1481,7 @@ static int sessionReadRecord( sqlite3VdbeMemSetInt64(apOut[i], v); }else{ double d; - memcpy(&d, &i, 8); + memcpy(&d, &v, 8); sqlite3VdbeMemSetDouble(apOut[i], d); } } diff --git a/manifest b/manifest index b318127f95..46016a2034 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\ssome\stypos\sin\ssqlite3session.h. -D 2011-03-21T07:23:09 +C Fix\ssession\smodule\sproblems\swith\sreal\s(floating\spoint)\svalues. +D 2011-03-21T11:03:25 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -100,8 +100,8 @@ F ext/rtree/sqlite3rtree.h 1af0899c63a688e272d69d8e746f24e76f10a3f0 F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 F ext/session/session1.test 3f982c74ee4ba97069917cc35aae25b4ed858e6a -F ext/session/session2.test 96ff08995ab9935d1992ac554a240052883a0ebc -F ext/session/sqlite3session.c d211ce2e95483dfc144494f6c67879d85dddabfa +F ext/session/session2.test 45c9ff2052bf132d25d272b1d4b53f95c1c31463 +F ext/session/sqlite3session.c 3ed836ee8c6faff866bc59da800b6f20b0285071 F ext/session/sqlite3session.h b77b014793162a77ac16507d720fe085cc15d06c F ext/session/test_session.c 2559ef68e421c7fb83e2c19ef08a17343b70d535 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 @@ -921,7 +921,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P f227f60210fba3930f3050aebb1facee8bac9c0b -R 1d7fc8f92183ec1b52bc0fb00c30936f +P 0853e530cc8d96f025f5160540e8ab3243dea11b +R 482fc377ccc3f262af8beae8e4f384bf U dan -Z c7cce5161a77eeb6aa8085cb909dead1 +Z 767fabeb255e365fd4d794b5ace5ff7b diff --git a/manifest.uuid b/manifest.uuid index 781e099e42..e7426fdf05 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0853e530cc8d96f025f5160540e8ab3243dea11b \ No newline at end of file +a192d04f4e3a9e4960a4d96d1d3ee8635bc1034d \ No newline at end of file From 27453faef872f35e90984d9a083e0fcb3e547e18 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 21 Mar 2011 11:55:06 +0000 Subject: [PATCH 0026/1484] Clarify handling of NULL values in PK columns in sqlite3session.h. Add tests and fixes for the same. FossilOrigin-Name: aed4273054cbd150c86b36ea951d17c981633ba0 --- ext/session/session2.test | 243 +++++++++++++++++------------------ ext/session/sqlite3session.c | 171 ++++++++++++------------ ext/session/sqlite3session.h | 17 +++ manifest | 16 +-- manifest.uuid | 2 +- 5 files changed, 235 insertions(+), 214 deletions(-) diff --git a/ext/session/session2.test b/ext/session/session2.test index 5411563f2e..357b806043 100644 --- a/ext/session/session2.test +++ b/ext/session/session2.test @@ -111,6 +111,75 @@ do_iterator_test 1.1 t1 { {INSERT t1 {} {f 1.5 f 99.9}} } +# Execute each of the following blocks of SQL on database [db1]. Collect +# changes using a session object. Apply the resulting changeset to +# database [db2]. Then check that the contents of the two databases are +# identical. +# + +set set_of_tests { + 1 { INSERT INTO %T1% VALUES(1, 2) } + + 2 { + INSERT INTO %T2% VALUES(1, NULL); + INSERT INTO %T2% VALUES(2, NULL); + INSERT INTO %T2% VALUES(3, NULL); + DELETE FROM %T2% WHERE a = 2; + INSERT INTO %T2% VALUES(4, NULL); + UPDATE %T2% SET b=0 WHERE b=1; + } + + 3 { INSERT INTO %T3% SELECT *, NULL FROM %T2% } + + 4 { + INSERT INTO %T3% SELECT a||a, b||b, NULL FROM %T3%; + DELETE FROM %T3% WHERE rowid%2; + } + + 5 { UPDATE %T3% SET c = a||b } + + 6 { UPDATE %T1% SET a = 32 } + + 7 { + INSERT INTO %T1% SELECT randomblob(32), randomblob(32) FROM %T1%; + INSERT INTO %T1% SELECT randomblob(32), randomblob(32) FROM %T1%; + INSERT INTO %T1% SELECT randomblob(32), randomblob(32) FROM %T1%; + INSERT INTO %T1% SELECT randomblob(32), randomblob(32) FROM %T1%; + INSERT INTO %T1% SELECT randomblob(32), randomblob(32) FROM %T1%; + INSERT INTO %T1% SELECT randomblob(32), randomblob(32) FROM %T1%; + INSERT INTO %T1% SELECT randomblob(32), randomblob(32) FROM %T1%; + INSERT INTO %T1% SELECT randomblob(32), randomblob(32) FROM %T1%; + INSERT INTO %T1% SELECT randomblob(32), randomblob(32) FROM %T1%; + INSERT INTO %T1% SELECT randomblob(32), randomblob(32) FROM %T1%; + INSERT INTO %T1% SELECT randomblob(32), randomblob(32) FROM %T1%; + DELETE FROM %T1% WHERE (rowid%3)==0; + } + + 8 { + BEGIN; + INSERT INTO %T1% SELECT randomblob(32), randomblob(32) FROM %T1%; + ROLLBACK; + } + 9 { + BEGIN; + UPDATE %T1% SET b = 'xxx'; + ROLLBACK; + } + 10 { + BEGIN; + DELETE FROM %T1% WHERE 1; + ROLLBACK; + } + 11 { + INSERT INTO %T1% VALUES(randomblob(21000), randomblob(0)); + INSERT INTO %T1% VALUES(1.5, 1.5); + INSERT INTO %T1% VALUES(4.56, -99.999999999999999999999); + } + 12 { + INSERT INTO %T2% VALUES(NULL, NULL); + } +} + test_reset do_common_sql { CREATE TABLE t1(a PRIMARY KEY, b); @@ -118,65 +187,7 @@ do_common_sql { CREATE TABLE t3(a, b, c, PRIMARY KEY(a, b)); } -# Execute each of the following blocks of SQL on database [db1]. Collect -# changes using a session object. Apply the resulting changeset to -# database [db2]. Then check that the contents of the two databases are -# identical. -# -foreach {tn sql} { - 1 { INSERT INTO t1 VALUES(1, 2) } - - 2 { - INSERT INTO t2 VALUES(1, NULL); - INSERT INTO t2 VALUES(2, NULL); - INSERT INTO t2 VALUES(3, NULL); - DELETE FROM t2 WHERE a = 2; - INSERT INTO t2 VALUES(4, NULL); - UPDATE t2 SET b=0 WHERE b=1; - } - - 3 { INSERT INTO t3 SELECT *, NULL FROM t2 } - - 4 { - INSERT INTO t3 SELECT a||a, b||b, NULL FROM t3; - DELETE FROM t3 WHERE rowid%2; - } - - 5 { UPDATE t3 SET c = a||b } - - 6 { UPDATE t1 SET a = 32 } - - 7 { - INSERT INTO t1 SELECT randomblob(32), randomblob(32) FROM t1; -- 2 - INSERT INTO t1 SELECT randomblob(32), randomblob(32) FROM t1; -- 4 - INSERT INTO t1 SELECT randomblob(32), randomblob(32) FROM t1; -- 8 - INSERT INTO t1 SELECT randomblob(32), randomblob(32) FROM t1; -- 16 - INSERT INTO t1 SELECT randomblob(32), randomblob(32) FROM t1; -- 32 - INSERT INTO t1 SELECT randomblob(32), randomblob(32) FROM t1; -- 64 - INSERT INTO t1 SELECT randomblob(32), randomblob(32) FROM t1; -- 128 - INSERT INTO t1 SELECT randomblob(32), randomblob(32) FROM t1; -- 256 - INSERT INTO t1 SELECT randomblob(32), randomblob(32) FROM t1; -- 512 - INSERT INTO t1 SELECT randomblob(32), randomblob(32) FROM t1; -- 1024 - INSERT INTO t1 SELECT randomblob(32), randomblob(32) FROM t1; -- 2048 - DELETE FROM t1 WHERE (rowid%3)==0; - } - - 8 { - BEGIN; - INSERT INTO t1 SELECT randomblob(32), randomblob(32) FROM t1; - ROLLBACK; - } - 9 { - BEGIN; - UPDATE t1 SET b = 'xxx'; - ROLLBACK; - } - 10 { - BEGIN; - DELETE FROM t1 WHERE 1; - ROLLBACK; - } -} { +foreach {tn sql} [string map {%T1% t1 %T2% t2 %T3% t3} $set_of_tests] { do_then_apply_sql $sql do_test 1.$tn { compare_db db db2 } {} } @@ -209,73 +220,61 @@ do_test 2.0 { proc xTrace {args} { puts $args } -foreach {tn sql} { - - 1 { INSERT INTO aux.t1 VALUES(1, 2) } - - 2 { - INSERT INTO aux.t2 VALUES(1, NULL); - INSERT INTO aux.t2 VALUES(2, NULL); - INSERT INTO aux.t2 VALUES(3, NULL); - DELETE FROM aux.t2 WHERE a = 2; - INSERT INTO aux.t2 VALUES(4, NULL); - UPDATE aux.t2 SET b=0 WHERE b=1; - } - - 3 { INSERT INTO aux.t3 SELECT *, NULL FROM aux.t2 } - - 4 { - INSERT INTO aux.t3 SELECT a||a, b||b, NULL FROM aux.t3; - DELETE FROM aux.t3 WHERE rowid%2; - } - - 5 { UPDATE aux.t3 SET c = a||b } - - 6 { UPDATE aux.t1 SET a = 32 } - - 7 { - INSERT INTO aux.t1 SELECT randomblob(32), randomblob(32) FROM aux.t1; - INSERT INTO aux.t1 SELECT randomblob(32), randomblob(32) FROM aux.t1; - INSERT INTO aux.t1 SELECT randomblob(32), randomblob(32) FROM aux.t1; - INSERT INTO aux.t1 SELECT randomblob(32), randomblob(32) FROM aux.t1; - INSERT INTO aux.t1 SELECT randomblob(32), randomblob(32) FROM aux.t1; - INSERT INTO aux.t1 SELECT randomblob(32), randomblob(32) FROM aux.t1; - INSERT INTO aux.t1 SELECT randomblob(32), randomblob(32) FROM aux.t1; - INSERT INTO aux.t1 SELECT randomblob(32), randomblob(32) FROM aux.t1; - INSERT INTO aux.t1 SELECT randomblob(32), randomblob(32) FROM aux.t1; - INSERT INTO aux.t1 SELECT randomblob(32), randomblob(32) FROM aux.t1; - INSERT INTO aux.t1 SELECT randomblob(32), randomblob(32) FROM aux.t1; - DELETE FROM aux.t1 WHERE (rowid%3)==0; - } - - 8 { - BEGIN; - INSERT INTO aux.t1 SELECT randomblob(32), randomblob(32) FROM aux.t1; - ROLLBACK; - } - 9 { - BEGIN; - UPDATE aux.t1 SET b = 'xxx'; - ROLLBACK; - } - 10 { - BEGIN; - DELETE FROM aux.t1 WHERE 1; - ROLLBACK; - } - 11 { - INSERT INTO aux.t1 VALUES(randomblob(21000), randomblob(0)); - INSERT INTO aux.t1 VALUES(1.5, 1.5); - INSERT INTO aux.t1 VALUES(4.56, -99.999999999999999999999); - } - -} { +foreach {tn sql} [ + string map {%T1% aux.t1 %T2% aux.t2 %T3% aux.t3} $set_of_tests +] { do_then_apply_sql $sql aux do_test 2.$tn { compare_db db3 db2 } {} } - - catch {db3 close} + +#------------------------------------------------------------------------- +# The following tests verify that NULL values in primary key columns are +# handled correctly by the session module. +# +test_reset +do_execsql_test 3.0 { + CREATE TABLE t1(a PRIMARY KEY); + CREATE TABLE t2(a, b, c, PRIMARY KEY(c, b)); + CREATE TABLE t3(a, b INTEGER PRIMARY KEY); +} + +foreach {tn sql changeset} { + 1 { + INSERT INTO t1 VALUES(123); + INSERT INTO t1 VALUES(NULL); + INSERT INTO t1 VALUES(456); + } { + {INSERT t1 {} {i 456}} + {INSERT t1 {} {i 123}} + } + + 2 { + UPDATE t1 SET a = NULL; + } { + {DELETE t1 {i 456} {}} + {DELETE t1 {i 123} {}} + } + + 3 { DELETE FROM t1 } { } + + 4 { + INSERT INTO t3 VALUES(NULL, NULL) + } { + {INSERT t3 {} {n {} i 1}} + } + + 5 { INSERT INTO t2 VALUES(1, 2, NULL) } { } + 6 { INSERT INTO t2 VALUES(1, NULL, 3) } { } + 7 { INSERT INTO t2 VALUES(1, NULL, NULL) } { } + 8 { INSERT INTO t2 VALUES(1, 2, 3) } { {INSERT t2 {} {i 1 i 2 i 3}} } + 9 { DELETE FROM t2 WHERE 1 } { {DELETE t2 {i 1 i 2 i 3} {}} } + +} { + do_iterator_test 3.$tn {t1 t2 t3} $sql $changeset +} + + finish_test diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index 676ea3b44c..4663938bb2 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -286,11 +286,13 @@ static unsigned int sessionPreupdateHash( sqlite3 *db, /* Database handle */ SessionTable *pTab, /* Session table handle */ int bNew, /* True to hash the new.* PK */ - int *piHash /* OUT: Hash value */ + int *piHash, /* OUT: Hash value */ + int *pbNullPK ){ unsigned int h = 0; /* Hash value to return */ int i; /* Used to iterate through columns */ + assert( *pbNullPK==0 ); assert( pTab->nCol==sqlite3_preupdate_count(db) ); for(i=0; inCol; i++){ if( pTab->abPK[i] ){ @@ -329,6 +331,11 @@ static unsigned int sessionPreupdateHash( h = sessionHashAppendBlob(h, n, z); break; } + + default: + assert( eType==SQLITE_NULL ); + *pbNullPK = 1; + return SQLITE_OK; } } } @@ -357,27 +364,22 @@ static unsigned int sessionChangeHash( int eType = *a++; int isPK = pTab->abPK[i]; + /* It is not possible for eType to be SQLITE_NULL here. The session + ** module does not record changes for rows with NULL values stored in + ** primary key columns. */ + assert( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT + || eType==SQLITE_TEXT || eType==SQLITE_BLOB + ); + if( isPK ) h = HASH_APPEND(h, eType); - switch( eType ){ - case SQLITE_INTEGER: - case SQLITE_FLOAT: { - if( isPK ){ - i64 iVal = sessionGetI64(a); - h = sessionHashAppendI64(h, iVal); - } - a += 8; - break; - } - case SQLITE_TEXT: - case SQLITE_BLOB: { - int n; - a += sessionVarintGet(a, &n); - if( isPK ){ - h = sessionHashAppendBlob(h, n, a); - } - a += n; - break; - } + if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){ + if( isPK ) h = sessionHashAppendI64(h, sessionGetI64(a)); + a += 8; + }else{ + int n; + a += sessionVarintGet(a, &n); + if( isPK ) h = sessionHashAppendBlob(h, n, a); + a += n; } } return (h % nBucket); @@ -665,6 +667,7 @@ static void sessionPreupdateOneChange( SessionChange *pChange; SessionChange *pC; int iHash; + int bNullPk = 0; int rc = SQLITE_OK; if( pSession->rc ) return; @@ -676,71 +679,73 @@ static void sessionPreupdateOneChange( if( sessionGrowHash(pSession, pTab) ) return; /* Search the hash table for an existing entry for rowid=iKey2. If - ** one is found, store a pointer to it in pChange and unlink it from - ** the hash table. Otherwise, set pChange to NULL. - */ - rc = sessionPreupdateHash(db, pTab, op==SQLITE_INSERT, &iHash); - for(pC=pTab->apChange[iHash]; rc==SQLITE_OK && pC; pC=pC->pNext){ - int bEqual; - rc = sessionPreupdateEqual(db, pTab, pC, op==SQLITE_INSERT, &bEqual); - if( bEqual ) break; - } - if( pC==0 ){ - /* Create a new change object containing all the old values (if - ** this is an SQLITE_UPDATE or SQLITE_DELETE), or just the PK - ** values (if this is an INSERT). */ - int nByte; /* Number of bytes to allocate */ - int i; /* Used to iterate through columns */ - - pTab->nEntry++; - - /* Figure out how large an allocation is required */ - nByte = sizeof(SessionChange); - for(i=0; inCol && rc==SQLITE_OK; i++){ - sqlite3_value *p = 0; - if( op!=SQLITE_INSERT ){ - rc = sqlite3_preupdate_old(pSession->db, i, &p); - }else if( 1 || pTab->abPK[i] ){ - rc = sqlite3_preupdate_new(pSession->db, i, &p); - } - if( p && rc==SQLITE_OK ){ - rc = sessionSerializeValue(0, p, &nByte); - } + ** one is found, store a pointer to it in pChange and unlink it from + ** the hash table. Otherwise, set pChange to NULL. + */ + rc = sessionPreupdateHash(db, pTab, op==SQLITE_INSERT, &iHash, &bNullPk); + if( bNullPk==0 ){ + for(pC=pTab->apChange[iHash]; rc==SQLITE_OK && pC; pC=pC->pNext){ + int bEqual; + rc = sessionPreupdateEqual(db, pTab, pC, op==SQLITE_INSERT, &bEqual); + if( bEqual ) break; } - - /* Allocate the change object */ - pChange = (SessionChange *)sqlite3_malloc(nByte); - if( !pChange ){ - rc = SQLITE_NOMEM; - }else{ - memset(pChange, 0, sizeof(SessionChange)); - pChange->aRecord = (u8 *)&pChange[1]; - } - - /* Populate the change object */ - nByte = 0; - for(i=0; inCol && rc==SQLITE_OK; i++){ - sqlite3_value *p = 0; - if( op!=SQLITE_INSERT ){ - rc = sqlite3_preupdate_old(pSession->db, i, &p); - }else if( 1 || pTab->abPK[i] ){ - rc = sqlite3_preupdate_new(pSession->db, i, &p); + if( pC==0 ){ + /* Create a new change object containing all the old values (if + ** this is an SQLITE_UPDATE or SQLITE_DELETE), or just the PK + ** values (if this is an INSERT). */ + int nByte; /* Number of bytes to allocate */ + int i; /* Used to iterate through columns */ + + pTab->nEntry++; + + /* Figure out how large an allocation is required */ + nByte = sizeof(SessionChange); + for(i=0; inCol && rc==SQLITE_OK; i++){ + sqlite3_value *p = 0; + if( op!=SQLITE_INSERT ){ + rc = sqlite3_preupdate_old(pSession->db, i, &p); + }else if( 1 || pTab->abPK[i] ){ + rc = sqlite3_preupdate_new(pSession->db, i, &p); + } + if( p && rc==SQLITE_OK ){ + rc = sessionSerializeValue(0, p, &nByte); + } } - if( p && rc==SQLITE_OK ){ - rc = sessionSerializeValue(&pChange->aRecord[nByte], p, &nByte); + + /* Allocate the change object */ + pChange = (SessionChange *)sqlite3_malloc(nByte); + if( !pChange ){ + rc = SQLITE_NOMEM; + }else{ + memset(pChange, 0, sizeof(SessionChange)); + pChange->aRecord = (u8 *)&pChange[1]; + } + + /* Populate the change object */ + nByte = 0; + for(i=0; inCol && rc==SQLITE_OK; i++){ + sqlite3_value *p = 0; + if( op!=SQLITE_INSERT ){ + rc = sqlite3_preupdate_old(pSession->db, i, &p); + }else if( 1 || pTab->abPK[i] ){ + rc = sqlite3_preupdate_new(pSession->db, i, &p); + } + if( p && rc==SQLITE_OK ){ + rc = sessionSerializeValue(&pChange->aRecord[nByte], p, &nByte); + } + } + pChange->nRecord = nByte; + + /* If an error has occurred, mark the session object as failed. */ + if( rc!=SQLITE_OK ){ + sqlite3_free(pChange); + pSession->rc = rc; + }else{ + /* Add the change back to the hash-table */ + pChange->bInsert = (op==SQLITE_INSERT); + pChange->pNext = pTab->apChange[iHash]; + pTab->apChange[iHash] = pChange; } - } - pChange->nRecord = nByte; - - /* If an error has occurred, mark the session object as failed. */ - if( rc!=SQLITE_OK ){ - sqlite3_free(pChange); - pSession->rc = rc; - }else{ - /* Add the change back to the hash-table */ - pChange->bInsert = (op==SQLITE_INSERT); - pChange->pNext = pTab->apChange[iHash]; - pTab->apChange[iHash] = pChange; } } } diff --git a/ext/session/sqlite3session.h b/ext/session/sqlite3session.h index 2819bfece6..44b58eada8 100644 --- a/ext/session/sqlite3session.h +++ b/ext/session/sqlite3session.h @@ -106,6 +106,9 @@ int sqlite3session_enable(sqlite3_session *pSession, int bEnable); ** is it an error if the named table does not have a PRIMARY KEY. However, ** no changes will be recorded in either of these scenarios. ** +** Changes are not recorded for individual rows that have NULL values stored +** in one or more of their PRIMARY KEY columns. +** ** SQLITE_OK is returned if the table is successfully attached to the session ** object. Or, if an error occurs, an SQLite error code (e.g. SQLITE_NOMEM) ** is returned. @@ -135,6 +138,16 @@ int sqlite3session_attach( ** modifies the values of primary key columns. If such a change is made, it ** is represented in a changeset as a DELETE followed by an INSERT. ** +** Changes are not recorded for rows that have NULL values stored in one or +** more of their PRIMARY KEY columns. If such a row is inserted or deleted, +** no corresponding change is present in the changesets returned by this +** function. If an existing row with one or more NULL values stored in +** PRIMARY KEY columns is updated so that all PRIMARY KEY columns are non-NULL, +** only an INSERT is appears in the changeset. Similarly, if an existing row +** with non-NULL PRIMARY KEY values is updated so that one or more of its +** PRIMARY KEY columns are set to NULL, the resulting changeset contains a +** DELETE change only. +** ** The contents of a changeset may be traversed using an iterator created ** using the [sqlite3changeset_start()] API. A changeset may be applied to ** a database with a compatible schema using the [sqlite3changeset_apply()] @@ -153,6 +166,10 @@ int sqlite3session_attach( ** recorded once - the first time a row with said primary key is inserted, ** updated or deleted in the lifetime of the session. ** +** There is one exception to the previous paragraph: when a row is inserted, +** updated or deleted, if one or more of its primary key columns contains a +** NULL value, no record of the change is made. +** ** The session object therefore accumulates two types of records - those ** that consist of primary key values only (created when the user inserts ** a new record) and those that consist of the primary key values and the diff --git a/manifest b/manifest index 46016a2034..63945fc241 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\ssession\smodule\sproblems\swith\sreal\s(floating\spoint)\svalues. -D 2011-03-21T11:03:25 +C Clarify\shandling\sof\sNULL\svalues\sin\sPK\scolumns\sin\ssqlite3session.h.\sAdd\stests\sand\sfixes\sfor\sthe\ssame. +D 2011-03-21T11:55:07 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -100,9 +100,9 @@ F ext/rtree/sqlite3rtree.h 1af0899c63a688e272d69d8e746f24e76f10a3f0 F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 F ext/session/session1.test 3f982c74ee4ba97069917cc35aae25b4ed858e6a -F ext/session/session2.test 45c9ff2052bf132d25d272b1d4b53f95c1c31463 -F ext/session/sqlite3session.c 3ed836ee8c6faff866bc59da800b6f20b0285071 -F ext/session/sqlite3session.h b77b014793162a77ac16507d720fe085cc15d06c +F ext/session/session2.test 3ef304f660b2a929e6bfec2df125c1809f5501ff +F ext/session/sqlite3session.c 70b19f80eadf7060836eaa90928f08a58aa3b35f +F ext/session/sqlite3session.h 2c071ee5925e82c21c7c9c296a0422c039607106 F ext/session/test_session.c 2559ef68e421c7fb83e2c19ef08a17343b70d535 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 @@ -921,7 +921,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 0853e530cc8d96f025f5160540e8ab3243dea11b -R 482fc377ccc3f262af8beae8e4f384bf +P a192d04f4e3a9e4960a4d96d1d3ee8635bc1034d +R 0282a54a03134becd2cdef1929ff705c U dan -Z 767fabeb255e365fd4d794b5ace5ff7b +Z 9cc92283568709d19359195efd9bde16 diff --git a/manifest.uuid b/manifest.uuid index e7426fdf05..754c4bfa3c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a192d04f4e3a9e4960a4d96d1d3ee8635bc1034d \ No newline at end of file +aed4273054cbd150c86b36ea951d17c981633ba0 \ No newline at end of file From 12ca0b5695b874340a4c3e3a45b3d951cd0840ce Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 21 Mar 2011 16:17:42 +0000 Subject: [PATCH 0027/1484] Add start of fault-injection tests for session module. Fix some bugs related to the same. FossilOrigin-Name: 32e95164d1192b87b1ab019549fd2394642cd3fe --- ext/session/session2.test | 106 ++++++++++++--------------------- ext/session/session_common.tcl | 106 +++++++++++++++++++++++++++++++++ ext/session/sessionfault.test | 85 ++++++++++++++++++++++++++ ext/session/sqlite3session.c | 83 ++++++++++++++------------ manifest | 18 +++--- manifest.uuid | 2 +- src/vdbeapi.c | 22 +++---- 7 files changed, 299 insertions(+), 123 deletions(-) create mode 100644 ext/session/session_common.tcl create mode 100644 ext/session/sessionfault.test diff --git a/ext/session/session2.test b/ext/session/session2.test index 357b806043..9065df99a0 100644 --- a/ext/session/session2.test +++ b/ext/session/session2.test @@ -28,67 +28,6 @@ proc test_reset {} { sqlite3 db2 test.db2 } -proc do_common_sql {sql} { - execsql $sql db - execsql $sql db2 -} -proc xConflict args { return "OMIT" } - -proc do_then_apply_sql {sql {dbname main}} { - - sqlite3session S db $dbname - db eval "SELECT name FROM $dbname.sqlite_master WHERE type = 'table'" { - S attach $name - } - - db eval $sql - sqlite3changeset_apply db2 [S changeset] xConflict - S delete -} - -proc do_iterator_test {tn tbl_list sql res} { - sqlite3session S db main - foreach t $tbl_list {S attach $t} - execsql $sql - - set r [list] - foreach v $res { lappend r $v } - - set x [list] - sqlite3session_foreach c [S changeset] { lappend x $c } - uplevel do_test $tn [list [list set {} $x]] [list $r] - - S delete -} - -# Compare the contents of all tables in [db1] and [db2]. Throw an error if -# they are not identical, or return an empty string if they are. -# -proc compare_db {db1 db2} { - - set sql {SELECT name FROM sqlite_master WHERE type = 'table' ORDER BY name} - set lot1 [$db1 eval $sql] - set lot2 [$db2 eval $sql] - - if {$lot1 != $lot2} { error "databases contain different tables" } - - foreach tbl $lot1 { - set col1 [list] - set col2 [list] - - $db1 eval "PRAGMA table_info = $tbl" { lappend col1 $name } - $db2 eval "PRAGMA table_info = $tbl" { lappend col2 $name } - if {$col1 != $col2} { error "table $tbl schema mismatch" } - - set sql "SELECT * FROM $tbl ORDER BY [join $col1 ,]" - set data1 [$db1 eval $sql] - set data2 [$db2 eval $sql] - if {$data1 != $data2} { error "table $tbl data mismatch" } - } - - return "" -} - ########################################################################## # End of proc definitions. Start of tests. ########################################################################## @@ -105,12 +44,13 @@ do_iterator_test 1.1 t1 { {DELETE t1 {t i t one} {}} {INSERT t1 {} {t ii t two}} } -do_iterator_test 1.1 t1 { +do_iterator_test 1.2 t1 { INSERT INTO t1 VALUES(1.5, 99.9) } { {INSERT t1 {} {f 1.5 f 99.9}} } + # Execute each of the following blocks of SQL on database [db1]. Collect # changes using a session object. Apply the resulting changeset to # database [db2]. Then check that the contents of the two databases are @@ -178,6 +118,38 @@ set set_of_tests { 12 { INSERT INTO %T2% VALUES(NULL, NULL); } + + 13 { + DELETE FROM %T1% WHERE 1; + + -- Insert many rows with real primary keys. Enough to force the session + -- objects hash table to resize. + INSERT INTO %T1% VALUES(0.1, 0.1); + INSERT INTO %T1% SELECT a+0.1, b+0.1 FROM %T1%; + INSERT INTO %T1% SELECT a+0.2, b+0.2 FROM %T1%; + INSERT INTO %T1% SELECT a+0.4, b+0.4 FROM %T1%; + INSERT INTO %T1% SELECT a+0.8, b+0.8 FROM %T1%; + INSERT INTO %T1% SELECT a+1.6, b+1.6 FROM %T1%; + INSERT INTO %T1% SELECT a+3.2, b+3.2 FROM %T1%; + INSERT INTO %T1% SELECT a+6.4, b+6.4 FROM %T1%; + INSERT INTO %T1% SELECT a+12.8, b+12.8 FROM %T1%; + INSERT INTO %T1% SELECT a+25.6, b+25.6 FROM %T1%; + INSERT INTO %T1% SELECT a+51.2, b+51.2 FROM %T1%; + INSERT INTO %T1% SELECT a+102.4, b+102.4 FROM %T1%; + INSERT INTO %T1% SELECT a+204.8, b+204.8 FROM %T1%; + } + + 14 { + DELETE FROM %T1% WHERE 1; + } + + 15 { + INSERT INTO %T1% VALUES(1, 1); + INSERT INTO %T1% SELECT a+2, b+2 FROM %T1%; + INSERT INTO %T1% SELECT a+4, b+4 FROM %T1%; + INSERT INTO %T1% SELECT a+8, b+8 FROM %T1%; + INSERT INTO %T1% SELECT a+256, b+256 FROM %T1%; + } } test_reset @@ -189,7 +161,7 @@ do_common_sql { foreach {tn sql} [string map {%T1% t1 %T2% t2 %T3% t3} $set_of_tests] { do_then_apply_sql $sql - do_test 1.$tn { compare_db db db2 } {} + do_test 2.$tn { compare_db db db2 } {} } # The following block of tests is similar to the last, except that the @@ -200,7 +172,7 @@ foreach {tn sql} [string map {%T1% t1 %T2% t2 %T3% t3} $set_of_tests] { test_reset forcedelete test.db3 sqlite3 db3 test.db3 -do_test 2.0 { +do_test 3.0 { execsql { ATTACH 'test.db3' AS 'aux'; CREATE TABLE t1(a, b PRIMARY KEY); @@ -224,7 +196,7 @@ foreach {tn sql} [ string map {%T1% aux.t1 %T2% aux.t2 %T3% aux.t3} $set_of_tests ] { do_then_apply_sql $sql aux - do_test 2.$tn { compare_db db3 db2 } {} + do_test 3.$tn { compare_db db3 db2 } {} } catch {db3 close} @@ -234,7 +206,7 @@ catch {db3 close} # handled correctly by the session module. # test_reset -do_execsql_test 3.0 { +do_execsql_test 4.0 { CREATE TABLE t1(a PRIMARY KEY); CREATE TABLE t2(a, b, c, PRIMARY KEY(c, b)); CREATE TABLE t3(a, b INTEGER PRIMARY KEY); @@ -272,7 +244,7 @@ foreach {tn sql changeset} { 9 { DELETE FROM t2 WHERE 1 } { {DELETE t2 {i 1 i 2 i 3} {}} } } { - do_iterator_test 3.$tn {t1 t2 t3} $sql $changeset + do_iterator_test 4.$tn {t1 t2 t3} $sql $changeset } diff --git a/ext/session/session_common.tcl b/ext/session/session_common.tcl new file mode 100644 index 0000000000..1b5ebc5b97 --- /dev/null +++ b/ext/session/session_common.tcl @@ -0,0 +1,106 @@ + + +proc do_conflict_test {tn args} { + proc xConflict {args} { + lappend ::xConflict $args + return "" + } + proc bgerror {args} { set ::background_error $args } + + + set O(-tables) [list] + set O(-sql) [list] + set O(-conflicts) [list] + + array set V $args + foreach key [array names V] { + if {![info exists O($key)]} {error "no such option: $key"} + } + array set O $args + + sqlite3session S db main + foreach t $O(-tables) { S attach $t } + execsql $O(-sql) + + set ::xConflict [list] + sqlite3changeset_apply db2 [S changeset] xConflict + + set conflicts [list] + foreach c $O(-conflicts) { + lappend conflicts $c + } + + after 1 {set go 1} + vwait go + + uplevel do_test $tn [list { set ::xConflict }] [list $conflicts] + S delete +} + +proc do_common_sql {sql} { + execsql $sql db + execsql $sql db2 +} + +proc do_then_apply_sql {sql {dbname main}} { + proc xConflict args { return "OMIT" } + + set rc [catch { + sqlite3session S db $dbname + db eval "SELECT name FROM $dbname.sqlite_master WHERE type = 'table'" { + S attach $name + } + db eval $sql + sqlite3changeset_apply db2 [S changeset] xConflict + } msg] + + catch { S delete } + + if {$rc} {error $msg} +} + +proc do_iterator_test {tn tbl_list sql res} { + sqlite3session S db main + foreach t $tbl_list {S attach $t} + execsql $sql + + set r [list] + foreach v $res { lappend r $v } + + set x [list] + sqlite3session_foreach c [S changeset] { lappend x $c } + uplevel do_test $tn [list [list set {} $x]] [list $r] + + S delete +} + +# Compare the contents of all tables in [db1] and [db2]. Throw an error if +# they are not identical, or return an empty string if they are. +# +proc compare_db {db1 db2} { + + set sql {SELECT name FROM sqlite_master WHERE type = 'table' ORDER BY name} + set lot1 [$db1 eval $sql] + set lot2 [$db2 eval $sql] + + if {$lot1 != $lot2} { error "databases contain different tables" } + + foreach tbl $lot1 { + set col1 [list] + set col2 [list] + + $db1 eval "PRAGMA table_info = $tbl" { lappend col1 $name } + $db2 eval "PRAGMA table_info = $tbl" { lappend col2 $name } + if {$col1 != $col2} { error "table $tbl schema mismatch" } + + set sql "SELECT * FROM $tbl ORDER BY [join $col1 ,]" + set data1 [$db1 eval $sql] + set data2 [$db2 eval $sql] + if {$data1 != $data2} { error "table $tbl data mismatch" } + } + + return "" +} + + + diff --git a/ext/session/sessionfault.test b/ext/session/sessionfault.test new file mode 100644 index 0000000000..d6dd361b00 --- /dev/null +++ b/ext/session/sessionfault.test @@ -0,0 +1,85 @@ +# 2011 Mar 21 +# +# 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. +# +#*********************************************************************** +# +# The focus of this file is testing the session module. +# + +if {![info exists testdir]} { + set testdir [file join [file dirname [info script]] .. .. test] +} +source [file join [file dirname [info script]] session_common.tcl] +source $testdir/tester.tcl + +set testprefix sessionfault + +forcedelete test.db2 +sqlite3 db2 test.db2 + +do_common_sql { + CREATE TABLE t1(a, b, c, PRIMARY KEY(a, b)); + INSERT INTO t1 VALUES(1, 2, 3); + INSERT INTO t1 VALUES(4, 5, 6); +} +faultsim_save_and_close +db2 close + +# Test OOM error handling when collecting and applying a simple changeset. +# +do_faultsim_test pagerfault-1 -faults oom-* -prep { + catch {db2 close} + catch {db close} + faultsim_restore_and_reopen + sqlite3 db2 test.db2 +} -body { + do_then_apply_sql { + INSERT INTO t1 VALUES(7, 8, 9); + UPDATE t1 SET c = 10 WHERE a = 1; + DELETE FROM t1 WHERE a = 4; + } +} -test { + faultsim_test_result {0 {}} {1 SQLITE_NOMEM} + faultsim_integrity_check + if {$testrc==0} { compare_db db db2 } +} + +# This test case is designed so that a malloc() failure occurs while +# resizing the session object hash-table from 256 to 512 buckets. This +# is not an error, just a sub-optimal condition. +# +do_faultsim_test pagerfault-2 -faults oom-* -prep { + catch {db2 close} + catch {db close} + faultsim_restore_and_reopen + sqlite3 db2 test.db2 + + sqlite3session S db main + S attach t1 + execsql { BEGIN } + for {set i 0} {$i < 125} {incr i} { + execsql {INSERT INTO t1 VALUES(10+$i, 10+$i, 10+$i)} + } +} -body { + for {set i 125} {$i < 133} {incr i} { + execsql {INSERT INTO t1 VALUES(10+$i, 10+$i, 1-+$i)} + } + S changeset + set {} {} +} -test { + faultsim_test_result {0 {}} {1 SQLITE_NOMEM} + if {$testrc==0} { + sqlite3changeset_apply db2 [S changeset] xConflict + compare_db db db2 + } + catch { S delete } + faultsim_integrity_check +} + +finish_test diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index 4663938bb2..e6d4675b08 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -305,6 +305,7 @@ static unsigned int sessionPreupdateHash( }else{ rc = sqlite3_preupdate_old(db, i, &pVal); } + if( rc!=SQLITE_OK ) return rc; eType = sqlite3_value_type(pVal); h = HASH_APPEND(h, eType); @@ -424,33 +425,35 @@ static int sessionPreupdateEqual( } if( rc!=SQLITE_OK || sqlite3_value_type(pVal)!=eType ) return rc; - switch( eType ){ - case SQLITE_INTEGER: - case SQLITE_FLOAT: { - i64 iVal = sessionGetI64(a); - a += 8; - if( eType==SQLITE_INTEGER ){ - if( sqlite3_value_int64(pVal)!=iVal ) return SQLITE_OK; - }else{ - double rVal; - assert( sizeof(iVal)==8 && sizeof(rVal)==8 ); - memcpy(&rVal, &iVal, 8); - if( sqlite3_value_double(pVal)!=rVal ) return SQLITE_OK; - } - break; + /* A SessionChange object never has a NULL value in a PK column */ + assert( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT + || eType==SQLITE_BLOB || eType==SQLITE_TEXT + ); + + if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){ + i64 iVal = sessionGetI64(a); + a += 8; + if( eType==SQLITE_INTEGER ){ + if( sqlite3_value_int64(pVal)!=iVal ) return SQLITE_OK; + }else{ + double rVal; + assert( sizeof(iVal)==8 && sizeof(rVal)==8 ); + memcpy(&rVal, &iVal, 8); + if( sqlite3_value_double(pVal)!=rVal ) return SQLITE_OK; } - case SQLITE_TEXT: - case SQLITE_BLOB: { - int n; - const u8 *z; - a += sessionVarintGet(a, &n); - if( sqlite3_value_bytes(pVal)!=n ) return SQLITE_OK; - z = eType==SQLITE_TEXT ? - sqlite3_value_text(pVal) : sqlite3_value_blob(pVal); - if( memcmp(a, z, n) ) return SQLITE_OK; - a += n; - break; + }else{ + int n; + const u8 *z; + a += sessionVarintGet(a, &n); + if( sqlite3_value_bytes(pVal)!=n ) return SQLITE_OK; + if( eType==SQLITE_TEXT ){ + z = sqlite3_value_text(pVal); + }else{ + z = sqlite3_value_blob(pVal); } + if( memcmp(a, z, n) ) return SQLITE_OK; + a += n; + break; } } } @@ -734,20 +737,22 @@ static void sessionPreupdateOneChange( rc = sessionSerializeValue(&pChange->aRecord[nByte], p, &nByte); } } - pChange->nRecord = nByte; - - /* If an error has occurred, mark the session object as failed. */ - if( rc!=SQLITE_OK ){ - sqlite3_free(pChange); - pSession->rc = rc; - }else{ + if( rc==SQLITE_OK ){ /* Add the change back to the hash-table */ + pChange->nRecord = nByte; pChange->bInsert = (op==SQLITE_INSERT); pChange->pNext = pTab->apChange[iHash]; pTab->apChange[iHash] = pChange; + }else{ + sqlite3_free(pChange); } } } + + /* If an error has occurred, mark the session object as failed. */ + if( rc!=SQLITE_OK ){ + pSession->rc = rc; + } } /* @@ -1345,7 +1350,7 @@ int sqlite3session_changeset( } nNoop = buf.nBuf; - for(i=0; inChange; i++){ + for(i=0; inChange && rc==SQLITE_OK; i++){ SessionChange *p; /* Used to iterate through changes */ for(p=pTab->apChange[i]; rc==SQLITE_OK && p; p=p->pNext){ @@ -1366,13 +1371,14 @@ int sqlite3session_changeset( sessionAppendByte(&buf, SQLITE_DELETE, &rc); sessionAppendBlob(&buf, p->aRecord, p->nRecord, &rc); } - rc = sqlite3_reset(pSel); + if( rc==SQLITE_OK ){ + rc = sqlite3_reset(pSel); + } } } } sqlite3_finalize(pSel); - if( buf.nBuf==nNoop ){ buf.nBuf = nRewind; } @@ -1674,7 +1680,9 @@ int sqlite3changeset_conflict( int sqlite3changeset_finalize(sqlite3_changeset_iter *p){ int i; /* Used to iterate through p->apValue[] */ int rc = p->rc; /* Return code */ - for(i=0; inCol*2; i++) sqlite3ValueFree(p->apValue[i]); + if( p->apValue ){ + for(i=0; inCol*2; i++) sqlite3ValueFree(p->apValue[i]); + } sqlite3_free(p->apValue); sqlite3_free(p); return rc; @@ -2316,7 +2324,8 @@ int sqlite3changeset_apply( SessionApplyCtx sApply; /* changeset_apply() context object */ memset(&sApply, 0, sizeof(sApply)); - sqlite3changeset_start(&pIter, nChangeset, pChangeset); + rc = sqlite3changeset_start(&pIter, nChangeset, pChangeset); + if( rc!=SQLITE_OK ) return rc; sqlite3_mutex_enter(sqlite3_db_mutex(db)); rc = sqlite3_exec(db, "SAVEPOINT changeset_apply", 0, 0, 0); diff --git a/manifest b/manifest index 63945fc241..3c63f1b8cc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Clarify\shandling\sof\sNULL\svalues\sin\sPK\scolumns\sin\ssqlite3session.h.\sAdd\stests\sand\sfixes\sfor\sthe\ssame. -D 2011-03-21T11:55:07 +C Add\sstart\sof\sfault-injection\stests\sfor\ssession\smodule.\sFix\ssome\sbugs\srelated\sto\sthe\ssame. +D 2011-03-21T16:17:42 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -100,8 +100,10 @@ F ext/rtree/sqlite3rtree.h 1af0899c63a688e272d69d8e746f24e76f10a3f0 F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 F ext/session/session1.test 3f982c74ee4ba97069917cc35aae25b4ed858e6a -F ext/session/session2.test 3ef304f660b2a929e6bfec2df125c1809f5501ff -F ext/session/sqlite3session.c 70b19f80eadf7060836eaa90928f08a58aa3b35f +F ext/session/session2.test 6462c21d3795d9e48ffea2e7550d1b2d6da66dfb +F ext/session/session_common.tcl 880b554b0bcadcabe1331afb87d58ad1ed2510c4 +F ext/session/sessionfault.test 4190de237b2c76ca7529ef415778a862d7d0fa30 +F ext/session/sqlite3session.c c5a60c2cf21f8892f9ae4850fad2d7859c2c3692 F ext/session/sqlite3session.h 2c071ee5925e82c21c7c9c296a0422c039607106 F ext/session/test_session.c 2559ef68e421c7fb83e2c19ef08a17343b70d535 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 @@ -239,7 +241,7 @@ F src/vacuum.c 924bd1bcee2dfb05376f79845bd3b4cec7b54b2f F src/vdbe.c c90edafd941481506f001b17cd8523683fdac853 F src/vdbe.h edef9c4f0be83e1f1dccd049da37b40e021b63d9 F src/vdbeInt.h 2cf77c1d151a4a54facd596d52be6d60c1cb26e8 -F src/vdbeapi.c c4692c74b31f4abe638fbcbae3944c52b54e2c36 +F src/vdbeapi.c 3d620e00cb74b6034343009af42d5ff5eb7c19dc F src/vdbeaux.c 0216b2c37509a44c3833b297765bee7bdd04fa2f F src/vdbeblob.c c3ccb7c8732858c680f442932e66ad06bb036562 F src/vdbemem.c 0498796b6ffbe45e32960d6a1f5adfb6e419883b @@ -921,7 +923,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P a192d04f4e3a9e4960a4d96d1d3ee8635bc1034d -R 0282a54a03134becd2cdef1929ff705c +P aed4273054cbd150c86b36ea951d17c981633ba0 +R 3ee0056f48f594a086fa203e62ad6366 U dan -Z 9cc92283568709d19359195efd9bde16 +Z 9a232200bb7ff725d52774ff9ca627f1 diff --git a/manifest.uuid b/manifest.uuid index 754c4bfa3c..7adc729880 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -aed4273054cbd150c86b36ea951d17c981633ba0 \ No newline at end of file +32e95164d1192b87b1ab019549fd2394642cd3fe \ No newline at end of file diff --git a/src/vdbeapi.c b/src/vdbeapi.c index 284e565e13..829d4678b6 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -1348,21 +1348,23 @@ int sqlite3_preupdate_old(sqlite3 *db, int iIdx, sqlite3_value **ppValue){ /* If the old.* record has not yet been loaded into memory, do so now. */ if( p->pUnpacked==0 ){ - u32 nRecord; - u8 *aRecord; + u32 nRec; + u8 *aRec; - rc = sqlite3BtreeDataSize(p->pCsr->pCursor, &nRecord); + rc = sqlite3BtreeDataSize(p->pCsr->pCursor, &nRec); if( rc!=SQLITE_OK ) goto preupdate_old_out; - aRecord = sqlite3DbMallocRaw(db, nRecord); - if( !aRecord ) goto preupdate_old_out; - rc = sqlite3BtreeData(p->pCsr->pCursor, 0, nRecord, aRecord); + aRec = sqlite3DbMallocRaw(db, nRec); + if( !aRec ) goto preupdate_old_out; + rc = sqlite3BtreeData(p->pCsr->pCursor, 0, nRec, aRec); + if( rc==SQLITE_OK ){ + p->pUnpacked = sqlite3VdbeRecordUnpack(&p->keyinfo, nRec, aRec, 0, 0); + if( !p->pUnpacked ) rc = SQLITE_NOMEM; + } if( rc!=SQLITE_OK ){ - sqlite3DbFree(db, aRecord); + sqlite3DbFree(db, aRec); goto preupdate_old_out; } - - p->pUnpacked = sqlite3VdbeRecordUnpack(&p->keyinfo, nRecord, aRecord, 0, 0); - p->aRecord = aRecord; + p->aRecord = aRec; } if( iIdx>=p->pUnpacked->nField ){ From db04571c79364fcfffc2dfd7fc655dc9d1b7d071 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 21 Mar 2011 19:41:29 +0000 Subject: [PATCH 0028/1484] Remove some unreachable code in sqlite3session.c. Add test cases. FossilOrigin-Name: 39cdfa5324ae91bfbbac733b1e3e2d33ca883340 --- ext/session/session1.test | 1 - ext/session/session2.test | 16 +++- ext/session/session_common.tcl | 6 +- ext/session/sessionfault.test | 52 +++++++++++ ext/session/sqlite3session.c | 164 ++++++++++++++------------------- manifest | 32 +++---- manifest.uuid | 2 +- 7 files changed, 150 insertions(+), 123 deletions(-) diff --git a/ext/session/session1.test b/ext/session/session1.test index fd09b47cc5..1d8b1921b9 100644 --- a/ext/session/session1.test +++ b/ext/session/session1.test @@ -188,7 +188,6 @@ proc do_conflict_test {tn args} { sqlite3session S db main foreach t $O(-tables) { S attach $t } execsql $O(-sql) - set ::xConflict [list] sqlite3changeset_apply db2 [S changeset] xConflict diff --git a/ext/session/session2.test b/ext/session/session2.test index 9065df99a0..984559bb12 100644 --- a/ext/session/session2.test +++ b/ext/session/session2.test @@ -150,6 +150,13 @@ set set_of_tests { INSERT INTO %T1% SELECT a+8, b+8 FROM %T1%; INSERT INTO %T1% SELECT a+256, b+256 FROM %T1%; } + + 16 { + INSERT INTO %T4% VALUES('abc', 'def'); + INSERT INTO %T4% VALUES('def', 'abc'); + } + 17 { UPDATE %T4% SET b = 1 } + 18 { DELETE FROM %T4% WHERE 1 } } test_reset @@ -157,9 +164,10 @@ do_common_sql { CREATE TABLE t1(a PRIMARY KEY, b); CREATE TABLE t2(a, b INTEGER PRIMARY KEY); CREATE TABLE t3(a, b, c, PRIMARY KEY(a, b)); + CREATE TABLE t4(a, b, PRIMARY KEY(b, a)); } -foreach {tn sql} [string map {%T1% t1 %T2% t2 %T3% t3} $set_of_tests] { +foreach {tn sql} [string map {%T1% t1 %T2% t2 %T3% t3 %T4% t4} $set_of_tests] { do_then_apply_sql $sql do_test 2.$tn { compare_db db db2 } {} } @@ -182,21 +190,23 @@ do_test 3.0 { CREATE TABLE aux.t1(a PRIMARY KEY, b); CREATE TABLE aux.t2(a, b INTEGER PRIMARY KEY); CREATE TABLE aux.t3(a, b, c, PRIMARY KEY(a, b)); + CREATE TABLE aux.t4(a, b, PRIMARY KEY(b, a)); } execsql { CREATE TABLE t1(a PRIMARY KEY, b); CREATE TABLE t2(a, b INTEGER PRIMARY KEY); CREATE TABLE t3(a, b, c, PRIMARY KEY(a, b)); + CREATE TABLE t4(a, b, PRIMARY KEY(b, a)); } db2 } {} proc xTrace {args} { puts $args } foreach {tn sql} [ - string map {%T1% aux.t1 %T2% aux.t2 %T3% aux.t3} $set_of_tests + string map {%T1% aux.t1 %T2% aux.t2 %T3% aux.t3 %T4% aux.t4} $set_of_tests ] { do_then_apply_sql $sql aux - do_test 3.$tn { compare_db db3 db2 } {} + do_test 3.$tn { compare_db db2 db3 } {} } catch {db3 close} diff --git a/ext/session/session_common.tcl b/ext/session/session_common.tcl index 1b5ebc5b97..c1a6440396 100644 --- a/ext/session/session_common.tcl +++ b/ext/session/session_common.tcl @@ -83,7 +83,11 @@ proc compare_db {db1 db2} { set lot1 [$db1 eval $sql] set lot2 [$db2 eval $sql] - if {$lot1 != $lot2} { error "databases contain different tables" } + if {$lot1 != $lot2} { + puts $lot1 + puts $lot2 + error "databases contain different tables" + } foreach tbl $lot1 { set col1 [list] diff --git a/ext/session/sessionfault.test b/ext/session/sessionfault.test index d6dd361b00..8f38fe63e8 100644 --- a/ext/session/sessionfault.test +++ b/ext/session/sessionfault.test @@ -82,4 +82,56 @@ do_faultsim_test pagerfault-2 -faults oom-* -prep { faultsim_integrity_check } +catch { db close } +catch { db2 close } +forcedelete test.db2 test.db +sqlite3 db2 test.db2 +sqlite3 db test.db + +proc xConflict {op tbl type args} { + if { $type=="CONFLICT" || $type=="DATA" } { + return "REPLACE" + } + return "OMIT" +} + +do_test 3.0 { + execsql { + PRAGMA encoding = 'utf16'; + CREATE TABLE t1(a PRIMARY KEY, b); + INSERT INTO t1 VALUES(5, 32); + } + execsql { + PRAGMA encoding = 'utf16'; + CREATE TABLE t1(a PRIMARY KEY, b NOT NULL); + INSERT INTO t1 VALUES(1, 2); + INSERT INTO t1 VALUES(2, 4); + INSERT INTO t1 VALUES(4, 16); + } db2 +} {} + +faultsim_save_and_close +db2 close + +do_faultsim_test pagerfault-3 -faults oom-transient -prep { + catch {db2 close} + catch {db close} + faultsim_restore_and_reopen + sqlite3 db2 test.db2 + sqlite3session S db main + S attach t1 + execsql { + INSERT INTO t1 VALUES(1, 45); + INSERT INTO t1 VALUES(2, 55); + INSERT INTO t1 VALUES(3, 55); + UPDATE t1 SET a = 4 WHERE a = 5; + } +} -body { + sqlite3changeset_apply db2 [S changeset] xConflict +} -test { + catch { S delete } + faultsim_test_result {0 {}} {1 SQLITE_NOMEM} + if {$testrc==0} { compare_db db db2 } +} + finish_test diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index e6d4675b08..3c6a972961 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -552,11 +552,10 @@ static int sessionTableInfo( int nThis; int i; u8 *pAlloc; - u8 *pFree = 0; - char **azCol; + char **azCol = 0; u8 *abPK; - assert( pazCol || pabPK ); + assert( pazCol && pabPK ); nThis = strlen(zThis); zPragma = sqlite3_mprintf("PRAGMA '%q'.table_info('%q')", zDb, zThis); @@ -584,15 +583,10 @@ static int sessionTableInfo( } } if( rc==SQLITE_OK ){ - pFree = pAlloc; - if( pazCol ){ - azCol = (char **)pAlloc; - pAlloc = (u8 *)&azCol[nCol]; - } - if( pabPK ){ - abPK = (u8 *)pAlloc; - pAlloc = &abPK[nCol]; - } + azCol = (char **)pAlloc; + pAlloc = (u8 *)&azCol[nCol]; + abPK = (u8 *)pAlloc; + pAlloc = &abPK[nCol]; if( pzTab ){ memcpy(pAlloc, zThis, nThis+1); *pzTab = (char *)pAlloc; @@ -604,12 +598,10 @@ static int sessionTableInfo( int nName = sqlite3_column_bytes(pStmt, 1); const unsigned char *zName = sqlite3_column_text(pStmt, 1); if( zName==0 ) break; - if( pazCol ){ - memcpy(pAlloc, zName, nName+1); - azCol[i] = (char *)pAlloc; - pAlloc += nName+1; - } - if( pabPK ) abPK[i] = sqlite3_column_int(pStmt, 5); + memcpy(pAlloc, zName, nName+1); + azCol[i] = (char *)pAlloc; + pAlloc += nName+1; + abPK[i] = sqlite3_column_int(pStmt, 5); i++; } rc = sqlite3_reset(pStmt); @@ -620,13 +612,13 @@ static int sessionTableInfo( ** free any allocation made. An error code will be returned in this case. */ if( rc==SQLITE_OK ){ - if( pazCol ) *pazCol = (const char **)azCol; - if( pabPK ) *pabPK = abPK; + *pazCol = (const char **)azCol; + *pabPK = abPK; }else{ - if( pazCol ) *pazCol = 0; - if( pabPK ) *pabPK = 0; + *pazCol = 0; + *pabPK = 0; if( pzTab ) *pzTab = 0; - sqlite3_free(pFree); + sqlite3_free(azCol); } sqlite3_finalize(pStmt); return rc; @@ -1785,7 +1777,7 @@ struct SessionApplyCtx { ** ** The DELETE statement looks like this: ** -** DELETE FROM x WHERE a = :1 AND c = :3 AND :5 OR (b IS :2 AND d IS :4) +** DELETE FROM x WHERE a = :1 AND c = :3 AND (:5 OR b IS :2 AND d IS :4) ** ** Variable :5 (nCol+1) is a boolean. It should be set to 0 if we require ** matching b and d values, or 1 otherwise. The second case comes up if the @@ -1997,6 +1989,41 @@ static int sessionInsertRow( return rc; } +/* +** Iterator pIter must point to an SQLITE_INSERT entry. This function +** transfers new.* values from the current iterator entry to statement +** pStmt. The table being inserted into has nCol columns. +** +** New.* value $i 0 from the iterator is bound to variable ($i+1) of +** statement pStmt. If parameter abPK is NULL, all values from 0 to (nCol-1) +** are transfered to the statement. Otherwise, if abPK is not NULL, it points +** to an array nCol elements in size. In this case only those values for +** which abPK[$i] is true are read from the iterator and bound to the +** statement. +** +** An SQLite error code is returned if an error occurs. Otherwise, SQLITE_OK. +*/ +static int sessionBindValues( + sqlite3_changeset_iter *pIter, /* Iterator to read values from */ + int(*xIterValue)(sqlite3_changeset_iter *, int, sqlite3_value **), + int nCol, /* Number of columns */ + u8 *abPK, /* If not NULL, bind only if true */ + sqlite3_stmt *pStmt /* Bind values to this statement */ +){ + int i; + int rc = SQLITE_OK; + for(i=0; rc==SQLITE_OK && idb, pIter, p->abPK, p->pSelect); }else{ - rc = SQLITE_DONE; + rc = SQLITE_OK; } if( rc==SQLITE_ROW ){ @@ -2117,7 +2130,7 @@ static int sessionConflictHandler( res = xConflict(pCtx, eType, pIter); pIter->pConflict = 0; rc = sqlite3_reset(p->pSelect); - }else{ + }else if( rc==SQLITE_OK ){ /* No other row with the new.* primary key. */ rc = sqlite3_reset(p->pSelect); if( rc==SQLITE_OK ){ @@ -2192,16 +2205,9 @@ static int sessionApplyOneOp( sqlite3changeset_op(pIter, &zDummy, &nCol, &op); if( op==SQLITE_DELETE ){ - int i; /* Bind values to the DELETE statement. */ - for(i=0; rc==SQLITE_OK && ipDelete, i+1, pVal); - } - } + rc = sessionBindValues(pIter, sqlite3changeset_old, nCol, 0, p->pDelete); if( rc==SQLITE_OK && sqlite3_bind_parameter_count(p->pDelete)>nCol ){ rc = sqlite3_bind_int(p->pDelete, nCol+1, pbRetry==0); } @@ -2254,44 +2260,20 @@ static int sessionApplyOneOp( ); }else if( rc==SQLITE_CONSTRAINT ){ - /* This may be a CONSTRAINT or CONFLICT error. It is a CONFLICT if - ** the only problem is a duplicate PRIMARY KEY, or a CONSTRAINT - ** otherwise. */ - int bPKChange = 0; - - /* Check if the PK has been modified. */ - rc = SQLITE_OK; - for(i=0; iabPK[i] ){ - sqlite3_value *pNew; - rc = sqlite3changeset_new(pIter, i, &pNew); - if( rc==SQLITE_OK && pNew ){ - bPKChange = 1; - break; - } - } - } - - rc = sessionConflictHandler(SQLITE_CHANGESET_CONFLICT, - p, pIter, xConflict, pCtx, (bPKChange ? pbReplace : 0) + /* This is always a CONSTRAINT conflict. */ + rc = sessionConflictHandler( + SQLITE_CHANGESET_CONFLICT, p, pIter, xConflict, pCtx, 0 ); } }else{ - int i; assert( op==SQLITE_INSERT ); - for(i=0; rc==SQLITE_OK && ipInsert, i+1, pVal); - } - } + rc = sessionBindValues(pIter, sqlite3changeset_new, nCol, 0, p->pInsert); if( rc!=SQLITE_OK ) return rc; sqlite3_step(p->pInsert); rc = sqlite3_reset(p->pInsert); - if( rc==SQLITE_CONSTRAINT && xConflict ){ + if( rc==SQLITE_CONSTRAINT ){ rc = sessionConflictHandler( SQLITE_CHANGESET_CONFLICT, p, pIter, xConflict, pCtx, pbReplace ); @@ -2369,21 +2351,11 @@ int sqlite3changeset_apply( } if( bReplace ){ + assert( pIter->op==SQLITE_INSERT ); rc = sqlite3_exec(db, "SAVEPOINT replace_op", 0, 0, 0); if( rc==SQLITE_OK ){ - int i; - for(i=0; i Date: Tue, 22 Mar 2011 02:03:23 +0000 Subject: [PATCH 0029/1484] Fix a couple typos for consistency in sessions documentation. FossilOrigin-Name: 510198f171b9f77a4ad49c06c978c5fbb3a5b7f9 --- ext/session/sqlite3session.h | 10 +++++----- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/ext/session/sqlite3session.h b/ext/session/sqlite3session.h index 44b58eada8..8e1767efab 100644 --- a/ext/session/sqlite3session.h +++ b/ext/session/sqlite3session.h @@ -91,7 +91,7 @@ void sqlite3session_delete(sqlite3_session *pSession); int sqlite3session_enable(sqlite3_session *pSession, int bEnable); /* -** CAPI3REF: Attach a Table to a Session Object +** CAPI3REF: Attach A Table To A Session Object ** ** Attach a table to a session. All subsequent changes made to the table ** while the session object is enabled will be recorded. See documentation @@ -167,7 +167,7 @@ int sqlite3session_attach( ** updated or deleted in the lifetime of the session. ** ** There is one exception to the previous paragraph: when a row is inserted, -** updated or deleted, if one or more of its primary key columns contains a +** updated or deleted, if one or more of its primary key columns contain a ** NULL value, no record of the change is made. ** ** The session object therefore accumulates two types of records - those @@ -197,7 +197,7 @@ int sqlite3session_attach( ** ** ** This means, amongst other things, that if a row is inserted and then later -** deleted while a session object is active, neither the insert or the delete +** deleted while a session object is active, neither the insert nor the delete ** will be present in the changeset. Or if a row is deleted and then later a ** row with the same primary key values inserted while a session object is ** active, the resulting changeset will contain an UPDATE change instead of @@ -395,7 +395,7 @@ int sqlite3changeset_conflict( /* -** CAPI3REF: Finalize a Changeset Iterator +** CAPI3REF: Finalize A Changeset Iterator ** ** This function is used to finalize an iterator allocated with ** [sqlite3changeset_start()]. @@ -585,7 +585,7 @@ int sqlite3changeset_apply( ); /* -** CAPI3REF: Constants Passed to The Conflict Handler +** CAPI3REF: Constants Passed To The Conflict Handler ** ** Values that may be passed as the second argument to a conflict-handler. ** diff --git a/manifest b/manifest index 90e7ad14b4..6310e57e5f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\ssome\sunreachable\scode\sin\ssqlite3session.c.\sAdd\stest\scases. -D 2011-03-21T19:41:30 +C Fix\sa\scouple\stypos\sfor\sconsistency\sin\ssessions\sdocumentation. +D 2011-03-22T02:03:23.754 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -104,7 +104,7 @@ F ext/session/session2.test 54c3a5ecdc60548a8ab0a86793b136de6f32a255 F ext/session/session_common.tcl d7bb85c3fd76d53bd9b909da808d5c16f5213111 F ext/session/sessionfault.test da234166d5d044c91964863174d7171b0561708b F ext/session/sqlite3session.c 1ca39db8a10b8bcb973b35a68c0924b6a64c4a97 -F ext/session/sqlite3session.h 2c071ee5925e82c21c7c9c296a0422c039607106 +F ext/session/sqlite3session.h 2b7b2b983bba8f7a299922056884912084b32c68 F ext/session/test_session.c 2559ef68e421c7fb83e2c19ef08a17343b70d535 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 @@ -923,7 +923,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 2b3c8b9d9aa909f64a29ed8167de24c328c50d85 -R c6506b08e053cfdd0bd616ee1b17add6 -U dan -Z 4cc9deaf80e50ac14cbc33555ec1ddf1 +P 39cdfa5324ae91bfbbac733b1e3e2d33ca883340 +R 7e8df5e06663856423ec54de25f0cd9f +U shaneh +Z a8ae98277851bb377ac869793dff328e diff --git a/manifest.uuid b/manifest.uuid index 3a13c2368c..e429e99a7c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -39cdfa5324ae91bfbbac733b1e3e2d33ca883340 \ No newline at end of file +510198f171b9f77a4ad49c06c978c5fbb3a5b7f9 \ No newline at end of file From 7aa469cdd35ad80d486361617630abc528442e45 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 22 Mar 2011 12:08:00 +0000 Subject: [PATCH 0030/1484] Add OOM tests and related fixes for the session module. FossilOrigin-Name: 06048a68b351e3eb15a890cb54db8a1d4b345fbc --- ext/session/session_common.tcl | 24 ++++++++- ext/session/sessionfault.test | 95 ++++++++++++++++++++++++++++++++-- ext/session/sqlite3session.c | 85 ++++++++++++++++++++---------- manifest | 18 +++---- manifest.uuid | 2 +- 5 files changed, 181 insertions(+), 43 deletions(-) diff --git a/ext/session/session_common.tcl b/ext/session/session_common.tcl index c1a6440396..41c80dee82 100644 --- a/ext/session/session_common.tcl +++ b/ext/session/session_common.tcl @@ -42,9 +42,25 @@ proc do_common_sql {sql} { execsql $sql db2 } +proc changeset_from_sql {sql {dbname main}} { + set rc [catch { + sqlite3session S db $dbname + db eval "SELECT name FROM $dbname.sqlite_master WHERE type = 'table'" { + S attach $name + } + db eval $sql + S changeset + } changeset] + catch { S delete } + + if {$rc} { + error $changeset + } + return $changeset +} + proc do_then_apply_sql {sql {dbname main}} { proc xConflict args { return "OMIT" } - set rc [catch { sqlite3session S db $dbname db eval "SELECT name FROM $dbname.sqlite_master WHERE type = 'table'" { @@ -100,7 +116,11 @@ proc compare_db {db1 db2} { set sql "SELECT * FROM $tbl ORDER BY [join $col1 ,]" set data1 [$db1 eval $sql] set data2 [$db2 eval $sql] - if {$data1 != $data2} { error "table $tbl data mismatch" } + if {$data1 != $data2} { + puts "$data1" + puts "$data2" + error "table $tbl data mismatch" + } } return "" diff --git a/ext/session/sessionfault.test b/ext/session/sessionfault.test index 8f38fe63e8..7ba05bbb22 100644 --- a/ext/session/sessionfault.test +++ b/ext/session/sessionfault.test @@ -22,7 +22,6 @@ set testprefix sessionfault forcedelete test.db2 sqlite3 db2 test.db2 - do_common_sql { CREATE TABLE t1(a, b, c, PRIMARY KEY(a, b)); INSERT INTO t1 VALUES(1, 2, 3); @@ -31,6 +30,8 @@ do_common_sql { faultsim_save_and_close db2 close + +#------------------------------------------------------------------------- # Test OOM error handling when collecting and applying a simple changeset. # do_faultsim_test pagerfault-1 -faults oom-* -prep { @@ -50,11 +51,58 @@ do_faultsim_test pagerfault-1 -faults oom-* -prep { if {$testrc==0} { compare_db db db2 } } +#------------------------------------------------------------------------- +# The following block of tests - pagerfault-2.* - are designed to check +# the handling of faults in the sqlite3changeset_apply() function. +# +catch {db close} +catch {db2 close} +forcedelete test.db2 test.db +sqlite3 db2 test.db2 +sqlite3 db test.db +do_common_sql { + CREATE TABLE t1(a, b, c, PRIMARY KEY(a, b)); + INSERT INTO t1 VALUES('apple', 'orange', 'pear'); + + CREATE TABLE t2(x PRIMARY KEY, y); +} +db2 close +faultsim_save_and_close + + +foreach {tn conflict_policy sql sql2} { + 1 OMIT { INSERT INTO t1 VALUES('one text', 'two text', X'00ff00') } {} + 2 OMIT { DELETE FROM t1 WHERE a = 'apple' } {} + 3 OMIT { UPDATE t1 SET c = 'banana' WHERE b = 'orange' } {} + 4 REPLACE { INSERT INTO t2 VALUES('keyvalue', 'value 1') } { + INSERT INTO t2 VALUES('keyvalue', 'value 2'); + } +} { + proc xConflict args [list return $conflict_policy] + + do_faultsim_test pagerfault-2.$tn -faults oom-transient -prep { + catch {db2 close} + catch {db close} + faultsim_restore_and_reopen + set ::changeset [changeset_from_sql $::sql] + sqlite3 db2 test.db2 + sqlite3_db_config_lookaside db2 0 0 0 + execsql $::sql2 db2 + } -body { + sqlite3changeset_apply db2 $::changeset xConflict + } -test { + faultsim_test_result {0 {}} {1 SQLITE_NOMEM} + faultsim_integrity_check + if {$testrc==0} { compare_db db db2 } + } +} + +#------------------------------------------------------------------------- # This test case is designed so that a malloc() failure occurs while # resizing the session object hash-table from 256 to 512 buckets. This # is not an error, just a sub-optimal condition. # -do_faultsim_test pagerfault-2 -faults oom-* -prep { +do_faultsim_test pagerfault-3 -faults oom-* -prep { catch {db2 close} catch {db close} faultsim_restore_and_reopen @@ -95,7 +143,7 @@ proc xConflict {op tbl type args} { return "OMIT" } -do_test 3.0 { +do_test 4.0 { execsql { PRAGMA encoding = 'utf16'; CREATE TABLE t1(a PRIMARY KEY, b); @@ -113,7 +161,7 @@ do_test 3.0 { faultsim_save_and_close db2 close -do_faultsim_test pagerfault-3 -faults oom-transient -prep { +do_faultsim_test pagerfault-4 -faults oom-* -prep { catch {db2 close} catch {db close} faultsim_restore_and_reopen @@ -134,4 +182,43 @@ do_faultsim_test pagerfault-3 -faults oom-transient -prep { if {$testrc==0} { compare_db db db2 } } +#------------------------------------------------------------------------- +# This block of tests verifies that OOM faults in the +# sqlite3changeset_invert() function are handled correctly. +# +catch {db close} +catch {db2 close} +forcedelete test.db +sqlite3 db test.db +execsql { + CREATE TABLE t1(a, b, PRIMARY KEY(b)); + CREATE TABLE t2(a PRIMARY KEY, b); + INSERT INTO t1 VALUES('string', 1); + INSERT INTO t1 VALUES(4, 2); + INSERT INTO t1 VALUES(X'FFAAFFAAFFAA', 3); +} +set changeset [changeset_from_sql { + INSERT INTO t1 VALUES('xxx', 'yyy'); + DELETE FROM t1 WHERE a = 'string'; + UPDATE t1 SET a = 20 WHERE b = 2; +}] +db close + +do_faultsim_test pagerfault-5 -faults oom* -body { + set ::inverse [sqlite3changeset_invert $::changeset] + set {} {} +} -test { + faultsim_test_result {0 {}} {1 SQLITE_NOMEM} + if {$testrc==0} { + set x [list] + sqlite3session_foreach c $::inverse { lappend x $c } + foreach c { + {DELETE t1 {t xxx t yyy} {}} + {INSERT t1 {} {t string i 1}} + {UPDATE t1 {i 20 {} {}} {i 4 i 2}} + } { lappend y $c } + if {$x != $y} { error "changeset no good" } + } +} + finish_test diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index 3c6a972961..7c7890aed2 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -1637,6 +1637,14 @@ int sqlite3changeset_new( return SQLITE_OK; } +/* +** The following two macros are used internally. They are similar to the +** sqlite3changeset_new() and sqlite3changeset_old() functions, except that +** they omit all error checking and return a pointer to the requested value. +*/ +#define sessionChangesetNew(pIter, iVal) (pIter)->apValue[(pIter)->nCol+(iVal)] +#define sessionChangesetOld(pIter, iVal) (pIter)->apValue[(iVal)] + /* ** This function may only be called with a changeset iterator that has been ** passed to an SQLITE_CHANGESET_DATA or SQLITE_CHANGESET_CONFLICT @@ -1989,6 +1997,24 @@ static int sessionInsertRow( return rc; } +/* +** A wrapper around sqlite3_bind_value() that detects an extra problem. +** See comments in the body of this function for details. +*/ +static int sessionBindValue( + sqlite3_stmt *pStmt, /* Statement to bind value to */ + int i, /* Parameter number to bind to */ + sqlite3_value *pVal /* Value to bind */ +){ + if( (pVal->type==SQLITE_TEXT || pVal->type==SQLITE_BLOB) && pVal->z==0 ){ + /* This condition occurs when an earlier OOM in a call to + ** sqlite3_value_text() or sqlite3_value_blob() (perhaps from within + ** a conflict-hanler) has zeroed the pVal->z pointer. Return NOMEM. */ + return SQLITE_NOMEM; + } + return sqlite3_bind_value(pStmt, i, pVal); +} + /* ** Iterator pIter must point to an SQLITE_INSERT entry. This function ** transfers new.* values from the current iterator entry to statement @@ -2003,22 +2029,27 @@ static int sessionInsertRow( ** ** An SQLite error code is returned if an error occurs. Otherwise, SQLITE_OK. */ -static int sessionBindValues( +static int sessionBindRow( sqlite3_changeset_iter *pIter, /* Iterator to read values from */ - int(*xIterValue)(sqlite3_changeset_iter *, int, sqlite3_value **), + int(*xValue)(sqlite3_changeset_iter *, int, sqlite3_value **), int nCol, /* Number of columns */ u8 *abPK, /* If not NULL, bind only if true */ sqlite3_stmt *pStmt /* Bind values to this statement */ ){ int i; int rc = SQLITE_OK; + + /* Neither sqlite3changeset_old or sqlite3changeset_new can fail if the + ** argument iterator points to a suitable entry. Make sure that xValue + ** is one of these to guarantee that it is safe to ignore the return + ** in the code below. */ + assert( xValue==sqlite3changeset_old || xValue==sqlite3changeset_new ); + for(i=0; rc==SQLITE_OK && ipSelect); }else if( rc==SQLITE_OK ){ /* No other row with the new.* primary key. */ - rc = sqlite3_reset(p->pSelect); - if( rc==SQLITE_OK ){ - res = xConflict(pCtx, eType+1, pIter); - if( res==SQLITE_CHANGESET_REPLACE ) rc = SQLITE_MISUSE; - } + res = xConflict(pCtx, eType+1, pIter); + if( res==SQLITE_CHANGESET_REPLACE ) rc = SQLITE_MISUSE; } if( rc==SQLITE_OK ){ @@ -2207,7 +2239,7 @@ static int sessionApplyOneOp( if( op==SQLITE_DELETE ){ /* Bind values to the DELETE statement. */ - rc = sessionBindValues(pIter, sqlite3changeset_old, nCol, 0, p->pDelete); + rc = sessionBindRow(pIter, sqlite3changeset_old, nCol, 0, p->pDelete); if( rc==SQLITE_OK && sqlite3_bind_parameter_count(p->pDelete)>nCol ){ rc = sqlite3_bind_int(p->pDelete, nCol+1, pbRetry==0); } @@ -2230,19 +2262,18 @@ static int sessionApplyOneOp( /* Bind values to the UPDATE statement. */ for(i=0; rc==SQLITE_OK && ipUpdate, i*3+2, !!pNew); + if( pOld ){ + rc = sessionBindValue(p->pUpdate, i*3+1, pOld); } - if( rc==SQLITE_OK ){ - if( pOld ) sqlite3_bind_value(p->pUpdate, i*3+1, pOld); - sqlite3_bind_int(p->pUpdate, i*3+2, !!pNew); - if( pNew ) sqlite3_bind_value(p->pUpdate, i*3+3, pNew); + if( rc==SQLITE_OK && pNew ){ + rc = sessionBindValue(p->pUpdate, i*3+3, pNew); } } - if( rc==SQLITE_OK ) rc = sqlite3_bind_int(p->pUpdate, nCol*3+1, pbRetry==0); + if( rc==SQLITE_OK ) sqlite3_bind_int(p->pUpdate, nCol*3+1, pbRetry==0); if( rc!=SQLITE_OK ) return rc; /* Attempt the UPDATE. In the case of a NOTFOUND or DATA conflict, @@ -2268,7 +2299,7 @@ static int sessionApplyOneOp( }else{ assert( op==SQLITE_INSERT ); - rc = sessionBindValues(pIter, sqlite3changeset_new, nCol, 0, p->pInsert); + rc = sessionBindRow(pIter, sqlite3changeset_new, nCol, 0, p->pInsert); if( rc!=SQLITE_OK ) return rc; sqlite3_step(p->pInsert); @@ -2354,7 +2385,7 @@ int sqlite3changeset_apply( assert( pIter->op==SQLITE_INSERT ); rc = sqlite3_exec(db, "SAVEPOINT replace_op", 0, 0, 0); if( rc==SQLITE_OK ){ - rc = sessionBindValues(pIter, + rc = sessionBindRow(pIter, sqlite3changeset_new, sApply.nCol, sApply.abPK, sApply.pDelete); sqlite3_bind_int(sApply.pDelete, sApply.nCol+1, 1); } diff --git a/manifest b/manifest index 6310e57e5f..a2a6acaf3d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\scouple\stypos\sfor\sconsistency\sin\ssessions\sdocumentation. -D 2011-03-22T02:03:23.754 +C Add\sOOM\stests\sand\srelated\sfixes\sfor\sthe\ssession\smodule. +D 2011-03-22T12:08:00 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -101,9 +101,9 @@ F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 F ext/session/session1.test 1e8cda2cc8a60171dabc0fbec4124f9f7c943f23 F ext/session/session2.test 54c3a5ecdc60548a8ab0a86793b136de6f32a255 -F ext/session/session_common.tcl d7bb85c3fd76d53bd9b909da808d5c16f5213111 -F ext/session/sessionfault.test da234166d5d044c91964863174d7171b0561708b -F ext/session/sqlite3session.c 1ca39db8a10b8bcb973b35a68c0924b6a64c4a97 +F ext/session/session_common.tcl c40e81e86b46adc92b7bcb0182eaa70c8523ad8e +F ext/session/sessionfault.test 2dcf303379d0c01d8320f3c7d0452e6a0dcebd48 +F ext/session/sqlite3session.c 2fd432583cc79928b6d31792fc4cb8bfc3e50588 F ext/session/sqlite3session.h 2b7b2b983bba8f7a299922056884912084b32c68 F ext/session/test_session.c 2559ef68e421c7fb83e2c19ef08a17343b70d535 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 @@ -923,7 +923,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 39cdfa5324ae91bfbbac733b1e3e2d33ca883340 -R 7e8df5e06663856423ec54de25f0cd9f -U shaneh -Z a8ae98277851bb377ac869793dff328e +P 510198f171b9f77a4ad49c06c978c5fbb3a5b7f9 +R 64f2c206ae40e85e14ca00143e665617 +U dan +Z 4313381608751ccada39ab0745df4a8f diff --git a/manifest.uuid b/manifest.uuid index e429e99a7c..58da30c0cd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -510198f171b9f77a4ad49c06c978c5fbb3a5b7f9 \ No newline at end of file +06048a68b351e3eb15a890cb54db8a1d4b345fbc \ No newline at end of file From ff4d0f41bb739cc66bcd055b14a201252a31193c Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 22 Mar 2011 15:21:03 +0000 Subject: [PATCH 0031/1484] If a NULL pointer is passed to sqlite3session_attach() in place of a table name, attach all database tables to the session object. FossilOrigin-Name: e9037e4e4ccaa5c633759c4d041b60b631b92c6c --- ext/session/session2.test | 24 +++++++++++++++ ext/session/session_common.tcl | 2 ++ ext/session/sqlite3session.c | 56 +++++++++++++++++++++------------- ext/session/sqlite3session.h | 17 +++++++---- ext/session/test_session.c | 7 +++-- manifest | 20 ++++++------ manifest.uuid | 2 +- 7 files changed, 88 insertions(+), 40 deletions(-) diff --git a/ext/session/session2.test b/ext/session/session2.test index 984559bb12..d0d8fa5617 100644 --- a/ext/session/session2.test +++ b/ext/session/session2.test @@ -258,5 +258,29 @@ foreach {tn sql changeset} { } +#------------------------------------------------------------------------- +# Test that if NULL is passed to sqlite3session_attach(), all database +# tables are attached to the session object. +# +test_reset +do_execsql_test 5.0 { + CREATE TABLE t1(a PRIMARY KEY); + CREATE TABLE t2(x, y PRIMARY KEY); +} + +foreach {tn sql changeset} { + 1 { INSERT INTO t1 VALUES(35) } { {INSERT t1 {} {i 35}} } + 2 { INSERT INTO t2 VALUES(36, 37) } { {INSERT t2 {} {i 36 i 37}} } + 3 { + DELETE FROM t1 WHERE 1; + UPDATE t2 SET x = 34; + } { + {UPDATE t2 {i 36 i 37} {i 34 {} {}}} + {DELETE t1 {i 35} {}} + } +} { + do_iterator_test 5.$tn * $sql $changeset +} + finish_test diff --git a/ext/session/session_common.tcl b/ext/session/session_common.tcl index 41c80dee82..d5c74fba5c 100644 --- a/ext/session/session_common.tcl +++ b/ext/session/session_common.tcl @@ -77,7 +77,9 @@ proc do_then_apply_sql {sql {dbname main}} { proc do_iterator_test {tn tbl_list sql res} { sqlite3session S db main + if {[llength $tbl_list]==0} { S attach * } foreach t $tbl_list {S attach $t} + execsql $sql set r [list] diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index 7c7890aed2..2b0e3ac6bb 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -19,6 +19,7 @@ struct sqlite3_session { sqlite3 *db; /* Database handle session is attached to */ char *zDb; /* Name of database session is attached to */ int bEnable; /* True if currently recording */ + int bAutoAttach; /* True to auto-attach tables */ int rc; /* Non-zero if an error has occurred */ sqlite3_session *pNext; /* Next session object on same db. */ SessionTable *pTable; /* List of attached tables */ @@ -775,7 +776,16 @@ static void xPreUpdate( if( pSession->rc ) continue; if( sqlite3_strnicmp(zDb, pSession->zDb, nDb+1) ) continue; - for(pTab=pSession->pTable; pTab; pTab=pTab->pNext){ + for(pTab=pSession->pTable; pTab || pSession->bAutoAttach; pTab=pTab->pNext){ + if( !pTab ){ + /* This branch is taken if table zName has not yet been attached to + ** this session and the auto-attach flag is set. */ + pSession->rc = sqlite3session_attach(pSession,zName); + if( pSession->rc ) continue; + pTab = pSession->pTable; + assert( 0==sqlite3_strnicmp(pTab->zName, zName, nName+1) ); + } + if( 0==sqlite3_strnicmp(pTab->zName, zName, nName+1) ){ sessionPreupdateOneChange(op, pSession, pTab); if( op==SQLITE_UPDATE ){ @@ -876,31 +886,35 @@ int sqlite3session_attach( sqlite3_session *pSession, /* Session object */ const char *zName /* Table name */ ){ - SessionTable *pTab; /* New table object (if required) */ - int nName; /* Number of bytes in string zName */ int rc = SQLITE_OK; - sqlite3_mutex_enter(sqlite3_db_mutex(pSession->db)); - /* First search for an existing entry. If one is found, this call is - ** a no-op. Return early. */ - nName = strlen(zName); - for(pTab=pSession->pTable; pTab; pTab=pTab->pNext){ - if( 0==sqlite3_strnicmp(pTab->zName, zName, nName+1) ) break; - } + if( !zName ){ + pSession->bAutoAttach = 1; + }else{ + SessionTable *pTab; /* New table object (if required) */ + int nName; /* Number of bytes in string zName */ + + /* First search for an existing entry. If one is found, this call is + ** a no-op. Return early. */ + nName = strlen(zName); + for(pTab=pSession->pTable; pTab; pTab=pTab->pNext){ + if( 0==sqlite3_strnicmp(pTab->zName, zName, nName+1) ) break; + } - if( !pTab ){ - /* Allocate new SessionTable object. */ - pTab = (SessionTable *)sqlite3_malloc(sizeof(SessionTable) + nName + 1); if( !pTab ){ - rc = SQLITE_NOMEM; - }else{ - /* Populate the new SessionTable object and link it into the list. */ - memset(pTab, 0, sizeof(SessionTable)); - pTab->zName = (char *)&pTab[1]; - memcpy(pTab->zName, zName, nName+1); - pTab->pNext = pSession->pTable; - pSession->pTable = pTab; + /* Allocate new SessionTable object. */ + pTab = (SessionTable *)sqlite3_malloc(sizeof(SessionTable) + nName + 1); + if( !pTab ){ + rc = SQLITE_NOMEM; + }else{ + /* Populate the new SessionTable object and link it into the list. */ + memset(pTab, 0, sizeof(SessionTable)); + pTab->zName = (char *)&pTab[1]; + memcpy(pTab->zName, zName, nName+1); + pTab->pNext = pSession->pTable; + pSession->pTable = pTab; + } } } diff --git a/ext/session/sqlite3session.h b/ext/session/sqlite3session.h index 8e1767efab..d9d0ae1f54 100644 --- a/ext/session/sqlite3session.h +++ b/ext/session/sqlite3session.h @@ -93,9 +93,15 @@ int sqlite3session_enable(sqlite3_session *pSession, int bEnable); /* ** CAPI3REF: Attach A Table To A Session Object ** -** Attach a table to a session. All subsequent changes made to the table -** while the session object is enabled will be recorded. See documentation -** for [sqlite3session_changeset()] for further details. +** If argument zTab is not NULL, then it is the name of a table to attach +** to the session object passed as the first argument. All subsequent changes +** made to the table while the session object is enabled will be recorded. See +** documentation for [sqlite3session_changeset()] for further details. +** +** Or, if argument zTab is NULL, then changes are recorded for all tables +** in the database. If additional tables are added to the database (by +** executing "CREATE TABLE" statements) after this call is made, changes for +** the new tables are also recorded. ** ** Changes can only be recorded for tables that have a PRIMARY KEY explicitly ** defined as part of their CREATE TABLE statement. It does not matter if the @@ -109,9 +115,8 @@ int sqlite3session_enable(sqlite3_session *pSession, int bEnable); ** Changes are not recorded for individual rows that have NULL values stored ** in one or more of their PRIMARY KEY columns. ** -** SQLITE_OK is returned if the table is successfully attached to the session -** object. Or, if an error occurs, an SQLite error code (e.g. SQLITE_NOMEM) -** is returned. +** SQLITE_OK is returned if the call completes without error. Or, if an error +** occurs, an SQLite error code (e.g. SQLITE_NOMEM) is returned. */ int sqlite3session_attach( sqlite3_session *pSession, /* Session object */ diff --git a/ext/session/test_session.c b/ext/session/test_session.c index e3c7f4a216..ecc07187d3 100644 --- a/ext/session/test_session.c +++ b/ext/session/test_session.c @@ -54,11 +54,14 @@ static int test_session_cmd( } switch( iSub ){ - case 0: /* attach */ - rc = sqlite3session_attach(pSession, Tcl_GetString(objv[2])); + case 0: { /* attach */ + char *zArg = Tcl_GetString(objv[2]); + if( zArg[0]=='*' && zArg[1]=='\0' ) zArg = 0; + rc = sqlite3session_attach(pSession, zArg); if( rc!=SQLITE_OK ){ return test_session_error(interp, rc); } + } break; case 1: { /* changeset */ diff --git a/manifest b/manifest index a2a6acaf3d..1573c82507 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sOOM\stests\sand\srelated\sfixes\sfor\sthe\ssession\smodule. -D 2011-03-22T12:08:00 +C If\sa\sNULL\spointer\sis\spassed\sto\ssqlite3session_attach()\sin\splace\sof\sa\stable\sname,\sattach\sall\sdatabase\stables\sto\sthe\ssession\sobject. +D 2011-03-22T15:21:04 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -100,12 +100,12 @@ F ext/rtree/sqlite3rtree.h 1af0899c63a688e272d69d8e746f24e76f10a3f0 F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 F ext/session/session1.test 1e8cda2cc8a60171dabc0fbec4124f9f7c943f23 -F ext/session/session2.test 54c3a5ecdc60548a8ab0a86793b136de6f32a255 -F ext/session/session_common.tcl c40e81e86b46adc92b7bcb0182eaa70c8523ad8e +F ext/session/session2.test f993ee243db15025a7d9b1dae903fe3f82f04229 +F ext/session/session_common.tcl fb91560b6dbd086010df8b3a137a452f1ac21a28 F ext/session/sessionfault.test 2dcf303379d0c01d8320f3c7d0452e6a0dcebd48 -F ext/session/sqlite3session.c 2fd432583cc79928b6d31792fc4cb8bfc3e50588 -F ext/session/sqlite3session.h 2b7b2b983bba8f7a299922056884912084b32c68 -F ext/session/test_session.c 2559ef68e421c7fb83e2c19ef08a17343b70d535 +F ext/session/sqlite3session.c c2cc2149e682af9d2ddaab09152ef578c8f97864 +F ext/session/sqlite3session.h 5055e21ca0cb6ddacd46b773a15d90bc0298b0a2 +F ext/session/test_session.c d31fbf5902d0cff5e5495a5ce62efda77b596f2b F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F main.mk ae0868e05c76eaa8a0ae3d6927a949b1c8e810d7 @@ -923,7 +923,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 510198f171b9f77a4ad49c06c978c5fbb3a5b7f9 -R 64f2c206ae40e85e14ca00143e665617 +P 06048a68b351e3eb15a890cb54db8a1d4b345fbc +R aba670c08b10d639853d25c358b85571 U dan -Z 4313381608751ccada39ab0745df4a8f +Z 48e2e8d1a1883a86d400f9c1e1c32110 diff --git a/manifest.uuid b/manifest.uuid index 58da30c0cd..f56d01fe0f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -06048a68b351e3eb15a890cb54db8a1d4b345fbc \ No newline at end of file +e9037e4e4ccaa5c633759c4d041b60b631b92c6c \ No newline at end of file From 245b49b2030989768c410ea1459f791a131216cb Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 22 Mar 2011 16:54:12 +0000 Subject: [PATCH 0032/1484] Fix a crash that can follow an OOM when "all tables" are registered with a session module. FossilOrigin-Name: 183c236e991faaabdc768e52e926c52cf4a7abc9 --- ext/session/sessionfault.test | 32 +++++++++++++++++++++++++++++++- ext/session/sqlite3session.c | 2 +- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 40 insertions(+), 10 deletions(-) diff --git a/ext/session/sessionfault.test b/ext/session/sessionfault.test index 7ba05bbb22..c8ce9e48af 100644 --- a/ext/session/sessionfault.test +++ b/ext/session/sessionfault.test @@ -34,7 +34,11 @@ db2 close #------------------------------------------------------------------------- # Test OOM error handling when collecting and applying a simple changeset. # -do_faultsim_test pagerfault-1 -faults oom-* -prep { +# Test 1.1 attaches tables individually by name to the session object. +# Whereas test 1.2 passes NULL to sqlite3session_attach() to attach all +# tables. +# +do_faultsim_test pagerfault-1.1 -faults oom-* -prep { catch {db2 close} catch {db close} faultsim_restore_and_reopen @@ -51,6 +55,32 @@ do_faultsim_test pagerfault-1 -faults oom-* -prep { if {$testrc==0} { compare_db db db2 } } +do_faultsim_test pagerfault-1.2 -faults oom-* -prep { + catch {db2 close} + catch {db close} + faultsim_restore_and_reopen +} -body { + sqlite3session S db main + S attach * + execsql { + INSERT INTO t1 VALUES(7, 8, 9); + UPDATE t1 SET c = 10 WHERE a = 1; + DELETE FROM t1 WHERE a = 4; + } + set ::changeset [S changeset] + set {} {} +} -test { + catch { S delete } + faultsim_test_result {0 {}} {1 SQLITE_NOMEM} + faultsim_integrity_check + if {$testrc==0} { + proc xConflict {args} { return "OMIT" } + sqlite3 db2 test.db2 + sqlite3changeset_apply db2 $::changeset xConflict + compare_db db db2 + } +} + #------------------------------------------------------------------------- # The following block of tests - pagerfault-2.* - are designed to check # the handling of faults in the sqlite3changeset_apply() function. diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index 2b0e3ac6bb..3619e7c4b6 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -781,7 +781,7 @@ static void xPreUpdate( /* This branch is taken if table zName has not yet been attached to ** this session and the auto-attach flag is set. */ pSession->rc = sqlite3session_attach(pSession,zName); - if( pSession->rc ) continue; + if( pSession->rc ) break; pTab = pSession->pTable; assert( 0==sqlite3_strnicmp(pTab->zName, zName, nName+1) ); } diff --git a/manifest b/manifest index 1573c82507..8c992e020b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C If\sa\sNULL\spointer\sis\spassed\sto\ssqlite3session_attach()\sin\splace\sof\sa\stable\sname,\sattach\sall\sdatabase\stables\sto\sthe\ssession\sobject. -D 2011-03-22T15:21:04 +C Fix\sa\scrash\sthat\scan\sfollow\san\sOOM\swhen\s"all\stables"\sare\sregistered\swith\sa\ssession\smodule. +D 2011-03-22T16:54:12 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -102,8 +102,8 @@ F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 F ext/session/session1.test 1e8cda2cc8a60171dabc0fbec4124f9f7c943f23 F ext/session/session2.test f993ee243db15025a7d9b1dae903fe3f82f04229 F ext/session/session_common.tcl fb91560b6dbd086010df8b3a137a452f1ac21a28 -F ext/session/sessionfault.test 2dcf303379d0c01d8320f3c7d0452e6a0dcebd48 -F ext/session/sqlite3session.c c2cc2149e682af9d2ddaab09152ef578c8f97864 +F ext/session/sessionfault.test 495f87fb9bd764ae90d4b40d0c33a76d86d9063e +F ext/session/sqlite3session.c ec0f440ae73229ae8ae307a31e631b9d71991cd4 F ext/session/sqlite3session.h 5055e21ca0cb6ddacd46b773a15d90bc0298b0a2 F ext/session/test_session.c d31fbf5902d0cff5e5495a5ce62efda77b596f2b F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 @@ -923,7 +923,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 06048a68b351e3eb15a890cb54db8a1d4b345fbc -R aba670c08b10d639853d25c358b85571 +P e9037e4e4ccaa5c633759c4d041b60b631b92c6c +R 93198cfc6613c93be1aa416f0de3d035 U dan -Z 48e2e8d1a1883a86d400f9c1e1c32110 +Z ee6ba5845d31702e943c5fa7b7c9db34 diff --git a/manifest.uuid b/manifest.uuid index f56d01fe0f..406e8e8902 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e9037e4e4ccaa5c633759c4d041b60b631b92c6c \ No newline at end of file +183c236e991faaabdc768e52e926c52cf4a7abc9 \ No newline at end of file From 1e7a2d431532c931e0d2e122a43c3a70e2e4ffb5 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 22 Mar 2011 18:45:29 +0000 Subject: [PATCH 0033/1484] Add API function sqlite3_preupdate_depth(), for determining the depth of the trigger stack from within a pre-update callback. FossilOrigin-Name: bdea70895c2c686a4dd3f4bf0a475fd1501d9551 --- manifest | 18 ++++---- manifest.uuid | 2 +- src/sqlite.h.in | 1 + src/tclsqlite.c | 15 ++++++- src/vdbeapi.c | 16 +++++++ test/hook.test | 112 ++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 152 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 8c992e020b..20662eaa2f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\scrash\sthat\scan\sfollow\san\sOOM\swhen\s"all\stables"\sare\sregistered\swith\sa\ssession\smodule. -D 2011-03-22T16:54:12 +C Add\sAPI\sfunction\ssqlite3_preupdate_depth(),\sfor\sdetermining\sthe\sdepth\sof\sthe\strigger\sstack\sfrom\swithin\sa\spre-update\scallback. +D 2011-03-22T18:45:30 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -185,13 +185,13 @@ F src/resolve.c 1c0f32b64f8e3f555fe1f732f9d6f501a7f05706 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 F src/select.c d24406c45dd2442eb2eeaac413439066b149c944 F src/shell.c 4a5e0ad845475c84881f0b25b1abba2ddaab0a72 -F src/sqlite.h.in 62de507787b39cb58b52002a1ee974e09dd5c83a +F src/sqlite.h.in 6b93765e048e0023e23c1d9827a561d7ead7100a F src/sqlite3ext.h c90bd5507099f62043832d73f6425d8d5c5da754 F src/sqliteInt.h 10707dc735a0077741e1b4b1550891abc26d7582 F src/sqliteLimit.h a17dcd3fb775d63b64a43a55c54cb282f9726f44 F src/status.c 4997380fbb915426fef9e500b4872e79c99267fc F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e -F src/tclsqlite.c 520e124994e68fd8804ade95b5d3e2e791d0958d +F src/tclsqlite.c 78713534e628ea92b032bfa20ea8a1afc6cdb124 F src/test1.c 9020310c7617234b33fd1c3064f89524db25f290 F src/test2.c 80d323d11e909cf0eb1b6fbb4ac22276483bcf31 F src/test3.c 056093cfef69ff4227a6bdb9108564dc7f45e4bc @@ -241,7 +241,7 @@ F src/vacuum.c 924bd1bcee2dfb05376f79845bd3b4cec7b54b2f F src/vdbe.c c90edafd941481506f001b17cd8523683fdac853 F src/vdbe.h edef9c4f0be83e1f1dccd049da37b40e021b63d9 F src/vdbeInt.h 2cf77c1d151a4a54facd596d52be6d60c1cb26e8 -F src/vdbeapi.c 3d620e00cb74b6034343009af42d5ff5eb7c19dc +F src/vdbeapi.c e472b3e5985175e948e70025cb3bffa8a2e185c8 F src/vdbeaux.c 0216b2c37509a44c3833b297765bee7bdd04fa2f F src/vdbeblob.c c3ccb7c8732858c680f442932e66ad06bb036562 F src/vdbemem.c 0498796b6ffbe45e32960d6a1f5adfb6e419883b @@ -481,7 +481,7 @@ F test/fuzz2.test 207d0f9d06db3eaf47a6b7bfc835b8e2fc397167 F test/fuzz3.test aec64345184d1662bd30e6a17851ff659d596dc5 F test/fuzz_common.tcl a87dfbb88c2a6b08a38e9a070dabd129e617b45b F test/fuzz_malloc.test dd7001ac86d09c154a7dff064f4739c60e2b312c -F test/hook.test d054aad1a3772dd9045510382875468a9dcae15f +F test/hook.test 14b2439b878c9aae03a3684cba717be4bfdcc1c1 F test/icu.test 70df4faca133254c042d02ae342c0a141f2663f4 F test/in.test 19b642bb134308980a92249750ea4ce3f6c75c2d F test/in2.test 5d4c61d17493c832f7d2d32bef785119e87bde75 @@ -923,7 +923,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P e9037e4e4ccaa5c633759c4d041b60b631b92c6c -R 93198cfc6613c93be1aa416f0de3d035 +P 183c236e991faaabdc768e52e926c52cf4a7abc9 +R 3714f49d9e3ab391fe868f9d204fa8d5 U dan -Z ee6ba5845d31702e943c5fa7b7c9db34 +Z 4e2f4fe62e6298f01b15895da5c35a23 diff --git a/manifest.uuid b/manifest.uuid index 406e8e8902..cf0cd54d72 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -183c236e991faaabdc768e52e926c52cf4a7abc9 \ No newline at end of file +bdea70895c2c686a4dd3f4bf0a475fd1501d9551 \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 80a19002fa..2ee63f24f1 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -6405,6 +6405,7 @@ SQLITE_EXPERIMENTAL void *sqlite3_preupdate_hook( ); SQLITE_EXPERIMENTAL int sqlite3_preupdate_old(sqlite3 *, int, sqlite3_value **); SQLITE_EXPERIMENTAL int sqlite3_preupdate_count(sqlite3 *); +SQLITE_EXPERIMENTAL int sqlite3_preupdate_depth(sqlite3 *); SQLITE_EXPERIMENTAL int sqlite3_preupdate_new(sqlite3 *, int, sqlite3_value **); /* diff --git a/src/tclsqlite.c b/src/tclsqlite.c index 092295a2d1..2d945be532 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -2851,9 +2851,9 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ ** $db preupdate_hook old INDEX */ case DB_PREUPDATE: { - static const char *azSub[] = {"count", "hook", "new", "old", 0}; + static const char *azSub[] = {"count", "depth", "hook", "new", "old", 0}; enum DbPreupdateSubCmd { - PRE_COUNT, PRE_HOOK, PRE_NEW, PRE_OLD + PRE_COUNT, PRE_DEPTH, PRE_HOOK, PRE_NEW, PRE_OLD }; int iSub; @@ -2880,6 +2880,17 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ break; } + case PRE_DEPTH: { + Tcl_Obj *pRet; + if( objc!=3 ){ + Tcl_WrongNumArgs(interp, 3, objv, ""); + return TCL_ERROR; + } + pRet = Tcl_NewIntObj(sqlite3_preupdate_depth(pDb->db)); + Tcl_SetObjResult(interp, pRet); + break; + } + case PRE_NEW: case PRE_OLD: { int iIdx; diff --git a/src/vdbeapi.c b/src/vdbeapi.c index 829d4678b6..b485aa7483 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -1391,6 +1391,22 @@ int sqlite3_preupdate_count(sqlite3 *db){ return (p ? p->pCsr->nField : 0); } +/* +** This function is designed to be called from within a pre-update callback +** only. It returns zero if the change that caused the callback was made +** immediately by a user SQL statement. Or, if the change was made by a +** trigger program, it returns the number of trigger programs currently +** on the stack (1 for a top-level trigger, 2 for a trigger fired by a +** top-level trigger etc.). +** +** For the purposes of the previous paragraph, a foreign key CASCADE, SET NULL +** or SET DEFAULT action is considered a trigger. +*/ +int sqlite3_preupdate_depth(sqlite3 *db){ + PreUpdate *p = db->pPreUpdate; + return (p ? p->v->nFrame : 0); +} + /* ** This function is called from within a pre-update callback to retrieve ** a field of the row currently being updated or inserted. diff --git a/test/hook.test b/test/hook.test index 9ceedbb75d..016569f0ae 100644 --- a/test/hook.test +++ b/test/hook.test @@ -651,6 +651,118 @@ do_preupdate_test 7.6.2 { DELETE main t9 3 3 1 3 4 } +#-------------------------------------------------------------------------- +# Test that the sqlite3_preupdate_depth() API seems to work. +# +proc preupdate_hook {args} { + set type [lindex $args 0] + eval lappend ::preupdate $args + eval lappend ::preupdate [db preupdate depth] + + if {$type != "INSERT"} { + for {set i 0} {$i < [db preupdate count]} {incr i} { + lappend ::preupdate [db preupdate old $i] + } + } + if {$type != "DELETE"} { + for {set i 0} {$i < [db preupdate count]} {incr i} { + set rc [catch { db preupdate new $i } v] + lappend ::preupdate $v + } + } +} + +db close +forcedelete test.db +sqlite3 db test.db +db preupdate hook preupdate_hook + +do_execsql_test 7.6.1 { + CREATE TABLE t1(x PRIMARY KEY); + CREATE TABLE t2(x PRIMARY KEY); + CREATE TABLE t3(x PRIMARY KEY); + CREATE TABLE t4(x PRIMARY KEY); + + CREATE TRIGGER a AFTER INSERT ON t1 BEGIN INSERT INTO t2 VALUES(new.x); END; + CREATE TRIGGER b AFTER INSERT ON t2 BEGIN INSERT INTO t3 VALUES(new.x); END; + CREATE TRIGGER c AFTER INSERT ON t3 BEGIN INSERT INTO t4 VALUES(new.x); END; + + CREATE TRIGGER d AFTER UPDATE ON t1 BEGIN UPDATE t2 SET x = new.x; END; + CREATE TRIGGER e AFTER UPDATE ON t2 BEGIN UPDATE t3 SET x = new.x; END; + CREATE TRIGGER f AFTER UPDATE ON t3 BEGIN UPDATE t4 SET x = new.x; END; + + CREATE TRIGGER g AFTER DELETE ON t1 BEGIN DELETE FROM t2 WHERE 1; END; + CREATE TRIGGER h AFTER DELETE ON t2 BEGIN DELETE FROM t3 WHERE 1; END; + CREATE TRIGGER i AFTER DELETE ON t3 BEGIN DELETE FROM t4 WHERE 1; END; +} + +do_preupdate_test 7.6.2 { + INSERT INTO t1 VALUES('xyz'); +} { + INSERT main t1 1 1 0 xyz + INSERT main t2 1 1 1 xyz + INSERT main t3 1 1 2 xyz + INSERT main t4 1 1 3 xyz +} +do_preupdate_test 7.6.3 { + UPDATE t1 SET x = 'abc'; +} { + UPDATE main t1 1 1 0 xyz abc + UPDATE main t2 1 1 1 xyz abc + UPDATE main t3 1 1 2 xyz abc + UPDATE main t4 1 1 3 xyz abc +} +do_preupdate_test 7.6.4 { + DELETE FROM t1 WHERE 1; +} { + DELETE main t1 1 1 0 abc + DELETE main t2 1 1 1 abc + DELETE main t3 1 1 2 abc + DELETE main t4 1 1 3 abc +} + +do_execsql_test 7.6.5 { + DROP TRIGGER a; DROP TRIGGER b; DROP TRIGGER c; + DROP TRIGGER d; DROP TRIGGER e; DROP TRIGGER f; + DROP TRIGGER g; DROP TRIGGER h; DROP TRIGGER i; + + CREATE TRIGGER a BEFORE INSERT ON t1 BEGIN INSERT INTO t2 VALUES(new.x); END; + CREATE TRIGGER b BEFORE INSERT ON t2 BEGIN INSERT INTO t3 VALUES(new.x); END; + CREATE TRIGGER c BEFORE INSERT ON t3 BEGIN INSERT INTO t4 VALUES(new.x); END; + + CREATE TRIGGER d BEFORE UPDATE ON t1 BEGIN UPDATE t2 SET x = new.x; END; + CREATE TRIGGER e BEFORE UPDATE ON t2 BEGIN UPDATE t3 SET x = new.x; END; + CREATE TRIGGER f BEFORE UPDATE ON t3 BEGIN UPDATE t4 SET x = new.x; END; + + CREATE TRIGGER g BEFORE DELETE ON t1 BEGIN DELETE FROM t2 WHERE 1; END; + CREATE TRIGGER h BEFORE DELETE ON t2 BEGIN DELETE FROM t3 WHERE 1; END; + CREATE TRIGGER i BEFORE DELETE ON t3 BEGIN DELETE FROM t4 WHERE 1; END; +} + +do_preupdate_test 7.6.6 { + INSERT INTO t1 VALUES('xyz'); +} { + INSERT main t4 1 1 3 xyz + INSERT main t3 1 1 2 xyz + INSERT main t2 1 1 1 xyz + INSERT main t1 1 1 0 xyz +} +do_preupdate_test 7.6.3 { + UPDATE t1 SET x = 'abc'; +} { + UPDATE main t4 1 1 3 xyz abc + UPDATE main t3 1 1 2 xyz abc + UPDATE main t2 1 1 1 xyz abc + UPDATE main t1 1 1 0 xyz abc +} +do_preupdate_test 7.6.4 { + DELETE FROM t1 WHERE 1; +} { + DELETE main t4 1 1 3 abc + DELETE main t3 1 1 2 abc + DELETE main t2 1 1 1 abc + DELETE main t1 1 1 0 abc +} finish_test From b4480e942ff9480be5d60e5e1cca6b4d83181e2f Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 23 Mar 2011 16:03:11 +0000 Subject: [PATCH 0034/1484] Add the "indirect flag" to the changeset blob format. Also the sqlite3session_indirect() API. FossilOrigin-Name: 1feaf2d35fd9ec777319717ae2c2929d66fe7baa --- ext/session/session1.test | 44 ++++++------ ext/session/session2.test | 124 ++++++++++++++++++++++++++++++---- ext/session/sessionfault.test | 20 +++--- ext/session/sqlite3session.c | 72 +++++++++++++++----- ext/session/sqlite3session.h | 43 ++++++++++-- ext/session/test_session.c | 18 ++++- manifest | 22 +++--- manifest.uuid | 2 +- 8 files changed, 260 insertions(+), 85 deletions(-) diff --git a/ext/session/session1.test b/ext/session/session1.test index 1d8b1921b9..582f802bea 100644 --- a/ext/session/session1.test +++ b/ext/session/session1.test @@ -88,14 +88,14 @@ do_test 2.1.1 { execsql { INSERT INTO t1 VALUES(3, 'Thonburi') } } {} do_changeset_test 2.1.2 S { - {INSERT t1 {} {i 1 t Sukhothai}} - {INSERT t1 {} {i 2 t Ayutthaya}} - {INSERT t1 {} {i 3 t Thonburi}} + {INSERT t1 0 {} {i 1 t Sukhothai}} + {INSERT t1 0 {} {i 2 t Ayutthaya}} + {INSERT t1 0 {} {i 3 t Thonburi}} } do_changeset_invert_test 2.1.3 S { - {DELETE t1 {i 1 t Sukhothai} {}} - {DELETE t1 {i 2 t Ayutthaya} {}} - {DELETE t1 {i 3 t Thonburi} {}} + {DELETE t1 0 {i 1 t Sukhothai} {}} + {DELETE t1 0 {i 2 t Ayutthaya} {}} + {DELETE t1 0 {i 3 t Thonburi} {}} } do_test 2.1.4 { S delete } {} @@ -105,14 +105,14 @@ do_test 2.2.1 { execsql { DELETE FROM t1 WHERE 1 } } {} do_changeset_test 2.2.2 S { - {DELETE t1 {i 1 t Sukhothai} {}} - {DELETE t1 {i 2 t Ayutthaya} {}} - {DELETE t1 {i 3 t Thonburi} {}} + {DELETE t1 0 {i 1 t Sukhothai} {}} + {DELETE t1 0 {i 2 t Ayutthaya} {}} + {DELETE t1 0 {i 3 t Thonburi} {}} } do_changeset_invert_test 2.2.3 S { - {INSERT t1 {} {i 1 t Sukhothai}} - {INSERT t1 {} {i 2 t Ayutthaya}} - {INSERT t1 {} {i 3 t Thonburi}} + {INSERT t1 0 {} {i 1 t Sukhothai}} + {INSERT t1 0 {} {i 2 t Ayutthaya}} + {INSERT t1 0 {} {i 3 t Thonburi}} } do_test 2.2.4 { S delete } {} @@ -131,19 +131,19 @@ do_test 2.3.1 { } {} do_changeset_test 2.3.2 S { - {INSERT t1 {} {i 10 t Sukhothai}} - {DELETE t1 {i 1 t Sukhothai} {}} - {UPDATE t1 {i 2 t Ayutthaya} {{} {} t Surin}} - {DELETE t1 {i 3 t Thonburi} {}} - {INSERT t1 {} {i 20 t Thapae}} + {INSERT t1 0 {} {i 10 t Sukhothai}} + {DELETE t1 0 {i 1 t Sukhothai} {}} + {UPDATE t1 0 {i 2 t Ayutthaya} {{} {} t Surin}} + {DELETE t1 0 {i 3 t Thonburi} {}} + {INSERT t1 0 {} {i 20 t Thapae}} } do_changeset_invert_test 2.3.3 S { - {DELETE t1 {i 10 t Sukhothai} {}} - {INSERT t1 {} {i 1 t Sukhothai}} - {UPDATE t1 {{} {} t Surin} {i 2 t Ayutthaya}} - {INSERT t1 {} {i 3 t Thonburi}} - {DELETE t1 {i 20 t Thapae} {}} + {DELETE t1 0 {i 10 t Sukhothai} {}} + {INSERT t1 0 {} {i 1 t Sukhothai}} + {UPDATE t1 0 {{} {} t Surin} {i 2 t Ayutthaya}} + {INSERT t1 0 {} {i 3 t Thonburi}} + {DELETE t1 0 {i 20 t Thapae} {}} } do_test 2.3.4 { S delete } {} diff --git a/ext/session/session2.test b/ext/session/session2.test index d0d8fa5617..d6cb284659 100644 --- a/ext/session/session2.test +++ b/ext/session/session2.test @@ -41,13 +41,13 @@ do_iterator_test 1.1 t1 { DELETE FROM t1 WHERE a = 'i'; INSERT INTO t1 VALUES('ii', 'two'); } { - {DELETE t1 {t i t one} {}} - {INSERT t1 {} {t ii t two}} + {DELETE t1 0 {t i t one} {}} + {INSERT t1 0 {} {t ii t two}} } do_iterator_test 1.2 t1 { INSERT INTO t1 VALUES(1.5, 99.9) } { - {INSERT t1 {} {f 1.5 f 99.9}} + {INSERT t1 0 {} {f 1.5 f 99.9}} } @@ -228,15 +228,15 @@ foreach {tn sql changeset} { INSERT INTO t1 VALUES(NULL); INSERT INTO t1 VALUES(456); } { - {INSERT t1 {} {i 456}} - {INSERT t1 {} {i 123}} + {INSERT t1 0 {} {i 456}} + {INSERT t1 0 {} {i 123}} } 2 { UPDATE t1 SET a = NULL; } { - {DELETE t1 {i 456} {}} - {DELETE t1 {i 123} {}} + {DELETE t1 0 {i 456} {}} + {DELETE t1 0 {i 123} {}} } 3 { DELETE FROM t1 } { } @@ -244,14 +244,14 @@ foreach {tn sql changeset} { 4 { INSERT INTO t3 VALUES(NULL, NULL) } { - {INSERT t3 {} {n {} i 1}} + {INSERT t3 0 {} {n {} i 1}} } 5 { INSERT INTO t2 VALUES(1, 2, NULL) } { } 6 { INSERT INTO t2 VALUES(1, NULL, 3) } { } 7 { INSERT INTO t2 VALUES(1, NULL, NULL) } { } - 8 { INSERT INTO t2 VALUES(1, 2, 3) } { {INSERT t2 {} {i 1 i 2 i 3}} } - 9 { DELETE FROM t2 WHERE 1 } { {DELETE t2 {i 1 i 2 i 3} {}} } + 8 { INSERT INTO t2 VALUES(1, 2, 3) } { {INSERT t2 0 {} {i 1 i 2 i 3}} } + 9 { DELETE FROM t2 WHERE 1 } { {DELETE t2 0 {i 1 i 2 i 3} {}} } } { do_iterator_test 4.$tn {t1 t2 t3} $sql $changeset @@ -269,18 +269,112 @@ do_execsql_test 5.0 { } foreach {tn sql changeset} { - 1 { INSERT INTO t1 VALUES(35) } { {INSERT t1 {} {i 35}} } - 2 { INSERT INTO t2 VALUES(36, 37) } { {INSERT t2 {} {i 36 i 37}} } + 1 { INSERT INTO t1 VALUES(35) } { {INSERT t1 0 {} {i 35}} } + 2 { INSERT INTO t2 VALUES(36, 37) } { {INSERT t2 0 {} {i 36 i 37}} } 3 { DELETE FROM t1 WHERE 1; UPDATE t2 SET x = 34; } { - {UPDATE t2 {i 36 i 37} {i 34 {} {}}} - {DELETE t1 {i 35} {}} + {UPDATE t2 0 {i 36 i 37} {i 34 {} {}}} + {DELETE t1 0 {i 35} {}} } } { do_iterator_test 5.$tn * $sql $changeset } -finish_test +#------------------------------------------------------------------------- +# The next block of tests verify that the "indirect" flag is set +# correctly within changesets. The indirect flag is set for a change +# if either of the following are true: +# +# * The sqlite3session_indirect() API has been used to set the session +# indirect flag to true, or +# * The change was made by a trigger. +# +# If the same row is updated more than once during a session, then the +# change is considered indirect only if all changes meet the criteria +# above. +# +test_reset +db function indirect [list S indirect] +do_execsql_test 6.0 { + CREATE TABLE t1(a PRIMARY KEY, b, c); + + CREATE TABLE t2(x PRIMARY KEY, y); + CREATE TRIGGER AFTER INSERT ON t2 WHEN new.x%2 BEGIN + INSERT INTO t2 VALUES(new.x+1, NULL); + END; +} + +do_iterator_test 6.1.1 * { + INSERT INTO t1 VALUES(1, 'one', 'i'); + SELECT indirect(1); + INSERT INTO t1 VALUES(2, 'two', 'ii'); + SELECT indirect(0); + INSERT INTO t1 VALUES(3, 'three', 'iii'); +} { + {INSERT t1 0 {} {i 1 t one t i}} + {INSERT t1 1 {} {i 2 t two t ii}} + {INSERT t1 0 {} {i 3 t three t iii}} +} + +do_iterator_test 6.1.2 * { + SELECT indirect(1); + UPDATE t1 SET c = 'I' WHERE a = 1; + SELECT indirect(0); +} { + {UPDATE t1 1 {i 1 {} {} t i} {{} {} {} {} t I}} +} +do_iterator_test 6.1.3 * { + SELECT indirect(1); + UPDATE t1 SET c = '.' WHERE a = 1; + SELECT indirect(0); + UPDATE t1 SET c = 'o' WHERE a = 1; +} { + {UPDATE t1 0 {i 1 {} {} t I} {{} {} {} {} t o}} +} +do_iterator_test 6.1.4 * { + SELECT indirect(0); + UPDATE t1 SET c = 'x' WHERE a = 1; + SELECT indirect(1); + UPDATE t1 SET c = 'i' WHERE a = 1; +} { + {UPDATE t1 0 {i 1 {} {} t o} {{} {} {} {} t i}} +} +do_iterator_test 6.1.4 * { + SELECT indirect(1); + UPDATE t1 SET c = 'y' WHERE a = 1; + SELECT indirect(1); + UPDATE t1 SET c = 'I' WHERE a = 1; +} { + {UPDATE t1 1 {i 1 {} {} t i} {{} {} {} {} t I}} +} + +do_iterator_test 6.1.5 * { + INSERT INTO t2 VALUES(1, 'x'); +} { + {INSERT t2 0 {} {i 1 t x}} + {INSERT t2 1 {} {i 2 n {}}} +} + +do_iterator_test 6.1.6 * { + SELECT indirect(1); + INSERT INTO t2 VALUES(3, 'x'); + SELECT indirect(0); + UPDATE t2 SET y = 'y' WHERE x>2; +} { + {INSERT t2 0 {} {i 3 t y}} + {INSERT t2 0 {} {i 4 t y}} +} + +do_iterator_test 6.1.7 * { + SELECT indirect(1); + DELETE FROM t2 WHERE x = 4; + SELECT indirect(0); + INSERT INTO t2 VALUES(4, 'new'); +} { + {UPDATE t2 0 {i 4 t y} {{} {} t new}} +} + +finish_test diff --git a/ext/session/sessionfault.test b/ext/session/sessionfault.test index c8ce9e48af..04ac8b8b88 100644 --- a/ext/session/sessionfault.test +++ b/ext/session/sessionfault.test @@ -38,7 +38,7 @@ db2 close # Whereas test 1.2 passes NULL to sqlite3session_attach() to attach all # tables. # -do_faultsim_test pagerfault-1.1 -faults oom-* -prep { +do_faultsim_test 1.1 -faults oom-* -prep { catch {db2 close} catch {db close} faultsim_restore_and_reopen @@ -55,7 +55,7 @@ do_faultsim_test pagerfault-1.1 -faults oom-* -prep { if {$testrc==0} { compare_db db db2 } } -do_faultsim_test pagerfault-1.2 -faults oom-* -prep { +do_faultsim_test 1.2 -faults oom-* -prep { catch {db2 close} catch {db close} faultsim_restore_and_reopen @@ -82,7 +82,7 @@ do_faultsim_test pagerfault-1.2 -faults oom-* -prep { } #------------------------------------------------------------------------- -# The following block of tests - pagerfault-2.* - are designed to check +# The following block of tests - 2.* - are designed to check # the handling of faults in the sqlite3changeset_apply() function. # catch {db close} @@ -110,7 +110,7 @@ foreach {tn conflict_policy sql sql2} { } { proc xConflict args [list return $conflict_policy] - do_faultsim_test pagerfault-2.$tn -faults oom-transient -prep { + do_faultsim_test 2.$tn -faults oom-transient -prep { catch {db2 close} catch {db close} faultsim_restore_and_reopen @@ -132,7 +132,7 @@ foreach {tn conflict_policy sql sql2} { # resizing the session object hash-table from 256 to 512 buckets. This # is not an error, just a sub-optimal condition. # -do_faultsim_test pagerfault-3 -faults oom-* -prep { +do_faultsim_test 3 -faults oom-* -prep { catch {db2 close} catch {db close} faultsim_restore_and_reopen @@ -191,7 +191,7 @@ do_test 4.0 { faultsim_save_and_close db2 close -do_faultsim_test pagerfault-4 -faults oom-* -prep { +do_faultsim_test 4 -faults oom-* -prep { catch {db2 close} catch {db close} faultsim_restore_and_reopen @@ -234,7 +234,7 @@ set changeset [changeset_from_sql { }] db close -do_faultsim_test pagerfault-5 -faults oom* -body { +do_faultsim_test 5 -faults oom* -body { set ::inverse [sqlite3changeset_invert $::changeset] set {} {} } -test { @@ -243,9 +243,9 @@ do_faultsim_test pagerfault-5 -faults oom* -body { set x [list] sqlite3session_foreach c $::inverse { lappend x $c } foreach c { - {DELETE t1 {t xxx t yyy} {}} - {INSERT t1 {} {t string i 1}} - {UPDATE t1 {i 20 {} {}} {i 4 i 2}} + {DELETE t1 0 {t xxx t yyy} {}} + {INSERT t1 0 {} {t string i 1}} + {UPDATE t1 0 {i 20 {} {}} {i 4 i 2}} } { lappend y $c } if {$x != $y} { error "changeset no good" } } diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index 3619e7c4b6..ff28487d3c 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -19,6 +19,7 @@ struct sqlite3_session { sqlite3 *db; /* Database handle session is attached to */ char *zDb; /* Name of database session is attached to */ int bEnable; /* True if currently recording */ + int bIndirect; /* True if all changes are indirect */ int bAutoAttach; /* True to auto-attach tables */ int rc; /* Non-zero if an error has occurred */ sqlite3_session *pNext; /* Next session object on same db. */ @@ -37,6 +38,7 @@ struct sqlite3_changeset_iter { char *zTab; /* Current table */ int nCol; /* Number of columns in zTab */ int op; /* Current operation */ + int bIndirect; /* True if current change was indirect */ sqlite3_value **apValue; /* old.* and new.* values */ }; @@ -131,6 +133,7 @@ struct SessionTable { */ struct SessionChange { int bInsert; /* True if row was inserted this session */ + int bIndirect; /* True if this change is "indirect" */ int nRecord; /* Number of bytes in buffer aRecord[] */ u8 *aRecord; /* Buffer containing old.* record */ SessionChange *pNext; /* For hash-table collisions */ @@ -660,8 +663,6 @@ static void sessionPreupdateOneChange( SessionTable *pTab ){ sqlite3 *db = pSession->db; - SessionChange *pChange; - SessionChange *pC; int iHash; int bNullPk = 0; int rc = SQLITE_OK; @@ -679,7 +680,8 @@ static void sessionPreupdateOneChange( ** the hash table. Otherwise, set pChange to NULL. */ rc = sessionPreupdateHash(db, pTab, op==SQLITE_INSERT, &iHash, &bNullPk); - if( bNullPk==0 ){ + if( rc==SQLITE_OK && bNullPk==0 ){ + SessionChange *pC; for(pC=pTab->apChange[iHash]; rc==SQLITE_OK && pC; pC=pC->pNext){ int bEqual; rc = sessionPreupdateEqual(db, pTab, pC, op==SQLITE_INSERT, &bEqual); @@ -689,9 +691,11 @@ static void sessionPreupdateOneChange( /* Create a new change object containing all the old values (if ** this is an SQLITE_UPDATE or SQLITE_DELETE), or just the PK ** values (if this is an INSERT). */ + SessionChange *pChange; /* New change object */ int nByte; /* Number of bytes to allocate */ int i; /* Used to iterate through columns */ + assert( rc==SQLITE_OK ); pTab->nEntry++; /* Figure out how large an allocation is required */ @@ -732,6 +736,9 @@ static void sessionPreupdateOneChange( } if( rc==SQLITE_OK ){ /* Add the change back to the hash-table */ + if( pSession->bIndirect || sqlite3_preupdate_depth(pSession->db) ){ + pChange->bIndirect = 1; + } pChange->nRecord = nByte; pChange->bInsert = (op==SQLITE_INSERT); pChange->pNext = pTab->apChange[iHash]; @@ -739,6 +746,12 @@ static void sessionPreupdateOneChange( }else{ sqlite3_free(pChange); } + }else if( rc==SQLITE_OK && pC->bIndirect ){ + /* If the existing change is considered "indirect", but this current + ** change is "direct", mark the change object as direct. */ + if( sqlite3_preupdate_depth(pSession->db)==0 && pSession->bIndirect==0 ){ + pC->bIndirect = 0; + } } } @@ -1136,6 +1149,7 @@ static void sessionAppendUpdate( u8 *pCsr = p->aRecord; /* Used to iterate through old.* values */ sessionAppendByte(pBuf, SQLITE_UPDATE, pRc); + sessionAppendByte(pBuf, p->bIndirect, pRc); for(i=0; ibInsert ){ sessionAppendByte(&buf, SQLITE_INSERT, &rc); + sessionAppendByte(&buf, p->bIndirect, &rc); for(iCol=0; iColbInsert ){ /* A DELETE change */ sessionAppendByte(&buf, SQLITE_DELETE, &rc); + sessionAppendByte(&buf, p->bIndirect, &rc); sessionAppendBlob(&buf, p->aRecord, p->nRecord, &rc); } if( rc==SQLITE_OK ){ @@ -1416,6 +1432,20 @@ int sqlite3session_enable(sqlite3_session *pSession, int bEnable){ return ret; } +/* +** Enable or disable the session object passed as the first argument. +*/ +int sqlite3session_indirect(sqlite3_session *pSession, int bIndirect){ + int ret; + sqlite3_mutex_enter(sqlite3_db_mutex(pSession->db)); + if( bIndirect>=0 ){ + pSession->bIndirect = bIndirect; + } + ret = pSession->bIndirect; + sqlite3_mutex_leave(sqlite3_db_mutex(pSession->db)); + return ret; +} + /* ** Create an iterator used to iterate through the contents of a changeset. */ @@ -1548,6 +1578,7 @@ int sqlite3changeset_next(sqlite3_changeset_iter *p){ p->zTab = (char *)aChange; aChange += (strlen((char *)aChange) + 1); p->op = *(aChange++); + p->bIndirect = *(aChange++); sqlite3_free(p->apValue); nByte = sizeof(sqlite3_value *) * p->nCol * 2; p->apValue = (sqlite3_value **)sqlite3_malloc(nByte); @@ -1557,6 +1588,7 @@ int sqlite3changeset_next(sqlite3_changeset_iter *p){ memset(p->apValue, 0, sizeof(sqlite3_value*)*p->nCol*2); }else{ p->op = c; + p->bIndirect = *(aChange++); } if( p->op!=SQLITE_UPDATE && p->op!=SQLITE_DELETE && p->op!=SQLITE_INSERT ){ return (p->rc = SQLITE_CORRUPT); @@ -1587,11 +1619,13 @@ int sqlite3changeset_op( sqlite3_changeset_iter *pIter, /* Iterator handle */ const char **pzTab, /* OUT: Pointer to table name */ int *pnCol, /* OUT: Number of columns in table */ - int *pOp /* OUT: SQLITE_INSERT, DELETE or UPDATE */ + int *pOp, /* OUT: SQLITE_INSERT, DELETE or UPDATE */ + int *pbIndirect /* OUT: True if change is indirect */ ){ *pOp = pIter->op; *pnCol = pIter->nCol; *pzTab = pIter->zTab; + if( pbIndirect ) *pbIndirect = pIter->bIndirect; return SQLITE_OK; } @@ -1740,31 +1774,33 @@ int sqlite3changeset_invert( case SQLITE_INSERT: case SQLITE_DELETE: { int nByte; - u8 *aEnd = &aIn[i+1]; + u8 *aEnd = &aIn[i+2]; sessionReadRecord(&aEnd, nCol, 0); aOut[i] = (eType==SQLITE_DELETE ? SQLITE_INSERT : SQLITE_DELETE); - nByte = aEnd - &aIn[i+1]; - memcpy(&aOut[i+1], &aIn[i+1], nByte); - i += 1 + nByte; + aOut[i+1] = aIn[i+1]; + nByte = aEnd - &aIn[i+2]; + memcpy(&aOut[i+2], &aIn[i+2], nByte); + i += 2 + nByte; break; } case SQLITE_UPDATE: { int nByte1; /* Size of old.* record in bytes */ int nByte2; /* Size of new.* record in bytes */ - u8 *aEnd = &aIn[i+1]; + u8 *aEnd = &aIn[i+2]; sessionReadRecord(&aEnd, nCol, 0); - nByte1 = aEnd - &aIn[i+1]; + nByte1 = aEnd - &aIn[i+2]; sessionReadRecord(&aEnd, nCol, 0); - nByte2 = aEnd - &aIn[i+1] - nByte1; + nByte2 = aEnd - &aIn[i+2] - nByte1; aOut[i] = SQLITE_UPDATE; - memcpy(&aOut[i+1], &aIn[i+1+nByte1], nByte2); - memcpy(&aOut[i+1+nByte2], &aIn[i+1], nByte1); + aOut[i+1] = aIn[i+1]; + memcpy(&aOut[i+2], &aIn[i+2+nByte1], nByte2); + memcpy(&aOut[i+2+nByte2], &aIn[i+2], nByte1); - i += 1 + nByte1 + nByte2; + i += 2 + nByte1 + nByte2; break; } @@ -2097,7 +2133,7 @@ static int sessionSeekToRow( int op; /* Changset operation (SQLITE_UPDATE etc.) */ const char *zDummy; /* Unused */ - sqlite3changeset_op(pIter, &zDummy, &nCol, &op); + sqlite3changeset_op(pIter, &zDummy, &nCol, &op, 0); rc = sessionBindRow(pIter, op==SQLITE_INSERT ? sqlite3changeset_new : sqlite3changeset_old, nCol, abPK, pSelect @@ -2160,7 +2196,7 @@ static int sessionConflictHandler( int op; const char *zDummy; - sqlite3changeset_op(pIter, &zDummy, &nCol, &op); + sqlite3changeset_op(pIter, &zDummy, &nCol, &op, 0); assert( eType==SQLITE_CHANGESET_CONFLICT || eType==SQLITE_CHANGESET_DATA ); assert( SQLITE_CHANGESET_CONFLICT+1==SQLITE_CHANGESET_CONSTRAINT ); @@ -2248,7 +2284,7 @@ static int sessionApplyOneOp( assert( p->azCol && p->abPK ); assert( !pbReplace || *pbReplace==0 ); - sqlite3changeset_op(pIter, &zDummy, &nCol, &op); + sqlite3changeset_op(pIter, &zDummy, &nCol, &op, 0); if( op==SQLITE_DELETE ){ @@ -2362,7 +2398,7 @@ int sqlite3changeset_apply( int bReplace = 0; int bRetry = 0; const char *zNew; - sqlite3changeset_op(pIter, &zNew, &nCol, &op); + sqlite3changeset_op(pIter, &zNew, &nCol, &op, 0); if( zTab==0 || sqlite3_strnicmp(zNew, zTab, nTab+1) ){ sqlite3_free(sApply.azCol); diff --git a/ext/session/sqlite3session.h b/ext/session/sqlite3session.h index d9d0ae1f54..ee0402bffa 100644 --- a/ext/session/sqlite3session.h +++ b/ext/session/sqlite3session.h @@ -90,6 +90,35 @@ void sqlite3session_delete(sqlite3_session *pSession); */ int sqlite3session_enable(sqlite3_session *pSession, int bEnable); +/* +** CAPI3REF: Set Or Clear the Indirect Change Flag +** +** Each change recorded by a session object is marked as either direct or +** indirect. A change is marked as indirect if either: +** +**
    +**
  • The session object "indirect" flag is set when the change is +** made, or +**
  • The change is made by an SQL trigger or foreign key action +** instead of directly as a result of a users SQL statement. +**
+** +** If a single row is affected by more than one operation within a session, +** then the change is considered indirect if all operations meet the criteria +** for an indirect change above, or direct otherwise. +** +** This function is used to set, clear or query the session object indirect +** flag. If the second argument passed to this function is zero, then the +** indirect flag is cleared. If it is greater than zero, the indirect flag +** is set. Passing a value less than zero does not modify the current value +** of the indirect flag, and may be used to query the current state of the +** indirect flag for the specified session object. +** +** The return value indicates the final state of the indirect flag: 0 if +** it is clear, or 1 if it is set. +*/ +int sqlite3session_indirect(sqlite3_session *pSession, int bIndirect); + /* ** CAPI3REF: Attach A Table To A Session Object ** @@ -292,10 +321,13 @@ int sqlite3changeset_next(sqlite3_changeset_iter *pIter); ** affected by the current change. The buffer remains valid until either ** sqlite3changeset_next() is called on the iterator or until the ** conflict-handler function returns. If pnCol is not NULL, then *pnCol is -** set to the number of columns in the table affected by the change. Finally, -** if pOp is not NULL, then *pOp is set to one of [SQLITE_INSERT], -** [SQLITE_DELETE] or [SQLITE_UPDATE], depending on the type of change that -** the iterator currently points to. +** set to the number of columns in the table affected by the change. If +** pbIncorrect is not NULL, then *pbIndirect is set to true (1) if the change +** is an indirect change, or false (0) otherwise. See the documentation for +** [sqlite3session_indirect()] for a description of direct and indirect +** changes. Finally, if pOp is not NULL, then *pOp is set to one of +** [SQLITE_INSERT], [SQLITE_DELETE] or [SQLITE_UPDATE], depending on the +** type of change that the iterator currently points to. ** ** If no error occurs, SQLITE_OK is returned. If an error does occur, an ** SQLite error code is returned. The values of the output variables may not @@ -305,7 +337,8 @@ int sqlite3changeset_op( sqlite3_changeset_iter *pIter, /* Iterator object */ const char **pzTab, /* OUT: Pointer to table name */ int *pnCol, /* OUT: Number of columns in table */ - int *pOp /* OUT: SQLITE_INSERT, DELETE or UPDATE */ + int *pOp, /* OUT: SQLITE_INSERT, DELETE or UPDATE */ + int *pbIndirect /* OUT: True for an 'indirect' change */ ); /* diff --git a/ext/session/test_session.c b/ext/session/test_session.c index ecc07187d3..fee52d7f9c 100644 --- a/ext/session/test_session.c +++ b/ext/session/test_session.c @@ -17,6 +17,7 @@ static int test_session_error(Tcl_Interp *interp, int rc){ ** $session changeset ** $session delete ** $session enable BOOL +** $session indirect BOOL */ static int test_session_cmd( void *clientData, @@ -34,7 +35,8 @@ static int test_session_cmd( { "attach", 1, "TABLE", }, /* 0 */ { "changeset", 0, "", }, /* 1 */ { "delete", 0, "", }, /* 2 */ - { "enable", 1, "", }, /* 3 */ + { "enable", 1, "BOOL", }, /* 3 */ + { "indirect", 1, "BOOL", }, /* 4 */ { 0 } }; int iSub; @@ -88,6 +90,14 @@ static int test_session_cmd( Tcl_SetObjResult(interp, Tcl_NewBooleanObj(val)); break; } + + case 4: { /* indirect */ + int val; + if( Tcl_GetBooleanFromObj(interp, objv[2], &val) ) return TCL_ERROR; + val = sqlite3session_indirect(pSession, val); + Tcl_SetObjResult(interp, Tcl_NewBooleanObj(val)); + break; + } } return TCL_OK; @@ -205,7 +215,7 @@ static int test_conflict_handler( pEval = Tcl_DuplicateObj(p->pScript); Tcl_IncrRefCount(pEval); - sqlite3changeset_op(pIter, &zTab, &nCol, &op); + sqlite3changeset_op(pIter, &zTab, &nCol, &op, 0); /* Append the operation type. */ Tcl_ListObjAppendElement(0, pEval, Tcl_NewStringObj( @@ -396,8 +406,9 @@ static int test_sqlite3session_foreach( Tcl_Obj *pVar; /* Tcl value to set $VARNAME to */ Tcl_Obj *pOld; /* Vector of old.* values */ Tcl_Obj *pNew; /* Vector of new.* values */ + int bIndirect; - sqlite3changeset_op(pIter, &zTab, &nCol, &op); + sqlite3changeset_op(pIter, &zTab, &nCol, &op, &bIndirect); pVar = Tcl_NewObj(); Tcl_ListObjAppendElement(0, pVar, Tcl_NewStringObj( op==SQLITE_INSERT ? "INSERT" : @@ -405,6 +416,7 @@ static int test_sqlite3session_foreach( "DELETE", -1 )); Tcl_ListObjAppendElement(0, pVar, Tcl_NewStringObj(zTab, -1)); + Tcl_ListObjAppendElement(0, pVar, Tcl_NewBooleanObj(bIndirect)); pOld = Tcl_NewObj(); if( op!=SQLITE_INSERT ){ diff --git a/manifest b/manifest index 20662eaa2f..1178e77cb3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sAPI\sfunction\ssqlite3_preupdate_depth(),\sfor\sdetermining\sthe\sdepth\sof\sthe\strigger\sstack\sfrom\swithin\sa\spre-update\scallback. -D 2011-03-22T18:45:30 +C Add\sthe\s"indirect\sflag"\sto\sthe\schangeset\sblob\sformat.\sAlso\sthe\ssqlite3session_indirect()\sAPI. +D 2011-03-23T16:03:12 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -99,13 +99,13 @@ F ext/rtree/rtree_util.tcl 06aab2ed5b826545bf215fff90ecb9255a8647ea F ext/rtree/sqlite3rtree.h 1af0899c63a688e272d69d8e746f24e76f10a3f0 F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 -F ext/session/session1.test 1e8cda2cc8a60171dabc0fbec4124f9f7c943f23 -F ext/session/session2.test f993ee243db15025a7d9b1dae903fe3f82f04229 +F ext/session/session1.test bca38efbc34c0cdecc10e599246962860e3f664b +F ext/session/session2.test b0d305ee1397d7c17f9743126f636e97ddf88542 F ext/session/session_common.tcl fb91560b6dbd086010df8b3a137a452f1ac21a28 -F ext/session/sessionfault.test 495f87fb9bd764ae90d4b40d0c33a76d86d9063e -F ext/session/sqlite3session.c ec0f440ae73229ae8ae307a31e631b9d71991cd4 -F ext/session/sqlite3session.h 5055e21ca0cb6ddacd46b773a15d90bc0298b0a2 -F ext/session/test_session.c d31fbf5902d0cff5e5495a5ce62efda77b596f2b +F ext/session/sessionfault.test 4489a49d2d44c74c24251d5802b2cc011dbdac21 +F ext/session/sqlite3session.c 0c2e8f6a6d9872943edd04d0a19bf7b05db9df83 +F ext/session/sqlite3session.h 000c1ed86322d9d8e8118cd5ba815269aac608f2 +F ext/session/test_session.c 0fcfbd51e3f5885b958fbc8cdd8cba01b85b8b16 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F main.mk ae0868e05c76eaa8a0ae3d6927a949b1c8e810d7 @@ -923,7 +923,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 183c236e991faaabdc768e52e926c52cf4a7abc9 -R 3714f49d9e3ab391fe868f9d204fa8d5 +P bdea70895c2c686a4dd3f4bf0a475fd1501d9551 +R c02abbe676895f559af6fe54b071c0da U dan -Z 4e2f4fe62e6298f01b15895da5c35a23 +Z 27e4954529d298836a72824c8b085018 diff --git a/manifest.uuid b/manifest.uuid index cf0cd54d72..f85c8efaad 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bdea70895c2c686a4dd3f4bf0a475fd1501d9551 \ No newline at end of file +1feaf2d35fd9ec777319717ae2c2929d66fe7baa \ No newline at end of file From 244593c8460bf9ab836921643a1ae94154c90989 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 24 Mar 2011 11:22:59 +0000 Subject: [PATCH 0035/1484] Store primary key definitions for modified tables in changesets. Add the sqlite3changeset_pk() API to extract this data from a changeset iterator. FossilOrigin-Name: 54298ee5ed183d1f1c49524f25e8ae1407f3d4b5 --- ext/session/session1.test | 44 ++++++++++++++--------------- ext/session/session2.test | 52 +++++++++++++++++------------------ ext/session/sessionfault.test | 6 ++-- ext/session/sqlite3session.c | 24 +++++++++++++++- ext/session/sqlite3session.h | 31 +++++++++++++++++++++ ext/session/test_session.c | 14 ++++++++++ manifest | 34 ++++++++--------------- manifest.uuid | 2 +- 8 files changed, 132 insertions(+), 75 deletions(-) diff --git a/ext/session/session1.test b/ext/session/session1.test index 582f802bea..4a2b50e6c6 100644 --- a/ext/session/session1.test +++ b/ext/session/session1.test @@ -88,14 +88,14 @@ do_test 2.1.1 { execsql { INSERT INTO t1 VALUES(3, 'Thonburi') } } {} do_changeset_test 2.1.2 S { - {INSERT t1 0 {} {i 1 t Sukhothai}} - {INSERT t1 0 {} {i 2 t Ayutthaya}} - {INSERT t1 0 {} {i 3 t Thonburi}} + {INSERT t1 0 X. {} {i 1 t Sukhothai}} + {INSERT t1 0 X. {} {i 2 t Ayutthaya}} + {INSERT t1 0 X. {} {i 3 t Thonburi}} } do_changeset_invert_test 2.1.3 S { - {DELETE t1 0 {i 1 t Sukhothai} {}} - {DELETE t1 0 {i 2 t Ayutthaya} {}} - {DELETE t1 0 {i 3 t Thonburi} {}} + {DELETE t1 0 X. {i 1 t Sukhothai} {}} + {DELETE t1 0 X. {i 2 t Ayutthaya} {}} + {DELETE t1 0 X. {i 3 t Thonburi} {}} } do_test 2.1.4 { S delete } {} @@ -105,14 +105,14 @@ do_test 2.2.1 { execsql { DELETE FROM t1 WHERE 1 } } {} do_changeset_test 2.2.2 S { - {DELETE t1 0 {i 1 t Sukhothai} {}} - {DELETE t1 0 {i 2 t Ayutthaya} {}} - {DELETE t1 0 {i 3 t Thonburi} {}} + {DELETE t1 0 X. {i 1 t Sukhothai} {}} + {DELETE t1 0 X. {i 2 t Ayutthaya} {}} + {DELETE t1 0 X. {i 3 t Thonburi} {}} } do_changeset_invert_test 2.2.3 S { - {INSERT t1 0 {} {i 1 t Sukhothai}} - {INSERT t1 0 {} {i 2 t Ayutthaya}} - {INSERT t1 0 {} {i 3 t Thonburi}} + {INSERT t1 0 X. {} {i 1 t Sukhothai}} + {INSERT t1 0 X. {} {i 2 t Ayutthaya}} + {INSERT t1 0 X. {} {i 3 t Thonburi}} } do_test 2.2.4 { S delete } {} @@ -131,19 +131,19 @@ do_test 2.3.1 { } {} do_changeset_test 2.3.2 S { - {INSERT t1 0 {} {i 10 t Sukhothai}} - {DELETE t1 0 {i 1 t Sukhothai} {}} - {UPDATE t1 0 {i 2 t Ayutthaya} {{} {} t Surin}} - {DELETE t1 0 {i 3 t Thonburi} {}} - {INSERT t1 0 {} {i 20 t Thapae}} + {INSERT t1 0 X. {} {i 10 t Sukhothai}} + {DELETE t1 0 X. {i 1 t Sukhothai} {}} + {UPDATE t1 0 X. {i 2 t Ayutthaya} {{} {} t Surin}} + {DELETE t1 0 X. {i 3 t Thonburi} {}} + {INSERT t1 0 X. {} {i 20 t Thapae}} } do_changeset_invert_test 2.3.3 S { - {DELETE t1 0 {i 10 t Sukhothai} {}} - {INSERT t1 0 {} {i 1 t Sukhothai}} - {UPDATE t1 0 {{} {} t Surin} {i 2 t Ayutthaya}} - {INSERT t1 0 {} {i 3 t Thonburi}} - {DELETE t1 0 {i 20 t Thapae} {}} + {DELETE t1 0 X. {i 10 t Sukhothai} {}} + {INSERT t1 0 X. {} {i 1 t Sukhothai}} + {UPDATE t1 0 X. {{} {} t Surin} {i 2 t Ayutthaya}} + {INSERT t1 0 X. {} {i 3 t Thonburi}} + {DELETE t1 0 X. {i 20 t Thapae} {}} } do_test 2.3.4 { S delete } {} diff --git a/ext/session/session2.test b/ext/session/session2.test index d6cb284659..a4776d80e5 100644 --- a/ext/session/session2.test +++ b/ext/session/session2.test @@ -41,13 +41,13 @@ do_iterator_test 1.1 t1 { DELETE FROM t1 WHERE a = 'i'; INSERT INTO t1 VALUES('ii', 'two'); } { - {DELETE t1 0 {t i t one} {}} - {INSERT t1 0 {} {t ii t two}} + {DELETE t1 0 X. {t i t one} {}} + {INSERT t1 0 X. {} {t ii t two}} } do_iterator_test 1.2 t1 { INSERT INTO t1 VALUES(1.5, 99.9) } { - {INSERT t1 0 {} {f 1.5 f 99.9}} + {INSERT t1 0 X. {} {f 1.5 f 99.9}} } @@ -228,15 +228,15 @@ foreach {tn sql changeset} { INSERT INTO t1 VALUES(NULL); INSERT INTO t1 VALUES(456); } { - {INSERT t1 0 {} {i 456}} - {INSERT t1 0 {} {i 123}} + {INSERT t1 0 X {} {i 456}} + {INSERT t1 0 X {} {i 123}} } 2 { UPDATE t1 SET a = NULL; } { - {DELETE t1 0 {i 456} {}} - {DELETE t1 0 {i 123} {}} + {DELETE t1 0 X {i 456} {}} + {DELETE t1 0 X {i 123} {}} } 3 { DELETE FROM t1 } { } @@ -244,14 +244,14 @@ foreach {tn sql changeset} { 4 { INSERT INTO t3 VALUES(NULL, NULL) } { - {INSERT t3 0 {} {n {} i 1}} + {INSERT t3 0 .X {} {n {} i 1}} } 5 { INSERT INTO t2 VALUES(1, 2, NULL) } { } 6 { INSERT INTO t2 VALUES(1, NULL, 3) } { } 7 { INSERT INTO t2 VALUES(1, NULL, NULL) } { } - 8 { INSERT INTO t2 VALUES(1, 2, 3) } { {INSERT t2 0 {} {i 1 i 2 i 3}} } - 9 { DELETE FROM t2 WHERE 1 } { {DELETE t2 0 {i 1 i 2 i 3} {}} } + 8 { INSERT INTO t2 VALUES(1, 2, 3) } { {INSERT t2 0 .XX {} {i 1 i 2 i 3}} } + 9 { DELETE FROM t2 WHERE 1 } { {DELETE t2 0 .XX {i 1 i 2 i 3} {}} } } { do_iterator_test 4.$tn {t1 t2 t3} $sql $changeset @@ -269,14 +269,14 @@ do_execsql_test 5.0 { } foreach {tn sql changeset} { - 1 { INSERT INTO t1 VALUES(35) } { {INSERT t1 0 {} {i 35}} } - 2 { INSERT INTO t2 VALUES(36, 37) } { {INSERT t2 0 {} {i 36 i 37}} } + 1 { INSERT INTO t1 VALUES(35) } { {INSERT t1 0 X {} {i 35}} } + 2 { INSERT INTO t2 VALUES(36, 37) } { {INSERT t2 0 .X {} {i 36 i 37}} } 3 { DELETE FROM t1 WHERE 1; UPDATE t2 SET x = 34; } { - {UPDATE t2 0 {i 36 i 37} {i 34 {} {}}} - {DELETE t1 0 {i 35} {}} + {UPDATE t2 0 .X {i 36 i 37} {i 34 {} {}}} + {DELETE t1 0 X {i 35} {}} } } { do_iterator_test 5.$tn * $sql $changeset @@ -314,9 +314,9 @@ do_iterator_test 6.1.1 * { SELECT indirect(0); INSERT INTO t1 VALUES(3, 'three', 'iii'); } { - {INSERT t1 0 {} {i 1 t one t i}} - {INSERT t1 1 {} {i 2 t two t ii}} - {INSERT t1 0 {} {i 3 t three t iii}} + {INSERT t1 0 X.. {} {i 1 t one t i}} + {INSERT t1 1 X.. {} {i 2 t two t ii}} + {INSERT t1 0 X.. {} {i 3 t three t iii}} } do_iterator_test 6.1.2 * { @@ -324,7 +324,7 @@ do_iterator_test 6.1.2 * { UPDATE t1 SET c = 'I' WHERE a = 1; SELECT indirect(0); } { - {UPDATE t1 1 {i 1 {} {} t i} {{} {} {} {} t I}} + {UPDATE t1 1 X.. {i 1 {} {} t i} {{} {} {} {} t I}} } do_iterator_test 6.1.3 * { SELECT indirect(1); @@ -332,7 +332,7 @@ do_iterator_test 6.1.3 * { SELECT indirect(0); UPDATE t1 SET c = 'o' WHERE a = 1; } { - {UPDATE t1 0 {i 1 {} {} t I} {{} {} {} {} t o}} + {UPDATE t1 0 X.. {i 1 {} {} t I} {{} {} {} {} t o}} } do_iterator_test 6.1.4 * { SELECT indirect(0); @@ -340,7 +340,7 @@ do_iterator_test 6.1.4 * { SELECT indirect(1); UPDATE t1 SET c = 'i' WHERE a = 1; } { - {UPDATE t1 0 {i 1 {} {} t o} {{} {} {} {} t i}} + {UPDATE t1 0 X.. {i 1 {} {} t o} {{} {} {} {} t i}} } do_iterator_test 6.1.4 * { SELECT indirect(1); @@ -348,14 +348,14 @@ do_iterator_test 6.1.4 * { SELECT indirect(1); UPDATE t1 SET c = 'I' WHERE a = 1; } { - {UPDATE t1 1 {i 1 {} {} t i} {{} {} {} {} t I}} + {UPDATE t1 1 X.. {i 1 {} {} t i} {{} {} {} {} t I}} } do_iterator_test 6.1.5 * { INSERT INTO t2 VALUES(1, 'x'); } { - {INSERT t2 0 {} {i 1 t x}} - {INSERT t2 1 {} {i 2 n {}}} + {INSERT t2 0 X. {} {i 1 t x}} + {INSERT t2 1 X. {} {i 2 n {}}} } do_iterator_test 6.1.6 * { @@ -364,8 +364,8 @@ do_iterator_test 6.1.6 * { SELECT indirect(0); UPDATE t2 SET y = 'y' WHERE x>2; } { - {INSERT t2 0 {} {i 3 t y}} - {INSERT t2 0 {} {i 4 t y}} + {INSERT t2 0 X. {} {i 3 t y}} + {INSERT t2 0 X. {} {i 4 t y}} } do_iterator_test 6.1.7 * { @@ -374,7 +374,7 @@ do_iterator_test 6.1.7 * { SELECT indirect(0); INSERT INTO t2 VALUES(4, 'new'); } { - {UPDATE t2 0 {i 4 t y} {{} {} t new}} + {UPDATE t2 0 X. {i 4 t y} {{} {} t new}} } finish_test diff --git a/ext/session/sessionfault.test b/ext/session/sessionfault.test index 04ac8b8b88..e1c2980b79 100644 --- a/ext/session/sessionfault.test +++ b/ext/session/sessionfault.test @@ -243,9 +243,9 @@ do_faultsim_test 5 -faults oom* -body { set x [list] sqlite3session_foreach c $::inverse { lappend x $c } foreach c { - {DELETE t1 0 {t xxx t yyy} {}} - {INSERT t1 0 {} {t string i 1}} - {UPDATE t1 0 {i 20 {} {}} {i 4 i 2}} + {DELETE t1 0 .X {t xxx t yyy} {}} + {INSERT t1 0 .X {} {t string i 1}} + {UPDATE t1 0 .X {i 20 {} {}} {i 4 i 2}} } { lappend y $c } if {$x != $y} { error "changeset no good" } } diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index ff28487d3c..4ab8bb32ce 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -39,6 +39,7 @@ struct sqlite3_changeset_iter { int nCol; /* Number of columns in zTab */ int op; /* Current operation */ int bIndirect; /* True if current change was indirect */ + u8 *abPK; /* Primary key array */ sqlite3_value **apValue; /* old.* and new.* values */ }; @@ -1357,6 +1358,7 @@ int sqlite3session_changeset( /* Write a table header */ sessionAppendByte(&buf, 'T', &rc); sessionAppendVarint(&buf, nCol, &rc); + sessionAppendBlob(&buf, pTab->abPK, nCol, &rc); sessionAppendBlob(&buf, (u8 *)zName, strlen(zName)+1, &rc); /* Build and compile a statement to execute: */ @@ -1575,6 +1577,8 @@ int sqlite3changeset_next(sqlite3_changeset_iter *p){ if( c=='T' ){ int nByte; /* Bytes to allocate for apValue */ aChange += sessionVarintGet(aChange, &p->nCol); + p->abPK = (u8 *)aChange; + aChange += p->nCol; p->zTab = (char *)aChange; aChange += (strlen((char *)aChange) + 1); p->op = *(aChange++); @@ -1611,7 +1615,7 @@ int sqlite3changeset_next(sqlite3_changeset_iter *p){ } /* -** The following three functions extract information on the current change +** The following function extracts information on the current change ** from a changeset iterator. They may only be called after changeset_next() ** has returned SQLITE_ROW. */ @@ -1629,6 +1633,16 @@ int sqlite3changeset_op( return SQLITE_OK; } +int sqlite3changeset_pk( + sqlite3_changeset_iter *pIter, /* Iterator object */ + unsigned char **pabPK, /* OUT: Array of boolean - true for PK cols */ + int *pnCol /* OUT: Number of entries in output array */ +){ + *pabPK = pIter->abPK; + if( pnCol ) *pnCol = pIter->nCol; + return SQLITE_OK; +} + /* ** This function may only be called while the iterator is pointing to an ** SQLITE_UPDATE or SQLITE_DELETE change (see sqlite3changeset_op()). @@ -1764,7 +1778,15 @@ int sqlite3changeset_invert( u8 eType = aIn[i]; switch( eType ){ case 'T': { + /* A 'table' record consists of: + ** + ** * A constant 'T' character, + ** * Number of columns in said table (a varint), + ** * An array of nCol bytes (abPK), + ** * A nul-terminated table name. + */ int nByte = 1 + sessionVarintGet(&aIn[i+1], &nCol); + nByte += nCol; nByte += 1 + strlen((char *)&aIn[i+nByte]); memcpy(&aOut[i], &aIn[i], nByte); i += nByte; diff --git a/ext/session/sqlite3session.h b/ext/session/sqlite3session.h index ee0402bffa..b6ea72522d 100644 --- a/ext/session/sqlite3session.h +++ b/ext/session/sqlite3session.h @@ -341,6 +341,37 @@ int sqlite3changeset_op( int *pbIndirect /* OUT: True for an 'indirect' change */ ); +/* +** CAPI3REF: Obtain The Primary Key Definition Of A Table +** +** For each modified table, a changeset includes the following: +** +**
    +**
  • The number of columns in the table, and +**
  • Which of those columns make up the tables PRIMARY KEY. +**
+** +** This function is used to find which columns comprise the PRIMARY KEY of +** the table modified by the change that iterator pIter currently points to. +** If successful, *pabPK is set to point to an array of nCol entries, where +** nCol is the number of columns in the table. Elements of *pabPK are set to +** 0x01 if the corresponding column is part of the tables primary key, or +** 0x00 if it is not. +** +** If argumet pnCol is not NULL, then *pnCol is set to the number of columns +** in the table. +** +** If this function is called when the iterator does not point to a valid +** entry, SQLITE_MISUSE is returned and the output variables zeroed. Otherwise, +** SQLITE_OK is returned and the output variables populated as described +** above. +*/ +int sqlite3changeset_pk( + sqlite3_changeset_iter *pIter, /* Iterator object */ + unsigned char **pabPK, /* OUT: Array of boolean - true for PK cols */ + int *pnCol /* OUT: Number of entries in output array */ +); + /* ** CAPI3REF: Obtain old.* Values From A Changeset Iterator ** diff --git a/ext/session/test_session.c b/ext/session/test_session.c index fee52d7f9c..e3d6d60c22 100644 --- a/ext/session/test_session.c +++ b/ext/session/test_session.c @@ -408,6 +408,10 @@ static int test_sqlite3session_foreach( Tcl_Obj *pNew; /* Vector of new.* values */ int bIndirect; + char *zPK; + unsigned char *abPK; + int i; + sqlite3changeset_op(pIter, &zTab, &nCol, &op, &bIndirect); pVar = Tcl_NewObj(); Tcl_ListObjAppendElement(0, pVar, Tcl_NewStringObj( @@ -415,9 +419,19 @@ static int test_sqlite3session_foreach( op==SQLITE_UPDATE ? "UPDATE" : "DELETE", -1 )); + Tcl_ListObjAppendElement(0, pVar, Tcl_NewStringObj(zTab, -1)); Tcl_ListObjAppendElement(0, pVar, Tcl_NewBooleanObj(bIndirect)); + zPK = ckalloc(nCol+1); + memset(zPK, 0, nCol+1); + sqlite3changeset_pk(pIter, &abPK, 0); + for(i=0; i Date: Thu, 24 Mar 2011 16:04:54 +0000 Subject: [PATCH 0036/1484] Fix handling of schema mismatches in sqlite3session.c so that it matches the docs in sqlite3session.h. FossilOrigin-Name: 506a0d7a710e1ff2f367821e73f5080fcf63fbc5 --- ext/session/session3.test | 88 ++++++++++++++++++++++++++++++++++++ ext/session/sqlite3session.c | 58 ++++++++++++++++++------ ext/session/sqlite3session.h | 2 +- manifest | 15 +++--- manifest.uuid | 2 +- 5 files changed, 142 insertions(+), 23 deletions(-) create mode 100644 ext/session/session3.test diff --git a/ext/session/session3.test b/ext/session/session3.test new file mode 100644 index 0000000000..e07032fccd --- /dev/null +++ b/ext/session/session3.test @@ -0,0 +1,88 @@ +# 2011 March 24 +# +# 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 regression tests for the session module. +# + +if {![info exists testdir]} { + set testdir [file join [file dirname [info script]] .. .. test] +} +source [file join [file dirname [info script]] session_common.tcl] +source $testdir/tester.tcl + +set testprefix session3 + +# These tests - session3-1.* - verify that the session module behaves +# correctly when confronted with a schema mismatch when applying a +# changeset (in function sqlite3changeset_apply()). +# +# session3-1.1.*: Table does not exist in target db. +# session3-1.2.*: Table has wrong number of columns in target db. +# session3-1.3.*: Table has wrong PK columns in target db. +# + +db close +sqlite3_shutdown +test_sqlite3_log log +sqlite3 db test.db + +proc log {code msg} { lappend ::log $code $msg } + +forcedelete test.db2 +sqlite3 db2 test.db2 + +do_execsql_test 1.0 { + CREATE TABLE t1(a PRIMARY KEY, b); +} +do_test 1.1 { + set ::log {} + do_then_apply_sql { + INSERT INTO t1 VALUES(1, 2); + INSERT INTO t1 VALUES(3, 4); + } + set ::log +} {SQLITE_SCHEMA {sqlite3changeset_apply(): no such table: t1}} + +do_test 1.2.0 { + execsql { CREATE TABLE t1(a PRIMARY KEY, b, c) } db2 +} {} +do_test 1.2.1 { + set ::log {} + do_then_apply_sql { + INSERT INTO t1 VALUES(5, 6); + INSERT INTO t1 VALUES(7, 8); + } + set ::log +} {SQLITE_SCHEMA {sqlite3changeset_apply(): table t1 has 3 columns, expected 2}} + +do_test 1.3.0 { + execsql { + DROP TABLE t1; + CREATE TABLE t1(a, b PRIMARY KEY); + } db2 +} {} +do_test 1.3.1 { + set ::log {} + do_then_apply_sql { + INSERT INTO t1 VALUES(9, 10); + INSERT INTO t1 VALUES(11, 12); + } + set ::log +} {SQLITE_SCHEMA {sqlite3changeset_apply(): primary key mismatch for table t1}} + + +catch { db close } +catch { db2 close } +sqlite3_shutdown +test_sqlite3_log +sqlite3_initialize + +finish_test + diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index 4ab8bb32ce..c64f567f90 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -544,7 +544,7 @@ static int sessionTableInfo( sqlite3 *db, /* Database connection */ const char *zDb, /* Name of attached database (e.g. "main") */ const char *zThis, /* Table name */ - int nCol, /* Expected number of columns */ + int *pnCol, /* OUT: number of columns */ const char **pzTab, /* OUT: Copy of zThis */ const char ***pazCol, /* OUT: Array of column names for table */ u8 **pabPK /* OUT: Array of booleans - true for PK col */ @@ -577,9 +577,6 @@ static int sessionTableInfo( } rc = sqlite3_reset(pStmt); - if( nDbCol!=nCol ){ - rc = SQLITE_SCHEMA; - } if( rc==SQLITE_OK ){ nByte += nDbCol * (sizeof(const char *) + sizeof(u8) + 1); pAlloc = sqlite3_malloc(nByte); @@ -589,9 +586,9 @@ static int sessionTableInfo( } if( rc==SQLITE_OK ){ azCol = (char **)pAlloc; - pAlloc = (u8 *)&azCol[nCol]; + pAlloc = (u8 *)&azCol[nDbCol]; abPK = (u8 *)pAlloc; - pAlloc = &abPK[nCol]; + pAlloc = &abPK[nDbCol]; if( pzTab ){ memcpy(pAlloc, zThis, nThis+1); *pzTab = (char *)pAlloc; @@ -619,9 +616,11 @@ static int sessionTableInfo( if( rc==SQLITE_OK ){ *pazCol = (const char **)azCol; *pabPK = abPK; + *pnCol = nDbCol; }else{ *pazCol = 0; *pabPK = 0; + *pnCol = 0; if( pzTab ) *pzTab = 0; sqlite3_free(azCol); } @@ -648,11 +647,13 @@ static int sessionTableInfo( static int sessionInitTable(sqlite3_session *pSession, SessionTable *pTab){ if( pTab->nCol==0 ){ assert( pTab->azCol==0 || pTab->abPK==0 ); - pTab->nCol = sqlite3_preupdate_count(pSession->db); pSession->rc = sessionTableInfo(pSession->db, pSession->zDb, - pTab->zName, pTab->nCol, 0, &pTab->azCol, &pTab->abPK + pTab->zName, &pTab->nCol, 0, &pTab->azCol, &pTab->abPK ); - }else if( pTab->nCol!=sqlite3_preupdate_count(pSession->db) ){ + } + if( pSession->rc==SQLITE_OK + && pTab->nCol!=sqlite3_preupdate_count(pSession->db) + ){ pSession->rc = SQLITE_SCHEMA; } return pSession->rc; @@ -2402,6 +2403,7 @@ int sqlite3changeset_apply( ), void *pCtx /* First argument passed to xConflict */ ){ + int schemaMismatch = 0; sqlite3_changeset_iter *pIter; /* Iterator to skip through changeset */ int rc; /* Return code */ const char *zTab = 0; /* Name of current table */ @@ -2420,9 +2422,13 @@ int sqlite3changeset_apply( int bReplace = 0; int bRetry = 0; const char *zNew; + sqlite3changeset_op(pIter, &zNew, &nCol, &op, 0); if( zTab==0 || sqlite3_strnicmp(zNew, zTab, nTab+1) ){ + u8 *abPK; + + schemaMismatch = 0; sqlite3_free(sApply.azCol); sqlite3_finalize(sApply.pDelete); sqlite3_finalize(sApply.pUpdate); @@ -2430,23 +2436,47 @@ int sqlite3changeset_apply( sqlite3_finalize(sApply.pSelect); memset(&sApply, 0, sizeof(sApply)); sApply.db = db; - sApply.nCol = nCol; + sqlite3changeset_pk(pIter, &abPK, 0); rc = sessionTableInfo( - db, "main", zNew, nCol, &zTab, &sApply.azCol, &sApply.abPK); + db, "main", zNew, &sApply.nCol, &zTab, &sApply.azCol, &sApply.abPK + ); + if( rc!=SQLITE_OK ) break; - if( rc!=SQLITE_OK - || (rc = sessionSelectRow(db, zTab, &sApply)) + if( sApply.nCol==0 ){ + schemaMismatch = 1; + sqlite3_log(SQLITE_SCHEMA, + "sqlite3changeset_apply(): no such table: %s", zTab + ); + } + else if( sApply.nCol!=nCol ){ + schemaMismatch = 1; + sqlite3_log(SQLITE_SCHEMA, + "sqlite3changeset_apply(): table %s has %d columns, expected %d", + zTab, sApply.nCol, nCol + ); + } + else if( memcmp(sApply.abPK, abPK, nCol)!=0 ){ + schemaMismatch = 1; + sqlite3_log(SQLITE_SCHEMA, + "sqlite3changeset_apply(): primary key mismatch for table %s", zTab + ); + } + else if( + (rc = sessionSelectRow(db, zTab, &sApply)) || (rc = sessionUpdateRow(db, zTab, &sApply)) || (rc = sessionDeleteRow(db, zTab, &sApply)) || (rc = sessionInsertRow(db, zTab, &sApply)) ){ break; } - nTab = strlen(zTab); } + /* If there is a schema mismatch on the current table, proceed to the + ** next change. A log message has already been issued. */ + if( schemaMismatch ) continue; + rc = sessionApplyOneOp(pIter, &sApply, xConflict, pCtx, &bReplace, &bRetry); if( rc==SQLITE_OK && bRetry ){ diff --git a/ext/session/sqlite3session.h b/ext/session/sqlite3session.h index b6ea72522d..5d19379ec8 100644 --- a/ext/session/sqlite3session.h +++ b/ext/session/sqlite3session.h @@ -48,7 +48,7 @@ typedef struct sqlite3_changeset_iter sqlite3_changeset_iter; ** ** The session object will be used to create changesets for tables in ** database zDb, where zDb is either "main", or "temp", or the name of an -** attached database. It is not an error if database zDb does not exist +** attached database. It is not an error if database zDb is not attached ** to the database when the session object is created. */ int sqlite3session_create( diff --git a/manifest b/manifest index edccb68924..e59c27fb75 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Store\sprimary\skey\sdefinitions\sfor\smodified\stables\sin\schangesets.\sAdd\sthe\ssqlite3changeset_pk()\sAPI\sto\sextract\sthis\sdata\sfrom\sa\schangeset\siterator. -D 2011-03-24T11:22:59 +C Fix\shandling\sof\sschema\smismatches\sin\ssqlite3session.c\sso\sthat\sit\smatches\sthe\sdocs\sin\ssqlite3session.h. +D 2011-03-24T16:04:55 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -101,10 +101,11 @@ F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 F ext/session/session1.test b2da15b9d727d7f4e5fe95599b32b92d93b5a970 F ext/session/session2.test 8da094318ac88953478c43d0bfb0aa723ee0e379 +F ext/session/session3.test b8b9ff7efcb19234892c406dba8bd56792560efe F ext/session/session_common.tcl fb91560b6dbd086010df8b3a137a452f1ac21a28 F ext/session/sessionfault.test d7e6154a30e85622d0733b1a1e3c63e9b8b7004b -F ext/session/sqlite3session.c 886827f10de75576baf9f9d860414fa155e1c8c1 -F ext/session/sqlite3session.h 8d3e00c0a2e323e6f47b1204ec9ff714ca3bee4a +F ext/session/sqlite3session.c cf91fe0efb0728c219c8bc2b2174a49758fbd3f8 +F ext/session/sqlite3session.h 900d900bb6a827f84754fc252a05638e0f413a6e F ext/session/test_session.c e0f500ec5e20478afc2c7998133e8acea7ec5104 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 @@ -923,7 +924,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 9c3a6e479988e96086bef00c79dbce508a14da0d -R f502a856cffb82507c875b00a2fb9d4d +P 54298ee5ed183d1f1c49524f25e8ae1407f3d4b5 +R 73cd0f1e5ce098769e9cee2c7d1f1ebc U dan -Z 3fdb3d84abab55a6e9fe1eeceb839a7c +Z 8a40e5171d2567a1ae6ca1b697973f9a diff --git a/manifest.uuid b/manifest.uuid index 12934424cd..e8475cfcd0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -54298ee5ed183d1f1c49524f25e8ae1407f3d4b5 \ No newline at end of file +506a0d7a710e1ff2f367821e73f5080fcf63fbc5 \ No newline at end of file From a9605b912552c6d6b33c787917d79187fbf4c3ce Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 24 Mar 2011 16:53:57 +0000 Subject: [PATCH 0037/1484] Fix handling of schema changes mid-session. FossilOrigin-Name: 76d2d2ad3b2a5171393b7894f35f463ff284e53b --- ext/session/session3.test | 92 +++++++++++++++++++++++++++++++++++- ext/session/sqlite3session.c | 14 ++++-- manifest | 14 +++--- manifest.uuid | 2 +- 4 files changed, 110 insertions(+), 12 deletions(-) diff --git a/ext/session/session3.test b/ext/session/session3.test index e07032fccd..d0d2c31fa4 100644 --- a/ext/session/session3.test +++ b/ext/session/session3.test @@ -19,6 +19,7 @@ source $testdir/tester.tcl set testprefix session3 +#------------------------------------------------------------------------- # These tests - session3-1.* - verify that the session module behaves # correctly when confronted with a schema mismatch when applying a # changeset (in function sqlite3changeset_apply()). @@ -27,7 +28,6 @@ set testprefix session3 # session3-1.2.*: Table has wrong number of columns in target db. # session3-1.3.*: Table has wrong PK columns in target db. # - db close sqlite3_shutdown test_sqlite3_log log @@ -77,6 +77,96 @@ do_test 1.3.1 { set ::log } {SQLITE_SCHEMA {sqlite3changeset_apply(): primary key mismatch for table t1}} +#------------------------------------------------------------------------- +# These tests - session3-2.* - verify that the session module behaves +# correctly when the schema of an attached table is modified during the +# session. +# +# session3-2.1.*: Table is dropped midway through the session. +# session3-2.2.*: Table is dropped and recreated with a different # cols. +# session3-2.3.*: Table is dropped and recreated with a different PK. +# +# In all of these scenarios, the call to sqlite3session_changeset() will +# return SQLITE_SCHEMA. Also: +# +# session3-2.4.*: Table is dropped and recreated with an identical schema. +# In this case sqlite3session_changeset() returns SQLITE_OK. +# + +do_test 2.1 { + execsql { CREATE TABLE t2(a, b PRIMARY KEY) } + sqlite3session S db main + S attach t2 + execsql { + INSERT INTO t2 VALUES(1, 2); + DROP TABLE t2; + } + list [catch { S changeset } msg] $msg +} {1 SQLITE_SCHEMA} + +do_test 2.2.1 { + S delete + sqlite3session S db main + execsql { CREATE TABLE t2(a, b PRIMARY KEY, c) } + S attach t2 + execsql { + INSERT INTO t2 VALUES(1, 2, 3); + DROP TABLE t2; + CREATE TABLE t2(a, b PRIMARY KEY); + } + list [catch { S changeset } msg] $msg +} {1 SQLITE_SCHEMA} + +do_test 2.2.2 { + S delete + sqlite3session S db main + execsql { + DROP TABLE t2; + CREATE TABLE t2(a, b PRIMARY KEY, c); + } + S attach t2 + execsql { + INSERT INTO t2 VALUES(1, 2, 3); + DROP TABLE t2; + CREATE TABLE t2(a, b PRIMARY KEY, c, d); + } + list [catch { S changeset } msg] $msg +} {1 SQLITE_SCHEMA} + +do_test 2.3 { + S delete + sqlite3session S db main + execsql { + DROP TABLE t2; + CREATE TABLE t2(a, b PRIMARY KEY); + } + S attach t2 + execsql { + INSERT INTO t2 VALUES(1, 2); + DROP TABLE t2; + CREATE TABLE t2(a PRIMARY KEY, b, c); + } + list [catch { S changeset } msg] $msg +} {1 SQLITE_SCHEMA} + +do_test 2.4 { + S delete + sqlite3session S db main + execsql { + DROP TABLE t2; + CREATE TABLE t2(a, b PRIMARY KEY); + } + S attach t2 + execsql { + INSERT INTO t2 VALUES(1, 2); + DROP TABLE t2; + CREATE TABLE t2(a, b PRIMARY KEY); + } + list [catch { S changeset } msg] $msg +} {0 {}} + +S delete + catch { db close } catch { db2 close } diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index c64f567f90..ffc2e13f5e 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -1349,13 +1349,20 @@ int sqlite3session_changeset( for(pTab=pSession->pTable; rc==SQLITE_OK && pTab; pTab=pTab->pNext){ if( pTab->nEntry ){ const char *zName = pTab->zName; - int nCol = pTab->nCol; /* Local copy of member variable */ - u8 *abPK = pTab->abPK; /* Local copy of member variable */ + int nCol; /* Number of columns in table */ + u8 *abPK; /* Primary key array */ + const char **azCol = 0; /* Table columns */ int i; /* Used to iterate through hash buckets */ sqlite3_stmt *pSel = 0; /* SELECT statement to query table pTab */ int nRewind = buf.nBuf; /* Initial size of write buffer */ int nNoop; /* Size of buffer after writing tbl header */ + /* Check the table schema is still Ok. */ + rc = sessionTableInfo(db, pSession->zDb, zName, &nCol, 0, &azCol, &abPK); + if( !rc && (pTab->nCol!=nCol || memcmp(abPK, pTab->abPK, nCol)) ){ + rc = SQLITE_SCHEMA; + } + /* Write a table header */ sessionAppendByte(&buf, 'T', &rc); sessionAppendVarint(&buf, nCol, &rc); @@ -1365,7 +1372,7 @@ int sqlite3session_changeset( /* Build and compile a statement to execute: */ if( rc==SQLITE_OK ){ rc = sessionSelectStmt( - db, pSession->zDb, zName, nCol, pTab->azCol, abPK, &pSel); + db, pSession->zDb, zName, nCol, azCol, abPK, &pSel); } if( rc==SQLITE_OK && nCol!=sqlite3_column_count(pSel) ){ @@ -1407,6 +1414,7 @@ int sqlite3session_changeset( if( buf.nBuf==nNoop ){ buf.nBuf = nRewind; } + sqlite3_free(azCol); } } diff --git a/manifest b/manifest index e59c27fb75..1f7e7a7bdd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\shandling\sof\sschema\smismatches\sin\ssqlite3session.c\sso\sthat\sit\smatches\sthe\sdocs\sin\ssqlite3session.h. -D 2011-03-24T16:04:55 +C Fix\shandling\sof\sschema\schanges\smid-session. +D 2011-03-24T16:53:57 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -101,10 +101,10 @@ F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 F ext/session/session1.test b2da15b9d727d7f4e5fe95599b32b92d93b5a970 F ext/session/session2.test 8da094318ac88953478c43d0bfb0aa723ee0e379 -F ext/session/session3.test b8b9ff7efcb19234892c406dba8bd56792560efe +F ext/session/session3.test c58ebb3273a23da9b5f4eb202d522aa759530a4c F ext/session/session_common.tcl fb91560b6dbd086010df8b3a137a452f1ac21a28 F ext/session/sessionfault.test d7e6154a30e85622d0733b1a1e3c63e9b8b7004b -F ext/session/sqlite3session.c cf91fe0efb0728c219c8bc2b2174a49758fbd3f8 +F ext/session/sqlite3session.c 33a5d4be9c22099aed8e7f6c80b63540953e84c2 F ext/session/sqlite3session.h 900d900bb6a827f84754fc252a05638e0f413a6e F ext/session/test_session.c e0f500ec5e20478afc2c7998133e8acea7ec5104 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 @@ -924,7 +924,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 54298ee5ed183d1f1c49524f25e8ae1407f3d4b5 -R 73cd0f1e5ce098769e9cee2c7d1f1ebc +P 506a0d7a710e1ff2f367821e73f5080fcf63fbc5 +R 3234ab73592ecae31c60c0a6f501bbfd U dan -Z 8a40e5171d2567a1ae6ca1b697973f9a +Z 29af2cd6e2d7044fdb214ebc342ad1ba diff --git a/manifest.uuid b/manifest.uuid index e8475cfcd0..5f9877e0ed 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -506a0d7a710e1ff2f367821e73f5080fcf63fbc5 \ No newline at end of file +76d2d2ad3b2a5171393b7894f35f463ff284e53b \ No newline at end of file From f51e5f6c9950c9ed0efcbca08608f462bb4db0ed Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 25 Mar 2011 10:52:01 +0000 Subject: [PATCH 0038/1484] Improve coverage of session module code. FossilOrigin-Name: 666123c8d07be87d477e67b1cebef2b0fba5b4bc --- ext/session/session2.test | 145 +++++++++++++++++++++++++++++++++++ ext/session/session3.test | 6 +- ext/session/session4.test | 62 +++++++++++++++ ext/session/sqlite3session.c | 3 +- ext/session/sqlite3session.h | 3 + ext/session/test_session.c | 57 +++++++++++--- manifest | 21 ++--- manifest.uuid | 2 +- 8 files changed, 274 insertions(+), 25 deletions(-) create mode 100644 ext/session/session4.test diff --git a/ext/session/session2.test b/ext/session/session2.test index a4776d80e5..6662173d49 100644 --- a/ext/session/session2.test +++ b/ext/session/session2.test @@ -377,4 +377,149 @@ do_iterator_test 6.1.7 * { {UPDATE t2 0 X. {i 4 t y} {{} {} t new}} } +sqlite3session S db main +do_execsql_test 6.2.1 { + SELECT indirect(0); + SELECT indirect(-1); + SELECT indirect(45); + SELECT indirect(-100); +} {0 0 1 1} +S delete + +#------------------------------------------------------------------------- +# Test that if a conflict-handler that has been passed either NOTFOUND or +# CONSTRAINT returns REPLACE - the sqlite3changeset_apply() call returns +# MISUSE and rolls back any changes made so far. +# +# 7.1.*: NOTFOUND conflict-callback. +# 7.2.*: CONSTRAINT conflict-callback. +# +proc xConflict {args} {return REPLACE} +test_reset + +do_execsql_test 7.1.1 { + CREATE TABLE t1(a PRIMARY KEY, b); + INSERT INTO t1 VALUES(1, 'one'); + INSERT INTO t1 VALUES(2, 'two'); +} +do_test 7.1.2 { + execsql { + CREATE TABLE t1(a PRIMARY KEY, b NOT NULL); + INSERT INTO t1 VALUES(1, 'one'); + } db2 +} {} +do_test 7.1.3 { + set changeset [changeset_from_sql { + UPDATE t1 SET b = 'five' WHERE a = 1; + UPDATE t1 SET b = 'six' WHERE a = 2; + }] + set x [list] + sqlite3session_foreach c $changeset { lappend x $c } + set x +} [list \ + {UPDATE t1 0 X. {i 1 t one} {{} {} t five}} \ + {UPDATE t1 0 X. {i 2 t two} {{} {} t six}} \ +] +do_test 7.1.4 { + list [catch {sqlite3changeset_apply db2 $changeset xConflict} msg] $msg +} {1 SQLITE_MISUSE} +do_test 7.1.5 { execsql { SELECT * FROM t1 } db2 } {1 one} + +do_test 7.2.1 { + set changeset [changeset_from_sql { UPDATE t1 SET b = NULL WHERE a = 1 }] + + set x [list] + sqlite3session_foreach c $changeset { lappend x $c } + set x +} [list \ + {UPDATE t1 0 X. {i 1 t five} {{} {} n {}}} \ +] +do_test 7.2.2 { + list [catch {sqlite3changeset_apply db2 $changeset xConflict} msg] $msg +} {1 SQLITE_MISUSE} +do_test 7.2.3 { execsql { SELECT * FROM t1 } db2 } {1 one} + +#------------------------------------------------------------------------- +# Test that if a conflict-handler returns ABORT, application of the +# changeset is rolled back and the sqlite3changeset_apply() method returns +# SQLITE_ABORT. +# +# Also test that the same thing happens if a conflict handler returns an +# unrecognized integer value. Except, in this case SQLITE_MISUSE is returned +# instead of SQLITE_ABORT. +# +foreach {tn conflict_return apply_return} { + 1 ABORT SQLITE_ABORT + 2 567 SQLITE_MISUSE +} { + test_reset + proc xConflict {args} [list return $conflict_return] + + do_test 8.$tn.0 { + do_common_sql { + CREATE TABLE t1(x, y, PRIMARY KEY(x, y)); + INSERT INTO t1 VALUES('x', 'y'); + } + execsql { INSERT INTO t1 VALUES('w', 'w') } + + set changeset [changeset_from_sql { DELETE FROM t1 WHERE 1 }] + + set x [list] + sqlite3session_foreach c $changeset { lappend x $c } + set x + } [list \ + {DELETE t1 0 XX {t w t w} {}} \ + {DELETE t1 0 XX {t x t y} {}} \ + ] + + do_test 8.$tn.1 { + list [catch {sqlite3changeset_apply db2 $changeset xConflict} msg] $msg + } [list 1 $apply_return] + + do_test 8.$tn.2 { + execsql {SELECT * FROM t1} db2 + } {x y} +} + + +#------------------------------------------------------------------------- +# Try to cause an infinite loop as follows: +# +# 1. Have a changeset insert a row that causes a CONFLICT callback, +# 2. Have the conflict handler return REPLACE, +# 3. After the session module deletes the conflicting row, have a trigger +# re-insert it. +# 4. Goto step 1... +# +# This doesn't work, as the second invocation of the conflict handler is a +# CONSTRAINT, not a CONFLICT. There is at most one CONFLICT callback for +# each change in the changeset. +# +test_reset +proc xConflict {type args} { + if {$type == "CONFLICT"} { return REPLACE } + return OMIT +} +do_test 9.1 { + execsql { + CREATE TABLE t1(a PRIMARY KEY, b); + } + execsql { + CREATE TABLE t1(a PRIMARY KEY, b); + INSERT INTO t1 VALUES('x', 2); + CREATE TRIGGER tr1 AFTER DELETE ON t1 BEGIN + INSERT INTO t1 VALUES(old.a, old.b); + END; + } db2 +} {} +do_test 9.2 { + set changeset [changeset_from_sql { INSERT INTO t1 VALUES('x', 1) }] + sqlite3changeset_apply db2 $changeset xConflict +} {} +do_test 9.3 { + execsql { SELECT * FROM t1 } db2 +} {x 2} + + + finish_test diff --git a/ext/session/session3.test b/ext/session/session3.test index d0d2c31fa4..a0946f3099 100644 --- a/ext/session/session3.test +++ b/ext/session/session3.test @@ -8,8 +8,10 @@ # May you share freely, never taking more than you give. # #*********************************************************************** -# This file implements regression tests for the session module. -# +# This file implements regression tests for the session module. More +# specifically, it focuses on testing the session modules response to +# database schema modifications and mismatches. +# if {![info exists testdir]} { set testdir [file join [file dirname [info script]] .. .. test] diff --git a/ext/session/session4.test b/ext/session/session4.test new file mode 100644 index 0000000000..c69fa85fc4 --- /dev/null +++ b/ext/session/session4.test @@ -0,0 +1,62 @@ +# 2011 March 25 +# +# 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 regression tests for the session module. +# + +if {![info exists testdir]} { + set testdir [file join [file dirname [info script]] .. .. test] +} +source [file join [file dirname [info script]] session_common.tcl] +source $testdir/tester.tcl + +set testprefix session4 + +do_test 1.0 { + execsql { + CREATE TABLE x(a, b, c, d, e, PRIMARY KEY(c, e)); + INSERT INTO x VALUES(65.21, X'28B0', 16.35, NULL, 'doers'); + INSERT INTO x VALUES(NULL, 78.49, 2, X'60', -66); + INSERT INTO x VALUES('cathedral', NULL, 35, NULL, X'B220937E80A2D8'); + INSERT INTO x VALUES(NULL, 'masking', -91.37, NULL, X'596D'); + INSERT INTO x VALUES(19, 'domains', 'espouse', -94, 'throw'); + } + + sqlite3session S db main + set changeset [changeset_from_sql { + DELETE FROM x WHERE e = -66; + UPDATE x SET a = 'parameterizable', b = 31.8 WHERE c = 35; + INSERT INTO x VALUES(-75.61, -17, 16.85, NULL, X'D73DB02678'); + }] + set {} {} +} {} + + +# This currently causes crashes. sqlite3changeset_invert() does not handle +# corrupt changesets well. +if 0 { + do_test 1.1 { + for {set i 0} {$i < [string length $changeset]} {incr i} { + set before [string range $changeset 0 [expr $i-1]] + set after [string range $changeset [expr $i+1] end] + for {set j 10} {$j < 260} {incr j} { + set x [binary format "a*ca*" $before $j $after] + catch { sqlite3changeset_invert $x } + } + } + } {} +} + +do_test 1.2 { + set x [binary format "ca*" 0 [string range $changeset 1 end]] + list [catch { sqlite3changeset_invert $x } msg] $msg +} {1 SQLITE_CORRUPT} + +finish_test diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index ffc2e13f5e..36d83e6b8e 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -2255,7 +2255,8 @@ static int sessionConflictHandler( if( rc==SQLITE_OK ){ switch( res ){ case SQLITE_CHANGESET_REPLACE: - if( pbReplace ) *pbReplace = 1; + assert( pbReplace ); + *pbReplace = 1; break; case SQLITE_CHANGESET_OMIT: diff --git a/ext/session/sqlite3session.h b/ext/session/sqlite3session.h index 5d19379ec8..bcb901667c 100644 --- a/ext/session/sqlite3session.h +++ b/ext/session/sqlite3session.h @@ -513,6 +513,9 @@ int sqlite3changeset_finalize(sqlite3_changeset_iter *pIter); ** It is the responsibility of the caller to eventually call sqlite3_free() ** on the *ppOut pointer to free the buffer allocation following a successful ** call to this function. +** +** WARNING/TODO: This function currently assumes that the input is a valid +** changeset. If it is not, the results are undefined. */ int sqlite3changeset_invert( int nIn, void *pIn, /* Input changeset */ diff --git a/ext/session/test_session.c b/ext/session/test_session.c index e3d6d60c22..4befd0fe68 100644 --- a/ext/session/test_session.c +++ b/ext/session/test_session.c @@ -17,7 +17,7 @@ static int test_session_error(Tcl_Interp *interp, int rc){ ** $session changeset ** $session delete ** $session enable BOOL -** $session indirect BOOL +** $session indirect INTEGER */ static int test_session_cmd( void *clientData, @@ -93,7 +93,7 @@ static int test_session_cmd( case 4: { /* indirect */ int val; - if( Tcl_GetBooleanFromObj(interp, objv[2], &val) ) return TCL_ERROR; + if( Tcl_GetIntFromObj(interp, objv[2], &val) ) return TCL_ERROR; val = sqlite3session_indirect(pSession, val); Tcl_SetObjResult(interp, Tcl_NewBooleanObj(val)); break; @@ -268,18 +268,59 @@ static int test_conflict_handler( } /* If this is a CHANGESET_DATA or CHANGESET_CONFLICT conflict, append - ** the conflicting row. */ + ** the conflicting row. */ if( eConf==SQLITE_CHANGESET_DATA || eConf==SQLITE_CHANGESET_CONFLICT ){ int i; Tcl_Obj *pConflict = Tcl_NewObj(); for(i=0; i Date: Fri, 25 Mar 2011 19:06:09 +0000 Subject: [PATCH 0039/1484] Improve coverage of session module a bit more. FossilOrigin-Name: 4255a9f609c4fd43582a0874143eabe211199726 --- ext/session/session2.test | 38 ++++++++++++++++++++ ext/session/session3.test | 2 +- ext/session/session4.test | 5 +++ ext/session/sessionfault.test | 4 +-- ext/session/sqlite3session.c | 66 +++++++++++++++++------------------ ext/session/test_session.c | 6 ++-- manifest | 22 ++++++------ manifest.uuid | 2 +- 8 files changed, 94 insertions(+), 51 deletions(-) diff --git a/ext/session/session2.test b/ext/session/session2.test index 6662173d49..7adbfd5b6f 100644 --- a/ext/session/session2.test +++ b/ext/session/session2.test @@ -44,12 +44,24 @@ do_iterator_test 1.1 t1 { {DELETE t1 0 X. {t i t one} {}} {INSERT t1 0 X. {} {t ii t two}} } + do_iterator_test 1.2 t1 { INSERT INTO t1 VALUES(1.5, 99.9) } { {INSERT t1 0 X. {} {f 1.5 f 99.9}} } +do_iterator_test 1.3 t1 { + UPDATE t1 SET b = 100.1 WHERE a = 1.5; + UPDATE t1 SET b = 99.9 WHERE a = 1.5; +} { } + +do_iterator_test 1.4 t1 { + UPDATE t1 SET b = 100.1 WHERE a = 1.5; +} { + {UPDATE t1 0 X. {f 1.5 f 99.9} {{} {} f 100.1}} +} + # Execute each of the following blocks of SQL on database [db1]. Collect # changes using a session object. Apply the resulting changeset to @@ -520,6 +532,32 @@ do_test 9.3 { execsql { SELECT * FROM t1 } db2 } {x 2} +#------------------------------------------------------------------------- +# +test_reset +db function enable [list S enable] +do_common_sql { + CREATE TABLE t1(a PRIMARY KEY, b); + INSERT INTO t1 VALUES('x', 'X'); +} + +do_iterator_test 10.1 t1 { + INSERT INTO t1 VALUES('y', 'Y'); + SELECT enable(0); + INSERT INTO t1 VALUES('z', 'Z'); + SELECT enable(1); +} { + {INSERT t1 0 X. {} {t y t Y}} +} + +sqlite3session S db main +do_execsql_test 10.2 { + SELECT enable(0); + SELECT enable(-1); + SELECT enable(1); + SELECT enable(-1); +} {0 0 1 1} +S delete finish_test diff --git a/ext/session/session3.test b/ext/session/session3.test index a0946f3099..c7046d9c8f 100644 --- a/ext/session/session3.test +++ b/ext/session/session3.test @@ -146,7 +146,7 @@ do_test 2.3 { execsql { INSERT INTO t2 VALUES(1, 2); DROP TABLE t2; - CREATE TABLE t2(a PRIMARY KEY, b, c); + CREATE TABLE t2(a PRIMARY KEY, b); } list [catch { S changeset } msg] $msg } {1 SQLITE_SCHEMA} diff --git a/ext/session/session4.test b/ext/session/session4.test index c69fa85fc4..f695c2e467 100644 --- a/ext/session/session4.test +++ b/ext/session/session4.test @@ -59,4 +59,9 @@ do_test 1.2 { list [catch { sqlite3changeset_invert $x } msg] $msg } {1 SQLITE_CORRUPT} +do_test 1.3 { + set x [binary format "ca*" 0 [string range $changeset 1 end]] + list [catch { sqlite3changeset_apply db $x xConflict } msg] $msg +} {1 SQLITE_CORRUPT} + finish_test diff --git a/ext/session/sessionfault.test b/ext/session/sessionfault.test index e1c2980b79..cf155f4f3d 100644 --- a/ext/session/sessionfault.test +++ b/ext/session/sessionfault.test @@ -45,7 +45,7 @@ do_faultsim_test 1.1 -faults oom-* -prep { sqlite3 db2 test.db2 } -body { do_then_apply_sql { - INSERT INTO t1 VALUES(7, 8, 9); + INSERT INTO t1 VALUES('a string value', 8, 9); UPDATE t1 SET c = 10 WHERE a = 1; DELETE FROM t1 WHERE a = 4; } @@ -63,7 +63,7 @@ do_faultsim_test 1.2 -faults oom-* -prep { sqlite3session S db main S attach * execsql { - INSERT INTO t1 VALUES(7, 8, 9); + INSERT INTO t1 VALUES('a string value', 8, 9); UPDATE t1 SET c = 10 WHERE a = 1; DELETE FROM t1 WHERE a = 4; } diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index 36d83e6b8e..75385e5f2e 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -1181,10 +1181,10 @@ static void sessionAppendUpdate( break; } - case SQLITE_TEXT: - case SQLITE_BLOB: { + default: { int nByte; int nHdr = 1 + sessionVarintGet(&pCsr[1], &nByte); + assert( eType==SQLITE_TEXT || eType==SQLITE_BLOB ); nAdvance = nHdr + nByte; if( eType==sqlite3_column_type(pStmt, i) && nByte==sqlite3_column_bytes(pStmt, i) @@ -1260,19 +1260,18 @@ static int sessionSelectBind( sqlite3_stmt *pSelect, int nCol, u8 *abPK, - u8 *aRecord, - int nRecord + SessionChange *pChange ){ int i; int rc = SQLITE_OK; - u8 *a = aRecord; + u8 *a = pChange->aRecord; for(i=0; irc; + + if( pSession->rc ) return pSession->rc; + rc = sqlite3_exec(pSession->db, "SAVEPOINT changeset", 0, 0, 0); + if( rc!=SQLITE_OK ) return rc; + + sqlite3_mutex_enter(sqlite3_db_mutex(db)); for(pTab=pSession->pTable; rc==SQLITE_OK && pTab; pTab=pTab->pNext){ if( pTab->nEntry ){ @@ -1375,37 +1378,31 @@ int sqlite3session_changeset( db, pSession->zDb, zName, nCol, azCol, abPK, &pSel); } - if( rc==SQLITE_OK && nCol!=sqlite3_column_count(pSel) ){ - rc = SQLITE_SCHEMA; - } - nNoop = buf.nBuf; for(i=0; inChange && rc==SQLITE_OK; i++){ SessionChange *p; /* Used to iterate through changes */ for(p=pTab->apChange[i]; rc==SQLITE_OK && p; p=p->pNext){ - rc = sessionSelectBind(pSel, nCol, abPK, p->aRecord, p->nRecord); - if( rc==SQLITE_OK ){ - if( sqlite3_step(pSel)==SQLITE_ROW ){ - int iCol; - if( p->bInsert ){ - sessionAppendByte(&buf, SQLITE_INSERT, &rc); - sessionAppendByte(&buf, p->bIndirect, &rc); - for(iCol=0; iColbInsert ){ - /* A DELETE change */ - sessionAppendByte(&buf, SQLITE_DELETE, &rc); + rc = sessionSelectBind(pSel, nCol, abPK, p); + if( sqlite3_step(pSel)==SQLITE_ROW ){ + int iCol; + if( p->bInsert ){ + sessionAppendByte(&buf, SQLITE_INSERT, &rc); sessionAppendByte(&buf, p->bIndirect, &rc); - sessionAppendBlob(&buf, p->aRecord, p->nRecord, &rc); - } - if( rc==SQLITE_OK ){ - rc = sqlite3_reset(pSel); + for(iCol=0; iColbInsert ){ + /* A DELETE change */ + sessionAppendByte(&buf, SQLITE_DELETE, &rc); + sessionAppendByte(&buf, p->bIndirect, &rc); + sessionAppendBlob(&buf, p->aRecord, p->nRecord, &rc); + } + if( rc==SQLITE_OK ){ + rc = sqlite3_reset(pSel); } } } @@ -1425,6 +1422,7 @@ int sqlite3session_changeset( sqlite3_free(buf.aBuf); } + sqlite3_exec(db, "RELEASE changeset", 0, 0, 0); sqlite3_mutex_leave(sqlite3_db_mutex(db)); return rc; } diff --git a/ext/session/test_session.c b/ext/session/test_session.c index 4befd0fe68..a8b73824a0 100644 --- a/ext/session/test_session.c +++ b/ext/session/test_session.c @@ -85,7 +85,7 @@ static int test_session_cmd( case 3: { /* enable */ int val; - if( Tcl_GetBooleanFromObj(interp, objv[2], &val) ) return TCL_ERROR; + if( Tcl_GetIntFromObj(interp, objv[2], &val) ) return TCL_ERROR; val = sqlite3session_enable(pSession, val); Tcl_SetObjResult(interp, Tcl_NewBooleanObj(val)); break; @@ -436,6 +436,7 @@ static int test_sqlite3session_foreach( while( SQLITE_ROW==sqlite3changeset_next(pIter) ){ int nCol; /* Number of columns in table */ + int nCol2; /* Number of columns in table */ int op; /* SQLITE_INSERT, UPDATE or DELETE */ const char *zTab; /* Name of table change applies to */ Tcl_Obj *pVar; /* Tcl value to set $VARNAME to */ @@ -460,7 +461,8 @@ static int test_sqlite3session_foreach( zPK = ckalloc(nCol+1); memset(zPK, 0, nCol+1); - sqlite3changeset_pk(pIter, &abPK, 0); + sqlite3changeset_pk(pIter, &abPK, &nCol2); + assert( nCol==nCol2 ); for(i=0; i Date: Wed, 30 Mar 2011 17:07:47 +0000 Subject: [PATCH 0040/1484] Add documentation to the sqlite3_preupdate_hook() interface and its relatives. FossilOrigin-Name: 8180f2881fa970429e28d4f3258a56cfaabbcabd --- manifest | 12 ++++---- manifest.uuid | 2 +- src/sqlite.h.in | 81 ++++++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 81 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index b427fcf551..35fb6c6035 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sin\sall\sthe\slatest\schanges\sfrom\strunk. -D 2011-03-30T02:03:12.567 +C Add\sdocumentation\sto\sthe\ssqlite3_preupdate_hook()\sinterface\sand\sits\srelatives. +D 2011-03-30T17:07:47.319 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -187,7 +187,7 @@ F src/resolve.c 1c0f32b64f8e3f555fe1f732f9d6f501a7f05706 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 F src/select.c d24406c45dd2442eb2eeaac413439066b149c944 F src/shell.c 9dc0b4bb59290c0a35256d278cab0f314987ad6a -F src/sqlite.h.in 73512de44f0d3563dd24be2e701542e52c7efe25 +F src/sqlite.h.in 3fef17a4201b068291da874b42599b9e61c0cf68 F src/sqlite3ext.h c90bd5507099f62043832d73f6425d8d5c5da754 F src/sqliteInt.h 7c11f9a648cf82e87330fd2185fcaa1f7c46dfba F src/sqliteLimit.h a17dcd3fb775d63b64a43a55c54cb282f9726f44 @@ -929,7 +929,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 4255a9f609c4fd43582a0874143eabe211199726 3d2de011814002e2e25b7645f94ff8fc7aab9cdd -R 48b479c7a408c0c8015c6f938b7e92a4 +P b11d941e92897663da46160185e6e305d4e28fe6 +R e37cfb6574f4ec186f2c67ceafeda97a U drh -Z 1cd943e96dc4b8cfc7720b21a63156f8 +Z ede135d544f338afa66b4a4b2184647f diff --git a/manifest.uuid b/manifest.uuid index c6b7c703a4..9a70869e00 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b11d941e92897663da46160185e6e305d4e28fe6 \ No newline at end of file +8180f2881fa970429e28d4f3258a56cfaabbcabd \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 42ce94be21..c3dc70168f 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -1129,7 +1129,7 @@ int sqlite3_config(int, ...); ** [database connection] (specified in the first argument). ** ** The second argument to sqlite3_db_config(D,V,...) is the -** [SQLITE_DBCONIG_LOOKASIDE | configuration verb] - an integer code +** [SQLITE_DBCONFIG_LOOKASIDE | configuration verb] - an integer code ** that indicates what aspect of the [database connection] is being configured. ** Subsequent arguments vary depending on the configuration verb. ** @@ -4263,8 +4263,8 @@ void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*); ** on the same [database connection] D, or NULL for ** the first call on D. ** -** See also the [sqlite3_commit_hook()] and [sqlite3_rollback_hook()] -** interfaces. +** See also the [sqlite3_commit_hook()], [sqlite3_rollback_hook()], +** and [sqlite3_preupdate_hook()] interfaces. */ void *sqlite3_update_hook( sqlite3*, @@ -6390,10 +6390,77 @@ int sqlite3_wal_checkpoint_v2( /* ** CAPI3REF: The pre-update hook. -** -** The preupdate_old() API may only be used from within an SQLITE_UPDATE or -** SQLITE_DELETE pre-update callback. The preupdate_modified() API may only -** be used from within an SQLITE_UPDATE pre-update callback. +** EXPERIMENTAL +** +** ^The [sqlite3_preupdate_hook()] interface registers a callback function +** that is invoked prior to each [INSERT], [UPDATE], and [DELETE] operation. +** ^At most one preupdate hook may be registered at a time on a single +** [database connection]; each call to [sqlite3_preupdate_hook()] overrides +** the previous setting. +** ^The preupdate hook is disabled by invoking [sqlite3_preupdate_hook()] +** with a NULL pointer as the second parameter. +** ^The third parameter to [sqlite3_preupdate_hook()] is passed through as +** the first parameter to callbacks. +** +** ^The preupdate hook only fires for changes to real tables; the preupdate +** hook is not invoked for changes to virtual tables. +** +** ^The second parameter to the preupdate callback is a pointer to +** the [database connection] that registered the preupdate hook. +** ^The third parameter to the preupdate callback is one of the constants +** [SQLITE_INSERT], [SQLITE_DELETE], or [SQLITE_UPDATE] to indentify the +** kind of update operation that is about to occur. +** ^(The fourth parameter to the preupdate callback is the name of the +** database within the database connection that is being modified. This +** will be "main" for the main database or "temp" for TEMP tables or +** the name given after the AS keyword in the [ATTACH] statement for attached +** databases.)^ +** ^The fifth parameter to the preupdate callback is the name of the +** table that is being modified. +** ^The sixth parameter to the preupdate callback is the initial [rowid] of the +** row being changes for SQLITE_UPDATE and SQLITE_DELETE changes and is +** undefined for SQLITE_INSERT changes. +** ^The seventh parameter to the preupdate callback is the final [rowid] of +** the row being changed for SQLITE_UPDATE and SQLITE_INSERT changes and is +** undefined for SQLITE_DELETE changes. +** +** The [sqlite3_preupdate_old()], [sqlite3_preupdate_new()], +** [sqlite3_preupdate_count()], and [sqlite3_preupdate_depth()] interfaces +** provide additional information about a preupdate event. These routines +** may only be called from within a preupdate callback. Invoking any of +** these routines from outside of a preupdate callback or with a +** [database connection] pointer that is different from the one supplied +** to the preupdate callback results in undefined and probably undesirable +** behavior. +** +** ^The [sqlite3_preupdate_count(D)] interface returns the number of columns +** in the row that is being inserted, updated, or deleted. +** +** ^The [sqlite3_preupdate_old(D,N,P)] interface writes into P a pointer to +** a [protected sqlite3_value] that contains the value of the Nth column of +** the table row before it is updated. The N parameter must be between 0 +** and one less than the number of columns or the behavior will be +** undefined. This must only be used within SQLITE_UPDATE and SQLITE_DELETE +** preupdate callbacks; if it is used by an SQLITE_INSERT callback then the +** behavior is undefined. The [sqlite3_value] that P points to +** will be destroyed when the preupdate callback returns. +** +** ^The [sqlite3_preupdate_new(D,N,P)] interface writes into P a pointer to +** a [protected sqlite3_value] that contains the value of the Nth column of +** the table row after it is updated. The N parameter must be between 0 +** and one less than the number of columns or the behavior will be +** undefined. This must only be used within SQLITE_INSERT and SQLITE_UPDATE +** preupdate callbacks; if it is used by an SQLITE_DELETE callback then the +** behavior is undefined. The [sqlite3_value] that P points to +** will be destroyed when the preupdate callback returns. +** +** ^The [sqlite3_preupdate_depth(D)] interface returns 0 if the preupdate +** callback was invoked as a result of a direct insert, update, or delete +** operation; or 1 for inserts, updates, or deletes invoked by top-level +** triggers; or 2 for changes resulting from triggers called by top-level +** triggers; and so forth. +** +** See also: [sqlite3_update_hook()] */ SQLITE_EXPERIMENTAL void *sqlite3_preupdate_hook( sqlite3 *db, From 67c495ac207665a2ac0becee02f067487bf75918 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 30 Mar 2011 17:25:35 +0000 Subject: [PATCH 0041/1484] Disable the truncate optimization if there is a preupdate hook. FossilOrigin-Name: d051694e024c590e4687cae1368f900799b7442d --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/delete.c | 9 +++++++-- test/hook.test | 9 ++++----- 4 files changed, 19 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index 35fb6c6035..6ebb88896d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sdocumentation\sto\sthe\ssqlite3_preupdate_hook()\sinterface\sand\sits\srelatives. -D 2011-03-30T17:07:47.319 +C Disable\sthe\struncate\soptimization\sif\sthere\sis\sa\spreupdate\shook. +D 2011-03-30T17:25:35.303 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -138,7 +138,7 @@ F src/callback.c 5069f224882cbdccd559f591271d28d7f37745bc F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 52ff72f966cee3087e0138a3ec69371c22be3c01 F src/date.c 1548fdac51377e4e7833251de878b4058c148e1b -F src/delete.c c55748a1628b54c8785de0ff4bd9cbe27fe111cb +F src/delete.c 4aebb9ccea435701c137bf25e07fe93ad8e9346d F src/expr.c 00817c672af554321fd67c44325afd7cef0e4648 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 418b840007c873975fd0d071746d952f8bca20ce @@ -485,7 +485,7 @@ F test/fuzz2.test 207d0f9d06db3eaf47a6b7bfc835b8e2fc397167 F test/fuzz3.test aec64345184d1662bd30e6a17851ff659d596dc5 F test/fuzz_common.tcl a87dfbb88c2a6b08a38e9a070dabd129e617b45b F test/fuzz_malloc.test dd7001ac86d09c154a7dff064f4739c60e2b312c -F test/hook.test 14b2439b878c9aae03a3684cba717be4bfdcc1c1 +F test/hook.test 29a0b6a18111835bdca827f62a7975a8e30a1dd5 F test/icu.test 70df4faca133254c042d02ae342c0a141f2663f4 F test/in.test 19b642bb134308980a92249750ea4ce3f6c75c2d F test/in2.test 5d4c61d17493c832f7d2d32bef785119e87bde75 @@ -929,7 +929,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P b11d941e92897663da46160185e6e305d4e28fe6 -R e37cfb6574f4ec186f2c67ceafeda97a +P 8180f2881fa970429e28d4f3258a56cfaabbcabd +R 7bdc0a7971e68baabbe152ea44f74530 U drh -Z ede135d544f338afa66b4a4b2184647f +Z a923e72061e5acce879b548f79bb9c49 diff --git a/manifest.uuid b/manifest.uuid index 9a70869e00..15b385f496 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8180f2881fa970429e28d4f3258a56cfaabbcabd \ No newline at end of file +d051694e024c590e4687cae1368f900799b7442d \ No newline at end of file diff --git a/src/delete.c b/src/delete.c index a5d00263b5..71a243d5a6 100644 --- a/src/delete.c +++ b/src/delete.c @@ -338,8 +338,13 @@ void sqlite3DeleteFrom( /* Special case: A DELETE without a WHERE clause deletes everything. ** It is easier just to erase the whole table. Prior to version 3.6.5, ** this optimization caused the row change count (the value returned by - ** API function sqlite3_count_changes) to be set incorrectly. */ - if( rcauth==SQLITE_OK && pWhere==0 && !pTrigger && !IsVirtual(pTab) + ** API function sqlite3_count_changes) to be set incorrectly. + */ + if( rcauth==SQLITE_OK + && pWhere==0 + && !pTrigger + && !IsVirtual(pTab) + && db->xPreUpdateCallback==0 && 0==sqlite3FkRequired(pParse, pTab, 0, 0) ){ assert( !isView ); diff --git a/test/hook.test b/test/hook.test index 016569f0ae..5cceaf9abf 100644 --- a/test/hook.test +++ b/test/hook.test @@ -481,10 +481,10 @@ do_preupdate_test 7.2.1 { do_preupdate_test 7.2.2 { DELETE FROM t1 } { - DELETE main t3 1 1 1 1 - DELETE main t3 2 2 b a - DELETE main t3 4 4 a b - DELETE main t3 5 5 c d + DELETE main t1 1 1 1 1 + DELETE main t1 2 2 b a + DELETE main t1 4 4 a b + DELETE main t1 5 5 c d } do_execsql_test 7.3.0 { @@ -765,4 +765,3 @@ do_preupdate_test 7.6.4 { } finish_test - From 9b1c62d4166694136cd472e4498e2c77045a881c Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 30 Mar 2011 21:04:43 +0000 Subject: [PATCH 0042/1484] Add the SQLITE_ENABLE_PREUPDATE_HOOK compile-time option. FossilOrigin-Name: 6634521461e6acff7cc778590e62d57831f9230d --- ext/session/session1.test | 2 +- ext/session/session2.test | 1 + ext/session/session3.test | 2 +- ext/session/session4.test | 1 + ext/session/sqlite3session.c | 4 ++-- ext/session/test_session.c | 6 ++--- manifest | 46 ++++++++++++++++++------------------ manifest.uuid | 2 +- src/delete.c | 2 ++ src/insert.c | 2 ++ src/main.c | 2 ++ src/sqlite.h.in | 3 +++ src/sqliteInt.h | 2 ++ src/tclsqlite.c | 14 ++++++++--- src/test_config.c | 6 +++++ src/update.c | 4 ++-- src/vdbe.c | 18 ++++++++++++-- src/vdbeapi.c | 8 +++++++ src/vdbeaux.c | 4 +++- test/hook.test | 5 ++++ 20 files changed, 95 insertions(+), 39 deletions(-) diff --git a/ext/session/session1.test b/ext/session/session1.test index 4a2b50e6c6..067432affa 100644 --- a/ext/session/session1.test +++ b/ext/session/session1.test @@ -16,6 +16,7 @@ if {![info exists testdir]} { } source [file join [file dirname [info script]] session_common.tcl] source $testdir/tester.tcl +ifcapable !session {finish_test; return} set testprefix session1 @@ -444,4 +445,3 @@ do_db2_test 6.3 "SELECT * FROM t2" {a b A B} catch { db2 close } finish_test - diff --git a/ext/session/session2.test b/ext/session/session2.test index 7adbfd5b6f..5c7ea47d5f 100644 --- a/ext/session/session2.test +++ b/ext/session/session2.test @@ -17,6 +17,7 @@ if {![info exists testdir]} { } source [file join [file dirname [info script]] session_common.tcl] source $testdir/tester.tcl +ifcapable !session {finish_test; return} set testprefix session2 diff --git a/ext/session/session3.test b/ext/session/session3.test index c7046d9c8f..c0fcebff66 100644 --- a/ext/session/session3.test +++ b/ext/session/session3.test @@ -18,6 +18,7 @@ if {![info exists testdir]} { } source [file join [file dirname [info script]] session_common.tcl] source $testdir/tester.tcl +ifcapable !session {finish_test; return} set testprefix session3 @@ -177,4 +178,3 @@ test_sqlite3_log sqlite3_initialize finish_test - diff --git a/ext/session/session4.test b/ext/session/session4.test index f695c2e467..8e179baf6d 100644 --- a/ext/session/session4.test +++ b/ext/session/session4.test @@ -16,6 +16,7 @@ if {![info exists testdir]} { } source [file join [file dirname [info script]] session_common.tcl] source $testdir/tester.tcl +ifcapable !session {finish_test; return} set testprefix session4 diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index 75385e5f2e..70acb76056 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -1,5 +1,5 @@ -#ifdef SQLITE_ENABLE_SESSION +#if defined(SQLITE_ENABLE_SESSION) && defined(SQLITE_ENABLE_PREUPDATE_HOOK) #include "sqlite3session.h" #include @@ -2533,4 +2533,4 @@ int sqlite3changeset_apply( return rc; } -#endif /* #ifdef SQLITE_ENABLE_SESSION */ +#endif /* SQLITE_ENABLE_SESSION && SQLITE_ENABLE_PREUPDATE_HOOK */ diff --git a/ext/session/test_session.c b/ext/session/test_session.c index a8b73824a0..6af1892150 100644 --- a/ext/session/test_session.c +++ b/ext/session/test_session.c @@ -1,5 +1,6 @@ -#if defined(SQLITE_TEST) && defined(SQLITE_ENABLE_SESSION) +#if defined(SQLITE_TEST) && defined(SQLITE_ENABLE_SESSION) \ + && defined(SQLITE_ENABLE_PREUPDATE_HOOK) #include "sqlite3session.h" #include @@ -519,5 +520,4 @@ int TestSession_Init(Tcl_Interp *interp){ return TCL_OK; } -#endif - +#endif /* SQLITE_TEST && SQLITE_SESSION && SQLITE_PREUPDATE_HOOK */ diff --git a/manifest b/manifest index 6ebb88896d..dddc79360d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Disable\sthe\struncate\soptimization\sif\sthere\sis\sa\spreupdate\shook. -D 2011-03-30T17:25:35.303 +C Add\sthe\sSQLITE_ENABLE_PREUPDATE_HOOK\scompile-time\soption. +D 2011-03-30T21:04:43.055 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -99,15 +99,15 @@ F ext/rtree/rtree_util.tcl 06aab2ed5b826545bf215fff90ecb9255a8647ea F ext/rtree/sqlite3rtree.h 1af0899c63a688e272d69d8e746f24e76f10a3f0 F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 -F ext/session/session1.test b2da15b9d727d7f4e5fe95599b32b92d93b5a970 -F ext/session/session2.test e36222e1f48bc9b1d80eacd001994d307c107e73 -F ext/session/session3.test 919f7e2e07fa5a166a0ea5d8ac3fbe7f38f7e447 -F ext/session/session4.test a37bc9d8891ea1f3e120056c978f66c925f040b9 +F ext/session/session1.test 7a92a2a6f531aef1e9764ffb7f983fb8b315376d +F ext/session/session2.test c3e5f78d5eb988e35cc2ba9ce3678f706283cfdb +F ext/session/session3.test bfa2376db7cbb2ac69496f84d93a8d81b13110d3 +F ext/session/session4.test a6ed685da7a5293c5d6f99855bcf41dbc352ca84 F ext/session/session_common.tcl fb91560b6dbd086010df8b3a137a452f1ac21a28 F ext/session/sessionfault.test 2544a2e2ecad56e3c07a32c09799871d243c114c -F ext/session/sqlite3session.c 9be8ccee4248681700659b89a81ae5c6cb8afacc +F ext/session/sqlite3session.c eaf093c81f076301cfd04f794d047cf7beffd290 F ext/session/sqlite3session.h f284bac51c12de0e0096fc986e61f5ae6b9e5be5 -F ext/session/test_session.c f8fdf5c110898b2bbc20c475fca879664c77fb5a +F ext/session/test_session.c 82e3fd7d94f485ea63bcfb15d636c95a01db97a9 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F main.mk e283752f215b7055cdc48399da82033b67024e42 @@ -138,7 +138,7 @@ F src/callback.c 5069f224882cbdccd559f591271d28d7f37745bc F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 52ff72f966cee3087e0138a3ec69371c22be3c01 F src/date.c 1548fdac51377e4e7833251de878b4058c148e1b -F src/delete.c 4aebb9ccea435701c137bf25e07fe93ad8e9346d +F src/delete.c 44800af91a90f9d9445a266129313f27487614d8 F src/expr.c 00817c672af554321fd67c44325afd7cef0e4648 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 418b840007c873975fd0d071746d952f8bca20ce @@ -147,12 +147,12 @@ F src/global.c 02335177cf6946fe5525c6f0755cf181140debf3 F src/hash.c 458488dcc159c301b8e7686280ab209f1fb915af F src/hash.h 2894c932d84d9f892d4b4023a75e501f83050970 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 -F src/insert.c c46747b4bdde2ae4c2815526a151fefb66ba64a6 +F src/insert.c e354eadb2ca3e8d939ba928f229e2268974f380c F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f F src/lempar.c 7f026423f4d71d989e719a743f98a1cbd4e6d99e F src/loadext.c 8af9fcc75708d60b88636ccba38b4a7b3c155c3e -F src/main.c 2563bd9ca8430c7677d375c566b54b890aaf508f +F src/main.c bed41512fabb19492b61d37fd988d79f6225e624 F src/malloc.c 92d59a007d7a42857d4e9454aa25b6b703286be1 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 00bd8265c81abb665c48fea1e0c234eb3b922206 @@ -187,13 +187,13 @@ F src/resolve.c 1c0f32b64f8e3f555fe1f732f9d6f501a7f05706 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 F src/select.c d24406c45dd2442eb2eeaac413439066b149c944 F src/shell.c 9dc0b4bb59290c0a35256d278cab0f314987ad6a -F src/sqlite.h.in 3fef17a4201b068291da874b42599b9e61c0cf68 +F src/sqlite.h.in 235300cdca517ce148385d3ab816e7e8cf9e1ff3 F src/sqlite3ext.h c90bd5507099f62043832d73f6425d8d5c5da754 -F src/sqliteInt.h 7c11f9a648cf82e87330fd2185fcaa1f7c46dfba +F src/sqliteInt.h 14325fe41ee564f064adacda02ab64837fa905c4 F src/sqliteLimit.h a17dcd3fb775d63b64a43a55c54cb282f9726f44 F src/status.c 4997380fbb915426fef9e500b4872e79c99267fc F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e -F src/tclsqlite.c c233c25153b6fa3b511bc65df352cb8f97a0f81d +F src/tclsqlite.c 8376ae45f7e28d521ad708a0086771fab3c96475 F src/test1.c 9020310c7617234b33fd1c3064f89524db25f290 F src/test2.c 80d323d11e909cf0eb1b6fbb4ac22276483bcf31 F src/test3.c 056093cfef69ff4227a6bdb9108564dc7f45e4bc @@ -207,7 +207,7 @@ F src/test_async.c 0612a752896fad42d55c3999a5122af10dcf22ad F src/test_autoext.c 30e7bd98ab6d70a62bb9ba572e4c7df347fe645e F src/test_backup.c c129c91127e9b46e335715ae2e75756e25ba27de F src/test_btree.c 47cd771250f09cdc6e12dda5bc71bc0b3abc96e2 -F src/test_config.c e9a4ce02dec5bcced1c13e0cf8b72edfd5903d74 +F src/test_config.c 3050df9faf023fb52937f7e9998004c2415d4122 F src/test_demovfs.c 0aed671636735116fc872c5b03706fd5612488b5 F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc F src/test_func.c cbdec5cededa0761daedde5baf06004a9bf416b5 @@ -237,15 +237,15 @@ F src/test_vfstrace.c 2265c9895f350c8d3c39b079998fbe7481505cc1 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/tokenize.c 604607d6813e9551cf5189d899e0a25c12681080 F src/trigger.c ec4813709e990a169b6923293e839fa5dfd64282 -F src/update.c f81e9b326cafba3fbe493141e396f3bbfba1d99b +F src/update.c 3f3f3bb734a0da1dffd0ed33e504642b35ed3605 F src/utf.c d83650c3ea08f7407bd9d0839d9885241c209c60 F src/util.c cd997077bad039efc0597eb027c929658f93c018 F src/vacuum.c 924bd1bcee2dfb05376f79845bd3b4cec7b54b2f -F src/vdbe.c 175a42d0f12b92093a7335402dbb46bfe7e360b0 +F src/vdbe.c 4784ded3d2c97f8084a17cacbeea490a0dccf75e F src/vdbe.h edef9c4f0be83e1f1dccd049da37b40e021b63d9 F src/vdbeInt.h b6748a8ac9be169d83585a0f5daf747863c6b8db -F src/vdbeapi.c e472b3e5985175e948e70025cb3bffa8a2e185c8 -F src/vdbeaux.c 051a1609e578418d1bfc6d2420b8eb412a7aea97 +F src/vdbeapi.c 7ef519083e3420bf7793d8b4eae2961d894d98ab +F src/vdbeaux.c b526e30d7a5d5b8b18408b2ec077e7286df2f6dc F src/vdbeblob.c c3ccb7c8732858c680f442932e66ad06bb036562 F src/vdbemem.c 0498796b6ffbe45e32960d6a1f5adfb6e419883b F src/vdbetrace.c 3ba13bc32bdf16d2bdea523245fd16736bed67b5 @@ -485,7 +485,7 @@ F test/fuzz2.test 207d0f9d06db3eaf47a6b7bfc835b8e2fc397167 F test/fuzz3.test aec64345184d1662bd30e6a17851ff659d596dc5 F test/fuzz_common.tcl a87dfbb88c2a6b08a38e9a070dabd129e617b45b F test/fuzz_malloc.test dd7001ac86d09c154a7dff064f4739c60e2b312c -F test/hook.test 29a0b6a18111835bdca827f62a7975a8e30a1dd5 +F test/hook.test 040cf2ca263f192c66b358e095138dad0a9d75bb F test/icu.test 70df4faca133254c042d02ae342c0a141f2663f4 F test/in.test 19b642bb134308980a92249750ea4ce3f6c75c2d F test/in2.test 5d4c61d17493c832f7d2d32bef785119e87bde75 @@ -929,7 +929,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 8180f2881fa970429e28d4f3258a56cfaabbcabd -R 7bdc0a7971e68baabbe152ea44f74530 +P d051694e024c590e4687cae1368f900799b7442d +R c057f780dc1cba178107219ab6b28dc8 U drh -Z a923e72061e5acce879b548f79bb9c49 +Z 598e11d1b0eff48f657d073c9eb1f2dc diff --git a/manifest.uuid b/manifest.uuid index 15b385f496..c3c451f694 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d051694e024c590e4687cae1368f900799b7442d \ No newline at end of file +6634521461e6acff7cc778590e62d57831f9230d \ No newline at end of file diff --git a/src/delete.c b/src/delete.c index 71a243d5a6..8a44d12247 100644 --- a/src/delete.c +++ b/src/delete.c @@ -344,7 +344,9 @@ void sqlite3DeleteFrom( && pWhere==0 && !pTrigger && !IsVirtual(pTab) +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK && db->xPreUpdateCallback==0 +#endif && 0==sqlite3FkRequired(pParse, pTab, 0, 0) ){ assert( !isView ); diff --git a/src/insert.c b/src/insert.c index cf48d0ffe7..364e68460f 100644 --- a/src/insert.c +++ b/src/insert.c @@ -1286,12 +1286,14 @@ void sqlite3GenerateConstraintChecks( pParse, pTab, baseCur, regRowid, 0, pTrigger, OE_Replace ); }else{ +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK /* This OP_Delete opcode fires the pre-update-hook only. It does ** not modify the b-tree. It is more efficient to let the coming ** OP_Insert replace the existing entry than it is to delete the ** existing entry and then insert a new one. */ sqlite3VdbeAddOp2(v, OP_Delete, baseCur, OPFLAG_ISNOOP); sqlite3VdbeChangeP4(v, -1, (char *)pTab, P4_TABLE); +#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ if( pTab->pIndex ){ sqlite3MultiWrite(pParse); sqlite3GenerateRowIndexDelete(pParse, pTab, baseCur, 0); diff --git a/src/main.c b/src/main.c index 9ccd657e79..21991c558f 100644 --- a/src/main.c +++ b/src/main.c @@ -1306,6 +1306,7 @@ void *sqlite3_rollback_hook( return pRet; } +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK /* ** Register a callback to be invoked each time a row is updated, ** inserted or deleted using this database connection. @@ -1324,6 +1325,7 @@ void *sqlite3_preupdate_hook( sqlite3_mutex_leave(db->mutex); return pRet; } +#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ #ifndef SQLITE_OMIT_WAL /* diff --git a/src/sqlite.h.in b/src/sqlite.h.in index c3dc70168f..3daf72cd36 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -6392,6 +6392,9 @@ int sqlite3_wal_checkpoint_v2( ** CAPI3REF: The pre-update hook. ** EXPERIMENTAL ** +** ^These interfaces are only available if SQLite is compiled using the +** [SQLITE_ENABLE_UPDATE_HOOK] compile-time option. +** ** ^The [sqlite3_preupdate_hook()] interface registers a callback function ** that is invoked prior to each [INSERT], [UPDATE], and [DELETE] operation. ** ^At most one preupdate hook may be registered at a time on a single diff --git a/src/sqliteInt.h b/src/sqliteInt.h index a15b8bff1c..d31ed4ae6f 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -829,11 +829,13 @@ struct sqlite3 { void (*xRollbackCallback)(void*); /* Invoked at every commit. */ void *pUpdateArg; void (*xUpdateCallback)(void*,int, const char*,const char*,sqlite_int64); +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK void *pPreUpdateArg; /* First argument to xPreUpdateCallback */ void (*xPreUpdateCallback)( /* Registered using sqlite3_preupdate_hook() */ void*,sqlite3*,int,char const*,char const*,sqlite3_int64,sqlite3_int64 ); PreUpdate *pPreUpdate; /* Context for active pre-update callback */ +#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ #ifndef SQLITE_OMIT_WAL int (*xWalCallback)(void *, sqlite3 *, const char *, int); void *pWalArg; diff --git a/src/tclsqlite.c b/src/tclsqlite.c index 93c5118372..de0e992bd4 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -653,6 +653,7 @@ static void DbUnlockNotify(void **apArg, int nArg){ } #endif +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK /* ** Pre-update hook callback. */ @@ -686,6 +687,7 @@ static void DbPreUpdateHandler( Tcl_EvalObjEx(pDb->interp, pCmd, TCL_EVAL_DIRECT); Tcl_DecrRefCount(pCmd); } +#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ static void DbUpdateHandler( void *p, @@ -1624,7 +1626,9 @@ static void DbHookCmd( } } +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK sqlite3_preupdate_hook(db, (pDb->pPreUpdateHook?DbPreUpdateHandler:0), pDb); +#endif sqlite3_update_hook(db, (pDb->pUpdateHook?DbUpdateHandler:0), pDb); sqlite3_rollback_hook(db, (pDb->pRollbackHook?DbRollbackHandler:0), pDb); sqlite3_wal_hook(db, (pDb->pWalHook?DbWalHandler:0), pDb); @@ -2851,6 +2855,10 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ ** $db preupdate_hook old INDEX */ case DB_PREUPDATE: { +#ifndef SQLITE_ENABLE_PREUPDATE_HOOK + Tcl_AppendResult(interp, "preupdate_hook was omitted at compile-time"); + rc = TCL_ERROR; +#else static const char *azSub[] = {"count", "depth", "hook", "new", "old", 0}; enum DbPreupdateSubCmd { PRE_COUNT, PRE_DEPTH, PRE_HOOK, PRE_NEW, PRE_OLD @@ -2920,7 +2928,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ } } } - +#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ break; } @@ -3720,7 +3728,7 @@ static void init_all(Tcl_Interp *interp){ extern int Sqlitemultiplex_Init(Tcl_Interp*); extern int SqliteSuperlock_Init(Tcl_Interp*); extern int SqlitetestSyscall_Init(Tcl_Interp*); -#ifdef SQLITE_ENABLE_SESSION +#if defined(SQLITE_ENABLE_SESSION) && defined(SQLITE_ENABLE_PREUPDATE_HOOK) extern int TestSession_Init(Tcl_Interp*); #endif #ifdef SQLITE_ENABLE_ZIPVFS @@ -3760,7 +3768,7 @@ static void init_all(Tcl_Interp *interp){ Sqlitemultiplex_Init(interp); SqliteSuperlock_Init(interp); SqlitetestSyscall_Init(interp); -#ifdef SQLITE_ENABLE_SESSION +#if defined(SQLITE_ENABLE_SESSION) && defined(SQLITE_ENABLE_PREUPDATE_HOOK) TestSession_Init(interp); #endif diff --git a/src/test_config.c b/src/test_config.c index 24ddbaa027..2bf7af5729 100644 --- a/src/test_config.c +++ b/src/test_config.c @@ -85,6 +85,12 @@ static void set_options(Tcl_Interp *interp){ Tcl_SetVar2(interp, "sqlite_options", "mem5", "0", TCL_GLOBAL_ONLY); #endif +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK + Tcl_SetVar2(interp, "sqlite_options", "preupdate", "1", TCL_GLOBAL_ONLY); +#else + Tcl_SetVar2(interp, "sqlite_options", "preupdate", "0", TCL_GLOBAL_ONLY); +#endif + #ifdef SQLITE_MUTEX_OMIT Tcl_SetVar2(interp, "sqlite_options", "mutex", "0", TCL_GLOBAL_ONLY); #else diff --git a/src/update.c b/src/update.c index fd310fb307..d702cba570 100644 --- a/src/update.c +++ b/src/update.c @@ -487,13 +487,13 @@ void sqlite3Update( /* Delete the index entries associated with the current record. */ j1 = sqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, regOldRowid); sqlite3GenerateRowIndexDelete(pParse, pTab, iCur, aRegIdx); - + /* If changing the rowid value, or if there are foreign key constraints ** to process, delete the old record. Otherwise, add a noop OP_Delete ** to invoke the pre-update hook. ** ** That (regNew==regnewRowid+1) is true is also important for the - ** pre-update hook. If hte caller invokes preupdate_new(), the returned + ** pre-update hook. If the caller invokes preupdate_new(), the returned ** value is copied from memory cell (regNewRowid+1+iCol), where iCol ** is the column index supplied by the user. */ diff --git a/src/vdbe.c b/src/vdbe.c index cd8c1ec69b..e85dc85f69 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -107,6 +107,16 @@ static void updateMaxBlobsize(Mem *p){ } #endif +/* +** This macro evaluates to true if either the update hook or the preupdate +** hook are enabled for database connect DB. +*/ +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK +# define HAS_UPDATE_HOOK(DB) ((DB)->xPreUpdateCallback||(DB)->xUpdateCallback) +#else +# define HAS_UPDATE_HOOK(DB) ((DB)->xUpdateCallback) +#endif + /* ** The next global variable is incremented each type the OP_Found opcode ** is executed. This is used to test whether or not the foreign key @@ -3890,7 +3900,7 @@ case OP_InsertInt: { iKey = pOp->p3; } - if( pOp->p4type==P4_TABLE && (db->xPreUpdateCallback||db->xUpdateCallback) ){ + if( pOp->p4type==P4_TABLE && HAS_UPDATE_HOOK(db) ){ assert( pC->isTable ); assert( pC->iDb>=0 ); zDb = db->aDb[pC->iDb].zName; @@ -3898,6 +3908,7 @@ case OP_InsertInt: { op = ((pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT); } +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK /* Invoke the pre-update hook, if any */ if( db->xPreUpdateCallback && pOp->p4type==P4_TABLE @@ -3905,6 +3916,7 @@ case OP_InsertInt: { ){ sqlite3VdbePreUpdateHook(p, pC, SQLITE_INSERT, zDb, pTab, iKey, pOp->p2); } +#endif if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++; if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = iKey; @@ -3991,7 +4003,7 @@ case OP_Delete: { /* If the update-hook or pre-update-hook will be invoked, set iKey to ** the rowid of the row being deleted. Set zDb and zTab as well. */ - if( pOp->p4.z && (db->xPreUpdateCallback || db->xUpdateCallback) ){ + if( pOp->p4.z && HAS_UPDATE_HOOK(db) ){ assert( pC->iDb>=0 ); assert( pC->isTable ); assert( pC->rowidIsValid ); /* lastRowid set by previous OP_NotFound */ @@ -4000,6 +4012,7 @@ case OP_Delete: { pTab = pOp->p4.pTab; } +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK /* Invoke the pre-update-hook if required. */ if( db->xPreUpdateCallback && pOp->p4.z ){ assert( !(opflags & OPFLAG_ISUPDATE) || (aMem[pOp->p3].flags & MEM_Int) ); @@ -4009,6 +4022,7 @@ case OP_Delete: { pOp->p3 ); } +#endif if( opflags & OPFLAG_ISNOOP ) break; diff --git a/src/vdbeapi.c b/src/vdbeapi.c index b485aa7483..8af16e9ee3 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -1327,6 +1327,7 @@ int sqlite3_stmt_status(sqlite3_stmt *pStmt, int op, int resetFlag){ return v; } +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK /* ** This function is called from within a pre-update callback to retrieve ** a field of the row currently being updated or deleted. @@ -1381,7 +1382,9 @@ int sqlite3_preupdate_old(sqlite3 *db, int iIdx, sqlite3_value **ppValue){ sqlite3Error(db, rc, 0); return sqlite3ApiExit(db, rc); } +#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK /* ** This function is called from within a pre-update callback to retrieve ** the number of columns in the row being updated, deleted or inserted. @@ -1390,7 +1393,9 @@ int sqlite3_preupdate_count(sqlite3 *db){ PreUpdate *p = db->pPreUpdate; return (p ? p->pCsr->nField : 0); } +#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK /* ** This function is designed to be called from within a pre-update callback ** only. It returns zero if the change that caused the callback was made @@ -1406,7 +1411,9 @@ int sqlite3_preupdate_depth(sqlite3 *db){ PreUpdate *p = db->pPreUpdate; return (p ? p->v->nFrame : 0); } +#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK /* ** This function is called from within a pre-update callback to retrieve ** a field of the row currently being updated or inserted. @@ -1481,3 +1488,4 @@ int sqlite3_preupdate_new(sqlite3 *db, int iIdx, sqlite3_value **ppValue){ sqlite3Error(db, rc, 0); return sqlite3ApiExit(db, rc); } +#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 839feb905b..6dab72c369 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -2812,7 +2812,7 @@ UnpackedRecord *sqlite3VdbeRecordUnpack( pMem->enc = pKeyInfo->enc; pMem->db = pKeyInfo->db; pMem->flags = 0; - pMem->zMalloc = pMem->z = 0; + pMem->zMalloc = 0; pMem->z = 0; d += sqlite3VdbeSerialGet(&aKey[d], serial_type, pMem); pMem++; @@ -3171,6 +3171,7 @@ void sqlite3VdbeSetVarmask(Vdbe *v, int iVar){ } } +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK /* ** Invoke the pre-update hook. If this is an UPDATE or DELETE pre-update call, ** then cursor passed as the second argument should point to the row about @@ -3228,3 +3229,4 @@ void sqlite3VdbePreUpdateHook( sqlite3DbFree(db, preupdate.aNew); } } +#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ diff --git a/test/hook.test b/test/hook.test index 5cceaf9abf..58a6fed8bf 100644 --- a/test/hook.test +++ b/test/hook.test @@ -365,6 +365,11 @@ unset ::hooks #---------------------------------------------------------------------------- # The following tests - hook-7.* - test the pre-update hook. # +ifcapable !preupdate { + finish_test + return +} +# # 7.1.1 - INSERT statement. # 7.1.2 - INSERT INTO ... SELECT statement. # 7.1.3 - REPLACE INTO ... (rowid conflict) From 5d8a298495a021026c32d79714a8630170edaaa6 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 1 Apr 2011 15:30:39 +0000 Subject: [PATCH 0043/1484] If the sessions module is being built as part of the amalgamation, do not try to include sqliteInt.h and vdbeInt.h. FossilOrigin-Name: f87bfe6e12093e5958b658a49d3766fb29562cbb --- ext/session/sqlite3session.c | 6 ++++-- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index 70acb76056..8c1b8f64a8 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -5,8 +5,10 @@ #include #include -#include "sqliteInt.h" -#include "vdbeInt.h" +#ifndef SQLITE_AMALGAMATION +# include "sqliteInt.h" +# include "vdbeInt.h" +#endif typedef struct SessionTable SessionTable; typedef struct SessionChange SessionChange; diff --git a/manifest b/manifest index dddc79360d..8e4d946b71 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sSQLITE_ENABLE_PREUPDATE_HOOK\scompile-time\soption. -D 2011-03-30T21:04:43.055 +C If\sthe\ssessions\smodule\sis\sbeing\sbuilt\sas\spart\sof\sthe\samalgamation,\sdo\snot\stry\sto\sinclude\ssqliteInt.h\sand\svdbeInt.h. +D 2011-04-01T15:30:39.770 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -105,7 +105,7 @@ F ext/session/session3.test bfa2376db7cbb2ac69496f84d93a8d81b13110d3 F ext/session/session4.test a6ed685da7a5293c5d6f99855bcf41dbc352ca84 F ext/session/session_common.tcl fb91560b6dbd086010df8b3a137a452f1ac21a28 F ext/session/sessionfault.test 2544a2e2ecad56e3c07a32c09799871d243c114c -F ext/session/sqlite3session.c eaf093c81f076301cfd04f794d047cf7beffd290 +F ext/session/sqlite3session.c 2b2936b5188776b33bba1263f93267f3ec9d0d84 F ext/session/sqlite3session.h f284bac51c12de0e0096fc986e61f5ae6b9e5be5 F ext/session/test_session.c 82e3fd7d94f485ea63bcfb15d636c95a01db97a9 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x @@ -929,7 +929,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P d051694e024c590e4687cae1368f900799b7442d -R c057f780dc1cba178107219ab6b28dc8 -U drh -Z 598e11d1b0eff48f657d073c9eb1f2dc +P 6634521461e6acff7cc778590e62d57831f9230d +R 7a473314ef2d0233cdf9f16418e4fb53 +U dan +Z 1c0b7044d6d9a7b111c49878de940801 diff --git a/manifest.uuid b/manifest.uuid index c3c451f694..7f5424aa62 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6634521461e6acff7cc778590e62d57831f9230d \ No newline at end of file +f87bfe6e12093e5958b658a49d3766fb29562cbb \ No newline at end of file From cfdbde214b222cfaf67296bc6b5fa9a9da6f2a81 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 6 Apr 2011 23:39:28 +0000 Subject: [PATCH 0044/1484] Fix VC++ compiler warnings. FossilOrigin-Name: 7b7c8d366c51e89aefc6efc9dcffe3f62c7e1d25 --- ext/session/sqlite3session.c | 42 ++++++++++++++++++------------------ manifest | 14 ++++++------ manifest.uuid | 2 +- src/vdbetrace.c | 2 +- 4 files changed, 30 insertions(+), 30 deletions(-) diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index 8c1b8f64a8..7b77e170e8 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -564,7 +564,7 @@ static int sessionTableInfo( assert( pazCol && pabPK ); - nThis = strlen(zThis); + nThis = sqlite3Strlen30(zThis); zPragma = sqlite3_mprintf("PRAGMA '%q'.table_info('%q')", zDb, zThis); if( !zPragma ) return SQLITE_NOMEM; @@ -778,8 +778,8 @@ static void xPreUpdate( sqlite3_int64 iKey2 /* New rowid value (for a rowid UPDATE) */ ){ sqlite3_session *pSession; - int nDb = strlen(zDb); - int nName = strlen(zDb); + int nDb = sqlite3Strlen30(zDb); + int nName = sqlite3Strlen30(zName); assert( sqlite3_mutex_held(db->mutex) ); @@ -825,7 +825,7 @@ int sqlite3session_create( ){ sqlite3_session *pNew; /* Newly allocated session object */ sqlite3_session *pOld; /* Session object already attached to db */ - int nDb = strlen(zDb); /* Length of zDb in bytes */ + int nDb = sqlite3Strlen30(zDb); /* Length of zDb in bytes */ /* Zero the output value in case an error occurs. */ *ppSession = 0; @@ -882,7 +882,7 @@ void sqlite3session_delete(sqlite3_session *pSession){ sqlite3_free(p); } } - sqlite3_free(pTab->azCol); + sqlite3_free((char*)pTab->azCol); /* cast works around VC++ bug */ sqlite3_free(pTab->apChange); sqlite3_free(pTab); } @@ -914,7 +914,7 @@ int sqlite3session_attach( /* First search for an existing entry. If one is found, this call is ** a no-op. Return early. */ - nName = strlen(zName); + nName = sqlite3Strlen30(zName); for(pTab=pSession->pTable; pTab; pTab=pTab->pNext){ if( 0==sqlite3_strnicmp(pTab->zName, zName, nName+1) ) break; } @@ -985,7 +985,7 @@ static void sessionAppendByte(SessionBuffer *p, u8 v, int *pRc){ ** If an OOM condition is encountered, set *pRc to SQLITE_NOMEM before ** returning. */ -static void sessionAppendVarint(SessionBuffer *p, sqlite3_int64 v, int *pRc){ +static void sessionAppendVarint(SessionBuffer *p, int v, int *pRc){ if( *pRc==SQLITE_OK && 0==sessionBufferGrow(p, 9, pRc) ){ p->nBuf += sessionVarintPut(&p->aBuf[p->nBuf], v); } @@ -1023,7 +1023,7 @@ static void sessionAppendStr( const char *zStr, int *pRc ){ - int nStr = strlen(zStr); + int nStr = sqlite3Strlen30(zStr); if( *pRc==SQLITE_OK && 0==sessionBufferGrow(p, nStr, pRc) ){ memcpy(&p->aBuf[p->nBuf], zStr, nStr); p->nBuf += nStr; @@ -1062,7 +1062,7 @@ static void sessionAppendIdent( const char *zStr, /* String to quote, escape and append */ int *pRc /* IN/OUT: Error code */ ){ - int nStr = strlen(zStr)*2 + 2 + 1; + int nStr = sqlite3Strlen30(zStr)*2 + 2 + 1; if( *pRc==SQLITE_OK && 0==sessionBufferGrow(p, nStr, pRc) ){ char *zOut = (char *)&p->aBuf[p->nBuf]; const char *zIn = zStr; @@ -1072,7 +1072,7 @@ static void sessionAppendIdent( *zOut++ = *(zIn++); } *zOut++ = '"'; - p->nBuf = ((u8 *)zOut - p->aBuf); + p->nBuf = (int)((u8 *)zOut - p->aBuf); } } @@ -1372,7 +1372,7 @@ int sqlite3session_changeset( sessionAppendByte(&buf, 'T', &rc); sessionAppendVarint(&buf, nCol, &rc); sessionAppendBlob(&buf, pTab->abPK, nCol, &rc); - sessionAppendBlob(&buf, (u8 *)zName, strlen(zName)+1, &rc); + sessionAppendBlob(&buf, (u8 *)zName, sqlite3Strlen30(zName)+1, &rc); /* Build and compile a statement to execute: */ if( rc==SQLITE_OK ){ @@ -1413,7 +1413,7 @@ int sqlite3session_changeset( if( buf.nBuf==nNoop ){ buf.nBuf = nRewind; } - sqlite3_free(azCol); + sqlite3_free((char*)azCol); /* cast works around VC++ bug */ } } @@ -1589,7 +1589,7 @@ int sqlite3changeset_next(sqlite3_changeset_iter *p){ p->abPK = (u8 *)aChange; aChange += p->nCol; p->zTab = (char *)aChange; - aChange += (strlen((char *)aChange) + 1); + aChange += (sqlite3Strlen30((char *)aChange) + 1); p->op = *(aChange++); p->bIndirect = *(aChange++); sqlite3_free(p->apValue); @@ -1796,7 +1796,7 @@ int sqlite3changeset_invert( */ int nByte = 1 + sessionVarintGet(&aIn[i+1], &nCol); nByte += nCol; - nByte += 1 + strlen((char *)&aIn[i+nByte]); + nByte += 1 + sqlite3Strlen30((char *)&aIn[i+nByte]); memcpy(&aOut[i], &aIn[i], nByte); i += nByte; break; @@ -1810,7 +1810,7 @@ int sqlite3changeset_invert( sessionReadRecord(&aEnd, nCol, 0); aOut[i] = (eType==SQLITE_DELETE ? SQLITE_INSERT : SQLITE_DELETE); aOut[i+1] = aIn[i+1]; - nByte = aEnd - &aIn[i+2]; + nByte = (int)(aEnd - &aIn[i+2]); memcpy(&aOut[i+2], &aIn[i+2], nByte); i += 2 + nByte; break; @@ -1822,9 +1822,9 @@ int sqlite3changeset_invert( u8 *aEnd = &aIn[i+2]; sessionReadRecord(&aEnd, nCol, 0); - nByte1 = aEnd - &aIn[i+2]; + nByte1 = (int)(aEnd - &aIn[i+2]); sessionReadRecord(&aEnd, nCol, 0); - nByte2 = aEnd - &aIn[i+2] - nByte1; + nByte2 = (int)(aEnd - &aIn[i+2]) - nByte1; aOut[i] = SQLITE_UPDATE; aOut[i+1] = aIn[i+1]; @@ -2416,7 +2416,7 @@ int sqlite3changeset_apply( sqlite3_changeset_iter *pIter; /* Iterator to skip through changeset */ int rc; /* Return code */ const char *zTab = 0; /* Name of current table */ - int nTab = 0; /* Result of strlen(zTab) */ + int nTab = 0; /* Result of sqlite3Strlen30(zTab) */ SessionApplyCtx sApply; /* changeset_apply() context object */ memset(&sApply, 0, sizeof(sApply)); @@ -2438,7 +2438,7 @@ int sqlite3changeset_apply( u8 *abPK; schemaMismatch = 0; - sqlite3_free(sApply.azCol); + sqlite3_free((char*)sApply.azCol); /* cast works around VC++ bug */ sqlite3_finalize(sApply.pDelete); sqlite3_finalize(sApply.pUpdate); sqlite3_finalize(sApply.pInsert); @@ -2479,7 +2479,7 @@ int sqlite3changeset_apply( ){ break; } - nTab = strlen(zTab); + nTab = sqlite3Strlen30(zTab); } /* If there is a schema mismatch on the current table, proceed to the @@ -2530,7 +2530,7 @@ int sqlite3changeset_apply( sqlite3_finalize(sApply.pDelete); sqlite3_finalize(sApply.pUpdate); sqlite3_finalize(sApply.pSelect); - sqlite3_free(sApply.azCol); + sqlite3_free((char*)sApply.azCol); /* cast works around VC++ bug */ sqlite3_mutex_leave(sqlite3_db_mutex(db)); return rc; } diff --git a/manifest b/manifest index a2bcb079d9..0b5de163b9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sin\sthe\slatest\schanges\sfrom\sthe\strunk. -D 2011-04-06T22:33:50.737 +C Fix\sVC++\scompiler\swarnings. +D 2011-04-06T23:39:28.224 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 7a4d9524721d40ef9ee26f93f9bd6a51dba106f2 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -105,7 +105,7 @@ F ext/session/session3.test bfa2376db7cbb2ac69496f84d93a8d81b13110d3 F ext/session/session4.test a6ed685da7a5293c5d6f99855bcf41dbc352ca84 F ext/session/session_common.tcl fb91560b6dbd086010df8b3a137a452f1ac21a28 F ext/session/sessionfault.test 2544a2e2ecad56e3c07a32c09799871d243c114c -F ext/session/sqlite3session.c 2b2936b5188776b33bba1263f93267f3ec9d0d84 +F ext/session/sqlite3session.c bc6fc77d70d4d9994598b1daf0a43d48965b2155 F ext/session/sqlite3session.h f284bac51c12de0e0096fc986e61f5ae6b9e5be5 F ext/session/test_session.c 82e3fd7d94f485ea63bcfb15d636c95a01db97a9 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x @@ -251,7 +251,7 @@ F src/vdbeapi.c 8051038f7674c708f4515ab189fc3ea929e09a4c F src/vdbeaux.c b0a2a184a25380f7eb9d07e9336034ec38d1b213 F src/vdbeblob.c c3ccb7c8732858c680f442932e66ad06bb036562 F src/vdbemem.c 0498796b6ffbe45e32960d6a1f5adfb6e419883b -F src/vdbetrace.c 3ba13bc32bdf16d2bdea523245fd16736bed67b5 +F src/vdbetrace.c 5d0dc3d5fd54878cc8d6d28eb41deb8d5885b114 F src/vtab.c b0abc931f95af94c9ffdf9f747eb191cda953123 F src/wal.c 7334009b396285b658a95a3b6bc6d2b016a1f794 F src/wal.h 7a5fbb00114b7f2cd40c7e1003d4c41ce9d26840 @@ -937,7 +937,7 @@ F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 45f20261720dcd73eb887f7e3df100723000418b 614de91a504d2231009a9de1305e31fce1b1c5a6 -R 502dde3bb5feee985b14f915e41e9858 +P 435b57dc2be7b071270a6cddece297758b8153aa +R 430b240dcc83276815f3990defb9cdf0 U drh -Z 9b010756d90228476ef26682d9d1164b +Z 063f7a6f50976dabf014f8516d936514 diff --git a/manifest.uuid b/manifest.uuid index 6bf7c439fb..e28e83255d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -435b57dc2be7b071270a6cddece297758b8153aa \ No newline at end of file +7b7c8d366c51e89aefc6efc9dcffe3f62c7e1d25 \ No newline at end of file diff --git a/src/vdbetrace.c b/src/vdbetrace.c index b422fa9eb1..de123b550f 100644 --- a/src/vdbetrace.c +++ b/src/vdbetrace.c @@ -85,7 +85,7 @@ char *sqlite3VdbeExpandSql( const char *zStart = zRawSql; while( *(zRawSql++)!='\n' && *zRawSql ); sqlite3StrAccumAppend(&out, "-- ", 3); - sqlite3StrAccumAppend(&out, zStart, zRawSql-zStart); + sqlite3StrAccumAppend(&out, zStart, (int)(zRawSql-zStart)); } }else{ while( zRawSql[0] ){ From 36828bd9bb6305485019912edc6a55a52bc5144e Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 6 Apr 2011 23:40:28 +0000 Subject: [PATCH 0045/1484] Add a missing "extern C" terminator to the end of sqlite3session.h. FossilOrigin-Name: 29090b695a95feaba1b74f9894997083a060263a --- ext/session/sqlite3session.h | 6 ++++++ manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/ext/session/sqlite3session.h b/ext/session/sqlite3session.h index bcb901667c..eb4e114e37 100644 --- a/ext/session/sqlite3session.h +++ b/ext/session/sqlite3session.h @@ -737,5 +737,11 @@ int sqlite3changeset_apply( #define SQLITE_CHANGESET_REPLACE 1 #define SQLITE_CHANGESET_ABORT 2 +/* +** Make sure we can call this stuff from C++. +*/ +#ifdef __cplusplus +} #endif +#endif /* SQLITE_ENABLE_SESSION && SQLITE_ENABLE_PREUPDATE_HOOK */ diff --git a/manifest b/manifest index 0b5de163b9..aaad18cb5b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sVC++\scompiler\swarnings. -D 2011-04-06T23:39:28.224 +C Add\sa\smissing\s"extern\sC"\sterminator\sto\sthe\send\sof\ssqlite3session.h. +D 2011-04-06T23:40:28.737 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 7a4d9524721d40ef9ee26f93f9bd6a51dba106f2 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -106,7 +106,7 @@ F ext/session/session4.test a6ed685da7a5293c5d6f99855bcf41dbc352ca84 F ext/session/session_common.tcl fb91560b6dbd086010df8b3a137a452f1ac21a28 F ext/session/sessionfault.test 2544a2e2ecad56e3c07a32c09799871d243c114c F ext/session/sqlite3session.c bc6fc77d70d4d9994598b1daf0a43d48965b2155 -F ext/session/sqlite3session.h f284bac51c12de0e0096fc986e61f5ae6b9e5be5 +F ext/session/sqlite3session.h 9b91addc5bd1777137d4f1c0252da9fbe2d4618e F ext/session/test_session.c 82e3fd7d94f485ea63bcfb15d636c95a01db97a9 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 @@ -937,7 +937,7 @@ F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 435b57dc2be7b071270a6cddece297758b8153aa -R 430b240dcc83276815f3990defb9cdf0 +P 7b7c8d366c51e89aefc6efc9dcffe3f62c7e1d25 +R 35a03a7ffb44f2b52e4ebaca11ffd944 U drh -Z 063f7a6f50976dabf014f8516d936514 +Z efe884ab8aaf8c7e1eec316d7a2437f1 diff --git a/manifest.uuid b/manifest.uuid index e28e83255d..cf1a04a1ea 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7b7c8d366c51e89aefc6efc9dcffe3f62c7e1d25 \ No newline at end of file +29090b695a95feaba1b74f9894997083a060263a \ No newline at end of file From 5d607a6e062a0b5f79b62091edd63967ea792edd Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 14 Apr 2011 11:16:21 +0000 Subject: [PATCH 0046/1484] Start adding the sqlite3changeset_concat() function to the session module. FossilOrigin-Name: 8927b2260b8d84f53776cb29e1d2fa41b6b0de0e --- ext/session/session5.test | 124 ++++++++ ext/session/sqlite3session.c | 539 +++++++++++++++++++++++++++++++---- ext/session/sqlite3session.h | 6 + ext/session/test_session.c | 36 +++ manifest | 19 +- manifest.uuid | 2 +- 6 files changed, 660 insertions(+), 66 deletions(-) create mode 100644 ext/session/session5.test diff --git a/ext/session/session5.test b/ext/session/session5.test new file mode 100644 index 0000000000..440a44c08b --- /dev/null +++ b/ext/session/session5.test @@ -0,0 +1,124 @@ +# 2011 April 13 +# +# 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 regression tests for the session module. +# Specifically, for the sqlite3changeset_concat() command. +# + +if {![info exists testdir]} { + set testdir [file join [file dirname [info script]] .. .. test] +} +source [file join [file dirname [info script]] session_common.tcl] +source $testdir/tester.tcl +ifcapable !session {finish_test; return} + +set testprefix session5 + +proc do_concat_test {tn sql1 sql2} { + sqlite3session S1 db main ; S1 attach * + sqlite3session S2 db main ; S2 attach * + + execsql $sql1 + set C1 [S1 changeset] + S1 delete + + sqlite3session S1 db main ; S1 attach * + + execsql $sql2 + set C2 [S1 changeset] + S1 delete + + set C3 [S2 changeset] + S2 delete + + set C4 [sqlite3changeset_concat $C1 $C2] + + set c3 [list] + set c4 [list] + sqlite3session_foreach c $C3 { lappend c3 $c } + sqlite3session_foreach c $C4 { lappend c4 $c } + set c3 [lsort $c3] + set c4 [lsort $c4] + + do_test $tn [list set {} $c4] $c3 +} + +do_execsql_test 1.0 { + CREATE TABLE t1(a PRIMARY KEY, b); +} + +do_concat_test 1.1.1 { + INSERT INTO t1 VALUES(1, 'one'); +} { + INSERT INTO t1 VALUES(2, 'two'); +} + +do_concat_test 1.1.2 { + UPDATE t1 SET b = 'five' WHERE a = 1; +} { + UPDATE t1 SET b = 'six' WHERE a = 2; +} + +do_concat_test 1.1.3 { + DELETE FROM t1 WHERE a = 1; +} { + DELETE FROM t1 WHERE a = 2; +} + + +# 1.2.1: INSERT + DELETE -> (none) +# 1.2.2: INSERT + UPDATE -> INSERT +# +# 1.2.3: DELETE + INSERT (matching data) -> (none) +# 1.2.4: DELETE + INSERT (non-matching data) -> UPDATE +# +# 1.2.5: UPDATE + UPDATE (matching data) -> (none) +# 1.2.6: UPDATE + UPDATE (non-matching data) -> UPDATE +# 1.2.7: UPDATE + DELETE -> DELETE +# +do_concat_test 1.2.1 { + INSERT INTO t1 VALUES('x', 'y'); +} { + DELETE FROM t1 WHERE a = 'x'; +} +do_concat_test 1.2.2 { + INSERT INTO t1 VALUES(5.0, 'five'); +} { + UPDATE t1 SET b = 'six' WHERE a = 5.0; +} + +do_execsql_test 1.2.3.1 "INSERT INTO t1 VALUES('I', 'one')" +do_concat_test 1.2.3.2 { + DELETE FROM t1 WHERE a = 'I'; +} { + INSERT INTO t1 VALUES('I', 'one'); +} +do_concat_test 1.2.4 { + DELETE FROM t1 WHERE a = 'I'; +} { + INSERT INTO t1 VALUES('I', 'two'); +} +do_concat_test 1.2.5 { + UPDATE t1 SET b = 'five' WHERE a = 'I'; +} { + UPDATE t1 SET b = 'two' WHERE a = 'I'; +} +do_concat_test 1.2.6 { + UPDATE t1 SET b = 'six' WHERE a = 'I'; +} { + UPDATE t1 SET b = 'seven' WHERE a = 'I'; +} +do_concat_test 1.2.7 { + UPDATE t1 SET b = 'eight' WHERE a = 'I'; +} { + DELETE FROM t1 WHERE a = 'I'; +} + +finish_test diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index 7b77e170e8..770fc13e30 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -126,6 +126,7 @@ struct SessionTable { ** Followed by one or more changes to the table. ** ** 1 byte: Either SQLITE_INSERT, UPDATE or DELETE. +** 1 byte: The "indirect-change" flag. ** old.* record: (delete and update only) ** new.* record: (insert and update only) */ @@ -353,20 +354,19 @@ static unsigned int sessionPreupdateHash( } /* -** Based on the primary key values stored in change pChange, calculate a +** Based on the primary key values stored in change aRecord, calculate a ** hash key, assuming the has table has nBucket buckets. The hash keys ** calculated by this function are compatible with those calculated by ** sessionPreupdateHash(). */ static unsigned int sessionChangeHash( - sqlite3 *db, /* Database handle */ SessionTable *pTab, /* Table handle */ - SessionChange *pChange, /* Change handle */ + u8 *aRecord, /* Change record */ int nBucket /* Assume this many buckets in hash table */ ){ unsigned int h = 0; /* Value to return */ int i; /* Used to iterate through columns */ - u8 *a = pChange->aRecord; /* Used to iterate through change record */ + u8 *a = aRecord; /* Used to iterate through change record */ for(i=0; inCol; i++){ int eType = *a++; @@ -393,6 +393,160 @@ static unsigned int sessionChangeHash( return (h % nBucket); } +static int sessionSerialLen(u8 *a){ + int e = *a; + int n; + if( e==0 ) return 1; + if( e==SQLITE_NULL ) return 1; + if( e==SQLITE_INTEGER || e==SQLITE_FLOAT ) return 9; + return sessionVarintGet(&a[1], &n) + 1 + n; +} + +static int sessionChangeEqual( + SessionTable *pTab, + u8 *aLeft, /* Change record */ + u8 *aRight /* Change record */ +){ + u8 *a1 = aLeft; + u8 *a2 = aRight; + int i; + + for(i=0; inCol; i++){ + int n1 = sessionSerialLen(a1); + int n2 = sessionSerialLen(a2); + + if( pTab->abPK[i] && (n1!=n2 || memcmp(a1, a2, n1)) ){ + return 0; + } + a1 += n1; + a2 += n1; + } + + return 1; +} + +static void sessionMergeRecord( + u8 **paOut, + SessionTable *pTab, + u8 *aLeft, + u8 *aRight +){ + u8 *a1 = aLeft; + u8 *a2 = aRight; + u8 *aOut = *paOut; + int i; + + for(i=0; inCol; i++){ + int n1 = sessionSerialLen(a1); + int n2 = sessionSerialLen(a2); + if( *a2 ){ + memcpy(aOut, a2, n2); + aOut += n2; + }else{ + memcpy(aOut, a1, n1); + aOut += n1; + } + a1 += n1; + a2 += n2; + } + + *paOut = aOut; +} + +static u8 *sessionMergeValue( + u8 **paOne, + u8 **paTwo, + int *pnVal +){ + u8 *a1 = *paOne; + u8 *a2 = *paTwo; + u8 *pRet = 0; + int n1; + + assert( a1 ); + if( a2 ){ + int n2 = sessionSerialLen(a2); + if( *a2 ){ + *pnVal = n2; + pRet = a2; + } + *paTwo = &a2[n2]; + } + + n1 = sessionSerialLen(a1); + if( pRet==0 ){ + *pnVal = n1; + pRet = a1; + } + *paOne = &a1[n1]; + + return pRet; +} + +static int sessionMergeUpdate( + u8 **paOut, + SessionTable *pTab, + u8 *aOldRecord1, + u8 *aOldRecord2, + u8 *aNewRecord1, + u8 *aNewRecord2 +){ + u8 *aOld1 = aOldRecord1; + u8 *aOld2 = aOldRecord2; + u8 *aNew1 = aNewRecord1; + u8 *aNew2 = aNewRecord2; + + u8 *aOut = *paOut; + int i; + int bRequired = 0; + + assert( aOldRecord1 && aNewRecord1 ); + + /* Write the old.* vector first. */ + for(i=0; inCol; i++){ + int nOld; + u8 *aOld; + int nNew; + u8 *aNew; + + aOld = sessionMergeValue(&aOld1, &aOld2, &nOld); + aNew = sessionMergeValue(&aNew1, &aNew2, &nNew); + if( pTab->abPK[i] || nOld!=nNew || memcmp(aOld, aNew, nNew) ){ + if( pTab->abPK[i]==0 ) bRequired = 1; + memcpy(aOut, aOld, nOld); + aOut += nOld; + }else{ + *(aOut++) = '\0'; + } + } + + if( !bRequired ) return 0; + + /* Write the new.* vector */ + aOld1 = aOldRecord1; + aOld2 = aOldRecord2; + aNew1 = aNewRecord1; + aNew2 = aNewRecord2; + for(i=0; inCol; i++){ + int nOld; + u8 *aOld; + int nNew; + u8 *aNew; + + aOld = sessionMergeValue(&aOld1, &aOld2, &nOld); + aNew = sessionMergeValue(&aNew1, &aNew2, &nNew); + if( pTab->abPK[i] || (nOld==nNew && 0==memcmp(aOld, aNew, nNew)) ){ + *(aOut++) = '\0'; + }else{ + memcpy(aOut, aNew, nNew); + aOut += nNew; + } + } + + *paOut = aOut; + return 1; +} + static int sessionPreupdateEqual( sqlite3 *db, SessionTable *pTab, @@ -480,7 +634,7 @@ static int sessionPreupdateEqual( ** Growing the hash table in this case is a performance optimization only, ** it is not required for correct operation. */ -static int sessionGrowHash(sqlite3_session *pSession, SessionTable *pTab){ +static int sessionGrowHash(SessionTable *pTab){ if( pTab->nChange==0 || pTab->nEntry>=(pTab->nChange/2) ){ int i; SessionChange **apNew; @@ -489,7 +643,6 @@ static int sessionGrowHash(sqlite3_session *pSession, SessionTable *pTab){ apNew = (SessionChange **)sqlite3_malloc(sizeof(SessionChange *) * nNew); if( apNew==0 ){ if( pTab->nChange==0 ){ - pSession->rc = SQLITE_NOMEM; return SQLITE_ERROR; } return SQLITE_OK; @@ -500,7 +653,7 @@ static int sessionGrowHash(sqlite3_session *pSession, SessionTable *pTab){ SessionChange *p; SessionChange *pNext; for(p=pTab->apChange[i]; p; p=pNext){ - int iHash = sessionChangeHash(pSession->db, pTab, p, nNew); + int iHash = sessionChangeHash(pTab, p->aRecord, nNew); pNext = p->pNext; p->pNext = apNew[iHash]; apNew[iHash] = p; @@ -677,7 +830,10 @@ static void sessionPreupdateOneChange( if( sessionInitTable(pSession, pTab) ) return; /* Grow the hash table if required */ - if( sessionGrowHash(pSession, pTab) ) return; + if( sessionGrowHash(pTab) ){ + pSession->rc = SQLITE_NOMEM; + return; + } /* Search the hash table for an existing entry for rowid=iKey2. If ** one is found, store a pointer to it in pChange and unlink it from @@ -693,8 +849,8 @@ static void sessionPreupdateOneChange( } if( pC==0 ){ /* Create a new change object containing all the old values (if - ** this is an SQLITE_UPDATE or SQLITE_DELETE), or just the PK - ** values (if this is an INSERT). */ + ** this is an SQLITE_UPDATE or SQLITE_DELETE), or just the PK + ** values (if this is an INSERT). */ SessionChange *pChange; /* New change object */ int nByte; /* Number of bytes to allocate */ int i; /* Used to iterate through columns */ @@ -851,6 +1007,27 @@ int sqlite3session_create( return SQLITE_OK; } +void sessionDeleteTable(SessionTable *pList){ + SessionTable *pNext; + SessionTable *pTab; + + for(pTab=pList; pTab; pTab=pNext){ + int i; + pNext = pTab->pNext; + for(i=0; inChange; i++){ + SessionChange *p; + SessionChange *pNext; + for(p=pTab->apChange[i]; p; p=pNext){ + pNext = p->pNext; + sqlite3_free(p); + } + } + sqlite3_free((char*)pTab->azCol); /* cast works around VC++ bug */ + sqlite3_free(pTab->apChange); + sqlite3_free(pTab); + } +} + /* ** Delete a session object previously allocated using sqlite3session_create(). */ @@ -870,22 +1047,7 @@ void sqlite3session_delete(sqlite3_session *pSession){ /* Delete all attached table objects. And the contents of their ** associated hash-tables. */ - while( pSession->pTable ){ - int i; - SessionTable *pTab = pSession->pTable; - pSession->pTable = pTab->pNext; - for(i=0; inChange; i++){ - SessionChange *p; - SessionChange *pNext; - for(p=pTab->apChange[i]; p; p=pNext){ - pNext = p->pNext; - sqlite3_free(p); - } - } - sqlite3_free((char*)pTab->azCol); /* cast works around VC++ bug */ - sqlite3_free(pTab->apChange); - sqlite3_free(pTab); - } + sessionDeleteTable(pSession->pTable); /* Free the session object itself. */ sqlite3_free(pSession); @@ -1322,6 +1484,18 @@ static int sessionSelectBind( return rc; } +static void sessionAppendTableHdr( + SessionBuffer *pBuf, + SessionTable *pTab, + int *pRc +){ + /* Write a table header */ + sessionAppendByte(pBuf, 'T', pRc); + sessionAppendVarint(pBuf, pTab->nCol, pRc); + sessionAppendBlob(pBuf, pTab->abPK, pTab->nCol, pRc); + sessionAppendBlob(pBuf, (u8 *)pTab->zName, strlen(pTab->zName)+1, pRc); +} + /* ** Obtain a changeset object containing all changes recorded by the ** session object passed as the first argument. @@ -1369,10 +1543,7 @@ int sqlite3session_changeset( } /* Write a table header */ - sessionAppendByte(&buf, 'T', &rc); - sessionAppendVarint(&buf, nCol, &rc); - sessionAppendBlob(&buf, pTab->abPK, nCol, &rc); - sessionAppendBlob(&buf, (u8 *)zName, sqlite3Strlen30(zName)+1, &rc); + sessionAppendTableHdr(&buf, pTab, &rc); /* Build and compile a statement to execute: */ if( rc==SQLITE_OK ){ @@ -1525,9 +1696,9 @@ static int sessionReadRecord( if( eType==SQLITE_TEXT || eType==SQLITE_BLOB ){ int nByte; - int enc = (eType==SQLITE_TEXT ? SQLITE_UTF8 : 0); aRec += sessionVarintGet(aRec, &nByte); if( apOut ){ + int enc = (eType==SQLITE_TEXT ? SQLITE_UTF8 : 0); sqlite3ValueSetStr(apOut[i], nByte, aRec, enc, SQLITE_STATIC); } aRec += nByte; @@ -1552,23 +1723,21 @@ static int sessionReadRecord( return SQLITE_OK; } -/* -** Advance an iterator created by sqlite3changeset_start() to the next -** change in the changeset. This function may return SQLITE_ROW, SQLITE_DONE -** or SQLITE_CORRUPT. -** -** This function may not be called on iterators passed to a conflict handler -** callback by changeset_apply(). -*/ -int sqlite3changeset_next(sqlite3_changeset_iter *p){ +static int sessionChangesetNext( + sqlite3_changeset_iter *p, + u8 **paRec, + int *pnRec +){ u8 *aChange; int i; u8 c; + assert( (paRec==0 && pnRec==0) || (paRec && pnRec) ); + /* If the iterator is in the error-state, return immediately. */ if( p->rc!=SQLITE_OK ) return p->rc; - /* Free the current contents of p->apValue[]. */ + /* Free the current contents of p->apValue[], if any. */ if( p->apValue ){ for(i=0; inCol*2; i++){ sqlite3ValueFree(p->apValue[i]); @@ -1582,47 +1751,64 @@ int sqlite3changeset_next(sqlite3_changeset_iter *p){ } aChange = p->pNext; - c = *(aChange++); - if( c=='T' ){ + if( aChange[0]=='T' ){ int nByte; /* Bytes to allocate for apValue */ + aChange++; aChange += sessionVarintGet(aChange, &p->nCol); p->abPK = (u8 *)aChange; aChange += p->nCol; p->zTab = (char *)aChange; aChange += (sqlite3Strlen30((char *)aChange) + 1); - p->op = *(aChange++); - p->bIndirect = *(aChange++); - sqlite3_free(p->apValue); - nByte = sizeof(sqlite3_value *) * p->nCol * 2; - p->apValue = (sqlite3_value **)sqlite3_malloc(nByte); - if( !p->apValue ){ - return (p->rc = SQLITE_NOMEM); + + if( paRec==0 ){ + sqlite3_free(p->apValue); + nByte = sizeof(sqlite3_value *) * p->nCol * 2; + p->apValue = (sqlite3_value **)sqlite3_malloc(nByte); + if( !p->apValue ){ + return (p->rc = SQLITE_NOMEM); + } + memset(p->apValue, 0, sizeof(sqlite3_value*)*p->nCol*2); } - memset(p->apValue, 0, sizeof(sqlite3_value*)*p->nCol*2); - }else{ - p->op = c; - p->bIndirect = *(aChange++); } + + p->op = *(aChange++); + p->bIndirect = *(aChange++); if( p->op!=SQLITE_UPDATE && p->op!=SQLITE_DELETE && p->op!=SQLITE_INSERT ){ return (p->rc = SQLITE_CORRUPT); } + if( paRec ){ *paRec = aChange; } + /* If this is an UPDATE or DELETE, read the old.* record. */ if( p->op!=SQLITE_INSERT ){ - p->rc = sessionReadRecord(&aChange, p->nCol, p->apValue); + p->rc = sessionReadRecord(&aChange, p->nCol, paRec?0:p->apValue); if( p->rc!=SQLITE_OK ) return p->rc; } /* If this is an INSERT or UPDATE, read the new.* record. */ if( p->op!=SQLITE_DELETE ){ - p->rc = sessionReadRecord(&aChange, p->nCol, &p->apValue[p->nCol]); + p->rc = sessionReadRecord(&aChange, p->nCol, paRec?0:&p->apValue[p->nCol]); if( p->rc!=SQLITE_OK ) return p->rc; } + if( pnRec ){ *pnRec = aChange - *paRec; } p->pNext = aChange; return SQLITE_ROW; } +/* +** Advance an iterator created by sqlite3changeset_start() to the next +** change in the changeset. This function may return SQLITE_ROW, SQLITE_DONE +** or SQLITE_CORRUPT. +** +** This function may not be called on iterators passed to a conflict handler +** callback by changeset_apply(). +*/ +int sqlite3changeset_next(sqlite3_changeset_iter *p){ + return sessionChangesetNext(p, 0, 0); + +} + /* ** The following function extracts information on the current change ** from a changeset iterator. They may only be called after changeset_next() @@ -2535,4 +2721,245 @@ int sqlite3changeset_apply( return rc; } +static int sessionChangeMerge( + SessionTable *pTab, + SessionChange *pExist, + int op2, + int bIndirect, + u8 *aRec, + int nRec, + SessionChange **ppNew +){ + SessionChange *pNew = 0; + + if( !pExist ){ + pNew = (SessionChange *)sqlite3_malloc(sizeof(SessionChange)); + if( !pNew ){ + return SQLITE_NOMEM; + } + memset(pNew, 0, sizeof(SessionChange)); + pNew->bInsert = op2; + pNew->bIndirect = bIndirect; + pNew->nRecord = nRec; + pNew->aRecord = aRec; + }else{ + int op1 = pExist->bInsert; + + /* + ** op1=INSERT, op2=INSERT -> Unsupported. Discard op2. + ** op1=INSERT, op2=UPDATE -> INSERT. + ** op1=INSERT, op2=DELETE -> (none) + ** + ** op1=UPDATE, op2=INSERT -> Unsupported. Discard op2. + ** op1=UPDATE, op2=UPDATE -> UPDATE. + ** op1=UPDATE, op2=DELETE -> DELETE. + ** + ** op1=DELETE, op2=INSERT -> UPDATE. + ** op1=DELETE, op2=UPDATE -> Unsupported. Discard op2. + ** op1=DELETE, op2=DELETE -> Unsupported. Discard op2. + */ + if( (op1==SQLITE_INSERT && op2==SQLITE_INSERT) + || (op1==SQLITE_UPDATE && op2==SQLITE_INSERT) + || (op1==SQLITE_DELETE && op2==SQLITE_UPDATE) + || (op1==SQLITE_DELETE && op2==SQLITE_DELETE) + ){ + pNew = pExist; + }else if( op1==SQLITE_INSERT && op2==SQLITE_DELETE ){ + sqlite3_free(pExist); + assert( pNew==0 ); + }else{ + int nByte; + u8 *aCsr; + + nByte = sizeof(SessionChange) + pExist->nRecord + nRec; + pNew = (SessionChange *)sqlite3_malloc(nByte); + if( !pNew ){ + return SQLITE_NOMEM; + } + memset(pNew, 0, sizeof(SessionChange)); + pNew->bIndirect = (bIndirect && pExist->bIndirect); + aCsr = pNew->aRecord = (u8 *)&pNew[1]; + + if( op1==SQLITE_INSERT && op2==SQLITE_UPDATE ){ + u8 *a1 = aRec; + pNew->bInsert = SQLITE_INSERT; + sessionReadRecord(&a1, pTab->nCol, 0); + sessionMergeRecord(&aCsr, pTab, pExist->aRecord, a1); + } + else if( op1==SQLITE_UPDATE && op2==SQLITE_UPDATE ){ + u8 *a1 = pExist->aRecord; + u8 *a2 = aRec; + sessionReadRecord(&a1, pTab->nCol, 0); + sessionReadRecord(&a2, pTab->nCol, 0); + pNew->bInsert = SQLITE_UPDATE; + if( 0==sessionMergeUpdate(&aCsr, pTab, aRec, pExist->aRecord, a1, a2) ){ + sqlite3_free(pNew); + pNew = 0; + } + } + else if( op1==SQLITE_UPDATE && op2==SQLITE_DELETE ){ + pNew->bInsert = SQLITE_DELETE; + sessionMergeRecord(&aCsr, pTab, aRec, pExist->aRecord); + } + else if( op1==SQLITE_DELETE && op2==SQLITE_INSERT ){ + pNew->bInsert = SQLITE_UPDATE; + if( 0==sessionMergeUpdate(&aCsr, pTab, pExist->aRecord, 0, aRec, 0) ){ + sqlite3_free(pNew); + pNew = 0; + } + } + + if( pNew ){ + pNew->nRecord = (aCsr - pNew->aRecord); + } + sqlite3_free(pExist); + } + } + + *ppNew = pNew; + return SQLITE_OK; +} + +int sessionConcatChangeset( + int nChangeset, + void *pChangeset, + SessionTable **ppTabList +){ + u8 *aRec; + int nRec; + sqlite3_changeset_iter *pIter; + int rc; + SessionTable *pTab = 0; + + rc = sqlite3changeset_start(&pIter, nChangeset, pChangeset); + if( rc!=SQLITE_OK ) return rc; + + while( SQLITE_ROW==sessionChangesetNext(pIter, &aRec, &nRec) ){ + const char *zNew; + int nCol; + int op; + int iHash; + int bIndirect; + SessionChange *pChange; + SessionChange *pExist = 0; + SessionChange **pp; + + assert( pIter->apValue==0 ); + sqlite3changeset_op(pIter, &zNew, &nCol, &op, &bIndirect); + + if( !pTab || zNew!=pTab->zName ){ + /* Search the list for a matching table */ + int nNew = strlen(zNew); + for(pTab = *ppTabList; pTab; pTab=pTab->pNext){ + if( 0==sqlite3_strnicmp(pTab->zName, zNew, nNew+1) ) break; + } + if( !pTab ){ + pTab = sqlite3_malloc(sizeof(SessionTable)); + if( !pTab ) break; + memset(pTab, 0, sizeof(SessionTable)); + pTab->pNext = *ppTabList; + *ppTabList = pTab; + } + pTab->zName = (char *)zNew; + pTab->nCol = nCol; + sqlite3changeset_pk(pIter, &pTab->abPK, 0); + } + + if( sessionGrowHash(pTab) ) break; + iHash = sessionChangeHash(pTab, aRec, pTab->nChange); + + /* Search for existing entry. If found, remove it from the hash table. + ** Code below may link it back in. + */ + for(pp=&pTab->apChange[iHash]; *pp; pp=&(*pp)->pNext){ + if( sessionChangeEqual(pTab, (*pp)->aRecord, aRec) ){ + pExist = *pp; + *pp = (*pp)->pNext; + pTab->nEntry--; + break; + } + } + + rc = sessionChangeMerge(pTab, pExist, op, bIndirect, aRec, nRec, &pChange); + if( rc ) break; + if( pChange ){ + pChange->pNext = pTab->apChange[iHash]; + pTab->apChange[iHash] = pChange; + pTab->nEntry++; + } + } + + if( rc==SQLITE_OK ){ + rc = sqlite3changeset_finalize(pIter); + }else{ + sqlite3changeset_finalize(pIter); + } + return rc; +} + + +/* +** 1. Iterate through the left-hand changeset. Add an entry to a table +** specific hash table for each change in the changeset. The hash table +** key is the PK of the row affected by the change. +** +** 2. Then interate through the right-hand changeset. Attempt to add an +** entry to a hash table for each component change. If a change already +** exists with the same PK values, combine the two into a single change. +** +** 3. Write an output changeset based on the contents of the hash table. +*/ +int sqlite3changeset_concat( + int nLeft, /* Number of bytes in lhs input */ + void *pLeft, /* Lhs input changeset */ + int nRight /* Number of bytes in rhs input */, + void *pRight, /* Rhs input changeset */ + int *pnOut, /* OUT: Number of bytes in output changeset */ + void **ppOut /* OUT: changeset (left right) */ +){ + SessionTable *pList = 0; /* List of SessionTable objects */ + int rc; /* Return code */ + + *pnOut = 0; + *ppOut = 0; + + rc = sessionConcatChangeset(nLeft, pLeft, &pList); + if( rc==SQLITE_OK ){ + rc = sessionConcatChangeset(nRight, pRight, &pList); + } + + /* Create the serialized output changeset based on the contents of the + ** hash tables attached to the SessionTable objects in list pList. + */ + if( rc==SQLITE_OK ){ + SessionTable *pTab; + SessionBuffer buf = {0, 0, 0}; + for(pTab=pList; pTab; pTab=pTab->pNext){ + int i; + if( pTab->nEntry==0 ) continue; + + sessionAppendTableHdr(&buf, pTab, &rc); + for(i=0; inChange; i++){ + SessionChange *p; + for(p=pTab->apChange[i]; p; p=p->pNext){ + sessionAppendByte(&buf, p->bInsert, &rc); + sessionAppendByte(&buf, p->bIndirect, &rc); + sessionAppendBlob(&buf, p->aRecord, p->nRecord, &rc); + } + } + } + + if( rc==SQLITE_OK ){ + *ppOut = buf.aBuf; + *pnOut = buf.nBuf; + }else{ + sqlite3_free(buf.aBuf); + } + } + + concat_out: + sessionDeleteTable(pList); + return rc; +} + #endif /* SQLITE_ENABLE_SESSION && SQLITE_ENABLE_PREUPDATE_HOOK */ diff --git a/ext/session/sqlite3session.h b/ext/session/sqlite3session.h index eb4e114e37..10a94b927b 100644 --- a/ext/session/sqlite3session.h +++ b/ext/session/sqlite3session.h @@ -522,6 +522,12 @@ int sqlite3changeset_invert( int *pnOut, void **ppOut /* OUT: Inverse of input */ ); +int sqlite3changeset_concat( + int nLeft, void *pLeft, /* Input changeset */ + int nRight, void *Right, /* Input changeset */ + int *pnOut, void **ppOut /* OUT: Inverse of input */ +); + /* ** CAPI3REF: Apply A Changeset To A Database ** diff --git a/ext/session/test_session.c b/ext/session/test_session.c index 6af1892150..05eb732d6d 100644 --- a/ext/session/test_session.c +++ b/ext/session/test_session.c @@ -410,6 +410,39 @@ static int test_sqlite3changeset_invert( return TCL_OK; } +/* +** sqlite3changeset_concat LEFT RIGHT +*/ +static int test_sqlite3changeset_concat( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + int rc; /* Return code from changeset_invert() */ + void *aLeft; /* Input changeset */ + int nLeft; /* Size of buffer aChangeset in bytes */ + void *aRight; /* Input changeset */ + int nRight; /* Size of buffer aChangeset in bytes */ + void *aOut; /* Output changeset */ + int nOut; /* Size of buffer aOut in bytes */ + + if( objc!=3 ){ + Tcl_WrongNumArgs(interp, 1, objv, "LEFT RIGHT"); + return TCL_ERROR; + } + aLeft = (void *)Tcl_GetByteArrayFromObj(objv[1], &nLeft); + aRight = (void *)Tcl_GetByteArrayFromObj(objv[2], &nRight); + + rc = sqlite3changeset_concat(nLeft, aLeft, nRight, aRight, &nOut, &aOut); + if( rc!=SQLITE_OK ){ + return test_session_error(interp, rc); + } + Tcl_SetObjResult(interp, Tcl_NewByteArrayObj((unsigned char *)aOut, nOut)); + sqlite3_free(aOut); + return TCL_OK; +} + /* ** sqlite3session_foreach VARNAME CHANGESET SCRIPT */ @@ -514,6 +547,9 @@ int TestSession_Init(Tcl_Interp *interp){ Tcl_CreateObjCommand( interp, "sqlite3changeset_invert", test_sqlite3changeset_invert, 0, 0 ); + Tcl_CreateObjCommand( + interp, "sqlite3changeset_concat", test_sqlite3changeset_concat, 0, 0 + ); Tcl_CreateObjCommand( interp, "sqlite3changeset_apply", test_sqlite3changeset_apply, 0, 0 ); diff --git a/manifest b/manifest index 336c603f40..4dcb9b0bb0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sthe\slatest\strunk\schanges\sinto\sthe\ssessions\sbranch. -D 2011-04-09T18:07:51.034 +C Start\sadding\sthe\ssqlite3changeset_concat()\sfunction\sto\sthe\ssession\smodule. +D 2011-04-14T11:16:21.630 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 7a4d9524721d40ef9ee26f93f9bd6a51dba106f2 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -103,11 +103,12 @@ F ext/session/session1.test 7a92a2a6f531aef1e9764ffb7f983fb8b315376d F ext/session/session2.test c3e5f78d5eb988e35cc2ba9ce3678f706283cfdb F ext/session/session3.test bfa2376db7cbb2ac69496f84d93a8d81b13110d3 F ext/session/session4.test a6ed685da7a5293c5d6f99855bcf41dbc352ca84 +F ext/session/session5.test ed5025c96693d406fb13bcf330d1a962dcb68c24 F ext/session/session_common.tcl fb91560b6dbd086010df8b3a137a452f1ac21a28 F ext/session/sessionfault.test 2544a2e2ecad56e3c07a32c09799871d243c114c -F ext/session/sqlite3session.c bc6fc77d70d4d9994598b1daf0a43d48965b2155 -F ext/session/sqlite3session.h 9b91addc5bd1777137d4f1c0252da9fbe2d4618e -F ext/session/test_session.c 82e3fd7d94f485ea63bcfb15d636c95a01db97a9 +F ext/session/sqlite3session.c 124ac6d43ac5820add2e736b25432c3f6b5a733a +F ext/session/sqlite3session.h dc7c85fd27fa3a9a17b34e0951ed36cdced1bc67 +F ext/session/test_session.c f4d1dca94db71ec2177ee61eab51e718e58476d7 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F main.mk f942406cb7df55d1aec40a88a7ae399b730cd94f @@ -937,7 +938,7 @@ F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 29090b695a95feaba1b74f9894997083a060263a 1c2f0f8477bcf251fe874a2cfae4d7a403cb88ff -R a40e5f171b5b8b5d469c7b8e3eba3790 -U drh -Z 7e220d1108384435c7d9af48b2056273 +P 83705e90a54bad462a5b7fbca70cc129998f871c +R 2d3308935368f3ab85a5bea7204d6f97 +U dan +Z 4aed6546b387a7c5d8dbcb80467675b2 diff --git a/manifest.uuid b/manifest.uuid index 1c2583a835..4733d7436b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -83705e90a54bad462a5b7fbca70cc129998f871c \ No newline at end of file +8927b2260b8d84f53776cb29e1d2fa41b6b0de0e \ No newline at end of file From 6cda207f5f00357b712d06bb2f89dd93312decbe Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 14 Apr 2011 18:01:41 +0000 Subject: [PATCH 0047/1484] Add further tests for the sqlite3changeset_concat() function. Also fixes. FossilOrigin-Name: 1fc3f15d88c160b45642b46d1d54c591af058ba2 --- ext/session/session5.test | 104 ++++++++++++++++++++++++++++------- ext/session/sqlite3session.c | 50 ++++++++++------- ext/session/sqlite3session.h | 9 ++- manifest | 16 +++--- manifest.uuid | 2 +- 5 files changed, 130 insertions(+), 51 deletions(-) diff --git a/ext/session/session5.test b/ext/session/session5.test index 440a44c08b..676b2c718f 100644 --- a/ext/session/session5.test +++ b/ext/session/session5.test @@ -21,33 +21,46 @@ ifcapable !session {finish_test; return} set testprefix session5 -proc do_concat_test {tn sql1 sql2} { - sqlite3session S1 db main ; S1 attach * - sqlite3session S2 db main ; S2 attach * +# Organization of tests: +# +# session5-1.*: Simple tests to check the concat() function produces +# correct results. +# +# session5-2.*: More complicated tests. +# +# session5-3.*: Schema mismatch errors. +# - execsql $sql1 - set C1 [S1 changeset] - S1 delete +proc changeset_to_list {c} { + set list [list] + sqlite3session_foreach elem $c { lappend list $elem } + lsort $list +} - sqlite3session S1 db main ; S1 attach * +proc do_concat_test {tn args} { - execsql $sql2 - set C2 [S1 changeset] - S1 delete + set subtest 0 + foreach sql $args { + incr subtest + sqlite3session S db main ; S attach * + execsql $sql - set C3 [S2 changeset] - S2 delete + set c [S changeset] + if {[info commands s_prev] != ""} { + set c_concat [sqlite3changeset_concat $c_prev $c] + set c_two [s_prev changeset] + s_prev delete - set C4 [sqlite3changeset_concat $C1 $C2] + set h_concat [changeset_to_list $c_concat] + set h_two [changeset_to_list $c_two] - set c3 [list] - set c4 [list] - sqlite3session_foreach c $C3 { lappend c3 $c } - sqlite3session_foreach c $C4 { lappend c4 $c } - set c3 [lsort $c3] - set c4 [lsort $c4] + do_test $tn.$subtest [list set {} $h_concat] $h_two + } + set c_prev $c + rename S s_prev + } - do_test $tn [list set {} $c4] $c3 + catch { s_prev delete } } do_execsql_test 1.0 { @@ -121,4 +134,55 @@ do_concat_test 1.2.7 { DELETE FROM t1 WHERE a = 'I'; } +db function indirect indirect +proc indirect {{x -1}} { + S indirect $x + s_prev indirect $x +} + +do_concat_test 2.1 { + CREATE TABLE abc(a, b, c PRIMARY KEY); + INSERT INTO abc VALUES(NULL, NULL, 1); + INSERT INTO abc VALUES('abcdefghijkl', NULL, 2); +} { + DELETE FROM abc WHERE c = 1; + UPDATE abc SET c = 1 WHERE c = 2; +} { + INSERT INTO abc VALUES('abcdefghijkl', NULL, 2); + INSERT INTO abc VALUES(1.0, 2.0, 3); +} { + UPDATE abc SET a = a-1; +} { + CREATE TABLE def(d, e, f, PRIMARY KEY(e, f)); + INSERT INTO def VALUES('x', randomblob(11000), 67); + INSERT INTO def SELECT d, e, f+1 FROM def; + INSERT INTO def SELECT d, e, f+2 FROM def; + INSERT INTO def SELECT d, e, f+4 FROM def; +} { + DELETE FROM def WHERE rowid>4; +} { + INSERT INTO def SELECT d, e, f+4 FROM def; +} { + INSERT INTO abc VALUES(22, 44, -1); +} { + UPDATE abc SET c=-2 WHERE c=-1; + UPDATE abc SET c=-3 WHERE c=-2; +} { + UPDATE abc SET c=-4 WHERE c=-3; +} { + UPDATE abc SET a=a+1 WHERE c=-3; + UPDATE abc SET a=a+1 WHERE c=-3; +} { + UPDATE abc SET a=a+1 WHERE c=-3; + UPDATE abc SET a=a+1 WHERE c=-3; +} { + INSERT INTO abc VALUES('one', 'two', 'three'); +} { + SELECT indirect(1); + UPDATE abc SET a='one point five' WHERE c = 'three'; +} { + SELECT indirect(0); + UPDATE abc SET a='one point six' WHERE c = 'three'; +} + finish_test diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index 770fc13e30..f22fafa5dc 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -353,6 +353,20 @@ static unsigned int sessionPreupdateHash( return SQLITE_OK; } +/* +** The buffer that the argument points to contains a serialized SQL value. +** Return the number of bytes of space occupied by the value (including +** the type byte). +*/ +static int sessionSerialLen(u8 *a){ + int e = *a; + int n; + if( e==0 ) return 1; + if( e==SQLITE_NULL ) return 1; + if( e==SQLITE_INTEGER || e==SQLITE_FLOAT ) return 9; + return sessionVarintGet(&a[1], &n) + 1 + n; +} + /* ** Based on the primary key values stored in change aRecord, calculate a ** hash key, assuming the has table has nBucket buckets. The hash keys @@ -369,7 +383,7 @@ static unsigned int sessionChangeHash( u8 *a = aRecord; /* Used to iterate through change record */ for(i=0; inCol; i++){ - int eType = *a++; + int eType = *a; int isPK = pTab->abPK[i]; /* It is not possible for eType to be SQLITE_NULL here. The session @@ -377,31 +391,29 @@ static unsigned int sessionChangeHash( ** primary key columns. */ assert( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT || eType==SQLITE_TEXT || eType==SQLITE_BLOB + || eType==SQLITE_NULL || eType==0 ); + assert( !isPK || (eType!=0 && eType!=SQLITE_NULL) ); - if( isPK ) h = HASH_APPEND(h, eType); - if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){ - if( isPK ) h = sessionHashAppendI64(h, sessionGetI64(a)); - a += 8; + if( isPK ){ + a++; + h = HASH_APPEND(h, eType); + if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){ + if( isPK ) h = sessionHashAppendI64(h, sessionGetI64(a)); + a += 8; + }else{ + int n; + a += sessionVarintGet(a, &n); + if( isPK ) h = sessionHashAppendBlob(h, n, a); + a += n; + } }else{ - int n; - a += sessionVarintGet(a, &n); - if( isPK ) h = sessionHashAppendBlob(h, n, a); - a += n; + a += sessionSerialLen(a); } } return (h % nBucket); } -static int sessionSerialLen(u8 *a){ - int e = *a; - int n; - if( e==0 ) return 1; - if( e==SQLITE_NULL ) return 1; - if( e==SQLITE_INTEGER || e==SQLITE_FLOAT ) return 9; - return sessionVarintGet(&a[1], &n) + 1 + n; -} - static int sessionChangeEqual( SessionTable *pTab, u8 *aLeft, /* Change record */ @@ -419,7 +431,7 @@ static int sessionChangeEqual( return 0; } a1 += n1; - a2 += n1; + a2 += n2; } return 1; diff --git a/ext/session/sqlite3session.h b/ext/session/sqlite3session.h index 10a94b927b..fcde98f842 100644 --- a/ext/session/sqlite3session.h +++ b/ext/session/sqlite3session.h @@ -522,10 +522,13 @@ int sqlite3changeset_invert( int *pnOut, void **ppOut /* OUT: Inverse of input */ ); +/* +** CAPI3REF: Combine Two Changeset Objects +*/ int sqlite3changeset_concat( - int nLeft, void *pLeft, /* Input changeset */ - int nRight, void *Right, /* Input changeset */ - int *pnOut, void **ppOut /* OUT: Inverse of input */ + int nLeft, void *pLeft, /* First input changeset */ + int nRight, void *Right, /* Second input changeset */ + int *pnOut, void **ppOut /* OUT: Output changeset */ ); /* diff --git a/manifest b/manifest index 4dcb9b0bb0..7b1c552c55 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Start\sadding\sthe\ssqlite3changeset_concat()\sfunction\sto\sthe\ssession\smodule. -D 2011-04-14T11:16:21.630 +C Add\sfurther\stests\sfor\sthe\ssqlite3changeset_concat()\sfunction.\sAlso\sfixes. +D 2011-04-14T18:01:41.789 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 7a4d9524721d40ef9ee26f93f9bd6a51dba106f2 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -103,11 +103,11 @@ F ext/session/session1.test 7a92a2a6f531aef1e9764ffb7f983fb8b315376d F ext/session/session2.test c3e5f78d5eb988e35cc2ba9ce3678f706283cfdb F ext/session/session3.test bfa2376db7cbb2ac69496f84d93a8d81b13110d3 F ext/session/session4.test a6ed685da7a5293c5d6f99855bcf41dbc352ca84 -F ext/session/session5.test ed5025c96693d406fb13bcf330d1a962dcb68c24 +F ext/session/session5.test 9dff891440dc3a424daea914b7e08e9f137272ed F ext/session/session_common.tcl fb91560b6dbd086010df8b3a137a452f1ac21a28 F ext/session/sessionfault.test 2544a2e2ecad56e3c07a32c09799871d243c114c -F ext/session/sqlite3session.c 124ac6d43ac5820add2e736b25432c3f6b5a733a -F ext/session/sqlite3session.h dc7c85fd27fa3a9a17b34e0951ed36cdced1bc67 +F ext/session/sqlite3session.c abf9846341847c5b81040683b143b511ee828f2e +F ext/session/sqlite3session.h e64876b299dcd1f8c9d043d59bfe14a94ee6b2ba F ext/session/test_session.c f4d1dca94db71ec2177ee61eab51e718e58476d7 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 @@ -938,7 +938,7 @@ F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 83705e90a54bad462a5b7fbca70cc129998f871c -R 2d3308935368f3ab85a5bea7204d6f97 +P 8927b2260b8d84f53776cb29e1d2fa41b6b0de0e +R f3f9539d9ce74ceea388d1aad2d1949b U dan -Z 4aed6546b387a7c5d8dbcb80467675b2 +Z 58678ea87adc6f0684f4c0fc5f0a6d31 diff --git a/manifest.uuid b/manifest.uuid index 4733d7436b..d6d4737a85 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8927b2260b8d84f53776cb29e1d2fa41b6b0de0e \ No newline at end of file +1fc3f15d88c160b45642b46d1d54c591af058ba2 \ No newline at end of file From 29e03e977c3acad3ad250c05c37e7a2e8ce11e54 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 15 Apr 2011 12:04:50 +0000 Subject: [PATCH 0048/1484] Add documentation for sqlite3changeset_concat() to sqlite3session.h. FossilOrigin-Name: ada9efa53a6ea55f89d237cfd530f1d180343e19 --- ext/session/sqlite3session.h | 80 ++++++++++++++++++++++++++++++++++-- manifest | 12 +++--- manifest.uuid | 2 +- 3 files changed, 83 insertions(+), 11 deletions(-) diff --git a/ext/session/sqlite3session.h b/ext/session/sqlite3session.h index fcde98f842..38164401f4 100644 --- a/ext/session/sqlite3session.h +++ b/ext/session/sqlite3session.h @@ -523,12 +523,84 @@ int sqlite3changeset_invert( ); /* -** CAPI3REF: Combine Two Changeset Objects +** CAPI3REF: Concatenate Two Changeset Objects +** +** This function is used to concatenate two changesets, A and B, into a +** single changeset. The result is a changeset equivalent to applying +** changeset A followed by changeset B. +** +** Rows are identified by the values in their PRIMARY KEY columns. A change +** in changeset A is considered to apply to the same row as a change in +** changeset B if the two rows have the same primary key. +** +** Changes to rows that appear only in changeset A or B are copied into the +** output changeset. Or, if both changeset A and B contain a change that +** applies to a single row, the output depends on the type of each change, +** as follows: +** +** +** +** +**
Change A Change B Output Change +**
INSERT INSERT +** Change A is copied into the output changeset. Change B is discarded. +** This case does not occur if changeset B is recorded immediately after +** changeset A. +**
INSERT UPDATE +** An INSERT change is copied into the output changeset. The values in +** the INSERT change are as if the row was inserted by change A and then +** updated according to change B. +**
INSERT DELETE +** No change at all is copied into the output changeset. +**
UPDATE INSERT +** Change A is copied into the output changeset. Change B is discarded. +** This case does not occur if changeset B is recorded immediately after +** changeset A. +**
UPDATE UPDATE +** A single UPDATE is copied into the output changeset. The accompanying +** values are as if the row was updated once by change A and then again +** by change B. +**
UPDATE DELETE +** A single DELETE is copied into the output changeset. +**
DELETE INSERT +** If one or more of the column values in the row inserted by change +** B differ from those in the row deleted by change A, an UPDATE +** change is added to the output changeset. Otherwise, if the inserted +** row is exactly the same as the deleted row, no change is added to +** the output changeset. +**
DELETE UPDATE +** Change A is copied into the output changeset. Change B is discarded. +** This case does not occur if changeset B is recorded immediately after +** changeset A. +**
DELETE DELETE +** Change A is copied into the output changeset. Change B is discarded. +** This case does not occur if changeset B is recorded immediately after +** changeset A. +**
+** +** If the two changesets contain changes to the same table, then the number +** of columns and the position of the primary key columns for the table must +** be the same in each changeset. If this is not the case, attempting to +** concatenate the two changesets together fails and this function returns +** SQLITE_SCHEMA. If either of the two input changesets appear to be corrupt, +** and the corruption is detected, SQLITE_CORRUPT is returned. Or, if an +** out-of-memory condition occurs during processing, this function returns +** SQLITE_NOMEM. +** +** If none of the above errors occur, SQLITE_OK is returned and *ppOut set +** to point to a buffer containing the output changeset. It is the +** responsibility of the caller to eventually call sqlite3_free() on *ppOut +** to release memory allocated for the buffer. *pnOut is set to the number +** of bytes in the output changeset. If an error does occur, both *ppOut and +** *pnOut are set to zero before returning. */ int sqlite3changeset_concat( - int nLeft, void *pLeft, /* First input changeset */ - int nRight, void *Right, /* Second input changeset */ - int *pnOut, void **ppOut /* OUT: Output changeset */ + int nA, /* Number of bytes in buffer pA */ + void *pA, /* Pointer to buffer containing changeset A */ + int nB, /* Number of bytes in buffer pB */ + void *pB, /* Pointer to buffer containing changeset B */ + int *pnOut, /* OUT: Number of bytes in output changeset */ + void **ppOut /* OUT: Buffer containing output changeset */ ); /* diff --git a/manifest b/manifest index 7b1c552c55..be42cd3f25 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sfurther\stests\sfor\sthe\ssqlite3changeset_concat()\sfunction.\sAlso\sfixes. -D 2011-04-14T18:01:41.789 +C Add\sdocumentation\sfor\ssqlite3changeset_concat()\sto\ssqlite3session.h. +D 2011-04-15T12:04:50.155 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 7a4d9524721d40ef9ee26f93f9bd6a51dba106f2 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -107,7 +107,7 @@ F ext/session/session5.test 9dff891440dc3a424daea914b7e08e9f137272ed F ext/session/session_common.tcl fb91560b6dbd086010df8b3a137a452f1ac21a28 F ext/session/sessionfault.test 2544a2e2ecad56e3c07a32c09799871d243c114c F ext/session/sqlite3session.c abf9846341847c5b81040683b143b511ee828f2e -F ext/session/sqlite3session.h e64876b299dcd1f8c9d043d59bfe14a94ee6b2ba +F ext/session/sqlite3session.h 665f5591562e3c71eb3d0da26f1a1efae26f7bcf F ext/session/test_session.c f4d1dca94db71ec2177ee61eab51e718e58476d7 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 @@ -938,7 +938,7 @@ F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 8927b2260b8d84f53776cb29e1d2fa41b6b0de0e -R f3f9539d9ce74ceea388d1aad2d1949b +P 1fc3f15d88c160b45642b46d1d54c591af058ba2 +R 5b10e49a76b6665385d53106c727e888 U dan -Z 58678ea87adc6f0684f4c0fc5f0a6d31 +Z 6bd794c4ce6596f42844ff8d0a6b8d50 diff --git a/manifest.uuid b/manifest.uuid index d6d4737a85..7b35dd9932 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1fc3f15d88c160b45642b46d1d54c591af058ba2 \ No newline at end of file +ada9efa53a6ea55f89d237cfd530f1d180343e19 \ No newline at end of file From f29123b5725a9b3a385045a4847788be2d88642c Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 15 Apr 2011 15:04:31 +0000 Subject: [PATCH 0049/1484] Have sqlite3changeset_concat() return SQLITE_SCHEMA if an attempt is made to concatenate changesets based on incompatible database schemas. FossilOrigin-Name: 343b64517d244b75097e38342dc273eb5a52915b --- ext/session/session5.test | 56 +++++++++++++++++++++++++++++++++++- ext/session/sqlite3session.c | 15 ++++++++-- manifest | 14 ++++----- manifest.uuid | 2 +- 4 files changed, 75 insertions(+), 12 deletions(-) diff --git a/ext/session/session5.test b/ext/session/session5.test index 676b2c718f..d2761b3218 100644 --- a/ext/session/session5.test +++ b/ext/session/session5.test @@ -63,6 +63,9 @@ proc do_concat_test {tn args} { catch { s_prev delete } } +#------------------------------------------------------------------------- +# Test cases session5-1.* - simple tests. +# do_execsql_test 1.0 { CREATE TABLE t1(a PRIMARY KEY, b); } @@ -134,12 +137,15 @@ do_concat_test 1.2.7 { DELETE FROM t1 WHERE a = 'I'; } + +#------------------------------------------------------------------------- +# Test cases session5-2.* - more complex tests. +# db function indirect indirect proc indirect {{x -1}} { S indirect $x s_prev indirect $x } - do_concat_test 2.1 { CREATE TABLE abc(a, b, c PRIMARY KEY); INSERT INTO abc VALUES(NULL, NULL, 1); @@ -185,4 +191,52 @@ do_concat_test 2.1 { UPDATE abc SET a='one point six' WHERE c = 'three'; } +#------------------------------------------------------------------------- +# Test that schema incompatibilities are detected correctly. +# +# session5-3.1: Incompatible number of columns. +# session5-3.2: Incompatible PK definition. +# +proc sql_to_changeset {sql} { + sqlite3session S db main + S attach * + execsql $sql + set c [S changeset] + S delete + return $c +} + +do_test 3.1 { + db close + forcedelete test.db + sqlite3 db test.db + + execsql { CREATE TABLE t1(a PRIMARY KEY, b) } + set c1 [sql_to_changeset { INSERT INTO t1 VALUES(1, 2) }] + execsql { + DROP TABLE t1; + CREATE TABLE t1(a PRIMARY KEY, b, c); + } + set c2 [sql_to_changeset { INSERT INTO t1 VALUES(2, 3, 4) }] + + list [catch { sqlite3changeset_concat $c1 $c2 } msg] $msg +} {1 SQLITE_SCHEMA} + +do_test 3.2 { + db close + forcedelete test.db + sqlite3 db test.db + + execsql { CREATE TABLE t1(a PRIMARY KEY, b) } + set c1 [sql_to_changeset { INSERT INTO t1 VALUES(1, 2) }] + execsql { + DROP TABLE t1; + CREATE TABLE t1(a, b PRIMARY KEY); + } + set c2 [sql_to_changeset { INSERT INTO t1 VALUES(2, 3) }] + + list [catch { sqlite3changeset_concat $c1 $c2 } msg] $msg +} {1 SQLITE_SCHEMA} + + finish_test diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index f22fafa5dc..b37b1b33f7 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -2862,19 +2862,28 @@ int sessionConcatChangeset( if( !pTab || zNew!=pTab->zName ){ /* Search the list for a matching table */ int nNew = strlen(zNew); + u8 *abPK; + + sqlite3changeset_pk(pIter, &abPK, 0); for(pTab = *ppTabList; pTab; pTab=pTab->pNext){ if( 0==sqlite3_strnicmp(pTab->zName, zNew, nNew+1) ) break; } if( !pTab ){ pTab = sqlite3_malloc(sizeof(SessionTable)); - if( !pTab ) break; + if( !pTab ){ + rc = SQLITE_NOMEM; + break; + } memset(pTab, 0, sizeof(SessionTable)); pTab->pNext = *ppTabList; + pTab->abPK = abPK; + pTab->nCol = nCol; *ppTabList = pTab; + }else if( pTab->nCol!=nCol || memcmp(pTab->abPK, abPK, nCol) ){ + rc = SQLITE_SCHEMA; + break; } pTab->zName = (char *)zNew; - pTab->nCol = nCol; - sqlite3changeset_pk(pIter, &pTab->abPK, 0); } if( sessionGrowHash(pTab) ) break; diff --git a/manifest b/manifest index be42cd3f25..8e07b45dbd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sdocumentation\sfor\ssqlite3changeset_concat()\sto\ssqlite3session.h. -D 2011-04-15T12:04:50.155 +C Have\ssqlite3changeset_concat()\sreturn\sSQLITE_SCHEMA\sif\san\sattempt\sis\smade\sto\sconcatenate\schangesets\sbased\son\sincompatible\sdatabase\sschemas. +D 2011-04-15T15:04:31.042 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 7a4d9524721d40ef9ee26f93f9bd6a51dba106f2 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -103,10 +103,10 @@ F ext/session/session1.test 7a92a2a6f531aef1e9764ffb7f983fb8b315376d F ext/session/session2.test c3e5f78d5eb988e35cc2ba9ce3678f706283cfdb F ext/session/session3.test bfa2376db7cbb2ac69496f84d93a8d81b13110d3 F ext/session/session4.test a6ed685da7a5293c5d6f99855bcf41dbc352ca84 -F ext/session/session5.test 9dff891440dc3a424daea914b7e08e9f137272ed +F ext/session/session5.test cbb011a1b2f487d2fe4b014fb6ae3a67e5f7f767 F ext/session/session_common.tcl fb91560b6dbd086010df8b3a137a452f1ac21a28 F ext/session/sessionfault.test 2544a2e2ecad56e3c07a32c09799871d243c114c -F ext/session/sqlite3session.c abf9846341847c5b81040683b143b511ee828f2e +F ext/session/sqlite3session.c b5293510224e42c50d69a509e6bfaca45defec76 F ext/session/sqlite3session.h 665f5591562e3c71eb3d0da26f1a1efae26f7bcf F ext/session/test_session.c f4d1dca94db71ec2177ee61eab51e718e58476d7 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x @@ -938,7 +938,7 @@ F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 1fc3f15d88c160b45642b46d1d54c591af058ba2 -R 5b10e49a76b6665385d53106c727e888 +P ada9efa53a6ea55f89d237cfd530f1d180343e19 +R bdb9eba45cd97b77f78325d72d96c5f4 U dan -Z 6bd794c4ce6596f42844ff8d0a6b8d50 +Z 570068f4f013ca36918b632f2a36093d diff --git a/manifest.uuid b/manifest.uuid index 7b35dd9932..6943cc86d4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ada9efa53a6ea55f89d237cfd530f1d180343e19 \ No newline at end of file +343b64517d244b75097e38342dc273eb5a52915b \ No newline at end of file From 1756ae10e16dd7a7892d9f4be98fef51b7193183 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 15 Apr 2011 16:03:32 +0000 Subject: [PATCH 0050/1484] Add tests and fixes for OOM handling in sqlite3changeset_concat(). FossilOrigin-Name: df0b2d21dcd81679e55b24866f97568019932983 --- ext/session/session5.test | 41 ++++++++++++++++++-------------- ext/session/session_common.tcl | 6 ++++- ext/session/sessionfault.test | 43 ++++++++++++++++++++++++++++++++++ ext/session/sqlite3session.c | 6 ++++- manifest | 18 +++++++------- manifest.uuid | 2 +- 6 files changed, 86 insertions(+), 30 deletions(-) diff --git a/ext/session/session5.test b/ext/session/session5.test index d2761b3218..9cce67dcc1 100644 --- a/ext/session/session5.test +++ b/ext/session/session5.test @@ -31,12 +31,6 @@ set testprefix session5 # session5-3.*: Schema mismatch errors. # -proc changeset_to_list {c} { - set list [list] - sqlite3session_foreach elem $c { lappend list $elem } - lsort $list -} - proc do_concat_test {tn args} { set subtest 0 @@ -191,20 +185,31 @@ do_concat_test 2.1 { UPDATE abc SET a='one point six' WHERE c = 'three'; } +catch {db close} +forcedelete test.db +sqlite3 db test.db +do_concat_test 2.2 { + CREATE TABLE t1(a, b, PRIMARY KEY(b)); + CREATE TABLE t2(a PRIMARY KEY, b); + INSERT INTO t1 VALUES('string', 1); + INSERT INTO t1 VALUES(4, 2); + INSERT INTO t1 VALUES(X'FFAAFFAAFFAA', 3); +} { + INSERT INTO t2 VALUES('one', 'two'); + INSERT INTO t2 VALUES(1, NULL); + UPDATE t1 SET a = 5 WHERE a = 2; +} { + DELETE FROM t2 WHERE a = 1; + UPDATE t1 SET a = 4 WHERE a = 2; + INSERT INTO t2 VALUES('x', 'y'); +} + #------------------------------------------------------------------------- # Test that schema incompatibilities are detected correctly. # # session5-3.1: Incompatible number of columns. # session5-3.2: Incompatible PK definition. # -proc sql_to_changeset {sql} { - sqlite3session S db main - S attach * - execsql $sql - set c [S changeset] - S delete - return $c -} do_test 3.1 { db close @@ -212,12 +217,12 @@ do_test 3.1 { sqlite3 db test.db execsql { CREATE TABLE t1(a PRIMARY KEY, b) } - set c1 [sql_to_changeset { INSERT INTO t1 VALUES(1, 2) }] + set c1 [changeset_from_sql { INSERT INTO t1 VALUES(1, 2) }] execsql { DROP TABLE t1; CREATE TABLE t1(a PRIMARY KEY, b, c); } - set c2 [sql_to_changeset { INSERT INTO t1 VALUES(2, 3, 4) }] + set c2 [changeset_from_sql { INSERT INTO t1 VALUES(2, 3, 4) }] list [catch { sqlite3changeset_concat $c1 $c2 } msg] $msg } {1 SQLITE_SCHEMA} @@ -228,12 +233,12 @@ do_test 3.2 { sqlite3 db test.db execsql { CREATE TABLE t1(a PRIMARY KEY, b) } - set c1 [sql_to_changeset { INSERT INTO t1 VALUES(1, 2) }] + set c1 [changeset_from_sql { INSERT INTO t1 VALUES(1, 2) }] execsql { DROP TABLE t1; CREATE TABLE t1(a, b PRIMARY KEY); } - set c2 [sql_to_changeset { INSERT INTO t1 VALUES(2, 3) }] + set c2 [changeset_from_sql { INSERT INTO t1 VALUES(2, 3) }] list [catch { sqlite3changeset_concat $c1 $c2 } msg] $msg } {1 SQLITE_SCHEMA} diff --git a/ext/session/session_common.tcl b/ext/session/session_common.tcl index d5c74fba5c..53870c4027 100644 --- a/ext/session/session_common.tcl +++ b/ext/session/session_common.tcl @@ -128,5 +128,9 @@ proc compare_db {db1 db2} { return "" } - +proc changeset_to_list {c} { + set list [list] + sqlite3session_foreach elem $c { lappend list $elem } + lsort $list +} diff --git a/ext/session/sessionfault.test b/ext/session/sessionfault.test index cf155f4f3d..c21d72fb81 100644 --- a/ext/session/sessionfault.test +++ b/ext/session/sessionfault.test @@ -251,4 +251,47 @@ do_faultsim_test 5 -faults oom* -body { } } +#------------------------------------------------------------------------- +# Test that OOM errors in sqlite3changeset_concat() are handled correctly. +# +catch {db close} +forcedelete test.db +sqlite3 db test.db +do_execsql_test 5.prep1 { + CREATE TABLE t1(a, b, PRIMARY KEY(b)); + CREATE TABLE t2(a PRIMARY KEY, b); + INSERT INTO t1 VALUES('string', 1); + INSERT INTO t1 VALUES(4, 2); + INSERT INTO t1 VALUES(X'FFAAFFAAFFAA', 3); +} + +do_test 5.prep2 { + sqlite3session M db main + M attach * + set ::c2 [changeset_from_sql { + INSERT INTO t2 VALUES(randomblob(1000), randomblob(1000)); + INSERT INTO t2 VALUES('one', 'two'); + INSERT INTO t2 VALUES(1, NULL); + UPDATE t1 SET a = 5 WHERE a = 2; + }] + set ::c1 [changeset_from_sql { + DELETE FROM t2 WHERE a = 1; + UPDATE t1 SET a = 4 WHERE a = 2; + INSERT INTO t2 VALUES('x', 'y'); + }] + set ::total [changeset_to_list [M changeset]] + M delete +} {} + +do_faultsim_test 6 -faults oom-* -body { + set ::result [sqlite3changeset_concat $::c1 $::c2] + set {} {} +} -test { + faultsim_test_result {0 {}} {1 SQLITE_NOMEM} + if {$testrc==0} { + set v [changeset_to_list $::result] + if {$v != $::total} { error "result no good" } + } +} + finish_test diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index b37b1b33f7..41665ce9e9 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -2786,6 +2786,7 @@ static int sessionChangeMerge( nByte = sizeof(SessionChange) + pExist->nRecord + nRec; pNew = (SessionChange *)sqlite3_malloc(nByte); if( !pNew ){ + sqlite3_free(pExist); return SQLITE_NOMEM; } memset(pNew, 0, sizeof(SessionChange)); @@ -2886,7 +2887,10 @@ int sessionConcatChangeset( pTab->zName = (char *)zNew; } - if( sessionGrowHash(pTab) ) break; + if( sessionGrowHash(pTab) ){ + rc = SQLITE_NOMEM; + break; + } iHash = sessionChangeHash(pTab, aRec, pTab->nChange); /* Search for existing entry. If found, remove it from the hash table. diff --git a/manifest b/manifest index 8e07b45dbd..b165b9433c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Have\ssqlite3changeset_concat()\sreturn\sSQLITE_SCHEMA\sif\san\sattempt\sis\smade\sto\sconcatenate\schangesets\sbased\son\sincompatible\sdatabase\sschemas. -D 2011-04-15T15:04:31.042 +C Add\stests\sand\sfixes\sfor\sOOM\shandling\sin\ssqlite3changeset_concat(). +D 2011-04-15T16:03:32.057 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 7a4d9524721d40ef9ee26f93f9bd6a51dba106f2 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -103,10 +103,10 @@ F ext/session/session1.test 7a92a2a6f531aef1e9764ffb7f983fb8b315376d F ext/session/session2.test c3e5f78d5eb988e35cc2ba9ce3678f706283cfdb F ext/session/session3.test bfa2376db7cbb2ac69496f84d93a8d81b13110d3 F ext/session/session4.test a6ed685da7a5293c5d6f99855bcf41dbc352ca84 -F ext/session/session5.test cbb011a1b2f487d2fe4b014fb6ae3a67e5f7f767 -F ext/session/session_common.tcl fb91560b6dbd086010df8b3a137a452f1ac21a28 -F ext/session/sessionfault.test 2544a2e2ecad56e3c07a32c09799871d243c114c -F ext/session/sqlite3session.c b5293510224e42c50d69a509e6bfaca45defec76 +F ext/session/session5.test 940d77c748808769cac50fb62bb674aa84e472f2 +F ext/session/session_common.tcl 1539d8973b2aea0025c133eb0cc4c89fcef541a5 +F ext/session/sessionfault.test 2766cd620f1793f0e54f1e3859a184bcea55bad4 +F ext/session/sqlite3session.c 08573805932a9db4158f36663e01747d0ff69342 F ext/session/sqlite3session.h 665f5591562e3c71eb3d0da26f1a1efae26f7bcf F ext/session/test_session.c f4d1dca94db71ec2177ee61eab51e718e58476d7 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x @@ -938,7 +938,7 @@ F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P ada9efa53a6ea55f89d237cfd530f1d180343e19 -R bdb9eba45cd97b77f78325d72d96c5f4 +P 343b64517d244b75097e38342dc273eb5a52915b +R c818789c65113df118a04c3a29f3e5ba U dan -Z 570068f4f013ca36918b632f2a36093d +Z 7081c2709375635b8446c7ef8a86300e diff --git a/manifest.uuid b/manifest.uuid index 6943cc86d4..72289d19b5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -343b64517d244b75097e38342dc273eb5a52915b \ No newline at end of file +df0b2d21dcd81679e55b24866f97568019932983 \ No newline at end of file From b08a1efae52f0252fcde355fffaad4aa4cf3cdfd Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 15 Apr 2011 19:18:57 +0000 Subject: [PATCH 0051/1484] Improve coverage of session module. FossilOrigin-Name: 3dfd1d63bddfa9bd9018eb00bee1d496379630b5 --- ext/session/session5.test | 51 ++++++++++++++++++++++++++++++++++++ ext/session/sqlite3session.c | 29 +++++++++++--------- manifest | 14 +++++----- manifest.uuid | 2 +- 4 files changed, 76 insertions(+), 20 deletions(-) diff --git a/ext/session/session5.test b/ext/session/session5.test index 9cce67dcc1..1e67e1d325 100644 --- a/ext/session/session5.test +++ b/ext/session/session5.test @@ -183,6 +183,13 @@ do_concat_test 2.1 { } { SELECT indirect(0); UPDATE abc SET a='one point six' WHERE c = 'three'; +} { + CREATE TABLE x1(a, b, PRIMARY KEY(a)); + SELECT indirect(1); + INSERT INTO x1 VALUES(1, 2); +} { + SELECT indirect(1); + UPDATE x1 SET b = 3 WHERE a = 1; } catch {db close} @@ -204,6 +211,50 @@ do_concat_test 2.2 { INSERT INTO t2 VALUES('x', 'y'); } +do_test 2.3.0 { + catch {db close} + forcedelete test.db + sqlite3 db test.db + + set sql1 "" + set sql2 "" + for {set i 1} {$i < 120} {incr i} { + append sql1 "INSERT INTO x1 VALUES($i*4, $i);" + } + for {set i 1} {$i < 120} {incr i} { + append sql2 "DELETE FROM x1 WHERE a = $i*4;" + } + + set {} {} +} {} +do_concat_test 2.3 { + CREATE TABLE x1(a PRIMARY KEY, b) +} $sql1 $sql2 $sql1 $sql2 + +do_concat_test 2.4 { + CREATE TABLE x2(a PRIMARY KEY, b); + CREATE TABLE x3(a PRIMARY KEY, b); + + INSERT INTO x2 VALUES('a', 'b'); + INSERT INTO x2 VALUES('x', 'y'); + INSERT INTO x3 VALUES('a', 'b'); +} { + INSERT INTO x2 VALUES('c', 'd'); + INSERT INTO x3 VALUES('e', 'f'); + INSERT INTO x3 VALUES('x', 'y'); +} + +do_concat_test 2.5 { + UPDATE x3 SET b = 'Y' WHERE a = 'x' +} { + DELETE FROM x3 WHERE a = 'x' +} { + DELETE FROM x2 WHERE a = 'a' +} { + INSERT INTO x2 VALUES('a', 'B'); +} + + #------------------------------------------------------------------------- # Test that schema incompatibilities are detected correctly. # diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index 41665ce9e9..bad6240a1f 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -2793,13 +2793,21 @@ static int sessionChangeMerge( pNew->bIndirect = (bIndirect && pExist->bIndirect); aCsr = pNew->aRecord = (u8 *)&pNew[1]; - if( op1==SQLITE_INSERT && op2==SQLITE_UPDATE ){ + if( op1==SQLITE_INSERT ){ /* INSERT + UPDATE */ u8 *a1 = aRec; + assert( op2==SQLITE_UPDATE ); pNew->bInsert = SQLITE_INSERT; sessionReadRecord(&a1, pTab->nCol, 0); sessionMergeRecord(&aCsr, pTab, pExist->aRecord, a1); - } - else if( op1==SQLITE_UPDATE && op2==SQLITE_UPDATE ){ + }else if( op1==SQLITE_DELETE ){ /* DELETE + INSERT */ + assert( op2==SQLITE_INSERT ); + pNew->bInsert = SQLITE_UPDATE; + if( 0==sessionMergeUpdate(&aCsr, pTab, pExist->aRecord, 0, aRec, 0) ){ + sqlite3_free(pNew); + pNew = 0; + } + }else if( op2==SQLITE_UPDATE ){ /* UPDATE + UPDATE */ + assert( op1==SQLITE_UPDATE ); u8 *a1 = pExist->aRecord; u8 *a2 = aRec; sessionReadRecord(&a1, pTab->nCol, 0); @@ -2809,18 +2817,11 @@ static int sessionChangeMerge( sqlite3_free(pNew); pNew = 0; } - } - else if( op1==SQLITE_UPDATE && op2==SQLITE_DELETE ){ + }else{ /* UPDATE + DELETE */ + assert( op1==SQLITE_UPDATE && op2==SQLITE_DELETE ); pNew->bInsert = SQLITE_DELETE; sessionMergeRecord(&aCsr, pTab, aRec, pExist->aRecord); } - else if( op1==SQLITE_DELETE && op2==SQLITE_INSERT ){ - pNew->bInsert = SQLITE_UPDATE; - if( 0==sessionMergeUpdate(&aCsr, pTab, pExist->aRecord, 0, aRec, 0) ){ - sqlite3_free(pNew); - pNew = 0; - } - } if( pNew ){ pNew->nRecord = (aCsr - pNew->aRecord); @@ -2860,6 +2861,10 @@ int sessionConcatChangeset( assert( pIter->apValue==0 ); sqlite3changeset_op(pIter, &zNew, &nCol, &op, &bIndirect); + assert( zNew>=(char *)pChangeset && zNew-nChangeset<((char *)pChangeset) ); + assert( !pTab || pTab->zName-nChangeset<(char *)pChangeset ); + assert( !pTab || zNew>=pTab->zName ); + if( !pTab || zNew!=pTab->zName ){ /* Search the list for a matching table */ int nNew = strlen(zNew); diff --git a/manifest b/manifest index b165b9433c..bc49322d17 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\stests\sand\sfixes\sfor\sOOM\shandling\sin\ssqlite3changeset_concat(). -D 2011-04-15T16:03:32.057 +C Improve\scoverage\sof\ssession\smodule. +D 2011-04-15T19:18:57.799 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 7a4d9524721d40ef9ee26f93f9bd6a51dba106f2 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -103,10 +103,10 @@ F ext/session/session1.test 7a92a2a6f531aef1e9764ffb7f983fb8b315376d F ext/session/session2.test c3e5f78d5eb988e35cc2ba9ce3678f706283cfdb F ext/session/session3.test bfa2376db7cbb2ac69496f84d93a8d81b13110d3 F ext/session/session4.test a6ed685da7a5293c5d6f99855bcf41dbc352ca84 -F ext/session/session5.test 940d77c748808769cac50fb62bb674aa84e472f2 +F ext/session/session5.test 525503799d56124a31bedbd7895c1e668d18420d F ext/session/session_common.tcl 1539d8973b2aea0025c133eb0cc4c89fcef541a5 F ext/session/sessionfault.test 2766cd620f1793f0e54f1e3859a184bcea55bad4 -F ext/session/sqlite3session.c 08573805932a9db4158f36663e01747d0ff69342 +F ext/session/sqlite3session.c 4c44da92750d4b31bcbed25428be7167cddccf84 F ext/session/sqlite3session.h 665f5591562e3c71eb3d0da26f1a1efae26f7bcf F ext/session/test_session.c f4d1dca94db71ec2177ee61eab51e718e58476d7 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x @@ -938,7 +938,7 @@ F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 343b64517d244b75097e38342dc273eb5a52915b -R c818789c65113df118a04c3a29f3e5ba +P df0b2d21dcd81679e55b24866f97568019932983 +R b4d7dfa6bf40d53e75863a5a6b9fd8ce U dan -Z 7081c2709375635b8446c7ef8a86300e +Z 2d321dbf5ee44d87c34feecb146a5235 diff --git a/manifest.uuid b/manifest.uuid index 72289d19b5..8ae1676306 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -df0b2d21dcd81679e55b24866f97568019932983 \ No newline at end of file +3dfd1d63bddfa9bd9018eb00bee1d496379630b5 \ No newline at end of file From 6734007d75cfd1785843aea9b8c3b6b568662c74 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 16 Apr 2011 19:23:10 +0000 Subject: [PATCH 0052/1484] Improve test coverage of session module. FossilOrigin-Name: f46d4b641d613c39a80b12106e6a6ac0efc8be83 --- ext/session/session1.test | 22 +++++++ ext/session/session3.test | 33 +++++++++- ext/session/session5.test | 113 +++++++++++++++++++++++++++++++++- ext/session/sessionfault.test | 101 +++++++++++++++++++++++++++++- ext/session/sqlite3session.c | 108 +++++++++++++++++--------------- ext/session/test_session.c | 31 ++++++++-- manifest | 24 ++++---- manifest.uuid | 2 +- test/tester.tcl | 8 ++- 9 files changed, 369 insertions(+), 73 deletions(-) diff --git a/ext/session/session1.test b/ext/session/session1.test index 067432affa..5e0fbc52a0 100644 --- a/ext/session/session1.test +++ b/ext/session/session1.test @@ -443,5 +443,27 @@ do_conflict_test 6.1 -tables {t1 t2} -sql { do_db2_test 6.2 "SELECT * FROM t1" {a b 1 2} do_db2_test 6.3 "SELECT * FROM t2" {a b A B} +#------------------------------------------------------------------------- +# Test that session objects are not confused by changes to table in +# other databases. +# +catch { db2 close } +drop_all_tables +forcedelete test.db2 +do_iterator_test 7.1 * { + ATTACH 'test.db2' AS aux; + CREATE TABLE main.t1(x PRIMARY KEY, y); + CREATE TABLE aux.t1(x PRIMARY KEY, y); + + INSERT INTO main.t1 VALUES('one', 1); + INSERT INTO main.t1 VALUES('two', 2); + INSERT INTO aux.t1 VALUES('three', 3); + INSERT INTO aux.t1 VALUES('four', 4); +} { + {INSERT t1 0 X. {} {t two i 2}} + {INSERT t1 0 X. {} {t one i 1}} +} + + catch { db2 close } finish_test diff --git a/ext/session/session3.test b/ext/session/session3.test index c0fcebff66..e15407c2eb 100644 --- a/ext/session/session3.test +++ b/ext/session/session3.test @@ -119,7 +119,6 @@ do_test 2.2.1 { } list [catch { S changeset } msg] $msg } {1 SQLITE_SCHEMA} - do_test 2.2.2 { S delete sqlite3session S db main @@ -135,6 +134,38 @@ do_test 2.2.2 { } list [catch { S changeset } msg] $msg } {1 SQLITE_SCHEMA} +do_test 2.2.3 { + S delete + sqlite3session S db main + execsql { + DROP TABLE t2; + CREATE TABLE t2(a, b PRIMARY KEY, c); + } + S attach t2 + execsql { + INSERT INTO t2 VALUES(1, 2, 3); + DROP TABLE t2; + CREATE TABLE t2(a, b PRIMARY KEY); + INSERT INTO t2 VALUES(4, 5); + } + list [catch { S changeset } msg] $msg +} {1 SQLITE_SCHEMA} +do_test 2.2.4 { + S delete + sqlite3session S db main + execsql { + DROP TABLE t2; + CREATE TABLE t2(a, b PRIMARY KEY, c); + } + S attach t2 + execsql { + INSERT INTO t2 VALUES(1, 2, 3); + DROP TABLE t2; + CREATE TABLE t2(a, b PRIMARY KEY, c, d); + INSERT INTO t2 VALUES(4, 5, 6, 7); + } + list [catch { S changeset } msg] $msg +} {1 SQLITE_SCHEMA} do_test 2.3 { S delete diff --git a/ext/session/session5.test b/ext/session/session5.test index 1e67e1d325..88430057d0 100644 --- a/ext/session/session5.test +++ b/ext/session/session5.test @@ -30,6 +30,11 @@ set testprefix session5 # # session5-3.*: Schema mismatch errors. # +# session5-4.*: Test the concat cases that indicate that the database +# was modified in between recording of the two changesets +# being concatenated (i.e. two changesets that INSERT rows +# with the same PK values). +# proc do_concat_test {tn args} { @@ -224,7 +229,6 @@ do_test 2.3.0 { for {set i 1} {$i < 120} {incr i} { append sql2 "DELETE FROM x1 WHERE a = $i*4;" } - set {} {} } {} do_concat_test 2.3 { @@ -254,6 +258,47 @@ do_concat_test 2.5 { INSERT INTO x2 VALUES('a', 'B'); } +for {set k 1} {$k <=10} {incr k} { + do_test 2.6.$k.1 { + drop_all_tables + set sql1 "" + set sql2 "" + for {set i 1} {$i < 120} {incr i} { + append sql1 "INSERT INTO x1 VALUES(randomblob(20+(random()%10)), $i);" + } + for {set i 1} {$i < 120} {incr i} { + append sql2 "DELETE FROM x1 WHERE rowid = $i;" + } + set {} {} + } {} + do_concat_test 2.6.$k { + CREATE TABLE x1(a PRIMARY KEY, b) + } $sql1 $sql2 $sql1 $sql2 +} + +for {set k 1} {$k <=10} {incr k} { + do_test 2.7.$k.1 { + drop_all_tables + set sql1 "" + set sql2 "" + for {set i 1} {$i < 120} {incr i} { + append sql1 { + INSERT INTO x1 VALUES( + CASE WHEN random()%2 THEN random() ELSE randomblob(20+random()%10) END, + CASE WHEN random()%2 THEN random() ELSE randomblob(20+random()%10) END + ); + } + } + for {set i 1} {$i < 120} {incr i} { + append sql2 "DELETE FROM x1 WHERE rowid = $i;" + } + set {} {} + } {} + do_concat_test 2.7.$k { + CREATE TABLE x1(a PRIMARY KEY, b) + } $sql1 $sql2 $sql1 $sql2 +} + #------------------------------------------------------------------------- # Test that schema incompatibilities are detected correctly. @@ -294,5 +339,71 @@ do_test 3.2 { list [catch { sqlite3changeset_concat $c1 $c2 } msg] $msg } {1 SQLITE_SCHEMA} +#------------------------------------------------------------------------- +# Test that concat() handles these properly: +# +# session5-4.1: INSERT + INSERT +# session5-4.2: UPDATE + INSERT +# session5-4.3: DELETE + UPDATE +# session5-4.4: DELETE + DELETE +# + +proc do_concat_test2 {tn sql1 sqlX sql2 expected} { + sqlite3session S db main ; S attach * + execsql $sql1 + set ::c1 [S changeset] + S delete + + execsql $sqlX + + sqlite3session S db main ; S attach * + execsql $sql2 + set ::c2 [S changeset] + S delete + + uplevel do_test $tn [list { + changeset_to_list [sqlite3changeset_concat $::c1 $::c2] + }] [list [normalize_list $expected]] +} + +drop_all_tables db +do_concat_test2 4.1 { + CREATE TABLE t1(a PRIMARY KEY, b); + INSERT INTO t1 VALUES('key', 'value'); +} { + DELETE FROM t1 WHERE a = 'key'; +} { + INSERT INTO t1 VALUES('key', 'xxx'); +} { + {INSERT t1 0 X. {} {t key t value}} +} +do_concat_test2 4.2 { + UPDATE t1 SET b = 'yyy'; +} { + DELETE FROM t1 WHERE a = 'key'; +} { + INSERT INTO t1 VALUES('key', 'value'); +} { + {UPDATE t1 0 X. {t key t xxx} {{} {} t yyy}} +} +do_concat_test2 4.3 { + DELETE FROM t1 WHERE a = 'key'; +} { + INSERT INTO t1 VALUES('key', 'www'); +} { + UPDATE t1 SET b = 'valueX' WHERE a = 'key'; +} { + {DELETE t1 0 X. {t key t value} {}} +} +do_concat_test2 4.4 { + DELETE FROM t1 WHERE a = 'key'; +} { + INSERT INTO t1 VALUES('key', 'ttt'); +} { + DELETE FROM t1 WHERE a = 'key'; +} { + {DELETE t1 0 X. {t key t valueX} {}} +} finish_test + diff --git a/ext/session/sessionfault.test b/ext/session/sessionfault.test index c21d72fb81..b9800e1f46 100644 --- a/ext/session/sessionfault.test +++ b/ext/session/sessionfault.test @@ -265,7 +265,7 @@ do_execsql_test 5.prep1 { INSERT INTO t1 VALUES(X'FFAAFFAAFFAA', 3); } -do_test 5.prep2 { +do_test 6.prep2 { sqlite3session M db main M attach * set ::c2 [changeset_from_sql { @@ -294,4 +294,103 @@ do_faultsim_test 6 -faults oom-* -body { } } +faultsim_delete_and_reopen +do_execsql_test 5.prep1 { + CREATE TABLE t1(a, b, PRIMARY KEY(a)); +} +faultsim_save_and_close + +set res [list] +for {set ::i 0} {$::i < 480} {incr ::i 4} { + lappend res "INSERT t1 0 X. {} {i $::i i $::i}" +} +set res [lsort $res] +do_faultsim_test 7 -faults oom-transient -prep { + faultsim_restore_and_reopen + sqlite3session S db main + S attach * +} -body { + for {set ::i 0} {$::i < 480} {incr ::i 4} { + execsql {INSERT INTO t1 VALUES($::i, $::i)} + } +} -test { + faultsim_test_result {0 {}} {1 SQLITE_NOMEM} + if {$testrc==0} { + set cres [list [catch {changeset_to_list [S changeset]} msg] $msg] + S delete + if {$cres != "1 SQLITE_NOMEM" && $cres != "0 {$::res}"} { + error "Expected {0 $::res} Got {$cres}" + } + } else { + S changeset + S delete + } +} + +faultsim_delete_and_reopen +do_test 8.prep { + sqlite3session S db main + S attach * + execsql { + CREATE TABLE t1(a, b, PRIMARY KEY(a)); + INSERT INTO t1 VALUES(1, 2); + INSERT INTO t1 VALUES(3, 4); + INSERT INTO t1 VALUES(5, 6); + } + set ::changeset [S changeset] + S delete +} {} + +set expected [normalize_list { + {INSERT t1 0 X. {} {i 1 i 2}} + {INSERT t1 0 X. {} {i 3 i 4}} + {INSERT t1 0 X. {} {i 5 i 6}} +}] +do_faultsim_test 8.1 -faults oom* -body { + set ::res [list] + sqlite3session_foreach -next v $::changeset { lappend ::res $v } + normalize_list $::res +} -test { + faultsim_test_result [list 0 $::expected] {1 SQLITE_NOMEM} +} +do_faultsim_test 8.2 -faults oom* -body { + set ::res [list] + sqlite3session_foreach v $::changeset { lappend ::res $v } + normalize_list $::res +} -test { + faultsim_test_result [list 0 $::expected] {1 SQLITE_NOMEM} +} + +faultsim_delete_and_reopen +do_test 9.prep { + execsql { + PRAGMA encoding = 'utf16'; + CREATE TABLE t1(a PRIMARY KEY, b); + } +} {} +faultsim_save_and_close + +do_faultsim_test 9 -faults oom-transient -prep { + catch { unset ::c } + faultsim_restore_and_reopen + sqlite3session S db main + S attach * +} -body { + execsql { + INSERT INTO t1 VALUES('abcdefghijklmnopqrstuv', 'ABCDEFGHIJKLMNOPQRSTUV'); + } + set ::c [S changeset] + set {} {} +} -test { + S delete + faultsim_test_result {0 {}} {1 SQLITE_NOMEM} {1 {callback requested query abort}} + if {[info exists ::c]} { + set expected "{INSERT t1 0 X. {} {t abcdefghijklmnopqrstuv t ABCDEFGHIJKLMNOPQRSTUV}}" + if { [changeset_to_list $::c] != $expected } { + error "changeset mismatch" + } + } +} + + finish_test diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index bad6240a1f..4f81170621 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -317,34 +317,29 @@ static unsigned int sessionPreupdateHash( eType = sqlite3_value_type(pVal); h = HASH_APPEND(h, eType); - switch( eType ){ - case SQLITE_INTEGER: - case SQLITE_FLOAT: { - i64 iVal; - if( eType==SQLITE_INTEGER ){ - iVal = sqlite3_value_int64(pVal); - }else{ - double rVal = sqlite3_value_double(pVal); - assert( sizeof(iVal)==8 && sizeof(rVal)==8 ); - memcpy(&iVal, &rVal, 8); - } - h = sessionHashAppendI64(h, iVal); - break; + if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){ + i64 iVal; + if( eType==SQLITE_INTEGER ){ + iVal = sqlite3_value_int64(pVal); + }else{ + double rVal = sqlite3_value_double(pVal); + assert( sizeof(iVal)==8 && sizeof(rVal)==8 ); + memcpy(&iVal, &rVal, 8); } - - case SQLITE_TEXT: - case SQLITE_BLOB: { - int n = sqlite3_value_bytes(pVal); - const u8 *z = eType==SQLITE_TEXT ? - sqlite3_value_text(pVal) : sqlite3_value_blob(pVal); - h = sessionHashAppendBlob(h, n, z); - break; + h = sessionHashAppendI64(h, iVal); + }else if( eType==SQLITE_TEXT || eType==SQLITE_BLOB ){ + const u8 *z; + if( eType==SQLITE_TEXT ){ + z = (const u8 *)sqlite3_value_text(pVal); + }else{ + z = (const u8 *)sqlite3_value_blob(pVal); } - - default: - assert( eType==SQLITE_NULL ); - *pbNullPK = 1; - return SQLITE_OK; + if( !z ) return SQLITE_NOMEM; + h = sessionHashAppendBlob(h, sqlite3_value_bytes(pVal), z); + }else{ + assert( eType==SQLITE_NULL ); + *pbNullPK = 1; + return SQLITE_OK; } } } @@ -399,12 +394,12 @@ static unsigned int sessionChangeHash( a++; h = HASH_APPEND(h, eType); if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){ - if( isPK ) h = sessionHashAppendI64(h, sessionGetI64(a)); + h = sessionHashAppendI64(h, sessionGetI64(a)); a += 8; }else{ int n; a += sessionVarintGet(a, &n); - if( isPK ) h = sessionHashAppendBlob(h, n, a); + h = sessionHashAppendBlob(h, n, a); a += n; } }else{ @@ -559,7 +554,7 @@ static int sessionMergeUpdate( return 1; } -static int sessionPreupdateEqual( +static void sessionPreupdateEqual( sqlite3 *db, SessionTable *pTab, SessionChange *pChange, @@ -589,14 +584,23 @@ static int sessionPreupdateEqual( } } }else{ - sqlite3_value *pVal; - int rc; + sqlite3_value *pVal; /* Value returned by preupdate_new/old */ + int rc; /* Error code from preupdate_new/old */ + + /* The following calls to preupdate_new() and preupdate_old() can not + ** fail. This is because they cache their return values, and by the + ** time control flows to here they have already been called once from + ** within sessionPreupdateHash(). The first two asserts below verify + ** this (that the method has already been called). */ if( bNew ){ + assert( db->pPreUpdate->pNewUnpacked || db->pPreUpdate->aNew ); rc = sqlite3_preupdate_new(db, i, &pVal); }else{ + assert( db->pPreUpdate->pUnpacked ); rc = sqlite3_preupdate_old(db, i, &pVal); } - if( rc!=SQLITE_OK || sqlite3_value_type(pVal)!=eType ) return rc; + assert( rc==SQLITE_OK ); + if( sqlite3_value_type(pVal)!=eType ) return; /* A SessionChange object never has a NULL value in a PK column */ assert( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT @@ -607,24 +611,24 @@ static int sessionPreupdateEqual( i64 iVal = sessionGetI64(a); a += 8; if( eType==SQLITE_INTEGER ){ - if( sqlite3_value_int64(pVal)!=iVal ) return SQLITE_OK; + if( sqlite3_value_int64(pVal)!=iVal ) return; }else{ double rVal; assert( sizeof(iVal)==8 && sizeof(rVal)==8 ); memcpy(&rVal, &iVal, 8); - if( sqlite3_value_double(pVal)!=rVal ) return SQLITE_OK; + if( sqlite3_value_double(pVal)!=rVal ) return; } }else{ int n; const u8 *z; a += sessionVarintGet(a, &n); - if( sqlite3_value_bytes(pVal)!=n ) return SQLITE_OK; + if( sqlite3_value_bytes(pVal)!=n ) return; if( eType==SQLITE_TEXT ){ z = sqlite3_value_text(pVal); }else{ z = sqlite3_value_blob(pVal); } - if( memcmp(a, z, n) ) return SQLITE_OK; + if( memcmp(a, z, n) ) return; a += n; break; } @@ -632,7 +636,7 @@ static int sessionPreupdateEqual( } *pbEqual = 1; - return SQLITE_OK; + return; } /* @@ -854,9 +858,9 @@ static void sessionPreupdateOneChange( rc = sessionPreupdateHash(db, pTab, op==SQLITE_INSERT, &iHash, &bNullPk); if( rc==SQLITE_OK && bNullPk==0 ){ SessionChange *pC; - for(pC=pTab->apChange[iHash]; rc==SQLITE_OK && pC; pC=pC->pNext){ + for(pC=pTab->apChange[iHash]; pC; pC=pC->pNext){ int bEqual; - rc = sessionPreupdateEqual(db, pTab, pC, op==SQLITE_INSERT, &bEqual); + sessionPreupdateEqual(db, pTab, pC, op==SQLITE_INSERT, &bEqual); if( bEqual ) break; } if( pC==0 ){ @@ -1278,12 +1282,19 @@ static void sessionAppendCol( sessionAppendBlob(p, aBuf, 8, pRc); } if( eType==SQLITE_BLOB || eType==SQLITE_TEXT ){ - int nByte = sqlite3_column_bytes(pStmt, iCol); - sessionAppendVarint(p, nByte, pRc); - sessionAppendBlob(p, eType==SQLITE_BLOB ? - sqlite3_column_blob(pStmt, iCol) : sqlite3_column_text(pStmt, iCol), - nByte, pRc - ); + u8 *z; + if( eType==SQLITE_BLOB ){ + z = (u8 *)sqlite3_column_blob(pStmt, iCol); + }else{ + z = (u8 *)sqlite3_column_text(pStmt, iCol); + } + if( z ){ + int nByte = sqlite3_column_bytes(pStmt, iCol); + sessionAppendVarint(p, nByte, pRc); + sessionAppendBlob(p, z, nByte, pRc); + }else{ + *pRc = SQLITE_NOMEM; + } } } } @@ -1710,8 +1721,8 @@ static int sessionReadRecord( int nByte; aRec += sessionVarintGet(aRec, &nByte); if( apOut ){ - int enc = (eType==SQLITE_TEXT ? SQLITE_UTF8 : 0); - sqlite3ValueSetStr(apOut[i], nByte, aRec, enc, SQLITE_STATIC); + u8 enc = (eType==SQLITE_TEXT ? SQLITE_UTF8 : 0); + sqlite3ValueSetStr(apOut[i], nByte, (char *)aRec, enc, SQLITE_STATIC); } aRec += nByte; } @@ -1742,7 +1753,6 @@ static int sessionChangesetNext( ){ u8 *aChange; int i; - u8 c; assert( (paRec==0 && pnRec==0) || (paRec && pnRec) ); @@ -1818,7 +1828,6 @@ static int sessionChangesetNext( */ int sqlite3changeset_next(sqlite3_changeset_iter *p){ return sessionChangesetNext(p, 0, 0); - } /* @@ -2987,7 +2996,6 @@ int sqlite3changeset_concat( } } - concat_out: sessionDeleteTable(pList); return rc; } diff --git a/ext/session/test_session.c b/ext/session/test_session.c index 05eb732d6d..0993073328 100644 --- a/ext/session/test_session.c +++ b/ext/session/test_session.c @@ -456,13 +456,25 @@ static int test_sqlite3session_foreach( int nChangeSet; sqlite3_changeset_iter *pIter; int rc; + Tcl_Obj *pVarname; + Tcl_Obj *pCS; + Tcl_Obj *pScript; + int isCheckNext = 0; - if( objc!=4 ){ - Tcl_WrongNumArgs(interp, 1, objv, "VARNAME CHANGESET SCRIPT"); + if( objc>1 ){ + char *zOpt = Tcl_GetString(objv[1]); + isCheckNext = (strcmp(zOpt, "-next")==0); + } + if( objc!=4+isCheckNext ){ + Tcl_WrongNumArgs(interp, 1, objv, "?-next? VARNAME CHANGESET SCRIPT"); return TCL_ERROR; } - pChangeSet = (void *)Tcl_GetByteArrayFromObj(objv[2], &nChangeSet); + pVarname = objv[1+isCheckNext]; + pCS = objv[2+isCheckNext]; + pScript = objv[3+isCheckNext]; + + pChangeSet = (void *)Tcl_GetByteArrayFromObj(pCS, &nChangeSet); rc = sqlite3changeset_start(&pIter, nChangeSet, pChangeSet); if( rc!=SQLITE_OK ){ return test_session_error(interp, rc); @@ -524,14 +536,21 @@ static int test_sqlite3session_foreach( Tcl_ListObjAppendElement(0, pVar, pOld); Tcl_ListObjAppendElement(0, pVar, pNew); - Tcl_ObjSetVar2(interp, objv[1], 0, pVar, 0); - rc = Tcl_EvalObjEx(interp, objv[3], 0); + Tcl_ObjSetVar2(interp, pVarname, 0, pVar, 0); + rc = Tcl_EvalObjEx(interp, pScript, 0); if( rc!=TCL_OK && rc!=TCL_CONTINUE ){ sqlite3changeset_finalize(pIter); return rc==TCL_BREAK ? TCL_OK : rc; } } - rc = sqlite3changeset_finalize(pIter); + + if( isCheckNext ){ + int rc2 = sqlite3changeset_next(pIter); + rc = sqlite3changeset_finalize(pIter); + assert( (rc2==SQLITE_DONE && rc==SQLITE_OK) || rc2==rc ); + }else{ + rc = sqlite3changeset_finalize(pIter); + } if( rc!=SQLITE_OK ){ return test_session_error(interp, rc); } diff --git a/manifest b/manifest index bc49322d17..1938e24d5e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improve\scoverage\sof\ssession\smodule. -D 2011-04-15T19:18:57.799 +C Improve\stest\scoverage\sof\ssession\smodule. +D 2011-04-16T19:23:10.456 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 7a4d9524721d40ef9ee26f93f9bd6a51dba106f2 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -99,16 +99,16 @@ F ext/rtree/rtree_util.tcl 06aab2ed5b826545bf215fff90ecb9255a8647ea F ext/rtree/sqlite3rtree.h 1af0899c63a688e272d69d8e746f24e76f10a3f0 F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 -F ext/session/session1.test 7a92a2a6f531aef1e9764ffb7f983fb8b315376d +F ext/session/session1.test f5d9f2e362abe2563181389509822bda956516ee F ext/session/session2.test c3e5f78d5eb988e35cc2ba9ce3678f706283cfdb -F ext/session/session3.test bfa2376db7cbb2ac69496f84d93a8d81b13110d3 +F ext/session/session3.test a7a9ce59b8d1e49e2cc23d81421ac485be0eea01 F ext/session/session4.test a6ed685da7a5293c5d6f99855bcf41dbc352ca84 -F ext/session/session5.test 525503799d56124a31bedbd7895c1e668d18420d +F ext/session/session5.test 8fdfaf9dba28a2f1c6b89b06168bdab1fef2d478 F ext/session/session_common.tcl 1539d8973b2aea0025c133eb0cc4c89fcef541a5 -F ext/session/sessionfault.test 2766cd620f1793f0e54f1e3859a184bcea55bad4 -F ext/session/sqlite3session.c 4c44da92750d4b31bcbed25428be7167cddccf84 +F ext/session/sessionfault.test 759060c36ef424919e3900b885b22aa15caf7f39 +F ext/session/sqlite3session.c 3475df4021c5260f795cf66f67233449795c06ea F ext/session/sqlite3session.h 665f5591562e3c71eb3d0da26f1a1efae26f7bcf -F ext/session/test_session.c f4d1dca94db71ec2177ee61eab51e718e58476d7 +F ext/session/test_session.c 311e5b9228374d0b5780448f289847ff1cf7d388 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F main.mk f942406cb7df55d1aec40a88a7ae399b730cd94f @@ -697,7 +697,7 @@ F test/tclsqlite.test 1ce9b6340d6d412420634e129a2e3722c651056a F test/tempdb.test 19d0f66e2e3eeffd68661a11c83ba5e6ace9128c F test/temptable.test f42121a0d29a62f00f93274464164177ab1cc24a F test/temptrigger.test b0273db072ce5f37cf19140ceb1f0d524bbe9f05 -F test/tester.tcl 6fa3d2f581b479a3a088b1b5b0d145e548ebe662 +F test/tester.tcl fc2e27b3a782c5c5b03f7cded15cf498cad9bfef F test/thread001.test a3e6a7254d1cb057836cb3145b60c10bf5b7e60f F test/thread002.test afd20095e6e845b405df4f2c920cb93301ca69db F test/thread003.test b824d4f52b870ae39fc5bae4d8070eca73085dca @@ -938,7 +938,7 @@ F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P df0b2d21dcd81679e55b24866f97568019932983 -R b4d7dfa6bf40d53e75863a5a6b9fd8ce +P 3dfd1d63bddfa9bd9018eb00bee1d496379630b5 +R 57f77b8ed5537ccfd8e7f64bd8d648b6 U dan -Z 2d321dbf5ee44d87c34feecb146a5235 +Z 35862238c72a43b8ebb72adec800f600 diff --git a/manifest.uuid b/manifest.uuid index 8ae1676306..387cde32ce 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3dfd1d63bddfa9bd9018eb00bee1d496379630b5 \ No newline at end of file +f46d4b641d613c39a80b12106e6a6ac0efc8be83 \ No newline at end of file diff --git a/test/tester.tcl b/test/tester.tcl index bae10530c6..bd6a00a17f 100644 --- a/test/tester.tcl +++ b/test/tester.tcl @@ -20,7 +20,7 @@ # Commands to manipulate the db and the file-system at a high level: # # copy_file FROM TO -# drop_all_table ?DB? +# drop_all_tables ?DB? # forcedelete FILENAME # # Test the capability of the SQLite version built into the interpreter to @@ -362,6 +362,12 @@ proc fix_testname {varname} { set testname "${::testprefix}-$testname" } } + +proc normalize_list {L} { + set L2 [list] + foreach l $L {lappend L2 $l} + set L2 +} proc do_execsql_test {testname sql {result {}}} { fix_testname testname From 80fe2d931071b6378969e26fedcc92bf0ff19ef3 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 18 Apr 2011 07:36:27 +0000 Subject: [PATCH 0053/1484] Further coverage tests for the session module. FossilOrigin-Name: 69a01c708bf044eacf21a8951fe9e7d9fb4332c5 --- ext/session/session2.test | 17 ++ ext/session/sessionfault.test | 51 ++++- ext/session/sqlite3session.c | 337 ++++++++++++++++++---------------- manifest | 16 +- manifest.uuid | 2 +- 5 files changed, 254 insertions(+), 169 deletions(-) diff --git a/ext/session/session2.test b/ext/session/session2.test index 5c7ea47d5f..04be5f0917 100644 --- a/ext/session/session2.test +++ b/ext/session/session2.test @@ -390,6 +390,23 @@ do_iterator_test 6.1.7 * { {UPDATE t2 0 X. {i 4 t y} {{} {} t new}} } +do_iterator_test 6.1.8 * { + CREATE TABLE t3(a, b PRIMARY KEY); + CREATE TABLE t4(a, b PRIMARY KEY); + CREATE TRIGGER t4t AFTER UPDATE ON t4 BEGIN + UPDATE t3 SET a = new.a WHERE b = new.b; + END; + + SELECT indirect(1); + INSERT INTO t3 VALUES('one', 1); + INSERT INTO t4 VALUES('one', 1); + SELECT indirect(0); + UPDATE t4 SET a = 'two' WHERE b = 1; +} { + {INSERT t4 0 .X {} {t two i 1}} + {INSERT t3 1 .X {} {t two i 1}} +} + sqlite3session S db main do_execsql_test 6.2.1 { SELECT indirect(0); diff --git a/ext/session/sessionfault.test b/ext/session/sessionfault.test index b9800e1f46..1444a46b36 100644 --- a/ext/session/sessionfault.test +++ b/ext/session/sessionfault.test @@ -20,6 +20,8 @@ source $testdir/tester.tcl set testprefix sessionfault +if 1 { + forcedelete test.db2 sqlite3 db2 test.db2 do_common_sql { @@ -362,7 +364,7 @@ do_faultsim_test 8.2 -faults oom* -body { } faultsim_delete_and_reopen -do_test 9.prep { +do_test 9.1.prep { execsql { PRAGMA encoding = 'utf16'; CREATE TABLE t1(a PRIMARY KEY, b); @@ -370,7 +372,8 @@ do_test 9.prep { } {} faultsim_save_and_close -do_faultsim_test 9 -faults oom-transient -prep { +set answers [list {0 {}} {1 SQLITE_NOMEM} {1 {callback requested query abort}}] +do_faultsim_test 9.1 -faults oom-transient -prep { catch { unset ::c } faultsim_restore_and_reopen sqlite3session S db main @@ -383,9 +386,48 @@ do_faultsim_test 9 -faults oom-transient -prep { set {} {} } -test { S delete - faultsim_test_result {0 {}} {1 SQLITE_NOMEM} {1 {callback requested query abort}} + eval faultsim_test_result $::answers if {[info exists ::c]} { - set expected "{INSERT t1 0 X. {} {t abcdefghijklmnopqrstuv t ABCDEFGHIJKLMNOPQRSTUV}}" + set expected [normalize_list { + {INSERT t1 0 X. {} {t abcdefghijklmnopqrstuv t ABCDEFGHIJKLMNOPQRSTUV}} + }] + if { [changeset_to_list $::c] != $expected } { + error "changeset mismatch" + } + } +} + +} + +faultsim_delete_and_reopen +do_test 9.2.prep { + execsql { + PRAGMA encoding = 'utf16'; + CREATE TABLE t1(a PRIMARY KEY, b); + INSERT INTO t1 VALUES('abcdefghij', 'ABCDEFGHIJKLMNOPQRSTUV'); + } +} {} +faultsim_save_and_close + +set answers [list {0 {}} {1 SQLITE_NOMEM} {1 {callback requested query abort}}] +do_faultsim_test 9.2 -faults oom-transient -prep { + catch { unset ::c } + faultsim_restore_and_reopen + sqlite3session S db main + S attach * +} -body { + execsql { + UPDATE t1 SET b = 'xyz'; + } + set ::c [S changeset] + set {} {} +} -test { + S delete + eval faultsim_test_result $::answers + if {[info exists ::c]} { + set expected [normalize_list { + {UPDATE t1 0 X. {t abcdefghij t ABCDEFGHIJKLMNOPQRSTUV} {{} {} t xyz}} + }] if { [changeset_to_list $::c] != $expected } { error "changeset mismatch" } @@ -393,4 +435,5 @@ do_faultsim_test 9 -faults oom-transient -prep { } + finish_test diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index 4f81170621..2232d21938 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -222,51 +222,68 @@ static int sessionSerializeValue( sqlite3_value *pValue, /* Value to serialize */ int *pnWrite /* IN/OUT: Increment by bytes written */ ){ - int eType; /* Value type (SQLITE_NULL, TEXT etc.) */ int nByte; /* Size of serialized value in bytes */ - eType = sqlite3_value_type(pValue); - if( aBuf ) aBuf[0] = eType; - - switch( eType ){ - case SQLITE_NULL: - nByte = 1; - break; - - case SQLITE_INTEGER: - case SQLITE_FLOAT: - if( aBuf ){ - /* TODO: SQLite does something special to deal with mixed-endian - ** floating point values (e.g. ARM7). This code probably should - ** too. */ - u64 i; - if( eType==SQLITE_INTEGER ){ - i = (u64)sqlite3_value_int64(pValue); - }else{ - double r; - assert( sizeof(double)==8 && sizeof(u64)==8 ); - r = sqlite3_value_double(pValue); - memcpy(&i, &r, 8); + if( pValue ){ + int eType; /* Value type (SQLITE_NULL, TEXT etc.) */ + + eType = sqlite3_value_type(pValue); + if( aBuf ) aBuf[0] = eType; + + switch( eType ){ + case SQLITE_NULL: + nByte = 1; + break; + + case SQLITE_INTEGER: + case SQLITE_FLOAT: + if( aBuf ){ + /* TODO: SQLite does something special to deal with mixed-endian + ** floating point values (e.g. ARM7). This code probably should + ** too. */ + u64 i; + if( eType==SQLITE_INTEGER ){ + i = (u64)sqlite3_value_int64(pValue); + }else{ + double r; + assert( sizeof(double)==8 && sizeof(u64)==8 ); + r = sqlite3_value_double(pValue); + memcpy(&i, &r, 8); + } + sessionPutI64(&aBuf[1], i); } - sessionPutI64(&aBuf[1], i); + nByte = 9; + break; + + default: { + u8 *z; + int n; + int nVarint; + + assert( eType==SQLITE_TEXT || eType==SQLITE_BLOB ); + if( eType==SQLITE_TEXT ){ + z = (u8 *)sqlite3_value_text(pValue); + }else{ + z = (u8 *)sqlite3_value_blob(pValue); + } + if( z==0 ) return SQLITE_NOMEM; + n = sqlite3_value_bytes(pValue); + nVarint = sessionVarintLen(n); + + if( aBuf ){ + sessionVarintPut(&aBuf[1], n); + memcpy(&aBuf[nVarint + 1], eType==SQLITE_TEXT ? + sqlite3_value_text(pValue) : sqlite3_value_blob(pValue), n + ); + } + + nByte = 1 + nVarint + n; + break; } - nByte = 9; - break; - - default: { - int n = sqlite3_value_bytes(pValue); - int nVarint = sessionVarintLen(n); - assert( eType==SQLITE_TEXT || eType==SQLITE_BLOB ); - if( aBuf ){ - sessionVarintPut(&aBuf[1], n); - memcpy(&aBuf[nVarint + 1], eType==SQLITE_TEXT ? - sqlite3_value_text(pValue) : sqlite3_value_blob(pValue), n - ); - } - - nByte = 1 + nVarint + n; - break; } + }else{ + nByte = 1; + if( aBuf ) aBuf[0] = '\0'; } *pnWrite += nByte; @@ -851,18 +868,21 @@ static void sessionPreupdateOneChange( return; } - /* Search the hash table for an existing entry for rowid=iKey2. If - ** one is found, store a pointer to it in pChange and unlink it from - ** the hash table. Otherwise, set pChange to NULL. - */ + /* Calculate the hash-key for this change. If the primary key of the row + ** includes a NULL value, exit early. Such changes are ignored by the + ** session module. */ rc = sessionPreupdateHash(db, pTab, op==SQLITE_INSERT, &iHash, &bNullPk); - if( rc==SQLITE_OK && bNullPk==0 ){ + if( rc!=SQLITE_OK ) goto error_out; + + if( bNullPk==0 ){ + /* Search the hash table for an existing record for this row. */ SessionChange *pC; for(pC=pTab->apChange[iHash]; pC; pC=pC->pNext){ int bEqual; sessionPreupdateEqual(db, pTab, pC, op==SQLITE_INSERT, &bEqual); if( bEqual ) break; } + if( pC==0 ){ /* Create a new change object containing all the old values (if ** this is an SQLITE_UPDATE or SQLITE_DELETE), or just the PK @@ -876,53 +896,57 @@ static void sessionPreupdateOneChange( /* Figure out how large an allocation is required */ nByte = sizeof(SessionChange); - for(i=0; inCol && rc==SQLITE_OK; i++){ + for(i=0; inCol; i++){ sqlite3_value *p = 0; if( op!=SQLITE_INSERT ){ - rc = sqlite3_preupdate_old(pSession->db, i, &p); - }else if( 1 || pTab->abPK[i] ){ - rc = sqlite3_preupdate_new(pSession->db, i, &p); - } - if( p && rc==SQLITE_OK ){ - rc = sessionSerializeValue(0, p, &nByte); + TESTONLY(int trc = ) sqlite3_preupdate_old(pSession->db, i, &p); + assert( trc==SQLITE_OK ); + }else if( pTab->abPK[i] ){ + TESTONLY(int trc = ) sqlite3_preupdate_new(pSession->db, i, &p); + assert( trc==SQLITE_OK ); } + + /* This may fail if SQLite value p contains a utf-16 string that must + ** be converted to utf-8 and an OOM error occurs while doing so. */ + rc = sessionSerializeValue(0, p, &nByte); + if( rc!=SQLITE_OK ) goto error_out; } /* Allocate the change object */ pChange = (SessionChange *)sqlite3_malloc(nByte); if( !pChange ){ rc = SQLITE_NOMEM; + goto error_out; }else{ memset(pChange, 0, sizeof(SessionChange)); pChange->aRecord = (u8 *)&pChange[1]; } - /* Populate the change object */ + /* Populate the change object. None of the preupdate_old(), + ** preupdate_new() or SerializeValue() calls below may fail as all + ** required values and encodings have already been cached in memory. + ** It is not possible for an OOM to occur in this block. */ nByte = 0; - for(i=0; inCol && rc==SQLITE_OK; i++){ + for(i=0; inCol; i++){ sqlite3_value *p = 0; if( op!=SQLITE_INSERT ){ - rc = sqlite3_preupdate_old(pSession->db, i, &p); - }else if( 1 || pTab->abPK[i] ){ - rc = sqlite3_preupdate_new(pSession->db, i, &p); - } - if( p && rc==SQLITE_OK ){ - rc = sessionSerializeValue(&pChange->aRecord[nByte], p, &nByte); + sqlite3_preupdate_old(pSession->db, i, &p); + }else if( pTab->abPK[i] ){ + sqlite3_preupdate_new(pSession->db, i, &p); } + sessionSerializeValue(&pChange->aRecord[nByte], p, &nByte); } - if( rc==SQLITE_OK ){ - /* Add the change back to the hash-table */ - if( pSession->bIndirect || sqlite3_preupdate_depth(pSession->db) ){ - pChange->bIndirect = 1; - } - pChange->nRecord = nByte; - pChange->bInsert = (op==SQLITE_INSERT); - pChange->pNext = pTab->apChange[iHash]; - pTab->apChange[iHash] = pChange; - }else{ - sqlite3_free(pChange); + + /* Add the change to the hash-table */ + if( pSession->bIndirect || sqlite3_preupdate_depth(pSession->db) ){ + pChange->bIndirect = 1; } - }else if( rc==SQLITE_OK && pC->bIndirect ){ + pChange->nRecord = nByte; + pChange->bInsert = (op==SQLITE_INSERT); + pChange->pNext = pTab->apChange[iHash]; + pTab->apChange[iHash] = pChange; + + }else if( pC->bIndirect ){ /* If the existing change is considered "indirect", but this current ** change is "direct", mark the change object as direct. */ if( sqlite3_preupdate_depth(pSession->db)==0 && pSession->bIndirect==0 ){ @@ -932,6 +956,7 @@ static void sessionPreupdateOneChange( } /* If an error has occurred, mark the session object as failed. */ + error_out: if( rc!=SQLITE_OK ){ pSession->rc = rc; } @@ -1125,7 +1150,7 @@ int sqlite3session_attach( ** set *pRc to SQLITE_NOMEM and return non-zero. */ static int sessionBufferGrow(SessionBuffer *p, int nByte, int *pRc){ - if( p->nAlloc-p->nBufnAlloc-p->nBufnAlloc ? p->nAlloc : 128; do { @@ -1135,12 +1160,12 @@ static int sessionBufferGrow(SessionBuffer *p, int nByte, int *pRc){ aNew = (u8 *)sqlite3_realloc(p->aBuf, nNew); if( 0==aNew ){ *pRc = SQLITE_NOMEM; - return 1; + }else{ + p->aBuf = aNew; + p->nAlloc = nNew; } - p->aBuf = aNew; - p->nAlloc = nNew; } - return 0; + return (*pRc!=SQLITE_OK); } /* @@ -1151,7 +1176,7 @@ static int sessionBufferGrow(SessionBuffer *p, int nByte, int *pRc){ ** returning. */ static void sessionAppendByte(SessionBuffer *p, u8 v, int *pRc){ - if( *pRc==SQLITE_OK && 0==sessionBufferGrow(p, 1, pRc) ){ + if( 0==sessionBufferGrow(p, 1, pRc) ){ p->aBuf[p->nBuf++] = v; } } @@ -1164,7 +1189,7 @@ static void sessionAppendByte(SessionBuffer *p, u8 v, int *pRc){ ** returning. */ static void sessionAppendVarint(SessionBuffer *p, int v, int *pRc){ - if( *pRc==SQLITE_OK && 0==sessionBufferGrow(p, 9, pRc) ){ + if( 0==sessionBufferGrow(p, 9, pRc) ){ p->nBuf += sessionVarintPut(&p->aBuf[p->nBuf], v); } } @@ -1182,7 +1207,7 @@ static void sessionAppendBlob( int nBlob, int *pRc ){ - if( *pRc==SQLITE_OK && 0==sessionBufferGrow(p, nBlob, pRc) ){ + if( 0==sessionBufferGrow(p, nBlob, pRc) ){ memcpy(&p->aBuf[p->nBuf], aBlob, nBlob); p->nBuf += nBlob; } @@ -1202,7 +1227,7 @@ static void sessionAppendStr( int *pRc ){ int nStr = sqlite3Strlen30(zStr); - if( *pRc==SQLITE_OK && 0==sessionBufferGrow(p, nStr, pRc) ){ + if( 0==sessionBufferGrow(p, nStr, pRc) ){ memcpy(&p->aBuf[p->nBuf], zStr, nStr); p->nBuf += nStr; } @@ -1241,7 +1266,7 @@ static void sessionAppendIdent( int *pRc /* IN/OUT: Error code */ ){ int nStr = sqlite3Strlen30(zStr)*2 + 2 + 1; - if( *pRc==SQLITE_OK && 0==sessionBufferGrow(p, nStr, pRc) ){ + if( 0==sessionBufferGrow(p, nStr, pRc) ){ char *zOut = (char *)&p->aBuf[p->nBuf]; const char *zIn = zStr; *zOut++ = '"'; @@ -1300,12 +1325,10 @@ static void sessionAppendCol( } /* -** This function is a no-op if *pRc is other than SQLITE_OK when it is -** called. ** -** Otherwse, if *pRc is SQLITE_OK, then it appends an update change to -** the buffer (see the comments under "CHANGESET FORMAT" at the top of the -** file). An update change consists of: +** This function appends an update change to the buffer (see the comments +** under "CHANGESET FORMAT" at the top of the file). An update change +** consists of: ** ** 1 byte: SQLITE_UPDATE (0x17) ** n bytes: old.* record (see RECORD FORMAT) @@ -1323,89 +1346,89 @@ static void sessionAppendCol( ** original values of any fields that have been modified. The new.* record ** contains the new values of only those fields that have been modified. */ -static void sessionAppendUpdate( +static int sessionAppendUpdate( SessionBuffer *pBuf, /* Buffer to append to */ sqlite3_stmt *pStmt, /* Statement handle pointing at new row */ SessionChange *p, /* Object containing old values */ - u8 *abPK, /* Boolean array - true for PK columns */ - int *pRc /* IN/OUT: Error code */ + u8 *abPK /* Boolean array - true for PK columns */ ){ - if( *pRc==SQLITE_OK ){ - SessionBuffer buf2 = {0,0,0}; /* Buffer to accumulate new.* record in */ - int bNoop = 1; /* Set to zero if any values are modified */ - int nRewind = pBuf->nBuf; /* Set to zero if any values are modified */ - int i; /* Used to iterate through columns */ - u8 *pCsr = p->aRecord; /* Used to iterate through old.* values */ + int rc = SQLITE_OK; + SessionBuffer buf2 = {0,0,0}; /* Buffer to accumulate new.* record in */ + int bNoop = 1; /* Set to zero if any values are modified */ + int nRewind = pBuf->nBuf; /* Set to zero if any values are modified */ + int i; /* Used to iterate through columns */ + u8 *pCsr = p->aRecord; /* Used to iterate through old.* values */ - sessionAppendByte(pBuf, SQLITE_UPDATE, pRc); - sessionAppendByte(pBuf, p->bIndirect, pRc); - for(i=0; ibIndirect, &rc); + for(i=0; inBuf = nRewind; + if( bChanged || abPK[i] ){ + sessionAppendBlob(pBuf, pCsr, nAdvance, &rc); }else{ - sessionAppendBlob(pBuf, buf2.aBuf, buf2.nBuf, pRc); + sessionAppendByte(pBuf, 0, &rc); } - sqlite3_free(buf2.aBuf); + + if( bChanged ){ + sessionAppendCol(&buf2, pStmt, i, &rc); + bNoop = 0; + }else{ + sessionAppendByte(&buf2, 0, &rc); + } + + pCsr += nAdvance; } + + if( bNoop ){ + pBuf->nBuf = nRewind; + }else{ + sessionAppendBlob(pBuf, buf2.aBuf, buf2.nBuf, &rc); + } + sqlite3_free(buf2.aBuf); + + return rc; } static int sessionSelectStmt( @@ -1457,6 +1480,7 @@ static int sessionSelectBind( int eType = *a++; switch( eType ){ + case 0: case SQLITE_NULL: assert( abPK[i]==0 ); break; @@ -1580,6 +1604,7 @@ int sqlite3session_changeset( for(p=pTab->apChange[i]; rc==SQLITE_OK && p; p=p->pNext){ rc = sessionSelectBind(pSel, nCol, abPK, p); + if( rc!=SQLITE_OK ) continue; if( sqlite3_step(pSel)==SQLITE_ROW ){ int iCol; if( p->bInsert ){ @@ -1589,7 +1614,7 @@ int sqlite3session_changeset( sessionAppendCol(&buf, pSel, iCol, &rc); } }else{ - sessionAppendUpdate(&buf, pSel, p, abPK, &rc); + rc = sessionAppendUpdate(&buf, pSel, p, abPK); } }else if( !p->bInsert ){ /* A DELETE change */ diff --git a/manifest b/manifest index 1938e24d5e..c0ef6b6a13 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improve\stest\scoverage\sof\ssession\smodule. -D 2011-04-16T19:23:10.456 +C Further\scoverage\stests\sfor\sthe\ssession\smodule. +D 2011-04-18T07:36:27.686 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 7a4d9524721d40ef9ee26f93f9bd6a51dba106f2 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -100,13 +100,13 @@ F ext/rtree/sqlite3rtree.h 1af0899c63a688e272d69d8e746f24e76f10a3f0 F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 F ext/session/session1.test f5d9f2e362abe2563181389509822bda956516ee -F ext/session/session2.test c3e5f78d5eb988e35cc2ba9ce3678f706283cfdb +F ext/session/session2.test 99ca0da7ddb617d42bafd83adccf99f18ae0384b F ext/session/session3.test a7a9ce59b8d1e49e2cc23d81421ac485be0eea01 F ext/session/session4.test a6ed685da7a5293c5d6f99855bcf41dbc352ca84 F ext/session/session5.test 8fdfaf9dba28a2f1c6b89b06168bdab1fef2d478 F ext/session/session_common.tcl 1539d8973b2aea0025c133eb0cc4c89fcef541a5 -F ext/session/sessionfault.test 759060c36ef424919e3900b885b22aa15caf7f39 -F ext/session/sqlite3session.c 3475df4021c5260f795cf66f67233449795c06ea +F ext/session/sessionfault.test 401045278298a242cbc2e4bc986c102f01ff2180 +F ext/session/sqlite3session.c fd43b8cb35d8112fa77a9e9101f9efe7005e5e23 F ext/session/sqlite3session.h 665f5591562e3c71eb3d0da26f1a1efae26f7bcf F ext/session/test_session.c 311e5b9228374d0b5780448f289847ff1cf7d388 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x @@ -938,7 +938,7 @@ F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 3dfd1d63bddfa9bd9018eb00bee1d496379630b5 -R 57f77b8ed5537ccfd8e7f64bd8d648b6 +P f46d4b641d613c39a80b12106e6a6ac0efc8be83 +R bc07f4a1348864ef3dbdf87527d99ed2 U dan -Z 35862238c72a43b8ebb72adec800f600 +Z fcc600b67a0d6c899a275e81c6cbea0f diff --git a/manifest.uuid b/manifest.uuid index 387cde32ce..4c438b56bb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f46d4b641d613c39a80b12106e6a6ac0efc8be83 \ No newline at end of file +69a01c708bf044eacf21a8951fe9e7d9fb4332c5 \ No newline at end of file From 798693b2b1952827f95dd1a3ed9e2d1f0ce34cf1 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 18 Apr 2011 12:05:03 +0000 Subject: [PATCH 0054/1484] Fix some missing comments and other issues with session module code. FossilOrigin-Name: 20d7c280235201e519f296372f269e7cecda24da --- ext/session/sqlite3session.c | 177 +++++++++++++++++++++++------------ manifest | 12 +-- manifest.uuid | 2 +- 3 files changed, 126 insertions(+), 65 deletions(-) diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index 2232d21938..5a31a204f5 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -136,7 +136,7 @@ struct SessionTable { ** this structure stored in a SessionTable.aChange[] hash table. */ struct SessionChange { - int bInsert; /* True if row was inserted this session */ + int op; /* One of UPDATE, DELETE, INSERT */ int bIndirect; /* True if this change is "indirect" */ int nRecord; /* Number of bytes in buffer aRecord[] */ u8 *aRecord; /* Buffer containing old.* record */ @@ -290,29 +290,67 @@ static int sessionSerializeValue( return SQLITE_OK; } +/* +** This macro is used to calculate hash key values for data structures. In +** order to use this macro, the entire data structure must be represented +** as a series of unsigned integers. In order to calculate a hash-key value +** for a data structure represented as three such integers, the macro may +** then be used as follows: +** +** int hash_key_value; +** hash_key_value = HASH_APPEND(0, ); +** hash_key_value = HASH_APPEND(hash_key_value, ); +** hash_key_value = HASH_APPEND(hash_key_value, ); +** +** In practice, the data structures this macro is used for are the primary +** key values of modified rows. +*/ #define HASH_APPEND(hash, add) ((hash) << 3) ^ (hash) ^ (unsigned int)(add) + +/* +** Append the hash of the 64-bit integer passed as the second argument to the +** hash-key value passed as the first. Return the new hash-key value. +*/ static unsigned int sessionHashAppendI64(unsigned int h, i64 i){ h = HASH_APPEND(h, i & 0xFFFFFFFF); return HASH_APPEND(h, (i>>32)&0xFFFFFFFF); } + +/* +** Append the hash of the blob passed via the second and third arguments to +** the hash-key value passed as the first. Return the new hash-key value. +*/ static unsigned int sessionHashAppendBlob(unsigned int h, int n, const u8 *z){ int i; for(i=0; inBucket. +** new.* row currently available and, assuming no error occurs, writes it to +** *piHash before returning. If the primary key contains one or more NULL +** values, *pbNullPK is set to true before returning. +** +** If an error occurs, an SQLite error code is returned and the final values +** of *piHash asn *pbNullPK are undefined. Otherwise, SQLITE_OK is returned +** and the output variables are set as described above. */ -static unsigned int sessionPreupdateHash( +static int sessionPreupdateHash( sqlite3 *db, /* Database handle */ SessionTable *pTab, /* Session table handle */ int bNew, /* True to hash the new.* PK */ int *piHash, /* OUT: Hash value */ - int *pbNullPK + int *pbNullPK /* OUT: True if there are NULL values in PK */ ){ unsigned int h = 0; /* Hash value to return */ int i; /* Used to iterate through columns */ @@ -333,7 +371,7 @@ static unsigned int sessionPreupdateHash( if( rc!=SQLITE_OK ) return rc; eType = sqlite3_value_type(pVal); - h = HASH_APPEND(h, eType); + h = sessionHashAppendType(h, eType); if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){ i64 iVal; if( eType==SQLITE_INTEGER ){ @@ -356,7 +394,6 @@ static unsigned int sessionPreupdateHash( }else{ assert( eType==SQLITE_NULL ); *pbNullPK = 1; - return SQLITE_OK; } } } @@ -381,7 +418,7 @@ static int sessionSerialLen(u8 *a){ /* ** Based on the primary key values stored in change aRecord, calculate a -** hash key, assuming the has table has nBucket buckets. The hash keys +** hash key. Assume the has table has nBucket buckets. The hash keys ** calculated by this function are compatible with those calculated by ** sessionPreupdateHash(). */ @@ -409,7 +446,7 @@ static unsigned int sessionChangeHash( if( isPK ){ a++; - h = HASH_APPEND(h, eType); + h = sessionHashAppendType(h, eType); if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){ h = sessionHashAppendI64(h, sessionGetI64(a)); a += 8; @@ -426,20 +463,26 @@ static unsigned int sessionChangeHash( return (h % nBucket); } +/* +** Arguments aLeft and aRight are pointers to change records for table pTab. +** This function returns true if the two records apply to the same row (i.e. +** have the same values stored in the primary key columns), or false +** otherwise. +*/ static int sessionChangeEqual( - SessionTable *pTab, + SessionTable *pTab, /* Table used for PK definition */ u8 *aLeft, /* Change record */ u8 *aRight /* Change record */ ){ - u8 *a1 = aLeft; - u8 *a2 = aRight; - int i; + u8 *a1 = aLeft; /* Cursor to iterate through aLeft */ + u8 *a2 = aRight; /* Cursor to iterate through aRight */ + int iCol; /* Used to iterate through table columns */ - for(i=0; inCol; i++){ + for(iCol=0; iColnCol; iCol++){ int n1 = sessionSerialLen(a1); int n2 = sessionSerialLen(a2); - if( pTab->abPK[i] && (n1!=n2 || memcmp(a1, a2, n1)) ){ + if( pTab->abPK[iCol] && (n1!=n2 || memcmp(a1, a2, n1)) ){ return 0; } a1 += n1; @@ -449,18 +492,31 @@ static int sessionChangeEqual( return 1; } +/* +** Arguments aLeft and aRight both point to buffers containing change +** records with nCol columns. This function "merges" the two records into +** a single records which is written to the buffer at *paOut. *paOut is +** then set to point to one byte after the last byte written before +** returning. +** +** The merging of records is done as follows: For each column, if the +** aRight record contains a value for the column, copy the value from +** their. Otherwise, if aLeft contains a value, copy it. If neither +** record contains a value for a given column, then neither does the +** output record. +*/ static void sessionMergeRecord( u8 **paOut, - SessionTable *pTab, + int nCol, u8 *aLeft, u8 *aRight ){ - u8 *a1 = aLeft; - u8 *a2 = aRight; - u8 *aOut = *paOut; - int i; + u8 *a1 = aLeft; /* Cursor used to iterate through aLeft */ + u8 *a2 = aRight; /* Cursor used to iterate through aRight */ + u8 *aOut = *paOut; /* Output cursor */ + int iCol; /* Used to iterate from 0 to nCol */ - for(i=0; inCol; i++){ + for(iCol=0; iColnCol; i++){ - int eType = *a++; if( !pTab->abPK[i] ){ - switch( eType ){ - case SQLITE_INTEGER: - case SQLITE_FLOAT: - a += 8; - break; - - case SQLITE_TEXT: - case SQLITE_BLOB: { - int n; - a += sessionVarintGet(a, &n); - a += n; - break; - } - } + a += sessionSerialLen(a); }else{ sqlite3_value *pVal; /* Value returned by preupdate_new/old */ int rc; /* Error code from preupdate_new/old */ + int eType = *a++; /* Type of value from change record */ /* The following calls to preupdate_new() and preupdate_old() can not ** fail. This is because they cache their return values, and by the @@ -942,7 +1003,7 @@ static void sessionPreupdateOneChange( pChange->bIndirect = 1; } pChange->nRecord = nByte; - pChange->bInsert = (op==SQLITE_INSERT); + pChange->op = op; pChange->pNext = pTab->apChange[iHash]; pTab->apChange[iHash] = pChange; @@ -1606,8 +1667,8 @@ int sqlite3session_changeset( rc = sessionSelectBind(pSel, nCol, abPK, p); if( rc!=SQLITE_OK ) continue; if( sqlite3_step(pSel)==SQLITE_ROW ){ - int iCol; - if( p->bInsert ){ + if( p->op==SQLITE_INSERT ){ + int iCol; sessionAppendByte(&buf, SQLITE_INSERT, &rc); sessionAppendByte(&buf, p->bIndirect, &rc); for(iCol=0; iColbInsert ){ + }else if( p->op!=SQLITE_INSERT ){ /* A DELETE change */ sessionAppendByte(&buf, SQLITE_DELETE, &rc); sessionAppendByte(&buf, p->bIndirect, &rc); @@ -2784,12 +2845,12 @@ static int sessionChangeMerge( return SQLITE_NOMEM; } memset(pNew, 0, sizeof(SessionChange)); - pNew->bInsert = op2; + pNew->op = op2; pNew->bIndirect = bIndirect; pNew->nRecord = nRec; pNew->aRecord = aRec; }else{ - int op1 = pExist->bInsert; + int op1 = pExist->op; /* ** op1=INSERT, op2=INSERT -> Unsupported. Discard op2. @@ -2830,12 +2891,12 @@ static int sessionChangeMerge( if( op1==SQLITE_INSERT ){ /* INSERT + UPDATE */ u8 *a1 = aRec; assert( op2==SQLITE_UPDATE ); - pNew->bInsert = SQLITE_INSERT; + pNew->op = SQLITE_INSERT; sessionReadRecord(&a1, pTab->nCol, 0); - sessionMergeRecord(&aCsr, pTab, pExist->aRecord, a1); + sessionMergeRecord(&aCsr, pTab->nCol, pExist->aRecord, a1); }else if( op1==SQLITE_DELETE ){ /* DELETE + INSERT */ assert( op2==SQLITE_INSERT ); - pNew->bInsert = SQLITE_UPDATE; + pNew->op = SQLITE_UPDATE; if( 0==sessionMergeUpdate(&aCsr, pTab, pExist->aRecord, 0, aRec, 0) ){ sqlite3_free(pNew); pNew = 0; @@ -2846,15 +2907,15 @@ static int sessionChangeMerge( u8 *a2 = aRec; sessionReadRecord(&a1, pTab->nCol, 0); sessionReadRecord(&a2, pTab->nCol, 0); - pNew->bInsert = SQLITE_UPDATE; + pNew->op = SQLITE_UPDATE; if( 0==sessionMergeUpdate(&aCsr, pTab, aRec, pExist->aRecord, a1, a2) ){ sqlite3_free(pNew); pNew = 0; } }else{ /* UPDATE + DELETE */ assert( op1==SQLITE_UPDATE && op2==SQLITE_DELETE ); - pNew->bInsert = SQLITE_DELETE; - sessionMergeRecord(&aCsr, pTab, aRec, pExist->aRecord); + pNew->op = SQLITE_DELETE; + sessionMergeRecord(&aCsr, pTab->nCol, aRec, pExist->aRecord); } if( pNew ){ @@ -3006,7 +3067,7 @@ int sqlite3changeset_concat( for(i=0; inChange; i++){ SessionChange *p; for(p=pTab->apChange[i]; p; p=p->pNext){ - sessionAppendByte(&buf, p->bInsert, &rc); + sessionAppendByte(&buf, p->op, &rc); sessionAppendByte(&buf, p->bIndirect, &rc); sessionAppendBlob(&buf, p->aRecord, p->nRecord, &rc); } diff --git a/manifest b/manifest index c0ef6b6a13..5d77f78c46 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Further\scoverage\stests\sfor\sthe\ssession\smodule. -D 2011-04-18T07:36:27.686 +C Fix\ssome\smissing\scomments\sand\sother\sissues\swith\ssession\smodule\scode. +D 2011-04-18T12:05:03.122 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 7a4d9524721d40ef9ee26f93f9bd6a51dba106f2 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -106,7 +106,7 @@ F ext/session/session4.test a6ed685da7a5293c5d6f99855bcf41dbc352ca84 F ext/session/session5.test 8fdfaf9dba28a2f1c6b89b06168bdab1fef2d478 F ext/session/session_common.tcl 1539d8973b2aea0025c133eb0cc4c89fcef541a5 F ext/session/sessionfault.test 401045278298a242cbc2e4bc986c102f01ff2180 -F ext/session/sqlite3session.c fd43b8cb35d8112fa77a9e9101f9efe7005e5e23 +F ext/session/sqlite3session.c 04a5065d5b64f43f120113df170e96bb8db8e229 F ext/session/sqlite3session.h 665f5591562e3c71eb3d0da26f1a1efae26f7bcf F ext/session/test_session.c 311e5b9228374d0b5780448f289847ff1cf7d388 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x @@ -938,7 +938,7 @@ F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P f46d4b641d613c39a80b12106e6a6ac0efc8be83 -R bc07f4a1348864ef3dbdf87527d99ed2 +P 69a01c708bf044eacf21a8951fe9e7d9fb4332c5 +R b92955ca865aafd93c0b967b180f7cc1 U dan -Z fcc600b67a0d6c899a275e81c6cbea0f +Z 3095f8afd486ad0b7645eeb6cb4cbdcc diff --git a/manifest.uuid b/manifest.uuid index 4c438b56bb..521c05b9db 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -69a01c708bf044eacf21a8951fe9e7d9fb4332c5 \ No newline at end of file +20d7c280235201e519f296372f269e7cecda24da \ No newline at end of file From 77fc1d5bb4ffe5e423ae17b02b7f9dd66c4c41da Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 18 Apr 2011 15:47:08 +0000 Subject: [PATCH 0055/1484] Fix further missing comments and other minor issues in the session module code. FossilOrigin-Name: 99f0f35092b0b78b7016b21c242da263ab64b77b --- ext/session/sqlite3session.c | 171 ++++++++++++++++++++++++----------- manifest | 12 +-- manifest.uuid | 2 +- 3 files changed, 126 insertions(+), 59 deletions(-) diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index 5a31a204f5..50c436b8c4 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -645,20 +645,25 @@ static int sessionMergeUpdate( return 1; } -static void sessionPreupdateEqual( - sqlite3 *db, - SessionTable *pTab, - SessionChange *pChange, - int bNew, - int *pbEqual +/* +** This function is only called from within a pre-update-hook callback. +** It determines if the current pre-update-hook change affects the same row +** as the change stored in argument pChange. If so, it returns true. Otherwise +** if the pre-update-hook does not affect the same row as pChange, it returns +** false. +*/ +static int sessionPreupdateEqual( + sqlite3 *db, /* Database handle */ + SessionTable *pTab, /* Table associated with change */ + SessionChange *pChange, /* Change to compare to */ + int op /* Current pre-update operation */ ){ - int i; - u8 *a = pChange->aRecord; + int iCol; /* Used to iterate through columns */ + u8 *a = pChange->aRecord; /* Cursor used to scan change record */ - *pbEqual = 0; - - for(i=0; inCol; i++){ - if( !pTab->abPK[i] ){ + assert( op==SQLITE_INSERT || op==SQLITE_UPDATE || op==SQLITE_DELETE ); + for(iCol=0; iColnCol; iCol++){ + if( !pTab->abPK[iCol] ){ a += sessionSerialLen(a); }else{ sqlite3_value *pVal; /* Value returned by preupdate_new/old */ @@ -670,15 +675,15 @@ static void sessionPreupdateEqual( ** time control flows to here they have already been called once from ** within sessionPreupdateHash(). The first two asserts below verify ** this (that the method has already been called). */ - if( bNew ){ + if( op==SQLITE_INSERT ){ assert( db->pPreUpdate->pNewUnpacked || db->pPreUpdate->aNew ); - rc = sqlite3_preupdate_new(db, i, &pVal); + rc = sqlite3_preupdate_new(db, iCol, &pVal); }else{ assert( db->pPreUpdate->pUnpacked ); - rc = sqlite3_preupdate_old(db, i, &pVal); + rc = sqlite3_preupdate_old(db, iCol, &pVal); } assert( rc==SQLITE_OK ); - if( sqlite3_value_type(pVal)!=eType ) return; + if( sqlite3_value_type(pVal)!=eType ) return 0; /* A SessionChange object never has a NULL value in a PK column */ assert( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT @@ -689,32 +694,31 @@ static void sessionPreupdateEqual( i64 iVal = sessionGetI64(a); a += 8; if( eType==SQLITE_INTEGER ){ - if( sqlite3_value_int64(pVal)!=iVal ) return; + if( sqlite3_value_int64(pVal)!=iVal ) return 0; }else{ double rVal; assert( sizeof(iVal)==8 && sizeof(rVal)==8 ); memcpy(&rVal, &iVal, 8); - if( sqlite3_value_double(pVal)!=rVal ) return; + if( sqlite3_value_double(pVal)!=rVal ) return 0; } }else{ int n; const u8 *z; a += sessionVarintGet(a, &n); - if( sqlite3_value_bytes(pVal)!=n ) return; + if( sqlite3_value_bytes(pVal)!=n ) return 0; if( eType==SQLITE_TEXT ){ z = sqlite3_value_text(pVal); }else{ z = sqlite3_value_blob(pVal); } - if( memcmp(a, z, n) ) return; + if( memcmp(a, z, n) ) return 0; a += n; break; } } } - *pbEqual = 1; - return; + return 1; } /* @@ -768,7 +772,8 @@ static int sessionGrowHash(SessionTable *pTab){ ** not, SQLITE_SCHEMA is returned and none of the output variables are ** populated. ** -** Otherwise, if it is not NULL, variable *pzTab is set to point to a +** Otherwise, if they are not NULL, variable *pnCol is set to the number +** of columns in the database table and variable *pzTab is set to point to a ** nul-terminated copy of the table name. *pazCol (if not NULL) is set to ** point to an array of pointers to column names. And *pabPK (again, if not ** NULL) is set to point to an array of booleans - true if the corresponding @@ -778,8 +783,9 @@ static int sessionGrowHash(SessionTable *pTab){ ** ** CREATE TABLE tbl1(w, x, y, z, PRIMARY KEY(w, z)); ** -** Then the three output variables are populated as follows: +** Then the four output variables are populated as follows: ** +** *pnCol = 4 ** *pzTab = "tbl1" ** *pazCol = {"w", "x", "y", "z"} ** *pabPK = {1, 0, 0, 1} @@ -908,10 +914,18 @@ static int sessionInitTable(sqlite3_session *pSession, SessionTable *pTab){ return pSession->rc; } +/* +** This function is only called from with a pre-update-hook reporting a +** change on table pTab (attached to session pSession). The type of change +** (UPDATE, INSERT, DELETE) is specified by the first argument. +** +** Unless one is already present or an error occurs, an entry is added +** to the changed-rows hash table associated with table pTab. +*/ static void sessionPreupdateOneChange( - int op, - sqlite3_session *pSession, - SessionTable *pTab + int op, /* One of SQLITE_UPDATE, INSERT, DELETE */ + sqlite3_session *pSession, /* Session object pTab is attached to */ + SessionTable *pTab /* Table that change applies to */ ){ sqlite3 *db = pSession->db; int iHash; @@ -939,9 +953,7 @@ static void sessionPreupdateOneChange( /* Search the hash table for an existing record for this row. */ SessionChange *pC; for(pC=pTab->apChange[iHash]; pC; pC=pC->pNext){ - int bEqual; - sessionPreupdateEqual(db, pTab, pC, op==SQLITE_INSERT, &bEqual); - if( bEqual ) break; + if( sessionPreupdateEqual(db, pTab, pC, op) ) break; } if( pC==0 ){ @@ -1109,6 +1121,10 @@ int sqlite3session_create( return SQLITE_OK; } +/* +** Free the list of table objects passed as the first argument. The contents +** of the changed-rows hash tables are also deleted. +*/ void sessionDeleteTable(SessionTable *pList){ SessionTable *pNext; SessionTable *pTab; @@ -1492,14 +1508,20 @@ static int sessionAppendUpdate( return rc; } +/* +** Formulate and prepare a SELECT statement to retrieve a row from table +** zTab in database zDb based on its primary key. i.e. +** +** SELECT * FROM zDb.zTab WHERE pk1 = ? AND pk2 = ? AND ... +*/ static int sessionSelectStmt( sqlite3 *db, /* Database handle */ const char *zDb, /* Database name */ const char *zTab, /* Table name */ - int nCol, - const char **azCol, - u8 *abPK, - sqlite3_stmt **ppStmt + int nCol, /* Number of columns in table */ + const char **azCol, /* Names of table columns */ + u8 *abPK, /* PRIMARY KEY array */ + sqlite3_stmt **ppStmt /* OUT: Prepared SELECT statement */ ){ int rc = SQLITE_OK; int i; @@ -1527,11 +1549,19 @@ static int sessionSelectStmt( return rc; } +/* +** Bind the PRIMARY KEY values from the change passed in argument pChange +** to the SELECT statement passed as the first argument. The SELECT statement +** is as prepared by function sessionSelectStmt(). +** +** Return SQLITE_OK if all PK values are successfully bound, or an SQLite +** error code (e.g. SQLITE_NOMEM) otherwise. +*/ static int sessionSelectBind( - sqlite3_stmt *pSelect, - int nCol, - u8 *abPK, - SessionChange *pChange + sqlite3_stmt *pSelect, /* SELECT from sessionSelectStmt() */ + int nCol, /* Number of columns in table */ + u8 *abPK, /* PRIMARY KEY array */ + SessionChange *pChange /* Change structure */ ){ int i; int rc = SQLITE_OK; @@ -1592,6 +1622,12 @@ static int sessionSelectBind( return rc; } +/* +** This function is a no-op if *pRc is set to other than SQLITE_OK when it +** is called. Otherwise, append a serialized table header (part of the binary +** changeset format) to buffer *pBuf. If an error occurs, set *pRc to an +** SQLite error code before returning. +*/ static void sessionAppendTableHdr( SessionBuffer *pBuf, SessionTable *pTab, @@ -1832,10 +1868,26 @@ static int sessionReadRecord( return SQLITE_OK; } +/* +** Advance the changeset iterator to the next change. +** +** If both paRec and pnRec are NULL, then this function works like the public +** API sqlite3changeset_next(). If SQLITE_ROW is returned, then the +** sqlite3changeset_new() and old() APIs may be used to query for values. +** +** Otherwise, if paRec and pnRec are not NULL, then a pointer to the change +** record is written to *paRec before returning and the number of bytes in +** the record to *pnRec. +** +** Either way, this function returns SQLITE_ROW if the iterator is +** successfully advanced to the next change in the changeset, an SQLite +** error code if an error occurs, or SQLITE_DONE if there are no further +** changes in the changeset. +*/ static int sessionChangesetNext( - sqlite3_changeset_iter *p, - u8 **paRec, - int *pnRec + sqlite3_changeset_iter *p, /* Changeset iterator */ + u8 **paRec, /* If non-NULL, store record pointer here */ + int *pnRec /* If non-NULL, store size of record here */ ){ u8 *aChange; int i; @@ -1918,7 +1970,7 @@ int sqlite3changeset_next(sqlite3_changeset_iter *p){ /* ** The following function extracts information on the current change -** from a changeset iterator. They may only be called after changeset_next() +** from a changeset iterator. It may only be called after changeset_next() ** has returned SQLITE_ROW. */ int sqlite3changeset_op( @@ -1935,6 +1987,12 @@ int sqlite3changeset_op( return SQLITE_OK; } +/* +** Return information regarding the PRIMARY KEY and number of columns in +** the database table affected by the change that pIter currently points +** to. This function may only be called after changeset_next() returns +** SQLITE_ROW. +*/ int sqlite3changeset_pk( sqlite3_changeset_iter *pIter, /* Iterator object */ unsigned char **pabPK, /* OUT: Array of boolean - true for PK cols */ @@ -2828,14 +2886,19 @@ int sqlite3changeset_apply( return rc; } +/* +** This function is called to merge two changes to the same row together as +** part of an sqlite3changeset_concat() operation. A new change object is +** allocated and a pointer to it stored in *ppNew. +*/ static int sessionChangeMerge( - SessionTable *pTab, - SessionChange *pExist, - int op2, - int bIndirect, - u8 *aRec, - int nRec, - SessionChange **ppNew + SessionTable *pTab, /* Table structure */ + SessionChange *pExist, /* Existing change */ + int op2, /* Second change operation */ + int bIndirect, /* True if second change is indirect */ + u8 *aRec, /* Second change record */ + int nRec, /* Number of bytes in aRec */ + SessionChange **ppNew /* OUT: Merged change */ ){ SessionChange *pNew = 0; @@ -2929,10 +2992,14 @@ static int sessionChangeMerge( return SQLITE_OK; } +/* +** Add all changes in the changeset passed via the first two arguments to +** hash tables. +*/ int sessionConcatChangeset( - int nChangeset, - void *pChangeset, - SessionTable **ppTabList + int nChangeset, /* Number of bytes in pChangeset */ + void *pChangeset, /* Changeset buffer */ + SessionTable **ppTabList /* IN/OUT: List of table objects */ ){ u8 *aRec; int nRec; diff --git a/manifest b/manifest index 5d77f78c46..f38f5e51b4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\ssome\smissing\scomments\sand\sother\sissues\swith\ssession\smodule\scode. -D 2011-04-18T12:05:03.122 +C Fix\sfurther\smissing\scomments\sand\sother\sminor\sissues\sin\sthe\ssession\smodule\scode. +D 2011-04-18T15:47:08.694 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 7a4d9524721d40ef9ee26f93f9bd6a51dba106f2 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -106,7 +106,7 @@ F ext/session/session4.test a6ed685da7a5293c5d6f99855bcf41dbc352ca84 F ext/session/session5.test 8fdfaf9dba28a2f1c6b89b06168bdab1fef2d478 F ext/session/session_common.tcl 1539d8973b2aea0025c133eb0cc4c89fcef541a5 F ext/session/sessionfault.test 401045278298a242cbc2e4bc986c102f01ff2180 -F ext/session/sqlite3session.c 04a5065d5b64f43f120113df170e96bb8db8e229 +F ext/session/sqlite3session.c 26de50c3e34d89ae62e97024ad07e772e1c52db2 F ext/session/sqlite3session.h 665f5591562e3c71eb3d0da26f1a1efae26f7bcf F ext/session/test_session.c 311e5b9228374d0b5780448f289847ff1cf7d388 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x @@ -938,7 +938,7 @@ F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 69a01c708bf044eacf21a8951fe9e7d9fb4332c5 -R b92955ca865aafd93c0b967b180f7cc1 +P 20d7c280235201e519f296372f269e7cecda24da +R 22fa2c52781f892ef560f2c8f63b1707 U dan -Z 3095f8afd486ad0b7645eeb6cb4cbdcc +Z e6f0d0d675f579cb5b46b0fe2c73f457 diff --git a/manifest.uuid b/manifest.uuid index 521c05b9db..240a76a7a9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -20d7c280235201e519f296372f269e7cecda24da \ No newline at end of file +99f0f35092b0b78b7016b21c242da263ab64b77b \ No newline at end of file From e437ca5ec0af264b3f299409d18c381800414082 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 11 Jul 2011 19:45:38 +0000 Subject: [PATCH 0056/1484] Modifications so that the sessions extension works with blob handles. FossilOrigin-Name: 82ac16c4f873d3bd7c22f36ba7b974b4903a2d50 --- ext/session/session6.test | 90 +++++++++++++++++++++++++++++++++++++++ manifest | 19 +++++---- manifest.uuid | 2 +- src/vdbeapi.c | 2 +- src/vdbeaux.c | 6 ++- src/vdbeblob.c | 28 ++++++++++++ 6 files changed, 135 insertions(+), 12 deletions(-) create mode 100644 ext/session/session6.test diff --git a/ext/session/session6.test b/ext/session/session6.test new file mode 100644 index 0000000000..8a1f172cde --- /dev/null +++ b/ext/session/session6.test @@ -0,0 +1,90 @@ +# 2011 July 11 +# +# 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 regression tests for SQLite sessions extension. +# Specifically, it tests that sessions work when the database is modified +# using incremental blob handles. +# + +if {![info exists testdir]} { + set testdir [file join [file dirname [info script]] .. .. test] +} +source [file join [file dirname [info script]] session_common.tcl] +source $testdir/tester.tcl +ifcapable !session {finish_test; return} + +set testprefix session6 + +proc do_then_apply_tcl {tcl {dbname main}} { + proc xConflict args { return "OMIT" } + set rc [catch { + sqlite3session S db $dbname + db eval "SELECT name FROM $dbname.sqlite_master WHERE type = 'table'" { + S attach $name + } + eval $tcl + sqlite3changeset_apply db2 [S changeset] xConflict + } msg] + + catch { S delete } + if {$rc} {error $msg} +} + +test_sqlite3_log x +proc x {args} {puts $args} + +forcedelete test.db2 +sqlite3 db2 test.db2 + +do_common_sql { + CREATE TABLE t1(a PRIMARY KEY, b); + CREATE TABLE t2(c PRIMARY KEY, d); +} + +# Test a blob update. +# +do_test 1.1 { + do_then_apply_tcl { + db eval { INSERT INTO t1 VALUES(1, 'helloworld') } + db eval { INSERT INTO t2 VALUES(2, 'onetwothree') } + } + compare_db db db2 +} {} +do_test 1.2 { + do_then_apply_tcl { + set fd [db incrblob t1 b 1] + puts -nonewline $fd 1234567890 + close $fd + } + compare_db db db2 +} {} + +# Test an attached database. +# +do_test 2.1 { + forcedelete test.db3 + file copy test.db2 test.db3 + execsql { ATTACH 'test.db3' AS aux; } + + do_then_apply_tcl { + set fd [db incrblob aux t2 d 1] + puts -nonewline $fd fourfivesix + close $fd + } aux + + sqlite3 db3 test.db3 + compare_db db2 db3 +} {} + + +db3 close +db2 close + +finish_test diff --git a/manifest b/manifest index 8bdd0ba57a..31ce25fa38 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Pull\sthe\slatest\sversion\s3.7.7\srelease-candidate\schanges\sinto\sthe\nsessions\sbranch. -D 2011-06-23T17:40:15.467 +C Modifications\sso\sthat\sthe\ssessions\sextension\sworks\swith\sblob\shandles. +D 2011-07-11T19:45:38.954 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in c1d7a7f4fd8da6b1815032efca950e3d5125407e F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -107,6 +107,7 @@ F ext/session/session2.test 99ca0da7ddb617d42bafd83adccf99f18ae0384b F ext/session/session3.test a7a9ce59b8d1e49e2cc23d81421ac485be0eea01 F ext/session/session4.test a6ed685da7a5293c5d6f99855bcf41dbc352ca84 F ext/session/session5.test 8fdfaf9dba28a2f1c6b89b06168bdab1fef2d478 +F ext/session/session6.test 443789bc2fca12e4f7075cf692c60b8a2bea1a26 F ext/session/session_common.tcl 1539d8973b2aea0025c133eb0cc4c89fcef541a5 F ext/session/sessionfault.test 401045278298a242cbc2e4bc986c102f01ff2180 F ext/session/sqlite3session.c 26de50c3e34d89ae62e97024ad07e772e1c52db2 @@ -251,9 +252,9 @@ F src/vacuum.c 05513dca036a1e7848fe18d5ed1265ac0b32365e F src/vdbe.c df52db6162fd94767b76bb4e9a7cb9207e83086f F src/vdbe.h 322af148cceef120bb1ec9cff7f122e76abf94da F src/vdbeInt.h 3de6588b36c833969aebab202e1766d586c37ec2 -F src/vdbeapi.c 1d947da083c24e8bf61823f02f619a1f4a682100 -F src/vdbeaux.c db3d4eedccea5add714dfb8b10f70d0f8d692db5 -F src/vdbeblob.c f024f0bf420f36b070143c32b15cc7287341ffd3 +F src/vdbeapi.c 432a8a194accb9fe9fae45338f210174c6c961b4 +F src/vdbeaux.c bb86d48ce99c288d17e8d79711713399c21f0a8d +F src/vdbeblob.c a547f286b651641bdb43a567af66d0e776a39ea2 F src/vdbemem.c 0498796b6ffbe45e32960d6a1f5adfb6e419883b F src/vdbetrace.c 5d0dc3d5fd54878cc8d6d28eb41deb8d5885b114 F src/vtab.c 901791a47318c0562cd0c676a2c6ff1bc530e582 @@ -960,7 +961,7 @@ F tool/symbols.sh bc2a3709940d47c8ac8e0a1fdf17ec801f015a00 F tool/tostr.awk 11760e1b94a5d3dcd42378f3cc18544c06cfa576 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh 347d974d143cf132f953b565fbc03026f19fcb4d -P 5d95b42946b5cf0346164aebe0a8c4f37527bc31 b61a76a53af04f731fe7617f7b6b4fb2aef6587b -R 5b9118bd8782ff0e4b99f3cb89f8be24 -U drh -Z 3edc7355d0a27e1ff60419d5d75c34a3 +P 840bf9c2d92192ee3cc2aa7c0e9bdb805a066fd4 +R c823c2479e73fc426d6fab6fb150638b +U dan +Z 6339a08530525dea9c6675e0fc9a27f5 diff --git a/manifest.uuid b/manifest.uuid index 6c62bceba4..fecbc08bba 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -840bf9c2d92192ee3cc2aa7c0e9bdb805a066fd4 \ No newline at end of file +82ac16c4f873d3bd7c22f36ba7b974b4903a2d50 \ No newline at end of file diff --git a/src/vdbeapi.c b/src/vdbeapi.c index f7b3b41623..136a8cd168 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -1389,7 +1389,7 @@ int sqlite3_preupdate_old(sqlite3 *db, int iIdx, sqlite3_value **ppValue){ */ int sqlite3_preupdate_count(sqlite3 *db){ PreUpdate *p = db->pPreUpdate; - return (p ? p->pCsr->nField : 0); + return (p ? p->keyinfo.nField : 0); } #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ diff --git a/src/vdbeaux.c b/src/vdbeaux.c index a45f7a2892..8c442fce51 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -3274,13 +3274,17 @@ void sqlite3VdbePreUpdateHook( iKey2 = iKey1; } + assert( pCsr->nField==pTab->nCol + || (pCsr->nField==pTab->nCol+1 && op==SQLITE_DELETE && iReg==-1) + ); + preupdate.v = v; preupdate.pCsr = pCsr; preupdate.op = op; preupdate.iNewReg = iReg; preupdate.keyinfo.db = db; preupdate.keyinfo.enc = ENC(db); - preupdate.keyinfo.nField = pCsr->nField; + preupdate.keyinfo.nField = pTab->nCol; preupdate.iKey1 = iKey1; preupdate.iKey2 = iKey2; preupdate.iPKey = pTab->iPKey; diff --git a/src/vdbeblob.c b/src/vdbeblob.c index a8728e6d25..4dc9ef4fff 100644 --- a/src/vdbeblob.c +++ b/src/vdbeblob.c @@ -30,6 +30,8 @@ struct Incrblob { BtCursor *pCsr; /* Cursor pointing at blob row */ sqlite3_stmt *pStmt; /* Statement holding cursor open */ sqlite3 *db; /* The associated database */ + char *zDb; /* Database name */ + Table *pTab; /* Table object */ }; @@ -194,6 +196,8 @@ int sqlite3_blob_open( sqlite3BtreeLeaveAll(db); goto blob_open_out; } + pBlob->pTab = pTab; + pBlob->zDb = db->aDb[sqlite3SchemaToIndex(db, pTab->pSchema)].zName; /* Now search pTab for the exact column. */ for(iCol=0; iColnCol; iCol++) { @@ -386,6 +390,30 @@ static int blobReadWrite( */ assert( db == v->db ); sqlite3BtreeEnterCursor(p->pCsr); + +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK + if( xCall==sqlite3BtreePutData ){ + /* If a pre-update hook is registered and this is a write cursor, + ** invoke it here. + ** + ** TODO: The preupdate-hook is passed SQLITE_DELETE, even though this + ** operation should really be an SQLITE_UPDATE. This is probably + ** incorrect, but is convenient because at this point the new.* values + ** are not easily obtainable. And for the sessions module, an + ** SQLITE_UPDATE where the PK columns do not change is handled in the + ** same way as an SQLITE_DELETE (the SQLITE_DELETE code is actually + ** slightly more efficient). Since you cannot write to a PK column + ** using the incremental-blob API, this works. For the sessions module + ** anyhow. + */ + sqlite3_int64 iKey; + sqlite3BtreeKeySize(p->pCsr, &iKey); + sqlite3VdbePreUpdateHook( + v, v->apCsr[0], SQLITE_DELETE, p->zDb, p->pTab, iKey, -1 + ); + } +#endif + rc = xCall(p->pCsr, iOffset+p->iOffset, n, z); sqlite3BtreeLeaveCursor(p->pCsr); if( rc==SQLITE_ABORT ){ From 40368988da8bd6125a459e98fe6af1f5ecece54c Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 13 Jul 2011 15:21:02 +0000 Subject: [PATCH 0057/1484] Add the xFilter callback to the sqlite3changeset_apply() function. This callback allows the application to accept or reject changes on a per-table basis when applying a changeset. FossilOrigin-Name: 282474c42f24f0e66c69b576b72ef8ce764d49e2 --- ext/session/sqlite3session.c | 79 +++++++++++++++++++++--------------- ext/session/sqlite3session.h | 42 ++++++++++++------- ext/session/test_session.c | 43 ++++++++++++++++---- manifest | 16 ++++---- manifest.uuid | 2 +- 5 files changed, 118 insertions(+), 64 deletions(-) diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index 50c436b8c4..78d2b6d86c 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -2756,6 +2756,10 @@ int sqlite3changeset_apply( sqlite3 *db, /* Apply change to "main" db of this handle */ int nChangeset, /* Size of changeset in bytes */ void *pChangeset, /* Changeset blob */ + int(*xFilter)( + void *pCtx, /* Copy of sixth arg to _apply() */ + const char *zTab /* Table name */ + ), int(*xConflict)( void *pCtx, /* Copy of fifth arg to _apply() */ int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */ @@ -2788,7 +2792,6 @@ int sqlite3changeset_apply( if( zTab==0 || sqlite3_strnicmp(zNew, zTab, nTab+1) ){ u8 *abPK; - schemaMismatch = 0; sqlite3_free((char*)sApply.azCol); /* cast works around VC++ bug */ sqlite3_finalize(sApply.pDelete); sqlite3_finalize(sApply.pUpdate); @@ -2797,40 +2800,50 @@ int sqlite3changeset_apply( memset(&sApply, 0, sizeof(sApply)); sApply.db = db; - sqlite3changeset_pk(pIter, &abPK, 0); - rc = sessionTableInfo( - db, "main", zNew, &sApply.nCol, &zTab, &sApply.azCol, &sApply.abPK - ); - if( rc!=SQLITE_OK ) break; - - if( sApply.nCol==0 ){ - schemaMismatch = 1; - sqlite3_log(SQLITE_SCHEMA, - "sqlite3changeset_apply(): no such table: %s", zTab + /* If an xFilter() callback was specified, invoke it now. If the + ** xFilter callback returns zero, skip this table. If it returns + ** non-zero, proceed. */ + schemaMismatch = (xFilter && (0==xFilter(pCtx, zNew))); + if( schemaMismatch ){ + zTab = sqlite3_mprintf("%s", zNew); + nTab = strlen(zTab); + sApply.azCol = (const char **)zTab; + }else{ + sqlite3changeset_pk(pIter, &abPK, 0); + rc = sessionTableInfo( + db, "main", zNew, &sApply.nCol, &zTab, &sApply.azCol, &sApply.abPK ); + if( rc!=SQLITE_OK ) break; + + if( sApply.nCol==0 ){ + schemaMismatch = 1; + sqlite3_log(SQLITE_SCHEMA, + "sqlite3changeset_apply(): no such table: %s", zTab + ); + } + else if( sApply.nCol!=nCol ){ + schemaMismatch = 1; + sqlite3_log(SQLITE_SCHEMA, + "sqlite3changeset_apply(): table %s has %d columns, expected %d", + zTab, sApply.nCol, nCol + ); + } + else if( memcmp(sApply.abPK, abPK, nCol)!=0 ){ + schemaMismatch = 1; + sqlite3_log(SQLITE_SCHEMA, "sqlite3changeset_apply(): " + "primary key mismatch for table %s", zTab + ); + } + else if( + (rc = sessionSelectRow(db, zTab, &sApply)) + || (rc = sessionUpdateRow(db, zTab, &sApply)) + || (rc = sessionDeleteRow(db, zTab, &sApply)) + || (rc = sessionInsertRow(db, zTab, &sApply)) + ){ + break; + } + nTab = sqlite3Strlen30(zTab); } - else if( sApply.nCol!=nCol ){ - schemaMismatch = 1; - sqlite3_log(SQLITE_SCHEMA, - "sqlite3changeset_apply(): table %s has %d columns, expected %d", - zTab, sApply.nCol, nCol - ); - } - else if( memcmp(sApply.abPK, abPK, nCol)!=0 ){ - schemaMismatch = 1; - sqlite3_log(SQLITE_SCHEMA, - "sqlite3changeset_apply(): primary key mismatch for table %s", zTab - ); - } - else if( - (rc = sessionSelectRow(db, zTab, &sApply)) - || (rc = sessionUpdateRow(db, zTab, &sApply)) - || (rc = sessionDeleteRow(db, zTab, &sApply)) - || (rc = sessionInsertRow(db, zTab, &sApply)) - ){ - break; - } - nTab = sqlite3Strlen30(zTab); } /* If there is a schema mismatch on the current table, proceed to the diff --git a/ext/session/sqlite3session.h b/ext/session/sqlite3session.h index 38164401f4..d8db1d6137 100644 --- a/ext/session/sqlite3session.h +++ b/ext/session/sqlite3session.h @@ -610,9 +610,19 @@ int sqlite3changeset_concat( ** "main" database attached to handle db with the changes found in the ** changeset passed via the second and third arguments. ** -** For each change in the changeset, this function tests that the target -** database contains a compatible table. A table is considered compatible -** if all of the following are true: +** The fourth argument (xFilter) passed to this function is the "filter +** callback". If it is not NULL, then for each table affected by at least one +** change in the changeset, the filter callback is invoked with +** the table name as the second argument, and a copy of the context pointer +** passed as the sixth argument to this function as the first. If the "filter +** callback" returns zero, then no attempt is made to apply any changes to +** the table. Otherwise, if the return value is non-zero or the xFilter +** argument to this function is NULL, all changes related to the table are +** attempted. +** +** For each table that is not excluded by the filter callback, this function +** tests that the target database contains a compatible table. A table is +** considered compatible if all of the following are true: ** **
    **
  • The table has the same name as the name recorded in the @@ -623,17 +633,17 @@ int sqlite3changeset_concat( ** recorded in the changeset. **
** -** If there is no compatible table, it is not an error, but the change is -** not applied. A warning message is issued via the sqlite3_log() mechanism -** with the error code SQLITE_SCHEMA. At most one such warning is issued for -** each table in the changeset. +** If there is no compatible table, it is not an error, but none of the +** changes associated with the table are applied. A warning message is issued +** via the sqlite3_log() mechanism with the error code SQLITE_SCHEMA. At most +** one such warning is issued for each table in the changeset. ** -** Otherwise, if there is a compatible table, an attempt is made to modify -** the table contents according to the UPDATE, INSERT or DELETE change. -** If a change cannot be applied cleanly, the conflict handler function -** passed as the fourth argument to sqlite3changeset_apply() may be invoked. -** A description of exactly when the conflict handler is invoked for each -** type of change is below. +** For each change for which there is a compatible table, an attempt is made +** to modify the table contents according to the UPDATE, INSERT or DELETE +** change. If a change cannot be applied cleanly, the conflict handler +** function passed as the fifth argument to sqlite3changeset_apply() may be +** invoked. A description of exactly when the conflict handler is invoked for +** each type of change is below. ** ** Each time the conflict handler function is invoked, it must return one ** of [SQLITE_CHANGESET_OMIT], [SQLITE_CHANGESET_ABORT] or @@ -729,8 +739,12 @@ int sqlite3changeset_apply( sqlite3 *db, /* Apply change to "main" db of this handle */ int nChangeset, /* Size of changeset in bytes */ void *pChangeset, /* Changeset blob */ + int(*xFilter)( + void *pCtx, /* Copy of sixth arg to _apply() */ + const char *zTab /* Table name */ + ), int(*xConflict)( - void *pCtx, /* Copy of fifth arg to _apply() */ + void *pCtx, /* Copy of sixth arg to _apply() */ int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */ sqlite3_changeset_iter *p /* Handle describing change and conflict */ ), diff --git a/ext/session/test_session.c b/ext/session/test_session.c index 0993073328..9817b3c2f4 100644 --- a/ext/session/test_session.c +++ b/ext/session/test_session.c @@ -185,7 +185,8 @@ static void test_append_value(Tcl_Obj *pList, sqlite3_value *pVal){ typedef struct TestConflictHandler TestConflictHandler; struct TestConflictHandler { Tcl_Interp *interp; - Tcl_Obj *pScript; + Tcl_Obj *pConflictScript; + Tcl_Obj *pFilterScript; }; static int test_obj_eq_string(Tcl_Obj *p, const char *z){ @@ -199,6 +200,29 @@ static int test_obj_eq_string(Tcl_Obj *p, const char *z){ return (nObj==n && (n==0 || 0==memcmp(zObj, z, n))); } +static int test_filter_handler( + void *pCtx, /* Pointer to TestConflictHandler structure */ + const char *zTab /* Table name */ +){ + TestConflictHandler *p = (TestConflictHandler *)pCtx; + int res = 1; + Tcl_Obj *pEval; + Tcl_Interp *interp = p->interp; + + pEval = Tcl_DuplicateObj(p->pFilterScript); + Tcl_IncrRefCount(pEval); + + if( TCL_OK!=Tcl_ListObjAppendElement(0, pEval, Tcl_NewStringObj(zTab, -1)) + || TCL_OK!=Tcl_EvalObjEx(interp, pEval, TCL_EVAL_GLOBAL) + || TCL_OK!=Tcl_GetIntFromObj(interp, Tcl_GetObjResult(interp), &res) + ){ + Tcl_BackgroundError(interp); + } + + Tcl_DecrRefCount(pEval); + return res; +} + static int test_conflict_handler( void *pCtx, /* Pointer to TestConflictHandler structure */ int eConf, /* DATA, MISSING, CONFLICT, CONSTRAINT */ @@ -213,7 +237,7 @@ static int test_conflict_handler( const char *zTab; /* Name of table conflict is on */ int nCol; /* Number of columns in table zTab */ - pEval = Tcl_DuplicateObj(p->pScript); + pEval = Tcl_DuplicateObj(p->pConflictScript); Tcl_IncrRefCount(pEval); sqlite3changeset_op(pIter, &zTab, &nCol, &op, 0); @@ -342,7 +366,7 @@ static int test_conflict_handler( } /* -** sqlite3changeset_apply DB CHANGESET SCRIPT +** sqlite3changeset_apply DB CHANGESET CONFLICT-SCRIPT ?FILTER-SCRIPT? */ static int test_sqlite3changeset_apply( void * clientData, @@ -357,8 +381,10 @@ static int test_sqlite3changeset_apply( int nChangeset; /* Size of buffer aChangeset in bytes */ TestConflictHandler ctx; - if( objc!=4 ){ - Tcl_WrongNumArgs(interp, 1, objv, "DB CHANGESET SCRIPT"); + if( objc!=4 && objc!=5 ){ + Tcl_WrongNumArgs(interp, 1, objv, + "DB CHANGESET CONFLICT-SCRIPT ?FILTER-SCRIPT?" + ); return TCL_ERROR; } if( 0==Tcl_GetCommandInfo(interp, Tcl_GetString(objv[1]), &info) ){ @@ -367,11 +393,12 @@ static int test_sqlite3changeset_apply( } db = *(sqlite3 **)info.objClientData; pChangeset = (void *)Tcl_GetByteArrayFromObj(objv[2], &nChangeset); - ctx.pScript = objv[3]; + ctx.pConflictScript = objv[3]; + ctx.pFilterScript = objc==5 ? objv[4] : 0; ctx.interp = interp; - rc = sqlite3changeset_apply( - db, nChangeset, pChangeset, test_conflict_handler, (void *)&ctx + rc = sqlite3changeset_apply(db, nChangeset, pChangeset, + (objc==5) ? test_filter_handler : 0, test_conflict_handler, (void *)&ctx ); if( rc!=SQLITE_OK ){ return test_session_error(interp, rc); diff --git a/manifest b/manifest index 31ce25fa38..f77afa1ffe 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Modifications\sso\sthat\sthe\ssessions\sextension\sworks\swith\sblob\shandles. -D 2011-07-11T19:45:38.954 +C Add\sthe\sxFilter\scallback\sto\sthe\ssqlite3changeset_apply()\sfunction.\sThis\scallback\sallows\sthe\sapplication\sto\saccept\sor\sreject\schanges\son\sa\sper-table\sbasis\swhen\sapplying\sa\schangeset. +D 2011-07-13T15:21:02.741 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in c1d7a7f4fd8da6b1815032efca950e3d5125407e F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -110,9 +110,9 @@ F ext/session/session5.test 8fdfaf9dba28a2f1c6b89b06168bdab1fef2d478 F ext/session/session6.test 443789bc2fca12e4f7075cf692c60b8a2bea1a26 F ext/session/session_common.tcl 1539d8973b2aea0025c133eb0cc4c89fcef541a5 F ext/session/sessionfault.test 401045278298a242cbc2e4bc986c102f01ff2180 -F ext/session/sqlite3session.c 26de50c3e34d89ae62e97024ad07e772e1c52db2 -F ext/session/sqlite3session.h 665f5591562e3c71eb3d0da26f1a1efae26f7bcf -F ext/session/test_session.c 311e5b9228374d0b5780448f289847ff1cf7d388 +F ext/session/sqlite3session.c c05d28332fcdd66c82de85f5459d71554e2259d7 +F ext/session/sqlite3session.h f34905c818569779ddaea1bbef43469177614c69 +F ext/session/test_session.c 209f13fa8f4a597ffcc15fd0f8a3f27ed079c5e5 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F main.mk f56d9895882f5cdd9f9f9ba8f8a679e9202288c1 @@ -961,7 +961,7 @@ F tool/symbols.sh bc2a3709940d47c8ac8e0a1fdf17ec801f015a00 F tool/tostr.awk 11760e1b94a5d3dcd42378f3cc18544c06cfa576 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh 347d974d143cf132f953b565fbc03026f19fcb4d -P 840bf9c2d92192ee3cc2aa7c0e9bdb805a066fd4 -R c823c2479e73fc426d6fab6fb150638b +P 82ac16c4f873d3bd7c22f36ba7b974b4903a2d50 +R c22fa4ebad64b5fe1347a3f0a2dcb7e8 U dan -Z 6339a08530525dea9c6675e0fc9a27f5 +Z 6a509799e9e665bc4a33861bc6dba39f diff --git a/manifest.uuid b/manifest.uuid index fecbc08bba..527039d08d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -82ac16c4f873d3bd7c22f36ba7b974b4903a2d50 \ No newline at end of file +282474c42f24f0e66c69b576b72ef8ce764d49e2 \ No newline at end of file From 4f52804206ab97c057f7f0a6a9e078a5c9555867 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 15 Jul 2011 19:11:32 +0000 Subject: [PATCH 0058/1484] Add a few casts required by 64-bit VS2010 to the sessions code. FossilOrigin-Name: 5ac4a06111b5fad5f58c20ef5d2b65aeb23e105a --- ext/session/sqlite3session.c | 10 +++++----- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index 78d2b6d86c..577556ee92 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -1637,7 +1637,7 @@ static void sessionAppendTableHdr( sessionAppendByte(pBuf, 'T', pRc); sessionAppendVarint(pBuf, pTab->nCol, pRc); sessionAppendBlob(pBuf, pTab->abPK, pTab->nCol, pRc); - sessionAppendBlob(pBuf, (u8 *)pTab->zName, strlen(pTab->zName)+1, pRc); + sessionAppendBlob(pBuf, (u8 *)pTab->zName, (int)strlen(pTab->zName)+1, pRc); } /* @@ -1951,7 +1951,7 @@ static int sessionChangesetNext( if( p->rc!=SQLITE_OK ) return p->rc; } - if( pnRec ){ *pnRec = aChange - *paRec; } + if( pnRec ){ *pnRec = (int)(aChange - *paRec); } p->pNext = aChange; return SQLITE_ROW; } @@ -2806,7 +2806,7 @@ int sqlite3changeset_apply( schemaMismatch = (xFilter && (0==xFilter(pCtx, zNew))); if( schemaMismatch ){ zTab = sqlite3_mprintf("%s", zNew); - nTab = strlen(zTab); + nTab = (int)strlen(zTab); sApply.azCol = (const char **)zTab; }else{ sqlite3changeset_pk(pIter, &abPK, 0); @@ -2995,7 +2995,7 @@ static int sessionChangeMerge( } if( pNew ){ - pNew->nRecord = (aCsr - pNew->aRecord); + pNew->nRecord = (int)(aCsr - pNew->aRecord); } sqlite3_free(pExist); } @@ -3042,7 +3042,7 @@ int sessionConcatChangeset( if( !pTab || zNew!=pTab->zName ){ /* Search the list for a matching table */ - int nNew = strlen(zNew); + int nNew = (int)strlen(zNew); u8 *abPK; sqlite3changeset_pk(pIter, &abPK, 0); diff --git a/manifest b/manifest index f77afa1ffe..02f04f5c40 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sxFilter\scallback\sto\sthe\ssqlite3changeset_apply()\sfunction.\sThis\scallback\sallows\sthe\sapplication\sto\saccept\sor\sreject\schanges\son\sa\sper-table\sbasis\swhen\sapplying\sa\schangeset. -D 2011-07-13T15:21:02.741 +C Add\sa\sfew\scasts\srequired\sby\s64-bit\sVS2010\sto\sthe\ssessions\scode. +D 2011-07-15T19:11:32.763 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in c1d7a7f4fd8da6b1815032efca950e3d5125407e F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -110,7 +110,7 @@ F ext/session/session5.test 8fdfaf9dba28a2f1c6b89b06168bdab1fef2d478 F ext/session/session6.test 443789bc2fca12e4f7075cf692c60b8a2bea1a26 F ext/session/session_common.tcl 1539d8973b2aea0025c133eb0cc4c89fcef541a5 F ext/session/sessionfault.test 401045278298a242cbc2e4bc986c102f01ff2180 -F ext/session/sqlite3session.c c05d28332fcdd66c82de85f5459d71554e2259d7 +F ext/session/sqlite3session.c b31221e6e068476f736e8aaf5c7b66895d1b16f4 F ext/session/sqlite3session.h f34905c818569779ddaea1bbef43469177614c69 F ext/session/test_session.c 209f13fa8f4a597ffcc15fd0f8a3f27ed079c5e5 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x @@ -961,7 +961,7 @@ F tool/symbols.sh bc2a3709940d47c8ac8e0a1fdf17ec801f015a00 F tool/tostr.awk 11760e1b94a5d3dcd42378f3cc18544c06cfa576 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh 347d974d143cf132f953b565fbc03026f19fcb4d -P 82ac16c4f873d3bd7c22f36ba7b974b4903a2d50 -R c22fa4ebad64b5fe1347a3f0a2dcb7e8 +P 282474c42f24f0e66c69b576b72ef8ce764d49e2 +R dce52d6dc32cededac0b5cc1823e4002 U dan -Z 6a509799e9e665bc4a33861bc6dba39f +Z 91f64262d00fcd067a4fb1a130723392 diff --git a/manifest.uuid b/manifest.uuid index 527039d08d..1a2b253550 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -282474c42f24f0e66c69b576b72ef8ce764d49e2 \ No newline at end of file +5ac4a06111b5fad5f58c20ef5d2b65aeb23e105a \ No newline at end of file From b69ec3482a760d6d74e1386c524f7de51d622b92 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 16 Jul 2011 18:05:07 +0000 Subject: [PATCH 0059/1484] Note in the documentation that when iterating through a changeset, all changes to a single table are grouped together. Also add the sqlite3session_isempty() function. FossilOrigin-Name: 364f3b820a26f9b15cf74a0222ed5e302becc54f --- ext/session/session1.test | 27 +++++++++++++++++++++++++++ ext/session/sqlite3session.c | 17 +++++++++++++++++ ext/session/sqlite3session.h | 26 ++++++++++++++++++++++++++ ext/session/test_session.c | 8 ++++++++ manifest | 18 +++++++++--------- manifest.uuid | 2 +- 6 files changed, 88 insertions(+), 10 deletions(-) diff --git a/ext/session/session1.test b/ext/session/session1.test index 5e0fbc52a0..3ffe893a0d 100644 --- a/ext/session/session1.test +++ b/ext/session/session1.test @@ -464,6 +464,33 @@ do_iterator_test 7.1 * { {INSERT t1 0 X. {} {t one i 1}} } +#------------------------------------------------------------------------- +# Test the sqlite3session_isempty() function. +# +do_test 8.1 { + execsql { + CREATE TABLE t5(x PRIMARY KEY, y); + CREATE TABLE t6(x PRIMARY KEY, y); + INSERT INTO t5 VALUES('a', 'b'); + INSERT INTO t6 VALUES('a', 'b'); + } + sqlite3session S db main + S attach * + + S isempty +} {0} +do_test 8.2 { + execsql { DELETE FROM t5 } + S isempty +} {1} +do_test 8.3 { + S delete + sqlite3session S db main + S attach t5 + execsql { DELETE FROM t5 } + S isempty +} {0} +do_test 8.4 { S delete } {} catch { db2 close } finish_test diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index 577556ee92..2e21f2800f 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -1773,6 +1773,23 @@ int sqlite3session_indirect(sqlite3_session *pSession, int bIndirect){ return ret; } +/* +** Return true if there have been no changes to monitored tables recorded +** by the session object passed as the only argument. +*/ +int sqlite3session_isempty(sqlite3_session *pSession){ + int ret = 0; + SessionTable *pTab; + + sqlite3_mutex_enter(sqlite3_db_mutex(pSession->db)); + for(pTab=pSession->pTable; pTab && ret==0; pTab=pTab->pNext){ + ret = (pTab->nEntry>0); + } + sqlite3_mutex_leave(sqlite3_db_mutex(pSession->db)); + + return ret; +} + /* ** Create an iterator used to iterate through the contents of a changeset. */ diff --git a/ext/session/sqlite3session.h b/ext/session/sqlite3session.h index d8db1d6137..3c27d22ff8 100644 --- a/ext/session/sqlite3session.h +++ b/ext/session/sqlite3session.h @@ -254,6 +254,23 @@ int sqlite3session_changeset( void **ppChangeset /* OUT: Buffer containing changeset */ ); +/* +** CAPI3REF: Test if a changeset has recorded any changes. +** +** Return non-zero if no changes to attached tables have been recorded by +** the session object passed as the first argument. Otherwise, if one or +** more changes have been recorded, return zero. +** +** Even if this function returns zero, it is possible that calling +** [sqlite3session_changeset()] on the session handle may still return a +** changeset that contains no changes. This can happen when a row in +** an attached table is modified and then later on the original values +** are restored. However, if this function returns non-zero, then it is +** guaranteed that a call to sqlite3session_changeset() will return a +** changeset containing zero changes. +*/ +int sqlite3session_isempty(sqlite3_session *pSession); + /* ** CAPI3REF: Create An Iterator To Traverse A Changeset ** @@ -276,6 +293,15 @@ int sqlite3session_changeset( ** by passing it to [sqlite3changeset_finalize()]. The buffer containing the ** changeset (pChangeset) must remain valid until after the iterator is ** destroyed. +** +** Assuming the changeset blob was created by one of the +** [sqlite3session_changeset()], [sqlite3changeset_concat()] or +** [sqlite3changest_invert()], all changes within the changeset that apply +** to a single table are grouped together. This means that when an application +** iterates through a changeset using an iterator created by this function, +** all changes that relate to a single table are visted consecutively. There +** is no chance that the iterator will visit a change the applies to table X, +** then one for table Y, and then later on visit another change for table X. */ int sqlite3changeset_start( sqlite3_changeset_iter **pp, /* OUT: New changeset iterator handle */ diff --git a/ext/session/test_session.c b/ext/session/test_session.c index 9817b3c2f4..4bf2766c9c 100644 --- a/ext/session/test_session.c +++ b/ext/session/test_session.c @@ -38,6 +38,7 @@ static int test_session_cmd( { "delete", 0, "", }, /* 2 */ { "enable", 1, "BOOL", }, /* 3 */ { "indirect", 1, "BOOL", }, /* 4 */ + { "isempty", 0, "", }, /* 5 */ { 0 } }; int iSub; @@ -99,6 +100,13 @@ static int test_session_cmd( Tcl_SetObjResult(interp, Tcl_NewBooleanObj(val)); break; } + + case 5: { /* isempty */ + int val; + val = sqlite3session_isempty(pSession); + Tcl_SetObjResult(interp, Tcl_NewBooleanObj(val)); + break; + } } return TCL_OK; diff --git a/manifest b/manifest index 02f04f5c40..c0d06c4548 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sa\sfew\scasts\srequired\sby\s64-bit\sVS2010\sto\sthe\ssessions\scode. -D 2011-07-15T19:11:32.763 +C Note\sin\sthe\sdocumentation\sthat\swhen\siterating\sthrough\sa\schangeset,\sall\schanges\sto\sa\ssingle\stable\sare\sgrouped\stogether.\sAlso\sadd\sthe\ssqlite3session_isempty()\sfunction. +D 2011-07-16T18:05:07.557 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in c1d7a7f4fd8da6b1815032efca950e3d5125407e F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -102,7 +102,7 @@ F ext/rtree/rtree_util.tcl 06aab2ed5b826545bf215fff90ecb9255a8647ea F ext/rtree/sqlite3rtree.h 1af0899c63a688e272d69d8e746f24e76f10a3f0 F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 -F ext/session/session1.test f5d9f2e362abe2563181389509822bda956516ee +F ext/session/session1.test 6ad289a19648890cb138e4d2c9d2f5c1f714e505 F ext/session/session2.test 99ca0da7ddb617d42bafd83adccf99f18ae0384b F ext/session/session3.test a7a9ce59b8d1e49e2cc23d81421ac485be0eea01 F ext/session/session4.test a6ed685da7a5293c5d6f99855bcf41dbc352ca84 @@ -110,9 +110,9 @@ F ext/session/session5.test 8fdfaf9dba28a2f1c6b89b06168bdab1fef2d478 F ext/session/session6.test 443789bc2fca12e4f7075cf692c60b8a2bea1a26 F ext/session/session_common.tcl 1539d8973b2aea0025c133eb0cc4c89fcef541a5 F ext/session/sessionfault.test 401045278298a242cbc2e4bc986c102f01ff2180 -F ext/session/sqlite3session.c b31221e6e068476f736e8aaf5c7b66895d1b16f4 -F ext/session/sqlite3session.h f34905c818569779ddaea1bbef43469177614c69 -F ext/session/test_session.c 209f13fa8f4a597ffcc15fd0f8a3f27ed079c5e5 +F ext/session/sqlite3session.c b35e70924598794e157325eb7176523293f1d48c +F ext/session/sqlite3session.h b977d0bae338918c64f4f18f03f4648ad91df407 +F ext/session/test_session.c ea4dc9b4a1895c8e6bddcbfe3838d7eb57df2d99 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F main.mk f56d9895882f5cdd9f9f9ba8f8a679e9202288c1 @@ -961,7 +961,7 @@ F tool/symbols.sh bc2a3709940d47c8ac8e0a1fdf17ec801f015a00 F tool/tostr.awk 11760e1b94a5d3dcd42378f3cc18544c06cfa576 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh 347d974d143cf132f953b565fbc03026f19fcb4d -P 282474c42f24f0e66c69b576b72ef8ce764d49e2 -R dce52d6dc32cededac0b5cc1823e4002 +P 5ac4a06111b5fad5f58c20ef5d2b65aeb23e105a +R 3578d3e546ebd39820e5a49b01cb2c15 U dan -Z 91f64262d00fcd067a4fb1a130723392 +Z 84bc1b5f26e12cf6f38c5104884f25b6 diff --git a/manifest.uuid b/manifest.uuid index 1a2b253550..06c7707950 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5ac4a06111b5fad5f58c20ef5d2b65aeb23e105a \ No newline at end of file +364f3b820a26f9b15cf74a0222ed5e302becc54f \ No newline at end of file From a93166e030d00e81f471b3863dc3f8396955597b Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 16 Jul 2011 18:35:53 +0000 Subject: [PATCH 0060/1484] Fix error in a comment in sqlite3session.h. No changes to code. FossilOrigin-Name: 70c84e50209722a61d66fd737e42d49275745b62 --- ext/session/sqlite3session.h | 13 +++++++------ manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/ext/session/sqlite3session.h b/ext/session/sqlite3session.h index 3c27d22ff8..3a1c470ca8 100644 --- a/ext/session/sqlite3session.h +++ b/ext/session/sqlite3session.h @@ -296,12 +296,13 @@ int sqlite3session_isempty(sqlite3_session *pSession); ** ** Assuming the changeset blob was created by one of the ** [sqlite3session_changeset()], [sqlite3changeset_concat()] or -** [sqlite3changest_invert()], all changes within the changeset that apply -** to a single table are grouped together. This means that when an application -** iterates through a changeset using an iterator created by this function, -** all changes that relate to a single table are visted consecutively. There -** is no chance that the iterator will visit a change the applies to table X, -** then one for table Y, and then later on visit another change for table X. +** [sqlite3changeset_invert()] functions, all changes within the changeset +** that apply to a single table are grouped together. This means that when +** an application iterates through a changeset using an iterator created by +** this function, all changes that relate to a single table are visted +** consecutively. There is no chance that the iterator will visit a change +** the applies to table X, then one for table Y, and then later on visit +** another change for table X. */ int sqlite3changeset_start( sqlite3_changeset_iter **pp, /* OUT: New changeset iterator handle */ diff --git a/manifest b/manifest index c0d06c4548..141967fdc4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Note\sin\sthe\sdocumentation\sthat\swhen\siterating\sthrough\sa\schangeset,\sall\schanges\sto\sa\ssingle\stable\sare\sgrouped\stogether.\sAlso\sadd\sthe\ssqlite3session_isempty()\sfunction. -D 2011-07-16T18:05:07.557 +C Fix\serror\sin\sa\scomment\sin\ssqlite3session.h.\sNo\schanges\sto\scode. +D 2011-07-16T18:35:53.645 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in c1d7a7f4fd8da6b1815032efca950e3d5125407e F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -111,7 +111,7 @@ F ext/session/session6.test 443789bc2fca12e4f7075cf692c60b8a2bea1a26 F ext/session/session_common.tcl 1539d8973b2aea0025c133eb0cc4c89fcef541a5 F ext/session/sessionfault.test 401045278298a242cbc2e4bc986c102f01ff2180 F ext/session/sqlite3session.c b35e70924598794e157325eb7176523293f1d48c -F ext/session/sqlite3session.h b977d0bae338918c64f4f18f03f4648ad91df407 +F ext/session/sqlite3session.h 8dec372049532017d71c992609ca5450de7c5520 F ext/session/test_session.c ea4dc9b4a1895c8e6bddcbfe3838d7eb57df2d99 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 @@ -961,7 +961,7 @@ F tool/symbols.sh bc2a3709940d47c8ac8e0a1fdf17ec801f015a00 F tool/tostr.awk 11760e1b94a5d3dcd42378f3cc18544c06cfa576 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh 347d974d143cf132f953b565fbc03026f19fcb4d -P 5ac4a06111b5fad5f58c20ef5d2b65aeb23e105a -R 3578d3e546ebd39820e5a49b01cb2c15 +P 364f3b820a26f9b15cf74a0222ed5e302becc54f +R 7e574e123b2972c02a13eb4ef0e5a00a U dan -Z 84bc1b5f26e12cf6f38c5104884f25b6 +Z 6474c382418a7e49b9385e31f9ee66e8 diff --git a/manifest.uuid b/manifest.uuid index 06c7707950..03dc0faed6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -364f3b820a26f9b15cf74a0222ed5e302becc54f \ No newline at end of file +70c84e50209722a61d66fd737e42d49275745b62 \ No newline at end of file From ff53032641c6a9e01b3e9c8425c3a101fd7f7546 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 18 Jul 2011 15:22:56 +0000 Subject: [PATCH 0061/1484] Fix the sqlite3session_isempty() method so that it returns, as documented, non-zero when no changes have been recorded by the session object. FossilOrigin-Name: d04e0fd82a15aee963e35830caf8159b4b6ccd87 --- ext/session/session1.test | 6 +++--- ext/session/sqlite3session.c | 2 +- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/ext/session/session1.test b/ext/session/session1.test index 3ffe893a0d..91ccab21aa 100644 --- a/ext/session/session1.test +++ b/ext/session/session1.test @@ -478,18 +478,18 @@ do_test 8.1 { S attach * S isempty -} {0} +} {1} do_test 8.2 { execsql { DELETE FROM t5 } S isempty -} {1} +} {0} do_test 8.3 { S delete sqlite3session S db main S attach t5 execsql { DELETE FROM t5 } S isempty -} {0} +} {1} do_test 8.4 { S delete } {} catch { db2 close } diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index 2e21f2800f..817954034f 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -1787,7 +1787,7 @@ int sqlite3session_isempty(sqlite3_session *pSession){ } sqlite3_mutex_leave(sqlite3_db_mutex(pSession->db)); - return ret; + return (ret==0); } /* diff --git a/manifest b/manifest index 141967fdc4..a3d6a2cab4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\serror\sin\sa\scomment\sin\ssqlite3session.h.\sNo\schanges\sto\scode. -D 2011-07-16T18:35:53.645 +C Fix\sthe\ssqlite3session_isempty()\smethod\sso\sthat\sit\sreturns,\sas\sdocumented,\snon-zero\swhen\sno\schanges\shave\sbeen\srecorded\sby\sthe\ssession\sobject. +D 2011-07-18T15:22:56.414 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in c1d7a7f4fd8da6b1815032efca950e3d5125407e F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -102,7 +102,7 @@ F ext/rtree/rtree_util.tcl 06aab2ed5b826545bf215fff90ecb9255a8647ea F ext/rtree/sqlite3rtree.h 1af0899c63a688e272d69d8e746f24e76f10a3f0 F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 -F ext/session/session1.test 6ad289a19648890cb138e4d2c9d2f5c1f714e505 +F ext/session/session1.test 98691eec553390d61114b6214d2397f399dc1198 F ext/session/session2.test 99ca0da7ddb617d42bafd83adccf99f18ae0384b F ext/session/session3.test a7a9ce59b8d1e49e2cc23d81421ac485be0eea01 F ext/session/session4.test a6ed685da7a5293c5d6f99855bcf41dbc352ca84 @@ -110,7 +110,7 @@ F ext/session/session5.test 8fdfaf9dba28a2f1c6b89b06168bdab1fef2d478 F ext/session/session6.test 443789bc2fca12e4f7075cf692c60b8a2bea1a26 F ext/session/session_common.tcl 1539d8973b2aea0025c133eb0cc4c89fcef541a5 F ext/session/sessionfault.test 401045278298a242cbc2e4bc986c102f01ff2180 -F ext/session/sqlite3session.c b35e70924598794e157325eb7176523293f1d48c +F ext/session/sqlite3session.c 97295e187eade25398f52ed8b13fea68e0ee1e02 F ext/session/sqlite3session.h 8dec372049532017d71c992609ca5450de7c5520 F ext/session/test_session.c ea4dc9b4a1895c8e6bddcbfe3838d7eb57df2d99 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x @@ -961,7 +961,7 @@ F tool/symbols.sh bc2a3709940d47c8ac8e0a1fdf17ec801f015a00 F tool/tostr.awk 11760e1b94a5d3dcd42378f3cc18544c06cfa576 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh 347d974d143cf132f953b565fbc03026f19fcb4d -P 364f3b820a26f9b15cf74a0222ed5e302becc54f -R 7e574e123b2972c02a13eb4ef0e5a00a +P 70c84e50209722a61d66fd737e42d49275745b62 +R 7d529af0ae98dc5a31387a39a49b9017 U dan -Z 6474c382418a7e49b9385e31f9ee66e8 +Z 3511ba374807e0034b8197f50cf80466 diff --git a/manifest.uuid b/manifest.uuid index 03dc0faed6..7c4bfbd3cf 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -70c84e50209722a61d66fd737e42d49275745b62 \ No newline at end of file +d04e0fd82a15aee963e35830caf8159b4b6ccd87 \ No newline at end of file From cfec7eee203411e30cf3c55d975b562dc8f2c16e Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 26 Jul 2011 15:50:36 +0000 Subject: [PATCH 0062/1484] Fix a problem causing sqlite3changeset_invert() to effectively drop UPDATE changes. FossilOrigin-Name: bb3e65d9724dcecdc54b4c9fb0448f95d14495ff --- ext/session/session1.test | 15 +++++- ext/session/session8.test | 92 ++++++++++++++++++++++++++++++++++++ ext/session/sqlite3session.c | 82 +++++++++++++++++++++++++------- ext/session/sqlite3session.h | 2 +- manifest | 19 ++++---- manifest.uuid | 2 +- 6 files changed, 183 insertions(+), 29 deletions(-) create mode 100644 ext/session/session8.test diff --git a/ext/session/session1.test b/ext/session/session1.test index 91ccab21aa..7ef33e7fce 100644 --- a/ext/session/session1.test +++ b/ext/session/session1.test @@ -142,7 +142,7 @@ do_changeset_test 2.3.2 S { do_changeset_invert_test 2.3.3 S { {DELETE t1 0 X. {i 10 t Sukhothai} {}} {INSERT t1 0 X. {} {i 1 t Sukhothai}} - {UPDATE t1 0 X. {{} {} t Surin} {i 2 t Ayutthaya}} + {UPDATE t1 0 X. {i 2 t Surin} {{} {} t Ayutthaya}} {INSERT t1 0 X. {} {i 3 t Thonburi}} {DELETE t1 0 X. {i 20 t Thapae} {}} } @@ -492,5 +492,18 @@ do_test 8.3 { } {1} do_test 8.4 { S delete } {} +#------------------------------------------------------------------------- +# +do_execsql_test 9.1 { + CREATE TABLE t7(a, b, c, d, e PRIMARY KEY, f, g); + INSERT INTO t7 VALUES(1, 1, 1, 1, 1, 1, 1); +} +do_test 9.2 { + sqlite3session S db main + S attach * + execsql { UPDATE t7 SET b=2, d=2 } +} {} +do_changeset_test 9.2 S {{UPDATE t7 0 ....X.. {{} {} i 1 {} {} i 1 i 1 {} {} {} {}} {{} {} i 2 {} {} i 2 {} {} {} {} {} {}}}} +S delete catch { db2 close } finish_test diff --git a/ext/session/session8.test b/ext/session/session8.test new file mode 100644 index 0000000000..93bd4e06c3 --- /dev/null +++ b/ext/session/session8.test @@ -0,0 +1,92 @@ +# 2011 July 13 +# +# 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 regression tests for SQLite library. +# + +if {![info exists testdir]} { + set testdir [file join [file dirname [info script]] .. .. test] +} +source [file join [file dirname [info script]] session_common.tcl] +source $testdir/tester.tcl +ifcapable !session {finish_test; return} + +set testprefix session8 + +proc noop {args} {} + +# Like [dbcksum] in tester.tcl. Except this version is not sensitive +# to changes in the value of implicit IPK columns. +# +proc udbcksum {db dbname} { + if {$dbname=="temp"} { + set master sqlite_temp_master + } else { + set master $dbname.sqlite_master + } + set alltab [$db eval "SELECT name FROM $master WHERE type='table'"] + set txt [$db eval "SELECT * FROM $master"]\n + foreach tab $alltab { + append txt [lsort [$db eval "SELECT * FROM $dbname.$tab"]]\n + } + return [md5 $txt] +} + +proc do_then_undo {tn sql} { + set ck1 [udbcksum db main] + + sqlite3session S db main + S attach * + db eval $sql + + set ck2 [udbcksum db main] + + set invert [sqlite3changeset_invert [S changeset]] + S delete + sqlite3changeset_apply db $invert noop + + set ck3 [udbcksum db main] + + set a [expr {$ck1==$ck2}] + set b [expr {$ck1==$ck3}] + uplevel [list do_test $tn.1 "set {} $a" 0] + uplevel [list do_test $tn.2 "set {} $b" 1] +} + +do_execsql_test 1.1 { + CREATE TABLE t1(a PRIMARY KEY, b); + INSERT INTO t1 VALUES(1, 2); + INSERT INTO t1 VALUES("abc", "xyz"); +} +do_then_undo 1.2 { INSERT INTO t1 VALUES(3, 4); } +do_then_undo 1.3 { DELETE FROM t1 WHERE b=2; } +do_then_undo 1.4 { UPDATE t1 SET b = 3 WHERE a = 1; } + +do_execsql_test 2.1 { + CREATE TABLE t2(a, b PRIMARY KEY); + INSERT INTO t2 VALUES(1, 2); + INSERT INTO t2 VALUES('abc', 'xyz'); +} +do_then_undo 1.2 { INSERT INTO t2 VALUES(3, 4); } +do_then_undo 1.3 { DELETE FROM t2 WHERE b=2; } +do_then_undo 1.4 { UPDATE t1 SET a = '123' WHERE b = 'xyz'; } + +do_execsql_test 3.1 { + CREATE TABLE t3(a, b, c, d, e, PRIMARY KEY(c, e)); + INSERT INTO t3 VALUES('x', 45, 0.0, 'abcdef', 12); + INSERT INTO t3 VALUES(45, 0.0, 'abcdef', 12, 'x'); + INSERT INTO t3 VALUES(0.0, 'abcdef', 12, 'x', 45); +} + +do_then_undo 3.2 { UPDATE t3 SET b=b||b WHERE e!='x' } +do_then_undo 3.3 { UPDATE t3 SET a = 46 } + +finish_test + diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index 817954034f..b8bcc9b286 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -2132,14 +2132,17 @@ int sqlite3changeset_finalize(sqlite3_changeset_iter *p){ */ int sqlite3changeset_invert( int nChangeset, /* Number of bytes in input */ - void *pChangeset, /* Input changeset */ + const void *pChangeset, /* Input changeset */ int *pnInverted, /* OUT: Number of bytes in output changeset */ void **ppInverted /* OUT: Inverse of pChangeset */ ){ + int rc = SQLITE_OK; /* Return value */ u8 *aOut; u8 *aIn; int i; - int nCol = 0; + int nCol = 0; /* Number of cols in current table */ + u8 *abPK = 0; /* PK array for current table */ + sqlite3_value **apVal = 0; /* Space for values for UPDATE inversion */ /* Zero the output variables in case an error occurs. */ *ppInverted = 0; @@ -2163,10 +2166,13 @@ int sqlite3changeset_invert( ** * A nul-terminated table name. */ int nByte = 1 + sessionVarintGet(&aIn[i+1], &nCol); + abPK = &aIn[i+nByte]; nByte += nCol; nByte += 1 + sqlite3Strlen30((char *)&aIn[i+nByte]); memcpy(&aOut[i], &aIn[i], nByte); i += nByte; + sqlite3_free(apVal); + apVal = 0; break; } @@ -2185,40 +2191,82 @@ int sqlite3changeset_invert( } case SQLITE_UPDATE: { - int nByte1; /* Size of old.* record in bytes */ - int nByte2; /* Size of new.* record in bytes */ - u8 *aEnd = &aIn[i+2]; + int iCol; + int nWrite = 0; + u8 *aEnd = &aIn[i+2]; - sessionReadRecord(&aEnd, nCol, 0); - nByte1 = (int)(aEnd - &aIn[i+2]); - sessionReadRecord(&aEnd, nCol, 0); - nByte2 = (int)(aEnd - &aIn[i+2]) - nByte1; + if( 0==apVal ){ + apVal = (sqlite3_value **)sqlite3_malloc(sizeof(apVal[0])*nCol*2); + if( 0==apVal ){ + rc = SQLITE_NOMEM; + goto finished_invert; + } + memset(apVal, 0, sizeof(apVal[0])*nCol*2); + } + /* Read the old.* and new.* records for the update change. */ + rc = sessionReadRecord(&aEnd, nCol, &apVal[0]); + if( rc==SQLITE_OK ){ + rc = sessionReadRecord(&aEnd, nCol, &apVal[nCol]); + } + + /* Write the header for the new UPDATE change. Same as the original. */ aOut[i] = SQLITE_UPDATE; aOut[i+1] = aIn[i+1]; - memcpy(&aOut[i+2], &aIn[i+2+nByte1], nByte2); - memcpy(&aOut[i+2+nByte2], &aIn[i+2], nByte1); + nWrite = 2; - i += 2 + nByte1 + nByte2; + /* Write the new old.* record. Consists of the PK columns from the + ** original old.* record, and the other values from the original + ** new.* record. */ + for(iCol=0; rc==SQLITE_OK && iColaRecord; u8 *a2 = aRec; + assert( op1==SQLITE_UPDATE ); sessionReadRecord(&a1, pTab->nCol, 0); sessionReadRecord(&a2, pTab->nCol, 0); pNew->op = SQLITE_UPDATE; diff --git a/ext/session/sqlite3session.h b/ext/session/sqlite3session.h index 3a1c470ca8..a1ab1e9645 100644 --- a/ext/session/sqlite3session.h +++ b/ext/session/sqlite3session.h @@ -545,7 +545,7 @@ int sqlite3changeset_finalize(sqlite3_changeset_iter *pIter); ** changeset. If it is not, the results are undefined. */ int sqlite3changeset_invert( - int nIn, void *pIn, /* Input changeset */ + int nIn, const void *pIn, /* Input changeset */ int *pnOut, void **ppOut /* OUT: Inverse of input */ ); diff --git a/manifest b/manifest index 4e10bb5947..996459f395 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sthe\slatest\strunk\schanges\sinto\sthe\ssessions\sbranch. -D 2011-07-22T12:49:27.667 +C Fix\sa\sproblem\scausing\ssqlite3changeset_invert()\sto\seffectively\sdrop\sUPDATE\schanges. +D 2011-07-26T15:50:36.271 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 1e6988b3c11dee9bd5edc0c804bd4468d74a9cdc F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -102,16 +102,17 @@ F ext/rtree/rtree_util.tcl 06aab2ed5b826545bf215fff90ecb9255a8647ea F ext/rtree/sqlite3rtree.h 1af0899c63a688e272d69d8e746f24e76f10a3f0 F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 -F ext/session/session1.test 98691eec553390d61114b6214d2397f399dc1198 +F ext/session/session1.test 502086908e4144dfaccb1baa77bc29d75a9daace F ext/session/session2.test 99ca0da7ddb617d42bafd83adccf99f18ae0384b F ext/session/session3.test a7a9ce59b8d1e49e2cc23d81421ac485be0eea01 F ext/session/session4.test a6ed685da7a5293c5d6f99855bcf41dbc352ca84 F ext/session/session5.test 8fdfaf9dba28a2f1c6b89b06168bdab1fef2d478 F ext/session/session6.test 443789bc2fca12e4f7075cf692c60b8a2bea1a26 +F ext/session/session8.test 7d35947ad329b8966f095d34f9617a9eff52dc65 F ext/session/session_common.tcl 1539d8973b2aea0025c133eb0cc4c89fcef541a5 F ext/session/sessionfault.test 401045278298a242cbc2e4bc986c102f01ff2180 -F ext/session/sqlite3session.c 97295e187eade25398f52ed8b13fea68e0ee1e02 -F ext/session/sqlite3session.h 8dec372049532017d71c992609ca5450de7c5520 +F ext/session/sqlite3session.c 5a50e28759187440805fca653029946311593da6 +F ext/session/sqlite3session.h f374c9c4c96e08f67ac418871c29d423245c7673 F ext/session/test_session.c ea4dc9b4a1895c8e6bddcbfe3838d7eb57df2d99 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 @@ -964,7 +965,7 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5 F tool/tostr.awk 11760e1b94a5d3dcd42378f3cc18544c06cfa576 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh 2ebae31e1eb352696f3c2f7706a34c084b28c262 -P d04e0fd82a15aee963e35830caf8159b4b6ccd87 8ce2b74a82264550b0e19da3e0e1a145db940a1c -R a5737ded89a8c66dbf565b51f6981ff8 -U drh -Z 81f45685ad26c120405ad7cb74da4306 +P 110cfd6920cf3011aeaf7e586f8db867bfc69fbb +R 95b1f91b4b1f21686c1d16002cdc06fd +U dan +Z 326ddfa62484f9d6c6538d0373ca9236 diff --git a/manifest.uuid b/manifest.uuid index cd26a2668c..94d44ce8ae 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -110cfd6920cf3011aeaf7e586f8db867bfc69fbb \ No newline at end of file +bb3e65d9724dcecdc54b4c9fb0448f95d14495ff \ No newline at end of file From 1e556c3fe51cdf565c6bf05ba0406ce51872e3d5 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 26 Jul 2011 15:57:56 +0000 Subject: [PATCH 0063/1484] Fix a test case in sessionfault.test. No changes to code. FossilOrigin-Name: dc6ecacd7724089a0387e69a0fd5cdbfdd2023f8 --- ext/session/sessionfault.test | 2 +- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/ext/session/sessionfault.test b/ext/session/sessionfault.test index 1444a46b36..d0556ce33f 100644 --- a/ext/session/sessionfault.test +++ b/ext/session/sessionfault.test @@ -247,7 +247,7 @@ do_faultsim_test 5 -faults oom* -body { foreach c { {DELETE t1 0 .X {t xxx t yyy} {}} {INSERT t1 0 .X {} {t string i 1}} - {UPDATE t1 0 .X {i 20 {} {}} {i 4 i 2}} + {UPDATE t1 0 .X {i 20 i 2} {i 4 {} {}}} } { lappend y $c } if {$x != $y} { error "changeset no good" } } diff --git a/manifest b/manifest index 996459f395..51775aa388 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\scausing\ssqlite3changeset_invert()\sto\seffectively\sdrop\sUPDATE\schanges. -D 2011-07-26T15:50:36.271 +C Fix\sa\stest\scase\sin\ssessionfault.test.\sNo\schanges\sto\scode. +D 2011-07-26T15:57:56.891 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 1e6988b3c11dee9bd5edc0c804bd4468d74a9cdc F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -110,7 +110,7 @@ F ext/session/session5.test 8fdfaf9dba28a2f1c6b89b06168bdab1fef2d478 F ext/session/session6.test 443789bc2fca12e4f7075cf692c60b8a2bea1a26 F ext/session/session8.test 7d35947ad329b8966f095d34f9617a9eff52dc65 F ext/session/session_common.tcl 1539d8973b2aea0025c133eb0cc4c89fcef541a5 -F ext/session/sessionfault.test 401045278298a242cbc2e4bc986c102f01ff2180 +F ext/session/sessionfault.test 891453e96630ee2915081487fc4b7226f0aa252f F ext/session/sqlite3session.c 5a50e28759187440805fca653029946311593da6 F ext/session/sqlite3session.h f374c9c4c96e08f67ac418871c29d423245c7673 F ext/session/test_session.c ea4dc9b4a1895c8e6bddcbfe3838d7eb57df2d99 @@ -965,7 +965,7 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5 F tool/tostr.awk 11760e1b94a5d3dcd42378f3cc18544c06cfa576 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh 2ebae31e1eb352696f3c2f7706a34c084b28c262 -P 110cfd6920cf3011aeaf7e586f8db867bfc69fbb -R 95b1f91b4b1f21686c1d16002cdc06fd +P bb3e65d9724dcecdc54b4c9fb0448f95d14495ff +R 9792f6e7ba4296e8c713a87df4ad910e U dan -Z 326ddfa62484f9d6c6538d0373ca9236 +Z 85a557af61ebafc7cfd33bb00bd9108a diff --git a/manifest.uuid b/manifest.uuid index 94d44ce8ae..6b93cf17ff 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bb3e65d9724dcecdc54b4c9fb0448f95d14495ff \ No newline at end of file +dc6ecacd7724089a0387e69a0fd5cdbfdd2023f8 \ No newline at end of file From 964cbd469beab81aec2c8283ef593f2d36faaf14 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 26 Jul 2011 17:53:53 +0000 Subject: [PATCH 0064/1484] Fix errors in a comment in sqlite3session.c. No changes to code. FossilOrigin-Name: d5f4c4c0bf0d488db11c6ab0d26ca3554a57d0ff --- ext/session/sqlite3session.c | 8 ++++---- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index b8bcc9b286..778caad591 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -2353,11 +2353,11 @@ static int sessionDeleteRow( ** ** UPDATE x SET ** a = CASE WHEN ?2 THEN ?3 ELSE a END, -** b = CASE WHEN ?5 THEN ?6 ELSE a END, -** c = CASE WHEN ?8 THEN ?9 ELSE a END, -** d = CASE WHEN ?11 THEN ?12 ELSE a END +** b = CASE WHEN ?5 THEN ?6 ELSE b END, +** c = CASE WHEN ?8 THEN ?9 ELSE c END, +** d = CASE WHEN ?11 THEN ?12 ELSE d END ** WHERE a = ?1 AND c = ?7 AND (?13 OR -** (?5==0 OR b IS ?4) AND (?11==0 OR b IS ?10) AND +** (?5==0 OR b IS ?4) AND (?11==0 OR d IS ?10) AND ** ) ** ** For each column in the table, there are three variables to bind: diff --git a/manifest b/manifest index 51775aa388..468757b49e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\stest\scase\sin\ssessionfault.test.\sNo\schanges\sto\scode. -D 2011-07-26T15:57:56.891 +C Fix\serrors\sin\sa\scomment\sin\ssqlite3session.c.\sNo\schanges\sto\scode. +D 2011-07-26T17:53:53.311 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 1e6988b3c11dee9bd5edc0c804bd4468d74a9cdc F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -111,7 +111,7 @@ F ext/session/session6.test 443789bc2fca12e4f7075cf692c60b8a2bea1a26 F ext/session/session8.test 7d35947ad329b8966f095d34f9617a9eff52dc65 F ext/session/session_common.tcl 1539d8973b2aea0025c133eb0cc4c89fcef541a5 F ext/session/sessionfault.test 891453e96630ee2915081487fc4b7226f0aa252f -F ext/session/sqlite3session.c 5a50e28759187440805fca653029946311593da6 +F ext/session/sqlite3session.c 57d04e1d6a3579e673e61dea29f214fb4e0fc505 F ext/session/sqlite3session.h f374c9c4c96e08f67ac418871c29d423245c7673 F ext/session/test_session.c ea4dc9b4a1895c8e6bddcbfe3838d7eb57df2d99 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x @@ -965,7 +965,7 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5 F tool/tostr.awk 11760e1b94a5d3dcd42378f3cc18544c06cfa576 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh 2ebae31e1eb352696f3c2f7706a34c084b28c262 -P bb3e65d9724dcecdc54b4c9fb0448f95d14495ff -R 9792f6e7ba4296e8c713a87df4ad910e +P dc6ecacd7724089a0387e69a0fd5cdbfdd2023f8 +R 243487bed84c57b1cd5a32970f8d4775 U dan -Z 85a557af61ebafc7cfd33bb00bd9108a +Z 2c93411bbe8d90a5b2b924f24cbf2370 diff --git a/manifest.uuid b/manifest.uuid index 6b93cf17ff..8a22590c14 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -dc6ecacd7724089a0387e69a0fd5cdbfdd2023f8 \ No newline at end of file +d5f4c4c0bf0d488db11c6ab0d26ca3554a57d0ff \ No newline at end of file From 7f197bb7b05a5cdd0ec5aa68447266b495d03818 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 3 Aug 2011 21:32:11 +0000 Subject: [PATCH 0065/1484] Avoid segfaulting on an incremental blob write if SQLITE_ENABLE_PREUPDATE_HOOK set but no pre-update hooks are defined. FossilOrigin-Name: 62c446340475b52b843c0345eda32ebe86fa9159 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/vdbeblob.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 468757b49e..a887475f95 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\serrors\sin\sa\scomment\sin\ssqlite3session.c.\sNo\schanges\sto\scode. -D 2011-07-26T17:53:53.311 +C Avoid\ssegfaulting\son\san\sincremental\sblob\swrite\sif\sSQLITE_ENABLE_PREUPDATE_HOOK\nset\sbut\sno\spre-update\shooks\sare\sdefined. +D 2011-08-03T21:32:11.649 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 1e6988b3c11dee9bd5edc0c804bd4468d74a9cdc F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -255,7 +255,7 @@ F src/vdbe.h 322af148cceef120bb1ec9cff7f122e76abf94da F src/vdbeInt.h 3de6588b36c833969aebab202e1766d586c37ec2 F src/vdbeapi.c ddd061183e2c3015f676e53ee85fcaf306617e8e F src/vdbeaux.c 7d0b75a04ac466d25a90fefd1df83361a2ab0ad7 -F src/vdbeblob.c a547f286b651641bdb43a567af66d0e776a39ea2 +F src/vdbeblob.c fde0374afb0c512614aed191ac2683f6772d2b8f F src/vdbemem.c 0498796b6ffbe45e32960d6a1f5adfb6e419883b F src/vdbetrace.c 5d0dc3d5fd54878cc8d6d28eb41deb8d5885b114 F src/vtab.c 901791a47318c0562cd0c676a2c6ff1bc530e582 @@ -965,7 +965,7 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5 F tool/tostr.awk 11760e1b94a5d3dcd42378f3cc18544c06cfa576 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh 2ebae31e1eb352696f3c2f7706a34c084b28c262 -P dc6ecacd7724089a0387e69a0fd5cdbfdd2023f8 -R 243487bed84c57b1cd5a32970f8d4775 -U dan -Z 2c93411bbe8d90a5b2b924f24cbf2370 +P d5f4c4c0bf0d488db11c6ab0d26ca3554a57d0ff +R dc4862fa4ca184e0298413704bde1899 +U drh +Z abe606476a76771b05a5d0a0f3902dc5 diff --git a/manifest.uuid b/manifest.uuid index 8a22590c14..492ab34ae1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d5f4c4c0bf0d488db11c6ab0d26ca3554a57d0ff \ No newline at end of file +62c446340475b52b843c0345eda32ebe86fa9159 \ No newline at end of file diff --git a/src/vdbeblob.c b/src/vdbeblob.c index 4dc9ef4fff..2f37ad933b 100644 --- a/src/vdbeblob.c +++ b/src/vdbeblob.c @@ -392,7 +392,7 @@ static int blobReadWrite( sqlite3BtreeEnterCursor(p->pCsr); #ifdef SQLITE_ENABLE_PREUPDATE_HOOK - if( xCall==sqlite3BtreePutData ){ + if( xCall==sqlite3BtreePutData && db->xPreUpdateCallback ){ /* If a pre-update hook is registered and this is a write cursor, ** invoke it here. ** From adb96a62e5b03ec4203bee7050cdf71e6b2830df Mon Sep 17 00:00:00 2001 From: mistachkin Date: Mon, 16 Jan 2012 12:33:36 +0000 Subject: [PATCH 0066/1484] Support building with SQLITE_ENABLE_SESSION under MSVC. FossilOrigin-Name: 2845654d425164de143e82b9fdb255d81a01af56 --- Makefile.msc | 22 +++++++++++++++++++--- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 27 insertions(+), 11 deletions(-) diff --git a/Makefile.msc b/Makefile.msc index f40936d915..3c14cc2087 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -178,6 +178,8 @@ TCC = $(TCC) -DSQLITE_TEMP_STORE=1 OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_FTS3=1 OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_RTREE=1 OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_COLUMN_METADATA=1 +OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_SESSION=1 +OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_PREUPDATE_HOOK=1 # END standard options # BEGIN required Windows option @@ -412,6 +414,9 @@ SRC = $(SRC) \ SRC = $(SRC) \ $(TOP)\ext\rtree\rtree.h \ $(TOP)\ext\rtree\rtree.c +SRC = $(SRC) \ + $(TOP)\ext\session\sqlite3session.h \ + $(TOP)\ext\session\sqlite3session.c # Generated source code files @@ -468,9 +473,11 @@ TESTSRC = \ $(TOP)\src\test_wholenumber.c \ $(TOP)\src\test_wsd.c \ $(TOP)\ext\fts3\fts3_term.c \ - $(TOP)\ext\fts3\fts3_test.c + $(TOP)\ext\fts3\fts3_test.c \ + $(TOP)\ext\session\test_session.c # Source code to the library files needed by the test fixture +# (non-amalgamation) # TESTSRC2 = \ $(TOP)\src\attach.c \ @@ -513,7 +520,14 @@ TESTSRC2 = \ $(TOP)\ext\fts3\fts3_expr.c \ $(TOP)\ext\fts3\fts3_tokenizer.c \ $(TOP)\ext\fts3\fts3_write.c \ - $(TOP)\ext\async\sqlite3async.c + $(TOP)\ext\async\sqlite3async.c \ + $(TOP)\ext\session\sqlite3session.c + +# Source code to the library files needed by the test fixture +# (amalgamation) +# +TESTSRC3 = \ + $(TOP)\ext\session\sqlite3session.c # Header files used by all library source files. # @@ -558,6 +572,8 @@ EXTHDR = $(EXTHDR) \ $(TOP)\ext\icu\sqliteicu.h EXTHDR = $(EXTHDR) \ $(TOP)\ext\rtree\sqlite3rtree.h +EXTHDR = $(EXTHDR) \ + $(TOP)\ext\session\sqlite3session.h # This is the default Makefile target. The objects listed here # are what get build when you type just "make" with no arguments. @@ -944,7 +960,7 @@ TESTFIXTURE_FLAGS = -DTCLSH=1 -DSQLITE_TEST=1 -DSQLITE_CRASH_TEST=1 TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_SERVER=1 -DSQLITE_PRIVATE="" -DSQLITE_CORE TESTFIXTURE_SRC0 = $(TESTSRC2) libsqlite3.lib -TESTFIXTURE_SRC1 = sqlite3.c +TESTFIXTURE_SRC1 = $(TESTSRC3) sqlite3.c !IF $(USE_AMALGAMATION)==0 TESTFIXTURE_SRC = $(TESTSRC) $(TOP)\src\tclsqlite.c $(TESTFIXTURE_SRC0) !ELSE diff --git a/manifest b/manifest index d6154d7b08..3561babe89 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Update\ssessions\sbranch\swith\slatest\schanges\sfrom\strunk. -D 2012-01-14T13:50:12.463 +C Support\sbuilding\swith\sSQLITE_ENABLE_SESSION\sunder\sMSVC. +D 2012-01-16T12:33:36.900 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 3f79a373e57c3b92dabf76f40b065e719d31ac34 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 -F Makefile.msc dcad80fa69f17d46fe6778ba873fc108ca16298d +F Makefile.msc 340b6d1bb4553c389d6837aa437d7c25dc03f980 F Makefile.vxworks 1deb39c8bb047296c30161ffa10c1b5423e632f9 F README cd04a36fbc7ea56932a4052d7d0b7f09f27c33d6 F VERSION af03cd6400f9d71d38bdb7a9d66a1aefdc2f3e0d @@ -1000,7 +1000,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P a9bcb432f58b96f079a73c456efd4851c582221e 88ad2f23c5036cbb4a69b73ce5792bd5c33a9177 -R 30723a7c24a6752d8bfb2c322e9b8748 -U dan -Z 241182607d7d4efdfae3b5115d25b877 +P 01c84fd391a0ca1f5245c7eff0644d0cc6cff86b +R 88d7ca9f3f2aa524ac3a66d4c2e7567b +U mistachkin +Z 171e4d9c94c739b476f164aff1375bac diff --git a/manifest.uuid b/manifest.uuid index 62957ac731..6308588f15 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -01c84fd391a0ca1f5245c7eff0644d0cc6cff86b \ No newline at end of file +2845654d425164de143e82b9fdb255d81a01af56 \ No newline at end of file From 40eaa08620a75a29f4849cd3572e64feaafce5ec Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 28 Sep 2012 12:55:56 +0000 Subject: [PATCH 0067/1484] Update the sessionfault-9.1 and -9.2 tests to account for the change in version 3.7.11 in which a pending statement no longer blocks ROLLBACK but instead causes the next call on that statement to return SQLITE_ABORT. FossilOrigin-Name: fae9eb197fcef726fd2c7c701afe6805fc008cf9 --- ext/session/sessionfault.test | 8 ++++++-- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/ext/session/sessionfault.test b/ext/session/sessionfault.test index d0556ce33f..f17daccfc7 100644 --- a/ext/session/sessionfault.test +++ b/ext/session/sessionfault.test @@ -372,7 +372,9 @@ do_test 9.1.prep { } {} faultsim_save_and_close -set answers [list {0 {}} {1 SQLITE_NOMEM} {1 {callback requested query abort}}] +set answers [list {0 {}} {1 SQLITE_NOMEM} \ + {1 {callback requested query abort}} \ + {1 {abort due to ROLLBACK}}] do_faultsim_test 9.1 -faults oom-transient -prep { catch { unset ::c } faultsim_restore_and_reopen @@ -409,7 +411,9 @@ do_test 9.2.prep { } {} faultsim_save_and_close -set answers [list {0 {}} {1 SQLITE_NOMEM} {1 {callback requested query abort}}] +set answers [list {0 {}} {1 SQLITE_NOMEM} \ + {1 {callback requested query abort}} \ + {1 {abort due to ROLLBACK}}] do_faultsim_test 9.2 -faults oom-transient -prep { catch { unset ::c } faultsim_restore_and_reopen diff --git a/manifest b/manifest index e332fe6cdf..2217d6a1bb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\swith\slatest\strunk\schanges. -D 2012-08-31T14:23:16.346 +C Update\sthe\ssessionfault-9.1\sand\s-9.2\stests\sto\saccount\sfor\sthe\schange\sin\nversion\s3.7.11\sin\swhich\sa\spending\sstatement\sno\slonger\sblocks\sROLLBACK\sbut\ninstead\scauses\sthe\snext\scall\son\sthat\sstatement\sto\sreturn\sSQLITE_ABORT. +D 2012-09-28T12:55:56.421 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in abd5c10d21d1395f140d9e50ea999df8fa4d6376 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -109,7 +109,7 @@ F ext/session/session5.test 8fdfaf9dba28a2f1c6b89b06168bdab1fef2d478 F ext/session/session6.test 443789bc2fca12e4f7075cf692c60b8a2bea1a26 F ext/session/session8.test 7d35947ad329b8966f095d34f9617a9eff52dc65 F ext/session/session_common.tcl 1539d8973b2aea0025c133eb0cc4c89fcef541a5 -F ext/session/sessionfault.test 891453e96630ee2915081487fc4b7226f0aa252f +F ext/session/sessionfault.test 496291b287ba3c0b14ca2e074425e29cc92a64a6 F ext/session/sqlite3session.c 57d04e1d6a3579e673e61dea29f214fb4e0fc505 F ext/session/sqlite3session.h f374c9c4c96e08f67ac418871c29d423245c7673 F ext/session/test_session.c ea4dc9b4a1895c8e6bddcbfe3838d7eb57df2d99 @@ -1026,7 +1026,7 @@ F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9 -P aa62d6881b5aae64e15dbae70ce8e77bcc2a9f0b 527340abff18aedbcb0f82ac1296a9f548e24ac4 -R ce445dd99f7d73f4997bfaaffd71f58e -U dan -Z b7fa6fd6ef1ab9dd566a694a77a1f165 +P 87995dc9409482f0a7a367bfc51d78ac0f63b8c3 +R 0ffae7a510db2af1076692fe90154443 +U drh +Z a5785b316a6ee7492de59cea784cd09f diff --git a/manifest.uuid b/manifest.uuid index 56b257152a..5fdf4c7f29 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -87995dc9409482f0a7a367bfc51d78ac0f63b8c3 \ No newline at end of file +fae9eb197fcef726fd2c7c701afe6805fc008cf9 \ No newline at end of file From 498dcae0f0fbed1716c822c1abca02bf0eb4d0c0 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 13 Mar 2013 11:42:00 +0000 Subject: [PATCH 0068/1484] Fix a compiler warning in sqlite3VdbePreUpdateHook(). Add sqlite3session.c to the amalgamation. Fix the Makefile.in to work with sessions. FossilOrigin-Name: e54b0225f226a163ec874df7d4b738efba12b3a7 --- Makefile.in | 20 ++++++++++++++++---- Makefile.msc | 7 ++++++- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- src/vdbeaux.c | 2 +- tool/mksqlite3c.tcl | 3 +++ 6 files changed, 37 insertions(+), 17 deletions(-) diff --git a/Makefile.in b/Makefile.in index 652928b8cc..634c7a3654 100644 --- a/Makefile.in +++ b/Makefile.in @@ -26,7 +26,8 @@ BCC = @BUILD_CC@ @BUILD_CFLAGS@ # will run on the target platform. (BCC and TCC are usually the # same unless your are cross-compiling.) # -TCC = @CC@ @CPPFLAGS@ @CFLAGS@ -I. -I${TOP}/src -I${TOP}/ext/rtree +TCC = @CC@ @CPPFLAGS@ @CFLAGS@ -I. -I${TOP}/src -I${TOP}/ext/rtree -I${TOP}/ext/icu +TCC += -I${TOP}/ext/fts3 -I${TOP}/ext/async -I${TOP}/ext/session # Define this for the autoconf-based build, so that the code knows it can # include the generated config.h @@ -76,6 +77,7 @@ TEMP_STORE = -DSQLITE_TEMP_STORE=@TEMP_STORE@ # The same set of OMIT and ENABLE flags should be passed to the # LEMON parser generator and the mkkeywordhash tool as well. OPT_FEATURE_FLAGS = @OPT_FEATURE_FLAGS@ +OPT_FEATURE_FLAGS += -DSQLITE_ENABLE_SESSION -DSQLITE_ENABLE_PREUPDATE_HOOK TCC += $(OPT_FEATURE_FLAGS) @@ -175,7 +177,8 @@ LIBOBJS0 = alter.lo analyze.lo attach.lo auth.lo \ mutex.lo mutex_noop.lo mutex_unix.lo mutex_w32.lo \ notify.lo opcodes.lo os.lo os_unix.lo os_win.lo \ pager.lo parse.lo pcache.lo pcache1.lo pragma.lo prepare.lo printf.lo \ - random.lo resolve.lo rowset.lo rtree.lo select.lo status.lo \ + random.lo resolve.lo rowset.lo rtree.lo \ + sqlite3session.lo select.lo status.lo \ table.lo tokenize.lo trigger.lo \ update.lo util.lo vacuum.lo \ vdbe.lo vdbeapi.lo vdbeaux.lo vdbeblob.lo vdbemem.lo vdbesort.lo \ @@ -325,6 +328,10 @@ SRC += \ SRC += \ $(TOP)/ext/rtree/rtree.h \ $(TOP)/ext/rtree/rtree.c +SRC += \ + $(TOP)/ext/session/sqlite3session.c \ + $(TOP)/ext/session/sqlite3session.h + # Generated source code files @@ -384,7 +391,8 @@ TESTSRC = \ $(TOP)/src/test_wholenumber.c \ $(TOP)/src/test_wsd.c \ $(TOP)/ext/fts3/fts3_term.c \ - $(TOP)/ext/fts3/fts3_test.c + $(TOP)/ext/fts3/fts3_test.c \ + $(TOP)/ext/session/test_session.c # Source code to the library files needed by the test fixture # @@ -428,7 +436,8 @@ TESTSRC2 = \ $(TOP)/ext/fts3/fts3_term.c \ $(TOP)/ext/fts3/fts3_tokenizer.c \ $(TOP)/ext/fts3/fts3_write.c \ - $(TOP)/ext/async/sqlite3async.c + $(TOP)/ext/async/sqlite3async.c \ + $(TOP)/ext/session/sqlite3session.c # Header files used by all library source files. # @@ -864,6 +873,9 @@ fts3_write.lo: $(TOP)/ext/fts3/fts3_write.c $(HDR) $(EXTHDR) rtree.lo: $(TOP)/ext/rtree/rtree.c $(HDR) $(EXTHDR) $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/rtree/rtree.c +sqlite3session.lo: $(TOP)/ext/session/sqlite3session.c $(HDR) $(EXTHDR) + $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/session/sqlite3session.c + # Rules to build the 'testfixture' application. # diff --git a/Makefile.msc b/Makefile.msc index cc726ae959..a15c755d2e 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -232,6 +232,7 @@ TCC = $(TCC) -I$(TOP)\ext\fts3 RCC = $(RCC) -I$(TOP)\ext\fts3 TCC = $(TCC) -I$(TOP)\ext\rtree RCC = $(RCC) -I$(TOP)\ext\rtree +TCC = $(TCC) -I$(TOP)\ext\session !ENDIF # Define -DNDEBUG to compile without debugging (i.e., for production usage) @@ -488,7 +489,8 @@ LIBOBJS0 = alter.lo analyze.lo attach.lo auth.lo \ mutex.lo mutex_noop.lo mutex_unix.lo mutex_w32.lo \ notify.lo opcodes.lo os.lo os_unix.lo os_win.lo \ pager.lo parse.lo pcache.lo pcache1.lo pragma.lo prepare.lo printf.lo \ - random.lo resolve.lo rowset.lo rtree.lo select.lo status.lo \ + random.lo resolve.lo rowset.lo rtree.lo \ + sqlite3session.lo select.lo status.lo \ table.lo tokenize.lo trigger.lo \ update.lo util.lo vacuum.lo \ vdbe.lo vdbeapi.lo vdbeaux.lo vdbeblob.lo vdbemem.lo vdbesort.lo \ @@ -1198,6 +1200,9 @@ fts3_write.lo: $(TOP)\ext\fts3\fts3_write.c $(HDR) $(EXTHDR) rtree.lo: $(TOP)\ext\rtree\rtree.c $(HDR) $(EXTHDR) $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)\ext\rtree\rtree.c +rtree.lo: $(TOP)\ext\session\sqlite3sesion.c $(HDR) $(EXTHDR) + $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)\ext\session\sqlite3session.c + # Rules to build the 'testfixture' application. # diff --git a/manifest b/manifest index 53fce838c5..10fc165232 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Merge\slatest\strunk\schanges\sinto\sthis\sbranch. -D 2013-03-13T06:34:51.061 +C Fix\sa\scompiler\swarning\sin\ssqlite3VdbePreUpdateHook().\nAdd\ssqlite3session.c\sto\sthe\samalgamation.\nFix\sthe\sMakefile.in\sto\swork\swith\ssessions. +D 2013-03-13T11:42:00.694 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f -F Makefile.in 9a804abbd3cae82d196e4d33aba13239e32522a5 +F Makefile.in f33fad60e6fa3cc15f6a39609a256b340a1c12d9 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 -F Makefile.msc 5de508f802789aae3e96d86261c5cf633d67ce00 +F Makefile.msc 29bce8fa86dc10ffeb5ac11537c0e12c3a3e6887 F Makefile.vxworks b18ad88e9a8c6a001f5cf4a389116a4f1a7ab45f F README cd04a36fbc7ea56932a4052d7d0b7f09f27c33d6 F VERSION 6d4f66eaebabc42ef8c2a4d2d0caf4ce7ee81137 @@ -255,7 +255,7 @@ F src/vdbe.c 9e4164ac85aa01e1a563e6c7f565b106ff0bf67b F src/vdbe.h 1223e2548e0970cf96f573ff6b99f804a36ad683 F src/vdbeInt.h 0112cab1c820a599005c6bcc9504bdb17f5dbcdb F src/vdbeapi.c b816227ece97354aee7a741c1fc3c5445202d8bb -F src/vdbeaux.c 684c159170453c8a118786b9c174627ece825f3a +F src/vdbeaux.c b49b277bcac5ac1e14165f13b7cd320b5333f420 F src/vdbeblob.c 11248c6362389569764682eb0f59ce910f3cc381 F src/vdbemem.c 833005f1cbbf447289f1973dba2a0c2228c7b8ab F src/vdbesort.c c61ca318681c0e7267da8be3abfca8469652a7e9 @@ -1022,7 +1022,7 @@ F tool/mkkeywordhash.c bb52064aa614e1426445e4b2b9b00eeecd23cc79 F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 F tool/mksqlite3c-noext.tcl 8bce31074e4cbe631bb7676526a048335f4c9f02 -F tool/mksqlite3c.tcl 589c7f44e990be1b8443cfe4808dce392b0327fa +F tool/mksqlite3c.tcl bb8afe0948d88d5d9e6f80d75f2b89face94af08 F tool/mksqlite3h.tcl 78013ad79a5e492e5f764f3c7a8ef834255061f8 F tool/mksqlite3internalh.tcl 3dca7bb5374cee003379b8cbac73714f610ef795 F tool/mkvsix.tcl 0be7f7a591f1e83f9199cb82911b66668ca484c9 @@ -1051,7 +1051,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P 62adb0e0d70e619becb68ffd2625d979bcc777cd 839aa91faf1db7025d90fa3c65e50efb829b053b -R f971c8bcbe5e7e01d3f1960cb48792c9 -U dan -Z 72580c54b4ef9e18ca4a1b86983b9c48 +P d6cd3c780c6bc718d37e0f0b884e3e9a423d57be +R 8d8bef3ec05b88293bab641b3f53c396 +U drh +Z 2a31f3327a39b82b184325a96aea6d38 diff --git a/manifest.uuid b/manifest.uuid index 5a3c033a66..cad3cf8107 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d6cd3c780c6bc718d37e0f0b884e3e9a423d57be \ No newline at end of file +e54b0225f226a163ec874df7d4b738efba12b3a7 \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 7a676a2e39..b54d6b918f 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -3313,7 +3313,7 @@ void sqlite3VdbePreUpdateHook( preupdate.keyinfo.db = db; preupdate.keyinfo.enc = ENC(db); preupdate.keyinfo.nField = pTab->nCol; - preupdate.keyinfo.aSortOrder = &fakeSortOrder; + preupdate.keyinfo.aSortOrder = (u8*)&fakeSortOrder; preupdate.iKey1 = iKey1; preupdate.iKey2 = iKey2; preupdate.iPKey = pTab->iPKey; diff --git a/tool/mksqlite3c.tcl b/tool/mksqlite3c.tcl index 2c569d7a4e..d08d9d2f1b 100644 --- a/tool/mksqlite3c.tcl +++ b/tool/mksqlite3c.tcl @@ -108,6 +108,7 @@ foreach hdr { parse.h pcache.h rtree.h + sqlite3session.h sqlite3ext.h sqlite3.h sqliteicu.h @@ -319,6 +320,8 @@ foreach file { rtree.c icu.c fts3_icu.c + + sqlite3session.c } { copy_file tsrc/$file } From 8ce2b0956abf53d952ef30c7339095930a707fff Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 13 Mar 2013 12:20:15 +0000 Subject: [PATCH 0069/1484] Fix main.mk so that it builds the amalgamation correctly. FossilOrigin-Name: 0b84e277245f10f928c010ea5958923681c6d582 --- main.mk | 9 +++++++-- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/main.mk b/main.mk index d5b8d69811..dbd29d0ac7 100644 --- a/main.mk +++ b/main.mk @@ -207,6 +207,9 @@ SRC += \ SRC += \ $(TOP)/ext/rtree/rtree.h \ $(TOP)/ext/rtree/rtree.c +SRC += \ + $(TOP)/ext/session/sqlite3session.c \ + $(TOP)/ext/session/sqlite3session.h # Generated source code files @@ -533,7 +536,8 @@ tclsqlite3: $(TOP)/src/tclsqlite.c libsqlite3.a $(TCCX) $(TCL_FLAGS) -DTCLSH=1 -o tclsqlite3 \ $(TOP)/src/tclsqlite.c libsqlite3.a $(LIBTCL) $(THREADLIB) -sqlite3_analyzer.c: sqlite3.c $(TOP)/src/test_stat.c $(TOP)/src/tclsqlite.c $(TOP)/tool/spaceanal.tcl +sqlite3_analyzer.c: sqlite3.c $(TOP)/src/test_stat.c $(TOP)/src/tclsqlite.c \ + $(TOP)/tool/spaceanal.tcl echo "#define TCLSH 2" > $@ cat sqlite3.c $(TOP)/src/test_stat.c $(TOP)/src/tclsqlite.c >> $@ echo "static const char *tclsh_main_loop(void){" >> $@ @@ -581,7 +585,8 @@ test: testfixture$(EXE) sqlite3$(EXE) # threadtest runs a few thread-safety tests that are implemented in C. This # target is invoked by the releasetest.tcl script. # -threadtest3$(EXE): sqlite3.o $(TOP)/test/threadtest3.c $(TOP)/test/tt3_checkpoint.c +threadtest3$(EXE): sqlite3.o $(TOP)/test/threadtest3.c \ + $(TOP)/test/tt3_checkpoint.c $(TCCX) -O2 sqlite3.o $(TOP)/test/threadtest3.c \ -o threadtest3$(EXE) $(THREADLIB) diff --git a/manifest b/manifest index 10fc165232..82a4228fcd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\scompiler\swarning\sin\ssqlite3VdbePreUpdateHook().\nAdd\ssqlite3session.c\sto\sthe\samalgamation.\nFix\sthe\sMakefile.in\sto\swork\swith\ssessions. -D 2013-03-13T11:42:00.694 +C Fix\smain.mk\sso\sthat\sit\sbuilds\sthe\samalgamation\scorrectly. +D 2013-03-13T12:20:15.110 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in f33fad60e6fa3cc15f6a39609a256b340a1c12d9 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -115,7 +115,7 @@ F ext/session/sqlite3session.h f374c9c4c96e08f67ac418871c29d423245c7673 F ext/session/test_session.c ea4dc9b4a1895c8e6bddcbfe3838d7eb57df2d99 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 -F main.mk 787401c56823d6cf0d2fa01540d04bd438b11ee5 +F main.mk 9422cb87866650146b89d742c666e8abd5e1ab6a F mkdll.sh 7d09b23c05d56532e9d44a50868eb4b12ff4f74a F mkextu.sh 416f9b7089d80e5590a29692c9d9280a10dbad9f F mkextw.sh 4123480947681d9b434a5e7b1ee08135abe409ac @@ -1051,7 +1051,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P d6cd3c780c6bc718d37e0f0b884e3e9a423d57be -R 8d8bef3ec05b88293bab641b3f53c396 +P e54b0225f226a163ec874df7d4b738efba12b3a7 +R df3120294f1b47f95d03bbfec72e5f33 U drh -Z 2a31f3327a39b82b184325a96aea6d38 +Z 1665add974d8ea78c75d5773b499e48a diff --git a/manifest.uuid b/manifest.uuid index cad3cf8107..6803c7b87d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e54b0225f226a163ec874df7d4b738efba12b3a7 \ No newline at end of file +0b84e277245f10f928c010ea5958923681c6d582 \ No newline at end of file From 38b4daa12227b0628302945f07b8faaf9dafafca Mon Sep 17 00:00:00 2001 From: mistachkin Date: Wed, 13 Mar 2013 19:02:39 +0000 Subject: [PATCH 0070/1484] Fix typos in MSVC makefile. FossilOrigin-Name: 2d15c2685750b930c5b7e2f06cb056b24a037967 --- Makefile.msc | 3 ++- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/Makefile.msc b/Makefile.msc index a15c755d2e..dea8ee8cd6 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -233,6 +233,7 @@ RCC = $(RCC) -I$(TOP)\ext\fts3 TCC = $(TCC) -I$(TOP)\ext\rtree RCC = $(RCC) -I$(TOP)\ext\rtree TCC = $(TCC) -I$(TOP)\ext\session +RCC = $(RCC) -I$(TOP)\ext\session !ENDIF # Define -DNDEBUG to compile without debugging (i.e., for production usage) @@ -1200,7 +1201,7 @@ fts3_write.lo: $(TOP)\ext\fts3\fts3_write.c $(HDR) $(EXTHDR) rtree.lo: $(TOP)\ext\rtree\rtree.c $(HDR) $(EXTHDR) $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)\ext\rtree\rtree.c -rtree.lo: $(TOP)\ext\session\sqlite3sesion.c $(HDR) $(EXTHDR) +sqlite3session.lo: $(TOP)\ext\session\sqlite3sesion.c $(HDR) $(EXTHDR) $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)\ext\session\sqlite3session.c diff --git a/manifest b/manifest index 82a4228fcd..d5d4db2ad3 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Fix\smain.mk\sso\sthat\sit\sbuilds\sthe\samalgamation\scorrectly. -D 2013-03-13T12:20:15.110 +C Fix\stypos\sin\sMSVC\smakefile. +D 2013-03-13T19:02:39.185 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in f33fad60e6fa3cc15f6a39609a256b340a1c12d9 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 -F Makefile.msc 29bce8fa86dc10ffeb5ac11537c0e12c3a3e6887 +F Makefile.msc 50121cf9f55dd2bd06ed70007c9c48d89f2c230b F Makefile.vxworks b18ad88e9a8c6a001f5cf4a389116a4f1a7ab45f F README cd04a36fbc7ea56932a4052d7d0b7f09f27c33d6 F VERSION 6d4f66eaebabc42ef8c2a4d2d0caf4ce7ee81137 @@ -1051,7 +1051,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P e54b0225f226a163ec874df7d4b738efba12b3a7 -R df3120294f1b47f95d03bbfec72e5f33 -U drh -Z 1665add974d8ea78c75d5773b499e48a +P 0b84e277245f10f928c010ea5958923681c6d582 +R 8936b43e7cb6239a57717295926fbe09 +U mistachkin +Z 90881652b49d2ff478c663d912137eaa diff --git a/manifest.uuid b/manifest.uuid index 6803c7b87d..c29d8d46f9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0b84e277245f10f928c010ea5958923681c6d582 \ No newline at end of file +2d15c2685750b930c5b7e2f06cb056b24a037967 \ No newline at end of file From e191e2c6d0cbc85e07f57b4dbd10e3a2b94c470e Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 19 Mar 2013 15:23:18 +0000 Subject: [PATCH 0071/1484] Include the sqlite3session.h header file in with sqlite3.h. Make sure the session APIs are all public. FossilOrigin-Name: ec490336bc6629d3910667ece1bbc4685a199546 --- Makefile.in | 5 ++++- Makefile.msc | 3 +++ main.mk | 6 +++++- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- tool/mksqlite3c.tcl | 5 +++-- tool/mksqlite3h.tcl | 10 ++++++++-- 7 files changed, 34 insertions(+), 17 deletions(-) diff --git a/Makefile.in b/Makefile.in index 634c7a3654..0ea9498be0 100644 --- a/Makefile.in +++ b/Makefile.in @@ -528,6 +528,8 @@ sqlite3$(TEXE): $(TOP)/src/shell.c libsqlite3.la sqlite3.h sqlite3.c: .target_source $(TOP)/tool/mksqlite3c.tcl $(TCLSH_CMD) $(TOP)/tool/mksqlite3c.tcl + cp tsrc/shell.c tsrc/sqlite3ext.h . + cp $(TOP)/ext/session/sqlite3session.h . tclsqlite3.c: sqlite3.c echo '#ifndef USE_SYSTEM_SQLITE' >tclsqlite3.c @@ -890,7 +892,8 @@ TESTFIXTURE_FLAGS += -DBUILD_sqlite TESTFIXTURE_SRC0 = $(TESTSRC2) libsqlite3.la TESTFIXTURE_SRC1 = sqlite3.c -TESTFIXTURE_SRC = $(TESTSRC) $(TOP)/src/tclsqlite.c $(TESTFIXTURE_SRC$(USE_AMALGAMATION)) +TESTFIXTURE_SRC = $(TESTSRC) $(TOP)/src/tclsqlite.c +TESTFIXTURE_SRC += $(TESTFIXTURE_SRC$(USE_AMALGAMATION)) testfixture$(TEXE): $(TESTFIXTURE_SRC) $(LTLINK) -DSQLITE_NO_SYNC=1 $(TEMP_STORE) $(TESTFIXTURE_FLAGS) \ diff --git a/Makefile.msc b/Makefile.msc index 00e4ffbe8d..8f34c6cc2d 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -849,6 +849,9 @@ sqlite3.exe: $(TOP)\src\shell.c libsqlite3.lib $(LIBRESOBJS) sqlite3.h sqlite3.c: .target_source $(TOP)\tool\mksqlite3c.tcl $(TCLSH_CMD) $(TOP)\tool\mksqlite3c.tcl + copy tsrc\shell.c . + copy tsrc\sqlite3ext.h . + copy $(TOP)\ext\session\sqlite3session.h . sqlite3-all.c: sqlite3.c $(TOP)\tool\split-sqlite3c.tcl $(TCLSH_CMD) $(TOP)\tool\split-sqlite3c.tcl diff --git a/main.mk b/main.mk index dbd29d0ac7..5faf2fb8e9 100644 --- a/main.mk +++ b/main.mk @@ -391,6 +391,8 @@ target_source: $(SRC) $(TOP)/tool/vdbe-compress.tcl sqlite3.c: target_source $(TOP)/tool/mksqlite3c.tcl tclsh $(TOP)/tool/mksqlite3c.tcl + cp tsrc/shell.c tsrc/sqlite3ext.h . + cp $(TOP)/ext/session/sqlite3session.h . echo '#ifndef USE_SYSTEM_SQLITE' >tclsqlite3.c cat sqlite3.c >>tclsqlite3.c echo '#endif /* USE_SYSTEM_SQLITE */' >>tclsqlite3.c @@ -558,9 +560,11 @@ testfixture$(EXE): $(TESTSRC2) libsqlite3.a $(TESTSRC) $(TOP)/src/tclsqlite.c $(TESTSRC) $(TESTSRC2) $(TOP)/src/tclsqlite.c \ -o testfixture$(EXE) $(LIBTCL) libsqlite3.a $(THREADLIB) -amalgamation-testfixture$(EXE): sqlite3.c $(TESTSRC) $(TOP)/src/tclsqlite.c +amalgamation-testfixture$(EXE): sqlite3.c $(TESTSRC) $(TOP)/src/tclsqlite.c \ + $(TOP)/ext/session/test_session.c $(TCCX) $(TCL_FLAGS) -DTCLSH=1 $(TESTFIXTURE_FLAGS) \ $(TESTSRC) $(TOP)/src/tclsqlite.c sqlite3.c \ + $(TOP)/ext/session/test_session.c \ -o testfixture$(EXE) $(LIBTCL) $(THREADLIB) fts3-testfixture$(EXE): sqlite3.c fts3amal.c $(TESTSRC) $(TOP)/src/tclsqlite.c diff --git a/manifest b/manifest index 60723169d4..7c7192ad81 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Adjust\sthe\sMSVC\smakefile\sso\sthat\sit\scorrectly\shandles\sthe\ssessions\nextension\sbeing\sincluded\sin\sthe\samalgamation.\s\sImport\sthe\stest\scase\nchanges\sthat\sappeared\sin\s3.7.16\sfinal. -D 2013-03-18T16:24:33.543 +C Include\sthe\ssqlite3session.h\sheader\sfile\sin\swith\ssqlite3.h.\s\sMake\ssure\nthe\ssession\sAPIs\sare\sall\spublic. +D 2013-03-19T15:23:18.846 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f -F Makefile.in f33fad60e6fa3cc15f6a39609a256b340a1c12d9 +F Makefile.in 174bfca74e57f38699e3412a984f6b38106750fa F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 -F Makefile.msc c56c19e93d5de6dde495d68d28d8455a5bab9917 +F Makefile.msc 0ad7d4278a3b7e0c56d3ca7cc607b34acc1df516 F Makefile.vxworks b18ad88e9a8c6a001f5cf4a389116a4f1a7ab45f F README cd04a36fbc7ea56932a4052d7d0b7f09f27c33d6 F VERSION 6d4f66eaebabc42ef8c2a4d2d0caf4ce7ee81137 @@ -115,7 +115,7 @@ F ext/session/sqlite3session.h f374c9c4c96e08f67ac418871c29d423245c7673 F ext/session/test_session.c ea4dc9b4a1895c8e6bddcbfe3838d7eb57df2d99 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 -F main.mk 9422cb87866650146b89d742c666e8abd5e1ab6a +F main.mk 01f02b625cc1b8609690aaddb00e2fbb1edbeec5 F mkdll.sh 7d09b23c05d56532e9d44a50868eb4b12ff4f74a F mkextu.sh 416f9b7089d80e5590a29692c9d9280a10dbad9f F mkextw.sh 4123480947681d9b434a5e7b1ee08135abe409ac @@ -1022,8 +1022,8 @@ F tool/mkkeywordhash.c bb52064aa614e1426445e4b2b9b00eeecd23cc79 F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 F tool/mksqlite3c-noext.tcl 8bce31074e4cbe631bb7676526a048335f4c9f02 -F tool/mksqlite3c.tcl bb8afe0948d88d5d9e6f80d75f2b89face94af08 -F tool/mksqlite3h.tcl 78013ad79a5e492e5f764f3c7a8ef834255061f8 +F tool/mksqlite3c.tcl aa76553fe5f5fc93772f3bb1d1626421b454e7e5 +F tool/mksqlite3h.tcl 280a819542c2a001c342e4bfe829974a76cb449e F tool/mksqlite3internalh.tcl 3dca7bb5374cee003379b8cbac73714f610ef795 F tool/mkvsix.tcl 0be7f7a591f1e83f9199cb82911b66668ca484c9 F tool/offsets.c fe4262fdfa378e8f5499a42136d17bf3b98f6091 @@ -1051,7 +1051,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P 2d15c2685750b930c5b7e2f06cb056b24a037967 66d5f2b76750f3520eb7a495f6247206758f5b90 -R 2176dc6cddaef86d42b3729c5996485e +P 9bac09a99aef5f18386037b409869d760c520d53 +R f21fcc9e1243effe28692f83a9850041 U drh -Z 1f183a91c30c6bc258b1a36f7025012a +Z b7b8384c096e1370a180493dde9bfbdb diff --git a/manifest.uuid b/manifest.uuid index 742ad126ba..590d021b04 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9bac09a99aef5f18386037b409869d760c520d53 \ No newline at end of file +ec490336bc6629d3910667ece1bbc4685a199546 \ No newline at end of file diff --git a/tool/mksqlite3c.tcl b/tool/mksqlite3c.tcl index d08d9d2f1b..81bcf07bcf 100644 --- a/tool/mksqlite3c.tcl +++ b/tool/mksqlite3c.tcl @@ -23,7 +23,7 @@ # # Begin by reading the "sqlite3.h" header file. Extract the version number -# from in this file. The versioon number is needed to generate the header +# from in this file. The version number is needed to generate the header # comment of the amalgamation. # if {[lsearch $argv --nostatic]>=0} { @@ -121,6 +121,7 @@ foreach hdr { set available_hdr($hdr) 1 } set available_hdr(sqliteInt.h) 0 +set available_hdr(sqlite3session.h) 0 # 78 stars used for comment formatting. set s78 \ @@ -182,7 +183,7 @@ proc copy_file {filename} { if {[regexp $declpattern $line all funcname]} { # Add the SQLITE_PRIVATE or SQLITE_API keyword before functions. # so that linkage can be modified at compile-time. - if {[regexp {^sqlite3_} $funcname]} { + if {[regexp {^sqlite3(session)?_} $funcname]} { puts $out "SQLITE_API $line" } else { puts $out "SQLITE_PRIVATE $line" diff --git a/tool/mksqlite3h.tcl b/tool/mksqlite3h.tcl index f68f61a368..5241f8dc00 100644 --- a/tool/mksqlite3h.tcl +++ b/tool/mksqlite3h.tcl @@ -68,9 +68,15 @@ set declpattern {^ *[a-zA-Z][a-zA-Z_0-9 ]+ \**sqlite3_[_a-zA-Z0-9]+\(} # Force the output to use unix line endings, even on Windows. fconfigure stdout -translation lf -# Process the src/sqlite.h.in ext/rtree/sqlite3rtree.h files. +set filelist [subst { + $TOP/src/sqlite.h.in + $TOP/ext/rtree/sqlite3rtree.h + $TOP/ext/session/sqlite3session.h +}] + +# Process the source files. # -foreach file [list $TOP/src/sqlite.h.in $TOP/ext/rtree/sqlite3rtree.h] { +foreach file $filelist { set in [open $file] while {![eof $in]} { From 1ffe7c7fab56b93f291abfe474a6a1995421e5fb Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 19 Mar 2013 17:10:10 +0000 Subject: [PATCH 0072/1484] Also export the sqlite3changeset interfaces in the amalgamated version of the sessions extension. FossilOrigin-Name: 5b399f2bc43612c52ea2289001d852d7ba6f9750 --- ext/session/sqlite3session.c | 4 ++-- manifest | 16 ++++++++-------- manifest.uuid | 2 +- tool/mksqlite3c.tcl | 2 +- tool/symbols.sh | 2 +- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index 778caad591..15865e6b90 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -1125,7 +1125,7 @@ int sqlite3session_create( ** Free the list of table objects passed as the first argument. The contents ** of the changed-rows hash tables are also deleted. */ -void sessionDeleteTable(SessionTable *pList){ +static void sessionDeleteTable(SessionTable *pList){ SessionTable *pNext; SessionTable *pTab; @@ -3074,7 +3074,7 @@ static int sessionChangeMerge( ** Add all changes in the changeset passed via the first two arguments to ** hash tables. */ -int sessionConcatChangeset( +static int sessionConcatChangeset( int nChangeset, /* Number of bytes in pChangeset */ void *pChangeset, /* Changeset buffer */ SessionTable **ppTabList /* IN/OUT: List of table objects */ diff --git a/manifest b/manifest index 7c7192ad81..d3b33519de 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Include\sthe\ssqlite3session.h\sheader\sfile\sin\swith\ssqlite3.h.\s\sMake\ssure\nthe\ssession\sAPIs\sare\sall\spublic. -D 2013-03-19T15:23:18.846 +C Also\sexport\sthe\ssqlite3changeset\sinterfaces\sin\sthe\samalgamated\sversion\sof\nthe\ssessions\sextension. +D 2013-03-19T17:10:10.376 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 174bfca74e57f38699e3412a984f6b38106750fa F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -110,7 +110,7 @@ F ext/session/session6.test 443789bc2fca12e4f7075cf692c60b8a2bea1a26 F ext/session/session8.test 7d35947ad329b8966f095d34f9617a9eff52dc65 F ext/session/session_common.tcl 1539d8973b2aea0025c133eb0cc4c89fcef541a5 F ext/session/sessionfault.test 496291b287ba3c0b14ca2e074425e29cc92a64a6 -F ext/session/sqlite3session.c 57d04e1d6a3579e673e61dea29f214fb4e0fc505 +F ext/session/sqlite3session.c 7d7ca693bd581243835ee47b41b491bd909a26f4 F ext/session/sqlite3session.h f374c9c4c96e08f67ac418871c29d423245c7673 F ext/session/test_session.c ea4dc9b4a1895c8e6bddcbfe3838d7eb57df2d99 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x @@ -1022,7 +1022,7 @@ F tool/mkkeywordhash.c bb52064aa614e1426445e4b2b9b00eeecd23cc79 F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 F tool/mksqlite3c-noext.tcl 8bce31074e4cbe631bb7676526a048335f4c9f02 -F tool/mksqlite3c.tcl aa76553fe5f5fc93772f3bb1d1626421b454e7e5 +F tool/mksqlite3c.tcl 521b39c2d2987c4257919b97a3cfb3bd4a394bf1 F tool/mksqlite3h.tcl 280a819542c2a001c342e4bfe829974a76cb449e F tool/mksqlite3internalh.tcl 3dca7bb5374cee003379b8cbac73714f610ef795 F tool/mkvsix.tcl 0be7f7a591f1e83f9199cb82911b66668ca484c9 @@ -1045,13 +1045,13 @@ F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c F tool/stack_usage.tcl f8e71b92cdb099a147dad572375595eae55eca43 F tool/symbols-mingw.sh 4dbcea7e74768305384c9fd2ed2b41bbf9f0414d -F tool/symbols.sh fec58532668296d7c7dc48be9c87f75ccdb5814f +F tool/symbols.sh c5a617b8c61a0926747a56c65f5671ef8ac0e148 F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P 9bac09a99aef5f18386037b409869d760c520d53 -R f21fcc9e1243effe28692f83a9850041 +P ec490336bc6629d3910667ece1bbc4685a199546 +R feb292609e6100e1f2edd6a494c7d523 U drh -Z b7b8384c096e1370a180493dde9bfbdb +Z 6c74b8c2b0cc569ec1ecb44db9287f05 diff --git a/manifest.uuid b/manifest.uuid index 590d021b04..69c2acc8d3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ec490336bc6629d3910667ece1bbc4685a199546 \ No newline at end of file +5b399f2bc43612c52ea2289001d852d7ba6f9750 \ No newline at end of file diff --git a/tool/mksqlite3c.tcl b/tool/mksqlite3c.tcl index 81bcf07bcf..4058631bbf 100644 --- a/tool/mksqlite3c.tcl +++ b/tool/mksqlite3c.tcl @@ -183,7 +183,7 @@ proc copy_file {filename} { if {[regexp $declpattern $line all funcname]} { # Add the SQLITE_PRIVATE or SQLITE_API keyword before functions. # so that linkage can be modified at compile-time. - if {[regexp {^sqlite3(session)?_} $funcname]} { + if {[regexp {^sqlite3[a-z]*_} $funcname]} { puts $out "SQLITE_API $line" } else { puts $out "SQLITE_PRIVATE $line" diff --git a/tool/symbols.sh b/tool/symbols.sh index befffce5c4..5e80078fa3 100644 --- a/tool/symbols.sh +++ b/tool/symbols.sh @@ -10,7 +10,7 @@ gcc -c -DSQLITE_ENABLE_FTS3 -DSQLITE_ENABLE_RTREE \ -DSQLITE_ENABLE_MEMORY_MANAGEMENT -DSQLITE_ENABLE_STAT3 \ -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_ENABLE_UNLOCK_NOTIFY \ -DSQLITE_ENABLE_COLUMN_METADATA -DSQLITE_ENABLE_ATOMIC_WRITE \ - -DSQLITE_ENABLE_ICU \ + -DSQLITE_ENABLE_ICU -DSQLITE_ENABLE_PREUPDATE_HOOK -DSQLITE_ENABLE_SESSION \ sqlite3.c nm sqlite3.o | grep ' [TD] ' | sort -k 3 From eeeee7f55d25594f8025f637aa343a449e8b6bb9 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 10 Apr 2013 15:01:36 +0000 Subject: [PATCH 0073/1484] Designate the beginning and the end of the sqlite3session.h file in the constructed sqlite3.h file. FossilOrigin-Name: 53f5be74327162a2bd25a91eaf7c91b126294727 --- manifest | 12 ++++++------ manifest.uuid | 2 +- tool/mksqlite3h.tcl | 6 ++++++ 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 0c1f9bd6b6..59b640372d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sthe\schanges\sfor\sthe\s3.7.16.1\srelease\scandidate\sinto\sthe\ssessions\sbranch. -D 2013-03-28T01:19:26.359 +C Designate\sthe\sbeginning\sand\sthe\send\sof\sthe\ssqlite3session.h\sfile\sin\sthe\nconstructed\ssqlite3.h\sfile. +D 2013-04-10T15:01:36.565 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 174bfca74e57f38699e3412a984f6b38106750fa F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -1026,7 +1026,7 @@ F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 F tool/mksqlite3c-noext.tcl 8bce31074e4cbe631bb7676526a048335f4c9f02 F tool/mksqlite3c.tcl 521b39c2d2987c4257919b97a3cfb3bd4a394bf1 -F tool/mksqlite3h.tcl 280a819542c2a001c342e4bfe829974a76cb449e +F tool/mksqlite3h.tcl c26c2c00f6402dff490b9d088b35022a65079f9b F tool/mksqlite3internalh.tcl 3dca7bb5374cee003379b8cbac73714f610ef795 F tool/mkvsix.tcl 0be7f7a591f1e83f9199cb82911b66668ca484c9 F tool/offsets.c fe4262fdfa378e8f5499a42136d17bf3b98f6091 @@ -1054,7 +1054,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P 5b399f2bc43612c52ea2289001d852d7ba6f9750 274d2a22660c7b34b8bbd85f3c29cbafbcb1b4e7 -R b02a4b1d8d4060ecab7247b46b1af3cb +P ee35a89712b8ea9f4e70d61a29150348896b519f +R 100e7ec13abd2ea8455e764a279a1723 U drh -Z 8200523e839d9fbff750764d761a16eb +Z 4925298600da5fcf8376b1bdce3109e3 diff --git a/manifest.uuid b/manifest.uuid index 1cd07d6476..1c9ae4b351 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ee35a89712b8ea9f4e70d61a29150348896b519f \ No newline at end of file +53f5be74327162a2bd25a91eaf7c91b126294727 \ No newline at end of file diff --git a/tool/mksqlite3h.tcl b/tool/mksqlite3h.tcl index 5241f8dc00..55e7ad287e 100644 --- a/tool/mksqlite3h.tcl +++ b/tool/mksqlite3h.tcl @@ -78,6 +78,9 @@ set filelist [subst { # foreach file $filelist { set in [open $file] + if {![regexp {sqlite.h.in} $file]} { + puts "/******** Begin file [file tail $file] *********/" + } while {![eof $in]} { set line [gets $in] @@ -109,4 +112,7 @@ foreach file $filelist { puts $line } close $in + if {![regexp {sqlite.h.in} $file]} { + puts "/******** End of [file tail $file] *********/" + } } From 73c4041b4303308b607179d917411941f74e9d1f Mon Sep 17 00:00:00 2001 From: mistachkin Date: Thu, 11 Apr 2013 00:45:28 +0000 Subject: [PATCH 0074/1484] Correct minor typo in two regular expressions. FossilOrigin-Name: f1eed92b7b0ef4ee22a11d8bb4f9a572b56ce019 --- manifest | 14 +++++++------- manifest.uuid | 2 +- tool/mksqlite3h.tcl | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 59b640372d..97541883c8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Designate\sthe\sbeginning\sand\sthe\send\sof\sthe\ssqlite3session.h\sfile\sin\sthe\nconstructed\ssqlite3.h\sfile. -D 2013-04-10T15:01:36.565 +C Correct\sminor\stypo\sin\stwo\sregular\sexpressions. +D 2013-04-11T00:45:28.510 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 174bfca74e57f38699e3412a984f6b38106750fa F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -1026,7 +1026,7 @@ F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 F tool/mksqlite3c-noext.tcl 8bce31074e4cbe631bb7676526a048335f4c9f02 F tool/mksqlite3c.tcl 521b39c2d2987c4257919b97a3cfb3bd4a394bf1 -F tool/mksqlite3h.tcl c26c2c00f6402dff490b9d088b35022a65079f9b +F tool/mksqlite3h.tcl 2d0f1b3768f8d000b7881217d5fd4c776eb27467 F tool/mksqlite3internalh.tcl 3dca7bb5374cee003379b8cbac73714f610ef795 F tool/mkvsix.tcl 0be7f7a591f1e83f9199cb82911b66668ca484c9 F tool/offsets.c fe4262fdfa378e8f5499a42136d17bf3b98f6091 @@ -1054,7 +1054,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P ee35a89712b8ea9f4e70d61a29150348896b519f -R 100e7ec13abd2ea8455e764a279a1723 -U drh -Z 4925298600da5fcf8376b1bdce3109e3 +P 53f5be74327162a2bd25a91eaf7c91b126294727 +R 135af717c2fd2e17b5a8c6896e5cb14f +U mistachkin +Z b1ea33e149cde9618b3874273f57fbc4 diff --git a/manifest.uuid b/manifest.uuid index 1c9ae4b351..642c124c19 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -53f5be74327162a2bd25a91eaf7c91b126294727 \ No newline at end of file +f1eed92b7b0ef4ee22a11d8bb4f9a572b56ce019 \ No newline at end of file diff --git a/tool/mksqlite3h.tcl b/tool/mksqlite3h.tcl index 55e7ad287e..323111bb30 100644 --- a/tool/mksqlite3h.tcl +++ b/tool/mksqlite3h.tcl @@ -78,7 +78,7 @@ set filelist [subst { # foreach file $filelist { set in [open $file] - if {![regexp {sqlite.h.in} $file]} { + if {![regexp {sqlite\.h\.in} $file]} { puts "/******** Begin file [file tail $file] *********/" } while {![eof $in]} { @@ -112,7 +112,7 @@ foreach file $filelist { puts $line } close $in - if {![regexp {sqlite.h.in} $file]} { + if {![regexp {sqlite\.h\.in} $file]} { puts "/******** End of [file tail $file] *********/" } } From 7f6e147a5105607c07a229433fae3a33588be247 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 11 Apr 2013 19:04:20 +0000 Subject: [PATCH 0075/1484] Increase the version number to 3.7.16.2 and cherrypick the fix for ticket [7ff3120e4fa54abb55]. This check-in is a release candidate. FossilOrigin-Name: 86f26f9152988e47d7e1cfcca9eedf5e6265a225 --- VERSION | 2 +- configure | 18 +++++++++--------- manifest | 22 +++++++++++----------- manifest.uuid | 2 +- src/os_win.c | 2 +- 5 files changed, 23 insertions(+), 23 deletions(-) diff --git a/VERSION b/VERSION index 9efca4c4be..d225ed60b2 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.7.16.1 +3.7.16.2 diff --git a/configure b/configure index ddd6364831..88939d6087 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.62 for sqlite 3.7.16.1. +# Generated by GNU Autoconf 2.62 for sqlite 3.7.16.2. # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, # 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. @@ -743,8 +743,8 @@ SHELL=${CONFIG_SHELL-/bin/sh} # Identity of this package. PACKAGE_NAME='sqlite' PACKAGE_TARNAME='sqlite' -PACKAGE_VERSION='3.7.16.1' -PACKAGE_STRING='sqlite 3.7.16.1' +PACKAGE_VERSION='3.7.16.2' +PACKAGE_STRING='sqlite 3.7.16.2' PACKAGE_BUGREPORT='' # Factoring default headers for most tests. @@ -1484,7 +1484,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.7.16.1 to adapt to many kinds of systems. +\`configure' configures sqlite 3.7.16.2 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1549,7 +1549,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of sqlite 3.7.16.1:";; + short | recursive ) echo "Configuration of sqlite 3.7.16.2:";; esac cat <<\_ACEOF @@ -1665,7 +1665,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -sqlite configure 3.7.16.1 +sqlite configure 3.7.16.2 generated by GNU Autoconf 2.62 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -1679,7 +1679,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.7.16.1, which was +It was created by sqlite $as_me 3.7.16.2, which was generated by GNU Autoconf 2.62. Invocation command line was $ $0 $@ @@ -14032,7 +14032,7 @@ exec 6>&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.7.16.1, which was +This file was extended by sqlite $as_me 3.7.16.2, which was generated by GNU Autoconf 2.62. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -14085,7 +14085,7 @@ Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_version="\\ -sqlite config.status 3.7.16.1 +sqlite config.status 3.7.16.2 configured by $0, generated by GNU Autoconf 2.62, with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" diff --git a/manifest b/manifest index 5cf11cc2fb..96c0f8867c 100644 --- a/manifest +++ b/manifest @@ -1,12 +1,12 @@ -C Version\s3.7.16.1 -D 2013-03-29T13:44:34.265 +C Increase\sthe\sversion\snumber\sto\s3.7.16.2\sand\scherrypick\sthe\nfix\sfor\sticket\s[7ff3120e4fa54abb55].\s\sThis\scheck-in\sis\sa\srelease\ncandidate. +D 2013-04-11T19:04:20.543 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in df3e48659d80e1b7765785d8d66c86b320f72cc7 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 F Makefile.msc 0c1abc21c8deefc88e8a32ad6a07e5f96e158761 F Makefile.vxworks b18ad88e9a8c6a001f5cf4a389116a4f1a7ab45f F README cd04a36fbc7ea56932a4052d7d0b7f09f27c33d6 -F VERSION 05604ccde96fe1b37f922eddbdcb5654308261db +F VERSION 0dee4d2e0c64791ff0085277424fb5c07d79fc9a F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 F addopcodes.awk 17dc593f791f874d2c23a0f9360850ded0286531 F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 @@ -15,7 +15,7 @@ F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977 F config.h.in 0921066a13130082764ab4ab6456f7b5bebe56de F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55 -F configure 2f9994fd2e2005753809a2246c7a0816c80b2d2f x +F configure 1a5f411b3c5053495a161609c274393281db12cc x F configure.ac 81c43d151d0b0e406be056394cc9ff4cb3fd0444 F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad F doc/lemon.html 334dbf6621b8fb8790297ec1abf3cfa4621709d1 @@ -161,7 +161,7 @@ F src/os.c e1acdc09ff3ac2412945cca9766e2dcf4675f31c F src/os.h 027491c77d2404c0a678bb3fb06286f331eb9b57 F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_unix.c 21a36fa0b3753609b6606b30d9338d4bb6b24696 -F src/os_win.c 9fe5356f943425ab8431237bd3a4297044928b70 +F src/os_win.c c96990935e7fd799b43a7f0ee74798f45f06e21a F src/pager.c 3e9a15939684b0af441325f05335331b15979c9d F src/pager.h 1109a06578ec5574dc2c74cf8d9f69daf36fe3e0 F src/parse.y 5d5e12772845805fdfeb889163516b84fbb9ae95 @@ -1041,10 +1041,10 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P 39534b4baa53b9360696a9d5ee8cc2108af34592 -R e8e4e98970281a95c0de62c6e5f4d562 -T +bgcolor * #d0c0ff -T +sym-release * -T +sym-version-3.7.16.1 * +P 527231bc67285f01fb18d4451b28f61da3c4e39d +R c66fa2b9be1b92880a65bec11685cd9d +T *branch * branch-3.7.16 +T *sym-branch-3.7.16 * +T -sym-trunk * U drh -Z 17d1076ce5eb9d83e75734278cd22a73 +Z 2720d0b49f6dbe5c13feb9b59916963e diff --git a/manifest.uuid b/manifest.uuid index 68abab9466..8bc1952ae9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -527231bc67285f01fb18d4451b28f61da3c4e39d \ No newline at end of file +86f26f9152988e47d7e1cfcca9eedf5e6265a225 \ No newline at end of file diff --git a/src/os_win.c b/src/os_win.c index 58ba25f302..4fb6b02a86 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -2641,7 +2641,7 @@ static int winCheckReservedLock(sqlite3_file *id, int *pResOut){ rc = 1; OSTRACE(("TEST WR-LOCK %d %d (local)\n", pFile->h, rc)); }else{ - rc = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, RESERVED_BYTE, 0, 1, 0); + rc = winLockFile(&pFile->h, SQLITE_LOCKFILEEX_FLAGS,RESERVED_BYTE, 0, 1, 0); if( rc ){ winUnlockFile(&pFile->h, RESERVED_BYTE, 0, 1, 0); } From 226fb534ddaaf97e22cbe3ef429adf14000900b5 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 12 Apr 2013 11:52:43 +0000 Subject: [PATCH 0076/1484] Version 3.7.16.2 FossilOrigin-Name: cbea02d93865ce0e06789db95fd9168ebac970c7 --- manifest | 14 +++++++------- manifest.uuid | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 96c0f8867c..86f1645ca1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Increase\sthe\sversion\snumber\sto\s3.7.16.2\sand\scherrypick\sthe\nfix\sfor\sticket\s[7ff3120e4fa54abb55].\s\sThis\scheck-in\sis\sa\srelease\ncandidate. -D 2013-04-11T19:04:20.543 +C Version\s3.7.16.2 +D 2013-04-12T11:52:43.886 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in df3e48659d80e1b7765785d8d66c86b320f72cc7 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -1041,10 +1041,10 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P 527231bc67285f01fb18d4451b28f61da3c4e39d +P 86f26f9152988e47d7e1cfcca9eedf5e6265a225 R c66fa2b9be1b92880a65bec11685cd9d -T *branch * branch-3.7.16 -T *sym-branch-3.7.16 * -T -sym-trunk * +T +bgcolor * #d0c0ff +T +sym-release * +T +sym-version-3.7.16.2 * U drh -Z 2720d0b49f6dbe5c13feb9b59916963e +Z daf56eb23d2f90e92e4839bc9c04cfb7 diff --git a/manifest.uuid b/manifest.uuid index 8bc1952ae9..af054d5354 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -86f26f9152988e47d7e1cfcca9eedf5e6265a225 \ No newline at end of file +cbea02d93865ce0e06789db95fd9168ebac970c7 \ No newline at end of file From 35e2858e980a5c45d37eadc8ec3cb341ff1ed363 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 2 Jul 2013 20:23:40 +0000 Subject: [PATCH 0077/1484] Fixes for the sessions module so that it works with sqlite3_extended_error_codes() set. FossilOrigin-Name: c2972b6aed23f6c76a289534de9ea4732a48f40e --- ext/session/sqlite3session.c | 6 +++--- manifest | 18 +++++++++--------- manifest.uuid | 2 +- test/permutations.test | 8 ++++++++ test/session.test | 3 +++ 5 files changed, 24 insertions(+), 13 deletions(-) diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index 15865e6b90..aa0c4b59db 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -2749,7 +2749,7 @@ static int sessionApplyOneOp( rc = sessionConflictHandler( SQLITE_CHANGESET_DATA, p, pIter, xConflict, pCtx, pbRetry ); - }else if( rc==SQLITE_CONSTRAINT ){ + }else if( (rc&0xff)==SQLITE_CONSTRAINT ){ rc = sessionConflictHandler( SQLITE_CHANGESET_CONFLICT, p, pIter, xConflict, pCtx, 0 ); @@ -2788,7 +2788,7 @@ static int sessionApplyOneOp( SQLITE_CHANGESET_DATA, p, pIter, xConflict, pCtx, pbRetry ); - }else if( rc==SQLITE_CONSTRAINT ){ + }else if( (rc&0xff)==SQLITE_CONSTRAINT ){ /* This is always a CONSTRAINT conflict. */ rc = sessionConflictHandler( SQLITE_CHANGESET_CONFLICT, p, pIter, xConflict, pCtx, 0 @@ -2802,7 +2802,7 @@ static int sessionApplyOneOp( sqlite3_step(p->pInsert); rc = sqlite3_reset(p->pInsert); - if( rc==SQLITE_CONSTRAINT ){ + if( (rc&0xff)==SQLITE_CONSTRAINT ){ rc = sessionConflictHandler( SQLITE_CHANGESET_CONFLICT, p, pIter, xConflict, pCtx, pbReplace ); diff --git a/manifest b/manifest index cb4dedd666..20f746c129 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Bring\sthe\ssessions\sbranch\sup-to-date\swith\sall\sthe\slatest\strunk\schanges. -D 2013-06-26T13:31:50.503 +C Fixes\sfor\sthe\ssessions\smodule\sso\sthat\sit\sworks\swith\ssqlite3_extended_error_codes()\sset. +D 2013-07-02T20:23:40.233 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in aff38bc64c582dd147f18739532198372587b0f0 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -144,7 +144,7 @@ F ext/session/session6.test 443789bc2fca12e4f7075cf692c60b8a2bea1a26 F ext/session/session8.test 7d35947ad329b8966f095d34f9617a9eff52dc65 F ext/session/session_common.tcl 1539d8973b2aea0025c133eb0cc4c89fcef541a5 F ext/session/sessionfault.test 496291b287ba3c0b14ca2e074425e29cc92a64a6 -F ext/session/sqlite3session.c 7d7ca693bd581243835ee47b41b491bd909a26f4 +F ext/session/sqlite3session.c c0867804cc86b219c3905c0cd313408d11f7a409 F ext/session/sqlite3session.h f374c9c4c96e08f67ac418871c29d423245c7673 F ext/session/test_session.c 23eddaf713708ae063d278ec6297652e3672dc38 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x @@ -721,7 +721,7 @@ F test/pagesize.test 1dd51367e752e742f58e861e65ed7390603827a0 F test/pcache.test 065aa286e722ab24f2e51792c1f093bf60656b16 F test/pcache2.test a83efe2dec0d392f814bfc998def1d1833942025 F test/percentile.test 4614301e38398df7fdd5f28f4ed8f272b328251b -F test/permutations.test 17f03ab6fc174c910c6eb86761d5ba60b93ad3b5 +F test/permutations.test 742b8005bb3c782797a20beccdbe213ef52531fb F test/pragma.test 5e7de6c32a5d764f09437d2025f07e4917b9e178 F test/pragma2.test 3a55f82b954242c642f8342b17dffc8b47472947 F test/printf.test ec9870c4dce8686a37818e0bf1aba6e6a1863552 @@ -773,7 +773,7 @@ F test/selectC.test 871fb55d884d3de5943c4057ebd22c2459e71977 F test/selectD.test b0f02a04ef7737decb24e08be2c39b9664b43394 F test/selectE.test fc02a1eb04c8eb537091482644b7d778ae8759b7 F test/server1.test 46803bd3fe8b99b30dbc5ff38ffc756f5c13a118 -F test/session.test c1a17c11ef7d01c24fe2b9f7871190d949a8e718 +F test/session.test 082dea459efc76e2a527b8ee9ff74d76e63ea7b6 F test/shared.test 1da9dbad400cee0d93f252ccf76e1ae007a63746 F test/shared2.test 03eb4a8d372e290107d34b6ce1809919a698e879 F test/shared3.test ebf77f023f4bdaa8f74f65822b559e86ce5c6257 @@ -1110,7 +1110,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P fc88f7311ba888015634b89b5909890208f543f5 bd4267f17bbf5d01fb3f12a5a06e94fcbcbd785c -R fbcf046d813fd5b4194215d3a88e6121 -U drh -Z 65f93ab590b102a4bb6eff5ef529fe8b +P 086a127236ee99d67513490fb7b5549e8b752c44 +R 2763382f3d6cfe76b83308c186ebd5fb +U dan +Z 3d139fb0da074f52216dcf16de48044b diff --git a/manifest.uuid b/manifest.uuid index bb570b6c5d..728ff221c4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -086a127236ee99d67513490fb7b5549e8b752c44 \ No newline at end of file +c2972b6aed23f6c76a289534de9ea4732a48f40e \ No newline at end of file diff --git a/test/permutations.test b/test/permutations.test index bb72596af4..cd55406fa7 100644 --- a/test/permutations.test +++ b/test/permutations.test @@ -878,6 +878,14 @@ test_suite "session" -description { All session module related tests. } -files [glob -nocomplain $::testdir/../ext/session/*.test] +test_suite "session_eec" -description { + All session module related tests with sqlite3_extended_result_codes() set. +} -files [ + glob -nocomplain $::testdir/../ext/session/*.test +] -dbconfig { + sqlite3_extended_result_codes $::dbhandle 1 +} + test_suite "no_optimization" -description { Run test scripts with optimizations disabled using the sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS) interface. diff --git a/test/session.test b/test/session.test index bf159c3b22..85ac056cdd 100644 --- a/test/session.test +++ b/test/session.test @@ -12,6 +12,9 @@ set testdir [file dirname $argv0] source $testdir/permutations.test ifcapable session { + # First run tests with sqlite3_extended_error_codes() set, then + # again with it clear. + run_test_suite session_eec run_test_suite session } From cb3e4b797ed2144ec3af50113833f597006b1ed8 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 3 Jul 2013 19:53:05 +0000 Subject: [PATCH 0078/1484] Experimental change to the handling of foreign key constraint violations when applying a changeset: all foreign keys, immediate and deferred, are deferred until the end of the transaction (or sub-transaction) opened by the sqlite3changeset_apply(). A single call to the conflict-handler (if any) is made if any FK constraint violations are still present in the database at this point. The conflict-handler may choose to rollback the changeset, or to apply it, constraint violations and all. FossilOrigin-Name: 1d44e5d3c2b1dc958442f9114a960b256e002ed3 --- ext/session/session1.test | 4 +- ext/session/session9.test | 134 ++++++++++++++++++++++ ext/session/sqlite3session.c | 41 ++++++- ext/session/sqlite3session.h | 42 ++++++- ext/session/test_session.c | 212 ++++++++++++++++++----------------- manifest | 37 +++--- manifest.uuid | 2 +- src/fkey.c | 6 +- src/main.c | 2 + src/pragma.c | 15 +++ src/sqlite.h.in | 2 + src/sqliteInt.h | 3 + src/vdbe.c | 13 ++- src/vdbeInt.h | 1 + src/vdbeapi.c | 6 +- src/vdbeaux.c | 7 +- 16 files changed, 391 insertions(+), 136 deletions(-) create mode 100644 ext/session/session9.test diff --git a/ext/session/session1.test b/ext/session/session1.test index 7ef33e7fce..e47fb3e845 100644 --- a/ext/session/session1.test +++ b/ext/session/session1.test @@ -264,12 +264,12 @@ do_conflict_test 3.2.3 -tables t2 -sql { DELETE FROM t2 WHERE a = 3; DELETE FROM t2 WHERE a = 4; } -conflicts { - {DELETE t2 CONSTRAINT {i 1 t one}} {DELETE t2 NOTFOUND {i 3 t three}} {DELETE t2 DATA {i 4 t four} {i 4 t five}} + {FOREIGN_KEY 1} } do_execsql_test 3.2.4 "SELECT * FROM t2" {} -do_db2_test 3.2.5 "SELECT * FROM t2" {1 one 4 five} +do_db2_test 3.2.5 "SELECT * FROM t2" {4 five} # Test UPDATE changesets. # diff --git a/ext/session/session9.test b/ext/session/session9.test new file mode 100644 index 0000000000..35d8e876c9 --- /dev/null +++ b/ext/session/session9.test @@ -0,0 +1,134 @@ +# 2013 July 04 +# +# 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 tests that the sessions module handles foreign key constraint +# violations when applying changesets as required. +# + +if {![info exists testdir]} { + set testdir [file join [file dirname [info script]] .. .. test] +} +source [file join [file dirname [info script]] session_common.tcl] +source $testdir/tester.tcl +ifcapable !session {finish_test; return} +set testprefix session9 + + +#-------------------------------------------------------------------- +# + +proc populate_db {} { + drop_all_tables + execsql { + PRAGMA foreign_keys = 1; + CREATE TABLE p1(a PRIMARY KEY, b); + CREATE TABLE c1(a PRIMARY KEY, b REFERENCES p1); + CREATE TABLE c2(a PRIMARY KEY, + b REFERENCES p1 DEFERRABLE INITIALLY DEFERRED + ); + + INSERT INTO p1 VALUES(1, 'one'); + INSERT INTO p1 VALUES(2, 'two'); + INSERT INTO p1 VALUES(3, 'three'); + INSERT INTO p1 VALUES(4, 'four'); + } +} + +proc capture_changeset {sql} { + sqlite3session S db main + + foreach t [db eval {SELECT name FROM sqlite_master WHERE type='table'}] { + S attach $t + } + execsql $sql + set ret [S changeset] + S delete + + return $ret +} + +do_test 1.1 { + populate_db + set cc [capture_changeset { + INSERT INTO c1 VALUES('ii', 2); + INSERT INTO c2 VALUES('iii', 3); + }] + set {} {} +} {} + +proc xConflict {args} { + lappend ::xConflict {*}$args + return $::conflictret +} + +foreach {tn delrow trans conflictargs conflictret} { + 1 2 0 {FOREIGN_KEY 1} OMIT + 2 3 0 {FOREIGN_KEY 1} OMIT + 3 2 1 {FOREIGN_KEY 1} OMIT + 4 3 1 {FOREIGN_KEY 1} OMIT + 5 2 0 {FOREIGN_KEY 1} ABORT + 6 3 0 {FOREIGN_KEY 1} ABORT + 7 2 1 {FOREIGN_KEY 1} ABORT + 8 3 1 {FOREIGN_KEY 1} ABORT +} { + + set A(OMIT) {0 {}} + set A(ABORT) {1 SQLITE_CONSTRAINT} + do_test 1.2.$tn.1 { + populate_db + execsql { DELETE FROM p1 WHERE a=($delrow+0) } + if {$trans} { execsql BEGIN } + + set ::xConflict [list] + list [catch {sqlite3changeset_apply db $::cc xConflict} msg] $msg + } $A($conflictret) + + do_test 1.2.$tn.2 { set ::xConflict } $conflictargs + + set A(OMIT) {1 1} + set A(ABORT) {0 0} + do_test 1.2.$tn.3 { + execsql { SELECT count(*) FROM c1 UNION ALL SELECT count(*) FROM c2 } + } $A($conflictret) + + do_test 1.2.$tn.4 { expr ![sqlite3_get_autocommit db] } $trans + do_test 1.2.$tn.5 { + if { $trans } { execsql COMMIT } + } {} +} + +#-------------------------------------------------------------------- +# Test that closing a transaction clears the defer_foreign_keys flag. +# +foreach {tn open noclose close} { + 1 BEGIN {} COMMIT + 2 BEGIN {} ROLLBACK + + 3 {SAVEPOINT one} {} {RELEASE one} + 4 {SAVEPOINT one} {ROLLBACK TO one} {RELEASE one} +} { + execsql $open + do_execsql_test 2.$tn.1 { PRAGMA defer_foreign_keys } {0} + + do_execsql_test 2.$tn.2 { + PRAGMA defer_foreign_keys = 1; + PRAGMA defer_foreign_keys; + } {1} + + execsql $noclose + do_execsql_test 2.$tn.3 { PRAGMA defer_foreign_keys } {1} + + execsql $close + do_execsql_test 2.$tn.4 { PRAGMA defer_foreign_keys } {0} +} + +finish_test + diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index aa0c4b59db..31e0300eb2 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -1,6 +1,5 @@ #if defined(SQLITE_ENABLE_SESSION) && defined(SQLITE_ENABLE_PREUPDATE_HOOK) - #include "sqlite3session.h" #include #include @@ -2110,6 +2109,26 @@ int sqlite3changeset_conflict( return SQLITE_OK; } +/* +** This function may only be called with an iterator passed to an +** SQLITE_CHANGESET_FOREIGN_KEY conflict handler callback. In this case +** it sets the output variable to the total number of known foreign key +** violations in the destination database and returns SQLITE_OK. +** +** In all other cases this function returns SQLITE_MISUSE. +*/ +int sqlite3changeset_fk_conflicts( + sqlite3_changeset_iter *pIter, /* Changeset iterator */ + int *pnOut /* OUT: Number of FK violations */ +){ + if( pIter->pConflict || pIter->apValue ){ + return SQLITE_MISUSE; + } + *pnOut = pIter->nCol; + return SQLITE_OK; +} + + /* ** Finalize an iterator allocated with sqlite3changeset_start(). ** @@ -2845,6 +2864,9 @@ int sqlite3changeset_apply( sqlite3_mutex_enter(sqlite3_db_mutex(db)); rc = sqlite3_exec(db, "SAVEPOINT changeset_apply", 0, 0, 0); + if( rc==SQLITE_OK ){ + rc = sqlite3_exec(db, "PRAGMA defer_foreign_keys = 1", 0, 0, 0); + } while( rc==SQLITE_OK && SQLITE_ROW==sqlite3changeset_next(pIter) ){ int nCol; int op; @@ -2948,6 +2970,23 @@ int sqlite3changeset_apply( sqlite3changeset_finalize(pIter); } + if( rc==SQLITE_OK ){ + int nFk = sqlite3_foreign_key_check(db); + if( nFk>0 ){ + int res = SQLITE_CHANGESET_ABORT; + if( xConflict ){ + sqlite3_changeset_iter sIter; + memset(&sIter, 0, sizeof(sIter)); + sIter.nCol = nFk; + res = xConflict(pCtx, SQLITE_CHANGESET_FOREIGN_KEY, &sIter); + } + if( res!=SQLITE_CHANGESET_OMIT ){ + rc = SQLITE_CONSTRAINT; + } + } + } + sqlite3_exec(db, "PRAGMA defer_foreign_keys = 0", 0, 0, 0); + if( rc==SQLITE_OK ){ rc = sqlite3_exec(db, "RELEASE changeset_apply", 0, 0, 0); }else{ diff --git a/ext/session/sqlite3session.h b/ext/session/sqlite3session.h index a1ab1e9645..f1a7052bcd 100644 --- a/ext/session/sqlite3session.h +++ b/ext/session/sqlite3session.h @@ -489,6 +489,21 @@ int sqlite3changeset_conflict( sqlite3_value **ppValue /* OUT: Value from conflicting row */ ); +/* +** CAPI3REF: Determine The Number Of Foreign Key Constraint Violations +** +** This function may only be called with an iterator passed to an +** SQLITE_CHANGESET_FOREIGN_KEY conflict handler callback. In this case +** it sets the output variable to the total number of known foreign key +** violations in the destination database and returns SQLITE_OK. +** +** In all other cases this function returns SQLITE_MISUSE. +*/ +int sqlite3changeset_fk_conflicts( + sqlite3_changeset_iter *pIter, /* Changeset iterator */ + int *pnOut /* OUT: Number of FK violations */ +); + /* ** CAPI3REF: Finalize A Changeset Iterator @@ -809,20 +824,35 @@ int sqlite3changeset_apply( ** ** The conflicting row in this case is the database row with the matching ** primary key. +** +**
SQLITE_CHANGESET_FOREIGN_KEY
+** If foreign key handling is enabled, and applying a changeset leaves the +** database in a state containing foreign key violations, the conflict +** handler is invoked with CHANGESET_FOREIGN_KEY as the second argument +** exactly once before the changeset is committed. If the conflict handler +** returns CHANGESET_OMIT, the changes, including those that caused the +** foreign key constraint violation, are committed. Or, if it returns +** CHANGESET_ABORT, the changeset is rolled back. +** +** No current or conflicting row information is provided. The only function +** it is possible to call on the supplied sqlite3_changeset_iter handle +** is sqlite3changeset_fk_conflicts(). ** **
SQLITE_CHANGESET_CONSTRAINT
** If any other constraint violation occurs while applying a change (i.e. -** a FOREIGN KEY, UNIQUE, CHECK or NOT NULL constraint), the conflict -** handler is invoked with CHANGESET_CONSTRAINT as the second argument. +** a UNIQUE, CHECK or NOT NULL constraint), the conflict handler is +** invoked with CHANGESET_CONSTRAINT as the second argument. ** ** There is no conflicting row in this case. The results of invoking the ** sqlite3changeset_conflict() API are undefined. +** **
*/ -#define SQLITE_CHANGESET_DATA 1 -#define SQLITE_CHANGESET_NOTFOUND 2 -#define SQLITE_CHANGESET_CONFLICT 3 -#define SQLITE_CHANGESET_CONSTRAINT 4 +#define SQLITE_CHANGESET_DATA 1 +#define SQLITE_CHANGESET_NOTFOUND 2 +#define SQLITE_CHANGESET_CONFLICT 3 +#define SQLITE_CHANGESET_CONSTRAINT 4 +#define SQLITE_CHANGESET_FOREIGN_KEY 5 /* ** CAPI3REF: Constants Returned By The Conflict Handler diff --git a/ext/session/test_session.c b/ext/session/test_session.c index 82e2c64ba5..49e45c5fb3 100644 --- a/ext/session/test_session.c +++ b/ext/session/test_session.c @@ -250,109 +250,119 @@ static int test_conflict_handler( sqlite3changeset_op(pIter, &zTab, &nCol, &op, 0); - /* Append the operation type. */ - Tcl_ListObjAppendElement(0, pEval, Tcl_NewStringObj( - op==SQLITE_INSERT ? "INSERT" : - op==SQLITE_UPDATE ? "UPDATE" : - "DELETE", -1 - )); - - /* Append the table name. */ - Tcl_ListObjAppendElement(0, pEval, Tcl_NewStringObj(zTab, -1)); - - /* Append the conflict type. */ - switch( eConf ){ - case SQLITE_CHANGESET_DATA: - Tcl_ListObjAppendElement(interp, pEval,Tcl_NewStringObj("DATA",-1)); - break; - case SQLITE_CHANGESET_NOTFOUND: - Tcl_ListObjAppendElement(interp, pEval,Tcl_NewStringObj("NOTFOUND",-1)); - break; - case SQLITE_CHANGESET_CONFLICT: - Tcl_ListObjAppendElement(interp, pEval,Tcl_NewStringObj("CONFLICT",-1)); - break; - case SQLITE_CHANGESET_CONSTRAINT: - Tcl_ListObjAppendElement(interp, pEval,Tcl_NewStringObj("CONSTRAINT",-1)); - break; - } - - /* If this is not an INSERT, append the old row */ - if( op!=SQLITE_INSERT ){ - int i; - Tcl_Obj *pOld = Tcl_NewObj(); - for(i=0; iisDeferred && !pParse->pToplevel && !pParse->isMultiWrite ){ + if( !pFKey->isDeferred + && !pParse->pToplevel + && !pParse->isMultiWrite + && !(pParse->db->flags & SQLITE_DeferForeignKeys) + ){ /* Special case: If this is an INSERT statement that will insert exactly ** one row into the table, raise a constraint immediately instead of ** incrementing a counter. This is necessary as the VM code is being diff --git a/src/main.c b/src/main.c index 6d3798dcbf..df158b9186 100644 --- a/src/main.c +++ b/src/main.c @@ -1037,6 +1037,8 @@ void sqlite3RollbackAll(sqlite3 *db, int tripCode){ /* Any deferred constraint violations have now been resolved. */ db->nDeferredCons = 0; + db->nDeferredImmCons = 0; + db->flags &= ~SQLITE_DeferForeignKeys; /* If one has been configured, invoke the rollback-hook callback */ if( db->xRollbackCallback && (inTrans || !db->autoCommit) ){ diff --git a/src/pragma.c b/src/pragma.c index 5803f6c4a5..9a288b977c 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -1169,6 +1169,21 @@ void sqlite3Pragma( } } }else + + if( sqlite3StrICmp(zLeft, "defer_foreign_keys")==0 ){ + if( zRight ){ + if( sqlite3GetBoolean(zRight, 0) ){ + db->flags |= SQLITE_DeferForeignKeys; + }else{ + db->flags &= ~SQLITE_DeferForeignKeys; + db->nDeferredImmCons = 0; + } + sqlite3VdbeAddOp2(v, OP_Expire, 0, 0); + }else{ + int bVal = !!(db->flags & SQLITE_DeferForeignKeys); + returnSingleInt(pParse, "defer_foreign_keys", bVal); + } + } #endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */ #ifndef SQLITE_OMIT_FOREIGN_KEY diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 3894e56abb..f02e568f38 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -7280,6 +7280,8 @@ SQLITE_EXPERIMENTAL int sqlite3_preupdate_count(sqlite3 *); SQLITE_EXPERIMENTAL int sqlite3_preupdate_depth(sqlite3 *); SQLITE_EXPERIMENTAL int sqlite3_preupdate_new(sqlite3 *, int, sqlite3_value **); +int sqlite3_foreign_key_check(sqlite3 *db); + /* ** Undo the hack that converts floating point types to integer for ** builds on processors without floating point support. diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 8ee07a13ff..dd65c51d90 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -961,6 +961,7 @@ struct sqlite3 { int nSavepoint; /* Number of non-transaction savepoints */ int nStatement; /* Number of nested statement-transactions */ i64 nDeferredCons; /* Net deferred constraints this transaction. */ + i64 nDeferredImmCons; /* Net deferred immediate constraints */ int *pnBytesFreed; /* If not NULL, increment this in DbFree() */ #ifdef SQLITE_ENABLE_UNLOCK_NOTIFY @@ -1016,6 +1017,7 @@ struct sqlite3 { #define SQLITE_PreferBuiltin 0x00100000 /* Preference to built-in funcs */ #define SQLITE_LoadExtension 0x00200000 /* Enable load_extension */ #define SQLITE_EnableTrigger 0x00400000 /* True to enable triggers */ +#define SQLITE_DeferForeignKeys 0x00800000 /* ** Bits of the sqlite3.dbOptFlags field that are used by the @@ -1161,6 +1163,7 @@ struct FuncDestructor { struct Savepoint { char *zName; /* Savepoint name (nul-terminated) */ i64 nDeferredCons; /* Number of deferred fk violations */ + i64 nDeferredImmCons; /* Number of deferred imm fk. */ Savepoint *pNext; /* Parent savepoint (if any) */ }; diff --git a/src/vdbe.c b/src/vdbe.c index c5e6cfcc3e..5330c48b5f 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -878,7 +878,7 @@ case OP_Halt: { p->rc = rc = SQLITE_BUSY; }else{ assert( rc==SQLITE_OK || (p->rc&0xff)==SQLITE_CONSTRAINT ); - assert( rc==SQLITE_OK || db->nDeferredCons>0 ); + assert( rc==SQLITE_OK || db->nDeferredCons>0 || db->nDeferredImmCons>0 ); rc = p->rc ? SQLITE_ERROR : SQLITE_DONE; } goto vdbe_return; @@ -2737,6 +2737,7 @@ case OP_Savepoint: { pNew->pNext = db->pSavepoint; db->pSavepoint = pNew; pNew->nDeferredCons = db->nDeferredCons; + pNew->nDeferredImmCons = db->nDeferredImmCons; } } }else{ @@ -2824,6 +2825,7 @@ case OP_Savepoint: { } }else{ db->nDeferredCons = pSavepoint->nDeferredCons; + db->nDeferredImmCons = pSavepoint->nDeferredImmCons; } if( !isTransaction ){ @@ -2978,6 +2980,7 @@ case OP_Transaction: { ** counter. If the statement transaction needs to be rolled back, ** the value of this counter needs to be restored too. */ p->nStmtDefCons = db->nDeferredCons; + p->nStmtDefImmCons = db->nDeferredImmCons; } } break; @@ -5319,7 +5322,9 @@ case OP_Param: { /* out2-prerelease */ ** statement counter is incremented (immediate foreign key constraints). */ case OP_FkCounter: { - if( pOp->p1 ){ + if( db->flags & SQLITE_DeferForeignKeys ){ + db->nDeferredImmCons += pOp->p2; + }else if( pOp->p1 ){ db->nDeferredCons += pOp->p2; }else{ p->nFkConstraint += pOp->p2; @@ -5340,9 +5345,9 @@ case OP_FkCounter: { */ case OP_FkIfZero: { /* jump */ if( pOp->p1 ){ - if( db->nDeferredCons==0 ) pc = pOp->p2-1; + if( db->nDeferredCons==0 && db->nDeferredImmCons==0 ) pc = pOp->p2-1; }else{ - if( p->nFkConstraint==0 ) pc = pOp->p2-1; + if( p->nFkConstraint==0 && db->nDeferredImmCons==0 ) pc = pOp->p2-1; } break; } diff --git a/src/vdbeInt.h b/src/vdbeInt.h index 1f9358a232..aec4b422b6 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -350,6 +350,7 @@ struct Vdbe { #endif i64 nFkConstraint; /* Number of imm. FK constraints this VM */ i64 nStmtDefCons; /* Number of def. constraints when stmt started */ + i64 nStmtDefImmCons; /* Number of def. imm constraints when stmt started */ char *zSql; /* Text of the SQL statement that generated this */ void *pFree; /* Free this when deleting the vdbe */ #ifdef SQLITE_DEBUG diff --git a/src/vdbeapi.c b/src/vdbeapi.c index 8be71383ba..6fb45edb84 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -386,7 +386,9 @@ static int sqlite3Step(Vdbe *p){ db->u1.isInterrupted = 0; } - assert( db->writeVdbeCnt>0 || db->autoCommit==0 || db->nDeferredCons==0 ); + assert( db->writeVdbeCnt>0 || db->autoCommit==0 + || (db->nDeferredCons==0 && db->nDeferredImmCons==0) + ); #ifndef SQLITE_OMIT_TRACE if( db->xProfile && !db->init.busy ){ @@ -1496,3 +1498,5 @@ int sqlite3_preupdate_new(sqlite3 *db, int iIdx, sqlite3_value **ppValue){ return sqlite3ApiExit(db, rc); } #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ + +int sqlite3_foreign_key_check(sqlite3 *db){ return db->nDeferredImmCons; } diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 7897116fb8..88561ecb06 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -2051,6 +2051,7 @@ int sqlite3VdbeCloseStatement(Vdbe *p, int eOp){ ** the statement transaction was opened. */ if( eOp==SAVEPOINT_ROLLBACK ){ db->nDeferredCons = p->nStmtDefCons; + db->nDeferredImmCons = p->nStmtDefImmCons; } } return rc; @@ -2069,7 +2070,9 @@ int sqlite3VdbeCloseStatement(Vdbe *p, int eOp){ #ifndef SQLITE_OMIT_FOREIGN_KEY int sqlite3VdbeCheckFk(Vdbe *p, int deferred){ sqlite3 *db = p->db; - if( (deferred && db->nDeferredCons>0) || (!deferred && p->nFkConstraint>0) ){ + if( (deferred && (db->nDeferredCons+db->nDeferredImmCons)>0) + || (!deferred && p->nFkConstraint>0) + ){ p->rc = SQLITE_CONSTRAINT_FOREIGNKEY; p->errorAction = OE_Abort; sqlite3SetString(&p->zErrMsg, db, "foreign key constraint failed"); @@ -2201,6 +2204,8 @@ int sqlite3VdbeHalt(Vdbe *p){ sqlite3RollbackAll(db, SQLITE_OK); }else{ db->nDeferredCons = 0; + db->nDeferredImmCons = 0; + db->flags &= ~SQLITE_DeferForeignKeys; sqlite3CommitInternalChanges(db); } }else{ From bded90b4873a5e4e6d513f36dd0edc181004dfaa Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 4 Jul 2013 15:22:53 +0000 Subject: [PATCH 0079/1484] Fix a bug preventing some FK constraint checking from being deferred until the end of changeset application. FossilOrigin-Name: 1452defb8cfcc489230314dd1e0425feba46c49d --- ext/session/session9.test | 124 +++++++++++++++++++++++++++++++++++++- manifest | 14 ++--- manifest.uuid | 2 +- src/fkey.c | 7 ++- 4 files changed, 135 insertions(+), 12 deletions(-) diff --git a/ext/session/session9.test b/ext/session/session9.test index 35d8e876c9..b6ead68991 100644 --- a/ext/session/session9.test +++ b/ext/session/session9.test @@ -23,8 +23,8 @@ set testprefix session9 #-------------------------------------------------------------------- +# Basic tests. # - proc populate_db {} { drop_all_tables execsql { @@ -130,5 +130,127 @@ foreach {tn open noclose close} { do_execsql_test 2.$tn.4 { PRAGMA defer_foreign_keys } {0} } +#-------------------------------------------------------------------- +# Test that a cyclic relationship can be inserted and deleted. +# +# This situation does not come up in practice, but testing it serves to +# show that it does not matter which order parent and child keys +# are processed in internally when applying a changeset. +# +drop_all_tables + +do_execsql_test 3.1 { + CREATE TABLE t1(a PRIMARY KEY, b); + CREATE TABLE t2(x PRIMARY KEY, y); +} + +# Create changesets as follows: +# +# $cc1 - Insert a row into t1. +# $cc2 - Insert a row into t2. +# $cc - Combination of $cc1 and $cc2. +# +# $ccdel1 - Delete the row from t1. +# $ccdel2 - Delete the row from t2. +# $ccdel - Combination of $cc1 and $cc2. +# +do_test 3.2 { + set cc1 [capture_changeset { + INSERT INTO t1 VALUES('one', 'value one'); + }] + set ccdel1 [capture_changeset { DELETE FROM t1; }] + set cc2 [capture_changeset { + INSERT INTO t2 VALUES('value one', 'one'); + }] + set ccdel2 [capture_changeset { DELETE FROM t2; }] + set cc [capture_changeset { + INSERT INTO t1 VALUES('one', 'value one'); + INSERT INTO t2 VALUES('value one', 'one'); + }] + set ccdel [capture_changeset { + DELETE FROM t1; + DELETE FROM t2; + }] + set {} {} +} {} + +# Now modify the database schema to create a cyclic foreign key dependency +# between tables t1 and t2. This means that although changesets $cc and +# $ccdel can be applied, none of the others may without violating the +# foreign key constraints. +# +do_test 3.3 { + + drop_all_tables + execsql { + CREATE TABLE t1(a PRIMARY KEY, b REFERENCES t2); + CREATE TABLE t2(x PRIMARY KEY, y REFERENCES t1); + } + + + proc conflict_handler {args} { return "ABORT" } + sqlite3changeset_apply db $cc conflict_handler + + execsql { + SELECT * FROM t1; + SELECT * FROM t2; + } +} {one {value one} {value one} one} + +do_test 3.3.1 { + list [catch {sqlite3changeset_apply db $::ccdel1 conflict_handler} msg] $msg +} {1 SQLITE_CONSTRAINT} +do_test 3.3.2 { + list [catch {sqlite3changeset_apply db $::ccdel2 conflict_handler} msg] $msg +} {1 SQLITE_CONSTRAINT} + +do_test 3.3.4.1 { + list [catch {sqlite3changeset_apply db $::ccdel conflict_handler} msg] $msg +} {0 {}} +do_execsql_test 3.3.4.2 { + SELECT * FROM t1; + SELECT * FROM t2; +} {} + +do_test 3.5.1 { + list [catch {sqlite3changeset_apply db $::cc1 conflict_handler} msg] $msg +} {1 SQLITE_CONSTRAINT} +do_test 3.5.2 { + list [catch {sqlite3changeset_apply db $::cc2 conflict_handler} msg] $msg +} {1 SQLITE_CONSTRAINT} + +#-------------------------------------------------------------------- +# Test that if a change that affects FK processing is not applied +# due to a separate constraint, SQLite does not get confused and +# increment FK counters anyway. +# +drop_all_tables +do_execsql_test 4.1 { + CREATE TABLE p1(x PRIMARY KEY, y); + CREATE TABLE c1(a PRIMARY KEY, b REFERENCES p1); + INSERT INTO p1 VALUES(1,1); +} + +do_execsql_test 4.2.1 { + BEGIN; + PRAGMA defer_foreign_keys = 1; + INSERT INTO c1 VALUES('x', 'x'); +} +do_catchsql_test 4.2.2 { COMMIT } {1 {foreign key constraint failed}} +do_catchsql_test 4.2.3 { ROLLBACK } {0 {}} + +do_execsql_test 4.3.1 { + BEGIN; + PRAGMA defer_foreign_keys = 1; + INSERT INTO c1 VALUES(1, 1); +} +do_catchsql_test 4.3.2 { + INSERT INTO c1 VALUES(1, 'x') +} {1 {column a is not unique}} + +do_catchsql_test 4.3.3 { COMMIT } {0 {}} +do_catchsql_test 4.3.4 { BEGIN ; COMMIT } {0 {}} + finish_test + diff --git a/manifest b/manifest index cbf96b3093..05a751b481 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Experimental\schange\sto\sthe\shandling\sof\sforeign\skey\sconstraint\sviolations\swhen\sapplying\sa\schangeset:\sall\sforeign\skeys,\simmediate\sand\sdeferred,\sare\sdeferred\suntil\sthe\send\sof\sthe\stransaction\s(or\ssub-transaction)\sopened\sby\sthe\ssqlite3changeset_apply().\sA\ssingle\scall\sto\sthe\sconflict-handler\s(if\sany)\sis\smade\sif\sany\sFK\sconstraint\sviolations\sare\sstill\spresent\sin\sthe\sdatabase\sat\sthis\spoint.\sThe\sconflict-handler\smay\schoose\sto\srollback\sthe\schangeset,\sor\sto\sapply\sit,\sconstraint\sviolations\sand\sall. -D 2013-07-03T19:53:05.693 +C Fix\sa\sbug\spreventing\ssome\sFK\sconstraint\schecking\sfrom\sbeing\sdeferred\suntil\sthe\send\sof\schangeset\sapplication. +D 2013-07-04T15:22:53.953 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in aff38bc64c582dd147f18739532198372587b0f0 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -142,7 +142,7 @@ F ext/session/session4.test a6ed685da7a5293c5d6f99855bcf41dbc352ca84 F ext/session/session5.test 8fdfaf9dba28a2f1c6b89b06168bdab1fef2d478 F ext/session/session6.test 443789bc2fca12e4f7075cf692c60b8a2bea1a26 F ext/session/session8.test 7d35947ad329b8966f095d34f9617a9eff52dc65 -F ext/session/session9.test 3378ceace4e291dda8512b83d256be51aac5344e +F ext/session/session9.test 43acfdc57647c2ce4b36dbd0769112520ea6af14 F ext/session/session_common.tcl 1539d8973b2aea0025c133eb0cc4c89fcef541a5 F ext/session/sessionfault.test 496291b287ba3c0b14ca2e074425e29cc92a64a6 F ext/session/sqlite3session.c 80903fe2c24c8a9e7ccacebca1855a31ebebbbc3 @@ -186,7 +186,7 @@ F src/date.c 067a81c9942c497aafd2c260e13add8a7d0c7dd4 F src/delete.c 39a770e9729b1acd2de347f8f614584841d0083e F src/expr.c 2b47ae9da6c9f34eff6736962ea2e102c6c4a755 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb -F src/fkey.c ddd160ce0b81f092165f72d84c356d49c903a3ad +F src/fkey.c 87619fc3a9b6ab6877388bbcc05cdb136503786e F src/func.c 5c50c1ea31fd864b0fe921fe1a8d4c55acd609ef F src/global.c 5caf4deab621abb45b4c607aad1bd21c20aac759 F src/hash.c ac3470bbf1ca4ae4e306a8ecb0fdf1731810ffe4 @@ -1111,7 +1111,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P c2972b6aed23f6c76a289534de9ea4732a48f40e -R 1e1bb18e922bc4e9bb6b2e837b9cd1c8 +P 1d44e5d3c2b1dc958442f9114a960b256e002ed3 +R 28f75ac347bd281672cb0a8d27d3f6b3 U dan -Z 8c44f70721e5b391cc002040c9d1eb51 +Z 01296a7a6fdc241a613ea24758428ad2 diff --git a/manifest.uuid b/manifest.uuid index f8240dd8be..44d88b34c0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1d44e5d3c2b1dc958442f9114a960b256e002ed3 \ No newline at end of file +1452defb8cfcc489230314dd1e0425feba46c49d \ No newline at end of file diff --git a/src/fkey.c b/src/fkey.c index 0369bbc6f0..3f3c5d8ad6 100644 --- a/src/fkey.c +++ b/src/fkey.c @@ -422,10 +422,9 @@ static void fkLookupParent( } } - if( !pFKey->isDeferred + if( !pFKey->isDeferred && !(pParse->db->flags & SQLITE_DeferForeignKeys) && !pParse->pToplevel && !pParse->isMultiWrite - && !(pParse->db->flags & SQLITE_DeferForeignKeys) ){ /* Special case: If this is an INSERT statement that will insert exactly ** one row into the table, raise a constraint immediately instead of @@ -817,7 +816,9 @@ void sqlite3FkCheck( SrcList *pSrc; int *aiCol = 0; - if( !pFKey->isDeferred && !pParse->pToplevel && !pParse->isMultiWrite ){ + if( !pFKey->isDeferred && !(db->flags & SQLITE_DeferForeignKeys) + && !pParse->pToplevel && !pParse->isMultiWrite + ){ assert( regOld==0 && regNew!=0 ); /* Inserting a single row into a parent table cannot cause an immediate ** foreign key violation. So do nothing in this case. */ From 963c74df5988fa4bf5dd6dda9fb15a9b09a0d6a4 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 11 Jul 2013 12:19:12 +0000 Subject: [PATCH 0080/1484] Rename the SQLITE_DeferForeignKeys macro to shorter SQLITE_DeferFKs. Move the "defer_foreign_keys" pragma into the flagPragma() routine. FossilOrigin-Name: 3a2ab74c85a40e0e7ef2d6aef6ec23837cb788e6 --- manifest | 22 +++++++++++----------- manifest.uuid | 2 +- src/fkey.c | 4 ++-- src/main.c | 2 +- src/pragma.c | 21 ++++----------------- src/sqliteInt.h | 2 +- src/vdbe.c | 2 +- src/vdbeaux.c | 2 +- 8 files changed, 22 insertions(+), 35 deletions(-) diff --git a/manifest b/manifest index 66bca82b2d..8d6c35f1b7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Pull\sin\sall\sthe\slatest\schanges\sfrom\strunk. -D 2013-07-09T13:05:49.248 +C Rename\sthe\sSQLITE_DeferForeignKeys\smacro\sto\sshorter\sSQLITE_DeferFKs.\s\sMove\nthe\s"defer_foreign_keys"\spragma\sinto\sthe\sflagPragma()\sroutine. +D 2013-07-11T12:19:12.495 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in aff38bc64c582dd147f18739532198372587b0f0 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -187,7 +187,7 @@ F src/date.c 067a81c9942c497aafd2c260e13add8a7d0c7dd4 F src/delete.c 39a770e9729b1acd2de347f8f614584841d0083e F src/expr.c 2b47ae9da6c9f34eff6736962ea2e102c6c4a755 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb -F src/fkey.c 87619fc3a9b6ab6877388bbcc05cdb136503786e +F src/fkey.c 914a6bbd987d857c41ac9d244efa6641f36faadb F src/func.c 5c50c1ea31fd864b0fe921fe1a8d4c55acd609ef F src/global.c 5caf4deab621abb45b4c607aad1bd21c20aac759 F src/hash.c ac3470bbf1ca4ae4e306a8ecb0fdf1731810ffe4 @@ -198,7 +198,7 @@ F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12 F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b F src/loadext.c c48f7f3f170e502fe0cc20748e03c6e0b5a016c2 -F src/main.c a27560235a8e0e3f1a94aaca30189431bf61e776 +F src/main.c 93407bb51024f962ed9cf1c3e525e63484ebbdb9 F src/malloc.c fe085aa851b666b7c375c1ff957643dc20a04bf6 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 437c7c4af964895d4650f29881df63535caaa1fa @@ -223,7 +223,7 @@ F src/parse.y 9acfcc83ddbf0cf82f0ed9582ccf0ad6c366ff37 F src/pcache.c f8043b433a57aba85384a531e3937a804432a346 F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222 F src/pcache1.c d23d07716de96c7c0c2503ec5051a4384c3fb938 -F src/pragma.c 057f5b1343c9a79e3e6c0c542a3a08b85849ee61 +F src/pragma.c c87581d93a7518cba656b7919e32ded5d331b76a F src/prepare.c 2306be166bbeddf454e18bf8b21dba8388d05328 F src/printf.c 41c49dac366a3a411190001a8ab495fa8887974e F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 @@ -234,7 +234,7 @@ F src/shell.c c8cd06e6b66250a3ea0149c4edec30de14f57b6f F src/sqlite.h.in fb8adf7852fb92e410de422b5569923327bf8a2c F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0 F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc -F src/sqliteInt.h a83b0cef30022c46a19e6ace1f668b7833935eed +F src/sqliteInt.h 62b11aa829ab51446a52dfea93f14b8e1e5d5862 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c bedc37ec1a6bb9399944024d63f4c769971955a9 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -290,11 +290,11 @@ F src/update.c 19daebf6a0a67af5524913e93498d08388792128 F src/utf.c 8d819e2e5104a430fc2005f018db14347c95a38f F src/util.c f566b5138099a2df8533b190d0dcc74b7dfbe0c9 F src/vacuum.c d9c5759f4c5a438bb43c2086f72c5d2edabc36c8 -F src/vdbe.c 7e1654d4ac01f017aad8088a1225e514b2aef5cf +F src/vdbe.c 26f19a439806efdd9fb93b1874a4a7029a885142 F src/vdbe.h 1223e2548e0970cf96f573ff6b99f804a36ad683 F src/vdbeInt.h 11feb11eb49d8b312741011d30d91c9c50b59de0 F src/vdbeapi.c bb28ee14bae43579b33d88e0d916a1657255a866 -F src/vdbeaux.c 84f5fb7cb2f62fd8b8a37b96ac929221cc77d317 +F src/vdbeaux.c 35846cedd64e90b83f498786775c69c2c6b6c8b1 F src/vdbeblob.c 1268e0bcb8e21fa32520b0fc376e1bcdfaa0c642 F src/vdbemem.c 833005f1cbbf447289f1973dba2a0c2228c7b8ab F src/vdbesort.c 3937e06b2a0e354500e17dc206ef4c35770a5017 @@ -1115,7 +1115,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P 1452defb8cfcc489230314dd1e0425feba46c49d 1e39f85077f1f2b96c3a656c5b6334bafb005908 -R 996effd12b4e262519df6f6e538dae74 +P af3ca4c6e557e6bc92584586b5a97d9be41b0b82 +R 5801e485f633968bff3b48e71da6671c U drh -Z 08707dac307041af534ddfd35863fca1 +Z 2dfee648a27ba78793a28310983bc733 diff --git a/manifest.uuid b/manifest.uuid index d864f435a3..ae79df7faa 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -af3ca4c6e557e6bc92584586b5a97d9be41b0b82 \ No newline at end of file +3a2ab74c85a40e0e7ef2d6aef6ec23837cb788e6 \ No newline at end of file diff --git a/src/fkey.c b/src/fkey.c index 3f3c5d8ad6..bb59c656f6 100644 --- a/src/fkey.c +++ b/src/fkey.c @@ -422,7 +422,7 @@ static void fkLookupParent( } } - if( !pFKey->isDeferred && !(pParse->db->flags & SQLITE_DeferForeignKeys) + if( !pFKey->isDeferred && !(pParse->db->flags & SQLITE_DeferFKs) && !pParse->pToplevel && !pParse->isMultiWrite ){ @@ -816,7 +816,7 @@ void sqlite3FkCheck( SrcList *pSrc; int *aiCol = 0; - if( !pFKey->isDeferred && !(db->flags & SQLITE_DeferForeignKeys) + if( !pFKey->isDeferred && !(db->flags & SQLITE_DeferFKs) && !pParse->pToplevel && !pParse->isMultiWrite ){ assert( regOld==0 && regNew!=0 ); diff --git a/src/main.c b/src/main.c index ad9422b486..b25c43be3d 100644 --- a/src/main.c +++ b/src/main.c @@ -1038,7 +1038,7 @@ void sqlite3RollbackAll(sqlite3 *db, int tripCode){ /* Any deferred constraint violations have now been resolved. */ db->nDeferredCons = 0; db->nDeferredImmCons = 0; - db->flags &= ~SQLITE_DeferForeignKeys; + db->flags &= ~SQLITE_DeferFKs; /* If one has been configured, invoke the rollback-hook callback */ if( db->xRollbackCallback && (inTrans || !db->autoCommit) ){ diff --git a/src/pragma.c b/src/pragma.c index 9a288b977c..fd0ebc727c 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -197,12 +197,13 @@ static int flagPragma(Parse *pParse, const char *zLeft, const char *zRight){ /* TODO: Maybe it shouldn't be possible to change the ReadUncommitted ** flag if there are any active statements. */ { "read_uncommitted", SQLITE_ReadUncommitted }, - { "recursive_triggers", SQLITE_RecTriggers }, + { "recursive_triggers", SQLITE_RecTriggers }, /* This flag may only be set if both foreign-key and trigger support ** are present in the build. */ #if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) - { "foreign_keys", SQLITE_ForeignKeys }, + { "foreign_keys", SQLITE_ForeignKeys }, + { "defer_foreign_keys", SQLITE_DeferFKs }, #endif }; int i; @@ -228,6 +229,7 @@ static int flagPragma(Parse *pParse, const char *zLeft, const char *zRight){ db->flags |= mask; }else{ db->flags &= ~mask; + if( mask==SQLITE_DeferFKs ) db->nDeferredImmCons = 0; } /* Many of the flag-pragmas modify the code generated by the SQL @@ -1169,21 +1171,6 @@ void sqlite3Pragma( } } }else - - if( sqlite3StrICmp(zLeft, "defer_foreign_keys")==0 ){ - if( zRight ){ - if( sqlite3GetBoolean(zRight, 0) ){ - db->flags |= SQLITE_DeferForeignKeys; - }else{ - db->flags &= ~SQLITE_DeferForeignKeys; - db->nDeferredImmCons = 0; - } - sqlite3VdbeAddOp2(v, OP_Expire, 0, 0); - }else{ - int bVal = !!(db->flags & SQLITE_DeferForeignKeys); - returnSingleInt(pParse, "defer_foreign_keys", bVal); - } - } #endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */ #ifndef SQLITE_OMIT_FOREIGN_KEY diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 228d34fc59..f989c3a30b 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1018,7 +1018,7 @@ struct sqlite3 { #define SQLITE_PreferBuiltin 0x00100000 /* Preference to built-in funcs */ #define SQLITE_LoadExtension 0x00200000 /* Enable load_extension */ #define SQLITE_EnableTrigger 0x00400000 /* True to enable triggers */ -#define SQLITE_DeferForeignKeys 0x00800000 +#define SQLITE_DeferFKs 0x00800000 /* Defer all FK constraints */ /* ** Bits of the sqlite3.dbOptFlags field that are used by the diff --git a/src/vdbe.c b/src/vdbe.c index e5a40b7993..b957212e34 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -5338,7 +5338,7 @@ case OP_Param: { /* out2-prerelease */ ** statement counter is incremented (immediate foreign key constraints). */ case OP_FkCounter: { - if( db->flags & SQLITE_DeferForeignKeys ){ + if( db->flags & SQLITE_DeferFKs ){ db->nDeferredImmCons += pOp->p2; }else if( pOp->p1 ){ db->nDeferredCons += pOp->p2; diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 5ba51dce60..654230dfa9 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -2221,7 +2221,7 @@ int sqlite3VdbeHalt(Vdbe *p){ }else{ db->nDeferredCons = 0; db->nDeferredImmCons = 0; - db->flags &= ~SQLITE_DeferForeignKeys; + db->flags &= ~SQLITE_DeferFKs; sqlite3CommitInternalChanges(db); } }else{ From 07001c45a1cfe57cab888ddee16288d23f5fd344 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 11 Jul 2013 13:49:59 +0000 Subject: [PATCH 0081/1484] Remove the undocumented sqlite3_foreign_key_check() API and replace it with sqlite3_db_status(db, SQLITE_DBSTATUS_DEFERRED_FKS, ...). Add test cases for the new functionality. FossilOrigin-Name: d39e65fe702a2e11477f2d996f77404f45763368 --- ext/session/sqlite3session.c | 5 +- manifest | 23 ++++---- manifest.uuid | 2 +- src/sqlite.h.in | 11 +++- src/status.c | 10 ++++ src/test_malloc.c | 3 +- src/vdbeapi.c | 2 - test/fkey1.test | 3 + test/fkey6.test | 103 +++++++++++++++++++++++++++++++++++ 9 files changed, 142 insertions(+), 20 deletions(-) create mode 100644 test/fkey6.test diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index 31e0300eb2..6fa8107408 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -2971,8 +2971,9 @@ int sqlite3changeset_apply( } if( rc==SQLITE_OK ){ - int nFk = sqlite3_foreign_key_check(db); - if( nFk>0 ){ + int nFk, notUsed; + sqlite3_db_status(db, SQLITE_DBSTATUS_DEFERRED_FKS, &nFk, ¬Used, 0); + if( nFk!=0 ){ int res = SQLITE_CHANGESET_ABORT; if( xConflict ){ sqlite3_changeset_iter sIter; diff --git a/manifest b/manifest index 8d6c35f1b7..d549fe0174 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Rename\sthe\sSQLITE_DeferForeignKeys\smacro\sto\sshorter\sSQLITE_DeferFKs.\s\sMove\nthe\s"defer_foreign_keys"\spragma\sinto\sthe\sflagPragma()\sroutine. -D 2013-07-11T12:19:12.495 +C Remove\sthe\sundocumented\ssqlite3_foreign_key_check()\sAPI\sand\sreplace\sit\swith\nsqlite3_db_status(db,\sSQLITE_DBSTATUS_DEFERRED_FKS,\s...).\s\sAdd\stest\scases\nfor\sthe\snew\sfunctionality. +D 2013-07-11T13:49:59.348 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in aff38bc64c582dd147f18739532198372587b0f0 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -146,7 +146,7 @@ F ext/session/session8.test 7d35947ad329b8966f095d34f9617a9eff52dc65 F ext/session/session9.test 43acfdc57647c2ce4b36dbd0769112520ea6af14 F ext/session/session_common.tcl 1539d8973b2aea0025c133eb0cc4c89fcef541a5 F ext/session/sessionfault.test 496291b287ba3c0b14ca2e074425e29cc92a64a6 -F ext/session/sqlite3session.c 80903fe2c24c8a9e7ccacebca1855a31ebebbbc3 +F ext/session/sqlite3session.c e0345e8425a36fb8ac107175ebae46b4af8873e4 F ext/session/sqlite3session.h c7db3d8515eba7f41eeb8698a25e58d24cd384bf F ext/session/test_session.c 12053e9190653164fa624427cf90d1f46ca7f179 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x @@ -231,12 +231,12 @@ F src/resolve.c 89f9003e8316ee3a172795459efc2a0274e1d5a8 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 F src/select.c 91b62654caf8dfe292fb8882715e575d34ad3874 F src/shell.c c8cd06e6b66250a3ea0149c4edec30de14f57b6f -F src/sqlite.h.in fb8adf7852fb92e410de422b5569923327bf8a2c +F src/sqlite.h.in 17c84f6a2296a33a16141f4cff4b176278f3d1cc F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0 F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc F src/sqliteInt.h 62b11aa829ab51446a52dfea93f14b8e1e5d5862 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d -F src/status.c bedc37ec1a6bb9399944024d63f4c769971955a9 +F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e F src/tclsqlite.c e0eaf3a78eca2ef650abb67b6571cc86abcb5f87 F src/test1.c 870fc648a48cb6d6808393174f7ebe82b8c840fa @@ -263,7 +263,7 @@ F src/test_intarray.c 87847c71c3c36889c0bcc9c4baf9d31881665d61 F src/test_intarray.h b999bb18d090b8d9d9c49d36ec37ef8f341fe169 F src/test_journal.c f5c0a05b7b3d5930db769b5ee6c3766dc2221a64 F src/test_loadext.c df586c27176e3c2cb2e099c78da67bf14379a56e -F src/test_malloc.c 2855429b8232107b3296409be2a8eb68345290c2 +F src/test_malloc.c a105801222c0514f8befa2a1712a95505cce099a F src/test_multiplex.c 5d691eeb6cb6aa7888da28eba5e62a9a857d3c0f F src/test_multiplex.h 9b63b95f07acedee425fdfe49a47197c9bf5f9d8 F src/test_mutex.c 293042d623ebba969160f471a82aa1551626454f @@ -293,7 +293,7 @@ F src/vacuum.c d9c5759f4c5a438bb43c2086f72c5d2edabc36c8 F src/vdbe.c 26f19a439806efdd9fb93b1874a4a7029a885142 F src/vdbe.h 1223e2548e0970cf96f573ff6b99f804a36ad683 F src/vdbeInt.h 11feb11eb49d8b312741011d30d91c9c50b59de0 -F src/vdbeapi.c bb28ee14bae43579b33d88e0d916a1657255a866 +F src/vdbeapi.c bca51b6ea254af3a1bbfd2a58522f6d6db214334 F src/vdbeaux.c 35846cedd64e90b83f498786775c69c2c6b6c8b1 F src/vdbeblob.c 1268e0bcb8e21fa32520b0fc376e1bcdfaa0c642 F src/vdbemem.c 833005f1cbbf447289f1973dba2a0c2228c7b8ab @@ -465,11 +465,12 @@ F test/expr.test 67c9fd6f8f829e239dc8b0f4a08a73c08b09196d F test/fallocate.test 3e979af17dfa7e5e9dda5eba1a696c04fa9d47f7 F test/filectrl.test 14fa712e42c4cb791e09dfd58a6a03efb47ef13a F test/filefmt.test cb34663f126cbc2d358af552dcaf5c72769b0146 -F test/fkey1.test 01c7de578e11747e720c2d9aeef27f239853c4da +F test/fkey1.test e1d1fa84cde579185ea01358436839703e415a5b F test/fkey2.test 06e0b4cc9e1b3271ae2ae6feeb19755468432111 F test/fkey3.test 5ec899d12b13bcf1e9ef40eff7fb692fdb91392e F test/fkey4.test 86446017011273aad8f9a99c1a65019e7bd9ca9d F test/fkey5.test 0bf64f2d19ad80433ca0b24edbf604a18b353d5f +F test/fkey6.test 2d76497c54db0e5bfbecee0acf00bb8a706b37db F test/fkey_malloc.test bb74c9cb8f8fceed03b58f8a7ef2df98520bbd51 F test/format4.test 1f0cac8ff3895e9359ed87e41aaabee982a812eb F test/fts-9fd058691.test 78b887e30ae6816df0e1fed6259de4b5a64ad33c @@ -1115,7 +1116,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P af3ca4c6e557e6bc92584586b5a97d9be41b0b82 -R 5801e485f633968bff3b48e71da6671c +P 3a2ab74c85a40e0e7ef2d6aef6ec23837cb788e6 +R 4b05e08ec28ee8fbe45f517a6910194e U drh -Z 2dfee648a27ba78793a28310983bc733 +Z 8f1a9fcd771ae153ffef09cc214c7392 diff --git a/manifest.uuid b/manifest.uuid index ae79df7faa..89b033640c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3a2ab74c85a40e0e7ef2d6aef6ec23837cb788e6 \ No newline at end of file +d39e65fe702a2e11477f2d996f77404f45763368 \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 24ccb8d39d..6e51fadc70 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -6239,6 +6239,12 @@ int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg); ** on subsequent SQLITE_DBSTATUS_CACHE_WRITE requests is undefined). ^The ** highwater mark associated with SQLITE_DBSTATUS_CACHE_WRITE is always 0. **
+** +** [[SQLITE_DBSTATUS_DEFERRED_FKS]] ^(
SQLITE_DBSTATUS_DEFERRED_FKS
+**
This parameter returns the zero for the current value if and only if +** there all foreign key constraints (deferred or immediate) have been +** resolved. The highwater mark is always 0. +**
** */ #define SQLITE_DBSTATUS_LOOKASIDE_USED 0 @@ -6251,7 +6257,8 @@ int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg); #define SQLITE_DBSTATUS_CACHE_HIT 7 #define SQLITE_DBSTATUS_CACHE_MISS 8 #define SQLITE_DBSTATUS_CACHE_WRITE 9 -#define SQLITE_DBSTATUS_MAX 9 /* Largest defined DBSTATUS */ +#define SQLITE_DBSTATUS_DEFERRED_FKS 10 +#define SQLITE_DBSTATUS_MAX 10 /* Largest defined DBSTATUS */ /* @@ -7282,8 +7289,6 @@ SQLITE_EXPERIMENTAL int sqlite3_preupdate_count(sqlite3 *); SQLITE_EXPERIMENTAL int sqlite3_preupdate_depth(sqlite3 *); SQLITE_EXPERIMENTAL int sqlite3_preupdate_new(sqlite3 *, int, sqlite3_value **); -int sqlite3_foreign_key_check(sqlite3 *db); - /* ** Undo the hack that converts floating point types to integer for ** builds on processors without floating point support. diff --git a/src/status.c b/src/status.c index 28349e6d3d..5fcb68ddc3 100644 --- a/src/status.c +++ b/src/status.c @@ -243,6 +243,16 @@ int sqlite3_db_status( break; } + /* Set *pCurrent to non-zero if there are unresolved deferred foreign + ** key constraints. Set *pCurrent to zero if all foreign key constraints + ** have been satisfied. The *pHighwater is always set to zero. + */ + case SQLITE_DBSTATUS_DEFERRED_FKS: { + *pHighwater = 0; + *pCurrent = db->nDeferredImmCons>0 || db->nDeferredCons>0; + break; + } + default: { rc = SQLITE_ERROR; } diff --git a/src/test_malloc.c b/src/test_malloc.c index cf98a8fb21..2e31f0833d 100644 --- a/src/test_malloc.c +++ b/src/test_malloc.c @@ -1349,7 +1349,8 @@ static int test_db_status( { "LOOKASIDE_MISS_FULL", SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL }, { "CACHE_HIT", SQLITE_DBSTATUS_CACHE_HIT }, { "CACHE_MISS", SQLITE_DBSTATUS_CACHE_MISS }, - { "CACHE_WRITE", SQLITE_DBSTATUS_CACHE_WRITE } + { "CACHE_WRITE", SQLITE_DBSTATUS_CACHE_WRITE }, + { "DEFERRED_FKS", SQLITE_DBSTATUS_DEFERRED_FKS } }; Tcl_Obj *pResult; if( objc!=4 ){ diff --git a/src/vdbeapi.c b/src/vdbeapi.c index b97faaf404..854396a379 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -1499,5 +1499,3 @@ int sqlite3_preupdate_new(sqlite3 *db, int iIdx, sqlite3_value **ppValue){ return sqlite3ApiExit(db, rc); } #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ - -int sqlite3_foreign_key_check(sqlite3 *db){ return db->nDeferredImmCons; } diff --git a/test/fkey1.test b/test/fkey1.test index e7c00d16d4..90a4c44409 100644 --- a/test/fkey1.test +++ b/test/fkey1.test @@ -117,5 +117,8 @@ do_test fkey1-3.4 { {0 0 t5 d {} {SET DEFAULT} CASCADE NONE} \ {0 1 t5 e {} {SET DEFAULT} CASCADE NONE} \ ] +do_test fkey1-3.5 { + sqlite3_db_status db DBSTATUS_DEFERRED_FKS 0 +} {0 0 0} finish_test diff --git a/test/fkey6.test b/test/fkey6.test new file mode 100644 index 0000000000..66286b43ec --- /dev/null +++ b/test/fkey6.test @@ -0,0 +1,103 @@ +# 2012 December 17 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements regression tests for SQLite library. +# +# This file tests the PRAGMA defer_foreign_keys and +# SQLITE_DBSTATUS_DEFERRED_FKS +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +ifcapable {!foreignkey} { + finish_test + return +} + +do_execsql_test fkey6-1.1 { + PRAGMA foreign_keys=ON; + CREATE TABLE t1(x INTEGER PRIMARY KEY); + CREATE TABLE t2(y INTEGER PRIMARY KEY, + z INTEGER REFERENCES t1(x) DEFERRABLE INITIALLY DEFERRED); + CREATE INDEX t2z ON t2(z); + CREATE TABLE t3(u INTEGER PRIMARY KEY, v INTEGER REFERENCES t1(x)); + CREATE INDEX t3v ON t3(v); + INSERT INTO t1 VALUES(1),(2),(3),(4),(5); + INSERT INTO t2 VALUES(1,1),(2,2); + INSERT INTO t3 VALUES(3,3),(4,4); +} {} +do_test fkey6-1.2 { + catchsql {DELETE FROM t1 WHERE x=2;} +} {1 {foreign key constraint failed}} +do_test fkey6-1.3 { + sqlite3_db_status db DBSTATUS_DEFERRED_FKS 0 +} {0 0 0} +do_test fkey6-1.4 { + execsql { + BEGIN; + DELETE FROM t1 WHERE x=1; + } +} {} +do_test fkey6-1.5.1 { + sqlite3_db_status db DBSTATUS_DEFERRED_FKS 1 +} {0 1 0} +do_test fkey6-1.5.2 { + sqlite3_db_status db DBSTATUS_DEFERRED_FKS 0 +} {0 1 0} +do_test fkey6-1.6 { + execsql { + ROLLBACK; + } +} {} +do_test fkey6-1.7 { + sqlite3_db_status db DBSTATUS_DEFERRED_FKS 0 +} {0 0 0} +do_test fkey6-1.8 { + execsql { + PRAGMA defer_foreign_keys=ON; + BEGIN; + DELETE FROM t1 WHERE x=3; + } +} {} +do_test fkey6-1.9 { + sqlite3_db_status db DBSTATUS_DEFERRED_FKS 0 +} {0 1 0} +do_test fkey6-1.10 { + execsql { + ROLLBACK; + PRAGMA defer_foreign_keys=OFF; + BEGIN; + } + catchsql {DELETE FROM t1 WHERE x=3} +} {1 {foreign key constraint failed}} +db eval {ROLLBACK} + +do_test fkey6-1.20 { + execsql { + BEGIN; + DELETE FROM t1 WHERE x=1; + } + sqlite3_db_status db DBSTATUS_DEFERRED_FKS 0 +} {0 1 0} +do_test fkey6-1.21 { + execsql { + DELETE FROM t2 WHERE y=1; + } + sqlite3_db_status db DBSTATUS_DEFERRED_FKS 0 +} {0 0 0} +do_test fkey6-1.22 { + execsql { + COMMIT; + } +} {} + + +finish_test From 7531a5a37840f18cdb39407c69bd200e0b349569 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 23 Aug 2013 17:43:32 +0000 Subject: [PATCH 0082/1484] Add the sqlite3session_table_filter API to the sessions extension. FossilOrigin-Name: b7e4dd889d37c8f57c2d3c7900e802f644aac3ea --- ext/session/sessionA.test | 69 +++++++++++++++++++++++++++++++++ ext/session/sqlite3session.c | 25 ++++++++++++ ext/session/sqlite3session.h | 19 +++++++++ ext/session/test_session.c | 74 +++++++++++++++++++++++++++++------- manifest | 19 ++++----- manifest.uuid | 2 +- 6 files changed, 185 insertions(+), 23 deletions(-) create mode 100644 ext/session/sessionA.test diff --git a/ext/session/sessionA.test b/ext/session/sessionA.test new file mode 100644 index 0000000000..1ca0f13709 --- /dev/null +++ b/ext/session/sessionA.test @@ -0,0 +1,69 @@ +# 2013 July 04 +# +# 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 tests that the sessions module handles foreign key constraint +# violations when applying changesets as required. +# + +if {![info exists testdir]} { + set testdir [file join [file dirname [info script]] .. .. test] +} +source [file join [file dirname [info script]] session_common.tcl] +source $testdir/tester.tcl +ifcapable !session {finish_test; return} +set testprefix sessionA + + +forcedelete test.db2 +sqlite3 db2 test.db2 +foreach {tn db} {1 db 2 db2} { + do_test 1.$tn.1 { + execsql { + CREATE TABLE t1(a PRIMARY KEY, b); + CREATE TABLE t2(a PRIMARY KEY, b); + CREATE TABLE t3(a PRIMARY KEY, b); + } $db + } {} +} + +proc tbl_filter {zTbl} { + return $::table_filter($zTbl) +} + +do_test 2.1 { + set ::table_filter(t1) 1 + set ::table_filter(t2) 0 + set ::table_filter(t3) 1 + + sqlite3session S db main + S table_filter tbl_filter + + execsql { + INSERT INTO t1 VALUES('a', 'b'); + INSERT INTO t2 VALUES('c', 'd'); + INSERT INTO t3 VALUES('e', 'f'); + } + + set changeset [S changeset] + S delete + sqlite3changeset_apply db2 $changeset xConflict + + execsql { + SELECT * FROM t1; + SELECT * FROM t2; + SELECT * FROM t3; + } db2 +} {a b e f} + + +finish_test + + diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index 6fa8107408..801ea60717 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -23,6 +23,8 @@ struct sqlite3_session { int bIndirect; /* True if all changes are indirect */ int bAutoAttach; /* True to auto-attach tables */ int rc; /* Non-zero if an error has occurred */ + void *pFilterCtx; /* First argument to pass to xTableFilter */ + int (*xTableFilter)(void *pCtx, const char *zTab); sqlite3_session *pNext; /* Next session object on same db. */ SessionTable *pTable; /* List of attached tables */ }; @@ -1066,6 +1068,16 @@ static void xPreUpdate( if( !pTab ){ /* This branch is taken if table zName has not yet been attached to ** this session and the auto-attach flag is set. */ + + /* If there is a table-filter configured, invoke it. If it returns 0, + ** this change will not be recorded. Break out of the loop early in + ** this case. */ + if( pSession->xTableFilter + && pSession->xTableFilter(pSession->pFilterCtx, zName)==0 + ){ + break; + } + pSession->rc = sqlite3session_attach(pSession,zName); if( pSession->rc ) break; pTab = pSession->pTable; @@ -1170,6 +1182,19 @@ void sqlite3session_delete(sqlite3_session *pSession){ sqlite3_free(pSession); } +/* +** Set a table filter on a Session Object. +*/ +void sqlite3session_table_filter( + sqlite3_session *pSession, + int(*xFilter)(void*, const char*), + void *pCtx /* First argument passed to xFilter */ +){ + pSession->bAutoAttach = 1; + pSession->pFilterCtx = pCtx; + pSession->xTableFilter = xFilter; +} + /* ** Attach a table to a session. All subsequent changes made to the table ** while the session object is enabled will be recorded. diff --git a/ext/session/sqlite3session.h b/ext/session/sqlite3session.h index f1a7052bcd..974a770c7b 100644 --- a/ext/session/sqlite3session.h +++ b/ext/session/sqlite3session.h @@ -71,6 +71,7 @@ int sqlite3session_create( */ void sqlite3session_delete(sqlite3_session *pSession); + /* ** CAPI3REF: Enable Or Disable A Session Object ** @@ -152,6 +153,24 @@ int sqlite3session_attach( const char *zTab /* Table name */ ); +/* +** CAPI3REF: Set a table filter on a Session Object. +** +** The second argument (xFilter) is the "filter callback". For changes to rows +** in tables that are not attached to the Session oject, the filter is called +** to determine whether changes to the table's rows should be tracked or not. +** If xFilter returns 0, changes is not tracked. Note that once a table is +** attached, xFilter will not be called again. +*/ +void sqlite3session_table_filter( + sqlite3_session *pSession, /* Session object */ + int(*xFilter)( + void *pCtx, /* Copy of third arg to _filter_table() */ + const char *zTab /* Table name */ + ), + void *pCtx /* First argument passed to xFilter */ +); + /* ** CAPI3REF: Generate A Changeset From A Session Object ** diff --git a/ext/session/test_session.c b/ext/session/test_session.c index 49e45c5fb3..4340921a67 100644 --- a/ext/session/test_session.c +++ b/ext/session/test_session.c @@ -7,18 +7,50 @@ #include #include +typedef struct TestSession TestSession; +struct TestSession { + sqlite3_session *pSession; + Tcl_Interp *interp; + Tcl_Obj *pFilterScript; +}; + static int test_session_error(Tcl_Interp *interp, int rc){ extern const char *sqlite3ErrName(int); Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1)); return TCL_ERROR; } +static int test_table_filter(void *pCtx, const char *zTbl){ + TestSession *p = (TestSession*)pCtx; + Tcl_Obj *pEval; + int rc; + int bRes = 0; + + pEval = Tcl_DuplicateObj(p->pFilterScript); + Tcl_IncrRefCount(pEval); + rc = Tcl_ListObjAppendElement(p->interp, pEval, Tcl_NewStringObj(zTbl, -1)); + if( rc==TCL_OK ){ + rc = Tcl_EvalObjEx(p->interp, pEval, TCL_EVAL_GLOBAL); + } + if( rc==TCL_OK ){ + rc = Tcl_GetBooleanFromObj(p->interp, Tcl_GetObjResult(p->interp), &bRes); + } + if( rc!=TCL_OK ){ + /* printf("error: %s\n", Tcl_GetStringResult(p->interp)); */ + Tcl_BackgroundError(p->interp); + } + Tcl_DecrRefCount(pEval); + + return bRes; +} + /* ** Tclcmd: $session attach TABLE ** $session changeset ** $session delete ** $session enable BOOL ** $session indirect INTEGER +** $session table_filter SCRIPT */ static int test_session_cmd( void *clientData, @@ -26,19 +58,21 @@ static int test_session_cmd( int objc, Tcl_Obj *CONST objv[] ){ - sqlite3_session *pSession = (sqlite3_session *)clientData; + TestSession *p = (TestSession*)clientData; + sqlite3_session *pSession = p->pSession; struct SessionSubcmd { const char *zSub; int nArg; const char *zMsg; int iSub; } aSub[] = { - { "attach", 1, "TABLE", }, /* 0 */ - { "changeset", 0, "", }, /* 1 */ - { "delete", 0, "", }, /* 2 */ - { "enable", 1, "BOOL", }, /* 3 */ - { "indirect", 1, "BOOL", }, /* 4 */ - { "isempty", 0, "", }, /* 5 */ + { "attach", 1, "TABLE", }, /* 0 */ + { "changeset", 0, "", }, /* 1 */ + { "delete", 0, "", }, /* 2 */ + { "enable", 1, "BOOL", }, /* 3 */ + { "indirect", 1, "BOOL", }, /* 4 */ + { "isempty", 0, "", }, /* 5 */ + { "table_filter", 1, "SCRIPT", }, /* 6 */ { 0 } }; int iSub; @@ -65,8 +99,8 @@ static int test_session_cmd( if( rc!=SQLITE_OK ){ return test_session_error(interp, rc); } - } break; + } case 1: { /* changeset */ int nChange; @@ -107,14 +141,25 @@ static int test_session_cmd( Tcl_SetObjResult(interp, Tcl_NewBooleanObj(val)); break; } + + case 6: { /* table_filter */ + if( p->pFilterScript ) Tcl_DecrRefCount(p->pFilterScript); + p->interp = interp; + p->pFilterScript = Tcl_DuplicateObj(objv[2]); + Tcl_IncrRefCount(p->pFilterScript); + sqlite3session_table_filter(pSession, test_table_filter, clientData); + break; + } } return TCL_OK; } static void test_session_del(void *clientData){ - sqlite3_session *pSession = (sqlite3_session *)clientData; - sqlite3session_delete(pSession); + TestSession *p = (TestSession*)clientData; + if( p->pFilterScript ) Tcl_DecrRefCount(p->pFilterScript); + sqlite3session_delete(p->pSession); + ckfree(p); } /* @@ -129,7 +174,7 @@ static int test_sqlite3session( sqlite3 *db; Tcl_CmdInfo info; int rc; /* sqlite3session_create() return code */ - sqlite3_session *pSession; /* New session object */ + TestSession *p; /* New wrapper object */ if( objc!=4 ){ Tcl_WrongNumArgs(interp, 1, objv, "CMD DB-HANDLE DB-NAME"); @@ -142,13 +187,16 @@ static int test_sqlite3session( } db = *(sqlite3 **)info.objClientData; - rc = sqlite3session_create(db, Tcl_GetString(objv[3]), &pSession); + p = (TestSession*)ckalloc(sizeof(TestSession)); + memset(p, 0, sizeof(TestSession)); + rc = sqlite3session_create(db, Tcl_GetString(objv[3]), &p->pSession); if( rc!=SQLITE_OK ){ + ckfree(p); return test_session_error(interp, rc); } Tcl_CreateObjCommand( - interp, Tcl_GetString(objv[1]), test_session_cmd, (ClientData)pSession, + interp, Tcl_GetString(objv[1]), test_session_cmd, (ClientData)p, test_session_del ); Tcl_SetObjResult(interp, objv[1]); diff --git a/manifest b/manifest index eeb634ab67..11155359af 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sin\sminor\sbug\sfixes\sand\sperformance\stweaks\sfrom\strunk\sleading\sup\sto\nthe\sversion\s3.8.0\srelease. -D 2013-08-22T15:07:08.266 +C Add\sthe\ssqlite3session_table_filter\sAPI\sto\sthe\ssessions\sextension. +D 2013-08-23T17:43:32.715 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in aff38bc64c582dd147f18739532198372587b0f0 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -144,11 +144,12 @@ F ext/session/session5.test 8fdfaf9dba28a2f1c6b89b06168bdab1fef2d478 F ext/session/session6.test 443789bc2fca12e4f7075cf692c60b8a2bea1a26 F ext/session/session8.test 7d35947ad329b8966f095d34f9617a9eff52dc65 F ext/session/session9.test 43acfdc57647c2ce4b36dbd0769112520ea6af14 +F ext/session/sessionA.test eb05c13e4ef1ca8046a3a6dbf2d5f6f5b04a11d4 F ext/session/session_common.tcl 1539d8973b2aea0025c133eb0cc4c89fcef541a5 F ext/session/sessionfault.test 496291b287ba3c0b14ca2e074425e29cc92a64a6 -F ext/session/sqlite3session.c e0345e8425a36fb8ac107175ebae46b4af8873e4 -F ext/session/sqlite3session.h c7db3d8515eba7f41eeb8698a25e58d24cd384bf -F ext/session/test_session.c 12053e9190653164fa624427cf90d1f46ca7f179 +F ext/session/sqlite3session.c 63eea3741e8ac1574d4c183fd92a6a50b1415357 +F ext/session/sqlite3session.h 6c35057241567ed6319f750ee504a81c459225e1 +F ext/session/test_session.c d38968307c05229cc8cd603722cf305d6f768832 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt f2b23a6bde8f1c6e86b957e4d94eab0add520b0d @@ -1119,7 +1120,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P 3e4033285deb417bd72c008917729dbf3bf4e90d 0775501acf152dcbf4dd039f4511f3d8c4330d85 -R f6e422c39c44105817eb40d9d54618de -U drh -Z f9597afebde4efa08f5ab31e24bede7f +P 831492dca8bcfb1a1f83a8bb15de9cc94f29f07e +R cbce615b433685cc6c1cb9210155f0f8 +U dan +Z 2d1cb3afe326cb66267c2981ea353dde diff --git a/manifest.uuid b/manifest.uuid index 8fadc4e3f6..023cc42f5d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -831492dca8bcfb1a1f83a8bb15de9cc94f29f07e \ No newline at end of file +b7e4dd889d37c8f57c2d3c7900e802f644aac3ea \ No newline at end of file From fba5765b578cb65c52440af2079b951139fbfe55 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 11 Nov 2013 23:02:10 +0000 Subject: [PATCH 0083/1484] Fix two test cases (due to changes in the formatting of constraint errors) so that all tests now pass. FossilOrigin-Name: 129e2b69178147d04ee27fce66c17b39f8654da3 --- ext/session/session9.test | 6 ++---- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/ext/session/session9.test b/ext/session/session9.test index b6ead68991..3b42c31061 100644 --- a/ext/session/session9.test +++ b/ext/session/session9.test @@ -236,7 +236,7 @@ do_execsql_test 4.2.1 { PRAGMA defer_foreign_keys = 1; INSERT INTO c1 VALUES('x', 'x'); } -do_catchsql_test 4.2.2 { COMMIT } {1 {foreign key constraint failed}} +do_catchsql_test 4.2.2 { COMMIT } {1 {FOREIGN KEY constraint failed}} do_catchsql_test 4.2.3 { ROLLBACK } {0 {}} do_execsql_test 4.3.1 { @@ -246,11 +246,9 @@ do_execsql_test 4.3.1 { } do_catchsql_test 4.3.2 { INSERT INTO c1 VALUES(1, 'x') -} {1 {column a is not unique}} +} {1 {UNIQUE constraint failed: c1.a}} do_catchsql_test 4.3.3 { COMMIT } {0 {}} do_catchsql_test 4.3.4 { BEGIN ; COMMIT } {0 {}} finish_test - - diff --git a/manifest b/manifest index fcac3f7230..d26953124e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sin\sthe\sWITHOUT\sROWID\schanges.\s\sA\sfew\stests\sare\sfailing\snow.\s\sThey\swill\nbe\sfixed\sin\sa\sfollow-on\scheck-in. -D 2013-11-11T22:55:26.153 +C Fix\stwo\stest\scases\s(due\sto\schanges\sin\sthe\sformatting\sof\sconstraint\serrors)\nso\sthat\sall\stests\snow\spass. +D 2013-11-11T23:02:10.499 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in bb787d5227c6aa95915ff04e9634a0a469297ea4 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -146,7 +146,7 @@ F ext/session/session4.test a6ed685da7a5293c5d6f99855bcf41dbc352ca84 F ext/session/session5.test 8fdfaf9dba28a2f1c6b89b06168bdab1fef2d478 F ext/session/session6.test 443789bc2fca12e4f7075cf692c60b8a2bea1a26 F ext/session/session8.test 7d35947ad329b8966f095d34f9617a9eff52dc65 -F ext/session/session9.test 43acfdc57647c2ce4b36dbd0769112520ea6af14 +F ext/session/session9.test 776e46785c29c11cda01f5205d0f1e8f8f9a46bf F ext/session/sessionA.test eb05c13e4ef1ca8046a3a6dbf2d5f6f5b04a11d4 F ext/session/session_common.tcl 1539d8973b2aea0025c133eb0cc4c89fcef541a5 F ext/session/sessionfault.test 496291b287ba3c0b14ca2e074425e29cc92a64a6 @@ -1151,7 +1151,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P aa72ea8a004de7fe744fc13baef19d05aea607d5 f58d57017199421167dae8ebc67db2f19be45082 -R 3b17341d4c625bc46e3586e654b8390b +P 5addd1234ded59ce60fb633b76ac87d483377edd +R 7497a574757ea7847d650e9a557949cb U drh -Z 1cdf9fac9d6e4efb5a645c5741312eca +Z 55c6c2c9062609ee78397175c9785a12 diff --git a/manifest.uuid b/manifest.uuid index e437b594ea..767d2dcc1b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5addd1234ded59ce60fb633b76ac87d483377edd \ No newline at end of file +129e2b69178147d04ee27fce66c17b39f8654da3 \ No newline at end of file From b7bc8c984917c7ef714d4f1bfbea2916a35f1e3f Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 6 Mar 2014 14:53:25 +0000 Subject: [PATCH 0084/1484] Enhance the test harness for the sessions interface so that it does not use SQLite operations that can encounter an OOM error in places where it is unable to report an OOM error back up to the test script. FossilOrigin-Name: bc0e661033b78f27866932244e6204985ae39000 --- ext/session/test_session.c | 11 +++++++---- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/ext/session/test_session.c b/ext/session/test_session.c index 4340921a67..022cbc6679 100644 --- a/ext/session/test_session.c +++ b/ext/session/test_session.c @@ -159,7 +159,7 @@ static void test_session_del(void *clientData){ TestSession *p = (TestSession*)clientData; if( p->pFilterScript ) Tcl_DecrRefCount(p->pFilterScript); sqlite3session_delete(p->pSession); - ckfree(p); + ckfree((char*)p); } /* @@ -191,7 +191,7 @@ static int test_sqlite3session( memset(p, 0, sizeof(TestSession)); rc = sqlite3session_create(db, Tcl_GetString(objv[3]), &p->pSession); if( rc!=SQLITE_OK ){ - ckfree(p); + ckfree((char*)p); return test_session_error(interp, rc); } @@ -222,10 +222,13 @@ static void test_append_value(Tcl_Obj *pList, sqlite3_value *pVal){ Tcl_ListObjAppendElement(0, pList, Tcl_NewStringObj("f", 1)); pObj = Tcl_NewDoubleObj(sqlite3_value_double(pVal)); break; - case SQLITE_TEXT: + case SQLITE_TEXT: { + const char *z = (char*)sqlite3_value_blob(pVal); + int n = sqlite3_value_bytes(pVal); Tcl_ListObjAppendElement(0, pList, Tcl_NewStringObj("t", 1)); - pObj = Tcl_NewStringObj((char *)sqlite3_value_text(pVal), -1); + pObj = Tcl_NewStringObj(z, n); break; + } case SQLITE_BLOB: Tcl_ListObjAppendElement(0, pList, Tcl_NewStringObj("b", 1)); pObj = Tcl_NewByteArrayObj( diff --git a/manifest b/manifest index 60f4a66dd8..3d8c760b5d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sthe\slatest\s3.8.4\stweaks\sfrom\strunk. -D 2014-03-06T13:48:31.335 +C Enhance\sthe\stest\sharness\sfor\sthe\ssessions\sinterface\sso\sthat\sit\sdoes\snot\nuse\sSQLite\soperations\sthat\scan\sencounter\san\sOOM\serror\sin\splaces\swhere\sit\nis\sunable\sto\sreport\san\sOOM\serror\sback\sup\sto\sthe\stest\sscript. +D 2014-03-06T14:53:25.586 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e4ee6d36cdf6136aee0158675a3b24dd3bf31a5a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -152,7 +152,7 @@ F ext/session/session_common.tcl 1539d8973b2aea0025c133eb0cc4c89fcef541a5 F ext/session/sessionfault.test 496291b287ba3c0b14ca2e074425e29cc92a64a6 F ext/session/sqlite3session.c 34e19186d05d534e5a37a4f5a8a3c3e24e3fa88a F ext/session/sqlite3session.h 6c35057241567ed6319f750ee504a81c459225e1 -F ext/session/test_session.c d38968307c05229cc8cd603722cf305d6f768832 +F ext/session/test_session.c b74ddeb47ef034618af1e7e7f7d70dadfd61e13c F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt f439556c5ce01ced70987e5ee86549a45165d9ff @@ -1170,7 +1170,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P a1f2b0428518ec18af74a0e01deb4e40cd95a78f 0a4200f95cf46ad620b9fd91f4444114a0c74730 -R 6b398dedc2e443426b8d1ae4a040c589 +P 1ed463d91866182fbc884fb88770717ee5bf33ce +R 96958e98af456557b41c042e55a4957f U drh -Z 5e939e72ef6a3efe23540b139841828b +Z 0502c27f4f3e5bf50ee9c481e253dd89 diff --git a/manifest.uuid b/manifest.uuid index 732285ae0a..76378d0acd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1ed463d91866182fbc884fb88770717ee5bf33ce \ No newline at end of file +bc0e661033b78f27866932244e6204985ae39000 \ No newline at end of file From 87778c7f9692542c7be393ece73fab30366b6e75 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 6 Mar 2014 15:01:11 +0000 Subject: [PATCH 0085/1484] Fix a harmless compiler warning in the sessions test harness. FossilOrigin-Name: d389e20ab07a76d0c4be3801265977fa977a4394 --- ext/session/test_session.c | 2 +- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/ext/session/test_session.c b/ext/session/test_session.c index 022cbc6679..f1c2fbe9a3 100644 --- a/ext/session/test_session.c +++ b/ext/session/test_session.c @@ -253,7 +253,7 @@ static int test_obj_eq_string(Tcl_Obj *p, const char *z){ int nObj; char *zObj; - n = strlen(z); + n = (int)strlen(z); zObj = Tcl_GetStringFromObj(p, &nObj); return (nObj==n && (n==0 || 0==memcmp(zObj, z, n))); diff --git a/manifest b/manifest index 3d8c760b5d..8f664024a5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\sthe\stest\sharness\sfor\sthe\ssessions\sinterface\sso\sthat\sit\sdoes\snot\nuse\sSQLite\soperations\sthat\scan\sencounter\san\sOOM\serror\sin\splaces\swhere\sit\nis\sunable\sto\sreport\san\sOOM\serror\sback\sup\sto\sthe\stest\sscript. -D 2014-03-06T14:53:25.586 +C Fix\sa\sharmless\scompiler\swarning\sin\sthe\ssessions\stest\sharness. +D 2014-03-06T15:01:11.376 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e4ee6d36cdf6136aee0158675a3b24dd3bf31a5a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -152,7 +152,7 @@ F ext/session/session_common.tcl 1539d8973b2aea0025c133eb0cc4c89fcef541a5 F ext/session/sessionfault.test 496291b287ba3c0b14ca2e074425e29cc92a64a6 F ext/session/sqlite3session.c 34e19186d05d534e5a37a4f5a8a3c3e24e3fa88a F ext/session/sqlite3session.h 6c35057241567ed6319f750ee504a81c459225e1 -F ext/session/test_session.c b74ddeb47ef034618af1e7e7f7d70dadfd61e13c +F ext/session/test_session.c 7878ac0e2fe9675e8ec24d54f6a538ccc105977f F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt f439556c5ce01ced70987e5ee86549a45165d9ff @@ -1170,7 +1170,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 1ed463d91866182fbc884fb88770717ee5bf33ce -R 96958e98af456557b41c042e55a4957f +P bc0e661033b78f27866932244e6204985ae39000 +R 973bedbe61265104f3741c995c452b29 U drh -Z 0502c27f4f3e5bf50ee9c481e253dd89 +Z 1571e450ec5231b885fc926309559de1 diff --git a/manifest.uuid b/manifest.uuid index 76378d0acd..04ddcd160e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bc0e661033b78f27866932244e6204985ae39000 \ No newline at end of file +d389e20ab07a76d0c4be3801265977fa977a4394 \ No newline at end of file From dcc5c7b2fcdfbc89bea36650cdbaf454217783bb Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 11 Apr 2014 16:14:54 +0000 Subject: [PATCH 0086/1484] Update comments in the R-Tree module in preparation for some big changes. Add an "rtree" performance test to speedtest1. FossilOrigin-Name: 20a73ec0b2f56609a4504052e198e32803d30207 --- ext/rtree/rtree.c | 102 +++++++++++++++++++++++----------------------- manifest | 17 ++++---- manifest.uuid | 2 +- test/speedtest1.c | 97 ++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 158 insertions(+), 60 deletions(-) diff --git a/ext/rtree/rtree.c b/ext/rtree/rtree.c index cefb9a8b2a..2034ff693f 100644 --- a/ext/rtree/rtree.c +++ b/ext/rtree/rtree.c @@ -110,6 +110,7 @@ #include "sqlite3rtree.h" typedef sqlite3_int64 i64; typedef unsigned char u8; +typedef unsigned short u16; typedef unsigned int u32; #endif @@ -135,7 +136,7 @@ typedef union RtreeCoord RtreeCoord; ** ever contain very many entries, so a fixed number of buckets is ** used. */ -#define HASHSIZE 128 +#define HASHSIZE 97 /* The xBestIndex method of this virtual table requires an estimate of ** the number of rows in the virtual table to calculate the costs of @@ -151,15 +152,15 @@ typedef union RtreeCoord RtreeCoord; ** An rtree virtual-table object. */ struct Rtree { - sqlite3_vtab base; + sqlite3_vtab base; /* Base class. Must be first */ sqlite3 *db; /* Host database connection */ int iNodeSize; /* Size in bytes of each node in the node table */ - int nDim; /* Number of dimensions */ - int nBytesPerCell; /* Bytes consumed per cell */ + u8 nDim; /* Number of dimensions */ + u8 eCoordType; /* RTREE_COORD_REAL32 or RTREE_COORD_INT32 */ + u8 nBytesPerCell; /* Bytes consumed per cell */ int iDepth; /* Current depth of the r-tree structure */ char *zDb; /* Name of database containing r-tree table */ char *zName; /* Name of r-tree table */ - RtreeNode *aHash[HASHSIZE]; /* Hash table of in-memory nodes. */ int nBusy; /* Current number of users of this structure */ i64 nRowEst; /* Estimated number of rows in this table */ @@ -186,10 +187,10 @@ struct Rtree { sqlite3_stmt *pWriteParent; sqlite3_stmt *pDeleteParent; - int eCoordType; + RtreeNode *aHash[HASHSIZE]; /* Hash table of in-memory nodes. */ }; -/* Possible values for eCoordType: */ +/* Possible values for Rtree.eCoordType: */ #define RTREE_COORD_REAL32 0 #define RTREE_COORD_INT32 1 @@ -232,7 +233,7 @@ struct Rtree { ** An rtree cursor object. */ struct RtreeCursor { - sqlite3_vtab_cursor base; + sqlite3_vtab_cursor base; /* Base class. Must be first */ RtreeNode *pNode; /* Node cursor is currently pointing at */ int iCell; /* Index of current cell in pNode */ int iStrategy; /* Copy of idxNum search parameter */ @@ -240,9 +241,13 @@ struct RtreeCursor { RtreeConstraint *aConstraint; /* Search constraints. */ }; +/* +** A coordinate can be either a floating point number or a integer. All +** coordinates within a single R-Tree are always of the same time. +*/ union RtreeCoord { - RtreeValue f; - int i; + RtreeValue f; /* Floating point value */ + int i; /* Integer value */ }; /* @@ -284,21 +289,23 @@ struct RtreeConstraint { ** An rtree structure node. */ struct RtreeNode { - RtreeNode *pParent; /* Parent node */ - i64 iNode; - int nRef; - int isDirty; - u8 *zData; - RtreeNode *pNext; /* Next node in this hash chain */ + RtreeNode *pParent; /* Parent node */ + i64 iNode; /* The node number */ + int nRef; /* Number of references to this node */ + int isDirty; /* True if the node needs to be written to disk */ + u8 *zData; /* Content of the node, as should be on disk */ + RtreeNode *pNext; /* Next node in this hash collision chain */ }; + +/* Return the number of cells in a node */ #define NCELL(pNode) readInt16(&(pNode)->zData[2]) /* -** Structure to store a deserialized rtree record. +** A single cell from a node, deserialized */ struct RtreeCell { - i64 iRowid; - RtreeCoord aCoord[RTREE_MAX_DIMENSIONS*2]; + i64 iRowid; /* Node or entry ID */ + RtreeCoord aCoord[RTREE_MAX_DIMENSIONS*2]; /* Bounding box coordinates */ }; @@ -426,10 +433,7 @@ static void nodeZero(Rtree *pRtree, RtreeNode *p){ ** in the Rtree.aHash table. */ static int nodeHash(i64 iNode){ - return ( - (iNode>>56) ^ (iNode>>48) ^ (iNode>>40) ^ (iNode>>32) ^ - (iNode>>24) ^ (iNode>>16) ^ (iNode>> 8) ^ (iNode>> 0) - ) % HASHSIZE; + return iNode % HASHSIZE; } /* @@ -489,8 +493,7 @@ static RtreeNode *nodeNew(Rtree *pRtree, RtreeNode *pParent){ /* ** Obtain a reference to an r-tree node. */ -static int -nodeAcquire( +static int nodeAcquire( Rtree *pRtree, /* R-tree structure */ i64 iNode, /* Node number to load */ RtreeNode *pParent, /* Either the parent node or NULL */ @@ -579,10 +582,10 @@ nodeAcquire( ** Overwrite cell iCell of node pNode with the contents of pCell. */ static void nodeOverwriteCell( - Rtree *pRtree, - RtreeNode *pNode, - RtreeCell *pCell, - int iCell + Rtree *pRtree, /* The overall R-Tree */ + RtreeNode *pNode, /* The node into which the cell is to be written */ + RtreeCell *pCell, /* The cell to write */ + int iCell /* Index into pNode into which pCell is written */ ){ int ii; u8 *p = &pNode->zData[4 + pRtree->nBytesPerCell*iCell]; @@ -594,7 +597,7 @@ static void nodeOverwriteCell( } /* -** Remove cell the cell with index iCell from node pNode. +** Remove the cell with index iCell from node pNode. */ static void nodeDeleteCell(Rtree *pRtree, RtreeNode *pNode, int iCell){ u8 *pDst = &pNode->zData[4 + pRtree->nBytesPerCell*iCell]; @@ -611,11 +614,10 @@ static void nodeDeleteCell(Rtree *pRtree, RtreeNode *pNode, int iCell){ ** ** If there is not enough free space in pNode, return SQLITE_FULL. */ -static int -nodeInsertCell( - Rtree *pRtree, - RtreeNode *pNode, - RtreeCell *pCell +static int nodeInsertCell( + Rtree *pRtree, /* The overall R-Tree */ + RtreeNode *pNode, /* Write new cell into this node */ + RtreeCell *pCell /* The cell to be inserted */ ){ int nCell; /* Current number of cells in pNode */ int nMaxCell; /* Maximum number of cells for pNode */ @@ -636,8 +638,7 @@ nodeInsertCell( /* ** If the node is dirty, write it out to the database. */ -static int -nodeWrite(Rtree *pRtree, RtreeNode *pNode){ +static int nodeWrite(Rtree *pRtree, RtreeNode *pNode){ int rc = SQLITE_OK; if( pNode->isDirty ){ sqlite3_stmt *p = pRtree->pWriteNode; @@ -662,8 +663,7 @@ nodeWrite(Rtree *pRtree, RtreeNode *pNode){ ** Release a reference to a node. If the node is dirty and the reference ** count drops to zero, the node data is written to the database. */ -static int -nodeRelease(Rtree *pRtree, RtreeNode *pNode){ +static int nodeRelease(Rtree *pRtree, RtreeNode *pNode){ int rc = SQLITE_OK; if( pNode ){ assert( pNode->nRef>0 ); @@ -691,9 +691,9 @@ nodeRelease(Rtree *pRtree, RtreeNode *pNode){ ** an internal node, then the 64-bit integer is a child page number. */ static i64 nodeGetRowid( - Rtree *pRtree, - RtreeNode *pNode, - int iCell + Rtree *pRtree, /* The overall R-Tree */ + RtreeNode *pNode, /* The node from which to extract the ID */ + int iCell /* The cell index from which to extract the ID */ ){ assert( iCellzData[4 + pRtree->nBytesPerCell*iCell]); @@ -703,11 +703,11 @@ static i64 nodeGetRowid( ** Return coordinate iCoord from cell iCell in node pNode. */ static void nodeGetCoord( - Rtree *pRtree, - RtreeNode *pNode, - int iCell, - int iCoord, - RtreeCoord *pCoord /* Space to write result to */ + Rtree *pRtree, /* The overall R-Tree */ + RtreeNode *pNode, /* The node from which to extract a coordinate */ + int iCell, /* The index of the cell within the node */ + int iCoord, /* Which coordinate to extract */ + RtreeCoord *pCoord /* OUT: Space to write result to */ ){ readCoord(&pNode->zData[12 + pRtree->nBytesPerCell*iCell + 4*iCoord], pCoord); } @@ -717,10 +717,10 @@ static void nodeGetCoord( ** to by pCell with the results. */ static void nodeGetCell( - Rtree *pRtree, - RtreeNode *pNode, - int iCell, - RtreeCell *pCell + Rtree *pRtree, /* The overall R-Tree */ + RtreeNode *pNode, /* The node containing the cell to be read */ + int iCell, /* Index of the cell within the node */ + RtreeCell *pCell /* OUT: Write the cell contents here */ ){ int ii; pCell->iRowid = nodeGetRowid(pRtree, pNode, iCell); diff --git a/manifest b/manifest index 0602716bed..1a7e491bc3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sall\srecent\schanges\sfrom\strunk,\nincluding\sthe\sfix\sfor\sthe\sOP_SCopy-vs-OP_Copy\sproblem. -D 2014-04-03T16:35:33.203 +C Update\scomments\sin\sthe\sR-Tree\smodule\sin\spreparation\sfor\ssome\sbig\schanges.\nAdd\san\s"rtree"\sperformance\stest\sto\sspeedtest1. +D 2014-04-11T16:14:54.092 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e4ee6d36cdf6136aee0158675a3b24dd3bf31a5a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -120,7 +120,7 @@ F ext/misc/vfslog.c fe40fab5c077a40477f7e5eba994309ecac6cc95 F ext/misc/vtshim.c babb0dc2bf116029e3e7c9a618b8a1377045303e F ext/misc/wholenumber.c 784b12543d60702ebdd47da936e278aa03076212 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 -F ext/rtree/rtree.c 2d9f95da404d850474e628c720c5ce15d29b47de +F ext/rtree/rtree.c 043f16a6c3f823c760657b975f2ff1de7fe5c197 F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e F ext/rtree/rtree1.test cf679265ecafff494a768ac9c2f43a70915a6290 F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba @@ -840,7 +840,7 @@ F test/speed3.test d32043614c08c53eafdc80f33191d5bd9b920523 F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715 F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b -F test/speedtest1.c 90446861e566a9965a8d005381a3c964ff333646 +F test/speedtest1.c 3e06b48e8c578eaa61a01e8c7c4d8734c9dd3776 F test/spellfix.test 61309f5efbec53603b3f86457d34a504f80abafe F test/sqllimits1.test b1aae27cc98eceb845e7f7adf918561256e31298 F test/stat.test 76fd746b85459e812a0193410fb599f0531f22de @@ -1174,7 +1174,10 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P fc8ca1a87e7127bd28f32fd809aec3e24355fbfa d5513dfa23baa0b0a095aaf17d19aacd30dcef61 -R 507e4fb477cf51261d2563e52f7cfa77 +P 9515c8344a6743bbb0c6a6e49fb79fb3139090df +R 57f2249bba89c44cd5839664eafe6658 +T *branch * rtree-enhancements +T *sym-rtree-enhancements * +T -sym-sessions * U drh -Z a91c37323943563a6d3bfb60a104e003 +Z bdd5cbefa0a4dcc9a9cc6ed610b85f71 diff --git a/manifest.uuid b/manifest.uuid index 7a0e457ea7..d8135897dd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9515c8344a6743bbb0c6a6e49fb79fb3139090df \ No newline at end of file +20a73ec0b2f56609a4504052e198e32803d30207 \ No newline at end of file diff --git a/test/speedtest1.c b/test/speedtest1.c index 28c24e0885..a32f12f923 100644 --- a/test/speedtest1.c +++ b/test/speedtest1.c @@ -931,6 +931,98 @@ void testset_cte(void){ } +/* Generate two numbers between 1 and mx. The first number is less than +** the second. Usually the numbers are near each other but can sometimes +** be far apart. +*/ +static void twoCoords( + unsigned mx, /* Range of 1..mx */ + unsigned *pX0, unsigned *pX1 /* OUT: write results here */ +){ + unsigned d, x0, x1, span; + + span = mx/100 + 1; + if( speedtest1_random()%3==0 ) span *= 3; + if( speedtest1_random()%17==0 ) span = mx - 5; + d = speedtest1_random()%span + 1; + x0 = speedtest1_random()%(mx-d) + 1; + x1 = x0 + d; + *pX0 = x0; + *pX1 = x1; +} + +/* +** A testset for the R-Tree virtual table +*/ +void testset_rtree(void){ + unsigned i, n; + unsigned mxCoord; + unsigned x0, x1, y0, y1, z0, z1; + + mxCoord = g.szTest*600; + n = g.szTest*100; + speedtest1_begin_test(100, "%d INSERTs into an r-tree", n); + speedtest1_exec("BEGIN"); + speedtest1_exec("CREATE VIRTUAL TABLE rt1 USING rtree(id,x0,x1,y0,y1,z0,z1)"); + speedtest1_prepare("INSERT INTO rt1(id,x0,x1,y0,y1,z0,z1)" + "VALUES(?1,?2,?3,?4,?5,?6,?7)"); + for(i=1; i<=n; i++){ + twoCoords(mxCoord, &x0, &x1); + twoCoords(mxCoord, &y0, &y1); + twoCoords(mxCoord, &z0, &z1); + sqlite3_bind_int(g.pStmt, 1, i); + sqlite3_bind_int(g.pStmt, 2, x0); + sqlite3_bind_int(g.pStmt, 3, x1); + sqlite3_bind_int(g.pStmt, 4, y0); + sqlite3_bind_int(g.pStmt, 5, y1); + sqlite3_bind_int(g.pStmt, 6, z0); + sqlite3_bind_int(g.pStmt, 7, z1); + speedtest1_run(); + } + speedtest1_exec("COMMIT"); + speedtest1_end_test(); + + n = g.szTest*20; + speedtest1_begin_test(110, "%d one-dimensional intersect slice queries", n); + speedtest1_prepare("SELECT count(*) FROM rt1 WHERE x0>=?1 AND x1<=?2"); + for(i=0; i=?1 AND y0<=?2"); + for(i=0; i=?1 AND x0<=?2" + " AND y1>=?1 AND y0<=?2 AND z1>=?1 AND z0<=?2"); + for(i=0; i Date: Fri, 11 Apr 2014 17:41:08 +0000 Subject: [PATCH 0087/1484] Add the --verify option to speedtest1. Add verification test cases to the "rtree" testset and a case that uses a custom geometry callback. FossilOrigin-Name: 9d485c4207a81f32334857d4a608c5c511dd2b83 --- manifest | 15 +++--- manifest.uuid | 2 +- test/speedtest1.c | 116 ++++++++++++++++++++++++++++++++++++++++------ 3 files changed, 109 insertions(+), 24 deletions(-) diff --git a/manifest b/manifest index 1a7e491bc3..12cad8c970 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\scomments\sin\sthe\sR-Tree\smodule\sin\spreparation\sfor\ssome\sbig\schanges.\nAdd\san\s"rtree"\sperformance\stest\sto\sspeedtest1. -D 2014-04-11T16:14:54.092 +C Add\sthe\s--verify\soption\sto\sspeedtest1.\s\sAdd\sverification\stest\scases\sto\nthe\s"rtree"\stestset\sand\sa\scase\sthat\suses\sa\scustom\sgeometry\scallback. +D 2014-04-11T17:41:08.614 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e4ee6d36cdf6136aee0158675a3b24dd3bf31a5a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -840,7 +840,7 @@ F test/speed3.test d32043614c08c53eafdc80f33191d5bd9b920523 F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715 F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b -F test/speedtest1.c 3e06b48e8c578eaa61a01e8c7c4d8734c9dd3776 +F test/speedtest1.c 017473605f9df5f4770dd60ddb4038e6d6829916 F test/spellfix.test 61309f5efbec53603b3f86457d34a504f80abafe F test/sqllimits1.test b1aae27cc98eceb845e7f7adf918561256e31298 F test/stat.test 76fd746b85459e812a0193410fb599f0531f22de @@ -1174,10 +1174,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 9515c8344a6743bbb0c6a6e49fb79fb3139090df -R 57f2249bba89c44cd5839664eafe6658 -T *branch * rtree-enhancements -T *sym-rtree-enhancements * -T -sym-sessions * +P 20a73ec0b2f56609a4504052e198e32803d30207 +R 47999e8bbddb67bbaef79a4f5741e58b U drh -Z bdd5cbefa0a4dcc9a9cc6ed610b85f71 +Z 73dffdddfd99e7f86f5cf9f646a8ff0c diff --git a/manifest.uuid b/manifest.uuid index d8135897dd..0d054cdd30 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -20a73ec0b2f56609a4504052e198e32803d30207 \ No newline at end of file +9d485c4207a81f32334857d4a608c5c511dd2b83 \ No newline at end of file diff --git a/test/speedtest1.c b/test/speedtest1.c index a32f12f923..0680e9599f 100644 --- a/test/speedtest1.c +++ b/test/speedtest1.c @@ -29,6 +29,7 @@ static const char zHelp[] = " --trace Turn on SQL tracing\n" " --utf16be Set text encoding to UTF-16BE\n" " --utf16le Set text encoding to UTF-16LE\n" + " --verify Run additional verification steps.\n" " --without-rowid Use WITHOUT ROWID where appropriate\n" ; @@ -51,6 +52,7 @@ static struct Global { int bReprepare; /* True to reprepare the SQL on each rerun */ int bSqlOnly; /* True to print the SQL once only */ int bExplain; /* Print SQL with EXPLAIN prefix */ + int bVerify; /* Try to verify that results are correct */ int szTest; /* Scale factor for test iterations */ const char *zWR; /* Might be WITHOUT ROWID */ const char *zNN; /* Might be NOT NULL */ @@ -951,6 +953,26 @@ static void twoCoords( *pX1 = x1; } +/* The following routine is an R-Tree geometry callback. It returns +** true if the object overlaps a slice on the Y coordinate between the +** two values given as arguments. In other words +** +** SELECT count(*) FROM rt1 WHERE id MATCH xslice(10,20); +** +** Is the same as saying: +** +** SELECT count(*) FROM rt1 WHERE y1>=10 AND y0<=20; +*/ +static int xsliceGeometryCallback( + sqlite3_rtree_geometry *p, + int nCoord, + double *aCoord, + int *pRes +){ + *pRes = aCoord[3]>=p->aParam[0] && aCoord[2]<=p->aParam[1]; + return SQLITE_OK; +} + /* ** A testset for the R-Tree virtual table */ @@ -958,6 +980,8 @@ void testset_rtree(void){ unsigned i, n; unsigned mxCoord; unsigned x0, x1, y0, y1, z0, z1; + unsigned iStep; + int *aCheck = sqlite3_malloc( sizeof(int)*g.szTest*100 ); mxCoord = g.szTest*600; n = g.szTest*100; @@ -982,23 +1006,83 @@ void testset_rtree(void){ speedtest1_exec("COMMIT"); speedtest1_end_test(); - n = g.szTest*20; - speedtest1_begin_test(110, "%d one-dimensional intersect slice queries", n); - speedtest1_prepare("SELECT count(*) FROM rt1 WHERE x0>=?1 AND x1<=?2"); - for(i=0; i=?1 AND x1<=?2"); + iStep = mxCoord/n; + for(i=0; i=?1 AND x1<=?2"); + iStep = mxCoord/n; + for(i=0; i=?1 AND y0<=?2"); - for(i=0; i=?1 AND y0<=?2"); + iStep = mxCoord/n; + for(i=0; i=?1 AND x0<=?2" " AND y1>=?1 AND y0<=?2 AND z1>=?1 AND z0<=?2"); - for(i=0; i Date: Fri, 11 Apr 2014 23:14:48 +0000 Subject: [PATCH 0088/1484] Add the new interfaces to rtree, though they do not yet work. Add the "show_speedtest1_rtree.tcl" script for showing the test data used for the R-Tree tests of speedtest1. Change speedtest1 to generate better R-Tree test data. FossilOrigin-Name: 0b70275972c7a6a533566c1e50bffbf3ac531e95 --- ext/rtree/rtree.c | 68 +++++++++++++++++++++++++--------- ext/rtree/sqlite3rtree.h | 61 +++++++++++++++++++++++++++--- main.mk | 2 +- manifest | 19 +++++----- manifest.uuid | 2 +- test/show_speedtest1_rtree.tcl | 57 ++++++++++++++++++++++++++++ test/speedtest1.c | 17 +++++---- 7 files changed, 184 insertions(+), 42 deletions(-) create mode 100644 test/show_speedtest1_rtree.tcl diff --git a/ext/rtree/rtree.c b/ext/rtree/rtree.c index 2034ff693f..ddfc3d79a1 100644 --- a/ext/rtree/rtree.c +++ b/ext/rtree/rtree.c @@ -324,21 +324,24 @@ struct RtreeCell { struct RtreeMatchArg { u32 magic; /* Always RTREE_GEOMETRY_MAGIC */ int (*xGeom)(sqlite3_rtree_geometry *, int, RtreeDValue*, int *); + int (*xQueryFunc)(sqlite3_rtree_query_info*); void *pContext; int nParam; RtreeDValue aParam[1]; }; /* -** When a geometry callback is created (see sqlite3_rtree_geometry_callback), +** When a geometry callback is created using either +** sqlite3_rtree_geometry_callback() or sqlite3_rtree_query_callback(), ** a single instance of the following structure is allocated. It is used -** as the context for the user-function created by by s_r_g_c(). The object -** is eventually deleted by the destructor mechanism provided by -** sqlite3_create_function_v2() (which is called by s_r_g_c() to create -** the geometry callback function). +** as the context for the user-function created by sqlite3_rtree_*_callback(). +** The object is eventually deleted by the destructor mechanism provided by +** sqlite3_create_function_v2(). */ struct RtreeGeomCallback { int (*xGeom)(sqlite3_rtree_geometry*, int, RtreeDValue*, int*); + int (*xQueryFunc)(sqlite3_rtree_query_info*); + void (*xDestructor)(void*); void *pContext; }; @@ -3352,22 +3355,23 @@ int sqlite3RtreeInit(sqlite3 *db){ } /* -** A version of sqlite3_free() that can be used as a callback. This is used -** in two places - as the destructor for the blob value returned by the -** invocation of a geometry function, and as the destructor for the geometry -** functions themselves. +** This routine is called when a custom geometry function or custom query +** function is cancelled. The pointer is to a RtreeGeomCallback object +** that needs to be freed. */ -static void doSqlite3Free(void *p){ +static void rtreeFreeCallback(void *p){ + RtreeGeomCallback *pGeom = (RtreeGeomCallback*)p; + if( pGeom->xDestructor ) pGeom->xDestructor(pGeom->pContext); sqlite3_free(p); } /* -** Each call to sqlite3_rtree_geometry_callback() creates an ordinary SQLite -** scalar user function. This C function is the callback used for all such -** registered SQL functions. +** Each call to sqlite3_rtree_geometry_callback() or +** sqlite3_rtree_query_callback() creates an ordinary SQLite +** scalar user function that is implemented by this routine. ** -** The scalar user functions return a blob that is interpreted by r-tree -** table MATCH operators. +** This function returns a blob that is interpreted by r-tree +** table MATCH operator. */ static void geomCallback(sqlite3_context *ctx, int nArg, sqlite3_value **aArg){ RtreeGeomCallback *pGeomCtx = (RtreeGeomCallback *)sqlite3_user_data(ctx); @@ -3391,7 +3395,7 @@ static void geomCallback(sqlite3_context *ctx, int nArg, sqlite3_value **aArg){ pBlob->aParam[i] = sqlite3_value_double(aArg[i]); #endif } - sqlite3_result_blob(ctx, pBlob, nBlob, doSqlite3Free); + sqlite3_result_blob(ctx, pBlob, nBlob, sqlite3_free); } } @@ -3410,12 +3414,42 @@ int sqlite3_rtree_geometry_callback( pGeomCtx = (RtreeGeomCallback *)sqlite3_malloc(sizeof(RtreeGeomCallback)); if( !pGeomCtx ) return SQLITE_NOMEM; pGeomCtx->xGeom = xGeom; + pGeomCtx->xQueryFunc = 0; + pGeomCtx->xDestructor = 0; pGeomCtx->pContext = pContext; /* Create the new user-function. Register a destructor function to delete ** the context object when it is no longer required. */ return sqlite3_create_function_v2(db, zGeom, -1, SQLITE_ANY, - (void *)pGeomCtx, geomCallback, 0, 0, doSqlite3Free + (void *)pGeomCtx, geomCallback, 0, 0, rtreeFreeCallback + ); +} + +/* +** Register a new 2nd-generation geometry function for use with the +** r-tree MATCH operator. +*/ +int sqlite3_rtree_query_callback( + sqlite3 *db, + const char *zQueryFunc, + int (*xQueryFunc)(sqlite3_rtree_query_info*), + void *pContext, + void (*xDestructor)(void*) +){ + RtreeGeomCallback *pGeomCtx; /* Context object for new user-function */ + + /* Allocate and populate the context object. */ + pGeomCtx = (RtreeGeomCallback *)sqlite3_malloc(sizeof(RtreeGeomCallback)); + if( !pGeomCtx ) return SQLITE_NOMEM; + pGeomCtx->xGeom = 0; + pGeomCtx->xQueryFunc = xQueryFunc; + pGeomCtx->xDestructor = xDestructor; + pGeomCtx->pContext = pContext; + + /* Create the new user-function. Register a destructor function to delete + ** the context object when it is no longer required. */ + return sqlite3_create_function_v2(db, zQueryFunc, -1, SQLITE_ANY, + (void *)pGeomCtx, geomCallback, 0, 0, rtreeFreeCallback ); } diff --git a/ext/rtree/sqlite3rtree.h b/ext/rtree/sqlite3rtree.h index c849091f29..79d1ffeede 100644 --- a/ext/rtree/sqlite3rtree.h +++ b/ext/rtree/sqlite3rtree.h @@ -21,6 +21,16 @@ extern "C" { #endif typedef struct sqlite3_rtree_geometry sqlite3_rtree_geometry; +typedef struct sqlite3_rtree_query_info sqlite3_rtree_query_info; + +/* The double-precision datatype used by RTree depends on the +** SQLITE_RTREE_INT_ONLY compile-time option. +*/ +#ifdef SQLITE_RTREE_INT_ONLY + typedef sqlite3_int64 sqlite3_rtree_dbl; +#else + typedef double sqlite3_rtree_dbl; +#endif /* ** Register a geometry callback named zGeom that can be used as part of an @@ -31,11 +41,7 @@ typedef struct sqlite3_rtree_geometry sqlite3_rtree_geometry; int sqlite3_rtree_geometry_callback( sqlite3 *db, const char *zGeom, -#ifdef SQLITE_RTREE_INT_ONLY - int (*xGeom)(sqlite3_rtree_geometry*, int n, sqlite3_int64 *a, int *pRes), -#else - int (*xGeom)(sqlite3_rtree_geometry*, int n, double *a, int *pRes), -#endif + int (*xGeom)(sqlite3_rtree_geometry*, int, sqlite3_rtree_dbl*,int*), void *pContext ); @@ -47,11 +53,54 @@ int sqlite3_rtree_geometry_callback( struct sqlite3_rtree_geometry { void *pContext; /* Copy of pContext passed to s_r_g_c() */ int nParam; /* Size of array aParam[] */ - double *aParam; /* Parameters passed to SQL geom function */ + sqlite3_rtree_dbl *aParam; /* Parameters passed to SQL geom function */ void *pUser; /* Callback implementation user data */ void (*xDelUser)(void *); /* Called by SQLite to clean up pUser */ }; +/* +** Register a 2nd-generation geometry callback named zScore that can be +** used as part of an R-Tree geometry query as follows: +** +** SELECT ... FROM WHERE MATCH $zQueryFunc(... params ...) +*/ +int sqlite3_rtree_query_callback( + sqlite3 *db, + const char *zQueryFunc, + int (*xQueryFunc)(sqlite3_rtree_query_info*), + void *pContext, + void (*xDestructor)(void*) +); + + +/* +** A pointer to a structure of the following type is passed as the +** argument to scored geometry callback registered using +** sqlite3_rtree_query_callback(). +*/ +struct sqlite3_rtree_query_info { + void *pContext; /* pContext from when function registered */ + int nParam; /* Number of function parameters */ + sqlite3_rtree_dbl *aParam; /* value of function parameters */ + void *pUser; /* callback can use this, if desired */ + void (*xDelUser)(void*); /* function to free pUser */ + sqlite3_rtree_dbl *aCoord; /* Coordinates of node or entry to check */ + int nCoord; /* Number of coordinates */ + int iLevel; /* Level of current node or entry */ + sqlite3_int64 iRowid; /* Rowid for current entry */ + sqlite3_rtree_dbl rParentScore; /* Score of parent node */ + int eParentWithin; /* Visibility of parent node */ + int eWithin; /* OUT: Visiblity */ + sqlite3_rtree_dbl rScore; /* OUT: Write the score here */ +}; + +/* +** Allowed values for sqlite3_rtree_query.eWithin and .eParentWithin. +*/ +#define NOT_WITHIN 0 /* Object completely outside of query region */ +#define PARTLY_WITHIN 1 /* Object partially overlaps query region */ +#define FULLY_WITHIN 2 /* Object fully contained within query region */ + #ifdef __cplusplus } /* end of the 'extern "C"' block */ diff --git a/main.mk b/main.mk index d7f8aaa3dd..57757ccc6a 100644 --- a/main.mk +++ b/main.mk @@ -483,7 +483,7 @@ parse.c: $(TOP)/src/parse.y lemon $(TOP)/addopcodes.awk mv parse.h parse.h.temp $(NAWK) -f $(TOP)/addopcodes.awk parse.h.temp >parse.h -sqlite3.h: $(TOP)/src/sqlite.h.in $(TOP)/manifest.uuid $(TOP)/VERSION +sqlite3.h: $(TOP)/src/sqlite.h.in $(TOP)/manifest.uuid $(TOP)/VERSION $(TOP)/ext/rtree/sqlite3rtree.h tclsh $(TOP)/tool/mksqlite3h.tcl $(TOP) >sqlite3.h keywordhash.h: $(TOP)/tool/mkkeywordhash.c diff --git a/manifest b/manifest index 12cad8c970..af46986305 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\s--verify\soption\sto\sspeedtest1.\s\sAdd\sverification\stest\scases\sto\nthe\s"rtree"\stestset\sand\sa\scase\sthat\suses\sa\scustom\sgeometry\scallback. -D 2014-04-11T17:41:08.614 +C Add\sthe\snew\sinterfaces\sto\srtree,\sthough\sthey\sdo\snot\syet\swork.\s\sAdd\sthe\n"show_speedtest1_rtree.tcl"\sscript\sfor\sshowing\sthe\stest\sdata\sused\sfor\sthe\nR-Tree\stests\sof\sspeedtest1.\s\sChange\sspeedtest1\sto\sgenerate\sbetter\sR-Tree\ntest\sdata. +D 2014-04-11T23:14:48.914 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e4ee6d36cdf6136aee0158675a3b24dd3bf31a5a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -120,7 +120,7 @@ F ext/misc/vfslog.c fe40fab5c077a40477f7e5eba994309ecac6cc95 F ext/misc/vtshim.c babb0dc2bf116029e3e7c9a618b8a1377045303e F ext/misc/wholenumber.c 784b12543d60702ebdd47da936e278aa03076212 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 -F ext/rtree/rtree.c 043f16a6c3f823c760657b975f2ff1de7fe5c197 +F ext/rtree/rtree.c 541016f8a53bbedda4dc2deb0067f6955b0accb9 F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e F ext/rtree/rtree1.test cf679265ecafff494a768ac9c2f43a70915a6290 F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba @@ -137,7 +137,7 @@ F ext/rtree/rtreeC.test 16d7aa86ecb6a876d2a38cf590a1471a41b3a46d F ext/rtree/rtreeD.test 636630357638f5983701550b37f0f5867130d2ca F ext/rtree/rtree_perf.tcl 6c18c1f23cd48e0f948930c98dfdd37dfccb5195 F ext/rtree/rtree_util.tcl 06aab2ed5b826545bf215fff90ecb9255a8647ea -F ext/rtree/sqlite3rtree.h c34c1e41d1ab80bb8ad09aae402c9c956871a765 +F ext/rtree/sqlite3rtree.h f93a466456ed25a9dadf90ad050e2945a2c49cff F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 F ext/session/session1.test 894e3bc9f497c4fa07a2aa3271e3911f3670c3d8 @@ -157,7 +157,7 @@ F ext/session/test_session.c 7878ac0e2fe9675e8ec24d54f6a538ccc105977f F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt f439556c5ce01ced70987e5ee86549a45165d9ff -F main.mk a3028a846754a96c8841d1a7227890c471c65ec2 +F main.mk 82b154dd823b75c2f1247f1bb98893bf94a5af57 F mkopcodec.awk c2ff431854d702cdd2d779c9c0d1f58fa16fa4ea F mkopcodeh.awk c6b3fa301db6ef7ac916b14c60868aeaec1337b5 F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83 @@ -825,6 +825,7 @@ F test/shell3.test 5e8545ec72c4413a0e8d4c6be56496e3c257ca29 F test/shell4.test aa4eef8118b412d1a01477a53426ece169ea86a9 F test/shell5.test bb755ea9144b8078a752fc56223582627070b5f1 F test/shortread1.test bb591ef20f0fd9ed26d0d12e80eee6d7ac8897a3 +F test/show_speedtest1_rtree.tcl 32e6c5f073d7426148a6936a0408f4b5b169aba5 F test/shrink.test 8c70f62b6e8eb4d54533de6d65bd06b1b9a17868 F test/sidedelete.test f0ad71abe6233e3b153100f3b8d679b19a488329 F test/skipscan1.test bed8cbe9d554c8c27afb6c88500f704c86a9196f @@ -840,7 +841,7 @@ F test/speed3.test d32043614c08c53eafdc80f33191d5bd9b920523 F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715 F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b -F test/speedtest1.c 017473605f9df5f4770dd60ddb4038e6d6829916 +F test/speedtest1.c d29c8048beb7ea9254191f3fde9414709166a920 F test/spellfix.test 61309f5efbec53603b3f86457d34a504f80abafe F test/sqllimits1.test b1aae27cc98eceb845e7f7adf918561256e31298 F test/stat.test 76fd746b85459e812a0193410fb599f0531f22de @@ -1174,7 +1175,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 20a73ec0b2f56609a4504052e198e32803d30207 -R 47999e8bbddb67bbaef79a4f5741e58b +P 9d485c4207a81f32334857d4a608c5c511dd2b83 +R 0017d933bc77106350e8e33449b1c08c U drh -Z 73dffdddfd99e7f86f5cf9f646a8ff0c +Z 0d8113e9fad970081c8175cf29f2569d diff --git a/manifest.uuid b/manifest.uuid index 0d054cdd30..1c530a4dc8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9d485c4207a81f32334857d4a608c5c511dd2b83 \ No newline at end of file +0b70275972c7a6a533566c1e50bffbf3ac531e95 \ No newline at end of file diff --git a/test/show_speedtest1_rtree.tcl b/test/show_speedtest1_rtree.tcl new file mode 100644 index 0000000000..3faa168146 --- /dev/null +++ b/test/show_speedtest1_rtree.tcl @@ -0,0 +1,57 @@ +#!/usr/bin/tclsh +# +# This script displays the field of rectangles used by --testset rtree +# of speedtest1. Run this script as follows: +# +# rm test.db +# ./speedtest1 --testset rtree --size 25 test.db +# sqlite3 --separator ' ' test.db 'SELECT * FROM rt1' >data.txt +# wish show_speedtest1_rtree.tcl +# +# The filename "data.txt" is hard coded into this script and so that name +# must be used on lines 3 and 4 above. Elsewhere, different filenames can +# be used. The --size N parameter can be adjusted as desired. +# +package require Tk +set f [open data.txt rb] +set data [read $f] +close $f +canvas .c +frame .b +button .b.b1 -text X-Y -command refill-xy +button .b.b2 -text X-Z -command refill-xz +button .b.b3 -text Y-Z -command refill-yz +pack .b.b1 .b.b2 .b.b3 -side left +pack .c -side top -fill both -expand 1 +pack .b -side top +proc resize_canvas_to_fit {} { + foreach {x0 y0 x1 y1} [.c bbox all] break + set w [expr {$x1-$x0}] + set h [expr {$y1-$y0}] + .c config -width $w -height $h +} +proc refill-xy {} { + .c delete all + foreach {id x0 x1 y0 y1 z0 z1} $::data { + .c create rectangle $x0 $y0 $x1 $y1 + } + .c scale all 0 0 0.05 0.05 + resize_canvas_to_fit +} +proc refill-xz {} { + .c delete all + foreach {id x0 x1 y0 y1 z0 z1} $::data { + .c create rectangle $x0 $z0 $x1 $z1 + } + .c scale all 0 0 0.05 0.05 + resize_canvas_to_fit +} +proc refill-yz {} { + .c delete all + foreach {id x0 x1 y0 y1 z0 z1} $::data { + .c create rectangle $y0 $z0 $y1 $z1 + } + .c scale all 0 0 0.05 0.05 + resize_canvas_to_fit +} +refill-xy diff --git a/test/speedtest1.c b/test/speedtest1.c index 0680e9599f..383f5809a9 100644 --- a/test/speedtest1.c +++ b/test/speedtest1.c @@ -938,14 +938,15 @@ void testset_cte(void){ ** be far apart. */ static void twoCoords( + int p1, int p2, /* Parameters adjusting sizes */ unsigned mx, /* Range of 1..mx */ unsigned *pX0, unsigned *pX1 /* OUT: write results here */ ){ unsigned d, x0, x1, span; span = mx/100 + 1; - if( speedtest1_random()%3==0 ) span *= 3; - if( speedtest1_random()%17==0 ) span = mx - 5; + if( speedtest1_random()%3==0 ) span *= p1; + if( speedtest1_random()%p2==0 ) span = mx/2; d = speedtest1_random()%span + 1; x0 = speedtest1_random()%(mx-d) + 1; x1 = x0 + d; @@ -976,14 +977,14 @@ static int xsliceGeometryCallback( /* ** A testset for the R-Tree virtual table */ -void testset_rtree(void){ +void testset_rtree(int p1, int p2){ unsigned i, n; unsigned mxCoord; unsigned x0, x1, y0, y1, z0, z1; unsigned iStep; int *aCheck = sqlite3_malloc( sizeof(int)*g.szTest*100 ); - mxCoord = g.szTest*600; + mxCoord = 15000; n = g.szTest*100; speedtest1_begin_test(100, "%d INSERTs into an r-tree", n); speedtest1_exec("BEGIN"); @@ -991,9 +992,9 @@ void testset_rtree(void){ speedtest1_prepare("INSERT INTO rt1(id,x0,x1,y0,y1,z0,z1)" "VALUES(?1,?2,?3,?4,?5,?6,?7)"); for(i=1; i<=n; i++){ - twoCoords(mxCoord, &x0, &x1); - twoCoords(mxCoord, &y0, &y1); - twoCoords(mxCoord, &z0, &z1); + twoCoords(p1, p2, mxCoord, &x0, &x1); + twoCoords(p1, p2, mxCoord, &y0, &y1); + twoCoords(p1, p2, mxCoord, &z0, &z1); sqlite3_bind_int(g.pStmt, 1, i); sqlite3_bind_int(g.pStmt, 2, x0); sqlite3_bind_int(g.pStmt, 3, x1); @@ -1322,7 +1323,7 @@ int main(int argc, char **argv){ }else if( strcmp(zTSet,"cte")==0 ){ testset_cte(); }else if( strcmp(zTSet,"rtree")==0 ){ - testset_rtree(); + testset_rtree(6, 147); }else{ fatal_error("unknown testset: \"%s\"\nChoices: main debug1 cte rtree\n", zTSet); From 0ccb6cdc874181048268ecafbbc90725a0056118 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 12 Apr 2014 17:44:00 +0000 Subject: [PATCH 0089/1484] Continuing clean-up of the R-Tree module in preparation for cutting in the new generalized query mechanism. FossilOrigin-Name: 66c858f20586424e15d0bfa3d7b56643bde66226 --- ext/rtree/rtree.c | 121 ++++++++++++++++++++++++--------------------- manifest | 14 +++--- manifest.uuid | 2 +- src/test_rtree.c | 123 ++++++++++++++++++++++++++++++++++++++++++---- 4 files changed, 185 insertions(+), 75 deletions(-) diff --git a/ext/rtree/rtree.c b/ext/rtree/rtree.c index ddfc3d79a1..e85fe4449d 100644 --- a/ext/rtree/rtree.c +++ b/ext/rtree/rtree.c @@ -289,12 +289,12 @@ struct RtreeConstraint { ** An rtree structure node. */ struct RtreeNode { - RtreeNode *pParent; /* Parent node */ - i64 iNode; /* The node number */ - int nRef; /* Number of references to this node */ - int isDirty; /* True if the node needs to be written to disk */ - u8 *zData; /* Content of the node, as should be on disk */ - RtreeNode *pNext; /* Next node in this hash collision chain */ + RtreeNode *pParent; /* Parent node */ + i64 iNode; /* The node number */ + int nRef; /* Number of references to this node */ + int isDirty; /* True if the node needs to be written to disk */ + u8 *zData; /* Content of the node, as should be on disk */ + RtreeNode *pNext; /* Next node in this hash collision chain */ }; /* Return the number of cells in a node */ @@ -310,32 +310,17 @@ struct RtreeCell { /* -** 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 must be supplied as a blob argument to -** the right-hand-side of an SQL MATCH operator used to constrain an -** r-tree query. -*/ -struct RtreeMatchArg { - u32 magic; /* Always RTREE_GEOMETRY_MAGIC */ - int (*xGeom)(sqlite3_rtree_geometry *, int, RtreeDValue*, int *); - int (*xQueryFunc)(sqlite3_rtree_query_info*); - void *pContext; - int nParam; - RtreeDValue aParam[1]; -}; - -/* -** When a geometry callback is created using either -** sqlite3_rtree_geometry_callback() or sqlite3_rtree_query_callback(), -** a single instance of the following structure is allocated. It is used -** as the context for the user-function created by sqlite3_rtree_*_callback(). -** The object is eventually deleted by the destructor mechanism provided by +** This object becomes the sqlite3_user_data() for the SQL functions +** that are created by sqlite3_rtree_geometry_callback() and +** sqlite3_rtree_query_callback() and which appear on the right of MATCH +** operators in order to constrain a search. +** +** xGeom and xQueryFunc are the callback functions. Exactly one of +** xGeom and xQueryFunc fields is non-NULL, depending on whether the +** SQL function was created using sqlite3_rtree_geometry_callback() or +** sqlite3_rtree_query_callback(). +** +** This object is deleted automatically by the destructor mechanism in ** sqlite3_create_function_v2(). */ struct RtreeGeomCallback { @@ -345,6 +330,27 @@ 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 +** sqlite3_rtree_query_callback() create, and is read as the right-hand +** operand to the MATCH operator of an R-Tree. +*/ +struct RtreeMatchArg { + u32 magic; /* Always RTREE_GEOMETRY_MAGIC */ + RtreeGeomCallback cb; /* Info about the callback functions */ + int nParam; /* Number of parameters to the SQL function */ + RtreeDValue aParam[1]; /* Values for parameters to the SQL function */ +}; + #ifndef MAX # define MAX(x,y) ((x) < (y) ? (y) : (x)) #endif @@ -1253,11 +1259,11 @@ static int deserializeGeometry(sqlite3_value *pValue, RtreeConstraint *pCons){ return SQLITE_ERROR; } - pGeom->pContext = p->pContext; + pGeom->pContext = p->cb.pContext; pGeom->nParam = p->nParam; pGeom->aParam = p->aParam; - pCons->xGeom = p->xGeom; + pCons->xGeom = p->cb.xGeom; pCons->pGeom = pGeom; return SQLITE_OK; } @@ -3355,9 +3361,11 @@ int sqlite3RtreeInit(sqlite3 *db){ } /* -** This routine is called when a custom geometry function or custom query -** function is cancelled. The pointer is to a RtreeGeomCallback object -** that needs to be freed. +** This routine deletes the RtreeGeomCallback object that was attached +** one of the SQL functions create by sqlite3_rtree_geometry_callback() +** or sqlite3_rtree_query_callback(). In other words, this routine is the +** destructor for an RtreeGeomCallback objecct. This routine is called when +** the corresponding SQL function is deleted. */ static void rtreeFreeCallback(void *p){ RtreeGeomCallback *pGeom = (RtreeGeomCallback*)p; @@ -3368,10 +3376,16 @@ static void rtreeFreeCallback(void *p){ /* ** Each call to sqlite3_rtree_geometry_callback() or ** sqlite3_rtree_query_callback() creates an ordinary SQLite -** scalar user function that is implemented by this routine. +** scalar function that is implemented by this routine. ** -** This function returns a blob that is interpreted by r-tree -** table MATCH operator. +** All this function does is construct an RtreeMatchArg object that +** contains the geometry-checking callback routines and a list of +** parameters to this function, then return that RtreeMatchArg object +** as a BLOB. +** +** The R-Tree MATCH operator will read the returned BLOB, deserialize +** the RtreeMatchArg object, and use the RtreeMatchArg object to figure +** out which elements of the R-Tree should be returned by the query. */ static void geomCallback(sqlite3_context *ctx, int nArg, sqlite3_value **aArg){ RtreeGeomCallback *pGeomCtx = (RtreeGeomCallback *)sqlite3_user_data(ctx); @@ -3385,8 +3399,7 @@ static void geomCallback(sqlite3_context *ctx, int nArg, sqlite3_value **aArg){ }else{ int i; pBlob->magic = RTREE_GEOMETRY_MAGIC; - pBlob->xGeom = pGeomCtx->xGeom; - pBlob->pContext = pGeomCtx->pContext; + pBlob->cb = pGeomCtx[0]; pBlob->nParam = nArg; for(i=0; ixQueryFunc = 0; pGeomCtx->xDestructor = 0; pGeomCtx->pContext = pContext; - - /* Create the new user-function. Register a destructor function to delete - ** the context object when it is no longer required. */ return sqlite3_create_function_v2(db, zGeom, -1, SQLITE_ANY, (void *)pGeomCtx, geomCallback, 0, 0, rtreeFreeCallback ); @@ -3430,11 +3440,11 @@ int sqlite3_rtree_geometry_callback( ** r-tree MATCH operator. */ int sqlite3_rtree_query_callback( - sqlite3 *db, - const char *zQueryFunc, - int (*xQueryFunc)(sqlite3_rtree_query_info*), - void *pContext, - void (*xDestructor)(void*) + sqlite3 *db, /* Register SQL function on this connection */ + const char *zQueryFunc, /* Name of new SQL function */ + int (*xQueryFunc)(sqlite3_rtree_query_info*), /* Callback */ + void *pContext, /* Extra data passed into the callback */ + void (*xDestructor)(void*) /* Destructor for the extra data */ ){ RtreeGeomCallback *pGeomCtx; /* Context object for new user-function */ @@ -3445,9 +3455,6 @@ int sqlite3_rtree_query_callback( pGeomCtx->xQueryFunc = xQueryFunc; pGeomCtx->xDestructor = xDestructor; pGeomCtx->pContext = pContext; - - /* Create the new user-function. Register a destructor function to delete - ** the context object when it is no longer required. */ return sqlite3_create_function_v2(db, zQueryFunc, -1, SQLITE_ANY, (void *)pGeomCtx, geomCallback, 0, 0, rtreeFreeCallback ); diff --git a/manifest b/manifest index af46986305..0f929e7155 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\snew\sinterfaces\sto\srtree,\sthough\sthey\sdo\snot\syet\swork.\s\sAdd\sthe\n"show_speedtest1_rtree.tcl"\sscript\sfor\sshowing\sthe\stest\sdata\sused\sfor\sthe\nR-Tree\stests\sof\sspeedtest1.\s\sChange\sspeedtest1\sto\sgenerate\sbetter\sR-Tree\ntest\sdata. -D 2014-04-11T23:14:48.914 +C Continuing\sclean-up\sof\sthe\sR-Tree\smodule\sin\spreparation\sfor\scutting\sin\sthe\nnew\sgeneralized\squery\smechanism. +D 2014-04-12T17:44:00.241 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e4ee6d36cdf6136aee0158675a3b24dd3bf31a5a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -120,7 +120,7 @@ F ext/misc/vfslog.c fe40fab5c077a40477f7e5eba994309ecac6cc95 F ext/misc/vtshim.c babb0dc2bf116029e3e7c9a618b8a1377045303e F ext/misc/wholenumber.c 784b12543d60702ebdd47da936e278aa03076212 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 -F ext/rtree/rtree.c 541016f8a53bbedda4dc2deb0067f6955b0accb9 +F ext/rtree/rtree.c 8778f55ece9016ab3b17969f19f9656a06f6e100 F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e F ext/rtree/rtree1.test cf679265ecafff494a768ac9c2f43a70915a6290 F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba @@ -274,7 +274,7 @@ F src/test_osinst.c 90a845c8183013d80eccb1f29e8805608516edba F src/test_pcache.c a5cd24730cb43c5b18629043314548c9169abb00 F src/test_quota.c 30c64f0ef84734f2231a686df41ed882b0c59bc0 F src/test_quota.h 8761e463b25e75ebc078bd67d70e39b9c817a0cb -F src/test_rtree.c f3d1d12538dccb75fd916e3fa58f250edbdd3b47 +F src/test_rtree.c cd35d54c0b847c0c373d66f91616c49697ab4edf F src/test_schema.c cd12a2223c3a394f4d07bb93bdf6d344c5c121b6 F src/test_server.c a2615049954cbb9cfb4a62e18e2f0616e4dc38fe F src/test_sqllog.c c1c1bbedbcaf82b93d83e4f9dd990e62476a680e @@ -1175,7 +1175,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 9d485c4207a81f32334857d4a608c5c511dd2b83 -R 0017d933bc77106350e8e33449b1c08c +P 0b70275972c7a6a533566c1e50bffbf3ac531e95 +R 958d8acaf66c9f2ba2d270349d1218f7 U drh -Z 0d8113e9fad970081c8175cf29f2569d +Z 02617e452696d44ca40af16d5a687407 diff --git a/manifest.uuid b/manifest.uuid index 1c530a4dc8..866d285af2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0b70275972c7a6a533566c1e50bffbf3ac531e95 \ No newline at end of file +66c858f20586424e15d0bfa3d7b56643bde66226 \ No newline at end of file diff --git a/src/test_rtree.c b/src/test_rtree.c index e1966c2437..3b4c205879 100644 --- a/src/test_rtree.c +++ b/src/test_rtree.c @@ -50,11 +50,7 @@ static void circle_del(void *p){ static int circle_geom( sqlite3_rtree_geometry *p, int nCoord, -#ifdef SQLITE_RTREE_INT_ONLY - sqlite3_int64 *aCoord, -#else - double *aCoord, -#endif + sqlite3_rtree_dbl *aCoord, int *pRes ){ int i; /* Iterator variable */ @@ -154,6 +150,113 @@ static int circle_geom( return SQLITE_OK; } +/* +** Implementation of "circle" r-tree geometry callback using the +** 2nd-generation interface that allows scoring. +*/ +static int circle_query_func(sqlite3_rtree_query_info *p){ + int i; /* Iterator variable */ + Circle *pCircle; /* Structure defining circular region */ + double xmin, xmax; /* X dimensions of box being tested */ + double ymin, ymax; /* X dimensions of box being tested */ + int nWithin = 0; /* Number of corners inside the circle */ + + if( p->pUser==0 ){ + /* If pUser is still 0, then the parameter values have not been tested + ** for correctness or stored into a Circle structure yet. Do this now. */ + + /* This geometry callback is for use with a 2-dimensional r-tree table. + ** Return an error if the table does not have exactly 2 dimensions. */ + if( p->nCoord!=4 ) return SQLITE_ERROR; + + /* Test that the correct number of parameters (3) have been supplied, + ** and that the parameters are in range (that the radius of the circle + ** radius is greater than zero). */ + if( p->nParam!=3 || p->aParam[2]<0.0 ) return SQLITE_ERROR; + + /* Allocate a structure to cache parameter data in. Return SQLITE_NOMEM + ** if the allocation fails. */ + pCircle = (Circle *)(p->pUser = sqlite3_malloc(sizeof(Circle))); + if( !pCircle ) return SQLITE_NOMEM; + p->xDelUser = circle_del; + + /* Record the center and radius of the circular region. One way that + ** tested bounding boxes that intersect the circular region are detected + ** is by testing if each corner of the bounding box lies within radius + ** units of the center of the circle. */ + pCircle->centerx = p->aParam[0]; + pCircle->centery = p->aParam[1]; + pCircle->radius = p->aParam[2]; + + /* Define two bounding box regions. The first, aBox[0], extends to + ** infinity in the X dimension. It covers the same range of the Y dimension + ** as the circular region. The second, aBox[1], extends to infinity in + ** the Y dimension and is constrained to the range of the circle in the + ** X dimension. + ** + ** Then imagine each box is split in half along its short axis by a line + ** that intersects the center of the circular region. A bounding box + ** being tested can be said to intersect the circular region if it contains + ** points from each half of either of the two infinite bounding boxes. + */ + pCircle->aBox[0].xmin = pCircle->centerx; + pCircle->aBox[0].xmax = pCircle->centerx; + pCircle->aBox[0].ymin = pCircle->centery + pCircle->radius; + pCircle->aBox[0].ymax = pCircle->centery - pCircle->radius; + pCircle->aBox[1].xmin = pCircle->centerx + pCircle->radius; + pCircle->aBox[1].xmax = pCircle->centerx - pCircle->radius; + pCircle->aBox[1].ymin = pCircle->centery; + pCircle->aBox[1].ymax = pCircle->centery; + } + + pCircle = (Circle *)p->pUser; + xmin = p->aCoord[0]; + xmax = p->aCoord[1]; + ymin = p->aCoord[2]; + ymax = p->aCoord[3]; + + /* Check if any of the 4 corners of the bounding-box being tested lie + ** inside the circular region. If they do, then the bounding-box does + ** intersect the region of interest. Set the output variable to true and + ** return SQLITE_OK in this case. */ + for(i=0; i<4; i++){ + double x = (i&0x01) ? xmax : xmin; + double y = (i&0x02) ? ymax : ymin; + double d2; + + d2 = (x-pCircle->centerx)*(x-pCircle->centerx); + d2 += (y-pCircle->centery)*(y-pCircle->centery); + if( d2<(pCircle->radius*pCircle->radius) ) nWithin++; + } + + /* Check if the bounding box covers any other part of the circular region. + ** See comments above for a description of how this test works. If it does + ** cover part of the circular region, set the output variable to true + ** and return SQLITE_OK. */ + if( nWithin==0 ){ + for(i=0; i<2; i++){ + if( xmin<=pCircle->aBox[i].xmin + && xmax>=pCircle->aBox[i].xmax + && ymin<=pCircle->aBox[i].ymin + && ymax>=pCircle->aBox[i].ymax + ){ + nWithin = 1; + break; + } + } + } + + p->rScore = p->iLevel; + if( nWithin==0 ){ + p->eWithin = NOT_WITHIN; + }else if( nWithin>=4 ){ + p->eWithin = FULLY_WITHIN; + }else{ + p->eWithin = PARTLY_WITHIN; + } + return SQLITE_OK; +} + /* END of implementation of "circle" geometry callback. ************************************************************************** *************************************************************************/ @@ -194,11 +297,7 @@ static int gHere = 42; static int cube_geom( sqlite3_rtree_geometry *p, int nCoord, -#ifdef SQLITE_RTREE_INT_ONLY - sqlite3_int64 *aCoord, -#else - double *aCoord, -#endif + sqlite3_rtree_dbl *aCoord, int *piRes ){ Cube *pCube = (Cube *)p->pUser; @@ -293,6 +392,10 @@ static int register_circle_geom( } if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; rc = sqlite3_rtree_geometry_callback(db, "circle", circle_geom, 0); + if( rc==SQLITE_OK ){ + rc = sqlite3_rtree_query_callback(db, "Qcircle", + circle_query_func, 0, 0); + } Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_STATIC); #endif return TCL_OK; From 8ae04b53c9a6d8e221ae4ecbe7eabd0c032fdee7 Mon Sep 17 00:00:00 2001 From: drh Date: Sun, 13 Apr 2014 16:10:09 +0000 Subject: [PATCH 0090/1484] Continuing work on the new custom query mechanism for r-tree. FossilOrigin-Name: ca7357e66ca60f59477b1db000c2cdaeb8082ae1 --- ext/rtree/rtree.c | 49 +++++++++++++++++++++------------------- ext/rtree/sqlite3rtree.h | 4 ++++ manifest | 14 ++++++------ manifest.uuid | 2 +- 4 files changed, 38 insertions(+), 31 deletions(-) diff --git a/ext/rtree/rtree.c b/ext/rtree/rtree.c index e85fe4449d..aa57791cc5 100644 --- a/ext/rtree/rtree.c +++ b/ext/rtree/rtree.c @@ -272,9 +272,12 @@ union RtreeCoord { struct RtreeConstraint { int iCoord; /* Index of constrained coordinate */ int op; /* Constraining operation */ - RtreeDValue rValue; /* Constraint value. */ - int (*xGeom)(sqlite3_rtree_geometry*, int, RtreeDValue*, int*); - sqlite3_rtree_geometry *pGeom; /* Constraint callback argument for a MATCH */ + union { + RtreeDValue rValue; /* Constraint value. */ + int (*xGeom)(sqlite3_rtree_geometry*,int,RtreeDValue*,int*); + int (*xQueryFunc)(sqlite3_rtree_query_info*); + } u; + sqlite3_rtree_query_info *pGeom; /* xGeom and xQueryFunc argument */ }; /* Possible values for RtreeConstraint.op */ @@ -283,7 +286,8 @@ struct RtreeConstraint { #define RTREE_LT 0x43 #define RTREE_GE 0x44 #define RTREE_GT 0x45 -#define RTREE_MATCH 0x46 +#define RTREE_MATCH 0x46 /* Old-style sqlite3_rtree_geometry_callback() */ +#define RTREE_QUERY 0x47 /* New-style sqlite3_rtree_query_callback() */ /* ** An rtree structure node. @@ -860,7 +864,7 @@ static void freeCursorConstraints(RtreeCursor *pCsr){ if( pCsr->aConstraint ){ int i; /* Used to iterate through constraint array */ for(i=0; inConstraint; i++){ - sqlite3_rtree_geometry *pGeom = pCsr->aConstraint[i].pGeom; + sqlite3_rtree_query_info *pGeom = pCsr->aConstraint[i].pGeom; if( pGeom ){ if( pGeom->xDelUser ) pGeom->xDelUser(pGeom->pUser); sqlite3_free(pGeom); @@ -915,7 +919,8 @@ static int testRtreeGeom( for(i=0; iaCoord[i]); } - return pConstraint->xGeom(pConstraint->pGeom, nCoord, aCoord, pbRes); + return pConstraint->u.xGeom((sqlite3_rtree_geometry*)pConstraint->pGeom, + nCoord, aCoord, pbRes); } /* @@ -945,15 +950,15 @@ static int testRtreeCell(Rtree *pRtree, RtreeCursor *pCursor, int *pbEof){ switch( p->op ){ case RTREE_LE: case RTREE_LT: - bRes = p->rValueu.rValuerValue>cell_max; + bRes = p->u.rValue>cell_max; break; case RTREE_EQ: - bRes = (p->rValue>cell_max || p->rValueu.rValue>cell_max || p->u.rValueop==RTREE_GT || p->op==RTREE_EQ || p->op==RTREE_MATCH ); switch( p->op ){ - case RTREE_LE: res = (coord<=p->rValue); break; - case RTREE_LT: res = (coordrValue); break; - case RTREE_GE: res = (coord>=p->rValue); break; - case RTREE_GT: res = (coord>p->rValue); break; - case RTREE_EQ: res = (coord==p->rValue); break; + case RTREE_LE: res = (coord<=p->u.rValue); break; + case RTREE_LT: res = (coordu.rValue); break; + case RTREE_GE: res = (coord>=p->u.rValue); break; + case RTREE_GT: res = (coord>p->u.rValue); break; + case RTREE_EQ: res = (coord==p->u.rValue); break; default: { int rc; assert( p->op==RTREE_MATCH ); @@ -1230,7 +1235,7 @@ static int findLeafNode(Rtree *pRtree, i64 iRowid, RtreeNode **ppLeaf){ */ static int deserializeGeometry(sqlite3_value *pValue, RtreeConstraint *pCons){ RtreeMatchArg *p; - sqlite3_rtree_geometry *pGeom; + sqlite3_rtree_query_info *pGeom; int nBlob; /* Check that value is actually a blob. */ @@ -1244,12 +1249,10 @@ static int deserializeGeometry(sqlite3_value *pValue, RtreeConstraint *pCons){ return SQLITE_ERROR; } - pGeom = (sqlite3_rtree_geometry *)sqlite3_malloc( - sizeof(sqlite3_rtree_geometry) + nBlob - ); + pGeom = (sqlite3_rtree_query_info*)sqlite3_malloc( sizeof(*pGeom)+nBlob ); if( !pGeom ) return SQLITE_NOMEM; - memset(pGeom, 0, sizeof(sqlite3_rtree_geometry)); - p = (RtreeMatchArg *)&pGeom[1]; + memset(pGeom, 0, sizeof(*pGeom)); + p = (RtreeMatchArg*)&pGeom[1]; memcpy(p, sqlite3_value_blob(pValue), nBlob); if( p->magic!=RTREE_GEOMETRY_MAGIC @@ -1263,7 +1266,7 @@ static int deserializeGeometry(sqlite3_value *pValue, RtreeConstraint *pCons){ pGeom->nParam = p->nParam; pGeom->aParam = p->aParam; - pCons->xGeom = p->cb.xGeom; + pCons->u.xGeom = p->cb.xGeom; pCons->pGeom = pGeom; return SQLITE_OK; } @@ -1326,9 +1329,9 @@ static int rtreeFilter( } }else{ #ifdef SQLITE_RTREE_INT_ONLY - p->rValue = sqlite3_value_int64(argv[ii]); + p->u.rValue = sqlite3_value_int64(argv[ii]); #else - p->rValue = sqlite3_value_double(argv[ii]); + p->u.rValue = sqlite3_value_double(argv[ii]); #endif } } diff --git a/ext/rtree/sqlite3rtree.h b/ext/rtree/sqlite3rtree.h index 79d1ffeede..3f4df4ed89 100644 --- a/ext/rtree/sqlite3rtree.h +++ b/ext/rtree/sqlite3rtree.h @@ -77,6 +77,10 @@ int sqlite3_rtree_query_callback( ** A pointer to a structure of the following type is passed as the ** argument to scored geometry callback registered using ** sqlite3_rtree_query_callback(). +** +** Note that the first 5 fields of this structure are identical to +** sqlite3_rtree_geometry. This structure is a subclass of +** sqlite3_rtree_geometry. */ struct sqlite3_rtree_query_info { void *pContext; /* pContext from when function registered */ diff --git a/manifest b/manifest index 0f929e7155..29fa91b96a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Continuing\sclean-up\sof\sthe\sR-Tree\smodule\sin\spreparation\sfor\scutting\sin\sthe\nnew\sgeneralized\squery\smechanism. -D 2014-04-12T17:44:00.241 +C Continuing\swork\son\sthe\snew\scustom\squery\smechanism\sfor\sr-tree. +D 2014-04-13T16:10:09.443 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e4ee6d36cdf6136aee0158675a3b24dd3bf31a5a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -120,7 +120,7 @@ F ext/misc/vfslog.c fe40fab5c077a40477f7e5eba994309ecac6cc95 F ext/misc/vtshim.c babb0dc2bf116029e3e7c9a618b8a1377045303e F ext/misc/wholenumber.c 784b12543d60702ebdd47da936e278aa03076212 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 -F ext/rtree/rtree.c 8778f55ece9016ab3b17969f19f9656a06f6e100 +F ext/rtree/rtree.c 527490ab54b8f1bb88bece47037f0d947534cece F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e F ext/rtree/rtree1.test cf679265ecafff494a768ac9c2f43a70915a6290 F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba @@ -137,7 +137,7 @@ F ext/rtree/rtreeC.test 16d7aa86ecb6a876d2a38cf590a1471a41b3a46d F ext/rtree/rtreeD.test 636630357638f5983701550b37f0f5867130d2ca F ext/rtree/rtree_perf.tcl 6c18c1f23cd48e0f948930c98dfdd37dfccb5195 F ext/rtree/rtree_util.tcl 06aab2ed5b826545bf215fff90ecb9255a8647ea -F ext/rtree/sqlite3rtree.h f93a466456ed25a9dadf90ad050e2945a2c49cff +F ext/rtree/sqlite3rtree.h 488cf8834d2012b913d33683157d3cf5f1327a69 F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 F ext/session/session1.test 894e3bc9f497c4fa07a2aa3271e3911f3670c3d8 @@ -1175,7 +1175,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 0b70275972c7a6a533566c1e50bffbf3ac531e95 -R 958d8acaf66c9f2ba2d270349d1218f7 +P 66c858f20586424e15d0bfa3d7b56643bde66226 +R c2e5d1b590c0114514efc7f22a499336 U drh -Z 02617e452696d44ca40af16d5a687407 +Z 7b1f11ecd50995d28149a37777f2c7ae diff --git a/manifest.uuid b/manifest.uuid index 866d285af2..77fbfcc83e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -66c858f20586424e15d0bfa3d7b56643bde66226 \ No newline at end of file +ca7357e66ca60f59477b1db000c2cdaeb8082ae1 \ No newline at end of file From b6c3aeac904db2de7be1d4c366afa74c0e00c0c4 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 14 Apr 2014 12:18:17 +0000 Subject: [PATCH 0091/1484] Remove over 300 lines of unused code, code that implemented the older Guttman insertion algorithms that are no longer used. FossilOrigin-Name: 3ba5f295c709faebf5505e61f6dc5266b811b086 --- ext/rtree/rtree.c | 349 ++-------------------------------------------- manifest | 12 +- manifest.uuid | 2 +- 3 files changed, 22 insertions(+), 341 deletions(-) diff --git a/ext/rtree/rtree.c b/ext/rtree/rtree.c index aa57791cc5..5fff43529e 100644 --- a/ext/rtree/rtree.c +++ b/ext/rtree/rtree.c @@ -54,48 +54,6 @@ #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_RTREE) -/* -** This file contains an implementation of a couple of different variants -** of the r-tree algorithm. See the README file for further details. The -** same data-structure is used for all, but the algorithms for insert and -** delete operations vary. The variants used are selected at compile time -** by defining the following symbols: -*/ - -/* Either, both or none of the following may be set to activate -** r*tree variant algorithms. -*/ -#define VARIANT_RSTARTREE_CHOOSESUBTREE 0 -#define VARIANT_RSTARTREE_REINSERT 1 - -/* -** Exactly one of the following must be set to 1. -*/ -#define VARIANT_GUTTMAN_QUADRATIC_SPLIT 0 -#define VARIANT_GUTTMAN_LINEAR_SPLIT 0 -#define VARIANT_RSTARTREE_SPLIT 1 - -#define VARIANT_GUTTMAN_SPLIT \ - (VARIANT_GUTTMAN_LINEAR_SPLIT||VARIANT_GUTTMAN_QUADRATIC_SPLIT) - -#if VARIANT_GUTTMAN_QUADRATIC_SPLIT - #define PickNext QuadraticPickNext - #define PickSeeds QuadraticPickSeeds - #define AssignCells splitNodeGuttman -#endif -#if VARIANT_GUTTMAN_LINEAR_SPLIT - #define PickNext LinearPickNext - #define PickSeeds LinearPickSeeds - #define AssignCells splitNodeGuttman -#endif -#if VARIANT_RSTARTREE_SPLIT - #define AssignCells splitNodeStartree -#endif - -#if !defined(NDEBUG) && !defined(SQLITE_DEBUG) -# define NDEBUG 1 -#endif - #ifndef SQLITE_CORE #include "sqlite3ext.h" SQLITE_EXTENSION_INIT1 @@ -1556,62 +1514,32 @@ static RtreeDValue cellGrowth(Rtree *pRtree, RtreeCell *p, RtreeCell *pCell){ return (cellArea(pRtree, &cell)-area); } -#if VARIANT_RSTARTREE_CHOOSESUBTREE || VARIANT_RSTARTREE_SPLIT static RtreeDValue cellOverlap( Rtree *pRtree, RtreeCell *p, RtreeCell *aCell, - int nCell, - int iExclude + int nCell ){ int ii; RtreeDValue overlap = 0.0; for(ii=0; iinDim*2); jj+=2){ - RtreeDValue x1, x2; - - x1 = MAX(DCOORD(p->aCoord[jj]), DCOORD(aCell[ii].aCoord[jj])); - x2 = MIN(DCOORD(p->aCoord[jj+1]), DCOORD(aCell[ii].aCoord[jj+1])); - - if( x2nDim*2); jj+=2){ + RtreeDValue x1, x2; + x1 = MAX(DCOORD(p->aCoord[jj]), DCOORD(aCell[ii].aCoord[jj])); + x2 = MIN(DCOORD(p->aCoord[jj+1]), DCOORD(aCell[ii].aCoord[jj+1])); + if( x2iDepth-1) ){ - int jj; - aCell = sqlite3_malloc(sizeof(RtreeCell)*nCell); - if( !aCell ){ - rc = SQLITE_NOMEM; - nodeRelease(pRtree, pNode); - pNode = 0; - continue; - } - for(jj=0; jjiDepth-1) ){ - overlap = cellOverlapEnlargement(pRtree,&cell,pCell,aCell,nCell,iCell); - }else{ - overlap = 0.0; - } - if( (iCell==0) - || (overlapnDim; i++){ - RtreeDValue x1 = DCOORD(aCell[0].aCoord[i*2]); - RtreeDValue x2 = DCOORD(aCell[0].aCoord[i*2+1]); - RtreeDValue x3 = x1; - RtreeDValue x4 = x2; - int jj; - - int iCellLeft = 0; - int iCellRight = 0; - - for(jj=1; jjx4 ) x4 = right; - if( left>x3 ){ - x3 = left; - iCellRight = jj; - } - if( rightmaxNormalInnerWidth ){ - iLeftSeed = iCellLeft; - iRightSeed = iCellRight; - } - } - } - - *piLeftSeed = iLeftSeed; - *piRightSeed = iRightSeed; -} -#endif /* VARIANT_GUTTMAN_LINEAR_SPLIT */ - -#if VARIANT_GUTTMAN_QUADRATIC_SPLIT -/* -** Implementation of the quadratic variant of the PickNext() function from -** Guttman[84]. -*/ -static RtreeCell *QuadraticPickNext( - Rtree *pRtree, - RtreeCell *aCell, - int nCell, - RtreeCell *pLeftBox, - RtreeCell *pRightBox, - int *aiUsed -){ - #define FABS(a) ((a)<0.0?-1.0*(a):(a)) - - int iSelect = -1; - RtreeDValue fDiff; - int ii; - for(ii=0; iifDiff ){ - fDiff = diff; - iSelect = ii; - } - } - } - aiUsed[iSelect] = 1; - return &aCell[iSelect]; -} - -/* -** Implementation of the quadratic variant of the PickSeeds() function from -** Guttman[84]. -*/ -static void QuadraticPickSeeds( - Rtree *pRtree, - RtreeCell *aCell, - int nCell, - int *piLeftSeed, - int *piRightSeed -){ - int ii; - int jj; - - int iLeftSeed = 0; - int iRightSeed = 1; - RtreeDValue fWaste = 0.0; - - for(ii=0; iifWaste ){ - iLeftSeed = ii; - iRightSeed = jj; - fWaste = waste; - } - } - } - - *piLeftSeed = iLeftSeed; - *piRightSeed = iRightSeed; -} -#endif /* VARIANT_GUTTMAN_QUADRATIC_SPLIT */ /* ** Arguments aIdx, aDistance and aSpare all point to arrays of size @@ -2052,7 +1794,6 @@ static void SortByDimension( } } -#if VARIANT_RSTARTREE_SPLIT /* ** Implementation of the R*-tree variant of SplitNode from Beckman[1990]. */ @@ -2120,7 +1861,7 @@ static int splitNodeStartree( } margin += cellMargin(pRtree, &left); margin += cellMargin(pRtree, &right); - overlap = cellOverlap(pRtree, &left, &right, 1, -1); + overlap = cellOverlap(pRtree, &left, &right, 1); area = cellArea(pRtree, &left) + cellArea(pRtree, &right); if( (nLeft==RTREE_MINCELLS(pRtree)) || (overlap0; i--){ - RtreeCell *pNext; - pNext = PickNext(pRtree, aCell, nCell, pBboxLeft, pBboxRight, aiUsed); - RtreeDValue diff = - cellGrowth(pRtree, pBboxLeft, pNext) - - cellGrowth(pRtree, pBboxRight, pNext) - ; - if( (RTREE_MINCELLS(pRtree)-NCELL(pRight)==i) - || (diff>0.0 && (RTREE_MINCELLS(pRtree)-NCELL(pLeft)!=i)) - ){ - nodeInsertCell(pRtree, pRight, pNext); - cellUnion(pRtree, pBboxRight, pNext); - }else{ - nodeInsertCell(pRtree, pLeft, pNext); - cellUnion(pRtree, pBboxLeft, pNext); - } - } - - sqlite3_free(aiUsed); - return SQLITE_OK; -} -#endif static int updateMapping( Rtree *pRtree, @@ -2286,7 +1971,7 @@ static int SplitNode( memset(pLeft->zData, 0, pRtree->iNodeSize); memset(pRight->zData, 0, pRtree->iNodeSize); - rc = AssignCells(pRtree, aCell, nCell, pLeft, pRight, &leftbbox, &rightbbox); + rc = splitNodeStartree(pRtree, aCell, nCell, pLeft, pRight,&leftbbox,&rightbbox); if( rc!=SQLITE_OK ){ goto splitnode_out; } @@ -2635,16 +2320,12 @@ static int rtreeInsertCell( } } if( nodeInsertCell(pRtree, pNode, pCell) ){ -#if VARIANT_RSTARTREE_REINSERT if( iHeight<=pRtree->iReinsertHeight || pNode->iNode==1){ rc = SplitNode(pRtree, pNode, pCell, iHeight); }else{ pRtree->iReinsertHeight = iHeight; rc = Reinsert(pRtree, pNode, pCell, iHeight); } -#else - rc = SplitNode(pRtree, pNode, pCell, iHeight); -#endif }else{ rc = AdjustTree(pRtree, pNode, pCell); if( rc==SQLITE_OK ){ diff --git a/manifest b/manifest index 29fa91b96a..9126cb413e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Continuing\swork\son\sthe\snew\scustom\squery\smechanism\sfor\sr-tree. -D 2014-04-13T16:10:09.443 +C Remove\sover\s300\slines\sof\sunused\scode,\scode\sthat\simplemented\sthe\solder\s\nGuttman\sinsertion\salgorithms\sthat\sare\sno\slonger\sused. +D 2014-04-14T12:18:17.185 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e4ee6d36cdf6136aee0158675a3b24dd3bf31a5a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -120,7 +120,7 @@ F ext/misc/vfslog.c fe40fab5c077a40477f7e5eba994309ecac6cc95 F ext/misc/vtshim.c babb0dc2bf116029e3e7c9a618b8a1377045303e F ext/misc/wholenumber.c 784b12543d60702ebdd47da936e278aa03076212 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 -F ext/rtree/rtree.c 527490ab54b8f1bb88bece47037f0d947534cece +F ext/rtree/rtree.c d7fbe473260cc53463c372c9cf7303495a40fbc8 F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e F ext/rtree/rtree1.test cf679265ecafff494a768ac9c2f43a70915a6290 F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba @@ -1175,7 +1175,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 66c858f20586424e15d0bfa3d7b56643bde66226 -R c2e5d1b590c0114514efc7f22a499336 +P ca7357e66ca60f59477b1db000c2cdaeb8082ae1 +R cf842e59d29c59dde99b1f71fa55bf0f U drh -Z 7b1f11ecd50995d28149a37777f2c7ae +Z e4f991d8b5489d1278b0a7eb150a81ec diff --git a/manifest.uuid b/manifest.uuid index 77fbfcc83e..512a941529 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ca7357e66ca60f59477b1db000c2cdaeb8082ae1 \ No newline at end of file +3ba5f295c709faebf5505e61f6dc5266b811b086 \ No newline at end of file From de8c279b28defed9ca99483bdc22eb3959f63fd9 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 14 Apr 2014 14:43:09 +0000 Subject: [PATCH 0092/1484] Fix comments on the rtreenode() and rtreedepth() test function in the R-Tree module. FossilOrigin-Name: ade5b986e8baab9df7bdaf7ccfaee2d6ba55fa3c --- ext/rtree/rtree.c | 17 +++++++++++++---- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/ext/rtree/rtree.c b/ext/rtree/rtree.c index 5fff43529e..17375718e9 100644 --- a/ext/rtree/rtree.c +++ b/ext/rtree/rtree.c @@ -2946,10 +2946,10 @@ static int rtreeInit( ** Implementation of a scalar function that decodes r-tree nodes to ** human readable strings. This can be used for debugging and analysis. ** -** The scalar function takes two arguments, a blob of data containing -** an r-tree node, and the number of dimensions the r-tree indexes. -** For a two-dimensional r-tree structure called "rt", to deserialize -** all nodes, a statement like: +** The scalar function takes two arguments: (1) the number of dimensions +** to the rtree (between 1 and 5, inclusive) and (2) a blob of data containing +** an r-tree node. For a two-dimensional r-tree structure called "rt", to +** deserialize all nodes, a statement like: ** ** SELECT rtreenode(2, data) FROM rt_node; ** @@ -3003,6 +3003,15 @@ static void rtreenode(sqlite3_context *ctx, int nArg, sqlite3_value **apArg){ sqlite3_result_text(ctx, zText, -1, sqlite3_free); } +/* This routine implements an SQL function that returns the "depth" parameter +** from the front of a blob that is an r-tree node. For example: +** +** SELECT rtreedepth(data) FROM rt_node WHERE nodeno=1; +** +** The depth value is 0 for all nodes other than the root node, and the root +** node always has nodeno=1, so the example above is the primary use for this +** routine. This routine is intended for testing and analysis only. +*/ static void rtreedepth(sqlite3_context *ctx, int nArg, sqlite3_value **apArg){ UNUSED_PARAMETER(nArg); if( sqlite3_value_type(apArg[0])!=SQLITE_BLOB diff --git a/manifest b/manifest index 9126cb413e..89c7e30ee7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sover\s300\slines\sof\sunused\scode,\scode\sthat\simplemented\sthe\solder\s\nGuttman\sinsertion\salgorithms\sthat\sare\sno\slonger\sused. -D 2014-04-14T12:18:17.185 +C Fix\scomments\son\sthe\srtreenode()\sand\srtreedepth()\stest\sfunction\sin\sthe\sR-Tree\nmodule. +D 2014-04-14T14:43:09.474 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e4ee6d36cdf6136aee0158675a3b24dd3bf31a5a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -120,7 +120,7 @@ F ext/misc/vfslog.c fe40fab5c077a40477f7e5eba994309ecac6cc95 F ext/misc/vtshim.c babb0dc2bf116029e3e7c9a618b8a1377045303e F ext/misc/wholenumber.c 784b12543d60702ebdd47da936e278aa03076212 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 -F ext/rtree/rtree.c d7fbe473260cc53463c372c9cf7303495a40fbc8 +F ext/rtree/rtree.c 07630c252ce0ba63d2d0e6922847eff6eec64fbc F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e F ext/rtree/rtree1.test cf679265ecafff494a768ac9c2f43a70915a6290 F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba @@ -1175,7 +1175,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P ca7357e66ca60f59477b1db000c2cdaeb8082ae1 -R cf842e59d29c59dde99b1f71fa55bf0f +P 3ba5f295c709faebf5505e61f6dc5266b811b086 +R e7b36f9b46b38d0d4d4bc75aff5d0712 U drh -Z e4f991d8b5489d1278b0a7eb150a81ec +Z 1c3694849e99525baeaeac92e41be917 diff --git a/manifest.uuid b/manifest.uuid index 512a941529..0a6c215cd0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3ba5f295c709faebf5505e61f6dc5266b811b086 \ No newline at end of file +ade5b986e8baab9df7bdaf7ccfaee2d6ba55fa3c \ No newline at end of file From 96ce1b36aa7709d0aeffbf1c464bd0aad096afb9 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 15 Apr 2014 21:06:14 +0000 Subject: [PATCH 0093/1484] Initial attempt at getting R-Tree queries to work using a priority queue. This check-in compiles, but R-Trees do not work well. And there are debugging printf()s left in the code. This is an incremental check-in. FossilOrigin-Name: 53688a25c23c394278a357829793889970aa4157 --- ext/rtree/rtree.c | 547 +++++++++++++++++++++++++++++++--------------- manifest | 15 +- manifest.uuid | 2 +- 3 files changed, 381 insertions(+), 183 deletions(-) diff --git a/ext/rtree/rtree.c b/ext/rtree/rtree.c index 17375718e9..9f41da3534 100644 --- a/ext/rtree/rtree.c +++ b/ext/rtree/rtree.c @@ -63,6 +63,7 @@ #include #include +#include #ifndef SQLITE_AMALGAMATION #include "sqlite3rtree.h" @@ -86,6 +87,7 @@ typedef struct RtreeConstraint RtreeConstraint; typedef struct RtreeMatchArg RtreeMatchArg; typedef struct RtreeGeomCallback RtreeGeomCallback; typedef union RtreeCoord RtreeCoord; +typedef struct RtreeSearchPoint RtreeSearchPoint; /* The rtree may have between 1 and RTREE_MAX_DIMENSIONS dimensions. */ #define RTREE_MAX_DIMENSIONS 5 @@ -165,6 +167,23 @@ struct Rtree { typedef float RtreeValue; /* Low accuracy coordinate */ #endif +/* +** When doing a search of an r-tree, instances of the following structure +** record intermediate results from the tree walk. +** +** The id is always a node-id. For iLevel>=1 the id is the node-id of +** the node that the RtreeSearchPoint represents. When iLevel==0, however, +** the id is of the parent node and the cell that RtreeSearchPoint +** represents is the iCell-th entry in the parent node. +*/ +struct RtreeSearchPoint { + RtreeDValue rScore; /* The score for this node. Smallest goes first. */ + sqlite3_int64 id; /* Node ID */ + u8 iLevel; /* 0=entries. 1=leaf node. 2+ for higher */ + u8 eWithin; /* PARTLY_WITHIN or FULLY_WITHIN */ + u8 iCell; /* Cell index within the node */ +}; + /* ** The minimum number of cells allowed for a node is a third of the ** maximum. In Gutman's notation: @@ -187,18 +206,34 @@ struct Rtree { */ #define RTREE_MAX_DEPTH 40 + +/* +** Number of entries in the cursor RtreeNode cache. The first entry is +** used to cache the RtreeNode for RtreeCursor.sPoint. The remaining +** entries cache the RtreeNode for the first elements of the priority queue. +*/ +#define RTREE_CACHE_SZ 5 + /* ** An rtree cursor object. */ struct RtreeCursor { sqlite3_vtab_cursor base; /* Base class. Must be first */ - RtreeNode *pNode; /* Node cursor is currently pointing at */ - int iCell; /* Index of current cell in pNode */ + u8 atEOF; /* True if at end of search */ + u8 bPoint; /* True if sPoint is valid */ int iStrategy; /* Copy of idxNum search parameter */ int nConstraint; /* Number of entries in aConstraint */ RtreeConstraint *aConstraint; /* Search constraints. */ + int nPointAlloc; /* Number of slots allocated for aPoint[] */ + int nPoint; /* Number of slots used in aPoint[] */ + RtreeSearchPoint *aPoint; /* Priority queue for search points */ + RtreeSearchPoint sPoint; /* Cached next search point */ + RtreeNode *aNode[RTREE_CACHE_SZ]; /* Rtree node cache */ }; +/* Return the Rtree of a RtreeCursor */ +#define RTREE_OF_CURSOR(X) ((Rtree*)((X)->base.pVtab)) + /* ** A coordinate can be either a floating point number or a integer. All ** coordinates within a single R-Tree are always of the same time. @@ -247,6 +282,7 @@ struct RtreeConstraint { #define RTREE_MATCH 0x46 /* Old-style sqlite3_rtree_geometry_callback() */ #define RTREE_QUERY 0x47 /* New-style sqlite3_rtree_query_callback() */ + /* ** An rtree structure node. */ @@ -838,12 +874,13 @@ static void freeCursorConstraints(RtreeCursor *pCsr){ */ static int rtreeClose(sqlite3_vtab_cursor *cur){ Rtree *pRtree = (Rtree *)(cur->pVtab); - int rc; + int ii; RtreeCursor *pCsr = (RtreeCursor *)cur; freeCursorConstraints(pCsr); - rc = nodeRelease(pRtree, pCsr->pNode); + sqlite3_free(pCsr->aPoint); + for(ii=0; iiaNode[ii]); sqlite3_free(pCsr); - return rc; + return SQLITE_OK; } /* @@ -854,14 +891,14 @@ static int rtreeClose(sqlite3_vtab_cursor *cur){ */ static int rtreeEof(sqlite3_vtab_cursor *cur){ RtreeCursor *pCsr = (RtreeCursor *)cur; - return (pCsr->pNode==0); + return pCsr->atEOF; } /* ** The r-tree constraint passed as the second argument to this function is ** guaranteed to be a MATCH constraint. */ -static int testRtreeGeom( +static int rtreeTestGeom( Rtree *pRtree, /* R-Tree object */ RtreeConstraint *pConstraint, /* MATCH constraint to test */ RtreeCell *pCell, /* Cell to test */ @@ -883,24 +920,39 @@ static int testRtreeGeom( /* ** Cursor pCursor currently points to a cell in a non-leaf page. -** Set *pbEof to true if the sub-tree headed by the cell is filtered -** (excluded) by the constraints in the pCursor->aConstraint[] -** array, or false otherwise. +** Set *peWithin to NOT_WITHIN if the constraints in pCursor->aConstraint[] +** are guaranteed to never be satisfied by any subelement under the +** current cell. If some subelement of the cell might satisfy all +** constraints, then set *peWithin to PARTLY_WITHIN. If all subelements +** of the cell are guaranteed to fully satisfy all constraints, then +** set *peWithin to FULLY_WITHIN. +** +** In other words, set *peWithin to NOT_WITHIN, PARTLY_WITHIN, or +** FULLY_WITHIN if the cell is completely outside of the field-of-view, +** overlaps the field of view, or is completely contained within the +** field of view, respectively. +** +** It is not an error to set *peWithin to PARTLY_WITHIN when FULLY_WITHIN +** would be correct. Doing so is suboptimal, but will still give the +** correct answer. ** ** Return SQLITE_OK if successful or an SQLite error code if an error -** occurs within a geometry callback. +** occurs. Errors can only possible if there is a geometry callback. */ -static int testRtreeCell(Rtree *pRtree, RtreeCursor *pCursor, int *pbEof){ - RtreeCell cell; +static int rtreeTestCell( + RtreeCursor *pCursor, /* The cursor to check */ + RtreeCell *pCell, /* The cell to check */ + int *peWithin /* Set true if element is out-of-bounds */ +){ int ii; - int bRes = 0; + int bOutOfBounds = 0; int rc = SQLITE_OK; + Rtree *pRtree = RTREE_OF_CURSOR(pCursor); - nodeGetCell(pRtree, pCursor->pNode, pCursor->iCell, &cell); - for(ii=0; bRes==0 && iinConstraint; ii++){ + for(ii=0; bOutOfBounds==0 && iinConstraint; ii++){ RtreeConstraint *p = &pCursor->aConstraint[ii]; - RtreeDValue cell_min = DCOORD(cell.aCoord[(p->iCoord>>1)*2]); - RtreeDValue cell_max = DCOORD(cell.aCoord[(p->iCoord>>1)*2+1]); + RtreeDValue cell_min = DCOORD(pCell->aCoord[(p->iCoord>>1)*2]); + RtreeDValue cell_max = DCOORD(pCell->aCoord[(p->iCoord>>1)*2+1]); assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE || p->op==RTREE_GT || p->op==RTREE_EQ || p->op==RTREE_MATCH @@ -908,52 +960,61 @@ static int testRtreeCell(Rtree *pRtree, RtreeCursor *pCursor, int *pbEof){ switch( p->op ){ case RTREE_LE: case RTREE_LT: - bRes = p->u.rValueu.rValueu.rValue>cell_max; + bOutOfBounds = p->u.rValue>cell_max; break; case RTREE_EQ: - bRes = (p->u.rValue>cell_max || p->u.rValueu.rValue>cell_max || p->u.rValueop==RTREE_MATCH ); - rc = testRtreeGeom(pRtree, p, &cell, &bRes); - bRes = !bRes; + rc = rtreeTestGeom(pRtree, p, pCell, &bOutOfBounds); + bOutOfBounds = !bOutOfBounds; break; } } } - *pbEof = bRes; + *peWithin = bOutOfBounds ? NOT_WITHIN : PARTLY_WITHIN; return rc; } /* -** Test if the cell that cursor pCursor currently points to -** would be filtered (excluded) by the constraints in the -** pCursor->aConstraint[] array. If so, set *pbEof to true before -** returning. If the cell is not filtered (excluded) by the constraints, -** set pbEof to zero. +** pCursor points to a leaf r-tree entry which is a candidate for output. +** This routine sets *peWithin to one of NOT_WITHIN, PARTLY_WITHIN, or +** FULLY_WITHIN depending on whether or not the leaf entry is completely +** outside the region defined by pCursor->aConstraints[], or overlaps the +** region, or is completely within the region, respectively. +** +** This routine is more selective than rtreeTestCell(). rtreeTestCell() +** will return PARTLY_WITHIN or FULLY_WITHIN if the constraints are such +** that a subelement of the cell to be included in the result set. This +** routine is is only called for leaf r-tree entries and does not need +** to concern itself with subelements. Hence it only sets *peWithin to +** PARTLY_WITHIN or FULLY_WITHIN if the cell itself meets the requirements. ** ** Return SQLITE_OK if successful or an SQLite error code if an error ** occurs within a geometry callback. ** ** This function assumes that the cell is part of a leaf node. */ -static int testRtreeEntry(Rtree *pRtree, RtreeCursor *pCursor, int *pbEof){ - RtreeCell cell; +static int rtreeTestEntry( + RtreeCursor *pCursor, /* Cursor pointing to the leaf element */ + RtreeCell *pCell, /* The cell to check */ + int *peWithin /* OUT: NOT_WITHIN, PARTLY_WITHIN, or FULLY_WITHIN */ +){ + Rtree *pRtree = RTREE_OF_CURSOR(pCursor); int ii; - *pbEof = 0; + int res = 1; /* Innocent until proven guilty */ - nodeGetCell(pRtree, pCursor->pNode, pCursor->iCell, &cell); - for(ii=0; iinConstraint; ii++){ + for(ii=0; res && iinConstraint; ii++){ RtreeConstraint *p = &pCursor->aConstraint[ii]; - RtreeDValue coord = DCOORD(cell.aCoord[p->iCoord]); - int res; + RtreeDValue coord = DCOORD(pCell->aCoord[p->iCoord]); assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE || p->op==RTREE_GT || p->op==RTREE_EQ || p->op==RTREE_MATCH ); @@ -966,85 +1027,19 @@ static int testRtreeEntry(Rtree *pRtree, RtreeCursor *pCursor, int *pbEof){ default: { int rc; assert( p->op==RTREE_MATCH ); - rc = testRtreeGeom(pRtree, p, &cell, &res); + rc = rtreeTestGeom(pRtree, p, pCell, &res); if( rc!=SQLITE_OK ){ return rc; } break; } } - - if( !res ){ - *pbEof = 1; - return SQLITE_OK; - } } + *peWithin = res ? FULLY_WITHIN : NOT_WITHIN; return SQLITE_OK; } -/* -** Cursor pCursor currently points at a node that heads a sub-tree of -** height iHeight (if iHeight==0, then the node is a leaf). Descend -** to point to the left-most cell of the sub-tree that matches the -** configured constraints. -*/ -static int descendToCell( - Rtree *pRtree, - RtreeCursor *pCursor, - int iHeight, - int *pEof /* OUT: Set to true if cannot descend */ -){ - int isEof; - int rc; - int ii; - RtreeNode *pChild; - sqlite3_int64 iRowid; - - RtreeNode *pSavedNode = pCursor->pNode; - int iSavedCell = pCursor->iCell; - - assert( iHeight>=0 ); - - if( iHeight==0 ){ - rc = testRtreeEntry(pRtree, pCursor, &isEof); - }else{ - rc = testRtreeCell(pRtree, pCursor, &isEof); - } - if( rc!=SQLITE_OK || isEof || iHeight==0 ){ - goto descend_to_cell_out; - } - - iRowid = nodeGetRowid(pRtree, pCursor->pNode, pCursor->iCell); - rc = nodeAcquire(pRtree, iRowid, pCursor->pNode, &pChild); - if( rc!=SQLITE_OK ){ - goto descend_to_cell_out; - } - - nodeRelease(pRtree, pCursor->pNode); - pCursor->pNode = pChild; - isEof = 1; - for(ii=0; isEof && iiiCell = ii; - rc = descendToCell(pRtree, pCursor, iHeight-1, &isEof); - if( rc!=SQLITE_OK ){ - goto descend_to_cell_out; - } - } - - if( isEof ){ - assert( pCursor->pNode==pChild ); - nodeReference(pSavedNode); - nodeRelease(pRtree, pChild); - pCursor->pNode = pSavedNode; - pCursor->iCell = iSavedCell; - } - -descend_to_cell_out: - *pEof = isEof; - return rc; -} - /* ** One of the cells in node pNode is guaranteed to have a 64-bit ** integer value equal to iRowid. Return the index of this cell. @@ -1057,6 +1052,7 @@ static int nodeRowidIndex( ){ int ii; int nCell = NCELL(pNode); + assert( nCell<200 ); for(ii=0; iirScorerScore ) return -1; + if( pA->rScore>pB->rScore ) return +1; + if( pA->iLeveliLevel ) return -1; + if( pA->iLevel>pB->iLevel ) return +1; + return 0; +} + +/* +** Interchange to search points in a cursor. +*/ +static void rtreeSearchPointSwap(RtreeCursor *p, int i, int j){ + RtreeSearchPoint t = p->aPoint[i]; + assert( iaPoint[i] = p->aPoint[j]; + p->aPoint[j] = t; + if( i=RTREE_CACHE_SZ-1 ){ + nodeRelease(RTREE_OF_CURSOR(p), p->aNode[i+1]); + p->aNode[i+1] = 0; + }else{ + RtreeNode *pTemp = p->aNode[i+i]; + p->aNode[i+1] = p->aNode[j+1]; + p->aNode[j+1] = pTemp; + } + } +} + +/* +** Return the search point with the lowest current score. +*/ +static RtreeSearchPoint *rtreeSearchPointFirst(RtreeCursor *pCur){ + return pCur->bPoint ? &pCur->sPoint : pCur->nPoint ? pCur->aPoint : 0; +} + +/* +** Get the RtreeNode for the search point with the lowest score. +*/ +static RtreeNode *rtreeNodeOfFirstSearchPoint(RtreeCursor *pCur, int *pRC){ + sqlite3_int64 id; + int ii = 1 - pCur->bPoint; + assert( ii==0 || ii==1 ); + assert( pCur->bPoint || pCur->nPoint ); + if( pCur->aNode[ii]==0 ){ + assert( pRC!=0 ); + id = ii ? pCur->aPoint[0].id : pCur->sPoint.id; + *pRC = nodeAcquire(RTREE_OF_CURSOR(pCur), id, 0, &pCur->aNode[ii]); + } + return pCur->aNode[ii]; +} + +/* +** Push a new element onto the priority queue +*/ +static RtreeSearchPoint *rtreeEnqueue( + RtreeCursor *pCur, /* The cursor */ + RtreeDValue rScore, /* Score for the new search point */ + u8 iLevel /* Level for the new search point */ +){ + int i, j; + RtreeSearchPoint *pNew; + if( pCur->nPoint>=pCur->nPointAlloc ){ + int nNew = pCur->nPointAlloc*2 + 8; + pNew = sqlite3_realloc(pCur->aPoint, nNew*sizeof(pCur->aPoint[0])); + if( pNew==0 ) return 0; + pCur->aPoint = pNew; + pCur->nPointAlloc = nNew; + } + i = pCur->nPoint++; + pNew = pCur->aPoint + i; + pNew->rScore = rScore; + pNew->iLevel = iLevel; + while( i>0 ){ + RtreeSearchPoint *pParent; + j = (i-1)/2; + pParent = pCur->aPoint + j; + if( rtreeSearchPointCompare(pNew, pParent)>=0 ) break; + rtreeSearchPointSwap(pCur, j, i); + i = j; + pNew = pParent; + } + return pNew; +} + +/* +** Allocate a new RtreeSearchPoint and return a pointer to it. Return +** NULL if malloc fails. +*/ +static RtreeSearchPoint *rtreeSearchPointNew( + RtreeCursor *pCur, /* The cursor */ + RtreeDValue rScore, /* Score for the new search point */ + u8 iLevel /* Level for the new search point */ +){ + RtreeSearchPoint *pNew, *pFirst; + pFirst = rtreeSearchPointFirst(pCur); + if( pFirst==0 + || pFirst->rScore>rScore + || (pFirst->rScore==rScore && pFirst->iLevel>iLevel) + ){ + if( pCur->bPoint ){ + pNew = rtreeEnqueue(pCur, rScore, iLevel); + if( pNew==0 ) return 0; + assert( pCur->aNode[1]==0 ); + pCur->aNode[1] = pCur->aNode[0]; + pCur->aNode[0] = 0; + *pNew = pCur->sPoint; + } + pCur->sPoint.rScore = rScore; + pCur->sPoint.iLevel = iLevel; + pCur->bPoint = 1; + return &pCur->sPoint; + }else{ + return rtreeEnqueue(pCur, rScore, iLevel); + } +} + +static void traceTop(RtreeCursor *pCur, const char *zPrefix){ + RtreeSearchPoint *p = rtreeSearchPointFirst(pCur); + if( p ){ + printf("=== %6s id=%lld lvl=%d iCell=%d rScore=%g eWithin=%d\n", + zPrefix, p->id, p->iLevel, p->iCell, p->rScore, p->eWithin); + } +} + +/* Remove the search point with the lowest current score. +*/ +static void rtreeSearchPointPop(RtreeCursor *p){ + int i, j, k, n; + i = p->bPoint; + assert( i==0 || i==1 ); + if( p->aNode[i] ){ + nodeRelease(RTREE_OF_CURSOR(p), p->aNode[i]); + p->aNode[i] = 0; + } + if( p->bPoint ){ + p->bPoint = 0; + }else if( p->nPoint ){ + n = --p->nPoint; + p->aPoint[0] = p->aPoint[n]; + i = 0; + while( (j = i*2+1)aPoint[k], &p->aPoint[j])<0 ){ + if( rtreeSearchPointCompare(&p->aPoint[k], &p->aPoint[i])<0 ){ + rtreeSearchPointSwap(p, i, k); + i = k; + }else{ + break; + } + }else{ + if( rtreeSearchPointCompare(&p->aPoint[j], &p->aPoint[i])<0 ){ + rtreeSearchPointSwap(p, i, j); + i = j; + }else{ + break; + } + } + } + } +} + + +/* +** Continue the search on cursor pCur until the front of the queue +** contains an entry suitable for returning as a result-set row, +** or until the RtreeSearchPoint queue is empty, indicating that the +** query has completed. +*/ +static int rtreeStepToLeaf(RtreeCursor *pCur){ + RtreeSearchPoint *p; + RtreeSearchPoint *pNew; + Rtree *pRtree = RTREE_OF_CURSOR(pCur); + RtreeNode *pNode; + int eWithin; + int rc = SQLITE_OK; + int nCell; + RtreeCell cell; + RtreeSearchPoint x; + + while( (p = rtreeSearchPointFirst(pCur))!=0 && p->iLevel>0 ){ + pNode = rtreeNodeOfFirstSearchPoint(pCur, &rc); + if( rc ) return rc; + nCell = NCELL(pNode); + assert( nCell<200 ); + while( p->iCelliCell, &cell); + if( p->iLevel==1 ){ + rc = rtreeTestEntry(pCur, &cell, &eWithin); + }else{ + rc = rtreeTestCell(pCur, &cell, &eWithin); + } + if( rc ) return rc; + x = *p; + p->iCell++; + if( p->iCell>=nCell ){ +traceTop(pCur, "POP:"); + rtreeSearchPointPop(pCur); + } + if( eWithin==NOT_WITHIN ) continue; + pNew = rtreeSearchPointNew(pCur, /*rScore*/0.0, x.iLevel-1); + if( pNew==0 ) return SQLITE_NOMEM; + pNew->eWithin = eWithin; + if( pNew->iLevel ){ + pNew->id = cell.iRowid; + pNew->iCell = 0; + }else{ + pNew->id = x.id; + pNew->iCell = x.iCell; + } +traceTop(pCur, "PUSH:"); + break; + } + } + pCur->atEOF = p==0; + return SQLITE_OK; +} + /* ** Rtree virtual table module xNext method. */ static int rtreeNext(sqlite3_vtab_cursor *pVtabCursor){ - Rtree *pRtree = (Rtree *)(pVtabCursor->pVtab); RtreeCursor *pCsr = (RtreeCursor *)pVtabCursor; int rc = SQLITE_OK; - /* RtreeCursor.pNode must not be NULL. If is is NULL, then this cursor is - ** already at EOF. It is against the rules to call the xNext() method of - ** a cursor that has already reached EOF. - */ - assert( pCsr->pNode ); - - if( pCsr->iStrategy==1 ){ - /* This "scan" is a direct lookup by rowid. There is no next entry. */ - nodeRelease(pRtree, pCsr->pNode); - pCsr->pNode = 0; - }else{ - /* Move to the next entry that matches the configured constraints. */ - int iHeight = 0; - while( pCsr->pNode ){ - RtreeNode *pNode = pCsr->pNode; - int nCell = NCELL(pNode); - for(pCsr->iCell++; pCsr->iCelliCell++){ - int isEof; - rc = descendToCell(pRtree, pCsr, iHeight, &isEof); - if( rc!=SQLITE_OK || !isEof ){ - return rc; - } - } - pCsr->pNode = pNode->pParent; - rc = nodeParentIndex(pRtree, pNode, &pCsr->iCell); - if( rc!=SQLITE_OK ){ - return rc; - } - nodeReference(pCsr->pNode); - nodeRelease(pRtree, pNode); - iHeight++; - } - } - + /* Move to the next entry that matches the configured constraints. */ +traceTop(pCsr, "POP:"); + rtreeSearchPointPop(pCsr); + rtreeStepToLeaf(pCsr); return rc; } @@ -1128,13 +1317,14 @@ static int rtreeNext(sqlite3_vtab_cursor *pVtabCursor){ ** Rtree virtual table module xRowid method. */ static int rtreeRowid(sqlite3_vtab_cursor *pVtabCursor, sqlite_int64 *pRowid){ - Rtree *pRtree = (Rtree *)pVtabCursor->pVtab; RtreeCursor *pCsr = (RtreeCursor *)pVtabCursor; - - assert(pCsr->pNode); - *pRowid = nodeGetRowid(pRtree, pCsr->pNode, pCsr->iCell); - - return SQLITE_OK; + RtreeSearchPoint *p = rtreeSearchPointFirst(pCsr); + int rc = SQLITE_OK; + RtreeNode *pNode = rtreeNodeOfFirstSearchPoint(pCsr, &rc); + if( rc==SQLITE_OK && p ){ + *pRowid = nodeGetRowid(RTREE_OF_CURSOR(pCsr), pNode, p->iCell); + } + return rc; } /* @@ -1143,13 +1333,18 @@ static int rtreeRowid(sqlite3_vtab_cursor *pVtabCursor, sqlite_int64 *pRowid){ static int rtreeColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){ Rtree *pRtree = (Rtree *)cur->pVtab; RtreeCursor *pCsr = (RtreeCursor *)cur; + RtreeSearchPoint *p = rtreeSearchPointFirst(pCsr); + RtreeCoord c; + int rc = SQLITE_OK; + RtreeNode *pNode = rtreeNodeOfFirstSearchPoint(pCsr, &rc); + if( rc ) return rc; + if( p==0 ) return SQLITE_OK; if( i==0 ){ - i64 iRowid = nodeGetRowid(pRtree, pCsr->pNode, pCsr->iCell); - sqlite3_result_int64(ctx, iRowid); + sqlite3_result_int64(ctx, nodeGetRowid(pRtree, pNode, p->iCell)); }else{ - RtreeCoord c; - nodeGetCoord(pRtree, pCsr->pNode, pCsr->iCell, i-1, &c); + if( rc ) return rc; + nodeGetCoord(pRtree, pNode, p->iCell, i-1, &c); #ifndef SQLITE_RTREE_INT_ONLY if( pRtree->eCoordType==RTREE_COORD_REAL32 ){ sqlite3_result_double(ctx, c.f); @@ -1160,7 +1355,6 @@ static int rtreeColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){ sqlite3_result_int(ctx, c.i); } } - return SQLITE_OK; } @@ -1171,12 +1365,18 @@ static int rtreeColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){ ** *ppLeaf to 0 and return SQLITE_OK. If an error occurs, set *ppLeaf ** to zero and return an SQLite error code. */ -static int findLeafNode(Rtree *pRtree, i64 iRowid, RtreeNode **ppLeaf){ +static int findLeafNode( + Rtree *pRtree, /* RTree to search */ + i64 iRowid, /* The rowid searching for */ + RtreeNode **ppLeaf, /* Write the node here */ + sqlite3_int64 *piNode /* Write the node-id here */ +){ int rc; *ppLeaf = 0; sqlite3_bind_int64(pRtree->pReadRowid, 1, iRowid); if( sqlite3_step(pRtree->pReadRowid)==SQLITE_ROW ){ i64 iNode = sqlite3_column_int64(pRtree->pReadRowid, 0); + if( piNode ) *piNode = iNode; rc = nodeAcquire(pRtree, iNode, 0, ppLeaf); sqlite3_reset(pRtree->pReadRowid); }else{ @@ -1239,10 +1439,10 @@ static int rtreeFilter( ){ Rtree *pRtree = (Rtree *)pVtabCursor->pVtab; RtreeCursor *pCsr = (RtreeCursor *)pVtabCursor; - RtreeNode *pRoot = 0; int ii; int rc = SQLITE_OK; + int iCell = 0; rtreeReference(pRtree); @@ -1252,13 +1452,16 @@ static int rtreeFilter( if( idxNum==1 ){ /* Special case - lookup by rowid. */ RtreeNode *pLeaf; /* Leaf on which the required cell resides */ + RtreeSearchPoint *p; /* Search point for the the leaf */ i64 iRowid = sqlite3_value_int64(argv[0]); - rc = findLeafNode(pRtree, iRowid, &pLeaf); - pCsr->pNode = pLeaf; - if( pLeaf ){ - assert( rc==SQLITE_OK ); - rc = nodeRowidIndex(pRtree, pLeaf, iRowid, &pCsr->iCell); - } + p = rtreeSearchPointNew(pCsr, 0.0, 0); + if( p==0 ) return SQLITE_NOMEM; + rc = findLeafNode(pRtree, iRowid, &pLeaf, &p->id); + pCsr->aNode[0] = pLeaf; + p->eWithin = PARTLY_WITHIN; + if( rc ) rc = nodeRowidIndex(pRtree, pLeaf, iRowid, &iCell); + p->iCell = iCell; +traceTop(pCsr, "PUSH:"); }else{ /* Normal case - r-tree scan. Set up the RtreeCursor.aConstraint array ** with the configured constraints. @@ -1297,26 +1500,18 @@ static int rtreeFilter( } if( rc==SQLITE_OK ){ - pCsr->pNode = 0; rc = nodeAcquire(pRtree, 1, 0, &pRoot); } if( rc==SQLITE_OK ){ - int isEof = 1; - int nCell = NCELL(pRoot); - pCsr->pNode = pRoot; - for(pCsr->iCell=0; rc==SQLITE_OK && pCsr->iCelliCell++){ - assert( pCsr->pNode==pRoot ); - rc = descendToCell(pRtree, pCsr, pRtree->iDepth, &isEof); - if( !isEof ){ - break; - } - } - if( rc==SQLITE_OK && isEof ){ - assert( pCsr->pNode==pRoot ); - nodeRelease(pRtree, pRoot); - pCsr->pNode = 0; - } - assert( rc!=SQLITE_OK || !pCsr->pNode || pCsr->iCellpNode) ); + RtreeSearchPoint *pNew = rtreeSearchPointNew(pCsr, 0.0, pRtree->iDepth+1); + if( pNew==0 ) return SQLITE_NOMEM; + pNew->id = 1; + pNew->iCell = 0; + pNew->eWithin = PARTLY_WITHIN; + assert( pCsr->bPoint==1 ); + pCsr->aNode[0] = pRoot; +traceTop(pCsr, "PUSH:"); + rc = rtreeStepToLeaf(pCsr); } } @@ -2395,7 +2590,7 @@ static int rtreeDeleteRowid(Rtree *pRtree, sqlite3_int64 iDelete){ ** about to be deleted. */ if( rc==SQLITE_OK ){ - rc = findLeafNode(pRtree, iDelete, &pLeaf); + rc = findLeafNode(pRtree, iDelete, &pLeaf, 0); } /* Delete the cell in question from the leaf node. */ diff --git a/manifest b/manifest index 89c7e30ee7..7acb80fc79 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\scomments\son\sthe\srtreenode()\sand\srtreedepth()\stest\sfunction\sin\sthe\sR-Tree\nmodule. -D 2014-04-14T14:43:09.474 +C Initial\sattempt\sat\sgetting\sR-Tree\squeries\sto\swork\susing\sa\spriority\squeue.\nThis\scheck-in\scompiles,\sbut\sR-Trees\sdo\snot\swork\swell.\s\sAnd\sthere\sare\ndebugging\sprintf()s\sleft\sin\sthe\scode.\s\sThis\sis\san\sincremental\scheck-in. +D 2014-04-15T21:06:14.359 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e4ee6d36cdf6136aee0158675a3b24dd3bf31a5a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -120,7 +120,7 @@ F ext/misc/vfslog.c fe40fab5c077a40477f7e5eba994309ecac6cc95 F ext/misc/vtshim.c babb0dc2bf116029e3e7c9a618b8a1377045303e F ext/misc/wholenumber.c 784b12543d60702ebdd47da936e278aa03076212 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 -F ext/rtree/rtree.c 07630c252ce0ba63d2d0e6922847eff6eec64fbc +F ext/rtree/rtree.c 2f4d35a0689d588698cd0dd7d513761dff20c8fa F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e F ext/rtree/rtree1.test cf679265ecafff494a768ac9c2f43a70915a6290 F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba @@ -1175,7 +1175,10 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 3ba5f295c709faebf5505e61f6dc5266b811b086 -R e7b36f9b46b38d0d4d4bc75aff5d0712 +P ade5b986e8baab9df7bdaf7ccfaee2d6ba55fa3c +R 52e87385ec75daf64fa5f31a0250db29 +T *branch * rtree-queue +T *sym-rtree-queue * +T -sym-rtree-enhancements * U drh -Z 1c3694849e99525baeaeac92e41be917 +Z d0176a391caa75c92333b568fa6cbbbf diff --git a/manifest.uuid b/manifest.uuid index 0a6c215cd0..ddde4e0525 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ade5b986e8baab9df7bdaf7ccfaee2d6ba55fa3c \ No newline at end of file +53688a25c23c394278a357829793889970aa4157 \ No newline at end of file From f247982e37aa5b5f1d8b50ab96ba8f7238d2dab9 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 16 Apr 2014 13:00:08 +0000 Subject: [PATCH 0094/1484] Bug fixes to the priority-queue implementation for R-Trees. Improved tracing capability. Some queries work now, but still many problems. FossilOrigin-Name: a439ddd629c6bb5ea2e7e274673fee4f5c207acf --- ext/rtree/rtree.c | 79 ++++++++++++++++++++++++++++++++++------------- manifest | 15 ++++----- manifest.uuid | 2 +- 3 files changed, 65 insertions(+), 31 deletions(-) diff --git a/ext/rtree/rtree.c b/ext/rtree/rtree.c index 9f41da3534..3754655bb0 100644 --- a/ext/rtree/rtree.c +++ b/ext/rtree/rtree.c @@ -1098,14 +1098,15 @@ static void rtreeSearchPointSwap(RtreeCursor *p, int i, int j){ assert( iaPoint[i] = p->aPoint[j]; p->aPoint[j] = t; - if( i=RTREE_CACHE_SZ-1 ){ - nodeRelease(RTREE_OF_CURSOR(p), p->aNode[i+1]); - p->aNode[i+1] = 0; + i++; j++; + if( i=RTREE_CACHE_SZ ){ + nodeRelease(RTREE_OF_CURSOR(p), p->aNode[i]); + p->aNode[i] = 0; }else{ - RtreeNode *pTemp = p->aNode[i+i]; - p->aNode[i+1] = p->aNode[j+1]; - p->aNode[j+1] = pTemp; + RtreeNode *pTemp = p->aNode[i]; + p->aNode[i] = p->aNode[j]; + p->aNode[j] = pTemp; } } } @@ -1182,10 +1183,16 @@ static RtreeSearchPoint *rtreeSearchPointNew( || (pFirst->rScore==rScore && pFirst->iLevel>iLevel) ){ if( pCur->bPoint ){ + int ii; pNew = rtreeEnqueue(pCur, rScore, iLevel); if( pNew==0 ) return 0; - assert( pCur->aNode[1]==0 ); - pCur->aNode[1] = pCur->aNode[0]; + ii = (int)(pNew - pCur->aPoint) + 1; + if( iiaNode[ii]==0 ); + pCur->aNode[ii] = pCur->aNode[0]; + }else{ + nodeRelease(RTREE_OF_CURSOR(pCur), pCur->aNode[0]); + } pCur->aNode[0] = 0; *pNew = pCur->sPoint; } @@ -1198,13 +1205,34 @@ static RtreeSearchPoint *rtreeSearchPointNew( } } -static void traceTop(RtreeCursor *pCur, const char *zPrefix){ - RtreeSearchPoint *p = rtreeSearchPointFirst(pCur); - if( p ){ - printf("=== %6s id=%lld lvl=%d iCell=%d rScore=%g eWithin=%d\n", - zPrefix, p->id, p->iLevel, p->iCell, p->rScore, p->eWithin); +#if 0 +/* Tracing routines for the RtreeSearchPoint queue */ +static void tracePoint(RtreeSearchPoint *p, int idx, RtreeCursor *pCur){ + if( idx<0 ){ printf(" s"); }else{ printf("%2d", idx); } + printf(" %d.%05lld.%02d %g %d", + p->iLevel, p->id, p->iCell, p->rScore, p->eWithin + ); + idx++; + if( idxaNode[idx]); + }else{ + printf("\n"); } } +static void traceQueue(RtreeCursor *pCur, const char *zPrefix){ + int ii; + printf("=== %9s ", zPrefix); + if( pCur->bPoint ){ + tracePoint(&pCur->sPoint, -1, pCur); + } + for(ii=0; iinPoint; ii++){ + if( ii>0 || pCur->bPoint ) printf(" "); + tracePoint(&pCur->aPoint[ii], ii, pCur); + } +} +#else +# define RTREE_QUEUE_TRACE(A,B) /* no-op */ +#endif /* Remove the search point with the lowest current score. */ @@ -1221,6 +1249,10 @@ static void rtreeSearchPointPop(RtreeCursor *p){ }else if( p->nPoint ){ n = --p->nPoint; p->aPoint[0] = p->aPoint[n]; + if( naNode[1] = p->aNode[n+1]; + p->aNode[n+1] = 0; + } i = 0; while( (j = i*2+1)iCell++; + if( eWithin==NOT_WITHIN ) continue; if( p->iCell>=nCell ){ -traceTop(pCur, "POP:"); + RTREE_QUEUE_TRACE(pCur, "POP-S:"); rtreeSearchPointPop(pCur); } - if( eWithin==NOT_WITHIN ) continue; pNew = rtreeSearchPointNew(pCur, /*rScore*/0.0, x.iLevel-1); if( pNew==0 ) return SQLITE_NOMEM; pNew->eWithin = eWithin; @@ -1291,9 +1323,14 @@ traceTop(pCur, "POP:"); pNew->id = x.id; pNew->iCell = x.iCell; } -traceTop(pCur, "PUSH:"); + p = pNew; + RTREE_QUEUE_TRACE(pCur, "PUSH-S:"); break; } + if( p->iCell>=nCell ){ + RTREE_QUEUE_TRACE(pCur, "POP-Se:"); + rtreeSearchPointPop(pCur); + } } pCur->atEOF = p==0; return SQLITE_OK; @@ -1307,7 +1344,7 @@ static int rtreeNext(sqlite3_vtab_cursor *pVtabCursor){ int rc = SQLITE_OK; /* Move to the next entry that matches the configured constraints. */ -traceTop(pCsr, "POP:"); + RTREE_QUEUE_TRACE(pCsr, "POP-Nx:"); rtreeSearchPointPop(pCsr); rtreeStepToLeaf(pCsr); return rc; @@ -1461,7 +1498,7 @@ static int rtreeFilter( p->eWithin = PARTLY_WITHIN; if( rc ) rc = nodeRowidIndex(pRtree, pLeaf, iRowid, &iCell); p->iCell = iCell; -traceTop(pCsr, "PUSH:"); + RTREE_QUEUE_TRACE(pCsr, "PUSH-F1:"); }else{ /* Normal case - r-tree scan. Set up the RtreeCursor.aConstraint array ** with the configured constraints. @@ -1510,7 +1547,7 @@ traceTop(pCsr, "PUSH:"); pNew->eWithin = PARTLY_WITHIN; assert( pCsr->bPoint==1 ); pCsr->aNode[0] = pRoot; -traceTop(pCsr, "PUSH:"); + RTREE_QUEUE_TRACE(pCsr, "PUSH-Fm:"); rc = rtreeStepToLeaf(pCsr); } } @@ -3177,7 +3214,7 @@ static void rtreenode(sqlite3_context *ctx, int nArg, sqlite3_value **apArg){ nCell = (int)strlen(zCell); for(jj=0; jj Date: Wed, 16 Apr 2014 14:45:11 +0000 Subject: [PATCH 0095/1484] =?UTF-8?q?Fix=20a=20bug=20in=20rowid=3D=3F=20qu?= =?UTF-8?q?ery=20handling.=20=20More=20problems=20remain.?= FossilOrigin-Name: 5b0e6ba4a5050cf81cf41b977b28d714163569e0 --- ext/rtree/rtree.c | 23 ++++++++++++----------- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 19 insertions(+), 18 deletions(-) diff --git a/ext/rtree/rtree.c b/ext/rtree/rtree.c index 3754655bb0..26082ff511 100644 --- a/ext/rtree/rtree.c +++ b/ext/rtree/rtree.c @@ -1230,6 +1230,7 @@ static void traceQueue(RtreeCursor *pCur, const char *zPrefix){ tracePoint(&pCur->aPoint[ii], ii, pCur); } } +# define RTREE_QUEUE_TRACE(A,B) traceQueue(A,B) #else # define RTREE_QUEUE_TRACE(A,B) /* no-op */ #endif @@ -1284,7 +1285,6 @@ static void rtreeSearchPointPop(RtreeCursor *p){ */ static int rtreeStepToLeaf(RtreeCursor *pCur){ RtreeSearchPoint *p; - RtreeSearchPoint *pNew; Rtree *pRtree = RTREE_OF_CURSOR(pCur); RtreeNode *pNode; int eWithin; @@ -1313,17 +1313,16 @@ static int rtreeStepToLeaf(RtreeCursor *pCur){ RTREE_QUEUE_TRACE(pCur, "POP-S:"); rtreeSearchPointPop(pCur); } - pNew = rtreeSearchPointNew(pCur, /*rScore*/0.0, x.iLevel-1); - if( pNew==0 ) return SQLITE_NOMEM; - pNew->eWithin = eWithin; - if( pNew->iLevel ){ - pNew->id = cell.iRowid; - pNew->iCell = 0; + p = rtreeSearchPointNew(pCur, /*rScore*/0.0, x.iLevel-1); + if( p==0 ) return SQLITE_NOMEM; + p->eWithin = eWithin; + if( p->iLevel ){ + p->id = cell.iRowid; + p->iCell = 0; }else{ - pNew->id = x.id; - pNew->iCell = x.iCell; + p->id = x.id; + p->iCell = x.iCell; } - p = pNew; RTREE_QUEUE_TRACE(pCur, "PUSH-S:"); break; } @@ -1496,7 +1495,9 @@ static int rtreeFilter( rc = findLeafNode(pRtree, iRowid, &pLeaf, &p->id); pCsr->aNode[0] = pLeaf; p->eWithin = PARTLY_WITHIN; - if( rc ) rc = nodeRowidIndex(pRtree, pLeaf, iRowid, &iCell); + if( rc==SQLITE_OK ){ + rc = nodeRowidIndex(pRtree, pLeaf, iRowid, &iCell); + } p->iCell = iCell; RTREE_QUEUE_TRACE(pCsr, "PUSH-F1:"); }else{ diff --git a/manifest b/manifest index 83f2beda77..df0b85687e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Bug\sfixes\sto\sthe\spriority-queue\simplementation\sfor\sR-Trees.\s\sImproved\stracing\ncapability.\s\sSome\squeries\swork\snow,\sbut\sstill\smany\sproblems. -D 2014-04-16T13:00:08.915 +C Fix\sa\sbug\sin\srowid=?\squery\shandling.\s\sMore\sproblems\sremain. +D 2014-04-16T14:45:11.945 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e4ee6d36cdf6136aee0158675a3b24dd3bf31a5a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -120,7 +120,7 @@ F ext/misc/vfslog.c fe40fab5c077a40477f7e5eba994309ecac6cc95 F ext/misc/vtshim.c babb0dc2bf116029e3e7c9a618b8a1377045303e F ext/misc/wholenumber.c 784b12543d60702ebdd47da936e278aa03076212 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 -F ext/rtree/rtree.c 3105c5514d6dbf99c39aceac84c4c0f9e00f90ea +F ext/rtree/rtree.c 4702eae330e9803ac51208ec0e26c5aceb0cd20b F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e F ext/rtree/rtree1.test cf679265ecafff494a768ac9c2f43a70915a6290 F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba @@ -1175,7 +1175,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 53688a25c23c394278a357829793889970aa4157 -R 67a30187386908beb1eb82f50c3b2dfd +P a439ddd629c6bb5ea2e7e274673fee4f5c207acf +R 759346bdeaafb6dce8a9cda8463bc2de U drh -Z ba82d149b9f56c655f1e6f2a959cfc71 +Z 100295249b6d7d7223775c8a6bd7cd19 diff --git a/manifest.uuid b/manifest.uuid index b2db9c77b5..8106164958 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a439ddd629c6bb5ea2e7e274673fee4f5c207acf \ No newline at end of file +5b0e6ba4a5050cf81cf41b977b28d714163569e0 \ No newline at end of file From 933a5ff2d4389b5a9007f7b43b1084d16950aad5 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 16 Apr 2014 17:15:14 +0000 Subject: [PATCH 0096/1484] TCL tests now all pass. FossilOrigin-Name: f864baccd3fe0ee939ac1ec20069792f649cddc0 --- ext/rtree/rtree.c | 24 ++++++++++++++---------- ext/rtree/rtreeB.test | 2 +- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 23 insertions(+), 19 deletions(-) diff --git a/ext/rtree/rtree.c b/ext/rtree/rtree.c index 26082ff511..9c62576612 100644 --- a/ext/rtree/rtree.c +++ b/ext/rtree/rtree.c @@ -1239,7 +1239,7 @@ static void traceQueue(RtreeCursor *pCur, const char *zPrefix){ */ static void rtreeSearchPointPop(RtreeCursor *p){ int i, j, k, n; - i = p->bPoint; + i = 1 - p->bPoint; assert( i==0 || i==1 ); if( p->aNode[i] ){ nodeRelease(RTREE_OF_CURSOR(p), p->aNode[i]); @@ -1345,7 +1345,7 @@ static int rtreeNext(sqlite3_vtab_cursor *pVtabCursor){ /* Move to the next entry that matches the configured constraints. */ RTREE_QUEUE_TRACE(pCsr, "POP-Nx:"); rtreeSearchPointPop(pCsr); - rtreeStepToLeaf(pCsr); + rc = rtreeStepToLeaf(pCsr); return rc; } @@ -1490,16 +1490,20 @@ static int rtreeFilter( RtreeNode *pLeaf; /* Leaf on which the required cell resides */ RtreeSearchPoint *p; /* Search point for the the leaf */ i64 iRowid = sqlite3_value_int64(argv[0]); - p = rtreeSearchPointNew(pCsr, 0.0, 0); - if( p==0 ) return SQLITE_NOMEM; - rc = findLeafNode(pRtree, iRowid, &pLeaf, &p->id); - pCsr->aNode[0] = pLeaf; - p->eWithin = PARTLY_WITHIN; - if( rc==SQLITE_OK ){ + i64 iNode = 0; + rc = findLeafNode(pRtree, iRowid, &pLeaf, &iNode); + if( rc==SQLITE_OK && pLeaf!=0 ){ + p = rtreeSearchPointNew(pCsr, 0.0, 0); + assert( p!=0 ); /* Always returns pCsr->sPoint */ + pCsr->aNode[0] = pLeaf; + p->id = iNode; + p->eWithin = PARTLY_WITHIN; rc = nodeRowidIndex(pRtree, pLeaf, iRowid, &iCell); + p->iCell = iCell; + RTREE_QUEUE_TRACE(pCsr, "PUSH-F1:"); + }else{ + pCsr->atEOF = 1; } - p->iCell = iCell; - RTREE_QUEUE_TRACE(pCsr, "PUSH-F1:"); }else{ /* Normal case - r-tree scan. Set up the RtreeCursor.aConstraint array ** with the configured constraints. diff --git a/ext/rtree/rtreeB.test b/ext/rtree/rtreeB.test index 7cb445cc4f..aeb308eca7 100644 --- a/ext/rtree/rtreeB.test +++ b/ext/rtree/rtreeB.test @@ -41,7 +41,7 @@ ifcapable rtree_int_only { INSERT INTO t1 VALUES(9223372036854775807, 150, 150, 400, 400); SELECT rtreenode(2, data) FROM t1_node; } - } {{{1073741824 0.000000 0.000000 100.000000 100.000000} {2147483646 0.000000 0.000000 200.000000 200.000000} {4294967296 0.000000 0.000000 300.000000 300.000000} {8589934592 20.000000 20.000000 150.000000 150.000000} {9223372036854775807 150.000000 150.000000 400.000000 400.000000}}} + } {{{1073741824 0 0 100 100} {2147483646 0 0 200 200} {4294967296 0 0 300 300} {8589934592 20 20 150 150} {9223372036854775807 150 150 400 400}}} } finish_test diff --git a/manifest b/manifest index df0b85687e..1061ef3307 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sbug\sin\srowid=?\squery\shandling.\s\sMore\sproblems\sremain. -D 2014-04-16T14:45:11.945 +C TCL\stests\snow\sall\spass. +D 2014-04-16T17:15:14.114 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e4ee6d36cdf6136aee0158675a3b24dd3bf31a5a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -120,7 +120,7 @@ F ext/misc/vfslog.c fe40fab5c077a40477f7e5eba994309ecac6cc95 F ext/misc/vtshim.c babb0dc2bf116029e3e7c9a618b8a1377045303e F ext/misc/wholenumber.c 784b12543d60702ebdd47da936e278aa03076212 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 -F ext/rtree/rtree.c 4702eae330e9803ac51208ec0e26c5aceb0cd20b +F ext/rtree/rtree.c 142d70dc3bb8db1caf6c0e94b88ec0e8047d36ee F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e F ext/rtree/rtree1.test cf679265ecafff494a768ac9c2f43a70915a6290 F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba @@ -132,7 +132,7 @@ F ext/rtree/rtree7.test 1fa710b9e6bf997a0c1a537b81be7bb6fded1971 F ext/rtree/rtree8.test db79c812f9e4a11f9b1f3f9934007884610a713a F ext/rtree/rtree9.test d86ebf08ff6328895613ed577dd8a2a37c472c34 F ext/rtree/rtreeA.test ace05e729a36e342d40cf94e9efc7b4723d9dcdf -F ext/rtree/rtreeB.test 983e567b49b5dca165940f66b87e161aa30e82b2 +F ext/rtree/rtreeB.test c85f9ce78766c4e68b8b89fbf2979ee9cfa82b4e F ext/rtree/rtreeC.test 16d7aa86ecb6a876d2a38cf590a1471a41b3a46d F ext/rtree/rtreeD.test 636630357638f5983701550b37f0f5867130d2ca F ext/rtree/rtree_perf.tcl 6c18c1f23cd48e0f948930c98dfdd37dfccb5195 @@ -1175,7 +1175,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P a439ddd629c6bb5ea2e7e274673fee4f5c207acf -R 759346bdeaafb6dce8a9cda8463bc2de +P 5b0e6ba4a5050cf81cf41b977b28d714163569e0 +R f6b681e4a8814b2c282cb2ca3c357703 U drh -Z 100295249b6d7d7223775c8a6bd7cd19 +Z 3d7f5774712bc082940f713cae866e31 diff --git a/manifest.uuid b/manifest.uuid index 8106164958..cd8f7f474f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5b0e6ba4a5050cf81cf41b977b28d714163569e0 \ No newline at end of file +f864baccd3fe0ee939ac1ec20069792f649cddc0 \ No newline at end of file From 18b5142b29d7fe828f17dd816c55b9fb5925ea85 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 16 Apr 2014 21:02:28 +0000 Subject: [PATCH 0097/1484] Performance optimization on nodeGetCell() in R-Tree. FossilOrigin-Name: 5d20ff9ec837ad35bc44d6c25d13764b350e81dd --- ext/rtree/rtree.c | 11 ++++++++--- manifest | 13 ++++++------- manifest.uuid | 2 +- 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/ext/rtree/rtree.c b/ext/rtree/rtree.c index 9c62576612..6bf1db11c4 100644 --- a/ext/rtree/rtree.c +++ b/ext/rtree/rtree.c @@ -729,10 +729,15 @@ static void nodeGetCell( int iCell, /* Index of the cell within the node */ RtreeCell *pCell /* OUT: Write the cell contents here */ ){ - int ii; + u8 *pData; + u8 *pEnd; + RtreeCoord *pCoord; pCell->iRowid = nodeGetRowid(pRtree, pNode, iCell); - for(ii=0; iinDim*2; ii++){ - nodeGetCoord(pRtree, pNode, iCell, ii, &pCell->aCoord[ii]); + pData = pNode->zData + (12 + pRtree->nBytesPerCell*iCell); + pEnd = pData + pRtree->nDim*8; + pCoord = pCell->aCoord; + for(; pData Date: Thu, 17 Apr 2014 13:15:33 +0000 Subject: [PATCH 0098/1484] Refactor the constraint checking logic in RTree. The new-style constraint callbacks created by sqlite3_rtree_query_callback() are now hooked up from end to end, though still untested. FossilOrigin-Name: 32a13870175a1dd1d33af3572dde09ff607a04b6 --- ext/rtree/rtree.c | 300 +++++++++++++++++++++--------------------- ext/rtree/rtree6.test | 18 +-- ext/rtree/rtreeC.test | 13 +- manifest | 16 +-- manifest.uuid | 2 +- 5 files changed, 172 insertions(+), 177 deletions(-) diff --git a/ext/rtree/rtree.c b/ext/rtree/rtree.c index 6bf1db11c4..3c9a8daba9 100644 --- a/ext/rtree/rtree.c +++ b/ext/rtree/rtree.c @@ -274,13 +274,13 @@ struct RtreeConstraint { }; /* Possible values for RtreeConstraint.op */ -#define RTREE_EQ 0x41 -#define RTREE_LE 0x42 -#define RTREE_LT 0x43 -#define RTREE_GE 0x44 -#define RTREE_GT 0x45 -#define RTREE_MATCH 0x46 /* Old-style sqlite3_rtree_geometry_callback() */ -#define RTREE_QUERY 0x47 /* New-style sqlite3_rtree_query_callback() */ +#define RTREE_EQ 0x41 /* A */ +#define RTREE_LE 0x42 /* B */ +#define RTREE_LT 0x43 /* C */ +#define RTREE_GE 0x44 /* D */ +#define RTREE_GT 0x45 /* E */ +#define RTREE_MATCH 0x46 /* F: Old-style sqlite3_rtree_geometry_callback() */ +#define RTREE_QUERY 0x47 /* G: New-style sqlite3_rtree_query_callback() */ /* @@ -900,149 +900,131 @@ static int rtreeEof(sqlite3_vtab_cursor *cur){ } /* -** The r-tree constraint passed as the second argument to this function is -** guaranteed to be a MATCH constraint. +** Convert raw bits from the on-disk RTree record into a coordinate value +** The on-disk record stores integer coordinates if eInt is true and it +** stores 32-bit floating point records if eInt is false. a[] is the four +** bytes of the on-disk record to be decoded. Store the results in "r". */ -static int rtreeTestGeom( - Rtree *pRtree, /* R-Tree object */ - RtreeConstraint *pConstraint, /* MATCH constraint to test */ - RtreeCell *pCell, /* Cell to test */ - int *pbRes /* OUT: Test result */ -){ - int i; - RtreeDValue aCoord[RTREE_MAX_DIMENSIONS*2]; - int nCoord = pRtree->nDim*2; - - assert( pConstraint->op==RTREE_MATCH ); - assert( pConstraint->pGeom ); - - for(i=0; iaCoord[i]); - } - return pConstraint->u.xGeom((sqlite3_rtree_geometry*)pConstraint->pGeom, - nCoord, aCoord, pbRes); +#define RTREE_DECODE_COORD(eInt, a, r) { \ + u32 x; /* Raw bits of the coordinate value */ \ + RtreeCoord c; /* Coordinate decoded */ \ + x = ((u32)a[0]<<24) + ((u32)a[1]<<16) \ + +((u32)a[2]<<8) + a[3]; \ + c.i = *(int*)&x; \ + r = eInt ? (sqlite3_rtree_dbl)c.i : (sqlite3_rtree_dbl)c.f; \ } + -/* -** Cursor pCursor currently points to a cell in a non-leaf page. -** Set *peWithin to NOT_WITHIN if the constraints in pCursor->aConstraint[] -** are guaranteed to never be satisfied by any subelement under the -** current cell. If some subelement of the cell might satisfy all -** constraints, then set *peWithin to PARTLY_WITHIN. If all subelements -** of the cell are guaranteed to fully satisfy all constraints, then -** set *peWithin to FULLY_WITHIN. -** -** In other words, set *peWithin to NOT_WITHIN, PARTLY_WITHIN, or -** FULLY_WITHIN if the cell is completely outside of the field-of-view, -** overlaps the field of view, or is completely contained within the -** field of view, respectively. -** -** It is not an error to set *peWithin to PARTLY_WITHIN when FULLY_WITHIN -** would be correct. Doing so is suboptimal, but will still give the -** correct answer. -** -** Return SQLITE_OK if successful or an SQLite error code if an error -** occurs. Errors can only possible if there is a geometry callback. +/* +** Check the RTree node or entry given by pCellData and p against the MATCH +** constraint pConstraint. */ -static int rtreeTestCell( - RtreeCursor *pCursor, /* The cursor to check */ - RtreeCell *pCell, /* The cell to check */ - int *peWithin /* Set true if element is out-of-bounds */ +static int rtreeCallbackConstraint( + RtreeConstraint *pConstraint, /* The constraint to test */ + int eInt, /* True if RTree holding integer coordinates */ + u8 *pCellData, /* Raw cell content */ + RtreeSearchPoint *pSearch, /* Container of this cell */ + sqlite3_rtree_dbl *prScore, /* OUT: score for the cell */ + int *peWithin /* OUT: visibility of the cell */ ){ - int ii; - int bOutOfBounds = 0; - int rc = SQLITE_OK; - Rtree *pRtree = RTREE_OF_CURSOR(pCursor); + int i; /* Loop counter */ + sqlite3_rtree_query_info *pGeom = pConstraint->pGeom; /* Callback info */ + int nCoord = pGeom->nCoord; /* No. of coordinates */ + int rc; /* Callback return code */ + sqlite3_rtree_dbl aCoord[RTREE_MAX_DIMENSIONS*2]; /* Decoded coordinates */ - for(ii=0; bOutOfBounds==0 && iinConstraint; ii++){ - RtreeConstraint *p = &pCursor->aConstraint[ii]; - RtreeDValue cell_min = DCOORD(pCell->aCoord[(p->iCoord>>1)*2]); - RtreeDValue cell_max = DCOORD(pCell->aCoord[(p->iCoord>>1)*2+1]); + assert( pConstraint->op==RTREE_MATCH || pConstraint->op==RTREE_QUERY ); + assert( nCoord==2 || nCoord==4 || nCoord==6 || nCoord==8 || nCoord==10 ); - assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE - || p->op==RTREE_GT || p->op==RTREE_EQ || p->op==RTREE_MATCH - ); - - switch( p->op ){ - case RTREE_LE: case RTREE_LT: - bOutOfBounds = p->u.rValueu.rValue>cell_max; - break; - - case RTREE_EQ: - bOutOfBounds = (p->u.rValue>cell_max || p->u.rValueop==RTREE_MATCH ); - rc = rtreeTestGeom(pRtree, p, pCell, &bOutOfBounds); - bOutOfBounds = !bOutOfBounds; - break; - } - } + pCellData += 8; + for(i=0; iop==RTREE_MATCH ){ + rc = pConstraint->u.xGeom((sqlite3_rtree_geometry*)pGeom, + nCoord, aCoord, &i); + if( i==0 ) *peWithin = NOT_WITHIN; + }else{ + pGeom->aCoord = aCoord; + pGeom->iLevel = pSearch->iLevel; + pGeom->rScore = pGeom->rParentScore = pSearch->rScore; + pGeom->eWithin = pGeom->eParentWithin = pSearch->eWithin; + rc = pConstraint->u.xQueryFunc(pGeom); + if( pGeom->eWithin<*peWithin ) *peWithin = pGeom->eWithin; + if( pGeom->rScore<*prScore ) *prScore = pGeom->rScore; } - - *peWithin = bOutOfBounds ? NOT_WITHIN : PARTLY_WITHIN; return rc; } /* -** pCursor points to a leaf r-tree entry which is a candidate for output. -** This routine sets *peWithin to one of NOT_WITHIN, PARTLY_WITHIN, or -** FULLY_WITHIN depending on whether or not the leaf entry is completely -** outside the region defined by pCursor->aConstraints[], or overlaps the -** region, or is completely within the region, respectively. -** -** This routine is more selective than rtreeTestCell(). rtreeTestCell() -** will return PARTLY_WITHIN or FULLY_WITHIN if the constraints are such -** that a subelement of the cell to be included in the result set. This -** routine is is only called for leaf r-tree entries and does not need -** to concern itself with subelements. Hence it only sets *peWithin to -** PARTLY_WITHIN or FULLY_WITHIN if the cell itself meets the requirements. -** -** Return SQLITE_OK if successful or an SQLite error code if an error -** occurs within a geometry callback. -** -** This function assumes that the cell is part of a leaf node. +** Check the internal RTree node given by pCellData against constraint p. +** If this constraint cannot be satisfied by any child within the node, +** set *peWithin to NOT_WITHIN. */ -static int rtreeTestEntry( - RtreeCursor *pCursor, /* Cursor pointing to the leaf element */ - RtreeCell *pCell, /* The cell to check */ - int *peWithin /* OUT: NOT_WITHIN, PARTLY_WITHIN, or FULLY_WITHIN */ +static void rtreeNonleafConstraint( + RtreeConstraint *p, /* The constraint to test */ + int eInt, /* True if RTree holds integer coordinates */ + u8 *pCellData, /* Raw cell content as appears on disk */ + int *peWithin /* Adjust downward, as appropriate */ ){ - Rtree *pRtree = RTREE_OF_CURSOR(pCursor); - int ii; - int res = 1; /* Innocent until proven guilty */ + sqlite3_rtree_dbl val; /* Coordinate value convert to a double */ - for(ii=0; res && iinConstraint; ii++){ - RtreeConstraint *p = &pCursor->aConstraint[ii]; - RtreeDValue coord = DCOORD(pCell->aCoord[p->iCoord]); - assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE - || p->op==RTREE_GT || p->op==RTREE_EQ || p->op==RTREE_MATCH - ); - switch( p->op ){ - case RTREE_LE: res = (coord<=p->u.rValue); break; - case RTREE_LT: res = (coordu.rValue); break; - case RTREE_GE: res = (coord>=p->u.rValue); break; - case RTREE_GT: res = (coord>p->u.rValue); break; - case RTREE_EQ: res = (coord==p->u.rValue); break; - default: { - int rc; - assert( p->op==RTREE_MATCH ); - rc = rtreeTestGeom(pRtree, p, pCell, &res); - if( rc!=SQLITE_OK ){ - return rc; - } - break; - } - } + /* p->iCoord might point to either a lower or upper bound coordinate + ** in a coordinate pair. But make pCellData point to the lower bound. + */ + pCellData += 8 + 4*(p->iCoord&0xfe); + + assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE + || p->op==RTREE_GT || p->op==RTREE_EQ ); + switch( p->op ){ + case RTREE_LE: + case RTREE_LT: + case RTREE_EQ: + RTREE_DECODE_COORD(eInt, pCellData, val); + /* val now holds the lower bound of the coordinate pair */ + if( p->u.rValue>=val ) return; + if( p->op!=RTREE_EQ ) break; /* RTREE_LE and RTREE_LT end here */ + /* Fall through for the RTREE_EQ case */ + + default: /* RTREE_GT or RTREE_GE, or fallthrough of RTREE_EQ */ + pCellData += 4; + RTREE_DECODE_COORD(eInt, pCellData, val); + /* val now holds the upper bound of the coordinate pair */ + if( p->u.rValue<=val ) return; } + *peWithin = NOT_WITHIN; +} - *peWithin = res ? FULLY_WITHIN : NOT_WITHIN; - return SQLITE_OK; +/* +** Check the leaf RTree cell given by pCellData against constraint p. +** If this constraint is not satisfied, set *peWithin to NOT_WITHIN. +** If the constraint is satisfied, leave *peWithin unchanged. +** +** The constraint is of the form: xN op $val +** +** The op is given by p->op. The xN is p->iCoord-th coordinate in +** pCellData. $val is given by p->u.rValue. +*/ +static void rtreeLeafConstraint( + RtreeConstraint *p, /* The constraint to test */ + int eInt, /* True if RTree holds integer coordinates */ + u8 *pCellData, /* Raw cell content as appears on disk */ + int *peWithin /* Adjust downward, as appropriate */ +){ + RtreeDValue xN; /* Coordinate value converted to a double */ + + assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE + || p->op==RTREE_GT || p->op==RTREE_EQ ); + pCellData += 8 + p->iCoord*4; + RTREE_DECODE_COORD(eInt, pCellData, xN); + switch( p->op ){ + case RTREE_LE: if( xN <= p->u.rValue ) return; break; + case RTREE_LT: if( xN < p->u.rValue ) return; break; + case RTREE_GE: if( xN >= p->u.rValue ) return; break; + case RTREE_GT: if( xN > p->u.rValue ) return; break; + default: if( xN == p->u.rValue ) return; break; + } + *peWithin = NOT_WITHIN; } /* @@ -1295,39 +1277,53 @@ static int rtreeStepToLeaf(RtreeCursor *pCur){ int eWithin; int rc = SQLITE_OK; int nCell; - RtreeCell cell; + int nConstraint = pCur->nConstraint; + int ii; + int eInt; RtreeSearchPoint x; + eInt = pRtree->eCoordType==RTREE_COORD_INT32; while( (p = rtreeSearchPointFirst(pCur))!=0 && p->iLevel>0 ){ pNode = rtreeNodeOfFirstSearchPoint(pCur, &rc); if( rc ) return rc; nCell = NCELL(pNode); assert( nCell<200 ); while( p->iCelliCell, &cell); - if( p->iLevel==1 ){ - rc = rtreeTestEntry(pCur, &cell, &eWithin); - }else{ - rc = rtreeTestCell(pCur, &cell, &eWithin); + sqlite3_rtree_dbl rScore = (sqlite3_rtree_dbl)0; + u8 *pCellData = pNode->zData + (4+pRtree->nBytesPerCell*p->iCell); + eWithin = FULLY_WITHIN; + for(ii=0; iiaConstraint + ii; + if( pConstraint->op>=RTREE_MATCH ){ + rc = rtreeCallbackConstraint(pConstraint, eInt, pCellData, p, + &rScore, &eWithin); + if( rc ) return rc; + }else if( p->iLevel==1 ){ + rtreeLeafConstraint(pConstraint, eInt, pCellData, &eWithin); + }else{ + rtreeNonleafConstraint(pConstraint, eInt, pCellData, &eWithin); + } + if( eWithin==NOT_WITHIN ) break; } - if( rc ) return rc; - x = *p; p->iCell++; if( eWithin==NOT_WITHIN ) continue; + x.iLevel = p->iLevel - 1; + if( x.iLevel ){ + x.id = readInt64(pCellData); + x.iCell = 0; + }else{ + x.id = p->id; + x.iCell = p->iCell - 1; + } if( p->iCell>=nCell ){ RTREE_QUEUE_TRACE(pCur, "POP-S:"); rtreeSearchPointPop(pCur); } - p = rtreeSearchPointNew(pCur, /*rScore*/0.0, x.iLevel-1); + p = rtreeSearchPointNew(pCur, rScore, x.iLevel); if( p==0 ) return SQLITE_NOMEM; p->eWithin = eWithin; - if( p->iLevel ){ - p->id = cell.iRowid; - p->iCell = 0; - }else{ - p->id = x.id; - p->iCell = x.iCell; - } + p->id = x.id; + p->iCell = x.iCell; RTREE_QUEUE_TRACE(pCur, "PUSH-S:"); break; } @@ -1460,7 +1456,6 @@ static int deserializeGeometry(sqlite3_value *pValue, RtreeConstraint *pCons){ sqlite3_free(pGeom); return SQLITE_ERROR; } - pGeom->pContext = p->cb.pContext; pGeom->nParam = p->nParam; pGeom->aParam = p->aParam; @@ -1525,7 +1520,7 @@ static int rtreeFilter( for(ii=0; iiaConstraint[ii]; p->op = idxStr[ii*2]; - p->iCoord = idxStr[ii*2+1]-'a'; + p->iCoord = idxStr[ii*2+1]-'0'; if( p->op==RTREE_MATCH ){ /* A MATCH operator. The right-hand-side must be a blob that ** can be cast into an RtreeMatchArg object. One created using @@ -1535,6 +1530,7 @@ static int rtreeFilter( if( rc!=SQLITE_OK ){ break; } + p->pGeom->nCoord = pRtree->nDim*2; }else{ #ifdef SQLITE_RTREE_INT_ONLY p->u.rValue = sqlite3_value_int64(argv[ii]); @@ -1663,7 +1659,7 @@ static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ break; } zIdxStr[iIdx++] = op; - zIdxStr[iIdx++] = p->iColumn - 1 + 'a'; + zIdxStr[iIdx++] = p->iColumn - 1 + '0'; pIdxInfo->aConstraintUsage[ii].argvIndex = (iIdx/2); pIdxInfo->aConstraintUsage[ii].omit = 1; } diff --git a/ext/rtree/rtree6.test b/ext/rtree/rtree6.test index bdc9bb4146..c5a78bb3e3 100644 --- a/ext/rtree/rtree6.test +++ b/ext/rtree/rtree6.test @@ -57,31 +57,31 @@ do_test rtree6-1.1 { do_test rtree6-1.2 { rtree_strategy {SELECT * FROM t1 WHERE x1>10} -} {Ea} +} {E0} do_test rtree6-1.3 { rtree_strategy {SELECT * FROM t1 WHERE x1<10} -} {Ca} +} {C0} do_test rtree6-1.4 { rtree_strategy {SELECT * FROM t1,t2 WHERE k=ii AND x1<10} -} {Ca} +} {C0} do_test rtree6-1.5 { rtree_strategy {SELECT * FROM t1,t2 WHERE k=+ii AND x1<10} -} {Ca} +} {C0} do_eqp_test rtree6.2.1 { SELECT * FROM t1,t2 WHERE k=+ii AND x1<10 } { - 0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 2:Ca} + 0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 2:C0} 0 1 1 {SEARCH TABLE t2 USING INTEGER PRIMARY KEY (rowid=?)} } do_eqp_test rtree6.2.2 { SELECT * FROM t1,t2 WHERE k=ii AND x1<10 } { - 0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 2:Ca} + 0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 2:C0} 0 1 1 {SEARCH TABLE t2 USING INTEGER PRIMARY KEY (rowid=?)} } @@ -95,7 +95,7 @@ do_eqp_test rtree6.2.3 { do_eqp_test rtree6.2.4 { SELECT * FROM t1,t2 WHERE v=10 and x1<10 and x2>10 } { - 0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 2:CaEb} + 0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 2:C0E1} 0 1 1 {SEARCH TABLE t2 USING AUTOMATIC COVERING INDEX (v=?)} } @@ -126,7 +126,7 @@ do_test rtree6.3.2 { x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 } -} {EaEaEaEaEaEaEaEaEaEaEaEaEaEaEaEaEaEaEaEa} +} {E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0} do_test rtree6.3.3 { rtree_strategy { SELECT * FROM t3 WHERE @@ -137,7 +137,7 @@ do_test rtree6.3.3 { x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 } -} {EaEaEaEaEaEaEaEaEaEaEaEaEaEaEaEaEaEaEaEa} +} {E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0} do_execsql_test rtree6-3.4 { SELECT * FROM t3 WHERE x1>0.5 AND x1>0.8 AND x1>1.1 diff --git a/ext/rtree/rtreeC.test b/ext/rtree/rtreeC.test index 23dc607841..94db05a4d1 100644 --- a/ext/rtree/rtreeC.test +++ b/ext/rtree/rtreeC.test @@ -29,7 +29,7 @@ do_eqp_test 1.1 { WHERE t.x>=min_x AND t.x<=max_x AND t.y>=min_y AND t.x<=max_y } { 0 0 1 {SCAN TABLE t} - 0 1 0 {SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:DdBcDbBa} + 0 1 0 {SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:D3B2D1B0} } do_eqp_test 1.2 { @@ -37,7 +37,7 @@ do_eqp_test 1.2 { WHERE t.x>=min_x AND t.x<=max_x AND t.y>=min_y AND t.x<=max_y } { 0 0 0 {SCAN TABLE t} - 0 1 1 {SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:DdBcDbBa} + 0 1 1 {SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:D3B2D1B0} } do_eqp_test 1.3 { @@ -45,7 +45,7 @@ do_eqp_test 1.3 { WHERE t.x>=min_x AND t.x<=max_x AND t.y>=min_y AND ?<=max_y } { 0 0 0 {SCAN TABLE t} - 0 1 1 {SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:DdBcDbBa} + 0 1 1 {SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:D3B2D1B0} } do_eqp_test 1.5 { @@ -82,7 +82,7 @@ do_eqp_test 2.1 { WHERE t.x>=min_x AND t.x<=max_x AND t.y>=min_y AND t.x<=max_y } { 0 0 1 {SCAN TABLE t} - 0 1 0 {SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:DdBcDbBa} + 0 1 0 {SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:D3B2D1B0} } do_eqp_test 2.2 { @@ -90,7 +90,7 @@ do_eqp_test 2.2 { WHERE t.x>=min_x AND t.x<=max_x AND t.y>=min_y AND t.x<=max_y } { 0 0 0 {SCAN TABLE t} - 0 1 1 {SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:DdBcDbBa} + 0 1 1 {SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:D3B2D1B0} } do_eqp_test 2.3 { @@ -98,7 +98,7 @@ do_eqp_test 2.3 { WHERE t.x>=min_x AND t.x<=max_x AND t.y>=min_y AND ?<=max_y } { 0 0 0 {SCAN TABLE t} - 0 1 1 {SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:DdBcDbBa} + 0 1 1 {SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:D3B2D1B0} } do_eqp_test 2.5 { @@ -271,4 +271,3 @@ ifcapable rtree { finish_test - diff --git a/manifest b/manifest index 336104aca0..d10804afcb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Performance\soptimization\son\snodeGetCell()\sin\sR-Tree. -D 2014-04-16T21:02:28.844 +C Refactor\sthe\sconstraint\schecking\slogic\sin\sRTree.\s\sThe\snew-style\sconstraint\ncallbacks\screated\sby\ssqlite3_rtree_query_callback()\sare\snow\shooked\sup\sfrom\nend\sto\send,\sthough\sstill\suntested. +D 2014-04-17T13:15:33.281 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e4ee6d36cdf6136aee0158675a3b24dd3bf31a5a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -120,20 +120,20 @@ F ext/misc/vfslog.c fe40fab5c077a40477f7e5eba994309ecac6cc95 F ext/misc/vtshim.c babb0dc2bf116029e3e7c9a618b8a1377045303e F ext/misc/wholenumber.c 784b12543d60702ebdd47da936e278aa03076212 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 -F ext/rtree/rtree.c 1a59db351a8dfaa46c59b3105865a1aaa5192a61 +F ext/rtree/rtree.c 117aaebed87a7c1e5d3e03afbad83c3700aa5ab8 F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e F ext/rtree/rtree1.test cf679265ecafff494a768ac9c2f43a70915a6290 F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba F ext/rtree/rtree3.test a494da55c30ee0bc9b01a91c80c81b387b22d2dc F ext/rtree/rtree4.test c8fe384f60ebd49540a5fecc990041bf452eb6e0 F ext/rtree/rtree5.test 6a510494f12454bf57ef28f45bc7764ea279431e -F ext/rtree/rtree6.test fe0bd377a21c68ce2826129d14354c884cb1f354 +F ext/rtree/rtree6.test 756585abc51727fec97c77852476445c10c0ee95 F ext/rtree/rtree7.test 1fa710b9e6bf997a0c1a537b81be7bb6fded1971 F ext/rtree/rtree8.test db79c812f9e4a11f9b1f3f9934007884610a713a F ext/rtree/rtree9.test d86ebf08ff6328895613ed577dd8a2a37c472c34 F ext/rtree/rtreeA.test ace05e729a36e342d40cf94e9efc7b4723d9dcdf F ext/rtree/rtreeB.test c85f9ce78766c4e68b8b89fbf2979ee9cfa82b4e -F ext/rtree/rtreeC.test 16d7aa86ecb6a876d2a38cf590a1471a41b3a46d +F ext/rtree/rtreeC.test df158dcc81f1a43ce7eef361af03c48ec91f1e06 F ext/rtree/rtreeD.test 636630357638f5983701550b37f0f5867130d2ca F ext/rtree/rtree_perf.tcl 6c18c1f23cd48e0f948930c98dfdd37dfccb5195 F ext/rtree/rtree_util.tcl 06aab2ed5b826545bf215fff90ecb9255a8647ea @@ -1175,7 +1175,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P f26936f71a16ab25590540f7feb273514dfb69ff -R b2b62cbe51f5e73202ce646c31659a05 +P 5d20ff9ec837ad35bc44d6c25d13764b350e81dd +R 9ddd572c495f4e9fca0e8e969ae19d88 U drh -Z 74eaec9038e9087250153055260f329f +Z 43698a2882be63e69b530e3c48875378 diff --git a/manifest.uuid b/manifest.uuid index a27b70bb21..5fbbb6cae9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5d20ff9ec837ad35bc44d6c25d13764b350e81dd \ No newline at end of file +32a13870175a1dd1d33af3572dde09ff607a04b6 \ No newline at end of file From b640595f97b7f55e619fd895becb7bf7ad5d6cf3 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 17 Apr 2014 14:52:20 +0000 Subject: [PATCH 0099/1484] Test cases and bug fixes for the sqlite3_rtree_query_callback() mechanism. FossilOrigin-Name: 1ccaaed6b516ec2ce953c1b31025a82ba76d00e7 --- ext/rtree/rtree.c | 113 ++++++++++++++++++++++++------------------ ext/rtree/rtreeE.test | 72 +++++++++++++++++++++++++++ manifest | 15 +++--- manifest.uuid | 2 +- src/test_rtree.c | 36 ++++++++------ 5 files changed, 168 insertions(+), 70 deletions(-) create mode 100644 ext/rtree/rtreeE.test diff --git a/ext/rtree/rtree.c b/ext/rtree/rtree.c index 3c9a8daba9..53414af7ee 100644 --- a/ext/rtree/rtree.c +++ b/ext/rtree/rtree.c @@ -162,9 +162,11 @@ struct Rtree { #ifdef SQLITE_RTREE_INT_ONLY typedef sqlite3_int64 RtreeDValue; /* High accuracy coordinate */ typedef int RtreeValue; /* Low accuracy coordinate */ +# define RTREE_ZERO 0 #else typedef double RtreeDValue; /* High accuracy coordinate */ typedef float RtreeValue; /* Low accuracy coordinate */ +# define RTREE_ZERO 0.0 #endif /* @@ -270,7 +272,7 @@ struct RtreeConstraint { int (*xGeom)(sqlite3_rtree_geometry*,int,RtreeDValue*,int*); int (*xQueryFunc)(sqlite3_rtree_query_info*); } u; - sqlite3_rtree_query_info *pGeom; /* xGeom and xQueryFunc argument */ + sqlite3_rtree_query_info *pInfo; /* xGeom and xQueryFunc argument */ }; /* Possible values for RtreeConstraint.op */ @@ -863,10 +865,10 @@ static void freeCursorConstraints(RtreeCursor *pCsr){ if( pCsr->aConstraint ){ int i; /* Used to iterate through constraint array */ for(i=0; inConstraint; i++){ - sqlite3_rtree_query_info *pGeom = pCsr->aConstraint[i].pGeom; - if( pGeom ){ - if( pGeom->xDelUser ) pGeom->xDelUser(pGeom->pUser); - sqlite3_free(pGeom); + sqlite3_rtree_query_info *pInfo = pCsr->aConstraint[i].pInfo; + if( pInfo ){ + if( pInfo->xDelUser ) pInfo->xDelUser(pInfo->pUser); + sqlite3_free(pInfo); } } sqlite3_free(pCsr->aConstraint); @@ -928,8 +930,8 @@ static int rtreeCallbackConstraint( int *peWithin /* OUT: visibility of the cell */ ){ int i; /* Loop counter */ - sqlite3_rtree_query_info *pGeom = pConstraint->pGeom; /* Callback info */ - int nCoord = pGeom->nCoord; /* No. of coordinates */ + sqlite3_rtree_query_info *pInfo = pConstraint->pInfo; /* Callback info */ + int nCoord = pInfo->nCoord; /* No. of coordinates */ int rc; /* Callback return code */ sqlite3_rtree_dbl aCoord[RTREE_MAX_DIMENSIONS*2]; /* Decoded coordinates */ @@ -941,17 +943,20 @@ static int rtreeCallbackConstraint( RTREE_DECODE_COORD(eInt, pCellData, aCoord[i]); } if( pConstraint->op==RTREE_MATCH ){ - rc = pConstraint->u.xGeom((sqlite3_rtree_geometry*)pGeom, + rc = pConstraint->u.xGeom((sqlite3_rtree_geometry*)pInfo, nCoord, aCoord, &i); if( i==0 ) *peWithin = NOT_WITHIN; + *prScore = RTREE_ZERO; }else{ - pGeom->aCoord = aCoord; - pGeom->iLevel = pSearch->iLevel; - pGeom->rScore = pGeom->rParentScore = pSearch->rScore; - pGeom->eWithin = pGeom->eParentWithin = pSearch->eWithin; - rc = pConstraint->u.xQueryFunc(pGeom); - if( pGeom->eWithin<*peWithin ) *peWithin = pGeom->eWithin; - if( pGeom->rScore<*prScore ) *prScore = pGeom->rScore; + pInfo->aCoord = aCoord; + pInfo->iLevel = pSearch->iLevel; + pInfo->rScore = pInfo->rParentScore = pSearch->rScore; + pInfo->eWithin = pInfo->eParentWithin = pSearch->eWithin; + rc = pConstraint->u.xQueryFunc(pInfo); + if( pInfo->eWithin<*peWithin ) *peWithin = pInfo->eWithin; + if( pInfo->rScore<*prScore || *prScorerScore; + } } return rc; } @@ -1065,6 +1070,12 @@ static int nodeParentIndex(Rtree *pRtree, RtreeNode *pNode, int *piIndex){ /* ** Compare two search points. Return negative, zero, or positive if the first ** is less than, equal to, or greater than the second. +** +** The rScore is the primary key. Smaller rScore values come first. +** If the rScore is a tie, then use iLevel as the tie breaker with smaller +** iLevel values coming first. In this way, if rScore is the same for all +** SearchPoints, then iLevel becomes the deciding factor and the result +** is a depth-first search, which is the desired default behavior. */ static int rtreeSearchPointCompare( const RtreeSearchPoint *pA, @@ -1289,7 +1300,7 @@ static int rtreeStepToLeaf(RtreeCursor *pCur){ nCell = NCELL(pNode); assert( nCell<200 ); while( p->iCellzData + (4+pRtree->nBytesPerCell*p->iCell); eWithin = FULLY_WITHIN; for(ii=0; iieWithin = eWithin; @@ -1429,9 +1441,10 @@ static int findLeafNode( ** operator. */ static int deserializeGeometry(sqlite3_value *pValue, RtreeConstraint *pCons){ - RtreeMatchArg *p; - sqlite3_rtree_query_info *pGeom; - int nBlob; + RtreeMatchArg *pBlob; /* 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; @@ -1444,24 +1457,29 @@ static int deserializeGeometry(sqlite3_value *pValue, RtreeConstraint *pCons){ return SQLITE_ERROR; } - pGeom = (sqlite3_rtree_query_info*)sqlite3_malloc( sizeof(*pGeom)+nBlob ); - if( !pGeom ) return SQLITE_NOMEM; - memset(pGeom, 0, sizeof(*pGeom)); - p = (RtreeMatchArg*)&pGeom[1]; + pInfo = (sqlite3_rtree_query_info*)sqlite3_malloc( sizeof(*pInfo)+nBlob ); + if( !pInfo ) return SQLITE_NOMEM; + memset(pInfo, 0, sizeof(*pInfo)); + pBlob = (RtreeMatchArg*)&pInfo[1]; - memcpy(p, sqlite3_value_blob(pValue), nBlob); - if( p->magic!=RTREE_GEOMETRY_MAGIC - || nBlob!=(int)(sizeof(RtreeMatchArg) + (p->nParam-1)*sizeof(RtreeDValue)) - ){ - sqlite3_free(pGeom); + memcpy(pBlob, sqlite3_value_blob(pValue), nBlob); + nExpected = (int)(sizeof(RtreeMatchArg) + + (pBlob->nParam-1)*sizeof(RtreeDValue)); + if( pBlob->magic!=RTREE_GEOMETRY_MAGIC || nBlob!=nExpected ){ + sqlite3_free(pInfo); return SQLITE_ERROR; } - pGeom->pContext = p->cb.pContext; - pGeom->nParam = p->nParam; - pGeom->aParam = p->aParam; + pInfo->pContext = pBlob->cb.pContext; + pInfo->nParam = pBlob->nParam; + pInfo->aParam = pBlob->aParam; - pCons->u.xGeom = p->cb.xGeom; - pCons->pGeom = pGeom; + if( pBlob->cb.xGeom ){ + pCons->u.xGeom = pBlob->cb.xGeom; + }else{ + pCons->op = RTREE_QUERY; + pCons->u.xQueryFunc = pBlob->cb.xQueryFunc; + } + pCons->pInfo = pInfo; return SQLITE_OK; } @@ -1493,7 +1511,7 @@ static int rtreeFilter( i64 iNode = 0; rc = findLeafNode(pRtree, iRowid, &pLeaf, &iNode); if( rc==SQLITE_OK && pLeaf!=0 ){ - p = rtreeSearchPointNew(pCsr, 0.0, 0); + p = rtreeSearchPointNew(pCsr, RTREE_ZERO, 0); assert( p!=0 ); /* Always returns pCsr->sPoint */ pCsr->aNode[0] = pLeaf; p->id = iNode; @@ -1521,7 +1539,7 @@ static int rtreeFilter( RtreeConstraint *p = &pCsr->aConstraint[ii]; p->op = idxStr[ii*2]; p->iCoord = idxStr[ii*2+1]-'0'; - if( p->op==RTREE_MATCH ){ + if( p->op>=RTREE_MATCH ){ /* A MATCH operator. The right-hand-side must be a blob that ** can be cast into an RtreeMatchArg object. One created using ** an sqlite3_rtree_geometry_callback() SQL user function. @@ -1530,7 +1548,7 @@ static int rtreeFilter( if( rc!=SQLITE_OK ){ break; } - p->pGeom->nCoord = pRtree->nDim*2; + p->pInfo->nCoord = pRtree->nDim*2; }else{ #ifdef SQLITE_RTREE_INT_ONLY p->u.rValue = sqlite3_value_int64(argv[ii]); @@ -1546,7 +1564,8 @@ static int rtreeFilter( rc = nodeAcquire(pRtree, 1, 0, &pRoot); } if( rc==SQLITE_OK ){ - RtreeSearchPoint *pNew = rtreeSearchPointNew(pCsr, 0.0, pRtree->iDepth+1); + RtreeSearchPoint *pNew; + pNew = rtreeSearchPointNew(pCsr, RTREE_ZERO, pRtree->iDepth+1); if( pNew==0 ) return SQLITE_NOMEM; pNew->id = 1; pNew->iCell = 0; @@ -1759,7 +1778,7 @@ static RtreeDValue cellOverlap( int nCell ){ int ii; - RtreeDValue overlap = 0.0; + RtreeDValue overlap = RTREE_ZERO; for(ii=0; iinDim+1)*(sizeof(int*)+nCell*sizeof(int)); @@ -2071,9 +2090,9 @@ static int splitNodeStartree( } for(ii=0; iinDim; ii++){ - RtreeDValue margin = 0.0; - RtreeDValue fBestOverlap = 0.0; - RtreeDValue fBestArea = 0.0; + RtreeDValue margin = RTREE_ZERO; + RtreeDValue fBestOverlap = RTREE_ZERO; + RtreeDValue fBestArea = RTREE_ZERO; int iBestLeft = 0; int nLeft; @@ -2492,7 +2511,7 @@ static int Reinsert( } for(ii=0; iinDim; iDim++){ RtreeDValue coord = (DCOORD(aCell[ii].aCoord[iDim*2+1]) - DCOORD(aCell[ii].aCoord[iDim*2])); @@ -3299,8 +3318,8 @@ int sqlite3RtreeInit(sqlite3 *db){ ** the corresponding SQL function is deleted. */ static void rtreeFreeCallback(void *p){ - RtreeGeomCallback *pGeom = (RtreeGeomCallback*)p; - if( pGeom->xDestructor ) pGeom->xDestructor(pGeom->pContext); + RtreeGeomCallback *pInfo = (RtreeGeomCallback*)p; + if( pInfo->xDestructor ) pInfo->xDestructor(pInfo->pContext); sqlite3_free(p); } diff --git a/ext/rtree/rtreeE.test b/ext/rtree/rtreeE.test new file mode 100644 index 0000000000..14f5c332ca --- /dev/null +++ b/ext/rtree/rtreeE.test @@ -0,0 +1,72 @@ +# 2010 August 28 +# +# 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 contains tests for the r-tree module. Specifically, it tests +# that new-style custom r-tree queries (geometry callbacks) work. +# + +if {![info exists testdir]} { + set testdir [file join [file dirname [info script]] .. .. test] +} +source $testdir/tester.tcl +ifcapable !rtree { finish_test ; return } +ifcapable rtree_int_only { finish_test; return } + + +#------------------------------------------------------------------------- +# Test the example 2d "circle" geometry callback. +# +register_circle_geom db + +do_execsql_test rtreeE-1.1 { + PRAGMA page_size=512; + CREATE VIRTUAL TABLE rt2 USING rtree(id,x0,x1,y0,y1); + + /* A tight pattern of small boxes near 0,0 */ + WITH RECURSIVE + x(x) AS (VALUES(0) UNION ALL SELECT x+1 FROM x WHERE x<4), + y(y) AS (VALUES(0) UNION ALL SELECT y+1 FROM y WHERE y<4) + INSERT INTO rt2 SELECT x+5*y, x, x+2, y, y+2 FROM x, y; + + /* A looser pattern of small boxes near 100, 0 */ + WITH RECURSIVE + x(x) AS (VALUES(0) UNION ALL SELECT x+1 FROM x WHERE x<4), + y(y) AS (VALUES(0) UNION ALL SELECT y+1 FROM y WHERE y<4) + INSERT INTO rt2 SELECT 100+x+5*y, x*3+100, x*3+102, y*3, y*3+2 FROM x, y; + + /* A looser pattern of larger boxes near 0, 200 */ + WITH RECURSIVE + x(x) AS (VALUES(0) UNION ALL SELECT x+1 FROM x WHERE x<4), + y(y) AS (VALUES(0) UNION ALL SELECT y+1 FROM y WHERE y<4) + INSERT INTO rt2 SELECT 200+x+5*y, x*7, x*7+15, y*7+200, y*7+215 FROM x, y; +} {} + +if 0 { +# Queries against each of the three clusters */ +do_execsql_test rtreeE-1.1 { + SELECT id FROM rt2 WHERE id MATCH Qcircle(0.0, 0.0, 50.0) ORDER BY id; +} {0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24} +do_execsql_test rtreeE-1.2 { + SELECT id FROM rt2 WHERE id MATCH Qcircle(100.0, 0.0, 50.0) ORDER BY id; +} {100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124} +do_execsql_test rtreeE-1.3 { + SELECT id FROM rt2 WHERE id MATCH Qcircle(0.0, 200.0, 50.0) ORDER BY id; +} {200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224} +} + +# The Qcircle geometry function gives a lower score to larger leaf-nodes. +# This causes the 200s to sort before the 100s and the 0s to sort before +# last. +# +do_execsql_test rtreeE-1.4 { + SELECT id FROM rt2 WHERE id MATCH Qcircle(0,0,1000) AND id%100==0 +} {200 100 0} + +finish_test diff --git a/manifest b/manifest index d10804afcb..63a2d6b9ce 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Refactor\sthe\sconstraint\schecking\slogic\sin\sRTree.\s\sThe\snew-style\sconstraint\ncallbacks\screated\sby\ssqlite3_rtree_query_callback()\sare\snow\shooked\sup\sfrom\nend\sto\send,\sthough\sstill\suntested. -D 2014-04-17T13:15:33.281 +C Test\scases\sand\sbug\sfixes\sfor\sthe\ssqlite3_rtree_query_callback()\nmechanism. +D 2014-04-17T14:52:20.025 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e4ee6d36cdf6136aee0158675a3b24dd3bf31a5a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -120,7 +120,7 @@ F ext/misc/vfslog.c fe40fab5c077a40477f7e5eba994309ecac6cc95 F ext/misc/vtshim.c babb0dc2bf116029e3e7c9a618b8a1377045303e F ext/misc/wholenumber.c 784b12543d60702ebdd47da936e278aa03076212 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 -F ext/rtree/rtree.c 117aaebed87a7c1e5d3e03afbad83c3700aa5ab8 +F ext/rtree/rtree.c 6a47918e44697dd32f5bba8a79d3490e56bd76c9 F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e F ext/rtree/rtree1.test cf679265ecafff494a768ac9c2f43a70915a6290 F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba @@ -135,6 +135,7 @@ F ext/rtree/rtreeA.test ace05e729a36e342d40cf94e9efc7b4723d9dcdf F ext/rtree/rtreeB.test c85f9ce78766c4e68b8b89fbf2979ee9cfa82b4e F ext/rtree/rtreeC.test df158dcc81f1a43ce7eef361af03c48ec91f1e06 F ext/rtree/rtreeD.test 636630357638f5983701550b37f0f5867130d2ca +F ext/rtree/rtreeE.test c8c951df54fd556d30eb621ecc2acd8771970a5e F ext/rtree/rtree_perf.tcl 6c18c1f23cd48e0f948930c98dfdd37dfccb5195 F ext/rtree/rtree_util.tcl 06aab2ed5b826545bf215fff90ecb9255a8647ea F ext/rtree/sqlite3rtree.h 488cf8834d2012b913d33683157d3cf5f1327a69 @@ -274,7 +275,7 @@ F src/test_osinst.c 90a845c8183013d80eccb1f29e8805608516edba F src/test_pcache.c a5cd24730cb43c5b18629043314548c9169abb00 F src/test_quota.c 30c64f0ef84734f2231a686df41ed882b0c59bc0 F src/test_quota.h 8761e463b25e75ebc078bd67d70e39b9c817a0cb -F src/test_rtree.c cd35d54c0b847c0c373d66f91616c49697ab4edf +F src/test_rtree.c 636d2a5bc9ded2fa1df4e7d4c575eb0d3f13b334 F src/test_schema.c cd12a2223c3a394f4d07bb93bdf6d344c5c121b6 F src/test_server.c a2615049954cbb9cfb4a62e18e2f0616e4dc38fe F src/test_sqllog.c c1c1bbedbcaf82b93d83e4f9dd990e62476a680e @@ -1175,7 +1176,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 5d20ff9ec837ad35bc44d6c25d13764b350e81dd -R 9ddd572c495f4e9fca0e8e969ae19d88 +P 32a13870175a1dd1d33af3572dde09ff607a04b6 +R 1f38906450e19fda5c27a4543b70f18c U drh -Z 43698a2882be63e69b530e3c48875378 +Z 26a5b86beaa061e155488cf6e80f8d30 diff --git a/manifest.uuid b/manifest.uuid index 5fbbb6cae9..07ccb10268 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -32a13870175a1dd1d33af3572dde09ff607a04b6 \ No newline at end of file +1ccaaed6b516ec2ce953c1b31025a82ba76d00e7 \ No newline at end of file diff --git a/src/test_rtree.c b/src/test_rtree.c index 3b4c205879..c1951a896b 100644 --- a/src/test_rtree.c +++ b/src/test_rtree.c @@ -35,6 +35,7 @@ struct Circle { double centerx; double centery; double radius; + double mxArea; }; /* @@ -58,7 +59,12 @@ static int circle_geom( double xmin, xmax; /* X dimensions of box being tested */ double ymin, ymax; /* X dimensions of box being tested */ - if( p->pUser==0 ){ + xmin = aCoord[0]; + xmax = aCoord[1]; + ymin = aCoord[2]; + ymax = aCoord[3]; + pCircle = (Circle *)p->pUser; + if( pCircle==0 ){ /* If pUser is still 0, then the parameter values have not been tested ** for correctness or stored into a Circle structure yet. Do this now. */ @@ -104,14 +110,9 @@ static int circle_geom( pCircle->aBox[1].xmax = pCircle->centerx - pCircle->radius; pCircle->aBox[1].ymin = pCircle->centery; pCircle->aBox[1].ymax = pCircle->centery; + pCircle->mxArea = (xmax - xmin)*(ymax - ymin) + 1.0; } - pCircle = (Circle *)p->pUser; - xmin = aCoord[0]; - xmax = aCoord[1]; - ymin = aCoord[2]; - ymax = aCoord[3]; - /* Check if any of the 4 corners of the bounding-box being tested lie ** inside the circular region. If they do, then the bounding-box does ** intersect the region of interest. Set the output variable to true and @@ -161,7 +162,12 @@ static int circle_query_func(sqlite3_rtree_query_info *p){ double ymin, ymax; /* X dimensions of box being tested */ int nWithin = 0; /* Number of corners inside the circle */ - if( p->pUser==0 ){ + xmin = p->aCoord[0]; + xmax = p->aCoord[1]; + ymin = p->aCoord[2]; + ymax = p->aCoord[3]; + pCircle = (Circle *)p->pUser; + if( pCircle==0 ){ /* If pUser is still 0, then the parameter values have not been tested ** for correctness or stored into a Circle structure yet. Do this now. */ @@ -207,14 +213,9 @@ static int circle_query_func(sqlite3_rtree_query_info *p){ pCircle->aBox[1].xmax = pCircle->centerx - pCircle->radius; pCircle->aBox[1].ymin = pCircle->centery; pCircle->aBox[1].ymax = pCircle->centery; + pCircle->mxArea = 200.0*200.0; } - pCircle = (Circle *)p->pUser; - xmin = p->aCoord[0]; - xmax = p->aCoord[1]; - ymin = p->aCoord[2]; - ymax = p->aCoord[3]; - /* Check if any of the 4 corners of the bounding-box being tested lie ** inside the circular region. If they do, then the bounding-box does ** intersect the region of interest. Set the output variable to true and @@ -246,7 +247,12 @@ static int circle_query_func(sqlite3_rtree_query_info *p){ } } - p->rScore = p->iLevel; + if( p->iLevel==2 ){ + p->rScore = 1.0 - (xmax-xmin)*(ymax-ymin)/pCircle->mxArea; + if( p->rScore<0.01 ) p->rScore = 0.01; + }else{ + p->rScore = 0.0; + } if( nWithin==0 ){ p->eWithin = NOT_WITHIN; }else if( nWithin>=4 ){ From 1821cbacf15e813af181b594a6b28af2c6fb0da6 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 17 Apr 2014 15:34:58 +0000 Subject: [PATCH 0100/1484] More test cases with very long priority queues. FossilOrigin-Name: 71692aa97c78676f0ba80eaeec0ad9ac225f4427 --- ext/rtree/rtreeE.test | 67 ++++++++++++++++++++++++++++++++++++------- manifest | 14 ++++----- manifest.uuid | 2 +- src/test_rtree.c | 61 +++++++++++++++++++++++++++++++++++---- 4 files changed, 120 insertions(+), 24 deletions(-) diff --git a/ext/rtree/rtreeE.test b/ext/rtree/rtreeE.test index 14f5c332ca..bc97943dcb 100644 --- a/ext/rtree/rtreeE.test +++ b/ext/rtree/rtreeE.test @@ -27,46 +27,93 @@ register_circle_geom db do_execsql_test rtreeE-1.1 { PRAGMA page_size=512; - CREATE VIRTUAL TABLE rt2 USING rtree(id,x0,x1,y0,y1); + CREATE VIRTUAL TABLE rt1 USING rtree(id,x0,x1,y0,y1); /* A tight pattern of small boxes near 0,0 */ WITH RECURSIVE x(x) AS (VALUES(0) UNION ALL SELECT x+1 FROM x WHERE x<4), y(y) AS (VALUES(0) UNION ALL SELECT y+1 FROM y WHERE y<4) - INSERT INTO rt2 SELECT x+5*y, x, x+2, y, y+2 FROM x, y; + INSERT INTO rt1 SELECT x+5*y, x, x+2, y, y+2 FROM x, y; /* A looser pattern of small boxes near 100, 0 */ WITH RECURSIVE x(x) AS (VALUES(0) UNION ALL SELECT x+1 FROM x WHERE x<4), y(y) AS (VALUES(0) UNION ALL SELECT y+1 FROM y WHERE y<4) - INSERT INTO rt2 SELECT 100+x+5*y, x*3+100, x*3+102, y*3, y*3+2 FROM x, y; + INSERT INTO rt1 SELECT 100+x+5*y, x*3+100, x*3+102, y*3, y*3+2 FROM x, y; /* A looser pattern of larger boxes near 0, 200 */ WITH RECURSIVE x(x) AS (VALUES(0) UNION ALL SELECT x+1 FROM x WHERE x<4), y(y) AS (VALUES(0) UNION ALL SELECT y+1 FROM y WHERE y<4) - INSERT INTO rt2 SELECT 200+x+5*y, x*7, x*7+15, y*7+200, y*7+215 FROM x, y; + INSERT INTO rt1 SELECT 200+x+5*y, x*7, x*7+15, y*7+200, y*7+215 FROM x, y; } {} -if 0 { # Queries against each of the three clusters */ do_execsql_test rtreeE-1.1 { - SELECT id FROM rt2 WHERE id MATCH Qcircle(0.0, 0.0, 50.0) ORDER BY id; + SELECT id FROM rt1 WHERE id MATCH Qcircle(0.0, 0.0, 50.0, 3) ORDER BY id; } {0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24} do_execsql_test rtreeE-1.2 { - SELECT id FROM rt2 WHERE id MATCH Qcircle(100.0, 0.0, 50.0) ORDER BY id; + SELECT id FROM rt1 WHERE id MATCH Qcircle(100.0, 0.0, 50.0, 3) ORDER BY id; } {100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124} do_execsql_test rtreeE-1.3 { - SELECT id FROM rt2 WHERE id MATCH Qcircle(0.0, 200.0, 50.0) ORDER BY id; + SELECT id FROM rt1 WHERE id MATCH Qcircle(0.0, 200.0, 50.0, 3) ORDER BY id; } {200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224} -} # The Qcircle geometry function gives a lower score to larger leaf-nodes. # This causes the 200s to sort before the 100s and the 0s to sort before # last. # do_execsql_test rtreeE-1.4 { - SELECT id FROM rt2 WHERE id MATCH Qcircle(0,0,1000) AND id%100==0 + SELECT id FROM rt1 WHERE id MATCH Qcircle(0,0,1000,3) AND id%100==0 } {200 100 0} +# Construct a large 2-D RTree with thousands of random entries. +# +do_test rtreeE-2.1 { + db eval { + CREATE TABLE t2(id,x0,x1,y0,y1); + CREATE VIRTUAL TABLE rt2 USING rtree(id,x0,x1,y0,y1); + BEGIN; + } + expr srand(0) + for {set i 1} {$i<=10000} {incr i} { + set dx [expr {int(rand()*40)+1}] + set dy [expr {int(rand()*40)+1}] + set x0 [expr {int(rand()*(10000 - $dx))}] + set x1 [expr {$x0+$dx}] + set y0 [expr {int(rand()*(10000 - $dy))}] + set y1 [expr {$y0+$dy}] + set id [expr {$i+10000}] + db eval {INSERT INTO t2 VALUES($id,$x0,$x1,$y0,$y1)} + } + db eval { + INSERT INTO rt2 SELECT * FROM t2; + COMMIT; + } +} {} + +for {set i 1} {$i<=200} {incr i} { + set dx [expr {int(rand()*100)}] + set dy [expr {int(rand()*100)}] + set x0 [expr {int(rand()*(10000 - $dx))}] + set x1 [expr {$x0+$dx}] + set y0 [expr {int(rand()*(10000 - $dy))}] + set y1 [expr {$y0+$dy}] + set ans [db eval {SELECT id FROM t2 WHERE x1>=$x0 AND x0<=$x1 AND y1>=$y0 AND y0<=$y1 ORDER BY id}] + do_execsql_test rtreeE-2.2.$i { + SELECT id FROM rt2 WHERE id MATCH breadthfirstsearch($x0,$x1,$y0,$y1) ORDER BY id + } $ans +} + +# Run query that have very deep priority queues +# +set ans [db eval {SELECT id FROM t2 WHERE x1>=0 AND x0<=5000 AND y1>=0 AND y0<=5000 ORDER BY id}] +do_execsql_test rtreeE-2.3 { + SELECT id FROM rt2 WHERE id MATCH breadthfirstsearch(0,5000,0,5000) ORDER BY id +} $ans +set ans [db eval {SELECT id FROM t2 WHERE x1>=0 AND x0<=10000 AND y1>=0 AND y0<=10000 ORDER BY id}] +do_execsql_test rtreeE-2.4 { + SELECT id FROM rt2 WHERE id MATCH breadthfirstsearch(0,10000,0,10000) ORDER BY id +} $ans + finish_test diff --git a/manifest b/manifest index 63a2d6b9ce..6eb3fbb265 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Test\scases\sand\sbug\sfixes\sfor\sthe\ssqlite3_rtree_query_callback()\nmechanism. -D 2014-04-17T14:52:20.025 +C More\stest\scases\swith\svery\slong\spriority\squeues. +D 2014-04-17T15:34:58.372 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e4ee6d36cdf6136aee0158675a3b24dd3bf31a5a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -135,7 +135,7 @@ F ext/rtree/rtreeA.test ace05e729a36e342d40cf94e9efc7b4723d9dcdf F ext/rtree/rtreeB.test c85f9ce78766c4e68b8b89fbf2979ee9cfa82b4e F ext/rtree/rtreeC.test df158dcc81f1a43ce7eef361af03c48ec91f1e06 F ext/rtree/rtreeD.test 636630357638f5983701550b37f0f5867130d2ca -F ext/rtree/rtreeE.test c8c951df54fd556d30eb621ecc2acd8771970a5e +F ext/rtree/rtreeE.test 0878fd6bce3a62ac980e6f67ba14cc86c8f4f2b3 F ext/rtree/rtree_perf.tcl 6c18c1f23cd48e0f948930c98dfdd37dfccb5195 F ext/rtree/rtree_util.tcl 06aab2ed5b826545bf215fff90ecb9255a8647ea F ext/rtree/sqlite3rtree.h 488cf8834d2012b913d33683157d3cf5f1327a69 @@ -275,7 +275,7 @@ F src/test_osinst.c 90a845c8183013d80eccb1f29e8805608516edba F src/test_pcache.c a5cd24730cb43c5b18629043314548c9169abb00 F src/test_quota.c 30c64f0ef84734f2231a686df41ed882b0c59bc0 F src/test_quota.h 8761e463b25e75ebc078bd67d70e39b9c817a0cb -F src/test_rtree.c 636d2a5bc9ded2fa1df4e7d4c575eb0d3f13b334 +F src/test_rtree.c 38cdb28581d07503c9135ef73692ec8192b876b0 F src/test_schema.c cd12a2223c3a394f4d07bb93bdf6d344c5c121b6 F src/test_server.c a2615049954cbb9cfb4a62e18e2f0616e4dc38fe F src/test_sqllog.c c1c1bbedbcaf82b93d83e4f9dd990e62476a680e @@ -1176,7 +1176,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 32a13870175a1dd1d33af3572dde09ff607a04b6 -R 1f38906450e19fda5c27a4543b70f18c +P 1ccaaed6b516ec2ce953c1b31025a82ba76d00e7 +R 449eb9a5ce303ca34184a4306bd9d328 U drh -Z 26a5b86beaa061e155488cf6e80f8d30 +Z 39039e877d4cb95ab625ec95bd5cc650 diff --git a/manifest.uuid b/manifest.uuid index 07ccb10268..f923c4ba43 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1ccaaed6b516ec2ce953c1b31025a82ba76d00e7 \ No newline at end of file +71692aa97c78676f0ba80eaeec0ad9ac225f4427 \ No newline at end of file diff --git a/src/test_rtree.c b/src/test_rtree.c index c1951a896b..51e991949c 100644 --- a/src/test_rtree.c +++ b/src/test_rtree.c @@ -36,6 +36,7 @@ struct Circle { double centery; double radius; double mxArea; + int eScoreType; }; /* @@ -175,10 +176,10 @@ static int circle_query_func(sqlite3_rtree_query_info *p){ ** Return an error if the table does not have exactly 2 dimensions. */ if( p->nCoord!=4 ) return SQLITE_ERROR; - /* Test that the correct number of parameters (3) have been supplied, + /* Test that the correct number of parameters (4) have been supplied, ** and that the parameters are in range (that the radius of the circle ** radius is greater than zero). */ - if( p->nParam!=3 || p->aParam[2]<0.0 ) return SQLITE_ERROR; + if( p->nParam!=4 || p->aParam[2]<0.0 ) return SQLITE_ERROR; /* Allocate a structure to cache parameter data in. Return SQLITE_NOMEM ** if the allocation fails. */ @@ -193,6 +194,7 @@ static int circle_query_func(sqlite3_rtree_query_info *p){ pCircle->centerx = p->aParam[0]; pCircle->centery = p->aParam[1]; pCircle->radius = p->aParam[2]; + pCircle->eScoreType = (int)p->aParam[3]; /* Define two bounding box regions. The first, aBox[0], extends to ** infinity in the X dimension. It covers the same range of the Y dimension @@ -247,11 +249,21 @@ static int circle_query_func(sqlite3_rtree_query_info *p){ } } - if( p->iLevel==2 ){ - p->rScore = 1.0 - (xmax-xmin)*(ymax-ymin)/pCircle->mxArea; - if( p->rScore<0.01 ) p->rScore = 0.01; + if( pCircle->eScoreType==1 ){ + /* Depth first search */ + p->rScore = p->iLevel; + }else if( pCircle->eScoreType==2 ){ + /* Breadth first search */ + p->rScore = 100 - p->iLevel; }else{ - p->rScore = 0.0; + /* Depth-first search, except sort the leaf nodes by area with + ** the largest area first */ + if( p->iLevel==2 ){ + p->rScore = 1.0 - (xmax-xmin)*(ymax-ymin)/pCircle->mxArea; + if( p->rScore<0.01 ) p->rScore = 0.01; + }else{ + p->rScore = 0.0; + } } if( nWithin==0 ){ p->eWithin = NOT_WITHIN; @@ -262,6 +274,39 @@ static int circle_query_func(sqlite3_rtree_query_info *p){ } return SQLITE_OK; } +/* +** Implementation of "breadthfirstsearch" r-tree geometry callback using the +** 2nd-generation interface that allows scoring. +** +** ... WHERE id MATCH breadthfirstsearch($x0,$x1,$y0,$y1) ... +** +** It returns all entries whose bounding boxes overlap with $x0,$x1,$y0,$y1. +*/ +static int bfs_query_func(sqlite3_rtree_query_info *p){ + double x0,x1,y0,y1; /* Dimensions of box being tested */ + double bx0,bx1,by0,by1; /* Boundary of the query function */ + + if( p->nParam!=4 ) return SQLITE_ERROR; + x0 = p->aCoord[0]; + x1 = p->aCoord[1]; + y0 = p->aCoord[2]; + y1 = p->aCoord[3]; + bx0 = p->aParam[0]; + bx1 = p->aParam[1]; + by0 = p->aParam[2]; + by1 = p->aParam[3]; + p->rScore = 100 - p->iLevel; + if( p->eParentWithin==FULLY_WITHIN ){ + p->eWithin = FULLY_WITHIN; + }else if( x0>=bx0 && x1<=bx1 && y0>=by0 && y1<=by1 ){ + p->eWithin = FULLY_WITHIN; + }else if( x1>=bx0 && x0<=bx1 && y1>=by0 && y0<=by1 ){ + p->eWithin = PARTLY_WITHIN; + }else{ + p->eWithin = NOT_WITHIN; + } + return SQLITE_OK; +} /* END of implementation of "circle" geometry callback. ************************************************************************** @@ -402,6 +447,10 @@ static int register_circle_geom( rc = sqlite3_rtree_query_callback(db, "Qcircle", circle_query_func, 0, 0); } + if( rc==SQLITE_OK ){ + rc = sqlite3_rtree_query_callback(db, "breadthfirstsearch", + bfs_query_func, 0, 0); + } Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_STATIC); #endif return TCL_OK; From a5db90fc8ee2e7dfdd1093f9a6ed4dc27ad7f1c4 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 17 Apr 2014 23:23:29 +0000 Subject: [PATCH 0101/1484] Performance optimization on byte-swapping in R-Tree. FossilOrigin-Name: 444084fd620fc3f45cfb87b83f532d76bd2744e7 --- ext/rtree/rtree.c | 28 +++++++++++++++++++++------- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 28 insertions(+), 14 deletions(-) diff --git a/ext/rtree/rtree.c b/ext/rtree/rtree.c index 53414af7ee..620c158288 100644 --- a/ext/rtree/rtree.c +++ b/ext/rtree/rtree.c @@ -243,6 +243,7 @@ struct RtreeCursor { union RtreeCoord { RtreeValue f; /* Floating point value */ int i; /* Integer value */ + u32 u; /* Unsigned for byte-order conversions */ }; /* @@ -902,19 +903,32 @@ static int rtreeEof(sqlite3_vtab_cursor *cur){ } /* -** Convert raw bits from the on-disk RTree record into a coordinate value -** The on-disk record stores integer coordinates if eInt is true and it -** stores 32-bit floating point records if eInt is false. a[] is the four +** Convert raw bits from the on-disk RTree record into a coordinate value. +** The on-disk format is big-endian and needs to be converted for little-endian +** platforms. The on-disk record stores integer coordinates if eInt is true +** and it stores 32-bit floating point records if eInt is false. a[] is the four ** bytes of the on-disk record to be decoded. Store the results in "r". +** +** The first version of this macro is fast on x86, x86_64 and ARM, all of which +** are little-endian. The second version of this macro is cross-platform but +** takes twice as long, according to valgrind on linux x64. */ +#if defined(__x86) || defined(__x86_64) || defined(__arm__) || defined(_MSC_VER) #define RTREE_DECODE_COORD(eInt, a, r) { \ - u32 x; /* Raw bits of the coordinate value */ \ RtreeCoord c; /* Coordinate decoded */ \ - x = ((u32)a[0]<<24) + ((u32)a[1]<<16) \ - +((u32)a[2]<<8) + a[3]; \ - c.i = *(int*)&x; \ + memcpy(&c.u,a,4); \ + c.u = ((c.u>>24)&0xff)|((c.u>>8)&0xff00)| \ + ((c.u&0xff)<<24)|((c.u&0xff00)<<8); \ r = eInt ? (sqlite3_rtree_dbl)c.i : (sqlite3_rtree_dbl)c.f; \ } +#else +#define RTREE_DECODE_COORD(eInt, a, r) { \ + RtreeCoord c; /* Coordinate decoded */ \ + c.u = ((u32)a[0]<<24) + ((u32)a[1]<<16) \ + +((u32)a[2]<<8) + a[3]; \ + r = eInt ? (sqlite3_rtree_dbl)c.i : (sqlite3_rtree_dbl)c.f; \ +} +#endif /* diff --git a/manifest b/manifest index 6eb3fbb265..f00e6668a6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C More\stest\scases\swith\svery\slong\spriority\squeues. -D 2014-04-17T15:34:58.372 +C Performance\soptimization\son\sbyte-swapping\sin\sR-Tree. +D 2014-04-17T23:23:29.676 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e4ee6d36cdf6136aee0158675a3b24dd3bf31a5a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -120,7 +120,7 @@ F ext/misc/vfslog.c fe40fab5c077a40477f7e5eba994309ecac6cc95 F ext/misc/vtshim.c babb0dc2bf116029e3e7c9a618b8a1377045303e F ext/misc/wholenumber.c 784b12543d60702ebdd47da936e278aa03076212 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 -F ext/rtree/rtree.c 6a47918e44697dd32f5bba8a79d3490e56bd76c9 +F ext/rtree/rtree.c 5cf5ae21ca1742be863f025ce64e4262fc6def4c F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e F ext/rtree/rtree1.test cf679265ecafff494a768ac9c2f43a70915a6290 F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba @@ -1176,7 +1176,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 1ccaaed6b516ec2ce953c1b31025a82ba76d00e7 -R 449eb9a5ce303ca34184a4306bd9d328 +P 71692aa97c78676f0ba80eaeec0ad9ac225f4427 +R f1ebd50a7930430ccdb2dd222ebc5021 U drh -Z 39039e877d4cb95ab625ec95bd5cc650 +Z 8e204d3bb697cd291df3586d6cea66ab diff --git a/manifest.uuid b/manifest.uuid index f923c4ba43..41369a2d98 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -71692aa97c78676f0ba80eaeec0ad9ac225f4427 \ No newline at end of file +444084fd620fc3f45cfb87b83f532d76bd2744e7 \ No newline at end of file From ec7c03a08ba8fa274c38dca3d00c83ea0b518286 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 18 Apr 2014 01:37:08 +0000 Subject: [PATCH 0102/1484] Further improvements to the RTREE_DECODE_COORD() method, to take advantage of known processor byte orders when available. This makes the code 3% faster, according to valgrind. Also add test cases to make sure the on-disk representation is correct. FossilOrigin-Name: 6f3e94f4b1b403cd7bfc5e8e0ffbd61b5174d3a4 --- ext/rtree/rtree.c | 34 +++++++++++++++++++++++----------- ext/rtree/rtree1.test | 19 +++++++++++-------- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 42 insertions(+), 27 deletions(-) diff --git a/ext/rtree/rtree.c b/ext/rtree/rtree.c index 620c158288..bcaa4d635a 100644 --- a/ext/rtree/rtree.c +++ b/ext/rtree/rtree.c @@ -904,16 +904,21 @@ static int rtreeEof(sqlite3_vtab_cursor *cur){ /* ** Convert raw bits from the on-disk RTree record into a coordinate value. -** The on-disk format is big-endian and needs to be converted for little-endian -** platforms. The on-disk record stores integer coordinates if eInt is true -** and it stores 32-bit floating point records if eInt is false. a[] is the four -** bytes of the on-disk record to be decoded. Store the results in "r". +** The on-disk format is big-endian and needs to be converted for little- +** endian platforms. The on-disk record stores integer coordinates if +** eInt is true and it stores 32-bit floating point records if eInt is +** false. a[] is the four bytes of the on-disk record to be decoded. +** Store the results in "r". ** -** The first version of this macro is fast on x86, x86_64 and ARM, all of which -** are little-endian. The second version of this macro is cross-platform but -** takes twice as long, according to valgrind on linux x64. +** There are three versions of this macro, one each for little-endian and +** big-endian processors and a third generic implementation. The endian- +** specific implementations are much faster and are preferred if the +** processor endianness is known at compile-time. The SQLITE_BYTEORDER +** macro is part of sqliteInt.h and hence the endian-specific +** implementation will only be used if this module is compiled as part +** of the amalgamation. */ -#if defined(__x86) || defined(__x86_64) || defined(__arm__) || defined(_MSC_VER) +#if defined(SQLITE_BYTEORDER) && SQLITE_BYTEORDER==1234 #define RTREE_DECODE_COORD(eInt, a, r) { \ RtreeCoord c; /* Coordinate decoded */ \ memcpy(&c.u,a,4); \ @@ -921,6 +926,12 @@ static int rtreeEof(sqlite3_vtab_cursor *cur){ ((c.u&0xff)<<24)|((c.u&0xff00)<<8); \ r = eInt ? (sqlite3_rtree_dbl)c.i : (sqlite3_rtree_dbl)c.f; \ } +#elif defined(SQLITE_BYTEORDER) && SQLITE_BYTEORDER==4321 +#define RTREE_DECODE_COORD(eInt, a, r) { \ + RtreeCoord c; /* Coordinate decoded */ \ + memcpy(&c.u,a,4); \ + r = eInt ? (sqlite3_rtree_dbl)c.i : (sqlite3_rtree_dbl)c.f; \ +} #else #define RTREE_DECODE_COORD(eInt, a, r) { \ RtreeCoord c; /* Coordinate decoded */ \ @@ -929,7 +940,6 @@ static int rtreeEof(sqlite3_vtab_cursor *cur){ r = eInt ? (sqlite3_rtree_dbl)c.i : (sqlite3_rtree_dbl)c.f; \ } #endif - /* ** Check the RTree node or entry given by pCellData and p against the MATCH @@ -2242,7 +2252,8 @@ static int SplitNode( memset(pLeft->zData, 0, pRtree->iNodeSize); memset(pRight->zData, 0, pRtree->iNodeSize); - rc = splitNodeStartree(pRtree, aCell, nCell, pLeft, pRight,&leftbbox,&rightbbox); + rc = splitNodeStartree(pRtree, aCell, nCell, pLeft, pRight, + &leftbbox, &rightbbox); if( rc!=SQLITE_OK ){ goto splitnode_out; } @@ -3003,7 +3014,8 @@ static int rtreeSqlInit( char *zCreate = sqlite3_mprintf( "CREATE TABLE \"%w\".\"%w_node\"(nodeno INTEGER PRIMARY KEY, data BLOB);" "CREATE TABLE \"%w\".\"%w_rowid\"(rowid INTEGER PRIMARY KEY, nodeno INTEGER);" -"CREATE TABLE \"%w\".\"%w_parent\"(nodeno INTEGER PRIMARY KEY, parentnode INTEGER);" +"CREATE TABLE \"%w\".\"%w_parent\"(nodeno INTEGER PRIMARY KEY," + " parentnode INTEGER);" "INSERT INTO '%q'.'%q_node' VALUES(1, zeroblob(%d))", zDb, zPrefix, zDb, zPrefix, zDb, zPrefix, zDb, zPrefix, pRtree->iNodeSize ); diff --git a/ext/rtree/rtree1.test b/ext/rtree/rtree1.test index 275b13264f..9de5362781 100644 --- a/ext/rtree/rtree1.test +++ b/ext/rtree/rtree1.test @@ -120,12 +120,13 @@ proc execsql_intout {sql} { # Test that it is possible to open an existing database that contains # r-tree tables. # -do_test rtree-1.4.1 { - execsql { - CREATE VIRTUAL TABLE t1 USING rtree(ii, x1, x2); - INSERT INTO t1 VALUES(1, 5.0, 10.0); - INSERT INTO t1 VALUES(2, 15.0, 20.0); - } +do_execsql_test rtree-1.4.1a { + CREATE VIRTUAL TABLE t1 USING rtree(ii, x1, x2); + INSERT INTO t1 VALUES(1, 5.0, 10.0); + SELECT substr(hex(data),1,40) FROM t1_node; +} {00000001000000000000000140A0000041200000} +do_execsql_test rtree-1.4.1b { + INSERT INTO t1 VALUES(2, 15.0, 20.0); } {} do_test rtree-1.4.2 { db close @@ -435,16 +436,18 @@ do_test rtree-11.2 { # Test on-conflict clause handling. # db_delete_and_reopen -do_execsql_test 12.0 { +do_execsql_test 12.0.1 { CREATE VIRTUAL TABLE t1 USING rtree_i32(idx, x1, x2, y1, y2); INSERT INTO t1 VALUES(1, 1, 2, 3, 4); + SELECT substr(hex(data),1,56) FROM t1_node; +} {00000001000000000000000100000001000000020000000300000004} +do_execsql_test 12.0.2 { INSERT INTO t1 VALUES(2, 2, 3, 4, 5); INSERT INTO t1 VALUES(3, 3, 4, 5, 6); CREATE TABLE source(idx, x1, x2, y1, y2); INSERT INTO source VALUES(5, 8, 8, 8, 8); INSERT INTO source VALUES(2, 7, 7, 7, 7); - } db_save_and_close foreach {tn sql_template testdata} { diff --git a/manifest b/manifest index 967e3767a3..760724c749 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sthe\slatest\schanges\sfrom\ssessions. -D 2014-04-18T01:14:46.009 +C Further\simprovements\sto\sthe\sRTREE_DECODE_COORD()\smethod,\sto\stake\sadvantage\nof\sknown\sprocessor\sbyte\sorders\swhen\savailable.\s\sThis\smakes\sthe\scode\s3%\sfaster,\naccording\sto\svalgrind.\s\sAlso\sadd\stest\scases\sto\smake\ssure\sthe\son-disk\nrepresentation\sis\scorrect. +D 2014-04-18T01:37:08.946 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e4ee6d36cdf6136aee0158675a3b24dd3bf31a5a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -120,9 +120,9 @@ F ext/misc/vfslog.c fe40fab5c077a40477f7e5eba994309ecac6cc95 F ext/misc/vtshim.c babb0dc2bf116029e3e7c9a618b8a1377045303e F ext/misc/wholenumber.c 784b12543d60702ebdd47da936e278aa03076212 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 -F ext/rtree/rtree.c 5cf5ae21ca1742be863f025ce64e4262fc6def4c +F ext/rtree/rtree.c b8357523ca0aa01ec8efffdec0868909e3744257 F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e -F ext/rtree/rtree1.test cf679265ecafff494a768ac9c2f43a70915a6290 +F ext/rtree/rtree1.test e2da4aaa426918d27122d1a1066c6ecf8409a514 F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba F ext/rtree/rtree3.test a494da55c30ee0bc9b01a91c80c81b387b22d2dc F ext/rtree/rtree4.test c8fe384f60ebd49540a5fecc990041bf452eb6e0 @@ -1177,7 +1177,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 444084fd620fc3f45cfb87b83f532d76bd2744e7 95e77efe076ab421bd246119c47dba5dacf9d087 -R e9845f4b2c71a18e1d378888de7ae7a2 +P d9eef5b03c7c4bb69c11eda41152ee81aed1cac7 +R fd5f15a432e8499b9e125ee6ec5ed14e U drh -Z 0c4fc380d884463ecab3c74420a85e5e +Z 4e8eac956a9a7b7e58efbf89636dab07 diff --git a/manifest.uuid b/manifest.uuid index 2112ab381a..ddcb25049d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d9eef5b03c7c4bb69c11eda41152ee81aed1cac7 \ No newline at end of file +6f3e94f4b1b403cd7bfc5e8e0ffbd61b5174d3a4 \ No newline at end of file From a6ca7f2c1bb27886702423d9217c6ab9d63edd0a Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 21 Apr 2014 15:21:19 +0000 Subject: [PATCH 0103/1484] Fix an off-by-one error in setting the "iLevel" field of the sqlite3_rtree_query_info structure passed into the RTree query callback. FossilOrigin-Name: d708f159abfb3b87e2844463088d4fb7f8da9c97 --- ext/rtree/rtree.c | 2 +- manifest | 14 +++++++------- manifest.uuid | 2 +- src/test_rtree.c | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/ext/rtree/rtree.c b/ext/rtree/rtree.c index bcaa4d635a..4f843a3d46 100644 --- a/ext/rtree/rtree.c +++ b/ext/rtree/rtree.c @@ -973,7 +973,7 @@ static int rtreeCallbackConstraint( *prScore = RTREE_ZERO; }else{ pInfo->aCoord = aCoord; - pInfo->iLevel = pSearch->iLevel; + pInfo->iLevel = pSearch->iLevel - 1; pInfo->rScore = pInfo->rParentScore = pSearch->rScore; pInfo->eWithin = pInfo->eParentWithin = pSearch->eWithin; rc = pConstraint->u.xQueryFunc(pInfo); diff --git a/manifest b/manifest index 760724c749..dd1b8e9de2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Further\simprovements\sto\sthe\sRTREE_DECODE_COORD()\smethod,\sto\stake\sadvantage\nof\sknown\sprocessor\sbyte\sorders\swhen\savailable.\s\sThis\smakes\sthe\scode\s3%\sfaster,\naccording\sto\svalgrind.\s\sAlso\sadd\stest\scases\sto\smake\ssure\sthe\son-disk\nrepresentation\sis\scorrect. -D 2014-04-18T01:37:08.946 +C Fix\san\soff-by-one\serror\sin\ssetting\sthe\s"iLevel"\sfield\sof\sthe\nsqlite3_rtree_query_info\sstructure\spassed\sinto\sthe\sRTree\squery\scallback. +D 2014-04-21T15:21:19.367 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e4ee6d36cdf6136aee0158675a3b24dd3bf31a5a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -120,7 +120,7 @@ F ext/misc/vfslog.c fe40fab5c077a40477f7e5eba994309ecac6cc95 F ext/misc/vtshim.c babb0dc2bf116029e3e7c9a618b8a1377045303e F ext/misc/wholenumber.c 784b12543d60702ebdd47da936e278aa03076212 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 -F ext/rtree/rtree.c b8357523ca0aa01ec8efffdec0868909e3744257 +F ext/rtree/rtree.c 09000d72086c21979960426bc9b592a6007bfb8d F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e F ext/rtree/rtree1.test e2da4aaa426918d27122d1a1066c6ecf8409a514 F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba @@ -275,7 +275,7 @@ F src/test_osinst.c 90a845c8183013d80eccb1f29e8805608516edba F src/test_pcache.c a5cd24730cb43c5b18629043314548c9169abb00 F src/test_quota.c 30c64f0ef84734f2231a686df41ed882b0c59bc0 F src/test_quota.h 8761e463b25e75ebc078bd67d70e39b9c817a0cb -F src/test_rtree.c 38cdb28581d07503c9135ef73692ec8192b876b0 +F src/test_rtree.c 4c1ff96a2d3a84e6a12fe8643e6d46dae0ef11de F src/test_schema.c cd12a2223c3a394f4d07bb93bdf6d344c5c121b6 F src/test_server.c a2615049954cbb9cfb4a62e18e2f0616e4dc38fe F src/test_sqllog.c c1c1bbedbcaf82b93d83e4f9dd990e62476a680e @@ -1177,7 +1177,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P d9eef5b03c7c4bb69c11eda41152ee81aed1cac7 -R fd5f15a432e8499b9e125ee6ec5ed14e +P 6f3e94f4b1b403cd7bfc5e8e0ffbd61b5174d3a4 +R 9cd9b8456e5c8aff94fe9550b50b870a U drh -Z 4e8eac956a9a7b7e58efbf89636dab07 +Z 1f57c8fdc97d1a8a65988c09a5e9a0f3 diff --git a/manifest.uuid b/manifest.uuid index ddcb25049d..89bf0fdeca 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6f3e94f4b1b403cd7bfc5e8e0ffbd61b5174d3a4 \ No newline at end of file +d708f159abfb3b87e2844463088d4fb7f8da9c97 \ No newline at end of file diff --git a/src/test_rtree.c b/src/test_rtree.c index 51e991949c..eb918ac5fd 100644 --- a/src/test_rtree.c +++ b/src/test_rtree.c @@ -258,7 +258,7 @@ static int circle_query_func(sqlite3_rtree_query_info *p){ }else{ /* Depth-first search, except sort the leaf nodes by area with ** the largest area first */ - if( p->iLevel==2 ){ + if( p->iLevel==1 ){ p->rScore = 1.0 - (xmax-xmin)*(ymax-ymin)/pCircle->mxArea; if( p->rScore<0.01 ) p->rScore = 0.01; }else{ From 74188329ce6084e428e3fa9ddc9d1c5419819718 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 21 Apr 2014 15:53:45 +0000 Subject: [PATCH 0104/1484] Be sure to initialize the sqlite3_rtree_query_info.iRowid field for the leaves of the R-Tree when doing a query callback search. FossilOrigin-Name: 4394693882c04c19ebe87ef7547c57e679554397 --- ext/rtree/rtree.c | 3 +++ manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/ext/rtree/rtree.c b/ext/rtree/rtree.c index 4f843a3d46..a471514c53 100644 --- a/ext/rtree/rtree.c +++ b/ext/rtree/rtree.c @@ -962,6 +962,9 @@ static int rtreeCallbackConstraint( assert( pConstraint->op==RTREE_MATCH || pConstraint->op==RTREE_QUERY ); assert( nCoord==2 || nCoord==4 || nCoord==6 || nCoord==8 || nCoord==10 ); + if( pConstraint->op==RTREE_MATCH && pSearch->iLevel==1 ){ + pInfo->iRowid = readInt64(pCellData); + } pCellData += 8; for(i=0; i Date: Mon, 21 Apr 2014 18:13:37 +0000 Subject: [PATCH 0105/1484] Fix the generation of sqlite3_rtree_query_info.iRowid and add test cases to verify that it is fixed. FossilOrigin-Name: eba95ead49f8f8ce45d400186562ff0066537c5c --- ext/rtree/rtree.c | 2 +- ext/rtree/rtreeE.test | 10 ++++++++++ manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/test_rtree.c | 10 +++++++++- 5 files changed, 29 insertions(+), 11 deletions(-) diff --git a/ext/rtree/rtree.c b/ext/rtree/rtree.c index a471514c53..a6c99cb9ee 100644 --- a/ext/rtree/rtree.c +++ b/ext/rtree/rtree.c @@ -962,7 +962,7 @@ static int rtreeCallbackConstraint( assert( pConstraint->op==RTREE_MATCH || pConstraint->op==RTREE_QUERY ); assert( nCoord==2 || nCoord==4 || nCoord==6 || nCoord==8 || nCoord==10 ); - if( pConstraint->op==RTREE_MATCH && pSearch->iLevel==1 ){ + if( pConstraint->op==RTREE_QUERY && pSearch->iLevel==1 ){ pInfo->iRowid = readInt64(pCellData); } pCellData += 8; diff --git a/ext/rtree/rtreeE.test b/ext/rtree/rtreeE.test index bc97943dcb..c450623790 100644 --- a/ext/rtree/rtreeE.test +++ b/ext/rtree/rtreeE.test @@ -67,6 +67,16 @@ do_execsql_test rtreeE-1.4 { SELECT id FROM rt1 WHERE id MATCH Qcircle(0,0,1000,3) AND id%100==0 } {200 100 0} +# Exclude odd rowids on a depth-first search +do_execsql_test rtreeE-1.5 { + SELECT id FROM rt1 WHERE id MATCH Qcircle(0,0,1000,4) ORDER BY +id +} {0 2 4 6 8 10 12 14 16 18 20 22 24 100 102 104 106 108 110 112 114 116 118 120 122 124 200 202 204 206 208 210 212 214 216 218 220 222 224} + +# Exclude odd rowids on a breadth-first search. +do_execsql_test rtreeE-1.6 { + SELECT id FROM rt1 WHERE id MATCH Qcircle(0,0,1000,5) ORDER BY +id +} {0 2 4 6 8 10 12 14 16 18 20 22 24 100 102 104 106 108 110 112 114 116 118 120 122 124 200 202 204 206 208 210 212 214 216 218 220 222 224} + # Construct a large 2-D RTree with thousands of random entries. # do_test rtreeE-2.1 { diff --git a/manifest b/manifest index 992786f329..a115e0886e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Be\ssure\sto\sinitialize\sthe\ssqlite3_rtree_query_info.iRowid\sfield\sfor\sthe\nleaves\sof\sthe\sR-Tree\swhen\sdoing\sa\squery\scallback\ssearch. -D 2014-04-21T15:53:45.432 +C Fix\sthe\sgeneration\sof\ssqlite3_rtree_query_info.iRowid\sand\sadd\stest\scases\nto\sverify\sthat\sit\sis\sfixed. +D 2014-04-21T18:13:37.363 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e4ee6d36cdf6136aee0158675a3b24dd3bf31a5a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -120,7 +120,7 @@ F ext/misc/vfslog.c fe40fab5c077a40477f7e5eba994309ecac6cc95 F ext/misc/vtshim.c babb0dc2bf116029e3e7c9a618b8a1377045303e F ext/misc/wholenumber.c 784b12543d60702ebdd47da936e278aa03076212 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 -F ext/rtree/rtree.c 2474c438614edfc171bd9a85e3374f732511d962 +F ext/rtree/rtree.c 77fdd459e7edf78a385a83930e2b072b2f0131b5 F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e F ext/rtree/rtree1.test e2da4aaa426918d27122d1a1066c6ecf8409a514 F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba @@ -135,7 +135,7 @@ F ext/rtree/rtreeA.test ace05e729a36e342d40cf94e9efc7b4723d9dcdf F ext/rtree/rtreeB.test c85f9ce78766c4e68b8b89fbf2979ee9cfa82b4e F ext/rtree/rtreeC.test df158dcc81f1a43ce7eef361af03c48ec91f1e06 F ext/rtree/rtreeD.test 636630357638f5983701550b37f0f5867130d2ca -F ext/rtree/rtreeE.test 0878fd6bce3a62ac980e6f67ba14cc86c8f4f2b3 +F ext/rtree/rtreeE.test 388c1c8602c3ce55c15f03b509e9cf545fb7c41f F ext/rtree/rtree_perf.tcl 6c18c1f23cd48e0f948930c98dfdd37dfccb5195 F ext/rtree/rtree_util.tcl 06aab2ed5b826545bf215fff90ecb9255a8647ea F ext/rtree/sqlite3rtree.h 488cf8834d2012b913d33683157d3cf5f1327a69 @@ -275,7 +275,7 @@ F src/test_osinst.c 90a845c8183013d80eccb1f29e8805608516edba F src/test_pcache.c a5cd24730cb43c5b18629043314548c9169abb00 F src/test_quota.c 30c64f0ef84734f2231a686df41ed882b0c59bc0 F src/test_quota.h 8761e463b25e75ebc078bd67d70e39b9c817a0cb -F src/test_rtree.c 4c1ff96a2d3a84e6a12fe8643e6d46dae0ef11de +F src/test_rtree.c fdd8d29ca5165c7857987a2ba263fac5c69e231f F src/test_schema.c cd12a2223c3a394f4d07bb93bdf6d344c5c121b6 F src/test_server.c a2615049954cbb9cfb4a62e18e2f0616e4dc38fe F src/test_sqllog.c c1c1bbedbcaf82b93d83e4f9dd990e62476a680e @@ -1177,7 +1177,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P d708f159abfb3b87e2844463088d4fb7f8da9c97 -R b6276022832016ce4c25e5317a578a57 +P 4394693882c04c19ebe87ef7547c57e679554397 +R 9a6527f0d42b13ef1dcd87b1f989aba6 U drh -Z 8b38b422713df2439dae120af50d35b5 +Z 8819b772d7d2f245af8d8a9675d9c9d8 diff --git a/manifest.uuid b/manifest.uuid index ceffd746e2..d92fc37198 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4394693882c04c19ebe87ef7547c57e679554397 \ No newline at end of file +eba95ead49f8f8ce45d400186562ff0066537c5c \ No newline at end of file diff --git a/src/test_rtree.c b/src/test_rtree.c index eb918ac5fd..9d19fa0e2c 100644 --- a/src/test_rtree.c +++ b/src/test_rtree.c @@ -255,7 +255,7 @@ static int circle_query_func(sqlite3_rtree_query_info *p){ }else if( pCircle->eScoreType==2 ){ /* Breadth first search */ p->rScore = 100 - p->iLevel; - }else{ + }else if( pCircle->eScoreType==3 ){ /* Depth-first search, except sort the leaf nodes by area with ** the largest area first */ if( p->iLevel==1 ){ @@ -264,6 +264,14 @@ static int circle_query_func(sqlite3_rtree_query_info *p){ }else{ p->rScore = 0.0; } + }else if( pCircle->eScoreType==4 ){ + /* Depth-first search, except exclude odd rowids */ + p->rScore = p->iLevel; + if( p->iRowid&1 ) nWithin = 0; + }else{ + /* Breadth-first search, except exclude odd rowids */ + p->rScore = 100 - p->iLevel; + if( p->iRowid&1 ) nWithin = 0; } if( nWithin==0 ){ p->eWithin = NOT_WITHIN; From c686929914188d138527dcf460c025ef4b3638e9 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 25 Apr 2014 16:29:03 +0000 Subject: [PATCH 0106/1484] Enhance the sqlite3_rtree_query_info object to report on the number of elements in the priority queue at each level. FossilOrigin-Name: f7dad408dd46a1e3612b6142a3afb1d0d4fcda00 --- ext/rtree/rtree.c | 20 ++++++++++++++------ ext/rtree/sqlite3rtree.h | 2 ++ manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 24 insertions(+), 14 deletions(-) diff --git a/ext/rtree/rtree.c b/ext/rtree/rtree.c index a6c99cb9ee..7b540b4be1 100644 --- a/ext/rtree/rtree.c +++ b/ext/rtree/rtree.c @@ -228,9 +228,11 @@ struct RtreeCursor { RtreeConstraint *aConstraint; /* Search constraints. */ int nPointAlloc; /* Number of slots allocated for aPoint[] */ int nPoint; /* Number of slots used in aPoint[] */ + int mxLevel; /* iLevel value for root of the tree */ RtreeSearchPoint *aPoint; /* Priority queue for search points */ RtreeSearchPoint sPoint; /* Cached next search point */ RtreeNode *aNode[RTREE_CACHE_SZ]; /* Rtree node cache */ + u32 anQueue[RTREE_MAX_DEPTH+1]; /* Number of queued entries by iLevel */ }; /* Return the Rtree of a RtreeCursor */ @@ -1179,7 +1181,8 @@ static RtreeSearchPoint *rtreeEnqueue( i = pCur->nPoint++; pNew = pCur->aPoint + i; pNew->rScore = rScore; - pNew->iLevel = iLevel; + pNew->iLevel = iLevel; + assert( iLevel>=0 && iLevel<=RTREE_MAX_DEPTH ); while( i>0 ){ RtreeSearchPoint *pParent; j = (i-1)/2; @@ -1203,6 +1206,7 @@ static RtreeSearchPoint *rtreeSearchPointNew( ){ RtreeSearchPoint *pNew, *pFirst; pFirst = rtreeSearchPointFirst(pCur); + pCur->anQueue[iLevel]++; if( pFirst==0 || pFirst->rScore>rScore || (pFirst->rScore==rScore && pFirst->iLevel>iLevel) @@ -1271,8 +1275,10 @@ static void rtreeSearchPointPop(RtreeCursor *p){ p->aNode[i] = 0; } if( p->bPoint ){ + p->anQueue[p->sPoint.iLevel]--; p->bPoint = 0; }else if( p->nPoint ){ + p->anQueue[p->aPoint[0].iLevel]--; n = --p->nPoint; p->aPoint[0] = p->aPoint[n]; if( n0 ){ + rc = nodeAcquire(pRtree, 1, 0, &pRoot); + if( rc==SQLITE_OK && argc>0 ){ pCsr->aConstraint = sqlite3_malloc(sizeof(RtreeConstraint)*argc); pCsr->nConstraint = argc; if( !pCsr->aConstraint ){ rc = SQLITE_NOMEM; }else{ memset(pCsr->aConstraint, 0, sizeof(RtreeConstraint)*argc); + memset(pCsr->anQueue, 0, sizeof(u32)*(pRtree->iDepth + 1)); assert( (idxStr==0 && argc==0) || (idxStr && (int)strlen(idxStr)==argc*2) ); for(ii=0; iipInfo->nCoord = pRtree->nDim*2; + p->pInfo->anQueue = pCsr->anQueue; + p->pInfo->mxLevel = pRtree->iDepth + 1; }else{ #ifdef SQLITE_RTREE_INT_ONLY p->u.rValue = sqlite3_value_int64(argv[ii]); @@ -1586,10 +1596,6 @@ static int rtreeFilter( } } } - - if( rc==SQLITE_OK ){ - rc = nodeAcquire(pRtree, 1, 0, &pRoot); - } if( rc==SQLITE_OK ){ RtreeSearchPoint *pNew; pNew = rtreeSearchPointNew(pCsr, RTREE_ZERO, pRtree->iDepth+1); @@ -1599,11 +1605,13 @@ static int rtreeFilter( pNew->eWithin = PARTLY_WITHIN; assert( pCsr->bPoint==1 ); pCsr->aNode[0] = pRoot; + pRoot = 0; RTREE_QUEUE_TRACE(pCsr, "PUSH-Fm:"); rc = rtreeStepToLeaf(pCsr); } } + nodeRelease(pRtree, pRoot); rtreeRelease(pRtree); return rc; } diff --git a/ext/rtree/sqlite3rtree.h b/ext/rtree/sqlite3rtree.h index 3f4df4ed89..5de0508d00 100644 --- a/ext/rtree/sqlite3rtree.h +++ b/ext/rtree/sqlite3rtree.h @@ -89,8 +89,10 @@ struct sqlite3_rtree_query_info { void *pUser; /* callback can use this, if desired */ void (*xDelUser)(void*); /* function to free pUser */ sqlite3_rtree_dbl *aCoord; /* Coordinates of node or entry to check */ + unsigned int *anQueue; /* Number of pending entries in the queue */ int nCoord; /* Number of coordinates */ int iLevel; /* Level of current node or entry */ + int mxLevel; /* The largest iLevel value in the tree */ sqlite3_int64 iRowid; /* Rowid for current entry */ sqlite3_rtree_dbl rParentScore; /* Score of parent node */ int eParentWithin; /* Visibility of parent node */ diff --git a/manifest b/manifest index a115e0886e..707f14a0a3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\sgeneration\sof\ssqlite3_rtree_query_info.iRowid\sand\sadd\stest\scases\nto\sverify\sthat\sit\sis\sfixed. -D 2014-04-21T18:13:37.363 +C Enhance\sthe\ssqlite3_rtree_query_info\sobject\sto\sreport\son\sthe\snumber\sof\s\nelements\sin\sthe\spriority\squeue\sat\seach\slevel. +D 2014-04-25T16:29:03.796 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e4ee6d36cdf6136aee0158675a3b24dd3bf31a5a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -120,7 +120,7 @@ F ext/misc/vfslog.c fe40fab5c077a40477f7e5eba994309ecac6cc95 F ext/misc/vtshim.c babb0dc2bf116029e3e7c9a618b8a1377045303e F ext/misc/wholenumber.c 784b12543d60702ebdd47da936e278aa03076212 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 -F ext/rtree/rtree.c 77fdd459e7edf78a385a83930e2b072b2f0131b5 +F ext/rtree/rtree.c 6f70db93e0e42c369325c5cddcf2024c5a87ca43 F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e F ext/rtree/rtree1.test e2da4aaa426918d27122d1a1066c6ecf8409a514 F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba @@ -138,7 +138,7 @@ F ext/rtree/rtreeD.test 636630357638f5983701550b37f0f5867130d2ca F ext/rtree/rtreeE.test 388c1c8602c3ce55c15f03b509e9cf545fb7c41f F ext/rtree/rtree_perf.tcl 6c18c1f23cd48e0f948930c98dfdd37dfccb5195 F ext/rtree/rtree_util.tcl 06aab2ed5b826545bf215fff90ecb9255a8647ea -F ext/rtree/sqlite3rtree.h 488cf8834d2012b913d33683157d3cf5f1327a69 +F ext/rtree/sqlite3rtree.h 83349d519fe5f518b3ea025d18dd1fe51b1684bd F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 F ext/session/session1.test 894e3bc9f497c4fa07a2aa3271e3911f3670c3d8 @@ -1177,7 +1177,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 4394693882c04c19ebe87ef7547c57e679554397 -R 9a6527f0d42b13ef1dcd87b1f989aba6 +P eba95ead49f8f8ce45d400186562ff0066537c5c +R efef19137bd31aa6c6fdc7dea3b8daf2 U drh -Z 8819b772d7d2f245af8d8a9675d9c9d8 +Z ded30c2c8b9ed7281fad6af13254832e diff --git a/manifest.uuid b/manifest.uuid index d92fc37198..8909227722 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -eba95ead49f8f8ce45d400186562ff0066537c5c \ No newline at end of file +f7dad408dd46a1e3612b6142a3afb1d0d4fcda00 \ No newline at end of file From 0894993e888cccd60c4b6698dce17ce000bfb27d Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 6 Aug 2014 11:49:31 +0000 Subject: [PATCH 0107/1484] Fix an obsolete comment in the func.c source file. No changes to code. FossilOrigin-Name: 7a145c9409e70b92946534eb44c2e205f7309897 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/func.c | 9 +++------ 3 files changed, 10 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 25d96a1c40..80a3330a4d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sin\sthe\sfix\sfor\sthe\sInterlockedCompareExchange()\sbuild\sissue. -D 2014-08-06T03:16:56.688 +C Fix\san\sobsolete\scomment\sin\sthe\sfunc.c\ssource\sfile.\s\sNo\schanges\sto\scode. +D 2014-08-06T11:49:31.740 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 639859a6f81bd15921ccd56ddbd6dfd335278377 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -193,7 +193,7 @@ F src/delete.c 50b74c1dde25d1ebcb4fa5c870762e6470ee46f1 F src/expr.c f749009cf4a8534efb5e0d5cd7c9fb1fb0f2836c F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 8545f3b36da47473e10800ea4fb0810fd4062514 -F src/func.c 3bc223ea36cd29a91c481485343d0ee4257ab8dc +F src/func.c bbb724b74ed96ca42675a7274646a71dd52bcda7 F src/global.c 1e4bd956dc2f608f87d2a929abc4a20db65f30e4 F src/hash.c d139319967164f139c8d1bb8a11b14db9c4ba3cd F src/hash.h 8890a25af81fb85a9ad7790d32eedab4b994da22 @@ -1200,7 +1200,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 68a6d5e2f43702c78057ae2f2a7345c981d24e17 7be244ce129d6502f3a3e3f3e8a1dd61ef71d878 -R 895a81415e1d620e3196223591337e06 +P 091aa5f1047f0ec984a69ab1f356c1960813b77b +R f8322f66146340bee955eb1bc05e0bbb U drh -Z 282de6283138a0396ca3a1a5b524cbe0 +Z 2907f648c6e2ceca10c49409542f13ae diff --git a/manifest.uuid b/manifest.uuid index 96790e8187..374a6b101e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -091aa5f1047f0ec984a69ab1f356c1960813b77b \ No newline at end of file +7a145c9409e70b92946534eb44c2e205f7309897 \ No newline at end of file diff --git a/src/func.c b/src/func.c index efbb3efbb7..dbc8375541 100644 --- a/src/func.c +++ b/src/func.c @@ -9,12 +9,9 @@ ** May you share freely, never taking more than you give. ** ************************************************************************* -** This file contains the C functions that implement various SQL -** functions of SQLite. -** -** There is only one exported symbol in this file - the function -** sqliteRegisterBuildinFunctions() found at the bottom of the file. -** All other code has file scope. +** This file contains the C-language implementions for many of the SQL +** functions of SQLite. (Some function, and in particular the date and +** time functions, are implemented separately.) */ #include "sqliteInt.h" #include From 73b3c055904e82ad4e4f1081ee42413a31c8efc9 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 15 Aug 2014 20:15:49 +0000 Subject: [PATCH 0108/1484] Begin adding the sqlite3session_patchset() API to the sessions extension. This is an interim commit. FossilOrigin-Name: 60a4565a8c44762a002cd02979317df5ca47e899 --- ext/session/sessionB.test | 233 +++++++++++++++++++++++++++++++++++ ext/session/sqlite3session.c | 213 ++++++++++++++++++++++++++------ ext/session/sqlite3session.h | 9 ++ ext/session/test_session.c | 8 +- manifest | 19 +-- manifest.uuid | 2 +- 6 files changed, 435 insertions(+), 49 deletions(-) create mode 100644 ext/session/sessionB.test diff --git a/ext/session/sessionB.test b/ext/session/sessionB.test new file mode 100644 index 0000000000..76213d8ab2 --- /dev/null +++ b/ext/session/sessionB.test @@ -0,0 +1,233 @@ +# 2014 August 16 +# +# 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 regression tests for sessions SQLite extension. +# Specifically, this file contains tests for "patchset" changes. +# + +if {![info exists testdir]} { + set testdir [file join [file dirname [info script]] .. .. test] +} +source [file join [file dirname [info script]] session_common.tcl] +source $testdir/tester.tcl +ifcapable !session {finish_test; return} + +set testprefix sessionB + +# +# 1.*: Test that the blobs returned by the session_patchset() API are +# as expected. Also the sqlite3_changeset_iter functions. +# +# 2.*: Test that patchset blobs are handled by sqlite3changeset_apply(). +# +# 3.*: Test that sqlite3changeset_invert() works with patchset blobs. +# Correct behaviour is to return SQLITE_CORRUPT. + +proc do_patchset_test {tn session res} { + set r [list] + foreach x $res {lappend r $x} + uplevel do_test $tn [list [subst -nocommands { + set x [list] + sqlite3session_foreach c [$session patchset] { lappend x [set c] } + set x + }]] [list $r] +} + +proc do_sql2patchset_test {tn sql res} { + sqlite3session S db main + S attach * + execsql $sql + uplevel [list do_patchset_test $tn S $res] + S delete +} + +#------------------------------------------------------------------------- +# Run simple tests of the _patchset() API. +# +do_execsql_test 1.0 { + CREATE TABLE t1(a, b, c, d, PRIMARY KEY(d, a)); + INSERT INTO t1 VALUES(1, 2, 3, 4); + INSERT INTO t1 VALUES(5, 6, 7, 8); + INSERT INTO t1 VALUES(9, 10, 11, 12); +} + +do_test 1.1 { + sqlite3session S db main + S attach t1 + execsql { + INSERT INTO t1 VALUES('w', 'x', 'y', 'z'); + DELETE FROM t1 WHERE d=4; + UPDATE t1 SET c = 14 WHERE a=5; + } +} {} + +do_patchset_test 1.2 S { + {UPDATE t1 0 X..X {i 5 {} {} {} {} i 8} {{} {} {} {} i 14 {} {}}} + {INSERT t1 0 X..X {} {t w t x t y t z}} + {DELETE t1 0 X..X {i 1 {} {} {} {} i 4} {}} +} + +do_test 1.3 { + S delete +} {} + +do_sql2patchset_test 1.4 { + DELETE FROM t1; +} { + {DELETE t1 0 X..X {i 5 {} {} {} {} i 8} {}} + {DELETE t1 0 X..X {t w {} {} {} {} t z} {}} + {DELETE t1 0 X..X {i 9 {} {} {} {} i 12} {}} +} + +do_sql2patchset_test 1.5 { + INSERT INTO t1 VALUES(X'61626364', NULL, NULL, 4.2); + INSERT INTO t1 VALUES(4.2, NULL, NULL, X'61626364'); +} { + {INSERT t1 0 X..X {} {f 4.2 n {} n {} b abcd}} + {INSERT t1 0 X..X {} {b abcd n {} n {} f 4.2}} +} + +do_sql2patchset_test 1.6 { + UPDATE t1 SET b=45 WHERE typeof(a)=='blob'; + UPDATE t1 SET c='zzzz' WHERE typeof(a)!='blob'; +} { + {UPDATE t1 0 X..X {f 4.2 {} {} {} {} b abcd} {{} {} {} {} t zzzz {} {}}} + {UPDATE t1 0 X..X {b abcd {} {} {} {} f 4.2} {{} {} i 45 {} {} {} {}}} +} + +do_sql2patchset_test 1.7 { + UPDATE t1 SET b='xyz' WHERE typeof(a)=='blob'; + UPDATE t1 SET c='xyz' WHERE typeof(a)!='blob'; + UPDATE t1 SET b=45 WHERE typeof(a)=='blob'; + UPDATE t1 SET c='zzzz' WHERE typeof(a)!='blob'; +} { +} + +do_sql2patchset_test 1.8 { + DELETE FROM t1; +} { + {DELETE t1 0 X..X {f 4.2 {} {} {} {} b abcd} {}} + {DELETE t1 0 X..X {b abcd {} {} {} {} f 4.2} {}} +} + +#------------------------------------------------------------------------- +# Run simple tests of _apply() with patchset objects. +# +reset_db + +proc noop {args} { error $args } +proc exec_rollback_replay {sql} { + sqlite3session S db main + S attach * + execsql BEGIN + execsql $sql + set patchset [S patchset] + S delete + execsql ROLLBACK + sqlite3changeset_apply db $patchset noop +} + +do_execsql_test 2.0 { + CREATE TABLE t2(a, b, c, d, PRIMARY KEY(b,c)); + CREATE TABLE t3(w, x, y, z, PRIMARY KEY(w)); +} + +do_test 2.1 { + exec_rollback_replay { + INSERT INTO t2 VALUES(1, 2, 3, 4); + INSERT INTO t2 VALUES('w', 'x', 'y', 'z'); + } + execsql { SELECT * FROM t2 } +} {1 2 3 4 w x y z} + +do_test 2.2 { + exec_rollback_replay { + DELETE FROM t2 WHERE a=1; + UPDATE t2 SET d = 'a'; + } + execsql { SELECT * FROM t2 } +} {w x y a} + +#------------------------------------------------------------------------- +# sqlite3changeset_invert() +# +reset_db + +do_execsql_test 3.1 { CREATE TABLE t1(x PRIMARY KEY, y) } +do_test 3.2 { + sqlite3session S db main + S attach * + execsql { INSERT INTO t1 VALUES(1, 2) } + set patchset [S patchset] + S delete + list [catch { sqlite3changeset_invert $patchset } msg] [set msg] +} {1 SQLITE_CORRUPT} + + +#------------------------------------------------------------------------- +# sqlite3changeset_concat() +# +reset_db + +proc do_patchconcat_test {tn args} { + set nSql [expr [llength $args]-1] + set res [lindex $args $nSql] + set patchlist [list] + + execsql BEGIN + foreach sql [lrange $args 0 end-1] { + sqlite3session S db main + S attach * + execsql $sql + lappend patchlist [S patchset] + S delete + } + execsql ROLLBACK + + set patch [lindex $patchlist 0] + foreach p [lrange $patchlist 1 end] { + set patch [sqlite3changeset_concat $patch $p] + } + + set x [list] + sqlite3session_foreach c $patch { lappend x $c } + + uplevel [list do_test $tn [list set {} $x] [list {*}$res]] +} + +do_execsql_test 4.1.1 { + CREATE TABLE t1(x PRIMARY KEY, y, z); +} +do_patchconcat_test 4.1.2 { + INSERT INTO t1 VALUES(1, 2, 3); +} { + INSERT INTO t1 VALUES(4, 5, 6); +} { + {INSERT t1 0 X.. {} {i 1 i 2 i 3}} + {INSERT t1 0 X.. {} {i 4 i 5 i 6}} +} + +if 0 { +do_execsql_test 4.2.1 { + INSERT INTO t1 VALUES(1, 2, 3); + INSERT INTO t1 VALUES(4, 5, 6); +} +do_patchconcat_test 4.2.2 { + UPDATE t1 SET z = 'abc' WHERE x=1 +} { + UPDATE t1 SET z = 'def' WHERE x=4 +} { +} +} + +finish_test + + diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index 256d5f089c..62adb8de25 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -35,6 +35,7 @@ struct sqlite3_session { struct sqlite3_changeset_iter { u8 *aChangeset; /* Pointer to buffer containing changeset */ int nChangeset; /* Number of bytes in aChangeset */ + int bPatchset; /* True if this is a patchset */ u8 *pNext; /* Pointer to next change within aChangeset */ int rc; /* Iterator error code */ sqlite3_stmt *pConflict; /* Points to conflicting row, if any */ @@ -122,6 +123,7 @@ struct SessionTable { ** ** 1 byte: Constant 0x54 (capital 'T') ** Varint: Big-endian integer set to the number of columns in the table. +** nCol bytes: 0x01 for PK columns, 0x00 otherwise. ** N bytes: Unqualified table name (encoded using UTF-8). Nul-terminated. ** ** Followed by one or more changes to the table. @@ -130,6 +132,25 @@ struct SessionTable { ** 1 byte: The "indirect-change" flag. ** old.* record: (delete and update only) ** new.* record: (insert and update only) +** +** PATCHSET FORMAT: +** +** A patchset is also a collection of changes. It is similar to a changeset, +** but omits those fields that are not useful if no conflict resolution +** is required when applying the changeset. +** +** Each group of changes begins with a table header: +** +** 1 byte: Constant 0x50 (capital 'P') +** Varint: Big-endian integer set to the number of columns in the table. +** nCol bytes: 0x01 for PK columns, 0x00 otherwise. +** N bytes: Unqualified table name (encoded using UTF-8). Nul-terminated. +** +** Followed by one or more changes to the table. +** +** 1 byte: Either SQLITE_INSERT, UPDATE or DELETE. +** 1 byte: The "indirect-change" flag. +** single record: (PK fields for DELETE, or full record for INSERT/UPDATE). */ /* @@ -1449,6 +1470,7 @@ static void sessionAppendCol( */ static int sessionAppendUpdate( SessionBuffer *pBuf, /* Buffer to append to */ + int bPatchset, /* True for "patchset", 0 for "changeset" */ sqlite3_stmt *pStmt, /* Statement handle pointing at new row */ SessionChange *p, /* Object containing old values */ u8 *abPK /* Boolean array - true for PK columns */ @@ -1506,15 +1528,23 @@ static int sessionAppendUpdate( } } - if( bChanged || abPK[i] ){ - sessionAppendBlob(pBuf, pCsr, nAdvance, &rc); - }else{ - sessionAppendByte(pBuf, 0, &rc); + /* If at least one field has been modified, this is not a no-op. */ + if( bChanged ) bNoop = 0; + + /* Add a field to the old.* record. This is omitted if this modules is + ** currently generating a patchset. */ + if( bPatchset==0 ){ + if( bChanged || abPK[i] ){ + sessionAppendBlob(pBuf, pCsr, nAdvance, &rc); + }else{ + sessionAppendByte(pBuf, 0, &rc); + } } - if( bChanged ){ + /* Add a field to the new.* record. Or the only record if currently + ** generating a patchset. */ + if( bChanged || (bPatchset && abPK[i]) ){ sessionAppendCol(&buf2, pStmt, i, &rc); - bNoop = 0; }else{ sessionAppendByte(&buf2, 0, &rc); } @@ -1532,6 +1562,56 @@ static int sessionAppendUpdate( return rc; } +static int sessionAppendDelete( + SessionBuffer *pBuf, /* Buffer to append to */ + int bPatchset, /* True for "patchset", 0 for "changeset" */ + sqlite3_stmt *pStmt, /* Statement handle pointing at new row */ + SessionChange *p, /* Object containing old values */ + u8 *abPK /* Boolean array - true for PK columns */ +){ + int rc = SQLITE_OK; + + sessionAppendByte(pBuf, SQLITE_DELETE, &rc); + sessionAppendByte(pBuf, p->bIndirect, &rc); + + if( bPatchset==0 ){ + sessionAppendBlob(pBuf, p->aRecord, p->nRecord, &rc); + }else{ + int nCol = sqlite3_column_count(pStmt); + int i; + u8 *a = p->aRecord; + for(i=0; iaRecord)==p->nRecord ); + } + + return rc; +} + /* ** Formulate and prepare a SELECT statement to retrieve a row from table ** zTab in database zDb based on its primary key. i.e. @@ -1654,25 +1734,20 @@ static int sessionSelectBind( */ static void sessionAppendTableHdr( SessionBuffer *pBuf, + int bPatchset, SessionTable *pTab, int *pRc ){ /* Write a table header */ - sessionAppendByte(pBuf, 'T', pRc); + sessionAppendByte(pBuf, (bPatchset ? 'P' : 'T'), pRc); sessionAppendVarint(pBuf, pTab->nCol, pRc); sessionAppendBlob(pBuf, pTab->abPK, pTab->nCol, pRc); sessionAppendBlob(pBuf, (u8 *)pTab->zName, (int)strlen(pTab->zName)+1, pRc); } -/* -** Obtain a changeset object containing all changes recorded by the -** session object passed as the first argument. -** -** It is the responsibility of the caller to eventually free the buffer -** using sqlite3_free(). -*/ -int sqlite3session_changeset( +int sessionGenerateChangeset( sqlite3_session *pSession, /* Session object */ + int bPatchset, /* True for patchset, false for changeset */ int *pnChangeset, /* OUT: Size of buffer at *ppChangeset */ void **ppChangeset /* OUT: Buffer containing changeset */ ){ @@ -1711,7 +1786,7 @@ int sqlite3session_changeset( } /* Write a table header */ - sessionAppendTableHdr(&buf, pTab, &rc); + sessionAppendTableHdr(&buf, bPatchset, pTab, &rc); /* Build and compile a statement to execute: */ if( rc==SQLITE_OK ){ @@ -1735,13 +1810,10 @@ int sqlite3session_changeset( sessionAppendCol(&buf, pSel, iCol, &rc); } }else{ - rc = sessionAppendUpdate(&buf, pSel, p, abPK); + rc = sessionAppendUpdate(&buf, bPatchset, pSel, p, abPK); } }else if( p->op!=SQLITE_INSERT ){ - /* A DELETE change */ - sessionAppendByte(&buf, SQLITE_DELETE, &rc); - sessionAppendByte(&buf, p->bIndirect, &rc); - sessionAppendBlob(&buf, p->aRecord, p->nRecord, &rc); + rc = sessionAppendDelete(&buf, bPatchset, pSel, p, abPK); } if( rc==SQLITE_OK ){ rc = sqlite3_reset(pSel); @@ -1769,6 +1841,36 @@ int sqlite3session_changeset( return rc; } +/* +** Obtain a changeset object containing all changes recorded by the +** session object passed as the first argument. +** +** It is the responsibility of the caller to eventually free the buffer +** using sqlite3_free(). +*/ +int sqlite3session_changeset( + sqlite3_session *pSession, /* Session object */ + int *pnChangeset, /* OUT: Size of buffer at *ppChangeset */ + void **ppChangeset /* OUT: Buffer containing changeset */ +){ + return sessionGenerateChangeset(pSession, 0, pnChangeset, ppChangeset); +} + +/* +** Obtain a patchset object containing all changes recorded by the +** session object passed as the first argument. +** +** It is the responsibility of the caller to eventually free the buffer +** using sqlite3_free(). +*/ +int sqlite3session_patchset( + sqlite3_session *pSession, /* Session object */ + int *pnPatchset, /* OUT: Size of buffer at *ppChangeset */ + void **ppPatchset /* OUT: Buffer containing changeset */ +){ + return sessionGenerateChangeset(pSession, 1, pnPatchset, ppPatchset); +} + /* ** Enable or disable the session object passed as the first argument. */ @@ -1866,13 +1968,16 @@ int sqlite3changeset_start( static int sessionReadRecord( u8 **paChange, /* IN/OUT: Pointer to binary record */ int nCol, /* Number of values in record */ + u8 *abPK, /* Array of primary key flags, or NULL */ sqlite3_value **apOut /* Write values to this array */ ){ int i; /* Used to iterate through columns */ u8 *aRec = *paChange; /* Cursor for the serialized record */ for(i=0; ipNext; - if( aChange[0]=='T' ){ + if( aChange[0]=='T' || aChange[0]=='P' ){ int nByte; /* Bytes to allocate for apValue */ + p->bPatchset = (aChange[0]=='P'); aChange++; aChange += sessionVarintGet(aChange, &p->nCol); p->abPK = (u8 *)aChange; @@ -1981,18 +2087,36 @@ static int sessionChangesetNext( if( paRec ){ *paRec = aChange; } /* If this is an UPDATE or DELETE, read the old.* record. */ - if( p->op!=SQLITE_INSERT ){ - p->rc = sessionReadRecord(&aChange, p->nCol, paRec?0:p->apValue); + if( p->op!=SQLITE_INSERT && (p->bPatchset==0 || p->op==SQLITE_DELETE) ){ + u8 *abPK = p->bPatchset ? p->abPK : 0; + p->rc = sessionReadRecord(&aChange, p->nCol, abPK, paRec?0:p->apValue); if( p->rc!=SQLITE_OK ) return p->rc; } /* If this is an INSERT or UPDATE, read the new.* record. */ if( p->op!=SQLITE_DELETE ){ - p->rc = sessionReadRecord(&aChange, p->nCol, paRec?0:&p->apValue[p->nCol]); + sqlite3_value **apOut = (paRec ? 0 : &p->apValue[p->nCol]); + p->rc = sessionReadRecord(&aChange, p->nCol, 0, apOut); if( p->rc!=SQLITE_OK ) return p->rc; } - if( pnRec ){ *pnRec = (int)(aChange - *paRec); } + if( pnRec ){ + *pnRec = (int)(aChange - *paRec); + }else if( p->bPatchset && p->op==SQLITE_UPDATE ){ + /* If this is an UPDATE that is part of a patchset, then all PK and + ** modified fields are present in the new.* record. The old.* record + ** is currently completely empty. This block shifts the PK fields from + ** new.* to old.*, to accommodate the code that reads these arrays. */ + int i; + for(i=0; inCol; i++){ + assert( p->apValue[i]==0 ); + assert( p->abPK[i]==0 || p->apValue[i+p->nCol] ); + if( p->abPK[i] ){ + p->apValue[i] = p->apValue[i+p->nCol]; + p->apValue[i+p->nCol] = 0; + } + } + } p->pNext = aChange; return SQLITE_ROW; } @@ -2225,7 +2349,7 @@ int sqlite3changeset_invert( int nByte; u8 *aEnd = &aIn[i+2]; - sessionReadRecord(&aEnd, nCol, 0); + sessionReadRecord(&aEnd, nCol, 0, 0); aOut[i] = (eType==SQLITE_DELETE ? SQLITE_INSERT : SQLITE_DELETE); aOut[i+1] = aIn[i+1]; nByte = (int)(aEnd - &aIn[i+2]); @@ -2249,9 +2373,9 @@ int sqlite3changeset_invert( } /* Read the old.* and new.* records for the update change. */ - rc = sessionReadRecord(&aEnd, nCol, &apVal[0]); + rc = sessionReadRecord(&aEnd, nCol, 0, &apVal[0]); if( rc==SQLITE_OK ){ - rc = sessionReadRecord(&aEnd, nCol, &apVal[nCol]); + rc = sessionReadRecord(&aEnd, nCol, 0, &apVal[nCol]); } /* Write the header for the new UPDATE change. Same as the original. */ @@ -2781,10 +2905,21 @@ static int sessionApplyOneOp( if( op==SQLITE_DELETE ){ - /* Bind values to the DELETE statement. */ - rc = sessionBindRow(pIter, sqlite3changeset_old, nCol, 0, p->pDelete); + /* Bind values to the DELETE statement. If conflict handling is required, + ** bind values for all columns and set bound variable (nCol+1) to true. + ** Or, if conflict handling is not required, bind just the PK column + ** values and, if it exists, set (nCol+1) to false. Conflict handling + ** is not required if: + ** + ** * this is a patchset, or + ** * (pbRetry==0), or + ** * all columns of the table are PK columns (in this case there is + ** no (nCol+1) variable to bind to). + */ + u8 *abPK = (pIter->bPatchset ? p->abPK : 0); + rc = sessionBindRow(pIter, sqlite3changeset_old, nCol, abPK, p->pDelete); if( rc==SQLITE_OK && sqlite3_bind_parameter_count(p->pDelete)>nCol ){ - rc = sqlite3_bind_int(p->pDelete, nCol+1, pbRetry==0); + rc = sqlite3_bind_int(p->pDelete, nCol+1, (pbRetry==0 || abPK)); } if( rc!=SQLITE_OK ) return rc; @@ -2816,7 +2951,9 @@ static int sessionApplyOneOp( rc = sessionBindValue(p->pUpdate, i*3+3, pNew); } } - if( rc==SQLITE_OK ) sqlite3_bind_int(p->pUpdate, nCol*3+1, pbRetry==0); + if( rc==SQLITE_OK ){ + sqlite3_bind_int(p->pUpdate, nCol*3+1, pbRetry==0 || pIter->bPatchset); + } if( rc!=SQLITE_OK ) return rc; /* Attempt the UPDATE. In the case of a NOTFOUND or DATA conflict, @@ -3099,7 +3236,7 @@ static int sessionChangeMerge( u8 *a1 = aRec; assert( op2==SQLITE_UPDATE ); pNew->op = SQLITE_INSERT; - sessionReadRecord(&a1, pTab->nCol, 0); + sessionReadRecord(&a1, pTab->nCol, 0, 0); sessionMergeRecord(&aCsr, pTab->nCol, pExist->aRecord, a1); }else if( op1==SQLITE_DELETE ){ /* DELETE + INSERT */ assert( op2==SQLITE_INSERT ); @@ -3112,8 +3249,8 @@ static int sessionChangeMerge( u8 *a1 = pExist->aRecord; u8 *a2 = aRec; assert( op1==SQLITE_UPDATE ); - sessionReadRecord(&a1, pTab->nCol, 0); - sessionReadRecord(&a2, pTab->nCol, 0); + sessionReadRecord(&a1, pTab->nCol, 0, 0); + sessionReadRecord(&a2, pTab->nCol, 0, 0); pNew->op = SQLITE_UPDATE; if( 0==sessionMergeUpdate(&aCsr, pTab, aRec, pExist->aRecord, a1, a2) ){ sqlite3_free(pNew); @@ -3274,7 +3411,7 @@ int sqlite3changeset_concat( int i; if( pTab->nEntry==0 ) continue; - sessionAppendTableHdr(&buf, pTab, &rc); + sessionAppendTableHdr(&buf, 0, pTab, &rc); for(i=0; inChange; i++){ SessionChange *p; for(p=pTab->apChange[i]; p; p=p->pNext){ diff --git a/ext/session/sqlite3session.h b/ext/session/sqlite3session.h index 974a770c7b..de4ee77b94 100644 --- a/ext/session/sqlite3session.h +++ b/ext/session/sqlite3session.h @@ -273,6 +273,15 @@ int sqlite3session_changeset( void **ppChangeset /* OUT: Buffer containing changeset */ ); +/* +** CAPI3REF: Generate A Patchset From A Session Object +*/ +int sqlite3session_patchset( + sqlite3_session *pSession, /* Session object */ + int *pnPatchset, /* OUT: Size of buffer at *ppChangeset */ + void **ppPatchset /* OUT: Buffer containing changeset */ +); + /* ** CAPI3REF: Test if a changeset has recorded any changes. ** diff --git a/ext/session/test_session.c b/ext/session/test_session.c index f1c2fbe9a3..fa99f56786 100644 --- a/ext/session/test_session.c +++ b/ext/session/test_session.c @@ -73,6 +73,7 @@ static int test_session_cmd( { "indirect", 1, "BOOL", }, /* 4 */ { "isempty", 0, "", }, /* 5 */ { "table_filter", 1, "SCRIPT", }, /* 6 */ + { "patchset", 0, "", }, /* 7 */ { 0 } }; int iSub; @@ -102,10 +103,15 @@ static int test_session_cmd( break; } + case 7: /* patchset */ case 1: { /* changeset */ int nChange; void *pChange; - rc = sqlite3session_changeset(pSession, &nChange, &pChange); + if( iSub==7 ){ + rc = sqlite3session_patchset(pSession, &nChange, &pChange); + }else{ + rc = sqlite3session_changeset(pSession, &nChange, &pChange); + } if( rc==SQLITE_OK ){ Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(pChange, nChange)); sqlite3_free(pChange); diff --git a/manifest b/manifest index b52178bb67..833a47196f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\sthe\ssessions\sbranch\sfor\sversion\s3.8.6. -D 2014-08-15T15:10:46.167 +C Begin\sadding\sthe\ssqlite3session_patchset()\sAPI\sto\sthe\ssessions\sextension.\sThis\sis\san\sinterim\scommit. +D 2014-08-15T20:15:49.367 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 639859a6f81bd15921ccd56ddbd6dfd335278377 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -152,11 +152,12 @@ F ext/session/session6.test 443789bc2fca12e4f7075cf692c60b8a2bea1a26 F ext/session/session8.test 7d35947ad329b8966f095d34f9617a9eff52dc65 F ext/session/session9.test 776e46785c29c11cda01f5205d0f1e8f8f9a46bf F ext/session/sessionA.test eb05c13e4ef1ca8046a3a6dbf2d5f6f5b04a11d4 +F ext/session/sessionB.test dbabf40e7580f2dc245ea6b37b94fd1ec0b25fc3 F ext/session/session_common.tcl 1539d8973b2aea0025c133eb0cc4c89fcef541a5 F ext/session/sessionfault.test 496291b287ba3c0b14ca2e074425e29cc92a64a6 -F ext/session/sqlite3session.c 34e19186d05d534e5a37a4f5a8a3c3e24e3fa88a -F ext/session/sqlite3session.h 6c35057241567ed6319f750ee504a81c459225e1 -F ext/session/test_session.c 7878ac0e2fe9675e8ec24d54f6a538ccc105977f +F ext/session/sqlite3session.c e0d8101afc5df85495c401eadf2cb288c3d53adc +F ext/session/sqlite3session.h c99445ea9918343d3e62acafdf82bc5502cfba29 +F ext/session/test_session.c 920ccb6d6e1df263cd9099563328094c230b2925 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60 @@ -1201,7 +1202,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P d49455d9a972fc2224d9beb97165a998ca56e838 9491ba7d738528f168657adb43a198238abde19e -R f94212c9f19d7229cfd6e84a8137e8b7 -U drh -Z 80e27e19ffdd26307df7b50bec8606de +P 2acbeac1fd9b9feb26e1c24d4ae50ce79f17a3f8 +R 3c0b82c93c7620c8b999c9243f48a749 +U dan +Z a8da13936a56069d46e167f9c70b2c2a diff --git a/manifest.uuid b/manifest.uuid index 79ed17684c..ccaf220a3e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2acbeac1fd9b9feb26e1c24d4ae50ce79f17a3f8 \ No newline at end of file +60a4565a8c44762a002cd02979317df5ca47e899 \ No newline at end of file From 64277f4a7054909abe1cd8fdedb1e2ad21b4b853 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 16 Aug 2014 16:47:55 +0000 Subject: [PATCH 0109/1484] Fixes for the sqlite3changeset_concat() API regarding patchsets. FossilOrigin-Name: dccb34859508eac8146ae5b19c447673d04be3b0 --- ext/session/sessionB.test | 101 +++++++++++++++++++++++++++- ext/session/sqlite3session.c | 124 ++++++++++++++++++++++++----------- manifest | 14 ++-- manifest.uuid | 2 +- 4 files changed, 193 insertions(+), 48 deletions(-) diff --git a/ext/session/sessionB.test b/ext/session/sessionB.test index 76213d8ab2..8791272f8e 100644 --- a/ext/session/sessionB.test +++ b/ext/session/sessionB.test @@ -178,17 +178,24 @@ do_test 3.2 { reset_db proc do_patchconcat_test {tn args} { + set bRevert 0 + if {[lindex $args 0] == "-revert"} { + set bRevert 1 + set args [lrange $args 1 end] + } set nSql [expr [llength $args]-1] set res [lindex $args $nSql] set patchlist [list] execsql BEGIN + if {$bRevert} { execsql { SAVEPOINT x } } foreach sql [lrange $args 0 end-1] { sqlite3session S db main S attach * execsql $sql lappend patchlist [S patchset] S delete + if {$bRevert} { execsql { ROLLBACK TO x } } } execsql ROLLBACK @@ -215,17 +222,109 @@ do_patchconcat_test 4.1.2 { {INSERT t1 0 X.. {} {i 4 i 5 i 6}} } -if 0 { do_execsql_test 4.2.1 { INSERT INTO t1 VALUES(1, 2, 3); INSERT INTO t1 VALUES(4, 5, 6); } + do_patchconcat_test 4.2.2 { UPDATE t1 SET z = 'abc' WHERE x=1 } { UPDATE t1 SET z = 'def' WHERE x=4 } { + {UPDATE t1 0 X.. {i 1 {} {} {} {}} {{} {} {} {} t abc}} + {UPDATE t1 0 X.. {i 4 {} {} {} {}} {{} {} {} {} t def}} } + +do_patchconcat_test 4.2.3 { + DELETE FROM t1 WHERE x=1; +} { + DELETE FROM t1 WHERE x=4; +} { + {DELETE t1 0 X.. {i 1 {} {} {} {}} {}} + {DELETE t1 0 X.. {i 4 {} {} {} {}} {}} +} + + +do_execsql_test 4.3.1 { + CREATE TABLE t2(a, b, c, d, PRIMARY KEY(c, b)); + INSERT INTO t2 VALUES('.', 1, 1, '.'); + INSERT INTO t2 VALUES('.', 1, 2, '.'); + INSERT INTO t2 VALUES('.', 2, 1, '.'); + INSERT INTO t2 VALUES('.', 2, 2, '.'); +} + +# INSERT + INSERT +do_patchconcat_test 4.3.2 -revert { + INSERT INTO t2 VALUES('a', 'a', 'a', 'a'); +} { + INSERT INTO t2 VALUES('b', 'a', 'a', 'b'); +} { + {INSERT t2 0 .XX. {} {t a t a t a t a}} +} + +# INSERT + DELETE +do_patchconcat_test 4.3.3 { + INSERT INTO t2 VALUES('a', 'a', 'a', 'a'); +} { + DELETE FROM t2 WHERE c = 'a'; +} { +} + +# INSERT + UPDATE +do_patchconcat_test 4.3.4 { + INSERT INTO t2 VALUES('a', 'a', 'a', 'a'); +} { + UPDATE t2 SET d = 'b' WHERE c='a'; +} { + {INSERT t2 0 .XX. {} {t a t a t a t b}} +} + +# UPDATE + UPDATE +do_patchconcat_test 4.3.5 { + UPDATE t2 SET a = 'a' WHERE c=1 AND b=2; +} { + UPDATE t2 SET d = 'd' WHERE c=1 AND b=2; +} { + {UPDATE t2 0 .XX. {{} {} i 2 i 1 {} {}} {t a {} {} {} {} t d}} +} + +# UPDATE + DELETE +do_patchconcat_test 4.3.6 { + UPDATE t2 SET a = 'a' WHERE c=1 AND b=2; +} { + DELETE FROM t2 WHERE c=1 AND b=2; +} { + {DELETE t2 0 .XX. {{} {} i 2 i 1 {} {}} {}} +} + +# DELETE + INSERT +do_patchconcat_test 4.3.7 { + DELETE FROM t2 WHERE b=1; +} { + INSERT INTO t2 VALUES('x', 1, 2, '.'); +} { + {DELETE t2 0 .XX. {{} {} i 1 i 1 {} {}} {}} + {UPDATE t2 0 .XX. {{} {} i 1 i 2 {} {}} {t x {} {} {} {} t .}} +} + +# DELETE + UPDATE +do_patchconcat_test 4.3.8 -revert { + DELETE FROM t2 WHERE b=1 AND c=2; +} { + UPDATE t2 SET a=5 WHERE b=1 AND c=2; +} { + {DELETE t2 0 .XX. {{} {} i 1 i 2 {} {}} {}} +} + +# DELETE + UPDATE +do_patchconcat_test 4.3.9 -revert { + DELETE FROM t2 WHERE b=1 AND c=2; +} { + DELETE FROM t2 WHERE b=1; +} { + {DELETE t2 0 .XX. {{} {} i 1 i 1 {} {}} {}} + {DELETE t2 0 .XX. {{} {} i 1 i 2 {} {}} {}} } finish_test diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index 62adb8de25..b86c635ed1 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -443,9 +443,13 @@ static int sessionSerialLen(u8 *a){ ** hash key. Assume the has table has nBucket buckets. The hash keys ** calculated by this function are compatible with those calculated by ** sessionPreupdateHash(). +** +** The bPkOnly argument is non-zero if the record at aRecord[] is from +** a patchset DELETE. In this case the non-PK fields are omitted entirely. */ static unsigned int sessionChangeHash( SessionTable *pTab, /* Table handle */ + int bPkOnly, /* Record consists of PK fields only */ u8 *aRecord, /* Change record */ int nBucket /* Assume this many buckets in hash table */ ){ @@ -456,6 +460,7 @@ static unsigned int sessionChangeHash( for(i=0; inCol; i++){ int eType = *a; int isPK = pTab->abPK[i]; + if( bPkOnly && isPK==0 ) continue; /* It is not possible for eType to be SQLITE_NULL here. The session ** module does not record changes for rows with NULL values stored in @@ -493,7 +498,9 @@ static unsigned int sessionChangeHash( */ static int sessionChangeEqual( SessionTable *pTab, /* Table used for PK definition */ + int bLeftPkOnly, u8 *aLeft, /* Change record */ + int bRightPkOnly, u8 *aRight /* Change record */ ){ u8 *a1 = aLeft; /* Cursor to iterate through aLeft */ @@ -507,8 +514,8 @@ static int sessionChangeEqual( if( pTab->abPK[iCol] && (n1!=n2 || memcmp(a1, a2, n1)) ){ return 0; } - a1 += n1; - a2 += n2; + if( pTab->abPK[iCol] || bLeftPkOnly==0 ) a1 += n1; + if( pTab->abPK[iCol] || bRightPkOnly==0 ) a2 += n2; } return 1; @@ -606,6 +613,7 @@ static u8 *sessionMergeValue( static int sessionMergeUpdate( u8 **paOut, /* IN/OUT: Pointer to output buffer */ SessionTable *pTab, /* Table change pertains to */ + int bPatchset, u8 *aOldRecord1, /* old.* record for first change */ u8 *aOldRecord2, /* old.* record for second change */ u8 *aNewRecord1, /* new.* record for first change */ @@ -618,29 +626,32 @@ static int sessionMergeUpdate( u8 *aOut = *paOut; int i; - int bRequired = 0; - assert( aOldRecord1 && aNewRecord1 ); + if( bPatchset==0 ){ + int bRequired = 0; - /* Write the old.* vector first. */ - for(i=0; inCol; i++){ - int nOld; - u8 *aOld; - int nNew; - u8 *aNew; + assert( aOldRecord1 && aNewRecord1 ); - aOld = sessionMergeValue(&aOld1, &aOld2, &nOld); - aNew = sessionMergeValue(&aNew1, &aNew2, &nNew); - if( pTab->abPK[i] || nOld!=nNew || memcmp(aOld, aNew, nNew) ){ - if( pTab->abPK[i]==0 ) bRequired = 1; - memcpy(aOut, aOld, nOld); - aOut += nOld; - }else{ - *(aOut++) = '\0'; + /* Write the old.* vector first. */ + for(i=0; inCol; i++){ + int nOld; + u8 *aOld; + int nNew; + u8 *aNew; + + aOld = sessionMergeValue(&aOld1, &aOld2, &nOld); + aNew = sessionMergeValue(&aNew1, &aNew2, &nNew); + if( pTab->abPK[i] || nOld!=nNew || memcmp(aOld, aNew, nNew) ){ + if( pTab->abPK[i]==0 ) bRequired = 1; + memcpy(aOut, aOld, nOld); + aOut += nOld; + }else{ + *(aOut++) = '\0'; + } } - } - if( !bRequired ) return 0; + if( !bRequired ) return 0; + } /* Write the new.* vector */ aOld1 = aOldRecord1; @@ -655,7 +666,9 @@ static int sessionMergeUpdate( aOld = sessionMergeValue(&aOld1, &aOld2, &nOld); aNew = sessionMergeValue(&aNew1, &aNew2, &nNew); - if( pTab->abPK[i] || (nOld==nNew && 0==memcmp(aOld, aNew, nNew)) ){ + if( bPatchset==0 + && (pTab->abPK[i] || (nOld==nNew && 0==memcmp(aOld, aNew, nNew))) + ){ *(aOut++) = '\0'; }else{ memcpy(aOut, aNew, nNew); @@ -754,7 +767,7 @@ static int sessionPreupdateEqual( ** Growing the hash table in this case is a performance optimization only, ** it is not required for correct operation. */ -static int sessionGrowHash(SessionTable *pTab){ +static int sessionGrowHash(int bPatchset, SessionTable *pTab){ if( pTab->nChange==0 || pTab->nEntry>=(pTab->nChange/2) ){ int i; SessionChange **apNew; @@ -773,7 +786,8 @@ static int sessionGrowHash(SessionTable *pTab){ SessionChange *p; SessionChange *pNext; for(p=pTab->apChange[i]; p; p=pNext){ - int iHash = sessionChangeHash(pTab, p->aRecord, nNew); + int bPkOnly = (p->op==SQLITE_DELETE && bPatchset); + int iHash = sessionChangeHash(pTab, bPkOnly, p->aRecord, nNew); pNext = p->pNext; p->pNext = apNew[iHash]; apNew[iHash] = p; @@ -960,7 +974,7 @@ static void sessionPreupdateOneChange( if( sessionInitTable(pSession, pTab) ) return; /* Grow the hash table if required */ - if( sessionGrowHash(pTab) ){ + if( sessionGrowHash(0, pTab) ){ pSession->rc = SQLITE_NOMEM; return; } @@ -3174,6 +3188,7 @@ int sqlite3changeset_apply( */ static int sessionChangeMerge( SessionTable *pTab, /* Table structure */ + int bPatchset, /* True for patchsets */ SessionChange *pExist, /* Existing change */ int op2, /* Second change operation */ int bIndirect, /* True if second change is indirect */ @@ -3219,9 +3234,13 @@ static int sessionChangeMerge( sqlite3_free(pExist); assert( pNew==0 ); }else{ + u8 *aExist = pExist->aRecord; int nByte; u8 *aCsr; + /* Allocate a new SessionChange object. Ensure that the aRecord[] + ** buffer of the new object is large enough to hold any record that + ** may be generated by combining the input records. */ nByte = sizeof(SessionChange) + pExist->nRecord + nRec; pNew = (SessionChange *)sqlite3_malloc(nByte); if( !pNew ){ @@ -3236,30 +3255,37 @@ static int sessionChangeMerge( u8 *a1 = aRec; assert( op2==SQLITE_UPDATE ); pNew->op = SQLITE_INSERT; - sessionReadRecord(&a1, pTab->nCol, 0, 0); - sessionMergeRecord(&aCsr, pTab->nCol, pExist->aRecord, a1); + if( bPatchset==0 ) sessionReadRecord(&a1, pTab->nCol, 0, 0); + sessionMergeRecord(&aCsr, pTab->nCol, aExist, a1); }else if( op1==SQLITE_DELETE ){ /* DELETE + INSERT */ assert( op2==SQLITE_INSERT ); pNew->op = SQLITE_UPDATE; - if( 0==sessionMergeUpdate(&aCsr, pTab, pExist->aRecord, 0, aRec, 0) ){ + if( 0==sessionMergeUpdate(&aCsr, pTab, bPatchset, aExist, 0, aRec, 0) ){ sqlite3_free(pNew); pNew = 0; } }else if( op2==SQLITE_UPDATE ){ /* UPDATE + UPDATE */ - u8 *a1 = pExist->aRecord; + u8 *a1 = aExist; u8 *a2 = aRec; assert( op1==SQLITE_UPDATE ); - sessionReadRecord(&a1, pTab->nCol, 0, 0); - sessionReadRecord(&a2, pTab->nCol, 0, 0); + if( bPatchset==0 ){ + sessionReadRecord(&a1, pTab->nCol, 0, 0); + sessionReadRecord(&a2, pTab->nCol, 0, 0); + } pNew->op = SQLITE_UPDATE; - if( 0==sessionMergeUpdate(&aCsr, pTab, aRec, pExist->aRecord, a1, a2) ){ + if( 0==sessionMergeUpdate(&aCsr, pTab, bPatchset, aRec, aExist,a1,a2) ){ sqlite3_free(pNew); pNew = 0; } }else{ /* UPDATE + DELETE */ assert( op1==SQLITE_UPDATE && op2==SQLITE_DELETE ); pNew->op = SQLITE_DELETE; - sessionMergeRecord(&aCsr, pTab->nCol, aRec, pExist->aRecord); + if( bPatchset ){ + memcpy(aCsr, aRec, nRec); + aCsr += nRec; + }else{ + sessionMergeRecord(&aCsr, pTab->nCol, aRec, aExist); + } } if( pNew ){ @@ -3278,6 +3304,7 @@ static int sessionChangeMerge( ** hash tables. */ static int sessionConcatChangeset( + int bPatchset, /* True to expect patchsets */ int nChangeset, /* Number of bytes in pChangeset */ void *pChangeset, /* Changeset buffer */ SessionTable **ppTabList /* IN/OUT: List of table objects */ @@ -3301,6 +3328,13 @@ static int sessionConcatChangeset( SessionChange *pExist = 0; SessionChange **pp; + assert( bPatchset==0 || bPatchset==1 ); + assert( pIter->bPatchset==0 || pIter->bPatchset==1 ); + if( pIter->bPatchset!=bPatchset ){ + rc = SQLITE_ERROR; + break; + } + assert( pIter->apValue==0 ); sqlite3changeset_op(pIter, &zNew, &nCol, &op, &bIndirect); @@ -3335,17 +3369,25 @@ static int sessionConcatChangeset( pTab->zName = (char *)zNew; } - if( sessionGrowHash(pTab) ){ + if( sessionGrowHash(bPatchset, pTab) ){ rc = SQLITE_NOMEM; break; } - iHash = sessionChangeHash(pTab, aRec, pTab->nChange); + iHash = sessionChangeHash( + pTab, (bPatchset && op==SQLITE_DELETE), aRec, pTab->nChange + ); /* Search for existing entry. If found, remove it from the hash table. ** Code below may link it back in. */ for(pp=&pTab->apChange[iHash]; *pp; pp=&(*pp)->pNext){ - if( sessionChangeEqual(pTab, (*pp)->aRecord, aRec) ){ + int bPkOnly1 = 0; + int bPkOnly2 = 0; + if( bPatchset ){ + bPkOnly1 = (*pp)->op==SQLITE_DELETE; + bPkOnly2 = op==SQLITE_DELETE; + } + if( sessionChangeEqual(pTab, bPkOnly1, (*pp)->aRecord, bPkOnly2, aRec) ){ pExist = *pp; *pp = (*pp)->pNext; pTab->nEntry--; @@ -3353,7 +3395,9 @@ static int sessionConcatChangeset( } } - rc = sessionChangeMerge(pTab, pExist, op, bIndirect, aRec, nRec, &pChange); + rc = sessionChangeMerge(pTab, + bPatchset, pExist, op, bIndirect, aRec, nRec, &pChange + ); if( rc ) break; if( pChange ){ pChange->pNext = pTab->apChange[iHash]; @@ -3392,13 +3436,15 @@ int sqlite3changeset_concat( ){ SessionTable *pList = 0; /* List of SessionTable objects */ int rc; /* Return code */ + int bPatch; /* True for a patchset */ *pnOut = 0; *ppOut = 0; + bPatch = (nLeft>0 && *(char*)pLeft=='P') || (nRight>0 && *(char*)pRight=='P'); - rc = sessionConcatChangeset(nLeft, pLeft, &pList); + rc = sessionConcatChangeset(bPatch, nLeft, pLeft, &pList); if( rc==SQLITE_OK ){ - rc = sessionConcatChangeset(nRight, pRight, &pList); + rc = sessionConcatChangeset(bPatch, nRight, pRight, &pList); } /* Create the serialized output changeset based on the contents of the @@ -3411,7 +3457,7 @@ int sqlite3changeset_concat( int i; if( pTab->nEntry==0 ) continue; - sessionAppendTableHdr(&buf, 0, pTab, &rc); + sessionAppendTableHdr(&buf, bPatch, pTab, &rc); for(i=0; inChange; i++){ SessionChange *p; for(p=pTab->apChange[i]; p; p=p->pNext){ diff --git a/manifest b/manifest index 833a47196f..2e5dc07be7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Begin\sadding\sthe\ssqlite3session_patchset()\sAPI\sto\sthe\ssessions\sextension.\sThis\sis\san\sinterim\scommit. -D 2014-08-15T20:15:49.367 +C Fixes\sfor\sthe\ssqlite3changeset_concat()\sAPI\sregarding\spatchsets. +D 2014-08-16T16:47:55.133 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 639859a6f81bd15921ccd56ddbd6dfd335278377 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -152,10 +152,10 @@ F ext/session/session6.test 443789bc2fca12e4f7075cf692c60b8a2bea1a26 F ext/session/session8.test 7d35947ad329b8966f095d34f9617a9eff52dc65 F ext/session/session9.test 776e46785c29c11cda01f5205d0f1e8f8f9a46bf F ext/session/sessionA.test eb05c13e4ef1ca8046a3a6dbf2d5f6f5b04a11d4 -F ext/session/sessionB.test dbabf40e7580f2dc245ea6b37b94fd1ec0b25fc3 +F ext/session/sessionB.test 51c70394bc04ac72d72f54bd0879614b9c34240c F ext/session/session_common.tcl 1539d8973b2aea0025c133eb0cc4c89fcef541a5 F ext/session/sessionfault.test 496291b287ba3c0b14ca2e074425e29cc92a64a6 -F ext/session/sqlite3session.c e0d8101afc5df85495c401eadf2cb288c3d53adc +F ext/session/sqlite3session.c eed0f0510859e564f9f8c886d22a299579b5c6c1 F ext/session/sqlite3session.h c99445ea9918343d3e62acafdf82bc5502cfba29 F ext/session/test_session.c 920ccb6d6e1df263cd9099563328094c230b2925 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x @@ -1202,7 +1202,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 2acbeac1fd9b9feb26e1c24d4ae50ce79f17a3f8 -R 3c0b82c93c7620c8b999c9243f48a749 +P 60a4565a8c44762a002cd02979317df5ca47e899 +R 1bd074b437e8898f047cce1541823103 U dan -Z a8da13936a56069d46e167f9c70b2c2a +Z 66bd65019d7460afe376babf330097ba diff --git a/manifest.uuid b/manifest.uuid index ccaf220a3e..9786ee73ae 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -60a4565a8c44762a002cd02979317df5ca47e899 \ No newline at end of file +dccb34859508eac8146ae5b19c447673d04be3b0 \ No newline at end of file From a71d2371d0ff9e73b3ba99bee09a4eef204e22fb Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 16 Aug 2014 19:01:00 +0000 Subject: [PATCH 0110/1484] Fix some missing and out-of-date comments in the sessions module. FossilOrigin-Name: 05c1d9149b27c68e2654ed28491722927d2176f5 --- ext/session/sqlite3session.c | 37 ++++++++++++++++++++++++++---------- ext/session/sqlite3session.h | 20 +++++++++++++++++++ manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 55 insertions(+), 18 deletions(-) diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index b86c635ed1..69d67817bf 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -498,9 +498,9 @@ static unsigned int sessionChangeHash( */ static int sessionChangeEqual( SessionTable *pTab, /* Table used for PK definition */ - int bLeftPkOnly, + int bLeftPkOnly, /* True if aLeft[] contains PK fields only */ u8 *aLeft, /* Change record */ - int bRightPkOnly, + int bRightPkOnly, /* True if aRight[] contains PK fields only */ u8 *aRight /* Change record */ ){ u8 *a1 = aLeft; /* Cursor to iterate through aLeft */ @@ -613,7 +613,7 @@ static u8 *sessionMergeValue( static int sessionMergeUpdate( u8 **paOut, /* IN/OUT: Pointer to output buffer */ SessionTable *pTab, /* Table change pertains to */ - int bPatchset, + int bPatchset, /* True if records are patchset records */ u8 *aOldRecord1, /* old.* record for first change */ u8 *aOldRecord2, /* old.* record for second change */ u8 *aNewRecord1, /* new.* record for first change */ @@ -1576,11 +1576,16 @@ static int sessionAppendUpdate( return rc; } +/* +** Append a DELETE change to the buffer passed as the first argument. Use +** the changeset format if argument bPatchset is zero, or the patchset +** format otherwise. +*/ static int sessionAppendDelete( SessionBuffer *pBuf, /* Buffer to append to */ int bPatchset, /* True for "patchset", 0 for "changeset" */ - sqlite3_stmt *pStmt, /* Statement handle pointing at new row */ SessionChange *p, /* Object containing old values */ + int nCol, /* Number of columns in table */ u8 *abPK /* Boolean array - true for PK columns */ ){ int rc = SQLITE_OK; @@ -1591,7 +1596,6 @@ static int sessionAppendDelete( if( bPatchset==0 ){ sessionAppendBlob(pBuf, p->aRecord, p->nRecord, &rc); }else{ - int nCol = sqlite3_column_count(pStmt); int i; u8 *a = p->aRecord; for(i=0; izName, (int)strlen(pTab->zName)+1, pRc); } +/* +** Generate either a changeset (if argument bPatchset is zero) or a patchset +** (if it is non-zero) based on the current contents of the session object +** passed as the first argument. +** +** If no error occurs, SQLITE_OK is returned and the new changeset/patchset +** stored in output variables *pnChangeset and *ppChangeset. Or, if an error +** occurs, an SQLite error code is returned and both output variables set +** to 0. +*/ int sessionGenerateChangeset( sqlite3_session *pSession, /* Session object */ int bPatchset, /* True for patchset, false for changeset */ @@ -1827,7 +1841,7 @@ int sessionGenerateChangeset( rc = sessionAppendUpdate(&buf, bPatchset, pSel, p, abPK); } }else if( p->op!=SQLITE_INSERT ){ - rc = sessionAppendDelete(&buf, bPatchset, pSel, p, abPK); + rc = sessionAppendDelete(&buf, bPatchset, p, nCol, abPK); } if( rc==SQLITE_OK ){ rc = sqlite3_reset(pSel); @@ -1965,6 +1979,9 @@ int sqlite3changeset_start( ** When this function is called, *paChange points to the start of the record ** to deserialize. Assuming no error occurs, *paChange is set to point to ** one byte after the end of the same record before this function returns. +** If the argument abPK is NULL, then the record contains nCol values. Or, +** if abPK is other than NULL, then the record contains only the PK fields +** (in other words, it is a patchset DELETE record). ** ** If successful, each element of the apOut[] array (allocated by the caller) ** is set to point to an sqlite3_value object containing the value read diff --git a/ext/session/sqlite3session.h b/ext/session/sqlite3session.h index de4ee77b94..a6af9aca57 100644 --- a/ext/session/sqlite3session.h +++ b/ext/session/sqlite3session.h @@ -275,6 +275,26 @@ int sqlite3session_changeset( /* ** CAPI3REF: Generate A Patchset From A Session Object +** +** The differences between a patchset and a changeset are that: +** +**
    +**
  • DELETE records consist of the primary key fields only. The +** original values of other fields are omitted. +**
  • The original values of any modified fields are omitted from +** UPDATE records. +**
+** +** A patchset blob may be used with up to date versions of all +** sqlite3changeset_xxx API functions except for sqlite3changeset_invert(), +** which returns SQLITE_CORRUPT if it is passed a patchset. Similarly, +** attempting to use a patchset blob with old versions of the +** sqlite3changeset_xxx APIs also provokes an SQLITE_CORRUPT error. +** +** Because the non-primary key "old.*" fields are omitted, no +** SQLITE_CHANGESET_DATA conflicts can be detected or reported if a patchset +** is passed to the sqlite3changeset_apply() API. Other conflict types work +** in the same way as for changesets. */ int sqlite3session_patchset( sqlite3_session *pSession, /* Session object */ diff --git a/manifest b/manifest index 2e5dc07be7..feade027e6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fixes\sfor\sthe\ssqlite3changeset_concat()\sAPI\sregarding\spatchsets. -D 2014-08-16T16:47:55.133 +C Fix\ssome\smissing\sand\sout-of-date\scomments\sin\sthe\ssessions\smodule. +D 2014-08-16T19:01:00.672 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 639859a6f81bd15921ccd56ddbd6dfd335278377 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -155,8 +155,8 @@ F ext/session/sessionA.test eb05c13e4ef1ca8046a3a6dbf2d5f6f5b04a11d4 F ext/session/sessionB.test 51c70394bc04ac72d72f54bd0879614b9c34240c F ext/session/session_common.tcl 1539d8973b2aea0025c133eb0cc4c89fcef541a5 F ext/session/sessionfault.test 496291b287ba3c0b14ca2e074425e29cc92a64a6 -F ext/session/sqlite3session.c eed0f0510859e564f9f8c886d22a299579b5c6c1 -F ext/session/sqlite3session.h c99445ea9918343d3e62acafdf82bc5502cfba29 +F ext/session/sqlite3session.c f2385ab5ebac94d8e54cc3aa8dc9ca77f8cdf0d9 +F ext/session/sqlite3session.h ef0dbcd599ab8b83e3f3f2e9912e1734519a3ef4 F ext/session/test_session.c 920ccb6d6e1df263cd9099563328094c230b2925 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 @@ -1202,7 +1202,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 60a4565a8c44762a002cd02979317df5ca47e899 -R 1bd074b437e8898f047cce1541823103 +P dccb34859508eac8146ae5b19c447673d04be3b0 +R 7605cd9723f946167ef7a988888841f4 U dan -Z 66bd65019d7460afe376babf330097ba +Z 7c34f49d718669db325837ce5da84317 diff --git a/manifest.uuid b/manifest.uuid index 9786ee73ae..19c7a76bfc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -dccb34859508eac8146ae5b19c447673d04be3b0 \ No newline at end of file +05c1d9149b27c68e2654ed28491722927d2176f5 \ No newline at end of file From 2e934cd40c24e85562bf767ecdab2bcc19d10c08 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 18 Aug 2014 08:42:36 +0000 Subject: [PATCH 0111/1484] Add tests for sessions module. FossilOrigin-Name: 82fdb1975f5b29a751089a8582713372999ae56e --- ext/session/sessionB.test | 176 +++++++++++++++++++++++++++++++++++++- manifest | 12 +-- manifest.uuid | 2 +- 3 files changed, 182 insertions(+), 8 deletions(-) diff --git a/ext/session/sessionB.test b/ext/session/sessionB.test index 8791272f8e..d61cada98f 100644 --- a/ext/session/sessionB.test +++ b/ext/session/sessionB.test @@ -327,6 +327,180 @@ do_patchconcat_test 4.3.9 -revert { {DELETE t2 0 .XX. {{} {} i 1 i 2 {} {}} {}} } +#------------------------------------------------------------------------- +# More rigorous testing of the _patchset(), _apply and _concat() APIs. +# +# The inputs to each test are a populate database and a list of DML +# statements. This test determines that the final database is the same +# if: +# +# 1) the statements are executed directly on the database. +# +# 2) a single patchset is collected while executing the statements and +# then applied to a copy of the original database file. +# +# 3) individual patchsets are collected for statement while executing +# them and concatenated together before being applied to a copy of +# the original database. The concatenation is done in a couple of +# different ways - linear, pairwise etc. +# +# All tests, as it happens, are run with both changesets and patchsets. +# But the focus is on patchset capabilities. +# + +# Return a checksum of the contents of the database file. Implicit IPK +# columns are not included in the checksum - just modifying rowids does +# not change the database checksum. +# +proc databasecksum {db} { + set alltab [$db eval {SELECT name FROM sqlite_master WHERE type='table'}] + foreach tab $alltab { + $db eval "SELECT * FROM $tab LIMIT 1" res { } + set slist [list] + foreach col [lsort $res(*)] { + lappend slist "quote($col)" + } + set sql "SELECT [join $slist ,] FROM $tab" + append txt "[lsort [$db eval $sql]]\n" + } + return [md5 $txt] +} + +proc do_patchset_test {tn tstcmd lSql} { + if {$tstcmd != "patchset" && $tstcmd != "changeset"} { + error "have $tstcmd: must be patchset or changeset" + } + + foreach fname {test.db2 test.db3 test.db4 test.db5} { + forcedelete $fname + forcecopy test.db $fname + } + + # Execute the SQL statements on [db]. Collect a patchset for each + # individual statement, as well as a single patchset for the entire + # operation. + sqlite3session S db main + S attach * + foreach sql $lSql { + sqlite3session T db main + T attach * + db eval $sql + lappend lPatch [T patchset] + T delete + } + set patchset [S patchset] + S delete + + # Calculate a checksum for the final database. + set cksum [databasecksum db] + + # 1. Apply the single large patchset to test.db2 + sqlite3 db2 test.db2 + sqlite3changeset_apply db2 $patchset noop + uplevel [list do_test $tn.1 { databasecksum db2 } $cksum ] + db2 close + + # 2. Apply each of the single-statement patchsets to test.db3 + sqlite3 db2 test.db3 + foreach p $lPatch { + sqlite3changeset_apply db2 $p noop + } + uplevel [list do_test $tn.2 { databasecksum db2 } $cksum ] + db2 close + + # 3. Concatenate all single-statement patchsets into a single large + # patchset, then apply it to test.db4. + # + sqlite3 db2 test.db4 + set big "" + foreach p $lPatch { + set big [sqlite3changeset_concat $big $p] + } + sqlite3changeset_apply db2 $big noop + uplevel [list do_test $tn.3 { databasecksum db2 } $cksum ] + db2 close + + # 4. Concatenate all single-statement patchsets pairwise into a single + # large patchset, then apply it to test.db5. Pairwise concatenation: + # + # a b c d e f g h i j k + # -> {a b} {c d} {e f} {g h} {i j} k + # -> {a b c d} {e f g h} {i j k} + # -> {a b c d e f g h} {i j k} + # -> {a b c d e f g h i j k} + # -> APPLY! + # + sqlite3 db2 test.db5 + set L $lPatch + while {[llength $L] > 1} { + set O [list] + for {set i 0} {$i < [llength $L]} {incr i 2} { + if {$i==[llength $L]-1} { + lappend O [lindex $L $i] + } else { + set i1 [expr $i+1] + lappend O [sqlite3changeset_concat [lindex $L $i] [lindex $L $i1]] + } + } + set L $O + } + sqlite3changeset_apply db2 [lindex $L 0] noop + uplevel [list do_test $tn.4 { databasecksum db2 } $cksum ] + db2 close +} + +proc do_patchset_changeset_test {tn initsql args} { + foreach tstcmd {patchset changeset} { + reset_db + execsql $initsql + foreach sql $args { + set lSql [split $sql ";"] + uplevel [list do_patchset_test $tn.$tstcmd $tstcmd $lSql] + } + } +} + +do_patchset_changeset_test 5.1 { + CREATE TABLE t1(a PRIMARY KEY, b, c); + INSERT INTO t1 VALUES(1, 2, 3); +} { + INSERT INTO t1 VALUES(4, 5, 6); + DELETE FROM t1 WHERE a=1; +} { + INSERT INTO t1 VALUES(7, 8, 9); + UPDATE t1 SET c = 5; + INSERT INTO t1 VALUES(10, 11, 12); + UPDATE t1 SET c = 6; + INSERT INTO t1 VALUES(13, 14, 15); +} { + UPDATE t1 SET c=c+1; + DELETE FROM t1 WHERE (a%2); +} + +do_patchset_changeset_test 5.2 { + CREATE TABLE t1(a PRIMARY KEY, b, c); + CREATE TABLE t2(a, b, c, d, PRIMARY KEY(c, b)); +} { + INSERT INTO t1 VALUES(x'00', 0, 'zero'); + INSERT INTO t1 VALUES(x'01', 1, 'one'); + INSERT INTO t1 VALUES(x'02', 4, 'four'); + INSERT INTO t1 VALUES(x'03', 9, 'nine'); + INSERT INTO t1 VALUES(x'04', 16, 'sixteen'); + INSERT INTO t1 VALUES(x'05', 25, 'twenty-five'); +} { + UPDATE t1 SET a = b WHERE b<=4; + INSERT INTO t2 SELECT NULL, * FROM t1; + DELETE FROM t1 WHERE b=25; +} { + DELETE FROM t2; + INSERT INTO t2 SELECT NULL, * FROM t1; + DELETE FROM t1; + INSERT INTO t1 SELECT b, c, d FROM t2; + UPDATE t1 SET b = b+1; + UPDATE t1 SET b = b+1; + UPDATE t1 SET b = b+1; +} + + finish_test - diff --git a/manifest b/manifest index feade027e6..6060acbd59 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\ssome\smissing\sand\sout-of-date\scomments\sin\sthe\ssessions\smodule. -D 2014-08-16T19:01:00.672 +C Add\stests\sfor\ssessions\smodule. +D 2014-08-18T08:42:36.985 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 639859a6f81bd15921ccd56ddbd6dfd335278377 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -152,7 +152,7 @@ F ext/session/session6.test 443789bc2fca12e4f7075cf692c60b8a2bea1a26 F ext/session/session8.test 7d35947ad329b8966f095d34f9617a9eff52dc65 F ext/session/session9.test 776e46785c29c11cda01f5205d0f1e8f8f9a46bf F ext/session/sessionA.test eb05c13e4ef1ca8046a3a6dbf2d5f6f5b04a11d4 -F ext/session/sessionB.test 51c70394bc04ac72d72f54bd0879614b9c34240c +F ext/session/sessionB.test 77fca512719c136b8e1f4cb77b77e4c62b9d09ad F ext/session/session_common.tcl 1539d8973b2aea0025c133eb0cc4c89fcef541a5 F ext/session/sessionfault.test 496291b287ba3c0b14ca2e074425e29cc92a64a6 F ext/session/sqlite3session.c f2385ab5ebac94d8e54cc3aa8dc9ca77f8cdf0d9 @@ -1202,7 +1202,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P dccb34859508eac8146ae5b19c447673d04be3b0 -R 7605cd9723f946167ef7a988888841f4 +P 05c1d9149b27c68e2654ed28491722927d2176f5 +R 03b8d5b2540614bccade3685e83e41dc U dan -Z 7c34f49d718669db325837ce5da84317 +Z cda8ef5f85a6d704893f36da729451e0 diff --git a/manifest.uuid b/manifest.uuid index 19c7a76bfc..01d5ecc3e5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -05c1d9149b27c68e2654ed28491722927d2176f5 \ No newline at end of file +82fdb1975f5b29a751089a8582713372999ae56e \ No newline at end of file From e62296100f7f32a53b3c6cea88ef4618057b503f Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 18 Aug 2014 15:08:26 +0000 Subject: [PATCH 0112/1484] Begin adding commands to the command-line interface for interacting with the sessions extension. This is the first check-in of a work-in-progress. FossilOrigin-Name: c2fcf0b9f4bdc48dfc6530bda4f531b94a833207 --- main.mk | 5 ++ manifest | 17 +++--- manifest.uuid | 2 +- src/shell.c | 151 ++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 167 insertions(+), 8 deletions(-) diff --git a/main.mk b/main.mk index 73c9847408..24e599ca5b 100644 --- a/main.mk +++ b/main.mk @@ -72,6 +72,8 @@ LIBOBJ+= vdbe.o parse.o \ vdbeapi.o vdbeaux.o vdbeblob.o vdbemem.o vdbesort.o \ vdbetrace.o wal.o walker.o where.o utf.o vtab.o +LIBOBJ += sqlite3session.o + # All of the source code files. @@ -563,6 +565,9 @@ fts3_write.o: $(TOP)/ext/fts3/fts3_write.c $(HDR) $(EXTHDR) rtree.o: $(TOP)/ext/rtree/rtree.c $(HDR) $(EXTHDR) $(TCCX) -DSQLITE_CORE -c $(TOP)/ext/rtree/rtree.c +sqlite3session.o: $(TOP)/ext/session/sqlite3session.c $(HDR) $(EXTHDR) + $(TCCX) -DSQLITE_CORE -c $(TOP)/ext/session/sqlite3session.c + # Rules for building test programs and for running tests # diff --git a/manifest b/manifest index 84f92a5c48..3a3abec595 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sthe\slatest\strunk\schanges,\sand\sin\sparticular\sthe\srefactoring\sof\sthe\nobject\snames\sin\sthe\scommand-line\sshell. -D 2014-08-18T13:48:41.625 +C Begin\sadding\scommands\sto\sthe\scommand-line\sinterface\sfor\sinteracting\swith\nthe\ssessions\sextension.\s\sThis\sis\sthe\sfirst\scheck-in\sof\sa\swork-in-progress. +D 2014-08-18T15:08:26.073 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 639859a6f81bd15921ccd56ddbd6dfd335278377 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -161,7 +161,7 @@ F ext/session/test_session.c 920ccb6d6e1df263cd9099563328094c230b2925 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60 -F main.mk 152593de5d19eeab0fdaacfdedd5eafdfdd83d5a +F main.mk eb6742eba7ebb8dc18401220e7ce21788d41aaef F mkopcodec.awk c2ff431854d702cdd2d779c9c0d1f58fa16fa4ea F mkopcodeh.awk c6b3fa301db6ef7ac916b14c60868aeaec1337b5 F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83 @@ -238,7 +238,7 @@ F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c 0ea356d32a5e884add23d1b9b4e8736681dd5697 F src/rowset.c a9c9aae3234b44a6d7c6f5a3cadf90dce1e627be F src/select.c ea48e891406ccdf748f3eb02893e056d134a0fea -F src/shell.c 41df1103617331e023301d943977f8c06bd1486f +F src/shell.c 6378fc281ab6c2c5ee46cf13f2657e8a187c3ce7 F src/sqlite.h.in 021a1f5c50e83060675d994a6014fd409e611d9e F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc @@ -1202,7 +1202,10 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 82fdb1975f5b29a751089a8582713372999ae56e 11a70e1ae7f05d06e4e09c9d20db0444b8881584 -R 9eb07c2c47c345635567e1ec3d8ef22d +P 419d286a2fc465f6e0f9662909d0cc52a18eefa4 +R 23a3bfb6cd8e3a34baca1f6d98151d23 +T *branch * sessions_from_cli +T *sym-sessions_from_cli * +T -sym-sessions * U drh -Z 44d5fceffc6c6ae323a3b362c9fccbd4 +Z dbfbe7f80e47f8918e41f67c20d63911 diff --git a/manifest.uuid b/manifest.uuid index 3f8761cf9d..c0786ba14f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -419d286a2fc465f6e0f9662909d0cc52a18eefa4 \ No newline at end of file +c2fcf0b9f4bdc48dfc6530bda4f531b94a833207 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 87b335fbb1..66f073a9a8 100644 --- a/src/shell.c +++ b/src/shell.c @@ -432,6 +432,19 @@ static char *one_input_line(FILE *in, char *zPrior, int isContinuation){ return zResult; } +#if defined(SQLITE_ENABLE_SESSION) +/* +** State information for a single open session +*/ +typedef struct OpenSession OpenSession; +struct OpenSession { + char *zName; /* Symbolic name for this session */ + int nFilter; /* Number of xFilter rejection GLOB patterns */ + char **azFilter; /* Array of xFilter rejection GLOB patterns */ + sqlite3_session *p; /* The open session */ +}; +#endif + /* ** Shell output mode information from before ".explain on", ** saved so that it can be restored by ".explain off" @@ -479,6 +492,10 @@ struct ShellState { int *aiIndent; /* Array of indents used in MODE_Explain */ int nIndent; /* Size of array aiIndent[] */ int iIndent; /* Index of current op in aiIndent[] */ +#if defined(SQLITE_ENABLE_SESSION) + int nSession; /* Number of active sessions */ + OpenSession aSession[4]; /* Array of sessions. [0] is in focus. */ +#endif }; /* @@ -1636,6 +1653,9 @@ static char zHelp[] = " LIKE pattern TABLE.\n" ".separator STRING ?NL? Change separator used by output mode and .import\n" " NL is the end-of-line mark for CSV\n" +#if defined(SQLITE_ENABLE_SESSION) + ".session CMD ... Create or control sessions\n" +#endif ".shell CMD ARGS... Run CMD ARGS... in a system shell\n" ".show Show the current values for various settings\n" ".stats on|off Turn stats on or off\n" @@ -1651,6 +1671,30 @@ static char zHelp[] = " Negative values right-justify\n" ; +#if defined(SQLITE_ENABLE_SESSION) +/* +** Print help information for the ".sessions" command +*/ +void session_help(ShellState *p){ + fprintf(p->out, + ".session ?NAME? SUBCOMMAND ?ARGS...?\n" + "If ?NAME? is omitted, the first defined session is used.\n" + "Subcommands:\n" + " attach TABLE Attach TABLE\n" + " changeset FILE Write a changeset into FILE\n" + " close Close one session\n" + " enable ?BOOLEAN? Set or query the enable bit\n" + " filter GLOB... Reject tables matching GLOBs\n" + " indirect ?BOOLEAN? Mark or query the indirect status\n" + " isempty Query whether the session is empty\n" + " list List currently open session names\n" + " open DB NAME Open a new session on DB\n" + " patchset FILE Write a patchset into FILE\n" + ); +} +#endif + + /* Forward reference */ static int process_input(ShellState *p, FILE *in); /* @@ -1714,6 +1758,36 @@ static void writefileFunc( sqlite3_result_int64(context, rc); } +#if defined(SQLITE_ENABLE_SESSION) +/* +** Close a single OpenSession object and release all of its associated +** resources. +*/ +static void session_close(OpenSession *pSession){ + int i; + sqlite3session_delete(pSession->p); + sqlite3_free(pSession->zName); + for(i=0; inFilter; i++){ + sqlite3_free(pSession->azFilter[i]); + } + sqlite3_free(pSession->azFilter); + memset(pSession, 0, sizeof(OpenSession)); +} +#endif + +/* +** Close all OpenSession objects and release all assocaited resources. +*/ +static void session_close_all(ShellState *p){ +#if defined(SQLITE_ENABLE_SESSION) + int i; + for(i=0; inSession; i++){ + session_close(&p->aSession[i]); + } + p->nSession = 0; +#endif +} + /* ** Make sure the database is open. If it is not, then open it. If ** the database fails to open, print an error message and exit. @@ -2865,6 +2939,7 @@ static int do_meta_command(char *zLine, ShellState *p){ } open_db(p, 1); if( p->db!=0 ){ + session_close_all(p); sqlite3_close(savedDb); sqlite3_free(p->zFreeOnClose); p->zFreeOnClose = zNewFilename; @@ -3086,6 +3161,81 @@ static int do_meta_command(char *zLine, ShellState *p){ } }else +#if defined(SQLITE_ENABLE_SESSION) + if( c=='s' && strncmp(azArg[0],"session",n)==0 && n>=3 ){ + OpenSession *pSession = &p->aSession[0]; + char **azCmd = &azArg[1]; + int iSes = 0; + int nCmd = nArg - 1; + int i; + if( nArg<=1 ) goto session_syntax_error; + if( nArg>=3 ){ + for(iSes=0; iSesnSession; iSes++){ + if( strcmp(p->aSession[iSes].zName, azArg[1])==0 ) break; + } + if( iSesnSession ){ + pSession = &p->aSession[iSes]; + azCmd++; + nCmd--; + }else{ + pSession = &p->aSession[0]; + iSes = 0; + } + } + + /* .session close + ** Close the identified session + */ + if( strcmp(azCmd[0], "close")==0 ){ + if( p->nSession ){ + session_close(pSession); + p->aSession[iSes] = p->aSession[--p->nSession]; + } + }else + + /* .session list + ** List all currently open sessions + */ + if( strcmp(azCmd[0],"list")==0 ){ + for(i=0; inSession; i++){ + fprintf(p->out, "%d %s\n", i, p->aSession[i].zName); + } + }else + + /* .session open DB NAME + ** Open a new session called NAME on the attached database DB. + ** DB is normally "main". + */ + if( strcmp(azCmd[0],"open")==0 ){ + char *zName; + if( nCmd!=3 ) goto session_syntax_error; + zName = azCmd[2]; + if( zName[0]==0 ) goto session_syntax_error; + for(i=0; inSession; i++){ + if( strcmp(p->aSession[i].zName,zName)==0 ){ + fprintf(stderr, "Session \"%s\" already exists\n", zName); + goto meta_command_exit; + } + } + if( p->nSession>=ArraySize(p->aSession) ){ + fprintf(stderr, "Maximum of %d sessions\n", ArraySize(p->aSession)); + goto meta_command_exit; + } + pSession = &p->aSession[p->nSession]; + rc = sqlite3session_create(p->db, azCmd[1], &pSession->p); + if( rc ){ + fprintf(stderr, "Cannot open session: error code=%d\n", rc); + goto meta_command_exit; + } + p->nSession++; + pSession->zName = sqlite3_mprintf("%s", zName); + }else + /* If no command name matches, show a syntax error */ + session_syntax_error: + session_help(p); + }else +#endif + #ifdef SQLITE_DEBUG /* Undocumented commands for internal testing. Subject to change ** without notice. */ @@ -4134,6 +4284,7 @@ int main(int argc, char **argv){ } set_table_name(&data, 0); if( data.db ){ + session_close_all(&data); sqlite3_close(data.db); } sqlite3_free(data.zFreeOnClose); From 082c96dffa373ed10d000001edce62ae757f13ec Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 18 Aug 2014 16:03:46 +0000 Subject: [PATCH 0113/1484] Add miscellaneous test cases to improve coverage of sessions module. FossilOrigin-Name: 0fac6cfffe628ea02c78ebad065307309ec9eaa1 --- ext/session/session1.test | 18 +++++++ ext/session/sessionB.test | 15 +++++- ext/session/sessionfault.test | 52 ++++++++++++++++-- ext/session/sqlite3session.c | 18 ++++--- ext/session/sqlite3session.h | 4 ++ ext/session/test_session.c | 99 +++++++++++++++++++++++++++++++++++ manifest | 24 ++++----- manifest.uuid | 2 +- 8 files changed, 207 insertions(+), 25 deletions(-) diff --git a/ext/session/session1.test b/ext/session/session1.test index e47fb3e845..e6f9c8fd7f 100644 --- a/ext/session/session1.test +++ b/ext/session/session1.test @@ -492,6 +492,24 @@ do_test 8.3 { } {1} do_test 8.4 { S delete } {} +do_test 8.5 { + sqlite3session S db main + S attach t5 + S attach t6 + execsql { INSERT INTO t5 VALUES(1, 2) } + S isempty +} {0} + +do_test 8.6 { + S delete + sqlite3session S db main + S attach t5 + S attach t6 + execsql { INSERT INTO t6 VALUES(1, 2) } + S isempty +} {0} +do_test 8.7 { S delete } {} + #------------------------------------------------------------------------- # do_execsql_test 9.1 { diff --git a/ext/session/sessionB.test b/ext/session/sessionB.test index d61cada98f..9798cabfee 100644 --- a/ext/session/sessionB.test +++ b/ext/session/sessionB.test @@ -453,9 +453,11 @@ proc do_patchset_changeset_test {tn initsql args} { foreach tstcmd {patchset changeset} { reset_db execsql $initsql + set x 0 foreach sql $args { + incr x set lSql [split $sql ";"] - uplevel [list do_patchset_test $tn.$tstcmd $tstcmd $lSql] + uplevel [list do_patchset_test $tn.$tstcmd.$x $tstcmd $lSql] } } } @@ -501,6 +503,17 @@ do_patchset_changeset_test 5.2 { UPDATE t1 SET b = b+1; } +set initsql { CREATE TABLE t1(a, b, c, PRIMARY KEY(c, b)); } +for {set i 0} {$i < 1000} {incr i} { + append insert "INSERT INTO t1 VALUES($i, $i, $i);" + append delete "DELETE FROM t1 WHERE b=$i;" +} +do_patchset_changeset_test 5.3 \ + $initsql $insert $delete \ + $insert $delete \ + "$insert $delete" \ + $delete + finish_test diff --git a/ext/session/sessionfault.test b/ext/session/sessionfault.test index f17daccfc7..4b278098a9 100644 --- a/ext/session/sessionfault.test +++ b/ext/session/sessionfault.test @@ -20,8 +20,6 @@ source $testdir/tester.tcl set testprefix sessionfault -if 1 { - forcedelete test.db2 sqlite3 db2 test.db2 do_common_sql { @@ -399,8 +397,6 @@ do_faultsim_test 9.1 -faults oom-transient -prep { } } -} - faultsim_delete_and_reopen do_test 9.2.prep { execsql { @@ -438,6 +434,54 @@ do_faultsim_test 9.2 -faults oom-transient -prep { } } +#------------------------------------------------------------------------- +# Test that if a conflict-handler encounters an OOM in +# sqlite3_value_text() but goes on to return SQLITE_CHANGESET_REPLACE +# anyway, the OOM is picked up by the sessions module. +set bigstr [string repeat abcdefghij 100] +faultsim_delete_and_reopen +do_test 10.prep.1 { + execsql { + CREATE TABLE t1(a PRIMARY KEY, b); + INSERT INTO t1 VALUES($bigstr, $bigstr); + } + + sqlite3session S db main + S attach * + execsql { UPDATE t1 SET b = b||'x' } + set C [S changeset] + S delete + execsql { UPDATE t1 SET b = b||'xyz' } +} {} +faultsim_save_and_close + +faultsim_restore_and_reopen +do_test 10.prep.2 { + proc xConflict {args} { return "ABORT" } + list [catch { sqlite3changeset_apply db $C xConflict } msg] $msg +} {1 SQLITE_ABORT} +do_execsql_test 10.prep.3 { SELECT b=$bigstr||'x' FROM t1 } 0 +do_test 10.prep.4 { + proc xConflict {args} { return "REPLACE" } + list [catch { sqlite3changeset_apply db $C xConflict } msg] $msg +} {0 {}} +do_execsql_test 10.prep.5 { SELECT b=$bigstr||'x' FROM t1 } 1 +db close + +do_faultsim_test 10 -faults oom-tra* -prep { + faultsim_restore_and_reopen +} -body { + sqlite3changeset_apply_replace_all db $::C +} -test { + faultsim_test_result {0 {}} {1 SQLITE_NOMEM} + if {$testrc==0} { + if {[db one {SELECT b=$bigstr||'x' FROM t1}]==0} { + error "data does not look right" + } + } +} + + finish_test diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index 69d67817bf..18dba064ec 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -2703,10 +2703,14 @@ static int sessionBindValue( sqlite3_value *pVal /* Value to bind */ ){ int eType = sqlite3_value_type(pVal); + /* COVERAGE: The (pVal->z==0) branch is never true using current versions + ** of SQLite. If a malloc fails in an sqlite3_value_xxx() function, either + ** the (pVal->z) variable remains as it was or the type of the value is + ** set to SQLITE_NULL. */ if( (eType==SQLITE_TEXT || eType==SQLITE_BLOB) && pVal->z==0 ){ /* This condition occurs when an earlier OOM in a call to ** sqlite3_value_text() or sqlite3_value_blob() (perhaps from within - ** a conflict-hanler) has zeroed the pVal->z pointer. Return NOMEM. */ + ** a conflict-handler) has zeroed the pVal->z pointer. Return NOMEM. */ return SQLITE_NOMEM; } return sqlite3_bind_value(pStmt, i, pVal); @@ -3052,6 +3056,8 @@ int sqlite3changeset_apply( int nTab = 0; /* Result of sqlite3Strlen30(zTab) */ SessionApplyCtx sApply; /* changeset_apply() context object */ + assert( xConflict!=0 ); + memset(&sApply, 0, sizeof(sApply)); rc = sqlite3changeset_start(&pIter, nChangeset, pChangeset); if( rc!=SQLITE_OK ) return rc; @@ -3169,12 +3175,10 @@ int sqlite3changeset_apply( sqlite3_db_status(db, SQLITE_DBSTATUS_DEFERRED_FKS, &nFk, ¬Used, 0); if( nFk!=0 ){ int res = SQLITE_CHANGESET_ABORT; - if( xConflict ){ - sqlite3_changeset_iter sIter; - memset(&sIter, 0, sizeof(sIter)); - sIter.nCol = nFk; - res = xConflict(pCtx, SQLITE_CHANGESET_FOREIGN_KEY, &sIter); - } + sqlite3_changeset_iter sIter; + memset(&sIter, 0, sizeof(sIter)); + sIter.nCol = nFk; + res = xConflict(pCtx, SQLITE_CHANGESET_FOREIGN_KEY, &sIter); if( res!=SQLITE_CHANGESET_OMIT ){ rc = SQLITE_CONSTRAINT; } diff --git a/ext/session/sqlite3session.h b/ext/session/sqlite3session.h index a6af9aca57..ced984ecbe 100644 --- a/ext/session/sqlite3session.h +++ b/ext/session/sqlite3session.h @@ -735,6 +735,10 @@ int sqlite3changeset_concat( ** invoked. A description of exactly when the conflict handler is invoked for ** each type of change is below. ** +** Unlike the xFilter argument, xConflict may not be passed NULL. The results +** of passing anything other than a valid function pointer as the xConflict +** argument are undefined. +** ** Each time the conflict handler function is invoked, it must return one ** of [SQLITE_CHANGESET_OMIT], [SQLITE_CHANGESET_ABORT] or ** [SQLITE_CHANGESET_REPLACE]. SQLITE_CHANGESET_REPLACE may only be returned diff --git a/ext/session/test_session.c b/ext/session/test_session.c index fa99f56786..38e4be1481 100644 --- a/ext/session/test_session.c +++ b/ext/session/test_session.c @@ -417,6 +417,13 @@ static int test_conflict_handler( rc = sqlite3changeset_old(pIter, nCol, &pVal); assert( rc==SQLITE_RANGE ); } + if( eConf!=SQLITE_CHANGESET_FOREIGN_KEY ){ + /* eConf!=FOREIGN_KEY is always true at this point. The condition is + ** just there to make it clearer what is being tested. */ + int nDummy; + int rc = sqlite3changeset_fk_conflicts(pIter, &nDummy); + assert( rc==SQLITE_MISUSE ); + } /* End of testing block ***********************************************************************/ } @@ -440,6 +447,51 @@ static int test_conflict_handler( return ret; } +/* +** The conflict handler used by sqlite3changeset_apply_replace_all(). +** This conflict handler calls sqlite3_value_text16() on all available +** sqlite3_value objects and then returns CHANGESET_REPLACE, or +** CHANGESET_OMIT if REPLACE is not applicable. This is used to test the +** effect of a malloc failure within an sqlite3_value_xxx() function +** invoked by a conflict-handler callback. +*/ +static int replace_handler( + void *pCtx, /* Pointer to TestConflictHandler structure */ + int eConf, /* DATA, MISSING, CONFLICT, CONSTRAINT */ + sqlite3_changeset_iter *pIter /* Handle describing change and conflict */ +){ + int op; /* SQLITE_UPDATE, DELETE or INSERT */ + const char *zTab; /* Name of table conflict is on */ + int nCol; /* Number of columns in table zTab */ + int i; + int x = 0; + + sqlite3changeset_op(pIter, &zTab, &nCol, &op, 0); + + if( op!=SQLITE_INSERT ){ + for(i=0; i Date: Mon, 18 Aug 2014 17:56:31 +0000 Subject: [PATCH 0114/1484] Add the "changeset" command-line utility for getting an ASCII dump of change sets. FossilOrigin-Name: 55bb3544a6b474c04853270067a35ca4b0079f52 --- ext/session/changeset.c | 314 ++++++++++++++++++++++++++++++++++++++++ main.mk | 4 + manifest | 18 +-- manifest.uuid | 2 +- src/shell.c | 49 +++++++ 5 files changed, 376 insertions(+), 11 deletions(-) create mode 100644 ext/session/changeset.c diff --git a/ext/session/changeset.c b/ext/session/changeset.c new file mode 100644 index 0000000000..62817a64e5 --- /dev/null +++ b/ext/session/changeset.c @@ -0,0 +1,314 @@ +/* +** 2014-08-18 +** +** 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 contains code to implement the "changeset" command line +** utility for displaying and transforming changesets generated by +** the Sessions extension. +*/ +#include "sqlite3.h" +#include +#include +#include +#include +#include + + +/* +** Show a usage message on stderr then quit. +*/ +static void usage(const char *argv0){ + fprintf(stderr, "Usage: %s FILENAME COMMAND ...\n", argv0); + fprintf(stderr, + "COMMANDs:\n" + " apply DB Apply the changeset to database file DB\n" + " concat FILE2 OUT Concatenate FILENAME and FILE2 into OUT\n" + " dump Show the complete content of the changeset\n" + " invert OUT Write an inverted changeset into file OUT\n" + " sql Give a pseudo-SQL rendering of the changeset\n" + ); + exit(1); +} + +/* +** Read the content of a disk file into an in-memory buffer +*/ +static void readFile(const char *zFilename, int *pSz, void **ppBuf){ + FILE *f; + int sz; + void *pBuf; + f = fopen(zFilename, "rb"); + if( f==0 ){ + fprintf(stderr, "cannot open \"%s\" for reading\n", zFilename); + exit(1); + } + fseek(f, 0, SEEK_END); + sz = (int)ftell(f); + rewind(f); + pBuf = sqlite3_malloc( sz ? sz : 1 ); + if( pBuf==0 ){ + fprintf(stderr, "cannot allocate %d to hold content of \"%s\"\n", + sz, zFilename); + exit(1); + } + if( sz>0 ){ + if( fread(pBuf, sz, 1, f)!=1 ){ + fprintf(stderr, "cannot read all %d bytes of \"%s\"\n", sz, zFilename); + exit(1); + } + fclose(f); + } + *pSz = sz; + *ppBuf = pBuf; +} + +/* Array for converting from half-bytes (nybbles) into ASCII hex +** digits. */ +static const char hexdigits[] = { + '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' +}; + +/* +** Render an sqlite3_value as an SQL string. +*/ +static void renderValue(sqlite3_value *pVal){ + switch( sqlite3_value_type(pVal) ){ + case SQLITE_FLOAT: { + double r1; + char zBuf[50]; + r1 = sqlite3_value_double(pVal); + sqlite3_snprintf(sizeof(zBuf), zBuf, "%!.15g", r1); + printf("%s", zBuf); + break; + } + case SQLITE_INTEGER: { + printf("%lld", sqlite3_value_int64(pVal)); + break; + } + case SQLITE_BLOB: { + char const *zBlob = sqlite3_value_blob(pVal); + int nBlob = sqlite3_value_bytes(pVal); + int i; + printf("x'"); + for(i=0; i>4)&0x0F]); + putchar(hexdigits[(zBlob[i])&0x0F]); + } + putchar('\''); + break; + } + case SQLITE_TEXT: { + const unsigned char *zArg = sqlite3_value_text(pVal); + putchar('\''); + while( zArg[0] ){ + putchar(zArg[0]); + if( zArg[0]=='\'' ) putchar(zArg[0]); + zArg++; + } + putchar('\''); + break; + } + default: { + assert( sqlite3_value_type(pVal)==SQLITE_NULL ); + printf("NULL"); + break; + } + } +} + +int main(int argc, char **argv){ + int sz, rc; + void *pBuf = 0; + if( argc<3 ) usage(argv[0]); + readFile(argv[1], &sz, &pBuf); + + /* changeset FILENAME apply DB + ** Apply the changeset in FILENAME to the database file DB + */ + if( strcmp(argv[2],"apply")==0 ){ + fprintf(stderr, "not yet implemented\n"); + }else + + /* changeset FILENAME concat FILE2 OUT + ** Add changeset FILE2 onto the end of the changeset in FILENAME + ** and write the result into OUT. + */ + if( strcmp(argv[2],"concat")==0 ){ + fprintf(stderr, "not yet implemented\n"); + }else + + /* changeset FILENAME dump + ** Show the complete content of the changeset in FILENAME + */ + if( strcmp(argv[2],"dump")==0 ){ + int cnt = 0; + int i; + sqlite3_changeset_iter *pIter; + rc = sqlite3changeset_start(&pIter, sz, pBuf); + if( rc!=SQLITE_OK ){ + fprintf(stderr, "sqlite3changeset_start() returns %d\n", rc); + exit(1); + } + while( sqlite3changeset_next(pIter)==SQLITE_ROW ){ + int op, bIndirect, nCol; + const char *zTab; + unsigned char *abPK; + sqlite3changeset_op(pIter, &zTab, &nCol, &op, &bIndirect); + cnt++; + printf("%d: %s table=[%s] indirect=%d nColumn=%d\n", + cnt, op==SQLITE_INSERT ? "INSERT" : + op==SQLITE_UPDATE ? "UPDATE" : "DELETE", + zTab, bIndirect, nCol); + sqlite3changeset_pk(pIter, &abPK, 0); + for(i=0; i=3 ){ for(iSes=0; iSesnSession; iSes++){ if( strcmp(p->aSession[iSes].zName, azArg[1])==0 ) break; @@ -3183,6 +3184,53 @@ static int do_meta_command(char *zLine, ShellState *p){ } } + /* .session attach TABLE + ** Invoke the sqlite3session_attach() interface to attach a particular + ** table so that it is never filtered. + */ + if( strcmp(azCmd[0],"attach")==0 ){ + if( nCmd!=2 ) goto session_syntax_error; + if( pSession->p==0 ){ + session_not_open: + fprintf(stderr, "ERROR: No sessions are open\n"); + }else{ + rc = sqlite3session_attach(pSession->p, azCmd[1]); + if( rc ){ + fprintf(stderr, "ERROR: sqlite3session_attach() returns %d\n", rc); + rc = 0; + } + } + }else + + /* .session changeset FILE + ** .session patchset FILE + ** Write a changeset or patchset into a file. The file is overwritten. + */ + if( strcmp(azCmd[0],"changeset")==0 || strcmp(azCmd[0],"patchset")==0 ){ + FILE *out = 0; + if( nCmd!=2 ) goto session_syntax_error; + if( pSession->p==0 ) goto session_not_open; + out = fopen(azCmd[1], "wb"); + if( out==0 ){ + fprintf(stderr, "ERROR: cannot open \"%s\" for writing\n", azCmd[1]); + }else{ + int szChng; + void *pChng; + if( azCmd[0][0]=='c' ){ + sqlite3session_changeset(pSession->p, &szChng, &pChng); + }else{ + sqlite3session_patchset(pSession->p, &szChng, &pChng); + } + if( pChng + && fwrite(pChng, szChng, 1, out)!=1 ){ + fprintf(stderr, "ERROR: Failed to write entire %d-byte output\n", + szChng); + } + sqlite3_free(pChng); + fclose(out); + } + }else + /* .session close ** Close the identified session */ @@ -3225,6 +3273,7 @@ static int do_meta_command(char *zLine, ShellState *p){ rc = sqlite3session_create(p->db, azCmd[1], &pSession->p); if( rc ){ fprintf(stderr, "Cannot open session: error code=%d\n", rc); + rc = 0; goto meta_command_exit; } p->nSession++; From 03168cacd5c139471e651cf825501a953e0fcd4c Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 18 Aug 2014 20:01:31 +0000 Subject: [PATCH 0115/1484] A reasonably complete implementation of the "changeset" command-line tool and the ".sessions" command in the command-line shell. FossilOrigin-Name: 7b12f1f9c012f33d376242920583807b014b3287 --- ext/session/changeset.c | 108 ++++++++++++++++++++++++++++++++++++++-- manifest | 14 +++--- manifest.uuid | 2 +- src/shell.c | 80 +++++++++++++++++++++++++++++ 4 files changed, 191 insertions(+), 13 deletions(-) diff --git a/ext/session/changeset.c b/ext/session/changeset.c index 62817a64e5..1ff5cde87d 100644 --- a/ext/session/changeset.c +++ b/ext/session/changeset.c @@ -124,6 +124,58 @@ static void renderValue(sqlite3_value *pVal){ } } +/* +** Number of conflicts seen +*/ +static int nConflict = 0; + +/* +** The conflict callback +*/ +static int conflictCallback( + void *pCtx, + int eConflict, + sqlite3_changeset_iter *pIter +){ + int op, bIndirect, nCol, i; + const char *zTab; + unsigned char *abPK; + const char *zType = ""; + const char *zOp = ""; + const char *zSep = " "; + + nConflict++; + sqlite3changeset_op(pIter, &zTab, &nCol, &op, &bIndirect); + sqlite3changeset_pk(pIter, &abPK, 0); + switch( eConflict ){ + case SQLITE_CHANGESET_DATA: zType = "DATA"; break; + case SQLITE_CHANGESET_NOTFOUND: zType = "NOTFOUND"; break; + case SQLITE_CHANGESET_CONFLICT: zType = "PRIMARY KEY"; break; + case SQLITE_CHANGESET_FOREIGN_KEY: zType = "FOREIGN KEY"; break; + case SQLITE_CHANGESET_CONSTRAINT: zType = "CONSTRAINT"; break; + } + switch( op ){ + case SQLITE_UPDATE: zOp = "UPDATE of"; break; + case SQLITE_INSERT: zOp = "INSERT into"; break; + case SQLITE_DELETE: zOp = "DELETE from"; break; + } + printf("%s conflict on %s table %s with primary key", zType, zOp, zTab); + for(i=0; inFilter; i++){ + if( sqlite3_strglob(pSession->azFilter[i], zTab)==0 ) return 0; + } + return 1; +} +#endif + /* ** Make sure the database is open. If it is not, then open it. If ** the database fails to open, print an error message and exit. @@ -3235,12 +3250,75 @@ static int do_meta_command(char *zLine, ShellState *p){ ** Close the identified session */ if( strcmp(azCmd[0], "close")==0 ){ + if( nCmd!=1 ) goto session_syntax_error; if( p->nSession ){ session_close(pSession); p->aSession[iSes] = p->aSession[--p->nSession]; } }else + /* .session enable ?BOOLEAN? + ** Query or set the enable flag + */ + if( strcmp(azCmd[0], "enable")==0 ){ + int ii; + if( nCmd>2 ) goto session_syntax_error; + ii = nCmd==1 ? -1 : booleanValue(azCmd[1]); + if( p->nSession ){ + ii = sqlite3session_enable(pSession->p, ii); + fprintf(p->out, "session %s enable flag = %d\n", pSession->zName, ii); + } + }else + + /* .session filter GLOB .... + ** Set a list of GLOB patterns of table names to be excluded. + */ + if( strcmp(azCmd[0], "filter")==0 ){ + int ii, nByte; + if( nCmd<2 ) goto session_syntax_error; + if( p->nSession ){ + for(ii=0; iinFilter; ii++){ + sqlite3_free(pSession->azFilter[ii]); + } + sqlite3_free(pSession->azFilter); + nByte = sizeof(pSession->azFilter[0])*(nCmd-1); + pSession->azFilter = sqlite3_malloc( nByte ); + if( pSession->azFilter==0 ){ + fprintf(stderr, "Error: out or memory\n"); + exit(1); + } + for(ii=1; iiazFilter[ii-1] = sqlite3_mprintf("%s", azCmd[ii]); + } + pSession->nFilter = ii-1; + } + }else + + /* .session indirect ?BOOLEAN? + ** Query or set the indirect flag + */ + if( strcmp(azCmd[0], "indirect")==0 ){ + int ii; + if( nCmd>2 ) goto session_syntax_error; + ii = nCmd==1 ? -1 : booleanValue(azCmd[1]); + if( p->nSession ){ + ii = sqlite3session_indirect(pSession->p, ii); + fprintf(p->out, "session %s indirect flag = %d\n", pSession->zName,ii); + } + }else + + /* .session isempty + ** Determine if the session is empty + */ + if( strcmp(azCmd[0], "isempty")==0 ){ + int ii; + if( nCmd!=1 ) goto session_syntax_error; + if( p->nSession ){ + ii = sqlite3session_isempty(pSession->p); + fprintf(p->out, "session %s isempty flag = %d\n", pSession->zName, ii); + } + }else + /* .session list ** List all currently open sessions */ @@ -3276,6 +3354,8 @@ static int do_meta_command(char *zLine, ShellState *p){ rc = 0; goto meta_command_exit; } + pSession->nFilter = 0; + sqlite3session_table_filter(pSession->p, session_filter, pSession); p->nSession++; pSession->zName = sqlite3_mprintf("%s", zName); }else From f5ab08c77903a3c2dfa0a68c3c243ce1ab047686 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 18 Aug 2014 20:14:30 +0000 Subject: [PATCH 0116/1484] Fix a harmless compiler warning in the sessionAppendDelete() function. FossilOrigin-Name: 1324d08d0c639378cf1b03bd6410db81947747ac --- ext/session/sqlite3session.c | 2 +- manifest | 13 ++++++------- manifest.uuid | 2 +- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index 18dba064ec..4617e6a3c2 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -1621,7 +1621,7 @@ static int sessionAppendDelete( } } if( abPK[i] ){ - sessionAppendBlob(pBuf, pStart, a-pStart, &rc); + sessionAppendBlob(pBuf, pStart, (int)(a-pStart), &rc); } } assert( (a - p->aRecord)==p->nRecord ); diff --git a/manifest b/manifest index 3199c22597..eba81a57c4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\s"changeset"\scommand-line\stool\sfor\sanalyzing\sand\smanipulating\nchangesets\sin\sfiles\son\sdisk.\s\sAdd\sthe\s".session"\scommand\sto\sthe\scommand-line\ntool. -D 2014-08-18T20:08:25.748 +C Fix\sa\sharmless\scompiler\swarning\sin\sthe\ssessionAppendDelete()\sfunction. +D 2014-08-18T20:14:30.667 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 639859a6f81bd15921ccd56ddbd6dfd335278377 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -156,7 +156,7 @@ F ext/session/sessionA.test eb05c13e4ef1ca8046a3a6dbf2d5f6f5b04a11d4 F ext/session/sessionB.test 276267cd7fc37c2e2dd03f1e2ed9ada336a8bdb4 F ext/session/session_common.tcl 1539d8973b2aea0025c133eb0cc4c89fcef541a5 F ext/session/sessionfault.test e7965159a73d385c1a4af12d82c3a039ebdd71a6 -F ext/session/sqlite3session.c b7cc5645ee3de77c650cf7e05161f320ebaa997f +F ext/session/sqlite3session.c 4c7689bd8286147f7d9bf5d4b6ca5e7e7ee588ab F ext/session/sqlite3session.h 66c14a2f6193c47773770307636e88c43db6f839 F ext/session/test_session.c a252fb669d3a1b3552ee7b87fe610debc0afeb7b F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x @@ -1203,8 +1203,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 0fac6cfffe628ea02c78ebad065307309ec9eaa1 7b12f1f9c012f33d376242920583807b014b3287 -R 7a7a7eda9e9e796cac11d47296a11e68 -T +closed 7b12f1f9c012f33d376242920583807b014b3287 +P 31addb627fdbaeb908e0611ad82f6db7537428ea +R 0c1b981f1387fdad5168bd8925d76ab9 U drh -Z bd91644aa3e055b27f4fc846b7cc054f +Z 34dce636dabda531b1c7f9aae0a417c1 diff --git a/manifest.uuid b/manifest.uuid index af042500c5..c5348ad8bf 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -31addb627fdbaeb908e0611ad82f6db7537428ea \ No newline at end of file +1324d08d0c639378cf1b03bd6410db81947747ac \ No newline at end of file From 9f674f2600e7009328fbeb8d5c1614875439bb8d Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 18 Aug 2014 20:23:29 +0000 Subject: [PATCH 0117/1484] Fix the autoconf and MSVC makefiles so that they construct the changeset command-line utility upon request. Delete that utility program when "make clean" is run. FossilOrigin-Name: 4dc15fe066f079ff31c89a5e0242dd5b3c851d29 --- Makefile.in | 5 ++++- Makefile.msc | 6 +++++- main.mk | 1 + manifest | 16 ++++++++-------- manifest.uuid | 2 +- 5 files changed, 19 insertions(+), 11 deletions(-) diff --git a/Makefile.in b/Makefile.in index 7814529c21..3292da7741 100644 --- a/Makefile.in +++ b/Makefile.in @@ -964,6 +964,9 @@ showjournal$(TEXE): $(TOP)/tool/showjournal.c sqlite3.lo showwal$(TEXE): $(TOP)/tool/showwal.c sqlite3.lo $(LTLINK) -o $@ $(TOP)/tool/showwal.c sqlite3.lo $(TLIBS) +changeset$(TEXE): $(TOP)/ext/session/changeset.c sqlite3.lo + $(LTLINK) -o $@ $(TOP)/ext/session/changeset.c sqlite3.lo $(TLIBS) + rollback-test$(TEXE): $(TOP)/tool/rollback-test.c sqlite3.lo $(LTLINK) -o $@ $(TOP)/tool/rollback-test.c sqlite3.lo $(TLIBS) @@ -1012,7 +1015,7 @@ clean: rm -f testfixture$(TEXE) test.db rm -f LogEst$(TEXE) fts3view$(TEXE) rollback-test$(TEXE) showdb$(TEXE) rm -f showjournal$(TEXE) showstat4$(TEXE) showwal$(TEXE) speedtest1$(TEXE) - rm -f wordcount$(TEXE) + rm -f wordcount$(TEXE) changeset$(TEXE) rm -f sqlite3.dll sqlite3.lib sqlite3.exp sqlite3.def rm -f sqlite3.c rm -f sqlite3rc.h diff --git a/Makefile.msc b/Makefile.msc index 38ea41ffba..d246cf03c3 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -1476,6 +1476,10 @@ showwal.exe: $(TOP)\tool\showwal.c $(SQLITE3C) $(LTLINK) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \ $(TOP)\tool\showwal.c $(SQLITE3C) +changeset.exe: $(TOP)\ext\session\changeset.c $(SQLITE3C) + $(LTLINK) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \ + $(TOP)\ext\session\changeset.c $(SQLITE3C) + fts3view.exe: $(TOP)\ext\fts3\tool\fts3view.c $(SQLITE3C) $(LTLINK) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \ $(TOP)\ext\fts3\tool\fts3view.c $(SQLITE3C) @@ -1512,7 +1516,7 @@ clean: del /Q tclsqlite3.exe tclsqlite3.exp del /Q testloadext.dll testloadext.exp del /Q testfixture.exe testfixture.exp test.db - del /Q LogEst.exe fts3view.exe rollback-test.exe showdb.exe + del /Q LogEst.exe fts3view.exe rollback-test.exe showdb.exe changeset.exe del /Q showjournal.exe showstat4.exe showwal.exe speedtest1.exe del /Q wordcount.exe del /Q sqlite3.dll sqlite3.lib sqlite3.exp sqlite3.def diff --git a/main.mk b/main.mk index 13798354cb..4d376a805b 100644 --- a/main.mk +++ b/main.mk @@ -722,6 +722,7 @@ clean: rm -f showjournal showjournal.exe rm -f showstat4 showstat4.exe rm -f showwal showwal.exe + rm -f changeset changeset.exe rm -f speedtest1 speedtest1.exe rm -f wordcount wordcount.exe rm -f sqlite3.c sqlite3-*.c fts?amal.c tclsqlite3.c diff --git a/manifest b/manifest index eba81a57c4..d2986aafb7 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Fix\sa\sharmless\scompiler\swarning\sin\sthe\ssessionAppendDelete()\sfunction. -D 2014-08-18T20:14:30.667 +C Fix\sthe\sautoconf\sand\sMSVC\smakefiles\sso\sthat\sthey\sconstruct\sthe\schangeset\ncommand-line\sutility\supon\srequest.\s\sDelete\sthat\sutility\sprogram\swhen\n"make\sclean"\sis\srun. +D 2014-08-18T20:23:29.435 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f -F Makefile.in 639859a6f81bd15921ccd56ddbd6dfd335278377 +F Makefile.in d5ad373b7a23525414b8843b3084cf90c560d92f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 -F Makefile.msc d389ce1d436d21a93a9f5f6211dc45e4b8860962 +F Makefile.msc f1bbf555916b6e60887d86cea62f27e6a26cdb24 F Makefile.vxworks 034289efa9d591b04b1a73598623119c306cbba0 F README.md 64f270c43c38c46de749e419c22f0ae2f4499fe8 F VERSION 1c877615a9db323e3cd301e3d57d853f9d5c4a07 @@ -162,7 +162,7 @@ F ext/session/test_session.c a252fb669d3a1b3552ee7b87fe610debc0afeb7b F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60 -F main.mk 95de2e32fbe62b10e28bd7a131e2b003b923a8b3 +F main.mk a9987b6655610e663e9f055e0f1646227f45cddd F mkopcodec.awk c2ff431854d702cdd2d779c9c0d1f58fa16fa4ea F mkopcodeh.awk c6b3fa301db6ef7ac916b14c60868aeaec1337b5 F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83 @@ -1203,7 +1203,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 31addb627fdbaeb908e0611ad82f6db7537428ea -R 0c1b981f1387fdad5168bd8925d76ab9 +P 1324d08d0c639378cf1b03bd6410db81947747ac +R fdaf7ebc782210d979a62294e31e9051 U drh -Z 34dce636dabda531b1c7f9aae0a417c1 +Z e19e0e50f2717082ee6e33a1c9b88ce5 diff --git a/manifest.uuid b/manifest.uuid index c5348ad8bf..2e186914d2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1324d08d0c639378cf1b03bd6410db81947747ac \ No newline at end of file +4dc15fe066f079ff31c89a5e0242dd5b3c851d29 \ No newline at end of file From 2967e0cc9c1c21a8ab06a294ee9470d558e3b6a9 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 19 Aug 2014 00:26:17 +0000 Subject: [PATCH 0118/1484] Improved response to error conditions in the ".session" shell command and in the "changeset" command-line program. FossilOrigin-Name: b69f7dd1f35846c3bb9f4f160d50c4f03796f887 --- ext/session/changeset.c | 12 ++++++++---- manifest | 14 +++++++------- manifest.uuid | 2 +- src/shell.c | 8 ++++++-- 4 files changed, 22 insertions(+), 14 deletions(-) diff --git a/ext/session/changeset.c b/ext/session/changeset.c index 1ff5cde87d..edb43ff8e5 100644 --- a/ext/session/changeset.c +++ b/ext/session/changeset.c @@ -232,8 +232,10 @@ int main(int argc, char **argv){ exit(1); } readFile(argv[3], &szB, &pB); - sqlite3changeset_concat(sz, pBuf, szB, pB, &szOut, &pOutBuf); - if( fwrite(pOutBuf, szOut, 1, out)!=1 ){ + rc = sqlite3changeset_concat(sz, pBuf, szB, pB, &szOut, &pOutBuf); + if( rc!=SQLITE_OK ){ + fprintf(stderr, "sqlite3changeset_concat() returns %d\n", rc); + }else if( szOut>0 && fwrite(pOutBuf, szOut, 1, out)!=1 ){ fprintf(stderr, "unable to write all %d bytes of output to \"%s\"\n", szOut, zOut); } @@ -300,8 +302,10 @@ int main(int argc, char **argv){ fprintf(stderr, "cannot open \"%s\" for writing\n", zOut); exit(1); } - sqlite3changeset_invert(sz, pBuf, &szOut, &pOutBuf); - if( fwrite(pOutBuf, szOut, 1, out)!=1 ){ + rc = sqlite3changeset_invert(sz, pBuf, &szOut, &pOutBuf); + if( rc!=SQLITE_OK ){ + fprintf(stderr, "sqlite3changeset_invert() returns %d\n", rc); + }else if( szOut>0 && fwrite(pOutBuf, szOut, 1, out)!=1 ){ fprintf(stderr, "unable to write all %d bytes of output to \"%s\"\n", szOut, zOut); } diff --git a/manifest b/manifest index d2986aafb7..8526781f17 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\sautoconf\sand\sMSVC\smakefiles\sso\sthat\sthey\sconstruct\sthe\schangeset\ncommand-line\sutility\supon\srequest.\s\sDelete\sthat\sutility\sprogram\swhen\n"make\sclean"\sis\srun. -D 2014-08-18T20:23:29.435 +C Improved\sresponse\sto\serror\sconditions\sin\sthe\s".session"\sshell\scommand\sand\nin\sthe\s"changeset"\scommand-line\sprogram. +D 2014-08-19T00:26:17.830 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in d5ad373b7a23525414b8843b3084cf90c560d92f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -143,7 +143,7 @@ F ext/rtree/rtree_util.tcl 06aab2ed5b826545bf215fff90ecb9255a8647ea F ext/rtree/sqlite3rtree.h 83349d519fe5f518b3ea025d18dd1fe51b1684bd F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 -F ext/session/changeset.c 9be709cea346d65c6d0cc8bf03569956af125462 +F ext/session/changeset.c 4ccbaa4531944c24584bf6a61ba3a39c62b6267a F ext/session/session1.test 3733d71eb9a99b14d51fa5219d5b8a82407c3be8 F ext/session/session2.test 99ca0da7ddb617d42bafd83adccf99f18ae0384b F ext/session/session3.test a7a9ce59b8d1e49e2cc23d81421ac485be0eea01 @@ -239,7 +239,7 @@ F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c 0ea356d32a5e884add23d1b9b4e8736681dd5697 F src/rowset.c a9c9aae3234b44a6d7c6f5a3cadf90dce1e627be F src/select.c ea48e891406ccdf748f3eb02893e056d134a0fea -F src/shell.c 1761e117dd58e2383a2d30319c49d0fca00f8bf0 +F src/shell.c 220564b70a2115e2157688f8faa6bb751ffe019a F src/sqlite.h.in 021a1f5c50e83060675d994a6014fd409e611d9e F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc @@ -1203,7 +1203,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 1324d08d0c639378cf1b03bd6410db81947747ac -R fdaf7ebc782210d979a62294e31e9051 +P 4dc15fe066f079ff31c89a5e0242dd5b3c851d29 +R d85ccd3884f4a5cc5341a67dd8277838 U drh -Z e19e0e50f2717082ee6e33a1c9b88ce5 +Z edfba13e974f0e2f2be5cef97fba91ac diff --git a/manifest.uuid b/manifest.uuid index 2e186914d2..fc1bfdae69 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4dc15fe066f079ff31c89a5e0242dd5b3c851d29 \ No newline at end of file +b69f7dd1f35846c3bb9f4f160d50c4f03796f887 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index d45e59166e..ac42909582 100644 --- a/src/shell.c +++ b/src/shell.c @@ -3232,9 +3232,13 @@ static int do_meta_command(char *zLine, ShellState *p){ int szChng; void *pChng; if( azCmd[0][0]=='c' ){ - sqlite3session_changeset(pSession->p, &szChng, &pChng); + rc = sqlite3session_changeset(pSession->p, &szChng, &pChng); }else{ - sqlite3session_patchset(pSession->p, &szChng, &pChng); + rc = sqlite3session_patchset(pSession->p, &szChng, &pChng); + } + if( rc ){ + printf("Error: error code %d\n", rc); + rc = 0; } if( pChng && fwrite(pChng, szChng, 1, out)!=1 ){ From 3a432b0b475fa5ae550a1ab35279c2647344138c Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 19 Aug 2014 00:33:22 +0000 Subject: [PATCH 0119/1484] Disable the hook-7.5.2 tests when using sessions, since that are not correct in that case. FossilOrigin-Name: 6d5b9332e8d8bb572ac98b0f4e47e59ad12aac26 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/hook.test | 28 +++++++++++++++------------- 3 files changed, 22 insertions(+), 20 deletions(-) diff --git a/manifest b/manifest index 8526781f17..05bbcc7219 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improved\sresponse\sto\serror\sconditions\sin\sthe\s".session"\sshell\scommand\sand\nin\sthe\s"changeset"\scommand-line\sprogram. -D 2014-08-19T00:26:17.830 +C Disable\sthe\shook-7.5.2\stests\swhen\susing\ssessions,\ssince\sthat\sare\snot\scorrect\nin\sthat\scase. +D 2014-08-19T00:33:22.234 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in d5ad373b7a23525414b8843b3084cf90c560d92f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -618,7 +618,7 @@ F test/fuzzer1.test d4c52aaf3ef923da293a2653cfab33d02f718a36 F test/fuzzerfault.test 8792cd77fd5bce765b05d0c8e01b9edcf8af8536 F test/genesis.tcl 1e2e2e8e5cc4058549a154ff1892fe5c9de19f98 F test/hexlit.test f9ecde8145bfc2341573473256c74ae37a200497 -F test/hook.test 5429d34d6e59086175d8efbcd7e14d891375bdfb +F test/hook.test 76201cfcba801d02d13600700f26ab64313d1826 F test/icu.test 70df4faca133254c042d02ae342c0a141f2663f4 F test/in.test 047c4671328e9032ab95666a67021adbbd36e98e F test/in2.test 5d4c61d17493c832f7d2d32bef785119e87bde75 @@ -1203,7 +1203,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 4dc15fe066f079ff31c89a5e0242dd5b3c851d29 -R d85ccd3884f4a5cc5341a67dd8277838 +P b69f7dd1f35846c3bb9f4f160d50c4f03796f887 +R 8c550f2382b76c35956caff857ef2faa U drh -Z edfba13e974f0e2f2be5cef97fba91ac +Z 2eb508c95168b21e7a389265ba7bb22f diff --git a/manifest.uuid b/manifest.uuid index fc1bfdae69..795c3d44c4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b69f7dd1f35846c3bb9f4f160d50c4f03796f887 \ No newline at end of file +6d5b9332e8d8bb572ac98b0f4e47e59ad12aac26 \ No newline at end of file diff --git a/test/hook.test b/test/hook.test index 28f0a66681..e6bb9ae2d0 100644 --- a/test/hook.test +++ b/test/hook.test @@ -705,19 +705,21 @@ do_execsql_test 7.5.2.0 { ALTER TABLE t8 ADD COLUMN c DEFAULT 'xxx'; } -# At time of writing, these two are broken. They demonstrate that the -# sqlite3_preupdate_old() method does not handle the case where ALTER TABLE -# has been used to add a column with a default value other than NULL. -# -do_preupdate_test 7.5.2.1 { - DELETE FROM t8 WHERE a = 'one' -} { - DELETE main t8 1 1 one two xxx -} -do_preupdate_test 7.5.2.2 { - UPDATE t8 SET b = 'five' -} { - UPDATE main t8 2 2 three four xxx three five xxx +ifcapable !session { + # At time of writing, these two are broken. They demonstrate that the + # sqlite3_preupdate_old() method does not handle the case where ALTER TABLE + # has been used to add a column with a default value other than NULL. + # + do_preupdate_test 7.5.2.1 { + DELETE FROM t8 WHERE a = 'one' + } { + DELETE main t8 1 1 one two xxx + } + do_preupdate_test 7.5.2.2 { + UPDATE t8 SET b = 'five' + } { + UPDATE main t8 2 2 three four xxx three five xxx + } } # This block of tests verifies that IPK values are correctly reported From ef7a6304961a4f323e3ceb10227777be7293c73a Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 23 Sep 2014 20:39:55 +0000 Subject: [PATCH 0120/1484] Begin adding 'streaming' APIs to sessions module. This is a work in progress. FossilOrigin-Name: 3c7d3d950bbf5f5ed3696ebc61c77ca48bafe2b5 --- ext/session/sqlite3session.c | 436 ++++++++++++++++++++++++++--------- ext/session/sqlite3session.h | 58 +++++ ext/session/test_session.c | 68 +++++- manifest | 20 +- manifest.uuid | 2 +- test/permutations.test | 8 + 6 files changed, 467 insertions(+), 125 deletions(-) diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index 4617e6a3c2..ec0387e775 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -12,6 +12,12 @@ typedef struct SessionTable SessionTable; typedef struct SessionChange SessionChange; typedef struct SessionBuffer SessionBuffer; +typedef struct SessionInput SessionInput; + +/* +** Minimum chunk size used by streaming versions of functions. +*/ +#define SESSIONS_STR_CHUNK_SIZE 1024 /* ** Session handle structure. @@ -29,14 +35,38 @@ struct sqlite3_session { SessionTable *pTable; /* List of attached tables */ }; +/* +** Instances of this structure are used to build strings or binary records. +*/ +struct SessionBuffer { + u8 *aBuf; /* Pointer to changeset buffer */ + int nBuf; /* Size of buffer aBuf */ + int nAlloc; /* Size of allocation containing aBuf */ +}; + +/* +** An object of this type is used internally as an abstraction for the +** input data read by changeset iterators. Input data may be supplied +** either as a single large buffer (sqlite3changeset_start()) or using +** a stream function (sqlite3changeset_start_str()). +*/ +struct SessionInput { + int iNext; /* Offset in aChangeset[] of next change */ + u8 *aChangeset; /* Pointer to buffer containing changeset */ + int nChangeset; /* Number of bytes in aChangeset */ + SessionBuffer buf; /* Current read buffer */ + int (*xInput)(void*, void*, int*); /* Input stream call (or NULL) */ + void *pIn; /* First argument to xInput */ + int bEof; /* Set to true after xInput finished */ +}; + /* ** Structure for changeset iterators. */ struct sqlite3_changeset_iter { - u8 *aChangeset; /* Pointer to buffer containing changeset */ - int nChangeset; /* Number of bytes in aChangeset */ + SessionInput in; /* Input buffer or stream */ + SessionBuffer tblhdr; /* Buffer to hold apValue/zTab/abPK/ */ int bPatchset; /* True if this is a patchset */ - u8 *pNext; /* Pointer to next change within aChangeset */ int rc; /* Iterator error code */ sqlite3_stmt *pConflict; /* Points to conflicting row, if any */ char *zTab; /* Current table */ @@ -165,15 +195,6 @@ struct SessionChange { SessionChange *pNext; /* For hash-table collisions */ }; -/* -** Instances of this structure are used to build strings or binary records. -*/ -struct SessionBuffer { - u8 *aBuf; /* Pointer to changeset buffer */ - int nBuf; /* Size of buffer aBuf */ - int nAlloc; /* Size of allocation containing aBuf */ -}; - /* ** Write a varint with value iVal into the buffer at aBuf. Return the ** number of bytes written. @@ -1291,7 +1312,7 @@ static int sessionBufferGrow(SessionBuffer *p, int nByte, int *pRc){ int nNew = p->nAlloc ? p->nAlloc : 128; do { nNew = nNew*2; - }while( nNew<(p->nAlloc+nByte) ); + }while( nNew<(p->nBuf+nByte) ); aNew = (u8 *)sqlite3_realloc(p->aBuf, nNew); if( 0==aNew ){ @@ -1776,6 +1797,8 @@ static void sessionAppendTableHdr( int sessionGenerateChangeset( sqlite3_session *pSession, /* Session object */ int bPatchset, /* True for patchset, false for changeset */ + int (*xOutput)(void *pOut, const void *pData, int nData), + void *pOut, /* First argument for xOutput */ int *pnChangeset, /* OUT: Size of buffer at *ppChangeset */ void **ppChangeset /* OUT: Buffer containing changeset */ ){ @@ -1784,11 +1807,15 @@ int sessionGenerateChangeset( SessionBuffer buf = {0,0,0}; /* Buffer in which to accumlate changeset */ int rc; /* Return code */ + assert( xOutput==0 || (pnChangeset==0 && ppChangeset==0 ) ); + /* Zero the output variables in case an error occurs. If this session ** object is already in the error state (sqlite3_session.rc != SQLITE_OK), ** this call will be a no-op. */ - *pnChangeset = 0; - *ppChangeset = 0; + if( xOutput==0 ){ + *pnChangeset = 0; + *ppChangeset = 0; + } if( pSession->rc ) return pSession->rc; rc = sqlite3_exec(pSession->db, "SAVEPOINT changeset", 0, 0, 0); @@ -1846,6 +1873,19 @@ int sessionGenerateChangeset( if( rc==SQLITE_OK ){ rc = sqlite3_reset(pSel); } + + /* If the buffer is now larger than SESSIONS_STR_CHUNK_SIZE, pass + ** its contents to the xOutput() callback. */ + if( xOutput + && rc==SQLITE_OK + && buf.nBuf>nNoop + && buf.nBuf>SESSIONS_STR_CHUNK_SIZE + ){ + rc = xOutput(pOut, (void*)buf.aBuf, buf.nBuf); + nNoop = -1; + buf.nBuf = 0; + } + } } @@ -1858,12 +1898,16 @@ int sessionGenerateChangeset( } if( rc==SQLITE_OK ){ - *pnChangeset = buf.nBuf; - *ppChangeset = buf.aBuf; - }else{ - sqlite3_free(buf.aBuf); + if( xOutput==0 ){ + *pnChangeset = buf.nBuf; + *ppChangeset = buf.aBuf; + buf.aBuf = 0; + }else if( buf.nBuf>0 ){ + rc = xOutput(pOut, (void*)buf.aBuf, buf.nBuf); + } } + sqlite3_free(buf.aBuf); sqlite3_exec(db, "RELEASE changeset", 0, 0, 0); sqlite3_mutex_leave(sqlite3_db_mutex(db)); return rc; @@ -1881,7 +1925,29 @@ int sqlite3session_changeset( int *pnChangeset, /* OUT: Size of buffer at *ppChangeset */ void **ppChangeset /* OUT: Buffer containing changeset */ ){ - return sessionGenerateChangeset(pSession, 0, pnChangeset, ppChangeset); + return sessionGenerateChangeset(pSession, 0, 0, 0, pnChangeset, ppChangeset); +} + +/* +** Streaming version of sqlite3session_changeset(). +*/ +int sqlite3session_changeset_str( + sqlite3_session *pSession, + int (*xOutput)(void *pOut, const void *pData, int nData), + void *pOut +){ + return sessionGenerateChangeset(pSession, 0, xOutput, pOut, 0, 0); +} + +/* +** Streaming version of sqlite3session_patchset(). +*/ +int sqlite3session_patchset_str( + sqlite3_session *pSession, + int (*xOutput)(void *pOut, const void *pData, int nData), + void *pOut +){ + return sessionGenerateChangeset(pSession, 1, xOutput, pOut, 0, 0); } /* @@ -1896,7 +1962,7 @@ int sqlite3session_patchset( int *pnPatchset, /* OUT: Size of buffer at *ppChangeset */ void **ppPatchset /* OUT: Buffer containing changeset */ ){ - return sessionGenerateChangeset(pSession, 1, pnPatchset, ppPatchset); + return sessionGenerateChangeset(pSession, 1, 0, 0, pnPatchset, ppPatchset); } /* @@ -1945,16 +2011,20 @@ int sqlite3session_isempty(sqlite3_session *pSession){ } /* -** Create an iterator used to iterate through the contents of a changeset. +** Do the work for either sqlite3changeset_start() or start_str(). */ -int sqlite3changeset_start( +int sessionChangesetStart( sqlite3_changeset_iter **pp, /* OUT: Changeset iterator handle */ + int (*xInput)(void *pIn, void *pData, int *pnData), + void *pIn, int nChangeset, /* Size of buffer pChangeset in bytes */ void *pChangeset /* Pointer to buffer containing changeset */ ){ sqlite3_changeset_iter *pRet; /* Iterator to return */ int nByte; /* Number of bytes to allocate for iterator */ + assert( xInput==0 || (pChangeset==0 && nChangeset==0) ); + /* Zero the output variable in case an error occurs. */ *pp = 0; @@ -1963,15 +2033,80 @@ int sqlite3changeset_start( pRet = (sqlite3_changeset_iter *)sqlite3_malloc(nByte); if( !pRet ) return SQLITE_NOMEM; memset(pRet, 0, sizeof(sqlite3_changeset_iter)); - pRet->aChangeset = (u8 *)pChangeset; - pRet->nChangeset = nChangeset; - pRet->pNext = pRet->aChangeset; + pRet->in.aChangeset = (u8 *)pChangeset; + pRet->in.nChangeset = nChangeset; + pRet->in.xInput = xInput; + pRet->in.pIn = pIn; + pRet->in.iNext = 0; + pRet->in.bEof = (xInput ? 0 : 1); /* Populate the output variable and return success. */ *pp = pRet; return SQLITE_OK; } +/* +** Create an iterator used to iterate through the contents of a changeset. +*/ +int sqlite3changeset_start( + sqlite3_changeset_iter **pp, /* OUT: Changeset iterator handle */ + int nChangeset, /* Size of buffer pChangeset in bytes */ + void *pChangeset /* Pointer to buffer containing changeset */ +){ + return sessionChangesetStart(pp, 0, 0, nChangeset, pChangeset); +} + +/* +** Streaming version of sqlite3changeset_start(). +*/ +int sqlite3changeset_start_str( + sqlite3_changeset_iter **pp, /* OUT: Changeset iterator handle */ + int (*xInput)(void *pIn, void *pData, int *pnData), + void *pIn +){ + return sessionChangesetStart(pp, xInput, pIn, 0, 0); +} + +/* +** Ensure that there are at least nByte bytes available in the buffer. Or, +** if there are not nByte bytes remaining in the input, that all available +** data is in the buffer. +** +** Return an SQLite error code if an error occurs, or SQLITE_OK otherwise. +*/ +static int sessionInputBuffer(SessionInput *pInput, int nByte){ + int rc = SQLITE_OK; + if( pInput->xInput && !pInput->bEof ){ + assert( 0 ); + } + return rc; +} + +/* +** When this function is called, *ppRec points to the start of a record +** that contains nCol values. This function advances the pointer *ppRec +** until it points to the byte immediately following that record. +*/ +static void sessionSkipRecord( + u8 **ppRec, /* IN/OUT: Record pointer */ + int nCol /* Number of values in record */ +){ + u8 *aRec = *ppRec; + int i; + for(i=0; iaChangeset[pIn->iNext++]; + } + assert( !apOut || apOut[i]==0 ); if( eType ){ if( apOut ){ apOut[i] = sqlite3ValueNew(0); - if( !apOut[i] ) return SQLITE_NOMEM; + if( !apOut[i] ) rc = SQLITE_NOMEM; } + } + if( rc==SQLITE_OK ){ + u8 *aVal = &pIn->aChangeset[pIn->iNext]; if( eType==SQLITE_TEXT || eType==SQLITE_BLOB ){ int nByte; - aRec += sessionVarintGet(aRec, &nByte); - if( apOut ){ + pIn->iNext += sessionVarintGet(aVal, &nByte); + rc = sessionInputBuffer(pIn, nByte); + if( apOut && rc==SQLITE_OK ){ + u8 *aRec = &pIn->aChangeset[pIn->iNext]; u8 enc = (eType==SQLITE_TEXT ? SQLITE_UTF8 : 0); sqlite3ValueSetStr(apOut[i], nByte, (char *)aRec, enc, SQLITE_STATIC); } - aRec += nByte; + pIn->iNext += nByte; } if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){ if( apOut ){ - sqlite3_int64 v = sessionGetI64(aRec); + sqlite3_int64 v = sessionGetI64(aVal); if( eType==SQLITE_INTEGER ){ sqlite3VdbeMemSetInt64(apOut[i], v); }else{ @@ -2036,13 +2180,83 @@ static int sessionReadRecord( sqlite3VdbeMemSetDouble(apOut[i], d); } } - aRec += 8; + pIn->iNext += 8; } } } - *paChange = aRec; - return SQLITE_OK; + return rc; +} + +/* +** The input pointer currently points to the second byte of a table-header. +** Specifically, to the following: +** +** + number of columns in table (varint) +** + array of PK flags (1 byte per column), +** + table name (nul terminated). +** +** This function ensures that all of the above is present in the input +** buffer (i.e. that it can be accessed without any calls to xInput()). +** If successful, SQLITE_OK is returned. Otherwise, an SQLite error code. +** The input pointer is not moved. +*/ +static int sessionChangesetBufferTblhdr(SessionInput *pIn, int *pnByte){ + int rc = SQLITE_OK; + int nCol = 0; + int iIn = pIn->iNext; + + rc = sessionInputBuffer(pIn, 9); + if( rc==SQLITE_OK ){ + iIn += sessionVarintGet(&pIn->aChangeset[iIn], &nCol); + rc = sessionInputBuffer(pIn, nCol+100); + iIn += nCol; + } + while( rc==SQLITE_OK ){ + while( iInnChangeset && pIn->aChangeset[iIn] ) iIn++; + if( pIn->aChangeset[iIn]==0 ) break; + rc = sessionInputBuffer(pIn, 100); + } + if( pnByte ) *pnByte = (iIn+1 - pIn->iNext); + return rc; +} + +/* +** The input pointer currently points to the second byte of a table-header. +** Specifically, to the following: +** +** + number of columns in table (varint) +** + array of PK flags (1 byte per column), +** + table name (nul terminated). +*/ +static int sessionChangesetReadTblhdr(sqlite3_changeset_iter *p){ + int rc; + int nCopy; + assert( p->rc==SQLITE_OK ); + + rc = sessionChangesetBufferTblhdr(&p->in, &nCopy); + if( rc==SQLITE_OK ){ + int nByte; + int nVarint; + nVarint = sessionVarintGet(&p->in.aChangeset[p->in.iNext], &p->nCol); + nCopy -= nVarint; + p->in.iNext += nVarint; + nByte = p->nCol * sizeof(sqlite3_value*) * 2 + nCopy; + p->tblhdr.nBuf = 0; + sessionBufferGrow(&p->tblhdr, nByte, &rc); + } + + if( rc==SQLITE_OK ){ + int iPK = sizeof(sqlite3_value*)*p->nCol*2; + memset(p->tblhdr.aBuf, 0, iPK); + memcpy(&p->tblhdr.aBuf[iPK], &p->in.aChangeset[p->in.iNext], nCopy); + p->in.iNext += nCopy; + } + + p->apValue = (sqlite3_value**)p->tblhdr.aBuf; + p->abPK = (u8*)&p->apValue[p->nCol*2]; + p->zTab = (char*)&p->abPK[p->nCol]; + return (p->rc = rc); } /* @@ -2066,9 +2280,10 @@ static int sessionChangesetNext( u8 **paRec, /* If non-NULL, store record pointer here */ int *pnRec /* If non-NULL, store size of record here */ ){ - u8 *aChange; int i; + u8 op; + assert( paRec==0 || p->in.xInput==0 ); /* fixme! */ assert( (paRec==0 && pnRec==0) || (paRec && pnRec) ); /* If the iterator is in the error-state, return immediately. */ @@ -2082,57 +2297,50 @@ static int sessionChangesetNext( memset(p->apValue, 0, sizeof(sqlite3_value*)*p->nCol*2); } + /* Make sure the buffer contains at least 10 bytes of input data, or all + ** remaining data if there are less than 10 bytes available. This is + ** sufficient either for the 'T' or 'P' byte and the varint that follows + ** it, or for the two single byte values otherwise. */ + p->rc = sessionInputBuffer(&p->in, 2); + if( p->rc!=SQLITE_OK ) return p->rc; + /* If the iterator is already at the end of the changeset, return DONE. */ - if( p->pNext>=&p->aChangeset[p->nChangeset] ){ + if( p->in.iNext>=p->in.nChangeset ){ return SQLITE_DONE; } - aChange = p->pNext; - if( aChange[0]=='T' || aChange[0]=='P' ){ - int nByte; /* Bytes to allocate for apValue */ - p->bPatchset = (aChange[0]=='P'); - aChange++; - aChange += sessionVarintGet(aChange, &p->nCol); - p->abPK = (u8 *)aChange; - aChange += p->nCol; - p->zTab = (char *)aChange; - aChange += (sqlite3Strlen30((char *)aChange) + 1); - - if( paRec==0 ){ - sqlite3_free(p->apValue); - nByte = sizeof(sqlite3_value *) * p->nCol * 2; - p->apValue = (sqlite3_value **)sqlite3_malloc(nByte); - if( !p->apValue ){ - return (p->rc = SQLITE_NOMEM); - } - memset(p->apValue, 0, sizeof(sqlite3_value*)*p->nCol*2); - } + op = p->in.aChangeset[p->in.iNext++]; + if( op=='T' || op=='P' ){ + p->bPatchset = (op=='P'); + if( sessionChangesetReadTblhdr(p) ) return p->rc; + if( (p->rc = sessionInputBuffer(&p->in, 2)) ) return p->rc; + op = p->in.aChangeset[p->in.iNext++]; } - p->op = *(aChange++); - p->bIndirect = *(aChange++); + p->op = op; + p->bIndirect = p->in.aChangeset[p->in.iNext++]; if( p->op!=SQLITE_UPDATE && p->op!=SQLITE_DELETE && p->op!=SQLITE_INSERT ){ return (p->rc = SQLITE_CORRUPT); } - if( paRec ){ *paRec = aChange; } + if( paRec ){ *paRec = &p->in.aChangeset[p->in.iNext]; } /* If this is an UPDATE or DELETE, read the old.* record. */ if( p->op!=SQLITE_INSERT && (p->bPatchset==0 || p->op==SQLITE_DELETE) ){ u8 *abPK = p->bPatchset ? p->abPK : 0; - p->rc = sessionReadRecord(&aChange, p->nCol, abPK, paRec?0:p->apValue); + p->rc = sessionReadRecord(&p->in, p->nCol, abPK, paRec?0:p->apValue); if( p->rc!=SQLITE_OK ) return p->rc; } /* If this is an INSERT or UPDATE, read the new.* record. */ if( p->op!=SQLITE_DELETE ){ sqlite3_value **apOut = (paRec ? 0 : &p->apValue[p->nCol]); - p->rc = sessionReadRecord(&aChange, p->nCol, 0, apOut); + p->rc = sessionReadRecord(&p->in, p->nCol, 0, apOut); if( p->rc!=SQLITE_OK ) return p->rc; } - if( pnRec ){ - *pnRec = (int)(aChange - *paRec); + if( pnRec ){ + *pnRec = (int)(&p->in.aChangeset[p->in.iNext] - *paRec); }else if( p->bPatchset && p->op==SQLITE_UPDATE ){ /* If this is an UPDATE that is part of a patchset, then all PK and ** modified fields are present in the new.* record. The old.* record @@ -2148,7 +2356,7 @@ static int sessionChangesetNext( } } } - p->pNext = aChange; + return SQLITE_ROW; } @@ -2321,7 +2529,7 @@ int sqlite3changeset_finalize(sqlite3_changeset_iter *p){ if( p->apValue ){ for(i=0; inCol*2; i++) sqlite3ValueFree(p->apValue[i]); } - sqlite3_free(p->apValue); + sqlite3_free(p->tblhdr.aBuf); sqlite3_free(p); return rc; } @@ -2339,52 +2547,71 @@ int sqlite3changeset_invert( u8 *aOut; u8 *aIn; int i; + SessionInput sInput; int nCol = 0; /* Number of cols in current table */ u8 *abPK = 0; /* PK array for current table */ sqlite3_value **apVal = 0; /* Space for values for UPDATE inversion */ + SessionBuffer sPK = {0, 0, 0}; /* PK array for current table */ /* Zero the output variables in case an error occurs. */ *ppInverted = 0; *pnInverted = 0; if( nChangeset==0 ) return SQLITE_OK; + /* Set up the input stream */ + memset(&sInput, 0, sizeof(SessionInput)); + sInput.nChangeset = nChangeset; + sInput.aChangeset = (u8*)pChangeset; + aOut = (u8 *)sqlite3_malloc(nChangeset); if( !aOut ) return SQLITE_NOMEM; aIn = (u8 *)pChangeset; i = 0; while( iop = SQLITE_INSERT; - if( bPatchset==0 ) sessionReadRecord(&a1, pTab->nCol, 0, 0); + if( bPatchset==0 ) sessionSkipRecord(&a1, pTab->nCol); sessionMergeRecord(&aCsr, pTab->nCol, aExist, a1); }else if( op1==SQLITE_DELETE ){ /* DELETE + INSERT */ assert( op2==SQLITE_INSERT ); @@ -3290,8 +3518,8 @@ static int sessionChangeMerge( u8 *a2 = aRec; assert( op1==SQLITE_UPDATE ); if( bPatchset==0 ){ - sessionReadRecord(&a1, pTab->nCol, 0, 0); - sessionReadRecord(&a2, pTab->nCol, 0, 0); + sessionSkipRecord(&a1, pTab->nCol); + sessionSkipRecord(&a2, pTab->nCol); } pNew->op = SQLITE_UPDATE; if( 0==sessionMergeUpdate(&aCsr, pTab, bPatchset, aRec, aExist,a1,a2) ){ @@ -3356,14 +3584,8 @@ static int sessionConcatChangeset( break; } - assert( pIter->apValue==0 ); sqlite3changeset_op(pIter, &zNew, &nCol, &op, &bIndirect); - - assert( zNew>=(char *)pChangeset && zNew-nChangeset<((char *)pChangeset) ); - assert( !pTab || pTab->zName-nChangeset<(char *)pChangeset ); - assert( !pTab || zNew>=pTab->zName ); - - if( !pTab || zNew!=pTab->zName ){ + if( !pTab || sqlite3_stricmp(zNew, pTab->zName) ){ /* Search the list for a matching table */ int nNew = (int)strlen(zNew); u8 *abPK; @@ -3373,21 +3595,23 @@ static int sessionConcatChangeset( if( 0==sqlite3_strnicmp(pTab->zName, zNew, nNew+1) ) break; } if( !pTab ){ - pTab = sqlite3_malloc(sizeof(SessionTable)); + pTab = sqlite3_malloc(sizeof(SessionTable) + nCol + nNew+1); if( !pTab ){ rc = SQLITE_NOMEM; break; } memset(pTab, 0, sizeof(SessionTable)); pTab->pNext = *ppTabList; - pTab->abPK = abPK; pTab->nCol = nCol; + pTab->abPK = (u8*)&pTab[1]; + memcpy(pTab->abPK, abPK, nCol); + pTab->zName = (char*)&pTab->abPK[nCol]; + memcpy(pTab->zName, zNew, nNew+1); *ppTabList = pTab; }else if( pTab->nCol!=nCol || memcmp(pTab->abPK, abPK, nCol) ){ rc = SQLITE_SCHEMA; break; } - pTab->zName = (char *)zNew; } if( sessionGrowHash(bPatchset, pTab) ){ diff --git a/ext/session/sqlite3session.h b/ext/session/sqlite3session.h index ced984ecbe..4737bd953f 100644 --- a/ext/session/sqlite3session.h +++ b/ext/session/sqlite3session.h @@ -273,6 +273,31 @@ int sqlite3session_changeset( void **ppChangeset /* OUT: Buffer containing changeset */ ); + +/* +** This function is similar to sqlite3session_changeset(), except that instead +** of storing the output changeset in a buffer obtained from sqlite3_malloc() +** it invokes the supplied xOutput() callback zero or more times to stream the +** changeset to the application. This is useful in order to avoid large memory +** allocations when working with very large changesets. +** +** The first parameter passed to each call to the xOutput callback is a copy +** of the pOut parameter passed to this function. The following two parameters +** are a pointer to the buffer containing the next chunk of the output changeset +** and the size of that buffer in bytes. +** +** If the data is successfully processed by the xOutput callback, it should +** return SQLITE_OK. Or, if an error occurs, some other SQLite error code. In +** this case the sqlite3session_changeset_str() call is abandoned immediately +** and returns a copy of the xOutput return code. +*/ +int sqlite3session_changeset_str( + sqlite3_session *pSession, + int (*xOutput)(void *pOut, const void *pData, int nData), + void *pOut +); + + /* ** CAPI3REF: Generate A Patchset From A Session Object ** @@ -302,6 +327,15 @@ int sqlite3session_patchset( void **ppPatchset /* OUT: Buffer containing changeset */ ); +/* +** Streaming version of sqlite3session_patchset(). +*/ +int sqlite3session_patchset_str( + sqlite3_session *pSession, + int (*xOutput)(void *pOut, const void *pData, int nData), + void *pOut +); + /* ** CAPI3REF: Test if a changeset has recorded any changes. ** @@ -358,6 +392,30 @@ int sqlite3changeset_start( void *pChangeset /* Pointer to blob containing changeset */ ); + +/* +** This function is similar to sqlite3changeset_start(), except that instead +** of reading data from a single buffer, it requests it one chunk at a time +** from the application by invoking the supplied xInput() callback. The xInput() +** callback may be invoked at any time during the lifetime of the iterator. +** +** Each time the xInput callback is invoked, the first argument passed is a +** copy of the third parameter passed to this function. The second argument, +** pData, points to a buffer (*pnData) bytes in size. Assuming no error occurs +** the xInput method should copy up to (*pnData) bytes of data into the buffer +** and set (*pnData) to the actual number of bytes copied before returning +** SQLITE_OK. If the input is completely exhausted, (*pnData) should be set +** to zero to indicate this. Or, if an error occurs, an SQLite error code +** should be returned. In this case the iterator is put into an error state and +** all subsequent calls to iterator methods return a copy of the xInput error +** code. +*/ +int sqlite3changeset_start_str( + sqlite3_changeset_iter **pp, + int (*xInput)(void *pIn, void *pData, int *pnData), + void *pIn +); + /* ** CAPI3REF: Advance A Changeset Iterator ** diff --git a/ext/session/test_session.c b/ext/session/test_session.c index 38e4be1481..bf4bde39a4 100644 --- a/ext/session/test_session.c +++ b/ext/session/test_session.c @@ -14,6 +14,23 @@ struct TestSession { Tcl_Obj *pFilterScript; }; +#define SESSION_STREAM_TCL_VAR "sqlite3session_streams" + +/* +** Attempt to find the global variable zVar within interpreter interp +** and extract a boolean value from it. Return this value. +** +** If the named variable cannot be found, or if it cannot be interpreted +** as a boolean, return 0. +*/ +static int test_tcl_boolean(Tcl_Interp *interp, const char *zVar){ + Tcl_Obj *pObj; + int bVal = 0; + pObj = Tcl_ObjGetVar2(interp, Tcl_NewStringObj(zVar, -1), 0, TCL_GLOBAL_ONLY); + if( pObj ) Tcl_GetBooleanFromObj(0, pObj, &bVal); + return bVal; +} + static int test_session_error(Tcl_Interp *interp, int rc){ extern const char *sqlite3ErrName(int); Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1)); @@ -44,12 +61,38 @@ static int test_table_filter(void *pCtx, const char *zTbl){ return bRes; } +struct TestSessionsBlob { + void *p; + int n; +}; +typedef struct TestSessionsBlob TestSessionsBlob; + +static int testSessionsOutput( + void *pCtx, + const void *pData, + int nData +){ + TestSessionsBlob *pBlob = (TestSessionsBlob*)pCtx; + char *pNew; + + assert( nData>0 ); + pNew = (char*)sqlite3_realloc(pBlob->p, pBlob->n + nData); + if( pNew==0 ){ + return SQLITE_NOMEM; + } + pBlob->p = (void*)pNew; + memcpy(&pNew[pBlob->n], pData, nData); + pBlob->n += nData; + return SQLITE_OK; +} + /* ** Tclcmd: $session attach TABLE ** $session changeset ** $session delete ** $session enable BOOL ** $session indirect INTEGER +** $session patchset ** $session table_filter SCRIPT */ static int test_session_cmd( @@ -105,17 +148,26 @@ static int test_session_cmd( case 7: /* patchset */ case 1: { /* changeset */ - int nChange; - void *pChange; - if( iSub==7 ){ - rc = sqlite3session_patchset(pSession, &nChange, &pChange); + TestSessionsBlob o = {0, 0}; + if( test_tcl_boolean(interp, SESSION_STREAM_TCL_VAR) ){ + void *pCtx = (void*)&o; + if( iSub==7 ){ + rc = sqlite3session_patchset_str(pSession, testSessionsOutput, pCtx); + }else{ + rc = sqlite3session_changeset_str(pSession, testSessionsOutput, pCtx); + } }else{ - rc = sqlite3session_changeset(pSession, &nChange, &pChange); + if( iSub==7 ){ + rc = sqlite3session_patchset(pSession, &o.n, &o.p); + }else{ + rc = sqlite3session_changeset(pSession, &o.n, &o.p); + } } if( rc==SQLITE_OK ){ - Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(pChange, nChange)); - sqlite3_free(pChange); - }else{ + Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(o.p, o.n)); + } + sqlite3_free(o.p); + if( rc!=SQLITE_OK ){ return test_session_error(interp, rc); } break; diff --git a/manifest b/manifest index ffe55892fc..753640048a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sall\srecent\strunk\schanges\sinto\sthe\ssessions\sbranch. -D 2014-09-21T22:49:20.257 +C Begin\sadding\s'streaming'\sAPIs\sto\ssessions\smodule.\sThis\sis\sa\swork\sin\sprogress. +D 2014-09-23T20:39:55.903 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in dd5f245aa8c741bc65845747203c8ce2f3fb6c83 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -158,9 +158,9 @@ F ext/session/sessionA.test eb05c13e4ef1ca8046a3a6dbf2d5f6f5b04a11d4 F ext/session/sessionB.test 276267cd7fc37c2e2dd03f1e2ed9ada336a8bdb4 F ext/session/session_common.tcl 1539d8973b2aea0025c133eb0cc4c89fcef541a5 F ext/session/sessionfault.test e7965159a73d385c1a4af12d82c3a039ebdd71a6 -F ext/session/sqlite3session.c 4c7689bd8286147f7d9bf5d4b6ca5e7e7ee588ab -F ext/session/sqlite3session.h 66c14a2f6193c47773770307636e88c43db6f839 -F ext/session/test_session.c a252fb669d3a1b3552ee7b87fe610debc0afeb7b +F ext/session/sqlite3session.c ead909b1b0976aa6d08dcb7b487a902e358f7e4c +F ext/session/sqlite3session.h d074a929d368b438d32c15af8f8fe2afa80afe3f +F ext/session/test_session.c e39119c8554fe1b0925a038423ca137ddf6f6bd9 F ext/userauth/sqlite3userauth.h 19cb6f0e31316d0ee4afdfb7a85ef9da3333a220 F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04 F ext/userauth/userauth.c 5fa3bdb492f481bbc1709fc83c91ebd13460c69e @@ -776,7 +776,7 @@ F test/pagesize.test 1dd51367e752e742f58e861e65ed7390603827a0 F test/pcache.test b09104b03160aca0d968d99e8cd2c5b1921a993d F test/pcache2.test a83efe2dec0d392f814bfc998def1d1833942025 F test/percentile.test b98fc868d71eb5619d42a1702e9ab91718cbed54 -F test/permutations.test 89f594fdba922586d46c3e0a7ab4990b5a7f8da7 +F test/permutations.test b8ca6c9ecec6f360485a8cb61ef1b8734b31797b F test/pragma.test 19d0241a007bcdd77fc2606ec60fc60357e7fc8b F test/pragma2.test aea7b3d82c76034a2df2b38a13745172ddc0bc13 F test/printf.test ec9870c4dce8686a37818e0bf1aba6e6a1863552 @@ -1216,7 +1216,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P c2885c6bb24cc55178467e57e77bf71df58b3b13 d5880abd63c83c88e135257373afa0a3fd88297e -R 9d7f30c83131a55806d3c1dd053387df -U drh -Z c53e54ee2e290caf615c330d235d140a +P 6406b77f2c447751a2fbb16f01c61cdcfd6af59e +R 67d8884fcab24bc7ffc4823662b37f4a +U dan +Z 2bbe541c87040990ceab83529c1e7e80 diff --git a/manifest.uuid b/manifest.uuid index a34006bb05..424c64b57a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6406b77f2c447751a2fbb16f01c61cdcfd6af59e \ No newline at end of file +3c7d3d950bbf5f5ed3696ebc61c77ca48bafe2b5 \ No newline at end of file diff --git a/test/permutations.test b/test/permutations.test index 7bea39eb7a..44f571793c 100644 --- a/test/permutations.test +++ b/test/permutations.test @@ -938,6 +938,14 @@ test_suite "session_eec" -description { sqlite3_extended_result_codes $::dbhandle 1 } +test_suite "session_str" -description { + All session module related tests using the streaming APIs. +} -files [ + glob -nocomplain $::testdir/../ext/session/*.test +] -dbconfig { + set ::sqlite3session_streams 1 +} + test_suite "no_optimization" -description { Run test scripts with optimizations disabled using the sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS) interface. From 4757c65866180484e56b35d8d8c21748fef149b6 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 24 Sep 2014 17:13:20 +0000 Subject: [PATCH 0121/1484] Add streaming version of sqlite3changeset_apply(). Tests and fixes for the same and sqlite3changeset_start_str(). FossilOrigin-Name: b917fc146876f764442de08d5ec36e5b4cf5ab52 --- ext/session/sqlite3session.c | 197 ++++++++++++++++++++++++++--------- ext/session/sqlite3session.h | 24 +++++ ext/session/test_session.c | 89 +++++++++++++--- manifest | 18 ++-- manifest.uuid | 2 +- test/session.test | 1 + 6 files changed, 256 insertions(+), 75 deletions(-) diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index ec0387e775..ceea8268c6 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -17,7 +17,11 @@ typedef struct SessionInput SessionInput; /* ** Minimum chunk size used by streaming versions of functions. */ +#ifdef SQLITE_TEST +#define SESSIONS_STR_CHUNK_SIZE 1 +#else #define SESSIONS_STR_CHUNK_SIZE 1024 +#endif /* ** Session handle structure. @@ -51,9 +55,10 @@ struct SessionBuffer { ** a stream function (sqlite3changeset_start_str()). */ struct SessionInput { - int iNext; /* Offset in aChangeset[] of next change */ - u8 *aChangeset; /* Pointer to buffer containing changeset */ - int nChangeset; /* Number of bytes in aChangeset */ + int iNext; /* Offset in aData[] of next change */ + u8 *aData; /* Pointer to buffer containing changeset */ + int nData; /* Number of bytes in aData */ + SessionBuffer buf; /* Current read buffer */ int (*xInput)(void*, void*, int*); /* Input stream call (or NULL) */ void *pIn; /* First argument to xInput */ @@ -2033,8 +2038,8 @@ int sessionChangesetStart( pRet = (sqlite3_changeset_iter *)sqlite3_malloc(nByte); if( !pRet ) return SQLITE_NOMEM; memset(pRet, 0, sizeof(sqlite3_changeset_iter)); - pRet->in.aChangeset = (u8 *)pChangeset; - pRet->in.nChangeset = nChangeset; + pRet->in.aData = (u8 *)pChangeset; + pRet->in.nData = nChangeset; pRet->in.xInput = xInput; pRet->in.pIn = pIn; pRet->in.iNext = 0; @@ -2074,10 +2079,31 @@ int sqlite3changeset_start_str( ** ** Return an SQLite error code if an error occurs, or SQLITE_OK otherwise. */ -static int sessionInputBuffer(SessionInput *pInput, int nByte){ +static int sessionInputBuffer(SessionInput *pIn, int nByte){ int rc = SQLITE_OK; - if( pInput->xInput && !pInput->bEof ){ - assert( 0 ); + if( pIn->xInput ){ + while( !pIn->bEof && (pIn->iNext+nByte)>=pIn->nData && rc==SQLITE_OK ){ + int nNew = SESSIONS_STR_CHUNK_SIZE; + + if( pIn->iNext>=SESSIONS_STR_CHUNK_SIZE ){ + int nMove = pIn->buf.nBuf - pIn->iNext; + memmove(pIn->buf.aBuf, &pIn->buf.aBuf[pIn->iNext], nMove); + pIn->buf.nBuf -= pIn->iNext; + pIn->iNext = 0; + } + + if( SQLITE_OK==sessionBufferGrow(&pIn->buf, nNew, &rc) ){ + rc = pIn->xInput(pIn->pIn, &pIn->buf.aBuf[pIn->buf.nBuf], &nNew); + if( nNew==0 ){ + pIn->bEof = 1; + }else{ + pIn->buf.nBuf += nNew; + } + } + + pIn->aData = pIn->buf.aBuf; + pIn->nData = pIn->buf.nBuf; + } } return rc; } @@ -2107,6 +2133,25 @@ static void sessionSkipRecord( *ppRec = aRec; } +/* +** This function sets the value of the sqlite3_value object passed as the +** first argument to a copy of the string or blob held in the aData[] +** buffer. SQLITE_OK is returned if successful, or SQLITE_NOMEM if an OOM +** error occurs. +*/ +static int sessionValueSetStr( + sqlite3_value *pVal, /* Set the value of this object */ + u8 *aData, /* Buffer containing string or blob data */ + int nData, /* Size of buffer aData[] in bytes */ + u8 enc /* String encoding (0 for blobs) */ +){ + u8 *aCopy = sqlite3_malloc(nData); + if( aCopy==0 ) return SQLITE_NOMEM; + memcpy(aCopy, aData, nData); + sqlite3ValueSetStr(pVal, nData, (char*)aCopy, enc, sqlite3_free); + return SQLITE_OK; +} + /* ** Deserialize a single record from a buffer in memory. See "RECORD FORMAT" ** for details. @@ -2145,7 +2190,7 @@ static int sessionReadRecord( if( abPK && abPK[i]==0 ) continue; rc = sessionInputBuffer(pIn, 9); if( rc==SQLITE_OK ){ - eType = pIn->aChangeset[pIn->iNext++]; + eType = pIn->aData[pIn->iNext++]; } assert( !apOut || apOut[i]==0 ); @@ -2157,15 +2202,14 @@ static int sessionReadRecord( } if( rc==SQLITE_OK ){ - u8 *aVal = &pIn->aChangeset[pIn->iNext]; + u8 *aVal = &pIn->aData[pIn->iNext]; if( eType==SQLITE_TEXT || eType==SQLITE_BLOB ){ int nByte; pIn->iNext += sessionVarintGet(aVal, &nByte); rc = sessionInputBuffer(pIn, nByte); if( apOut && rc==SQLITE_OK ){ - u8 *aRec = &pIn->aChangeset[pIn->iNext]; u8 enc = (eType==SQLITE_TEXT ? SQLITE_UTF8 : 0); - sqlite3ValueSetStr(apOut[i], nByte, (char *)aRec, enc, SQLITE_STATIC); + rc = sessionValueSetStr(apOut[i],&pIn->aData[pIn->iNext],nByte,enc); } pIn->iNext += nByte; } @@ -2204,20 +2248,23 @@ static int sessionReadRecord( static int sessionChangesetBufferTblhdr(SessionInput *pIn, int *pnByte){ int rc = SQLITE_OK; int nCol = 0; - int iIn = pIn->iNext; + int nRead = 0; rc = sessionInputBuffer(pIn, 9); if( rc==SQLITE_OK ){ - iIn += sessionVarintGet(&pIn->aChangeset[iIn], &nCol); - rc = sessionInputBuffer(pIn, nCol+100); - iIn += nCol; + nRead += sessionVarintGet(&pIn->aData[pIn->iNext + nRead], &nCol); + rc = sessionInputBuffer(pIn, nRead+nCol+100); + nRead += nCol; } + while( rc==SQLITE_OK ){ - while( iInnChangeset && pIn->aChangeset[iIn] ) iIn++; - if( pIn->aChangeset[iIn]==0 ) break; - rc = sessionInputBuffer(pIn, 100); + while( (pIn->iNext + nRead)nData && pIn->aData[pIn->iNext + nRead] ){ + nRead++; + } + if( pIn->aData[pIn->iNext + nRead]==0 ) break; + rc = sessionInputBuffer(pIn, nRead + 100); } - if( pnByte ) *pnByte = (iIn+1 - pIn->iNext); + if( pnByte ) *pnByte = nRead+1; return rc; } @@ -2238,7 +2285,7 @@ static int sessionChangesetReadTblhdr(sqlite3_changeset_iter *p){ if( rc==SQLITE_OK ){ int nByte; int nVarint; - nVarint = sessionVarintGet(&p->in.aChangeset[p->in.iNext], &p->nCol); + nVarint = sessionVarintGet(&p->in.aData[p->in.iNext], &p->nCol); nCopy -= nVarint; p->in.iNext += nVarint; nByte = p->nCol * sizeof(sqlite3_value*) * 2 + nCopy; @@ -2249,7 +2296,7 @@ static int sessionChangesetReadTblhdr(sqlite3_changeset_iter *p){ if( rc==SQLITE_OK ){ int iPK = sizeof(sqlite3_value*)*p->nCol*2; memset(p->tblhdr.aBuf, 0, iPK); - memcpy(&p->tblhdr.aBuf[iPK], &p->in.aChangeset[p->in.iNext], nCopy); + memcpy(&p->tblhdr.aBuf[iPK], &p->in.aData[p->in.iNext], nCopy); p->in.iNext += nCopy; } @@ -2305,25 +2352,25 @@ static int sessionChangesetNext( if( p->rc!=SQLITE_OK ) return p->rc; /* If the iterator is already at the end of the changeset, return DONE. */ - if( p->in.iNext>=p->in.nChangeset ){ + if( p->in.iNext>=p->in.nData ){ return SQLITE_DONE; } - op = p->in.aChangeset[p->in.iNext++]; + op = p->in.aData[p->in.iNext++]; if( op=='T' || op=='P' ){ p->bPatchset = (op=='P'); if( sessionChangesetReadTblhdr(p) ) return p->rc; if( (p->rc = sessionInputBuffer(&p->in, 2)) ) return p->rc; - op = p->in.aChangeset[p->in.iNext++]; + op = p->in.aData[p->in.iNext++]; } p->op = op; - p->bIndirect = p->in.aChangeset[p->in.iNext++]; + p->bIndirect = p->in.aData[p->in.iNext++]; if( p->op!=SQLITE_UPDATE && p->op!=SQLITE_DELETE && p->op!=SQLITE_INSERT ){ - return (p->rc = SQLITE_CORRUPT); + return (p->rc = SQLITE_CORRUPT_BKPT); } - if( paRec ){ *paRec = &p->in.aChangeset[p->in.iNext]; } + if( paRec ){ *paRec = &p->in.aData[p->in.iNext]; } /* If this is an UPDATE or DELETE, read the old.* record. */ if( p->op!=SQLITE_INSERT && (p->bPatchset==0 || p->op==SQLITE_DELETE) ){ @@ -2340,7 +2387,7 @@ static int sessionChangesetNext( } if( pnRec ){ - *pnRec = (int)(&p->in.aChangeset[p->in.iNext] - *paRec); + *pnRec = (int)(&p->in.aData[p->in.iNext] - *paRec); }else if( p->bPatchset && p->op==SQLITE_UPDATE ){ /* If this is an UPDATE that is part of a patchset, then all PK and ** modified fields are present in the new.* record. The old.* record @@ -2530,6 +2577,7 @@ int sqlite3changeset_finalize(sqlite3_changeset_iter *p){ for(i=0; inCol*2; i++) sqlite3ValueFree(p->apValue[i]); } sqlite3_free(p->tblhdr.aBuf); + sqlite3_free(p->in.buf.aBuf); sqlite3_free(p); return rc; } @@ -2560,8 +2608,8 @@ int sqlite3changeset_invert( /* Set up the input stream */ memset(&sInput, 0, sizeof(SessionInput)); - sInput.nChangeset = nChangeset; - sInput.aChangeset = (u8*)pChangeset; + sInput.nData = nChangeset; + sInput.aData = (u8*)pChangeset; aOut = (u8 *)sqlite3_malloc(nChangeset); if( !aOut ) return SQLITE_NOMEM; @@ -2571,7 +2619,7 @@ int sqlite3changeset_invert( while( inData - p->iData; /* Bytes of data available */ + int nRet = p->nStream; /* Bytes actually returned */ + + if( nRet>nReq ) nRet = nReq; + if( nRet>nRem ) nRet = nRem; + + assert( nRet>=0 ); + if( nRet>0 ){ + memcpy(pData, &p->aData[p->iData], nRet); + p->iData += nRet; + } + + *pnData = nRet; + return SQLITE_OK; +} + + /* ** sqlite3changeset_apply DB CHANGESET CONFLICT-SCRIPT ?FILTER-SCRIPT? */ @@ -559,6 +591,10 @@ static int test_sqlite3changeset_apply( void *pChangeset; /* Buffer containing changeset */ int nChangeset; /* Size of buffer aChangeset in bytes */ TestConflictHandler ctx; + TestStreamInput sStr; + + memset(&sStr, 0, sizeof(sStr)); + sStr.nStream = test_tcl_integer(interp, SESSION_STREAM_TCL_VAR); if( objc!=4 && objc!=5 ){ Tcl_WrongNumArgs(interp, 1, objv, @@ -576,9 +612,18 @@ static int test_sqlite3changeset_apply( ctx.pFilterScript = objc==5 ? objv[4] : 0; ctx.interp = interp; - rc = sqlite3changeset_apply(db, nChangeset, pChangeset, - (objc==5) ? test_filter_handler : 0, test_conflict_handler, (void *)&ctx - ); + if( sStr.nStream==0 ){ + rc = sqlite3changeset_apply(db, nChangeset, pChangeset, + (objc==5) ? test_filter_handler : 0, test_conflict_handler, (void *)&ctx + ); + }else{ + sStr.aData = (unsigned char*)pChangeset; + sStr.nData = nChangeset; + rc = sqlite3changeset_apply_str(db, testStreamInput, (void*)&sStr, + (objc==5) ? test_filter_handler : 0, test_conflict_handler, (void *)&ctx + ); + } + if( rc!=SQLITE_OK ){ return test_session_error(interp, rc); } @@ -632,7 +677,7 @@ static int test_sqlite3changeset_invert( ){ int rc; /* Return code from changeset_invert() */ void *aChangeset; /* Input changeset */ - int nChangeSet; /* Size of buffer aChangeset in bytes */ + int nChangeset; /* Size of buffer aChangeset in bytes */ void *aOut; /* Output changeset */ int nOut; /* Size of buffer aOut in bytes */ @@ -640,9 +685,9 @@ static int test_sqlite3changeset_invert( Tcl_WrongNumArgs(interp, 1, objv, "CHANGESET"); return TCL_ERROR; } - aChangeset = (void *)Tcl_GetByteArrayFromObj(objv[1], &nChangeSet); + aChangeset = (void *)Tcl_GetByteArrayFromObj(objv[1], &nChangeset); - rc = sqlite3changeset_invert(nChangeSet, aChangeset, &nOut, &aOut); + rc = sqlite3changeset_invert(nChangeset, aChangeset, &nOut, &aOut); if( rc!=SQLITE_OK ){ return test_session_error(interp, rc); } @@ -693,8 +738,8 @@ static int test_sqlite3session_foreach( int objc, Tcl_Obj *CONST objv[] ){ - void *pChangeSet; - int nChangeSet; + void *pChangeset; + int nChangeset; sqlite3_changeset_iter *pIter; int rc; Tcl_Obj *pVarname; @@ -702,6 +747,9 @@ static int test_sqlite3session_foreach( Tcl_Obj *pScript; int isCheckNext = 0; + TestStreamInput sStr; + memset(&sStr, 0, sizeof(sStr)); + if( objc>1 ){ char *zOpt = Tcl_GetString(objv[1]); isCheckNext = (strcmp(zOpt, "-next")==0); @@ -715,8 +763,15 @@ static int test_sqlite3session_foreach( pCS = objv[2+isCheckNext]; pScript = objv[3+isCheckNext]; - pChangeSet = (void *)Tcl_GetByteArrayFromObj(pCS, &nChangeSet); - rc = sqlite3changeset_start(&pIter, nChangeSet, pChangeSet); + pChangeset = (void *)Tcl_GetByteArrayFromObj(pCS, &nChangeset); + sStr.nStream = test_tcl_integer(interp, SESSION_STREAM_TCL_VAR); + if( sStr.nStream==0 ){ + rc = sqlite3changeset_start(&pIter, nChangeset, pChangeset); + }else{ + sStr.aData = (unsigned char*)pChangeset; + sStr.nData = nChangeset; + rc = sqlite3changeset_start_str(&pIter, testStreamInput, (void*)&sStr); + } if( rc!=SQLITE_OK ){ return test_session_error(interp, rc); } diff --git a/manifest b/manifest index 753640048a..e7faacba4f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Begin\sadding\s'streaming'\sAPIs\sto\ssessions\smodule.\sThis\sis\sa\swork\sin\sprogress. -D 2014-09-23T20:39:55.903 +C Add\sstreaming\sversion\sof\ssqlite3changeset_apply().\sTests\sand\sfixes\sfor\sthe\ssame\sand\ssqlite3changeset_start_str(). +D 2014-09-24T17:13:20.331 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in dd5f245aa8c741bc65845747203c8ce2f3fb6c83 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -158,9 +158,9 @@ F ext/session/sessionA.test eb05c13e4ef1ca8046a3a6dbf2d5f6f5b04a11d4 F ext/session/sessionB.test 276267cd7fc37c2e2dd03f1e2ed9ada336a8bdb4 F ext/session/session_common.tcl 1539d8973b2aea0025c133eb0cc4c89fcef541a5 F ext/session/sessionfault.test e7965159a73d385c1a4af12d82c3a039ebdd71a6 -F ext/session/sqlite3session.c ead909b1b0976aa6d08dcb7b487a902e358f7e4c -F ext/session/sqlite3session.h d074a929d368b438d32c15af8f8fe2afa80afe3f -F ext/session/test_session.c e39119c8554fe1b0925a038423ca137ddf6f6bd9 +F ext/session/sqlite3session.c 1c653844900de41e175f77f22fe1af7abb05e798 +F ext/session/sqlite3session.h 7e7a31ad1992f6678a20654c9751dacd10384292 +F ext/session/test_session.c 77f1e7a269daeb60f82441ff859c812d686ef79d F ext/userauth/sqlite3userauth.h 19cb6f0e31316d0ee4afdfb7a85ef9da3333a220 F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04 F ext/userauth/userauth.c 5fa3bdb492f481bbc1709fc83c91ebd13460c69e @@ -832,7 +832,7 @@ F test/selectD.test b0f02a04ef7737decb24e08be2c39b9664b43394 F test/selectE.test fc02a1eb04c8eb537091482644b7d778ae8759b7 F test/selectF.test 21c94e6438f76537b72532fa9fd4710cdd455fc3 F test/server1.test 46803bd3fe8b99b30dbc5ff38ffc756f5c13a118 -F test/session.test 082dea459efc76e2a527b8ee9ff74d76e63ea7b6 +F test/session.test 35f9c76809c26bee45d86891c7620b692ef9b8a8 F test/shared.test 1da9dbad400cee0d93f252ccf76e1ae007a63746 F test/shared2.test 03eb4a8d372e290107d34b6ce1809919a698e879 F test/shared3.test fcd65cb11d189eff5f5c85cc4fad246fb0933108 @@ -1216,7 +1216,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 6406b77f2c447751a2fbb16f01c61cdcfd6af59e -R 67d8884fcab24bc7ffc4823662b37f4a +P 3c7d3d950bbf5f5ed3696ebc61c77ca48bafe2b5 +R bba1026624291c9ce371985c2bc9cae0 U dan -Z 2bbe541c87040990ceab83529c1e7e80 +Z 40a11f75418a19b3b02aba54325bf64c diff --git a/manifest.uuid b/manifest.uuid index 424c64b57a..4b63e2e10a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3c7d3d950bbf5f5ed3696ebc61c77ca48bafe2b5 \ No newline at end of file +b917fc146876f764442de08d5ec36e5b4cf5ab52 \ No newline at end of file diff --git a/test/session.test b/test/session.test index 85ac056cdd..da04ac45c5 100644 --- a/test/session.test +++ b/test/session.test @@ -16,6 +16,7 @@ ifcapable session { # again with it clear. run_test_suite session_eec run_test_suite session + run_test_suite session_str } finish_test From fa122adac1d0b19fef73945db4f061225bf922f6 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 25 Sep 2014 14:54:20 +0000 Subject: [PATCH 0122/1484] Add streaming version of sqlite3changeset_invert() to sessions module. FossilOrigin-Name: 8ded6a46794c7bff1c8b790c662ba7e92f576380 --- ext/session/sqlite3session.c | 220 +++++++++++++++++++++++++---------- ext/session/sqlite3session.h | 10 ++ ext/session/test_session.c | 31 +++-- manifest | 16 +-- manifest.uuid | 2 +- 5 files changed, 198 insertions(+), 81 deletions(-) diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index ceea8268c6..b62f039943 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -334,10 +334,11 @@ static int sessionSerializeValue( if( aBuf ) aBuf[0] = '\0'; } - *pnWrite += nByte; + if( pnWrite ) *pnWrite += nByte; return SQLITE_OK; } + /* ** This macro is used to calculate hash key values for data structures. In ** order to use this macro, the entire data structure must be represented @@ -1330,6 +1331,29 @@ static int sessionBufferGrow(SessionBuffer *p, int nByte, int *pRc){ return (*pRc!=SQLITE_OK); } +/* +** Append the value passed as the second argument to the buffer passed +** as the first. +** +** This function is a no-op if *pRc is non-zero when it is called. +** Otherwise, if an error occurs, *pRc is set to an SQLite error code +** before returning. +*/ +static void sessionAppendValue(SessionBuffer *p, sqlite3_value *pVal, int *pRc){ + int rc = *pRc; + if( rc==SQLITE_OK ){ + int nByte = 0; + sessionSerializeValue(0, pVal, &nByte); + sessionBufferGrow(p, nByte, &rc); + if( rc==SQLITE_OK ){ + rc = sessionSerializeValue(&p->aBuf[p->nBuf], pVal, 0); + p->nBuf += nByte; + }else{ + *pRc = rc; + } + } +} + /* ** This function is a no-op if *pRc is other than SQLITE_OK when it is ** called. Otherwise, append a single byte to the buffer. @@ -2268,6 +2292,38 @@ static int sessionChangesetBufferTblhdr(SessionInput *pIn, int *pnByte){ return rc; } +/* +** The input pointer currently points to the first byte of the first field +** of a record consisting of nCol columns. This function ensures the entire +** record is buffered. +*/ +static int sessionChangesetBufferRecord( + SessionInput *pIn, + int nCol, + int *pnByte +){ + int rc = SQLITE_OK; + int nByte = 0; + int i; + for(i=0; rc==SQLITE_OK && iaData[pIn->iNext + nByte++]; + if( eType==SQLITE_TEXT || eType==SQLITE_BLOB ){ + int n; + nByte += sessionVarintGet(&pIn->aData[pIn->iNext+nByte], &n); + nByte += n; + rc = sessionInputBuffer(pIn, nByte); + }else if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){ + nByte += 8; + } + } + } + *pnByte = nByte; + return rc; +} + /* ** The input pointer currently points to the second byte of a table-header. ** Specifically, to the following: @@ -2582,44 +2638,37 @@ int sqlite3changeset_finalize(sqlite3_changeset_iter *p){ return rc; } -/* -** Invert a changeset object. -*/ -int sqlite3changeset_invert( - int nChangeset, /* Number of bytes in input */ - const void *pChangeset, /* Input changeset */ +static int sessionChangesetInvert( + SessionInput *pInput, /* Input changeset */ + int (*xOutput)(void *pOut, const void *pData, int nData), + void *pOut, int *pnInverted, /* OUT: Number of bytes in output changeset */ void **ppInverted /* OUT: Inverse of pChangeset */ ){ int rc = SQLITE_OK; /* Return value */ - u8 *aOut; - u8 *aIn; - int i; - SessionInput sInput; + SessionBuffer sOut; /* Output buffer */ int nCol = 0; /* Number of cols in current table */ u8 *abPK = 0; /* PK array for current table */ sqlite3_value **apVal = 0; /* Space for values for UPDATE inversion */ SessionBuffer sPK = {0, 0, 0}; /* PK array for current table */ + /* Initialize the output buffer */ + memset(&sOut, 0, sizeof(SessionBuffer)); + /* Zero the output variables in case an error occurs. */ - *ppInverted = 0; - *pnInverted = 0; - if( nChangeset==0 ) return SQLITE_OK; + if( ppInverted ){ + *ppInverted = 0; + *pnInverted = 0; + } - /* Set up the input stream */ - memset(&sInput, 0, sizeof(SessionInput)); - sInput.nData = nChangeset; - sInput.aData = (u8*)pChangeset; - - aOut = (u8 *)sqlite3_malloc(nChangeset); - if( !aOut ) return SQLITE_NOMEM; - aIn = (u8 *)pChangeset; - - i = 0; - while( iiNext>=pInput->nData ) break; + eType = pInput->aData[pInput->iNext]; + switch( eType ){ case 'T': { /* A 'table' record consists of: @@ -2630,19 +2679,19 @@ int sqlite3changeset_invert( ** * A nul-terminated table name. */ int nByte; - int nVarint; - int iNext = sInput.iNext; - sInput.iNext++; - if( (rc = sessionChangesetBufferTblhdr(&sInput, &nByte)) ){ + int nVar; + pInput->iNext++; + if( (rc = sessionChangesetBufferTblhdr(pInput, &nByte)) ){ goto finished_invert; } - nVarint = sessionVarintGet(&sInput.aData[iNext+1], &nCol); + nVar = sessionVarintGet(&pInput->aData[pInput->iNext], &nCol); sPK.nBuf = 0; - sessionAppendBlob(&sPK, &sInput.aData[iNext+1+nVarint], nCol, &rc); + sessionAppendBlob(&sPK, &pInput->aData[pInput->iNext+nVar], nCol, &rc); + sessionAppendByte(&sOut, eType, &rc); + sessionAppendBlob(&sOut, &pInput->aData[pInput->iNext], nByte, &rc); if( rc ) goto finished_invert; - sInput.iNext += nByte; - memcpy(&aOut[i], &sInput.aData[iNext], nByte+1); - i += nByte+1; + + pInput->iNext += nByte; sqlite3_free(apVal); apVal = 0; abPK = sPK.aBuf; @@ -2651,22 +2700,22 @@ int sqlite3changeset_invert( case SQLITE_INSERT: case SQLITE_DELETE: { - int iStart; int nByte; - sInput.iNext += 2; - iStart = sInput.iNext; - sessionReadRecord(&sInput, nCol, 0, 0); - aOut[i] = (eType==SQLITE_DELETE ? SQLITE_INSERT : SQLITE_DELETE); - aOut[i+1] = aIn[i+1]; /* indirect-flag */ - nByte = sInput.iNext - iStart; - memcpy(&aOut[i+2], &sInput.aData[iStart], nByte); - i += 2 + nByte; + int bIndirect = pInput->aData[pInput->iNext+1]; + int eType2 = (eType==SQLITE_DELETE ? SQLITE_INSERT : SQLITE_DELETE); + pInput->iNext += 2; + assert( rc==SQLITE_OK ); + rc = sessionChangesetBufferRecord(pInput, nCol, &nByte); + sessionAppendByte(&sOut, eType2, &rc); + sessionAppendByte(&sOut, bIndirect, &rc); + sessionAppendBlob(&sOut, &pInput->aData[pInput->iNext], nByte, &rc); + pInput->iNext += nByte; + if( rc ) goto finished_invert; break; } case SQLITE_UPDATE: { int iCol; - int nWrite = 0; if( 0==apVal ){ apVal = (sqlite3_value **)sqlite3_malloc(sizeof(apVal[0])*nCol*2); @@ -2678,15 +2727,14 @@ int sqlite3changeset_invert( } /* Write the header for the new UPDATE change. Same as the original. */ - aOut[i] = SQLITE_UPDATE; - aOut[i+1] = sInput.aData[sInput.iNext+1]; - nWrite = 2; + sessionAppendByte(&sOut, eType, &rc); + sessionAppendByte(&sOut, pInput->aData[pInput->iNext+1], &rc); /* Read the old.* and new.* records for the update change. */ - sInput.iNext += 2; - rc = sessionReadRecord(&sInput, nCol, 0, &apVal[0]); + pInput->iNext += 2; + rc = sessionReadRecord(pInput, nCol, 0, &apVal[0]); if( rc==SQLITE_OK ){ - rc = sessionReadRecord(&sInput, nCol, 0, &apVal[nCol]); + rc = sessionReadRecord(pInput, nCol, 0, &apVal[nCol]); } /* Write the new old.* record. Consists of the PK columns from the @@ -2694,7 +2742,7 @@ int sqlite3changeset_invert( ** new.* record. */ for(iCol=0; rc==SQLITE_OK && iCol=SESSIONS_STR_CHUNK_SIZE ){ + rc = xOutput(pOut, sOut.aBuf, sOut.nBuf); + sOut.nBuf = 0; + if( rc!=SQLITE_OK ) goto finished_invert; + } } assert( rc==SQLITE_OK ); - *pnInverted = nChangeset; - *ppInverted = (void *)aOut; + if( pnInverted ){ + *pnInverted = sOut.nBuf; + *ppInverted = sOut.aBuf; + sOut.aBuf = 0; + }else if( sOut.nBuf>0 ){ + rc = xOutput(pOut, sOut.aBuf, sOut.nBuf); + } finished_invert: - if( rc!=SQLITE_OK ){ - sqlite3_free(aOut); - } + sqlite3_free(sOut.aBuf); sqlite3_free(apVal); sqlite3_free(sPK.aBuf); return rc; } + +/* +** Invert a changeset object. +*/ +int sqlite3changeset_invert( + int nChangeset, /* Number of bytes in input */ + const void *pChangeset, /* Input changeset */ + int *pnInverted, /* OUT: Number of bytes in output changeset */ + void **ppInverted /* OUT: Inverse of pChangeset */ +){ + SessionInput sInput; + + /* Set up the input stream */ + memset(&sInput, 0, sizeof(SessionInput)); + sInput.nData = nChangeset; + sInput.aData = (u8*)pChangeset; + + return sessionChangesetInvert(&sInput, 0, 0, pnInverted, ppInverted); +} + +/* +** Streaming version of sqlite3changeset_invert(). +*/ +int sqlite3changeset_invert_str( + int (*xInput)(void *pIn, void *pData, int *pnData), + void *pIn, + int (*xOutput)(void *pOut, const void *pData, int nData), + void *pOut +){ + SessionInput sInput; + int rc; + + /* Set up the input stream */ + memset(&sInput, 0, sizeof(SessionInput)); + sInput.xInput = xInput; + sInput.pIn = pIn; + + rc = sessionChangesetInvert(&sInput, xOutput, pOut, 0, 0); + sqlite3_free(sInput.buf.aBuf); + return rc; +} + typedef struct SessionApplyCtx SessionApplyCtx; struct SessionApplyCtx { sqlite3 *db; diff --git a/ext/session/sqlite3session.h b/ext/session/sqlite3session.h index 28623391d4..ce91cb68f1 100644 --- a/ext/session/sqlite3session.h +++ b/ext/session/sqlite3session.h @@ -670,6 +670,16 @@ int sqlite3changeset_invert( int *pnOut, void **ppOut /* OUT: Inverse of input */ ); +/* +** Streaming version of sqlite3changeset_invert(). +*/ +int sqlite3changeset_invert_str( + int (*xInput)(void *pIn, void *pData, int *pnData), + void *pIn, + int (*xOutput)(void *pOut, const void *pData, int nData), + void *pOut +); + /* ** CAPI3REF: Concatenate Two Changeset Objects ** diff --git a/ext/session/test_session.c b/ext/session/test_session.c index 444519c98b..edd508d0e3 100644 --- a/ext/session/test_session.c +++ b/ext/session/test_session.c @@ -676,24 +676,33 @@ static int test_sqlite3changeset_invert( Tcl_Obj *CONST objv[] ){ int rc; /* Return code from changeset_invert() */ - void *aChangeset; /* Input changeset */ - int nChangeset; /* Size of buffer aChangeset in bytes */ - void *aOut; /* Output changeset */ - int nOut; /* Size of buffer aOut in bytes */ + TestStreamInput sIn; /* Input stream */ + TestSessionsBlob sOut; /* Output blob */ if( objc!=2 ){ Tcl_WrongNumArgs(interp, 1, objv, "CHANGESET"); return TCL_ERROR; } - aChangeset = (void *)Tcl_GetByteArrayFromObj(objv[1], &nChangeset); - rc = sqlite3changeset_invert(nChangeset, aChangeset, &nOut, &aOut); - if( rc!=SQLITE_OK ){ - return test_session_error(interp, rc); + memset(&sIn, 0, sizeof(sIn)); + memset(&sOut, 0, sizeof(sOut)); + sIn.nStream = test_tcl_integer(interp, SESSION_STREAM_TCL_VAR); + sIn.aData = Tcl_GetByteArrayFromObj(objv[1], &sIn.nData); + + if( sIn.nStream ){ + rc = sqlite3changeset_invert_str( + testStreamInput, (void*)&sIn, testSessionsOutput, (void*)&sOut + ); + }else{ + rc = sqlite3changeset_invert(sIn.nData, sIn.aData, &sOut.n, &sOut.p); } - Tcl_SetObjResult(interp, Tcl_NewByteArrayObj((unsigned char *)aOut, nOut)); - sqlite3_free(aOut); - return TCL_OK; + if( rc!=SQLITE_OK ){ + rc = test_session_error(interp, rc); + }else{ + Tcl_SetObjResult(interp,Tcl_NewByteArrayObj((unsigned char*)sOut.p,sOut.n)); + } + sqlite3_free(sOut.p); + return rc; } /* diff --git a/manifest b/manifest index e7faacba4f..3a15e079e7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sstreaming\sversion\sof\ssqlite3changeset_apply().\sTests\sand\sfixes\sfor\sthe\ssame\sand\ssqlite3changeset_start_str(). -D 2014-09-24T17:13:20.331 +C Add\sstreaming\sversion\sof\ssqlite3changeset_invert()\sto\ssessions\smodule. +D 2014-09-25T14:54:20.019 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in dd5f245aa8c741bc65845747203c8ce2f3fb6c83 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -158,9 +158,9 @@ F ext/session/sessionA.test eb05c13e4ef1ca8046a3a6dbf2d5f6f5b04a11d4 F ext/session/sessionB.test 276267cd7fc37c2e2dd03f1e2ed9ada336a8bdb4 F ext/session/session_common.tcl 1539d8973b2aea0025c133eb0cc4c89fcef541a5 F ext/session/sessionfault.test e7965159a73d385c1a4af12d82c3a039ebdd71a6 -F ext/session/sqlite3session.c 1c653844900de41e175f77f22fe1af7abb05e798 -F ext/session/sqlite3session.h 7e7a31ad1992f6678a20654c9751dacd10384292 -F ext/session/test_session.c 77f1e7a269daeb60f82441ff859c812d686ef79d +F ext/session/sqlite3session.c 9edf9273280c804c45e7508be9644cf96f278c63 +F ext/session/sqlite3session.h 944d7b2c3e87b5598a2c34afe8dd032d51d09818 +F ext/session/test_session.c 4449ef150e52baad844aa08c29569f3ec10902d8 F ext/userauth/sqlite3userauth.h 19cb6f0e31316d0ee4afdfb7a85ef9da3333a220 F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04 F ext/userauth/userauth.c 5fa3bdb492f481bbc1709fc83c91ebd13460c69e @@ -1216,7 +1216,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 3c7d3d950bbf5f5ed3696ebc61c77ca48bafe2b5 -R bba1026624291c9ce371985c2bc9cae0 +P b917fc146876f764442de08d5ec36e5b4cf5ab52 +R b1265a84c7bae5ddb87cac377b4def7e U dan -Z 40a11f75418a19b3b02aba54325bf64c +Z 0bbb9bee98e102db876d83b2977969a7 diff --git a/manifest.uuid b/manifest.uuid index 4b63e2e10a..49b0c2f888 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b917fc146876f764442de08d5ec36e5b4cf5ab52 \ No newline at end of file +8ded6a46794c7bff1c8b790c662ba7e92f576380 \ No newline at end of file From cbf6d2d2aa7fdceffd755dbe92954e4cca0dbfc5 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 25 Sep 2014 20:43:28 +0000 Subject: [PATCH 0123/1484] Add streaming version of sqlite3changeset_concat(). FossilOrigin-Name: 88eb6656bdb047a104837a2e15e7fe18c0a7a159 --- ext/session/sessionB.test | 9 +- ext/session/sqlite3session.c | 218 +++++++++++++++++++++++------------ ext/session/sqlite3session.h | 12 ++ ext/session/test_session.c | 43 ++++--- manifest | 18 +-- manifest.uuid | 2 +- 6 files changed, 203 insertions(+), 99 deletions(-) diff --git a/ext/session/sessionB.test b/ext/session/sessionB.test index 9798cabfee..2fc061f4e6 100644 --- a/ext/session/sessionB.test +++ b/ext/session/sessionB.test @@ -22,6 +22,11 @@ ifcapable !session {finish_test; return} set testprefix sessionB +# Fix the bug in concatenating patchsets that contain DELETE ops +# before re-enabling this. +finish_test +return + # # 1.*: Test that the blobs returned by the session_patchset() API are # as expected. Also the sqlite3_changeset_iter functions. @@ -385,10 +390,10 @@ proc do_patchset_test {tn tstcmd lSql} { sqlite3session T db main T attach * db eval $sql - lappend lPatch [T patchset] + lappend lPatch [T $tstcmd] T delete } - set patchset [S patchset] + set patchset [S $tstcmd] S delete # Calculate a checksum for the final database. diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index b62f039943..8c6cacd1a4 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -2386,7 +2386,6 @@ static int sessionChangesetNext( int i; u8 op; - assert( paRec==0 || p->in.xInput==0 ); /* fixme! */ assert( (paRec==0 && pnRec==0) || (paRec && pnRec) ); /* If the iterator is in the error-state, return immediately. */ @@ -2426,36 +2425,48 @@ static int sessionChangesetNext( return (p->rc = SQLITE_CORRUPT_BKPT); } - if( paRec ){ *paRec = &p->in.aData[p->in.iNext]; } - - /* If this is an UPDATE or DELETE, read the old.* record. */ - if( p->op!=SQLITE_INSERT && (p->bPatchset==0 || p->op==SQLITE_DELETE) ){ - u8 *abPK = p->bPatchset ? p->abPK : 0; - p->rc = sessionReadRecord(&p->in, p->nCol, abPK, paRec?0:p->apValue); + if( paRec ){ + int nVal; /* Number of values to buffer */ + if( p->bPatchset==0 && op==SQLITE_UPDATE ){ + nVal = p->nCol * 2; + }else if( p->bPatchset && op==SQLITE_DELETE ){ + nVal = 0; + for(i=0; inCol; i++) if( p->abPK[i] ) nVal++; + }else{ + nVal = p->nCol; + } + p->rc = sessionChangesetBufferRecord(&p->in, nVal, pnRec); if( p->rc!=SQLITE_OK ) return p->rc; - } + *paRec = &p->in.aData[p->in.iNext]; + p->in.iNext += *pnRec; + }else{ - /* If this is an INSERT or UPDATE, read the new.* record. */ - if( p->op!=SQLITE_DELETE ){ - sqlite3_value **apOut = (paRec ? 0 : &p->apValue[p->nCol]); - p->rc = sessionReadRecord(&p->in, p->nCol, 0, apOut); - if( p->rc!=SQLITE_OK ) return p->rc; - } + /* If this is an UPDATE or DELETE, read the old.* record. */ + if( p->op!=SQLITE_INSERT && (p->bPatchset==0 || p->op==SQLITE_DELETE) ){ + u8 *abPK = p->bPatchset ? p->abPK : 0; + p->rc = sessionReadRecord(&p->in, p->nCol, abPK, p->apValue); + if( p->rc!=SQLITE_OK ) return p->rc; + } - if( pnRec ){ - *pnRec = (int)(&p->in.aData[p->in.iNext] - *paRec); - }else if( p->bPatchset && p->op==SQLITE_UPDATE ){ - /* If this is an UPDATE that is part of a patchset, then all PK and - ** modified fields are present in the new.* record. The old.* record - ** is currently completely empty. This block shifts the PK fields from - ** new.* to old.*, to accommodate the code that reads these arrays. */ - int i; - for(i=0; inCol; i++){ - assert( p->apValue[i]==0 ); - assert( p->abPK[i]==0 || p->apValue[i+p->nCol] ); - if( p->abPK[i] ){ - p->apValue[i] = p->apValue[i+p->nCol]; - p->apValue[i+p->nCol] = 0; + /* If this is an INSERT or UPDATE, read the new.* record. */ + if( p->op!=SQLITE_DELETE ){ + p->rc = sessionReadRecord(&p->in, p->nCol, 0, &p->apValue[p->nCol]); + if( p->rc!=SQLITE_OK ) return p->rc; + } + + if( p->bPatchset && p->op==SQLITE_UPDATE ){ + /* If this is an UPDATE that is part of a patchset, then all PK and + ** modified fields are present in the new.* record. The old.* record + ** is currently completely empty. This block shifts the PK fields from + ** new.* to old.*, to accommodate the code that reads these arrays. */ + int i; + for(i=0; inCol; i++){ + assert( p->apValue[i]==0 ); + assert( p->abPK[i]==0 || p->apValue[i+p->nCol] ); + if( p->abPK[i] ){ + p->apValue[i] = p->apValue[i+p->nCol]; + p->apValue[i+p->nCol] = 0; + } } } } @@ -2627,14 +2638,17 @@ int sqlite3changeset_fk_conflicts( ** callback by changeset_apply(). */ int sqlite3changeset_finalize(sqlite3_changeset_iter *p){ - int i; /* Used to iterate through p->apValue[] */ - int rc = p->rc; /* Return code */ - if( p->apValue ){ - for(i=0; inCol*2; i++) sqlite3ValueFree(p->apValue[i]); + int rc = SQLITE_OK; + if( p ){ + int i; /* Used to iterate through p->apValue[] */ + rc = p->rc; + if( p->apValue ){ + for(i=0; inCol*2; i++) sqlite3ValueFree(p->apValue[i]); + } + sqlite3_free(p->tblhdr.aBuf); + sqlite3_free(p->in.buf.aBuf); + sqlite3_free(p); } - sqlite3_free(p->tblhdr.aBuf); - sqlite3_free(p->in.buf.aBuf); - sqlite3_free(p); return rc; } @@ -3647,7 +3661,7 @@ static int sessionChangeMerge( SessionChange *pNew = 0; if( !pExist ){ - pNew = (SessionChange *)sqlite3_malloc(sizeof(SessionChange)); + pNew = (SessionChange *)sqlite3_malloc(sizeof(SessionChange) + nRec); if( !pNew ){ return SQLITE_NOMEM; } @@ -3655,7 +3669,8 @@ static int sessionChangeMerge( pNew->op = op2; pNew->bIndirect = bIndirect; pNew->nRecord = nRec; - pNew->aRecord = aRec; + pNew->aRecord = (u8*)&pNew[1]; + memcpy(pNew->aRecord, aRec, nRec); }else{ int op1 = pExist->op; @@ -3751,21 +3766,15 @@ static int sessionChangeMerge( ** Add all changes in the changeset passed via the first two arguments to ** hash tables. */ -static int sessionConcatChangeset( - int bPatchset, /* True to expect patchsets */ - int nChangeset, /* Number of bytes in pChangeset */ - void *pChangeset, /* Changeset buffer */ +static int sessionAddChangeset( + sqlite3_changeset_iter *pIter, /* Iterator to read from */ SessionTable **ppTabList /* IN/OUT: List of table objects */ ){ u8 *aRec; int nRec; - sqlite3_changeset_iter *pIter; - int rc; + int rc = SQLITE_OK; SessionTable *pTab = 0; - rc = sqlite3changeset_start(&pIter, nChangeset, pChangeset); - if( rc!=SQLITE_OK ) return rc; - while( SQLITE_ROW==sessionChangesetNext(pIter, &aRec, &nRec) ){ const char *zNew; int nCol; @@ -3776,12 +3785,14 @@ static int sessionConcatChangeset( SessionChange *pExist = 0; SessionChange **pp; +#if 0 assert( bPatchset==0 || bPatchset==1 ); assert( pIter->bPatchset==0 || pIter->bPatchset==1 ); if( pIter->bPatchset!=bPatchset ){ rc = SQLITE_ERROR; break; } +#endif sqlite3changeset_op(pIter, &zNew, &nCol, &op, &bIndirect); if( !pTab || sqlite3_stricmp(zNew, pTab->zName) ){ @@ -3813,12 +3824,12 @@ static int sessionConcatChangeset( } } - if( sessionGrowHash(bPatchset, pTab) ){ + if( sessionGrowHash(pIter->bPatchset, pTab) ){ rc = SQLITE_NOMEM; break; } iHash = sessionChangeHash( - pTab, (bPatchset && op==SQLITE_DELETE), aRec, pTab->nChange + pTab, (pIter->bPatchset && op==SQLITE_DELETE), aRec, pTab->nChange ); /* Search for existing entry. If found, remove it from the hash table. @@ -3827,7 +3838,7 @@ static int sessionConcatChangeset( for(pp=&pTab->apChange[iHash]; *pp; pp=&(*pp)->pNext){ int bPkOnly1 = 0; int bPkOnly2 = 0; - if( bPatchset ){ + if( pIter->bPatchset ){ bPkOnly1 = (*pp)->op==SQLITE_DELETE; bPkOnly2 = op==SQLITE_DELETE; } @@ -3840,7 +3851,7 @@ static int sessionConcatChangeset( } rc = sessionChangeMerge(pTab, - bPatchset, pExist, op, bIndirect, aRec, nRec, &pChange + pIter->bPatchset, pExist, op, bIndirect, aRec, nRec, &pChange ); if( rc ) break; if( pChange ){ @@ -3850,15 +3861,10 @@ static int sessionConcatChangeset( } } - if( rc==SQLITE_OK ){ - rc = sqlite3changeset_finalize(pIter); - }else{ - sqlite3changeset_finalize(pIter); - } + if( rc==SQLITE_OK ) rc = pIter->rc; return rc; } - /* ** 1. Iterate through the left-hand changeset. Add an entry to a table ** specific hash table for each change in the changeset. The hash table @@ -3870,26 +3876,25 @@ static int sessionConcatChangeset( ** ** 3. Write an output changeset based on the contents of the hash table. */ -int sqlite3changeset_concat( - int nLeft, /* Number of bytes in lhs input */ - void *pLeft, /* Lhs input changeset */ - int nRight /* Number of bytes in rhs input */, - void *pRight, /* Rhs input changeset */ - int *pnOut, /* OUT: Number of bytes in output changeset */ - void **ppOut /* OUT: changeset (left right) */ +int sessionChangesetConcat( + sqlite3_changeset_iter *pLeft, + sqlite3_changeset_iter *pRight, + int (*xOutput)(void *pOut, const void *pData, int nData), + void *pOut, + int *pnOut, + void **ppOut ){ SessionTable *pList = 0; /* List of SessionTable objects */ int rc; /* Return code */ int bPatch; /* True for a patchset */ - *pnOut = 0; - *ppOut = 0; - bPatch = (nLeft>0 && *(char*)pLeft=='P') || (nRight>0 && *(char*)pRight=='P'); + assert( xOutput==0 || (ppOut==0 && pnOut==0) ); - rc = sessionConcatChangeset(bPatch, nLeft, pLeft, &pList); + rc = sessionAddChangeset(pLeft, &pList); if( rc==SQLITE_OK ){ - rc = sessionConcatChangeset(bPatch, nRight, pRight, &pList); + rc = sessionAddChangeset(pRight, &pList); } + bPatch = pLeft->bPatchset || pRight->bPatchset; /* Create the serialized output changeset based on the contents of the ** hash tables attached to the SessionTable objects in list pList. @@ -3897,7 +3902,7 @@ int sqlite3changeset_concat( if( rc==SQLITE_OK ){ SessionTable *pTab; SessionBuffer buf = {0, 0, 0}; - for(pTab=pList; pTab; pTab=pTab->pNext){ + for(pTab=pList; pTab && rc==SQLITE_OK; pTab=pTab->pNext){ int i; if( pTab->nEntry==0 ) continue; @@ -3910,18 +3915,85 @@ int sqlite3changeset_concat( sessionAppendBlob(&buf, p->aRecord, p->nRecord, &rc); } } + + if( rc==SQLITE_OK && xOutput && buf.nBuf>=SESSIONS_STR_CHUNK_SIZE ){ + rc = xOutput(pOut, buf.aBuf, buf.nBuf); + buf.nBuf = 0; + } } if( rc==SQLITE_OK ){ - *ppOut = buf.aBuf; - *pnOut = buf.nBuf; - }else{ - sqlite3_free(buf.aBuf); + if( xOutput ){ + if( buf.nBuf>0 ) rc = xOutput(pOut, buf.aBuf, buf.nBuf); + }else{ + *ppOut = buf.aBuf; + *pnOut = buf.nBuf; + buf.aBuf = 0; + } } + sqlite3_free(buf.aBuf); } sessionDeleteTable(pList); return rc; } +/* +** Combine two changesets together. +*/ +int sqlite3changeset_concat( + int nLeft, /* Number of bytes in lhs input */ + void *pLeft, /* Lhs input changeset */ + int nRight /* Number of bytes in rhs input */, + void *pRight, /* Rhs input changeset */ + int *pnOut, /* OUT: Number of bytes in output changeset */ + void **ppOut /* OUT: changeset (left right) */ +){ + sqlite3_changeset_iter *pIter1 = 0; + sqlite3_changeset_iter *pIter2 = 0; + int rc; + + *pnOut = 0; + *ppOut = 0; + rc = sqlite3changeset_start(&pIter1, nLeft, pLeft); + if( rc==SQLITE_OK ){ + rc = sqlite3changeset_start(&pIter2, nRight, pRight); + } + if( rc==SQLITE_OK ){ + rc = sessionChangesetConcat(pIter1, pIter2, 0, 0, pnOut, ppOut); + } + + sqlite3changeset_finalize(pIter1); + sqlite3changeset_finalize(pIter2); + return rc; +} + +/* +** Streaming version of sqlite3changeset_concat(). +*/ +int sqlite3changeset_concat_str( + int (*xInputA)(void *pIn, void *pData, int *pnData), + void *pInA, + int (*xInputB)(void *pIn, void *pData, int *pnData), + void *pInB, + int (*xOutput)(void *pOut, const void *pData, int nData), + void *pOut +){ + sqlite3_changeset_iter *pIter1 = 0; + sqlite3_changeset_iter *pIter2 = 0; + int rc; + + rc = sqlite3changeset_start_str(&pIter1, xInputA, pInA); + if( rc==SQLITE_OK ){ + rc = sqlite3changeset_start_str(&pIter2, xInputB, pInB); + } + if( rc==SQLITE_OK ){ + rc = sessionChangesetConcat(pIter1, pIter2, xOutput, pOut, 0, 0); + } + + sqlite3changeset_finalize(pIter1); + sqlite3changeset_finalize(pIter2); + return rc; +} + #endif /* SQLITE_ENABLE_SESSION && SQLITE_ENABLE_PREUPDATE_HOOK */ diff --git a/ext/session/sqlite3session.h b/ext/session/sqlite3session.h index ce91cb68f1..ad58c0d772 100644 --- a/ext/session/sqlite3session.h +++ b/ext/session/sqlite3session.h @@ -761,6 +761,18 @@ int sqlite3changeset_concat( void **ppOut /* OUT: Buffer containing output changeset */ ); +/* +** Streaming verson of sqlite3changeset_concat(). +*/ +int sqlite3changeset_concat_str( + int (*xInputA)(void *pIn, void *pData, int *pnData), + void *pInA, + int (*xInputB)(void *pIn, void *pData, int *pnData), + void *pInB, + int (*xOutput)(void *pOut, const void *pData, int nData), + void *pOut +); + /* ** CAPI3REF: Apply A Changeset To A Database ** diff --git a/ext/session/test_session.c b/ext/session/test_session.c index edd508d0e3..df690d44ad 100644 --- a/ext/session/test_session.c +++ b/ext/session/test_session.c @@ -715,27 +715,42 @@ static int test_sqlite3changeset_concat( Tcl_Obj *CONST objv[] ){ int rc; /* Return code from changeset_invert() */ - void *aLeft; /* Input changeset */ - int nLeft; /* Size of buffer aChangeset in bytes */ - void *aRight; /* Input changeset */ - int nRight; /* Size of buffer aChangeset in bytes */ - void *aOut; /* Output changeset */ - int nOut; /* Size of buffer aOut in bytes */ + + TestStreamInput sLeft; /* Input stream */ + TestStreamInput sRight; /* Input stream */ + TestSessionsBlob sOut = {0,0}; /* Output blob */ if( objc!=3 ){ Tcl_WrongNumArgs(interp, 1, objv, "LEFT RIGHT"); return TCL_ERROR; } - aLeft = (void *)Tcl_GetByteArrayFromObj(objv[1], &nLeft); - aRight = (void *)Tcl_GetByteArrayFromObj(objv[2], &nRight); - rc = sqlite3changeset_concat(nLeft, aLeft, nRight, aRight, &nOut, &aOut); - if( rc!=SQLITE_OK ){ - return test_session_error(interp, rc); + memset(&sLeft, 0, sizeof(sLeft)); + memset(&sRight, 0, sizeof(sRight)); + sLeft.aData = Tcl_GetByteArrayFromObj(objv[1], &sLeft.nData); + sRight.aData = Tcl_GetByteArrayFromObj(objv[2], &sRight.nData); + sLeft.nStream = test_tcl_integer(interp, SESSION_STREAM_TCL_VAR); + sRight.nStream = sLeft.nStream; + + if( sLeft.nStream>0 ){ + rc = sqlite3changeset_concat_str( + testStreamInput, (void*)&sLeft, + testStreamInput, (void*)&sRight, + testSessionsOutput, (void*)&sOut + ); + }else{ + rc = sqlite3changeset_concat( + sLeft.nData, sLeft.aData, sRight.nData, sRight.aData, &sOut.n, &sOut.p + ); } - Tcl_SetObjResult(interp, Tcl_NewByteArrayObj((unsigned char *)aOut, nOut)); - sqlite3_free(aOut); - return TCL_OK; + + if( rc!=SQLITE_OK ){ + rc = test_session_error(interp, rc); + }else{ + Tcl_SetObjResult(interp,Tcl_NewByteArrayObj((unsigned char*)sOut.p,sOut.n)); + } + sqlite3_free(sOut.p); + return rc; } /* diff --git a/manifest b/manifest index 3a15e079e7..ddf1638203 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sstreaming\sversion\sof\ssqlite3changeset_invert()\sto\ssessions\smodule. -D 2014-09-25T14:54:20.019 +C Add\sstreaming\sversion\sof\ssqlite3changeset_concat(). +D 2014-09-25T20:43:28.741 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in dd5f245aa8c741bc65845747203c8ce2f3fb6c83 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -155,12 +155,12 @@ F ext/session/session6.test 443789bc2fca12e4f7075cf692c60b8a2bea1a26 F ext/session/session8.test 7d35947ad329b8966f095d34f9617a9eff52dc65 F ext/session/session9.test 776e46785c29c11cda01f5205d0f1e8f8f9a46bf F ext/session/sessionA.test eb05c13e4ef1ca8046a3a6dbf2d5f6f5b04a11d4 -F ext/session/sessionB.test 276267cd7fc37c2e2dd03f1e2ed9ada336a8bdb4 +F ext/session/sessionB.test c414583719a6a1b430bbb4b32cdffc6089d2b139 F ext/session/session_common.tcl 1539d8973b2aea0025c133eb0cc4c89fcef541a5 F ext/session/sessionfault.test e7965159a73d385c1a4af12d82c3a039ebdd71a6 -F ext/session/sqlite3session.c 9edf9273280c804c45e7508be9644cf96f278c63 -F ext/session/sqlite3session.h 944d7b2c3e87b5598a2c34afe8dd032d51d09818 -F ext/session/test_session.c 4449ef150e52baad844aa08c29569f3ec10902d8 +F ext/session/sqlite3session.c 368fe2e3f4c435673acbc1df7f470ebd383e168f +F ext/session/sqlite3session.h 04529352750006b32811384db64eb1b6e5c3cd80 +F ext/session/test_session.c 194083ee1f0f6f38404f662fe9b50849abd3b7ee F ext/userauth/sqlite3userauth.h 19cb6f0e31316d0ee4afdfb7a85ef9da3333a220 F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04 F ext/userauth/userauth.c 5fa3bdb492f481bbc1709fc83c91ebd13460c69e @@ -1216,7 +1216,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P b917fc146876f764442de08d5ec36e5b4cf5ab52 -R b1265a84c7bae5ddb87cac377b4def7e +P 8ded6a46794c7bff1c8b790c662ba7e92f576380 +R ee60d24169659791aff86861c22f5852 U dan -Z 0bbb9bee98e102db876d83b2977969a7 +Z 192d45bf138dc22ddb0bc36d2880342f diff --git a/manifest.uuid b/manifest.uuid index 49b0c2f888..a34e37dfb6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8ded6a46794c7bff1c8b790c662ba7e92f576380 \ No newline at end of file +88eb6656bdb047a104837a2e15e7fe18c0a7a159 \ No newline at end of file From fa29ecc4ed5b09b157b6270097ebbc7c2e951632 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 26 Sep 2014 10:52:21 +0000 Subject: [PATCH 0124/1484] Fix a problem with concatenating patchsets containing DELETE and INSERT operations on the same row. FossilOrigin-Name: 4d8537eafb40e3687abc057ba26a1f7014f2c2d9 --- ext/session/sessionB.test | 5 ----- ext/session/sqlite3session.c | 19 ++++++++++++++----- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 22 insertions(+), 18 deletions(-) diff --git a/ext/session/sessionB.test b/ext/session/sessionB.test index 2fc061f4e6..b11c3110a1 100644 --- a/ext/session/sessionB.test +++ b/ext/session/sessionB.test @@ -22,11 +22,6 @@ ifcapable !session {finish_test; return} set testprefix sessionB -# Fix the bug in concatenating patchsets that contain DELETE ops -# before re-enabling this. -finish_test -return - # # 1.*: Test that the blobs returned by the session_patchset() API are # as expected. Also the sqlite3_changeset_iter functions. diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index 8c6cacd1a4..a0e0697ee3 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -597,11 +597,15 @@ static void sessionMergeRecord( ** as to point to the next value in the record. ** ** If, when this function is called, *paTwo points to a valid value (i.e. -** *paTwo[0] is not 0x00 - the "no value" placeholder), a copy of the *paOne +** *paTwo[0] is not 0x00 - the "no value" placeholder), a copy of the *paTwo ** pointer is returned and *pnVal is set to the number of bytes in the ** serialized value. Otherwise, a copy of *paOne is returned and *pnVal ** set to the number of bytes in the value at *paOne. If *paOne points -** to the "no value" placeholder, *pnVal is set to 1. +** to the "no value" placeholder, *pnVal is set to 1. In other words: +** +** if( *paTwo is valid ) return *paTwo; +** return *paOne; +** */ static u8 *sessionMergeValue( u8 **paOne, /* IN/OUT: Left-hand buffer pointer */ @@ -3723,9 +3727,14 @@ static int sessionChangeMerge( }else if( op1==SQLITE_DELETE ){ /* DELETE + INSERT */ assert( op2==SQLITE_INSERT ); pNew->op = SQLITE_UPDATE; - if( 0==sessionMergeUpdate(&aCsr, pTab, bPatchset, aExist, 0, aRec, 0) ){ - sqlite3_free(pNew); - pNew = 0; + if( bPatchset ){ + memcpy(aCsr, aRec, nRec); + aCsr += nRec; + }else{ + if( 0==sessionMergeUpdate(&aCsr, pTab, bPatchset, aExist, 0,aRec,0) ){ + sqlite3_free(pNew); + pNew = 0; + } } }else if( op2==SQLITE_UPDATE ){ /* UPDATE + UPDATE */ u8 *a1 = aExist; diff --git a/manifest b/manifest index ddf1638203..07a4e34a3b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sstreaming\sversion\sof\ssqlite3changeset_concat(). -D 2014-09-25T20:43:28.741 +C Fix\sa\sproblem\swith\sconcatenating\spatchsets\scontaining\sDELETE\sand\sINSERT\soperations\son\sthe\ssame\srow. +D 2014-09-26T10:52:21.193 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in dd5f245aa8c741bc65845747203c8ce2f3fb6c83 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -155,10 +155,10 @@ F ext/session/session6.test 443789bc2fca12e4f7075cf692c60b8a2bea1a26 F ext/session/session8.test 7d35947ad329b8966f095d34f9617a9eff52dc65 F ext/session/session9.test 776e46785c29c11cda01f5205d0f1e8f8f9a46bf F ext/session/sessionA.test eb05c13e4ef1ca8046a3a6dbf2d5f6f5b04a11d4 -F ext/session/sessionB.test c414583719a6a1b430bbb4b32cdffc6089d2b139 +F ext/session/sessionB.test d4ac901b43d4922a17dff08bbaa2f5354487ce4d F ext/session/session_common.tcl 1539d8973b2aea0025c133eb0cc4c89fcef541a5 F ext/session/sessionfault.test e7965159a73d385c1a4af12d82c3a039ebdd71a6 -F ext/session/sqlite3session.c 368fe2e3f4c435673acbc1df7f470ebd383e168f +F ext/session/sqlite3session.c ade9fa2f7341b822dddaa865115ec964a030df94 F ext/session/sqlite3session.h 04529352750006b32811384db64eb1b6e5c3cd80 F ext/session/test_session.c 194083ee1f0f6f38404f662fe9b50849abd3b7ee F ext/userauth/sqlite3userauth.h 19cb6f0e31316d0ee4afdfb7a85ef9da3333a220 @@ -1216,7 +1216,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 8ded6a46794c7bff1c8b790c662ba7e92f576380 -R ee60d24169659791aff86861c22f5852 +P 88eb6656bdb047a104837a2e15e7fe18c0a7a159 +R 81a0c7112c65d31bc1808253eb2f372f U dan -Z 192d45bf138dc22ddb0bc36d2880342f +Z a169087f5f6ea34184b5d5b4868830f7 diff --git a/manifest.uuid b/manifest.uuid index a34e37dfb6..c388e5763a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -88eb6656bdb047a104837a2e15e7fe18c0a7a159 \ No newline at end of file +4d8537eafb40e3687abc057ba26a1f7014f2c2d9 \ No newline at end of file From 16228167c24b757214d2f8485d8b79c1bc0dc16f Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 27 Sep 2014 12:26:18 +0000 Subject: [PATCH 0125/1484] Improve sessions module documentation and comments. Fix some other code issues. FossilOrigin-Name: bfc8bd80f8b225cebc66478448510ce84223ae7d --- ext/session/sqlite3session.c | 48 ++++--- ext/session/sqlite3session.h | 237 ++++++++++++++++++++--------------- manifest | 14 +-- manifest.uuid | 2 +- 4 files changed, 171 insertions(+), 130 deletions(-) diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index a0e0697ee3..eb1ff1e774 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -49,10 +49,10 @@ struct SessionBuffer { }; /* -** An object of this type is used internally as an abstraction for the -** input data read by changeset iterators. Input data may be supplied -** either as a single large buffer (sqlite3changeset_start()) or using -** a stream function (sqlite3changeset_start_str()). +** An object of this type is used internally as an abstraction for +** input data. Input data may be supplied either as a single large buffer +** (e.g. sqlite3changeset_start()) or using a stream function (e.g. +** sqlite3changeset_start_str()). */ struct SessionInput { int iNext; /* Offset in aData[] of next change */ @@ -2173,6 +2173,10 @@ static int sessionValueSetStr( int nData, /* Size of buffer aData[] in bytes */ u8 enc /* String encoding (0 for blobs) */ ){ + /* In theory this code could just pass SQLITE_TRANSIENT as the final + ** argument to sqlite3ValueSetStr() and have the copy created + ** automatically. But doing so makes it difficult to detect any OOM + ** error. Hence the code to create the copy externally. */ u8 *aCopy = sqlite3_malloc(nData); if( aCopy==0 ) return SQLITE_NOMEM; memcpy(aCopy, aData, nData); @@ -2299,12 +2303,16 @@ static int sessionChangesetBufferTblhdr(SessionInput *pIn, int *pnByte){ /* ** The input pointer currently points to the first byte of the first field ** of a record consisting of nCol columns. This function ensures the entire -** record is buffered. +** record is buffered. It does not move the input pointer. +** +** If successful, SQLITE_OK is returned and *pnByte is set to the size of +** the record in bytes. Otherwise, an SQLite error code is returned. The +** final value of *pnByte is undefined in this case. */ static int sessionChangesetBufferRecord( - SessionInput *pIn, - int nCol, - int *pnByte + SessionInput *pIn, /* Input data */ + int nCol, /* Number of columns in record */ + int *pnByte /* OUT: Size of record in bytes */ ){ int rc = SQLITE_OK; int nByte = 0; @@ -2335,6 +2343,15 @@ static int sessionChangesetBufferRecord( ** + number of columns in table (varint) ** + array of PK flags (1 byte per column), ** + table name (nul terminated). +** +** This function decodes the table-header and populates the p->nCol, +** p->zTab and p->abPK[] variables accordingly. The p->apValue[] array is +** also allocated or resized according to the new value of p->nCol. The +** input pointer is left pointing to the byte following the table header. +** +** If successful, SQLITE_OK is returned. Otherwise, an SQLite error code +** is returned and the final values of the various fields enumerated above +** are undefined. */ static int sessionChangesetReadTblhdr(sqlite3_changeset_iter *p){ int rc; @@ -3775,7 +3792,7 @@ static int sessionChangeMerge( ** Add all changes in the changeset passed via the first two arguments to ** hash tables. */ -static int sessionAddChangeset( +static int sessionChangesetToHash( sqlite3_changeset_iter *pIter, /* Iterator to read from */ SessionTable **ppTabList /* IN/OUT: List of table objects */ ){ @@ -3794,15 +3811,6 @@ static int sessionAddChangeset( SessionChange *pExist = 0; SessionChange **pp; -#if 0 - assert( bPatchset==0 || bPatchset==1 ); - assert( pIter->bPatchset==0 || pIter->bPatchset==1 ); - if( pIter->bPatchset!=bPatchset ){ - rc = SQLITE_ERROR; - break; - } -#endif - sqlite3changeset_op(pIter, &zNew, &nCol, &op, &bIndirect); if( !pTab || sqlite3_stricmp(zNew, pTab->zName) ){ /* Search the list for a matching table */ @@ -3899,9 +3907,9 @@ int sessionChangesetConcat( assert( xOutput==0 || (ppOut==0 && pnOut==0) ); - rc = sessionAddChangeset(pLeft, &pList); + rc = sessionChangesetToHash(pLeft, &pList); if( rc==SQLITE_OK ){ - rc = sessionAddChangeset(pRight, &pList); + rc = sessionChangesetToHash(pRight, &pList); } bPatch = pLeft->bPatchset || pRight->bPatchset; diff --git a/ext/session/sqlite3session.h b/ext/session/sqlite3session.h index ad58c0d772..0dd03067ed 100644 --- a/ext/session/sqlite3session.h +++ b/ext/session/sqlite3session.h @@ -274,30 +274,6 @@ int sqlite3session_changeset( ); -/* -** This function is similar to sqlite3session_changeset(), except that instead -** of storing the output changeset in a buffer obtained from sqlite3_malloc() -** it invokes the supplied xOutput() callback zero or more times to stream the -** changeset to the application. This is useful in order to avoid large memory -** allocations when working with very large changesets. -** -** The first parameter passed to each call to the xOutput callback is a copy -** of the pOut parameter passed to this function. The following two parameters -** are a pointer to the buffer containing the next chunk of the output changeset -** and the size of that buffer in bytes. -** -** If the data is successfully processed by the xOutput callback, it should -** return SQLITE_OK. Or, if an error occurs, some other SQLite error code. In -** this case the sqlite3session_changeset_str() call is abandoned immediately -** and returns a copy of the xOutput return code. -*/ -int sqlite3session_changeset_str( - sqlite3_session *pSession, - int (*xOutput)(void *pOut, const void *pData, int nData), - void *pOut -); - - /* ** CAPI3REF: Generate A Patchset From A Session Object ** @@ -327,15 +303,6 @@ int sqlite3session_patchset( void **ppPatchset /* OUT: Buffer containing changeset */ ); -/* -** Streaming version of sqlite3session_patchset(). -*/ -int sqlite3session_patchset_str( - sqlite3_session *pSession, - int (*xOutput)(void *pOut, const void *pData, int nData), - void *pOut -); - /* ** CAPI3REF: Test if a changeset has recorded any changes. ** @@ -393,29 +360,6 @@ int sqlite3changeset_start( ); -/* -** This function is similar to sqlite3changeset_start(), except that instead -** of reading data from a single buffer, it requests it one chunk at a time -** from the application by invoking the supplied xInput() callback. The xInput() -** callback may be invoked at any time during the lifetime of the iterator. -** -** Each time the xInput callback is invoked, the first argument passed is a -** copy of the third parameter passed to this function. The second argument, -** pData, points to a buffer (*pnData) bytes in size. Assuming no error occurs -** the xInput method should copy up to (*pnData) bytes of data into the buffer -** and set (*pnData) to the actual number of bytes copied before returning -** SQLITE_OK. If the input is completely exhausted, (*pnData) should be set -** to zero to indicate this. Or, if an error occurs, an SQLite error code -** should be returned. In this case the iterator is put into an error state and -** all subsequent calls to iterator methods return a copy of the xInput error -** code. -*/ -int sqlite3changeset_start_str( - sqlite3_changeset_iter **pp, - int (*xInput)(void *pIn, void *pData, int *pnData), - void *pIn -); - /* ** CAPI3REF: Advance A Changeset Iterator ** @@ -670,16 +614,6 @@ int sqlite3changeset_invert( int *pnOut, void **ppOut /* OUT: Inverse of input */ ); -/* -** Streaming version of sqlite3changeset_invert(). -*/ -int sqlite3changeset_invert_str( - int (*xInput)(void *pIn, void *pData, int *pnData), - void *pIn, - int (*xOutput)(void *pOut, const void *pData, int nData), - void *pOut -); - /* ** CAPI3REF: Concatenate Two Changeset Objects ** @@ -761,18 +695,6 @@ int sqlite3changeset_concat( void **ppOut /* OUT: Buffer containing output changeset */ ); -/* -** Streaming verson of sqlite3changeset_concat(). -*/ -int sqlite3changeset_concat_str( - int (*xInputA)(void *pIn, void *pData, int *pnData), - void *pInA, - int (*xInputB)(void *pIn, void *pData, int *pnData), - void *pInB, - int (*xOutput)(void *pOut, const void *pData, int nData), - void *pOut -); - /* ** CAPI3REF: Apply A Changeset To A Database ** @@ -925,30 +847,6 @@ int sqlite3changeset_apply( void *pCtx /* First argument passed to xConflict */ ); -/* -** This function is similar to sqlite3changeset_apply(), except that instead -** of reading data from a single buffer, it requests it one chunk at a time -** from the application by invoking the supplied xInput() callback. -** -** See the documentation for sqlite3changeset_start_str() for a description -** of how the xInput callback should be implemented. -*/ -int sqlite3changeset_apply_str( - sqlite3 *db, /* Apply change to "main" db of this handle */ - int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */ - void *pIn, /* First arg for xInput */ - int(*xFilter)( - void *pCtx, /* Copy of sixth arg to _apply() */ - const char *zTab /* Table name */ - ), - int(*xConflict)( - void *pCtx, /* Copy of sixth arg to _apply() */ - int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */ - sqlite3_changeset_iter *p /* Handle describing change and conflict */ - ), - void *pCtx /* First argument passed to xConflict */ -); - /* ** CAPI3REF: Constants Passed To The Conflict Handler ** @@ -1045,6 +943,141 @@ int sqlite3changeset_apply_str( #define SQLITE_CHANGESET_REPLACE 1 #define SQLITE_CHANGESET_ABORT 2 +/* +** CAPI3REF: Streaming Versions of API functions. +** +** The six streaming API xxx_str() functions serve similar purposes to the +** corresponding non-streaming API functions: +** +** +** +**
Streaming functionNon-streaming equivalent
sqlite3changeset_apply_str[sqlite3changeset_apply] +**
sqlite3changeset_concat_str[sqlite3changeset_concat] +**
sqlite3changeset_invert_str[sqlite3changeset_invert] +**
sqlite3changeset_start_str[sqlite3changeset_start] +**
sqlite3session_changeset_str[sqlite3session_changeset] +**
sqlite3session_patchset_str[sqlite3session_patchset] +**
+** +** Non-streaming functions that accept changesets (or patchsets) as input +** require that the entire changeset be stored in a single buffer in memory. +** Similarly, those that return a changeset or patchset do so by returning +** a pointer to a single large buffer allocated using sqlite3_malloc(). +** Normally this is convenient. However, if an application running in a +** low-memory environment is required to handle very large changesets, the +** large contiguous memory allocations required can become onerous. +** +** In order to avoid this problem, instead of a single large buffer, input +** is passed to a streaming API functions by way of a callback function that +** the sessions module invokes to incrementally request input data as it is +** required. In all cases, a pair of API function parameters such as +** +**
+**        int nChangeset,
+**        void *pChangeset,
+**  
+** +** Is replaced by: +** +**
+**        int (*xInput)(void *pIn, void *pData, int *pnData),
+**        void *pIn,
+**  
+** +** Each time the xInput callback is invoked by the sessions module, the first +** argument passed is a copy of the supplied pIn context pointer. The second +** argument, pData, points to a buffer (*pnData) bytes in size. Assuming no +** error occurs the xInput method should copy up to (*pnData) bytes of data +** into the buffer and set (*pnData) to the actual number of bytes copied +** before returning SQLITE_OK. If the input is completely exhausted, (*pnData) +** should be set to zero to indicate this. Or, if an error occurs, an SQLite +** error code should be returned. In all cases, if an xInput callback returns +** an error, all processing is abandoned and the streaming API function +** returns a copy of the error code to the caller. +** +** In the case of sqlite3changeset_start_str(), the xInput callback may be +** invoked by the sessions module at any point during the lifetime of the +** iterator. If such an xInput callback returns an error, the iterator enters +** an error state, whereby all subsequent calls to iterator functions +** immediately fail with the same error code as returned by xInput. +** +** Similarly, streaming API functions that return changesets (or patchsets) +** return them in chunks by way of a callback function instead of via a +** pointer to a single large buffer. In this case, a pair of parameters such +** as: +** +**
+**        int *pnChangeset,
+**        void **ppChangeset,
+**  
+** +** Is replaced by: +** +**
+**        int (*xOutput)(void *pOut, const void *pData, int nData),
+**        void *pOut
+**  
+** +** The xOutput callback is invoked zero or more times to return data to +** the application. The first parameter passed to each call is a copy of the +** pOut pointer supplied by the application. The second parameter, pData, +** points to a buffer nData bytes in size containing the chunk of output +** data being returned. If the xOutput callback successfully processes the +** supplied data, it should return SQLITE_OK to indicate success. Otherwise, +** it should return some other SQLite error code. In this case processing +** is immediately abandoned and the streaming API function returns a copy +** of the xOutput error code to the application. +** +** The sessions module never invokes an xOutput callback with the third +** parameter set to a value less than or equal to zero. Other than this, +** no guarantees are made as to the size of the chunks of data returned. +*/ +int sqlite3changeset_apply_str( + sqlite3 *db, /* Apply change to "main" db of this handle */ + int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */ + void *pIn, /* First arg for xInput */ + int(*xFilter)( + void *pCtx, /* Copy of sixth arg to _apply() */ + const char *zTab /* Table name */ + ), + int(*xConflict)( + void *pCtx, /* Copy of sixth arg to _apply() */ + int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */ + sqlite3_changeset_iter *p /* Handle describing change and conflict */ + ), + void *pCtx /* First argument passed to xConflict */ +); +int sqlite3changeset_concat_str( + int (*xInputA)(void *pIn, void *pData, int *pnData), + void *pInA, + int (*xInputB)(void *pIn, void *pData, int *pnData), + void *pInB, + int (*xOutput)(void *pOut, const void *pData, int nData), + void *pOut +); +int sqlite3changeset_invert_str( + int (*xInput)(void *pIn, void *pData, int *pnData), + void *pIn, + int (*xOutput)(void *pOut, const void *pData, int nData), + void *pOut +); +int sqlite3changeset_start_str( + sqlite3_changeset_iter **pp, + int (*xInput)(void *pIn, void *pData, int *pnData), + void *pIn +); +int sqlite3session_changeset_str( + sqlite3_session *pSession, + int (*xOutput)(void *pOut, const void *pData, int nData), + void *pOut +); +int sqlite3session_patchset_str( + sqlite3_session *pSession, + int (*xOutput)(void *pOut, const void *pData, int nData), + void *pOut +); + + /* ** Make sure we can call this stuff from C++. */ diff --git a/manifest b/manifest index 07a4e34a3b..258fb598ba 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\swith\sconcatenating\spatchsets\scontaining\sDELETE\sand\sINSERT\soperations\son\sthe\ssame\srow. -D 2014-09-26T10:52:21.193 +C Improve\ssessions\smodule\sdocumentation\sand\scomments.\sFix\ssome\sother\scode\sissues. +D 2014-09-27T12:26:18.848 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in dd5f245aa8c741bc65845747203c8ce2f3fb6c83 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -158,8 +158,8 @@ F ext/session/sessionA.test eb05c13e4ef1ca8046a3a6dbf2d5f6f5b04a11d4 F ext/session/sessionB.test d4ac901b43d4922a17dff08bbaa2f5354487ce4d F ext/session/session_common.tcl 1539d8973b2aea0025c133eb0cc4c89fcef541a5 F ext/session/sessionfault.test e7965159a73d385c1a4af12d82c3a039ebdd71a6 -F ext/session/sqlite3session.c ade9fa2f7341b822dddaa865115ec964a030df94 -F ext/session/sqlite3session.h 04529352750006b32811384db64eb1b6e5c3cd80 +F ext/session/sqlite3session.c 9ce77f4752cd5d8982e7b64f665ae66754dda723 +F ext/session/sqlite3session.h b57009fb88835cc4684376bd3eae0d6ab364968a F ext/session/test_session.c 194083ee1f0f6f38404f662fe9b50849abd3b7ee F ext/userauth/sqlite3userauth.h 19cb6f0e31316d0ee4afdfb7a85ef9da3333a220 F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04 @@ -1216,7 +1216,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 88eb6656bdb047a104837a2e15e7fe18c0a7a159 -R 81a0c7112c65d31bc1808253eb2f372f +P 4d8537eafb40e3687abc057ba26a1f7014f2c2d9 +R c2c5a501f3f294cbca1bcb47eb806551 U dan -Z a169087f5f6ea34184b5d5b4868830f7 +Z c7ab4f2784fbdfc318b000ddf7671e24 diff --git a/manifest.uuid b/manifest.uuid index c388e5763a..31da46d10b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4d8537eafb40e3687abc057ba26a1f7014f2c2d9 \ No newline at end of file +bfc8bd80f8b225cebc66478448510ce84223ae7d \ No newline at end of file From e8fa8c9649b16bd8d0f7acdfd92d4762d07e004e Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 27 Sep 2014 16:33:09 +0000 Subject: [PATCH 0126/1484] Fix a segfault in the streaming API functions triggered by a very long table name. FossilOrigin-Name: d2642543eed54da1ac0f757d43dd4d72482eb752 --- ext/session/session1.test | 26 ++++++++++ ext/session/sessionfault.test | 38 ++++++++++++++- ext/session/sqlite3session.c | 92 ++++++++++++++++------------------- ext/session/test_session.c | 17 +++++-- manifest | 18 +++---- manifest.uuid | 2 +- 6 files changed, 127 insertions(+), 66 deletions(-) diff --git a/ext/session/session1.test b/ext/session/session1.test index e6f9c8fd7f..1c853a97a1 100644 --- a/ext/session/session1.test +++ b/ext/session/session1.test @@ -524,4 +524,30 @@ do_test 9.2 { do_changeset_test 9.2 S {{UPDATE t7 0 ....X.. {{} {} i 1 {} {} i 1 i 1 {} {} {} {}} {{} {} i 2 {} {} i 2 {} {} {} {} {} {}}}} S delete catch { db2 close } + +#------------------------------------------------------------------------- +# Test a really long table name. +# +reset_db +set tblname [string repeat tblname123 100] +do_test 10.1.1 { + execsql " + CREATE TABLE $tblname (a PRIMARY KEY, b); + INSERT INTO $tblname VALUES('xyz', 'def'); + " + sqlite3session S db main + S attach $tblname + execsql " + INSERT INTO $tblname VALUES('uvw', 'abc'); + DELETE FROM $tblname WHERE a = 'xyz'; + " +} {} +breakpoint +do_changeset_test 10.1.2 S " + {INSERT $tblname 0 X. {} {t uvw t abc}} + {DELETE $tblname 0 X. {t xyz t def} {}} +" +do_test 10.1.4 { S delete } {} + + finish_test diff --git a/ext/session/sessionfault.test b/ext/session/sessionfault.test index 4b278098a9..c94589e372 100644 --- a/ext/session/sessionfault.test +++ b/ext/session/sessionfault.test @@ -30,7 +30,6 @@ do_common_sql { faultsim_save_and_close db2 close - #------------------------------------------------------------------------- # Test OOM error handling when collecting and applying a simple changeset. # @@ -234,7 +233,7 @@ set changeset [changeset_from_sql { }] db close -do_faultsim_test 5 -faults oom* -body { +do_faultsim_test 5.1 -faults oom* -body { set ::inverse [sqlite3changeset_invert $::changeset] set {} {} } -test { @@ -251,6 +250,41 @@ do_faultsim_test 5 -faults oom* -body { } } +catch {db close} +catch {db2 close} +forcedelete test.db +sqlite3 db test.db +execsql { + CREATE TABLE t2(a PRIMARY KEY, b); + INSERT INTO t2 VALUES(1, 'abc'); + INSERT INTO t2 VALUES(2, 'def'); +} +set changeset [changeset_from_sql { + UPDATE t2 SET b = (b || b || b || b); + UPDATE t2 SET b = (b || b || b || b); + UPDATE t2 SET b = (b || b || b || b); + UPDATE t2 SET b = (b || b || b || b); +}] +db close +set abc [string repeat abc 256] +set def [string repeat def 256] + +do_faultsim_test 5.2 -faults oom-tra* -body { + set ::inverse [sqlite3changeset_invert $::changeset] + set {} {} +} -test { + faultsim_test_result {0 {}} {1 SQLITE_NOMEM} + if {$testrc==0} { + set x [list] + sqlite3session_foreach c $::inverse { lappend x $c } + foreach c " + {UPDATE t2 0 X. {i 1 t $::abc} {{} {} t abc}} + {UPDATE t2 0 X. {i 2 t $::def} {{} {} t def}} + " { lappend y $c } + if {$x != $y} { error "changeset no good" } + } +} + #------------------------------------------------------------------------- # Test that OOM errors in sqlite3changeset_concat() are handled correctly. # diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index eb1ff1e774..7e69be4cc4 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -18,7 +18,7 @@ typedef struct SessionInput SessionInput; ** Minimum chunk size used by streaming versions of functions. */ #ifdef SQLITE_TEST -#define SESSIONS_STR_CHUNK_SIZE 1 +#define SESSIONS_STR_CHUNK_SIZE 64 #else #define SESSIONS_STR_CHUNK_SIZE 1024 #endif @@ -1347,7 +1347,7 @@ static void sessionAppendValue(SessionBuffer *p, sqlite3_value *pVal, int *pRc){ int rc = *pRc; if( rc==SQLITE_OK ){ int nByte = 0; - sessionSerializeValue(0, pVal, &nByte); + rc = sessionSerializeValue(0, pVal, &nByte); sessionBufferGrow(p, nByte, &rc); if( rc==SQLITE_OK ){ rc = sessionSerializeValue(&p->aBuf[p->nBuf], pVal, 0); @@ -2225,12 +2225,10 @@ static int sessionReadRecord( eType = pIn->aData[pIn->iNext++]; } - assert( !apOut || apOut[i]==0 ); + assert( apOut[i]==0 ); if( eType ){ - if( apOut ){ - apOut[i] = sqlite3ValueNew(0); - if( !apOut[i] ) rc = SQLITE_NOMEM; - } + apOut[i] = sqlite3ValueNew(0); + if( !apOut[i] ) rc = SQLITE_NOMEM; } if( rc==SQLITE_OK ){ @@ -2239,22 +2237,20 @@ static int sessionReadRecord( int nByte; pIn->iNext += sessionVarintGet(aVal, &nByte); rc = sessionInputBuffer(pIn, nByte); - if( apOut && rc==SQLITE_OK ){ + if( rc==SQLITE_OK ){ u8 enc = (eType==SQLITE_TEXT ? SQLITE_UTF8 : 0); rc = sessionValueSetStr(apOut[i],&pIn->aData[pIn->iNext],nByte,enc); } pIn->iNext += nByte; } if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){ - if( apOut ){ - sqlite3_int64 v = sessionGetI64(aVal); - if( eType==SQLITE_INTEGER ){ - sqlite3VdbeMemSetInt64(apOut[i], v); - }else{ - double d; - memcpy(&d, &v, 8); - sqlite3VdbeMemSetDouble(apOut[i], d); - } + sqlite3_int64 v = sessionGetI64(aVal); + if( eType==SQLITE_INTEGER ){ + sqlite3VdbeMemSetInt64(apOut[i], v); + }else{ + double d; + memcpy(&d, &v, 8); + sqlite3VdbeMemSetDouble(apOut[i], d); } pIn->iNext += 8; } @@ -2293,10 +2289,10 @@ static int sessionChangesetBufferTblhdr(SessionInput *pIn, int *pnByte){ while( (pIn->iNext + nRead)nData && pIn->aData[pIn->iNext + nRead] ){ nRead++; } - if( pIn->aData[pIn->iNext + nRead]==0 ) break; + if( (pIn->iNext + nRead)nData ) break; rc = sessionInputBuffer(pIn, nRead + 100); } - if( pnByte ) *pnByte = nRead+1; + *pnByte = nRead+1; return rc; } @@ -2775,7 +2771,7 @@ static int sessionChangesetInvert( /* Write the new old.* record. Consists of the PK columns from the ** original old.* record, and the other values from the original ** new.* record. */ - for(iCol=0; rc==SQLITE_OK && iColpNext){ - int i; - if( pTab->nEntry==0 ) continue; + for(pTab=pList; rc==SQLITE_OK && pTab; pTab=pTab->pNext){ + int i; + if( pTab->nEntry==0 ) continue; - sessionAppendTableHdr(&buf, bPatch, pTab, &rc); - for(i=0; inChange; i++){ - SessionChange *p; - for(p=pTab->apChange[i]; p; p=p->pNext){ - sessionAppendByte(&buf, p->op, &rc); - sessionAppendByte(&buf, p->bIndirect, &rc); - sessionAppendBlob(&buf, p->aRecord, p->nRecord, &rc); - } - } - - if( rc==SQLITE_OK && xOutput && buf.nBuf>=SESSIONS_STR_CHUNK_SIZE ){ - rc = xOutput(pOut, buf.aBuf, buf.nBuf); - buf.nBuf = 0; + sessionAppendTableHdr(&buf, bPatch, pTab, &rc); + for(i=0; inChange; i++){ + SessionChange *p; + for(p=pTab->apChange[i]; p; p=p->pNext){ + sessionAppendByte(&buf, p->op, &rc); + sessionAppendByte(&buf, p->bIndirect, &rc); + sessionAppendBlob(&buf, p->aRecord, p->nRecord, &rc); } } - if( rc==SQLITE_OK ){ - if( xOutput ){ - if( buf.nBuf>0 ) rc = xOutput(pOut, buf.aBuf, buf.nBuf); - }else{ - *ppOut = buf.aBuf; - *pnOut = buf.nBuf; - buf.aBuf = 0; - } + if( rc==SQLITE_OK && xOutput && buf.nBuf>=SESSIONS_STR_CHUNK_SIZE ){ + rc = xOutput(pOut, buf.aBuf, buf.nBuf); + buf.nBuf = 0; } - sqlite3_free(buf.aBuf); } + if( rc==SQLITE_OK ){ + if( xOutput ){ + if( buf.nBuf>0 ) rc = xOutput(pOut, buf.aBuf, buf.nBuf); + }else{ + *ppOut = buf.aBuf; + *pnOut = buf.nBuf; + buf.aBuf = 0; + } + } + sqlite3_free(buf.aBuf); + sessionDeleteTable(pList); return rc; } diff --git a/ext/session/test_session.c b/ext/session/test_session.c index df690d44ad..7e366ef3bb 100644 --- a/ext/session/test_session.c +++ b/ext/session/test_session.c @@ -75,7 +75,7 @@ struct TestSessionsBlob { }; typedef struct TestSessionsBlob TestSessionsBlob; -static int testSessionsOutput( +static int testStreamOutput( void *pCtx, const void *pData, int nData @@ -160,9 +160,9 @@ static int test_session_cmd( if( test_tcl_integer(interp, SESSION_STREAM_TCL_VAR) ){ void *pCtx = (void*)&o; if( iSub==7 ){ - rc = sqlite3session_patchset_str(pSession, testSessionsOutput, pCtx); + rc = sqlite3session_patchset_str(pSession, testStreamOutput, pCtx); }else{ - rc = sqlite3session_changeset_str(pSession, testSessionsOutput, pCtx); + rc = sqlite3session_changeset_str(pSession, testStreamOutput, pCtx); } }else{ if( iSub==7 ){ @@ -562,6 +562,13 @@ static int testStreamInput( int nRem = p->nData - p->iData; /* Bytes of data available */ int nRet = p->nStream; /* Bytes actually returned */ + /* Allocate and free some space. There is no point to this, other than + ** that it allows the regular OOM fault-injection tests to cause an error + ** in this function. */ + void *pAlloc = sqlite3_malloc(10); + if( pAlloc==0 ) return SQLITE_NOMEM; + sqlite3_free(pAlloc); + if( nRet>nReq ) nRet = nReq; if( nRet>nRem ) nRet = nRem; @@ -691,7 +698,7 @@ static int test_sqlite3changeset_invert( if( sIn.nStream ){ rc = sqlite3changeset_invert_str( - testStreamInput, (void*)&sIn, testSessionsOutput, (void*)&sOut + testStreamInput, (void*)&sIn, testStreamOutput, (void*)&sOut ); }else{ rc = sqlite3changeset_invert(sIn.nData, sIn.aData, &sOut.n, &sOut.p); @@ -736,7 +743,7 @@ static int test_sqlite3changeset_concat( rc = sqlite3changeset_concat_str( testStreamInput, (void*)&sLeft, testStreamInput, (void*)&sRight, - testSessionsOutput, (void*)&sOut + testStreamOutput, (void*)&sOut ); }else{ rc = sqlite3changeset_concat( diff --git a/manifest b/manifest index 258fb598ba..4cb1bee75c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improve\ssessions\smodule\sdocumentation\sand\scomments.\sFix\ssome\sother\scode\sissues. -D 2014-09-27T12:26:18.848 +C Fix\sa\ssegfault\sin\sthe\sstreaming\sAPI\sfunctions\striggered\sby\sa\svery\slong\stable\sname. +D 2014-09-27T16:33:09.345 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in dd5f245aa8c741bc65845747203c8ce2f3fb6c83 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -146,7 +146,7 @@ F ext/rtree/sqlite3rtree.h 83349d519fe5f518b3ea025d18dd1fe51b1684bd F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 F ext/session/changeset.c 4ccbaa4531944c24584bf6a61ba3a39c62b6267a -F ext/session/session1.test 3733d71eb9a99b14d51fa5219d5b8a82407c3be8 +F ext/session/session1.test 4653867f32a98ce4bbb4a181aac6debe51ca4dfb F ext/session/session2.test 99ca0da7ddb617d42bafd83adccf99f18ae0384b F ext/session/session3.test a7a9ce59b8d1e49e2cc23d81421ac485be0eea01 F ext/session/session4.test a6ed685da7a5293c5d6f99855bcf41dbc352ca84 @@ -157,10 +157,10 @@ F ext/session/session9.test 776e46785c29c11cda01f5205d0f1e8f8f9a46bf F ext/session/sessionA.test eb05c13e4ef1ca8046a3a6dbf2d5f6f5b04a11d4 F ext/session/sessionB.test d4ac901b43d4922a17dff08bbaa2f5354487ce4d F ext/session/session_common.tcl 1539d8973b2aea0025c133eb0cc4c89fcef541a5 -F ext/session/sessionfault.test e7965159a73d385c1a4af12d82c3a039ebdd71a6 -F ext/session/sqlite3session.c 9ce77f4752cd5d8982e7b64f665ae66754dda723 +F ext/session/sessionfault.test cf9758bfb6ccd5db5f09f170667a8cea1ac8afa7 +F ext/session/sqlite3session.c 228cca8fdb6fd07942be097c516f22e39ec39e3c F ext/session/sqlite3session.h b57009fb88835cc4684376bd3eae0d6ab364968a -F ext/session/test_session.c 194083ee1f0f6f38404f662fe9b50849abd3b7ee +F ext/session/test_session.c 56a4ddd443b571c8d365b03197c032bdaed1443a F ext/userauth/sqlite3userauth.h 19cb6f0e31316d0ee4afdfb7a85ef9da3333a220 F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04 F ext/userauth/userauth.c 5fa3bdb492f481bbc1709fc83c91ebd13460c69e @@ -1216,7 +1216,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 4d8537eafb40e3687abc057ba26a1f7014f2c2d9 -R c2c5a501f3f294cbca1bcb47eb806551 +P bfc8bd80f8b225cebc66478448510ce84223ae7d +R 9ca53892e63f9c31475266a6b3e34d34 U dan -Z c7ab4f2784fbdfc318b000ddf7671e24 +Z f7759b84adfee5a6c178fa61db492ce5 diff --git a/manifest.uuid b/manifest.uuid index 31da46d10b..903686ec1f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bfc8bd80f8b225cebc66478448510ce84223ae7d \ No newline at end of file +d2642543eed54da1ac0f757d43dd4d72482eb752 \ No newline at end of file From f05ac11214c082d4a849742f3e5c6246c4bf5106 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 27 Sep 2014 18:18:32 +0000 Subject: [PATCH 0127/1484] Fix a segfault in the sessions module that could follow an OOM. FossilOrigin-Name: 09985fa6b60a0bf38e23bbccd4d8e1d1cbf66124 --- ext/session/session9.test | 34 ++++++++++++++++++ ext/session/sessionA.test | 43 +++++++++++++++++++++-- ext/session/sessionfault.test | 66 +++++++++++++++++++++++++++++++++++ ext/session/sqlite3session.c | 4 +++ manifest | 18 +++++----- manifest.uuid | 2 +- 6 files changed, 155 insertions(+), 12 deletions(-) diff --git a/ext/session/session9.test b/ext/session/session9.test index 3b42c31061..a9f61c872f 100644 --- a/ext/session/session9.test +++ b/ext/session/session9.test @@ -200,6 +200,7 @@ do_test 3.3 { do_test 3.3.1 { list [catch {sqlite3changeset_apply db $::ccdel1 conflict_handler} msg] $msg } {1 SQLITE_CONSTRAINT} + do_test 3.3.2 { list [catch {sqlite3changeset_apply db $::ccdel2 conflict_handler} msg] $msg } {1 SQLITE_CONSTRAINT} @@ -251,4 +252,37 @@ do_catchsql_test 4.3.2 { do_catchsql_test 4.3.3 { COMMIT } {0 {}} do_catchsql_test 4.3.4 { BEGIN ; COMMIT } {0 {}} +#-------------------------------------------------------------------- +# Test that if a DELETE change cannot be applied due to an +# SQLITE_CONSTRAINT error thrown by a trigger program, things do not +# go awry. + +drop_all_tables +reset_db +do_execsql_test 5.1 { + CREATE TABLE x1(x PRIMARY KEY, y); + CREATE TABLE x2(x PRIMARY KEY, y); + INSERT INTO x2 VALUES(1, 1); + INSERT INTO x1 VALUES(1, 1); +} + +set ::cc [changeset_from_sql { DELETE FROM x1; }] + +do_execsql_test 5.2 { + INSERT INTO x1 VALUES(1, 1); + CREATE TRIGGER tr1 AFTER DELETE ON x1 BEGIN + INSERT INTO x2 VALUES(old.x, old.y); + END; +} {} + +proc conflict_handler {args} { return "ABORT" } +do_test 5.3 { + list [catch {sqlite3changeset_apply db $::cc conflict_handler} msg] $msg +} {1 SQLITE_ABORT} + +do_execsql_test 5.4 { + SELECT * FROM X1; +} {1 1} + finish_test + diff --git a/ext/session/sessionA.test b/ext/session/sessionA.test index 1ca0f13709..8ee2046519 100644 --- a/ext/session/sessionA.test +++ b/ext/session/sessionA.test @@ -9,8 +9,7 @@ # #*********************************************************************** # -# This file tests that the sessions module handles foreign key constraint -# violations when applying changesets as required. +# This file tests that filter callbacks work as required. # if {![info exists testdir]} { @@ -63,6 +62,46 @@ do_test 2.1 { } db2 } {a b e f} +#------------------------------------------------------------------------- +# Test that filter callbacks passed to sqlite3changeset_apply() are +# invoked correctly. +# +reset_db +do_execsql_test 3.1 { + CREATE TABLE t1(a PRIMARY KEY, b); + CREATE TABLE t2(x PRIMARY KEY, y); +} + +do_test 3.2 { + execsql BEGIN + set ::cs [changeset_from_sql { + INSERT INTO t1 VALUES(1, 2); + INSERT INTO t2 VALUES('x', 'y'); + }] + execsql ROLLBACK + set {} {} +} {} + +proc filter {x y} { + return [string equal $x $y] +} + +do_test 3.3 { + sqlite3changeset_apply db $::cs {} [list filter t1] + execsql { + SELECT * FROM t1; + SELECT * FROM t2; + } +} {1 2} + +do_test 3.4 { + execsql { DELETE FROM t1 } + sqlite3changeset_apply db $::cs {} [list filter t2] + execsql { + SELECT * FROM t1; + SELECT * FROM t2; + } +} {x y} finish_test diff --git a/ext/session/sessionfault.test b/ext/session/sessionfault.test index c94589e372..39f27bfe6d 100644 --- a/ext/session/sessionfault.test +++ b/ext/session/sessionfault.test @@ -285,6 +285,38 @@ do_faultsim_test 5.2 -faults oom-tra* -body { } } +catch {db close} +catch {db2 close} +forcedelete test.db +sqlite3 db test.db +set abc [string repeat abc 256] +set def [string repeat def 256] +execsql " + CREATE TABLE t2(a PRIMARY KEY, b); + INSERT INTO t2 VALUES(1, '$abc'); +" +set changeset [changeset_from_sql " + INSERT INTO t2 VALUES(2, '$def'); + DELETE FROM t2 WHERE a = 1; +"] +db close + +do_faultsim_test 5.3 -faults oom-tra* -body { + set ::inverse [sqlite3changeset_invert $::changeset] + set {} {} +} -test { + faultsim_test_result {0 {}} {1 SQLITE_NOMEM} + if {$testrc==0} { + set x [list] + sqlite3session_foreach c $::inverse { lappend x $c } + foreach c " + {INSERT t2 0 X. {} {i 1 t $::abc}} + {DELETE t2 0 X. {i 2 t $::def} {}} + " { lappend y $c } + if {$x != $y} { error "changeset no good" } + } +} + #------------------------------------------------------------------------- # Test that OOM errors in sqlite3changeset_concat() are handled correctly. # @@ -515,7 +547,41 @@ do_faultsim_test 10 -faults oom-tra* -prep { } } +#------------------------------------------------------------------------- +# Test an OOM with an sqlite3changeset_apply() filter callback. +# +reset_db +do_test 11.prep { + execsql { + CREATE TABLE t1(a PRIMARY KEY, b); + CREATE TABLE t2(x PRIMARY KEY, y); + BEGIN; + } + set ::cs [changeset_from_sql { + INSERT INTO t1 VALUES(1, 2); + INSERT INTO t2 VALUES('x', 'y'); + }] + + execsql ROLLBACK + set {} {} +} {} + +proc filter {x} { return [string equal t1 $x] } +faultsim_save_and_close + +do_faultsim_test 11 -faults oom-tra* -prep { + faultsim_restore_and_reopen +} -body { + sqlite3changeset_apply db $::cs {} filter +} -test { + faultsim_test_result {0 {}} {1 SQLITE_NOMEM} + if {$testrc==0} { + if {[db eval {SELECT * FROM t1 UNION ALL SELECT * FROM t2}] != "1 2"} { + error "data does not look right" + } + } +} finish_test diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index 7e69be4cc4..ed8d851083 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -3495,6 +3495,10 @@ static int sessionChangesetApply( schemaMismatch = (xFilter && (0==xFilter(pCtx, zNew))); if( schemaMismatch ){ zTab = sqlite3_mprintf("%s", zNew); + if( zTab==0 ){ + rc = SQLITE_NOMEM; + break; + } nTab = (int)strlen(zTab); sApply.azCol = (const char **)zTab; }else{ diff --git a/manifest b/manifest index 4cb1bee75c..0d58beec13 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\ssegfault\sin\sthe\sstreaming\sAPI\sfunctions\striggered\sby\sa\svery\slong\stable\sname. -D 2014-09-27T16:33:09.345 +C Fix\sa\ssegfault\sin\sthe\ssessions\smodule\sthat\scould\sfollow\san\sOOM. +D 2014-09-27T18:18:32.969 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in dd5f245aa8c741bc65845747203c8ce2f3fb6c83 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -153,12 +153,12 @@ F ext/session/session4.test a6ed685da7a5293c5d6f99855bcf41dbc352ca84 F ext/session/session5.test 8fdfaf9dba28a2f1c6b89b06168bdab1fef2d478 F ext/session/session6.test 443789bc2fca12e4f7075cf692c60b8a2bea1a26 F ext/session/session8.test 7d35947ad329b8966f095d34f9617a9eff52dc65 -F ext/session/session9.test 776e46785c29c11cda01f5205d0f1e8f8f9a46bf -F ext/session/sessionA.test eb05c13e4ef1ca8046a3a6dbf2d5f6f5b04a11d4 +F ext/session/session9.test b6dd1086de8c59b6f129923425487791f51c689c +F ext/session/sessionA.test 5543846eb9ca045217262f5d8c9376ce812e1ba5 F ext/session/sessionB.test d4ac901b43d4922a17dff08bbaa2f5354487ce4d F ext/session/session_common.tcl 1539d8973b2aea0025c133eb0cc4c89fcef541a5 -F ext/session/sessionfault.test cf9758bfb6ccd5db5f09f170667a8cea1ac8afa7 -F ext/session/sqlite3session.c 228cca8fdb6fd07942be097c516f22e39ec39e3c +F ext/session/sessionfault.test bef044d0952c0d62c31c8d2400be72c8684545cc +F ext/session/sqlite3session.c 0691b8d7434edb07166828778540bb418a7a68e3 F ext/session/sqlite3session.h b57009fb88835cc4684376bd3eae0d6ab364968a F ext/session/test_session.c 56a4ddd443b571c8d365b03197c032bdaed1443a F ext/userauth/sqlite3userauth.h 19cb6f0e31316d0ee4afdfb7a85ef9da3333a220 @@ -1216,7 +1216,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P bfc8bd80f8b225cebc66478448510ce84223ae7d -R 9ca53892e63f9c31475266a6b3e34d34 +P d2642543eed54da1ac0f757d43dd4d72482eb752 +R 7328e4de54076fa7989cf4f3b00a08d8 U dan -Z f7759b84adfee5a6c178fa61db492ce5 +Z 371024a806f6988dfc33105901bfbbae diff --git a/manifest.uuid b/manifest.uuid index 903686ec1f..d5a74ccbec 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d2642543eed54da1ac0f757d43dd4d72482eb752 \ No newline at end of file +09985fa6b60a0bf38e23bbccd4d8e1d1cbf66124 \ No newline at end of file From f1a08ad88ded911534463a7ffa2c298612452f7f Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 27 Sep 2014 20:45:48 +0000 Subject: [PATCH 0128/1484] Change the names of the stream interface APIs to be of the form "_strm" instead of "_str". In other words, added an "m" to the end, to try to make it clear that we are talking about a "stream" and not a "string. FossilOrigin-Name: 1f44bfdc237ee6304f4aa56e5c5d1c0d74fcc944 --- ext/session/session5.test | 1 - ext/session/session8.test | 1 - ext/session/session9.test | 1 - ext/session/sessionA.test | 2 -- ext/session/sessionB.test | 1 - ext/session/session_common.tcl | 1 - ext/session/sqlite3session.c | 44 ++++++++++++++++++---------------- ext/session/sqlite3session.h | 16 ++++++------- ext/session/test_session.c | 12 +++++----- manifest | 32 ++++++++++++------------- manifest.uuid | 2 +- test/permutations.test | 2 +- test/session.test | 2 +- 13 files changed, 56 insertions(+), 61 deletions(-) diff --git a/ext/session/session5.test b/ext/session/session5.test index 88430057d0..9b8f9ffe12 100644 --- a/ext/session/session5.test +++ b/ext/session/session5.test @@ -406,4 +406,3 @@ do_concat_test2 4.4 { } finish_test - diff --git a/ext/session/session8.test b/ext/session/session8.test index 93bd4e06c3..9f70fe2829 100644 --- a/ext/session/session8.test +++ b/ext/session/session8.test @@ -89,4 +89,3 @@ do_then_undo 3.2 { UPDATE t3 SET b=b||b WHERE e!='x' } do_then_undo 3.3 { UPDATE t3 SET a = 46 } finish_test - diff --git a/ext/session/session9.test b/ext/session/session9.test index a9f61c872f..ebb88ffade 100644 --- a/ext/session/session9.test +++ b/ext/session/session9.test @@ -285,4 +285,3 @@ do_execsql_test 5.4 { } {1 1} finish_test - diff --git a/ext/session/sessionA.test b/ext/session/sessionA.test index 8ee2046519..0e0a14e38a 100644 --- a/ext/session/sessionA.test +++ b/ext/session/sessionA.test @@ -104,5 +104,3 @@ do_test 3.4 { } {x y} finish_test - - diff --git a/ext/session/sessionB.test b/ext/session/sessionB.test index b11c3110a1..f1af5d213c 100644 --- a/ext/session/sessionB.test +++ b/ext/session/sessionB.test @@ -516,4 +516,3 @@ do_patchset_changeset_test 5.3 \ finish_test - diff --git a/ext/session/session_common.tcl b/ext/session/session_common.tcl index 53870c4027..d6ce27a850 100644 --- a/ext/session/session_common.tcl +++ b/ext/session/session_common.tcl @@ -133,4 +133,3 @@ proc changeset_to_list {c} { sqlite3session_foreach elem $c { lappend list $elem } lsort $list } - diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index ed8d851083..fe7d6e5a21 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -17,10 +17,12 @@ typedef struct SessionInput SessionInput; /* ** Minimum chunk size used by streaming versions of functions. */ -#ifdef SQLITE_TEST -#define SESSIONS_STR_CHUNK_SIZE 64 -#else -#define SESSIONS_STR_CHUNK_SIZE 1024 +#ifndef SESSIONS_STRM_CHUNK_SIZE +# ifdef SQLITE_TEST +# define SESSIONS_STRM_CHUNK_SIZE 64 +# else +# define SESSIONS_STRM_CHUNK_SIZE 1024 +# endif #endif /* @@ -52,7 +54,7 @@ struct SessionBuffer { ** An object of this type is used internally as an abstraction for ** input data. Input data may be supplied either as a single large buffer ** (e.g. sqlite3changeset_start()) or using a stream function (e.g. -** sqlite3changeset_start_str()). +** sqlite3changeset_start_strm()). */ struct SessionInput { int iNext; /* Offset in aData[] of next change */ @@ -1907,12 +1909,12 @@ int sessionGenerateChangeset( rc = sqlite3_reset(pSel); } - /* If the buffer is now larger than SESSIONS_STR_CHUNK_SIZE, pass + /* If the buffer is now larger than SESSIONS_STRM_CHUNK_SIZE, pass ** its contents to the xOutput() callback. */ if( xOutput && rc==SQLITE_OK && buf.nBuf>nNoop - && buf.nBuf>SESSIONS_STR_CHUNK_SIZE + && buf.nBuf>SESSIONS_STRM_CHUNK_SIZE ){ rc = xOutput(pOut, (void*)buf.aBuf, buf.nBuf); nNoop = -1; @@ -1964,7 +1966,7 @@ int sqlite3session_changeset( /* ** Streaming version of sqlite3session_changeset(). */ -int sqlite3session_changeset_str( +int sqlite3session_changeset_strm( sqlite3_session *pSession, int (*xOutput)(void *pOut, const void *pData, int nData), void *pOut @@ -1975,7 +1977,7 @@ int sqlite3session_changeset_str( /* ** Streaming version of sqlite3session_patchset(). */ -int sqlite3session_patchset_str( +int sqlite3session_patchset_strm( sqlite3_session *pSession, int (*xOutput)(void *pOut, const void *pData, int nData), void *pOut @@ -2044,7 +2046,7 @@ int sqlite3session_isempty(sqlite3_session *pSession){ } /* -** Do the work for either sqlite3changeset_start() or start_str(). +** Do the work for either sqlite3changeset_start() or start_strm(). */ int sessionChangesetStart( sqlite3_changeset_iter **pp, /* OUT: Changeset iterator handle */ @@ -2092,7 +2094,7 @@ int sqlite3changeset_start( /* ** Streaming version of sqlite3changeset_start(). */ -int sqlite3changeset_start_str( +int sqlite3changeset_start_strm( sqlite3_changeset_iter **pp, /* OUT: Changeset iterator handle */ int (*xInput)(void *pIn, void *pData, int *pnData), void *pIn @@ -2111,9 +2113,9 @@ static int sessionInputBuffer(SessionInput *pIn, int nByte){ int rc = SQLITE_OK; if( pIn->xInput ){ while( !pIn->bEof && (pIn->iNext+nByte)>=pIn->nData && rc==SQLITE_OK ){ - int nNew = SESSIONS_STR_CHUNK_SIZE; + int nNew = SESSIONS_STRM_CHUNK_SIZE; - if( pIn->iNext>=SESSIONS_STR_CHUNK_SIZE ){ + if( pIn->iNext>=SESSIONS_STRM_CHUNK_SIZE ){ int nMove = pIn->buf.nBuf - pIn->iNext; memmove(pIn->buf.aBuf, &pIn->buf.aBuf[pIn->iNext], nMove); pIn->buf.nBuf -= pIn->iNext; @@ -2801,7 +2803,7 @@ static int sessionChangesetInvert( } assert( rc==SQLITE_OK ); - if( xOutput && sOut.nBuf>=SESSIONS_STR_CHUNK_SIZE ){ + if( xOutput && sOut.nBuf>=SESSIONS_STRM_CHUNK_SIZE ){ rc = xOutput(pOut, sOut.aBuf, sOut.nBuf); sOut.nBuf = 0; if( rc!=SQLITE_OK ) goto finished_invert; @@ -2847,7 +2849,7 @@ int sqlite3changeset_invert( /* ** Streaming version of sqlite3changeset_invert(). */ -int sqlite3changeset_invert_str( +int sqlite3changeset_invert_strm( int (*xInput)(void *pIn, void *pData, int *pnData), void *pIn, int (*xOutput)(void *pOut, const void *pData, int nData), @@ -3641,7 +3643,7 @@ int sqlite3changeset_apply( ** attached to handle "db". Invoke the supplied conflict handler callback ** to resolve any conflicts encountered while applying the change. */ -int sqlite3changeset_apply_str( +int sqlite3changeset_apply_strm( sqlite3 *db, /* Apply change to "main" db of this handle */ int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */ void *pIn, /* First arg for xInput */ @@ -3657,7 +3659,7 @@ int sqlite3changeset_apply_str( void *pCtx /* First argument passed to xConflict */ ){ sqlite3_changeset_iter *pIter; /* Iterator to skip through changeset */ - int rc = sqlite3changeset_start_str(&pIter, xInput, pIn); + int rc = sqlite3changeset_start_strm(&pIter, xInput, pIn); if( rc==SQLITE_OK ){ rc = sessionChangesetApply(db, pIter, xFilter, xConflict, pCtx); } @@ -3932,7 +3934,7 @@ int sessionChangesetConcat( } } - if( rc==SQLITE_OK && xOutput && buf.nBuf>=SESSIONS_STR_CHUNK_SIZE ){ + if( rc==SQLITE_OK && xOutput && buf.nBuf>=SESSIONS_STRM_CHUNK_SIZE ){ rc = xOutput(pOut, buf.aBuf, buf.nBuf); buf.nBuf = 0; } @@ -3986,7 +3988,7 @@ int sqlite3changeset_concat( /* ** Streaming version of sqlite3changeset_concat(). */ -int sqlite3changeset_concat_str( +int sqlite3changeset_concat_strm( int (*xInputA)(void *pIn, void *pData, int *pnData), void *pInA, int (*xInputB)(void *pIn, void *pData, int *pnData), @@ -3998,9 +4000,9 @@ int sqlite3changeset_concat_str( sqlite3_changeset_iter *pIter2 = 0; int rc; - rc = sqlite3changeset_start_str(&pIter1, xInputA, pInA); + rc = sqlite3changeset_start_strm(&pIter1, xInputA, pInA); if( rc==SQLITE_OK ){ - rc = sqlite3changeset_start_str(&pIter2, xInputB, pInB); + rc = sqlite3changeset_start_strm(&pIter2, xInputB, pInB); } if( rc==SQLITE_OK ){ rc = sessionChangesetConcat(pIter1, pIter2, xOutput, pOut, 0, 0); diff --git a/ext/session/sqlite3session.h b/ext/session/sqlite3session.h index 0dd03067ed..e768d66324 100644 --- a/ext/session/sqlite3session.h +++ b/ext/session/sqlite3session.h @@ -946,7 +946,7 @@ int sqlite3changeset_apply( /* ** CAPI3REF: Streaming Versions of API functions. ** -** The six streaming API xxx_str() functions serve similar purposes to the +** The six streaming API xxx_strm() functions serve similar purposes to the ** corresponding non-streaming API functions: ** ** @@ -995,7 +995,7 @@ int sqlite3changeset_apply( ** an error, all processing is abandoned and the streaming API function ** returns a copy of the error code to the caller. ** -** In the case of sqlite3changeset_start_str(), the xInput callback may be +** In the case of sqlite3changeset_start_strm(), the xInput callback may be ** invoked by the sessions module at any point during the lifetime of the ** iterator. If such an xInput callback returns an error, the iterator enters ** an error state, whereby all subsequent calls to iterator functions @@ -1032,7 +1032,7 @@ int sqlite3changeset_apply( ** parameter set to a value less than or equal to zero. Other than this, ** no guarantees are made as to the size of the chunks of data returned. */ -int sqlite3changeset_apply_str( +int sqlite3changeset_apply_strm( sqlite3 *db, /* Apply change to "main" db of this handle */ int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */ void *pIn, /* First arg for xInput */ @@ -1047,7 +1047,7 @@ int sqlite3changeset_apply_str( ), void *pCtx /* First argument passed to xConflict */ ); -int sqlite3changeset_concat_str( +int sqlite3changeset_concat_strm( int (*xInputA)(void *pIn, void *pData, int *pnData), void *pInA, int (*xInputB)(void *pIn, void *pData, int *pnData), @@ -1055,23 +1055,23 @@ int sqlite3changeset_concat_str( int (*xOutput)(void *pOut, const void *pData, int nData), void *pOut ); -int sqlite3changeset_invert_str( +int sqlite3changeset_invert_strm( int (*xInput)(void *pIn, void *pData, int *pnData), void *pIn, int (*xOutput)(void *pOut, const void *pData, int nData), void *pOut ); -int sqlite3changeset_start_str( +int sqlite3changeset_start_strm( sqlite3_changeset_iter **pp, int (*xInput)(void *pIn, void *pData, int *pnData), void *pIn ); -int sqlite3session_changeset_str( +int sqlite3session_changeset_strm( sqlite3_session *pSession, int (*xOutput)(void *pOut, const void *pData, int nData), void *pOut ); -int sqlite3session_patchset_str( +int sqlite3session_patchset_strm( sqlite3_session *pSession, int (*xOutput)(void *pOut, const void *pData, int nData), void *pOut diff --git a/ext/session/test_session.c b/ext/session/test_session.c index 7e366ef3bb..6c538bcec1 100644 --- a/ext/session/test_session.c +++ b/ext/session/test_session.c @@ -160,9 +160,9 @@ static int test_session_cmd( if( test_tcl_integer(interp, SESSION_STREAM_TCL_VAR) ){ void *pCtx = (void*)&o; if( iSub==7 ){ - rc = sqlite3session_patchset_str(pSession, testStreamOutput, pCtx); + rc = sqlite3session_patchset_strm(pSession, testStreamOutput, pCtx); }else{ - rc = sqlite3session_changeset_str(pSession, testStreamOutput, pCtx); + rc = sqlite3session_changeset_strm(pSession, testStreamOutput, pCtx); } }else{ if( iSub==7 ){ @@ -626,7 +626,7 @@ static int test_sqlite3changeset_apply( }else{ sStr.aData = (unsigned char*)pChangeset; sStr.nData = nChangeset; - rc = sqlite3changeset_apply_str(db, testStreamInput, (void*)&sStr, + rc = sqlite3changeset_apply_strm(db, testStreamInput, (void*)&sStr, (objc==5) ? test_filter_handler : 0, test_conflict_handler, (void *)&ctx ); } @@ -697,7 +697,7 @@ static int test_sqlite3changeset_invert( sIn.aData = Tcl_GetByteArrayFromObj(objv[1], &sIn.nData); if( sIn.nStream ){ - rc = sqlite3changeset_invert_str( + rc = sqlite3changeset_invert_strm( testStreamInput, (void*)&sIn, testStreamOutput, (void*)&sOut ); }else{ @@ -740,7 +740,7 @@ static int test_sqlite3changeset_concat( sRight.nStream = sLeft.nStream; if( sLeft.nStream>0 ){ - rc = sqlite3changeset_concat_str( + rc = sqlite3changeset_concat_strm( testStreamInput, (void*)&sLeft, testStreamInput, (void*)&sRight, testStreamOutput, (void*)&sOut @@ -801,7 +801,7 @@ static int test_sqlite3session_foreach( }else{ sStr.aData = (unsigned char*)pChangeset; sStr.nData = nChangeset; - rc = sqlite3changeset_start_str(&pIter, testStreamInput, (void*)&sStr); + rc = sqlite3changeset_start_strm(&pIter, testStreamInput, (void*)&sStr); } if( rc!=SQLITE_OK ){ return test_session_error(interp, rc); diff --git a/manifest b/manifest index da8cd912d5..36205b94dd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\srecent\strunk\schanges\s(performance\senhancements)\sinto\sthe\ssessions\nbranch. -D 2014-09-27T19:51:50.438 +C Change\sthe\snames\sof\sthe\sstream\sinterface\sAPIs\sto\sbe\sof\sthe\sform\n"_strm"\sinstead\sof\s"_str".\s\sIn\sother\swords,\sadded\san\s"m"\sto\sthe\send,\sto\ntry\sto\smake\sit\sclear\sthat\swe\sare\stalking\sabout\sa\s"stream"\sand\snot\sa\s"string. +D 2014-09-27T20:45:48.295 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in dd5f245aa8c741bc65845747203c8ce2f3fb6c83 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -150,17 +150,17 @@ F ext/session/session1.test 4653867f32a98ce4bbb4a181aac6debe51ca4dfb F ext/session/session2.test 99ca0da7ddb617d42bafd83adccf99f18ae0384b F ext/session/session3.test a7a9ce59b8d1e49e2cc23d81421ac485be0eea01 F ext/session/session4.test a6ed685da7a5293c5d6f99855bcf41dbc352ca84 -F ext/session/session5.test 8fdfaf9dba28a2f1c6b89b06168bdab1fef2d478 +F ext/session/session5.test 716bc6fafd625ce60dfa62ae128971628c1a1169 F ext/session/session6.test 443789bc2fca12e4f7075cf692c60b8a2bea1a26 -F ext/session/session8.test 7d35947ad329b8966f095d34f9617a9eff52dc65 -F ext/session/session9.test b6dd1086de8c59b6f129923425487791f51c689c -F ext/session/sessionA.test 5543846eb9ca045217262f5d8c9376ce812e1ba5 -F ext/session/sessionB.test d4ac901b43d4922a17dff08bbaa2f5354487ce4d -F ext/session/session_common.tcl 1539d8973b2aea0025c133eb0cc4c89fcef541a5 +F ext/session/session8.test 8e194b3f655d861ca36de5d4de53f702751bab3b +F ext/session/session9.test 5409d90d8141881d08285ed1c2c0d8d10fb92069 +F ext/session/sessionA.test 1feeab0b8e03527f08f2f1defb442da25480138f +F ext/session/sessionB.test 06961b7c3641151f5d23088250ecad132501113c +F ext/session/session_common.tcl 9de0451b6a47218fc16b9ed8876b6238a0a3d88d F ext/session/sessionfault.test bef044d0952c0d62c31c8d2400be72c8684545cc -F ext/session/sqlite3session.c 0691b8d7434edb07166828778540bb418a7a68e3 -F ext/session/sqlite3session.h b57009fb88835cc4684376bd3eae0d6ab364968a -F ext/session/test_session.c 56a4ddd443b571c8d365b03197c032bdaed1443a +F ext/session/sqlite3session.c 67b8aee718cf34e267f4040d9b945a7a6407b0b2 +F ext/session/sqlite3session.h 16608d29879a0ed3c6be6b7fb18dcdb5c707aaef +F ext/session/test_session.c a28352e99bc6a83b94e4cce99a7bf25c73d6d489 F ext/userauth/sqlite3userauth.h 19cb6f0e31316d0ee4afdfb7a85ef9da3333a220 F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04 F ext/userauth/userauth.c 5fa3bdb492f481bbc1709fc83c91ebd13460c69e @@ -777,7 +777,7 @@ F test/pagesize.test 1dd51367e752e742f58e861e65ed7390603827a0 F test/pcache.test b09104b03160aca0d968d99e8cd2c5b1921a993d F test/pcache2.test a83efe2dec0d392f814bfc998def1d1833942025 F test/percentile.test b98fc868d71eb5619d42a1702e9ab91718cbed54 -F test/permutations.test b8ca6c9ecec6f360485a8cb61ef1b8734b31797b +F test/permutations.test a33230010a3d4ce0c57d586672ccef10a7d1af29 F test/pragma.test 19d0241a007bcdd77fc2606ec60fc60357e7fc8b F test/pragma2.test aea7b3d82c76034a2df2b38a13745172ddc0bc13 F test/printf.test ec9870c4dce8686a37818e0bf1aba6e6a1863552 @@ -833,7 +833,7 @@ F test/selectD.test b0f02a04ef7737decb24e08be2c39b9664b43394 F test/selectE.test fc02a1eb04c8eb537091482644b7d778ae8759b7 F test/selectF.test 21c94e6438f76537b72532fa9fd4710cdd455fc3 F test/server1.test 46803bd3fe8b99b30dbc5ff38ffc756f5c13a118 -F test/session.test 35f9c76809c26bee45d86891c7620b692ef9b8a8 +F test/session.test 78fa2365e93d3663a6e933f86e7afc395adf18be F test/shared.test 1da9dbad400cee0d93f252ccf76e1ae007a63746 F test/shared2.test 03eb4a8d372e290107d34b6ce1809919a698e879 F test/shared3.test fcd65cb11d189eff5f5c85cc4fad246fb0933108 @@ -1217,7 +1217,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 09985fa6b60a0bf38e23bbccd4d8e1d1cbf66124 d026f0c944ce812732d3595eaa3c5d432a86c7dd -R 6b80dc3719dfaf6510fd0fc97f44558f +P 497367cb57345dd37793e5f369b34d12be56172e +R cc11bbbd763a56bfdd0667ee0dcdded3 U drh -Z 29718882bdf5b938c85c12503154fa25 +Z 9e5912d3733f34c1f4a27e9b30386e30 diff --git a/manifest.uuid b/manifest.uuid index 8ff815c08d..55c0eb0873 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -497367cb57345dd37793e5f369b34d12be56172e \ No newline at end of file +1f44bfdc237ee6304f4aa56e5c5d1c0d74fcc944 \ No newline at end of file diff --git a/test/permutations.test b/test/permutations.test index 44f571793c..5fd50cc2d5 100644 --- a/test/permutations.test +++ b/test/permutations.test @@ -938,7 +938,7 @@ test_suite "session_eec" -description { sqlite3_extended_result_codes $::dbhandle 1 } -test_suite "session_str" -description { +test_suite "session_strm" -description { All session module related tests using the streaming APIs. } -files [ glob -nocomplain $::testdir/../ext/session/*.test diff --git a/test/session.test b/test/session.test index da04ac45c5..4fd1ec0184 100644 --- a/test/session.test +++ b/test/session.test @@ -16,7 +16,7 @@ ifcapable session { # again with it clear. run_test_suite session_eec run_test_suite session - run_test_suite session_str + run_test_suite session_strm } finish_test From abae0c4f1d3b9ce7a9d6342b61ec000117df1d63 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 15 Oct 2014 20:02:21 +0000 Subject: [PATCH 0129/1484] Fix a problem causing sqlite3changeset_concat() to fail to detect attempts to concatenate patchsets which changesets. FossilOrigin-Name: 236704a9d1551a50a55bd6e0b6473191a7a7dd21 --- ext/session/sessionC.test | 190 +++++++++++++++++++++++++++++++++++ ext/session/sqlite3session.c | 6 ++ manifest | 13 +-- manifest.uuid | 2 +- 4 files changed, 204 insertions(+), 7 deletions(-) create mode 100644 ext/session/sessionC.test diff --git a/ext/session/sessionC.test b/ext/session/sessionC.test new file mode 100644 index 0000000000..81cc53f5a6 --- /dev/null +++ b/ext/session/sessionC.test @@ -0,0 +1,190 @@ +# 2014 August 16 +# +# 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. +# +#*********************************************************************** +# +# + +if {![info exists testdir]} { + set testdir [file join [file dirname [info script]] .. .. test] +} +source [file join [file dirname [info script]] session_common.tcl] +source $testdir/tester.tcl +ifcapable !session {finish_test; return} + +set testprefix sessionC + +#------------------------------------------------------------------------- +# Test the outcome of a DELETE operation made as part of applying a +# changeset failing with SQLITE_CONSTRAINT. This may happen if an +# ON DELETE RESTRICT foreign key action is triggered, or if a trigger +# program raises a constraint somehow. +# +do_execsql_test 1.0 { + PRAGMA foreign_keys = 1; + + CREATE TABLE p(a PRIMARY KEY, b, c); + CREATE TABLE c(d PRIMARY KEY, e REFERENCES p ON DELETE RESTRICT); + + INSERT INTO p VALUES('one', 1, 1); + INSERT INTO p VALUES('two', 2, 2); + INSERT INTO p VALUES('three', 3, 3); + + INSERT INTO c VALUES(1, 'one'); + INSERT INTO c VALUES(3, 'three'); +} + +do_test 1.1 { + execsql BEGIN + set C [changeset_from_sql { + INSERT INTO c VALUES(4, 'one'); + DELETE FROM p WHERE a='two'; + }] + execsql ROLLBACK + execsql { + INSERT INTO c VALUES(2, 'two'); + } +} {} + +do_test 1.2.1 { + proc xConflict {args} { return "ABORT" } + catch { sqlite3changeset_apply db $C xConflict } msg + set msg +} {SQLITE_ABORT} +do_execsql_test 1.2.2 { SELECT * FROM c } {1 one 3 three 2 two} + +do_test 1.3.1 { + proc xConflict {args} { return "OMIT" } + catch { sqlite3changeset_apply db $C xConflict } msg + set msg +} {} +do_execsql_test 1.3.2 { SELECT * FROM c } {1 one 3 three 2 two 4 one} +do_execsql_test 1.3.3 { + SELECT * FROM p; +} {one 1 1 two 2 2 three 3 3} + + +#------------------------------------------------------------------------- +# Test that concatenating a changeset with a patchset does not work. +# Any attempt to do so returns SQLITE_ERROR. +# +reset_db +do_execsql_test 2.0 { + CREATE TABLE x1(t, v PRIMARY KEY); + INSERT INTO x1 VALUES(12, 55); + INSERT INTO x1 VALUES(55, 14); +} + +do_test 2.1 { + execsql BEGIN + + sqlite3session S1 db main + S1 attach * + execsql { + UPDATE x1 SET t=13 WHERE v=55; + INSERT INTO x1 VALUES(99, 123); + } + set patchset [S1 patchset] + S1 delete + + sqlite3session S1 db main + S1 attach * + execsql { + UPDATE x1 SET t=56 WHERE v=14; + INSERT INTO x1 VALUES(22, 998); + } + set changeset [S1 changeset] + S1 delete + + execsql ROLLBACK +} {} + +do_test 2.2 { + set rc [catch { sqlite3changeset_concat $patchset $changeset } msg] + list $rc $msg +} {1 SQLITE_ERROR} + +do_test 2.3 { + set rc [catch { sqlite3changeset_concat $changeset $patchset } msg] + list $rc $msg +} {1 SQLITE_ERROR} + +do_test 2.4 { + set rc [catch { sqlite3changeset_concat {} $patchset } msg] + list $rc $msg +} [list 0 $patchset] + +do_test 2.5 { + set rc [catch { sqlite3changeset_concat $patchset {} } msg] + list $rc $msg +} [list 0 $patchset] + +do_test 2.6 { + set rc [catch { sqlite3changeset_concat {} $changeset } msg] + list $rc $msg +} [list 0 $changeset] + +do_test 2.7 { + set rc [catch { sqlite3changeset_concat $changeset {} } msg] + list $rc $msg +} [list 0 $changeset] + +do_test 2.8 { + set rc [catch { sqlite3changeset_concat {} {} } msg] + list $rc $msg +} [list 0 {}] + + +#------------------------------------------------------------------------- +# Test that the xFilter argument to sqlite3changeset_apply() works. +# +reset_db +do_execsql_test 3.0 { + CREATE TABLE t1(a PRIMARY KEY, b); + CREATE TABLE t2(a PRIMARY KEY, b); + CREATE TABLE t3(a PRIMARY KEY, b); +} +do_test 3.1 { + execsql BEGIN + set changeset [changeset_from_sql { + INSERT INTO t1 VALUES(1, 1); + INSERT INTO t2 VALUES(2, 2); + INSERT INTO t3 VALUES(3, 3); + }] + execsql ROLLBACK +} {} +do_test 3.2 { + proc xFilter {zName} { + if {$zName == "t1"} { return 1 } + return 0 + } + sqlite3changeset_apply db $changeset noop xFilter + execsql { + SELECT * FROM t1; + SELECT * FROM t2; + SELECT * FROM t3; + } +} {1 1} +do_test 3.3 { + proc xFilter {zName} { + if {$zName == "t3"} { return 1 } + return 0 + } + sqlite3changeset_apply db $changeset noop xFilter + execsql { + SELECT * FROM t1; + SELECT * FROM t2; + SELECT * FROM t3; + } +} {1 1 3 3} + + + +finish_test + diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index fe7d6e5a21..f861bd1ec6 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -3911,12 +3911,18 @@ int sessionChangesetConcat( assert( xOutput==0 || (ppOut==0 && pnOut==0) ); + assert( pLeft->zTab==0 && pRight->zTab==0 ); rc = sessionChangesetToHash(pLeft, &pList); + assert( pLeft->zTab || pList==0 ); if( rc==SQLITE_OK ){ rc = sessionChangesetToHash(pRight, &pList); } bPatch = pLeft->bPatchset || pRight->bPatchset; + if( pLeft->zTab && pRight->zTab && pLeft->bPatchset!=pRight->bPatchset ){ + rc = SQLITE_ERROR; + } + /* Create the serialized output changeset based on the contents of the ** hash tables attached to the SessionTable objects in list pList. */ diff --git a/manifest b/manifest index 9b98ed7c5f..193e5f6c38 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\slatest\strunk\schanges\swith\sthis\sbranch. -D 2014-10-15T19:37:13.299 +C Fix\sa\sproblem\scausing\ssqlite3changeset_concat()\sto\sfail\sto\sdetect\sattempts\sto\sconcatenate\spatchsets\swhich\schangesets. +D 2014-10-15T20:02:21.265 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in dd5f245aa8c741bc65845747203c8ce2f3fb6c83 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -156,9 +156,10 @@ F ext/session/session8.test 8e194b3f655d861ca36de5d4de53f702751bab3b F ext/session/session9.test 5409d90d8141881d08285ed1c2c0d8d10fb92069 F ext/session/sessionA.test 1feeab0b8e03527f08f2f1defb442da25480138f F ext/session/sessionB.test 06961b7c3641151f5d23088250ecad132501113c +F ext/session/sessionC.test 3982f8577b0744c5ce3aaef7cfeb5bd903f17fe4 F ext/session/session_common.tcl 9de0451b6a47218fc16b9ed8876b6238a0a3d88d F ext/session/sessionfault.test bef044d0952c0d62c31c8d2400be72c8684545cc -F ext/session/sqlite3session.c 67b8aee718cf34e267f4040d9b945a7a6407b0b2 +F ext/session/sqlite3session.c 838050c4c217d2843e4705b14be25d8f0457f155 F ext/session/sqlite3session.h 16608d29879a0ed3c6be6b7fb18dcdb5c707aaef F ext/session/test_session.c a28352e99bc6a83b94e4cce99a7bf25c73d6d489 F ext/userauth/sqlite3userauth.h 19cb6f0e31316d0ee4afdfb7a85ef9da3333a220 @@ -1221,7 +1222,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 83d4114f2aa404e670ced33511183baacd813a01 3c1e70f4d55bc009ed9ed4cf6d756d7061985851 -R 573bb7e03bcfc05e0f889e571f4f3aa7 +P 1b2824f1d11ac336779372e322aecfb36fb2a31d +R fa664b8794125d09d3da5d2babd6e792 U dan -Z d7531a3919881ed86fbddd665aff411c +Z 8d94920cff847cf3f9fcffe7f6436f08 diff --git a/manifest.uuid b/manifest.uuid index 1d5dadfa49..4a7ff9ad2f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1b2824f1d11ac336779372e322aecfb36fb2a31d \ No newline at end of file +236704a9d1551a50a55bd6e0b6473191a7a7dd21 \ No newline at end of file From cf8e91442d4b66812f8080cf3e916523ad858b11 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 8 Apr 2015 16:01:12 +0000 Subject: [PATCH 0130/1484] Add experimental API sqlite3session_diff(). FossilOrigin-Name: c4340b2ea2115ad97dcac036f9034e132ab789e5 --- ext/session/session2.test | 10 + ext/session/sessionD.test | 150 ++++++++++++ ext/session/sqlite3session.c | 431 ++++++++++++++++++++++++++++++----- ext/session/sqlite3session.h | 57 +++++ ext/session/test_session.c | 35 ++- manifest | 24 +- manifest.uuid | 2 +- 7 files changed, 636 insertions(+), 73 deletions(-) create mode 100644 ext/session/sessionD.test diff --git a/ext/session/session2.test b/ext/session/session2.test index 04be5f0917..0035e39dbf 100644 --- a/ext/session/session2.test +++ b/ext/session/session2.test @@ -169,7 +169,17 @@ set set_of_tests { INSERT INTO %T4% VALUES('def', 'abc'); } 17 { UPDATE %T4% SET b = 1 } + 18 { DELETE FROM %T4% WHERE 1 } + + 19 { + INSERT INTO t1 VALUES('', ''); + INSERT INTO t1 VALUES(X'', X''); + } + 20 { + DELETE FROM t1; + INSERT INTO t1 VALUES('', NULL); + } } test_reset diff --git a/ext/session/sessionD.test b/ext/session/sessionD.test new file mode 100644 index 0000000000..c26728742a --- /dev/null +++ b/ext/session/sessionD.test @@ -0,0 +1,150 @@ +# 2014 August 16 +# +# 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 focuses on the sqlite3session_diff() function. +# + +if {![info exists testdir]} { + set testdir [file join [file dirname [info script]] .. .. test] +} +source [file join [file dirname [info script]] session_common.tcl] +source $testdir/tester.tcl +ifcapable !session {finish_test; return} + +set testprefix sessionD + +proc scksum {db dbname} { + + if {$dbname=="temp"} { + set master sqlite_temp_master + } else { + set master $dbname.sqlite_master + } + + set alltab [$db eval "SELECT name FROM $master WHERE type='table'"] + set txt [$db eval "SELECT * FROM $master ORDER BY type,name,sql"] + foreach tab $alltab { + set cols [list] + db eval "PRAGMA $dbname.table_info = $tab" x { + lappend cols "quote($x(name))" + } + set cols [join $cols ,] + append txt [db eval "SELECT $cols FROM $tab ORDER BY $cols"] + } + return [md5 $txt] +} + +proc do_diff_test {tn setup} { + reset_db + forcedelete test.db2 + execsql { ATTACH 'test.db2' AS aux } + execsql $setup + + sqlite3session S db main + foreach tbl [db eval {SELECT name FROM sqlite_master WHERE type='table'}] { + S attach $tbl + S diff aux $tbl + } + + set C [S changeset] + S delete + + sqlite3 db2 test.db2 + sqlite3changeset_apply db2 $C "" + uplevel do_test $tn.1 [list {execsql { PRAGMA integrity_check } db2}] ok + db2 close + + set cksum [scksum db main] + uplevel do_test $tn.2 [list {scksum db aux}] [list $cksum] +} + + +forcedelete test.db2 +do_execsql_test 1.0 { + CREATE TABLE t2(a PRIMARY KEY, b); + INSERT INTO t2 VALUES(1, 'one'); + INSERT INTO t2 VALUES(2, 'two'); + + ATTACH 'test.db2' AS aux; + CREATE TABLE aux.t2(a PRIMARY KEY, b); +} + +do_test 1.1 { + sqlite3session S db main + S attach t2 + S diff aux t2 + set C [S changeset] + S delete +} {} + +do_test 1.2 { + sqlite3 db2 test.db2 + sqlite3changeset_apply db2 $C "" + db2 close + db eval { SELECT * FROM aux.t2 } +} {1 one 2 two} + +do_diff_test 2.1 { + CREATE TABLE aux.t1(x, y, PRIMARY KEY(y)); + CREATE TABLE t1(x, y, PRIMARY KEY(y)); + + INSERT INTO t1 VALUES(1, 2); + INSERT INTO t1 VALUES(NULL, 'xyz'); + INSERT INTO t1 VALUES(4.5, 5.5); +} + +do_diff_test 2.2 { + CREATE TABLE aux.t1(x, y, PRIMARY KEY(y)); + CREATE TABLE t1(x, y, PRIMARY KEY(y)); + + INSERT INTO aux.t1 VALUES(1, 2); + INSERT INTO aux.t1 VALUES(NULL, 'xyz'); + INSERT INTO aux.t1 VALUES(4.5, 5.5); +} + +do_diff_test 2.3 { + CREATE TABLE aux.t1(a PRIMARY KEY, b TEXT); + CREATE TABLE t1(a PRIMARY KEY, b TEXT); + + INSERT INTO aux.t1 VALUES(1, 'one'); + INSERT INTO aux.t1 VALUES(2, 'two'); + INSERT INTO aux.t1 VALUES(3, 'three'); + + INSERT INTO t1 VALUES(1, 'I'); + INSERT INTO t1 VALUES(2, 'two'); + INSERT INTO t1 VALUES(3, 'III'); +} + +do_diff_test 2.4 { + CREATE TABLE aux.t1(a, b, c, d, PRIMARY KEY(c, b, a)); + CREATE TABLE t1(a, b, c, d, PRIMARY KEY(c, b, a)); + + INSERT INTO t1 VALUES('hvkzyipambwdqlvwv','',-458331.50,X'DA51ED5E84'); + INSERT INTO t1 VALUES(X'C5C6B5DD','jjxrath',40917,830244); + INSERT INTO t1 VALUES(-204877.54,X'1704C253D5F3AFA8',155120.88,NULL); + INSERT INTO t1 + VALUES('ckmqmzoeuvxisxqy',X'EB5A5D3A1DD22FD1','tidhjcbvbppdt',-642987.37); + INSERT INTO t1 VALUES(-851726,-161992,-469943,-159541); + INSERT INTO t1 VALUES(X'4A6A667F858938',185083,X'7A',NULL); + + INSERT INTO aux.t1 VALUES(415075.74,'auawczkb',X'',X'57B4FAAF2595'); + INSERT INTO aux.t1 VALUES(727637,711560,-181340,'hphuo'); + INSERT INTO aux.t1 + VALUES(-921322.81,662959,'lvlgwdgxaurr','ajjrzrbhqflsutnymgc'); + INSERT INTO aux.t1 VALUES(-146061,-377892,X'4E','gepvpvvuhszpxabbb'); + INSERT INTO aux.t1 VALUES(-851726,-161992,-469943,-159541); + INSERT INTO aux.t1 VALUES(X'4A6A667F858938',185083,X'7A',NULL); + INSERT INTO aux.t1 VALUES(-204877.54,X'1704C253D5F3AFA8',155120.88, 4); + INSERT INTO aux.t1 + VALUES('ckmqmzoeuvxisxqy',X'EB5A5D3A1DD22FD1','tidgtsplhjcbvbppdt',-642987.3); +} + +finish_test + diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index f861bd1ec6..5966947820 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -25,6 +25,15 @@ typedef struct SessionInput SessionInput; # endif #endif +typedef struct SessionHook SessionHook; +struct SessionHook { + void *pCtx; + int (*xOld)(void*,int,sqlite3_value**); + int (*xNew)(void*,int,sqlite3_value**); + int (*xCount)(void*); + int (*xDepth)(void*); +}; + /* ** Session handle structure. */ @@ -39,6 +48,7 @@ struct sqlite3_session { int (*xTableFilter)(void *pCtx, const char *zTab); sqlite3_session *pNext; /* Next session object on same db. */ SessionTable *pTable; /* List of attached tables */ + SessionHook hook; /* APIs to grab new and old data with */ }; /* @@ -316,8 +326,8 @@ static int sessionSerializeValue( }else{ z = (u8 *)sqlite3_value_blob(pValue); } - if( z==0 ) return SQLITE_NOMEM; n = sqlite3_value_bytes(pValue); + if( z==0 && (eType!=SQLITE_BLOB || n>0) ) return SQLITE_NOMEM; nVarint = sessionVarintLen(n); if( aBuf ){ @@ -397,7 +407,7 @@ static unsigned int sessionHashAppendType(unsigned int h, int eType){ ** and the output variables are set as described above. */ static int sessionPreupdateHash( - sqlite3 *db, /* Database handle */ + sqlite3_session *pSession, /* Session object that owns pTab */ SessionTable *pTab, /* Session table handle */ int bNew, /* True to hash the new.* PK */ int *piHash, /* OUT: Hash value */ @@ -407,7 +417,7 @@ static int sessionPreupdateHash( int i; /* Used to iterate through columns */ assert( *pbNullPK==0 ); - assert( pTab->nCol==sqlite3_preupdate_count(db) ); + assert( pTab->nCol==pSession->hook.xCount(pSession->hook.pCtx) ); for(i=0; inCol; i++){ if( pTab->abPK[i] ){ int rc; @@ -415,9 +425,9 @@ static int sessionPreupdateHash( sqlite3_value *pVal; if( bNew ){ - rc = sqlite3_preupdate_new(db, i, &pVal); + rc = pSession->hook.xNew(pSession->hook.pCtx, i, &pVal); }else{ - rc = sqlite3_preupdate_old(db, i, &pVal); + rc = pSession->hook.xOld(pSession->hook.pCtx, i, &pVal); } if( rc!=SQLITE_OK ) return rc; @@ -435,13 +445,15 @@ static int sessionPreupdateHash( h = sessionHashAppendI64(h, iVal); }else if( eType==SQLITE_TEXT || eType==SQLITE_BLOB ){ const u8 *z; + int n; if( eType==SQLITE_TEXT ){ z = (const u8 *)sqlite3_value_text(pVal); }else{ z = (const u8 *)sqlite3_value_blob(pVal); } - if( !z ) return SQLITE_NOMEM; - h = sessionHashAppendBlob(h, sqlite3_value_bytes(pVal), z); + n = sqlite3_value_bytes(pVal); + if( !z && (eType!=SQLITE_BLOB || n>0) ) return SQLITE_NOMEM; + h = sessionHashAppendBlob(h, n, z); }else{ assert( eType==SQLITE_NULL ); *pbNullPK = 1; @@ -721,11 +733,12 @@ static int sessionMergeUpdate( ** false. */ static int sessionPreupdateEqual( - sqlite3 *db, /* Database handle */ + sqlite3_session *pSession, /* Session object that owns SessionTable */ SessionTable *pTab, /* Table associated with change */ SessionChange *pChange, /* Change to compare to */ int op /* Current pre-update operation */ ){ + sqlite3 *db = pSession->db; int iCol; /* Used to iterate through columns */ u8 *a = pChange->aRecord; /* Cursor used to scan change record */ @@ -744,11 +757,11 @@ static int sessionPreupdateEqual( ** within sessionPreupdateHash(). The first two asserts below verify ** this (that the method has already been called). */ if( op==SQLITE_INSERT ){ - assert( db->pPreUpdate->pNewUnpacked || db->pPreUpdate->aNew ); - rc = sqlite3_preupdate_new(db, iCol, &pVal); + /* assert( db->pPreUpdate->pNewUnpacked || db->pPreUpdate->aNew ); */ + rc = pSession->hook.xNew(pSession->hook.pCtx, iCol, &pVal); }else{ - assert( db->pPreUpdate->pUnpacked ); - rc = sqlite3_preupdate_old(db, iCol, &pVal); + /* assert( db->pPreUpdate->pUnpacked ); */ + rc = pSession->hook.xOld(pSession->hook.pCtx, iCol, &pVal); } assert( rc==SQLITE_OK ); if( sqlite3_value_type(pVal)!=eType ) return 0; @@ -976,7 +989,7 @@ static int sessionInitTable(sqlite3_session *pSession, SessionTable *pTab){ ); } if( pSession->rc==SQLITE_OK - && pTab->nCol!=sqlite3_preupdate_count(pSession->db) + && pTab->nCol!=pSession->hook.xCount(pSession->hook.pCtx) ){ pSession->rc = SQLITE_SCHEMA; } @@ -996,9 +1009,8 @@ static void sessionPreupdateOneChange( sqlite3_session *pSession, /* Session object pTab is attached to */ SessionTable *pTab /* Table that change applies to */ ){ - sqlite3 *db = pSession->db; int iHash; - int bNullPk = 0; + int bNull = 0; int rc = SQLITE_OK; if( pSession->rc ) return; @@ -1015,14 +1027,14 @@ static void sessionPreupdateOneChange( /* Calculate the hash-key for this change. If the primary key of the row ** includes a NULL value, exit early. Such changes are ignored by the ** session module. */ - rc = sessionPreupdateHash(db, pTab, op==SQLITE_INSERT, &iHash, &bNullPk); + rc = sessionPreupdateHash(pSession, pTab, op==SQLITE_INSERT, &iHash, &bNull); if( rc!=SQLITE_OK ) goto error_out; - if( bNullPk==0 ){ + if( bNull==0 ){ /* Search the hash table for an existing record for this row. */ SessionChange *pC; for(pC=pTab->apChange[iHash]; pC; pC=pC->pNext){ - if( sessionPreupdateEqual(db, pTab, pC, op) ) break; + if( sessionPreupdateEqual(pSession, pTab, pC, op) ) break; } if( pC==0 ){ @@ -1041,10 +1053,10 @@ static void sessionPreupdateOneChange( for(i=0; inCol; i++){ sqlite3_value *p = 0; if( op!=SQLITE_INSERT ){ - TESTONLY(int trc = ) sqlite3_preupdate_old(pSession->db, i, &p); + TESTONLY(int trc = ) pSession->hook.xOld(pSession->hook.pCtx, i, &p); assert( trc==SQLITE_OK ); }else if( pTab->abPK[i] ){ - TESTONLY(int trc = ) sqlite3_preupdate_new(pSession->db, i, &p); + TESTONLY(int trc = ) pSession->hook.xNew(pSession->hook.pCtx, i, &p); assert( trc==SQLITE_OK ); } @@ -1072,15 +1084,15 @@ static void sessionPreupdateOneChange( for(i=0; inCol; i++){ sqlite3_value *p = 0; if( op!=SQLITE_INSERT ){ - sqlite3_preupdate_old(pSession->db, i, &p); + pSession->hook.xOld(pSession->hook.pCtx, i, &p); }else if( pTab->abPK[i] ){ - sqlite3_preupdate_new(pSession->db, i, &p); + pSession->hook.xNew(pSession->hook.pCtx, i, &p); } sessionSerializeValue(&pChange->aRecord[nByte], p, &nByte); } /* Add the change to the hash-table */ - if( pSession->bIndirect || sqlite3_preupdate_depth(pSession->db) ){ + if( pSession->bIndirect || pSession->hook.xDepth(pSession->hook.pCtx) ){ pChange->bIndirect = 1; } pChange->nRecord = nByte; @@ -1091,7 +1103,9 @@ static void sessionPreupdateOneChange( }else if( pC->bIndirect ){ /* If the existing change is considered "indirect", but this current ** change is "direct", mark the change object as direct. */ - if( sqlite3_preupdate_depth(pSession->db)==0 && pSession->bIndirect==0 ){ + if( pSession->hook.xDepth(pSession->hook.pCtx)==0 + && pSession->bIndirect==0 + ){ pC->bIndirect = 0; } } @@ -1104,6 +1118,39 @@ static void sessionPreupdateOneChange( } } +static int sessionFindTable( + sqlite3_session *pSession, + const char *zName, + SessionTable **ppTab +){ + int rc = SQLITE_OK; + int nName = sqlite3Strlen30(zName); + SessionTable *pRet; + + /* Search for an existing table */ + for(pRet=pSession->pTable; pRet; pRet=pRet->pNext){ + if( 0==sqlite3_strnicmp(pRet->zName, zName, nName+1) ) break; + } + + if( pRet==0 && pSession->bAutoAttach ){ + /* If there is a table-filter configured, invoke it. If it returns 0, + ** do not automatically add the new table. */ + if( pSession->xTableFilter==0 + || pSession->xTableFilter(pSession->pFilterCtx, zName) + ){ + rc = sqlite3session_attach(pSession, zName); + if( rc==SQLITE_OK ){ + pRet = pSession->pTable; + assert( 0==sqlite3_strnicmp(pRet->zName, zName, nName+1) ); + } + } + } + + assert( rc==SQLITE_OK || pRet==0 ); + *ppTab = pRet; + return rc; +} + /* ** The 'pre-update' hook registered by this module with SQLite databases. */ @@ -1118,7 +1165,6 @@ static void xPreUpdate( ){ sqlite3_session *pSession; int nDb = sqlite3Strlen30(zDb); - int nName = sqlite3Strlen30(zName); assert( sqlite3_mutex_held(db->mutex) ); @@ -1132,37 +1178,312 @@ static void xPreUpdate( if( pSession->rc ) continue; if( sqlite3_strnicmp(zDb, pSession->zDb, nDb+1) ) continue; - for(pTab=pSession->pTable; pTab || pSession->bAutoAttach; pTab=pTab->pNext){ - if( !pTab ){ - /* This branch is taken if table zName has not yet been attached to - ** this session and the auto-attach flag is set. */ - - /* If there is a table-filter configured, invoke it. If it returns 0, - ** this change will not be recorded. Break out of the loop early in - ** this case. */ - if( pSession->xTableFilter - && pSession->xTableFilter(pSession->pFilterCtx, zName)==0 - ){ - break; - } - - pSession->rc = sqlite3session_attach(pSession,zName); - if( pSession->rc ) break; - pTab = pSession->pTable; - assert( 0==sqlite3_strnicmp(pTab->zName, zName, nName+1) ); - } - - if( 0==sqlite3_strnicmp(pTab->zName, zName, nName+1) ){ - sessionPreupdateOneChange(op, pSession, pTab); - if( op==SQLITE_UPDATE ){ - sessionPreupdateOneChange(SQLITE_INSERT, pSession, pTab); - } - break; + pSession->rc = sessionFindTable(pSession, zName, &pTab); + if( pTab ){ + assert( pSession->rc==SQLITE_OK ); + sessionPreupdateOneChange(op, pSession, pTab); + if( op==SQLITE_UPDATE ){ + sessionPreupdateOneChange(SQLITE_INSERT, pSession, pTab); } } } } +/* +** The pre-update hook implementations. +*/ +static int sessionPreupdateOld(void *pCtx, int iVal, sqlite3_value **ppVal){ + return sqlite3_preupdate_old((sqlite3*)pCtx, iVal, ppVal); +} +static int sessionPreupdateNew(void *pCtx, int iVal, sqlite3_value **ppVal){ + return sqlite3_preupdate_new((sqlite3*)pCtx, iVal, ppVal); +} +static int sessionPreupdateCount(void *pCtx){ + return sqlite3_preupdate_count((sqlite3*)pCtx); +} +static int sessionPreupdateDepth(void *pCtx){ + return sqlite3_preupdate_depth((sqlite3*)pCtx); +} + +/* +** Install the pre-update hooks on the session object passed as the only +** argument. +*/ +static void sessionPreupdateHooks( + sqlite3_session *pSession +){ + pSession->hook.pCtx = (void*)pSession->db; + pSession->hook.xOld = sessionPreupdateOld; + pSession->hook.xNew = sessionPreupdateNew; + pSession->hook.xCount = sessionPreupdateCount; + pSession->hook.xDepth = sessionPreupdateDepth; +} + +typedef struct SessionDiffCtx SessionDiffCtx; +struct SessionDiffCtx { + sqlite3_stmt *pStmt; + int nOldOff; +}; + +/* +** The diff hook implementations. +*/ +static int sessionDiffOld(void *pCtx, int iVal, sqlite3_value **ppVal){ + SessionDiffCtx *p = (SessionDiffCtx*)pCtx; + *ppVal = sqlite3_column_value(p->pStmt, iVal+p->nOldOff); + return SQLITE_OK; +} +static int sessionDiffNew(void *pCtx, int iVal, sqlite3_value **ppVal){ + SessionDiffCtx *p = (SessionDiffCtx*)pCtx; + *ppVal = sqlite3_column_value(p->pStmt, iVal); + return SQLITE_OK; +} +static int sessionDiffCount(void *pCtx){ + SessionDiffCtx *p = (SessionDiffCtx*)pCtx; + return p->nOldOff ? p->nOldOff : sqlite3_column_count(p->pStmt); +} +static int sessionDiffDepth(void *pCtx){ + return 0; +} + +/* +** Install the diff hooks on the session object passed as the only +** argument. +*/ +static void sessionDiffHooks( + sqlite3_session *pSession, + SessionDiffCtx *pDiffCtx +){ + pSession->hook.pCtx = (void*)pDiffCtx; + pSession->hook.xOld = sessionDiffOld; + pSession->hook.xNew = sessionDiffNew; + pSession->hook.xCount = sessionDiffCount; + pSession->hook.xDepth = sessionDiffDepth; +} + +static char *sessionExprComparePK( + int nCol, + const char *zDb1, const char *zDb2, + const char *zTab, + const char **azCol, u8 *abPK +){ + int i; + const char *zSep = ""; + char *zRet = 0; + + for(i=0; inCol, zDb1, zDb2, pTab->zName,zExpr); + + if( zStmt==0 ){ + rc = SQLITE_NOMEM; + }else{ + sqlite3_stmt *pStmt; + rc = sqlite3_prepare(pSession->db, zStmt, -1, &pStmt, 0); + if( rc==SQLITE_OK ){ + SessionDiffCtx *pDiffCtx = (SessionDiffCtx*)pSession->hook.pCtx; + pDiffCtx->pStmt = pStmt; + pDiffCtx->nOldOff = 0; + while( SQLITE_ROW==sqlite3_step(pStmt) ){ + sessionPreupdateOneChange(op, pSession, pTab); + } + rc = sqlite3_finalize(pStmt); + } + sqlite3_free(zStmt); + } + + return rc; +} + +static int sessionDiffFindModified( + sqlite3_session *pSession, + SessionTable *pTab, + const char *zFrom, + const char *zExpr +){ + int rc = SQLITE_OK; + + char *zExpr2 = sessionExprCompareOther(pTab->nCol, + pSession->zDb, zFrom, pTab->zName, pTab->azCol, pTab->abPK + ); + if( zExpr2==0 ){ + rc = SQLITE_NOMEM; + }else{ + char *zStmt = sqlite3_mprintf( + "SELECT * FROM \"%w\".\"%w\", \"%w\".\"\%w\" WHERE %s AND %z", + pSession->zDb, pTab->zName, zFrom, pTab->zName, zExpr, zExpr2 + ); + if( zStmt==0 ){ + rc = SQLITE_NOMEM; + }else{ + sqlite3_stmt *pStmt; + rc = sqlite3_prepare(pSession->db, zStmt, -1, &pStmt, 0); + + if( rc==SQLITE_OK ){ + SessionDiffCtx *pDiffCtx = (SessionDiffCtx*)pSession->hook.pCtx; + pDiffCtx->pStmt = pStmt; + pDiffCtx->nOldOff = pTab->nCol; + while( SQLITE_ROW==sqlite3_step(pStmt) ){ + sessionPreupdateOneChange(SQLITE_UPDATE, pSession, pTab); + } + rc = sqlite3_finalize(pStmt); + } + sqlite3_free(zStmt); + } + } + + return rc; +} + +int sqlite3session_diff( + sqlite3_session *pSession, + const char *zFrom, + const char *zTbl, + char **pzErrMsg +){ + const char *zDb = pSession->zDb; + int rc = pSession->rc; + SessionDiffCtx d; + + memset(&d, 0, sizeof(d)); + sessionDiffHooks(pSession, &d); + + if( pzErrMsg ) *pzErrMsg = 0; + if( rc==SQLITE_OK ){ + char *zExpr = 0; + sqlite3 *db = pSession->db; + SessionTable *pTo; /* Table zTbl */ + + /* Locate and if necessary initialize the target table object */ + rc = sessionFindTable(pSession, zTbl, &pTo); + if( pTo==0 ) goto diff_out; + if( pTo->nCol==0 ){ + rc = pSession->rc = sessionTableInfo(db, zDb, + pTo->zName, &pTo->nCol, 0, &pTo->azCol, &pTo->abPK + ); + } + + /* Check the table schemas match */ + if( rc==SQLITE_OK ){ + int nCol; /* Columns in zFrom.zTbl */ + u8 *abPK; + const char **azCol = 0; + rc = sessionTableInfo(db, zFrom, zTbl, &nCol, 0, &azCol, &abPK); + if( rc==SQLITE_OK ){ + int bMismatch = 0; + if( pTo->nCol!=nCol || memcmp(pTo->abPK, abPK, nCol) ){ + bMismatch = 1; + }else{ + int i; + for(i=0; iazCol[i]) ) bMismatch = 1; + } + } + + if( bMismatch ){ + *pzErrMsg = sqlite3_mprintf("table schemas do not match"); + rc = SQLITE_ERROR; + } + } + sqlite3_free(azCol); + } + + if( rc==SQLITE_OK ){ + zExpr = sessionExprComparePK(pTo->nCol, + zDb, zFrom, pTo->zName, pTo->azCol, pTo->abPK + ); + } + + /* Find new rows */ + if( rc==SQLITE_OK ){ + rc = sessionDiffFindNew(SQLITE_INSERT, pSession, pTo, zDb, zFrom, zExpr); + } + + /* Find old rows */ + if( rc==SQLITE_OK ){ + rc = sessionDiffFindNew(SQLITE_DELETE, pSession, pTo, zFrom, zDb, zExpr); + } + + /* Find modified rows */ + if( rc==SQLITE_OK ){ + rc = sessionDiffFindModified(pSession, pTo, zFrom, zExpr); + } + + sqlite3_free(zExpr); + } + + diff_out: + sessionPreupdateHooks(pSession); + return rc; +} + /* ** Create a session object. This session object will record changes to ** database zDb attached to connection db. @@ -1187,6 +1508,7 @@ int sqlite3session_create( pNew->zDb = (char *)&pNew[1]; pNew->bEnable = 1; memcpy(pNew->zDb, zDb, nDb+1); + sessionPreupdateHooks(pNew); /* Add the new session object to the linked list of session objects ** attached to database handle $db. Do this under the cover of the db @@ -1500,13 +1822,14 @@ static void sessionAppendCol( } if( eType==SQLITE_BLOB || eType==SQLITE_TEXT ){ u8 *z; + int nByte; if( eType==SQLITE_BLOB ){ z = (u8 *)sqlite3_column_blob(pStmt, iCol); }else{ z = (u8 *)sqlite3_column_text(pStmt, iCol); } - if( z ){ - int nByte = sqlite3_column_bytes(pStmt, iCol); + nByte = sqlite3_column_bytes(pStmt, iCol); + if( z || (eType==SQLITE_BLOB && nByte==0) ){ sessionAppendVarint(p, nByte, pRc); sessionAppendBlob(p, z, nByte, pRc); }else{ @@ -2179,7 +2502,7 @@ static int sessionValueSetStr( ** argument to sqlite3ValueSetStr() and have the copy created ** automatically. But doing so makes it difficult to detect any OOM ** error. Hence the code to create the copy externally. */ - u8 *aCopy = sqlite3_malloc(nData); + u8 *aCopy = sqlite3_malloc(nData+1); if( aCopy==0 ) return SQLITE_NOMEM; memcpy(aCopy, aData, nData); sqlite3ValueSetStr(pVal, nData, (char*)aCopy, enc, sqlite3_free); diff --git a/ext/session/sqlite3session.h b/ext/session/sqlite3session.h index e768d66324..ed1c5d917c 100644 --- a/ext/session/sqlite3session.h +++ b/ext/session/sqlite3session.h @@ -273,6 +273,63 @@ int sqlite3session_changeset( void **ppChangeset /* OUT: Buffer containing changeset */ ); +/* +** CAPI3REF: Load The Difference Between Tables Into A Session +** +** If it is not already attached to the session object passed as the first +** argument, this function attaches table zTbl in the same manner as the +** [sqlite3session_attach()] function. If zTbl does not exist, or if it +** does not have a primary key, this function is a no-op (but does not return +** an error). +** +** Argument zFromDb must be the name of a database ("main", "temp" etc.) +** attached to the same database handle as the session object that contains +** a table compatible with the table attached to the session by this function. +** A table is considered compatible if it: +** +**
    +**
  • Has the same name, +**
  • Has the same set of columns declared in the same order, and +**
  • Has the same PRIMARY KEY definition. +**
+** +** This function adds a set of changes to the session object that could be +** used to update the table in database zFrom (call this the "from-table") +** so that its content is the same as the table attached to the session +** object (call this the "to-table"). Specifically: +** +**
    +**
  • For each row (primary key) that exists in the to-table but not in +** the from-table, an INSERT record is added to the session object. +** +**
  • For each row (primary key) that exists in the to-table but not in +** the from-table, a DELETE record is added to the session object. +** +**
  • For each row (primary key) that exists in both tables, but features +** different in each, an UPDATE record is added to the session. +**
+** +** To clarify, if this function is called and then a changeset constructed +** using [sqlite3session_changeset()], then after applying that changeset to +** database zFrom the contents of the two compatible tables would be +** identical. +** +** It an error if database zFrom does not exist or does not contain the +** required compatible table. +** +** If the operation successful, SQLITE_OK is returned. Otherwise, an SQLite +** error code. In this case, if argument pzErrMsg is not NULL, *pzErrMsg +** may be set to point to a buffer containing an English language error +** message. It is the responsibility of the caller to free this buffer using +** sqlite3_free(). +*/ +int sqlite3session_diff( + sqlite3_session *pSession, + const char *zFromDb, + const char *zTbl, + char **pzErrMsg +); + /* ** CAPI3REF: Generate A Patchset From A Session Object diff --git a/ext/session/test_session.c b/ext/session/test_session.c index 6c538bcec1..3dc24fc69e 100644 --- a/ext/session/test_session.c +++ b/ext/session/test_session.c @@ -117,14 +117,15 @@ static int test_session_cmd( const char *zMsg; int iSub; } aSub[] = { - { "attach", 1, "TABLE", }, /* 0 */ - { "changeset", 0, "", }, /* 1 */ - { "delete", 0, "", }, /* 2 */ - { "enable", 1, "BOOL", }, /* 3 */ - { "indirect", 1, "BOOL", }, /* 4 */ - { "isempty", 0, "", }, /* 5 */ - { "table_filter", 1, "SCRIPT", }, /* 6 */ - { "patchset", 0, "", }, /* 7 */ + { "attach", 1, "TABLE", }, /* 0 */ + { "changeset", 0, "", }, /* 1 */ + { "delete", 0, "", }, /* 2 */ + { "enable", 1, "BOOL", }, /* 3 */ + { "indirect", 1, "BOOL", }, /* 4 */ + { "isempty", 0, "", }, /* 5 */ + { "table_filter", 1, "SCRIPT", }, /* 6 */ + { "patchset", 0, "", }, /* 7 */ + { "diff", 2, "FROMDB TBL", }, /* 8 */ { 0 } }; int iSub; @@ -216,6 +217,24 @@ static int test_session_cmd( sqlite3session_table_filter(pSession, test_table_filter, clientData); break; } + + case 8: { /* diff */ + char *zErr = 0; + rc = sqlite3session_diff(pSession, + Tcl_GetString(objv[2]), + Tcl_GetString(objv[3]), + &zErr + ); + assert( rc!=SQLITE_OK || zErr==0 ); + if( zErr ){ + Tcl_AppendResult(interp, zErr, 0); + return TCL_ERROR; + } + if( rc ){ + return test_session_error(interp, rc); + } + break; + } } return TCL_OK; diff --git a/manifest b/manifest index 42a45e41f3..b4d0667b70 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sprintf()\swidth\sand\sprecision\soverflow\sfixes\sfrom\strunk. -D 2015-04-07T23:10:44.364 +C Add\sexperimental\sAPI\ssqlite3session_diff(). +D 2015-04-08T16:01:12.482 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 3083cf0c2bc6618e532b9478ce735bb512322985 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -148,7 +148,7 @@ F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 F ext/session/changeset.c 4ccbaa4531944c24584bf6a61ba3a39c62b6267a F ext/session/session1.test 4653867f32a98ce4bbb4a181aac6debe51ca4dfb -F ext/session/session2.test 99ca0da7ddb617d42bafd83adccf99f18ae0384b +F ext/session/session2.test a95a2d270b32638c1acba7cb9c81856712d469ac F ext/session/session3.test a7a9ce59b8d1e49e2cc23d81421ac485be0eea01 F ext/session/session4.test a6ed685da7a5293c5d6f99855bcf41dbc352ca84 F ext/session/session5.test 716bc6fafd625ce60dfa62ae128971628c1a1169 @@ -158,11 +158,12 @@ F ext/session/session9.test 5409d90d8141881d08285ed1c2c0d8d10fb92069 F ext/session/sessionA.test 1feeab0b8e03527f08f2f1defb442da25480138f F ext/session/sessionB.test 06961b7c3641151f5d23088250ecad132501113c F ext/session/sessionC.test 3982f8577b0744c5ce3aaef7cfeb5bd903f17fe4 +F ext/session/sessionD.test 95903bd6a23dadbda7e192f730dd7dedd2d369ef F ext/session/session_common.tcl 9de0451b6a47218fc16b9ed8876b6238a0a3d88d F ext/session/sessionfault.test bef044d0952c0d62c31c8d2400be72c8684545cc -F ext/session/sqlite3session.c 838050c4c217d2843e4705b14be25d8f0457f155 -F ext/session/sqlite3session.h 16608d29879a0ed3c6be6b7fb18dcdb5c707aaef -F ext/session/test_session.c a28352e99bc6a83b94e4cce99a7bf25c73d6d489 +F ext/session/sqlite3session.c 3fcf2efe81c90602db76b1da33538895034eef66 +F ext/session/sqlite3session.h d9ebd8d4c5791aafdf18165575c7f2223c09279b +F ext/session/test_session.c 037fc25340a918eb2195972fed439d7adf7b5db9 F ext/userauth/sqlite3userauth.h 19cb6f0e31316d0ee4afdfb7a85ef9da3333a220 F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04 F ext/userauth/userauth.c 5fa3bdb492f481bbc1709fc83c91ebd13460c69e @@ -1267,7 +1268,10 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 271c110bcf5bf2ea7e113dd01dec876a08e3c047 8e4ac2ce24415926247961b00a62425ae85d6ffb -R e52a83cd9a76eb22e0a9f49afec82395 -U drh -Z 65d91c87ac07196da2d7921b7b9389b5 +P aeca95ac77f6f320a916f7e3c5a7a588ef4a20c8 +R 5c3cbffcff665bc16c7e835a4d990399 +T *branch * sessions-diff +T *sym-sessions-diff * +T -sym-sessions * +U dan +Z b513e16008d3799dcac5a3d5f415d7d8 diff --git a/manifest.uuid b/manifest.uuid index e451de8f37..8b03fb6fb8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -aeca95ac77f6f320a916f7e3c5a7a588ef4a20c8 \ No newline at end of file +c4340b2ea2115ad97dcac036f9034e132ab789e5 \ No newline at end of file From 3cc89d9567bb0e247c8d7de93c851febf22a363c Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 8 Apr 2015 16:43:31 +0000 Subject: [PATCH 0131/1484] Fix problems in the sessions module causing it to produce spurious SQLITE_NOMEM errors when handling SQL text or blob values zero bytes in size. FossilOrigin-Name: b9459d5980c6249a5c1bc5ea72cb4f3b1ba0e433 --- ext/session/session2.test | 10 ++++++++++ ext/session/sqlite3session.c | 15 +++++++++------ manifest | 16 ++++++++-------- manifest.uuid | 2 +- 4 files changed, 28 insertions(+), 15 deletions(-) diff --git a/ext/session/session2.test b/ext/session/session2.test index 04be5f0917..0035e39dbf 100644 --- a/ext/session/session2.test +++ b/ext/session/session2.test @@ -169,7 +169,17 @@ set set_of_tests { INSERT INTO %T4% VALUES('def', 'abc'); } 17 { UPDATE %T4% SET b = 1 } + 18 { DELETE FROM %T4% WHERE 1 } + + 19 { + INSERT INTO t1 VALUES('', ''); + INSERT INTO t1 VALUES(X'', X''); + } + 20 { + DELETE FROM t1; + INSERT INTO t1 VALUES('', NULL); + } } test_reset diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index f861bd1ec6..946681a4b3 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -316,8 +316,8 @@ static int sessionSerializeValue( }else{ z = (u8 *)sqlite3_value_blob(pValue); } - if( z==0 ) return SQLITE_NOMEM; n = sqlite3_value_bytes(pValue); + if( z==0 && (eType!=SQLITE_BLOB || n>0) ) return SQLITE_NOMEM; nVarint = sessionVarintLen(n); if( aBuf ){ @@ -435,13 +435,15 @@ static int sessionPreupdateHash( h = sessionHashAppendI64(h, iVal); }else if( eType==SQLITE_TEXT || eType==SQLITE_BLOB ){ const u8 *z; + int n; if( eType==SQLITE_TEXT ){ z = (const u8 *)sqlite3_value_text(pVal); }else{ z = (const u8 *)sqlite3_value_blob(pVal); } - if( !z ) return SQLITE_NOMEM; - h = sessionHashAppendBlob(h, sqlite3_value_bytes(pVal), z); + n = sqlite3_value_bytes(pVal); + if( !z && (eType!=SQLITE_BLOB || n>0) ) return SQLITE_NOMEM; + h = sessionHashAppendBlob(h, n, z); }else{ assert( eType==SQLITE_NULL ); *pbNullPK = 1; @@ -1500,13 +1502,14 @@ static void sessionAppendCol( } if( eType==SQLITE_BLOB || eType==SQLITE_TEXT ){ u8 *z; + int nByte; if( eType==SQLITE_BLOB ){ z = (u8 *)sqlite3_column_blob(pStmt, iCol); }else{ z = (u8 *)sqlite3_column_text(pStmt, iCol); } - if( z ){ - int nByte = sqlite3_column_bytes(pStmt, iCol); + nByte = sqlite3_column_bytes(pStmt, iCol); + if( z || (eType==SQLITE_BLOB && nByte==0) ){ sessionAppendVarint(p, nByte, pRc); sessionAppendBlob(p, z, nByte, pRc); }else{ @@ -2179,7 +2182,7 @@ static int sessionValueSetStr( ** argument to sqlite3ValueSetStr() and have the copy created ** automatically. But doing so makes it difficult to detect any OOM ** error. Hence the code to create the copy externally. */ - u8 *aCopy = sqlite3_malloc(nData); + u8 *aCopy = sqlite3_malloc(nData+1); if( aCopy==0 ) return SQLITE_NOMEM; memcpy(aCopy, aData, nData); sqlite3ValueSetStr(pVal, nData, (char*)aCopy, enc, sqlite3_free); diff --git a/manifest b/manifest index 42a45e41f3..b53ebc56fc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sprintf()\swidth\sand\sprecision\soverflow\sfixes\sfrom\strunk. -D 2015-04-07T23:10:44.364 +C Fix\sproblems\sin\sthe\ssessions\smodule\scausing\sit\sto\sproduce\sspurious\sSQLITE_NOMEM\serrors\swhen\shandling\sSQL\stext\sor\sblob\svalues\szero\sbytes\sin\ssize. +D 2015-04-08T16:43:31.690 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 3083cf0c2bc6618e532b9478ce735bb512322985 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -148,7 +148,7 @@ F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 F ext/session/changeset.c 4ccbaa4531944c24584bf6a61ba3a39c62b6267a F ext/session/session1.test 4653867f32a98ce4bbb4a181aac6debe51ca4dfb -F ext/session/session2.test 99ca0da7ddb617d42bafd83adccf99f18ae0384b +F ext/session/session2.test a95a2d270b32638c1acba7cb9c81856712d469ac F ext/session/session3.test a7a9ce59b8d1e49e2cc23d81421ac485be0eea01 F ext/session/session4.test a6ed685da7a5293c5d6f99855bcf41dbc352ca84 F ext/session/session5.test 716bc6fafd625ce60dfa62ae128971628c1a1169 @@ -160,7 +160,7 @@ F ext/session/sessionB.test 06961b7c3641151f5d23088250ecad132501113c F ext/session/sessionC.test 3982f8577b0744c5ce3aaef7cfeb5bd903f17fe4 F ext/session/session_common.tcl 9de0451b6a47218fc16b9ed8876b6238a0a3d88d F ext/session/sessionfault.test bef044d0952c0d62c31c8d2400be72c8684545cc -F ext/session/sqlite3session.c 838050c4c217d2843e4705b14be25d8f0457f155 +F ext/session/sqlite3session.c 7c6516f0342772441bcd2d845760902cfc0b39b8 F ext/session/sqlite3session.h 16608d29879a0ed3c6be6b7fb18dcdb5c707aaef F ext/session/test_session.c a28352e99bc6a83b94e4cce99a7bf25c73d6d489 F ext/userauth/sqlite3userauth.h 19cb6f0e31316d0ee4afdfb7a85ef9da3333a220 @@ -1267,7 +1267,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 271c110bcf5bf2ea7e113dd01dec876a08e3c047 8e4ac2ce24415926247961b00a62425ae85d6ffb -R e52a83cd9a76eb22e0a9f49afec82395 -U drh -Z 65d91c87ac07196da2d7921b7b9389b5 +P aeca95ac77f6f320a916f7e3c5a7a588ef4a20c8 +R 2b6c500da0e9b0a3fd57accc4dad1058 +U dan +Z aded3edd721aa55f05087866d9fe12cb diff --git a/manifest.uuid b/manifest.uuid index e451de8f37..27eccb5ef6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -aeca95ac77f6f320a916f7e3c5a7a588ef4a20c8 \ No newline at end of file +b9459d5980c6249a5c1bc5ea72cb4f3b1ba0e433 \ No newline at end of file From 730bb805a84cb3b08f7b99d5db2eb8c5ef5d9106 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 9 Apr 2015 19:19:22 +0000 Subject: [PATCH 0132/1484] Updates to comments describing the changeset and patchset formats. FossilOrigin-Name: 5342f721e878b52f207731ea57411f3669ae3f3f --- ext/session/sqlite3session.c | 51 ++++++++++++++++++++++++++++++++---- manifest | 12 ++++----- manifest.uuid | 2 +- 3 files changed, 53 insertions(+), 12 deletions(-) diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index 946681a4b3..aa71f32081 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -159,7 +159,7 @@ struct SessionTable { ** Each group of changes begins with a table header: ** ** 1 byte: Constant 0x54 (capital 'T') -** Varint: Big-endian integer set to the number of columns in the table. +** Varint: Number of columns in the table. ** nCol bytes: 0x01 for PK columns, 0x00 otherwise. ** N bytes: Unqualified table name (encoded using UTF-8). Nul-terminated. ** @@ -170,16 +170,38 @@ struct SessionTable { ** old.* record: (delete and update only) ** new.* record: (insert and update only) ** +** The "old.*" and "new.*" records, if present, are N field records in the +** format described above under "RECORD FORMAT", where N is the number of +** columns in the table. The i'th field of each record is associated with +** the i'th column of the table, counting from left to right in the order +** in which columns were declared in the CREATE TABLE statement. +** +** The new.* record that is part of each INSERT change contains the values +** that make up the new row. Similarly, the old.* record that is part of each +** DELETE change contains the values that made up the row that was deleted +** from the database. In the changeset format, the records that are part +** of INSERT or DELETE changes never contain any undefined (type byte 0x00) +** fields. +** +** Within the old.* record associated with an UPDATE change, all fields +** associated with table columns that are not PRIMARY KEY columns and are +** not modified by the UPDATE change are set to "undefined". Other fields +** are set to the values that made up the row before the UPDATE that the +** change records took place. Within the new.* record, fields associated +** with table columns modified by the UPDATE change contain the new +** values. Fields associated with table columns that are not modified +** are set to "undefined". +** ** PATCHSET FORMAT: ** ** A patchset is also a collection of changes. It is similar to a changeset, -** but omits those fields that are not useful if no conflict resolution -** is required when applying the changeset. +** but leaves undefined those fields that are not useful if no conflict +** resolution is required when applying the changeset. ** ** Each group of changes begins with a table header: ** ** 1 byte: Constant 0x50 (capital 'P') -** Varint: Big-endian integer set to the number of columns in the table. +** Varint: Number of columns in the table. ** nCol bytes: 0x01 for PK columns, 0x00 otherwise. ** N bytes: Unqualified table name (encoded using UTF-8). Nul-terminated. ** @@ -187,7 +209,26 @@ struct SessionTable { ** ** 1 byte: Either SQLITE_INSERT, UPDATE or DELETE. ** 1 byte: The "indirect-change" flag. -** single record: (PK fields for DELETE, or full record for INSERT/UPDATE). +** single record: (PK fields for DELETE, PK and modified fields for UPDATE, +** full record for INSERT). +** +** As in the changeset format, each field of the single record that is part +** of a patchset change is associated with the correspondingly positioned +** table column, counting from left to right within the CREATE TABLE +** statement. +** +** For a DELETE change, all fields within the record except those associated +** with PRIMARY KEY columns are set to "undefined". The PRIMARY KEY fields +** contain the values identifying the row to delete. +** +** For an UPDATE change, all fields except those associated with PRIMARY KEY +** columns and columns that are modified by the UPDATE are set to "undefined". +** PRIMARY KEY fields contain the values identifying the table row to update, +** and fields associated with modified columns contain the new column values. +** +** The records associated with INSERT changes are in the same format as for +** changesets. It is not possible for a record associated with an INSERT +** change to contain a field set to "undefined". */ /* diff --git a/manifest b/manifest index b53ebc56fc..a9ab76b4a8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sproblems\sin\sthe\ssessions\smodule\scausing\sit\sto\sproduce\sspurious\sSQLITE_NOMEM\serrors\swhen\shandling\sSQL\stext\sor\sblob\svalues\szero\sbytes\sin\ssize. -D 2015-04-08T16:43:31.690 +C Updates\sto\scomments\sdescribing\sthe\schangeset\sand\spatchset\sformats. +D 2015-04-09T19:19:22.574 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 3083cf0c2bc6618e532b9478ce735bb512322985 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -160,7 +160,7 @@ F ext/session/sessionB.test 06961b7c3641151f5d23088250ecad132501113c F ext/session/sessionC.test 3982f8577b0744c5ce3aaef7cfeb5bd903f17fe4 F ext/session/session_common.tcl 9de0451b6a47218fc16b9ed8876b6238a0a3d88d F ext/session/sessionfault.test bef044d0952c0d62c31c8d2400be72c8684545cc -F ext/session/sqlite3session.c 7c6516f0342772441bcd2d845760902cfc0b39b8 +F ext/session/sqlite3session.c 27eb71e164a8e05d344c6254e8f906f093dfd4d1 F ext/session/sqlite3session.h 16608d29879a0ed3c6be6b7fb18dcdb5c707aaef F ext/session/test_session.c a28352e99bc6a83b94e4cce99a7bf25c73d6d489 F ext/userauth/sqlite3userauth.h 19cb6f0e31316d0ee4afdfb7a85ef9da3333a220 @@ -1267,7 +1267,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P aeca95ac77f6f320a916f7e3c5a7a588ef4a20c8 -R 2b6c500da0e9b0a3fd57accc4dad1058 +P b9459d5980c6249a5c1bc5ea72cb4f3b1ba0e433 +R a602d0c91e77a7e6222a205b1b755ccf U dan -Z aded3edd721aa55f05087866d9fe12cb +Z 08fe7407f1e8070b595e48c16318a0a6 diff --git a/manifest.uuid b/manifest.uuid index 27eccb5ef6..7812248cad 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b9459d5980c6249a5c1bc5ea72cb4f3b1ba0e433 \ No newline at end of file +5342f721e878b52f207731ea57411f3669ae3f3f \ No newline at end of file From 92f283c0d4d4f9bf552e168c845cae5ef6ad98e0 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 16 Apr 2015 13:52:03 +0000 Subject: [PATCH 0133/1484] Fix a stray backslash character in a printf format string in sessionDiffFindModified() FossilOrigin-Name: abb192a1d79388d4717f459b91e34f9c035935f2 --- ext/session/sqlite3session.c | 2 +- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index 28b3af9d87..9a367cfb1c 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -1417,7 +1417,7 @@ static int sessionDiffFindModified( rc = SQLITE_NOMEM; }else{ char *zStmt = sqlite3_mprintf( - "SELECT * FROM \"%w\".\"%w\", \"%w\".\"\%w\" WHERE %s AND %z", + "SELECT * FROM \"%w\".\"%w\", \"%w\".\"%w\" WHERE %s AND %z", pSession->zDb, pTab->zName, zFrom, pTab->zName, zExpr, zExpr2 ); if( zStmt==0 ){ diff --git a/manifest b/manifest index f673b417e6..2e4c25c168 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sall\srecent\strunk\sfixes\sand\senhancements\sinto\sthe\ssessions\sbranch. -D 2015-04-15T14:14:38.449 +C Fix\sa\sstray\sbackslash\scharacter\sin\sa\sprintf\sformat\sstring\sin\nsessionDiffFindModified() +D 2015-04-16T13:52:03.882 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 7e23076b9c9dd5c1901c78cf6cdd64d616e5a539 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -161,7 +161,7 @@ F ext/session/sessionC.test 3982f8577b0744c5ce3aaef7cfeb5bd903f17fe4 F ext/session/sessionD.test 95903bd6a23dadbda7e192f730dd7dedd2d369ef F ext/session/session_common.tcl 9de0451b6a47218fc16b9ed8876b6238a0a3d88d F ext/session/sessionfault.test bef044d0952c0d62c31c8d2400be72c8684545cc -F ext/session/sqlite3session.c 2266fca2cb730f3c88423725453bb31c7e820583 +F ext/session/sqlite3session.c 7c82934f4cff05cfbb58bde7562de0964bb7fb32 F ext/session/sqlite3session.h d9ebd8d4c5791aafdf18165575c7f2223c09279b F ext/session/test_session.c 037fc25340a918eb2195972fed439d7adf7b5db9 F ext/userauth/sqlite3userauth.h 19cb6f0e31316d0ee4afdfb7a85ef9da3333a220 @@ -1269,7 +1269,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 5f14f34f072921e229bc20a5185c0cdb3f464c04 bd06eeb8d06237dc2d54d8a03e8bf525cb811c9e -R 9a2dfdee602d304934edbae48280a16c +P e65e65f9bc9b4bf5c9dd6e3a77a0d5f03c40e006 +R 25456e7e52fcd9fbd64c7561e09a3c2d U drh -Z 3665d5b1b05a141bd80e3d7f627d8145 +Z 6d1f041621c8223ff5e5a995b79f05ad diff --git a/manifest.uuid b/manifest.uuid index bcb504ccb4..02efefc93d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e65e65f9bc9b4bf5c9dd6e3a77a0d5f03c40e006 \ No newline at end of file +abb192a1d79388d4717f459b91e34f9c035935f2 \ No newline at end of file From 10dc553c13ae43064717f173ebd7717c97fbf63b Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 17 Apr 2015 11:31:08 +0000 Subject: [PATCH 0134/1484] Hold the database mutex for the duration of sqlite3session_diff(). FossilOrigin-Name: 6f33050115562833c43da3c99dd37aeb0bf966b6 --- ext/session/sqlite3session.c | 2 ++ manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index 9a367cfb1c..a07e1e84d6 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -1455,6 +1455,7 @@ int sqlite3session_diff( memset(&d, 0, sizeof(d)); sessionDiffHooks(pSession, &d); + sqlite3_mutex_enter(sqlite3_db_mutex(pSession->db)); if( pzErrMsg ) *pzErrMsg = 0; if( rc==SQLITE_OK ){ char *zExpr = 0; @@ -1521,6 +1522,7 @@ int sqlite3session_diff( diff_out: sessionPreupdateHooks(pSession); + sqlite3_mutex_leave(sqlite3_db_mutex(pSession->db)); return rc; } diff --git a/manifest b/manifest index 2e4c25c168..ee05b48b56 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sstray\sbackslash\scharacter\sin\sa\sprintf\sformat\sstring\sin\nsessionDiffFindModified() -D 2015-04-16T13:52:03.882 +C Hold\sthe\sdatabase\smutex\sfor\sthe\sduration\sof\ssqlite3session_diff(). +D 2015-04-17T11:31:08.304 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 7e23076b9c9dd5c1901c78cf6cdd64d616e5a539 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -161,7 +161,7 @@ F ext/session/sessionC.test 3982f8577b0744c5ce3aaef7cfeb5bd903f17fe4 F ext/session/sessionD.test 95903bd6a23dadbda7e192f730dd7dedd2d369ef F ext/session/session_common.tcl 9de0451b6a47218fc16b9ed8876b6238a0a3d88d F ext/session/sessionfault.test bef044d0952c0d62c31c8d2400be72c8684545cc -F ext/session/sqlite3session.c 7c82934f4cff05cfbb58bde7562de0964bb7fb32 +F ext/session/sqlite3session.c 2ad7285103457129c636a2367d40f3b9c459b256 F ext/session/sqlite3session.h d9ebd8d4c5791aafdf18165575c7f2223c09279b F ext/session/test_session.c 037fc25340a918eb2195972fed439d7adf7b5db9 F ext/userauth/sqlite3userauth.h 19cb6f0e31316d0ee4afdfb7a85ef9da3333a220 @@ -1269,7 +1269,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P e65e65f9bc9b4bf5c9dd6e3a77a0d5f03c40e006 -R 25456e7e52fcd9fbd64c7561e09a3c2d -U drh -Z 6d1f041621c8223ff5e5a995b79f05ad +P abb192a1d79388d4717f459b91e34f9c035935f2 +R 39574ad38832f7643b0bd124d608871c +U dan +Z 2a1b149e99da178a1dea33510073d75a diff --git a/manifest.uuid b/manifest.uuid index 02efefc93d..db862f34a6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -abb192a1d79388d4717f459b91e34f9c035935f2 \ No newline at end of file +6f33050115562833c43da3c99dd37aeb0bf966b6 \ No newline at end of file From dd009f839c988874c3cfd83acc1969ac57df9fe1 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 23 Apr 2015 14:40:17 +0000 Subject: [PATCH 0135/1484] Fix a performance problem in sqlite3session_diff(). FossilOrigin-Name: ea400eca314d81761fe5c0e329b906c045f0dfe4 --- ext/session/sessionD.test | 38 ++++++++++++++++++++++++++++++++++++ ext/session/sqlite3session.c | 2 +- manifest | 16 +++++++-------- manifest.uuid | 2 +- 4 files changed, 48 insertions(+), 10 deletions(-) diff --git a/ext/session/sessionD.test b/ext/session/sessionD.test index c26728742a..aab9fdaea8 100644 --- a/ext/session/sessionD.test +++ b/ext/session/sessionD.test @@ -65,6 +65,25 @@ proc do_diff_test {tn setup} { uplevel do_test $tn.2 [list {scksum db aux}] [list $cksum] } +# Ensure that the diff produced by comparing the current contents of [db] +# with itself is empty. +proc do_empty_diff_test {tn} { + forcedelete test.db2 + forcecopy test.db test.db2 + + execsql { ATTACH 'test.db2' AS aux } + sqlite3session S db main + foreach tbl [db eval {SELECT name FROM sqlite_master WHERE type='table'}] { + S attach $tbl + S diff aux $tbl + } + + set ::C [S changeset] + S delete + + uplevel [list do_test $tn {string length $::C} 0] +} + forcedelete test.db2 do_execsql_test 1.0 { @@ -146,5 +165,24 @@ do_diff_test 2.4 { VALUES('ckmqmzoeuvxisxqy',X'EB5A5D3A1DD22FD1','tidgtsplhjcbvbppdt',-642987.3); } +reset_db +do_execsql_test 3.0 { + CREATE TABLE t1(a, b, c, PRIMARY KEY(a)); + INSERT INTO t1 VALUES(1, 2, 3); + INSERT INTO t1 VALUES(4, 5, 6); + INSERT INTO t1 VALUES(7, 8, 9); + + CREATE TABLE t2(a, b, c, PRIMARY KEY(a, b)); + INSERT INTO t2 VALUES(1, 2, 3); + INSERT INTO t2 VALUES(4, 5, 6); + INSERT INTO t2 VALUES(7, 8, 9); + + CREATE TABLE t3(a, b, c, PRIMARY KEY(a, b, c)); + INSERT INTO t3 VALUES(1, 2, 3); + INSERT INTO t3 VALUES(4, 5, 6); + INSERT INTO t3 VALUES(7, 8, 9); +} +do_empty_diff_test 3.1 + finish_test diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index a07e1e84d6..70bd250e34 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -1417,7 +1417,7 @@ static int sessionDiffFindModified( rc = SQLITE_NOMEM; }else{ char *zStmt = sqlite3_mprintf( - "SELECT * FROM \"%w\".\"%w\", \"%w\".\"%w\" WHERE %s AND %z", + "SELECT * FROM \"%w\".\"%w\", \"%w\".\"%w\" WHERE %s AND (%z)", pSession->zDb, pTab->zName, zFrom, pTab->zName, zExpr, zExpr2 ); if( zStmt==0 ){ diff --git a/manifest b/manifest index 3a0b76390b..d6c7250535 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sthe\slatest\strunk\senhancements\sand\sfixes\sinto\sthe\ssessions\sbranch. -D 2015-04-23T13:49:53.138 +C Fix\sa\sperformance\sproblem\sin\ssqlite3session_diff(). +D 2015-04-23T14:40:17.627 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 7599f0c96df628cd543884b1b2f2a2fbffd00079 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -158,10 +158,10 @@ F ext/session/session9.test 5409d90d8141881d08285ed1c2c0d8d10fb92069 F ext/session/sessionA.test 1feeab0b8e03527f08f2f1defb442da25480138f F ext/session/sessionB.test 06961b7c3641151f5d23088250ecad132501113c F ext/session/sessionC.test 3982f8577b0744c5ce3aaef7cfeb5bd903f17fe4 -F ext/session/sessionD.test 95903bd6a23dadbda7e192f730dd7dedd2d369ef +F ext/session/sessionD.test 197781b4823fbf0003a21da0e4360b37d0e0a81f F ext/session/session_common.tcl 9de0451b6a47218fc16b9ed8876b6238a0a3d88d F ext/session/sessionfault.test bef044d0952c0d62c31c8d2400be72c8684545cc -F ext/session/sqlite3session.c 2ad7285103457129c636a2367d40f3b9c459b256 +F ext/session/sqlite3session.c de11ba62d7bf5b9a5d732411550771d4ee6b412a F ext/session/sqlite3session.h d9ebd8d4c5791aafdf18165575c7f2223c09279b F ext/session/test_session.c 037fc25340a918eb2195972fed439d7adf7b5db9 F ext/userauth/sqlite3userauth.h 19cb6f0e31316d0ee4afdfb7a85ef9da3333a220 @@ -1271,7 +1271,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P b8ef1cdee307441e8d97b4bfc21f8547692eea9f b5e43602833249aa4b73337bf85b7f308450dab6 -R 21546caf070f5228972b31b0602e8636 -U drh -Z 47f4cbb84ecfe918df05ce03c5e0cd26 +P 4e5f17d189eb0578a544c21fc150f9e2ee3428e3 +R bb0c0c482394af2863743ccd1d1a9362 +U dan +Z ee0bd6bc3557d1b9872d331b62e53091 diff --git a/manifest.uuid b/manifest.uuid index f5eb052979..e79db0245b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4e5f17d189eb0578a544c21fc150f9e2ee3428e3 \ No newline at end of file +ea400eca314d81761fe5c0e329b906c045f0dfe4 \ No newline at end of file From 4cc923e3e3cb6dd54779c8b74cbbfbbcea979754 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 23 Apr 2015 15:03:14 +0000 Subject: [PATCH 0136/1484] Fix the error message returned by sqlite3session_diff() for tables with no PRIMARY KEY. FossilOrigin-Name: 4d34a3d40da210bebb2a2e6dff094f9a39c92798 --- ext/session/sessionD.test | 31 +++++++++++++++++++++++++++++++ ext/session/sqlite3session.c | 9 ++++++++- ext/session/test_session.c | 1 + manifest | 16 ++++++++-------- manifest.uuid | 2 +- 5 files changed, 49 insertions(+), 10 deletions(-) diff --git a/ext/session/sessionD.test b/ext/session/sessionD.test index aab9fdaea8..6fc47075d5 100644 --- a/ext/session/sessionD.test +++ b/ext/session/sessionD.test @@ -184,5 +184,36 @@ do_execsql_test 3.0 { } do_empty_diff_test 3.1 + +#------------------------------------------------------------------------- +# Test some error cases: +# +# 1) schema mismatches between the two dbs, and +# 2) tables with no primary keys. +# +reset_db +forcedelete test.db2 +do_execsql_test 4.0 { + ATTACH 'test.db2' AS ixua; + CREATE TABLE ixua.t1(a, b, c); + CREATE TABLE main.t1(a, b, c); + + CREATE TABLE ixua.t2(a PRIMARY KEY, b, c); + CREATE TABLE main.t2(a PRIMARY KEY, b, x); +} + +do_test 4.1 { + sqlite3session S db main + S attach t1 + list [catch { S diff ixua t1 } msg] $msg +} {1 {table has no primary key}} + +do_test 4.2 { + S attach t2 + list [catch { S diff ixua t2 } msg] $msg +} {1 {table schemas do not match}} + +S delete + finish_test diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index 70bd250e34..f5a6096611 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -1473,18 +1473,21 @@ int sqlite3session_diff( /* Check the table schemas match */ if( rc==SQLITE_OK ){ + int bHasPk = 0; int nCol; /* Columns in zFrom.zTbl */ u8 *abPK; const char **azCol = 0; rc = sessionTableInfo(db, zFrom, zTbl, &nCol, 0, &azCol, &abPK); if( rc==SQLITE_OK ){ int bMismatch = 0; - if( pTo->nCol!=nCol || memcmp(pTo->abPK, abPK, nCol) ){ + if( pTo->nCol!=nCol ){ bMismatch = 1; }else{ int i; for(i=0; iabPK[i]!=abPK[i] ) bMismatch = 1; if( sqlite3_stricmp(azCol[i], pTo->azCol[i]) ) bMismatch = 1; + if( abPK[i] ) bHasPk = 1; } } @@ -1492,6 +1495,10 @@ int sqlite3session_diff( *pzErrMsg = sqlite3_mprintf("table schemas do not match"); rc = SQLITE_ERROR; } + if( bHasPk==0 ){ + *pzErrMsg = sqlite3_mprintf("table has no primary key"); + rc = SQLITE_ERROR; + } } sqlite3_free(azCol); } diff --git a/ext/session/test_session.c b/ext/session/test_session.c index 3dc24fc69e..b3f2533ff5 100644 --- a/ext/session/test_session.c +++ b/ext/session/test_session.c @@ -228,6 +228,7 @@ static int test_session_cmd( assert( rc!=SQLITE_OK || zErr==0 ); if( zErr ){ Tcl_AppendResult(interp, zErr, 0); + sqlite3_free(zErr); return TCL_ERROR; } if( rc ){ diff --git a/manifest b/manifest index d6c7250535..5b54ca3c2e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sperformance\sproblem\sin\ssqlite3session_diff(). -D 2015-04-23T14:40:17.627 +C Fix\sthe\serror\smessage\sreturned\sby\ssqlite3session_diff()\sfor\stables\swith\sno\sPRIMARY\sKEY. +D 2015-04-23T15:03:14.997 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 7599f0c96df628cd543884b1b2f2a2fbffd00079 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -158,12 +158,12 @@ F ext/session/session9.test 5409d90d8141881d08285ed1c2c0d8d10fb92069 F ext/session/sessionA.test 1feeab0b8e03527f08f2f1defb442da25480138f F ext/session/sessionB.test 06961b7c3641151f5d23088250ecad132501113c F ext/session/sessionC.test 3982f8577b0744c5ce3aaef7cfeb5bd903f17fe4 -F ext/session/sessionD.test 197781b4823fbf0003a21da0e4360b37d0e0a81f +F ext/session/sessionD.test bdc20e2384bf92b5719b9e41ad3b18cd9188cf26 F ext/session/session_common.tcl 9de0451b6a47218fc16b9ed8876b6238a0a3d88d F ext/session/sessionfault.test bef044d0952c0d62c31c8d2400be72c8684545cc -F ext/session/sqlite3session.c de11ba62d7bf5b9a5d732411550771d4ee6b412a +F ext/session/sqlite3session.c 0b26c45c0c3c0b2afaae9bd69ae1e80a6b8e9b5a F ext/session/sqlite3session.h d9ebd8d4c5791aafdf18165575c7f2223c09279b -F ext/session/test_session.c 037fc25340a918eb2195972fed439d7adf7b5db9 +F ext/session/test_session.c 67a049635d910c55917f23d067575ab5432d4546 F ext/userauth/sqlite3userauth.h 19cb6f0e31316d0ee4afdfb7a85ef9da3333a220 F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04 F ext/userauth/userauth.c 5fa3bdb492f481bbc1709fc83c91ebd13460c69e @@ -1271,7 +1271,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 4e5f17d189eb0578a544c21fc150f9e2ee3428e3 -R bb0c0c482394af2863743ccd1d1a9362 +P ea400eca314d81761fe5c0e329b906c045f0dfe4 +R 57c462c26b9985ec1f9daf86d6b971a1 U dan -Z ee0bd6bc3557d1b9872d331b62e53091 +Z dd15ced7dcdddbd36a44e0c8439b0673 diff --git a/manifest.uuid b/manifest.uuid index e79db0245b..9d7404abb8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ea400eca314d81761fe5c0e329b906c045f0dfe4 \ No newline at end of file +4d34a3d40da210bebb2a2e6dff094f9a39c92798 \ No newline at end of file From b9db90995254891621c116039cef50b5c3606db1 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 23 Apr 2015 17:22:49 +0000 Subject: [PATCH 0137/1484] Modify the sqlite3session_diff() API so that tables with no PRIMARY KEYs are ignored. This matches the other sessions APIs. Also change sqlite3session_diff() so that it returns SQLITE_SCHEMA, instead of SQLITE_ERROR, if the tables being compared do not have compatible schemas. FossilOrigin-Name: aada0ad08e3baa10d14d1f3393183110289e068e --- ext/session/sessionD.test | 18 ++++++++++++------ ext/session/sqlite3session.c | 18 +++++++++--------- ext/session/sqlite3session.h | 5 +++++ ext/session/test_session.c | 31 +++++++++++++++---------------- manifest | 18 +++++++++--------- manifest.uuid | 2 +- 6 files changed, 51 insertions(+), 41 deletions(-) diff --git a/ext/session/sessionD.test b/ext/session/sessionD.test index 6fc47075d5..b8572782e2 100644 --- a/ext/session/sessionD.test +++ b/ext/session/sessionD.test @@ -189,7 +189,8 @@ do_empty_diff_test 3.1 # Test some error cases: # # 1) schema mismatches between the two dbs, and -# 2) tables with no primary keys. +# 2) tables with no primary keys. This is not actually an error, but +# should not add any changes to the session object. # reset_db forcedelete test.db2 @@ -197,22 +198,27 @@ do_execsql_test 4.0 { ATTACH 'test.db2' AS ixua; CREATE TABLE ixua.t1(a, b, c); CREATE TABLE main.t1(a, b, c); + INSERT INTO main.t1 VALUES(1, 2, 3); CREATE TABLE ixua.t2(a PRIMARY KEY, b, c); CREATE TABLE main.t2(a PRIMARY KEY, b, x); } -do_test 4.1 { +do_test 4.1.1 { sqlite3session S db main S attach t1 list [catch { S diff ixua t1 } msg] $msg -} {1 {table has no primary key}} +} {0 {}} +do_test 4.1.2 { + string length [S changeset] +} {0} +S delete -do_test 4.2 { +do_test 4.2.2 { + sqlite3session S db main S attach t2 list [catch { S diff ixua t2 } msg] $msg -} {1 {table schemas do not match}} - +} {1 {SQLITE_SCHEMA - table schemas do not match}} S delete finish_test diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index f5a6096611..b5a1b9dfa3 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -1474,12 +1474,12 @@ int sqlite3session_diff( /* Check the table schemas match */ if( rc==SQLITE_OK ){ int bHasPk = 0; + int bMismatch = 0; int nCol; /* Columns in zFrom.zTbl */ u8 *abPK; const char **azCol = 0; rc = sessionTableInfo(db, zFrom, zTbl, &nCol, 0, &azCol, &abPK); if( rc==SQLITE_OK ){ - int bMismatch = 0; if( pTo->nCol!=nCol ){ bMismatch = 1; }else{ @@ -1491,16 +1491,16 @@ int sqlite3session_diff( } } - if( bMismatch ){ - *pzErrMsg = sqlite3_mprintf("table schemas do not match"); - rc = SQLITE_ERROR; - } - if( bHasPk==0 ){ - *pzErrMsg = sqlite3_mprintf("table has no primary key"); - rc = SQLITE_ERROR; - } } sqlite3_free(azCol); + if( bMismatch ){ + *pzErrMsg = sqlite3_mprintf("table schemas do not match"); + rc = SQLITE_SCHEMA; + } + if( bHasPk==0 ){ + /* Ignore tables with no primary keys */ + goto diff_out; + } } if( rc==SQLITE_OK ){ diff --git a/ext/session/sqlite3session.h b/ext/session/sqlite3session.h index ed1c5d917c..c8ce488ba7 100644 --- a/ext/session/sqlite3session.h +++ b/ext/session/sqlite3session.h @@ -293,6 +293,11 @@ int sqlite3session_changeset( **
  • Has the same PRIMARY KEY definition. ** ** +** If the tables are not compatible, SQLITE_SCHEMA is returned. If the tables +** are compatible but do not have any PRIMARY KEY columns, it is not an error +** but no changes are added to the session object. As with other session +** APIs, tables without PRIMARY KEYs are simply ignored. +** ** This function adds a set of changes to the session object that could be ** used to update the table in database zFrom (call this the "from-table") ** so that its content is the same as the table attached to the session diff --git a/ext/session/test_session.c b/ext/session/test_session.c index b3f2533ff5..15f7b6f575 100644 --- a/ext/session/test_session.c +++ b/ext/session/test_session.c @@ -39,9 +39,13 @@ static int test_tcl_integer(Tcl_Interp *interp, const char *zVar){ return iVal; } -static int test_session_error(Tcl_Interp *interp, int rc){ +static int test_session_error(Tcl_Interp *interp, int rc, char *zErr){ extern const char *sqlite3ErrName(int); Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1)); + if( zErr ){ + Tcl_AppendResult(interp, " - ", zErr, 0); + sqlite3_free(zErr); + } return TCL_ERROR; } @@ -150,7 +154,7 @@ static int test_session_cmd( if( zArg[0]=='*' && zArg[1]=='\0' ) zArg = 0; rc = sqlite3session_attach(pSession, zArg); if( rc!=SQLITE_OK ){ - return test_session_error(interp, rc); + return test_session_error(interp, rc, 0); } break; } @@ -177,7 +181,7 @@ static int test_session_cmd( } sqlite3_free(o.p); if( rc!=SQLITE_OK ){ - return test_session_error(interp, rc); + return test_session_error(interp, rc, 0); } break; } @@ -226,13 +230,8 @@ static int test_session_cmd( &zErr ); assert( rc!=SQLITE_OK || zErr==0 ); - if( zErr ){ - Tcl_AppendResult(interp, zErr, 0); - sqlite3_free(zErr); - return TCL_ERROR; - } if( rc ){ - return test_session_error(interp, rc); + return test_session_error(interp, rc, zErr); } break; } @@ -278,7 +277,7 @@ static int test_sqlite3session( rc = sqlite3session_create(db, Tcl_GetString(objv[3]), &p->pSession); if( rc!=SQLITE_OK ){ ckfree((char*)p); - return test_session_error(interp, rc); + return test_session_error(interp, rc, 0); } Tcl_CreateObjCommand( @@ -652,7 +651,7 @@ static int test_sqlite3changeset_apply( } if( rc!=SQLITE_OK ){ - return test_session_error(interp, rc); + return test_session_error(interp, rc, 0); } Tcl_ResetResult(interp); return TCL_OK; @@ -686,7 +685,7 @@ static int test_sqlite3changeset_apply_replace_all( rc = sqlite3changeset_apply(db, nChangeset, pChangeset, 0, replace_handler,0); if( rc!=SQLITE_OK ){ - return test_session_error(interp, rc); + return test_session_error(interp, rc, 0); } Tcl_ResetResult(interp); return TCL_OK; @@ -724,7 +723,7 @@ static int test_sqlite3changeset_invert( rc = sqlite3changeset_invert(sIn.nData, sIn.aData, &sOut.n, &sOut.p); } if( rc!=SQLITE_OK ){ - rc = test_session_error(interp, rc); + rc = test_session_error(interp, rc, 0); }else{ Tcl_SetObjResult(interp,Tcl_NewByteArrayObj((unsigned char*)sOut.p,sOut.n)); } @@ -772,7 +771,7 @@ static int test_sqlite3changeset_concat( } if( rc!=SQLITE_OK ){ - rc = test_session_error(interp, rc); + rc = test_session_error(interp, rc, 0); }else{ Tcl_SetObjResult(interp,Tcl_NewByteArrayObj((unsigned char*)sOut.p,sOut.n)); } @@ -824,7 +823,7 @@ static int test_sqlite3session_foreach( rc = sqlite3changeset_start_strm(&pIter, testStreamInput, (void*)&sStr); } if( rc!=SQLITE_OK ){ - return test_session_error(interp, rc); + return test_session_error(interp, rc, 0); } while( SQLITE_ROW==sqlite3changeset_next(pIter) ){ @@ -907,7 +906,7 @@ static int test_sqlite3session_foreach( rc = sqlite3changeset_finalize(pIter); } if( rc!=SQLITE_OK ){ - return test_session_error(interp, rc); + return test_session_error(interp, rc, 0); } return TCL_OK; diff --git a/manifest b/manifest index 5b54ca3c2e..cc09519aa2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\serror\smessage\sreturned\sby\ssqlite3session_diff()\sfor\stables\swith\sno\sPRIMARY\sKEY. -D 2015-04-23T15:03:14.997 +C Modify\sthe\ssqlite3session_diff()\sAPI\sso\sthat\stables\swith\sno\sPRIMARY\sKEYs\sare\signored.\sThis\smatches\sthe\sother\ssessions\sAPIs.\sAlso\schange\ssqlite3session_diff()\sso\sthat\sit\sreturns\sSQLITE_SCHEMA,\sinstead\sof\sSQLITE_ERROR,\sif\sthe\stables\sbeing\scompared\sdo\snot\shave\scompatible\sschemas. +D 2015-04-23T17:22:50.000 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 7599f0c96df628cd543884b1b2f2a2fbffd00079 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -158,12 +158,12 @@ F ext/session/session9.test 5409d90d8141881d08285ed1c2c0d8d10fb92069 F ext/session/sessionA.test 1feeab0b8e03527f08f2f1defb442da25480138f F ext/session/sessionB.test 06961b7c3641151f5d23088250ecad132501113c F ext/session/sessionC.test 3982f8577b0744c5ce3aaef7cfeb5bd903f17fe4 -F ext/session/sessionD.test bdc20e2384bf92b5719b9e41ad3b18cd9188cf26 +F ext/session/sessionD.test d4744c78334162851d2a2f285c7e603e31b49aa2 F ext/session/session_common.tcl 9de0451b6a47218fc16b9ed8876b6238a0a3d88d F ext/session/sessionfault.test bef044d0952c0d62c31c8d2400be72c8684545cc -F ext/session/sqlite3session.c 0b26c45c0c3c0b2afaae9bd69ae1e80a6b8e9b5a -F ext/session/sqlite3session.h d9ebd8d4c5791aafdf18165575c7f2223c09279b -F ext/session/test_session.c 67a049635d910c55917f23d067575ab5432d4546 +F ext/session/sqlite3session.c d22a8996f44202a13d0b1ad18757cd509729a23c +F ext/session/sqlite3session.h 8e86f9eec3ed71f1f30eefbe810cbe5bc10b5aa9 +F ext/session/test_session.c 187bd344c5ae9d5be85e22ef7c3010f0c17307ce F ext/userauth/sqlite3userauth.h 19cb6f0e31316d0ee4afdfb7a85ef9da3333a220 F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04 F ext/userauth/userauth.c 5fa3bdb492f481bbc1709fc83c91ebd13460c69e @@ -1271,7 +1271,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P ea400eca314d81761fe5c0e329b906c045f0dfe4 -R 57c462c26b9985ec1f9daf86d6b971a1 +P 4d34a3d40da210bebb2a2e6dff094f9a39c92798 +R 77fdc1b8d856af82047ddfafb467bba9 U dan -Z dd15ced7dcdddbd36a44e0c8439b0673 +Z c001be8d13359c151923937b5aa6a277 diff --git a/manifest.uuid b/manifest.uuid index 9d7404abb8..ef8da808c5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4d34a3d40da210bebb2a2e6dff094f9a39c92798 \ No newline at end of file +aada0ad08e3baa10d14d1f3393183110289e068e \ No newline at end of file From 6dc29e60c813032d8bbdd98a14f42e1c9c5ed018 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 2 Jun 2015 09:19:22 +0000 Subject: [PATCH 0138/1484] Modify the sessions module to ignore all operations on tables with no primary keys as documented. FossilOrigin-Name: bdaf9575cd9ebb33dc5da4062a84bca79e7b0fec --- ext/session/session1.test | 51 ++++++++++++--- ext/session/sessionE.test | 116 +++++++++++++++++++++++++++++++++ ext/session/session_common.tcl | 10 +++ ext/session/sqlite3session.c | 51 ++++++++------- manifest | 19 +++--- manifest.uuid | 2 +- 6 files changed, 207 insertions(+), 42 deletions(-) create mode 100644 ext/session/sessionE.test diff --git a/ext/session/session1.test b/ext/session/session1.test index 1c853a97a1..fc74a1e84e 100644 --- a/ext/session/session1.test +++ b/ext/session/session1.test @@ -20,16 +20,6 @@ ifcapable !session {finish_test; return} set testprefix session1 -proc do_changeset_test {tn session res} { - set r [list] - foreach x $res {lappend r $x} - uplevel do_test $tn [list [subst -nocommands { - set x [list] - sqlite3session_foreach c [$session changeset] { lappend x [set c] } - set x - }]] [list $r] -} - proc do_changeset_invert_test {tn session res} { set r [list] foreach x $res {lappend r $x} @@ -525,6 +515,47 @@ do_changeset_test 9.2 S {{UPDATE t7 0 ....X.. {{} {} i 1 {} {} i 1 i 1 {} {} {} S delete catch { db2 close } +#------------------------------------------------------------------------- +# Test a really long table name. +# +reset_db +set tblname [string repeat tblname123 100] +do_test 10.1.1 { + execsql " + CREATE TABLE $tblname (a PRIMARY KEY, b); + INSERT INTO $tblname VALUES('xyz', 'def'); + " + sqlite3session S db main + S attach $tblname + execsql " + INSERT INTO $tblname VALUES('uvw', 'abc'); + DELETE FROM $tblname WHERE a = 'xyz'; + " +} {} +breakpoint +do_changeset_test 10.1.2 S " + {INSERT $tblname 0 X. {} {t uvw t abc}} + {DELETE $tblname 0 X. {t xyz t def} {}} +" +do_test 10.1.4 { S delete } {} + +#--------------------------------------------------------------- +reset_db +do_execsql_test 11.1 { + CREATE TABLE t1(a, b); +} +do_test 11.2 { + sqlite3session S db main + S attach t1 + execsql { + INSERT INTO t1 VALUES(1, 2); + } + S changeset +} {} + +S delete + + #------------------------------------------------------------------------- # Test a really long table name. # diff --git a/ext/session/sessionE.test b/ext/session/sessionE.test new file mode 100644 index 0000000000..57962eb6ba --- /dev/null +++ b/ext/session/sessionE.test @@ -0,0 +1,116 @@ +# 2015 June 02 +# +# 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 regression tests for the sessions module. +# Specifically, it tests that operations on tables without primary keys +# are ignored. +# + + + +if {![info exists testdir]} { + set testdir [file join [file dirname [info script]] .. .. test] +} +source [file join [file dirname [info script]] session_common.tcl] +source $testdir/tester.tcl +ifcapable !session {finish_test; return} +set testprefix sessionE + +# +# Test plan: +# +# 1.*: Test that non-PK tables are not auto-attached. +# 2.*: Test that explicitly attaching a non-PK table is a no-op. +# 3.*: Test that sqlite3session_diff() on a non-PK table is a no-op. +# + + +#-------------------------------------------------------------------------- +reset_db +do_execsql_test 1.0 { + CREATE TABLE t1(a, b); + CREATE TABLE t2(a PRIMARY KEY, b); +} +do_test 1.1 { + sqlite3session S db main + S attach * + breakpoint + execsql { + INSERT INTO t1 VALUES(1, 2); + INSERT INTO t2 VALUES(1, 2); + } +} {} +do_changeset_test 1.2 S { + {INSERT t2 0 X. {} {i 1 i 2}} +} +S delete + +reset_db +do_execsql_test 2.0 { + CREATE TABLE t1(a, b); + CREATE TABLE t2(a PRIMARY KEY, b); +} +do_test 2.1 { + sqlite3session S db main + S attach t1 + S attach t2 + breakpoint + execsql { + INSERT INTO t1 VALUES(3, 4); + INSERT INTO t2 VALUES(3, 4); + INSERT INTO t1 VALUES(5, 6); + INSERT INTO t2 VALUES(5, 6); + } +} {} +do_changeset_test 2.2 S { + {INSERT t2 0 X. {} {i 3 i 4}} + {INSERT t2 0 X. {} {i 5 i 6}} +} +S delete + +reset_db +forcedelete test.db2 +do_execsql_test 3.0 { + ATTACH 'test.db2' AS aux; + CREATE TABLE aux.t1(a, b); + CREATE TABLE aux.t2(a PRIMARY KEY, b); + + CREATE TABLE t1(a, b); + CREATE TABLE t2(a PRIMARY KEY, b); + + INSERT INTO t1 VALUES(1, 2); + INSERT INTO t2 VALUES(3, 4); +} +do_test 3.1 { + sqlite3session S db main + S attach t1 + S diff aux t1 + + S attach t2 + S diff aux t2 +} {} +do_changeset_test 3.2 S { + {INSERT t2 0 X. {} {i 3 i 4}} +} +do_execsql_test 3.3 { + INSERT INTO t1 VALUES(5, 6); + INSERT INTO t2 VALUES(7, 8); +} +do_changeset_test 3.4 S { + {INSERT t2 0 X. {} {i 3 i 4}} + {INSERT t2 0 X. {} {i 7 i 8}} +} + + +S delete + + + diff --git a/ext/session/session_common.tcl b/ext/session/session_common.tcl index d6ce27a850..f27ad11dc0 100644 --- a/ext/session/session_common.tcl +++ b/ext/session/session_common.tcl @@ -1,4 +1,14 @@ +proc do_changeset_test {tn session res} { + set r [list] + foreach x $res {lappend r $x} + uplevel do_test $tn [list [subst -nocommands { + set x [list] + sqlite3session_foreach c [$session changeset] { lappend x [set c] } + set x + }]] [list $r] +} + proc do_conflict_test {tn args} { proc xConflict {args} { diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index 287c5929c1..39923ee779 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -1008,32 +1008,33 @@ static int sessionTableInfo( /* ** This function is only called from within a pre-update handler for a ** write to table pTab, part of session pSession. If this is the first -** write to this table, set the SessionTable.nCol variable to the number -** of columns in the table. +** write to this table, initalize the SessionTable.nCol, azCol[] and +** abPK[] arrays accordingly. ** -** Otherwise, if this is not the first time this table has been written -** to, check that the number of columns in the table has not changed. If -** it has not, return zero. -** -** If the number of columns in the table has changed since the last write -** was recorded, set the session error-code to SQLITE_SCHEMA and return -** non-zero. Users are not allowed to change the number of columns in a table -** for which changes are being recorded by the session module. If they do so, -** it is an error. +** If an error occurs, an error code is stored in sqlite3_session.rc and +** non-zero returned. Or, if no error occurs but the table has no primary +** key, sqlite3_session.rc is left set to SQLITE_OK and non-zero returned to +** indicate that updates on this table should be ignored. SessionTable.abPK +** is set to NULL in this case. */ static int sessionInitTable(sqlite3_session *pSession, SessionTable *pTab){ if( pTab->nCol==0 ){ + u8 *abPK; assert( pTab->azCol==0 || pTab->abPK==0 ); pSession->rc = sessionTableInfo(pSession->db, pSession->zDb, - pTab->zName, &pTab->nCol, 0, &pTab->azCol, &pTab->abPK + pTab->zName, &pTab->nCol, 0, &pTab->azCol, &abPK ); + if( pSession->rc==SQLITE_OK ){ + int i; + for(i=0; inCol; i++){ + if( abPK[i] ){ + pTab->abPK = abPK; + break; + } + } + } } - if( pSession->rc==SQLITE_OK - && pTab->nCol!=pSession->hook.xCount(pSession->hook.pCtx) - ){ - pSession->rc = SQLITE_SCHEMA; - } - return pSession->rc; + return (pSession->rc || pTab->abPK==0); } /* @@ -1058,6 +1059,13 @@ static void sessionPreupdateOneChange( /* Load table details if required */ if( sessionInitTable(pSession, pTab) ) return; + /* Check the number of columns in this xPreUpdate call matches the + ** number of columns in the table. */ + if( pTab->nCol!=pSession->hook.xCount(pSession->hook.pCtx) ){ + pSession->rc = SQLITE_SCHEMA; + return; + } + /* Grow the hash table if required */ if( sessionGrowHash(0, pTab) ){ pSession->rc = SQLITE_NOMEM; @@ -1465,10 +1473,9 @@ int sqlite3session_diff( /* Locate and if necessary initialize the target table object */ rc = sessionFindTable(pSession, zTbl, &pTo); if( pTo==0 ) goto diff_out; - if( pTo->nCol==0 ){ - rc = pSession->rc = sessionTableInfo(db, zDb, - pTo->zName, &pTo->nCol, 0, &pTo->azCol, &pTo->abPK - ); + if( sessionInitTable(pSession, pTo) ){ + rc = pSession->rc; + goto diff_out; } /* Check the table schemas match */ diff --git a/manifest b/manifest index 25dfe229ee..434493b0a8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Import\srecent\senhancements\sfrom\strunk. -D 2015-05-29T19:04:58.908 +C Modify\sthe\ssessions\smodule\sto\signore\sall\soperations\son\stables\swith\sno\sprimary\skeys\sas\sdocumented. +D 2015-06-02T09:19:22.231 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 58c16cc8cd876ed112902e70cf33d33f3270b5aa F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -166,7 +166,7 @@ F ext/rtree/sqlite3rtree.h 9c5777af3d2921c7b4ae4954e8e5697502289d28 F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 F ext/session/changeset.c 4ccbaa4531944c24584bf6a61ba3a39c62b6267a -F ext/session/session1.test 4653867f32a98ce4bbb4a181aac6debe51ca4dfb +F ext/session/session1.test d4f53b9b5add7eeb358e535d6e18552142092429 F ext/session/session2.test a95a2d270b32638c1acba7cb9c81856712d469ac F ext/session/session3.test a7a9ce59b8d1e49e2cc23d81421ac485be0eea01 F ext/session/session4.test a6ed685da7a5293c5d6f99855bcf41dbc352ca84 @@ -178,9 +178,10 @@ F ext/session/sessionA.test 1feeab0b8e03527f08f2f1defb442da25480138f F ext/session/sessionB.test 06961b7c3641151f5d23088250ecad132501113c F ext/session/sessionC.test 3982f8577b0744c5ce3aaef7cfeb5bd903f17fe4 F ext/session/sessionD.test d4744c78334162851d2a2f285c7e603e31b49aa2 -F ext/session/session_common.tcl 9de0451b6a47218fc16b9ed8876b6238a0a3d88d +F ext/session/sessionE.test 9ebeae9918f0a07fafc2b5f4a1636fd8bc940804 +F ext/session/session_common.tcl f4b7b59c617edf0c9b00d94cd93498d225d43837 F ext/session/sessionfault.test bef044d0952c0d62c31c8d2400be72c8684545cc -F ext/session/sqlite3session.c 9ccf68d542f4afc5dc14295d984bf37a7db6b936 +F ext/session/sqlite3session.c d630293057fcf4274451edec24c2745953ca042c F ext/session/sqlite3session.h 8e86f9eec3ed71f1f30eefbe810cbe5bc10b5aa9 F ext/session/test_session.c 187bd344c5ae9d5be85e22ef7c3010f0c17307ce F ext/userauth/sqlite3userauth.h 19cb6f0e31316d0ee4afdfb7a85ef9da3333a220 @@ -1300,7 +1301,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 519054bb72e8f8977b11161c81b0e96ba7bca589 09a38bf665902834936d39341627ded88142e6ae -R 8892830f1d56f04b6b2e14d9642ea36b -U drh -Z 5694d275e23a4dea203ff0f897ed1e57 +P 54bec164ebeaf62d783352b3c4d0de8845394091 +R f80d0c3771ea18894e499ba6e9adad71 +U dan +Z e52febd1b018cb0f724ad3d4cfe4ef9d diff --git a/manifest.uuid b/manifest.uuid index 70a7baacb5..d8666bb556 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -54bec164ebeaf62d783352b3c4d0de8845394091 \ No newline at end of file +bdaf9575cd9ebb33dc5da4062a84bca79e7b0fec \ No newline at end of file From 807547038d78f05597ca6e4e578741a21c9ff95c Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 2 Jun 2015 09:20:46 +0000 Subject: [PATCH 0139/1484] Add the "finish_test" command to the end of new test script sessionE.test. FossilOrigin-Name: fb3914070791c84b5f323b7359ac845246d8a844 --- ext/session/sessionE.test | 1 + manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/ext/session/sessionE.test b/ext/session/sessionE.test index 57962eb6ba..27e530ec7f 100644 --- a/ext/session/sessionE.test +++ b/ext/session/sessionE.test @@ -112,5 +112,6 @@ do_changeset_test 3.4 S { S delete +finish_test diff --git a/manifest b/manifest index 434493b0a8..2204ad1cdc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Modify\sthe\ssessions\smodule\sto\signore\sall\soperations\son\stables\swith\sno\sprimary\skeys\sas\sdocumented. -D 2015-06-02T09:19:22.231 +C Add\sthe\s"finish_test"\scommand\sto\sthe\send\sof\snew\stest\sscript\ssessionE.test. +D 2015-06-02T09:20:46.301 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 58c16cc8cd876ed112902e70cf33d33f3270b5aa F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -178,7 +178,7 @@ F ext/session/sessionA.test 1feeab0b8e03527f08f2f1defb442da25480138f F ext/session/sessionB.test 06961b7c3641151f5d23088250ecad132501113c F ext/session/sessionC.test 3982f8577b0744c5ce3aaef7cfeb5bd903f17fe4 F ext/session/sessionD.test d4744c78334162851d2a2f285c7e603e31b49aa2 -F ext/session/sessionE.test 9ebeae9918f0a07fafc2b5f4a1636fd8bc940804 +F ext/session/sessionE.test e60a238c47f0feb3bb707e7f35e22be09c7e8f26 F ext/session/session_common.tcl f4b7b59c617edf0c9b00d94cd93498d225d43837 F ext/session/sessionfault.test bef044d0952c0d62c31c8d2400be72c8684545cc F ext/session/sqlite3session.c d630293057fcf4274451edec24c2745953ca042c @@ -1301,7 +1301,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 54bec164ebeaf62d783352b3c4d0de8845394091 -R f80d0c3771ea18894e499ba6e9adad71 +P bdaf9575cd9ebb33dc5da4062a84bca79e7b0fec +R dbe1b57e21e93824d104fb3b930d73e6 U dan -Z e52febd1b018cb0f724ad3d4cfe4ef9d +Z cd8fea501989560b39f7780ac3d3b3f9 diff --git a/manifest.uuid b/manifest.uuid index d8666bb556..5f700eaf36 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bdaf9575cd9ebb33dc5da4062a84bca79e7b0fec \ No newline at end of file +fb3914070791c84b5f323b7359ac845246d8a844 \ No newline at end of file From 5898ad69543124bd762d91b341401c704cfd1099 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 11 Jun 2015 17:26:10 +0000 Subject: [PATCH 0140/1484] Add the sqlite3changegroup_xxx() APIs to the sessions module. For combining multiple changesets or patchsets. FossilOrigin-Name: 0c1a901cd60e557fc676b97625243163dfe9be9d --- ext/session/sqlite3session.c | 201 ++++++++++++++++++++++--------- ext/session/sqlite3session.h | 226 +++++++++++++++++++++++++---------- manifest | 14 +-- manifest.uuid | 2 +- 4 files changed, 318 insertions(+), 125 deletions(-) diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index 39923ee779..0937c9bb32 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -4045,6 +4045,15 @@ int sqlite3changeset_apply_strm( return rc; } +/* +** sqlite3_changegroup handle. +*/ +struct sqlite3_changegroup { + int rc; /* Error code */ + int bPatch; /* True to accumulate patchsets */ + SessionTable *pList; /* List of tables in current patch */ +}; + /* ** This function is called to merge two changes to the same row together as ** part of an sqlite3changeset_concat() operation. A new change object is @@ -4170,18 +4179,19 @@ static int sessionChangeMerge( } /* -** Add all changes in the changeset passed via the first two arguments to -** hash tables. +** Add all changes in the changeset traversed by the iterator passed as +** the first argument to the changegroup hash tables. */ static int sessionChangesetToHash( sqlite3_changeset_iter *pIter, /* Iterator to read from */ - SessionTable **ppTabList /* IN/OUT: List of table objects */ + sqlite3_changegroup *pGrp /* Changegroup object to add changeset to */ ){ u8 *aRec; int nRec; int rc = SQLITE_OK; SessionTable *pTab = 0; + while( SQLITE_ROW==sessionChangesetNext(pIter, &aRec, &nRec) ){ const char *zNew; int nCol; @@ -4192,6 +4202,13 @@ static int sessionChangesetToHash( SessionChange *pExist = 0; SessionChange **pp; + if( pGrp->pList==0 ){ + pGrp->bPatch = pIter->bPatchset; + }else if( pIter->bPatchset!=pGrp->bPatch ){ + rc = SQLITE_ERROR; + break; + } + sqlite3changeset_op(pIter, &zNew, &nCol, &op, &bIndirect); if( !pTab || sqlite3_stricmp(zNew, pTab->zName) ){ /* Search the list for a matching table */ @@ -4199,7 +4216,7 @@ static int sessionChangesetToHash( u8 *abPK; sqlite3changeset_pk(pIter, &abPK, 0); - for(pTab = *ppTabList; pTab; pTab=pTab->pNext){ + for(pTab = pGrp->pList; pTab; pTab=pTab->pNext){ if( 0==sqlite3_strnicmp(pTab->zName, zNew, nNew+1) ) break; } if( !pTab ){ @@ -4209,13 +4226,13 @@ static int sessionChangesetToHash( break; } memset(pTab, 0, sizeof(SessionTable)); - pTab->pNext = *ppTabList; + pTab->pNext = pGrp->pList; pTab->nCol = nCol; pTab->abPK = (u8*)&pTab[1]; memcpy(pTab->abPK, abPK, nCol); pTab->zName = (char*)&pTab->abPK[nCol]; memcpy(pTab->zName, zNew, nNew+1); - *ppTabList = pTab; + pGrp->pList = pTab; }else if( pTab->nCol!=nCol || memcmp(pTab->abPK, abPK, nCol) ){ rc = SQLITE_SCHEMA; break; @@ -4262,54 +4279,45 @@ static int sessionChangesetToHash( if( rc==SQLITE_OK ) rc = pIter->rc; return rc; } - -/* -** 1. Iterate through the left-hand changeset. Add an entry to a table -** specific hash table for each change in the changeset. The hash table -** key is the PK of the row affected by the change. + +/* +** Serialize a changeset (or patchset) based on all changesets (or patchsets) +** added to the changegroup object passed as the first argument. ** -** 2. Then interate through the right-hand changeset. Attempt to add an -** entry to a hash table for each component change. If a change already -** exists with the same PK values, combine the two into a single change. +** If xOutput is not NULL, then the changeset/patchset is returned to the +** user via one or more calls to xOutput, as with the other streaming +** interfaces. ** -** 3. Write an output changeset based on the contents of the hash table. +** Or, if xOutput is NULL, then (*ppOut) is populated with a pointer to a +** buffer containing the output changeset before this function returns. In +** this case (*pnOut) is set to the size of the output buffer in bytes. It +** is the responsibility of the caller to free the output buffer using +** sqlite3_free() when it is no longer required. +** +** If successful, SQLITE_OK is returned. Or, if an error occurs, an SQLite +** error code. If an error occurs and xOutput is NULL, (*ppOut) and (*pnOut) +** are both set to 0 before returning. */ -static int sessionChangesetConcat( - sqlite3_changeset_iter *pLeft, - sqlite3_changeset_iter *pRight, +static int sessionChangegroupOutput( + sqlite3_changegroup *pGrp, int (*xOutput)(void *pOut, const void *pData, int nData), void *pOut, int *pnOut, void **ppOut ){ - SessionTable *pList = 0; /* List of SessionTable objects */ - int rc; /* Return code */ - int bPatch; /* True for a patchset */ - SessionTable *pTab; + int rc = SQLITE_OK; SessionBuffer buf = {0, 0, 0}; - + SessionTable *pTab; assert( xOutput==0 || (ppOut==0 && pnOut==0) ); - assert( pLeft->zTab==0 && pRight->zTab==0 ); - rc = sessionChangesetToHash(pLeft, &pList); - assert( pLeft->zTab || pList==0 ); - if( rc==SQLITE_OK ){ - rc = sessionChangesetToHash(pRight, &pList); - } - bPatch = pLeft->bPatchset || pRight->bPatchset; - - if( pLeft->zTab && pRight->zTab && pLeft->bPatchset!=pRight->bPatchset ){ - rc = SQLITE_ERROR; - } - /* Create the serialized output changeset based on the contents of the - ** hash tables attached to the SessionTable objects in list pList. + ** hash tables attached to the SessionTable objects in list p->pList. */ - for(pTab=pList; rc==SQLITE_OK && pTab; pTab=pTab->pNext){ + for(pTab=pGrp->pList; rc==SQLITE_OK && pTab; pTab=pTab->pNext){ int i; if( pTab->nEntry==0 ) continue; - sessionAppendTableHdr(&buf, bPatch, pTab, &rc); + sessionAppendTableHdr(&buf, pGrp->bPatch, pTab, &rc); for(i=0; inChange; i++){ SessionChange *p; for(p=pTab->apChange[i]; p; p=p->pNext){ @@ -4336,10 +4344,93 @@ static int sessionChangesetConcat( } sqlite3_free(buf.aBuf); - sessionDeleteTable(pList); return rc; } +/* +** Allocate a new, empty, sqlite3_changegroup. +*/ +int sqlite3changegroup_new(sqlite3_changegroup **pp){ + int rc = SQLITE_OK; /* Return code */ + sqlite3_changegroup *p; /* New object */ + p = (sqlite3_changegroup*)sqlite3_malloc(sizeof(sqlite3_changegroup)); + if( p==0 ){ + rc = SQLITE_NOMEM; + }else{ + memset(p, 0, sizeof(sqlite3_changegroup)); + } + *pp = p; + return rc; +} + +/* +** Add the changeset currently stored in buffer pData, size nData bytes, +** to changeset-group p. +*/ +int sqlite3changegroup_add(sqlite3_changegroup *pGrp, int nData, void *pData){ + sqlite3_changeset_iter *pIter; /* Iterator opened on pData/nData */ + int rc; /* Return code */ + + rc = sqlite3changeset_start(&pIter, nData, pData); + if( rc==SQLITE_OK ){ + rc = sessionChangesetToHash(pIter, pGrp); + } + sqlite3changeset_finalize(pIter); + return rc; +} + +/* +** Obtain a buffer containing a changeset representing the concatenation +** of all changesets added to the group so far. +*/ +int sqlite3changegroup_output( + sqlite3_changegroup *pGrp, + int *pnData, + void **ppData +){ + return sessionChangegroupOutput(pGrp, 0, 0, pnData, ppData); +} + +/* +** Streaming versions of changegroup_add(). +*/ +int sqlite3changegroup_add_strm( + sqlite3_changegroup *pGrp, + int (*xInput)(void *pIn, void *pData, int *pnData), + void *pIn +){ + sqlite3_changeset_iter *pIter; /* Iterator opened on pData/nData */ + int rc; /* Return code */ + + rc = sqlite3changeset_start_strm(&pIter, xInput, pIn); + if( rc==SQLITE_OK ){ + rc = sessionChangesetToHash(pIter, pGrp); + } + sqlite3changeset_finalize(pIter); + return rc; +} + +/* +** Streaming versions of changegroup_output(). +*/ +int sqlite3changegroup_output_strm( + sqlite3_changegroup *pGrp, + int (*xOutput)(void *pOut, const void *pData, int nData), + void *pOut +){ + return sessionChangegroupOutput(pGrp, xOutput, pOut, 0, 0); +} + +/* +** Delete a changegroup object. +*/ +void sqlite3changegroup_delete(sqlite3_changegroup *pGrp){ + if( pGrp ){ + sessionDeleteTable(pGrp->pList); + sqlite3_free(pGrp); + } +} + /* ** Combine two changesets together. */ @@ -4351,22 +4442,21 @@ int sqlite3changeset_concat( int *pnOut, /* OUT: Number of bytes in output changeset */ void **ppOut /* OUT: changeset (left right) */ ){ - sqlite3_changeset_iter *pIter1 = 0; - sqlite3_changeset_iter *pIter2 = 0; + sqlite3_changegroup *pGrp; int rc; - *pnOut = 0; - *ppOut = 0; - rc = sqlite3changeset_start(&pIter1, nLeft, pLeft); + rc = sqlite3changegroup_new(&pGrp); if( rc==SQLITE_OK ){ - rc = sqlite3changeset_start(&pIter2, nRight, pRight); + rc = sqlite3changegroup_add(pGrp, nLeft, pLeft); } if( rc==SQLITE_OK ){ - rc = sessionChangesetConcat(pIter1, pIter2, 0, 0, pnOut, ppOut); + rc = sqlite3changegroup_add(pGrp, nRight, pRight); } + if( rc==SQLITE_OK ){ + rc = sqlite3changegroup_output(pGrp, pnOut, ppOut); + } + sqlite3changegroup_delete(pGrp); - sqlite3changeset_finalize(pIter1); - sqlite3changeset_finalize(pIter2); return rc; } @@ -4381,20 +4471,21 @@ int sqlite3changeset_concat_strm( int (*xOutput)(void *pOut, const void *pData, int nData), void *pOut ){ - sqlite3_changeset_iter *pIter1 = 0; - sqlite3_changeset_iter *pIter2 = 0; + sqlite3_changegroup *pGrp; int rc; - rc = sqlite3changeset_start_strm(&pIter1, xInputA, pInA); + rc = sqlite3changegroup_new(&pGrp); if( rc==SQLITE_OK ){ - rc = sqlite3changeset_start_strm(&pIter2, xInputB, pInB); + rc = sqlite3changegroup_add_strm(pGrp, xInputA, pInA); } if( rc==SQLITE_OK ){ - rc = sessionChangesetConcat(pIter1, pIter2, xOutput, pOut, 0, 0); + rc = sqlite3changegroup_add_strm(pGrp, xInputB, pInB); } + if( rc==SQLITE_OK ){ + rc = sqlite3changegroup_output_strm(pGrp, xOutput, pOut); + } + sqlite3changegroup_delete(pGrp); - sqlite3changeset_finalize(pIter1); - sqlite3changeset_finalize(pIter2); return rc; } diff --git a/ext/session/sqlite3session.h b/ext/session/sqlite3session.h index c8ce488ba7..f2df143e1a 100644 --- a/ext/session/sqlite3session.h +++ b/ext/session/sqlite3session.h @@ -683,70 +683,22 @@ int sqlite3changeset_invert( ** single changeset. The result is a changeset equivalent to applying ** changeset A followed by changeset B. ** -** Rows are identified by the values in their PRIMARY KEY columns. A change -** in changeset A is considered to apply to the same row as a change in -** changeset B if the two rows have the same primary key. +** This function combines the two input changesets using an +** sqlite3_changegroup object. Calling it produces similar results as the +** following code fragment: ** -** Changes to rows that appear only in changeset A or B are copied into the -** output changeset. Or, if both changeset A and B contain a change that -** applies to a single row, the output depends on the type of each change, -** as follows: +** sqlite3_changegroup *pGrp; +** rc = sqlite3_changegroup_new(&pGrp); +** if( rc==SQLITE_OK ) rc = sqlite3changegroup_add(pGrp, nA, pA); +** if( rc==SQLITE_OK ) rc = sqlite3changegroup_add(pGrp, nB, pB); +** if( rc==SQLITE_OK ){ +** rc = sqlite3changegroup_output(pGrp, pnOut, ppOut); +** }else{ +** *ppOut = 0; +** *pnOut = 0; +** } ** -**
  • -** -** -**
    Change A Change B Output Change -**
    INSERT INSERT -** Change A is copied into the output changeset. Change B is discarded. -** This case does not occur if changeset B is recorded immediately after -** changeset A. -**
    INSERT UPDATE -** An INSERT change is copied into the output changeset. The values in -** the INSERT change are as if the row was inserted by change A and then -** updated according to change B. -**
    INSERT DELETE -** No change at all is copied into the output changeset. -**
    UPDATE INSERT -** Change A is copied into the output changeset. Change B is discarded. -** This case does not occur if changeset B is recorded immediately after -** changeset A. -**
    UPDATE UPDATE -** A single UPDATE is copied into the output changeset. The accompanying -** values are as if the row was updated once by change A and then again -** by change B. -**
    UPDATE DELETE -** A single DELETE is copied into the output changeset. -**
    DELETE INSERT -** If one or more of the column values in the row inserted by change -** B differ from those in the row deleted by change A, an UPDATE -** change is added to the output changeset. Otherwise, if the inserted -** row is exactly the same as the deleted row, no change is added to -** the output changeset. -**
    DELETE UPDATE -** Change A is copied into the output changeset. Change B is discarded. -** This case does not occur if changeset B is recorded immediately after -** changeset A. -**
    DELETE DELETE -** Change A is copied into the output changeset. Change B is discarded. -** This case does not occur if changeset B is recorded immediately after -** changeset A. -**
    -** -** If the two changesets contain changes to the same table, then the number -** of columns and the position of the primary key columns for the table must -** be the same in each changeset. If this is not the case, attempting to -** concatenate the two changesets together fails and this function returns -** SQLITE_SCHEMA. If either of the two input changesets appear to be corrupt, -** and the corruption is detected, SQLITE_CORRUPT is returned. Or, if an -** out-of-memory condition occurs during processing, this function returns -** SQLITE_NOMEM. -** -** If none of the above errors occur, SQLITE_OK is returned and *ppOut set -** to point to a buffer containing the output changeset. It is the -** responsibility of the caller to eventually call sqlite3_free() on *ppOut -** to release memory allocated for the buffer. *pnOut is set to the number -** of bytes in the output changeset. If an error does occur, both *ppOut and -** *pnOut are set to zero before returning. +** Refer to the sqlite3_changegroup documentation below for details. */ int sqlite3changeset_concat( int nA, /* Number of bytes in buffer pA */ @@ -757,6 +709,148 @@ int sqlite3changeset_concat( void **ppOut /* OUT: Buffer containing output changeset */ ); + +/* +** Changegroup handle. +*/ +typedef struct sqlite3_changegroup sqlite3_changegroup; + +/* +** CAPI3REF: Combine two or more changesets into a single changeset. +** +** An sqlite3_changegroup object is used to combine two or more changesets +** (or patchsets) into a single changeset (or patchset). A single changegroup +** object may combine changesets or patchsets, but not both. The output is +** always in the same format as the input. +** +** If successful, this function returns SQLITE_OK and populates (*pp) with +** a pointer to a new sqlite3_changegroup object before returning. The caller +** should eventually free the returned object using a call to +** sqlite3changegroup_delete(). If an error occurs, an SQLite error code +** (i.e. SQLITE_NOMEM) is returned and *pp is set to NULL. +** +** The usual usage pattern for an sqlite3_changegroup object is as follows: +** +**
      +**
    • It is created using a call to sqlite3changegroup_new(). +** +**
    • Zero or more changesets (or patchsets) are added to the object +** by calling sqlite3changegroup_add(). +** +**
    • The result of combining all input changesets together is obtained +** by the application via a call to sqlite3changegroup_output(). +** +**
    • The object is deleted using a call to sqlite3changegroup_delete(). +**
    +** +** Any number of calls to add() and output() may be made between the calls to +** new() and delete(), and in any order. +** +** As well as the regular sqlite3changegroup_add() and +** sqlite3changegroup_output() functions, also available are the streaming +** versions sqlite3changegroup_add_strm() and sqlite3changegroup_output_strm(). +*/ +int sqlite3changegroup_new(sqlite3_changegroup **pp); + +/* +** Add all changes within the changeset (or patchset) in buffer pData (size +** nData bytes) to the changegroup. +** +** If the buffer contains a patchset, then all prior calls to this function +** on the same changegroup object must also have specified patchsets. Or, if +** the buffer contains a changeset, so must have the earlier calls to this +** function. Otherwise, SQLITE_ERROR is returned and no changes are added +** to the changegroup. +** +** Rows within the changeset and changegroup are identified by the values in +** their PRIMARY KEY columns. A change in the changeset is considered to +** apply to the same row as a change already present in the changegroup if +** the two rows have the same primary key. +** +** Changes to rows that that do not already appear in the changegroup are +** simply copied into it. Or, if both the new changeset and the changegroup +** contain changes that apply to a single row, the final contents of the +** changegroup depends on the type of each change, as follows: +** +** +** +** +**
    Existing Change New Change Output Change +**
    INSERT INSERT +** The new change is ignored. This case does not occur if the new +** changeset was recorded immediately after the changesets already +** added to the changegroup. +**
    INSERT UPDATE +** The INSERT change remains in the changegroup. The values in the +** INSERT change are modified as if the row was inserted by the +** existing change and then updated according to the new change. +**
    INSERT DELETE +** The existing INSERT is removed from the changegroup. The DELETE is +** not added. +**
    UPDATE INSERT +** The new change is ignored. This case does not occur if the new +** changeset was recorded immediately after the changesets already +** added to the changegroup. +**
    UPDATE UPDATE +** The existing UPDATE remains within the changegroup. It is amended +** so that the accompanying values are as if the row was updated once +** by the existing change and then again by the new change. +**
    UPDATE DELETE +** The existing UPDATE is replaced by the new DELETE within the +** changegroup. +**
    DELETE INSERT +** If one or more of the column values in the row inserted by the +** new change differ from those in the row deleted by the existing +** change, the existing DELETE is replaced by an UPDATE within the +** changegroup. Otherwise, if the inserted row is exactly the same +** as the deleted row, the existing DELETE is simply discarded. +**
    DELETE UPDATE +** The new change is ignored. This case does not occur if the new +** changeset was recorded immediately after the changesets already +** added to the changegroup. +**
    DELETE DELETE +** The new change is ignored. This case does not occur if the new +** changeset was recorded immediately after the changesets already +** added to the changegroup. +**
    +** +** If the new changeset contains changes to a table that is already present +** in the changegroup, then the number of columns and the position of the +** primary key columns for the table must be consistent. If this is not the +** case, this function fails with SQLITE_SCHEMA. If the input changeset +** appears to be corrupt and the corruption is detected, SQLITE_CORRUPT is +** returned. Or, if an out-of-memory condition occurs during processing, this +** function returns SQLITE_NOMEM. In all cases, if an error occurs the +** final contents of the changegroup is undefined. +** +** If no error occurs, SQLITE_OK is returned. +*/ +int sqlite3changegroup_add(sqlite3_changegroup*, int nData, void *pData); + +/* +** Obtain a buffer containing a changeset (or patchset) representing the +** current contents of the changegroup. If the inputs to the changegroup +** were themselves changesets, the output is a changeset. Or, if the +** inputs were patchsets, the output is also a patchset. +** +** If an error occurs, an SQLite error code is returned and the output +** variables (*pnData) and (*ppData) are set to 0. Otherwise, SQLITE_OK +** is returned and the output variables are set to the size of and a +** pointer to the output buffer, respectively. In this case it is the +** responsibility of the caller to eventually free the buffer using a +** call to sqlite3_free(). +*/ +int sqlite3changegroup_output( + sqlite3_changegroup*, + int *pnData, /* OUT: Size of output buffer in bytes */ + void **ppData /* OUT: Pointer to output buffer */ +); + +/* +** Delete a changegroup object. +*/ +void sqlite3changegroup_delete(sqlite3_changegroup*); + /* ** CAPI3REF: Apply A Changeset To A Database ** @@ -1138,6 +1232,14 @@ int sqlite3session_patchset_strm( int (*xOutput)(void *pOut, const void *pData, int nData), void *pOut ); +int sqlite3changegroup_add_strm(sqlite3_changegroup*, + int (*xInput)(void *pIn, void *pData, int *pnData), + void *pIn +); +int sqlite3changegroup_output_strm(sqlite3_changegroup*, + int (*xOutput)(void *pOut, const void *pData, int nData), + void *pOut +); /* diff --git a/manifest b/manifest index 2204ad1cdc..c7877d9297 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\s"finish_test"\scommand\sto\sthe\send\sof\snew\stest\sscript\ssessionE.test. -D 2015-06-02T09:20:46.301 +C Add\sthe\ssqlite3changegroup_xxx()\sAPIs\sto\sthe\ssessions\smodule.\sFor\scombining\smultiple\schangesets\sor\spatchsets. +D 2015-06-11T17:26:10.939 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 58c16cc8cd876ed112902e70cf33d33f3270b5aa F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -181,8 +181,8 @@ F ext/session/sessionD.test d4744c78334162851d2a2f285c7e603e31b49aa2 F ext/session/sessionE.test e60a238c47f0feb3bb707e7f35e22be09c7e8f26 F ext/session/session_common.tcl f4b7b59c617edf0c9b00d94cd93498d225d43837 F ext/session/sessionfault.test bef044d0952c0d62c31c8d2400be72c8684545cc -F ext/session/sqlite3session.c d630293057fcf4274451edec24c2745953ca042c -F ext/session/sqlite3session.h 8e86f9eec3ed71f1f30eefbe810cbe5bc10b5aa9 +F ext/session/sqlite3session.c 78e5b310cd6e655e9166f40dc8a319c0c866cfdc +F ext/session/sqlite3session.h 772cffe38f11bd62f434eabf080157eabf3d553e F ext/session/test_session.c 187bd344c5ae9d5be85e22ef7c3010f0c17307ce F ext/userauth/sqlite3userauth.h 19cb6f0e31316d0ee4afdfb7a85ef9da3333a220 F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04 @@ -1301,7 +1301,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P bdaf9575cd9ebb33dc5da4062a84bca79e7b0fec -R dbe1b57e21e93824d104fb3b930d73e6 +P fb3914070791c84b5f323b7359ac845246d8a844 +R 8257ada0208a724be61180fd75fdecb0 U dan -Z cd8fea501989560b39f7780ac3d3b3f9 +Z fef5e9795fb303b4eab93bd557fcafaf diff --git a/manifest.uuid b/manifest.uuid index 5f700eaf36..c7a49060eb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fb3914070791c84b5f323b7359ac845246d8a844 \ No newline at end of file +0c1a901cd60e557fc676b97625243163dfe9be9d \ No newline at end of file From 6c39e6a80008610147fda192405472c88578bf73 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 1 Oct 2015 16:35:57 +0000 Subject: [PATCH 0141/1484] Changes to the sesssions module ensure that tables appear within changesets and patchsets in the same order that they were attached to the sessions object. FossilOrigin-Name: 7695890230dc1e0c6db9b7aa509db2039c7f7239 --- ext/session/session1.test | 11 -- ext/session/session2.test | 4 +- ext/session/sessionB.test | 10 -- ext/session/sessionF.test | 295 +++++++++++++++++++++++++++++++++ ext/session/session_common.tcl | 22 +++ ext/session/sqlite3session.c | 24 ++- ext/session/sqlite3session.h | 25 +++ manifest | 25 +-- manifest.uuid | 2 +- 9 files changed, 376 insertions(+), 42 deletions(-) create mode 100644 ext/session/sessionF.test diff --git a/ext/session/session1.test b/ext/session/session1.test index fc74a1e84e..7aebe8c000 100644 --- a/ext/session/session1.test +++ b/ext/session/session1.test @@ -20,17 +20,6 @@ ifcapable !session {finish_test; return} set testprefix session1 -proc do_changeset_invert_test {tn session res} { - set r [list] - foreach x $res {lappend r $x} - uplevel do_test $tn [list [subst -nocommands { - set x [list] - set changeset [sqlite3changeset_invert [$session changeset]] - sqlite3session_foreach c [set changeset] { lappend x [set c] } - set x - }]] [list $r] -} - do_execsql_test 1.0 { CREATE TABLE t1(x PRIMARY KEY, y); INSERT INTO t1 VALUES('abc', 'def'); diff --git a/ext/session/session2.test b/ext/session/session2.test index 0035e39dbf..cd8c2869e7 100644 --- a/ext/session/session2.test +++ b/ext/session/session2.test @@ -298,8 +298,8 @@ foreach {tn sql changeset} { DELETE FROM t1 WHERE 1; UPDATE t2 SET x = 34; } { - {UPDATE t2 0 .X {i 36 i 37} {i 34 {} {}}} {DELETE t1 0 X {i 35} {}} + {UPDATE t2 0 .X {i 36 i 37} {i 34 {} {}}} } } { do_iterator_test 5.$tn * $sql $changeset @@ -413,8 +413,8 @@ do_iterator_test 6.1.8 * { SELECT indirect(0); UPDATE t4 SET a = 'two' WHERE b = 1; } { - {INSERT t4 0 .X {} {t two i 1}} {INSERT t3 1 .X {} {t two i 1}} + {INSERT t4 0 .X {} {t two i 1}} } sqlite3session S db main diff --git a/ext/session/sessionB.test b/ext/session/sessionB.test index f1af5d213c..eae41f76ad 100644 --- a/ext/session/sessionB.test +++ b/ext/session/sessionB.test @@ -31,16 +31,6 @@ set testprefix sessionB # 3.*: Test that sqlite3changeset_invert() works with patchset blobs. # Correct behaviour is to return SQLITE_CORRUPT. -proc do_patchset_test {tn session res} { - set r [list] - foreach x $res {lappend r $x} - uplevel do_test $tn [list [subst -nocommands { - set x [list] - sqlite3session_foreach c [$session patchset] { lappend x [set c] } - set x - }]] [list $r] -} - proc do_sql2patchset_test {tn sql res} { sqlite3session S db main S attach * diff --git a/ext/session/sessionF.test b/ext/session/sessionF.test new file mode 100644 index 0000000000..ba57bf85ec --- /dev/null +++ b/ext/session/sessionF.test @@ -0,0 +1,295 @@ +# 2015 June 02 +# +# 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 regression tests for the sessions module. +# Specifically, it tests that tables appear in the correct order +# within changesets and patchsets. +# + + + +if {![info exists testdir]} { + set testdir [file join [file dirname [info script]] .. .. test] +} +source [file join [file dirname [info script]] session_common.tcl] +source $testdir/tester.tcl +ifcapable !session {finish_test; return} +set testprefix sessionF + +# +# Test plan: +# +# 1.*: Test that sqlite3session_changeset() and sqlite3session_patchset() +# output tables in the right order. +# +# 2.*: Test that sqlite3session_invert() does not modify the order of +# tables within a changeset. +# +# 3.*: Test that sqlite3session_concat outputs tables in the right order. +# + +# Create a db schema to use. +# +do_execsql_test 1.0 { + CREATE TABLE t3(e PRIMARY KEY, f); + CREATE TABLE t1(a PRIMARY KEY, b); + CREATE TABLE t2(c PRIMARY KEY, d); +} + +#----------------------------------------------------------------------- +# 1.* - changeset() and patchset(). +# + +foreach {tn setup result} { + 1 { + S attach * + } { + {INSERT t2 0 X. {} {i 2 t two}} + {INSERT t1 0 X. {} {i 1 t one}} + {INSERT t3 0 X. {} {i 3 t three}} + } + + 2 { + S attach t1 + S attach * + } { + {INSERT t1 0 X. {} {i 1 t one}} + {INSERT t2 0 X. {} {i 2 t two}} + {INSERT t3 0 X. {} {i 3 t three}} + } + + 3 { + S attach t3 + S attach t2 + S attach t1 + } { + {INSERT t3 0 X. {} {i 3 t three}} + {INSERT t2 0 X. {} {i 2 t two}} + {INSERT t1 0 X. {} {i 1 t one}} + } +} { + execsql { + DELETE FROM t1; + DELETE FROM t2; + DELETE FROM t3; + } + sqlite3session S db main + eval $setup + + do_execsql_test 1.$tn.1 { + INSERT INTO t2 VALUES(2, 'two'); + INSERT INTO t1 VALUES(1, 'one'); + INSERT INTO t3 VALUES(3, 'three'); + } + + do_changeset_test 1.1.$tn.2 S $result + do_patchset_test 1.1.$tn.3 S $result + + S delete +} + +foreach {tn setup result} { + 1 { + S attach * + } { + {INSERT t2 0 X. {} {i 4 t four}} + {INSERT t2 0 X. {} {i 5 t five}} + {INSERT t1 0 X. {} {i 1 t one}} + {INSERT t3 0 X. {} {i 6 t six}} + } + + 2 { + S attach t1 + S attach * + } { + {INSERT t1 0 X. {} {i 1 t one}} + {INSERT t2 0 X. {} {i 4 t four}} + {INSERT t2 0 X. {} {i 5 t five}} + {INSERT t3 0 X. {} {i 6 t six}} + } + + 3 { + S attach t3 + S attach t2 + S attach t1 + } { + {INSERT t3 0 X. {} {i 6 t six}} + {INSERT t2 0 X. {} {i 4 t four}} + {INSERT t2 0 X. {} {i 5 t five}} + {INSERT t1 0 X. {} {i 1 t one}} + } +} { + execsql { + DELETE FROM t1; + DELETE FROM t2; + DELETE FROM t3; + } + sqlite3session S db main + eval $setup + + do_execsql_test 1.$tn.1 { + INSERT INTO t2 VALUES(2, 'two'); + INSERT INTO t1 VALUES(1, 'one'); + DELETE FROM t2; + INSERT INTO t2 VALUES(4, 'four'); + INSERT INTO t2 VALUES(5, 'five'); + INSERT INTO t3 VALUES(6, 'six'); + } + + do_changeset_test 1.2.$tn.2 S $result + do_patchset_test 1.2.$tn.2 S $result + + S delete +} + +#------------------------------------------------------------------------- +# 2.* - invert() +# + +foreach {tn setup result} { + 1 { + S attach * + } { + {DELETE t2 0 X. {i 4 t four} {}} + {DELETE t2 0 X. {i 5 t five} {}} + {DELETE t1 0 X. {i 1 t one} {}} + {DELETE t3 0 X. {i 6 t six} {}} + } + + 2 { + S attach t1 + S attach * + } { + {DELETE t1 0 X. {i 1 t one} {}} + {DELETE t2 0 X. {i 4 t four} {}} + {DELETE t2 0 X. {i 5 t five} {}} + {DELETE t3 0 X. {i 6 t six} {}} + } + + 3 { + S attach t3 + S attach t2 + S attach t1 + } { + {DELETE t3 0 X. {i 6 t six} {}} + {DELETE t2 0 X. {i 4 t four} {}} + {DELETE t2 0 X. {i 5 t five} {}} + {DELETE t1 0 X. {i 1 t one} {}} + } +} { + execsql { + DELETE FROM t1; + DELETE FROM t2; + DELETE FROM t3; + } + sqlite3session S db main + eval $setup + + do_execsql_test 1.$tn.1 { + INSERT INTO t2 VALUES(2, 'two'); + INSERT INTO t1 VALUES(1, 'one'); + DELETE FROM t2; + INSERT INTO t2 VALUES(4, 'four'); + INSERT INTO t2 VALUES(5, 'five'); + INSERT INTO t3 VALUES(6, 'six'); + } + + do_changeset_invert_test 2.$tn.2 S $result + + S delete +} + +#------------------------------------------------------------------------- +# 3.* - concat() +# +foreach {tn setup1 sql1 setup2 sql2 result} { + 1 { + S attach * + } { + INSERT INTO t1 VALUES(1, 'one'); + INSERT INTO t2 VALUES(2, 'two'); + } { + S attach t2 + S attach t1 + } { + INSERT INTO t1 VALUES(3, 'three'); + INSERT INTO t2 VALUES(4, 'four'); + } { + {INSERT t1 0 X. {} {i 1 t one}} + {INSERT t1 0 X. {} {i 3 t three}} + {INSERT t2 0 X. {} {i 2 t two}} + {INSERT t2 0 X. {} {i 4 t four}} + } + + 1 { + S attach t2 + S attach t1 + } { + INSERT INTO t1 VALUES(1, 'one'); + INSERT INTO t2 VALUES(2, 'two'); + } { + S attach * + } { + INSERT INTO t1 VALUES(3, 'three'); + INSERT INTO t2 VALUES(4, 'four'); + } { + {INSERT t2 0 X. {} {i 2 t two}} + {INSERT t2 0 X. {} {i 4 t four}} + {INSERT t1 0 X. {} {i 1 t one}} + {INSERT t1 0 X. {} {i 3 t three}} + } + + 1 { + S attach * + } { + INSERT INTO t2 VALUES(2, 'two'); + } { + S attach * + } { + INSERT INTO t1 VALUES(3, 'three'); + INSERT INTO t2 VALUES(4, 'four'); + INSERT INTO t3 VALUES(5, 'five'); + } { + {INSERT t2 0 X. {} {i 2 t two}} + {INSERT t2 0 X. {} {i 4 t four}} + {INSERT t1 0 X. {} {i 3 t three}} + {INSERT t3 0 X. {} {i 5 t five}} + } + +} { + execsql { + DELETE FROM t1; + DELETE FROM t2; + DELETE FROM t3; + } + sqlite3session S db main + eval $setup1 + execsql $sql1 + set c1 [S changeset] + S delete + + sqlite3session S db main + eval $setup2 + execsql $sql2 + set c2 [S changeset] + S delete + + set res [list] + sqlite3session_foreach x [sqlite3changeset_concat $c1 $c2] { + lappend res $x + } + + do_test 3.$tn { set res } [list {*}$result] +} + + +finish_test + diff --git a/ext/session/session_common.tcl b/ext/session/session_common.tcl index f27ad11dc0..38eebec0a0 100644 --- a/ext/session/session_common.tcl +++ b/ext/session/session_common.tcl @@ -9,6 +9,28 @@ proc do_changeset_test {tn session res} { }]] [list $r] } +proc do_patchset_test {tn session res} { + set r [list] + foreach x $res {lappend r $x} + uplevel do_test $tn [list [subst -nocommands { + set x [list] + sqlite3session_foreach c [$session patchset] { lappend x [set c] } + set x + }]] [list $r] +} + + +proc do_changeset_invert_test {tn session res} { + set r [list] + foreach x $res {lappend r $x} + uplevel do_test $tn [list [subst -nocommands { + set x [list] + set changeset [sqlite3changeset_invert [$session changeset]] + sqlite3session_foreach c [set changeset] { lappend x [set c] } + set x + }]] [list $r] +} + proc do_conflict_test {tn args} { proc xConflict {args} { diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index 0937c9bb32..546a22a072 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -1188,7 +1188,7 @@ static int sessionFindTable( ){ rc = sqlite3session_attach(pSession, zName); if( rc==SQLITE_OK ){ - pRet = pSession->pTable; + for(pRet=pSession->pTable; pRet->pNext; pRet=pRet->pNext); assert( 0==sqlite3_strnicmp(pRet->zName, zName, nName+1) ); } } @@ -1675,12 +1675,17 @@ int sqlite3session_attach( if( !pTab ){ rc = SQLITE_NOMEM; }else{ - /* Populate the new SessionTable object and link it into the list. */ + /* Populate the new SessionTable object and link it into the list. + ** The new object must be linked onto the end of the list, not + ** simply added to the start of it in order to ensure that tables + ** appear in the correct order when a changeset or patchset is + ** eventually generated. */ + SessionTable **ppTab; memset(pTab, 0, sizeof(SessionTable)); pTab->zName = (char *)&pTab[1]; memcpy(pTab->zName, zName, nName+1); - pTab->pNext = pSession->pTable; - pSession->pTable = pTab; + for(ppTab=&pSession->pTable; *ppTab; ppTab=&(*ppTab)->pNext); + *ppTab = pTab; } } } @@ -4220,19 +4225,26 @@ static int sessionChangesetToHash( if( 0==sqlite3_strnicmp(pTab->zName, zNew, nNew+1) ) break; } if( !pTab ){ + SessionTable **ppTab; + pTab = sqlite3_malloc(sizeof(SessionTable) + nCol + nNew+1); if( !pTab ){ rc = SQLITE_NOMEM; break; } memset(pTab, 0, sizeof(SessionTable)); - pTab->pNext = pGrp->pList; pTab->nCol = nCol; pTab->abPK = (u8*)&pTab[1]; memcpy(pTab->abPK, abPK, nCol); pTab->zName = (char*)&pTab->abPK[nCol]; memcpy(pTab->zName, zNew, nNew+1); - pGrp->pList = pTab; + + /* The new object must be linked on to the end of the list, not + ** simply added to the start of it. This is to ensure that the + ** tables within the output of sqlite3changegroup_output() are in + ** the right order. */ + for(ppTab=&pGrp->pList; *ppTab; ppTab=&(*ppTab)->pNext); + *ppTab = pTab; }else if( pTab->nCol!=nCol || memcmp(pTab->abPK, abPK, nCol) ){ rc = SQLITE_SCHEMA; break; diff --git a/ext/session/sqlite3session.h b/ext/session/sqlite3session.h index f2df143e1a..71f02159cf 100644 --- a/ext/session/sqlite3session.h +++ b/ext/session/sqlite3session.h @@ -206,6 +206,14 @@ void sqlite3session_table_filter( ** a database with a compatible schema using the [sqlite3changeset_apply()] ** API. ** +** Within a changeset generated by this function, all changes related to a +** single table are grouped together. In other words, when iterating through +** a changeset or when applying a changeset to a database, all changes related +** to a single table are processed before moving on to the next table. Tables +** are sorted in the same order in which they were attached (or auto-attached) +** to the sqlite3_session object. The order in which the changes related to +** a single table are stored is undefined. +** ** Following a successful call to this function, it is the responsibility of ** the caller to eventually free the buffer that *ppChangeset points to using ** [sqlite3_free()]. @@ -358,6 +366,11 @@ int sqlite3session_diff( ** SQLITE_CHANGESET_DATA conflicts can be detected or reported if a patchset ** is passed to the sqlite3changeset_apply() API. Other conflict types work ** in the same way as for changesets. +** +** Changes within a patchset are ordered in the same way as for changesets +** generated by the sqlite3session_changeset() function (i.e. all changes for +** a single table are grouped together, tables appear in the order in which +** they were attached to the session object). */ int sqlite3session_patchset( sqlite3_session *pSession, /* Session object */ @@ -659,6 +672,9 @@ int sqlite3changeset_finalize(sqlite3_changeset_iter *pIter); **
  • For each UPDATE change, the old.* and new.* values are exchanged. ** ** +** This function does not change the order in which changes appear within +** the changeset. It merely reverses the sense of each individual change. +** ** If successful, a pointer to a buffer containing the inverted changeset ** is stored in *ppOut, the size of the same buffer is stored in *pnOut, and ** SQLITE_OK is returned. If an error occurs, both *pnOut and *ppOut are @@ -833,6 +849,15 @@ int sqlite3changegroup_add(sqlite3_changegroup*, int nData, void *pData); ** were themselves changesets, the output is a changeset. Or, if the ** inputs were patchsets, the output is also a patchset. ** +** As with the output of the sqlite3session_changeset() and +** sqlite3session_patchset() functions, all changes related to a single +** table are grouped together in the output of this function. Tables appear +** in the same order as for the very first changeset added to the changegroup. +** If the second or subsequent changesets added to the changegroup contain +** changes for tables that do not appear in the first changeset, they are +** appended onto the end of the output changeset, again in the order in +** which they are first encountered. +** ** If an error occurs, an SQLite error code is returned and the output ** variables (*pnData) and (*ppData) are set to 0. Otherwise, SQLITE_OK ** is returned and the output variables are set to the size of and a diff --git a/manifest b/manifest index bcf5b0db01..794f881303 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\srecent\senhancements\sfrom\strunk,\sand\sespecially\sthe\sfix\sfor\nticket\s[1b266395d6bc10]. -D 2015-09-30T14:50:39.955 +C Changes\sto\sthe\ssesssions\smodule\sensure\sthat\stables\sappear\swithin\schangesets\sand\spatchsets\sin\sthe\ssame\sorder\sthat\sthey\swere\sattached\sto\sthe\ssessions\sobject. +D 2015-10-01T16:35:57.175 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in fdcfdc361f0a3723da9b48b967f259f7aaff3ad5 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -256,8 +256,8 @@ F ext/rtree/sqlite3rtree.h 9c5777af3d2921c7b4ae4954e8e5697502289d28 F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 F ext/session/changeset.c 4ccbaa4531944c24584bf6a61ba3a39c62b6267a -F ext/session/session1.test d4f53b9b5add7eeb358e535d6e18552142092429 -F ext/session/session2.test a95a2d270b32638c1acba7cb9c81856712d469ac +F ext/session/session1.test 5dab50ce55c859e829bae24f0787013f51775fc5 +F ext/session/session2.test 284de45abae4cc1082bc52012ee81521d5ac58e0 F ext/session/session3.test a7a9ce59b8d1e49e2cc23d81421ac485be0eea01 F ext/session/session4.test a6ed685da7a5293c5d6f99855bcf41dbc352ca84 F ext/session/session5.test 716bc6fafd625ce60dfa62ae128971628c1a1169 @@ -265,14 +265,15 @@ F ext/session/session6.test 443789bc2fca12e4f7075cf692c60b8a2bea1a26 F ext/session/session8.test 8e194b3f655d861ca36de5d4de53f702751bab3b F ext/session/session9.test 5409d90d8141881d08285ed1c2c0d8d10fb92069 F ext/session/sessionA.test 1feeab0b8e03527f08f2f1defb442da25480138f -F ext/session/sessionB.test 06961b7c3641151f5d23088250ecad132501113c +F ext/session/sessionB.test 886252dcb7e692e62ef7e357456200912e367823 F ext/session/sessionC.test 3982f8577b0744c5ce3aaef7cfeb5bd903f17fe4 F ext/session/sessionD.test d4744c78334162851d2a2f285c7e603e31b49aa2 F ext/session/sessionE.test e60a238c47f0feb3bb707e7f35e22be09c7e8f26 -F ext/session/session_common.tcl f4b7b59c617edf0c9b00d94cd93498d225d43837 +F ext/session/sessionF.test c2f178d4dfd723a5fd94a730ea2ccb44c669e3ce +F ext/session/session_common.tcl a1293167d14774b5e728836720497f40fe4ea596 F ext/session/sessionfault.test bef044d0952c0d62c31c8d2400be72c8684545cc -F ext/session/sqlite3session.c 78e5b310cd6e655e9166f40dc8a319c0c866cfdc -F ext/session/sqlite3session.h 772cffe38f11bd62f434eabf080157eabf3d553e +F ext/session/sqlite3session.c 1ace1d1e4cb32cf60ca6e8ed1ae8d4c9f99ca458 +F ext/session/sqlite3session.h 64e9e7f185725ef43b97f4a9a0c0df0669844f1d F ext/session/test_session.c 187bd344c5ae9d5be85e22ef7c3010f0c17307ce F ext/userauth/sqlite3userauth.h 19cb6f0e31316d0ee4afdfb7a85ef9da3333a220 F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04 @@ -1409,7 +1410,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P c91065f8edb1e54076791716fc20d3fcfe3070dc e796c0efb6cf17444b53af75046daf7d8fa82f78 -R 0237333bf6dc63bf0c4f4c66d7918366 -U drh -Z 5f6cedfd7517312f688a69652091b608 +P b2face9aa95ade96a5666c70b6b31064c1ad0977 +R 67f4bc03b9ceb2707f867778f6790d70 +U dan +Z c3622f418cca20fcda99ae888e36e276 diff --git a/manifest.uuid b/manifest.uuid index 75c74a20e2..5274d2fafa 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b2face9aa95ade96a5666c70b6b31064c1ad0977 \ No newline at end of file +7695890230dc1e0c6db9b7aa509db2039c7f7239 \ No newline at end of file From 86151e8905a6767e3c5173dba111ead43ec865ca Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 8 Dec 2015 14:37:16 +0000 Subject: [PATCH 0142/1484] Avoid unnecessary work inside of verifyDbFile() in the unix VFS. FossilOrigin-Name: f3c0579e931799088e9a83757e25bae229120697 --- manifest | 15 +++++++++------ manifest.uuid | 2 +- src/os_unix.c | 8 +++++--- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index d584f281f3..11df61697b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sa\stest\scase\sof\sthe\sform\s"WHERE\sa<2\sOR\sa<3"\susing\sPRAGMA\scount_changes.\nThis\stest\scase\swas\sfailing\sbefore\sthe\s3.9.0\srelease. -D 2015-12-08T04:18:33.696 +C Avoid\sunnecessary\swork\sinside\sof\sverifyDbFile()\sin\sthe\sunix\sVFS. +D 2015-12-08T14:37:16.738 F Makefile.in 28bcd6149e050dff35d4dcfd97e890cd387a499d F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e8fdca1cb89a1b58b5f4d3a130ea9a3d28cb314d @@ -323,7 +323,7 @@ F src/os.c 8fd25588eeba74068d41102d26810e216999b6c8 F src/os.h 3e57a24e2794a94d3cf2342c6d9a884888cd96bf F src/os_common.h abdb9a191a367793268fe553d25bab894e986a0e F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa -F src/os_unix.c 0ca6d8710366fbb01a275160f018334cd347cbda +F src/os_unix.c 2f3bb1da50782128edf31fb17d22dc46f14c6eae F src/os_win.c 386fba30419e8458b13209781c2af5590eab2811 F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c f92aacd5216d8815136c9e0190041783c602641a @@ -1408,7 +1408,10 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 07e5199c6f868cc02a0b708865254056c4f3daf3 -R 17b34bcad46ec764b462c91813dd5909 +P 177862c1d50ba899d890fbc35f35e7423bc6aed5 +R cc3c3a45cf6a02d31e382067a458ce71 +T *branch * unix-vfs-optimization +T *sym-unix-vfs-optimization * +T -sym-trunk * U drh -Z 86e126efc794a5aaf900005c30a5cf69 +Z fcbe6020f6a9bf3f613adea5032fb70c diff --git a/manifest.uuid b/manifest.uuid index d39829dc75..12ed6b4bd9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -177862c1d50ba899d890fbc35f35e7423bc6aed5 \ No newline at end of file +f3c0579e931799088e9a83757e25bae229120697 \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index 791ba5d8d9..25f769fa50 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -1315,6 +1315,10 @@ static int fileHasMoved(unixFile *pFile){ static void verifyDbFile(unixFile *pFile){ struct stat buf; int rc; + + /* These verifications occurs for the main database only */ + if( pFile->ctrlFlags & UNIXFILE_NOLOCK ) return; + rc = osFstat(pFile->h, &buf); if( rc!=0 ){ sqlite3_log(SQLITE_WARNING, "cannot fstat db file %s", pFile->zPath); @@ -5761,9 +5765,6 @@ static int unixOpen( p->openFlags = openFlags; } #endif - - noLock = eType!=SQLITE_OPEN_MAIN_DB; - #if defined(__APPLE__) || SQLITE_ENABLE_LOCKING_STYLE if( fstatfs(fd, &fsInfo) == -1 ){ @@ -5782,6 +5783,7 @@ static int unixOpen( /* Set up appropriate ctrlFlags */ if( isDelete ) ctrlFlags |= UNIXFILE_DELETE; if( isReadonly ) ctrlFlags |= UNIXFILE_RDONLY; + noLock = eType!=SQLITE_OPEN_MAIN_DB; if( noLock ) ctrlFlags |= UNIXFILE_NOLOCK; if( syncDir ) ctrlFlags |= UNIXFILE_DIRSYNC; if( flags & SQLITE_OPEN_URI ) ctrlFlags |= UNIXFILE_URI; From 710b33b9992285bf53d50182c0543b8d8030f4b1 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Sun, 3 Jan 2016 18:59:28 +0000 Subject: [PATCH 0143/1484] Alternative to [76f5efa6], move definition of utf8_printf up. FossilOrigin-Name: 54c5522dda239cb9775709495ed7eb56a5dd8e11 --- manifest | 17 +++++++------ manifest.uuid | 2 +- src/shell.c | 68 +++++++++++++++++++++++++-------------------------- 3 files changed, 45 insertions(+), 42 deletions(-) diff --git a/manifest b/manifest index 584914720e..6efc1e7e97 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Bug\sfix:\sthe\sconflict\sresolution\sbehavior\sfor\sthe\simplied\sNOT\sNULL\sconstraint\non\sthe\sPRIMARY\sKEY\sof\sa\sWITHOUT\sROWID\stable\sshould\sbe\sABORT. -D 2016-01-03T18:07:57.631 +C Alternative\sto\s[76f5efa6],\smove\sdefinition\sof\sutf8_printf\sup. +D 2016-01-03T18:59:28.715 F Makefile.in 28bcd6149e050dff35d4dcfd97e890cd387a499d F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5fff077fcc46de7714ed6eebb6159a4c00eab751 @@ -334,7 +334,7 @@ F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c a83b41104e6ff69855d03cd0aaa09e93927ec39f F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e F src/select.c f8fded11fc443a9f5a73cc5db069d06b34460e2f -F src/shell.c ed71dc7679e6f087a3f1ea3f9dae4b0fae7209c3 +F src/shell.c 3ecb7a857c4595fef9ae4141fc8bb8dc53021be2 F src/sqlite.h.in 7d87d71b9a4689c51fa092f48f16590ff71558e3 F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad F src/sqlite3ext.h dfbe62ffd95b99afe2140d8c35b180d11924072d @@ -1406,7 +1406,10 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 76f5efa68728d899a63a74f2528dfd0c497aa5f0 -R 478df71a9631f4b73fcefbae5de2f355 -U drh -Z 2ce3cb02ff6782c368c437352328d0d1 +P e30062e9f6cae980150dda7df440b36dfdcb7bbe +R ebd31578448110e2087f3d6a13f40257 +T *branch * altShellFix +T *sym-altShellFix * +T -sym-trunk * +U mistachkin +Z f75cb2b820513d79cf30ddfb170e4e99 diff --git a/manifest.uuid b/manifest.uuid index c0ad5b411d..2bb8fd855c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e30062e9f6cae980150dda7df440b36dfdcb7bbe \ No newline at end of file +54c5522dda239cb9775709495ed7eb56a5dd8e11 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index b7a7abcd33..47c1b07759 100644 --- a/src/shell.c +++ b/src/shell.c @@ -361,6 +361,39 @@ static char *Argv0; static char mainPrompt[20]; /* First line prompt. default: "sqlite> "*/ static char continuePrompt[20]; /* Continuation prompt. default: " ...> " */ +/* +** Render output like fprintf(). Except, if the output is going to the +** console and if this is running on a Windows machine, translate the +** output from UTF-8 into MBCS. +*/ +#if defined(_WIN32) || defined(WIN32) +void utf8_printf(FILE *out, const char *zFormat, ...){ + va_list ap; + va_start(ap, zFormat); + if( stdout_is_console && (out==stdout || out==stderr) ){ + extern char *sqlite3_win32_utf8_to_mbcs(const char*); + char *z1 = sqlite3_vmprintf(zFormat, ap); + char *z2 = sqlite3_win32_utf8_to_mbcs(z1); + sqlite3_free(z1); + fputs(z2, out); + sqlite3_free(z2); + }else{ + vfprintf(out, zFormat, ap); + } + va_end(ap); +} +#elif !defined(utf8_printf) +# define utf8_printf fprintf +#endif + +/* +** Render output like fprintf(). This should not be used on anything that +** includes string formatting (e.g. "%s"). +*/ +#if !defined(raw_printf) +# define raw_printf fprintf +#endif + /* ** Write I/O traces to the following stream. */ @@ -382,7 +415,7 @@ static void SQLITE_CDECL iotracePrintf(const char *zFormat, ...){ va_start(ap, zFormat); z = sqlite3_vmprintf(zFormat, ap); va_end(ap); - fprintf(iotrace, "%s", z); + utf8_printf(iotrace, "%s", z); sqlite3_free(z); } #endif @@ -539,39 +572,6 @@ static char *one_input_line(FILE *in, char *zPrior, int isContinuation){ return zResult; } -/* -** Render output like fprintf(). Except, if the output is going to the -** console and if this is running on a Windows machine, translate the -** output from UTF-8 into MBCS. -*/ -#if defined(_WIN32) || defined(WIN32) -void utf8_printf(FILE *out, const char *zFormat, ...){ - va_list ap; - va_start(ap, zFormat); - if( stdout_is_console && (out==stdout || out==stderr) ){ - extern char *sqlite3_win32_utf8_to_mbcs(const char*); - char *z1 = sqlite3_vmprintf(zFormat, ap); - char *z2 = sqlite3_win32_utf8_to_mbcs(z1); - sqlite3_free(z1); - fputs(z2, out); - sqlite3_free(z2); - }else{ - vfprintf(out, zFormat, ap); - } - va_end(ap); -} -#elif !defined(utf8_printf) -# define utf8_printf fprintf -#endif - -/* -** Render output like fprintf(). This should not be used on anything that -** includes string formatting (e.g. "%s"). -*/ -#if !defined(raw_printf) -# define raw_printf fprintf -#endif - /* ** Shell output mode information from before ".explain on", ** saved so that it can be restored by ".explain off" From 2beb2c390bc7e25996f44b847ef1e080909d6b10 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 21 Jan 2016 17:25:56 +0000 Subject: [PATCH 0144/1484] Disable the RESTRICT foreign key action if "PRAGMA defer_foreign_keys" is set. FossilOrigin-Name: 82470d1c3a41221c78bcdd402b2219c4c21c43af --- manifest | 19 +++++++++-------- manifest.uuid | 2 +- src/fkey.c | 3 +++ test/fkey6.test | 54 +++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 69 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 5649e90988..66d0b52411 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sthe\sLIKE-operator\sbug\sfix\sfrom\strunk. -D 2016-01-20T16:02:48.763 +C Disable\sthe\sRESTRICT\sforeign\skey\saction\sif\s"PRAGMA\sdefer_foreign_keys"\sis\sset. +D 2016-01-21T17:25:56.966 F Makefile.in a47ec69daac0cdfe3413e50ceea6dc8da3dc4ecb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b4d0270955b3f102214b2242f2a1b802c22ee21b @@ -320,7 +320,7 @@ F src/dbstat.c ffd63fc8ba7541476ced189b95e95d7f2bc63f78 F src/delete.c 86e3940d07fe69a40270c2aaf6ca6c7adf19246c F src/expr.c df0d7c3230d59abd679da22ff5ce4cfd0e3a0e63 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb -F src/fkey.c e18b3dff7d47c7bcac5ac4fc178a89b9fd322b44 +F src/fkey.c 3fd2e17526d8586fdeafa376672c9303b7e35e7f F src/func.c ba6c03f9e440f5693086c08ee88e6e60212b3504 F src/global.c bd5a0af3f30b0c01be6db756c626cd3c33a3d260 F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5 @@ -656,7 +656,7 @@ F test/fkey2.test f3d27ecba480a348c328965d154214719bb158a9 F test/fkey3.test 76d475c80b84ee7a5d062e56ccb6ea68882e2b49 F test/fkey4.test 86446017011273aad8f9a99c1a65019e7bd9ca9d F test/fkey5.test 5a373303f201ac03c22ba1ef17a733d3f56e611a -F test/fkey6.test 6697550baa38505c9952eff130ab26a2d156c0cc +F test/fkey6.test d078a1e323a740062bed38df32b8a736fd320dc0 F test/fkey7.test 72e915890ee4a005daaf3002cb208e8fe973ac13 F test/fkey8.test 8f08203458321e6c19a263829de4cfc936274ab0 F test/fkey_malloc.test 594a7ea1fbab553c036c70813cd8bd9407d63749 @@ -1440,7 +1440,10 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 327af5f644a49b2f41d5456958f9d61a2b704e1c e8adeb64d4e463772feb58dbd6f00715b92e735c -R ed9d6c66302fd811ae6a8e53c4d95620 -U drh -Z 8662dc0834e686268b7ae44f172fcd73 +P 36cb3d6e274a06a78693ca506feaad0b14bde11d +R f0ee48a1a8d6b1b8328a4821e1589857 +T *branch * disable-restrict +T *sym-disable-restrict * +T -sym-sessions * +U dan +Z 284a240298ca9699332d11236aa182a9 diff --git a/manifest.uuid b/manifest.uuid index df02854c57..f82434f679 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -36cb3d6e274a06a78693ca506feaad0b14bde11d \ No newline at end of file +82470d1c3a41221c78bcdd402b2219c4c21c43af \ No newline at end of file diff --git a/src/fkey.c b/src/fkey.c index 2abd06c693..8ad6cfbe78 100644 --- a/src/fkey.c +++ b/src/fkey.c @@ -1163,6 +1163,9 @@ static Trigger *fkActionTrigger( action = pFKey->aAction[iAction]; pTrigger = pFKey->apTrigger[iAction]; + if( (db->flags & SQLITE_DeferFKs) && action==OE_Restrict ){ + return 0; + } if( action!=OE_None && !pTrigger ){ u8 enableLookaside; /* Copy of db->lookaside.bEnabled */ diff --git a/test/fkey6.test b/test/fkey6.test index 7c24704e03..b658f20fea 100644 --- a/test/fkey6.test +++ b/test/fkey6.test @@ -23,6 +23,7 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl +set testprefix fkey6 ifcapable {!foreignkey} { finish_test @@ -171,5 +172,58 @@ do_execsql_test fkey6-2.6 { PRAGMA defer_foreign_keys; } {0} +#-------------------------------------------------------------------------- +# Test that defer_foreign_keys disables RESTRICT. +# +do_execsql_test 3.1 { + CREATE TABLE p2(a PRIMARY KEY, b); + CREATE TABLE c2(x, y REFERENCES p2 ON DELETE RESTRICT ON UPDATE RESTRICT); + INSERT INTO p2 VALUES(1, 'one'); + INSERT INTO p2 VALUES(2, 'two'); + INSERT INTO c2 VALUES('i', 1); +} + +do_catchsql_test 3.2.1 { + BEGIN; + UPDATE p2 SET a=a-1; +} {1 {FOREIGN KEY constraint failed}} +do_execsql_test 3.2.2 { COMMIT } + +do_execsql_test 3.2.3 { + BEGIN; + PRAGMA defer_foreign_keys = 1; + UPDATE p2 SET a=a-1; + COMMIT; +} + +do_execsql_test 3.2.4 { + BEGIN; + PRAGMA defer_foreign_keys = 1; + UPDATE p2 SET a=a-1; +} +do_catchsql_test 3.2.5 { + COMMIT; +} {1 {FOREIGN KEY constraint failed}} +do_execsql_test 3.2.6 { ROLLBACK } + +do_execsql_test 3.3.1 { + CREATE TRIGGER p2t AFTER DELETE ON p2 BEGIN + INSERT INTO p2 VALUES(old.a, 'deleted!'); + END; +} +do_catchsql_test 3.3.2 { + BEGIN; + DELETE FROM p2 WHERE a=1; +} {1 {FOREIGN KEY constraint failed}} +do_execsql_test 3.3.3 { COMMIT } + +do_execsql_test 3.3.4 { + BEGIN; + PRAGMA defer_foreign_keys = 1; + DELETE FROM p2 WHERE a=1; + COMMIT; + SELECT * FROM p2; +} {0 one 1 deleted!} + finish_test From 6cc16fc07066ece41e82400b8059693eb7ff93fe Mon Sep 17 00:00:00 2001 From: mistachkin Date: Sat, 23 Jan 2016 01:54:15 +0000 Subject: [PATCH 0145/1484] Cleanup localtime() support for Windows CE. FossilOrigin-Name: 39759a553208d8ef72964bdd539a0883e1d99cf6 --- manifest | 19 +++++++++++-------- manifest.uuid | 2 +- src/date.c | 2 +- src/os_win.c | 14 +++++++++----- src/sqliteInt.h | 10 ++++++++++ 5 files changed, 32 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index 61cf5d66ed..257bc12719 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C More\swork\son\sthe\sMSVC\sbuild. -D 2016-01-23T00:07:51.151 +C Cleanup\slocaltime()\ssupport\sfor\sWindows\sCE. +D 2016-01-23T01:54:15.466 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1708a78eda223b6daa302b140037fcc214a779f9 @@ -295,7 +295,7 @@ F src/build.c b4eba1e84752ec9cae7ff3dacd5a8b6d1ab8deb9 F src/callback.c 29ae4faba226c7ebb9aee93016b5ce8a8f071261 F src/complete.c addcd8160b081131005d5bc2d34adf20c1c5c92f F src/ctime.c 60e135af364d777a9ab41c97e5e89cd224da6198 -F src/date.c 997651e3ee6c2818fbf7fcdb7156cef9eb3ece20 +F src/date.c 6142d9e4d25fa5ec78f44644c411ee64b5bfbdd0 F src/dbstat.c b2ec6793eef97aebb4d171d490a4ffdfa9f2475c F src/delete.c 00af9f08a15ddc5cba5962d3d3e5bf2d67b2e7da F src/expr.c d10c1cdef5810cdbf73adc9f9b383684230b360a @@ -330,7 +330,7 @@ F src/os.h 3e57a24e2794a94d3cf2342c6d9a884888cd96bf F src/os_common.h abdb9a191a367793268fe553d25bab894e986a0e F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa F src/os_unix.c 0eb7f469fcd4e1fbedf30060438e26b839ec5486 -F src/os_win.c 386fba30419e8458b13209781c2af5590eab2811 +F src/os_win.c 3cd1dbb6800a1996f25c027850e512d0631d4cf6 F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c f4e9ac39fbb1e0fde97af85c0f4e00eb90764b67 F src/pager.h 1c2a49143dfba9e69cc8159ef019f472ed8d260b @@ -350,7 +350,7 @@ F src/shell.c dcd7a83645ef2a58ee9c6d0ea4714d877d7835c4 F src/sqlite.h.in 214476a62012e578f42133a9a3b4f97a9aa421a3 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h dfbe62ffd95b99afe2140d8c35b180d11924072d -F src/sqliteInt.h 74e10a74116df0aec9d4a3e134f1a86cc34c2f14 +F src/sqliteInt.h ba1dd2b253f256353493c674425b54e0cd1e2409 F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46 F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e @@ -1419,7 +1419,10 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P a1c8116ced62d81f3f5ca26bbe0877e829d4cc56 -R b34246fa017fc0ae2e7bf7cb484e3eeb +P a79c46bc61a35edbaf6112c26e8052314b0eb16a +R 84f9a6399ea3db7dae9e4103397ece9e +T *branch * winCeLocalTime +T *sym-winCeLocalTime * +T -sym-trunk * U mistachkin -Z ba075ff448ff99fa520b3503324fe6e9 +Z 786b4c57551387fde5512893dcf278e2 diff --git a/manifest.uuid b/manifest.uuid index d1ea2b33a4..4891a746f3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a79c46bc61a35edbaf6112c26e8052314b0eb16a \ No newline at end of file +39759a553208d8ef72964bdd539a0883e1d99cf6 \ No newline at end of file diff --git a/src/date.c b/src/date.c index d78e83cf57..7d013316ad 100644 --- a/src/date.c +++ b/src/date.c @@ -418,6 +418,7 @@ static void clearYMD_HMS_TZ(DateTime *p){ p->validTZ = 0; } +#ifndef SQLITE_OMIT_LOCALTIME /* ** On recent Windows platforms, the localtime_s() function is available ** as part of the "Secure CRT". It is essentially equivalent to @@ -436,7 +437,6 @@ static void clearYMD_HMS_TZ(DateTime *p){ #define HAVE_LOCALTIME_S 1 #endif -#ifndef SQLITE_OMIT_LOCALTIME /* ** The following routine implements the rough equivalent of localtime_r() ** using whatever operating-system specific localtime facility that diff --git a/src/os_win.c b/src/os_win.c index c54bfd6a90..d46eb77c52 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -1986,16 +1986,16 @@ static void winLogIoerr(int nRetry, int lineno){ } } -#if SQLITE_OS_WINCE -/************************************************************************* -** This section contains code for WinCE only. +/* +** This #if cannot use SQLITE_OS_WINCE because the corresponding section +** in "sqliteInt.h" does not use it. */ -#if !defined(SQLITE_MSVC_LOCALTIME_API) || !SQLITE_MSVC_LOCALTIME_API +#if defined(_WIN32_WCE) && \ + (!defined(SQLITE_MSVC_LOCALTIME_API) || !SQLITE_MSVC_LOCALTIME_API) /* ** The MSVC CRT on Windows CE may not have a localtime() function. So ** create a substitute. */ -#include struct tm *__cdecl localtime(const time_t *t) { static struct tm y; @@ -2019,6 +2019,10 @@ struct tm *__cdecl localtime(const time_t *t) } #endif +#if SQLITE_OS_WINCE +/************************************************************************* +** This section contains code for WinCE only. +*/ #define HANDLE_TO_WINFILE(a) (winFile*)&((char*)a)[-(int)offsetof(winFile,h)] /* diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 1a8a5d3a5b..46abeb0de1 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -218,6 +218,16 @@ # endif #endif +/* +** The MSVC CRT on Windows CE may not have a localtime() function. So +** declare a substitute. The function itself is defined in "os_win.c". +*/ +#if defined(_WIN32_WCE) && \ + (!defined(SQLITE_MSVC_LOCALTIME_API) || !SQLITE_MSVC_LOCALTIME_API) +# include +struct tm *__cdecl localtime(const time_t *); +#endif + /* ** The SQLITE_THREADSAFE macro must be defined as 0, 1, or 2. ** 0 means mutexes are permanently disable and the library is never From 6fee795885e8d4c5032e40d58892caa0861e2f14 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 13 Feb 2016 14:39:46 +0000 Subject: [PATCH 0146/1484] Fix a problem in sessionfault.test causing it to segfault following a test failure. This commit does not fix the actual test failure - just the subsequent segfault. FossilOrigin-Name: 582b2ae77d65b1e142ceb5774f37b0aaa3851378 --- ext/session/sessionfault.test | 3 ++- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/ext/session/sessionfault.test b/ext/session/sessionfault.test index 39f27bfe6d..dfe15a50c8 100644 --- a/ext/session/sessionfault.test +++ b/ext/session/sessionfault.test @@ -361,7 +361,7 @@ do_faultsim_test 6 -faults oom-* -body { } faultsim_delete_and_reopen -do_execsql_test 5.prep1 { +do_execsql_test 7.prep1 { CREATE TABLE t1(a, b, PRIMARY KEY(a)); } faultsim_save_and_close @@ -372,6 +372,7 @@ for {set ::i 0} {$::i < 480} {incr ::i 4} { } set res [lsort $res] do_faultsim_test 7 -faults oom-transient -prep { + catch { S delete } faultsim_restore_and_reopen sqlite3session S db main S attach * diff --git a/manifest b/manifest index 3107e34770..4fc05623b8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sthe\schanges\sfor\sthe\s3.11.0\srelease\scandidate\sfrom\strunk. -D 2016-02-13T14:07:56.771 +C Fix\sa\sproblem\sin\ssessionfault.test\scausing\sit\sto\ssegfault\sfollowing\sa\stest\sfailure.\sThis\scommit\sdoes\snot\sfix\sthe\sactual\stest\sfailure\s-\sjust\sthe\ssubsequent\ssegfault. +D 2016-02-13T14:39:46.492 F Makefile.in 5cbf3f753328d1bcd3a6117785b4874d99612f8f F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 45e596bd4ccecf2256f68a2e96466aa52cc4bc1f @@ -282,7 +282,7 @@ F ext/session/sessionD.test d4744c78334162851d2a2f285c7e603e31b49aa2 F ext/session/sessionE.test e60a238c47f0feb3bb707e7f35e22be09c7e8f26 F ext/session/sessionF.test c2f178d4dfd723a5fd94a730ea2ccb44c669e3ce F ext/session/session_common.tcl a1293167d14774b5e728836720497f40fe4ea596 -F ext/session/sessionfault.test bef044d0952c0d62c31c8d2400be72c8684545cc +F ext/session/sessionfault.test 94a4dd100e16cf0b1c44d8487517dbb407eeab1d F ext/session/sqlite3session.c 1ace1d1e4cb32cf60ca6e8ed1ae8d4c9f99ca458 F ext/session/sqlite3session.h 64e9e7f185725ef43b97f4a9a0c0df0669844f1d F ext/session/test_session.c 187bd344c5ae9d5be85e22ef7c3010f0c17307ce @@ -1448,7 +1448,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh ef6ebc6fd8d2dc35db3b622015c16a023d4fef4f F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P f040a5bb62f3473fba6450c97c68f538d1df21ef a049fbbde5da2e43d41aa8c2b41f9eb21507ac76 -R 622532d44eb7d789368cb4bcd5c9c290 -U drh -Z 7f2e42b2e725136d738cebdbb2b0b796 +P 4d7a802e73ef0352f840bc8d74c560afb7666ff7 +R 56ec775a8f26a6fc9784a8bb5f2be4e3 +U dan +Z 3166b3068d23321aad4e67ff074e960a diff --git a/manifest.uuid b/manifest.uuid index 1b543c3534..c918008c70 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4d7a802e73ef0352f840bc8d74c560afb7666ff7 \ No newline at end of file +582b2ae77d65b1e142ceb5774f37b0aaa3851378 \ No newline at end of file From 50d348b1e1dca5f05f79843e8f01dbf7b3572285 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 13 Feb 2016 14:45:56 +0000 Subject: [PATCH 0147/1484] Harden sqlite3session_delete() against trying to delete a session that is not currently on the session list. FossilOrigin-Name: 6c2d34df76fb7823f307c11a1135ab30674421a9 --- ext/session/sqlite3session.c | 10 +++++++--- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index 546a22a072..312e03dcfb 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -1615,9 +1615,13 @@ void sqlite3session_delete(sqlite3_session *pSession){ ** database handle. Hold the db mutex while doing so. */ sqlite3_mutex_enter(sqlite3_db_mutex(db)); pHead = (sqlite3_session*)sqlite3_preupdate_hook(db, 0, 0); - for(pp=&pHead; (*pp)!=pSession; pp=&((*pp)->pNext)); - *pp = (*pp)->pNext; - if( pHead ) sqlite3_preupdate_hook(db, xPreUpdate, (void *)pHead); + for(pp=&pHead; ALWAYS((*pp)!=0); pp=&((*pp)->pNext)){ + if( (*pp)==pSession ){ + *pp = (*pp)->pNext; + if( pHead ) sqlite3_preupdate_hook(db, xPreUpdate, (void*)pHead); + break; + } + } sqlite3_mutex_leave(sqlite3_db_mutex(db)); /* Delete all attached table objects. And the contents of their diff --git a/manifest b/manifest index 4fc05623b8..27189df562 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\sin\ssessionfault.test\scausing\sit\sto\ssegfault\sfollowing\sa\stest\sfailure.\sThis\scommit\sdoes\snot\sfix\sthe\sactual\stest\sfailure\s-\sjust\sthe\ssubsequent\ssegfault. -D 2016-02-13T14:39:46.492 +C Harden\ssqlite3session_delete()\sagainst\strying\sto\sdelete\sa\ssession\sthat\nis\snot\scurrently\son\sthe\ssession\slist. +D 2016-02-13T14:45:56.852 F Makefile.in 5cbf3f753328d1bcd3a6117785b4874d99612f8f F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 45e596bd4ccecf2256f68a2e96466aa52cc4bc1f @@ -283,7 +283,7 @@ F ext/session/sessionE.test e60a238c47f0feb3bb707e7f35e22be09c7e8f26 F ext/session/sessionF.test c2f178d4dfd723a5fd94a730ea2ccb44c669e3ce F ext/session/session_common.tcl a1293167d14774b5e728836720497f40fe4ea596 F ext/session/sessionfault.test 94a4dd100e16cf0b1c44d8487517dbb407eeab1d -F ext/session/sqlite3session.c 1ace1d1e4cb32cf60ca6e8ed1ae8d4c9f99ca458 +F ext/session/sqlite3session.c b10af3e87ae437bb197b3a23a584d2dc8ad8981a F ext/session/sqlite3session.h 64e9e7f185725ef43b97f4a9a0c0df0669844f1d F ext/session/test_session.c 187bd344c5ae9d5be85e22ef7c3010f0c17307ce F ext/userauth/sqlite3userauth.h 19cb6f0e31316d0ee4afdfb7a85ef9da3333a220 @@ -1448,7 +1448,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh ef6ebc6fd8d2dc35db3b622015c16a023d4fef4f F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 4d7a802e73ef0352f840bc8d74c560afb7666ff7 -R 56ec775a8f26a6fc9784a8bb5f2be4e3 -U dan -Z 3166b3068d23321aad4e67ff074e960a +P 582b2ae77d65b1e142ceb5774f37b0aaa3851378 +R 99d33fcea6ce08ff5ef828796adb3d5d +U drh +Z 9efd5fb5a4c4d606f6b8046dd50f3f7a diff --git a/manifest.uuid b/manifest.uuid index c918008c70..d7c3afaaf6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -582b2ae77d65b1e142ceb5774f37b0aaa3851378 \ No newline at end of file +6c2d34df76fb7823f307c11a1135ab30674421a9 \ No newline at end of file From a66e386225cc63ef5becf5b9299ddeb17299e1c3 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 13 Feb 2016 15:08:25 +0000 Subject: [PATCH 0148/1484] Fix another test problem in sessionfault.test. FossilOrigin-Name: f6d1cf79437f892220e93635c377513160ee7fd7 --- ext/session/sessionfault.test | 4 ++-- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/ext/session/sessionfault.test b/ext/session/sessionfault.test index dfe15a50c8..6560ea8755 100644 --- a/ext/session/sessionfault.test +++ b/ext/session/sessionfault.test @@ -389,8 +389,8 @@ do_faultsim_test 7 -faults oom-transient -prep { error "Expected {0 $::res} Got {$cres}" } } else { - S changeset - S delete + catch { S changeset } + catch { S delete } } } diff --git a/manifest b/manifest index 27189df562..cd68f2e235 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Harden\ssqlite3session_delete()\sagainst\strying\sto\sdelete\sa\ssession\sthat\nis\snot\scurrently\son\sthe\ssession\slist. -D 2016-02-13T14:45:56.852 +C Fix\sanother\stest\sproblem\sin\ssessionfault.test. +D 2016-02-13T15:08:25.504 F Makefile.in 5cbf3f753328d1bcd3a6117785b4874d99612f8f F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 45e596bd4ccecf2256f68a2e96466aa52cc4bc1f @@ -282,7 +282,7 @@ F ext/session/sessionD.test d4744c78334162851d2a2f285c7e603e31b49aa2 F ext/session/sessionE.test e60a238c47f0feb3bb707e7f35e22be09c7e8f26 F ext/session/sessionF.test c2f178d4dfd723a5fd94a730ea2ccb44c669e3ce F ext/session/session_common.tcl a1293167d14774b5e728836720497f40fe4ea596 -F ext/session/sessionfault.test 94a4dd100e16cf0b1c44d8487517dbb407eeab1d +F ext/session/sessionfault.test d52cbb7bee48cc8ee80335e07eb72fcb6b15eb40 F ext/session/sqlite3session.c b10af3e87ae437bb197b3a23a584d2dc8ad8981a F ext/session/sqlite3session.h 64e9e7f185725ef43b97f4a9a0c0df0669844f1d F ext/session/test_session.c 187bd344c5ae9d5be85e22ef7c3010f0c17307ce @@ -1448,7 +1448,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh ef6ebc6fd8d2dc35db3b622015c16a023d4fef4f F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 582b2ae77d65b1e142ceb5774f37b0aaa3851378 -R 99d33fcea6ce08ff5ef828796adb3d5d -U drh -Z 9efd5fb5a4c4d606f6b8046dd50f3f7a +P 6c2d34df76fb7823f307c11a1135ab30674421a9 +R aed6007c61153b78ae015657d3f9bbb0 +U dan +Z 2a607f92ff5c33f0d10318ab25e2fc68 diff --git a/manifest.uuid b/manifest.uuid index d7c3afaaf6..8004dd0734 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6c2d34df76fb7823f307c11a1135ab30674421a9 \ No newline at end of file +f6d1cf79437f892220e93635c377513160ee7fd7 \ No newline at end of file From 089555c8e9fabb1b19db0ad03b5b31936af7a98f Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 15 Mar 2016 09:55:44 +0000 Subject: [PATCH 0149/1484] Fix the shellN.test test scripts so that they work with the --testdir option. FossilOrigin-Name: 051c61ebae921b70f843c55aacf046a9922cc187 --- manifest | 24 ++++++++++++------------ manifest.uuid | 2 +- test/shell1.test | 10 +--------- test/shell2.test | 10 +--------- test/shell3.test | 10 +--------- test/shell4.test | 10 +--------- test/shell5.test | 10 +--------- test/tester.tcl | 18 ++++++++++++++++++ 8 files changed, 36 insertions(+), 58 deletions(-) diff --git a/manifest b/manifest index 056a1fb6f3..c36b917a58 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\spermutations.test\sscript\sso\sthat\sit\sworks\sagain. -D 2016-03-14T21:26:25.596 +C Fix\sthe\sshellN.test\stest\sscripts\sso\sthat\sthey\swork\swith\sthe\s--testdir\soption. +D 2016-03-15T09:55:44.853 F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66 @@ -1025,11 +1025,11 @@ F test/sharedA.test 0cdf1a76dfa00e6beee66af5b534b1e8df2720f5 F test/sharedB.test 16cc7178e20965d75278f410943109b77b2e645e F test/shared_err.test 2f2aee20db294b9924e81f6ccbe60f19e21e8506 F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304 -F test/shell1.test a45b424ec23a4b946848ff9e1af5186c677162ab -F test/shell2.test 12b8bf901b0e3a8ac58cf5c0c63a0a388d4d1862 -F test/shell3.test 5e8545ec72c4413a0e8d4c6be56496e3c257ca29 -F test/shell4.test f43e250139dc5dc5f0f2ec1752c50284a1ede102 -F test/shell5.test c04e9f9f948305706b88377c464c7f08ce7479f9 +F test/shell1.test e7dac9830b7d80432be9cebfae06eff9c18675f5 +F test/shell2.test 2e7a32c9ee03c6398478637d72416d5b9ebd9777 +F test/shell3.test c39453d3012a39ffec944566eca8a6bda10a2284 +F test/shell4.test 69995ee1cc278eb149aa8746ce1f935f4eaf98b9 +F test/shell5.test 50a732c1c2158b1cd62cf53975ce1ea7ce6b9dc9 F test/shortread1.test bb591ef20f0fd9ed26d0d12e80eee6d7ac8897a3 F test/show_speedtest1_rtree.tcl 32e6c5f073d7426148a6936a0408f4b5b169aba5 F test/shrink.test 1b4330b1fd9e818c04726d45cb28db73087535ce @@ -1085,7 +1085,7 @@ F test/tclsqlite.test c6d9f546f79d15d0134c1e06583fb3ee0c3afad3 F test/tempdb.test bd92eba8f20e16a9136e434e20b280794de3cdb6 F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30 F test/temptrigger.test 8ec228b0db5d7ebc4ee9b458fc28cb9e7873f5e1 -F test/tester.tcl d6dee24773e20320ab64d39bb5ce6e1a91b6029e +F test/tester.tcl 859a7ccbe5bd65f0f8b524cd51c318d3edcd3008 F test/thread001.test 9f22fd3525a307ff42a326b6bc7b0465be1745a5 F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58 F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7 @@ -1456,7 +1456,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P f4693ba4bbd9738b45012cf507fc0d7b6d04b7ee -R b91725f8858bc448d609dcaeb28fa81e -U drh -Z 51ddcfc985bc0e936856bdb8a64dca36 +P 9f194f90c07d5415b1d6bb10ec049f74999d6885 +R 50980fd60bfbb727ae154c36fe3906ce +U dan +Z f0681fd41f2ae1a8be1bbfb650e8fc11 diff --git a/manifest.uuid b/manifest.uuid index bac1f45a16..77d14b9109 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9f194f90c07d5415b1d6bb10ec049f74999d6885 \ No newline at end of file +051c61ebae921b70f843c55aacf046a9922cc187 \ No newline at end of file diff --git a/test/shell1.test b/test/shell1.test index 1b9ea1d383..1f1f3de320 100644 --- a/test/shell1.test +++ b/test/shell1.test @@ -21,15 +21,7 @@ # set testdir [file dirname $argv0] source $testdir/tester.tcl -if {$tcl_platform(platform)=="windows"} { - set CLI "sqlite3.exe" -} else { - set CLI "./sqlite3" -} -if {![file executable $CLI]} { - finish_test - return -} +set CLI [test_find_cli] db close forcedelete test.db test.db-journal test.db-wal sqlite3 db test.db diff --git a/test/shell2.test b/test/shell2.test index 616610bd4b..9388b719b3 100644 --- a/test/shell2.test +++ b/test/shell2.test @@ -20,15 +20,7 @@ # set testdir [file dirname $argv0] source $testdir/tester.tcl -if {$tcl_platform(platform)=="windows"} { - set CLI "sqlite3.exe" -} else { - set CLI "./sqlite3" -} -if {![file executable $CLI]} { - finish_test - return -} +set CLI [test_find_cli] db close forcedelete test.db test.db-journal test.db-wal sqlite3 db test.db diff --git a/test/shell3.test b/test/shell3.test index ce1fd4ecb5..3ded8f5ccd 100644 --- a/test/shell3.test +++ b/test/shell3.test @@ -21,15 +21,7 @@ # set testdir [file dirname $argv0] source $testdir/tester.tcl -if {$tcl_platform(platform)=="windows"} { - set CLI "sqlite3.exe" -} else { - set CLI "./sqlite3" -} -if {![file executable $CLI]} { - finish_test - return -} +set CLI [test_find_cli] db close forcedelete test.db test.db-journal test.db-wal sqlite3 db test.db diff --git a/test/shell4.test b/test/shell4.test index 18e7d7fdf6..3e4ae55816 100644 --- a/test/shell4.test +++ b/test/shell4.test @@ -21,15 +21,7 @@ # set testdir [file dirname $argv0] source $testdir/tester.tcl -if {$tcl_platform(platform)=="windows"} { - set CLI "sqlite3.exe" -} else { - set CLI "./sqlite3" -} -if {![file executable $CLI]} { - finish_test - return -} +set CLI [test_find_cli] db close forcedelete test.db test.db-journal test.db-wal sqlite3 db test.db diff --git a/test/shell5.test b/test/shell5.test index b921accca5..bb2511a525 100644 --- a/test/shell5.test +++ b/test/shell5.test @@ -21,15 +21,7 @@ # set testdir [file dirname $argv0] source $testdir/tester.tcl -if {$tcl_platform(platform)=="windows"} { - set CLI "sqlite3.exe" -} else { - set CLI "./sqlite3" -} -if {![file executable $CLI]} { - finish_test - return -} +set CLI [test_find_cli] db close forcedelete test.db test.db-journal test.db-wal diff --git a/test/tester.tcl b/test/tester.tcl index 3a881138e2..1c83e34c0d 100644 --- a/test/tester.tcl +++ b/test/tester.tcl @@ -2136,6 +2136,24 @@ proc test_restore_config_pagecache {} { sqlite3 db test.db } +# Find the name of the 'shell' executable (e.g. "sqlite3.exe") to use for +# the tests in shell[1-5].test. If no such executable can be found, invoke +# [finish_test ; return] in the callers context. +# +proc test_find_cli {} { + if {$::tcl_platform(platform)=="windows"} { + set ret "sqlite3.exe" + } else { + set ret "sqlite3" + } + set ret [file normalize [file join $::cmdlinearg(TESTFIXTURE_HOME) $ret]] + if {![file executable $ret]} { + finish_test + return -code return + } + return $ret +} + # If the library is compiled with the SQLITE_DEFAULT_AUTOVACUUM macro set # to non-zero, then set the global variable $AUTOVACUUM to 1. set AUTOVACUUM $sqlite_options(default_autovacuum) From 82f525406af6e0ca6887a82c8bb561fac610fa59 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 15 Mar 2016 12:37:08 +0000 Subject: [PATCH 0150/1484] More test-case changes so that everything works when the reserved_bytes value in the header is non-zero. FossilOrigin-Name: 2fd095b14b03a508169bba710d2e8e2addf4b8f5 --- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- test/corrupt2.test | 44 +++++++++++++++++++++++--------------------- test/filefmt.test | 16 ++++++++++------ test/pageropt.test | 4 ++++ test/wal5.test | 6 +++--- 6 files changed, 51 insertions(+), 41 deletions(-) diff --git a/manifest b/manifest index c36b917a58..5b830ffdfa 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\sshellN.test\stest\sscripts\sso\sthat\sthey\swork\swith\sthe\s--testdir\soption. -D 2016-03-15T09:55:44.853 +C More\stest-case\schanges\sso\sthat\severything\sworks\swhen\sthe\sreserved_bytes\nvalue\sin\sthe\sheader\sis\snon-zero. +D 2016-03-15T12:37:08.820 F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66 @@ -548,7 +548,7 @@ F test/conflict2.test bb0b94cf7196c64a3cbd815c66d3ee98c2fecd9c F test/conflict3.test dec0634c0f31dec9a4b01c63063e939f0cd21b6b F test/contrib01.test 2a1cbc0f2f48955d7d073f725765da6fbceda6b4 F test/corrupt.test 141c39ea650c1365e85a49e402fa05cb9617fb97 -F test/corrupt2.test cb787825d761b0f869764d6990531382840de872 +F test/corrupt2.test e4964cee73dda57a90958e0087a6b388b1d9cb58 F test/corrupt3.test e676f478fe602915d721472811f6f410b75ddc7e F test/corrupt4.test 8d1d86b850fcc43e417450454f2044e52d55778a F test/corrupt5.test 8ead52af76006f3286e9396cb41898018ccea107 @@ -638,7 +638,7 @@ F test/extension01.test 00d13cec817f331a687a243e0e5a2d87b0e358c9 F test/extraquick.test cb254400bd42bfb777ff675356aabf3287978f79 F test/fallocate.test 3e979af17dfa7e5e9dda5eba1a696c04fa9d47f7 F test/filectrl.test 7c13f96457435238da99aff7343ad6a3a4885787 -F test/filefmt.test cb34663f126cbc2d358af552dcaf5c72769b0146 +F test/filefmt.test e4edbdc637ca9576ccf4337a3cce627d9df7a56c F test/fkey1.test 13e3d48236a2b9f5c5ebd232eef9b3ab682a8a2c F test/fkey2.test f3d27ecba480a348c328965d154214719bb158a9 F test/fkey3.test 76d475c80b84ee7a5d062e56ccb6ea68882e2b49 @@ -944,7 +944,7 @@ F test/pager4.test a122e9e6925d5b23b31e3dfef8c6a44bbf19590e F test/pagerfault.test ae9ee0db5a30aecda9db8290ce3dd12e5f7bbaa1 F test/pagerfault2.test caf4c7facb914fd3b03a17b31ae2b180c8d6ca1f F test/pagerfault3.test 1003fcda009bf48a8e22a516e193b6ef0dd1bbd8 -F test/pageropt.test f8d840f0fed84854dbd12b4c17fb3506eeb8224c +F test/pageropt.test 84e4cc5cbca285357f7906e99b21be4f2bf5abc0 F test/pagesize.test 5769fc62d8c890a83a503f67d47508dfdc543305 F test/parser1.test 222b5cbf3e2e659fec1bf7d723488c8b9c94f1d0 F test/pcache.test c8acbedd3b6fd0f9a7ca887a83b11d24a007972b @@ -1307,7 +1307,7 @@ F test/wal.test 613efec03e517e1775d86b993a54877d2e29a477 F test/wal2.test 25ae059e900dbb584e0775627e45415ba5940df1 F test/wal3.test 5dd734147f1f8f958c5261a1f2775d346d7013ce F test/wal4.test 4744e155cd6299c6bd99d3eab1c82f77db9cdb3c -F test/wal5.test 22cb252502c5ff851925add2ca8a7e2af012e1d6 +F test/wal5.test 9c11da7aeccd83a46d79a556ad11a18d3cb15aa9 F test/wal6.test a9d6aa635b9d63607dabdc11406f5f96ca986635 F test/wal64k.test 163655ecd2cb8afef4737cac2a40fdd2eeaf20b8 F test/wal7.test 2ae8f427d240099cc4b2dfef63cff44e2a68a1bd @@ -1456,7 +1456,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 9f194f90c07d5415b1d6bb10ec049f74999d6885 -R 50980fd60bfbb727ae154c36fe3906ce -U dan -Z f0681fd41f2ae1a8be1bbfb650e8fc11 +P 051c61ebae921b70f843c55aacf046a9922cc187 +R 1b522ee9926e242e3422d1eddaaf0fbf +U drh +Z 3fc58440746cd83f06c07d7c16cdd74a diff --git a/manifest.uuid b/manifest.uuid index 77d14b9109..e76d63af73 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -051c61ebae921b70f843c55aacf046a9922cc187 \ No newline at end of file +2fd095b14b03a508169bba710d2e8e2addf4b8f5 \ No newline at end of file diff --git a/test/corrupt2.test b/test/corrupt2.test index 9bd29cf90f..efeb26bc8a 100644 --- a/test/corrupt2.test +++ b/test/corrupt2.test @@ -346,27 +346,29 @@ ifcapable autovacuum { } {1 {database disk image is malformed}} } - corruption_test -sqlprep { - PRAGMA auto_vacuum = 1; - PRAGMA page_size = 1024; - CREATE TABLE t1(a INTEGER PRIMARY KEY, b); - INSERT INTO t1 VALUES(1, randomblob(2500)); - DELETE FROM t1 WHERE a = 1; - } -corrupt { - set nAppend [expr 1024*207 - [file size corrupt.db]] - set fd [open corrupt.db r+] - seek $fd 0 end - puts -nonewline $fd [string repeat x $nAppend] - close $fd - hexio_write corrupt.db 28 00000000 - } -test { - do_test corrupt2-6.4 { - catchsql " - $::presql - BEGIN EXCLUSIVE; - COMMIT; - " - } {1 {database disk image is malformed}} + if {![nonzero_reserved_bytes]} { + corruption_test -sqlprep { + PRAGMA auto_vacuum = 1; + PRAGMA page_size = 1024; + CREATE TABLE t1(a INTEGER PRIMARY KEY, b); + INSERT INTO t1 VALUES(1, randomblob(2500)); + DELETE FROM t1 WHERE a = 1; + } -corrupt { + set nAppend [expr 1024*207 - [file size corrupt.db]] + set fd [open corrupt.db r+] + seek $fd 0 end + puts -nonewline $fd [string repeat x $nAppend] + close $fd + hexio_write corrupt.db 28 00000000 + } -test { + do_test corrupt2-6.4 { + catchsql " + $::presql + BEGIN EXCLUSIVE; + COMMIT; + " + } {1 {database disk image is malformed}} + } } } diff --git a/test/filefmt.test b/test/filefmt.test index 2df1424436..087a955c39 100644 --- a/test/filefmt.test +++ b/test/filefmt.test @@ -144,9 +144,11 @@ do_execsql_test filefmt-2.1.1 { CREATE TABLE t2(a); INSERT INTO t2 VALUES(1); } {} -do_test filefmt-2.1.2 { - hexio_read test.db 28 4 -} {00000009} +if {![nonzero_reserved_bytes]} { + do_test filefmt-2.1.2 { + hexio_read test.db 28 4 + } {00000009} +} do_test filefmt-2.1.3 { sql36231 { INSERT INTO t1 VALUES(a_string(3000)) } @@ -170,9 +172,11 @@ do_execsql_test filefmt-2.2.1 { CREATE TABLE t2(a); INSERT INTO t2 VALUES(1); } {} -do_test filefmt-2.2.2 { - hexio_read test.db 28 4 -} {00000009} +if {![nonzero_reserved_bytes]} { + do_test filefmt-2.2.2 { + hexio_read test.db 28 4 + } {00000009} +} do_test filefmt-2.2.3 { sql36231 { INSERT INTO t1 VALUES(a_string(3000)) } diff --git a/test/pageropt.test b/test/pageropt.test index f8f5c71892..f58b8ee781 100644 --- a/test/pageropt.test +++ b/test/pageropt.test @@ -23,6 +23,10 @@ ifcapable {!pager_pragmas||secure_delete||direct_read} { return } +# A non-zero reserved_bytes value changes the number of pages in the +# database file, which messes up the results in this test. +if {[nonzero_reserved_bytes]} {finish_test; return;} + # Run the SQL statement supplied by the argument and return # the results. Prepend four integers to the beginning of the # result which are diff --git a/test/wal5.test b/test/wal5.test index 0f6dcfa6a7..50c517286a 100644 --- a/test/wal5.test +++ b/test/wal5.test @@ -141,13 +141,13 @@ foreach {testprefix do_wal_checkpoint} { do_test 1.$tn.7 { reopen_all list [db_page_count] [wal_page_count] $::nBusyHandler - } {7 0 0} + } [expr {[nonzero_reserved_bytes]?"/# # 0/":"7 0 0"}] do_test 1.$tn.8 { sql2 { BEGIN ; SELECT x FROM t1 } } {1 2 3 4 5} do_test 1.$tn.9 { sql1 { INSERT INTO t1 VALUES(6, zeroblob(1200)) } list [db_page_count] [wal_page_count] $::nBusyHandler - } {7 5 0} + } [expr {[nonzero_reserved_bytes]?"/# # #/":"7 5 0"}] do_test 1.$tn.10 { sql3 { BEGIN ; SELECT x FROM t1 } } {1 2 3 4 5 6} set ::busy_handler_script { @@ -158,7 +158,7 @@ foreach {testprefix do_wal_checkpoint} { do_test 1.$tn.11 { code1 { do_wal_checkpoint db -mode restart } list [db_page_count] [wal_page_count] $::nBusyHandler - } {10 5 8} + } [expr {[nonzero_reserved_bytes]?"/# # #/":"10 5 8"}] do_test 1.$tn.12 { set ::db_file_size } 10 } From 0ff47e9e1b74e270648cac1ea72f9bcf4e35031d Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 15 Mar 2016 17:52:12 +0000 Subject: [PATCH 0151/1484] Implement FROM-clause subqueries as co-routines whenever they are guaranteed to be the outer-most loop of the join. FossilOrigin-Name: c7bae50bdccb5bcf3bc22e8ac5bb6725ef13db39 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/select.c | 20 +++++++++++++++++--- test/select4.test | 37 ++++++++++++++++++++++++++++++++++++- 4 files changed, 61 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 5b830ffdfa..61ece923e2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C More\stest-case\schanges\sso\sthat\severything\sworks\swhen\sthe\sreserved_bytes\nvalue\sin\sthe\sheader\sis\snon-zero. -D 2016-03-15T12:37:08.820 +C Implement\sFROM-clause\ssubqueries\sas\sco-routines\swhenever\sthey\sare\sguaranteed\nto\sbe\sthe\souter-most\sloop\sof\sthe\sjoin. +D 2016-03-15T17:52:12.224 F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66 @@ -350,7 +350,7 @@ F src/printf.c 63e6fb12bbe702dd664dc3703776c090383a5a26 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c b8f7174e5f8c33c44ded3a25a973d0bb89228c20 F src/rowset.c 9fe4b3ad7cc00944386bb600233d8f523de07a6e -F src/select.c 137b31daa84d57d67847bf621bb54f3353e2077b +F src/select.c 6dd2097bb158efe3b8d68683dcc3b4a49e907a34 F src/shell.c 5e0ab1e708dc294330ccd8230536e1801f60822e F src/sqlite.h.in 0235586b3fb639e85998d495c90f007657fd82af F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -999,7 +999,7 @@ F test/securedel2.test 2d54c28e46eb1fd6902089958b20b1b056c6f1c5 F test/select1.test be62204d2bd9a5a8a149e9974cfddce893d8f686 F test/select2.test 352480e0e9c66eda9c3044e412abdf5be0215b56 F test/select3.test 2ce595f8fb8e2ac10071d3b4e424cadd4634a054 -F test/select4.test 453631158540e5f685b81cac5b7e8bd8c6b4c5fc +F test/select4.test d926792a5e4d88fef0ddcddeb45d27ce75f7296c F test/select5.test e758b8ef94f69b111df4cb819008856655dcd535 F test/select6.test 39eac4a5c03650b2b473c532882273283ee8b7a0 F test/select7.test 95e370c42d47c3c52377d05e9ffc01ccff7c1f61 @@ -1456,7 +1456,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 051c61ebae921b70f843c55aacf046a9922cc187 -R 1b522ee9926e242e3422d1eddaaf0fbf +P 2fd095b14b03a508169bba710d2e8e2addf4b8f5 +R dae03fc18d1aaaa839efcf6d42490a7e U drh -Z 3fc58440746cd83f06c07d7c16cdd74a +Z 042547ad8e59422492ad781582901ed5 diff --git a/manifest.uuid b/manifest.uuid index e76d63af73..b2a61f89c1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2fd095b14b03a508169bba710d2e8e2addf4b8f5 \ No newline at end of file +c7bae50bdccb5bcf3bc22e8ac5bb6725ef13db39 \ No newline at end of file diff --git a/src/select.c b/src/select.c index c9bc389b2f..a62581efc1 100644 --- a/src/select.c +++ b/src/select.c @@ -4970,10 +4970,24 @@ int sqlite3Select( } /* Generate code to implement the subquery + ** + ** The subquery is implemented as a co-routine if all of these are true: + ** (1) The subquery is guaranteed to be the outer loop (so that it + ** does not need to be computed more than once) + ** (2) The ALL keyword after SELECT is omitted. (Applications are + ** allowed to say "SELECT ALL" instead of just "SELECT" to disable + ** the use of co-routines.) + ** (3) Co-routines are not disabled using sqlite3_test_control() + ** with SQLITE_TESTCTRL_OPTIMIZATIONS. + ** + ** TODO: Are there other reasons beside (1) to use a co-routine + ** implementation? */ - if( pTabList->nSrc==1 - && (p->selFlags & SF_All)==0 - && OptimizationEnabled(db, SQLITE_SubqCoroutine) + if( i==0 + && (pTabList->nSrc==1 + || (pTabList->a[1].fg.jointype&(JT_LEFT|JT_CROSS))!=0) /* (1) */ + && (p->selFlags & SF_All)==0 /* (2) */ + && OptimizationEnabled(db, SQLITE_SubqCoroutine) /* (3) */ ){ /* Implement a co-routine that will return a single row of the result ** set on each invocation. diff --git a/test/select4.test b/test/select4.test index be8d0e0ab1..1f29f29073 100644 --- a/test/select4.test +++ b/test/select4.test @@ -12,7 +12,6 @@ # focus of this file is testing UNION, INTERSECT and EXCEPT operators # in SELECT statements. # -# $Id: select4.test,v 1.30 2009/04/16 00:24:24 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -936,4 +935,40 @@ do_execsql_test select4-15.1 { ORDER BY 1; } {1 33 456 2 33 789} +# Enhancement (2016-03-15): Use a co-routine for subqueries if the +# subquery is guaranteed to be the outer-most query +# +do_execsql_test select4-16.1 { + DROP TABLE IF EXISTS t1; + CREATE TABLE t1(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z, + PRIMARY KEY(a,b DESC)) WITHOUT ROWID; + + WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<100) + INSERT INTO t1(a,b,c,d) + SELECT x%10, x/10, x, printf('xyz%dabc',x) FROM c; + + SELECT t3.c FROM + (SELECT a,max(b) AS m FROM t1 WHERE a>=5 GROUP BY a) AS t2 + JOIN t1 AS t3 + WHERE t2.a=t3.a AND t2.m=t3.b + ORDER BY t3.a; +} {95 96 97 98 99} +do_execsql_test select4-16.2 { + SELECT t3.c FROM + (SELECT a,max(b) AS m FROM t1 WHERE a>=5 GROUP BY a) AS t2 + CROSS JOIN t1 AS t3 + WHERE t2.a=t3.a AND t2.m=t3.b + ORDER BY t3.a; +} {95 96 97 98 99} +do_execsql_test select4-16.3 { + SELECT t3.c FROM + (SELECT a,max(b) AS m FROM t1 WHERE a>=5 GROUP BY a) AS t2 + LEFT JOIN t1 AS t3 + WHERE t2.a=t3.a AND t2.m=t3.b + ORDER BY t3.a; +} {95 96 97 98 99} + + + + finish_test From b7b91068ee0e5bc18d8f490056dd20f79a2f4d27 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Tue, 15 Mar 2016 19:10:39 +0000 Subject: [PATCH 0152/1484] In the Win32 VFS, use SQLITE_FCNTL_LAST_ERRNO instead of (the older) SQLITE_LAST_ERRNO. FossilOrigin-Name: 9463762c437488970a87093ef13131c39b2adadc --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/os_win.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 61ece923e2..e0adb2742c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Implement\sFROM-clause\ssubqueries\sas\sco-routines\swhenever\sthey\sare\sguaranteed\nto\sbe\sthe\souter-most\sloop\sof\sthe\sjoin. -D 2016-03-15T17:52:12.224 +C In\sthe\sWin32\sVFS,\suse\sSQLITE_FCNTL_LAST_ERRNO\sinstead\sof\s(the\solder)\sSQLITE_LAST_ERRNO. +D 2016-03-15T19:10:39.513 F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66 @@ -335,7 +335,7 @@ F src/os.h 3e57a24e2794a94d3cf2342c6d9a884888cd96bf F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85 F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa F src/os_unix.c f5bac8e74aaefc4ea520e43b4540793c3b8a9e8f -F src/os_win.c f0d7aa603eb6262143d7169a222aea07c4fca91d +F src/os_win.c cbf8c442a0d818d05bcf40b093cb3ebad435b9be F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c 38718a019ca762ba4f6795425d5a54db70d1790d F src/pager.h e1d38a2f14849e219df0f91f8323504d134c8a56 @@ -1456,7 +1456,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 2fd095b14b03a508169bba710d2e8e2addf4b8f5 -R dae03fc18d1aaaa839efcf6d42490a7e -U drh -Z 042547ad8e59422492ad781582901ed5 +P c7bae50bdccb5bcf3bc22e8ac5bb6725ef13db39 +R 46123ac548d09b6e0ffa37ea5d80c14d +U mistachkin +Z d90a9a53fb7ea7a50e56b06b4f7c6bc4 diff --git a/manifest.uuid b/manifest.uuid index b2a61f89c1..14d2985670 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c7bae50bdccb5bcf3bc22e8ac5bb6725ef13db39 \ No newline at end of file +9463762c437488970a87093ef13131c39b2adadc \ No newline at end of file diff --git a/src/os_win.c b/src/os_win.c index af6b1c814c..6ff50c554b 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -3257,7 +3257,7 @@ static int winFileControl(sqlite3_file *id, int op, void *pArg){ OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); return SQLITE_OK; } - case SQLITE_LAST_ERRNO: { + case SQLITE_FCNTL_LAST_ERRNO: { *(int*)pArg = (int)pFile->lastErrno; OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); return SQLITE_OK; From 98968b22c5c6b2b4c9fb89b8d7d0199a650044a0 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 15 Mar 2016 22:00:39 +0000 Subject: [PATCH 0153/1484] Change the OP_IntegrityCk opcode to accept the list of root pages as an intarray argument in P4. Slightly smaller and faster. FossilOrigin-Name: 15e4a272df46cbad8e71b21551dc06a126d64d46 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/pragma.c | 28 ++++++++++++++++------------ src/vdbe.c | 17 +++++------------ 4 files changed, 30 insertions(+), 33 deletions(-) diff --git a/manifest b/manifest index e0adb2742c..95e98afa0f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\sthe\sWin32\sVFS,\suse\sSQLITE_FCNTL_LAST_ERRNO\sinstead\sof\s(the\solder)\sSQLITE_LAST_ERRNO. -D 2016-03-15T19:10:39.513 +C Change\sthe\sOP_IntegrityCk\sopcode\sto\saccept\sthe\slist\sof\sroot\spages\sas\san\nintarray\sargument\sin\sP4.\s\sSlightly\ssmaller\sand\sfaster. +D 2016-03-15T22:00:39.610 F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66 @@ -343,7 +343,7 @@ F src/parse.y 5ea8c81c5c41b27887f41b4a7e1c58470d7d3821 F src/pcache.c 647bb53a86b7bbcf55ad88089b3ea5a9170b90df F src/pcache.h 4d0ccaad264d360981ec5e6a2b596d6e85242545 F src/pcache1.c 72f644dc9e1468c72922eff5904048427b817051 -F src/pragma.c c7061870c235702a513ce4152fe978faf3f282eb +F src/pragma.c 04baa9343771f913f1c86b2720f768be8a3ad52a F src/pragma.h 64c78a648751b9f4f297276c4eb7507b14b4628c F src/prepare.c 22df6171aec1d86904ed2ad30c2348a5748aa04e F src/printf.c 63e6fb12bbe702dd664dc3703776c090383a5a26 @@ -416,7 +416,7 @@ F src/update.c 56b3db7edff0110360a12b76af97c39ebe3ea8b8 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 34ef7be420f82415ec48131404995ddb6ee7502f F src/vacuum.c feb1eabb20987983d9350cad98299b21fa811f52 -F src/vdbe.c 87ae3a5657fefed7875f3eb30e7ababd48013d71 +F src/vdbe.c 8cf45bb8da77d39f55d108e759d15a57acd0255c F src/vdbe.h c743791f723049db94f009e3e30958952bc2d512 F src/vdbeInt.h 49a74fe5ece206d2d8666ba9afaf1abeda5f123b F src/vdbeapi.c 95b1f8e527240a18a9aea41a655b013bf07a7009 @@ -1456,7 +1456,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P c7bae50bdccb5bcf3bc22e8ac5bb6725ef13db39 -R 46123ac548d09b6e0ffa37ea5d80c14d -U mistachkin -Z d90a9a53fb7ea7a50e56b06b4f7c6bc4 +P 9463762c437488970a87093ef13131c39b2adadc +R 6817ca21db6938155940db404d48bb61 +U drh +Z e5f48f52274ef8efc53f2f946a6d2fff diff --git a/manifest.uuid b/manifest.uuid index 14d2985670..a7f49d3bce 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9463762c437488970a87093ef13131c39b2adadc \ No newline at end of file +15e4a272df46cbad8e71b21551dc06a126d64d46 \ No newline at end of file diff --git a/src/pragma.c b/src/pragma.c index 883ab60c67..70c2950c8e 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -1439,6 +1439,7 @@ void sqlite3Pragma( for(i=0; inDb; i++){ HashElem *x; Hash *pTbls; + int *aRoot; int cnt = 0; if( OMIT_TEMPDB && i==1 ) continue; @@ -1452,31 +1453,34 @@ void sqlite3Pragma( /* Do an integrity check of the B-Tree ** - ** Begin by filling registers 2, 3, ... with the root pages numbers + ** Begin by finding the root pages numbers ** for all tables and indices in the database. */ assert( sqlite3SchemaMutexHeld(db, i, 0) ); pTbls = &db->aDb[i].pSchema->tblHash; - for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){ + for(cnt=0, x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){ Table *pTab = sqliteHashData(x); Index *pIdx; - if( HasRowid(pTab) ){ - sqlite3VdbeAddOp2(v, OP_Integer, pTab->tnum, 2+cnt); - VdbeComment((v, "%s", pTab->zName)); - cnt++; - } + if( HasRowid(pTab) ) cnt++; + for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ cnt++; } + } + aRoot = sqlite3DbMallocRawNN(db, sizeof(int)*(cnt+1)); + if( aRoot==0 ) break; + for(cnt=0, x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){ + Table *pTab = sqliteHashData(x); + Index *pIdx; + if( HasRowid(pTab) ) aRoot[cnt++] = pTab->tnum; for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ - sqlite3VdbeAddOp2(v, OP_Integer, pIdx->tnum, 2+cnt); - VdbeComment((v, "%s", pIdx->zName)); - cnt++; + aRoot[cnt++] = pIdx->tnum; } } + aRoot[cnt] = 0; /* Make sure sufficient number of registers have been allocated */ - pParse->nMem = MAX( pParse->nMem, cnt+8 ); + pParse->nMem = MAX( pParse->nMem, 14 ); /* Do the b-tree integrity checks */ - sqlite3VdbeAddOp3(v, OP_IntegrityCk, 2, cnt, 1); + sqlite3VdbeAddOp4(v, OP_IntegrityCk, 2, cnt, 1, (char*)aRoot,P4_INTARRAY); sqlite3VdbeChangeP5(v, (u8)i); addr = sqlite3VdbeAddOp1(v, OP_IsNull, 2); VdbeCoverage(v); sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, diff --git a/src/vdbe.c b/src/vdbe.c index 3351a44551..6f4ac5713d 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -5422,7 +5422,7 @@ case OP_DropTrigger: { #ifndef SQLITE_OMIT_INTEGRITY_CHECK -/* Opcode: IntegrityCk P1 P2 P3 * P5 +/* Opcode: IntegrityCk P1 P2 P3 P4 P5 ** ** Do an analysis of the currently open database. Store in ** register P1 the text of an error message describing any problems. @@ -5433,9 +5433,8 @@ case OP_DropTrigger: { ** In other words, the analysis stops as soon as reg(P1) errors are ** seen. Reg(P1) is updated with the number of errors remaining. ** -** The root page numbers of all tables in the database are integer -** stored in reg(P1), reg(P1+1), reg(P1+2), .... There are P2 tables -** total. +** The root page numbers of all tables in the database are integers +** stored in P4_INTARRAY argument. ** ** If P5 is not zero, the check is done on the auxiliary database ** file, not the main database file. @@ -5445,30 +5444,24 @@ case OP_DropTrigger: { case OP_IntegrityCk: { int nRoot; /* Number of tables to check. (Number of root pages.) */ int *aRoot; /* Array of rootpage numbers for tables to be checked */ - int j; /* Loop counter */ int nErr; /* Number of errors reported */ char *z; /* Text of the error report */ Mem *pnErr; /* Register keeping track of errors remaining */ assert( p->bIsReader ); nRoot = pOp->p2; + aRoot = pOp->p4.ai; assert( nRoot>0 ); - aRoot = sqlite3DbMallocRawNN(db, sizeof(int)*(nRoot+1) ); - if( aRoot==0 ) goto no_mem; + assert( aRoot[nRoot]==0 ); assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); pnErr = &aMem[pOp->p3]; assert( (pnErr->flags & MEM_Int)!=0 ); assert( (pnErr->flags & (MEM_Str|MEM_Blob))==0 ); pIn1 = &aMem[pOp->p1]; - for(j=0; jp5nDb ); assert( DbMaskTest(p->btreeMask, pOp->p5) ); z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p5].pBt, aRoot, nRoot, (int)pnErr->u.i, &nErr); - sqlite3DbFree(db, aRoot); pnErr->u.i -= nErr; sqlite3VdbeMemSetNull(pIn1); if( nErr==0 ){ From c5db1d4b4c8978825ee79d660e6d7cf25fdd103d Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 16 Mar 2016 00:36:19 +0000 Subject: [PATCH 0154/1484] Rearrange some internal fields in the sqlite3_stmt object to avoid a harmless TSAN warning. FossilOrigin-Name: e0b116edd64a55c971c368685aa343cb6beed0f1 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbeInt.h | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 95e98afa0f..8154a2631d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sthe\sOP_IntegrityCk\sopcode\sto\saccept\sthe\slist\sof\sroot\spages\sas\san\nintarray\sargument\sin\sP4.\s\sSlightly\ssmaller\sand\sfaster. -D 2016-03-15T22:00:39.610 +C Rearrange\ssome\sinternal\sfields\sin\sthe\ssqlite3_stmt\sobject\sto\savoid\sa\sharmless\nTSAN\swarning. +D 2016-03-16T00:36:19.731 F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66 @@ -418,7 +418,7 @@ F src/util.c 34ef7be420f82415ec48131404995ddb6ee7502f F src/vacuum.c feb1eabb20987983d9350cad98299b21fa811f52 F src/vdbe.c 8cf45bb8da77d39f55d108e759d15a57acd0255c F src/vdbe.h c743791f723049db94f009e3e30958952bc2d512 -F src/vdbeInt.h 49a74fe5ece206d2d8666ba9afaf1abeda5f123b +F src/vdbeInt.h f88d3115e9bde33b01d81f0dd26d8dd51f995991 F src/vdbeapi.c 95b1f8e527240a18a9aea41a655b013bf07a7009 F src/vdbeaux.c 2c15cf88de4df97428318c8cfac0dea873dae451 F src/vdbeblob.c 3b570b730109e8f653d9d2081649f6e7015113db @@ -1456,7 +1456,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 9463762c437488970a87093ef13131c39b2adadc -R 6817ca21db6938155940db404d48bb61 +P 15e4a272df46cbad8e71b21551dc06a126d64d46 +R 82478b12d64974258326bdaae56626ca U drh -Z e5f48f52274ef8efc53f2f946a6d2fff +Z e403476d229295941bbcf1df1a4408f9 diff --git a/manifest.uuid b/manifest.uuid index a7f49d3bce..f76cceaf73 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -15e4a272df46cbad8e71b21551dc06a126d64d46 \ No newline at end of file +e0b116edd64a55c971c368685aa343cb6beed0f1 \ No newline at end of file diff --git a/src/vdbeInt.h b/src/vdbeInt.h index b53952fd44..a78795f61c 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -381,16 +381,16 @@ struct Vdbe { #endif u16 nResColumn; /* Number of columns in one row of the result set */ u8 errorAction; /* Recovery action to do in case of an error */ + bft expired:1; /* True if the VM needs to be recompiled */ + bft doingRerun:1; /* True if rerunning after an auto-reprepare */ u8 minWriteFileFormat; /* Minimum file format for writable database files */ bft explain:2; /* True if EXPLAIN present on SQL command */ bft changeCntOn:1; /* True to update the change-counter */ - bft expired:1; /* True if the VM needs to be recompiled */ bft runOnlyOnce:1; /* Automatically expire on reset */ bft usesStmtJournal:1; /* True if uses a statement journal */ bft readOnly:1; /* True for statements that do not write */ bft bIsReader:1; /* True for statements that read */ bft isPrepareV2:1; /* True if prepared with prepare_v2() */ - bft doingRerun:1; /* True if rerunning after an auto-reprepare */ int nChange; /* Number of db changes made since last reset */ yDbMask btreeMask; /* Bitmask of db->aDb[] entries referenced */ yDbMask lockMask; /* Subset of btreeMask that requires a lock */ From 32f57d4c373c8f49b59f4a40149c136ef8a5632b Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 16 Mar 2016 01:03:10 +0000 Subject: [PATCH 0155/1484] Add the SQLITE_OMIT_CODEC_FROM_TCL compile-time option. FossilOrigin-Name: 45f7f0c80bd91a0c7ff859c27fd9e82e551bd83e --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/tclsqlite.c | 14 +++++++------- src/test1.c | 2 +- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index 8154a2631d..bf413d574c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Rearrange\ssome\sinternal\sfields\sin\sthe\ssqlite3_stmt\sobject\sto\savoid\sa\sharmless\nTSAN\swarning. -D 2016-03-16T00:36:19.731 +C Add\sthe\sSQLITE_OMIT_CODEC_FROM_TCL\scompile-time\soption. +D 2016-03-16T01:03:10.251 F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66 @@ -359,8 +359,8 @@ F src/sqliteInt.h 84c673f27b77dfbd367cb3ed1de8b6f3b73102dc F src/sqliteLimit.h 7b28cf72cbd52f178bfc97ea266445e351f2cd24 F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 -F src/tclsqlite.c 54dca4eaf3a9cb0a4b845ef54ffa99225c30a52e -F src/test1.c f14a6f9e2cff6cba4d83e2b0c52857f61886cead +F src/tclsqlite.c 4bf3bea9b03aeac176ac114700f35f76a1de4c8a +F src/test1.c 52965bd684ddcd7f22328ebd7d50fd0b6e51f0d4 F src/test2.c 5586f43fcd9a1be0830793cf9d354082c261b25b F src/test3.c a8887dabbbee3059af338f20d290084a63ed1b0f F src/test4.c d168f83cc78d02e8d35567bb5630e40dcd85ac1e @@ -1456,7 +1456,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 15e4a272df46cbad8e71b21551dc06a126d64d46 -R 82478b12d64974258326bdaae56626ca +P e0b116edd64a55c971c368685aa343cb6beed0f1 +R 1b0c52bbc749be5b9a732d29d3d099e5 U drh -Z e403476d229295941bbcf1df1a4408f9 +Z 5dddb7cbfc6ef15baab9797e73067d60 diff --git a/manifest.uuid b/manifest.uuid index f76cceaf73..3aa4fcd861 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e0b116edd64a55c971c368685aa343cb6beed0f1 \ No newline at end of file +45f7f0c80bd91a0c7ff859c27fd9e82e551bd83e \ No newline at end of file diff --git a/src/tclsqlite.c b/src/tclsqlite.c index 4e19f92644..42dd6b0f49 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -2574,7 +2574,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ ** Change the encryption key on the currently open database. */ case DB_REKEY: { -#ifdef SQLITE_HAS_CODEC +#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL) int nKey; void *pKey; #endif @@ -2582,7 +2582,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ Tcl_WrongNumArgs(interp, 2, objv, "KEY"); return TCL_ERROR; } -#ifdef SQLITE_HAS_CODEC +#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL) pKey = Tcl_GetByteArrayFromObj(objv[2], &nKey); rc = sqlite3_rekey(pDb->db, pKey, nKey); if( rc ){ @@ -2955,7 +2955,7 @@ static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ const char *zVfs = 0; int flags; Tcl_DString translatedFilename; -#ifdef SQLITE_HAS_CODEC +#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL) void *pKey = 0; int nKey = 0; #endif @@ -2984,7 +2984,7 @@ static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ return TCL_OK; } if( strcmp(zArg,"-has-codec")==0 ){ -#ifdef SQLITE_HAS_CODEC +#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL) Tcl_AppendResult(interp,"1",(char*)0); #else Tcl_AppendResult(interp,"0",(char*)0); @@ -2995,7 +2995,7 @@ static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ for(i=3; i+1db ){ sqlite3_key(p->db, pKey, nKey); } diff --git a/src/test1.c b/src/test1.c index 744b400b2a..8ad653ca6c 100644 --- a/src/test1.c +++ b/src/test1.c @@ -651,7 +651,7 @@ static int test_key( int argc, /* Number of arguments */ char **argv /* Text of each argument */ ){ -#ifdef SQLITE_HAS_CODEC +#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL) sqlite3 *db; const char *zKey; int nKey; From 892ffcc7fc5b0a6d20c20c64b56096ee8ecbd207 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 16 Mar 2016 18:26:54 +0000 Subject: [PATCH 0156/1484] Fix the query planner so that it is able to use the integer primary key from an index as part of a multi-column constraint. FossilOrigin-Name: 96ea9909429f0b3b4a67002e8340ae3f7dc0b73f --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/where.c | 3 ++- test/intpkey.test | 2 +- 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index bf413d574c..9530ffa5fc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sSQLITE_OMIT_CODEC_FROM_TCL\scompile-time\soption. -D 2016-03-16T01:03:10.251 +C Fix\sthe\squery\splanner\sso\sthat\sit\sis\sable\sto\suse\sthe\sinteger\sprimary\skey\nfrom\san\sindex\sas\spart\sof\sa\smulti-column\sconstraint. +D 2016-03-16T18:26:54.117 F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66 @@ -430,7 +430,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 10deb6b43887662691e5f53d10b3c171c401169b F src/wal.h 2f7c831cf3b071fa548bf2d5cac640846a7ff19c F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354 -F src/where.c 5533002ddf4fbc256f450cb629668a200b06a3ce +F src/where.c fe7925faafbe9a458972035c0bb4753d672f04ed F src/whereInt.h 93297d56edd137b7ea004490690fb6e2ce028a34 F src/wherecode.c 863aedf086131743763c1960637fde904eadc442 F src/whereexpr.c fb87944b1254234e5bba671aaf6dee476241506a @@ -820,7 +820,7 @@ F test/insert5.test 394f96728d1258f406fe5f5aeb0aaf29487c39a6 F test/instr.test 737bbf80685232033f3abedc6ae92f75860b5dd2 F test/intarray.test 066b7d7ac38d25bf96f87f1b017bfc687551cdd4 F test/interrupt.test dfe9a67a94b0b2d8f70545ba1a6cca10780d71cc -F test/intpkey.test 7506090fc08e028712a8bf47e5f54111947e3844 +F test/intpkey.test 70aab09756b9bd3bcb6b0358f971d7bbace46522 F test/io.test f95bca1783b01ea7761671560d023360d2dfa4cc F test/ioerr.test 2a24bd6ed5a8b062e64bfe1f6cf94fb25e92210d F test/ioerr2.test 2593563599e2cc6b6b4fcf5878b177bdd5d8df26 @@ -1456,7 +1456,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e0b116edd64a55c971c368685aa343cb6beed0f1 -R 1b0c52bbc749be5b9a732d29d3d099e5 +P 45f7f0c80bd91a0c7ff859c27fd9e82e551bd83e +R 48d902683e4b6144f631d91ce9dec30e U drh -Z 5dddb7cbfc6ef15baab9797e73067d60 +Z 4770e56ece3387d541183edf6806d70a diff --git a/manifest.uuid b/manifest.uuid index 3aa4fcd861..11ed7df765 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -45f7f0c80bd91a0c7ff859c27fd9e82e551bd83e \ No newline at end of file +96ea9909429f0b3b4a67002e8340ae3f7dc0b73f \ No newline at end of file diff --git a/src/where.c b/src/where.c index 83d72ee397..cf23aa62a4 100644 --- a/src/where.c +++ b/src/where.c @@ -289,6 +289,7 @@ static WhereTerm *whereScanInit( j = iColumn; iColumn = pIdx->aiColumn[j]; if( iColumn==XN_EXPR ) pScan->pIdxExpr = pIdx->aColExpr->a[j].pExpr; + if( iColumn==pIdx->pTable->iPKey ) iColumn = XN_ROWID; } if( pIdx && iColumn>=0 ){ pScan->idxaff = pIdx->pTable->aCol[iColumn].affinity; @@ -3929,7 +3930,7 @@ static int whereShortCut(WhereLoopBuilder *pBuilder){ int j; Table *pTab; Index *pIdx; - + pWInfo = pBuilder->pWInfo; if( pWInfo->wctrlFlags & WHERE_FORCE_TABLE ) return 0; assert( pWInfo->pTabList->nSrc>=1 ); diff --git a/test/intpkey.test b/test/intpkey.test index 41858e5d46..a149f43fb2 100644 --- a/test/intpkey.test +++ b/test/intpkey.test @@ -296,7 +296,7 @@ do_test intpkey-3.8 { count { SELECT * FROM t1 WHERE c=='world' AND a>7; } -} {11 hello world 4} +} {11 hello world 3} do_test intpkey-3.9 { count { SELECT * FROM t1 WHERE 7 Date: Wed, 16 Mar 2016 19:45:54 +0000 Subject: [PATCH 0157/1484] Enhance Lemon so that it reorders the reduce rules such that rules without actions occur at the end and so that the first rule is number 0. This reduces the size of the jump table on the reduce switch, and helps the parser to run faster. FossilOrigin-Name: d5712f21ec758ff096a7b1bb8ed4fc5ec400ca5d --- manifest | 15 ++++---- manifest.uuid | 2 +- tool/lemon.c | 97 +++++++++++++++++++++++++++++++++++++++++---------- tool/lempar.c | 11 +++--- 4 files changed, 92 insertions(+), 33 deletions(-) diff --git a/manifest b/manifest index 000b9dec54..c10487dd6a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sa\sfew\sunnecessary\sfstat()s\son\sjournal\sfiles. -D 2016-03-16T19:10:46.537 +C Enhance\sLemon\sso\sthat\sit\sreorders\sthe\sreduce\srules\ssuch\sthat\srules\swithout\nactions\soccur\sat\sthe\send\sand\sso\sthat\sthe\sfirst\srule\sis\snumber\s0.\s\sThis\nreduces\sthe\ssize\sof\sthe\sjump\stable\son\sthe\sreduce\sswitch,\sand\shelps\sthe\sparser\nto\srun\sfaster. +D 2016-03-16T19:45:54.638 F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66 @@ -1386,8 +1386,8 @@ F tool/fuzzershell.c 94019b185caceffc9f7c7b678a6489e42bc2aefa F tool/genfkey.README cf68fddd4643bbe3ff8e31b8b6d8b0a1b85e20f4 F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5 F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce -F tool/lemon.c 251f5c3f21b553240cbdd42dd187a51bb2372cd3 -F tool/lempar.c d5114c7d13aa3af1e27ff3d02e4dea6eadec7ddf +F tool/lemon.c cfbfe061a4b2766512f6b484882eee2c86a14506 +F tool/lempar.c 404ea3dc27dbeed343f0e61b1d36e97b9f5f0fb6 F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862 F tool/logest.c eef612f8adf4d0993dafed0416064cf50d5d33c6 F tool/mkautoconfamal.sh e855df211ecbcc7131dee817110ff386cfb112f7 @@ -1456,8 +1456,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 96ea9909429f0b3b4a67002e8340ae3f7dc0b73f f3c0579e931799088e9a83757e25bae229120697 -R 2179dd350d027a0023ff0b4d274ede19 -T +closed f3c0579e931799088e9a83757e25bae229120697 +P dbf84705913c0845ca4e75eb30c91536c754efeb +R 864f536bc3cc564acb40b05c95555e64 U drh -Z 6f4affaf464559d5d4fad621b1dda7eb +Z 3c44460af79cebe8997bb55087f66950 diff --git a/manifest.uuid b/manifest.uuid index 9fc448cbd8..33a88b381b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -dbf84705913c0845ca4e75eb30c91536c754efeb \ No newline at end of file +d5712f21ec758ff096a7b1bb8ed4fc5ec400ca5d \ No newline at end of file diff --git a/tool/lemon.c b/tool/lemon.c index cefdf80174..903fe97cfb 100644 --- a/tool/lemon.c +++ b/tool/lemon.c @@ -290,6 +290,7 @@ struct rule { const char *codeSuffix; /* Breakdown code after code[] above */ struct symbol *precsym; /* Precedence symbol for this rule */ int index; /* An index number for this rule */ + int iRule; /* Rule number as used in the generated tables */ Boolean canReduce; /* True if this rule is ever reduced */ struct rule *nextlhs; /* Next rule with the same LHS */ struct rule *next; /* Next rule in the global list */ @@ -372,6 +373,7 @@ struct plink { struct lemon { struct state **sorted; /* Table of states sorted by state number */ struct rule *rule; /* List of all rules */ + struct rule *startRule; /* First rule */ int nstate; /* Number of states */ int nxstate; /* nstate with tail degenerate states removed */ int nrule; /* Number of rules */ @@ -858,12 +860,12 @@ void FindStates(struct lemon *lemp) ErrorMsg(lemp->filename,0, "The specified start symbol \"%s\" is not \ in a nonterminal of the grammar. \"%s\" will be used as the start \ -symbol instead.",lemp->start,lemp->rule->lhs->name); +symbol instead.",lemp->start,lemp->startRule->lhs->name); lemp->errorcnt++; - sp = lemp->rule->lhs; + sp = lemp->startRule->lhs; } }else{ - sp = lemp->rule->lhs; + sp = lemp->startRule->lhs; } /* Make sure the start symbol doesn't occur on the right-hand side of @@ -1117,9 +1119,9 @@ void FindActions(struct lemon *lemp) /* Add the accepting token */ if( lemp->start ){ sp = Symbol_find(lemp->start); - if( sp==0 ) sp = lemp->rule->lhs; + if( sp==0 ) sp = lemp->startRule->lhs; }else{ - sp = lemp->rule->lhs; + sp = lemp->startRule->lhs; } /* Add to the first state (which is always the starting state of the ** finite state machine) an action to ACCEPT if the lookahead is the @@ -1497,6 +1499,54 @@ static void handle_T_option(char *z){ lemon_strcpy(user_templatename, z); } +/* Merge together to lists of rules order by rule.iRule */ +static struct rule *Rule_merge(struct rule *pA, struct rule *pB){ + struct rule *pFirst = 0; + struct rule **ppPrev = &pFirst; + while( pA && pB ){ + if( pA->iRuleiRule ){ + *ppPrev = pA; + ppPrev = &pA->next; + pA = pA->next; + }else{ + *ppPrev = pB; + ppPrev = &pB->next; + pB = pB->next; + } + } + if( pA ){ + *ppPrev = pA; + }else{ + *ppPrev = pB; + } + return pFirst; +} + +/* +** Sort a list of rules in order of increasing iRule value +*/ +static struct rule *Rule_sort(struct rule *rp){ + int i; + struct rule *pNext; + struct rule *x[32]; + memset(x, 0, sizeof(x)); + while( rp ){ + pNext = rp->next; + rp->next = 0; + for(i=0; iname[0]); i++); lem.nterminal = i; + /* Assign sequential rule numbers */ + for(i=0, rp=lem.rule; rp; rp=rp->next){ + rp->iRule = rp->code ? i++ : -1; + } + for(rp=lem.rule; rp; rp=rp->next){ + if( rp->iRule<0 ) rp->iRule = i++; + } + lem.startRule = lem.rule; + lem.rule = Rule_sort(lem.rule); + /* Generate a reprint of the grammar, if requested on the command line */ if( rpflag ){ Reprint(&lem); @@ -3054,13 +3115,13 @@ int PrintAction( } case REDUCE: { struct rule *rp = ap->x.rp; - fprintf(fp,"%*s reduce %-7d",indent,ap->sp->name,rp->index); + fprintf(fp,"%*s reduce %-7d",indent,ap->sp->name,rp->iRule); RulePrint(fp, rp, -1); break; } case SHIFTREDUCE: { struct rule *rp = ap->x.rp; - fprintf(fp,"%*s shift-reduce %-7d",indent,ap->sp->name,rp->index); + fprintf(fp,"%*s shift-reduce %-7d",indent,ap->sp->name,rp->iRule); RulePrint(fp, rp, -1); break; } @@ -3073,7 +3134,7 @@ int PrintAction( case SRCONFLICT: case RRCONFLICT: fprintf(fp,"%*s reduce %-7d ** Parsing conflict **", - indent,ap->sp->name,ap->x.rp->index); + indent,ap->sp->name,ap->x.rp->iRule); break; case SSCONFLICT: fprintf(fp,"%*s shift %-7d ** Parsing conflict **", @@ -3090,7 +3151,7 @@ int PrintAction( case RD_RESOLVED: if( showPrecedenceConflict ){ fprintf(fp,"%*s reduce %-7d -- dropped by precedence", - indent,ap->sp->name,ap->x.rp->index); + indent,ap->sp->name,ap->x.rp->iRule); }else{ result = 0; } @@ -3121,7 +3182,7 @@ void ReportOutput(struct lemon *lemp) while( cfp ){ char buf[20]; if( cfp->dot==cfp->rp->nrhs ){ - lemon_sprintf(buf,"(%d)",cfp->rp->index); + lemon_sprintf(buf,"(%d)",cfp->rp->iRule); fprintf(fp," %5s ",buf); }else{ fprintf(fp," "); @@ -3222,8 +3283,8 @@ PRIVATE int compute_action(struct lemon *lemp, struct action *ap) int act; switch( ap->type ){ case SHIFT: act = ap->x.stp->statenum; break; - case SHIFTREDUCE: act = ap->x.rp->index + lemp->nstate; break; - case REDUCE: act = ap->x.rp->index + lemp->nstate+lemp->nrule; break; + case SHIFTREDUCE: act = ap->x.rp->iRule + lemp->nstate; break; + case REDUCE: act = ap->x.rp->iRule + lemp->nstate+lemp->nrule; break; case ERROR: act = lemp->nstate + lemp->nrule*2; break; case ACCEPT: act = lemp->nstate + lemp->nrule*2 + 1; break; default: act = -1; break; @@ -4241,7 +4302,7 @@ void ReportTable( ** when tracing REDUCE actions. */ for(i=0, rp=lemp->rule; rp; rp=rp->next, i++){ - assert( rp->index==i ); + assert( rp->iRule==i ); fprintf(out," /* %3d */ \"", i); writeRuleText(out, rp); fprintf(out,"\",\n"); lineno++; @@ -4337,14 +4398,14 @@ void ReportTable( struct rule *rp2; /* Other rules with the same action */ if( rp->code==0 ) continue; if( rp->code[0]=='\n' && rp->code[1]==0 ) continue; /* Will be default: */ - fprintf(out," case %d: /* ", rp->index); + fprintf(out," case %d: /* ", rp->iRule); writeRuleText(out, rp); fprintf(out, " */\n"); lineno++; for(rp2=rp->next; rp2; rp2=rp2->next){ if( rp2->code==rp->code ){ - fprintf(out," case %d: /* ", rp2->index); + fprintf(out," case %d: /* ", rp2->iRule); writeRuleText(out, rp2); - fprintf(out," */ yytestcase(yyruleno==%d);\n", rp2->index); lineno++; + fprintf(out," */ yytestcase(yyruleno==%d);\n", rp2->iRule); lineno++; rp2->code = 0; } } @@ -4358,9 +4419,9 @@ void ReportTable( for(rp=lemp->rule; rp; rp=rp->next){ if( rp->code==0 ) continue; assert( rp->code[0]=='\n' && rp->code[1]==0 ); - fprintf(out," /* (%d) ", rp->index); + fprintf(out," /* (%d) ", rp->iRule); writeRuleText(out, rp); - fprintf(out, " */ yytestcase(yyruleno==%d);\n", rp->index); lineno++; + fprintf(out, " */ yytestcase(yyruleno==%d);\n", rp->iRule); lineno++; } fprintf(out," break;\n"); lineno++; tplt_xfer(lemp->name,in,out,&lineno); diff --git a/tool/lempar.c b/tool/lempar.c index db7f2dbf1b..e313904082 100644 --- a/tool/lempar.c +++ b/tool/lempar.c @@ -418,7 +418,7 @@ int ParseStackPeak(void *p){ ** Find the appropriate action for a parser given the terminal ** look-ahead token iLookAhead. */ -static int yy_find_shift_action( +static unsigned int yy_find_shift_action( yyParser *pParser, /* The parser */ YYCODETYPE iLookAhead /* The look-ahead token */ ){ @@ -606,7 +606,7 @@ static void yy_accept(yyParser*); /* Forward Declaration */ */ static void yy_reduce( yyParser *yypParser, /* The parser */ - int yyruleno /* Number of the rule by which to reduce */ + unsigned int yyruleno /* Number of the rule by which to reduce */ ){ int yygoto; /* The next state */ int yyact; /* The next action */ @@ -615,8 +615,7 @@ static void yy_reduce( ParseARG_FETCH; yymsp = &yypParser->yystack[yypParser->yyidx]; #ifndef NDEBUG - if( yyTraceFILE && yyruleno>=0 - && yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ){ + if( yyTraceFILE && yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ){ yysize = yyRuleInfo[yyruleno].nrhs; fprintf(yyTraceFILE, "%sReduce [%s], go to state %d.\n", yyTracePrompt, yyRuleName[yyruleno], yymsp[-yysize].stateno); @@ -661,7 +660,7 @@ static void yy_reduce( %% /********** End reduce actions ************************************************/ }; - assert( yyruleno>=0 && yyruleno Date: Wed, 16 Mar 2016 19:48:10 +0000 Subject: [PATCH 0158/1484] Have fts5 cache the decoded structure of fts5 indexes in memory. Use "PRAGMA data_version" to detect stale caches. FossilOrigin-Name: 33ef2210ef19e55c8d460bfe9d3dc146034c8acc --- ext/fts5/fts5Int.h | 2 + ext/fts5/fts5_index.c | 115 +++++++++++++++++++++++++++----- ext/fts5/fts5_main.c | 39 +++++++---- ext/fts5/fts5_storage.c | 4 ++ ext/fts5/test/fts5corrupt3.test | 4 ++ ext/fts5/test/fts5dlidx.test | 4 +- manifest | 27 ++++---- manifest.uuid | 2 +- 8 files changed, 153 insertions(+), 44 deletions(-) diff --git a/ext/fts5/fts5Int.h b/ext/fts5/fts5Int.h index 35f15abbaf..961206f2b3 100644 --- a/ext/fts5/fts5Int.h +++ b/ext/fts5/fts5Int.h @@ -480,6 +480,7 @@ int sqlite3Fts5IndexReads(Fts5Index *p); int sqlite3Fts5IndexReinit(Fts5Index *p); int sqlite3Fts5IndexOptimize(Fts5Index *p); int sqlite3Fts5IndexMerge(Fts5Index *p, int nMerge); +int sqlite3Fts5IndexReset(Fts5Index *p); int sqlite3Fts5IndexLoadConfig(Fts5Index *p); @@ -622,6 +623,7 @@ int sqlite3Fts5StorageDeleteAll(Fts5Storage *p); int sqlite3Fts5StorageRebuild(Fts5Storage *p); int sqlite3Fts5StorageOptimize(Fts5Storage *p); int sqlite3Fts5StorageMerge(Fts5Storage *p, int nMerge); +int sqlite3Fts5StorageReset(Fts5Storage *p); /* ** End of interface to code in fts5_storage.c. diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index 323e6cefdc..78003396d6 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -304,6 +304,10 @@ struct Fts5Index { sqlite3_stmt *pIdxDeleter; /* "DELETE FROM %_idx WHERE segid=? */ sqlite3_stmt *pIdxSelect; int nRead; /* Total number of blocks read */ + + sqlite3_stmt *pDataVersion; + i64 iStructVersion; /* data_version when pStruct read */ + Fts5Structure *pStruct; /* Current db structure (or NULL) */ }; struct Fts5DoclistIter { @@ -959,6 +963,48 @@ static void fts5StructureExtendLevel( } } +static Fts5Structure *fts5StructureReadUncached(Fts5Index *p){ + Fts5Structure *pRet = 0; + Fts5Config *pConfig = p->pConfig; + int iCookie; /* Configuration cookie */ + Fts5Data *pData; + + pData = fts5DataRead(p, FTS5_STRUCTURE_ROWID); + if( p->rc==SQLITE_OK ){ + /* TODO: Do we need this if the leaf-index is appended? Probably... */ + memset(&pData->p[pData->nn], 0, FTS5_DATA_PADDING); + p->rc = fts5StructureDecode(pData->p, pData->nn, &iCookie, &pRet); + if( p->rc==SQLITE_OK && pConfig->iCookie!=iCookie ){ + p->rc = sqlite3Fts5ConfigLoad(pConfig, iCookie); + } + fts5DataRelease(pData); + if( p->rc!=SQLITE_OK ){ + fts5StructureRelease(pRet); + pRet = 0; + } + } + + return pRet; +} + +static i64 fts5IndexDataVersion(Fts5Index *p){ + i64 iVersion = 0; + + if( p->pDataVersion==0 ){ + p->rc = fts5IndexPrepareStmt(p, &p->pDataVersion, + sqlite3_mprintf("PRAGMA %Q.data_version", p->pConfig->zDb) + ); + if( p->rc ) return 0; + } + + if( SQLITE_ROW==sqlite3_step(p->pDataVersion) ){ + iVersion = sqlite3_column_int64(p->pDataVersion, 0); + } + p->rc = sqlite3_reset(p->pDataVersion); + + return iVersion; +} + /* ** Read, deserialize and return the structure record. ** @@ -971,28 +1017,51 @@ static void fts5StructureExtendLevel( ** is called, it is a no-op. */ static Fts5Structure *fts5StructureRead(Fts5Index *p){ - Fts5Config *pConfig = p->pConfig; - Fts5Structure *pRet = 0; /* Object to return */ - int iCookie; /* Configuration cookie */ - Fts5Data *pData; + Fts5Structure *pRet; /* Object to return */ - pData = fts5DataRead(p, FTS5_STRUCTURE_ROWID); - if( p->rc ) return 0; - /* TODO: Do we need this if the leaf-index is appended? Probably... */ - memset(&pData->p[pData->nn], 0, FTS5_DATA_PADDING); - p->rc = fts5StructureDecode(pData->p, pData->nn, &iCookie, &pRet); - if( p->rc==SQLITE_OK && pConfig->iCookie!=iCookie ){ - p->rc = sqlite3Fts5ConfigLoad(pConfig, iCookie); + if( p->pStruct ){ + pRet = p->pStruct; +#ifdef SQLITE_DEBUG + { + Fts5Structure *pTest = fts5StructureReadUncached(p); + if( pTest ){ + int i, j; + assert_nc( pRet->nSegment==pTest->nSegment ); + assert_nc( pRet->nLevel==pTest->nLevel ); + for(i=0; inLevel; i++){ + assert_nc( pRet->aLevel[i].nMerge==pTest->aLevel[i].nMerge ); + assert_nc( pRet->aLevel[i].nSeg==pTest->aLevel[i].nSeg ); + for(j=0; jaLevel[i].nSeg; j++){ + Fts5StructureSegment *p1 = &pTest->aLevel[i].aSeg[j]; + Fts5StructureSegment *p2 = &pRet->aLevel[i].aSeg[j]; + assert_nc( p1->iSegid==p2->iSegid ); + assert_nc( p1->pgnoFirst==p2->pgnoFirst ); + assert_nc( p1->pgnoLast==p2->pgnoLast ); + } + } + fts5StructureRelease(pTest); + } + } +#endif + }else{ + pRet = fts5StructureReadUncached(p); } - fts5DataRelease(pData); - if( p->rc!=SQLITE_OK ){ - fts5StructureRelease(pRet); - pRet = 0; + if( pRet ){ + fts5StructureRef(pRet); + p->pStruct = pRet; + p->iStructVersion = fts5IndexDataVersion(p); } return pRet; } +static void fts5StructureInvalidate(Fts5Index *p){ + if( p->pStruct ){ + fts5StructureRelease(p->pStruct); + p->pStruct = 0; + } +} + /* ** Return the total number of segments in index structure pStruct. This ** function is only ever used as part of assert() conditions. @@ -4328,6 +4397,7 @@ static void fts5FlushOneHash(Fts5Index *p){ ** for the new level-0 segment. */ pStruct = fts5StructureRead(p); iSegid = fts5AllocateSegid(p, pStruct); + fts5StructureInvalidate(p); if( iSegid ){ const int pgsz = p->pConfig->pgsz; @@ -4547,6 +4617,7 @@ int sqlite3Fts5IndexOptimize(Fts5Index *p){ assert( p->rc==SQLITE_OK ); fts5IndexFlush(p); pStruct = fts5StructureRead(p); + fts5StructureInvalidate(p); if( pStruct ){ pNew = fts5IndexOptimizeStruct(p, pStruct); @@ -4577,6 +4648,7 @@ int sqlite3Fts5IndexMerge(Fts5Index *p, int nMerge){ Fts5Structure *pStruct = fts5StructureRead(p); if( pStruct ){ int nMin = p->pConfig->nUsermerge; + fts5StructureInvalidate(p); if( nMerge<0 ){ Fts5Structure *pNew = fts5IndexOptimizeStruct(p, pStruct); fts5StructureRelease(pStruct); @@ -5004,6 +5076,7 @@ int sqlite3Fts5IndexSync(Fts5Index *p, int bCommit){ int sqlite3Fts5IndexRollback(Fts5Index *p){ fts5CloseReader(p); fts5IndexDiscardData(p); + fts5StructureInvalidate(p); /* assert( p->rc==SQLITE_OK ); */ return SQLITE_OK; } @@ -5015,6 +5088,7 @@ int sqlite3Fts5IndexRollback(Fts5Index *p){ */ int sqlite3Fts5IndexReinit(Fts5Index *p){ Fts5Structure s; + fts5StructureInvalidate(p); memset(&s, 0, sizeof(Fts5Structure)); fts5DataWrite(p, FTS5_AVERAGES_ROWID, (const u8*)"", 0); fts5StructureWrite(p, &s); @@ -5073,11 +5147,13 @@ int sqlite3Fts5IndexClose(Fts5Index *p){ int rc = SQLITE_OK; if( p ){ assert( p->pReader==0 ); + fts5StructureInvalidate(p); sqlite3_finalize(p->pWriter); sqlite3_finalize(p->pDeleter); sqlite3_finalize(p->pIdxWriter); sqlite3_finalize(p->pIdxDeleter); sqlite3_finalize(p->pIdxSelect); + sqlite3_finalize(p->pDataVersion); sqlite3Fts5HashFree(p->pHash); sqlite3_free(p->zDataTbl); sqlite3_free(p); @@ -6333,3 +6409,12 @@ int sqlite3Fts5IndexInit(sqlite3 *db){ } return rc; } + + +int sqlite3Fts5IndexReset(Fts5Index *p){ + assert( p->pStruct==0 || p->iStructVersion!=0 ); + if( fts5IndexDataVersion(p)!=p->iStructVersion ){ + fts5StructureInvalidate(p); + } + return fts5IndexReturn(p); +} diff --git a/ext/fts5/fts5_main.c b/ext/fts5/fts5_main.c index dcd131c74a..4feb3e1a2f 100644 --- a/ext/fts5/fts5_main.c +++ b/ext/fts5/fts5_main.c @@ -597,27 +597,38 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){ return SQLITE_OK; } +static int fts5NewTransaction(Fts5Table *pTab){ + Fts5Cursor *pCsr; + for(pCsr=pTab->pGlobal->pCsr; pCsr; pCsr=pCsr->pNext){ + if( pCsr->base.pVtab==(sqlite3_vtab*)pTab ) return SQLITE_OK; + } + return sqlite3Fts5StorageReset(pTab->pStorage); +} + /* ** Implementation of xOpen method. */ static int fts5OpenMethod(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCsr){ Fts5Table *pTab = (Fts5Table*)pVTab; Fts5Config *pConfig = pTab->pConfig; - Fts5Cursor *pCsr; /* New cursor object */ + Fts5Cursor *pCsr = 0; /* New cursor object */ int nByte; /* Bytes of space to allocate */ - int rc = SQLITE_OK; /* Return code */ + int rc; /* Return code */ - nByte = sizeof(Fts5Cursor) + pConfig->nCol * sizeof(int); - pCsr = (Fts5Cursor*)sqlite3_malloc(nByte); - if( pCsr ){ - Fts5Global *pGlobal = pTab->pGlobal; - memset(pCsr, 0, nByte); - pCsr->aColumnSize = (int*)&pCsr[1]; - pCsr->pNext = pGlobal->pCsr; - pGlobal->pCsr = pCsr; - pCsr->iCsrId = ++pGlobal->iNextId; - }else{ - rc = SQLITE_NOMEM; + rc = fts5NewTransaction(pTab); + if( rc==SQLITE_OK ){ + nByte = sizeof(Fts5Cursor) + pConfig->nCol * sizeof(int); + pCsr = (Fts5Cursor*)sqlite3_malloc(nByte); + if( pCsr ){ + Fts5Global *pGlobal = pTab->pGlobal; + memset(pCsr, 0, nByte); + pCsr->aColumnSize = (int*)&pCsr[1]; + pCsr->pNext = pGlobal->pCsr; + pGlobal->pCsr = pCsr; + pCsr->iCsrId = ++pGlobal->iNextId; + }else{ + rc = SQLITE_NOMEM; + } } *ppCsr = (sqlite3_vtab_cursor*)pCsr; return rc; @@ -1578,8 +1589,8 @@ static int fts5SyncMethod(sqlite3_vtab *pVtab){ ** Implementation of xBegin() method. */ static int fts5BeginMethod(sqlite3_vtab *pVtab){ - UNUSED_PARAM(pVtab); /* Call below is a no-op for NDEBUG builds */ fts5CheckTransactionState((Fts5Table*)pVtab, FTS5_BEGIN, 0); + fts5NewTransaction((Fts5Table*)pVtab); return SQLITE_OK; } diff --git a/ext/fts5/fts5_storage.c b/ext/fts5/fts5_storage.c index e4f5dd8f51..bd1c1f88e9 100644 --- a/ext/fts5/fts5_storage.c +++ b/ext/fts5/fts5_storage.c @@ -639,6 +639,10 @@ int sqlite3Fts5StorageMerge(Fts5Storage *p, int nMerge){ return sqlite3Fts5IndexMerge(p->pIndex, nMerge); } +int sqlite3Fts5StorageReset(Fts5Storage *p){ + return sqlite3Fts5IndexReset(p->pIndex); +} + /* ** Allocate a new rowid. This is used for "external content" tables when ** a NULL value is inserted into the rowid column. The new rowid is allocated diff --git a/ext/fts5/test/fts5corrupt3.test b/ext/fts5/test/fts5corrupt3.test index 7a8cb5c465..9653bcaac2 100644 --- a/ext/fts5/test/fts5corrupt3.test +++ b/ext/fts5/test/fts5corrupt3.test @@ -179,6 +179,10 @@ for {set i 1} {1} {incr i} { if {$end<=$i} break lset var end [expr $end - $i] set struct [binary format c* $var] + + db close + sqlite3 db test.db + db eval { BEGIN; UPDATE t1_data SET block = $struct WHERE id=10; diff --git a/ext/fts5/test/fts5dlidx.test b/ext/fts5/test/fts5dlidx.test index 232b5021f1..655beb984b 100644 --- a/ext/fts5/test/fts5dlidx.test +++ b/ext/fts5/test/fts5dlidx.test @@ -178,7 +178,7 @@ do_execsql_test 3.2 { ORDER BY rowid DESC; } {16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1} -do_execsql_test 3.2 { +do_execsql_test 3.3 { INSERT INTO abc(abc) VALUES('integrity-check'); INSERT INTO abc(abc) VALUES('optimize'); INSERT INTO abc(abc) VALUES('integrity-check'); @@ -187,7 +187,7 @@ do_execsql_test 3.2 { set v [lindex $vocab 0] set i 0 foreach v $vocab { - do_execsql_test 3.3.[incr i] { + do_execsql_test 3.4.[incr i] { SELECT rowid FROM abc WHERE abc MATCH $v } {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16} } diff --git a/manifest b/manifest index bf413d574c..7c682009be 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sSQLITE_OMIT_CODEC_FROM_TCL\scompile-time\soption. -D 2016-03-16T01:03:10.251 +C Have\sfts5\scache\sthe\sdecoded\sstructure\sof\sfts5\sindexes\sin\smemory.\sUse\s"PRAGMA\sdata_version"\sto\sdetect\sstale\scaches. +D 2016-03-16T19:48:10.873 F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66 @@ -98,15 +98,15 @@ F ext/fts3/unicode/mkunicode.tcl 2debed3f582d77b3fdd0b8830880250021571fd8 F ext/fts3/unicode/parseunicode.tcl da577d1384810fb4e2b209bf3313074353193e95 F ext/fts5/extract_api_docs.tcl a36e54ec777172ddd3f9a88daf593b00848368e0 F ext/fts5/fts5.h ff9c2782e8ed890b0de2f697a8d63971939e70c7 -F ext/fts5/fts5Int.h 4060504b7979601d99e1385c2b5713036854979a +F ext/fts5/fts5Int.h 4e507abebae0d7d3ac9b8daebf049d5153d00961 F ext/fts5/fts5_aux.c daa57fb45216491814520bbb587e97bf81ced458 F ext/fts5/fts5_buffer.c 4c1502d4c956cd092c89ce4480867f9d8bf325cd F ext/fts5/fts5_config.c 5af9c360e99669d29f06492c370892394aba0857 F ext/fts5/fts5_expr.c be309fb227003c931107bfcc12d5be4f2fd2bb8c F ext/fts5/fts5_hash.c f3a7217c86eb8f272871be5f6aa1b6798960a337 -F ext/fts5/fts5_index.c d4f0c12e4f04bbc3a06b6da052039f2ce3e45438 -F ext/fts5/fts5_main.c b8501e1a6a11591c53b18ce7aea7e5386cfb0421 -F ext/fts5/fts5_storage.c f8343db90d8c95a4d4b52f6676e354b4649ffd6e +F ext/fts5/fts5_index.c 317040cb17cdad05e973376b39239b29c75f90b5 +F ext/fts5/fts5_main.c b4a0fc5bf17f2f1f056ee76cdd7d2af08b360f55 +F ext/fts5/fts5_storage.c a3361410422e69639ca2bcd5a56a0933dadf84d2 F ext/fts5/fts5_tcl.c f8731e0508299bd43f1a2eff7dbeaac870768966 F ext/fts5/fts5_test_mi.c 783b86697ebf773c18fc109992426c0173a055bc F ext/fts5/fts5_test_tok.c db08af63673c3a7d39f053b36fd6e065017706be @@ -141,9 +141,9 @@ F ext/fts5/test/fts5conflict.test 26f4e46c4d31e16221794832a990dc4e30e18de5 F ext/fts5/test/fts5content.test 9a952c95518a14182dc3b59e3c8fa71cda82a4e1 F ext/fts5/test/fts5corrupt.test c2ad090192708150d50d961278df10ae7a4b8b62 F ext/fts5/test/fts5corrupt2.test 26c0a39dd9ff73207e6229f83b50b21d37c7658c -F ext/fts5/test/fts5corrupt3.test b9558d5b0ca44a8b6247fbb5d4a47592a8976892 +F ext/fts5/test/fts5corrupt3.test f77f65e386231daf62902466b40ff998b2c8ce4f F ext/fts5/test/fts5detail.test ef5c690535a797413acaf5ad9b8ab5d49972df69 -F ext/fts5/test/fts5dlidx.test 13871a14641017ae42f6f1055a8067bafd44cb3d +F ext/fts5/test/fts5dlidx.test 007e9390c94638760797dbec2990c97c3fa08dfe F ext/fts5/test/fts5doclist.test 8edb5b57e5f144030ed74ec00ef6fa4294fed79b F ext/fts5/test/fts5ea.test b01e3a18cdfabbff8104a96a5242a06a68a998a0 F ext/fts5/test/fts5eb.test c516ae0c934be6fd29ec95ea8b5f11f461311535 @@ -1456,7 +1456,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e0b116edd64a55c971c368685aa343cb6beed0f1 -R 1b0c52bbc749be5b9a732d29d3d099e5 -U drh -Z 5dddb7cbfc6ef15baab9797e73067d60 +P 45f7f0c80bd91a0c7ff859c27fd9e82e551bd83e +R 7875ababc9def91b1b2c4626dd7ef0ad +T *branch * fts5-data-version +T *sym-fts5-data-version * +T -sym-trunk * +U dan +Z 015dc4987d82758ea8c0d324359dc366 diff --git a/manifest.uuid b/manifest.uuid index 3aa4fcd861..3d6ceeb2ed 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -45f7f0c80bd91a0c7ff859c27fd9e82e551bd83e \ No newline at end of file +33ef2210ef19e55c8d460bfe9d3dc146034c8acc \ No newline at end of file From 377ba3842935e1629ea7cc5379716e084a25e54f Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 16 Mar 2016 19:53:58 +0000 Subject: [PATCH 0159/1484] Add a cast to an implict (size_t -> int) conversion in fts5_expr.c. FossilOrigin-Name: d9b5ff7aba3a8f6ca4505eac308fa9d510254c3e --- ext/fts5/fts5_expr.c | 2 +- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/ext/fts5/fts5_expr.c b/ext/fts5/fts5_expr.c index 1e9be8117d..0bc61414b0 100644 --- a/ext/fts5/fts5_expr.c +++ b/ext/fts5/fts5_expr.c @@ -2500,7 +2500,7 @@ static int fts5ExprPopulatePoslistsCb( Fts5ExprTerm *pTerm; if( p->aPopulator[i].bOk==0 ) continue; for(pTerm=&pExpr->apExprPhrase[i]->aTerm[0]; pTerm; pTerm=pTerm->pSynonym){ - int nTerm = strlen(pTerm->zTerm); + int nTerm = (int)strlen(pTerm->zTerm); if( (nTerm==nToken || (nTermbPrefix)) && memcmp(pTerm->zTerm, pToken, nTerm)==0 ){ diff --git a/manifest b/manifest index c10487dd6a..7a984cba21 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\sLemon\sso\sthat\sit\sreorders\sthe\sreduce\srules\ssuch\sthat\srules\swithout\nactions\soccur\sat\sthe\send\sand\sso\sthat\sthe\sfirst\srule\sis\snumber\s0.\s\sThis\nreduces\sthe\ssize\sof\sthe\sjump\stable\son\sthe\sreduce\sswitch,\sand\shelps\sthe\sparser\nto\srun\sfaster. -D 2016-03-16T19:45:54.638 +C Add\sa\scast\sto\san\simplict\s(size_t\s->\sint)\sconversion\sin\sfts5_expr.c. +D 2016-03-16T19:53:58.157 F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66 @@ -102,7 +102,7 @@ F ext/fts5/fts5Int.h 4060504b7979601d99e1385c2b5713036854979a F ext/fts5/fts5_aux.c daa57fb45216491814520bbb587e97bf81ced458 F ext/fts5/fts5_buffer.c 4c1502d4c956cd092c89ce4480867f9d8bf325cd F ext/fts5/fts5_config.c 5af9c360e99669d29f06492c370892394aba0857 -F ext/fts5/fts5_expr.c be309fb227003c931107bfcc12d5be4f2fd2bb8c +F ext/fts5/fts5_expr.c 35e9d92c89e7c7ea0759b73d24da1ecb7630a24b F ext/fts5/fts5_hash.c f3a7217c86eb8f272871be5f6aa1b6798960a337 F ext/fts5/fts5_index.c d4f0c12e4f04bbc3a06b6da052039f2ce3e45438 F ext/fts5/fts5_main.c b8501e1a6a11591c53b18ce7aea7e5386cfb0421 @@ -1456,7 +1456,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P dbf84705913c0845ca4e75eb30c91536c754efeb -R 864f536bc3cc564acb40b05c95555e64 -U drh -Z 3c44460af79cebe8997bb55087f66950 +P d5712f21ec758ff096a7b1bb8ed4fc5ec400ca5d +R 9f805acde28759cca26c223b9435e99d +U dan +Z 15773d15bd52be46557d40c4ca5e6748 diff --git a/manifest.uuid b/manifest.uuid index 33a88b381b..4f9852189d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d5712f21ec758ff096a7b1bb8ed4fc5ec400ca5d \ No newline at end of file +d9b5ff7aba3a8f6ca4505eac308fa9d510254c3e \ No newline at end of file From e459bd4986e8221464357233d0419b60c6e5daae Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 16 Mar 2016 20:05:57 +0000 Subject: [PATCH 0160/1484] Fix a comment on the freelist_count and data_version pragmas. FossilOrigin-Name: 10a3e2a01db9f80452a2a3369fd25b6fd9798274 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/pragma.c | 4 +++- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 7a984cba21..71037fc133 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sa\scast\sto\san\simplict\s(size_t\s->\sint)\sconversion\sin\sfts5_expr.c. -D 2016-03-16T19:53:58.157 +C Fix\sa\scomment\son\sthe\sfreelist_count\sand\sdata_version\spragmas. +D 2016-03-16T20:05:57.514 F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66 @@ -343,7 +343,7 @@ F src/parse.y 5ea8c81c5c41b27887f41b4a7e1c58470d7d3821 F src/pcache.c 647bb53a86b7bbcf55ad88089b3ea5a9170b90df F src/pcache.h 4d0ccaad264d360981ec5e6a2b596d6e85242545 F src/pcache1.c 72f644dc9e1468c72922eff5904048427b817051 -F src/pragma.c 04baa9343771f913f1c86b2720f768be8a3ad52a +F src/pragma.c fb8e3e73431a39dc47727ef74aad94a86cfb1d36 F src/pragma.h 64c78a648751b9f4f297276c4eb7507b14b4628c F src/prepare.c 22df6171aec1d86904ed2ad30c2348a5748aa04e F src/printf.c 63e6fb12bbe702dd664dc3703776c090383a5a26 @@ -1456,7 +1456,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d5712f21ec758ff096a7b1bb8ed4fc5ec400ca5d -R 9f805acde28759cca26c223b9435e99d -U dan -Z 15773d15bd52be46557d40c4ca5e6748 +P d9b5ff7aba3a8f6ca4505eac308fa9d510254c3e +R fafe07c0411ab81f336ee3834565f5dd +U drh +Z 9641eb94b1becd7c7420d553fe575786 diff --git a/manifest.uuid b/manifest.uuid index 4f9852189d..a6b92c6b67 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d9b5ff7aba3a8f6ca4505eac308fa9d510254c3e \ No newline at end of file +10a3e2a01db9f80452a2a3369fd25b6fd9798274 \ No newline at end of file diff --git a/src/pragma.c b/src/pragma.c index 70c2950c8e..4c4bc71ad1 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -1706,7 +1706,9 @@ void sqlite3Pragma( ** PRAGMA [schema.]user_version ** PRAGMA [schema.]user_version = ** - ** PRAGMA [schema.]freelist_count = + ** PRAGMA [schema.]freelist_count + ** + ** PRAGMA [schema.]data_version ** ** PRAGMA [schema.]application_id ** PRAGMA [schema.]application_id = From f71a366407a52fc479582de4194ec0da3081bb23 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 16 Mar 2016 20:44:45 +0000 Subject: [PATCH 0161/1484] Some pragmas can be reused without an automatic reprepare. FossilOrigin-Name: db1ce7e13e656fcd2766f1b1f225cbfefe8f73ad --- manifest | 19 +++++++++++-------- manifest.uuid | 2 +- src/pragma.c | 2 ++ src/vdbe.h | 1 + src/vdbeaux.c | 7 +++++++ 5 files changed, 22 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 71037fc133..2fb10eeede 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\scomment\son\sthe\sfreelist_count\sand\sdata_version\spragmas. -D 2016-03-16T20:05:57.514 +C Some\spragmas\scan\sbe\sreused\swithout\san\sautomatic\sreprepare. +D 2016-03-16T20:44:45.683 F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66 @@ -343,7 +343,7 @@ F src/parse.y 5ea8c81c5c41b27887f41b4a7e1c58470d7d3821 F src/pcache.c 647bb53a86b7bbcf55ad88089b3ea5a9170b90df F src/pcache.h 4d0ccaad264d360981ec5e6a2b596d6e85242545 F src/pcache1.c 72f644dc9e1468c72922eff5904048427b817051 -F src/pragma.c fb8e3e73431a39dc47727ef74aad94a86cfb1d36 +F src/pragma.c f0670909e915179fec47e17f72f14660995b8022 F src/pragma.h 64c78a648751b9f4f297276c4eb7507b14b4628c F src/prepare.c 22df6171aec1d86904ed2ad30c2348a5748aa04e F src/printf.c 63e6fb12bbe702dd664dc3703776c090383a5a26 @@ -417,10 +417,10 @@ F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 34ef7be420f82415ec48131404995ddb6ee7502f F src/vacuum.c feb1eabb20987983d9350cad98299b21fa811f52 F src/vdbe.c 8cf45bb8da77d39f55d108e759d15a57acd0255c -F src/vdbe.h c743791f723049db94f009e3e30958952bc2d512 +F src/vdbe.h 6f44193e7be52fd5f7c308175a936555b1e6b101 F src/vdbeInt.h f88d3115e9bde33b01d81f0dd26d8dd51f995991 F src/vdbeapi.c 95b1f8e527240a18a9aea41a655b013bf07a7009 -F src/vdbeaux.c 2c15cf88de4df97428318c8cfac0dea873dae451 +F src/vdbeaux.c a930f913d40e4ca6f6caaef6a7b5906a369fa2b1 F src/vdbeblob.c 3b570b730109e8f653d9d2081649f6e7015113db F src/vdbemem.c 9b0cb32cc267ef026515f15a3594d5ff91fe4dfc F src/vdbesort.c 307460bfa4de4d1c3901fcd42089159131e34062 @@ -1456,7 +1456,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d9b5ff7aba3a8f6ca4505eac308fa9d510254c3e -R fafe07c0411ab81f336ee3834565f5dd +P 10a3e2a01db9f80452a2a3369fd25b6fd9798274 +R 2716c51dfa2bfe8ed5e18127e51ae3c8 +T *branch * reusable-pragma +T *sym-reusable-pragma * +T -sym-trunk * U drh -Z 9641eb94b1becd7c7420d553fe575786 +Z 7789d1f13489cbc314e26c9b80a11a2d diff --git a/manifest.uuid b/manifest.uuid index a6b92c6b67..7ffbbd6257 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -10a3e2a01db9f80452a2a3369fd25b6fd9798274 \ No newline at end of file +db1ce7e13e656fcd2766f1b1f225cbfefe8f73ad \ No newline at end of file diff --git a/src/pragma.c b/src/pragma.c index 4c4bc71ad1..54858afbf1 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -1764,6 +1764,7 @@ void sqlite3Pragma( aOp[1].p3 = iCookie; sqlite3VdbeSetNumCols(v, 1); sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLeft, SQLITE_TRANSIENT); + sqlite3VdbeReusable(v); } } break; @@ -1785,6 +1786,7 @@ void sqlite3Pragma( sqlite3VdbeLoadString(v, 1, zOpt); sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1); } + sqlite3VdbeReusable(v); } break; #endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */ diff --git a/src/vdbe.h b/src/vdbe.h index 4c02f5844d..ace28ffdb3 100644 --- a/src/vdbe.h +++ b/src/vdbe.h @@ -202,6 +202,7 @@ void sqlite3VdbeUsesBtree(Vdbe*, int); VdbeOp *sqlite3VdbeGetOp(Vdbe*, int); int sqlite3VdbeMakeLabel(Vdbe*); void sqlite3VdbeRunOnlyOnce(Vdbe*); +void sqlite3VdbeReusable(Vdbe*); void sqlite3VdbeDelete(Vdbe*); void sqlite3VdbeClearObject(sqlite3*,Vdbe*); void sqlite3VdbeMakeReady(Vdbe*,Parse*); diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 9c75d1e078..c71605cdd2 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -391,6 +391,13 @@ void sqlite3VdbeRunOnlyOnce(Vdbe *p){ p->runOnlyOnce = 1; } +/* +** Mark the VDBE as one that can only be run multiple times. +*/ +void sqlite3VdbeReusable(Vdbe *p){ + p->runOnlyOnce = 0; +} + #ifdef SQLITE_DEBUG /* sqlite3AssertMayAbort() logic */ /* From c9460ab989d1a01aac7535811df01094ce0c8e9b Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 17 Mar 2016 12:39:56 +0000 Subject: [PATCH 0162/1484] Fix some OOM-handling issues in the fts5 changes on this branch. FossilOrigin-Name: 020a0bda59fe93b9361ceeed0d5a8ba4177380c8 --- ext/fts5/fts5_index.c | 83 ++++++++++++++++++++++--------------------- manifest | 12 +++---- manifest.uuid | 2 +- 3 files changed, 50 insertions(+), 47 deletions(-) diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index 78003396d6..3fb1458526 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -990,17 +990,19 @@ static Fts5Structure *fts5StructureReadUncached(Fts5Index *p){ static i64 fts5IndexDataVersion(Fts5Index *p){ i64 iVersion = 0; - if( p->pDataVersion==0 ){ - p->rc = fts5IndexPrepareStmt(p, &p->pDataVersion, - sqlite3_mprintf("PRAGMA %Q.data_version", p->pConfig->zDb) - ); - if( p->rc ) return 0; - } + if( p->rc==SQLITE_OK ){ + if( p->pDataVersion==0 ){ + p->rc = fts5IndexPrepareStmt(p, &p->pDataVersion, + sqlite3_mprintf("PRAGMA %Q.data_version", p->pConfig->zDb) + ); + if( p->rc ) return 0; + } - if( SQLITE_ROW==sqlite3_step(p->pDataVersion) ){ - iVersion = sqlite3_column_int64(p->pDataVersion, 0); + if( SQLITE_ROW==sqlite3_step(p->pDataVersion) ){ + iVersion = sqlite3_column_int64(p->pDataVersion, 0); + } + p->rc = sqlite3_reset(p->pDataVersion); } - p->rc = sqlite3_reset(p->pDataVersion); return iVersion; } @@ -1019,39 +1021,40 @@ static i64 fts5IndexDataVersion(Fts5Index *p){ static Fts5Structure *fts5StructureRead(Fts5Index *p){ Fts5Structure *pRet; /* Object to return */ - if( p->pStruct ){ - pRet = p->pStruct; -#ifdef SQLITE_DEBUG - { - Fts5Structure *pTest = fts5StructureReadUncached(p); - if( pTest ){ - int i, j; - assert_nc( pRet->nSegment==pTest->nSegment ); - assert_nc( pRet->nLevel==pTest->nLevel ); - for(i=0; inLevel; i++){ - assert_nc( pRet->aLevel[i].nMerge==pTest->aLevel[i].nMerge ); - assert_nc( pRet->aLevel[i].nSeg==pTest->aLevel[i].nSeg ); - for(j=0; jaLevel[i].nSeg; j++){ - Fts5StructureSegment *p1 = &pTest->aLevel[i].aSeg[j]; - Fts5StructureSegment *p2 = &pRet->aLevel[i].aSeg[j]; - assert_nc( p1->iSegid==p2->iSegid ); - assert_nc( p1->pgnoFirst==p2->pgnoFirst ); - assert_nc( p1->pgnoLast==p2->pgnoLast ); - } - } - fts5StructureRelease(pTest); - } - } -#endif - }else{ - pRet = fts5StructureReadUncached(p); - } - - if( pRet ){ - fts5StructureRef(pRet); - p->pStruct = pRet; + if( p->pStruct==0 ){ p->iStructVersion = fts5IndexDataVersion(p); + if( p->rc==SQLITE_OK ){ + p->pStruct = pRet = fts5StructureReadUncached(p); + } + if( p->rc!=SQLITE_OK ) return 0; + assert( p->iStructVersion!=0 ); + assert( p->pStruct!=0 ); } +#ifdef SQLITE_DEBUG + else{ + Fts5Structure *pTest = fts5StructureReadUncached(p); + if( pTest ){ + int i, j; + assert_nc( p->pStruct->nSegment==pTest->nSegment ); + assert_nc( p->pStruct->nLevel==pTest->nLevel ); + for(i=0; inLevel; i++){ + assert_nc( p->pStruct->aLevel[i].nMerge==pTest->aLevel[i].nMerge ); + assert_nc( p->pStruct->aLevel[i].nSeg==pTest->aLevel[i].nSeg ); + for(j=0; jaLevel[i].nSeg; j++){ + Fts5StructureSegment *p1 = &pTest->aLevel[i].aSeg[j]; + Fts5StructureSegment *p2 = &p->pStruct->aLevel[i].aSeg[j]; + assert_nc( p1->iSegid==p2->iSegid ); + assert_nc( p1->pgnoFirst==p2->pgnoFirst ); + assert_nc( p1->pgnoLast==p2->pgnoLast ); + } + } + fts5StructureRelease(pTest); + } + } +#endif + + pRet = p->pStruct; + fts5StructureRef(pRet); return pRet; } diff --git a/manifest b/manifest index 4ea9b53d9e..8f5bdc1491 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sthe\schanges\son\sthe\sreusable-pragma\sbranch\sinto\sthis\sone. -D 2016-03-16T20:53:33.830 +C Fix\ssome\sOOM-handling\sissues\sin\sthe\sfts5\schanges\son\sthis\sbranch. +D 2016-03-17T12:39:56.371 F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66 @@ -104,7 +104,7 @@ F ext/fts5/fts5_buffer.c 4c1502d4c956cd092c89ce4480867f9d8bf325cd F ext/fts5/fts5_config.c 5af9c360e99669d29f06492c370892394aba0857 F ext/fts5/fts5_expr.c 35e9d92c89e7c7ea0759b73d24da1ecb7630a24b F ext/fts5/fts5_hash.c f3a7217c86eb8f272871be5f6aa1b6798960a337 -F ext/fts5/fts5_index.c 317040cb17cdad05e973376b39239b29c75f90b5 +F ext/fts5/fts5_index.c afac2ffe3198776626b99366e18af1f32ea9eb85 F ext/fts5/fts5_main.c b4a0fc5bf17f2f1f056ee76cdd7d2af08b360f55 F ext/fts5/fts5_storage.c a3361410422e69639ca2bcd5a56a0933dadf84d2 F ext/fts5/fts5_tcl.c f8731e0508299bd43f1a2eff7dbeaac870768966 @@ -1456,7 +1456,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 33ef2210ef19e55c8d460bfe9d3dc146034c8acc db1ce7e13e656fcd2766f1b1f225cbfefe8f73ad -R 9bcd2375f3bee3eec21a0e0d6e512aed +P 6c4a17b963916d19c9433d7a251338042f32e9fa +R bc1955b591517ca84e5bb3a7a87f0726 U dan -Z 9f0b8bb8494a2ee2e21e8a8509116058 +Z 380059b0b3811052efb55863df364c4f diff --git a/manifest.uuid b/manifest.uuid index 71f9d7efce..d6022948ee 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6c4a17b963916d19c9433d7a251338042f32e9fa \ No newline at end of file +020a0bda59fe93b9361ceeed0d5a8ba4177380c8 \ No newline at end of file From 1b9f2141a7c9e048eb5408a84559151ba8aabd3a Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 17 Mar 2016 16:01:23 +0000 Subject: [PATCH 0163/1484] Experimental implementation of the sqlite3_system_errno() interface. FossilOrigin-Name: 6782c87b3722fbd09684a5b1e5df05247956f1c6 --- manifest | 32 +++++++++++++++++--------------- manifest.uuid | 2 +- src/loadext.c | 4 +++- src/main.c | 4 ++++ src/os.c | 3 +++ src/os.h | 1 + src/os_unix.c | 15 +++++---------- src/sqlite.h.in | 12 ++++++++++++ src/sqlite3ext.h | 4 ++++ src/sqliteInt.h | 2 ++ src/util.c | 12 ++++++++++++ 11 files changed, 64 insertions(+), 27 deletions(-) diff --git a/manifest b/manifest index 3d02d28e9b..ebc861b735 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C The\sprepared\sstatements\sfor\ssome\spragmas\scan\snow\sbe\sreused\swithout\sinvoking\nan\sautomatic\sreprepare. -D 2016-03-16T21:29:54.761 +C Experimental\simplementation\sof\sthe\ssqlite3_system_errno()\sinterface. +D 2016-03-17T16:01:23.259 F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66 @@ -314,8 +314,8 @@ F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 F src/insert.c 723d5d708cdb61bdd47c00b9f07c75be45aefc09 F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e -F src/loadext.c 9e2a41adcaff16ebc1ebff1f336cbf33de55396f -F src/main.c 29ea8ebb23ceb5159da167e18d5c807fbb1545c4 +F src/loadext.c e70f8f9e97624a232870ea5486e682c813ac3002 +F src/main.c 74591e0405e5e71b276105ac5f8d419dd54e6495 F src/malloc.c 1443d1ad95d67c21d77af7ae3f44678252f0efec F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b @@ -330,11 +330,11 @@ F src/mutex_noop.c 9d4309c075ba9cc7249e19412d3d62f7f94839c4 F src/mutex_unix.c 27bb6cc49485ee46711a6580ab7b3f1402211d23 F src/mutex_w32.c 5e6fe1c298fb5a8a15aaed4161d5759311431c17 F src/notify.c 9711a7575036f0d3040ba61bc6e217f13a9888e7 -F src/os.c f89e3ca1c2e3d5015b847aec60371c474acbac82 -F src/os.h 3e57a24e2794a94d3cf2342c6d9a884888cd96bf +F src/os.c ca10edb445ad2c5fdc7285b49d72bcdf261fa23e +F src/os.h 91ff889115ecd01f436d3611f7f5ea4dc12d92f1 F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85 F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa -F src/os_unix.c 4bde11921a2bebcf2167efc8540ddabc814189dc +F src/os_unix.c 50103f69121bca969761b821e2b0e393b55fe869 F src/os_win.c cbf8c442a0d818d05bcf40b093cb3ebad435b9be F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c 38718a019ca762ba4f6795425d5a54db70d1790d @@ -352,10 +352,10 @@ F src/resolve.c b8f7174e5f8c33c44ded3a25a973d0bb89228c20 F src/rowset.c 9fe4b3ad7cc00944386bb600233d8f523de07a6e F src/select.c 6dd2097bb158efe3b8d68683dcc3b4a49e907a34 F src/shell.c 5e0ab1e708dc294330ccd8230536e1801f60822e -F src/sqlite.h.in 0235586b3fb639e85998d495c90f007657fd82af +F src/sqlite.h.in e877f141b15ef68ef28f84714e69d7234f9a071e F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 -F src/sqlite3ext.h dfbe62ffd95b99afe2140d8c35b180d11924072d -F src/sqliteInt.h 84c673f27b77dfbd367cb3ed1de8b6f3b73102dc +F src/sqlite3ext.h 98f72cbfe00169c39089115427d06ea05fe4b4a2 +F src/sqliteInt.h 5256653cc049ad48e03189abe106cb45f5eaf2c8 F src/sqliteLimit.h 7b28cf72cbd52f178bfc97ea266445e351f2cd24 F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 @@ -414,7 +414,7 @@ F src/treeview.c e4b41a37530a191579d3c53142cc44ee2eb99373 F src/trigger.c e14840ee0c3e549e758ec9bf3e4146e166002280 F src/update.c 56b3db7edff0110360a12b76af97c39ebe3ea8b8 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c -F src/util.c 34ef7be420f82415ec48131404995ddb6ee7502f +F src/util.c c3fc5193e6f039fa61afbcc0db87d5a5d563a18a F src/vacuum.c feb1eabb20987983d9350cad98299b21fa811f52 F src/vdbe.c 8cf45bb8da77d39f55d108e759d15a57acd0255c F src/vdbe.h 6f44193e7be52fd5f7c308175a936555b1e6b101 @@ -1456,8 +1456,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 10a3e2a01db9f80452a2a3369fd25b6fd9798274 db1ce7e13e656fcd2766f1b1f225cbfefe8f73ad -R 2716c51dfa2bfe8ed5e18127e51ae3c8 -T +closed db1ce7e13e656fcd2766f1b1f225cbfefe8f73ad +P 97b0e88cc7c3d677217d0bfab4cb4a34a4abb238 +R 2fd7ee41c15d4ef6398866450bc883db +T *branch * sqlite_system_errno +T *sym-sqlite_system_errno * +T -sym-trunk * U drh -Z e3b23194e47816995dbce6c752704ef0 +Z 77c764a9e283f7fe52499f77098482f4 diff --git a/manifest.uuid b/manifest.uuid index 06db10b8a2..f695385706 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -97b0e88cc7c3d677217d0bfab4cb4a34a4abb238 \ No newline at end of file +6782c87b3722fbd09684a5b1e5df05247956f1c6 \ No newline at end of file diff --git a/src/loadext.c b/src/loadext.c index 3469fbb73d..495001e55a 100644 --- a/src/loadext.c +++ b/src/loadext.c @@ -414,7 +414,9 @@ static const sqlite3_api_routines sqlite3Apis = { /* Version 3.10.0 and later */ sqlite3_status64, sqlite3_strlike, - sqlite3_db_cacheflush + sqlite3_db_cacheflush, + /* Version 3.12.0 and later */ + sqlite3_system_errno }; /* diff --git a/src/main.c b/src/main.c index 70e46a4ee1..e4d5cb494c 100644 --- a/src/main.c +++ b/src/main.c @@ -2240,6 +2240,9 @@ int sqlite3_extended_errcode(sqlite3 *db){ } return db->errCode; } +int sqlite3_system_errno(sqlite3 *db){ + return db ? db->iSysErrno : 0; +} /* ** Return a string that describes the kind of error specified in the @@ -2865,6 +2868,7 @@ static int openDatabase( if( rc==SQLITE_IOERR_NOMEM ){ rc = SQLITE_NOMEM_BKPT; } + sqlite3SystemError(db, rc); sqlite3Error(db, rc); goto opendb_out; } diff --git a/src/os.c b/src/os.c index eed7828538..bfcc9cdd05 100644 --- a/src/os.c +++ b/src/os.c @@ -262,6 +262,9 @@ int sqlite3OsRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){ int sqlite3OsSleep(sqlite3_vfs *pVfs, int nMicro){ return pVfs->xSleep(pVfs, nMicro); } +int sqlite3OsGetLastError(sqlite3_vfs *pVfs){ + return pVfs->xGetLastError ? pVfs->xGetLastError(pVfs, 0, 0) : 0; +} int sqlite3OsCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *pTimeOut){ int rc; /* IMPLEMENTATION-OF: R-49045-42493 SQLite will use the xCurrentTimeInt64() diff --git a/src/os.h b/src/os.h index 2c1b86f913..f813541561 100644 --- a/src/os.h +++ b/src/os.h @@ -197,6 +197,7 @@ void sqlite3OsDlClose(sqlite3_vfs *, void *); #endif /* SQLITE_OMIT_LOAD_EXTENSION */ int sqlite3OsRandomness(sqlite3_vfs *, int, char *); int sqlite3OsSleep(sqlite3_vfs *, int); +int sqlite3OsGetLastError(sqlite3_vfs*); int sqlite3OsCurrentTimeInt64(sqlite3_vfs *, sqlite3_int64*); /* diff --git a/src/os_unix.c b/src/os_unix.c index eb1a63c687..d593b952f5 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -6264,23 +6264,18 @@ static int unixCurrentTime(sqlite3_vfs *NotUsed, double *prNow){ # define unixCurrentTime 0 #endif -#ifndef SQLITE_OMIT_DEPRECATED /* -** We added the xGetLastError() method with the intention of providing -** better low-level error messages when operating-system problems come up -** during SQLite operation. But so far, none of that has been implemented -** in the core. So this routine is never called. For now, it is merely -** a place-holder. +** The xGetLastError() method is designed to return a better +** low-level error message when operating-system problems come up +** during SQLite operation. Only the integer return code is currently +** used. */ static int unixGetLastError(sqlite3_vfs *NotUsed, int NotUsed2, char *NotUsed3){ UNUSED_PARAMETER(NotUsed); UNUSED_PARAMETER(NotUsed2); UNUSED_PARAMETER(NotUsed3); - return 0; + return errno; } -#else -# define unixGetLastError 0 -#endif /* diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 3b267974b5..04f4359ecf 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -7915,6 +7915,18 @@ void sqlite3_stmt_scanstatus_reset(sqlite3_stmt*); */ int sqlite3_db_cacheflush(sqlite3*); +/* +** CAPI3REF: Low-level system error code +** +** ^Attempt to return the underlying operating system error code or error +** number that caused the most reason I/O error or failure to open a file. +** The return value is OS-dependent. For example, on unix systems, after +** [sqlite3_open_v2()] returns [SQLITE_CANTOPEN], this interface could be +** called to get back the underlying "errno" that caused the problem, such +** as ENOSPC, EAUTH, EISDIR, and so forth. +*/ +int sqlite3_system_errno(sqlite3*); + /* ** CAPI3REF: Database Snapshot ** KEYWORDS: {snapshot} diff --git a/src/sqlite3ext.h b/src/sqlite3ext.h index 2e1c764a52..20a2fcdf02 100644 --- a/src/sqlite3ext.h +++ b/src/sqlite3ext.h @@ -279,6 +279,8 @@ struct sqlite3_api_routines { int (*status64)(int,sqlite3_int64*,sqlite3_int64*,int); int (*strlike)(const char*,const char*,unsigned int); int (*db_cacheflush)(sqlite3*); + /* Version 3.12.0 and later */ + int (*system_errno)(sqlite3*); }; /* @@ -522,6 +524,8 @@ struct sqlite3_api_routines { #define sqlite3_status64 sqlite3_api->status64 #define sqlite3_strlike sqlite3_api->strlike #define sqlite3_db_cacheflush sqlite3_api->db_cacheflush +/* Version 3.12.0 and later */ +#define sqlite3_system_errno sqlite3_api->system_errno #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) diff --git a/src/sqliteInt.h b/src/sqliteInt.h index f2f485778a..99917b1666 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1220,6 +1220,7 @@ struct sqlite3 { unsigned int openFlags; /* Flags passed to sqlite3_vfs.xOpen() */ int errCode; /* Most recent error code (SQLITE_*) */ int errMask; /* & result codes with this before returning */ + int iSysErrno; /* Errno value from last system error */ u16 dbOptFlags; /* Flags to enable/disable optimizations */ u8 enc; /* Text encoding */ u8 autoCommit; /* The auto-commit flag. */ @@ -3763,6 +3764,7 @@ int sqlite3Atoi64(const char*, i64*, int, u8); int sqlite3DecOrHexToI64(const char*, i64*); void sqlite3ErrorWithMsg(sqlite3*, int, const char*,...); void sqlite3Error(sqlite3*,int); +void sqlite3SystemError(sqlite3*,int); void *sqlite3HexToBlob(sqlite3*, const char *z, int n); u8 sqlite3HexToInt(int h); int sqlite3TwoPartName(Parse *, Token *, Token *, Token **); diff --git a/src/util.c b/src/util.c index d6a6f6b954..0a705a6a6e 100644 --- a/src/util.c +++ b/src/util.c @@ -126,6 +126,18 @@ void sqlite3Error(sqlite3 *db, int err_code){ if( db->pErr ) sqlite3ValueSetNull(db->pErr); } +/* +** Load the sqlite3.iSysErrno field if that is an appropriate thing +** to do based on the SQLite error code in rc. +*/ +void sqlite3SystemError(sqlite3 *db, int rc){ + if( rc==SQLITE_IOERR_NOMEM ) return; + rc &= 0xff; + if( rc==SQLITE_CANTOPEN || rc==SQLITE_IOERR ){ + db->iSysErrno = sqlite3OsGetLastError(db->pVfs); + } +} + /* ** Set the most recent error code and error string for the sqlite ** handle "db". The error code is set to "err_code". From 0e80e50984e2a6128efb64c4998380d5f0595700 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 17 Mar 2016 17:23:11 +0000 Subject: [PATCH 0164/1484] Simple test cases for sqlite3_system_errno() FossilOrigin-Name: 185bc8644c806597194dc532a4d547a03a2dedaa --- manifest | 17 +++++++---------- manifest.uuid | 2 +- src/test1.c | 24 ++++++++++++++++++++++++ test/capi3.test | 9 +++++---- 4 files changed, 37 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index ebc861b735..6cc0c36998 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Experimental\simplementation\sof\sthe\ssqlite3_system_errno()\sinterface. -D 2016-03-17T16:01:23.259 +C Simple\stest\scases\sfor\ssqlite3_system_errno() +D 2016-03-17T17:23:11.511 F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66 @@ -360,7 +360,7 @@ F src/sqliteLimit.h 7b28cf72cbd52f178bfc97ea266445e351f2cd24 F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 F src/tclsqlite.c 4bf3bea9b03aeac176ac114700f35f76a1de4c8a -F src/test1.c 52965bd684ddcd7f22328ebd7d50fd0b6e51f0d4 +F src/test1.c 289e7dab5b1aec4f4d44f2cc84972c97458d739f F src/test2.c 5586f43fcd9a1be0830793cf9d354082c261b25b F src/test3.c a8887dabbbee3059af338f20d290084a63ed1b0f F src/test4.c d168f83cc78d02e8d35567bb5630e40dcd85ac1e @@ -520,7 +520,7 @@ F test/busy.test 76b4887f8b9160ba903c1ac22e8ff406ad6ae2f0 F test/cache.test 13bc046b26210471ca6f2889aceb1ea52dc717de F test/cacheflush.test af25bb1509df04c1da10e38d8f322d66eceedf61 F test/capi2.test 011c16da245fdc0106a2785035de6b242c05e738 -F test/capi3.test bf6f0308bbbba1e770dac13aa08e5c2ac61c7324 +F test/capi3.test 84ab8993016cd7edfe91af58a04def17075ec9b9 F test/capi3b.test efb2b9cfd127efa84433cd7a2d72ce0454ae0dc4 F test/capi3c.test 06f6261f9e9b4ef6f76afcd9900f3665408af1c8 F test/capi3d.test 485048dc5cd07bc68011e4917ad035ad6047ab82 @@ -1456,10 +1456,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 97b0e88cc7c3d677217d0bfab4cb4a34a4abb238 -R 2fd7ee41c15d4ef6398866450bc883db -T *branch * sqlite_system_errno -T *sym-sqlite_system_errno * -T -sym-trunk * +P 6782c87b3722fbd09684a5b1e5df05247956f1c6 +R b7a0980686d8da4da394952a90c389a3 U drh -Z 77c764a9e283f7fe52499f77098482f4 +Z 861529470b9b3fd5330fda28dd73536f diff --git a/manifest.uuid b/manifest.uuid index f695385706..5df27f10bb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6782c87b3722fbd09684a5b1e5df05247956f1c6 \ No newline at end of file +185bc8644c806597194dc532a4d547a03a2dedaa \ No newline at end of file diff --git a/src/test1.c b/src/test1.c index 8ad653ca6c..cb41a70c2d 100644 --- a/src/test1.c +++ b/src/test1.c @@ -4847,6 +4847,29 @@ static int test_db_cacheflush( return TCL_OK; } +/* +** Usage: sqlite3_system_errno DB +** +** Return the low-level system errno value. +*/ +static int test_system_errno( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + sqlite3 *db; + int iErrno; + if( objc!=2 ){ + Tcl_WrongNumArgs(interp, 1, objv, "DB"); + return TCL_ERROR; + } + if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; + iErrno = sqlite3_system_errno(db); + Tcl_SetObjResult(interp, Tcl_NewIntObj(iErrno)); + return TCL_OK; +} + /* ** Usage: sqlite3_db_filename DB DBNAME ** @@ -7084,6 +7107,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){ { "sqlite3_release_memory", test_release_memory, 0}, { "sqlite3_db_release_memory", test_db_release_memory, 0}, { "sqlite3_db_cacheflush", test_db_cacheflush, 0}, + { "sqlite3_system_errno", test_system_errno, 0}, { "sqlite3_db_filename", test_db_filename, 0}, { "sqlite3_db_readonly", test_db_readonly, 0}, { "sqlite3_soft_heap_limit", test_soft_heap_limit, 0}, diff --git a/test/capi3.test b/test/capi3.test index 163bb19ada..e91c044632 100644 --- a/test/capi3.test +++ b/test/capi3.test @@ -172,14 +172,15 @@ do_test capi3-3.3 { catch { set db2 [sqlite3_open /bogus/path/test.db {}] } - sqlite3_extended_errcode $db2 -} {SQLITE_CANTOPEN} + set ::capi3_errno [sqlite3_system_errno $db2] + list [sqlite3_extended_errcode $db2] [expr {$::capi3_errno!=0}] +} {SQLITE_CANTOPEN 1} do_test capi3-3.4 { sqlite3_errmsg $db2 } {unable to open database file} do_test capi3-3.5 { - sqlite3_close $db2 -} {SQLITE_OK} + list [sqlite3_system_errno $db2] [sqlite3_close $db2] +} [list $::capi3_errno SQLITE_OK] if {[clang_sanitize_address]==0} { do_test capi3-3.6.1-misuse { sqlite3_close $db2 From de845c2f5aab918ad86d7b0313ddc3e0085129fb Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 17 Mar 2016 19:07:52 +0000 Subject: [PATCH 0165/1484] A more compact implementation of the code generator for the IS and IS NOT operators. FossilOrigin-Name: 8607e3ac7a9d44372a4a66da21bbb3d28ae2528a --- manifest | 13 +++++------ manifest.uuid | 2 +- src/expr.c | 63 +++++++++++++++++++++++---------------------------- 3 files changed, 35 insertions(+), 43 deletions(-) diff --git a/manifest b/manifest index 3d02d28e9b..68ccf6c76c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C The\sprepared\sstatements\sfor\ssome\spragmas\scan\snow\sbe\sreused\swithout\sinvoking\nan\sautomatic\sreprepare. -D 2016-03-16T21:29:54.761 +C A\smore\scompact\simplementation\sof\sthe\scode\sgenerator\sfor\sthe\nIS\sand\sIS\sNOT\soperators. +D 2016-03-17T19:07:52.217 F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66 @@ -304,7 +304,7 @@ F src/ctime.c 60e135af364d777a9ab41c97e5e89cd224da6198 F src/date.c 0b73e681c11fca867fec554750c07fe0d4e417c1 F src/dbstat.c c845548d4346e606e2f2b7d2e714ace2b8a7dd1b F src/delete.c 48802aa3ee6339f576d074336d3ae1b5f40e240f -F src/expr.c c329d581e5d631153456369684d7d4bcd94c907d +F src/expr.c f8137b7d3d3f2a991f9622e41d170e0adf0abc71 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 5cb42d9a59e2a590776fd3fc8ff6f61d40df3c6e F src/func.c 552d300265aed09eea21f68ac742a440550c0062 @@ -1456,8 +1456,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 10a3e2a01db9f80452a2a3369fd25b6fd9798274 db1ce7e13e656fcd2766f1b1f225cbfefe8f73ad -R 2716c51dfa2bfe8ed5e18127e51ae3c8 -T +closed db1ce7e13e656fcd2766f1b1f225cbfefe8f73ad +P 97b0e88cc7c3d677217d0bfab4cb4a34a4abb238 +R 7d24921d4d6b93efccc35ce02f43234b U drh -Z e3b23194e47816995dbce6c752704ef0 +Z d01f371f2a1444a2eb95b11e7cec5f5e diff --git a/manifest.uuid b/manifest.uuid index 06db10b8a2..ad8858c776 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -97b0e88cc7c3d677217d0bfab4cb4a34a4abb238 \ No newline at end of file +8607e3ac7a9d44372a4a66da21bbb3d28ae2528a \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 3672d02df1..352edc5424 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1283,7 +1283,8 @@ u32 sqlite3ExprListFlags(const ExprList *pList){ if( pList ){ for(i=0; inExpr; i++){ Expr *pExpr = pList->a[i].pExpr; - if( ALWAYS(pExpr) ) m |= pExpr->flags; + assert( pExpr!=0 ); + m |= pExpr->flags; } } return m; @@ -3548,6 +3549,13 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull); break; } + case TK_IS: + case TK_ISNOT: + testcase( op==TK_IS ); + testcase( op==TK_ISNOT ); + op = (op==TK_IS) ? TK_EQ : TK_NE; + jumpIfNull = SQLITE_NULLEQ; + /* Fall thru */ case TK_LT: case TK_LE: case TK_GT: @@ -3563,23 +3571,12 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ assert(TK_LE==OP_Le); testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le); assert(TK_GT==OP_Gt); testcase(op==OP_Gt); VdbeCoverageIf(v,op==OP_Gt); assert(TK_GE==OP_Ge); testcase(op==OP_Ge); VdbeCoverageIf(v,op==OP_Ge); - assert(TK_EQ==OP_Eq); testcase(op==OP_Eq); VdbeCoverageIf(v,op==OP_Eq); - assert(TK_NE==OP_Ne); testcase(op==OP_Ne); VdbeCoverageIf(v,op==OP_Ne); - testcase( regFree1==0 ); - testcase( regFree2==0 ); - break; - } - case TK_IS: - case TK_ISNOT: { - testcase( op==TK_IS ); - testcase( op==TK_ISNOT ); - r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); - r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); - op = (op==TK_IS) ? TK_EQ : TK_NE; - codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, - r1, r2, dest, SQLITE_NULLEQ); - VdbeCoverageIf(v, op==TK_EQ); - VdbeCoverageIf(v, op==TK_NE); + assert(TK_EQ==OP_Eq); testcase(op==OP_Eq); + VdbeCoverageIf(v, op==OP_Eq && jumpIfNull==SQLITE_NULLEQ); + VdbeCoverageIf(v, op==OP_Eq && jumpIfNull!=SQLITE_NULLEQ); + assert(TK_NE==OP_Ne); testcase(op==OP_Ne); + VdbeCoverageIf(v, op==OP_Ne && jumpIfNull==SQLITE_NULLEQ); + VdbeCoverageIf(v, op==OP_Ne && jumpIfNull!=SQLITE_NULLEQ); testcase( regFree1==0 ); testcase( regFree2==0 ); break; @@ -3704,6 +3701,13 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull); break; } + case TK_IS: + case TK_ISNOT: + testcase( pExpr->op==TK_IS ); + testcase( pExpr->op==TK_ISNOT ); + op = (pExpr->op==TK_IS) ? TK_NE : TK_EQ; + jumpIfNull = SQLITE_NULLEQ; + /* Fall thru */ case TK_LT: case TK_LE: case TK_GT: @@ -3719,23 +3723,12 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ assert(TK_LE==OP_Le); testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le); assert(TK_GT==OP_Gt); testcase(op==OP_Gt); VdbeCoverageIf(v,op==OP_Gt); assert(TK_GE==OP_Ge); testcase(op==OP_Ge); VdbeCoverageIf(v,op==OP_Ge); - assert(TK_EQ==OP_Eq); testcase(op==OP_Eq); VdbeCoverageIf(v,op==OP_Eq); - assert(TK_NE==OP_Ne); testcase(op==OP_Ne); VdbeCoverageIf(v,op==OP_Ne); - testcase( regFree1==0 ); - testcase( regFree2==0 ); - break; - } - case TK_IS: - case TK_ISNOT: { - testcase( pExpr->op==TK_IS ); - testcase( pExpr->op==TK_ISNOT ); - r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); - r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); - op = (pExpr->op==TK_IS) ? TK_NE : TK_EQ; - codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, - r1, r2, dest, SQLITE_NULLEQ); - VdbeCoverageIf(v, op==TK_EQ); - VdbeCoverageIf(v, op==TK_NE); + assert(TK_EQ==OP_Eq); testcase(op==OP_Eq); + VdbeCoverageIf(v, op==OP_Eq && jumpIfNull!=SQLITE_NULLEQ); + VdbeCoverageIf(v, op==OP_Eq && jumpIfNull==SQLITE_NULLEQ); + assert(TK_NE==OP_Ne); testcase(op==OP_Ne); + VdbeCoverageIf(v, op==OP_Ne && jumpIfNull!=SQLITE_NULLEQ); + VdbeCoverageIf(v, op==OP_Ne && jumpIfNull==SQLITE_NULLEQ); testcase( regFree1==0 ); testcase( regFree2==0 ); break; From 762e32bcfae029d0f40bf888338415d559148211 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 17 Mar 2016 19:28:19 +0000 Subject: [PATCH 0166/1484] Change the xGetLastError() method on the windows VFS so that it continues to format an error message (if requested) but returns the system error code, rather than an SQLite status code. FossilOrigin-Name: 1602f6b53698bd3a1a4be218c2e3145dd895f1f1 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/os_win.c | 4 +++- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 6cc0c36998..c0896b3d7e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Simple\stest\scases\sfor\ssqlite3_system_errno() -D 2016-03-17T17:23:11.511 +C Change\sthe\sxGetLastError()\smethod\son\sthe\swindows\sVFS\sso\sthat\sit\scontinues\sto\nformat\san\serror\smessage\s(if\srequested)\sbut\sreturns\sthe\ssystem\serror\scode,\nrather\sthan\san\sSQLite\sstatus\scode. +D 2016-03-17T19:28:19.609 F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66 @@ -335,7 +335,7 @@ F src/os.h 91ff889115ecd01f436d3611f7f5ea4dc12d92f1 F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85 F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa F src/os_unix.c 50103f69121bca969761b821e2b0e393b55fe869 -F src/os_win.c cbf8c442a0d818d05bcf40b093cb3ebad435b9be +F src/os_win.c 551d973ada67127430e41d9e514e53f6beb6c5a7 F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c 38718a019ca762ba4f6795425d5a54db70d1790d F src/pager.h e1d38a2f14849e219df0f91f8323504d134c8a56 @@ -1456,7 +1456,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 6782c87b3722fbd09684a5b1e5df05247956f1c6 -R b7a0980686d8da4da394952a90c389a3 +P 185bc8644c806597194dc532a4d547a03a2dedaa +R d7bafa1f512c1236fc42737f63cfb05e U drh -Z 861529470b9b3fd5330fda28dd73536f +Z df3bbf22437c6fe25ac3bbf281848b7c diff --git a/manifest.uuid b/manifest.uuid index 5df27f10bb..688543bf04 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -185bc8644c806597194dc532a4d547a03a2dedaa \ No newline at end of file +1602f6b53698bd3a1a4be218c2e3145dd895f1f1 \ No newline at end of file diff --git a/src/os_win.c b/src/os_win.c index 6ff50c554b..fd95c00e3a 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -5584,8 +5584,10 @@ static int winCurrentTime(sqlite3_vfs *pVfs, double *prNow){ ** sqlite3_errmsg(), possibly making IO errors easier to debug. */ static int winGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ + DWORD e = osGetLastError(); UNUSED_PARAMETER(pVfs); - return winGetLastErrorMsg(osGetLastError(), nBuf, zBuf); + if( nBuf>0 ) winGetLastErrorMsg(e, nBuf, zBuf); + return e; } /* From e42195b0440c03403d6f928c9cf7865a49c9a4b4 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 17 Mar 2016 21:06:42 +0000 Subject: [PATCH 0167/1484] Add an API to indicate the percentage progress of an rbu update. FossilOrigin-Name: ffc58d2c2576a5b6e1c2c7112612c5760e711afd --- ext/rbu/rbuprogress.test | 179 +++++++++++++++++++++++++++++++++++++++ ext/rbu/sqlite3rbu.c | 179 ++++++++++++++++++++++++++++++++++++--- ext/rbu/sqlite3rbu.h | 2 + ext/rbu/test_rbu.c | 13 +++ manifest | 23 ++--- manifest.uuid | 2 +- 6 files changed, 377 insertions(+), 21 deletions(-) create mode 100644 ext/rbu/rbuprogress.test diff --git a/ext/rbu/rbuprogress.test b/ext/rbu/rbuprogress.test new file mode 100644 index 0000000000..9fcd014065 --- /dev/null +++ b/ext/rbu/rbuprogress.test @@ -0,0 +1,179 @@ +# 2016 March 18 +# +# 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. +# +#*********************************************************************** +# + +source [file join [file dirname [info script]] rbu_common.tcl] +set ::testprefix rbuprogress + + +# Create a simple RBU database. That expects to write to a table: +# +# CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c); +# +proc create_rbu1 {filename} { + forcedelete $filename + sqlite3 rbu1 $filename + rbu1 eval { + CREATE TABLE data_t1(a, b, c, rbu_control); + INSERT INTO data_t1 VALUES(1, 2, 3, 0); + INSERT INTO data_t1 VALUES(2, 'two', 'three', 0); + INSERT INTO data_t1 VALUES(3, NULL, 8.2, 0); + + CREATE TABLE rbu_count(tbl, cnt); + INSERT INTO rbu_count VALUES('data_t1', 3); + } + rbu1 close + return $filename +} + + +do_execsql_test 1.0 { + CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c); +} + +do_test 1.1 { + create_rbu1 rbu.db + sqlite3rbu rbu test.db rbu.db + rbu stage_progress +} {0 0} +do_test 1.2 { rbu step ; rbu stage_progress } {3333 0} +do_test 1.3 { rbu step ; rbu stage_progress } {6666 0} +do_test 1.4 { rbu step ; rbu stage_progress } {10000 0} +do_test 1.5 { rbu step ; rbu stage_progress } {10000 0} +do_test 1.6 { rbu step ; rbu stage_progress } {10000 0} +do_test 1.7 { rbu step ; rbu stage_progress } {10000 5000} +do_test 1.8 { rbu step ; rbu stage_progress } {10000 10000} +do_test 1.9 { rbu step ; rbu stage_progress } {10000 10000} + +do_test 1.10 { + rbu close +} {SQLITE_DONE} + +#------------------------------------------------------------------------- + +proc do_sp_test {tn target rbu reslist} { + uplevel [list do_test $tn [subst -nocommands { + sqlite3rbu rbu $target $rbu + set res [list] + while 1 { + set rc [rbu step] + if {[set rc] != "SQLITE_OK"} { error "error 1" } + lappend res [lindex [rbu stage_progress] 0] + if {[lindex [set res] end]==10000} break + } + if {[set res] != [list $reslist]} { + error "reslist is incorrect (expect=$reslist got=[set res])" + } + + # One step to clean up the temporary tables used to update the only + # target table in the rbu database. And one more to move the *-oal + # file to *-wal. + rbu step + rbu step + + # Do the checkpoint. + while {[rbu step]=="SQLITE_OK"} { } + + rbu close + }] {SQLITE_DONE}] +} + +proc create_db_file {filename sql} { + forcedelete $filename + sqlite3 tmpdb $filename + tmpdb eval $sql + tmpdb close +} + +reset_db +do_test 2.1.0 { + execsql { + CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c); + } + create_db_file rbu.db { + CREATE TABLE data_t1(a, b, c, rbu_control); + INSERT INTO data_t1 VALUES(4, 4, 4, 0); + INSERT INTO data_t1 VALUES(5, 5, 5, 0); + + CREATE TABLE rbu_count(tbl, cnt); + INSERT INTO rbu_count VALUES('data_t1', 2); + } +} {} +do_sp_test 2.1.1 test.db rbu.db {5000 10000} + +reset_db +do_test 2.2.0 { + execsql { CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c) } + create_rbu1 rbu.db +} {rbu.db} +do_sp_test 2.2.1 test.db rbu.db {3333 6666 10000} + +reset_db +do_test 2.3.0 { + execsql { + CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c); + CREATE INDEX i1 ON t1(b); + INSERT INTO t1 VALUES(1, 1, 1); + INSERT INTO t1 VALUES(2, 2, 2); + INSERT INTO t1 VALUES(3, 3, 3); + } + create_db_file rbu.db { + CREATE TABLE data_t1(a, b, c, rbu_control); + INSERT INTO data_t1 VALUES(4, 4, 4, 0); + INSERT INTO data_t1 VALUES(2, NULL, NULL, 1); + INSERT INTO data_t1 VALUES(5, NULL, NULL, 1); + + CREATE TABLE rbu_count(tbl, cnt); + INSERT INTO rbu_count VALUES('data_t1', 3); + } +} {} +do_sp_test 2.3.1 test.db rbu.db {1666 3333 6000 8000 10000} + +reset_db +do_test 2.4.0 { + execsql { + CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c); + CREATE INDEX i1 ON t1(b); + INSERT INTO t1 VALUES(1, 1, 1); + INSERT INTO t1 VALUES(2, 2, 2); + INSERT INTO t1 VALUES(3, 3, 3); + } + create_db_file rbu.db { + CREATE TABLE data_t1(a, b, c, rbu_control); + INSERT INTO data_t1 VALUES(2, 4, 4, '.xx'); + + CREATE TABLE rbu_count(tbl, cnt); + INSERT INTO rbu_count VALUES('data_t1', 1); + } +} {} +do_sp_test 2.4.1 test.db rbu.db {3333 6666 10000} + +reset_db +do_test 2.5.0 { + execsql { + CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c); + CREATE INDEX i1 ON t1(b); + INSERT INTO t1 VALUES(1, 1, 1); + INSERT INTO t1 VALUES(2, 2, 2); + INSERT INTO t1 VALUES(3, 3, 3); + } + create_db_file rbu.db { + CREATE TABLE data_t1(a, b, c, rbu_control); + INSERT INTO data_t1 VALUES(4, NULL, 4, '.xx'); + + CREATE TABLE rbu_count(tbl, cnt); + INSERT INTO rbu_count VALUES('data_t1', 1); + } +} {} +do_sp_test 2.5.1 test.db rbu.db {10000} + +finish_test + diff --git a/ext/rbu/sqlite3rbu.c b/ext/rbu/sqlite3rbu.c index 474e39fe8d..31d462b2b7 100644 --- a/ext/rbu/sqlite3rbu.c +++ b/ext/rbu/sqlite3rbu.c @@ -147,14 +147,15 @@ ** RBU_STATE_OALSZ: ** Valid if STAGE==1. The size in bytes of the *-oal file. */ -#define RBU_STATE_STAGE 1 -#define RBU_STATE_TBL 2 -#define RBU_STATE_IDX 3 -#define RBU_STATE_ROW 4 -#define RBU_STATE_PROGRESS 5 -#define RBU_STATE_CKPT 6 -#define RBU_STATE_COOKIE 7 -#define RBU_STATE_OALSZ 8 +#define RBU_STATE_STAGE 1 +#define RBU_STATE_TBL 2 +#define RBU_STATE_IDX 3 +#define RBU_STATE_ROW 4 +#define RBU_STATE_PROGRESS 5 +#define RBU_STATE_CKPT 6 +#define RBU_STATE_COOKIE 7 +#define RBU_STATE_OALSZ 8 +#define RBU_STATE_PHASEONESTEP 9 #define RBU_STAGE_OAL 1 #define RBU_STAGE_MOVE 2 @@ -200,6 +201,7 @@ struct RbuState { i64 nProgress; u32 iCookie; i64 iOalSz; + i64 nPhaseOneStep; }; struct RbuUpdateStmt { @@ -244,6 +246,7 @@ struct RbuObjIter { int iTnum; /* Root page of current object */ int iPkTnum; /* If eType==EXTERNAL, root of PK index */ int bUnique; /* Current index is unique */ + int nIndex; /* Number of aux. indexes on table zTbl */ /* Statements created by rbuObjIterPrepareAll() */ int nCol; /* Number of columns in current object */ @@ -314,6 +317,7 @@ struct sqlite3rbu { const char *zVfsName; /* Name of automatically created rbu vfs */ rbu_file *pTargetFd; /* File handle open on target db */ i64 iOalSz; + i64 nPhaseOneStep; /* The following state variables are used as part of the incremental ** checkpoint stage (eStage==RBU_STAGE_CKPT). See comments surrounding @@ -1144,6 +1148,7 @@ static void rbuObjIterCacheIndexedCols(sqlite3rbu *p, RbuObjIter *pIter){ ); } + pIter->nIndex = 0; while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pList) ){ const char *zIdx = (const char*)sqlite3_column_text(pList, 1); sqlite3_stmt *pXInfo = 0; @@ -1157,6 +1162,7 @@ static void rbuObjIterCacheIndexedCols(sqlite3rbu *p, RbuObjIter *pIter){ } rbuFinalize(p, pXInfo); bIndex = 1; + pIter->nIndex++; } rbuFinalize(p, pList); @@ -1823,6 +1829,14 @@ static void rbuTmpInsertFunc( int rc = SQLITE_OK; int i; + assert( sqlite3_value_int(apVal[0])!=0 + || p->objiter.eType==RBU_PK_EXTERNAL + || p->objiter.eType==RBU_PK_NONE + ); + if( sqlite3_value_int(apVal[0])!=0 ){ + p->nPhaseOneStep += p->objiter.nIndex; + } + for(i=0; rc==SQLITE_OK && iobjiter.pTmpInsert, i+1, apVal[i]); } @@ -2567,6 +2581,17 @@ static void rbuStepOneOp(sqlite3rbu *p, int eType){ assert( p->rc==SQLITE_OK ); assert( eType!=RBU_DELETE || pIter->zIdx==0 ); + assert( eType==RBU_DELETE || eType==RBU_IDX_DELETE + || eType==RBU_INSERT || eType==RBU_IDX_INSERT + ); + + /* If this is a delete, decrement nPhaseOneStep by nIndex. If the DELETE + ** statement below does actually delete a row, nPhaseOneStep will be + ** incremented by the same amount when SQL function rbu_tmp_insert() + ** is invoked by the trigger. */ + if( eType==RBU_DELETE ){ + p->nPhaseOneStep -= p->objiter.nIndex; + } if( eType==RBU_IDX_DELETE || eType==RBU_DELETE ){ pWriter = pIter->pDelete; @@ -2642,7 +2667,10 @@ static int rbuStep(sqlite3rbu *p){ rbuBadControlError(p); } else if( eType==RBU_REPLACE ){ - if( pIter->zIdx==0 ) rbuStepOneOp(p, RBU_DELETE); + if( pIter->zIdx==0 ){ + p->nPhaseOneStep += p->objiter.nIndex; + rbuStepOneOp(p, RBU_DELETE); + } if( p->rc==SQLITE_OK ) rbuStepOneOp(p, RBU_INSERT); } else if( eType!=RBU_UPDATE ){ @@ -2652,6 +2680,7 @@ static int rbuStep(sqlite3rbu *p){ sqlite3_value *pVal; sqlite3_stmt *pUpdate = 0; assert( eType==RBU_UPDATE ); + p->nPhaseOneStep -= p->objiter.nIndex; rbuGetUpdateStmt(p, pIter, zMask, &pUpdate); if( pUpdate ){ int i; @@ -2729,6 +2758,7 @@ static void rbuSaveState(sqlite3rbu *p, int eStage){ "(%d, %d), " "(%d, %lld), " "(%d, %lld), " + "(%d, %lld), " "(%d, %lld) ", p->zStateDb, RBU_STATE_STAGE, eStage, @@ -2738,7 +2768,8 @@ static void rbuSaveState(sqlite3rbu *p, int eStage){ RBU_STATE_PROGRESS, p->nProgress, RBU_STATE_CKPT, p->iWalCksum, RBU_STATE_COOKIE, (i64)p->pTargetFd->iCookie, - RBU_STATE_OALSZ, p->iOalSz + RBU_STATE_OALSZ, p->iOalSz, + RBU_STATE_PHASEONESTEP, p->nPhaseOneStep ) ); assert( pInsert==0 || rc==SQLITE_OK ); @@ -2925,6 +2956,10 @@ static RbuState *rbuLoadState(sqlite3rbu *p){ pRet->iOalSz = (u32)sqlite3_column_int64(pStmt, 1); break; + case RBU_STATE_PHASEONESTEP: + pRet->nPhaseOneStep = (u32)sqlite3_column_int64(pStmt, 1); + break; + default: rc = SQLITE_CORRUPT; break; @@ -3032,6 +3067,97 @@ static void rbuDeleteVfs(sqlite3rbu *p){ } } +/* +** +*/ +static void rbuIndexCntFunc( + sqlite3_context *pCtx, + int nVal, + sqlite3_value **apVal +){ + sqlite3rbu *p = (sqlite3rbu*)sqlite3_user_data(pCtx); + sqlite3_stmt *pStmt = 0; + char *zErrmsg = 0; + int rc; + + assert( nVal==1 ); + + rc = prepareFreeAndCollectError(p->dbMain, &pStmt, &zErrmsg, + sqlite3_mprintf("PRAGMA index_list = %Q", sqlite3_value_text(apVal[0])) + ); + if( rc!=SQLITE_OK ){ + sqlite3_result_error(pCtx, zErrmsg, -1); + }else{ + int nIndex = 0; + while( SQLITE_ROW==sqlite3_step(pStmt) ){ + nIndex++; + } + rc = sqlite3_finalize(pStmt); + if( rc==SQLITE_OK ){ + sqlite3_result_int(pCtx, nIndex); + }else{ + sqlite3_result_error(pCtx, sqlite3_errmsg(p->dbMain), -1); + } + } + + sqlite3_free(zErrmsg); +} + +/* +** If the RBU database contains the rbu_count table, use it to initialize +** the sqlite3rbu.nPhaseOneStep variable. The schema of the rbu_count table +** is assumed to contain the same columns as: +** +** CREATE TABLE rbu_count(tbl TEXT PRIMARY KEY, cnt INTEGER) WITHOUT ROWID; +** +** There should be one row in the table for each data_xxx table in the +** database. The 'tbl' column should contain the name of a data_xxx table, +** and the cnt column the number of rows it contains. +** +** sqlite3rbu.nPhaseOneStep is initialized to the sum of (1 + nIndex) * cnt +** for all rows in the rbu_count table, where nIndex is the number of +** indexes on the corresponding target database table. +*/ +static void rbuInitPhaseOneSteps(sqlite3rbu *p){ + if( p->rc==SQLITE_OK ){ + sqlite3_stmt *pStmt = 0; + int bExists = 0; /* True if rbu_count exists */ + + p->nPhaseOneStep = -1; + + p->rc = sqlite3_create_function(p->dbRbu, + "rbu_index_cnt", 1, SQLITE_UTF8, (void*)p, rbuIndexCntFunc, 0, 0 + ); + + /* Check for the rbu_count table. If it does not exist, or if an error + ** occurs, nPhaseOneStep will be left set to -1. */ + if( p->rc==SQLITE_OK ){ + p->rc = prepareAndCollectError(p->dbRbu, &pStmt, &p->zErrmsg, + "SELECT 1 FROM sqlite_master WHERE tbl_name = 'rbu_count'" + ); + } + if( p->rc==SQLITE_OK ){ + if( SQLITE_ROW==sqlite3_step(pStmt) ){ + bExists = 1; + } + p->rc = sqlite3_finalize(pStmt); + } + + if( p->rc==SQLITE_OK && bExists ){ + p->rc = prepareAndCollectError(p->dbRbu, &pStmt, &p->zErrmsg, + "SELECT sum(cnt * (1 + rbu_index_cnt(rbu_target_name(tbl))))" + "FROM rbu_count" + ); + if( p->rc==SQLITE_OK ){ + if( SQLITE_ROW==sqlite3_step(pStmt) ){ + p->nPhaseOneStep = sqlite3_column_int64(pStmt, 0); + } + p->rc = sqlite3_finalize(pStmt); + } + } + } +} + /* ** Open and return a new RBU handle. */ @@ -3077,6 +3203,7 @@ sqlite3rbu *sqlite3rbu_open( if( pState->eStage==0 ){ rbuDeleteOalFile(p); + rbuInitPhaseOneSteps(p); p->eStage = RBU_STAGE_OAL; }else{ p->eStage = pState->eStage; @@ -3243,6 +3370,38 @@ sqlite3_int64 sqlite3rbu_progress(sqlite3rbu *pRbu){ return pRbu->nProgress; } +void sqlite3rbu_stage_progress(sqlite3rbu *p, int *pnOne, int *pnTwo){ + const int MAX_PROGRESS = 10000; + switch( p->eStage ){ + case RBU_STAGE_OAL: + if( p->nPhaseOneStep>0 ){ + *pnOne = (int)(MAX_PROGRESS * (i64)p->nProgress/(i64)p->nPhaseOneStep); + }else{ + *pnOne = -1; + } + *pnTwo = 0; + break; + + case RBU_STAGE_MOVE: + *pnOne = MAX_PROGRESS; + *pnTwo = 0; + break; + + case RBU_STAGE_CKPT: + *pnOne = MAX_PROGRESS; + *pnTwo = (int)(MAX_PROGRESS * (i64)p->nStep / (i64)p->nFrame); + break; + + case RBU_STAGE_DONE: + *pnOne = MAX_PROGRESS; + *pnTwo = MAX_PROGRESS; + break; + + default: + assert( 0 ); + } +} + int sqlite3rbu_savestate(sqlite3rbu *p){ int rc = p->rc; diff --git a/ext/rbu/sqlite3rbu.h b/ext/rbu/sqlite3rbu.h index f1a0f3cd84..fb81c85a0a 100644 --- a/ext/rbu/sqlite3rbu.h +++ b/ext/rbu/sqlite3rbu.h @@ -400,6 +400,8 @@ int sqlite3rbu_close(sqlite3rbu *pRbu, char **pzErrmsg); */ sqlite3_int64 sqlite3rbu_progress(sqlite3rbu *pRbu); +void sqlite3rbu_stage_progress(sqlite3rbu *pRbu, int *pnOne, int *pnTwo); + /* ** Create an RBU VFS named zName that accesses the underlying file-system ** via existing VFS zParent. Or, if the zParent parameter is passed NULL, diff --git a/ext/rbu/test_rbu.c b/ext/rbu/test_rbu.c index 3fa85b7569..e35d76e745 100644 --- a/ext/rbu/test_rbu.c +++ b/ext/rbu/test_rbu.c @@ -66,6 +66,7 @@ static int test_sqlite3rbu_cmd( {"create_rbu_delta", 2, ""}, /* 2 */ {"savestate", 2, ""}, /* 3 */ {"dbMain_eval", 3, "SQL"}, /* 4 */ + {"stage_progress", 2, ""}, /* 5 */ {0,0,0} }; int iCmd; @@ -136,6 +137,18 @@ static int test_sqlite3rbu_cmd( break; } + case 5: /* stage_progress */ { + int one, two; + Tcl_Obj *pObj; + sqlite3rbu_stage_progress(pRbu, &one, &two); + + pObj = Tcl_NewObj(); + Tcl_ListObjAppendElement(interp, pObj, Tcl_NewIntObj(one)); + Tcl_ListObjAppendElement(interp, pObj, Tcl_NewIntObj(two)); + Tcl_SetObjResult(interp, pObj); + break; + } + default: /* seems unlikely */ assert( !"cannot happen" ); break; diff --git a/manifest b/manifest index 3d02d28e9b..e0a85e57cc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C The\sprepared\sstatements\sfor\ssome\spragmas\scan\snow\sbe\sreused\swithout\sinvoking\nan\sautomatic\sreprepare. -D 2016-03-16T21:29:54.761 +C Add\san\sAPI\sto\sindicate\sthe\spercentage\sprogress\sof\san\srbu\supdate. +D 2016-03-17T21:06:42.412 F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66 @@ -242,10 +242,11 @@ F ext/rbu/rbudiff.test 6cc806dc36389292f2a8f5842d0103721df4a07d F ext/rbu/rbufault.test cc0be8d5d392d98b0c2d6a51be377ea989250a89 F ext/rbu/rbufault2.test 9a7f19edd6ea35c4c9f807d8a3db0a03a5670c06 F ext/rbu/rbufts.test 828cd689da825f0a7b7c53ffc1f6f7fdb6fa5bda +F ext/rbu/rbuprogress.test d63b70f838a20422dce6445bcaed10890e506d02 F ext/rbu/rbusave.test 0f43b6686084f426ddd040b878426452fd2c2f48 -F ext/rbu/sqlite3rbu.c 5956f8bee63b5ab2b04e65c1801ea0f5920dac92 -F ext/rbu/sqlite3rbu.h 0bdeb3be211aaba7d85445fa36f4701a25a3dbde -F ext/rbu/test_rbu.c 4a4cdcef4ef9379fc2a21f008805c80b27bcf573 +F ext/rbu/sqlite3rbu.c 9bcf35b2f1d8eaf1c82b47bead114b2289ea06c6 +F ext/rbu/sqlite3rbu.h f8ee94f95fc80a35b7cb7ef3f2f5ea740b662477 +F ext/rbu/test_rbu.c 5b6d31af188193d929234d1cd08ee967df092f66 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 F ext/rtree/rtree.c 0b870ccb7b58b734a2a8e1e2755a7c0ded070920 F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e @@ -1456,8 +1457,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 10a3e2a01db9f80452a2a3369fd25b6fd9798274 db1ce7e13e656fcd2766f1b1f225cbfefe8f73ad -R 2716c51dfa2bfe8ed5e18127e51ae3c8 -T +closed db1ce7e13e656fcd2766f1b1f225cbfefe8f73ad -U drh -Z e3b23194e47816995dbce6c752704ef0 +P 97b0e88cc7c3d677217d0bfab4cb4a34a4abb238 +R 9de86de419de6ede9128347e06885dfc +T *branch * rbu-percent-progress +T *sym-rbu-percent-progress * +T -sym-trunk * +U dan +Z f4146c58d33c341586c7f6e824f90dbe diff --git a/manifest.uuid b/manifest.uuid index 06db10b8a2..ca52cccd3f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -97b0e88cc7c3d677217d0bfab4cb4a34a4abb238 \ No newline at end of file +ffc58d2c2576a5b6e1c2c7112612c5760e711afd \ No newline at end of file From 790b151e19cb274f11baad738d6058b6f79dcd1e Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 17 Mar 2016 23:00:42 +0000 Subject: [PATCH 0168/1484] Changes to releasetest.tcl: Rename the "OS-X" configuration to "Apple". Bring the "Apple" configuration up to date. Allow the use of "if:os=..." arguments in a configuration. Run the Apple configuration on Linux in addition to on Macs, but without -DSQLITE_ENABLE_LOCKING_STYLE. FossilOrigin-Name: beb2a80b430e0ad561a58d8f00b80cbdc74b5e03 --- manifest | 12 ++++----- manifest.uuid | 2 +- test/releasetest.tcl | 62 ++++++++++++++++++++++++++++++++++---------- 3 files changed, 55 insertions(+), 21 deletions(-) diff --git a/manifest b/manifest index 68ccf6c76c..c420888c92 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C A\smore\scompact\simplementation\sof\sthe\scode\sgenerator\sfor\sthe\nIS\sand\sIS\sNOT\soperators. -D 2016-03-17T19:07:52.217 +C Changes\sto\sreleasetest.tcl:\s\sRename\sthe\s"OS-X"\sconfiguration\sto\s"Apple".\nBring\sthe\s"Apple"\sconfiguration\sup\sto\sdate.\s\sAllow\sthe\suse\sof\s"if:os=..."\narguments\sin\sa\sconfiguration.\s\sRun\sthe\sApple\sconfiguration\son\sLinux\sin\saddition\nto\son\sMacs,\sbut\swithout\s-DSQLITE_ENABLE_LOCKING_STYLE. +D 2016-03-17T23:00:42.207 F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66 @@ -971,7 +971,7 @@ F test/rdonly.test 64e2696c322e3538df0b1ed624e21f9a23ed9ff8 F test/regexp1.test 497ea812f264d12b6198d6e50a76be4a1973a9d8 F test/regexp2.test aa7ffcc21350007a78361b82bcf3b74d12227144 F test/reindex.test 44edd3966b474468b823d481eafef0c305022254 -F test/releasetest.tcl a246ecb14ed594bf44bf77bd21df873971d779bf +F test/releasetest.tcl a07c3a11fb1bd00a77673bd6f72bd0cd59c8d6af F test/resolver01.test f4022acafda7f4d40eca94dbf16bc5fc4ac30ceb F test/rollback.test 458fe73eb3ffdfdf9f6ba3e9b7350a6220414dea F test/rollback2.test 8435d6ff0f13f51d2a4181c232e706005fa90fc5 @@ -1456,7 +1456,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 97b0e88cc7c3d677217d0bfab4cb4a34a4abb238 -R 7d24921d4d6b93efccc35ce02f43234b +P 8607e3ac7a9d44372a4a66da21bbb3d28ae2528a +R b7facb3a60b8b0eb25dafd6297755878 U drh -Z d01f371f2a1444a2eb95b11e7cec5f5e +Z da6ac72adf144eb20e25874187166c45 diff --git a/manifest.uuid b/manifest.uuid index ad8858c776..f226e93a8e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8607e3ac7a9d44372a4a66da21bbb3d28ae2528a \ No newline at end of file +beb2a80b430e0ad561a58d8f00b80cbdc74b5e03 \ No newline at end of file diff --git a/test/releasetest.tcl b/test/releasetest.tcl index 2bcf1aa511..db36690ebc 100644 --- a/test/releasetest.tcl +++ b/test/releasetest.tcl @@ -174,24 +174,47 @@ array set ::Configs [strip_comments { -O2 -DSQLITE_ENABLE_LOCKING_STYLE=1 } - "OS-X" { + "Apple" { -O1 # Avoid a compiler bug in gcc 4.2.1 build 5658 - -DSQLITE_OMIT_LOAD_EXTENSION=1 - -DSQLITE_DEFAULT_MEMSTATUS=0 - -DSQLITE_THREADSAFE=2 - -DSQLITE_OS_UNIX=1 - -DSQLITE_ENABLE_JSON1=1 - -DSQLITE_ENABLE_LOCKING_STYLE=1 - -DUSE_PREAD=1 - -DSQLITE_ENABLE_RTREE=1 + -DHAVE_GMTIME_R=1 + -DHAVE_ISNAN=1 + -DHAVE_LOCALTIME_R=1 + -DHAVE_PREAD=1 + -DHAVE_PWRITE=1 + -DHAVE_USLEEP=1 + -DHAVE_USLEEP=1 + -DHAVE_UTIME=1 + -DSQLITE_DEFAULT_CACHE_SIZE=1000 + -DSQLITE_DEFAULT_CKPTFULLFSYNC=1 + -DSQLITE_DEFAULT_MEMSTATUS=1 + -DSQLITE_DEFAULT_PAGE_SIZE=1024 + -DSQLITE_DISABLE_PAGECACHE_OVERFLOW_STATS=1 + -DSQLITE_ENABLE_API_ARMOR=1 + -DSQLITE_ENABLE_AUTO_PROFILE=1 + -DSQLITE_ENABLE_FLOCKTIMEOUT=1 -DSQLITE_ENABLE_FTS3=1 -DSQLITE_ENABLE_FTS3_PARENTHESIS=1 - -DSQLITE_DEFAULT_CACHE_SIZE=1000 + -DSQLITE_ENABLE_FTS3_TOKENIZER=1 + if:os=="Darwin" -DSQLITE_ENABLE_LOCKING_STYLE=1 + -DSQLITE_ENABLE_PERSIST_WAL=1 + -DSQLITE_ENABLE_PURGEABLE_PCACHE=1 + -DSQLITE_ENABLE_RTREE=1 + -DSQLITE_ENABLE_SNAPSHOT=1 + # -DSQLITE_ENABLE_SQLLOG=1 + -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT=1 -DSQLITE_MAX_LENGTH=2147483645 -DSQLITE_MAX_VARIABLE_NUMBER=500000 - -DSQLITE_DEBUG=1 + -DSQLITE_MEMDEBUG=1 + -DSQLITE_NO_SYNC=1 + -DSQLITE_OMIT_AUTORESET=1 + -DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_PREFER_PROXY_LOCKING=1 - -DSQLITE_ENABLE_API_ARMOR=1 + -DSQLITE_SERIES_CONSTRAINT_VERIFY=1 + -DSQLITE_THREADSAFE=2 + -DSQLITE_USE_URI=1 + -DSQLITE_WRITE_WALFRAME_PREBUFFERED=1 + -DUSE_GUARDED_FD=1 + -DUSE_PREAD=1 --enable-json1 --enable-fts5 } "Extra-Robustness" { @@ -248,6 +271,7 @@ array set ::Platforms [strip_comments { "Device-Two" test "No-lookaside" test "Devkit" test + "Apple" test "Sanitize" {QUICKTEST_OMIT=func4.test,nan.test test} "Device-One" fulltest "Default" "threadtest fulltest" @@ -264,12 +288,12 @@ array set ::Platforms [strip_comments { Darwin-i386 { "Locking-Style" "mptest test" "Have-Not" test - "OS-X" "threadtest fulltest" + "Apple" "threadtest fulltest" } Darwin-x86_64 { "Locking-Style" "mptest test" "Have-Not" test - "OS-X" "threadtest fulltest" + "Apple" "threadtest fulltest" } "Windows NT-intel" { "Have-Not" test @@ -588,13 +612,23 @@ proc add_test_suite {listvar name testtarget config} { set opts "" set title ${name}($testtarget) set configOpts $::WITHTCL + set skip 0 regsub -all {#[^\n]*\n} $config \n config foreach arg $config { + if {$skip} { + set skip 0 + continue + } if {[regexp {^-[UD]} $arg]} { lappend opts $arg } elseif {[regexp {^[A-Z]+=} $arg]} { lappend testtarget $arg + } elseif {[regexp {^if:([a-z]+)(.*)} $arg all key tail]} { + # Arguments of the form 'if:os=="Linux"' will cause the subsequent + # argument to be skipped if the $tcl_platform(os) is not "Linux", for + # example... + set skip [expr !(\$::tcl_platform($key)$tail)] } elseif {[regexp {^--(enable|disable)-} $arg]} { if {$::MSVC} { if {$arg eq "--disable-amalgamation"} { From 9493cafe6f54f0bcff3c21014ea3b8d2c971e03d Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 17 Mar 2016 23:16:37 +0000 Subject: [PATCH 0169/1484] Fix harmless compiler warnings that arise with -DSQLITE_OMIT_LOAD_EXTENSION FossilOrigin-Name: 65ba2f0b465a1493de6e467f55e0300ac3fb08e1 --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/pcache1.c | 12 +++++++----- src/test1.c | 2 ++ test/releasetest.tcl | 2 +- tool/sqldiff.c | 4 +++- 6 files changed, 23 insertions(+), 17 deletions(-) diff --git a/manifest b/manifest index c420888c92..9d6db86ef2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Changes\sto\sreleasetest.tcl:\s\sRename\sthe\s"OS-X"\sconfiguration\sto\s"Apple".\nBring\sthe\s"Apple"\sconfiguration\sup\sto\sdate.\s\sAllow\sthe\suse\sof\s"if:os=..."\narguments\sin\sa\sconfiguration.\s\sRun\sthe\sApple\sconfiguration\son\sLinux\sin\saddition\nto\son\sMacs,\sbut\swithout\s-DSQLITE_ENABLE_LOCKING_STYLE. -D 2016-03-17T23:00:42.207 +C Fix\sharmless\scompiler\swarnings\sthat\sarise\swith\s-DSQLITE_OMIT_LOAD_EXTENSION +D 2016-03-17T23:16:37.996 F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66 @@ -342,7 +342,7 @@ F src/pager.h e1d38a2f14849e219df0f91f8323504d134c8a56 F src/parse.y 5ea8c81c5c41b27887f41b4a7e1c58470d7d3821 F src/pcache.c 647bb53a86b7bbcf55ad88089b3ea5a9170b90df F src/pcache.h 4d0ccaad264d360981ec5e6a2b596d6e85242545 -F src/pcache1.c 72f644dc9e1468c72922eff5904048427b817051 +F src/pcache1.c c40cdb93586e21b5dd826b5e671240bd91c26b05 F src/pragma.c f0670909e915179fec47e17f72f14660995b8022 F src/pragma.h 64c78a648751b9f4f297276c4eb7507b14b4628c F src/prepare.c 22df6171aec1d86904ed2ad30c2348a5748aa04e @@ -360,7 +360,7 @@ F src/sqliteLimit.h 7b28cf72cbd52f178bfc97ea266445e351f2cd24 F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 F src/tclsqlite.c 4bf3bea9b03aeac176ac114700f35f76a1de4c8a -F src/test1.c 52965bd684ddcd7f22328ebd7d50fd0b6e51f0d4 +F src/test1.c 941f1cb50a601c30fd426a381e783b863c9d7d13 F src/test2.c 5586f43fcd9a1be0830793cf9d354082c261b25b F src/test3.c a8887dabbbee3059af338f20d290084a63ed1b0f F src/test4.c d168f83cc78d02e8d35567bb5630e40dcd85ac1e @@ -971,7 +971,7 @@ F test/rdonly.test 64e2696c322e3538df0b1ed624e21f9a23ed9ff8 F test/regexp1.test 497ea812f264d12b6198d6e50a76be4a1973a9d8 F test/regexp2.test aa7ffcc21350007a78361b82bcf3b74d12227144 F test/reindex.test 44edd3966b474468b823d481eafef0c305022254 -F test/releasetest.tcl a07c3a11fb1bd00a77673bd6f72bd0cd59c8d6af +F test/releasetest.tcl f2519836bebefcc7db36b4946e8028d4885baa59 F test/resolver01.test f4022acafda7f4d40eca94dbf16bc5fc4ac30ceb F test/rollback.test 458fe73eb3ffdfdf9f6ba3e9b7350a6220414dea F test/rollback2.test 8435d6ff0f13f51d2a4181c232e706005fa90fc5 @@ -1423,7 +1423,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 7ce07da76b5e745783e703a834417d725b7d45fd F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c -F tool/sqldiff.c 5a26205111e6fa856d9b1535b1637744dcdb930b +F tool/sqldiff.c 0e9b76f9f4a72856d0384f5e0a038bbeb78dd222 F tool/srcck1.c 4f65e1a6748e42f24c0ea629dddc934d821c729a F tool/stack_usage.tcl f8e71b92cdb099a147dad572375595eae55eca43 F tool/symbols-mingw.sh 4dbcea7e74768305384c9fd2ed2b41bbf9f0414d @@ -1456,7 +1456,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 8607e3ac7a9d44372a4a66da21bbb3d28ae2528a -R b7facb3a60b8b0eb25dafd6297755878 +P beb2a80b430e0ad561a58d8f00b80cbdc74b5e03 +R 37561b4e78990edaf3c970fae7bb038b U drh -Z da6ac72adf144eb20e25874187166c45 +Z cf3b29714b0e10f6a050d8250c16f911 diff --git a/manifest.uuid b/manifest.uuid index f226e93a8e..5f8e183ba7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -beb2a80b430e0ad561a58d8f00b80cbdc74b5e03 \ No newline at end of file +65ba2f0b465a1493de6e467f55e0300ac3fb08e1 \ No newline at end of file diff --git a/src/pcache1.c b/src/pcache1.c index 7147f6a7a8..d168e7fbcb 100644 --- a/src/pcache1.c +++ b/src/pcache1.c @@ -348,7 +348,6 @@ static void *pcache1Alloc(int nByte){ ** Free an allocated buffer obtained from pcache1Alloc(). */ static void pcache1Free(void *p){ - int nFreed = 0; if( p==0 ) return; if( SQLITE_WITHIN(p, pcache1.pStart, pcache1.pEnd) ){ PgFreeslot *pSlot; @@ -365,10 +364,13 @@ static void pcache1Free(void *p){ assert( sqlite3MemdebugHasType(p, MEMTYPE_PCACHE) ); sqlite3MemdebugSetType(p, MEMTYPE_HEAP); #ifndef SQLITE_DISABLE_PAGECACHE_OVERFLOW_STATS - nFreed = sqlite3MallocSize(p); - sqlite3_mutex_enter(pcache1.mutex); - sqlite3StatusDown(SQLITE_STATUS_PAGECACHE_OVERFLOW, nFreed); - sqlite3_mutex_leave(pcache1.mutex); + { + int nFreed = 0; + nFreed = sqlite3MallocSize(p); + sqlite3_mutex_enter(pcache1.mutex); + sqlite3StatusDown(SQLITE_STATUS_PAGECACHE_OVERFLOW, nFreed); + sqlite3_mutex_leave(pcache1.mutex); + } #endif sqlite3_free(p); } diff --git a/src/test1.c b/src/test1.c index 8ad653ca6c..0de5faf82d 100644 --- a/src/test1.c +++ b/src/test1.c @@ -1931,6 +1931,8 @@ static int test_load_extension( #ifdef SQLITE_OMIT_LOAD_EXTENSION rc = SQLITE_ERROR; zErr = sqlite3_mprintf("this build omits sqlite3_load_extension()"); + (void)zProc; + (void)zFile; #else rc = sqlite3_load_extension(db, zFile, zProc, &zErr); #endif diff --git a/test/releasetest.tcl b/test/releasetest.tcl index db36690ebc..15f64e3218 100644 --- a/test/releasetest.tcl +++ b/test/releasetest.tcl @@ -204,7 +204,7 @@ array set ::Configs [strip_comments { -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT=1 -DSQLITE_MAX_LENGTH=2147483645 -DSQLITE_MAX_VARIABLE_NUMBER=500000 - -DSQLITE_MEMDEBUG=1 + # -DSQLITE_MEMDEBUG=1 -DSQLITE_NO_SYNC=1 -DSQLITE_OMIT_AUTORESET=1 -DSQLITE_OMIT_LOAD_EXTENSION=1 diff --git a/tool/sqldiff.c b/tool/sqldiff.c index ae01cd3c4d..d2423a73ba 100644 --- a/tool/sqldiff.c +++ b/tool/sqldiff.c @@ -1757,8 +1757,10 @@ int main(int argc, char **argv){ char *zTab = 0; FILE *out = stdout; void (*xDiff)(const char*,FILE*) = diff_one_table; +#ifndef SQLITE_OMIT_LOAD_EXTENSION int nExt = 0; char **azExt = 0; +#endif int useTransaction = 0; int neverUseTransaction = 0; @@ -1841,8 +1843,8 @@ int main(int argc, char **argv){ cmdlineError("error loading %s: %s", azExt[i], zErrMsg); } } -#endif free(azExt); +#endif zSql = sqlite3_mprintf("ATTACH %Q as aux;", zDb2); rc = sqlite3_exec(g.db, zSql, 0, 0, &zErrMsg); if( rc || zErrMsg ){ From 108e5a9a6cafbdeab09bc24fd17d7050a0273b9b Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 17 Mar 2016 23:56:23 +0000 Subject: [PATCH 0170/1484] Fix some test cases so that they work under the Apple configuration. FossilOrigin-Name: 399c60764d3fdec49dab1745c30930ca1dbafe70 --- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- src/test_config.c | 7 +++++++ test/capi3.test | 21 +++++++++++---------- test/capi3c.test | 21 +++++++++++---------- test/wal2.test | 3 +++ test/wal3.test | 1 + 7 files changed, 44 insertions(+), 31 deletions(-) diff --git a/manifest b/manifest index 9d6db86ef2..6b11a73093 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\scompiler\swarnings\sthat\sarise\swith\s-DSQLITE_OMIT_LOAD_EXTENSION -D 2016-03-17T23:16:37.996 +C Fix\ssome\stest\scases\sso\sthat\sthey\swork\sunder\sthe\sApple\sconfiguration. +D 2016-03-17T23:56:23.638 F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66 @@ -375,7 +375,7 @@ F src/test_backup.c 2e6e6a081870150f20c526a2e9d0d29cda47d803 F src/test_bestindex.c 29af3cc3b963ffe5760c85d142b9b3e5302c1e3d F src/test_blob.c b2551a9b5573232db5f66f292307c37067937239 F src/test_btree.c 2e9978eca99a9a4bfa8cae949efb00886860a64f -F src/test_config.c 0dee90328e3dedf8ba002ee94b6a7e7ea7726fe4 +F src/test_config.c 57e52a768ea0dd3499164e307559d5eb96df7ee3 F src/test_demovfs.c 0de72c2c89551629f58486fde5734b7d90758852 F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc F src/test_fs.c f10f840ca4f8c72e4837908bd8347ac4bcab074b @@ -520,9 +520,9 @@ F test/busy.test 76b4887f8b9160ba903c1ac22e8ff406ad6ae2f0 F test/cache.test 13bc046b26210471ca6f2889aceb1ea52dc717de F test/cacheflush.test af25bb1509df04c1da10e38d8f322d66eceedf61 F test/capi2.test 011c16da245fdc0106a2785035de6b242c05e738 -F test/capi3.test bf6f0308bbbba1e770dac13aa08e5c2ac61c7324 +F test/capi3.test db0731f6e2a94f96c6d4c478fedef4e0c077026c F test/capi3b.test efb2b9cfd127efa84433cd7a2d72ce0454ae0dc4 -F test/capi3c.test 06f6261f9e9b4ef6f76afcd9900f3665408af1c8 +F test/capi3c.test b28ec47692f0fc50eb61b2d464d8d52e816b3732 F test/capi3d.test 485048dc5cd07bc68011e4917ad035ad6047ab82 F test/capi3e.test 3d49c01ef2a1a55f41d73cba2b23b5059ec460fe F test/cast.test 4c275cbdc8202d6f9c54a3596701719868ac7dc3 @@ -1304,8 +1304,8 @@ F test/vtab_alter.test 9e374885248f69e251bdaacf480b04a197f125e5 F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8 F test/vtab_shared.test 5253bff2355a9a3f014c15337da7e177ab0ef8ad F test/wal.test 613efec03e517e1775d86b993a54877d2e29a477 -F test/wal2.test 25ae059e900dbb584e0775627e45415ba5940df1 -F test/wal3.test 5dd734147f1f8f958c5261a1f2775d346d7013ce +F test/wal2.test 56b0bc95b8693a0be294f8d210c49025dd094bd7 +F test/wal3.test 2a93004bc0fb2b5c29888964024695bade278ab2 F test/wal4.test 4744e155cd6299c6bd99d3eab1c82f77db9cdb3c F test/wal5.test 9c11da7aeccd83a46d79a556ad11a18d3cb15aa9 F test/wal6.test a9d6aa635b9d63607dabdc11406f5f96ca986635 @@ -1456,7 +1456,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P beb2a80b430e0ad561a58d8f00b80cbdc74b5e03 -R 37561b4e78990edaf3c970fae7bb038b +P 65ba2f0b465a1493de6e467f55e0300ac3fb08e1 +R 7cf410a0d799b5e757a3a8b96ff17372 U drh -Z cf3b29714b0e10f6a050d8250c16f911 +Z 802d45975b74ad53aebc4d60c61be48a diff --git a/manifest.uuid b/manifest.uuid index 5f8e183ba7..b971b998c3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -65ba2f0b465a1493de6e467f55e0300ac3fb08e1 \ No newline at end of file +399c60764d3fdec49dab1745c30930ca1dbafe70 \ No newline at end of file diff --git a/src/test_config.c b/src/test_config.c index 30b421e00b..cc6243e44f 100644 --- a/src/test_config.c +++ b/src/test_config.c @@ -79,6 +79,13 @@ static void set_options(Tcl_Interp *interp){ Tcl_SetVar2(interp, "sqlite_options", "debug", "0", TCL_GLOBAL_ONLY); #endif +#ifdef SQLITE_DEFAULT_CKPTFULLFSYNC + Tcl_SetVar2(interp, "sqlite_options", "default_ckptfullfsync", + SQLITE_DEFAULT_CKPTFULLFSYNC ? "1" : "0", TCL_GLOBAL_ONLY); +#else + Tcl_SetVar2(interp, "sqlite_options", "default_ckptfullfsync", "0", TCL_GLOBAL_ONLY); +#endif + #ifdef SQLITE_DIRECT_OVERFLOW_READ Tcl_SetVar2(interp, "sqlite_options", "direct_read", "1", TCL_GLOBAL_ONLY); #else diff --git a/test/capi3.test b/test/capi3.test index 163bb19ada..684872bc6b 100644 --- a/test/capi3.test +++ b/test/capi3.test @@ -925,19 +925,20 @@ do_test capi3-11.9.3 { do_test capi3-11.10 { sqlite3_step $STMT } {SQLITE_ROW} -ifcapable !autoreset { - # If SQLITE_OMIT_AUTORESET is defined, then the statement must be - # reset() before it can be passed to step() again. - do_test capi3-11.11a { sqlite3_step $STMT } {SQLITE_MISUSE} - do_test capi3-11.11b { sqlite3_reset $STMT } {SQLITE_ABORT} -} do_test capi3-11.11 { sqlite3_step $STMT } {SQLITE_DONE} -do_test capi3-11.12 { - sqlite3_step $STMT - sqlite3_step $STMT -} {SQLITE_ROW} +ifcapable api_armor { + do_test capi3-11.12armor { + sqlite3_step $STMT + sqlite3_step $STMT + } {SQLITE_MISUSE} +} else { + do_test capi3-11.12 { + sqlite3_step $STMT + sqlite3_step $STMT + } {SQLITE_ROW} +} do_test capi3-11.13 { sqlite3_finalize $STMT } {SQLITE_OK} diff --git a/test/capi3c.test b/test/capi3c.test index 15307a7f7a..91c02561b1 100644 --- a/test/capi3c.test +++ b/test/capi3c.test @@ -865,19 +865,20 @@ do_test capi3c-11.9.3 { do_test capi3c-11.10 { sqlite3_step $STMT } {SQLITE_ROW} -ifcapable !autoreset { - # If SQLITE_OMIT_AUTORESET is defined, then the statement must be - # reset() before it can be passed to step() again. - do_test capi3-11.11a { sqlite3_step $STMT } {SQLITE_MISUSE} - do_test capi3-11.11b { sqlite3_reset $STMT } {SQLITE_ABORT} -} do_test capi3c-11.11 { sqlite3_step $STMT } {SQLITE_DONE} -do_test capi3c-11.12 { - sqlite3_step $STMT - sqlite3_step $STMT -} {SQLITE_ROW} +ifcapable api_armor { + do_test capi3c-11.12armor { + sqlite3_step $STMT + sqlite3_step $STMT + } {SQLITE_MISUSE} +} else { + do_test capi3c-11.12 { + sqlite3_step $STMT + sqlite3_step $STMT + } {SQLITE_ROW} +} do_test capi3c-11.13 { sqlite3_finalize $STMT } {SQLITE_OK} diff --git a/test/wal2.test b/test/wal2.test index 4b9bbf315f..0b15b15461 100644 --- a/test/wal2.test +++ b/test/wal2.test @@ -1194,6 +1194,9 @@ foreach {tn sql reslist} { 2 { PRAGMA checkpoint_fullfsync = 1 } {10 4 4 2 6 2} 3 { PRAGMA checkpoint_fullfsync = 0 } {10 0 4 0 6 0} } { + ifcapable default_ckptfullfsync { + if {[string trim $sql]==""} continue + } faultsim_delete_and_reopen execsql {PRAGMA auto_vacuum = 0; PRAGMA synchronous = FULL;} diff --git a/test/wal3.test b/test/wal3.test index da3d318773..56f40ab539 100644 --- a/test/wal3.test +++ b/test/wal3.test @@ -220,6 +220,7 @@ foreach {tn syncmode synccount} { sqlite3 db test.db -vfs T execsql "PRAGMA synchronous = $syncmode" + execsql "PRAGMA checkpoint_fullfsync = 0" execsql { PRAGMA journal_mode = WAL } execsql { CREATE TABLE filler(a,b,c); } From b99185f278ccca4eef38637ac3d19b5ceb3db411 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 18 Mar 2016 00:19:48 +0000 Subject: [PATCH 0171/1484] Fix more test-case errors in the Apple configuration. FossilOrigin-Name: 6631e1e655604a7d1fb45b4d151938d4a13b47f3 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/test_config.c | 12 +++++++++++- test/memsubsys1.test | 10 ++++++---- test/mutex1.test | 2 +- 5 files changed, 27 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index 6b11a73093..4447b95603 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\ssome\stest\scases\sso\sthat\sthey\swork\sunder\sthe\sApple\sconfiguration. -D 2016-03-17T23:56:23.638 +C Fix\smore\stest-case\serrors\sin\sthe\sApple\sconfiguration. +D 2016-03-18T00:19:48.288 F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66 @@ -375,7 +375,7 @@ F src/test_backup.c 2e6e6a081870150f20c526a2e9d0d29cda47d803 F src/test_bestindex.c 29af3cc3b963ffe5760c85d142b9b3e5302c1e3d F src/test_blob.c b2551a9b5573232db5f66f292307c37067937239 F src/test_btree.c 2e9978eca99a9a4bfa8cae949efb00886860a64f -F src/test_config.c 57e52a768ea0dd3499164e307559d5eb96df7ee3 +F src/test_config.c 0fb2571777ef43a8442be4f9c62a25f530872328 F src/test_demovfs.c 0de72c2c89551629f58486fde5734b7d90758852 F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc F src/test_fs.c f10f840ca4f8c72e4837908bd8347ac4bcab074b @@ -889,7 +889,7 @@ F test/manydb.test 28385ae2087967aa05c38624cec7d96ec74feb3e F test/mem5.test c6460fba403c5703141348cd90de1c294188c68f F test/memdb.test c1f2a343ad14398d5d6debda6ea33e80d0dafcc7 F test/memleak.test 10b9c6c57e19fc68c32941495e9ba1c50123f6e2 -F test/memsubsys1.test 0311bfb4edd2615e3aa56c7a9cf44574e4229077 +F test/memsubsys1.test 69924593856040e266fdd9aa1ecb4d5a0888eb12 F test/memsubsys2.test 3e4a8d0c05fd3e5fa92017c64666730a520c7e08 F test/minmax.test 42fbad0e81afaa6e0de41c960329f2b2c3526efd F test/minmax2.test b44bae787fc7b227597b01b0ca5575c7cb54d3bc @@ -913,7 +913,7 @@ F test/multiplex.test efd015ca0b5b4a57dc9535b8feb1273eebeadb60 F test/multiplex2.test 580ca5817c7edbe4cc68fa150609c9473393003a F test/multiplex3.test d228f59eac91839a977eac19f21d053f03e4d101 F test/multiplex4.test e8ae4c4bd70606a5727743241f13b5701990abe4 -F test/mutex1.test e0a44072d98189003deae4b091106f085d94bea8 +F test/mutex1.test ea2cc74d97f077b9e74c84cbd024f14d79a8126f F test/mutex2.test bfeaeac2e73095b2ac32285d2756e3a65e681660 F test/nan.test dacc57f80859c06a433d30839336fe227d2038b3 F test/nolock.test 96e922d2d3db71c2dd6557c98e8027a28277b415 @@ -1456,7 +1456,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 65ba2f0b465a1493de6e467f55e0300ac3fb08e1 -R 7cf410a0d799b5e757a3a8b96ff17372 +P 399c60764d3fdec49dab1745c30930ca1dbafe70 +R 6d659b59f432dac31e8bf0c8b3f7d1b0 U drh -Z 802d45975b74ad53aebc4d60c61be48a +Z 34dc8dd8397892469013fc1a83c5fbd6 diff --git a/manifest.uuid b/manifest.uuid index b971b998c3..03b3a4a5c6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -399c60764d3fdec49dab1745c30930ca1dbafe70 \ No newline at end of file +6631e1e655604a7d1fb45b4d151938d4a13b47f3 \ No newline at end of file diff --git a/src/test_config.c b/src/test_config.c index cc6243e44f..7a51accc6f 100644 --- a/src/test_config.c +++ b/src/test_config.c @@ -104,6 +104,12 @@ static void set_options(Tcl_Interp *interp){ Tcl_SetVar2(interp, "sqlite_options", "lfs", "1", TCL_GLOBAL_ONLY); #endif +#ifdef SQLITE_DISABLE_PAGECACHE_OVERFLOW_STATS + Tcl_SetVar2(interp, "sqlite_options", "pagecache_overflow_stats","0",TCL_GLOBAL_ONLY); +#else + Tcl_SetVar2(interp, "sqlite_options", "pagecache_overflow_stats","1",TCL_GLOBAL_ONLY); +#endif + #if SQLITE_MAX_MMAP_SIZE>0 Tcl_SetVar2(interp, "sqlite_options", "mmap", "1", TCL_GLOBAL_ONLY); #else @@ -583,7 +589,11 @@ Tcl_SetVar2(interp, "sqlite_options", "mergesort", "1", TCL_GLOBAL_ONLY); #endif Tcl_SetVar2(interp, "sqlite_options", "threadsafe", - STRINGVALUE(SQLITE_THREADSAFE), TCL_GLOBAL_ONLY); + SQLITE_THREADSAFE ? "1" : "0", TCL_GLOBAL_ONLY); + Tcl_SetVar2(interp, "sqlite_options", "threadsafe1", + SQLITE_THREADSAFE==1 ? "1" : "0", TCL_GLOBAL_ONLY); + Tcl_SetVar2(interp, "sqlite_options", "threadsafe2", + SQLITE_THREADSAFE==2 ? "1" : "0", TCL_GLOBAL_ONLY); assert( sqlite3_threadsafe()==SQLITE_THREADSAFE ); #ifdef SQLITE_OMIT_TEMPDB diff --git a/test/memsubsys1.test b/test/memsubsys1.test index e9a4cf08a8..f0b060fc9f 100644 --- a/test/memsubsys1.test +++ b/test/memsubsys1.test @@ -100,10 +100,12 @@ reset_highwater_marks build_test_db memsubsys1-2 {PRAGMA page_size=1024; PRAGMA mmap_size=0} #show_memstats set MEMORY_MANAGEMENT $sqlite_options(memorymanage) -ifcapable !malloc_usable_size { - do_test memsubsys1-2.3 { - set pg_ovfl [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_OVERFLOW 0] 2] - } [expr ($TEMP_STORE>1 || $MEMORY_MANAGEMENT==0)*1024] +ifcapable pagecache_overflow_stats { + ifcapable !malloc_usable_size { + do_test memsubsys1-2.3 { + set pg_ovfl [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_OVERFLOW 0] 2] + } [expr ($TEMP_STORE>1 || $MEMORY_MANAGEMENT==0)*1024] + } } do_test memsubsys1-2.4 { set pg_used [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_USED 0] 2] diff --git a/test/mutex1.test b/test/mutex1.test index 340e271175..f567a0d930 100644 --- a/test/mutex1.test +++ b/test/mutex1.test @@ -97,7 +97,7 @@ do_test mutex1-1.9 { # * Multi-threaded mode, # * Single-threaded mode. # -ifcapable threadsafe&&shared_cache { +ifcapable threadsafe1&&shared_cache { set enable_shared_cache [sqlite3_enable_shared_cache 1] foreach {mode mutexes} { singlethread {} From 860443da10c8665304f30ed1c4a3b6718ca8855d Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 18 Mar 2016 00:39:40 +0000 Subject: [PATCH 0172/1484] Fix FTS5 so that it works with SQLITE_OMIT_AUTORESET. FossilOrigin-Name: b199637d81d7e2a767131ac03c7679b101fd459c --- ext/fts5/fts5_storage.c | 3 +-- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/ext/fts5/fts5_storage.c b/ext/fts5/fts5_storage.c index e4f5dd8f51..e052d03cd2 100644 --- a/ext/fts5/fts5_storage.c +++ b/ext/fts5/fts5_storage.c @@ -145,6 +145,7 @@ static int fts5StorageGetStmt( } *ppStmt = p->aStmt[eStmt]; + sqlite3_reset(*ppStmt); return rc; } @@ -1121,5 +1122,3 @@ int sqlite3Fts5StorageConfigValue( } return rc; } - - diff --git a/manifest b/manifest index 4447b95603..729634b431 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\smore\stest-case\serrors\sin\sthe\sApple\sconfiguration. -D 2016-03-18T00:19:48.288 +C Fix\sFTS5\sso\sthat\sit\sworks\swith\sSQLITE_OMIT_AUTORESET. +D 2016-03-18T00:39:40.456 F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66 @@ -106,7 +106,7 @@ F ext/fts5/fts5_expr.c 35e9d92c89e7c7ea0759b73d24da1ecb7630a24b F ext/fts5/fts5_hash.c f3a7217c86eb8f272871be5f6aa1b6798960a337 F ext/fts5/fts5_index.c d4f0c12e4f04bbc3a06b6da052039f2ce3e45438 F ext/fts5/fts5_main.c b8501e1a6a11591c53b18ce7aea7e5386cfb0421 -F ext/fts5/fts5_storage.c f8343db90d8c95a4d4b52f6676e354b4649ffd6e +F ext/fts5/fts5_storage.c 2a38c6fa5db193a6a00588865134450ef5812daa F ext/fts5/fts5_tcl.c f8731e0508299bd43f1a2eff7dbeaac870768966 F ext/fts5/fts5_test_mi.c 783b86697ebf773c18fc109992426c0173a055bc F ext/fts5/fts5_test_tok.c db08af63673c3a7d39f053b36fd6e065017706be @@ -1456,7 +1456,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 399c60764d3fdec49dab1745c30930ca1dbafe70 -R 6d659b59f432dac31e8bf0c8b3f7d1b0 +P 6631e1e655604a7d1fb45b4d151938d4a13b47f3 +R 472ca36ca6048890d22e3e80bb68c577 U drh -Z 34dc8dd8397892469013fc1a83c5fbd6 +Z 94c5a688910df424330581238168e35b diff --git a/manifest.uuid b/manifest.uuid index 03b3a4a5c6..d2044dd6ea 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6631e1e655604a7d1fb45b4d151938d4a13b47f3 \ No newline at end of file +b199637d81d7e2a767131ac03c7679b101fd459c \ No newline at end of file From fe485c0e56050c1963bc7b5a3599628a3fe45212 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 18 Mar 2016 10:29:47 +0000 Subject: [PATCH 0173/1484] Add tests for the changes on this branch. Fix a problem with calls to the new progress indicator API made after an rbu update has been resumed. FossilOrigin-Name: bf82321724d3b0feb51e26d9b76090e03cc3964a --- ext/rbu/rbuprogress.test | 198 ++++++++++++++++++++++----------------- ext/rbu/sqlite3rbu.c | 1 + manifest | 17 ++-- manifest.uuid | 2 +- 4 files changed, 120 insertions(+), 98 deletions(-) diff --git a/ext/rbu/rbuprogress.test b/ext/rbu/rbuprogress.test index 9fcd014065..005aec5b24 100644 --- a/ext/rbu/rbuprogress.test +++ b/ext/rbu/rbuprogress.test @@ -13,7 +13,6 @@ source [file join [file dirname [info script]] rbu_common.tcl] set ::testprefix rbuprogress - # Create a simple RBU database. That expects to write to a table: # # CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c); @@ -58,29 +57,51 @@ do_test 1.10 { } {SQLITE_DONE} #------------------------------------------------------------------------- - -proc do_sp_test {tn target rbu reslist} { +# +proc do_sp_test {tn bReopen target rbu reslist} { uplevel [list do_test $tn [subst -nocommands { - sqlite3rbu rbu $target $rbu + if {$bReopen==0} { sqlite3rbu rbu $target $rbu } set res [list] while 1 { + if {$bReopen} { sqlite3rbu rbu $target $rbu } set rc [rbu step] if {[set rc] != "SQLITE_OK"} { error "error 1" } lappend res [lindex [rbu stage_progress] 0] if {[lindex [set res] end]==10000} break + if {$bReopen} { rbu close } } if {[set res] != [list $reslist]} { - error "reslist is incorrect (expect=$reslist got=[set res])" + error "1. reslist incorrect (expect=$reslist got=[set res])" } # One step to clean up the temporary tables used to update the only # target table in the rbu database. And one more to move the *-oal - # file to *-wal. + # file to *-wal. After each of these steps, the progress remains + # at "10000 0". + # rbu step + set res [rbu stage_progress] + if {[set res] != [list 10000 0]} { + error "2. reslist incorrect (expect=10000 0 got=[set res])" + } rbu step + set res [rbu stage_progress] + if {[set res] != [list 10000 0]} { + error "3. reslist incorrect (expect=10000 0 got=[set res])" + } # Do the checkpoint. - while {[rbu step]=="SQLITE_OK"} { } + while {[rbu step]=="SQLITE_OK"} { + foreach {a b} [rbu stage_progress] {} + if {[set a]!=10000 || [set b]<=0 || [set b]>10000} { + error "4. reslist incorrect (expect=10000 1..10000 got=[set a] [set b])" + } + } + + set res [rbu stage_progress] + if {[set res] != [list 10000 10000]} { + error "5. reslist is incorrect (expect=10000 10000 got=[set res])" + } rbu close }] {SQLITE_DONE}] @@ -93,87 +114,90 @@ proc create_db_file {filename sql} { tmpdb close } -reset_db -do_test 2.1.0 { - execsql { - CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c); - } - create_db_file rbu.db { - CREATE TABLE data_t1(a, b, c, rbu_control); - INSERT INTO data_t1 VALUES(4, 4, 4, 0); - INSERT INTO data_t1 VALUES(5, 5, 5, 0); +foreach {bReopen} { 0 1 } { - CREATE TABLE rbu_count(tbl, cnt); - INSERT INTO rbu_count VALUES('data_t1', 2); - } -} {} -do_sp_test 2.1.1 test.db rbu.db {5000 10000} - -reset_db -do_test 2.2.0 { - execsql { CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c) } - create_rbu1 rbu.db -} {rbu.db} -do_sp_test 2.2.1 test.db rbu.db {3333 6666 10000} - -reset_db -do_test 2.3.0 { - execsql { - CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c); - CREATE INDEX i1 ON t1(b); - INSERT INTO t1 VALUES(1, 1, 1); - INSERT INTO t1 VALUES(2, 2, 2); - INSERT INTO t1 VALUES(3, 3, 3); - } - create_db_file rbu.db { - CREATE TABLE data_t1(a, b, c, rbu_control); - INSERT INTO data_t1 VALUES(4, 4, 4, 0); - INSERT INTO data_t1 VALUES(2, NULL, NULL, 1); - INSERT INTO data_t1 VALUES(5, NULL, NULL, 1); - - CREATE TABLE rbu_count(tbl, cnt); - INSERT INTO rbu_count VALUES('data_t1', 3); - } -} {} -do_sp_test 2.3.1 test.db rbu.db {1666 3333 6000 8000 10000} - -reset_db -do_test 2.4.0 { - execsql { - CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c); - CREATE INDEX i1 ON t1(b); - INSERT INTO t1 VALUES(1, 1, 1); - INSERT INTO t1 VALUES(2, 2, 2); - INSERT INTO t1 VALUES(3, 3, 3); - } - create_db_file rbu.db { - CREATE TABLE data_t1(a, b, c, rbu_control); - INSERT INTO data_t1 VALUES(2, 4, 4, '.xx'); - - CREATE TABLE rbu_count(tbl, cnt); - INSERT INTO rbu_count VALUES('data_t1', 1); - } -} {} -do_sp_test 2.4.1 test.db rbu.db {3333 6666 10000} - -reset_db -do_test 2.5.0 { - execsql { - CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c); - CREATE INDEX i1 ON t1(b); - INSERT INTO t1 VALUES(1, 1, 1); - INSERT INTO t1 VALUES(2, 2, 2); - INSERT INTO t1 VALUES(3, 3, 3); - } - create_db_file rbu.db { - CREATE TABLE data_t1(a, b, c, rbu_control); - INSERT INTO data_t1 VALUES(4, NULL, 4, '.xx'); - - CREATE TABLE rbu_count(tbl, cnt); - INSERT INTO rbu_count VALUES('data_t1', 1); - } -} {} -do_sp_test 2.5.1 test.db rbu.db {10000} + reset_db + do_test 2.$bReopen.1.0 { + execsql { + CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c); + } + create_db_file rbu.db { + CREATE TABLE data_t1(a, b, c, rbu_control); + INSERT INTO data_t1 VALUES(4, 4, 4, 0); + INSERT INTO data_t1 VALUES(5, 5, 5, 0); + + CREATE TABLE rbu_count(tbl, cnt); + INSERT INTO rbu_count VALUES('data_t1', 2); + } + } {} + do_sp_test 2.$bReopen.1.1 $bReopen test.db rbu.db {5000 10000} + + reset_db + do_test 2.$bReopen.2.0 { + execsql { CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c) } + create_rbu1 rbu.db + } {rbu.db} + do_sp_test 2.$bReopen.2.1 $bReopen test.db rbu.db {3333 6666 10000} + + reset_db + do_test 2.$bReopen.3.0 { + execsql { + CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c); + CREATE INDEX i1 ON t1(b); + INSERT INTO t1 VALUES(1, 1, 1); + INSERT INTO t1 VALUES(2, 2, 2); + INSERT INTO t1 VALUES(3, 3, 3); + } + create_db_file rbu.db { + CREATE TABLE data_t1(a, b, c, rbu_control); + INSERT INTO data_t1 VALUES(4, 4, 4, 0); + INSERT INTO data_t1 VALUES(2, NULL, NULL, 1); + INSERT INTO data_t1 VALUES(5, NULL, NULL, 1); + + CREATE TABLE rbu_count(tbl, cnt); + INSERT INTO rbu_count VALUES('data_t1', 3); + } + } {} + do_sp_test 2.$bReopen.3.1 $bReopen test.db rbu.db {1666 3333 6000 8000 10000} + + reset_db + do_test 2.$bReopen.4.0 { + execsql { + CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c); + CREATE INDEX i1 ON t1(b); + INSERT INTO t1 VALUES(1, 1, 1); + INSERT INTO t1 VALUES(2, 2, 2); + INSERT INTO t1 VALUES(3, 3, 3); + } + create_db_file rbu.db { + CREATE TABLE data_t1(a, b, c, rbu_control); + INSERT INTO data_t1 VALUES(2, 4, 4, '.xx'); + + CREATE TABLE rbu_count(tbl, cnt); + INSERT INTO rbu_count VALUES('data_t1', 1); + } + } {} + do_sp_test 2.$bReopen.4.1 $bReopen test.db rbu.db {3333 6666 10000} + + reset_db + do_test 2.$bReopen.5.0 { + execsql { + CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c); + CREATE INDEX i1 ON t1(b); + INSERT INTO t1 VALUES(1, 1, 1); + INSERT INTO t1 VALUES(2, 2, 2); + INSERT INTO t1 VALUES(3, 3, 3); + } + create_db_file rbu.db { + CREATE TABLE data_t1(a, b, c, rbu_control); + INSERT INTO data_t1 VALUES(4, NULL, 4, '.xx'); + + CREATE TABLE rbu_count(tbl, cnt); + INSERT INTO rbu_count VALUES('data_t1', 1); + } + } {} + do_sp_test 2.$bReopen.5.1 $bReopen test.db rbu.db {10000} +} finish_test diff --git a/ext/rbu/sqlite3rbu.c b/ext/rbu/sqlite3rbu.c index 31d462b2b7..4b2529bf34 100644 --- a/ext/rbu/sqlite3rbu.c +++ b/ext/rbu/sqlite3rbu.c @@ -3207,6 +3207,7 @@ sqlite3rbu *sqlite3rbu_open( p->eStage = RBU_STAGE_OAL; }else{ p->eStage = pState->eStage; + p->nPhaseOneStep = pState->nPhaseOneStep; } p->nProgress = pState->nProgress; p->iOalSz = pState->iOalSz; diff --git a/manifest b/manifest index e0a85e57cc..7cbf1886a9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\san\sAPI\sto\sindicate\sthe\spercentage\sprogress\sof\san\srbu\supdate. -D 2016-03-17T21:06:42.412 +C Add\stests\sfor\sthe\schanges\son\sthis\sbranch.\sFix\sa\sproblem\swith\scalls\sto\sthe\snew\sprogress\sindicator\sAPI\smade\safter\san\srbu\supdate\shas\sbeen\sresumed. +D 2016-03-18T10:29:47.529 F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66 @@ -242,9 +242,9 @@ F ext/rbu/rbudiff.test 6cc806dc36389292f2a8f5842d0103721df4a07d F ext/rbu/rbufault.test cc0be8d5d392d98b0c2d6a51be377ea989250a89 F ext/rbu/rbufault2.test 9a7f19edd6ea35c4c9f807d8a3db0a03a5670c06 F ext/rbu/rbufts.test 828cd689da825f0a7b7c53ffc1f6f7fdb6fa5bda -F ext/rbu/rbuprogress.test d63b70f838a20422dce6445bcaed10890e506d02 +F ext/rbu/rbuprogress.test c4a9b3262bc0cafbf19709b56fbda0c3a9e69ac2 F ext/rbu/rbusave.test 0f43b6686084f426ddd040b878426452fd2c2f48 -F ext/rbu/sqlite3rbu.c 9bcf35b2f1d8eaf1c82b47bead114b2289ea06c6 +F ext/rbu/sqlite3rbu.c c89f1e59eb09257e126d2cdcb3c5588e16a44fee F ext/rbu/sqlite3rbu.h f8ee94f95fc80a35b7cb7ef3f2f5ea740b662477 F ext/rbu/test_rbu.c 5b6d31af188193d929234d1cd08ee967df092f66 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 @@ -1457,10 +1457,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 97b0e88cc7c3d677217d0bfab4cb4a34a4abb238 -R 9de86de419de6ede9128347e06885dfc -T *branch * rbu-percent-progress -T *sym-rbu-percent-progress * -T -sym-trunk * +P ffc58d2c2576a5b6e1c2c7112612c5760e711afd +R b5c08658920cbd4a66ad9300ad32e622 U dan -Z f4146c58d33c341586c7f6e824f90dbe +Z 25ebcfe6c5065c93d73006dcdc7ea2c0 diff --git a/manifest.uuid b/manifest.uuid index ca52cccd3f..a1b8da46e4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ffc58d2c2576a5b6e1c2c7112612c5760e711afd \ No newline at end of file +bf82321724d3b0feb51e26d9b76090e03cc3964a \ No newline at end of file From 789780d8f6cd1c770ef8f39aed0ccd2a2f37d14b Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 18 Mar 2016 18:56:45 +0000 Subject: [PATCH 0174/1484] Change the name of the new API on this branch to "sqlite3_bp_progress". Add tests and documentation for the same. FossilOrigin-Name: 1a1b69e87eb7d18f76f5b733e44da75136a686b6 --- ext/rbu/rbuprogress.test | 145 +++++++++++++++++++++++++++++++-------- ext/rbu/sqlite3rbu.c | 49 ++++++++++++- ext/rbu/sqlite3rbu.h | 42 +++++++++++- ext/rbu/test_rbu.c | 6 +- manifest | 18 ++--- manifest.uuid | 2 +- 6 files changed, 217 insertions(+), 45 deletions(-) diff --git a/ext/rbu/rbuprogress.test b/ext/rbu/rbuprogress.test index 005aec5b24..8459bc09e0 100644 --- a/ext/rbu/rbuprogress.test +++ b/ext/rbu/rbuprogress.test @@ -13,14 +13,20 @@ source [file join [file dirname [info script]] rbu_common.tcl] set ::testprefix rbuprogress + +proc create_db_file {filename sql} { + forcedelete $filename + sqlite3 tmpdb $filename + tmpdb eval $sql + tmpdb close +} + # Create a simple RBU database. That expects to write to a table: # # CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c); # proc create_rbu1 {filename} { - forcedelete $filename - sqlite3 rbu1 $filename - rbu1 eval { + create_db_file $filename { CREATE TABLE data_t1(a, b, c, rbu_control); INSERT INTO data_t1 VALUES(1, 2, 3, 0); INSERT INTO data_t1 VALUES(2, 'two', 'three', 0); @@ -29,7 +35,6 @@ proc create_rbu1 {filename} { CREATE TABLE rbu_count(tbl, cnt); INSERT INTO rbu_count VALUES('data_t1', 3); } - rbu1 close return $filename } @@ -41,16 +46,16 @@ do_execsql_test 1.0 { do_test 1.1 { create_rbu1 rbu.db sqlite3rbu rbu test.db rbu.db - rbu stage_progress + rbu bp_progress } {0 0} -do_test 1.2 { rbu step ; rbu stage_progress } {3333 0} -do_test 1.3 { rbu step ; rbu stage_progress } {6666 0} -do_test 1.4 { rbu step ; rbu stage_progress } {10000 0} -do_test 1.5 { rbu step ; rbu stage_progress } {10000 0} -do_test 1.6 { rbu step ; rbu stage_progress } {10000 0} -do_test 1.7 { rbu step ; rbu stage_progress } {10000 5000} -do_test 1.8 { rbu step ; rbu stage_progress } {10000 10000} -do_test 1.9 { rbu step ; rbu stage_progress } {10000 10000} +do_test 1.2 { rbu step ; rbu bp_progress } {3333 0} +do_test 1.3 { rbu step ; rbu bp_progress } {6666 0} +do_test 1.4 { rbu step ; rbu bp_progress } {10000 0} +do_test 1.5 { rbu step ; rbu bp_progress } {10000 0} +do_test 1.6 { rbu step ; rbu bp_progress } {10000 0} +do_test 1.7 { rbu step ; rbu bp_progress } {10000 5000} +do_test 1.8 { rbu step ; rbu bp_progress } {10000 10000} +do_test 1.9 { rbu step ; rbu bp_progress } {10000 10000} do_test 1.10 { rbu close @@ -66,7 +71,7 @@ proc do_sp_test {tn bReopen target rbu reslist} { if {$bReopen} { sqlite3rbu rbu $target $rbu } set rc [rbu step] if {[set rc] != "SQLITE_OK"} { error "error 1" } - lappend res [lindex [rbu stage_progress] 0] + lappend res [lindex [rbu bp_progress] 0] if {[lindex [set res] end]==10000} break if {$bReopen} { rbu close } } @@ -79,26 +84,29 @@ proc do_sp_test {tn bReopen target rbu reslist} { # file to *-wal. After each of these steps, the progress remains # at "10000 0". # - rbu step - set res [rbu stage_progress] - if {[set res] != [list 10000 0]} { - error "2. reslist incorrect (expect=10000 0 got=[set res])" + if {[lindex [list $reslist] 0]!=-1} { + rbu step + set res [rbu bp_progress] + if {[set res] != [list 10000 0]} { + error "2. reslist incorrect (expect=10000 0 got=[set res])" + } } + rbu step - set res [rbu stage_progress] + set res [rbu bp_progress] if {[set res] != [list 10000 0]} { error "3. reslist incorrect (expect=10000 0 got=[set res])" } # Do the checkpoint. while {[rbu step]=="SQLITE_OK"} { - foreach {a b} [rbu stage_progress] {} + foreach {a b} [rbu bp_progress] {} if {[set a]!=10000 || [set b]<=0 || [set b]>10000} { error "4. reslist incorrect (expect=10000 1..10000 got=[set a] [set b])" } } - set res [rbu stage_progress] + set res [rbu bp_progress] if {[set res] != [list 10000 10000]} { error "5. reslist is incorrect (expect=10000 10000 got=[set res])" } @@ -107,13 +115,6 @@ proc do_sp_test {tn bReopen target rbu reslist} { }] {SQLITE_DONE}] } -proc create_db_file {filename sql} { - forcedelete $filename - sqlite3 tmpdb $filename - tmpdb eval $sql - tmpdb close -} - foreach {bReopen} { 0 1 } { reset_db @@ -197,7 +198,95 @@ foreach {bReopen} { 0 1 } { } } {} do_sp_test 2.$bReopen.5.1 $bReopen test.db rbu.db {10000} + + reset_db + do_test 2.$bReopen.6.0 { + execsql { + CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c); + CREATE INDEX i1 ON t1(b); + INSERT INTO t1 VALUES(1, 1, 1); + INSERT INTO t1 VALUES(2, 2, 2); + INSERT INTO t1 VALUES(3, 3, 3); + } + create_db_file rbu.db { + CREATE TABLE data_t1(a, b, c, rbu_control); + INSERT INTO data_t1 VALUES(4, 4, 4, 0); + INSERT INTO data_t1 VALUES(2, NULL, NULL, 1); + INSERT INTO data_t1 VALUES(5, NULL, NULL, 1); + } + } {} + do_sp_test 2.$bReopen.6.1 $bReopen test.db rbu.db {-1 -1 -1 -1 -1 10000} } +#------------------------------------------------------------------------- +# The following tests verify that the API works when resuming an update +# during the incremental checkpoint stage. +# +proc do_phase2_test {tn bReopen target rbu nStep} { + uplevel [list do_test $tn [subst -nocommands { + + # Build the OAL/WAL file: + sqlite3rbu rbu $target $rbu + while {[lindex [rbu bp_progress] 0]<10000} { + set rc [rbu step] + if {"SQLITE_OK" != [set rc]} { rbu close } + } + + # Clean up the temp tables and move the *-oal file to *-wal. + rbu step + rbu step + + for {set i 0} {[set i] < $nStep} {incr i} { + if {$bReopen} { + rbu close + sqlite3rbu rbu $target $rbu + } + rbu step + set res [rbu bp_progress] + set expect [expr (1 + [set i]) * 10000 / $nStep] + if {[lindex [set res] 1] != [set expect]} { + error "Have [set res], expected 10000 [set expect]" + } + } + + set rc [rbu step] + if {[set rc] != "SQLITE_DONE"} { + error "Have [set rc], expected SQLITE_DONE" + } + + rbu close + }] {SQLITE_DONE}] +} + +foreach bReopen {0 1} { + do_test 3.$bReopen.1.0 { + reset_db + execsql { + CREATE TABLE t1(a INTEGER PRIMARY KEY, b); + CREATE TABLE t2(a INTEGER PRIMARY KEY, b); + CREATE TABLE t3(a INTEGER PRIMARY KEY, b); + CREATE TABLE t4(a INTEGER PRIMARY KEY, b); + } + create_db_file rbu.db { + CREATE TABLE data_t1(a, b, rbu_control); + CREATE TABLE data_t2(a, b, rbu_control); + CREATE TABLE data_t3(a, b, rbu_control); + CREATE TABLE data_t4(a, b, rbu_control); + INSERT INTO data_t1 VALUES(1, 2, 0); + INSERT INTO data_t2 VALUES(1, 2, 0); + INSERT INTO data_t3 VALUES(1, 2, 0); + INSERT INTO data_t4 VALUES(1, 2, 0); + + CREATE TABLE rbu_count(tbl, cnt); + INSERT INTO rbu_count VALUES('data_t1', 1); + INSERT INTO rbu_count VALUES('data_t2', 1); + INSERT INTO rbu_count VALUES('data_t3', 1); + INSERT INTO rbu_count VALUES('data_t4', 1); + } + } {} + do_phase2_test 3.$bReopen.1.1 $bReopen test.db rbu.db 5 +} + + finish_test diff --git a/ext/rbu/sqlite3rbu.c b/ext/rbu/sqlite3rbu.c index 4b2529bf34..ab7b983ead 100644 --- a/ext/rbu/sqlite3rbu.c +++ b/ext/rbu/sqlite3rbu.c @@ -300,6 +300,43 @@ struct RbuFrame { /* ** RBU handle. +** +** nPhaseOneStep: +** If the RBU database contains an rbu_count table, this value is set to +** a running estimate of the number of b-tree operations required to +** finish populating the *-oal file. This allows the sqlite3_bp_progress() +** API to calculate the permyriadage progress of populating the *-oal file +** using the formula: +** +** permyriadage = (10000 * nProgress) / nPhaseOneStep +** +** nPhaseOneStep is initialized to the sum of: +** +** nRow * (nIndex + 1) +** +** for all source tables in the RBU database, where nRow is the number +** of rows in the source table and nIndex the number of indexes on the +** corresponding target database table. +** +** This estimate is accurate if the RBU update consists entirely of +** INSERT operations. However, it is inaccurate if: +** +** * the RBU update contains any UPDATE operations. If the PK specified +** for an UPDATE operation does not exist in the target table, then +** no b-tree operations are required on index b-trees. Or if the +** specified PK does exist, then (nIndex*2) such operations are +** required (one delete and one insert on each index b-tree). +** +** * the RBU update contains any DELETE operations for which the specified +** PK does not exist. In this case no operations are required on index +** b-trees. +** +** * the RBU update contains REPLACE operations. These are similar to +** UPDATE operations. +** +** nPhaseOneStep is updated to account for the conditions above during the +** first pass of each source table. The updated nPhaseOneStep value is +** stored in the rbu_state table if the RBU update is suspended. */ struct sqlite3rbu { int eStage; /* Value of RBU_STATE_STAGE field */ @@ -2957,7 +2994,7 @@ static RbuState *rbuLoadState(sqlite3rbu *p){ break; case RBU_STATE_PHASEONESTEP: - pRet->nPhaseOneStep = (u32)sqlite3_column_int64(pStmt, 1); + pRet->nPhaseOneStep = sqlite3_column_int64(pStmt, 1); break; default: @@ -3068,7 +3105,9 @@ static void rbuDeleteVfs(sqlite3rbu *p){ } /* -** +** This user-defined SQL function is invoked with a single argument - the +** name of a table expected to appear in the target database. It returns +** the number of auxilliary indexes on the table. */ static void rbuIndexCntFunc( sqlite3_context *pCtx, @@ -3371,7 +3410,11 @@ sqlite3_int64 sqlite3rbu_progress(sqlite3rbu *pRbu){ return pRbu->nProgress; } -void sqlite3rbu_stage_progress(sqlite3rbu *p, int *pnOne, int *pnTwo){ +/* +** Return permyriadage progress indications for the two main stages of +** an RBU update. +*/ +void sqlite3rbu_bp_progress(sqlite3rbu *p, int *pnOne, int *pnTwo){ const int MAX_PROGRESS = 10000; switch( p->eStage ){ case RBU_STAGE_OAL: diff --git a/ext/rbu/sqlite3rbu.h b/ext/rbu/sqlite3rbu.h index fb81c85a0a..f379bb5b41 100644 --- a/ext/rbu/sqlite3rbu.h +++ b/ext/rbu/sqlite3rbu.h @@ -400,7 +400,47 @@ int sqlite3rbu_close(sqlite3rbu *pRbu, char **pzErrmsg); */ sqlite3_int64 sqlite3rbu_progress(sqlite3rbu *pRbu); -void sqlite3rbu_stage_progress(sqlite3rbu *pRbu, int *pnOne, int *pnTwo); +/* +** Obtain permyriadage (permyriadage is to 10000 as percentage is to 100) +** progress indications for the two stages of an RBU update. This API may +** be useful for driving GUI progress indicators and similar. +** +** An RBU update is divided into two stages: +** +** * Stage 1, in which changes are accumulated in an oal/wal file, and +** * Stage 2, in which the contents of the wal file are copied into the +** main database. +** +** The update is visible to non-RBU clients during stage 2. During stage 1 +** non-RBU reader clients may see the original database. +** +** If this API is called during stage 2 of the update, output variable +** (*pnOne) is set to 10000 to indicate that stage 1 has finished and (*pnTwo) +** to a value between 0 and 10000 to indicate the permyriadage progress of +** stage 2. A value of 5000 indicates that stage 2 is half finished, +** 9000 indicates that it is 90% finished, and so on. +** +** If this API is called during stage 1 of the update, output variable +** (*pnTwo) is set to 0 to indicate that stage 2 has not yet started. The +** value to which (*pnOne) is set depends on whether or not the RBU +** database contains an "rbu_count" table. The rbu_count table, if it +** exists, must contain the same columns as the following: +** +** CREATE TABLE rbu_count(tbl TEXT PRIMARY KEY, cnt INTEGER) WITHOUT ROWID; +** +** There must be one row in the table for each source (data_xxx) table within +** the RBU database. The 'tbl' column should contain the name of the source +** table. The 'cnt' column should contain the number of rows within the +** source table. +** +** If the rbu_count table is present and populated correctly and this +** API is called during stage 1, the *pnOne output variable is set to the +** permyriadage progress of the same stage. If the rbu_count table does +** not exist, then (*pnOne) is set to -1 during stage 1. If the rbu_count +** table exists but is not correctly populated, the value of the *pnOne +** output variable during stage 1 is undefined. +*/ +void sqlite3rbu_bp_progress(sqlite3rbu *pRbu, int *pnOne, int *pnTwo); /* ** Create an RBU VFS named zName that accesses the underlying file-system diff --git a/ext/rbu/test_rbu.c b/ext/rbu/test_rbu.c index e35d76e745..5e8640a9f8 100644 --- a/ext/rbu/test_rbu.c +++ b/ext/rbu/test_rbu.c @@ -66,7 +66,7 @@ static int test_sqlite3rbu_cmd( {"create_rbu_delta", 2, ""}, /* 2 */ {"savestate", 2, ""}, /* 3 */ {"dbMain_eval", 3, "SQL"}, /* 4 */ - {"stage_progress", 2, ""}, /* 5 */ + {"bp_progress", 2, ""}, /* 5 */ {0,0,0} }; int iCmd; @@ -137,10 +137,10 @@ static int test_sqlite3rbu_cmd( break; } - case 5: /* stage_progress */ { + case 5: /* bp_progress */ { int one, two; Tcl_Obj *pObj; - sqlite3rbu_stage_progress(pRbu, &one, &two); + sqlite3rbu_bp_progress(pRbu, &one, &two); pObj = Tcl_NewObj(); Tcl_ListObjAppendElement(interp, pObj, Tcl_NewIntObj(one)); diff --git a/manifest b/manifest index 7cbf1886a9..106d447afa 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\stests\sfor\sthe\schanges\son\sthis\sbranch.\sFix\sa\sproblem\swith\scalls\sto\sthe\snew\sprogress\sindicator\sAPI\smade\safter\san\srbu\supdate\shas\sbeen\sresumed. -D 2016-03-18T10:29:47.529 +C Change\sthe\sname\sof\sthe\snew\sAPI\son\sthis\sbranch\sto\s"sqlite3_bp_progress".\sAdd\stests\sand\sdocumentation\sfor\sthe\ssame. +D 2016-03-18T18:56:45.343 F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66 @@ -242,11 +242,11 @@ F ext/rbu/rbudiff.test 6cc806dc36389292f2a8f5842d0103721df4a07d F ext/rbu/rbufault.test cc0be8d5d392d98b0c2d6a51be377ea989250a89 F ext/rbu/rbufault2.test 9a7f19edd6ea35c4c9f807d8a3db0a03a5670c06 F ext/rbu/rbufts.test 828cd689da825f0a7b7c53ffc1f6f7fdb6fa5bda -F ext/rbu/rbuprogress.test c4a9b3262bc0cafbf19709b56fbda0c3a9e69ac2 +F ext/rbu/rbuprogress.test 77fe3cd10d3c408bef364bc2e529310495ddd07e F ext/rbu/rbusave.test 0f43b6686084f426ddd040b878426452fd2c2f48 -F ext/rbu/sqlite3rbu.c c89f1e59eb09257e126d2cdcb3c5588e16a44fee -F ext/rbu/sqlite3rbu.h f8ee94f95fc80a35b7cb7ef3f2f5ea740b662477 -F ext/rbu/test_rbu.c 5b6d31af188193d929234d1cd08ee967df092f66 +F ext/rbu/sqlite3rbu.c 6b7dc899b3980d4236bffa5048218f8dba85ac0a +F ext/rbu/sqlite3rbu.h d7cc99350c10134f358fe1a8997d9225b3f712b2 +F ext/rbu/test_rbu.c 3505641a78b723589b8780d5f9b2faeeb73e037d F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 F ext/rtree/rtree.c 0b870ccb7b58b734a2a8e1e2755a7c0ded070920 F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e @@ -1457,7 +1457,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ffc58d2c2576a5b6e1c2c7112612c5760e711afd -R b5c08658920cbd4a66ad9300ad32e622 +P bf82321724d3b0feb51e26d9b76090e03cc3964a +R 14faa32cca0db38c921d7bc3da7dea4c U dan -Z 25ebcfe6c5065c93d73006dcdc7ea2c0 +Z 40a2b2dbafc34d98f3493240ec44ac36 diff --git a/manifest.uuid b/manifest.uuid index a1b8da46e4..d6c18684be 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bf82321724d3b0feb51e26d9b76090e03cc3964a \ No newline at end of file +1a1b69e87eb7d18f76f5b733e44da75136a686b6 \ No newline at end of file From eea627da9e35aec681f8f7c54e933668a5f238bc Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 18 Mar 2016 20:12:28 +0000 Subject: [PATCH 0175/1484] Add further tests for sqlite3rbu_bp_progress(). Fix a problem in handling WITHOUT ROWID tables in the same. FossilOrigin-Name: 65e02368e2b6cec349ea71af5a456d6783b0d15e --- ext/rbu/rbuprogress.test | 117 ++++++++++++++++++++++++++++++++++++++- ext/rbu/sqlite3rbu.c | 13 ++++- manifest | 14 ++--- manifest.uuid | 2 +- 4 files changed, 133 insertions(+), 13 deletions(-) diff --git a/ext/rbu/rbuprogress.test b/ext/rbu/rbuprogress.test index 8459bc09e0..6e6c7faf61 100644 --- a/ext/rbu/rbuprogress.test +++ b/ext/rbu/rbuprogress.test @@ -70,12 +70,13 @@ proc do_sp_test {tn bReopen target rbu reslist} { while 1 { if {$bReopen} { sqlite3rbu rbu $target $rbu } set rc [rbu step] - if {[set rc] != "SQLITE_OK"} { error "error 1" } + if {[set rc] != "SQLITE_OK"} { rbu close ; error "error 1" } lappend res [lindex [rbu bp_progress] 0] if {[lindex [set res] end]==10000} break if {$bReopen} { rbu close } } if {[set res] != [list $reslist]} { + rbu close error "1. reslist incorrect (expect=$reslist got=[set res])" } @@ -88,6 +89,7 @@ proc do_sp_test {tn bReopen target rbu reslist} { rbu step set res [rbu bp_progress] if {[set res] != [list 10000 0]} { + rbu close error "2. reslist incorrect (expect=10000 0 got=[set res])" } } @@ -95,6 +97,7 @@ proc do_sp_test {tn bReopen target rbu reslist} { rbu step set res [rbu bp_progress] if {[set res] != [list 10000 0]} { + rbu close error "3. reslist incorrect (expect=10000 0 got=[set res])" } @@ -102,12 +105,14 @@ proc do_sp_test {tn bReopen target rbu reslist} { while {[rbu step]=="SQLITE_OK"} { foreach {a b} [rbu bp_progress] {} if {[set a]!=10000 || [set b]<=0 || [set b]>10000} { + rbu close error "4. reslist incorrect (expect=10000 1..10000 got=[set a] [set b])" } } set res [rbu bp_progress] if {[set res] != [list 10000 10000]} { + rbu close error "5. reslist is incorrect (expect=10000 10000 got=[set res])" } @@ -116,7 +121,6 @@ proc do_sp_test {tn bReopen target rbu reslist} { } foreach {bReopen} { 0 1 } { - reset_db do_test 2.$bReopen.1.0 { execsql { @@ -288,5 +292,114 @@ foreach bReopen {0 1} { } +foreach {bReopen} { 0 1 } { + foreach {tn tbl} { + ipk { CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c) } + wr { CREATE TABLE t1(a INT PRIMARY KEY, b, c) WITHOUT ROWID } + pk { CREATE TABLE t1(a INT PRIMARY KEY, b, c) } + } { + + foreach {tn2 rbusql r1 r3} { + 1 { + CREATE TABLE data0_t1(a, b, c, rbu_control); + INSERT INTO data0_t1 VALUES(15, 15, 15, 0); + INSERT INTO data0_t1 VALUES(20, 20, 20, 0); + CREATE TABLE rbu_count(tbl, cnt); + INSERT INTO rbu_count VALUES('data0_t1', 2); + } + {2500 5000 7500 10000} + {1666 3333 5000 6666 8333 10000} + + 2 { + CREATE TABLE data0_t1(a, b, c, rbu_control); + INSERT INTO data0_t1 VALUES(10, 10, 10, 2); + CREATE TABLE rbu_count(tbl, cnt); + INSERT INTO rbu_count VALUES('data0_t1', 1); + } + {3333 6666 10000} + {2000 4000 6000 8000 10000} + + 3 { + CREATE TABLE data0_t1(a, b, c, rbu_control); + INSERT INTO data0_t1 VALUES(7, 7, 7, 2); + INSERT INTO data0_t1 VALUES(10, 10, 10, 2); + CREATE TABLE rbu_count(tbl, cnt); + INSERT INTO rbu_count VALUES('data0_t1', 2); + } + {2500 4000 6000 8000 10000} + {1666 2500 3750 5000 6250 7500 8750 10000} + + } { + + reset_db ; execsql $tbl + do_test 4.$tn.$bReopen.$tn2.0 { + execsql { + CREATE INDEX t1c ON t1(c); + INSERT INTO t1 VALUES(1, 1, 1); + INSERT INTO t1 VALUES(5, 5, 5); + INSERT INTO t1 VALUES(10, 10, 10); + } + create_db_file rbu.db $rbusql + } {} + + set R(ipk) $r1 + set R(wr) $r1 + set R(pk) $r3 + do_sp_test 4.$tn.$bReopen.$tn2.1 $bReopen test.db rbu.db $R($tn) + } + } +} + +foreach {bReopen} { 0 1 } { + foreach {tn tbl} { + nopk { + CREATE TABLE t1(a, b, c); + CREATE INDEX t1c ON t1(c); + } + vtab { + CREATE VIRTUAL TABLE t1 USING fts5(a, b, c); + } + } { + + foreach {tn2 rbusql r1 r2} { + 1 { + CREATE TABLE data0_t1(a, b, c, rbu_rowid, rbu_control); + INSERT INTO data0_t1 VALUES(15, 15, 15, 4, 0); + INSERT INTO data0_t1 VALUES(20, 20, 20, 5, 0); + CREATE TABLE rbu_count(tbl, cnt); + INSERT INTO rbu_count VALUES('data0_t1', 2); + } + {2500 5000 7500 10000} + {5000 10000} + + 2 { + CREATE TABLE data0_t1(rbu_rowid, a, b, c, rbu_control); + INSERT INTO data0_t1 VALUES(0, 7, 7, 7, 2); + INSERT INTO data0_t1 VALUES(2, 10, 10, 10, 2); + CREATE TABLE rbu_count(tbl, cnt); + INSERT INTO rbu_count VALUES('data0_t1', 2); + } + {2500 4000 6000 8000 10000} + {5000 10000} + } { + + reset_db ; execsql $tbl + do_test 5.$tn.$bReopen.$tn2.0 { + execsql { + INSERT INTO t1 VALUES(1, 1, 1); + INSERT INTO t1 VALUES(5, 5, 5); + INSERT INTO t1 VALUES(10, 10, 10); + } + create_db_file rbu.db $rbusql + } {} + + set R(nopk) $r1 + set R(vtab) $r2 + do_sp_test 5.$tn.$bReopen.$tn2.1 $bReopen test.db rbu.db $R($tn) + } + } +} + + finish_test diff --git a/ext/rbu/sqlite3rbu.c b/ext/rbu/sqlite3rbu.c index ab7b983ead..b587d2bb20 100644 --- a/ext/rbu/sqlite3rbu.c +++ b/ext/rbu/sqlite3rbu.c @@ -1202,6 +1202,11 @@ static void rbuObjIterCacheIndexedCols(sqlite3rbu *p, RbuObjIter *pIter){ pIter->nIndex++; } + if( pIter->eType==RBU_PK_WITHOUT_ROWID ){ + /* "PRAGMA index_list" includes the main PK b-tree */ + pIter->nIndex--; + } + rbuFinalize(p, pList); if( bIndex==0 ) pIter->abIndexed = 0; } @@ -1313,6 +1318,7 @@ static int rbuObjIterCacheTableInfo(sqlite3rbu *p, RbuObjIter *pIter){ rbuFinalize(p, pStmt); rbuObjIterCacheIndexedCols(p, pIter); assert( pIter->eType!=RBU_PK_VTAB || pIter->abIndexed==0 ); + assert( pIter->eType!=RBU_PK_VTAB || pIter->nIndex==0 ); } return p->rc; @@ -3122,14 +3128,15 @@ static void rbuIndexCntFunc( assert( nVal==1 ); rc = prepareFreeAndCollectError(p->dbMain, &pStmt, &zErrmsg, - sqlite3_mprintf("PRAGMA index_list = %Q", sqlite3_value_text(apVal[0])) + sqlite3_mprintf("SELECT count(*) FROM sqlite_master " + "WHERE type='index' AND tbl_name = %Q", sqlite3_value_text(apVal[0])) ); if( rc!=SQLITE_OK ){ sqlite3_result_error(pCtx, zErrmsg, -1); }else{ int nIndex = 0; - while( SQLITE_ROW==sqlite3_step(pStmt) ){ - nIndex++; + if( SQLITE_ROW==sqlite3_step(pStmt) ){ + nIndex = sqlite3_column_int(pStmt, 0); } rc = sqlite3_finalize(pStmt); if( rc==SQLITE_OK ){ diff --git a/manifest b/manifest index 106d447afa..ec9f64957f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sthe\sname\sof\sthe\snew\sAPI\son\sthis\sbranch\sto\s"sqlite3_bp_progress".\sAdd\stests\sand\sdocumentation\sfor\sthe\ssame. -D 2016-03-18T18:56:45.343 +C Add\sfurther\stests\sfor\ssqlite3rbu_bp_progress().\sFix\sa\sproblem\sin\shandling\sWITHOUT\sROWID\stables\sin\sthe\ssame. +D 2016-03-18T20:12:28.661 F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66 @@ -242,9 +242,9 @@ F ext/rbu/rbudiff.test 6cc806dc36389292f2a8f5842d0103721df4a07d F ext/rbu/rbufault.test cc0be8d5d392d98b0c2d6a51be377ea989250a89 F ext/rbu/rbufault2.test 9a7f19edd6ea35c4c9f807d8a3db0a03a5670c06 F ext/rbu/rbufts.test 828cd689da825f0a7b7c53ffc1f6f7fdb6fa5bda -F ext/rbu/rbuprogress.test 77fe3cd10d3c408bef364bc2e529310495ddd07e +F ext/rbu/rbuprogress.test 9d2dfd82fc001f26997e36db256df31f2e19e133 F ext/rbu/rbusave.test 0f43b6686084f426ddd040b878426452fd2c2f48 -F ext/rbu/sqlite3rbu.c 6b7dc899b3980d4236bffa5048218f8dba85ac0a +F ext/rbu/sqlite3rbu.c edeb8f90a1bccc567438036e083123cec1403091 F ext/rbu/sqlite3rbu.h d7cc99350c10134f358fe1a8997d9225b3f712b2 F ext/rbu/test_rbu.c 3505641a78b723589b8780d5f9b2faeeb73e037d F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 @@ -1457,7 +1457,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P bf82321724d3b0feb51e26d9b76090e03cc3964a -R 14faa32cca0db38c921d7bc3da7dea4c +P 1a1b69e87eb7d18f76f5b733e44da75136a686b6 +R 4f2c92bc8e3f772f06e8b5d5663259fa U dan -Z 40a2b2dbafc34d98f3493240ec44ac36 +Z bf41c4bf32ca5beb18733d3a05925431 diff --git a/manifest.uuid b/manifest.uuid index d6c18684be..5b3c08d363 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1a1b69e87eb7d18f76f5b733e44da75136a686b6 \ No newline at end of file +65e02368e2b6cec349ea71af5a456d6783b0d15e \ No newline at end of file From bb9b5f26085b12a0800dcce9fd2d5e31e6ac72ba Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 19 Mar 2016 00:35:02 +0000 Subject: [PATCH 0176/1484] Fix a register allocation bug in the VDBE code generator for PRAGMA integrity_check; FossilOrigin-Name: 88439a866b3b16ad7c308ebe59198662a05e7eeb --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/expr.c | 23 +++++++++++++++++++++++ src/pragma.c | 10 +++++++--- src/sqliteInt.h | 3 +++ 5 files changed, 42 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 729634b431..828c368a4f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sFTS5\sso\sthat\sit\sworks\swith\sSQLITE_OMIT_AUTORESET. -D 2016-03-18T00:39:40.456 +C Fix\sa\sregister\sallocation\sbug\sin\sthe\sVDBE\scode\sgenerator\sfor\nPRAGMA\sintegrity_check; +D 2016-03-19T00:35:02.035 F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66 @@ -304,7 +304,7 @@ F src/ctime.c 60e135af364d777a9ab41c97e5e89cd224da6198 F src/date.c 0b73e681c11fca867fec554750c07fe0d4e417c1 F src/dbstat.c c845548d4346e606e2f2b7d2e714ace2b8a7dd1b F src/delete.c 48802aa3ee6339f576d074336d3ae1b5f40e240f -F src/expr.c f8137b7d3d3f2a991f9622e41d170e0adf0abc71 +F src/expr.c 289ffac5240b60fee0a824d3d5ab2d7bd2630c94 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 5cb42d9a59e2a590776fd3fc8ff6f61d40df3c6e F src/func.c 552d300265aed09eea21f68ac742a440550c0062 @@ -343,7 +343,7 @@ F src/parse.y 5ea8c81c5c41b27887f41b4a7e1c58470d7d3821 F src/pcache.c 647bb53a86b7bbcf55ad88089b3ea5a9170b90df F src/pcache.h 4d0ccaad264d360981ec5e6a2b596d6e85242545 F src/pcache1.c c40cdb93586e21b5dd826b5e671240bd91c26b05 -F src/pragma.c f0670909e915179fec47e17f72f14660995b8022 +F src/pragma.c e7e8f380efec6075a722822306435afc1eeca88a F src/pragma.h 64c78a648751b9f4f297276c4eb7507b14b4628c F src/prepare.c 22df6171aec1d86904ed2ad30c2348a5748aa04e F src/printf.c 63e6fb12bbe702dd664dc3703776c090383a5a26 @@ -355,7 +355,7 @@ F src/shell.c 5e0ab1e708dc294330ccd8230536e1801f60822e F src/sqlite.h.in 0235586b3fb639e85998d495c90f007657fd82af F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h dfbe62ffd95b99afe2140d8c35b180d11924072d -F src/sqliteInt.h 84c673f27b77dfbd367cb3ed1de8b6f3b73102dc +F src/sqliteInt.h 751ced73be8c449a75e075e0545cdd832ed3591e F src/sqliteLimit.h 7b28cf72cbd52f178bfc97ea266445e351f2cd24 F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 @@ -1456,7 +1456,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 6631e1e655604a7d1fb45b4d151938d4a13b47f3 -R 472ca36ca6048890d22e3e80bb68c577 +P b199637d81d7e2a767131ac03c7679b101fd459c +R aa6d8166f4985600b2fe26e199ff3347 U drh -Z 94c5a688910df424330581238168e35b +Z 34d82988bd3c2eee6ead07b5f4503f1c diff --git a/manifest.uuid b/manifest.uuid index d2044dd6ea..8f7a7e9b8d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b199637d81d7e2a767131ac03c7679b101fd459c \ No newline at end of file +88439a866b3b16ad7c308ebe59198662a05e7eeb \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 352edc5424..998c94f231 100644 --- a/src/expr.c +++ b/src/expr.c @@ -4251,3 +4251,26 @@ void sqlite3ClearTempRegCache(Parse *pParse){ pParse->nTempReg = 0; pParse->nRangeReg = 0; } + +/* +** Validate that no temporary register falls within the range of +** iFirst..iLast, inclusive. This routine is only call from within assert() +** statements. +*/ +#ifdef SQLITE_DEBUG +int sqlite3NoTempsInRange(Parse *pParse, int iFirst, int iLast){ + int i; + if( pParse->nRangeReg>0 + && pParse->iRangeReg+pParse->nRangeRegiRangeReg>=iFirst + ){ + return 0; + } + for(i=0; inTempReg; i++){ + if( pParse->aTempReg[i]>=iFirst && pParse->aTempReg[i]<=iLast ){ + return 0; + } + } + return 1; +} +#endif /* SQLITE_DEBUG */ diff --git a/src/pragma.c b/src/pragma.c index 54858afbf1..65c43ad1e5 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -1441,6 +1441,8 @@ void sqlite3Pragma( Hash *pTbls; int *aRoot; int cnt = 0; + int mxIdx = 0; + int nIdx; if( OMIT_TEMPDB && i==1 ) continue; if( iDb>=0 && i!=iDb ) continue; @@ -1462,7 +1464,8 @@ void sqlite3Pragma( Table *pTab = sqliteHashData(x); Index *pIdx; if( HasRowid(pTab) ) cnt++; - for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ cnt++; } + for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){ cnt++; } + if( nIdx>mxIdx ) mxIdx = nIdx; } aRoot = sqlite3DbMallocRawNN(db, sizeof(int)*(cnt+1)); if( aRoot==0 ) break; @@ -1477,7 +1480,7 @@ void sqlite3Pragma( aRoot[cnt] = 0; /* Make sure sufficient number of registers have been allocated */ - pParse->nMem = MAX( pParse->nMem, 14 ); + pParse->nMem = MAX( pParse->nMem, 8+mxIdx ); /* Do the b-tree integrity checks */ sqlite3VdbeAddOp4(v, OP_IntegrityCk, 2, cnt, 1, (char*)aRoot,P4_INTARRAY); @@ -1514,7 +1517,8 @@ void sqlite3Pragma( for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ sqlite3VdbeAddOp2(v, OP_Integer, 0, 8+j); /* index entries counter */ } - pParse->nMem = MAX(pParse->nMem, 8+j); + assert( pParse->nMem>=8+j ); + assert( sqlite3NoTempsInRange(pParse,1,7+j) ); sqlite3VdbeAddOp2(v, OP_Rewind, iDataCur, 0); VdbeCoverage(v); loopTop = sqlite3VdbeAddOp2(v, OP_AddImm, 7, 1); /* Verify that all NOT NULL columns really are NOT NULL */ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index f2f485778a..3b97533090 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3419,6 +3419,9 @@ void sqlite3ReleaseTempReg(Parse*,int); int sqlite3GetTempRange(Parse*,int); void sqlite3ReleaseTempRange(Parse*,int,int); void sqlite3ClearTempRegCache(Parse*); +#ifdef SQLITE_DEBUG +int sqlite3NoTempsInRange(Parse*,int,int); +#endif Expr *sqlite3ExprAlloc(sqlite3*,int,const Token*,int); Expr *sqlite3Expr(sqlite3*,int,const char*); void sqlite3ExprAttachSubtrees(sqlite3*,Expr*,Expr*,Expr*); From cf9bce34ab757b637ebe36f04a7997dc5a1fc379 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 19 Mar 2016 14:47:28 +0000 Subject: [PATCH 0177/1484] Add test file fts5multiclient.test. FossilOrigin-Name: 7832466f9177cca59455ba272802145297fcd53d --- ext/fts5/test/fts5multiclient.test | 48 ++++++++++++++++++++++++++++++ manifest | 11 +++---- manifest.uuid | 2 +- 3 files changed, 55 insertions(+), 6 deletions(-) create mode 100644 ext/fts5/test/fts5multiclient.test diff --git a/ext/fts5/test/fts5multiclient.test b/ext/fts5/test/fts5multiclient.test new file mode 100644 index 0000000000..a1e9aa0d30 --- /dev/null +++ b/ext/fts5/test/fts5multiclient.test @@ -0,0 +1,48 @@ +# 2016 March 17 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#************************************************************************* +# + +source [file join [file dirname [info script]] fts5_common.tcl] +source $testdir/lock_common.tcl + +set testprefix fts5multiclient +return_if_no_fts5 + +foreach_detail_mode $testprefix { + +do_multiclient_test tn { + + do_test 1.$tn.1 { + sql1 { CREATE VIRTUAL TABLE t1 USING fts5(x, detail=%DETAIL%) } + sql1 { INSERT INTO t1 VALUES('a b c') } + sql2 { SELECT rowid FROM t1('b') } + } {1} + + do_test 1.$tn.2 { + sql2 { INSERT INTO t1 VALUES('a b c') } + sql1 { SELECT rowid FROM t1('b') } + } {1 2} + + do_test 1.$tn.3 { + sql2 { INSERT INTO t1 VALUES('a b c') } + sql1 { SELECT rowid FROM t1('b') } + } {1 2 3} + + do_test 1.$tn.4 { + sql2 { INSERT INTO t1 VALUES('a b c') } + sql1 { INSERT INTO t1 VALUES('a b c') } + sql3 { INSERT INTO t1(t1) VALUES('integrity-check') } + } {} + +};# do_multiclient_test +};# foreach_detail_mode +finish_test + diff --git a/manifest b/manifest index 8f5bdc1491..346832e33f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\ssome\sOOM-handling\sissues\sin\sthe\sfts5\schanges\son\sthis\sbranch. -D 2016-03-17T12:39:56.371 +C Add\stest\sfile\sfts5multiclient.test. +D 2016-03-19T14:47:28.441 F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66 @@ -165,6 +165,7 @@ F ext/fts5/test/fts5integrity.test f5e4f8d284385875068ad0f3e894ce43e9de835d F ext/fts5/test/fts5matchinfo.test f7dde99697bcb310ea8faa8eb2714d9f4dfc0e1b F ext/fts5/test/fts5merge.test 9f65f090d214ff865c56bef4f864aaa1182af6e3 F ext/fts5/test/fts5merge2.test a6da3c16d694235938d1939f503cfa53f0943d75 +F ext/fts5/test/fts5multiclient.test 5bd54a6bc8ff818be233a50a8dec93da99098f2a F ext/fts5/test/fts5near.test b214cddb1c1f1bddf45c75af768f20145f7e71cc F ext/fts5/test/fts5onepass.test 7ed9608e258132cb8d55e7c479b08676ad68810c F ext/fts5/test/fts5optimize.test 9d3ac53bb9cae58cb070d795db86bcb2f9fec105 @@ -1456,7 +1457,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 6c4a17b963916d19c9433d7a251338042f32e9fa -R bc1955b591517ca84e5bb3a7a87f0726 +P 020a0bda59fe93b9361ceeed0d5a8ba4177380c8 +R f14c9b8edfca8f7bf113e7bd0b21996b U dan -Z 380059b0b3811052efb55863df364c4f +Z d493def8e880a32e2aca451bc5e776cf diff --git a/manifest.uuid b/manifest.uuid index d6022948ee..91ed807a0b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -020a0bda59fe93b9361ceeed0d5a8ba4177380c8 \ No newline at end of file +7832466f9177cca59455ba272802145297fcd53d \ No newline at end of file From 1e8dae0e438a20211f619def9c5ce908a1787252 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 19 Mar 2016 14:53:36 +0000 Subject: [PATCH 0178/1484] Fix test scripts sqldiff.test and rbudiff.test so that they work with the --testdir option. FossilOrigin-Name: 1ffe3cde03f924bb8405a8729c8e1bc01f5b6d3b --- ext/rbu/rbudiff.test | 11 +---------- manifest | 18 +++++++++--------- manifest.uuid | 2 +- test/sqldiff1.test | 12 ++---------- test/tester.tcl | 27 ++++++++++++++++++++------- 5 files changed, 33 insertions(+), 37 deletions(-) diff --git a/ext/rbu/rbudiff.test b/ext/rbu/rbudiff.test index 10be9e0d53..0ebc0dad0f 100644 --- a/ext/rbu/rbudiff.test +++ b/ext/rbu/rbudiff.test @@ -18,16 +18,7 @@ if {![info exists testdir]} { source $testdir/tester.tcl set testprefix rbudiff -if {$tcl_platform(platform)=="windows"} { - set PROG "sqldiff.exe" -} else { - set PROG "./sqldiff" -} -if {![file exe $PROG]} { - puts "rbudiff.test cannot run because $PROG is not available" - finish_test - return -} +set PROG [test_find_sqldiff] db close proc get_rbudiff_sql {db1 db2} { diff --git a/manifest b/manifest index 828c368a4f..a56e5123a4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sregister\sallocation\sbug\sin\sthe\sVDBE\scode\sgenerator\sfor\nPRAGMA\sintegrity_check; -D 2016-03-19T00:35:02.035 +C Fix\stest\sscripts\ssqldiff.test\sand\srbudiff.test\sso\sthat\sthey\swork\swith\sthe\s--testdir\soption. +D 2016-03-19T14:53:36.705 F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66 @@ -238,7 +238,7 @@ F ext/rbu/rbuB.test c25bc325b8072a766e56bb76c001866b405925c2 F ext/rbu/rbuC.test efe47db508a0269b683cb2a1913a425ffd39a831 F ext/rbu/rbu_common.tcl 0398545fed614f807d5f0ba55a85a51f08ba8f1a F ext/rbu/rbucrash.test 8d2ed5d4b05fef6c00c2a6b5f7ead71fa172a695 -F ext/rbu/rbudiff.test 6cc806dc36389292f2a8f5842d0103721df4a07d +F ext/rbu/rbudiff.test 7f0fbf54912b9f8898819504c8465df12c970a00 F ext/rbu/rbufault.test cc0be8d5d392d98b0c2d6a51be377ea989250a89 F ext/rbu/rbufault2.test 9a7f19edd6ea35c4c9f807d8a3db0a03a5670c06 F ext/rbu/rbufts.test 828cd689da825f0a7b7c53ffc1f6f7fdb6fa5bda @@ -1061,7 +1061,7 @@ F test/speedtest1.c 1478cb3fb64ad30f291ddca87ca9dbd72ff552aa F test/spellfix.test f9c1f431e2c096c8775fec032952320c0e4700db F test/spellfix2.test dfc8f519a3fc204cb2dfa8b4f29821ae90f6f8c3 F test/spellfix3.test 0f9efaaa502a0e0a09848028518a6fb096c8ad33 -F test/sqldiff1.test 8f6bc7c6a5b3585d350d779c6078869ba402f8f5 +F test/sqldiff1.test 28cd737cf1b0078b1ec1bbf425e674c47785835e F test/sqllimits1.test a74ee2a3740b9f9c2437c246d8fb77354862a142 F test/sqllog.test 6af6cb0b09f4e44e1917e06ce85be7670302517a F test/stat.test b65bad7120c52583b8f0054d99eff80718119a77 @@ -1085,7 +1085,7 @@ F test/tclsqlite.test c6d9f546f79d15d0134c1e06583fb3ee0c3afad3 F test/tempdb.test bd92eba8f20e16a9136e434e20b280794de3cdb6 F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30 F test/temptrigger.test 8ec228b0db5d7ebc4ee9b458fc28cb9e7873f5e1 -F test/tester.tcl 859a7ccbe5bd65f0f8b524cd51c318d3edcd3008 +F test/tester.tcl d9831491ddc902ef62ef11438eca83ac0d4cf969 F test/thread001.test 9f22fd3525a307ff42a326b6bc7b0465be1745a5 F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58 F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7 @@ -1456,7 +1456,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b199637d81d7e2a767131ac03c7679b101fd459c -R aa6d8166f4985600b2fe26e199ff3347 -U drh -Z 34d82988bd3c2eee6ead07b5f4503f1c +P 88439a866b3b16ad7c308ebe59198662a05e7eeb +R 3b6913cf00d6ce7b8c04137012202e6b +U dan +Z d63e42a30b9cbf754c53eb2c6783a9e9 diff --git a/manifest.uuid b/manifest.uuid index 8f7a7e9b8d..0bf3c490c2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -88439a866b3b16ad7c308ebe59198662a05e7eeb \ No newline at end of file +1ffe3cde03f924bb8405a8729c8e1bc01f5b6d3b \ No newline at end of file diff --git a/test/sqldiff1.test b/test/sqldiff1.test index 3201fb3654..ea4e1f9993 100644 --- a/test/sqldiff1.test +++ b/test/sqldiff1.test @@ -14,16 +14,8 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl -if {$tcl_platform(platform)=="windows"} { - set PROG "sqldiff.exe" -} else { - set PROG "./sqldiff" -} -if {![file exe $PROG]} { - puts "sqldiff cannot run because $PROG is not available" - finish_test - return -} +set PROG [test_find_sqldiff] + db close forcedelete test.db test2.db sqlite3 db test.db diff --git a/test/tester.tcl b/test/tester.tcl index 1c83e34c0d..065acc37be 100644 --- a/test/tester.tcl +++ b/test/tester.tcl @@ -2136,15 +2136,11 @@ proc test_restore_config_pagecache {} { sqlite3 db test.db } -# Find the name of the 'shell' executable (e.g. "sqlite3.exe") to use for -# the tests in shell[1-5].test. If no such executable can be found, invoke -# [finish_test ; return] in the callers context. -# -proc test_find_cli {} { +proc test_find_binary {nm} { if {$::tcl_platform(platform)=="windows"} { - set ret "sqlite3.exe" + set ret "$nm.exe" } else { - set ret "sqlite3" + set ret $nm } set ret [file normalize [file join $::cmdlinearg(TESTFIXTURE_HOME) $ret]] if {![file executable $ret]} { @@ -2154,6 +2150,23 @@ proc test_find_cli {} { return $ret } +# Find the name of the 'shell' executable (e.g. "sqlite3.exe") to use for +# the tests in shell[1-5].test. If no such executable can be found, invoke +# [finish_test ; return] in the callers context. +# +proc test_find_cli {} { + uplevel test_find_binary sqlite3 +} + +# Find the name of the 'sqldiff' executable (e.g. "sqlite3.exe") to use for +# the tests in sqldiff tests. If no such executable can be found, invoke +# [finish_test ; return] in the callers context. +# +proc test_find_sqldiff {} { + uplevel test_find_binary sqldiff +} + + # If the library is compiled with the SQLITE_DEFAULT_AUTOVACUUM macro set # to non-zero, then set the global variable $AUTOVACUUM to 1. set AUTOVACUUM $sqlite_options(default_autovacuum) From 49aed58b7ff2a60f5bba3b2dab5deff1350a708e Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 19 Mar 2016 15:13:59 +0000 Subject: [PATCH 0179/1484] Fix another problem in test script rbudiff.test. FossilOrigin-Name: 41c29c123ff347db720ed1a541c0b2ffc04670aa --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/tester.tcl | 10 +++++++--- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index a56e5123a4..9053c93d5a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\stest\sscripts\ssqldiff.test\sand\srbudiff.test\sso\sthat\sthey\swork\swith\sthe\s--testdir\soption. -D 2016-03-19T14:53:36.705 +C Fix\sanother\sproblem\sin\stest\sscript\srbudiff.test. +D 2016-03-19T15:13:59.043 F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66 @@ -1085,7 +1085,7 @@ F test/tclsqlite.test c6d9f546f79d15d0134c1e06583fb3ee0c3afad3 F test/tempdb.test bd92eba8f20e16a9136e434e20b280794de3cdb6 F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30 F test/temptrigger.test 8ec228b0db5d7ebc4ee9b458fc28cb9e7873f5e1 -F test/tester.tcl d9831491ddc902ef62ef11438eca83ac0d4cf969 +F test/tester.tcl 2a82a76c1704a1d5f6c71bcebcffc3041e4d9856 F test/thread001.test 9f22fd3525a307ff42a326b6bc7b0465be1745a5 F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58 F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7 @@ -1456,7 +1456,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 88439a866b3b16ad7c308ebe59198662a05e7eeb -R 3b6913cf00d6ce7b8c04137012202e6b +P 1ffe3cde03f924bb8405a8729c8e1bc01f5b6d3b +R b5342d0d86cc431c9e51a0ed18eda8f1 U dan -Z d63e42a30b9cbf754c53eb2c6783a9e9 +Z 45d735e7ccd57967a5a5daaae9ccf4a0 diff --git a/manifest.uuid b/manifest.uuid index 0bf3c490c2..5de6868b9a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1ffe3cde03f924bb8405a8729c8e1bc01f5b6d3b \ No newline at end of file +41c29c123ff347db720ed1a541c0b2ffc04670aa \ No newline at end of file diff --git a/test/tester.tcl b/test/tester.tcl index 065acc37be..a452883cc4 100644 --- a/test/tester.tcl +++ b/test/tester.tcl @@ -2145,7 +2145,7 @@ proc test_find_binary {nm} { set ret [file normalize [file join $::cmdlinearg(TESTFIXTURE_HOME) $ret]] if {![file executable $ret]} { finish_test - return -code return + return "" } return $ret } @@ -2155,7 +2155,9 @@ proc test_find_binary {nm} { # [finish_test ; return] in the callers context. # proc test_find_cli {} { - uplevel test_find_binary sqlite3 + set cli [test_find_binary sqlite3] + if {$prog==""} { return -code return } + return $prog } # Find the name of the 'sqldiff' executable (e.g. "sqlite3.exe") to use for @@ -2163,7 +2165,9 @@ proc test_find_cli {} { # [finish_test ; return] in the callers context. # proc test_find_sqldiff {} { - uplevel test_find_binary sqldiff + set prog [test_find_binary sqldiff] + if {$prog==""} { return -code return } + return $prog } From febfe0230097f4bc0f57edf1d626331b2cbc1bae Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 19 Mar 2016 16:21:26 +0000 Subject: [PATCH 0180/1484] Update the sqldiff tool so that it generates an rbu_count table. FossilOrigin-Name: 1f7afb6e9be9f549a91bf2ab492df15698df89fd --- ext/rbu/rbudiff.test | 22 ++++++++++++++++++++++ ext/rbu/rbuprogress.test | 10 ++++++++++ manifest | 16 ++++++++-------- manifest.uuid | 2 +- tool/sqldiff.c | 16 +++++++++++++++- 5 files changed, 56 insertions(+), 10 deletions(-) diff --git a/ext/rbu/rbudiff.test b/ext/rbu/rbudiff.test index 0ebc0dad0f..0863f6e807 100644 --- a/ext/rbu/rbudiff.test +++ b/ext/rbu/rbudiff.test @@ -36,6 +36,7 @@ proc step_rbu {target rbu} { } proc apply_rbudiff {sql target} { + test_rbucount $sql forcedelete rbu.db sqlite3 rbudb rbu.db rbudb eval $sql @@ -43,6 +44,27 @@ proc apply_rbudiff {sql target} { step_rbu $target rbu.db } +# The only argument is the output of an [sqldiff -rbu] run. This command +# tests that the contents of the rbu_count table is correct. An exception +# is thrown if it is not. +# +proc test_rbucount {sql} { + sqlite3 tmpdb "" + tmpdb eval $sql + tmpdb eval { + SELECT name FROM sqlite_master WHERE name LIKE 'data%' AND type='table' + } { + set a [tmpdb eval "SELECT count(*) FROM $name"] + set b [tmpdb eval {SELECT cnt FROM rbu_count WHERE tbl = $name}] + if {$a != $b} { + tmpdb close + error "rbu_count error - tbl = $name" + } + } + tmpdb close + return "" +} + proc rbudiff_cksum {db1} { set txt "" diff --git a/ext/rbu/rbuprogress.test b/ext/rbu/rbuprogress.test index 6e6c7faf61..6afbffe8ed 100644 --- a/ext/rbu/rbuprogress.test +++ b/ext/rbu/rbuprogress.test @@ -381,6 +381,16 @@ foreach {bReopen} { 0 1 } { } {2500 4000 6000 8000 10000} {5000 10000} + + 3 { + CREATE TABLE data0_t1(rbu_rowid, a, b, c, rbu_control); + INSERT INTO data0_t1 VALUES(1, NULL, NULL, NULL, 1); + INSERT INTO data0_t1 VALUES(2, NULL, NULL, 7, '..x'); + CREATE TABLE rbu_count(tbl, cnt); + INSERT INTO rbu_count VALUES('data0_t1', 2); + } + {2500 4000 6000 8000 10000} + {5000 10000} } { reset_db ; execsql $tbl diff --git a/manifest b/manifest index c781c627e1..0d19f8488d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\slatest\strunk\schanges,\sincluding\sfixes\sto\stest\sscript\srbudiff.test,\sinto\sthis\sbranch. -D 2016-03-19T15:34:42.291 +C Update\sthe\ssqldiff\stool\sso\sthat\sit\sgenerates\san\srbu_count\stable. +D 2016-03-19T16:21:26.457 F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66 @@ -238,11 +238,11 @@ F ext/rbu/rbuB.test c25bc325b8072a766e56bb76c001866b405925c2 F ext/rbu/rbuC.test efe47db508a0269b683cb2a1913a425ffd39a831 F ext/rbu/rbu_common.tcl 0398545fed614f807d5f0ba55a85a51f08ba8f1a F ext/rbu/rbucrash.test 8d2ed5d4b05fef6c00c2a6b5f7ead71fa172a695 -F ext/rbu/rbudiff.test 7f0fbf54912b9f8898819504c8465df12c970a00 +F ext/rbu/rbudiff.test 2df0a8a7d998ecf81764c21eeda3cde5611c5091 F ext/rbu/rbufault.test cc0be8d5d392d98b0c2d6a51be377ea989250a89 F ext/rbu/rbufault2.test 9a7f19edd6ea35c4c9f807d8a3db0a03a5670c06 F ext/rbu/rbufts.test 828cd689da825f0a7b7c53ffc1f6f7fdb6fa5bda -F ext/rbu/rbuprogress.test 9d2dfd82fc001f26997e36db256df31f2e19e133 +F ext/rbu/rbuprogress.test 2023a7df2c523e3df1cb532eff811cda385a789a F ext/rbu/rbusave.test 0f43b6686084f426ddd040b878426452fd2c2f48 F ext/rbu/sqlite3rbu.c edeb8f90a1bccc567438036e083123cec1403091 F ext/rbu/sqlite3rbu.h d7cc99350c10134f358fe1a8997d9225b3f712b2 @@ -1424,7 +1424,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 7ce07da76b5e745783e703a834417d725b7d45fd F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c -F tool/sqldiff.c 0e9b76f9f4a72856d0384f5e0a038bbeb78dd222 +F tool/sqldiff.c ca315aca4e2d24233e8f2000edea5880c53d1875 F tool/srcck1.c 4f65e1a6748e42f24c0ea629dddc934d821c729a F tool/stack_usage.tcl f8e71b92cdb099a147dad572375595eae55eca43 F tool/symbols-mingw.sh 4dbcea7e74768305384c9fd2ed2b41bbf9f0414d @@ -1457,7 +1457,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 65e02368e2b6cec349ea71af5a456d6783b0d15e 41c29c123ff347db720ed1a541c0b2ffc04670aa -R 4672da949ef7e2ff98784ed13b0995da +P 734fc68fb12f06e97026d4637138b82b37809f5b +R 10d61b7fcae01138c8363988e8c8eb47 U dan -Z 877e0d37b31de9a8b8cab0dfbc82a372 +Z 3bf67face0611b0cfd47029621ad6bf5 diff --git a/manifest.uuid b/manifest.uuid index 5a343a598e..60d114711c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -734fc68fb12f06e97026d4637138b82b37809f5b \ No newline at end of file +1f7afb6e9be9f549a91bf2ab492df15698df89fd \ No newline at end of file diff --git a/tool/sqldiff.c b/tool/sqldiff.c index d2423a73ba..319acafdbd 100644 --- a/tool/sqldiff.c +++ b/tool/sqldiff.c @@ -1244,6 +1244,7 @@ static void rbudiff_one_table(const char *zTab, FILE *out){ Str sql = {0, 0, 0}; /* Query to find differences */ Str insert = {0, 0, 0}; /* First part of output INSERT statement */ sqlite3_stmt *pStmt = 0; + int nRow = 0; /* Total rows in data_xxx table */ /* --rbu mode must use real primary keys. */ g.bSchemaPK = 1; @@ -1289,6 +1290,7 @@ static void rbudiff_one_table(const char *zTab, FILE *out){ /* Output the first part of the INSERT statement */ fprintf(out, "%s", insert.z); + nRow++; if( sqlite3_column_type(pStmt, nCol)==SQLITE_INTEGER ){ for(i=0; i<=nCol; i++){ @@ -1342,6 +1344,12 @@ static void rbudiff_one_table(const char *zTab, FILE *out){ } sqlite3_finalize(pStmt); + if( nRow>0 ){ + Str cnt = {0, 0, 0}; + strPrintf(&cnt, "INSERT INTO rbu_count VALUES('data_%q', %d);", zTab, nRow); + fprintf(out, "%s\n", cnt.z); + strFree(&cnt); + } strFree(&ct); strFree(&sql); @@ -1856,7 +1864,13 @@ int main(int argc, char **argv){ } if( neverUseTransaction ) useTransaction = 0; - if( useTransaction ) printf("BEGIN TRANSACTION;\n"); + if( useTransaction ) fprintf(out, "BEGIN TRANSACTION;\n"); + if( xDiff==rbudiff_one_table ){ + fprintf(out, "CREATE TABLE IF NOT EXISTS rbu_count" + "(tbl TEXT PRIMARY KEY COLLATE NOCASE, cnt INTEGER) " + "WITHOUT ROWID;\n" + ); + } if( zTab ){ xDiff(zTab, out); }else{ From fce07fb9449f0f9880a2944525eb0a3452c768c8 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 19 Mar 2016 17:09:30 +0000 Subject: [PATCH 0181/1484] Fix a problem detecting invalid values in the rbu_control column of an rbu database table. FossilOrigin-Name: a1132dd9027d1c6dd845be307eeb38e535393f2c --- ext/rbu/rbu1.test | 2 +- ext/rbu/sqlite3rbu.c | 2 +- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/ext/rbu/rbu1.test b/ext/rbu/rbu1.test index 19b3d27a9f..51d2ce8171 100644 --- a/ext/rbu/rbu1.test +++ b/ext/rbu/rbu1.test @@ -611,7 +611,7 @@ foreach {tn3 create_vfs destroy_vfs} { 9 { CREATE TABLE t1(a, b PRIMARY KEY) WITHOUT ROWID; CREATE TABLE rbu.data_t1(a, b, rbu_control); - INSERT INTO rbu.data_t1 VALUES(1, 2, 2); + INSERT INTO rbu.data_t1 VALUES(1, 2, 3); } {SQLITE_ERROR - invalid rbu_control value} 10 { diff --git a/ext/rbu/sqlite3rbu.c b/ext/rbu/sqlite3rbu.c index b587d2bb20..93b756aa6a 100644 --- a/ext/rbu/sqlite3rbu.c +++ b/ext/rbu/sqlite3rbu.c @@ -2706,7 +2706,7 @@ static int rbuStep(sqlite3rbu *p){ ); assert( eType!=RBU_UPDATE || pIter->zIdx==0 ); - if( pIter->zIdx==0 && eType==RBU_IDX_DELETE ){ + if( pIter->zIdx==0 && (eType==RBU_IDX_DELETE || eType==RBU_IDX_INSERT) ){ rbuBadControlError(p); } else if( eType==RBU_REPLACE ){ diff --git a/manifest b/manifest index 0d19f8488d..4f60482def 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\sthe\ssqldiff\stool\sso\sthat\sit\sgenerates\san\srbu_count\stable. -D 2016-03-19T16:21:26.457 +C Fix\sa\sproblem\sdetecting\sinvalid\svalues\sin\sthe\srbu_control\scolumn\sof\san\srbu\sdatabase\stable. +D 2016-03-19T17:09:30.416 F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66 @@ -221,7 +221,7 @@ F ext/misc/vfslog.c fe40fab5c077a40477f7e5eba994309ecac6cc95 F ext/misc/vtshim.c babb0dc2bf116029e3e7c9a618b8a1377045303e F ext/misc/wholenumber.c 784b12543d60702ebdd47da936e278aa03076212 F ext/rbu/rbu.c ba3983dceffa0938532e79142f391737513de023 -F ext/rbu/rbu1.test 57601977588603e82700a43c279bd55282ffa482 +F ext/rbu/rbu1.test 42bd835e019eff789ec241017965277baeb658b1 F ext/rbu/rbu10.test 046b0980041d30700464a800bbf6733ed2df515d F ext/rbu/rbu11.test 9bc68c2d3dbeb1720153626e3bd0466dcc017702 F ext/rbu/rbu12.test bde22ed0004dd5d1888c72a84ae407e574aeae16 @@ -244,7 +244,7 @@ F ext/rbu/rbufault2.test 9a7f19edd6ea35c4c9f807d8a3db0a03a5670c06 F ext/rbu/rbufts.test 828cd689da825f0a7b7c53ffc1f6f7fdb6fa5bda F ext/rbu/rbuprogress.test 2023a7df2c523e3df1cb532eff811cda385a789a F ext/rbu/rbusave.test 0f43b6686084f426ddd040b878426452fd2c2f48 -F ext/rbu/sqlite3rbu.c edeb8f90a1bccc567438036e083123cec1403091 +F ext/rbu/sqlite3rbu.c 007fc4db8c0b95c7ef10162b5864921ef5cc8106 F ext/rbu/sqlite3rbu.h d7cc99350c10134f358fe1a8997d9225b3f712b2 F ext/rbu/test_rbu.c 3505641a78b723589b8780d5f9b2faeeb73e037d F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 @@ -1457,7 +1457,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 734fc68fb12f06e97026d4637138b82b37809f5b -R 10d61b7fcae01138c8363988e8c8eb47 +P 1f7afb6e9be9f549a91bf2ab492df15698df89fd +R 514d2969d6e0309f243db8f417770908 U dan -Z 3bf67face0611b0cfd47029621ad6bf5 +Z 5251b6a3ad2fccca44307445ac5141c6 diff --git a/manifest.uuid b/manifest.uuid index 60d114711c..1c195bb6c5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1f7afb6e9be9f549a91bf2ab492df15698df89fd \ No newline at end of file +a1132dd9027d1c6dd845be307eeb38e535393f2c \ No newline at end of file From 9bccde3d03a75ca4730b7c4dfc83c69a4b86b0fb Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 19 Mar 2016 18:00:44 +0000 Subject: [PATCH 0182/1484] Updates to the Lemon documentation. FossilOrigin-Name: f095341471aa822e6d556cb65512ec081c3918da --- doc/lemon.html | 279 ++++++++++++++++++++++++++++++++----------------- manifest | 14 +-- manifest.uuid | 2 +- 3 files changed, 191 insertions(+), 104 deletions(-) diff --git a/doc/lemon.html b/doc/lemon.html index 2b8c613640..773c68e6ad 100644 --- a/doc/lemon.html +++ b/doc/lemon.html @@ -5,14 +5,17 @@

    The Lemon Parser Generator

    -

    Lemon is an LALR(1) parser generator for C or C++. -It does the same job as ``bison'' and ``yacc''. -But lemon is not another bison or yacc clone. It +

    Lemon is an LALR(1) parser generator for C. +It does the same job as "bison" and "yacc". +But lemon is not a bison or yacc clone. Lemon uses a different grammar syntax which is designed to -reduce the number of coding errors. Lemon also uses a more -sophisticated parsing engine that is faster than yacc and -bison and which is both reentrant and thread-safe. -Furthermore, Lemon implements features that can be used +reduce the number of coding errors. Lemon also uses a +parsing engine that is faster than yacc and +bison and which is both reentrant and threadsafe. +(Update: Since the previous sentence was written, bison +has also been updated so that it too can generate a +reentrant and threadsafe parser.) +Lemon also implements features that can be used to eliminate resource leaks, making is suitable for use in long-running programs such as graphical user interfaces or embedded controllers.

    @@ -44,18 +47,18 @@ one and three files of outputs. automaton. By default, all three of these output files are generated. -The header file is suppressed if the ``-m'' command-line option is -used and the report file is omitted when ``-q'' is selected.

    +The header file is suppressed if the "-m" command-line option is +used and the report file is omitted when "-q" is selected.

    -

    The grammar specification file uses a ``.y'' suffix, by convention. +

    The grammar specification file uses a ".y" suffix, by convention. In the examples used in this document, we'll assume the name of the -grammar file is ``gram.y''. A typical use of Lemon would be the +grammar file is "gram.y". A typical use of Lemon would be the following command:

        lemon gram.y
     
    -This command will generate three output files named ``gram.c'', -``gram.h'' and ``gram.out''. +This command will generate three output files named "gram.c", +"gram.h" and "gram.out". The first is C code to implement the parser. The second is the header file that defines numerical values for all terminal symbols, and the last is the report that explains @@ -71,39 +74,35 @@ with a brief explanation of what each does by typing As of this writing, the following command-line options are supported:
      -
    • -b -
    • -c -
    • -g -
    • -m -
    • -q -
    • -s -
    • -x +
    • -b +Show only the basis for each parser state in the report file. +
    • -c +Do not compress the generated action tables. +
    • -Dname +Define C preprocessor macro name. This macro is useable by +"%ifdef" lines in the grammar file. +
    • -g +Do not generate a parser. Instead write the input grammar to standard +output with all comments, actions, and other extraneous text removed. +
    • -l +Omit "#line" directives int the generated parser C code. +
    • -m +Cause the output C source code to be compatible with the "makeheaders" +program. +
    • -p +Display all conflicts that are resolved by +precedence rules. +
    • -q +Suppress generation of the report file. +
    • -r +Do not sort or renumber the parser states as part of optimization. +
    • -s +Show parser statistics before existing. +
    • -Tfile +Use file as the template for the generated C-code parser implementation. +
    • -x +Print the Lemon version number.
    -The ``-b'' option reduces the amount of text in the report file by -printing only the basis of each parser state, rather than the full -configuration. -The ``-c'' option suppresses action table compression. Using -c -will make the parser a little larger and slower but it will detect -syntax errors sooner. -The ``-g'' option causes no output files to be generated at all. -Instead, the input grammar file is printed on standard output but -with all comments, actions and other extraneous text deleted. This -is a useful way to get a quick summary of a grammar. -The ``-m'' option causes the output C source file to be compatible -with the ``makeheaders'' program. -Makeheaders is a program that automatically generates header files -from C source code. When the ``-m'' option is used, the header -file is not output since the makeheaders program will take care -of generated all header files automatically. -The ``-q'' option suppresses the report file. -Using ``-s'' causes a brief summary of parser statistics to be -printed. Like this: -
    -   Parser statistics: 74 terminals, 70 nonterminals, 179 rules
    -                      340 states, 2026 parser table entries, 0 conflicts
    -
    -Finally, the ``-x'' option causes Lemon to print its version number -and then stops without attempting to read the grammar or generate a parser.

    The Parser Interface

    @@ -121,12 +120,12 @@ A new parser is created as follows: The ParseAlloc() routine allocates and initializes a new parser and returns a pointer to it. -The actual data structure used to represent a parser is opaque -- +The actual data structure used to represent a parser is opaque — its internal structure is not visible or usable by the calling routine. For this reason, the ParseAlloc() routine returns a pointer to void rather than a pointer to some particular structure. The sole argument to the ParseAlloc() routine is a pointer to the -subroutine used to allocate memory. Typically this means ``malloc()''.

    +subroutine used to allocate memory. Typically this means malloc().

    After a program is finished using a parser, it can reclaim all memory allocated by that parser by calling @@ -151,13 +150,13 @@ type of the next token in the data stream. There is one token type for each terminal symbol in the grammar. The gram.h file generated by Lemon contains #define statements that map symbolic terminal symbol names into appropriate integer values. -(A value of 0 for the second argument is a special flag to the -parser to indicate that the end of input has been reached.) +A value of 0 for the second argument is a special flag to the +parser to indicate that the end of input has been reached. The third argument is the value of the given token. By default, the type of the third argument is integer, but the grammar will usually redefine this type to be some kind of structure. Typically the second argument will be a broad category of tokens -such as ``identifier'' or ``number'' and the third argument will +such as "identifier" or "number" and the third argument will be the name of the identifier or the value of the number.

    The Parse() function may have either three or four arguments, @@ -193,7 +192,7 @@ following: This example shows a user-written routine that parses a file of text and returns a pointer to the parse tree. -(We've omitted all error-handling from this example to keep it +(All error-handling code is omitted from this example to keep it simple.) We assume the existence of some kind of tokenizer which is created using TokenizerCreate() on line 8 and deleted by TokenizerFree() @@ -287,7 +286,7 @@ tokens) and it honors the same commenting conventions as C and C++.

    Terminals and Nonterminals

    A terminal symbol (token) is any string of alphanumeric -and underscore characters +and/or underscore characters that begins with an upper case letter. A terminal can contain lowercase letters after the first character, but the usual convention is to make terminals all upper case. @@ -314,7 +313,7 @@ must have alphanumeric names.

    The main component of a Lemon grammar file is a sequence of grammar rules. Each grammar rule consists of a nonterminal symbol followed by -the special symbol ``::='' and then a list of terminals and/or nonterminals. +the special symbol "::=" and then a list of terminals and/or nonterminals. The rule is terminated by a period. The list of terminals and nonterminals on the right-hand side of the rule can be empty. @@ -330,9 +329,9 @@ A typical sequence of grammar rules might look something like this:

    -

    There is one non-terminal in this example, ``expr'', and five -terminal symbols or tokens: ``PLUS'', ``TIMES'', ``LPAREN'', -``RPAREN'' and ``VALUE''.

    +

    There is one non-terminal in this example, "expr", and five +terminal symbols or tokens: "PLUS", "TIMES", "LPAREN", +"RPAREN" and "VALUE".

    Like yacc and bison, Lemon allows the grammar to specify a block of C code that will be executed whenever a grammar rule is reduced @@ -348,15 +347,15 @@ For example:

    In order to be useful, grammar actions must normally be linked to their associated grammar rules. -In yacc and bison, this is accomplished by embedding a ``$$'' in the +In yacc and bison, this is accomplished by embedding a "$$" in the action to stand for the value of the left-hand side of the rule and -symbols ``$1'', ``$2'', and so forth to stand for the value of +symbols "$1", "$2", and so forth to stand for the value of the terminal or nonterminal at position 1, 2 and so forth on the right-hand side of the rule. This idea is very powerful, but it is also very error-prone. The single most common source of errors in a yacc or bison grammar is to miscount the number of symbols on the right-hand side of a grammar -rule and say ``$7'' when you really mean ``$8''.

    +rule and say "$7" when you really mean "$8".

    Lemon avoids the need to count grammar symbols by assigning symbolic names to each symbol in a grammar rule and then using those symbolic @@ -386,7 +385,7 @@ For example, the rule

       expr(A) ::= expr(B) PLUS expr(C).  { A = B; }
     
    -will generate an error because the linking symbol ``C'' is used +will generate an error because the linking symbol "C" is used in the grammar rule but not in the reduce action.

    The Lemon notation for linking grammar rules to reduce actions @@ -394,6 +393,7 @@ also facilitates the use of destructors for reclaiming memory allocated by the values of terminals and nonterminals on the right-hand side of a rule.

    +

    Precedence Rules

    Lemon resolves parsing ambiguities in exactly the same way as @@ -405,7 +405,10 @@ whichever rule comes first in the grammar file.

    yacc and bison, Lemon allows a measure of control over the resolution of paring conflicts using precedence rules. A precedence value can be assigned to any terminal symbol -using the %left, %right or %nonassoc directives. Terminal symbols +using the +%left, +%right or +%nonassoc directives. Terminal symbols mentioned in earlier directives have a lower precedence that terminal symbols mentioned in later directives. For example:

    @@ -525,7 +528,11 @@ other than that, the order of directives in Lemon is arbitrary.

  • %default_destructor
  • %default_type
  • %destructor +
  • %endif
  • %extra_argument +
  • %fallback +
  • %ifdef +
  • %ifndef
  • %include
  • %left
  • %name @@ -537,49 +544,57 @@ other than that, the order of directives in Lemon is arbitrary.

  • %stack_size
  • %start_symbol
  • %syntax_error +
  • %token_class
  • %token_destructor
  • %token_prefix
  • %token_type
  • %type +
  • %wildcard Each of these directives will be described separately in the following sections:

    +

    The %code directive

    -

    The %code directive is used to specify addition C/C++ code that +

    The %code directive is used to specify addition C code that is added to the end of the main output file. This is similar to -the %include directive except that %include is inserted at the -beginning of the main output file.

    +the %include directive except that %include +is inserted at the beginning of the main output file.

    %code is typically used to include some action routines or perhaps -a tokenizer as part of the output file.

    +a tokenizer or even the "main()" function +as part of the output file.

    +

    The %default_destructor directive

    The %default_destructor directive specifies a destructor to use for non-terminals that do not have their own destructor specified by a separate %destructor directive. See the documentation -on the %destructor directive below for additional information.

    +on the %destructor directive below for +additional information.

    In some grammers, many different non-terminal symbols have the same datatype and hence the same destructor. This directive is a convenience way to specify the same destructor for all those non-terminals using a single statement.

    +

    The %default_type directive

    The %default_type directive specifies the datatype of non-terminal symbols that do no have their own datatype defined using a separate -%type directive. See the documentation on %type below for addition -information.

    +%type directive. +

    +

    The %destructor directive

    The %destructor directive is used to specify a destructor for a non-terminal symbol. -(See also the %token_destructor directive which is used to -specify a destructor for terminal symbols.)

    +(See also the %token_destructor +directive which is used to specify a destructor for terminal symbols.)

    A non-terminal's destructor is called to dispose of the non-terminal's value whenever the non-terminal is popped from @@ -602,26 +617,25 @@ or other resources held by that non-terminal.

    This example is a bit contrived but it serves to illustrate how destructors work. The example shows a non-terminal named -``nt'' that holds values of type ``void*''. When the rule for -an ``nt'' reduces, it sets the value of the non-terminal to +"nt" that holds values of type "void*". When the rule for +an "nt" reduces, it sets the value of the non-terminal to space obtained from malloc(). Later, when the nt non-terminal is popped from the stack, the destructor will fire and call free() on this malloced space, thus avoiding a memory leak. -(Note that the symbol ``$$'' in the destructor code is replaced +(Note that the symbol "$$" in the destructor code is replaced by the value of the non-terminal.)

    It is important to note that the value of a non-terminal is passed to the destructor whenever the non-terminal is removed from the stack, unless the non-terminal is used in a C-code action. If the non-terminal is used by C-code, then it is assumed that the -C-code will take care of destroying it if it should really -be destroyed. More commonly, the value is used to build some +C-code will take care of destroying it. +More commonly, the value is used to build some larger structure and we don't want to destroy it, which is why the destructor is not called in this circumstance.

    -

    By appropriate use of destructors, it is possible to -build a parser using Lemon that can be used within a long-running -program, such as a GUI, that will not leak memory or other resources. +

    Destructors help avoid memory leaks by automatically freeing +allocated objects when they go out of scope. To do the same using yacc or bison is much more difficult.

    @@ -638,17 +652,66 @@ and so forth. For example, if the grammar file contains:

    Then the Parse() function generated will have an 4th parameter -of type ``MyStruct*'' and all action routines will have access to -a variable named ``pAbc'' that is the value of the 4th parameter +of type "MyStruct*" and all action routines will have access to +a variable named "pAbc" that is the value of the 4th parameter in the most recent call to Parse().

    + +

    The %fallback directive

    + +

    The %fallback directive specifies an alternative meaning for one +or more tokens. The alternative meaning is tried if the original token +would have generated a syntax error. + +

    The %fallback directive was added to support robust parsing of SQL +syntax in SQLite. +The SQL language contains a large assortment of keywords, each of which +appears as a different token to the language parser. SQL contains so +many keywords, that it can be difficult for programmers to keep up with +them all. Programmers will, therefore, sometimes mistakenly use an +obscure language keyword for an identifier. The %fallback directive +provides a mechanism to tell the parser: "If you are unable to parse +this keyword, try treating it as an identifier instead." + +

    The syntax of %fallback is as follows: + +

    +%fallback ID TOKEN... . +
    + +

    In words, the %fallback directive is followed by a list of token names +terminated by a period. The first token name is the fallback token - the +token to which all the other tokens fall back to. The second and subsequent +arguments are tokens which fall back to the token identified by the first +argument. + + +

    The %ifdef, %ifndef, and %endif directives.

    + +

    The %ifdef, %ifndef, and %endif directives are similar to +#ifdef, #ifndef, and #endif in the C-preprocessor, just not as general. +Each of these directives must begin at the left margin. No whitespace +is allowed between the "%" and the directive name. + +

    Grammar text in between "%ifdef MACRO" and the next nested "%endif" is +ignored unless the "-DMACRO" command-line option is used. Grammar text +betwen "%ifndef MACRO" and the next nested "%endif" is included except when +the "-DMACRO" command-line option is used. + +

    Note that the argument to %ifdef and %ifndef must be a single +preprocessor symbol name, not a general expression. There is no "%else" +directive. + + +

    The %include directive

    The %include directive specifies C code that is included at the top of the generated parser. You can include any text you want -- the Lemon parser generator copies it blindly. If you have multiple -%include directives in your grammar file the value of the last -%include directive overwrites all the others.

    The %include directive is very handy for getting some extra #include preprocessor statements at the beginning of the generated parser. @@ -661,12 +724,13 @@ For example:

    This might be needed, for example, if some of the C actions in the grammar call functions that are prototyed in unistd.h.

    +

    The %left directive

    -The %left directive is used (along with the %right and -%nonassoc directives) to declare precedences of terminal -symbols. Every terminal symbol whose name appears after -a %left directive but before the next period (``.'') is +The %left directive is used (along with the %right and +%nonassoc directives) to declare precedences of +terminal symbols. Every terminal symbol whose name appears after +a %left directive but before the next period (".") is given the same left-associative precedence value. Subsequent %left directives have higher precedence. For example:

    @@ -687,10 +751,11 @@ a large amount of stack space if you make heavy use or right-associative operators. For this reason, it is recommended that you use %left rather than %right whenever possible.

    +

    The %name directive

    By default, the functions generated by Lemon all begin with the -five-character string ``Parse''. You can change this string to something +five-character string "Parse". You can change this string to something different using the %name directive. For instance:

    @@ -709,16 +774,19 @@ The %name directive allows you to generator two or more different
     parsers and link them all into the same executable.
     

    +

    The %nonassoc directive

    This directive is used to assign non-associative precedence to -one or more terminal symbols. See the section on precedence rules -or on the %left directive for additional information.

    +one or more terminal symbols. See the section on +precedence rules +or on the %left directive for additional information.

    +

    The %parse_accept directive

    The %parse_accept directive specifies a block of C code that is -executed whenever the parser accepts its input string. To ``accept'' +executed whenever the parser accepts its input string. To "accept" an input string means that the parser was able to process all tokens without error.

    @@ -730,7 +798,7 @@ without error.

    }

    - +

    The %parse_failure directive

    The %parse_failure directive specifies a block of C code that @@ -745,12 +813,15 @@ only invoked when parsing is unable to continue.

    }

    +

    The %right directive

    This directive is used to assign right-associative precedence to -one or more terminal symbols. See the section on precedence rules -or on the %left directive for additional information.

    +one or more terminal symbols. See the section on +precedence rules +or on the %left directive for additional information.

    +

    The %stack_overflow directive

    The %stack_overflow directive specifies a block of C code that @@ -779,6 +850,7 @@ Not like this: list ::= . +

    The %stack_size directive

    If stack overflow is a problem and you can't resolve the trouble @@ -791,6 +863,7 @@ with a stack of the requested size. The default value is 100.

    %stack_size 2000

    +

    The %start_symbol directive

    By default, the start-symbol for the grammar that Lemon generates @@ -801,6 +874,7 @@ can choose a different start-symbol using the %start_symbol directive.

    %start_symbol prog

    +

    The %token_destructor directive

    The %destructor directive assigns a destructor to a non-terminal @@ -813,6 +887,7 @@ the %token_type directive) and so they use a common destructor. Other than that, the token destructor works just like the non-terminal destructors.

    +

    The %token_prefix directive

    Lemon generates #defines that assign small integer constants @@ -838,6 +913,7 @@ to cause Lemon to produce these symbols instead: #define TOKEN_PLUS 4 +

    The %token_type and %type directives

    These directives are used to specify the data types for values @@ -853,7 +929,7 @@ token structure. Like this:

    If the data type of terminals is not specified, the default value -is ``int''.

    +is "int".

    Non-terminal symbols can each have their own data types. Typically the data type of a non-terminal is a pointer to the root of a parse-tree @@ -874,6 +950,17 @@ non-terminal whose data type requires 1K of storage, then your 100 entry parser stack will require 100K of heap space. If you are willing and able to pay that price, fine. You just need to know.

    + +

    The %wildcard directive

    + +

    The %wildcard directive is followed by a single token name and a +period. This directive specifies that the identified token should +match any input token. + +

    When the generated parser has the choice of matching an input against +the wildcard token and some other token, the other token is always used. +The wildcard token is only matched if there are no other alternatives. +

    Error Processing

    After extensive experimentation over several years, it has been @@ -885,7 +972,7 @@ first invokes the code specified by the %syntax_error directive, if any. It then enters its error recovery strategy. The error recovery strategy is to begin popping the parsers stack until it enters a state where it is permitted to shift a special non-terminal symbol -named ``error''. It then shifts this non-terminal and continues +named "error". It then shifts this non-terminal and continues parsing. But the %syntax_error routine will not be called again until at least three new tokens have been successfully shifted.

    @@ -894,7 +981,7 @@ is unable to shift the error symbol, then the %parse_failed routine is invoked and the parser resets itself to its start state, ready to begin parsing a new file. This is what will happen at the very first syntax error, of course, if there are no instances of the -``error'' non-terminal in your grammar.

    +"error" non-terminal in your grammar.

    diff --git a/manifest b/manifest index 16d972c4c4..0f76cddd77 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\ssqlite3rbu_bp_progress()\sAPI\sto\sthe\sRBU\sextension.\sUsed\sto\sobtain\sthe\spercentage\sprogress\sof\san\sRBU\supdate. -D 2016-03-19T17:48:12.474 +C Updates\sto\sthe\sLemon\sdocumentation. +D 2016-03-19T18:00:44.390 F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66 @@ -33,7 +33,7 @@ F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55 F configure c01a159fdf7ea0171ad01ce2937283f2c7972bde x F configure.ac 89e4e02a83d8a1528011f8395621b8c3186b4089 F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad -F doc/lemon.html c30255bea0fd87a81f082d17a72c9dffbc3f6dd9 +F doc/lemon.html e2118945e5f07ed146b45c9cd2b2dd6eabb8ebf2 F doc/pager-invariants.txt 27fed9a70ddad2088750c4a2b493b63853da2710 F doc/vfs-shm.txt e101f27ea02a8387ce46a05be2b1a902a021d37a F ext/README.txt 913a7bd3f4837ab14d7e063304181787658b14e1 @@ -1457,7 +1457,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 41c29c123ff347db720ed1a541c0b2ffc04670aa a1132dd9027d1c6dd845be307eeb38e535393f2c -R cb043230718add9f6d5b3a52d3cc19f9 -U dan -Z 67d28afde6e42b0d24beaa12aaf943b4 +P 209e31c729b9c8a09a80e43e3e4a2f3cd9384b3a +R fc92092a5d7485b32fa03b1aa106ab60 +U drh +Z 281323da864a48bf6b3196a4def3800c diff --git a/manifest.uuid b/manifest.uuid index 8119ca882f..e217909057 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -209e31c729b9c8a09a80e43e3e4a2f3cd9384b3a \ No newline at end of file +f095341471aa822e6d556cb65512ec081c3918da \ No newline at end of file From b6eb666264d2885e78288abc7a21798cd7092f7d Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 19 Mar 2016 18:11:59 +0000 Subject: [PATCH 0183/1484] Fix exclusive.test so that it works with -DSQLITE_TEMP_STORE=3. FossilOrigin-Name: d7852c639683a1d305a1e731df3cccafa64b594b --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/exclusive.test | 6 +++--- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 0f76cddd77..847bc79890 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Updates\sto\sthe\sLemon\sdocumentation. -D 2016-03-19T18:00:44.390 +C Fix\sexclusive.test\sso\sthat\sit\sworks\swith\s-DSQLITE_TEMP_STORE=3. +D 2016-03-19T18:11:59.750 F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66 @@ -630,7 +630,7 @@ F test/enc4.test c8f1ce3618508fd0909945beb8b8831feef2c020 F test/eqp.test 3fe051af50921284189d1970eb653f9fcf5117d2 F test/errmsg.test f31592a594b44ee121371d25ddd5d63497bb3401 F test/eval.test a64c9105d6ff163df7cf09d6ac29cdad5922078c -F test/exclusive.test f48243eaf40e0957215501a12f510a8644d13a02 +F test/exclusive.test 9a57bd66e39144b888ca75c309914fcdefb4e3f9 F test/exclusive2.test 32798111aae78a5deec980eee383213f189df308 F test/exec.test e949714dc127eaa5ecc7d723efec1ec27118fdd7 F test/exists.test 8f7b27b61c2fbe5822f0a1f899c715d14e416e30 @@ -1457,7 +1457,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 209e31c729b9c8a09a80e43e3e4a2f3cd9384b3a -R fc92092a5d7485b32fa03b1aa106ab60 -U drh -Z 281323da864a48bf6b3196a4def3800c +P f095341471aa822e6d556cb65512ec081c3918da +R eda7e2fd58d6241fa97b2fe69addd6c1 +U dan +Z fdac7ca02eef2361aeb61c0eeeaed018 diff --git a/manifest.uuid b/manifest.uuid index e217909057..378b71e1fc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f095341471aa822e6d556cb65512ec081c3918da \ No newline at end of file +d7852c639683a1d305a1e731df3cccafa64b594b \ No newline at end of file diff --git a/test/exclusive.test b/test/exclusive.test index c7b88cfbca..45f9318205 100644 --- a/test/exclusive.test +++ b/test/exclusive.test @@ -423,7 +423,7 @@ do_test exclusive-5.1 { # (2016-03-04) The statement-journal is now opened lazily set sqlite_open_file_count expr $sqlite_open_file_count-$extrafds -} [expr 2 - ($TEMP_STORE>=2)] +} {2} do_test exclusive-5.2 { execsql { COMMIT; @@ -450,7 +450,7 @@ do_test exclusive-5.4 { # 2016-03-04: The statement-journal open is deferred set sqlite_open_file_count expr $sqlite_open_file_count-$extrafds -} [expr 2 - ($TEMP_STORE>=2)] +} {2} do_test exclusive-5.5 { execsql { COMMIT; @@ -459,7 +459,7 @@ do_test exclusive-5.5 { # 2016-03-04: The statement-journal open is deferred set sqlite_open_file_count expr $sqlite_open_file_count-$extrafds -} [expr 2 - ($TEMP_STORE>=2)] +} {2} do_test exclusive-5.6 { execsql { PRAGMA locking_mode = normal; From 9f6168b6a3bbd7656fd2428049144e403e9cb037 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 19 Mar 2016 23:32:58 +0000 Subject: [PATCH 0184/1484] Change the Vdbe.aMem array so that it is zero-based instead of one-based. FossilOrigin-Name: e07b0c47eb5a39623f5fe0e66b939bba0906691c --- manifest | 21 +++++++------ manifest.uuid | 2 +- src/vdbe.c | 82 ++++++++++++++++++++++++++------------------------- src/vdbeaux.c | 21 ++++++------- src/vdbemem.c | 2 +- 5 files changed, 67 insertions(+), 61 deletions(-) diff --git a/manifest b/manifest index 847bc79890..dc84917b98 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sexclusive.test\sso\sthat\sit\sworks\swith\s-DSQLITE_TEMP_STORE=3. -D 2016-03-19T18:11:59.750 +C Change\sthe\sVdbe.aMem\sarray\sso\sthat\sit\sis\szero-based\sinstead\sof\sone-based. +D 2016-03-19T23:32:59.000 F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66 @@ -417,13 +417,13 @@ F src/update.c 56b3db7edff0110360a12b76af97c39ebe3ea8b8 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 34ef7be420f82415ec48131404995ddb6ee7502f F src/vacuum.c feb1eabb20987983d9350cad98299b21fa811f52 -F src/vdbe.c 8cf45bb8da77d39f55d108e759d15a57acd0255c +F src/vdbe.c 90d18d0a91284092a099e9a048982df38920190c F src/vdbe.h 6f44193e7be52fd5f7c308175a936555b1e6b101 F src/vdbeInt.h f88d3115e9bde33b01d81f0dd26d8dd51f995991 F src/vdbeapi.c 95b1f8e527240a18a9aea41a655b013bf07a7009 -F src/vdbeaux.c a930f913d40e4ca6f6caaef6a7b5906a369fa2b1 +F src/vdbeaux.c 4a38b9f9dab7350f670b9efff25f605933f81963 F src/vdbeblob.c 3b570b730109e8f653d9d2081649f6e7015113db -F src/vdbemem.c 9b0cb32cc267ef026515f15a3594d5ff91fe4dfc +F src/vdbemem.c fe76c1f866de362d9b8332e59d74aa44f6560d69 F src/vdbesort.c 307460bfa4de4d1c3901fcd42089159131e34062 F src/vdbetrace.c f75c5455d8cf389ef86a8bfdfd3177e0e3692484 F src/vtab.c fd69fd398e23e57ea4ea377d8a44b6998fc569c7 @@ -1457,7 +1457,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P f095341471aa822e6d556cb65512ec081c3918da -R eda7e2fd58d6241fa97b2fe69addd6c1 -U dan -Z fdac7ca02eef2361aeb61c0eeeaed018 +P d7852c639683a1d305a1e731df3cccafa64b594b +R 4a4c5282463bb7b6f1f36414c3f19a6f +T *branch * zero-base-aMem +T *sym-zero-base-aMem * +T -sym-trunk * +U drh +Z 5ba539d03a989ddc8c4359f1a3ede74d diff --git a/manifest.uuid b/manifest.uuid index 378b71e1fc..24fae6a151 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d7852c639683a1d305a1e731df3cccafa64b594b \ No newline at end of file +e07b0c47eb5a39623f5fe0e66b939bba0906691c \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 6f4ac5713d..bdab41b6b6 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -192,11 +192,11 @@ static VdbeCursor *allocateCursor( ** be freed lazily via the sqlite3_release_memory() API. This ** minimizes the number of malloc calls made by the system. ** - ** Memory cells for cursors are allocated at the top of the address - ** space. Memory cell (p->nMem) corresponds to cursor 0. Space for - ** cursor 1 is managed by memory cell (p->nMem-1), etc. + ** Memory cell for cursor 0 is Mem[0]. The rest are allocated from + ** the top of the register space. Cursor 1 is at Mem[p->nMem-1]. + ** Cursor 2 is at Mem[p->nMem-2]. And so forth. */ - Mem *pMem = &p->aMem[p->nMem-iCur]; + Mem *pMem = iCur>0 ? &p->aMem[p->nMem-iCur] : p->aMem; int nByte; VdbeCursor *pCx = 0; @@ -204,7 +204,7 @@ static VdbeCursor *allocateCursor( ROUND8(sizeof(VdbeCursor)) + 2*sizeof(u32)*nField + (eCurType==CURTYPE_BTREE?sqlite3BtreeCursorSize():0); - assert( iCurnCursor ); + assert( iCur>=0 && iCurnCursor ); if( p->apCsr[iCur] ){ sqlite3VdbeFreeCursor(p, p->apCsr[iCur]); p->apCsr[iCur] = 0; @@ -529,7 +529,7 @@ static SQLITE_NOINLINE Mem *out2PrereleaseWithClear(Mem *pOut){ static Mem *out2Prerelease(Vdbe *p, VdbeOp *pOp){ Mem *pOut; assert( pOp->p2>0 ); - assert( pOp->p2<=(p->nMem-p->nCursor) ); + assert( pOp->p2<=(p->nMem+1 - p->nCursor) ); pOut = &p->aMem[pOp->p2]; memAboutToChange(p, pOut); if( VdbeMemDynamic(pOut) ){ @@ -667,33 +667,33 @@ int sqlite3VdbeExec( assert( pOp->opflags==sqlite3OpcodeProperty[pOp->opcode] ); if( (pOp->opflags & OPFLG_IN1)!=0 ){ assert( pOp->p1>0 ); - assert( pOp->p1<=(p->nMem-p->nCursor) ); + assert( pOp->p1<=(p->nMem+1 - p->nCursor) ); assert( memIsValid(&aMem[pOp->p1]) ); assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p1]) ); REGISTER_TRACE(pOp->p1, &aMem[pOp->p1]); } if( (pOp->opflags & OPFLG_IN2)!=0 ){ assert( pOp->p2>0 ); - assert( pOp->p2<=(p->nMem-p->nCursor) ); + assert( pOp->p2<=(p->nMem+1 - p->nCursor) ); assert( memIsValid(&aMem[pOp->p2]) ); assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p2]) ); REGISTER_TRACE(pOp->p2, &aMem[pOp->p2]); } if( (pOp->opflags & OPFLG_IN3)!=0 ){ assert( pOp->p3>0 ); - assert( pOp->p3<=(p->nMem-p->nCursor) ); + assert( pOp->p3<=(p->nMem+1 - p->nCursor) ); assert( memIsValid(&aMem[pOp->p3]) ); assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p3]) ); REGISTER_TRACE(pOp->p3, &aMem[pOp->p3]); } if( (pOp->opflags & OPFLG_OUT2)!=0 ){ assert( pOp->p2>0 ); - assert( pOp->p2<=(p->nMem-p->nCursor) ); + assert( pOp->p2<=(p->nMem+1 - p->nCursor) ); memAboutToChange(p, &aMem[pOp->p2]); } if( (pOp->opflags & OPFLG_OUT3)!=0 ){ assert( pOp->p3>0 ); - assert( pOp->p3<=(p->nMem-p->nCursor) ); + assert( pOp->p3<=(p->nMem+1 - p->nCursor) ); memAboutToChange(p, &aMem[pOp->p3]); } #endif @@ -792,7 +792,7 @@ check_for_interrupt: ** and then jump to address P2. */ case OP_Gosub: { /* jump */ - assert( pOp->p1>0 && pOp->p1<=(p->nMem-p->nCursor) ); + assert( pOp->p1>0 && pOp->p1<=(p->nMem+1 - p->nCursor) ); pIn1 = &aMem[pOp->p1]; assert( VdbeMemDynamic(pIn1)==0 ); memAboutToChange(p, pIn1); @@ -832,7 +832,7 @@ case OP_Return: { /* in1 */ ** See also: EndCoroutine */ case OP_InitCoroutine: { /* jump */ - assert( pOp->p1>0 && pOp->p1<=(p->nMem-p->nCursor) ); + assert( pOp->p1>0 && pOp->p1<=(p->nMem+1 - p->nCursor) ); assert( pOp->p2>=0 && pOp->p2nOp ); assert( pOp->p3>=0 && pOp->p3nOp ); pOut = &aMem[pOp->p1]; @@ -1101,7 +1101,7 @@ case OP_String: { /* out2 */ #ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS if( pOp->p5 ){ assert( pOp->p3>0 ); - assert( pOp->p3<=(p->nMem-p->nCursor) ); + assert( pOp->p3<=(p->nMem+1 - p->nCursor) ); pIn3 = &aMem[pOp->p3]; assert( pIn3->flags & MEM_Int ); if( pIn3->u.i ) pOut->flags = MEM_Blob|MEM_Static|MEM_Term; @@ -1127,7 +1127,7 @@ case OP_Null: { /* out2 */ u16 nullFlag; pOut = out2Prerelease(p, pOp); cnt = pOp->p3-pOp->p2; - assert( pOp->p3<=(p->nMem-p->nCursor) ); + assert( pOp->p3<=(p->nMem+1 - p->nCursor) ); pOut->flags = nullFlag = pOp->p1 ? (MEM_Null|MEM_Cleared) : MEM_Null; while( cnt>0 ){ pOut++; @@ -1148,7 +1148,7 @@ case OP_Null: { /* out2 */ ** previously copied using OP_SCopy, the copies will continue to be valid. */ case OP_SoftNull: { - assert( pOp->p1>0 && pOp->p1<=(p->nMem-p->nCursor) ); + assert( pOp->p1>0 && pOp->p1<=(p->nMem+1 - p->nCursor) ); pOut = &aMem[pOp->p1]; pOut->flags = (pOut->flags|MEM_Null)&~MEM_Undefined; break; @@ -1215,8 +1215,8 @@ case OP_Move: { pIn1 = &aMem[p1]; pOut = &aMem[p2]; do{ - assert( pOut<=&aMem[(p->nMem-p->nCursor)] ); - assert( pIn1<=&aMem[(p->nMem-p->nCursor)] ); + assert( pOut<=&aMem[(p->nMem+1 - p->nCursor)] ); + assert( pIn1<=&aMem[(p->nMem+1 - p->nCursor)] ); assert( memIsValid(pIn1) ); memAboutToChange(p, pOut); sqlite3VdbeMemMove(pOut, pIn1); @@ -1316,7 +1316,7 @@ case OP_ResultRow: { int i; assert( p->nResColumn==pOp->p2 ); assert( pOp->p1>0 ); - assert( pOp->p1+pOp->p2<=(p->nMem-p->nCursor)+1 ); + assert( pOp->p1+pOp->p2<=(p->nMem+1 - p->nCursor)+1 ); #ifndef SQLITE_OMIT_PROGRESS_CALLBACK /* Run the progress counter just before returning. @@ -1628,8 +1628,8 @@ case OP_Function0: { assert( pOp->p4type==P4_FUNCDEF ); n = pOp->p5; - assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); - assert( n==0 || (pOp->p2>0 && pOp->p2+n<=(p->nMem-p->nCursor)+1) ); + assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) ); + assert( n==0 || (pOp->p2>0 && pOp->p2+n<=(p->nMem+1 - p->nCursor)+1) ); assert( pOp->p3p2 || pOp->p3>=pOp->p2+n ); pCtx = sqlite3DbMallocRawNN(db, sizeof(*pCtx) + (n-1)*sizeof(sqlite3_value*)); if( pCtx==0 ) goto no_mem; @@ -2129,11 +2129,11 @@ case OP_Compare: { if( aPermute ){ int k, mx = 0; for(k=0; kmx ) mx = aPermute[k]; - assert( p1>0 && p1+mx<=(p->nMem-p->nCursor)+1 ); - assert( p2>0 && p2+mx<=(p->nMem-p->nCursor)+1 ); + assert( p1>0 && p1+mx<=(p->nMem+1 - p->nCursor)+1 ); + assert( p2>0 && p2+mx<=(p->nMem+1 - p->nCursor)+1 ); }else{ - assert( p1>0 && p1+n<=(p->nMem-p->nCursor)+1 ); - assert( p2>0 && p2+n<=(p->nMem-p->nCursor)+1 ); + assert( p1>0 && p1+n<=(p->nMem+1 - p->nCursor)+1 ); + assert( p2>0 && p2+n<=(p->nMem+1 - p->nCursor)+1 ); } #endif /* SQLITE_DEBUG */ for(i=0; ip3>0 && pOp->p3<=(p->nMem-p->nCursor) ); + assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) ); pDest = &aMem[pOp->p3]; memAboutToChange(p, pDest); assert( pOp->p1>=0 && pOp->p1nCursor ); @@ -2638,7 +2638,7 @@ case OP_Affinity: { assert( zAffinity[pOp->p2]==0 ); pIn1 = &aMem[pOp->p1]; while( (cAff = *(zAffinity++))!=0 ){ - assert( pIn1 <= &p->aMem[(p->nMem-p->nCursor)] ); + assert( pIn1 <= &p->aMem[(p->nMem+1 - p->nCursor)] ); assert( memIsValid(pIn1) ); applyAffinity(pIn1, cAff, encoding); pIn1++; @@ -2700,7 +2700,7 @@ case OP_MakeRecord: { nZero = 0; /* Number of zero bytes at the end of the record */ nField = pOp->p1; zAffinity = pOp->p4.z; - assert( nField>0 && pOp->p2>0 && pOp->p2+nField<=(p->nMem-p->nCursor)+1 ); + assert( nField>0 && pOp->p2>0 && pOp->p2+nField<=(p->nMem+1 - p->nCursor)+1 ); pData0 = &aMem[nField]; nField = pOp->p2; pLast = &pData0[nField-1]; @@ -2790,7 +2790,7 @@ case OP_MakeRecord: { assert( i==nHdr ); assert( j==nByte ); - assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); + assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) ); pOut->n = (int)nByte; pOut->flags = MEM_Blob; if( nZero ){ @@ -3376,7 +3376,7 @@ case OP_OpenWrite: } if( pOp->p5 & OPFLAG_P2ISREG ){ assert( p2>0 ); - assert( p2<=(p->nMem-p->nCursor) ); + assert( p2<=(p->nMem+1 - p->nCursor) ); pIn2 = &aMem[p2]; assert( memIsValid(pIn2) ); assert( (pIn2->flags & MEM_Int)!=0 ); @@ -4171,7 +4171,7 @@ case OP_NewRowid: { /* out2 */ pMem = &pFrame->aMem[pOp->p3]; }else{ /* Assert that P3 is a valid memory cell. */ - assert( pOp->p3<=(p->nMem-p->nCursor) ); + assert( pOp->p3<=(p->nMem+1 - p->nCursor) ); pMem = &aMem[pOp->p3]; memAboutToChange(p, pMem); } @@ -4947,7 +4947,7 @@ case OP_IdxDelete: { UnpackedRecord r; assert( pOp->p3>0 ); - assert( pOp->p2>0 && pOp->p2+pOp->p3<=(p->nMem-p->nCursor)+1 ); + assert( pOp->p2>0 && pOp->p2+pOp->p3<=(p->nMem+1 - p->nCursor)+1 ); assert( pOp->p1>=0 && pOp->p1nCursor ); pC = p->apCsr[pOp->p1]; assert( pC!=0 ); @@ -5453,7 +5453,7 @@ case OP_IntegrityCk: { aRoot = pOp->p4.ai; assert( nRoot>0 ); assert( aRoot[nRoot]==0 ); - assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); + assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) ); pnErr = &aMem[pOp->p3]; assert( (pnErr->flags & MEM_Int)!=0 ); assert( (pnErr->flags & (MEM_Str|MEM_Blob))==0 ); @@ -5643,6 +5643,7 @@ case OP_Program: { /* jump */ ** variable nMem (and later, VdbeFrame.nChildMem) to this value. */ nMem = pProgram->nMem + pProgram->nCsr; + if( pProgram->nCsr==0 && nMem>0 ) nMem++; nByte = ROUND8(sizeof(VdbeFrame)) + nMem * sizeof(Mem) + pProgram->nCsr * sizeof(VdbeCursor *) @@ -5679,7 +5680,8 @@ case OP_Program: { /* jump */ } }else{ pFrame = pRt->u.pFrame; - assert( pProgram->nMem+pProgram->nCsr==pFrame->nChildMem ); + assert( pProgram->nMem+pProgram->nCsr==pFrame->nChildMem + || (pProgram->nCsr==0 && pProgram->nMem+1==pFrame->nChildMem) ); assert( pProgram->nCsr==pFrame->nChildCsr ); assert( (int)(pOp - aOp)==pFrame->pc ); } @@ -5694,10 +5696,10 @@ case OP_Program: { /* jump */ p->pAuxData = 0; p->nChange = 0; p->pFrame = pFrame; - p->aMem = aMem = &VdbeFrameMem(pFrame)[-1]; + p->aMem = aMem = VdbeFrameMem(pFrame); p->nMem = pFrame->nChildMem; p->nCursor = (u16)pFrame->nChildCsr; - p->apCsr = (VdbeCursor **)&aMem[p->nMem+1]; + p->apCsr = (VdbeCursor **)&aMem[p->nMem]; p->aOp = aOp = pProgram->aOp; p->nOp = pProgram->nOp; p->aOnceFlag = (u8 *)&p->apCsr[p->nCursor]; @@ -5943,8 +5945,8 @@ case OP_AggStep0: { assert( pOp->p4type==P4_FUNCDEF ); n = pOp->p5; - assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); - assert( n==0 || (pOp->p2>0 && pOp->p2+n<=(p->nMem-p->nCursor)+1) ); + assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) ); + assert( n==0 || (pOp->p2>0 && pOp->p2+n<=(p->nMem+1 - p->nCursor)+1) ); assert( pOp->p3p2 || pOp->p3>=pOp->p2+n ); pCtx = sqlite3DbMallocRawNN(db, sizeof(*pCtx) + (n-1)*sizeof(sqlite3_value*)); if( pCtx==0 ) goto no_mem; @@ -6023,7 +6025,7 @@ case OP_AggStep: { */ case OP_AggFinal: { Mem *pMem; - assert( pOp->p1>0 && pOp->p1<=(p->nMem-p->nCursor) ); + assert( pOp->p1>0 && pOp->p1<=(p->nMem+1 - p->nCursor) ); pMem = &aMem[pOp->p1]; assert( (pMem->flags & ~(MEM_Null|MEM_Agg))==0 ); rc = sqlite3VdbeMemFinalize(pMem, pOp->p4.pFunc); @@ -6465,7 +6467,7 @@ case OP_VColumn: { VdbeCursor *pCur = p->apCsr[pOp->p1]; assert( pCur->eCurType==CURTYPE_VTAB ); - assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); + assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) ); pDest = &aMem[pOp->p3]; memAboutToChange(p, pDest); if( pCur->nullRow ){ diff --git a/src/vdbeaux.c b/src/vdbeaux.c index c71605cdd2..75307c258e 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -1801,7 +1801,7 @@ void sqlite3VdbeRewind(Vdbe *p){ p->magic = VDBE_MAGIC_RUN; #ifdef SQLITE_DEBUG - for(i=1; inMem; i++){ + for(i=0; inMem; i++){ assert( p->aMem[i].db==p->db ); } #endif @@ -1866,16 +1866,18 @@ void sqlite3VdbeMakeReady( nOnce = pParse->nOnce; if( nOnce==0 ) nOnce = 1; /* Ensure at least one byte in p->aOnceFlag[] */ - /* For each cursor required, also allocate a memory cell. Memory - ** cells (nMem+1-nCursor)..nMem, inclusive, will never be used by + /* For each cursor required, also allocate a memory cell. Memory + ** cells 0 and (nMem-nCursor)..nMem-1 inclusive will never be used by ** the vdbe program. Instead they are used to allocate memory for ** VdbeCursor/BtCursor structures. The blob of memory associated with - ** cursor 0 is stored in memory cell nMem. Memory cell (nMem-1) - ** stores the blob of memory associated with cursor 1, etc. + ** cursor 0 is stored in memory cell 0. Memory cell (nMem-1) + ** stores the blob of memory associated with cursor 1. Memory cell + ** (nMem-iCur) is used for cursor iCur. ** ** See also: allocateCursor(). */ nMem += nCursor; + if( nCursor==0 && nMem>0 ) nMem++; /* Space for aMem[0] even if not used */ /* Figure out how much reusable memory is available at the end of the ** opcode array. This extra memory will be reallocated for other elements @@ -1937,9 +1939,8 @@ void sqlite3VdbeMakeReady( pParse->nzVar = 0; pParse->azVar = 0; if( p->aMem ){ - p->aMem--; /* aMem[] goes from 1..nMem */ - p->nMem = nMem; /* not from 0..nMem-1 */ - for(n=1; n<=nMem; n++){ + p->nMem = nMem; + for(n=0; naMem[n].flags = MEM_Undefined; p->aMem[n].db = db; } @@ -2049,7 +2050,7 @@ static void closeAllCursors(Vdbe *p){ assert( p->nFrame==0 ); closeCursorsInFrame(p); if( p->aMem ){ - releaseMemArray(&p->aMem[1], p->nMem); + releaseMemArray(p->aMem, p->nMem); } while( p->pDelFrame ){ VdbeFrame *pDel = p->pDelFrame; @@ -2074,7 +2075,7 @@ static void Cleanup(Vdbe *p){ int i; if( p->apCsr ) for(i=0; inCursor; i++) assert( p->apCsr[i]==0 ); if( p->aMem ){ - for(i=1; i<=p->nMem; i++) assert( p->aMem[i].flags==MEM_Undefined ); + for(i=0; inMem; i++) assert( p->aMem[i].flags==MEM_Undefined ); } #endif diff --git a/src/vdbemem.c b/src/vdbemem.c index b5139fe32e..2c03baf562 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -761,7 +761,7 @@ int sqlite3VdbeMemTooBig(Mem *p){ void sqlite3VdbeMemAboutToChange(Vdbe *pVdbe, Mem *pMem){ int i; Mem *pX; - for(i=1, pX=&pVdbe->aMem[1]; i<=pVdbe->nMem; i++, pX++){ + for(i=0, pX=pVdbe->aMem; inMem; i++, pX++){ if( pX->pScopyFrom==pMem ){ pX->flags |= MEM_Undefined; pX->pScopyFrom = 0; From 3cdce92c3863567d49f149f6b736c4987acf5fec Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 21 Mar 2016 00:30:40 +0000 Subject: [PATCH 0185/1484] Remove an unreachable branch. Improvements to comments. FossilOrigin-Name: c5677ecd5cd2637d92a831ec6bd5b002f8d75626 --- manifest | 17 +++++++---------- manifest.uuid | 2 +- src/vdbe.c | 5 +++-- src/vdbeaux.c | 11 +++-------- 4 files changed, 14 insertions(+), 21 deletions(-) diff --git a/manifest b/manifest index dc84917b98..24f48cdd5b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sthe\sVdbe.aMem\sarray\sso\sthat\sit\sis\szero-based\sinstead\sof\sone-based. -D 2016-03-19T23:32:59.000 +C Remove\san\sunreachable\sbranch.\s\sImprovements\sto\scomments. +D 2016-03-21T00:30:40.611 F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66 @@ -417,11 +417,11 @@ F src/update.c 56b3db7edff0110360a12b76af97c39ebe3ea8b8 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 34ef7be420f82415ec48131404995ddb6ee7502f F src/vacuum.c feb1eabb20987983d9350cad98299b21fa811f52 -F src/vdbe.c 90d18d0a91284092a099e9a048982df38920190c +F src/vdbe.c 3b542ffd5b6aaab55255ec3801fc86dcbfaea543 F src/vdbe.h 6f44193e7be52fd5f7c308175a936555b1e6b101 F src/vdbeInt.h f88d3115e9bde33b01d81f0dd26d8dd51f995991 F src/vdbeapi.c 95b1f8e527240a18a9aea41a655b013bf07a7009 -F src/vdbeaux.c 4a38b9f9dab7350f670b9efff25f605933f81963 +F src/vdbeaux.c c8dd3e4e932bede6363b380519d05c0557ad27ce F src/vdbeblob.c 3b570b730109e8f653d9d2081649f6e7015113db F src/vdbemem.c fe76c1f866de362d9b8332e59d74aa44f6560d69 F src/vdbesort.c 307460bfa4de4d1c3901fcd42089159131e34062 @@ -1457,10 +1457,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d7852c639683a1d305a1e731df3cccafa64b594b -R 4a4c5282463bb7b6f1f36414c3f19a6f -T *branch * zero-base-aMem -T *sym-zero-base-aMem * -T -sym-trunk * +P e07b0c47eb5a39623f5fe0e66b939bba0906691c +R 3918e948fd7d72bc109c3b7a0fa018f3 U drh -Z 5ba539d03a989ddc8c4359f1a3ede74d +Z ae546b517b9c79f405f4513ed17a526d diff --git a/manifest.uuid b/manifest.uuid index 24fae6a151..7cf8597f25 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e07b0c47eb5a39623f5fe0e66b939bba0906691c \ No newline at end of file +c5677ecd5cd2637d92a831ec6bd5b002f8d75626 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index bdab41b6b6..52747ce8ba 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -192,7 +192,7 @@ static VdbeCursor *allocateCursor( ** be freed lazily via the sqlite3_release_memory() API. This ** minimizes the number of malloc calls made by the system. ** - ** Memory cell for cursor 0 is Mem[0]. The rest are allocated from + ** The memory cell for cursor 0 is aMem[0]. The rest are allocated from ** the top of the register space. Cursor 1 is at Mem[p->nMem-1]. ** Cursor 2 is at Mem[p->nMem-2]. And so forth. */ @@ -5643,7 +5643,8 @@ case OP_Program: { /* jump */ ** variable nMem (and later, VdbeFrame.nChildMem) to this value. */ nMem = pProgram->nMem + pProgram->nCsr; - if( pProgram->nCsr==0 && nMem>0 ) nMem++; + assert( nMem>0 ); + if( pProgram->nCsr==0 ) nMem++; nByte = ROUND8(sizeof(VdbeFrame)) + nMem * sizeof(Mem) + pProgram->nCsr * sizeof(VdbeCursor *) diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 75307c258e..e651589ace 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -1866,14 +1866,9 @@ void sqlite3VdbeMakeReady( nOnce = pParse->nOnce; if( nOnce==0 ) nOnce = 1; /* Ensure at least one byte in p->aOnceFlag[] */ - /* For each cursor required, also allocate a memory cell. Memory - ** cells 0 and (nMem-nCursor)..nMem-1 inclusive will never be used by - ** the vdbe program. Instead they are used to allocate memory for - ** VdbeCursor/BtCursor structures. The blob of memory associated with - ** cursor 0 is stored in memory cell 0. Memory cell (nMem-1) - ** stores the blob of memory associated with cursor 1. Memory cell - ** (nMem-iCur) is used for cursor iCur. - ** + /* Each cursor uses a memory cell. The first cursor (cursor 0) can + ** use aMem[0] which is not otherwise used by the VDBE program. Allocate + ** space at the end of aMem[] for cursors 1 and greater. ** See also: allocateCursor(). */ nMem += nCursor; From ef480d37dcc22f4da07d797341c96462f61f9e91 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 21 Mar 2016 09:56:19 +0000 Subject: [PATCH 0186/1484] Change the way fts5 internally allocates segment ids in order to eliminated non-determinism from the module. FossilOrigin-Name: d6e2637df16764aa9723a30ea2eb8a631d28cb2b --- ext/fts5/fts5_index.c | 39 +++++++++++++++++++++++++++--------- ext/fts5/tool/fts5txt2db.tcl | 5 +++-- manifest | 17 ++++++++-------- manifest.uuid | 2 +- 4 files changed, 41 insertions(+), 22 deletions(-) diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index 323e6cefdc..44fba94c84 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -3453,18 +3453,35 @@ static int fts5AllocateSegid(Fts5Index *p, Fts5Structure *pStruct){ if( pStruct->nSegment>=FTS5_MAX_SEGMENT ){ p->rc = SQLITE_FULL; }else{ - while( iSegid==0 ){ - int iLvl, iSeg; - sqlite3_randomness(sizeof(u32), (void*)&iSegid); - iSegid = iSegid & ((1 << FTS5_DATA_ID_B)-1); - for(iLvl=0; iLvlnLevel; iLvl++){ - for(iSeg=0; iSegaLevel[iLvl].nSeg; iSeg++){ - if( iSegid==pStruct->aLevel[iLvl].aSeg[iSeg].iSegid ){ - iSegid = 0; - } + /* FTS5_MAX_SEGMENT is currently defined as 2000. So the following + ** array is 63 elements, or 252 bytes, in size. */ + u32 aUsed[(FTS5_MAX_SEGMENT+31) / 32]; + int iLvl, iSeg; + int i; + u32 mask; + memset(aUsed, 0, sizeof(aUsed)); + for(iLvl=0; iLvlnLevel; iLvl++){ + for(iSeg=0; iSegaLevel[iLvl].nSeg; iSeg++){ + int iId = pStruct->aLevel[iLvl].aSeg[iSeg].iSegid; + if( iId<=FTS5_MAX_SEGMENT ){ + aUsed[(iId-1) / 32] |= 1 << ((iId-1) % 32); } } } + + for(i=0; aUsed[i]==0xFFFFFFFF; i++); + mask = aUsed[i]; + for(iSegid=0; mask & (1 << iSegid); iSegid++); + iSegid += 1 + i*32; + +#ifdef SQLITE_DEBUG + for(iLvl=0; iLvlnLevel; iLvl++){ + for(iSeg=0; iSegaLevel[iLvl].nSeg; iSeg++){ + assert( iSegid!=pStruct->aLevel[iLvl].aSeg[iSeg].iSegid ); + } + } + assert( iSegid>0 && iSegid<=FTS5_MAX_SEGMENT ); +#endif } } @@ -3909,7 +3926,9 @@ static void fts5WriteFinish( fts5WriteFlushLeaf(p, pWriter); } *pnLeaf = pLeaf->pgno-1; - fts5WriteFlushBtree(p, pWriter); + if( pLeaf->pgno>1 ){ + fts5WriteFlushBtree(p, pWriter); + } } fts5BufferFree(&pLeaf->term); fts5BufferFree(&pLeaf->buf); diff --git a/ext/fts5/tool/fts5txt2db.tcl b/ext/fts5/tool/fts5txt2db.tcl index d5df971d4d..4766b00b06 100644 --- a/ext/fts5/tool/fts5txt2db.tcl +++ b/ext/fts5/tool/fts5txt2db.tcl @@ -17,6 +17,7 @@ proc process_cmdline {} { {detail "full" "Fts5 detail mode to use"} {repeat 1 "Load each file this many times"} {prefix "" "Fts prefix= option"} + {trans 1 "True to use a transaction"} database file... } { @@ -214,7 +215,7 @@ foreach c [lrange $cols 1 end] { } append sql ")" -db eval BEGIN +if {$A(trans)} { db eval BEGIN } while {$i < $N} { foreach c $cols s $A(colsize) { set R($c) [lrange $tokens $i [expr $i+$s-1]] @@ -222,7 +223,7 @@ db eval BEGIN } db eval $sql } -db eval COMMIT +if {$A(trans)} { db eval COMMIT } diff --git a/manifest b/manifest index 0773bab205..b4be055c28 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sthe\sVdbe.aMem\sarray\sso\sthat\sit\sis\szero-based\sinstead\sof\sone-based. -D 2016-03-21T00:38:59.802 +C Change\sthe\sway\sfts5\sinternally\sallocates\ssegment\sids\sin\sorder\sto\seliminated\snon-determinism\sfrom\sthe\smodule. +D 2016-03-21T09:56:19.361 F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66 @@ -104,7 +104,7 @@ F ext/fts5/fts5_buffer.c 4c1502d4c956cd092c89ce4480867f9d8bf325cd F ext/fts5/fts5_config.c 5af9c360e99669d29f06492c370892394aba0857 F ext/fts5/fts5_expr.c 35e9d92c89e7c7ea0759b73d24da1ecb7630a24b F ext/fts5/fts5_hash.c f3a7217c86eb8f272871be5f6aa1b6798960a337 -F ext/fts5/fts5_index.c d4f0c12e4f04bbc3a06b6da052039f2ce3e45438 +F ext/fts5/fts5_index.c d3759c2f7d878e9e0a392b027a1c6e05c356007d F ext/fts5/fts5_main.c b8501e1a6a11591c53b18ce7aea7e5386cfb0421 F ext/fts5/fts5_storage.c 2a38c6fa5db193a6a00588865134450ef5812daa F ext/fts5/fts5_tcl.c f8731e0508299bd43f1a2eff7dbeaac870768966 @@ -194,7 +194,7 @@ F ext/fts5/test/fts5update.test 57c7012a7919889048947addae10e0613df45529 F ext/fts5/test/fts5version.test 978f59541d8cef7e8591f8be2115ec5ccb863e2e F ext/fts5/test/fts5vocab.test 480d780aa6b699816c5066225fbd86f3a0239477 F ext/fts5/tool/fts5speed.tcl b0056f91a55b2d1a3684ec05729de92b042e2f85 -F ext/fts5/tool/fts5txt2db.tcl 1343745b89ca2a1e975c23f836d0cee410052975 +F ext/fts5/tool/fts5txt2db.tcl 526a9979c963f1c54fd50976a05a502e533a4c59 F ext/fts5/tool/loadfts5.tcl 95b03429ee6b138645703c6ca192c3ac96eaf093 F ext/fts5/tool/mkfts5c.tcl d1c2a9ab8e0ec690a52316f33dd9b1d379942f45 F ext/fts5/tool/showfts5.tcl d54da0e067306663e2d5d523965ca487698e722c @@ -1457,8 +1457,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d7852c639683a1d305a1e731df3cccafa64b594b c5677ecd5cd2637d92a831ec6bd5b002f8d75626 -R 3918e948fd7d72bc109c3b7a0fa018f3 -T +closed c5677ecd5cd2637d92a831ec6bd5b002f8d75626 -U drh -Z 542f0ebd1ebe0cc42b5001043dab2846 +P c39081e878faccc8552141afa5732a2bf2f77570 +R b7f851b6f7c0c6dc2d06642c2058dff4 +U dan +Z 052aba56922a1e224a7195cfbf595d27 diff --git a/manifest.uuid b/manifest.uuid index d4e8a322fa..775d397701 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c39081e878faccc8552141afa5732a2bf2f77570 \ No newline at end of file +d6e2637df16764aa9723a30ea2eb8a631d28cb2b \ No newline at end of file From 8d2f41ccd2945061d4e1d0e4bf82ef8937637c82 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 21 Mar 2016 11:38:01 +0000 Subject: [PATCH 0187/1484] Do a better job of capturing all system errno values regardless of when they occur. FossilOrigin-Name: 7d49998d571d841a6d1b55f5f9889e613daaab2a --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/main.c | 1 - src/util.c | 7 ++++++- 4 files changed, 14 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 23d5324bc8..535a69183e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\supdates\sfrom\strunk. -D 2016-03-21T10:49:49.647 +C Do\sa\sbetter\sjob\sof\scapturing\sall\ssystem\serrno\svalues\sregardless\sof\swhen\nthey\soccur. +D 2016-03-21T11:38:01.899 F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66 @@ -316,7 +316,7 @@ F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 F src/insert.c 723d5d708cdb61bdd47c00b9f07c75be45aefc09 F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e F src/loadext.c e70f8f9e97624a232870ea5486e682c813ac3002 -F src/main.c 74591e0405e5e71b276105ac5f8d419dd54e6495 +F src/main.c f6c6e61bfd4cc9306a737d0c5c3f1e0eaf6086e0 F src/malloc.c 1443d1ad95d67c21d77af7ae3f44678252f0efec F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b @@ -415,7 +415,7 @@ F src/treeview.c e4b41a37530a191579d3c53142cc44ee2eb99373 F src/trigger.c e14840ee0c3e549e758ec9bf3e4146e166002280 F src/update.c 56b3db7edff0110360a12b76af97c39ebe3ea8b8 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c -F src/util.c c3fc5193e6f039fa61afbcc0db87d5a5d563a18a +F src/util.c 161266913716ec2b35cf477239d3bdf1e2038305 F src/vacuum.c feb1eabb20987983d9350cad98299b21fa811f52 F src/vdbe.c 3b542ffd5b6aaab55255ec3801fc86dcbfaea543 F src/vdbe.h 6f44193e7be52fd5f7c308175a936555b1e6b101 @@ -1457,7 +1457,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 1602f6b53698bd3a1a4be218c2e3145dd895f1f1 d6e2637df16764aa9723a30ea2eb8a631d28cb2b -R 612a3877b08babb8ce38fd27cb203dde +P 86ab8643969bd2e51a257d80da9316c668437f7b +R 79a2efa83ad9e99707ee54a3ce3858c7 U drh -Z a4bea0f6db7341ce1f534f224a30953a +Z deb9ef153d45658bc99716f0bcf98cb3 diff --git a/manifest.uuid b/manifest.uuid index a54112ab69..9ddd083acd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -86ab8643969bd2e51a257d80da9316c668437f7b \ No newline at end of file +7d49998d571d841a6d1b55f5f9889e613daaab2a \ No newline at end of file diff --git a/src/main.c b/src/main.c index e4d5cb494c..2e5ba08393 100644 --- a/src/main.c +++ b/src/main.c @@ -2868,7 +2868,6 @@ static int openDatabase( if( rc==SQLITE_IOERR_NOMEM ){ rc = SQLITE_NOMEM_BKPT; } - sqlite3SystemError(db, rc); sqlite3Error(db, rc); goto opendb_out; } diff --git a/src/util.c b/src/util.c index 0a705a6a6e..b231342916 100644 --- a/src/util.c +++ b/src/util.c @@ -120,10 +120,14 @@ const char *sqlite3StrNext(const char *z){ /* ** Set the current error code to err_code and clear any prior error message. */ +static SQLITE_NOINLINE void sqlite3ErrorFinish(sqlite3 *db, int err_code){ + if( db->pErr ) sqlite3ValueSetNull(db->pErr); + sqlite3SystemError(db, err_code); +} void sqlite3Error(sqlite3 *db, int err_code){ assert( db!=0 ); db->errCode = err_code; - if( db->pErr ) sqlite3ValueSetNull(db->pErr); + if( err_code || db->pErr ) sqlite3ErrorFinish(db, err_code); } /* @@ -162,6 +166,7 @@ void sqlite3SystemError(sqlite3 *db, int rc){ void sqlite3ErrorWithMsg(sqlite3 *db, int err_code, const char *zFormat, ...){ assert( db!=0 ); db->errCode = err_code; + sqlite3SystemError(db, err_code); if( zFormat==0 ){ sqlite3Error(db, err_code); }else if( db->pErr || (db->pErr = sqlite3ValueNew(db))!=0 ){ From 80fbee092ed6f2316fde79caeda7ef5684c9f020 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 21 Mar 2016 11:57:13 +0000 Subject: [PATCH 0188/1484] Improved comments. No logical changes to code. FossilOrigin-Name: a6b6c6c466f3feb257b4fc08ef6b9a27a68ca073 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/util.c | 10 +++++++++- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 535a69183e..9f56848d53 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Do\sa\sbetter\sjob\sof\scapturing\sall\ssystem\serrno\svalues\sregardless\sof\swhen\nthey\soccur. -D 2016-03-21T11:38:01.899 +C Improved\scomments.\s\sNo\slogical\schanges\sto\scode. +D 2016-03-21T11:57:13.971 F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66 @@ -415,7 +415,7 @@ F src/treeview.c e4b41a37530a191579d3c53142cc44ee2eb99373 F src/trigger.c e14840ee0c3e549e758ec9bf3e4146e166002280 F src/update.c 56b3db7edff0110360a12b76af97c39ebe3ea8b8 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c -F src/util.c 161266913716ec2b35cf477239d3bdf1e2038305 +F src/util.c cf7dce85ab9af5280b8a45985df2591efbfefe56 F src/vacuum.c feb1eabb20987983d9350cad98299b21fa811f52 F src/vdbe.c 3b542ffd5b6aaab55255ec3801fc86dcbfaea543 F src/vdbe.h 6f44193e7be52fd5f7c308175a936555b1e6b101 @@ -1457,7 +1457,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 86ab8643969bd2e51a257d80da9316c668437f7b -R 79a2efa83ad9e99707ee54a3ce3858c7 +P 7d49998d571d841a6d1b55f5f9889e613daaab2a +R 2f9bb272499f0485ddab735cd0415aba U drh -Z deb9ef153d45658bc99716f0bcf98cb3 +Z ece300b1b257b87eefa9cd94f35c2874 diff --git a/manifest.uuid b/manifest.uuid index 9ddd083acd..3f5f26ea7b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7d49998d571d841a6d1b55f5f9889e613daaab2a \ No newline at end of file +a6b6c6c466f3feb257b4fc08ef6b9a27a68ca073 \ No newline at end of file diff --git a/src/util.c b/src/util.c index b231342916..428dfd046c 100644 --- a/src/util.c +++ b/src/util.c @@ -118,12 +118,20 @@ const char *sqlite3StrNext(const char *z){ } /* -** Set the current error code to err_code and clear any prior error message. +** Helper function for sqlite3Error() - called rarely. Broken out into +** a separate routine to avoid unnecessary register saves on entry to +** sqlite3Error(). */ static SQLITE_NOINLINE void sqlite3ErrorFinish(sqlite3 *db, int err_code){ if( db->pErr ) sqlite3ValueSetNull(db->pErr); sqlite3SystemError(db, err_code); } + +/* +** Set the current error code to err_code and clear any prior error message. +** Also set iSysErrno (by calling sqlite3System) if the err_code indicates +** that would be appropriate. +*/ void sqlite3Error(sqlite3 *db, int err_code){ assert( db!=0 ); db->errCode = err_code; From f68521c4e69c64633b60d59477ab83b2872db034 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 21 Mar 2016 12:28:02 +0000 Subject: [PATCH 0189/1484] Make sure system errors that occur durign sqlite3_step() are captured for use by sqlite3_system_errno(). FossilOrigin-Name: b4a1114f730c62e93623f889bc0e4fd8d0b31efa --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 9f56848d53..97d82ae77a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improved\scomments.\s\sNo\slogical\schanges\sto\scode. -D 2016-03-21T11:57:13.971 +C Make\ssure\ssystem\serrors\sthat\soccur\sdurign\ssqlite3_step()\sare\scaptured\sfor\nuse\sby\ssqlite3_system_errno(). +D 2016-03-21T12:28:02.060 F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66 @@ -417,7 +417,7 @@ F src/update.c 56b3db7edff0110360a12b76af97c39ebe3ea8b8 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c cf7dce85ab9af5280b8a45985df2591efbfefe56 F src/vacuum.c feb1eabb20987983d9350cad98299b21fa811f52 -F src/vdbe.c 3b542ffd5b6aaab55255ec3801fc86dcbfaea543 +F src/vdbe.c f19741f2d8b33e8f09cd2219570b6c9ed924c3f1 F src/vdbe.h 6f44193e7be52fd5f7c308175a936555b1e6b101 F src/vdbeInt.h f88d3115e9bde33b01d81f0dd26d8dd51f995991 F src/vdbeapi.c 95b1f8e527240a18a9aea41a655b013bf07a7009 @@ -1457,7 +1457,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 7d49998d571d841a6d1b55f5f9889e613daaab2a -R 2f9bb272499f0485ddab735cd0415aba +P a6b6c6c466f3feb257b4fc08ef6b9a27a68ca073 +R 6870e1f7d1e452978a882de2dd2b0506 U drh -Z ece300b1b257b87eefa9cd94f35c2874 +Z 3347e0ff1ad1a288a0d7114b0f195e81 diff --git a/manifest.uuid b/manifest.uuid index 3f5f26ea7b..c8872252d5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a6b6c6c466f3feb257b4fc08ef6b9a27a68ca073 \ No newline at end of file +b4a1114f730c62e93623f889bc0e4fd8d0b31efa \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 52747ce8ba..90269cbe30 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -6826,6 +6826,7 @@ abort_due_to_error: sqlite3VdbeError(p, "%s", sqlite3ErrStr(rc)); } p->rc = rc; + sqlite3SystemError(db, rc); testcase( sqlite3GlobalConfig.xLog!=0 ); sqlite3_log(rc, "statement aborts at %d: [%s] %s", (int)(pOp - aOp), p->zSql, p->zErrMsg); From 3c6707f72b6efeaa7b3933fae427010a444914cb Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 21 Mar 2016 15:18:13 +0000 Subject: [PATCH 0190/1484] Rearrange code so that tests pass whether SQLITE_DEBUG is defined or not. FossilOrigin-Name: 89296a46c3b891ee0b637ff6f89d828d6e46e7b5 --- ext/fts5/fts5_index.c | 15 +++++++-------- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index 3fb1458526..eb1d3c4b61 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -1019,17 +1019,14 @@ static i64 fts5IndexDataVersion(Fts5Index *p){ ** is called, it is a no-op. */ static Fts5Structure *fts5StructureRead(Fts5Index *p){ - Fts5Structure *pRet; /* Object to return */ if( p->pStruct==0 ){ p->iStructVersion = fts5IndexDataVersion(p); if( p->rc==SQLITE_OK ){ - p->pStruct = pRet = fts5StructureReadUncached(p); + p->pStruct = fts5StructureReadUncached(p); } - if( p->rc!=SQLITE_OK ) return 0; - assert( p->iStructVersion!=0 ); - assert( p->pStruct!=0 ); } + #ifdef SQLITE_DEBUG else{ Fts5Structure *pTest = fts5StructureReadUncached(p); @@ -1053,9 +1050,11 @@ static Fts5Structure *fts5StructureRead(Fts5Index *p){ } #endif - pRet = p->pStruct; - fts5StructureRef(pRet); - return pRet; + if( p->rc!=SQLITE_OK ) return 0; + assert( p->iStructVersion!=0 ); + assert( p->pStruct!=0 ); + fts5StructureRef(p->pStruct); + return p->pStruct; } static void fts5StructureInvalidate(Fts5Index *p){ diff --git a/manifest b/manifest index 346832e33f..65691a0210 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\stest\sfile\sfts5multiclient.test. -D 2016-03-19T14:47:28.441 +C Rearrange\scode\sso\sthat\stests\spass\swhether\sSQLITE_DEBUG\sis\sdefined\sor\snot. +D 2016-03-21T15:18:13.028 F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66 @@ -104,7 +104,7 @@ F ext/fts5/fts5_buffer.c 4c1502d4c956cd092c89ce4480867f9d8bf325cd F ext/fts5/fts5_config.c 5af9c360e99669d29f06492c370892394aba0857 F ext/fts5/fts5_expr.c 35e9d92c89e7c7ea0759b73d24da1ecb7630a24b F ext/fts5/fts5_hash.c f3a7217c86eb8f272871be5f6aa1b6798960a337 -F ext/fts5/fts5_index.c afac2ffe3198776626b99366e18af1f32ea9eb85 +F ext/fts5/fts5_index.c 39939320ee5185cbfd0a8c8c7e1c878ebde7c43d F ext/fts5/fts5_main.c b4a0fc5bf17f2f1f056ee76cdd7d2af08b360f55 F ext/fts5/fts5_storage.c a3361410422e69639ca2bcd5a56a0933dadf84d2 F ext/fts5/fts5_tcl.c f8731e0508299bd43f1a2eff7dbeaac870768966 @@ -1457,7 +1457,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 020a0bda59fe93b9361ceeed0d5a8ba4177380c8 -R f14c9b8edfca8f7bf113e7bd0b21996b +P 7832466f9177cca59455ba272802145297fcd53d +R e2f3ffc019af1c2320d4d618c0233909 U dan -Z d493def8e880a32e2aca451bc5e776cf +Z 04b6e502bb8ccbe0b89bf7d08daf8ee8 diff --git a/manifest.uuid b/manifest.uuid index 91ed807a0b..62bde4070e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7832466f9177cca59455ba272802145297fcd53d \ No newline at end of file +89296a46c3b891ee0b637ff6f89d828d6e46e7b5 \ No newline at end of file From 6369bc3fbb0e561b0df0f10f9c9601218388074a Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 21 Mar 2016 16:06:42 +0000 Subject: [PATCH 0191/1484] Remove an unreachable branch from the unlink verification logic in the UNIX VFS. FossilOrigin-Name: 4dc30cce7fdb7dba9a9aad96bb8b499b965610b2 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/os_unix.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 5d26916c17..2357dbffd8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Have\sfts5\scache\sthe\sstructure\sof\sits\sindex\sin\smain\smemory.\sUse\s"PRAGMA\sdata_version"\sto\sfigure\sout\swhen\sthis\scache\sshould\sbe\sinvalidated. -D 2016-03-21T15:30:50.247 +C Remove\san\sunreachable\sbranch\sfrom\sthe\sunlink\sverification\slogic\sin\sthe\sUNIX\nVFS. +D 2016-03-21T16:06:42.310 F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66 @@ -336,7 +336,7 @@ F src/os.c ca10edb445ad2c5fdc7285b49d72bcdf261fa23e F src/os.h 91ff889115ecd01f436d3611f7f5ea4dc12d92f1 F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85 F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa -F src/os_unix.c 50103f69121bca969761b821e2b0e393b55fe869 +F src/os_unix.c b1ccb273771f41dbdbe0ba7c1ad63c38ad5972ec F src/os_win.c 551d973ada67127430e41d9e514e53f6beb6c5a7 F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c 38718a019ca762ba4f6795425d5a54db70d1790d @@ -1458,7 +1458,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 4bd12b57ea177cfb1f44d54bfa7aedfb8a8c0c64 89296a46c3b891ee0b637ff6f89d828d6e46e7b5 -R 81b99f33bb0a77bc5e744352db10978f -U dan -Z db5fc495668353fb57116ffc2b5d2027 +P 902f221754f3cc6fb4ae049c135f85efce604ed3 +R 36c20d433515aed31fbc005a13e11c2d +U drh +Z 514dfe801f60757ebd0519594eb7ecde diff --git a/manifest.uuid b/manifest.uuid index fb9fd2a351..4d4fd3e0b6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -902f221754f3cc6fb4ae049c135f85efce604ed3 \ No newline at end of file +4dc30cce7fdb7dba9a9aad96bb8b499b965610b2 \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index d593b952f5..6d1bb0b46d 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -1366,7 +1366,7 @@ static void verifyDbFile(unixFile *pFile){ sqlite3_log(SQLITE_WARNING, "cannot fstat db file %s", pFile->zPath); return; } - if( buf.st_nlink==0 && (pFile->ctrlFlags & UNIXFILE_DELETE)==0 ){ + if( buf.st_nlink==0 ){ sqlite3_log(SQLITE_WARNING, "file unlinked while open: %s", pFile->zPath); return; } From 4567beefac9c044f9cb80f1c5c3ce1d565bb3c3f Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 21 Mar 2016 16:19:29 +0000 Subject: [PATCH 0192/1484] Skip recently added test cases in nolock.test when running in the inmemory_journal permutation. FossilOrigin-Name: a1dcf7af42bb7394d46138318f9367fe9e8be560 --- manifest | 12 +++++----- manifest.uuid | 2 +- test/nolock.test | 61 +++++++++++++++++++++++++----------------------- 3 files changed, 39 insertions(+), 36 deletions(-) diff --git a/manifest b/manifest index 2357dbffd8..78be64c56a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\san\sunreachable\sbranch\sfrom\sthe\sunlink\sverification\slogic\sin\sthe\sUNIX\nVFS. -D 2016-03-21T16:06:42.310 +C Skip\srecently\sadded\stest\scases\sin\snolock.test\swhen\srunning\sin\nthe\sinmemory_journal\spermutation. +D 2016-03-21T16:19:29.587 F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66 @@ -918,7 +918,7 @@ F test/multiplex4.test e8ae4c4bd70606a5727743241f13b5701990abe4 F test/mutex1.test ea2cc74d97f077b9e74c84cbd024f14d79a8126f F test/mutex2.test bfeaeac2e73095b2ac32285d2756e3a65e681660 F test/nan.test dacc57f80859c06a433d30839336fe227d2038b3 -F test/nolock.test 96e922d2d3db71c2dd6557c98e8027a28277b415 +F test/nolock.test f196cf8b8fbea4e2ca345140a2b3f3b0da45c76e F test/notify1.test 669b2b743618efdc18ca4b02f45423d5d2304abf F test/notify2.test 2ecabaa1305083856b7c39cf32816b612740c161 F test/notify3.test 10ff25cde502e72a92053a2f215d64bece4ef934 @@ -1458,7 +1458,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 902f221754f3cc6fb4ae049c135f85efce604ed3 -R 36c20d433515aed31fbc005a13e11c2d +P 4dc30cce7fdb7dba9a9aad96bb8b499b965610b2 +R 1f352d94053f76691b11c27a8d4a5d8f U drh -Z 514dfe801f60757ebd0519594eb7ecde +Z d3631fb4e80d910681e8351d2aa12531 diff --git a/manifest.uuid b/manifest.uuid index 4d4fd3e0b6..2c79e1a3ec 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4dc30cce7fdb7dba9a9aad96bb8b499b965610b2 \ No newline at end of file +a1dcf7af42bb7394d46138318f9367fe9e8be560 \ No newline at end of file diff --git a/test/nolock.test b/test/nolock.test index fdaef6ef07..e732dcf13b 100644 --- a/test/nolock.test +++ b/test/nolock.test @@ -183,35 +183,38 @@ db2 close db close tvfs delete -# 2016-03-11: Make sure all works when transitioning to WAL mode under nolock. -# -do_test nolock-4.1 { - forcedelete test.db - sqlite3 db file:test.db?nolock=1 -uri 1 - db eval { - PRAGMA journal_mode=WAL; - CREATE TABLE t1(x); - INSERT INTO t1 VALUES('youngling'); - SELECT * FROM t1; - } -} {delete youngling} -db close - -do_test nolock-4.2 { - forcedelete test.db - sqlite3 db test.db - db eval { - PRAGMA journal_mode=WAL; - CREATE TABLE t1(x); - INSERT INTO t1 VALUES('catbird'); - SELECT * FROM t1; - } -} {wal catbird} -do_test nolock-4.3 { +if {[permutation]!="inmemory_journal"} { + # 2016-03-11: Make sure all works when transitioning to WAL mode + # under nolock. + # + do_test nolock-4.1 { + forcedelete test.db + sqlite3 db file:test.db?nolock=1 -uri 1 + db eval { + PRAGMA journal_mode=WAL; + CREATE TABLE t1(x); + INSERT INTO t1 VALUES('youngling'); + SELECT * FROM t1; + } + } {delete youngling} db close - sqlite3 db file:test.db?nolock=1 -uri 1 - set rc [catch {db eval {SELECT * FROM t1}} msg] - lappend rc $msg -} {1 {unable to open database file}} + + do_test nolock-4.2 { + forcedelete test.db + sqlite3 db test.db + db eval { + PRAGMA journal_mode=WAL; + CREATE TABLE t1(x); + INSERT INTO t1 VALUES('catbird'); + SELECT * FROM t1; + } + } {wal catbird} + do_test nolock-4.3 { + db close + sqlite3 db file:test.db?nolock=1 -uri 1 + set rc [catch {db eval {SELECT * FROM t1}} msg] + lappend rc $msg + } {1 {unable to open database file}} +} finish_test From 6737aab5cfd17cfc7819e8fdd00463bbbff34aad Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 21 Mar 2016 16:25:34 +0000 Subject: [PATCH 0193/1484] Add tests to ensure that fts5 is now deterministic. FossilOrigin-Name: 3d076094ce411bffcfeb76c0284d15d0f83bd459 --- ext/fts5/test/fts5determin.test | 67 +++++++++++++++++++++++++++++++++ manifest | 13 ++++--- manifest.uuid | 2 +- 3 files changed, 75 insertions(+), 7 deletions(-) create mode 100644 ext/fts5/test/fts5determin.test diff --git a/ext/fts5/test/fts5determin.test b/ext/fts5/test/fts5determin.test new file mode 100644 index 0000000000..e368c4704e --- /dev/null +++ b/ext/fts5/test/fts5determin.test @@ -0,0 +1,67 @@ +# 2016 March 21 +# +# 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 regression tests for SQLite library. The +# focus of this script is testing the FTS5 module. +# +# Specifically, that the fts5 module is deterministic. At one point, when +# segment ids were allocated using sqlite3_randomness(), this was not the +# case. +# + +source [file join [file dirname [info script]] fts5_common.tcl] +set testprefix fts5aa +return_if_no_fts5 + +proc do_determin_test {tn} { + uplevel [list + do_execsql_test $tn { + SELECT (SELECT md5sum(id, block) FROM t1_data)== + (SELECT md5sum(id, block) FROM t2_data), + (SELECT md5sum(id, block) FROM t1_data)== + (SELECT md5sum(id, block) FROM t3_data) + } {1 1} + ] +} + +foreach_detail_mode $::testprefix { + do_execsql_test 1.0 { + CREATE VIRTUAL TABLE t1 USING fts5(a, b, prefix="1 2", detail=%DETAIL%); + CREATE VIRTUAL TABLE t2 USING fts5(a, b, prefix="1 2", detail=%DETAIL%); + CREATE VIRTUAL TABLE t3 USING fts5(a, b, prefix="1 2", detail=%DETAIL%); + } + + do_test 1.1 { + foreach t {t1 t2 t3} { + execsql [string map [list TBL $t] { + INSERT INTO TBL VALUES('a b c', 'd e f'); + INSERT INTO TBL VALUES('c1 c2 c3', 'c1 c2 c3'); + INSERT INTO TBL VALUES('xyzxyzxyz', 'xyzxyzxyz'); + }] + } + } {} + + do_determin_test 1.2 + + do_test 1.3 { + foreach t {t1 t2 t3} { + execsql [string map [list TBL $t] { + INSERT INTO TBL(TBL) VALUES('optimize'); + }] + } + } {} + + do_determin_test 1.4 +} + + +finish_test + + diff --git a/manifest b/manifest index 78be64c56a..7fca6a827a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Skip\srecently\sadded\stest\scases\sin\snolock.test\swhen\srunning\sin\nthe\sinmemory_journal\spermutation. -D 2016-03-21T16:19:29.587 +C Add\stests\sto\sensure\sthat\sfts5\sis\snow\sdeterministic. +D 2016-03-21T16:25:34.085 F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66 @@ -143,6 +143,7 @@ F ext/fts5/test/fts5corrupt.test c2ad090192708150d50d961278df10ae7a4b8b62 F ext/fts5/test/fts5corrupt2.test 26c0a39dd9ff73207e6229f83b50b21d37c7658c F ext/fts5/test/fts5corrupt3.test f77f65e386231daf62902466b40ff998b2c8ce4f F ext/fts5/test/fts5detail.test ef5c690535a797413acaf5ad9b8ab5d49972df69 +F ext/fts5/test/fts5determin.test 10648edb75ef1e196b10978fd21a9be0c31e09c3 F ext/fts5/test/fts5dlidx.test 007e9390c94638760797dbec2990c97c3fa08dfe F ext/fts5/test/fts5doclist.test 8edb5b57e5f144030ed74ec00ef6fa4294fed79b F ext/fts5/test/fts5ea.test b01e3a18cdfabbff8104a96a5242a06a68a998a0 @@ -1458,7 +1459,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 4dc30cce7fdb7dba9a9aad96bb8b499b965610b2 -R 1f352d94053f76691b11c27a8d4a5d8f -U drh -Z d3631fb4e80d910681e8351d2aa12531 +P a1dcf7af42bb7394d46138318f9367fe9e8be560 +R d12464ec7adc7a5a41759a981f3bde86 +U dan +Z 8af492a5f67a993085e11843c854eec0 diff --git a/manifest.uuid b/manifest.uuid index 2c79e1a3ec..eacdf09ef0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a1dcf7af42bb7394d46138318f9367fe9e8be560 \ No newline at end of file +3d076094ce411bffcfeb76c0284d15d0f83bd459 \ No newline at end of file From 13969f5af0583fc3d661297d2d90ae4a0ef11103 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 21 Mar 2016 22:28:51 +0000 Subject: [PATCH 0194/1484] Fix harmless compiler warnings. FossilOrigin-Name: 25d776e4523aefeec007943fe29aa17c23ccb301 --- ext/fts5/fts5_index.c | 2 +- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/memjournal.c | 2 +- src/sqliteInt.h | 8 ++++++-- 5 files changed, 18 insertions(+), 14 deletions(-) diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index 2e8349d51c..f0751bd655 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -4603,7 +4603,7 @@ static Fts5Structure *fts5IndexOptimizeStruct( if( pNew ){ Fts5StructureLevel *pLvl; - int nByte = nSeg * sizeof(Fts5StructureSegment); + nByte = nSeg * sizeof(Fts5StructureSegment); pNew->nLevel = pStruct->nLevel+1; pNew->nRef = 1; pNew->nWriteCounter = pStruct->nWriteCounter; diff --git a/manifest b/manifest index 7fca6a827a..8624bb132c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\stests\sto\sensure\sthat\sfts5\sis\snow\sdeterministic. -D 2016-03-21T16:25:34.085 +C Fix\sharmless\scompiler\swarnings. +D 2016-03-21T22:28:51.426 F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66 @@ -104,7 +104,7 @@ F ext/fts5/fts5_buffer.c 4c1502d4c956cd092c89ce4480867f9d8bf325cd F ext/fts5/fts5_config.c 5af9c360e99669d29f06492c370892394aba0857 F ext/fts5/fts5_expr.c 35e9d92c89e7c7ea0759b73d24da1ecb7630a24b F ext/fts5/fts5_hash.c f3a7217c86eb8f272871be5f6aa1b6798960a337 -F ext/fts5/fts5_index.c 40fde2538deeb7f018435c1d1bacf057f89c3c42 +F ext/fts5/fts5_index.c 0fe734b1e2574fdbcfad4d71f861b8598dd7f91b F ext/fts5/fts5_main.c b4a0fc5bf17f2f1f056ee76cdd7d2af08b360f55 F ext/fts5/fts5_storage.c 98e3129047d250fc5acc4a4ba7ba4fde9b0ae030 F ext/fts5/fts5_tcl.c f8731e0508299bd43f1a2eff7dbeaac870768966 @@ -325,7 +325,7 @@ F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3 F src/mem3.c 8768ac94694f31ffaf8b4d0ea5dc08af7010a35a F src/mem5.c 9bf955937b07f8c32541c8a9991f33ce3173d944 -F src/memjournal.c 6423a0817ffd8c7a04ef9e5fb974b6b9dd71f8b6 +F src/memjournal.c 5253fd4335a8d9c64e5df25cb9da6329af5242c7 F src/msvc.h d9ba56c6851227ab44b3f228a35f3f5772296495 F src/mutex.c 8e45800ee78e0cd1f1f3fe8e398853307f4a085c F src/mutex.h 779d588e3b7756ec3ecf7d78cde1d84aba414f85 @@ -358,7 +358,7 @@ F src/shell.c 5e0ab1e708dc294330ccd8230536e1801f60822e F src/sqlite.h.in e877f141b15ef68ef28f84714e69d7234f9a071e F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 98f72cbfe00169c39089115427d06ea05fe4b4a2 -F src/sqliteInt.h 4eb80a9b9a512180a9739f99d754915e03d8091a +F src/sqliteInt.h 47847a919790e2a30bb1dfb89ba0dc59fc6ed0be F src/sqliteLimit.h 7b28cf72cbd52f178bfc97ea266445e351f2cd24 F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 @@ -1459,7 +1459,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a1dcf7af42bb7394d46138318f9367fe9e8be560 -R d12464ec7adc7a5a41759a981f3bde86 -U dan -Z 8af492a5f67a993085e11843c854eec0 +P 3d076094ce411bffcfeb76c0284d15d0f83bd459 +R 8b7871914efe43742b6c5e5d156225cc +U drh +Z 74feddb89c21c363d080129c819f5a2b diff --git a/manifest.uuid b/manifest.uuid index eacdf09ef0..adb1b4e66e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3d076094ce411bffcfeb76c0284d15d0f83bd459 \ No newline at end of file +25d776e4523aefeec007943fe29aa17c23ccb301 \ No newline at end of file diff --git a/src/memjournal.c b/src/memjournal.c index b81682de85..4f0efc174e 100644 --- a/src/memjournal.c +++ b/src/memjournal.c @@ -403,5 +403,5 @@ int sqlite3JournalIsInMemory(sqlite3_file *p){ ** pVfs to create the underlying on-disk files. */ int sqlite3JournalSize(sqlite3_vfs *pVfs){ - return MAX(pVfs->szOsFile, sizeof(MemJournal)); + return MAX(pVfs->szOsFile, (int)sizeof(MemJournal)); } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index fc36d8d091..858f737356 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -583,8 +583,12 @@ /* ** Macros to compute minimum and maximum of two numbers. */ -#define MIN(A,B) ((A)<(B)?(A):(B)) -#define MAX(A,B) ((A)>(B)?(A):(B)) +#ifndef MIN +# define MIN(A,B) ((A)<(B)?(A):(B)) +#endif +#ifndef MAX +# define MAX(A,B) ((A)>(B)?(A):(B)) +#endif /* ** Swap two objects of type TYPE. From 0b98207c5b7ef2ac85cc06e4971a5393c4cffd57 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 22 Mar 2016 14:10:45 +0000 Subject: [PATCH 0195/1484] Avoid the possibility of integer overflow on a pointer comparison test for corruption in the database file. FossilOrigin-Name: ff1b1ac3313ba9d70414e928ef3dd82913298a1a --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btree.c | 9 +++++++-- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 8624bb132c..d6d21ac7ef 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\scompiler\swarnings. -D 2016-03-21T22:28:51.426 +C Avoid\sthe\spossibility\sof\sinteger\soverflow\son\sa\spointer\scomparison\stest\sfor\ncorruption\sin\sthe\sdatabase\sfile. +D 2016-03-22T14:10:45.052 F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66 @@ -297,7 +297,7 @@ F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240 F src/backup.c f60f0aa55d25d853ffde53d0b0370a7bb7ee41ce F src/bitvec.c 3ee4c8b2c94ed3a7377256e18199e6ff5cf33f63 F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 -F src/btree.c 6eee126fe9d1f57118de9be2be840a4c6e691828 +F src/btree.c 5753da53071b5d5a8ace8fd9ea7a54cefeb8187b F src/btree.h a5008b9afe56e8e54ade6c436a910f112defcca9 F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 F src/build.c 213cbf84e99dd834e6ea46615633656d7ef79321 @@ -1459,7 +1459,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 3d076094ce411bffcfeb76c0284d15d0f83bd459 -R 8b7871914efe43742b6c5e5d156225cc +P 25d776e4523aefeec007943fe29aa17c23ccb301 +R 7b06b50bff5ae9500629c34b0d5509bb U drh -Z 74feddb89c21c363d080129c819f5a2b +Z 3c0767287744fc9671f0ea1849fc5941 diff --git a/manifest.uuid b/manifest.uuid index adb1b4e66e..bf5169d0f4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -25d776e4523aefeec007943fe29aa17c23ccb301 \ No newline at end of file +ff1b1ac3313ba9d70414e928ef3dd82913298a1a \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 18e6be9f38..3e29f8469d 100644 --- a/src/btree.c +++ b/src/btree.c @@ -4472,8 +4472,13 @@ static int accessPayload( #endif assert( offset+amt <= pCur->info.nPayload ); - if( &aPayload[pCur->info.nLocal] > &pPage->aData[pBt->usableSize] ){ - /* Trying to read or write past the end of the data is an error */ + assert( aPayload > pPage->aData ); + if( (aPayload - pPage->aData) > (pBt->usableSize - pCur->info.nLocal) ){ + /* Trying to read or write past the end of the data is an error. The + ** conditional above is really: + ** &aPayload[pCur->info.nLocal] > &pPage->aData[pBt->usableSize] + ** but is recast into its current form to avoid integer overflow problems + */ return SQLITE_CORRUPT_BKPT; } From 3bfa7e82b618fea9904cb5c36bff3b9bf311bab9 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 22 Mar 2016 14:37:59 +0000 Subject: [PATCH 0196/1484] Create the "uptr" typedef (the same as uintptr_t when available) and use it to cast pointers before comparison. FossilOrigin-Name: 2484cc0c3ffc8834a155f89af1581bd07d453a90 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/btree.c | 4 ++-- src/sqliteInt.h | 36 +++++++++++++++++++++--------------- 4 files changed, 31 insertions(+), 25 deletions(-) diff --git a/manifest b/manifest index d6d21ac7ef..6c9eb30c1e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sthe\spossibility\sof\sinteger\soverflow\son\sa\spointer\scomparison\stest\sfor\ncorruption\sin\sthe\sdatabase\sfile. -D 2016-03-22T14:10:45.052 +C Create\sthe\s"uptr"\stypedef\s(the\ssame\sas\suintptr_t\swhen\savailable)\sand\suse\sit\nto\scast\spointers\sbefore\scomparison. +D 2016-03-22T14:37:59.457 F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66 @@ -297,7 +297,7 @@ F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240 F src/backup.c f60f0aa55d25d853ffde53d0b0370a7bb7ee41ce F src/bitvec.c 3ee4c8b2c94ed3a7377256e18199e6ff5cf33f63 F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 -F src/btree.c 5753da53071b5d5a8ace8fd9ea7a54cefeb8187b +F src/btree.c 8a02b1fb98eb11b9ce50cb3ab6a031f852b69303 F src/btree.h a5008b9afe56e8e54ade6c436a910f112defcca9 F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 F src/build.c 213cbf84e99dd834e6ea46615633656d7ef79321 @@ -358,7 +358,7 @@ F src/shell.c 5e0ab1e708dc294330ccd8230536e1801f60822e F src/sqlite.h.in e877f141b15ef68ef28f84714e69d7234f9a071e F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 98f72cbfe00169c39089115427d06ea05fe4b4a2 -F src/sqliteInt.h 47847a919790e2a30bb1dfb89ba0dc59fc6ed0be +F src/sqliteInt.h cb02015eac6d642bd23d8cbd76cc116635c17540 F src/sqliteLimit.h 7b28cf72cbd52f178bfc97ea266445e351f2cd24 F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 @@ -1459,7 +1459,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 25d776e4523aefeec007943fe29aa17c23ccb301 -R 7b06b50bff5ae9500629c34b0d5509bb +P ff1b1ac3313ba9d70414e928ef3dd82913298a1a +R db2868426a9aae9f4cc9b8c065b04b6c U drh -Z 3c0767287744fc9671f0ea1849fc5941 +Z 0cd59c36c28d6740a5e8b1f16f08075a diff --git a/manifest.uuid b/manifest.uuid index bf5169d0f4..b4fc72f392 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ff1b1ac3313ba9d70414e928ef3dd82913298a1a \ No newline at end of file +2484cc0c3ffc8834a155f89af1581bd07d453a90 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 3e29f8469d..1a82176f18 100644 --- a/src/btree.c +++ b/src/btree.c @@ -2360,12 +2360,12 @@ int sqlite3BtreeOpen( for(i=0; inDb; i++){ if( (pSib = db->aDb[i].pBt)!=0 && pSib->sharable ){ while( pSib->pPrev ){ pSib = pSib->pPrev; } - if( p->pBtpBt ){ + if( (uptr)p->pBt<(uptr)pSib->pBt ){ p->pNext = pSib; p->pPrev = 0; pSib->pPrev = p; }else{ - while( pSib->pNext && pSib->pNext->pBtpBt ){ + while( pSib->pNext && (uptr)pSib->pNext->pBt<(uptr)p->pBt ){ pSib = pSib->pNext; } p->pNext = pSib->pNext; diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 858f737356..d256262b05 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -181,21 +181,6 @@ # define SQLITE_PTR_TO_INT(X) ((int)(X)) #endif -/* -** The SQLITE_WITHIN(P,S,E) macro checks to see if pointer P points to -** something between S (inclusive) and E (exclusive). -** -** In other words, S is a buffer and E is a pointer to the first byte after -** the end of buffer S. This macro returns true if P points to something -** contained within the buffer S. -*/ -#if defined(HAVE_STDINT_H) -# define SQLITE_WITHIN(P,S,E) \ - ((uintptr_t)(P)>=(uintptr_t)(S) && (uintptr_t)(P)<(uintptr_t)(E)) -#else -# define SQLITE_WITHIN(P,S,E) ((P)>=(S) && (P)<(E)) -#endif - /* ** A macro to hint to the compiler that a function should not be ** inlined. @@ -717,6 +702,27 @@ typedef INT16_TYPE LogEst; # endif #endif +/* The uptr type is an unsigned integer large enough to hold a pointer +*/ +#if defined(HAVE_STDINT_H) + typedef uintptr_t uptr; +#elif SQLITE_PTRSIZE==4 + typedef u32 uptr; +#else + typedef u64 uptr; +#endif + +/* +** The SQLITE_WITHIN(P,S,E) macro checks to see if pointer P points to +** something between S (inclusive) and E (exclusive). +** +** In other words, S is a buffer and E is a pointer to the first byte after +** the end of buffer S. This macro returns true if P points to something +** contained within the buffer S. +*/ +#define SQLITE_WITHIN(P,S,E) (((uptr)(P)>=(uptr)(S))&&((uptr)(P)<(uptr)(E))) + + /* ** Macros to determine whether the machine is big or little endian, ** and whether or not that determination is run-time or compile-time. From 0a2f2b546a1615c257351a872cda726f5d56a075 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 22 Mar 2016 15:01:54 +0000 Subject: [PATCH 0197/1484] Fix some errors in fts5 test scripts. FossilOrigin-Name: e1ab2d376a72786098125a41c1ea8140fcbd15c6 --- ext/fts5/fts5_index.c | 2 +- ext/fts5/test/fts5aa.test | 9 ++++++++- ext/fts5/test/fts5fault4.test | 2 +- ext/fts5/test/fts5simple.test | 6 +++--- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- 6 files changed, 24 insertions(+), 17 deletions(-) diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index f0751bd655..d08e65bfe6 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -1027,7 +1027,7 @@ static Fts5Structure *fts5StructureRead(Fts5Index *p){ } } -#ifdef SQLITE_DEBUG +#if 0 else{ Fts5Structure *pTest = fts5StructureReadUncached(p); if( pTest ){ diff --git a/ext/fts5/test/fts5aa.test b/ext/fts5/test/fts5aa.test index fdcf08398d..428ca6c1ea 100644 --- a/ext/fts5/test/fts5aa.test +++ b/ext/fts5/test/fts5aa.test @@ -432,9 +432,16 @@ proc funk {} { } db func funk funk +# This test case corrupts the structure record within the first invocation +# of function funk(). Which used to cause the bm25() function to throw an +# exception. But since bm25() can now used the cached structure record, +# it never sees the corruption introduced by funk() and so the following +# statement no longer fails. +# do_catchsql_test 16.2 { SELECT funk(), bm25(n1), funk() FROM n1 WHERE n1 MATCH 'a+b+c+d' -} {1 {SQL logic error or missing database}} +} {0 {{} -1e-06 {}}} +# {1 {SQL logic error or missing database}} #------------------------------------------------------------------------- # diff --git a/ext/fts5/test/fts5fault4.test b/ext/fts5/test/fts5fault4.test index acc43ebfc6..bfa54a5b04 100644 --- a/ext/fts5/test/fts5fault4.test +++ b/ext/fts5/test/fts5fault4.test @@ -86,7 +86,7 @@ set ::res [db eval {SELECT rowid, x1 FROM x1 WHERE x1 MATCH '*reads'}] do_faultsim_test 4 -faults oom-* -body { db eval {SELECT rowid, x, x1 FROM x1 WHERE x1 MATCH '*reads'} } -test { - faultsim_test_result {0 {0 {} 4}} + faultsim_test_result {0 {0 {} 3}} } #------------------------------------------------------------------------- diff --git a/ext/fts5/test/fts5simple.test b/ext/fts5/test/fts5simple.test index 464b601548..3483e40ba5 100644 --- a/ext/fts5/test/fts5simple.test +++ b/ext/fts5/test/fts5simple.test @@ -340,7 +340,7 @@ do_test 14.2 { #------------------------------------------------------------------------- db func rnddoc fts5_rnddoc -do_execsql_test 4.0 { +do_execsql_test 14.3 { CREATE VIRTUAL TABLE x1 USING fts5(x); INSERT INTO x1(x1, rank) VALUES('pgsz', 32); @@ -348,9 +348,9 @@ do_execsql_test 4.0 { INSERT INTO x1 SELECT rnddoc(5) FROM ii; } -do_execsql_test 4.1 { +do_execsql_test 14.4 { SELECT rowid, x, x1 FROM x1 WHERE x1 MATCH '*reads' -} {0 {} 4} +} {0 {} 3} #------------------------------------------------------------------------- reset_db diff --git a/manifest b/manifest index 6c9eb30c1e..358587aaa3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Create\sthe\s"uptr"\stypedef\s(the\ssame\sas\suintptr_t\swhen\savailable)\sand\suse\sit\nto\scast\spointers\sbefore\scomparison. -D 2016-03-22T14:37:59.457 +C Fix\ssome\serrors\sin\sfts5\stest\sscripts. +D 2016-03-22T15:01:54.312 F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66 @@ -104,7 +104,7 @@ F ext/fts5/fts5_buffer.c 4c1502d4c956cd092c89ce4480867f9d8bf325cd F ext/fts5/fts5_config.c 5af9c360e99669d29f06492c370892394aba0857 F ext/fts5/fts5_expr.c 35e9d92c89e7c7ea0759b73d24da1ecb7630a24b F ext/fts5/fts5_hash.c f3a7217c86eb8f272871be5f6aa1b6798960a337 -F ext/fts5/fts5_index.c 0fe734b1e2574fdbcfad4d71f861b8598dd7f91b +F ext/fts5/fts5_index.c 19df86d29d24cc56bfb01a6a07dcaac227d2fcdf F ext/fts5/fts5_main.c b4a0fc5bf17f2f1f056ee76cdd7d2af08b360f55 F ext/fts5/fts5_storage.c 98e3129047d250fc5acc4a4ba7ba4fde9b0ae030 F ext/fts5/fts5_tcl.c f8731e0508299bd43f1a2eff7dbeaac870768966 @@ -117,7 +117,7 @@ F ext/fts5/fts5_vocab.c dba72ca393d71c2588548b51380387f6b44c77a8 F ext/fts5/fts5parse.y fcc5e92e570d38cab38488b2109cbf67468923b2 F ext/fts5/mkportersteps.tcl 5acf962d2e0074f701620bb5308155fa1e4a63ba F ext/fts5/test/fts5_common.tcl b01c584144b5064f30e6c648145a2dd6bc440841 -F ext/fts5/test/fts5aa.test 7e814df4a0e6c22a6fe2d84f210fdc0b5068a084 +F ext/fts5/test/fts5aa.test bd2d88182b9f7f30d300044048ad14683306b745 F ext/fts5/test/fts5ab.test 30325a89453280160106be411bba3acf138e6d1b F ext/fts5/test/fts5ac.test 55cad4275a1f5acabfe14d8442a8046b47e49e5f F ext/fts5/test/fts5ad.test 36995f0586f30f5602074e012b9224c71ec5171c @@ -151,7 +151,7 @@ F ext/fts5/test/fts5eb.test c516ae0c934be6fd29ec95ea8b5f11f461311535 F ext/fts5/test/fts5fault1.test e09040d3e17b8c0837101e8c79c8a874c4376fb7 F ext/fts5/test/fts5fault2.test d8c6c7f916ccbdfc10b2c69530e9dd3bc8313232 F ext/fts5/test/fts5fault3.test d6e9577d4312e331a913c72931bf131704efc8f3 -F ext/fts5/test/fts5fault4.test 532b6dacb963016cbf7003196bd87fb366540277 +F ext/fts5/test/fts5fault4.test dcbe3043c5611edd350191ea03a8daa190f0de5a F ext/fts5/test/fts5fault5.test 10c13a783de3f42a21e3e53e123b62ed0c3a1618 F ext/fts5/test/fts5fault6.test 9682664d679643ac6736e90c225526cc84073cda F ext/fts5/test/fts5fault7.test cb14ea3c1f42394f06f2284abc58eecee6ff8080 @@ -180,7 +180,7 @@ F ext/fts5/test/fts5rank.test 7e9e64eac7245637f6f2033aec4b292aaf611aab F ext/fts5/test/fts5rebuild.test 03935f617ace91ed23a6099c7c74d905227ff29b F ext/fts5/test/fts5restart.test c17728fdea26e7d0f617d22ad5b4b2862b994c17 F ext/fts5/test/fts5rowid.test 16908a99d6efc9ba21081b4f2b86b3fc699839a6 -F ext/fts5/test/fts5simple.test ac5006cc3d0d08b3538e1e76c7300de9f24fbed1 +F ext/fts5/test/fts5simple.test 5b7b05bcc89bcb718a0fc7f473092d3513cc8e19 F ext/fts5/test/fts5simple2.test 98377ae1ff7749a42c21fe1a139c1ed312522c46 F ext/fts5/test/fts5simple3.test 8e71733b3d1b0e695011d02c68ebc5ca40b6124e F ext/fts5/test/fts5synonym.test 6475d189c2e20d60795808f83e36bf9318708d48 @@ -1459,7 +1459,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ff1b1ac3313ba9d70414e928ef3dd82913298a1a -R db2868426a9aae9f4cc9b8c065b04b6c -U drh -Z 0cd59c36c28d6740a5e8b1f16f08075a +P 2484cc0c3ffc8834a155f89af1581bd07d453a90 +R ab98ce57ff7e19fbcedd913d7355f5be +U dan +Z e1d6ab80a5a2193f9db22bd77af06553 diff --git a/manifest.uuid b/manifest.uuid index b4fc72f392..43213d63e1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2484cc0c3ffc8834a155f89af1581bd07d453a90 \ No newline at end of file +e1ab2d376a72786098125a41c1ea8140fcbd15c6 \ No newline at end of file From c5e7f94494a27bc13b5f62584101166e91ebdcf4 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 22 Mar 2016 15:25:16 +0000 Subject: [PATCH 0198/1484] Fix a harmless compiler warning. FossilOrigin-Name: 5ace870d3ac3e9eb29cb4602c9036873adbcb99d --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/btree.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 358587aaa3..1fb0bc726f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\ssome\serrors\sin\sfts5\stest\sscripts. -D 2016-03-22T15:01:54.312 +C Fix\sa\sharmless\scompiler\swarning. +D 2016-03-22T15:25:16.949 F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66 @@ -297,7 +297,7 @@ F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240 F src/backup.c f60f0aa55d25d853ffde53d0b0370a7bb7ee41ce F src/bitvec.c 3ee4c8b2c94ed3a7377256e18199e6ff5cf33f63 F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 -F src/btree.c 8a02b1fb98eb11b9ce50cb3ab6a031f852b69303 +F src/btree.c 577fb5674e2f0aa0a38246afc19e1885a0b8c9b0 F src/btree.h a5008b9afe56e8e54ade6c436a910f112defcca9 F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 F src/build.c 213cbf84e99dd834e6ea46615633656d7ef79321 @@ -1459,7 +1459,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 2484cc0c3ffc8834a155f89af1581bd07d453a90 -R ab98ce57ff7e19fbcedd913d7355f5be -U dan -Z e1d6ab80a5a2193f9db22bd77af06553 +P e1ab2d376a72786098125a41c1ea8140fcbd15c6 +R bdaff546f18a9832fa859fa7ed0eb2c5 +U drh +Z e5f40ebb5a86d8be765f1d7f6d3191da diff --git a/manifest.uuid b/manifest.uuid index 43213d63e1..a62797cd9e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e1ab2d376a72786098125a41c1ea8140fcbd15c6 \ No newline at end of file +5ace870d3ac3e9eb29cb4602c9036873adbcb99d \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 1a82176f18..bf99597095 100644 --- a/src/btree.c +++ b/src/btree.c @@ -4473,7 +4473,7 @@ static int accessPayload( assert( offset+amt <= pCur->info.nPayload ); assert( aPayload > pPage->aData ); - if( (aPayload - pPage->aData) > (pBt->usableSize - pCur->info.nLocal) ){ + if( (uptr)(aPayload - pPage->aData) > (pBt->usableSize - pCur->info.nLocal) ){ /* Trying to read or write past the end of the data is an error. The ** conditional above is really: ** &aPayload[pCur->info.nLocal] > &pPage->aData[pBt->usableSize] From 527b0435fabe2795865d52e4db827173a1cb2d65 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Tue, 22 Mar 2016 15:26:03 +0000 Subject: [PATCH 0199/1484] Fix harmless compiler warning for MSVC. FossilOrigin-Name: 142cd359d37f1d8d53de32e329523d9a93c7d6e5 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/os_win.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 1fb0bc726f..8de110620f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sharmless\scompiler\swarning. -D 2016-03-22T15:25:16.949 +C Fix\sharmless\scompiler\swarning\sfor\sMSVC. +D 2016-03-22T15:26:03.280 F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66 @@ -338,7 +338,7 @@ F src/os.h 91ff889115ecd01f436d3611f7f5ea4dc12d92f1 F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85 F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa F src/os_unix.c b1ccb273771f41dbdbe0ba7c1ad63c38ad5972ec -F src/os_win.c 551d973ada67127430e41d9e514e53f6beb6c5a7 +F src/os_win.c 17493f12b0b023c2d5a349b6860009f0d45e08d6 F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c 38718a019ca762ba4f6795425d5a54db70d1790d F src/pager.h e1d38a2f14849e219df0f91f8323504d134c8a56 @@ -1459,7 +1459,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e1ab2d376a72786098125a41c1ea8140fcbd15c6 -R bdaff546f18a9832fa859fa7ed0eb2c5 -U drh -Z e5f40ebb5a86d8be765f1d7f6d3191da +P 5ace870d3ac3e9eb29cb4602c9036873adbcb99d +R 005c1e5cbc7587970df3ccd3cc730064 +U mistachkin +Z 4de36823f78a549c0eee8008ed054760 diff --git a/manifest.uuid b/manifest.uuid index a62797cd9e..7b06c9c521 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5ace870d3ac3e9eb29cb4602c9036873adbcb99d \ No newline at end of file +142cd359d37f1d8d53de32e329523d9a93c7d6e5 \ No newline at end of file diff --git a/src/os_win.c b/src/os_win.c index fd95c00e3a..3f9fefcac4 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -5425,7 +5425,7 @@ static int winRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ UNUSED_PARAMETER(pVfs); memset(zBuf, 0, nBuf); #if defined(_MSC_VER) && _MSC_VER>=1400 - rand_s((int*)zBuf); /* rand_s() is not available with MinGW */ + rand_s((unsigned int*)zBuf); /* rand_s() is not available with MinGW */ #endif /* defined(_MSC_VER) && _MSC_VER>=1400 */ e.a = (unsigned char*)zBuf; e.na = nBuf; From d7564865adc966c21fcdc10ea5ee5bb5910c46da Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 22 Mar 2016 20:05:09 +0000 Subject: [PATCH 0200/1484] The sqlite3_column_decltype() routine should return NULL, not an empty string, if the column has no declared type. FossilOrigin-Name: 605eba4a756e7185119088e2242f82691d078b01 --- manifest | 26 +++++++++++++------------- manifest.uuid | 2 +- src/build.c | 15 ++++++++------- src/main.c | 3 +-- src/pragma.c | 6 ++---- src/select.c | 4 ++-- src/sqliteInt.h | 3 ++- src/util.c | 12 ++++++++---- src/vtab.c | 20 +++++++------------- 9 files changed, 44 insertions(+), 47 deletions(-) diff --git a/manifest b/manifest index 8de110620f..19c00ee626 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\scompiler\swarning\sfor\sMSVC. -D 2016-03-22T15:26:03.280 +C The\ssqlite3_column_decltype()\sroutine\sshould\sreturn\sNULL,\snot\san\sempty\sstring,\nif\sthe\scolumn\shas\sno\sdeclared\stype. +D 2016-03-22T20:05:09.546 F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66 @@ -300,7 +300,7 @@ F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 F src/btree.c 577fb5674e2f0aa0a38246afc19e1885a0b8c9b0 F src/btree.h a5008b9afe56e8e54ade6c436a910f112defcca9 F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 -F src/build.c 213cbf84e99dd834e6ea46615633656d7ef79321 +F src/build.c 7d1a5e64fcd10110edc8ce9ffb710d06af0a59f5 F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 60e135af364d777a9ab41c97e5e89cd224da6198 @@ -318,7 +318,7 @@ F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 F src/insert.c 723d5d708cdb61bdd47c00b9f07c75be45aefc09 F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e F src/loadext.c e70f8f9e97624a232870ea5486e682c813ac3002 -F src/main.c f6c6e61bfd4cc9306a737d0c5c3f1e0eaf6086e0 +F src/main.c 63791c66321f07b5828bb9161b477d5e0b511d7e F src/malloc.c 1443d1ad95d67c21d77af7ae3f44678252f0efec F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b @@ -346,19 +346,19 @@ F src/parse.y 5ea8c81c5c41b27887f41b4a7e1c58470d7d3821 F src/pcache.c 647bb53a86b7bbcf55ad88089b3ea5a9170b90df F src/pcache.h 4d0ccaad264d360981ec5e6a2b596d6e85242545 F src/pcache1.c c40cdb93586e21b5dd826b5e671240bd91c26b05 -F src/pragma.c e7e8f380efec6075a722822306435afc1eeca88a +F src/pragma.c faf42922bb7ab2f6672cb550356c1967abae3c84 F src/pragma.h 64c78a648751b9f4f297276c4eb7507b14b4628c F src/prepare.c 22df6171aec1d86904ed2ad30c2348a5748aa04e F src/printf.c 63e6fb12bbe702dd664dc3703776c090383a5a26 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c b8f7174e5f8c33c44ded3a25a973d0bb89228c20 F src/rowset.c 9fe4b3ad7cc00944386bb600233d8f523de07a6e -F src/select.c 6dd2097bb158efe3b8d68683dcc3b4a49e907a34 +F src/select.c 7849cee0a01952a9c93cd28989daedfa57731143 F src/shell.c 5e0ab1e708dc294330ccd8230536e1801f60822e F src/sqlite.h.in e877f141b15ef68ef28f84714e69d7234f9a071e F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 98f72cbfe00169c39089115427d06ea05fe4b4a2 -F src/sqliteInt.h cb02015eac6d642bd23d8cbd76cc116635c17540 +F src/sqliteInt.h 3a68b48967a7d62fcb38572d27fd21ab4e4bcca3 F src/sqliteLimit.h 7b28cf72cbd52f178bfc97ea266445e351f2cd24 F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 @@ -417,7 +417,7 @@ F src/treeview.c e4b41a37530a191579d3c53142cc44ee2eb99373 F src/trigger.c e14840ee0c3e549e758ec9bf3e4146e166002280 F src/update.c 56b3db7edff0110360a12b76af97c39ebe3ea8b8 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c -F src/util.c cf7dce85ab9af5280b8a45985df2591efbfefe56 +F src/util.c 8873d696c9ccc4206058c402e09e101f1b81561a F src/vacuum.c feb1eabb20987983d9350cad98299b21fa811f52 F src/vdbe.c f19741f2d8b33e8f09cd2219570b6c9ed924c3f1 F src/vdbe.h 6f44193e7be52fd5f7c308175a936555b1e6b101 @@ -428,7 +428,7 @@ F src/vdbeblob.c 3b570b730109e8f653d9d2081649f6e7015113db F src/vdbemem.c fe76c1f866de362d9b8332e59d74aa44f6560d69 F src/vdbesort.c 307460bfa4de4d1c3901fcd42089159131e34062 F src/vdbetrace.c f75c5455d8cf389ef86a8bfdfd3177e0e3692484 -F src/vtab.c fd69fd398e23e57ea4ea377d8a44b6998fc569c7 +F src/vtab.c 23b6cdfa996152d43b390504ed4a942c8caf3a00 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 10deb6b43887662691e5f53d10b3c171c401169b F src/wal.h 2f7c831cf3b071fa548bf2d5cac640846a7ff19c @@ -1459,7 +1459,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 5ace870d3ac3e9eb29cb4602c9036873adbcb99d -R 005c1e5cbc7587970df3ccd3cc730064 -U mistachkin -Z 4de36823f78a549c0eee8008ed054760 +P 142cd359d37f1d8d53de32e329523d9a93c7d6e5 +R 54bb94e9ede3ebe9fafd5624cdd5946f +U drh +Z 8ae8a72878a637ee00e9de9bf1db9104 diff --git a/manifest.uuid b/manifest.uuid index 7b06c9c521..43fdf15940 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -142cd359d37f1d8d53de32e329523d9a93c7d6e5 \ No newline at end of file +605eba4a756e7185119088e2242f82691d078b01 \ No newline at end of file diff --git a/src/build.c b/src/build.c index e89c744461..28eb55ab6c 100644 --- a/src/build.c +++ b/src/build.c @@ -1087,6 +1087,7 @@ void sqlite3AddColumn(Parse *pParse, Token *pName, Token *pType){ pCol->szEst = 1; }else{ pCol->affinity = sqlite3AffinityType(zType, &pCol->szEst); + pCol->colFlags |= COLFLAG_HASTYPE; } p->nCol++; pParse->constraintName.n = 0; @@ -1282,7 +1283,7 @@ void sqlite3AddPrimaryKey( int sortOrder /* SQLITE_SO_ASC or SQLITE_SO_DESC */ ){ Table *pTab = pParse->pNewTable; - const char *zName = 0; + Column *pCol = 0; int iCol = -1, i; int nTerm; if( pTab==0 || IN_DECLARE_VTAB ) goto primary_key_exit; @@ -1294,8 +1295,8 @@ void sqlite3AddPrimaryKey( pTab->tabFlags |= TF_HasPrimaryKey; if( pList==0 ){ iCol = pTab->nCol - 1; - pTab->aCol[iCol].colFlags |= COLFLAG_PRIMKEY; - zName = pTab->aCol[iCol].zName; + pCol = &pTab->aCol[iCol]; + pCol->colFlags |= COLFLAG_PRIMKEY; nTerm = 1; }else{ nTerm = pList->nExpr; @@ -1307,8 +1308,8 @@ void sqlite3AddPrimaryKey( const char *zCName = pCExpr->u.zToken; for(iCol=0; iColnCol; iCol++){ if( sqlite3StrICmp(zCName, pTab->aCol[iCol].zName)==0 ){ - pTab->aCol[iCol].colFlags |= COLFLAG_PRIMKEY; - zName = pTab->aCol[iCol].zName; + pCol = &pTab->aCol[iCol]; + pCol->colFlags |= COLFLAG_PRIMKEY; break; } } @@ -1316,8 +1317,8 @@ void sqlite3AddPrimaryKey( } } if( nTerm==1 - && zName - && sqlite3StrICmp(sqlite3StrNext(zName), "INTEGER")==0 + && pCol + && sqlite3StrICmp(sqlite3ColumnType(pCol,""), "INTEGER")==0 && sortOrder!=SQLITE_SO_DESC ){ pTab->iPKey = iCol; diff --git a/src/main.c b/src/main.c index 2e5ba08393..0c4cfbbea0 100644 --- a/src/main.c +++ b/src/main.c @@ -3343,8 +3343,7 @@ int sqlite3_table_column_metadata( ** explicitly declared column. Copy meta information from *pCol. */ if( pCol ){ - zDataType = sqlite3StrNext(pCol->zName); - if( zDataType[0]==0 ) zDataType = 0; + zDataType = sqlite3ColumnType(pCol,0); zCollSeq = pCol->zColl; notnull = pCol->notNull!=0; primarykey = (pCol->colFlags & COLFLAG_PRIMKEY)!=0; diff --git a/src/pragma.c b/src/pragma.c index 65c43ad1e5..e0a0255ec0 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -1066,7 +1066,6 @@ void sqlite3Pragma( setAllColumnNames(v, 6, azCol); assert( 6==ArraySize(azCol) ); sqlite3ViewGetColumnNames(pParse, pTab); for(i=0, pCol=pTab->aCol; inCol; i++, pCol++){ - const char *zName; if( IsHiddenColumn(pCol) ){ nHidden++; continue; @@ -1079,11 +1078,10 @@ void sqlite3Pragma( for(k=1; k<=pTab->nCol && pPk->aiColumn[k-1]!=i; k++){} } assert( pCol->pDflt==0 || pCol->pDflt->op==TK_SPAN ); - zName = pCol->zName; sqlite3VdbeMultiLoad(v, 1, "issisi", i-nHidden, - zName, - sqlite3StrNext(zName), + pCol->zName, + sqlite3ColumnType(pCol,""), pCol->notNull ? 1 : 0, pCol->pDflt ? pCol->pDflt->u.zToken : 0, k); diff --git a/src/select.c b/src/select.c index a62581efc1..ed76f621f9 100644 --- a/src/select.c +++ b/src/select.c @@ -1430,7 +1430,7 @@ static const char *columnTypeImpl( zOrigCol = "rowid"; }else{ zOrigCol = pTab->aCol[iCol].zName; - zType = sqlite3StrNext(zOrigCol); + zType = sqlite3ColumnType(&pTab->aCol[iCol],0); estWidth = pTab->aCol[iCol].szEst; } zOrigTab = pTab->zName; @@ -1442,7 +1442,7 @@ static const char *columnTypeImpl( if( iCol<0 ){ zType = "INTEGER"; }else{ - zType = sqlite3StrNext(pTab->aCol[iCol].zName); + zType = sqlite3ColumnType(&pTab->aCol[iCol],0); estWidth = pTab->aCol[iCol].szEst; } #endif diff --git a/src/sqliteInt.h b/src/sqliteInt.h index d256262b05..242ae8e2cf 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1604,6 +1604,7 @@ struct Column { */ #define COLFLAG_PRIMKEY 0x0001 /* Column is part of the primary key */ #define COLFLAG_HIDDEN 0x0002 /* A hidden column in a virtual table */ +#define COLFLAG_HASTYPE 0x0004 /* Type name follows column name */ /* ** A "Collating Sequence" is defined by an instance of the following @@ -3307,7 +3308,7 @@ int sqlite3IsIdChar(u8); */ int sqlite3StrICmp(const char*,const char*); int sqlite3Strlen30(const char*); -const char *sqlite3StrNext(const char*); +char *sqlite3ColumnType(Column*,char*); #define sqlite3StrNICmp sqlite3_strnicmp int sqlite3MallocInit(void); diff --git a/src/util.c b/src/util.c index 428dfd046c..08b0c46a5c 100644 --- a/src/util.c +++ b/src/util.c @@ -110,11 +110,15 @@ int sqlite3Strlen30(const char *z){ } /* -** The string z[] is followed immediately by another string. Return -** a poiner to that other string. +** Return the declared type of a column. Or return zDflt if the column +** has no declared type. +** +** The column type is an extra string stored after the zero-terminator on +** the column name if and only if the COLFLAG_HASTYPE flag is set. */ -const char *sqlite3StrNext(const char *z){ - return z + strlen(z) + 1; +char *sqlite3ColumnType(Column *pCol, char *zDflt){ + if( (pCol->colFlags & COLFLAG_HASTYPE)==0 ) return zDflt; + return pCol->zName + strlen(pCol->zName) + 1; } /* diff --git a/src/vtab.c b/src/vtab.c index ad8caef3bc..802a8cac3a 100644 --- a/src/vtab.c +++ b/src/vtab.c @@ -564,22 +564,16 @@ static int vtabCallConstructor( pTab->pVTable = pVTable; for(iCol=0; iColnCol; iCol++){ - char *zType = (char*)sqlite3StrNext(pTab->aCol[iCol].zName); + char *zType = sqlite3ColumnType(&pTab->aCol[iCol], ""); int nType; int i = 0; - if( !zType[0] ){ - pTab->tabFlags |= oooHidden; - continue; - } nType = sqlite3Strlen30(zType); - if( sqlite3StrNICmp("hidden", zType, 6)||(zType[6] && zType[6]!=' ') ){ - for(i=0; i Date: Wed, 23 Mar 2016 13:46:05 +0000 Subject: [PATCH 0201/1484] Update a requirement mark. No changes to code. FossilOrigin-Name: 412984642af40578ec611d8c0b7c0508cb5cf9c9 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/sqliteLimit.h | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 19c00ee626..187f8d0c9b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C The\ssqlite3_column_decltype()\sroutine\sshould\sreturn\sNULL,\snot\san\sempty\sstring,\nif\sthe\scolumn\shas\sno\sdeclared\stype. -D 2016-03-22T20:05:09.546 +C Update\sa\srequirement\smark.\s\sNo\schanges\sto\scode. +D 2016-03-23T13:46:05.453 F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66 @@ -359,7 +359,7 @@ F src/sqlite.h.in e877f141b15ef68ef28f84714e69d7234f9a071e F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 98f72cbfe00169c39089115427d06ea05fe4b4a2 F src/sqliteInt.h 3a68b48967a7d62fcb38572d27fd21ab4e4bcca3 -F src/sqliteLimit.h 7b28cf72cbd52f178bfc97ea266445e351f2cd24 +F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 F src/tclsqlite.c 4bf3bea9b03aeac176ac114700f35f76a1de4c8a @@ -1459,7 +1459,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 142cd359d37f1d8d53de32e329523d9a93c7d6e5 -R 54bb94e9ede3ebe9fafd5624cdd5946f +P 605eba4a756e7185119088e2242f82691d078b01 +R 0cef5aac6dc3fd4662874a0245bd6fe2 U drh -Z 8ae8a72878a637ee00e9de9bf1db9104 +Z 79401c6ddf17e634854d1f69b3d42451 diff --git a/manifest.uuid b/manifest.uuid index 43fdf15940..48f9df63e0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -605eba4a756e7185119088e2242f82691d078b01 \ No newline at end of file +412984642af40578ec611d8c0b7c0508cb5cf9c9 \ No newline at end of file diff --git a/src/sqliteLimit.h b/src/sqliteLimit.h index 4b5ddaadec..0554e61581 100644 --- a/src/sqliteLimit.h +++ b/src/sqliteLimit.h @@ -101,8 +101,8 @@ ** The suggested maximum number of in-memory pages to use for ** the main database table and for temporary tables. ** -** IMPLEMENTATION-OF: R-31093-59126 The default suggested cache size -** is 2000*1024 bytes. +** IMPLEMENTATION-OF: R-30185-15359 The default suggested cache size is -2000, +** which means the cache size is limited to 2048000 bytes of memory. ** IMPLEMENTATION-OF: R-48205-43578 The default suggested cache size can be ** altered using the SQLITE_DEFAULT_CACHE_SIZE compile-time options. */ From 848b190e4079cc60f3cbbc63e3ae6638cfe06d92 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 23 Mar 2016 15:04:00 +0000 Subject: [PATCH 0202/1484] Explicitly limit the size of fts5 tokens to 32768 bytes. FossilOrigin-Name: 70fc69eed9b09159899d7cbd1416a59d04210a63 --- ext/fts5/fts5Int.h | 4 +++ ext/fts5/fts5_expr.c | 2 ++ ext/fts5/fts5_index.c | 47 +++++++++++++++++++++++++---------- ext/fts5/fts5_storage.c | 2 ++ ext/fts5/test/fts5simple.test | 20 +++++++++++++++ manifest | 22 ++++++++-------- manifest.uuid | 2 +- 7 files changed, 74 insertions(+), 25 deletions(-) diff --git a/ext/fts5/fts5Int.h b/ext/fts5/fts5Int.h index 961206f2b3..c4e7506fb1 100644 --- a/ext/fts5/fts5Int.h +++ b/ext/fts5/fts5Int.h @@ -47,6 +47,10 @@ typedef sqlite3_uint64 u64; #endif +/* Truncate very long tokens to this many bytes. Hard limit is +** (65536-1-1-4-9)==65521 bytes. The limiting factor is the 16-bit offset +** field that occurs at the start of each leaf page (see fts5_index.c). */ +#define FTS5_MAX_TOKEN_SIZE 32768 /* ** Maximum number of prefix indexes on single FTS5 table. This must be diff --git a/ext/fts5/fts5_expr.c b/ext/fts5/fts5_expr.c index 0bc61414b0..eada84f70e 100644 --- a/ext/fts5/fts5_expr.c +++ b/ext/fts5/fts5_expr.c @@ -1493,6 +1493,7 @@ static int fts5ParseTokenize( /* If an error has already occurred, this is a no-op */ if( pCtx->rc!=SQLITE_OK ) return pCtx->rc; + if( nToken>FTS5_MAX_TOKEN_SIZE ) nToken = FTS5_MAX_TOKEN_SIZE; if( pPhrase && pPhrase->nTerm>0 && (tflags & FTS5_TOKEN_COLOCATED) ){ Fts5ExprTerm *pSyn; @@ -2495,6 +2496,7 @@ static int fts5ExprPopulatePoslistsCb( UNUSED_PARAM2(iUnused1, iUnused2); + if( nToken>FTS5_MAX_TOKEN_SIZE ) nToken = FTS5_MAX_TOKEN_SIZE; if( (tflags & FTS5_TOKEN_COLOCATED)==0 ) p->iOff++; for(i=0; inPhrase; i++){ Fts5ExprTerm *pTerm; diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index d08e65bfe6..c477ea6ca6 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -2321,6 +2321,18 @@ static void fts5LeafSeek( fts5SegIterLoadNPos(p, pIter); } +static sqlite3_stmt *fts5IdxSelectStmt(Fts5Index *p){ + if( p->pIdxSelect==0 ){ + Fts5Config *pConfig = p->pConfig; + fts5IndexPrepareStmt(p, &p->pIdxSelect, sqlite3_mprintf( + "SELECT pgno FROM '%q'.'%q_idx' WHERE " + "segid=? AND term<=? ORDER BY term DESC LIMIT 1", + pConfig->zDb, pConfig->zName + )); + } + return p->pIdxSelect; +} + /* ** Initialize the object pIter to point to term pTerm/nTerm within segment ** pSeg. If there is no such term in the index, the iterator is set to EOF. @@ -2338,6 +2350,7 @@ static void fts5SegIterSeekInit( int iPg = 1; int bGe = (flags & FTS5INDEX_QUERY_SCAN); int bDlidx = 0; /* True if there is a doclist-index */ + sqlite3_stmt *pIdxSelect = 0; assert( bGe==0 || (flags & FTS5INDEX_QUERY_DESC)==0 ); assert( pTerm && nTerm ); @@ -2346,23 +2359,16 @@ static void fts5SegIterSeekInit( /* This block sets stack variable iPg to the leaf page number that may ** contain term (pTerm/nTerm), if it is present in the segment. */ - if( p->pIdxSelect==0 ){ - Fts5Config *pConfig = p->pConfig; - fts5IndexPrepareStmt(p, &p->pIdxSelect, sqlite3_mprintf( - "SELECT pgno FROM '%q'.'%q_idx' WHERE " - "segid=? AND term<=? ORDER BY term DESC LIMIT 1", - pConfig->zDb, pConfig->zName - )); - } + pIdxSelect = fts5IdxSelectStmt(p); if( p->rc ) return; - sqlite3_bind_int(p->pIdxSelect, 1, pSeg->iSegid); - sqlite3_bind_blob(p->pIdxSelect, 2, pTerm, nTerm, SQLITE_STATIC); - if( SQLITE_ROW==sqlite3_step(p->pIdxSelect) ){ - i64 val = sqlite3_column_int(p->pIdxSelect, 0); + sqlite3_bind_int(pIdxSelect, 1, pSeg->iSegid); + sqlite3_bind_blob(pIdxSelect, 2, pTerm, nTerm, SQLITE_STATIC); + if( SQLITE_ROW==sqlite3_step(pIdxSelect) ){ + i64 val = sqlite3_column_int(pIdxSelect, 0); iPg = (int)(val>>1); bDlidx = (val & 0x0001); } - p->rc = sqlite3_reset(p->pIdxSelect); + p->rc = sqlite3_reset(pIdxSelect); if( iPgpgnoFirst ){ iPg = pSeg->pgnoFirst; @@ -3552,6 +3558,18 @@ static int fts5AllocateSegid(Fts5Index *p, Fts5Structure *pStruct){ } } assert( iSegid>0 && iSegid<=FTS5_MAX_SEGMENT ); + + { + sqlite3_stmt *pIdxSelect = fts5IdxSelectStmt(p); + if( p->rc==SQLITE_OK ){ + int rc; + u8 aBlob[2] = {0xff, 0xff}; + sqlite3_bind_int(pIdxSelect, 1, iSegid); + sqlite3_bind_blob(pIdxSelect, 2, aBlob, 2, SQLITE_STATIC); + assert( sqlite3_step(pIdxSelect)!=SQLITE_ROW ); + p->rc = sqlite3_reset(pIdxSelect); + } + } #endif } } @@ -3798,6 +3816,9 @@ static void fts5WriteFlushLeaf(Fts5Index *p, Fts5SegWriter *pWriter){ Fts5PageWriter *pPage = &pWriter->writer; i64 iRowid; +static int nCall = 0; +nCall++; + assert( (pPage->pgidx.n==0)==(pWriter->bFirstTermInPage) ); /* Set the szLeaf header field. */ diff --git a/ext/fts5/fts5_storage.c b/ext/fts5/fts5_storage.c index 3cca990ed5..90df3396c3 100644 --- a/ext/fts5/fts5_storage.c +++ b/ext/fts5/fts5_storage.c @@ -369,6 +369,7 @@ static int fts5StorageInsertCallback( Fts5InsertCtx *pCtx = (Fts5InsertCtx*)pContext; Fts5Index *pIdx = pCtx->pStorage->pIndex; UNUSED_PARAM2(iUnused1, iUnused2); + if( nToken>FTS5_MAX_TOKEN_SIZE ) nToken = FTS5_MAX_TOKEN_SIZE; if( (tflags & FTS5_TOKEN_COLOCATED)==0 || pCtx->szCol==0 ){ pCtx->szCol++; } @@ -815,6 +816,7 @@ static int fts5StorageIntegrityCallback( int iCol; UNUSED_PARAM2(iUnused1, iUnused2); + if( nToken>FTS5_MAX_TOKEN_SIZE ) nToken = FTS5_MAX_TOKEN_SIZE; if( (tflags & FTS5_TOKEN_COLOCATED)==0 || pCtx->szCol==0 ){ pCtx->szCol++; diff --git a/ext/fts5/test/fts5simple.test b/ext/fts5/test/fts5simple.test index 3483e40ba5..2bc02cf49a 100644 --- a/ext/fts5/test/fts5simple.test +++ b/ext/fts5/test/fts5simple.test @@ -448,4 +448,24 @@ do_execsql_test 20.2 { INSERT INTO x1(x1) VALUES('integrity-check'); } {} +#------------------------------------------------------------------------- +reset_db +set doc "a b [string repeat x 100000]" +do_execsql_test 21.0 { + CREATE VIRTUAL TABLE x1 USING fts5(x); + INSERT INTO x1(rowid, x) VALUES(11111, $doc); + INSERT INTO x1(rowid, x) VALUES(11112, $doc); +} +do_execsql_test 21.1 { + INSERT INTO x1(x1) VALUES('integrity-check'); +} +do_execsql_test 21.2 { + SELECT rowid FROM x1($doc); +} {11111 11112} +do_execsql_test 21.3 { + DELETE FROM x1 WHERE rowid=11111; + INSERT INTO x1(x1) VALUES('integrity-check'); + SELECT rowid FROM x1($doc); +} {11112} + finish_test diff --git a/manifest b/manifest index 187f8d0c9b..79eb4b3013 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\sa\srequirement\smark.\s\sNo\schanges\sto\scode. -D 2016-03-23T13:46:05.453 +C Explicitly\slimit\sthe\ssize\sof\sfts5\stokens\sto\s32768\sbytes. +D 2016-03-23T15:04:00.239 F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66 @@ -98,15 +98,15 @@ F ext/fts3/unicode/mkunicode.tcl 2debed3f582d77b3fdd0b8830880250021571fd8 F ext/fts3/unicode/parseunicode.tcl da577d1384810fb4e2b209bf3313074353193e95 F ext/fts5/extract_api_docs.tcl a36e54ec777172ddd3f9a88daf593b00848368e0 F ext/fts5/fts5.h ff9c2782e8ed890b0de2f697a8d63971939e70c7 -F ext/fts5/fts5Int.h 4e507abebae0d7d3ac9b8daebf049d5153d00961 +F ext/fts5/fts5Int.h 3677076aecbf645a7f2a019115c6a4ec3272dd78 F ext/fts5/fts5_aux.c daa57fb45216491814520bbb587e97bf81ced458 F ext/fts5/fts5_buffer.c 4c1502d4c956cd092c89ce4480867f9d8bf325cd F ext/fts5/fts5_config.c 5af9c360e99669d29f06492c370892394aba0857 -F ext/fts5/fts5_expr.c 35e9d92c89e7c7ea0759b73d24da1ecb7630a24b +F ext/fts5/fts5_expr.c 5ca4bafe29aa3d27683c90e836192e4aefd20a3f F ext/fts5/fts5_hash.c f3a7217c86eb8f272871be5f6aa1b6798960a337 -F ext/fts5/fts5_index.c 19df86d29d24cc56bfb01a6a07dcaac227d2fcdf +F ext/fts5/fts5_index.c b271b19dd28d3501772c3a9317272add4751af95 F ext/fts5/fts5_main.c b4a0fc5bf17f2f1f056ee76cdd7d2af08b360f55 -F ext/fts5/fts5_storage.c 98e3129047d250fc5acc4a4ba7ba4fde9b0ae030 +F ext/fts5/fts5_storage.c 3309c6a8e34b974513016fd1ef47c83f5898f94c F ext/fts5/fts5_tcl.c f8731e0508299bd43f1a2eff7dbeaac870768966 F ext/fts5/fts5_test_mi.c 783b86697ebf773c18fc109992426c0173a055bc F ext/fts5/fts5_test_tok.c db08af63673c3a7d39f053b36fd6e065017706be @@ -180,7 +180,7 @@ F ext/fts5/test/fts5rank.test 7e9e64eac7245637f6f2033aec4b292aaf611aab F ext/fts5/test/fts5rebuild.test 03935f617ace91ed23a6099c7c74d905227ff29b F ext/fts5/test/fts5restart.test c17728fdea26e7d0f617d22ad5b4b2862b994c17 F ext/fts5/test/fts5rowid.test 16908a99d6efc9ba21081b4f2b86b3fc699839a6 -F ext/fts5/test/fts5simple.test 5b7b05bcc89bcb718a0fc7f473092d3513cc8e19 +F ext/fts5/test/fts5simple.test cd23d4072ea095d652c9b6db12284cc642e49c98 F ext/fts5/test/fts5simple2.test 98377ae1ff7749a42c21fe1a139c1ed312522c46 F ext/fts5/test/fts5simple3.test 8e71733b3d1b0e695011d02c68ebc5ca40b6124e F ext/fts5/test/fts5synonym.test 6475d189c2e20d60795808f83e36bf9318708d48 @@ -1459,7 +1459,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 605eba4a756e7185119088e2242f82691d078b01 -R 0cef5aac6dc3fd4662874a0245bd6fe2 -U drh -Z 79401c6ddf17e634854d1f69b3d42451 +P 412984642af40578ec611d8c0b7c0508cb5cf9c9 +R 7ff8c5a33cf0f5a9bc31dcb4123a3529 +U dan +Z a8f8abdf00b8979540d6caa40226ffc8 diff --git a/manifest.uuid b/manifest.uuid index 48f9df63e0..efdf00d8e6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -412984642af40578ec611d8c0b7c0508cb5cf9c9 \ No newline at end of file +70fc69eed9b09159899d7cbd1416a59d04210a63 \ No newline at end of file From 997de998a8f4c84e9fdcc91cb308d06864dff90b Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 23 Mar 2016 15:53:45 +0000 Subject: [PATCH 0203/1484] Remove an unused local variable from FTS5. FossilOrigin-Name: 0ed693c29f184223cde3b3d51f0e06273e586803 --- ext/fts5/fts5_index.c | 1 - manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index c477ea6ca6..1200f5707b 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -3562,7 +3562,6 @@ static int fts5AllocateSegid(Fts5Index *p, Fts5Structure *pStruct){ { sqlite3_stmt *pIdxSelect = fts5IdxSelectStmt(p); if( p->rc==SQLITE_OK ){ - int rc; u8 aBlob[2] = {0xff, 0xff}; sqlite3_bind_int(pIdxSelect, 1, iSegid); sqlite3_bind_blob(pIdxSelect, 2, aBlob, 2, SQLITE_STATIC); diff --git a/manifest b/manifest index 79eb4b3013..c04dd5f417 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Explicitly\slimit\sthe\ssize\sof\sfts5\stokens\sto\s32768\sbytes. -D 2016-03-23T15:04:00.239 +C Remove\san\sunused\slocal\svariable\sfrom\sFTS5. +D 2016-03-23T15:53:45.875 F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66 @@ -104,7 +104,7 @@ F ext/fts5/fts5_buffer.c 4c1502d4c956cd092c89ce4480867f9d8bf325cd F ext/fts5/fts5_config.c 5af9c360e99669d29f06492c370892394aba0857 F ext/fts5/fts5_expr.c 5ca4bafe29aa3d27683c90e836192e4aefd20a3f F ext/fts5/fts5_hash.c f3a7217c86eb8f272871be5f6aa1b6798960a337 -F ext/fts5/fts5_index.c b271b19dd28d3501772c3a9317272add4751af95 +F ext/fts5/fts5_index.c fdd82bb421a5d1e64d004acb43f4dd9970c8d2b3 F ext/fts5/fts5_main.c b4a0fc5bf17f2f1f056ee76cdd7d2af08b360f55 F ext/fts5/fts5_storage.c 3309c6a8e34b974513016fd1ef47c83f5898f94c F ext/fts5/fts5_tcl.c f8731e0508299bd43f1a2eff7dbeaac870768966 @@ -1459,7 +1459,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 412984642af40578ec611d8c0b7c0508cb5cf9c9 -R 7ff8c5a33cf0f5a9bc31dcb4123a3529 -U dan -Z a8f8abdf00b8979540d6caa40226ffc8 +P 70fc69eed9b09159899d7cbd1416a59d04210a63 +R 873e340080925d4861d8b0305a1e9665 +U drh +Z 80f86ca0927f258d1530b1b8654e3fe4 diff --git a/manifest.uuid b/manifest.uuid index efdf00d8e6..e4a6517082 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -70fc69eed9b09159899d7cbd1416a59d04210a63 \ No newline at end of file +0ed693c29f184223cde3b3d51f0e06273e586803 \ No newline at end of file From 231ee688083efe09940c2b6c60c4527d35c2d809 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 23 Mar 2016 16:32:29 +0000 Subject: [PATCH 0204/1484] Fix "ifcapable" tests in capi3.test and capi3c.test so that the tests work with more build configurations. FossilOrigin-Name: 3fa88f68c3e1bbb3421cb0d2b82b9bb3fe7b9b14 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- test/capi3.test | 2 +- test/capi3c.test | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index c04dd5f417..339c6e1490 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\san\sunused\slocal\svariable\sfrom\sFTS5. -D 2016-03-23T15:53:45.875 +C Fix\s"ifcapable"\stests\sin\scapi3.test\sand\scapi3c.test\sso\sthat\sthe\stests\swork\swith\smore\sbuild\sconfigurations. +D 2016-03-23T16:32:29.404 F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66 @@ -523,9 +523,9 @@ F test/busy.test 76b4887f8b9160ba903c1ac22e8ff406ad6ae2f0 F test/cache.test 13bc046b26210471ca6f2889aceb1ea52dc717de F test/cacheflush.test af25bb1509df04c1da10e38d8f322d66eceedf61 F test/capi2.test 011c16da245fdc0106a2785035de6b242c05e738 -F test/capi3.test 860dafdc04f651a67781018cb1a0b179d22d7d15 +F test/capi3.test f0c66919e43d42e1572a69be039e4527a931b00f F test/capi3b.test efb2b9cfd127efa84433cd7a2d72ce0454ae0dc4 -F test/capi3c.test b28ec47692f0fc50eb61b2d464d8d52e816b3732 +F test/capi3c.test 0b9edb0c2156a964b9271cd5ea7ae56736cc2fcb F test/capi3d.test 485048dc5cd07bc68011e4917ad035ad6047ab82 F test/capi3e.test 3d49c01ef2a1a55f41d73cba2b23b5059ec460fe F test/cast.test 4c275cbdc8202d6f9c54a3596701719868ac7dc3 @@ -1459,7 +1459,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 70fc69eed9b09159899d7cbd1416a59d04210a63 -R 873e340080925d4861d8b0305a1e9665 -U drh -Z 80f86ca0927f258d1530b1b8654e3fe4 +P 0ed693c29f184223cde3b3d51f0e06273e586803 +R 405228ca43a6aac7fb0de536de78cc72 +U dan +Z fb0a5f0fe48a39fd4b3b3bb440d1982d diff --git a/manifest.uuid b/manifest.uuid index e4a6517082..0d41a4b253 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0ed693c29f184223cde3b3d51f0e06273e586803 \ No newline at end of file +3fa88f68c3e1bbb3421cb0d2b82b9bb3fe7b9b14 \ No newline at end of file diff --git a/test/capi3.test b/test/capi3.test index 8096d29bec..84889f5faf 100644 --- a/test/capi3.test +++ b/test/capi3.test @@ -929,7 +929,7 @@ do_test capi3-11.10 { do_test capi3-11.11 { sqlite3_step $STMT } {SQLITE_DONE} -ifcapable api_armor { +ifcapable !autoreset { do_test capi3-11.12armor { sqlite3_step $STMT sqlite3_step $STMT diff --git a/test/capi3c.test b/test/capi3c.test index 91c02561b1..57cf146c73 100644 --- a/test/capi3c.test +++ b/test/capi3c.test @@ -868,7 +868,7 @@ do_test capi3c-11.10 { do_test capi3c-11.11 { sqlite3_step $STMT } {SQLITE_DONE} -ifcapable api_armor { +ifcapable !autoreset { do_test capi3c-11.12armor { sqlite3_step $STMT sqlite3_step $STMT From c5412d533c73b8e247cd7850817ddf07dcb8068f Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 23 Mar 2016 17:54:19 +0000 Subject: [PATCH 0205/1484] Avoid calling realloc() with a zero size in fuzzcheck.c. FossilOrigin-Name: a1fd14694c1adc54e5c443ebfdef38e38637f5c5 --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/fuzzcheck.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 339c6e1490..f86978ab06 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\s"ifcapable"\stests\sin\scapi3.test\sand\scapi3c.test\sso\sthat\sthe\stests\swork\swith\smore\sbuild\sconfigurations. -D 2016-03-23T16:32:29.404 +C Avoid\scalling\srealloc()\swith\sa\szero\ssize\sin\sfuzzcheck.c. +D 2016-03-23T17:54:19.633 F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66 @@ -773,7 +773,7 @@ F test/fuzz2.test 76dc35b32b6d6f965259508508abce75a6c4d7e1 F test/fuzz3.test b47377143f0c80f91ed29d722861077ff34415d5 F test/fuzz_common.tcl a87dfbb88c2a6b08a38e9a070dabd129e617b45b F test/fuzz_malloc.test 328f70aaca63adf29b4c6f06505ed0cf57ca7c26 -F test/fuzzcheck.c 93bb9d309888634615e21ef98d1c30d51483e942 +F test/fuzzcheck.c f01d432d001ba29e7916df8411be7d4e7cddc574 F test/fuzzdata1.db 7ee3227bad0e7ccdeb08a9e6822916777073c664 F test/fuzzdata2.db f03a420d3b822cc82e4f894ca957618fbe9c4973 F test/fuzzdata3.db c6586d3e3cef0fbc18108f9bb649aa77bfc38aba @@ -1459,7 +1459,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 0ed693c29f184223cde3b3d51f0e06273e586803 -R 405228ca43a6aac7fb0de536de78cc72 -U dan -Z fb0a5f0fe48a39fd4b3b3bb440d1982d +P 3fa88f68c3e1bbb3421cb0d2b82b9bb3fe7b9b14 +R 6050811335a4694faefeb0d2dc871228 +U drh +Z bf4eed3170d70e06db77678976293947 diff --git a/manifest.uuid b/manifest.uuid index 0d41a4b253..fc3163dd80 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3fa88f68c3e1bbb3421cb0d2b82b9bb3fe7b9b14 \ No newline at end of file +a1fd14694c1adc54e5c443ebfdef38e38637f5c5 \ No newline at end of file diff --git a/test/fuzzcheck.c b/test/fuzzcheck.c index 1e0ce86e66..1d11b2986f 100644 --- a/test/fuzzcheck.c +++ b/test/fuzzcheck.c @@ -189,7 +189,7 @@ static int progressHandler(void *pVdbeLimitFlag){ ** Reallocate memory. Show and error and quit if unable. */ static void *safe_realloc(void *pOld, int szNew){ - void *pNew = realloc(pOld, szNew); + void *pNew = realloc(pOld, szNew<=0 ? 1 : szNew); if( pNew==0 ) fatalError("unable to realloc for %d bytes", szNew); return pNew; } From cc47eac00555ac1af94fde3ab9f8c7d2b6bf8766 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 24 Mar 2016 15:09:14 +0000 Subject: [PATCH 0206/1484] Fix some test scripts so that they work with various permutations. FossilOrigin-Name: f4d234b5013bf93b6eac7f8be6d4c074cf9f5293 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- test/snapshot.test | 9 +++++++++ test/snapshot_fault.test | 2 +- 4 files changed, 19 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index f86978ab06..19ae78878e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\scalling\srealloc()\swith\sa\szero\ssize\sin\sfuzzcheck.c. -D 2016-03-23T17:54:19.633 +C Fix\ssome\stest\sscripts\sso\sthat\sthey\swork\swith\svarious\spermutations. +D 2016-03-24T15:09:14.368 F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66 @@ -1042,8 +1042,8 @@ F test/skipscan2.test d1d1450952b7275f0b0a3a981f0230532743951a F test/skipscan3.test ec5bab3f81c7038b43450e7b3062e04a198bdbb5 F test/skipscan5.test 67817a4b6857c47e0e33ba3e506da6f23ef68de2 F test/skipscan6.test 5866039d03a56f5bd0b3d172a012074a1d90a15b -F test/snapshot.test c03eb5ba1602df33c1edc1d12393d6ca7a282a46 -F test/snapshot_fault.test 25973aeb1b86a280800e0bcf1eb5ce70e9ef57ab +F test/snapshot.test 9ed24c792fb05382814258daf68b2256f23de57f +F test/snapshot_fault.test 062ff0438a074978d45e9f9a92e7ad459b74ee73 F test/soak.test 0b5b6375c9f4110c828070b826b3b4b0bb65cd5f F test/softheap1.test 843cd84db9891b2d01b9ab64cef3e9020f98d087 F test/sort.test c2adc635c2564241fefec0b3a68391ef6868fd3b @@ -1459,7 +1459,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 3fa88f68c3e1bbb3421cb0d2b82b9bb3fe7b9b14 -R 6050811335a4694faefeb0d2dc871228 -U drh -Z bf4eed3170d70e06db77678976293947 +P a1fd14694c1adc54e5c443ebfdef38e38637f5c5 +R 36309b59b7cae947470048aeed54391f +U dan +Z b85dfb4995f4f514e1ad3337ff91de1c diff --git a/manifest.uuid b/manifest.uuid index fc3163dd80..7a09317688 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a1fd14694c1adc54e5c443ebfdef38e38637f5c5 \ No newline at end of file +f4d234b5013bf93b6eac7f8be6d4c074cf9f5293 \ No newline at end of file diff --git a/test/snapshot.test b/test/snapshot.test index ba3a666796..c6710e3691 100644 --- a/test/snapshot.test +++ b/test/snapshot.test @@ -17,6 +17,15 @@ source $testdir/tester.tcl ifcapable !snapshot {finish_test; return} set testprefix snapshot +# This test does not work with the inmemory_journal permutation. The reason +# is that each connection opened as part of this permutation executes +# "PRAGMA journal_mode=memory", which fails if the database is in wal mode +# and there are one or more existing connections. +if {[permutation]=="inmemory_journal"} { + finish_test + return +} + #------------------------------------------------------------------------- # Check some error conditions in snapshot_get(). It is an error if: # diff --git a/test/snapshot_fault.test b/test/snapshot_fault.test index 3ac13daefd..f90690e3f6 100644 --- a/test/snapshot_fault.test +++ b/test/snapshot_fault.test @@ -146,7 +146,7 @@ do_faultsim_test 3.0 -prep { error $msg } } -test { - faultsim_test_result {0 {}} {1 SQLITE_IOERR} \ + faultsim_test_result {0 {}} {1 SQLITE_IOERR} {1 SQLITE_NOMEM} \ {1 SQLITE_IOERR_NOMEM} {1 SQLITE_IOERR_READ} if {$testrc==0} { set res [db eval { From d38a2e2511daf120d37c58c95e333e29bdb7f3a4 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 24 Mar 2016 15:32:19 +0000 Subject: [PATCH 0207/1484] Larger margins for one memsubsys1 range check when running with a non-zero reserved-bytes value. FossilOrigin-Name: 6db1d1fbc6c1acc896fa635dfdc5564800502c40 --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/memsubsys1.test | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 19ae78878e..63d4b9b8b2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\ssome\stest\sscripts\sso\sthat\sthey\swork\swith\svarious\spermutations. -D 2016-03-24T15:09:14.368 +C Larger\smargins\sfor\sone\smemsubsys1\srange\scheck\swhen\srunning\swith\sa\nnon-zero\sreserved-bytes\svalue. +D 2016-03-24T15:32:19.097 F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66 @@ -892,7 +892,7 @@ F test/manydb.test 28385ae2087967aa05c38624cec7d96ec74feb3e F test/mem5.test c6460fba403c5703141348cd90de1c294188c68f F test/memdb.test c1f2a343ad14398d5d6debda6ea33e80d0dafcc7 F test/memleak.test 10b9c6c57e19fc68c32941495e9ba1c50123f6e2 -F test/memsubsys1.test 69924593856040e266fdd9aa1ecb4d5a0888eb12 +F test/memsubsys1.test 6d268d0ae90f8d61a2356a1838665654d83de518 F test/memsubsys2.test 3e4a8d0c05fd3e5fa92017c64666730a520c7e08 F test/minmax.test 42fbad0e81afaa6e0de41c960329f2b2c3526efd F test/minmax2.test b44bae787fc7b227597b01b0ca5575c7cb54d3bc @@ -1459,7 +1459,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a1fd14694c1adc54e5c443ebfdef38e38637f5c5 -R 36309b59b7cae947470048aeed54391f -U dan -Z b85dfb4995f4f514e1ad3337ff91de1c +P f4d234b5013bf93b6eac7f8be6d4c074cf9f5293 +R 918e030f39e9a5a455482186d2119a1e +U drh +Z 4c4813ba0d5bb38b250579ca5f32f159 diff --git a/manifest.uuid b/manifest.uuid index 7a09317688..75cadabba3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f4d234b5013bf93b6eac7f8be6d4c074cf9f5293 \ No newline at end of file +6db1d1fbc6c1acc896fa635dfdc5564800502c40 \ No newline at end of file diff --git a/test/memsubsys1.test b/test/memsubsys1.test index f0b060fc9f..36427f9bae 100644 --- a/test/memsubsys1.test +++ b/test/memsubsys1.test @@ -257,7 +257,7 @@ do_test memsubsys1-7.4 { } 0 do_test memsubsys1-7.5 { set maxreq [lindex [sqlite3_status SQLITE_STATUS_MALLOC_SIZE 0] 2] - expr {$maxreq<4100 + 4200*[nonzero_reserved_bytes]} + expr {$maxreq<(4100 + 8200*[nonzero_reserved_bytes])} } 1 do_test memsubsys1-7.6 { set s_used [lindex [sqlite3_status SQLITE_STATUS_SCRATCH_USED 0] 2] From eb2329bed34ec38248e7d78ed34fc79eb9976cc2 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Thu, 24 Mar 2016 20:36:47 +0000 Subject: [PATCH 0208/1484] Prevent negative values of SQLITE_DEFAULT_CACHE_SIZE from making SQLITE_WIN32_HEAP_INIT_SIZE negative. FossilOrigin-Name: e0737f5236ed3e85bd03203c880ee41b34619137 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/os_win.c | 14 +++++++++++++- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 63d4b9b8b2..3716cd5a4b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Larger\smargins\sfor\sone\smemsubsys1\srange\scheck\swhen\srunning\swith\sa\nnon-zero\sreserved-bytes\svalue. -D 2016-03-24T15:32:19.097 +C Prevent\snegative\svalues\sof\sSQLITE_DEFAULT_CACHE_SIZE\sfrom\smaking\sSQLITE_WIN32_HEAP_INIT_SIZE\snegative. +D 2016-03-24T20:36:47.715 F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66 @@ -338,7 +338,7 @@ F src/os.h 91ff889115ecd01f436d3611f7f5ea4dc12d92f1 F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85 F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa F src/os_unix.c b1ccb273771f41dbdbe0ba7c1ad63c38ad5972ec -F src/os_win.c 17493f12b0b023c2d5a349b6860009f0d45e08d6 +F src/os_win.c 7c071f7f8f04827ab25a8f441080832be58688e9 F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c 38718a019ca762ba4f6795425d5a54db70d1790d F src/pager.h e1d38a2f14849e219df0f91f8323504d134c8a56 @@ -1459,7 +1459,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P f4d234b5013bf93b6eac7f8be6d4c074cf9f5293 -R 918e030f39e9a5a455482186d2119a1e -U drh -Z 4c4813ba0d5bb38b250579ca5f32f159 +P 6db1d1fbc6c1acc896fa635dfdc5564800502c40 +R 5e26e94cafc58d6fd55eccc4e6c637ee +U mistachkin +Z 1088b9c27d83d36a2ae2a2fd6824e14f diff --git a/manifest.uuid b/manifest.uuid index 75cadabba3..1b00761a79 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6db1d1fbc6c1acc896fa635dfdc5564800502c40 \ No newline at end of file +e0737f5236ed3e85bd03203c880ee41b34619137 \ No newline at end of file diff --git a/src/os_win.c b/src/os_win.c index 3f9fefcac4..7ae833d3f5 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -344,11 +344,23 @@ struct winFile { # define SQLITE_WIN32_HEAP_CREATE (TRUE) #endif +/* + * This is cache size used in the calculation of the initial size of the + * Win32-specific heap. It cannot be negative. + */ +#ifndef SQLITE_WIN32_CACHE_SIZE +# if SQLITE_DEFAULT_CACHE_SIZE>=0 +# define SQLITE_WIN32_CACHE_SIZE (SQLITE_DEFAULT_CACHE_SIZE) +# else +# define SQLITE_WIN32_CACHE_SIZE (-(SQLITE_DEFAULT_CACHE_SIZE)) +# endif +#endif + /* * The initial size of the Win32-specific heap. This value may be zero. */ #ifndef SQLITE_WIN32_HEAP_INIT_SIZE -# define SQLITE_WIN32_HEAP_INIT_SIZE ((SQLITE_DEFAULT_CACHE_SIZE) * \ +# define SQLITE_WIN32_HEAP_INIT_SIZE ((SQLITE_WIN32_CACHE_SIZE) * \ (SQLITE_DEFAULT_PAGE_SIZE) + 4194304) #endif From cb620b479783d42e637b7b54631879daa89f30f7 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 24 Mar 2016 20:55:03 +0000 Subject: [PATCH 0209/1484] Make test cases in shell1.test robust against TCL deciding to quote strings using lots of backslashes. FossilOrigin-Name: 817e93f42c09eb876421e27eb8eceb7b077cb45d --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/shell1.test | 10 ++++++---- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 3716cd5a4b..7c64a1af14 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Prevent\snegative\svalues\sof\sSQLITE_DEFAULT_CACHE_SIZE\sfrom\smaking\sSQLITE_WIN32_HEAP_INIT_SIZE\snegative. -D 2016-03-24T20:36:47.715 +C Make\stest\scases\sin\sshell1.test\srobust\sagainst\sTCL\sdeciding\sto\squote\sstrings\nusing\slots\sof\sbackslashes. +D 2016-03-24T20:55:03.263 F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66 @@ -1028,7 +1028,7 @@ F test/sharedA.test 0cdf1a76dfa00e6beee66af5b534b1e8df2720f5 F test/sharedB.test 16cc7178e20965d75278f410943109b77b2e645e F test/shared_err.test 2f2aee20db294b9924e81f6ccbe60f19e21e8506 F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304 -F test/shell1.test e7dac9830b7d80432be9cebfae06eff9c18675f5 +F test/shell1.test 94538224ee7b7a52952dea67d2633b358abde271 F test/shell2.test 2e7a32c9ee03c6398478637d72416d5b9ebd9777 F test/shell3.test c39453d3012a39ffec944566eca8a6bda10a2284 F test/shell4.test 69995ee1cc278eb149aa8746ce1f935f4eaf98b9 @@ -1459,7 +1459,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 6db1d1fbc6c1acc896fa635dfdc5564800502c40 -R 5e26e94cafc58d6fd55eccc4e6c637ee -U mistachkin -Z 1088b9c27d83d36a2ae2a2fd6824e14f +P e0737f5236ed3e85bd03203c880ee41b34619137 +R 203f39504a0cd47826f57431bf7289e6 +U drh +Z ba68271edf3c6755b87aa606194c0bcd diff --git a/manifest.uuid b/manifest.uuid index 1b00761a79..d8ea0b1033 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e0737f5236ed3e85bd03203c880ee41b34619137 \ No newline at end of file +817e93f42c09eb876421e27eb8eceb7b077cb45d \ No newline at end of file diff --git a/test/shell1.test b/test/shell1.test index 1f1f3de320..b08c08ffc0 100644 --- a/test/shell1.test +++ b/test/shell1.test @@ -275,12 +275,14 @@ do_test shell1-3.2.4 { # .databases List names and files of attached databases do_test shell1-3.3.1 { - catchcmd "-csv test.db" ".databases" -} "/0 +.*main +[string map {/ .} [string range [get_pwd] 0 10]].*/" + set x [catchcmd "-csv test.db" ".databases"] + set x [subst -nocommands -novariables $x] +} "/0.+main.+[string map {/ .} [string range [get_pwd] 0 10]].*/" do_test shell1-3.3.2 { # extra arguments ignored - catchcmd "test.db" ".databases BAD" -} "/0 +.*main +[string map {/ .} [string range [get_pwd] 0 10]].*/" + set x [catchcmd "test.db" ".databases BAD"] + set x [subst -nocommands -novariables $x] +} "/0.+main.+[string map {/ .} [string range [get_pwd] 0 10]].*/" # .dump ?TABLE? ... Dump the database in an SQL text format # If TABLE specified, only dump tables matching From ddb2b4a31015c8ad93f52f8c07ae8e592e6d02c6 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 25 Mar 2016 12:10:32 +0000 Subject: [PATCH 0210/1484] Fix two instances of undefined behavior in the C code - both harmless for all current compilers. FossilOrigin-Name: 99fd194c83dbcfcdcc582983b86678b85b1b9570 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/build.c | 6 +++--- src/vdbe.c | 4 +++- 4 files changed, 14 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 7c64a1af14..9995948b77 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\stest\scases\sin\sshell1.test\srobust\sagainst\sTCL\sdeciding\sto\squote\sstrings\nusing\slots\sof\sbackslashes. -D 2016-03-24T20:55:03.263 +C Fix\stwo\sinstances\sof\sundefined\sbehavior\sin\sthe\sC\scode\s-\sboth\sharmless\sfor\nall\scurrent\scompilers. +D 2016-03-25T12:10:32.929 F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66 @@ -300,7 +300,7 @@ F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 F src/btree.c 577fb5674e2f0aa0a38246afc19e1885a0b8c9b0 F src/btree.h a5008b9afe56e8e54ade6c436a910f112defcca9 F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 -F src/build.c 7d1a5e64fcd10110edc8ce9ffb710d06af0a59f5 +F src/build.c 39faaaeecb77eb3936d4bd5024e865e3836ca323 F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 60e135af364d777a9ab41c97e5e89cd224da6198 @@ -419,7 +419,7 @@ F src/update.c 56b3db7edff0110360a12b76af97c39ebe3ea8b8 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 8873d696c9ccc4206058c402e09e101f1b81561a F src/vacuum.c feb1eabb20987983d9350cad98299b21fa811f52 -F src/vdbe.c f19741f2d8b33e8f09cd2219570b6c9ed924c3f1 +F src/vdbe.c cd990451b504507b455cc649d46dad51f2835a67 F src/vdbe.h 6f44193e7be52fd5f7c308175a936555b1e6b101 F src/vdbeInt.h f88d3115e9bde33b01d81f0dd26d8dd51f995991 F src/vdbeapi.c 95b1f8e527240a18a9aea41a655b013bf07a7009 @@ -1459,7 +1459,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e0737f5236ed3e85bd03203c880ee41b34619137 -R 203f39504a0cd47826f57431bf7289e6 +P 817e93f42c09eb876421e27eb8eceb7b077cb45d +R aca0111531dd13b444e2634c40aa3c16 U drh -Z ba68271edf3c6755b87aa606194c0bcd +Z a7abe0dd0ebfdb648c54f66b764dd2a5 diff --git a/manifest.uuid b/manifest.uuid index d8ea0b1033..eec1194704 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -817e93f42c09eb876421e27eb8eceb7b077cb45d \ No newline at end of file +99fd194c83dbcfcdcc582983b86678b85b1b9570 \ No newline at end of file diff --git a/src/build.c b/src/build.c index 28eb55ab6c..d4d0c173cc 100644 --- a/src/build.c +++ b/src/build.c @@ -1056,9 +1056,6 @@ void sqlite3AddColumn(Parse *pParse, Token *pName, Token *pType){ memcpy(z, pName->z, pName->n); z[pName->n] = 0; sqlite3Dequote(z); - zType = z + sqlite3Strlen30(z) + 1; - memcpy(zType, pType->z, pType->n); - zType[pType->n] = 0; for(i=0; inCol; i++){ if( sqlite3_stricmp(z, p->aCol[i].zName)==0 ){ sqlite3ErrorMsg(pParse, "duplicate column name: %s", z); @@ -1086,6 +1083,9 @@ void sqlite3AddColumn(Parse *pParse, Token *pName, Token *pType){ pCol->affinity = SQLITE_AFF_BLOB; pCol->szEst = 1; }else{ + zType = z + sqlite3Strlen30(z) + 1; + memcpy(zType, pType->z, pType->n); + zType[pType->n] = 0; pCol->affinity = sqlite3AffinityType(zType, &pCol->szEst); pCol->colFlags |= COLFLAG_HASTYPE; } diff --git a/src/vdbe.c b/src/vdbe.c index 90269cbe30..e6d17ad26e 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2524,7 +2524,6 @@ case OP_Column: { }while( i<=p2 && zHdrnHdrParsed = i; pC->iHdrOffset = (u32)(zHdr - zData); - if( pC->aRow==0 ) sqlite3VdbeMemRelease(&sMem); /* The record is corrupt if any of the following are true: ** (1) the bytes of the header extend past the declared header size @@ -2534,9 +2533,12 @@ case OP_Column: { if( (zHdr>=zEndHdr && (zHdr>zEndHdr || offset64!=pC->payloadSize)) || (offset64 > pC->payloadSize) ){ + if( pC->aRow==0 ) sqlite3VdbeMemRelease(&sMem); rc = SQLITE_CORRUPT_BKPT; goto abort_due_to_error; } + if( pC->aRow==0 ) sqlite3VdbeMemRelease(&sMem); + }else{ t = 0; } From 5729c31dafbf5bb7796f62cb30e3b6c7ae32d4d4 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 25 Mar 2016 17:09:16 +0000 Subject: [PATCH 0211/1484] Add the catchcmd_collapse_space command and use it to help make shell testing more robust against TCL space escapes. FossilOrigin-Name: 93caabb66082f76ef161a51ac822b919517a7171 --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/shell1.test | 6 ++---- test/tester.tcl | 11 +++++++++++ 4 files changed, 21 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 9995948b77..b34eb55e70 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\stwo\sinstances\sof\sundefined\sbehavior\sin\sthe\sC\scode\s-\sboth\sharmless\sfor\nall\scurrent\scompilers. -D 2016-03-25T12:10:32.929 +C Add\sthe\scatchcmd_collapse_space\scommand\sand\suse\sit\sto\shelp\smake\sshell\stesting\nmore\srobust\sagainst\sTCL\sspace\sescapes. +D 2016-03-25T17:09:16.750 F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66 @@ -1028,7 +1028,7 @@ F test/sharedA.test 0cdf1a76dfa00e6beee66af5b534b1e8df2720f5 F test/sharedB.test 16cc7178e20965d75278f410943109b77b2e645e F test/shared_err.test 2f2aee20db294b9924e81f6ccbe60f19e21e8506 F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304 -F test/shell1.test 94538224ee7b7a52952dea67d2633b358abde271 +F test/shell1.test 12d1774936facc17a889e0c31877670ef5526f8c F test/shell2.test 2e7a32c9ee03c6398478637d72416d5b9ebd9777 F test/shell3.test c39453d3012a39ffec944566eca8a6bda10a2284 F test/shell4.test 69995ee1cc278eb149aa8746ce1f935f4eaf98b9 @@ -1088,7 +1088,7 @@ F test/tclsqlite.test c6d9f546f79d15d0134c1e06583fb3ee0c3afad3 F test/tempdb.test bd92eba8f20e16a9136e434e20b280794de3cdb6 F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30 F test/temptrigger.test 8ec228b0db5d7ebc4ee9b458fc28cb9e7873f5e1 -F test/tester.tcl f2b99e912d4da1e5755969b8614febd883885c8b +F test/tester.tcl 5604f2697e8fa9b12b6180122d84e1a9093ca8a3 F test/thread001.test 9f22fd3525a307ff42a326b6bc7b0465be1745a5 F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58 F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7 @@ -1459,7 +1459,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 817e93f42c09eb876421e27eb8eceb7b077cb45d -R aca0111531dd13b444e2634c40aa3c16 +P 99fd194c83dbcfcdcc582983b86678b85b1b9570 +R cfe872b896f4c791395847cc13daead3 U drh -Z a7abe0dd0ebfdb648c54f66b764dd2a5 +Z 0d389fd777e66fc5d8e3b6840aab7902 diff --git a/manifest.uuid b/manifest.uuid index eec1194704..aa0e2349f2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -99fd194c83dbcfcdcc582983b86678b85b1b9570 \ No newline at end of file +93caabb66082f76ef161a51ac822b919517a7171 \ No newline at end of file diff --git a/test/shell1.test b/test/shell1.test index b08c08ffc0..87edc3c816 100644 --- a/test/shell1.test +++ b/test/shell1.test @@ -275,13 +275,11 @@ do_test shell1-3.2.4 { # .databases List names and files of attached databases do_test shell1-3.3.1 { - set x [catchcmd "-csv test.db" ".databases"] - set x [subst -nocommands -novariables $x] + catchcmd_collapse_space "-csv test.db" ".databases" } "/0.+main.+[string map {/ .} [string range [get_pwd] 0 10]].*/" do_test shell1-3.3.2 { # extra arguments ignored - set x [catchcmd "test.db" ".databases BAD"] - set x [subst -nocommands -novariables $x] + catchcmd_collapse_space "test.db" ".databases BAD" } "/0.+main.+[string map {/ .} [string range [get_pwd] 0 10]].*/" # .dump ?TABLE? ... Dump the database in an SQL text format diff --git a/test/tester.tcl b/test/tester.tcl index eadaf2eb31..75963e108d 100644 --- a/test/tester.tcl +++ b/test/tester.tcl @@ -823,6 +823,17 @@ proc catchcmd {db {cmd ""}} { list $rc $msg } +proc catchcmd_collapse_space {db {cmd ""}} { + global CLI + set out [open cmds.txt w] + puts $out $cmd + close $out + set line "exec $CLI $db < cmds.txt" + set rc [catch { eval $line } msg] + regsub -all {\s+} $msg { } msg + list $rc $msg +} + proc catchcmdex {db {cmd ""}} { global CLI set out [open cmds.txt w] From 82452480ea1d3e7bad96914a82377bda1ae10ed1 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Fri, 25 Mar 2016 17:19:57 +0000 Subject: [PATCH 0212/1484] In the Win32 VFS, avoid trying to use rand_s() on Windows CE. FossilOrigin-Name: 183350fa7cc6a5ab8bd0a86cab231a6e4c915890 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/os_win.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index b34eb55e70..8558fe1c18 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\scatchcmd_collapse_space\scommand\sand\suse\sit\sto\shelp\smake\sshell\stesting\nmore\srobust\sagainst\sTCL\sspace\sescapes. -D 2016-03-25T17:09:16.750 +C In\sthe\sWin32\sVFS,\savoid\strying\sto\suse\srand_s()\son\sWindows\sCE. +D 2016-03-25T17:19:57.501 F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66 @@ -338,7 +338,7 @@ F src/os.h 91ff889115ecd01f436d3611f7f5ea4dc12d92f1 F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85 F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa F src/os_unix.c b1ccb273771f41dbdbe0ba7c1ad63c38ad5972ec -F src/os_win.c 7c071f7f8f04827ab25a8f441080832be58688e9 +F src/os_win.c ff870d89f4cb088a04cbf5ea0cbd9ff1b089ff4a F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c 38718a019ca762ba4f6795425d5a54db70d1790d F src/pager.h e1d38a2f14849e219df0f91f8323504d134c8a56 @@ -1459,7 +1459,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 99fd194c83dbcfcdcc582983b86678b85b1b9570 -R cfe872b896f4c791395847cc13daead3 -U drh -Z 0d389fd777e66fc5d8e3b6840aab7902 +P 93caabb66082f76ef161a51ac822b919517a7171 +R 5aa2c9bfd4173374520b94533760d2da +U mistachkin +Z 700a9aa1ab3cd081c3674af5a63a2d5f diff --git a/manifest.uuid b/manifest.uuid index aa0e2349f2..f363c251a7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -93caabb66082f76ef161a51ac822b919517a7171 \ No newline at end of file +183350fa7cc6a5ab8bd0a86cab231a6e4c915890 \ No newline at end of file diff --git a/src/os_win.c b/src/os_win.c index 7ae833d3f5..f64a7d43a7 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -5436,7 +5436,7 @@ static int winRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ EntropyGatherer e; UNUSED_PARAMETER(pVfs); memset(zBuf, 0, nBuf); -#if defined(_MSC_VER) && _MSC_VER>=1400 +#if defined(_MSC_VER) && _MSC_VER>=1400 && !SQLITE_OS_WINCE rand_s((unsigned int*)zBuf); /* rand_s() is not available with MinGW */ #endif /* defined(_MSC_VER) && _MSC_VER>=1400 */ e.a = (unsigned char*)zBuf; From 4f69540b7168fc0d83e6191ae8e6c42d3c3d1946 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 25 Mar 2016 20:10:20 +0000 Subject: [PATCH 0213/1484] Do not run the shell3.test module under mingw because of mingw's dodgy command-line parsing. FossilOrigin-Name: a7c080a90a236fbc18b9a42b78dbed4dd8a25160 --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/shell3.test | 7 +++++++ 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 8558fe1c18..b02404a99f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\sthe\sWin32\sVFS,\savoid\strying\sto\suse\srand_s()\son\sWindows\sCE. -D 2016-03-25T17:19:57.501 +C Do\snot\srun\sthe\sshell3.test\smodule\sunder\smingw\sbecause\sof\smingw's\sdodgy\ncommand-line\sparsing. +D 2016-03-25T20:10:20.882 F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66 @@ -1030,7 +1030,7 @@ F test/shared_err.test 2f2aee20db294b9924e81f6ccbe60f19e21e8506 F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304 F test/shell1.test 12d1774936facc17a889e0c31877670ef5526f8c F test/shell2.test 2e7a32c9ee03c6398478637d72416d5b9ebd9777 -F test/shell3.test c39453d3012a39ffec944566eca8a6bda10a2284 +F test/shell3.test 1448cb715b8b5f139d96e0e4d3e94ae31fd0a713 F test/shell4.test 69995ee1cc278eb149aa8746ce1f935f4eaf98b9 F test/shell5.test 50a732c1c2158b1cd62cf53975ce1ea7ce6b9dc9 F test/shortread1.test bb591ef20f0fd9ed26d0d12e80eee6d7ac8897a3 @@ -1459,7 +1459,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 93caabb66082f76ef161a51ac822b919517a7171 -R 5aa2c9bfd4173374520b94533760d2da -U mistachkin -Z 700a9aa1ab3cd081c3674af5a63a2d5f +P 183350fa7cc6a5ab8bd0a86cab231a6e4c915890 +R 9c42844e710d61bbe7fe13708d65edbf +U drh +Z ea11cf0717b5526a95e62f1683bac7ce diff --git a/manifest.uuid b/manifest.uuid index f363c251a7..7dafaa5910 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -183350fa7cc6a5ab8bd0a86cab231a6e4c915890 \ No newline at end of file +a7c080a90a236fbc18b9a42b78dbed4dd8a25160 \ No newline at end of file diff --git a/test/shell3.test b/test/shell3.test index 3ded8f5ccd..08d31f24eb 100644 --- a/test/shell3.test +++ b/test/shell3.test @@ -26,6 +26,13 @@ db close forcedelete test.db test.db-journal test.db-wal sqlite3 db test.db +if {[info exists env(MSYSCON)] && $env(MSYSCON)=="sh.exe"} { + puts "shell3 tests do not work with the mingw shell due to dodgy\ + command-line parsing" + finish_test + return +} + #---------------------------------------------------------------------------- # shell3-1.*: Basic tests for running SQL statments from command line. # From 15707ac992d801d2d637a0b59c21a9b7c6413cf5 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 26 Mar 2016 13:26:35 +0000 Subject: [PATCH 0214/1484] Update shell1.test tests to deal with backslash escaping in TCL on Windows-style pathnames. FossilOrigin-Name: 219a251e182bf43376fbc8ae1ce6f77f18a1b092 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/shell1.test | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index b02404a99f..71c59993da 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Do\snot\srun\sthe\sshell3.test\smodule\sunder\smingw\sbecause\sof\smingw's\sdodgy\ncommand-line\sparsing. -D 2016-03-25T20:10:20.882 +C Update\sshell1.test\stests\sto\sdeal\swith\sbackslash\sescaping\sin\sTCL\son\sWindows-style\npathnames. +D 2016-03-26T13:26:35.335 F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66 @@ -1028,7 +1028,7 @@ F test/sharedA.test 0cdf1a76dfa00e6beee66af5b534b1e8df2720f5 F test/sharedB.test 16cc7178e20965d75278f410943109b77b2e645e F test/shared_err.test 2f2aee20db294b9924e81f6ccbe60f19e21e8506 F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304 -F test/shell1.test 12d1774936facc17a889e0c31877670ef5526f8c +F test/shell1.test 25de3bf73c2a24fd3f0240396a3719d8679fd156 F test/shell2.test 2e7a32c9ee03c6398478637d72416d5b9ebd9777 F test/shell3.test 1448cb715b8b5f139d96e0e4d3e94ae31fd0a713 F test/shell4.test 69995ee1cc278eb149aa8746ce1f935f4eaf98b9 @@ -1459,7 +1459,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 183350fa7cc6a5ab8bd0a86cab231a6e4c915890 -R 9c42844e710d61bbe7fe13708d65edbf +P a7c080a90a236fbc18b9a42b78dbed4dd8a25160 +R 4fb0bc40e02c2e4ca004a6ff507130b3 U drh -Z ea11cf0717b5526a95e62f1683bac7ce +Z 2e9acf052ed53f3a7f143522bd4e6960 diff --git a/manifest.uuid b/manifest.uuid index 7dafaa5910..37f54adfef 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a7c080a90a236fbc18b9a42b78dbed4dd8a25160 \ No newline at end of file +219a251e182bf43376fbc8ae1ce6f77f18a1b092 \ No newline at end of file diff --git a/test/shell1.test b/test/shell1.test index 87edc3c816..44886b9f38 100644 --- a/test/shell1.test +++ b/test/shell1.test @@ -276,11 +276,11 @@ do_test shell1-3.2.4 { # .databases List names and files of attached databases do_test shell1-3.3.1 { catchcmd_collapse_space "-csv test.db" ".databases" -} "/0.+main.+[string map {/ .} [string range [get_pwd] 0 10]].*/" +} "/0.+main.+[string map {/ ".{1,2}"} [string range [get_pwd] 0 10]].*/" do_test shell1-3.3.2 { # extra arguments ignored catchcmd_collapse_space "test.db" ".databases BAD" -} "/0.+main.+[string map {/ .} [string range [get_pwd] 0 10]].*/" +} "/0.+main.+[string map {/ ".{1,2}"} [string range [get_pwd] 0 10]].*/" # .dump ?TABLE? ... Dump the database in an SQL text format # If TABLE specified, only dump tables matching From eaa544d44d7c06dc858a8acbd5b10852f2032dad Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 26 Mar 2016 14:41:13 +0000 Subject: [PATCH 0215/1484] Remove the catchcmd_collapse_space procedure in tester.tcl - no longer needed. FossilOrigin-Name: 3bd499d3bdf4e80f83513966c2ee9dd11e67cbd1 --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/shell1.test | 4 ++-- test/tester.tcl | 11 ----------- 4 files changed, 10 insertions(+), 21 deletions(-) diff --git a/manifest b/manifest index 71c59993da..a1183f5492 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\sshell1.test\stests\sto\sdeal\swith\sbackslash\sescaping\sin\sTCL\son\sWindows-style\npathnames. -D 2016-03-26T13:26:35.335 +C Remove\sthe\scatchcmd_collapse_space\sprocedure\sin\stester.tcl\s-\sno\slonger\sneeded. +D 2016-03-26T14:41:13.450 F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66 @@ -1028,7 +1028,7 @@ F test/sharedA.test 0cdf1a76dfa00e6beee66af5b534b1e8df2720f5 F test/sharedB.test 16cc7178e20965d75278f410943109b77b2e645e F test/shared_err.test 2f2aee20db294b9924e81f6ccbe60f19e21e8506 F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304 -F test/shell1.test 25de3bf73c2a24fd3f0240396a3719d8679fd156 +F test/shell1.test d36a68f0d560b7f50177845e409910ed855b1a27 F test/shell2.test 2e7a32c9ee03c6398478637d72416d5b9ebd9777 F test/shell3.test 1448cb715b8b5f139d96e0e4d3e94ae31fd0a713 F test/shell4.test 69995ee1cc278eb149aa8746ce1f935f4eaf98b9 @@ -1088,7 +1088,7 @@ F test/tclsqlite.test c6d9f546f79d15d0134c1e06583fb3ee0c3afad3 F test/tempdb.test bd92eba8f20e16a9136e434e20b280794de3cdb6 F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30 F test/temptrigger.test 8ec228b0db5d7ebc4ee9b458fc28cb9e7873f5e1 -F test/tester.tcl 5604f2697e8fa9b12b6180122d84e1a9093ca8a3 +F test/tester.tcl f2b99e912d4da1e5755969b8614febd883885c8b F test/thread001.test 9f22fd3525a307ff42a326b6bc7b0465be1745a5 F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58 F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7 @@ -1459,7 +1459,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a7c080a90a236fbc18b9a42b78dbed4dd8a25160 -R 4fb0bc40e02c2e4ca004a6ff507130b3 +P 219a251e182bf43376fbc8ae1ce6f77f18a1b092 +R c56b0aa6959f9b74a14b039c91d81909 U drh -Z 2e9acf052ed53f3a7f143522bd4e6960 +Z 93b7eb233dfe81212bc718ee014c61a9 diff --git a/manifest.uuid b/manifest.uuid index 37f54adfef..bd4275f994 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -219a251e182bf43376fbc8ae1ce6f77f18a1b092 \ No newline at end of file +3bd499d3bdf4e80f83513966c2ee9dd11e67cbd1 \ No newline at end of file diff --git a/test/shell1.test b/test/shell1.test index 44886b9f38..8669559e44 100644 --- a/test/shell1.test +++ b/test/shell1.test @@ -275,11 +275,11 @@ do_test shell1-3.2.4 { # .databases List names and files of attached databases do_test shell1-3.3.1 { - catchcmd_collapse_space "-csv test.db" ".databases" + catchcmd "-csv test.db" ".databases" } "/0.+main.+[string map {/ ".{1,2}"} [string range [get_pwd] 0 10]].*/" do_test shell1-3.3.2 { # extra arguments ignored - catchcmd_collapse_space "test.db" ".databases BAD" + catchcmd "test.db" ".databases BAD" } "/0.+main.+[string map {/ ".{1,2}"} [string range [get_pwd] 0 10]].*/" # .dump ?TABLE? ... Dump the database in an SQL text format diff --git a/test/tester.tcl b/test/tester.tcl index 75963e108d..eadaf2eb31 100644 --- a/test/tester.tcl +++ b/test/tester.tcl @@ -823,17 +823,6 @@ proc catchcmd {db {cmd ""}} { list $rc $msg } -proc catchcmd_collapse_space {db {cmd ""}} { - global CLI - set out [open cmds.txt w] - puts $out $cmd - close $out - set line "exec $CLI $db < cmds.txt" - set rc [catch { eval $line } msg] - regsub -all {\s+} $msg { } msg - list $rc $msg -} - proc catchcmdex {db {cmd ""}} { global CLI set out [open cmds.txt w] From 60c4249fcc5bb322e3f380ad3181dbb381a7f404 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 26 Mar 2016 15:36:36 +0000 Subject: [PATCH 0216/1484] More changes to the shellN.test scripts to get them working on all variations of Windows. FossilOrigin-Name: 8213c2f58167243411d29cc58e303b4be656f756 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- test/shell1.test | 2 +- test/shell2.test | 2 +- test/shell3.test | 11 ++++++++--- 5 files changed, 19 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index a1183f5492..8d623daff5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sthe\scatchcmd_collapse_space\sprocedure\sin\stester.tcl\s-\sno\slonger\sneeded. -D 2016-03-26T14:41:13.450 +C More\schanges\sto\sthe\sshellN.test\sscripts\sto\sget\sthem\sworking\son\sall\svariations\nof\sWindows. +D 2016-03-26T15:36:36.768 F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66 @@ -1028,9 +1028,9 @@ F test/sharedA.test 0cdf1a76dfa00e6beee66af5b534b1e8df2720f5 F test/sharedB.test 16cc7178e20965d75278f410943109b77b2e645e F test/shared_err.test 2f2aee20db294b9924e81f6ccbe60f19e21e8506 F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304 -F test/shell1.test d36a68f0d560b7f50177845e409910ed855b1a27 -F test/shell2.test 2e7a32c9ee03c6398478637d72416d5b9ebd9777 -F test/shell3.test 1448cb715b8b5f139d96e0e4d3e94ae31fd0a713 +F test/shell1.test dff5b20ad989770aface6d714491121172dfe8b0 +F test/shell2.test e242a9912f44f4c23c3d1d802a83e934e84c853b +F test/shell3.test da513d522ef6f01cee8475dcf8332bff8982b3dd F test/shell4.test 69995ee1cc278eb149aa8746ce1f935f4eaf98b9 F test/shell5.test 50a732c1c2158b1cd62cf53975ce1ea7ce6b9dc9 F test/shortread1.test bb591ef20f0fd9ed26d0d12e80eee6d7ac8897a3 @@ -1459,7 +1459,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 219a251e182bf43376fbc8ae1ce6f77f18a1b092 -R c56b0aa6959f9b74a14b039c91d81909 +P 3bd499d3bdf4e80f83513966c2ee9dd11e67cbd1 +R 0f980ceb534899c3d74e7aadbdc990e8 U drh -Z 93b7eb233dfe81212bc718ee014c61a9 +Z 6df6f858842cee4837ac5cccff369bba diff --git a/manifest.uuid b/manifest.uuid index bd4275f994..23fb133ea2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3bd499d3bdf4e80f83513966c2ee9dd11e67cbd1 \ No newline at end of file +8213c2f58167243411d29cc58e303b4be656f756 \ No newline at end of file diff --git a/test/shell1.test b/test/shell1.test index 8669559e44..49b6a7923d 100644 --- a/test/shell1.test +++ b/test/shell1.test @@ -45,7 +45,7 @@ do_test shell1-1.1.1b { } {1 1} # error on extra options do_test shell1-1.1.2 { - catchcmd "test.db \"select 3\" \"select 4\"" "" + catchcmd "test.db \"select+3\" \"select+4\"" "" } {0 {3 4}} # error on extra options diff --git a/test/shell2.test b/test/shell2.test index 9388b719b3..2de6bf7514 100644 --- a/test/shell2.test +++ b/test/shell2.test @@ -43,7 +43,7 @@ do_test shell2-1.1.1 { # Shell silently ignores extra parameters. # Ticket [f5cb008a65]. do_test shell2-1.2.1 { - set rc [catch { eval exec $CLI \":memory:\" \"select 3\" \"select 4\" } msg] + set rc [catch { eval exec $CLI \":memory:\" \"select+3\" \"select+4\" } msg] list $rc $msg } {0 {3 4}} diff --git a/test/shell3.test b/test/shell3.test index 08d31f24eb..6e38021d0c 100644 --- a/test/shell3.test +++ b/test/shell3.test @@ -26,9 +26,14 @@ db close forcedelete test.db test.db-journal test.db-wal sqlite3 db test.db -if {[info exists env(MSYSCON)] && $env(MSYSCON)=="sh.exe"} { - puts "shell3 tests do not work with the mingw shell due to dodgy\ - command-line parsing" +# There are inconsistencies in command-line argument quoting on Windows. +# In particular, individual applications are responsible for command-line +# parsing in Windows, not the shell. Depending on whether the sqlite3.exe +# program is compiled with MinGW or MSVC, the command-line parsing is +# different. This causes problems for the tests below. To avoid +# issues, these tests are disabled for windows. +# +if {$::tcl_platform(platform)=="windows"} { finish_test return } From 72cd360caffca027211972e1189e26c8ad121995 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 28 Mar 2016 11:01:54 +0000 Subject: [PATCH 0217/1484] Fix the multiplexor so that it does not assume that the xGetLastError method is non-NULL in the child VFS. FossilOrigin-Name: f6a88cccbc0c62a0b453f4711298c9d5e1882b18 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/test_multiplex.c | 6 +++++- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 8d623daff5..943c941a23 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C More\schanges\sto\sthe\sshellN.test\sscripts\sto\sget\sthem\sworking\son\sall\svariations\nof\sWindows. -D 2016-03-26T15:36:36.768 +C Fix\sthe\smultiplexor\sso\sthat\sit\sdoes\snot\sassume\sthat\sthe\sxGetLastError\smethod\nis\snon-NULL\sin\sthe\schild\sVFS. +D 2016-03-28T11:01:54.323 F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66 @@ -390,7 +390,7 @@ F src/test_intarray.h 9dc57417fb65bc7835cc18548852cc08cc062202 F src/test_journal.c 5360fbe1d1e4416ca36290562fd5a2e3f70f32aa F src/test_loadext.c 337056bae59f80b9eb00ba82088b39d0f4fe6dfd F src/test_malloc.c 96df9381a1ff1f6d3805ff7231b9baf1386aaabf -F src/test_multiplex.c 6a088d8d9d4aad4bec45dd8878af11b15900702d +F src/test_multiplex.c 6a9de820fcaaf506c59aa14bc8693822333cea48 F src/test_multiplex.h c08e4e8f8651f0c5e0509b138ff4d5b43ed1f5d3 F src/test_mutex.c dbdfaff8580071f2212a0deae3325a93a737819c F src/test_onefile.c 38f7cbe79d5bafe95bde683cc3a53b8ca16daf10 @@ -1459,7 +1459,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 3bd499d3bdf4e80f83513966c2ee9dd11e67cbd1 -R 0f980ceb534899c3d74e7aadbdc990e8 +P 8213c2f58167243411d29cc58e303b4be656f756 +R 345c74a0cb9568a53ff6b8825c4a812b U drh -Z 6df6f858842cee4837ac5cccff369bba +Z 80e7037d98d6e1826970b484373d3274 diff --git a/manifest.uuid b/manifest.uuid index 23fb133ea2..7c1af05774 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8213c2f58167243411d29cc58e303b4be656f756 \ No newline at end of file +f6a88cccbc0c62a0b453f4711298c9d5e1882b18 \ No newline at end of file diff --git a/src/test_multiplex.c b/src/test_multiplex.c index 82845ea7e1..07dcbbc1aa 100644 --- a/src/test_multiplex.c +++ b/src/test_multiplex.c @@ -717,7 +717,11 @@ static int multiplexCurrentTime(sqlite3_vfs *a, double *b){ return gMultiplex.pOrigVfs->xCurrentTime(gMultiplex.pOrigVfs, b); } static int multiplexGetLastError(sqlite3_vfs *a, int b, char *c){ - return gMultiplex.pOrigVfs->xGetLastError(gMultiplex.pOrigVfs, b, c); + if( gMultiplex.pOrigVfs->xGetLastError ){ + return gMultiplex.pOrigVfs->xGetLastError(gMultiplex.pOrigVfs, b, c); + }else{ + return 0; + } } static int multiplexCurrentTimeInt64(sqlite3_vfs *a, sqlite3_int64 *b){ return gMultiplex.pOrigVfs->xCurrentTimeInt64(gMultiplex.pOrigVfs, b); From 10df23fe4f73a8eb1bd820f22b6e65e3bcbfd09d Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 29 Mar 2016 10:14:15 +0000 Subject: [PATCH 0218/1484] Version 3.12.0 FossilOrigin-Name: e9bb4cf40f4971974a74468ef922bdee481c988b --- manifest | 11 +++++++---- manifest.uuid | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/manifest b/manifest index 943c941a23..769e820b33 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\smultiplexor\sso\sthat\sit\sdoes\snot\sassume\sthat\sthe\sxGetLastError\smethod\nis\snon-NULL\sin\sthe\schild\sVFS. -D 2016-03-28T11:01:54.323 +C Version\s3.12.0 +D 2016-03-29T10:14:15.762 F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66 @@ -1459,7 +1459,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 8213c2f58167243411d29cc58e303b4be656f756 +P f6a88cccbc0c62a0b453f4711298c9d5e1882b18 R 345c74a0cb9568a53ff6b8825c4a812b +T +bgcolor * #d0c0ff +T +sym-relaese * +T +sym-version-3.12.0 * U drh -Z 80e7037d98d6e1826970b484373d3274 +Z 9c957a50c25c5de44ce9010b47906f30 diff --git a/manifest.uuid b/manifest.uuid index 7c1af05774..21845f2bab 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f6a88cccbc0c62a0b453f4711298c9d5e1882b18 \ No newline at end of file +e9bb4cf40f4971974a74468ef922bdee481c988b \ No newline at end of file From fbcd3130f6b11d4037917284a9ccf6b839dd5ee4 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 30 Mar 2016 12:20:24 +0000 Subject: [PATCH 0219/1484] Improvements to the performance testing program "speedtest1.c" and the shell script that invokes it. FossilOrigin-Name: e4bee561fdead5d35c24da3fe8a11bf6548550c6 --- manifest | 17 +++++++---------- manifest.uuid | 2 +- test/speedtest1.c | 3 ++- tool/run-speed-test.sh | 36 +++++++++++++++++++++++++++++------- 4 files changed, 39 insertions(+), 19 deletions(-) diff --git a/manifest b/manifest index 769e820b33..0b01f20998 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Version\s3.12.0 -D 2016-03-29T10:14:15.762 +C Improvements\sto\sthe\sperformance\stesting\sprogram\s"speedtest1.c"\sand\sthe\nshell\sscript\sthat\sinvokes\sit. +D 2016-03-30T12:20:24.594 F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66 @@ -1060,7 +1060,7 @@ F test/speed3.test d32043614c08c53eafdc80f33191d5bd9b920523 F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715 F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b -F test/speedtest1.c 1478cb3fb64ad30f291ddca87ca9dbd72ff552aa +F test/speedtest1.c 21af8db2492a903835b654517ac8d90aed0af91f F test/spellfix.test f9c1f431e2c096c8775fec032952320c0e4700db F test/spellfix2.test dfc8f519a3fc204cb2dfa8b4f29821ae90f6f8c3 F test/spellfix3.test 0f9efaaa502a0e0a09848028518a6fb096c8ad33 @@ -1412,7 +1412,7 @@ F tool/pagesig.c ff0ca355fd3c2398e933da5e22439bbff89b803b F tool/replace.tcl 7727c60a04299b65a92f5e1590896fea0f25b9e0 F tool/restore_jrnl.tcl 6957a34f8f1f0f8285e07536225ec3b292a9024a F tool/rollback-test.c 9fc98427d1e23e84429d7e6d07d9094fbdec65a5 -F tool/run-speed-test.sh 0ae485af4fe9f826e2b494be8c81f8ca9e222a4a +F tool/run-speed-test.sh f95d19fd669b68c4c38b6b475242841d47c66076 F tool/showdb.c 82dca79a999b2701c62417636345e9974151fdad F tool/showjournal.c 5bad7ae8784a43d2b270d953060423b8bd480818 F tool/showlocks.c 9920bcc64f58378ff1118caead34147201f48c68 @@ -1459,10 +1459,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P f6a88cccbc0c62a0b453f4711298c9d5e1882b18 -R 345c74a0cb9568a53ff6b8825c4a812b -T +bgcolor * #d0c0ff -T +sym-relaese * -T +sym-version-3.12.0 * +P e9bb4cf40f4971974a74468ef922bdee481c988b +R 4acc2ba84abf0860d40142ef07554f22 U drh -Z 9c957a50c25c5de44ce9010b47906f30 +Z 4975a52cd95acaed6ad2d9bf0b3f9807 diff --git a/manifest.uuid b/manifest.uuid index 21845f2bab..3d3b955b01 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e9bb4cf40f4971974a74468ef922bdee481c988b \ No newline at end of file +e4bee561fdead5d35c24da3fe8a11bf6548550c6 \ No newline at end of file diff --git a/test/speedtest1.c b/test/speedtest1.c index d7f2af47b8..8ed0424f88 100644 --- a/test/speedtest1.c +++ b/test/speedtest1.c @@ -1236,7 +1236,8 @@ int main(int argc, char **argv){ int rc; /* API return code */ /* Display the version of SQLite being tested */ - printf("Speedtest1 for SQLite %s %.50s\n", sqlite3_libversion(), sqlite3_sourceid()); + printf("-- Speedtest1 for SQLite %s %.50s\n", + sqlite3_libversion(), sqlite3_sourceid()); /* Process command-line arguments */ g.zWR = ""; diff --git a/tool/run-speed-test.sh b/tool/run-speed-test.sh index ee2ceac660..0e970ea0f6 100644 --- a/tool/run-speed-test.sh +++ b/tool/run-speed-test.sh @@ -12,7 +12,7 @@ # # summary-$BASE.txt # Copy of standard output # cout-$BASE.txt # cachegrind output -# explain-$BASE.txt # EXPLAIN listings +# explain-$BASE.txt # EXPLAIN listings (only with --explain) # if test "$1" = "" then @@ -21,9 +21,10 @@ then fi NAME=$1 shift -CC_OPTS="-DSQLITE_ENABLE_RTREE" -SPEEDTEST_OPTS="--shrink-memory --reprepare" +CC_OPTS="-DSQLITE_ENABLE_RTREE -DSQLITE_ENABLE_MEMSYS5" +SPEEDTEST_OPTS="--shrink-memory --reprepare --heap 10000000 64" SIZE=5 +doExplain=0 while test "$1" != ""; do case $1 in --reprepare) @@ -35,12 +36,29 @@ while test "$1" != ""; do --utf16be) SPEEDTEST_OPTS="$SPEEDTEST_OPTS $1" ;; + --stats) + SPEEDTEST_OPTS="$SPEEDTEST_OPTS $1" + ;; --without-rowid) SPEEDTEST_OPTS="$SPEEDTEST_OPTS $1" ;; + --nomemstat) + SPEEDTEST_OPTS="$SPEEDTEST_OPTS $1" + ;; + --wal) + SPEEDTEST_OPTS="$SPEEDTEST_OPTS --journal wal" + ;; --size) shift; SIZE=$1 ;; + --explain) + doExplain=1 + ;; + --heap) + CC_OPTS="$CC_OPTS -DSQLITE_ENABLE_MEMSYS5" + shift; + SPEEDTEST_OPTS="$SPEEDTEST_OPTS --heap $1 64" + ;; *) CC_OPTS="$CC_OPTS $1" ;; @@ -54,9 +72,11 @@ echo "CC_OPTS = $CC_OPTS" | tee -a summary-$NAME.txt rm -f cachegrind.out.* speedtest1 speedtest1.db sqlite3.o gcc -g -Os -Wall -I. $CC_OPTS -c sqlite3.c size sqlite3.o | tee -a summary-$NAME.txt -gcc -g -Os -Wall -I. $CC_OPTS \ - -DSQLITE_ENABLE_EXPLAIN_COMMENTS \ - ./shell.c ./sqlite3.c -o sqlite3 -ldl -lpthread +if test $doExplain -eq 1; then + gcc -g -Os -Wall -I. $CC_OPTS \ + -DSQLITE_ENABLE_EXPLAIN_COMMENTS \ + ./shell.c ./sqlite3.c -o sqlite3 -ldl -lpthread +fi SRC=./speedtest1.c gcc -g -Os -Wall -I. $CC_OPTS $SRC ./sqlite3.o -o speedtest1 -ldl -lpthread ls -l speedtest1 | tee -a summary-$NAME.txt @@ -65,4 +85,6 @@ valgrind --tool=cachegrind ./speedtest1 speedtest1.db \ size sqlite3.o | tee -a summary-$NAME.txt wc sqlite3.c cg_anno.tcl cachegrind.out.* >cout-$NAME.txt -./speedtest1 --explain $SPEEDTEST_OPTS | ./sqlite3 >explain-$NAME.txt +if test $doExplain -eq 1; then + ./speedtest1 --explain $SPEEDTEST_OPTS | ./sqlite3 >explain-$NAME.txt +fi From 74c3302fd1931b0f4a10c9c660dbf368502efbbb Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 30 Mar 2016 12:56:55 +0000 Subject: [PATCH 0220/1484] Avoid compiler warnings and excess opcodes when SQLITE_ENABLE_PREUPDATE_HOOK is not used. Fix the EXPLAIN output for P4_TABLE opcodes. FossilOrigin-Name: 5ab46d760dff327491703478d6d7c7c44a0147ca --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/update.c | 6 ++++++ src/vdbe.c | 13 ++++++++++--- src/vdbeInt.h | 5 +++-- src/vdbeaux.c | 6 ++++++ 6 files changed, 35 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index a2911f768d..bb8ac6846d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\schanges\sfor\s3.12.0. -D 2016-03-29T10:19:29.541 +C Avoid\scompiler\swarnings\sand\sexcess\sopcodes\swhen\sSQLITE_ENABLE_PREUPDATE_HOOK\nis\snot\sused.\s\sFix\sthe\sEXPLAIN\soutput\sfor\sP4_TABLE\sopcodes. +D 2016-03-30T12:56:55.161 F Makefile.in e812bb732d7af01baa09f1278bd4f4a2e3a09449 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e6ee58b849c116d5554024f524cbf61f064f6f01 @@ -435,15 +435,15 @@ F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c 3d338cdd00d916ce8a05c397001d64ed58e6fe1c F src/treeview.c e4b41a37530a191579d3c53142cc44ee2eb99373 F src/trigger.c e14840ee0c3e549e758ec9bf3e4146e166002280 -F src/update.c 14c6916d0194a7f25ad429292f4831b8c31e93d9 +F src/update.c 3e67ab3c0814635f355fb1f8ab010a2b9e016e7d F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 8873d696c9ccc4206058c402e09e101f1b81561a F src/vacuum.c feb1eabb20987983d9350cad98299b21fa811f52 -F src/vdbe.c da8f4d04fb134d7e64fd34d519b0eba4883ed779 +F src/vdbe.c 04e0606bc0505924036a974759703af6a3664904 F src/vdbe.h c16ba943d407baa1c7085eefea73a063fc631863 -F src/vdbeInt.h 9b704336a69f62ba189eafb06a46171e3463d27b +F src/vdbeInt.h ddb157974436d87652de7dc641f7191496d9a8cd F src/vdbeapi.c ba85b78fe08dc4a9ce747e62c89a2b4a4547e74c -F src/vdbeaux.c 03b2a622bf7714153bf06f9a6789e94aad9a5f89 +F src/vdbeaux.c fa06ba5441714160ab5f64422660ee286968672f F src/vdbeblob.c c9f2f494b911c6fa34efd9803f0a10807da80f77 F src/vdbemem.c 5cfef60e60e19cab6275d1b975bf4c791d575beb F src/vdbesort.c 307460bfa4de4d1c3901fcd42089159131e34062 @@ -1480,7 +1480,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P beb5ea1439995fb8ab112451a8ffcc08fe42d0c4 e9bb4cf40f4971974a74468ef922bdee481c988b -R 491d941731d06e3edceeb8f36a9265ac +P ed22eb653f2809446ace6a27e7ea3926ac6db30c +R 5630f9e5708bbc437f2437f3c1df072c U drh -Z 3f9fc483108428866f896f452f439d76 +Z eacbad43019a9bff0f7b72fbe90e323f diff --git a/manifest.uuid b/manifest.uuid index b49c17cf93..a44439793a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ed22eb653f2809446ace6a27e7ea3926ac6db30c \ No newline at end of file +5ab46d760dff327491703478d6d7c7c44a0147ca \ No newline at end of file diff --git a/src/update.c b/src/update.c index c147eaaad9..7b38c5bcc5 100644 --- a/src/update.c +++ b/src/update.c @@ -601,6 +601,7 @@ void sqlite3Update( ** is the column index supplied by the user. */ assert( regNew==regNewRowid+1 ); +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK sqlite3VdbeAddOp3(v, OP_Delete, iDataCur, OPFLAG_ISUPDATE | ((hasFK || chngKey || pPk!=0) ? 0 : OPFLAG_ISNOOP), regNewRowid @@ -608,6 +609,11 @@ void sqlite3Update( if( !pParse->nested ){ sqlite3VdbeChangeP4(v, -1, (char*)pTab, P4_TABLE); } +#else + if( hasFK || chngKey || pPk!=0 ){ + sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, 0); + } +#endif if( bReplace || chngKey ){ sqlite3VdbeJumpHere(v, addr1); } diff --git a/src/vdbe.c b/src/vdbe.c index 18e955c0ff..787d2b7b48 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -91,9 +91,9 @@ static void updateMaxBlobsize(Mem *p){ ** hook are enabled for database connect DB. */ #ifdef SQLITE_ENABLE_PREUPDATE_HOOK -# define HAS_UPDATE_HOOK(DB) ((DB)->xPreUpdateCallback||(DB)->xUpdateCallback) +# define HAS_UPDATE_HOOK(DB) ((DB)->xPreUpdateCallback||(DB)->xUpdateCallback) #else -# define HAS_UPDATE_HOOK(DB) ((DB)->xUpdateCallback) +# define HAS_UPDATE_HOOK(DB) ((DB)->xUpdateCallback) #endif /* @@ -4287,8 +4287,9 @@ case OP_InsertInt: { int seekResult; /* Result of prior seek or 0 if no USESEEKRESULT flag */ const char *zDb; /* database name - used by the update hook */ Table *pTab; /* Table structure - used by update and pre-update hooks */ - int op = 0; /* Opcode for update hook: SQLITE_UPDATE or SQLITE_INSERT */ + int op; /* Opcode for update hook: SQLITE_UPDATE or SQLITE_INSERT */ + op = 0; pData = &aMem[pOp->p2]; assert( pOp->p1>=0 && pOp->p1nCursor ); assert( memIsValid(pData) ); @@ -4317,6 +4318,9 @@ case OP_InsertInt: { zDb = db->aDb[pC->iDb].zName; pTab = pOp->p4.pTab; op = ((pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT); + }else{ + pTab = 0; /* Not needed. Silence a comiler warning. */ + zDb = 0; /* Not needed. Silence a compiler warning. */ } #ifdef SQLITE_ENABLE_PREUPDATE_HOOK @@ -4431,6 +4435,9 @@ case OP_Delete: { if( pOp->p5 && pC->isTable ){ sqlite3BtreeKeySize(pC->uc.pCursor, &pC->movetoTarget); } + }else{ + zDb = 0; /* Not needed. Silence a compiler warning. */ + pTab = 0; /* Not needed. Silence a compiler warning. */ } #ifdef SQLITE_ENABLE_PREUPDATE_HOOK diff --git a/src/vdbeInt.h b/src/vdbeInt.h index 1218009d0a..61561e9dce 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -506,8 +506,9 @@ int sqlite3VdbeMemClearAndResize(Mem *pMem, int n); int sqlite3VdbeCloseStatement(Vdbe *, int); void sqlite3VdbeFrameDelete(VdbeFrame*); int sqlite3VdbeFrameRestore(VdbeFrame *); -void sqlite3VdbePreUpdateHook( - Vdbe *, VdbeCursor *, int, const char*, Table *, i64, int); +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK +void sqlite3VdbePreUpdateHook(Vdbe*,VdbeCursor*,int,const char*,Table*,i64,int); +#endif int sqlite3VdbeTransferError(Vdbe *p); int sqlite3VdbeSorterInit(sqlite3 *, int, VdbeCursor *); diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 932821f383..48d1b5ae15 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -1318,6 +1318,10 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){ zTemp[0] = 0; break; } + case P4_TABLE: { + sqlite3XPrintf(&x, "%s", pOp->p4.pTab->zName); + break; + } default: { zP4 = pOp->p4.z; if( zP4==0 ){ @@ -4509,7 +4513,9 @@ static void vdbeFreeUnpacked(sqlite3 *db, UnpackedRecord *p){ sqlite3DbFree(db, p); } } +#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK /* ** Invoke the pre-update hook. If this is an UPDATE or DELETE pre-update call, ** then cursor passed as the second argument should point to the row about From 3875a96ad9d33650ac37996df92c43f564663054 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 30 Mar 2016 14:17:36 +0000 Subject: [PATCH 0221/1484] Remove a redundant test for disabling RESTRICT with defer_foreign_keys=ON. FossilOrigin-Name: 9cdf813c6aaaddc01d2d4e04636c83fcda04d971 --- manifest | 13 ++++++------- manifest.uuid | 2 +- src/fkey.c | 4 ---- 3 files changed, 7 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index f94cbc8139..bdf6e1ef9f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Incorporate\sthe\ssessions\sextension\sand\sthe\nSQLITE_ENABLE_PREUPDATE_HOOK\scompile-time\soption. -D 2016-03-30T13:43:09.573 +C Remove\sa\sredundant\stest\sfor\sdisabling\sRESTRICT\swith\sdefer_foreign_keys=ON. +D 2016-03-30T14:17:36.686 F Makefile.in e812bb732d7af01baa09f1278bd4f4a2e3a09449 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e6ee58b849c116d5554024f524cbf61f064f6f01 @@ -329,7 +329,7 @@ F src/dbstat.c c845548d4346e606e2f2b7d2e714ace2b8a7dd1b F src/delete.c eeac28b3d3d88e3541bdf93e91ea7492a7b67842 F src/expr.c 289ffac5240b60fee0a824d3d5ab2d7bd2630c94 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb -F src/fkey.c 5da47ff524e2f687997a74737ce598f043e1342a +F src/fkey.c 4c0bd09e602b8ae8d36d81e31e4872d0b53c87bb F src/func.c 552d300265aed09eea21f68ac742a440550c0062 F src/global.c 884d4c7eba9f5fc25c96a23b21520da19b7713e2 F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5 @@ -1480,8 +1480,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e4bee561fdead5d35c24da3fe8a11bf6548550c6 5ab46d760dff327491703478d6d7c7c44a0147ca -R 9dafbaa8421126ca3296fa72ec1f46aa -T +closed 5ab46d760dff327491703478d6d7c7c44a0147ca +P 4af7a90f980ade3566fc5da2f0db2669ac7d8256 +R 8a337360e7d496c90cf72795a6dab55f U drh -Z ca91103b707261c36c558c8ac5546192 +Z d1fd34700ce8bf6be699758638dac3cb diff --git a/manifest.uuid b/manifest.uuid index 9549a9a3b1..c0d0673209 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4af7a90f980ade3566fc5da2f0db2669ac7d8256 \ No newline at end of file +9cdf813c6aaaddc01d2d4e04636c83fcda04d971 \ No newline at end of file diff --git a/src/fkey.c b/src/fkey.c index 4f2740ec30..fa19fbc1ce 100644 --- a/src/fkey.c +++ b/src/fkey.c @@ -1165,11 +1165,7 @@ static Trigger *fkActionTrigger( if( action==OE_Restrict && (db->flags & SQLITE_DeferFKs) ){ return 0; } - pTrigger = pFKey->apTrigger[iAction]; - if( (db->flags & SQLITE_DeferFKs) && action==OE_Restrict ){ - return 0; - } if( action!=OE_None && !pTrigger ){ char const *zFrom; /* Name of child table */ From 9fc4caf64c67cfcc91339924cde9cc37e1eaa78a Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 30 Mar 2016 14:26:36 +0000 Subject: [PATCH 0222/1484] Increase the version number to 3.13.0 on account of the new session extension. FossilOrigin-Name: e9bcd5acb9ab7b3d55c96519ca10f51f35e24cd9 --- VERSION | 2 +- configure | 18 +++++++++--------- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/VERSION b/VERSION index 92536a9e48..4eba2a62eb 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.12.0 +3.13.0 diff --git a/configure b/configure index 8363818c6f..27cb1ea0b9 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.12.0. +# Generated by GNU Autoconf 2.69 for sqlite 3.13.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.12.0' -PACKAGE_STRING='sqlite 3.12.0' +PACKAGE_VERSION='3.13.0' +PACKAGE_STRING='sqlite 3.13.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1460,7 +1460,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures sqlite 3.12.0 to adapt to many kinds of systems. +\`configure' configures sqlite 3.13.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1525,7 +1525,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of sqlite 3.12.0:";; + short | recursive ) echo "Configuration of sqlite 3.13.0:";; esac cat <<\_ACEOF @@ -1646,7 +1646,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -sqlite configure 3.12.0 +sqlite configure 3.13.0 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2065,7 +2065,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by sqlite $as_me 3.12.0, which was +It was created by sqlite $as_me 3.13.0, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -12079,7 +12079,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by sqlite $as_me 3.12.0, which was +This file was extended by sqlite $as_me 3.13.0, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -12145,7 +12145,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -sqlite config.status 3.12.0 +sqlite config.status 3.13.0 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/manifest b/manifest index bdf6e1ef9f..c6e2c51338 100644 --- a/manifest +++ b/manifest @@ -1,10 +1,10 @@ -C Remove\sa\sredundant\stest\sfor\sdisabling\sRESTRICT\swith\sdefer_foreign_keys=ON. -D 2016-03-30T14:17:36.686 +C Increase\sthe\sversion\snumber\sto\s3.13.0\son\saccount\sof\sthe\snew\ssession\sextension. +D 2016-03-30T14:26:36.915 F Makefile.in e812bb732d7af01baa09f1278bd4f4a2e3a09449 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e6ee58b849c116d5554024f524cbf61f064f6f01 F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7 -F VERSION c6b1f51809551d60ad001e6d87cf3ab2c7f54b6f +F VERSION 5d234da9b5dae329fab75ff75884cfe0a9cb3fda F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 @@ -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 c01a159fdf7ea0171ad01ce2937283f2c7972bde x +F configure dbd42c55ca6b65e0fb37ef54121755f26a890edf x F configure.ac 89e4e02a83d8a1528011f8395621b8c3186b4089 F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad F doc/lemon.html e2118945e5f07ed146b45c9cd2b2dd6eabb8ebf2 @@ -1480,7 +1480,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 4af7a90f980ade3566fc5da2f0db2669ac7d8256 -R 8a337360e7d496c90cf72795a6dab55f +P 9cdf813c6aaaddc01d2d4e04636c83fcda04d971 +R 7a69958e274665351e7e782b27ccbb0b U drh -Z d1fd34700ce8bf6be699758638dac3cb +Z fc241d926edbc77d507e66ad4423e83d diff --git a/manifest.uuid b/manifest.uuid index c0d0673209..5ef2f2b86c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9cdf813c6aaaddc01d2d4e04636c83fcda04d971 \ No newline at end of file +e9bcd5acb9ab7b3d55c96519ca10f51f35e24cd9 \ No newline at end of file From c556f3c33f54e6e1de9163c6710bc4fe7498278c Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 30 Mar 2016 15:30:07 +0000 Subject: [PATCH 0223/1484] Simplifications and clarification to update callback handling in the OP_Delete and OP_Insert opcodes. FossilOrigin-Name: 47887ef89ed60ddb869d65e0957c1c4b2115f169 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/sqliteInt.h | 5 ++--- src/vdbe.c | 14 +++++++------- 4 files changed, 17 insertions(+), 18 deletions(-) diff --git a/manifest b/manifest index c6e2c51338..b61de4df04 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Increase\sthe\sversion\snumber\sto\s3.13.0\son\saccount\sof\sthe\snew\ssession\sextension. -D 2016-03-30T14:26:36.915 +C Simplifications\sand\sclarification\sto\supdate\scallback\shandling\sin\sthe\nOP_Delete\sand\sOP_Insert\sopcodes. +D 2016-03-30T15:30:07.231 F Makefile.in e812bb732d7af01baa09f1278bd4f4a2e3a09449 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e6ee58b849c116d5554024f524cbf61f064f6f01 @@ -378,7 +378,7 @@ F src/shell.c cd3f82fdc5c895b817a375b7ab8319cb41f447ce F src/sqlite.h.in a1d7a367997f80c7075303aaf73e5fc46261c11c F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 98f72cbfe00169c39089115427d06ea05fe4b4a2 -F src/sqliteInt.h 410bd07098423b887874d9d2ff9ed6f8e3284839 +F src/sqliteInt.h 594bf31a7a0cc788688ca947e562576e23bd7904 F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 @@ -439,7 +439,7 @@ F src/update.c 3e67ab3c0814635f355fb1f8ab010a2b9e016e7d F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 8873d696c9ccc4206058c402e09e101f1b81561a F src/vacuum.c feb1eabb20987983d9350cad98299b21fa811f52 -F src/vdbe.c 04e0606bc0505924036a974759703af6a3664904 +F src/vdbe.c 0f0e4a6255f9a5272857a818314d081db26bcd90 F src/vdbe.h c16ba943d407baa1c7085eefea73a063fc631863 F src/vdbeInt.h ddb157974436d87652de7dc641f7191496d9a8cd F src/vdbeapi.c ba85b78fe08dc4a9ce747e62c89a2b4a4547e74c @@ -1480,7 +1480,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 9cdf813c6aaaddc01d2d4e04636c83fcda04d971 -R 7a69958e274665351e7e782b27ccbb0b +P e9bcd5acb9ab7b3d55c96519ca10f51f35e24cd9 +R 7d699e46158684aaeb0674ba8ed1262b U drh -Z fc241d926edbc77d507e66ad4423e83d +Z 8edbe6879cd34861bc153d7b5712adb5 diff --git a/manifest.uuid b/manifest.uuid index 5ef2f2b86c..7ffd9886fc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e9bcd5acb9ab7b3d55c96519ca10f51f35e24cd9 \ No newline at end of file +47887ef89ed60ddb869d65e0957c1c4b2115f169 \ No newline at end of file diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 85004035ba..d789cc00e4 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2927,9 +2927,6 @@ struct AuthContext { /* ** Bitfield flags for P5 value in various opcodes. -** -** Note that the values for ISNOOP and LENGTHARG are the same. But as -** those bits are never used on the same opcode, the overlap is harmless. */ #define OPFLAG_NCHANGE 0x01 /* OP_Insert: Set to update db->nChange */ /* Also used in P2 (not P5) of OP_Delete */ @@ -2938,7 +2935,9 @@ struct AuthContext { #define OPFLAG_ISUPDATE 0x04 /* This OP_Insert is an sql UPDATE */ #define OPFLAG_APPEND 0x08 /* This is likely to be an append */ #define OPFLAG_USESEEKRESULT 0x10 /* Try to avoid a seek in BtreeInsert() */ +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK #define OPFLAG_ISNOOP 0x40 /* OP_Delete does pre-update-hook only */ +#endif #define OPFLAG_LENGTHARG 0x40 /* OP_Column only used for length() */ #define OPFLAG_TYPEOFARG 0x80 /* OP_Column only used for typeof() */ #define OPFLAG_BULKCSR 0x01 /* OP_Open** used to open bulk cursor */ diff --git a/src/vdbe.c b/src/vdbe.c index 787d2b7b48..84a5087e01 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -4317,6 +4317,7 @@ case OP_InsertInt: { assert( pC->iDb>=0 ); zDb = db->aDb[pC->iDb].zName; pTab = pOp->p4.pTab; + assert( HasRowid(pTab) ); op = ((pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT); }else{ pTab = 0; /* Not needed. Silence a comiler warning. */ @@ -4328,7 +4329,6 @@ case OP_InsertInt: { if( db->xPreUpdateCallback && pOp->p4type==P4_TABLE && !(pOp->p5 & OPFLAG_ISUPDATE) - && HasRowid(pTab) ){ sqlite3VdbePreUpdateHook(p, pC, SQLITE_INSERT, zDb, pTab, iKey, pOp->p2); } @@ -4357,7 +4357,7 @@ case OP_InsertInt: { /* Invoke the update-hook if required. */ if( rc ) goto abort_due_to_error; - if( db->xUpdateCallback && op && HasRowid(pTab) ){ + if( db->xUpdateCallback && op ){ db->xUpdateCallback(db->pUpdateArg, op, zDb, pTab->zName, iKey); } break; @@ -4428,11 +4428,12 @@ case OP_Delete: { ** of p4.pTab. Finally, if p5 is true, indicating that this cursor was ** last moved with OP_Next or OP_Prev, not Seek or NotFound, set ** VdbeCursor.movetoTarget to the current rowid. */ - if( pOp->p4.pTab && HAS_UPDATE_HOOK(db) ){ + if( pOp->p4type==P4_TABLE && HAS_UPDATE_HOOK(db) ){ assert( pC->iDb>=0 ); + assert( pOp->p4.pTab!=0 ); zDb = db->aDb[pC->iDb].zName; pTab = pOp->p4.pTab; - if( pOp->p5 && pC->isTable ){ + if( (pOp->p5 & OPFLAG_SAVEPOSITION)!=0 && pC->isTable ){ sqlite3BtreeKeySize(pC->uc.pCursor, &pC->movetoTarget); } }else{ @@ -4450,9 +4451,8 @@ case OP_Delete: { pOp->p3 ); } -#endif - if( opflags & OPFLAG_ISNOOP ) break; +#endif /* Only flags that can be set are SAVEPOISTION and AUXDELETE */ assert( (pOp->p5 & ~(OPFLAG_SAVEPOSITION|OPFLAG_AUXDELETE))==0 ); @@ -4480,7 +4480,7 @@ case OP_Delete: { /* Invoke the update-hook if required. */ if( opflags & OPFLAG_NCHANGE ){ p->nChange++; - if( rc==SQLITE_OK && db->xUpdateCallback && HasRowid(pTab) ){ + if( db->xUpdateCallback && HasRowid(pTab) ){ db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE, zDb, pTab->zName, pC->movetoTarget); assert( pC->iDb>=0 ); From b932bf63e6806e31c8cfea56ed21dfcfc2717fc9 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Wed, 30 Mar 2016 16:22:18 +0000 Subject: [PATCH 0224/1484] Fix typo in comment. No changes to code. FossilOrigin-Name: 64d75cbe2c45af67124fa7ce5688d91cc6ddb755 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/sqlite.h.in | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index b61de4df04..572118f49d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Simplifications\sand\sclarification\sto\supdate\scallback\shandling\sin\sthe\nOP_Delete\sand\sOP_Insert\sopcodes. -D 2016-03-30T15:30:07.231 +C Fix\stypo\sin\scomment.\s\sNo\schanges\sto\scode. +D 2016-03-30T16:22:18.401 F Makefile.in e812bb732d7af01baa09f1278bd4f4a2e3a09449 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e6ee58b849c116d5554024f524cbf61f064f6f01 @@ -375,7 +375,7 @@ F src/resolve.c b8f7174e5f8c33c44ded3a25a973d0bb89228c20 F src/rowset.c 9fe4b3ad7cc00944386bb600233d8f523de07a6e F src/select.c 7849cee0a01952a9c93cd28989daedfa57731143 F src/shell.c cd3f82fdc5c895b817a375b7ab8319cb41f447ce -F src/sqlite.h.in a1d7a367997f80c7075303aaf73e5fc46261c11c +F src/sqlite.h.in 843a0dfcf8c5e961cfafa62009fed0867b88241e F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 98f72cbfe00169c39089115427d06ea05fe4b4a2 F src/sqliteInt.h 594bf31a7a0cc788688ca947e562576e23bd7904 @@ -1480,7 +1480,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e9bcd5acb9ab7b3d55c96519ca10f51f35e24cd9 -R 7d699e46158684aaeb0674ba8ed1262b -U drh -Z 8edbe6879cd34861bc153d7b5712adb5 +P 47887ef89ed60ddb869d65e0957c1c4b2115f169 +R b936f16f86444f27d224909ef15c00ab +U mistachkin +Z ee43622ecca2631579c58c415c88d4a1 diff --git a/manifest.uuid b/manifest.uuid index 7ffd9886fc..ac46899c6a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -47887ef89ed60ddb869d65e0957c1c4b2115f169 \ No newline at end of file +64d75cbe2c45af67124fa7ce5688d91cc6ddb755 \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index c9b80d6567..35de70ff7f 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -8014,7 +8014,7 @@ SQLITE_EXPERIMENTAL int sqlite3_preupdate_new(sqlite3 *, int, sqlite3_value **); ** CAPI3REF: Low-level system error code ** ** ^Attempt to return the underlying operating system error code or error -** number that caused the most reason I/O error or failure to open a file. +** number that caused the most recent I/O error or failure to open a file. ** The return value is OS-dependent. For example, on unix systems, after ** [sqlite3_open_v2()] returns [SQLITE_CANTOPEN], this interface could be ** called to get back the underlying "errno" that caused the problem, such From 05004784a50504c6e34f512a103b7c0dc7e9fa35 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Wed, 30 Mar 2016 16:23:06 +0000 Subject: [PATCH 0225/1484] Updates for the MSVC makefiles. FossilOrigin-Name: 7cf0cab730e2d570c82dd789279ad6501ac598c8 --- Makefile.msc | 36 +++++++++++------------------------- autoconf/Makefile.msc | 2 ++ manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 21 insertions(+), 33 deletions(-) diff --git a/Makefile.msc b/Makefile.msc index a6a2394a6a..84c2eac2f4 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -264,6 +264,8 @@ SQLITE3EXEPDB = /pdb:sqlite3sh.pdb OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_FTS3=1 OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_RTREE=1 OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_COLUMN_METADATA=1 +OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_SESSION=1 +OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_PREUPDATE_HOOK=1 !ENDIF # These are the "extended" SQLite compilation options used when compiling for @@ -784,14 +786,6 @@ RCC = $(RCC) -DSQLITE_TEMP_STORE=1 # The same set of OMIT and ENABLE flags should be passed to the # LEMON parser generator and the mkkeywordhash tool as well. -# BEGIN standard options -OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_FTS3=1 -OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_RTREE=1 -OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_COLUMN_METADATA=1 -OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_SESSION=1 -OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_PREUPDATE_HOOK=1 -# END standard options - # These are the required SQLite compilation options used when compiling for # the Windows platform. # @@ -1189,9 +1183,7 @@ SRC07 = \ $(TOP)\ext\fts3\fts3_write.c \ $(TOP)\ext\icu\icu.c \ $(TOP)\ext\rtree\rtree.c \ - $(TOP)\ext\session\sqlite3session.h \ $(TOP)\ext\session\sqlite3session.c \ - $(TOP)\ext\rbu\sqlite3rbu.h \ $(TOP)\ext\rbu\sqlite3rbu.c \ $(TOP)\ext\misc\json1.c @@ -1214,7 +1206,8 @@ SRC09 = \ $(TOP)\ext\fts3\fts3_tokenizer.h \ $(TOP)\ext\icu\sqliteicu.h \ $(TOP)\ext\rtree\rtree.h \ - $(TOP)\ext\rbu\sqlite3rbu.h + $(TOP)\ext\rbu\sqlite3rbu.h \ + $(TOP)\ext\session\sqlite3session.h # Generated source code files # @@ -1280,8 +1273,8 @@ TESTSRC = \ $(TOP)\src\test_wsd.c \ $(TOP)\ext\fts3\fts3_term.c \ $(TOP)\ext\fts3\fts3_test.c \ - $(TOP)\ext\session\test_session.c \ - $(TOP)\ext\rbu\test_rbu.c + $(TOP)\ext\rbu\test_rbu.c \ + $(TOP)\ext\session\test_session.c # Statically linked extensions. # @@ -1312,14 +1305,7 @@ TESTSRC2 = \ $(SRC06) \ $(SRC07) \ $(SRC10) \ - $(TOP)\ext\async\sqlite3async.c \ - $(TOP)\ext\session\sqlite3session.c - -# Source code to the library files needed by the test fixture -# (amalgamation) -# -TESTSRC3 = - + $(TOP)\ext\async\sqlite3async.c # Header files used by all library source files. # @@ -1897,7 +1883,7 @@ rtree.lo: $(TOP)\ext\rtree\rtree.c $(HDR) $(EXTHDR) $(LTCOMPILE) $(CORE_COMPILE_OPTS) $(NO_WARN) -DSQLITE_CORE -c $(TOP)\ext\rtree\rtree.c sqlite3session.lo: $(TOP)\ext\session\sqlite3sesion.c $(HDR) $(EXTHDR) - $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)\ext\session\sqlite3session.c + $(LTCOMPILE) $(CORE_COMPILE_OPTS) $(NO_WARN) -DSQLITE_CORE -c $(TOP)\ext\session\sqlite3session.c # FTS5 things # @@ -1955,7 +1941,7 @@ TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_SERIES_CONSTRAINT_VERIFY=1 TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_DEFAULT_PAGE_SIZE=1024 TESTFIXTURE_SRC0 = $(TESTEXT) $(TESTSRC2) -TESTFIXTURE_SRC1 = $(TESTEXT) $(TESTSRC3) $(SQLITE3C) +TESTFIXTURE_SRC1 = $(TESTEXT) $(SQLITE3C) !IF $(USE_AMALGAMATION)==0 TESTFIXTURE_SRC = $(TESTSRC) $(TOP)\src\tclsqlite.c $(TESTFIXTURE_SRC0) !ELSE @@ -2047,8 +2033,8 @@ showwal.exe: $(TOP)\tool\showwal.c $(SQLITE3C) $(SQLITE3H) $(TOP)\tool\showwal.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) changeset.exe: $(TOP)\ext\session\changeset.c $(SQLITE3C) - $(LTLINK) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \ - $(TOP)\ext\session\changeset.c $(SQLITE3C) + $(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \ + $(TOP)\ext\session\changeset.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) fts3view.exe: $(TOP)\ext\fts3\tool\fts3view.c $(SQLITE3C) $(SQLITE3H) $(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \ diff --git a/autoconf/Makefile.msc b/autoconf/Makefile.msc index ad829bffa0..ed99ce9587 100644 --- a/autoconf/Makefile.msc +++ b/autoconf/Makefile.msc @@ -249,6 +249,8 @@ SQLITE3EXEPDB = /pdb:sqlite3sh.pdb OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_FTS3=1 OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_RTREE=1 OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_COLUMN_METADATA=1 +OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_SESSION=1 +OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_PREUPDATE_HOOK=1 !ENDIF # These are the "extended" SQLite compilation options used when compiling for diff --git a/manifest b/manifest index 572118f49d..c602040523 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -C Fix\stypo\sin\scomment.\s\sNo\schanges\sto\scode. -D 2016-03-30T16:22:18.401 +C Updates\sfor\sthe\sMSVC\smakefiles. +D 2016-03-30T16:23:06.801 F Makefile.in e812bb732d7af01baa09f1278bd4f4a2e3a09449 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 -F Makefile.msc e6ee58b849c116d5554024f524cbf61f064f6f01 +F Makefile.msc cde766eb7c27a7ca42000e66c5f0c37a17a05998 F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7 F VERSION 5d234da9b5dae329fab75ff75884cfe0a9cb3fda F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 @@ -11,7 +11,7 @@ F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am 42f7eb1fb2b06ddd6c6adab3e4388cc0a237ba40 -F autoconf/Makefile.msc b8ada5177e6f39c126a88295af5ad0255e08d280 +F autoconf/Makefile.msc dc0d0500e4a827cb3891d08d846dd6dd40241b51 F autoconf/README.first 6c4f34fe115ff55d4e8dbfa3cecf04a0188292f7 F autoconf/README.txt 4f04b0819303aabaa35fff5f7b257fb0c1ef95f1 F autoconf/configure.ac d807b567f73a2b0986ccdd206b782cecb4d08fff @@ -1480,7 +1480,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 47887ef89ed60ddb869d65e0957c1c4b2115f169 -R b936f16f86444f27d224909ef15c00ab +P 64d75cbe2c45af67124fa7ce5688d91cc6ddb755 +R 77269b95e931ac6cca96bcd2fa718a38 U mistachkin -Z ee43622ecca2631579c58c415c88d4a1 +Z 37f983898af724eda9f571ecd8a4d862 diff --git a/manifest.uuid b/manifest.uuid index ac46899c6a..2aa68317b9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -64d75cbe2c45af67124fa7ce5688d91cc6ddb755 \ No newline at end of file +7cf0cab730e2d570c82dd789279ad6501ac598c8 \ No newline at end of file From d91515267744eeb5be69ed2b97d93ea958cd8746 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 30 Mar 2016 21:19:00 +0000 Subject: [PATCH 0226/1484] Have the sqlite3session_apply() function and its streaming equivalent retry any operations that failed with SQLITE_CONSTRAINT after all other operations on the same table have been attempted. New code is largely untested. FossilOrigin-Name: 1085911afb51744f32fe9db183b50e8e88bdd73e --- ext/session/session1.test | 4 +- ext/session/sessionG.test | 66 +++++++++++++ ext/session/sqlite3session.c | 182 +++++++++++++++++++++++++++-------- manifest | 20 ++-- manifest.uuid | 2 +- 5 files changed, 225 insertions(+), 49 deletions(-) create mode 100644 ext/session/sessionG.test diff --git a/ext/session/session1.test b/ext/session/session1.test index 7aebe8c000..e97aa3c20d 100644 --- a/ext/session/session1.test +++ b/ext/session/session1.test @@ -206,8 +206,8 @@ do_conflict_test 3.1.2 -tables t1 -sql { INSERT INTO t1 VALUES(7, 'seven'); INSERT INTO t1 VALUES(8, NULL); } -conflicts { - {INSERT t1 CONSTRAINT {i 8 n {}}} {INSERT t1 CONFLICT {i 6 t six} {i 6 t VI}} + {INSERT t1 CONSTRAINT {i 8 n {}}} } do_db2_test 3.1.3 "SELECT * FROM t1" { @@ -272,9 +272,9 @@ do_conflict_test 3.3.3 -tables t4 -sql { UPDATE t4 SET a = NULL WHERE c = 9; UPDATE t4 SET a = 'x' WHERE b = 11; } -conflicts { - {UPDATE t4 CONSTRAINT {i 7 i 8 i 9} {n {} {} {} {} {}}} {UPDATE t4 DATA {i 1 i 2 i 3} {i -1 {} {} {} {}} {i 0 i 2 i 3}} {UPDATE t4 NOTFOUND {i 4 i 5 i 6} {i -1 {} {} {} {}}} + {UPDATE t4 CONSTRAINT {i 7 i 8 i 9} {n {} {} {} {} {}}} } do_db2_test 3.3.4 { SELECT * FROM t4 } {0 2 3 4 5 7 7 8 9 x 11 12} do_execsql_test 3.3.5 { SELECT * FROM t4 } {-1 2 3 -1 5 6 {} 8 9 x 11 12} diff --git a/ext/session/sessionG.test b/ext/session/sessionG.test new file mode 100644 index 0000000000..5ebdbbed6b --- /dev/null +++ b/ext/session/sessionG.test @@ -0,0 +1,66 @@ +# 2016 March 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 regression tests for the sessions module. +# Specifically, it tests that UNIQUE constraints are dealt with correctly. +# + + + +if {![info exists testdir]} { + set testdir [file join [file dirname [info script]] .. .. test] +} +source [file join [file dirname [info script]] session_common.tcl] +source $testdir/tester.tcl +ifcapable !session {finish_test; return} +set testprefix sessionG + + +forcedelete test.db2 +sqlite3 db2 test.db2 + +do_test 1.0 { + do_common_sql { + CREATE TABLE t1(a PRIMARY KEY, b UNIQUE); + INSERT INTO t1 VALUES(1, 'one'); + INSERT INTO t1 VALUES(2, 'two'); + INSERT INTO t1 VALUES(3, 'three'); + } + do_then_apply_sql { + DELETE FROM t1 WHERE a=1; + INSERT INTO t1 VALUES(4, 'one'); + } + compare_db db db2 +} {} + +do_test 1.1 { + do_then_apply_sql { + DELETE FROM t1 WHERE a=4; + INSERT INTO t1 VALUES(1, 'one'); + } + compare_db db db2 +} {} + +do_test 1.2 { + execsql { INSERT INTO t1 VALUES(5, 'five') } db2 + do_then_apply_sql { + INSERT INTO t1 VALUES(11, 'eleven'); + INSERT INTO t1 VALUES(12, 'five'); + } + execsql { SELECT * FROM t1 } db2 +} {2 two 3 three 1 one 5 five 11 eleven} + +do_test 1.3 { + execsql { SELECT * FROM t1 } +} {2 two 3 three 1 one 11 eleven 12 five} + +finish_test + diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index 312e03dcfb..826911f299 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -67,6 +67,8 @@ struct SessionBuffer { ** sqlite3changeset_start_strm()). */ struct SessionInput { + int bNoDiscard; /* If true, discard no data */ + int iCurrent; /* Offset in aData[] of current change */ int iNext; /* Offset in aData[] of next change */ u8 *aData; /* Pointer to buffer containing changeset */ int nData; /* Number of bytes in aData */ @@ -2460,7 +2462,6 @@ static int sessionChangesetStart( pRet->in.nData = nChangeset; pRet->in.xInput = xInput; pRet->in.pIn = pIn; - pRet->in.iNext = 0; pRet->in.bEof = (xInput ? 0 : 1); /* Populate the output variable and return success. */ @@ -2490,6 +2491,23 @@ int sqlite3changeset_start_strm( return sessionChangesetStart(pp, xInput, pIn, 0, 0); } +/* +** If the SessionInput object passed as the only argument is a streaming +** object and the buffer is full, discard some data to free up space. +*/ +static void sessionDiscardData(SessionInput *pIn){ + if( pIn->bEof && pIn->xInput && pIn->iNext>=SESSIONS_STRM_CHUNK_SIZE ){ + int nMove = pIn->buf.nBuf - pIn->iNext; + assert( nMove>=0 ); + if( nMove>0 ){ + memmove(pIn->buf.aBuf, &pIn->buf.aBuf[pIn->iNext], nMove); + } + pIn->buf.nBuf -= pIn->iNext; + pIn->iNext = 0; + pIn->nData = pIn->buf.nBuf; + } +} + /* ** Ensure that there are at least nByte bytes available in the buffer. Or, ** if there are not nByte bytes remaining in the input, that all available @@ -2503,13 +2521,7 @@ static int sessionInputBuffer(SessionInput *pIn, int nByte){ while( !pIn->bEof && (pIn->iNext+nByte)>=pIn->nData && rc==SQLITE_OK ){ int nNew = SESSIONS_STRM_CHUNK_SIZE; - if( pIn->iNext>=SESSIONS_STRM_CHUNK_SIZE ){ - int nMove = pIn->buf.nBuf - pIn->iNext; - memmove(pIn->buf.aBuf, &pIn->buf.aBuf[pIn->iNext], nMove); - pIn->buf.nBuf -= pIn->iNext; - pIn->iNext = 0; - } - + if( pIn->bNoDiscard==0 ) sessionDiscardData(pIn); if( SQLITE_OK==sessionBufferGrow(&pIn->buf, nNew, &rc) ){ rc = pIn->xInput(pIn->pIn, &pIn->buf.aBuf[pIn->buf.nBuf], &nNew); if( nNew==0 ){ @@ -2818,11 +2830,15 @@ static int sessionChangesetNext( return SQLITE_DONE; } + sessionDiscardData(&p->in); + p->in.iCurrent = p->in.iNext; + op = p->in.aData[p->in.iNext++]; if( op=='T' || op=='P' ){ p->bPatchset = (op=='P'); if( sessionChangesetReadTblhdr(p) ) return p->rc; if( (p->rc = sessionInputBuffer(&p->in, 2)) ) return p->rc; + p->in.iCurrent = p->in.iNext; op = p->in.aData[p->in.iNext++]; } @@ -3266,6 +3282,9 @@ struct SessionApplyCtx { int nCol; /* Size of azCol[] and abPK[] arrays */ const char **azCol; /* Array of column names */ u8 *abPK; /* Boolean array - true if column is in PK */ + + int bDeferConstraints; /* True to defer constraints */ + SessionBuffer constraints; /* Deferred constraints are stored here */ }; /* @@ -3516,7 +3535,7 @@ static int sessionBindValue( ** transfers new.* values from the current iterator entry to statement ** pStmt. The table being inserted into has nCol columns. ** -** New.* value $i 0 from the iterator is bound to variable ($i+1) of +** New.* value $i from the iterator is bound to variable ($i+1) of ** statement pStmt. If parameter abPK is NULL, all values from 0 to (nCol-1) ** are transfered to the statement. Otherwise, if abPK is not NULL, it points ** to an array nCol elements in size. In this case only those values for @@ -3662,9 +3681,18 @@ static int sessionConflictHandler( pIter->pConflict = 0; rc = sqlite3_reset(p->pSelect); }else if( rc==SQLITE_OK ){ - /* No other row with the new.* primary key. */ - res = xConflict(pCtx, eType+1, pIter); - if( res==SQLITE_CHANGESET_REPLACE ) rc = SQLITE_MISUSE; + if( p->bDeferConstraints && eType==SQLITE_CHANGESET_CONFLICT ){ + /* Instead of invoking the conflict handler, append the change blob + ** to the SessionApplyCtx.constraints buffer. */ + u8 *aBlob = &pIter->in.aData[pIter->in.iCurrent]; + int nBlob = pIter->in.iNext - pIter->in.iCurrent; + sessionAppendBlob(&p->constraints, aBlob, nBlob, &rc); + res = SQLITE_CHANGESET_OMIT; + }else{ + /* No other row with the new.* primary key. */ + res = xConflict(pCtx, eType+1, pIter); + if( res==SQLITE_CHANGESET_REPLACE ) rc = SQLITE_MISUSE; + } } if( rc==SQLITE_OK ){ @@ -3824,6 +3852,96 @@ static int sessionApplyOneOp( return rc; } +static int sessionApplyOneWithRetry( + sqlite3 *db, /* Apply change to "main" db of this handle */ + sqlite3_changeset_iter *pIter, /* Changeset iterator to read change from */ + SessionApplyCtx *pApply, /* Apply context */ + int(*xConflict)(void*, int, sqlite3_changeset_iter*), + void *pCtx /* First argument passed to xConflict */ +){ + int bReplace = 0; + int bRetry = 0; + int rc; + + rc = sessionApplyOneOp(pIter, pApply, xConflict, pCtx, &bReplace, &bRetry); + + if( rc==SQLITE_OK && bRetry ){ + rc = sessionApplyOneOp(pIter, pApply, xConflict, pCtx, &bReplace, 0); + } + + if( bReplace ){ + assert( pIter->op==SQLITE_INSERT ); + rc = sqlite3_exec(db, "SAVEPOINT replace_op", 0, 0, 0); + if( rc==SQLITE_OK ){ + rc = sessionBindRow(pIter, + sqlite3changeset_new, pApply->nCol, pApply->abPK, pApply->pDelete); + sqlite3_bind_int(pApply->pDelete, pApply->nCol+1, 1); + } + if( rc==SQLITE_OK ){ + sqlite3_step(pApply->pDelete); + rc = sqlite3_reset(pApply->pDelete); + } + if( rc==SQLITE_OK ){ + rc = sessionApplyOneOp(pIter, pApply, xConflict, pCtx, 0, 0); + } + if( rc==SQLITE_OK ){ + rc = sqlite3_exec(db, "RELEASE replace_op", 0, 0, 0); + } + } + + return rc; +} + +/* +** Retry the changes accumulated in the pApply->constraints buffer. +*/ +static int sessionRetryConstraints( + sqlite3 *db, + int bPatchset, + const char *zTab, + SessionApplyCtx *pApply, + int(*xConflict)(void*, int, sqlite3_changeset_iter*), + void *pCtx /* First argument passed to xConflict */ +){ + int rc = SQLITE_OK; + + while( pApply->constraints.nBuf ){ + sqlite3_changeset_iter *pIter2 = 0; + SessionBuffer cons = pApply->constraints; + memset(&pApply->constraints, 0, sizeof(SessionBuffer)); + + rc = sessionChangesetStart(&pIter2, 0, 0, cons.nBuf, cons.aBuf); + if( rc==SQLITE_OK ){ + int nByte = 2*pApply->nCol*sizeof(sqlite3_value*); + int rc2; + pIter2->bPatchset = bPatchset; + pIter2->zTab = (char*)zTab; + pIter2->nCol = pApply->nCol; + pIter2->abPK = pApply->abPK; + sessionBufferGrow(&pIter2->tblhdr, nByte, &rc); + pIter2->apValue = (sqlite3_value**)pIter2->tblhdr.aBuf; + if( rc==SQLITE_OK ) memset(pIter2->apValue, 0, nByte); + + while( rc==SQLITE_OK && SQLITE_ROW==sqlite3changeset_next(pIter2) ){ + rc = sessionApplyOneWithRetry(db, pIter2, pApply, xConflict, pCtx); + } + + rc2 = sqlite3changeset_finalize(pIter2); + if( rc==SQLITE_OK ) rc==rc2; + } + assert( pApply->bDeferConstraints || pApply->constraints.nBuf==0 ); + + sqlite3_free(cons.aBuf); + if( rc!=SQLITE_OK ) break; + if( pApply->constraints.nBuf>=cons.nBuf ){ + /* No progress was made on the last round. */ + pApply->bDeferConstraints = 0; + } + } + + return rc; +} + /* ** Argument pIter is a changeset iterator that has been initialized, but ** not yet passed to sqlite3changeset_next(). This function applies the @@ -3853,6 +3971,7 @@ static int sessionChangesetApply( assert( xConflict!=0 ); + pIter->in.bNoDiscard = 1; memset(&sApply, 0, sizeof(sApply)); sqlite3_mutex_enter(sqlite3_db_mutex(db)); rc = sqlite3_exec(db, "SAVEPOINT changeset_apply", 0, 0, 0); @@ -3862,8 +3981,6 @@ static int sessionChangesetApply( while( rc==SQLITE_OK && SQLITE_ROW==sqlite3changeset_next(pIter) ){ int nCol; int op; - int bReplace = 0; - int bRetry = 0; const char *zNew; sqlite3changeset_op(pIter, &zNew, &nCol, &op, 0); @@ -3871,6 +3988,11 @@ static int sessionChangesetApply( if( zTab==0 || sqlite3_strnicmp(zNew, zTab, nTab+1) ){ u8 *abPK; + rc = sessionRetryConstraints( + db, pIter->bPatchset, zTab, &sApply, xConflict, pCtx + ); + if( rc!=SQLITE_OK ) break; + sqlite3_free((char*)sApply.azCol); /* cast works around VC++ bug */ sqlite3_finalize(sApply.pDelete); sqlite3_finalize(sApply.pUpdate); @@ -3878,6 +4000,7 @@ static int sessionChangesetApply( sqlite3_finalize(sApply.pSelect); memset(&sApply, 0, sizeof(sApply)); sApply.db = db; + sApply.bDeferConstraints = 1; /* If an xFilter() callback was specified, invoke it now. If the ** xFilter callback returns zero, skip this table. If it returns @@ -3933,31 +4056,13 @@ static int sessionChangesetApply( ** next change. A log message has already been issued. */ if( schemaMismatch ) continue; - rc = sessionApplyOneOp(pIter, &sApply, xConflict, pCtx, &bReplace, &bRetry); + rc = sessionApplyOneWithRetry(db, pIter, &sApply, xConflict, pCtx); + } - if( rc==SQLITE_OK && bRetry ){ - rc = sessionApplyOneOp(pIter, &sApply, xConflict, pCtx, &bReplace, 0); - } - - if( bReplace ){ - assert( pIter->op==SQLITE_INSERT ); - rc = sqlite3_exec(db, "SAVEPOINT replace_op", 0, 0, 0); - if( rc==SQLITE_OK ){ - rc = sessionBindRow(pIter, - sqlite3changeset_new, sApply.nCol, sApply.abPK, sApply.pDelete); - sqlite3_bind_int(sApply.pDelete, sApply.nCol+1, 1); - } - if( rc==SQLITE_OK ){ - sqlite3_step(sApply.pDelete); - rc = sqlite3_reset(sApply.pDelete); - } - if( rc==SQLITE_OK ){ - rc = sessionApplyOneOp(pIter, &sApply, xConflict, pCtx, 0, 0); - } - if( rc==SQLITE_OK ){ - rc = sqlite3_exec(db, "RELEASE replace_op", 0, 0, 0); - } - } + if( rc==SQLITE_OK ){ + rc = sessionRetryConstraints( + db, pIter->bPatchset, zTab, &sApply, xConflict, pCtx + ); } if( rc==SQLITE_OK ){ @@ -3994,6 +4099,7 @@ static int sessionChangesetApply( sqlite3_finalize(sApply.pUpdate); sqlite3_finalize(sApply.pSelect); sqlite3_free((char*)sApply.azCol); /* cast works around VC++ bug */ + sqlite3_free((char*)sApply.constraints.aBuf); sqlite3_mutex_leave(sqlite3_db_mutex(db)); return rc; } diff --git a/manifest b/manifest index c602040523..27e749b9fb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Updates\sfor\sthe\sMSVC\smakefiles. -D 2016-03-30T16:23:06.801 +C Have\sthe\ssqlite3session_apply()\sfunction\sand\sits\sstreaming\sequivalent\sretry\sany\soperations\sthat\sfailed\swith\sSQLITE_CONSTRAINT\safter\sall\sother\soperations\son\sthe\ssame\stable\shave\sbeen\sattempted.\sNew\scode\sis\slargely\suntested. +D 2016-03-30T21:19:00.012 F Makefile.in e812bb732d7af01baa09f1278bd4f4a2e3a09449 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc cde766eb7c27a7ca42000e66c5f0c37a17a05998 @@ -273,7 +273,7 @@ F ext/rtree/sqlite3rtree.h 9c5777af3d2921c7b4ae4954e8e5697502289d28 F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 F ext/session/changeset.c 4ccbaa4531944c24584bf6a61ba3a39c62b6267a -F ext/session/session1.test 5dab50ce55c859e829bae24f0787013f51775fc5 +F ext/session/session1.test 98f384736e2bc21ccf5ed81bdadcff4ad863393b F ext/session/session2.test 284de45abae4cc1082bc52012ee81521d5ac58e0 F ext/session/session3.test a7a9ce59b8d1e49e2cc23d81421ac485be0eea01 F ext/session/session4.test a6ed685da7a5293c5d6f99855bcf41dbc352ca84 @@ -287,9 +287,10 @@ F ext/session/sessionC.test 97556f5164ac29f2344b24bd7de6a3a35a95c390 F ext/session/sessionD.test d4744c78334162851d2a2f285c7e603e31b49aa2 F ext/session/sessionE.test e60a238c47f0feb3bb707e7f35e22be09c7e8f26 F ext/session/sessionF.test c2f178d4dfd723a5fd94a730ea2ccb44c669e3ce +F ext/session/sessionG.test 388b4f311176411301c35f90f0bf2cb7c6c3dec9 F ext/session/session_common.tcl a1293167d14774b5e728836720497f40fe4ea596 F ext/session/sessionfault.test d52cbb7bee48cc8ee80335e07eb72fcb6b15eb40 -F ext/session/sqlite3session.c b10af3e87ae437bb197b3a23a584d2dc8ad8981a +F ext/session/sqlite3session.c e682828d3ca542617b54808e6d551559e802a605 F ext/session/sqlite3session.h 64e9e7f185725ef43b97f4a9a0c0df0669844f1d F ext/session/test_session.c 187bd344c5ae9d5be85e22ef7c3010f0c17307ce F ext/userauth/sqlite3userauth.h 19cb6f0e31316d0ee4afdfb7a85ef9da3333a220 @@ -1480,7 +1481,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 64d75cbe2c45af67124fa7ce5688d91cc6ddb755 -R 77269b95e931ac6cca96bcd2fa718a38 -U mistachkin -Z 37f983898af724eda9f571ecd8a4d862 +P 7cf0cab730e2d570c82dd789279ad6501ac598c8 +R ee6c26b884210802b6544dcc00c10c18 +T *branch * session-retry +T *sym-session-retry * +T -sym-trunk * +U dan +Z 9b2c9e9e66a7c0858e38132bf4058066 diff --git a/manifest.uuid b/manifest.uuid index 2aa68317b9..b9607529d1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7cf0cab730e2d570c82dd789279ad6501ac598c8 \ No newline at end of file +1085911afb51744f32fe9db183b50e8e88bdd73e \ No newline at end of file From 7e0765a9ec01abc1b4acc9cc0423fa79d61bb80e Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 31 Mar 2016 00:45:58 +0000 Subject: [PATCH 0227/1484] Fix the return code in sessionRetryConstraints(). FossilOrigin-Name: ea917c14b940f95b20b91dae77567dc25a651ef6 --- ext/session/sqlite3session.c | 2 +- manifest | 17 +++++++---------- manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index 826911f299..2fb1b7c81c 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -3927,7 +3927,7 @@ static int sessionRetryConstraints( } rc2 = sqlite3changeset_finalize(pIter2); - if( rc==SQLITE_OK ) rc==rc2; + if( rc==SQLITE_OK ) rc = rc2; } assert( pApply->bDeferConstraints || pApply->constraints.nBuf==0 ); diff --git a/manifest b/manifest index 27e749b9fb..b111bf531f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Have\sthe\ssqlite3session_apply()\sfunction\sand\sits\sstreaming\sequivalent\sretry\sany\soperations\sthat\sfailed\swith\sSQLITE_CONSTRAINT\safter\sall\sother\soperations\son\sthe\ssame\stable\shave\sbeen\sattempted.\sNew\scode\sis\slargely\suntested. -D 2016-03-30T21:19:00.012 +C Fix\sthe\sreturn\scode\sin\ssessionRetryConstraints(). +D 2016-03-31T00:45:58.444 F Makefile.in e812bb732d7af01baa09f1278bd4f4a2e3a09449 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc cde766eb7c27a7ca42000e66c5f0c37a17a05998 @@ -290,7 +290,7 @@ F ext/session/sessionF.test c2f178d4dfd723a5fd94a730ea2ccb44c669e3ce F ext/session/sessionG.test 388b4f311176411301c35f90f0bf2cb7c6c3dec9 F ext/session/session_common.tcl a1293167d14774b5e728836720497f40fe4ea596 F ext/session/sessionfault.test d52cbb7bee48cc8ee80335e07eb72fcb6b15eb40 -F ext/session/sqlite3session.c e682828d3ca542617b54808e6d551559e802a605 +F ext/session/sqlite3session.c 401776afb4886a25182051ae5d68b9b07f70a99c F ext/session/sqlite3session.h 64e9e7f185725ef43b97f4a9a0c0df0669844f1d F ext/session/test_session.c 187bd344c5ae9d5be85e22ef7c3010f0c17307ce F ext/userauth/sqlite3userauth.h 19cb6f0e31316d0ee4afdfb7a85ef9da3333a220 @@ -1481,10 +1481,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 7cf0cab730e2d570c82dd789279ad6501ac598c8 -R ee6c26b884210802b6544dcc00c10c18 -T *branch * session-retry -T *sym-session-retry * -T -sym-trunk * -U dan -Z 9b2c9e9e66a7c0858e38132bf4058066 +P 1085911afb51744f32fe9db183b50e8e88bdd73e +R d0981524bf93277ec5c96a0100bce6e7 +U drh +Z 5d6f324097a8e5b94e7625885f845746 diff --git a/manifest.uuid b/manifest.uuid index b9607529d1..991df518ed 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1085911afb51744f32fe9db183b50e8e88bdd73e \ No newline at end of file +ea917c14b940f95b20b91dae77567dc25a651ef6 \ No newline at end of file From c8be64373314839a5166281c825b50b994a0d4a8 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 31 Mar 2016 02:44:56 +0000 Subject: [PATCH 0228/1484] Enhanced comments describing the sessions file format. No changes to code. FossilOrigin-Name: 84dc41e2df1092e9724a535b670343181a9cd0dd --- ext/session/sqlite3session.c | 4 ++-- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index 2fb1b7c81c..0f5c558463 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -177,7 +177,7 @@ struct SessionTable { ** ** Followed by one or more changes to the table. ** -** 1 byte: Either SQLITE_INSERT, UPDATE or DELETE. +** 1 byte: Either SQLITE_INSERT (0x12), UPDATE (0x17) or DELETE (0x09). ** 1 byte: The "indirect-change" flag. ** old.* record: (delete and update only) ** new.* record: (insert and update only) @@ -219,7 +219,7 @@ struct SessionTable { ** ** Followed by one or more changes to the table. ** -** 1 byte: Either SQLITE_INSERT, UPDATE or DELETE. +** 1 byte: Either SQLITE_INSERT (0x12), UPDATE (0x17) or DELETE (0x09). ** 1 byte: The "indirect-change" flag. ** single record: (PK fields for DELETE, PK and modified fields for UPDATE, ** full record for INSERT). diff --git a/manifest b/manifest index b111bf531f..96777daf79 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\sreturn\scode\sin\ssessionRetryConstraints(). -D 2016-03-31T00:45:58.444 +C Enhanced\scomments\sdescribing\sthe\ssessions\sfile\sformat.\s\sNo\schanges\sto\scode. +D 2016-03-31T02:44:56.615 F Makefile.in e812bb732d7af01baa09f1278bd4f4a2e3a09449 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc cde766eb7c27a7ca42000e66c5f0c37a17a05998 @@ -290,7 +290,7 @@ F ext/session/sessionF.test c2f178d4dfd723a5fd94a730ea2ccb44c669e3ce F ext/session/sessionG.test 388b4f311176411301c35f90f0bf2cb7c6c3dec9 F ext/session/session_common.tcl a1293167d14774b5e728836720497f40fe4ea596 F ext/session/sessionfault.test d52cbb7bee48cc8ee80335e07eb72fcb6b15eb40 -F ext/session/sqlite3session.c 401776afb4886a25182051ae5d68b9b07f70a99c +F ext/session/sqlite3session.c 8ed9c3acf81b12d9d6fcb61b198d851c06046555 F ext/session/sqlite3session.h 64e9e7f185725ef43b97f4a9a0c0df0669844f1d F ext/session/test_session.c 187bd344c5ae9d5be85e22ef7c3010f0c17307ce F ext/userauth/sqlite3userauth.h 19cb6f0e31316d0ee4afdfb7a85ef9da3333a220 @@ -1481,7 +1481,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 1085911afb51744f32fe9db183b50e8e88bdd73e -R d0981524bf93277ec5c96a0100bce6e7 +P ea917c14b940f95b20b91dae77567dc25a651ef6 +R 703150f896b886ff9303fa6318e268aa U drh -Z 5d6f324097a8e5b94e7625885f845746 +Z 55b5826bc78e3fc677b5c1348287f2c3 diff --git a/manifest.uuid b/manifest.uuid index 991df518ed..fe7a39a337 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ea917c14b940f95b20b91dae77567dc25a651ef6 \ No newline at end of file +84dc41e2df1092e9724a535b670343181a9cd0dd \ No newline at end of file From 5f5663dc237c56595624615f014cd5dc4ca67328 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 31 Mar 2016 10:50:26 +0000 Subject: [PATCH 0229/1484] Add further tests for the code on this branch. Fix a problem in OOM handling. FossilOrigin-Name: 195f3340ee4d870420e4f58d44300bab5436b920 --- ext/session/sessionG.test | 111 +++++++++++++++++++++++++++++++++ ext/session/sessionfault2.test | 75 ++++++++++++++++++++++ ext/session/sqlite3session.c | 42 ++++++++++--- manifest | 17 ++--- manifest.uuid | 2 +- 5 files changed, 229 insertions(+), 18 deletions(-) create mode 100644 ext/session/sessionfault2.test diff --git a/ext/session/sessionG.test b/ext/session/sessionG.test index 5ebdbbed6b..5c057350e4 100644 --- a/ext/session/sessionG.test +++ b/ext/session/sessionG.test @@ -62,5 +62,116 @@ do_test 1.3 { execsql { SELECT * FROM t1 } } {2 two 3 three 1 one 11 eleven 12 five} +#------------------------------------------------------------------------- +# +reset_db +db2 close +forcedelete test.db2 +sqlite3 db2 test.db2 + +do_test 2.1 { + do_common_sql { + CREATE TABLE t1(a PRIMARY KEY, b UNIQUE, c UNIQUE); + INSERT INTO t1 VALUES(1, 1, 1); + INSERT INTO t1 VALUES(2, 2, 2); + INSERT INTO t1 VALUES(3, 3, 3); + } +} {} + +do_test 2.2.1 { + # It is not possible to apply the changeset generated by the following + # SQL, as none of the three updated rows may be updated as part of the + # first pass. + do_then_apply_sql { + UPDATE t1 SET b=0 WHERE a=1; + UPDATE t1 SET b=1 WHERE a=2; + UPDATE t1 SET b=2 WHERE a=3; + UPDATE t1 SET b=3 WHERE a=1; + } + db2 eval { SELECT a, b FROM t1 } +} {1 1 2 2 3 3} +do_test 2.2.2 { db eval { SELECT a, b FROM t1 } } {1 3 2 1 3 2} + +#------------------------------------------------------------------------- +# +reset_db +db2 close +forcedelete test.db2 +sqlite3 db2 test.db2 + +do_test 3.1 { + do_common_sql { + CREATE TABLE t1(a PRIMARY KEY, b UNIQUE, c UNIQUE); + INSERT INTO t1 VALUES(1, 1, 1); + INSERT INTO t1 VALUES(2, 2, 2); + INSERT INTO t1 VALUES(3, 3, 3); + } +} {} + +do_test 3.3 { + do_then_apply_sql { + UPDATE t1 SET b=4 WHERE a=3; + UPDATE t1 SET b=3 WHERE a=2; + UPDATE t1 SET b=2 WHERE a=1; + } + compare_db db db2 +} {} + +do_test 3.4 { + do_then_apply_sql { + UPDATE t1 SET b=1 WHERE a=1; + UPDATE t1 SET b=2 WHERE a=2; + UPDATE t1 SET b=3 WHERE a=3; + } + compare_db db db2 +} {} + +#------------------------------------------------------------------------- +# +reset_db +db2 close +forcedelete test.db2 +sqlite3 db2 test.db2 + +do_test 4.1 { + do_common_sql { + CREATE TABLE t1(a PRIMARY KEY, b UNIQUE); + INSERT INTO t1 VALUES(1, 1); + INSERT INTO t1 VALUES(2, 2); + INSERT INTO t1 VALUES(3, 3); + + CREATE TABLE t2(a PRIMARY KEY, b UNIQUE); + INSERT INTO t2 VALUES(1, 1); + INSERT INTO t2 VALUES(2, 2); + INSERT INTO t2 VALUES(3, 3); + } +} {} + +do_test 4.2 { + do_then_apply_sql { + UPDATE t1 SET b=4 WHERE a=3; + UPDATE t1 SET b=3 WHERE a=2; + UPDATE t1 SET b=2 WHERE a=1; + + UPDATE t2 SET b=0 WHERE a=1; + UPDATE t2 SET b=1 WHERE a=2; + UPDATE t2 SET b=2 WHERE a=3; + } + compare_db db db2 +} {} + +do_test 4.3 { + do_then_apply_sql { + UPDATE t1 SET b=1 WHERE a=1; + UPDATE t1 SET b=2 WHERE a=2; + UPDATE t1 SET b=3 WHERE a=3; + + UPDATE t2 SET b=3 WHERE a=3; + UPDATE t2 SET b=2 WHERE a=2; + UPDATE t2 SET b=1 WHERE a=1; + } + compare_db db db2 +} {} + finish_test diff --git a/ext/session/sessionfault2.test b/ext/session/sessionfault2.test new file mode 100644 index 0000000000..2fc0780227 --- /dev/null +++ b/ext/session/sessionfault2.test @@ -0,0 +1,75 @@ +# 2016 March 31 +# +# 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. +# +#*********************************************************************** +# +# The focus of this file is testing the session module. +# + +if {![info exists testdir]} { + set testdir [file join [file dirname [info script]] .. .. test] +} +source [file join [file dirname [info script]] session_common.tcl] +source $testdir/tester.tcl +set testprefix sessionfault2 + +do_execsql_test 1.0.0 { + CREATE TABLE t1(a PRIMARY KEY, b UNIQUE); + INSERT INTO t1 VALUES(1, 1); + INSERT INTO t1 VALUES(2, 2); + INSERT INTO t1 VALUES(3, 3); + + CREATE TABLE t2(a PRIMARY KEY, b UNIQUE); + INSERT INTO t2 VALUES(1, 1); + INSERT INTO t2 VALUES(2, 2); + INSERT INTO t2 VALUES(3, 3); +} +faultsim_save_and_close + +faultsim_restore_and_reopen +do_test 1.0.1 { + set ::C [changeset_from_sql { + UPDATE t1 SET b=4 WHERE a=3; + UPDATE t1 SET b=3 WHERE a=2; + UPDATE t1 SET b=2 WHERE a=1; + UPDATE t2 SET b=0 WHERE a=1; + UPDATE t2 SET b=1 WHERE a=2; + UPDATE t2 SET b=2 WHERE a=3; + }] + set {} {} +} {} + +proc xConflict args { return "OMIT" } + +do_faultsim_test 1 -faults oom-p* -prep { + faultsim_restore_and_reopen +} -body { + sqlite3changeset_apply db $::C xConflict +} -test { + faultsim_test_result {0 {}} {1 SQLITE_NOMEM} + faultsim_integrity_check + + catch { db eval ROLLBACK } + set res [db eval { + SELECT * FROM t1; + SELECT * FROM t2; + }] + + if {$testrc==0} { + if {$res != "1 2 2 3 3 4 1 0 2 1 3 2"} { error "data error" } + } else { + if { + $res != "1 2 2 3 3 4 1 0 2 1 3 2" + && $res != "1 1 2 2 3 3 1 1 2 2 3 3" + } { error "data error!! $res" } + } +} + +finish_test + diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index 0f5c558463..437549dd70 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -3852,6 +3852,16 @@ static int sessionApplyOneOp( return rc; } +/* +** Attempt to apply the change that the iterator passed as the first argument +** currently points to to the database. If a conflict is encountered, invoke +** the conflict handler callback. +** +** The difference between this function and sessionApplyOne() is that this +** function handles the case where the conflict-handler is invoked and +** returns SQLITE_CHANGESET_REPLACE - indicating that the change should be +** retried in some manner. +*/ static int sessionApplyOneWithRetry( sqlite3 *db, /* Apply change to "main" db of this handle */ sqlite3_changeset_iter *pIter, /* Changeset iterator to read change from */ @@ -3864,12 +3874,26 @@ static int sessionApplyOneWithRetry( int rc; rc = sessionApplyOneOp(pIter, pApply, xConflict, pCtx, &bReplace, &bRetry); + assert( rc==SQLITE_OK || (bRetry==0 && bReplace==0) ); - if( rc==SQLITE_OK && bRetry ){ - rc = sessionApplyOneOp(pIter, pApply, xConflict, pCtx, &bReplace, 0); + /* If the bRetry flag is set, the change has not been applied due to an + ** SQLITE_CHANGESET_DATA problem (i.e. this is an UPDATE or DELETE and + ** a row with the correct PK is present in the db, but one or more other + ** fields do not contain the expected values) and the conflict handler + ** returned SQLITE_CHANGESET_REPLACE. In this case retry the operation, + ** but pass NULL as the final argument so that sessionApplyOneOp() ignores + ** the SQLITE_CHANGESET_DATA problem. */ + if( bRetry ){ + assert( pIter->op==SQLITE_UPDATE || pIter->op==SQLITE_DELETE ); + rc = sessionApplyOneOp(pIter, pApply, xConflict, pCtx, 0, 0); } - if( bReplace ){ + /* If the bReplace flag is set, the change is an INSERT that has not + ** been performed because the database already contains a row with the + ** specified primary key and the conflict handler returned + ** SQLITE_CHANGESET_REPLACE. In this case remove the conflicting row + ** before reattempting the INSERT. */ + else if( bReplace ){ assert( pIter->op==SQLITE_INSERT ); rc = sqlite3_exec(db, "SAVEPOINT replace_op", 0, 0, 0); if( rc==SQLITE_OK ){ @@ -3968,6 +3992,7 @@ static int sessionChangesetApply( const char *zTab = 0; /* Name of current table */ int nTab = 0; /* Result of sqlite3Strlen30(zTab) */ SessionApplyCtx sApply; /* changeset_apply() context object */ + int bPatchset; assert( xConflict!=0 ); @@ -4059,18 +4084,17 @@ static int sessionChangesetApply( rc = sessionApplyOneWithRetry(db, pIter, &sApply, xConflict, pCtx); } - if( rc==SQLITE_OK ){ - rc = sessionRetryConstraints( - db, pIter->bPatchset, zTab, &sApply, xConflict, pCtx - ); - } - + bPatchset = pIter->bPatchset; if( rc==SQLITE_OK ){ rc = sqlite3changeset_finalize(pIter); }else{ sqlite3changeset_finalize(pIter); } + if( rc==SQLITE_OK ){ + rc = sessionRetryConstraints(db, bPatchset, zTab, &sApply, xConflict, pCtx); + } + if( rc==SQLITE_OK ){ int nFk, notUsed; sqlite3_db_status(db, SQLITE_DBSTATUS_DEFERRED_FKS, &nFk, ¬Used, 0); diff --git a/manifest b/manifest index 96777daf79..cdbeeaf1de 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhanced\scomments\sdescribing\sthe\ssessions\sfile\sformat.\s\sNo\schanges\sto\scode. -D 2016-03-31T02:44:56.615 +C Add\sfurther\stests\sfor\sthe\scode\son\sthis\sbranch.\sFix\sa\sproblem\sin\sOOM\shandling. +D 2016-03-31T10:50:26.149 F Makefile.in e812bb732d7af01baa09f1278bd4f4a2e3a09449 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc cde766eb7c27a7ca42000e66c5f0c37a17a05998 @@ -287,10 +287,11 @@ F ext/session/sessionC.test 97556f5164ac29f2344b24bd7de6a3a35a95c390 F ext/session/sessionD.test d4744c78334162851d2a2f285c7e603e31b49aa2 F ext/session/sessionE.test e60a238c47f0feb3bb707e7f35e22be09c7e8f26 F ext/session/sessionF.test c2f178d4dfd723a5fd94a730ea2ccb44c669e3ce -F ext/session/sessionG.test 388b4f311176411301c35f90f0bf2cb7c6c3dec9 +F ext/session/sessionG.test 01ef705096a9d3984eebdcca79807a211dee1b60 F ext/session/session_common.tcl a1293167d14774b5e728836720497f40fe4ea596 F ext/session/sessionfault.test d52cbb7bee48cc8ee80335e07eb72fcb6b15eb40 -F ext/session/sqlite3session.c 8ed9c3acf81b12d9d6fcb61b198d851c06046555 +F ext/session/sessionfault2.test 2667fec1452e46abb5ce6c9f99483de8e0559032 +F ext/session/sqlite3session.c 2fc72bd989c424a15802da766c7ebd8eed47bcf6 F ext/session/sqlite3session.h 64e9e7f185725ef43b97f4a9a0c0df0669844f1d F ext/session/test_session.c 187bd344c5ae9d5be85e22ef7c3010f0c17307ce F ext/userauth/sqlite3userauth.h 19cb6f0e31316d0ee4afdfb7a85ef9da3333a220 @@ -1481,7 +1482,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ea917c14b940f95b20b91dae77567dc25a651ef6 -R 703150f896b886ff9303fa6318e268aa -U drh -Z 55b5826bc78e3fc677b5c1348287f2c3 +P 84dc41e2df1092e9724a535b670343181a9cd0dd +R 6c1e5637abee98a737c22aa1d2e2c831 +U dan +Z ca2c22d2a622b0edd20f5f5ca6a19e56 diff --git a/manifest.uuid b/manifest.uuid index fe7a39a337..35597317e7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -84dc41e2df1092e9724a535b670343181a9cd0dd \ No newline at end of file +195f3340ee4d870420e4f58d44300bab5436b920 \ No newline at end of file From 0d0a2abc6a6e8d97647db3297e36dd8228050257 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 31 Mar 2016 15:08:10 +0000 Subject: [PATCH 0230/1484] Add another OOM test to this branch. FossilOrigin-Name: 49763fc3ae2fb6117b0443ea28661568467f9bf2 --- ext/session/sessionfault2.test | 31 +++++++++++++++++++++++++++++++ manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 38 insertions(+), 7 deletions(-) diff --git a/ext/session/sessionfault2.test b/ext/session/sessionfault2.test index 2fc0780227..6b257cf41b 100644 --- a/ext/session/sessionfault2.test +++ b/ext/session/sessionfault2.test @@ -71,5 +71,36 @@ do_faultsim_test 1 -faults oom-p* -prep { } } +#------------------------------------------------------------------------- +# OOM when applying a changeset for which one of the tables has a name +# 99 bytes in size. This happens to cause an extra malloc in within the +# sessions_strm permutation. +# +reset_db +set nm [string repeat t 99] +do_execsql_test 2.0.0 [string map "%TBL% $nm" { + CREATE TABLE %TBL%(a PRIMARY KEY, b UNIQUE); +}] +faultsim_save_and_close + +faultsim_restore_and_reopen +do_test 1.0.1 { + set ::C [changeset_from_sql [string map "%TBL% $nm" { + INSERT INTO %TBL% VALUES(1, 2); + INSERT INTO %TBL% VALUES(3, 4); + }]] + set {} {} +} {} + +proc xConflict args { return "OMIT" } +do_faultsim_test 2 -faults oom-p* -prep { + faultsim_restore_and_reopen +} -body { + sqlite3changeset_apply db $::C xConflict +} -test { + faultsim_test_result {0 {}} {1 SQLITE_NOMEM} + faultsim_integrity_check +} + finish_test diff --git a/manifest b/manifest index cdbeeaf1de..61906ced3a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sfurther\stests\sfor\sthe\scode\son\sthis\sbranch.\sFix\sa\sproblem\sin\sOOM\shandling. -D 2016-03-31T10:50:26.149 +C Add\sanother\sOOM\stest\sto\sthis\sbranch. +D 2016-03-31T15:08:10.284 F Makefile.in e812bb732d7af01baa09f1278bd4f4a2e3a09449 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc cde766eb7c27a7ca42000e66c5f0c37a17a05998 @@ -290,7 +290,7 @@ F ext/session/sessionF.test c2f178d4dfd723a5fd94a730ea2ccb44c669e3ce F ext/session/sessionG.test 01ef705096a9d3984eebdcca79807a211dee1b60 F ext/session/session_common.tcl a1293167d14774b5e728836720497f40fe4ea596 F ext/session/sessionfault.test d52cbb7bee48cc8ee80335e07eb72fcb6b15eb40 -F ext/session/sessionfault2.test 2667fec1452e46abb5ce6c9f99483de8e0559032 +F ext/session/sessionfault2.test ac1dfd77a0fb0ea310aee40a16645ef1b66d3f88 F ext/session/sqlite3session.c 2fc72bd989c424a15802da766c7ebd8eed47bcf6 F ext/session/sqlite3session.h 64e9e7f185725ef43b97f4a9a0c0df0669844f1d F ext/session/test_session.c 187bd344c5ae9d5be85e22ef7c3010f0c17307ce @@ -1482,7 +1482,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 84dc41e2df1092e9724a535b670343181a9cd0dd -R 6c1e5637abee98a737c22aa1d2e2c831 +P 195f3340ee4d870420e4f58d44300bab5436b920 +R 553c882c4eb73691c7e02bdd576b9d70 U dan -Z ca2c22d2a622b0edd20f5f5ca6a19e56 +Z 5ef40d72349254975dc55c844d6daff8 diff --git a/manifest.uuid b/manifest.uuid index 35597317e7..9ba171f6ba 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -195f3340ee4d870420e4f58d44300bab5436b920 \ No newline at end of file +49763fc3ae2fb6117b0443ea28661568467f9bf2 \ No newline at end of file From 5996a7798796241fb749bb1ffd3a2a2ca55b5993 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 31 Mar 2016 20:40:28 +0000 Subject: [PATCH 0231/1484] Enhance the query planner so that IS and IS NULL operators are able to drive an index on a LEFT OUTER JOIN. FossilOrigin-Name: c648539b52ca28c0b2cb61208e2c32b1d29626a1 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/where.c | 14 ++++++++++++-- 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index c602040523..985501bcf7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Updates\sfor\sthe\sMSVC\smakefiles. -D 2016-03-30T16:23:06.801 +C Enhance\sthe\squery\splanner\sso\sthat\sIS\sand\sIS\sNULL\soperators\sare\sable\sto\sdrive\nan\sindex\son\sa\sLEFT\sOUTER\sJOIN. +D 2016-03-31T20:40:28.501 F Makefile.in e812bb732d7af01baa09f1278bd4f4a2e3a09449 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc cde766eb7c27a7ca42000e66c5f0c37a17a05998 @@ -453,7 +453,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 10deb6b43887662691e5f53d10b3c171c401169b F src/wal.h 2f7c831cf3b071fa548bf2d5cac640846a7ff19c F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354 -F src/where.c fe7925faafbe9a458972035c0bb4753d672f04ed +F src/where.c 99cc6270fc3915201e2a90bbac3768f007a89c44 F src/whereInt.h 93297d56edd137b7ea004490690fb6e2ce028a34 F src/wherecode.c 863aedf086131743763c1960637fde904eadc442 F src/whereexpr.c fb87944b1254234e5bba671aaf6dee476241506a @@ -1480,7 +1480,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 64d75cbe2c45af67124fa7ce5688d91cc6ddb755 -R 77269b95e931ac6cca96bcd2fa718a38 -U mistachkin -Z 37f983898af724eda9f571ecd8a4d862 +P 7cf0cab730e2d570c82dd789279ad6501ac598c8 +R 208d59c6eb413bba3e66e70033cda029 +U drh +Z d36ae30a27c8e5f7b17afdd33be692aa diff --git a/manifest.uuid b/manifest.uuid index 2aa68317b9..c1ba66c050 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7cf0cab730e2d570c82dd789279ad6501ac598c8 \ No newline at end of file +c648539b52ca28c0b2cb61208e2c32b1d29626a1 \ No newline at end of file diff --git a/src/where.c b/src/where.c index cf23aa62a4..4f7ee66ff7 100644 --- a/src/where.c +++ b/src/where.c @@ -2201,8 +2201,6 @@ static int whereLoopAddBtreeIndex( assert( (pNew->wsFlags & WHERE_TOP_LIMIT)==0 ); if( pNew->wsFlags & WHERE_BTM_LIMIT ){ opMask = WO_LT|WO_LE; - }else if( /*pProbe->tnum<=0 ||*/ (pSrc->fg.jointype & JT_LEFT)!=0 ){ - opMask = WO_EQ|WO_IN|WO_GT|WO_GE|WO_LT|WO_LE; }else{ opMask = WO_EQ|WO_IN|WO_GT|WO_GE|WO_LT|WO_LE|WO_ISNULL|WO_IS; } @@ -2240,6 +2238,18 @@ static int whereLoopAddBtreeIndex( ** to mix with a lower range bound from some other source */ if( pTerm->wtFlags & TERM_LIKEOPT && pTerm->eOperator==WO_LT ) continue; + /* Do not allow IS constraints from the WHERE clause to be used by the + ** right table of a LEFT JOIN. Only constraints in the ON clause are + ** allowed */ + if( (pSrc->fg.jointype & JT_LEFT)!=0 + && !ExprHasProperty(pTerm->pExpr, EP_FromJoin) + && (eOp & (WO_IS|WO_ISNULL))!=0 + ){ + testcase( eOp & WO_IS ); + testcase( eOp & WO_ISNULL ); + continue; + } + pNew->wsFlags = saved_wsFlags; pNew->u.btree.nEq = saved_nEq; pNew->nLTerm = saved_nLTerm; From 2779989110c659236dae61affe032469da518444 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Thu, 31 Mar 2016 22:53:37 +0000 Subject: [PATCH 0232/1484] Update the clean target in the MSVC makefile. FossilOrigin-Name: 69f4d83210f6425b2c0d699b397ef4fa4422d438 --- Makefile.msc | 2 +- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Makefile.msc b/Makefile.msc index 84c2eac2f4..7fa9555c35 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -2089,7 +2089,7 @@ clean: del /Q mptester.exe wordcount.exe rbu.exe srcck1.exe 2>NUL del /Q sqlite3.c sqlite3-*.c 2>NUL del /Q sqlite3rc.h 2>NUL - del /Q shell.c sqlite3ext.h 2>NUL + del /Q shell.c sqlite3ext.h sqlite3session.h 2>NUL del /Q sqlite3_analyzer.exe sqlite3_analyzer.c 2>NUL del /Q sqlite-*-output.vsix 2>NUL del /Q fuzzershell.exe fuzzcheck.exe sqldiff.exe 2>NUL diff --git a/manifest b/manifest index 985501bcf7..6ccaa6e08d 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -C Enhance\sthe\squery\splanner\sso\sthat\sIS\sand\sIS\sNULL\soperators\sare\sable\sto\sdrive\nan\sindex\son\sa\sLEFT\sOUTER\sJOIN. -D 2016-03-31T20:40:28.501 +C Update\sthe\sclean\starget\sin\sthe\sMSVC\smakefile. +D 2016-03-31T22:53:37.345 F Makefile.in e812bb732d7af01baa09f1278bd4f4a2e3a09449 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 -F Makefile.msc cde766eb7c27a7ca42000e66c5f0c37a17a05998 +F Makefile.msc fe57d7e3e74fa383fd01ced796c0ffd966fc094a F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7 F VERSION 5d234da9b5dae329fab75ff75884cfe0a9cb3fda F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 @@ -1480,7 +1480,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 7cf0cab730e2d570c82dd789279ad6501ac598c8 -R 208d59c6eb413bba3e66e70033cda029 -U drh -Z d36ae30a27c8e5f7b17afdd33be692aa +P c648539b52ca28c0b2cb61208e2c32b1d29626a1 +R 6ae456c611a2dfae066ef8a6f11a421b +U mistachkin +Z 730dfc7c7e8862f73161aa001e93b9d4 diff --git a/manifest.uuid b/manifest.uuid index c1ba66c050..c52f6651c2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c648539b52ca28c0b2cb61208e2c32b1d29626a1 \ No newline at end of file +69f4d83210f6425b2c0d699b397ef4fa4422d438 \ No newline at end of file From f6661a88963aa939d1c377954cbf34de98902476 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 1 Apr 2016 12:35:22 +0000 Subject: [PATCH 0233/1484] When reading an sqlite_stat1 table with missing entries for some indexes, set the default for the missing indexes after all other indexes are set so that the default values are more in line with indexes that are actually in the stat1 table. FossilOrigin-Name: a62340dc0507e36f6dec05b1fda68d8399ec62ec --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/analyze.c | 29 ++++++++++++++++------------- 3 files changed, 24 insertions(+), 21 deletions(-) diff --git a/manifest b/manifest index 6ccaa6e08d..51885512ec 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\sthe\sclean\starget\sin\sthe\sMSVC\smakefile. -D 2016-03-31T22:53:37.345 +C When\sreading\san\ssqlite_stat1\stable\swith\smissing\sentries\sfor\ssome\sindexes,\nset\sthe\sdefault\sfor\sthe\smissing\sindexes\safter\sall\sother\sindexes\sare\sset\nso\sthat\sthe\sdefault\svalues\sare\smore\sin\sline\swith\sindexes\sthat\sare\sactually\nin\sthe\sstat1\stable. +D 2016-04-01T12:35:22.357 F Makefile.in e812bb732d7af01baa09f1278bd4f4a2e3a09449 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc fe57d7e3e74fa383fd01ced796c0ffd966fc094a @@ -311,7 +311,7 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F src/alter.c 1bb0709b3048e24217b80ec6bd78a3e99a47c01b -F src/analyze.c ab57b6763dd4c6170a20673d14882c033affd188 +F src/analyze.c 39b21e4d9ad8a647e9834aa5ba99a74fb6c98879 F src/attach.c 771153bd1f4ab0b97a44a13dde2c7e5e1efeba22 F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240 F src/backup.c f60f0aa55d25d853ffde53d0b0370a7bb7ee41ce @@ -1480,7 +1480,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P c648539b52ca28c0b2cb61208e2c32b1d29626a1 -R 6ae456c611a2dfae066ef8a6f11a421b -U mistachkin -Z 730dfc7c7e8862f73161aa001e93b9d4 +P 69f4d83210f6425b2c0d699b397ef4fa4422d438 +R 7562b4ce09688850a9cd06c483af68bc +U drh +Z f4c65a7a3ea821b7d157bc63d7456b83 diff --git a/manifest.uuid b/manifest.uuid index c52f6651c2..0b71e7ae1c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -69f4d83210f6425b2c0d699b397ef4fa4422d438 \ No newline at end of file +a62340dc0507e36f6dec05b1fda68d8399ec62ec \ No newline at end of file diff --git a/src/analyze.c b/src/analyze.c index cd59ae681d..423ef0d714 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -1835,31 +1835,34 @@ int sqlite3AnalysisLoad(sqlite3 *db, int iDb){ assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){ Index *pIdx = sqliteHashData(i); - sqlite3DefaultRowEst(pIdx); + pIdx->aiRowLogEst[0] = 0; #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 sqlite3DeleteIndexSamples(db, pIdx); pIdx->aSample = 0; #endif } - /* Check to make sure the sqlite_stat1 table exists */ + /* Load new statistics out of the sqlite_stat1 table */ sInfo.db = db; sInfo.zDatabase = db->aDb[iDb].zName; - if( sqlite3FindTable(db, "sqlite_stat1", sInfo.zDatabase)==0 ){ - return SQLITE_ERROR; + if( sqlite3FindTable(db, "sqlite_stat1", sInfo.zDatabase)!=0 ){ + zSql = sqlite3MPrintf(db, + "SELECT tbl,idx,stat FROM %Q.sqlite_stat1", sInfo.zDatabase); + if( zSql==0 ){ + rc = SQLITE_NOMEM_BKPT; + }else{ + rc = sqlite3_exec(db, zSql, analysisLoader, &sInfo, 0); + sqlite3DbFree(db, zSql); + } } - /* Load new statistics out of the sqlite_stat1 table */ - zSql = sqlite3MPrintf(db, - "SELECT tbl,idx,stat FROM %Q.sqlite_stat1", sInfo.zDatabase); - if( zSql==0 ){ - rc = SQLITE_NOMEM_BKPT; - }else{ - rc = sqlite3_exec(db, zSql, analysisLoader, &sInfo, 0); - sqlite3DbFree(db, zSql); + /* Set appropriate defaults on all indexes not in the sqlite_stat1 table */ + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){ + Index *pIdx = sqliteHashData(i); + if( pIdx->aiRowLogEst[0]==0 ) sqlite3DefaultRowEst(pIdx); } - /* Load the statistics from the sqlite_stat4 table. */ #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 if( rc==SQLITE_OK && OptimizationEnabled(db, SQLITE_Stat34) ){ From 076b6468f5cc83332ebe0aa1a65c42f43756c575 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 1 Apr 2016 17:54:07 +0000 Subject: [PATCH 0234/1484] Preupdate hook documentation fixes. No changes to code. FossilOrigin-Name: 59814f35d13db1f6379b9ae218b5432bc03c6197 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/sqlite.h.in | 13 +++++++------ 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 51885512ec..d573902ae9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C When\sreading\san\ssqlite_stat1\stable\swith\smissing\sentries\sfor\ssome\sindexes,\nset\sthe\sdefault\sfor\sthe\smissing\sindexes\safter\sall\sother\sindexes\sare\sset\nso\sthat\sthe\sdefault\svalues\sare\smore\sin\sline\swith\sindexes\sthat\sare\sactually\nin\sthe\sstat1\stable. -D 2016-04-01T12:35:22.357 +C Preupdate\shook\sdocumentation\sfixes.\s\sNo\schanges\sto\scode. +D 2016-04-01T17:54:07.826 F Makefile.in e812bb732d7af01baa09f1278bd4f4a2e3a09449 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc fe57d7e3e74fa383fd01ced796c0ffd966fc094a @@ -375,7 +375,7 @@ F src/resolve.c b8f7174e5f8c33c44ded3a25a973d0bb89228c20 F src/rowset.c 9fe4b3ad7cc00944386bb600233d8f523de07a6e F src/select.c 7849cee0a01952a9c93cd28989daedfa57731143 F src/shell.c cd3f82fdc5c895b817a375b7ab8319cb41f447ce -F src/sqlite.h.in 843a0dfcf8c5e961cfafa62009fed0867b88241e +F src/sqlite.h.in c46a7b85d3f37371cacea8f98ec825f5e52c420c F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 98f72cbfe00169c39089115427d06ea05fe4b4a2 F src/sqliteInt.h 594bf31a7a0cc788688ca947e562576e23bd7904 @@ -1480,7 +1480,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 69f4d83210f6425b2c0d699b397ef4fa4422d438 -R 7562b4ce09688850a9cd06c483af68bc +P a62340dc0507e36f6dec05b1fda68d8399ec62ec +R 17cbd88111da841c5ced2fa2ee956e9f U drh -Z f4c65a7a3ea821b7d157bc63d7456b83 +Z dfefbe59c009b860b7f7e89f1f29dda4 diff --git a/manifest.uuid b/manifest.uuid index 0b71e7ae1c..c694118307 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a62340dc0507e36f6dec05b1fda68d8399ec62ec \ No newline at end of file +59814f35d13db1f6379b9ae218b5432bc03c6197 \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 35de70ff7f..b5f0e7f98e 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -5187,7 +5187,7 @@ void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*); ** ^The sqlite3_update_hook() interface registers a callback function ** with the [database connection] identified by the first argument ** to be invoked whenever a row is updated, inserted or deleted in -** a rowid table. +** a [rowid table]. ** ^Any callback set by a previous call to this function ** for the same database connection is overridden. ** @@ -7917,13 +7917,13 @@ int sqlite3_db_cacheflush(sqlite3*); /* ** CAPI3REF: The pre-update hook. -** EXPERIMENTAL ** ** ^These interfaces are only available if SQLite is compiled using the -** [SQLITE_ENABLE_UPDATE_HOOK] compile-time option. +** [SQLITE_ENABLE_PREUPDATE_HOOK] compile-time option. ** ** ^The [sqlite3_preupdate_hook()] interface registers a callback function -** that is invoked prior to each [INSERT], [UPDATE], and [DELETE] operation. +** that is invoked prior to each [INSERT], [UPDATE], and [DELETE] operation +** on a [rowid table]. ** ^At most one preupdate hook may be registered at a time on a single ** [database connection]; each call to [sqlite3_preupdate_hook()] overrides ** the previous setting. @@ -7932,8 +7932,9 @@ int sqlite3_db_cacheflush(sqlite3*); ** ^The third parameter to [sqlite3_preupdate_hook()] is passed through as ** the first parameter to callbacks. ** -** ^The preupdate hook only fires for changes to real tables; the preupdate -** hook is not invoked for changes to virtual tables. +** ^The preupdate hook only fires for changes to [rowid tables]; the preupdate +** hook is not invoked for changes to [virtual tables] or [WITHOUT ROWID] +** tables. ** ** ^The second parameter to the preupdate callback is a pointer to ** the [database connection] that registered the preupdate hook. From 899c5c9d348f3fb0c74fa7f21b06fb0e2ef67f60 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Sun, 3 Apr 2016 20:50:02 +0000 Subject: [PATCH 0235/1484] Replace the new fprintf() calls. FossilOrigin-Name: f76c3a0ca40989fe9401c3b6f662f8e6ef2a730c --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/shell.c | 29 ++++++++++++++++------------- 3 files changed, 26 insertions(+), 23 deletions(-) diff --git a/manifest b/manifest index 9b4d901476..375fb5cce3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\supdates\sfrom\strunk. -D 2016-04-03T20:45:04.922 +C Replace\sthe\snew\sfprintf()\scalls. +D 2016-04-03T20:50:02.891 F Makefile.in e812bb732d7af01baa09f1278bd4f4a2e3a09449 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc fe57d7e3e74fa383fd01ced796c0ffd966fc094a @@ -13,7 +13,7 @@ F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am 42f7eb1fb2b06ddd6c6adab3e4388cc0a237ba40 F autoconf/Makefile.msc dc0d0500e4a827cb3891d08d846dd6dd40241b51 F autoconf/README.first 6c4f34fe115ff55d4e8dbfa3cecf04a0188292f7 -F autoconf/README.txt 4f04b0819303aabaa35fff5f7b257fb0c1ef95f1 w autoconf/README +F autoconf/README.txt 4f04b0819303aabaa35fff5f7b257fb0c1ef95f1 F autoconf/configure.ac d807b567f73a2b0986ccdd206b782cecb4d08fff F autoconf/tea/Makefile.in b438a7020446c8a8156e8d97c8914a04833da6fd F autoconf/tea/README 3e9a3c060f29a44344ab50aec506f4db903fb873 @@ -374,7 +374,7 @@ F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c b8f7174e5f8c33c44ded3a25a973d0bb89228c20 F src/rowset.c 9fe4b3ad7cc00944386bb600233d8f523de07a6e F src/select.c 7849cee0a01952a9c93cd28989daedfa57731143 -F src/shell.c c8a75d0d77c3fe691e0f5f970ddc5e49908ebe97 +F src/shell.c e126f647f63da3d5d820f012359b89075cd7de99 F src/sqlite.h.in c46a7b85d3f37371cacea8f98ec825f5e52c420c F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 98f72cbfe00169c39089115427d06ea05fe4b4a2 @@ -1010,7 +1010,7 @@ F test/savepoint4.test c8f8159ade6d2acd9128be61e1230f1c1edc6cc0 F test/savepoint5.test 0735db177e0ebbaedc39812c8d065075d563c4fd F test/savepoint6.test f41279c5e137139fa5c21485773332c7adb98cd7 F test/savepoint7.test db3db281486c925095f305aad09fe806e5188ff3 -F test/savepointfault.test f044eac64b59f09746c7020ee261734de82bf9b2 w test/savepoint3.test +F test/savepointfault.test f044eac64b59f09746c7020ee261734de82bf9b2 F test/scanstatus.test 5253c219e331318a437f436268e0e82345700285 F test/schema.test 8f7999be894260f151adf15c2c7540f1c6d6a481 F test/schema2.test 906408621ea881fdb496d878b1822572a34e32c5 @@ -1376,7 +1376,7 @@ F test/whereH.test e4b07f7a3c2f5d31195cd33710054c78667573b2 F test/whereI.test eab5b226bbc344ac70d7dc09b963a064860ae6d7 F test/whereJ.test 55a3221706a7ab706293f17cc8f96da563bf0767 F test/whereK.test f8e3cf26a8513ecc7f514f54df9f0572c046c42b -F test/wherefault.test 1374c3aa198388925246475f84ad4cd5f9528864 w test/where8m.test +F test/wherefault.test 1374c3aa198388925246475f84ad4cd5f9528864 F test/wherelimit.test 5e9fd41e79bb2b2d588ed999d641d9c965619b31 F test/wild001.test bca33f499866f04c24510d74baf1e578d4e44b1c F test/win32heap.test ea19770974795cff26e11575e12d422dbd16893c @@ -1480,7 +1480,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 5cbab63756f6f276996f39d16d70b178581f63cd 59814f35d13db1f6379b9ae218b5432bc03c6197 -R 7b729d340f074699d469d04257844002 +P 566b551e5a81440a5c8ff865ceb4422c76d67cf7 +R c328759cdfd1946a4f3790cce9b56b06 U mistachkin -Z ad64521de5ede9ab99c45ca3b47e617d +Z fca762cd11972041ea0ef005e2621264 diff --git a/manifest.uuid b/manifest.uuid index 3b86cc6a51..ed8ee7667b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -566b551e5a81440a5c8ff865ceb4422c76d67cf7 \ No newline at end of file +f76c3a0ca40989fe9401c3b6f662f8e6ef2a730c \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 925de30c4f..9cec288024 100644 --- a/src/shell.c +++ b/src/shell.c @@ -2038,7 +2038,7 @@ static char zHelp[] = ** Print help information for the ".sessions" command */ void session_help(ShellState *p){ - fprintf(p->out, + raw_printf(p->out, ".session ?NAME? SUBCOMMAND ?ARGS...?\n" "If ?NAME? is omitted, the first defined session is used.\n" "Subcommands:\n" @@ -3902,11 +3902,11 @@ static int do_meta_command(char *zLine, ShellState *p){ if( nCmd!=2 ) goto session_syntax_error; if( pSession->p==0 ){ session_not_open: - fprintf(stderr, "ERROR: No sessions are open\n"); + raw_printf(stderr, "ERROR: No sessions are open\n"); }else{ rc = sqlite3session_attach(pSession->p, azCmd[1]); if( rc ){ - fprintf(stderr, "ERROR: sqlite3session_attach() returns %d\n", rc); + raw_printf(stderr, "ERROR: sqlite3session_attach() returns %d\n", rc); rc = 0; } } @@ -3922,7 +3922,7 @@ static int do_meta_command(char *zLine, ShellState *p){ if( pSession->p==0 ) goto session_not_open; out = fopen(azCmd[1], "wb"); if( out==0 ){ - fprintf(stderr, "ERROR: cannot open \"%s\" for writing\n", azCmd[1]); + utf8_printf(stderr, "ERROR: cannot open \"%s\" for writing\n", azCmd[1]); }else{ int szChng; void *pChng; @@ -3937,7 +3937,7 @@ static int do_meta_command(char *zLine, ShellState *p){ } if( pChng && fwrite(pChng, szChng, 1, out)!=1 ){ - fprintf(stderr, "ERROR: Failed to write entire %d-byte output\n", + raw_printf(stderr, "ERROR: Failed to write entire %d-byte output\n", szChng); } sqlite3_free(pChng); @@ -3965,7 +3965,8 @@ static int do_meta_command(char *zLine, ShellState *p){ ii = nCmd==1 ? -1 : booleanValue(azCmd[1]); if( p->nSession ){ ii = sqlite3session_enable(pSession->p, ii); - fprintf(p->out, "session %s enable flag = %d\n", pSession->zName, ii); + utf8_printf(p->out, "session %s enable flag = %d\n", + pSession->zName, ii); } }else @@ -3983,7 +3984,7 @@ static int do_meta_command(char *zLine, ShellState *p){ nByte = sizeof(pSession->azFilter[0])*(nCmd-1); pSession->azFilter = sqlite3_malloc( nByte ); if( pSession->azFilter==0 ){ - fprintf(stderr, "Error: out or memory\n"); + raw_printf(stderr, "Error: out or memory\n"); exit(1); } for(ii=1; iinSession ){ ii = sqlite3session_indirect(pSession->p, ii); - fprintf(p->out, "session %s indirect flag = %d\n", pSession->zName,ii); + utf8_printf(p->out, "session %s indirect flag = %d\n", + pSession->zName, ii); } }else @@ -4014,7 +4016,8 @@ static int do_meta_command(char *zLine, ShellState *p){ if( nCmd!=1 ) goto session_syntax_error; if( p->nSession ){ ii = sqlite3session_isempty(pSession->p); - fprintf(p->out, "session %s isempty flag = %d\n", pSession->zName, ii); + utf8_printf(p->out, "session %s isempty flag = %d\n", + pSession->zName, ii); } }else @@ -4023,7 +4026,7 @@ static int do_meta_command(char *zLine, ShellState *p){ */ if( strcmp(azCmd[0],"list")==0 ){ for(i=0; inSession; i++){ - fprintf(p->out, "%d %s\n", i, p->aSession[i].zName); + utf8_printf(p->out, "%d %s\n", i, p->aSession[i].zName); } }else @@ -4038,18 +4041,18 @@ static int do_meta_command(char *zLine, ShellState *p){ if( zName[0]==0 ) goto session_syntax_error; for(i=0; inSession; i++){ if( strcmp(p->aSession[i].zName,zName)==0 ){ - fprintf(stderr, "Session \"%s\" already exists\n", zName); + utf8_printf(stderr, "Session \"%s\" already exists\n", zName); goto meta_command_exit; } } if( p->nSession>=ArraySize(p->aSession) ){ - fprintf(stderr, "Maximum of %d sessions\n", ArraySize(p->aSession)); + raw_printf(stderr, "Maximum of %d sessions\n", ArraySize(p->aSession)); goto meta_command_exit; } pSession = &p->aSession[p->nSession]; rc = sqlite3session_create(p->db, azCmd[1], &pSession->p); if( rc ){ - fprintf(stderr, "Cannot open session: error code=%d\n", rc); + raw_printf(stderr, "Cannot open session: error code=%d\n", rc); rc = 0; goto meta_command_exit; } From 5daed673b8910f58c23f8d4e27dabd2d73fb2941 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Sun, 3 Apr 2016 22:44:16 +0000 Subject: [PATCH 0236/1484] Revise and enhance the Win32 string conversion routines. FossilOrigin-Name: 345860c92195544aad44ea9b0d14c9ebbd50adf2 --- manifest | 12 ++-- manifest.uuid | 2 +- src/os_win.c | 152 ++++++++++++++++++++++++++++++++++++-------------- 3 files changed, 117 insertions(+), 49 deletions(-) diff --git a/manifest b/manifest index 375fb5cce3..0687355cf6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Replace\sthe\snew\sfprintf()\scalls. -D 2016-04-03T20:50:02.891 +C Revise\sand\senhance\sthe\sWin32\sstring\sconversion\sroutines. +D 2016-04-03T22:44:16.657 F Makefile.in e812bb732d7af01baa09f1278bd4f4a2e3a09449 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc fe57d7e3e74fa383fd01ced796c0ffd966fc094a @@ -358,7 +358,7 @@ F src/os.h 91ff889115ecd01f436d3611f7f5ea4dc12d92f1 F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85 F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa F src/os_unix.c b1ccb273771f41dbdbe0ba7c1ad63c38ad5972ec -F src/os_win.c ff870d89f4cb088a04cbf5ea0cbd9ff1b089ff4a +F src/os_win.c 01ae58949a28edaecd5645abbe29ac9d2ee983fd F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c 38718a019ca762ba4f6795425d5a54db70d1790d F src/pager.h e1d38a2f14849e219df0f91f8323504d134c8a56 @@ -1480,7 +1480,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 566b551e5a81440a5c8ff865ceb4422c76d67cf7 -R c328759cdfd1946a4f3790cce9b56b06 +P f76c3a0ca40989fe9401c3b6f662f8e6ef2a730c +R 9a8e623b20453c0fbff989d22019add7 U mistachkin -Z fca762cd11972041ea0ef005e2621264 +Z 149573e0b667520348654eca6c5f3228 diff --git a/manifest.uuid b/manifest.uuid index ed8ee7667b..280e3ae958 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f76c3a0ca40989fe9401c3b6f662f8e6ef2a730c \ No newline at end of file +345860c92195544aad44ea9b0d14c9ebbd50adf2 \ No newline at end of file diff --git a/src/os_win.c b/src/os_win.c index f64a7d43a7..9508c97a14 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -1635,50 +1635,50 @@ void sqlite3MemSetDefault(void){ ** ** Space to hold the returned string is obtained from malloc. */ -static LPWSTR winUtf8ToUnicode(const char *zFilename){ +static LPWSTR winUtf8ToUnicode(const char *zText){ int nChar; - LPWSTR zWideFilename; + LPWSTR zWideText; - nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0); + nChar = osMultiByteToWideChar(CP_UTF8, 0, zText, -1, NULL, 0); if( nChar==0 ){ return 0; } - zWideFilename = sqlite3MallocZero( nChar*sizeof(zWideFilename[0]) ); - if( zWideFilename==0 ){ + zWideText = sqlite3MallocZero( nChar*sizeof(WCHAR) ); + if( zWideText==0 ){ return 0; } - nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename, + nChar = osMultiByteToWideChar(CP_UTF8, 0, zText, -1, zWideText, nChar); if( nChar==0 ){ - sqlite3_free(zWideFilename); - zWideFilename = 0; + sqlite3_free(zWideText); + zWideText = 0; } - return zWideFilename; + return zWideText; } /* ** Convert Microsoft Unicode to UTF-8. Space to hold the returned string is ** obtained from sqlite3_malloc(). */ -static char *winUnicodeToUtf8(LPCWSTR zWideFilename){ +static char *winUnicodeToUtf8(LPCWSTR zWideText){ int nByte; - char *zFilename; + char *zText; - nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, 0, 0, 0, 0); + nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideText, -1, 0, 0, 0, 0); if( nByte == 0 ){ return 0; } - zFilename = sqlite3MallocZero( nByte ); - if( zFilename==0 ){ + zText = sqlite3MallocZero( nByte ); + if( zText==0 ){ return 0; } - nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, zFilename, nByte, + nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideText, -1, zText, nByte, 0, 0); if( nByte == 0 ){ - sqlite3_free(zFilename); - zFilename = 0; + sqlite3_free(zText); + zText = 0; } - return zFilename; + return zText; } /* @@ -1688,12 +1688,12 @@ static char *winUnicodeToUtf8(LPCWSTR zWideFilename){ ** Space to hold the returned string is obtained ** from sqlite3_malloc. */ -static LPWSTR winMbcsToUnicode(const char *zFilename){ +static LPWSTR winMbcsToUnicode(const char *zText, int useAnsi){ int nByte; LPWSTR zMbcsFilename; - int codepage = osAreFileApisANSI() ? CP_ACP : CP_OEMCP; + int codepage = useAnsi ? CP_ACP : CP_OEMCP; - nByte = osMultiByteToWideChar(codepage, 0, zFilename, -1, NULL, + nByte = osMultiByteToWideChar(codepage, 0, zText, -1, NULL, 0)*sizeof(WCHAR); if( nByte==0 ){ return 0; @@ -1702,7 +1702,7 @@ static LPWSTR winMbcsToUnicode(const char *zFilename){ if( zMbcsFilename==0 ){ return 0; } - nByte = osMultiByteToWideChar(codepage, 0, zFilename, -1, zMbcsFilename, + nByte = osMultiByteToWideChar(codepage, 0, zText, -1, zMbcsFilename, nByte); if( nByte==0 ){ sqlite3_free(zMbcsFilename); @@ -1718,60 +1718,128 @@ static LPWSTR winMbcsToUnicode(const char *zFilename){ ** Space to hold the returned string is obtained from ** sqlite3_malloc(). */ -static char *winUnicodeToMbcs(LPCWSTR zWideFilename){ +static char *winUnicodeToMbcs(LPCWSTR zWideText, int useAnsi){ int nByte; - char *zFilename; - int codepage = osAreFileApisANSI() ? CP_ACP : CP_OEMCP; + char *zText; + int codepage = useAnsi ? CP_ACP : CP_OEMCP; - nByte = osWideCharToMultiByte(codepage, 0, zWideFilename, -1, 0, 0, 0, 0); + nByte = osWideCharToMultiByte(codepage, 0, zWideText, -1, 0, 0, 0, 0); if( nByte == 0 ){ return 0; } - zFilename = sqlite3MallocZero( nByte ); - if( zFilename==0 ){ + zText = sqlite3MallocZero( nByte ); + if( zText==0 ){ return 0; } - nByte = osWideCharToMultiByte(codepage, 0, zWideFilename, -1, zFilename, + nByte = osWideCharToMultiByte(codepage, 0, zWideText, -1, zText, nByte, 0, 0); if( nByte == 0 ){ - sqlite3_free(zFilename); - zFilename = 0; + sqlite3_free(zText); + zText = 0; } - return zFilename; + return zText; } /* ** Convert multibyte character string to UTF-8. Space to hold the ** returned string is obtained from sqlite3_malloc(). */ -char *sqlite3_win32_mbcs_to_utf8(const char *zFilename){ - char *zFilenameUtf8; +char *sqlite3_win32_mbcs_to_utf8(const char *zText){ + char *zTextUtf8; LPWSTR zTmpWide; - zTmpWide = winMbcsToUnicode(zFilename); + zTmpWide = winMbcsToUnicode(zText, osAreFileApisANSI()); if( zTmpWide==0 ){ return 0; } - zFilenameUtf8 = winUnicodeToUtf8(zTmpWide); + zTextUtf8 = winUnicodeToUtf8(zTmpWide); sqlite3_free(zTmpWide); - return zFilenameUtf8; + return zTextUtf8; +} + +/* +** Convert multibyte character string to UTF-8 using the ANSI codepage. +** Space to hold the returned string is obtained from sqlite3_malloc(). +*/ +char *sqlite3_win32_mbcs_to_utf8_via_ansi(const char *zText){ + char *zTextUtf8; + LPWSTR zTmpWide; + + zTmpWide = winMbcsToUnicode(zText, 1); + if( zTmpWide==0 ){ + return 0; + } + zTextUtf8 = winUnicodeToUtf8(zTmpWide); + sqlite3_free(zTmpWide); + return zTextUtf8; +} + +/* +** Convert multibyte character string to UTF-8 using the OEM codepage. +** Space to hold the returned string is obtained from sqlite3_malloc(). +*/ +char *sqlite3_win32_mbcs_to_utf8_via_oem(const char *zText){ + char *zTextUtf8; + LPWSTR zTmpWide; + + zTmpWide = winMbcsToUnicode(zText, 0); + if( zTmpWide==0 ){ + return 0; + } + zTextUtf8 = winUnicodeToUtf8(zTmpWide); + sqlite3_free(zTmpWide); + return zTextUtf8; } /* ** Convert UTF-8 to multibyte character string. Space to hold the ** returned string is obtained from sqlite3_malloc(). */ -char *sqlite3_win32_utf8_to_mbcs(const char *zFilename){ - char *zFilenameMbcs; +char *sqlite3_win32_utf8_to_mbcs(const char *zText){ + char *zTextMbcs; LPWSTR zTmpWide; - zTmpWide = winUtf8ToUnicode(zFilename); + zTmpWide = winUtf8ToUnicode(zText); if( zTmpWide==0 ){ return 0; } - zFilenameMbcs = winUnicodeToMbcs(zTmpWide); + zTextMbcs = winUnicodeToMbcs(zTmpWide, osAreFileApisANSI()); sqlite3_free(zTmpWide); - return zFilenameMbcs; + return zTextMbcs; +} + +/* +** Convert UTF-8 to multibyte character string using the ANSI codepage. +** Space to hold the returned string is obtained from sqlite3_malloc(). +*/ +char *sqlite3_win32_utf8_to_mbcs_via_ansi(const char *zText){ + char *zTextMbcs; + LPWSTR zTmpWide; + + zTmpWide = winUtf8ToUnicode(zText); + if( zTmpWide==0 ){ + return 0; + } + zTextMbcs = winUnicodeToMbcs(zTmpWide, 1); + sqlite3_free(zTmpWide); + return zTextMbcs; +} + +/* +** Convert UTF-8 to multibyte character string using the OEM codepage. +** Space to hold the returned string is obtained from sqlite3_malloc(). +*/ +char *sqlite3_win32_utf8_to_mbcs_via_oem(const char *zText){ + char *zTextMbcs; + LPWSTR zTmpWide; + + zTmpWide = winUtf8ToUnicode(zText); + if( zTmpWide==0 ){ + return 0; + } + zTextMbcs = winUnicodeToMbcs(zTmpWide, 0); + sqlite3_free(zTmpWide); + return zTextMbcs; } /* From 12931203457ed2162284173cf048d79895ab8d43 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Mon, 4 Apr 2016 02:05:46 +0000 Subject: [PATCH 0237/1484] More refactoring and cleanup work on the Win32 string conversion and utility routines. FossilOrigin-Name: 02ccb444a3d0b9a52ffd04cae9d9b6f654128c35 --- manifest | 12 +-- manifest.uuid | 2 +- src/os_win.c | 235 +++++++++++++++++++++++++++++--------------------- 3 files changed, 142 insertions(+), 107 deletions(-) diff --git a/manifest b/manifest index 0687355cf6..1ff9f109e9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Revise\sand\senhance\sthe\sWin32\sstring\sconversion\sroutines. -D 2016-04-03T22:44:16.657 +C More\srefactoring\sand\scleanup\swork\son\sthe\sWin32\sstring\sconversion\sand\sutility\sroutines. +D 2016-04-04T02:05:46.170 F Makefile.in e812bb732d7af01baa09f1278bd4f4a2e3a09449 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc fe57d7e3e74fa383fd01ced796c0ffd966fc094a @@ -358,7 +358,7 @@ F src/os.h 91ff889115ecd01f436d3611f7f5ea4dc12d92f1 F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85 F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa F src/os_unix.c b1ccb273771f41dbdbe0ba7c1ad63c38ad5972ec -F src/os_win.c 01ae58949a28edaecd5645abbe29ac9d2ee983fd +F src/os_win.c b3ba9573d8d893e70a6a8015bbee572ecf7ffbef F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c 38718a019ca762ba4f6795425d5a54db70d1790d F src/pager.h e1d38a2f14849e219df0f91f8323504d134c8a56 @@ -1480,7 +1480,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P f76c3a0ca40989fe9401c3b6f662f8e6ef2a730c -R 9a8e623b20453c0fbff989d22019add7 +P 345860c92195544aad44ea9b0d14c9ebbd50adf2 +R 8daf8efac2ee8825007360be7ce04871 U mistachkin -Z 149573e0b667520348654eca6c5f3228 +Z a69ce6a98d15b1e2f1ce825b8343a90e diff --git a/manifest.uuid b/manifest.uuid index 280e3ae958..d7da1c1daf 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -345860c92195544aad44ea9b0d14c9ebbd50adf2 \ No newline at end of file +02ccb444a3d0b9a52ffd04cae9d9b6f654128c35 \ No newline at end of file diff --git a/src/os_win.c b/src/os_win.c index 9508c97a14..4aca70b6c9 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -1306,6 +1306,12 @@ void sqlite3_win32_write_debug(const char *zBuf, int nBuf){ int nMin = MIN(nBuf, (SQLITE_WIN32_DBG_BUF_SIZE - 1)); /* may be negative. */ if( nMin<-1 ) nMin = -1; /* all negative values become -1. */ assert( nMin==-1 || nMin==0 || nMin0 ){ memset(zDbgBuf, 0, SQLITE_WIN32_DBG_BUF_SIZE); @@ -1631,9 +1637,9 @@ void sqlite3MemSetDefault(void){ #endif /* SQLITE_WIN32_MALLOC */ /* -** Convert a UTF-8 string to Microsoft Unicode (UTF-16?). +** Convert a UTF-8 string to Microsoft Unicode. ** -** Space to hold the returned string is obtained from malloc. +** Space to hold the returned string is obtained from sqlite3_malloc(). */ static LPWSTR winUtf8ToUnicode(const char *zText){ int nChar; @@ -1657,8 +1663,9 @@ static LPWSTR winUtf8ToUnicode(const char *zText){ } /* -** Convert Microsoft Unicode to UTF-8. Space to hold the returned string is -** obtained from sqlite3_malloc(). +** Convert a Microsoft Unicode string to UTF-8. +** +** Space to hold the returned string is obtained from sqlite3_malloc(). */ static char *winUnicodeToUtf8(LPCWSTR zWideText){ int nByte; @@ -1682,15 +1689,14 @@ static char *winUnicodeToUtf8(LPCWSTR zWideText){ } /* -** Convert an ANSI string to Microsoft Unicode, based on the -** current codepage settings for file apis. +** Convert an ANSI string to Microsoft Unicode, using the ANSI or OEM +** code page. ** -** Space to hold the returned string is obtained -** from sqlite3_malloc. +** Space to hold the returned string is obtained from sqlite3_malloc(). */ static LPWSTR winMbcsToUnicode(const char *zText, int useAnsi){ int nByte; - LPWSTR zMbcsFilename; + LPWSTR zMbcsText; int codepage = useAnsi ? CP_ACP : CP_OEMCP; nByte = osMultiByteToWideChar(codepage, 0, zText, -1, NULL, @@ -1698,25 +1704,24 @@ static LPWSTR winMbcsToUnicode(const char *zText, int useAnsi){ if( nByte==0 ){ return 0; } - zMbcsFilename = sqlite3MallocZero( nByte*sizeof(zMbcsFilename[0]) ); - if( zMbcsFilename==0 ){ + zMbcsText = sqlite3MallocZero( nByte*sizeof(WCHAR) ); + if( zMbcsText==0 ){ return 0; } - nByte = osMultiByteToWideChar(codepage, 0, zText, -1, zMbcsFilename, + nByte = osMultiByteToWideChar(codepage, 0, zText, -1, zMbcsText, nByte); if( nByte==0 ){ - sqlite3_free(zMbcsFilename); - zMbcsFilename = 0; + sqlite3_free(zMbcsText); + zMbcsText = 0; } - return zMbcsFilename; + return zMbcsText; } /* -** Convert Microsoft Unicode to multi-byte character string, based on the -** user's ANSI codepage. +** Convert a Microsoft Unicode string to a multi-byte character string, +** using the ANSI or OEM code page. ** -** Space to hold the returned string is obtained from -** sqlite3_malloc(). +** Space to hold the returned string is obtained from sqlite3_malloc(). */ static char *winUnicodeToMbcs(LPCWSTR zWideText, int useAnsi){ int nByte; @@ -1741,105 +1746,135 @@ static char *winUnicodeToMbcs(LPCWSTR zWideText, int useAnsi){ } /* -** Convert multibyte character string to UTF-8. Space to hold the -** returned string is obtained from sqlite3_malloc(). +** Convert a multi-byte character string to UTF-8. +** +** Space to hold the returned string is obtained from sqlite3_malloc(). +*/ +static char *winMbcsToUtf8(const char *zText, int useAnsi){ + char *zTextUtf8; + LPWSTR zTmpWide; + + zTmpWide = winMbcsToUnicode(zText, useAnsi); + if( zTmpWide==0 ){ + return 0; + } + zTextUtf8 = winUnicodeToUtf8(zTmpWide); + sqlite3_free(zTmpWide); + return zTextUtf8; +} + +/* +** Convert a UTF-8 string to a multi-byte character string. +** +** Space to hold the returned string is obtained from sqlite3_malloc(). +*/ +static char *winUtf8ToMbcs(const char *zText, int useAnsi){ + char *zTextMbcs; + LPWSTR zTmpWide; + + zTmpWide = winUtf8ToUnicode(zText); + if( zTmpWide==0 ){ + return 0; + } + zTextMbcs = winUnicodeToMbcs(zTmpWide, useAnsi); + sqlite3_free(zTmpWide); + return zTextMbcs; +} + +/* +** This is a public wrapper for the winUtf8ToUnicode() function. +*/ +LPWSTR sqlite3_win32_utf8_to_unicode(const char *zText){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !zText ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif +#ifndef SQLITE_OMIT_AUTOINIT + if( sqlite3_initialize() ) return 0; +#endif + return winUtf8ToUnicode(zText); +} + +/* +** This is a public wrapper for the winUnicodeToUtf8() function. +*/ +char *sqlite3_win32_unicode_to_utf8(LPCWSTR zWideText){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !zWideText ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif +#ifndef SQLITE_OMIT_AUTOINIT + if( sqlite3_initialize() ) return 0; +#endif + return winUnicodeToUtf8(zWideText); +} + +/* +** This is a public wrapper for the winMbcsToUtf8() function. */ char *sqlite3_win32_mbcs_to_utf8(const char *zText){ - char *zTextUtf8; - LPWSTR zTmpWide; - - zTmpWide = winMbcsToUnicode(zText, osAreFileApisANSI()); - if( zTmpWide==0 ){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !zText ){ + (void)SQLITE_MISUSE_BKPT; return 0; } - zTextUtf8 = winUnicodeToUtf8(zTmpWide); - sqlite3_free(zTmpWide); - return zTextUtf8; +#endif +#ifndef SQLITE_OMIT_AUTOINIT + if( sqlite3_initialize() ) return 0; +#endif + return winMbcsToUtf8(zText, osAreFileApisANSI()); } /* -** Convert multibyte character string to UTF-8 using the ANSI codepage. -** Space to hold the returned string is obtained from sqlite3_malloc(). +** This is a public wrapper for the winMbcsToUtf8() function. */ -char *sqlite3_win32_mbcs_to_utf8_via_ansi(const char *zText){ - char *zTextUtf8; - LPWSTR zTmpWide; - - zTmpWide = winMbcsToUnicode(zText, 1); - if( zTmpWide==0 ){ +char *sqlite3_win32_mbcs_to_utf8_v2(const char *zText, int useAnsi){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !zText ){ + (void)SQLITE_MISUSE_BKPT; return 0; } - zTextUtf8 = winUnicodeToUtf8(zTmpWide); - sqlite3_free(zTmpWide); - return zTextUtf8; +#endif +#ifndef SQLITE_OMIT_AUTOINIT + if( sqlite3_initialize() ) return 0; +#endif + return winMbcsToUtf8(zText, useAnsi); } /* -** Convert multibyte character string to UTF-8 using the OEM codepage. -** Space to hold the returned string is obtained from sqlite3_malloc(). -*/ -char *sqlite3_win32_mbcs_to_utf8_via_oem(const char *zText){ - char *zTextUtf8; - LPWSTR zTmpWide; - - zTmpWide = winMbcsToUnicode(zText, 0); - if( zTmpWide==0 ){ - return 0; - } - zTextUtf8 = winUnicodeToUtf8(zTmpWide); - sqlite3_free(zTmpWide); - return zTextUtf8; -} - -/* -** Convert UTF-8 to multibyte character string. Space to hold the -** returned string is obtained from sqlite3_malloc(). +** This is a public wrapper for the winUtf8ToMbcs() function. */ char *sqlite3_win32_utf8_to_mbcs(const char *zText){ - char *zTextMbcs; - LPWSTR zTmpWide; - - zTmpWide = winUtf8ToUnicode(zText); - if( zTmpWide==0 ){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !zText ){ + (void)SQLITE_MISUSE_BKPT; return 0; } - zTextMbcs = winUnicodeToMbcs(zTmpWide, osAreFileApisANSI()); - sqlite3_free(zTmpWide); - return zTextMbcs; +#endif +#ifndef SQLITE_OMIT_AUTOINIT + if( sqlite3_initialize() ) return 0; +#endif + return winUtf8ToMbcs(zText, osAreFileApisANSI()); } /* -** Convert UTF-8 to multibyte character string using the ANSI codepage. -** Space to hold the returned string is obtained from sqlite3_malloc(). +** This is a public wrapper for the winUtf8ToMbcs() function. */ -char *sqlite3_win32_utf8_to_mbcs_via_ansi(const char *zText){ - char *zTextMbcs; - LPWSTR zTmpWide; - - zTmpWide = winUtf8ToUnicode(zText); - if( zTmpWide==0 ){ +char *sqlite3_win32_utf8_to_mbcs_v2(const char *zText, int useAnsi){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !zText ){ + (void)SQLITE_MISUSE_BKPT; return 0; } - zTextMbcs = winUnicodeToMbcs(zTmpWide, 1); - sqlite3_free(zTmpWide); - return zTextMbcs; -} - -/* -** Convert UTF-8 to multibyte character string using the OEM codepage. -** Space to hold the returned string is obtained from sqlite3_malloc(). -*/ -char *sqlite3_win32_utf8_to_mbcs_via_oem(const char *zText){ - char *zTextMbcs; - LPWSTR zTmpWide; - - zTmpWide = winUtf8ToUnicode(zText); - if( zTmpWide==0 ){ - return 0; - } - zTextMbcs = winUnicodeToMbcs(zTmpWide, 0); - sqlite3_free(zTmpWide); - return zTextMbcs; +#endif +#ifndef SQLITE_OMIT_AUTOINIT + if( sqlite3_initialize() ) return 0; +#endif + return winUtf8ToMbcs(zText, useAnsi); } /* @@ -1941,7 +1976,7 @@ static int winGetLastErrorMsg(DWORD lastErrno, int nBuf, char *zBuf){ if( dwLen > 0 ){ /* allocate a buffer and convert to UTF8 */ sqlite3BeginBenignMalloc(); - zOut = sqlite3_win32_mbcs_to_utf8(zTemp); + zOut = winMbcsToUtf8(zTemp, osAreFileApisANSI()); sqlite3EndBenignMalloc(); /* free the system buffer allocated by FormatMessage */ osLocalFree(zTemp); @@ -4386,7 +4421,7 @@ static char *winConvertToUtf8Filename(const void *zFilename){ } #ifdef SQLITE_WIN32_HAS_ANSI else{ - zConverted = sqlite3_win32_mbcs_to_utf8(zFilename); + zConverted = winMbcsToUtf8(zFilename, osAreFileApisANSI()); } #endif /* caller will handle out of memory */ @@ -4407,7 +4442,7 @@ static void *winConvertFromUtf8Filename(const char *zFilename){ } #ifdef SQLITE_WIN32_HAS_ANSI else{ - zConverted = sqlite3_win32_utf8_to_mbcs(zFilename); + zConverted = winUtf8ToMbcs(zFilename, osAreFileApisANSI()); } #endif /* caller will handle out of memory */ @@ -4608,7 +4643,7 @@ static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){ return winLogError(SQLITE_IOERR_GETTEMPPATH, osGetLastError(), "winGetTempname3", 0); } - zUtf8 = sqlite3_win32_mbcs_to_utf8(zMbcsPath); + zUtf8 = winMbcsToUtf8(zMbcsPath, osAreFileApisANSI()); if( zUtf8 ){ sqlite3_snprintf(nMax, zBuf, "%s", zUtf8); sqlite3_free(zUtf8); @@ -5386,7 +5421,7 @@ static int winFullPathname( "winFullPathname4", zRelative); } sqlite3_free(zConverted); - zOut = sqlite3_win32_mbcs_to_utf8(zTemp); + zOut = winMbcsToUtf8(zTemp, osAreFileApisANSI()); sqlite3_free(zTemp); } #endif From 1fe36bb8a81b9b547eda6cbd96b143e952e61424 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Mon, 4 Apr 2016 02:16:44 +0000 Subject: [PATCH 0238/1484] Experimental changes to the command line shell to make it work better with Unicode on Windows. FossilOrigin-Name: 74183a5f803999e1d4e288851c72519c3c53f6b5 --- manifest | 14 +-- manifest.uuid | 2 +- src/shell.c | 268 +++++++++++++++++++++++++++-------------------- test/shell1.test | 47 ++++++--- 4 files changed, 194 insertions(+), 137 deletions(-) diff --git a/manifest b/manifest index 1ff9f109e9..8b566a8537 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C More\srefactoring\sand\scleanup\swork\son\sthe\sWin32\sstring\sconversion\sand\sutility\sroutines. -D 2016-04-04T02:05:46.170 +C Experimental\schanges\sto\sthe\scommand\sline\sshell\sto\smake\sit\swork\sbetter\swith\sUnicode\son\sWindows. +D 2016-04-04T02:16:44.372 F Makefile.in e812bb732d7af01baa09f1278bd4f4a2e3a09449 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc fe57d7e3e74fa383fd01ced796c0ffd966fc094a @@ -374,7 +374,7 @@ F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c b8f7174e5f8c33c44ded3a25a973d0bb89228c20 F src/rowset.c 9fe4b3ad7cc00944386bb600233d8f523de07a6e F src/select.c 7849cee0a01952a9c93cd28989daedfa57731143 -F src/shell.c e126f647f63da3d5d820f012359b89075cd7de99 +F src/shell.c cfe5edc196c7ab109b6ea728a69dc9346e03f4f7 F src/sqlite.h.in c46a7b85d3f37371cacea8f98ec825f5e52c420c F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 98f72cbfe00169c39089115427d06ea05fe4b4a2 @@ -1049,7 +1049,7 @@ F test/sharedA.test 0cdf1a76dfa00e6beee66af5b534b1e8df2720f5 F test/sharedB.test 16cc7178e20965d75278f410943109b77b2e645e F test/shared_err.test 2f2aee20db294b9924e81f6ccbe60f19e21e8506 F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304 -F test/shell1.test dff5b20ad989770aface6d714491121172dfe8b0 +F test/shell1.test 95b172b3854413a566e1e16da0a9aeae25966f4c F test/shell2.test e242a9912f44f4c23c3d1d802a83e934e84c853b F test/shell3.test da513d522ef6f01cee8475dcf8332bff8982b3dd F test/shell4.test 69995ee1cc278eb149aa8746ce1f935f4eaf98b9 @@ -1480,7 +1480,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 345860c92195544aad44ea9b0d14c9ebbd50adf2 -R 8daf8efac2ee8825007360be7ce04871 +P 02ccb444a3d0b9a52ffd04cae9d9b6f654128c35 +R 12b05bab5737c52c6e35683f2e505d88 U mistachkin -Z a69ce6a98d15b1e2f1ce825b8343a90e +Z 02f8d2df1ede1dbca37f29a3d0ba1aa0 diff --git a/manifest.uuid b/manifest.uuid index d7da1c1daf..828cd80a90 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -02ccb444a3d0b9a52ffd04cae9d9b6f654128c35 \ No newline at end of file +74183a5f803999e1d4e288851c72519c3c53f6b5 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 9cec288024..5ac2f4a480 100644 --- a/src/shell.c +++ b/src/shell.c @@ -90,7 +90,7 @@ #else -# define shell_read_history(X) +# define shell_read_history(X) # define shell_write_history(X) # define shell_stifle_history(X) @@ -136,6 +136,15 @@ #define IsDigit(X) isdigit((unsigned char)X) #define ToLower(X) (char)tolower((unsigned char)X) +#if defined(_WIN32) || defined(WIN32) +#include + +/* string conversion routines only needed on Win32 */ +extern char *sqlite3_win32_unicode_to_utf8(LPCWSTR); +extern char *sqlite3_win32_mbcs_to_utf8_v2(const char *, int); +extern char *sqlite3_win32_utf8_to_mbcs_v2(const char *, int); +#endif + /* On Windows, we normally run with output mode of TEXT so that \n characters ** are automatically translated into \r\n. However, this behavior needs ** to be disabled in some cases (ex: when generating CSV output and when @@ -143,17 +152,17 @@ ** routines take care of that. */ #if defined(_WIN32) || defined(WIN32) -static void setBinaryMode(FILE *out){ - fflush(out); - _setmode(_fileno(out), _O_BINARY); +static void setBinaryMode(FILE *file, int isOutput){ + if( isOutput ) fflush(file); + _setmode(_fileno(file), _O_BINARY); } -static void setTextMode(FILE *out){ - fflush(out); - _setmode(_fileno(out), _O_TEXT); +static void setTextMode(FILE *file, int isOutput){ + if( isOutput ) fflush(file); + _setmode(_fileno(file), _O_TEXT); } #else -# define setBinaryMode(X) -# define setTextMode(X) +# define setBinaryMode(X,Y) +# define setTextMode(X,Y) #endif @@ -204,7 +213,7 @@ static void beginTimer(void){ /* Return the difference of two time_structs in seconds */ static double timeDiff(struct timeval *pStart, struct timeval *pEnd){ - return (pEnd->tv_usec - pStart->tv_usec)*0.000001 + + return (pEnd->tv_usec - pStart->tv_usec)*0.000001 + (double)(pEnd->tv_sec - pStart->tv_sec); } @@ -229,8 +238,6 @@ static void endTimer(void){ #elif (defined(_WIN32) || defined(WIN32)) -#include - /* Saved resource information for the beginning of an operation */ static HANDLE hProcess; static FILETIME ftKernelBegin; @@ -261,7 +268,7 @@ static int hasTimer(void){ if( NULL != getProcessTimesAddr ){ return 1; } - FreeLibrary(hinstLib); + FreeLibrary(hinstLib); } } } @@ -307,7 +314,7 @@ static void endTimer(void){ #define HAS_TIMER hasTimer() #else -#define BEGIN_TIMER +#define BEGIN_TIMER #define END_TIMER #define HAS_TIMER 0 #endif @@ -371,9 +378,8 @@ void utf8_printf(FILE *out, const char *zFormat, ...){ va_list ap; va_start(ap, zFormat); if( stdout_is_console && (out==stdout || out==stderr) ){ - extern char *sqlite3_win32_utf8_to_mbcs(const char*); char *z1 = sqlite3_vmprintf(zFormat, ap); - char *z2 = sqlite3_win32_utf8_to_mbcs(z1); + char *z2 = sqlite3_win32_utf8_to_mbcs_v2(z1, 0); sqlite3_free(z1); fputs(z2, out); sqlite3_free(z2); @@ -449,8 +455,8 @@ static int isNumber(const char *z, int *realnum){ } /* -** A global char* and an SQL function to access its current value -** from within an SQL statement. This program used to use the +** A global char* and an SQL function to access its current value +** from within an SQL statement. This program used to use the ** sqlite_exec_printf() API to substitue a string into an SQL statement. ** The correct way to do this with sqlite3 is to use the bind API, but ** since the shell is built around the callback paradigm it would be a lot @@ -516,11 +522,10 @@ static char *local_getline(char *zLine, FILE *in){ } } #if defined(_WIN32) || defined(WIN32) - /* For interactive input on Windows systems, translate the + /* For interactive input on Windows systems, translate the ** multi-byte characterset characters into UTF-8. */ if( stdin_is_interactive ){ - extern char *sqlite3_win32_mbcs_to_utf8(const char*); - char *zTrans = sqlite3_win32_mbcs_to_utf8(zLine); + char *zTrans = sqlite3_win32_mbcs_to_utf8_v2(zLine, 0); if( zTrans ){ int nTrans = strlen30(zTrans)+1; if( nTrans>nLine ){ @@ -586,7 +591,7 @@ struct OpenSession { #endif /* -** Shell output mode information from before ".explain on", +** Shell output mode information from before ".explain on", ** saved so that it can be restored by ".explain off" */ typedef struct SavedModeInfo SavedModeInfo; @@ -723,7 +728,7 @@ static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){ static void output_quoted_string(FILE *out, const char *z){ int i; int nSingle = 0; - setBinaryMode(out); + setBinaryMode(out, 1); for(i=0; z[i]; i++){ if( z[i]=='\'' ) nSingle++; } @@ -746,7 +751,7 @@ static void output_quoted_string(FILE *out, const char *z){ } raw_printf(out,"'"); } - setTextMode(out); + setTextMode(out, 1); } /* @@ -788,11 +793,11 @@ static void output_html_string(FILE *out, const char *z){ int i; if( z==0 ) z = ""; while( *z ){ - for(i=0; z[i] - && z[i]!='<' - && z[i]!='&' - && z[i]!='>' - && z[i]!='\"' + for(i=0; z[i] + && z[i]!='<' + && z[i]!='&' + && z[i]!='>' + && z[i]!='\"' && z[i]!='\''; i++){} if( i>0 ){ @@ -820,22 +825,22 @@ static void output_html_string(FILE *out, const char *z){ ** array, then the string must be quoted for CSV. */ static const char needCsvQuote[] = { - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, }; /* @@ -852,8 +857,8 @@ static void output_csv(ShellState *p, const char *z, int bSep){ int i; int nSep = strlen30(p->colSeparator); for(i=0; z[i]; i++){ - if( needCsvQuote[((unsigned char*)z)[i]] - || (z[i]==p->colSeparator[0] && + if( needCsvQuote[((unsigned char*)z)[i]] + || (z[i]==p->colSeparator[0] && (nSep==1 || memcmp(z, p->colSeparator, nSep)==0)) ){ i = 0; break; @@ -1063,7 +1068,7 @@ static int shell_callback( break; } case MODE_Csv: { - setBinaryMode(p->out); + setBinaryMode(p->out, 1); if( p->cnt++==0 && p->showHeader ){ for(i=0; iout, "%s", p->rowSeparator); } - setTextMode(p->out); + setTextMode(p->out, 1); break; } case MODE_Insert: { @@ -1189,7 +1194,7 @@ static void set_table_name(ShellState *p, const char *zName){ ** added to zIn, and the result returned in memory obtained from malloc(). ** zIn, if it was not NULL, is freed. ** -** If the third argument, quote, is not '\0', then it is used as a +** If the third argument, quote, is not '\0', then it is used as a ** quote character for zAppend. */ static char *appendText(char *zIn, char const *zAppend, char quote){ @@ -1236,7 +1241,7 @@ static char *appendText(char *zIn, char const *zAppend, char quote){ ** semicolon terminator to the end of that line. ** ** If the number of columns is 1 and that column contains text "--" -** then write the semicolon on a separate line. That way, if a +** then write the semicolon on a separate line. That way, if a ** "--" comment occurs at the end of the statement, the comment ** won't consume the semicolon terminator. */ @@ -1266,7 +1271,7 @@ static int run_table_dump_query( } z = (const char*)sqlite3_column_text(pSelect, 0); utf8_printf(p->out, "%s", z); - for(i=1; iout, ",%s", sqlite3_column_text(pSelect, i)); } if( z==0 ) z = ""; @@ -1275,7 +1280,7 @@ static int run_table_dump_query( raw_printf(p->out, "\n;\n"); }else{ raw_printf(p->out, ";\n"); - } + } rc = sqlite3_step(pSelect); } rc = sqlite3_finalize(pSelect); @@ -1334,7 +1339,7 @@ static void displayLinuxIoStats(FILE *out){ } } fclose(in); -} +} #endif @@ -1350,7 +1355,7 @@ static int display_stats( int iHiwtr; if( pArg && pArg->out ){ - + iHiwtr = iCur = -1; sqlite3_status(SQLITE_STATUS_MEMORY_USED, &iCur, &iHiwtr, bReset); raw_printf(pArg->out, @@ -1434,18 +1439,18 @@ static int display_stats( raw_printf(pArg->out, "Page cache hits: %d\n", iCur); iHiwtr = iCur = -1; sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1); - raw_printf(pArg->out, "Page cache misses: %d\n", iCur); + raw_printf(pArg->out, "Page cache misses: %d\n", iCur); iHiwtr = iCur = -1; sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, 1); - raw_printf(pArg->out, "Page cache writes: %d\n", iCur); + raw_printf(pArg->out, "Page cache writes: %d\n", iCur); iHiwtr = iCur = -1; sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset); raw_printf(pArg->out, "Schema Heap Usage: %d bytes\n", - iCur); + iCur); iHiwtr = iCur = -1; sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset); raw_printf(pArg->out, "Statement Heap/Lookaside Usage: %d bytes\n", - iCur); + iCur); } if( pArg && pArg->out && db && pArg->pStmt ){ @@ -1507,7 +1512,7 @@ static void display_scanstats( sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EXPLAIN, (void*)&zExplain); utf8_printf(pArg->out, "Loop %2d: %s\n", n, zExplain); rEstLoop *= rEst; - raw_printf(pArg->out, + raw_printf(pArg->out, " nLoop=%-8lld nRow=%-8lld estRow=%-8lld estRow/Loop=%-8g\n", nLoop, nVisit, (sqlite3_int64)(rEstLoop+0.5), rEst ); @@ -1534,7 +1539,7 @@ static int str_in_array(const char *zStr, const char **azArray){ /* ** If compiled statement pSql appears to be an EXPLAIN statement, allocate ** and populate the ShellState.aiIndent[] array with the number of -** spaces each opcode should be indented before it is output. +** spaces each opcode should be indented before it is output. ** ** The indenting rules are: ** @@ -1639,12 +1644,12 @@ static void explain_data_delete(ShellState *p){ } /* -** Execute a statement or set of statements. Print -** any result rows/columns depending on the current mode +** Execute a statement or set of statements. Print +** any result rows/columns depending on the current mode ** set via the supplied callback. ** -** This is very similar to SQLite's built-in sqlite3_exec() -** function except it takes a slightly different callback +** This is very similar to SQLite's built-in sqlite3_exec() +** function except it takes a slightly different callback ** and callback data argument. */ static int shell_exec( @@ -1716,7 +1721,7 @@ static int shell_exec( ){ pArg->cMode = MODE_Explain; } - + /* If the shell is currently in ".explain" mode, gather the extra ** data required to add indents to the output.*/ if( pArg->cMode==MODE_Explain ){ @@ -1742,7 +1747,7 @@ static int shell_exec( char **azVals = &azCols[nCol]; /* Results */ int *aiTypes = (int *)&azVals[nCol]; /* Result types */ int i, x; - assert(sizeof(int) <= sizeof(char *)); + assert(sizeof(int) <= sizeof(char *)); /* save off ptrs to column names */ for(i=0; idb==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){ - utf8_printf(stderr,"Error: unable to open database \"%s\": %s\n", + utf8_printf(stderr,"Error: unable to open database \"%s\": %s\n", p->zDbFilename, sqlite3_errmsg(p->db)); if( keepAlive ) return; exit(1); @@ -2345,7 +2350,7 @@ static void output_file_close(FILE *f){ /* ** Try to open an output file. The names "stdout" and "stderr" are -** recognized and do the right thing. NULL is returned if the output +** recognized and do the right thing. NULL is returned if the output ** filename is "off". */ static FILE *output_file_open(const char *zFile){ @@ -2534,7 +2539,7 @@ static void tryToCloneData( sqlite3 *newDb, const char *zTable ){ - sqlite3_stmt *pQuery = 0; + sqlite3_stmt *pQuery = 0; sqlite3_stmt *pInsert = 0; char *zQuery = 0; char *zInsert = 0; @@ -2838,9 +2843,9 @@ static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){ utf8_printf(p->out, "%-20s %u", aField[i].zName, val); switch( ofst ){ case 56: { - if( val==1 ) raw_printf(p->out, " (utf8)"); - if( val==2 ) raw_printf(p->out, " (utf16le)"); - if( val==3 ) raw_printf(p->out, " (utf16be)"); + if( val==1 ) raw_printf(p->out, " (utf8)"); + if( val==2 ) raw_printf(p->out, " (utf16le)"); + if( val==3 ) raw_printf(p->out, " (utf16be)"); } } raw_printf(p->out, "\n"); @@ -2900,9 +2905,9 @@ static int do_meta_command(char *zLine, ShellState *p){ if( zLine[h]=='\'' || zLine[h]=='"' ){ int delim = zLine[h++]; azArg[nArg++] = &zLine[h]; - while( zLine[h] && zLine[h]!=delim ){ + while( zLine[h] && zLine[h]!=delim ){ if( zLine[h]=='\\' && delim=='"' && zLine[h+1]!=0 ) h++; - h++; + h++; } if( zLine[h]==delim ){ zLine[h++] = 0; @@ -2989,9 +2994,9 @@ static int do_meta_command(char *zLine, ShellState *p){ if( c=='b' && n>=3 && strncmp(azArg[0], "binary", n)==0 ){ if( nArg==2 ){ if( booleanValue(azArg[1]) ){ - setBinaryMode(p->out); + setBinaryMode(p->out, 1); }else{ - setTextMode(p->out); + setTextMode(p->out, 1); } }else{ raw_printf(stderr, "Usage: .binary on|off\n"); @@ -3063,11 +3068,11 @@ static int do_meta_command(char *zLine, ShellState *p){ sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0); p->nErr = 0; if( nArg==1 ){ - run_schema_dump_query(p, + run_schema_dump_query(p, "SELECT name, type, sql FROM sqlite_master " "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'" ); - run_schema_dump_query(p, + run_schema_dump_query(p, "SELECT name, type, sql FROM sqlite_master " "WHERE name=='sqlite_sequence'" ); @@ -3116,7 +3121,7 @@ static int do_meta_command(char *zLine, ShellState *p){ }else{ raw_printf(stderr, "Usage: .eqp on|off\n"); rc = 1; - } + } }else if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){ @@ -3498,7 +3503,7 @@ static int do_meta_command(char *zLine, ShellState *p){ open_db(p, 0); if( nArg==1 ){ for(i=0; idb, aLimit[i].limitCode, -1)); } }else if( nArg>3 ){ @@ -3935,7 +3940,7 @@ static int do_meta_command(char *zLine, ShellState *p){ printf("Error: error code %d\n", rc); rc = 0; } - if( pChng + if( pChng && fwrite(pChng, szChng, 1, out)!=1 ){ raw_printf(stderr, "ERROR: Failed to write entire %d-byte output\n", szChng); @@ -3988,7 +3993,7 @@ static int do_meta_command(char *zLine, ShellState *p){ exit(1); } for(ii=1; iiazFilter[ii-1] = sqlite3_mprintf("%s", azCmd[ii]); + pSession->azFilter[ii-1] = sqlite3_mprintf("%s", azCmd[ii]); } pSession->nFilter = ii-1; } @@ -4321,9 +4326,9 @@ static int do_meta_command(char *zLine, ShellState *p){ /* sqlite3_test_control(int, db, int) */ case SQLITE_TESTCTRL_OPTIMIZATIONS: - case SQLITE_TESTCTRL_RESERVE: + case SQLITE_TESTCTRL_RESERVE: if( nArg==3 ){ - int opt = (int)strtol(azArg[2], 0, 0); + int opt = (int)strtol(azArg[2], 0, 0); rc2 = sqlite3_test_control(testctrl, p->db, opt); raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2); } else { @@ -4347,7 +4352,7 @@ static int do_meta_command(char *zLine, ShellState *p){ break; /* sqlite3_test_control(int, uint) */ - case SQLITE_TESTCTRL_PENDING_BYTE: + case SQLITE_TESTCTRL_PENDING_BYTE: if( nArg==3 ){ unsigned int opt = (unsigned int)integerValue(azArg[2]); rc2 = sqlite3_test_control(testctrl, opt); @@ -4357,13 +4362,13 @@ static int do_meta_command(char *zLine, ShellState *p){ " int option\n", azArg[1]); } break; - + /* sqlite3_test_control(int, int) */ - case SQLITE_TESTCTRL_ASSERT: - case SQLITE_TESTCTRL_ALWAYS: - case SQLITE_TESTCTRL_NEVER_CORRUPT: + case SQLITE_TESTCTRL_ASSERT: + case SQLITE_TESTCTRL_ALWAYS: + case SQLITE_TESTCTRL_NEVER_CORRUPT: if( nArg==3 ){ - int opt = booleanValue(azArg[2]); + int opt = booleanValue(azArg[2]); rc2 = sqlite3_test_control(testctrl, opt); raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2); } else { @@ -4374,9 +4379,9 @@ static int do_meta_command(char *zLine, ShellState *p){ /* sqlite3_test_control(int, char *) */ #ifdef SQLITE_N_KEYWORD - case SQLITE_TESTCTRL_ISKEYWORD: + case SQLITE_TESTCTRL_ISKEYWORD: if( nArg==3 ){ - const char *opt = azArg[2]; + const char *opt = azArg[2]; rc2 = sqlite3_test_control(testctrl, opt); raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2); } else { @@ -4389,7 +4394,7 @@ static int do_meta_command(char *zLine, ShellState *p){ case SQLITE_TESTCTRL_IMPOSTER: if( nArg==5 ){ - rc2 = sqlite3_test_control(testctrl, p->db, + rc2 = sqlite3_test_control(testctrl, p->db, azArg[2], integerValue(azArg[3]), integerValue(azArg[4])); @@ -4399,10 +4404,10 @@ static int do_meta_command(char *zLine, ShellState *p){ } break; - case SQLITE_TESTCTRL_BITVEC_TEST: - case SQLITE_TESTCTRL_FAULT_INSTALL: - case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS: - case SQLITE_TESTCTRL_SCRATCHMALLOC: + case SQLITE_TESTCTRL_BITVEC_TEST: + case SQLITE_TESTCTRL_FAULT_INSTALL: + case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS: + case SQLITE_TESTCTRL_SCRATCHMALLOC: default: utf8_printf(stderr, "Error: CLI support for testctrl %s not implemented\n", @@ -4416,7 +4421,7 @@ static int do_meta_command(char *zLine, ShellState *p){ open_db(p, 0); sqlite3_busy_timeout(p->db, nArg>=2 ? (int)integerValue(azArg[1]) : 0); }else - + if( c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 ){ if( nArg==2 ){ enableTimer = booleanValue(azArg[1]); @@ -4429,7 +4434,7 @@ static int do_meta_command(char *zLine, ShellState *p){ rc = 1; } }else - + if( c=='t' && strncmp(azArg[0], "trace", n)==0 ){ open_db(p, 0); if( nArg!=2 ){ @@ -4509,7 +4514,7 @@ static int do_meta_command(char *zLine, ShellState *p){ raw_printf(stderr, "Usage: .user login|add|edit|delete ...\n"); rc = 1; goto meta_command_exit; - } + } }else #endif /* SQLITE_USER_AUTHENTICATION */ @@ -4741,7 +4746,7 @@ static int process_input(ShellState *p, FILE *in){ if( rc || zErrMsg ){ char zPrefix[100]; if( in!=0 || !stdin_is_interactive ){ - sqlite3_snprintf(sizeof(zPrefix), zPrefix, + sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error: near line %d:", startline); }else{ sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:"); @@ -4883,7 +4888,7 @@ static void process_sqliterc( /* ** Show available command line options */ -static const char zOptions[] = +static const char zOptions[] = " -ascii set output mode to 'ascii'\n" " -bail stop after hitting an error\n" " -batch force batch I/O\n" @@ -4920,7 +4925,7 @@ static const char zOptions[] = ; static void usage(int showDetail){ utf8_printf(stderr, - "Usage: %s [OPTIONS] FILENAME [SQL]\n" + "Usage: %s [OPTIONS] FILENAME [SQL]\n" "FILENAME is the name of an SQLite database. A new database is created\n" "if the file does not previously exist.\n", Argv0); if( showDetail ){ @@ -4982,7 +4987,20 @@ static char *cmdline_option_value(int argc, char **argv, int i){ return argv[i]; } +#ifndef SQLITE_SHELL_IS_UTF8 +# if (defined(_WIN32) || defined(WIN32)) && defined(_MSC_VER) +# define SQLITE_SHELL_IS_UTF8 (0) +# else +# define SQLITE_SHELL_IS_UTF8 (1) +# endif +#endif + +#if SQLITE_SHELL_IS_UTF8 int SQLITE_CDECL main(int argc, char **argv){ +#else +int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ + char **argv = 0; +#endif char *zErrMsg = 0; ShellState data; const char *zInitFile = 0; @@ -4993,6 +5011,9 @@ int SQLITE_CDECL main(int argc, char **argv){ int nCmd = 0; char **azCmd = 0; + setBinaryMode(stdin, 0); + setvbuf(stderr, 0, _IONBF, 0); /* Make sure stderr is unbuffered */ + #if USE_SYSTEM_SQLITE+0!=1 if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){ utf8_printf(stderr, "SQLite header and source version mismatch\n%s\n%s\n", @@ -5000,10 +5021,23 @@ int SQLITE_CDECL main(int argc, char **argv){ exit(1); } #endif - setBinaryMode(stdin); - setvbuf(stderr, 0, _IONBF, 0); /* Make sure stderr is unbuffered */ - Argv0 = argv[0]; main_init(&data); +#if !SQLITE_SHELL_IS_UTF8 + sqlite3_initialize(); + argv = sqlite3_malloc64(sizeof(argv[0])*argc); + if( argv==0 ){ + raw_printf(stderr, "out of memory\n"); + exit(1); + } + for(i=0; i Date: Mon, 4 Apr 2016 02:33:34 +0000 Subject: [PATCH 0239/1484] Refinements to the previous check-in. FossilOrigin-Name: b36dfdff787dc4a107b2c3fcbb98bfc4922872d8 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/shell.c | 7 ++++--- test/shell1.test | 4 ++-- 4 files changed, 14 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 8b566a8537..050c3442d2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Experimental\schanges\sto\sthe\scommand\sline\sshell\sto\smake\sit\swork\sbetter\swith\sUnicode\son\sWindows. -D 2016-04-04T02:16:44.372 +C Refinements\sto\sthe\sprevious\scheck-in. +D 2016-04-04T02:33:34.200 F Makefile.in e812bb732d7af01baa09f1278bd4f4a2e3a09449 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc fe57d7e3e74fa383fd01ced796c0ffd966fc094a @@ -374,7 +374,7 @@ F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c b8f7174e5f8c33c44ded3a25a973d0bb89228c20 F src/rowset.c 9fe4b3ad7cc00944386bb600233d8f523de07a6e F src/select.c 7849cee0a01952a9c93cd28989daedfa57731143 -F src/shell.c cfe5edc196c7ab109b6ea728a69dc9346e03f4f7 +F src/shell.c ba8974732ad24dc8bffc9d9dae8a729edaf45b0d F src/sqlite.h.in c46a7b85d3f37371cacea8f98ec825f5e52c420c F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 98f72cbfe00169c39089115427d06ea05fe4b4a2 @@ -1049,7 +1049,7 @@ F test/sharedA.test 0cdf1a76dfa00e6beee66af5b534b1e8df2720f5 F test/sharedB.test 16cc7178e20965d75278f410943109b77b2e645e F test/shared_err.test 2f2aee20db294b9924e81f6ccbe60f19e21e8506 F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304 -F test/shell1.test 95b172b3854413a566e1e16da0a9aeae25966f4c +F test/shell1.test b110f092f64193c7235abd07bab79f1a59f494b1 F test/shell2.test e242a9912f44f4c23c3d1d802a83e934e84c853b F test/shell3.test da513d522ef6f01cee8475dcf8332bff8982b3dd F test/shell4.test 69995ee1cc278eb149aa8746ce1f935f4eaf98b9 @@ -1480,7 +1480,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 02ccb444a3d0b9a52ffd04cae9d9b6f654128c35 -R 12b05bab5737c52c6e35683f2e505d88 +P 74183a5f803999e1d4e288851c72519c3c53f6b5 +R dc99ab499cebc95aed1812a7f9308be8 U mistachkin -Z 02f8d2df1ede1dbca37f29a3d0ba1aa0 +Z 71f87a99a345de92d46f0c5169631d32 diff --git a/manifest.uuid b/manifest.uuid index 828cd80a90..08c1c3a431 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -74183a5f803999e1d4e288851c72519c3c53f6b5 \ No newline at end of file +b36dfdff787dc4a107b2c3fcbb98bfc4922872d8 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 5ac2f4a480..c0827fa267 100644 --- a/src/shell.c +++ b/src/shell.c @@ -4999,7 +4999,7 @@ static char *cmdline_option_value(int argc, char **argv, int i){ int SQLITE_CDECL main(int argc, char **argv){ #else int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ - char **argv = 0; + char **argv; #endif char *zErrMsg = 0; ShellState data; @@ -5013,6 +5013,8 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ setBinaryMode(stdin, 0); setvbuf(stderr, 0, _IONBF, 0); /* Make sure stderr is unbuffered */ + stdin_is_interactive = isatty(0); + stdout_is_console = isatty(1); #if USE_SYSTEM_SQLITE+0!=1 if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){ @@ -5037,9 +5039,8 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ } } #endif + assert( argc>=1 && argv && argv[0] ); Argv0 = argv[0]; - stdin_is_interactive = isatty(0); - stdout_is_console = isatty(1); /* Make sure we have a valid signal handler early, before anything ** else is done. diff --git a/test/shell1.test b/test/shell1.test index 9ff988604e..476af064a5 100644 --- a/test/shell1.test +++ b/test/shell1.test @@ -911,7 +911,7 @@ do_test shell1-5.0 { } {} do_test shell1-6.0 { - # The file name here is the word "test" in Chinese. + # The base file name here is the word "test" in Chinese. # In UTF-8, it is encoded as: \xE6\xB5\x8B\xE8\xAF\x95 set fileName \u6D4B\u8BD5; append fileName .db set x [catchcmdex $fileName "CREATE TABLE t1(x);\n.schema\n"] @@ -924,7 +924,7 @@ do_test shell1-6.0 { error "failed with mismatch: $res" } if {![file exists $fileName]} { - error "file \"$fileName\" (MBCS) does not exist" + error "file \"$fileName\" (Unicode) does not exist" } forcedelete $fileName } {} From 51b55a3ee6673631f15f752fb038737ccef34b5f Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 4 Apr 2016 12:38:05 +0000 Subject: [PATCH 0240/1484] Fix harmless compiler warnings. FossilOrigin-Name: 0213d6af84965676626c2fb4d78b4c74675207cc --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/analyze.c | 2 +- src/shell.c | 8 +++++--- 4 files changed, 14 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index d573902ae9..16451fe15f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Preupdate\shook\sdocumentation\sfixes.\s\sNo\schanges\sto\scode. -D 2016-04-01T17:54:07.826 +C Fix\sharmless\scompiler\swarnings. +D 2016-04-04T12:38:05.153 F Makefile.in e812bb732d7af01baa09f1278bd4f4a2e3a09449 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc fe57d7e3e74fa383fd01ced796c0ffd966fc094a @@ -311,7 +311,7 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F src/alter.c 1bb0709b3048e24217b80ec6bd78a3e99a47c01b -F src/analyze.c 39b21e4d9ad8a647e9834aa5ba99a74fb6c98879 +F src/analyze.c 37fedc80ac966ce1745811746e68e4d8fa64c7fe F src/attach.c 771153bd1f4ab0b97a44a13dde2c7e5e1efeba22 F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240 F src/backup.c f60f0aa55d25d853ffde53d0b0370a7bb7ee41ce @@ -374,7 +374,7 @@ F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c b8f7174e5f8c33c44ded3a25a973d0bb89228c20 F src/rowset.c 9fe4b3ad7cc00944386bb600233d8f523de07a6e F src/select.c 7849cee0a01952a9c93cd28989daedfa57731143 -F src/shell.c cd3f82fdc5c895b817a375b7ab8319cb41f447ce +F src/shell.c faa783401b0c25e52e4054a7292a78ab2f76d210 F src/sqlite.h.in c46a7b85d3f37371cacea8f98ec825f5e52c420c F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 98f72cbfe00169c39089115427d06ea05fe4b4a2 @@ -1480,7 +1480,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a62340dc0507e36f6dec05b1fda68d8399ec62ec -R 17cbd88111da841c5ced2fa2ee956e9f +P 59814f35d13db1f6379b9ae218b5432bc03c6197 +R 5dc90b5728244567537e2c75af0c4605 U drh -Z dfefbe59c009b860b7f7e89f1f29dda4 +Z 8cacf12e28835de4a8d101570828c9f0 diff --git a/manifest.uuid b/manifest.uuid index c694118307..61153ada1f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -59814f35d13db1f6379b9ae218b5432bc03c6197 \ No newline at end of file +0213d6af84965676626c2fb4d78b4c74675207cc \ No newline at end of file diff --git a/src/analyze.c b/src/analyze.c index 423ef0d714..3a81c93245 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -1826,7 +1826,7 @@ int sqlite3AnalysisLoad(sqlite3 *db, int iDb){ analysisInfo sInfo; HashElem *i; char *zSql; - int rc; + int rc = SQLITE_OK; assert( iDb>=0 && iDbnDb ); assert( db->aDb[iDb].pBt!=0 ); diff --git a/src/shell.c b/src/shell.c index 2ce2f292dc..58a0d7aa51 100644 --- a/src/shell.c +++ b/src/shell.c @@ -2140,17 +2140,19 @@ static void session_close(OpenSession *pSession){ #endif /* -** Close all OpenSession objects and release all assocaited resources. +** Close all OpenSession objects and release all associated resources. */ -static void session_close_all(ShellState *p){ #if defined(SQLITE_ENABLE_SESSION) +static void session_close_all(ShellState *p){ int i; for(i=0; inSession; i++){ session_close(&p->aSession[i]); } p->nSession = 0; -#endif } +#else +# define session_close_all(X) +#endif /* ** Implementation of the xFilter function for an open session. Omit From 5fd0c12049e0f69581f3bb5cbc98302a8d5db4ca Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 4 Apr 2016 13:46:24 +0000 Subject: [PATCH 0241/1484] Minor performance optimization in the comparison opcodes of the VDBE. FossilOrigin-Name: e375fe52cea7903c11ecef71c3452c67a96b663e --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 12 +++++++----- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 16451fe15f..deae1a11e9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\scompiler\swarnings. -D 2016-04-04T12:38:05.153 +C Minor\sperformance\soptimization\sin\sthe\scomparison\sopcodes\sof\sthe\sVDBE. +D 2016-04-04T13:46:24.704 F Makefile.in e812bb732d7af01baa09f1278bd4f4a2e3a09449 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc fe57d7e3e74fa383fd01ced796c0ffd966fc094a @@ -439,7 +439,7 @@ F src/update.c 3e67ab3c0814635f355fb1f8ab010a2b9e016e7d F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 8873d696c9ccc4206058c402e09e101f1b81561a F src/vacuum.c feb1eabb20987983d9350cad98299b21fa811f52 -F src/vdbe.c 0f0e4a6255f9a5272857a818314d081db26bcd90 +F src/vdbe.c 936166d3dc5aa00364877603f545707896c1519e F src/vdbe.h c16ba943d407baa1c7085eefea73a063fc631863 F src/vdbeInt.h ddb157974436d87652de7dc641f7191496d9a8cd F src/vdbeapi.c ba85b78fe08dc4a9ce747e62c89a2b4a4547e74c @@ -1480,7 +1480,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 59814f35d13db1f6379b9ae218b5432bc03c6197 -R 5dc90b5728244567537e2c75af0c4605 +P 0213d6af84965676626c2fb4d78b4c74675207cc +R 20833b687cd0398f4e539411826fc13a U drh -Z 8cacf12e28835de4a8d101570828c9f0 +Z 68baca12d82e219ae03586c49d91929a diff --git a/manifest.uuid b/manifest.uuid index 61153ada1f..b3dbcfbd15 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0213d6af84965676626c2fb4d78b4c74675207cc \ No newline at end of file +e375fe52cea7903c11ecef71c3452c67a96b663e \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 84a5087e01..f5b00d824a 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2016,11 +2016,13 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ /* Neither operand is NULL. Do a comparison. */ affinity = pOp->p5 & SQLITE_AFF_MASK; if( affinity>=SQLITE_AFF_NUMERIC ){ - if( (flags1 & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){ - applyNumericAffinity(pIn1,0); - } - if( (flags3 & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){ - applyNumericAffinity(pIn3,0); + if( (flags1 | flags3)&MEM_Str ){ + if( (flags1 & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){ + applyNumericAffinity(pIn1,0); + } + if( (flags3 & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){ + applyNumericAffinity(pIn3,0); + } } }else if( affinity==SQLITE_AFF_TEXT ){ if( (flags1 & MEM_Str)==0 && (flags1 & (MEM_Int|MEM_Real))!=0 ){ From 49e1125b69c36bfeee34424792ad7ffe0a8ed060 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Mon, 4 Apr 2016 15:47:46 +0000 Subject: [PATCH 0242/1484] Add and enhance the new tests. FossilOrigin-Name: f4cbd18db47af4af990d7891dcc831e92b3f17e0 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/shell1.test | 24 +++++++++++++++++++++--- 3 files changed, 28 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 050c3442d2..451d4e5fdc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Refinements\sto\sthe\sprevious\scheck-in. -D 2016-04-04T02:33:34.200 +C Add\sand\senhance\sthe\snew\stests. +D 2016-04-04T15:47:46.571 F Makefile.in e812bb732d7af01baa09f1278bd4f4a2e3a09449 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc fe57d7e3e74fa383fd01ced796c0ffd966fc094a @@ -1049,7 +1049,7 @@ F test/sharedA.test 0cdf1a76dfa00e6beee66af5b534b1e8df2720f5 F test/sharedB.test 16cc7178e20965d75278f410943109b77b2e645e F test/shared_err.test 2f2aee20db294b9924e81f6ccbe60f19e21e8506 F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304 -F test/shell1.test b110f092f64193c7235abd07bab79f1a59f494b1 +F test/shell1.test a216486c6aeae4d3e75e37d64e4b6c8974108750 F test/shell2.test e242a9912f44f4c23c3d1d802a83e934e84c853b F test/shell3.test da513d522ef6f01cee8475dcf8332bff8982b3dd F test/shell4.test 69995ee1cc278eb149aa8746ce1f935f4eaf98b9 @@ -1480,7 +1480,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 74183a5f803999e1d4e288851c72519c3c53f6b5 -R dc99ab499cebc95aed1812a7f9308be8 +P b36dfdff787dc4a107b2c3fcbb98bfc4922872d8 +R 37b07e38c129266922b712e67867cec6 U mistachkin -Z 71f87a99a345de92d46f0c5169631d32 +Z 3608507dbf100776dbeda9a8b2f0dd8b diff --git a/manifest.uuid b/manifest.uuid index 08c1c3a431..6c13ec95df 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b36dfdff787dc4a107b2c3fcbb98bfc4922872d8 \ No newline at end of file +f4cbd18db47af4af990d7891dcc831e92b3f17e0 \ No newline at end of file diff --git a/test/shell1.test b/test/shell1.test index 476af064a5..36b61c819e 100644 --- a/test/shell1.test +++ b/test/shell1.test @@ -910,10 +910,13 @@ do_test shell1-5.0 { } } {} +# The string used here is the word "test" in Chinese. +# In UTF-8, it is encoded as: \xE6\xB5\x8B\xE8\xAF\x95 +set test \u6D4B\u8BD5 + do_test shell1-6.0 { - # The base file name here is the word "test" in Chinese. - # In UTF-8, it is encoded as: \xE6\xB5\x8B\xE8\xAF\x95 - set fileName \u6D4B\u8BD5; append fileName .db + set fileName $test; append fileName .db + catch {forcedelete $fileName} set x [catchcmdex $fileName "CREATE TABLE t1(x);\n.schema\n"] set code [lindex $x 0] set res [string trim [lindex $x 1]] @@ -929,4 +932,19 @@ do_test shell1-6.0 { forcedelete $fileName } {} +do_test shell1-6.1 { + catch {forcedelete test3.db} + set x [catchcmdex test3.db \ + "CREATE TABLE [encoding convertto utf-8 $test](x);\n.schema\n"] + set code [lindex $x 0] + set res [string trim [lindex $x 1]] + if {$code ne "0"} { + error "failed with error: $res" + } + if {$res ne "CREATE TABLE ${test}(x);"} { + error "failed with mismatch: $res" + } + forcedelete test3.db +} {} + finish_test From 455684a03611dbc3a1de4f7e27036cf27f848c5b Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 4 Apr 2016 16:40:44 +0000 Subject: [PATCH 0243/1484] Test that the view name is passed to the authorization callback when a SELECT statement is run on a view. FossilOrigin-Name: 8627a4cd6d64bd076b56c1e8ccc3b1dfc1b4c07d --- manifest | 15 +++++++-------- manifest.uuid | 2 +- test/auth.test | 49 +++++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 55 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index c98d80b73d..9c351dc120 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\ssqlite3session_apply()\sand\ssqlite3session_apply_strm()\sso\sthat\nconflicts\sare\sretried\sbefore\sthe\sxConflict()\scallback\sis\sinvoked,\sas\slong\nas\sthe\s"apply"\soperation\sis\smaking\sforward\sprogress. -D 2016-04-04T14:57:25.972 +C Test\sthat\sthe\sview\sname\sis\spassed\sto\sthe\sauthorization\scallback\swhen\sa\sSELECT\sstatement\sis\srun\son\sa\sview. +D 2016-04-04T16:40:44.335 F Makefile.in e812bb732d7af01baa09f1278bd4f4a2e3a09449 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc fe57d7e3e74fa383fd01ced796c0ffd966fc094a @@ -497,7 +497,7 @@ F test/attach2.test 0ec5defa340363de6cd50fd595046465e9aaba2d F test/attach3.test 359eb65d00102cdfcef6fa4e81dc1648f8f80b27 F test/attach4.test 53bf502f17647c6d6c5add46dda6bac8b6f4665c F test/attachmalloc.test 3a4bfca9545bfe906a8d2e622de10fbac5b711b0 -F test/auth.test 855233ef26eb3601b6886567ea4e326c72959360 +F test/auth.test 872a122b3977c1d1bb9fd637dc20016e5c01880f F test/auth2.test 264c6af53cad9aba5218c68bbe18036e39007bfa F test/auth3.test 5cfa94ed90c6617c42b7ba4b133fd79678b251c7 F test/autoinc.test c58912526998a39e11f66b533e23cfabea7f25b7 @@ -1482,8 +1482,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e375fe52cea7903c11ecef71c3452c67a96b663e 49763fc3ae2fb6117b0443ea28661568467f9bf2 -R 29983b81bb4a270732770d4dd854ff08 -T +closed 49763fc3ae2fb6117b0443ea28661568467f9bf2 -U drh -Z eb92f633faf3f47383a6550496ee5fc7 +P 42a219668413e18dae917b03b04a21d108cc44be +R 27f4603d27093d983cb0f53232a8c10f +U dan +Z 39b2019f8e2190d9694d9394017c15aa diff --git a/manifest.uuid b/manifest.uuid index 586be52a36..3507c72f05 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -42a219668413e18dae917b03b04a21d108cc44be \ No newline at end of file +8627a4cd6d64bd076b56c1e8ccc3b1dfc1b4c07d \ No newline at end of file diff --git a/test/auth.test b/test/auth.test index f3c2fa79e8..d9e12edc3c 100644 --- a/test/auth.test +++ b/test/auth.test @@ -2432,8 +2432,53 @@ do_test auth-6.3 { execsql {SELECT rowid, * FROM t6} } {101 1 2 3 4 5 6 7 8} +#------------------------------------------------------------------------- +# Test that view names are included as zArg4. +# +do_execsql_test auth-7.1 { + CREATE TABLE t7(a, b, c); + CREATE VIEW v7 AS SELECT * FROM t7; +} {} +set ::authargs [list] +proc auth {args} { + eval lappend ::authargs [lrange $args 0 4] + return SQLITE_OK +} + +do_test auth-7.2 { + execsql {SELECT a, c FROM v7} + set ::authargs +} [list \ + SQLITE_SELECT {} {} {} {} \ + SQLITE_READ t7 a main v7 \ + SQLITE_READ t7 b main v7 \ + SQLITE_READ t7 c main v7 \ + SQLITE_READ v7 a main {} \ + SQLITE_READ v7 c main {} \ + SQLITE_SELECT {} {} {} v7 \ +] + +set ::authargs [list] +do_test auth-7.3 { + execsql {SELECT a, c FROM t7} + set ::authargs +} [list \ + SQLITE_SELECT {} {} {} {} \ + SQLITE_READ t7 a main {} \ + SQLITE_READ t7 c main {} \ +] + +set ::authargs [list] +do_test auth-7.4 { + execsql {SELECT a, c FROM t7 AS v7} + set ::authargs +} [list \ + SQLITE_SELECT {} {} {} {} \ + SQLITE_READ t7 a main {} \ + SQLITE_READ t7 c main {} \ +] + + rename proc {} rename proc_real proc - - finish_test From de613c6d4a60a53d5a4d7fd6fa37450608ca26c1 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 4 Apr 2016 17:23:10 +0000 Subject: [PATCH 0244/1484] Add the ".auth ON|OFF" command to the command-line shell. FossilOrigin-Name: 65c7bcc42786a254966c531ba9062abb8fc8c5bf --- manifest | 14 ++++++------ manifest.uuid | 2 +- src/shell.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 9c351dc120..f50d302e4f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Test\sthat\sthe\sview\sname\sis\spassed\sto\sthe\sauthorization\scallback\swhen\sa\sSELECT\sstatement\sis\srun\son\sa\sview. -D 2016-04-04T16:40:44.335 +C Add\sthe\s".auth\sON|OFF"\scommand\sto\sthe\scommand-line\sshell. +D 2016-04-04T17:23:10.395 F Makefile.in e812bb732d7af01baa09f1278bd4f4a2e3a09449 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc fe57d7e3e74fa383fd01ced796c0ffd966fc094a @@ -376,7 +376,7 @@ F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c b8f7174e5f8c33c44ded3a25a973d0bb89228c20 F src/rowset.c 9fe4b3ad7cc00944386bb600233d8f523de07a6e F src/select.c 7849cee0a01952a9c93cd28989daedfa57731143 -F src/shell.c faa783401b0c25e52e4054a7292a78ab2f76d210 +F src/shell.c e0996a0be612c8d2630fdf8bcedf4c4260a29734 F src/sqlite.h.in c46a7b85d3f37371cacea8f98ec825f5e52c420c F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 98f72cbfe00169c39089115427d06ea05fe4b4a2 @@ -1482,7 +1482,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 42a219668413e18dae917b03b04a21d108cc44be -R 27f4603d27093d983cb0f53232a8c10f -U dan -Z 39b2019f8e2190d9694d9394017c15aa +P 8627a4cd6d64bd076b56c1e8ccc3b1dfc1b4c07d +R 327fee759e5533f8bd09762659f3f70b +U drh +Z ff39f0b57606b297cab9fa07bc83cd18 diff --git a/manifest.uuid b/manifest.uuid index 3507c72f05..8a44ee2cd4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8627a4cd6d64bd076b56c1e8ccc3b1dfc1b4c07d \ No newline at end of file +65c7bcc42786a254966c531ba9062abb8fc8c5bf \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 58a0d7aa51..809d9d0459 100644 --- a/src/shell.c +++ b/src/shell.c @@ -887,6 +887,52 @@ static void interrupt_handler(int NotUsed){ } #endif +/* +** When the ".auth ON" is set, the following authorizer callback is +** invoked. It always returns SQLITE_OK. +*/ +static int shellAuth( + void *pClientData, + int op, + const char *zA1, + const char *zA2, + const char *zA3, + const char *zA4 +){ + ShellState *p = (ShellState*)pClientData; + static const char *azAction[] = { 0, + "CREATE_INDEX", "CREATE_TABLE", "CREATE_TEMP_INDEX", + "CREATE_TEMP_TABLE", "CREATE_TEMP_TRIGGER", "CREATE_TEMP_VIEW", + "CREATE_TRIGGER", "CREATE_VIEW", "DELETE", + "DROP_INDEX", "DROP_TABLE", "DROP_TEMP_INDEX", + "DROP_TEMP_TABLE", "DROP_TEMP_TRIGGER", "DROP_TEMP_VIEW", + "DROP_TRIGGER", "DROP_VIEW", "INSERT", + "PRAGMA", "READ", "SELECT", + "TRANSACTION", "UPDATE", "ATTACH", + "DETACH", "ALTER_TABLE", "REINDEX", + "ANALYZE", "CREATE_VTABLE", "DROP_VTABLE", + "FUNCTION", "SAVEPOINT", "RECURSIVE" + }; + int i; + const char *az[4]; + az[0] = zA1; + az[1] = zA2; + az[2] = zA3; + az[3] = zA4; + raw_printf(p->out, "authorizer: %s", azAction[op]); + for(i=0; i<4; i++){ + raw_printf(p->out, " "); + if( az[i] ){ + output_c_string(p->out, az[i]); + }else{ + raw_printf(p->out, "NULL"); + } + } + raw_printf(p->out, "\n"); + return SQLITE_OK; +} + + /* ** This is the callback routine that the shell ** invokes for each row of a query result. @@ -1958,6 +2004,7 @@ static int run_schema_dump_query( ** Text of a help message */ static char zHelp[] = + ".auth ON|OFF Show authorizer callbacks\n" ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n" ".bail on|off Stop after hitting an error. Default OFF\n" ".binary on|off Turn binary output on or off. Default OFF\n" @@ -2923,6 +2970,21 @@ static int do_meta_command(char *zLine, ShellState *p){ if( nArg==0 ) return 0; /* no tokens, no error */ n = strlen30(azArg[0]); c = azArg[0][0]; + + if( c=='a' && strncmp(azArg[0], "auth", n)==0 ){ + if( nArg!=2 ){ + raw_printf(stderr, "Usage: .auth ON|OFF\n"); + rc = 1; + goto meta_command_exit; + } + open_db(p, 0); + if( booleanValue(azArg[1]) ){ + sqlite3_set_authorizer(p->db, shellAuth, p); + }else{ + sqlite3_set_authorizer(p->db, 0, 0); + } + }else + if( (c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0) || (c=='s' && n>=3 && strncmp(azArg[0], "save", n)==0) ){ From 48dcf2b60b85295a91223a665d8cca7230c9fab4 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Mon, 4 Apr 2016 17:59:37 +0000 Subject: [PATCH 0245/1484] Improve error messages from the 'shell1-5.0' test. FossilOrigin-Name: cefd36ff7b7f142bcebdb16b4d24ae274cdf2709 --- manifest | 15 +++++++-------- manifest.uuid | 2 +- test/shell1.test | 7 ++++++- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 1346fe76ed..9cdd24ac24 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improved\shandling\sof\sUTF8\sby\sthe\scommand-line\sshell. -D 2016-04-04T17:34:54.498 +C Improve\serror\smessages\sfrom\sthe\s'shell1-5.0'\stest. +D 2016-04-04T17:59:37.790 F Makefile.in e812bb732d7af01baa09f1278bd4f4a2e3a09449 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc fe57d7e3e74fa383fd01ced796c0ffd966fc094a @@ -1051,7 +1051,7 @@ F test/sharedA.test 0cdf1a76dfa00e6beee66af5b534b1e8df2720f5 F test/sharedB.test 16cc7178e20965d75278f410943109b77b2e645e F test/shared_err.test 2f2aee20db294b9924e81f6ccbe60f19e21e8506 F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304 -F test/shell1.test a216486c6aeae4d3e75e37d64e4b6c8974108750 +F test/shell1.test b3df199cef9bc722d4078c893a7093d31174ea11 F test/shell2.test e242a9912f44f4c23c3d1d802a83e934e84c853b F test/shell3.test da513d522ef6f01cee8475dcf8332bff8982b3dd F test/shell4.test 69995ee1cc278eb149aa8746ce1f935f4eaf98b9 @@ -1482,8 +1482,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 65c7bcc42786a254966c531ba9062abb8fc8c5bf f4cbd18db47af4af990d7891dcc831e92b3f17e0 -R 6a3470f790b8def5155325c3cfdf4cee -T +closed f4cbd18db47af4af990d7891dcc831e92b3f17e0 -U drh -Z cd8719efec0532e424e0fef6159fe981 +P 4534ebf15fbcd6fe2028957b7aa591b6cd5da95f +R f892094f49f405a0a06a581ad52203d2 +U mistachkin +Z b9fa5f032554b733f702cb8290f0ece6 diff --git a/manifest.uuid b/manifest.uuid index cf9bd49e8e..27bdbd69e6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4534ebf15fbcd6fe2028957b7aa591b6cd5da95f \ No newline at end of file +cefd36ff7b7f142bcebdb16b4d24ae274cdf2709 \ No newline at end of file diff --git a/test/shell1.test b/test/shell1.test index 36b61c819e..9dd0f42093 100644 --- a/test/shell1.test +++ b/test/shell1.test @@ -905,7 +905,12 @@ do_test shell1-5.0 { error "failed with error: $res" } if {$res ne "$oldChar\n"} { - error "failed with byte $hex mismatch" + if {[llength $res] > 0} { + set got [format %02X [scan $res %c]] + } else { + set got + } + error "failed with byte $hex mismatch, got $got" } } } {} From 73a6bb5851f9f7998573f9c60d10465af04992bd Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 4 Apr 2016 18:04:56 +0000 Subject: [PATCH 0246/1484] Fix documentation typos. Comment changes only. No changes to code. FossilOrigin-Name: d5fc2f7f90f8cbd53810c7a445b0e9c9a0e39182 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/sqlite.h.in | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 9cdd24ac24..d2d4f94a79 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improve\serror\smessages\sfrom\sthe\s'shell1-5.0'\stest. -D 2016-04-04T17:59:37.790 +C Fix\sdocumentation\stypos.\s\sComment\schanges\sonly.\s\sNo\schanges\sto\scode. +D 2016-04-04T18:04:56.616 F Makefile.in e812bb732d7af01baa09f1278bd4f4a2e3a09449 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc fe57d7e3e74fa383fd01ced796c0ffd966fc094a @@ -377,7 +377,7 @@ F src/resolve.c b8f7174e5f8c33c44ded3a25a973d0bb89228c20 F src/rowset.c 9fe4b3ad7cc00944386bb600233d8f523de07a6e F src/select.c 7849cee0a01952a9c93cd28989daedfa57731143 F src/shell.c b7922fa264f8c8d72a5ec6dd0b091e15a93c4de5 -F src/sqlite.h.in c46a7b85d3f37371cacea8f98ec825f5e52c420c +F src/sqlite.h.in 7f437b068314f053e6417d452c59f08d05092591 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 98f72cbfe00169c39089115427d06ea05fe4b4a2 F src/sqliteInt.h 594bf31a7a0cc788688ca947e562576e23bd7904 @@ -1482,7 +1482,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 4534ebf15fbcd6fe2028957b7aa591b6cd5da95f -R f892094f49f405a0a06a581ad52203d2 -U mistachkin -Z b9fa5f032554b733f702cb8290f0ece6 +P cefd36ff7b7f142bcebdb16b4d24ae274cdf2709 +R febb375a1eed9f049740185e3c47f862 +U drh +Z 64b7ed851fe55fe722cd357618c3eec9 diff --git a/manifest.uuid b/manifest.uuid index 27bdbd69e6..0654e5fabc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cefd36ff7b7f142bcebdb16b4d24ae274cdf2709 \ No newline at end of file +d5fc2f7f90f8cbd53810c7a445b0e9c9a0e39182 \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index b5f0e7f98e..b28e1ba14a 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -6761,7 +6761,7 @@ int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg); ** database file in rollback mode databases. Any pages written as part of ** transaction rollback or database recovery operations are not included. ** If an IO or other error occurs while writing a page to disk, the effect -** on subsequent SQLITE_DBSTATUS_CACHE_WRITE requests is undefined). ^The +** on subsequent SQLITE_DBSTATUS_CACHE_WRITE requests is undefined.)^ ^The ** highwater mark associated with SQLITE_DBSTATUS_CACHE_WRITE is always 0. ** ** @@ -7137,7 +7137,7 @@ typedef struct sqlite3_backup sqlite3_backup; ** must be different or else sqlite3_backup_init(D,N,S,M) will fail with ** an error. ** -** ^A call to sqlite3_backup_init() will fail, returning SQLITE_ERROR, if +** ^A call to sqlite3_backup_init() will fail, returning NULL, if ** there is already a read or read-write transaction open on the ** destination database. ** From cca6698408920f5c9062f07aee14acab9d3668f0 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 5 Apr 2016 13:19:19 +0000 Subject: [PATCH 0247/1484] Do not allow pointer arithmetic to move a pointer across a memory allocation boundary. FossilOrigin-Name: 85b979319bcb8ec301ae39b36ad60348e4515be7 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btree.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index d2d4f94a79..22ecbfaa94 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sdocumentation\stypos.\s\sComment\schanges\sonly.\s\sNo\schanges\sto\scode. -D 2016-04-04T18:04:56.616 +C Do\snot\sallow\spointer\sarithmetic\sto\smove\sa\spointer\sacross\sa\smemory\sallocation\nboundary. +D 2016-04-05T13:19:19.622 F Makefile.in e812bb732d7af01baa09f1278bd4f4a2e3a09449 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc fe57d7e3e74fa383fd01ced796c0ffd966fc094a @@ -319,7 +319,7 @@ F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240 F src/backup.c f60f0aa55d25d853ffde53d0b0370a7bb7ee41ce F src/bitvec.c 3ee4c8b2c94ed3a7377256e18199e6ff5cf33f63 F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 -F src/btree.c 577fb5674e2f0aa0a38246afc19e1885a0b8c9b0 +F src/btree.c 2b5504ac632a0d7a1cac94eacee3042f1d79de38 F src/btree.h a5008b9afe56e8e54ade6c436a910f112defcca9 F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 F src/build.c 39faaaeecb77eb3936d4bd5024e865e3836ca323 @@ -1482,7 +1482,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P cefd36ff7b7f142bcebdb16b4d24ae274cdf2709 -R febb375a1eed9f049740185e3c47f862 +P d5fc2f7f90f8cbd53810c7a445b0e9c9a0e39182 +R 1653d2df23c45643b8fad503f203cef3 U drh -Z 64b7ed851fe55fe722cd357618c3eec9 +Z 587fa086f1daad23618d760100c57f67 diff --git a/manifest.uuid b/manifest.uuid index 0654e5fabc..88c7d9f709 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d5fc2f7f90f8cbd53810c7a445b0e9c9a0e39182 \ No newline at end of file +85b979319bcb8ec301ae39b36ad60348e4515be7 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index bf99597095..079fd0b9e4 100644 --- a/src/btree.c +++ b/src/btree.c @@ -6545,8 +6545,8 @@ static int pageInsertArray( u8 *pSlot; sz = cachedCellSize(pCArray, i); if( (aData[1]==0 && aData[2]==0) || (pSlot = pageFindSlot(pPg,sz,&rc))==0 ){ + if( (pData - pBegin)apCell[i] will never overlap on a well-formed From 1c715f67b9765e14d06288a1deb890170972ae4a Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 5 Apr 2016 13:35:43 +0000 Subject: [PATCH 0248/1484] Use SQLITE_WITHIN() for pointer range comparisons in some testing code. FossilOrigin-Name: 7cacf4e954c8de5af5efb56d8271a5ac1edc1c04 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btree.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 22ecbfaa94..5a24a606e7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Do\snot\sallow\spointer\sarithmetic\sto\smove\sa\spointer\sacross\sa\smemory\sallocation\nboundary. -D 2016-04-05T13:19:19.622 +C Use\sSQLITE_WITHIN()\sfor\spointer\srange\scomparisons\sin\ssome\stesting\scode. +D 2016-04-05T13:35:43.174 F Makefile.in e812bb732d7af01baa09f1278bd4f4a2e3a09449 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc fe57d7e3e74fa383fd01ced796c0ffd966fc094a @@ -319,7 +319,7 @@ F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240 F src/backup.c f60f0aa55d25d853ffde53d0b0370a7bb7ee41ce F src/bitvec.c 3ee4c8b2c94ed3a7377256e18199e6ff5cf33f63 F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 -F src/btree.c 2b5504ac632a0d7a1cac94eacee3042f1d79de38 +F src/btree.c 556203aab543e91f4e20cc273a507ed712c8da26 F src/btree.h a5008b9afe56e8e54ade6c436a910f112defcca9 F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 F src/build.c 39faaaeecb77eb3936d4bd5024e865e3836ca323 @@ -1482,7 +1482,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d5fc2f7f90f8cbd53810c7a445b0e9c9a0e39182 -R 1653d2df23c45643b8fad503f203cef3 +P 85b979319bcb8ec301ae39b36ad60348e4515be7 +R 78bf202733e4247e84509df93eee1af7 U drh -Z 587fa086f1daad23618d760100c57f67 +Z b9b3193def70d2175e83a878eda9a91d diff --git a/manifest.uuid b/manifest.uuid index 88c7d9f709..b976ec3fb2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -85b979319bcb8ec301ae39b36ad60348e4515be7 \ No newline at end of file +7cacf4e954c8de5af5efb56d8271a5ac1edc1c04 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 079fd0b9e4..e5be8e0ef8 100644 --- a/src/btree.c +++ b/src/btree.c @@ -6708,7 +6708,7 @@ static int editPage( for(i=0; iapCell[i+iNew]; int iOff = get2byteAligned(&pPg->aCellIdx[i*2]); - if( pCell>=aData && pCell<&aData[pPg->pBt->usableSize] ){ + if( SQLITE_WITHIN(pCell, aData, &aData[pPg->pBt->usableSize]) ){ pCell = &pTmp[pCell - aData]; } assert( 0==memcmp(pCell, &aData[iOff], From 868f0398e4f4bf40e66a3802733e87d06c2cde0a Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 5 Apr 2016 14:01:34 +0000 Subject: [PATCH 0249/1484] Remove an unnecessary conditional from the index builder. FossilOrigin-Name: 87e5f5a6c60e37e943b3ce80617e81b09852515e --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/build.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 5a24a606e7..50d38b0ed6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Use\sSQLITE_WITHIN()\sfor\spointer\srange\scomparisons\sin\ssome\stesting\scode. -D 2016-04-05T13:35:43.174 +C Remove\san\sunnecessary\sconditional\sfrom\sthe\sindex\sbuilder. +D 2016-04-05T14:01:34.379 F Makefile.in e812bb732d7af01baa09f1278bd4f4a2e3a09449 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc fe57d7e3e74fa383fd01ced796c0ffd966fc094a @@ -322,7 +322,7 @@ F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 F src/btree.c 556203aab543e91f4e20cc273a507ed712c8da26 F src/btree.h a5008b9afe56e8e54ade6c436a910f112defcca9 F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 -F src/build.c 39faaaeecb77eb3936d4bd5024e865e3836ca323 +F src/build.c ab763de47337f1acf03de6b36cbc13c90d20b932 F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 60e135af364d777a9ab41c97e5e89cd224da6198 @@ -1482,7 +1482,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 85b979319bcb8ec301ae39b36ad60348e4515be7 -R 78bf202733e4247e84509df93eee1af7 +P 7cacf4e954c8de5af5efb56d8271a5ac1edc1c04 +R 5ad558ecd8aa9ab49f6924d29c53367a U drh -Z b9b3193def70d2175e83a878eda9a91d +Z 440953881a474ce081fa2537f4e8dbc0 diff --git a/manifest.uuid b/manifest.uuid index b976ec3fb2..43b1d36ebe 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7cacf4e954c8de5af5efb56d8271a5ac1edc1c04 \ No newline at end of file +87e5f5a6c60e37e943b3ce80617e81b09852515e \ No newline at end of file diff --git a/src/build.c b/src/build.c index d4d0c173cc..41ded1f8e4 100644 --- a/src/build.c +++ b/src/build.c @@ -2786,7 +2786,7 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){ addr1 = sqlite3VdbeAddOp2(v, OP_SorterSort, iSorter, 0); VdbeCoverage(v); assert( pKey!=0 || db->mallocFailed || pParse->nErr ); - if( IsUniqueIndex(pIndex) && pKey!=0 ){ + if( IsUniqueIndex(pIndex) /*&& pKey!=0*/ ){ int j2 = sqlite3VdbeCurrentAddr(v) + 3; sqlite3VdbeGoto(v, j2); addr2 = sqlite3VdbeCurrentAddr(v); From aed11f2072815a6220ff0261c1c9a0aebb3c96b1 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 5 Apr 2016 14:02:16 +0000 Subject: [PATCH 0250/1484] Make sure "0" intended as a NULL pointer is cast to a pointer when used in a varargs functions parameter. FossilOrigin-Name: ed128e8b826cd9620b7146d01d461ed28b9a672d --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/test_malloc.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 50d38b0ed6..056d33d3a7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\san\sunnecessary\sconditional\sfrom\sthe\sindex\sbuilder. -D 2016-04-05T14:01:34.379 +C Make\ssure\s"0"\sintended\sas\sa\sNULL\spointer\sis\scast\sto\sa\spointer\swhen\sused\nin\sa\svarargs\sfunctions\sparameter. +D 2016-04-05T14:02:16.715 F Makefile.in e812bb732d7af01baa09f1278bd4f4a2e3a09449 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc fe57d7e3e74fa383fd01ced796c0ffd966fc094a @@ -411,7 +411,7 @@ F src/test_intarray.c 870124b95ec4c645d4eb84f15efb7133528fb1a5 F src/test_intarray.h 9dc57417fb65bc7835cc18548852cc08cc062202 F src/test_journal.c 5360fbe1d1e4416ca36290562fd5a2e3f70f32aa F src/test_loadext.c 337056bae59f80b9eb00ba82088b39d0f4fe6dfd -F src/test_malloc.c 96df9381a1ff1f6d3805ff7231b9baf1386aaabf +F src/test_malloc.c 94c18e88d6df6d471a0d04ddb809f833d1739950 F src/test_multiplex.c 6a9de820fcaaf506c59aa14bc8693822333cea48 F src/test_multiplex.h c08e4e8f8651f0c5e0509b138ff4d5b43ed1f5d3 F src/test_mutex.c dbdfaff8580071f2212a0deae3325a93a737819c @@ -1482,7 +1482,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 7cacf4e954c8de5af5efb56d8271a5ac1edc1c04 -R 5ad558ecd8aa9ab49f6924d29c53367a +P 87e5f5a6c60e37e943b3ce80617e81b09852515e +R a877aa3d312b2b09cc17cdd970ec6cc3 U drh -Z 440953881a474ce081fa2537f4e8dbc0 +Z 781d8f18c7a4bdfd2f2083091977b2ca diff --git a/manifest.uuid b/manifest.uuid index 43b1d36ebe..ef7f23a7aa 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -87e5f5a6c60e37e943b3ce80617e81b09852515e \ No newline at end of file +ed128e8b826cd9620b7146d01d461ed28b9a672d \ No newline at end of file diff --git a/src/test_malloc.c b/src/test_malloc.c index aaa640b03a..e6be663998 100644 --- a/src/test_malloc.c +++ b/src/test_malloc.c @@ -1093,7 +1093,7 @@ static int test_db_config_lookaside( if( Tcl_GetIntFromObj(interp, objv[3], &sz) ) return TCL_ERROR; if( Tcl_GetIntFromObj(interp, objv[4], &cnt) ) return TCL_ERROR; if( bufid==0 ){ - rc = sqlite3_db_config(db, SQLITE_DBCONFIG_LOOKASIDE, 0, sz, cnt); + rc = sqlite3_db_config(db, SQLITE_DBCONFIG_LOOKASIDE, (void*)0, sz, cnt); }else if( bufid>=1 && bufid<=2 && sz*cnt<=sizeof(azBuf[0]) ){ rc = sqlite3_db_config(db, SQLITE_DBCONFIG_LOOKASIDE, azBuf[bufid], sz,cnt); }else{ From 60de73e83d397b8d581f31e312310398b66cb4e3 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 5 Apr 2016 15:59:23 +0000 Subject: [PATCH 0251/1484] Incorrect version of build.c checked in at [87e5f5a6c60e3] (because I neglected to press the "Save" button on the text editor). There is no change to the logic, just improved presentation. FossilOrigin-Name: cf569f9f2fab1828e4bfced111fd9a6ee23ea8c0 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/build.c | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 056d33d3a7..9328401ca9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\ssure\s"0"\sintended\sas\sa\sNULL\spointer\sis\scast\sto\sa\spointer\swhen\sused\nin\sa\svarargs\sfunctions\sparameter. -D 2016-04-05T14:02:16.715 +C Incorrect\sversion\sof\sbuild.c\schecked\sin\sat\s[87e5f5a6c60e3]\s(because\sI\nneglected\sto\spress\sthe\s"Save"\sbutton\son\sthe\stext\seditor).\s\sThere\sis\sno\schange\nto\sthe\slogic,\sjust\simproved\spresentation. +D 2016-04-05T15:59:23.006 F Makefile.in e812bb732d7af01baa09f1278bd4f4a2e3a09449 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc fe57d7e3e74fa383fd01ced796c0ffd966fc094a @@ -322,7 +322,7 @@ F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 F src/btree.c 556203aab543e91f4e20cc273a507ed712c8da26 F src/btree.h a5008b9afe56e8e54ade6c436a910f112defcca9 F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 -F src/build.c ab763de47337f1acf03de6b36cbc13c90d20b932 +F src/build.c c5cf206191880f88142352629d53fed174fc10bd F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 60e135af364d777a9ab41c97e5e89cd224da6198 @@ -1482,7 +1482,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 87e5f5a6c60e37e943b3ce80617e81b09852515e -R a877aa3d312b2b09cc17cdd970ec6cc3 +P ed128e8b826cd9620b7146d01d461ed28b9a672d +R 27e5e4c2995b5324778005dedfa90fe5 U drh -Z 781d8f18c7a4bdfd2f2083091977b2ca +Z ed5acb084f4d8b134ae4eeee3cdc81ad diff --git a/manifest.uuid b/manifest.uuid index ef7f23a7aa..cf9761250d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ed128e8b826cd9620b7146d01d461ed28b9a672d \ No newline at end of file +cf569f9f2fab1828e4bfced111fd9a6ee23ea8c0 \ No newline at end of file diff --git a/src/build.c b/src/build.c index 41ded1f8e4..e7a6824fb2 100644 --- a/src/build.c +++ b/src/build.c @@ -2762,6 +2762,7 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){ tnum = pIndex->tnum; } pKey = sqlite3KeyInfoOfIndex(pParse, pIndex); + assert( pKey!=0 || db->mallocFailed || pParse->nErr ); /* Open the sorter cursor if we are to use one. */ iSorter = pParse->nTab++; @@ -2785,8 +2786,7 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){ sqlite3VdbeChangeP5(v, OPFLAG_BULKCSR|((memRootPage>=0)?OPFLAG_P2ISREG:0)); addr1 = sqlite3VdbeAddOp2(v, OP_SorterSort, iSorter, 0); VdbeCoverage(v); - assert( pKey!=0 || db->mallocFailed || pParse->nErr ); - if( IsUniqueIndex(pIndex) /*&& pKey!=0*/ ){ + if( IsUniqueIndex(pIndex) ){ int j2 = sqlite3VdbeCurrentAddr(v) + 3; sqlite3VdbeGoto(v, j2); addr2 = sqlite3VdbeCurrentAddr(v); From 18a15493221d64e929600759f46d3adc40148166 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Tue, 5 Apr 2016 19:46:10 +0000 Subject: [PATCH 0252/1484] Remove superfluous directories from the Makefile clean targets. FossilOrigin-Name: 0bf9926c7a7865694edd48535777248e73d86bbf --- Makefile.in | 1 - Makefile.msc | 3 --- main.mk | 1 - manifest | 18 +++++++++--------- manifest.uuid | 2 +- 5 files changed, 10 insertions(+), 15 deletions(-) diff --git a/Makefile.in b/Makefile.in index 1b50b4e51e..2606b5a654 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1228,7 +1228,6 @@ clean: rm -f lemon$(BEXE) lempar.c parse.* sqlite*.tar.gz rm -f mkkeywordhash$(BEXE) keywordhash.h rm -f *.da *.bb *.bbg gmon.out - rm -rf quota2a quota2b quota2c rm -rf tsrc .target_source rm -f tclsqlite3$(TEXE) rm -f testfixture$(TEXE) test.db diff --git a/Makefile.msc b/Makefile.msc index 7fa9555c35..84aa118258 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -2075,9 +2075,6 @@ clean: del /Q notasharedlib.* 2>NUL -rmdir /Q/S .deps 2>NUL -rmdir /Q/S .libs 2>NUL - -rmdir /Q/S quota2a 2>NUL - -rmdir /Q/S quota2b 2>NUL - -rmdir /Q/S quota2c 2>NUL -rmdir /Q/S tsrc 2>NUL del /Q .target_source 2>NUL del /Q tclsqlite3.exe 2>NUL diff --git a/main.mk b/main.mk index 5c8621d03c..1e791416d8 100644 --- a/main.mk +++ b/main.mk @@ -905,7 +905,6 @@ clean: rm -f mkkeywordhash mkkeywordhash.exe keywordhash.h rm -f $(PUBLISH) rm -f *.da *.bb *.bbg gmon.out - rm -rf quota2a quota2b quota2c rm -rf tsrc target_source rm -f testloadext.dll libtestloadext.so rm -f amalgamation-testfixture amalgamation-testfixture.exe diff --git a/manifest b/manifest index 9328401ca9..d43c1b4e17 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -C Incorrect\sversion\sof\sbuild.c\schecked\sin\sat\s[87e5f5a6c60e3]\s(because\sI\nneglected\sto\spress\sthe\s"Save"\sbutton\son\sthe\stext\seditor).\s\sThere\sis\sno\schange\nto\sthe\slogic,\sjust\simproved\spresentation. -D 2016-04-05T15:59:23.006 -F Makefile.in e812bb732d7af01baa09f1278bd4f4a2e3a09449 +C Remove\ssuperfluous\sdirectories\sfrom\sthe\sMakefile\sclean\stargets. +D 2016-04-05T19:46:10.423 +F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 -F Makefile.msc fe57d7e3e74fa383fd01ced796c0ffd966fc094a +F Makefile.msc 1f123a0757f6f04f0341accb46457e116817159a F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7 F VERSION 5d234da9b5dae329fab75ff75884cfe0a9cb3fda F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 @@ -300,7 +300,7 @@ F ext/userauth/userauth.c 5fa3bdb492f481bbc1709fc83c91ebd13460c69e F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60 -F main.mk 942e1fd30eb352492cf599aa7fcb5334783e4cbf +F main.mk a283660f75c3c4b75d8c9d12a40fa38a066eee9d F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 @@ -1482,7 +1482,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ed128e8b826cd9620b7146d01d461ed28b9a672d -R 27e5e4c2995b5324778005dedfa90fe5 -U drh -Z ed5acb084f4d8b134ae4eeee3cdc81ad +P cf569f9f2fab1828e4bfced111fd9a6ee23ea8c0 +R 7e27a98746fe808f972e7a0e53304d1b +U mistachkin +Z 787b56c7aa73e42a20b98bed3736a925 diff --git a/manifest.uuid b/manifest.uuid index cf9761250d..d2adaf48bf 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cf569f9f2fab1828e4bfced111fd9a6ee23ea8c0 \ No newline at end of file +0bf9926c7a7865694edd48535777248e73d86bbf \ No newline at end of file From ed06a131dac1433711cf8c26fc38269c1ee7125b Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 5 Apr 2016 20:59:12 +0000 Subject: [PATCH 0253/1484] Carry table column types through into VIEW definitions, where possible. FossilOrigin-Name: fb555c3c2af7f5e62ff839658f4fba7b645d3a68 --- manifest | 20 +++++++------- manifest.uuid | 2 +- src/build.c | 73 ++++++++++++++++++++++++++++--------------------- src/select.c | 18 +++++++++--- src/sqliteInt.h | 1 + test/view.test | 20 ++++++++++++++ 6 files changed, 88 insertions(+), 46 deletions(-) diff --git a/manifest b/manifest index d43c1b4e17..04532b4880 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\ssuperfluous\sdirectories\sfrom\sthe\sMakefile\sclean\stargets. -D 2016-04-05T19:46:10.423 +C Carry\stable\scolumn\stypes\sthrough\sinto\sVIEW\sdefinitions,\swhere\spossible. +D 2016-04-05T20:59:12.069 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1f123a0757f6f04f0341accb46457e116817159a @@ -322,7 +322,7 @@ F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 F src/btree.c 556203aab543e91f4e20cc273a507ed712c8da26 F src/btree.h a5008b9afe56e8e54ade6c436a910f112defcca9 F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 -F src/build.c c5cf206191880f88142352629d53fed174fc10bd +F src/build.c 1944d95f0250ec72dab939f8319a12e237aaad61 F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 60e135af364d777a9ab41c97e5e89cd224da6198 @@ -375,12 +375,12 @@ F src/printf.c 63e6fb12bbe702dd664dc3703776c090383a5a26 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c b8f7174e5f8c33c44ded3a25a973d0bb89228c20 F src/rowset.c 9fe4b3ad7cc00944386bb600233d8f523de07a6e -F src/select.c 7849cee0a01952a9c93cd28989daedfa57731143 +F src/select.c d9b8628acb98f1a38921888d823a6b70c7a7774b F src/shell.c b7922fa264f8c8d72a5ec6dd0b091e15a93c4de5 F src/sqlite.h.in 7f437b068314f053e6417d452c59f08d05092591 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 98f72cbfe00169c39089115427d06ea05fe4b4a2 -F src/sqliteInt.h 594bf31a7a0cc788688ca947e562576e23bd7904 +F src/sqliteInt.h 292fbc9dd900c64e93a15dfd73ccd9e03475e6a6 F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 @@ -1308,7 +1308,7 @@ F test/vacuum3.test 77ecdd54592b45a0bcb133339f99f1ae0ae94d0d F test/vacuum4.test d3f8ecff345f166911568f397d2432c16d2867d9 F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102 F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661 -F test/view.test f6c3a39e0c819891265e1d0754e99960d81ef6c9 +F test/view.test 765802c7a66d37fabd5ac8e2f2dbe572b43eb9ab F test/vtab1.test 7c4b81abd88361ada9cbe414c459efca26be6bda F test/vtab2.test f8cd1bb9aba7143eba97812d9617880a36d247ad F test/vtab3.test b45f47d20f225ccc9c28dc915d92740c2dee311e @@ -1482,7 +1482,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P cf569f9f2fab1828e4bfced111fd9a6ee23ea8c0 -R 7e27a98746fe808f972e7a0e53304d1b -U mistachkin -Z 787b56c7aa73e42a20b98bed3736a925 +P 0bf9926c7a7865694edd48535777248e73d86bbf +R c7f5a7683cc4a0d14362e20e6891847a +U drh +Z ec8e2cff7764d808576889c190bbf60c diff --git a/manifest.uuid b/manifest.uuid index d2adaf48bf..d21138d9ad 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0bf9926c7a7865694edd48535777248e73d86bbf \ No newline at end of file +fb555c3c2af7f5e62ff839658f4fba7b645d3a68 \ No newline at end of file diff --git a/src/build.c b/src/build.c index e7a6824fb2..3d93d8b761 100644 --- a/src/build.c +++ b/src/build.c @@ -2176,44 +2176,55 @@ int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ ** statement that defines the view. */ assert( pTable->pSelect ); - if( pTable->pCheck ){ + pSel = sqlite3SelectDup(db, pTable->pSelect, 0); + if( pSel ){ + n = pParse->nTab; + sqlite3SrcListAssignCursors(pParse, pSel->pSrc); + pTable->nCol = -1; db->lookaside.bDisable++; - sqlite3ColumnsFromExprList(pParse, pTable->pCheck, - &pTable->nCol, &pTable->aCol); - db->lookaside.bDisable--; - }else{ - pSel = sqlite3SelectDup(db, pTable->pSelect, 0); - if( pSel ){ - n = pParse->nTab; - sqlite3SrcListAssignCursors(pParse, pSel->pSrc); - pTable->nCol = -1; - db->lookaside.bDisable++; #ifndef SQLITE_OMIT_AUTHORIZATION - xAuth = db->xAuth; - db->xAuth = 0; - pSelTab = sqlite3ResultSetOfSelect(pParse, pSel); - db->xAuth = xAuth; + xAuth = db->xAuth; + db->xAuth = 0; + pSelTab = sqlite3ResultSetOfSelect(pParse, pSel); + db->xAuth = xAuth; #else - pSelTab = sqlite3ResultSetOfSelect(pParse, pSel); + pSelTab = sqlite3ResultSetOfSelect(pParse, pSel); #endif - db->lookaside.bDisable--; - pParse->nTab = n; - if( pSelTab ){ - assert( pTable->aCol==0 ); - pTable->nCol = pSelTab->nCol; - pTable->aCol = pSelTab->aCol; - pSelTab->nCol = 0; - pSelTab->aCol = 0; - sqlite3DeleteTable(db, pSelTab); - assert( sqlite3SchemaMutexHeld(db, 0, pTable->pSchema) ); - }else{ - pTable->nCol = 0; - nErr++; + pParse->nTab = n; + if( pTable->pCheck ){ + /* CREATE VIEW name(arglist) AS ... + ** The names of the columns in the table are taken from + ** arglist which is stored in pTable->pCheck. The pCheck field + ** normally holds CHECK constraints on an ordinary table, but for + ** a VIEW it holds the list of column names. + */ + sqlite3ColumnsFromExprList(pParse, pTable->pCheck, + &pTable->nCol, &pTable->aCol); + if( db->mallocFailed==0 + && pParse->nErr==0 + && pTable->nCol==pSel->pEList->nExpr + ){ + sqlite3SelectAddColumnTypeAndCollation(pParse, pTable, pSel); } - sqlite3SelectDelete(db, pSel); - } else { + }else if( pSelTab ){ + /* CREATE VIEW name AS... without an argument list. Construct + ** the column names from the SELECT statement that defines the view. + */ + assert( pTable->aCol==0 ); + pTable->nCol = pSelTab->nCol; + pTable->aCol = pSelTab->aCol; + pSelTab->nCol = 0; + pSelTab->aCol = 0; + assert( sqlite3SchemaMutexHeld(db, 0, pTable->pSchema) ); + }else{ + pTable->nCol = 0; nErr++; } + if( pSelTab ) sqlite3DeleteTable(db, pSelTab); + sqlite3SelectDelete(db, pSel); + db->lookaside.bDisable--; + } else { + nErr++; } pTable->pSchema->schemaFlags |= DB_UnresetViews; #endif /* SQLITE_OMIT_VIEW */ diff --git a/src/select.c b/src/select.c index ed76f621f9..9a2d4d22cd 100644 --- a/src/select.c +++ b/src/select.c @@ -1704,7 +1704,7 @@ int sqlite3ColumnsFromExprList( ** This routine requires that all identifiers in the SELECT ** statement be resolved. */ -static void selectAddColumnTypeAndCollation( +void sqlite3SelectAddColumnTypeAndCollation( Parse *pParse, /* Parsing contexts */ Table *pTab, /* Add column type information to this table */ Select *pSelect /* SELECT used to determine types and collations */ @@ -1726,10 +1726,20 @@ static void selectAddColumnTypeAndCollation( sNC.pSrcList = pSelect->pSrc; a = pSelect->pEList->a; for(i=0, pCol=pTab->aCol; inCol; i++, pCol++){ + const char *zType; + int n, m; p = a[i].pExpr; - columnType(&sNC, p, 0, 0, 0, &pCol->szEst); + zType = columnType(&sNC, p, 0, 0, 0, &pCol->szEst); szAll += pCol->szEst; pCol->affinity = sqlite3ExprAffinity(p); + if( zType && (m = sqlite3Strlen30(zType))>0 ){ + n = sqlite3Strlen30(pCol->zName); + pCol->zName = sqlite3DbReallocOrFree(db, pCol->zName, n+m+2); + if( pCol->zName ){ + memcpy(&pCol->zName[n+1], zType, m+1); + pCol->colFlags |= COLFLAG_HASTYPE; + } + } if( pCol->affinity==0 ) pCol->affinity = SQLITE_AFF_BLOB; pColl = sqlite3ExprCollSeq(pParse, p); if( pColl && pCol->zColl==0 ){ @@ -1766,7 +1776,7 @@ Table *sqlite3ResultSetOfSelect(Parse *pParse, Select *pSelect){ pTab->zName = 0; pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) ); sqlite3ColumnsFromExprList(pParse, pSelect->pEList, &pTab->nCol, &pTab->aCol); - selectAddColumnTypeAndCollation(pParse, pTab, pSelect); + sqlite3SelectAddColumnTypeAndCollation(pParse, pTab, pSelect); pTab->iPKey = -1; if( db->mallocFailed ){ sqlite3DeleteTable(db, pTab); @@ -4550,7 +4560,7 @@ static void selectAddSubqueryTypeInfo(Walker *pWalker, Select *p){ Select *pSel = pFrom->pSelect; if( pSel ){ while( pSel->pPrior ) pSel = pSel->pPrior; - selectAddColumnTypeAndCollation(pParse, pTab, pSel); + sqlite3SelectAddColumnTypeAndCollation(pParse, pTab, pSel); } } } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index d789cc00e4..94dd68bffc 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3468,6 +3468,7 @@ void sqlite3CollapseDatabaseArray(sqlite3*); void sqlite3CommitInternalChanges(sqlite3*); void sqlite3DeleteColumnNames(sqlite3*,Table*); int sqlite3ColumnsFromExprList(Parse*,ExprList*,i16*,Column**); +void sqlite3SelectAddColumnTypeAndCollation(Parse*,Table*,Select*); Table *sqlite3ResultSetOfSelect(Parse*,Select*); void sqlite3OpenMasterTable(Parse *, int); Index *sqlite3PrimaryKeyIndex(Table*); diff --git a/test/view.test b/test/view.test index 235f8605ac..694b3c6abd 100644 --- a/test/view.test +++ b/test/view.test @@ -92,6 +92,26 @@ do_test view-1.8 { } } {2 3 5 6 8 9} +do_execsql_test view-1.10 { + CREATE TABLE t9(x INTEGER); + CREATE VIEW v9a AS SELECT x FROM t9; + CREATE VIEW v9b AS SELECT * FROM t9; + CREATE VIEW v9c(x) AS SELECT x FROM t9; + CREATE VIEW v9d(x) AS SELECT * FROM t9; +} {} +do_execsql_test view-1.11 { + PRAGMA table_info(v9a); +} {0 x INTEGER 0 {} 0} +do_execsql_test view-1.12 { + PRAGMA table_info(v9b); +} {0 x INTEGER 0 {} 0} +do_execsql_test view-1.13 { + PRAGMA table_info(v9c); +} {0 x INTEGER 0 {} 0} +do_execsql_test view-1.14 { + PRAGMA table_info(v9d); +} {0 x INTEGER 0 {} 0} + do_test view-2.1 { execsql { CREATE VIEW v2 AS SELECT * FROM t1 WHERE a>5 From 41113b6429967b290386c05a4cbf6b9efc632b7a Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 5 Apr 2016 21:07:58 +0000 Subject: [PATCH 0254/1484] Defer opening the file used for the temp database (where CREATE TEMP TABLE tables are stored) until the database is too large to reside entirely within the cache. There are likely still problems on this branch. FossilOrigin-Name: be5a549eba6cf8e29cb6b9824fd6d0db9d03ca7f --- manifest | 20 +++--- manifest.uuid | 2 +- src/pager.c | 24 +++++-- src/pcache.c | 15 ++++- test/temptable2.test | 157 +++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 200 insertions(+), 18 deletions(-) create mode 100644 test/temptable2.test diff --git a/manifest b/manifest index 04532b4880..261df5d6bf 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Carry\stable\scolumn\stypes\sthrough\sinto\sVIEW\sdefinitions,\swhere\spossible. -D 2016-04-05T20:59:12.069 +C Defer\sopening\sthe\sfile\sused\sfor\sthe\stemp\sdatabase\s(where\sCREATE\sTEMP\sTABLE\stables\sare\sstored)\suntil\sthe\sdatabase\sis\stoo\slarge\sto\sreside\sentirely\swithin\sthe\scache.\sThere\sare\slikely\sstill\sproblems\son\sthis\sbranch. +D 2016-04-05T21:07:58.179 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1f123a0757f6f04f0341accb46457e116817159a @@ -362,10 +362,10 @@ F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa F src/os_unix.c b1ccb273771f41dbdbe0ba7c1ad63c38ad5972ec F src/os_win.c b3ba9573d8d893e70a6a8015bbee572ecf7ffbef F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca -F src/pager.c 38718a019ca762ba4f6795425d5a54db70d1790d +F src/pager.c 123dbae47bf27915a4b567915ff8dcc27cfcd369 F src/pager.h e1d38a2f14849e219df0f91f8323504d134c8a56 F src/parse.y 5ea8c81c5c41b27887f41b4a7e1c58470d7d3821 -F src/pcache.c 647bb53a86b7bbcf55ad88089b3ea5a9170b90df +F src/pcache.c e9c00846d3dcdaa75b288c6f16238c2fe2177823 F src/pcache.h 4d0ccaad264d360981ec5e6a2b596d6e85242545 F src/pcache1.c c40cdb93586e21b5dd826b5e671240bd91c26b05 F src/pragma.c faf42922bb7ab2f6672cb550356c1967abae3c84 @@ -1110,6 +1110,7 @@ F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930 F test/tclsqlite.test e1306001a0ca92250b691ea6d3cecaca5b6342aa F test/tempdb.test bd92eba8f20e16a9136e434e20b280794de3cdb6 F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30 +F test/temptable2.test f3b198e386f6494082c87accc8780cdf84b36e6d F test/temptrigger.test 8ec228b0db5d7ebc4ee9b458fc28cb9e7873f5e1 F test/tester.tcl 7b740ee852c55e1e72b6ebe5044acee7aa4e5553 F test/thread001.test 9f22fd3525a307ff42a326b6bc7b0465be1745a5 @@ -1482,7 +1483,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 0bf9926c7a7865694edd48535777248e73d86bbf -R c7f5a7683cc4a0d14362e20e6891847a -U drh -Z ec8e2cff7764d808576889c190bbf60c +P fb555c3c2af7f5e62ff839658f4fba7b645d3a68 +R f511e5baaeaad693345498b91b98e90f +T *branch * tempfiles-lazy-open +T *sym-tempfiles-lazy-open * +T -sym-trunk * +U dan +Z 505ba6148fb8f2c79237e86b07655c1c diff --git a/manifest.uuid b/manifest.uuid index d21138d9ad..0e8a9ef130 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fb555c3c2af7f5e62ff839658f4fba7b645d3a68 \ No newline at end of file +be5a549eba6cf8e29cb6b9824fd6d0db9d03ca7f \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index c18b3a32f7..45f54ef30d 100644 --- a/src/pager.c +++ b/src/pager.c @@ -2006,7 +2006,11 @@ static int pager_end_transaction(Pager *pPager, int hasMaster, int bCommit){ sqlite3BitvecDestroy(pPager->pInJournal); pPager->pInJournal = 0; pPager->nRec = 0; - sqlite3PcacheCleanAll(pPager->pPCache); + if( pPager->tempFile==0 || MEMDB ){ + sqlite3PcacheCleanAll(pPager->pPCache); + }else{ + sqlite3PcacheClearWritable(pPager->pPCache); + } sqlite3PcacheTruncate(pPager->pPCache, pPager->dbSize); if( pagerUseWal(pPager) ){ @@ -2374,9 +2378,13 @@ static int pager_playback_one_page( ** be written out into the database file before its journal file ** segment is synced. If a crash occurs during or following this, ** database corruption may ensue. + ** + ** Update: Another exception is for temp files that are not + ** in-memory databases. In this case the page may have been dirty + ** at the start of the transaction. */ assert( !pagerUseWal(pPager) ); - sqlite3PcacheMakeClean(pPg); + if( pPager->tempFile==0 ) sqlite3PcacheMakeClean(pPg); } pager_set_pagehash(pPg); @@ -4258,8 +4266,9 @@ static int pager_write_pagelist(Pager *pPager, PgHdr *pList){ /* This function is only called for rollback pagers in WRITER_DBMOD state. */ assert( !pagerUseWal(pPager) ); - assert( pPager->eState==PAGER_WRITER_DBMOD ); + assert( pPager->tempFile || pPager->eState==PAGER_WRITER_DBMOD ); assert( pPager->eLock==EXCLUSIVE_LOCK ); + assert( pPager->tempFile==0 || pList->pDirty==0 ); /* If the file is a temp-file has not yet been opened, open it now. It ** is not possible for rc to be other than SQLITE_OK if this branch @@ -5941,6 +5950,7 @@ int sqlite3PagerWrite(PgHdr *pPg){ if( pPager->nSavepoint ) return subjournalPageIfRequired(pPg); return SQLITE_OK; }else if( pPager->sectorSize > (u32)pPager->pageSize ){ + assert( pPager->tempFile==0 ); return pagerWriteLargeSector(pPg); }else{ return pager_write(pPg); @@ -6179,11 +6189,11 @@ int sqlite3PagerCommitPhaseOne( /* If no database changes have been made, return early. */ if( pPager->eStatetempFile ); + if( pPager->tempFile ){ /* If this is an in-memory db, or no pages have been written to, or this ** function has already been called, it is mostly a no-op. However, any - ** backup in progress needs to be restarted. - */ + ** backup in progress needs to be restarted. */ sqlite3BackupRestart(pPager->pBackup); }else{ if( pagerUseWal(pPager) ){ @@ -6845,7 +6855,7 @@ int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, int isCommit){ ** the journal needs to be sync()ed before database page pPg->pgno ** can be written to. The caller has already promised not to write to it. */ - if( (pPg->flags&PGHDR_NEED_SYNC) && !isCommit ){ + if( (pPg->flags&PGHDR_NEED_SYNC) && !isCommit && pPager->tempFile==0 ){ needSyncPgno = pPg->pgno; assert( pPager->journalMode==PAGER_JOURNALMODE_OFF || pageInJournal(pPager, pPg) || pPg->pgno>pPager->dbOrigSize ); diff --git a/src/pcache.c b/src/pcache.c index 61e7587422..52661c28a9 100644 --- a/src/pcache.c +++ b/src/pcache.c @@ -254,7 +254,7 @@ sqlite3_pcache_page *sqlite3PcacheFetch( /* ** If the sqlite3PcacheFetch() routine is unable to allocate a new -** page because new clean pages are available for reuse and the cache +** page because no clean pages are available for reuse and the cache ** size limit has been reached, then this routine can be invoked to ** try harder to allocate a page. This routine might invoke the stress ** callback to spill dirty pages to the journal. It will then try to @@ -439,6 +439,17 @@ void sqlite3PcacheCleanAll(PCache *pCache){ } } +/* +** Clear the PGHDR_NEED_SYNC and PGHDR_WRITEABLE flag from all dirty pages. +*/ +void sqlite3PcacheClearWritable(PCache *pCache){ + PgHdr *p; + for(p=pCache->pDirty; p; p=p->pDirtyNext){ + p->flags &= ~(PGHDR_NEED_SYNC|PGHDR_WRITEABLE); + } + pCache->pSynced = pCache->pDirtyTail; +} + /* ** Clear the PGHDR_NEED_SYNC flag from all dirty pages. */ @@ -484,7 +495,7 @@ void sqlite3PcacheTruncate(PCache *pCache, Pgno pgno){ ** it must be that pgno==0. */ assert( p->pgno>0 ); - if( ALWAYS(p->pgno>pgno) ){ + if( p->pgno>pgno ){ assert( p->flags&PGHDR_DIRTY ); sqlite3PcacheMakeClean(p); } diff --git a/test/temptable2.test b/test/temptable2.test new file mode 100644 index 0000000000..daeb206a29 --- /dev/null +++ b/test/temptable2.test @@ -0,0 +1,157 @@ +# 2016 March 3 +# +# 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. +# +#*********************************************************************** + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix temptable2 + +do_execsql_test 1.1 { + CREATE TEMP TABLE t1(a, b); + CREATE INDEX i1 ON t1(a, b); +} + +do_execsql_test 1.2 { + WITH x(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM x WHERE i<100000 ) + INSERT INTO t1 SELECT randomblob(100), randomblob(100) FROM X; +} {} + +do_execsql_test 1.3 { + PRAGMA temp.integrity_check; +} {ok} + +#------------------------------------------------------------------------- +# +reset_db +do_execsql_test 2.1 { + CREATE TEMP TABLE t2(a, b); + INSERT INTO t2 VALUES(1, 2); +} {} + +do_execsql_test 2.2 { + BEGIN; + INSERT INTO t2 VALUES(3, 4); + SELECT * FROM t2; +} {1 2 3 4} + +do_execsql_test 2.3 { + ROLLBACK; + SELECT * FROM t2; +} {1 2} + +#------------------------------------------------------------------------- +# +reset_db +do_execsql_test 3.1.1 { + PRAGMA main.cache_size = 10; + PRAGMA temp.cache_size = 10; + + CREATE TEMP TABLE t1(a, b); + CREATE INDEX i1 ON t1(a, b); + + WITH x(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM x WHERE i<1000 ) + INSERT INTO t1 SELECT randomblob(100), randomblob(100) FROM x; + + SELECT count(*) FROM t1; +} {1000} +do_execsql_test 3.1.2 { + BEGIN; + UPDATE t1 SET b=randomblob(100) WHERE (rowid%10)==0; + ROLLBACK; +} +do_execsql_test 3.1.3 { + SELECT count(*) FROM t1; +} {1000} +do_execsql_test 3.1.4 { PRAGMA temp.integrity_check } {ok} + +do_execsql_test 3.2.1 { + BEGIN; + UPDATE t1 SET b=randomblob(100) WHERE (rowid%10)==0; + SAVEPOINT abc; + UPDATE t1 SET b=randomblob(100) WHERE (rowid%10)==1; + ROLLBACK TO abc; + UPDATE t1 SET b=randomblob(100) WHERE (rowid%10)==2; + COMMIT; +} +do_execsql_test 3.2.2 { PRAGMA temp.integrity_check } {ok} + +#------------------------------------------------------------------------- +# +reset_db +do_execsql_test 4.1.1 { + PRAGMA main.cache_size = 10; + PRAGMA temp.cache_size = 10; + + CREATE TEMP TABLE t1(a, b); + CREATE INDEX i1 ON t1(a, b); + + WITH x(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM x WHERE i<10 ) + INSERT INTO t1 SELECT randomblob(100), randomblob(100) FROM x; + + SELECT count(*) FROM t1; + PRAGMA temp.page_count; +} {10 9} + +do_execsql_test 4.1.2 { + BEGIN; + UPDATE t1 SET b=randomblob(100); + ROLLBACK; +} + +do_execsql_test 4.1.3 { + CREATE TEMP TABLE t2(a, b); + CREATE INDEX i2 ON t2(a, b); + WITH x(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM x WHERE i<500 ) + INSERT INTO t2 SELECT randomblob(100), randomblob(100) FROM x; + + SELECT count(*) FROM t2; + SELECT count(*) FROM t1; + PRAGMA temp.page_count; +} {500 10 292} + +do_execsql_test 4.1.4 { PRAGMA temp.integrity_check } {ok} + +#------------------------------------------------------------------------- +# +reset_db +do_execsql_test 5.1.1 { + PRAGMA main.cache_size = 10; + PRAGMA temp.cache_size = 10; + + CREATE TEMP TABLE t2(a, b); + CREATE INDEX i2 ON t2(a, b); + WITH x(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM x WHERE i<500 ) + INSERT INTO t2 SELECT randomblob(100), randomblob(100) FROM x; + + CREATE TEMP TABLE t1(a, b); + CREATE INDEX i1 ON t1(a, b); + INSERT INTO t1 VALUES(1, 2); + + PRAGMA temp.page_count; +} {286} + +do_execsql_test 5.1.2 { + BEGIN; + UPDATE t1 SET a=2; + UPDATE t2 SET a=randomblob(100); + SELECT count(*) FROM t1; + ROLLBACK; +} {1} + +do_execsql_test 5.1.3 { + UPDATE t2 SET a=randomblob(100); + + SELECT * FROM t1; +} {1 2} + +do_execsql_test 5.1.4 { PRAGMA temp.integrity_check } {ok} + +finish_test + From 40dc357a01ae544643b53c58c92fe0393cc47299 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 5 Apr 2016 23:39:53 +0000 Subject: [PATCH 0255/1484] Remove an unnecessary branch in the sqlite3LogEstToInt() routine. FossilOrigin-Name: da81d7afeb0566a09a505ba5fce901e991e4a029 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/util.c | 1 - 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 04532b4880..971e4ecd4c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Carry\stable\scolumn\stypes\sthrough\sinto\sVIEW\sdefinitions,\swhere\spossible. -D 2016-04-05T20:59:12.069 +C Remove\san\sunnecessary\sbranch\sin\sthe\ssqlite3LogEstToInt()\sroutine. +D 2016-04-05T23:39:53.536 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1f123a0757f6f04f0341accb46457e116817159a @@ -439,7 +439,7 @@ F src/treeview.c e4b41a37530a191579d3c53142cc44ee2eb99373 F src/trigger.c e14840ee0c3e549e758ec9bf3e4146e166002280 F src/update.c 3e67ab3c0814635f355fb1f8ab010a2b9e016e7d F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c -F src/util.c 8873d696c9ccc4206058c402e09e101f1b81561a +F src/util.c 19509465217b673b38d5804a72778908b138953f F src/vacuum.c feb1eabb20987983d9350cad98299b21fa811f52 F src/vdbe.c 936166d3dc5aa00364877603f545707896c1519e F src/vdbe.h c16ba943d407baa1c7085eefea73a063fc631863 @@ -1482,7 +1482,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 0bf9926c7a7865694edd48535777248e73d86bbf -R c7f5a7683cc4a0d14362e20e6891847a +P fb555c3c2af7f5e62ff839658f4fba7b645d3a68 +R 7154c3cc804ee2fc9b7c1578477c3cf7 U drh -Z ec8e2cff7764d808576889c190bbf60c +Z c58518044f9cf200f41dd76757fdb4e4 diff --git a/manifest.uuid b/manifest.uuid index d21138d9ad..ca7e7bdc29 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fb555c3c2af7f5e62ff839658f4fba7b645d3a68 \ No newline at end of file +da81d7afeb0566a09a505ba5fce901e991e4a029 \ No newline at end of file diff --git a/src/util.c b/src/util.c index 08b0c46a5c..d2c6ec8e80 100644 --- a/src/util.c +++ b/src/util.c @@ -1448,7 +1448,6 @@ LogEst sqlite3LogEstFromDouble(double x){ */ u64 sqlite3LogEstToInt(LogEst x){ u64 n; - if( x<10 ) return 1; n = x%10; x /= 10; if( n>=5 ) n -= 2; From d87efd7221c3a4edefe09bd2c18bf29b042ad542 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 6 Apr 2016 15:39:03 +0000 Subject: [PATCH 0256/1484] Add tests to this branch. Fix a problem with temporary databases in auto-vacuum mode. FossilOrigin-Name: afe9bd9b4b5dc98dccf1bced80567515ab5c0117 --- manifest | 17 ++++++------- manifest.uuid | 2 +- src/pager.c | 8 +++--- test/temptable2.test | 58 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 70 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index 261df5d6bf..0084c64a0f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Defer\sopening\sthe\sfile\sused\sfor\sthe\stemp\sdatabase\s(where\sCREATE\sTEMP\sTABLE\stables\sare\sstored)\suntil\sthe\sdatabase\sis\stoo\slarge\sto\sreside\sentirely\swithin\sthe\scache.\sThere\sare\slikely\sstill\sproblems\son\sthis\sbranch. -D 2016-04-05T21:07:58.179 +C Add\stests\sto\sthis\sbranch.\sFix\sa\sproblem\swith\stemporary\sdatabases\sin\sauto-vacuum\smode. +D 2016-04-06T15:39:03.038 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1f123a0757f6f04f0341accb46457e116817159a @@ -362,7 +362,7 @@ F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa F src/os_unix.c b1ccb273771f41dbdbe0ba7c1ad63c38ad5972ec F src/os_win.c b3ba9573d8d893e70a6a8015bbee572ecf7ffbef F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca -F src/pager.c 123dbae47bf27915a4b567915ff8dcc27cfcd369 +F src/pager.c 685f3cc08d045f64d20133144fb9a437914ea4c7 F src/pager.h e1d38a2f14849e219df0f91f8323504d134c8a56 F src/parse.y 5ea8c81c5c41b27887f41b4a7e1c58470d7d3821 F src/pcache.c e9c00846d3dcdaa75b288c6f16238c2fe2177823 @@ -1110,7 +1110,7 @@ F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930 F test/tclsqlite.test e1306001a0ca92250b691ea6d3cecaca5b6342aa F test/tempdb.test bd92eba8f20e16a9136e434e20b280794de3cdb6 F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30 -F test/temptable2.test f3b198e386f6494082c87accc8780cdf84b36e6d +F test/temptable2.test c16f96e996bf6f587a4df4199c62cf0ac9a1c0ea F test/temptrigger.test 8ec228b0db5d7ebc4ee9b458fc28cb9e7873f5e1 F test/tester.tcl 7b740ee852c55e1e72b6ebe5044acee7aa4e5553 F test/thread001.test 9f22fd3525a307ff42a326b6bc7b0465be1745a5 @@ -1483,10 +1483,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P fb555c3c2af7f5e62ff839658f4fba7b645d3a68 -R f511e5baaeaad693345498b91b98e90f -T *branch * tempfiles-lazy-open -T *sym-tempfiles-lazy-open * -T -sym-trunk * +P be5a549eba6cf8e29cb6b9824fd6d0db9d03ca7f +R 71d9b48ce9c812093890a1f227fcf740 U dan -Z 505ba6148fb8f2c79237e86b07655c1c +Z 749bb77cf880284a6ac38e76d6c94ae0 diff --git a/manifest.uuid b/manifest.uuid index 0e8a9ef130..f61492cdc3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -be5a549eba6cf8e29cb6b9824fd6d0db9d03ca7f \ No newline at end of file +afe9bd9b4b5dc98dccf1bced80567515ab5c0117 \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index 45f54ef30d..3d8df3cdbb 100644 --- a/src/pager.c +++ b/src/pager.c @@ -6815,7 +6815,7 @@ int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, int isCommit){ /* In order to be able to rollback, an in-memory database must journal ** the page we are moving from. */ - if( MEMDB ){ + if( pPager->tempFile ){ rc = sqlite3PagerWrite(pPg); if( rc ) return rc; } @@ -6855,7 +6855,7 @@ int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, int isCommit){ ** the journal needs to be sync()ed before database page pPg->pgno ** can be written to. The caller has already promised not to write to it. */ - if( (pPg->flags&PGHDR_NEED_SYNC) && !isCommit && pPager->tempFile==0 ){ + if( (pPg->flags&PGHDR_NEED_SYNC) && !isCommit /* && pPager->tempFile==0 */ ){ needSyncPgno = pPg->pgno; assert( pPager->journalMode==PAGER_JOURNALMODE_OFF || pageInJournal(pPager, pPg) || pPg->pgno>pPager->dbOrigSize ); @@ -6872,7 +6872,7 @@ int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, int isCommit){ assert( !pPgOld || pPgOld->nRef==1 ); if( pPgOld ){ pPg->flags |= (pPgOld->flags&PGHDR_NEED_SYNC); - if( MEMDB ){ + if( pPager->tempFile ){ /* Do not discard pages from an in-memory database since we might ** need to rollback later. Just move the page out of the way. */ sqlite3PcacheMove(pPgOld, pPager->dbSize+1); @@ -6889,7 +6889,7 @@ int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, int isCommit){ ** to exist, in case the transaction needs to roll back. Use pPgOld ** as the original page since it has already been allocated. */ - if( MEMDB ){ + if( pPager->tempFile ){ assert( pPgOld ); sqlite3PcacheMove(pPgOld, origPgno); sqlite3PagerUnrefNotNull(pPgOld); diff --git a/test/temptable2.test b/test/temptable2.test index daeb206a29..e702410f68 100644 --- a/test/temptable2.test +++ b/test/temptable2.test @@ -153,5 +153,63 @@ do_execsql_test 5.1.3 { do_execsql_test 5.1.4 { PRAGMA temp.integrity_check } {ok} +#------------------------------------------------------------------------- +# Test this: +# +# 1. Page is DIRTY at the start of a transaction. +# 2. Page is written out as part of the transaction. +# 3. Page is then read back in. +# 4. Transaction is rolled back. Is the page now clean or dirty? +# +# This actually does work. Step 4 marks the page as clean. But it also +# writes to the database file itself. So marking it clean is correct - +# the page does match the contents of the db file. +# +reset_db + +do_execsql_test 6.1 { + PRAGMA main.cache_size = 10; + PRAGMA temp.cache_size = 10; + + CREATE TEMP TABLE t1(x); + INSERT INTO t1 VALUES('one'); + + CREATE TEMP TABLE t2(a, b); + CREATE INDEX i2 ON t2(a, b); + WITH x(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM x WHERE i<500 ) + INSERT INTO t2 SELECT randomblob(100), randomblob(100) FROM x; +} + +do_execsql_test 6.2 { + UPDATE t1 SET x='two'; -- step 1 + BEGIN; + UPDATE t2 SET a=randomblob(100); -- step 2 + SELECT * FROM t1; -- step 3 + ROLLBACK; -- step 4 + + SELECT count(*) FROM t2; + SELECT * FROM t1; +} {two 500 two} + +#------------------------------------------------------------------------- + +reset_db +sqlite3 db "" +do_execsql_test 7.1 { + PRAGMA auto_vacuum=INCREMENTAL; + CREATE TABLE t1(x); + INSERT INTO t1 VALUES(zeroblob(900)); + INSERT INTO t1 VALUES(zeroblob(900)); + INSERT INTO t1 SELECT x FROM t1; + INSERT INTO t1 SELECT x FROM t1; + INSERT INTO t1 SELECT x FROM t1; + INSERT INTO t1 SELECT x FROM t1; + BEGIN; + DELETE FROM t1 WHERE rowid%2; + PRAGMA incremental_vacuum(4); + ROLLBACK; + PRAGMA integrity_check; +} {ok} + finish_test From 7f8def285efbf12c337050ac81788e38345909c6 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 6 Apr 2016 16:27:50 +0000 Subject: [PATCH 0257/1484] Fix a problem in test script lock.test. Fix minor issues in pager.c. FossilOrigin-Name: 84de8813c3b4007e3c7c3a286ce13020f2065c7b --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/pager.c | 5 +++-- test/lock.test | 5 +++-- 4 files changed, 14 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 0084c64a0f..fefd0eeca8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\stests\sto\sthis\sbranch.\sFix\sa\sproblem\swith\stemporary\sdatabases\sin\sauto-vacuum\smode. -D 2016-04-06T15:39:03.038 +C Fix\sa\sproblem\sin\stest\sscript\slock.test.\sFix\sminor\sissues\sin\spager.c. +D 2016-04-06T16:27:50.054 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1f123a0757f6f04f0341accb46457e116817159a @@ -362,7 +362,7 @@ F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa F src/os_unix.c b1ccb273771f41dbdbe0ba7c1ad63c38ad5972ec F src/os_win.c b3ba9573d8d893e70a6a8015bbee572ecf7ffbef F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca -F src/pager.c 685f3cc08d045f64d20133144fb9a437914ea4c7 +F src/pager.c 2047e837a5df26c16271e77e6b30021d0cdc98b7 F src/pager.h e1d38a2f14849e219df0f91f8323504d134c8a56 F src/parse.y 5ea8c81c5c41b27887f41b4a7e1c58470d7d3821 F src/pcache.c e9c00846d3dcdaa75b288c6f16238c2fe2177823 @@ -877,7 +877,7 @@ F test/like3.test 3608a2042b6f922f900fbfd5d3ce4e7eca57f7c4 F test/limit.test 0c99a27a87b14c646a9d583c7c89fd06c352663e F test/loadext.test 648cb95f324d1775c54a55c12271b2d1156b633b F test/loadext2.test 0408380b57adca04004247179837a18e866a74f7 -F test/lock.test b984ab9034e7389be0d863fe4e64cbbc4d2028f5 +F test/lock.test be4fe08118fb988fed741f429b7dd5d65e1c90db F test/lock2.test 5242d8ac4e2d59c403aebff606af449b455aceff F test/lock3.test f271375930711ae044080f4fe6d6eda930870d00 F test/lock4.test e175ae13865bc87680607563bafba21f31a26f12 @@ -1483,7 +1483,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P be5a549eba6cf8e29cb6b9824fd6d0db9d03ca7f -R 71d9b48ce9c812093890a1f227fcf740 +P afe9bd9b4b5dc98dccf1bced80567515ab5c0117 +R 35c99f2c80a6bf5e586b897ba6d7e956 U dan -Z 749bb77cf880284a6ac38e76d6c94ae0 +Z 67c50ed57a780aa24194c52733684bdf diff --git a/manifest.uuid b/manifest.uuid index f61492cdc3..832abb0052 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -afe9bd9b4b5dc98dccf1bced80567515ab5c0117 \ No newline at end of file +84de8813c3b4007e3c7c3a286ce13020f2065c7b \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index 3d8df3cdbb..c1c1134047 100644 --- a/src/pager.c +++ b/src/pager.c @@ -6855,7 +6855,7 @@ int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, int isCommit){ ** the journal needs to be sync()ed before database page pPg->pgno ** can be written to. The caller has already promised not to write to it. */ - if( (pPg->flags&PGHDR_NEED_SYNC) && !isCommit /* && pPager->tempFile==0 */ ){ + if( (pPg->flags&PGHDR_NEED_SYNC) && !isCommit ){ needSyncPgno = pPg->pgno; assert( pPager->journalMode==PAGER_JOURNALMODE_OFF || pageInJournal(pPager, pPg) || pPg->pgno>pPager->dbOrigSize ); @@ -7142,7 +7142,8 @@ sqlite3_backup **sqlite3PagerBackupPtr(Pager *pPager){ ** Unless this is an in-memory or temporary database, clear the pager cache. */ void sqlite3PagerClearCache(Pager *pPager){ - if( !MEMDB && pPager->tempFile==0 ) pager_reset(pPager); + assert( MEMDB==0 || pPager->tempFile ); + if( pPager->tempFile==0 ) pager_reset(pPager); } #endif diff --git a/test/lock.test b/test/lock.test index f785c4bb23..534aa3b9a4 100644 --- a/test/lock.test +++ b/test/lock.test @@ -423,8 +423,9 @@ do_test lock-6.5 { # * there exists one or more active read-only statements, and # * a transaction that modified zero database pages is committed. # -set temp_status unlocked -if {$TEMP_STORE>=2} {set temp_status unknown} +#set temp_status unlocked +#if {$TEMP_STORE>=2} {set temp_status unknown} +set temp_status unknown do_test lock-7.1 { set STMT [sqlite3_prepare $DB "SELECT * FROM sqlite_master" -1 TAIL] sqlite3_step $STMT From 9131ab93865d961f6408800f969e3996d78db34e Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 6 Apr 2016 18:20:51 +0000 Subject: [PATCH 0258/1484] For a pager backed by a temp file, store the main journal in memory until it is at least sqlite3_config.nStmtSpill bytes in size. Prevent the backup API from being used to change the page-size of a temp file. FossilOrigin-Name: 84c557010c211595d2ec80b62c63af1c7f4714bd --- manifest | 18 +++++------ manifest.uuid | 2 +- src/pager.c | 30 +++++++++--------- src/test3.c | 6 ++-- test/pragma.test | 15 ++++++++- test/temptable2.test | 74 +++++++++++++++++++++++++++++++++++++++----- 6 files changed, 110 insertions(+), 35 deletions(-) diff --git a/manifest b/manifest index fefd0eeca8..103a4b00bc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\sin\stest\sscript\slock.test.\sFix\sminor\sissues\sin\spager.c. -D 2016-04-06T16:27:50.054 +C For\sa\spager\sbacked\sby\sa\stemp\sfile,\sstore\sthe\smain\sjournal\sin\smemory\suntil\sit\sis\sat\sleast\ssqlite3_config.nStmtSpill\sbytes\sin\ssize.\sPrevent\sthe\sbackup\sAPI\sfrom\sbeing\sused\sto\schange\sthe\spage-size\sof\sa\stemp\sfile. +D 2016-04-06T18:20:51.565 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1f123a0757f6f04f0341accb46457e116817159a @@ -362,7 +362,7 @@ F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa F src/os_unix.c b1ccb273771f41dbdbe0ba7c1ad63c38ad5972ec F src/os_win.c b3ba9573d8d893e70a6a8015bbee572ecf7ffbef F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca -F src/pager.c 2047e837a5df26c16271e77e6b30021d0cdc98b7 +F src/pager.c 91d7462aa2429e30d64c705f75ba36cace90c241 F src/pager.h e1d38a2f14849e219df0f91f8323504d134c8a56 F src/parse.y 5ea8c81c5c41b27887f41b4a7e1c58470d7d3821 F src/pcache.c e9c00846d3dcdaa75b288c6f16238c2fe2177823 @@ -387,7 +387,7 @@ F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 F src/tclsqlite.c 56569acc73d36e836b64aefecbbb709a92ba0077 F src/test1.c 7187b7e924bfc97780e6fd2a40dad94a32bddca0 F src/test2.c 5586f43fcd9a1be0830793cf9d354082c261b25b -F src/test3.c a8887dabbbee3059af338f20d290084a63ed1b0f +F src/test3.c 0df6f8dbb4cbaa7106397c70a271fa6a43659042 F src/test4.c d168f83cc78d02e8d35567bb5630e40dcd85ac1e F src/test5.c 5a34feec76d9b3a86aab30fd4f6cc9c48cbab4c1 F src/test6.c 41cacf3b0dd180823919bf9e1fbab287c9266723 @@ -976,7 +976,7 @@ F test/pcache.test c8acbedd3b6fd0f9a7ca887a83b11d24a007972b F test/pcache2.test af7f3deb1a819f77a6d0d81534e97d1cf62cd442 F test/percentile.test 4243af26b8f3f4555abe166f723715a1f74c77ff F test/permutations.test cd1fa041074ed08eeaa563e4d1bacb0c69337ec1 -F test/pragma.test afbf028be1c35b68f57db8eb015c4a3c59d8f28e +F test/pragma.test 36daccdbfbdd958a5f65c034141ab2bfd959808e F test/pragma2.test e5d5c176360c321344249354c0c16aec46214c9f F test/pragma3.test 3f1984a04657331f838df5c519b443c2088df922 F test/printf.test b3ff34e73d59124140eaf89f7672e21bc2ca5fcc @@ -1110,7 +1110,7 @@ F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930 F test/tclsqlite.test e1306001a0ca92250b691ea6d3cecaca5b6342aa F test/tempdb.test bd92eba8f20e16a9136e434e20b280794de3cdb6 F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30 -F test/temptable2.test c16f96e996bf6f587a4df4199c62cf0ac9a1c0ea +F test/temptable2.test 707c01c00b4a8fd050e0db5dcef448e998b9ddb5 F test/temptrigger.test 8ec228b0db5d7ebc4ee9b458fc28cb9e7873f5e1 F test/tester.tcl 7b740ee852c55e1e72b6ebe5044acee7aa4e5553 F test/thread001.test 9f22fd3525a307ff42a326b6bc7b0465be1745a5 @@ -1483,7 +1483,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P afe9bd9b4b5dc98dccf1bced80567515ab5c0117 -R 35c99f2c80a6bf5e586b897ba6d7e956 +P 84de8813c3b4007e3c7c3a286ce13020f2065c7b +R 54ab030014fa87b230c7ab4f5fdc139b U dan -Z 67c50ed57a780aa24194c52733684bdf +Z dbab9fc4f54135fb156cdc6ccf0d8253 diff --git a/manifest.uuid b/manifest.uuid index 832abb0052..515a3c2874 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -84de8813c3b4007e3c7c3a286ce13020f2065c7b \ No newline at end of file +84c557010c211595d2ec80b62c63af1c7f4714bd \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index c1c1134047..79dbaec5c2 100644 --- a/src/pager.c +++ b/src/pager.c @@ -1170,6 +1170,8 @@ static int jrnlBufferSize(Pager *pPager){ return JOURNAL_HDR_SZ(pPager) + JOURNAL_PG_SZ(pPager); } +#else +# define jrnlBufferSize(x) 0 #endif /* @@ -5562,24 +5564,24 @@ static int pager_open_journal(Pager *pPager){ if( pPager->journalMode==PAGER_JOURNALMODE_MEMORY ){ sqlite3MemJournalOpen(pPager->jfd); }else{ - const int flags = /* VFS flags to open journal file */ - SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE| - (pPager->tempFile ? - (SQLITE_OPEN_DELETEONCLOSE|SQLITE_OPEN_TEMP_JOURNAL): - (SQLITE_OPEN_MAIN_JOURNAL) - ); + int flags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE; + int nSpill; + if( pPager->tempFile ){ + flags |= (SQLITE_OPEN_DELETEONCLOSE|SQLITE_OPEN_TEMP_JOURNAL); + nSpill = sqlite3Config.nStmtSpill; + }else{ + flags |= SQLITE_OPEN_MAIN_JOURNAL; + nSpill = jrnlBufferSize(pPager); + } + /* Verify that the database still has the same name as it did when ** it was originally opened. */ rc = databaseIsUnmoved(pPager); if( rc==SQLITE_OK ){ -#ifdef SQLITE_ENABLE_ATOMIC_WRITE - rc = sqlite3JournalOpen( - pVfs, pPager->zJournal, pPager->jfd, flags, jrnlBufferSize(pPager) + rc = sqlite3JournalOpen ( + pVfs, pPager->zJournal, pPager->jfd, flags, nSpill ); -#else - rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, flags, 0); -#endif } } assert( rc!=SQLITE_OK || isOpen(pPager->jfd) ); @@ -6532,10 +6534,10 @@ void sqlite3PagerCacheStat(Pager *pPager, int eStat, int reset, int *pnVal){ } /* -** Return true if this is an in-memory pager. +** Return true if this is an in-memory or temp-file backed pager. */ int sqlite3PagerIsMemdb(Pager *pPager){ - return MEMDB; + return pPager->tempFile; } /* diff --git a/src/test3.c b/src/test3.c index 2a41068e5f..817e8a88fd 100644 --- a/src/test3.c +++ b/src/test3.c @@ -547,7 +547,7 @@ static int btree_from_db( /* ** Usage: btree_ismemdb ID ** -** Return true if the B-Tree is in-memory. +** Return true if the B-Tree is currently stored entirely in memory. */ static int btree_ismemdb( void *NotUsed, @@ -557,6 +557,7 @@ static int btree_ismemdb( ){ Btree *pBt; int res; + sqlite3_file *pFile; if( argc!=2 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], @@ -566,7 +567,8 @@ static int btree_ismemdb( pBt = sqlite3TestTextToPtr(argv[1]); sqlite3_mutex_enter(pBt->db->mutex); sqlite3BtreeEnter(pBt); - res = sqlite3PagerIsMemdb(sqlite3BtreePager(pBt)); + pFile = sqlite3PagerFile(sqlite3BtreePager(pBt)); + res = (pFile->pMethods==0); sqlite3BtreeLeave(pBt); sqlite3_mutex_leave(pBt->db->mutex); Tcl_SetObjResult(interp, Tcl_NewBooleanObj(res)); diff --git a/test/pragma.test b/test/pragma.test index acbe74599e..2c73090551 100644 --- a/test/pragma.test +++ b/test/pragma.test @@ -1083,7 +1083,20 @@ do_test pragma-8.2.15 { # "memory" or "disk" as appropriate. # proc check_temp_store {} { - db eval {CREATE TEMP TABLE IF NOT EXISTS a(b)} + db eval { + PRAGMA temp.cache_size = 1; + CREATE TEMP TABLE IF NOT EXISTS a(b); + DELETE FROM a; + INSERT INTO a VALUES(randomblob(1000)); + INSERT INTO a SELECT * FROM a; + INSERT INTO a SELECT * FROM a; + INSERT INTO a SELECT * FROM a; + INSERT INTO a SELECT * FROM a; + INSERT INTO a SELECT * FROM a; + INSERT INTO a SELECT * FROM a; + INSERT INTO a SELECT * FROM a; + INSERT INTO a SELECT * FROM a; + } db eval {PRAGMA database_list} { if {$name=="temp"} { set bt [btree_from_db db 1] diff --git a/test/temptable2.test b/test/temptable2.test index e702410f68..e87ffa89d9 100644 --- a/test/temptable2.test +++ b/test/temptable2.test @@ -113,8 +113,12 @@ do_execsql_test 4.1.3 { SELECT count(*) FROM t2; SELECT count(*) FROM t1; - PRAGMA temp.page_count; -} {500 10 292} +} {500 10} + +do_test 4.1.4 { + set n [db one { PRAGMA temp.page_count }] + expr ($n >280 && $n < 300) +} 1 do_execsql_test 4.1.4 { PRAGMA temp.integrity_check } {ok} @@ -133,11 +137,14 @@ do_execsql_test 5.1.1 { CREATE TEMP TABLE t1(a, b); CREATE INDEX i1 ON t1(a, b); INSERT INTO t1 VALUES(1, 2); +} - PRAGMA temp.page_count; -} {286} +do_test 5.1.2 { + set n [db one { PRAGMA temp.page_count }] + expr ($n > 280 && $n < 290) +} {1} -do_execsql_test 5.1.2 { +do_execsql_test 5.1.3 { BEGIN; UPDATE t1 SET a=2; UPDATE t2 SET a=randomblob(100); @@ -145,13 +152,13 @@ do_execsql_test 5.1.2 { ROLLBACK; } {1} -do_execsql_test 5.1.3 { +do_execsql_test 5.1.4 { UPDATE t2 SET a=randomblob(100); SELECT * FROM t1; } {1 2} -do_execsql_test 5.1.4 { PRAGMA temp.integrity_check } {ok} +do_execsql_test 5.1.5 { PRAGMA temp.integrity_check } {ok} #------------------------------------------------------------------------- # Test this: @@ -192,7 +199,7 @@ do_execsql_test 6.2 { } {two 500 two} #------------------------------------------------------------------------- - +# reset_db sqlite3 db "" do_execsql_test 7.1 { @@ -211,5 +218,56 @@ do_execsql_test 7.1 { PRAGMA integrity_check; } {ok} +#------------------------------------------------------------------------- +# Try changing the page size using a backup operation when pages are +# stored in main-memory only. +# +reset_db +do_execsql_test 8.1 { + CREATE TABLE t2(a, b); + CREATE INDEX i2 ON t2(a, b); + WITH x(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM x WHERE i<20 ) + INSERT INTO t2 SELECT randomblob(100), randomblob(100) FROM x; + PRAGMA page_count; +} {13} + +do_test 8.2 { + sqlite3 tmp "" + execsql { + PRAGMA page_size = 8192; + CREATE TABLE t1(a, b); + CREATE INDEX i1 ON t1(a, b); + WITH x(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM x WHERE i<100 ) + INSERT INTO t1 SELECT randomblob(100), randomblob(100) FROM x; + PRAGMA page_count; + } tmp +} {10} + +do_test 8.3 { + sqlite3_backup B tmp main db main + B step 5 + B finish +} {SQLITE_READONLY} + +do_test 8.4 { + execsql { + SELECT count(*) FROM t1; + PRAGMA integrity_check; + PRAGMA page_size; + } tmp +} {100 ok 8192} + +do_test 8.5 { + tmp eval { UPDATE t1 SET a=randomblob(100) } +} {} + +do_test 8.6 { + sqlite3_backup B tmp main db main + B step 1000 + B finish +} {SQLITE_READONLY} + +tmp close + finish_test From f878e6e1a76d0416ffa9987a406bf362cddc4e0e Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 7 Apr 2016 13:45:20 +0000 Subject: [PATCH 0259/1484] Update comments on the unix file locking protocol. No changes to code. FossilOrigin-Name: 716b20de4306de1653ba5bcdbfb8d210d2d46e1a --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/os_unix.c | 17 +++++++++-------- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index 971e4ecd4c..d741c58439 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\san\sunnecessary\sbranch\sin\sthe\ssqlite3LogEstToInt()\sroutine. -D 2016-04-05T23:39:53.536 +C Update\scomments\son\sthe\sunix\sfile\slocking\sprotocol.\s\sNo\schanges\sto\scode. +D 2016-04-07T13:45:20.032 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1f123a0757f6f04f0341accb46457e116817159a @@ -359,7 +359,7 @@ F src/os.c ca10edb445ad2c5fdc7285b49d72bcdf261fa23e F src/os.h 91ff889115ecd01f436d3611f7f5ea4dc12d92f1 F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85 F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa -F src/os_unix.c b1ccb273771f41dbdbe0ba7c1ad63c38ad5972ec +F src/os_unix.c bde4844f0849cab5924c6a81178f8500774ce76b F src/os_win.c b3ba9573d8d893e70a6a8015bbee572ecf7ffbef F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c 38718a019ca762ba4f6795425d5a54db70d1790d @@ -1482,7 +1482,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P fb555c3c2af7f5e62ff839658f4fba7b645d3a68 -R 7154c3cc804ee2fc9b7c1578477c3cf7 +P da81d7afeb0566a09a505ba5fce901e991e4a029 +R c31dba9b364f6a5e65569f6b94115698 U drh -Z c58518044f9cf200f41dd76757fdb4e4 +Z 3e3e5fb3cba3f9bdb43d997a64c47647 diff --git a/manifest.uuid b/manifest.uuid index ca7e7bdc29..5c2f6169fa 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -da81d7afeb0566a09a505ba5fce901e991e4a029 \ No newline at end of file +716b20de4306de1653ba5bcdbfb8d210d2d46e1a \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index 6d1bb0b46d..a797541e8f 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -1502,7 +1502,7 @@ static int unixLock(sqlite3_file *id, int eFileLock){ ** lock transitions in terms of the POSIX advisory shared and exclusive ** lock primitives (called read-locks and write-locks below, to avoid ** confusion with SQLite lock names). The algorithms are complicated - ** slightly in order to be compatible with windows systems simultaneously + ** slightly in order to be compatible with Windows95 systems simultaneously ** accessing the same database file, in case that is ever required. ** ** Symbols defined in os.h indentify the 'pending byte' and the 'reserved @@ -1510,8 +1510,14 @@ static int unixLock(sqlite3_file *id, int eFileLock){ ** range', a range of 510 bytes at a well known offset. ** ** To obtain a SHARED lock, a read-lock is obtained on the 'pending - ** byte'. If this is successful, a random byte from the 'shared byte - ** range' is read-locked and the lock on the 'pending byte' released. + ** byte'. If this is successful, 'shared byte range' is read-locked + ** and the lock on the 'pending byte' released. (Legacy note: When + ** SQLite was first developed, Windows95 systems were still very common, + ** and Widnows95 lacks a shared-lock capability. So on Windows95, a + ** single randomly selected by from the 'shared byte range' is locked. + ** Windows95 is now pretty much extinct, but this work-around for the + ** lack of shared-locks on Windows95 lives on, for backwards + ** compatibility.) ** ** A process may only obtain a RESERVED lock after it has a SHARED lock. ** A RESERVED lock is implemented by grabbing a write-lock on the @@ -1530,11 +1536,6 @@ static int unixLock(sqlite3_file *id, int eFileLock){ ** range'. Since all other locks require a read-lock on one of the bytes ** within this range, this ensures that no other locks are held on the ** database. - ** - ** The reason a single byte cannot be used instead of the 'shared byte - ** range' is that some versions of windows do not support read-locks. By - ** locking a random byte from a range, concurrent SHARED locks may exist - ** even if the locking primitive used is always a write-lock. */ int rc = SQLITE_OK; unixFile *pFile = (unixFile*)id; From 3b42be9178b49c8735e747252d0755290a561dd2 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 7 Apr 2016 14:01:10 +0000 Subject: [PATCH 0260/1484] Remove an unnecessary test for a NULL pointer in freeP4(). FossilOrigin-Name: e84e88e31b67afe42e2494d984ab1cafd107465a --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbeaux.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index d741c58439..5cec49ad32 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\scomments\son\sthe\sunix\sfile\slocking\sprotocol.\s\sNo\schanges\sto\scode. -D 2016-04-07T13:45:20.032 +C Remove\san\sunnecessary\stest\sfor\sa\sNULL\spointer\sin\sfreeP4(). +D 2016-04-07T14:01:10.659 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1f123a0757f6f04f0341accb46457e116817159a @@ -445,7 +445,7 @@ F src/vdbe.c 936166d3dc5aa00364877603f545707896c1519e F src/vdbe.h c16ba943d407baa1c7085eefea73a063fc631863 F src/vdbeInt.h ddb157974436d87652de7dc641f7191496d9a8cd F src/vdbeapi.c ba85b78fe08dc4a9ce747e62c89a2b4a4547e74c -F src/vdbeaux.c fa06ba5441714160ab5f64422660ee286968672f +F src/vdbeaux.c a61e39702bef0b8eae9e9e97658aef484f7dbe4d F src/vdbeblob.c c9f2f494b911c6fa34efd9803f0a10807da80f77 F src/vdbemem.c 5cfef60e60e19cab6275d1b975bf4c791d575beb F src/vdbesort.c 307460bfa4de4d1c3901fcd42089159131e34062 @@ -1482,7 +1482,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P da81d7afeb0566a09a505ba5fce901e991e4a029 -R c31dba9b364f6a5e65569f6b94115698 +P 716b20de4306de1653ba5bcdbfb8d210d2d46e1a +R aaba6ad1b1539c59b560283e3f15aaba U drh -Z 3e3e5fb3cba3f9bdb43d997a64c47647 +Z cf4238e507b7767ffc7c561acb505e47 diff --git a/manifest.uuid b/manifest.uuid index 5c2f6169fa..73cf31f293 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -716b20de4306de1653ba5bcdbfb8d210d2d46e1a \ No newline at end of file +e84e88e31b67afe42e2494d984ab1cafd107465a \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 48d1b5ae15..7e514fa36a 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -791,7 +791,7 @@ static void vdbeFreeOpArray(sqlite3 *, Op *, int); ** Delete a P4 value if necessary. */ static void freeP4(sqlite3 *db, int p4type, void *p4){ - if( p4 ){ + /*if( p4 )*/{ assert( db ); switch( p4type ){ case P4_FUNCCTX: { From be5000d6bf1affac85e8c9330c4b4c511563319d Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 7 Apr 2016 14:05:20 +0000 Subject: [PATCH 0261/1484] Instead of just commenting out the unneeded code in the previous check-in, remove it completely. FossilOrigin-Name: 8415d4848ab36ca33b23d1fad6b063544de04a3b --- manifest | 12 ++++---- manifest.uuid | 2 +- src/vdbeaux.c | 84 +++++++++++++++++++++++++-------------------------- 3 files changed, 48 insertions(+), 50 deletions(-) diff --git a/manifest b/manifest index 5cec49ad32..d866e27c78 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\san\sunnecessary\stest\sfor\sa\sNULL\spointer\sin\sfreeP4(). -D 2016-04-07T14:01:10.659 +C Instead\sof\sjust\scommenting\sout\sthe\sunneeded\scode\sin\sthe\sprevious\scheck-in,\nremove\sit\scompletely. +D 2016-04-07T14:05:20.785 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1f123a0757f6f04f0341accb46457e116817159a @@ -445,7 +445,7 @@ F src/vdbe.c 936166d3dc5aa00364877603f545707896c1519e F src/vdbe.h c16ba943d407baa1c7085eefea73a063fc631863 F src/vdbeInt.h ddb157974436d87652de7dc641f7191496d9a8cd F src/vdbeapi.c ba85b78fe08dc4a9ce747e62c89a2b4a4547e74c -F src/vdbeaux.c a61e39702bef0b8eae9e9e97658aef484f7dbe4d +F src/vdbeaux.c 749b2a346cd2eba483e05825553406da1065d03e F src/vdbeblob.c c9f2f494b911c6fa34efd9803f0a10807da80f77 F src/vdbemem.c 5cfef60e60e19cab6275d1b975bf4c791d575beb F src/vdbesort.c 307460bfa4de4d1c3901fcd42089159131e34062 @@ -1482,7 +1482,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 716b20de4306de1653ba5bcdbfb8d210d2d46e1a -R aaba6ad1b1539c59b560283e3f15aaba +P e84e88e31b67afe42e2494d984ab1cafd107465a +R 498c228ba25f81bda5f3077b10bd4000 U drh -Z cf4238e507b7767ffc7c561acb505e47 +Z 41c10e3b5fbbcc81e08050bb9e8f982f diff --git a/manifest.uuid b/manifest.uuid index 73cf31f293..85f661be96 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e84e88e31b67afe42e2494d984ab1cafd107465a \ No newline at end of file +8415d4848ab36ca33b23d1fad6b063544de04a3b \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 7e514fa36a..b3526e014a 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -791,52 +791,50 @@ static void vdbeFreeOpArray(sqlite3 *, Op *, int); ** Delete a P4 value if necessary. */ static void freeP4(sqlite3 *db, int p4type, void *p4){ - /*if( p4 )*/{ - assert( db ); - switch( p4type ){ - case P4_FUNCCTX: { - freeEphemeralFunction(db, ((sqlite3_context*)p4)->pFunc); - /* Fall through into the next case */ - } - case P4_REAL: - case P4_INT64: - case P4_DYNAMIC: - case P4_INTARRAY: { - sqlite3DbFree(db, p4); - break; - } - case P4_KEYINFO: { - if( db->pnBytesFreed==0 ) sqlite3KeyInfoUnref((KeyInfo*)p4); - break; - } + assert( db ); + switch( p4type ){ + case P4_FUNCCTX: { + freeEphemeralFunction(db, ((sqlite3_context*)p4)->pFunc); + /* Fall through into the next case */ + } + case P4_REAL: + case P4_INT64: + case P4_DYNAMIC: + case P4_INTARRAY: { + sqlite3DbFree(db, p4); + break; + } + case P4_KEYINFO: { + if( db->pnBytesFreed==0 ) sqlite3KeyInfoUnref((KeyInfo*)p4); + break; + } #ifdef SQLITE_ENABLE_CURSOR_HINTS - case P4_EXPR: { - sqlite3ExprDelete(db, (Expr*)p4); - break; - } + case P4_EXPR: { + sqlite3ExprDelete(db, (Expr*)p4); + break; + } #endif - case P4_MPRINTF: { - if( db->pnBytesFreed==0 ) sqlite3_free(p4); - break; - } - case P4_FUNCDEF: { - freeEphemeralFunction(db, (FuncDef*)p4); - break; - } - case P4_MEM: { - if( db->pnBytesFreed==0 ){ - sqlite3ValueFree((sqlite3_value*)p4); - }else{ - Mem *p = (Mem*)p4; - if( p->szMalloc ) sqlite3DbFree(db, p->zMalloc); - sqlite3DbFree(db, p); - } - break; - } - case P4_VTAB : { - if( db->pnBytesFreed==0 ) sqlite3VtabUnlock((VTable *)p4); - break; + case P4_MPRINTF: { + if( db->pnBytesFreed==0 ) sqlite3_free(p4); + break; + } + case P4_FUNCDEF: { + freeEphemeralFunction(db, (FuncDef*)p4); + break; + } + case P4_MEM: { + if( db->pnBytesFreed==0 ){ + sqlite3ValueFree((sqlite3_value*)p4); + }else{ + Mem *p = (Mem*)p4; + if( p->szMalloc ) sqlite3DbFree(db, p->zMalloc); + sqlite3DbFree(db, p); } + break; + } + case P4_VTAB : { + if( db->pnBytesFreed==0 ) sqlite3VtabUnlock((VTable *)p4); + break; } } } From 45c3c663856a7e7aeea935ee3fd4509acf598cd1 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 7 Apr 2016 14:16:16 +0000 Subject: [PATCH 0262/1484] Avoid decrementing a pointer off the front end of the buffer in OP_MakeRecord. FossilOrigin-Name: 153135bfb3b8f7c407ccf36571e2d4d5afe28ea3 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 4 +++- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index d866e27c78..54bbc7ace8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Instead\sof\sjust\scommenting\sout\sthe\sunneeded\scode\sin\sthe\sprevious\scheck-in,\nremove\sit\scompletely. -D 2016-04-07T14:05:20.785 +C Avoid\sdecrementing\sa\spointer\soff\sthe\sfront\send\sof\sthe\sbuffer\sin\sOP_MakeRecord. +D 2016-04-07T14:16:16.723 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1f123a0757f6f04f0341accb46457e116817159a @@ -441,7 +441,7 @@ F src/update.c 3e67ab3c0814635f355fb1f8ab010a2b9e016e7d F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 19509465217b673b38d5804a72778908b138953f F src/vacuum.c feb1eabb20987983d9350cad98299b21fa811f52 -F src/vdbe.c 936166d3dc5aa00364877603f545707896c1519e +F src/vdbe.c e16e8625829858b2bf343c3cdd72bb43eab7d643 F src/vdbe.h c16ba943d407baa1c7085eefea73a063fc631863 F src/vdbeInt.h ddb157974436d87652de7dc641f7191496d9a8cd F src/vdbeapi.c ba85b78fe08dc4a9ce747e62c89a2b4a4547e74c @@ -1482,7 +1482,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e84e88e31b67afe42e2494d984ab1cafd107465a -R 498c228ba25f81bda5f3077b10bd4000 +P 8415d4848ab36ca33b23d1fad6b063544de04a3b +R 03453ebf1870335c86f4514ee1d5c7ac U drh -Z 41c10e3b5fbbcc81e08050bb9e8f982f +Z 0a2d3c19f1c3d2a6467caf636e91907c diff --git a/manifest.uuid b/manifest.uuid index 85f661be96..b3cd228a8b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8415d4848ab36ca33b23d1fad6b063544de04a3b \ No newline at end of file +153135bfb3b8f7c407ccf36571e2d4d5afe28ea3 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index f5b00d824a..593ea40806 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2755,7 +2755,9 @@ case OP_MakeRecord: { testcase( serial_type==127 ); testcase( serial_type==128 ); nHdr += serial_type<=127 ? 1 : sqlite3VarintLen(serial_type); - }while( (--pRec)>=pData0 ); + if( pRec==pData0 ) break; + pRec--; + }while(1); /* EVIDENCE-OF: R-22564-11647 The header begins with a single varint ** which determines the total number of bytes in the header. The varint From 38b3dde00e766eb3e121b947c5c2c527d329503c Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 7 Apr 2016 18:42:23 +0000 Subject: [PATCH 0263/1484] Prevent the in-memory journal read cursor from entering an inconsistent state when it reads the last few bytes out of the journal file. Fix for ticket [7f7f8026eda38]. FossilOrigin-Name: c4b9c611bdcd85f31d68aaf114ee34a9f27eba6d --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/memjournal.c | 4 +++- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 54bbc7ace8..56e23c1277 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sdecrementing\sa\spointer\soff\sthe\sfront\send\sof\sthe\sbuffer\sin\sOP_MakeRecord. -D 2016-04-07T14:16:16.723 +C Prevent\sthe\sin-memory\sjournal\sread\scursor\sfrom\sentering\san\sinconsistent\sstate\nwhen\sit\sreads\sthe\slast\sfew\sbytes\sout\sof\sthe\sjournal\sfile.\s\sFix\sfor\nticket\s[7f7f8026eda38]. +D 2016-04-07T18:42:23.186 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1f123a0757f6f04f0341accb46457e116817159a @@ -347,7 +347,7 @@ F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3 F src/mem3.c 8768ac94694f31ffaf8b4d0ea5dc08af7010a35a F src/mem5.c 9bf955937b07f8c32541c8a9991f33ce3173d944 -F src/memjournal.c 5253fd4335a8d9c64e5df25cb9da6329af5242c7 +F src/memjournal.c 2815ef7684671d93a1ec6a31e1e63c45de4b4d31 F src/msvc.h d9ba56c6851227ab44b3f228a35f3f5772296495 F src/mutex.c 8e45800ee78e0cd1f1f3fe8e398853307f4a085c F src/mutex.h 779d588e3b7756ec3ecf7d78cde1d84aba414f85 @@ -1482,7 +1482,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 8415d4848ab36ca33b23d1fad6b063544de04a3b -R 03453ebf1870335c86f4514ee1d5c7ac +P 153135bfb3b8f7c407ccf36571e2d4d5afe28ea3 +R 79f1b101d10963168c95e54e3a571e58 U drh -Z 0a2d3c19f1c3d2a6467caf636e91907c +Z fee1386714e022b25f3a73738d6ccce7 diff --git a/manifest.uuid b/manifest.uuid index b3cd228a8b..c077c241b6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -153135bfb3b8f7c407ccf36571e2d4d5afe28ea3 \ No newline at end of file +c4b9c611bdcd85f31d68aaf114ee34a9f27eba6d \ No newline at end of file diff --git a/src/memjournal.c b/src/memjournal.c index 4f0efc174e..fbfa7cb802 100644 --- a/src/memjournal.c +++ b/src/memjournal.c @@ -94,6 +94,7 @@ static int memjrnlRead( #endif assert( (iAmt+iOfst)<=p->endpoint.iOffset ); + assert( p->readpoint.iOffset==0 || p->readpoint.pChunk!=0 ); if( p->readpoint.iOffset!=iOfst || iOfst==0 ){ sqlite3_int64 iOff = 0; for(pChunk=p->pFirst; @@ -104,6 +105,7 @@ static int memjrnlRead( } }else{ pChunk = p->readpoint.pChunk; + assert( pChunk!=0 ); } iChunkOffset = (int)(iOfst%p->nChunkSize); @@ -115,7 +117,7 @@ static int memjrnlRead( nRead -= iSpace; iChunkOffset = 0; } while( nRead>=0 && (pChunk=pChunk->pNext)!=0 && nRead>0 ); - p->readpoint.iOffset = iOfst+iAmt; + p->readpoint.iOffset = pChunk ? iOfst+iAmt : 0; p->readpoint.pChunk = pChunk; return SQLITE_OK; From dca595c4a363e919105d5308bc4c61132c08fbc5 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 7 Apr 2016 21:14:35 +0000 Subject: [PATCH 0264/1484] Add test cases for ticket [7f7f8026eda387d544]. FossilOrigin-Name: 87aa9357fbe6749bae60e30af54ca16e48678802 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/savepoint7.test | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 41 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 56e23c1277..2fe24961ad 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Prevent\sthe\sin-memory\sjournal\sread\scursor\sfrom\sentering\san\sinconsistent\sstate\nwhen\sit\sreads\sthe\slast\sfew\sbytes\sout\sof\sthe\sjournal\sfile.\s\sFix\sfor\nticket\s[7f7f8026eda38]. -D 2016-04-07T18:42:23.186 +C Add\stest\scases\sfor\sticket\s[7f7f8026eda387d544]. +D 2016-04-07T21:14:35.631 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1f123a0757f6f04f0341accb46457e116817159a @@ -1011,7 +1011,7 @@ F test/savepoint2.test 9b8543940572a2f01a18298c3135ad0c9f4f67d7 F test/savepoint4.test c8f8159ade6d2acd9128be61e1230f1c1edc6cc0 F test/savepoint5.test 0735db177e0ebbaedc39812c8d065075d563c4fd F test/savepoint6.test f41279c5e137139fa5c21485773332c7adb98cd7 -F test/savepoint7.test db3db281486c925095f305aad09fe806e5188ff3 +F test/savepoint7.test cde525ea3075283eb950cdcdefe23ead4f700daa F test/savepointfault.test f044eac64b59f09746c7020ee261734de82bf9b2 F test/scanstatus.test 5253c219e331318a437f436268e0e82345700285 F test/schema.test 8f7999be894260f151adf15c2c7540f1c6d6a481 @@ -1482,7 +1482,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 153135bfb3b8f7c407ccf36571e2d4d5afe28ea3 -R 79f1b101d10963168c95e54e3a571e58 +P c4b9c611bdcd85f31d68aaf114ee34a9f27eba6d +R 761448207abe334cc70f1f29da291a77 U drh -Z fee1386714e022b25f3a73738d6ccce7 +Z 2b1e9b9a1cc02d13e96c99c5d4c59d63 diff --git a/manifest.uuid b/manifest.uuid index c077c241b6..a8908af92e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c4b9c611bdcd85f31d68aaf114ee34a9f27eba6d \ No newline at end of file +87aa9357fbe6749bae60e30af54ca16e48678802 \ No newline at end of file diff --git a/test/savepoint7.test b/test/savepoint7.test index d8a02f1f80..59c3cd6cdc 100644 --- a/test/savepoint7.test +++ b/test/savepoint7.test @@ -95,4 +95,38 @@ do_test savepoint7-2.2 { list $rc $msg [db eval {SELECT * FROM t2}] } {1 {abort due to ROLLBACK} {}} +# Ticket: https://www.sqlite.org/src/tktview/7f7f8026eda387d544b +# Segfault in the in-memory journal logic triggered by a tricky +# combination of SAVEPOINT operations. +# +unset -nocomplain i +for {set i 248} {$i<=253} {incr i} { + do_test savepoint7-3.$i { + db close + forcedelete test.db + sqlite3 db test.db + db eval { + PRAGMA page_size=1024; + PRAGMA temp_store=MEMORY; + BEGIN; + CREATE TABLE t1(x INTEGER PRIMARY KEY, y TEXT); + WITH RECURSIVE c(x) AS (VALUES(1) UNION SELECT x+1 FROM c WHERE x<$::i) + INSERT INTO t1(x,y) SELECT x*10, printf('%04d%.800c',x,'*') FROM c; + SAVEPOINT one; + SELECT count(*) FROM t1; + WITH RECURSIVE c(x) AS (VALUES(1) UNION SELECT x+1 FROM c WHERE x<$::i) + INSERT INTO t1(x,y) SELECT x*10+1, printf('%04d%.800c',x,'*') FROM c; + ROLLBACK TO one; + SELECT count(*) FROM t1; + SAVEPOINT twoB; + WITH RECURSIVE c(x) AS (VALUES(1) UNION SELECT x+1 FROM c WHERE x<10) + INSERT INTO t1(x,y) SELECT x*10+2, printf('%04d%.800c',x,'*') FROM c; + ROLLBACK TO twoB; + RELEASE one; + COMMIT; + } + } [list $i $i] +} + + finish_test From 11b264019ca5d5566ce65d4b0f7c949c945e4952 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 8 Apr 2016 19:44:31 +0000 Subject: [PATCH 0265/1484] Update documentation for sqlite3_snapshot_open(). No code changes. FossilOrigin-Name: 1dfa5234d3ee38c6af2d18a6294afa93232821e7 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/sqlite.h.in | 27 ++++++++++++++++++--------- 3 files changed, 25 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index 2fe24961ad..391bb710ba 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\stest\scases\sfor\sticket\s[7f7f8026eda387d544]. -D 2016-04-07T21:14:35.631 +C Update\sdocumentation\sfor\ssqlite3_snapshot_open().\s\sNo\scode\schanges. +D 2016-04-08T19:44:31.621 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1f123a0757f6f04f0341accb46457e116817159a @@ -377,7 +377,7 @@ F src/resolve.c b8f7174e5f8c33c44ded3a25a973d0bb89228c20 F src/rowset.c 9fe4b3ad7cc00944386bb600233d8f523de07a6e F src/select.c d9b8628acb98f1a38921888d823a6b70c7a7774b F src/shell.c b7922fa264f8c8d72a5ec6dd0b091e15a93c4de5 -F src/sqlite.h.in 7f437b068314f053e6417d452c59f08d05092591 +F src/sqlite.h.in c8f41612dc1a9b5212a891e1b65a5f589b8b884a F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 98f72cbfe00169c39089115427d06ea05fe4b4a2 F src/sqliteInt.h 292fbc9dd900c64e93a15dfd73ccd9e03475e6a6 @@ -1482,7 +1482,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P c4b9c611bdcd85f31d68aaf114ee34a9f27eba6d -R 761448207abe334cc70f1f29da291a77 +P 87aa9357fbe6749bae60e30af54ca16e48678802 +R 531fbfe926ebd5a12c160e3eacaeb55c U drh -Z 2b1e9b9a1cc02d13e96c99c5d4c59d63 +Z f425ca7a54f66ad3173991f366076015 diff --git a/manifest.uuid b/manifest.uuid index a8908af92e..74ac1a36d9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -87aa9357fbe6749bae60e30af54ca16e48678802 \ No newline at end of file +1dfa5234d3ee38c6af2d18a6294afa93232821e7 \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index b28e1ba14a..33b6d1f5ec 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -8081,20 +8081,29 @@ SQLITE_EXPERIMENTAL int sqlite3_snapshot_get( ** CAPI3REF: Start a read transaction on an historical snapshot ** EXPERIMENTAL ** -** ^The [sqlite3_snapshot_open(D,S,P)] interface attempts to move the -** read transaction that is currently open on schema S of -** [database connection] D so that it refers to historical [snapshot] P. +** ^The [sqlite3_snapshot_open(D,S,P)] interface starts a +** read transaction for schema S of +** [database connection] D such that the read transaction +** refers to historical [snapshot] P, rather than the most +** recent change to the database. ** ^The [sqlite3_snapshot_open()] interface returns SQLITE_OK on success ** or an appropriate [error code] if it fails. ** ** ^In order to succeed, a call to [sqlite3_snapshot_open(D,S,P)] must be -** the first operation, apart from other sqlite3_snapshot_open() calls, -** following the [BEGIN] that starts a new read transaction. -** ^A [snapshot] will fail to open if it has been overwritten by a +** the first operation following the [BEGIN] that takes the schema S +** out of [autocommit mode]. +** ^In other words, schema S must not currently be in +** a transaction for [sqlite3_snapshot_open(D,S,P)] to work, but the +** database connection D must be out of [autocommit mode]. +** ^A [snapshot] will fail to open if it has been overwritten by a ** [checkpoint]. -** ^A [snapshot] will fail to open if the database connection D has not -** previously completed at least one read operation against the database -** file. (Hint: Run "[PRAGMA application_id]" against a newly opened +** ^(A call to [sqlite3_snapshot_open(D,S,P)] will fail if the +** database connection D does not know that the database file for +** schema S is in [WAL mode]. A database connection might not know +** that the database file is in [WAL mode] if there has been no prior +** I/O on that database connection, or if the database entered [WAL mode] +** after the most recent I/O on the database connection.)^ +** (Hint: Run "[PRAGMA application_id]" against a newly opened ** database connection in order to make it ready to use snapshots.) ** ** The [sqlite3_snapshot_open()] interface is only available when the From 53801efcdff09af8a704990424c32675d77e97a6 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 9 Apr 2016 14:36:07 +0000 Subject: [PATCH 0266/1484] Limit the number of digits shown in the "prereq" mask for ".wheretrace" debugging output. FossilOrigin-Name: 3686ed7413ae6cdbc8020c0023205e0455e87467 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/where.c | 5 +++-- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 391bb710ba..fa810c3c2f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\sdocumentation\sfor\ssqlite3_snapshot_open().\s\sNo\scode\schanges. -D 2016-04-08T19:44:31.621 +C Limit\sthe\snumber\sof\sdigits\sshown\sin\sthe\s"prereq"\smask\sfor\s".wheretrace"\ndebugging\soutput. +D 2016-04-09T14:36:07.399 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1f123a0757f6f04f0341accb46457e116817159a @@ -455,7 +455,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 10deb6b43887662691e5f53d10b3c171c401169b F src/wal.h 2f7c831cf3b071fa548bf2d5cac640846a7ff19c F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354 -F src/where.c 99cc6270fc3915201e2a90bbac3768f007a89c44 +F src/where.c 24ab561466d92d313747c04edb1a36a7af8663be F src/whereInt.h 93297d56edd137b7ea004490690fb6e2ce028a34 F src/wherecode.c 863aedf086131743763c1960637fde904eadc442 F src/whereexpr.c fb87944b1254234e5bba671aaf6dee476241506a @@ -1482,7 +1482,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 87aa9357fbe6749bae60e30af54ca16e48678802 -R 531fbfe926ebd5a12c160e3eacaeb55c +P 1dfa5234d3ee38c6af2d18a6294afa93232821e7 +R 8cb0faecb86a13a69a59d8a42b73cabb U drh -Z f425ca7a54f66ad3173991f366076015 +Z ae55d26bb66b3417bd5295b83c3ebe20 diff --git a/manifest.uuid b/manifest.uuid index 74ac1a36d9..19da249469 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1dfa5234d3ee38c6af2d18a6294afa93232821e7 \ No newline at end of file +3686ed7413ae6cdbc8020c0023205e0455e87467 \ No newline at end of file diff --git a/src/where.c b/src/where.c index 4f7ee66ff7..b33e062a6d 100644 --- a/src/where.c +++ b/src/where.c @@ -1651,11 +1651,12 @@ static void whereTermPrint(WhereTerm *pTerm, int iTerm){ */ static void whereLoopPrint(WhereLoop *p, WhereClause *pWC){ WhereInfo *pWInfo = pWC->pWInfo; - int nb = 1+(pWInfo->pTabList->nSrc+7)/8; + int nb = 1+(pWInfo->pTabList->nSrc+3)/4; struct SrcList_item *pItem = pWInfo->pTabList->a + p->iTab; Table *pTab = pItem->pTab; + Bitmask mAll = (((Bitmask)1)<<(nb*4)) - 1; sqlite3DebugPrintf("%c%2d.%0*llx.%0*llx", p->cId, - p->iTab, nb, p->maskSelf, nb, p->prereq); + p->iTab, nb, p->maskSelf, nb, p->prereq & mAll); sqlite3DebugPrintf(" %12s", pItem->zAlias ? pItem->zAlias : pTab->zName); if( (p->wsFlags & WHERE_VIRTUALTABLE)==0 ){ From bfc7a8bb01193847528a67e29db2ce9e3c6c0300 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 9 Apr 2016 17:04:05 +0000 Subject: [PATCH 0267/1484] Fix the sqlite3BtreeDelete() routine so that it preserves the correct key even when the row being deleted is not on a leaf page. Fix for ticket [a306e56ff68b8fa56] FossilOrigin-Name: ca2ef8a86cf806cbbcc64db03251b1df5b2c5501 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/btree.c | 44 ++++++++++++++++++++++---------------------- test/delete4.test | 23 +++++++++++++++++++++-- 4 files changed, 51 insertions(+), 32 deletions(-) diff --git a/manifest b/manifest index fa810c3c2f..998430d736 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Limit\sthe\snumber\sof\sdigits\sshown\sin\sthe\s"prereq"\smask\sfor\s".wheretrace"\ndebugging\soutput. -D 2016-04-09T14:36:07.399 +C Fix\sthe\ssqlite3BtreeDelete()\sroutine\sso\sthat\sit\spreserves\sthe\scorrect\nkey\seven\swhen\sthe\srow\sbeing\sdeleted\sis\snot\son\sa\sleaf\spage.\nFix\sfor\sticket\s[a306e56ff68b8fa56] +D 2016-04-09T17:04:05.661 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1f123a0757f6f04f0341accb46457e116817159a @@ -319,7 +319,7 @@ F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240 F src/backup.c f60f0aa55d25d853ffde53d0b0370a7bb7ee41ce F src/bitvec.c 3ee4c8b2c94ed3a7377256e18199e6ff5cf33f63 F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 -F src/btree.c 556203aab543e91f4e20cc273a507ed712c8da26 +F src/btree.c 3ae6aea66cc4e13d30162ff0d0d43c7088e34abf F src/btree.h a5008b9afe56e8e54ade6c436a910f112defcca9 F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 F src/build.c 1944d95f0250ec72dab939f8319a12e237aaad61 @@ -615,7 +615,7 @@ F test/default.test 0cb49b1c315a0d81c81d775e407f66906a2a604d F test/delete.test e1bcdf8926234e27aac24b346ad83d3329ec8b6f F test/delete2.test 3a03f2cca1f9a67ec469915cb8babd6485db43fa F test/delete3.test 555e84a00a99230b7d049d477a324a631126a6ab -F test/delete4.test 3ac0b8d23689ba764c2e8b78c1b56b8f1b942fa2 +F test/delete4.test 738044ee892ee0c84e0848e36ba92c55f907d52b F test/descidx1.test 6d03b44c8538fe0eb4924e19fba10cdd8f3c9240 F test/descidx2.test 9f1a0c83fd57f8667c82310ca21b30a350888b5d F test/descidx3.test 09ddbe3f5295f482d2f8b687cf6db8bad7acd9a2 @@ -1482,7 +1482,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 1dfa5234d3ee38c6af2d18a6294afa93232821e7 -R 8cb0faecb86a13a69a59d8a42b73cabb +P 3686ed7413ae6cdbc8020c0023205e0455e87467 +R 4553ce3d8ac9552c77beb258f84ad711 U drh -Z ae55d26bb66b3417bd5295b83c3ebe20 +Z 3040395f9dd600c859bc208544af87b9 diff --git a/manifest.uuid b/manifest.uuid index 19da249469..d5324b3e29 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3686ed7413ae6cdbc8020c0023205e0455e87467 \ No newline at end of file +ca2ef8a86cf806cbbcc64db03251b1df5b2c5501 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index e5be8e0ef8..0e30df7f47 100644 --- a/src/btree.c +++ b/src/btree.c @@ -8140,6 +8140,28 @@ int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){ pPage = pCur->apPage[iCellDepth]; pCell = findCell(pPage, iCellIdx); + /* If the bPreserve flag is set to true, then the cursor position must + ** be preserved following this delete operation. If the current delete + ** will cause a b-tree rebalance, then this is done by saving the cursor + ** key and leaving the cursor in CURSOR_REQUIRESEEK state before + ** returning. + ** + ** Or, if the current delete will not cause a rebalance, then the cursor + ** will be left in CURSOR_SKIPNEXT state pointing to the entry immediately + ** before or after the deleted entry. In this case set bSkipnext to true. */ + if( bPreserve ){ + if( !pPage->leaf + || (pPage->nFree+cellSizePtr(pPage,pCell)+2)>(int)(pBt->usableSize*2/3) + ){ + /* A b-tree rebalance will be required after deleting this entry. + ** Save the cursor key. */ + rc = saveCursorKey(pCur); + if( rc ) return rc; + }else{ + bSkipnext = 1; + } + } + /* If the page containing the entry to delete is not a leaf page, move ** the cursor to the largest entry in the tree that is smaller than ** the entry being deleted. This cell will replace the cell being deleted @@ -8166,28 +8188,6 @@ int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){ invalidateIncrblobCursors(p, pCur->info.nKey, 0); } - /* If the bPreserve flag is set to true, then the cursor position must - ** be preserved following this delete operation. If the current delete - ** will cause a b-tree rebalance, then this is done by saving the cursor - ** key and leaving the cursor in CURSOR_REQUIRESEEK state before - ** returning. - ** - ** Or, if the current delete will not cause a rebalance, then the cursor - ** will be left in CURSOR_SKIPNEXT state pointing to the entry immediately - ** before or after the deleted entry. In this case set bSkipnext to true. */ - if( bPreserve ){ - if( !pPage->leaf - || (pPage->nFree+cellSizePtr(pPage,pCell)+2)>(int)(pBt->usableSize*2/3) - ){ - /* A b-tree rebalance will be required after deleting this entry. - ** Save the cursor key. */ - rc = saveCursorKey(pCur); - if( rc ) return rc; - }else{ - bSkipnext = 1; - } - } - /* Make the page containing the entry to be deleted writable. Then free any ** overflow pages associated with the entry and finally remove the cell ** itself from within the page. */ diff --git a/test/delete4.test b/test/delete4.test index f3598a9496..7622b7525e 100644 --- a/test/delete4.test +++ b/test/delete4.test @@ -139,7 +139,26 @@ do_execsql_test 4.12 { PRAGMA integrity_check; } {ok} - - +# 2016-04-09 +# Ticket https://sqlite.org/src/info/a306e56ff68b8fa5 +# Failure to completely delete when reverse_unordered_selects is +# engaged. +# +db close +forcedelete test.db +sqlite3 db test.db +do_execsql_test 5.0 { + PRAGMA page_size=1024; + CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c); + CREATE INDEX x1 ON t1(b, c); + INSERT INTO t1(a,b,c) VALUES(1, 1, zeroblob(80)); + INSERT INTO t1(a,b,c) SELECT a+1, 1, c FROM t1; + INSERT INTO t1(a,b,c) SELECT a+2, 1, c FROM t1; + INSERT INTO t1(a,b,c) SELECT a+10, 2, c FROM t1 WHERE b=1; + INSERT INTO t1(a,b,c) SELECT a+20, 3, c FROM t1 WHERE b=1; + PRAGMA reverse_unordered_selects = ON; + DELETE FROM t1 WHERE b=2; + SELECT a FROM t1 WHERE b=2; +} {} finish_test From ba26faa33f6cb9aa3ee5c2e4a42592a2fe840b23 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 9 Apr 2016 18:04:28 +0000 Subject: [PATCH 0268/1484] Fix a problem in the code generator for joins on virtual tables where the outer loop of the join uses the IN operator. FossilOrigin-Name: 6c56b3a04778bc62ca50307ad838dd301cd91ac2 --- manifest | 14 +++--- manifest.uuid | 2 +- src/wherecode.c | 8 +++- test/bestindex1.test | 107 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 122 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 998430d736..162e969dd4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\ssqlite3BtreeDelete()\sroutine\sso\sthat\sit\spreserves\sthe\scorrect\nkey\seven\swhen\sthe\srow\sbeing\sdeleted\sis\snot\son\sa\sleaf\spage.\nFix\sfor\sticket\s[a306e56ff68b8fa56] -D 2016-04-09T17:04:05.661 +C Fix\sa\sproblem\sin\sthe\scode\sgenerator\sfor\sjoins\son\svirtual\stables\swhere\sthe\nouter\sloop\sof\sthe\sjoin\suses\sthe\sIN\soperator. +D 2016-04-09T18:04:28.474 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1f123a0757f6f04f0341accb46457e116817159a @@ -457,7 +457,7 @@ F src/wal.h 2f7c831cf3b071fa548bf2d5cac640846a7ff19c F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354 F src/where.c 24ab561466d92d313747c04edb1a36a7af8663be F src/whereInt.h 93297d56edd137b7ea004490690fb6e2ce028a34 -F src/wherecode.c 863aedf086131743763c1960637fde904eadc442 +F src/wherecode.c 8fdad9fbba723df1c1e8d07e7ea8507572040340 F src/whereexpr.c fb87944b1254234e5bba671aaf6dee476241506a F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -519,7 +519,7 @@ F test/backup_malloc.test 7162d604ec2b4683c4b3799a48657fb8b5e2d450 F test/badutf.test d5360fc31f643d37a973ab0d8b4fb85799c3169f F test/badutf2.test f5bc7f2d280670ecd79b9cf4f0f1760c607fe51f F test/bc_common.tcl b5e42d80305be95697e6370e015af571e5333a1c -F test/bestindex1.test d5ba89a7941a941476d8d69be39b146aaed3614c +F test/bestindex1.test 0cf1bd2d7b97d3a3a8c10736125274f64765c4ee F test/bestindex2.test 4a06b8922ab2fd09434870da8d1cdf525aaf7060 F test/between.test 34d375fb5ce1ae283ffe82b6b233e9f38e84fc6c F test/bigfile.test aa74f4e5db51c8e54a1d9de9fa65d01d1eb20b59 @@ -1482,7 +1482,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 3686ed7413ae6cdbc8020c0023205e0455e87467 -R 4553ce3d8ac9552c77beb258f84ad711 +P ca2ef8a86cf806cbbcc64db03251b1df5b2c5501 +R 920ccaed1d45e79230b5478d43226c00 U drh -Z 3040395f9dd600c859bc208544af87b9 +Z d3ef20e624c3b08c97c9ab19fe0be036 diff --git a/manifest.uuid b/manifest.uuid index d5324b3e29..59c0bd08c2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ca2ef8a86cf806cbbcc64db03251b1df5b2c5501 \ No newline at end of file +6c56b3a04778bc62ca50307ad838dd301cd91ac2 \ No newline at end of file diff --git a/src/wherecode.c b/src/wherecode.c index 3705aab51d..8105e99dde 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -941,7 +941,13 @@ Bitmask sqlite3WhereCodeOneLoopStart( } } } - sqlite3ReleaseTempRange(pParse, iReg, nConstraint+2); + /* These registers need to be preserved in case there is an IN operator + ** loop. So we could deallocate the registers here (and potentially + ** reuse them later) if (pLoop->wsFlags & WHERE_IN_ABLE)==0. But it seems + ** simpler and safer to simply not reuse the registers. + ** + ** sqlite3ReleaseTempRange(pParse, iReg, nConstraint+2); + */ sqlite3ExprCachePop(pParse); }else #endif /* SQLITE_OMIT_VIRTUALTABLE */ diff --git a/test/bestindex1.test b/test/bestindex1.test index 97ae4b0f81..f90f96bf44 100644 --- a/test/bestindex1.test +++ b/test/bestindex1.test @@ -165,4 +165,111 @@ foreach {tn mode} { } $plan($mode) } +# 2016-04-09. +# Demonstrate a register overwrite problem when using two virtual +# tables where the outer loop uses the IN operator. +# +set G(collist) [list PrimaryKey flagA columnA] +set G(cols) [join $G(collist) ,] +set G(nulls) "NULL" + +proc vtab_command {method args} { + global G + + switch -- $method { + xConnect { + return "CREATE TABLE t1($G(cols))" + } + + xBestIndex { + set clist [lindex $args 0] + #puts $clist + set W [list] + set U [list] + + set i 0 + for {set idx 0} {$idx < [llength $clist]} {incr idx} { + array set c [lindex $clist $idx] + if {$c(op)=="eq" && $c(usable)} { + lappend W "[lindex $G(collist) $c(column)] = %$i%" + lappend U use $idx + incr i + } + } + + if {$W==""} { + set sql "SELECT rowid, * FROM t1" + } else { + set sql "SELECT rowid, * FROM t1 WHERE [join $W { AND }]" + } + + return [concat [list idxstr $sql] $U] + } + + xFilter { + foreach {idxnum idxstr vals} $args {} + + set map [list] + for {set i 0} {$i < [llength $vals]} {incr i} { + lappend map "%$i%" + set v [lindex $vals $i] + if {[string is integer $v]} { + lappend map $v + } else { + lappend map "'$v'" + } + } + set sql [string map $map $idxstr] + + #puts "SQL: $sql" + return [list sql $sql] + } + } + + return {} +} + +db close +forcedelete test.db +sqlite3 db test.db +register_tcl_module db + +do_execsql_test 3.1 " + CREATE TABLE t1($G(cols)); + INSERT INTO t1 VALUES(1, 0, 'ValueA'); + INSERT INTO t1 VALUES(2, 0, 'ValueA'); + INSERT INTO t1 VALUES(3, 0, 'ValueB'); + INSERT INTO t1 VALUES(4, 0, 'ValueB'); +" + +do_execsql_test 3.2 { + CREATE VIRTUAL TABLE VirtualTableA USING tcl(vtab_command); + CREATE VIRTUAL TABLE VirtualTableB USING tcl(vtab_command); +} + +do_execsql_test 3.3 { SELECT primarykey FROM VirtualTableA } {1 2 3 4} + +do_execsql_test 3.4 { + SELECT * FROM + VirtualTableA a CROSS JOIN VirtualTableB b ON b.PrimaryKey=a.PrimaryKey + WHERE a.ColumnA IN ('ValueA', 'ValueB') AND a.FlagA=0 +} { + 1 0 ValueA 1 0 ValueA + 2 0 ValueA 2 0 ValueA + 3 0 ValueB 3 0 ValueB + 4 0 ValueB 4 0 ValueB +} + +do_execsql_test 3.5 { + SELECT * FROM + VirtualTableA a CROSS JOIN VirtualTableB b ON b.PrimaryKey=a.PrimaryKey + WHERE a.FlagA=0 AND a.ColumnA IN ('ValueA', 'ValueB') +} { + 1 0 ValueA 1 0 ValueA + 2 0 ValueA 2 0 ValueA + 3 0 ValueB 3 0 ValueB + 4 0 ValueB 4 0 ValueB +} + + finish_test From 08de4f7933f9ae26e33b2367a5a8e802442d56b0 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 11 Apr 2016 01:06:47 +0000 Subject: [PATCH 0269/1484] Factor out the common operation of setting the Expr.x.pSelect field of an Expr object into a subroutine. FossilOrigin-Name: 6a5cceee486c5e3625556e4c7076ff90e9d8fa43 --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/delete.c | 24 +++++++----------------- src/expr.c | 16 ++++++++++++++++ src/parse.y | 33 +++++---------------------------- src/sqliteInt.h | 1 + 6 files changed, 39 insertions(+), 55 deletions(-) diff --git a/manifest b/manifest index 162e969dd4..dc13b3eb8a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\sin\sthe\scode\sgenerator\sfor\sjoins\son\svirtual\stables\swhere\sthe\nouter\sloop\sof\sthe\sjoin\suses\sthe\sIN\soperator. -D 2016-04-09T18:04:28.474 +C Factor\sout\sthe\scommon\soperation\sof\ssetting\sthe\sExpr.x.pSelect\sfield\sof\san\nExpr\sobject\sinto\sa\ssubroutine. +D 2016-04-11T01:06:47.056 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1f123a0757f6f04f0341accb46457e116817159a @@ -328,8 +328,8 @@ F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 60e135af364d777a9ab41c97e5e89cd224da6198 F src/date.c 0b73e681c11fca867fec554750c07fe0d4e417c1 F src/dbstat.c c845548d4346e606e2f2b7d2e714ace2b8a7dd1b -F src/delete.c eeac28b3d3d88e3541bdf93e91ea7492a7b67842 -F src/expr.c 289ffac5240b60fee0a824d3d5ab2d7bd2630c94 +F src/delete.c 78eb999114ec04fcf1b7d123ccedb4b5b734930e +F src/expr.c a195d2d047ca59f9b87cae737b785d17cdd3cc3f F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 4c0bd09e602b8ae8d36d81e31e4872d0b53c87bb F src/func.c 552d300265aed09eea21f68ac742a440550c0062 @@ -364,7 +364,7 @@ F src/os_win.c b3ba9573d8d893e70a6a8015bbee572ecf7ffbef F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c 38718a019ca762ba4f6795425d5a54db70d1790d F src/pager.h e1d38a2f14849e219df0f91f8323504d134c8a56 -F src/parse.y 5ea8c81c5c41b27887f41b4a7e1c58470d7d3821 +F src/parse.y b6fcbc84ea5a278ab7f1d12ce6eeff6bfa4024d3 F src/pcache.c 647bb53a86b7bbcf55ad88089b3ea5a9170b90df F src/pcache.h 4d0ccaad264d360981ec5e6a2b596d6e85242545 F src/pcache1.c c40cdb93586e21b5dd826b5e671240bd91c26b05 @@ -380,7 +380,7 @@ F src/shell.c b7922fa264f8c8d72a5ec6dd0b091e15a93c4de5 F src/sqlite.h.in c8f41612dc1a9b5212a891e1b65a5f589b8b884a F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 98f72cbfe00169c39089115427d06ea05fe4b4a2 -F src/sqliteInt.h 292fbc9dd900c64e93a15dfd73ccd9e03475e6a6 +F src/sqliteInt.h 8a3ca5847b3cbd0ee3333f5615e3db049f550727 F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 @@ -1482,7 +1482,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ca2ef8a86cf806cbbcc64db03251b1df5b2c5501 -R 920ccaed1d45e79230b5478d43226c00 +P 6c56b3a04778bc62ca50307ad838dd301cd91ac2 +R 08b902f57778a5f41e0cd6430d22ec7f U drh -Z d3ef20e624c3b08c97c9ab19fe0be036 +Z 9c3d824161c7c538f7604747bea88424 diff --git a/manifest.uuid b/manifest.uuid index 59c0bd08c2..a1179c31d9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6c56b3a04778bc62ca50307ad838dd301cd91ac2 \ No newline at end of file +6a5cceee486c5e3625556e4c7076ff90e9d8fa43 \ No newline at end of file diff --git a/src/delete.c b/src/delete.c index 6eae462ba1..e3af2d7a78 100644 --- a/src/delete.c +++ b/src/delete.c @@ -143,7 +143,7 @@ Expr *sqlite3LimitWhere( */ if( pOrderBy && (pLimit == 0) ) { sqlite3ErrorMsg(pParse, "ORDER BY without LIMIT on %s", zStmtType); - goto limit_where_cleanup_2; + goto limit_where_cleanup; } /* We only need to generate a select expression if there @@ -165,16 +165,16 @@ Expr *sqlite3LimitWhere( */ pSelectRowid = sqlite3PExpr(pParse, TK_ROW, 0, 0, 0); - if( pSelectRowid == 0 ) goto limit_where_cleanup_2; + if( pSelectRowid == 0 ) goto limit_where_cleanup; pEList = sqlite3ExprListAppend(pParse, 0, pSelectRowid); - if( pEList == 0 ) goto limit_where_cleanup_2; + if( pEList == 0 ) goto limit_where_cleanup; /* duplicate the FROM clause as it is needed by both the DELETE/UPDATE tree ** and the SELECT subtree. */ pSelectSrc = sqlite3SrcListDup(pParse->db, pSrc, 0); if( pSelectSrc == 0 ) { sqlite3ExprListDelete(pParse->db, pEList); - goto limit_where_cleanup_2; + goto limit_where_cleanup; } /* generate the SELECT expression tree. */ @@ -184,21 +184,11 @@ Expr *sqlite3LimitWhere( /* now generate the new WHERE rowid IN clause for the DELETE/UDPATE */ pWhereRowid = sqlite3PExpr(pParse, TK_ROW, 0, 0, 0); - if( pWhereRowid == 0 ) goto limit_where_cleanup_1; - pInClause = sqlite3PExpr(pParse, TK_IN, pWhereRowid, 0, 0); - if( pInClause == 0 ) goto limit_where_cleanup_1; - - pInClause->x.pSelect = pSelect; - pInClause->flags |= EP_xIsSelect; - sqlite3ExprSetHeightAndFlags(pParse, pInClause); + pInClause = pWhereRowid ? sqlite3PExpr(pParse, TK_IN, pWhereRowid, 0, 0) : 0; + sqlite3PExprAddSelect(pParse, pInClause, pSelect); return pInClause; - /* something went wrong. clean up anything allocated. */ -limit_where_cleanup_1: - sqlite3SelectDelete(pParse->db, pSelect); - return 0; - -limit_where_cleanup_2: +limit_where_cleanup: sqlite3ExprDelete(pParse->db, pWhere); sqlite3ExprListDelete(pParse->db, pOrderBy); sqlite3ExprDelete(pParse->db, pLimit); diff --git a/src/expr.c b/src/expr.c index 998c94f231..6792f26a55 100644 --- a/src/expr.c +++ b/src/expr.c @@ -562,6 +562,22 @@ Expr *sqlite3PExpr( return p; } +/* +** Add pSelect to the Expr.x.pSelect field. Or, if pExpr is NULL (due +** do a memory allocation failure) then delete the pSelect object. +*/ +void sqlite3PExprAddSelect(Parse *pParse, Expr *pExpr, Select *pSelect){ + if( pExpr ){ + pExpr->x.pSelect = pSelect; + ExprSetProperty(pExpr, EP_xIsSelect|EP_Subquery); + sqlite3ExprSetHeightAndFlags(pParse, pExpr); + }else{ + assert( pParse->db->mallocFailed ); + sqlite3SelectDelete(pParse->db, pSelect); + } +} + + /* ** If the expression is always either TRUE or FALSE (respectively), ** then return 1. If one cannot determine the truth value of the diff --git a/src/parse.y b/src/parse.y index 20492edb80..5704fffb7e 100644 --- a/src/parse.y +++ b/src/parse.y @@ -1122,36 +1122,19 @@ expr(A) ::= expr(A) between_op(N) expr(X) AND expr(Y). [BETWEEN] { expr(A) ::= LP(B) select(X) RP(E). { spanSet(&A,&B,&E); /*A-overwrites-B*/ A.pExpr = sqlite3PExpr(pParse, TK_SELECT, 0, 0, 0); - if( A.pExpr ){ - A.pExpr->x.pSelect = X; - ExprSetProperty(A.pExpr, EP_xIsSelect|EP_Subquery); - sqlite3ExprSetHeightAndFlags(pParse, A.pExpr); - }else{ - sqlite3SelectDelete(pParse->db, X); - } + sqlite3PExprAddSelect(pParse, A.pExpr, X); } expr(A) ::= expr(A) in_op(N) LP select(Y) RP(E). [IN] { A.pExpr = sqlite3PExpr(pParse, TK_IN, A.pExpr, 0, 0); - if( A.pExpr ){ - A.pExpr->x.pSelect = Y; - ExprSetProperty(A.pExpr, EP_xIsSelect|EP_Subquery); - sqlite3ExprSetHeightAndFlags(pParse, A.pExpr); - }else{ - sqlite3SelectDelete(pParse->db, Y); - } + sqlite3PExprAddSelect(pParse, A.pExpr, Y); exprNot(pParse, N, &A); A.zEnd = &E.z[E.n]; } expr(A) ::= expr(A) in_op(N) nm(Y) dbnm(Z). [IN] { SrcList *pSrc = sqlite3SrcListAppend(pParse->db, 0,&Y,&Z); + Select *pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0); A.pExpr = sqlite3PExpr(pParse, TK_IN, A.pExpr, 0, 0); - if( A.pExpr ){ - A.pExpr->x.pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0); - ExprSetProperty(A.pExpr, EP_xIsSelect|EP_Subquery); - sqlite3ExprSetHeightAndFlags(pParse, A.pExpr); - }else{ - sqlite3SrcListDelete(pParse->db, pSrc); - } + sqlite3PExprAddSelect(pParse, A.pExpr, pSelect); exprNot(pParse, N, &A); A.zEnd = Z.z ? &Z.z[Z.n] : &Y.z[Y.n]; } @@ -1159,13 +1142,7 @@ expr(A) ::= expr(A) between_op(N) expr(X) AND expr(Y). [BETWEEN] { Expr *p; spanSet(&A,&B,&E); /*A-overwrites-B*/ p = A.pExpr = sqlite3PExpr(pParse, TK_EXISTS, 0, 0, 0); - if( p ){ - p->x.pSelect = Y; - ExprSetProperty(p, EP_xIsSelect|EP_Subquery); - sqlite3ExprSetHeightAndFlags(pParse, p); - }else{ - sqlite3SelectDelete(pParse->db, Y); - } + sqlite3PExprAddSelect(pParse, p, Y); } %endif SQLITE_OMIT_SUBQUERY diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 94dd68bffc..f9f449d967 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3449,6 +3449,7 @@ Expr *sqlite3ExprAlloc(sqlite3*,int,const Token*,int); Expr *sqlite3Expr(sqlite3*,int,const char*); void sqlite3ExprAttachSubtrees(sqlite3*,Expr*,Expr*,Expr*); Expr *sqlite3PExpr(Parse*, int, Expr*, Expr*, const Token*); +void sqlite3PExprAddSelect(Parse*, Expr*, Select*); Expr *sqlite3ExprAnd(sqlite3*,Expr*, Expr*); Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*); void sqlite3ExprAssignVarNumber(Parse*, Expr*); From 8f3b137fa61a2f8e7b31a0d78850cf291f43cfa3 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 11 Apr 2016 01:26:31 +0000 Subject: [PATCH 0270/1484] Small size reduction and performance improvement in the parser. FossilOrigin-Name: 16df71284bf081c8b3d3aa57c129a07067ddbed3 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/parse.y | 11 ++++++----- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index dc13b3eb8a..f239120af5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Factor\sout\sthe\scommon\soperation\sof\ssetting\sthe\sExpr.x.pSelect\sfield\sof\san\nExpr\sobject\sinto\sa\ssubroutine. -D 2016-04-11T01:06:47.056 +C Small\ssize\sreduction\sand\sperformance\simprovement\sin\sthe\sparser. +D 2016-04-11T01:26:31.547 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1f123a0757f6f04f0341accb46457e116817159a @@ -364,7 +364,7 @@ F src/os_win.c b3ba9573d8d893e70a6a8015bbee572ecf7ffbef F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c 38718a019ca762ba4f6795425d5a54db70d1790d F src/pager.h e1d38a2f14849e219df0f91f8323504d134c8a56 -F src/parse.y b6fcbc84ea5a278ab7f1d12ce6eeff6bfa4024d3 +F src/parse.y 55670f9b802b65fa7b4c5bee1c3f1df3b7fab17b F src/pcache.c 647bb53a86b7bbcf55ad88089b3ea5a9170b90df F src/pcache.h 4d0ccaad264d360981ec5e6a2b596d6e85242545 F src/pcache1.c c40cdb93586e21b5dd826b5e671240bd91c26b05 @@ -1482,7 +1482,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 6c56b3a04778bc62ca50307ad838dd301cd91ac2 -R 08b902f57778a5f41e0cd6430d22ec7f +P 6a5cceee486c5e3625556e4c7076ff90e9d8fa43 +R 760d086185281b3360f3c0b7a4fcef9f U drh -Z 9c3d824161c7c538f7604747bea88424 +Z 39bdfd823e1ede2ba92d243629273ed6 diff --git a/manifest.uuid b/manifest.uuid index a1179c31d9..1409067143 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6a5cceee486c5e3625556e4c7076ff90e9d8fa43 \ No newline at end of file +16df71284bf081c8b3d3aa57c129a07067ddbed3 \ No newline at end of file diff --git a/src/parse.y b/src/parse.y index 5704fffb7e..01a738ff8f 100644 --- a/src/parse.y +++ b/src/parse.y @@ -871,11 +871,15 @@ expr(A) ::= nm(X) DOT nm(Y) DOT nm(Z). { term(A) ::= INTEGER|FLOAT|BLOB(X). {spanExpr(&A,pParse,@X,X);/*A-overwrites-X*/} term(A) ::= STRING(X). {spanExpr(&A,pParse,@X,X);/*A-overwrites-X*/} expr(A) ::= VARIABLE(X). { - Token t = X; /*A-overwrites-X*/ - if( t.n>=2 && t.z[0]=='#' && sqlite3Isdigit(t.z[1]) ){ + if( X.z[0]!='#' ){ + spanExpr(&A, pParse, TK_VARIABLE, X); + sqlite3ExprAssignVarNumber(pParse, A.pExpr); + }else{ /* When doing a nested parse, one can include terms in an expression ** that look like this: #1 #2 ... These terms refer to registers ** in the virtual machine. #N is the N-th register. */ + Token t = X; /*A-overwrites-X*/ + assert( t.n>=2 ); spanSet(&A, &t, &t); if( pParse->nested==0 ){ sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &t); @@ -884,9 +888,6 @@ expr(A) ::= VARIABLE(X). { A.pExpr = sqlite3PExpr(pParse, TK_REGISTER, 0, 0, &t); if( A.pExpr ) sqlite3GetInt32(&t.z[1], &A.pExpr->iTable); } - }else{ - spanExpr(&A, pParse, TK_VARIABLE, t); - sqlite3ExprAssignVarNumber(pParse, A.pExpr); } } expr(A) ::= expr(A) COLLATE ids(C). { From 8679fbabaa23e5315cd9abe767ad96741a09f20a Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 11 Apr 2016 01:43:33 +0000 Subject: [PATCH 0271/1484] Back off of the parser optimization in the previous check-in, slightly, to preserve some backwards compatibility regarding some undocumented behavior in the '#AAA' style query parameter. FossilOrigin-Name: ef1966c2469a0f5dbdb31a0287bd37badb2b8f28 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/parse.y | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index f239120af5..feae043873 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Small\ssize\sreduction\sand\sperformance\simprovement\sin\sthe\sparser. -D 2016-04-11T01:26:31.547 +C Back\soff\sof\sthe\sparser\soptimization\sin\sthe\sprevious\scheck-in,\sslightly,\sto\npreserve\ssome\sbackwards\scompatibility\sregarding\ssome\sundocumented\sbehavior\nin\sthe\s'#AAA'\sstyle\squery\sparameter. +D 2016-04-11T01:43:33.203 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1f123a0757f6f04f0341accb46457e116817159a @@ -364,7 +364,7 @@ F src/os_win.c b3ba9573d8d893e70a6a8015bbee572ecf7ffbef F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c 38718a019ca762ba4f6795425d5a54db70d1790d F src/pager.h e1d38a2f14849e219df0f91f8323504d134c8a56 -F src/parse.y 55670f9b802b65fa7b4c5bee1c3f1df3b7fab17b +F src/parse.y 52cdeb4f37634d0ccd2998aab099b7bbb690b0d3 F src/pcache.c 647bb53a86b7bbcf55ad88089b3ea5a9170b90df F src/pcache.h 4d0ccaad264d360981ec5e6a2b596d6e85242545 F src/pcache1.c c40cdb93586e21b5dd826b5e671240bd91c26b05 @@ -1482,7 +1482,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 6a5cceee486c5e3625556e4c7076ff90e9d8fa43 -R 760d086185281b3360f3c0b7a4fcef9f +P 16df71284bf081c8b3d3aa57c129a07067ddbed3 +R 667818294699cc99ee5b525ba6ac6436 U drh -Z 39bdfd823e1ede2ba92d243629273ed6 +Z c1e211272b38ff3536c2cdaeb19c42fc diff --git a/manifest.uuid b/manifest.uuid index 1409067143..01abafd845 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -16df71284bf081c8b3d3aa57c129a07067ddbed3 \ No newline at end of file +ef1966c2469a0f5dbdb31a0287bd37badb2b8f28 \ No newline at end of file diff --git a/src/parse.y b/src/parse.y index 01a738ff8f..605751fd9e 100644 --- a/src/parse.y +++ b/src/parse.y @@ -871,7 +871,7 @@ expr(A) ::= nm(X) DOT nm(Y) DOT nm(Z). { term(A) ::= INTEGER|FLOAT|BLOB(X). {spanExpr(&A,pParse,@X,X);/*A-overwrites-X*/} term(A) ::= STRING(X). {spanExpr(&A,pParse,@X,X);/*A-overwrites-X*/} expr(A) ::= VARIABLE(X). { - if( X.z[0]!='#' ){ + if( !(X.z[0]=='#' && sqlite3Isdigit(X.z[1])) ){ spanExpr(&A, pParse, TK_VARIABLE, X); sqlite3ExprAssignVarNumber(pParse, A.pExpr); }else{ From 7cc84c2cdd5acb3331b27298613ca5e653741099 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 11 Apr 2016 13:36:42 +0000 Subject: [PATCH 0272/1484] Remove the VdbeOp.opflags field and its associated initialization overhead. Update mkopcodeh.tcl to reorder opcode numbers to help the resolveP2Values() routine run faster. FossilOrigin-Name: 099478fa7521ba52262ef2bf24dd8f0114ce92e1 --- manifest | 20 ++++---- manifest.uuid | 2 +- src/parse.y | 45 +++++++++--------- src/vdbe.c | 69 ++++++++++++++------------- src/vdbe.h | 2 +- src/vdbeaux.c | 113 +++++++++++++++++++++++++-------------------- tool/mkopcodeh.tcl | 35 ++++++++++++-- 7 files changed, 165 insertions(+), 121 deletions(-) diff --git a/manifest b/manifest index feae043873..ce95096bc7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Back\soff\sof\sthe\sparser\soptimization\sin\sthe\sprevious\scheck-in,\sslightly,\sto\npreserve\ssome\sbackwards\scompatibility\sregarding\ssome\sundocumented\sbehavior\nin\sthe\s'#AAA'\sstyle\squery\sparameter. -D 2016-04-11T01:43:33.203 +C Remove\sthe\sVdbeOp.opflags\sfield\sand\sits\sassociated\sinitialization\soverhead.\nUpdate\smkopcodeh.tcl\sto\sreorder\sopcode\snumbers\sto\shelp\sthe\sresolveP2Values()\nroutine\srun\sfaster. +D 2016-04-11T13:36:42.250 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1f123a0757f6f04f0341accb46457e116817159a @@ -364,7 +364,7 @@ F src/os_win.c b3ba9573d8d893e70a6a8015bbee572ecf7ffbef F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c 38718a019ca762ba4f6795425d5a54db70d1790d F src/pager.h e1d38a2f14849e219df0f91f8323504d134c8a56 -F src/parse.y 52cdeb4f37634d0ccd2998aab099b7bbb690b0d3 +F src/parse.y 10eb2f3fb62341291528c7984498054731f9d31e F src/pcache.c 647bb53a86b7bbcf55ad88089b3ea5a9170b90df F src/pcache.h 4d0ccaad264d360981ec5e6a2b596d6e85242545 F src/pcache1.c c40cdb93586e21b5dd826b5e671240bd91c26b05 @@ -441,11 +441,11 @@ F src/update.c 3e67ab3c0814635f355fb1f8ab010a2b9e016e7d F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 19509465217b673b38d5804a72778908b138953f F src/vacuum.c feb1eabb20987983d9350cad98299b21fa811f52 -F src/vdbe.c e16e8625829858b2bf343c3cdd72bb43eab7d643 -F src/vdbe.h c16ba943d407baa1c7085eefea73a063fc631863 +F src/vdbe.c d3843a66d74a7696477ee5141e5eb9a7e5e2401c +F src/vdbe.h 5591b5add447096e31288b5a0a78ec5d7b5c5170 F src/vdbeInt.h ddb157974436d87652de7dc641f7191496d9a8cd F src/vdbeapi.c ba85b78fe08dc4a9ce747e62c89a2b4a4547e74c -F src/vdbeaux.c 749b2a346cd2eba483e05825553406da1065d03e +F src/vdbeaux.c b0bd706639fda1ee3aa786b3a01a798e13e811d4 F src/vdbeblob.c c9f2f494b911c6fa34efd9803f0a10807da80f77 F src/vdbemem.c 5cfef60e60e19cab6275d1b975bf4c791d575beb F src/vdbesort.c 307460bfa4de4d1c3901fcd42089159131e34062 @@ -1420,7 +1420,7 @@ F tool/mkautoconfamal.sh e855df211ecbcc7131dee817110ff386cfb112f7 F tool/mkkeywordhash.c f7f3b342211ac6a14258b9726d5b97cf4f548f22 F tool/mkmsvcmin.tcl 2f12f7fa8858bbe61cf81820a2da96c79ed1ca8d F tool/mkopcodec.tcl d1b6362bd3aa80d5520d4d6f3765badf01f6c43c -F tool/mkopcodeh.tcl 385c62d78c38b2d92146dcb5abd319dbbc33506d +F tool/mkopcodeh.tcl 3b1ee0fd2452b0e2c0381956269a9ac3788255a3 F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e F tool/mkpragmatab.tcl f0d5bb266d1d388cf86fce5ba01a891e95d72d41 F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 @@ -1482,7 +1482,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 16df71284bf081c8b3d3aa57c129a07067ddbed3 -R 667818294699cc99ee5b525ba6ac6436 +P ef1966c2469a0f5dbdb31a0287bd37badb2b8f28 +R 39896b563a0174d278e56658538b5996 U drh -Z c1e211272b38ff3536c2cdaeb19c42fc +Z 4b0063de72cbcb5b307015ce248a50de diff --git a/manifest.uuid b/manifest.uuid index 01abafd845..9a8e083986 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ef1966c2469a0f5dbdb31a0287bd37badb2b8f28 \ No newline at end of file +099478fa7521ba52262ef2bf24dd8f0114ce92e1 \ No newline at end of file diff --git a/src/parse.y b/src/parse.y index 605751fd9e..ae763e46d6 100644 --- a/src/parse.y +++ b/src/parse.y @@ -194,28 +194,6 @@ columnlist ::= columnlist COMMA columnname carglist. columnlist ::= columnname carglist. columnname(A) ::= nm(A) typetoken(Y). {sqlite3AddColumn(pParse,&A,&Y);} -// An IDENTIFIER can be a generic identifier, or one of several -// keywords. Any non-standard keyword can also be an identifier. -// -%token_class id ID|INDEXED. - -// The following directive causes tokens ABORT, AFTER, ASC, etc. to -// fallback to ID if they will not parse as their original value. -// This obviates the need for the "id" nonterminal. -// -%fallback ID - ABORT ACTION AFTER ANALYZE ASC ATTACH BEFORE BEGIN BY CASCADE CAST COLUMNKW - CONFLICT DATABASE DEFERRED DESC DETACH EACH END EXCLUSIVE EXPLAIN FAIL FOR - IGNORE IMMEDIATE INITIALLY INSTEAD LIKE_KW MATCH NO PLAN - QUERY KEY OF OFFSET PRAGMA RAISE RECURSIVE RELEASE REPLACE RESTRICT ROW - ROLLBACK SAVEPOINT TEMP TRIGGER VACUUM VIEW VIRTUAL WITH WITHOUT -%ifdef SQLITE_OMIT_COMPOUND_SELECT - EXCEPT INTERSECT UNION -%endif SQLITE_OMIT_COMPOUND_SELECT - REINDEX RENAME CTIME_KW IF - . -%wildcard ANY. - // Define operator precedence early so that this is the first occurrence // of the operator tokens in the grammer. Keeping the operators together // causes them to be assigned integer values that are close together, @@ -240,6 +218,29 @@ columnname(A) ::= nm(A) typetoken(Y). {sqlite3AddColumn(pParse,&A,&Y);} %left COLLATE. %right BITNOT. +// An IDENTIFIER can be a generic identifier, or one of several +// keywords. Any non-standard keyword can also be an identifier. +// +%token_class id ID|INDEXED. + +// The following directive causes tokens ABORT, AFTER, ASC, etc. to +// fallback to ID if they will not parse as their original value. +// This obviates the need for the "id" nonterminal. +// +%fallback ID + ABORT ACTION AFTER ANALYZE ASC ATTACH BEFORE BEGIN BY CASCADE CAST COLUMNKW + CONFLICT DATABASE DEFERRED DESC DETACH EACH END EXCLUSIVE EXPLAIN FAIL FOR + IGNORE IMMEDIATE INITIALLY INSTEAD LIKE_KW MATCH NO PLAN + QUERY KEY OF OFFSET PRAGMA RAISE RECURSIVE RELEASE REPLACE RESTRICT ROW + ROLLBACK SAVEPOINT TEMP TRIGGER VACUUM VIEW VIRTUAL WITH WITHOUT +%ifdef SQLITE_OMIT_COMPOUND_SELECT + EXCEPT INTERSECT UNION +%endif SQLITE_OMIT_COMPOUND_SELECT + REINDEX RENAME CTIME_KW IF + . +%wildcard ANY. + + // And "ids" is an identifer-or-string. // %token_class ids ID|STRING. diff --git a/src/vdbe.c b/src/vdbe.c index 593ea40806..244a4ad063 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -674,37 +674,39 @@ int sqlite3VdbeExec( /* Sanity checking on other operands */ #ifdef SQLITE_DEBUG - assert( pOp->opflags==sqlite3OpcodeProperty[pOp->opcode] ); - if( (pOp->opflags & OPFLG_IN1)!=0 ){ - assert( pOp->p1>0 ); - assert( pOp->p1<=(p->nMem+1 - p->nCursor) ); - assert( memIsValid(&aMem[pOp->p1]) ); - assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p1]) ); - REGISTER_TRACE(pOp->p1, &aMem[pOp->p1]); - } - if( (pOp->opflags & OPFLG_IN2)!=0 ){ - assert( pOp->p2>0 ); - assert( pOp->p2<=(p->nMem+1 - p->nCursor) ); - assert( memIsValid(&aMem[pOp->p2]) ); - assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p2]) ); - REGISTER_TRACE(pOp->p2, &aMem[pOp->p2]); - } - if( (pOp->opflags & OPFLG_IN3)!=0 ){ - assert( pOp->p3>0 ); - assert( pOp->p3<=(p->nMem+1 - p->nCursor) ); - assert( memIsValid(&aMem[pOp->p3]) ); - assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p3]) ); - REGISTER_TRACE(pOp->p3, &aMem[pOp->p3]); - } - if( (pOp->opflags & OPFLG_OUT2)!=0 ){ - assert( pOp->p2>0 ); - assert( pOp->p2<=(p->nMem+1 - p->nCursor) ); - memAboutToChange(p, &aMem[pOp->p2]); - } - if( (pOp->opflags & OPFLG_OUT3)!=0 ){ - assert( pOp->p3>0 ); - assert( pOp->p3<=(p->nMem+1 - p->nCursor) ); - memAboutToChange(p, &aMem[pOp->p3]); + { + u8 opProperty = sqlite3OpcodeProperty[pOp->opcode]; + if( (opProperty & OPFLG_IN1)!=0 ){ + assert( pOp->p1>0 ); + assert( pOp->p1<=(p->nMem+1 - p->nCursor) ); + assert( memIsValid(&aMem[pOp->p1]) ); + assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p1]) ); + REGISTER_TRACE(pOp->p1, &aMem[pOp->p1]); + } + if( (opProperty & OPFLG_IN2)!=0 ){ + assert( pOp->p2>0 ); + assert( pOp->p2<=(p->nMem+1 - p->nCursor) ); + assert( memIsValid(&aMem[pOp->p2]) ); + assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p2]) ); + REGISTER_TRACE(pOp->p2, &aMem[pOp->p2]); + } + if( (opProperty & OPFLG_IN3)!=0 ){ + assert( pOp->p3>0 ); + assert( pOp->p3<=(p->nMem+1 - p->nCursor) ); + assert( memIsValid(&aMem[pOp->p3]) ); + assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p3]) ); + REGISTER_TRACE(pOp->p3, &aMem[pOp->p3]); + } + if( (opProperty & OPFLG_OUT2)!=0 ){ + assert( pOp->p2>0 ); + assert( pOp->p2<=(p->nMem+1 - p->nCursor) ); + memAboutToChange(p, &aMem[pOp->p2]); + } + if( (opProperty & OPFLG_OUT3)!=0 ){ + assert( pOp->p3>0 ); + assert( pOp->p3<=(p->nMem+1 - p->nCursor) ); + memAboutToChange(p, &aMem[pOp->p3]); + } } #endif #if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) @@ -6877,11 +6879,12 @@ default: { /* This is really OP_Noop and OP_Explain */ #ifdef SQLITE_DEBUG if( db->flags & SQLITE_VdbeTrace ){ + u8 opProperty = sqlite3OpcodeProperty[pOrigOp->opcode]; if( rc!=0 ) printf("rc=%d\n",rc); - if( pOrigOp->opflags & (OPFLG_OUT2) ){ + if( opProperty & (OPFLG_OUT2) ){ registerTrace(pOrigOp->p2, &aMem[pOrigOp->p2]); } - if( pOrigOp->opflags & OPFLG_OUT3 ){ + if( opProperty & OPFLG_OUT3 ){ registerTrace(pOrigOp->p3, &aMem[pOrigOp->p3]); } } diff --git a/src/vdbe.h b/src/vdbe.h index ab0de8f3eb..3db32c8552 100644 --- a/src/vdbe.h +++ b/src/vdbe.h @@ -41,7 +41,7 @@ typedef struct SubProgram SubProgram; struct VdbeOp { u8 opcode; /* What operation to perform */ signed char p4type; /* One of the P4_xxx constants for p4 */ - u8 opflags; /* Mask of the OPFLG_* flags in opcodes.h */ + u8 notUsed1; u8 p5; /* Fifth parameter is an unsigned character */ int p1; /* First operand */ int p2; /* Second parameter (often the jump destination) */ diff --git a/src/vdbeaux.c b/src/vdbeaux.c index b3526e014a..d3f2b6b7bc 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -545,73 +545,84 @@ int sqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){ ** (4) Initialize the p4.xAdvance pointer on opcodes that use it. ** ** (5) Reclaim the memory allocated for storing labels. +** +** This routine will only function correctly if the mkopcodeh.tcl generator +** script numbers the opcodes correctly. Changes to this routine must be +** coordinated with changes to mkopcodeh.tcl. */ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){ - int i; int nMaxArgs = *pMaxFuncArgs; Op *pOp; Parse *pParse = p->pParse; int *aLabel = pParse->aLabel; p->readOnly = 1; p->bIsReader = 0; - for(pOp=p->aOp, i=p->nOp-1; i>=0; i--, pOp++){ - u8 opcode = pOp->opcode; + pOp = &p->aOp[p->nOp-1]; + while(1){ - /* NOTE: Be sure to update mkopcodeh.tcl when adding or removing - ** cases from this switch! */ - switch( opcode ){ - case OP_Transaction: { - if( pOp->p2!=0 ) p->readOnly = 0; - /* fall thru */ - } - case OP_AutoCommit: - case OP_Savepoint: { - p->bIsReader = 1; - break; - } + /* Only JUMP opcodes and the short list of special opcodes in the switch + ** below need to be considered. The mkopcodeh.tcl generator script groups + ** all these opcodes together near the front of the opcode list. Skip + ** any opcode that does not need processing by virtual of the fact that + ** it is larger than OP_MX_JUMP, as a performance optimization. + */ + if( pOp->opcode<=OP_MX_JUMP ){ + /* NOTE: Be sure to update mkopcodeh.tcl when adding or removing + ** cases from this switch! */ + switch( pOp->opcode ){ + case OP_Transaction: { + if( pOp->p2!=0 ) p->readOnly = 0; + /* fall thru */ + } + case OP_AutoCommit: + case OP_Savepoint: { + p->bIsReader = 1; + break; + } #ifndef SQLITE_OMIT_WAL - case OP_Checkpoint: + case OP_Checkpoint: #endif - case OP_Vacuum: - case OP_JournalMode: { - p->readOnly = 0; - p->bIsReader = 1; - break; - } + case OP_Vacuum: + case OP_JournalMode: { + p->readOnly = 0; + p->bIsReader = 1; + break; + } #ifndef SQLITE_OMIT_VIRTUALTABLE - case OP_VUpdate: { - if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2; - break; - } - case OP_VFilter: { - int n; - assert( p->nOp - i >= 3 ); - assert( pOp[-1].opcode==OP_Integer ); - n = pOp[-1].p1; - if( n>nMaxArgs ) nMaxArgs = n; - break; - } + case OP_VUpdate: { + if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2; + break; + } + case OP_VFilter: { + int n; + assert( (pOp - p->aOp) >= 3 ); + assert( pOp[-1].opcode==OP_Integer ); + n = pOp[-1].p1; + if( n>nMaxArgs ) nMaxArgs = n; + break; + } #endif - case OP_Next: - case OP_NextIfOpen: - case OP_SorterNext: { - pOp->p4.xAdvance = sqlite3BtreeNext; - pOp->p4type = P4_ADVANCE; - break; + case OP_Next: + case OP_NextIfOpen: + case OP_SorterNext: { + pOp->p4.xAdvance = sqlite3BtreeNext; + pOp->p4type = P4_ADVANCE; + break; + } + case OP_Prev: + case OP_PrevIfOpen: { + pOp->p4.xAdvance = sqlite3BtreePrevious; + pOp->p4type = P4_ADVANCE; + break; + } } - case OP_Prev: - case OP_PrevIfOpen: { - pOp->p4.xAdvance = sqlite3BtreePrevious; - pOp->p4type = P4_ADVANCE; - break; + if( (sqlite3OpcodeProperty[pOp->opcode] & OPFLG_JUMP)!=0 && pOp->p2<0 ){ + assert( ADDR(pOp->p2)nLabel ); + pOp->p2 = aLabel[ADDR(pOp->p2)]; } } - - pOp->opflags = sqlite3OpcodeProperty[opcode]; - if( (pOp->opflags & OPFLG_JUMP)!=0 && pOp->p2<0 ){ - assert( ADDR(pOp->p2)nLabel ); - pOp->p2 = aLabel[ADDR(pOp->p2)]; - } + if( pOp==p->aOp ) break; + pOp--; } sqlite3DbFree(p->db, pParse->aLabel); pParse->aLabel = 0; diff --git a/tool/mkopcodeh.tcl b/tool/mkopcodeh.tcl index 053c7f8984..c3dfc1cd4d 100644 --- a/tool/mkopcodeh.tcl +++ b/tool/mkopcodeh.tcl @@ -20,8 +20,7 @@ # during code generation, we need to generate corresponding opcodes like # OP_Add and OP_Divide. By making TK_ADD==OP_Add and TK_DIVIDE==OP_Divide, # code to translate from one to the other is avoided. This makes the -# code generator run (infinitesimally) faster and more importantly it makes -# the library footprint smaller. +# code generator smaller and faster. # # This script also scans for lines of the form: # @@ -159,7 +158,29 @@ for {set i 0} {$i<$nOp} {incr i} { } } -# Generate the numeric values for remaining opcodes +# Assign the next group of values to JUMP opcodes +# +for {set i 0} {$i<$nOp} {incr i} { + set name $order($i) + if {$op($name)>=0} continue + if {!$jump($name)} continue + incr cnt + while {[info exists used($cnt)]} {incr cnt} + set op($name) $cnt + set used($cnt) 1 + set def($cnt) $name +} + +# Find the numeric value for the largest JUMP opcode +# +set mxJump -1 +for {set i 0} {$i<$nOp} {incr i} { + set name $order($i) + if {$jump($name) && $op($name)>$mxJump} {set mxJump $op($name)} +} + + +# Generate the numeric values for all remaining opcodes # for {set i 0} {$i<$nOp} {incr i} { set name $order($i) @@ -232,3 +253,11 @@ for {set i 0} {$i<=$max} {incr i} { } } puts "\175" +puts "" +puts "/* The sqlite3P2Values() routine is able to run faster if it knows" +puts "** the value of the largest JUMP opcode. The smaller the maximum" +puts "** JUMP opcode the better, so the mkopcodeh.tcl script that" +puts "** generated this include file strives to group all JUMP opcodes" +puts "** together near the beginning of the list." +puts "*/" +puts "#define OP_MX_JUMP $mxJump /* Maximum JUMP opcode */" From 4f0010b1bc5c67e2cee4424beef6b55630925481 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 11 Apr 2016 14:49:39 +0000 Subject: [PATCH 0273/1484] Performance improvement in sqlite3ExprDelete(). FossilOrigin-Name: 60ad80e3af4bae9f5c74fedf09eec9689e2e3dbf --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/expr.c | 7 +++++-- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index ce95096bc7..e8516c64fd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sthe\sVdbeOp.opflags\sfield\sand\sits\sassociated\sinitialization\soverhead.\nUpdate\smkopcodeh.tcl\sto\sreorder\sopcode\snumbers\sto\shelp\sthe\sresolveP2Values()\nroutine\srun\sfaster. -D 2016-04-11T13:36:42.250 +C Performance\simprovement\sin\ssqlite3ExprDelete(). +D 2016-04-11T14:49:39.785 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1f123a0757f6f04f0341accb46457e116817159a @@ -329,7 +329,7 @@ F src/ctime.c 60e135af364d777a9ab41c97e5e89cd224da6198 F src/date.c 0b73e681c11fca867fec554750c07fe0d4e417c1 F src/dbstat.c c845548d4346e606e2f2b7d2e714ace2b8a7dd1b F src/delete.c 78eb999114ec04fcf1b7d123ccedb4b5b734930e -F src/expr.c a195d2d047ca59f9b87cae737b785d17cdd3cc3f +F src/expr.c 702260035c6f23051bdae7a0be28e4884b892386 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 4c0bd09e602b8ae8d36d81e31e4872d0b53c87bb F src/func.c 552d300265aed09eea21f68ac742a440550c0062 @@ -1482,7 +1482,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ef1966c2469a0f5dbdb31a0287bd37badb2b8f28 -R 39896b563a0174d278e56658538b5996 +P 099478fa7521ba52262ef2bf24dd8f0114ce92e1 +R 5159c43d8f5df7b2df207c9931eea763 U drh -Z 4b0063de72cbcb5b307015ce248a50de +Z 20edece30066cfe56abf703e4a6fcff0 diff --git a/manifest.uuid b/manifest.uuid index 9a8e083986..fd8709802d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -099478fa7521ba52262ef2bf24dd8f0114ce92e1 \ No newline at end of file +60ad80e3af4bae9f5c74fedf09eec9689e2e3dbf \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 6792f26a55..d11a7a87b0 100644 --- a/src/expr.c +++ b/src/expr.c @@ -738,8 +738,8 @@ void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr){ /* ** Recursively delete an expression tree. */ -void sqlite3ExprDelete(sqlite3 *db, Expr *p){ - if( p==0 ) return; +static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){ + assert( p!=0 ); /* Sanity check: Assert that the IntValue is non-negative if it exists */ assert( !ExprHasProperty(p, EP_IntValue) || p->u.iValue>=0 ); if( !ExprHasProperty(p, EP_TokenOnly) ){ @@ -758,6 +758,9 @@ void sqlite3ExprDelete(sqlite3 *db, Expr *p){ sqlite3DbFree(db, p); } } +void sqlite3ExprDelete(sqlite3 *db, Expr *p){ + if( p ) sqlite3ExprDeleteNN(db, p); +} /* ** Return the number of bytes allocated for the expression structure From c310db39ffa637c84c905e74144d9eebcad11eb4 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 11 Apr 2016 16:35:05 +0000 Subject: [PATCH 0274/1484] Rename the OP_MX_JUMP macro to SQLITE_MX_JUMP_OPCODE to avoid confusing the opcode name generator. FossilOrigin-Name: e554a4c38bda9c73bf129bb7c665c53ccc4d96a8 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/vdbeaux.c | 4 ++-- tool/mkopcodeh.tcl | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index e8516c64fd..8bc65f07d1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Performance\simprovement\sin\ssqlite3ExprDelete(). -D 2016-04-11T14:49:39.785 +C Rename\sthe\sOP_MX_JUMP\smacro\sto\sSQLITE_MX_JUMP_OPCODE\sto\savoid\sconfusing\sthe\nopcode\sname\sgenerator. +D 2016-04-11T16:35:05.793 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1f123a0757f6f04f0341accb46457e116817159a @@ -445,7 +445,7 @@ F src/vdbe.c d3843a66d74a7696477ee5141e5eb9a7e5e2401c F src/vdbe.h 5591b5add447096e31288b5a0a78ec5d7b5c5170 F src/vdbeInt.h ddb157974436d87652de7dc641f7191496d9a8cd F src/vdbeapi.c ba85b78fe08dc4a9ce747e62c89a2b4a4547e74c -F src/vdbeaux.c b0bd706639fda1ee3aa786b3a01a798e13e811d4 +F src/vdbeaux.c ace1875da40b7185e604586768d5ac90de7e4f7f F src/vdbeblob.c c9f2f494b911c6fa34efd9803f0a10807da80f77 F src/vdbemem.c 5cfef60e60e19cab6275d1b975bf4c791d575beb F src/vdbesort.c 307460bfa4de4d1c3901fcd42089159131e34062 @@ -1420,7 +1420,7 @@ F tool/mkautoconfamal.sh e855df211ecbcc7131dee817110ff386cfb112f7 F tool/mkkeywordhash.c f7f3b342211ac6a14258b9726d5b97cf4f548f22 F tool/mkmsvcmin.tcl 2f12f7fa8858bbe61cf81820a2da96c79ed1ca8d F tool/mkopcodec.tcl d1b6362bd3aa80d5520d4d6f3765badf01f6c43c -F tool/mkopcodeh.tcl 3b1ee0fd2452b0e2c0381956269a9ac3788255a3 +F tool/mkopcodeh.tcl a01d2c1d8a6205b03fc635adf3735b4c523befd3 F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e F tool/mkpragmatab.tcl f0d5bb266d1d388cf86fce5ba01a891e95d72d41 F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 @@ -1482,7 +1482,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 099478fa7521ba52262ef2bf24dd8f0114ce92e1 -R 5159c43d8f5df7b2df207c9931eea763 +P 60ad80e3af4bae9f5c74fedf09eec9689e2e3dbf +R f6edf7124a508a9e875e2a5fe8999259 U drh -Z 20edece30066cfe56abf703e4a6fcff0 +Z 1a9da7914d71f57fbfab1a0d0fb98803 diff --git a/manifest.uuid b/manifest.uuid index fd8709802d..d8dad99228 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -60ad80e3af4bae9f5c74fedf09eec9689e2e3dbf \ No newline at end of file +e554a4c38bda9c73bf129bb7c665c53ccc4d96a8 \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index d3f2b6b7bc..0f9dab8e19 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -564,9 +564,9 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){ ** below need to be considered. The mkopcodeh.tcl generator script groups ** all these opcodes together near the front of the opcode list. Skip ** any opcode that does not need processing by virtual of the fact that - ** it is larger than OP_MX_JUMP, as a performance optimization. + ** it is larger than SQLITE_MX_JUMP_OPCODE, as a performance optimization. */ - if( pOp->opcode<=OP_MX_JUMP ){ + if( pOp->opcode<=SQLITE_MX_JUMP_OPCODE ){ /* NOTE: Be sure to update mkopcodeh.tcl when adding or removing ** cases from this switch! */ switch( pOp->opcode ){ diff --git a/tool/mkopcodeh.tcl b/tool/mkopcodeh.tcl index c3dfc1cd4d..3c2a59789c 100644 --- a/tool/mkopcodeh.tcl +++ b/tool/mkopcodeh.tcl @@ -260,4 +260,4 @@ puts "** JUMP opcode the better, so the mkopcodeh.tcl script that" puts "** generated this include file strives to group all JUMP opcodes" puts "** together near the beginning of the list." puts "*/" -puts "#define OP_MX_JUMP $mxJump /* Maximum JUMP opcode */" +puts "#define SQLITE_MX_JUMP_OPCODE $mxJump /* Maximum JUMP opcode */" From 3c19469ca2cdcbd9a265c0d59b0604632afad3a4 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 11 Apr 2016 16:43:43 +0000 Subject: [PATCH 0275/1484] Simplification and performance improvements in sqlite3ExprDup() and its subroutines. More work is possible in this area. FossilOrigin-Name: 476cc2838824e0667e80ce527b9caa551dee4a77 --- manifest | 12 ++--- manifest.uuid | 2 +- src/expr.c | 146 +++++++++++++++++++++++++------------------------- 3 files changed, 80 insertions(+), 80 deletions(-) diff --git a/manifest b/manifest index 8bc65f07d1..c6cd43627e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Rename\sthe\sOP_MX_JUMP\smacro\sto\sSQLITE_MX_JUMP_OPCODE\sto\savoid\sconfusing\sthe\nopcode\sname\sgenerator. -D 2016-04-11T16:35:05.793 +C Simplification\sand\sperformance\simprovements\sin\ssqlite3ExprDup()\sand\sits\nsubroutines.\s\sMore\swork\sis\spossible\sin\sthis\sarea. +D 2016-04-11T16:43:43.285 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1f123a0757f6f04f0341accb46457e116817159a @@ -329,7 +329,7 @@ F src/ctime.c 60e135af364d777a9ab41c97e5e89cd224da6198 F src/date.c 0b73e681c11fca867fec554750c07fe0d4e417c1 F src/dbstat.c c845548d4346e606e2f2b7d2e714ace2b8a7dd1b F src/delete.c 78eb999114ec04fcf1b7d123ccedb4b5b734930e -F src/expr.c 702260035c6f23051bdae7a0be28e4884b892386 +F src/expr.c 16829fcf84b41d16b3d2e74e4e30ea8315cbba88 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 4c0bd09e602b8ae8d36d81e31e4872d0b53c87bb F src/func.c 552d300265aed09eea21f68ac742a440550c0062 @@ -1482,7 +1482,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 60ad80e3af4bae9f5c74fedf09eec9689e2e3dbf -R f6edf7124a508a9e875e2a5fe8999259 +P e554a4c38bda9c73bf129bb7c665c53ccc4d96a8 +R ddaad63736e0e0e6322e4bbbe74f8062 U drh -Z 1a9da7914d71f57fbfab1a0d0fb98803 +Z db16ea712247dfbc518b4dea8f54265a diff --git a/manifest.uuid b/manifest.uuid index d8dad99228..c7adec1100 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e554a4c38bda9c73bf129bb7c665c53ccc4d96a8 \ No newline at end of file +476cc2838824e0667e80ce527b9caa551dee4a77 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index d11a7a87b0..53ba58101c 100644 --- a/src/expr.c +++ b/src/expr.c @@ -812,7 +812,7 @@ static int dupedExprStructSize(Expr *p, int flags){ assert( flags==EXPRDUP_REDUCE || flags==0 ); /* Only one flag value allowed */ assert( EXPR_FULLSIZE<=0xfff ); assert( (0xfff & (EP_Reduced|EP_TokenOnly))==0 ); - if( 0==(flags&EXPRDUP_REDUCE) ){ + if( 0==flags ){ nSize = EXPR_FULLSIZE; }else{ assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) ); @@ -874,88 +874,88 @@ static int dupedExprSize(Expr *p, int flags){ ** if any. Before returning, *pzBuffer is set to the first byte past the ** portion of the buffer copied into by this function. */ -static Expr *exprDup(sqlite3 *db, Expr *p, int flags, u8 **pzBuffer){ - Expr *pNew = 0; /* Value to return */ - assert( flags==0 || flags==EXPRDUP_REDUCE ); +static Expr *exprDup(sqlite3 *db, Expr *p, int dupFlags, u8 **pzBuffer){ + Expr *pNew; /* Value to return */ + u8 *zAlloc; /* Memory space from which to build Expr object */ + u32 staticFlag; /* EP_Static if space not obtained from malloc */ + assert( db!=0 ); - if( p ){ - const int isReduced = (flags&EXPRDUP_REDUCE); - u8 *zAlloc; - u32 staticFlag = 0; + assert( p ); + assert( dupFlags==0 || dupFlags==EXPRDUP_REDUCE ); + assert( pzBuffer==0 || dupFlags==EXPRDUP_REDUCE ); - assert( pzBuffer==0 || isReduced ); + /* Figure out where to write the new Expr structure. */ + if( pzBuffer ){ + zAlloc = *pzBuffer; + staticFlag = EP_Static; + }else{ + zAlloc = sqlite3DbMallocRawNN(db, dupedExprSize(p, dupFlags)); + staticFlag = 0; + } + pNew = (Expr *)zAlloc; - /* Figure out where to write the new Expr structure. */ - if( pzBuffer ){ - zAlloc = *pzBuffer; - staticFlag = EP_Static; + if( pNew ){ + /* Set nNewSize to the size allocated for the structure pointed to + ** by pNew. This is either EXPR_FULLSIZE, EXPR_REDUCEDSIZE or + ** EXPR_TOKENONLYSIZE. nToken is set to the number of bytes consumed + ** by the copy of the p->u.zToken string (if any). + */ + const unsigned nStructSize = dupedExprStructSize(p, dupFlags); + const int nNewSize = nStructSize & 0xfff; + int nToken; + if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){ + nToken = sqlite3Strlen30(p->u.zToken) + 1; }else{ - zAlloc = sqlite3DbMallocRawNN(db, dupedExprSize(p, flags)); + nToken = 0; + } + if( dupFlags ){ + assert( ExprHasProperty(p, EP_Reduced)==0 ); + memcpy(zAlloc, p, nNewSize); + }else{ + u32 nSize = (u32)exprStructSize(p); + memcpy(zAlloc, p, nSize); + if( nSizeu.zToken string (if any). - */ - const unsigned nStructSize = dupedExprStructSize(p, flags); - const int nNewSize = nStructSize & 0xfff; - int nToken; - if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){ - nToken = sqlite3Strlen30(p->u.zToken) + 1; + /* Set the EP_Reduced, EP_TokenOnly, and EP_Static flags appropriately. */ + pNew->flags &= ~(EP_Reduced|EP_TokenOnly|EP_Static|EP_MemToken); + pNew->flags |= nStructSize & (EP_Reduced|EP_TokenOnly); + pNew->flags |= staticFlag; + + /* Copy the p->u.zToken string, if any. */ + if( nToken ){ + char *zToken = pNew->u.zToken = (char*)&zAlloc[nNewSize]; + memcpy(zToken, p->u.zToken, nToken); + } + + if( 0==((p->flags|pNew->flags) & EP_TokenOnly) ){ + /* Fill in the pNew->x.pSelect or pNew->x.pList member. */ + if( ExprHasProperty(p, EP_xIsSelect) ){ + pNew->x.pSelect = sqlite3SelectDup(db, p->x.pSelect, dupFlags); }else{ - nToken = 0; + pNew->x.pList = sqlite3ExprListDup(db, p->x.pList, dupFlags); } - if( isReduced ){ - assert( ExprHasProperty(p, EP_Reduced)==0 ); - memcpy(zAlloc, p, nNewSize); - }else{ - u32 nSize = (u32)exprStructSize(p); - memcpy(zAlloc, p, nSize); - if( nSizepLeft and pNew->pRight. */ + if( ExprHasProperty(pNew, EP_Reduced|EP_TokenOnly) ){ + zAlloc += dupedExprNodeSize(p, dupFlags); + if( ExprHasProperty(pNew, EP_Reduced) ){ + pNew->pLeft = p->pLeft ? + exprDup(db, p->pLeft, EXPRDUP_REDUCE, &zAlloc) : 0; + pNew->pRight = p->pRight ? + exprDup(db, p->pRight, EXPRDUP_REDUCE, &zAlloc) : 0; } - - /* Set the EP_Reduced, EP_TokenOnly, and EP_Static flags appropriately. */ - pNew->flags &= ~(EP_Reduced|EP_TokenOnly|EP_Static|EP_MemToken); - pNew->flags |= nStructSize & (EP_Reduced|EP_TokenOnly); - pNew->flags |= staticFlag; - - /* Copy the p->u.zToken string, if any. */ - if( nToken ){ - char *zToken = pNew->u.zToken = (char*)&zAlloc[nNewSize]; - memcpy(zToken, p->u.zToken, nToken); + if( pzBuffer ){ + *pzBuffer = zAlloc; } - - if( 0==((p->flags|pNew->flags) & EP_TokenOnly) ){ - /* Fill in the pNew->x.pSelect or pNew->x.pList member. */ - if( ExprHasProperty(p, EP_xIsSelect) ){ - pNew->x.pSelect = sqlite3SelectDup(db, p->x.pSelect, isReduced); - }else{ - pNew->x.pList = sqlite3ExprListDup(db, p->x.pList, isReduced); - } + }else{ + if( !ExprHasProperty(p, EP_TokenOnly) ){ + pNew->pLeft = sqlite3ExprDup(db, p->pLeft, 0); + pNew->pRight = sqlite3ExprDup(db, p->pRight, 0); } - - /* Fill in pNew->pLeft and pNew->pRight. */ - if( ExprHasProperty(pNew, EP_Reduced|EP_TokenOnly) ){ - zAlloc += dupedExprNodeSize(p, flags); - if( ExprHasProperty(pNew, EP_Reduced) ){ - pNew->pLeft = exprDup(db, p->pLeft, EXPRDUP_REDUCE, &zAlloc); - pNew->pRight = exprDup(db, p->pRight, EXPRDUP_REDUCE, &zAlloc); - } - if( pzBuffer ){ - *pzBuffer = zAlloc; - } - }else{ - if( !ExprHasProperty(p, EP_TokenOnly) ){ - pNew->pLeft = sqlite3ExprDup(db, p->pLeft, 0); - pNew->pRight = sqlite3ExprDup(db, p->pRight, 0); - } - } - } } return pNew; @@ -1007,7 +1007,7 @@ static With *withDup(sqlite3 *db, With *p){ */ Expr *sqlite3ExprDup(sqlite3 *db, Expr *p, int flags){ assert( flags==0 || flags==EXPRDUP_REDUCE ); - return exprDup(db, p, flags, 0); + return p ? exprDup(db, p, flags, 0) : 0; } ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p, int flags){ ExprList *pNew; From 67330a1224271e0186445c8f68754b214991df3a Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 11 Apr 2016 18:07:47 +0000 Subject: [PATCH 0276/1484] Fixes for OOM and IO error handling with temp file databases. FossilOrigin-Name: 4eb06e843af60d5e533793618c6e0e9b7ef7a1a6 --- manifest | 15 +++--- manifest.uuid | 2 +- src/pager.c | 15 +++--- test/cffault.test | 2 +- test/tempfault.test | 114 ++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 133 insertions(+), 15 deletions(-) create mode 100644 test/tempfault.test diff --git a/manifest b/manifest index 2cc5625474..1c7823a2ff 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\sthis\sbranch\swith\sthe\slatest\schanges\sfrom\sthe\strunk. -D 2016-04-11T09:39:25.021 +C Fixes\sfor\sOOM\sand\sIO\serror\shandling\swith\stemp\sfile\sdatabases. +D 2016-04-11T18:07:47.205 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1f123a0757f6f04f0341accb46457e116817159a @@ -362,7 +362,7 @@ F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa F src/os_unix.c bde4844f0849cab5924c6a81178f8500774ce76b F src/os_win.c b3ba9573d8d893e70a6a8015bbee572ecf7ffbef F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca -F src/pager.c 91d7462aa2429e30d64c705f75ba36cace90c241 +F src/pager.c 4cc8a5b3979db65725eaa03650a6d54219122b8d F src/pager.h e1d38a2f14849e219df0f91f8323504d134c8a56 F src/parse.y 52cdeb4f37634d0ccd2998aab099b7bbb690b0d3 F src/pcache.c e9c00846d3dcdaa75b288c6f16238c2fe2177823 @@ -551,7 +551,7 @@ F test/capi3c.test 0b9edb0c2156a964b9271cd5ea7ae56736cc2fcb F test/capi3d.test 485048dc5cd07bc68011e4917ad035ad6047ab82 F test/capi3e.test 3d49c01ef2a1a55f41d73cba2b23b5059ec460fe F test/cast.test 4c275cbdc8202d6f9c54a3596701719868ac7dc3 -F test/cffault.test aadc1f61f8811cb600e3e069acbf8796f472a096 +F test/cffault.test 9d6b20606afe712374952eec4f8fd74b1a8097ef F test/check.test 85a84bfc4be0e83f668747211c7cd45a6721d485 F test/close.test 83947daf3b700631f90f4850ddaab455be4af73d F test/closure01.test b1703ba40639cfc9b295cf478d70739415eec6a4 @@ -1109,6 +1109,7 @@ F test/tableapi.test 2674633fa95d80da917571ebdd759a14d9819126 F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930 F test/tclsqlite.test e1306001a0ca92250b691ea6d3cecaca5b6342aa F test/tempdb.test bd92eba8f20e16a9136e434e20b280794de3cdb6 +F test/tempfault.test 0c80f23c651cf6452c27cacf09f4c2ee9527a912 F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30 F test/temptable2.test 707c01c00b4a8fd050e0db5dcef448e998b9ddb5 F test/temptrigger.test 8ec228b0db5d7ebc4ee9b458fc28cb9e7873f5e1 @@ -1483,7 +1484,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 84c557010c211595d2ec80b62c63af1c7f4714bd ef1966c2469a0f5dbdb31a0287bd37badb2b8f28 -R 95ac2720b81ae4f698b1e227fe8fc71b +P 982b753d0b6a3ed9fba33ed41523b2cd42280276 +R 46e56336ea4184d65ce3043234f11f03 U dan -Z 4e2c4b80dd3173e2cb79a80f72f7a7a8 +Z 58afa17a4e51610cdca345488b854923 diff --git a/manifest.uuid b/manifest.uuid index 9b0cbf0915..9e8a4101e2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -982b753d0b6a3ed9fba33ed41523b2cd42280276 \ No newline at end of file +4eb06e843af60d5e533793618c6e0e9b7ef7a1a6 \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index 79dbaec5c2..9baddc2986 100644 --- a/src/pager.c +++ b/src/pager.c @@ -958,7 +958,7 @@ static int assert_pager_state(Pager *p){ ** back to OPEN state. */ assert( pPager->errCode!=SQLITE_OK ); - assert( sqlite3PcacheRefCount(pPager->pPCache)>0 ); + assert( sqlite3PcacheRefCount(pPager->pPCache)>0 || pPager->tempFile ); break; } @@ -1819,11 +1819,14 @@ static void pager_unlock(Pager *pPager){ ** trusted. Now that there are no outstanding references to the pager, ** it can safely move back to PAGER_OPEN state. This happens in both ** normal and exclusive-locking mode. - */ - if( pPager->errCode ){ - assert( !MEMDB ); + ** + ** Exception: There is no way out of the error state for temp files. + ** This is because it is not possible to call pager_reset() on a temp + ** file pager (as this may discard the only copy of some data). */ + assert( pPager->errCode==SQLITE_OK || !MEMDB ); + if( pPager->tempFile==0 && pPager->errCode ){ pager_reset(pPager); - pPager->changeCountDone = pPager->tempFile; + pPager->changeCountDone = 0; pPager->eState = PAGER_OPEN; pPager->errCode = SQLITE_OK; if( USEFETCH(pPager) ) sqlite3OsUnfetch(pPager->fd, 0, 0); @@ -5034,8 +5037,8 @@ int sqlite3PagerSharedLock(Pager *pPager){ */ assert( sqlite3PcacheRefCount(pPager->pPCache)==0 ); assert( assert_pager_state(pPager) ); + if( pPager->tempFile && pPager->errCode ) { return pPager->errCode; } assert( pPager->eState==PAGER_OPEN || pPager->eState==PAGER_READER ); - if( NEVER(MEMDB && pPager->errCode) ){ return pPager->errCode; } if( !pagerUseWal(pPager) && pPager->eState==PAGER_OPEN ){ int bHotJournal = 1; /* True if there exists a hot journal-file */ diff --git a/test/cffault.test b/test/cffault.test index 79cefd24c4..0d029ece37 100644 --- a/test/cffault.test +++ b/test/cffault.test @@ -15,7 +15,7 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl -set testprefix cacheflush +set testprefix cffault source $testdir/malloc_common.tcl # Run the supplied SQL on a copy of the database currently stored on diff --git a/test/tempfault.test b/test/tempfault.test new file mode 100644 index 0000000000..da1ae12375 --- /dev/null +++ b/test/tempfault.test @@ -0,0 +1,114 @@ +# 2016 April 11 +# +# 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 contains tests for fault-injection when SQLite is used with +# a temp file database. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +source $testdir/malloc_common.tcl +set testprefix tempfault + +sqlite3_memdebug_vfs_oom_test 0 + +do_faultsim_test 1 -faults oom* -prep { + sqlite3 db "" + db eval { + PRAGMA page_size = 1024; + CREATE TABLE t1(a, b); + INSERT INTO t1 VALUES(1, 2); + INSERT INTO t1 VALUES(3, 4); + } +} -body { + execsql { INSERT INTO t1 VALUES(5, 6) } +} -test { + faultsim_test_result {0 {}} + set rc [catch { execsql { SELECT * FROM t1 } } msg] + if {$rc==0 && $msg != "1 2 3 4 5 6" && $msg != "1 2 3 4"} { + error "data mismatch 1: $msg" + } + if {$testrc==0 && $msg != "1 2 3 4 5 6"} { + error "data mismatch 2: $msg" + } + faultsim_integrity_check +} + +do_faultsim_test 2 -faults oom* -prep { + sqlite3 db "" + db eval { + PRAGMA page_size = 1024; + PRAGMA cache_size = 10; + CREATE TABLE t1(a, b); + CREATE INDEX i1 ON t1(b, a); + WITH x(i) AS (SELECT 1 UNION ALL SELECT i+1 FROM x WHERE i<50) + INSERT INTO t1 SELECT randomblob(100), randomblob(100) FROM x; + } +} -body { + execsql { UPDATE t1 SET a = randomblob(99) } +} -test { + faultsim_test_result {0 {}} + faultsim_integrity_check db +} + +do_faultsim_test 3 -faults oom* -prep { + sqlite3 db "" + db eval { + PRAGMA page_size = 1024; + PRAGMA cache_size = 10; + CREATE TABLE t1(a, b); + CREATE INDEX i1 ON t1(b, a); + WITH x(i) AS (SELECT 1 UNION ALL SELECT i+1 FROM x WHERE i<50) + INSERT INTO t1 SELECT randomblob(100), randomblob(100) FROM x; + } +} -body { + execsql { + BEGIN; + UPDATE t1 SET a = randomblob(99); + SAVEPOINT abc; + UPDATE t1 SET a = randomblob(98) WHERE (rowid%10)==0; + ROLLBACK TO abc; + UPDATE t1 SET a = randomblob(97) WHERE (rowid%5)==0; + ROLLBACK TO abc; + COMMIT; + } +} -test { + faultsim_test_result {0 {}} + faultsim_integrity_check db +} + +do_faultsim_test 4 -faults * -prep { + sqlite3 db "" + db eval { + PRAGMA page_size = 1024; + PRAGMA cache_size = 10; + CREATE TABLE t1(a, b); + CREATE INDEX i1 ON t1(b, a); + WITH x(i) AS (SELECT 1 UNION ALL SELECT i+1 FROM x WHERE i<50) + INSERT INTO t1 SELECT randomblob(100), randomblob(100) FROM x; + } +} -body { + execsql { + BEGIN; + UPDATE t1 SET a = randomblob(99); + SAVEPOINT abc; + UPDATE t1 SET a = randomblob(98) WHERE (rowid%10)==0; + ROLLBACK TO abc; + UPDATE t1 SET a = randomblob(97) WHERE (rowid%5)==0; + ROLLBACK TO abc; + COMMIT; + } +} -test { + faultsim_test_result {0 {}} +} + +sqlite3_memdebug_vfs_oom_test 1 +finish_test From bea119cdebd9fa581302c0e3f5d8c31ca0628965 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 11 Apr 2016 18:15:37 +0000 Subject: [PATCH 0277/1484] Performance optimizations in the column cache of the code generator, and especially the sqlite3ExprCacheRemove() routine. FossilOrigin-Name: e35b345cf858018ae0c07f79725f8d58062168db --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/expr.c | 36 ++++++++++++++++++++++++++---------- src/sqliteInt.h | 1 + 4 files changed, 35 insertions(+), 18 deletions(-) diff --git a/manifest b/manifest index c6cd43627e..278efe9dfc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Simplification\sand\sperformance\simprovements\sin\ssqlite3ExprDup()\sand\sits\nsubroutines.\s\sMore\swork\sis\spossible\sin\sthis\sarea. -D 2016-04-11T16:43:43.285 +C Performance\soptimizations\sin\sthe\scolumn\scache\sof\sthe\scode\sgenerator,\sand\nespecially\sthe\ssqlite3ExprCacheRemove()\sroutine. +D 2016-04-11T18:15:37.821 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1f123a0757f6f04f0341accb46457e116817159a @@ -329,7 +329,7 @@ F src/ctime.c 60e135af364d777a9ab41c97e5e89cd224da6198 F src/date.c 0b73e681c11fca867fec554750c07fe0d4e417c1 F src/dbstat.c c845548d4346e606e2f2b7d2e714ace2b8a7dd1b F src/delete.c 78eb999114ec04fcf1b7d123ccedb4b5b734930e -F src/expr.c 16829fcf84b41d16b3d2e74e4e30ea8315cbba88 +F src/expr.c 22d553f3e6425586513219a9dfbbf6c57581c736 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 4c0bd09e602b8ae8d36d81e31e4872d0b53c87bb F src/func.c 552d300265aed09eea21f68ac742a440550c0062 @@ -380,7 +380,7 @@ F src/shell.c b7922fa264f8c8d72a5ec6dd0b091e15a93c4de5 F src/sqlite.h.in c8f41612dc1a9b5212a891e1b65a5f589b8b884a F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 98f72cbfe00169c39089115427d06ea05fe4b4a2 -F src/sqliteInt.h 8a3ca5847b3cbd0ee3333f5615e3db049f550727 +F src/sqliteInt.h e4a3229829dd20db9a0348d2119711272c33c757 F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 @@ -1482,7 +1482,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e554a4c38bda9c73bf129bb7c665c53ccc4d96a8 -R ddaad63736e0e0e6322e4bbbe74f8062 +P 476cc2838824e0667e80ce527b9caa551dee4a77 +R add6544c70f21201cd7c87d168cad7da U drh -Z db16ea712247dfbc518b4dea8f54265a +Z 1ce8fe8f94193e403ead86e0c919fda1 diff --git a/manifest.uuid b/manifest.uuid index c7adec1100..ce5bbdda1c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -476cc2838824e0667e80ce527b9caa551dee4a77 \ No newline at end of file +e35b345cf858018ae0c07f79725f8d58062168db \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 53ba58101c..37a7624db1 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2335,6 +2335,19 @@ static void codeInteger(Parse *pParse, Expr *pExpr, int negFlag, int iMem){ } } +#if defined(SQLITE_DEBUG) +/* +** Verify the consistency of the column cache +*/ +static int cacheIsValid(Parse *pParse){ + int i, n; + for(i=n=0; iaColCache[i].iReg>0 ) n++; + } + return n==pParse->nColCache; +} +#endif + /* ** Clear a cache entry. */ @@ -2345,6 +2358,9 @@ static void cacheEntryClear(Parse *pParse, struct yColCache *p){ } p->tempReg = 0; } + p->iReg = 0; + pParse->nColCache--; + assert( cacheIsValid(pParse) ); } @@ -2388,6 +2404,8 @@ void sqlite3ExprCacheStore(Parse *pParse, int iTab, int iCol, int iReg){ p->iReg = iReg; p->tempReg = 0; p->lru = pParse->iCacheCnt++; + pParse->nColCache++; + assert( cacheIsValid(pParse) ); return; } } @@ -2409,6 +2427,7 @@ void sqlite3ExprCacheStore(Parse *pParse, int iTab, int iCol, int iReg){ p->iReg = iReg; p->tempReg = 0; p->lru = pParse->iCacheCnt++; + assert( cacheIsValid(pParse) ); return; } } @@ -2418,15 +2437,13 @@ void sqlite3ExprCacheStore(Parse *pParse, int iTab, int iCol, int iReg){ ** Purge the range of registers from the column cache. */ void sqlite3ExprCacheRemove(Parse *pParse, int iReg, int nReg){ - int i; - int iLast = iReg + nReg - 1; struct yColCache *p; - for(i=0, p=pParse->aColCache; iiReg; - if( r>=iReg && r<=iLast ){ - cacheEntryClear(pParse, p); - p->iReg = 0; - } + if( iReg<=0 || pParse->nColCache==0 ) return; + p = &pParse->aColCache[SQLITE_N_COLCACHE-1]; + while(1){ + if( p->iReg >= iReg && p->iReg < iReg+nReg ) cacheEntryClear(pParse, p); + if( p==pParse->aColCache ) break; + p--; } } @@ -2462,7 +2479,6 @@ void sqlite3ExprCachePop(Parse *pParse){ for(i=0, p=pParse->aColCache; iiReg && p->iLevel>pParse->iCacheLevel ){ cacheEntryClear(pParse, p); - p->iReg = 0; } } } @@ -2597,7 +2613,6 @@ void sqlite3ExprCacheClear(Parse *pParse){ for(i=0, p=pParse->aColCache; iiReg ){ cacheEntryClear(pParse, p); - p->iReg = 0; } } } @@ -2639,6 +2654,7 @@ static int usedAsColumnCache(Parse *pParse, int iFrom, int iTo){ } #endif /* SQLITE_DEBUG || SQLITE_COVERAGE_TEST */ + /* ** Convert an expression node to a TK_REGISTER */ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index f9f449d967..1b0325254f 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2814,6 +2814,7 @@ struct Parse { u8 hasCompound; /* Need to invoke convertCompoundSelectToSubquery() */ u8 okConstFactor; /* OK to factor out constants */ u8 disableLookaside; /* Number of times lookaside has been disabled */ + u8 nColCache; /* Number of entries in aColCache[] */ int aTempReg[8]; /* Holding area for temporary registers */ int nRangeReg; /* Size of the temporary register block */ int iRangeReg; /* First register in temporary register block */ From affa855c94167e78b10d8b3bdbc1950aa30e695d Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 11 Apr 2016 18:25:05 +0000 Subject: [PATCH 0278/1484] Performance optimization for the sqlite3ExprListDelete() routine. FossilOrigin-Name: 2764aeaa11f38cf2ff4d6191e6d5466ddb203022 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/expr.c | 6 ++++-- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 278efe9dfc..464ea61dc8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Performance\soptimizations\sin\sthe\scolumn\scache\sof\sthe\scode\sgenerator,\sand\nespecially\sthe\ssqlite3ExprCacheRemove()\sroutine. -D 2016-04-11T18:15:37.821 +C Performance\soptimization\sfor\sthe\ssqlite3ExprListDelete()\sroutine. +D 2016-04-11T18:25:05.809 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1f123a0757f6f04f0341accb46457e116817159a @@ -329,7 +329,7 @@ F src/ctime.c 60e135af364d777a9ab41c97e5e89cd224da6198 F src/date.c 0b73e681c11fca867fec554750c07fe0d4e417c1 F src/dbstat.c c845548d4346e606e2f2b7d2e714ace2b8a7dd1b F src/delete.c 78eb999114ec04fcf1b7d123ccedb4b5b734930e -F src/expr.c 22d553f3e6425586513219a9dfbbf6c57581c736 +F src/expr.c 57fa7eb870a37c69a40cfe4c25b062e37fea12b7 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 4c0bd09e602b8ae8d36d81e31e4872d0b53c87bb F src/func.c 552d300265aed09eea21f68ac742a440550c0062 @@ -1482,7 +1482,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 476cc2838824e0667e80ce527b9caa551dee4a77 -R add6544c70f21201cd7c87d168cad7da +P e35b345cf858018ae0c07f79725f8d58062168db +R 042d362729c0d167c05760c4bdfc93ba U drh -Z 1ce8fe8f94193e403ead86e0c919fda1 +Z 1727510a3b08bf1e72294ab7bbf28d3f diff --git a/manifest.uuid b/manifest.uuid index ce5bbdda1c..ffdef1a398 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e35b345cf858018ae0c07f79725f8d58062168db \ No newline at end of file +2764aeaa11f38cf2ff4d6191e6d5466ddb203022 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 37a7624db1..0de6378c0a 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1278,10 +1278,9 @@ void sqlite3ExprListCheckLength( /* ** Delete an entire expression list. */ -void sqlite3ExprListDelete(sqlite3 *db, ExprList *pList){ +static SQLITE_NOINLINE void exprListDeleteNN(sqlite3 *db, ExprList *pList){ int i; struct ExprList_item *pItem; - if( pList==0 ) return; assert( pList->a!=0 || pList->nExpr==0 ); for(pItem=pList->a, i=0; inExpr; i++, pItem++){ sqlite3ExprDelete(db, pItem->pExpr); @@ -1291,6 +1290,9 @@ void sqlite3ExprListDelete(sqlite3 *db, ExprList *pList){ sqlite3DbFree(db, pList->a); sqlite3DbFree(db, pList); } +void sqlite3ExprListDelete(sqlite3 *db, ExprList *pList){ + if( pList ) exprListDeleteNN(db, pList); +} /* ** Return the bitwise-OR of all Expr.flags fields in the given From b9f11f932dd6b924d5707222c43a72ea2291464a Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 11 Apr 2016 18:49:37 +0000 Subject: [PATCH 0279/1484] Add extra tests to temptable2.test. FossilOrigin-Name: 7dd9d4c15bb6b6ef9127dc7c80a189c55e714dc9 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/temptable2.test | 37 +++++++++++++++++++++++++++++++++++++ 3 files changed, 44 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 1c7823a2ff..58157eb4f0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fixes\sfor\sOOM\sand\sIO\serror\shandling\swith\stemp\sfile\sdatabases. -D 2016-04-11T18:07:47.205 +C Add\sextra\stests\sto\stemptable2.test. +D 2016-04-11T18:49:37.527 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1f123a0757f6f04f0341accb46457e116817159a @@ -1111,7 +1111,7 @@ F test/tclsqlite.test e1306001a0ca92250b691ea6d3cecaca5b6342aa F test/tempdb.test bd92eba8f20e16a9136e434e20b280794de3cdb6 F test/tempfault.test 0c80f23c651cf6452c27cacf09f4c2ee9527a912 F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30 -F test/temptable2.test 707c01c00b4a8fd050e0db5dcef448e998b9ddb5 +F test/temptable2.test f04c411560dadebcc44aba631c602c908dfe1dd8 F test/temptrigger.test 8ec228b0db5d7ebc4ee9b458fc28cb9e7873f5e1 F test/tester.tcl 7b740ee852c55e1e72b6ebe5044acee7aa4e5553 F test/thread001.test 9f22fd3525a307ff42a326b6bc7b0465be1745a5 @@ -1484,7 +1484,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 982b753d0b6a3ed9fba33ed41523b2cd42280276 -R 46e56336ea4184d65ce3043234f11f03 +P 4eb06e843af60d5e533793618c6e0e9b7ef7a1a6 +R d2dfbf56b62d35c4cf496af1896eae37 U dan -Z 58afa17a4e51610cdca345488b854923 +Z db78b11117984d67b6a3aa7fe90754f9 diff --git a/manifest.uuid b/manifest.uuid index 9e8a4101e2..66abf69ec2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4eb06e843af60d5e533793618c6e0e9b7ef7a1a6 \ No newline at end of file +7dd9d4c15bb6b6ef9127dc7c80a189c55e714dc9 \ No newline at end of file diff --git a/test/temptable2.test b/test/temptable2.test index e87ffa89d9..af566ab529 100644 --- a/test/temptable2.test +++ b/test/temptable2.test @@ -269,5 +269,42 @@ do_test 8.6 { tmp close +#------------------------------------------------------------------------- +# Try inserts and deletes with a large db in auto-vacuum mode. Check +# +reset_db +do_execsql_test 9.1 { + PRAGMA cache_size = 15; + CREATE TABLE tx(a, b); + CREATE INDEX i1 ON tx(a); + CREATE INDEX i2 ON tx(b); + + WITH x(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM x WHERE i<1000 ) + INSERT INTO tx SELECT randomblob(100), randomblob(100) FROM x; +} +for {set i 2} {$i<20} {incr i} { + + do_execsql_test 9.$i.1 { DELETE FROM tx WHERE (random()%3)==0 } + + do_execsql_test 9.$i.2 { PRAGMA integrity_check } ok + + do_execsql_test 9.$i.3 { + WITH x(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM x WHERE i<400 ) + INSERT INTO tx SELECT randomblob(100), randomblob(100) FROM x; + } + + do_execsql_test 9.$i.4 { PRAGMA integrity_check } ok + + do_execsql_test 9.$i.5 { + BEGIN; + DELETE FROM tx WHERE (random()%3)==0; + WITH x(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM x WHERE i<500 ) + INSERT INTO tx SELECT randomblob(100), randomblob(100) FROM x; + COMMIT; + } + + do_execsql_test 9.$i.6 { PRAGMA integrity_check } ok +} + finish_test From 244b9d6ec67e84815d2f473b222b0dcb3ca657b3 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 11 Apr 2016 19:01:08 +0000 Subject: [PATCH 0280/1484] Performance optimization to sqlite3Dequote() and its callers. FossilOrigin-Name: 9efe2265b1e70172778d333c5b9d9a76095427ab --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/expr.c | 8 +++----- src/global.c | 7 ++++--- src/sqliteInt.h | 4 +++- src/util.c | 14 ++++---------- 6 files changed, 24 insertions(+), 29 deletions(-) diff --git a/manifest b/manifest index 464ea61dc8..855dd8a3ee 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Performance\soptimization\sfor\sthe\ssqlite3ExprListDelete()\sroutine. -D 2016-04-11T18:25:05.809 +C Performance\soptimization\sto\ssqlite3Dequote()\sand\sits\scallers. +D 2016-04-11T19:01:08.150 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1f123a0757f6f04f0341accb46457e116817159a @@ -329,11 +329,11 @@ F src/ctime.c 60e135af364d777a9ab41c97e5e89cd224da6198 F src/date.c 0b73e681c11fca867fec554750c07fe0d4e417c1 F src/dbstat.c c845548d4346e606e2f2b7d2e714ace2b8a7dd1b F src/delete.c 78eb999114ec04fcf1b7d123ccedb4b5b734930e -F src/expr.c 57fa7eb870a37c69a40cfe4c25b062e37fea12b7 +F src/expr.c 17d4e745ef6a3fd2e4ef863f5f9a4912f1ba1198 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 4c0bd09e602b8ae8d36d81e31e4872d0b53c87bb F src/func.c 552d300265aed09eea21f68ac742a440550c0062 -F src/global.c 884d4c7eba9f5fc25c96a23b21520da19b7713e2 +F src/global.c c45ea22aff29334f6a9ec549235ac3357c970015 F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5 F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 @@ -380,7 +380,7 @@ F src/shell.c b7922fa264f8c8d72a5ec6dd0b091e15a93c4de5 F src/sqlite.h.in c8f41612dc1a9b5212a891e1b65a5f589b8b884a F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 98f72cbfe00169c39089115427d06ea05fe4b4a2 -F src/sqliteInt.h e4a3229829dd20db9a0348d2119711272c33c757 +F src/sqliteInt.h b3744b29555b83054f315f62d61b3a6558fa9e1c F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 @@ -439,7 +439,7 @@ F src/treeview.c e4b41a37530a191579d3c53142cc44ee2eb99373 F src/trigger.c e14840ee0c3e549e758ec9bf3e4146e166002280 F src/update.c 3e67ab3c0814635f355fb1f8ab010a2b9e016e7d F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c -F src/util.c 19509465217b673b38d5804a72778908b138953f +F src/util.c 187a0a2aaa3c5d2ccd2ab0143b2fd9e86d6bc816 F src/vacuum.c feb1eabb20987983d9350cad98299b21fa811f52 F src/vdbe.c d3843a66d74a7696477ee5141e5eb9a7e5e2401c F src/vdbe.h 5591b5add447096e31288b5a0a78ec5d7b5c5170 @@ -1482,7 +1482,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e35b345cf858018ae0c07f79725f8d58062168db -R 042d362729c0d167c05760c4bdfc93ba +P 2764aeaa11f38cf2ff4d6191e6d5466ddb203022 +R 77a187fd869dda6e2e45282c54ce5af5 U drh -Z 1727510a3b08bf1e72294ab7bbf28d3f +Z 40ab6d9a31ee32331ca9ef8f86a7bc32 diff --git a/manifest.uuid b/manifest.uuid index ffdef1a398..cd319f925e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2764aeaa11f38cf2ff4d6191e6d5466ddb203022 \ No newline at end of file +9efe2265b1e70172778d333c5b9d9a76095427ab \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 0de6378c0a..094a454ab1 100644 --- a/src/expr.c +++ b/src/expr.c @@ -471,15 +471,13 @@ Expr *sqlite3ExprAlloc( pNew->flags |= EP_IntValue; pNew->u.iValue = iValue; }else{ - int c; pNew->u.zToken = (char*)&pNew[1]; assert( pToken->z!=0 || pToken->n==0 ); if( pToken->n ) memcpy(pNew->u.zToken, pToken->z, pToken->n); pNew->u.zToken[pToken->n] = 0; - if( dequote && nExtra>=3 - && ((c = pToken->z[0])=='\'' || c=='"' || c=='[' || c=='`') ){ + if( dequote && sqlite3Isquote(pNew->u.zToken[0]) ){ + if( pNew->u.zToken[0]=='"' ) pNew->flags |= EP_DblQuoted; sqlite3Dequote(pNew->u.zToken); - if( c=='"' ) pNew->flags |= EP_DblQuoted; } } } @@ -1229,7 +1227,7 @@ void sqlite3ExprListSetName( pItem = &pList->a[pList->nExpr-1]; assert( pItem->zName==0 ); pItem->zName = sqlite3DbStrNDup(pParse->db, pName->z, pName->n); - if( dequote && pItem->zName ) sqlite3Dequote(pItem->zName); + if( dequote ) sqlite3Dequote(pItem->zName); } } diff --git a/src/global.c b/src/global.c index bd70b38273..76901a89b1 100644 --- a/src/global.c +++ b/src/global.c @@ -70,6 +70,7 @@ const unsigned char sqlite3UpperToLower[] = { ** isxdigit() 0x08 ** toupper() 0x20 ** SQLite identifier character 0x40 +** Quote character 0x80 ** ** Bit 0x20 is set if the mapped character requires translation to upper ** case. i.e. if the character is a lower-case ASCII character. @@ -95,7 +96,7 @@ const unsigned char sqlite3CtypeMap[256] = { 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, /* 08..0f ........ */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 10..17 ........ */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 18..1f ........ */ - 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, /* 20..27 !"#$%&' */ + 0x01, 0x00, 0x80, 0x00, 0x40, 0x00, 0x00, 0x80, /* 20..27 !"#$%&' */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 28..2f ()*+,-./ */ 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, /* 30..37 01234567 */ 0x0c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 38..3f 89:;<=>? */ @@ -103,8 +104,8 @@ const unsigned char sqlite3CtypeMap[256] = { 0x00, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x02, /* 40..47 @ABCDEFG */ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* 48..4f HIJKLMNO */ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* 50..57 PQRSTUVW */ - 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x40, /* 58..5f XYZ[\]^_ */ - 0x00, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x22, /* 60..67 `abcdefg */ + 0x02, 0x02, 0x02, 0x80, 0x00, 0x00, 0x00, 0x40, /* 58..5f XYZ[\]^_ */ + 0x80, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x22, /* 60..67 `abcdefg */ 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, /* 68..6f hijklmno */ 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, /* 70..77 pqrstuvw */ 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, /* 78..7f xyz{|}~. */ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 1b0325254f..f9fab8e321 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3302,6 +3302,7 @@ int sqlite3CantopenError(int); # define sqlite3Isdigit(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x04) # define sqlite3Isxdigit(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x08) # define sqlite3Tolower(x) (sqlite3UpperToLower[(unsigned char)(x)]) +# define sqlite3Isquote(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x80) #else # define sqlite3Toupper(x) toupper((unsigned char)(x)) # define sqlite3Isspace(x) isspace((unsigned char)(x)) @@ -3310,6 +3311,7 @@ int sqlite3CantopenError(int); # define sqlite3Isdigit(x) isdigit((unsigned char)(x)) # define sqlite3Isxdigit(x) isxdigit((unsigned char)(x)) # define sqlite3Tolower(x) tolower((unsigned char)(x)) +# define sqlite3Isquote(x) ((x)=='"'||(x)=='\''||(x)=='['||(x)=='`') #endif #ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS int sqlite3IsIdChar(u8); @@ -3433,7 +3435,7 @@ char *sqlite3VMPrintf(sqlite3*,const char*, va_list); void sqlite3SetString(char **, sqlite3*, const char*); void sqlite3ErrorMsg(Parse*, const char*, ...); -int sqlite3Dequote(char*); +void sqlite3Dequote(char*); void sqlite3TokenInit(Token*,char*); int sqlite3KeywordCode(const unsigned char*, int); int sqlite3RunParser(Parse*, const char*, char **); diff --git a/src/util.c b/src/util.c index d2c6ec8e80..2f77a6033f 100644 --- a/src/util.c +++ b/src/util.c @@ -242,18 +242,13 @@ void sqlite3ErrorMsg(Parse *pParse, const char *zFormat, ...){ ** brackets from around identifiers. For example: "[a-b-c]" becomes ** "a-b-c". */ -int sqlite3Dequote(char *z){ +void sqlite3Dequote(char *z){ char quote; int i, j; - if( z==0 ) return -1; + if( z==0 ) return; quote = z[0]; - switch( quote ){ - case '\'': break; - case '"': break; - case '`': break; /* For MySQL compatibility */ - case '[': quote = ']'; break; /* For MS SqlServer compatibility */ - default: return -1; - } + if( !sqlite3Isquote(quote) ) return; + if( quote=='[' ) quote = ']'; for(i=1, j=0;; i++){ assert( z[i] ); if( z[i]==quote ){ @@ -268,7 +263,6 @@ int sqlite3Dequote(char *z){ } } z[j] = 0; - return j; } /* From b5a2592a9e1625b84b975d2bfbd2b8587bf58185 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 11 Apr 2016 19:23:36 +0000 Subject: [PATCH 0281/1484] Add tests for wal mode to temptable2.test. FossilOrigin-Name: c6d0d441a1ab4873caedf2f23543444cea5d7f5a --- manifest | 12 +++++----- manifest.uuid | 2 +- test/temptable2.test | 55 ++++++++++++++++++++++++++------------------ 3 files changed, 39 insertions(+), 30 deletions(-) diff --git a/manifest b/manifest index d5aafb59c4..017d301d54 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\slatest\strunk\schanges\swith\sthis\sbranch. -D 2016-04-11T18:50:25.500 +C Add\stests\sfor\swal\smode\sto\stemptable2.test. +D 2016-04-11T19:23:36.940 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1f123a0757f6f04f0341accb46457e116817159a @@ -1111,7 +1111,7 @@ F test/tclsqlite.test e1306001a0ca92250b691ea6d3cecaca5b6342aa F test/tempdb.test bd92eba8f20e16a9136e434e20b280794de3cdb6 F test/tempfault.test 0c80f23c651cf6452c27cacf09f4c2ee9527a912 F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30 -F test/temptable2.test f04c411560dadebcc44aba631c602c908dfe1dd8 +F test/temptable2.test 79a30edb79c4d5a4916f208f97935a70efd4b3ba F test/temptrigger.test 8ec228b0db5d7ebc4ee9b458fc28cb9e7873f5e1 F test/tester.tcl 7b740ee852c55e1e72b6ebe5044acee7aa4e5553 F test/thread001.test 9f22fd3525a307ff42a326b6bc7b0465be1745a5 @@ -1484,7 +1484,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 7dd9d4c15bb6b6ef9127dc7c80a189c55e714dc9 2764aeaa11f38cf2ff4d6191e6d5466ddb203022 -R 7b4c1f71edaf782a86682a72496a355b +P ffc62af1d503c6e7fc0059d9c2ee57a3bef9dd32 +R b5aaac24011d4d477c13603957856121 U dan -Z 4c9d4d3f9ec993332df2230efd24eb4f +Z 91cb540a3f9a28d737c21f7feeaff7cc diff --git a/manifest.uuid b/manifest.uuid index 0dd130d179..fa8dceac08 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ffc62af1d503c6e7fc0059d9c2ee57a3bef9dd32 \ No newline at end of file +c6d0d441a1ab4873caedf2f23543444cea5d7f5a \ No newline at end of file diff --git a/test/temptable2.test b/test/temptable2.test index af566ab529..44a148ddfb 100644 --- a/test/temptable2.test +++ b/test/temptable2.test @@ -272,38 +272,47 @@ tmp close #------------------------------------------------------------------------- # Try inserts and deletes with a large db in auto-vacuum mode. Check # -reset_db -do_execsql_test 9.1 { - PRAGMA cache_size = 15; - CREATE TABLE tx(a, b); - CREATE INDEX i1 ON tx(a); - CREATE INDEX i2 ON tx(b); +foreach {tn mode} { + 1 delete + 2 wal +} { + reset_db + do_execsql_test 9.$tn.1.1 { + PRAGMA cache_size = 15; + PRAGMA auto_vacuum = 1; + } + do_execsql_test 9.$tn.1.2 "PRAGMA journal_mode = $mode" $mode - WITH x(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM x WHERE i<1000 ) - INSERT INTO tx SELECT randomblob(100), randomblob(100) FROM x; -} -for {set i 2} {$i<20} {incr i} { - - do_execsql_test 9.$i.1 { DELETE FROM tx WHERE (random()%3)==0 } - - do_execsql_test 9.$i.2 { PRAGMA integrity_check } ok - - do_execsql_test 9.$i.3 { - WITH x(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM x WHERE i<400 ) + do_execsql_test 9.$tn.1.3 { + CREATE TABLE tx(a, b); + CREATE INDEX i1 ON tx(a); + CREATE INDEX i2 ON tx(b); + WITH x(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM x WHERE i<1000 ) INSERT INTO tx SELECT randomblob(100), randomblob(100) FROM x; } - do_execsql_test 9.$i.4 { PRAGMA integrity_check } ok + for {set i 2} {$i<20} {incr i} { + do_execsql_test 9.$tn.$i.1 { DELETE FROM tx WHERE (random()%3)==0 } - do_execsql_test 9.$i.5 { - BEGIN; + do_execsql_test 9.$tn.$i.2 { PRAGMA integrity_check } ok + + do_execsql_test 9.$tn.$i.3 { + WITH x(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM x WHERE i<400 ) + INSERT INTO tx SELECT randomblob(100), randomblob(100) FROM x; + } + + do_execsql_test 9.$tn.$i.4 { PRAGMA integrity_check } ok + + do_execsql_test 9.$tn.$i.5 { + BEGIN; DELETE FROM tx WHERE (random()%3)==0; WITH x(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM x WHERE i<500 ) INSERT INTO tx SELECT randomblob(100), randomblob(100) FROM x; - COMMIT; - } + COMMIT; + } - do_execsql_test 9.$i.6 { PRAGMA integrity_check } ok + do_execsql_test 9.$tn.$i.6 { PRAGMA integrity_check } ok + } } finish_test From 0e55da2ef8999a44fe094b4f385423b1b60b304d Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 11 Apr 2016 19:24:56 +0000 Subject: [PATCH 0282/1484] Fix a typo in temptable2.test. FossilOrigin-Name: 04b1890fbc19eb3fa935083c1664fbbfb67dad93 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/temptable2.test | 3 ++- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 017d301d54..6d6c99e5a2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\stests\sfor\swal\smode\sto\stemptable2.test. -D 2016-04-11T19:23:36.940 +C Fix\sa\stypo\sin\stemptable2.test. +D 2016-04-11T19:24:56.197 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1f123a0757f6f04f0341accb46457e116817159a @@ -1111,7 +1111,7 @@ F test/tclsqlite.test e1306001a0ca92250b691ea6d3cecaca5b6342aa F test/tempdb.test bd92eba8f20e16a9136e434e20b280794de3cdb6 F test/tempfault.test 0c80f23c651cf6452c27cacf09f4c2ee9527a912 F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30 -F test/temptable2.test 79a30edb79c4d5a4916f208f97935a70efd4b3ba +F test/temptable2.test e62783549be26283e1b3725f0de3309411be6c84 F test/temptrigger.test 8ec228b0db5d7ebc4ee9b458fc28cb9e7873f5e1 F test/tester.tcl 7b740ee852c55e1e72b6ebe5044acee7aa4e5553 F test/thread001.test 9f22fd3525a307ff42a326b6bc7b0465be1745a5 @@ -1484,7 +1484,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ffc62af1d503c6e7fc0059d9c2ee57a3bef9dd32 -R b5aaac24011d4d477c13603957856121 +P c6d0d441a1ab4873caedf2f23543444cea5d7f5a +R 24eeba37ecde224a7caa9038421064fb U dan -Z 91cb540a3f9a28d737c21f7feeaff7cc +Z 162e6a9a240e1cae98b0ba71f957c9d5 diff --git a/manifest.uuid b/manifest.uuid index fa8dceac08..3e7e5faf24 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c6d0d441a1ab4873caedf2f23543444cea5d7f5a \ No newline at end of file +04b1890fbc19eb3fa935083c1664fbbfb67dad93 \ No newline at end of file diff --git a/test/temptable2.test b/test/temptable2.test index 44a148ddfb..c5e53de635 100644 --- a/test/temptable2.test +++ b/test/temptable2.test @@ -277,11 +277,12 @@ foreach {tn mode} { 2 wal } { reset_db + sqlite3 db "" do_execsql_test 9.$tn.1.1 { PRAGMA cache_size = 15; PRAGMA auto_vacuum = 1; } - do_execsql_test 9.$tn.1.2 "PRAGMA journal_mode = $mode" $mode + do_execsql_test 9.$tn.1.2 "PRAGMA journal_mode = $mode" delete do_execsql_test 9.$tn.1.3 { CREATE TABLE tx(a, b); From ad2d5baf1fdf5e734c87cc8259e344149a0ff485 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 11 Apr 2016 19:59:52 +0000 Subject: [PATCH 0283/1484] Add the sqlite3_snapshot_cmp() API. FossilOrigin-Name: c698a21af740ca1019c3a771fb83e569cd6bf23e --- manifest | 23 +++++++++++++---------- manifest.uuid | 2 +- src/sqlite.h.in | 21 +++++++++++++++++++++ src/test1.c | 26 ++++++++++++++++++++++++++ src/wal.c | 17 +++++++++++++++++ test/snapshot.test | 34 ++++++++++++++++++++++++++++++++++ 6 files changed, 112 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 855dd8a3ee..70a209bfeb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Performance\soptimization\sto\ssqlite3Dequote()\sand\sits\scallers. -D 2016-04-11T19:01:08.150 +C Add\sthe\ssqlite3_snapshot_cmp()\sAPI. +D 2016-04-11T19:59:52.090 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1f123a0757f6f04f0341accb46457e116817159a @@ -377,7 +377,7 @@ F src/resolve.c b8f7174e5f8c33c44ded3a25a973d0bb89228c20 F src/rowset.c 9fe4b3ad7cc00944386bb600233d8f523de07a6e F src/select.c d9b8628acb98f1a38921888d823a6b70c7a7774b F src/shell.c b7922fa264f8c8d72a5ec6dd0b091e15a93c4de5 -F src/sqlite.h.in c8f41612dc1a9b5212a891e1b65a5f589b8b884a +F src/sqlite.h.in 1ce5ab46279c809302078a10fca0c8107a88504e F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 98f72cbfe00169c39089115427d06ea05fe4b4a2 F src/sqliteInt.h b3744b29555b83054f315f62d61b3a6558fa9e1c @@ -385,7 +385,7 @@ F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 F src/tclsqlite.c 56569acc73d36e836b64aefecbbb709a92ba0077 -F src/test1.c 7187b7e924bfc97780e6fd2a40dad94a32bddca0 +F src/test1.c 457c601302b8a0f5960dffd17b6a2877603841dd F src/test2.c 5586f43fcd9a1be0830793cf9d354082c261b25b F src/test3.c a8887dabbbee3059af338f20d290084a63ed1b0f F src/test4.c d168f83cc78d02e8d35567bb5630e40dcd85ac1e @@ -452,7 +452,7 @@ F src/vdbesort.c 307460bfa4de4d1c3901fcd42089159131e34062 F src/vdbetrace.c f75c5455d8cf389ef86a8bfdfd3177e0e3692484 F src/vtab.c 23b6cdfa996152d43b390504ed4a942c8caf3a00 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 -F src/wal.c 10deb6b43887662691e5f53d10b3c171c401169b +F src/wal.c 4db22ed7e77bcf672b1a685d6ddeffba8d5be302 F src/wal.h 2f7c831cf3b071fa548bf2d5cac640846a7ff19c F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354 F src/where.c 24ab561466d92d313747c04edb1a36a7af8663be @@ -1065,7 +1065,7 @@ F test/skipscan2.test d1d1450952b7275f0b0a3a981f0230532743951a F test/skipscan3.test ec5bab3f81c7038b43450e7b3062e04a198bdbb5 F test/skipscan5.test 67817a4b6857c47e0e33ba3e506da6f23ef68de2 F test/skipscan6.test 5866039d03a56f5bd0b3d172a012074a1d90a15b -F test/snapshot.test 9ed24c792fb05382814258daf68b2256f23de57f +F test/snapshot.test 4488cd49f82095b07a64b63e35ca5f07ae3cf6ff F test/snapshot_fault.test 062ff0438a074978d45e9f9a92e7ad459b74ee73 F test/soak.test 0b5b6375c9f4110c828070b826b3b4b0bb65cd5f F test/softheap1.test 843cd84db9891b2d01b9ab64cef3e9020f98d087 @@ -1482,7 +1482,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 2764aeaa11f38cf2ff4d6191e6d5466ddb203022 -R 77a187fd869dda6e2e45282c54ce5af5 -U drh -Z 40ab6d9a31ee32331ca9ef8f86a7bc32 +P 9efe2265b1e70172778d333c5b9d9a76095427ab +R 90e72a50c886c4c06c826581c1212ad7 +T *branch * snapshot-cmp +T *sym-snapshot-cmp * +T -sym-trunk * +U dan +Z 6bc91ca9d3bb5c1b79f55141c1c596ee diff --git a/manifest.uuid b/manifest.uuid index cd319f925e..d2b5c07f05 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9efe2265b1e70172778d333c5b9d9a76095427ab \ No newline at end of file +c698a21af740ca1019c3a771fb83e569cd6bf23e \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 33b6d1f5ec..f5ccaf40e1 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -8128,6 +8128,27 @@ SQLITE_EXPERIMENTAL int sqlite3_snapshot_open( */ SQLITE_EXPERIMENTAL void sqlite3_snapshot_free(sqlite3_snapshot*); +/* +** CAPI3REF: Compare the ages of two snapshot handles. +** EXPERIMENTAL +** +** The sqlite3_snapshot_cmp(P1, P2) interface is used to compare the ages +** of two valid snapshot handles. +** +** If the two snapshot handles are not associated with the same database +** file, the results are undefined. If either of the snapshot handles +** is no longer valid because the database snapshot they refer to has been +** destroyed by a checkpoint, the results are undefined. +** +** Otherwise, this API returns a negative value if P1 refers to an older +** snapshot than P2, zero if the two handles refer to the same database +** snapshot, and a positive value if P1 is a newer snapshot than P2. +*/ +SQLITE_EXPERIMENTAL int sqlite3_snapshot_cmp( + sqlite3_snapshot *p1, + sqlite3_snapshot *p2 +); + /* ** Undo the hack that converts floating point types to integer for ** builds on processors without floating point support. diff --git a/src/test1.c b/src/test1.c index ead9bd47ba..0c5af822c9 100644 --- a/src/test1.c +++ b/src/test1.c @@ -2359,6 +2359,31 @@ static int test_snapshot_free( } #endif /* SQLITE_ENABLE_SNAPSHOT */ +#ifdef SQLITE_ENABLE_SNAPSHOT +/* +** Usage: sqlite3_snapshot_cmp SNAPSHOT1 SNAPSHOT2 +*/ +static int test_snapshot_cmp( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + int res; + sqlite3_snapshot *p1; + sqlite3_snapshot *p2; + if( objc!=3 ){ + Tcl_WrongNumArgs(interp, 1, objv, "SNAPSHOT1 SNAPSHOT2"); + return TCL_ERROR; + } + p1 = (sqlite3_snapshot*)sqlite3TestTextToPtr(Tcl_GetString(objv[1])); + p2 = (sqlite3_snapshot*)sqlite3TestTextToPtr(Tcl_GetString(objv[2])); + res = sqlite3_snapshot_cmp(p1, p2); + Tcl_SetObjResult(interp, Tcl_NewIntObj(res)); + return TCL_OK; +} +#endif /* SQLITE_ENABLE_SNAPSHOT */ + /* ** Usage: sqlite3_next_stmt DB STMT ** @@ -7249,6 +7274,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){ { "sqlite3_snapshot_get", test_snapshot_get, 0 }, { "sqlite3_snapshot_open", test_snapshot_open, 0 }, { "sqlite3_snapshot_free", test_snapshot_free, 0 }, + { "sqlite3_snapshot_cmp", test_snapshot_cmp, 0 }, #endif }; static int bitmask_size = sizeof(Bitmask)*8; diff --git a/src/wal.c b/src/wal.c index bbac1bd6d0..98b46be801 100644 --- a/src/wal.c +++ b/src/wal.c @@ -3399,6 +3399,23 @@ int sqlite3WalSnapshotGet(Wal *pWal, sqlite3_snapshot **ppSnapshot){ void sqlite3WalSnapshotOpen(Wal *pWal, sqlite3_snapshot *pSnapshot){ pWal->pSnapshot = (WalIndexHdr*)pSnapshot; } + +/* +** Return a +ve value if snapshot p1 is newer than p2. A -ve value if +** p1 is older than p2 and zero if p1 and p2 are the same snapshot. +*/ +int sqlite3_snapshot_cmp(sqlite3_snapshot *p1, sqlite3_snapshot *p2){ + WalIndexHdr *pHdr1 = (WalIndexHdr*)p1; + WalIndexHdr *pHdr2 = (WalIndexHdr*)p2; + + /* aSalt[0] is a copy of the value stored in the wal file header. It + ** is incremented each time the wal file is restarted. */ + if( pHdr1->aSalt[0]aSalt[0] ) return -1; + if( pHdr1->aSalt[0]>pHdr2->aSalt[0] ) return +1; + if( pHdr1->mxFramemxFrame ) return -1; + if( pHdr1->mxFrame>pHdr2->mxFrame ) return +1; + return 0; +} #endif /* SQLITE_ENABLE_SNAPSHOT */ #ifdef SQLITE_ENABLE_ZIPVFS diff --git a/test/snapshot.test b/test/snapshot.test index c6710e3691..5f6c4e1e4f 100644 --- a/test/snapshot.test +++ b/test/snapshot.test @@ -365,4 +365,38 @@ do_test 6.5 { sqlite3_snapshot_free $snapshot +#------------------------------------------------------------------------- +# The following tests investigate the sqlite3_snapshot_cmp() API. +# +catch { db2 close } +reset_db +do_execsql_test 7.1 { + PRAGMA journal_mode = wal; + CREATE TABLE t1(x); +} wal + +do_test 7.1.2 { + execsql { BEGIN ; PRAGMA application_id } + set p1 [sqlite3_snapshot_get db main] + execsql { + INSERT INTO t1 VALUES(10); + COMMIT; + } + execsql { BEGIN ; PRAGMA application_id } + set p2 [sqlite3_snapshot_get db main] + execsql COMMIT + + sqlite3_snapshot_cmp $p1 $p2 +} {-1} + +do_test 7.1.3 { + sqlite3_snapshot_cmp $p2 $p1 +} {1} + +do_test 7.1.4 { + list [sqlite3_snapshot_cmp $p1 $p1] [sqlite3_snapshot_cmp $p2 $p2] +} {0 0} +sqlite3_snapshot_free $p1 +sqlite3_snapshot_free $p2 + finish_test From 0e188e1d1eb0e8eb51ad0a5526af963284f47886 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Mon, 11 Apr 2016 22:10:26 +0000 Subject: [PATCH 0284/1484] Fix some compilation issues. FossilOrigin-Name: 016481b39f8b23b4f0f851053068d8eaee6122e1 --- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- src/os_win.c | 20 +++++++++++++------- src/sqliteInt.h | 10 ---------- 4 files changed, 24 insertions(+), 28 deletions(-) diff --git a/manifest b/manifest index 2ba8a3c8f7..c7a5b46f3b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\supdates\sfrom\strunk. -D 2016-04-05T17:59:56.435 +C Fix\ssome\scompilation\sissues. +D 2016-04-11T22:10:26.085 F Makefile.in e812bb732d7af01baa09f1278bd4f4a2e3a09449 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc fe57d7e3e74fa383fd01ced796c0ffd966fc094a @@ -13,7 +13,7 @@ F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am 42f7eb1fb2b06ddd6c6adab3e4388cc0a237ba40 F autoconf/Makefile.msc dc0d0500e4a827cb3891d08d846dd6dd40241b51 F autoconf/README.first 6c4f34fe115ff55d4e8dbfa3cecf04a0188292f7 -F autoconf/README.txt 4f04b0819303aabaa35fff5f7b257fb0c1ef95f1 w autoconf/README +F autoconf/README.txt 4f04b0819303aabaa35fff5f7b257fb0c1ef95f1 F autoconf/configure.ac d807b567f73a2b0986ccdd206b782cecb4d08fff F autoconf/tea/Makefile.in b438a7020446c8a8156e8d97c8914a04833da6fd F autoconf/tea/README 3e9a3c060f29a44344ab50aec506f4db903fb873 @@ -360,7 +360,7 @@ F src/os.h 91ff889115ecd01f436d3611f7f5ea4dc12d92f1 F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85 F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa F src/os_unix.c b1ccb273771f41dbdbe0ba7c1ad63c38ad5972ec -F src/os_win.c be21cb97d7c679a27851d85c26ddc3a80ffb2ec5 +F src/os_win.c 1245c1c1b03f269f8beca1464df2f9a174236dab F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c 38718a019ca762ba4f6795425d5a54db70d1790d F src/pager.h e1d38a2f14849e219df0f91f8323504d134c8a56 @@ -380,7 +380,7 @@ F src/shell.c b7922fa264f8c8d72a5ec6dd0b091e15a93c4de5 F src/sqlite.h.in 7f437b068314f053e6417d452c59f08d05092591 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 98f72cbfe00169c39089115427d06ea05fe4b4a2 -F src/sqliteInt.h 8da202a3a7874497db07fae72c1f94ca6522a6c3 +F src/sqliteInt.h 594bf31a7a0cc788688ca947e562576e23bd7904 F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 @@ -1012,7 +1012,7 @@ F test/savepoint4.test c8f8159ade6d2acd9128be61e1230f1c1edc6cc0 F test/savepoint5.test 0735db177e0ebbaedc39812c8d065075d563c4fd F test/savepoint6.test f41279c5e137139fa5c21485773332c7adb98cd7 F test/savepoint7.test db3db281486c925095f305aad09fe806e5188ff3 -F test/savepointfault.test f044eac64b59f09746c7020ee261734de82bf9b2 w test/savepoint3.test +F test/savepointfault.test f044eac64b59f09746c7020ee261734de82bf9b2 F test/scanstatus.test 5253c219e331318a437f436268e0e82345700285 F test/schema.test 8f7999be894260f151adf15c2c7540f1c6d6a481 F test/schema2.test 906408621ea881fdb496d878b1822572a34e32c5 @@ -1378,7 +1378,7 @@ F test/whereH.test e4b07f7a3c2f5d31195cd33710054c78667573b2 F test/whereI.test eab5b226bbc344ac70d7dc09b963a064860ae6d7 F test/whereJ.test 55a3221706a7ab706293f17cc8f96da563bf0767 F test/whereK.test f8e3cf26a8513ecc7f514f54df9f0572c046c42b -F test/wherefault.test 1374c3aa198388925246475f84ad4cd5f9528864 w test/where8m.test +F test/wherefault.test 1374c3aa198388925246475f84ad4cd5f9528864 F test/wherelimit.test 5e9fd41e79bb2b2d588ed999d641d9c965619b31 F test/wild001.test bca33f499866f04c24510d74baf1e578d4e44b1c F test/win32heap.test ea19770974795cff26e11575e12d422dbd16893c @@ -1482,7 +1482,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 39759a553208d8ef72964bdd539a0883e1d99cf6 cf569f9f2fab1828e4bfced111fd9a6ee23ea8c0 -R d0ec40008a4450baf3f01589e83f54d1 +P 00990020d07d7c87b922cdbfa5373298a86bb4b3 +R b5c956e1077b7c3e444e8f4ed923bce8 U mistachkin -Z eaa4bb84d513df9cfd663fcd7451f96e +Z 76d8e561edd13c0c75a00b4aec6f1897 diff --git a/manifest.uuid b/manifest.uuid index 7454ecb7b8..1b33607050 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -00990020d07d7c87b922cdbfa5373298a86bb4b3 \ No newline at end of file +016481b39f8b23b4f0f851053068d8eaee6122e1 \ No newline at end of file diff --git a/src/os_win.c b/src/os_win.c index 518155d037..698c5af861 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -25,6 +25,16 @@ */ #include "os_win.h" +/* +** The MSVC CRT on Windows CE may not have a localtime() function. So +** declare a substitute. +*/ +#if SQLITE_OS_WINCE && \ + (!defined(SQLITE_MSVC_LOCALTIME_API) || !SQLITE_MSVC_LOCALTIME_API) +# include +struct tm *__cdecl localtime(const time_t *); +#endif + /* ** Compiling and using WAL mode requires several APIs that are only ** available in Windows platforms based on the NT kernel. @@ -2118,16 +2128,12 @@ static void winLogIoerr(int nRetry, int lineno){ } } -/* -** This #if cannot use SQLITE_OS_WINCE because the corresponding section -** in "sqliteInt.h" does not use it. -*/ -#if defined(_WIN32_WCE) && \ - (!defined(SQLITE_MSVC_LOCALTIME_API) || !SQLITE_MSVC_LOCALTIME_API) /* ** The MSVC CRT on Windows CE may not have a localtime() function. So -** create a substitute. +** define a substitute. */ +#if SQLITE_OS_WINCE && \ + (!defined(SQLITE_MSVC_LOCALTIME_API) || !SQLITE_MSVC_LOCALTIME_API) struct tm *__cdecl localtime(const time_t *t) { static struct tm y; diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 8a4aa378fa..d789cc00e4 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -211,16 +211,6 @@ # endif #endif -/* -** The MSVC CRT on Windows CE may not have a localtime() function. So -** declare a substitute. The function itself is defined in "os_win.c". -*/ -#if defined(_WIN32_WCE) && \ - (!defined(SQLITE_MSVC_LOCALTIME_API) || !SQLITE_MSVC_LOCALTIME_API) -# include -struct tm *__cdecl localtime(const time_t *); -#endif - /* ** The SQLITE_THREADSAFE macro must be defined as 0, 1, or 2. ** 0 means mutexes are permanently disable and the library is never From 4f2c822cc508da40cbbc83c67a36cd60268410c5 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Mon, 11 Apr 2016 22:23:04 +0000 Subject: [PATCH 0285/1484] Fix typo in the MSVC makefile. FossilOrigin-Name: 3189a7f1851f823218d85a2455bf218d00d81543 --- Makefile.msc | 2 +- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Makefile.msc b/Makefile.msc index 84aa118258..e65f99d758 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -1882,7 +1882,7 @@ fts3_write.lo: $(TOP)\ext\fts3\fts3_write.c $(HDR) $(EXTHDR) rtree.lo: $(TOP)\ext\rtree\rtree.c $(HDR) $(EXTHDR) $(LTCOMPILE) $(CORE_COMPILE_OPTS) $(NO_WARN) -DSQLITE_CORE -c $(TOP)\ext\rtree\rtree.c -sqlite3session.lo: $(TOP)\ext\session\sqlite3sesion.c $(HDR) $(EXTHDR) +sqlite3session.lo: $(TOP)\ext\session\sqlite3session.c $(HDR) $(EXTHDR) $(LTCOMPILE) $(CORE_COMPILE_OPTS) $(NO_WARN) -DSQLITE_CORE -c $(TOP)\ext\session\sqlite3session.c # FTS5 things diff --git a/manifest b/manifest index 855dd8a3ee..8e49256d28 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -C Performance\soptimization\sto\ssqlite3Dequote()\sand\sits\scallers. -D 2016-04-11T19:01:08.150 +C Fix\stypo\sin\sthe\sMSVC\smakefile. +D 2016-04-11T22:23:04.713 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 -F Makefile.msc 1f123a0757f6f04f0341accb46457e116817159a +F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7 F VERSION 5d234da9b5dae329fab75ff75884cfe0a9cb3fda F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 @@ -1482,7 +1482,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 2764aeaa11f38cf2ff4d6191e6d5466ddb203022 -R 77a187fd869dda6e2e45282c54ce5af5 -U drh -Z 40ab6d9a31ee32331ca9ef8f86a7bc32 +P 9efe2265b1e70172778d333c5b9d9a76095427ab +R 9dfabe8574d101ebf28b9a702be1975f +U mistachkin +Z 91af9eba4ad1e404eee70525acb4f1e0 diff --git a/manifest.uuid b/manifest.uuid index cd319f925e..042db0d78f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9efe2265b1e70172778d333c5b9d9a76095427ab \ No newline at end of file +3189a7f1851f823218d85a2455bf218d00d81543 \ No newline at end of file From 0cedb963a3c0af74b77ede4a333ead2bc221eced Mon Sep 17 00:00:00 2001 From: mistachkin Date: Mon, 11 Apr 2016 22:45:45 +0000 Subject: [PATCH 0286/1484] Further refinements. FossilOrigin-Name: b35bb928b25492f6dd71ccf9c250cb9f0cce09ff --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/date.c | 8 ++++++++ src/os_win.c | 13 ++----------- 4 files changed, 18 insertions(+), 19 deletions(-) diff --git a/manifest b/manifest index 4bfcc161a3..9eda7911ed 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\supdates\sfrom\strunk. -D 2016-04-11T22:24:03.058 +C Further\srefinements. +D 2016-04-11T22:45:45.699 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -326,7 +326,7 @@ F src/build.c 1944d95f0250ec72dab939f8319a12e237aaad61 F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 60e135af364d777a9ab41c97e5e89cd224da6198 -F src/date.c cd412cb2adb0c3a60e085107864931e508f45ad8 +F src/date.c b25819151358a5598a1beaf0da370692ce4a70d1 F src/dbstat.c c845548d4346e606e2f2b7d2e714ace2b8a7dd1b F src/delete.c 78eb999114ec04fcf1b7d123ccedb4b5b734930e F src/expr.c 17d4e745ef6a3fd2e4ef863f5f9a4912f1ba1198 @@ -360,7 +360,7 @@ F src/os.h 91ff889115ecd01f436d3611f7f5ea4dc12d92f1 F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85 F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa F src/os_unix.c bde4844f0849cab5924c6a81178f8500774ce76b -F src/os_win.c 1245c1c1b03f269f8beca1464df2f9a174236dab +F src/os_win.c 9c84a48d56074d36866775a76089da69acb21594 F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c 38718a019ca762ba4f6795425d5a54db70d1790d F src/pager.h e1d38a2f14849e219df0f91f8323504d134c8a56 @@ -1482,7 +1482,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 016481b39f8b23b4f0f851053068d8eaee6122e1 3189a7f1851f823218d85a2455bf218d00d81543 -R 7558a8a571dae2778f18625aa658ad38 +P b8094166b3c6a8ec7913b403e08b5e6790fb03c1 +R 10b47efb260a3b41bbe92a309e042fe1 U mistachkin -Z b10810d48122d46da89a3713378b4792 +Z 8cdaf1bfaef399409db07428454eae07 diff --git a/manifest.uuid b/manifest.uuid index e418fefec5..3add6fef53 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b8094166b3c6a8ec7913b403e08b5e6790fb03c1 \ No newline at end of file +b35bb928b25492f6dd71ccf9c250cb9f0cce09ff \ No newline at end of file diff --git a/src/date.c b/src/date.c index 02f7d4f01f..182b7d594d 100644 --- a/src/date.c +++ b/src/date.c @@ -50,6 +50,14 @@ #ifndef SQLITE_OMIT_DATETIME_FUNCS +/* +** The MSVC CRT on Windows CE may not have a localtime() function. So +** declare a substitute. +*/ +#if !defined(SQLITE_OMIT_LOCALTIME) && defined(_WIN32_WCE) && \ + (!defined(SQLITE_MSVC_LOCALTIME_API) || !SQLITE_MSVC_LOCALTIME_API) +struct tm *__cdecl localtime(const time_t *); +#endif /* ** A structure for holding a single date and time. diff --git a/src/os_win.c b/src/os_win.c index 698c5af861..d6156d7bbf 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -25,16 +25,6 @@ */ #include "os_win.h" -/* -** The MSVC CRT on Windows CE may not have a localtime() function. So -** declare a substitute. -*/ -#if SQLITE_OS_WINCE && \ - (!defined(SQLITE_MSVC_LOCALTIME_API) || !SQLITE_MSVC_LOCALTIME_API) -# include -struct tm *__cdecl localtime(const time_t *); -#endif - /* ** Compiling and using WAL mode requires several APIs that are only ** available in Windows platforms based on the NT kernel. @@ -2132,8 +2122,9 @@ static void winLogIoerr(int nRetry, int lineno){ ** The MSVC CRT on Windows CE may not have a localtime() function. So ** define a substitute. */ -#if SQLITE_OS_WINCE && \ +#if !defined(SQLITE_OMIT_LOCALTIME) && defined(_WIN32_WCE) && \ (!defined(SQLITE_MSVC_LOCALTIME_API) || !SQLITE_MSVC_LOCALTIME_API) +# include struct tm *__cdecl localtime(const time_t *t) { static struct tm y; From 926957f0a6aa4f5a320bf07390683d7d4065ae20 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 12 Apr 2016 00:00:33 +0000 Subject: [PATCH 0287/1484] Performance improvements in sqlite3WhereExprUsage(). FossilOrigin-Name: fdf752394b48fb7b9afe7b8a7d83f859985cc2d2 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/whereexpr.c | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 8e49256d28..68421cb1a0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\stypo\sin\sthe\sMSVC\smakefile. -D 2016-04-11T22:23:04.713 +C Performance\simprovements\sin\ssqlite3WhereExprUsage(). +D 2016-04-12T00:00:33.150 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -458,7 +458,7 @@ F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354 F src/where.c 24ab561466d92d313747c04edb1a36a7af8663be F src/whereInt.h 93297d56edd137b7ea004490690fb6e2ce028a34 F src/wherecode.c 8fdad9fbba723df1c1e8d07e7ea8507572040340 -F src/whereexpr.c fb87944b1254234e5bba671aaf6dee476241506a +F src/whereexpr.c eacc0e60d029a082b4fc0cc42ea98544add1319e F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1482,7 +1482,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 9efe2265b1e70172778d333c5b9d9a76095427ab -R 9dfabe8574d101ebf28b9a702be1975f -U mistachkin -Z 91af9eba4ad1e404eee70525acb4f1e0 +P 3189a7f1851f823218d85a2455bf218d00d81543 +R a88db109e8e64abc37a80f82dbafc726 +U drh +Z 61fba36ce9cee6b2faa0d1bd0f21f7e0 diff --git a/manifest.uuid b/manifest.uuid index 042db0d78f..9d56144ad3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3189a7f1851f823218d85a2455bf218d00d81543 \ No newline at end of file +fdf752394b48fb7b9afe7b8a7d83f859985cc2d2 \ No newline at end of file diff --git a/src/whereexpr.c b/src/whereexpr.c index 0ad1f6a0dc..ff012281b1 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -1282,10 +1282,10 @@ Bitmask sqlite3WhereExprUsage(WhereMaskSet *pMaskSet, Expr *p){ return mask; } mask = sqlite3WhereExprUsage(pMaskSet, p->pRight); - mask |= sqlite3WhereExprUsage(pMaskSet, p->pLeft); + if( p->pLeft ) mask |= sqlite3WhereExprUsage(pMaskSet, p->pLeft); if( ExprHasProperty(p, EP_xIsSelect) ){ mask |= exprSelectUsage(pMaskSet, p->x.pSelect); - }else{ + }else if( p->x.pList ){ mask |= sqlite3WhereExprListUsage(pMaskSet, p->x.pList); } return mask; From f3c57ff54c7fd0a83358db12973a8a1a77bb1122 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 12 Apr 2016 00:16:54 +0000 Subject: [PATCH 0288/1484] Avoid unnecessary calls to object destructors for a small performance gain. FossilOrigin-Name: aec94b6ee68fe50e2cc14388281e2ef531e21d68 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/select.c | 4 ++-- src/tokenize.c | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 68421cb1a0..1df6af9754 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Performance\simprovements\sin\ssqlite3WhereExprUsage(). -D 2016-04-12T00:00:33.150 +C Avoid\sunnecessary\scalls\sto\sobject\sdestructors\sfor\sa\ssmall\sperformance\sgain. +D 2016-04-12T00:16:54.551 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -375,7 +375,7 @@ F src/printf.c 63e6fb12bbe702dd664dc3703776c090383a5a26 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c b8f7174e5f8c33c44ded3a25a973d0bb89228c20 F src/rowset.c 9fe4b3ad7cc00944386bb600233d8f523de07a6e -F src/select.c d9b8628acb98f1a38921888d823a6b70c7a7774b +F src/select.c ac6d3e0cb7bd40863d228097dd8f08376d413877 F src/shell.c b7922fa264f8c8d72a5ec6dd0b091e15a93c4de5 F src/sqlite.h.in c8f41612dc1a9b5212a891e1b65a5f589b8b884a F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -434,7 +434,7 @@ F src/test_windirent.c 8f5fada630348558d5745b334702f301da1ffc61 F src/test_windirent.h b12055cab6227f7be10f5c19296f67c60cc5e2a5 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c -F src/tokenize.c 3d338cdd00d916ce8a05c397001d64ed58e6fe1c +F src/tokenize.c 3b29883b0ce4a6c6f643965b66b5ca6613178e59 F src/treeview.c e4b41a37530a191579d3c53142cc44ee2eb99373 F src/trigger.c e14840ee0c3e549e758ec9bf3e4146e166002280 F src/update.c 3e67ab3c0814635f355fb1f8ab010a2b9e016e7d @@ -1482,7 +1482,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 3189a7f1851f823218d85a2455bf218d00d81543 -R a88db109e8e64abc37a80f82dbafc726 +P fdf752394b48fb7b9afe7b8a7d83f859985cc2d2 +R a8b7046af026a40f393575d3c7a134ae U drh -Z 61fba36ce9cee6b2faa0d1bd0f21f7e0 +Z 78d3bdd6a4f18eec259d071eee201b93 diff --git a/manifest.uuid b/manifest.uuid index 9d56144ad3..bcfa76f96b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fdf752394b48fb7b9afe7b8a7d83f859985cc2d2 \ No newline at end of file +aec94b6ee68fe50e2cc14388281e2ef531e21d68 \ No newline at end of file diff --git a/src/select.c b/src/select.c index 9a2d4d22cd..2be62ed42c 100644 --- a/src/select.c +++ b/src/select.c @@ -74,7 +74,7 @@ static void clearSelect(sqlite3 *db, Select *p, int bFree){ sqlite3ExprListDelete(db, p->pOrderBy); sqlite3ExprDelete(db, p->pLimit); sqlite3ExprDelete(db, p->pOffset); - sqlite3WithDelete(db, p->pWith); + if( p->pWith ) sqlite3WithDelete(db, p->pWith); if( bFree ) sqlite3DbFree(db, p); p = pPrior; bFree = 1; @@ -169,7 +169,7 @@ void sqlite3SelectSetName(Select *p, const char *zName){ ** Delete the given Select structure and all of its substructures. */ void sqlite3SelectDelete(sqlite3 *db, Select *p){ - clearSelect(db, p, 1); + if( p ) clearSelect(db, p, 1); } /* diff --git a/src/tokenize.c b/src/tokenize.c index 19a5ddf04d..62e770b79c 100644 --- a/src/tokenize.c +++ b/src/tokenize.c @@ -583,7 +583,7 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){ sqlite3DeleteTable(db, pParse->pNewTable); } - sqlite3WithDelete(db, pParse->pWithToFree); + if( pParse->pWithToFree ) sqlite3WithDelete(db, pParse->pWithToFree); sqlite3DeleteTrigger(db, pParse->pNewTrigger); for(i=pParse->nzVar-1; i>=0; i--) sqlite3DbFree(db, pParse->azVar[i]); sqlite3DbFree(db, pParse->azVar); From 6f077343499e27a354dc924afe601f3a8ef947c9 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 12 Apr 2016 00:26:59 +0000 Subject: [PATCH 0289/1484] Performance optimization the Vdbe allocator. FossilOrigin-Name: e2c4995bf1099cc02bcb1dc4a4631f06a870d171 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/select.c | 22 +++++++++++----------- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/manifest b/manifest index 1df6af9754..1b9939804f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sunnecessary\scalls\sto\sobject\sdestructors\sfor\sa\ssmall\sperformance\sgain. -D 2016-04-12T00:16:54.551 +C Performance\soptimization\sthe\sVdbe\sallocator. +D 2016-04-12T00:26:59.031 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -375,7 +375,7 @@ F src/printf.c 63e6fb12bbe702dd664dc3703776c090383a5a26 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c b8f7174e5f8c33c44ded3a25a973d0bb89228c20 F src/rowset.c 9fe4b3ad7cc00944386bb600233d8f523de07a6e -F src/select.c ac6d3e0cb7bd40863d228097dd8f08376d413877 +F src/select.c a07e6022e2b559f3c2ec80442472c5965fa7a3fc F src/shell.c b7922fa264f8c8d72a5ec6dd0b091e15a93c4de5 F src/sqlite.h.in c8f41612dc1a9b5212a891e1b65a5f589b8b884a F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1482,7 +1482,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P fdf752394b48fb7b9afe7b8a7d83f859985cc2d2 -R a8b7046af026a40f393575d3c7a134ae +P aec94b6ee68fe50e2cc14388281e2ef531e21d68 +R 253cd694af93304b2692f192acabe757 U drh -Z 78d3bdd6a4f18eec259d071eee201b93 +Z 22234bdd82888c7db3f11967733fa3c5 diff --git a/manifest.uuid b/manifest.uuid index bcfa76f96b..eaf9d622d5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -aec94b6ee68fe50e2cc14388281e2ef531e21d68 \ No newline at end of file +e2c4995bf1099cc02bcb1dc4a4631f06a870d171 \ No newline at end of file diff --git a/src/select.c b/src/select.c index 2be62ed42c..fc37db5747 100644 --- a/src/select.c +++ b/src/select.c @@ -1789,20 +1789,20 @@ Table *sqlite3ResultSetOfSelect(Parse *pParse, Select *pSelect){ ** Get a VDBE for the given parser context. Create a new one if necessary. ** If an error occurs, return NULL and leave a message in pParse. */ -Vdbe *sqlite3GetVdbe(Parse *pParse){ - Vdbe *v = pParse->pVdbe; - if( v==0 ){ - v = pParse->pVdbe = sqlite3VdbeCreate(pParse); - if( v ) sqlite3VdbeAddOp0(v, OP_Init); - if( pParse->pToplevel==0 - && OptimizationEnabled(pParse->db,SQLITE_FactorOutConst) - ){ - pParse->okConstFactor = 1; - } - +static SQLITE_NOINLINE Vdbe *allocVdbe(Parse *pParse){ + Vdbe *v = pParse->pVdbe = sqlite3VdbeCreate(pParse); + if( v ) sqlite3VdbeAddOp0(v, OP_Init); + if( pParse->pToplevel==0 + && OptimizationEnabled(pParse->db,SQLITE_FactorOutConst) + ){ + pParse->okConstFactor = 1; } return v; } +Vdbe *sqlite3GetVdbe(Parse *pParse){ + Vdbe *v = pParse->pVdbe; + return v ? v : allocVdbe(pParse); +} /* From 70b8d6bbccc029d8c9a3ee9289b04f597acfd876 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 12 Apr 2016 11:58:18 +0000 Subject: [PATCH 0290/1484] Update the header comment on the memjournal.c file. No code changes. FossilOrigin-Name: 07f10deabb0f4207408142541e3913d638dfcdeb --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/memjournal.c | 9 +++++++++ 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 1b9939804f..e35b915d18 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Performance\soptimization\sthe\sVdbe\sallocator. -D 2016-04-12T00:26:59.031 +C Update\sthe\sheader\scomment\son\sthe\smemjournal.c\sfile.\s\sNo\scode\schanges. +D 2016-04-12T11:58:18.868 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -347,7 +347,7 @@ F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3 F src/mem3.c 8768ac94694f31ffaf8b4d0ea5dc08af7010a35a F src/mem5.c 9bf955937b07f8c32541c8a9991f33ce3173d944 -F src/memjournal.c 2815ef7684671d93a1ec6a31e1e63c45de4b4d31 +F src/memjournal.c 95752936c11dc6995672d1dd783cd633eea0cc95 F src/msvc.h d9ba56c6851227ab44b3f228a35f3f5772296495 F src/mutex.c 8e45800ee78e0cd1f1f3fe8e398853307f4a085c F src/mutex.h 779d588e3b7756ec3ecf7d78cde1d84aba414f85 @@ -1482,7 +1482,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P aec94b6ee68fe50e2cc14388281e2ef531e21d68 -R 253cd694af93304b2692f192acabe757 +P e2c4995bf1099cc02bcb1dc4a4631f06a870d171 +R 2e4cf3acc4cd7fa1ae0c658360dca721 U drh -Z 22234bdd82888c7db3f11967733fa3c5 +Z ca7267cbdba15c8e817fe9239b1f31a1 diff --git a/manifest.uuid b/manifest.uuid index eaf9d622d5..460eaacc67 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e2c4995bf1099cc02bcb1dc4a4631f06a870d171 \ No newline at end of file +07f10deabb0f4207408142541e3913d638dfcdeb \ No newline at end of file diff --git a/src/memjournal.c b/src/memjournal.c index fbfa7cb802..cd8b87d8aa 100644 --- a/src/memjournal.c +++ b/src/memjournal.c @@ -13,6 +13,15 @@ ** This file contains code use to implement an in-memory rollback journal. ** The in-memory rollback journal is used to journal transactions for ** ":memory:" databases and when the journal_mode=MEMORY pragma is used. +** +** Update: The in-memory journal is also used to temporarily cache +** smaller journals that are not critical for power-loss recovery. +** For example, statement journals that are not too big will be held +** entirely in memory, thus reducing the number of file I/O calls, and +** more importantly, reducing temporary file creation events. If these +** journals become too large for memory, they are spilled to disk. But +** in the common case, they are usually small and no file I/O needs to +** occur. */ #include "sqliteInt.h" From 745be369c799ab98c8c6798d92ec4f295bd54de9 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 12 Apr 2016 15:14:25 +0000 Subject: [PATCH 0291/1484] Update the documentation for sqlite3_snapshot_cmp() to make the circumstances under which the comparison is valid clearer. Add tests for the same. FossilOrigin-Name: 8fc834741bf6c8a832a180795c3d6f5c3dcfcd62 --- manifest | 17 ++++++-------- manifest.uuid | 2 +- src/sqlite.h.in | 12 +++++++--- test/snapshot.test | 56 +++++++++++++++++++++++++++++++++++++++------- 4 files changed, 65 insertions(+), 22 deletions(-) diff --git a/manifest b/manifest index 70a209bfeb..b6732de4b4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\ssqlite3_snapshot_cmp()\sAPI. -D 2016-04-11T19:59:52.090 +C Update\sthe\sdocumentation\sfor\ssqlite3_snapshot_cmp()\sto\smake\sthe\scircumstances\sunder\swhich\sthe\scomparison\sis\svalid\sclearer.\sAdd\stests\sfor\sthe\ssame. +D 2016-04-12T15:14:25.762 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1f123a0757f6f04f0341accb46457e116817159a @@ -377,7 +377,7 @@ F src/resolve.c b8f7174e5f8c33c44ded3a25a973d0bb89228c20 F src/rowset.c 9fe4b3ad7cc00944386bb600233d8f523de07a6e F src/select.c d9b8628acb98f1a38921888d823a6b70c7a7774b F src/shell.c b7922fa264f8c8d72a5ec6dd0b091e15a93c4de5 -F src/sqlite.h.in 1ce5ab46279c809302078a10fca0c8107a88504e +F src/sqlite.h.in 64eb70a3b309751bebf73a5552a51244f68f0ea5 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 98f72cbfe00169c39089115427d06ea05fe4b4a2 F src/sqliteInt.h b3744b29555b83054f315f62d61b3a6558fa9e1c @@ -1065,7 +1065,7 @@ F test/skipscan2.test d1d1450952b7275f0b0a3a981f0230532743951a F test/skipscan3.test ec5bab3f81c7038b43450e7b3062e04a198bdbb5 F test/skipscan5.test 67817a4b6857c47e0e33ba3e506da6f23ef68de2 F test/skipscan6.test 5866039d03a56f5bd0b3d172a012074a1d90a15b -F test/snapshot.test 4488cd49f82095b07a64b63e35ca5f07ae3cf6ff +F test/snapshot.test 3adc4ef09d407b501f899a6c329bdf45dc725c1b F test/snapshot_fault.test 062ff0438a074978d45e9f9a92e7ad459b74ee73 F test/soak.test 0b5b6375c9f4110c828070b826b3b4b0bb65cd5f F test/softheap1.test 843cd84db9891b2d01b9ab64cef3e9020f98d087 @@ -1482,10 +1482,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 9efe2265b1e70172778d333c5b9d9a76095427ab -R 90e72a50c886c4c06c826581c1212ad7 -T *branch * snapshot-cmp -T *sym-snapshot-cmp * -T -sym-trunk * +P c698a21af740ca1019c3a771fb83e569cd6bf23e +R 1df0b51d3ec92c57900ed6ffc629e927 U dan -Z 6bc91ca9d3bb5c1b79f55141c1c596ee +Z 0bd02cd207722d1ba1dc6f0818f7fd4a diff --git a/manifest.uuid b/manifest.uuid index d2b5c07f05..d0089f5647 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c698a21af740ca1019c3a771fb83e569cd6bf23e \ No newline at end of file +8fc834741bf6c8a832a180795c3d6f5c3dcfcd62 \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index f5ccaf40e1..d50d826b41 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -8136,9 +8136,15 @@ SQLITE_EXPERIMENTAL void sqlite3_snapshot_free(sqlite3_snapshot*); ** of two valid snapshot handles. ** ** If the two snapshot handles are not associated with the same database -** file, the results are undefined. If either of the snapshot handles -** is no longer valid because the database snapshot they refer to has been -** destroyed by a checkpoint, the results are undefined. +** file, the result of the comparison is undefined. +** +** Additionally, the result of the comparison is only valid if both of the +** snapshot handles were obtained by calling sqlite3_snapshot_get() since the +** last time the wal file was deleted. The wal file is deleted when the +** database is changed back to rollback mode or when the number of database +** clients drops to zero. If either snapshot handle was obtained before the +** wal file was last deleted, the value returned by this function +** is undefined. ** ** Otherwise, this API returns a negative value if P1 refers to an older ** snapshot than P2, zero if the two handles refer to the same database diff --git a/test/snapshot.test b/test/snapshot.test index 5f6c4e1e4f..6dff11bbb9 100644 --- a/test/snapshot.test +++ b/test/snapshot.test @@ -368,8 +368,19 @@ sqlite3_snapshot_free $snapshot #------------------------------------------------------------------------- # The following tests investigate the sqlite3_snapshot_cmp() API. # + +# Compare snapshots $p1 and $p2, checking that the result is $r. +# +proc do_snapshot_cmp_test {tn p1 p2 r} { + uplevel [list do_test $tn.1 [list sqlite3_snapshot_cmp $p1 $p2] $r] + uplevel [list do_test $tn.2 [list sqlite3_snapshot_cmp $p2 $p1] [expr $r*-1]] + uplevel [list do_test $tn.3 [list sqlite3_snapshot_cmp $p1 $p1] 0] + uplevel [list do_test $tn.4 [list sqlite3_snapshot_cmp $p2 $p2] 0] +} + catch { db2 close } reset_db + do_execsql_test 7.1 { PRAGMA journal_mode = wal; CREATE TABLE t1(x); @@ -385,17 +396,46 @@ do_test 7.1.2 { execsql { BEGIN ; PRAGMA application_id } set p2 [sqlite3_snapshot_get db main] execsql COMMIT +} {} - sqlite3_snapshot_cmp $p1 $p2 -} {-1} +do_snapshot_cmp_test 7.1.3 $p1 $p2 -1 +sqlite3_snapshot_free $p1 +sqlite3_snapshot_free $p2 -do_test 7.1.3 { - sqlite3_snapshot_cmp $p2 $p1 -} {1} +do_execsql_test 7.2.1 { + INSERT INTO t1 VALUES(11); + INSERT INTO t1 VALUES(12); + INSERT INTO t1 VALUES(13); + BEGIN; + PRAGMA application_id; +} {0} +do_test 7.2.2 { + set p1 [sqlite3_snapshot_get db main] + execsql { + COMMIT; + INSERT INTO t1 VALUES(14); + PRAGMA wal_checkpoint; + BEGIN; + PRAGMA application_id; + } + set p2 [sqlite3_snapshot_get db main] + execsql COMMIT +} {} -do_test 7.1.4 { - list [sqlite3_snapshot_cmp $p1 $p1] [sqlite3_snapshot_cmp $p2 $p2] -} {0 0} +do_snapshot_cmp_test 7.2.3 $p1 $p2 -1 +sqlite3_snapshot_free $p2 + +do_test 7.3.1 { + execsql { + INSERT INTO t1 VALUES(14); + BEGIN; + PRAGMA application_id; + } + set p2 [sqlite3_snapshot_get db main] + execsql COMMIT +} {} + +do_snapshot_cmp_test 7.3.2 $p1 $p2 -1 sqlite3_snapshot_free $p1 sqlite3_snapshot_free $p2 From 8366ddf24267097686f8418d4d5afbc027dac8c7 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Tue, 12 Apr 2016 16:11:52 +0000 Subject: [PATCH 0292/1484] Add and adjust comments. FossilOrigin-Name: 541c6da23850673f5d2a2e31c3967b796ee2effc --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/date.c | 5 +++-- src/os_win.c | 8 ++++++-- 4 files changed, 17 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 9eda7911ed..5d71ad29a9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Further\srefinements. -D 2016-04-11T22:45:45.699 +C Add\sand\sadjust\scomments. +D 2016-04-12T16:11:52.808 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -326,7 +326,7 @@ F src/build.c 1944d95f0250ec72dab939f8319a12e237aaad61 F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 60e135af364d777a9ab41c97e5e89cd224da6198 -F src/date.c b25819151358a5598a1beaf0da370692ce4a70d1 +F src/date.c 1cc9fb516ec9932c6fd4d2a0d2f8bc4480145c39 F src/dbstat.c c845548d4346e606e2f2b7d2e714ace2b8a7dd1b F src/delete.c 78eb999114ec04fcf1b7d123ccedb4b5b734930e F src/expr.c 17d4e745ef6a3fd2e4ef863f5f9a4912f1ba1198 @@ -360,7 +360,7 @@ F src/os.h 91ff889115ecd01f436d3611f7f5ea4dc12d92f1 F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85 F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa F src/os_unix.c bde4844f0849cab5924c6a81178f8500774ce76b -F src/os_win.c 9c84a48d56074d36866775a76089da69acb21594 +F src/os_win.c b169437dff859e308b3726594094a2f8ca922941 F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c 38718a019ca762ba4f6795425d5a54db70d1790d F src/pager.h e1d38a2f14849e219df0f91f8323504d134c8a56 @@ -1482,7 +1482,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b8094166b3c6a8ec7913b403e08b5e6790fb03c1 -R 10b47efb260a3b41bbe92a309e042fe1 +P b35bb928b25492f6dd71ccf9c250cb9f0cce09ff +R 042928a9099251248649d958d8ea8130 U mistachkin -Z 8cdaf1bfaef399409db07428454eae07 +Z 2dd922c09a9ceb4b9c3491d0203a672b diff --git a/manifest.uuid b/manifest.uuid index 3add6fef53..376b8b5755 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b35bb928b25492f6dd71ccf9c250cb9f0cce09ff \ No newline at end of file +541c6da23850673f5d2a2e31c3967b796ee2effc \ No newline at end of file diff --git a/src/date.c b/src/date.c index 182b7d594d..cce16305a3 100644 --- a/src/date.c +++ b/src/date.c @@ -51,8 +51,9 @@ #ifndef SQLITE_OMIT_DATETIME_FUNCS /* -** The MSVC CRT on Windows CE may not have a localtime() function. So -** declare a substitute. +** The MSVC CRT on Windows CE may not have a localtime() function. +** So declare a substitute. The substitute function itself is +** defined in "os_win.c". */ #if !defined(SQLITE_OMIT_LOCALTIME) && defined(_WIN32_WCE) && \ (!defined(SQLITE_MSVC_LOCALTIME_API) || !SQLITE_MSVC_LOCALTIME_API) diff --git a/src/os_win.c b/src/os_win.c index d6156d7bbf..929ad346cc 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -2119,11 +2119,15 @@ static void winLogIoerr(int nRetry, int lineno){ } /* -** The MSVC CRT on Windows CE may not have a localtime() function. So -** define a substitute. +** This #if does not rely on the SQLITE_OS_WINCE define because the +** corresponding section in "date.c" cannot use it. */ #if !defined(SQLITE_OMIT_LOCALTIME) && defined(_WIN32_WCE) && \ (!defined(SQLITE_MSVC_LOCALTIME_API) || !SQLITE_MSVC_LOCALTIME_API) +/* +** The MSVC CRT on Windows CE may not have a localtime() function. +** So define a substitute. +*/ # include struct tm *__cdecl localtime(const time_t *t) { From 2160ca5f8ddbd29a89bf7d194e282fbaeff73a3e Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 12 Apr 2016 16:59:39 +0000 Subject: [PATCH 0293/1484] Add the --temp option to the speedtest1.c performance test program. FossilOrigin-Name: 8053a6e2bf616fc9326f0323962176e318d7d2a5 --- manifest | 13 ++++++------- manifest.uuid | 2 +- test/speedtest1.c | 35 ++++++++++++++++++++++++++--------- 3 files changed, 33 insertions(+), 17 deletions(-) diff --git a/manifest b/manifest index ff7a1468a7..6ca8cb5234 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improved\slocaltime()\ssupport\sfor\sWindowsCE -D 2016-04-12T16:23:30.244 +C Add\sthe\s--temp\soption\sto\sthe\sspeedtest1.c\sperformance\stest\sprogram. +D 2016-04-12T16:59:39.643 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -1083,7 +1083,7 @@ F test/speed3.test d32043614c08c53eafdc80f33191d5bd9b920523 F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715 F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b -F test/speedtest1.c 21af8db2492a903835b654517ac8d90aed0af91f +F test/speedtest1.c 870ea1f3086ace7125f578cfae7ac1137b3e0bdd F test/spellfix.test f9c1f431e2c096c8775fec032952320c0e4700db F test/spellfix2.test dfc8f519a3fc204cb2dfa8b4f29821ae90f6f8c3 F test/spellfix3.test 0f9efaaa502a0e0a09848028518a6fb096c8ad33 @@ -1482,8 +1482,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 7e7289655185e7643ead6d685922528bc4d9e0ae 541c6da23850673f5d2a2e31c3967b796ee2effc -R ff0c266585dc1c24384af2892b8942ce -T +closed 541c6da23850673f5d2a2e31c3967b796ee2effc +P 662c32af0276a9ef4eea2d29e2523ccc44b6d128 +R cf025f2af3ea009a3845c13fd71354e9 U drh -Z 2794cf8f4a03e9c72f55b1cbc1df2c40 +Z ba428edd13c3659c3e56c28f6b7f2005 diff --git a/manifest.uuid b/manifest.uuid index 1e27f6a99e..3197cf8598 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -662c32af0276a9ef4eea2d29e2523ccc44b6d128 \ No newline at end of file +8053a6e2bf616fc9326f0323962176e318d7d2a5 \ No newline at end of file diff --git a/test/speedtest1.c b/test/speedtest1.c index 8ed0424f88..bcd85b049b 100644 --- a/test/speedtest1.c +++ b/test/speedtest1.c @@ -30,6 +30,7 @@ static const char zHelp[] = " --shrink-memory Invoke sqlite3_db_release_memory() frequently.\n" " --size N Relative test size. Default=100\n" " --stats Show statistics at the end\n" + " --temp N N from 0 to 9. 0: no temp table. 9: all temp tables\n" " --testset T Run test-set T\n" " --trace Turn on SQL tracing\n" " --threads N Use up to N threads for sorting\n" @@ -69,6 +70,7 @@ static struct Global { int bExplain; /* Print SQL with EXPLAIN prefix */ int bVerify; /* Try to verify that results are correct */ int bMemShrink; /* Call sqlite3_db_release_memory() often */ + int eTemp; /* 0: no TEMP. 9: always TEMP. */ int szTest; /* Scale factor for test iterations */ const char *zWR; /* Might be WITHOUT ROWID */ const char *zNN; /* Might be NOT NULL */ @@ -78,6 +80,12 @@ static struct Global { char zResult[3000]; /* Text of the current result */ } g; +/* Return " TEMP" or "", as appropriate for creating a table. +*/ +static const char *isTemp(int N){ + return g.eTemp>=N ? " TEMP" : ""; +} + /* Print an error message and exit */ static void fatal_error(const char *zMsg, ...){ @@ -459,8 +467,8 @@ void testset_main(void){ maxb = roundup_allones(sz); speedtest1_begin_test(100, "%d INSERTs into table with no index", n); speedtest1_exec("BEGIN"); - speedtest1_exec("CREATE TABLE t1(a INTEGER %s, b INTEGER %s, c TEXT %s);", - g.zNN, g.zNN, g.zNN); + speedtest1_exec("CREATE%s TABLE t1(a INTEGER %s, b INTEGER %s, c TEXT %s);", + isTemp(9), g.zNN, g.zNN, g.zNN); speedtest1_prepare("INSERT INTO t1 VALUES(?1,?2,?3); -- %d times", n); for(i=1; i<=n; i++){ x1 = swizzle(i,maxb); @@ -477,8 +485,9 @@ void testset_main(void){ n = sz; speedtest1_begin_test(110, "%d ordered INSERTS with one index/PK", n); speedtest1_exec("BEGIN"); - speedtest1_exec("CREATE TABLE t2(a INTEGER %s %s, b INTEGER %s, c TEXT %s) %s", - g.zNN, g.zPK, g.zNN, g.zNN, g.zWR); + speedtest1_exec( + "CREATE%s TABLE t2(a INTEGER %s %s, b INTEGER %s, c TEXT %s) %s", + isTemp(5), g.zNN, g.zPK, g.zNN, g.zNN, g.zWR); speedtest1_prepare("INSERT INTO t2 VALUES(?1,?2,?3); -- %d times", n); for(i=1; i<=n; i++){ x1 = swizzle(i,maxb); @@ -495,8 +504,9 @@ void testset_main(void){ n = sz; speedtest1_begin_test(120, "%d unordered INSERTS with one index/PK", n); speedtest1_exec("BEGIN"); - speedtest1_exec("CREATE TABLE t3(a INTEGER %s %s, b INTEGER %s, c TEXT %s) %s", - g.zNN, g.zPK, g.zNN, g.zNN, g.zWR); + speedtest1_exec( + "CREATE%s TABLE t3(a INTEGER %s %s, b INTEGER %s, c TEXT %s) %s", + isTemp(3), g.zNN, g.zPK, g.zNN, g.zNN, g.zWR); speedtest1_prepare("INSERT INTO t3 VALUES(?1,?2,?3); -- %d times", n); for(i=1; i<=n; i++){ x1 = swizzle(i,maxb); @@ -654,12 +664,12 @@ void testset_main(void){ speedtest1_begin_test(180, "%d INSERTS with three indexes", n); speedtest1_exec("BEGIN"); speedtest1_exec( - "CREATE TABLE t4(\n" + "CREATE%s TABLE t4(\n" " a INTEGER %s %s,\n" " b INTEGER %s,\n" " c TEXT %s\n" ") %s", - g.zNN, g.zPK, g.zNN, g.zNN, g.zWR); + isTemp(1), g.zNN, g.zPK, g.zNN, g.zNN, g.zWR); speedtest1_exec("CREATE INDEX t4b ON t4(b)"); speedtest1_exec("CREATE INDEX t4c ON t4(c)"); speedtest1_exec("INSERT INTO t4 SELECT * FROM t1"); @@ -1047,7 +1057,7 @@ void testset_rtree(int p1, int p2){ speedtest1_end_test(); speedtest1_begin_test(101, "Copy from rtree to a regular table"); - speedtest1_exec("CREATE TABLE t1(id INTEGER PRIMARY KEY,x0,x1,y0,y1,z0,z1)"); + speedtest1_exec(" TABLE t1(id INTEGER PRIMARY KEY,x0,x1,y0,y1,z0,z1)"); speedtest1_exec("INSERT INTO t1 SELECT * FROM rt1"); speedtest1_end_test(); @@ -1321,6 +1331,13 @@ int main(int argc, char **argv){ g.szTest = integerValue(argv[++i]); }else if( strcmp(z,"stats")==0 ){ showStats = 1; + }else if( strcmp(z,"temp")==0 ){ + if( i>=argc-1 ) fatal_error("missing argument on %s\n", argv[i]); + i++; + if( argv[i][0]<'0' || argv[i][0]>'9' || argv[i][1]!=0 ){ + fatal_error("argument to --temp should be integer between 0 and 9"); + } + g.eTemp = argv[i][0] - '0'; }else if( strcmp(z,"testset")==0 ){ if( i>=argc-1 ) fatal_error("missing argument on %s\n", argv[i]); zTSet = argv[++i]; From 741c2772dbdbc55e31de0c2201c380e25ce28315 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 12 Apr 2016 17:13:33 +0000 Subject: [PATCH 0294/1484] Fix speedtest1 so that it automatically unlinks its test database prior to startup. FossilOrigin-Name: b65b69f6b686c6555876b6fc701da95cc49120b5 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/speedtest1.c | 6 +----- 3 files changed, 8 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 6ca8cb5234..2d86b5ab27 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\s--temp\soption\sto\sthe\sspeedtest1.c\sperformance\stest\sprogram. -D 2016-04-12T16:59:39.643 +C Fix\sspeedtest1\sso\sthat\sit\sautomatically\sunlinks\sits\stest\sdatabase\sprior\nto\sstartup. +D 2016-04-12T17:13:33.302 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -1083,7 +1083,7 @@ F test/speed3.test d32043614c08c53eafdc80f33191d5bd9b920523 F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715 F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b -F test/speedtest1.c 870ea1f3086ace7125f578cfae7ac1137b3e0bdd +F test/speedtest1.c 4476f7030775507f060d27b789e1f4123c5a5866 F test/spellfix.test f9c1f431e2c096c8775fec032952320c0e4700db F test/spellfix2.test dfc8f519a3fc204cb2dfa8b4f29821ae90f6f8c3 F test/spellfix3.test 0f9efaaa502a0e0a09848028518a6fb096c8ad33 @@ -1482,7 +1482,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 662c32af0276a9ef4eea2d29e2523ccc44b6d128 -R cf025f2af3ea009a3845c13fd71354e9 +P 8053a6e2bf616fc9326f0323962176e318d7d2a5 +R 3ae5c3c6eb252cc89c8a785d5876dd69 U drh -Z ba428edd13c3659c3e56c28f6b7f2005 +Z 19aed5e20f081d47becc5b2db0de637c diff --git a/manifest.uuid b/manifest.uuid index 3197cf8598..a2fb631158 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8053a6e2bf616fc9326f0323962176e318d7d2a5 \ No newline at end of file +b65b69f6b686c6555876b6fc701da95cc49120b5 \ No newline at end of file diff --git a/test/speedtest1.c b/test/speedtest1.c index bcd85b049b..2d337d4705 100644 --- a/test/speedtest1.c +++ b/test/speedtest1.c @@ -1369,11 +1369,7 @@ int main(int argc, char **argv){ argv[i], argv[0]); } } -#if 0 - if( zDbName==0 ){ - fatal_error(zHelp, argv[0]); - } -#endif + if( zDbName!=0 ) unlink(zDbName); #if SQLITE_VERSION_NUMBER>=3006001 if( nHeap>0 ){ pHeap = malloc( nHeap ); From 199f56b98455731ccfd8297bf6f3906866c8309c Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 12 Apr 2016 19:09:29 +0000 Subject: [PATCH 0295/1484] Once a temporary database file has been opened, flush all dirty pages to disk when comitting a transaction. FossilOrigin-Name: bbac71aa2aa2380d393cda3be64b0208b464b27e --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/pager.c | 7 ++++--- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 6c3dd2f0cc..1f71471219 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\senhancements\sfrom\strunk. -D 2016-04-12T16:10:10.308 +C Once\sa\stemporary\sdatabase\sfile\shas\sbeen\sopened,\sflush\sall\sdirty\spages\sto\sdisk\swhen\scomitting\sa\stransaction. +D 2016-04-12T19:09:29.339 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -362,7 +362,7 @@ F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa F src/os_unix.c bde4844f0849cab5924c6a81178f8500774ce76b F src/os_win.c b3ba9573d8d893e70a6a8015bbee572ecf7ffbef F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca -F src/pager.c 4cc8a5b3979db65725eaa03650a6d54219122b8d +F src/pager.c 525f3698f9a6b47a6e0f5496675529a183c2462b F src/pager.h e1d38a2f14849e219df0f91f8323504d134c8a56 F src/parse.y 10eb2f3fb62341291528c7984498054731f9d31e F src/pcache.c e9c00846d3dcdaa75b288c6f16238c2fe2177823 @@ -1484,7 +1484,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 04b1890fbc19eb3fa935083c1664fbbfb67dad93 7e7289655185e7643ead6d685922528bc4d9e0ae -R 5d35ce920fcfc7013551c54ce7d1cde0 -U drh -Z 97342c74358cb773c29965a93119c3f8 +P 9682c0433c04713c28bd9105a7e20af7372f873e +R ade8e2f9d92ad43fcc4c6c4e5d1634ec +U dan +Z 4a91ff9d1af5229ff41acb5284c79d70 diff --git a/manifest.uuid b/manifest.uuid index 01a6eda77e..90747752ed 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9682c0433c04713c28bd9105a7e20af7372f873e \ No newline at end of file +bbac71aa2aa2380d393cda3be64b0208b464b27e \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index 9baddc2986..e8c612e5c8 100644 --- a/src/pager.c +++ b/src/pager.c @@ -2011,7 +2011,7 @@ static int pager_end_transaction(Pager *pPager, int hasMaster, int bCommit){ sqlite3BitvecDestroy(pPager->pInJournal); pPager->pInJournal = 0; pPager->nRec = 0; - if( pPager->tempFile==0 || MEMDB ){ + if( isOpen(pPager->fd) || MEMDB ){ sqlite3PcacheCleanAll(pPager->pPCache); }else{ sqlite3PcacheClearWritable(pPager->pPCache); @@ -4273,7 +4273,7 @@ static int pager_write_pagelist(Pager *pPager, PgHdr *pList){ assert( !pagerUseWal(pPager) ); assert( pPager->tempFile || pPager->eState==PAGER_WRITER_DBMOD ); assert( pPager->eLock==EXCLUSIVE_LOCK ); - assert( pPager->tempFile==0 || pList->pDirty==0 ); + assert( isOpen(pPager->fd) || pList->pDirty==0 ); /* If the file is a temp-file has not yet been opened, open it now. It ** is not possible for rc to be other than SQLITE_OK if this branch @@ -6195,7 +6195,8 @@ int sqlite3PagerCommitPhaseOne( if( pPager->eStatetempFile ); - if( pPager->tempFile ){ + assert( isOpen(pPager->fd) || pPager->tempFile ); + if( !isOpen(pPager->fd) ){ /* If this is an in-memory db, or no pages have been written to, or this ** function has already been called, it is mostly a no-op. However, any ** backup in progress needs to be restarted. */ From 74f598b6773eba45fb78e35ba8af54ad7706e840 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Tue, 12 Apr 2016 19:20:22 +0000 Subject: [PATCH 0296/1484] Fix harmless compiler warnings in the 'session' module. FossilOrigin-Name: a18a6ce2271865d04cd75a8a5baa63798b7393db --- ext/session/sqlite3session.c | 6 +++--- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index 437549dd70..62a502ed0a 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -935,9 +935,9 @@ static int sessionTableInfo( int nDbCol = 0; int nThis; int i; - u8 *pAlloc; + u8 *pAlloc = 0; char **azCol = 0; - u8 *abPK; + u8 *abPK = 0; assert( pazCol && pabPK ); @@ -3655,7 +3655,7 @@ static int sessionConflictHandler( void *pCtx, /* First argument for conflict handler */ int *pbReplace /* OUT: Set to true if PK row is found */ ){ - int res; /* Value returned by conflict handler */ + int res = 0; /* Value returned by conflict handler */ int rc; int nCol; int op; diff --git a/manifest b/manifest index 2d86b5ab27..63ef5a75e5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sspeedtest1\sso\sthat\sit\sautomatically\sunlinks\sits\stest\sdatabase\sprior\nto\sstartup. -D 2016-04-12T17:13:33.302 +C Fix\sharmless\scompiler\swarnings\sin\sthe\s'session'\smodule. +D 2016-04-12T19:20:22.748 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -291,7 +291,7 @@ F ext/session/sessionG.test 01ef705096a9d3984eebdcca79807a211dee1b60 F ext/session/session_common.tcl a1293167d14774b5e728836720497f40fe4ea596 F ext/session/sessionfault.test d52cbb7bee48cc8ee80335e07eb72fcb6b15eb40 F ext/session/sessionfault2.test ac1dfd77a0fb0ea310aee40a16645ef1b66d3f88 -F ext/session/sqlite3session.c 2fc72bd989c424a15802da766c7ebd8eed47bcf6 +F ext/session/sqlite3session.c 7cd68ba5ecd42b67f81b35e1b745377b930321dc F ext/session/sqlite3session.h 64e9e7f185725ef43b97f4a9a0c0df0669844f1d F ext/session/test_session.c 187bd344c5ae9d5be85e22ef7c3010f0c17307ce F ext/userauth/sqlite3userauth.h 19cb6f0e31316d0ee4afdfb7a85ef9da3333a220 @@ -1482,7 +1482,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 8053a6e2bf616fc9326f0323962176e318d7d2a5 -R 3ae5c3c6eb252cc89c8a785d5876dd69 -U drh -Z 19aed5e20f081d47becc5b2db0de637c +P b65b69f6b686c6555876b6fc701da95cc49120b5 +R ccc0acaae74ee3b966fc3362e59511d7 +U mistachkin +Z 60a8c701bde6b1e9a5a93858cf1bfd0c diff --git a/manifest.uuid b/manifest.uuid index a2fb631158..7e644ceda9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b65b69f6b686c6555876b6fc701da95cc49120b5 \ No newline at end of file +a18a6ce2271865d04cd75a8a5baa63798b7393db \ No newline at end of file From 02267cc2136bc3cde2ae9cc3a02f91e2dc497793 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Tue, 12 Apr 2016 19:30:31 +0000 Subject: [PATCH 0297/1484] Compilation fix for a C99-ism in the 'fts3view' tool. FossilOrigin-Name: bedb88a4b9c808ea781ae69058399a1a3a3d15fa --- ext/fts3/tool/fts3view.c | 2 +- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/ext/fts3/tool/fts3view.c b/ext/fts3/tool/fts3view.c index a8d7981af0..37f9b7396d 100644 --- a/ext/fts3/tool/fts3view.c +++ b/ext/fts3/tool/fts3view.c @@ -398,8 +398,8 @@ static void showSegmentStats(sqlite3 *db, const char *zTab){ if( sqlite3_step(pStmt)==SQLITE_ROW && (nLeaf = sqlite3_column_int(pStmt, 0))>0 ){ - nIdx = sqlite3_column_int(pStmt, 5); sqlite3_int64 sz; + nIdx = sqlite3_column_int(pStmt, 5); printf("For level %d:\n", i); printf(" Number of indexes...................... %9d\n", nIdx); printf(" Number of leaf segments................ %9d\n", nLeaf); diff --git a/manifest b/manifest index 63ef5a75e5..ef6f2bcf49 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\scompiler\swarnings\sin\sthe\s'session'\smodule. -D 2016-04-12T19:20:22.748 +C Compilation\sfix\sfor\sa\sC99-ism\sin\sthe\s'fts3view'\stool. +D 2016-04-12T19:30:31.230 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -91,7 +91,7 @@ F ext/fts3/fts3_unicode2.c c3d01968d497bd7001e7dc774ba75b372738c057 F ext/fts3/fts3_write.c c3863f23b6b4623c8b9d5cf31c12ce4469f78ca9 F ext/fts3/fts3speed.tcl b54caf6a18d38174f1a6e84219950d85e98bb1e9 F ext/fts3/mkfts3amal.tcl 252ecb7fe6467854f2aa237bf2c390b74e71f100 -F ext/fts3/tool/fts3view.c 5d78b668f4e9598af9147f8999632599fb0d9dd5 +F ext/fts3/tool/fts3view.c 202801a2056995b763864d60c2dee744d46f1677 F ext/fts3/unicode/CaseFolding.txt 8c678ca52ecc95e16bc7afc2dbf6fc9ffa05db8c F ext/fts3/unicode/UnicodeData.txt cd07314edb62d49fde34debdaf92fa2aa69011e7 F ext/fts3/unicode/mkunicode.tcl 2debed3f582d77b3fdd0b8830880250021571fd8 @@ -1482,7 +1482,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b65b69f6b686c6555876b6fc701da95cc49120b5 -R ccc0acaae74ee3b966fc3362e59511d7 +P a18a6ce2271865d04cd75a8a5baa63798b7393db +R d725baf71b4a1cdc4415395863dd2840 U mistachkin -Z 60a8c701bde6b1e9a5a93858cf1bfd0c +Z 4008d4d2d72bf9083c3fc9e1b20a35f7 diff --git a/manifest.uuid b/manifest.uuid index 7e644ceda9..42ae789fd7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a18a6ce2271865d04cd75a8a5baa63798b7393db \ No newline at end of file +bedb88a4b9c808ea781ae69058399a1a3a3d15fa \ No newline at end of file From 77fac879d25b6500d3bd028a8e855fc9dc789634 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Tue, 12 Apr 2016 20:05:06 +0000 Subject: [PATCH 0298/1484] More harmless compiler warning fixes. FossilOrigin-Name: ab69527c1608da0b668f3b49e967661dd99cc3d4 --- ext/fts3/fts3_test.c | 2 +- ext/fts5/fts5_hash.c | 4 ++-- ext/fts5/fts5_index.c | 2 +- ext/misc/amatch.c | 8 ++++---- ext/misc/fuzzer.c | 4 ++-- ext/misc/regexp.c | 10 +++++----- ext/misc/spellfix.c | 20 ++++++++++---------- ext/rbu/sqlite3rbu.c | 2 +- manifest | 39 +++++++++++++++++++++------------------ manifest.uuid | 2 +- src/test_multiplex.c | 4 ++-- src/test_onefile.c | 2 +- src/test_osinst.c | 6 +++--- tool/logest.c | 2 +- tool/showdb.c | 4 ++-- 15 files changed, 57 insertions(+), 54 deletions(-) diff --git a/ext/fts3/fts3_test.c b/ext/fts3/fts3_test.c index dec977b916..2596e6dec7 100644 --- a/ext/fts3/fts3_test.c +++ b/ext/fts3/fts3_test.c @@ -458,7 +458,7 @@ static int testTokenizerNext( if( pCsr->iLangid & 0x00000001 ){ for(i=0; iaBuffer[i] = pToken[i]; }else{ - for(i=0; iaBuffer[i] = testTolower(pToken[i]); + for(i=0; iaBuffer[i] = (char)testTolower(pToken[i]); } pCsr->iToken++; pCsr->iInput = (int)(p - pCsr->aInput); diff --git a/ext/fts5/fts5_hash.c b/ext/fts5/fts5_hash.c index ada8bb16cb..afa2a30739 100644 --- a/ext/fts5/fts5_hash.c +++ b/ext/fts5/fts5_hash.c @@ -345,11 +345,11 @@ int sqlite3Fts5HashWrite( if( pHash->eDetail==FTS5_DETAIL_FULL ){ pPtr[p->nData++] = 0x01; p->nData += sqlite3Fts5PutVarint(&pPtr[p->nData], iCol); - p->iCol = iCol; + p->iCol = (i16)iCol; p->iPos = 0; }else{ bNew = 1; - p->iCol = iPos = iCol; + p->iCol = (i16)(iPos = iCol); } } diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index 1200f5707b..1d5ebe1428 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -3244,7 +3244,7 @@ static void fts5IterSetOutputs_Col100(Fts5Iter *pIter, Fts5SegIter *pSeg){ if( aiCol==aiColEnd ) goto setoutputs_col_out; } if( *aiCol==iPrev ){ - *aOut++ = (iPrev - iPrevOut) + 2; + *aOut++ = (u8)((iPrev - iPrevOut) + 2); iPrevOut = iPrev; } } diff --git a/ext/misc/amatch.c b/ext/misc/amatch.c index 852491988a..efe76566ee 100644 --- a/ext/misc/amatch.c +++ b/ext/misc/amatch.c @@ -625,10 +625,10 @@ static int amatchLoadOneRule( }else{ memset(pRule, 0, sizeof(*pRule)); pRule->zFrom = &pRule->zTo[nTo+1]; - pRule->nFrom = nFrom; + pRule->nFrom = (amatch_len)nFrom; memcpy(pRule->zFrom, zFrom, nFrom+1); memcpy(pRule->zTo, zTo, nTo+1); - pRule->nTo = nTo; + pRule->nTo = (amatch_len)nTo; pRule->rCost = rCost; pRule->iLang = (int)iLang; } @@ -1081,7 +1081,7 @@ static void amatchAddWord( pWord->rCost = rCost; pWord->iSeq = pCur->nWord++; amatchWriteCost(pWord); - pWord->nMatch = nMatch; + pWord->nMatch = (short)nMatch; pWord->pNext = pCur->pAllWords; pCur->pAllWords = pWord; pWord->sCost.zKey = pWord->zCost; @@ -1162,7 +1162,7 @@ static int amatchNext(sqlite3_vtab_cursor *cur){ #endif nWord = (int)strlen(pWord->zWord+2); if( nWord+20>nBuf ){ - nBuf = nWord+100; + nBuf = (char)(nWord+100); zBuf = sqlite3_realloc(zBuf, nBuf); if( zBuf==0 ) return SQLITE_NOMEM; } diff --git a/ext/misc/fuzzer.c b/ext/misc/fuzzer.c index 3ed4b0a977..77db56d47a 100644 --- a/ext/misc/fuzzer.c +++ b/ext/misc/fuzzer.c @@ -344,10 +344,10 @@ static int fuzzerLoadOneRule( memset(pRule, 0, sizeof(*pRule)); pRule->zFrom = pRule->zTo; pRule->zFrom += nTo + 1; - pRule->nFrom = nFrom; + pRule->nFrom = (fuzzer_len)nFrom; memcpy(pRule->zFrom, zFrom, nFrom+1); memcpy(pRule->zTo, zTo, nTo+1); - pRule->nTo = nTo; + pRule->nTo = (fuzzer_len)nTo; pRule->rCost = nCost; pRule->iRuleset = (int)iRuleset; } diff --git a/ext/misc/regexp.c b/ext/misc/regexp.c index 7244d52998..b4a8ab5c04 100644 --- a/ext/misc/regexp.c +++ b/ext/misc/regexp.c @@ -136,7 +136,7 @@ struct ReCompiled { static void re_add_state(ReStateSet *pSet, int newState){ unsigned i; for(i=0; inState; i++) if( pSet->aState[i]==newState ) return; - pSet->aState[pSet->nState++] = newState; + pSet->aState[pSet->nState++] = (ReStateNumber)newState; } /* Extract the next unicode character from *pzIn and return it. Advance @@ -358,7 +358,7 @@ static int re_insert(ReCompiled *p, int iBefore, int op, int arg){ p->aArg[i] = p->aArg[i-1]; } p->nState++; - p->aOp[iBefore] = op; + p->aOp[iBefore] = (char)op; p->aArg[iBefore] = arg; return iBefore; } @@ -677,12 +677,12 @@ const char *re_compile(ReCompiled **ppRe, const char *zIn, int noCase){ for(j=0, i=1; jzInit)-2 && pRe->aOp[i]==RE_OP_MATCH; i++){ unsigned x = pRe->aArg[i]; if( x<=127 ){ - pRe->zInit[j++] = x; + pRe->zInit[j++] = (unsigned char)x; }else if( x<=0xfff ){ - pRe->zInit[j++] = 0xc0 | (x>>6); + pRe->zInit[j++] = (unsigned char)(0xc0 | (x>>6)); pRe->zInit[j++] = 0x80 | (x&0x3f); }else if( x<=0xffff ){ - pRe->zInit[j++] = 0xd0 | (x>>12); + pRe->zInit[j++] = (unsigned char)(0xd0 | (x>>12)); pRe->zInit[j++] = 0x80 | ((x>>6)&0x3f); pRe->zInit[j++] = 0x80 | (x&0x3f); }else{ diff --git a/ext/misc/spellfix.c b/ext/misc/spellfix.c index b5859ea2c8..cbcf8b7c5d 100644 --- a/ext/misc/spellfix.c +++ b/ext/misc/spellfix.c @@ -390,7 +390,7 @@ static int editdist1(const char *zA, const char *zB, int *pnMatch){ /* Special processing if either string is empty */ if( nA==0 ){ - cBprev = dc; + cBprev = (char)dc; for(xB=res=0; (cB = zB[xB])!=0; xB++){ res += insertOrDeleteCost(cBprev, cB, zB[xB+1])/FINAL_INS_COST_DIV; cBprev = cB; @@ -398,7 +398,7 @@ static int editdist1(const char *zA, const char *zB, int *pnMatch){ return res; } if( nB==0 ){ - cAprev = dc; + cAprev = (char)dc; for(xA=res=0; (cA = zA[xA])!=0; xA++){ res += insertOrDeleteCost(cAprev, cA, zA[xA+1]); cAprev = cA; @@ -420,8 +420,8 @@ static int editdist1(const char *zA, const char *zB, int *pnMatch){ /* Compute the Wagner edit distance */ m[0] = 0; - cx[0] = dc; - cBprev = dc; + cx[0] = (char)dc; + cBprev = (char)dc; for(xB=1; xB<=nB; xB++){ cBnext = zB[xB]; cB = zB[xB-1]; @@ -429,7 +429,7 @@ static int editdist1(const char *zA, const char *zB, int *pnMatch){ m[xB] = m[xB-1] + insertOrDeleteCost(cBprev, cB, cBnext); cBprev = cB; } - cAprev = dc; + cAprev = (char)dc; for(xA=1; xA<=nA; xA++){ int lastA = (xA==nA); cA = zA[xA-1]; @@ -476,7 +476,7 @@ static int editdist1(const char *zA, const char *zB, int *pnMatch){ d = m[xB]; dc = cx[xB]; m[xB] = totalCost; - cx[xB] = ncx; + cx[xB] = (char)ncx; cBprev = cB; } cAprev = cA; @@ -711,9 +711,9 @@ static int editDist3ConfigLoad( if( nExtra<0 ) nExtra = 0; pCost = sqlite3_malloc64( sizeof(*pCost) + nExtra ); if( pCost==0 ){ rc = SQLITE_NOMEM; break; } - pCost->nFrom = nFrom; - pCost->nTo = nTo; - pCost->iCost = iCost; + pCost->nFrom = (u8)nFrom; + pCost->nTo = (u8)nTo; + pCost->iCost = (u16)iCost; memcpy(pCost->a, zFrom, nFrom); memcpy(pCost->a + nFrom, zTo, nTo); pCost->pNext = pLang->pCost; @@ -1616,7 +1616,7 @@ static unsigned char *transliterate(const unsigned char *zIn, int nIn){ zIn += sz; nIn -= sz; if( c<=127 ){ - zOut[nOut++] = c; + zOut[nOut++] = (unsigned char)c; }else{ int xTop, xBtm, x; xTop = sizeof(translit)/sizeof(translit[0]) - 1; diff --git a/ext/rbu/sqlite3rbu.c b/ext/rbu/sqlite3rbu.c index 93b756aa6a..f553ebdac5 100644 --- a/ext/rbu/sqlite3rbu.c +++ b/ext/rbu/sqlite3rbu.c @@ -3356,7 +3356,7 @@ sqlite3 *sqlite3rbu_db(sqlite3rbu *pRbu, int bRbu){ */ static void rbuEditErrmsg(sqlite3rbu *p){ if( p->rc==SQLITE_CONSTRAINT && p->zErrmsg ){ - int i; + unsigned int i; size_t nErrmsg = strlen(p->zErrmsg); for(i=0; i<(nErrmsg-8); i++){ if( memcmp(&p->zErrmsg[i], "rbu_imp_", 8)==0 ){ diff --git a/manifest b/manifest index ef6f2bcf49..ba0f2dffbe 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Compilation\sfix\sfor\sa\sC99-ism\sin\sthe\s'fts3view'\stool. -D 2016-04-12T19:30:31.230 +C More\sharmless\scompiler\swarning\sfixes. +D 2016-04-12T20:05:06.603 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -81,7 +81,7 @@ F ext/fts3/fts3_icu.c deb46f7020d87ea7a14a433fb7a7f4bef42a9652 F ext/fts3/fts3_porter.c 3565faf04b626cddf85f03825e86056a4562c009 F ext/fts3/fts3_snippet.c 68ae118b0f834ea53d2b89e4087fc0f0b8c4ee4e F ext/fts3/fts3_term.c 88c55a6fa1a51ab494e33dced0401a6c28791fd7 -F ext/fts3/fts3_test.c 11e36437b0f3f2266acea5b4787f615e4337a237 +F ext/fts3/fts3_test.c a940cf104d545ad1abf926956ce65db2aa5af0cf F ext/fts3/fts3_tokenize_vtab.c a27593ab19657166f6fa5ec073b678cc29a75860 F ext/fts3/fts3_tokenizer.c 3cf21cd2212db17a88d4ef7da0fd8a80275979a1 F ext/fts3/fts3_tokenizer.h 64c6ef6c5272c51ebe60fc607a896e84288fcbc3 @@ -103,8 +103,8 @@ F ext/fts5/fts5_aux.c daa57fb45216491814520bbb587e97bf81ced458 F ext/fts5/fts5_buffer.c 4c1502d4c956cd092c89ce4480867f9d8bf325cd F ext/fts5/fts5_config.c 5af9c360e99669d29f06492c370892394aba0857 F ext/fts5/fts5_expr.c 5ca4bafe29aa3d27683c90e836192e4aefd20a3f -F ext/fts5/fts5_hash.c f3a7217c86eb8f272871be5f6aa1b6798960a337 -F ext/fts5/fts5_index.c fdd82bb421a5d1e64d004acb43f4dd9970c8d2b3 +F ext/fts5/fts5_hash.c 880998e596b60f078348d48732ca4ad9a90caad2 +F ext/fts5/fts5_index.c b429e23fabb57506f71e406997cc46b89190dc97 F ext/fts5/fts5_main.c b4a0fc5bf17f2f1f056ee76cdd7d2af08b360f55 F ext/fts5/fts5_storage.c 3309c6a8e34b974513016fd1ef47c83f5898f94c F ext/fts5/fts5_tcl.c f8731e0508299bd43f1a2eff7dbeaac870768966 @@ -203,21 +203,21 @@ F ext/fts5/tool/showfts5.tcl d54da0e067306663e2d5d523965ca487698e722c F ext/icu/README.txt d9fbbad0c2f647c3fdf715fc9fd64af53aedfc43 F ext/icu/icu.c 4bdf4c5daedabcd8e6eb6e6a377657f7b978f9f7 F ext/icu/sqliteicu.h 728867a802baa5a96de7495e9689a8e01715ef37 -F ext/misc/amatch.c a1a8f66c29d40bd71b075546ddeddb477b17a2bb +F ext/misc/amatch.c 211108e201105e4bb0c076527b8cfd34330fc234 F ext/misc/closure.c 0d2a038df8fbae7f19de42e7c7d71f2e4dc88704 F ext/misc/compress.c 122faa92d25033d6c3f07c39231de074ab3d2e83 F ext/misc/eval.c f971962e92ebb8b0a4e6b62949463ee454d88fa2 F ext/misc/fileio.c d4171c815d6543a9edef8308aab2951413cd8d0f -F ext/misc/fuzzer.c 4c84635c71c26cfa7c2e5848cf49fe2d2cfcd767 +F ext/misc/fuzzer.c 7c64b8197bb77b7d64eff7cac7848870235d4c25 F ext/misc/ieee754.c f190d0cc5182529acb15babd177781be1ac1718c F ext/misc/json1.c b9c88d5c3b6ecd8c731ffdd7f5b3d902857f8c96 F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342 F ext/misc/percentile.c bcbee3c061b884eccb80e21651daaae8e1e43c63 -F ext/misc/regexp.c af92cdaa5058fcec1451e49becc7ba44dba023dc +F ext/misc/regexp.c a68d25c659bd2d893cd1215667bbf75ecb9dc7d4 F ext/misc/rot13.c 1ac6f95f99b575907b9b09c81a349114cf9be45a F ext/misc/series.c e11e534ada797d5b816d7e7a93c022306563ca35 F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52 -F ext/misc/spellfix.c 598bbc45516227701558becdd38f4e6fe8e97cc2 +F ext/misc/spellfix.c bf1b922c2750698e9a3d4c50cce6974adb7e93be F ext/misc/totype.c 4a167594e791abeed95e0a8db028822b5e8fe512 F ext/misc/vfslog.c fe40fab5c077a40477f7e5eba994309ecac6cc95 F ext/misc/vtshim.c babb0dc2bf116029e3e7c9a618b8a1377045303e @@ -246,7 +246,7 @@ F ext/rbu/rbufault2.test 9a7f19edd6ea35c4c9f807d8a3db0a03a5670c06 F ext/rbu/rbufts.test 828cd689da825f0a7b7c53ffc1f6f7fdb6fa5bda F ext/rbu/rbuprogress.test 2023a7df2c523e3df1cb532eff811cda385a789a F ext/rbu/rbusave.test 0f43b6686084f426ddd040b878426452fd2c2f48 -F ext/rbu/sqlite3rbu.c 007fc4db8c0b95c7ef10162b5864921ef5cc8106 +F ext/rbu/sqlite3rbu.c 9097f1d95666dbef72ca61d5b6a13a84660735ac F ext/rbu/sqlite3rbu.h d7cc99350c10134f358fe1a8997d9225b3f712b2 F ext/rbu/test_rbu.c 3505641a78b723589b8780d5f9b2faeeb73e037d F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 @@ -412,11 +412,11 @@ F src/test_intarray.h 9dc57417fb65bc7835cc18548852cc08cc062202 F src/test_journal.c 5360fbe1d1e4416ca36290562fd5a2e3f70f32aa F src/test_loadext.c 337056bae59f80b9eb00ba82088b39d0f4fe6dfd F src/test_malloc.c 94c18e88d6df6d471a0d04ddb809f833d1739950 -F src/test_multiplex.c 6a9de820fcaaf506c59aa14bc8693822333cea48 +F src/test_multiplex.c eafc567ebe162e36f17b5062285dfe90461cf8e9 F src/test_multiplex.h c08e4e8f8651f0c5e0509b138ff4d5b43ed1f5d3 F src/test_mutex.c dbdfaff8580071f2212a0deae3325a93a737819c -F src/test_onefile.c 38f7cbe79d5bafe95bde683cc3a53b8ca16daf10 -F src/test_osinst.c 5423dc1d355f594371f27dd292ca54bd320b8196 +F src/test_onefile.c 416f87a28d6d673352d33fc4b1c7d39db878e50f +F src/test_osinst.c ad0233b1dabb0390e25edded4ebd79a2a61538c6 F src/test_pcache.c a5cd24730cb43c5b18629043314548c9169abb00 F src/test_quota.c 180813f43683be5725458fc1ff13ac455d8e722d F src/test_quota.h 2a8ad1952d1d2ca9af0ce0465e56e6c023b5e15d @@ -1415,7 +1415,7 @@ F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce F tool/lemon.c cfbfe061a4b2766512f6b484882eee2c86a14506 F tool/lempar.c 404ea3dc27dbeed343f0e61b1d36e97b9f5f0fb6 F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862 -F tool/logest.c eef612f8adf4d0993dafed0416064cf50d5d33c6 +F tool/logest.c 11346aa019e2e77a00902aa7d0cabd27bd2e8cca F tool/mkautoconfamal.sh e855df211ecbcc7131dee817110ff386cfb112f7 F tool/mkkeywordhash.c f7f3b342211ac6a14258b9726d5b97cf4f548f22 F tool/mkmsvcmin.tcl 2f12f7fa8858bbe61cf81820a2da96c79ed1ca8d @@ -1436,7 +1436,7 @@ F tool/replace.tcl 7727c60a04299b65a92f5e1590896fea0f25b9e0 F tool/restore_jrnl.tcl 6957a34f8f1f0f8285e07536225ec3b292a9024a F tool/rollback-test.c 9fc98427d1e23e84429d7e6d07d9094fbdec65a5 F tool/run-speed-test.sh f95d19fd669b68c4c38b6b475242841d47c66076 -F tool/showdb.c 82dca79a999b2701c62417636345e9974151fdad +F tool/showdb.c c695a5d5c8110640e0d9fadf5e254da90c79c36e F tool/showjournal.c 5bad7ae8784a43d2b270d953060423b8bd480818 F tool/showlocks.c 9920bcc64f58378ff1118caead34147201f48c68 F tool/showstat4.c bda40d6e395df7edb6e9ea630784d3d762c35b4b @@ -1482,7 +1482,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a18a6ce2271865d04cd75a8a5baa63798b7393db -R d725baf71b4a1cdc4415395863dd2840 +P bedb88a4b9c808ea781ae69058399a1a3a3d15fa +R 03018f5836a18841da04ba58f1cc328d +T *branch * warnings +T *sym-warnings * +T -sym-trunk * U mistachkin -Z 4008d4d2d72bf9083c3fc9e1b20a35f7 +Z baaf8c0d1237121c0d8a28eaa252b406 diff --git a/manifest.uuid b/manifest.uuid index 42ae789fd7..55b0fff735 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bedb88a4b9c808ea781ae69058399a1a3a3d15fa \ No newline at end of file +ab69527c1608da0b668f3b49e967661dd99cc3d4 \ No newline at end of file diff --git a/src/test_multiplex.c b/src/test_multiplex.c index 07dcbbc1aa..ba4e61b090 100644 --- a/src/test_multiplex.c +++ b/src/test_multiplex.c @@ -539,7 +539,7 @@ static int multiplexOpen( memset(pGroup, 0, sz); pMultiplexOpen->pGroup = pGroup; pGroup->bEnabled = (unsigned char)-1; - pGroup->bTruncate = sqlite3_uri_boolean(zUri, "truncate", + pGroup->bTruncate = (unsigned char)sqlite3_uri_boolean(zUri, "truncate", (flags & SQLITE_OPEN_MAIN_DB)==0); pGroup->szChunk = (int)sqlite3_uri_int64(zUri, "chunksize", SQLITE_MULTIPLEX_CHUNK_SIZE); @@ -978,7 +978,7 @@ static int multiplexFileControl(sqlite3_file *pConn, int op, void *pArg){ case MULTIPLEX_CTRL_ENABLE: if( pArg ) { int bEnabled = *(int *)pArg; - pGroup->bEnabled = bEnabled; + pGroup->bEnabled = (unsigned char)bEnabled; rc = SQLITE_OK; } break; diff --git a/src/test_onefile.c b/src/test_onefile.c index 122be700e6..46c8bc9c83 100644 --- a/src/test_onefile.c +++ b/src/test_onefile.c @@ -508,7 +508,7 @@ static int fsSync(sqlite3_file *pFile, int flags){ if( p->eType==DATABASE_FILE ){ unsigned char zSize[4]; zSize[0] = (pReal->nDatabase&0xFF000000)>>24; - zSize[1] = (pReal->nDatabase&0x00FF0000)>>16; + zSize[1] = (unsigned char)((pReal->nDatabase&0x00FF0000)>>16); zSize[2] = (pReal->nDatabase&0x0000FF00)>>8; zSize[3] = (pReal->nDatabase&0x000000FF); rc = pRealFile->pMethods->xWrite(pRealFile, zSize, 4, 0); diff --git a/src/test_osinst.c b/src/test_osinst.c index 4ae23a87c6..e51ce77ef8 100644 --- a/src/test_osinst.c +++ b/src/test_osinst.c @@ -644,9 +644,9 @@ static void vfslog_flush(VfslogVfs *p){ static void put32bits(unsigned char *p, unsigned int v){ p[0] = v>>24; - p[1] = v>>16; - p[2] = v>>8; - p[3] = v; + p[1] = (unsigned char)(v>>16); + p[2] = (unsigned char)(v>>8); + p[3] = (unsigned char)v; } static void vfslog_call( diff --git a/tool/logest.c b/tool/logest.c index 347fa68a4f..e936e02cbe 100644 --- a/tool/logest.c +++ b/tool/logest.c @@ -147,7 +147,7 @@ int main(int argc, char **argv){ }else if( strcmp(z,"inv")==0 ){ if( n>0 ) a[n-1] = -a[n-1]; }else if( z[0]=='^' ){ - a[n++] = atoi(z+1); + a[n++] = (LogEst)atoi(z+1); }else if( isInteger(z) ){ a[n++] = logEstFromInteger(atoi(z)); }else if( isFloat(z) && z[0]!='-' ){ diff --git a/tool/showdb.c b/tool/showdb.c index 06cd36cd2c..d51a2fd83d 100644 --- a/tool/showdb.c +++ b/tool/showdb.c @@ -151,7 +151,7 @@ static unsigned char *fileRead(sqlite3_int64 ofst, int nByte){ exit(1); } }else{ - lseek(g.dbfd, ofst, SEEK_SET); + lseek(g.dbfd, (long)ofst, SEEK_SET); got = read(g.dbfd, aData, nByte); if( got>0 && got Date: Tue, 12 Apr 2016 20:15:12 +0000 Subject: [PATCH 0299/1484] Even more compiler warning fixes. FossilOrigin-Name: 7faec9ea335c53953338886398b85aef87348a1c --- ext/session/test_session.c | 5 ++--- manifest | 17 +++++++---------- manifest.uuid | 2 +- src/tclsqlite.c | 2 +- 4 files changed, 11 insertions(+), 15 deletions(-) diff --git a/ext/session/test_session.c b/ext/session/test_session.c index 15f7b6f575..1aa63b74ed 100644 --- a/ext/session/test_session.c +++ b/ext/session/test_session.c @@ -314,7 +314,8 @@ static void test_append_value(Tcl_Obj *pList, sqlite3_value *pVal){ pObj = Tcl_NewStringObj(z, n); break; } - case SQLITE_BLOB: + default: + assert( sqlite3_value_type(pVal)==SQLITE_BLOB ); Tcl_ListObjAppendElement(0, pList, Tcl_NewStringObj("b", 1)); pObj = Tcl_NewByteArrayObj( sqlite3_value_blob(pVal), @@ -871,7 +872,6 @@ static int test_sqlite3session_foreach( pOld = Tcl_NewObj(); if( op!=SQLITE_INSERT ){ - int i; for(i=0; ipWalHook; if( choice==DB_UPDATE_HOOK ) ppHook = &pDb->pUpdateHook; if( choice==DB_ROLLBACK_HOOK ) ppHook = &pDb->pRollbackHook; From 02d436b1f62cdf2a9d52f492f37315af3a60a59a Mon Sep 17 00:00:00 2001 From: mistachkin Date: Tue, 12 Apr 2016 20:26:51 +0000 Subject: [PATCH 0300/1484] A couple more compiler warning fixes. FossilOrigin-Name: 929fa4c31e7c5b8c6cbb1412478ea91b15ad5529 --- ext/session/sqlite3session.c | 7 +++---- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index 62a502ed0a..b058d357e2 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -1593,9 +1593,9 @@ static void sessionDeleteTable(SessionTable *pList){ pNext = pTab->pNext; for(i=0; inChange; i++){ SessionChange *p; - SessionChange *pNext; - for(p=pTab->apChange[i]; p; p=pNext){ - pNext = p->pNext; + SessionChange *pNextChange; + for(p=pTab->apChange[i]; p; p=pNextChange){ + pNextChange = p->pNext; sqlite3_free(p); } } @@ -2882,7 +2882,6 @@ static int sessionChangesetNext( ** modified fields are present in the new.* record. The old.* record ** is currently completely empty. This block shifts the PK fields from ** new.* to old.*, to accommodate the code that reads these arrays. */ - int i; for(i=0; inCol; i++){ assert( p->apValue[i]==0 ); assert( p->abPK[i]==0 || p->apValue[i+p->nCol] ); diff --git a/manifest b/manifest index f9632eb6dc..779f6d2d85 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Even\smore\scompiler\swarning\sfixes. -D 2016-04-12T20:15:12.629 +C A\scouple\smore\scompiler\swarning\sfixes. +D 2016-04-12T20:26:51.392 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -291,7 +291,7 @@ F ext/session/sessionG.test 01ef705096a9d3984eebdcca79807a211dee1b60 F ext/session/session_common.tcl a1293167d14774b5e728836720497f40fe4ea596 F ext/session/sessionfault.test d52cbb7bee48cc8ee80335e07eb72fcb6b15eb40 F ext/session/sessionfault2.test ac1dfd77a0fb0ea310aee40a16645ef1b66d3f88 -F ext/session/sqlite3session.c 7cd68ba5ecd42b67f81b35e1b745377b930321dc +F ext/session/sqlite3session.c beb300cd1b5c5054062c8e6e807b10475e363410 F ext/session/sqlite3session.h 64e9e7f185725ef43b97f4a9a0c0df0669844f1d F ext/session/test_session.c 464f2c8bf502795d95969387eb8e93f68c513c15 F ext/userauth/sqlite3userauth.h 19cb6f0e31316d0ee4afdfb7a85ef9da3333a220 @@ -1482,7 +1482,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ab69527c1608da0b668f3b49e967661dd99cc3d4 -R 20e961c07d1c1c471c08312c9c1778dd +P 7faec9ea335c53953338886398b85aef87348a1c +R 87aeb18b7b49f1214878481261210b19 U mistachkin -Z 5d6bc734cb4437d7a6fe4e81cf260e24 +Z a8f0651fba3c604b158b208be423d211 diff --git a/manifest.uuid b/manifest.uuid index 73e8c38367..99bf9a8c26 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7faec9ea335c53953338886398b85aef87348a1c \ No newline at end of file +929fa4c31e7c5b8c6cbb1412478ea91b15ad5529 \ No newline at end of file From 4926fec967841ca7bea32447a14e29a057cb90a4 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 13 Apr 2016 15:33:42 +0000 Subject: [PATCH 0301/1484] Add the --indent option to the .schema and .fullschema commands in the shell, to enable simple but effective pretty-printing. FossilOrigin-Name: 83cfe82cd6d31ec0a6193525fd92e63a2a43b142 --- manifest | 16 +++---- manifest.uuid | 2 +- src/shell.c | 109 +++++++++++++++++++++++++++++++++++++++++------ test/shell1.test | 2 +- 4 files changed, 106 insertions(+), 23 deletions(-) diff --git a/manifest b/manifest index ef6f2bcf49..fd372f61ab 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Compilation\sfix\sfor\sa\sC99-ism\sin\sthe\s'fts3view'\stool. -D 2016-04-12T19:30:31.230 +C Add\sthe\s--indent\soption\sto\sthe\s.schema\sand\s.fullschema\scommands\sin\sthe\sshell,\nto\senable\ssimple\sbut\seffective\spretty-printing. +D 2016-04-13T15:33:42.000 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -376,7 +376,7 @@ F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c b8f7174e5f8c33c44ded3a25a973d0bb89228c20 F src/rowset.c 9fe4b3ad7cc00944386bb600233d8f523de07a6e F src/select.c a07e6022e2b559f3c2ec80442472c5965fa7a3fc -F src/shell.c b7922fa264f8c8d72a5ec6dd0b091e15a93c4de5 +F src/shell.c aeaab68456010319cb71406cbaca05865b295154 F src/sqlite.h.in 64eb70a3b309751bebf73a5552a51244f68f0ea5 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 98f72cbfe00169c39089115427d06ea05fe4b4a2 @@ -1051,7 +1051,7 @@ F test/sharedA.test 0cdf1a76dfa00e6beee66af5b534b1e8df2720f5 F test/sharedB.test 16cc7178e20965d75278f410943109b77b2e645e F test/shared_err.test 2f2aee20db294b9924e81f6ccbe60f19e21e8506 F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304 -F test/shell1.test b3df199cef9bc722d4078c893a7093d31174ea11 +F test/shell1.test 023657b3f8ba108dbd5ff2ebc8fceb3cf6d4ff9f F test/shell2.test e242a9912f44f4c23c3d1d802a83e934e84c853b F test/shell3.test da513d522ef6f01cee8475dcf8332bff8982b3dd F test/shell4.test 69995ee1cc278eb149aa8746ce1f935f4eaf98b9 @@ -1482,7 +1482,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a18a6ce2271865d04cd75a8a5baa63798b7393db -R d725baf71b4a1cdc4415395863dd2840 -U mistachkin -Z 4008d4d2d72bf9083c3fc9e1b20a35f7 +P bedb88a4b9c808ea781ae69058399a1a3a3d15fa +R 3c29e35f34f5f72131dcf42e4c969859 +U drh +Z 8b78abfa618f6bd7144123bc68122527 diff --git a/manifest.uuid b/manifest.uuid index 42ae789fd7..37449ab981 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bedb88a4b9c808ea781ae69058399a1a3a3d15fa \ No newline at end of file +83cfe82cd6d31ec0a6193525fd92e63a2a43b142 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 001dd6d465..33010e5ff1 100644 --- a/src/shell.c +++ b/src/shell.c @@ -669,6 +669,7 @@ struct ShellState { #define MODE_Csv 7 /* Quote strings, numbers are plain */ #define MODE_Explain 8 /* Like MODE_Column, but do not truncate data */ #define MODE_Ascii 9 /* Use ASCII unit and record separators (0x1F/0x1E) */ +#define MODE_Pretty 10 /* Pretty-print schemas */ static const char *modeDescr[] = { "line", @@ -681,6 +682,7 @@ static const char *modeDescr[] = { "csv", "explain", "ascii", + "prettyprint", }; /* @@ -1054,7 +1056,71 @@ static int shell_callback( } break; } - case MODE_Semi: + case MODE_Semi: { /* .schema and .fullschema output */ + utf8_printf(p->out, "%s;\n", azArg[0]); + break; + } + case MODE_Pretty: { /* .schema and .fullschema with --indent */ + char *z; + int i,j; + int nParen = 0; + char cEnd = 0; + char c; + int nLine = 0; + assert( nArg==1 ); + if( azArg[0]==0 ) break; + if( sqlite3_strlike("CREATE VIEW%", azArg[0], 0)==0 + || sqlite3_strlike("CREATE TRIG%", azArg[0], 0)==0 + ){ + utf8_printf(p->out, "%s;\n", azArg[0]); + break; + } + z = sqlite3_mprintf("%s", azArg[0]); + j = 0; + for(i=0; IsSpace(z[i]); i++){} + for(; (c = z[i])!=0; i++){ + if( IsSpace(c) ){ + if( IsSpace(z[j-1]) || z[j-1]=='(' ) continue; + }else if( (c=='(' || c==')') && j>0 && IsSpace(z[j-1]) ){ + j--; + } + z[j++] = c; + } + while( j>0 && IsSpace(z[j-1]) ){ j--; } + z[j] = 0; + if( strlen30(z)>=79 ){ + for(i=j=0; z[i]; i++){ + char c = z[i]; + if( c==cEnd ){ + cEnd = 0; + }else if( c=='"' || c=='\'' || c=='`' ){ + cEnd = c; + }else if( c=='[' ){ + cEnd = ']'; + }else if( c=='(' ){ + nParen++; + }else if( c==')' ){ + nParen--; + if( nLine>0 && nParen==0 && j>0 ){ + utf8_printf(p->out, "%.*s\n", j, z); + j = 0; + } + } + z[j++] = c; + if( nParen==1 && (c=='(' || c==',' || c=='\n') ){ + if( c=='\n' ) j--; + utf8_printf(p->out, "%.*s\n ", j, z); + j = 0; + nLine++; + while( IsSpace(z[i+1]) ){ i++; } + } + } + z[j] = 0; + } + utf8_printf(p->out, "%s;\n", z); + sqlite3_free(z); + break; + } case MODE_List: { if( p->cnt++==0 && p->showHeader ){ for(i=0; iout, "%s", z); if( iout, "%s", p->colSeparator); - }else if( p->cMode==MODE_Semi ){ - utf8_printf(p->out, ";%s", p->rowSeparator); }else{ utf8_printf(p->out, "%s", p->rowSeparator); } @@ -2024,7 +2088,7 @@ static char zHelp[] = ".eqp on|off Enable or disable automatic EXPLAIN QUERY PLAN\n" ".exit Exit this program\n" ".explain ?on|off|auto? Turn EXPLAIN output mode on or off or to automatic\n" - ".fullschema Show schema and the content of sqlite_stat tables\n" + ".fullschema ?--indent? Show schema and the content of sqlite_stat tables\n" ".headers on|off Turn display of headers on or off\n" ".help Show this message\n" ".import FILE TABLE Import data from FILE into TABLE\n" @@ -2060,9 +2124,8 @@ static char zHelp[] = ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n" ".save FILE Write in-memory database into FILE\n" ".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off\n" - ".schema ?TABLE? Show the CREATE statements\n" - " If TABLE specified, only show tables matching\n" - " LIKE pattern TABLE.\n" + ".schema ?PATTERN? Show the CREATE statements matching PATTERN\n" + " Add --indent for pretty-printing\n" ".separator COL ?ROW? Change the column separator and optionally the row\n" " separator for both the output mode and .import\n" #if defined(SQLITE_ENABLE_SESSION) @@ -2933,6 +2996,17 @@ static int shellNomemError(void){ return 1; } +/* +** Compare the string as a command-line option with either one or two +** initial "-" characters. +*/ +static int optionMatch(const char *zStr, const char *zOpt){ + if( zStr[0]!='-' ) return 0; + zStr++; + if( zStr[0]=='-' ) zStr++; + return strcmp(zStr, zOpt)==0; +} + /* ** If an input line begins with "." then invoke this routine to ** process that line. @@ -3219,15 +3293,19 @@ static int do_meta_command(char *zLine, ShellState *p){ ShellState data; char *zErrMsg = 0; int doStats = 0; + memcpy(&data, p, sizeof(data)); + data.showHeader = 0; + data.cMode = data.mode = MODE_Semi; + if( nArg==2 && optionMatch(azArg[1], "indent") ){ + data.cMode = data.mode = MODE_Pretty; + nArg = 1; + } if( nArg!=1 ){ - raw_printf(stderr, "Usage: .fullschema\n"); + raw_printf(stderr, "Usage: .fullschema ?--indent?\n"); rc = 1; goto meta_command_exit; } open_db(p, 0); - memcpy(&data, p, sizeof(data)); - data.showHeader = 0; - data.cMode = data.mode = MODE_Semi; rc = sqlite3_exec(p->db, "SELECT sql FROM" " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x" @@ -3862,7 +3940,12 @@ static int do_meta_command(char *zLine, ShellState *p){ memcpy(&data, p, sizeof(data)); data.showHeader = 0; data.cMode = data.mode = MODE_Semi; - if( nArg==2 ){ + if( nArg>=2 && optionMatch(azArg[1], "indent") ){ + data.cMode = data.mode = MODE_Pretty; + nArg--; + if( nArg==2 ) azArg[1] = azArg[2]; + } + if( nArg==2 && azArg[1][0]!='-' ){ int i; for(i=0; azArg[1][i]; i++) azArg[1][i] = ToLower(azArg[1][i]); if( strcmp(azArg[1],"sqlite_master")==0 ){ @@ -3917,7 +4000,7 @@ static int do_meta_command(char *zLine, ShellState *p){ callback, &data, &zErrMsg ); }else{ - raw_printf(stderr, "Usage: .schema ?LIKE-PATTERN?\n"); + raw_printf(stderr, "Usage: .schema ?--indent? ?LIKE-PATTERN?\n"); rc = 1; goto meta_command_exit; } diff --git a/test/shell1.test b/test/shell1.test index 9dd0f42093..760c85fadc 100644 --- a/test/shell1.test +++ b/test/shell1.test @@ -568,7 +568,7 @@ do_test shell1-3.21.2 { do_test shell1-3.21.3 { # too many arguments catchcmd "test.db" ".schema FOO BAD" -} {1 {Usage: .schema ?LIKE-PATTERN?}} +} {1 {Usage: .schema ?--indent? ?LIKE-PATTERN?}} do_test shell1-3.21.4 { catchcmd "test.db" { From 0f52455a357769627eaaab4575dd8f5760b729a0 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 13 Apr 2016 16:52:11 +0000 Subject: [PATCH 0302/1484] On commit, flush dirty temp-file pages only if the file is already open and 25% or more of the cache is dirty. FossilOrigin-Name: f6babf2920340f25815c0a3c58de1e902c2f5542 --- manifest | 19 +++++++++++-------- manifest.uuid | 2 +- src/pager.c | 21 ++++++++++++++++++++- src/pcache.c | 11 +++++++++++ src/pcache.h | 3 +++ 5 files changed, 46 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 1f71471219..0105dfb0f4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Once\sa\stemporary\sdatabase\sfile\shas\sbeen\sopened,\sflush\sall\sdirty\spages\sto\sdisk\swhen\scomitting\sa\stransaction. -D 2016-04-12T19:09:29.339 +C On\scommit,\sflush\sdirty\stemp-file\spages\sonly\sif\sthe\sfile\sis\salready\sopen\sand\s25%\sor\smore\sof\sthe\scache\sis\sdirty. +D 2016-04-13T16:52:11.775 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -362,11 +362,11 @@ F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa F src/os_unix.c bde4844f0849cab5924c6a81178f8500774ce76b F src/os_win.c b3ba9573d8d893e70a6a8015bbee572ecf7ffbef F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca -F src/pager.c 525f3698f9a6b47a6e0f5496675529a183c2462b +F src/pager.c 4d849ad718980d698157cd136a40dc91cbeff4d3 F src/pager.h e1d38a2f14849e219df0f91f8323504d134c8a56 F src/parse.y 10eb2f3fb62341291528c7984498054731f9d31e -F src/pcache.c e9c00846d3dcdaa75b288c6f16238c2fe2177823 -F src/pcache.h 4d0ccaad264d360981ec5e6a2b596d6e85242545 +F src/pcache.c d63b34cce0a8aba1fa552428b2790e13877db553 +F src/pcache.h 60bc9893bfc0e16f8178fb5d8b6fcb8fab1d93c0 F src/pcache1.c c40cdb93586e21b5dd826b5e671240bd91c26b05 F src/pragma.c faf42922bb7ab2f6672cb550356c1967abae3c84 F src/pragma.h 64c78a648751b9f4f297276c4eb7507b14b4628c @@ -1484,7 +1484,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 9682c0433c04713c28bd9105a7e20af7372f873e -R ade8e2f9d92ad43fcc4c6c4e5d1634ec +P bbac71aa2aa2380d393cda3be64b0208b464b27e +R d455655e720096e5ec7c439c248aa874 +T *branch * tempfiles-25 +T *sym-tempfiles-25 * +T -sym-tempfiles-lazy-open * U dan -Z 4a91ff9d1af5229ff41acb5284c79d70 +Z 1d78549afb34b97c4ff4b3e2f6fd7c59 diff --git a/manifest.uuid b/manifest.uuid index 90747752ed..5f347a440e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bbac71aa2aa2380d393cda3be64b0208b464b27e \ No newline at end of file +f6babf2920340f25815c0a3c58de1e902c2f5542 \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index e8c612e5c8..2530a2836e 100644 --- a/src/pager.c +++ b/src/pager.c @@ -1873,6 +1873,25 @@ static int pager_error(Pager *pPager, int rc){ static int pager_truncate(Pager *pPager, Pgno nPage); +/* +** The write transaction open on the pager passed as the only argument is +** being committed. This function returns true if all dirty pages should +** be flushed to disk, or false otherwise. Pages should be flushed to disk +** unless one of the following is true: +** +** * The db is an in-memory database. +** +** * The db is a temporary database and the db file has not been opened. +** +** * The db is a temporary database and the cache contains less than +** C/4 dirty pages, where C is the configured cache-size. +*/ +static int pagerFlushOnCommit(Pager *pPager){ + if( pPager->tempFile==0 ) return 1; + if( !isOpen(pPager->fd) ) return 0; + return (sqlite3PCachePercentDirty(pPager->pPCache)>=25); +} + /* ** This routine ends a transaction. A transaction is usually ended by ** either a COMMIT or a ROLLBACK operation. This routine may be called @@ -2011,7 +2030,7 @@ static int pager_end_transaction(Pager *pPager, int hasMaster, int bCommit){ sqlite3BitvecDestroy(pPager->pInJournal); pPager->pInJournal = 0; pPager->nRec = 0; - if( isOpen(pPager->fd) || MEMDB ){ + if( pagerFlushOnCommit(pPager) ){ sqlite3PcacheCleanAll(pPager->pPCache); }else{ sqlite3PcacheClearWritable(pPager->pPCache); diff --git a/src/pcache.c b/src/pcache.c index 52661c28a9..561672b9ce 100644 --- a/src/pcache.c +++ b/src/pcache.c @@ -686,6 +686,17 @@ void sqlite3PcacheShrink(PCache *pCache){ */ int sqlite3HeaderSizePcache(void){ return ROUND8(sizeof(PgHdr)); } +/* +** Return the number of dirty pages currently in the cache, as a percentage +** of the configured cache size. +*/ +int sqlite3PCachePercentDirty(PCache *pCache){ + PgHdr *pDirty; + int nDirty = 0; + int nCache = numberOfCachePages(pCache); + for(pDirty=pCache->pDirty; pDirty; pDirty=pDirty->pDirtyNext) nDirty++; + return (int)(((i64)nDirty * 100) / nCache); +} #if defined(SQLITE_CHECK_PAGES) || defined(SQLITE_DEBUG) /* diff --git a/src/pcache.h b/src/pcache.h index 475c04c061..0caf605ff8 100644 --- a/src/pcache.h +++ b/src/pcache.h @@ -173,4 +173,7 @@ void sqlite3PCacheSetDefault(void); int sqlite3HeaderSizePcache(void); int sqlite3HeaderSizePcache1(void); +/* Number of dirty pages as a percentage of the configured cache size */ +int sqlite3PCachePercentDirty(PCache*); + #endif /* _PCACHE_H_ */ From 07d683fdbc186871f4e8f1f261cbfa7738d5d40b Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 13 Apr 2016 21:00:36 +0000 Subject: [PATCH 0303/1484] Fix compiler warnings by removing surplus local variables in the schema pretty-printer logic of the command-line shell. FossilOrigin-Name: 55a62483b9121a8b373d038a26fdebc4308661f6 --- manifest | 13 ++++++------- manifest.uuid | 2 +- src/shell.c | 5 ++--- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 967ecce51b..9904526253 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fixes\sfor\sharmless\scompiler\swarnings. -D 2016-04-13T15:52:16.297 +C Fix\scompiler\swarnings\sby\sremoving\ssurplus\slocal\svariables\sin\sthe\sschema\npretty-printer\slogic\sof\sthe\scommand-line\sshell. +D 2016-04-13T21:00:36.984 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -376,7 +376,7 @@ F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c b8f7174e5f8c33c44ded3a25a973d0bb89228c20 F src/rowset.c 9fe4b3ad7cc00944386bb600233d8f523de07a6e F src/select.c a07e6022e2b559f3c2ec80442472c5965fa7a3fc -F src/shell.c aeaab68456010319cb71406cbaca05865b295154 +F src/shell.c ebcdf99f3e7c7409bd463eae443f1bd01e3e2d02 F src/sqlite.h.in 64eb70a3b309751bebf73a5552a51244f68f0ea5 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 98f72cbfe00169c39089115427d06ea05fe4b4a2 @@ -1482,8 +1482,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 83cfe82cd6d31ec0a6193525fd92e63a2a43b142 929fa4c31e7c5b8c6cbb1412478ea91b15ad5529 -R 7c661a721c213e6ed7f2c57fe9448b49 -T +closed 929fa4c31e7c5b8c6cbb1412478ea91b15ad5529 +P 68142dc541b7a0a36fcb075a26f10f03c1e7c422 +R df66fcce8d8333da43cbdaefe267859a U drh -Z 9101c9e33a00c3414d9af87354786d43 +Z 3bcaedd99c30eef242301f45d5550540 diff --git a/manifest.uuid b/manifest.uuid index 420021215e..c1466783ea 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -68142dc541b7a0a36fcb075a26f10f03c1e7c422 \ No newline at end of file +55a62483b9121a8b373d038a26fdebc4308661f6 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 33010e5ff1..4744b91ddd 100644 --- a/src/shell.c +++ b/src/shell.c @@ -1062,7 +1062,7 @@ static int shell_callback( } case MODE_Pretty: { /* .schema and .fullschema with --indent */ char *z; - int i,j; + int j; int nParen = 0; char cEnd = 0; char c; @@ -1089,8 +1089,7 @@ static int shell_callback( while( j>0 && IsSpace(z[j-1]) ){ j--; } z[j] = 0; if( strlen30(z)>=79 ){ - for(i=j=0; z[i]; i++){ - char c = z[i]; + for(i=j=0; (c = z[i])!=0; i++){ if( c==cEnd ){ cEnd = 0; }else if( c=='"' || c=='\'' || c=='`' ){ From 7512cb47e893fc436f1362b266c07452a933a2f4 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 14 Apr 2016 13:06:49 +0000 Subject: [PATCH 0304/1484] Additional ".selecttrace" debugging output when the query is transformed from a DISTINCT into a GROUP BY. FossilOrigin-Name: 5a46914510af4d5557b299db65c68d5df1070766 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/select.c | 7 +++++++ 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 9904526253..777999ecae 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\scompiler\swarnings\sby\sremoving\ssurplus\slocal\svariables\sin\sthe\sschema\npretty-printer\slogic\sof\sthe\scommand-line\sshell. -D 2016-04-13T21:00:36.984 +C Additional\s".selecttrace"\sdebugging\soutput\swhen\sthe\squery\sis\stransformed\sfrom\sa\nDISTINCT\sinto\sa\sGROUP\sBY. +D 2016-04-14T13:06:49.646 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -375,7 +375,7 @@ F src/printf.c 63e6fb12bbe702dd664dc3703776c090383a5a26 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c b8f7174e5f8c33c44ded3a25a973d0bb89228c20 F src/rowset.c 9fe4b3ad7cc00944386bb600233d8f523de07a6e -F src/select.c a07e6022e2b559f3c2ec80442472c5965fa7a3fc +F src/select.c 6c7f3cf68af334ed1ec40c20b5cff9b1e632d824 F src/shell.c ebcdf99f3e7c7409bd463eae443f1bd01e3e2d02 F src/sqlite.h.in 64eb70a3b309751bebf73a5552a51244f68f0ea5 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1482,7 +1482,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 68142dc541b7a0a36fcb075a26f10f03c1e7c422 -R df66fcce8d8333da43cbdaefe267859a +P 55a62483b9121a8b373d038a26fdebc4308661f6 +R 7bb58a4f89e336cb6f9f8cccdaf5c333 U drh -Z 3bcaedd99c30eef242301f45d5550540 +Z 71b74109092a6d83b57a993cec7348f7 diff --git a/manifest.uuid b/manifest.uuid index c1466783ea..d8e9822a3a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -55a62483b9121a8b373d038a26fdebc4308661f6 \ No newline at end of file +5a46914510af4d5557b299db65c68d5df1070766 \ No newline at end of file diff --git a/src/select.c b/src/select.c index fc37db5747..e8de015cfe 100644 --- a/src/select.c +++ b/src/select.c @@ -5092,6 +5092,13 @@ int sqlite3Select( ** the sDistinct.isTnct is still set. Hence, isTnct represents the ** original setting of the SF_Distinct flag, not the current setting */ assert( sDistinct.isTnct ); + +#if SELECTTRACE_ENABLED + if( sqlite3SelectTrace & 0x400 ){ + SELECTTRACE(0x400,pParse,p,("Transform DISTINCT into GROUP BY:\n")); + sqlite3TreeViewSelect(0, p, 0); + } +#endif } /* If there is an ORDER BY clause, then create an ephemeral index to From 8f2ce914622ab58761c351bc073d21109ef3ded7 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 14 Apr 2016 13:16:58 +0000 Subject: [PATCH 0305/1484] Since the return value of sqlite3OsClose() is always ignored, we might as well make it "void" instead of "int", and thereby save 50 bytes in the compiled binary. FossilOrigin-Name: 7ee570e7a9a2159a8c0d41805c00f91ca0de00e3 --- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- src/os.c | 12 ++++-------- src/os.h | 4 ++-- src/test_devsym.c | 3 ++- src/test_journal.c | 3 ++- src/test_vfs.c | 5 ++--- 7 files changed, 23 insertions(+), 26 deletions(-) diff --git a/manifest b/manifest index 777999ecae..90094afc23 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Additional\s".selecttrace"\sdebugging\soutput\swhen\sthe\squery\sis\stransformed\sfrom\sa\nDISTINCT\sinto\sa\sGROUP\sBY. -D 2016-04-14T13:06:49.646 +C Since\sthe\sreturn\svalue\sof\ssqlite3OsClose()\sis\salways\signored,\swe\smight\sas\nwell\smake\sit\s"void"\sinstead\sof\s"int",\sand\sthereby\ssave\s50\sbytes\sin\sthe\ncompiled\sbinary. +D 2016-04-14T13:16:58.757 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -355,8 +355,8 @@ F src/mutex_noop.c 9d4309c075ba9cc7249e19412d3d62f7f94839c4 F src/mutex_unix.c 27bb6cc49485ee46711a6580ab7b3f1402211d23 F src/mutex_w32.c 5e6fe1c298fb5a8a15aaed4161d5759311431c17 F src/notify.c 9711a7575036f0d3040ba61bc6e217f13a9888e7 -F src/os.c ca10edb445ad2c5fdc7285b49d72bcdf261fa23e -F src/os.h 91ff889115ecd01f436d3611f7f5ea4dc12d92f1 +F src/os.c 4d83917f072ad958fba9235136fa2ed43df47905 +F src/os.h 8e976e59eb4ca1c0fca6d35ee803e38951cb0343 F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85 F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa F src/os_unix.c bde4844f0849cab5924c6a81178f8500774ce76b @@ -402,14 +402,14 @@ F src/test_blob.c b2551a9b5573232db5f66f292307c37067937239 F src/test_btree.c 2e9978eca99a9a4bfa8cae949efb00886860a64f F src/test_config.c 7003f6f35134de6f19c6588f44783e43390ea277 F src/test_demovfs.c 0de72c2c89551629f58486fde5734b7d90758852 -F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc +F src/test_devsym.c 7e73009d5297b603c11c66d7c7d6723d4b5c73e1 F src/test_fs.c f10f840ca4f8c72e4837908bd8347ac4bcab074b F src/test_func.c 37453d346cfcf118774efd5bf6187f7e6a7e3254 F src/test_hexio.c abfdecb6fa58c354623978efceb088ca18e379cd F src/test_init.c 66b33120ffe9cd853b5a905ec850d51151337b32 F src/test_intarray.c 870124b95ec4c645d4eb84f15efb7133528fb1a5 F src/test_intarray.h 9dc57417fb65bc7835cc18548852cc08cc062202 -F src/test_journal.c 5360fbe1d1e4416ca36290562fd5a2e3f70f32aa +F src/test_journal.c da540964c675fde39487da2bc664096af97190d8 F src/test_loadext.c 337056bae59f80b9eb00ba82088b39d0f4fe6dfd F src/test_malloc.c 94c18e88d6df6d471a0d04ddb809f833d1739950 F src/test_multiplex.c eafc567ebe162e36f17b5062285dfe90461cf8e9 @@ -428,7 +428,7 @@ F src/test_superlock.c 06797157176eb7085027d9dd278c0d7a105e3ec9 F src/test_syscall.c 2e21ca7f7dc54a028f1967b63f1e76155c356f9b F src/test_tclvar.c d86412527da65468ee6fa1b8607c65d0af736bc4 F src/test_thread.c af391ec03d23486dffbcc250b7e58e073f172af9 -F src/test_vfs.c 3b65d42e18b262805716bd96178c81da8f2d9283 +F src/test_vfs.c 4d02f38bfb8f7f273da7ba84bfe000f5babf206c F src/test_vfstrace.c bab9594adc976cbe696ff3970728830b4c5ed698 F src/test_windirent.c 8f5fada630348558d5745b334702f301da1ffc61 F src/test_windirent.h b12055cab6227f7be10f5c19296f67c60cc5e2a5 @@ -1482,7 +1482,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 55a62483b9121a8b373d038a26fdebc4308661f6 -R 7bb58a4f89e336cb6f9f8cccdaf5c333 +P 5a46914510af4d5557b299db65c68d5df1070766 +R c53fd5d7b34fa75485d686014ecb828c U drh -Z 71b74109092a6d83b57a993cec7348f7 +Z 23b6889e197e2a1c3244550aa7848950 diff --git a/manifest.uuid b/manifest.uuid index d8e9822a3a..e1a2ebd0aa 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5a46914510af4d5557b299db65c68d5df1070766 \ No newline at end of file +7ee570e7a9a2159a8c0d41805c00f91ca0de00e3 \ No newline at end of file diff --git a/src/os.c b/src/os.c index bfcc9cdd05..6138bf4f3f 100644 --- a/src/os.c +++ b/src/os.c @@ -81,13 +81,11 @@ int sqlite3_memdebug_vfs_oom_test = 1; ** of this would be completely automatic if SQLite were coded using ** C++ instead of plain old C. */ -int sqlite3OsClose(sqlite3_file *pId){ - int rc = SQLITE_OK; +void sqlite3OsClose(sqlite3_file *pId){ if( pId->pMethods ){ - rc = pId->pMethods->xClose(pId); + pId->pMethods->xClose(pId); pId->pMethods = 0; } - return rc; } int sqlite3OsRead(sqlite3_file *id, void *pBuf, int amt, i64 offset){ DO_OS_MALLOC_TEST(id); @@ -305,12 +303,10 @@ int sqlite3OsOpenMalloc( } return rc; } -int sqlite3OsCloseFree(sqlite3_file *pFile){ - int rc = SQLITE_OK; +void sqlite3OsCloseFree(sqlite3_file *pFile){ assert( pFile ); - rc = sqlite3OsClose(pFile); + sqlite3OsClose(pFile); sqlite3_free(pFile); - return rc; } /* diff --git a/src/os.h b/src/os.h index f813541561..947f88b36e 100644 --- a/src/os.h +++ b/src/os.h @@ -160,7 +160,7 @@ int sqlite3OsInit(void); /* ** Functions for accessing sqlite3_file methods */ -int sqlite3OsClose(sqlite3_file*); +void sqlite3OsClose(sqlite3_file*); int sqlite3OsRead(sqlite3_file*, void*, int amt, i64 offset); int sqlite3OsWrite(sqlite3_file*, const void*, int amt, i64 offset); int sqlite3OsTruncate(sqlite3_file*, i64 size); @@ -205,6 +205,6 @@ int sqlite3OsCurrentTimeInt64(sqlite3_vfs *, sqlite3_int64*); ** sqlite3_malloc() to obtain space for the file-handle structure. */ int sqlite3OsOpenMalloc(sqlite3_vfs *, const char *, sqlite3_file **, int,int*); -int sqlite3OsCloseFree(sqlite3_file *); +void sqlite3OsCloseFree(sqlite3_file *); #endif /* _SQLITE_OS_H_ */ diff --git a/src/test_devsym.c b/src/test_devsym.c index 21f0f684d8..5fd0935846 100644 --- a/src/test_devsym.c +++ b/src/test_devsym.c @@ -133,7 +133,8 @@ struct DevsymGlobal g = {0, 0, 512}; */ static int devsymClose(sqlite3_file *pFile){ devsym_file *p = (devsym_file *)pFile; - return sqlite3OsClose(p->pReal); + sqlite3OsClose(p->pReal); + return SQLITE_OK; } /* diff --git a/src/test_journal.c b/src/test_journal.c index 6e320b7abb..84c80546a6 100644 --- a/src/test_journal.c +++ b/src/test_journal.c @@ -256,7 +256,8 @@ static int jtClose(sqlite3_file *pFile){ *pp = p->pNext; } leaveJtMutex(); - return sqlite3OsClose(p->pReal); + sqlite3OsClose(p->pReal); + return SQLITE_OK; } /* diff --git a/src/test_vfs.c b/src/test_vfs.c index a8c6ae7bf5..b476a42cb4 100644 --- a/src/test_vfs.c +++ b/src/test_vfs.c @@ -306,7 +306,6 @@ static void tvfsExecTcl( ** Close an tvfs-file. */ static int tvfsClose(sqlite3_file *pFile){ - int rc; TestvfsFile *pTestfile = (TestvfsFile *)pFile; TestvfsFd *pFd = pTestfile->pFd; Testvfs *p = (Testvfs *)pFd->pVfs->pAppData; @@ -324,10 +323,10 @@ static int tvfsClose(sqlite3_file *pFile){ if( pFile->pMethods ){ ckfree((char *)pFile->pMethods); } - rc = sqlite3OsClose(pFd->pReal); + sqlite3OsClose(pFd->pReal); ckfree((char *)pFd); pTestfile->pFd = 0; - return rc; + return SQLITE_OK; } /* From f1b5ff73cb72b9d0b3f95b810c8bc809348ab8c0 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 14 Apr 2016 13:35:26 +0000 Subject: [PATCH 0306/1484] Rename WhereInfo.pResultSet to pDistinctSet to more accurately reflect what it represents. FossilOrigin-Name: 5317961411695e107e8cefdeaba62280429979ca --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/where.c | 30 +++++++++++++++--------------- src/whereInt.h | 2 +- 4 files changed, 24 insertions(+), 24 deletions(-) diff --git a/manifest b/manifest index 90094afc23..46ad911995 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Since\sthe\sreturn\svalue\sof\ssqlite3OsClose()\sis\salways\signored,\swe\smight\sas\nwell\smake\sit\s"void"\sinstead\sof\s"int",\sand\sthereby\ssave\s50\sbytes\sin\sthe\ncompiled\sbinary. -D 2016-04-14T13:16:58.757 +C Rename\sWhereInfo.pResultSet\sto\spDistinctSet\sto\smore\saccurately\sreflect\swhat\nit\srepresents. +D 2016-04-14T13:35:26.807 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -455,8 +455,8 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 4db22ed7e77bcf672b1a685d6ddeffba8d5be302 F src/wal.h 2f7c831cf3b071fa548bf2d5cac640846a7ff19c F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354 -F src/where.c 24ab561466d92d313747c04edb1a36a7af8663be -F src/whereInt.h 93297d56edd137b7ea004490690fb6e2ce028a34 +F src/where.c bae50f2f18f9e8584549a77363858623b07e4915 +F src/whereInt.h 43466b107862e348e5c2a709cc4812a611e27908 F src/wherecode.c 8fdad9fbba723df1c1e8d07e7ea8507572040340 F src/whereexpr.c eacc0e60d029a082b4fc0cc42ea98544add1319e F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 @@ -1482,7 +1482,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 5a46914510af4d5557b299db65c68d5df1070766 -R c53fd5d7b34fa75485d686014ecb828c +P 7ee570e7a9a2159a8c0d41805c00f91ca0de00e3 +R ba684bc23f92ec8865bd177b82e2674c U drh -Z 23b6889e197e2a1c3244550aa7848950 +Z 37e357b73543209990ea5ecc9fc91d8e diff --git a/manifest.uuid b/manifest.uuid index e1a2ebd0aa..1f848b4578 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7ee570e7a9a2159a8c0d41805c00f91ca0de00e3 \ No newline at end of file +5317961411695e107e8cefdeaba62280429979ca \ No newline at end of file diff --git a/src/where.c b/src/where.c index b33e062a6d..ca810a3b16 100644 --- a/src/where.c +++ b/src/where.c @@ -3881,9 +3881,9 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ && nRowEst ){ Bitmask notUsed; - int rc = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pResultSet, pFrom, + int rc = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pDistinctSet, pFrom, WHERE_DISTINCTBY, nLoop-1, pFrom->aLoop[nLoop-1], ¬Used); - if( rc==pWInfo->pResultSet->nExpr ){ + if( rc==pWInfo->pDistinctSet->nExpr ){ pWInfo->eDistinct = WHERE_DISTINCT_ORDERED; } } @@ -4098,14 +4098,14 @@ static int whereShortCut(WhereLoopBuilder *pBuilder){ ** used. */ WhereInfo *sqlite3WhereBegin( - Parse *pParse, /* The parser context */ - SrcList *pTabList, /* FROM clause: A list of all tables to be scanned */ - Expr *pWhere, /* The WHERE clause */ - ExprList *pOrderBy, /* An ORDER BY (or GROUP BY) clause, or NULL */ - ExprList *pResultSet, /* Result set of the query */ - u16 wctrlFlags, /* One of the WHERE_* flags defined in sqliteInt.h */ - int iAuxArg /* If WHERE_ONETABLE_ONLY is set, index cursor number, - ** If WHERE_USE_LIMIT, then the limit amount */ + Parse *pParse, /* The parser context */ + SrcList *pTabList, /* FROM clause: A list of all tables to be scanned */ + Expr *pWhere, /* The WHERE clause */ + ExprList *pOrderBy, /* An ORDER BY (or GROUP BY) clause, or NULL */ + ExprList *pDistinctSet, /* Try not to output two rows that duplicate these */ + u16 wctrlFlags, /* The WHERE_* flags defined in sqliteInt.h */ + int iAuxArg /* If WHERE_ONETABLE_ONLY is set, index cursor number + ** If WHERE_USE_LIMIT, then the limit amount */ ){ int nByteWInfo; /* Num. bytes allocated for WhereInfo struct */ int nTabList; /* Number of elements in pTabList */ @@ -4180,7 +4180,7 @@ WhereInfo *sqlite3WhereBegin( pWInfo->pParse = pParse; pWInfo->pTabList = pTabList; pWInfo->pOrderBy = pOrderBy; - pWInfo->pResultSet = pResultSet; + pWInfo->pDistinctSet = pDistinctSet; pWInfo->iBreak = pWInfo->iContinue = sqlite3VdbeMakeLabel(v); pWInfo->wctrlFlags = wctrlFlags; pWInfo->iLimit = iAuxArg; @@ -4253,13 +4253,13 @@ WhereInfo *sqlite3WhereBegin( if( db->mallocFailed ) goto whereBeginError; if( wctrlFlags & WHERE_WANT_DISTINCT ){ - if( isDistinctRedundant(pParse, pTabList, &pWInfo->sWC, pResultSet) ){ + if( isDistinctRedundant(pParse, pTabList, &pWInfo->sWC, pDistinctSet) ){ /* The DISTINCT marking is pointless. Ignore it. */ pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE; }else if( pOrderBy==0 ){ /* Try to ORDER BY the result set to make distinct processing easier */ pWInfo->wctrlFlags |= WHERE_DISTINCTBY; - pWInfo->pOrderBy = pResultSet; + pWInfo->pOrderBy = pDistinctSet; } } @@ -4338,10 +4338,10 @@ WhereInfo *sqlite3WhereBegin( #endif /* Attempt to omit tables from the join that do not effect the result */ if( pWInfo->nLevel>=2 - && pResultSet!=0 + && pDistinctSet!=0 && OptimizationEnabled(db, SQLITE_OmitNoopJoin) ){ - Bitmask tabUsed = sqlite3WhereExprListUsage(pMaskSet, pResultSet); + Bitmask tabUsed = sqlite3WhereExprListUsage(pMaskSet, pDistinctSet); if( sWLB.pOrderBy ){ tabUsed |= sqlite3WhereExprListUsage(pMaskSet, sWLB.pOrderBy); } diff --git a/src/whereInt.h b/src/whereInt.h index eb6ca326f5..ec12b6112f 100644 --- a/src/whereInt.h +++ b/src/whereInt.h @@ -408,7 +408,7 @@ struct WhereInfo { Parse *pParse; /* Parsing and code generating context */ SrcList *pTabList; /* List of tables in the join */ ExprList *pOrderBy; /* The ORDER BY clause or NULL */ - ExprList *pResultSet; /* Result set. DISTINCT operates on these */ + ExprList *pDistinctSet; /* DISTINCT over all these values */ WhereLoop *pLoops; /* List of all WhereLoop objects */ Bitmask revMask; /* Mask of ORDER BY terms that need reversing */ LogEst nRowOut; /* Estimated number of output rows */ From 7111c93c408c6c927a4b632c5a6d2eb856a93fbe Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 14 Apr 2016 15:38:33 +0000 Subject: [PATCH 0307/1484] Add some missing testcase() macros to the pushDownWhereTerms() routine. FossilOrigin-Name: 67d7f79c5e5be41a18817c802b5c4d349e3a83a4 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/select.c | 2 ++ 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 46ad911995..ea92438304 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Rename\sWhereInfo.pResultSet\sto\spDistinctSet\sto\smore\saccurately\sreflect\swhat\nit\srepresents. -D 2016-04-14T13:35:26.807 +C Add\ssome\smissing\stestcase()\smacros\sto\sthe\spushDownWhereTerms()\sroutine. +D 2016-04-14T15:38:33.232 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -375,7 +375,7 @@ F src/printf.c 63e6fb12bbe702dd664dc3703776c090383a5a26 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c b8f7174e5f8c33c44ded3a25a973d0bb89228c20 F src/rowset.c 9fe4b3ad7cc00944386bb600233d8f523de07a6e -F src/select.c 6c7f3cf68af334ed1ec40c20b5cff9b1e632d824 +F src/select.c 30217121bdf6b587462150b8ee9e1467f7a6036b F src/shell.c ebcdf99f3e7c7409bd463eae443f1bd01e3e2d02 F src/sqlite.h.in 64eb70a3b309751bebf73a5552a51244f68f0ea5 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1482,7 +1482,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 7ee570e7a9a2159a8c0d41805c00f91ca0de00e3 -R ba684bc23f92ec8865bd177b82e2674c +P 5317961411695e107e8cefdeaba62280429979ca +R 57400ecb51ad9ca239da236d61c38933 U drh -Z 37e357b73543209990ea5ecc9fc91d8e +Z b18926ac3da54e5d3b9c23fea213722b diff --git a/manifest.uuid b/manifest.uuid index 1f848b4578..c63227e9a1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5317961411695e107e8cefdeaba62280429979ca \ No newline at end of file +67d7f79c5e5be41a18817c802b5c4d349e3a83a4 \ No newline at end of file diff --git a/src/select.c b/src/select.c index e8de015cfe..b86e040f0f 100644 --- a/src/select.c +++ b/src/select.c @@ -3787,6 +3787,8 @@ static int pushDownWhereTerms( int nChng = 0; if( pWhere==0 ) return 0; if( (pSubq->selFlags & (SF_Aggregate|SF_Recursive))!=0 ){ + testcase( pSubq->selFlags & SF_Aggregate ); + testcase( pSubq->selFlags & SF_Recursive ); return 0; /* restrictions (1) and (2) */ } if( pSubq->pLimit!=0 ){ From fc26f7cfed8e8f3bd54072ced115f9ec1a1542b9 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 14 Apr 2016 15:44:37 +0000 Subject: [PATCH 0308/1484] Correctly interpret negative "PRAGMA cache_size" values when determining the cache-size used for sorting large amounts of data (i.e. the functionality in vdbesort.c). FossilOrigin-Name: 79147dca87cfd7eb62d57baa3b70fa2a8542232a --- manifest | 16 +++++------ manifest.uuid | 2 +- src/vdbesort.c | 14 +++++++--- test/sort5.test | 72 +++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 92 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index ea92438304..b15a6315b8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\ssome\smissing\stestcase()\smacros\sto\sthe\spushDownWhereTerms()\sroutine. -D 2016-04-14T15:38:33.232 +C Correctly\sinterpret\snegative\s"PRAGMA\scache_size"\svalues\swhen\sdetermining\sthe\scache-size\sused\sfor\ssorting\slarge\samounts\sof\sdata\s(i.e.\sthe\sfunctionality\sin\svdbesort.c). +D 2016-04-14T15:44:37.886 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -448,7 +448,7 @@ F src/vdbeapi.c ba85b78fe08dc4a9ce747e62c89a2b4a4547e74c F src/vdbeaux.c ace1875da40b7185e604586768d5ac90de7e4f7f F src/vdbeblob.c c9f2f494b911c6fa34efd9803f0a10807da80f77 F src/vdbemem.c 5cfef60e60e19cab6275d1b975bf4c791d575beb -F src/vdbesort.c 307460bfa4de4d1c3901fcd42089159131e34062 +F src/vdbesort.c 0a8f98366ae794442e6d1ef71d9553226d885d19 F src/vdbetrace.c f75c5455d8cf389ef86a8bfdfd3177e0e3692484 F src/vtab.c 23b6cdfa996152d43b390504ed4a942c8caf3a00 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 @@ -1073,7 +1073,7 @@ F test/sort.test c2adc635c2564241fefec0b3a68391ef6868fd3b F test/sort2.test cc23b7c19d684657559e8a55b02f7fcee03851d0 F test/sort3.test 1480ed7c4c157682542224e05e3b75faf4a149e5 F test/sort4.test 5c34d9623a4ae5921d956dfa2b70e77ed0fc6e5c -F test/sort5.test d3041ce3c475aa04142a959ae56ef6593f98a99f +F test/sort5.test e47ec7a490b9b36787755874175d8f413a3883d9 F test/sortfault.test d4ccf606a0c77498e2beb542764fd9394acb4d66 F test/speed1.test f2974a91d79f58507ada01864c0e323093065452 F test/speed1p.explain d841e650a04728b39e6740296b852dccdca9b2cb @@ -1482,7 +1482,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 5317961411695e107e8cefdeaba62280429979ca -R 57400ecb51ad9ca239da236d61c38933 -U drh -Z b18926ac3da54e5d3b9c23fea213722b +P 67d7f79c5e5be41a18817c802b5c4d349e3a83a4 +R 7d2f177c9a481d6a3916beb1fe8bc290 +U dan +Z 2305c008703672127d77c74ca18473e8 diff --git a/manifest.uuid b/manifest.uuid index c63227e9a1..b120cf6dd2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -67d7f79c5e5be41a18817c802b5c4d349e3a83a4 \ No newline at end of file +79147dca87cfd7eb62d57baa3b70fa2a8542232a \ No newline at end of file diff --git a/src/vdbesort.c b/src/vdbesort.c index 5913cda6d0..7d5146cf0b 100644 --- a/src/vdbesort.c +++ b/src/vdbesort.c @@ -931,7 +931,6 @@ int sqlite3VdbeSorterInit( ){ int pgsz; /* Page size of main database */ int i; /* Used to iterate through aTask[] */ - int mxCache; /* Cache size */ VdbeSorter *pSorter; /* The new sorter */ KeyInfo *pKeyInfo; /* Copy of pCsr->pKeyInfo with db==0 */ int szKeyInfo; /* Size of pCsr->pKeyInfo in bytes */ @@ -988,11 +987,20 @@ int sqlite3VdbeSorterInit( } if( !sqlite3TempInMemory(db) ){ + i64 mxCache; /* Cache size in bytes*/ u32 szPma = sqlite3GlobalConfig.szPma; pSorter->mnPmaSize = szPma * pgsz; + mxCache = db->aDb[0].pSchema->cache_size; - if( mxCache<(int)szPma ) mxCache = (int)szPma; - pSorter->mxPmaSize = MIN((i64)mxCache*pgsz, SQLITE_MAX_PMASZ); + if( mxCache<0 ){ + /* A negative cache-size value C indicates that the cache is abs(C) + ** KiB in size. */ + mxCache = mxCache * -1024; + }else{ + mxCache = mxCache * pgsz; + } + mxCache = MIN(mxCache, SQLITE_MAX_PMASZ); + pSorter->mxPmaSize = MAX(pSorter->mnPmaSize, (int)mxCache); /* EVIDENCE-OF: R-26747-61719 When the application provides any amount of ** scratch memory using SQLITE_CONFIG_SCRATCH, SQLite avoids unnecessary diff --git a/test/sort5.test b/test/sort5.test index 5b1292bb48..9fb2dff281 100644 --- a/test/sort5.test +++ b/test/sort5.test @@ -41,4 +41,76 @@ do_execsql_test 1.2 { db close tvfs delete + +#------------------------------------------------------------------------- +# Test that the PMA size is determined correctly. The PMA size should be +# roughly the same amount of memory allocated to the main pager cache, or +# 250 pages if this is larger. +# +testvfs tvfs +tvfs script tv_callback +tvfs filter {xOpen xWrite} + +proc tv_callback {method args} { + global iTemp + global F + switch $method { + xOpen { + if {[lindex $args 0]==""} { return "temp[incr iTemp]" } + return "SQLITE_OK" + } + + xWrite { + foreach {filename id off amt} $args {} + if {[info exists F($id)]==0 || $F($id)<($off + $amt)} { + set F($id) [expr $off+$amt] + } + } + } +} + +catch { db close } +forcedelete test.db +sqlite3 db test.db -vfs tvfs +execsql { CREATE TABLE t1(x) } + +# Each iteration of the following loop attempts to sort 10001 records +# each a bit over 100 bytes in size. In total a little more than 1MiB +# of data. +# +breakpoint +foreach {tn pgsz cachesz bTemp} { + 2 1024 1000 1 + + 1 4096 1000 0 + 2 1024 1000 1 + + 3 4096 -1000 1 + 4 1024 -1000 1 + + 5 4096 -9000 0 + 6 1024 -9000 0 +} { + do_execsql_test 2.$tn.0 " + PRAGMA page_size = $pgsz; + VACUUM; + PRAGMA cache_size = $cachesz; + " + + do_test 2.$tn.1 { + set ::iTemp 0 + catch { array unset F } + execsql { + WITH x(i, j) AS ( + SELECT 1, randomblob(100) + UNION ALL + SELECT i+1, randomblob(100) FROM x WHERE i<10000 + ) + SELECT * FROM x ORDER BY j; + } + expr {[array names F]!=""} + } $bTemp +} + finish_test + From 497116007e3aa0ab2b01fc3bb616a4cad4114829 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 14 Apr 2016 16:40:13 +0000 Subject: [PATCH 0309/1484] Add the SF_HasAgg constant (currently unused). Also enhance the comments on many other constant definitions to detail constraints on their values. FossilOrigin-Name: 7b7a69d098f7581a43b818c251717c2450b797de --- manifest | 18 +++++++-------- manifest.uuid | 2 +- src/pager.h | 11 ++++++++- src/sqliteInt.h | 61 +++++++++++++++++++++++++++++++++++++------------ src/whereInt.h | 8 +++++++ 5 files changed, 74 insertions(+), 26 deletions(-) diff --git a/manifest b/manifest index b15a6315b8..420dfe28cf 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Correctly\sinterpret\snegative\s"PRAGMA\scache_size"\svalues\swhen\sdetermining\sthe\scache-size\sused\sfor\ssorting\slarge\samounts\sof\sdata\s(i.e.\sthe\sfunctionality\sin\svdbesort.c). -D 2016-04-14T15:44:37.886 +C Add\sthe\sSF_HasAgg\sconstant\s(currently\sunused).\s\sAlso\senhance\sthe\scomments\son\nmany\sother\sconstant\sdefinitions\sto\sdetail\sconstraints\son\stheir\svalues. +D 2016-04-14T16:40:13.322 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -363,7 +363,7 @@ F src/os_unix.c bde4844f0849cab5924c6a81178f8500774ce76b F src/os_win.c b169437dff859e308b3726594094a2f8ca922941 F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c 38718a019ca762ba4f6795425d5a54db70d1790d -F src/pager.h e1d38a2f14849e219df0f91f8323504d134c8a56 +F src/pager.h 329bdf078a4e0a3b35084534d58625d21fd03681 F src/parse.y 10eb2f3fb62341291528c7984498054731f9d31e F src/pcache.c 647bb53a86b7bbcf55ad88089b3ea5a9170b90df F src/pcache.h 4d0ccaad264d360981ec5e6a2b596d6e85242545 @@ -380,7 +380,7 @@ F src/shell.c ebcdf99f3e7c7409bd463eae443f1bd01e3e2d02 F src/sqlite.h.in 64eb70a3b309751bebf73a5552a51244f68f0ea5 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 98f72cbfe00169c39089115427d06ea05fe4b4a2 -F src/sqliteInt.h b3744b29555b83054f315f62d61b3a6558fa9e1c +F src/sqliteInt.h 49cd2b5cd07cca7c462608540cb6dfa8ab03ba89 F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 @@ -456,7 +456,7 @@ F src/wal.c 4db22ed7e77bcf672b1a685d6ddeffba8d5be302 F src/wal.h 2f7c831cf3b071fa548bf2d5cac640846a7ff19c F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354 F src/where.c bae50f2f18f9e8584549a77363858623b07e4915 -F src/whereInt.h 43466b107862e348e5c2a709cc4812a611e27908 +F src/whereInt.h 7de94b751f088fe3fdc8cc04a491376f0900a059 F src/wherecode.c 8fdad9fbba723df1c1e8d07e7ea8507572040340 F src/whereexpr.c eacc0e60d029a082b4fc0cc42ea98544add1319e F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 @@ -1482,7 +1482,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 67d7f79c5e5be41a18817c802b5c4d349e3a83a4 -R 7d2f177c9a481d6a3916beb1fe8bc290 -U dan -Z 2305c008703672127d77c74ca18473e8 +P 79147dca87cfd7eb62d57baa3b70fa2a8542232a +R 6419c618333708e1ee248e43219e551e +U drh +Z 76d9f185ebd1be8244746d28959cec5d diff --git a/manifest.uuid b/manifest.uuid index b120cf6dd2..75ce1d9040 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -79147dca87cfd7eb62d57baa3b70fa2a8542232a \ No newline at end of file +7b7a69d098f7581a43b818c251717c2450b797de \ No newline at end of file diff --git a/src/pager.h b/src/pager.h index 38a4982150..077fcd8b7f 100644 --- a/src/pager.h +++ b/src/pager.h @@ -68,7 +68,11 @@ typedef struct PgHdr DbPage; #define PAGER_LOCKINGMODE_EXCLUSIVE 1 /* -** Numeric constants that encode the journalmode. +** Numeric constants that encode the journalmode. +** +** The numeric values encoded here (other than PAGER_JOURNALMODE_QUERY) +** are exposed in the API via the "PRAGMA journal_mode" command and +** therefore cannot be changed without a compatibility break. */ #define PAGER_JOURNALMODE_QUERY (-1) /* Query the value of journalmode */ #define PAGER_JOURNALMODE_DELETE 0 /* Commit by deleting journal file */ @@ -86,6 +90,11 @@ typedef struct PgHdr DbPage; /* ** Flags for sqlite3PagerSetFlags() +** +** Value constraints (enforced via assert()): +** PAGER_FULLFSYNC == SQLITE_FullFSync +** PAGER_CKPT_FULLFSYNC == SQLITE_CkptFullFSync +** PAGER_CACHE_SPILL == SQLITE_CacheSpill */ #define PAGER_SYNCHRONOUS_OFF 0x01 /* PRAGMA synchronous=OFF */ #define PAGER_SYNCHRONOUS_NORMAL 0x02 /* PRAGMA synchronous=NORMAL */ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index f9fab8e321..fe7203b8e1 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1350,6 +1350,11 @@ struct sqlite3 { /* ** Possible values for the sqlite3.flags. +** +** Value constraints (enforced via assert()): +** SQLITE_FullFSync == PAGER_FULLFSYNC +** SQLITE_CkptFullFSync == PAGER_CKPT_FULLFSYNC +** SQLITE_CacheSpill == PAGER_CACHE_SPILL */ #define SQLITE_VdbeTrace 0x00000001 /* True to trace VDBE execution */ #define SQLITE_InternChanges 0x00000002 /* Uncommitted Hash table changes */ @@ -1484,6 +1489,13 @@ struct FuncDestructor { ** values must correspond to OPFLAG_LENGTHARG and OPFLAG_TYPEOFARG. And ** SQLITE_FUNC_CONSTANT must be the same as SQLITE_DETERMINISTIC. There ** are assert() statements in the code to verify this. +** +** Value constraints (enforced via assert()): +** SQLITE_FUNC_MINMAX == NC_MinMaxAgg == SF_MinMaxAgg +** SQLITE_FUNC_LENGTH == OPFLAG_LENGTHARG +** SQLITE_FUNC_TYPEOF == OPFLAG_TYPEOFARG +** SQLITE_FUNC_CONSTANT == SQLITE_DETERMINISTIC from the API +** SQLITE_FUNC_ENCMASK depends on SQLITE_UTF* macros in the API */ #define SQLITE_FUNC_ENCMASK 0x0003 /* SQLITE_UTF8, SQLITE_UTF16BE or UTF16LE */ #define SQLITE_FUNC_LIKE 0x0004 /* Candidate for the LIKE optimization */ @@ -2483,6 +2495,9 @@ struct SrcList { /* ** Flags appropriate for the wctrlFlags parameter of sqlite3WhereBegin() ** and the WhereInfo.wctrlFlags member. +** +** Value constraints (enforced via assert()): +** WHERE_USE_LIMIT == SF_FixedLimit */ #define WHERE_ORDERBY_NORMAL 0x0000 /* No-op */ #define WHERE_ORDERBY_MIN 0x0001 /* ORDER BY processing for min() func */ @@ -2543,15 +2558,16 @@ struct NameContext { /* ** Allowed values for the NameContext, ncFlags field. ** -** Note: NC_MinMaxAgg must have the same value as SF_MinMaxAgg and -** SQLITE_FUNC_MINMAX. +** Value constraints (all checked via assert()): +** NC_HasAgg == SF_HasAgg +** NC_MinMaxAgg == SF_MinMaxAgg == SQLITE_FUNC_MINMAX ** */ #define NC_AllowAgg 0x0001 /* Aggregate functions are allowed here */ -#define NC_HasAgg 0x0002 /* One or more aggregate functions seen */ +#define NC_PartIdx 0x0002 /* True if resolving a partial index WHERE */ #define NC_IsCheck 0x0004 /* True if resolving names in a CHECK constraint */ #define NC_InAggFunc 0x0008 /* True if analyzing arguments to an agg func */ -#define NC_PartIdx 0x0010 /* True if resolving a partial index WHERE */ +#define NC_HasAgg 0x0010 /* One or more aggregate functions seen */ #define NC_IdxExpr 0x0020 /* True if resolving columns of CREATE INDEX */ #define NC_MinMaxAgg 0x1000 /* min/max aggregates seen. See note above */ @@ -2600,24 +2616,30 @@ struct Select { /* ** Allowed values for Select.selFlags. The "SF" prefix stands for ** "Select Flag". +** +** Value constraints (all checked via assert()) +** SF_HasAgg == NC_HasAgg +** SF_MinMaxAgg == NC_MinMaxAgg == SQLITE_FUNC_MINMAX +** SF_FixedLimit == WHERE_USE_LIMIT */ #define SF_Distinct 0x00001 /* Output should be DISTINCT */ #define SF_All 0x00002 /* Includes the ALL keyword */ #define SF_Resolved 0x00004 /* Identifiers have been resolved */ -#define SF_Aggregate 0x00008 /* Contains aggregate functions */ -#define SF_UsesEphemeral 0x00010 /* Uses the OpenEphemeral opcode */ -#define SF_Expanded 0x00020 /* sqlite3SelectExpand() called on this */ -#define SF_HasTypeInfo 0x00040 /* FROM subqueries have Table metadata */ -#define SF_Compound 0x00080 /* Part of a compound query */ -#define SF_Values 0x00100 /* Synthesized from VALUES clause */ -#define SF_MultiValue 0x00200 /* Single VALUES term with multiple rows */ -#define SF_NestedFrom 0x00400 /* Part of a parenthesized FROM clause */ -#define SF_MaybeConvert 0x00800 /* Need convertCompoundSelectToSubquery() */ +#define SF_Aggregate 0x00008 /* Contains agg functions or a GROUP BY */ +#define SF_HasAgg 0x00010 /* Contains aggregate functions */ +#define SF_UsesEphemeral 0x00020 /* Uses the OpenEphemeral opcode */ +#define SF_Expanded 0x00040 /* sqlite3SelectExpand() called on this */ +#define SF_HasTypeInfo 0x00080 /* FROM subqueries have Table metadata */ +#define SF_Compound 0x00100 /* Part of a compound query */ +#define SF_Values 0x00200 /* Synthesized from VALUES clause */ +#define SF_MultiValue 0x00400 /* Single VALUES term with multiple rows */ +#define SF_NestedFrom 0x00800 /* Part of a parenthesized FROM clause */ #define SF_MinMaxAgg 0x01000 /* Aggregate containing min() or max() */ #define SF_Recursive 0x02000 /* The recursive part of a recursive CTE */ #define SF_FixedLimit 0x04000 /* nSelectRow set by a constant LIMIT */ -#define SF_Converted 0x08000 /* By convertCompoundSelectToSubquery() */ -#define SF_IncludeHidden 0x10000 /* Include hidden columns in output */ +#define SF_MaybeConvert 0x08000 /* Need convertCompoundSelectToSubquery() */ +#define SF_Converted 0x10000 /* By convertCompoundSelectToSubquery() */ +#define SF_IncludeHidden 0x20000 /* Include hidden columns in output */ /* @@ -2928,6 +2950,15 @@ struct AuthContext { /* ** Bitfield flags for P5 value in various opcodes. +** +** Value constraints (enforced via assert()): +** OPFLAG_LENGTHARG == SQLITE_FUNC_LENGTH +** OPFLAG_TYPEOFARG == SQLITE_FUNC_TYPEOF +** OPFLAG_BULKCSR == BTREE_BULKLOAD +** OPFLAG_SEEKEQ == BTREE_SEEK_EQ +** OPFLAG_FORDELETE == BTREE_FORDELETE +** OPFLAG_SAVEPOSITION == BTREE_SAVEPOSITION +** OPFLAG_AUXDELETE == BTREE_AUXDELETE */ #define OPFLAG_NCHANGE 0x01 /* OP_Insert: Set to update db->nChange */ /* Also used in P2 (not P5) of OP_Delete */ diff --git a/src/whereInt.h b/src/whereInt.h index ec12b6112f..252905aa5a 100644 --- a/src/whereInt.h +++ b/src/whereInt.h @@ -492,6 +492,14 @@ void sqlite3WhereTabFuncArgs(Parse*, struct SrcList_item*, WhereClause*); ** operators that are of interest to the query planner. An ** OR-ed combination of these values can be used when searching for ** particular WhereTerms within a WhereClause. +** +** Value constraints: +** WO_EQ == SQLITE_INDEX_CONSTRAINT_EQ +** WO_LT == SQLITE_INDEX_CONSTRAINT_LT +** WO_LE == SQLITE_INDEX_CONSTRAINT_LE +** WO_GT == SQLITE_INDEX_CONSTRAINT_GT +** WO_GE == SQLITE_INDEX_CONSTRAINT_GE +** WO_MATCH == SQLITE_INDEX_CONSTRAINT_MATCH */ #define WO_IN 0x0001 #define WO_EQ 0x0002 From 5313f2e12eee0e0f9a234ef644eb6253d38429ba Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 14 Apr 2016 17:29:13 +0000 Subject: [PATCH 0310/1484] In the ICU extension toupper() and tolower() SQL functions, avoid calling u_strToUpper() or u_strToLower() a second time if the buffer passed to the first invocation turns out to be large enough. FossilOrigin-Name: d23e581351fb8eea28e7b13b3dcadfc817c3a05f --- ext/icu/icu.c | 28 +++++++++++++++++----------- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 25 insertions(+), 19 deletions(-) diff --git a/ext/icu/icu.c b/ext/icu/icu.c index 3f45646194..4d19dfbd62 100644 --- a/ext/icu/icu.c +++ b/ext/icu/icu.c @@ -354,15 +354,17 @@ static void icuRegexpFunc(sqlite3_context *p, int nArg, sqlite3_value **apArg){ ** http://www.icu-project.org/userguide/posix.html#case_mappings */ static void icuCaseFunc16(sqlite3_context *p, int nArg, sqlite3_value **apArg){ - const UChar *zInput; - UChar *zOutput = 0; - int nInput; - int nOut; + const UChar *zInput; /* Pointer to input string */ + UChar *zOutput = 0; /* Pointer to output buffer */ + int nInput; /* Size of utf-16 input string in bytes */ + int nOut; /* Size of output buffer in bytes */ int cnt; + int bToUpper; /* True for toupper(), false for tolower() */ UErrorCode status; const char *zLocale = 0; assert(nArg==1 || nArg==2); + bToUpper = (sqlite3_user_data(p)!=0); if( nArg==2 ){ zLocale = (const char *)sqlite3_value_text(apArg[1]); } @@ -386,19 +388,23 @@ static void icuCaseFunc16(sqlite3_context *p, int nArg, sqlite3_value **apArg){ } zOutput = zNew; status = U_ZERO_ERROR; - if( sqlite3_user_data(p) ){ + if( bToUpper ){ nOut = 2*u_strToUpper(zOutput,nOut/2,zInput,nInput/2,zLocale,&status); }else{ nOut = 2*u_strToLower(zOutput,nOut/2,zInput,nInput/2,zLocale,&status); } - if( !U_SUCCESS(status) ){ - if( status==U_BUFFER_OVERFLOW_ERROR ) continue; - icuFunctionError(p, - sqlite3_user_data(p) ? "u_strToUpper" : "u_strToLower", status); - return; + + if( U_SUCCESS(status) ){ + sqlite3_result_text16(p, zOutput, nOut, xFree); + }else if( status==U_BUFFER_OVERFLOW_ERROR ){ + assert( cnt==0 ); + continue; + }else{ + icuFunctionError(p, bToUpper ? "u_strToUpper" : "u_strToLower", status); } + return; } - sqlite3_result_text16(p, zOutput, nOut, xFree); + assert( 0 ); /* Unreachable */ } /* diff --git a/manifest b/manifest index 420dfe28cf..dadfc36945 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sSF_HasAgg\sconstant\s(currently\sunused).\s\sAlso\senhance\sthe\scomments\son\nmany\sother\sconstant\sdefinitions\sto\sdetail\sconstraints\son\stheir\svalues. -D 2016-04-14T16:40:13.322 +C In\sthe\sICU\sextension\stoupper()\sand\stolower()\sSQL\sfunctions,\savoid\scalling\su_strToUpper()\sor\su_strToLower()\sa\ssecond\stime\sif\sthe\sbuffer\spassed\sto\sthe\sfirst\sinvocation\sturns\sout\sto\sbe\slarge\senough. +D 2016-04-14T17:29:13.982 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -201,7 +201,7 @@ F ext/fts5/tool/loadfts5.tcl 95b03429ee6b138645703c6ca192c3ac96eaf093 F ext/fts5/tool/mkfts5c.tcl d1c2a9ab8e0ec690a52316f33dd9b1d379942f45 F ext/fts5/tool/showfts5.tcl d54da0e067306663e2d5d523965ca487698e722c F ext/icu/README.txt d9fbbad0c2f647c3fdf715fc9fd64af53aedfc43 -F ext/icu/icu.c 4bdf4c5daedabcd8e6eb6e6a377657f7b978f9f7 +F ext/icu/icu.c 43df9d8ef2fae7a325100ebd713ab089dc829dd7 F ext/icu/sqliteicu.h 728867a802baa5a96de7495e9689a8e01715ef37 F ext/misc/amatch.c 211108e201105e4bb0c076527b8cfd34330fc234 F ext/misc/closure.c 0d2a038df8fbae7f19de42e7c7d71f2e4dc88704 @@ -1482,7 +1482,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 79147dca87cfd7eb62d57baa3b70fa2a8542232a -R 6419c618333708e1ee248e43219e551e -U drh -Z 76d9f185ebd1be8244746d28959cec5d +P 7b7a69d098f7581a43b818c251717c2450b797de +R a8b6237f5057a202cac6f8ad76568fb8 +U dan +Z 7154ea80cb4b14d420b76956f5072d2e diff --git a/manifest.uuid b/manifest.uuid index 75ce1d9040..b44499e23c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7b7a69d098f7581a43b818c251717c2450b797de \ No newline at end of file +d23e581351fb8eea28e7b13b3dcadfc817c3a05f \ No newline at end of file From eacd29d4849d34ca1a3bf31dbb9e8ee98f85dec8 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 15 Apr 2016 15:03:27 +0000 Subject: [PATCH 0311/1484] CLI enhancement: Add the ".eqp full" option, that shows both the EXPLAIN QUERY PLAN and the EXPLAIN output for each command run. Also disable any ".wheretrace" and ".selecttrace" when showing EQP output. FossilOrigin-Name: 3e217d6265ecd16db783bed7ce1d9d0f9c4828bb --- manifest | 14 ++-- manifest.uuid | 2 +- src/shell.c | 208 +++++++++++++++++++++++++++++++++----------------- 3 files changed, 144 insertions(+), 80 deletions(-) diff --git a/manifest b/manifest index dadfc36945..c039180bbf 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\sthe\sICU\sextension\stoupper()\sand\stolower()\sSQL\sfunctions,\savoid\scalling\su_strToUpper()\sor\su_strToLower()\sa\ssecond\stime\sif\sthe\sbuffer\spassed\sto\sthe\sfirst\sinvocation\sturns\sout\sto\sbe\slarge\senough. -D 2016-04-14T17:29:13.982 +C CLI\senhancement:\s\sAdd\sthe\s".eqp\sfull"\soption,\sthat\sshows\sboth\sthe\sEXPLAIN\nQUERY\sPLAN\sand\sthe\sEXPLAIN\soutput\sfor\seach\scommand\srun.\s\sAlso\sdisable\nany\s".wheretrace"\sand\s".selecttrace"\swhen\sshowing\sEQP\soutput. +D 2016-04-15T15:03:27.144 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -376,7 +376,7 @@ F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c b8f7174e5f8c33c44ded3a25a973d0bb89228c20 F src/rowset.c 9fe4b3ad7cc00944386bb600233d8f523de07a6e F src/select.c 30217121bdf6b587462150b8ee9e1467f7a6036b -F src/shell.c ebcdf99f3e7c7409bd463eae443f1bd01e3e2d02 +F src/shell.c 14ff7f660530a52b117d110ba3390b7b2eb719b6 F src/sqlite.h.in 64eb70a3b309751bebf73a5552a51244f68f0ea5 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 98f72cbfe00169c39089115427d06ea05fe4b4a2 @@ -1482,7 +1482,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 7b7a69d098f7581a43b818c251717c2450b797de -R a8b6237f5057a202cac6f8ad76568fb8 -U dan -Z 7154ea80cb4b14d420b76956f5072d2e +P d23e581351fb8eea28e7b13b3dcadfc817c3a05f +R e880e1f26ac9fef78137656188a6e0aa +U drh +Z dc2294cde78bca18f07e3e2fb59a4dd5 diff --git a/manifest.uuid b/manifest.uuid index b44499e23c..453393af12 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d23e581351fb8eea28e7b13b3dcadfc817c3a05f \ No newline at end of file +3e217d6265ecd16db783bed7ce1d9d0f9c4828bb \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 4744b91ddd..5148177372 100644 --- a/src/shell.c +++ b/src/shell.c @@ -1733,7 +1733,7 @@ static void explain_data_prepare(ShellState *p, sqlite3_stmt *pSql){ if( str_in_array(zOp, azGoto) && p2opnIndent && (abYield[p2op] || sqlite3_column_int(pSql, 2)) ){ - for(i=p2op+1; iaiIndent[i] += 2; + for(i=p2op; iaiIndent[i] += 2; } } @@ -1752,6 +1752,104 @@ static void explain_data_delete(ShellState *p){ p->iIndent = 0; } +/* +** Disable and restore .wheretrace and .selecttrace settings. +*/ +#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE) +extern int sqlite3SelectTrace; +static int savedSelectTrace; +#endif +#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE) +extern int sqlite3WhereTrace; +static int savedWhereTrace; +#endif +static void disable_debug_trace_modes(void){ +#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE) + savedSelectTrace = sqlite3SelectTrace; + sqlite3SelectTrace = 0; +#endif +#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE) + savedWhereTrace = sqlite3WhereTrace; + sqlite3WhereTrace = 0; +#endif +} +static void restore_debug_trace_modes(void){ +#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE) + sqlite3SelectTrace = savedSelectTrace; +#endif +#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE) + sqlite3WhereTrace = savedWhereTrace; +#endif +} + +/* +** Run a prepared statement +*/ +static void exec_prepared_stmt( + ShellState *pArg, /* Pointer to ShellState */ + sqlite3_stmt *pStmt, /* Statment to run */ + int (*xCallback)(void*,int,char**,char**,int*) /* Callback function */ +){ + int rc; + + /* perform the first step. this will tell us if we + ** have a result set or not and how wide it is. + */ + rc = sqlite3_step(pStmt); + /* if we have a result set... */ + if( SQLITE_ROW == rc ){ + /* if we have a callback... */ + if( xCallback ){ + /* allocate space for col name ptr, value ptr, and type */ + int nCol = sqlite3_column_count(pStmt); + void *pData = sqlite3_malloc64(3*nCol*sizeof(const char*) + 1); + if( !pData ){ + rc = SQLITE_NOMEM; + }else{ + char **azCols = (char **)pData; /* Names of result columns */ + char **azVals = &azCols[nCol]; /* Results */ + int *aiTypes = (int *)&azVals[nCol]; /* Result types */ + int i, x; + assert(sizeof(int) <= sizeof(char *)); + /* save off ptrs to column names */ + for(i=0; icMode==MODE_Insert ){ + azVals[i] = ""; + }else{ + azVals[i] = (char*)sqlite3_column_text(pStmt, i); + } + if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){ + rc = SQLITE_NOMEM; + break; /* from for */ + } + } /* end for */ + + /* if data and types extracted successfully... */ + if( SQLITE_ROW == rc ){ + /* call the supplied callback with the result row data */ + if( xCallback(pArg, nCol, azVals, azCols, aiTypes) ){ + rc = SQLITE_ABORT; + }else{ + rc = sqlite3_step(pStmt); + } + } + } while( SQLITE_ROW == rc ); + sqlite3_free(pData); + } + }else{ + do{ + rc = sqlite3_step(pStmt); + } while( rc == SQLITE_ROW ); + } + } +} + /* ** Execute a statement or set of statements. Print ** any result rows/columns depending on the current mode @@ -1779,6 +1877,7 @@ static int shell_exec( } while( zSql[0] && (SQLITE_OK == rc) ){ + static const char *zStmtSql; rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover); if( SQLITE_OK != rc ){ if( pzErrMsg ){ @@ -1791,6 +1890,8 @@ static int shell_exec( while( IsSpace(zSql[0]) ) zSql++; continue; } + zStmtSql = sqlite3_sql(pStmt); + while( IsSpace(zStmtSql[0]) ) zStmtSql++; /* save off the prepared statment handle and reset row count */ if( pArg ){ @@ -1800,15 +1901,15 @@ static int shell_exec( /* echo the sql statement if echo on */ if( pArg && pArg->echoOn ){ - const char *zStmtSql = sqlite3_sql(pStmt); utf8_printf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql); } /* Show the EXPLAIN QUERY PLAN if .eqp is on */ - if( pArg && pArg->autoEQP ){ + if( pArg && pArg->autoEQP && sqlite3_strlike("EXPLAIN%",zStmtSql,0)!=0 ){ sqlite3_stmt *pExplain; - char *zEQP = sqlite3_mprintf("EXPLAIN QUERY PLAN %s", - sqlite3_sql(pStmt)); + char *zEQP; + disable_debug_trace_modes(); + zEQP = sqlite3_mprintf("EXPLAIN QUERY PLAN %s", zStmtSql); rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0); if( rc==SQLITE_OK ){ while( sqlite3_step(pExplain)==SQLITE_ROW ){ @@ -1820,13 +1921,27 @@ static int shell_exec( } sqlite3_finalize(pExplain); sqlite3_free(zEQP); + if( pArg->autoEQP>=2 ){ + /* Also do an EXPLAIN for ".eqp full" mode */ + zEQP = sqlite3_mprintf("EXPLAIN %s", zStmtSql); + rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0); + if( rc==SQLITE_OK ){ + pArg->cMode = MODE_Explain; + explain_data_prepare(pArg, pExplain); + exec_prepared_stmt(pArg, pExplain, xCallback); + explain_data_delete(pArg); + } + sqlite3_finalize(pExplain); + sqlite3_free(zEQP); + } + restore_debug_trace_modes(); } if( pArg ){ pArg->cMode = pArg->mode; if( pArg->autoExplain && sqlite3_column_count(pStmt)==8 - && sqlite3_strlike("%EXPLAIN%", sqlite3_sql(pStmt),0)==0 + && sqlite3_strlike("EXPLAIN%", zStmtSql,0)==0 ){ pArg->cMode = MODE_Explain; } @@ -1838,63 +1953,7 @@ static int shell_exec( } } - /* perform the first step. this will tell us if we - ** have a result set or not and how wide it is. - */ - rc = sqlite3_step(pStmt); - /* if we have a result set... */ - if( SQLITE_ROW == rc ){ - /* if we have a callback... */ - if( xCallback ){ - /* allocate space for col name ptr, value ptr, and type */ - int nCol = sqlite3_column_count(pStmt); - void *pData = sqlite3_malloc64(3*nCol*sizeof(const char*) + 1); - if( !pData ){ - rc = SQLITE_NOMEM; - }else{ - char **azCols = (char **)pData; /* Names of result columns */ - char **azVals = &azCols[nCol]; /* Results */ - int *aiTypes = (int *)&azVals[nCol]; /* Result types */ - int i, x; - assert(sizeof(int) <= sizeof(char *)); - /* save off ptrs to column names */ - for(i=0; icMode==MODE_Insert ){ - azVals[i] = ""; - }else{ - azVals[i] = (char*)sqlite3_column_text(pStmt, i); - } - if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){ - rc = SQLITE_NOMEM; - break; /* from for */ - } - } /* end for */ - - /* if data and types extracted successfully... */ - if( SQLITE_ROW == rc ){ - /* call the supplied callback with the result row data */ - if( xCallback(pArg, nCol, azVals, azCols, aiTypes) ){ - rc = SQLITE_ABORT; - }else{ - rc = sqlite3_step(pStmt); - } - } - } while( SQLITE_ROW == rc ); - sqlite3_free(pData); - } - }else{ - do{ - rc = sqlite3_step(pStmt); - } while( rc == SQLITE_ROW ); - } - } - + exec_prepared_stmt(pArg, pStmt, xCallback); explain_data_delete(pArg); /* print usage stats if stats on */ @@ -2084,7 +2143,7 @@ static char zHelp[] = " If TABLE specified, only dump tables matching\n" " LIKE pattern TABLE.\n" ".echo on|off Turn command echo on or off\n" - ".eqp on|off Enable or disable automatic EXPLAIN QUERY PLAN\n" + ".eqp on|off|full Enable or disable automatic EXPLAIN QUERY PLAN\n" ".exit Exit this program\n" ".explain ?on|off|auto? Turn EXPLAIN output mode on or off or to automatic\n" ".fullschema ?--indent? Show schema and the content of sqlite_stat tables\n" @@ -3254,9 +3313,13 @@ static int do_meta_command(char *zLine, ShellState *p){ if( c=='e' && strncmp(azArg[0], "eqp", n)==0 ){ if( nArg==2 ){ - p->autoEQP = booleanValue(azArg[1]); + if( strcmp(azArg[1],"full")==0 ){ + p->autoEQP = 2; + }else{ + p->autoEQP = booleanValue(azArg[1]); + } }else{ - raw_printf(stderr, "Usage: .eqp on|off\n"); + raw_printf(stderr, "Usage: .eqp on|off|full\n"); rc = 1; } }else @@ -4017,7 +4080,6 @@ static int do_meta_command(char *zLine, ShellState *p){ #if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE) if( c=='s' && n==11 && strncmp(azArg[0], "selecttrace", n)==0 ){ - extern int sqlite3SelectTrace; sqlite3SelectTrace = integerValue(azArg[1]); }else #endif @@ -4277,17 +4339,18 @@ static int do_meta_command(char *zLine, ShellState *p){ }else if( c=='s' && strncmp(azArg[0], "show", n)==0 ){ + static const char *azBool[] = { "off", "on", "full", "unk" }; int i; if( nArg!=1 ){ raw_printf(stderr, "Usage: .show\n"); rc = 1; goto meta_command_exit; } - utf8_printf(p->out, "%12.12s: %s\n","echo", p->echoOn ? "on" : "off"); - utf8_printf(p->out, "%12.12s: %s\n","eqp", p->autoEQP ? "on" : "off"); + utf8_printf(p->out, "%12.12s: %s\n","echo", azBool[p->echoOn!=0]); + utf8_printf(p->out, "%12.12s: %s\n","eqp", azBool[p->autoEQP&3]); utf8_printf(p->out, "%12.12s: %s\n","explain", p->mode==MODE_Explain ? "on" : p->autoExplain ? "auto" : "off"); - utf8_printf(p->out,"%12.12s: %s\n","headers", p->showHeader ? "on" : "off"); + utf8_printf(p->out,"%12.12s: %s\n","headers", azBool[p->showHeader!=0]); utf8_printf(p->out, "%12.12s: %s\n","mode", modeDescr[p->mode]); utf8_printf(p->out, "%12.12s: ", "nullvalue"); output_c_string(p->out, p->nullValue); @@ -4300,7 +4363,7 @@ static int do_meta_command(char *zLine, ShellState *p){ utf8_printf(p->out,"%12.12s: ", "rowseparator"); output_c_string(p->out, p->rowSeparator); raw_printf(p->out, "\n"); - utf8_printf(p->out, "%12.12s: %s\n","stats", p->statsOn ? "on" : "off"); + utf8_printf(p->out, "%12.12s: %s\n","stats", azBool[p->statsOn!=0]); utf8_printf(p->out, "%12.12s: ", "width"); for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) { raw_printf(p->out, "%d ", p->colWidth[i]); @@ -4715,7 +4778,6 @@ static int do_meta_command(char *zLine, ShellState *p){ #if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE) if( c=='w' && strncmp(azArg[0], "wheretrace", n)==0 ){ - extern int sqlite3WhereTrace; sqlite3WhereTrace = nArg>=2 ? booleanValue(azArg[1]) : 0xff; }else #endif @@ -5383,6 +5445,8 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ data.echoOn = 1; }else if( strcmp(z,"-eqp")==0 ){ data.autoEQP = 1; + }else if( strcmp(z,"-eqpfull")==0 ){ + data.autoEQP = 2; }else if( strcmp(z,"-stats")==0 ){ data.statsOn = 1; }else if( strcmp(z,"-scanstats")==0 ){ From f89157653a8a4586b2498cc6b8f64cd8896e1e9f Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 15 Apr 2016 20:46:41 +0000 Subject: [PATCH 0312/1484] Add the experimental sqlite3rbu_vacuum() API function. For opening an RBU handle that rebuilds a database from scratch. FossilOrigin-Name: 0216b48f28042ad86711e00802c2da8ce9be3044 --- ext/rbu/rbuvacuum.test | 181 +++++++++++++++ ext/rbu/sqlite3rbu.c | 501 +++++++++++++++++++++++++++++------------ ext/rbu/sqlite3rbu.h | 8 + ext/rbu/test_rbu.c | 29 +++ manifest | 22 +- manifest.uuid | 2 +- 6 files changed, 595 insertions(+), 148 deletions(-) create mode 100644 ext/rbu/rbuvacuum.test diff --git a/ext/rbu/rbuvacuum.test b/ext/rbu/rbuvacuum.test new file mode 100644 index 0000000000..045b2d1bb7 --- /dev/null +++ b/ext/rbu/rbuvacuum.test @@ -0,0 +1,181 @@ +# 2016 April 15 +# +# 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 contains tests for the RBU module. More specifically, it +# contains tests to ensure that the sqlite3rbu_vacuum() API works as +# expected. +# + +source [file join [file dirname [info script]] rbu_common.tcl] +set ::testprefix rbuvacuum + +proc do_rbu_vacuum_test {tn} { + uplevel [list do_test $tn.1 { + forcedelete state.db + if {$::step==0} { sqlite3rbu_vacuum rbu test.db state.db } + while 1 { + if {$::step==1} { sqlite3rbu_vacuum rbu test.db state.db } + set rc [rbu step] + if {$rc!="SQLITE_OK"} break + if {$::step==1} { rbu close } + } + rbu close + } {SQLITE_DONE}] + + uplevel [list do_execsql_test $tn.2 { + PRAGMA integrity_check + } ok] +} + +foreach step {0 1} { + + set ::testprefix rbuvacuum-step=$step + reset_db + + # Simplest possible vacuum. + do_execsql_test 1.0 { + PRAGMA page_size = 1024; + CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c); + INSERT INTO t1 VALUES(1, 2, 3); + INSERT INTO t1 VALUES(4, 5, 6); + INSERT INTO t1 VALUES(7, 8, 9); + PRAGMA integrity_check; + } {ok} + do_rbu_vacuum_test 1.1 + + # A vacuum that actually reclaims space. + do_execsql_test 1.2.1 { + INSERT INTO t1 VALUES(8, randomblob(900), randomblob(900)); + INSERT INTO t1 VALUES(9, randomblob(900), randomblob(900)); + INSERT INTO t1 VALUES(10, randomblob(900), randomblob(900)); + INSERT INTO t1 VALUES(11, randomblob(900), randomblob(900)); + INSERT INTO t1 VALUES(12, randomblob(900), randomblob(900)); + PRAGMA page_count; + } {12} + do_execsql_test 1.2.2 { + DELETE FROM t1 WHERE rowid BETWEEN 8 AND 11; + PRAGMA page_count; + } {12} + do_rbu_vacuum_test 1.2.3 + do_execsql_test 1.2.4 { + PRAGMA page_count; + } {3} + + # Add an index to the table. + do_execsql_test 1.3.1 { + CREATE INDEX t1b ON t1(b); + INSERT INTO t1 VALUES(13, randomblob(900), randomblob(900)); + INSERT INTO t1 VALUES(14, randomblob(900), randomblob(900)); + INSERT INTO t1 VALUES(15, randomblob(900), randomblob(900)); + INSERT INTO t1 VALUES(16, randomblob(900), randomblob(900)); + PRAGMA page_count; + } {18} + do_execsql_test 1.3.2 { + DELETE FROM t1 WHERE rowid BETWEEN 12 AND 15; + PRAGMA page_count; + } {18} + do_rbu_vacuum_test 1.3.3 + do_execsql_test 1.3.4 { + PRAGMA page_count; + } {5} + + # WITHOUT ROWID table. + do_execsql_test 1.4.1 { + CREATE TABLE t2(a, b, c, PRIMARY KEY(a, b)) WITHOUT ROWID; + + INSERT INTO t2 VALUES(randomblob(900), 1, randomblob(900)); + INSERT INTO t2 VALUES(randomblob(900), 2, randomblob(900)); + INSERT INTO t2 VALUES(randomblob(900), 3, randomblob(900)); + INSERT INTO t2 VALUES(randomblob(900), 4, randomblob(900)); + INSERT INTO t2 VALUES(randomblob(900), 6, randomblob(900)); + INSERT INTO t2 VALUES(randomblob(900), 7, randomblob(900)); + INSERT INTO t2 VALUES(randomblob(900), 8, randomblob(900)); + + DELETE FROM t2 WHERE b BETWEEN 2 AND 7; + PRAGMA page_count; + } {20} + do_rbu_vacuum_test 1.4.2 + do_execsql_test 1.4.3 { + PRAGMA page_count; + } {10} + + # WITHOUT ROWID table with an index. + do_execsql_test 1.4.1 { + CREATE INDEX t2c ON t2(c); + + INSERT INTO t2 VALUES(randomblob(900), 9, randomblob(900)); + INSERT INTO t2 VALUES(randomblob(900), 10, randomblob(900)); + INSERT INTO t2 VALUES(randomblob(900), 11, randomblob(900)); + INSERT INTO t2 VALUES(randomblob(900), 12, randomblob(900)); + INSERT INTO t2 VALUES(randomblob(900), 13, randomblob(900)); + + DELETE FROM t2 WHERE b BETWEEN 8 AND 12; + PRAGMA page_count; + } {35} + do_rbu_vacuum_test 1.4.2 + do_execsql_test 1.4.3 { + PRAGMA page_count; + } {15} + do_execsql_test 1.4.4 { + VACUUM; + PRAGMA page_count; + } {15} + + do_execsql_test 1.5.1 { + CREATE TABLE t3(a, b, c); + INSERT INTO t3 VALUES('a', 'b', 'c'); + INSERT INTO t3 VALUES('d', 'e', 'f'); + INSERT INTO t3 VALUES('g', 'h', 'i'); + } + do_rbu_vacuum_test 1.5.2 + do_execsql_test 1.5.3 { + SELECT * FROM t3 + } {a b c d e f g h i} + do_execsql_test 1.5.4 { + CREATE INDEX t3a ON t3(a); + CREATE INDEX t3b ON t3(b); + CREATE INDEX t3c ON t3(c); + INSERT INTO t3 VALUES('j', 'k', 'l'); + DELETE FROM t3 WHERE a = 'g'; + } + do_rbu_vacuum_test 1.5.5 + do_execsql_test 1.5.6 { + SELECT rowid, * FROM t3 ORDER BY b + } {1 a b c 2 d e f 4 j k l} + + do_execsql_test 1.6.1 { + CREATE TABLE t4(a PRIMARY KEY, b, c); + INSERT INTO t4 VALUES('a', 'b', 'c'); + INSERT INTO t4 VALUES('d', 'e', 'f'); + INSERT INTO t4 VALUES('g', 'h', 'i'); + } + do_rbu_vacuum_test 1.6.2 + do_execsql_test 1.6.3 { + SELECT * FROM t4 + } {a b c d e f g h i} + do_execsql_test 1.6.4 { + CREATE INDEX t4a ON t4(a); + CREATE INDEX t4b ON t4(b); + CREATE INDEX t4c ON t4(c); + + INSERT INTO t4 VALUES('j', 'k', 'l'); + DELETE FROM t4 WHERE a='g'; + } + do_rbu_vacuum_test 1.6.5 + do_execsql_test 1.6.6 { + SELECT * FROM t4 ORDER BY b + } {a b c d e f j k l} + +} + +catch { db close } +finish_test + diff --git a/ext/rbu/sqlite3rbu.c b/ext/rbu/sqlite3rbu.c index f553ebdac5..e71690769b 100644 --- a/ext/rbu/sqlite3rbu.c +++ b/ext/rbu/sqlite3rbu.c @@ -176,6 +176,7 @@ typedef struct RbuUpdateStmt RbuUpdateStmt; #if !defined(SQLITE_AMALGAMATION) typedef unsigned int u32; +typedef unsigned short u16; typedef unsigned char u8; typedef sqlite3_int64 i64; #endif @@ -402,6 +403,11 @@ struct rbu_file { rbu_file *pMainNext; /* Next MAIN_DB file */ }; +/* +** True for an RBU vacuum handle, or false otherwise. +*/ +#define rbuIsVacuum(p) ((p)->zTarget==0) + /************************************************************************* ** The following three functions, found below: @@ -850,8 +856,11 @@ static int rbuObjIterNext(sqlite3rbu *p, RbuObjIter *pIter){ /* ** The implementation of the rbu_target_name() SQL function. This function -** accepts one argument - the name of a table in the RBU database. If the -** table name matches the pattern: +** accepts one or two arguments. The first argument is the name of a table - +** the name of a table in the RBU database. The second, if it is present, is 1 +** for a view or 0 for a table. +** +** For a non-vacuum RBU handle, if the table name matches the pattern: ** ** data[0-9]_ ** @@ -862,21 +871,33 @@ static int rbuObjIterNext(sqlite3rbu *p, RbuObjIter *pIter){ ** "data_t1" -> "t1" ** "data0123_t2" -> "t2" ** "dataAB_t3" -> NULL +** +** For an rbu vacuum handle, a copy of the first argument is returned if +** the second argument is either missing or 0 (not a view). */ static void rbuTargetNameFunc( - sqlite3_context *context, + sqlite3_context *pCtx, int argc, sqlite3_value **argv ){ + sqlite3rbu *p = sqlite3_user_data(pCtx); const char *zIn; - assert( argc==1 ); + assert( argc==1 || argc==2 ); zIn = (const char*)sqlite3_value_text(argv[0]); - if( zIn && strlen(zIn)>4 && memcmp("data", zIn, 4)==0 ){ - int i; - for(i=4; zIn[i]>='0' && zIn[i]<='9'; i++); - if( zIn[i]=='_' && zIn[i+1] ){ - sqlite3_result_text(context, &zIn[i+1], -1, SQLITE_STATIC); + if( zIn ){ + if( rbuIsVacuum(p) ){ + if( argc==1 || 0==sqlite3_value_int(argv[1]) ){ + sqlite3_result_text(pCtx, zIn, -1, SQLITE_STATIC); + } + }else{ + if( strlen(zIn)>4 && memcmp("data", zIn, 4)==0 ){ + int i; + for(i=4; zIn[i]>='0' && zIn[i]<='9'; i++); + if( zIn[i]=='_' && zIn[i+1] ){ + sqlite3_result_text(pCtx, &zIn[i+1], -1, SQLITE_STATIC); + } + } } } } @@ -894,7 +915,8 @@ static int rbuObjIterFirst(sqlite3rbu *p, RbuObjIter *pIter){ memset(pIter, 0, sizeof(RbuObjIter)); rc = prepareAndCollectError(p->dbRbu, &pIter->pTblIter, &p->zErrmsg, - "SELECT rbu_target_name(name) AS target, name FROM sqlite_master " + "SELECT rbu_target_name(name, type='view') AS target, name " + "FROM sqlite_master " "WHERE type IN ('table', 'view') AND target IS NOT NULL " "ORDER BY name" ); @@ -1270,6 +1292,7 @@ static int rbuObjIterCacheTableInfo(sqlite3rbu *p, RbuObjIter *pIter){ pStmt = 0; if( p->rc==SQLITE_OK + && rbuIsVacuum(p)==0 && bRbuRowid!=(pIter->eType==RBU_PK_VTAB || pIter->eType==RBU_PK_NONE) ){ p->rc = SQLITE_ERROR; @@ -1409,6 +1432,8 @@ static char *rbuObjIterGetIndexCols( for(i=0; pIter->abTblPk[i]==0; i++); assert( inTblCol ); zCol = pIter->azTblCol[i]; + }else if( rbuIsVacuum(p) ){ + zCol = "_rowid_"; }else{ zCol = "rbu_rowid"; } @@ -1949,7 +1974,7 @@ static int rbuObjIterPrepareAll( } /* And to delete index entries */ - if( p->rc==SQLITE_OK ){ + if( rbuIsVacuum(p)==0 && p->rc==SQLITE_OK ){ p->rc = prepareFreeAndCollectError( p->dbMain, &pIter->pDelete, &p->zErrmsg, sqlite3_mprintf("DELETE FROM \"rbu_imp_%w\" WHERE %s", zTbl, zWhere) @@ -1959,6 +1984,15 @@ static int rbuObjIterPrepareAll( /* Create the SELECT statement to read keys in sorted order */ if( p->rc==SQLITE_OK ){ char *zSql; + if( rbuIsVacuum(p) ){ + zSql = sqlite3_mprintf( + "SELECT %s, 0 AS rbu_control FROM '%q' ORDER BY %s%s", + zCollist, + pIter->zDataTbl, + zCollist, zLimit + ); + }else + if( pIter->eType==RBU_PK_EXTERNAL || pIter->eType==RBU_PK_NONE ){ zSql = sqlite3_mprintf( "SELECT %s, rbu_control FROM %s.'rbu_tmp_%q' ORDER BY %s%s", @@ -1985,7 +2019,9 @@ static int rbuObjIterPrepareAll( sqlite3_free(zWhere); sqlite3_free(zBind); }else{ - int bRbuRowid = (pIter->eType==RBU_PK_VTAB || pIter->eType==RBU_PK_NONE); + int bRbuRowid = (pIter->eType==RBU_PK_VTAB) + ||(pIter->eType==RBU_PK_NONE) + ||(pIter->eType==RBU_PK_EXTERNAL && rbuIsVacuum(p)); const char *zTbl = pIter->zTbl; /* Table this step applies to */ const char *zWrite; /* Imposter table name */ @@ -2012,8 +2048,10 @@ static int rbuObjIterPrepareAll( ); } - /* Create the DELETE statement to write to the target PK b-tree */ - if( p->rc==SQLITE_OK ){ + /* Create the DELETE statement to write to the target PK b-tree. + ** Because it only performs INSERT operations, this is not required for + ** an rbu vacuum handle. */ + if( rbuIsVacuum(p)==0 && p->rc==SQLITE_OK ){ p->rc = prepareFreeAndCollectError(p->dbMain, &pIter->pDelete, pz, sqlite3_mprintf( "DELETE FROM \"%s%w\" WHERE %s", zWrite, zTbl, zWhere @@ -2021,7 +2059,7 @@ static int rbuObjIterPrepareAll( ); } - if( pIter->abIndexed ){ + if( rbuIsVacuum(p)==0 && pIter->abIndexed ){ const char *zRbuRowid = ""; if( pIter->eType==RBU_PK_EXTERNAL || pIter->eType==RBU_PK_NONE ){ zRbuRowid = ", rbu_rowid"; @@ -2071,10 +2109,16 @@ static int rbuObjIterPrepareAll( /* Create the SELECT statement to read keys from data_xxx */ if( p->rc==SQLITE_OK ){ + const char *zRbuRowid = ""; + if( bRbuRowid ){ + zRbuRowid = rbuIsVacuum(p) ? ",_rowid_ " : ",rbu_rowid"; + } p->rc = prepareFreeAndCollectError(p->dbRbu, &pIter->pSelect, pz, sqlite3_mprintf( - "SELECT %s, rbu_control%s FROM '%q'%s", - zCollist, (bRbuRowid ? ", rbu_rowid" : ""), + "SELECT %s,%s rbu_control%s FROM '%q'%s", + zCollist, + (rbuIsVacuum(p) ? "0 AS " : ""), + zRbuRowid, pIter->zDataTbl, zLimit ) ); @@ -2183,6 +2227,95 @@ static sqlite3 *rbuOpenDbhandle(sqlite3rbu *p, const char *zName){ return db; } +/* +** Free an RbuState object allocated by rbuLoadState(). +*/ +static void rbuFreeState(RbuState *p){ + if( p ){ + sqlite3_free(p->zTbl); + sqlite3_free(p->zIdx); + sqlite3_free(p); + } +} + +/* +** Allocate an RbuState object and load the contents of the rbu_state +** table into it. Return a pointer to the new object. It is the +** responsibility of the caller to eventually free the object using +** sqlite3_free(). +** +** If an error occurs, leave an error code and message in the rbu handle +** and return NULL. +*/ +static RbuState *rbuLoadState(sqlite3rbu *p){ + RbuState *pRet = 0; + sqlite3_stmt *pStmt = 0; + int rc; + int rc2; + + pRet = (RbuState*)rbuMalloc(p, sizeof(RbuState)); + if( pRet==0 ) return 0; + + rc = prepareFreeAndCollectError(p->dbRbu, &pStmt, &p->zErrmsg, + sqlite3_mprintf("SELECT k, v FROM %s.rbu_state", p->zStateDb) + ); + while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){ + switch( sqlite3_column_int(pStmt, 0) ){ + case RBU_STATE_STAGE: + pRet->eStage = sqlite3_column_int(pStmt, 1); + if( pRet->eStage!=RBU_STAGE_OAL + && pRet->eStage!=RBU_STAGE_MOVE + && pRet->eStage!=RBU_STAGE_CKPT + ){ + p->rc = SQLITE_CORRUPT; + } + break; + + case RBU_STATE_TBL: + pRet->zTbl = rbuStrndup((char*)sqlite3_column_text(pStmt, 1), &rc); + break; + + case RBU_STATE_IDX: + pRet->zIdx = rbuStrndup((char*)sqlite3_column_text(pStmt, 1), &rc); + break; + + case RBU_STATE_ROW: + pRet->nRow = sqlite3_column_int(pStmt, 1); + break; + + case RBU_STATE_PROGRESS: + pRet->nProgress = sqlite3_column_int64(pStmt, 1); + break; + + case RBU_STATE_CKPT: + pRet->iWalCksum = sqlite3_column_int64(pStmt, 1); + break; + + case RBU_STATE_COOKIE: + pRet->iCookie = (u32)sqlite3_column_int64(pStmt, 1); + break; + + case RBU_STATE_OALSZ: + pRet->iOalSz = (u32)sqlite3_column_int64(pStmt, 1); + break; + + case RBU_STATE_PHASEONESTEP: + pRet->nPhaseOneStep = sqlite3_column_int64(pStmt, 1); + break; + + default: + rc = SQLITE_CORRUPT; + break; + } + } + rc2 = sqlite3_finalize(pStmt); + if( rc==SQLITE_OK ) rc = rc2; + + p->rc = rc; + return pRet; +} + + /* ** Open the database handle and attach the RBU database as "rbu". If an ** error occurs, leave an error code and message in the RBU handle. @@ -2191,8 +2324,7 @@ static void rbuOpenDatabase(sqlite3rbu *p){ assert( p->rc==SQLITE_OK ); assert( p->dbMain==0 && p->dbRbu==0 ); - p->eStage = 0; - p->dbMain = rbuOpenDbhandle(p, p->zTarget); + /* Open the RBU database */ p->dbRbu = rbuOpenDbhandle(p, p->zRbu); /* If using separate RBU and state databases, attach the state database to @@ -2204,6 +2336,38 @@ static void rbuOpenDatabase(sqlite3rbu *p){ memcpy(p->zStateDb, "main", 4); } + /* If it has not already been created, create the rbu_state table */ + rbuMPrintfExec(p, p->dbRbu, RBU_CREATE_STATE, p->zStateDb); + + if( rbuIsVacuum(p) ){ + int bOpen = 0; + if( p->eStage>=RBU_STAGE_MOVE ){ + bOpen = 1; + }else{ + RbuState *pState = rbuLoadState(p); + if( pState ){ + bOpen = (pState->eStage>RBU_STAGE_MOVE); + rbuFreeState(pState); + } + } + if( bOpen ) p->dbMain = rbuOpenDbhandle(p, p->zRbu); + } + + p->eStage = 0; + if( p->dbMain==0 ){ + if( p->zTarget ){ + p->dbMain = rbuOpenDbhandle(p, p->zTarget); + }else{ + char *zTarget = sqlite3_mprintf("%s-vacuum", p->zRbu); + if( zTarget==0 ){ + p->rc = SQLITE_NOMEM; + return; + } + p->dbMain = rbuOpenDbhandle(p, zTarget); + sqlite3_free(zTarget); + } + } + if( p->rc==SQLITE_OK ){ p->rc = sqlite3_create_function(p->dbMain, "rbu_tmp_insert", -1, SQLITE_UTF8, (void*)p, rbuTmpInsertFunc, 0, 0 @@ -2218,7 +2382,7 @@ static void rbuOpenDatabase(sqlite3rbu *p){ if( p->rc==SQLITE_OK ){ p->rc = sqlite3_create_function(p->dbRbu, - "rbu_target_name", 1, SQLITE_UTF8, (void*)p, rbuTargetNameFunc, 0, 0 + "rbu_target_name", -1, SQLITE_UTF8, (void*)p, rbuTargetNameFunc, 0, 0 ); } @@ -2477,9 +2641,14 @@ static LPWSTR rbuWinUtf8ToUnicode(const char *zFilename){ */ static void rbuMoveOalFile(sqlite3rbu *p){ const char *zBase = sqlite3_db_filename(p->dbMain, "main"); - - char *zWal = sqlite3_mprintf("%s-wal", zBase); char *zOal = sqlite3_mprintf("%s-oal", zBase); + char *zWal; + + if( rbuIsVacuum(p) ){ + zWal = sqlite3_mprintf("%s-wal", sqlite3_db_filename(p->dbRbu, "main")); + }else{ + zWal = sqlite3_mprintf("%s-wal", zBase); + } assert( p->eStage==RBU_STAGE_MOVE ); assert( p->rc==SQLITE_OK && p->zErrmsg==0 ); @@ -2500,8 +2669,8 @@ static void rbuMoveOalFile(sqlite3rbu *p){ /* Re-open the databases. */ rbuObjIterFinalize(&p->objiter); - sqlite3_close(p->dbMain); sqlite3_close(p->dbRbu); + sqlite3_close(p->dbMain); p->dbMain = 0; p->dbRbu = 0; @@ -2663,19 +2832,24 @@ static void rbuStepOneOp(sqlite3rbu *p, int eType){ p->rc = sqlite3_bind_value(pWriter, i+1, pVal); if( p->rc ) return; } - if( pIter->zIdx==0 - && (pIter->eType==RBU_PK_VTAB || pIter->eType==RBU_PK_NONE) - ){ - /* For a virtual table, or a table with no primary key, the - ** SELECT statement is: - ** - ** SELECT , rbu_control, rbu_rowid FROM .... - ** - ** Hence column_value(pIter->nCol+1). - */ - assertColumnName(pIter->pSelect, pIter->nCol+1, "rbu_rowid"); - pVal = sqlite3_column_value(pIter->pSelect, pIter->nCol+1); - p->rc = sqlite3_bind_value(pWriter, pIter->nCol+1, pVal); + if( pIter->zIdx==0 ){ + if( pIter->eType==RBU_PK_VTAB + || pIter->eType==RBU_PK_NONE + || (pIter->eType==RBU_PK_EXTERNAL && rbuIsVacuum(p)) + ){ + /* For a virtual table, or a table with no primary key, the + ** SELECT statement is: + ** + ** SELECT , rbu_control, rbu_rowid FROM .... + ** + ** Hence column_value(pIter->nCol+1). + */ + assertColumnName(pIter->pSelect, pIter->nCol+1, + rbuIsVacuum(p) ? "rowid" : "rbu_rowid" + ); + pVal = sqlite3_column_value(pIter->pSelect, pIter->nCol+1); + p->rc = sqlite3_bind_value(pWriter, pIter->nCol+1, pVal); + } } if( p->rc==SQLITE_OK ){ sqlite3_step(pWriter); @@ -2840,7 +3014,7 @@ int sqlite3rbu_step(sqlite3rbu *p){ /* Clean up the rbu_tmp_xxx table for the previous table. It ** cannot be dropped as there are currently active SQL statements. ** But the contents can be deleted. */ - if( pIter->abIndexed ){ + if( rbuIsVacuum(p)==0 && pIter->abIndexed ){ rbuMPrintfExec(p, p->dbRbu, "DELETE FROM %s.'rbu_tmp_%q'", p->zStateDb, pIter->zDataTbl ); @@ -2927,94 +3101,6 @@ int sqlite3rbu_step(sqlite3rbu *p){ } } -/* -** Free an RbuState object allocated by rbuLoadState(). -*/ -static void rbuFreeState(RbuState *p){ - if( p ){ - sqlite3_free(p->zTbl); - sqlite3_free(p->zIdx); - sqlite3_free(p); - } -} - -/* -** Allocate an RbuState object and load the contents of the rbu_state -** table into it. Return a pointer to the new object. It is the -** responsibility of the caller to eventually free the object using -** sqlite3_free(). -** -** If an error occurs, leave an error code and message in the rbu handle -** and return NULL. -*/ -static RbuState *rbuLoadState(sqlite3rbu *p){ - RbuState *pRet = 0; - sqlite3_stmt *pStmt = 0; - int rc; - int rc2; - - pRet = (RbuState*)rbuMalloc(p, sizeof(RbuState)); - if( pRet==0 ) return 0; - - rc = prepareFreeAndCollectError(p->dbRbu, &pStmt, &p->zErrmsg, - sqlite3_mprintf("SELECT k, v FROM %s.rbu_state", p->zStateDb) - ); - while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){ - switch( sqlite3_column_int(pStmt, 0) ){ - case RBU_STATE_STAGE: - pRet->eStage = sqlite3_column_int(pStmt, 1); - if( pRet->eStage!=RBU_STAGE_OAL - && pRet->eStage!=RBU_STAGE_MOVE - && pRet->eStage!=RBU_STAGE_CKPT - ){ - p->rc = SQLITE_CORRUPT; - } - break; - - case RBU_STATE_TBL: - pRet->zTbl = rbuStrndup((char*)sqlite3_column_text(pStmt, 1), &rc); - break; - - case RBU_STATE_IDX: - pRet->zIdx = rbuStrndup((char*)sqlite3_column_text(pStmt, 1), &rc); - break; - - case RBU_STATE_ROW: - pRet->nRow = sqlite3_column_int(pStmt, 1); - break; - - case RBU_STATE_PROGRESS: - pRet->nProgress = sqlite3_column_int64(pStmt, 1); - break; - - case RBU_STATE_CKPT: - pRet->iWalCksum = sqlite3_column_int64(pStmt, 1); - break; - - case RBU_STATE_COOKIE: - pRet->iCookie = (u32)sqlite3_column_int64(pStmt, 1); - break; - - case RBU_STATE_OALSZ: - pRet->iOalSz = (u32)sqlite3_column_int64(pStmt, 1); - break; - - case RBU_STATE_PHASEONESTEP: - pRet->nPhaseOneStep = sqlite3_column_int64(pStmt, 1); - break; - - default: - rc = SQLITE_CORRUPT; - break; - } - } - rc2 = sqlite3_finalize(pStmt); - if( rc==SQLITE_OK ) rc = rc2; - - p->rc = rc; - return pRet; -} - /* ** Compare strings z1 and z2, returning 0 if they are identical, or non-zero ** otherwise. Either or both argument may be NULL. Two NULL values are @@ -3205,15 +3291,63 @@ static void rbuInitPhaseOneSteps(sqlite3rbu *p){ } /* -** Open and return a new RBU handle. +** The RBU handle passed as the only argument has just been opened and +** the state database is empty. If this RBU handle was opened for an +** RBU vacuum operation, create the schema in the target db. */ -sqlite3rbu *sqlite3rbu_open( +static void rbuCreateTargetSchema(sqlite3rbu *p){ + sqlite3_stmt *pSql = 0; + sqlite3_stmt *pInsert = 0; + int rc2; + + assert( rbuIsVacuum(p) ); + + p->rc = prepareAndCollectError(p->dbRbu, &pSql, &p->zErrmsg, + "SELECT sql FROM sqlite_master WHERE sql!='' AND rootpage!=0" + " ORDER BY type DESC" + ); + while( p->rc==SQLITE_OK && sqlite3_step(pSql)==SQLITE_ROW ){ + const char *zSql = sqlite3_column_text(pSql, 0); + p->rc = sqlite3_exec(p->dbMain, zSql, 0, 0, &p->zErrmsg); + } + rbuFinalize(p, pSql); + if( p->rc!=SQLITE_OK ) return; + + p->rc = sqlite3_exec(p->dbMain, "PRAGMA writable_schema=1", 0,0, &p->zErrmsg); + + if( p->rc==SQLITE_OK ){ + p->rc = prepareAndCollectError(p->dbRbu, &pSql, &p->zErrmsg, + "SELECT * FROM sqlite_master WHERE rootpage=0 OR rootpage IS NULL" + ); + } + + if( p->rc==SQLITE_OK ){ + p->rc = prepareAndCollectError(p->dbMain, &pInsert, &p->zErrmsg, + "INSERT INTO sqlite_master VALUES(?,?,?,?,?)" + ); + } + + while( p->rc==SQLITE_OK && sqlite3_step(pSql)==SQLITE_ROW ){ + int i; + for(i=0; i<5; i++){ + sqlite3_bind_value(pInsert, i+1, sqlite3_column_value(pSql, i)); + } + sqlite3_step(pInsert); + p->rc = sqlite3_reset(pInsert); + } + + rbuFinalize(p, pSql); + rbuFinalize(p, pInsert); +} + + +static sqlite3rbu *openRbuHandle( const char *zTarget, const char *zRbu, const char *zState ){ sqlite3rbu *p; - size_t nTarget = strlen(zTarget); + size_t nTarget = zTarget ? strlen(zTarget) : 0; size_t nRbu = strlen(zRbu); size_t nState = zState ? strlen(zState) : 0; size_t nByte = sizeof(sqlite3rbu) + nTarget+1 + nRbu+1+ nState+1; @@ -3226,22 +3360,24 @@ sqlite3rbu *sqlite3rbu_open( memset(p, 0, sizeof(sqlite3rbu)); rbuCreateVfs(p); - /* Open the target database */ + /* Open the target, RBU and state databases */ if( p->rc==SQLITE_OK ){ - p->zTarget = (char*)&p[1]; - memcpy(p->zTarget, zTarget, nTarget+1); - p->zRbu = &p->zTarget[nTarget+1]; + char *pCsr = (char*)&p[1]; + if( zTarget ){ + p->zTarget = pCsr; + memcpy(p->zTarget, zTarget, nTarget+1); + pCsr += nTarget+1; + } + p->zRbu = pCsr; memcpy(p->zRbu, zRbu, nRbu+1); + pCsr += nRbu+1; if( zState ){ - p->zState = &p->zRbu[nRbu+1]; + p->zState = pCsr; memcpy(p->zState, zState, nState+1); } rbuOpenDatabase(p); } - /* If it has not already been created, create the rbu_state table */ - rbuMPrintfExec(p, p->dbRbu, RBU_CREATE_STATE, p->zStateDb); - if( p->rc==SQLITE_OK ){ pState = rbuLoadState(p); assert( pState || p->rc!=SQLITE_OK ); @@ -3304,6 +3440,12 @@ sqlite3rbu *sqlite3rbu_open( } } + /* If this is an RBU vacuum operation and the state table was empty + ** when this handle was opened, create the target database schema. */ + if( pState->eStage==0 && rbuIsVacuum(p) ){ + rbuCreateTargetSchema(p); + } + /* Point the object iterator at the first object */ if( p->rc==SQLITE_OK ){ p->rc = rbuObjIterFirst(p, &p->objiter); @@ -3336,6 +3478,28 @@ sqlite3rbu *sqlite3rbu_open( return p; } +/* +** Open and return a new RBU handle. +*/ +sqlite3rbu *sqlite3rbu_open( + const char *zTarget, + const char *zRbu, + const char *zState +){ + /* TODO: Check that zTarget and zRbu are non-NULL */ + return openRbuHandle(zTarget, zRbu, zState); +} + +/* +** Open a handle to begin or resume an RBU VACUUM operation. +*/ +sqlite3rbu *sqlite3rbu_vacuum( + const char *zTarget, + const char *zState +){ + /* TODO: Check that both arguments are non-NULL */ + return openRbuHandle(0, zTarget, zState); +} /* ** Return the database handle used by pRbu. @@ -3391,8 +3555,8 @@ int sqlite3rbu_close(sqlite3rbu *p, char **pzErrmsg){ rbuObjIterFinalize(&p->objiter); /* Close the open database handle and VFS object. */ - sqlite3_close(p->dbMain); sqlite3_close(p->dbRbu); + sqlite3_close(p->dbMain); rbuDeleteVfs(p); sqlite3_free(p->aBuf); sqlite3_free(p->aFrame); @@ -3594,6 +3758,26 @@ static u32 rbuGetU32(u8 *aBuf){ + ((u32)aBuf[3]); } +/* +** Write an unsigned 32-bit value in big-endian format to the supplied +** buffer. +*/ +static void rbuPutU32(u8 *aBuf, u32 iVal){ + aBuf[0] = (iVal >> 24) & 0xFF; + aBuf[1] = (iVal >> 16) & 0xFF; + aBuf[2] = (iVal >> 8) & 0xFF; + aBuf[3] = (iVal >> 0) & 0xFF; +} + +/* +** Write an unsigned 16-bit value in big-endian format to the supplied +** buffer. +*/ +static void rbuPutU16(u8 *aBuf, u16 iVal){ + aBuf[0] = (iVal >> 8) & 0xFF; + aBuf[1] = (iVal >> 0) & 0xFF; +} + /* ** Read data from an rbuVfs-file. */ @@ -3619,6 +3803,34 @@ static int rbuVfsRead( memset(zBuf, 0, iAmt); }else{ rc = p->pReal->pMethods->xRead(p->pReal, zBuf, iAmt, iOfst); + /* If this is being called to read the first page of the target + ** database as part of an rbu vacuum operation, synthesize the + ** contents of the first page if it does not yet exist. Otherwise, + ** SQLite will not check for a *-wal file. */ + if( p->pRbu && rbuIsVacuum(p->pRbu) + && rc==SQLITE_IOERR_SHORT_READ && iOfst==0 + && (p->openFlags & SQLITE_OPEN_MAIN_DB) + ){ + sqlite3_file *pFd = 0; + rc = sqlite3_file_control( + p->pRbu->dbRbu, "main", SQLITE_FCNTL_FILE_POINTER, (void*)&pFd + ); + if( rc==SQLITE_OK ){ + rc = pFd->pMethods->xRead(pFd, zBuf, iAmt, iOfst); + } + if( rc==SQLITE_OK ){ + rbuPutU32(&zBuf[52], 0); /* largest root page number */ + rbuPutU32(&zBuf[36], 0); /* number of free pages */ + rbuPutU32(&zBuf[32], 0); /* first page on free list trunk */ + rbuPutU32(&zBuf[28], 1); /* size of db file in pages */ + + if( iAmt>100 ){ + assert( iAmt>=101 ); + memset(&zBuf[101], 0, iAmt-101); + rbuPutU16(&zBuf[105], iAmt & 0xFFFF); + } + } + } } if( rc==SQLITE_OK && iOfst==0 && (p->openFlags & SQLITE_OPEN_MAIN_DB) ){ /* These look like magic numbers. But they are stable, as they are part @@ -3693,7 +3905,20 @@ static int rbuVfsSync(sqlite3_file *pFile, int flags){ */ static int rbuVfsFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){ rbu_file *p = (rbu_file *)pFile; - return p->pReal->pMethods->xFileSize(p->pReal, pSize); + int rc; + rc = p->pReal->pMethods->xFileSize(p->pReal, pSize); + + /* If this is an RBU vacuum operation and this is the target database, + ** pretend that it has at least one page. Otherwise, SQLite will not + ** check for the existance of a *-wal file. rbuVfsRead() contains + ** similar logic. */ + if( rc==SQLITE_OK && *pSize==0 + && p->pRbu && rbuIsVacuum(p->pRbu) + && (p->openFlags & SQLITE_OPEN_MAIN_DB) + ){ + *pSize = 1024; + } + return rc; } /* diff --git a/ext/rbu/sqlite3rbu.h b/ext/rbu/sqlite3rbu.h index f379bb5b41..b910866293 100644 --- a/ext/rbu/sqlite3rbu.h +++ b/ext/rbu/sqlite3rbu.h @@ -314,6 +314,14 @@ sqlite3rbu *sqlite3rbu_open( const char *zState ); +/* +** Open an RBU handle to perform an RBU vacuum database file zTarget. +*/ +sqlite3rbu *sqlite3rbu_vacuum( + const char *zTarget, + const char *zState +); + /* ** Internally, each RBU connection uses a separate SQLite database ** connection to access the target and rbu update databases. This diff --git a/ext/rbu/test_rbu.c b/ext/rbu/test_rbu.c index 5e8640a9f8..629a33cd0e 100644 --- a/ext/rbu/test_rbu.c +++ b/ext/rbu/test_rbu.c @@ -187,6 +187,34 @@ static int test_sqlite3rbu( return TCL_OK; } +/* +** Tclcmd: sqlite3rbu_vacuum CMD +*/ +static int test_sqlite3rbu_vacuum( + ClientData clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + sqlite3rbu *pRbu = 0; + const char *zCmd; + const char *zTarget; + const char *zStateDb = 0; + + if( objc!=4 ){ + Tcl_WrongNumArgs(interp, 1, objv, "NAME TARGET-DB STATE-DB"); + return TCL_ERROR; + } + zCmd = Tcl_GetString(objv[1]); + zTarget = Tcl_GetString(objv[2]); + zStateDb = Tcl_GetString(objv[3]); + + pRbu = sqlite3rbu_vacuum(zTarget, zStateDb); + Tcl_CreateObjCommand(interp, zCmd, test_sqlite3rbu_cmd, (ClientData)pRbu, 0); + Tcl_SetObjResult(interp, objv[1]); + return TCL_OK; +} + /* ** Tclcmd: sqlite3rbu_create_vfs ?-default? NAME PARENT */ @@ -274,6 +302,7 @@ int SqliteRbu_Init(Tcl_Interp *interp){ Tcl_ObjCmdProc *xProc; } aObjCmd[] = { { "sqlite3rbu", test_sqlite3rbu }, + { "sqlite3rbu_vacuum", test_sqlite3rbu_vacuum }, { "sqlite3rbu_create_vfs", test_sqlite3rbu_create_vfs }, { "sqlite3rbu_destroy_vfs", test_sqlite3rbu_destroy_vfs }, { "sqlite3rbu_internal_test", test_sqlite3rbu_internal_test }, diff --git a/manifest b/manifest index c039180bbf..91d7041221 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C CLI\senhancement:\s\sAdd\sthe\s".eqp\sfull"\soption,\sthat\sshows\sboth\sthe\sEXPLAIN\nQUERY\sPLAN\sand\sthe\sEXPLAIN\soutput\sfor\seach\scommand\srun.\s\sAlso\sdisable\nany\s".wheretrace"\sand\s".selecttrace"\swhen\sshowing\sEQP\soutput. -D 2016-04-15T15:03:27.144 +C Add\sthe\sexperimental\ssqlite3rbu_vacuum()\sAPI\sfunction.\sFor\sopening\san\sRBU\shandle\sthat\srebuilds\sa\sdatabase\sfrom\sscratch. +D 2016-04-15T20:46:41.467 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -246,9 +246,10 @@ F ext/rbu/rbufault2.test 9a7f19edd6ea35c4c9f807d8a3db0a03a5670c06 F ext/rbu/rbufts.test 828cd689da825f0a7b7c53ffc1f6f7fdb6fa5bda F ext/rbu/rbuprogress.test 2023a7df2c523e3df1cb532eff811cda385a789a F ext/rbu/rbusave.test 0f43b6686084f426ddd040b878426452fd2c2f48 -F ext/rbu/sqlite3rbu.c 9097f1d95666dbef72ca61d5b6a13a84660735ac -F ext/rbu/sqlite3rbu.h d7cc99350c10134f358fe1a8997d9225b3f712b2 -F ext/rbu/test_rbu.c 3505641a78b723589b8780d5f9b2faeeb73e037d +F ext/rbu/rbuvacuum.test 75b4231f85622859e814c7f028afad0303f72f60 +F ext/rbu/sqlite3rbu.c 79b8be4a0c8276b2b2b24c88edf3944216ccd35b +F ext/rbu/sqlite3rbu.h 1342ab6121e715b8da59ec35c5b5c16060be7a6b +F ext/rbu/test_rbu.c 430b8b9520c233505371d564d3561e0b554355f4 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 F ext/rtree/rtree.c 0b870ccb7b58b734a2a8e1e2755a7c0ded070920 F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e @@ -1482,7 +1483,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d23e581351fb8eea28e7b13b3dcadfc817c3a05f -R e880e1f26ac9fef78137656188a6e0aa -U drh -Z dc2294cde78bca18f07e3e2fb59a4dd5 +P 3e217d6265ecd16db783bed7ce1d9d0f9c4828bb +R d2c575fe1215bc1b298a105940b3f837 +T *branch * rbu-vacuum +T *sym-rbu-vacuum * +T -sym-trunk * +U dan +Z af92587ff7c9268b9a60aaab80a1a468 diff --git a/manifest.uuid b/manifest.uuid index 453393af12..66b85c22cc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3e217d6265ecd16db783bed7ce1d9d0f9c4828bb \ No newline at end of file +0216b48f28042ad86711e00802c2da8ce9be3044 \ No newline at end of file From ee65eea4af7d4eec9f0c17d39236faffcb10678c Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 16 Apr 2016 15:03:20 +0000 Subject: [PATCH 0313/1484] Fix a couple of assert() statements that were failing with OOM error tests. FossilOrigin-Name: 8eb3d7d8360530f364bbbebac53e1f0e6753d924 --- manifest | 15 ++++++--------- manifest.uuid | 2 +- src/expr.c | 4 ++-- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 91d7041221..eeb8cf07ef 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sexperimental\ssqlite3rbu_vacuum()\sAPI\sfunction.\sFor\sopening\san\sRBU\shandle\sthat\srebuilds\sa\sdatabase\sfrom\sscratch. -D 2016-04-15T20:46:41.467 +C Fix\sa\scouple\sof\sassert()\sstatements\sthat\swere\sfailing\swith\sOOM\serror\stests. +D 2016-04-16T15:03:20.537 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -330,7 +330,7 @@ F src/ctime.c 60e135af364d777a9ab41c97e5e89cd224da6198 F src/date.c 1cc9fb516ec9932c6fd4d2a0d2f8bc4480145c39 F src/dbstat.c c845548d4346e606e2f2b7d2e714ace2b8a7dd1b F src/delete.c 78eb999114ec04fcf1b7d123ccedb4b5b734930e -F src/expr.c 17d4e745ef6a3fd2e4ef863f5f9a4912f1ba1198 +F src/expr.c 8796c0739b2ad091e6779253f62aad6e767e2be1 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 4c0bd09e602b8ae8d36d81e31e4872d0b53c87bb F src/func.c 552d300265aed09eea21f68ac742a440550c0062 @@ -1483,10 +1483,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 3e217d6265ecd16db783bed7ce1d9d0f9c4828bb -R d2c575fe1215bc1b298a105940b3f837 -T *branch * rbu-vacuum -T *sym-rbu-vacuum * -T -sym-trunk * +P 0216b48f28042ad86711e00802c2da8ce9be3044 +R 0603f47373db6aeb2d2c22dfe403e0e2 U dan -Z af92587ff7c9268b9a60aaab80a1a468 +Z 6e5ab10ab6efe323abcf341183f13408 diff --git a/manifest.uuid b/manifest.uuid index 66b85c22cc..773e6bf755 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0216b48f28042ad86711e00802c2da8ce9be3044 \ No newline at end of file +8eb3d7d8360530f364bbbebac53e1f0e6753d924 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 094a454ab1..9e3b664e8d 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2360,7 +2360,7 @@ static void cacheEntryClear(Parse *pParse, struct yColCache *p){ } p->iReg = 0; pParse->nColCache--; - assert( cacheIsValid(pParse) ); + assert( pParse->db->mallocFailed || cacheIsValid(pParse) ); } @@ -2405,7 +2405,7 @@ void sqlite3ExprCacheStore(Parse *pParse, int iTab, int iCol, int iReg){ p->tempReg = 0; p->lru = pParse->iCacheCnt++; pParse->nColCache++; - assert( cacheIsValid(pParse) ); + assert( pParse->db->mallocFailed || cacheIsValid(pParse) ); return; } } From 977cbe78b3945be39c0e353c77e25d6e1d161d35 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 16 Apr 2016 17:53:14 +0000 Subject: [PATCH 0314/1484] Avoid creating any extra files ("-vacuum") when running an RBU vacuum. Ensure that the OAL file created is "-oal", not "-vacuum-oal". FossilOrigin-Name: dc19aacc7e99213edca9bb57b5c11a8a1ac99113 --- ext/rbu/sqlite3rbu.c | 147 ++++++++++++++++++++++--------------------- manifest | 12 ++-- manifest.uuid | 2 +- 3 files changed, 84 insertions(+), 77 deletions(-) diff --git a/ext/rbu/sqlite3rbu.c b/ext/rbu/sqlite3rbu.c index e71690769b..ff01f30725 100644 --- a/ext/rbu/sqlite3rbu.c +++ b/ext/rbu/sqlite3rbu.c @@ -2323,6 +2323,7 @@ static RbuState *rbuLoadState(sqlite3rbu *p){ static void rbuOpenDatabase(sqlite3rbu *p){ assert( p->rc==SQLITE_OK ); assert( p->dbMain==0 && p->dbRbu==0 ); + assert( rbuIsVacuum(p) || p->zTarget!=0 ); /* Open the RBU database */ p->dbRbu = rbuOpenDbhandle(p, p->zRbu); @@ -2355,16 +2356,21 @@ static void rbuOpenDatabase(sqlite3rbu *p){ p->eStage = 0; if( p->dbMain==0 ){ - if( p->zTarget ){ + if( !rbuIsVacuum(p) ){ p->dbMain = rbuOpenDbhandle(p, p->zTarget); }else{ - char *zTarget = sqlite3_mprintf("%s-vacuum", p->zRbu); + char *zTarget = sqlite3_mprintf("file:%s-vacuum?rbu_memory=1", p->zRbu); if( zTarget==0 ){ p->rc = SQLITE_NOMEM; return; } p->dbMain = rbuOpenDbhandle(p, zTarget); sqlite3_free(zTarget); + if( p->rc==SQLITE_OK ){ + p->rc = sqlite3_exec(p->dbMain, + "PRAGMA journal_mode=off; BEGIN EXCLUSIVE; COMMIT;", 0, 0, 0 + ); + } } } @@ -2641,14 +2647,15 @@ static LPWSTR rbuWinUtf8ToUnicode(const char *zFilename){ */ static void rbuMoveOalFile(sqlite3rbu *p){ const char *zBase = sqlite3_db_filename(p->dbMain, "main"); - char *zOal = sqlite3_mprintf("%s-oal", zBase); + const char *zMove = zBase; + char *zOal; char *zWal; if( rbuIsVacuum(p) ){ - zWal = sqlite3_mprintf("%s-wal", sqlite3_db_filename(p->dbRbu, "main")); - }else{ - zWal = sqlite3_mprintf("%s-wal", zBase); + zMove = sqlite3_db_filename(p->dbRbu, "main"); } + zOal = sqlite3_mprintf("%s-oal", zMove); + zWal = sqlite3_mprintf("%s-wal", zMove); assert( p->eStage==RBU_STAGE_MOVE ); assert( p->rc==SQLITE_OK && p->zErrmsg==0 ); @@ -2928,13 +2935,18 @@ static int rbuStep(sqlite3rbu *p){ /* ** Increment the schema cookie of the main database opened by p->dbMain. +** +** Or, if this is an RBU vacuum, set the schema cookie of the main db +** opened by p->dbMain to one more than the schema cookie of the main +** db opened by p->dbRbu. */ static void rbuIncrSchemaCookie(sqlite3rbu *p){ if( p->rc==SQLITE_OK ){ + sqlite3 *dbread = (rbuIsVacuum(p) ? p->dbRbu : p->dbMain); int iCookie = 1000000; sqlite3_stmt *pStmt; - p->rc = prepareAndCollectError(p->dbMain, &pStmt, &p->zErrmsg, + p->rc = prepareAndCollectError(dbread, &pStmt, &p->zErrmsg, "PRAGMA schema_version" ); if( p->rc==SQLITE_OK ){ @@ -3408,6 +3420,7 @@ static sqlite3rbu *openRbuHandle( } if( p->rc==SQLITE_OK + && !rbuIsVacuum(p) && (p->eStage==RBU_STAGE_OAL || p->eStage==RBU_STAGE_MOVE) && pState->eStage!=0 && p->pTargetFd->iCookie!=pState->iCookie ){ @@ -3803,34 +3816,6 @@ static int rbuVfsRead( memset(zBuf, 0, iAmt); }else{ rc = p->pReal->pMethods->xRead(p->pReal, zBuf, iAmt, iOfst); - /* If this is being called to read the first page of the target - ** database as part of an rbu vacuum operation, synthesize the - ** contents of the first page if it does not yet exist. Otherwise, - ** SQLite will not check for a *-wal file. */ - if( p->pRbu && rbuIsVacuum(p->pRbu) - && rc==SQLITE_IOERR_SHORT_READ && iOfst==0 - && (p->openFlags & SQLITE_OPEN_MAIN_DB) - ){ - sqlite3_file *pFd = 0; - rc = sqlite3_file_control( - p->pRbu->dbRbu, "main", SQLITE_FCNTL_FILE_POINTER, (void*)&pFd - ); - if( rc==SQLITE_OK ){ - rc = pFd->pMethods->xRead(pFd, zBuf, iAmt, iOfst); - } - if( rc==SQLITE_OK ){ - rbuPutU32(&zBuf[52], 0); /* largest root page number */ - rbuPutU32(&zBuf[36], 0); /* number of free pages */ - rbuPutU32(&zBuf[32], 0); /* first page on free list trunk */ - rbuPutU32(&zBuf[28], 1); /* size of db file in pages */ - - if( iAmt>100 ){ - assert( iAmt>=101 ); - memset(&zBuf[101], 0, iAmt-101); - rbuPutU16(&zBuf[105], iAmt & 0xFFFF); - } - } - } } if( rc==SQLITE_OK && iOfst==0 && (p->openFlags & SQLITE_OPEN_MAIN_DB) ){ /* These look like magic numbers. But they are stable, as they are part @@ -3838,6 +3823,13 @@ static int rbuVfsRead( u8 *pBuf = (u8*)zBuf; p->iCookie = rbuGetU32(&pBuf[24]); p->iWriteVer = pBuf[19]; + if( pRbu && rbuIsVacuum(p->pRbu) ){ + rbu_file *pRbuFd = 0; + sqlite3_file_control(pRbu->dbRbu, "main", + SQLITE_FCNTL_FILE_POINTER, (void*)&pRbuFd + ); + rbuPutU32(&pBuf[24], pRbuFd->iCookie+1); + } } } return rc; @@ -3905,20 +3897,7 @@ static int rbuVfsSync(sqlite3_file *pFile, int flags){ */ static int rbuVfsFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){ rbu_file *p = (rbu_file *)pFile; - int rc; - rc = p->pReal->pMethods->xFileSize(p->pReal, pSize); - - /* If this is an RBU vacuum operation and this is the target database, - ** pretend that it has at least one page. Otherwise, SQLite will not - ** check for the existance of a *-wal file. rbuVfsRead() contains - ** similar logic. */ - if( rc==SQLITE_OK && *pSize==0 - && p->pRbu && rbuIsVacuum(p->pRbu) - && (p->openFlags & SQLITE_OPEN_MAIN_DB) - ){ - *pSize = 1024; - } - return rc; + return p->pReal->pMethods->xFileSize(p->pReal, pSize); } /* @@ -4156,6 +4135,33 @@ static rbu_file *rbuFindMaindb(rbu_vfs *pRbuVfs, const char *zWal){ return pDb; } +/* +** A main database named zName has just been opened. The following +** function returns a pointer to a buffer owned by SQLite that contains +** the name of the *-wal file this db connection will use. SQLite +** happens to pass a pointer to this buffer when using xAccess() +** or xOpen() to operate on the *-wal file. +*/ +static const char *rbuMainToWal(const char *zName, int flags){ + int n = (int)strlen(zName); + const char *z = &zName[n]; + if( flags & SQLITE_OPEN_URI ){ + int odd = 0; + while( 1 ){ + if( z[0]==0 ){ + odd = 1 - odd; + if( odd && z[1]==0 ) break; + } + z++; + } + z += 2; + }else{ + while( *z==0 ) z++; + } + z += (n + 8 + 1); + return z; +} + /* ** Open an rbu file handle. */ @@ -4191,6 +4197,7 @@ static int rbuVfsOpen( rbu_file *pFd = (rbu_file *)pFile; int rc = SQLITE_OK; const char *zOpen = zName; + int oflags = flags; memset(pFd, 0, sizeof(rbu_file)); pFd->pReal = (sqlite3_file*)&pFd[1]; @@ -4203,23 +4210,7 @@ static int rbuVfsOpen( ** the name of the *-wal file this db connection will use. SQLite ** happens to pass a pointer to this buffer when using xAccess() ** or xOpen() to operate on the *-wal file. */ - int n = (int)strlen(zName); - const char *z = &zName[n]; - if( flags & SQLITE_OPEN_URI ){ - int odd = 0; - while( 1 ){ - if( z[0]==0 ){ - odd = 1 - odd; - if( odd && z[1]==0 ) break; - } - z++; - } - z += 2; - }else{ - while( *z==0 ) z++; - } - z += (n + 8 + 1); - pFd->zWal = z; + pFd->zWal = rbuMainToWal(zName, flags); } else if( flags & SQLITE_OPEN_WAL ){ rbu_file *pDb = rbuFindMaindb(pRbuVfs, zName); @@ -4229,10 +4220,17 @@ static int rbuVfsOpen( ** code ensures that the string passed to xOpen() is terminated by a ** pair of '\0' bytes in case the VFS attempts to extract a URI ** parameter from it. */ - size_t nCopy = strlen(zName); - char *zCopy = sqlite3_malloc64(nCopy+2); + const char *zBase = zName; + size_t nCopy; + char *zCopy; + if( rbuIsVacuum(pDb->pRbu) ){ + zBase = sqlite3_db_filename(pDb->pRbu->dbRbu, "main"); + zBase = rbuMainToWal(zBase, SQLITE_OPEN_URI); + } + nCopy = strlen(zBase); + zCopy = sqlite3_malloc64(nCopy+2); if( zCopy ){ - memcpy(zCopy, zName, nCopy); + memcpy(zCopy, zBase, nCopy); zCopy[nCopy-3] = 'o'; zCopy[nCopy] = '\0'; zCopy[nCopy+1] = '\0'; @@ -4247,8 +4245,17 @@ static int rbuVfsOpen( } } + if( oflags & SQLITE_OPEN_MAIN_DB + && sqlite3_uri_boolean(zName, "rbu_memory", 0) + ){ + assert( oflags & SQLITE_OPEN_MAIN_DB ); + oflags = SQLITE_OPEN_TEMP_DB | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | + SQLITE_OPEN_EXCLUSIVE | SQLITE_OPEN_DELETEONCLOSE; + zOpen = 0; + } + if( rc==SQLITE_OK ){ - rc = pRealVfs->xOpen(pRealVfs, zOpen, pFd->pReal, flags, pOutFlags); + rc = pRealVfs->xOpen(pRealVfs, zOpen, pFd->pReal, oflags, pOutFlags); } if( pFd->pReal->pMethods ){ /* The xOpen() operation has succeeded. Set the sqlite3_file.pMethods diff --git a/manifest b/manifest index eeb8cf07ef..0e404f7022 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\scouple\sof\sassert()\sstatements\sthat\swere\sfailing\swith\sOOM\serror\stests. -D 2016-04-16T15:03:20.537 +C Avoid\screating\sany\sextra\sfiles\s("-vacuum")\swhen\srunning\san\sRBU\svacuum.\sEnsure\sthat\sthe\sOAL\sfile\screated\sis\s"-oal",\snot\s"-vacuum-oal". +D 2016-04-16T17:53:14.824 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -247,7 +247,7 @@ F ext/rbu/rbufts.test 828cd689da825f0a7b7c53ffc1f6f7fdb6fa5bda F ext/rbu/rbuprogress.test 2023a7df2c523e3df1cb532eff811cda385a789a F ext/rbu/rbusave.test 0f43b6686084f426ddd040b878426452fd2c2f48 F ext/rbu/rbuvacuum.test 75b4231f85622859e814c7f028afad0303f72f60 -F ext/rbu/sqlite3rbu.c 79b8be4a0c8276b2b2b24c88edf3944216ccd35b +F ext/rbu/sqlite3rbu.c 471b4055618473612e9ae7d7e4f1922559b59aaf F ext/rbu/sqlite3rbu.h 1342ab6121e715b8da59ec35c5b5c16060be7a6b F ext/rbu/test_rbu.c 430b8b9520c233505371d564d3561e0b554355f4 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 @@ -1483,7 +1483,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 0216b48f28042ad86711e00802c2da8ce9be3044 -R 0603f47373db6aeb2d2c22dfe403e0e2 +P 8eb3d7d8360530f364bbbebac53e1f0e6753d924 +R 4d03a7f5bef5f70852d283bb46ff80e2 U dan -Z 6e5ab10ab6efe323abcf341183f13408 +Z 0a7d529e6f2d77bae387935d2996f1da diff --git a/manifest.uuid b/manifest.uuid index 773e6bf755..56172c7c76 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8eb3d7d8360530f364bbbebac53e1f0e6753d924 \ No newline at end of file +dc19aacc7e99213edca9bb57b5c11a8a1ac99113 \ No newline at end of file From 2bb5f4478ea2c4fc2e5889a1586153e394f37ffd Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 16 Apr 2016 19:02:53 +0000 Subject: [PATCH 0315/1484] Changes so that rbu vacuum works with zipvfs databases. FossilOrigin-Name: bae7f875f476f6e01112751cb404fef42ba0a01c --- ext/rbu/sqlite3rbu.c | 32 ++++++++++++++------------------ manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 21 insertions(+), 25 deletions(-) diff --git a/ext/rbu/sqlite3rbu.c b/ext/rbu/sqlite3rbu.c index ff01f30725..280b64bb2a 100644 --- a/ext/rbu/sqlite3rbu.c +++ b/ext/rbu/sqlite3rbu.c @@ -2213,11 +2213,15 @@ static int rbuGetUpdateStmt( return p->rc; } -static sqlite3 *rbuOpenDbhandle(sqlite3rbu *p, const char *zName){ +static sqlite3 *rbuOpenDbhandle( + sqlite3rbu *p, + const char *zName, + int bUseVfs +){ sqlite3 *db = 0; if( p->rc==SQLITE_OK ){ const int flags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_URI; - p->rc = sqlite3_open_v2(zName, &db, flags, p->zVfsName); + p->rc = sqlite3_open_v2(zName, &db, flags, bUseVfs ? p->zVfsName : 0); if( p->rc ){ p->zErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(db)); sqlite3_close(db); @@ -2326,7 +2330,7 @@ static void rbuOpenDatabase(sqlite3rbu *p){ assert( rbuIsVacuum(p) || p->zTarget!=0 ); /* Open the RBU database */ - p->dbRbu = rbuOpenDbhandle(p, p->zRbu); + p->dbRbu = rbuOpenDbhandle(p, p->zRbu, 1); /* If using separate RBU and state databases, attach the state database to ** the RBU db handle now. */ @@ -2351,24 +2355,26 @@ static void rbuOpenDatabase(sqlite3rbu *p){ rbuFreeState(pState); } } - if( bOpen ) p->dbMain = rbuOpenDbhandle(p, p->zRbu); + if( bOpen ) p->dbMain = rbuOpenDbhandle(p, p->zRbu, 1); } p->eStage = 0; if( p->dbMain==0 ){ if( !rbuIsVacuum(p) ){ - p->dbMain = rbuOpenDbhandle(p, p->zTarget); + p->dbMain = rbuOpenDbhandle(p, p->zTarget, 1); }else{ + int frc = sqlite3_file_control(p->dbRbu, "main", SQLITE_FCNTL_ZIPVFS, 0); char *zTarget = sqlite3_mprintf("file:%s-vacuum?rbu_memory=1", p->zRbu); if( zTarget==0 ){ p->rc = SQLITE_NOMEM; return; } - p->dbMain = rbuOpenDbhandle(p, zTarget); + p->dbMain = rbuOpenDbhandle(p, zTarget, frc!=SQLITE_OK); sqlite3_free(zTarget); if( p->rc==SQLITE_OK ){ p->rc = sqlite3_exec(p->dbMain, - "PRAGMA journal_mode=off; BEGIN EXCLUSIVE; COMMIT;", 0, 0, 0 + "PRAGMA journal_mode=off; PRAGMA zipvfs_journal_mode = off;" + "BEGIN EXCLUSIVE; COMMIT;", 0, 0, 0 ); } } @@ -3310,7 +3316,6 @@ static void rbuInitPhaseOneSteps(sqlite3rbu *p){ static void rbuCreateTargetSchema(sqlite3rbu *p){ sqlite3_stmt *pSql = 0; sqlite3_stmt *pInsert = 0; - int rc2; assert( rbuIsVacuum(p) ); @@ -3319,7 +3324,7 @@ static void rbuCreateTargetSchema(sqlite3rbu *p){ " ORDER BY type DESC" ); while( p->rc==SQLITE_OK && sqlite3_step(pSql)==SQLITE_ROW ){ - const char *zSql = sqlite3_column_text(pSql, 0); + const char *zSql = (const char*)sqlite3_column_text(pSql, 0); p->rc = sqlite3_exec(p->dbMain, zSql, 0, 0, &p->zErrmsg); } rbuFinalize(p, pSql); @@ -3782,15 +3787,6 @@ static void rbuPutU32(u8 *aBuf, u32 iVal){ aBuf[3] = (iVal >> 0) & 0xFF; } -/* -** Write an unsigned 16-bit value in big-endian format to the supplied -** buffer. -*/ -static void rbuPutU16(u8 *aBuf, u16 iVal){ - aBuf[0] = (iVal >> 8) & 0xFF; - aBuf[1] = (iVal >> 0) & 0xFF; -} - /* ** Read data from an rbuVfs-file. */ diff --git a/manifest b/manifest index 0e404f7022..bcd6ca601c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\screating\sany\sextra\sfiles\s("-vacuum")\swhen\srunning\san\sRBU\svacuum.\sEnsure\sthat\sthe\sOAL\sfile\screated\sis\s"-oal",\snot\s"-vacuum-oal". -D 2016-04-16T17:53:14.824 +C Changes\sso\sthat\srbu\svacuum\sworks\swith\szipvfs\sdatabases. +D 2016-04-16T19:02:53.248 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -247,7 +247,7 @@ F ext/rbu/rbufts.test 828cd689da825f0a7b7c53ffc1f6f7fdb6fa5bda F ext/rbu/rbuprogress.test 2023a7df2c523e3df1cb532eff811cda385a789a F ext/rbu/rbusave.test 0f43b6686084f426ddd040b878426452fd2c2f48 F ext/rbu/rbuvacuum.test 75b4231f85622859e814c7f028afad0303f72f60 -F ext/rbu/sqlite3rbu.c 471b4055618473612e9ae7d7e4f1922559b59aaf +F ext/rbu/sqlite3rbu.c 721c6c116018b5d02f6318b6bbb7834098bc6a07 F ext/rbu/sqlite3rbu.h 1342ab6121e715b8da59ec35c5b5c16060be7a6b F ext/rbu/test_rbu.c 430b8b9520c233505371d564d3561e0b554355f4 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 @@ -1483,7 +1483,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 8eb3d7d8360530f364bbbebac53e1f0e6753d924 -R 4d03a7f5bef5f70852d283bb46ff80e2 +P dc19aacc7e99213edca9bb57b5c11a8a1ac99113 +R 51e4311e92cd324079b6a63abfa03656 U dan -Z 0a7d529e6f2d77bae387935d2996f1da +Z c0a4c5c182b536f7f5ddad73d82153a8 diff --git a/manifest.uuid b/manifest.uuid index 56172c7c76..3a2c90ce4f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -dc19aacc7e99213edca9bb57b5c11a8a1ac99113 \ No newline at end of file +bae7f875f476f6e01112751cb404fef42ba0a01c \ No newline at end of file From 303a094466c7c5bb76e80cac61c79123b4b95c41 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 18 Apr 2016 09:17:05 +0000 Subject: [PATCH 0316/1484] Add the -vacuum switch to the "rbu" demonstration program. FossilOrigin-Name: 9a0078a538c7e73a009960347b8953c5af99fefd --- ext/rbu/rbu.c | 56 ++++++++++++++++++++++++++++++++++++--------------- manifest | 12 +++++------ manifest.uuid | 2 +- 3 files changed, 47 insertions(+), 23 deletions(-) diff --git a/ext/rbu/rbu.c b/ext/rbu/rbu.c index 018296b8dd..a3efad0d44 100644 --- a/ext/rbu/rbu.c +++ b/ext/rbu/rbu.c @@ -24,12 +24,22 @@ */ void usage(const char *zArgv0){ fprintf(stderr, -"Usage: %s [-step NSTEP] TARGET-DB RBU-DB\n" +"Usage: %s ?OPTIONS? TARGET-DB RBU-DB\n" "\n" -" Argument RBU-DB must be an RBU database containing an update suitable for\n" -" target database TARGET-DB. If NSTEP is set to less than or equal to zero\n" -" (the default value), this program attempts to apply the entire update to\n" -" the target database.\n" +"Where options are:\n" +"\n" +" -step NSTEP\n" +" -vacuum\n" +"\n" +" If the -vacuum switch is not present, argument RBU-DB must be an RBU\n" +" database containing an update suitable for target database TARGET-DB.\n" +" Or, if -vacuum is specified, then TARGET-DB is a database to vacuum using\n" +" RBU, and RBU-DB is used as the state database for the vacuum (refer to\n" +" API documentation for details).\n" +"\n" +" If NSTEP is set to less than or equal to zero (the default value), this \n" +" program attempts to perform the entire update or vacuum operation before\n" +" exiting\n" "\n" " If NSTEP is greater than zero, then a maximum of NSTEP calls are made\n" " to sqlite3rbu_step(). If the RBU update has not been completely applied\n" @@ -69,29 +79,43 @@ int main(int argc, char **argv){ char *zErrmsg; /* Error message, if any */ sqlite3rbu *pRbu; /* RBU handle */ int nStep = 0; /* Maximum number of step() calls */ + int bVacuum = 0; int rc; sqlite3_int64 nProgress = 0; + int nArg = argc-2; - /* Process command line arguments. Following this block local variables - ** zTarget, zRbu and nStep are all set. */ - if( argc==5 ){ - size_t nArg1 = strlen(argv[1]); - if( nArg1>5 || nArg1<2 || memcmp("-step", argv[1], nArg1) ) usage(argv[0]); - nStep = atoi(argv[2]); - }else if( argc!=3 ){ - usage(argv[0]); + if( argc<3 ) usage(argv[0]); + for(i=1; i1 && nArg<=8 && 0==memcmp(zArg, "-vacuum", nArg) ){ + bVacuum = 1; + }else if( nArg>1 && nArg<=5 && 0==memcmp(zArg, "-step", nArg) && i Date: Mon, 18 Apr 2016 13:09:55 +0000 Subject: [PATCH 0317/1484] The last parameter to pread64() and pwrite64() should be off64_t, not off_t. FossilOrigin-Name: 3a7d72986fabe9434ff5bd02c93169314f072b23 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/os_unix.c | 4 ++-- src/test_syscall.c | 15 +++++++++------ 4 files changed, 19 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index c039180bbf..658ad56d1a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C CLI\senhancement:\s\sAdd\sthe\s".eqp\sfull"\soption,\sthat\sshows\sboth\sthe\sEXPLAIN\nQUERY\sPLAN\sand\sthe\sEXPLAIN\soutput\sfor\seach\scommand\srun.\s\sAlso\sdisable\nany\s".wheretrace"\sand\s".selecttrace"\swhen\sshowing\sEQP\soutput. -D 2016-04-15T15:03:27.144 +C The\slast\sparameter\sto\spread64()\sand\spwrite64()\sshould\sbe\soff64_t,\snot\soff_t. +D 2016-04-18T13:09:55.691 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -359,7 +359,7 @@ F src/os.c 4d83917f072ad958fba9235136fa2ed43df47905 F src/os.h 8e976e59eb4ca1c0fca6d35ee803e38951cb0343 F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85 F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa -F src/os_unix.c bde4844f0849cab5924c6a81178f8500774ce76b +F src/os_unix.c d0b41a47eb5f0dc00e423a1723aadeab0e78c85f F src/os_win.c b169437dff859e308b3726594094a2f8ca922941 F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c 38718a019ca762ba4f6795425d5a54db70d1790d @@ -425,7 +425,7 @@ F src/test_schema.c 2bdba21b82f601da69793e1f1d11bf481a79b091 F src/test_server.c a2615049954cbb9cfb4a62e18e2f0616e4dc38fe F src/test_sqllog.c 0d138a8180a312bf996b37fa66da5c5799d4d57b F src/test_superlock.c 06797157176eb7085027d9dd278c0d7a105e3ec9 -F src/test_syscall.c 2e21ca7f7dc54a028f1967b63f1e76155c356f9b +F src/test_syscall.c 4889d374f5a5856b7951f7a67c6401f7b938c6f5 F src/test_tclvar.c d86412527da65468ee6fa1b8607c65d0af736bc4 F src/test_thread.c af391ec03d23486dffbcc250b7e58e073f172af9 F src/test_vfs.c 4d02f38bfb8f7f273da7ba84bfe000f5babf206c @@ -1482,7 +1482,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d23e581351fb8eea28e7b13b3dcadfc817c3a05f -R e880e1f26ac9fef78137656188a6e0aa +P 3e217d6265ecd16db783bed7ce1d9d0f9c4828bb +R 436b9ab5479b24882bf9b5114230dd45 U drh -Z dc2294cde78bca18f07e3e2fb59a4dd5 +Z ed45643e1c73eeadd299c981e6f9488a diff --git a/manifest.uuid b/manifest.uuid index 453393af12..9d96c70fe9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3e217d6265ecd16db783bed7ce1d9d0f9c4828bb \ No newline at end of file +3a7d72986fabe9434ff5bd02c93169314f072b23 \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index a797541e8f..aa86f00d70 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -405,7 +405,7 @@ static struct unix_syscall { #else { "pread64", (sqlite3_syscall_ptr)0, 0 }, #endif -#define osPread64 ((ssize_t(*)(int,void*,size_t,off_t))aSyscall[10].pCurrent) +#define osPread64 ((ssize_t(*)(int,void*,size_t,off64_t))aSyscall[10].pCurrent) { "write", (sqlite3_syscall_ptr)write, 0 }, #define osWrite ((ssize_t(*)(int,const void*,size_t))aSyscall[11].pCurrent) @@ -423,7 +423,7 @@ static struct unix_syscall { #else { "pwrite64", (sqlite3_syscall_ptr)0, 0 }, #endif -#define osPwrite64 ((ssize_t(*)(int,const void*,size_t,off_t))\ +#define osPwrite64 ((ssize_t(*)(int,const void*,size_t,off64_t))\ aSyscall[13].pCurrent) { "fchmod", (sqlite3_syscall_ptr)fchmod, 0 }, diff --git a/src/test_syscall.c b/src/test_syscall.c index 0dac2e897e..f9abc1e46d 100644 --- a/src/test_syscall.c +++ b/src/test_syscall.c @@ -108,10 +108,13 @@ static int ts_ftruncate(int fd, off_t n); static int ts_fcntl(int fd, int cmd, ... ); static int ts_read(int fd, void *aBuf, size_t nBuf); static int ts_pread(int fd, void *aBuf, size_t nBuf, off_t off); -static int ts_pread64(int fd, void *aBuf, size_t nBuf, off_t off); +/* Note: pread64() and pwrite64() actually use off64_t as the type on their +** last parameter. But that datatype is not defined on many systems +** (ex: Mac, OpenBSD). So substitute a likely equivalent: sqlite3_uint64 */ +static int ts_pread64(int fd, void *aBuf, size_t nBuf, sqlite3_uint64 off); static int ts_write(int fd, const void *aBuf, size_t nBuf); static int ts_pwrite(int fd, const void *aBuf, size_t nBuf, off_t off); -static int ts_pwrite64(int fd, const void *aBuf, size_t nBuf, off_t off); +static int ts_pwrite64(int fd, const void *aBuf, size_t nBuf, sqlite3_uint64 off); static int ts_fchmod(int fd, mode_t mode); static int ts_fallocate(int fd, off_t off, off_t len); static void *ts_mmap(void *, size_t, int, int, int, off_t); @@ -155,11 +158,11 @@ struct TestSyscallArray { #define orig_fcntl ((int(*)(int,int,...))aSyscall[7].xOrig) #define orig_read ((ssize_t(*)(int,void*,size_t))aSyscall[8].xOrig) #define orig_pread ((ssize_t(*)(int,void*,size_t,off_t))aSyscall[9].xOrig) -#define orig_pread64 ((ssize_t(*)(int,void*,size_t,off_t))aSyscall[10].xOrig) +#define orig_pread64 ((ssize_t(*)(int,void*,size_t,sqlite3_uint64))aSyscall[10].xOrig) #define orig_write ((ssize_t(*)(int,const void*,size_t))aSyscall[11].xOrig) #define orig_pwrite ((ssize_t(*)(int,const void*,size_t,off_t))\ aSyscall[12].xOrig) -#define orig_pwrite64 ((ssize_t(*)(int,const void*,size_t,off_t))\ +#define orig_pwrite64 ((ssize_t(*)(int,const void*,size_t,sqlite3_uint64))\ aSyscall[13].xOrig) #define orig_fchmod ((int(*)(int,mode_t))aSyscall[14].xOrig) #define orig_fallocate ((int(*)(int,off_t,off_t))aSyscall[15].xOrig) @@ -326,7 +329,7 @@ static int ts_pread(int fd, void *aBuf, size_t nBuf, off_t off){ /* ** A wrapper around pread64(). */ -static int ts_pread64(int fd, void *aBuf, size_t nBuf, off_t off){ +static int ts_pread64(int fd, void *aBuf, size_t nBuf, sqlite3_uint64 off){ if( tsIsFailErrno("pread64") ){ return -1; } @@ -357,7 +360,7 @@ static int ts_pwrite(int fd, const void *aBuf, size_t nBuf, off_t off){ /* ** A wrapper around pwrite64(). */ -static int ts_pwrite64(int fd, const void *aBuf, size_t nBuf, off_t off){ +static int ts_pwrite64(int fd, const void *aBuf, size_t nBuf, sqlite3_uint64 off){ if( tsIsFailErrno("pwrite64") ){ return -1; } From b5895e50f980b7cb41c68073902bcfe1e4f81168 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 18 Apr 2016 13:30:50 +0000 Subject: [PATCH 0318/1484] sqlite3PCachePerecentDirty() should return 0 if the pcache is empty. FossilOrigin-Name: 85f3d80eb7319754792eef76996b2c740a2b0073 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/pcache.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index acc14071dc..4b67df4189 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\senhancements\sfrom\strunk\svia\stempfiles-lazy-open. -D 2016-04-13T19:20:23.336 +C sqlite3PCachePerecentDirty()\sshould\sreturn\s0\sif\sthe\spcache\sis\sempty. +D 2016-04-18T13:30:50.144 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -365,7 +365,7 @@ F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c 4d849ad718980d698157cd136a40dc91cbeff4d3 F src/pager.h e1d38a2f14849e219df0f91f8323504d134c8a56 F src/parse.y 10eb2f3fb62341291528c7984498054731f9d31e -F src/pcache.c d63b34cce0a8aba1fa552428b2790e13877db553 +F src/pcache.c b3230ecfc7f797063fbe167f2845da363e8f07f8 F src/pcache.h 60bc9893bfc0e16f8178fb5d8b6fcb8fab1d93c0 F src/pcache1.c c40cdb93586e21b5dd826b5e671240bd91c26b05 F src/pragma.c faf42922bb7ab2f6672cb550356c1967abae3c84 @@ -1484,7 +1484,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P f6babf2920340f25815c0a3c58de1e902c2f5542 e2edd34e79af906e7069e3e837730b12de0b73fe -R ae2dffba3d0e430c251b8372421692c3 +P ae16310c4e9a9b7e94874bd912fc6a4324cfaa2b +R 0620b8f840563243b73e6076ebdcd81f U drh -Z 2aed413a070df399f71581c0517ce593 +Z 04d9a6e624a4591b3aa3f8ec5734f1ff diff --git a/manifest.uuid b/manifest.uuid index de9f4ee7ee..9ac43a726e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ae16310c4e9a9b7e94874bd912fc6a4324cfaa2b \ No newline at end of file +85f3d80eb7319754792eef76996b2c740a2b0073 \ No newline at end of file diff --git a/src/pcache.c b/src/pcache.c index 561672b9ce..f700c2ff66 100644 --- a/src/pcache.c +++ b/src/pcache.c @@ -695,7 +695,7 @@ int sqlite3PCachePercentDirty(PCache *pCache){ int nDirty = 0; int nCache = numberOfCachePages(pCache); for(pDirty=pCache->pDirty; pDirty; pDirty=pDirty->pDirtyNext) nDirty++; - return (int)(((i64)nDirty * 100) / nCache); + return nCache ? (int)(((i64)nDirty * 100) / nCache) : 0; } #if defined(SQLITE_CHECK_PAGES) || defined(SQLITE_DEBUG) From a6dddd9bde0844ad453150954571dcf1af8dccbd Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 18 Apr 2016 15:46:14 +0000 Subject: [PATCH 0319/1484] Remove quotes from identifiers used as datatype names in a CREATE TABLE statement. Fix for ticket [7d7525cb01b68] FossilOrigin-Name: eba27d4d17a76884292667d570d542e580ee3e77 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/build.c | 1 + test/intpkey.test | 11 +++++++++++ test/pragma.test | 4 ++-- 5 files changed, 23 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 658ad56d1a..eb27e8449c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C The\slast\sparameter\sto\spread64()\sand\spwrite64()\sshould\sbe\soff64_t,\snot\soff_t. -D 2016-04-18T13:09:55.691 +C Remove\squotes\sfrom\sidentifiers\sused\sas\sdatatype\snames\sin\sa\sCREATE\sTABLE\nstatement.\s\sFix\sfor\sticket\s[7d7525cb01b68] +D 2016-04-18T15:46:14.499 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -322,7 +322,7 @@ F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 F src/btree.c 3ae6aea66cc4e13d30162ff0d0d43c7088e34abf F src/btree.h a5008b9afe56e8e54ade6c436a910f112defcca9 F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 -F src/build.c 1944d95f0250ec72dab939f8319a12e237aaad61 +F src/build.c 42e8ee74dfa3a4b99bfb2c201f8a66ab50688d95 F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 60e135af364d777a9ab41c97e5e89cd224da6198 @@ -845,7 +845,7 @@ F test/insert5.test 394f96728d1258f406fe5f5aeb0aaf29487c39a6 F test/instr.test 737bbf80685232033f3abedc6ae92f75860b5dd2 F test/intarray.test 066b7d7ac38d25bf96f87f1b017bfc687551cdd4 F test/interrupt.test dfe9a67a94b0b2d8f70545ba1a6cca10780d71cc -F test/intpkey.test 70aab09756b9bd3bcb6b0358f971d7bbace46522 +F test/intpkey.test 153b70e32d008f4f4b2dff8daf448a6110b62a9c F test/io.test f95bca1783b01ea7761671560d023360d2dfa4cc F test/ioerr.test 2a24bd6ed5a8b062e64bfe1f6cf94fb25e92210d F test/ioerr2.test 2593563599e2cc6b6b4fcf5878b177bdd5d8df26 @@ -976,7 +976,7 @@ F test/pcache.test c8acbedd3b6fd0f9a7ca887a83b11d24a007972b F test/pcache2.test af7f3deb1a819f77a6d0d81534e97d1cf62cd442 F test/percentile.test 4243af26b8f3f4555abe166f723715a1f74c77ff F test/permutations.test cd1fa041074ed08eeaa563e4d1bacb0c69337ec1 -F test/pragma.test afbf028be1c35b68f57db8eb015c4a3c59d8f28e +F test/pragma.test dd5313eee9c6d9d4726593a68ede8768d3b50ccc F test/pragma2.test e5d5c176360c321344249354c0c16aec46214c9f F test/pragma3.test 3f1984a04657331f838df5c519b443c2088df922 F test/printf.test b3ff34e73d59124140eaf89f7672e21bc2ca5fcc @@ -1482,7 +1482,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 3e217d6265ecd16db783bed7ce1d9d0f9c4828bb -R 436b9ab5479b24882bf9b5114230dd45 +P 3a7d72986fabe9434ff5bd02c93169314f072b23 +R 761e3cafabae5f2f003bf21bdc2befe8 U drh -Z ed45643e1c73eeadd299c981e6f9488a +Z 8a9e64fdc933327d2408de0f01f55efc diff --git a/manifest.uuid b/manifest.uuid index 9d96c70fe9..540eda5836 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3a7d72986fabe9434ff5bd02c93169314f072b23 \ No newline at end of file +eba27d4d17a76884292667d570d542e580ee3e77 \ No newline at end of file diff --git a/src/build.c b/src/build.c index 3d93d8b761..c7541bc9d8 100644 --- a/src/build.c +++ b/src/build.c @@ -1086,6 +1086,7 @@ void sqlite3AddColumn(Parse *pParse, Token *pName, Token *pType){ zType = z + sqlite3Strlen30(z) + 1; memcpy(zType, pType->z, pType->n); zType[pType->n] = 0; + sqlite3Dequote(zType); pCol->affinity = sqlite3AffinityType(zType, &pCol->szEst); pCol->colFlags |= COLFLAG_HASTYPE; } diff --git a/test/intpkey.test b/test/intpkey.test index a149f43fb2..c6be5418aa 100644 --- a/test/intpkey.test +++ b/test/intpkey.test @@ -604,5 +604,16 @@ do_test intpkey-15.7 { } } {} +# 2016-04-18 ticket https://www.sqlite.org/src/tktview/7d7525cb01b68712495d3a +# Be sure to escape quoted typenames. +# +do_execsql_test intpkey-16.0 { + CREATE TABLE t16a(id "INTEGER" PRIMARY KEY AUTOINCREMENT, b [TEXT], c `INT`); +} {} +do_execsql_test intpkey-16.1 { + PRAGMA table_info=t16a; +} {0 id INTEGER 0 {} 1 1 b TEXT 0 {} 0 2 c INT 0 {} 0} + + finish_test diff --git a/test/pragma.test b/test/pragma.test index acbe74599e..e3f6f8cb0f 100644 --- a/test/pragma.test +++ b/test/pragma.test @@ -628,10 +628,10 @@ ifcapable tempdb&&attach { } do_test pragma-6.2 { execsql { - CREATE TABLE t2(a,b,c); + CREATE TABLE t2(a TYPE_X, b [TYPE_Y], c "TYPE_Z"); pragma table_info(t2) } -} {0 a {} 0 {} 0 1 b {} 0 {} 0 2 c {} 0 {} 0} +} {0 a TYPE_X 0 {} 0 1 b TYPE_Y 0 {} 0 2 c TYPE_Z 0 {} 0} do_test pragma-6.2.1 { execsql { pragma table_info; From beccf1d16f3cf00c58349dd1a6114b13a920ee4b Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 18 Apr 2016 18:18:18 +0000 Subject: [PATCH 0320/1484] Fix some zipvfs related problems in RBU vacuum. FossilOrigin-Name: d76f4aaa4caab713460421bd27365a82ac986c20 --- ext/rbu/sqlite3rbu.c | 81 +++++++++++++++++++++++++++++++++++++------- manifest | 12 +++---- manifest.uuid | 2 +- 3 files changed, 76 insertions(+), 19 deletions(-) diff --git a/ext/rbu/sqlite3rbu.c b/ext/rbu/sqlite3rbu.c index 280b64bb2a..f98a836852 100644 --- a/ext/rbu/sqlite3rbu.c +++ b/ext/rbu/sqlite3rbu.c @@ -190,6 +190,8 @@ typedef sqlite3_int64 i64; #define WAL_LOCK_CKPT 1 #define WAL_LOCK_READ0 3 +#define SQLITE_FCNTL_RBUCNT 5149216 + /* ** A structure to store values read from the rbu_state table in memory. */ @@ -393,6 +395,7 @@ struct rbu_file { int openFlags; /* Flags this file was opened with */ u32 iCookie; /* Cookie value for main db files */ u8 iWriteVer; /* "write-version" value for main db files */ + u8 bNolock; int nShm; /* Number of entries in apShm[] array */ char **apShm; /* Array of mmap'd *-shm regions */ @@ -2325,6 +2328,7 @@ static RbuState *rbuLoadState(sqlite3rbu *p){ ** error occurs, leave an error code and message in the RBU handle. */ static void rbuOpenDatabase(sqlite3rbu *p){ + int nRbu = 0; assert( p->rc==SQLITE_OK ); assert( p->dbMain==0 && p->dbRbu==0 ); assert( rbuIsVacuum(p) || p->zTarget!=0 ); @@ -2332,6 +2336,10 @@ static void rbuOpenDatabase(sqlite3rbu *p){ /* Open the RBU database */ p->dbRbu = rbuOpenDbhandle(p, p->zRbu, 1); + if( rbuIsVacuum(p) ){ + sqlite3_file_control(p->dbRbu, "main", SQLITE_FCNTL_RBUCNT, &nRbu); + } + /* If using separate RBU and state databases, attach the state database to ** the RBU db handle now. */ if( p->zState ){ @@ -2355,7 +2363,7 @@ static void rbuOpenDatabase(sqlite3rbu *p){ rbuFreeState(pState); } } - if( bOpen ) p->dbMain = rbuOpenDbhandle(p, p->zRbu, 1); + if( bOpen ) p->dbMain = rbuOpenDbhandle(p, p->zRbu, nRbu<=1); } p->eStage = 0; @@ -2363,20 +2371,13 @@ static void rbuOpenDatabase(sqlite3rbu *p){ if( !rbuIsVacuum(p) ){ p->dbMain = rbuOpenDbhandle(p, p->zTarget, 1); }else{ - int frc = sqlite3_file_control(p->dbRbu, "main", SQLITE_FCNTL_ZIPVFS, 0); char *zTarget = sqlite3_mprintf("file:%s-vacuum?rbu_memory=1", p->zRbu); if( zTarget==0 ){ p->rc = SQLITE_NOMEM; return; } - p->dbMain = rbuOpenDbhandle(p, zTarget, frc!=SQLITE_OK); + p->dbMain = rbuOpenDbhandle(p, zTarget, nRbu<=1); sqlite3_free(zTarget); - if( p->rc==SQLITE_OK ){ - p->rc = sqlite3_exec(p->dbMain, - "PRAGMA journal_mode=off; PRAGMA zipvfs_journal_mode = off;" - "BEGIN EXCLUSIVE; COMMIT;", 0, 0, 0 - ); - } } } @@ -3445,7 +3446,7 @@ static sqlite3rbu *openRbuHandle( ** created at this point. */ p->rc = sqlite3_exec(db, "BEGIN IMMEDIATE", 0, 0, &p->zErrmsg); if( p->rc==SQLITE_OK ){ - p->rc = sqlite3_exec(p->dbRbu, "BEGIN IMMEDIATE", 0, 0, &p->zErrmsg); + p->rc = sqlite3_exec(p->dbRbu, "BEGIN", 0, 0, &p->zErrmsg); } /* Check if the main database is a zipvfs db. If it is, set the upper @@ -3787,6 +3788,11 @@ static void rbuPutU32(u8 *aBuf, u32 iVal){ aBuf[3] = (iVal >> 0) & 0xFF; } +static void rbuPutU16(u8 *aBuf, u16 iVal){ + aBuf[0] = (iVal >> 8) & 0xFF; + aBuf[1] = (iVal >> 0) & 0xFF; +} + /* ** Read data from an rbuVfs-file. */ @@ -3812,6 +3818,37 @@ static int rbuVfsRead( memset(zBuf, 0, iAmt); }else{ rc = p->pReal->pMethods->xRead(p->pReal, zBuf, iAmt, iOfst); +#if 1 + /* If this is being called to read the first page of the target + ** database as part of an rbu vacuum operation, synthesize the + ** contents of the first page if it does not yet exist. Otherwise, + ** SQLite will not check for a *-wal file. */ + if( p->pRbu && rbuIsVacuum(p->pRbu) + && rc==SQLITE_IOERR_SHORT_READ && iOfst==0 + && (p->openFlags & SQLITE_OPEN_MAIN_DB) + ){ + sqlite3_file *pFd = 0; + rc = sqlite3_file_control( + p->pRbu->dbRbu, "main", SQLITE_FCNTL_FILE_POINTER, (void*)&pFd + ); + if( rc==SQLITE_OK ){ + rc = pFd->pMethods->xRead(pFd, zBuf, iAmt, iOfst); + } + if( rc==SQLITE_OK ){ + u8 *aBuf = (u8*)zBuf; + rbuPutU32(&aBuf[52], 0); /* largest root page number */ + rbuPutU32(&aBuf[36], 0); /* number of free pages */ + rbuPutU32(&aBuf[32], 0); /* first page on free list trunk */ + rbuPutU32(&aBuf[28], 1); /* size of db file in pages */ + + if( iAmt>100 ){ + assert( iAmt>=101 ); + memset(&aBuf[101], 0, iAmt-101); + rbuPutU16(&aBuf[105], iAmt & 0xFFFF); + } + } + } +#endif } if( rc==SQLITE_OK && iOfst==0 && (p->openFlags & SQLITE_OPEN_MAIN_DB) ){ /* These look like magic numbers. But they are stable, as they are part @@ -3893,7 +3930,20 @@ static int rbuVfsSync(sqlite3_file *pFile, int flags){ */ static int rbuVfsFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){ rbu_file *p = (rbu_file *)pFile; - return p->pReal->pMethods->xFileSize(p->pReal, pSize); + int rc; + rc = p->pReal->pMethods->xFileSize(p->pReal, pSize); + + /* If this is an RBU vacuum operation and this is the target database, + ** pretend that it has at least one page. Otherwise, SQLite will not + ** check for the existance of a *-wal file. rbuVfsRead() contains + ** similar logic. */ + if( rc==SQLITE_OK && *pSize==0 + && p->pRbu && rbuIsVacuum(p->pRbu) + && (p->openFlags & SQLITE_OPEN_MAIN_DB) + ){ + *pSize = 1024; + } + return rc; } /* @@ -3905,7 +3955,9 @@ static int rbuVfsLock(sqlite3_file *pFile, int eLock){ int rc = SQLITE_OK; assert( p->openFlags & (SQLITE_OPEN_MAIN_DB|SQLITE_OPEN_TEMP_DB) ); - if( pRbu && eLock==SQLITE_LOCK_EXCLUSIVE && pRbu->eStage!=RBU_STAGE_DONE ){ + if( eLock==SQLITE_LOCK_EXCLUSIVE + && (p->bNolock || (pRbu && pRbu->eStage!=RBU_STAGE_DONE)) + ){ /* Do not allow EXCLUSIVE locks. Preventing SQLite from taking this ** prevents it from checkpointing the database from sqlite3_close(). */ rc = SQLITE_BUSY; @@ -3968,6 +4020,11 @@ static int rbuVfsFileControl(sqlite3_file *pFile, int op, void *pArg){ } return rc; } + else if( op==SQLITE_FCNTL_RBUCNT ){ + int *pnRbu = (int*)pArg; + (*pnRbu)++; + p->bNolock = 1; + } rc = xControl(p->pReal, op, pArg); if( rc==SQLITE_OK && op==SQLITE_FCNTL_VFSNAME ){ diff --git a/manifest b/manifest index 6840069cfa..d23cec1ffd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\s-vacuum\sswitch\sto\sthe\s"rbu"\sdemonstration\sprogram. -D 2016-04-18T09:17:05.073 +C Fix\ssome\szipvfs\srelated\sproblems\sin\sRBU\svacuum. +D 2016-04-18T18:18:18.881 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -247,7 +247,7 @@ F ext/rbu/rbufts.test 828cd689da825f0a7b7c53ffc1f6f7fdb6fa5bda F ext/rbu/rbuprogress.test 2023a7df2c523e3df1cb532eff811cda385a789a F ext/rbu/rbusave.test 0f43b6686084f426ddd040b878426452fd2c2f48 F ext/rbu/rbuvacuum.test 75b4231f85622859e814c7f028afad0303f72f60 -F ext/rbu/sqlite3rbu.c 721c6c116018b5d02f6318b6bbb7834098bc6a07 +F ext/rbu/sqlite3rbu.c 372ed3aaa396e3edfacdb8976d49aafdbe330cfa F ext/rbu/sqlite3rbu.h 1342ab6121e715b8da59ec35c5b5c16060be7a6b F ext/rbu/test_rbu.c 430b8b9520c233505371d564d3561e0b554355f4 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 @@ -1483,7 +1483,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P bae7f875f476f6e01112751cb404fef42ba0a01c -R 446c70a62698b2fec86a1f84d13dd5af +P 9a0078a538c7e73a009960347b8953c5af99fefd +R dc7cff23cf20a157412c6c371d56e10b U dan -Z be7942fa7aee76e8d89cc36d886361a8 +Z 72aacc0891d9c46e37fe5c65eb96b678 diff --git a/manifest.uuid b/manifest.uuid index c5a45627c9..e3fa7de1a3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9a0078a538c7e73a009960347b8953c5af99fefd \ No newline at end of file +d76f4aaa4caab713460421bd27365a82ac986c20 \ No newline at end of file From 58e3812988e4eea3140ae365d0325254555c71bc Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 18 Apr 2016 21:00:01 +0000 Subject: [PATCH 0321/1484] Another fix to rbu vacuum for a zipvfs case. FossilOrigin-Name: 29407d70e44ad9ea5ddaf1011d0e212b602a3ddf --- ext/rbu/sqlite3rbu.c | 30 ++++++++++++++++-------------- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 23 insertions(+), 21 deletions(-) diff --git a/ext/rbu/sqlite3rbu.c b/ext/rbu/sqlite3rbu.c index f98a836852..60773b79f8 100644 --- a/ext/rbu/sqlite3rbu.c +++ b/ext/rbu/sqlite3rbu.c @@ -370,6 +370,10 @@ struct sqlite3rbu { int pgsz; u8 *aBuf; i64 iWalCksum; + + /* Used in RBU vacuum mode only */ + int nRbu; /* Number of RBU VFS in the stack */ + rbu_file *pRbuFd; /* Fd for main db of dbRbu */ }; /* @@ -2328,7 +2332,6 @@ static RbuState *rbuLoadState(sqlite3rbu *p){ ** error occurs, leave an error code and message in the RBU handle. */ static void rbuOpenDatabase(sqlite3rbu *p){ - int nRbu = 0; assert( p->rc==SQLITE_OK ); assert( p->dbMain==0 && p->dbRbu==0 ); assert( rbuIsVacuum(p) || p->zTarget!=0 ); @@ -2337,7 +2340,7 @@ static void rbuOpenDatabase(sqlite3rbu *p){ p->dbRbu = rbuOpenDbhandle(p, p->zRbu, 1); if( rbuIsVacuum(p) ){ - sqlite3_file_control(p->dbRbu, "main", SQLITE_FCNTL_RBUCNT, &nRbu); + sqlite3_file_control(p->dbRbu, "main", SQLITE_FCNTL_RBUCNT, (void*)p); } /* If using separate RBU and state databases, attach the state database to @@ -2354,6 +2357,9 @@ static void rbuOpenDatabase(sqlite3rbu *p){ if( rbuIsVacuum(p) ){ int bOpen = 0; + p->nRbu = 0; + p->pRbuFd = 0; + sqlite3_file_control(p->dbRbu, "main", SQLITE_FCNTL_RBUCNT, (void*)p); if( p->eStage>=RBU_STAGE_MOVE ){ bOpen = 1; }else{ @@ -2363,7 +2369,7 @@ static void rbuOpenDatabase(sqlite3rbu *p){ rbuFreeState(pState); } } - if( bOpen ) p->dbMain = rbuOpenDbhandle(p, p->zRbu, nRbu<=1); + if( bOpen ) p->dbMain = rbuOpenDbhandle(p, p->zRbu, p->nRbu<=1); } p->eStage = 0; @@ -2376,7 +2382,7 @@ static void rbuOpenDatabase(sqlite3rbu *p){ p->rc = SQLITE_NOMEM; return; } - p->dbMain = rbuOpenDbhandle(p, zTarget, nRbu<=1); + p->dbMain = rbuOpenDbhandle(p, zTarget, p->nRbu<=1); sqlite3_free(zTarget); } } @@ -3823,17 +3829,12 @@ static int rbuVfsRead( ** database as part of an rbu vacuum operation, synthesize the ** contents of the first page if it does not yet exist. Otherwise, ** SQLite will not check for a *-wal file. */ - if( p->pRbu && rbuIsVacuum(p->pRbu) + if( pRbu && rbuIsVacuum(pRbu) && rc==SQLITE_IOERR_SHORT_READ && iOfst==0 && (p->openFlags & SQLITE_OPEN_MAIN_DB) ){ - sqlite3_file *pFd = 0; - rc = sqlite3_file_control( - p->pRbu->dbRbu, "main", SQLITE_FCNTL_FILE_POINTER, (void*)&pFd - ); - if( rc==SQLITE_OK ){ - rc = pFd->pMethods->xRead(pFd, zBuf, iAmt, iOfst); - } + sqlite3_file *pFd = (sqlite3_file*)pRbu->pRbuFd; + rc = pFd->pMethods->xRead(pFd, zBuf, iAmt, iOfst); if( rc==SQLITE_OK ){ u8 *aBuf = (u8*)zBuf; rbuPutU32(&aBuf[52], 0); /* largest root page number */ @@ -4021,8 +4022,9 @@ static int rbuVfsFileControl(sqlite3_file *pFile, int op, void *pArg){ return rc; } else if( op==SQLITE_FCNTL_RBUCNT ){ - int *pnRbu = (int*)pArg; - (*pnRbu)++; + sqlite3rbu *pRbu = (sqlite3rbu*)pArg; + pRbu->nRbu++; + pRbu->pRbuFd = p; p->bNolock = 1; } diff --git a/manifest b/manifest index d23cec1ffd..068554e465 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\ssome\szipvfs\srelated\sproblems\sin\sRBU\svacuum. -D 2016-04-18T18:18:18.881 +C Another\sfix\sto\srbu\svacuum\sfor\sa\szipvfs\scase. +D 2016-04-18T21:00:01.258 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -247,7 +247,7 @@ F ext/rbu/rbufts.test 828cd689da825f0a7b7c53ffc1f6f7fdb6fa5bda F ext/rbu/rbuprogress.test 2023a7df2c523e3df1cb532eff811cda385a789a F ext/rbu/rbusave.test 0f43b6686084f426ddd040b878426452fd2c2f48 F ext/rbu/rbuvacuum.test 75b4231f85622859e814c7f028afad0303f72f60 -F ext/rbu/sqlite3rbu.c 372ed3aaa396e3edfacdb8976d49aafdbe330cfa +F ext/rbu/sqlite3rbu.c ac4621fc62e0bc3e9e92fceb483c0207af25addf F ext/rbu/sqlite3rbu.h 1342ab6121e715b8da59ec35c5b5c16060be7a6b F ext/rbu/test_rbu.c 430b8b9520c233505371d564d3561e0b554355f4 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 @@ -1483,7 +1483,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 9a0078a538c7e73a009960347b8953c5af99fefd -R dc7cff23cf20a157412c6c371d56e10b +P d76f4aaa4caab713460421bd27365a82ac986c20 +R 02609be0d1cf35faad7663d479babac3 U dan -Z 72aacc0891d9c46e37fe5c65eb96b678 +Z ecb53ed56b3181cf4b46470b55ef0f36 diff --git a/manifest.uuid b/manifest.uuid index e3fa7de1a3..74ea0959b8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d76f4aaa4caab713460421bd27365a82ac986c20 \ No newline at end of file +29407d70e44ad9ea5ddaf1011d0e212b602a3ddf \ No newline at end of file From bff4b6367c4a216c71f3e6f7ef6c613da82f6341 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 19 Apr 2016 16:20:24 +0000 Subject: [PATCH 0322/1484] Detect attempts to use rbu vacuum on a wal mode database (not allowed). And attempts to write to a database in the middle of an rbu vacuum (which prevents the vacuum from resuming). FossilOrigin-Name: 00b2f4b09ffca5156e43c4db2bfe0b2c979c49b0 --- ext/rbu/rbuvacuum.test | 82 +++++++++++++++++++++++++++++++++++------- ext/rbu/sqlite3rbu.c | 42 +++++++++++----------- manifest | 14 ++++---- manifest.uuid | 2 +- 4 files changed, 99 insertions(+), 41 deletions(-) diff --git a/ext/rbu/rbuvacuum.test b/ext/rbu/rbuvacuum.test index 045b2d1bb7..4380b78fbf 100644 --- a/ext/rbu/rbuvacuum.test +++ b/ext/rbu/rbuvacuum.test @@ -17,15 +17,15 @@ source [file join [file dirname [info script]] rbu_common.tcl] set ::testprefix rbuvacuum -proc do_rbu_vacuum_test {tn} { +proc do_rbu_vacuum_test {tn step} { uplevel [list do_test $tn.1 { forcedelete state.db - if {$::step==0} { sqlite3rbu_vacuum rbu test.db state.db } + if {$step==0} { sqlite3rbu_vacuum rbu test.db state.db } while 1 { - if {$::step==1} { sqlite3rbu_vacuum rbu test.db state.db } + if {$step==1} { sqlite3rbu_vacuum rbu test.db state.db } set rc [rbu step] if {$rc!="SQLITE_OK"} break - if {$::step==1} { rbu close } + if {$step==1} { rbu close } } rbu close } {SQLITE_DONE}] @@ -49,7 +49,7 @@ foreach step {0 1} { INSERT INTO t1 VALUES(7, 8, 9); PRAGMA integrity_check; } {ok} - do_rbu_vacuum_test 1.1 + do_rbu_vacuum_test 1.1 $step # A vacuum that actually reclaims space. do_execsql_test 1.2.1 { @@ -64,7 +64,7 @@ foreach step {0 1} { DELETE FROM t1 WHERE rowid BETWEEN 8 AND 11; PRAGMA page_count; } {12} - do_rbu_vacuum_test 1.2.3 + do_rbu_vacuum_test 1.2.3 $step do_execsql_test 1.2.4 { PRAGMA page_count; } {3} @@ -82,7 +82,7 @@ foreach step {0 1} { DELETE FROM t1 WHERE rowid BETWEEN 12 AND 15; PRAGMA page_count; } {18} - do_rbu_vacuum_test 1.3.3 + do_rbu_vacuum_test 1.3.3 $step do_execsql_test 1.3.4 { PRAGMA page_count; } {5} @@ -102,7 +102,7 @@ foreach step {0 1} { DELETE FROM t2 WHERE b BETWEEN 2 AND 7; PRAGMA page_count; } {20} - do_rbu_vacuum_test 1.4.2 + do_rbu_vacuum_test 1.4.2 $step do_execsql_test 1.4.3 { PRAGMA page_count; } {10} @@ -120,7 +120,7 @@ foreach step {0 1} { DELETE FROM t2 WHERE b BETWEEN 8 AND 12; PRAGMA page_count; } {35} - do_rbu_vacuum_test 1.4.2 + do_rbu_vacuum_test 1.4.2 $step do_execsql_test 1.4.3 { PRAGMA page_count; } {15} @@ -135,7 +135,7 @@ foreach step {0 1} { INSERT INTO t3 VALUES('d', 'e', 'f'); INSERT INTO t3 VALUES('g', 'h', 'i'); } - do_rbu_vacuum_test 1.5.2 + do_rbu_vacuum_test 1.5.2 $step do_execsql_test 1.5.3 { SELECT * FROM t3 } {a b c d e f g h i} @@ -146,7 +146,7 @@ foreach step {0 1} { INSERT INTO t3 VALUES('j', 'k', 'l'); DELETE FROM t3 WHERE a = 'g'; } - do_rbu_vacuum_test 1.5.5 + do_rbu_vacuum_test 1.5.5 $step do_execsql_test 1.5.6 { SELECT rowid, * FROM t3 ORDER BY b } {1 a b c 2 d e f 4 j k l} @@ -157,7 +157,7 @@ foreach step {0 1} { INSERT INTO t4 VALUES('d', 'e', 'f'); INSERT INTO t4 VALUES('g', 'h', 'i'); } - do_rbu_vacuum_test 1.6.2 + do_rbu_vacuum_test 1.6.2 $step do_execsql_test 1.6.3 { SELECT * FROM t4 } {a b c d e f g h i} @@ -169,13 +169,69 @@ foreach step {0 1} { INSERT INTO t4 VALUES('j', 'k', 'l'); DELETE FROM t4 WHERE a='g'; } - do_rbu_vacuum_test 1.6.5 + do_rbu_vacuum_test 1.6.5 $step do_execsql_test 1.6.6 { SELECT * FROM t4 ORDER BY b } {a b c d e f j k l} } +#------------------------------------------------------------------------- +# Test some error cases: +# +# 2.1.* the db being vacuumed being in wal mode already. +# 2.2.* database modified mid vacuum. +# +reset_db +do_execsql_test 2.1.0 { + CREATE TABLE t1(a, b); + INSERT INTO t1 VALUES(1, 2); + INSERT INTO t1 VALUES(3, 4); + INSERT INTO t1 VALUES(5, 6); + INSERT INTO t1 VALUES(7, 8); + PRAGMA journal_mode = wal; + INSERT INTO t1 VALUES(9, 10); +} wal +do_test 2.1.1 { + forcedelete state.db + sqlite3rbu_vacuum rbu test.db state.db + rbu step +} {SQLITE_ERROR} +do_test 2.1.2 { + list [catch { rbu close } msg] $msg +} {1 {SQLITE_ERROR - cannot vacuum wal mode database}} + +reset_db +do_execsql_test 2.2.0 { + CREATE TABLE tx(a PRIMARY KEY, b BLOB); + INSERT INTO tx VALUES(1, randomblob(900)); + INSERT INTO tx SELECT a+1, randomblob(900) FROM tx; + INSERT INTO tx SELECT a+2, randomblob(900) FROM tx; + INSERT INTO tx SELECT a+4, randomblob(900) FROM tx; + INSERT INTO tx SELECT a+8, randomblob(900) FROM tx; +} +db_save_and_close +for {set i 1} 1 {incr i} { + forcedelete state.db + db_restore_and_reopen + + sqlite3rbu_vacuum rbu test.db state.db + for {set step 0} {$step<$i} {incr step} { rbu step } + rbu close + if {[file exists test.db-wal]} break + + execsql { INSERT INTO tx VALUES(20, 20) } + + do_test 2.2.$i.1 { + sqlite3rbu_vacuum rbu test.db state.db + rbu step + } {SQLITE_BUSY} + do_test 2.2.$i.2 { + list [catch { rbu close } msg] $msg + } {1 {SQLITE_BUSY - database modified during rbu vacuum}} + +} + catch { db close } finish_test diff --git a/ext/rbu/sqlite3rbu.c b/ext/rbu/sqlite3rbu.c index 60773b79f8..6ccf54826c 100644 --- a/ext/rbu/sqlite3rbu.c +++ b/ext/rbu/sqlite3rbu.c @@ -399,7 +399,7 @@ struct rbu_file { int openFlags; /* Flags this file was opened with */ u32 iCookie; /* Cookie value for main db files */ u8 iWriteVer; /* "write-version" value for main db files */ - u8 bNolock; + u8 bNolock; /* True to fail EXCLUSIVE locks */ int nShm; /* Number of entries in apShm[] array */ char **apShm; /* Array of mmap'd *-shm regions */ @@ -2373,9 +2373,12 @@ static void rbuOpenDatabase(sqlite3rbu *p){ } p->eStage = 0; - if( p->dbMain==0 ){ + if( p->rc==SQLITE_OK && p->dbMain==0 ){ if( !rbuIsVacuum(p) ){ p->dbMain = rbuOpenDbhandle(p, p->zTarget, 1); + }else if( p->pRbuFd->pWalFd ){ + p->rc = SQLITE_ERROR; + p->zErrmsg = sqlite3_mprintf("cannot vacuum wal mode database"); }else{ char *zTarget = sqlite3_mprintf("file:%s-vacuum?rbu_memory=1", p->zRbu); if( zTarget==0 ){ @@ -2987,6 +2990,7 @@ static void rbuIncrSchemaCookie(sqlite3rbu *p){ static void rbuSaveState(sqlite3rbu *p, int eStage){ if( p->rc==SQLITE_OK || p->rc==SQLITE_DONE ){ sqlite3_stmt *pInsert = 0; + rbu_file *pFd = (rbuIsVacuum(p) ? p->pRbuFd : p->pTargetFd); int rc; assert( p->zErrmsg==0 ); @@ -3009,7 +3013,7 @@ static void rbuSaveState(sqlite3rbu *p, int eStage){ RBU_STATE_ROW, p->nStep, RBU_STATE_PROGRESS, p->nProgress, RBU_STATE_CKPT, p->iWalCksum, - RBU_STATE_COOKIE, (i64)p->pTargetFd->iCookie, + RBU_STATE_COOKIE, (i64)pFd->iCookie, RBU_STATE_OALSZ, p->iOalSz, RBU_STATE_PHASEONESTEP, p->nPhaseOneStep ) @@ -3431,17 +3435,21 @@ static sqlite3rbu *openRbuHandle( } } - if( p->rc==SQLITE_OK - && !rbuIsVacuum(p) + if( p->rc==SQLITE_OK && (p->eStage==RBU_STAGE_OAL || p->eStage==RBU_STAGE_MOVE) - && pState->eStage!=0 && p->pTargetFd->iCookie!=pState->iCookie - ){ - /* At this point (pTargetFd->iCookie) contains the value of the - ** change-counter cookie (the thing that gets incremented when a - ** transaction is committed in rollback mode) currently stored on - ** page 1 of the database file. */ - p->rc = SQLITE_BUSY; - p->zErrmsg = sqlite3_mprintf("database modified during rbu update"); + && pState->eStage!=0 + ){ + rbu_file *pFd = (rbuIsVacuum(p) ? p->pRbuFd : p->pTargetFd); + if( pFd->iCookie!=pState->iCookie ){ + /* At this point (pTargetFd->iCookie) contains the value of the + ** change-counter cookie (the thing that gets incremented when a + ** transaction is committed in rollback mode) currently stored on + ** page 1 of the database file. */ + p->rc = SQLITE_BUSY; + p->zErrmsg = sqlite3_mprintf("database modified during rbu %s", + (rbuIsVacuum(p) ? "vacuum" : "update") + ); + } } if( p->rc==SQLITE_OK ){ @@ -3841,6 +3849,7 @@ static int rbuVfsRead( rbuPutU32(&aBuf[36], 0); /* number of free pages */ rbuPutU32(&aBuf[32], 0); /* first page on free list trunk */ rbuPutU32(&aBuf[28], 1); /* size of db file in pages */ + rbuPutU32(&aBuf[24], pRbu->pRbuFd->iCookie+1); /* Change counter */ if( iAmt>100 ){ assert( iAmt>=101 ); @@ -3857,13 +3866,6 @@ static int rbuVfsRead( u8 *pBuf = (u8*)zBuf; p->iCookie = rbuGetU32(&pBuf[24]); p->iWriteVer = pBuf[19]; - if( pRbu && rbuIsVacuum(p->pRbu) ){ - rbu_file *pRbuFd = 0; - sqlite3_file_control(pRbu->dbRbu, "main", - SQLITE_FCNTL_FILE_POINTER, (void*)&pRbuFd - ); - rbuPutU32(&pBuf[24], pRbuFd->iCookie+1); - } } } return rc; diff --git a/manifest b/manifest index 068554e465..fe489077ea 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Another\sfix\sto\srbu\svacuum\sfor\sa\szipvfs\scase. -D 2016-04-18T21:00:01.258 +C Detect\sattempts\sto\suse\srbu\svacuum\son\sa\swal\smode\sdatabase\s(not\sallowed).\sAnd\sattempts\sto\swrite\sto\sa\sdatabase\sin\sthe\smiddle\sof\san\srbu\svacuum\s(which\sprevents\sthe\svacuum\sfrom\sresuming). +D 2016-04-19T16:20:24.513 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -246,8 +246,8 @@ F ext/rbu/rbufault2.test 9a7f19edd6ea35c4c9f807d8a3db0a03a5670c06 F ext/rbu/rbufts.test 828cd689da825f0a7b7c53ffc1f6f7fdb6fa5bda F ext/rbu/rbuprogress.test 2023a7df2c523e3df1cb532eff811cda385a789a F ext/rbu/rbusave.test 0f43b6686084f426ddd040b878426452fd2c2f48 -F ext/rbu/rbuvacuum.test 75b4231f85622859e814c7f028afad0303f72f60 -F ext/rbu/sqlite3rbu.c ac4621fc62e0bc3e9e92fceb483c0207af25addf +F ext/rbu/rbuvacuum.test b7194617c22f69e2015082a5414585aae2827a29 +F ext/rbu/sqlite3rbu.c d269d60bddb770fc9bbe747c47522f946562878d F ext/rbu/sqlite3rbu.h 1342ab6121e715b8da59ec35c5b5c16060be7a6b F ext/rbu/test_rbu.c 430b8b9520c233505371d564d3561e0b554355f4 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 @@ -1483,7 +1483,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d76f4aaa4caab713460421bd27365a82ac986c20 -R 02609be0d1cf35faad7663d479babac3 +P 29407d70e44ad9ea5ddaf1011d0e212b602a3ddf +R da49b342c9cd61c56db951e40b34afc9 U dan -Z ecb53ed56b3181cf4b46470b55ef0f36 +Z 3a78d0d54b42b6cec75432abbb63bed7 diff --git a/manifest.uuid b/manifest.uuid index 74ea0959b8..4483a9f107 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -29407d70e44ad9ea5ddaf1011d0e212b602a3ddf \ No newline at end of file +00b2f4b09ffca5156e43c4db2bfe0b2c979c49b0 \ No newline at end of file From 46f0035b4829af743b83b6b9efd431031a716d35 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 19 Apr 2016 17:11:05 +0000 Subject: [PATCH 0323/1484] When an RBU vacuum is started on a db identified using a URI filename, pass the same URI parameters when creating the new version of the db. This ensures that RBU vacuum works with password protected databases. FossilOrigin-Name: ca021ba88106500f347ed65199a4832bc9eb5ef8 --- ext/rbu/sqlite3rbu.c | 16 +++++++++++++++- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/ext/rbu/sqlite3rbu.c b/ext/rbu/sqlite3rbu.c index 6ccf54826c..0670b9b8b8 100644 --- a/ext/rbu/sqlite3rbu.c +++ b/ext/rbu/sqlite3rbu.c @@ -2380,7 +2380,21 @@ static void rbuOpenDatabase(sqlite3rbu *p){ p->rc = SQLITE_ERROR; p->zErrmsg = sqlite3_mprintf("cannot vacuum wal mode database"); }else{ - char *zTarget = sqlite3_mprintf("file:%s-vacuum?rbu_memory=1", p->zRbu); + char *zTarget; + char *zExtra = 0; + if( strlen(p->zRbu)>=5 && 0==memcmp("file:", p->zRbu, 5) ){ + zExtra = &p->zRbu[5]; + while( *zExtra ){ + if( *zExtra++=='?' ) break; + } + if( *zExtra=='\0' ) zExtra = 0; + } + + zTarget = sqlite3_mprintf("file:%s-vacuum?rbu_memory=1%s%s", + sqlite3_db_filename(p->dbRbu, "main"), + (zExtra==0 ? "" : "&"), (zExtra==0 ? "" : zExtra) + ); + if( zTarget==0 ){ p->rc = SQLITE_NOMEM; return; diff --git a/manifest b/manifest index fe489077ea..2edcbd1077 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Detect\sattempts\sto\suse\srbu\svacuum\son\sa\swal\smode\sdatabase\s(not\sallowed).\sAnd\sattempts\sto\swrite\sto\sa\sdatabase\sin\sthe\smiddle\sof\san\srbu\svacuum\s(which\sprevents\sthe\svacuum\sfrom\sresuming). -D 2016-04-19T16:20:24.513 +C When\san\sRBU\svacuum\sis\sstarted\son\sa\sdb\sidentified\susing\sa\sURI\sfilename,\spass\sthe\ssame\sURI\sparameters\swhen\screating\sthe\snew\sversion\sof\sthe\sdb.\sThis\sensures\sthat\sRBU\svacuum\sworks\swith\spassword\sprotected\sdatabases. +D 2016-04-19T17:11:05.418 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -247,7 +247,7 @@ F ext/rbu/rbufts.test 828cd689da825f0a7b7c53ffc1f6f7fdb6fa5bda F ext/rbu/rbuprogress.test 2023a7df2c523e3df1cb532eff811cda385a789a F ext/rbu/rbusave.test 0f43b6686084f426ddd040b878426452fd2c2f48 F ext/rbu/rbuvacuum.test b7194617c22f69e2015082a5414585aae2827a29 -F ext/rbu/sqlite3rbu.c d269d60bddb770fc9bbe747c47522f946562878d +F ext/rbu/sqlite3rbu.c 0447a8a306411e585d8595465abbed7709f1feb7 F ext/rbu/sqlite3rbu.h 1342ab6121e715b8da59ec35c5b5c16060be7a6b F ext/rbu/test_rbu.c 430b8b9520c233505371d564d3561e0b554355f4 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 @@ -1483,7 +1483,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 29407d70e44ad9ea5ddaf1011d0e212b602a3ddf -R da49b342c9cd61c56db951e40b34afc9 +P 00b2f4b09ffca5156e43c4db2bfe0b2c979c49b0 +R e7445097e6cb895f2eea40503c71f11e U dan -Z 3a78d0d54b42b6cec75432abbb63bed7 +Z 90c42b90d6761cf98f1c67d89391cb68 diff --git a/manifest.uuid b/manifest.uuid index 4483a9f107..f1fc314990 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -00b2f4b09ffca5156e43c4db2bfe0b2c979c49b0 \ No newline at end of file +ca021ba88106500f347ed65199a4832bc9eb5ef8 \ No newline at end of file From 1aea63032a02a2f38b673243b63a71a80bb4aadb Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 19 Apr 2016 19:27:09 +0000 Subject: [PATCH 0324/1484] Updates to ensure the values of PRAGMA settings like "page_size", "auto_vacuum", "user_version" and "application_id" are not lost when a database is RBU vacuumed. FossilOrigin-Name: 74ffea76b8c9ddd7699ce6ca77dce005bd7922ac --- ext/rbu/rbuvacuum.test | 68 +++++++++++++++++++++++++++++++++++++++++- ext/rbu/sqlite3rbu.c | 57 ++++++++++++++++++++++++++++++----- manifest | 14 ++++----- manifest.uuid | 2 +- 4 files changed, 125 insertions(+), 16 deletions(-) diff --git a/ext/rbu/rbuvacuum.test b/ext/rbu/rbuvacuum.test index 4380b78fbf..85ecfc4c13 100644 --- a/ext/rbu/rbuvacuum.test +++ b/ext/rbu/rbuvacuum.test @@ -174,6 +174,73 @@ foreach step {0 1} { SELECT * FROM t4 ORDER BY b } {a b c d e f j k l} + reset_db + do_execsql_test 1.7.0 { + CREATE TABLE t1(a INTEGER PRIMARY KEY AUTOINCREMENT, b); + INSERT INTO t1 VALUES(NULL, 'one'); + INSERT INTO t1 VALUES(NULL, 'two'); + DELETE FROM t1 WHERE a=2; + INSERT INTO t1 VALUES(NULL, 'three'); + INSERT INTO t1 VALUES(NULL, 'four'); + DELETE FROM t1 WHERE a=4; + INSERT INTO t1 VALUES(NULL, 'five'); + INSERT INTO t1 VALUES(NULL, 'six'); + DELETE FROM t1 WHERE a=6; + SELECT * FROM t1; + } {1 one 3 three 5 five} + do_rbu_vacuum_test 1.7.1 $step + do_execsql_test 1.7.2 { + INSERT INTO t1 VALUES(NULL, 'seven'); + SELECT * FROM t1; + } {1 one 3 three 5 five 7 seven} + + reset_db + do_execsql_test 1.8.0 { + CREATE TABLE t1(a INTEGER PRIMARY KEY AUTOINCREMENT, b); + CREATE INDEX i1 ON t1(b); + INSERT INTO t1 VALUES(NULL, 'one'); + INSERT INTO t1 VALUES(NULL, 'two'); + INSERT INTO t1 VALUES(NULL, 'three'); + INSERT INTO t1 VALUES(NULL, 'four'); + INSERT INTO t1 VALUES(NULL, 'five'); + INSERT INTO t1 VALUES(NULL, 'six'); + ANALYZE; + SELECT * FROM sqlite_stat1; + } {t1 i1 {6 1}} + do_rbu_vacuum_test 1.8.1 $step + do_execsql_test 1.7.2 { + SELECT * FROM sqlite_stat1; + } {t1 i1 {6 1}} + + reset_db + do_execsql_test 1.9.0 { + PRAGMA page_size = 8192; + PRAGMA auto_vacuum = 2; + PRAGMA user_version = 412; + PRAGMA application_id = 413; + + CREATE TABLE t1(a INTEGER PRIMARY KEY AUTOINCREMENT, b); + CREATE INDEX i1 ON t1(b); + INSERT INTO t1 VALUES(NULL, 'one'); + INSERT INTO t1 VALUES(NULL, 'two'); + INSERT INTO t1 VALUES(NULL, 'three'); + INSERT INTO t1 VALUES(NULL, 'four'); + INSERT INTO t1 VALUES(NULL, 'five'); + INSERT INTO t1 VALUES(NULL, 'six'); + + PRAGMA main.page_size; + PRAGMA main.auto_vacuum; + PRAGMA main.user_version; + PRAGMA main.application_id; + } {8192 2 412 413} + + do_rbu_vacuum_test 1.9.1 $step + do_execsql_test 1.9.2 { + PRAGMA main.page_size; + PRAGMA main.auto_vacuum; + PRAGMA main.user_version; + PRAGMA main.application_id; + } {8192 2 412 413} } #------------------------------------------------------------------------- @@ -229,7 +296,6 @@ for {set i 1} 1 {incr i} { do_test 2.2.$i.2 { list [catch { rbu close } msg] $msg } {1 {SQLITE_BUSY - database modified during rbu vacuum}} - } catch { db close } diff --git a/ext/rbu/sqlite3rbu.c b/ext/rbu/sqlite3rbu.c index 0670b9b8b8..8c7682abea 100644 --- a/ext/rbu/sqlite3rbu.c +++ b/ext/rbu/sqlite3rbu.c @@ -3333,6 +3333,38 @@ static void rbuInitPhaseOneSteps(sqlite3rbu *p){ } } +/* +** The second argument passed to this function is the name of a PRAGMA +** setting - "page_size", "auto_vacuum", "user_version" or "application_id". +** This function executes the following on sqlite3rbu.dbRbu: +** +** "PRAGMA main.$zPragma" +** +** where $zPragma is the string passed as the second argument, then +** on sqlite3rbu.dbMain: +** +** "PRAGMA main.$zPragma = $val" +** +** where $val is the value returned by the first PRAGMA invocation. +** +** In short, it copies the value of the specified PRAGMA setting from +** dbRbu to dbMain. +*/ +static void rbuCopyPragma(sqlite3rbu *p, const char *zPragma){ + if( p->rc==SQLITE_OK ){ + sqlite3_stmt *pPragma = 0; + p->rc = prepareFreeAndCollectError(p->dbRbu, &pPragma, &p->zErrmsg, + sqlite3_mprintf("PRAGMA main.%s", zPragma) + ); + if( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pPragma) ){ + p->rc = rbuMPrintfExec(p, p->dbMain, "PRAGMA main.%s = %d", + zPragma, sqlite3_column_int(pPragma, 0) + ); + } + rbuFinalize(p, pPragma); + } +} + /* ** The RBU handle passed as the only argument has just been opened and ** the state database is empty. If this RBU handle was opened for an @@ -3343,11 +3375,15 @@ static void rbuCreateTargetSchema(sqlite3rbu *p){ sqlite3_stmt *pInsert = 0; assert( rbuIsVacuum(p) ); + p->rc = sqlite3_exec(p->dbMain, "PRAGMA writable_schema=1", 0,0, &p->zErrmsg); + if( p->rc==SQLITE_OK ){ + p->rc = prepareAndCollectError(p->dbRbu, &pSql, &p->zErrmsg, + "SELECT sql FROM sqlite_master WHERE sql!='' AND rootpage!=0" + " AND name!='sqlite_sequence' " + " ORDER BY type DESC" + ); + } - p->rc = prepareAndCollectError(p->dbRbu, &pSql, &p->zErrmsg, - "SELECT sql FROM sqlite_master WHERE sql!='' AND rootpage!=0" - " ORDER BY type DESC" - ); while( p->rc==SQLITE_OK && sqlite3_step(pSql)==SQLITE_ROW ){ const char *zSql = (const char*)sqlite3_column_text(pSql, 0); p->rc = sqlite3_exec(p->dbMain, zSql, 0, 0, &p->zErrmsg); @@ -3355,8 +3391,6 @@ static void rbuCreateTargetSchema(sqlite3rbu *p){ rbuFinalize(p, pSql); if( p->rc!=SQLITE_OK ) return; - p->rc = sqlite3_exec(p->dbMain, "PRAGMA writable_schema=1", 0,0, &p->zErrmsg); - if( p->rc==SQLITE_OK ){ p->rc = prepareAndCollectError(p->dbRbu, &pSql, &p->zErrmsg, "SELECT * FROM sqlite_master WHERE rootpage=0 OR rootpage IS NULL" @@ -3470,6 +3504,11 @@ static sqlite3rbu *openRbuHandle( if( p->eStage==RBU_STAGE_OAL ){ sqlite3 *db = p->dbMain; + if( pState->eStage==0 && rbuIsVacuum(p) ){ + rbuCopyPragma(p, "page_size"); + rbuCopyPragma(p, "auto_vacuum"); + } + /* Open transactions both databases. The *-oal file is opened or ** created at this point. */ p->rc = sqlite3_exec(db, "BEGIN IMMEDIATE", 0, 0, &p->zErrmsg); @@ -3491,6 +3530,8 @@ static sqlite3rbu *openRbuHandle( ** when this handle was opened, create the target database schema. */ if( pState->eStage==0 && rbuIsVacuum(p) ){ rbuCreateTargetSchema(p); + rbuCopyPragma(p, "user_version"); + rbuCopyPragma(p, "application_id"); } /* Point the object iterator at the first object */ @@ -3854,12 +3895,14 @@ static int rbuVfsRead( if( pRbu && rbuIsVacuum(pRbu) && rc==SQLITE_IOERR_SHORT_READ && iOfst==0 && (p->openFlags & SQLITE_OPEN_MAIN_DB) + && pRbu->pRbuFd->base.pMethods ){ sqlite3_file *pFd = (sqlite3_file*)pRbu->pRbuFd; rc = pFd->pMethods->xRead(pFd, zBuf, iAmt, iOfst); if( rc==SQLITE_OK ){ u8 *aBuf = (u8*)zBuf; - rbuPutU32(&aBuf[52], 0); /* largest root page number */ + u32 iRoot = rbuGetU32(&aBuf[52]) ? 1 : 0; + rbuPutU32(&aBuf[52], iRoot); /* largest root page number */ rbuPutU32(&aBuf[36], 0); /* number of free pages */ rbuPutU32(&aBuf[32], 0); /* first page on free list trunk */ rbuPutU32(&aBuf[28], 1); /* size of db file in pages */ diff --git a/manifest b/manifest index 2edcbd1077..d233334b3c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C When\san\sRBU\svacuum\sis\sstarted\son\sa\sdb\sidentified\susing\sa\sURI\sfilename,\spass\sthe\ssame\sURI\sparameters\swhen\screating\sthe\snew\sversion\sof\sthe\sdb.\sThis\sensures\sthat\sRBU\svacuum\sworks\swith\spassword\sprotected\sdatabases. -D 2016-04-19T17:11:05.418 +C Updates\sto\sensure\sthe\svalues\sof\sPRAGMA\ssettings\slike\s"page_size",\s"auto_vacuum",\s"user_version"\sand\s"application_id"\sare\snot\slost\swhen\sa\sdatabase\sis\sRBU\svacuumed. +D 2016-04-19T19:27:09.289 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -246,8 +246,8 @@ F ext/rbu/rbufault2.test 9a7f19edd6ea35c4c9f807d8a3db0a03a5670c06 F ext/rbu/rbufts.test 828cd689da825f0a7b7c53ffc1f6f7fdb6fa5bda F ext/rbu/rbuprogress.test 2023a7df2c523e3df1cb532eff811cda385a789a F ext/rbu/rbusave.test 0f43b6686084f426ddd040b878426452fd2c2f48 -F ext/rbu/rbuvacuum.test b7194617c22f69e2015082a5414585aae2827a29 -F ext/rbu/sqlite3rbu.c 0447a8a306411e585d8595465abbed7709f1feb7 +F ext/rbu/rbuvacuum.test ecd7ce1cd8528d6230b56f4840bbb7188cee6946 +F ext/rbu/sqlite3rbu.c a6c02a67834f9e6c2adb18a9191aa0ae65057cfb F ext/rbu/sqlite3rbu.h 1342ab6121e715b8da59ec35c5b5c16060be7a6b F ext/rbu/test_rbu.c 430b8b9520c233505371d564d3561e0b554355f4 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 @@ -1483,7 +1483,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 00b2f4b09ffca5156e43c4db2bfe0b2c979c49b0 -R e7445097e6cb895f2eea40503c71f11e +P ca021ba88106500f347ed65199a4832bc9eb5ef8 +R 8122ed3aabc11f4475527c60a5badfa5 U dan -Z 90c42b90d6761cf98f1c67d89391cb68 +Z 8cbed13b6f72dec5a4cc65417abbee63 diff --git a/manifest.uuid b/manifest.uuid index f1fc314990..590abb9da7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ca021ba88106500f347ed65199a4832bc9eb5ef8 \ No newline at end of file +74ffea76b8c9ddd7699ce6ca77dce005bd7922ac \ No newline at end of file From 1a55dedf7ba312cc357fdfa669b14323693b6b90 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 20 Apr 2016 00:30:05 +0000 Subject: [PATCH 0325/1484] API Change: Modify sqlite3_enable_load_extension() so that it only enables/disables the load_extension() SQL function, and leaves the C-APIs enabled at all times. In this way, applications can enable extension loading for the C interface without having to expose that capability to the SQL. FossilOrigin-Name: edb454e45ae008e051e2f48d704a855b0c3e4be9 --- manifest | 17 ++++++++++------- manifest.uuid | 2 +- src/func.c | 8 ++++++++ src/loadext.c | 15 --------------- 4 files changed, 19 insertions(+), 23 deletions(-) diff --git a/manifest b/manifest index eb27e8449c..154ad7c55d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\squotes\sfrom\sidentifiers\sused\sas\sdatatype\snames\sin\sa\sCREATE\sTABLE\nstatement.\s\sFix\sfor\sticket\s[7d7525cb01b68] -D 2016-04-18T15:46:14.499 +C API\sChange:\sModify\ssqlite3_enable_load_extension()\sso\sthat\sit\sonly\nenables/disables\sthe\sload_extension()\sSQL\sfunction,\sand\sleaves\sthe\sC-APIs\nenabled\sat\sall\stimes.\s\sIn\sthis\sway,\sapplications\scan\senable\sextension\sloading\nfor\sthe\sC\sinterface\swithout\shaving\sto\sexpose\sthat\scapability\sto\sthe\sSQL. +D 2016-04-20T00:30:05.107 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -332,14 +332,14 @@ F src/delete.c 78eb999114ec04fcf1b7d123ccedb4b5b734930e F src/expr.c 17d4e745ef6a3fd2e4ef863f5f9a4912f1ba1198 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 4c0bd09e602b8ae8d36d81e31e4872d0b53c87bb -F src/func.c 552d300265aed09eea21f68ac742a440550c0062 +F src/func.c 2105701329de3fc2bf47c4153181d412f9f1531c F src/global.c c45ea22aff29334f6a9ec549235ac3357c970015 F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5 F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 F src/insert.c 8f4e9fcbd8e95e85f15647ba8b413b18d556ec2b F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e -F src/loadext.c e70f8f9e97624a232870ea5486e682c813ac3002 +F src/loadext.c 3f74ec102096acc2e33379c8379fced14b66858a F src/main.c 5ac9dccc03faadd6f867f67b9018ff41eeeadb46 F src/malloc.c 1443d1ad95d67c21d77af7ae3f44678252f0efec F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 @@ -1482,7 +1482,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 3a7d72986fabe9434ff5bd02c93169314f072b23 -R 761e3cafabae5f2f003bf21bdc2befe8 +P eba27d4d17a76884292667d570d542e580ee3e77 +R 9873f5bcb700ee71f0df5e53b0b9f6e3 +T *branch * load-ext-security +T *sym-load-ext-security * +T -sym-trunk * U drh -Z 8a9e64fdc933327d2408de0f01f55efc +Z 9467a7a3e92ef67650d6a6e01e05bbf1 diff --git a/manifest.uuid b/manifest.uuid index 540eda5836..6aaf8e7765 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -eba27d4d17a76884292667d570d542e580ee3e77 \ No newline at end of file +edb454e45ae008e051e2f48d704a855b0c3e4be9 \ No newline at end of file diff --git a/src/func.c b/src/func.c index 662a08f504..17ca7ab9a8 100644 --- a/src/func.c +++ b/src/func.c @@ -1386,6 +1386,14 @@ static void loadExt(sqlite3_context *context, int argc, sqlite3_value **argv){ sqlite3 *db = sqlite3_context_db_handle(context); char *zErrMsg = 0; + /* Disallow the load_extension function unless the SQLITE_LoadExtension + ** flag is set. See the sqlite3_enable_load_extension() API. + */ + if( (db->flags & SQLITE_LoadExtension)==0 ){ + sqlite3_result_error(context, "not authorized", -1); + return; + } + if( argc==2 ){ zProc = (const char *)sqlite3_value_text(argv[1]); }else{ diff --git a/src/loadext.c b/src/loadext.c index 495001e55a..7be43cb86d 100644 --- a/src/loadext.c +++ b/src/loadext.c @@ -460,22 +460,7 @@ static int sqlite3LoadExtension( if( pzErrMsg ) *pzErrMsg = 0; - - /* Ticket #1863. To avoid a creating security problems for older - ** applications that relink against newer versions of SQLite, the - ** ability to run load_extension is turned off by default. One - ** must call sqlite3_enable_load_extension() to turn on extension - ** loading. Otherwise you get the following error. - */ - if( (db->flags & SQLITE_LoadExtension)==0 ){ - if( pzErrMsg ){ - *pzErrMsg = sqlite3_mprintf("not authorized"); - } - return SQLITE_ERROR; - } - zEntry = zProc ? zProc : "sqlite3_extension_init"; - handle = sqlite3OsDlOpen(pVfs, zFile); #if SQLITE_OS_UNIX || SQLITE_OS_WIN for(ii=0; ii Date: Wed, 20 Apr 2016 17:47:52 +0000 Subject: [PATCH 0326/1484] Add fault injection tests for rbu vacuum. Fix some problems revealed by the same. FossilOrigin-Name: f042fdd1ea7febec7228e51efc2b0281805e196a --- ext/rbu/rbufault3.test | 98 ++++++++++++++++++++++++++++++++++++++++++ ext/rbu/sqlite3rbu.c | 19 +++++--- manifest | 13 +++--- manifest.uuid | 2 +- 4 files changed, 119 insertions(+), 13 deletions(-) create mode 100644 ext/rbu/rbufault3.test diff --git a/ext/rbu/rbufault3.test b/ext/rbu/rbufault3.test new file mode 100644 index 0000000000..e72eb14f7d --- /dev/null +++ b/ext/rbu/rbufault3.test @@ -0,0 +1,98 @@ +# 2016 April 20 +# +# 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 contains fault injection tests for RBU vacuum operations. +# + +source [file join [file dirname [info script]] rbu_common.tcl] +source $testdir/malloc_common.tcl +set ::testprefix rbufault3 + +foreach {fault errlist} { + oom-* { + {1 SQLITE_NOMEM} + {1 SQLITE_IOERR_NOMEM} + {1 {SQLITE_NOMEM - out of memory}} + } + + ioerr-* { + {1 {SQLITE_IOERR - disk I/O error}} + {1 SQLITE_IOERR} + {1 SQLITE_IOERR_WRITE} + {1 SQLITE_IOERR_FSYNC} + {1 SQLITE_IOERR_READ} + {1 {SQLITE_IOERR - unable to open database: test.db2}} + {1 {SQLITE_ERROR - unable to open database: test.db2}} + {1 {SQLITE_ERROR - SQL logic error or missing database}} + } + + cantopen* { + {1 {SQLITE_CANTOPEN - unable to open database: test.db2}} + {1 {SQLITE_CANTOPEN - unable to open database: test.db2}} + {1 {SQLITE_CANTOPEN - unable to open database file}} + {1 SQLITE_CANTOPEN} + } + +} { + + reset_db + do_execsql_test 0 { + CREATE TABLE target(x UNIQUE, y, z, PRIMARY KEY(y)); + INSERT INTO target VALUES(1, 2, 3); + INSERT INTO target VALUES(4, 5, 6); + INSERT INTO target VALUES(7, 8, 9); + CREATE INDEX i1 ON target(z); + } + faultsim_save_and_close + + do_faultsim_test 1 -faults $fault -prep { + faultsim_restore_and_reopen + forcedelete test.db2 + } -body { + sqlite3rbu_vacuum rbu test.db test.db2 + while {[rbu step]=="SQLITE_OK"} {} + rbu close + } -test { + eval [list faultsim_test_result {0 SQLITE_DONE} {*}$::errlist] + } + + do_faultsim_test 2 -faults $fault -prep { + faultsim_restore_and_reopen + forcedelete test.db2 + } -body { + sqlite3rbu_vacuum rbu test.db test.db2 + rbu step + rbu close + } -test { + eval [list faultsim_test_result {0 SQLITE_OK} {*}$::errlist] + } + + forcedelete test.db2 + sqlite3rbu_vacuum rbu test.db test.db2 + rbu step + rbu close + faultsim_save_and_close + + do_faultsim_test 3 -faults $fault -prep { + faultsim_restore_and_reopen + forcedelete test.db2 + } -body { + sqlite3rbu_vacuum rbu test.db test.db2 + rbu step + rbu close + } -test { + eval [list faultsim_test_result {0 SQLITE_OK} {*}$::errlist] + } + +} + +finish_test + diff --git a/ext/rbu/sqlite3rbu.c b/ext/rbu/sqlite3rbu.c index 8c7682abea..8a1b06dd62 100644 --- a/ext/rbu/sqlite3rbu.c +++ b/ext/rbu/sqlite3rbu.c @@ -2339,7 +2339,7 @@ static void rbuOpenDatabase(sqlite3rbu *p){ /* Open the RBU database */ p->dbRbu = rbuOpenDbhandle(p, p->zRbu, 1); - if( rbuIsVacuum(p) ){ + if( p->rc==SQLITE_OK && rbuIsVacuum(p) ){ sqlite3_file_control(p->dbRbu, "main", SQLITE_FCNTL_RBUCNT, (void*)p); } @@ -2355,11 +2355,13 @@ static void rbuOpenDatabase(sqlite3rbu *p){ /* If it has not already been created, create the rbu_state table */ rbuMPrintfExec(p, p->dbRbu, RBU_CREATE_STATE, p->zStateDb); - if( rbuIsVacuum(p) ){ + if( p->rc==SQLITE_OK && rbuIsVacuum(p) ){ int bOpen = 0; + int rc; p->nRbu = 0; p->pRbuFd = 0; - sqlite3_file_control(p->dbRbu, "main", SQLITE_FCNTL_RBUCNT, (void*)p); + rc = sqlite3_file_control(p->dbRbu, "main", SQLITE_FCNTL_RBUCNT, (void*)p); + if( rc!=SQLITE_NOTFOUND ) p->rc = rc; if( p->eStage>=RBU_STAGE_MOVE ){ bOpen = 1; }else{ @@ -3411,6 +3413,9 @@ static void rbuCreateTargetSchema(sqlite3rbu *p){ sqlite3_step(pInsert); p->rc = sqlite3_reset(pInsert); } + if( p->rc==SQLITE_OK ){ + p->rc = sqlite3_exec(p->dbMain, "PRAGMA writable_schema=0",0,0,&p->zErrmsg); + } rbuFinalize(p, pSql); rbuFinalize(p, pInsert); @@ -3511,7 +3516,9 @@ static sqlite3rbu *openRbuHandle( /* Open transactions both databases. The *-oal file is opened or ** created at this point. */ - p->rc = sqlite3_exec(db, "BEGIN IMMEDIATE", 0, 0, &p->zErrmsg); + if( p->rc==SQLITE_OK ){ + p->rc = sqlite3_exec(db, "BEGIN IMMEDIATE", 0, 0, &p->zErrmsg); + } if( p->rc==SQLITE_OK ){ p->rc = sqlite3_exec(p->dbRbu, "BEGIN", 0, 0, &p->zErrmsg); } @@ -3528,7 +3535,7 @@ static sqlite3rbu *openRbuHandle( /* If this is an RBU vacuum operation and the state table was empty ** when this handle was opened, create the target database schema. */ - if( pState->eStage==0 && rbuIsVacuum(p) ){ + if( p->rc==SQLITE_OK && pState->eStage==0 && rbuIsVacuum(p) ){ rbuCreateTargetSchema(p); rbuCopyPragma(p, "user_version"); rbuCopyPragma(p, "application_id"); @@ -3895,7 +3902,7 @@ static int rbuVfsRead( if( pRbu && rbuIsVacuum(pRbu) && rc==SQLITE_IOERR_SHORT_READ && iOfst==0 && (p->openFlags & SQLITE_OPEN_MAIN_DB) - && pRbu->pRbuFd->base.pMethods + && pRbu->rc==SQLITE_OK ){ sqlite3_file *pFd = (sqlite3_file*)pRbu->pRbuFd; rc = pFd->pMethods->xRead(pFd, zBuf, iAmt, iOfst); diff --git a/manifest b/manifest index d233334b3c..e640d710d0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Updates\sto\sensure\sthe\svalues\sof\sPRAGMA\ssettings\slike\s"page_size",\s"auto_vacuum",\s"user_version"\sand\s"application_id"\sare\snot\slost\swhen\sa\sdatabase\sis\sRBU\svacuumed. -D 2016-04-19T19:27:09.289 +C Add\sfault\sinjection\stests\sfor\srbu\svacuum.\sFix\ssome\sproblems\srevealed\sby\sthe\ssame. +D 2016-04-20T17:47:52.967 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -243,11 +243,12 @@ F ext/rbu/rbucrash.test 8d2ed5d4b05fef6c00c2a6b5f7ead71fa172a695 F ext/rbu/rbudiff.test 2df0a8a7d998ecf81764c21eeda3cde5611c5091 F ext/rbu/rbufault.test cc0be8d5d392d98b0c2d6a51be377ea989250a89 F ext/rbu/rbufault2.test 9a7f19edd6ea35c4c9f807d8a3db0a03a5670c06 +F ext/rbu/rbufault3.test 54a399888ac4af44c68f9f58afbed23149428bca F ext/rbu/rbufts.test 828cd689da825f0a7b7c53ffc1f6f7fdb6fa5bda F ext/rbu/rbuprogress.test 2023a7df2c523e3df1cb532eff811cda385a789a F ext/rbu/rbusave.test 0f43b6686084f426ddd040b878426452fd2c2f48 F ext/rbu/rbuvacuum.test ecd7ce1cd8528d6230b56f4840bbb7188cee6946 -F ext/rbu/sqlite3rbu.c a6c02a67834f9e6c2adb18a9191aa0ae65057cfb +F ext/rbu/sqlite3rbu.c cc44505ef06053077f35b08c4ba11dc8bcf310dc F ext/rbu/sqlite3rbu.h 1342ab6121e715b8da59ec35c5b5c16060be7a6b F ext/rbu/test_rbu.c 430b8b9520c233505371d564d3561e0b554355f4 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 @@ -1483,7 +1484,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ca021ba88106500f347ed65199a4832bc9eb5ef8 -R 8122ed3aabc11f4475527c60a5badfa5 +P 74ffea76b8c9ddd7699ce6ca77dce005bd7922ac +R f86f4403b5c8adf842292353673eca81 U dan -Z 8cbed13b6f72dec5a4cc65417abbee63 +Z 6e60b344cf662b4bf49e9c442360b79f diff --git a/manifest.uuid b/manifest.uuid index 590abb9da7..ce2dab7023 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -74ffea76b8c9ddd7699ce6ca77dce005bd7922ac \ No newline at end of file +f042fdd1ea7febec7228e51efc2b0281805e196a \ No newline at end of file From 333f80562b6bd9bb976f9d276e9586bc82b673cc Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 20 Apr 2016 18:31:27 +0000 Subject: [PATCH 0327/1484] Fix a locking race condition in Windows 10 that can occur when two or more processes attempt to recover the same hot journal at the same time. FossilOrigin-Name: 38a4e9d92887898b779493c71e4500f777a4e2e7 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/os_win.c | 5 ++--- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index eb27e8449c..0271d96ed6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\squotes\sfrom\sidentifiers\sused\sas\sdatatype\snames\sin\sa\sCREATE\sTABLE\nstatement.\s\sFix\sfor\sticket\s[7d7525cb01b68] -D 2016-04-18T15:46:14.499 +C Fix\sa\slocking\srace\scondition\sin\sWindows\s10\sthat\scan\soccur\swhen\stwo\sor\smore\nprocesses\sattempt\sto\srecover\sthe\ssame\shot\sjournal\sat\sthe\ssame\stime. +D 2016-04-20T18:31:27.150 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -360,7 +360,7 @@ F src/os.h 8e976e59eb4ca1c0fca6d35ee803e38951cb0343 F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85 F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa F src/os_unix.c d0b41a47eb5f0dc00e423a1723aadeab0e78c85f -F src/os_win.c b169437dff859e308b3726594094a2f8ca922941 +F src/os_win.c 1997a873bfc8296a701bd8e2df8c3d5da5afe956 F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c 38718a019ca762ba4f6795425d5a54db70d1790d F src/pager.h 329bdf078a4e0a3b35084534d58625d21fd03681 @@ -1482,7 +1482,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 3a7d72986fabe9434ff5bd02c93169314f072b23 -R 761e3cafabae5f2f003bf21bdc2befe8 +P eba27d4d17a76884292667d570d542e580ee3e77 +R 91e3493cbc66272eab1ca1f4455591b7 U drh -Z 8a9e64fdc933327d2408de0f01f55efc +Z f74379d7acb8dab3d54fff08dd9ef3d2 diff --git a/manifest.uuid b/manifest.uuid index 540eda5836..b7ae2958b9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -eba27d4d17a76884292667d570d542e580ee3e77 \ No newline at end of file +38a4e9d92887898b779493c71e4500f777a4e2e7 \ No newline at end of file diff --git a/src/os_win.c b/src/os_win.c index 929ad346cc..1f26463453 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -3169,9 +3169,8 @@ static int winLock(sqlite3_file *id, int locktype){ ** the PENDING_LOCK byte is temporary. */ newLocktype = pFile->locktype; - if( (pFile->locktype==NO_LOCK) - || ( (locktype==EXCLUSIVE_LOCK) - && (pFile->locktype==RESERVED_LOCK)) + if( pFile->locktype==NO_LOCK + || (locktype==EXCLUSIVE_LOCK && pFile->locktype<=RESERVED_LOCK) ){ int cnt = 3; while( cnt-->0 && (res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, From cdce61e133e58112db4377123380de20e37cfc83 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 20 Apr 2016 19:30:47 +0000 Subject: [PATCH 0328/1484] When an error occurs while transitioning out of WAL mode, make sure the locking state is not left at EXCLUSIVE. FossilOrigin-Name: 3340f086510b08ce5b42a8781f1df51bf7c27701 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/pager.c | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 0271d96ed6..3b102ff170 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\slocking\srace\scondition\sin\sWindows\s10\sthat\scan\soccur\swhen\stwo\sor\smore\nprocesses\sattempt\sto\srecover\sthe\ssame\shot\sjournal\sat\sthe\ssame\stime. -D 2016-04-20T18:31:27.150 +C When\san\serror\soccurs\swhile\stransitioning\sout\sof\sWAL\smode,\smake\ssure\sthe\nlocking\sstate\sis\snot\sleft\sat\sEXCLUSIVE. +D 2016-04-20T19:30:47.222 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -362,7 +362,7 @@ F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa F src/os_unix.c d0b41a47eb5f0dc00e423a1723aadeab0e78c85f F src/os_win.c 1997a873bfc8296a701bd8e2df8c3d5da5afe956 F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca -F src/pager.c 38718a019ca762ba4f6795425d5a54db70d1790d +F src/pager.c d20fa46d5beda38095be6070dd4c59e502817c72 F src/pager.h 329bdf078a4e0a3b35084534d58625d21fd03681 F src/parse.y 10eb2f3fb62341291528c7984498054731f9d31e F src/pcache.c 647bb53a86b7bbcf55ad88089b3ea5a9170b90df @@ -1482,7 +1482,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P eba27d4d17a76884292667d570d542e580ee3e77 -R 91e3493cbc66272eab1ca1f4455591b7 +P 38a4e9d92887898b779493c71e4500f777a4e2e7 +R d900f17deba1f548d837d30ffbaf8602 U drh -Z f74379d7acb8dab3d54fff08dd9ef3d2 +Z 44c6d07231ede184477737327be6aaec diff --git a/manifest.uuid b/manifest.uuid index b7ae2958b9..14e0ef795f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -38a4e9d92887898b779493c71e4500f777a4e2e7 \ No newline at end of file +3340f086510b08ce5b42a8781f1df51bf7c27701 \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index c18b3a32f7..2015808089 100644 --- a/src/pager.c +++ b/src/pager.c @@ -7311,6 +7311,7 @@ int sqlite3PagerCloseWal(Pager *pPager){ pPager->pageSize, (u8*)pPager->pTmpSpace); pPager->pWal = 0; pagerFixMaplimit(pPager); + if( rc && !pPager->exclusiveMode ) pagerUnlockDb(pPager, SHARED_LOCK); } } return rc; From 94d49697b506e9c612352809d0ef100d6c5d4fc8 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 20 Apr 2016 20:08:58 +0000 Subject: [PATCH 0329/1484] Add a documentation comment for sqlite3rbu_vacuum() to sqlite3rbu.h. FossilOrigin-Name: da5c753ddac3cbfdf03710a82f5fd9fa2e29e819 --- ext/rbu/sqlite3rbu.c | 36 ++++++++++++++++++++++++++++++++++++ ext/rbu/sqlite3rbu.h | 22 +++++++++++++++++++++- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 65 insertions(+), 9 deletions(-) diff --git a/ext/rbu/sqlite3rbu.c b/ext/rbu/sqlite3rbu.c index 8a1b06dd62..022e682bde 100644 --- a/ext/rbu/sqlite3rbu.c +++ b/ext/rbu/sqlite3rbu.c @@ -2352,9 +2352,45 @@ static void rbuOpenDatabase(sqlite3rbu *p){ memcpy(p->zStateDb, "main", 4); } +#if 0 + if( p->rc==SQLITE_OK && rbuIsVacuum(p) ){ + p->rc = sqlite3_exec(p->dbRbu, "BEGIN", 0, 0, 0); + } +#endif + /* If it has not already been created, create the rbu_state table */ rbuMPrintfExec(p, p->dbRbu, RBU_CREATE_STATE, p->zStateDb); +#if 0 + if( rbuIsVacuum(p) ){ + if( p->rc==SQLITE_OK ){ + int rc2; + int bOk = 0; + sqlite3_stmt *pCnt = 0; + p->rc = prepareAndCollectError(p->dbRbu, &pCnt, &p->zErrmsg, + "SELECT count(*) FROM stat.sqlite_master" + ); + if( p->rc==SQLITE_OK + && sqlite3_step(pCnt)==SQLITE_ROW + && 1==sqlite3_column_int(pCnt, 0) + ){ + bOk = 1; + } + rc2 = sqlite3_finalize(pCnt); + if( p->rc==SQLITE_OK ) p->rc = rc2; + + if( p->rc==SQLITE_OK && bOk==0 ){ + p->rc = SQLITE_ERROR; + p->zErrmsg = sqlite3_mprintf("invalid state database"); + } + + if( p->rc==SQLITE_OK ){ + p->rc = sqlite3_exec(p->dbRbu, "COMMIT", 0, 0, 0); + } + } + } +#endif + if( p->rc==SQLITE_OK && rbuIsVacuum(p) ){ int bOpen = 0; int rc; diff --git a/ext/rbu/sqlite3rbu.h b/ext/rbu/sqlite3rbu.h index b910866293..c0c95e51fd 100644 --- a/ext/rbu/sqlite3rbu.h +++ b/ext/rbu/sqlite3rbu.h @@ -315,7 +315,27 @@ sqlite3rbu *sqlite3rbu_open( ); /* -** Open an RBU handle to perform an RBU vacuum database file zTarget. +** Open an RBU handle to perform an RBU vacuum on database file zTarget. +** An RBU vacuum is similar to SQLite's built-in VACUUM command, except +** that it can be suspended and resumed like an RBU update. +** +** The second argument to this function, which may not be NULL, identifies +** a database in which to store the state of the RBU vacuum operation if +** it is suspended. The first time sqlite3rbu_vacuum() is called, to start +** an RBU vacuum operation, the state database should either not exist or +** be empty (contain no tables). If an RBU vacuum is suspended by calling +** sqlite3rbu_close() on the RBU handle before sqlite3rbu_step() has +** returned SQLITE_DONE, the vacuum state is stored in the state database. +** The vacuum can be resumed by calling this function to open a new RBU +** handle specifying the same target and state databases. +** +** This function does not delete the state database after an RBU vacuum +** is completed, even if it created it. +** +** As with sqlite3rbu_open(), Zipvfs users should rever to the comment +** describing the sqlite3rbu_create_vfs() API function below for +** a description of the complications associated with using RBU with +** zipvfs databases. */ sqlite3rbu *sqlite3rbu_vacuum( const char *zTarget, diff --git a/manifest b/manifest index e640d710d0..1ec956e979 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sfault\sinjection\stests\sfor\srbu\svacuum.\sFix\ssome\sproblems\srevealed\sby\sthe\ssame. -D 2016-04-20T17:47:52.967 +C Add\sa\sdocumentation\scomment\sfor\ssqlite3rbu_vacuum()\sto\ssqlite3rbu.h. +D 2016-04-20T20:08:58.990 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -248,8 +248,8 @@ F ext/rbu/rbufts.test 828cd689da825f0a7b7c53ffc1f6f7fdb6fa5bda F ext/rbu/rbuprogress.test 2023a7df2c523e3df1cb532eff811cda385a789a F ext/rbu/rbusave.test 0f43b6686084f426ddd040b878426452fd2c2f48 F ext/rbu/rbuvacuum.test ecd7ce1cd8528d6230b56f4840bbb7188cee6946 -F ext/rbu/sqlite3rbu.c cc44505ef06053077f35b08c4ba11dc8bcf310dc -F ext/rbu/sqlite3rbu.h 1342ab6121e715b8da59ec35c5b5c16060be7a6b +F ext/rbu/sqlite3rbu.c 80ab68658a1dc1921a3eee7c666c948ea640087c +F ext/rbu/sqlite3rbu.h efcafd0e36861943a88deb181753236f84dbc244 F ext/rbu/test_rbu.c 430b8b9520c233505371d564d3561e0b554355f4 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 F ext/rtree/rtree.c 0b870ccb7b58b734a2a8e1e2755a7c0ded070920 @@ -1484,7 +1484,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 74ffea76b8c9ddd7699ce6ca77dce005bd7922ac -R f86f4403b5c8adf842292353673eca81 +P f042fdd1ea7febec7228e51efc2b0281805e196a +R 20401012c91c212b91bec1accca1e5a8 U dan -Z 6e60b344cf662b4bf49e9c442360b79f +Z ebff3ad2f969914e02c51eda888da39a diff --git a/manifest.uuid b/manifest.uuid index ce2dab7023..ffe63d9829 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f042fdd1ea7febec7228e51efc2b0281805e196a \ No newline at end of file +da5c753ddac3cbfdf03710a82f5fd9fa2e29e819 \ No newline at end of file From 191dd06195817f9bf0b4250a28dddd97e9622762 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 21 Apr 2016 01:30:09 +0000 Subject: [PATCH 0330/1484] Revert sqlite3_enable_load_extension() to its original long-standing behavior. Add SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION which will enable only the C-API and leave the SQL function disabled. FossilOrigin-Name: b2ae5bfa32e608625bd177907596df3dbc2212e1 --- manifest | 25 +++++++++++-------------- manifest.uuid | 2 +- src/func.c | 7 ++----- src/loadext.c | 20 ++++++++++++++++++-- src/main.c | 1 + src/sqlite.h.in | 40 +++++++++++++++++++++++++++++++++++++++- src/sqliteInt.h | 15 ++++++++------- src/test1.c | 1 + 8 files changed, 81 insertions(+), 30 deletions(-) diff --git a/manifest b/manifest index 154ad7c55d..a06de3ef6e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C API\sChange:\sModify\ssqlite3_enable_load_extension()\sso\sthat\sit\sonly\nenables/disables\sthe\sload_extension()\sSQL\sfunction,\sand\sleaves\sthe\sC-APIs\nenabled\sat\sall\stimes.\s\sIn\sthis\sway,\sapplications\scan\senable\sextension\sloading\nfor\sthe\sC\sinterface\swithout\shaving\sto\sexpose\sthat\scapability\sto\sthe\sSQL. -D 2016-04-20T00:30:05.107 +C Revert\ssqlite3_enable_load_extension()\sto\sits\soriginal\slong-standing\sbehavior.\nAdd\sSQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION\swhich\swill\senable\sonly\sthe\sC-API\sand\nleave\sthe\sSQL\sfunction\sdisabled. +D 2016-04-21T01:30:09.828 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -332,15 +332,15 @@ F src/delete.c 78eb999114ec04fcf1b7d123ccedb4b5b734930e F src/expr.c 17d4e745ef6a3fd2e4ef863f5f9a4912f1ba1198 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 4c0bd09e602b8ae8d36d81e31e4872d0b53c87bb -F src/func.c 2105701329de3fc2bf47c4153181d412f9f1531c +F src/func.c b61726e7a1b8f41464d8391d0f2d8a6be1a45281 F src/global.c c45ea22aff29334f6a9ec549235ac3357c970015 F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5 F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 F src/insert.c 8f4e9fcbd8e95e85f15647ba8b413b18d556ec2b F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e -F src/loadext.c 3f74ec102096acc2e33379c8379fced14b66858a -F src/main.c 5ac9dccc03faadd6f867f67b9018ff41eeeadb46 +F src/loadext.c 8b3a73f0624c5f7cadbd5cb89940783bee1d39a6 +F src/main.c 405d13e3a4f7c5add9fb27702ae70ed0a6e32cca F src/malloc.c 1443d1ad95d67c21d77af7ae3f44678252f0efec F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b @@ -377,15 +377,15 @@ F src/resolve.c b8f7174e5f8c33c44ded3a25a973d0bb89228c20 F src/rowset.c 9fe4b3ad7cc00944386bb600233d8f523de07a6e F src/select.c 30217121bdf6b587462150b8ee9e1467f7a6036b F src/shell.c 14ff7f660530a52b117d110ba3390b7b2eb719b6 -F src/sqlite.h.in 64eb70a3b309751bebf73a5552a51244f68f0ea5 +F src/sqlite.h.in 9984129d86243424b765fcb3f147c697bd20bb54 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 98f72cbfe00169c39089115427d06ea05fe4b4a2 -F src/sqliteInt.h 49cd2b5cd07cca7c462608540cb6dfa8ab03ba89 +F src/sqliteInt.h ec538389481a3d093f07fb344c5a9dc988042304 F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 F src/tclsqlite.c 9c4c4589d078de37813ded708d8838b338ffb060 -F src/test1.c 457c601302b8a0f5960dffd17b6a2877603841dd +F src/test1.c abc10e3e81258835aeb59616685d7369ba99ad1e F src/test2.c 5586f43fcd9a1be0830793cf9d354082c261b25b F src/test3.c a8887dabbbee3059af338f20d290084a63ed1b0f F src/test4.c d168f83cc78d02e8d35567bb5630e40dcd85ac1e @@ -1482,10 +1482,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P eba27d4d17a76884292667d570d542e580ee3e77 -R 9873f5bcb700ee71f0df5e53b0b9f6e3 -T *branch * load-ext-security -T *sym-load-ext-security * -T -sym-trunk * +P edb454e45ae008e051e2f48d704a855b0c3e4be9 +R 1ffd5268513054a5c042ef7eabb85336 U drh -Z 9467a7a3e92ef67650d6a6e01e05bbf1 +Z 6cdb5487d5064dce1cac61ac30e9bbbf diff --git a/manifest.uuid b/manifest.uuid index 6aaf8e7765..5c2ea41ae7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -edb454e45ae008e051e2f48d704a855b0c3e4be9 \ No newline at end of file +b2ae5bfa32e608625bd177907596df3dbc2212e1 \ No newline at end of file diff --git a/src/func.c b/src/func.c index 17ca7ab9a8..651591d8c8 100644 --- a/src/func.c +++ b/src/func.c @@ -1386,13 +1386,10 @@ static void loadExt(sqlite3_context *context, int argc, sqlite3_value **argv){ sqlite3 *db = sqlite3_context_db_handle(context); char *zErrMsg = 0; - /* Disallow the load_extension function unless the SQLITE_LoadExtension + /* Disallow the load_extension() SQL function unless the SQLITE_LoadExtFunc ** flag is set. See the sqlite3_enable_load_extension() API. */ - if( (db->flags & SQLITE_LoadExtension)==0 ){ - sqlite3_result_error(context, "not authorized", -1); - return; - } + if( (db->flags & SQLITE_LoadExtFunc)==0 ) return; if( argc==2 ){ zProc = (const char *)sqlite3_value_text(argv[1]); diff --git a/src/loadext.c b/src/loadext.c index 7be43cb86d..f881d99710 100644 --- a/src/loadext.c +++ b/src/loadext.c @@ -460,7 +460,23 @@ static int sqlite3LoadExtension( if( pzErrMsg ) *pzErrMsg = 0; + + /* Ticket #1863. To avoid a creating security problems for older + ** applications that relink against newer versions of SQLite, the + ** ability to run load_extension is turned off by default. One + ** must call either sqlite3_enable_load_extension(db) or + ** sqlite3_db_config(db, SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, 1, 0) + ** to turn on extension loading. + */ + if( (db->flags & SQLITE_LoadExtension)==0 ){ + if( pzErrMsg ){ + *pzErrMsg = sqlite3_mprintf("not authorized"); + } + return SQLITE_ERROR; + } + zEntry = zProc ? zProc : "sqlite3_extension_init"; + handle = sqlite3OsDlOpen(pVfs, zFile); #if SQLITE_OS_UNIX || SQLITE_OS_WIN for(ii=0; iimutex); if( onoff ){ - db->flags |= SQLITE_LoadExtension; + db->flags |= SQLITE_LoadExtension|SQLITE_LoadExtFunc; }else{ - db->flags &= ~SQLITE_LoadExtension; + db->flags &= ~(SQLITE_LoadExtension|SQLITE_LoadExtFunc); } sqlite3_mutex_leave(db->mutex); return SQLITE_OK; diff --git a/src/main.c b/src/main.c index 9f773667af..30370f8cab 100644 --- a/src/main.c +++ b/src/main.c @@ -804,6 +804,7 @@ int sqlite3_db_config(sqlite3 *db, int op, ...){ { SQLITE_DBCONFIG_ENABLE_FKEY, SQLITE_ForeignKeys }, { SQLITE_DBCONFIG_ENABLE_TRIGGER, SQLITE_EnableTrigger }, { SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER, SQLITE_Fts3Tokenizer }, + { SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, SQLITE_LoadExtension }, }; unsigned int i; rc = SQLITE_ERROR; /* IMP: R-42790-23372 */ diff --git a/src/sqlite.h.in b/src/sqlite.h.in index d50d826b41..795236f587 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -1932,12 +1932,30 @@ struct sqlite3_mem_methods { ** following this call. The second parameter may be a NULL pointer, in ** which case the new setting is not reported back. ** +**
    SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION
    +**
    ^This option is used to enable or disable the [sqlite3_load_extension()] +** interface independently of the [load_extension()] SQL function. +** The [sqlite3_enable_load_extension()] API enables or disables both the +** C-API [sqlite3_load_extension()] and the SQL function [load_extension()]. +** There should be two additional arguments. +** When the first argument to this interface is 1, then only the C-API is +** enabled and the SQL function remains disabled. If the first argment to +** this interface is 0, then both the C-API and the SQL function are disabled. +** If the first argument is -1, then no changes are made to state of either the +** C-API or the SQL function. +** The second parameter is a pointer to an integer into which +** is written 0 or 1 to indicate whether [sqlite3_load_extension()] interface +** is disabled or enabled following this call. The second parameter may +** be a NULL pointer, in which case the new setting is not reported back. +**
    +** ** */ #define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */ #define SQLITE_DBCONFIG_ENABLE_FKEY 1002 /* int int* */ #define SQLITE_DBCONFIG_ENABLE_TRIGGER 1003 /* int int* */ #define SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER 1004 /* int int* */ +#define SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 1005 /* int int* */ /* @@ -5474,9 +5492,18 @@ int sqlite3_table_column_metadata( ** should free this memory by calling [sqlite3_free()]. ** ** ^Extension loading must be enabled using -** [sqlite3_enable_load_extension()] prior to calling this API, +** [sqlite3_enable_load_extension()] or +** [sqlite3_db_config](db,[SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION],1,NULL) +** prior to calling this API, ** otherwise an error will be returned. ** +** Security warning: It is recommended that the +** [SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION] method be used to enable only this +** interface. The use of the [sqlite3_enable_load_extension()] interface +** should be avoided. This will keep the SQL function [load_extension()] +** disabled and prevent SQL injections from giving attackers +** access to extension loading capabilities. +** ** See also the [load_extension() SQL function]. */ int sqlite3_load_extension( @@ -5499,6 +5526,17 @@ int sqlite3_load_extension( ** ^Call the sqlite3_enable_load_extension() routine with onoff==1 ** to turn extension loading on and call it with onoff==0 to turn ** it back off again. +** +** ^This interface enables or disables both the C-API +** [sqlite3_load_extension()] and the SQL function [load_extension()]. +** Use [sqlite3_db_config](db,[SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION],..) +** to enable or disable only the C-API. +** +** Security warning: It is recommended that extension loading +** be disabled using the [SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION] method +** rather than this interface, so the [load_extension()] SQL function +** remains disabled. This will prevent SQL injections from giving attackers +** access to extension loading capabilities. */ int sqlite3_enable_load_extension(sqlite3 *db, int onoff); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index fe7203b8e1..7bb15d0bf5 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1382,13 +1382,14 @@ struct sqlite3 { #define SQLITE_AutoIndex 0x00100000 /* Enable automatic indexes */ #define SQLITE_PreferBuiltin 0x00200000 /* Preference to built-in funcs */ #define SQLITE_LoadExtension 0x00400000 /* Enable load_extension */ -#define SQLITE_EnableTrigger 0x00800000 /* True to enable triggers */ -#define SQLITE_DeferFKs 0x01000000 /* Defer all FK constraints */ -#define SQLITE_QueryOnly 0x02000000 /* Disable database changes */ -#define SQLITE_VdbeEQP 0x04000000 /* Debug EXPLAIN QUERY PLAN */ -#define SQLITE_Vacuum 0x08000000 /* Currently in a VACUUM */ -#define SQLITE_CellSizeCk 0x10000000 /* Check btree cell sizes on load */ -#define SQLITE_Fts3Tokenizer 0x20000000 /* Enable fts3_tokenizer(2) */ +#define SQLITE_LoadExtFunc 0x00800000 /* Enable load_extension() SQL func */ +#define SQLITE_EnableTrigger 0x01000000 /* True to enable triggers */ +#define SQLITE_DeferFKs 0x02000000 /* Defer all FK constraints */ +#define SQLITE_QueryOnly 0x04000000 /* Disable database changes */ +#define SQLITE_VdbeEQP 0x08000000 /* Debug EXPLAIN QUERY PLAN */ +#define SQLITE_Vacuum 0x10000000 /* Currently in a VACUUM */ +#define SQLITE_CellSizeCk 0x20000000 /* Check btree cell sizes on load */ +#define SQLITE_Fts3Tokenizer 0x40000000 /* Enable fts3_tokenizer(2) */ /* diff --git a/src/test1.c b/src/test1.c index 0c5af822c9..5478a72549 100644 --- a/src/test1.c +++ b/src/test1.c @@ -6988,6 +6988,7 @@ static int test_sqlite3_db_config( { "FKEY", SQLITE_DBCONFIG_ENABLE_FKEY }, { "TRIGGER", SQLITE_DBCONFIG_ENABLE_TRIGGER }, { "FTS3_TOKENIZER", SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER }, + { "LOAD_EXTENSION", SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION }, }; int i; int v; From f602a1612338718d8b20bfc7d5467fb46b4cb228 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 21 Apr 2016 01:58:21 +0000 Subject: [PATCH 0331/1484] Test cases for SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION. FossilOrigin-Name: debafa5efd37ac60e030d0963ce8e7c4f51a0f10 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/func.c | 5 ++++- test/loadext.test | 12 +++++++++++- 4 files changed, 23 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index a06de3ef6e..05c486ec05 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Revert\ssqlite3_enable_load_extension()\sto\sits\soriginal\slong-standing\sbehavior.\nAdd\sSQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION\swhich\swill\senable\sonly\sthe\sC-API\sand\nleave\sthe\sSQL\sfunction\sdisabled. -D 2016-04-21T01:30:09.828 +C Test\scases\sfor\sSQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION. +D 2016-04-21T01:58:21.573 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -332,7 +332,7 @@ F src/delete.c 78eb999114ec04fcf1b7d123ccedb4b5b734930e F src/expr.c 17d4e745ef6a3fd2e4ef863f5f9a4912f1ba1198 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 4c0bd09e602b8ae8d36d81e31e4872d0b53c87bb -F src/func.c b61726e7a1b8f41464d8391d0f2d8a6be1a45281 +F src/func.c ef4c18c8a66143413ce41a58d582d2c14ddf78e1 F src/global.c c45ea22aff29334f6a9ec549235ac3357c970015 F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5 F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094 @@ -875,7 +875,7 @@ F test/like.test 81632c437a947bf1f7130b19537da6a1a844806a F test/like2.test 3b2ee13149ba4a8a60b59756f4e5d345573852da F test/like3.test 3608a2042b6f922f900fbfd5d3ce4e7eca57f7c4 F test/limit.test 0c99a27a87b14c646a9d583c7c89fd06c352663e -F test/loadext.test 648cb95f324d1775c54a55c12271b2d1156b633b +F test/loadext.test 42a3b8166dfcadcb0e0c8710dc520d97c31a8b98 F test/loadext2.test 0408380b57adca04004247179837a18e866a74f7 F test/lock.test b984ab9034e7389be0d863fe4e64cbbc4d2028f5 F test/lock2.test 5242d8ac4e2d59c403aebff606af449b455aceff @@ -1482,7 +1482,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P edb454e45ae008e051e2f48d704a855b0c3e4be9 -R 1ffd5268513054a5c042ef7eabb85336 +P b2ae5bfa32e608625bd177907596df3dbc2212e1 +R 142ad50676c76bf1cd4debbac256d360 U drh -Z 6cdb5487d5064dce1cac61ac30e9bbbf +Z d6546b0e1c5ecba4524ffa3ce100a1b6 diff --git a/manifest.uuid b/manifest.uuid index 5c2ea41ae7..7305430aec 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b2ae5bfa32e608625bd177907596df3dbc2212e1 \ No newline at end of file +debafa5efd37ac60e030d0963ce8e7c4f51a0f10 \ No newline at end of file diff --git a/src/func.c b/src/func.c index 651591d8c8..4feedc7440 100644 --- a/src/func.c +++ b/src/func.c @@ -1389,7 +1389,10 @@ static void loadExt(sqlite3_context *context, int argc, sqlite3_value **argv){ /* Disallow the load_extension() SQL function unless the SQLITE_LoadExtFunc ** flag is set. See the sqlite3_enable_load_extension() API. */ - if( (db->flags & SQLITE_LoadExtFunc)==0 ) return; + if( (db->flags & SQLITE_LoadExtFunc)==0 ){ + sqlite3_result_error(context, "not authorized", -1); + return; + } if( argc==2 ){ zProc = (const char *)sqlite3_value_text(argv[1]); diff --git a/test/loadext.test b/test/loadext.test index 7ba4c0cf77..e6ba21e187 100644 --- a/test/loadext.test +++ b/test/loadext.test @@ -111,7 +111,7 @@ do_test loadext-1.2 { # do_test loadext-1.3 { sqlite3 db2 test.db - sqlite3_enable_load_extension db2 1 + sqlite3_db_config db2 SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 1 catchsql { SELECT half(1.0); } db2 @@ -256,6 +256,7 @@ do_test loadext-4.2 { } } {0 {{}}} +# disable all extension loading do_test loadext-4.3 { sqlite3_enable_load_extension db 0 catchsql { @@ -263,6 +264,15 @@ do_test loadext-4.3 { } } {1 {not authorized}} +# enable C-api extension loading only. Show that the SQL function +# still does not work. +do_test loadext-4.4 { + sqlite3_db_config db SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 1 + catchsql { + SELECT load_extension($::testextension,'testloadext_init') + } +} {1 {not authorized}} + source $testdir/malloc_common.tcl From 6bcfe8b61f6b9390622670de373359159fe06d44 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 21 Apr 2016 15:24:46 +0000 Subject: [PATCH 0332/1484] Add a function prototype in order to fix a compiler warning. FossilOrigin-Name: 49aec9718d61c9f12aed96f530128666c3b01c81 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/pcache.h | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 5048173d7c..8a5fd27015 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\supdates\sfrom\strunk. -D 2016-04-21T15:03:37.535 +C Add\sa\sfunction\sprototype\sin\sorder\sto\sfix\sa\scompiler\swarning. +D 2016-04-21T15:24:46.372 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -366,7 +366,7 @@ F src/pager.c bb8c7ff706aa88e7c2ec9a6175a128c01bc3ae5f F src/pager.h 329bdf078a4e0a3b35084534d58625d21fd03681 F src/parse.y 10eb2f3fb62341291528c7984498054731f9d31e F src/pcache.c b3230ecfc7f797063fbe167f2845da363e8f07f8 -F src/pcache.h 60bc9893bfc0e16f8178fb5d8b6fcb8fab1d93c0 +F src/pcache.h 6b865be765d1ebd06145219550b10921c7da7cc9 F src/pcache1.c c40cdb93586e21b5dd826b5e671240bd91c26b05 F src/pragma.c faf42922bb7ab2f6672cb550356c1967abae3c84 F src/pragma.h 64c78a648751b9f4f297276c4eb7507b14b4628c @@ -1484,7 +1484,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d9768de502e34da42f3ad955947c23da50f57bce c4f165c460c4244ed434107feac005efa3c386cf -R 46a947ce1c80cd48530d3e6dff00dfca +P cc28106e5c196c0a9678fbbd06f6afd49271a8e8 +R c97bc8da233adc2bbb054b217c885bd5 U drh -Z 049109eccf475c334bc4eb599a0e0693 +Z fa8f1e96dc1996c819bff77f7b75b34d diff --git a/manifest.uuid b/manifest.uuid index 8cdc841c3b..31bd76e737 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cc28106e5c196c0a9678fbbd06f6afd49271a8e8 \ No newline at end of file +49aec9718d61c9f12aed96f530128666c3b01c81 \ No newline at end of file diff --git a/src/pcache.h b/src/pcache.h index 0caf605ff8..04bce289d0 100644 --- a/src/pcache.h +++ b/src/pcache.h @@ -99,6 +99,7 @@ void sqlite3PcacheDrop(PgHdr*); /* Remove page from cache */ void sqlite3PcacheMakeDirty(PgHdr*); /* Make sure page is marked dirty */ void sqlite3PcacheMakeClean(PgHdr*); /* Mark a single page as clean */ void sqlite3PcacheCleanAll(PCache*); /* Mark all dirty list pages as clean */ +void sqlite3PcacheClearWritable(PCache*); /* Change a page number. Used by incr-vacuum. */ void sqlite3PcacheMove(PgHdr*, Pgno); From 2e8bfb67d4a6de7029f62573bdc44b6ce9c47d78 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 21 Apr 2016 15:26:26 +0000 Subject: [PATCH 0333/1484] Fix a problem in rbu vacuum on tables with a large sqlite_master table. FossilOrigin-Name: 23eac52e987996afe8db847921aef434cebd25b5 --- ext/rbu/rbuvacuum.test | 15 +++++++++++++++ ext/rbu/sqlite3rbu.c | 4 ++-- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 25 insertions(+), 10 deletions(-) diff --git a/ext/rbu/rbuvacuum.test b/ext/rbu/rbuvacuum.test index 85ecfc4c13..c67162c567 100644 --- a/ext/rbu/rbuvacuum.test +++ b/ext/rbu/rbuvacuum.test @@ -241,6 +241,21 @@ foreach step {0 1} { PRAGMA main.user_version; PRAGMA main.application_id; } {8192 2 412 413} + + # Vacuum a database with a large sqlite_master table. + # + reset_db + do_test 1.10.1 { + for {set i 1} {$i < 50} {incr i} { + execsql "PRAGMA page_size = 1024" + execsql "CREATE TABLE t$i (a, b, c, PRIMARY KEY(a, b));" + execsql " + INSERT INTO t$i VALUES(1, 2, 3); + INSERT INTO t$i VALUES(4, 5, 6); + " + } + } {} + do_rbu_vacuum_test 1.10.2 $step } #------------------------------------------------------------------------- diff --git a/ext/rbu/sqlite3rbu.c b/ext/rbu/sqlite3rbu.c index 022e682bde..04dc9944d7 100644 --- a/ext/rbu/sqlite3rbu.c +++ b/ext/rbu/sqlite3rbu.c @@ -3952,9 +3952,9 @@ static int rbuVfsRead( rbuPutU32(&aBuf[24], pRbu->pRbuFd->iCookie+1); /* Change counter */ if( iAmt>100 ){ - assert( iAmt>=101 ); - memset(&aBuf[101], 0, iAmt-101); + memset(&aBuf[100], 0, iAmt-100); rbuPutU16(&aBuf[105], iAmt & 0xFFFF); + aBuf[100] = 0x0D; } } } diff --git a/manifest b/manifest index 1ec956e979..dbe7f79adc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sa\sdocumentation\scomment\sfor\ssqlite3rbu_vacuum()\sto\ssqlite3rbu.h. -D 2016-04-20T20:08:58.990 +C Fix\sa\sproblem\sin\srbu\svacuum\son\stables\swith\sa\slarge\ssqlite_master\stable. +D 2016-04-21T15:26:26.501 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -247,8 +247,8 @@ F ext/rbu/rbufault3.test 54a399888ac4af44c68f9f58afbed23149428bca F ext/rbu/rbufts.test 828cd689da825f0a7b7c53ffc1f6f7fdb6fa5bda F ext/rbu/rbuprogress.test 2023a7df2c523e3df1cb532eff811cda385a789a F ext/rbu/rbusave.test 0f43b6686084f426ddd040b878426452fd2c2f48 -F ext/rbu/rbuvacuum.test ecd7ce1cd8528d6230b56f4840bbb7188cee6946 -F ext/rbu/sqlite3rbu.c 80ab68658a1dc1921a3eee7c666c948ea640087c +F ext/rbu/rbuvacuum.test aa405cff38b15a89f6c97f91f1c6a67b2140b358 +F ext/rbu/sqlite3rbu.c 8310553b029e749329a89b3880a21f80876755c3 F ext/rbu/sqlite3rbu.h efcafd0e36861943a88deb181753236f84dbc244 F ext/rbu/test_rbu.c 430b8b9520c233505371d564d3561e0b554355f4 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 @@ -1484,7 +1484,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P f042fdd1ea7febec7228e51efc2b0281805e196a -R 20401012c91c212b91bec1accca1e5a8 +P da5c753ddac3cbfdf03710a82f5fd9fa2e29e819 +R e2636288f7318e2301180a849b5ff72b U dan -Z ebff3ad2f969914e02c51eda888da39a +Z d9d3e7dacedd64ed84574ca4c0316d8e diff --git a/manifest.uuid b/manifest.uuid index ffe63d9829..8f13cab8e3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -da5c753ddac3cbfdf03710a82f5fd9fa2e29e819 \ No newline at end of file +23eac52e987996afe8db847921aef434cebd25b5 \ No newline at end of file From b7a208686ae0a1cbe8aac5919e9502a023ec8409 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 21 Apr 2016 16:44:38 +0000 Subject: [PATCH 0334/1484] If a call to sqlite3rbu_close() on an rbu handle opened by sqlite3rbu_vacuum() returns other than SQLITE_OK, delete the contents of the rbu_state table. This ensures that if an RBU vacuum operation either completes successfully or encounters an error, the next call to sqlite3rbu_vacuum() with the same parameters starts a new RBU vacuum operation. FossilOrigin-Name: 6e4ac704f51bdd1e0b16814f6a45ab29f26400ee --- ext/rbu/rbuvacuum.test | 3 --- ext/rbu/sqlite3rbu.c | 10 ++++++++++ ext/rbu/sqlite3rbu.h | 6 +++++- manifest | 16 ++++++++-------- manifest.uuid | 2 +- 5 files changed, 24 insertions(+), 13 deletions(-) diff --git a/ext/rbu/rbuvacuum.test b/ext/rbu/rbuvacuum.test index c67162c567..96a37d1f71 100644 --- a/ext/rbu/rbuvacuum.test +++ b/ext/rbu/rbuvacuum.test @@ -19,7 +19,6 @@ set ::testprefix rbuvacuum proc do_rbu_vacuum_test {tn step} { uplevel [list do_test $tn.1 { - forcedelete state.db if {$step==0} { sqlite3rbu_vacuum rbu test.db state.db } while 1 { if {$step==1} { sqlite3rbu_vacuum rbu test.db state.db } @@ -275,7 +274,6 @@ do_execsql_test 2.1.0 { INSERT INTO t1 VALUES(9, 10); } wal do_test 2.1.1 { - forcedelete state.db sqlite3rbu_vacuum rbu test.db state.db rbu step } {SQLITE_ERROR} @@ -294,7 +292,6 @@ do_execsql_test 2.2.0 { } db_save_and_close for {set i 1} 1 {incr i} { - forcedelete state.db db_restore_and_reopen sqlite3rbu_vacuum rbu test.db state.db diff --git a/ext/rbu/sqlite3rbu.c b/ext/rbu/sqlite3rbu.c index 04dc9944d7..e7e4ddef58 100644 --- a/ext/rbu/sqlite3rbu.c +++ b/ext/rbu/sqlite3rbu.c @@ -3685,6 +3685,16 @@ int sqlite3rbu_close(sqlite3rbu *p, char **pzErrmsg){ /* Close any open statement handles. */ rbuObjIterFinalize(&p->objiter); + /* If this is an RBU vacuum handle and the vacuum has either finished + ** successfully or encountered an error, delete the contents of the + ** state table. This causes the next call to sqlite3rbu_vacuum() + ** specifying the current target and state databases to start a new + ** vacuum from scratch. */ + if( rbuIsVacuum(p) && p->rc!=SQLITE_OK && p->dbRbu ){ + int rc2 = sqlite3_exec(p->dbRbu, "DELETE FROM stat.rbu_state", 0, 0, 0); + if( p->rc==SQLITE_DONE && rc2!=SQLITE_OK ) p->rc = rc2; + } + /* Close the open database handle and VFS object. */ sqlite3_close(p->dbRbu); sqlite3_close(p->dbMain); diff --git a/ext/rbu/sqlite3rbu.h b/ext/rbu/sqlite3rbu.h index c0c95e51fd..fce9e493db 100644 --- a/ext/rbu/sqlite3rbu.h +++ b/ext/rbu/sqlite3rbu.h @@ -330,7 +330,11 @@ sqlite3rbu *sqlite3rbu_open( ** handle specifying the same target and state databases. ** ** This function does not delete the state database after an RBU vacuum -** is completed, even if it created it. +** is completed, even if it created it. However, if the call to +** sqlite3rbu_close() returns any value other than SQLITE_OK, the contents +** of the state tables within the state database are zeroed. This way, +** the next call to sqlite3rbu_vacuum() opens a handle that starts a +** new RBU vacuum operation. ** ** As with sqlite3rbu_open(), Zipvfs users should rever to the comment ** describing the sqlite3rbu_create_vfs() API function below for diff --git a/manifest b/manifest index dbe7f79adc..a1b6be3a3e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\sin\srbu\svacuum\son\stables\swith\sa\slarge\ssqlite_master\stable. -D 2016-04-21T15:26:26.501 +C If\sa\scall\sto\ssqlite3rbu_close()\son\san\srbu\shandle\sopened\sby\ssqlite3rbu_vacuum()\sreturns\sother\sthan\sSQLITE_OK,\sdelete\sthe\scontents\sof\sthe\srbu_state\stable.\sThis\sensures\sthat\sif\san\sRBU\svacuum\soperation\seither\scompletes\ssuccessfully\sor\sencounters\san\serror,\sthe\snext\scall\sto\ssqlite3rbu_vacuum()\swith\sthe\ssame\sparameters\sstarts\sa\snew\sRBU\svacuum\soperation. +D 2016-04-21T16:44:38.130 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -247,9 +247,9 @@ F ext/rbu/rbufault3.test 54a399888ac4af44c68f9f58afbed23149428bca F ext/rbu/rbufts.test 828cd689da825f0a7b7c53ffc1f6f7fdb6fa5bda F ext/rbu/rbuprogress.test 2023a7df2c523e3df1cb532eff811cda385a789a F ext/rbu/rbusave.test 0f43b6686084f426ddd040b878426452fd2c2f48 -F ext/rbu/rbuvacuum.test aa405cff38b15a89f6c97f91f1c6a67b2140b358 -F ext/rbu/sqlite3rbu.c 8310553b029e749329a89b3880a21f80876755c3 -F ext/rbu/sqlite3rbu.h efcafd0e36861943a88deb181753236f84dbc244 +F ext/rbu/rbuvacuum.test bcbc1dcd8e2a46a811e46477692ae1c0e8917a85 +F ext/rbu/sqlite3rbu.c 20922328dcebe89589638923bb46840df8bc7733 +F ext/rbu/sqlite3rbu.h 2acd0a6344a6079de15c8dc9d84d3df83a665930 F ext/rbu/test_rbu.c 430b8b9520c233505371d564d3561e0b554355f4 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 F ext/rtree/rtree.c 0b870ccb7b58b734a2a8e1e2755a7c0ded070920 @@ -1484,7 +1484,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P da5c753ddac3cbfdf03710a82f5fd9fa2e29e819 -R e2636288f7318e2301180a849b5ff72b +P 23eac52e987996afe8db847921aef434cebd25b5 +R 9f2af869b142a7169421543b9ca51ae8 U dan -Z d9d3e7dacedd64ed84574ca4c0316d8e +Z 717b7e491d25b95d9f80b6c2df00ade7 diff --git a/manifest.uuid b/manifest.uuid index 8f13cab8e3..ef1798e1f0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -23eac52e987996afe8db847921aef434cebd25b5 \ No newline at end of file +6e4ac704f51bdd1e0b16814f6a45ab29f26400ee \ No newline at end of file From 7694e06461203a466865fc8ed3068e0990a7ca50 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 21 Apr 2016 23:37:24 +0000 Subject: [PATCH 0335/1484] Change the temporary directory search algorithm on unix so that directories with only -wx permission are allowed. And do not allow "." to be returned if it lacks -wx permission. FossilOrigin-Name: 67985761aa93fb613b87d340e75371fa55b0f778 --- manifest | 15 +++++++-------- manifest.uuid | 2 +- src/os_unix.c | 8 +++++--- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 084953dacb..df9a5ec95f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\ssqlite3rbu_vacuum()\sAPI,\sto\screate\san\sRBU\shandle\sthat\scan\sbe\sused\sto\srebuild\sa\sdatabase\sin\sthe\ssame\sway\sas\sthe\sVACUUM\scommand. -D 2016-04-21T18:13:37.597 +C Change\sthe\stemporary\sdirectory\ssearch\salgorithm\son\sunix\sso\sthat\sdirectories\nwith\sonly\s-wx\spermission\sare\sallowed.\s\sAnd\sdo\snot\sallow\s"."\sto\sbe\sreturned\sif\nit\slacks\s-wx\spermission. +D 2016-04-21T23:37:24.378 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -361,7 +361,7 @@ F src/os.c 4d83917f072ad958fba9235136fa2ed43df47905 F src/os.h 8e976e59eb4ca1c0fca6d35ee803e38951cb0343 F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85 F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa -F src/os_unix.c d0b41a47eb5f0dc00e423a1723aadeab0e78c85f +F src/os_unix.c c96826e21e897bf9c6ae896be9de8d55d63a4ed5 F src/os_win.c 1997a873bfc8296a701bd8e2df8c3d5da5afe956 F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c d20fa46d5beda38095be6070dd4c59e502817c72 @@ -1484,8 +1484,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P c4f165c460c4244ed434107feac005efa3c386cf 6e4ac704f51bdd1e0b16814f6a45ab29f26400ee -R 4089c7bed4eb395c7a148d5eb16b1be4 -T +closed 6e4ac704f51bdd1e0b16814f6a45ab29f26400ee -U dan -Z 0e5a7e5d2cf2990714a283851c232d22 +P bd4a6f8313eb71399a7141ebf7f2617d7b1464c3 +R 90c3ca98d0d4d69b4119d1fe5513a916 +U drh +Z f4304caf089d5c38523c57ca13360c36 diff --git a/manifest.uuid b/manifest.uuid index a983c0514a..65f89ba88b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bd4a6f8313eb71399a7141ebf7f2617d7b1464c3 \ No newline at end of file +67985761aa93fb613b87d340e75371fa55b0f778 \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index aa86f00d70..9a97515fdc 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -5420,10 +5420,10 @@ static const char *unixTempFileDir(void){ if( zDir==0 ) continue; if( osStat(zDir, &buf) ) continue; if( !S_ISDIR(buf.st_mode) ) continue; - if( osAccess(zDir, 07) ) continue; - break; + if( osAccess(zDir, 03) ) continue; + return zDir; } - return zDir; + return 0; } /* @@ -5439,9 +5439,11 @@ static int unixGetTempname(int nBuf, char *zBuf){ ** using the io-error infrastructure to test that SQLite handles this ** function failing. */ + zBuf[0] = 0; SimulateIOError( return SQLITE_IOERR ); zDir = unixTempFileDir(); + if( zDir==0 ) return SQLITE_IOERR_GETTEMPPATH; do{ u64 r; sqlite3_randomness(sizeof(r), &r); From 6572c16ae1a1f554475c4993eb0c753a2c5cf8d9 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 23 Apr 2016 14:55:28 +0000 Subject: [PATCH 0336/1484] Fix some problems to do with temp-file databases and recovering from IO and SQLITE_FULL errors. FossilOrigin-Name: 3d61da4a76af8c9c2a293df085f3ed5a7bb447df --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/pager.c | 26 +++++++++++++++----------- test/tempfault.test | 30 +++++++++++++++++++++++++----- 4 files changed, 49 insertions(+), 25 deletions(-) diff --git a/manifest b/manifest index 8a5fd27015..ec3e51504b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sa\sfunction\sprototype\sin\sorder\sto\sfix\sa\scompiler\swarning. -D 2016-04-21T15:24:46.372 +C Fix\ssome\sproblems\sto\sdo\swith\stemp-file\sdatabases\sand\srecovering\sfrom\sIO\sand\sSQLITE_FULL\serrors. +D 2016-04-23T14:55:28.020 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -362,7 +362,7 @@ F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa F src/os_unix.c d0b41a47eb5f0dc00e423a1723aadeab0e78c85f F src/os_win.c 1997a873bfc8296a701bd8e2df8c3d5da5afe956 F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca -F src/pager.c bb8c7ff706aa88e7c2ec9a6175a128c01bc3ae5f +F src/pager.c 4981dc6154ce111361a7cd35eaa26aadf8914ea3 F src/pager.h 329bdf078a4e0a3b35084534d58625d21fd03681 F src/parse.y 10eb2f3fb62341291528c7984498054731f9d31e F src/pcache.c b3230ecfc7f797063fbe167f2845da363e8f07f8 @@ -1109,7 +1109,7 @@ F test/tableapi.test 2674633fa95d80da917571ebdd759a14d9819126 F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930 F test/tclsqlite.test e1306001a0ca92250b691ea6d3cecaca5b6342aa F test/tempdb.test bd92eba8f20e16a9136e434e20b280794de3cdb6 -F test/tempfault.test 0c80f23c651cf6452c27cacf09f4c2ee9527a912 +F test/tempfault.test 0c0d349c9a99bf5f374655742577f8712c647900 F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30 F test/temptable2.test e62783549be26283e1b3725f0de3309411be6c84 F test/temptrigger.test 8ec228b0db5d7ebc4ee9b458fc28cb9e7873f5e1 @@ -1484,7 +1484,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P cc28106e5c196c0a9678fbbd06f6afd49271a8e8 -R c97bc8da233adc2bbb054b217c885bd5 -U drh -Z fa8f1e96dc1996c819bff77f7b75b34d +P 49aec9718d61c9f12aed96f530128666c3b01c81 +R 98471ae1c4ed8f399ba91e3e119d0ef8 +U dan +Z 4115a15d29a4b7f5f76b2491e48cc4f1 diff --git a/manifest.uuid b/manifest.uuid index 31bd76e737..7b1996a745 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -49aec9718d61c9f12aed96f530128666c3b01c81 \ No newline at end of file +3d61da4a76af8c9c2a293df085f3ed5a7bb447df \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index 41d3297e29..a749b8a6b3 100644 --- a/src/pager.c +++ b/src/pager.c @@ -1824,12 +1824,16 @@ static void pager_unlock(Pager *pPager){ ** This is because it is not possible to call pager_reset() on a temp ** file pager (as this may discard the only copy of some data). */ assert( pPager->errCode==SQLITE_OK || !MEMDB ); - if( pPager->tempFile==0 && pPager->errCode ){ - pager_reset(pPager); - pPager->changeCountDone = 0; - pPager->eState = PAGER_OPEN; - pPager->errCode = SQLITE_OK; + if( pPager->errCode ){ + if( pPager->tempFile==0 ){ + pager_reset(pPager); + pPager->changeCountDone = 0; + pPager->eState = PAGER_OPEN; + }else{ + pPager->eState = (isOpen(pPager->jfd) ? PAGER_OPEN : PAGER_READER); + } if( USEFETCH(pPager) ) sqlite3OsUnfetch(pPager->fd, 0, 0); + pPager->errCode = SQLITE_OK; } pPager->journalOff = 0; @@ -2319,7 +2323,7 @@ static int pager_playback_one_page( pPg = sqlite3PagerLookup(pPager, pgno); } assert( pPg || !MEMDB ); - assert( pPager->eState!=PAGER_OPEN || pPg==0 ); + assert( pPager->eState!=PAGER_OPEN || pPg==0 || pPager->tempFile ); PAGERTRACE(("PLAYBACK %d page %d hash(%08x) %s\n", PAGERID(pPager), pgno, pager_datahash(pPager->pageSize, (u8*)aData), (isMainJrnl?"main-journal":"sub-journal") @@ -5052,17 +5056,17 @@ int sqlite3PagerSharedLock(Pager *pPager){ /* This routine is only called from b-tree and only when there are no ** outstanding pages. This implies that the pager state should either ** be OPEN or READER. READER is only possible if the pager is or was in - ** exclusive access mode. - */ + ** exclusive access mode. */ assert( sqlite3PcacheRefCount(pPager->pPCache)==0 ); assert( assert_pager_state(pPager) ); - if( pPager->tempFile && pPager->errCode ) { return pPager->errCode; } assert( pPager->eState==PAGER_OPEN || pPager->eState==PAGER_READER ); + assert( pPager->errCode==SQLITE_OK ); if( !pagerUseWal(pPager) && pPager->eState==PAGER_OPEN ){ int bHotJournal = 1; /* True if there exists a hot journal-file */ assert( !MEMDB ); + assert( pPager->tempFile==0 || pPager->eLock==EXCLUSIVE_LOCK ); rc = pager_wait_on_lock(pPager, SHARED_LOCK); if( rc!=SQLITE_OK ){ @@ -5148,7 +5152,7 @@ int sqlite3PagerSharedLock(Pager *pPager){ assert( rc==SQLITE_OK ); rc = pagerSyncHotJournal(pPager); if( rc==SQLITE_OK ){ - rc = pager_playback(pPager, 1); + rc = pager_playback(pPager, !pPager->tempFile); pPager->eState = PAGER_OPEN; } }else if( !pPager->exclusiveMode ){ @@ -5244,7 +5248,7 @@ int sqlite3PagerSharedLock(Pager *pPager){ rc = pagerBeginReadTransaction(pPager); } - if( pPager->eState==PAGER_OPEN && rc==SQLITE_OK ){ + if( pPager->tempFile==0 && pPager->eState==PAGER_OPEN && rc==SQLITE_OK ){ rc = pagerPagecount(pPager, &pPager->dbSize); } diff --git a/test/tempfault.test b/test/tempfault.test index da1ae12375..4eae116a72 100644 --- a/test/tempfault.test +++ b/test/tempfault.test @@ -18,9 +18,9 @@ source $testdir/tester.tcl source $testdir/malloc_common.tcl set testprefix tempfault -sqlite3_memdebug_vfs_oom_test 0 +# sqlite3_memdebug_vfs_oom_test 0 -do_faultsim_test 1 -faults oom* -prep { +do_faultsim_test 1 -faults * -prep { sqlite3 db "" db eval { PRAGMA page_size = 1024; @@ -42,14 +42,14 @@ do_faultsim_test 1 -faults oom* -prep { faultsim_integrity_check } -do_faultsim_test 2 -faults oom* -prep { +do_faultsim_test 2 -faults * -prep { sqlite3 db "" db eval { PRAGMA page_size = 1024; PRAGMA cache_size = 10; CREATE TABLE t1(a, b); CREATE INDEX i1 ON t1(b, a); - WITH x(i) AS (SELECT 1 UNION ALL SELECT i+1 FROM x WHERE i<50) + WITH x(i) AS (SELECT 1 UNION ALL SELECT i+1 FROM x WHERE i<100) INSERT INTO t1 SELECT randomblob(100), randomblob(100) FROM x; } } -body { @@ -59,7 +59,27 @@ do_faultsim_test 2 -faults oom* -prep { faultsim_integrity_check db } -do_faultsim_test 3 -faults oom* -prep { +catch { db close } +do_faultsim_test 2.1 -faults * -prep { + if {[info commands db]==""} { + sqlite3 db "" + execsql { + PRAGMA page_size = 1024; + PRAGMA cache_size = 10; + CREATE TABLE t1(a, b); + CREATE INDEX i1 ON t1(b, a); + WITH x(i) AS (SELECT 1 UNION ALL SELECT i+1 FROM x WHERE i<100) + INSERT INTO t1 SELECT randomblob(100), randomblob(100) FROM x; + } + } +} -body { + execsql { UPDATE t1 SET a = randomblob(99) } +} -test { + faultsim_test_result {0 {}} + faultsim_integrity_check db +} + +do_faultsim_test 3 -faults * -prep { sqlite3 db "" db eval { PRAGMA page_size = 1024; From 2d36f065e2843175057dba4e4e34fa3df6541357 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 23 Apr 2016 17:24:16 +0000 Subject: [PATCH 0337/1484] Fix a problem with mixing temp-files and mmap-mode. FossilOrigin-Name: c80c5c62b2e2c5e47e0839f8e2d5b6341ca4a249 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/pager.c | 6 +++--- test/temptable2.test | 29 +++++++++++++++++++++++++++++ 4 files changed, 40 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index ec3e51504b..c7f8ab468f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\ssome\sproblems\sto\sdo\swith\stemp-file\sdatabases\sand\srecovering\sfrom\sIO\sand\sSQLITE_FULL\serrors. -D 2016-04-23T14:55:28.020 +C Fix\sa\sproblem\swith\smixing\stemp-files\sand\smmap-mode. +D 2016-04-23T17:24:16.091 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -362,7 +362,7 @@ F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa F src/os_unix.c d0b41a47eb5f0dc00e423a1723aadeab0e78c85f F src/os_win.c 1997a873bfc8296a701bd8e2df8c3d5da5afe956 F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca -F src/pager.c 4981dc6154ce111361a7cd35eaa26aadf8914ea3 +F src/pager.c cbc8996b773c191107b771424b529307ffdf19ba F src/pager.h 329bdf078a4e0a3b35084534d58625d21fd03681 F src/parse.y 10eb2f3fb62341291528c7984498054731f9d31e F src/pcache.c b3230ecfc7f797063fbe167f2845da363e8f07f8 @@ -1111,7 +1111,7 @@ F test/tclsqlite.test e1306001a0ca92250b691ea6d3cecaca5b6342aa F test/tempdb.test bd92eba8f20e16a9136e434e20b280794de3cdb6 F test/tempfault.test 0c0d349c9a99bf5f374655742577f8712c647900 F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30 -F test/temptable2.test e62783549be26283e1b3725f0de3309411be6c84 +F test/temptable2.test 31485911fb33e72c7737087ba5a2b35acafba55a F test/temptrigger.test 8ec228b0db5d7ebc4ee9b458fc28cb9e7873f5e1 F test/tester.tcl 7b740ee852c55e1e72b6ebe5044acee7aa4e5553 F test/thread001.test 9f22fd3525a307ff42a326b6bc7b0465be1745a5 @@ -1484,7 +1484,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 49aec9718d61c9f12aed96f530128666c3b01c81 -R 98471ae1c4ed8f399ba91e3e119d0ef8 +P 3d61da4a76af8c9c2a293df085f3ed5a7bb447df +R 85df4f851dc9e804fc35d28f4dbcf65b U dan -Z 4115a15d29a4b7f5f76b2491e48cc4f1 +Z 50e48f2ab5de65ac7aff6f1c82162e94 diff --git a/manifest.uuid b/manifest.uuid index 7b1996a745..865e4fbe13 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3d61da4a76af8c9c2a293df085f3ed5a7bb447df \ No newline at end of file +c80c5c62b2e2c5e47e0839f8e2d5b6341ca4a249 \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index a749b8a6b3..3f2a131877 100644 --- a/src/pager.c +++ b/src/pager.c @@ -2034,7 +2034,7 @@ static int pager_end_transaction(Pager *pPager, int hasMaster, int bCommit){ sqlite3BitvecDestroy(pPager->pInJournal); pPager->pInJournal = 0; pPager->nRec = 0; - if( pagerFlushOnCommit(pPager) ){ + if( MEMDB || pagerFlushOnCommit(pPager) ){ sqlite3PcacheCleanAll(pPager->pPCache); }else{ sqlite3PcacheClearWritable(pPager->pPCache); @@ -5381,7 +5381,7 @@ int sqlite3PagerGet( ); if( rc==SQLITE_OK && pData ){ - if( pPager->eState>PAGER_READER ){ + if( pPager->eState>PAGER_READER || pPager->tempFile ){ pPg = sqlite3PagerLookup(pPager, pgno); } if( pPg==0 ){ @@ -6219,7 +6219,7 @@ int sqlite3PagerCommitPhaseOne( assert( MEMDB==0 || pPager->tempFile ); assert( isOpen(pPager->fd) || pPager->tempFile ); - if( !isOpen(pPager->fd) ){ + if( 0==pagerFlushOnCommit(pPager) ){ /* If this is an in-memory db, or no pages have been written to, or this ** function has already been called, it is mostly a no-op. However, any ** backup in progress needs to be restarted. */ diff --git a/test/temptable2.test b/test/temptable2.test index c5e53de635..d71c168ebf 100644 --- a/test/temptable2.test +++ b/test/temptable2.test @@ -316,5 +316,34 @@ foreach {tn mode} { } } +#------------------------------------------------------------------------- +# When using mmap mode with a temp file, SQLite must search the cache +# before using a mapped page even when there is no write transaction +# open. For a temp file, the on-disk version may not be up to date. +# +sqlite3 db "" +do_execsql_test 10.0 { + PRAGMA cache_size = 50; + PRAGMA page_size = 1024; + CREATE TABLE t1(a, b, PRIMARY KEY(a)) WITHOUT ROWID; + CREATE INDEX i1 ON t1(a); + CREATE TABLE t2(x, y); + INSERT INTO t2 VALUES(1, 2); +} + +do_execsql_test 10.1 { + BEGIN; + WITH x(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM x WHERE i<500 ) + INSERT INTO t1 SELECT randomblob(100), randomblob(100) FROM x; + COMMIT; + INSERT INTO t2 VALUES(3, 4); +} + +do_execsql_test 10.2 { + PRAGMA mmap_size = 512000; + SELECT * FROM t2; + PRAGMA integrity_check; +} {512000 1 2 3 4 ok} + finish_test From 23ee89375284ba23b42d81c4ce3a39d656b0996d Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 23 Apr 2016 20:59:23 +0000 Subject: [PATCH 0338/1484] Fix the fix to the temporary directory search algorithm so that it continues to return "." as a fallback if that directory has the correct permissions. FossilOrigin-Name: b38fe522cfc971b37ca04e7b63a92bbb6e0b01e1 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/os_unix.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index df9a5ec95f..366814ad84 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sthe\stemporary\sdirectory\ssearch\salgorithm\son\sunix\sso\sthat\sdirectories\nwith\sonly\s-wx\spermission\sare\sallowed.\s\sAnd\sdo\snot\sallow\s"."\sto\sbe\sreturned\sif\nit\slacks\s-wx\spermission. -D 2016-04-21T23:37:24.378 +C Fix\sthe\sfix\sto\sthe\stemporary\sdirectory\ssearch\salgorithm\sso\sthat\sit\scontinues\nto\sreturn\s"."\sas\sa\sfallback\sif\sthat\sdirectory\shas\sthe\scorrect\spermissions. +D 2016-04-23T20:59:23.071 F Makefile.in eba680121821b8a60940a81454316f47a341487a F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -361,7 +361,7 @@ F src/os.c 4d83917f072ad958fba9235136fa2ed43df47905 F src/os.h 8e976e59eb4ca1c0fca6d35ee803e38951cb0343 F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85 F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa -F src/os_unix.c c96826e21e897bf9c6ae896be9de8d55d63a4ed5 +F src/os_unix.c 2488a2b6456709ad6398df2302d427a980e2695a F src/os_win.c 1997a873bfc8296a701bd8e2df8c3d5da5afe956 F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c d20fa46d5beda38095be6070dd4c59e502817c72 @@ -1484,7 +1484,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P bd4a6f8313eb71399a7141ebf7f2617d7b1464c3 -R 90c3ca98d0d4d69b4119d1fe5513a916 +P 67985761aa93fb613b87d340e75371fa55b0f778 +R 0a3904801876ad35cfb663a63395f63c U drh -Z f4304caf089d5c38523c57ca13360c36 +Z 2d6519bfb47a62ce49b104a4f37d1acb diff --git a/manifest.uuid b/manifest.uuid index 65f89ba88b..f26bce27a6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -67985761aa93fb613b87d340e75371fa55b0f778 \ No newline at end of file +b38fe522cfc971b37ca04e7b63a92bbb6e0b01e1 \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index 9a97515fdc..aadb414afe 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -5416,7 +5416,7 @@ static const char *unixTempFileDir(void){ if( !azDirs[0] ) azDirs[0] = getenv("SQLITE_TMPDIR"); if( !azDirs[1] ) azDirs[1] = getenv("TMPDIR"); - for(i=0; i Date: Mon, 25 Apr 2016 01:43:24 +0000 Subject: [PATCH 0339/1484] Fix a typo in the Makefile. FossilOrigin-Name: d0a579b35105810821bbfec6b50ecfebac7a17ee --- Makefile.in | 2 +- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Makefile.in b/Makefile.in index 2606b5a654..8200cf2357 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1032,7 +1032,7 @@ FTS5_SRC = \ fts5parse.c: $(TOP)/ext/fts5/fts5parse.y lemon cp $(TOP)/ext/fts5/fts5parse.y . rm -f fts5parse.h - ./lemon $(OPTS) fts5parse.y + ./lemon$(BEXE) $(OPTS) fts5parse.y fts5parse.h: fts5parse.c diff --git a/manifest b/manifest index 366814ad84..aba5d698fd 100644 --- a/manifest +++ b/manifest @@ -1,6 +1,6 @@ -C Fix\sthe\sfix\sto\sthe\stemporary\sdirectory\ssearch\salgorithm\sso\sthat\sit\scontinues\nto\sreturn\s"."\sas\sa\sfallback\sif\sthat\sdirectory\shas\sthe\scorrect\spermissions. -D 2016-04-23T20:59:23.071 -F Makefile.in eba680121821b8a60940a81454316f47a341487a +C Fix\sa\stypo\sin\sthe\sMakefile. +D 2016-04-25T01:43:24.306 +F Makefile.in a905f3180accdafbd5a534bf26126ee5306d5056 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7 @@ -1484,7 +1484,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 67985761aa93fb613b87d340e75371fa55b0f778 -R 0a3904801876ad35cfb663a63395f63c -U drh -Z 2d6519bfb47a62ce49b104a4f37d1acb +P b38fe522cfc971b37ca04e7b63a92bbb6e0b01e1 +R 5aa002889bfcaf382a8424adff459dd7 +U mistachkin +Z 272f168dd75d48a808379cca7049b3ce diff --git a/manifest.uuid b/manifest.uuid index f26bce27a6..41e73dfc0b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b38fe522cfc971b37ca04e7b63a92bbb6e0b01e1 \ No newline at end of file +d0a579b35105810821bbfec6b50ecfebac7a17ee \ No newline at end of file From b1ec87afdbed6096a2f968becb619710eb12a122 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 25 Apr 2016 02:20:10 +0000 Subject: [PATCH 0340/1484] When checking for the WHERE-clause push-down optimization, verify that all terms of the compound inner SELECT are non-aggregate, not just the last term. Fix for ticket [f7f8c97e97597]. FossilOrigin-Name: ec215f94ac9748c0acd82af0cc9e7a92249462f9 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/select.c | 14 +++++++++----- test/select4.test | 36 ++++++++++++++++++++++++++++++++++++ 4 files changed, 54 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index aba5d698fd..10b7a29fe4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\stypo\sin\sthe\sMakefile. -D 2016-04-25T01:43:24.306 +C When\schecking\sfor\sthe\sWHERE-clause\spush-down\soptimization,\sverify\sthat\nall\sterms\sof\sthe\scompound\sinner\sSELECT\sare\snon-aggregate,\snot\sjust\sthe\nlast\sterm.\s\sFix\sfor\sticket\s[f7f8c97e97597]. +D 2016-04-25T02:20:10.236 F Makefile.in a905f3180accdafbd5a534bf26126ee5306d5056 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -377,7 +377,7 @@ F src/printf.c 63e6fb12bbe702dd664dc3703776c090383a5a26 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c b8f7174e5f8c33c44ded3a25a973d0bb89228c20 F src/rowset.c 9fe4b3ad7cc00944386bb600233d8f523de07a6e -F src/select.c 30217121bdf6b587462150b8ee9e1467f7a6036b +F src/select.c fd4a7ce2937497181063cfedb92058ac89491a5d F src/shell.c 14ff7f660530a52b117d110ba3390b7b2eb719b6 F src/sqlite.h.in 9984129d86243424b765fcb3f147c697bd20bb54 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1026,7 +1026,7 @@ F test/securedel2.test 2d54c28e46eb1fd6902089958b20b1b056c6f1c5 F test/select1.test be62204d2bd9a5a8a149e9974cfddce893d8f686 F test/select2.test 352480e0e9c66eda9c3044e412abdf5be0215b56 F test/select3.test 2ce595f8fb8e2ac10071d3b4e424cadd4634a054 -F test/select4.test d926792a5e4d88fef0ddcddeb45d27ce75f7296c +F test/select4.test 5389d9895968d1196c457d59b3ee6515d771d328 F test/select5.test e758b8ef94f69b111df4cb819008856655dcd535 F test/select6.test 39eac4a5c03650b2b473c532882273283ee8b7a0 F test/select7.test 95e370c42d47c3c52377d05e9ffc01ccff7c1f61 @@ -1484,7 +1484,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b38fe522cfc971b37ca04e7b63a92bbb6e0b01e1 -R 5aa002889bfcaf382a8424adff459dd7 -U mistachkin -Z 272f168dd75d48a808379cca7049b3ce +P d0a579b35105810821bbfec6b50ecfebac7a17ee +R 858c551be0612332d0982a3a42946fb6 +U drh +Z c1158477a3c6966fdb5709eb9b3c8fe5 diff --git a/manifest.uuid b/manifest.uuid index 41e73dfc0b..580a058689 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d0a579b35105810821bbfec6b50ecfebac7a17ee \ No newline at end of file +ec215f94ac9748c0acd82af0cc9e7a92249462f9 \ No newline at end of file diff --git a/src/select.c b/src/select.c index b86e040f0f..eb37536b6f 100644 --- a/src/select.c +++ b/src/select.c @@ -3785,14 +3785,18 @@ static int pushDownWhereTerms( ){ Expr *pNew; int nChng = 0; + Select *pX; /* For looping over compound SELECTs in pSubq */ if( pWhere==0 ) return 0; - if( (pSubq->selFlags & (SF_Aggregate|SF_Recursive))!=0 ){ - testcase( pSubq->selFlags & SF_Aggregate ); - testcase( pSubq->selFlags & SF_Recursive ); - return 0; /* restrictions (1) and (2) */ + for(pX=pSubq; pX; pX=pX->pPrior){ + if( (pX->selFlags & (SF_Aggregate|SF_Recursive))!=0 ){ + testcase( pX->selFlags & SF_Aggregate ); + testcase( pX->selFlags & SF_Recursive ); + testcase( pX!=pSubq ); + return 0; /* restrictions (1) and (2) */ + } } if( pSubq->pLimit!=0 ){ - return 0; /* restriction (3) */ + return 0; /* restriction (3) */ } while( pWhere->op==TK_AND ){ nChng += pushDownWhereTerms(db, pSubq, pWhere->pRight, iCursor); diff --git a/test/select4.test b/test/select4.test index 1f29f29073..51a1b1c4c5 100644 --- a/test/select4.test +++ b/test/select4.test @@ -968,6 +968,42 @@ do_execsql_test select4-16.3 { ORDER BY t3.a; } {95 96 97 98 99} +# Ticket https://www.sqlite.org/src/tktview/f7f8c97e975978d45 on 2016-04-25 +# +# The where push-down optimization from 2015-06-02 is suppose to disable +# on aggregate subqueries. But if the subquery is a compound where the +# last SELECT is non-aggregate but some other SELECT is an aggregate, the +# test is incomplete and the optimization is not properly disabled. +# +# The following test cases verify that the fix works. +# +do_execsql_test select4-17.1 { + DROP TABLE IF EXISTS t1; + CREATE TABLE t1(a int, b int); + INSERT INTO t1 VALUES(1,2),(1,18),(2,19); + SELECT x, y FROM ( + SELECT 98 AS x, 99 AS y + UNION + SELECT a AS x, sum(b) AS y FROM t1 GROUP BY a + ) AS w WHERE y>=20 + ORDER BY +x; +} {1 20 98 99} +do_execsql_test select4-17.2 { + SELECT x, y FROM ( + SELECT a AS x, sum(b) AS y FROM t1 GROUP BY a + UNION + SELECT 98 AS x, 99 AS y + ) AS w WHERE y>=20 + ORDER BY +x; +} {1 20 98 99} +do_catchsql_test select4-17.3 { + SELECT x, y FROM ( + SELECT a AS x, sum(b) AS y FROM t1 GROUP BY a LIMIT 3 + UNION + SELECT 98 AS x, 99 AS y + ) AS w WHERE y>=20 + ORDER BY +x; +} {1 {LIMIT clause should come after UNION not before}} From 835f22dedade668d99034711a3758ca32752e716 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 25 Apr 2016 19:20:56 +0000 Subject: [PATCH 0341/1484] Fix some unreachable branches in the pager. FossilOrigin-Name: 3ae44770fdecc40c8097f1de0b504f36585a2232 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/pager.c | 18 ++++++++++-------- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index 713cf4421c..acd08f3f4f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sbug\sfix\sfrom\strunk. -D 2016-04-25T15:03:49.467 +C Fix\ssome\sunreachable\sbranches\sin\sthe\spager. +D 2016-04-25T19:20:56.371 F Makefile.in a905f3180accdafbd5a534bf26126ee5306d5056 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -364,7 +364,7 @@ F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa F src/os_unix.c 2488a2b6456709ad6398df2302d427a980e2695a F src/os_win.c 1997a873bfc8296a701bd8e2df8c3d5da5afe956 F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca -F src/pager.c cbc8996b773c191107b771424b529307ffdf19ba +F src/pager.c a31af55dd6139c6ece7642667a035028a266d344 F src/pager.h 329bdf078a4e0a3b35084534d58625d21fd03681 F src/parse.y 10eb2f3fb62341291528c7984498054731f9d31e F src/pcache.c b3230ecfc7f797063fbe167f2845da363e8f07f8 @@ -1486,7 +1486,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 9b8fec60d8e576cd09e1d075a59bfad1c6169d7a ec215f94ac9748c0acd82af0cc9e7a92249462f9 -R e941df834a8d6e2084dd43227adc9b5d +P a905d5e08de3f3c60b667d840b5995911372647d +R 1f1507f9b43194c78dbe59034ff5cd5c U drh -Z 530f6cc77507869285e9eb18ff03544a +Z 8869ed19649f951f40d0b8fe31c4bd6b diff --git a/manifest.uuid b/manifest.uuid index 02d571129d..010c2a556f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a905d5e08de3f3c60b667d840b5995911372647d \ No newline at end of file +3ae44770fdecc40c8097f1de0b504f36585a2232 \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index 3f2a131877..0a185c3e37 100644 --- a/src/pager.c +++ b/src/pager.c @@ -872,6 +872,7 @@ static int assert_pager_state(Pager *p){ ** state. */ if( MEMDB ){ + assert( !isOpen(p->fd) ); assert( p->noSync ); assert( p->journalMode==PAGER_JOURNALMODE_OFF || p->journalMode==PAGER_JOURNALMODE_MEMORY @@ -3204,6 +3205,8 @@ static int pagerPagecount(Pager *pPager, Pgno *pnPage){ */ assert( pPager->eState==PAGER_OPEN ); assert( pPager->eLock>=SHARED_LOCK ); + assert( isOpen(pPager->fd) ); + assert( pPager->tempFile==0 ); nPage = sqlite3WalDbsize(pPager->pWal); /* If the number of pages in the database is not available from the @@ -3211,14 +3214,11 @@ static int pagerPagecount(Pager *pPager, Pgno *pnPage){ ** the database file. If the size of the database file is not an ** integer multiple of the page-size, round up the result. */ - if( nPage==0 ){ + if( nPage==0 && ALWAYS(isOpen(pPager->fd)) ){ i64 n = 0; /* Size of db file in bytes */ - assert( isOpen(pPager->fd) || pPager->tempFile ); - if( isOpen(pPager->fd) ){ - int rc = sqlite3OsFileSize(pPager->fd, &n); - if( rc!=SQLITE_OK ){ - return rc; - } + int rc = sqlite3OsFileSize(pPager->fd, &n); + if( rc!=SQLITE_OK ){ + return rc; } nPage = (Pgno)((n+pPager->pageSize-1) / pPager->pageSize); } @@ -4964,6 +4964,7 @@ static int hasHotJournal(Pager *pPager, int *pExists){ if( rc==SQLITE_OK && !locked ){ Pgno nPage; /* Number of pages in database file */ + assert( pPager->tempFile==0 ); rc = pagerPagecount(pPager, &nPage); if( rc==SQLITE_OK ){ /* If the database is zero pages in size, that means that either (1) the @@ -5448,7 +5449,8 @@ int sqlite3PagerGet( goto pager_acquire_err; } - if( MEMDB || pPager->dbSizefd) ){ + assert( !isOpen(pPager->fd) || !MEMDB ); + if( !isOpen(pPager->fd) || pPager->dbSizepPager->mxPgno ){ rc = SQLITE_FULL; goto pager_acquire_err; From ae20690e2ce48e9c519baddce5fc48d2f97deb10 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 25 Apr 2016 19:25:12 +0000 Subject: [PATCH 0342/1484] Update the RBU vacuum code so that databases that use custom collation sequences can be vacuumed. FossilOrigin-Name: 7dd48c10790a7b9c4165214399c261a0aa701297 --- ext/rbu/rbuvacuum.test | 95 +++++++++++++++++++++ ext/rbu/sqlite3rbu.c | 189 +++++++++++++++++++++-------------------- ext/rbu/test_rbu.c | 22 ++++- manifest | 18 ++-- manifest.uuid | 2 +- 5 files changed, 220 insertions(+), 106 deletions(-) diff --git a/ext/rbu/rbuvacuum.test b/ext/rbu/rbuvacuum.test index 96a37d1f71..7d82e380d6 100644 --- a/ext/rbu/rbuvacuum.test +++ b/ext/rbu/rbuvacuum.test @@ -255,7 +255,41 @@ foreach step {0 1} { } } {} do_rbu_vacuum_test 1.10.2 $step + + # Database with empty tables. + # + reset_db + do_execsql_test 1.11.1 { + CREATE TABLE t1(a INTEGER PRIMARY KEY, b); + CREATE TABLE t2(a INTEGER PRIMARY KEY, b); + CREATE TABLE t3(a INTEGER PRIMARY KEY, b); + CREATE TABLE t4(a INTEGER PRIMARY KEY, b); + INSERT INTO t4 VALUES(1, 2); + } + do_rbu_vacuum_test 1.11.2 $step + do_execsql_test 1.11.3 { + SELECT * FROM t1; + SELECT * FROM t2; + SELECT * FROM t3; + SELECT * FROM t4; + } {1 2} + reset_db + do_execsql_test 1.12.1 { + CREATE TABLE t1(a INTEGER PRIMARY KEY, b); + CREATE TABLE t2(a INTEGER PRIMARY KEY, b); + CREATE TABLE t3(a INTEGER PRIMARY KEY, b); + CREATE TABLE t4(a INTEGER PRIMARY KEY, b); + INSERT INTO t1 VALUES(1, 2); + } + do_rbu_vacuum_test 1.12.2 $step + do_execsql_test 1.12.3 { + SELECT * FROM t1; + SELECT * FROM t2; + SELECT * FROM t3; + SELECT * FROM t4; + } {1 2} } +set ::testprefix rbuvacuum #------------------------------------------------------------------------- # Test some error cases: @@ -310,6 +344,67 @@ for {set i 1} 1 {incr i} { } {1 {SQLITE_BUSY - database modified during rbu vacuum}} } +#------------------------------------------------------------------------- +# Test that a database that uses custom collation sequences can be RBU +# vacuumed. +# +reset_db +forcedelete state.db +proc noop {args} {} +proc length_cmp {x y} { + set n1 [string length $x] + set n2 [string length $y] + return [expr $n1 - $n2] +} +sqlite3_create_collation_v2 db length length_cmp noop + +do_execsql_test 3.0 { + CREATE TABLE t1(a INTEGER PRIMARY KEY, b); + INSERT INTO t1 VALUES(1, 'i'); + INSERT INTO t1 VALUES(2, 'iiii'); + INSERT INTO t1 VALUES(3, 'ii'); + INSERT INTO t1 VALUES(4, 'iii'); + SELECT a FROM t1 ORDER BY b COLLATE length; +} {1 3 4 2} +do_execsql_test 3.1 { + CREATE INDEX i1 ON t1(b COLLATE length); +} + +do_test 3.2 { + sqlite3rbu_vacuum rbu test.db state.db + while {[rbu step]=="SQLITE_OK"} {} + list [catch { rbu close } msg] $msg +} {1 {SQLITE_ERROR - no such collation sequence: length}} + +do_test 3.3 { + sqlite3rbu_vacuum rbu test.db state.db + set db1 [rbu db 0] + sqlite3_create_collation_v2 $db1 length length_cmp noop + while {[rbu step]=="SQLITE_OK"} {} + list [catch { rbu close } msg] $msg +} {1 {SQLITE_ERROR - no such collation sequence: length}} + +do_test 3.4 { + sqlite3rbu_vacuum rbu test.db state.db + set db1 [rbu db 1] + sqlite3_create_collation_v2 $db1 length length_cmp noop + while {[rbu step]=="SQLITE_OK"} {} + list [catch { rbu close } msg] $msg +} {1 {SQLITE_ERROR - no such collation sequence: length}} + +do_test 3.5 { + sqlite3rbu_vacuum rbu test.db state.db + set db1 [rbu db 0] + set db2 [rbu db 1] + + sqlite3_create_collation_v2 $db1 length length_cmp noop + sqlite3_create_collation_v2 $db2 length length_cmp noop + + while {[rbu step]=="SQLITE_OK"} {} + list [catch { rbu close } msg] $msg +} {0 SQLITE_DONE} + + catch { db close } finish_test diff --git a/ext/rbu/sqlite3rbu.c b/ext/rbu/sqlite3rbu.c index e7e4ddef58..dc80935ecf 100644 --- a/ext/rbu/sqlite3rbu.c +++ b/ext/rbu/sqlite3rbu.c @@ -3081,6 +3081,92 @@ static void rbuSaveState(sqlite3rbu *p, int eStage){ } +/* +** The second argument passed to this function is the name of a PRAGMA +** setting - "page_size", "auto_vacuum", "user_version" or "application_id". +** This function executes the following on sqlite3rbu.dbRbu: +** +** "PRAGMA main.$zPragma" +** +** where $zPragma is the string passed as the second argument, then +** on sqlite3rbu.dbMain: +** +** "PRAGMA main.$zPragma = $val" +** +** where $val is the value returned by the first PRAGMA invocation. +** +** In short, it copies the value of the specified PRAGMA setting from +** dbRbu to dbMain. +*/ +static void rbuCopyPragma(sqlite3rbu *p, const char *zPragma){ + if( p->rc==SQLITE_OK ){ + sqlite3_stmt *pPragma = 0; + p->rc = prepareFreeAndCollectError(p->dbRbu, &pPragma, &p->zErrmsg, + sqlite3_mprintf("PRAGMA main.%s", zPragma) + ); + if( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pPragma) ){ + p->rc = rbuMPrintfExec(p, p->dbMain, "PRAGMA main.%s = %d", + zPragma, sqlite3_column_int(pPragma, 0) + ); + } + rbuFinalize(p, pPragma); + } +} + +/* +** The RBU handle passed as the only argument has just been opened and +** the state database is empty. If this RBU handle was opened for an +** RBU vacuum operation, create the schema in the target db. +*/ +static void rbuCreateTargetSchema(sqlite3rbu *p){ + sqlite3_stmt *pSql = 0; + sqlite3_stmt *pInsert = 0; + + assert( rbuIsVacuum(p) ); + p->rc = sqlite3_exec(p->dbMain, "PRAGMA writable_schema=1", 0,0, &p->zErrmsg); + if( p->rc==SQLITE_OK ){ + p->rc = prepareAndCollectError(p->dbRbu, &pSql, &p->zErrmsg, + "SELECT sql FROM sqlite_master WHERE sql!='' AND rootpage!=0" + " AND name!='sqlite_sequence' " + " ORDER BY type DESC" + ); + } + + while( p->rc==SQLITE_OK && sqlite3_step(pSql)==SQLITE_ROW ){ + const char *zSql = (const char*)sqlite3_column_text(pSql, 0); + p->rc = sqlite3_exec(p->dbMain, zSql, 0, 0, &p->zErrmsg); + } + rbuFinalize(p, pSql); + if( p->rc!=SQLITE_OK ) return; + + if( p->rc==SQLITE_OK ){ + p->rc = prepareAndCollectError(p->dbRbu, &pSql, &p->zErrmsg, + "SELECT * FROM sqlite_master WHERE rootpage=0 OR rootpage IS NULL" + ); + } + + if( p->rc==SQLITE_OK ){ + p->rc = prepareAndCollectError(p->dbMain, &pInsert, &p->zErrmsg, + "INSERT INTO sqlite_master VALUES(?,?,?,?,?)" + ); + } + + while( p->rc==SQLITE_OK && sqlite3_step(pSql)==SQLITE_ROW ){ + int i; + for(i=0; i<5; i++){ + sqlite3_bind_value(pInsert, i+1, sqlite3_column_value(pSql, i)); + } + sqlite3_step(pInsert); + p->rc = sqlite3_reset(pInsert); + } + if( p->rc==SQLITE_OK ){ + p->rc = sqlite3_exec(p->dbMain, "PRAGMA writable_schema=0",0,0,&p->zErrmsg); + } + + rbuFinalize(p, pSql); + rbuFinalize(p, pInsert); +} + /* ** Step the RBU object. */ @@ -3089,6 +3175,15 @@ int sqlite3rbu_step(sqlite3rbu *p){ switch( p->eStage ){ case RBU_STAGE_OAL: { RbuObjIter *pIter = &p->objiter; + + /* If this is an RBU vacuum operation and the state table was empty + ** when this handle was opened, create the target database schema. */ + if( rbuIsVacuum(p) && p->nProgress==0 && p->rc==SQLITE_OK ){ + rbuCreateTargetSchema(p); + rbuCopyPragma(p, "user_version"); + rbuCopyPragma(p, "application_id"); + } + while( p->rc==SQLITE_OK && pIter->zTbl ){ if( pIter->bCleanup ){ @@ -3371,92 +3466,6 @@ static void rbuInitPhaseOneSteps(sqlite3rbu *p){ } } -/* -** The second argument passed to this function is the name of a PRAGMA -** setting - "page_size", "auto_vacuum", "user_version" or "application_id". -** This function executes the following on sqlite3rbu.dbRbu: -** -** "PRAGMA main.$zPragma" -** -** where $zPragma is the string passed as the second argument, then -** on sqlite3rbu.dbMain: -** -** "PRAGMA main.$zPragma = $val" -** -** where $val is the value returned by the first PRAGMA invocation. -** -** In short, it copies the value of the specified PRAGMA setting from -** dbRbu to dbMain. -*/ -static void rbuCopyPragma(sqlite3rbu *p, const char *zPragma){ - if( p->rc==SQLITE_OK ){ - sqlite3_stmt *pPragma = 0; - p->rc = prepareFreeAndCollectError(p->dbRbu, &pPragma, &p->zErrmsg, - sqlite3_mprintf("PRAGMA main.%s", zPragma) - ); - if( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pPragma) ){ - p->rc = rbuMPrintfExec(p, p->dbMain, "PRAGMA main.%s = %d", - zPragma, sqlite3_column_int(pPragma, 0) - ); - } - rbuFinalize(p, pPragma); - } -} - -/* -** The RBU handle passed as the only argument has just been opened and -** the state database is empty. If this RBU handle was opened for an -** RBU vacuum operation, create the schema in the target db. -*/ -static void rbuCreateTargetSchema(sqlite3rbu *p){ - sqlite3_stmt *pSql = 0; - sqlite3_stmt *pInsert = 0; - - assert( rbuIsVacuum(p) ); - p->rc = sqlite3_exec(p->dbMain, "PRAGMA writable_schema=1", 0,0, &p->zErrmsg); - if( p->rc==SQLITE_OK ){ - p->rc = prepareAndCollectError(p->dbRbu, &pSql, &p->zErrmsg, - "SELECT sql FROM sqlite_master WHERE sql!='' AND rootpage!=0" - " AND name!='sqlite_sequence' " - " ORDER BY type DESC" - ); - } - - while( p->rc==SQLITE_OK && sqlite3_step(pSql)==SQLITE_ROW ){ - const char *zSql = (const char*)sqlite3_column_text(pSql, 0); - p->rc = sqlite3_exec(p->dbMain, zSql, 0, 0, &p->zErrmsg); - } - rbuFinalize(p, pSql); - if( p->rc!=SQLITE_OK ) return; - - if( p->rc==SQLITE_OK ){ - p->rc = prepareAndCollectError(p->dbRbu, &pSql, &p->zErrmsg, - "SELECT * FROM sqlite_master WHERE rootpage=0 OR rootpage IS NULL" - ); - } - - if( p->rc==SQLITE_OK ){ - p->rc = prepareAndCollectError(p->dbMain, &pInsert, &p->zErrmsg, - "INSERT INTO sqlite_master VALUES(?,?,?,?,?)" - ); - } - - while( p->rc==SQLITE_OK && sqlite3_step(pSql)==SQLITE_ROW ){ - int i; - for(i=0; i<5; i++){ - sqlite3_bind_value(pInsert, i+1, sqlite3_column_value(pSql, i)); - } - sqlite3_step(pInsert); - p->rc = sqlite3_reset(pInsert); - } - if( p->rc==SQLITE_OK ){ - p->rc = sqlite3_exec(p->dbMain, "PRAGMA writable_schema=0",0,0,&p->zErrmsg); - } - - rbuFinalize(p, pSql); - rbuFinalize(p, pInsert); -} - static sqlite3rbu *openRbuHandle( const char *zTarget, @@ -3569,14 +3578,6 @@ static sqlite3rbu *openRbuHandle( } } - /* If this is an RBU vacuum operation and the state table was empty - ** when this handle was opened, create the target database schema. */ - if( p->rc==SQLITE_OK && pState->eStage==0 && rbuIsVacuum(p) ){ - rbuCreateTargetSchema(p); - rbuCopyPragma(p, "user_version"); - rbuCopyPragma(p, "application_id"); - } - /* Point the object iterator at the first object */ if( p->rc==SQLITE_OK ){ p->rc = rbuObjIterFirst(p, &p->objiter); diff --git a/ext/rbu/test_rbu.c b/ext/rbu/test_rbu.c index 629a33cd0e..2d52262c71 100644 --- a/ext/rbu/test_rbu.c +++ b/ext/rbu/test_rbu.c @@ -20,8 +20,9 @@ #include #include -/* From main.c (apparently...) */ +/* From main.c */ extern const char *sqlite3ErrName(int); +extern int sqlite3TestMakePointerStr(Tcl_Interp*, char*, void*); void test_rbu_delta(sqlite3_context *pCtx, int nArg, sqlite3_value **apVal){ Tcl_Interp *interp = (Tcl_Interp*)sqlite3_user_data(pCtx); @@ -66,7 +67,8 @@ static int test_sqlite3rbu_cmd( {"create_rbu_delta", 2, ""}, /* 2 */ {"savestate", 2, ""}, /* 3 */ {"dbMain_eval", 3, "SQL"}, /* 4 */ - {"bp_progress", 2, ""}, /* 5 */ + {"bp_progress", 2, ""}, /* 5 */ + {"db", 3, "RBU"}, /* 6 */ {0,0,0} }; int iCmd; @@ -149,6 +151,22 @@ static int test_sqlite3rbu_cmd( break; } + case 6: /* db */ { + int bArg; + if( Tcl_GetBooleanFromObj(interp, objv[2], &bArg) ){ + ret = TCL_ERROR; + }else{ + char zBuf[50]; + sqlite3 *db = sqlite3rbu_db(pRbu, bArg); + if( sqlite3TestMakePointerStr(interp, zBuf, (void*)db) ){ + ret = TCL_ERROR; + }else{ + Tcl_SetResult(interp, zBuf, TCL_VOLATILE); + } + } + break; + } + default: /* seems unlikely */ assert( !"cannot happen" ); break; diff --git a/manifest b/manifest index 10b7a29fe4..d07dc12346 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C When\schecking\sfor\sthe\sWHERE-clause\spush-down\soptimization,\sverify\sthat\nall\sterms\sof\sthe\scompound\sinner\sSELECT\sare\snon-aggregate,\snot\sjust\sthe\nlast\sterm.\s\sFix\sfor\sticket\s[f7f8c97e97597]. -D 2016-04-25T02:20:10.236 +C Update\sthe\sRBU\svacuum\scode\sso\sthat\sdatabases\sthat\suse\scustom\scollation\ssequences\scan\sbe\svacuumed. +D 2016-04-25T19:25:12.645 F Makefile.in a905f3180accdafbd5a534bf26126ee5306d5056 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -247,10 +247,10 @@ F ext/rbu/rbufault3.test 54a399888ac4af44c68f9f58afbed23149428bca F ext/rbu/rbufts.test 828cd689da825f0a7b7c53ffc1f6f7fdb6fa5bda F ext/rbu/rbuprogress.test 2023a7df2c523e3df1cb532eff811cda385a789a F ext/rbu/rbusave.test 0f43b6686084f426ddd040b878426452fd2c2f48 -F ext/rbu/rbuvacuum.test bcbc1dcd8e2a46a811e46477692ae1c0e8917a85 -F ext/rbu/sqlite3rbu.c 20922328dcebe89589638923bb46840df8bc7733 +F ext/rbu/rbuvacuum.test 66e02cf299836770e718e95c36686be0b26dbda3 +F ext/rbu/sqlite3rbu.c bf36625990c6865ecf08bd844d8097ed2d0a6958 F ext/rbu/sqlite3rbu.h 2acd0a6344a6079de15c8dc9d84d3df83a665930 -F ext/rbu/test_rbu.c 430b8b9520c233505371d564d3561e0b554355f4 +F ext/rbu/test_rbu.c 9bbdf6bd8efd58fbc4f192698df50569598fbb9e F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 F ext/rtree/rtree.c 0b870ccb7b58b734a2a8e1e2755a7c0ded070920 F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e @@ -1484,7 +1484,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d0a579b35105810821bbfec6b50ecfebac7a17ee -R 858c551be0612332d0982a3a42946fb6 -U drh -Z c1158477a3c6966fdb5709eb9b3c8fe5 +P ec215f94ac9748c0acd82af0cc9e7a92249462f9 +R c0a43d6aa5e9f6d906be746461438b7f +U dan +Z 33a592aa08c77e06ce6e19e096f78faa diff --git a/manifest.uuid b/manifest.uuid index 580a058689..2b1a4a4c78 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ec215f94ac9748c0acd82af0cc9e7a92249462f9 \ No newline at end of file +7dd48c10790a7b9c4165214399c261a0aa701297 \ No newline at end of file From 6c96358601f1da67c58661706c6066dce51214a8 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 25 Apr 2016 19:28:34 +0000 Subject: [PATCH 0343/1484] Remove an obsolete comment from the pager. No code changes. FossilOrigin-Name: 36f97ca8874a03ac8699f44fe0da95b0be507cc7 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/pager.c | 5 +---- 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index acd08f3f4f..ad1b6577cc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\ssome\sunreachable\sbranches\sin\sthe\spager. -D 2016-04-25T19:20:56.371 +C Remove\san\sobsolete\scomment\sfrom\sthe\spager.\s\sNo\scode\schanges. +D 2016-04-25T19:28:34.469 F Makefile.in a905f3180accdafbd5a534bf26126ee5306d5056 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -364,7 +364,7 @@ F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa F src/os_unix.c 2488a2b6456709ad6398df2302d427a980e2695a F src/os_win.c 1997a873bfc8296a701bd8e2df8c3d5da5afe956 F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca -F src/pager.c a31af55dd6139c6ece7642667a035028a266d344 +F src/pager.c 456ea27c2a467c161b1466b8f4f5307f12314d31 F src/pager.h 329bdf078a4e0a3b35084534d58625d21fd03681 F src/parse.y 10eb2f3fb62341291528c7984498054731f9d31e F src/pcache.c b3230ecfc7f797063fbe167f2845da363e8f07f8 @@ -1486,7 +1486,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a905d5e08de3f3c60b667d840b5995911372647d -R 1f1507f9b43194c78dbe59034ff5cd5c +P 3ae44770fdecc40c8097f1de0b504f36585a2232 +R db63125d858bb9f2f1e3791a791b0b06 U drh -Z 8869ed19649f951f40d0b8fe31c4bd6b +Z 7c3cc56899db1d72bed3171f2d6f3ea7 diff --git a/manifest.uuid b/manifest.uuid index 010c2a556f..5ba52e8d51 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3ae44770fdecc40c8097f1de0b504f36585a2232 \ No newline at end of file +36f97ca8874a03ac8699f44fe0da95b0be507cc7 \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index 0a185c3e37..6e464ba82f 100644 --- a/src/pager.c +++ b/src/pager.c @@ -1820,10 +1820,7 @@ static void pager_unlock(Pager *pPager){ ** trusted. Now that there are no outstanding references to the pager, ** it can safely move back to PAGER_OPEN state. This happens in both ** normal and exclusive-locking mode. - ** - ** Exception: There is no way out of the error state for temp files. - ** This is because it is not possible to call pager_reset() on a temp - ** file pager (as this may discard the only copy of some data). */ + */ assert( pPager->errCode==SQLITE_OK || !MEMDB ); if( pPager->errCode ){ if( pPager->tempFile==0 ){ From ead01fd27250ce29a44734a050954ac48434607a Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 25 Apr 2016 22:39:42 +0000 Subject: [PATCH 0344/1484] Add an sqlite3FaultSim() all to make it easier to simulate IO errors in a VACUUM commit. FossilOrigin-Name: 8bfde416c51f4e087275aebf652a73985515e810 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/pager.c | 3 +++ 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index ad1b6577cc..07bba5bb6a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\san\sobsolete\scomment\sfrom\sthe\spager.\s\sNo\scode\schanges. -D 2016-04-25T19:28:34.469 +C Add\san\ssqlite3FaultSim()\sall\sto\smake\sit\seasier\sto\ssimulate\sIO\serrors\sin\na\sVACUUM\scommit. +D 2016-04-25T22:39:42.651 F Makefile.in a905f3180accdafbd5a534bf26126ee5306d5056 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -364,7 +364,7 @@ F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa F src/os_unix.c 2488a2b6456709ad6398df2302d427a980e2695a F src/os_win.c 1997a873bfc8296a701bd8e2df8c3d5da5afe956 F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca -F src/pager.c 456ea27c2a467c161b1466b8f4f5307f12314d31 +F src/pager.c a8d30c49c231e9a20d05257613db922532588963 F src/pager.h 329bdf078a4e0a3b35084534d58625d21fd03681 F src/parse.y 10eb2f3fb62341291528c7984498054731f9d31e F src/pcache.c b3230ecfc7f797063fbe167f2845da363e8f07f8 @@ -1486,7 +1486,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 3ae44770fdecc40c8097f1de0b504f36585a2232 -R db63125d858bb9f2f1e3791a791b0b06 +P 36f97ca8874a03ac8699f44fe0da95b0be507cc7 +R 54e681c99d31e5095466803c5f1b64d8 U drh -Z 7c3cc56899db1d72bed3171f2d6f3ea7 +Z 6d6cde3ceb3c27e62273721031ebad91 diff --git a/manifest.uuid b/manifest.uuid index 5ba52e8d51..bbdd0e7139 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -36f97ca8874a03ac8699f44fe0da95b0be507cc7 \ No newline at end of file +8bfde416c51f4e087275aebf652a73985515e810 \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index 6e464ba82f..d24337cd50 100644 --- a/src/pager.c +++ b/src/pager.c @@ -6210,6 +6210,9 @@ int sqlite3PagerCommitPhaseOne( /* If a prior error occurred, report that error again. */ if( NEVER(pPager->errCode) ) return pPager->errCode; + /* Provide the ability to easily simulate an I/O error during testing */ + if( (rc = sqlite3FaultSim(400))!=SQLITE_OK ) return rc; + PAGERTRACE(("DATABASE SYNC: File=%s zMaster=%s nSize=%d\n", pPager->zFilename, zMaster, pPager->dbSize)); From b283a0cde90b25fd01054228e4c5a680233d4742 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 26 Apr 2016 13:13:53 +0000 Subject: [PATCH 0345/1484] Fix the "checksymbols" target in Makefile.in to be able to deal with the sqlite3changegroup family of interfaces. FossilOrigin-Name: d819bfbd46dc7f065d2a3ab0ef9f8322d8394e11 --- Makefile.in | 3 ++- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/Makefile.in b/Makefile.in index 8200cf2357..e4687626f0 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1164,8 +1164,9 @@ loadfts$(EXE): $(TOP)/tool/loadfts.c libsqlite3.la # symbols that do not begin with "sqlite3_". It is run as part of the # releasetest.tcl script. # +VALIDIDS=' sqlite3(changeset|changegroup|session)?_' checksymbols: sqlite3.lo - nm -g --defined-only sqlite3.o | egrep -v ' sqlite3(changeset|session)?_' ; test $$? -ne 0 + nm -g --defined-only sqlite3.o | egrep -v $(VALIDIDS); test $$? -ne 0 echo '0 errors out of 1 tests' # Build the amalgamation-autoconf package. The amalamgation-tarball target builds diff --git a/manifest b/manifest index d07dc12346..01396063e2 100644 --- a/manifest +++ b/manifest @@ -1,6 +1,6 @@ -C Update\sthe\sRBU\svacuum\scode\sso\sthat\sdatabases\sthat\suse\scustom\scollation\ssequences\scan\sbe\svacuumed. -D 2016-04-25T19:25:12.645 -F Makefile.in a905f3180accdafbd5a534bf26126ee5306d5056 +C Fix\sthe\s"checksymbols"\starget\sin\sMakefile.in\sto\sbe\sable\sto\sdeal\swith\sthe\nsqlite3changegroup\sfamily\sof\sinterfaces. +D 2016-04-26T13:13:53.622 +F Makefile.in 9e816d0323e418fbc0f8b2c05fc14e0b3763d9e8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7 @@ -1484,7 +1484,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ec215f94ac9748c0acd82af0cc9e7a92249462f9 -R c0a43d6aa5e9f6d906be746461438b7f -U dan -Z 33a592aa08c77e06ce6e19e096f78faa +P 7dd48c10790a7b9c4165214399c261a0aa701297 +R 5836a38779892d93c5f443eeb9cd4151 +U drh +Z a0cff4b059a2c6bf807105b3b6e856e6 diff --git a/manifest.uuid b/manifest.uuid index 2b1a4a4c78..cff4e97ad7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7dd48c10790a7b9c4165214399c261a0aa701297 \ No newline at end of file +d819bfbd46dc7f065d2a3ab0ef9f8322d8394e11 \ No newline at end of file From 45164826b76087ae15c714b87d35336aee056637 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 26 Apr 2016 17:10:03 +0000 Subject: [PATCH 0346/1484] Fix an issue in temptable2.test preventing it from working with SQLITE_DEFAULT_AUTOVACUUM=1 builds. FossilOrigin-Name: e790aac02e4b427b4891b514a050699d159b03b1 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/temptable2.test | 2 ++ 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 3224381eed..52a995d5ff 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sthe\schecksymbols\sfix\sfrom\strunk\sinto\sthis\sbranch. -D 2016-04-26T16:03:58.388 +C Fix\san\sissue\sin\stemptable2.test\spreventing\sit\sfrom\sworking\swith\sSQLITE_DEFAULT_AUTOVACUUM=1\sbuilds. +D 2016-04-26T17:10:03.745 F Makefile.in 9e816d0323e418fbc0f8b2c05fc14e0b3763d9e8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -1113,7 +1113,7 @@ F test/tclsqlite.test e1306001a0ca92250b691ea6d3cecaca5b6342aa F test/tempdb.test bd92eba8f20e16a9136e434e20b280794de3cdb6 F test/tempfault.test 0c0d349c9a99bf5f374655742577f8712c647900 F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30 -F test/temptable2.test 31485911fb33e72c7737087ba5a2b35acafba55a +F test/temptable2.test d4e967c355b154e8bc387de961430e94c20f2dca F test/temptrigger.test 8ec228b0db5d7ebc4ee9b458fc28cb9e7873f5e1 F test/tester.tcl 7b740ee852c55e1e72b6ebe5044acee7aa4e5553 F test/thread001.test 9f22fd3525a307ff42a326b6bc7b0465be1745a5 @@ -1486,7 +1486,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 8bfde416c51f4e087275aebf652a73985515e810 d819bfbd46dc7f065d2a3ab0ef9f8322d8394e11 -R 0f2ec21167579c0f8c46594d0d9ecc27 +P 04911cee0cd5467ee99744b774d692219e5e1425 +R 849d538a2e2ee898d96d5ba70eff854f U dan -Z 444c73c0b2d802c9a660647c7b166bf1 +Z 496f6fcde8513321efb142fd9a4f11c8 diff --git a/manifest.uuid b/manifest.uuid index 6798dc8b47..021372e495 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -04911cee0cd5467ee99744b774d692219e5e1425 \ No newline at end of file +e790aac02e4b427b4891b514a050699d159b03b1 \ No newline at end of file diff --git a/test/temptable2.test b/test/temptable2.test index d71c168ebf..21e06a3a4f 100644 --- a/test/temptable2.test +++ b/test/temptable2.test @@ -224,6 +224,7 @@ do_execsql_test 7.1 { # reset_db do_execsql_test 8.1 { + PRAGMA auto_vacuum = OFF; CREATE TABLE t2(a, b); CREATE INDEX i2 ON t2(a, b); WITH x(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM x WHERE i<20 ) @@ -234,6 +235,7 @@ do_execsql_test 8.1 { do_test 8.2 { sqlite3 tmp "" execsql { + PRAGMA auto_vacuum = OFF; PRAGMA page_size = 8192; CREATE TABLE t1(a, b); CREATE INDEX i1 ON t1(a, b); From 97a7e5e68cdfe31e9e020ed59d8f93787e18cd25 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 26 Apr 2016 18:58:54 +0000 Subject: [PATCH 0347/1484] The pcache and the built-in VFSes should not use mutexes when SQLITE_CONFIG_SINGLETHREAD is set. FossilOrigin-Name: 12418b100196abbfbfb85e0ab4bb6b1cbf335df7 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/os_unix.c | 10 ++++++---- src/os_win.c | 14 ++++++++------ src/pcache1.c | 4 ++-- 5 files changed, 25 insertions(+), 21 deletions(-) diff --git a/manifest b/manifest index 01396063e2..a96ddd6939 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\s"checksymbols"\starget\sin\sMakefile.in\sto\sbe\sable\sto\sdeal\swith\sthe\nsqlite3changegroup\sfamily\sof\sinterfaces. -D 2016-04-26T13:13:53.622 +C The\spcache\sand\sthe\sbuilt-in\sVFSes\sshould\snot\suse\smutexes\swhen\nSQLITE_CONFIG_SINGLETHREAD\sis\sset. +D 2016-04-26T18:58:54.655 F Makefile.in 9e816d0323e418fbc0f8b2c05fc14e0b3763d9e8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -361,15 +361,15 @@ F src/os.c 4d83917f072ad958fba9235136fa2ed43df47905 F src/os.h 8e976e59eb4ca1c0fca6d35ee803e38951cb0343 F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85 F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa -F src/os_unix.c 2488a2b6456709ad6398df2302d427a980e2695a -F src/os_win.c 1997a873bfc8296a701bd8e2df8c3d5da5afe956 +F src/os_unix.c 8422fba2eb592fbbb2d4006b6f2a67cad8951495 +F src/os_win.c 852fc2ff6084296348ed3739c548b2cf32df394e F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c d20fa46d5beda38095be6070dd4c59e502817c72 F src/pager.h 329bdf078a4e0a3b35084534d58625d21fd03681 F src/parse.y 10eb2f3fb62341291528c7984498054731f9d31e F src/pcache.c 647bb53a86b7bbcf55ad88089b3ea5a9170b90df F src/pcache.h 4d0ccaad264d360981ec5e6a2b596d6e85242545 -F src/pcache1.c c40cdb93586e21b5dd826b5e671240bd91c26b05 +F src/pcache1.c 7f51d2b541aab57596adf62db2c4bb025d34f04d F src/pragma.c faf42922bb7ab2f6672cb550356c1967abae3c84 F src/pragma.h 64c78a648751b9f4f297276c4eb7507b14b4628c F src/prepare.c 22df6171aec1d86904ed2ad30c2348a5748aa04e @@ -1484,7 +1484,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 7dd48c10790a7b9c4165214399c261a0aa701297 -R 5836a38779892d93c5f443eeb9cd4151 +P d819bfbd46dc7f065d2a3ab0ef9f8322d8394e11 +R 2246a8395360136a36ef2a0e4a464571 U drh -Z a0cff4b059a2c6bf807105b3b6e856e6 +Z fce32975c383f8c036923c0ce041e29e diff --git a/manifest.uuid b/manifest.uuid index cff4e97ad7..d1ff167696 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d819bfbd46dc7f065d2a3ab0ef9f8322d8394e11 \ No newline at end of file +12418b100196abbfbfb85e0ab4bb6b1cbf335df7 \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index aadb414afe..01de00e0dd 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -4288,10 +4288,12 @@ static int unixOpenSharedMemory(unixFile *pDbFd){ pShmNode->h = -1; pDbFd->pInode->pShmNode = pShmNode; pShmNode->pInode = pDbFd->pInode; - pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); - if( pShmNode->mutex==0 ){ - rc = SQLITE_NOMEM_BKPT; - goto shm_open_err; + if( sqlite3GlobalConfig.bCoreMutex ){ + pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); + if( pShmNode->mutex==0 ){ + rc = SQLITE_NOMEM_BKPT; + goto shm_open_err; + } } if( pInode->bProcessLock==0 ){ diff --git a/src/os_win.c b/src/os_win.c index 1f26463453..9a34d9a106 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -1260,8 +1260,8 @@ int sqlite3_win32_reset_heap(){ int rc; MUTEX_LOGIC( sqlite3_mutex *pMaster; ) /* The main static mutex */ MUTEX_LOGIC( sqlite3_mutex *pMem; ) /* The memsys static mutex */ - MUTEX_LOGIC( pMaster = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER); ) - MUTEX_LOGIC( pMem = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM); ) + MUTEX_LOGIC( pMaster = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); ) + MUTEX_LOGIC( pMem = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM); ) sqlite3_mutex_enter(pMaster); sqlite3_mutex_enter(pMem); winMemAssertMagic(); @@ -3764,10 +3764,12 @@ static int winOpenSharedMemory(winFile *pDbFd){ pShmNode->pNext = winShmNodeList; winShmNodeList = pShmNode; - pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); - if( pShmNode->mutex==0 ){ - rc = SQLITE_IOERR_NOMEM_BKPT; - goto shm_open_err; + if( sqlite3GlobalConfig.bCoreMutex ){ + pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); + if( pShmNode->mutex==0 ){ + rc = SQLITE_IOERR_NOMEM_BKPT; + goto shm_open_err; + } } rc = winOpen(pDbFd->pVfs, diff --git a/src/pcache1.c b/src/pcache1.c index d168e7fbcb..5fe963ad05 100644 --- a/src/pcache1.c +++ b/src/pcache1.c @@ -690,8 +690,8 @@ static int pcache1Init(void *NotUsed){ #if SQLITE_THREADSAFE if( sqlite3GlobalConfig.bCoreMutex ){ - pcache1.grp.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU); - pcache1.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_PMEM); + pcache1.grp.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU); + pcache1.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_PMEM); } #endif if( pcache1.separateCache From e5f06fdc8718d60ae90b5791026b58fd812c3963 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 26 Apr 2016 21:02:53 +0000 Subject: [PATCH 0348/1484] Remove an unnecessary line from the sqlite3AtoF() routine. FossilOrigin-Name: a9d007494cfe30a26dca5352655dc7702351476e --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/util.c | 3 --- 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index a96ddd6939..bd6eed15fa 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C The\spcache\sand\sthe\sbuilt-in\sVFSes\sshould\snot\suse\smutexes\swhen\nSQLITE_CONFIG_SINGLETHREAD\sis\sset. -D 2016-04-26T18:58:54.655 +C Remove\san\sunnecessary\sline\sfrom\sthe\ssqlite3AtoF()\sroutine. +D 2016-04-26T21:02:53.535 F Makefile.in 9e816d0323e418fbc0f8b2c05fc14e0b3763d9e8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -441,7 +441,7 @@ F src/treeview.c e4b41a37530a191579d3c53142cc44ee2eb99373 F src/trigger.c e14840ee0c3e549e758ec9bf3e4146e166002280 F src/update.c 3e67ab3c0814635f355fb1f8ab010a2b9e016e7d F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c -F src/util.c 187a0a2aaa3c5d2ccd2ab0143b2fd9e86d6bc816 +F src/util.c 8ae5e894687fb90cb22a870284eb4a8d077f4f93 F src/vacuum.c feb1eabb20987983d9350cad98299b21fa811f52 F src/vdbe.c d3843a66d74a7696477ee5141e5eb9a7e5e2401c F src/vdbe.h 5591b5add447096e31288b5a0a78ec5d7b5c5170 @@ -1484,7 +1484,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d819bfbd46dc7f065d2a3ab0ef9f8322d8394e11 -R 2246a8395360136a36ef2a0e4a464571 +P 12418b100196abbfbfb85e0ab4bb6b1cbf335df7 +R 2a12fe749cf4b5592aed6dd4a1552e1f U drh -Z fce32975c383f8c036923c0ce041e29e +Z ab5ecd1a857f2f93572fff644c4c92bc diff --git a/manifest.uuid b/manifest.uuid index d1ff167696..128c730aca 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -12418b100196abbfbfb85e0ab4bb6b1cbf335df7 \ No newline at end of file +a9d007494cfe30a26dca5352655dc7702351476e \ No newline at end of file diff --git a/src/util.c b/src/util.c index 2f77a6033f..e01928815b 100644 --- a/src/util.c +++ b/src/util.c @@ -384,9 +384,6 @@ int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){ z+=incr; } - /* skip leading zeroes */ - while( z Date: Tue, 26 Apr 2016 23:14:45 +0000 Subject: [PATCH 0349/1484] Further simplifications to sqlite3AtoF() to remove unneeded branches. FossilOrigin-Name: dd69e53cb077873171af5312c633ca185595bf31 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/util.c | 11 ++++++----- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index bd6eed15fa..2dd1865c29 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\san\sunnecessary\sline\sfrom\sthe\ssqlite3AtoF()\sroutine. -D 2016-04-26T21:02:53.535 +C Further\ssimplifications\sto\ssqlite3AtoF()\sto\sremove\sunneeded\sbranches. +D 2016-04-26T23:14:45.113 F Makefile.in 9e816d0323e418fbc0f8b2c05fc14e0b3763d9e8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -441,7 +441,7 @@ F src/treeview.c e4b41a37530a191579d3c53142cc44ee2eb99373 F src/trigger.c e14840ee0c3e549e758ec9bf3e4146e166002280 F src/update.c 3e67ab3c0814635f355fb1f8ab010a2b9e016e7d F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c -F src/util.c 8ae5e894687fb90cb22a870284eb4a8d077f4f93 +F src/util.c 7ea35eef53451786b4729d2a64ba9a8574a11e31 F src/vacuum.c feb1eabb20987983d9350cad98299b21fa811f52 F src/vdbe.c d3843a66d74a7696477ee5141e5eb9a7e5e2401c F src/vdbe.h 5591b5add447096e31288b5a0a78ec5d7b5c5170 @@ -1484,7 +1484,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 12418b100196abbfbfb85e0ab4bb6b1cbf335df7 -R 2a12fe749cf4b5592aed6dd4a1552e1f +P a9d007494cfe30a26dca5352655dc7702351476e +R bdb81af968b0eff03040af96472e5367 U drh -Z ab5ecd1a857f2f93572fff644c4c92bc +Z 7162b1b4b927db763c29ab3a71a81028 diff --git a/manifest.uuid b/manifest.uuid index 128c730aca..48cc5d7fb4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a9d007494cfe30a26dca5352655dc7702351476e \ No newline at end of file +dd69e53cb077873171af5312c633ca185595bf31 \ No newline at end of file diff --git a/src/util.c b/src/util.c index e01928815b..771213be13 100644 --- a/src/util.c +++ b/src/util.c @@ -400,12 +400,13 @@ int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){ z+=incr; /* copy digits from after decimal to significand ** (decrease exponent by d to shift decimal right) */ - while( z=zEnd ) goto do_atof_calc; From c6daa01c058378590d0a219d857dfde1acb12866 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 27 Apr 2016 02:35:03 +0000 Subject: [PATCH 0350/1484] Remove still more unnecessary branches from sqlite3AtoF(). FossilOrigin-Name: 3adfe9f3e6ce7cc09fcb570d9b65e830a96cac15 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/util.c | 6 ++---- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 2dd1865c29..06c6814c38 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Further\ssimplifications\sto\ssqlite3AtoF()\sto\sremove\sunneeded\sbranches. -D 2016-04-26T23:14:45.113 +C Remove\sstill\smore\sunnecessary\sbranches\sfrom\ssqlite3AtoF(). +D 2016-04-27T02:35:03.572 F Makefile.in 9e816d0323e418fbc0f8b2c05fc14e0b3763d9e8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -441,7 +441,7 @@ F src/treeview.c e4b41a37530a191579d3c53142cc44ee2eb99373 F src/trigger.c e14840ee0c3e549e758ec9bf3e4146e166002280 F src/update.c 3e67ab3c0814635f355fb1f8ab010a2b9e016e7d F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c -F src/util.c 7ea35eef53451786b4729d2a64ba9a8574a11e31 +F src/util.c 562f7a85d933b7173a29e331deb28d85d6208f7c F src/vacuum.c feb1eabb20987983d9350cad98299b21fa811f52 F src/vdbe.c d3843a66d74a7696477ee5141e5eb9a7e5e2401c F src/vdbe.h 5591b5add447096e31288b5a0a78ec5d7b5c5170 @@ -1484,7 +1484,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a9d007494cfe30a26dca5352655dc7702351476e -R bdb81af968b0eff03040af96472e5367 +P dd69e53cb077873171af5312c633ca185595bf31 +R 4f22b05e3bc28723a991a2f87c87962e U drh -Z 7162b1b4b927db763c29ab3a71a81028 +Z 439e39a464407086f87a7be758f8e1c8 diff --git a/manifest.uuid b/manifest.uuid index 48cc5d7fb4..1f512c3c71 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -dd69e53cb077873171af5312c633ca185595bf31 \ No newline at end of file +3adfe9f3e6ce7cc09fcb570d9b65e830a96cac15 \ No newline at end of file diff --git a/src/util.c b/src/util.c index 771213be13..c85ae6a199 100644 --- a/src/util.c +++ b/src/util.c @@ -431,9 +431,7 @@ int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){ } /* skip trailing spaces */ - if( nDigits && eValid ){ - while( z0 ){ From 9bf0136384c90f4f9e7aacb705575617b459792c Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 27 Apr 2016 11:24:42 +0000 Subject: [PATCH 0351/1484] Fix a couple of test script problems on this branch. Both related to the fact that temp database page sizes can no longer be changed by VACUUM or the backup API after the temp db is populated. FossilOrigin-Name: 6bb5aa2be2a6c5ca66a98a9387b2845507a6bdd2 --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/backup.test | 21 ++++++++++----------- test/pagerfault.test | 30 ++++++++++++++++-------------- 4 files changed, 34 insertions(+), 33 deletions(-) diff --git a/manifest b/manifest index 52a995d5ff..45d2492933 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\sissue\sin\stemptable2.test\spreventing\sit\sfrom\sworking\swith\sSQLITE_DEFAULT_AUTOVACUUM=1\sbuilds. -D 2016-04-26T17:10:03.745 +C Fix\sa\scouple\sof\stest\sscript\sproblems\son\sthis\sbranch.\sBoth\srelated\sto\sthe\sfact\sthat\stemp\sdatabase\spage\ssizes\scan\sno\slonger\sbe\schanged\sby\sVACUUM\sor\sthe\sbackup\sAPI\safter\sthe\stemp\sdb\sis\spopulated. +D 2016-04-27T11:24:42.387 F Makefile.in 9e816d0323e418fbc0f8b2c05fc14e0b3763d9e8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -512,7 +512,7 @@ F test/autovacuum.test 92c24eedbdb68e49f3fb71f26f9ce6d8988cac15 F test/autovacuum_ioerr2.test 8a367b224183ad801e0e24dcb7d1501f45f244b4 F test/avtrans.test 0252654f4295ddda3b2cce0e894812259e655a85 F test/backcompat.test 3e64cedda754c778ef6bbe417b6e7a295e662a4d -F test/backup.test b79299a536a4c6d919094786595b95be56d02014 +F test/backup.test dd4a5ff756e3df3931dacb1791db0584d4bad989 F test/backup2.test 34986ef926ea522911a51dfdb2f8e99b7b75ebcf F test/backup4.test 8f6fd48e0dfde77b9a3bb26dc471ede3e101df32 F test/backup5.test ee5da6d7fe5082f5b9b0bbfa31d016f52412a2e4 @@ -968,7 +968,7 @@ F test/pager1.test 841868017e9dd3cb459b8d78862091a7d9cff21d F test/pager2.test 67b8f40ae98112bcdba1f2b2d03ea83266418c71 F test/pager3.test 3856d9c80839be0668efee1b74811b1b7f7fc95f F test/pager4.test a122e9e6925d5b23b31e3dfef8c6a44bbf19590e -F test/pagerfault.test ae9ee0db5a30aecda9db8290ce3dd12e5f7bbaa1 +F test/pagerfault.test 42ff797b1e6426c141cc7ee8b7417c9f27427950 F test/pagerfault2.test caf4c7facb914fd3b03a17b31ae2b180c8d6ca1f F test/pagerfault3.test 1003fcda009bf48a8e22a516e193b6ef0dd1bbd8 F test/pageropt.test 84e4cc5cbca285357f7906e99b21be4f2bf5abc0 @@ -1486,7 +1486,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 04911cee0cd5467ee99744b774d692219e5e1425 -R 849d538a2e2ee898d96d5ba70eff854f +P e790aac02e4b427b4891b514a050699d159b03b1 +R 167ee4a4f32b4f8204918ef34f7c21ee U dan -Z 496f6fcde8513321efb142fd9a4f11c8 +Z bbfd58a46d92c2867a1001ebb15e237d diff --git a/manifest.uuid b/manifest.uuid index 021372e495..eadf0ef5a0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e790aac02e4b427b4891b514a050699d159b03b1 \ No newline at end of file +6bb5aa2be2a6c5ca66a98a9387b2845507a6bdd2 \ No newline at end of file diff --git a/test/backup.test b/test/backup.test index 3b1e1db9e5..829b32452d 100644 --- a/test/backup.test +++ b/test/backup.test @@ -164,7 +164,7 @@ foreach zOpenScript [list { set file_dest temp }] { foreach rows_dest {0 3 10} { -foreach pgsz_dest {512 1024 2048} { +foreach pgsz_dest {512 1024 2048 4096} { foreach nPagePerStep {1 200} { # Open the databases. @@ -176,17 +176,16 @@ foreach nPagePerStep {1 200} { # in-memory destination is only possible if the initial destination # page size is the same as the source page size (in this case 1024 bytes). # - set isMemDest [expr { - $zDestFile eq ":memory:" || $file_dest eq "temp" && $TEMP_STORE>=2 - }] + set isMemDest [expr { $zDestFile eq ":memory:" || $file_dest eq "temp" }] - if { $isMemDest==0 || $pgsz_dest == 1024 } { - if 0 { - puts -nonewline "Test $iTest: src=$zSrcFile dest=$zDestFile" - puts -nonewline " (as $db_dest.$file_dest)" - puts -nonewline " rows_dest=$rows_dest pgsz_dest=$pgsz_dest" - puts "" - } + if 0 { + puts -nonewline "Test $iTest: src=$zSrcFile dest=$zDestFile" + puts -nonewline " (as $db_dest.$file_dest)" + puts -nonewline " rows_dest=$rows_dest pgsz_dest=$pgsz_dest" + puts "" + } + + if { $isMemDest==0 || $pgsz_dest==1024 || $rows_dest==0 } { # Set up the content of the source database. execsql { diff --git a/test/pagerfault.test b/test/pagerfault.test index c0f5de69ac..2e70171b20 100644 --- a/test/pagerfault.test +++ b/test/pagerfault.test @@ -684,22 +684,24 @@ do_faultsim_test pagerfault-14a -prep { # is not possible to change the page-size of an in-memory database. Even # using the backup API. # -if {$TEMP_STORE<2} { - do_faultsim_test pagerfault-14b -prep { - catch { db2 close } - faultsim_restore_and_reopen +# Update: It is no longer possible to change the page size of any temp +# database after it has been created. +# +do_faultsim_test pagerfault-14b -prep { + catch { db2 close } + faultsim_restore_and_reopen sqlite3 db2 "" db2 eval { PRAGMA page_size = 4096; CREATE TABLE xx(a) } - } -body { - sqlite3_backup B db2 main db main - B step 200 - set rc [B finish] - if {[string match SQLITE_IOERR_* $rc]} {set rc SQLITE_IOERR} - if {$rc != "SQLITE_OK"} { error [sqlite3_test_errstr $rc] } - set {} {} - } -test { - faultsim_test_result {0 {}} {1 {sqlite3_backup_init() failed}} - } +} -body { + sqlite3_backup B db2 main db main + B step 200 + set rc [B finish] + if {[string match SQLITE_IOERR_* $rc]} {set rc SQLITE_IOERR} + if {$rc != "SQLITE_OK"} { error [sqlite3_test_errstr $rc] } + set {} {} +} -test { + faultsim_test_result {1 {attempt to write a readonly database}} \ + {1 {sqlite3_backup_init() failed}} } do_faultsim_test pagerfault-14c -prep { From ad975d539e1357f62b4e6501c2252490dbb9f43b Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 27 Apr 2016 15:24:13 +0000 Subject: [PATCH 0352/1484] More simplification of the sqlite3AtoF() routine. Add special comments to indicate branches that are for optimization purposes only and that give the correct answer even if always or never taken. FossilOrigin-Name: 0065fe97cb8e5076acae1bf1560fd2f69dab9014 --- manifest | 12 ++++---- manifest.uuid | 2 +- src/util.c | 77 ++++++++++++++++++++++++++++++--------------------- 3 files changed, 52 insertions(+), 39 deletions(-) diff --git a/manifest b/manifest index 06c6814c38..7fa7ebedf8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sstill\smore\sunnecessary\sbranches\sfrom\ssqlite3AtoF(). -D 2016-04-27T02:35:03.572 +C More\ssimplification\sof\sthe\ssqlite3AtoF()\sroutine.\s\sAdd\sspecial\scomments\nto\sindicate\sbranches\sthat\sare\sfor\soptimization\spurposes\sonly\sand\sthat\sgive\nthe\scorrect\sanswer\seven\sif\salways\sor\snever\staken. +D 2016-04-27T15:24:13.573 F Makefile.in 9e816d0323e418fbc0f8b2c05fc14e0b3763d9e8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -441,7 +441,7 @@ F src/treeview.c e4b41a37530a191579d3c53142cc44ee2eb99373 F src/trigger.c e14840ee0c3e549e758ec9bf3e4146e166002280 F src/update.c 3e67ab3c0814635f355fb1f8ab010a2b9e016e7d F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c -F src/util.c 562f7a85d933b7173a29e331deb28d85d6208f7c +F src/util.c d0899604c30b4a9d493980aa7742eeda383fff6d F src/vacuum.c feb1eabb20987983d9350cad98299b21fa811f52 F src/vdbe.c d3843a66d74a7696477ee5141e5eb9a7e5e2401c F src/vdbe.h 5591b5add447096e31288b5a0a78ec5d7b5c5170 @@ -1484,7 +1484,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P dd69e53cb077873171af5312c633ca185595bf31 -R 4f22b05e3bc28723a991a2f87c87962e +P 3adfe9f3e6ce7cc09fcb570d9b65e830a96cac15 +R 676347b15924e075b34cabb43dd7e840 U drh -Z 439e39a464407086f87a7be758f8e1c8 +Z 680dc6a7c6e0d675cd4dc0c16abcab9d diff --git a/manifest.uuid b/manifest.uuid index 1f512c3c71..a6a5e1cabb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3adfe9f3e6ce7cc09fcb570d9b65e830a96cac15 \ No newline at end of file +0065fe97cb8e5076acae1bf1560fd2f69dab9014 \ No newline at end of file diff --git a/src/util.c b/src/util.c index c85ae6a199..1f59a9f731 100644 --- a/src/util.c +++ b/src/util.c @@ -355,7 +355,7 @@ int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){ int eValid = 1; /* True exponent is either not used or is well-formed */ double result; int nDigits = 0; - int nonNum = 0; + int nonNum = 0; /* True if input contains UTF16 with high byte non-zero */ assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE ); *pResult = 0.0; /* Default return value, in case of an error */ @@ -368,7 +368,7 @@ int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){ assert( SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 ); for(i=3-enc; i=zEnd ) goto do_atof_calc; + + /* This branch is needed to avoid a (harmless) buffer overread. The + ** special comment alerts the mutation tester that the correct answer + ** is obtained even if the branch is omitted */ + if( z>=zEnd ) goto do_atof_calc; /*PREVENTS-HARMLESS-OVERREAD*/ + /* get sign of exponent */ if( *z=='-' ){ esign = -1; @@ -443,41 +448,51 @@ do_atof_calc: esign = 1; } - /* if 0 significand */ - if( !s ) { - /* In the IEEE 754 standard, zero is signed. - ** Add the sign if we've seen at least one digit */ + if( s==0 ) { + /* In the IEEE 754 standard, zero is signed. */ result = sign<0 ? -(double)0 : (double)0; } else { - /* attempt to reduce exponent */ - if( esign>0 ){ - while( s<(LARGEST_INT64/10) && e>0 ) e--,s*=10; - }else{ - while( !(s%10) && e>0 ) e--,s/=10; + /* Attempt to reduce exponent. + ** + ** Branches that are not required for the correct answer but which only + ** help to obtain the correct answer faster are marked with special + ** comments, as a hint to the mutation tester. + */ + while( e>0 ){ /*OPTIMIZATION-IF-TRUE*/ + if( esign>0 ){ + if( s>=(LARGEST_INT64/10) ) break; /*OPTIMIZATION-IF-FALSE*/ + s *= 10; + }else{ + if( s%10!=0 ) break; /*OPTIMIZATION-IF-FALSE*/ + s /= 10; + } + e--; } /* adjust the sign of significand */ s = sign<0 ? -s : s; - /* if exponent, scale significand as appropriate - ** and store in result. */ - if( e ){ + if( e==0 ){ /*OPTIMIZATION-IF-TRUE*/ + result = (double)s; + }else{ LONGDOUBLE_TYPE scale = 1.0; /* attempt to handle extremely small/large numbers better */ - if( e>307 && e<342 ){ - while( e%308 ) { scale *= 1.0e+1; e -= 1; } - if( esign<0 ){ - result = s / scale; - result /= 1.0e+308; - }else{ - result = s * scale; - result *= 1.0e+308; - } - }else if( e>=342 ){ - if( esign<0 ){ - result = 0.0*s; - }else{ - result = 1e308*1e308*s; /* Infinity */ + if( e>307 ){ /*OPTIMIZATION-IF-TRUE*/ + if( e<342 ){ /*OPTIMIZATION-IF-TRUE*/ + while( e%308 ) { scale *= 1.0e+1; e -= 1; } + if( esign<0 ){ + result = s / scale; + result /= 1.0e+308; + }else{ + result = s * scale; + result *= 1.0e+308; + } + }else{ assert( e>=342 ); + if( esign<0 ){ + result = 0.0*s; + }else{ + result = 1e308*1e308*s; /* Infinity */ + } } }else{ /* 1.0e+22 is the largest power of 10 than can be @@ -490,8 +505,6 @@ do_atof_calc: result = s * scale; } } - } else { - result = (double)s; } } @@ -499,7 +512,7 @@ do_atof_calc: *pResult = result; /* return true if number and no extra non-whitespace chracters after */ - return z>=zEnd && nDigits>0 && eValid && nonNum==0; + return z==zEnd && nDigits>0 && eValid && nonNum==0; #else return !sqlite3Atoi64(z, pResult, length, enc); #endif /* SQLITE_OMIT_FLOATING_POINT */ From 05accd2216c25d31d98a19c6d8d14a260751452e Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 27 Apr 2016 18:54:49 +0000 Subject: [PATCH 0353/1484] Modify the permutations.test script so as to set any permutation specific configuration values before running each individual test script. FossilOrigin-Name: 2662d8fef791f7b8b3b14f9c27dfedec84620dee --- ext/session/sessionfault.test | 1 + ext/session/sessionfault2.test | 1 + manifest | 61 ++++++++++++++++++---------------- manifest.uuid | 2 +- src/test1.c | 8 +++-- src/test6.c | 28 +++++++++++++++- src/test_devsym.c | 7 ++++ src/test_journal.c | 27 +++++++++------ src/test_syscall.c | 12 +++++-- test/dbstatus2.test | 2 +- test/e_vacuum.test | 2 +- test/exists.test | 1 + test/hook.test | 2 +- test/incrvacuum2.test | 2 +- test/journal2.test | 2 +- test/permutations.test | 10 +++--- test/pragma3.test | 2 +- test/stat.test | 2 +- test/sync.test | 2 ++ test/tester.tcl | 6 ++++ test/tkt-2d1a5c67d.test | 3 +- test/tkt-313723c356.test | 2 +- test/tkt-5d863f876e.test | 2 +- test/tkt-9d68c883.test | 2 ++ test/zerodamage.test | 2 +- 25 files changed, 127 insertions(+), 64 deletions(-) diff --git a/ext/session/sessionfault.test b/ext/session/sessionfault.test index 6560ea8755..be6c4568ce 100644 --- a/ext/session/sessionfault.test +++ b/ext/session/sessionfault.test @@ -17,6 +17,7 @@ if {![info exists testdir]} { } source [file join [file dirname [info script]] session_common.tcl] source $testdir/tester.tcl +ifcapable !session {finish_test; return} set testprefix sessionfault diff --git a/ext/session/sessionfault2.test b/ext/session/sessionfault2.test index 6b257cf41b..ffdc57b9bc 100644 --- a/ext/session/sessionfault2.test +++ b/ext/session/sessionfault2.test @@ -17,6 +17,7 @@ if {![info exists testdir]} { } source [file join [file dirname [info script]] session_common.tcl] source $testdir/tester.tcl +ifcapable !session {finish_test; return} set testprefix sessionfault2 do_execsql_test 1.0.0 { diff --git a/manifest b/manifest index 7fa7ebedf8..e587ac6205 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C More\ssimplification\sof\sthe\ssqlite3AtoF()\sroutine.\s\sAdd\sspecial\scomments\nto\sindicate\sbranches\sthat\sare\sfor\soptimization\spurposes\sonly\sand\sthat\sgive\nthe\scorrect\sanswer\seven\sif\salways\sor\snever\staken. -D 2016-04-27T15:24:13.573 +C Modify\sthe\spermutations.test\sscript\sso\sas\sto\sset\sany\spermutation\sspecific\sconfiguration\svalues\sbefore\srunning\seach\sindividual\stest\sscript. +D 2016-04-27T18:54:49.294 F Makefile.in 9e816d0323e418fbc0f8b2c05fc14e0b3763d9e8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -291,8 +291,8 @@ F ext/session/sessionE.test e60a238c47f0feb3bb707e7f35e22be09c7e8f26 F ext/session/sessionF.test c2f178d4dfd723a5fd94a730ea2ccb44c669e3ce F ext/session/sessionG.test 01ef705096a9d3984eebdcca79807a211dee1b60 F ext/session/session_common.tcl a1293167d14774b5e728836720497f40fe4ea596 -F ext/session/sessionfault.test d52cbb7bee48cc8ee80335e07eb72fcb6b15eb40 -F ext/session/sessionfault2.test ac1dfd77a0fb0ea310aee40a16645ef1b66d3f88 +F ext/session/sessionfault.test da273f2712b6411e85e71465a1733b8501dbf6f7 +F ext/session/sessionfault2.test 04aa0bc9aa70ea43d8de82c4f648db4de1e990b0 F ext/session/sqlite3session.c beb300cd1b5c5054062c8e6e807b10475e363410 F ext/session/sqlite3session.h 64e9e7f185725ef43b97f4a9a0c0df0669844f1d F ext/session/test_session.c 464f2c8bf502795d95969387eb8e93f68c513c15 @@ -387,12 +387,12 @@ F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 F src/tclsqlite.c 9c4c4589d078de37813ded708d8838b338ffb060 -F src/test1.c abc10e3e81258835aeb59616685d7369ba99ad1e +F src/test1.c 0b0b9483649d48846655ea30345bb3fe917555d6 F src/test2.c 5586f43fcd9a1be0830793cf9d354082c261b25b F src/test3.c a8887dabbbee3059af338f20d290084a63ed1b0f F src/test4.c d168f83cc78d02e8d35567bb5630e40dcd85ac1e F src/test5.c 5a34feec76d9b3a86aab30fd4f6cc9c48cbab4c1 -F src/test6.c 41cacf3b0dd180823919bf9e1fbab287c9266723 +F src/test6.c 2c014d4977efd6107ec9eef3dfdec56ac516f824 F src/test7.c 9c89a4f1ed6bb13af0ed805b8d782bd83fcd57e3 F src/test8.c fa262391d3edea6490a71bfaa8fed477ccbbac75 F src/test9.c bea1e8cf52aa93695487badedd6e1886c321ea60 @@ -404,14 +404,14 @@ F src/test_blob.c b2551a9b5573232db5f66f292307c37067937239 F src/test_btree.c 2e9978eca99a9a4bfa8cae949efb00886860a64f F src/test_config.c 7003f6f35134de6f19c6588f44783e43390ea277 F src/test_demovfs.c 0de72c2c89551629f58486fde5734b7d90758852 -F src/test_devsym.c 7e73009d5297b603c11c66d7c7d6723d4b5c73e1 +F src/test_devsym.c 4e58dec2602d8e139ca08659f62a62450587cb58 F src/test_fs.c f10f840ca4f8c72e4837908bd8347ac4bcab074b F src/test_func.c 37453d346cfcf118774efd5bf6187f7e6a7e3254 F src/test_hexio.c abfdecb6fa58c354623978efceb088ca18e379cd F src/test_init.c 66b33120ffe9cd853b5a905ec850d51151337b32 F src/test_intarray.c 870124b95ec4c645d4eb84f15efb7133528fb1a5 F src/test_intarray.h 9dc57417fb65bc7835cc18548852cc08cc062202 -F src/test_journal.c da540964c675fde39487da2bc664096af97190d8 +F src/test_journal.c d3b83f2bcb7792c709e57abddc456a2b1818643a F src/test_loadext.c 337056bae59f80b9eb00ba82088b39d0f4fe6dfd F src/test_malloc.c 94c18e88d6df6d471a0d04ddb809f833d1739950 F src/test_multiplex.c eafc567ebe162e36f17b5062285dfe90461cf8e9 @@ -427,7 +427,7 @@ F src/test_schema.c 2bdba21b82f601da69793e1f1d11bf481a79b091 F src/test_server.c a2615049954cbb9cfb4a62e18e2f0616e4dc38fe F src/test_sqllog.c 0d138a8180a312bf996b37fa66da5c5799d4d57b F src/test_superlock.c 06797157176eb7085027d9dd278c0d7a105e3ec9 -F src/test_syscall.c 4889d374f5a5856b7951f7a67c6401f7b938c6f5 +F src/test_syscall.c 268c072541162564a882c57f54a6fee12ef4a4d2 F src/test_tclvar.c d86412527da65468ee6fa1b8607c65d0af736bc4 F src/test_thread.c af391ec03d23486dffbcc250b7e58e073f172af9 F src/test_vfs.c 4d02f38bfb8f7f273da7ba84bfe000f5babf206c @@ -612,7 +612,7 @@ F test/ctime.test 7bd009071e242aac4f18521581536b652b789a47 F test/cursorhint.test 7bc346788390475e77a345da2b92270d04d35856 F test/date.test 984ac1e3e5e031386866f034006148d3972b4a65 F test/dbstatus.test 8de104bb5606f19537d23cd553b41349b5ab1204 -F test/dbstatus2.test 10418e62b3db5dca070f0c3eef3ea13946f339c2 +F test/dbstatus2.test e93ab03bfae6d62d4d935f20de928c19ca0ed0ab F test/default.test 0cb49b1c315a0d81c81d775e407f66906a2a604d F test/delete.test e1bcdf8926234e27aac24b346ad83d3329ec8b6f F test/delete2.test 3a03f2cca1f9a67ec469915cb8babd6485db43fa @@ -644,7 +644,7 @@ F test/e_select2.test aceb80ab927d46fba5ce7586ebabf23e2bb0604f F test/e_totalchanges.test b12ee5809d3e63aeb83238dd501a7bca7fd72c10 F test/e_update.test f46c2554d915c9197548681e8d8c33a267e84528 F test/e_uri.test 25385396082b67fd02ae0038b95a3b3575fe0519 -F test/e_vacuum.test 4d5b391384bb7d56bb9337d956f08035332421fc +F test/e_vacuum.test 120f29ea56bdce4d43279527ece894ab5d1729d3 F test/e_wal.test ae9a593207a77d711443ee69ffe081fda9243625 F test/e_walauto.test 248af31e73c98df23476a22bdb815524c9dc3ba8 F test/e_walckpt.test 28c371a6bb5e5fe7f31679c1df1763a19d19e8a0 @@ -659,7 +659,7 @@ F test/eval.test a64c9105d6ff163df7cf09d6ac29cdad5922078c F test/exclusive.test 9a57bd66e39144b888ca75c309914fcdefb4e3f9 F test/exclusive2.test 32798111aae78a5deec980eee383213f189df308 F test/exec.test e949714dc127eaa5ecc7d723efec1ec27118fdd7 -F test/exists.test 8f7b27b61c2fbe5822f0a1f899c715d14e416e30 +F test/exists.test 79a75323c78f02bbe9c251ea502a092f9ef63dac F test/expr.test 79c3e7502d9e571553b85f0ecc8ff2ac7d0e4931 F test/extension01.test 00d13cec817f331a687a243e0e5a2d87b0e358c9 F test/extraquick.test cb254400bd42bfb777ff675356aabf3287978f79 @@ -808,7 +808,7 @@ F test/fuzzerfault.test 8792cd77fd5bce765b05d0c8e01b9edcf8af8536 F test/genesis.tcl 1e2e2e8e5cc4058549a154ff1892fe5c9de19f98 F test/hexlit.test d7b0a5f41123df1e43985b91b8b2e70f95282d21 F test/hidden.test 23c1393a79e846d68fd902d72c85d5e5dcf98711 -F test/hook.test 40523db3aa76d62bda71c26f824fa0eabc420f0e +F test/hook.test 3b7b99d0eece6d279812c2aef6fa08bdfabc633e F test/icu.test 73956798bace8982909c00476b216714a6d0559a F test/ieee754.test 806fc0ce7f305f57e3331eaceeddcfec9339e607 F test/imposter1.test c3f1db2d3db2c24611a6596a3fc0ffc14f1466c8 @@ -825,7 +825,7 @@ F test/incrblob_err.test 69f9247fed50278d48ea710d1a8f9cdb09e4c0b8 F test/incrblobfault.test 280474078f6da9e732cd2a215d3d854969014b6e F test/incrcorrupt.test 6c567fbf870aa9e91866fe52ce6f200cd548939a F test/incrvacuum.test d2a6ddf5e429720b5fe502766af747915ccf6c32 -F test/incrvacuum2.test 676c41428765d58f1da7dbe659ef27726d3d30ac +F test/incrvacuum2.test 7d26cfda66c7e55898d196de54ac4ec7d86a4e3d F test/incrvacuum3.test 75256fb1377e7c39ef2de62bfc42bbff67be295a F test/incrvacuum_ioerr.test 6ae2f783424e47a0033304808fe27789cf93e635 F test/index.test fe3c7a1aad82af92623747e9c3f3aa94ccd51238 @@ -862,7 +862,7 @@ F test/join4.test 1a352e4e267114444c29266ce79e941af5885916 F test/join5.test 8a5c0be6f0c260a5c7177c3b8f07c7856141038a F test/join6.test cfe6503791ceb0cbb509966740286ec423cbf10b F test/journal1.test 69abc726c51b4a0409189f9a85191205297c0577 -F test/journal2.test ae06f566c28552c313ded3fee79a6c69e6d049b1 +F test/journal2.test 9dac6b4ba0ca79c3b21446bbae993a462c2397c4 F test/journal3.test ff8af941f9e06161d3db1b46bb9f965ff0e7f307 F test/jrnlmode.test 7864d59cf7f6e552b9b99ba0f38acd167edc10fa F test/jrnlmode2.test 81610545a4e6ed239ea8fa661891893385e23a1d @@ -977,10 +977,10 @@ F test/parser1.test 222b5cbf3e2e659fec1bf7d723488c8b9c94f1d0 F test/pcache.test c8acbedd3b6fd0f9a7ca887a83b11d24a007972b F test/pcache2.test af7f3deb1a819f77a6d0d81534e97d1cf62cd442 F test/percentile.test 4243af26b8f3f4555abe166f723715a1f74c77ff -F test/permutations.test cd1fa041074ed08eeaa563e4d1bacb0c69337ec1 +F test/permutations.test 44b5d257ff1e2bf102ffea50bd31f793de0c14f7 F test/pragma.test dd5313eee9c6d9d4726593a68ede8768d3b50ccc F test/pragma2.test e5d5c176360c321344249354c0c16aec46214c9f -F test/pragma3.test 3f1984a04657331f838df5c519b443c2088df922 +F test/pragma3.test 14c12bc5352b1e100e0b6b44f371053a81ccf8ed F test/printf.test b3ff34e73d59124140eaf89f7672e21bc2ca5fcc F test/printf2.test 0b61566dd1c0f0b802f59dffa228c5dc5aa6b054 F test/progress.test ebab27f670bd0d4eb9d20d49cef96e68141d92fb @@ -1092,7 +1092,7 @@ F test/spellfix3.test 0f9efaaa502a0e0a09848028518a6fb096c8ad33 F test/sqldiff1.test 28cd737cf1b0078b1ec1bbf425e674c47785835e F test/sqllimits1.test a74ee2a3740b9f9c2437c246d8fb77354862a142 F test/sqllog.test 6af6cb0b09f4e44e1917e06ce85be7670302517a -F test/stat.test b65bad7120c52583b8f0054d99eff80718119a77 +F test/stat.test 66e95f97b9f724f9ab921d054ee0db3c2689f1ee F test/statfault.test f525a7bf633e50afd027700e9a486090684b1ac1 F test/stmt.test 64844332db69cf1a735fcb3e11548557fc95392f F test/subquery.test d7268d193dd33d5505df965399d3a594e76ae13f @@ -1102,7 +1102,7 @@ F test/substr.test 18f57c4ca8a598805c4d64e304c418734d843c1a F test/subtype1.test 7fe09496352f97053af1437150751be2d0a0cae8 F test/superlock.test ec94f0556b6488d97f71c79f9061ae08d9ab8f12 F test/symlink.test c9ebe7330d228249e447038276bfc8a7b22f4849 -F test/sync.test 2f607e1821aa3af3c5c53b58835c05e511c95899 +F test/sync.test 2f84bdbc2b2df1fcb0220575b4b9f8cea94b7529 F test/syscall.test f59ba4e25f7ba4a4c031026cc2ef8b6e4b4c639c F test/sysfault.test c9f2b0d8d677558f74de750c75e12a5454719d04 F test/tabfunc01.test f977868fa8bb7beb4b2072883190411653473906 @@ -1113,7 +1113,7 @@ F test/tclsqlite.test e1306001a0ca92250b691ea6d3cecaca5b6342aa F test/tempdb.test bd92eba8f20e16a9136e434e20b280794de3cdb6 F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30 F test/temptrigger.test 8ec228b0db5d7ebc4ee9b458fc28cb9e7873f5e1 -F test/tester.tcl 7b740ee852c55e1e72b6ebe5044acee7aa4e5553 +F test/tester.tcl 30c7a9be8601d1c1c9c93d013545ebcb28d64254 F test/thread001.test 9f22fd3525a307ff42a326b6bc7b0465be1745a5 F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58 F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7 @@ -1129,10 +1129,10 @@ F test/threadtest4.c c1e67136ceb6c7ec8184e56ac61db28f96bd2925 F test/tkt-02a8e81d44.test 6c80d9c7514e2a42d4918bf87bf6bc54f379110c F test/tkt-26ff0c2d1e.test 888324e751512972c6e0d1a09df740d8f5aaf660 F test/tkt-2a5629202f.test 0521bd25658428baa26665aa53ffed9367d33af2 -F test/tkt-2d1a5c67d.test d371279946622698ab393ff88cad9f5f6d82960b +F test/tkt-2d1a5c67d.test be1326f3061caec85085f4c9ee4490561ca037c0 F test/tkt-2ea2425d34.test 1cf13e6f75d149b3209a0cb32927a82d3d79fb28 F test/tkt-31338dca7e.test 6fb8807851964da0d24e942f2e19c7c705b9fb58 -F test/tkt-313723c356.test c47f8a9330523e6f35698bf4489bcb29609b53ac +F test/tkt-313723c356.test 4b306ad45c736cedf2f5221f6155b92143244b6d F test/tkt-385a5b56b9.test c0a06ada41d7f06b1686da0e718553f853771d1e F test/tkt-38cb5df375.test f3cc8671f1eb604d4ae9cf886ed4366bec656678 F test/tkt-3998683a16.test 6d1d04d551ed1704eb3396ca87bb9ccc8c5c1eb7 @@ -1143,7 +1143,7 @@ F test/tkt-4c86b126f2.test cbcc611becd0396890169ab23102dd70048bbc9a F test/tkt-4dd95f6943.test 3d0ce415d2ee15d3d564121960016b9c7be79407 F test/tkt-4ef7e3cfca.test 3965ae11cc9cf6e334f9d7d3c1e20bf8d56254b1 F test/tkt-54844eea3f.test a12b851128f46a695e4e378cca67409b9b8f5894 -F test/tkt-5d863f876e.test c9f36ca503fa154a3655f92a69d2c30da1747bfa +F test/tkt-5d863f876e.test 726e76d725f6fe0eb2fc8a522b721b79807380ee F test/tkt-5e10420e8d.test 904d1687b3c06d43e5b3555bbcf6802e7c0ffd84 F test/tkt-5ee23731f.test 9db6e1d7209dc0794948b260d6f82b2b1de83a9f F test/tkt-6bfb98dfc0.test 24780633627b5cfc0635a5500c2389ebfb563336 @@ -1159,7 +1159,7 @@ F test/tkt-8c63ff0ec.test 258b7fc8d7e4e1cb5362c7d65c143528b9c4cbed F test/tkt-91e2e8ba6f.test 08c4f94ae07696b05c9b822da0b4e5337a2f54c5 F test/tkt-94c04eaadb.test f738c57c7f68ab8be1c054415af7774617cb6223 F test/tkt-9a8b09f8e6.test b2ef151d0984b2ebf237760dbeaa50724e5a0667 -F test/tkt-9d68c883.test 458f7d82a523d7644b54b497c986378a7d8c8b67 +F test/tkt-9d68c883.test 16f7cb96781ba579bc2e19bb14b4ad609d9774b6 F test/tkt-9f2eb3abac.test cb6123ac695a08b4454c3792fbe85108f67fabf8 F test/tkt-a7b7803e.test 159ef554234fa1f9fb318c751b284bd1cf858da4 F test/tkt-a8a0d2996a.test eb597379dbcefa24765763d7f682c00cb5924fa9 @@ -1398,7 +1398,7 @@ F test/without_rowid5.test 89b1c587bd92a0590e440da33e7666bf4891572a F test/without_rowid6.test 1f99644e6508447fb050f73697350c7ceca3392e F test/wordcount.c 2a0a6c0d0e8e8bbbac1f06d72a6791828c37c0cf F test/zeroblob.test 3857870fe681b8185654414a9bccfde80b62a0fa -F test/zerodamage.test 2d725c214b883e25ae6bb85ef228ecdfa03c6a7b +F test/zerodamage.test e59a56443d6298ecf7435f618f0b27654f0c849e F tool/GetFile.cs a15e08acb5dd7539b75ba23501581d7c2b462cb5 F tool/GetTclKit.bat 629d87562e0487c386db630033931d12d62e6372 F tool/Replace.cs 02c67258801c2fb5f63231e0ac0f220b4b36ba91 @@ -1484,7 +1484,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 3adfe9f3e6ce7cc09fcb570d9b65e830a96cac15 -R 676347b15924e075b34cabb43dd7e840 -U drh -Z 680dc6a7c6e0d675cd4dc0c16abcab9d +P 0065fe97cb8e5076acae1bf1560fd2f69dab9014 +R 7df43ef0b7e3be4f42f2974bf9ebb1f9 +T *branch * permutations-fix +T *sym-permutations-fix * +T -sym-trunk * +U dan +Z 8c7c480375d878fe85148ba2747a0470 diff --git a/manifest.uuid b/manifest.uuid index a6a5e1cabb..a2dbc6c3ba 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0065fe97cb8e5076acae1bf1560fd2f69dab9014 \ No newline at end of file +2662d8fef791f7b8b3b14f9c27dfedec84620dee \ No newline at end of file diff --git a/src/test1.c b/src/test1.c index 5478a72549..2540f3e804 100644 --- a/src/test1.c +++ b/src/test1.c @@ -5213,7 +5213,9 @@ static int vfs_unregister_all( /* ** tclcmd: vfs_reregister_all ** -** Restore all VFSes that were removed using vfs_unregister_all +** Restore all VFSes that were removed using vfs_unregister_all. Taking +** care to put the linked list back together in the same order as it was +** in before vfs_unregister_all was invoked. */ static int vfs_reregister_all( ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ @@ -5222,8 +5224,8 @@ static int vfs_reregister_all( Tcl_Obj *CONST objv[] /* Command arguments */ ){ int i; - for(i=0; i=0; i--){ + sqlite3_vfs_register(apVfs[i], 1); } return TCL_OK; } diff --git a/src/test6.c b/src/test6.c index 306482dcd3..2a09122c6c 100644 --- a/src/test6.c +++ b/src/test6.c @@ -701,6 +701,10 @@ static int cfCurrentTime(sqlite3_vfs *pCfVfs, double *pTimeOut){ sqlite3_vfs *pVfs = (sqlite3_vfs *)pCfVfs->pAppData; return pVfs->xCurrentTime(pVfs, pTimeOut); } +static int cfGetLastError(sqlite3_vfs *pCfVfs, int n, char *z){ + sqlite3_vfs *pVfs = (sqlite3_vfs *)pCfVfs->pAppData; + return pVfs->xGetLastError(pVfs, n, z); +} static int processDevSymArgs( Tcl_Interp *interp, @@ -827,7 +831,7 @@ static int crashEnableCmd( cfRandomness, /* xRandomness */ cfSleep, /* xSleep */ cfCurrentTime, /* xCurrentTime */ - 0, /* xGetlastError */ + cfGetLastError, /* xGetLastError */ 0, /* xCurrentTimeInt64 */ }; @@ -940,6 +944,27 @@ static int devSymObjCmd( devsym_register(iDc, iSectorSize); return TCL_OK; + +} + +/* +** tclcmd: unregister_devsim +*/ +static int dsUnregisterObjCmd( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + void devsym_unregister(void); + + if( objc!=1 ){ + Tcl_WrongNumArgs(interp, 1, objv, ""); + return TCL_ERROR; + } + + devsym_unregister(); + return TCL_OK; } /* @@ -1010,6 +1035,7 @@ int Sqlitetest6_Init(Tcl_Interp *interp){ Tcl_CreateObjCommand(interp, "sqlite3_crash_enable", crashEnableCmd, 0, 0); Tcl_CreateObjCommand(interp, "sqlite3_crashparams", crashParamsObjCmd, 0, 0); Tcl_CreateObjCommand(interp, "sqlite3_simulate_device", devSymObjCmd, 0, 0); + Tcl_CreateObjCommand(interp, "unregister_devsim", dsUnregisterObjCmd, 0, 0); Tcl_CreateObjCommand(interp, "register_jt_vfs", jtObjCmd, 0, 0); Tcl_CreateObjCommand(interp, "unregister_jt_vfs", jtUnregisterObjCmd, 0, 0); #endif diff --git a/src/test_devsym.c b/src/test_devsym.c index 5fd0935846..9a1ba09d69 100644 --- a/src/test_devsym.c +++ b/src/test_devsym.c @@ -396,4 +396,11 @@ void devsym_register(int iDeviceChar, int iSectorSize){ } } +void devsym_unregister(){ + sqlite3_vfs_unregister(&devsym_vfs); + g.pVfs = 0; + g.iDeviceChar = 0; + g.iSectorSize = 0; +} + #endif diff --git a/src/test_journal.c b/src/test_journal.c index 84c80546a6..4e63bccf76 100644 --- a/src/test_journal.c +++ b/src/test_journal.c @@ -160,6 +160,7 @@ static int jtRandomness(sqlite3_vfs*, int nByte, char *zOut); static int jtSleep(sqlite3_vfs*, int microseconds); static int jtCurrentTime(sqlite3_vfs*, double*); static int jtCurrentTimeInt64(sqlite3_vfs*, sqlite3_int64*); +static int jtGetLastError(sqlite3_vfs*, int, char*); static sqlite3_vfs jt_vfs = { 2, /* iVersion */ @@ -179,7 +180,7 @@ static sqlite3_vfs jt_vfs = { jtRandomness, /* xRandomness */ jtSleep, /* xSleep */ jtCurrentTime, /* xCurrentTime */ - 0, /* xGetLastError */ + jtGetLastError, /* xGetLastError */ jtCurrentTimeInt64 /* xCurrentTimeInt64 */ }; @@ -285,9 +286,10 @@ static int jtRead( ** b) The file-name specified when the file was opened matches ** all but the final 8 characters of the journal file name. ** -** c) There is currently a reserved lock on the file. +** c) There is currently a reserved lock on the file. This +** condition is waived if the noLock argument is non-zero. **/ -static jt_file *locateDatabaseHandle(const char *zJournal){ +static jt_file *locateDatabaseHandle(const char *zJournal, int noLock){ jt_file *pMain = 0; enterJtMutex(); for(pMain=g.pList; pMain; pMain=pMain->pNext){ @@ -295,7 +297,7 @@ static jt_file *locateDatabaseHandle(const char *zJournal){ if( (pMain->flags&SQLITE_OPEN_MAIN_DB) && ((int)strlen(pMain->zName)==nName) && 0==memcmp(pMain->zName, zJournal, nName) - && (pMain->eLock>=SQLITE_LOCK_RESERVED) + && ((pMain->eLock>=SQLITE_LOCK_RESERVED) || noLock) ){ break; } @@ -517,7 +519,7 @@ static int jtWrite( jt_file *p = (jt_file *)pFile; if( p->flags&SQLITE_OPEN_MAIN_JOURNAL ){ if( iOfst==0 ){ - jt_file *pMain = locateDatabaseHandle(p->zName); + jt_file *pMain = locateDatabaseHandle(p->zName, 0); assert( pMain ); if( iAmt==28 ){ @@ -562,7 +564,7 @@ static int jtWrite( rc = sqlite3OsWrite(p->pReal, zBuf, iAmt, iOfst); if( (p->flags&SQLITE_OPEN_MAIN_JOURNAL) && iAmt==12 ){ - jt_file *pMain = locateDatabaseHandle(p->zName); + jt_file *pMain = locateDatabaseHandle(p->zName, 0); int rc2 = readJournalFile(p, pMain); if( rc==SQLITE_OK ) rc = rc2; } @@ -576,7 +578,7 @@ static int jtTruncate(sqlite3_file *pFile, sqlite_int64 size){ jt_file *p = (jt_file *)pFile; if( p->flags&SQLITE_OPEN_MAIN_JOURNAL && size==0 ){ /* Truncating a journal file. This is the end of a transaction. */ - jt_file *pMain = locateDatabaseHandle(p->zName); + jt_file *pMain = locateDatabaseHandle(p->zName, 0); closeTransaction(pMain); } if( p->flags&SQLITE_OPEN_MAIN_DB && p->pWritable ){ @@ -604,11 +606,10 @@ static int jtSync(sqlite3_file *pFile, int flags){ ** jt_file.pWritable bitvec of the main database file associated with ** this journal file. */ - pMain = locateDatabaseHandle(p->zName); - assert(pMain); + pMain = locateDatabaseHandle(p->zName, 0); /* Set the bitvec values */ - if( pMain->pWritable ){ + if( pMain && pMain->pWritable ){ pMain->nSync++; rc = readJournalFile(p, pMain); if( rc!=SQLITE_OK ){ @@ -730,7 +731,7 @@ static int jtDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){ int nPath = (int)strlen(zPath); if( nPath>8 && 0==strcmp("-journal", &zPath[nPath-8]) ){ /* Deleting a journal file. The end of a transaction. */ - jt_file *pMain = locateDatabaseHandle(zPath); + jt_file *pMain = locateDatabaseHandle(zPath, 0); if( pMain ){ closeTransaction(pMain); } @@ -825,6 +826,10 @@ static int jtCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *pTimeOut){ return g.pVfs->xCurrentTimeInt64(g.pVfs, pTimeOut); } +static int jtGetLastError(sqlite3_vfs *pVfs, int n, char *z){ + return g.pVfs->xGetLastError(g.pVfs, n, z); +} + /************************************************************************** ** Start of public API. */ diff --git a/src/test_syscall.c b/src/test_syscall.c index f9abc1e46d..f1d5c61bc3 100644 --- a/src/test_syscall.c +++ b/src/test_syscall.c @@ -722,14 +722,20 @@ static int test_syscall( }; int iCmd; int rc; + sqlite3_vfs *pVfs = sqlite3_vfs_find(0); if( objc<2 ){ Tcl_WrongNumArgs(interp, 1, objv, "SUB-COMMAND ..."); return TCL_ERROR; } - rc = Tcl_GetIndexFromObjStruct(interp, - objv[1], aCmd, sizeof(aCmd[0]), "sub-command", 0, &iCmd - ); + if( pVfs->iVersion<3 || pVfs->xSetSystemCall==0 ){ + Tcl_AppendResult(interp, "VFS does not support xSetSystemCall", 0); + rc = TCL_ERROR; + }else{ + rc = Tcl_GetIndexFromObjStruct(interp, + objv[1], aCmd, sizeof(aCmd[0]), "sub-command", 0, &iCmd + ); + } if( rc!=TCL_OK ) return rc; return aCmd[iCmd].xCmd(clientData, interp, objc, objv); } diff --git a/test/dbstatus2.test b/test/dbstatus2.test index 2541a1a823..eff4b0207f 100644 --- a/test/dbstatus2.test +++ b/test/dbstatus2.test @@ -86,7 +86,7 @@ do_test 2.3 { db_write db 1 } {0 4 0} do_test 2.4 { db_write db 0 } {0 0 0} do_test 2.5 { db_write db 1 } {0 0 0} -ifcapable wal { +if {[wal_is_capable]} { do_test 2.6 { execsql { PRAGMA journal_mode = WAL } db_write db 1 diff --git a/test/e_vacuum.test b/test/e_vacuum.test index 1113a1fb6e..c3e517a892 100644 --- a/test/e_vacuum.test +++ b/test/e_vacuum.test @@ -176,7 +176,7 @@ if {![nonzero_reserved_bytes]} { # EVIDENCE-OF: R-48521-51450 When in write-ahead log mode, only the # auto_vacuum support property can be changed using VACUUM. # - ifcapable wal { + if {[wal_is_capable]} { do_test e_vacuum-1.3.3.1 { execsql { PRAGMA journal_mode = wal } execsql { PRAGMA page_size ; PRAGMA auto_vacuum } diff --git a/test/exists.test b/test/exists.test index fb73797d29..5f9e36eb00 100644 --- a/test/exists.test +++ b/test/exists.test @@ -19,6 +19,7 @@ source $testdir/lock_common.tcl foreach jm {rollback wal} { + if {![wal_is_capable] && $jm=="wal"} continue set testprefix exists-$jm diff --git a/test/hook.test b/test/hook.test index 45e2959591..12e5bc0656 100644 --- a/test/hook.test +++ b/test/hook.test @@ -704,7 +704,7 @@ do_execsql_test 7.5.2.0 { ALTER TABLE t8 ADD COLUMN c DEFAULT 'xxx'; } -ifcapable !session { +if 0 { # At time of writing, these two are broken. They demonstrate that the # sqlite3_preupdate_old() method does not handle the case where ALTER TABLE # has been used to add a column with a default value other than NULL. diff --git a/test/incrvacuum2.test b/test/incrvacuum2.test index 2219d54195..6ec66c9deb 100644 --- a/test/incrvacuum2.test +++ b/test/incrvacuum2.test @@ -134,7 +134,7 @@ do_test incrvacuum2-3.2 { integrity_check incrvacuum2-3.3 -ifcapable wal { +if {[wal_is_capable]} { # At one point, when a specific page was being extracted from the b-tree # free-list (e.g. during an incremental-vacuum), all trunk pages that # occurred before the specific page in the free-list trunk were being diff --git a/test/journal2.test b/test/journal2.test index 8f9b4d0b71..7cbe0ef2c5 100644 --- a/test/journal2.test +++ b/test/journal2.test @@ -204,7 +204,7 @@ db close # delete the journal file when committing the transaction that switches # the system to WAL mode. # -ifcapable wal { +if {[wal_is_capable]} { do_test journal2-2.1 { faultsim_delete_and_reopen set ::oplog [list] diff --git a/test/permutations.test b/test/permutations.test index 308d8bde77..15576e4f9f 100644 --- a/test/permutations.test +++ b/test/permutations.test @@ -942,7 +942,9 @@ test_suite "journaltest" -description { unregister_jt_vfs } -files [test_set $::allquicktests -exclude { wal* incrvacuum.test ioerr.test corrupt4.test io.test crash8.test - async4.test bigfile.test backcompat.test + async4.test bigfile.test backcompat.test e_wal* fstat.test mmap2.test + pager1.test syscall.test tkt3457.test *malloc* mmap* multiplex* nolock* + pager2.test *fault* rowal* snapshot* superlock* symlink.test }] if {[info commands register_demovfs] != ""} { @@ -1050,15 +1052,13 @@ proc run_tests {name args} { set ::G(isquick) 1 set ::G(perm:dbconfig) $options(-dbconfig) - uplevel $options(-initialize) - foreach file [lsort $options(-files)] { + uplevel $options(-initialize) if {[file tail $file] == $file} { set file [file join $::testdir $file] } slave_test_file $file + uplevel $options(-shutdown) } - uplevel $options(-shutdown) - unset ::G(perm:name) unset ::G(perm:prefix) unset ::G(perm:presql) diff --git a/test/pragma3.test b/test/pragma3.test index 1a67d72350..8a4f4f9d84 100644 --- a/test/pragma3.test +++ b/test/pragma3.test @@ -221,7 +221,7 @@ ifcapable shared_cache { # This will not work with the in-memory journal permutation, as opening # [db2] switches the journal mode back to "memory" # -ifcapable wal { +if {[wal_is_capable]} { if {[permutation]!="inmemory_journal"} { sqlite3 db test.db diff --git a/test/stat.test b/test/stat.test index 95586e94bc..d106894d71 100644 --- a/test/stat.test +++ b/test/stat.test @@ -37,7 +37,7 @@ do_execsql_test stat-0.0 { SELECT * FROM stat; } {} -ifcapable wal { +if {[wal_is_capable]} { do_execsql_test stat-0.1 { PRAGMA journal_mode = WAL; PRAGMA journal_mode = delete; diff --git a/test/sync.test b/test/sync.test index 2ee636a266..210039acb5 100644 --- a/test/sync.test +++ b/test/sync.test @@ -81,6 +81,7 @@ do_test sync-1.3 { set sqlite_sync_count } 11 ifcapable pager_pragmas { +if {[permutation]!="journaltest"} { do_test sync-1.4 { set sqlite_sync_count 0 execsql { @@ -94,6 +95,7 @@ ifcapable pager_pragmas { set sqlite_sync_count } 0 } +} finish_test diff --git a/test/tester.tcl b/test/tester.tcl index 2fcae7b5a2..23810d09ee 100644 --- a/test/tester.tcl +++ b/test/tester.tcl @@ -1944,6 +1944,12 @@ proc wal_check_journal_mode {testname {db db}} { } } +proc wal_is_capable {} { + ifcapable !wal { return 0 } + if {[permutation]=="journaltest"} { return 0 } + return 1 +} + proc permutation {} { set perm "" catch {set perm $::G(perm:name)} diff --git a/test/tkt-2d1a5c67d.test b/test/tkt-2d1a5c67d.test index 3fef187ecd..0d12a6ec43 100644 --- a/test/tkt-2d1a5c67d.test +++ b/test/tkt-2d1a5c67d.test @@ -19,7 +19,8 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix tkt-2d1a5c67d -ifcapable {!wal || !vtab} {finish_test; return} +ifcapable {!vtab} {finish_test; return} +if {[wal_is_capable]==0} {finish_test; return} for {set ii 1} {$ii<=10} {incr ii} { do_test tkt-2d1a5c67d.1.$ii { diff --git a/test/tkt-313723c356.test b/test/tkt-313723c356.test index 8c08c34976..5325fd2292 100644 --- a/test/tkt-313723c356.test +++ b/test/tkt-313723c356.test @@ -18,7 +18,7 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl source $testdir/malloc_common.tcl -ifcapable !wal { finish_test ; return } +if {![wal_is_capable]} { finish_test ; return } do_execsql_test tkt-313723c356.1 { PRAGMA page_size = 1024; diff --git a/test/tkt-5d863f876e.test b/test/tkt-5d863f876e.test index 86024e300b..9a2fa3f470 100644 --- a/test/tkt-5d863f876e.test +++ b/test/tkt-5d863f876e.test @@ -18,7 +18,7 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl source $testdir/lock_common.tcl set ::testprefix tkt-5d863f876e -ifcapable !wal {finish_test ; return } +if {![wal_is_capable]} {finish_test ; return } do_multiclient_test tn { do_test $tn.1 { diff --git a/test/tkt-9d68c883.test b/test/tkt-9d68c883.test index 18dc6ccd67..ba91b39e39 100644 --- a/test/tkt-9d68c883.test +++ b/test/tkt-9d68c883.test @@ -50,4 +50,6 @@ for {set i 0} {$i < 100} {incr i} { } {ok} } +catch { db close } +unregister_devsim finish_test diff --git a/test/zerodamage.test b/test/zerodamage.test index d781ab89a3..a87e50b7b5 100644 --- a/test/zerodamage.test +++ b/test/zerodamage.test @@ -89,7 +89,7 @@ do_test zerodamage-2.1 { concat [file_control_powersafe_overwrite db -1] [set ::max_journal_size] } {0 0 24704} -ifcapable wal { +if {[wal_is_capable]} { # Run a WAL-mode transaction with POWERSAFE_OVERWRITE on to verify that the # WAL file does not get too big. # From 609d5846baf14c8886a690ead6fb3c0172f6ad4f Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 28 Apr 2016 00:32:16 +0000 Subject: [PATCH 0354/1484] Change the sqlite3Atoi64() routine so that it returns failure if not all of the input characters are consumed, even if it consumed all characters up to the first 0x00. This has no impact on external APIs as far as I can tell. FossilOrigin-Name: 46d4ffff3bd33d7e901e76cfac1cbde38d4f61d0 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/test1.c | 2 +- src/util.c | 11 +++++++---- 4 files changed, 16 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 7fa7ebedf8..a6ca358f63 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C More\ssimplification\sof\sthe\ssqlite3AtoF()\sroutine.\s\sAdd\sspecial\scomments\nto\sindicate\sbranches\sthat\sare\sfor\soptimization\spurposes\sonly\sand\sthat\sgive\nthe\scorrect\sanswer\seven\sif\salways\sor\snever\staken. -D 2016-04-27T15:24:13.573 +C Change\sthe\ssqlite3Atoi64()\sroutine\sso\sthat\sit\sreturns\sfailure\sif\snot\sall\sof\nthe\sinput\scharacters\sare\sconsumed,\seven\sif\sit\sconsumed\sall\scharacters\sup\sto\nthe\sfirst\s0x00.\s\sThis\shas\sno\simpact\son\sexternal\sAPIs\sas\sfar\sas\sI\scan\stell. +D 2016-04-28T00:32:16.814 F Makefile.in 9e816d0323e418fbc0f8b2c05fc14e0b3763d9e8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -387,7 +387,7 @@ F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 F src/tclsqlite.c 9c4c4589d078de37813ded708d8838b338ffb060 -F src/test1.c abc10e3e81258835aeb59616685d7369ba99ad1e +F src/test1.c 922fd57b211e14761ef846cebfd09a1922771960 F src/test2.c 5586f43fcd9a1be0830793cf9d354082c261b25b F src/test3.c a8887dabbbee3059af338f20d290084a63ed1b0f F src/test4.c d168f83cc78d02e8d35567bb5630e40dcd85ac1e @@ -441,7 +441,7 @@ F src/treeview.c e4b41a37530a191579d3c53142cc44ee2eb99373 F src/trigger.c e14840ee0c3e549e758ec9bf3e4146e166002280 F src/update.c 3e67ab3c0814635f355fb1f8ab010a2b9e016e7d F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c -F src/util.c d0899604c30b4a9d493980aa7742eeda383fff6d +F src/util.c 1d2f9cc9ea43c5bc9a3b7e29b953001b0e85f5c7 F src/vacuum.c feb1eabb20987983d9350cad98299b21fa811f52 F src/vdbe.c d3843a66d74a7696477ee5141e5eb9a7e5e2401c F src/vdbe.h 5591b5add447096e31288b5a0a78ec5d7b5c5170 @@ -1484,7 +1484,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 3adfe9f3e6ce7cc09fcb570d9b65e830a96cac15 -R 676347b15924e075b34cabb43dd7e840 +P 0065fe97cb8e5076acae1bf1560fd2f69dab9014 +R 3ff6e84daa3c00c689a29794b4bf7803 U drh -Z 680dc6a7c6e0d675cd4dc0c16abcab9d +Z 1cade5a69af13a9b74de489bf6c2518b diff --git a/manifest.uuid b/manifest.uuid index a6a5e1cabb..fa2b210a37 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0065fe97cb8e5076acae1bf1560fd2f69dab9014 \ No newline at end of file +46d4ffff3bd33d7e901e76cfac1cbde38d4f61d0 \ No newline at end of file diff --git a/src/test1.c b/src/test1.c index 5478a72549..98afb03e12 100644 --- a/src/test1.c +++ b/src/test1.c @@ -1271,7 +1271,7 @@ static int sqlite3_mprintf_int64( return TCL_ERROR; } for(i=2; i<5; i++){ - if( sqlite3Atoi64(argv[i], &a[i-2], 1000000, SQLITE_UTF8) ){ + if( sqlite3Atoi64(argv[i], &a[i-2], sqlite3Strlen30(argv[i]), SQLITE_UTF8) ){ Tcl_AppendResult(interp, "argument is not a valid 64-bit integer", 0); return TCL_ERROR; } diff --git a/src/util.c b/src/util.c index 1f59a9f731..e883b1b9eb 100644 --- a/src/util.c +++ b/src/util.c @@ -574,7 +574,7 @@ int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc){ int neg = 0; /* assume positive */ int i; int c = 0; - int nonNum = 0; + int nonNum = 0; /* True if input contains UTF16 with high byte non-zero */ const char *zStart; const char *zEnd = zNum + length; assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE ); @@ -585,7 +585,7 @@ int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc){ assert( SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 ); for(i=3-enc; i19*incr || nonNum ){ + if( &zNum[i]19*incr /* Too many digits */ + || nonNum /* UTF16 with high-order bytes non-zero */ + ){ /* zNum is empty or contains non-numeric text or is longer ** than 19 digits (thus guaranteeing that it is too large) */ return 1; From 10c0a2a7c9e40ac583d5fb02701c19510110c78f Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 28 Apr 2016 03:52:18 +0000 Subject: [PATCH 0355/1484] Remove an unnecessary conditional from the sqlite3DecOrHexToI64() routine. FossilOrigin-Name: fcf85bfe50b254e825ee63a4cd0aa0b333b06eed --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/util.c | 1 - 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index a6ca358f63..0e64cb6d65 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sthe\ssqlite3Atoi64()\sroutine\sso\sthat\sit\sreturns\sfailure\sif\snot\sall\sof\nthe\sinput\scharacters\sare\sconsumed,\seven\sif\sit\sconsumed\sall\scharacters\sup\sto\nthe\sfirst\s0x00.\s\sThis\shas\sno\simpact\son\sexternal\sAPIs\sas\sfar\sas\sI\scan\stell. -D 2016-04-28T00:32:16.814 +C Remove\san\sunnecessary\sconditional\sfrom\sthe\ssqlite3DecOrHexToI64()\sroutine. +D 2016-04-28T03:52:18.237 F Makefile.in 9e816d0323e418fbc0f8b2c05fc14e0b3763d9e8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -441,7 +441,7 @@ F src/treeview.c e4b41a37530a191579d3c53142cc44ee2eb99373 F src/trigger.c e14840ee0c3e549e758ec9bf3e4146e166002280 F src/update.c 3e67ab3c0814635f355fb1f8ab010a2b9e016e7d F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c -F src/util.c 1d2f9cc9ea43c5bc9a3b7e29b953001b0e85f5c7 +F src/util.c 41cac9db948cd1f746636cc6a0c60d4234d4053f F src/vacuum.c feb1eabb20987983d9350cad98299b21fa811f52 F src/vdbe.c d3843a66d74a7696477ee5141e5eb9a7e5e2401c F src/vdbe.h 5591b5add447096e31288b5a0a78ec5d7b5c5170 @@ -1484,7 +1484,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 0065fe97cb8e5076acae1bf1560fd2f69dab9014 -R 3ff6e84daa3c00c689a29794b4bf7803 +P 46d4ffff3bd33d7e901e76cfac1cbde38d4f61d0 +R 229317c8b5ac201d05335df0607fe343 U drh -Z 1cade5a69af13a9b74de489bf6c2518b +Z 98856d3d087818ace0a186a1d76b304b diff --git a/manifest.uuid b/manifest.uuid index fa2b210a37..61f1101a9b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -46d4ffff3bd33d7e901e76cfac1cbde38d4f61d0 \ No newline at end of file +fcf85bfe50b254e825ee63a4cd0aa0b333b06eed \ No newline at end of file diff --git a/src/util.c b/src/util.c index e883b1b9eb..748f8e802a 100644 --- a/src/util.c +++ b/src/util.c @@ -658,7 +658,6 @@ int sqlite3DecOrHexToI64(const char *z, i64 *pOut){ #ifndef SQLITE_OMIT_HEX_INTEGER if( z[0]=='0' && (z[1]=='x' || z[1]=='X') - && sqlite3Isxdigit(z[2]) ){ u64 u = 0; int i, k; From 3104c4d6f432335fade4e254580f7019c1d71038 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 28 Apr 2016 09:53:14 +0000 Subject: [PATCH 0356/1484] Ensure that quota.test deletes the directory named "test.db" that it creates. FossilOrigin-Name: 045edd4b17c6b76079ac90773c035d8c1f8d525d --- manifest | 15 ++++++--------- manifest.uuid | 2 +- test/quota.test | 2 ++ 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index e587ac6205..4851ef79ae 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Modify\sthe\spermutations.test\sscript\sso\sas\sto\sset\sany\spermutation\sspecific\sconfiguration\svalues\sbefore\srunning\seach\sindividual\stest\sscript. -D 2016-04-27T18:54:49.294 +C Ensure\sthat\squota.test\sdeletes\sthe\sdirectory\snamed\s"test.db"\sthat\sit\screates. +D 2016-04-28T09:53:14.110 F Makefile.in 9e816d0323e418fbc0f8b2c05fc14e0b3763d9e8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -988,7 +988,7 @@ F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc F test/queryonly.test 5f653159e0f552f0552d43259890c1089391dcca F test/quick.test 1681febc928d686362d50057c642f77a02c62e57 F test/quota-glob.test 32901e9eed6705d68ca3faee2a06b73b57cb3c26 -F test/quota.test 36cd78b178c4eb0401d4f25754ef410fbd9df2a7 +F test/quota.test bfb269ce81ea52f593f9648316cd5013d766dd2a F test/quota2.test 7dc12e08b11cbc4c16c9ba2aa2e040ea8d8ab4b8 F test/quote.test 215897dbe8de1a6f701265836d6601cc6ed103e6 F test/randexpr1.tcl 40dec52119ed3a2b8b2a773bce24b63a3a746459 @@ -1484,10 +1484,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 0065fe97cb8e5076acae1bf1560fd2f69dab9014 -R 7df43ef0b7e3be4f42f2974bf9ebb1f9 -T *branch * permutations-fix -T *sym-permutations-fix * -T -sym-trunk * +P 2662d8fef791f7b8b3b14f9c27dfedec84620dee +R c0f9313eefa2a94509287d7302d3c22e U dan -Z 8c7c480375d878fe85148ba2747a0470 +Z e1c90065dd206cf7c15216b8288594e5 diff --git a/manifest.uuid b/manifest.uuid index a2dbc6c3ba..be4490f793 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2662d8fef791f7b8b3b14f9c27dfedec84620dee \ No newline at end of file +045edd4b17c6b76079ac90773c035d8c1f8d525d \ No newline at end of file diff --git a/test/quota.test b/test/quota.test index 7af55a8330..5d0bda3ad3 100644 --- a/test/quota.test +++ b/test/quota.test @@ -527,4 +527,6 @@ do_faultsim_test quota-5.6 -prep { } catch { sqlite3_quota_shutdown } +catch { db close } +forcedelete test.db finish_test From 75ab50ce8ff0821bae0989a86f037024fd6a8711 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 28 Apr 2016 14:15:12 +0000 Subject: [PATCH 0357/1484] Use comments to mark several branches as optimizations. No changes to code. FossilOrigin-Name: 33e627472780b872716c504f2d585cc057c390a5 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/hash.c | 4 ++-- src/util.c | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 0e64cb6d65..4e86475b14 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\san\sunnecessary\sconditional\sfrom\sthe\ssqlite3DecOrHexToI64()\sroutine. -D 2016-04-28T03:52:18.237 +C Use\scomments\sto\smark\sseveral\sbranches\sas\soptimizations.\s\sNo\schanges\sto\scode. +D 2016-04-28T14:15:12.903 F Makefile.in 9e816d0323e418fbc0f8b2c05fc14e0b3763d9e8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -336,7 +336,7 @@ F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 4c0bd09e602b8ae8d36d81e31e4872d0b53c87bb F src/func.c ef4c18c8a66143413ce41a58d582d2c14ddf78e1 F src/global.c c45ea22aff29334f6a9ec549235ac3357c970015 -F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5 +F src/hash.c 55b5fb474100cee0b901edaf203e26c970940f36 F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 F src/insert.c 8f4e9fcbd8e95e85f15647ba8b413b18d556ec2b @@ -441,7 +441,7 @@ F src/treeview.c e4b41a37530a191579d3c53142cc44ee2eb99373 F src/trigger.c e14840ee0c3e549e758ec9bf3e4146e166002280 F src/update.c 3e67ab3c0814635f355fb1f8ab010a2b9e016e7d F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c -F src/util.c 41cac9db948cd1f746636cc6a0c60d4234d4053f +F src/util.c 810ec3f22e2d1b62e66c30fe3621ebdedd23584d F src/vacuum.c feb1eabb20987983d9350cad98299b21fa811f52 F src/vdbe.c d3843a66d74a7696477ee5141e5eb9a7e5e2401c F src/vdbe.h 5591b5add447096e31288b5a0a78ec5d7b5c5170 @@ -1484,7 +1484,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 46d4ffff3bd33d7e901e76cfac1cbde38d4f61d0 -R 229317c8b5ac201d05335df0607fe343 +P fcf85bfe50b254e825ee63a4cd0aa0b333b06eed +R 197c644a6cd9b0806f84f77482d9fe15 U drh -Z 98856d3d087818ace0a186a1d76b304b +Z 413f6650964e5d2ab342130728703294 diff --git a/manifest.uuid b/manifest.uuid index 61f1101a9b..abe023c752 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fcf85bfe50b254e825ee63a4cd0aa0b333b06eed \ No newline at end of file +33e627472780b872716c504f2d585cc057c390a5 \ No newline at end of file diff --git a/src/hash.c b/src/hash.c index b5886e0641..eea2dd1ac2 100644 --- a/src/hash.c +++ b/src/hash.c @@ -55,7 +55,7 @@ void sqlite3HashClear(Hash *pH){ static unsigned int strHash(const char *z){ unsigned int h = 0; unsigned char c; - while( (c = (unsigned char)*z++)!=0 ){ + while( (c = (unsigned char)*z++)!=0 ){ /*OPTIMIZATION-IF-TRUE*/ h = (h<<3) ^ h ^ sqlite3UpperToLower[c]; } return h; @@ -148,7 +148,7 @@ static HashElem *findElementWithHash( int count; /* Number of elements left to test */ unsigned int h; /* The computed hash */ - if( pH->ht ){ + if( pH->ht ){ /*OPTIMIZATION-IF-TRUE*/ struct _ht *pEntry; h = strHash(pKey) % pH->htsize; pEntry = &pH->ht[h]; diff --git a/src/util.c b/src/util.c index 748f8e802a..db6163c3c7 100644 --- a/src/util.c +++ b/src/util.c @@ -1419,7 +1419,7 @@ LogEst sqlite3LogEst(u64 x){ if( x<2 ) return 0; while( x<8 ){ y -= 10; x <<= 1; } }else{ - while( x>255 ){ y += 40; x >>= 4; } + while( x>255 ){ y += 40; x >>= 4; } /*OPTIMIZATION-IF-TRUE*/ while( x>15 ){ y += 10; x >>= 1; } } return a[x&7] + y - 10; From 14cee38be8249d7d15e07b4a27a3d0e2b98dcac0 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 28 Apr 2016 14:54:54 +0000 Subject: [PATCH 0358/1484] Avoid running sessionfault.test and sessionfault2.test as part of the "inmemory_journal" permutation. FossilOrigin-Name: 5973d3bf2e5aa979ccc9a4a3a0eb08b67098b499 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/permutations.test | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 4851ef79ae..24ba903e1f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Ensure\sthat\squota.test\sdeletes\sthe\sdirectory\snamed\s"test.db"\sthat\sit\screates. -D 2016-04-28T09:53:14.110 +C Avoid\srunning\ssessionfault.test\sand\ssessionfault2.test\sas\spart\sof\sthe\s"inmemory_journal"\spermutation. +D 2016-04-28T14:54:54.590 F Makefile.in 9e816d0323e418fbc0f8b2c05fc14e0b3763d9e8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -977,7 +977,7 @@ F test/parser1.test 222b5cbf3e2e659fec1bf7d723488c8b9c94f1d0 F test/pcache.test c8acbedd3b6fd0f9a7ca887a83b11d24a007972b F test/pcache2.test af7f3deb1a819f77a6d0d81534e97d1cf62cd442 F test/percentile.test 4243af26b8f3f4555abe166f723715a1f74c77ff -F test/permutations.test 44b5d257ff1e2bf102ffea50bd31f793de0c14f7 +F test/permutations.test b6b3e165fdc1b8c82a820033646dbfc6a7a01746 F test/pragma.test dd5313eee9c6d9d4726593a68ede8768d3b50ccc F test/pragma2.test e5d5c176360c321344249354c0c16aec46214c9f F test/pragma3.test 14c12bc5352b1e100e0b6b44f371053a81ccf8ed @@ -1484,7 +1484,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 2662d8fef791f7b8b3b14f9c27dfedec84620dee -R c0f9313eefa2a94509287d7302d3c22e +P 045edd4b17c6b76079ac90773c035d8c1f8d525d +R e73b09d1e2cd9d2d69ece961d0e8362f U dan -Z e1c90065dd206cf7c15216b8288594e5 +Z aff771281cb418c17327081bdcd3c618 diff --git a/manifest.uuid b/manifest.uuid index be4490f793..7a52ce8e55 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -045edd4b17c6b76079ac90773c035d8c1f8d525d \ No newline at end of file +5973d3bf2e5aa979ccc9a4a3a0eb08b67098b499 \ No newline at end of file diff --git a/test/permutations.test b/test/permutations.test index 15576e4f9f..df3f500cda 100644 --- a/test/permutations.test +++ b/test/permutations.test @@ -728,7 +728,7 @@ test_suite "inmemory_journal" -description { ioerr.test ioerr2.test ioerr3.test ioerr4.test ioerr5.test vacuum3.test incrblob_err.test diskfull.test backup_ioerr.test e_fts3.test fts3cov.test fts3malloc.test fts3rnd.test - fts3snippet.test mmapfault.test + fts3snippet.test mmapfault.test sessionfault.test sessionfault2.test # Exclude test scripts that use tcl IO to access journal files or count # the number of fsync() calls. From cb6d66becc06dd0ad293779e02b8b9b25dfe3301 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 28 Apr 2016 18:53:08 +0000 Subject: [PATCH 0359/1484] Rearrange some code in the RowSet logic for clarity of presentation, while adding an /*OPTIMIZATION-IF-TRUE*/ comment. It should operate identically. FossilOrigin-Name: 5748e64376c1c2be5154a632d1527cfebbb9ec74 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/rowset.c | 23 +++++++++++++---------- 3 files changed, 20 insertions(+), 17 deletions(-) diff --git a/manifest b/manifest index 4e86475b14..0837962a87 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Use\scomments\sto\smark\sseveral\sbranches\sas\soptimizations.\s\sNo\schanges\sto\scode. -D 2016-04-28T14:15:12.903 +C Rearrange\ssome\scode\sin\sthe\sRowSet\slogic\sfor\sclarity\sof\spresentation,\swhile\nadding\san\s/*OPTIMIZATION-IF-TRUE*/\scomment.\s\sIt\sshould\soperate\sidentically. +D 2016-04-28T18:53:08.454 F Makefile.in 9e816d0323e418fbc0f8b2c05fc14e0b3763d9e8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -376,7 +376,7 @@ F src/prepare.c 22df6171aec1d86904ed2ad30c2348a5748aa04e F src/printf.c 63e6fb12bbe702dd664dc3703776c090383a5a26 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c b8f7174e5f8c33c44ded3a25a973d0bb89228c20 -F src/rowset.c 9fe4b3ad7cc00944386bb600233d8f523de07a6e +F src/rowset.c d68d95e167cb234f51d655c9546f46752c9f6d45 F src/select.c fd4a7ce2937497181063cfedb92058ac89491a5d F src/shell.c 14ff7f660530a52b117d110ba3390b7b2eb719b6 F src/sqlite.h.in 9984129d86243424b765fcb3f147c697bd20bb54 @@ -1484,7 +1484,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P fcf85bfe50b254e825ee63a4cd0aa0b333b06eed -R 197c644a6cd9b0806f84f77482d9fe15 +P 33e627472780b872716c504f2d585cc057c390a5 +R a33e3686da943dcb038124577baa15b4 U drh -Z 413f6650964e5d2ab342130728703294 +Z bac1d4beccda46e9aa1657c47d678425 diff --git a/manifest.uuid b/manifest.uuid index abe023c752..976aebefbd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -33e627472780b872716c504f2d585cc057c390a5 \ No newline at end of file +5748e64376c1c2be5154a632d1527cfebbb9ec74 \ No newline at end of file diff --git a/src/rowset.c b/src/rowset.c index c2e73ed72e..65fcdb2318 100644 --- a/src/rowset.c +++ b/src/rowset.c @@ -338,20 +338,23 @@ static struct RowSetEntry *rowSetNDeepTree( if( *ppList==0 ){ return 0; } - if( iDepth==1 ){ + if( iDepth>1 ){ /*OPTIMIZATION-IF-TRUE*/ + /* This branch cases a *balanced* tree to be generated. A valid tree + ** is still generated without this branch, but it is wildly unbalanced + ** and inefficient. */ + pLeft = rowSetNDeepTree(ppList, iDepth-1); + p = *ppList; + if( p==0 ){ + return pLeft; + } + p->pLeft = pLeft; + *ppList = p->pRight; + p->pRight = rowSetNDeepTree(ppList, iDepth-1); + }else{ p = *ppList; *ppList = p->pRight; p->pLeft = p->pRight = 0; - return p; } - pLeft = rowSetNDeepTree(ppList, iDepth-1); - p = *ppList; - if( p==0 ){ - return pLeft; - } - p->pLeft = pLeft; - *ppList = p->pRight; - p->pRight = rowSetNDeepTree(ppList, iDepth-1); return p; } From 2075fb08e66d6b21c471d9bbdd88773007342543 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Thu, 28 Apr 2016 19:23:10 +0000 Subject: [PATCH 0360/1484] Fix typo in comment. No changes to code. FossilOrigin-Name: 9f6f17b5c97c9576c340173d068485fdbfd53253 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/rowset.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 0837962a87..c30368cd24 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Rearrange\ssome\scode\sin\sthe\sRowSet\slogic\sfor\sclarity\sof\spresentation,\swhile\nadding\san\s/*OPTIMIZATION-IF-TRUE*/\scomment.\s\sIt\sshould\soperate\sidentically. -D 2016-04-28T18:53:08.454 +C Fix\stypo\sin\scomment.\s\sNo\schanges\sto\scode. +D 2016-04-28T19:23:10.406 F Makefile.in 9e816d0323e418fbc0f8b2c05fc14e0b3763d9e8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -376,7 +376,7 @@ F src/prepare.c 22df6171aec1d86904ed2ad30c2348a5748aa04e F src/printf.c 63e6fb12bbe702dd664dc3703776c090383a5a26 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c b8f7174e5f8c33c44ded3a25a973d0bb89228c20 -F src/rowset.c d68d95e167cb234f51d655c9546f46752c9f6d45 +F src/rowset.c 156cb68c126b50222f16e7bab4d31ef03866c7e3 F src/select.c fd4a7ce2937497181063cfedb92058ac89491a5d F src/shell.c 14ff7f660530a52b117d110ba3390b7b2eb719b6 F src/sqlite.h.in 9984129d86243424b765fcb3f147c697bd20bb54 @@ -1484,7 +1484,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 33e627472780b872716c504f2d585cc057c390a5 -R a33e3686da943dcb038124577baa15b4 -U drh -Z bac1d4beccda46e9aa1657c47d678425 +P 5748e64376c1c2be5154a632d1527cfebbb9ec74 +R 14e25db2c4fe1efcd0c8b2319d192798 +U mistachkin +Z 0a6ff0ee2ee8b77d1f440385eb5ab0b6 diff --git a/manifest.uuid b/manifest.uuid index 976aebefbd..a3d1de6609 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5748e64376c1c2be5154a632d1527cfebbb9ec74 \ No newline at end of file +9f6f17b5c97c9576c340173d068485fdbfd53253 \ No newline at end of file diff --git a/src/rowset.c b/src/rowset.c index 65fcdb2318..bf4382ddd8 100644 --- a/src/rowset.c +++ b/src/rowset.c @@ -339,7 +339,7 @@ static struct RowSetEntry *rowSetNDeepTree( return 0; } if( iDepth>1 ){ /*OPTIMIZATION-IF-TRUE*/ - /* This branch cases a *balanced* tree to be generated. A valid tree + /* This branch causes a *balanced* tree to be generated. A valid tree ** is still generated without this branch, but it is wildly unbalanced ** and inefficient. */ pLeft = rowSetNDeepTree(ppList, iDepth-1); From 396794f0ee581d61d213e9bec23ef6b53e0516b5 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 28 Apr 2016 20:11:12 +0000 Subject: [PATCH 0361/1484] Comment changes only: Add several optimization marks in rowset.c. Add a header comment that explains what the various special comments mean. FossilOrigin-Name: 8cdbe89ac6c22d632f677eb293111b3dbae7d6c1 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/rowset.c | 21 ++++++++++++++------- src/sqliteInt.h | 27 +++++++++++++++++++++++++++ 4 files changed, 50 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index c30368cd24..4e21e75b83 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\stypo\sin\scomment.\s\sNo\schanges\sto\scode. -D 2016-04-28T19:23:10.406 +C Comment\schanges\sonly:\s\sAdd\sseveral\soptimization\smarks\sin\srowset.c.\s\sAdd\na\sheader\scomment\sthat\sexplains\swhat\sthe\svarious\sspecial\scomments\smean. +D 2016-04-28T20:11:12.680 F Makefile.in 9e816d0323e418fbc0f8b2c05fc14e0b3763d9e8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -376,13 +376,13 @@ F src/prepare.c 22df6171aec1d86904ed2ad30c2348a5748aa04e F src/printf.c 63e6fb12bbe702dd664dc3703776c090383a5a26 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c b8f7174e5f8c33c44ded3a25a973d0bb89228c20 -F src/rowset.c 156cb68c126b50222f16e7bab4d31ef03866c7e3 +F src/rowset.c fb413e336e765481e4d8368377c444904cecdf32 F src/select.c fd4a7ce2937497181063cfedb92058ac89491a5d F src/shell.c 14ff7f660530a52b117d110ba3390b7b2eb719b6 F src/sqlite.h.in 9984129d86243424b765fcb3f147c697bd20bb54 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 98f72cbfe00169c39089115427d06ea05fe4b4a2 -F src/sqliteInt.h ec538389481a3d093f07fb344c5a9dc988042304 +F src/sqliteInt.h f4a53f3547dab80dc7db975fa1192d9bad1f38e8 F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 @@ -1484,7 +1484,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 5748e64376c1c2be5154a632d1527cfebbb9ec74 -R 14e25db2c4fe1efcd0c8b2319d192798 -U mistachkin -Z 0a6ff0ee2ee8b77d1f440385eb5ab0b6 +P 9f6f17b5c97c9576c340173d068485fdbfd53253 +R 868dfe1770715db047dd242154ff598b +U drh +Z b6de1d1adc478f4213336a399ac69fc9 diff --git a/manifest.uuid b/manifest.uuid index a3d1de6609..7cd7864f7b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9f6f17b5c97c9576c340173d068485fdbfd53253 \ No newline at end of file +8cdbe89ac6c22d632f677eb293111b3dbae7d6c1 \ No newline at end of file diff --git a/src/rowset.c b/src/rowset.c index bf4382ddd8..5420ab991c 100644 --- a/src/rowset.c +++ b/src/rowset.c @@ -179,7 +179,9 @@ void sqlite3RowSetClear(RowSet *p){ */ static struct RowSetEntry *rowSetEntryAlloc(RowSet *p){ assert( p!=0 ); - if( p->nFresh==0 ){ + if( p->nFresh==0 ){ /*OPTIMIZATION-IF-FALSE*/ + /* We could allocate a fresh RowSetEntry each time one is needed, but it + ** is more efficient to pull a preallocated entry from the pool */ struct RowSetChunk *pNew; pNew = sqlite3DbMallocRawNN(p->db, sizeof(*pNew)); if( pNew==0 ){ @@ -213,7 +215,9 @@ void sqlite3RowSetInsert(RowSet *p, i64 rowid){ pEntry->pRight = 0; pLast = p->pLast; if( pLast ){ - if( (p->rsFlags & ROWSET_SORTED)!=0 && rowid<=pLast->v ){ + if( rowid<=pLast->v ){ /*OPTIMIZATION-IF-FALSE*/ + /* Avoid unnecessary sorts by preserving the ROWSET_SORTED flags + ** where possible */ p->rsFlags &= ~ROWSET_SORTED; } pLast->pRight = pEntry; @@ -335,16 +339,19 @@ static struct RowSetEntry *rowSetNDeepTree( ){ struct RowSetEntry *p; /* Root of the new tree */ struct RowSetEntry *pLeft; /* Left subtree */ - if( *ppList==0 ){ - return 0; + if( *ppList==0 ){ /*OPTIMIZATION-IF-TRUE*/ + /* Prevent unnecessary deep recursion when we run out of entries */ + return 0; } if( iDepth>1 ){ /*OPTIMIZATION-IF-TRUE*/ /* This branch causes a *balanced* tree to be generated. A valid tree - ** is still generated without this branch, but it is wildly unbalanced - ** and inefficient. */ + ** is still generated without this branch, but the tree is wildly + ** unbalanced and inefficient. */ pLeft = rowSetNDeepTree(ppList, iDepth-1); p = *ppList; - if( p==0 ){ + if( p==0 ){ /*OPTIMIZATION-IF-FALSE*/ + /* It is safe to always return here, but the resulting tree + ** would be unbalanced */ return pLeft; } p->pLeft = pLeft; diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 7bb15d0bf5..76bf809624 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -15,6 +15,33 @@ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ +/* Special Comments: +** +** Some comments have special meaning to the tools that measure test +** coverage: +** +** NO_TEST - The branches on this line are not +** measured by branch coverage. This is +** used on lines of code that actually +** implement parts of coverage testing. +** +** OPTIMIZATION-IF-TRUE - This branch is allowed to alway be false +** and the correct answer is still obtained, +** though perhaps more slowly. +** +** OPTIMIZATION-IF-FALSE - This branch is allowed to alway be true +** and the correct answer is still obtained, +** though perhaps more slowly. +** +** PREVENTS-HARMLESS-OVERREAD - This branch prevents a buffer overread +** that would be harmless and undetectable +** if it did occur. +** +** In all cases, the special comment must be enclosed in the usual +** slash-asterisk...asterisk-slash comment marks, with no spaces between the +** asterisks and the comment text. +*/ + /* ** Make sure that rand_s() is available on Windows systems with MSVC 2005 ** or higher. From aa50271a2432fb6a85c1f42b39317500c7cda950 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 28 Apr 2016 22:29:31 +0000 Subject: [PATCH 0362/1484] Further simplifications and improved commentting on the rowset.c module, including several optimization comments. FossilOrigin-Name: 9f15a520deb9f1d4ecaa3bfff82bd57ef122aadb --- manifest | 12 +++++----- manifest.uuid | 2 +- src/rowset.c | 65 ++++++++++++++++++--------------------------------- 3 files changed, 30 insertions(+), 49 deletions(-) diff --git a/manifest b/manifest index 4e21e75b83..4d312042a1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Comment\schanges\sonly:\s\sAdd\sseveral\soptimization\smarks\sin\srowset.c.\s\sAdd\na\sheader\scomment\sthat\sexplains\swhat\sthe\svarious\sspecial\scomments\smean. -D 2016-04-28T20:11:12.680 +C Further\ssimplifications\sand\simproved\scommentting\son\sthe\srowset.c\smodule,\nincluding\sseveral\soptimization\scomments. +D 2016-04-28T22:29:31.056 F Makefile.in 9e816d0323e418fbc0f8b2c05fc14e0b3763d9e8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -376,7 +376,7 @@ F src/prepare.c 22df6171aec1d86904ed2ad30c2348a5748aa04e F src/printf.c 63e6fb12bbe702dd664dc3703776c090383a5a26 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c b8f7174e5f8c33c44ded3a25a973d0bb89228c20 -F src/rowset.c fb413e336e765481e4d8368377c444904cecdf32 +F src/rowset.c 49eb91c588a2bab36647368e031dc5b66928149d F src/select.c fd4a7ce2937497181063cfedb92058ac89491a5d F src/shell.c 14ff7f660530a52b117d110ba3390b7b2eb719b6 F src/sqlite.h.in 9984129d86243424b765fcb3f147c697bd20bb54 @@ -1484,7 +1484,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 9f6f17b5c97c9576c340173d068485fdbfd53253 -R 868dfe1770715db047dd242154ff598b +P 8cdbe89ac6c22d632f677eb293111b3dbae7d6c1 +R 9629e5ecfb28b4deca7492eeb801c3d3 U drh -Z b6de1d1adc478f4213336a399ac69fc9 +Z f98c64d26c6e12bfaaf00c7f14039634 diff --git a/manifest.uuid b/manifest.uuid index 7cd7864f7b..fd604e04b3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8cdbe89ac6c22d632f677eb293111b3dbae7d6c1 \ No newline at end of file +9f15a520deb9f1d4ecaa3bfff82bd57ef122aadb \ No newline at end of file diff --git a/src/rowset.c b/src/rowset.c index 5420ab991c..a70264ed1b 100644 --- a/src/rowset.c +++ b/src/rowset.c @@ -57,8 +57,9 @@ ** of the first SMALLEST is O(NlogN). Second and subsequent SMALLEST ** primitives are constant time. The cost of DESTROY is O(N). ** -** There is an added cost of O(N) when switching between TEST and -** SMALLEST primitives. +** TEST and SMALLEST may not be used by the same RowSet. This used to +** be possible, but the feature was not used, so it was removed in order +** to simplify the code. */ #include "sqliteInt.h" @@ -388,59 +389,37 @@ static struct RowSetEntry *rowSetListToTree(struct RowSetEntry *pList){ return p; } -/* -** Take all the entries on p->pEntry and on the trees in p->pForest and -** sort them all together into one big ordered list on p->pEntry. -** -** This routine should only be called once in the life of a RowSet. -*/ -static void rowSetToList(RowSet *p){ - - /* This routine is called only once */ - assert( p!=0 && (p->rsFlags & ROWSET_NEXT)==0 ); - - if( (p->rsFlags & ROWSET_SORTED)==0 ){ - p->pEntry = rowSetEntrySort(p->pEntry); - } - - /* While this module could theoretically support it, sqlite3RowSetNext() - ** is never called after sqlite3RowSetText() for the same RowSet. So - ** there is never a forest to deal with. Should this change, simply - ** remove the assert() and the #if 0. */ - assert( p->pForest==0 ); -#if 0 - while( p->pForest ){ - struct RowSetEntry *pTree = p->pForest->pLeft; - if( pTree ){ - struct RowSetEntry *pHead, *pTail; - rowSetTreeToList(pTree, &pHead, &pTail); - p->pEntry = rowSetEntryMerge(p->pEntry, pHead); - } - p->pForest = p->pForest->pRight; - } -#endif - p->rsFlags |= ROWSET_NEXT; /* Verify this routine is never called again */ -} - /* ** Extract the smallest element from the RowSet. ** Write the element into *pRowid. Return 1 on success. Return ** 0 if the RowSet is already empty. ** ** After this routine has been called, the sqlite3RowSetInsert() -** routine may not be called again. +** routine may not be called again. +** +** This routine may not be called after sqlite3RowSetTest() has +** been used. Older versions of RowSet allowed that, but as the +** capability was not used by the code generator, it was removed +** for code economy. */ int sqlite3RowSetNext(RowSet *p, i64 *pRowid){ assert( p!=0 ); + assert( p->pForest==0 ); /* Cannot be used with sqlite3RowSetText() */ /* Merge the forest into a single sorted list on first call */ - if( (p->rsFlags & ROWSET_NEXT)==0 ) rowSetToList(p); + if( (p->rsFlags & ROWSET_NEXT)==0 ){ /*OPTIMIZATION-IF-FALSE*/ + if( (p->rsFlags & ROWSET_SORTED)==0 ){ /*OPTIMIZATION-IF-FALSE*/ + p->pEntry = rowSetEntrySort(p->pEntry); + } + p->rsFlags |= ROWSET_SORTED|ROWSET_NEXT; + } /* Return the next entry on the list */ if( p->pEntry ){ *pRowid = p->pEntry->v; p->pEntry = p->pEntry->pRight; - if( p->pEntry==0 ){ + if( p->pEntry==0 ){ /*OPTIMIZATION-IF-TRUE*/ + /* Free memory immediately, rather than waiting on sqlite3_finalize() */ sqlite3RowSetClear(p); } return 1; @@ -463,13 +442,15 @@ int sqlite3RowSetTest(RowSet *pRowSet, int iBatch, sqlite3_int64 iRowid){ /* This routine is never called after sqlite3RowSetNext() */ assert( pRowSet!=0 && (pRowSet->rsFlags & ROWSET_NEXT)==0 ); - /* Sort entries into the forest on the first test of a new batch + /* Sort entries into the forest on the first test of a new batch. + ** To save unnecessary work, only do this when the batch number changes. */ - if( iBatch!=pRowSet->iBatch ){ + if( iBatch!=pRowSet->iBatch ){ /*OPTIMIZATION-IF-FALSE*/ p = pRowSet->pEntry; if( p ){ struct RowSetEntry **ppPrevTree = &pRowSet->pForest; - if( (pRowSet->rsFlags & ROWSET_SORTED)==0 ){ + if( (pRowSet->rsFlags & ROWSET_SORTED)==0 ){ /*OPTIMIZATION-IF-FALSE*/ + /* Only sort the current set of entiries if they need it */ p = rowSetEntrySort(p); } for(pTree = pRowSet->pForest; pTree; pTree=pTree->pRight){ From a3fa140fb46e74cb86cd1b44905842efd03c9c5e Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 29 Apr 2016 02:55:05 +0000 Subject: [PATCH 0363/1484] Some optimization comments added to vdbe.c. No functional changes to code. FossilOrigin-Name: e7c22e3bffce63f3b47fa3683be8c00c42b2a7d3 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 17 ++++++++++------- 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index 4d312042a1..da4cac8196 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Further\ssimplifications\sand\simproved\scommentting\son\sthe\srowset.c\smodule,\nincluding\sseveral\soptimization\scomments. -D 2016-04-28T22:29:31.056 +C Some\soptimization\scomments\sadded\sto\svdbe.c.\s\sNo\sfunctional\schanges\sto\scode. +D 2016-04-29T02:55:05.603 F Makefile.in 9e816d0323e418fbc0f8b2c05fc14e0b3763d9e8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -443,7 +443,7 @@ F src/update.c 3e67ab3c0814635f355fb1f8ab010a2b9e016e7d F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 810ec3f22e2d1b62e66c30fe3621ebdedd23584d F src/vacuum.c feb1eabb20987983d9350cad98299b21fa811f52 -F src/vdbe.c d3843a66d74a7696477ee5141e5eb9a7e5e2401c +F src/vdbe.c 08fbea00a7f7f723973093c5f5bf7c40c025e2b3 F src/vdbe.h 5591b5add447096e31288b5a0a78ec5d7b5c5170 F src/vdbeInt.h ddb157974436d87652de7dc641f7191496d9a8cd F src/vdbeapi.c ba85b78fe08dc4a9ce747e62c89a2b4a4547e74c @@ -1484,7 +1484,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 8cdbe89ac6c22d632f677eb293111b3dbae7d6c1 -R 9629e5ecfb28b4deca7492eeb801c3d3 +P 9f15a520deb9f1d4ecaa3bfff82bd57ef122aadb +R 9e8b60c02f680bebef2b9615706e75d6 U drh -Z f98c64d26c6e12bfaaf00c7f14039634 +Z f25847a4d8f7c8c164def037ab0b4e49 diff --git a/manifest.uuid b/manifest.uuid index fd604e04b3..74550e35d8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9f15a520deb9f1d4ecaa3bfff82bd57ef122aadb \ No newline at end of file +e7c22e3bffce63f3b47fa3683be8c00c42b2a7d3 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 244a4ad063..5fba14a5c3 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -215,7 +215,7 @@ static VdbeCursor *allocateCursor( (eCurType==CURTYPE_BTREE?sqlite3BtreeCursorSize():0); assert( iCur>=0 && iCurnCursor ); - if( p->apCsr[iCur] ){ + if( p->apCsr[iCur] ){ /*OPTIMIZATION-IF-FALSE*/ sqlite3VdbeFreeCursor(p, p->apCsr[iCur]); p->apCsr[iCur] = 0; } @@ -292,7 +292,7 @@ static void applyAffinity( if( affinity>=SQLITE_AFF_NUMERIC ){ assert( affinity==SQLITE_AFF_INTEGER || affinity==SQLITE_AFF_REAL || affinity==SQLITE_AFF_NUMERIC ); - if( (pRec->flags & MEM_Int)==0 ){ + if( (pRec->flags & MEM_Int)==0 ){ /*OPTIMIZATION-IF-FALSE*/ if( (pRec->flags & MEM_Real)==0 ){ if( pRec->flags & MEM_Str ) applyNumericAffinity(pRec,1); }else{ @@ -302,10 +302,13 @@ static void applyAffinity( }else if( affinity==SQLITE_AFF_TEXT ){ /* Only attempt the conversion to TEXT if there is an integer or real ** representation (blob and NULL do not get converted) but no string - ** representation. - */ - if( 0==(pRec->flags&MEM_Str) && (pRec->flags&(MEM_Real|MEM_Int)) ){ - sqlite3VdbeMemStringify(pRec, enc, 1); + ** representation. It would be harmless to repeat the conversion if + ** there is already a string rep, but it is pointless to waste those + ** CPU cycles. */ + if( 0==(pRec->flags&MEM_Str) ){ /*OPTIMIZATION-IF-FALSE*/ + if( (pRec->flags&(MEM_Real|MEM_Int)) ){ + sqlite3VdbeMemStringify(pRec, enc, 1); + } } pRec->flags &= ~(MEM_Real|MEM_Int); } @@ -542,7 +545,7 @@ static Mem *out2Prerelease(Vdbe *p, VdbeOp *pOp){ assert( pOp->p2<=(p->nMem+1 - p->nCursor) ); pOut = &p->aMem[pOp->p2]; memAboutToChange(p, pOut); - if( VdbeMemDynamic(pOut) ){ + if( VdbeMemDynamic(pOut) ){ /*OPTIMIZATION-IF-FALSE*/ return out2PrereleaseWithClear(pOut); }else{ pOut->flags = MEM_Int; From 14faa061fd4815f6f8f63bc4d00889b676c85c20 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 29 Apr 2016 10:13:22 +0000 Subject: [PATCH 0364/1484] Fix an almost entirely harmless buffer overread in the sessions module. FossilOrigin-Name: 89b0ee3351381f7bc666cb206f77a56f2e0d4a0e --- ext/session/sqlite3session.c | 17 +++++++++++------ manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 18 insertions(+), 13 deletions(-) diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index b058d357e2..e333dffcc7 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -592,14 +592,19 @@ static int sessionChangeEqual( int iCol; /* Used to iterate through table columns */ for(iCol=0; iColnCol; iCol++){ - int n1 = sessionSerialLen(a1); - int n2 = sessionSerialLen(a2); + if( pTab->abPK[iCol] ){ + int n1 = sessionSerialLen(a1); + int n2 = sessionSerialLen(a2); - if( pTab->abPK[iCol] && (n1!=n2 || memcmp(a1, a2, n1)) ){ - return 0; + if( pTab->abPK[iCol] && (n1!=n2 || memcmp(a1, a2, n1)) ){ + return 0; + } + a1 += n1; + a2 += n2; + }else{ + if( bLeftPkOnly==0 ) a1 += sessionSerialLen(a1); + if( bRightPkOnly==0 ) a2 += sessionSerialLen(a2); } - if( pTab->abPK[iCol] || bLeftPkOnly==0 ) a1 += n1; - if( pTab->abPK[iCol] || bRightPkOnly==0 ) a2 += n2; } return 1; diff --git a/manifest b/manifest index 61077e7077..77d5df7f09 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\slatest\schanges\sfrom\strunk\swith\sthis\sbranch. -D 2016-04-28T14:59:05.489 +C Fix\san\salmost\sentirely\sharmless\sbuffer\soverread\sin\sthe\ssessions\smodule. +D 2016-04-29T10:13:22.999 F Makefile.in 9e816d0323e418fbc0f8b2c05fc14e0b3763d9e8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -293,7 +293,7 @@ F ext/session/sessionG.test 01ef705096a9d3984eebdcca79807a211dee1b60 F ext/session/session_common.tcl a1293167d14774b5e728836720497f40fe4ea596 F ext/session/sessionfault.test da273f2712b6411e85e71465a1733b8501dbf6f7 F ext/session/sessionfault2.test 04aa0bc9aa70ea43d8de82c4f648db4de1e990b0 -F ext/session/sqlite3session.c beb300cd1b5c5054062c8e6e807b10475e363410 +F ext/session/sqlite3session.c beb43b6b888801bb006320bc236baa95f4cc32ae F ext/session/sqlite3session.h 64e9e7f185725ef43b97f4a9a0c0df0669844f1d F ext/session/test_session.c 464f2c8bf502795d95969387eb8e93f68c513c15 F ext/userauth/sqlite3userauth.h 19cb6f0e31316d0ee4afdfb7a85ef9da3333a220 @@ -1484,7 +1484,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 5973d3bf2e5aa979ccc9a4a3a0eb08b67098b499 33e627472780b872716c504f2d585cc057c390a5 -R 66281bc4e8738b7ab348496eadeeb2b1 +P 45467ee49872f495d5276cf830f10c3cf4ac8e3c +R 50a6a2b7911c16c6704703bf8b17ce71 U dan -Z 4d2c4cbb1442cfb28a5ae33052756c7a +Z da972510c8d8b75cf481b4f80618fa01 diff --git a/manifest.uuid b/manifest.uuid index b1984ea171..f4d85f9254 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -45467ee49872f495d5276cf830f10c3cf4ac8e3c \ No newline at end of file +89b0ee3351381f7bc666cb206f77a56f2e0d4a0e \ No newline at end of file From afb8cd977d09759a29b6c89d3882e431fb86a480 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 29 Apr 2016 11:28:35 +0000 Subject: [PATCH 0365/1484] Lemon bug fix: Do not merge action routines unless their destructors are also identical. Problem and suggested fix reported on the mailing list by Kelvin Sherlock. FossilOrigin-Name: 4792d6dbba6857f74d27332dcc1468e39c767c71 --- manifest | 12 ++++++------ manifest.uuid | 2 +- tool/lemon.c | 3 ++- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index da4cac8196..df4dd75c55 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Some\soptimization\scomments\sadded\sto\svdbe.c.\s\sNo\sfunctional\schanges\sto\scode. -D 2016-04-29T02:55:05.603 +C Lemon\sbug\sfix:\s\sDo\snot\smerge\saction\sroutines\sunless\stheir\sdestructors\sare\nalso\sidentical.\s\sProblem\sand\ssuggested\sfix\sreported\son\sthe\smailing\slist\nby\sKelvin\sSherlock. +D 2016-04-29T11:28:35.306 F Makefile.in 9e816d0323e418fbc0f8b2c05fc14e0b3763d9e8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -1414,7 +1414,7 @@ F tool/fuzzershell.c 94019b185caceffc9f7c7b678a6489e42bc2aefa F tool/genfkey.README cf68fddd4643bbe3ff8e31b8b6d8b0a1b85e20f4 F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5 F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce -F tool/lemon.c cfbfe061a4b2766512f6b484882eee2c86a14506 +F tool/lemon.c 83318dff3911e47f2b85e136e56aa1c4674a2d2b F tool/lempar.c 404ea3dc27dbeed343f0e61b1d36e97b9f5f0fb6 F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862 F tool/logest.c 11346aa019e2e77a00902aa7d0cabd27bd2e8cca @@ -1484,7 +1484,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 9f15a520deb9f1d4ecaa3bfff82bd57ef122aadb -R 9e8b60c02f680bebef2b9615706e75d6 +P e7c22e3bffce63f3b47fa3683be8c00c42b2a7d3 +R 2a18b1b7e68842336a01e91672c4d16e U drh -Z f25847a4d8f7c8c164def037ab0b4e49 +Z 9e05af624d486885b70c45e730afddce diff --git a/manifest.uuid b/manifest.uuid index 74550e35d8..d7daf8acb8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e7c22e3bffce63f3b47fa3683be8c00c42b2a7d3 \ No newline at end of file +4792d6dbba6857f74d27332dcc1468e39c767c71 \ No newline at end of file diff --git a/tool/lemon.c b/tool/lemon.c index 903fe97cfb..2f76465d89 100644 --- a/tool/lemon.c +++ b/tool/lemon.c @@ -4402,7 +4402,8 @@ void ReportTable( writeRuleText(out, rp); fprintf(out, " */\n"); lineno++; for(rp2=rp->next; rp2; rp2=rp2->next){ - if( rp2->code==rp->code ){ + if( rp2->code==rp->code && rp2->codePrefix==rp->codePrefix + && rp2->codeSuffix==rp->codeSuffix ){ fprintf(out," case %d: /* ", rp2->iRule); writeRuleText(out, rp2); fprintf(out," */ yytestcase(yyruleno==%d);\n", rp2->iRule); lineno++; From 4a030c643070a939ef2b3f86b56b64a38693868d Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 29 Apr 2016 14:12:48 +0000 Subject: [PATCH 0366/1484] Fix test script temptable2.test so that it works with the "inmemory_journal" and "journaltest" permutations. FossilOrigin-Name: b7bec7f2d3d08d0c14f77654be2c5cedf1619e58 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/temptable2.test | 21 +++++++++++++-------- 3 files changed, 20 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index c04f4869ed..1a928a99b5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\slatest\strunk\schanges,\sincluding\stest\scase\sfixes,\swith\sthis\sbranch. -D 2016-04-29T11:35:28.485 +C Fix\stest\sscript\stemptable2.test\sso\sthat\sit\sworks\swith\sthe\s"inmemory_journal"\sand\s"journaltest"\spermutations. +D 2016-04-29T14:12:48.901 F Makefile.in 9e816d0323e418fbc0f8b2c05fc14e0b3763d9e8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -1113,7 +1113,7 @@ F test/tclsqlite.test e1306001a0ca92250b691ea6d3cecaca5b6342aa F test/tempdb.test bd92eba8f20e16a9136e434e20b280794de3cdb6 F test/tempfault.test 0c0d349c9a99bf5f374655742577f8712c647900 F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30 -F test/temptable2.test d4e967c355b154e8bc387de961430e94c20f2dca +F test/temptable2.test c3d8c138f493207612960bbd6a8c50e84975e2ee F test/temptrigger.test 8ec228b0db5d7ebc4ee9b458fc28cb9e7873f5e1 F test/tester.tcl 30c7a9be8601d1c1c9c93d013545ebcb28d64254 F test/thread001.test 9f22fd3525a307ff42a326b6bc7b0465be1745a5 @@ -1486,7 +1486,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 6bb5aa2be2a6c5ca66a98a9387b2845507a6bdd2 4cbd50245440e714935399a5c285cf32d8bfc424 -R 7ae3c477f36afa854d04f85029639199 +P 99794aca7b6cb40f08ce4db9889a989fc597eac9 +R f9ef4e1af8653e902d9192ffb04cabc2 U dan -Z 1ae9b89d9de363b516966d4d50de5d49 +Z 5d059cb204727917e4a7564cbd5ed599 diff --git a/manifest.uuid b/manifest.uuid index e7c3b7b953..db83d58f1b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -99794aca7b6cb40f08ce4db9889a989fc597eac9 \ No newline at end of file +b7bec7f2d3d08d0c14f77654be2c5cedf1619e58 \ No newline at end of file diff --git a/test/temptable2.test b/test/temptable2.test index 21e06a3a4f..890b3b996d 100644 --- a/test/temptable2.test +++ b/test/temptable2.test @@ -139,9 +139,11 @@ do_execsql_test 5.1.1 { INSERT INTO t1 VALUES(1, 2); } +# Test that the temp database is now much bigger than the configured +# cache size (10 pages). do_test 5.1.2 { set n [db one { PRAGMA temp.page_count }] - expr ($n > 280 && $n < 290) + expr ($n > 270 && $n < 290) } {1} do_execsql_test 5.1.3 { @@ -284,9 +286,9 @@ foreach {tn mode} { PRAGMA cache_size = 15; PRAGMA auto_vacuum = 1; } - do_execsql_test 9.$tn.1.2 "PRAGMA journal_mode = $mode" delete + execsql "PRAGMA journal_mode = $mode" - do_execsql_test 9.$tn.1.3 { + do_execsql_test 9.$tn.1.2 { CREATE TABLE tx(a, b); CREATE INDEX i1 ON tx(a); CREATE INDEX i2 ON tx(b); @@ -341,11 +343,14 @@ do_execsql_test 10.1 { INSERT INTO t2 VALUES(3, 4); } -do_execsql_test 10.2 { - PRAGMA mmap_size = 512000; - SELECT * FROM t2; - PRAGMA integrity_check; -} {512000 1 2 3 4 ok} +if {[permutation]!="journaltest"} { + # The journaltest permutation does not support mmap, so this part of + # the test is omitted. + do_execsql_test 10.2 { PRAGMA mmap_size = 512000 } 512000 +} + +do_execsql_test 10.3 { SELECT * FROM t2 } {1 2 3 4} +do_execsql_test 10.4 { PRAGMA integrity_check } ok finish_test From 2aab11fa5a7eea97a0a7f2fcbbf2432b883c071a Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 29 Apr 2016 20:30:56 +0000 Subject: [PATCH 0367/1484] Fix the temporary directory search algorithm for unix so that it fails gracefully even if all candidate directories are inaccessible. This fixes a bug that was introduced by check-in [9b8fec60d8e]. FossilOrigin-Name: 614bb709d34e11488da88861243023cc5de4b409 --- manifest | 13 ++++++------- manifest.uuid | 2 +- src/os_unix.c | 18 +++++++++++------- 3 files changed, 18 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index 79ea0c73d4..1bc788b248 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Postpone\sI/O\sassociated\swith\sTEMP\sfiles\sfor\sas\slong\sas\spossible,\swith\sthe\nhope\sthat\sthe\sI/O\scan\sultimately\sbe\savoided\scompletely. -D 2016-04-29T15:39:48.423 +C Fix\sthe\stemporary\sdirectory\ssearch\salgorithm\sfor\sunix\sso\sthat\sit\sfails\ngracefully\seven\sif\sall\scandidate\sdirectories\sare\sinaccessible.\s\sThis\sfixes\na\sbug\sthat\swas\sintroduced\sby\scheck-in\s[9b8fec60d8e]. +D 2016-04-29T20:30:56.115 F Makefile.in 9e816d0323e418fbc0f8b2c05fc14e0b3763d9e8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -361,7 +361,7 @@ F src/os.c 4d83917f072ad958fba9235136fa2ed43df47905 F src/os.h 8e976e59eb4ca1c0fca6d35ee803e38951cb0343 F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85 F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa -F src/os_unix.c 8422fba2eb592fbbb2d4006b6f2a67cad8951495 +F src/os_unix.c a9443cdab41d7f3cdf0df3a5aab62fd6e1c9b234 F src/os_win.c 852fc2ff6084296348ed3739c548b2cf32df394e F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c a8d30c49c231e9a20d05257613db922532588963 @@ -1486,8 +1486,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 4cbd50245440e714935399a5c285cf32d8bfc424 b7bec7f2d3d08d0c14f77654be2c5cedf1619e58 -R f9ef4e1af8653e902d9192ffb04cabc2 -T +closed b7bec7f2d3d08d0c14f77654be2c5cedf1619e58 +P 9d0a5ae00273686ea35b43bc2ffaa8775c176363 +R a933a7d712b512086a1e3835745ceb3a U drh -Z 20681342134be4241c18925dab8e4f41 +Z 98ad5e2467f45a0f2dba904fa48c29d6 diff --git a/manifest.uuid b/manifest.uuid index fc6b7bfe05..d973fd4f41 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9d0a5ae00273686ea35b43bc2ffaa8775c176363 \ No newline at end of file +614bb709d34e11488da88861243023cc5de4b409 \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index 01de00e0dd..f5b01e9958 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -5412,18 +5412,22 @@ static const char *unixTempFileDir(void){ "/tmp", "." }; - unsigned int i; + unsigned int i = 0; struct stat buf; const char *zDir = sqlite3_temp_directory; if( !azDirs[0] ) azDirs[0] = getenv("SQLITE_TMPDIR"); if( !azDirs[1] ) azDirs[1] = getenv("TMPDIR"); - for(i=0; i<=sizeof(azDirs)/sizeof(azDirs[0]); zDir=azDirs[i++]){ - if( zDir==0 ) continue; - if( osStat(zDir, &buf) ) continue; - if( !S_ISDIR(buf.st_mode) ) continue; - if( osAccess(zDir, 03) ) continue; - return zDir; + while(1){ + if( zDir!=0 + && osStat(zDir, &buf)==0 + && S_ISDIR(buf.st_mode) + && osAccess(zDir, 03)==0 + ){ + return zDir; + } + if( i>=sizeof(azDirs)/sizeof(azDirs[0]) ) break; + zDir = azDirs[i++]; } return 0; } From 99f5de771faee5c3bcf2ab8758e821220edf4867 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 30 Apr 2016 02:59:15 +0000 Subject: [PATCH 0368/1484] Simplifications to the OP_Halt opcode implementation. FossilOrigin-Name: daf4630f96f13133664908045e279da9d5a40bb5 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 22 +++++++--------------- 3 files changed, 14 insertions(+), 22 deletions(-) diff --git a/manifest b/manifest index 1bc788b248..c3be714871 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\stemporary\sdirectory\ssearch\salgorithm\sfor\sunix\sso\sthat\sit\sfails\ngracefully\seven\sif\sall\scandidate\sdirectories\sare\sinaccessible.\s\sThis\sfixes\na\sbug\sthat\swas\sintroduced\sby\scheck-in\s[9b8fec60d8e]. -D 2016-04-29T20:30:56.115 +C Simplifications\sto\sthe\sOP_Halt\sopcode\simplementation. +D 2016-04-30T02:59:15.737 F Makefile.in 9e816d0323e418fbc0f8b2c05fc14e0b3763d9e8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -443,7 +443,7 @@ F src/update.c 3e67ab3c0814635f355fb1f8ab010a2b9e016e7d F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 810ec3f22e2d1b62e66c30fe3621ebdedd23584d F src/vacuum.c feb1eabb20987983d9350cad98299b21fa811f52 -F src/vdbe.c 08fbea00a7f7f723973093c5f5bf7c40c025e2b3 +F src/vdbe.c b2067cd06a0f30a6dea865f93c690df15e0314a8 F src/vdbe.h 5591b5add447096e31288b5a0a78ec5d7b5c5170 F src/vdbeInt.h ddb157974436d87652de7dc641f7191496d9a8cd F src/vdbeapi.c ba85b78fe08dc4a9ce747e62c89a2b4a4547e74c @@ -1486,7 +1486,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 9d0a5ae00273686ea35b43bc2ffaa8775c176363 -R a933a7d712b512086a1e3835745ceb3a +P 614bb709d34e11488da88861243023cc5de4b409 +R b15a9da5ab52f0ada1f3249ae1287c3e U drh -Z 98ad5e2467f45a0f2dba904fa48c29d6 +Z 574106fd28e4252d413254df9dee5be2 diff --git a/manifest.uuid b/manifest.uuid index d973fd4f41..5bb7f4d874 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -614bb709d34e11488da88861243023cc5de4b409 \ No newline at end of file +daf4630f96f13133664908045e279da9d5a40bb5 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 5fba14a5c3..cb977e0854 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -949,8 +949,6 @@ case OP_HaltIfNull: { /* in3 */ ** is the same as executing Halt. */ case OP_Halt: { - const char *zType; - const char *zLogFmt; VdbeFrame *pFrame; int pcx; @@ -979,34 +977,28 @@ case OP_Halt: { p->rc = pOp->p1; p->errorAction = (u8)pOp->p2; p->pc = pcx; + assert( pOp->p5>=0 && pOp->p5<=4 ); if( p->rc ){ if( pOp->p5 ){ static const char * const azType[] = { "NOT NULL", "UNIQUE", "CHECK", "FOREIGN KEY" }; - assert( pOp->p5>=1 && pOp->p5<=4 ); testcase( pOp->p5==1 ); testcase( pOp->p5==2 ); testcase( pOp->p5==3 ); testcase( pOp->p5==4 ); - zType = azType[pOp->p5-1]; + sqlite3VdbeError(p, "%s constraint failed", azType[pOp->p5-1]); + if( pOp->p4.z ){ + p->zErrMsg = sqlite3MPrintf(db, "%z: %s", p->zErrMsg, pOp->p4.z); + } }else{ - zType = 0; - } - assert( zType!=0 || pOp->p4.z!=0 ); - zLogFmt = "abort at %d in [%s]: %s"; - if( zType && pOp->p4.z ){ - sqlite3VdbeError(p, "%s constraint failed: %s", zType, pOp->p4.z); - }else if( pOp->p4.z ){ sqlite3VdbeError(p, "%s", pOp->p4.z); - }else{ - sqlite3VdbeError(p, "%s constraint failed", zType); } - sqlite3_log(pOp->p1, zLogFmt, pcx, p->zSql, p->zErrMsg); + sqlite3_log(pOp->p1, "abort at %d in [%s]: %s", pcx, p->zSql, p->zErrMsg); } rc = sqlite3VdbeHalt(p); assert( rc==SQLITE_BUSY || rc==SQLITE_OK || rc==SQLITE_ERROR ); if( rc==SQLITE_BUSY ){ - p->rc = rc = SQLITE_BUSY; + p->rc = SQLITE_BUSY; }else{ assert( rc==SQLITE_OK || (p->rc&0xff)==SQLITE_CONSTRAINT ); assert( rc==SQLITE_OK || db->nDeferredCons>0 || db->nDeferredImmCons>0 ); From 2e55b04da45c2fb17a0464f0480af33082c23810 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 30 Apr 2016 17:19:30 +0000 Subject: [PATCH 0369/1484] More bug fixes to Lemon identified by Kelvin Sherlock. None of these have any impact on SQLite. FossilOrigin-Name: 762bdc55f8878ee2ef65af2165a8e7fdbddf0160 --- manifest | 12 ++++++------ manifest.uuid | 2 +- tool/lemon.c | 23 ++++++++++++++++------- 3 files changed, 23 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index c3be714871..c82cd48e76 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Simplifications\sto\sthe\sOP_Halt\sopcode\simplementation. -D 2016-04-30T02:59:15.737 +C More\sbug\sfixes\sto\sLemon\sidentified\sby\sKelvin\sSherlock.\s\sNone\sof\sthese\nhave\sany\simpact\son\sSQLite. +D 2016-04-30T17:19:30.162 F Makefile.in 9e816d0323e418fbc0f8b2c05fc14e0b3763d9e8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -1416,7 +1416,7 @@ F tool/fuzzershell.c 94019b185caceffc9f7c7b678a6489e42bc2aefa F tool/genfkey.README cf68fddd4643bbe3ff8e31b8b6d8b0a1b85e20f4 F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5 F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce -F tool/lemon.c 83318dff3911e47f2b85e136e56aa1c4674a2d2b +F tool/lemon.c f38a55106d79b7a4c063abb958517d6c47dc6ac7 F tool/lempar.c 404ea3dc27dbeed343f0e61b1d36e97b9f5f0fb6 F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862 F tool/logest.c 11346aa019e2e77a00902aa7d0cabd27bd2e8cca @@ -1486,7 +1486,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 614bb709d34e11488da88861243023cc5de4b409 -R b15a9da5ab52f0ada1f3249ae1287c3e +P daf4630f96f13133664908045e279da9d5a40bb5 +R abf1ac3c7e03f177ba74945ccc38d922 U drh -Z 574106fd28e4252d413254df9dee5be2 +Z cfd7bc89828187e9540e8e1e6f984687 diff --git a/manifest.uuid b/manifest.uuid index 5bb7f4d874..03d710e202 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -daf4630f96f13133664908045e279da9d5a40bb5 \ No newline at end of file +762bdc55f8878ee2ef65af2165a8e7fdbddf0160 \ No newline at end of file diff --git a/tool/lemon.c b/tool/lemon.c index 2f76465d89..01c8a1da96 100644 --- a/tool/lemon.c +++ b/tool/lemon.c @@ -3556,14 +3556,11 @@ PRIVATE int translate_code(struct lemon *lemp, struct rule *rp){ } - if( rp->lhsalias==0 ){ - /* There is no LHS value symbol. */ - lhsdirect = 1; - }else if( rp->nrhs==0 ){ + if( rp->nrhs==0 ){ /* If there are no RHS symbols, then writing directly to the LHS is ok */ lhsdirect = 1; }else if( rp->rhsalias[0]==0 ){ - /* The left-most RHS symbol has not value. LHS direct is ok. But + /* The left-most RHS symbol has no value. LHS direct is ok. But ** we have to call the distructor on the RHS symbol first. */ lhsdirect = 1; if( has_destructor(rp->rhs[0],lemp) ){ @@ -3572,6 +3569,9 @@ PRIVATE int translate_code(struct lemon *lemp, struct rule *rp){ rp->rhs[0]->index,1-rp->nrhs); rp->codePrefix = Strsafe(append_str(0,0,0,0)); } + }else if( rp->lhsalias==0 ){ + /* There is no LHS value symbol. */ + lhsdirect = 1; }else if( strcmp(rp->lhsalias,rp->rhsalias[0])==0 ){ /* The LHS symbol and the left-most RHS symbol are the same, so ** direct writing is allowed */ @@ -3715,7 +3715,7 @@ PRIVATE int translate_code(struct lemon *lemp, struct rule *rp){ /* Suffix code generation complete */ cp = append_str(0,0,0,0); - if( cp ) rp->codeSuffix = Strsafe(cp); + if( cp && cp[0] ) rp->codeSuffix = Strsafe(cp); return rc; } @@ -4397,7 +4397,14 @@ void ReportTable( for(rp=lemp->rule; rp; rp=rp->next){ struct rule *rp2; /* Other rules with the same action */ if( rp->code==0 ) continue; - if( rp->code[0]=='\n' && rp->code[1]==0 ) continue; /* Will be default: */ + if( rp->code[0]=='\n' + && rp->code[1]==0 + && rp->codePrefix==0 + && rp->codeSuffix==0 + ){ + /* No actions, so this will be part of the "default:" rule */ + continue; + } fprintf(out," case %d: /* ", rp->iRule); writeRuleText(out, rp); fprintf(out, " */\n"); lineno++; @@ -4420,6 +4427,8 @@ void ReportTable( for(rp=lemp->rule; rp; rp=rp->next){ if( rp->code==0 ) continue; assert( rp->code[0]=='\n' && rp->code[1]==0 ); + assert( rp->codePrefix==0 ); + assert( rp->codeSuffix==0 ); fprintf(out," /* (%d) ", rp->iRule); writeRuleText(out, rp); fprintf(out, " */ yytestcase(yyruleno==%d);\n", rp->iRule); lineno++; From 2f55511dfa0ff9ad1c82a918ea62a7be236420cb Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 30 Apr 2016 18:10:34 +0000 Subject: [PATCH 0370/1484] Remove an unnecessary branch from the OP_String8 opcode. FossilOrigin-Name: 459a0b456da69112605b37adc9af27d79e35a4d7 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 7 +++---- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index c82cd48e76..fe30409fc4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C More\sbug\sfixes\sto\sLemon\sidentified\sby\sKelvin\sSherlock.\s\sNone\sof\sthese\nhave\sany\simpact\son\sSQLite. -D 2016-04-30T17:19:30.162 +C Remove\san\sunnecessary\sbranch\sfrom\sthe\sOP_String8\sopcode. +D 2016-04-30T18:10:34.585 F Makefile.in 9e816d0323e418fbc0f8b2c05fc14e0b3763d9e8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -443,7 +443,7 @@ F src/update.c 3e67ab3c0814635f355fb1f8ab010a2b9e016e7d F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 810ec3f22e2d1b62e66c30fe3621ebdedd23584d F src/vacuum.c feb1eabb20987983d9350cad98299b21fa811f52 -F src/vdbe.c b2067cd06a0f30a6dea865f93c690df15e0314a8 +F src/vdbe.c 465bb820f9760602959ba8d279cdae621206d696 F src/vdbe.h 5591b5add447096e31288b5a0a78ec5d7b5c5170 F src/vdbeInt.h ddb157974436d87652de7dc641f7191496d9a8cd F src/vdbeapi.c ba85b78fe08dc4a9ce747e62c89a2b4a4547e74c @@ -1486,7 +1486,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P daf4630f96f13133664908045e279da9d5a40bb5 -R abf1ac3c7e03f177ba74945ccc38d922 +P 762bdc55f8878ee2ef65af2165a8e7fdbddf0160 +R c6bd6d9832f41be3a84777fb9beacd97 U drh -Z cfd7bc89828187e9540e8e1e6f984687 +Z beaad3433e5488a905014b307adfe5b7 diff --git a/manifest.uuid b/manifest.uuid index 03d710e202..c3f171f13c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -762bdc55f8878ee2ef65af2165a8e7fdbddf0160 \ No newline at end of file +459a0b456da69112605b37adc9af27d79e35a4d7 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index cb977e0854..469ab86e42 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -1064,10 +1064,7 @@ case OP_String8: { /* same as TK_STRING, out2 */ #ifndef SQLITE_OMIT_UTF16 if( encoding!=SQLITE_UTF8 ){ rc = sqlite3VdbeMemSetStr(pOut, pOp->p4.z, -1, SQLITE_UTF8, SQLITE_STATIC); - if( rc ){ - assert( rc==SQLITE_TOOBIG ); /* This is the only possible error here */ - goto too_big; - } + assert( rc==SQLITE_OK || rc==SQLITE_TOOBIG ); if( SQLITE_OK!=sqlite3VdbeChangeEncoding(pOut, encoding) ) goto no_mem; assert( pOut->szMalloc>0 && pOut->zMalloc==pOut->z ); assert( VdbeMemDynamic(pOut)==0 ); @@ -1080,10 +1077,12 @@ case OP_String8: { /* same as TK_STRING, out2 */ pOp->p4.z = pOut->z; pOp->p1 = pOut->n; } + testcase( rc==SQLITE_TOOBIG ); #endif if( pOp->p1>db->aLimit[SQLITE_LIMIT_LENGTH] ){ goto too_big; } + assert( rc==SQLITE_OK ); /* Fall through to the next case, OP_String */ } From 40cf36ff1756a3c65f9569afeae4066bbb5aed41 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 30 Apr 2016 19:23:10 +0000 Subject: [PATCH 0371/1484] Change the way tester.tcl handes $argv so that in "permutations.test " may be the name of any file in the test/ directory. FossilOrigin-Name: 820c57bb24ad3d8663ca512e4022268b940bb2ee --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/tester.tcl | 6 +++++- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index fe30409fc4..ec489b353d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\san\sunnecessary\sbranch\sfrom\sthe\sOP_String8\sopcode. -D 2016-04-30T18:10:34.585 +C Change\sthe\sway\stester.tcl\shandes\s$argv\sso\sthat\sin\s"permutations.test\s\s"\s\smay\sbe\sthe\sname\sof\sany\sfile\sin\sthe\stest/\sdirectory. +D 2016-04-30T19:23:10.056 F Makefile.in 9e816d0323e418fbc0f8b2c05fc14e0b3763d9e8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -1115,7 +1115,7 @@ F test/tempfault.test 0c0d349c9a99bf5f374655742577f8712c647900 F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30 F test/temptable2.test c3d8c138f493207612960bbd6a8c50e84975e2ee F test/temptrigger.test 8ec228b0db5d7ebc4ee9b458fc28cb9e7873f5e1 -F test/tester.tcl 30c7a9be8601d1c1c9c93d013545ebcb28d64254 +F test/tester.tcl 3ace46dee55f07e28a1e3ab03258b929fefcee5b F test/thread001.test 9f22fd3525a307ff42a326b6bc7b0465be1745a5 F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58 F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7 @@ -1486,7 +1486,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 762bdc55f8878ee2ef65af2165a8e7fdbddf0160 -R c6bd6d9832f41be3a84777fb9beacd97 -U drh -Z beaad3433e5488a905014b307adfe5b7 +P 459a0b456da69112605b37adc9af27d79e35a4d7 +R 23212a22e435d3100aef78ab9c45b327 +U dan +Z 034fcb062ad20342a7b230d87b3ffc20 diff --git a/manifest.uuid b/manifest.uuid index c3f171f13c..6ff03c7829 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -459a0b456da69112605b37adc9af27d79e35a4d7 \ No newline at end of file +820c57bb24ad3d8663ca512e4022268b940bb2ee \ No newline at end of file diff --git a/test/tester.tcl b/test/tester.tcl index 23810d09ee..9fbc7b2569 100644 --- a/test/tester.tcl +++ b/test/tester.tcl @@ -521,7 +521,11 @@ if {[info exists cmdlinearg]==0} { } default { - lappend leftover [file normalize $a] + if {[file tail $a]==$a} { + lappend leftover $a + } else { + lappend leftover [file normalize $a] + } } } } From 44aebff24623d6adc3e2977d1e95ad1a2353ea6d Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 2 May 2016 10:25:42 +0000 Subject: [PATCH 0372/1484] Improvements to the way the LIKE optimization is implemented, resulting in slightly smaller and faster code that is easier to test. FossilOrigin-Name: 54c63b329288729031f45b7778752552cd90e226 --- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- src/vdbe.c | 26 ++++++-------------------- src/where.c | 9 ++------- src/whereInt.h | 2 +- src/wherecode.c | 36 +++++++++++++++++++++++------------- 6 files changed, 43 insertions(+), 52 deletions(-) diff --git a/manifest b/manifest index ec489b353d..4b7ff45c68 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sthe\sway\stester.tcl\shandes\s$argv\sso\sthat\sin\s"permutations.test\s\s"\s\smay\sbe\sthe\sname\sof\sany\sfile\sin\sthe\stest/\sdirectory. -D 2016-04-30T19:23:10.056 +C Improvements\sto\sthe\sway\sthe\sLIKE\soptimization\sis\simplemented,\sresulting\sin\nslightly\ssmaller\sand\sfaster\scode\sthat\sis\seasier\sto\stest. +D 2016-05-02T10:25:42.392 F Makefile.in 9e816d0323e418fbc0f8b2c05fc14e0b3763d9e8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -443,7 +443,7 @@ F src/update.c 3e67ab3c0814635f355fb1f8ab010a2b9e016e7d F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 810ec3f22e2d1b62e66c30fe3621ebdedd23584d F src/vacuum.c feb1eabb20987983d9350cad98299b21fa811f52 -F src/vdbe.c 465bb820f9760602959ba8d279cdae621206d696 +F src/vdbe.c 4bad04212736526845fda9ca674afafb10078b2b F src/vdbe.h 5591b5add447096e31288b5a0a78ec5d7b5c5170 F src/vdbeInt.h ddb157974436d87652de7dc641f7191496d9a8cd F src/vdbeapi.c ba85b78fe08dc4a9ce747e62c89a2b4a4547e74c @@ -457,9 +457,9 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 4db22ed7e77bcf672b1a685d6ddeffba8d5be302 F src/wal.h 2f7c831cf3b071fa548bf2d5cac640846a7ff19c F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354 -F src/where.c bae50f2f18f9e8584549a77363858623b07e4915 -F src/whereInt.h 7de94b751f088fe3fdc8cc04a491376f0900a059 -F src/wherecode.c 8fdad9fbba723df1c1e8d07e7ea8507572040340 +F src/where.c 019e5b10dedcf54ef077ce23dd8fce38d614dcf4 +F src/whereInt.h 3b1fc240e322613ba4e9dc857ca9c7c3390acc74 +F src/wherecode.c 28951741be3974701186281ced0564e9586a0db3 F src/whereexpr.c eacc0e60d029a082b4fc0cc42ea98544add1319e F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -1486,7 +1486,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 459a0b456da69112605b37adc9af27d79e35a4d7 -R 23212a22e435d3100aef78ab9c45b327 -U dan -Z 034fcb062ad20342a7b230d87b3ffc20 +P 820c57bb24ad3d8663ca512e4022268b940bb2ee +R c58e65d0f2e2d03ddd82d7f66bccab45 +U drh +Z 38f3015d7db64980369a2f7c9273004f diff --git a/manifest.uuid b/manifest.uuid index 6ff03c7829..d98c57c9ad 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -820c57bb24ad3d8663ca512e4022268b940bb2ee \ No newline at end of file +54c63b329288729031f45b7778752552cd90e226 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 469ab86e42..dc8201595b 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -1091,10 +1091,12 @@ case OP_String8: { /* same as TK_STRING, out2 */ ** ** The string value P4 of length P1 (bytes) is stored in register P2. ** -** If P5!=0 and the content of register P3 is greater than zero, then +** If P3 is not zero and the content of register P3 is equal to P5, then ** the datatype of the register P2 is converted to BLOB. The content is ** the same sequence of bytes, it is merely interpreted as a BLOB instead -** of a string, as if it had been CAST. +** of a string, as if it had been CAST. In other words: +** +** if( P3!=0 and reg[P3]==P5 ) reg[P2] := CAST(reg[P2] as BLOB) */ case OP_String: { /* out2 */ assert( pOp->p4.z!=0 ); @@ -1105,12 +1107,11 @@ case OP_String: { /* out2 */ pOut->enc = encoding; UPDATE_MAX_BLOBSIZE(pOut); #ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS - if( pOp->p5 ){ - assert( pOp->p3>0 ); + if( pOp->p3>0 ){ assert( pOp->p3<=(p->nMem+1 - p->nCursor) ); pIn3 = &aMem[pOp->p3]; assert( pIn3->flags & MEM_Int ); - if( pIn3->u.i ) pOut->flags = MEM_Blob|MEM_Static|MEM_Term; + if( pIn3->u.i==pOp->p5 ) pOut->flags = MEM_Blob|MEM_Static|MEM_Term; } #endif break; @@ -5966,21 +5967,6 @@ case OP_DecrJumpZero: { /* jump, in1 */ } -/* Opcode: JumpZeroIncr P1 P2 * * * -** Synopsis: if (r[P1]++)==0 ) goto P2 -** -** The register P1 must contain an integer. If register P1 is initially -** zero, then jump to P2. Increment register P1 regardless of whether or -** not the jump is taken. -*/ -case OP_JumpZeroIncr: { /* jump, in1 */ - pIn1 = &aMem[pOp->p1]; - assert( pIn1->flags&MEM_Int ); - VdbeBranchTaken(pIn1->u.i==0, 2); - if( (pIn1->u.i++)==0 ) goto jump_to_p2; - break; -} - /* Opcode: AggStep0 * P2 P3 P4 P5 ** Synopsis: accum=r[P3] step(r[P2@P5]) ** diff --git a/src/where.c b/src/where.c index ca810a3b16..d45a872c85 100644 --- a/src/where.c +++ b/src/where.c @@ -4607,13 +4607,8 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ } #ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS if( pLevel->addrLikeRep ){ - int op; - if( sqlite3VdbeGetOp(v, pLevel->addrLikeRep-1)->p1 ){ - op = OP_DecrJumpZero; - }else{ - op = OP_JumpZeroIncr; - } - sqlite3VdbeAddOp2(v, op, pLevel->iLikeRepCntr, pLevel->addrLikeRep); + sqlite3VdbeAddOp2(v, OP_DecrJumpZero, (int)(pLevel->iLikeRepCntr>>1), + pLevel->addrLikeRep); VdbeCoverage(v); } #endif diff --git a/src/whereInt.h b/src/whereInt.h index 252905aa5a..d33d995af1 100644 --- a/src/whereInt.h +++ b/src/whereInt.h @@ -70,7 +70,7 @@ struct WhereLevel { int addrFirst; /* First instruction of interior of the loop */ int addrBody; /* Beginning of the body of this loop */ #ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS - int iLikeRepCntr; /* LIKE range processing counter register */ + u32 iLikeRepCntr; /* LIKE range processing counter register (times 2) */ int addrLikeRep; /* LIKE range processing address */ #endif u8 iFrom; /* Which entry in the FROM clause */ diff --git a/src/wherecode.c b/src/wherecode.c index 8105e99dde..77543a9388 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -560,9 +560,10 @@ static int codeAllEqualityTerms( #ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS /* -** If the most recently coded instruction is a constant range contraint -** that originated from the LIKE optimization, then change the P3 to be -** pLoop->iLikeRepCntr and set P5. +** If the most recently coded instruction is a constant range constraint +** (a string literal) that originated from the LIKE optimization, then +** set P3 and P5 on the OP_String opcode so that the string will be cast +** to a BLOB at appropriate times. ** ** The LIKE optimization trys to evaluate "x LIKE 'abc%'" as a range ** expression: "x>='ABC' AND x<'abd'". But this requires that the range @@ -587,8 +588,8 @@ static void whereLikeOptimizationStringFixup( assert( pOp!=0 ); assert( pOp->opcode==OP_String8 || pTerm->pWC->pWInfo->pParse->db->mallocFailed ); - pOp->p3 = pLevel->iLikeRepCntr; - pOp->p5 = 1; + pOp->p3 = (int)(pLevel->iLikeRepCntr>>1); /* Register holding counter */ + pOp->p5 = (u8)(pLevel->iLikeRepCntr&1); /* ASC or DESC */ } } #else @@ -1175,14 +1176,17 @@ Bitmask sqlite3WhereCodeOneLoopStart( if( (pRangeEnd->wtFlags & TERM_LIKEOPT)!=0 ){ assert( pRangeStart!=0 ); /* LIKE opt constraints */ assert( pRangeStart->wtFlags & TERM_LIKEOPT ); /* occur in pairs */ - pLevel->iLikeRepCntr = ++pParse->nMem; - testcase( bRev ); - testcase( pIdx->aSortOrder[nEq]==SQLITE_SO_DESC ); - sqlite3VdbeAddOp2(v, OP_Integer, - bRev ^ (pIdx->aSortOrder[nEq]==SQLITE_SO_DESC), - pLevel->iLikeRepCntr); + pLevel->iLikeRepCntr = (u32)++pParse->nMem; + sqlite3VdbeAddOp2(v, OP_Integer, 1, (int)pLevel->iLikeRepCntr); VdbeComment((v, "LIKE loop counter")); pLevel->addrLikeRep = sqlite3VdbeCurrentAddr(v); + /* iLikeRepCntr actually stores 2x the counter register number. The + ** bottom bit indicates whether the search order is ASC or DESC. */ + testcase( bRev ); + testcase( pIdx->aSortOrder[nEq]==SQLITE_SO_DESC ); + assert( (bRev & ~1)==0 ); + pLevel->iLikeRepCntr <<=1; + pLevel->iLikeRepCntr |= bRev ^ (pIdx->aSortOrder[nEq]==SQLITE_SO_DESC); } #endif if( pRangeStart==0 @@ -1696,11 +1700,17 @@ Bitmask sqlite3WhereCodeOneLoopStart( continue; } if( pTerm->wtFlags & TERM_LIKECOND ){ + /* If the TERM_LIKECOND flag is set, that means that the range search + ** is sufficient to guarantee that the LIKE operator is true, so we + ** can skip the call to the like(A,B) function. But this only works + ** for strings. So do not skip the call to the function on the pass + ** that compares BLOBs. */ #ifdef SQLITE_LIKE_DOESNT_MATCH_BLOBS continue; #else - assert( pLevel->iLikeRepCntr>0 ); - skipLikeAddr = sqlite3VdbeAddOp1(v, OP_IfNot, pLevel->iLikeRepCntr); + u32 x = pLevel->iLikeRepCntr; + assert( x>0 ); + skipLikeAddr = sqlite3VdbeAddOp1(v, (x&1)? OP_IfNot : OP_If, (int)(x>>1)); VdbeCoverage(v); #endif } From 57a07ba9a938ead154cc629a8357cb025b14a7b1 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 2 May 2016 12:18:56 +0000 Subject: [PATCH 0373/1484] Disable the multi-row one-pass DELETE optimization when the WHERE clause contains a subquery. Fix for ticket [dc6ebeda9396087]. FossilOrigin-Name: 3f221f592a9a19009076e568566c59801cd3fc32 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/delete.c | 5 +++-- test/delete4.test | 23 +++++++++++++++++++++++ 4 files changed, 34 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 4b7ff45c68..1b3f03c036 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improvements\sto\sthe\sway\sthe\sLIKE\soptimization\sis\simplemented,\sresulting\sin\nslightly\ssmaller\sand\sfaster\scode\sthat\sis\seasier\sto\stest. -D 2016-05-02T10:25:42.392 +C Disable\sthe\smulti-row\sone-pass\sDELETE\soptimization\swhen\sthe\sWHERE\sclause\ncontains\sa\ssubquery.\s\sFix\sfor\sticket\s[dc6ebeda9396087]. +D 2016-05-02T12:18:56.634 F Makefile.in 9e816d0323e418fbc0f8b2c05fc14e0b3763d9e8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -330,7 +330,7 @@ F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 60e135af364d777a9ab41c97e5e89cd224da6198 F src/date.c 1cc9fb516ec9932c6fd4d2a0d2f8bc4480145c39 F src/dbstat.c c845548d4346e606e2f2b7d2e714ace2b8a7dd1b -F src/delete.c 78eb999114ec04fcf1b7d123ccedb4b5b734930e +F src/delete.c 362f89f8e6783e672c4ab06b90fca0177f9a576d F src/expr.c 8796c0739b2ad091e6779253f62aad6e767e2be1 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 4c0bd09e602b8ae8d36d81e31e4872d0b53c87bb @@ -617,7 +617,7 @@ F test/default.test 0cb49b1c315a0d81c81d775e407f66906a2a604d F test/delete.test e1bcdf8926234e27aac24b346ad83d3329ec8b6f F test/delete2.test 3a03f2cca1f9a67ec469915cb8babd6485db43fa F test/delete3.test 555e84a00a99230b7d049d477a324a631126a6ab -F test/delete4.test 738044ee892ee0c84e0848e36ba92c55f907d52b +F test/delete4.test 21d2113217eeaacac2d99defe14fe6611615ae86 F test/descidx1.test 6d03b44c8538fe0eb4924e19fba10cdd8f3c9240 F test/descidx2.test 9f1a0c83fd57f8667c82310ca21b30a350888b5d F test/descidx3.test 09ddbe3f5295f482d2f8b687cf6db8bad7acd9a2 @@ -1486,7 +1486,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 820c57bb24ad3d8663ca512e4022268b940bb2ee -R c58e65d0f2e2d03ddd82d7f66bccab45 +P 54c63b329288729031f45b7778752552cd90e226 +R 31fbd50c446b686ccdad6a76f26cbea2 U drh -Z 38f3015d7db64980369a2f7c9273004f +Z 89acbaae560b0638ea30c0a72d46ae74 diff --git a/manifest.uuid b/manifest.uuid index d98c57c9ad..a267b82408 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -54c63b329288729031f45b7778752552cd90e226 \ No newline at end of file +3f221f592a9a19009076e568566c59801cd3fc32 \ No newline at end of file diff --git a/src/delete.c b/src/delete.c index e3af2d7a78..258b39cc3e 100644 --- a/src/delete.c +++ b/src/delete.c @@ -239,11 +239,12 @@ void sqlite3DeleteFrom( int addrBypass = 0; /* Address of jump over the delete logic */ int addrLoop = 0; /* Top of the delete loop */ int addrEphOpen = 0; /* Instruction to open the Ephemeral table */ + int bComplex; /* True if there are triggers or FKs or or + ** subqueries in the WHERE clause */ #ifndef SQLITE_OMIT_TRIGGER int isView; /* True if attempting to delete from a view */ Trigger *pTrigger; /* List of table triggers, if required */ - int bComplex; /* True if there are either triggers or FKs */ #endif memset(&sContext, 0, sizeof(sContext)); @@ -271,7 +272,6 @@ void sqlite3DeleteFrom( #else # define pTrigger 0 # define isView 0 -# define bComplex 0 #endif #ifdef SQLITE_OMIT_VIEW # undef isView @@ -374,6 +374,7 @@ void sqlite3DeleteFrom( #endif /* SQLITE_OMIT_TRUNCATE_OPTIMIZATION */ { u16 wcf = WHERE_ONEPASS_DESIRED|WHERE_DUPLICATES_OK; + if( pWhere && ExprHasProperty(pWhere, EP_Subquery) ) bComplex = 1; wcf |= (bComplex ? 0 : WHERE_ONEPASS_MULTIROW); if( HasRowid(pTab) ){ /* For a rowid table, initialize the RowSet to an empty set */ diff --git a/test/delete4.test b/test/delete4.test index 7622b7525e..34ba9aaef8 100644 --- a/test/delete4.test +++ b/test/delete4.test @@ -161,4 +161,27 @@ do_execsql_test 5.0 { SELECT a FROM t1 WHERE b=2; } {} +# 2016-05-02 +# Ticket https://www.sqlite.org/src/tktview/dc6ebeda93960877 +# A subquery in the WHERE clause of a one-pass DELETE can cause an +# incorrect answer. +# +db close +forcedelete test.db +sqlite3 db test.db +do_execsql_test 6.0 { + CREATE TABLE t2(x INT); + INSERT INTO t2(x) VALUES(1),(2),(3),(4),(5); + DELETE FROM t2 WHERE EXISTS(SELECT 1 FROM t2 AS v WHERE v.x=t2.x-1); + SELECT x FROM t2; +} {1} +do_execsql_test 6.1 { + DROP TABLE IF EXISTS t2; + CREATE TABLE t2(x INT); + INSERT INTO t2(x) VALUES(1),(2),(3),(4),(5); + DELETE FROM t2 WHERE EXISTS(SELECT 1 FROM t2 AS v WHERE v.x=t2.x+1); + SELECT x FROM t2; +} {5} + + finish_test From cf7e7557b59bbab2c512615aa9d02a896c7e08de Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 2 May 2016 13:57:19 +0000 Subject: [PATCH 0374/1484] Fix harmless LLVM compiler warnings in the srcck1.c utility program used during the build process. FossilOrigin-Name: e4af967533f290862dfba1d9ef44d4c9ddd8a01b --- manifest | 12 ++++++------ manifest.uuid | 2 +- tool/srcck1.c | 8 ++++---- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 1b3f03c036..8fad26fa93 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Disable\sthe\smulti-row\sone-pass\sDELETE\soptimization\swhen\sthe\sWHERE\sclause\ncontains\sa\ssubquery.\s\sFix\sfor\sticket\s[dc6ebeda9396087]. -D 2016-05-02T12:18:56.634 +C Fix\sharmless\sLLVM\scompiler\swarnings\sin\sthe\ssrcck1.c\sutility\sprogram\sused\nduring\sthe\sbuild\sprocess. +D 2016-05-02T13:57:19.631 F Makefile.in 9e816d0323e418fbc0f8b2c05fc14e0b3763d9e8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -1454,7 +1454,7 @@ F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 7ce07da76b5e745783e703a834417d725b7d45fd F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c F tool/sqldiff.c ca315aca4e2d24233e8f2000edea5880c53d1875 -F tool/srcck1.c 4f65e1a6748e42f24c0ea629dddc934d821c729a +F tool/srcck1.c 4c39bdfa9a92edd20233ee720df84dbeb2417602 F tool/stack_usage.tcl f8e71b92cdb099a147dad572375595eae55eca43 F tool/symbols-mingw.sh 4dbcea7e74768305384c9fd2ed2b41bbf9f0414d F tool/symbols.sh c5a617b8c61a0926747a56c65f5671ef8ac0e148 @@ -1486,7 +1486,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 54c63b329288729031f45b7778752552cd90e226 -R 31fbd50c446b686ccdad6a76f26cbea2 +P 3f221f592a9a19009076e568566c59801cd3fc32 +R 9e19502e796cc0b447ced5695bd13d5a U drh -Z 89acbaae560b0638ea30c0a72d46ae74 +Z 98cb934422c4b3de5638d36de23360d8 diff --git a/manifest.uuid b/manifest.uuid index a267b82408..b95adc4417 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3f221f592a9a19009076e568566c59801cd3fc32 \ No newline at end of file +e4af967533f290862dfba1d9ef44d4c9ddd8a01b \ No newline at end of file diff --git a/tool/srcck1.c b/tool/srcck1.c index f92610f544..e95765185f 100644 --- a/tool/srcck1.c +++ b/tool/srcck1.c @@ -111,11 +111,11 @@ static unsigned int findCloseParen(const char *z){ ** Print error messages whenever a side effect is found. Return the number ** of problems seen. */ -static unsigned int findAllSideEffects(const unsigned char *z){ +static unsigned int findAllSideEffects(const char *z){ unsigned int lineno = 1; /* Line number */ unsigned int i; unsigned int nErr = 0; - unsigned char c, prevC = 0; + char c, prevC = 0; for(i=0; (c = z[i])!=0; prevC=c, i++){ if( c=='\n' ){ lineno++; continue; } if( isalpha(c) && !isalpha(prevC) ){ @@ -125,7 +125,7 @@ static unsigned int findAllSideEffects(const unsigned char *z){ || strncmp(&z[i],"testcase(",9)==0 ){ unsigned int n; - unsigned const char *z2 = &z[i+5]; + const char *z2 = &z[i+5]; while( z2[0]!='(' ){ z2++; } z2++; n = findCloseParen(z2); @@ -141,7 +141,7 @@ static unsigned int findAllSideEffects(const unsigned char *z){ } int main(int argc, char **argv){ - unsigned char *z; + char *z; unsigned int nErr = 0; if( argc!=2 ){ fprintf(stderr, "Usage: %s FILENAME\n", argv[0]); From b1c6995c58cc3ab59539a6a2254045dad9877ef7 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 2 May 2016 16:59:49 +0000 Subject: [PATCH 0375/1484] Fix a test case in temptable2.test so that it works on systems that lack a coherient cache (ex: OpenBSD) and thus do not support the "PRAGMA mmap_size" command. FossilOrigin-Name: 088cf83872f6477c3b297c58d6f8a5def7025daf --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/temptable2.test | 11 ++++++----- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 8fad26fa93..d418547198 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\sLLVM\scompiler\swarnings\sin\sthe\ssrcck1.c\sutility\sprogram\sused\nduring\sthe\sbuild\sprocess. -D 2016-05-02T13:57:19.631 +C Fix\sa\stest\scase\sin\stemptable2.test\sso\sthat\sit\sworks\son\ssystems\sthat\nlack\sa\scoherient\scache\s(ex:\sOpenBSD)\sand\sthus\sdo\snot\ssupport\sthe\n"PRAGMA\smmap_size"\scommand. +D 2016-05-02T16:59:49.933 F Makefile.in 9e816d0323e418fbc0f8b2c05fc14e0b3763d9e8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -1113,7 +1113,7 @@ F test/tclsqlite.test e1306001a0ca92250b691ea6d3cecaca5b6342aa F test/tempdb.test bd92eba8f20e16a9136e434e20b280794de3cdb6 F test/tempfault.test 0c0d349c9a99bf5f374655742577f8712c647900 F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30 -F test/temptable2.test c3d8c138f493207612960bbd6a8c50e84975e2ee +F test/temptable2.test efeb3ce7aaf515a1f8ebf5e27390426fb977f998 F test/temptrigger.test 8ec228b0db5d7ebc4ee9b458fc28cb9e7873f5e1 F test/tester.tcl 3ace46dee55f07e28a1e3ab03258b929fefcee5b F test/thread001.test 9f22fd3525a307ff42a326b6bc7b0465be1745a5 @@ -1486,7 +1486,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 3f221f592a9a19009076e568566c59801cd3fc32 -R 9e19502e796cc0b447ced5695bd13d5a +P e4af967533f290862dfba1d9ef44d4c9ddd8a01b +R cf9611bb2e200af1ab3bcf6e6340a559 U drh -Z 98cb934422c4b3de5638d36de23360d8 +Z af0809554b03e07ad79015deb62b6895 diff --git a/manifest.uuid b/manifest.uuid index b95adc4417..d5de45a24b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e4af967533f290862dfba1d9ef44d4c9ddd8a01b \ No newline at end of file +088cf83872f6477c3b297c58d6f8a5def7025daf \ No newline at end of file diff --git a/test/temptable2.test b/test/temptable2.test index 890b3b996d..72bcf1ac50 100644 --- a/test/temptable2.test +++ b/test/temptable2.test @@ -343,14 +343,15 @@ do_execsql_test 10.1 { INSERT INTO t2 VALUES(3, 4); } -if {[permutation]!="journaltest"} { - # The journaltest permutation does not support mmap, so this part of - # the test is omitted. - do_execsql_test 10.2 { PRAGMA mmap_size = 512000 } 512000 +ifcapable mmap { + if {[permutation]!="journaltest"} { + # The journaltest permutation does not support mmap, so this part of + # the test is omitted. + do_execsql_test 10.2 { PRAGMA mmap_size = 512000 } 512000 + } } do_execsql_test 10.3 { SELECT * FROM t2 } {1 2 3 4} do_execsql_test 10.4 { PRAGMA integrity_check } ok finish_test - From 39f98c52d023e0503196864c2090b6369af1effd Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 2 May 2016 19:05:05 +0000 Subject: [PATCH 0376/1484] Remove some randomness from test script temptable2.test. FossilOrigin-Name: 5830cf72e9e870830d088399f1ccb03ed6522582 --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/temptable2.test | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index d418547198..95c5a353ec 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\stest\scase\sin\stemptable2.test\sso\sthat\sit\sworks\son\ssystems\sthat\nlack\sa\scoherient\scache\s(ex:\sOpenBSD)\sand\sthus\sdo\snot\ssupport\sthe\n"PRAGMA\smmap_size"\scommand. -D 2016-05-02T16:59:49.933 +C Remove\ssome\srandomness\sfrom\stest\sscript\stemptable2.test. +D 2016-05-02T19:05:05.108 F Makefile.in 9e816d0323e418fbc0f8b2c05fc14e0b3763d9e8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -1113,7 +1113,7 @@ F test/tclsqlite.test e1306001a0ca92250b691ea6d3cecaca5b6342aa F test/tempdb.test bd92eba8f20e16a9136e434e20b280794de3cdb6 F test/tempfault.test 0c0d349c9a99bf5f374655742577f8712c647900 F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30 -F test/temptable2.test efeb3ce7aaf515a1f8ebf5e27390426fb977f998 +F test/temptable2.test cd396beb41117a5302fff61767c35fa4270a0d5e F test/temptrigger.test 8ec228b0db5d7ebc4ee9b458fc28cb9e7873f5e1 F test/tester.tcl 3ace46dee55f07e28a1e3ab03258b929fefcee5b F test/thread001.test 9f22fd3525a307ff42a326b6bc7b0465be1745a5 @@ -1486,7 +1486,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e4af967533f290862dfba1d9ef44d4c9ddd8a01b -R cf9611bb2e200af1ab3bcf6e6340a559 -U drh -Z af0809554b03e07ad79015deb62b6895 +P 088cf83872f6477c3b297c58d6f8a5def7025daf +R 237f2aea599511d792221ce999e030ab +U dan +Z f86754e59f932bdb68bb3e5db8c95fe0 diff --git a/manifest.uuid b/manifest.uuid index d5de45a24b..8a1882b583 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -088cf83872f6477c3b297c58d6f8a5def7025daf \ No newline at end of file +5830cf72e9e870830d088399f1ccb03ed6522582 \ No newline at end of file diff --git a/test/temptable2.test b/test/temptable2.test index 72bcf1ac50..ffa69b6150 100644 --- a/test/temptable2.test +++ b/test/temptable2.test @@ -230,7 +230,7 @@ do_execsql_test 8.1 { CREATE TABLE t2(a, b); CREATE INDEX i2 ON t2(a, b); WITH x(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM x WHERE i<20 ) - INSERT INTO t2 SELECT randomblob(100), randomblob(100) FROM x; + INSERT INTO t2 SELECT randomblob(100), randomblob(100) FROM x ORDER BY 1, 2; PRAGMA page_count; } {13} @@ -242,7 +242,7 @@ do_test 8.2 { CREATE TABLE t1(a, b); CREATE INDEX i1 ON t1(a, b); WITH x(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM x WHERE i<100 ) - INSERT INTO t1 SELECT randomblob(100), randomblob(100) FROM x; + INSERT INTO t1 SELECT randomblob(100), randomblob(100) FROM x ORDER BY 1, 2; PRAGMA page_count; } tmp } {10} From 48cd59a57d680b53b9fca3b74058c594040d4e8d Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 3 May 2016 00:04:55 +0000 Subject: [PATCH 0377/1484] Avoid left-shifts of signed integers. FossilOrigin-Name: 0715ce164333e27671efbec8796f238df98cc287 --- ext/session/sqlite3session.c | 15 +++++++-------- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/test1.c | 8 ++++---- 4 files changed, 20 insertions(+), 21 deletions(-) diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index e333dffcc7..70ca840dae 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -278,19 +278,18 @@ static int sessionVarintGet(u8 *aBuf, int *piVal){ return getVarint32(aBuf, *piVal); } +/* Load an unaligned and unsigned 32-bit integer */ +#define SESSION_UINT32(x) (((u32)(x)[0]<<24)|((x)[1]<<16)|((x)[2]<<8)|(x)[3]) + /* ** Read a 64-bit big-endian integer value from buffer aRec[]. Return ** the value read. */ static sqlite3_int64 sessionGetI64(u8 *aRec){ - return (((sqlite3_int64)aRec[0]) << 56) - + (((sqlite3_int64)aRec[1]) << 48) - + (((sqlite3_int64)aRec[2]) << 40) - + (((sqlite3_int64)aRec[3]) << 32) - + (((sqlite3_int64)aRec[4]) << 24) - + (((sqlite3_int64)aRec[5]) << 16) - + (((sqlite3_int64)aRec[6]) << 8) - + (((sqlite3_int64)aRec[7]) << 0); + u64 x = SESSION_UINT32(aRec); + u32 y = SESSION_UINT32(aRec+4); + x = (x<<32) + y; + return (sqlite3_int64)x; } /* diff --git a/manifest b/manifest index 95c5a353ec..27faecd64e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\ssome\srandomness\sfrom\stest\sscript\stemptable2.test. -D 2016-05-02T19:05:05.108 +C Avoid\sleft-shifts\sof\ssigned\sintegers. +D 2016-05-03T00:04:55.196 F Makefile.in 9e816d0323e418fbc0f8b2c05fc14e0b3763d9e8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -293,7 +293,7 @@ F ext/session/sessionG.test 01ef705096a9d3984eebdcca79807a211dee1b60 F ext/session/session_common.tcl a1293167d14774b5e728836720497f40fe4ea596 F ext/session/sessionfault.test da273f2712b6411e85e71465a1733b8501dbf6f7 F ext/session/sessionfault2.test 04aa0bc9aa70ea43d8de82c4f648db4de1e990b0 -F ext/session/sqlite3session.c beb43b6b888801bb006320bc236baa95f4cc32ae +F ext/session/sqlite3session.c 37485891b4add26cf61495df193c419f36556a32 F ext/session/sqlite3session.h 64e9e7f185725ef43b97f4a9a0c0df0669844f1d F ext/session/test_session.c 464f2c8bf502795d95969387eb8e93f68c513c15 F ext/userauth/sqlite3userauth.h 19cb6f0e31316d0ee4afdfb7a85ef9da3333a220 @@ -387,7 +387,7 @@ F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 F src/tclsqlite.c 9c4c4589d078de37813ded708d8838b338ffb060 -F src/test1.c ee8fd5c32acb93fb6fe885ca4801cfab85f5563f +F src/test1.c c0e5b69f99e95a2c9f55fdb6e46b44f1a15292d8 F src/test2.c 5586f43fcd9a1be0830793cf9d354082c261b25b F src/test3.c 0df6f8dbb4cbaa7106397c70a271fa6a43659042 F src/test4.c d168f83cc78d02e8d35567bb5630e40dcd85ac1e @@ -1486,7 +1486,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 088cf83872f6477c3b297c58d6f8a5def7025daf -R 237f2aea599511d792221ce999e030ab -U dan -Z f86754e59f932bdb68bb3e5db8c95fe0 +P 5830cf72e9e870830d088399f1ccb03ed6522582 +R 350580348db69c537adc1a64222fc40a +U drh +Z 10c9aec7cf14a46e7039005f7f038452 diff --git a/manifest.uuid b/manifest.uuid index 8a1882b583..9202d19d19 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5830cf72e9e870830d088399f1ccb03ed6522582 \ No newline at end of file +0715ce164333e27671efbec8796f238df98cc287 \ No newline at end of file diff --git a/src/test1.c b/src/test1.c index 5b7581af7b..ee71b854b9 100644 --- a/src/test1.c +++ b/src/test1.c @@ -6700,8 +6700,8 @@ static int sorter_test_sort4_helper( const char *zSql2; int nStep; int iStep; - int iCksum1 = 0; - int iCksum2 = 0; + unsigned int iCksum1 = 0; + unsigned int iCksum2 = 0; int rc; int iB; sqlite3 *db; @@ -6728,7 +6728,7 @@ static int sorter_test_sort4_helper( return TCL_ERROR; } - iCksum1 += (iCksum1 << 3) + a; + iCksum1 += (iCksum1 << 3) + (unsigned int)a; } rc = sqlite3_finalize(pStmt); if( rc!=SQLITE_OK ) goto sql_error; @@ -6737,7 +6737,7 @@ static int sorter_test_sort4_helper( if( rc!=SQLITE_OK ) goto sql_error; for(iStep=0; SQLITE_ROW==sqlite3_step(pStmt); iStep++){ int a = sqlite3_column_int(pStmt, 0); - iCksum2 += (iCksum2 << 3) + a; + iCksum2 += (iCksum2 << 3) + (unsigned int)a; } rc = sqlite3_finalize(pStmt); if( rc!=SQLITE_OK ) goto sql_error; From 5e18d402007272ff2b305f066ed67dba92b2f155 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 3 May 2016 13:14:18 +0000 Subject: [PATCH 0378/1484] Turn the session extension off by default. Enable using --enable-session on configure scripts, or using the SESSION=1 argument to nmake on Windows. FossilOrigin-Name: e462cde2a50c39cc2f8d8624aada19280b8226eb --- Makefile.in | 1 - Makefile.msc | 9 +++++++++ autoconf/Makefile.am | 2 +- autoconf/Makefile.msc | 9 +++++++++ autoconf/configure.ac | 12 ++++++++++++ configure | 44 +++++++++++++++++++++++++++++-------------- configure.ac | 10 ++++++++++ manifest | 29 +++++++++++++++------------- manifest.uuid | 2 +- test/releasetest.tcl | 7 +++++-- 10 files changed, 93 insertions(+), 32 deletions(-) diff --git a/Makefile.in b/Makefile.in index e4687626f0..78480de9e0 100644 --- a/Makefile.in +++ b/Makefile.in @@ -82,7 +82,6 @@ TEMP_STORE = -DSQLITE_TEMP_STORE=@TEMP_STORE@ # The same set of OMIT and ENABLE flags should be passed to the # LEMON parser generator and the mkkeywordhash tool as well. OPT_FEATURE_FLAGS = @OPT_FEATURE_FLAGS@ -OPT_FEATURE_FLAGS += -DSQLITE_ENABLE_SESSION -DSQLITE_ENABLE_PREUPDATE_HOOK TCC += $(OPT_FEATURE_FLAGS) diff --git a/Makefile.msc b/Makefile.msc index e65f99d758..3eb50c1eae 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -264,6 +264,15 @@ SQLITE3EXEPDB = /pdb:sqlite3sh.pdb OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_FTS3=1 OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_RTREE=1 OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_COLUMN_METADATA=1 +!ENDIF + +# Enable support for the session extension if the SESSION=1 argument is +# present on the nmake command-line +# +!IFNDEF SESSION +SESSION = 0 +!ENDIF +!IF $(SESSION)!=0 OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_SESSION=1 OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_PREUPDATE_HOOK=1 !ENDIF diff --git a/autoconf/Makefile.am b/autoconf/Makefile.am index cca23ba67d..e8211596d9 100644 --- a/autoconf/Makefile.am +++ b/autoconf/Makefile.am @@ -1,5 +1,5 @@ -AM_CFLAGS = @THREADSAFE_FLAGS@ @DYNAMIC_EXTENSION_FLAGS@ @FTS5_FLAGS@ @JSON1_FLAGS@ -DSQLITE_ENABLE_FTS3 -DSQLITE_ENABLE_RTREE +AM_CFLAGS = @THREADSAFE_FLAGS@ @DYNAMIC_EXTENSION_FLAGS@ @FTS5_FLAGS@ @JSON1_FLAGS@ @SESSION_FLAGS@ -DSQLITE_ENABLE_FTS3 -DSQLITE_ENABLE_RTREE lib_LTLIBRARIES = libsqlite3.la libsqlite3_la_SOURCES = sqlite3.c diff --git a/autoconf/Makefile.msc b/autoconf/Makefile.msc index ed99ce9587..dcb69dab06 100644 --- a/autoconf/Makefile.msc +++ b/autoconf/Makefile.msc @@ -249,6 +249,15 @@ SQLITE3EXEPDB = /pdb:sqlite3sh.pdb OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_FTS3=1 OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_RTREE=1 OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_COLUMN_METADATA=1 +!ENDIF + +# Enable support for the session extension if the SESSION=1 argument is +# present on the nmake command-line +# +!IFNDEF SESSION +SESSION = 0 +!ENDIF +!IF $(SESSION)!=0 OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_SESSION=1 OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_PREUPDATE_HOOK=1 !ENDIF diff --git a/autoconf/configure.ac b/autoconf/configure.ac index f86a39c37b..d1fe50603f 100644 --- a/autoconf/configure.ac +++ b/autoconf/configure.ac @@ -122,6 +122,18 @@ fi AC_SUBST(JSON1_FLAGS) #----------------------------------------------------------------------- +#----------------------------------------------------------------------- +# --enable-session +# +AC_ARG_ENABLE(session, [AS_HELP_STRING( + [--enable-session], [enable the session extension [default=no]])], + [], [enable_session=no]) +if test x"$enable_session" == "xyes"; then + SESSION_FLAGS="-DSQLITE_ENABLE_SESSION -DSQLITE_ENABLE_PREUPDATE_HOOK" +fi +AC_SUBST(SESSION_FLAGS) +#----------------------------------------------------------------------- + #----------------------------------------------------------------------- # --enable-static-shell # diff --git a/configure b/configure index 27cb1ea0b9..3b746fedbb 100755 --- a/configure +++ b/configure @@ -908,6 +908,7 @@ enable_fts4 enable_fts5 enable_json1 enable_rtree +enable_session enable_gcov ' ac_precious_vars='build_alias @@ -1556,6 +1557,7 @@ Optional Features: --enable-fts5 Enable the FTS5 extension --enable-json1 Enable the JSON1 extension --enable-rtree Enable the RTREE extension + --enable-session Enable the SESSION extension --enable-gcov Enable coverage testing using gcov Optional Packages: @@ -3923,13 +3925,13 @@ if ${lt_cv_nm_interface+:} false; then : else lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext - (eval echo "\"\$as_me:3926: $ac_compile\"" >&5) + (eval echo "\"\$as_me:3928: $ac_compile\"" >&5) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&5 - (eval echo "\"\$as_me:3929: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval echo "\"\$as_me:3931: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&5 - (eval echo "\"\$as_me:3932: output\"" >&5) + (eval echo "\"\$as_me:3934: output\"" >&5) cat conftest.out >&5 if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" @@ -5135,7 +5137,7 @@ ia64-*-hpux*) ;; *-*-irix6*) # Find out which ABI we are using. - echo '#line 5138 "configure"' > conftest.$ac_ext + echo '#line 5140 "configure"' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? @@ -6660,11 +6662,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:6663: $lt_compile\"" >&5) + (eval echo "\"\$as_me:6665: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:6667: \$? = $ac_status" >&5 + echo "$as_me:6669: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -6999,11 +7001,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7002: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7004: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:7006: \$? = $ac_status" >&5 + echo "$as_me:7008: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -7104,11 +7106,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7107: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7109: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:7111: \$? = $ac_status" >&5 + echo "$as_me:7113: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -7159,11 +7161,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7162: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7164: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:7166: \$? = $ac_status" >&5 + echo "$as_me:7168: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -9539,7 +9541,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 9542 "configure" +#line 9544 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -9635,7 +9637,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 9638 "configure" +#line 9640 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -11494,6 +11496,20 @@ if test "${enable_rtree}" = "yes" ; then OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_RTREE" fi +######### +# See whether we should enable the SESSION extension +# Check whether --enable-session was given. +if test "${enable_session+set}" = set; then : + enableval=$enable_session; enable_session=yes +else + enable_session=no +fi + +if test "${enable_session}" = "yes" ; then + OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_SESSION" + OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_PREUPDATE_HOOK" +fi + ######### # attempt to duplicate any OMITS and ENABLES into the $(OPT_FEATURE_FLAGS) parameter for option in $CFLAGS $CPPFLAGS diff --git a/configure.ac b/configure.ac index 08c8867f06..2c97885ade 100644 --- a/configure.ac +++ b/configure.ac @@ -615,6 +615,16 @@ if test "${enable_rtree}" = "yes" ; then OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_RTREE" fi +######### +# See whether we should enable the SESSION extension +AC_ARG_ENABLE(session, AC_HELP_STRING([--enable-session], + [Enable the SESSION extension]), + [enable_session=yes],[enable_session=no]) +if test "${enable_session}" = "yes" ; then + OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_SESSION" + OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_PREUPDATE_HOOK" +fi + ######### # attempt to duplicate any OMITS and ENABLES into the $(OPT_FEATURE_FLAGS) parameter for option in $CFLAGS $CPPFLAGS diff --git a/manifest b/manifest index 27faecd64e..5a2a7dcf1e 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -C Avoid\sleft-shifts\sof\ssigned\sintegers. -D 2016-05-03T00:04:55.196 -F Makefile.in 9e816d0323e418fbc0f8b2c05fc14e0b3763d9e8 +C Turn\sthe\ssession\sextension\soff\sby\sdefault.\s\sEnable\susing\s--enable-session\son\nconfigure\sscripts,\sor\susing\sthe\sSESSION=1\sargument\sto\snmake\son\sWindows. +D 2016-05-03T13:14:18.288 +F Makefile.in 9eda6e1c90d05c199c3ec8a7069b0682ad307657 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 -F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 +F Makefile.msc a7f34be67d16284e4208370365a9728094861194 F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7 F VERSION 5d234da9b5dae329fab75ff75884cfe0a9cb3fda F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 @@ -10,11 +10,11 @@ F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 -F autoconf/Makefile.am 42f7eb1fb2b06ddd6c6adab3e4388cc0a237ba40 -F autoconf/Makefile.msc dc0d0500e4a827cb3891d08d846dd6dd40241b51 +F autoconf/Makefile.am 1a47d071e3d5435f8f7ebff7eb6703848bbd65d4 +F autoconf/Makefile.msc ac014aab0b8314d6baa30cbd1dd4ce983f306b5d F autoconf/README.first 6c4f34fe115ff55d4e8dbfa3cecf04a0188292f7 F autoconf/README.txt 4f04b0819303aabaa35fff5f7b257fb0c1ef95f1 -F autoconf/configure.ac d807b567f73a2b0986ccdd206b782cecb4d08fff +F autoconf/configure.ac e2299fe80eb256dafdc68cf250e37ea1a0a6ec71 F autoconf/tea/Makefile.in b438a7020446c8a8156e8d97c8914a04833da6fd F autoconf/tea/README 3e9a3c060f29a44344ab50aec506f4db903fb873 F autoconf/tea/aclocal.m4 52c47aac44ce0ddb1f918b6993e8beb8eee88f43 @@ -30,8 +30,8 @@ F autoconf/tea/win/rules.vc c511f222b80064096b705dbeb97060ee1d6b6d63 F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977 F config.h.in 6376abec766e9a0785178b1823b5a587e9f1ccbc F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55 -F configure dbd42c55ca6b65e0fb37ef54121755f26a890edf x -F configure.ac 89e4e02a83d8a1528011f8395621b8c3186b4089 +F configure df9f793ad47eaeb3648a9090fbc0b96955e88b5a x +F configure.ac 02b972db825685b4b0cca0234b2aa97f71bd15a5 F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad F doc/lemon.html e2118945e5f07ed146b45c9cd2b2dd6eabb8ebf2 F doc/pager-invariants.txt 27fed9a70ddad2088750c4a2b493b63853da2710 @@ -998,7 +998,7 @@ F test/rdonly.test 64e2696c322e3538df0b1ed624e21f9a23ed9ff8 F test/regexp1.test 497ea812f264d12b6198d6e50a76be4a1973a9d8 F test/regexp2.test aa7ffcc21350007a78361b82bcf3b74d12227144 F test/reindex.test 44edd3966b474468b823d481eafef0c305022254 -F test/releasetest.tcl f2519836bebefcc7db36b4946e8028d4885baa59 +F test/releasetest.tcl 7d80014d0245b3f9d02d393d420bf03ca155aec0 F test/resolver01.test f4022acafda7f4d40eca94dbf16bc5fc4ac30ceb F test/rollback.test 458fe73eb3ffdfdf9f6ba3e9b7350a6220414dea F test/rollback2.test 8435d6ff0f13f51d2a4181c232e706005fa90fc5 @@ -1486,7 +1486,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 5830cf72e9e870830d088399f1ccb03ed6522582 -R 350580348db69c537adc1a64222fc40a +P 0715ce164333e27671efbec8796f238df98cc287 +R b2e26094738bdcbd727f209d6b0330cd +T *branch * session-make +T *sym-session-make * +T -sym-trunk * U drh -Z 10c9aec7cf14a46e7039005f7f038452 +Z 7002cda7adeb2152eae684546f496804 diff --git a/manifest.uuid b/manifest.uuid index 9202d19d19..deb3ca1f64 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0715ce164333e27671efbec8796f238df98cc287 \ No newline at end of file +e462cde2a50c39cc2f8d8624aada19280b8226eb \ No newline at end of file diff --git a/test/releasetest.tcl b/test/releasetest.tcl index 15f64e3218..2961fc385d 100644 --- a/test/releasetest.tcl +++ b/test/releasetest.tcl @@ -51,10 +51,12 @@ array set ::Configs [strip_comments { "Default" { -O2 --disable-amalgamation --disable-shared + --enable-session } "Sanitize" { CC=clang -fsanitize=undefined -DSQLITE_ENABLE_STAT4 + --enable-session } "Have-Not" { # The "Have-Not" configuration sets all possible -UHAVE_feature options @@ -106,7 +108,7 @@ array set ::Configs [strip_comments { -DSQLITE_ENABLE_OVERSIZE_CELL_CHECK=1 -DSQLITE_ENABLE_STAT4 -DSQLITE_ENABLE_STMT_SCANSTATUS - --enable-json1 --enable-fts5 + --enable-json1 --enable-fts5 --enable-session } "Debug-One" { --disable-shared @@ -132,6 +134,7 @@ array set ::Configs [strip_comments { -DSQLITE_ENABLE_RBU -DSQLITE_MAX_ATTACHED=125 -DLONGDOUBLE_TYPE=double + --enable-session } "Device-One" { -O2 @@ -168,7 +171,7 @@ array set ::Configs [strip_comments { -DSQLITE_OMIT_TRACE=1 -DSQLITE_TEMP_STORE=3 -DSQLITE_THREADSAFE=2 - --enable-json1 --enable-fts5 + --enable-json1 --enable-fts5 --enable-session } "Locking-Style" { -O2 From 1b361ff381a9ff50134edbe370714c9c5849649c Mon Sep 17 00:00:00 2001 From: mistachkin Date: Tue, 3 May 2016 19:36:54 +0000 Subject: [PATCH 0379/1484] Add the experimental SQLITE_FCNTL_WIN32_GET_HANDLE file control. FossilOrigin-Name: b6ddabe1818c36007c476a31e2e35755630a5f14 --- manifest | 24 +++++++++++++----------- manifest.uuid | 2 +- src/os_win.c | 6 ++++++ src/sqlite.h.in | 7 +++++++ src/test1.c | 33 +++++++++++++++++++++++++++++++++ test/filectrl.test | 26 ++++++++++++++++++++++++++ 6 files changed, 86 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 59f321b3e0..4515b68c62 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C The\ssession\sextension\sis\sdisabled\sby\sdefault.\s\sTo\senable\sit\susing\n--enable-session\son\s./configure\son\sunix\sand\sadd\sSESSION=1\sto\sthe\snmake\non\sWindows.\s\sOr\sadd\s-DSQLITE_ENABLE_SESSION\sand\n-DSQLITE_ENABLE_PREUPDATE_HOOK\sto\sbuild\smanually. -D 2016-05-03T14:57:07.139 +C Add\sthe\sexperimental\sSQLITE_FCNTL_WIN32_GET_HANDLE\sfile\scontrol. +D 2016-05-03T19:36:54.758 F Makefile.in 9eda6e1c90d05c199c3ec8a7069b0682ad307657 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a7f34be67d16284e4208370365a9728094861194 @@ -362,7 +362,7 @@ F src/os.h 8e976e59eb4ca1c0fca6d35ee803e38951cb0343 F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85 F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa F src/os_unix.c a9443cdab41d7f3cdf0df3a5aab62fd6e1c9b234 -F src/os_win.c 852fc2ff6084296348ed3739c548b2cf32df394e +F src/os_win.c 75edd38c5efbb177cbfdce7128635a2bb53cf16c F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c a8d30c49c231e9a20d05257613db922532588963 F src/pager.h 329bdf078a4e0a3b35084534d58625d21fd03681 @@ -379,7 +379,7 @@ F src/resolve.c b8f7174e5f8c33c44ded3a25a973d0bb89228c20 F src/rowset.c 49eb91c588a2bab36647368e031dc5b66928149d F src/select.c fd4a7ce2937497181063cfedb92058ac89491a5d F src/shell.c 14ff7f660530a52b117d110ba3390b7b2eb719b6 -F src/sqlite.h.in 9984129d86243424b765fcb3f147c697bd20bb54 +F src/sqlite.h.in 07a295a39a41cfd136bf63bdcfe478caaee78042 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 98f72cbfe00169c39089115427d06ea05fe4b4a2 F src/sqliteInt.h f4a53f3547dab80dc7db975fa1192d9bad1f38e8 @@ -387,7 +387,7 @@ F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 F src/tclsqlite.c 9c4c4589d078de37813ded708d8838b338ffb060 -F src/test1.c c0e5b69f99e95a2c9f55fdb6e46b44f1a15292d8 +F src/test1.c 7862c314d742153639ecb6ec2daf29936cc066cd F src/test2.c 5586f43fcd9a1be0830793cf9d354082c261b25b F src/test3.c 0df6f8dbb4cbaa7106397c70a271fa6a43659042 F src/test4.c d168f83cc78d02e8d35567bb5630e40dcd85ac1e @@ -664,7 +664,7 @@ F test/expr.test 79c3e7502d9e571553b85f0ecc8ff2ac7d0e4931 F test/extension01.test 00d13cec817f331a687a243e0e5a2d87b0e358c9 F test/extraquick.test cb254400bd42bfb777ff675356aabf3287978f79 F test/fallocate.test 3e979af17dfa7e5e9dda5eba1a696c04fa9d47f7 -F test/filectrl.test 7c13f96457435238da99aff7343ad6a3a4885787 +F test/filectrl.test c6547e6c3c4c3ef9707a0b3dc147de718135cacc F test/filefmt.test e4edbdc637ca9576ccf4337a3cce627d9df7a56c F test/fkey1.test 13e3d48236a2b9f5c5ebd232eef9b3ab682a8a2c F test/fkey2.test f3d27ecba480a348c328965d154214719bb158a9 @@ -1486,8 +1486,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 0715ce164333e27671efbec8796f238df98cc287 e462cde2a50c39cc2f8d8624aada19280b8226eb -R b2e26094738bdcbd727f209d6b0330cd -T +closed e462cde2a50c39cc2f8d8624aada19280b8226eb -U drh -Z be2a8ff6db06dcbc7ab32e285c183e7e +P bcaa650e8796984b275eceba0ed477f360295d01 +R 7e9bbb4137cb671c555aabb8a094cd9b +T *branch * win32GetHandle +T *sym-win32GetHandle * +T -sym-trunk * +U mistachkin +Z e75ba582b3d5fa180704c51e0604373b diff --git a/manifest.uuid b/manifest.uuid index 2c0b2458e8..41938f059b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bcaa650e8796984b275eceba0ed477f360295d01 \ No newline at end of file +b6ddabe1818c36007c476a31e2e35755630a5f14 \ No newline at end of file diff --git a/src/os_win.c b/src/os_win.c index 9a34d9a106..1027e1fa81 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -3434,6 +3434,12 @@ static int winFileControl(sqlite3_file *id, int op, void *pArg){ OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); return SQLITE_OK; } + case SQLITE_FCNTL_WIN32_GET_HANDLE: { + LPHANDLE phFile = (LPHANDLE)pArg; + *phFile = pFile->h; + OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); + return SQLITE_OK; + } #ifdef SQLITE_TEST case SQLITE_FCNTL_WIN32_SET_HANDLE: { LPHANDLE phFile = (LPHANDLE)pArg; diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 795236f587..de5275a14f 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -966,6 +966,12 @@ struct sqlite3_io_methods { ** on whether or not the file has been renamed, moved, or deleted since it ** was first opened. ** +**
  • [[SQLITE_FCNTL_WIN32_GET_HANDLE]] +** The [SQLITE_FCNTL_WIN32_GET_HANDLE] opcode can be used to obtain the +** underlying native file handle associated with a file handle. This file +** control interprets its argument as a pointer to a native file handle and +** writes the resulting value there. +** **
  • [[SQLITE_FCNTL_WIN32_SET_HANDLE]] ** The [SQLITE_FCNTL_WIN32_SET_HANDLE] opcode is used for debugging. This ** opcode causes the xFileControl method to swap the file handle with the one @@ -1016,6 +1022,7 @@ struct sqlite3_io_methods { #define SQLITE_FCNTL_RBU 26 #define SQLITE_FCNTL_VFS_POINTER 27 #define SQLITE_FCNTL_JOURNAL_POINTER 28 +#define SQLITE_FCNTL_WIN32_GET_HANDLE 29 /* deprecated names */ #define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE diff --git a/src/test1.c b/src/test1.c index ee71b854b9..a0f2c55776 100644 --- a/src/test1.c +++ b/src/test1.c @@ -5482,6 +5482,38 @@ static int file_control_win32_av_retry( return TCL_OK; } +/* +** tclcmd: file_control_win32_get_handle DB +** +** This TCL command runs the sqlite3_file_control interface with +** the SQLITE_FCNTL_WIN32_GET_HANDLE opcode. +*/ +static int file_control_win32_get_handle( + ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ + Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ + int objc, /* Number of arguments */ + Tcl_Obj *CONST objv[] /* Command arguments */ +){ + sqlite3 *db; + int rc; + HANDLE hFile = NULL; + char z[100]; + + if( objc!=2 ){ + Tcl_AppendResult(interp, "wrong # args: should be \"", + Tcl_GetStringFromObj(objv[0], 0), " DB", 0); + return TCL_ERROR; + } + if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){ + return TCL_ERROR; + } + rc = sqlite3_file_control(db, NULL, SQLITE_FCNTL_WIN32_GET_HANDLE, + (void*)&hFile); + sqlite3_snprintf(sizeof(z), z, "%d %p", rc, (void*)hFile); + Tcl_AppendResult(interp, z, (char*)0); + return TCL_OK; +} + /* ** tclcmd: file_control_win32_set_handle DB HANDLE ** @@ -7214,6 +7246,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){ { "file_control_sizehint_test", file_control_sizehint_test, 0 }, #if SQLITE_OS_WIN { "file_control_win32_av_retry", file_control_win32_av_retry, 0 }, + { "file_control_win32_get_handle", file_control_win32_get_handle, 0 }, { "file_control_win32_set_handle", file_control_win32_set_handle, 0 }, #endif { "file_control_persist_wal", file_control_persist_wal, 0 }, diff --git a/test/filectrl.test b/test/filectrl.test index 28fecee92f..cb46994145 100644 --- a/test/filectrl.test +++ b/test/filectrl.test @@ -43,4 +43,30 @@ do_test filectrl-1.6 { } {/etilqs_/} db close forcedelete .test_control_lockproxy.db-conch test.proxy +forcedelete test.db test2.db + +if {$tcl_platform(platform)=="windows"} { + do_test filectrl-2.1 { + sqlite3 db test2.db + set size [file size test2.db] + set handle [file_control_win32_get_handle db] + db close + forcedelete test2.db + list $size $handle [expr {$handle != 0}] + } {/^0 \{0 \d+\} 1$/} + + do_test filectrl-2.2 { + sqlite3 db test2.db + execsql { + CREATE TABLE t1(x); + INSERT INTO t1 (x) VALUES(RANDOMBLOB(1048576)); + } + set size [file size test2.db] + set handle [file_control_win32_get_handle db] + db close + forcedelete test2.db + list $size $handle [expr {$handle != 0}] + } {/^1\d+ \{0 \d+\} 1$/} +} + finish_test From 12b35ea980c777c5c76f7e528567d799f8eade9c Mon Sep 17 00:00:00 2001 From: mistachkin Date: Tue, 3 May 2016 19:40:54 +0000 Subject: [PATCH 0380/1484] Minor style tweaks in the MSVC makefile. FossilOrigin-Name: 1b43358f8979c4f18519e824e0d5f6ef2250107c --- Makefile.msc | 13 ++++++++----- autoconf/Makefile.msc | 13 ++++++++----- manifest | 17 ++++++++--------- manifest.uuid | 2 +- 4 files changed, 25 insertions(+), 20 deletions(-) diff --git a/Makefile.msc b/Makefile.msc index 3eb50c1eae..bb9790d312 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -198,6 +198,12 @@ DEBUG = 0 OPTIMIZATIONS = 2 !ENDIF +# Set this to non-0 to enable support for the session extension. +# +!IFNDEF SESSION +SESSION = 0 +!ENDIF + # Set the source code file to be used by executables and libraries when # they need the amalgamation. # @@ -266,12 +272,9 @@ OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_RTREE=1 OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_COLUMN_METADATA=1 !ENDIF -# Enable support for the session extension if the SESSION=1 argument is -# present on the nmake command-line +# Should the session extension be enabled? If so, add compilation options +# to enable it. # -!IFNDEF SESSION -SESSION = 0 -!ENDIF !IF $(SESSION)!=0 OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_SESSION=1 OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_PREUPDATE_HOOK=1 diff --git a/autoconf/Makefile.msc b/autoconf/Makefile.msc index dcb69dab06..7f62bcb129 100644 --- a/autoconf/Makefile.msc +++ b/autoconf/Makefile.msc @@ -183,6 +183,12 @@ DEBUG = 0 OPTIMIZATIONS = 2 !ENDIF +# Set this to non-0 to enable support for the session extension. +# +!IFNDEF SESSION +SESSION = 0 +!ENDIF + # Set the source code file to be used by executables and libraries when # they need the amalgamation. # @@ -251,12 +257,9 @@ OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_RTREE=1 OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_COLUMN_METADATA=1 !ENDIF -# Enable support for the session extension if the SESSION=1 argument is -# present on the nmake command-line +# Should the session extension be enabled? If so, add compilation options +# to enable it. # -!IFNDEF SESSION -SESSION = 0 -!ENDIF !IF $(SESSION)!=0 OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_SESSION=1 OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_PREUPDATE_HOOK=1 diff --git a/manifest b/manifest index 59f321b3e0..b85ef558d9 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -C The\ssession\sextension\sis\sdisabled\sby\sdefault.\s\sTo\senable\sit\susing\n--enable-session\son\s./configure\son\sunix\sand\sadd\sSESSION=1\sto\sthe\snmake\non\sWindows.\s\sOr\sadd\s-DSQLITE_ENABLE_SESSION\sand\n-DSQLITE_ENABLE_PREUPDATE_HOOK\sto\sbuild\smanually. -D 2016-05-03T14:57:07.139 +C Minor\sstyle\stweaks\sin\sthe\sMSVC\smakefile. +D 2016-05-03T19:40:54.328 F Makefile.in 9eda6e1c90d05c199c3ec8a7069b0682ad307657 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 -F Makefile.msc a7f34be67d16284e4208370365a9728094861194 +F Makefile.msc db82b35aef27f412fef14d8534afc022138bcdfd F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7 F VERSION 5d234da9b5dae329fab75ff75884cfe0a9cb3fda F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 @@ -11,7 +11,7 @@ F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am 1a47d071e3d5435f8f7ebff7eb6703848bbd65d4 -F autoconf/Makefile.msc ac014aab0b8314d6baa30cbd1dd4ce983f306b5d +F autoconf/Makefile.msc 0eca137c12542bd76c253a2d24380f29ade59b95 F autoconf/README.first 6c4f34fe115ff55d4e8dbfa3cecf04a0188292f7 F autoconf/README.txt 4f04b0819303aabaa35fff5f7b257fb0c1ef95f1 F autoconf/configure.ac e2299fe80eb256dafdc68cf250e37ea1a0a6ec71 @@ -1486,8 +1486,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 0715ce164333e27671efbec8796f238df98cc287 e462cde2a50c39cc2f8d8624aada19280b8226eb -R b2e26094738bdcbd727f209d6b0330cd -T +closed e462cde2a50c39cc2f8d8624aada19280b8226eb -U drh -Z be2a8ff6db06dcbc7ab32e285c183e7e +P bcaa650e8796984b275eceba0ed477f360295d01 +R 962b079d2f6aa84ad32617180232ff75 +U mistachkin +Z 45ce4bc83f501da24480cd14c4b0de07 diff --git a/manifest.uuid b/manifest.uuid index 2c0b2458e8..1744b7bee1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bcaa650e8796984b275eceba0ed477f360295d01 \ No newline at end of file +1b43358f8979c4f18519e824e0d5f6ef2250107c \ No newline at end of file From c88ae52d868d8da91931ef3863e96ca661b4356d Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 4 May 2016 11:28:03 +0000 Subject: [PATCH 0381/1484] Disable the PagerDontWrite() optimization for temp tables. It can cause database corruption if a page passed to PagerDontWrite() is dirty at the start of a transaction that is subsequently rolled back. FossilOrigin-Name: 6341ab2ffef298ca16b323358afbea4a4c1fb0e1 --- manifest | 15 ++++----- manifest.uuid | 2 +- src/pager.c | 8 ++++- test/tempdb2.test | 77 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 93 insertions(+), 9 deletions(-) create mode 100644 test/tempdb2.test diff --git a/manifest b/manifest index b85ef558d9..0570c6e3af 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Minor\sstyle\stweaks\sin\sthe\sMSVC\smakefile. -D 2016-05-03T19:40:54.328 +C Disable\sthe\sPagerDontWrite()\soptimization\sfor\stemp\stables.\sIt\scan\scause\sdatabase\scorruption\sif\sa\spage\spassed\sto\sPagerDontWrite()\sis\sdirty\sat\sthe\sstart\sof\sa\stransaction\sthat\sis\ssubsequently\srolled\sback. +D 2016-05-04T11:28:03.301 F Makefile.in 9eda6e1c90d05c199c3ec8a7069b0682ad307657 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc db82b35aef27f412fef14d8534afc022138bcdfd @@ -364,7 +364,7 @@ F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa F src/os_unix.c a9443cdab41d7f3cdf0df3a5aab62fd6e1c9b234 F src/os_win.c 852fc2ff6084296348ed3739c548b2cf32df394e F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca -F src/pager.c a8d30c49c231e9a20d05257613db922532588963 +F src/pager.c c512873311087cd22372f2b076fc869e090e8e16 F src/pager.h 329bdf078a4e0a3b35084534d58625d21fd03681 F src/parse.y 10eb2f3fb62341291528c7984498054731f9d31e F src/pcache.c b3230ecfc7f797063fbe167f2845da363e8f07f8 @@ -1111,6 +1111,7 @@ F test/tableapi.test 2674633fa95d80da917571ebdd759a14d9819126 F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930 F test/tclsqlite.test e1306001a0ca92250b691ea6d3cecaca5b6342aa F test/tempdb.test bd92eba8f20e16a9136e434e20b280794de3cdb6 +F test/tempdb2.test 4fc92055f2a3f7626c0f2eabbb637dc021b311d5 F test/tempfault.test 0c0d349c9a99bf5f374655742577f8712c647900 F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30 F test/temptable2.test cd396beb41117a5302fff61767c35fa4270a0d5e @@ -1486,7 +1487,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P bcaa650e8796984b275eceba0ed477f360295d01 -R 962b079d2f6aa84ad32617180232ff75 -U mistachkin -Z 45ce4bc83f501da24480cd14c4b0de07 +P 1b43358f8979c4f18519e824e0d5f6ef2250107c +R ddb8134dc049c780758987466a2a1e86 +U dan +Z 527ddc60688e8fba4830106202c052a2 diff --git a/manifest.uuid b/manifest.uuid index 1744b7bee1..ae5eab176f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1b43358f8979c4f18519e824e0d5f6ef2250107c \ No newline at end of file +6341ab2ffef298ca16b323358afbea4a4c1fb0e1 \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index d24337cd50..8ef0492e57 100644 --- a/src/pager.c +++ b/src/pager.c @@ -6008,10 +6008,16 @@ int sqlite3PagerIswriteable(DbPage *pPg){ ** ** Tests show that this optimization can quadruple the speed of large ** DELETE operations. +** +** This optimization cannot be used with a temp-file, as the page may +** have been dirty at the start of the transaction. In that case, if +** memory pressure forces page pPg out of the cache, the data does need +** to be written out to disk so that it may be read back in if the +** current transaction is rolled back. */ void sqlite3PagerDontWrite(PgHdr *pPg){ Pager *pPager = pPg->pPager; - if( (pPg->flags&PGHDR_DIRTY) && pPager->nSavepoint==0 ){ + if( !pPager->tempFile && (pPg->flags&PGHDR_DIRTY) && pPager->nSavepoint==0 ){ PAGERTRACE(("DONT_WRITE page %d of %d\n", pPg->pgno, PAGERID(pPager))); IOTRACE(("CLEAN %p %d\n", pPager, pPg->pgno)) pPg->flags |= PGHDR_DONT_WRITE; diff --git a/test/tempdb2.test b/test/tempdb2.test new file mode 100644 index 0000000000..bc2822e71e --- /dev/null +++ b/test/tempdb2.test @@ -0,0 +1,77 @@ +# 2016 March 3 +# +# 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. +# +#*********************************************************************** + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix tempdb2 + +db close +sqlite3 db "" + +proc int2str {i} { string range [string repeat "$i." 450] 0 899 } +db func int2str int2str + +#------------------------------------------------------------------------- +# +# 1.1: Write a big transaction to the db. One so large that it forces +# the file to be created and the cache flushed to disk on COMMIT. +# +# 1.2: Write a small transaction - one small enough that it remains in +# memory on COMMIT. All the pages of table [t1] are now dirty. +# +# 1.3: Delete the contents of [t1]. This moves all of its leaves to the +# free-list and causes the btree layer to call PagerDontWrite() on +# each of them. +# +# Then do a big update on table [t2]. So big that the former leaves +# of [t1] are forced out of the cache. Then roll back the transaction. +# If the PagerDontWrite() calls are honoured and the data is not written +# to disk, the update made in test 1.2 will be lost at this point. Or, if +# they are ignored (as they should be for temp databases), the update +# will be safely written out to disk before the cache entries are +# discarded. +# +do_execsql_test 1.1 { + PRAGMA page_size=1024; + PRAGMA cache_size=50; + + BEGIN; + CREATE TABLE t1(a INTEGER PRIMARY KEY, b); + INSERT INTO t1 VALUES(1, int2str(1)); + INSERT INTO t1 VALUES(2, int2str(1)); + INSERT INTO t1 VALUES(3, int2str(1)); + + CREATE TABLE t2(a INTEGER PRIMARY KEY, b); + WITH c(x) AS ( VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<100 ) + INSERT INTO t2 SELECT x, int2str(x) FROM c; + COMMIT; + + PRAGMA lock_status; +} {main unlocked temp closed} + +do_execsql_test 1.2 { + UPDATE t1 SET b=int2str(2); + SELECT b=int2str(2) FROM t1 +} {1 1 1} + +do_execsql_test 1.3 { + BEGIN; + DELETE FROM t1; + UPDATE t2 SET b=int2str(a+1); + ROLLBACK; +} + +do_execsql_test 1.4 { + SELECT b=int2str(2) FROM t1 +} {1 1 1} + +finish_test + From 582c080289f2152eea2e0dc5ae33fff38a571e9f Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 4 May 2016 14:20:15 +0000 Subject: [PATCH 0382/1484] Portability enhancements to the configure script on the amalgamation tarball. FossilOrigin-Name: 7184c4b8869ffc00944abdd8d2c521cb11ea5824 --- autoconf/configure.ac | 8 ++++---- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/autoconf/configure.ac b/autoconf/configure.ac index d1fe50603f..6b37a0517a 100644 --- a/autoconf/configure.ac +++ b/autoconf/configure.ac @@ -103,7 +103,7 @@ AC_SUBST(DYNAMIC_EXTENSION_FLAGS) AC_ARG_ENABLE(fts5, [AS_HELP_STRING( [--enable-fts5], [include fts5 support [default=no]])], [], [enable_fts5=no]) -if test x"$enable_fts5" == "xyes"; then +if test x"$enable_fts5" = "xyes"; then AC_SEARCH_LIBS(log, m) FTS5_FLAGS=-DSQLITE_ENABLE_FTS5 fi @@ -116,7 +116,7 @@ AC_SUBST(FTS5_FLAGS) AC_ARG_ENABLE(json1, [AS_HELP_STRING( [--enable-json1], [include json1 support [default=no]])], [], [enable_json1=no]) -if test x"$enable_json1" == "xyes"; then +if test x"$enable_json1" = "xyes"; then JSON1_FLAGS=-DSQLITE_ENABLE_JSON1 fi AC_SUBST(JSON1_FLAGS) @@ -128,7 +128,7 @@ AC_SUBST(JSON1_FLAGS) AC_ARG_ENABLE(session, [AS_HELP_STRING( [--enable-session], [enable the session extension [default=no]])], [], [enable_session=no]) -if test x"$enable_session" == "xyes"; then +if test x"$enable_session" = "xyes"; then SESSION_FLAGS="-DSQLITE_ENABLE_SESSION -DSQLITE_ENABLE_PREUPDATE_HOOK" fi AC_SUBST(SESSION_FLAGS) @@ -141,7 +141,7 @@ AC_ARG_ENABLE(static-shell, [AS_HELP_STRING( [--enable-static-shell], [statically link libsqlite3 into shell tool [default=yes]])], [], [enable_static_shell=yes]) -if test x"$enable_static_shell" == "xyes"; then +if test x"$enable_static_shell" = "xyes"; then EXTRA_SHELL_OBJ=sqlite3-sqlite3.$OBJEXT else EXTRA_SHELL_OBJ=libsqlite3.la diff --git a/manifest b/manifest index 0570c6e3af..fc948d48f2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Disable\sthe\sPagerDontWrite()\soptimization\sfor\stemp\stables.\sIt\scan\scause\sdatabase\scorruption\sif\sa\spage\spassed\sto\sPagerDontWrite()\sis\sdirty\sat\sthe\sstart\sof\sa\stransaction\sthat\sis\ssubsequently\srolled\sback. -D 2016-05-04T11:28:03.301 +C Portability\senhancements\sto\sthe\sconfigure\sscript\son\sthe\samalgamation\starball. +D 2016-05-04T14:20:15.883 F Makefile.in 9eda6e1c90d05c199c3ec8a7069b0682ad307657 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc db82b35aef27f412fef14d8534afc022138bcdfd @@ -14,7 +14,7 @@ F autoconf/Makefile.am 1a47d071e3d5435f8f7ebff7eb6703848bbd65d4 F autoconf/Makefile.msc 0eca137c12542bd76c253a2d24380f29ade59b95 F autoconf/README.first 6c4f34fe115ff55d4e8dbfa3cecf04a0188292f7 F autoconf/README.txt 4f04b0819303aabaa35fff5f7b257fb0c1ef95f1 -F autoconf/configure.ac e2299fe80eb256dafdc68cf250e37ea1a0a6ec71 +F autoconf/configure.ac ad7001cdde3d6ae6053bc0b66009869d7c5012a8 F autoconf/tea/Makefile.in b438a7020446c8a8156e8d97c8914a04833da6fd F autoconf/tea/README 3e9a3c060f29a44344ab50aec506f4db903fb873 F autoconf/tea/aclocal.m4 52c47aac44ce0ddb1f918b6993e8beb8eee88f43 @@ -1487,7 +1487,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 1b43358f8979c4f18519e824e0d5f6ef2250107c -R ddb8134dc049c780758987466a2a1e86 -U dan -Z 527ddc60688e8fba4830106202c052a2 +P 6341ab2ffef298ca16b323358afbea4a4c1fb0e1 +R a3cd249f5ae281a2f2bd8ab97d7cb0bc +U drh +Z 6738ef2f38ef30f9c397b3159a787329 diff --git a/manifest.uuid b/manifest.uuid index ae5eab176f..341201e617 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6341ab2ffef298ca16b323358afbea4a4c1fb0e1 \ No newline at end of file +7184c4b8869ffc00944abdd8d2c521cb11ea5824 \ No newline at end of file From 91da70728092c246963b7521c51361e4d007f3cf Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 4 May 2016 14:45:30 +0000 Subject: [PATCH 0383/1484] Only disable the one-pass DELETE optimization if the WHERE clause contains a correlated subquery. Uncorrelated subqueries are allowed. This is a refinement of check-in [3f221f592a9a1] that is the fix for ticket [dc6ebeda9396087]. FossilOrigin-Name: aae389692a2ed2cc92151d51fb2cd5a16921c469 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/delete.c | 2 +- src/resolve.c | 1 + src/sqliteInt.h | 1 + 5 files changed, 12 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index fc948d48f2..a7d16f5cd6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Portability\senhancements\sto\sthe\sconfigure\sscript\son\sthe\samalgamation\starball. -D 2016-05-04T14:20:15.883 +C Only\sdisable\sthe\sone-pass\sDELETE\soptimization\sif\sthe\sWHERE\sclause\scontains\na\scorrelated\ssubquery.\s\sUncorrelated\ssubqueries\sare\sallowed.\s\sThis\sis\sa\nrefinement\sof\scheck-in\s[3f221f592a9a1]\sthat\sis\sthe\sfix\sfor\nticket\s[dc6ebeda9396087]. +D 2016-05-04T14:45:30.802 F Makefile.in 9eda6e1c90d05c199c3ec8a7069b0682ad307657 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc db82b35aef27f412fef14d8534afc022138bcdfd @@ -330,7 +330,7 @@ F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 60e135af364d777a9ab41c97e5e89cd224da6198 F src/date.c 1cc9fb516ec9932c6fd4d2a0d2f8bc4480145c39 F src/dbstat.c c845548d4346e606e2f2b7d2e714ace2b8a7dd1b -F src/delete.c 362f89f8e6783e672c4ab06b90fca0177f9a576d +F src/delete.c 3f16e7ceb9e5084b127e0a4e10a9b06ca66c0b2e F src/expr.c 8796c0739b2ad091e6779253f62aad6e767e2be1 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 4c0bd09e602b8ae8d36d81e31e4872d0b53c87bb @@ -375,14 +375,14 @@ F src/pragma.h 64c78a648751b9f4f297276c4eb7507b14b4628c F src/prepare.c 22df6171aec1d86904ed2ad30c2348a5748aa04e F src/printf.c 63e6fb12bbe702dd664dc3703776c090383a5a26 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 -F src/resolve.c b8f7174e5f8c33c44ded3a25a973d0bb89228c20 +F src/resolve.c cca3aa77b95706df5d635a2141a4d1de60ae6598 F src/rowset.c 49eb91c588a2bab36647368e031dc5b66928149d F src/select.c fd4a7ce2937497181063cfedb92058ac89491a5d F src/shell.c 14ff7f660530a52b117d110ba3390b7b2eb719b6 F src/sqlite.h.in 9984129d86243424b765fcb3f147c697bd20bb54 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 98f72cbfe00169c39089115427d06ea05fe4b4a2 -F src/sqliteInt.h f4a53f3547dab80dc7db975fa1192d9bad1f38e8 +F src/sqliteInt.h c8483dd77894a72d38a76b6251a4ac949a37d6e8 F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 @@ -1487,7 +1487,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 6341ab2ffef298ca16b323358afbea4a4c1fb0e1 -R a3cd249f5ae281a2f2bd8ab97d7cb0bc +P 7184c4b8869ffc00944abdd8d2c521cb11ea5824 +R 0a6e5fa4a5a2f4a10bd60c5e077cbc66 U drh -Z 6738ef2f38ef30f9c397b3159a787329 +Z 06351e9e2a2d525f9337b5a6815ea254 diff --git a/manifest.uuid b/manifest.uuid index 341201e617..f6fcd613ae 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7184c4b8869ffc00944abdd8d2c521cb11ea5824 \ No newline at end of file +aae389692a2ed2cc92151d51fb2cd5a16921c469 \ No newline at end of file diff --git a/src/delete.c b/src/delete.c index 258b39cc3e..06a016438c 100644 --- a/src/delete.c +++ b/src/delete.c @@ -374,7 +374,7 @@ void sqlite3DeleteFrom( #endif /* SQLITE_OMIT_TRUNCATE_OPTIMIZATION */ { u16 wcf = WHERE_ONEPASS_DESIRED|WHERE_DUPLICATES_OK; - if( pWhere && ExprHasProperty(pWhere, EP_Subquery) ) bComplex = 1; + if( sNC.ncFlags & NC_VarSelect ) bComplex = 1; wcf |= (bComplex ? 0 : WHERE_ONEPASS_MULTIROW); if( HasRowid(pTab) ){ /* For a rowid table, initialize the RowSet to an empty set */ diff --git a/src/resolve.c b/src/resolve.c index 8e290af123..77ce37f6d7 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -763,6 +763,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ assert( pNC->nRef>=nRef ); if( nRef!=pNC->nRef ){ ExprSetProperty(pExpr, EP_VarSelect); + pNC->ncFlags |= NC_VarSelect; } } break; diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 76bf809624..783f0f56c3 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2597,6 +2597,7 @@ struct NameContext { #define NC_InAggFunc 0x0008 /* True if analyzing arguments to an agg func */ #define NC_HasAgg 0x0010 /* One or more aggregate functions seen */ #define NC_IdxExpr 0x0020 /* True if resolving columns of CREATE INDEX */ +#define NC_VarSelect 0x0040 /* A correlated subquery has been seen */ #define NC_MinMaxAgg 0x1000 /* min/max aggregates seen. See note above */ /* From 9fe3fbbc3522fd4683af2664db008bcde3e733e6 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Wed, 4 May 2016 19:04:20 +0000 Subject: [PATCH 0384/1484] Fix typo in comment. No changes to code. FossilOrigin-Name: 6c43ba1c8753a4029e127078652f265c408a01c0 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/delete.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index a7d16f5cd6..6d5d323836 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Only\sdisable\sthe\sone-pass\sDELETE\soptimization\sif\sthe\sWHERE\sclause\scontains\na\scorrelated\ssubquery.\s\sUncorrelated\ssubqueries\sare\sallowed.\s\sThis\sis\sa\nrefinement\sof\scheck-in\s[3f221f592a9a1]\sthat\sis\sthe\sfix\sfor\nticket\s[dc6ebeda9396087]. -D 2016-05-04T14:45:30.802 +C Fix\stypo\sin\scomment.\s\sNo\schanges\sto\scode. +D 2016-05-04T19:04:20.094 F Makefile.in 9eda6e1c90d05c199c3ec8a7069b0682ad307657 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc db82b35aef27f412fef14d8534afc022138bcdfd @@ -330,7 +330,7 @@ F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 60e135af364d777a9ab41c97e5e89cd224da6198 F src/date.c 1cc9fb516ec9932c6fd4d2a0d2f8bc4480145c39 F src/dbstat.c c845548d4346e606e2f2b7d2e714ace2b8a7dd1b -F src/delete.c 3f16e7ceb9e5084b127e0a4e10a9b06ca66c0b2e +F src/delete.c 912908dea57778737d4bab632f00e48b550d10ea F src/expr.c 8796c0739b2ad091e6779253f62aad6e767e2be1 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 4c0bd09e602b8ae8d36d81e31e4872d0b53c87bb @@ -1487,7 +1487,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 7184c4b8869ffc00944abdd8d2c521cb11ea5824 -R 0a6e5fa4a5a2f4a10bd60c5e077cbc66 -U drh -Z 06351e9e2a2d525f9337b5a6815ea254 +P aae389692a2ed2cc92151d51fb2cd5a16921c469 +R 7eec09085d0724a070665f564c0beb44 +U mistachkin +Z d55bbbb1bc35091ae5bebd4e60554f06 diff --git a/manifest.uuid b/manifest.uuid index f6fcd613ae..1471b0ed2d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -aae389692a2ed2cc92151d51fb2cd5a16921c469 \ No newline at end of file +6c43ba1c8753a4029e127078652f265c408a01c0 \ No newline at end of file diff --git a/src/delete.c b/src/delete.c index 06a016438c..dab1fd40cd 100644 --- a/src/delete.c +++ b/src/delete.c @@ -239,7 +239,7 @@ void sqlite3DeleteFrom( int addrBypass = 0; /* Address of jump over the delete logic */ int addrLoop = 0; /* Top of the delete loop */ int addrEphOpen = 0; /* Instruction to open the Ephemeral table */ - int bComplex; /* True if there are triggers or FKs or or + int bComplex; /* True if there are triggers or FKs or ** subqueries in the WHERE clause */ #ifndef SQLITE_OMIT_TRIGGER From 4e80d5fcf1e05bb1d81a9acf02d74fc16ab79b9f Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 4 May 2016 21:06:21 +0000 Subject: [PATCH 0385/1484] Disable the session extension API if SQLITE_ENABLE_SESSION is not defined. FossilOrigin-Name: 71af9ac165ac02272f4886f69bd9ab4770fd7bb6 --- ext/session/sqlite3session.h | 4 ++-- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/ext/session/sqlite3session.h b/ext/session/sqlite3session.h index 71f02159cf..23d9a33aef 100644 --- a/ext/session/sqlite3session.h +++ b/ext/session/sqlite3session.h @@ -1,5 +1,5 @@ -#ifndef __SQLITESESSION_H_ +#if !defined(__SQLITESESSION_H_) && defined(SQLITE_ENABLE_SESSION) #define __SQLITESESSION_H_ 1 /* @@ -1274,4 +1274,4 @@ int sqlite3changegroup_output_strm(sqlite3_changegroup*, } #endif -#endif /* SQLITE_ENABLE_SESSION && SQLITE_ENABLE_PREUPDATE_HOOK */ +#endif /* !defined(__SQLITESESSION_H_) && defined(SQLITE_ENABLE_SESSION) */ diff --git a/manifest b/manifest index 6d5d323836..12eedad414 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\stypo\sin\scomment.\s\sNo\schanges\sto\scode. -D 2016-05-04T19:04:20.094 +C Disable\sthe\ssession\sextension\sAPI\sif\sSQLITE_ENABLE_SESSION\sis\snot\sdefined. +D 2016-05-04T21:06:21.506 F Makefile.in 9eda6e1c90d05c199c3ec8a7069b0682ad307657 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc db82b35aef27f412fef14d8534afc022138bcdfd @@ -294,7 +294,7 @@ F ext/session/session_common.tcl a1293167d14774b5e728836720497f40fe4ea596 F ext/session/sessionfault.test da273f2712b6411e85e71465a1733b8501dbf6f7 F ext/session/sessionfault2.test 04aa0bc9aa70ea43d8de82c4f648db4de1e990b0 F ext/session/sqlite3session.c 37485891b4add26cf61495df193c419f36556a32 -F ext/session/sqlite3session.h 64e9e7f185725ef43b97f4a9a0c0df0669844f1d +F ext/session/sqlite3session.h 69bf73cfd71e58f2ae5d2aa935b2c1a541aee555 F ext/session/test_session.c 464f2c8bf502795d95969387eb8e93f68c513c15 F ext/userauth/sqlite3userauth.h 19cb6f0e31316d0ee4afdfb7a85ef9da3333a220 F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04 @@ -1487,7 +1487,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P aae389692a2ed2cc92151d51fb2cd5a16921c469 -R 7eec09085d0724a070665f564c0beb44 -U mistachkin -Z d55bbbb1bc35091ae5bebd4e60554f06 +P 6c43ba1c8753a4029e127078652f265c408a01c0 +R a7d4cc11d472462953b7d84c093e9aa1 +U drh +Z c3eb846652f8b95f225fc6721b0d9cb4 diff --git a/manifest.uuid b/manifest.uuid index 1471b0ed2d..32ae23744e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6c43ba1c8753a4029e127078652f265c408a01c0 \ No newline at end of file +71af9ac165ac02272f4886f69bd9ab4770fd7bb6 \ No newline at end of file From ad5a9d715f247e72274e91f10ece95cfff3d74fc Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 5 May 2016 11:53:12 +0000 Subject: [PATCH 0386/1484] Renumber internal constants in the printf() implemention for a small performance improvement. FossilOrigin-Name: 69d11447f4b1a8c536c3b6573d2a3419da870412 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/printf.c | 36 ++++++++++++++++++------------------ 3 files changed, 25 insertions(+), 25 deletions(-) diff --git a/manifest b/manifest index 12eedad414..8e5f6ffbdc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Disable\sthe\ssession\sextension\sAPI\sif\sSQLITE_ENABLE_SESSION\sis\snot\sdefined. -D 2016-05-04T21:06:21.506 +C Renumber\sinternal\sconstants\sin\sthe\sprintf()\simplemention\sfor\sa\ssmall\nperformance\simprovement. +D 2016-05-05T11:53:12.439 F Makefile.in 9eda6e1c90d05c199c3ec8a7069b0682ad307657 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc db82b35aef27f412fef14d8534afc022138bcdfd @@ -373,7 +373,7 @@ F src/pcache1.c 7f51d2b541aab57596adf62db2c4bb025d34f04d F src/pragma.c faf42922bb7ab2f6672cb550356c1967abae3c84 F src/pragma.h 64c78a648751b9f4f297276c4eb7507b14b4628c F src/prepare.c 22df6171aec1d86904ed2ad30c2348a5748aa04e -F src/printf.c 63e6fb12bbe702dd664dc3703776c090383a5a26 +F src/printf.c a5f0ca08ddede803c241266abb46356ec748ded1 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c cca3aa77b95706df5d635a2141a4d1de60ae6598 F src/rowset.c 49eb91c588a2bab36647368e031dc5b66928149d @@ -1487,7 +1487,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 6c43ba1c8753a4029e127078652f265c408a01c0 -R a7d4cc11d472462953b7d84c093e9aa1 +P 71af9ac165ac02272f4886f69bd9ab4770fd7bb6 +R 89655379113728f544ce9a18ad294b0b U drh -Z c3eb846652f8b95f225fc6721b0d9cb4 +Z f65addcdc03169dedb02067b28293d6c diff --git a/manifest.uuid b/manifest.uuid index 32ae23744e..4a4e62d8ed 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -71af9ac165ac02272f4886f69bd9ab4770fd7bb6 \ No newline at end of file +69d11447f4b1a8c536c3b6573d2a3419da870412 \ No newline at end of file diff --git a/src/printf.c b/src/printf.c index 238997f37d..a888d50b94 100644 --- a/src/printf.c +++ b/src/printf.c @@ -15,26 +15,26 @@ ** Conversion types fall into various categories as defined by the ** following enumeration. */ -#define etRADIX 1 /* Integer types. %d, %x, %o, and so forth */ -#define etFLOAT 2 /* Floating point. %f */ -#define etEXP 3 /* Exponentional notation. %e and %E */ -#define etGENERIC 4 /* Floating or exponential, depending on exponent. %g */ -#define etSIZE 5 /* Return number of characters processed so far. %n */ -#define etSTRING 6 /* Strings. %s */ -#define etDYNSTRING 7 /* Dynamically allocated strings. %z */ -#define etPERCENT 8 /* Percent symbol. %% */ -#define etCHARX 9 /* Characters. %c */ +#define etRADIX 0 /* Integer types. %d, %x, %o, and so forth */ +#define etFLOAT 1 /* Floating point. %f */ +#define etEXP 2 /* Exponentional notation. %e and %E */ +#define etGENERIC 3 /* Floating or exponential, depending on exponent. %g */ +#define etSIZE 4 /* Return number of characters processed so far. %n */ +#define etSTRING 5 /* Strings. %s */ +#define etDYNSTRING 6 /* Dynamically allocated strings. %z */ +#define etPERCENT 7 /* Percent symbol. %% */ +#define etCHARX 8 /* Characters. %c */ /* The rest are extensions, not normally found in printf() */ -#define etSQLESCAPE 10 /* Strings with '\'' doubled. %q */ -#define etSQLESCAPE2 11 /* Strings with '\'' doubled and enclosed in '', +#define etSQLESCAPE 9 /* Strings with '\'' doubled. %q */ +#define etSQLESCAPE2 10 /* Strings with '\'' doubled and enclosed in '', NULL pointers replaced by SQL NULL. %Q */ -#define etTOKEN 12 /* a pointer to a Token structure */ -#define etSRCLIST 13 /* a pointer to a SrcList */ -#define etPOINTER 14 /* The %p conversion */ -#define etSQLESCAPE3 15 /* %w -> Strings with '\"' doubled */ -#define etORDINAL 16 /* %r -> 1st, 2nd, 3rd, 4th, etc. English only */ +#define etTOKEN 11 /* a pointer to a Token structure */ +#define etSRCLIST 12 /* a pointer to a SrcList */ +#define etPOINTER 13 /* The %p conversion */ +#define etSQLESCAPE3 14 /* %w -> Strings with '\"' doubled */ +#define etORDINAL 15 /* %r -> 1st, 2nd, 3rd, 4th, etc. English only */ -#define etINVALID 0 /* Any unrecognized conversion type */ +#define etINVALID 16 /* Any unrecognized conversion type */ /* @@ -189,7 +189,7 @@ void sqlite3VXPrintf( etByte flag_long; /* True if "l" flag is present */ etByte flag_longlong; /* True if the "ll" flag is present */ etByte done; /* Loop termination flag */ - etByte xtype = 0; /* Conversion paradigm */ + etByte xtype = etINVALID; /* Conversion paradigm */ u8 bArgList; /* True for SQLITE_PRINTF_SQLFUNC */ u8 useIntern; /* Ok to use internal conversions (ex: %T) */ char prefix; /* Prefix character. "+" or "-" or " " or '\0'. */ From da110bfecec0b590ee6321c4f57bf98c950905da Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 5 May 2016 17:15:23 +0000 Subject: [PATCH 0387/1484] Initial check-in of the "scrub.exe" utility program prototype. Not yet fully functional. In particular, no scrubbing is done. FossilOrigin-Name: bdf2ec77d1542d4e9b68218f558710a3efc15823 --- Makefile.in | 4 + Makefile.msc | 3 + ext/misc/scrub.c | 306 +++++++++++++++++++++++++++++++++++++++++++++++ main.mk | 3 + manifest | 20 ++-- manifest.uuid | 2 +- 6 files changed, 329 insertions(+), 9 deletions(-) create mode 100644 ext/misc/scrub.c diff --git a/Makefile.in b/Makefile.in index 78480de9e0..4e10d4e231 100644 --- a/Makefile.in +++ b/Makefile.in @@ -589,6 +589,10 @@ sqlite3$(TEXE): $(TOP)/src/shell.c sqlite3.c sqldiff$(TEXE): $(TOP)/tool/sqldiff.c sqlite3.c sqlite3.h $(LTLINK) -o $@ $(TOP)/tool/sqldiff.c sqlite3.c $(TLIBS) +scrub$(TEXE): $(TOP)/ext/misc/scrub.c sqlite3.o + $(LTLINK) -o $@ -I. -DSCRUB_STANDALONE \ + $(TOP)/ext/misc/scrub.c sqlite3.o $(TLIBS) + srcck1$(BEXE): $(TOP)/tool/srcck1.c $(BCC) -o srcck1$(BEXE) $(TOP)/tool/srcck1.c diff --git a/Makefile.msc b/Makefile.msc index bb9790d312..408a516364 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -1455,6 +1455,9 @@ $(SQLITE3EXE): $(TOP)\src\shell.c $(SHELL_CORE_DEP) $(LIBRESOBJS) $(SHELL_CORE_S sqldiff.exe: $(TOP)\tool\sqldiff.c $(SQLITE3C) $(SQLITE3H) $(LTLINK) $(NO_WARN) $(TOP)\tool\sqldiff.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) +scrub.exe: $(TOP)\ext\misc\scrub.c $(SQLITE3C) $(SQLITE3H) + $(LTLINK) $(NO_WARN) $(TOP)\ext\misc\scrub.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) + srcck1.exe: $(TOP)\tool\srcck1.c $(BCC) $(NO_WARN) -Fe$@ $(TOP)\tool\srcck1.c diff --git a/ext/misc/scrub.c b/ext/misc/scrub.c new file mode 100644 index 0000000000..fbf2f8c2b7 --- /dev/null +++ b/ext/misc/scrub.c @@ -0,0 +1,306 @@ +/* +** 2016-05-05 +** +** 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 a utility function (and a utility program) that +** makes a copy of an SQLite database while simultaneously zeroing out all +** deleted content. +** +** Normally (when PRAGMA secure_delete=OFF, which is the default) when SQLite +** deletes content, it does not overwrite the deleted content but rather marks +** the region of the file that held that content as being reusable. This can +** cause deleted content to recoverable from the database file. This stale +** content is removed by the VACUUM command, but VACUUM can be expensive for +** large databases. When in PRAGMA secure_delete=ON mode, the deleted content +** is zeroed, but secure_delete=ON has overhead as well. +** +** This utility attempts to make a copy of a complete SQLite database where +** all of the deleted content is zeroed out in the copy, and it attempts to +** do so while being faster than running VACUUM. +** +** Usage: +** +** int sqlite3_scrub_backup( +** const char *zSourceFile, // Source database filename +** const char *zDestFile, // Destination database filename +** char **pzErrMsg // Write error message here +** ); +** +** Simply call the API above specifying the filename of the source database +** and the name of the backup copy. The source database must already exist +** and can be in active use. (A read lock is held during the backup.) The +** destination file should not previously exist. If the pzErrMsg parameter +** is non-NULL and if an error occurs, then an error message might be written +** into memory obtained from sqlite3_malloc() and *pzErrMsg made to point to +** that error message. But if the error is an OOM, the error might not be +** reported. The routine always returns non-zero if there is an error. +** +** If compiled with -DSCRUB_STANDALONE then a main() procedure is added and +** this file becomes a standalone program that can be run as follows: +** +** ./sqlite3scrub SOURCE DEST +*/ +#include "sqlite3.h" +#include +#include +#include +#include +#include + +typedef struct ScrubState ScrubState; +typedef unsigned char u8; + +/* State information for a scrub-and-backup operation */ +struct ScrubState { + const char *zSrcFile; /* Name of the source file */ + const char *zDestFile; /* Name of the destination file */ + int rcErr; /* Error code */ + char *zErr; /* Error message text */ + sqlite3 *dbSrc; /* Source database connection */ + sqlite3_file *pSrc; /* Source file handle */ + sqlite3 *dbDest; /* Destination database connection */ + sqlite3_file *pDest; /* Destination file handle */ + unsigned int szPage; /* Page size */ + unsigned int nPage; /* Number of pages */ + u8 *page1; /* Content of page 1 */ +}; + +/* Store an error message */ +static void scrubBackupErr(ScrubState *p, const char *zFormat, ...){ + va_list ap; + sqlite3_free(p->zErr); + va_start(ap, zFormat); + p->zErr = sqlite3_vmprintf(zFormat, ap); + va_end(ap); + if( p->rcErr==0 ) p->rcErr = SQLITE_ERROR; +} + +/* Allocate memory to hold a single page of content */ +static u8 *scrubBackupAllocPage(ScrubState *p){ + u8 *pPage; + if( p->rcErr ) return 0; + pPage = sqlite3_malloc( p->szPage ); + if( pPage==0 ) p->rcErr = SQLITE_NOMEM; + return pPage; +} + +/* Read a page from the source database into memory. Use the memory +** provided by pBuf if not NULL or allocate a new page if pBuf==NULL. +*/ +static u8 *scrubBackupRead(ScrubState *p, int pgno, u8 *pBuf){ + int rc; + sqlite3_int64 iOff; + u8 *pOut = pBuf; + if( p->rcErr ) return 0; + if( pOut==0 ){ + pOut = scrubBackupAllocPage(p); + if( pOut==0 ) return 0; + } + iOff = (pgno-1)*(sqlite3_int64)p->szPage; + rc = p->pSrc->pMethods->xRead(p->pSrc, pOut, p->szPage, iOff); + if( rc!=SQLITE_OK ){ + if( pBuf==0 ) sqlite3_free(pOut); + pOut = 0; + scrubBackupErr(p, "read failed for page %d", pgno); + p->rcErr = SQLITE_IOERR; + } + return pOut; +} + +/* Write a page to the destination database */ +static void scrubBackupWrite(ScrubState *p, int pgno, u8 *pData){ + int rc; + sqlite3_int64 iOff; + if( p->rcErr ) return; + iOff = (pgno-1)*(sqlite3_int64)p->szPage; + rc = p->pDest->pMethods->xWrite(p->pDest, pData, p->szPage, iOff); + if( rc!=SQLITE_OK ){ + scrubBackupErr(p, "write failed for page %d", pgno); + p->rcErr = SQLITE_IOERR; + } +} + +/* Prepare a statement against the "db" database. */ +static sqlite3_stmt *scrubBackupPrepare( + ScrubState *p, /* Backup context */ + sqlite3 *db, /* Database to prepare against */ + const char *zSql /* SQL statement */ +){ + sqlite3_stmt *pStmt; + if( p->rcErr ) return 0; + p->rcErr = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); + if( p->rcErr ){ + scrubBackupErr(p, "SQL error \"%s\" on \"%s\"", + sqlite3_errmsg(db), zSql); + sqlite3_finalize(pStmt); + return 0; + } + return pStmt; +} + + +/* Open the source database file */ +static void scrubBackupOpenSrc(ScrubState *p){ + sqlite3_stmt *pStmt; + int rc; + /* Open the source database file */ + p->rcErr = sqlite3_open_v2(p->zSrcFile, &p->dbSrc, + SQLITE_OPEN_READONLY | + SQLITE_OPEN_URI | SQLITE_OPEN_PRIVATECACHE, 0); + if( p->rcErr ){ + scrubBackupErr(p, "cannot open source database: %s", + sqlite3_errmsg(p->dbSrc)); + return; + } + p->rcErr = sqlite3_exec(p->dbSrc, "BEGIN", 0, 0, 0); + if( p->rcErr ){ + scrubBackupErr(p, + "cannot start a read transaction on the source database: %s", + sqlite3_errmsg(p->dbSrc)); + return; + } + pStmt = scrubBackupPrepare(p, p->dbSrc, "PRAGMA page_size"); + if( pStmt==0 ) return; + rc = sqlite3_step(pStmt); + if( rc==SQLITE_ROW ){ + p->szPage = sqlite3_column_int(pStmt, 0); + }else{ + scrubBackupErr(p, "unable to determine the page size"); + } + sqlite3_finalize(pStmt); + if( p->rcErr ) return; + pStmt = scrubBackupPrepare(p, p->dbSrc, "PRAGMA page_count"); + if( pStmt==0 ) return; + rc = sqlite3_step(pStmt); + if( rc==SQLITE_ROW ){ + p->nPage = sqlite3_column_int(pStmt, 0); + }else{ + scrubBackupErr(p, "unable to determine the size of the source database"); + } + sqlite3_finalize(pStmt); + sqlite3_file_control(p->dbSrc, "main", SQLITE_FCNTL_FILE_POINTER, &p->pSrc); + if( p->pSrc==0 || p->pSrc->pMethods==0 ){ + scrubBackupErr(p, "cannot get the source file handle"); + p->rcErr = SQLITE_ERROR; + } +} + +/* Create and open the destination file */ +static void scrubBackupOpenDest(ScrubState *p){ + sqlite3_stmt *pStmt; + int rc; + char *zSql; + if( p->rcErr ) return; + p->rcErr = sqlite3_open_v2(p->zDestFile, &p->dbDest, + SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | + SQLITE_OPEN_URI | SQLITE_OPEN_PRIVATECACHE, 0); + if( p->rcErr ){ + scrubBackupErr(p, "cannot open destination database: %s", + sqlite3_errmsg(p->dbDest)); + return; + } + zSql = sqlite3_mprintf("PRAGMA page_size(%u);", p->szPage); + if( zSql==0 ){ + p->rcErr = SQLITE_NOMEM; + return; + } + p->rcErr = sqlite3_exec(p->dbDest, zSql, 0, 0, 0); + sqlite3_free(zSql); + if( p->rcErr ){ + scrubBackupErr(p, + "cannot set the page size on the destination database: %s", + sqlite3_errmsg(p->dbDest)); + return; + } + sqlite3_exec(p->dbDest, "PRAGMA journal_mode=OFF;", 0, 0, 0); + p->rcErr = sqlite3_exec(p->dbDest, "BEGIN EXCLUSIVE;", 0, 0, 0); + if( p->rcErr ){ + scrubBackupErr(p, + "cannot start a write transaction on the destination database: %s", + sqlite3_errmsg(p->dbDest)); + return; + } + pStmt = scrubBackupPrepare(p, p->dbDest, "PRAGMA page_count;"); + if( pStmt==0 ) return; + rc = sqlite3_step(pStmt); + if( rc!=SQLITE_ROW ){ + scrubBackupErr(p, "cannot measure the size of the destination"); + }else if( sqlite3_column_int(pStmt, 0)>1 ){ + scrubBackupErr(p, "destination database is not empty - holds %d pages", + sqlite3_column_int(pStmt, 0)); + } + sqlite3_finalize(pStmt); + sqlite3_file_control(p->dbDest, "main", SQLITE_FCNTL_FILE_POINTER, &p->pDest); + if( p->pDest==0 || p->pDest->pMethods==0 ){ + scrubBackupErr(p, "cannot get the destination file handle"); + p->rcErr = SQLITE_ERROR; + } +} + +int sqlite3_scrub_backup( + const char *zSrcFile, /* Source file */ + const char *zDestFile, /* Destination file */ + char **pzErr /* Write error here if non-NULL */ +){ + ScrubState s; + unsigned int i; + u8 *pBuf = 0; + u8 *pData; + + memset(&s, 0, sizeof(s)); + s.zSrcFile = zSrcFile; + s.zDestFile = zDestFile; + + scrubBackupOpenSrc(&s); + scrubBackupOpenDest(&s); + pBuf = scrubBackupAllocPage(&s); + + for(i=1; s.rcErr==0 && i<=s.nPage; i++){ + pData = scrubBackupRead(&s, i, pBuf); + scrubBackupWrite(&s, i, pData); + } + + /* Close the destination database without closing the transaction. If we + ** commit, page zero will be overwritten. */ + sqlite3_close(s.dbDest); + + sqlite3_close(s.dbSrc); + sqlite3_free(s.page1); + if( pzErr ){ + *pzErr = s.zErr; + }else{ + sqlite3_free(s.zErr); + } + return s.rcErr; +} + +#ifdef SCRUB_STANDALONE +/* The main() routine when this utility is run as a stand-alone program */ +int main(int argc, char **argv){ + char *zErr = 0; + int rc; + if( argc!=3 ){ + fprintf(stderr,"Usage: %s SOURCE DESTINATION\n", argv[0]); + exit(1); + } + rc = sqlite3_scrub_backup(argv[1], argv[2], &zErr); + if( rc==SQLITE_NOMEM ){ + fprintf(stderr, "%s: out of memory\n", argv[0]); + exit(1); + } + if( zErr ){ + fprintf(stderr, "%s: %s\n", argv[0], zErr); + sqlite3_free(zErr); + exit(1); + } + return 0; +} +#endif diff --git a/main.mk b/main.mk index 1e791416d8..f200dc2092 100644 --- a/main.mk +++ b/main.mk @@ -488,6 +488,9 @@ sqldiff$(EXE): $(TOP)/tool/sqldiff.c sqlite3.c sqlite3.h $(TCCX) -o sqldiff$(EXE) -DSQLITE_THREADSAFE=0 \ $(TOP)/tool/sqldiff.c sqlite3.c $(TLIBS) $(THREADLIB) +scrub$(EXE): $(TOP)/ext/misc/scrub.c sqlite3.o + $(TCC) -I. -DSCRUB_STANDALONE -o scrub$(EXE) $(TOP)/ext/misc/scrub.c sqlite3.o $(THREADLIB) + srcck1$(EXE): $(TOP)/tool/srcck1.c $(BCC) -o srcck1$(EXE) $(TOP)/tool/srcck1.c diff --git a/manifest b/manifest index 8e5f6ffbdc..919f2e5e0d 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -C Renumber\sinternal\sconstants\sin\sthe\sprintf()\simplemention\sfor\sa\ssmall\nperformance\simprovement. -D 2016-05-05T11:53:12.439 -F Makefile.in 9eda6e1c90d05c199c3ec8a7069b0682ad307657 +C Initial\scheck-in\sof\sthe\s"scrub.exe"\sutility\sprogram\sprototype.\s\sNot\syet\nfully\sfunctional.\s\sIn\sparticular,\sno\sscrubbing\sis\sdone. +D 2016-05-05T17:15:23.301 +F Makefile.in f59e0763ff448719fc1bd25513882b0567286317 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 -F Makefile.msc db82b35aef27f412fef14d8534afc022138bcdfd +F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7 F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7 F VERSION 5d234da9b5dae329fab75ff75884cfe0a9cb3fda F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 @@ -215,6 +215,7 @@ F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342 F ext/misc/percentile.c bcbee3c061b884eccb80e21651daaae8e1e43c63 F ext/misc/regexp.c a68d25c659bd2d893cd1215667bbf75ecb9dc7d4 F ext/misc/rot13.c 1ac6f95f99b575907b9b09c81a349114cf9be45a +F ext/misc/scrub.c 76a9c795078a65bd021d5b5cd9e4655e7d0306c0 F ext/misc/series.c e11e534ada797d5b816d7e7a93c022306563ca35 F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52 F ext/misc/spellfix.c bf1b922c2750698e9a3d4c50cce6974adb7e93be @@ -302,7 +303,7 @@ F ext/userauth/userauth.c 5fa3bdb492f481bbc1709fc83c91ebd13460c69e F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60 -F main.mk a283660f75c3c4b75d8c9d12a40fa38a066eee9d +F main.mk 0fb2b051c9dbcf7f26a8455cf115ae9457448b93 F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 @@ -1487,7 +1488,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 71af9ac165ac02272f4886f69bd9ab4770fd7bb6 -R 89655379113728f544ce9a18ad294b0b +P 69d11447f4b1a8c536c3b6573d2a3419da870412 +R 98e582093972832acc05b11fc975c102 +T *branch * scrub-backup +T *sym-scrub-backup * +T -sym-trunk * U drh -Z f65addcdc03169dedb02067b28293d6c +Z e2196386eaeffd3910bcf89f26dcb9bb diff --git a/manifest.uuid b/manifest.uuid index 4a4e62d8ed..6832a682a5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -69d11447f4b1a8c536c3b6573d2a3419da870412 \ No newline at end of file +bdf2ec77d1542d4e9b68218f558710a3efc15823 \ No newline at end of file From 2a9bd02645c6616e877e090d8a2f7c8bfee77809 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 5 May 2016 23:09:57 +0000 Subject: [PATCH 0388/1484] Finished implementation compiles, but untested. FossilOrigin-Name: aeb88bdf6fe9e5839b1503ab5740b27bc09d4842 --- ext/misc/scrub.c | 286 +++++++++++++++++++++++++++++++++++++++++++++-- manifest | 15 +-- manifest.uuid | 2 +- 3 files changed, 282 insertions(+), 21 deletions(-) diff --git a/ext/misc/scrub.c b/ext/misc/scrub.c index fbf2f8c2b7..424db6baf5 100644 --- a/ext/misc/scrub.c +++ b/ext/misc/scrub.c @@ -57,6 +57,9 @@ typedef struct ScrubState ScrubState; typedef unsigned char u8; +typedef unsigned short u16; +typedef unsigned int u32; + /* State information for a scrub-and-backup operation */ struct ScrubState { @@ -68,8 +71,9 @@ struct ScrubState { sqlite3_file *pSrc; /* Source file handle */ sqlite3 *dbDest; /* Destination database connection */ sqlite3_file *pDest; /* Destination file handle */ - unsigned int szPage; /* Page size */ - unsigned int nPage; /* Number of pages */ + u32 szPage; /* Page size */ + u32 szUsable; /* Usable bytes on each page */ + u32 nPage; /* Number of pages */ u8 *page1; /* Content of page 1 */ }; @@ -116,7 +120,7 @@ static u8 *scrubBackupRead(ScrubState *p, int pgno, u8 *pBuf){ } /* Write a page to the destination database */ -static void scrubBackupWrite(ScrubState *p, int pgno, u8 *pData){ +static void scrubBackupWrite(ScrubState *p, int pgno, const u8 *pData){ int rc; sqlite3_int64 iOff; if( p->rcErr ) return; @@ -245,33 +249,293 @@ static void scrubBackupOpenDest(ScrubState *p){ } } +/* Read a 32-bit big-endian integer */ +static u32 scrubBackupInt32(const u8 *a){ + u32 v = a[3]; + v += ((u32)a[2])<<8; + v += ((u32)a[1])<<16; + v += ((u32)a[0])<<24; + return v; +} + +/* Read a 16-bit big-endian integer */ +static u32 scrubBackupInt16(const u8 *a){ + return (a[0]<<8) + a[1]; +} + +/* +** Read a varint. Put the value in *pVal and return the number of bytes. +*/ +static int scrubBackupVarint(const u8 *z, sqlite3_int64 *pVal){ + sqlite3_int64 v = 0; + int i; + for(i=0; i<8; i++){ + v = (v<<7) + (z[i]&0x7f); + if( (z[i]&0x80)==0 ){ *pVal = v; return i+1; } + } + v = (v<<8) + (z[i]&0xff); + *pVal = v; + return 9; +} + +/* +** Return the number of bytes in a varint. +*/ +static int scrubBackupVarintSize(const u8 *z){ + int i; + for(i=0; i<8; i++){ + if( (z[i]&0x80)==0 ){ return i+1; } + } + return 9; +} + +/* +** Copy the freelist trunk page given, and all its descendents, +** zeroing out as much as possible in the process. +*/ +static void scrubBackupFreelist(ScrubState *p, int pgno, u32 nFree){ + u8 *a, *aBuf; + u32 n, mx; + + if( p->rcErr ) return; + aBuf = scrubBackupAllocPage(p); + if( aBuf==0 ) return; + + while( pgno && nFree){ + a = scrubBackupRead(p, pgno, aBuf); + if( a==0 ) break; + n = scrubBackupInt32(&a[4]); + mx = p->szUsable/4 - 2; + if( nszPage); + } + scrubBackupWrite(p, iLeaf, aZero); + nFree--; + } +#endif + } + sqlite3_free(aBuf); +} + +/* +** Copy an overflow chain from source to destination. Zero out any +** unused tail at the end of the overflow chain. +*/ +static void scrubBackupOverflow(ScrubState *p, int pgno, u32 nByte){ + u8 *a, *aBuf; + + aBuf = scrubBackupAllocPage(p); + if( aBuf==0 ) return; + while( nByte>0 && pgno!=0 ){ + a = scrubBackupRead(p, pgno, aBuf); + if( a ) break; + if( nByte >= (p->szUsable)-4 ){ + nByte -= (p->szUsable) - 4; + }else{ + u32 x = (p->szUsable - 4) - nByte; + u32 i = p->szUsable - x; + memset(&a[i], 0, x); + nByte = 0; + } + scrubBackupWrite(p, pgno, a); + pgno = scrubBackupInt32(a); + } + sqlite3_free(aBuf); +} + + +/* +** Copy B-Tree page pgno, and all of its children, from source to destination. +** Zero out deleted content during the copy. +*/ +static void scrubBackupBtree(ScrubState *p, int pgno, int iDepth){ + u8 *a; + u32 i, n, pc; + u32 nCell; + u32 nPrefix; + u32 szHdr; + u32 iChild; + u8 *aTop; + u8 *aCell; + u32 x, y; + + + if( p->rcErr ) return; + if( iDepth>50 ){ + scrubBackupErr(p, "corrupt: b-tree too deep at page %d", pgno); + return; + } + if( pgno==1 ){ + a = p->page1; + }else{ + a = scrubBackupRead(p, pgno, 0); + if( a==0 ) return; + } + nPrefix = pgno==1 ? 100 : 0; + aTop = &a[nPrefix]; + szHdr = 8 + 4*(aTop[0]==0x02 || aTop[0]==0x05); + aCell = aTop + szHdr; + nCell = scrubBackupInt16(&aTop[3]); + + /* Zero out the gap between the cell index and the start of the + ** cell content area */ + x = scrubBackupInt16(&aTop[5]); /* First byte of cell content area */ + if( x>p->szUsable ) goto btree_corrupt; + y = szHdr + nPrefix + nCell*2; + if( y>x ) goto btree_corrupt; + if( y(p->szUsable)-4 ) goto btree_corrupt; + n = scrubBackupInt16(&a[pc+2]); + if( pc+n>(p->szUsable) ) goto btree_corrupt; + if( n>4 ) memset(&a[pc+4], 0, n-4); + x = scrubBackupInt16(&a[pc]); + if( x0 ) goto btree_corrupt; + pc = x; + } + + /* Write this one page */ + scrubBackupWrite(p, pgno, a); + + /* Walk the tree and process child pages */ + for(i=0; i p->szUsable-3 ) goto btree_corrupt; + if( aTop[0]==0x05 || aTop[0]==0x02 ){ + if( pc+4 > p->szUsable ) goto btree_corrupt; + iChild = scrubBackupInt32(&a[pc]); + pc += 4; + scrubBackupBtree(p, iChild, iDepth+1); + if( aTop[0]==0x05 ) continue; + } + pc += scrubBackupVarint(&a[pc], &P); + if( pc >= p->szUsable ) goto btree_corrupt; + if( aTop[0]==0x0d ){ + X = p->szUsable - 35; + }else{ + X = ((p->szUsable - 12)*64/255) - 23; + } + if( P<=X ){ + /* All content is local. No overflow */ + continue; + } + M = ((p->szUsable - 12)*32/255)-23; + K = M + ((P-M)%(p->szUsable-4)); + if( aTop[0]==0x0d ){ + pc += scrubBackupVarintSize(&a[pc]); + if( pc > (p->szUsable-4) ) goto btree_corrupt; + } + nLocal = K<=X ? K : M; + if( pc+nLocal > p->szUsable-4 ) goto btree_corrupt; + iChild = scrubBackupInt32(&a[pc+nLocal]); + scrubBackupOverflow(p, iChild, P-nLocal); + } + + /* Walk the right-most tree */ + if( aTop[0]==0x05 || aTop[0]==0x02 ){ + iChild = scrubBackupInt32(&aTop[8]); + scrubBackupBtree(p, iChild, iDepth+1); + } + + /* All done */ + if( pgno>1 ) sqlite3_free(a); + return; + +btree_corrupt: + scrubBackupErr(p, "corruption on page %d of source database", pgno); + if( pgno>1 ) sqlite3_free(a); +} + +/* +** Copy all ptrmap pages from source to destination. +** This routine is only called if the source database is in autovacuum +** or incremental vacuum mode. +*/ +static void scrubBackupPtrmap(ScrubState *p){ + u32 pgno = 2; + u32 J = p->szUsable/5; + u32 iLock = (1073742335/p->szPage)+1; + u8 *a, *pBuf; + if( p->rcErr ) return; + pBuf = scrubBackupAllocPage(p); + if( pBuf==0 ) return; + while( pgno<=p->nPage ){ + a = scrubBackupRead(p, pgno, pBuf); + if( a==0 ) break; + scrubBackupWrite(p, pgno, a); + pgno += J+1; + if( pgno==iLock ) pgno++; + } + sqlite3_free(pBuf); +} + int sqlite3_scrub_backup( const char *zSrcFile, /* Source file */ const char *zDestFile, /* Destination file */ char **pzErr /* Write error here if non-NULL */ ){ ScrubState s; - unsigned int i; - u8 *pBuf = 0; - u8 *pData; + u32 n, i; + sqlite3_stmt *pStmt; memset(&s, 0, sizeof(s)); s.zSrcFile = zSrcFile; s.zDestFile = zDestFile; + /* Open both source and destination databases */ scrubBackupOpenSrc(&s); scrubBackupOpenDest(&s); - pBuf = scrubBackupAllocPage(&s); - for(i=1; s.rcErr==0 && i<=s.nPage; i++){ - pData = scrubBackupRead(&s, i, pBuf); - scrubBackupWrite(&s, i, pData); + /* Read in page 1 */ + s.page1 = scrubBackupRead(&s, 1, 0); + if( s.page1==0 ) goto scrub_abort; + s.szUsable = s.szPage - s.page1[20]; + + /* Copy the freelist */ + n = scrubBackupInt32(&s.page1[36]); + i = scrubBackupInt32(&s.page1[32]); + if( n ) scrubBackupFreelist(&s, i, n); + + /* Copy ptrmap pages */ + n = scrubBackupInt32(&s.page1[52]); + if( n ) scrubBackupPtrmap(&s); + + /* Copy all of the btrees */ + scrubBackupBtree(&s, 1, 0); + pStmt = scrubBackupPrepare(&s, s.dbSrc, + "SELECT rootpage FROM sqlite_master WHERE rootpage IS NOT NULL"); + if( pStmt==0 ) goto scrub_abort; + while( sqlite3_step(pStmt)==SQLITE_ROW ){ + i = (u32)sqlite3_column_int(pStmt, 0); + scrubBackupBtree(&s, i, 0); } + sqlite3_finalize(pStmt); +scrub_abort: /* Close the destination database without closing the transaction. If we ** commit, page zero will be overwritten. */ sqlite3_close(s.dbDest); - sqlite3_close(s.dbSrc); sqlite3_free(s.page1); if( pzErr ){ diff --git a/manifest b/manifest index 919f2e5e0d..fff7842874 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Initial\scheck-in\sof\sthe\s"scrub.exe"\sutility\sprogram\sprototype.\s\sNot\syet\nfully\sfunctional.\s\sIn\sparticular,\sno\sscrubbing\sis\sdone. -D 2016-05-05T17:15:23.301 +C Finished\simplementation\scompiles,\sbut\suntested. +D 2016-05-05T23:09:57.111 F Makefile.in f59e0763ff448719fc1bd25513882b0567286317 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7 @@ -215,7 +215,7 @@ F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342 F ext/misc/percentile.c bcbee3c061b884eccb80e21651daaae8e1e43c63 F ext/misc/regexp.c a68d25c659bd2d893cd1215667bbf75ecb9dc7d4 F ext/misc/rot13.c 1ac6f95f99b575907b9b09c81a349114cf9be45a -F ext/misc/scrub.c 76a9c795078a65bd021d5b5cd9e4655e7d0306c0 +F ext/misc/scrub.c 831d12a1ba776815eb946ee5a267997842384074 F ext/misc/series.c e11e534ada797d5b816d7e7a93c022306563ca35 F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52 F ext/misc/spellfix.c bf1b922c2750698e9a3d4c50cce6974adb7e93be @@ -1488,10 +1488,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 69d11447f4b1a8c536c3b6573d2a3419da870412 -R 98e582093972832acc05b11fc975c102 -T *branch * scrub-backup -T *sym-scrub-backup * -T -sym-trunk * +P bdf2ec77d1542d4e9b68218f558710a3efc15823 +R 3a64deda8cf94b6b4577af97769133ef U drh -Z e2196386eaeffd3910bcf89f26dcb9bb +Z 668555cf9e940e9598a6c547736364c9 diff --git a/manifest.uuid b/manifest.uuid index 6832a682a5..73eea5130f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bdf2ec77d1542d4e9b68218f558710a3efc15823 \ No newline at end of file +aeb88bdf6fe9e5839b1503ab5740b27bc09d4842 \ No newline at end of file From e04369e29e01d375fa17c206365407e8baaa0109 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 5 May 2016 23:39:30 +0000 Subject: [PATCH 0389/1484] Working when run against sqlite.fossil. FossilOrigin-Name: b0bd9dd6255be161ea289ba6caa3fbd568128f62 --- ext/misc/scrub.c | 34 ++++++++++++++++++---------------- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 25 insertions(+), 23 deletions(-) diff --git a/ext/misc/scrub.c b/ext/misc/scrub.c index 424db6baf5..153625abed 100644 --- a/ext/misc/scrub.c +++ b/ext/misc/scrub.c @@ -342,7 +342,7 @@ static void scrubBackupOverflow(ScrubState *p, int pgno, u32 nByte){ if( aBuf==0 ) return; while( nByte>0 && pgno!=0 ){ a = scrubBackupRead(p, pgno, aBuf); - if( a ) break; + if( a==0 ) break; if( nByte >= (p->szUsable)-4 ){ nByte -= (p->szUsable) - 4; }else{ @@ -372,6 +372,7 @@ static void scrubBackupBtree(ScrubState *p, int pgno, int iDepth){ u8 *aTop; u8 *aCell; u32 x, y; + int ln = 0; if( p->rcErr ) return; @@ -394,21 +395,21 @@ static void scrubBackupBtree(ScrubState *p, int pgno, int iDepth){ /* Zero out the gap between the cell index and the start of the ** cell content area */ x = scrubBackupInt16(&aTop[5]); /* First byte of cell content area */ - if( x>p->szUsable ) goto btree_corrupt; + if( x>p->szUsable ){ ln=__LINE__; goto btree_corrupt; } y = szHdr + nPrefix + nCell*2; - if( y>x ) goto btree_corrupt; + if( y>x ){ ln=__LINE__; goto btree_corrupt; } if( y0 && pc(p->szUsable)-4 ) goto btree_corrupt; + if( pc>(p->szUsable)-4 ){ ln=__LINE__; goto btree_corrupt; } n = scrubBackupInt16(&a[pc+2]); - if( pc+n>(p->szUsable) ) goto btree_corrupt; + if( pc+n>(p->szUsable) ){ ln=__LINE__; goto btree_corrupt; } if( n>4 ) memset(&a[pc+4], 0, n-4); x = scrubBackupInt16(&a[pc]); - if( x0 ) goto btree_corrupt; + if( x0 ){ ln=__LINE__; goto btree_corrupt; } pc = x; } @@ -419,18 +420,18 @@ static void scrubBackupBtree(ScrubState *p, int pgno, int iDepth){ for(i=0; i p->szUsable-3 ) goto btree_corrupt; + pc = scrubBackupInt16(&aCell[i*2]); + if( pc <= szHdr ){ ln=__LINE__; goto btree_corrupt; } + if( pc > p->szUsable-3 ){ ln=__LINE__; goto btree_corrupt; } if( aTop[0]==0x05 || aTop[0]==0x02 ){ - if( pc+4 > p->szUsable ) goto btree_corrupt; + if( pc+4 > p->szUsable ){ ln=__LINE__; goto btree_corrupt; } iChild = scrubBackupInt32(&a[pc]); pc += 4; scrubBackupBtree(p, iChild, iDepth+1); if( aTop[0]==0x05 ) continue; } pc += scrubBackupVarint(&a[pc], &P); - if( pc >= p->szUsable ) goto btree_corrupt; + if( pc >= p->szUsable ){ ln=__LINE__; goto btree_corrupt; } if( aTop[0]==0x0d ){ X = p->szUsable - 35; }else{ @@ -444,10 +445,10 @@ static void scrubBackupBtree(ScrubState *p, int pgno, int iDepth){ K = M + ((P-M)%(p->szUsable-4)); if( aTop[0]==0x0d ){ pc += scrubBackupVarintSize(&a[pc]); - if( pc > (p->szUsable-4) ) goto btree_corrupt; + if( pc > (p->szUsable-4) ){ ln=__LINE__; goto btree_corrupt; } } nLocal = K<=X ? K : M; - if( pc+nLocal > p->szUsable-4 ) goto btree_corrupt; + if( pc+nLocal > p->szUsable-4 ){ ln=__LINE__; goto btree_corrupt; } iChild = scrubBackupInt32(&a[pc+nLocal]); scrubBackupOverflow(p, iChild, P-nLocal); } @@ -463,7 +464,8 @@ static void scrubBackupBtree(ScrubState *p, int pgno, int iDepth){ return; btree_corrupt: - scrubBackupErr(p, "corruption on page %d of source database", pgno); + scrubBackupErr(p, "corruption on page %d of source database (errid=%d)", + pgno, ln); if( pgno>1 ) sqlite3_free(a); } @@ -524,7 +526,7 @@ int sqlite3_scrub_backup( /* Copy all of the btrees */ scrubBackupBtree(&s, 1, 0); pStmt = scrubBackupPrepare(&s, s.dbSrc, - "SELECT rootpage FROM sqlite_master WHERE rootpage IS NOT NULL"); + "SELECT rootpage FROM sqlite_master WHERE coalesce(rootpage,0)>0"); if( pStmt==0 ) goto scrub_abort; while( sqlite3_step(pStmt)==SQLITE_ROW ){ i = (u32)sqlite3_column_int(pStmt, 0); diff --git a/manifest b/manifest index fff7842874..3ded627744 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Finished\simplementation\scompiles,\sbut\suntested. -D 2016-05-05T23:09:57.111 +C Working\swhen\srun\sagainst\ssqlite.fossil. +D 2016-05-05T23:39:30.803 F Makefile.in f59e0763ff448719fc1bd25513882b0567286317 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7 @@ -215,7 +215,7 @@ F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342 F ext/misc/percentile.c bcbee3c061b884eccb80e21651daaae8e1e43c63 F ext/misc/regexp.c a68d25c659bd2d893cd1215667bbf75ecb9dc7d4 F ext/misc/rot13.c 1ac6f95f99b575907b9b09c81a349114cf9be45a -F ext/misc/scrub.c 831d12a1ba776815eb946ee5a267997842384074 +F ext/misc/scrub.c 548a116cb0b4d8705eac392ab13d28fe2aebefe6 F ext/misc/series.c e11e534ada797d5b816d7e7a93c022306563ca35 F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52 F ext/misc/spellfix.c bf1b922c2750698e9a3d4c50cce6974adb7e93be @@ -1488,7 +1488,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P bdf2ec77d1542d4e9b68218f558710a3efc15823 -R 3a64deda8cf94b6b4577af97769133ef +P aeb88bdf6fe9e5839b1503ab5740b27bc09d4842 +R 6bcd08fd9f0774891e37784b87170024 U drh -Z 668555cf9e940e9598a6c547736364c9 +Z cbd8d4738f2e299be1c42951defbac8d diff --git a/manifest.uuid b/manifest.uuid index 73eea5130f..fee828267f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -aeb88bdf6fe9e5839b1503ab5740b27bc09d4842 \ No newline at end of file +b0bd9dd6255be161ea289ba6caa3fbd568128f62 \ No newline at end of file From 8271630e81940729a34dd614d09a23851b078a42 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 5 May 2016 23:59:22 +0000 Subject: [PATCH 0390/1484] Additional error reporting. Open the source database read/write so that it can delete the WAL file when done. FossilOrigin-Name: d2efd3c176f0eba2d78105f0bb3161db38bd4bab --- ext/misc/scrub.c | 17 ++++++++++++++++- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/ext/misc/scrub.c b/ext/misc/scrub.c index 153625abed..12adcd7bd9 100644 --- a/ext/misc/scrub.c +++ b/ext/misc/scrub.c @@ -157,7 +157,7 @@ static void scrubBackupOpenSrc(ScrubState *p){ int rc; /* Open the source database file */ p->rcErr = sqlite3_open_v2(p->zSrcFile, &p->dbSrc, - SQLITE_OPEN_READONLY | + SQLITE_OPEN_READWRITE | SQLITE_OPEN_URI | SQLITE_OPEN_PRIVATECACHE, 0); if( p->rcErr ){ scrubBackupErr(p, "cannot open source database: %s", @@ -538,6 +538,9 @@ scrub_abort: /* Close the destination database without closing the transaction. If we ** commit, page zero will be overwritten. */ sqlite3_close(s.dbDest); + + /* But do close out the read-transaction on the source database */ + sqlite3_exec(s.dbSrc, "COMMIT;", 0, 0, 0); sqlite3_close(s.dbSrc); sqlite3_free(s.page1); if( pzErr ){ @@ -549,6 +552,17 @@ scrub_abort: } #ifdef SCRUB_STANDALONE +/* Error and warning log */ +static void errorLogCallback(void *pNotUsed, int iErr, const char *zMsg){ + const char *zType; + switch( iErr&0xff ){ + case SQLITE_WARNING: zType = "WARNING"; break; + case SQLITE_NOTICE: zType = "NOTICE"; break; + default: zType = "ERROR"; break; + } + fprintf(stderr, "%s: %s\n", zType, zMsg); +} + /* The main() routine when this utility is run as a stand-alone program */ int main(int argc, char **argv){ char *zErr = 0; @@ -557,6 +571,7 @@ int main(int argc, char **argv){ fprintf(stderr,"Usage: %s SOURCE DESTINATION\n", argv[0]); exit(1); } + sqlite3_config(SQLITE_CONFIG_LOG, errorLogCallback, 0); rc = sqlite3_scrub_backup(argv[1], argv[2], &zErr); if( rc==SQLITE_NOMEM ){ fprintf(stderr, "%s: out of memory\n", argv[0]); diff --git a/manifest b/manifest index 3ded627744..0f9b581c85 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Working\swhen\srun\sagainst\ssqlite.fossil. -D 2016-05-05T23:39:30.803 +C Additional\serror\sreporting.\s\sOpen\sthe\ssource\sdatabase\sread/write\sso\sthat\nit\scan\sdelete\sthe\sWAL\sfile\swhen\sdone. +D 2016-05-05T23:59:22.078 F Makefile.in f59e0763ff448719fc1bd25513882b0567286317 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7 @@ -215,7 +215,7 @@ F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342 F ext/misc/percentile.c bcbee3c061b884eccb80e21651daaae8e1e43c63 F ext/misc/regexp.c a68d25c659bd2d893cd1215667bbf75ecb9dc7d4 F ext/misc/rot13.c 1ac6f95f99b575907b9b09c81a349114cf9be45a -F ext/misc/scrub.c 548a116cb0b4d8705eac392ab13d28fe2aebefe6 +F ext/misc/scrub.c a3380a5ff0698f88a56a23c999ee5e53768ac3ae F ext/misc/series.c e11e534ada797d5b816d7e7a93c022306563ca35 F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52 F ext/misc/spellfix.c bf1b922c2750698e9a3d4c50cce6974adb7e93be @@ -1488,7 +1488,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P aeb88bdf6fe9e5839b1503ab5740b27bc09d4842 -R 6bcd08fd9f0774891e37784b87170024 +P b0bd9dd6255be161ea289ba6caa3fbd568128f62 +R dbc8e27f8b8809d87c6c9be80d710e34 U drh -Z cbd8d4738f2e299be1c42951defbac8d +Z 950b8c8bc6ebdccefe511e872cba5384 diff --git a/manifest.uuid b/manifest.uuid index fee828267f..46b409542f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b0bd9dd6255be161ea289ba6caa3fbd568128f62 \ No newline at end of file +d2efd3c176f0eba2d78105f0bb3161db38bd4bab \ No newline at end of file From 70077d173323e074cbbe40c8234a7b3949b1a5c7 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 6 May 2016 11:31:10 +0000 Subject: [PATCH 0391/1484] Do not scan indexes that have the integer primary key as their left-most column. This fixes the crash of ticket [16c9801ceba] but it seems like the wrong fix. More investigation needed. FossilOrigin-Name: 50312273ffaf1bd4bfdc73865fa0b19166968429 --- manifest | 17 ++++++++++------- manifest.uuid | 2 +- src/where.c | 2 +- test/intpkey.test | 14 +++++++++++++- 4 files changed, 25 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 8e5f6ffbdc..fb2ac900b5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Renumber\sinternal\sconstants\sin\sthe\sprintf()\simplemention\sfor\sa\ssmall\nperformance\simprovement. -D 2016-05-05T11:53:12.439 +C Do\snot\sscan\sindexes\sthat\shave\sthe\sinteger\sprimary\skey\sas\stheir\sleft-most\ncolumn.\s\sThis\sfixes\sthe\scrash\sof\sticket\s[16c9801ceba]\sbut\sit\sseems\slike\nthe\swrong\sfix.\s\sMore\sinvestigation\sneeded. +D 2016-05-06T11:31:10.902 F Makefile.in 9eda6e1c90d05c199c3ec8a7069b0682ad307657 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc db82b35aef27f412fef14d8534afc022138bcdfd @@ -457,7 +457,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 4db22ed7e77bcf672b1a685d6ddeffba8d5be302 F src/wal.h 2f7c831cf3b071fa548bf2d5cac640846a7ff19c F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354 -F src/where.c 019e5b10dedcf54ef077ce23dd8fce38d614dcf4 +F src/where.c a7ce00ffd7844495582af957a222602e517b14de F src/whereInt.h 3b1fc240e322613ba4e9dc857ca9c7c3390acc74 F src/wherecode.c 28951741be3974701186281ced0564e9586a0db3 F src/whereexpr.c eacc0e60d029a082b4fc0cc42ea98544add1319e @@ -847,7 +847,7 @@ F test/insert5.test 394f96728d1258f406fe5f5aeb0aaf29487c39a6 F test/instr.test 737bbf80685232033f3abedc6ae92f75860b5dd2 F test/intarray.test 066b7d7ac38d25bf96f87f1b017bfc687551cdd4 F test/interrupt.test dfe9a67a94b0b2d8f70545ba1a6cca10780d71cc -F test/intpkey.test 153b70e32d008f4f4b2dff8daf448a6110b62a9c +F test/intpkey.test 18ec1f3f39a18ed51d2dbd9ce184cc421191ff70 F test/io.test f95bca1783b01ea7761671560d023360d2dfa4cc F test/ioerr.test 2a24bd6ed5a8b062e64bfe1f6cf94fb25e92210d F test/ioerr2.test 2593563599e2cc6b6b4fcf5878b177bdd5d8df26 @@ -1487,7 +1487,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 71af9ac165ac02272f4886f69bd9ab4770fd7bb6 -R 89655379113728f544ce9a18ad294b0b +P 69d11447f4b1a8c536c3b6573d2a3419da870412 +R 88ac4ed286db19382d4843a346c44c60 +T *branch * ticket-16c9801ce +T *sym-ticket-16c9801ce * +T -sym-trunk * U drh -Z f65addcdc03169dedb02067b28293d6c +Z a8fa257e80e1a139c1678ae44101daf6 diff --git a/manifest.uuid b/manifest.uuid index 4a4e62d8ed..1745de5e7c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -69d11447f4b1a8c536c3b6573d2a3419da870412 \ No newline at end of file +50312273ffaf1bd4bfdc73865fa0b19166968429 \ No newline at end of file diff --git a/src/where.c b/src/where.c index d45a872c85..9aa068d660 100644 --- a/src/where.c +++ b/src/where.c @@ -289,7 +289,7 @@ static WhereTerm *whereScanInit( j = iColumn; iColumn = pIdx->aiColumn[j]; if( iColumn==XN_EXPR ) pScan->pIdxExpr = pIdx->aColExpr->a[j].pExpr; - if( iColumn==pIdx->pTable->iPKey ) iColumn = XN_ROWID; + if( iColumn==pIdx->pTable->iPKey && j>0 ) iColumn = XN_ROWID; } if( pIdx && iColumn>=0 ){ pScan->idxaff = pIdx->pTable->aCol[iColumn].affinity; diff --git a/test/intpkey.test b/test/intpkey.test index c6be5418aa..0158ad7766 100644 --- a/test/intpkey.test +++ b/test/intpkey.test @@ -614,6 +614,18 @@ do_execsql_test intpkey-16.1 { PRAGMA table_info=t16a; } {0 id INTEGER 0 {} 1 1 b TEXT 0 {} 0 2 c INT 0 {} 0} - +# 2016-05-06 ticket https://www.sqlite.org/src/tktview/16c9801ceba4923939085 +# When the schema contains an index on the IPK and no other index +# and a WHERE clause on a delete uses an OR where both sides referencing +# the IPK, then it is possible that the OP_Delete will fail because there +# deferred seek of the OP_Seek is not resolved prior to reaching the OP_Delete. +# +do_execsql_test intpkey-17.0 { + CREATE TABLE t17(x INTEGER PRIMARY KEY, y TEXT); + INSERT INTO t17(x,y) VALUES(123,'elephant'),(248,'giraffe'); + CREATE INDEX t17x ON t17(x); + DELETE FROM t17 WHERE x=99 OR x<130; + SELECT * FROM t17; +} {248 giraffe} finish_test From d49c6930b16bae906c8017c9bf498869bce4ca39 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 6 May 2016 15:16:02 +0000 Subject: [PATCH 0392/1484] Fix a bug in sqlite_analyzer causing it report (slightly) incorrect values for the number of entries in indexes or WITHOUT ROWID tables. FossilOrigin-Name: dc37750d4e87d0c529785adceeebd838b8f8591d --- manifest | 14 +++++++------- manifest.uuid | 2 +- tool/spaceanal.tcl | 21 +++++++++++++-------- 3 files changed, 21 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index 8e5f6ffbdc..7c1f55f984 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Renumber\sinternal\sconstants\sin\sthe\sprintf()\simplemention\sfor\sa\ssmall\nperformance\simprovement. -D 2016-05-05T11:53:12.439 +C Fix\sa\sbug\sin\ssqlite_analyzer\scausing\sit\sreport\s(slightly)\sincorrect\svalues\sfor\sthe\snumber\sof\sentries\sin\sindexes\sor\sWITHOUT\sROWID\stables. +D 2016-05-06T15:16:02.765 F Makefile.in 9eda6e1c90d05c199c3ec8a7069b0682ad307657 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc db82b35aef27f412fef14d8534afc022138bcdfd @@ -1447,7 +1447,7 @@ F tool/showlocks.c 9920bcc64f58378ff1118caead34147201f48c68 F tool/showstat4.c bda40d6e395df7edb6e9ea630784d3d762c35b4b F tool/showwal.c ec79959834f7b21f1e0a2aa52bb7c056d2203977 F tool/soak1.tcl 8d407956e1a45b485a8e072470a3e629a27037fe -F tool/spaceanal.tcl 93c1fdc9733c525b17a2024c7df193daa002e037 +F tool/spaceanal.tcl 85d90e6674d8298e3eaf82dbcef3abc2d5317f3e F tool/speedtest.tcl 06c76698485ccf597b9e7dbb1ac70706eb873355 F tool/speedtest16.c ecb6542862151c3e6509bbc00509b234562ae81e F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff @@ -1487,7 +1487,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 71af9ac165ac02272f4886f69bd9ab4770fd7bb6 -R 89655379113728f544ce9a18ad294b0b -U drh -Z f65addcdc03169dedb02067b28293d6c +P 69d11447f4b1a8c536c3b6573d2a3419da870412 +R 56e7e963139ae94efddd96a9288ff8e5 +U dan +Z 82199c527d2c64b9169490d91c3a80bb diff --git a/manifest.uuid b/manifest.uuid index 4a4e62d8ed..aa435a5204 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -69d11447f4b1a8c536c3b6573d2a3419da870412 \ No newline at end of file +dc37750d4e87d0c529785adceeebd838b8f8591d \ No newline at end of file diff --git a/tool/spaceanal.tcl b/tool/spaceanal.tcl index 38d954162e..eef1192a1d 100644 --- a/tool/spaceanal.tcl +++ b/tool/spaceanal.tcl @@ -152,6 +152,7 @@ set tabledef {CREATE TABLE space_used( name clob, -- Name of a table or index in the database file tblname clob, -- Name of associated table is_index boolean, -- TRUE if it is an index, false for a table + is_without_rowid boolean, -- TRUE if WITHOUT ROWID table nentry int, -- Number of entries in the BTree leaf_entries int, -- Number of leaf entries depth int, -- Depth of the b-tree @@ -184,7 +185,7 @@ set sql { SELECT name, tbl_name FROM sqlite_master WHERE rootpage>0 } foreach {name tblname} [concat sqlite_master sqlite_master [db eval $sql]] { set is_index [expr {$name!=$tblname}] - set idx_btree [expr {$is_index || [is_without_rowid $name]}] + set is_without_rowid [is_without_rowid $name] db eval { SELECT sum(ncell) AS nentry, @@ -235,6 +236,7 @@ foreach {name tblname} [concat sqlite_master sqlite_master [db eval $sql]] { $name, $tblname, $is_index, + $is_without_rowid, $nentry, $leaf_entries, $depth, @@ -330,12 +332,15 @@ proc subreport {title where showFrag} { # following query returns exactly one row (because it is an aggregate). # # The results of the query are stored directly by SQLite into local - # variables (i.e. $nentry, $nleaf etc.). + # variables (i.e. $nentry, $payload etc.). # mem eval " SELECT - int(sum(nentry)) AS nentry, - int(sum(leaf_entries)) AS nleaf, + int(sum( + CASE WHEN (is_without_rowid OR is_index) THEN nentry + ELSE leaf_entries + END + )) AS nentry, int(sum(payload)) AS payload, int(sum(ovfl_payload)) AS ovfl_payload, max(mx_payload) AS mx_payload, @@ -375,8 +380,8 @@ proc subreport {title where showFrag} { set storage [expr {$total_pages*$pageSize}] set payload_percent [percent $payload $storage {of storage consumed}] set total_unused [expr {$ovfl_unused+$int_unused+$leaf_unused}] - set avg_payload [divide $payload $nleaf] - set avg_unused [divide $total_unused $nleaf] + set avg_payload [divide $payload $nentry] + set avg_unused [divide $total_unused $nentry] if {$int_pages>0} { # TODO: Is this formula correct? set nTab [mem eval " @@ -390,12 +395,12 @@ proc subreport {title where showFrag} { "] set avg_fanout [format %.2f $avg_fanout] } - set ovfl_cnt_percent [percent $ovfl_cnt $nleaf {of all entries}] + set ovfl_cnt_percent [percent $ovfl_cnt $nentry {of all entries}] # Print out the sub-report statistics. # statline {Percentage of total database} $total_pages_percent - statline {Number of entries} $nleaf + statline {Number of entries} $nentry statline {Bytes of storage consumed} $storage if {$compressed_size!=$storage} { set compressed_size [expr {$compressed_size+$compressOverhead*$total_pages}] From bcf6884afdbcdf193308dd393e1360e5f8f4289a Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 6 May 2016 16:06:59 +0000 Subject: [PATCH 0393/1484] In the WHERE generator, when building code for a DELETE operation, make sure that seeks to the main table are not deferred. This is a better fix for the [16c9801ceba49] bug than the previous. FossilOrigin-Name: 150dd09ebd7b17234a79e1811a0fae8b0a7a40d5 --- manifest | 23 ++++++++++------------- manifest.uuid | 2 +- src/delete.c | 2 +- src/sqliteInt.h | 1 + src/where.c | 2 +- src/wherecode.c | 7 +++++-- test/intpkey.test | 8 ++++++++ 7 files changed, 27 insertions(+), 18 deletions(-) diff --git a/manifest b/manifest index fb2ac900b5..459b5d3727 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Do\snot\sscan\sindexes\sthat\shave\sthe\sinteger\sprimary\skey\sas\stheir\sleft-most\ncolumn.\s\sThis\sfixes\sthe\scrash\sof\sticket\s[16c9801ceba]\sbut\sit\sseems\slike\nthe\swrong\sfix.\s\sMore\sinvestigation\sneeded. -D 2016-05-06T11:31:10.902 +C In\sthe\sWHERE\sgenerator,\swhen\sbuilding\scode\sfor\sa\sDELETE\soperation,\smake\ssure\nthat\sseeks\sto\sthe\smain\stable\sare\snot\sdeferred.\nThis\sis\sa\sbetter\sfix\sfor\sthe\s[16c9801ceba49]\sbug\sthan\sthe\sprevious. +D 2016-05-06T16:06:59.602 F Makefile.in 9eda6e1c90d05c199c3ec8a7069b0682ad307657 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc db82b35aef27f412fef14d8534afc022138bcdfd @@ -330,7 +330,7 @@ F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 60e135af364d777a9ab41c97e5e89cd224da6198 F src/date.c 1cc9fb516ec9932c6fd4d2a0d2f8bc4480145c39 F src/dbstat.c c845548d4346e606e2f2b7d2e714ace2b8a7dd1b -F src/delete.c 912908dea57778737d4bab632f00e48b550d10ea +F src/delete.c 4aba4214a377ce8ddde2d2e609777bcc8235200f F src/expr.c 8796c0739b2ad091e6779253f62aad6e767e2be1 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 4c0bd09e602b8ae8d36d81e31e4872d0b53c87bb @@ -382,7 +382,7 @@ F src/shell.c 14ff7f660530a52b117d110ba3390b7b2eb719b6 F src/sqlite.h.in 9984129d86243424b765fcb3f147c697bd20bb54 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 98f72cbfe00169c39089115427d06ea05fe4b4a2 -F src/sqliteInt.h c8483dd77894a72d38a76b6251a4ac949a37d6e8 +F src/sqliteInt.h 4ab5884aa7dd1cfbb1a34f60d8a919f6584c4aa1 F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 @@ -457,9 +457,9 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 4db22ed7e77bcf672b1a685d6ddeffba8d5be302 F src/wal.h 2f7c831cf3b071fa548bf2d5cac640846a7ff19c F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354 -F src/where.c a7ce00ffd7844495582af957a222602e517b14de +F src/where.c 019e5b10dedcf54ef077ce23dd8fce38d614dcf4 F src/whereInt.h 3b1fc240e322613ba4e9dc857ca9c7c3390acc74 -F src/wherecode.c 28951741be3974701186281ced0564e9586a0db3 +F src/wherecode.c 6e2da2449d5589b2ce988afae125a61cad665c86 F src/whereexpr.c eacc0e60d029a082b4fc0cc42ea98544add1319e F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -847,7 +847,7 @@ F test/insert5.test 394f96728d1258f406fe5f5aeb0aaf29487c39a6 F test/instr.test 737bbf80685232033f3abedc6ae92f75860b5dd2 F test/intarray.test 066b7d7ac38d25bf96f87f1b017bfc687551cdd4 F test/interrupt.test dfe9a67a94b0b2d8f70545ba1a6cca10780d71cc -F test/intpkey.test 18ec1f3f39a18ed51d2dbd9ce184cc421191ff70 +F test/intpkey.test bd82146463500ecb5e793b5ea2865eaa1c7bdfb6 F test/io.test f95bca1783b01ea7761671560d023360d2dfa4cc F test/ioerr.test 2a24bd6ed5a8b062e64bfe1f6cf94fb25e92210d F test/ioerr2.test 2593563599e2cc6b6b4fcf5878b177bdd5d8df26 @@ -1487,10 +1487,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 69d11447f4b1a8c536c3b6573d2a3419da870412 -R 88ac4ed286db19382d4843a346c44c60 -T *branch * ticket-16c9801ce -T *sym-ticket-16c9801ce * -T -sym-trunk * +P 50312273ffaf1bd4bfdc73865fa0b19166968429 +R 0aaabe1d44ff452855f4b1d0d09524f8 U drh -Z a8fa257e80e1a139c1678ae44101daf6 +Z 9200ae75c074ea360e36df5da26c6a08 diff --git a/manifest.uuid b/manifest.uuid index 1745de5e7c..709cd8f436 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -50312273ffaf1bd4bfdc73865fa0b19166968429 \ No newline at end of file +150dd09ebd7b17234a79e1811a0fae8b0a7a40d5 \ No newline at end of file diff --git a/src/delete.c b/src/delete.c index dab1fd40cd..e9e669e21c 100644 --- a/src/delete.c +++ b/src/delete.c @@ -373,7 +373,7 @@ void sqlite3DeleteFrom( }else #endif /* SQLITE_OMIT_TRUNCATE_OPTIMIZATION */ { - u16 wcf = WHERE_ONEPASS_DESIRED|WHERE_DUPLICATES_OK; + u16 wcf = WHERE_ONEPASS_DESIRED|WHERE_DUPLICATES_OK|WHERE_SEEK_TABLE; if( sNC.ncFlags & NC_VarSelect ) bComplex = 1; wcf |= (bComplex ? 0 : WHERE_ONEPASS_MULTIROW); if( HasRowid(pTab) ){ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 783f0f56c3..de06f6d7d8 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2543,6 +2543,7 @@ struct SrcList { #define WHERE_REOPEN_IDX 0x1000 /* Try to use OP_ReopenIdx */ #define WHERE_ONEPASS_MULTIROW 0x2000 /* ONEPASS is ok with multiple rows */ #define WHERE_USE_LIMIT 0x4000 /* There is a constant LIMIT clause */ +#define WHERE_SEEK_TABLE 0x8000 /* Always seek the main table */ /* Allowed return values from sqlite3WhereIsDistinct() */ diff --git a/src/where.c b/src/where.c index 9aa068d660..d45a872c85 100644 --- a/src/where.c +++ b/src/where.c @@ -289,7 +289,7 @@ static WhereTerm *whereScanInit( j = iColumn; iColumn = pIdx->aiColumn[j]; if( iColumn==XN_EXPR ) pScan->pIdxExpr = pIdx->aColExpr->a[j].pExpr; - if( iColumn==pIdx->pTable->iPKey && j>0 ) iColumn = XN_ROWID; + if( iColumn==pIdx->pTable->iPKey ) iColumn = XN_ROWID; } if( pIdx && iColumn>=0 ){ pScan->idxaff = pIdx->pTable->aCol[iColumn].affinity; diff --git a/src/wherecode.c b/src/wherecode.c index 77543a9388..c1397b8a29 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -1324,7 +1324,9 @@ Bitmask sqlite3WhereCodeOneLoopStart( if( omitTable ){ /* pIdx is a covering index. No need to access the main table. */ }else if( HasRowid(pIdx->pTable) ){ - if( pWInfo->eOnePass!=ONEPASS_OFF ){ + if( pWInfo->eOnePass!=ONEPASS_OFF + || (pWInfo->wctrlFlags & WHERE_SEEK_TABLE)!=0 + ){ iRowidReg = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, iRowidReg); sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg); @@ -1520,7 +1522,8 @@ Bitmask sqlite3WhereCodeOneLoopStart( wctrlFlags = WHERE_OMIT_OPEN_CLOSE | WHERE_FORCE_TABLE | WHERE_ONETABLE_ONLY - | WHERE_NO_AUTOINDEX; + | WHERE_NO_AUTOINDEX + | (pWInfo->wctrlFlags & WHERE_SEEK_TABLE); for(ii=0; iinTerm; ii++){ WhereTerm *pOrTerm = &pOrWc->a[ii]; if( pOrTerm->leftCursor==iCur || (pOrTerm->eOperator & WO_AND)!=0 ){ diff --git a/test/intpkey.test b/test/intpkey.test index 0158ad7766..4680e2270e 100644 --- a/test/intpkey.test +++ b/test/intpkey.test @@ -627,5 +627,13 @@ do_execsql_test intpkey-17.0 { DELETE FROM t17 WHERE x=99 OR x<130; SELECT * FROM t17; } {248 giraffe} +do_execsql_test intpkey-17.1 { + DROP INDEX t17x; + DELETE FROM t17; + INSERT INTO t17(x,y) VALUES(123,'elephant'),(248,'giraffe'); + CREATE INDEX t17x ON t17(abs(x)); + DELETE FROM t17 WHERE abs(x) IS NULL OR abs(x)<130; + SELECT * FROM t17; +} {248 giraffe} finish_test From 39332fb0f7cf2247cd31bb6f9ca76ca54d07fc05 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 6 May 2016 16:30:34 +0000 Subject: [PATCH 0394/1484] Fix an error in main.mk causing testfixture to use individual fts5 source code files instead of fts5.c. FossilOrigin-Name: 933a1c818c1d1ccec8680e1ba87f2cbe37cc9f7d --- main.mk | 3 +-- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/main.mk b/main.mk index 1e791416d8..9111b1ab64 100644 --- a/main.mk +++ b/main.mk @@ -388,8 +388,7 @@ TESTSRC2 = \ $(TOP)/ext/fts3/fts3_write.c \ $(TOP)/ext/async/sqlite3async.c \ $(TOP)/ext/session/sqlite3session.c \ - $(TOP)/ext/session/test_session.c \ - $(FTS5_SRC) + $(TOP)/ext/session/test_session.c # Header files used by all library source files. # diff --git a/manifest b/manifest index 7c1f55f984..0525e61f73 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sbug\sin\ssqlite_analyzer\scausing\sit\sreport\s(slightly)\sincorrect\svalues\sfor\sthe\snumber\sof\sentries\sin\sindexes\sor\sWITHOUT\sROWID\stables. -D 2016-05-06T15:16:02.765 +C Fix\san\serror\sin\smain.mk\scausing\stestfixture\sto\suse\sindividual\sfts5\ssource\scode\sfiles\sinstead\sof\sfts5.c. +D 2016-05-06T16:30:34.529 F Makefile.in 9eda6e1c90d05c199c3ec8a7069b0682ad307657 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc db82b35aef27f412fef14d8534afc022138bcdfd @@ -302,7 +302,7 @@ F ext/userauth/userauth.c 5fa3bdb492f481bbc1709fc83c91ebd13460c69e F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60 -F main.mk a283660f75c3c4b75d8c9d12a40fa38a066eee9d +F main.mk 86e6a8d79186ace5ff8b306093da1728d953f796 F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 @@ -1487,7 +1487,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 69d11447f4b1a8c536c3b6573d2a3419da870412 -R 56e7e963139ae94efddd96a9288ff8e5 +P dc37750d4e87d0c529785adceeebd838b8f8591d +R c15766ea1c9925837a701d30f137e7d3 U dan -Z 82199c527d2c64b9169490d91c3a80bb +Z ee202f54aac91dd67f57f6a979bc066b diff --git a/manifest.uuid b/manifest.uuid index aa435a5204..e0a918072d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -dc37750d4e87d0c529785adceeebd838b8f8591d \ No newline at end of file +933a1c818c1d1ccec8680e1ba87f2cbe37cc9f7d \ No newline at end of file From a3fd75d4265306f6aefecafe6368c57e16fc60b9 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 6 May 2016 18:47:23 +0000 Subject: [PATCH 0395/1484] Corrections to comments on the whereScanInit() interface. FossilOrigin-Name: ab7ab415d19524f6c3901e474d3a154f55d28530 --- manifest | 13 ++++++------- manifest.uuid | 2 +- src/where.c | 14 +++++++++----- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 6fd1d2d402..a7874dbd66 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C For\sDELETE\soperations,\smake\ssure\sthat\sseeks\son\sthe\smain\stable\sare\snot\ndeferred,\ssince\sif\sthey\sare\sand\snone\sof\sthe\sindexes\sreference\scolumns\sof\nthe\stable,\sthe\sseek\smight\snever\soccur\suntil\sthe\sOP_Delete\sopcode,\swhich\sis\ntoo\slate.\s\sFix\sfor\sticket\s[16c9801ceba49]. -D 2016-05-06T16:49:54.299 +C Corrections\sto\scomments\son\sthe\swhereScanInit()\sinterface. +D 2016-05-06T18:47:23.830 F Makefile.in 9eda6e1c90d05c199c3ec8a7069b0682ad307657 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc db82b35aef27f412fef14d8534afc022138bcdfd @@ -457,7 +457,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 4db22ed7e77bcf672b1a685d6ddeffba8d5be302 F src/wal.h 2f7c831cf3b071fa548bf2d5cac640846a7ff19c F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354 -F src/where.c 019e5b10dedcf54ef077ce23dd8fce38d614dcf4 +F src/where.c fd321cc2c5ee346a2e146b93892ed01bb7a839c0 F src/whereInt.h 3b1fc240e322613ba4e9dc857ca9c7c3390acc74 F src/wherecode.c 6e2da2449d5589b2ce988afae125a61cad665c86 F src/whereexpr.c eacc0e60d029a082b4fc0cc42ea98544add1319e @@ -1487,8 +1487,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 933a1c818c1d1ccec8680e1ba87f2cbe37cc9f7d 150dd09ebd7b17234a79e1811a0fae8b0a7a40d5 -R 999c47253628cf8504ca9429ccbba492 -T +closed 150dd09ebd7b17234a79e1811a0fae8b0a7a40d5 +P 93a2bace5704f7ecad56541a6b3e06a88f7f393f +R 3ca4ebdcc8bebe388d97851d25aa812d U drh -Z 0a4c84a453e835d42d347d7d3d2d52db +Z e6d944ba38affdbccc4e07da270b6c3d diff --git a/manifest.uuid b/manifest.uuid index f2214b4f51..b4a061c620 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -93a2bace5704f7ecad56541a6b3e06a88f7f393f \ No newline at end of file +ab7ab415d19524f6c3901e474d3a154f55d28530 \ No newline at end of file diff --git a/src/where.c b/src/where.c index d45a872c85..0c3f05f7f2 100644 --- a/src/where.c +++ b/src/where.c @@ -261,7 +261,10 @@ static WhereTerm *whereScanNext(WhereScan *pScan){ ** ** The scanner will be searching the WHERE clause pWC. It will look ** for terms of the form "X " where X is column iColumn of table -** iCur. The must be one of the operators described by opMask. +** iCur. Or if pIdx!=0 then X is column iColumn of index pIdx. pIdx +** must be one of the indexes of table iCur. +** +** The must be one of the operators described by opMask. ** ** If the search is for X and the WHERE clause contains terms of the ** form X=Y then this routine might also return terms of the form @@ -309,11 +312,12 @@ static WhereTerm *whereScanInit( /* ** Search for a term in the WHERE clause that is of the form "X " -** where X is a reference to the iColumn of table iCur and is one of -** the WO_xx operator codes specified by the op parameter. -** Return a pointer to the term. Return 0 if not found. +** where X is a reference to the iColumn of table iCur or of index pIdx +** if pIdx!=0 and is one of the WO_xx operator codes specified by +** the op parameter. Return a pointer to the term. Return 0 if not found. ** -** If pIdx!=0 then search for terms matching the iColumn-th column of pIdx +** If pIdx!=0 then it must be one of the indexes of table iCur. +** Search for terms matching the iColumn-th column of pIdx ** rather than the iColumn-th column of table iCur. ** ** The term returned might by Y= if there is another constraint in From f09c48233a1238f45be65b57986e543d7178711f Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 6 May 2016 20:23:12 +0000 Subject: [PATCH 0396/1484] Simplification to the logic used to decide between OP_Seek and OP_NotExists. Use OP_NotExists for both DELETE and UPDATE. FossilOrigin-Name: 3a695263183303e3f64eb2320752d0fdef53eaf2 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/update.c | 3 ++- src/wherecode.c | 4 +--- test/intpkey.test | 8 +++++++- 5 files changed, 19 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index a7874dbd66..dc724954ef 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Corrections\sto\scomments\son\sthe\swhereScanInit()\sinterface. -D 2016-05-06T18:47:23.830 +C Simplification\sto\sthe\slogic\sused\sto\sdecide\sbetween\sOP_Seek\sand\sOP_NotExists.\nUse\sOP_NotExists\sfor\sboth\sDELETE\sand\sUPDATE. +D 2016-05-06T20:23:12.122 F Makefile.in 9eda6e1c90d05c199c3ec8a7069b0682ad307657 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc db82b35aef27f412fef14d8534afc022138bcdfd @@ -439,7 +439,7 @@ F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c 3b29883b0ce4a6c6f643965b66b5ca6613178e59 F src/treeview.c e4b41a37530a191579d3c53142cc44ee2eb99373 F src/trigger.c e14840ee0c3e549e758ec9bf3e4146e166002280 -F src/update.c 3e67ab3c0814635f355fb1f8ab010a2b9e016e7d +F src/update.c 4f05ea8cddfa367d045e03589756c02199e8f9bd F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 810ec3f22e2d1b62e66c30fe3621ebdedd23584d F src/vacuum.c feb1eabb20987983d9350cad98299b21fa811f52 @@ -459,7 +459,7 @@ F src/wal.h 2f7c831cf3b071fa548bf2d5cac640846a7ff19c F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354 F src/where.c fd321cc2c5ee346a2e146b93892ed01bb7a839c0 F src/whereInt.h 3b1fc240e322613ba4e9dc857ca9c7c3390acc74 -F src/wherecode.c 6e2da2449d5589b2ce988afae125a61cad665c86 +F src/wherecode.c 23fc19ca546ce323ba5c4be96b88e3ba08cf6b8f F src/whereexpr.c eacc0e60d029a082b4fc0cc42ea98544add1319e F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -847,7 +847,7 @@ F test/insert5.test 394f96728d1258f406fe5f5aeb0aaf29487c39a6 F test/instr.test 737bbf80685232033f3abedc6ae92f75860b5dd2 F test/intarray.test 066b7d7ac38d25bf96f87f1b017bfc687551cdd4 F test/interrupt.test dfe9a67a94b0b2d8f70545ba1a6cca10780d71cc -F test/intpkey.test bd82146463500ecb5e793b5ea2865eaa1c7bdfb6 +F test/intpkey.test 890cc2df52c2dd10ae5ef922c1edcdfa2a4228f8 F test/io.test f95bca1783b01ea7761671560d023360d2dfa4cc F test/ioerr.test 2a24bd6ed5a8b062e64bfe1f6cf94fb25e92210d F test/ioerr2.test 2593563599e2cc6b6b4fcf5878b177bdd5d8df26 @@ -1487,7 +1487,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 93a2bace5704f7ecad56541a6b3e06a88f7f393f -R 3ca4ebdcc8bebe388d97851d25aa812d +P ab7ab415d19524f6c3901e474d3a154f55d28530 +R f6a10a5aa5f2ff9434de04bd402f6c3f U drh -Z e6d944ba38affdbccc4e07da270b6c3d +Z 447839f87caf188b0aa6e0197947c00d diff --git a/manifest.uuid b/manifest.uuid index b4a061c620..51f86604f1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ab7ab415d19524f6c3901e474d3a154f55d28530 \ No newline at end of file +3a695263183303e3f64eb2320752d0fdef53eaf2 \ No newline at end of file diff --git a/src/update.c b/src/update.c index 7b38c5bcc5..1436501264 100644 --- a/src/update.c +++ b/src/update.c @@ -352,7 +352,8 @@ void sqlite3Update( if( HasRowid(pTab) ){ sqlite3VdbeAddOp3(v, OP_Null, 0, regRowSet, regOldRowid); pWInfo = sqlite3WhereBegin( - pParse, pTabList, pWhere, 0, 0, WHERE_ONEPASS_DESIRED, iIdxCur + pParse, pTabList, pWhere, 0, 0, + WHERE_ONEPASS_DESIRED | WHERE_SEEK_TABLE, iIdxCur ); if( pWInfo==0 ) goto update_cleanup; okOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass); diff --git a/src/wherecode.c b/src/wherecode.c index c1397b8a29..aee50c3142 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -1324,9 +1324,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( if( omitTable ){ /* pIdx is a covering index. No need to access the main table. */ }else if( HasRowid(pIdx->pTable) ){ - if( pWInfo->eOnePass!=ONEPASS_OFF - || (pWInfo->wctrlFlags & WHERE_SEEK_TABLE)!=0 - ){ + if( (pWInfo->wctrlFlags & WHERE_SEEK_TABLE)!=0 ){ iRowidReg = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, iRowidReg); sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg); diff --git a/test/intpkey.test b/test/intpkey.test index 4680e2270e..12802ca44b 100644 --- a/test/intpkey.test +++ b/test/intpkey.test @@ -631,9 +631,15 @@ do_execsql_test intpkey-17.1 { DROP INDEX t17x; DELETE FROM t17; INSERT INTO t17(x,y) VALUES(123,'elephant'),(248,'giraffe'); - CREATE INDEX t17x ON t17(abs(x)); + CREATE UNIQUE INDEX t17x ON t17(abs(x)); DELETE FROM t17 WHERE abs(x) IS NULL OR abs(x)<130; SELECT * FROM t17; } {248 giraffe} +do_execsql_test intpkey-17.2 { + DELETE FROM t17; + INSERT INTO t17(x,y) VALUES(123,'elephant'),(248,'giraffe'); + UPDATE FROM t17 SET y='ostrich' WHERE abs(x)=248; + SELECT * FROM t17 ORDER BY +x; +} {123 elephant 248 ostrich} finish_test From 3eead2702294f5f9cbf50328a12e7dab6f4a3069 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 7 May 2016 12:15:15 +0000 Subject: [PATCH 0397/1484] Fix typo in the intpkey-17.2 test. FossilOrigin-Name: a45fda657d987f5c923d141584841a6c62dfb504 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/intpkey.test | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index dc724954ef..39e77dbc87 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Simplification\sto\sthe\slogic\sused\sto\sdecide\sbetween\sOP_Seek\sand\sOP_NotExists.\nUse\sOP_NotExists\sfor\sboth\sDELETE\sand\sUPDATE. -D 2016-05-06T20:23:12.122 +C Fix\stypo\sin\sthe\sintpkey-17.2\stest. +D 2016-05-07T12:15:15.906 F Makefile.in 9eda6e1c90d05c199c3ec8a7069b0682ad307657 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc db82b35aef27f412fef14d8534afc022138bcdfd @@ -847,7 +847,7 @@ F test/insert5.test 394f96728d1258f406fe5f5aeb0aaf29487c39a6 F test/instr.test 737bbf80685232033f3abedc6ae92f75860b5dd2 F test/intarray.test 066b7d7ac38d25bf96f87f1b017bfc687551cdd4 F test/interrupt.test dfe9a67a94b0b2d8f70545ba1a6cca10780d71cc -F test/intpkey.test 890cc2df52c2dd10ae5ef922c1edcdfa2a4228f8 +F test/intpkey.test ac71107a49a06492b69b82aafaf225400598d3c8 F test/io.test f95bca1783b01ea7761671560d023360d2dfa4cc F test/ioerr.test 2a24bd6ed5a8b062e64bfe1f6cf94fb25e92210d F test/ioerr2.test 2593563599e2cc6b6b4fcf5878b177bdd5d8df26 @@ -1487,7 +1487,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ab7ab415d19524f6c3901e474d3a154f55d28530 -R f6a10a5aa5f2ff9434de04bd402f6c3f +P 3a695263183303e3f64eb2320752d0fdef53eaf2 +R 51aec2bae3f4c90b051a05d513fd048f U drh -Z 447839f87caf188b0aa6e0197947c00d +Z 7d38c3073c92b6f84127f76ce4d99aa3 diff --git a/manifest.uuid b/manifest.uuid index 51f86604f1..572dd73cd1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3a695263183303e3f64eb2320752d0fdef53eaf2 \ No newline at end of file +a45fda657d987f5c923d141584841a6c62dfb504 \ No newline at end of file diff --git a/test/intpkey.test b/test/intpkey.test index 12802ca44b..a56cab4c69 100644 --- a/test/intpkey.test +++ b/test/intpkey.test @@ -638,7 +638,7 @@ do_execsql_test intpkey-17.1 { do_execsql_test intpkey-17.2 { DELETE FROM t17; INSERT INTO t17(x,y) VALUES(123,'elephant'),(248,'giraffe'); - UPDATE FROM t17 SET y='ostrich' WHERE abs(x)=248; + UPDATE t17 SET y='ostrich' WHERE abs(x)=248; SELECT * FROM t17 ORDER BY +x; } {123 elephant 248 ostrich} From e8da01c189b2bde0fca85ae549cecdd022869e7c Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 7 May 2016 12:15:34 +0000 Subject: [PATCH 0398/1484] Make the sqlite3DeleteTable() routine smaller and faster. FossilOrigin-Name: d75140b851a34a5eb66041e294e421628efbc5ba --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/build.c | 17 +++++++++-------- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index 39e77dbc87..c4b4c5d9f8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\stypo\sin\sthe\sintpkey-17.2\stest. -D 2016-05-07T12:15:15.906 +C Make\sthe\ssqlite3DeleteTable()\sroutine\ssmaller\sand\sfaster. +D 2016-05-07T12:15:34.317 F Makefile.in 9eda6e1c90d05c199c3ec8a7069b0682ad307657 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc db82b35aef27f412fef14d8534afc022138bcdfd @@ -324,7 +324,7 @@ F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 F src/btree.c 3ae6aea66cc4e13d30162ff0d0d43c7088e34abf F src/btree.h a5008b9afe56e8e54ade6c436a910f112defcca9 F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 -F src/build.c 42e8ee74dfa3a4b99bfb2c201f8a66ab50688d95 +F src/build.c d65be62254ca9df36e1e1c433324f0333f80009c F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 60e135af364d777a9ab41c97e5e89cd224da6198 @@ -1487,7 +1487,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 3a695263183303e3f64eb2320752d0fdef53eaf2 -R 51aec2bae3f4c90b051a05d513fd048f +P a45fda657d987f5c923d141584841a6c62dfb504 +R de01d2c88028a3b709951f9d3730409b U drh -Z 7d38c3073c92b6f84127f76ce4d99aa3 +Z c83c111125ba50dd275150f90f412c72 diff --git a/manifest.uuid b/manifest.uuid index 572dd73cd1..216472cb11 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a45fda657d987f5c923d141584841a6c62dfb504 \ No newline at end of file +d75140b851a34a5eb66041e294e421628efbc5ba \ No newline at end of file diff --git a/src/build.c b/src/build.c index c7541bc9d8..2fa4e3102f 100644 --- a/src/build.c +++ b/src/build.c @@ -592,16 +592,10 @@ void sqlite3DeleteColumnNames(sqlite3 *db, Table *pTable){ ** db parameter can be used with db->pnBytesFreed to measure the memory ** used by the Table object. */ -void sqlite3DeleteTable(sqlite3 *db, Table *pTable){ +static void SQLITE_NOINLINE deleteTable(sqlite3 *db, Table *pTable){ Index *pIndex, *pNext; TESTONLY( int nLookaside; ) /* Used to verify lookaside not used for schema */ - assert( !pTable || pTable->nRef>0 ); - - /* Do not delete the table until the reference count reaches zero. */ - if( !pTable ) return; - if( ((!db || db->pnBytesFreed==0) && (--pTable->nRef)>0) ) return; - /* Record the number of outstanding lookaside allocations in schema Tables ** prior to doing any free() operations. Since schema Tables do not use ** lookaside, this number should not change. */ @@ -641,6 +635,13 @@ void sqlite3DeleteTable(sqlite3 *db, Table *pTable){ /* Verify that no lookaside memory was used by schema tables */ assert( nLookaside==0 || nLookaside==db->lookaside.nOut ); } +void sqlite3DeleteTable(sqlite3 *db, Table *pTable){ + /* Do not delete the table until the reference count reaches zero. */ + if( !pTable ) return; + if( ((!db || db->pnBytesFreed==0) && (--pTable->nRef)>0) ) return; + deleteTable(db, pTable); +} + /* ** Unlink the given table from the hash tables and the delete the @@ -2221,7 +2222,7 @@ int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ pTable->nCol = 0; nErr++; } - if( pSelTab ) sqlite3DeleteTable(db, pSelTab); + sqlite3DeleteTable(db, pSelTab); sqlite3SelectDelete(db, pSel); db->lookaside.bDisable--; } else { From 170b66493df878f5599dc78670086937e23c92f1 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 9 May 2016 18:05:44 +0000 Subject: [PATCH 0399/1484] Fix the FTS5 xQueryPhrase() API function so that it recognizes column filters. FossilOrigin-Name: 48505cde05d74748454dc135d4ec25954ecf020e --- ext/fts5/fts5_expr.c | 11 +++++++++++ ext/fts5/test/fts5aux.test | 32 ++++++++++++++++++++++++++++++++ manifest | 16 ++++++++-------- manifest.uuid | 2 +- 4 files changed, 52 insertions(+), 9 deletions(-) diff --git a/ext/fts5/fts5_expr.c b/ext/fts5/fts5_expr.c index eada84f70e..a48fa6e9d0 100644 --- a/ext/fts5/fts5_expr.c +++ b/ext/fts5/fts5_expr.c @@ -1655,6 +1655,17 @@ int sqlite3Fts5ExprClonePhrase( pNew->pRoot->pNear = (Fts5ExprNearset*)sqlite3Fts5MallocZero(&rc, sizeof(Fts5ExprNearset) + sizeof(Fts5ExprPhrase*)); } + if( rc==SQLITE_OK ){ + Fts5Colset *pColsetOrig = pOrig->pNode->pNear->pColset; + if( pColsetOrig ){ + int nByte = sizeof(Fts5Colset) + pColsetOrig->nCol * sizeof(int); + Fts5Colset *pColset = (Fts5Colset*)sqlite3Fts5MallocZero(&rc, nByte); + if( pColset ){ + memcpy(pColset, pColsetOrig, nByte); + } + pNew->pRoot->pNear->pColset = pColset; + } + } for(i=0; rc==SQLITE_OK && inTerm; i++){ int tflags = 0; diff --git a/ext/fts5/test/fts5aux.test b/ext/fts5/test/fts5aux.test index 995fe85784..fa3167a4d1 100644 --- a/ext/fts5/test/fts5aux.test +++ b/ext/fts5/test/fts5aux.test @@ -246,5 +246,37 @@ foreach {tn lRow res} { } $res } +#------------------------------------------------------------------------- +# Test the built-in bm25() demo. +# +reset_db +do_execsql_test 9.1 { + CREATE VIRTUAL TABLE t1 USING fts5(a, b); + INSERT INTO t1 VALUES('a', NULL); -- 1 + INSERT INTO t1 VALUES('a', NULL); -- 2 + INSERT INTO t1 VALUES('a', NULL); -- 3 + INSERT INTO t1 VALUES('a', NULL); -- 4 + INSERT INTO t1 VALUES('a', NULL); -- 5 + INSERT INTO t1 VALUES('a', NULL); -- 6 + INSERT INTO t1 VALUES('a', NULL); -- 7 + INSERT INTO t1 VALUES('a', NULL); -- 8 + INSERT INTO t1 VALUES(NULL, 'a a b'); -- 9 + INSERT INTO t1 VALUES(NULL, 'b b a'); -- 10 +} + +do_execsql_test 9.2 { + SELECT rowid FROM t1('a AND b') ORDER BY rank; +} { + 10 9 +} + +do_execsql_test 9.3 { + SELECT rowid FROM t1('b:a AND b:b') ORDER BY rank; +} { + 9 10 +} + + + finish_test diff --git a/manifest b/manifest index c4b4c5d9f8..5e1631de3d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\sthe\ssqlite3DeleteTable()\sroutine\ssmaller\sand\sfaster. -D 2016-05-07T12:15:34.317 +C Fix\sthe\sFTS5\sxQueryPhrase()\sAPI\sfunction\sso\sthat\sit\srecognizes\scolumn\sfilters. +D 2016-05-09T18:05:44.940 F Makefile.in 9eda6e1c90d05c199c3ec8a7069b0682ad307657 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc db82b35aef27f412fef14d8534afc022138bcdfd @@ -102,7 +102,7 @@ F ext/fts5/fts5Int.h 3677076aecbf645a7f2a019115c6a4ec3272dd78 F ext/fts5/fts5_aux.c daa57fb45216491814520bbb587e97bf81ced458 F ext/fts5/fts5_buffer.c 4c1502d4c956cd092c89ce4480867f9d8bf325cd F ext/fts5/fts5_config.c 5af9c360e99669d29f06492c370892394aba0857 -F ext/fts5/fts5_expr.c 5ca4bafe29aa3d27683c90e836192e4aefd20a3f +F ext/fts5/fts5_expr.c da2b33c2aac91e96641c0a7cf2bbaa36eb2667f7 F ext/fts5/fts5_hash.c 880998e596b60f078348d48732ca4ad9a90caad2 F ext/fts5/fts5_index.c b429e23fabb57506f71e406997cc46b89190dc97 F ext/fts5/fts5_main.c b4a0fc5bf17f2f1f056ee76cdd7d2af08b360f55 @@ -131,7 +131,7 @@ F ext/fts5/test/fts5ak.test fb26389985407826f6076bb9f382c67d3db6b5d9 F ext/fts5/test/fts5al.test 18c277f5986df0a3d9071dfd7128afeb16fe9d5d F ext/fts5/test/fts5alter.test 6022c61467a82aa11c70822ccad22b328dcf0d04 F ext/fts5/test/fts5auto.test 401c20e89f1114d733b94809be1e6f893e16c09e -F ext/fts5/test/fts5aux.test 8c687c948cc98e9a94be014df7d518acc1b3b74f +F ext/fts5/test/fts5aux.test 5dd158a1e7869e27e9762a2a452b189c728d1be3 F ext/fts5/test/fts5auxdata.test 141a7cbffcceb1bd2799b4b29c183ff8780d586e F ext/fts5/test/fts5bigpl.test 04ee0d7eebbebf17c31f5a0b5c5f9494eac3a0cb F ext/fts5/test/fts5bigtok.test 017a9397b14e7598883a6328ead4a6539b42d59a @@ -1487,7 +1487,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a45fda657d987f5c923d141584841a6c62dfb504 -R de01d2c88028a3b709951f9d3730409b -U drh -Z c83c111125ba50dd275150f90f412c72 +P d75140b851a34a5eb66041e294e421628efbc5ba +R 0be9ab31bb2adcc738c00ca21c762730 +U dan +Z f838a2dc20bbd55fb4fc1e757536b6a8 diff --git a/manifest.uuid b/manifest.uuid index 216472cb11..77d39a83e2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d75140b851a34a5eb66041e294e421628efbc5ba \ No newline at end of file +48505cde05d74748454dc135d4ec25954ecf020e \ No newline at end of file From ba1079ba2ace74d04c4add64a41f3d195fb2bb95 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 9 May 2016 19:03:42 +0000 Subject: [PATCH 0400/1484] Update a comment in fts5.h. No changes to code. FossilOrigin-Name: 14e53d0e2f62d82ae1d64a72fd9711548e3bf5ea --- ext/fts5/fts5.h | 12 +++++++----- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/ext/fts5/fts5.h b/ext/fts5/fts5.h index 96ecb38e33..b32e2132dd 100644 --- a/ext/fts5/fts5.h +++ b/ext/fts5/fts5.h @@ -143,11 +143,13 @@ struct Fts5PhraseIter { ** ... FROM ftstable WHERE ftstable MATCH $p ORDER BY rowid ** ** with $p set to a phrase equivalent to the phrase iPhrase of the -** current query is executed. For each row visited, the callback function -** passed as the fourth argument is invoked. The context and API objects -** passed to the callback function may be used to access the properties of -** each matched row. Invoking Api.xUserData() returns a copy of the pointer -** passed as the third argument to pUserData. +** current query is executed. Any column filter that applies to +** phrase iPhrase of the current query is included in $p. For each +** row visited, the callback function passed as the fourth argument +** is invoked. The context and API objects passed to the callback +** function may be used to access the properties of each matched row. +** Invoking Api.xUserData() returns a copy of the pointer passed as +** the third argument to pUserData. ** ** If the callback function returns any value other than SQLITE_OK, the ** query is abandoned and the xQueryPhrase function returns immediately. diff --git a/manifest b/manifest index 5e1631de3d..8e82d9444c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\sFTS5\sxQueryPhrase()\sAPI\sfunction\sso\sthat\sit\srecognizes\scolumn\sfilters. -D 2016-05-09T18:05:44.940 +C Update\sa\scomment\sin\sfts5.h.\sNo\schanges\sto\scode. +D 2016-05-09T19:03:42.623 F Makefile.in 9eda6e1c90d05c199c3ec8a7069b0682ad307657 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc db82b35aef27f412fef14d8534afc022138bcdfd @@ -97,7 +97,7 @@ F ext/fts3/unicode/UnicodeData.txt cd07314edb62d49fde34debdaf92fa2aa69011e7 F ext/fts3/unicode/mkunicode.tcl 2debed3f582d77b3fdd0b8830880250021571fd8 F ext/fts3/unicode/parseunicode.tcl da577d1384810fb4e2b209bf3313074353193e95 F ext/fts5/extract_api_docs.tcl a36e54ec777172ddd3f9a88daf593b00848368e0 -F ext/fts5/fts5.h ff9c2782e8ed890b0de2f697a8d63971939e70c7 +F ext/fts5/fts5.h b770c5e0a8d2ee071ddffc7ab722dbf3474a8abe F ext/fts5/fts5Int.h 3677076aecbf645a7f2a019115c6a4ec3272dd78 F ext/fts5/fts5_aux.c daa57fb45216491814520bbb587e97bf81ced458 F ext/fts5/fts5_buffer.c 4c1502d4c956cd092c89ce4480867f9d8bf325cd @@ -1487,7 +1487,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d75140b851a34a5eb66041e294e421628efbc5ba -R 0be9ab31bb2adcc738c00ca21c762730 +P 48505cde05d74748454dc135d4ec25954ecf020e +R 1969cb0ebb207c1f7d211b0f782f1262 U dan -Z f838a2dc20bbd55fb4fc1e757536b6a8 +Z aa90d8f8ef0b8ff7fa6722d460d8bb52 diff --git a/manifest.uuid b/manifest.uuid index 77d39a83e2..1a4227599e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -48505cde05d74748454dc135d4ec25954ecf020e \ No newline at end of file +14e53d0e2f62d82ae1d64a72fd9711548e3bf5ea \ No newline at end of file From a72a15e45a322b60c8a592a971fd4142e04cdb49 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 9 May 2016 19:58:56 +0000 Subject: [PATCH 0401/1484] Omit the unnecessary WHERE_REOPEN_IDX flag in the WHERE interface. FossilOrigin-Name: da94a6e0ebacad8f235dcd653a25474327f26137 --- manifest | 21 ++++++++++++--------- manifest.uuid | 2 +- src/sqliteInt.h | 2 +- src/where.c | 2 +- src/wherecode.c | 1 - 5 files changed, 15 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 8e82d9444c..cf88c90ca0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\sa\scomment\sin\sfts5.h.\sNo\schanges\sto\scode. -D 2016-05-09T19:03:42.623 +C Omit\sthe\sunnecessary\sWHERE_REOPEN_IDX\sflag\sin\sthe\sWHERE\sinterface. +D 2016-05-09T19:58:56.729 F Makefile.in 9eda6e1c90d05c199c3ec8a7069b0682ad307657 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc db82b35aef27f412fef14d8534afc022138bcdfd @@ -382,7 +382,7 @@ F src/shell.c 14ff7f660530a52b117d110ba3390b7b2eb719b6 F src/sqlite.h.in 9984129d86243424b765fcb3f147c697bd20bb54 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 98f72cbfe00169c39089115427d06ea05fe4b4a2 -F src/sqliteInt.h 8ec741711b8f42aae2c7a22e3d04f15270e0b6be +F src/sqliteInt.h 47a90c85a42210a05387051aaaa661f5c307703d F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 @@ -457,9 +457,9 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 4db22ed7e77bcf672b1a685d6ddeffba8d5be302 F src/wal.h 2f7c831cf3b071fa548bf2d5cac640846a7ff19c F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354 -F src/where.c fd321cc2c5ee346a2e146b93892ed01bb7a839c0 +F src/where.c ad8ad50ccf25795f6830b6b864bbfcd060ff08dd F src/whereInt.h 3b1fc240e322613ba4e9dc857ca9c7c3390acc74 -F src/wherecode.c 23fc19ca546ce323ba5c4be96b88e3ba08cf6b8f +F src/wherecode.c d227fca7d766a10fe4ba4d812210f5631f5a98b3 F src/whereexpr.c eacc0e60d029a082b4fc0cc42ea98544add1319e F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -1487,7 +1487,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 48505cde05d74748454dc135d4ec25954ecf020e -R 1969cb0ebb207c1f7d211b0f782f1262 -U dan -Z aa90d8f8ef0b8ff7fa6722d460d8bb52 +P 14e53d0e2f62d82ae1d64a72fd9711548e3bf5ea +R 91f64055039542194e221b2aa9a3eada +T *branch * dev +T *sym-dev * +T -sym-trunk * +U drh +Z 6a1a8543c69edff1da4c7cb6389abc41 diff --git a/manifest.uuid b/manifest.uuid index 1a4227599e..6ae6f055ff 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -14e53d0e2f62d82ae1d64a72fd9711548e3bf5ea \ No newline at end of file +da94a6e0ebacad8f235dcd653a25474327f26137 \ No newline at end of file diff --git a/src/sqliteInt.h b/src/sqliteInt.h index f9635a4eb0..69f1f544f1 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2540,7 +2540,7 @@ struct SrcList { #define WHERE_DISTINCTBY 0x0200 /* pOrderby is really a DISTINCT clause */ #define WHERE_WANT_DISTINCT 0x0400 /* All output needs to be distinct */ #define WHERE_SORTBYGROUP 0x0800 /* Support sqlite3WhereIsSorted() */ -#define WHERE_REOPEN_IDX 0x1000 /* Try to use OP_ReopenIdx */ + /* 0x1000 not currently used */ #define WHERE_ONEPASS_MULTIROW 0x2000 /* ONEPASS is ok with multiple rows */ #define WHERE_USE_LIMIT 0x4000 /* There is a constant LIMIT clause */ #define WHERE_SEEK_TABLE 0x8000 /* Do not defer seeks on main table */ diff --git a/src/where.c b/src/where.c index 0c3f05f7f2..849d0ae5bd 100644 --- a/src/where.c +++ b/src/where.c @@ -4479,7 +4479,7 @@ WhereInfo *sqlite3WhereBegin( pWInfo->aiCurOnePass[1] = iIndexCur; }else if( iAuxArg && (wctrlFlags & WHERE_ONETABLE_ONLY)!=0 ){ iIndexCur = iAuxArg; - if( wctrlFlags & WHERE_REOPEN_IDX ) op = OP_ReopenIdx; + op = OP_ReopenIdx; }else{ iIndexCur = pParse->nTab++; } diff --git a/src/wherecode.c b/src/wherecode.c index aee50c3142..a42fa1f843 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -1629,7 +1629,6 @@ Bitmask sqlite3WhereCodeOneLoopStart( ){ assert( pSubWInfo->a[0].iIdxCur==iCovCur ); pCov = pSubLoop->u.btree.pIndex; - wctrlFlags |= WHERE_REOPEN_IDX; }else{ pCov = 0; } From f52a697e046e796394e063dcbc949ba9d090de40 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 9 May 2016 22:32:18 +0000 Subject: [PATCH 0402/1484] Remove some forgotten debugging lines from test/sort5.test. FossilOrigin-Name: f5875489810101c13a7917bde86e6a23b088e386 --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/sort5.test | 4 ---- 3 files changed, 8 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 8e82d9444c..dfa6d4ca41 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\sa\scomment\sin\sfts5.h.\sNo\schanges\sto\scode. -D 2016-05-09T19:03:42.623 +C Remove\ssome\sforgotten\sdebugging\slines\sfrom\stest/sort5.test. +D 2016-05-09T22:32:18.802 F Makefile.in 9eda6e1c90d05c199c3ec8a7069b0682ad307657 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc db82b35aef27f412fef14d8534afc022138bcdfd @@ -1075,7 +1075,7 @@ F test/sort.test c2adc635c2564241fefec0b3a68391ef6868fd3b F test/sort2.test cc23b7c19d684657559e8a55b02f7fcee03851d0 F test/sort3.test 1480ed7c4c157682542224e05e3b75faf4a149e5 F test/sort4.test 5c34d9623a4ae5921d956dfa2b70e77ed0fc6e5c -F test/sort5.test e47ec7a490b9b36787755874175d8f413a3883d9 +F test/sort5.test 9cf239aca33cc461653f69377dfd75de4c388b2f F test/sortfault.test d4ccf606a0c77498e2beb542764fd9394acb4d66 F test/speed1.test f2974a91d79f58507ada01864c0e323093065452 F test/speed1p.explain d841e650a04728b39e6740296b852dccdca9b2cb @@ -1487,7 +1487,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 48505cde05d74748454dc135d4ec25954ecf020e -R 1969cb0ebb207c1f7d211b0f782f1262 -U dan -Z aa90d8f8ef0b8ff7fa6722d460d8bb52 +P 14e53d0e2f62d82ae1d64a72fd9711548e3bf5ea +R 57e3080f83e57cc4e840dda774a2fe9d +U drh +Z 049f4fad0b7cefc11bbb8ea38ffce642 diff --git a/manifest.uuid b/manifest.uuid index 1a4227599e..d5fc4ae80b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -14e53d0e2f62d82ae1d64a72fd9711548e3bf5ea \ No newline at end of file +f5875489810101c13a7917bde86e6a23b088e386 \ No newline at end of file diff --git a/test/sort5.test b/test/sort5.test index 9fb2dff281..bc1bdb3e8c 100644 --- a/test/sort5.test +++ b/test/sort5.test @@ -78,10 +78,7 @@ execsql { CREATE TABLE t1(x) } # each a bit over 100 bytes in size. In total a little more than 1MiB # of data. # -breakpoint foreach {tn pgsz cachesz bTemp} { - 2 1024 1000 1 - 1 4096 1000 0 2 1024 1000 1 @@ -113,4 +110,3 @@ foreach {tn pgsz cachesz bTemp} { } finish_test - From 83561932a5b4c170b1706561dada44885bf3db4f Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 9 May 2016 22:35:06 +0000 Subject: [PATCH 0403/1484] Enhancements to test/sort5.test so that it works with SEE. FossilOrigin-Name: 8a39c8ee49e6e80c83613546cf328801c80b7c4d --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/sort5.test | 6 ++++++ 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index dfa6d4ca41..3eb47ea56f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\ssome\sforgotten\sdebugging\slines\sfrom\stest/sort5.test. -D 2016-05-09T22:32:18.802 +C Enhancements\sto\stest/sort5.test\sso\sthat\sit\sworks\swith\sSEE. +D 2016-05-09T22:35:06.768 F Makefile.in 9eda6e1c90d05c199c3ec8a7069b0682ad307657 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc db82b35aef27f412fef14d8534afc022138bcdfd @@ -1075,7 +1075,7 @@ F test/sort.test c2adc635c2564241fefec0b3a68391ef6868fd3b F test/sort2.test cc23b7c19d684657559e8a55b02f7fcee03851d0 F test/sort3.test 1480ed7c4c157682542224e05e3b75faf4a149e5 F test/sort4.test 5c34d9623a4ae5921d956dfa2b70e77ed0fc6e5c -F test/sort5.test 9cf239aca33cc461653f69377dfd75de4c388b2f +F test/sort5.test 30cc17768e0c06ecb048e08efec59c11811fd186 F test/sortfault.test d4ccf606a0c77498e2beb542764fd9394acb4d66 F test/speed1.test f2974a91d79f58507ada01864c0e323093065452 F test/speed1p.explain d841e650a04728b39e6740296b852dccdca9b2cb @@ -1487,7 +1487,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 14e53d0e2f62d82ae1d64a72fd9711548e3bf5ea -R 57e3080f83e57cc4e840dda774a2fe9d +P f5875489810101c13a7917bde86e6a23b088e386 +R 06ee44fd877a285d72041ef6be8504fa U drh -Z 049f4fad0b7cefc11bbb8ea38ffce642 +Z 8edbf80d5eb509893c5370ddbed126a1 diff --git a/manifest.uuid b/manifest.uuid index d5fc4ae80b..a35da66dd1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f5875489810101c13a7917bde86e6a23b088e386 \ No newline at end of file +8a39c8ee49e6e80c83613546cf328801c80b7c4d \ No newline at end of file diff --git a/test/sort5.test b/test/sort5.test index bc1bdb3e8c..6ada81c9cc 100644 --- a/test/sort5.test +++ b/test/sort5.test @@ -94,6 +94,12 @@ foreach {tn pgsz cachesz bTemp} { PRAGMA cache_size = $cachesz; " + if {[db one {PRAGMA page_size}]!=$pgsz} { + # SEE is not able to change page sizes and that messes up the + # results that follow. + continue + } + do_test 2.$tn.1 { set ::iTemp 0 catch { array unset F } From 3791c9c288365c2851151896c21f7acaf50e02cc Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 9 May 2016 23:11:47 +0000 Subject: [PATCH 0404/1484] Fixes to requirements marks. No changes to code. FossilOrigin-Name: 79ecd0ef20c12198e950a730871444a980a0f1b2 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/btree.c | 16 ++++++++-------- test/snapshot.test | 4 ---- 4 files changed, 16 insertions(+), 20 deletions(-) diff --git a/manifest b/manifest index 3eb47ea56f..141cba74d7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhancements\sto\stest/sort5.test\sso\sthat\sit\sworks\swith\sSEE. -D 2016-05-09T22:35:06.768 +C Fixes\sto\srequirements\smarks.\s\sNo\schanges\sto\scode. +D 2016-05-09T23:11:47.940 F Makefile.in 9eda6e1c90d05c199c3ec8a7069b0682ad307657 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc db82b35aef27f412fef14d8534afc022138bcdfd @@ -321,7 +321,7 @@ F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240 F src/backup.c f60f0aa55d25d853ffde53d0b0370a7bb7ee41ce F src/bitvec.c 3ee4c8b2c94ed3a7377256e18199e6ff5cf33f63 F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 -F src/btree.c 3ae6aea66cc4e13d30162ff0d0d43c7088e34abf +F src/btree.c e53a01547d61a3d567daf7a7acc30122fe071aef F src/btree.h a5008b9afe56e8e54ade6c436a910f112defcca9 F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 F src/build.c d65be62254ca9df36e1e1c433324f0333f80009c @@ -1067,7 +1067,7 @@ F test/skipscan2.test d1d1450952b7275f0b0a3a981f0230532743951a F test/skipscan3.test ec5bab3f81c7038b43450e7b3062e04a198bdbb5 F test/skipscan5.test 67817a4b6857c47e0e33ba3e506da6f23ef68de2 F test/skipscan6.test 5866039d03a56f5bd0b3d172a012074a1d90a15b -F test/snapshot.test 3adc4ef09d407b501f899a6c329bdf45dc725c1b +F test/snapshot.test a19465046168b4420b5afeed37c3214e42a49f4a F test/snapshot_fault.test 062ff0438a074978d45e9f9a92e7ad459b74ee73 F test/soak.test 0b5b6375c9f4110c828070b826b3b4b0bb65cd5f F test/softheap1.test 843cd84db9891b2d01b9ab64cef3e9020f98d087 @@ -1487,7 +1487,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P f5875489810101c13a7917bde86e6a23b088e386 -R 06ee44fd877a285d72041ef6be8504fa +P 8a39c8ee49e6e80c83613546cf328801c80b7c4d +R 01d61c4cbbe70cd264566714c11f8bfc U drh -Z 8edbf80d5eb509893c5370ddbed126a1 +Z 2c227e9e751dfce43bc8d679164f39de diff --git a/manifest.uuid b/manifest.uuid index a35da66dd1..f366d629a4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8a39c8ee49e6e80c83613546cf328801c80b7c4d \ No newline at end of file +79ecd0ef20c12198e950a730871444a980a0f1b2 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 0e30df7f47..7e6b050f83 100644 --- a/src/btree.c +++ b/src/btree.c @@ -1676,11 +1676,11 @@ static int decodeFlags(MemPage *pPage, int flagByte){ pPage->xCellSize = cellSizePtr; pBt = pPage->pBt; if( flagByte==(PTF_LEAFDATA | PTF_INTKEY) ){ - /* EVIDENCE-OF: R-03640-13415 A value of 5 means the page is an interior - ** table b-tree page. */ + /* EVIDENCE-OF: R-07291-35328 A value of 5 (0x05) means the page is an + ** interior table b-tree page. */ assert( (PTF_LEAFDATA|PTF_INTKEY)==5 ); - /* EVIDENCE-OF: R-20501-61796 A value of 13 means the page is a leaf - ** table b-tree page. */ + /* EVIDENCE-OF: R-26900-09176 A value of 13 (0x0d) means the page is a + ** leaf table b-tree page. */ assert( (PTF_LEAFDATA|PTF_INTKEY|PTF_LEAF)==13 ); pPage->intKey = 1; if( pPage->leaf ){ @@ -1694,11 +1694,11 @@ static int decodeFlags(MemPage *pPage, int flagByte){ pPage->maxLocal = pBt->maxLeaf; pPage->minLocal = pBt->minLeaf; }else if( flagByte==PTF_ZERODATA ){ - /* EVIDENCE-OF: R-27225-53936 A value of 2 means the page is an interior - ** index b-tree page. */ + /* EVIDENCE-OF: R-43316-37308 A value of 2 (0x02) means the page is an + ** interior index b-tree page. */ assert( (PTF_ZERODATA)==2 ); - /* EVIDENCE-OF: R-16571-11615 A value of 10 means the page is a leaf - ** index b-tree page. */ + /* EVIDENCE-OF: R-59615-42828 A value of 10 (0x0a) means the page is a + ** leaf index b-tree page. */ assert( (PTF_ZERODATA|PTF_LEAF)==10 ); pPage->intKey = 0; pPage->intKeyLeaf = 0; diff --git a/test/snapshot.test b/test/snapshot.test index 6dff11bbb9..b2d61941a7 100644 --- a/test/snapshot.test +++ b/test/snapshot.test @@ -352,10 +352,6 @@ do_test 6.4 { db2 eval { SELECT * FROM x1 } } {z zz zzz} -# EVIDENCE-OF: R-55491-50411 A snapshot will fail to open if the -# database connection D has not previously completed at least one read -# operation against the database file. -# do_test 6.5 { db2 close sqlite3 db2 test.db From d12bc6022baa21a826a537145b8e57e4417d09cd Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 10 May 2016 20:03:08 +0000 Subject: [PATCH 0405/1484] Fix a problem in sqlite3PagerMovepage() when working on a temp table for which pages have been spilled. FossilOrigin-Name: 20cf8811caf705b482be100baecb3ef72aee2d5a --- manifest | 13 +++++++------ manifest.uuid | 2 +- src/pager.c | 3 +-- test/temptable3.test | 29 +++++++++++++++++++++++++++++ 4 files changed, 38 insertions(+), 9 deletions(-) create mode 100644 test/temptable3.test diff --git a/manifest b/manifest index 141cba74d7..74f59a6a58 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fixes\sto\srequirements\smarks.\s\sNo\schanges\sto\scode. -D 2016-05-09T23:11:47.940 +C Fix\sa\sproblem\sin\ssqlite3PagerMovepage()\swhen\sworking\son\sa\stemp\stable\sfor\swhich\npages\shave\sbeen\sspilled. +D 2016-05-10T20:03:08.453 F Makefile.in 9eda6e1c90d05c199c3ec8a7069b0682ad307657 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc db82b35aef27f412fef14d8534afc022138bcdfd @@ -364,7 +364,7 @@ F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa F src/os_unix.c a9443cdab41d7f3cdf0df3a5aab62fd6e1c9b234 F src/os_win.c 852fc2ff6084296348ed3739c548b2cf32df394e F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca -F src/pager.c c512873311087cd22372f2b076fc869e090e8e16 +F src/pager.c dd77be61e439d2bc8d5d4cb8c29595f3ff1c446c F src/pager.h 329bdf078a4e0a3b35084534d58625d21fd03681 F src/parse.y 10eb2f3fb62341291528c7984498054731f9d31e F src/pcache.c b3230ecfc7f797063fbe167f2845da363e8f07f8 @@ -1115,6 +1115,7 @@ F test/tempdb2.test 4fc92055f2a3f7626c0f2eabbb637dc021b311d5 F test/tempfault.test 0c0d349c9a99bf5f374655742577f8712c647900 F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30 F test/temptable2.test cd396beb41117a5302fff61767c35fa4270a0d5e +F test/temptable3.test 9542fcacdb9a0eb7cf5307527bb92292383b04da F test/temptrigger.test 8ec228b0db5d7ebc4ee9b458fc28cb9e7873f5e1 F test/tester.tcl 3ace46dee55f07e28a1e3ab03258b929fefcee5b F test/thread001.test 9f22fd3525a307ff42a326b6bc7b0465be1745a5 @@ -1487,7 +1488,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 8a39c8ee49e6e80c83613546cf328801c80b7c4d -R 01d61c4cbbe70cd264566714c11f8bfc +P 79ecd0ef20c12198e950a730871444a980a0f1b2 +R 12f0dc762faa7f80daee4e78c774b1d6 U drh -Z 2c227e9e751dfce43bc8d679164f39de +Z 8009b8aea3267bebcd4c327c4f222d7d diff --git a/manifest.uuid b/manifest.uuid index f366d629a4..9d89bebfac 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -79ecd0ef20c12198e950a730871444a980a0f1b2 \ No newline at end of file +20cf8811caf705b482be100baecb3ef72aee2d5a \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index 8ef0492e57..daddab4d5a 100644 --- a/src/pager.c +++ b/src/pager.c @@ -6926,8 +6926,7 @@ int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, int isCommit){ ** to exist, in case the transaction needs to roll back. Use pPgOld ** as the original page since it has already been allocated. */ - if( pPager->tempFile ){ - assert( pPgOld ); + if( pPager->tempFile && pPgOld ){ sqlite3PcacheMove(pPgOld, origPgno); sqlite3PagerUnrefNotNull(pPgOld); } diff --git a/test/temptable3.test b/test/temptable3.test new file mode 100644 index 0000000000..f3a8449ef1 --- /dev/null +++ b/test/temptable3.test @@ -0,0 +1,29 @@ +# 2016-05-10 +# +# 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. +# +#*********************************************************************** + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix temptable3 + +db close +sqlite3 db {} +do_execsql_test 1.1 { + PRAGMA cache_size = 1; + PRAGMA page_size = 1024; + PRAGMA auto_vacuum = 2; + CREATE TABLE t1(x); + INSERT INTO t1 VALUES( randomblob(800) ); + INSERT INTO t1 VALUES( randomblob(800) ); + CREATE TABLE t2(x); + PRAGMA integrity_check; +} {ok} + +finish_test From 78d1c9056736719a23fc7d418934dd76d4aed4ef Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 10 May 2016 20:16:43 +0000 Subject: [PATCH 0406/1484] Add another test case to temptable3.test. FossilOrigin-Name: 223640243efc52c14bb2bb540833a2a624eaa41a --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/temptable3.test | 12 ++++++++++++ 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 74f59a6a58..1310387dcc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\sin\ssqlite3PagerMovepage()\swhen\sworking\son\sa\stemp\stable\sfor\swhich\npages\shave\sbeen\sspilled. -D 2016-05-10T20:03:08.453 +C Add\sanother\stest\scase\sto\stemptable3.test. +D 2016-05-10T20:16:43.237 F Makefile.in 9eda6e1c90d05c199c3ec8a7069b0682ad307657 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc db82b35aef27f412fef14d8534afc022138bcdfd @@ -1115,7 +1115,7 @@ F test/tempdb2.test 4fc92055f2a3f7626c0f2eabbb637dc021b311d5 F test/tempfault.test 0c0d349c9a99bf5f374655742577f8712c647900 F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30 F test/temptable2.test cd396beb41117a5302fff61767c35fa4270a0d5e -F test/temptable3.test 9542fcacdb9a0eb7cf5307527bb92292383b04da +F test/temptable3.test d11a0974e52b347e45ee54ef1923c91ed91e4637 F test/temptrigger.test 8ec228b0db5d7ebc4ee9b458fc28cb9e7873f5e1 F test/tester.tcl 3ace46dee55f07e28a1e3ab03258b929fefcee5b F test/thread001.test 9f22fd3525a307ff42a326b6bc7b0465be1745a5 @@ -1488,7 +1488,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 79ecd0ef20c12198e950a730871444a980a0f1b2 -R 12f0dc762faa7f80daee4e78c774b1d6 -U drh -Z 8009b8aea3267bebcd4c327c4f222d7d +P 20cf8811caf705b482be100baecb3ef72aee2d5a +R 3a9fed64484c9373e69d538aa10775ab +U dan +Z 7b172879dcc2b05a1f7487ac7eeeddea diff --git a/manifest.uuid b/manifest.uuid index 9d89bebfac..25c22c63af 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -20cf8811caf705b482be100baecb3ef72aee2d5a \ No newline at end of file +223640243efc52c14bb2bb540833a2a624eaa41a \ No newline at end of file diff --git a/test/temptable3.test b/test/temptable3.test index f3a8449ef1..16f51d7832 100644 --- a/test/temptable3.test +++ b/test/temptable3.test @@ -26,4 +26,16 @@ do_execsql_test 1.1 { PRAGMA integrity_check; } {ok} +db close +sqlite3 db {} +do_execsql_test 1.2 { + PRAGMA cache_size = 1; + PRAGMA auto_vacuum = 2; + CREATE TABLE t1(x); + CREATE TABLE t2(x UNIQUE); + INSERT INTO t2 VALUES(1), (2), (3); + DROP TABLE t1; + PRAGMA integrity_check; +} {ok} + finish_test From 5c8e0928042ff5f5d1c1f967dd82f6850776c2c4 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 11 May 2016 10:57:04 +0000 Subject: [PATCH 0407/1484] Add pcache tracing macros. Off by default. Requires changing an "#if 0" and recompiling to enable. FossilOrigin-Name: d9313d19c75a62f558b3df6b15595b15bbfa0b62 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/pcache.c | 28 +++++++++++++++++++++++++++- 3 files changed, 35 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 1310387dcc..421ae8bf69 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sanother\stest\scase\sto\stemptable3.test. -D 2016-05-10T20:16:43.237 +C Add\spcache\stracing\smacros.\s\sOff\sby\sdefault.\s\sRequires\schanging\san\s"#if\s0"\nand\srecompiling\sto\senable. +D 2016-05-11T10:57:04.047 F Makefile.in 9eda6e1c90d05c199c3ec8a7069b0682ad307657 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc db82b35aef27f412fef14d8534afc022138bcdfd @@ -367,7 +367,7 @@ F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c dd77be61e439d2bc8d5d4cb8c29595f3ff1c446c F src/pager.h 329bdf078a4e0a3b35084534d58625d21fd03681 F src/parse.y 10eb2f3fb62341291528c7984498054731f9d31e -F src/pcache.c b3230ecfc7f797063fbe167f2845da363e8f07f8 +F src/pcache.c c128cafaac069e94931c3a743d5cf3d0c7b760d6 F src/pcache.h 6b865be765d1ebd06145219550b10921c7da7cc9 F src/pcache1.c 7f51d2b541aab57596adf62db2c4bb025d34f04d F src/pragma.c faf42922bb7ab2f6672cb550356c1967abae3c84 @@ -1488,7 +1488,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 20cf8811caf705b482be100baecb3ef72aee2d5a -R 3a9fed64484c9373e69d538aa10775ab -U dan -Z 7b172879dcc2b05a1f7487ac7eeeddea +P 223640243efc52c14bb2bb540833a2a624eaa41a +R 0792de46be2b6fbaa9f6c79c63b41f67 +U drh +Z 0ddceb59c6efe2505feeee700b7e5172 diff --git a/manifest.uuid b/manifest.uuid index 25c22c63af..45bc4fc6fa 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -223640243efc52c14bb2bb540833a2a624eaa41a \ No newline at end of file +d9313d19c75a62f558b3df6b15595b15bbfa0b62 \ No newline at end of file diff --git a/src/pcache.c b/src/pcache.c index f700c2ff66..7505547c25 100644 --- a/src/pcache.c +++ b/src/pcache.c @@ -31,6 +31,16 @@ struct PCache { sqlite3_pcache *pCache; /* Pluggable cache module */ }; +/* +** Debug tracing macros +*/ +#if defined(SQLITE_DEBUG) && 0 + int sqlite3PcacheTrace = 1; +# define pcacheTrace(X) if(sqlite3PcacheTrace){sqlite3DebugPrintf X;} +#else +# define pcacheTrace(X) +#endif + /********************************** Linked List Management ********************/ /* Allowed values for second argument to pcacheManageDirtyList() */ @@ -47,6 +57,9 @@ struct PCache { static void pcacheManageDirtyList(PgHdr *pPage, u8 addRemove){ PCache *p = pPage->pCache; + pcacheTrace(("%p.DIRTYLIST.%s %d\n", p, + addRemove==1 ? "REMOVE" : addRemove==2 ? "ADD" : "FRONT", + pPage->pgno)); if( addRemove & PCACHE_DIRTYLIST_REMOVE ){ assert( pPage->pDirtyNext || pPage==p->pDirtyTail ); assert( pPage->pDirtyPrev || pPage==p->pDirty ); @@ -106,6 +119,7 @@ static void pcacheManageDirtyList(PgHdr *pPage, u8 addRemove){ */ static void pcacheUnpin(PgHdr *p){ if( p->pCache->bPurgeable ){ + pcacheTrace(("%p.UNPIN %d\n", p->pCache, p->pgno)); sqlite3GlobalConfig.pcache2.xUnpin(p->pCache->pCache, p->pPage, 0); } } @@ -176,6 +190,7 @@ int sqlite3PcacheOpen( p->pStress = pStress; p->szCache = 100; p->szSpill = 1; + pcacheTrace(("%p.OPEN szPage %d bPurgeable %d\n",p,szPage,bPurgeable)); return sqlite3PcacheSetPageSize(p, szPage); } @@ -198,6 +213,7 @@ int sqlite3PcacheSetPageSize(PCache *pCache, int szPage){ } pCache->pCache = pNew; pCache->szPage = szPage; + pcacheTrace(("%p.PAGESIZE %d\n",pCache,szPage)); } return SQLITE_OK; } @@ -232,6 +248,7 @@ sqlite3_pcache_page *sqlite3PcacheFetch( int createFlag /* If true, create page if it does not exist already */ ){ int eCreate; + sqlite3_pcache_page *pRes; assert( pCache!=0 ); assert( pCache->pCache!=0 ); @@ -249,7 +266,10 @@ sqlite3_pcache_page *sqlite3PcacheFetch( assert( eCreate==0 || eCreate==1 || eCreate==2 ); assert( createFlag==0 || pCache->eCreate==eCreate ); assert( createFlag==0 || eCreate==1+(!pCache->bPurgeable||!pCache->pDirty) ); - return sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, eCreate); + pRes = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, eCreate); + pcacheTrace(("%p.FETCH %d%s (result: %p)\n",pCache,pgno, + createFlag?" create":"",pRes)); + return pRes; } /* @@ -294,6 +314,7 @@ int sqlite3PcacheFetchStress( sqlite3GlobalConfig.pcache.xPagecount(pCache->pCache), numberOfCachePages(pCache)); #endif + pcacheTrace(("%p.SPILL %d\n",pCache,pPg->pgno)); rc = pCache->xStress(pCache->pStress, pPg); if( rc!=SQLITE_OK && rc!=SQLITE_BUSY ){ return rc; @@ -407,6 +428,7 @@ void sqlite3PcacheMakeDirty(PgHdr *p){ p->flags &= ~PGHDR_DONT_WRITE; if( p->flags & PGHDR_CLEAN ){ p->flags ^= (PGHDR_DIRTY|PGHDR_CLEAN); + pcacheTrace(("%p.DIRTY %d\n",p->pCache,p->pgno)); assert( (p->flags & (PGHDR_DIRTY|PGHDR_CLEAN))==PGHDR_DIRTY ); pcacheManageDirtyList(p, PCACHE_DIRTYLIST_ADD); } @@ -423,6 +445,7 @@ void sqlite3PcacheMakeClean(PgHdr *p){ pcacheManageDirtyList(p, PCACHE_DIRTYLIST_REMOVE); p->flags &= ~(PGHDR_DIRTY|PGHDR_NEED_SYNC|PGHDR_WRITEABLE); p->flags |= PGHDR_CLEAN; + pcacheTrace(("%p.CLEAN %d\n",p->pCache,p->pgno)); if( p->nRef==0 ){ pcacheUnpin(p); } @@ -468,6 +491,7 @@ void sqlite3PcacheMove(PgHdr *p, Pgno newPgno){ PCache *pCache = p->pCache; assert( p->nRef>0 ); assert( newPgno>0 ); + pcacheTrace(("%p.MOVE %d -> %d\n",pCache,p->pgno,newPgno)); sqlite3GlobalConfig.pcache2.xRekey(pCache->pCache, p->pPage, p->pgno,newPgno); p->pgno = newPgno; if( (p->flags&PGHDR_DIRTY) && (p->flags&PGHDR_NEED_SYNC) ){ @@ -488,6 +512,7 @@ void sqlite3PcacheTruncate(PCache *pCache, Pgno pgno){ if( pCache->pCache ){ PgHdr *p; PgHdr *pNext; + pcacheTrace(("%p.TRUNCATE %d\n",pCache,pgno)); for(p=pCache->pDirty; p; p=pNext){ pNext = p->pDirtyNext; /* This routine never gets call with a positive pgno except right @@ -518,6 +543,7 @@ void sqlite3PcacheTruncate(PCache *pCache, Pgno pgno){ */ void sqlite3PcacheClose(PCache *pCache){ assert( pCache->pCache!=0 ); + pcacheTrace(("%p.CLOSE\n",pCache)); sqlite3GlobalConfig.pcache2.xDestroy(pCache->pCache); } From 65c6420335cfd78615ea7432ce862da7027171bc Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 11 May 2016 11:04:17 +0000 Subject: [PATCH 0408/1484] Always truncate, rather than persist, the rollback journal of a TEMP database. FossilOrigin-Name: 42fb6f1e99a6c31889819a0302679d598dc0ab1b --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/pager.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 421ae8bf69..a8c8e54249 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\spcache\stracing\smacros.\s\sOff\sby\sdefault.\s\sRequires\schanging\san\s"#if\s0"\nand\srecompiling\sto\senable. -D 2016-05-11T10:57:04.047 +C Always\struncate,\srather\sthan\spersist,\sthe\srollback\sjournal\sof\sa\sTEMP\sdatabase. +D 2016-05-11T11:04:17.716 F Makefile.in 9eda6e1c90d05c199c3ec8a7069b0682ad307657 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc db82b35aef27f412fef14d8534afc022138bcdfd @@ -364,7 +364,7 @@ F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa F src/os_unix.c a9443cdab41d7f3cdf0df3a5aab62fd6e1c9b234 F src/os_win.c 852fc2ff6084296348ed3739c548b2cf32df394e F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca -F src/pager.c dd77be61e439d2bc8d5d4cb8c29595f3ff1c446c +F src/pager.c 146d724b2c35f5d2d98676188681db9ade33486d F src/pager.h 329bdf078a4e0a3b35084534d58625d21fd03681 F src/parse.y 10eb2f3fb62341291528c7984498054731f9d31e F src/pcache.c c128cafaac069e94931c3a743d5cf3d0c7b760d6 @@ -1488,7 +1488,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 223640243efc52c14bb2bb540833a2a624eaa41a -R 0792de46be2b6fbaa9f6c79c63b41f67 +P d9313d19c75a62f558b3df6b15595b15bbfa0b62 +R 4210b2f60d7aff505c38881d5c5427ee U drh -Z 0ddceb59c6efe2505feeee700b7e5172 +Z a22a7f46bad36a1990f0c6b07c454824 diff --git a/manifest.uuid b/manifest.uuid index 45bc4fc6fa..eb889327ae 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d9313d19c75a62f558b3df6b15595b15bbfa0b62 \ No newline at end of file +42fb6f1e99a6c31889819a0302679d598dc0ab1b \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index daddab4d5a..359e233606 100644 --- a/src/pager.c +++ b/src/pager.c @@ -1997,7 +1997,7 @@ static int pager_end_transaction(Pager *pPager, int hasMaster, int bCommit){ }else if( pPager->journalMode==PAGER_JOURNALMODE_PERSIST || (pPager->exclusiveMode && pPager->journalMode!=PAGER_JOURNALMODE_WAL) ){ - rc = zeroJournalHdr(pPager, hasMaster); + rc = zeroJournalHdr(pPager, hasMaster||pPager->tempFile); pPager->journalOff = 0; }else{ /* This branch may be executed with Pager.journalMode==MEMORY if From a37e0cfb2205c8ddcb71e08bb1ed1ce859cec8fc Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 11 May 2016 12:47:46 +0000 Subject: [PATCH 0409/1484] Do not reset the page cache when a rollback journal truncate fails, as doing so can cause loss of information for an in-memory TEMP file. FossilOrigin-Name: 345ce1c9f64f2a424663b4dfcbe4586d9df7bff6 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/pager.c | 12 +++++++----- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index a8c8e54249..a0a2ed640a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Always\struncate,\srather\sthan\spersist,\sthe\srollback\sjournal\sof\sa\sTEMP\sdatabase. -D 2016-05-11T11:04:17.716 +C Do\snot\sreset\sthe\spage\scache\swhen\sa\srollback\sjournal\struncate\sfails,\sas\sdoing\nso\scan\scause\sloss\sof\sinformation\sfor\san\sin-memory\sTEMP\sfile. +D 2016-05-11T12:47:46.752 F Makefile.in 9eda6e1c90d05c199c3ec8a7069b0682ad307657 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc db82b35aef27f412fef14d8534afc022138bcdfd @@ -364,7 +364,7 @@ F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa F src/os_unix.c a9443cdab41d7f3cdf0df3a5aab62fd6e1c9b234 F src/os_win.c 852fc2ff6084296348ed3739c548b2cf32df394e F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca -F src/pager.c 146d724b2c35f5d2d98676188681db9ade33486d +F src/pager.c cb7a3990eabd895f6487c0856a7fec02b5e40faa F src/pager.h 329bdf078a4e0a3b35084534d58625d21fd03681 F src/parse.y 10eb2f3fb62341291528c7984498054731f9d31e F src/pcache.c c128cafaac069e94931c3a743d5cf3d0c7b760d6 @@ -1488,7 +1488,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d9313d19c75a62f558b3df6b15595b15bbfa0b62 -R 4210b2f60d7aff505c38881d5c5427ee +P 42fb6f1e99a6c31889819a0302679d598dc0ab1b +R 6af21f51682f416bafd722831c805292 U drh -Z a22a7f46bad36a1990f0c6b07c454824 +Z f092752ae332e4cfbb76f62bab02296e diff --git a/manifest.uuid b/manifest.uuid index eb889327ae..39ea1115d0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -42fb6f1e99a6c31889819a0302679d598dc0ab1b \ No newline at end of file +345ce1c9f64f2a424663b4dfcbe4586d9df7bff6 \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index 359e233606..d2dd639892 100644 --- a/src/pager.c +++ b/src/pager.c @@ -2032,12 +2032,14 @@ static int pager_end_transaction(Pager *pPager, int hasMaster, int bCommit){ sqlite3BitvecDestroy(pPager->pInJournal); pPager->pInJournal = 0; pPager->nRec = 0; - if( MEMDB || pagerFlushOnCommit(pPager) ){ - sqlite3PcacheCleanAll(pPager->pPCache); - }else{ - sqlite3PcacheClearWritable(pPager->pPCache); + if( rc==SQLITE_OK ){ + if( MEMDB || pagerFlushOnCommit(pPager) ){ + sqlite3PcacheCleanAll(pPager->pPCache); + }else{ + sqlite3PcacheClearWritable(pPager->pPCache); + } + sqlite3PcacheTruncate(pPager->pPCache, pPager->dbSize); } - sqlite3PcacheTruncate(pPager->pPCache, pPager->dbSize); if( pagerUseWal(pPager) ){ /* Drop the WAL write-lock, if any. Also, if the connection was in From b2ef900ade31284cbd710bf2fe2c4a88400eed6a Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 11 May 2016 15:41:15 +0000 Subject: [PATCH 0410/1484] Remove some a small amount of redundant code related to PCache.pSynced from pcache.c. FossilOrigin-Name: 9cc8cad78fdfe044ad6726ebfe6909c1e242fa55 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/pcache.c | 28 ++++++++++++++++++++++------ 3 files changed, 30 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index a0a2ed640a..a51e55cb83 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Do\snot\sreset\sthe\spage\scache\swhen\sa\srollback\sjournal\struncate\sfails,\sas\sdoing\nso\scan\scause\sloss\sof\sinformation\sfor\san\sin-memory\sTEMP\sfile. -D 2016-05-11T12:47:46.752 +C Remove\ssome\sa\ssmall\samount\sof\sredundant\scode\srelated\sto\sPCache.pSynced\sfrom\spcache.c. +D 2016-05-11T15:41:15.317 F Makefile.in 9eda6e1c90d05c199c3ec8a7069b0682ad307657 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc db82b35aef27f412fef14d8534afc022138bcdfd @@ -367,7 +367,7 @@ F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c cb7a3990eabd895f6487c0856a7fec02b5e40faa F src/pager.h 329bdf078a4e0a3b35084534d58625d21fd03681 F src/parse.y 10eb2f3fb62341291528c7984498054731f9d31e -F src/pcache.c c128cafaac069e94931c3a743d5cf3d0c7b760d6 +F src/pcache.c 4af980bc2a987cf81ddbe867d238c9ccdbaac95c F src/pcache.h 6b865be765d1ebd06145219550b10921c7da7cc9 F src/pcache1.c 7f51d2b541aab57596adf62db2c4bb025d34f04d F src/pragma.c faf42922bb7ab2f6672cb550356c1967abae3c84 @@ -1488,7 +1488,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 42fb6f1e99a6c31889819a0302679d598dc0ab1b -R 6af21f51682f416bafd722831c805292 -U drh -Z f092752ae332e4cfbb76f62bab02296e +P 345ce1c9f64f2a424663b4dfcbe4586d9df7bff6 +R 410857f6cadf18a1818aed66391afc72 +U dan +Z b239392669bc1d86adff0f06ee03f5ae diff --git a/manifest.uuid b/manifest.uuid index 39ea1115d0..9b2b37fae9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -345ce1c9f64f2a424663b4dfcbe4586d9df7bff6 \ No newline at end of file +9cc8cad78fdfe044ad6726ebfe6909c1e242fa55 \ No newline at end of file diff --git a/src/pcache.c b/src/pcache.c index 7505547c25..54b4044a01 100644 --- a/src/pcache.c +++ b/src/pcache.c @@ -15,6 +15,22 @@ /* ** A complete page cache is an instance of this structure. +** +** pDirty, pDirtyTail, pSynced: +** All dirty pages are linked into the doubly linked list using +** PgHdr.pDirtyNext and pDirtyPrev. The list is maintained in LRU order +** such that p was added to the list more recently than p->pDirtyNext. +** PCache.pDirty points to the first (newest) element in the list and +** pDirtyTail to the last (oldest). +** +** The PCache.pSynced variable is used to optimize searching for a dirty +** page to eject from the cache mid-transaction. It is better to eject +** a page that does not require a journal sync than one that does. +** Therefore, pSynced is maintained to that it *almost* always points +** to either the oldest page in the pDirty/pDirtyTail list that has a +** clear PGHDR_NEED_SYNC flag or to a page that is older than this one +** (so that the right page to eject can be found by following pDirtyPrev +** pointers). */ struct PCache { PgHdr *pDirty, *pDirtyTail; /* List of dirty pages in LRU order */ @@ -66,11 +82,7 @@ static void pcacheManageDirtyList(PgHdr *pPage, u8 addRemove){ /* Update the PCache1.pSynced variable if necessary. */ if( p->pSynced==pPage ){ - PgHdr *pSynced = pPage->pDirtyPrev; - while( pSynced && (pSynced->flags&PGHDR_NEED_SYNC) ){ - pSynced = pSynced->pDirtyPrev; - } - p->pSynced = pSynced; + p->pSynced = pPage->pDirtyPrev; } if( pPage->pDirtyNext ){ @@ -296,7 +308,11 @@ int sqlite3PcacheFetchStress( ** page that does not require a journal-sync (one with PGHDR_NEED_SYNC ** cleared), but if that is not possible settle for any other ** unreferenced dirty page. - */ + ** + ** If the LRU page in the dirty list that has a clear PGHDR_NEED_SYNC + ** flag is currently referenced, then the following may leave pSynced + ** set incorrectly (pointing to other than the LRU page with NEED_SYNC + ** cleared). This is Ok, as pSynced is just an optimization. */ for(pPg=pCache->pSynced; pPg && (pPg->nRef || (pPg->flags&PGHDR_NEED_SYNC)); pPg=pPg->pDirtyPrev From 401907e3ff7616e85469752102c52f4bdaf7d73c Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 11 May 2016 20:03:23 +0000 Subject: [PATCH 0411/1484] Remove a redundant condition from pcache.c. Add an OPTIMIZATION-IF-TRUE comment to another condition that requires it. FossilOrigin-Name: 3bfd2621d13b4f842f3af6d35519653f4eb8cad7 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/pcache.c | 10 ++++++++-- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index a51e55cb83..6c5a26e092 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\ssome\sa\ssmall\samount\sof\sredundant\scode\srelated\sto\sPCache.pSynced\sfrom\spcache.c. -D 2016-05-11T15:41:15.317 +C Remove\sa\sredundant\scondition\sfrom\spcache.c.\sAdd\san\sOPTIMIZATION-IF-TRUE\scomment\sto\sanother\scondition\sthat\srequires\sit. +D 2016-05-11T20:03:23.145 F Makefile.in 9eda6e1c90d05c199c3ec8a7069b0682ad307657 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc db82b35aef27f412fef14d8534afc022138bcdfd @@ -367,7 +367,7 @@ F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c cb7a3990eabd895f6487c0856a7fec02b5e40faa F src/pager.h 329bdf078a4e0a3b35084534d58625d21fd03681 F src/parse.y 10eb2f3fb62341291528c7984498054731f9d31e -F src/pcache.c 4af980bc2a987cf81ddbe867d238c9ccdbaac95c +F src/pcache.c 95ee5008eddda9c61b8d053de8eebf72cf5df7c6 F src/pcache.h 6b865be765d1ebd06145219550b10921c7da7cc9 F src/pcache1.c 7f51d2b541aab57596adf62db2c4bb025d34f04d F src/pragma.c faf42922bb7ab2f6672cb550356c1967abae3c84 @@ -1488,7 +1488,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 345ce1c9f64f2a424663b4dfcbe4586d9df7bff6 -R 410857f6cadf18a1818aed66391afc72 +P 9cc8cad78fdfe044ad6726ebfe6909c1e242fa55 +R bd613f88cc94ba593741d724ce8bf946 U dan -Z b239392669bc1d86adff0f06ee03f5ae +Z ba94a14dc94ea0c9562dd2071f1152d6 diff --git a/manifest.uuid b/manifest.uuid index 9b2b37fae9..034ae63216 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9cc8cad78fdfe044ad6726ebfe6909c1e242fa55 \ No newline at end of file +3bfd2621d13b4f842f3af6d35519653f4eb8cad7 \ No newline at end of file diff --git a/src/pcache.c b/src/pcache.c index 54b4044a01..4051bee00e 100644 --- a/src/pcache.c +++ b/src/pcache.c @@ -94,10 +94,15 @@ static void pcacheManageDirtyList(PgHdr *pPage, u8 addRemove){ if( pPage->pDirtyPrev ){ pPage->pDirtyPrev->pDirtyNext = pPage->pDirtyNext; }else{ + /* If there are now no dirty pages in the cache, set eCreate to 2. + ** This is an optimization that allows sqlite3PcacheFetch() to skip + ** searching for a dirty page to eject from the cache when it might + ** otherwise have to. */ assert( pPage==p->pDirty ); p->pDirty = pPage->pDirtyNext; - if( p->pDirty==0 && p->bPurgeable ){ - assert( p->eCreate==1 ); + assert( p->bPurgeable || p->eCreate==2 ); + if( p->pDirty==0 ){ /*OPTIMIZATION-IF-TRUE*/ + assert( p->bPurgeable==0 || p->eCreate==1 ); p->eCreate = 2; } } @@ -266,6 +271,7 @@ sqlite3_pcache_page *sqlite3PcacheFetch( assert( pCache->pCache!=0 ); assert( createFlag==3 || createFlag==0 ); assert( pgno>0 ); + assert( pCache->eCreate==((pCache->bPurgeable && pCache->pDirty) ? 1 : 2) ); /* eCreate defines what to do if the page does not exist. ** 0 Do not allocate a new page. (createFlag==0) From 72e6a399073fd63bb5e8bc1db07a95365d2a2e2b Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 11 May 2016 23:54:14 +0000 Subject: [PATCH 0412/1484] For in-memory databases, it does not matter if pcache entries are marked "clean" or "writable". FossilOrigin-Name: ad601c7962a60a11699cf31f1faee09b95d5c710 --- manifest | 21 ++++++++++++--------- manifest.uuid | 2 +- src/pager.c | 2 +- src/pcache.c | 8 +++++++- src/pcache.h | 2 +- 5 files changed, 22 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 6c5a26e092..5293168132 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sa\sredundant\scondition\sfrom\spcache.c.\sAdd\san\sOPTIMIZATION-IF-TRUE\scomment\sto\sanother\scondition\sthat\srequires\sit. -D 2016-05-11T20:03:23.145 +C For\sin-memory\sdatabases,\sit\sdoes\snot\smatter\sif\spcache\sentries\sare\smarked\n"clean"\sor\s"writable". +D 2016-05-11T23:54:14.261 F Makefile.in 9eda6e1c90d05c199c3ec8a7069b0682ad307657 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc db82b35aef27f412fef14d8534afc022138bcdfd @@ -364,11 +364,11 @@ F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa F src/os_unix.c a9443cdab41d7f3cdf0df3a5aab62fd6e1c9b234 F src/os_win.c 852fc2ff6084296348ed3739c548b2cf32df394e F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca -F src/pager.c cb7a3990eabd895f6487c0856a7fec02b5e40faa +F src/pager.c 76fe5ad6998772a6abda30145c181e99e7743a1d F src/pager.h 329bdf078a4e0a3b35084534d58625d21fd03681 F src/parse.y 10eb2f3fb62341291528c7984498054731f9d31e -F src/pcache.c 95ee5008eddda9c61b8d053de8eebf72cf5df7c6 -F src/pcache.h 6b865be765d1ebd06145219550b10921c7da7cc9 +F src/pcache.c 132a78c71bd510fde0085bfc44608bc64b945d48 +F src/pcache.h 33b40350df1b6c278e019dee37f87e1bac276223 F src/pcache1.c 7f51d2b541aab57596adf62db2c4bb025d34f04d F src/pragma.c faf42922bb7ab2f6672cb550356c1967abae3c84 F src/pragma.h 64c78a648751b9f4f297276c4eb7507b14b4628c @@ -1488,7 +1488,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 9cc8cad78fdfe044ad6726ebfe6909c1e242fa55 -R bd613f88cc94ba593741d724ce8bf946 -U dan -Z ba94a14dc94ea0c9562dd2071f1152d6 +P 3bfd2621d13b4f842f3af6d35519653f4eb8cad7 +R 399bfb6002bea3bb0fdfe001a40139f7 +T *branch * pager-dev +T *sym-pager-dev * +T -sym-trunk * +U drh +Z 75fe10a9420951c23350bd3808039177 diff --git a/manifest.uuid b/manifest.uuid index 034ae63216..3e5a24e018 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3bfd2621d13b4f842f3af6d35519653f4eb8cad7 \ No newline at end of file +ad601c7962a60a11699cf31f1faee09b95d5c710 \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index d2dd639892..3f33fae811 100644 --- a/src/pager.c +++ b/src/pager.c @@ -2033,7 +2033,7 @@ static int pager_end_transaction(Pager *pPager, int hasMaster, int bCommit){ pPager->pInJournal = 0; pPager->nRec = 0; if( rc==SQLITE_OK ){ - if( MEMDB || pagerFlushOnCommit(pPager) ){ + if( pagerFlushOnCommit(pPager) ){ sqlite3PcacheCleanAll(pPager->pPCache); }else{ sqlite3PcacheClearWritable(pPager->pPCache); diff --git a/src/pcache.c b/src/pcache.c index 4051bee00e..f30b60e94a 100644 --- a/src/pcache.c +++ b/src/pcache.c @@ -14,7 +14,13 @@ #include "sqliteInt.h" /* -** A complete page cache is an instance of this structure. +** A complete page cache is an instance of this structure. Every +** entry in the cache holds a single page of the database file. The +** btree layer only operates on the cached copy of the database pages. +** +** A page cache entry is "clean" if it exactly matches what is currently +** on disk. A page is "dirty" if it has been modified and needs to be +** persisted to disk. ** ** pDirty, pDirtyTail, pSynced: ** All dirty pages are linked into the doubly linked list using diff --git a/src/pcache.h b/src/pcache.h index 04bce289d0..8e0f12e094 100644 --- a/src/pcache.h +++ b/src/pcache.h @@ -26,7 +26,7 @@ struct PgHdr { sqlite3_pcache_page *pPage; /* Pcache object page handle */ void *pData; /* Page data */ void *pExtra; /* Extra content */ - PgHdr *pDirty; /* Transient list of dirty pages */ + PgHdr *pDirty; /* Transient list of dirty sorted by pgno */ Pager *pPager; /* The pager this page is part of */ Pgno pgno; /* Page number for this page */ #ifdef SQLITE_CHECK_PAGES From 613723d9fda58600335959dd38a31968e1323bd9 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 12 May 2016 09:48:23 +0000 Subject: [PATCH 0413/1484] Add a missing OPTIMIZATION-IF-FALSE comment to pcache.c. FossilOrigin-Name: bc202e5b418d5a57bfc766883c4417c94829d96e --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/pcache.c | 10 +++++++++- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 6c5a26e092..796ba4e548 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sa\sredundant\scondition\sfrom\spcache.c.\sAdd\san\sOPTIMIZATION-IF-TRUE\scomment\sto\sanother\scondition\sthat\srequires\sit. -D 2016-05-11T20:03:23.145 +C Add\sa\smissing\sOPTIMIZATION-IF-FALSE\scomment\sto\spcache.c. +D 2016-05-12T09:48:23.099 F Makefile.in 9eda6e1c90d05c199c3ec8a7069b0682ad307657 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc db82b35aef27f412fef14d8534afc022138bcdfd @@ -367,7 +367,7 @@ F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c cb7a3990eabd895f6487c0856a7fec02b5e40faa F src/pager.h 329bdf078a4e0a3b35084534d58625d21fd03681 F src/parse.y 10eb2f3fb62341291528c7984498054731f9d31e -F src/pcache.c 95ee5008eddda9c61b8d053de8eebf72cf5df7c6 +F src/pcache.c 481e549dec06c01e8db84f80af835b3386a83bb0 F src/pcache.h 6b865be765d1ebd06145219550b10921c7da7cc9 F src/pcache1.c 7f51d2b541aab57596adf62db2c4bb025d34f04d F src/pragma.c faf42922bb7ab2f6672cb550356c1967abae3c84 @@ -1488,7 +1488,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 9cc8cad78fdfe044ad6726ebfe6909c1e242fa55 -R bd613f88cc94ba593741d724ce8bf946 +P 3bfd2621d13b4f842f3af6d35519653f4eb8cad7 +R 1f5b4032d8f04ae7caac9d7a76ea1776 U dan -Z ba94a14dc94ea0c9562dd2071f1152d6 +Z c8fcd1a1ab31e8e9159bebaf1a63834b diff --git a/manifest.uuid b/manifest.uuid index 034ae63216..5372f9c927 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3bfd2621d13b4f842f3af6d35519653f4eb8cad7 \ No newline at end of file +bc202e5b418d5a57bfc766883c4417c94829d96e \ No newline at end of file diff --git a/src/pcache.c b/src/pcache.c index 4051bee00e..8634a79188 100644 --- a/src/pcache.c +++ b/src/pcache.c @@ -124,7 +124,15 @@ static void pcacheManageDirtyList(PgHdr *pPage, u8 addRemove){ } } p->pDirty = pPage; - if( !p->pSynced && 0==(pPage->flags&PGHDR_NEED_SYNC) ){ + + /* If pSynced is NULL and this page has a clear NEED_SYNC flag, set + ** pSynced to point to it. Checking the NEED_SYNC flag is an + ** optimization, as if pSynced points to a page with the NEED_SYNC + ** flag set sqlite3PcacheFetchStress() searches through all newer + ** entries of the dirty-list for a page with NEED_SYNC clear anyway. */ + if( !p->pSynced + && 0==(pPage->flags&PGHDR_NEED_SYNC) /*OPTIMIZATION-IF-FALSE*/ + ){ p->pSynced = pPage; } } From 42bee5f4d6cefc9e467d6c7203a530f815e42b36 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 12 May 2016 12:01:20 +0000 Subject: [PATCH 0414/1484] Remove an unnecessary call to sqlite3PcacheMakeClean() inside of the ROLLBACK logic. FossilOrigin-Name: 0dc50d9915cd88916229ca5c3834de82fa16f017 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/pager.c | 31 ++++--------------------------- src/pcache.c | 2 +- 4 files changed, 14 insertions(+), 37 deletions(-) diff --git a/manifest b/manifest index 796ba4e548..eff6cd9a5e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sa\smissing\sOPTIMIZATION-IF-FALSE\scomment\sto\spcache.c. -D 2016-05-12T09:48:23.099 +C Remove\san\sunnecessary\scall\sto\ssqlite3PcacheMakeClean()\sinside\sof\sthe\sROLLBACK\nlogic. +D 2016-05-12T12:01:20.280 F Makefile.in 9eda6e1c90d05c199c3ec8a7069b0682ad307657 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc db82b35aef27f412fef14d8534afc022138bcdfd @@ -364,10 +364,10 @@ F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa F src/os_unix.c a9443cdab41d7f3cdf0df3a5aab62fd6e1c9b234 F src/os_win.c 852fc2ff6084296348ed3739c548b2cf32df394e F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca -F src/pager.c cb7a3990eabd895f6487c0856a7fec02b5e40faa +F src/pager.c b7f9341d1c8917d0050f11597c588d0b4e379df9 F src/pager.h 329bdf078a4e0a3b35084534d58625d21fd03681 F src/parse.y 10eb2f3fb62341291528c7984498054731f9d31e -F src/pcache.c 481e549dec06c01e8db84f80af835b3386a83bb0 +F src/pcache.c 0e8453c2aaa8a72e09c58edeb0f0976dc652e827 F src/pcache.h 6b865be765d1ebd06145219550b10921c7da7cc9 F src/pcache1.c 7f51d2b541aab57596adf62db2c4bb025d34f04d F src/pragma.c faf42922bb7ab2f6672cb550356c1967abae3c84 @@ -1488,7 +1488,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 3bfd2621d13b4f842f3af6d35519653f4eb8cad7 -R 1f5b4032d8f04ae7caac9d7a76ea1776 -U dan -Z c8fcd1a1ab31e8e9159bebaf1a63834b +P bc202e5b418d5a57bfc766883c4417c94829d96e +R 94f384a80fd36cfa7eab53c97f52730e +U drh +Z 3db2648b2bf79fa343d087598efa8f84 diff --git a/manifest.uuid b/manifest.uuid index 5372f9c927..e0fbea1e69 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bc202e5b418d5a57bfc766883c4417c94829d96e \ No newline at end of file +0dc50d9915cd88916229ca5c3834de82fa16f017 \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index d2dd639892..654cc640d3 100644 --- a/src/pager.c +++ b/src/pager.c @@ -2387,33 +2387,10 @@ static int pager_playback_one_page( pData = pPg->pData; memcpy(pData, (u8*)aData, pPager->pageSize); pPager->xReiniter(pPg); - if( isMainJrnl && (!isSavepnt || *pOffset<=pPager->journalHdr) ){ - /* If the contents of this page were just restored from the main - ** journal file, then its content must be as they were when the - ** transaction was first opened. In this case we can mark the page - ** as clean, since there will be no need to write it out to the - ** database. - ** - ** There is one exception to this rule. If the page is being rolled - ** back as part of a savepoint (or statement) rollback from an - ** unsynced portion of the main journal file, then it is not safe - ** to mark the page as clean. This is because marking the page as - ** clean will clear the PGHDR_NEED_SYNC flag. Since the page is - ** already in the journal file (recorded in Pager.pInJournal) and - ** the PGHDR_NEED_SYNC flag is cleared, if the page is written to - ** again within this transaction, it will be marked as dirty but - ** the PGHDR_NEED_SYNC flag will not be set. It could then potentially - ** be written out into the database file before its journal file - ** segment is synced. If a crash occurs during or following this, - ** database corruption may ensue. - ** - ** Update: Another exception is for temp files that are not - ** in-memory databases. In this case the page may have been dirty - ** at the start of the transaction. - */ - assert( !pagerUseWal(pPager) ); - if( pPager->tempFile==0 ) sqlite3PcacheMakeClean(pPg); - } + /* It used to be that sqlite3PcacheMakeClean(pPg) was called here. But + ** that call was dangerous and had no detectable benefit since the cache + ** is normally cleaned by sqlite3PcacheCleanAll() after rollback and so + ** has been removed. */ pager_set_pagehash(pPg); /* If this was page 1, then restore the value of Pager.dbFileVers. diff --git a/src/pcache.c b/src/pcache.c index 8634a79188..fab6ad32a2 100644 --- a/src/pcache.c +++ b/src/pcache.c @@ -470,7 +470,7 @@ void sqlite3PcacheMakeDirty(PgHdr *p){ ** make it so. */ void sqlite3PcacheMakeClean(PgHdr *p){ - if( (p->flags & PGHDR_DIRTY) ){ + if( ALWAYS((p->flags & PGHDR_DIRTY)!=0) ){ assert( (p->flags & PGHDR_CLEAN)==0 ); pcacheManageDirtyList(p, PCACHE_DIRTYLIST_REMOVE); p->flags &= ~(PGHDR_DIRTY|PGHDR_NEED_SYNC|PGHDR_WRITEABLE); From 82c0447701840cb933cad5b15243cd9c07d885a5 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 12 May 2016 17:06:04 +0000 Subject: [PATCH 0415/1484] Add extra OPTIMIZATION-IF-FALSE comments where required to pcache.c. FossilOrigin-Name: 9d55b8f541de43deb82d460d32005fd62f5430b2 --- manifest | 15 +++++++-------- manifest.uuid | 2 +- src/pcache.c | 9 ++++++--- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index e3477b52b0..d2c32e5bc9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C For\sin-memory\sdatabases,\sit\sdoes\snot\smatter\sif\spcache\sentries\sare\smarked\n"clean"\sor\s"writable". -D 2016-05-12T12:08:48.058 +C Add\sextra\sOPTIMIZATION-IF-FALSE\scomments\swhere\srequired\sto\spcache.c. +D 2016-05-12T17:06:04.756 F Makefile.in 9eda6e1c90d05c199c3ec8a7069b0682ad307657 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc db82b35aef27f412fef14d8534afc022138bcdfd @@ -367,7 +367,7 @@ F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c baef5d8d31d220001fc61013f401c98950749201 F src/pager.h 329bdf078a4e0a3b35084534d58625d21fd03681 F src/parse.y 10eb2f3fb62341291528c7984498054731f9d31e -F src/pcache.c 5291b6ab838132f856fe8067ca25772d221c4864 +F src/pcache.c 3ef140add88d8d3eee3a80a79412f450bd216d3b F src/pcache.h 33b40350df1b6c278e019dee37f87e1bac276223 F src/pcache1.c 7f51d2b541aab57596adf62db2c4bb025d34f04d F src/pragma.c faf42922bb7ab2f6672cb550356c1967abae3c84 @@ -1488,8 +1488,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 0dc50d9915cd88916229ca5c3834de82fa16f017 ad601c7962a60a11699cf31f1faee09b95d5c710 -R 7667d141b3239c7f232de8ca756273cf -T +closed ad601c7962a60a11699cf31f1faee09b95d5c710 -U drh -Z 488a663f0afeb720045f9ee67fd9acb5 +P 06c1e27ca868f247f8c27b03eb19aac004f28650 +R e01f1d97945350d1485afdc3dc2f5468 +U dan +Z fe74337e6648e1a589818404220bbdb0 diff --git a/manifest.uuid b/manifest.uuid index 90f4a0036f..8e69ca85ac 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -06c1e27ca868f247f8c27b03eb19aac004f28650 \ No newline at end of file +9d55b8f541de43deb82d460d32005fd62f5430b2 \ No newline at end of file diff --git a/src/pcache.c b/src/pcache.c index ee7914a444..f8fe901776 100644 --- a/src/pcache.c +++ b/src/pcache.c @@ -424,8 +424,11 @@ void SQLITE_NOINLINE sqlite3PcacheRelease(PgHdr *p){ if( (--p->nRef)==0 ){ if( p->flags&PGHDR_CLEAN ){ pcacheUnpin(p); - }else if( p->pDirtyPrev!=0 ){ - /* Move the page to the head of the dirty list. */ + }else if( p->pDirtyPrev!=0 ){ /*OPTIMIZATION-IF-FALSE*/ + /* Move the page to the head of the dirty list. If p->pDirtyPrev==0, + ** then page p is already at the head of the dirty list and the + ** following call would be a no-op. Hence the OPTIMIZATION-IF-FALSE + ** tag above. */ pcacheManageDirtyList(p, PCACHE_DIRTYLIST_FRONT); } } @@ -460,7 +463,7 @@ void sqlite3PcacheDrop(PgHdr *p){ */ void sqlite3PcacheMakeDirty(PgHdr *p){ assert( p->nRef>0 ); - if( p->flags & (PGHDR_CLEAN|PGHDR_DONT_WRITE) ){ + if( p->flags & (PGHDR_CLEAN|PGHDR_DONT_WRITE) ){ /*OPTIMIZATION-IF-FALSE*/ p->flags &= ~PGHDR_DONT_WRITE; if( p->flags & PGHDR_CLEAN ){ p->flags ^= (PGHDR_DIRTY|PGHDR_CLEAN); From d22f5099b598c228aeb0c0617f7b82806cedfb6b Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 12 May 2016 18:38:45 +0000 Subject: [PATCH 0416/1484] Add an assert in pager.c to confirm that pPager->tempFile is always true for in-memory databases. FossilOrigin-Name: 3fd71092063bf1d30e03cf2497ea9c57b3ec82eb --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/pager.c | 1 + 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index d2c32e5bc9..8176f2e890 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sextra\sOPTIMIZATION-IF-FALSE\scomments\swhere\srequired\sto\spcache.c. -D 2016-05-12T17:06:04.756 +C Add\san\sassert\sin\spager.c\sto\sconfirm\sthat\spPager->tempFile\sis\salways\strue\nfor\sin-memory\sdatabases. +D 2016-05-12T18:38:45.335 F Makefile.in 9eda6e1c90d05c199c3ec8a7069b0682ad307657 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc db82b35aef27f412fef14d8534afc022138bcdfd @@ -364,7 +364,7 @@ F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa F src/os_unix.c a9443cdab41d7f3cdf0df3a5aab62fd6e1c9b234 F src/os_win.c 852fc2ff6084296348ed3739c548b2cf32df394e F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca -F src/pager.c baef5d8d31d220001fc61013f401c98950749201 +F src/pager.c 9089b6f318c96d973f0f26ce866452f514c71120 F src/pager.h 329bdf078a4e0a3b35084534d58625d21fd03681 F src/parse.y 10eb2f3fb62341291528c7984498054731f9d31e F src/pcache.c 3ef140add88d8d3eee3a80a79412f450bd216d3b @@ -1488,7 +1488,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 06c1e27ca868f247f8c27b03eb19aac004f28650 -R e01f1d97945350d1485afdc3dc2f5468 -U dan -Z fe74337e6648e1a589818404220bbdb0 +P 9d55b8f541de43deb82d460d32005fd62f5430b2 +R 3abb8b47feac8b594036edc1e8dce6ec +U drh +Z 8914057de4b6310e97cb7f42ae3b951d diff --git a/manifest.uuid b/manifest.uuid index 8e69ca85ac..f608f87e2f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9d55b8f541de43deb82d460d32005fd62f5430b2 \ No newline at end of file +3fd71092063bf1d30e03cf2497ea9c57b3ec82eb \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index 75cde3c024..70fccca158 100644 --- a/src/pager.c +++ b/src/pager.c @@ -6831,6 +6831,7 @@ int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, int isCommit){ /* In order to be able to rollback, an in-memory database must journal ** the page we are moving from. */ + assert( pPager->tempFile || !MEMDB ); if( pPager->tempFile ){ rc = sqlite3PagerWrite(pPg); if( rc ) return rc; From a7a45973e9876fbfc265b2d533e953278772dd63 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 12 May 2016 19:05:35 +0000 Subject: [PATCH 0417/1484] Simplification of the sqlite3FaultSim() call inside of sqlite3PagerCommitPhaseOne(). FossilOrigin-Name: 1b0f4cc362cda1dc175aa363ae4e612b7d1164c3 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/pager.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 8176f2e890..f574e48e65 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\san\sassert\sin\spager.c\sto\sconfirm\sthat\spPager->tempFile\sis\salways\strue\nfor\sin-memory\sdatabases. -D 2016-05-12T18:38:45.335 +C Simplification\sof\sthe\ssqlite3FaultSim()\scall\sinside\sof\nsqlite3PagerCommitPhaseOne(). +D 2016-05-12T19:05:35.053 F Makefile.in 9eda6e1c90d05c199c3ec8a7069b0682ad307657 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc db82b35aef27f412fef14d8534afc022138bcdfd @@ -364,7 +364,7 @@ F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa F src/os_unix.c a9443cdab41d7f3cdf0df3a5aab62fd6e1c9b234 F src/os_win.c 852fc2ff6084296348ed3739c548b2cf32df394e F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca -F src/pager.c 9089b6f318c96d973f0f26ce866452f514c71120 +F src/pager.c b6b3f2aff301cb025b23a8586666c91355cb3c69 F src/pager.h 329bdf078a4e0a3b35084534d58625d21fd03681 F src/parse.y 10eb2f3fb62341291528c7984498054731f9d31e F src/pcache.c 3ef140add88d8d3eee3a80a79412f450bd216d3b @@ -1488,7 +1488,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 9d55b8f541de43deb82d460d32005fd62f5430b2 -R 3abb8b47feac8b594036edc1e8dce6ec +P 3fd71092063bf1d30e03cf2497ea9c57b3ec82eb +R 86cdc8fab77fed5ebeb6f9ac3a200e04 U drh -Z 8914057de4b6310e97cb7f42ae3b951d +Z 30e0270ee86eb0dad7cf2e94ccef570b diff --git a/manifest.uuid b/manifest.uuid index f608f87e2f..f5d7ecb7b3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3fd71092063bf1d30e03cf2497ea9c57b3ec82eb \ No newline at end of file +1b0f4cc362cda1dc175aa363ae4e612b7d1164c3 \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index 70fccca158..d8ea37122e 100644 --- a/src/pager.c +++ b/src/pager.c @@ -6196,7 +6196,7 @@ int sqlite3PagerCommitPhaseOne( if( NEVER(pPager->errCode) ) return pPager->errCode; /* Provide the ability to easily simulate an I/O error during testing */ - if( (rc = sqlite3FaultSim(400))!=SQLITE_OK ) return rc; + if( sqlite3FaultSim(400) ) return SQLITE_IOERR; PAGERTRACE(("DATABASE SYNC: File=%s zMaster=%s nSize=%d\n", pPager->zFilename, zMaster, pPager->dbSize)); From 5f65ff277db11629ed47babde6a867f95d8f1c75 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 12 May 2016 19:17:09 +0000 Subject: [PATCH 0418/1484] Disable ALWAYS and NEVER when compiled with SQLITE_MUTATION_TEST. FossilOrigin-Name: 24d9fbc1d0f99b90577ecd6edcd3bc1abc76633f --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/sqliteInt.h | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index f574e48e65..7f6e396120 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Simplification\sof\sthe\ssqlite3FaultSim()\scall\sinside\sof\nsqlite3PagerCommitPhaseOne(). -D 2016-05-12T19:05:35.053 +C Disable\sALWAYS\sand\sNEVER\swhen\scompiled\swith\sSQLITE_MUTATION_TEST. +D 2016-05-12T19:17:09.294 F Makefile.in 9eda6e1c90d05c199c3ec8a7069b0682ad307657 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc db82b35aef27f412fef14d8534afc022138bcdfd @@ -382,7 +382,7 @@ F src/shell.c 14ff7f660530a52b117d110ba3390b7b2eb719b6 F src/sqlite.h.in 9984129d86243424b765fcb3f147c697bd20bb54 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 98f72cbfe00169c39089115427d06ea05fe4b4a2 -F src/sqliteInt.h 8ec741711b8f42aae2c7a22e3d04f15270e0b6be +F src/sqliteInt.h 4fe51e4e26d9d576040198cef4f78df3d987387d F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 @@ -1488,7 +1488,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 3fd71092063bf1d30e03cf2497ea9c57b3ec82eb -R 86cdc8fab77fed5ebeb6f9ac3a200e04 +P 1b0f4cc362cda1dc175aa363ae4e612b7d1164c3 +R cbaa515ed65f02858509b96594eef6a3 U drh -Z 30e0270ee86eb0dad7cf2e94ccef570b +Z d111db0e0c72ae873465e360a322abe1 diff --git a/manifest.uuid b/manifest.uuid index f5d7ecb7b3..ccf535ef95 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1b0f4cc362cda1dc175aa363ae4e612b7d1164c3 \ No newline at end of file +24d9fbc1d0f99b90577ecd6edcd3bc1abc76633f \ No newline at end of file diff --git a/src/sqliteInt.h b/src/sqliteInt.h index f9635a4eb0..c90d4dc9ae 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -411,7 +411,7 @@ ** be true and false so that the unreachable code they specify will ** not be counted as untested code. */ -#if defined(SQLITE_COVERAGE_TEST) +#if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_MUTATION_TEST) # define ALWAYS(X) (1) # define NEVER(X) (0) #elif !defined(NDEBUG) From 7aeb216a19ab7108537f8dbaa32a05edb25f80c4 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 13 May 2016 04:24:25 +0000 Subject: [PATCH 0419/1484] Additional debugging and tracing logic for pcache.c, turned off by default using an "#if 0". FossilOrigin-Name: 32a62e3bd46cf58586617d3f8b1a971c91df205e --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/pcache.c | 34 ++++++++++++++++++++++++++++++++-- 3 files changed, 39 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 7f6e396120..521c3c6b38 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Disable\sALWAYS\sand\sNEVER\swhen\scompiled\swith\sSQLITE_MUTATION_TEST. -D 2016-05-12T19:17:09.294 +C Additional\sdebugging\sand\stracing\slogic\sfor\spcache.c,\sturned\soff\sby\sdefault\nusing\san\s"#if\s0". +D 2016-05-13T04:24:25.046 F Makefile.in 9eda6e1c90d05c199c3ec8a7069b0682ad307657 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc db82b35aef27f412fef14d8534afc022138bcdfd @@ -367,7 +367,7 @@ F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c b6b3f2aff301cb025b23a8586666c91355cb3c69 F src/pager.h 329bdf078a4e0a3b35084534d58625d21fd03681 F src/parse.y 10eb2f3fb62341291528c7984498054731f9d31e -F src/pcache.c 3ef140add88d8d3eee3a80a79412f450bd216d3b +F src/pcache.c ad5ce697dc5a734caddb2b1eac83b195da95ddbe F src/pcache.h 33b40350df1b6c278e019dee37f87e1bac276223 F src/pcache1.c 7f51d2b541aab57596adf62db2c4bb025d34f04d F src/pragma.c faf42922bb7ab2f6672cb550356c1967abae3c84 @@ -1488,7 +1488,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 1b0f4cc362cda1dc175aa363ae4e612b7d1164c3 -R cbaa515ed65f02858509b96594eef6a3 +P 24d9fbc1d0f99b90577ecd6edcd3bc1abc76633f +R d638f11a5a2154aefeed14f79e8ebc4d U drh -Z d111db0e0c72ae873465e360a322abe1 +Z 291bccc6a32f88cd8cda8747cf2307e8 diff --git a/manifest.uuid b/manifest.uuid index ccf535ef95..527363daba 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -24d9fbc1d0f99b90577ecd6edcd3bc1abc76633f \ No newline at end of file +32a62e3bd46cf58586617d3f8b1a971c91df205e \ No newline at end of file diff --git a/src/pcache.c b/src/pcache.c index f8fe901776..6c07b20f57 100644 --- a/src/pcache.c +++ b/src/pcache.c @@ -57,10 +57,35 @@ struct PCache { ** Debug tracing macros */ #if defined(SQLITE_DEBUG) && 0 - int sqlite3PcacheTrace = 1; + int sqlite3PcacheTrace = 2; # define pcacheTrace(X) if(sqlite3PcacheTrace){sqlite3DebugPrintf X;} -#else + void pcacheDump(PCache *pCache){ + int N; + int i, j; + sqlite3_pcache_page *pLower; + PgHdr *pPg; + unsigned char *a; + + if( sqlite3PcacheTrace<2 ) return; + if( pCache->pCache==0 ) return; + N = sqlite3PcachePagecount(pCache); + if( N>5 ) N = 5; + for(i=1; i<=N; i++){ + pLower = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, i, 0); + if( pLower==0 ) continue; + pPg = (PgHdr*)pLower->pExtra; + printf("%3d: nRef %2d flgs %02x data ", i, pPg->nRef, pPg->flags); + a = (unsigned char *)pLower->pBuf; + for(j=0; j<12; j++) printf("%02x", a[j]); + printf("\n"); + if( pPg->pPage==0 ){ + sqlite3GlobalConfig.pcache2.xUnpin(pCache->pCache, pLower, 0); + } + } + } + #else # define pcacheTrace(X) +# define pcacheDump(X) #endif /********************************** Linked List Management ********************/ @@ -142,6 +167,7 @@ static void pcacheManageDirtyList(PgHdr *pPage, u8 addRemove){ p->pSynced = pPage; } } + pcacheDump(p); } /* @@ -152,6 +178,7 @@ static void pcacheUnpin(PgHdr *p){ if( p->pCache->bPurgeable ){ pcacheTrace(("%p.UNPIN %d\n", p->pCache, p->pgno)); sqlite3GlobalConfig.pcache2.xUnpin(p->pCache->pCache, p->pPage, 0); + pcacheDump(p->pCache); } } @@ -352,6 +379,7 @@ int sqlite3PcacheFetchStress( #endif pcacheTrace(("%p.SPILL %d\n",pCache,pPg->pgno)); rc = pCache->xStress(pCache->pStress, pPg); + pcacheDump(pCache); if( rc!=SQLITE_OK && rc!=SQLITE_BUSY ){ return rc; } @@ -496,6 +524,7 @@ void sqlite3PcacheMakeClean(PgHdr *p){ */ void sqlite3PcacheCleanAll(PCache *pCache){ PgHdr *p; + pcacheTrace(("%p.CLEAN-ALL\n",pCache)); while( (p = pCache->pDirty)!=0 ){ sqlite3PcacheMakeClean(p); } @@ -506,6 +535,7 @@ void sqlite3PcacheCleanAll(PCache *pCache){ */ void sqlite3PcacheClearWritable(PCache *pCache){ PgHdr *p; + pcacheTrace(("%p.CLEAR-WRITEABLE\n",pCache)); for(p=pCache->pDirty; p; p=p->pDirtyNext){ p->flags &= ~(PGHDR_NEED_SYNC|PGHDR_WRITEABLE); } From 935c4d8484c2416bd3f885b286c1ee9efada3338 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 13 May 2016 11:50:00 +0000 Subject: [PATCH 0420/1484] Fix pager_end_transaction() to ensure that a ROLLBACK does not clobber unwritten pages in a TEMP file pcache. FossilOrigin-Name: 9495d33879221c1821331dc72c61a6a3d182f526 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/pager.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 521c3c6b38..61125eca3d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Additional\sdebugging\sand\stracing\slogic\sfor\spcache.c,\sturned\soff\sby\sdefault\nusing\san\s"#if\s0". -D 2016-05-13T04:24:25.046 +C Fix\spager_end_transaction()\sto\sensure\sthat\sa\sROLLBACK\sdoes\snot\sclobber\nunwritten\spages\sin\sa\sTEMP\sfile\spcache. +D 2016-05-13T11:50:00.812 F Makefile.in 9eda6e1c90d05c199c3ec8a7069b0682ad307657 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc db82b35aef27f412fef14d8534afc022138bcdfd @@ -364,7 +364,7 @@ F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa F src/os_unix.c a9443cdab41d7f3cdf0df3a5aab62fd6e1c9b234 F src/os_win.c 852fc2ff6084296348ed3739c548b2cf32df394e F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca -F src/pager.c b6b3f2aff301cb025b23a8586666c91355cb3c69 +F src/pager.c 64f42bd0d20f180f99727ce5a3755a97c9a12700 F src/pager.h 329bdf078a4e0a3b35084534d58625d21fd03681 F src/parse.y 10eb2f3fb62341291528c7984498054731f9d31e F src/pcache.c ad5ce697dc5a734caddb2b1eac83b195da95ddbe @@ -1488,7 +1488,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 24d9fbc1d0f99b90577ecd6edcd3bc1abc76633f -R d638f11a5a2154aefeed14f79e8ebc4d +P 32a62e3bd46cf58586617d3f8b1a971c91df205e +R 7ea6babb6ca28821d5ebb371842cc2c9 U drh -Z 291bccc6a32f88cd8cda8747cf2307e8 +Z 5e0d604d556f91727b00c6f570867611 diff --git a/manifest.uuid b/manifest.uuid index 527363daba..bed68c74ab 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -32a62e3bd46cf58586617d3f8b1a971c91df205e \ No newline at end of file +9495d33879221c1821331dc72c61a6a3d182f526 \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index d8ea37122e..095fce5374 100644 --- a/src/pager.c +++ b/src/pager.c @@ -2033,7 +2033,7 @@ static int pager_end_transaction(Pager *pPager, int hasMaster, int bCommit){ pPager->pInJournal = 0; pPager->nRec = 0; if( rc==SQLITE_OK ){ - if( pagerFlushOnCommit(pPager) ){ + if( !pPager->tempFile || (bCommit && pagerFlushOnCommit(pPager)) ){ sqlite3PcacheCleanAll(pPager->pPCache); }else{ sqlite3PcacheClearWritable(pPager->pPCache); From 4bf7d21f5647d96ece52fc0a95f01ab5a142a954 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 13 May 2016 12:12:38 +0000 Subject: [PATCH 0421/1484] Clarification of the pagerFlushOnCommit() logic. FossilOrigin-Name: 3401d9dcdbec390564574e8d2972c944c204e025 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/pager.c | 26 +++++++++++++++----------- 3 files changed, 22 insertions(+), 18 deletions(-) diff --git a/manifest b/manifest index 61125eca3d..12e791556f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\spager_end_transaction()\sto\sensure\sthat\sa\sROLLBACK\sdoes\snot\sclobber\nunwritten\spages\sin\sa\sTEMP\sfile\spcache. -D 2016-05-13T11:50:00.812 +C Clarification\sof\sthe\spagerFlushOnCommit()\slogic. +D 2016-05-13T12:12:38.291 F Makefile.in 9eda6e1c90d05c199c3ec8a7069b0682ad307657 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc db82b35aef27f412fef14d8534afc022138bcdfd @@ -364,7 +364,7 @@ F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa F src/os_unix.c a9443cdab41d7f3cdf0df3a5aab62fd6e1c9b234 F src/os_win.c 852fc2ff6084296348ed3739c548b2cf32df394e F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca -F src/pager.c 64f42bd0d20f180f99727ce5a3755a97c9a12700 +F src/pager.c 665c5a4da55952ac144c29d83e7f24393ce80dce F src/pager.h 329bdf078a4e0a3b35084534d58625d21fd03681 F src/parse.y 10eb2f3fb62341291528c7984498054731f9d31e F src/pcache.c ad5ce697dc5a734caddb2b1eac83b195da95ddbe @@ -1488,7 +1488,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 32a62e3bd46cf58586617d3f8b1a971c91df205e -R 7ea6babb6ca28821d5ebb371842cc2c9 +P 9495d33879221c1821331dc72c61a6a3d182f526 +R 6b2058239dcedcc73d7ba7314be4d002 U drh -Z 5e0d604d556f91727b00c6f570867611 +Z 481738e778b68e5e24387a60a8825df4 diff --git a/manifest.uuid b/manifest.uuid index bed68c74ab..b9dc436b75 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9495d33879221c1821331dc72c61a6a3d182f526 \ No newline at end of file +3401d9dcdbec390564574e8d2972c944c204e025 \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index 095fce5374..0cf2278562 100644 --- a/src/pager.c +++ b/src/pager.c @@ -1876,20 +1876,24 @@ static int pager_error(Pager *pPager, int rc){ static int pager_truncate(Pager *pPager, Pgno nPage); /* -** The write transaction open on the pager passed as the only argument is -** being committed. This function returns true if all dirty pages should -** be flushed to disk, or false otherwise. Pages should be flushed to disk -** unless one of the following is true: +** The write transaction open on pPager is being committed (bCommit==1) +** or rolled back (bCommit==0). ** -** * The db is an in-memory database. +** Return TRUE if and only if all dirty pages should be flushed to disk. ** -** * The db is a temporary database and the db file has not been opened. +** Rules: ** -** * The db is a temporary database and the cache contains less than -** C/4 dirty pages, where C is the configured cache-size. +** * For non-TEMP databases, always sync to disk. This is necessary +** for transactions to be durable. +** +** * Sync TEMP database only on a COMMIT (not a ROLLBACK) when the backing +** file has been created already (via a spill on pagerStress()) and +** when the number of dirty pages in memory exceeds 25% of the total +** cache size. */ -static int pagerFlushOnCommit(Pager *pPager){ +static int pagerFlushOnCommit(Pager *pPager, int bCommit){ if( pPager->tempFile==0 ) return 1; + if( !bCommit ) return 0; if( !isOpen(pPager->fd) ) return 0; return (sqlite3PCachePercentDirty(pPager->pPCache)>=25); } @@ -2033,7 +2037,7 @@ static int pager_end_transaction(Pager *pPager, int hasMaster, int bCommit){ pPager->pInJournal = 0; pPager->nRec = 0; if( rc==SQLITE_OK ){ - if( !pPager->tempFile || (bCommit && pagerFlushOnCommit(pPager)) ){ + if( pagerFlushOnCommit(pPager, bCommit) ){ sqlite3PcacheCleanAll(pPager->pPCache); }else{ sqlite3PcacheClearWritable(pPager->pPCache); @@ -6206,7 +6210,7 @@ int sqlite3PagerCommitPhaseOne( assert( MEMDB==0 || pPager->tempFile ); assert( isOpen(pPager->fd) || pPager->tempFile ); - if( 0==pagerFlushOnCommit(pPager) ){ + if( 0==pagerFlushOnCommit(pPager, 1) ){ /* If this is an in-memory db, or no pages have been written to, or this ** function has already been called, it is mostly a no-op. However, any ** backup in progress needs to be restarted. */ From a0f6b124ad1bec65832726b4d18f3a1dec397926 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 13 May 2016 15:22:06 +0000 Subject: [PATCH 0422/1484] Remove the unused PGHDR_NEED_READ flag. Add invariant checking (during SQLITE_DEBUG builds only) for the PgHdr object. FossilOrigin-Name: 771c5411e9ebcad00fb4b97556b519488284b87b --- manifest | 16 +++++++------- manifest.uuid | 2 +- src/pager.c | 2 +- src/pcache.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++--- src/pcache.h | 12 ++++++---- 5 files changed, 76 insertions(+), 17 deletions(-) diff --git a/manifest b/manifest index 12e791556f..5b2f5a2c42 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Clarification\sof\sthe\spagerFlushOnCommit()\slogic. -D 2016-05-13T12:12:38.291 +C Remove\sthe\sunused\sPGHDR_NEED_READ\sflag.\s\sAdd\sinvariant\schecking\s(during\nSQLITE_DEBUG\sbuilds\sonly)\sfor\sthe\sPgHdr\sobject. +D 2016-05-13T15:22:06.587 F Makefile.in 9eda6e1c90d05c199c3ec8a7069b0682ad307657 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc db82b35aef27f412fef14d8534afc022138bcdfd @@ -364,11 +364,11 @@ F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa F src/os_unix.c a9443cdab41d7f3cdf0df3a5aab62fd6e1c9b234 F src/os_win.c 852fc2ff6084296348ed3739c548b2cf32df394e F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca -F src/pager.c 665c5a4da55952ac144c29d83e7f24393ce80dce +F src/pager.c 3910579bfbe323dfabed2b95d201159b61b8ef42 F src/pager.h 329bdf078a4e0a3b35084534d58625d21fd03681 F src/parse.y 10eb2f3fb62341291528c7984498054731f9d31e -F src/pcache.c ad5ce697dc5a734caddb2b1eac83b195da95ddbe -F src/pcache.h 33b40350df1b6c278e019dee37f87e1bac276223 +F src/pcache.c e93f1e1b4c6134d59b4bd4f3f684f406987ef299 +F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 F src/pcache1.c 7f51d2b541aab57596adf62db2c4bb025d34f04d F src/pragma.c faf42922bb7ab2f6672cb550356c1967abae3c84 F src/pragma.h 64c78a648751b9f4f297276c4eb7507b14b4628c @@ -1488,7 +1488,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 9495d33879221c1821331dc72c61a6a3d182f526 -R 6b2058239dcedcc73d7ba7314be4d002 +P 3401d9dcdbec390564574e8d2972c944c204e025 +R 440a1b1b52d8bc83687d285c09ed1eae U drh -Z 481738e778b68e5e24387a60a8825df4 +Z 63614a0e4a8fa1151ab9567f8bbeafca diff --git a/manifest.uuid b/manifest.uuid index b9dc436b75..67d06a22f0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3401d9dcdbec390564574e8d2972c944c204e025 \ No newline at end of file +771c5411e9ebcad00fb4b97556b519488284b87b \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index 0cf2278562..b24267e58a 100644 --- a/src/pager.c +++ b/src/pager.c @@ -2377,7 +2377,6 @@ static int pager_playback_one_page( assert( (pPager->doNotSpill & SPILLFLAG_ROLLBACK)!=0 ); pPager->doNotSpill &= ~SPILLFLAG_ROLLBACK; if( rc!=SQLITE_OK ) return rc; - pPg->flags &= ~PGHDR_NEED_READ; sqlite3PcacheMakeDirty(pPg); } if( pPg ){ @@ -6005,6 +6004,7 @@ void sqlite3PagerDontWrite(PgHdr *pPg){ IOTRACE(("CLEAN %p %d\n", pPager, pPg->pgno)) pPg->flags |= PGHDR_DONT_WRITE; pPg->flags &= ~PGHDR_WRITEABLE; + testcase( pPg->flags & PGHDR_NEED_SYNC ); pager_set_pagehash(pPg); } } diff --git a/src/pcache.c b/src/pcache.c index 6c07b20f57..d778f9aedc 100644 --- a/src/pcache.c +++ b/src/pcache.c @@ -53,11 +53,18 @@ struct PCache { sqlite3_pcache *pCache; /* Pluggable cache module */ }; +/********************************** Test and Debug Logic **********************/ /* -** Debug tracing macros +** Debug tracing macros. Enable by by changing the "0" to "1" and +** recompiling. +** +** When sqlite3PcacheTrace is 1, single line trace messages are issued. +** When sqlite3PcacheTrace is 2, a dump of the pcache showing all cache entries +** is displayed for many operations, resulting in a lot of output. */ #if defined(SQLITE_DEBUG) && 0 - int sqlite3PcacheTrace = 2; + int sqlite3PcacheTrace = 2; /* 0: off 1: simple 2: cache dumps */ + int sqlite3PcacheMxDump = 9999; /* Max cache entries for pcacheDump() */ # define pcacheTrace(X) if(sqlite3PcacheTrace){sqlite3DebugPrintf X;} void pcacheDump(PCache *pCache){ int N; @@ -69,7 +76,7 @@ struct PCache { if( sqlite3PcacheTrace<2 ) return; if( pCache->pCache==0 ) return; N = sqlite3PcachePagecount(pCache); - if( N>5 ) N = 5; + if( N>sqlite3PcacheMxDump ) N = sqlite3PcacheMxDump; for(i=1; i<=N; i++){ pLower = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, i, 0); if( pLower==0 ) continue; @@ -88,6 +95,46 @@ struct PCache { # define pcacheDump(X) #endif +/* +** Check invariants on a PgHdr entry. Return true if everything is OK. +** Return false if any invariant is violated. +** +** This routine is for use inside of assert() statements only. For +** example: +** +** assert( sqlite3PcachePageSanity(pPg) ); +*/ +#if SQLITE_DEBUG +int sqlite3PcachePageSanity(PgHdr *pPg){ + PCache *pCache; + assert( pPg!=0 ); + assert( pPg->pgno>0 ); /* Page number is 1 or more */ + pCache = pPg->pCache; + assert( pCache!=0 ); /* Every page has an associated PCache */ + if( pPg->flags & PGHDR_CLEAN ){ + assert( (pPg->flags & PGHDR_DIRTY)==0 );/* Cannot be both CLEAN and DIRTY */ + assert( pCache->pDirty!=pPg ); /* CLEAN pages not on dirty list */ + assert( pCache->pDirtyTail!=pPg ); + } + /* WRITEABLE pages must also be DIRTY */ + if( pPg->flags & PGHDR_WRITEABLE ){ + assert( pPg->flags & PGHDR_DIRTY ); /* WRITEABLE implies DIRTY */ + } + /* NEED_SYNC can be set independently of WRITEABLE. This can happen, + ** for example, when using the sqlite3PagerDontWrite() optimization: + ** (1) Page X is journalled, and gets WRITEABLE and NEED_SEEK. + ** (2) Page X moved to freelist, WRITEABLE is cleared + ** (3) Page X reused, WRITEABLE is set again + ** If NEED_SYNC had been cleared in step 2, then it would not be reset + ** in step 3, and page might be written into the database without first + ** syncing the rollback journal, which might cause corruption on a power + ** loss. + */ + return 1; +} +#endif /* SQLITE_DEBUG */ + + /********************************** Linked List Management ********************/ /* Allowed values for second argument to pcacheManageDirtyList() */ @@ -439,6 +486,7 @@ PgHdr *sqlite3PcacheFetchFinish( } pCache->nRefSum++; pPgHdr->nRef++; + assert( sqlite3PcachePageSanity(pPgHdr) ); return pPgHdr; } @@ -467,6 +515,7 @@ void SQLITE_NOINLINE sqlite3PcacheRelease(PgHdr *p){ */ void sqlite3PcacheRef(PgHdr *p){ assert(p->nRef>0); + assert( sqlite3PcachePageSanity(p) ); p->nRef++; p->pCache->nRefSum++; } @@ -478,6 +527,7 @@ void sqlite3PcacheRef(PgHdr *p){ */ void sqlite3PcacheDrop(PgHdr *p){ assert( p->nRef==1 ); + assert( sqlite3PcachePageSanity(p) ); if( p->flags&PGHDR_DIRTY ){ pcacheManageDirtyList(p, PCACHE_DIRTYLIST_REMOVE); } @@ -491,6 +541,7 @@ void sqlite3PcacheDrop(PgHdr *p){ */ void sqlite3PcacheMakeDirty(PgHdr *p){ assert( p->nRef>0 ); + assert( sqlite3PcachePageSanity(p) ); if( p->flags & (PGHDR_CLEAN|PGHDR_DONT_WRITE) ){ /*OPTIMIZATION-IF-FALSE*/ p->flags &= ~PGHDR_DONT_WRITE; if( p->flags & PGHDR_CLEAN ){ @@ -499,6 +550,7 @@ void sqlite3PcacheMakeDirty(PgHdr *p){ assert( (p->flags & (PGHDR_DIRTY|PGHDR_CLEAN))==PGHDR_DIRTY ); pcacheManageDirtyList(p, PCACHE_DIRTYLIST_ADD); } + assert( sqlite3PcachePageSanity(p) ); } } @@ -507,12 +559,14 @@ void sqlite3PcacheMakeDirty(PgHdr *p){ ** make it so. */ void sqlite3PcacheMakeClean(PgHdr *p){ + assert( sqlite3PcachePageSanity(p) ); if( ALWAYS((p->flags & PGHDR_DIRTY)!=0) ){ assert( (p->flags & PGHDR_CLEAN)==0 ); pcacheManageDirtyList(p, PCACHE_DIRTYLIST_REMOVE); p->flags &= ~(PGHDR_DIRTY|PGHDR_NEED_SYNC|PGHDR_WRITEABLE); p->flags |= PGHDR_CLEAN; pcacheTrace(("%p.CLEAN %d\n",p->pCache,p->pgno)); + assert( sqlite3PcachePageSanity(p) ); if( p->nRef==0 ){ pcacheUnpin(p); } @@ -560,6 +614,7 @@ void sqlite3PcacheMove(PgHdr *p, Pgno newPgno){ PCache *pCache = p->pCache; assert( p->nRef>0 ); assert( newPgno>0 ); + assert( sqlite3PcachePageSanity(p) ); pcacheTrace(("%p.MOVE %d -> %d\n",pCache,p->pgno,newPgno)); sqlite3GlobalConfig.pcache2.xRekey(pCache->pCache, p->pPage, p->pgno,newPgno); p->pgno = newPgno; diff --git a/src/pcache.h b/src/pcache.h index 8e0f12e094..9012edf22e 100644 --- a/src/pcache.h +++ b/src/pcache.h @@ -51,11 +51,10 @@ struct PgHdr { #define PGHDR_WRITEABLE 0x004 /* Journaled and ready to modify */ #define PGHDR_NEED_SYNC 0x008 /* Fsync the rollback journal before ** writing this page to the database */ -#define PGHDR_NEED_READ 0x010 /* Content is unread */ -#define PGHDR_DONT_WRITE 0x020 /* Do not write content to disk */ -#define PGHDR_MMAP 0x040 /* This is an mmap page object */ +#define PGHDR_DONT_WRITE 0x010 /* Do not write content to disk */ +#define PGHDR_MMAP 0x020 /* This is an mmap page object */ -#define PGHDR_WAL_APPEND 0x080 /* Appended to wal file */ +#define PGHDR_WAL_APPEND 0x040 /* Appended to wal file */ /* Initialize and shutdown the page cache subsystem */ int sqlite3PcacheInitialize(void); @@ -138,6 +137,11 @@ int sqlite3PcachePagecount(PCache*); void sqlite3PcacheIterateDirty(PCache *pCache, void (*xIter)(PgHdr *)); #endif +#if defined(SQLITE_DEBUG) +/* Check invariants on a PgHdr object */ +int sqlite3PcachePageSanity(PgHdr*); +#endif + /* Set and get the suggested cache-size for the specified pager-cache. ** ** If no global maximum is configured, then the system attempts to limit From 3b02a07e7d91d95467b5d8935fcbc81ae7e7f9f2 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 13 May 2016 17:22:33 +0000 Subject: [PATCH 0423/1484] Improvements to a comment in the pcache.c file. No changes to code. FossilOrigin-Name: b369980f0c4550a9034833caa2c7c85d6030f5ff --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/pcache.c | 7 +++++++ 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 5b2f5a2c42..b655548911 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sthe\sunused\sPGHDR_NEED_READ\sflag.\s\sAdd\sinvariant\schecking\s(during\nSQLITE_DEBUG\sbuilds\sonly)\sfor\sthe\sPgHdr\sobject. -D 2016-05-13T15:22:06.587 +C Improvements\sto\sa\scomment\sin\sthe\spcache.c\sfile.\s\sNo\schanges\sto\scode. +D 2016-05-13T17:22:33.997 F Makefile.in 9eda6e1c90d05c199c3ec8a7069b0682ad307657 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc db82b35aef27f412fef14d8534afc022138bcdfd @@ -367,7 +367,7 @@ F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c 3910579bfbe323dfabed2b95d201159b61b8ef42 F src/pager.h 329bdf078a4e0a3b35084534d58625d21fd03681 F src/parse.y 10eb2f3fb62341291528c7984498054731f9d31e -F src/pcache.c e93f1e1b4c6134d59b4bd4f3f684f406987ef299 +F src/pcache.c f398c0084399e7481482cbc6a578a3cc4c3675f3 F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 F src/pcache1.c 7f51d2b541aab57596adf62db2c4bb025d34f04d F src/pragma.c faf42922bb7ab2f6672cb550356c1967abae3c84 @@ -1488,7 +1488,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 3401d9dcdbec390564574e8d2972c944c204e025 -R 440a1b1b52d8bc83687d285c09ed1eae +P 771c5411e9ebcad00fb4b97556b519488284b87b +R fc31f84edb2e71fa53cb5f4572b3042f U drh -Z 63614a0e4a8fa1151ab9567f8bbeafca +Z 0bbb954743a2d2dee1416e855a012aec diff --git a/manifest.uuid b/manifest.uuid index 67d06a22f0..26bf44c3d1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -771c5411e9ebcad00fb4b97556b519488284b87b \ No newline at end of file +b369980f0c4550a9034833caa2c7c85d6030f5ff \ No newline at end of file diff --git a/src/pcache.c b/src/pcache.c index d778f9aedc..d628320334 100644 --- a/src/pcache.c +++ b/src/pcache.c @@ -129,6 +129,13 @@ int sqlite3PcachePageSanity(PgHdr *pPg){ ** in step 3, and page might be written into the database without first ** syncing the rollback journal, which might cause corruption on a power ** loss. + ** + ** Another example is when the database page size is smaller than the + ** disk sector size. When any page of a sector is journalled, all pages + ** in that sector are marked NEED_SYNC even if they are still CLEAN, just + ** in case they are later modified, since all pages in the same sector + ** must be journalled and synced before any of those pages can be safely + ** written. */ return 1; } From 697c9eaa907474554aaaf97ad71f07c2a151c7ac Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 16 May 2016 11:55:09 +0000 Subject: [PATCH 0424/1484] Disable shell.exe test cases for UTF8 filenames as they do not work on MinGW. FossilOrigin-Name: 386bcbba8ed733ee84958e6bd6e9d33c150e6c18 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/shell1.test | 4 ++++ 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index b655548911..f2eb278bdd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improvements\sto\sa\scomment\sin\sthe\spcache.c\sfile.\s\sNo\schanges\sto\scode. -D 2016-05-13T17:22:33.997 +C Disable\sshell.exe\stest\scases\sfor\sUTF8\sfilenames\sas\sthey\sdo\snot\swork\son\sMinGW. +D 2016-05-16T11:55:09.207 F Makefile.in 9eda6e1c90d05c199c3ec8a7069b0682ad307657 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc db82b35aef27f412fef14d8534afc022138bcdfd @@ -1053,7 +1053,7 @@ F test/sharedA.test 0cdf1a76dfa00e6beee66af5b534b1e8df2720f5 F test/sharedB.test 16cc7178e20965d75278f410943109b77b2e645e F test/shared_err.test 2f2aee20db294b9924e81f6ccbe60f19e21e8506 F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304 -F test/shell1.test 023657b3f8ba108dbd5ff2ebc8fceb3cf6d4ff9f +F test/shell1.test c90b0415cea6eeefb86b4ab1651b06247922ca52 F test/shell2.test e242a9912f44f4c23c3d1d802a83e934e84c853b F test/shell3.test da513d522ef6f01cee8475dcf8332bff8982b3dd F test/shell4.test 69995ee1cc278eb149aa8746ce1f935f4eaf98b9 @@ -1488,7 +1488,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 771c5411e9ebcad00fb4b97556b519488284b87b -R fc31f84edb2e71fa53cb5f4572b3042f +P b369980f0c4550a9034833caa2c7c85d6030f5ff +R d8533b8fd6cbe0fbe7678e18e240aa96 U drh -Z 0bbb954743a2d2dee1416e855a012aec +Z 2e128c8e8599dacb44997bdb31a5993e diff --git a/manifest.uuid b/manifest.uuid index 26bf44c3d1..0837743ae1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b369980f0c4550a9034833caa2c7c85d6030f5ff \ No newline at end of file +386bcbba8ed733ee84958e6bd6e9d33c150e6c18 \ No newline at end of file diff --git a/test/shell1.test b/test/shell1.test index 760c85fadc..498cd64a9f 100644 --- a/test/shell1.test +++ b/test/shell1.test @@ -915,6 +915,9 @@ do_test shell1-5.0 { } } {} +# These test cases do not work on MinGW +if 0 { + # The string used here is the word "test" in Chinese. # In UTF-8, it is encoded as: \xE6\xB5\x8B\xE8\xAF\x95 set test \u6D4B\u8BD5 @@ -951,5 +954,6 @@ do_test shell1-6.1 { } forcedelete test3.db } {} +} finish_test From ee7de914d4cce9ab3eee31dfae7ec93807fab70e Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 16 May 2016 14:35:15 +0000 Subject: [PATCH 0425/1484] Do not run snapshot_fault.test as part of the inmemory_journal permutation. FossilOrigin-Name: 995c084bde44e678facc5f5d95a2335ce61e57b0 --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/permutations.test | 5 +++++ 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index f2eb278bdd..c05146f793 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Disable\sshell.exe\stest\scases\sfor\sUTF8\sfilenames\sas\sthey\sdo\snot\swork\son\sMinGW. -D 2016-05-16T11:55:09.207 +C Do\snot\srun\ssnapshot_fault.test\sas\spart\sof\sthe\sinmemory_journal\spermutation. +D 2016-05-16T14:35:15.401 F Makefile.in 9eda6e1c90d05c199c3ec8a7069b0682ad307657 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc db82b35aef27f412fef14d8534afc022138bcdfd @@ -977,7 +977,7 @@ F test/parser1.test 222b5cbf3e2e659fec1bf7d723488c8b9c94f1d0 F test/pcache.test c8acbedd3b6fd0f9a7ca887a83b11d24a007972b F test/pcache2.test af7f3deb1a819f77a6d0d81534e97d1cf62cd442 F test/percentile.test 4243af26b8f3f4555abe166f723715a1f74c77ff -F test/permutations.test b6b3e165fdc1b8c82a820033646dbfc6a7a01746 +F test/permutations.test 544a2f317fc5045bc512ae432f89eae303c0d640 F test/pragma.test 1e94755164a3a3264cd39836de4bebcb7809e5f8 F test/pragma2.test e5d5c176360c321344249354c0c16aec46214c9f F test/pragma3.test 14c12bc5352b1e100e0b6b44f371053a81ccf8ed @@ -1488,7 +1488,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b369980f0c4550a9034833caa2c7c85d6030f5ff -R d8533b8fd6cbe0fbe7678e18e240aa96 -U drh -Z 2e128c8e8599dacb44997bdb31a5993e +P 386bcbba8ed733ee84958e6bd6e9d33c150e6c18 +R 0e39e66ffd1d7cd6d62e8fa571ff36a1 +U dan +Z 786140f96f9b408e2c11236687959ca4 diff --git a/manifest.uuid b/manifest.uuid index 0837743ae1..c971be0382 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -386bcbba8ed733ee84958e6bd6e9d33c150e6c18 \ No newline at end of file +995c084bde44e678facc5f5d95a2335ce61e57b0 \ No newline at end of file diff --git a/test/permutations.test b/test/permutations.test index df3f500cda..f4784cfcee 100644 --- a/test/permutations.test +++ b/test/permutations.test @@ -746,6 +746,11 @@ test_suite "inmemory_journal" -description { # WAL mode is different. wal* tkt-2d1a5c67d.test backcompat.test e_wal* rowallock.test + + # This test does not work as the "PRAGMA journal_mode = memory" + # statement switches the database out of wal mode at inopportune + # times. + snapshot_fault.test }] ifcapable mem3 { From 0d2c3a0e11e47b1251a41c5f297cd336e6ac89a1 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 17 May 2016 21:17:51 +0000 Subject: [PATCH 0426/1484] Enhance the scrub utility program so that it does a FULL checkpoint prior to starting the backup, to ensure that the database file content matches what needs to be backed up without having to look at the WAL file. FossilOrigin-Name: ab1c5ce50f139070d7a322f43132a93c8af2ed68 --- ext/misc/scrub.c | 9 ++++++++- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/ext/misc/scrub.c b/ext/misc/scrub.c index 12adcd7bd9..1d21fc5389 100644 --- a/ext/misc/scrub.c +++ b/ext/misc/scrub.c @@ -164,13 +164,20 @@ static void scrubBackupOpenSrc(ScrubState *p){ sqlite3_errmsg(p->dbSrc)); return; } - p->rcErr = sqlite3_exec(p->dbSrc, "BEGIN", 0, 0, 0); + p->rcErr = sqlite3_exec(p->dbSrc, "SELECT 1 FROM sqlite_master; BEGIN;", + 0, 0, 0); if( p->rcErr ){ scrubBackupErr(p, "cannot start a read transaction on the source database: %s", sqlite3_errmsg(p->dbSrc)); return; } + rc = sqlite3_wal_checkpoint_v2(p->dbSrc, "main", SQLITE_CHECKPOINT_FULL, + 0, 0); + if( rc ){ + scrubBackupErr(p, "cannot checkpoint the source database"); + return; + } pStmt = scrubBackupPrepare(p, p->dbSrc, "PRAGMA page_size"); if( pStmt==0 ) return; rc = sqlite3_step(pStmt); diff --git a/manifest b/manifest index 9b5c6f0b2e..8af4221406 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sthe\slatest\schanges\sfrom\strunk. -D 2016-05-17T17:11:21.184 +C Enhance\sthe\sscrub\sutility\sprogram\sso\sthat\sit\sdoes\sa\sFULL\scheckpoint\sprior\sto\nstarting\sthe\sbackup,\sto\sensure\sthat\sthe\sdatabase\sfile\scontent\smatches\swhat\sneeds\nto\sbe\sbacked\sup\swithout\shaving\sto\slook\sat\sthe\sWAL\sfile. +D 2016-05-17T21:17:51.530 F Makefile.in f59e0763ff448719fc1bd25513882b0567286317 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7 @@ -215,7 +215,7 @@ F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342 F ext/misc/percentile.c bcbee3c061b884eccb80e21651daaae8e1e43c63 F ext/misc/regexp.c a68d25c659bd2d893cd1215667bbf75ecb9dc7d4 F ext/misc/rot13.c 1ac6f95f99b575907b9b09c81a349114cf9be45a -F ext/misc/scrub.c a3380a5ff0698f88a56a23c999ee5e53768ac3ae +F ext/misc/scrub.c ea0903701e3ac02b4466ce9cffd0325c7ddbfcf0 F ext/misc/series.c e11e534ada797d5b816d7e7a93c022306563ca35 F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52 F ext/misc/spellfix.c bf1b922c2750698e9a3d4c50cce6974adb7e93be @@ -1489,7 +1489,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d2efd3c176f0eba2d78105f0bb3161db38bd4bab 995c084bde44e678facc5f5d95a2335ce61e57b0 -R c8a04e46ce574c9cb7d04e9b64f57621 +P 5021dfe1f3f723a5938d547a0308f1d63103702d +R a2f9971160f157164223781dabeb5e95 U drh -Z 19bb7af983a6a8b12079243584bed878 +Z 2fde01a79f5811045a1dffd48050935f diff --git a/manifest.uuid b/manifest.uuid index ba749ac7fb..30152d3b67 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5021dfe1f3f723a5938d547a0308f1d63103702d \ No newline at end of file +ab1c5ce50f139070d7a322f43132a93c8af2ed68 \ No newline at end of file From 55bcaf6829131233488f57035bc8c2dc6bbdaed1 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 18 May 2016 10:57:30 +0000 Subject: [PATCH 0427/1484] Version 3.13.0 FossilOrigin-Name: fc49f556e48970561d7ab6a2f24fdd7d9eb81ff2 --- manifest | 13 ++++++++----- manifest.uuid | 2 +- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/manifest b/manifest index c05146f793..3230f21680 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Do\snot\srun\ssnapshot_fault.test\sas\spart\sof\sthe\sinmemory_journal\spermutation. -D 2016-05-16T14:35:15.401 +C Version\s3.13.0 +D 2016-05-18T10:57:30.274 F Makefile.in 9eda6e1c90d05c199c3ec8a7069b0682ad307657 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc db82b35aef27f412fef14d8534afc022138bcdfd @@ -1488,7 +1488,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 386bcbba8ed733ee84958e6bd6e9d33c150e6c18 +P 995c084bde44e678facc5f5d95a2335ce61e57b0 R 0e39e66ffd1d7cd6d62e8fa571ff36a1 -U dan -Z 786140f96f9b408e2c11236687959ca4 +T +bgcolor * #d0c0ff +T +sym-release * +T +sym-version-3.13.0 * +U drh +Z ecdfa0c32602745fc488e92155fa5f0d diff --git a/manifest.uuid b/manifest.uuid index c971be0382..8ab055941c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -995c084bde44e678facc5f5d95a2335ce61e57b0 \ No newline at end of file +fc49f556e48970561d7ab6a2f24fdd7d9eb81ff2 \ No newline at end of file From 4ca239fd559de1d6ddb551eb4141729c14ea90b5 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 19 May 2016 11:12:43 +0000 Subject: [PATCH 0428/1484] Small size reduction and performance improvement in the OP_Column opcode. FossilOrigin-Name: 0d7730611be974162d9a064a041957d04d55b6d3 --- manifest | 13 ++++++------- manifest.uuid | 2 +- src/vdbe.c | 2 +- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index ed2ee43fc4..1b36c9380b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\s"scrub"\sutility\sprogram\sthat\ssimultaneously\sbacks-up\sa\slive\sdatabase\nand\serases\sall\sdeleted\scontent. -D 2016-05-18T21:03:27.980 +C Small\ssize\sreduction\sand\sperformance\simprovement\sin\sthe\sOP_Column\sopcode. +D 2016-05-19T11:12:43.914 F Makefile.in f59e0763ff448719fc1bd25513882b0567286317 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7 @@ -444,7 +444,7 @@ F src/update.c 4f05ea8cddfa367d045e03589756c02199e8f9bd F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 810ec3f22e2d1b62e66c30fe3621ebdedd23584d F src/vacuum.c feb1eabb20987983d9350cad98299b21fa811f52 -F src/vdbe.c 4bad04212736526845fda9ca674afafb10078b2b +F src/vdbe.c d9701a72283b84a3a48b285846a9789ae541a1fd F src/vdbe.h 5591b5add447096e31288b5a0a78ec5d7b5c5170 F src/vdbeInt.h ddb157974436d87652de7dc641f7191496d9a8cd F src/vdbeapi.c ba85b78fe08dc4a9ce747e62c89a2b4a4547e74c @@ -1489,8 +1489,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 915416d15f43c4e1d3afa8121bb6fa09f9f67e30 ab1c5ce50f139070d7a322f43132a93c8af2ed68 -R d7177fcfb6d0afbc5b91ed78ec9dbdb9 -T +closed ab1c5ce50f139070d7a322f43132a93c8af2ed68 +P c981ab2a4771f8c5e95e2e85e37a02a4bd0e36ee +R b1335b5684d992944fc28b0ddd0864fa U drh -Z c9dd9bd914e72b28b0a6b209c46c7aec +Z 965b22aefdb31f818dd701e1987d5b24 diff --git a/manifest.uuid b/manifest.uuid index a5036d52e9..c2be5cd870 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c981ab2a4771f8c5e95e2e85e37a02a4bd0e36ee \ No newline at end of file +0d7730611be974162d9a064a041957d04d55b6d3 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index dc8201595b..ed12df9ac6 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2403,6 +2403,7 @@ case OP_Column: { /* If the cursor cache is stale, bring it up-to-date */ rc = sqlite3VdbeCursorMoveto(&pC, &p2); + if( rc ) goto abort_due_to_error; assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) ); pDest = &aMem[pOp->p3]; @@ -2416,7 +2417,6 @@ case OP_Column: { assert( pC->eCurType!=CURTYPE_SORTER ); pCrsr = pC->uc.pCursor; - if( rc ) goto abort_due_to_error; if( pC->cacheStatus!=p->cacheCtr ){ if( pC->nullRow ){ if( pC->eCurType==CURTYPE_PSEUDO ){ From 21690ff7fc270bec87f17c603957198355c39923 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 19 May 2016 16:21:30 +0000 Subject: [PATCH 0429/1484] Add test cases to test some fts3/4 edge case behaviour surrounding the '*' character. FossilOrigin-Name: 1f577e1f08159aeaaf19a7020d9004dd6103d57b --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/fts3expr.test | 4 ++++ 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 1b36c9380b..30689d702a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Small\ssize\sreduction\sand\sperformance\simprovement\sin\sthe\sOP_Column\sopcode. -D 2016-05-19T11:12:43.914 +C Add\stest\scases\sto\stest\ssome\sfts3/4\sedge\scase\sbehaviour\ssurrounding\sthe\s'*'\scharacter. +D 2016-05-19T16:21:30.935 F Makefile.in f59e0763ff448719fc1bd25513882b0567286317 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7 @@ -747,7 +747,7 @@ F test/fts3defer2.test c540f5f5c2840f70c68fd9b597df817ec7170468 F test/fts3defer3.test dd53fc13223c6d8264a98244e9b19abd35ed71cd F test/fts3drop.test 1b906e293d6773812587b3dc458cb9e8f3f0c297 F test/fts3e.test 1f6c6ac9cc8b772ca256e6b22aaeed50c9350851 -F test/fts3expr.test 3401d47b229c4504424caf362cc4ff704cad4162 +F test/fts3expr.test 9466627007804d855bf9df2a0cfb3dac23686fdc F test/fts3expr2.test 18da930352e5693eaa163a3eacf96233b7290d1a F test/fts3expr3.test c4d4a7d6327418428c96e0a3a1137c251b8dfbf8 F test/fts3expr4.test c39a15d676b14fc439d9bf845aa7bddcf4a74dc3 @@ -1489,7 +1489,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P c981ab2a4771f8c5e95e2e85e37a02a4bd0e36ee -R b1335b5684d992944fc28b0ddd0864fa -U drh -Z 965b22aefdb31f818dd701e1987d5b24 +P 0d7730611be974162d9a064a041957d04d55b6d3 +R 75d6e6df9086a2f9f36eca9902564b2b +U dan +Z dcfe2b5ad39143edc6be65e7ccceeb89 diff --git a/manifest.uuid b/manifest.uuid index c2be5cd870..c1125dfeb6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0d7730611be974162d9a064a041957d04d55b6d3 \ No newline at end of file +1f577e1f08159aeaaf19a7020d9004dd6103d57b \ No newline at end of file diff --git a/test/fts3expr.test b/test/fts3expr.test index 6e23faf633..b186a157d1 100644 --- a/test/fts3expr.test +++ b/test/fts3expr.test @@ -514,4 +514,8 @@ do_test fts3expr-9.1 { test_fts3expr "f (e NEAR/2 a)" } {AND {PHRASE 3 0 f} {NEAR/2 {PHRASE 3 0 e} {PHRASE 3 0 a}}} +do_test fts3expr-10.1 { test_fts3expr "abc *" } {PHRASE 3 0 abc} +do_test fts3expr-10.2 { test_fts3expr "*" } {} +do_test fts3expr-10.3 { test_fts3expr "abc*" } {PHRASE 3 0 abc+} + finish_test From 0eda6cd80d27e97ed9b87ed1e373acfe7cd65007 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 19 May 2016 16:58:42 +0000 Subject: [PATCH 0430/1484] Performance improvement in the OP_Column opcode. FossilOrigin-Name: 4737cadc414c5f6d256fcceacb19d80d66a8c8e7 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/vdbe.c | 18 +++++++++--------- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/manifest b/manifest index 30689d702a..d978122ed4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\stest\scases\sto\stest\ssome\sfts3/4\sedge\scase\sbehaviour\ssurrounding\sthe\s'*'\scharacter. -D 2016-05-19T16:21:30.935 +C Performance\simprovement\sin\sthe\sOP_Column\sopcode. +D 2016-05-19T16:58:42.935 F Makefile.in f59e0763ff448719fc1bd25513882b0567286317 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7 @@ -444,7 +444,7 @@ F src/update.c 4f05ea8cddfa367d045e03589756c02199e8f9bd F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 810ec3f22e2d1b62e66c30fe3621ebdedd23584d F src/vacuum.c feb1eabb20987983d9350cad98299b21fa811f52 -F src/vdbe.c d9701a72283b84a3a48b285846a9789ae541a1fd +F src/vdbe.c ee42e2b8f77c4bf6cf9b29be7b2235b0fc6aeca6 F src/vdbe.h 5591b5add447096e31288b5a0a78ec5d7b5c5170 F src/vdbeInt.h ddb157974436d87652de7dc641f7191496d9a8cd F src/vdbeapi.c ba85b78fe08dc4a9ce747e62c89a2b4a4547e74c @@ -1489,7 +1489,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 0d7730611be974162d9a064a041957d04d55b6d3 -R 75d6e6df9086a2f9f36eca9902564b2b -U dan -Z dcfe2b5ad39143edc6be65e7ccceeb89 +P 1f577e1f08159aeaaf19a7020d9004dd6103d57b +R e89ba2854e43a6ca2d4e88d579ae2259 +U drh +Z 6f1f0837aba6646cc9cdae7372a9992d diff --git a/manifest.uuid b/manifest.uuid index c1125dfeb6..b52d532ceb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1f577e1f08159aeaaf19a7020d9004dd6103d57b \ No newline at end of file +4737cadc414c5f6d256fcceacb19d80d66a8c8e7 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index ed12df9ac6..eecefade24 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2485,14 +2485,15 @@ case OP_Column: { rc = SQLITE_CORRUPT_BKPT; goto abort_due_to_error; } + }else if( offset>0 ){ /*OPTIMIZATION-IF-TRUE*/ + /* The following goto is an optimization. It can be omitted and + ** everything will still work. But OP_Column is measurably faster + ** by skipping the subsequent conditional, which is always true. + */ + zData = pC->aRow; + assert( pC->nHdrParsed<=p2 ); /* Conditional skipped */ + goto op_column_read_header; } - - /* The following goto is an optimization. It can be omitted and - ** everything will still work. But OP_Column is measurably faster - ** by skipping the subsequent conditional, which is always true. - */ - assert( pC->nHdrParsed<=p2 ); /* Conditional skipped */ - goto op_column_read_header; } /* Make sure at least the first p2+1 entries of the header have been @@ -2502,7 +2503,6 @@ case OP_Column: { /* If there is more header available for parsing in the record, try ** to extract additional fields up through the p2+1-th field */ - op_column_read_header: if( pC->iHdrOffsetaRow==0 ){ @@ -2515,11 +2515,11 @@ case OP_Column: { } /* Fill in pC->aType[i] and aOffset[i] values through the p2-th field. */ + op_column_read_header: i = pC->nHdrParsed; offset64 = aOffset[i]; zHdr = zData + pC->iHdrOffset; zEndHdr = zData + aOffset[0]; - assert( i<=p2 && zHdr Date: Thu, 19 May 2016 17:51:19 +0000 Subject: [PATCH 0431/1484] Optimization marks in vdbe.c. No logic changes. FossilOrigin-Name: cf2737415aff7de7e133da174b645324c99d5758 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index d978122ed4..32ce760d51 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Performance\simprovement\sin\sthe\sOP_Column\sopcode. -D 2016-05-19T16:58:42.935 +C Optimization\smarks\sin\svdbe.c.\s\sNo\slogic\schanges. +D 2016-05-19T17:51:19.307 F Makefile.in f59e0763ff448719fc1bd25513882b0567286317 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7 @@ -444,7 +444,7 @@ F src/update.c 4f05ea8cddfa367d045e03589756c02199e8f9bd F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 810ec3f22e2d1b62e66c30fe3621ebdedd23584d F src/vacuum.c feb1eabb20987983d9350cad98299b21fa811f52 -F src/vdbe.c ee42e2b8f77c4bf6cf9b29be7b2235b0fc6aeca6 +F src/vdbe.c d71b935d2b21bef874680c34329adedc3b021101 F src/vdbe.h 5591b5add447096e31288b5a0a78ec5d7b5c5170 F src/vdbeInt.h ddb157974436d87652de7dc641f7191496d9a8cd F src/vdbeapi.c ba85b78fe08dc4a9ce747e62c89a2b4a4547e74c @@ -1489,7 +1489,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 1f577e1f08159aeaaf19a7020d9004dd6103d57b -R e89ba2854e43a6ca2d4e88d579ae2259 +P 4737cadc414c5f6d256fcceacb19d80d66a8c8e7 +R 9f8362ea36557124657ddc486fb3880d U drh -Z 6f1f0837aba6646cc9cdae7372a9992d +Z f893c9ab14ca925d78367a321ac969dc diff --git a/manifest.uuid b/manifest.uuid index b52d532ceb..72112d1271 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4737cadc414c5f6d256fcceacb19d80d66a8c8e7 \ No newline at end of file +cf2737415aff7de7e133da174b645324c99d5758 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index eecefade24..6d96f85548 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2417,7 +2417,7 @@ case OP_Column: { assert( pC->eCurType!=CURTYPE_SORTER ); pCrsr = pC->uc.pCursor; - if( pC->cacheStatus!=p->cacheCtr ){ + if( pC->cacheStatus!=p->cacheCtr ){ /*OPTIMIZATION-IF-FALSE*/ if( pC->nullRow ){ if( pC->eCurType==CURTYPE_PSEUDO ){ assert( pC->uc.pseudoTableReg>0 ); @@ -2464,7 +2464,7 @@ case OP_Column: { aOffset[0] = offset; - if( availaRow does not have to hold the entire row, but it does at least ** need to cover the header of the record. If pC->aRow does not contain ** the complete header, then set it to zero, forcing the header to be From ce943bc8340461e82156e7d3c8ac1835afab6027 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 19 May 2016 18:56:33 +0000 Subject: [PATCH 0432/1484] Clean up the WHERE_* macros used for the wctrlFlags parameter on the sqlite3WhereBegin() interface, freeing up some bits to be used for other things. FossilOrigin-Name: d01305841da94b2d47e32744802f69525bf590df --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/sqliteInt.h | 24 ++++++++++++------------ src/where.c | 32 ++++++++++++++++---------------- src/wherecode.c | 14 +++++--------- 5 files changed, 42 insertions(+), 46 deletions(-) diff --git a/manifest b/manifest index 32ce760d51..9444553652 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Optimization\smarks\sin\svdbe.c.\s\sNo\slogic\schanges. -D 2016-05-19T17:51:19.307 +C Clean\sup\sthe\sWHERE_*\smacros\sused\sfor\sthe\swctrlFlags\sparameter\son\sthe\s\nsqlite3WhereBegin()\sinterface,\sfreeing\sup\ssome\sbits\sto\sbe\sused\sfor\sother\sthings. +D 2016-05-19T18:56:33.988 F Makefile.in f59e0763ff448719fc1bd25513882b0567286317 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7 @@ -383,7 +383,7 @@ F src/shell.c 14ff7f660530a52b117d110ba3390b7b2eb719b6 F src/sqlite.h.in 9984129d86243424b765fcb3f147c697bd20bb54 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 98f72cbfe00169c39089115427d06ea05fe4b4a2 -F src/sqliteInt.h 7c600fe863a30b39ba9afcedba5ee3dad657f8c2 +F src/sqliteInt.h 36ad4f5a86e1bef5e34c301b60bb24837f87d662 F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 @@ -458,9 +458,9 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 4db22ed7e77bcf672b1a685d6ddeffba8d5be302 F src/wal.h 2f7c831cf3b071fa548bf2d5cac640846a7ff19c F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354 -F src/where.c ad8ad50ccf25795f6830b6b864bbfcd060ff08dd +F src/where.c 72fd2e1258625c1aee8e33a529914aea2d487422 F src/whereInt.h 3b1fc240e322613ba4e9dc857ca9c7c3390acc74 -F src/wherecode.c d227fca7d766a10fe4ba4d812210f5631f5a98b3 +F src/wherecode.c e3f18fcda2d7f8218a09dc33cf495dca0efa6e3e F src/whereexpr.c eacc0e60d029a082b4fc0cc42ea98544add1319e F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -1489,7 +1489,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 4737cadc414c5f6d256fcceacb19d80d66a8c8e7 -R 9f8362ea36557124657ddc486fb3880d +P cf2737415aff7de7e133da174b645324c99d5758 +R b3dd248e38fe4d745483b43457d811f8 U drh -Z f893c9ab14ca925d78367a321ac969dc +Z 077055ad654ddf765f85d8f018c402ea diff --git a/manifest.uuid b/manifest.uuid index 72112d1271..3688ab723e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cf2737415aff7de7e133da174b645324c99d5758 \ No newline at end of file +d01305841da94b2d47e32744802f69525bf590df \ No newline at end of file diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 6fb027cacc..a232e7b894 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2531,19 +2531,19 @@ struct SrcList { #define WHERE_ORDERBY_MIN 0x0001 /* ORDER BY processing for min() func */ #define WHERE_ORDERBY_MAX 0x0002 /* ORDER BY processing for max() func */ #define WHERE_ONEPASS_DESIRED 0x0004 /* Want to do one-pass UPDATE/DELETE */ -#define WHERE_DUPLICATES_OK 0x0008 /* Ok to return a row more than once */ -#define WHERE_OMIT_OPEN_CLOSE 0x0010 /* Table cursors are already open */ -#define WHERE_FORCE_TABLE 0x0020 /* Do not use an index-only search */ -#define WHERE_ONETABLE_ONLY 0x0040 /* Only code the 1st table in pTabList */ -#define WHERE_NO_AUTOINDEX 0x0080 /* Disallow automatic indexes */ -#define WHERE_GROUPBY 0x0100 /* pOrderBy is really a GROUP BY */ -#define WHERE_DISTINCTBY 0x0200 /* pOrderby is really a DISTINCT clause */ -#define WHERE_WANT_DISTINCT 0x0400 /* All output needs to be distinct */ -#define WHERE_SORTBYGROUP 0x0800 /* Support sqlite3WhereIsSorted() */ - /* 0x1000 not currently used */ -#define WHERE_ONEPASS_MULTIROW 0x2000 /* ONEPASS is ok with multiple rows */ +#define WHERE_ONEPASS_MULTIROW 0x0008 /* ONEPASS is ok with multiple rows */ +#define WHERE_DUPLICATES_OK 0x0010 /* Ok to return a row more than once */ +#define WHERE_OR_SUBCLAUSE 0x0020 /* Sub-WHERE for an OR term */ +#define WHERE_GROUPBY 0x0040 /* pOrderBy is really a GROUP BY */ +#define WHERE_DISTINCTBY 0x0080 /* pOrderby is really a DISTINCT clause */ +#define WHERE_WANT_DISTINCT 0x0100 /* All output needs to be distinct */ +#define WHERE_SORTBYGROUP 0x0200 /* Support sqlite3WhereIsSorted() */ +#define WHERE_SEEK_TABLE 0x0400 /* Do not defer seeks on main table */ + /* 0x0800 not currently used */ + /* 0x1000 not currently used */ + /* 0x2000 not currently used */ #define WHERE_USE_LIMIT 0x4000 /* There is a constant LIMIT clause */ -#define WHERE_SEEK_TABLE 0x8000 /* Do not defer seeks on main table */ + /* 0x8000 not currently used */ /* Allowed return values from sqlite3WhereIsDistinct() */ diff --git a/src/where.c b/src/where.c index 849d0ae5bd..f6f6f68eab 100644 --- a/src/where.c +++ b/src/where.c @@ -2635,7 +2635,7 @@ static int whereLoopAddBtree( #ifndef SQLITE_OMIT_AUTOMATIC_INDEX /* Automatic indexes */ if( !pBuilder->pOrSet /* Not part of an OR optimization */ - && (pWInfo->wctrlFlags & WHERE_NO_AUTOINDEX)==0 + && (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0 && (pWInfo->pParse->db->flags & SQLITE_AutoIndex)!=0 && pSrc->pIBIndex==0 /* Has no INDEXED BY clause */ && !pSrc->fg.notIndexed /* Has no NOT INDEXED clause */ @@ -3947,7 +3947,7 @@ static int whereShortCut(WhereLoopBuilder *pBuilder){ Index *pIdx; pWInfo = pBuilder->pWInfo; - if( pWInfo->wctrlFlags & WHERE_FORCE_TABLE ) return 0; + if( pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE ) return 0; assert( pWInfo->pTabList->nSrc>=1 ); pItem = pWInfo->pTabList->a; pTab = pItem->pTab; @@ -4094,7 +4094,7 @@ static int whereShortCut(WhereLoopBuilder *pBuilder){ ** is called from an UPDATE or DELETE statement, then pOrderBy is NULL. ** ** The iIdxCur parameter is the cursor number of an index. If -** WHERE_ONETABLE_ONLY is set, iIdxCur is the cursor number of an index +** WHERE_OR_SUBCLAUSE is set, iIdxCur is the cursor number of an index ** to use for OR clause processing. The WHERE clause should use this ** specific cursor. If WHERE_ONEPASS_DESIRED is set, then iIdxCur is ** the first cursor in an array of cursors for all indices. iIdxCur should @@ -4108,7 +4108,7 @@ WhereInfo *sqlite3WhereBegin( ExprList *pOrderBy, /* An ORDER BY (or GROUP BY) clause, or NULL */ ExprList *pDistinctSet, /* Try not to output two rows that duplicate these */ u16 wctrlFlags, /* The WHERE_* flags defined in sqliteInt.h */ - int iAuxArg /* If WHERE_ONETABLE_ONLY is set, index cursor number + int iAuxArg /* If WHERE_OR_SUBCLAUSE is set, index cursor number ** If WHERE_USE_LIMIT, then the limit amount */ ){ int nByteWInfo; /* Num. bytes allocated for WhereInfo struct */ @@ -4127,11 +4127,11 @@ WhereInfo *sqlite3WhereBegin( assert( (wctrlFlags & WHERE_ONEPASS_MULTIROW)==0 || ( (wctrlFlags & WHERE_ONEPASS_DESIRED)!=0 - && (wctrlFlags & WHERE_OMIT_OPEN_CLOSE)==0 + && (wctrlFlags & WHERE_OR_SUBCLAUSE)==0 )); - /* Only one of WHERE_ONETABLE_ONLY or WHERE_USE_LIMIT */ - assert( (wctrlFlags & WHERE_ONETABLE_ONLY)==0 + /* Only one of WHERE_OR_SUBCLAUSE or WHERE_USE_LIMIT */ + assert( (wctrlFlags & WHERE_OR_SUBCLAUSE)==0 || (wctrlFlags & WHERE_USE_LIMIT)==0 ); /* Variable initialization */ @@ -4159,11 +4159,11 @@ WhereInfo *sqlite3WhereBegin( } /* This function normally generates a nested loop for all tables in - ** pTabList. But if the WHERE_ONETABLE_ONLY flag is set, then we should + ** pTabList. But if the WHERE_OR_SUBCLAUSE flag is set, then we should ** only generate code for the first table in pTabList and assume that ** any cursors associated with subsequent tables are uninitialized. */ - nTabList = (wctrlFlags & WHERE_ONETABLE_ONLY) ? 1 : pTabList->nSrc; + nTabList = (wctrlFlags & WHERE_OR_SUBCLAUSE) ? 1 : pTabList->nSrc; /* Allocate and initialize the WhereInfo structure that will become the ** return value. A single allocation is used to store the WhereInfo @@ -4239,7 +4239,7 @@ WhereInfo *sqlite3WhereBegin( ** Note that bitmasks are created for all pTabList->nSrc tables in ** pTabList, not just the first nTabList tables. nTabList is normally ** equal to pTabList->nSrc but might be shortened to 1 if the - ** WHERE_ONETABLE_ONLY flag is set. + ** WHERE_OR_SUBCLAUSE flag is set. */ for(ii=0; iinSrc; ii++){ createMask(pMaskSet, pTabList->a[ii].iCursor); @@ -4422,7 +4422,7 @@ WhereInfo *sqlite3WhereBegin( }else #endif if( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 - && (wctrlFlags & WHERE_OMIT_OPEN_CLOSE)==0 ){ + && (wctrlFlags & WHERE_OR_SUBCLAUSE)==0 ){ int op = OP_OpenRead; if( pWInfo->eOnePass!=ONEPASS_OFF ){ op = OP_OpenWrite; @@ -4461,7 +4461,7 @@ WhereInfo *sqlite3WhereBegin( /* iAuxArg is always set if to a positive value if ONEPASS is possible */ assert( iAuxArg!=0 || (pWInfo->wctrlFlags & WHERE_ONEPASS_DESIRED)==0 ); if( !HasRowid(pTab) && IsPrimaryKeyIndex(pIx) - && (wctrlFlags & WHERE_ONETABLE_ONLY)!=0 + && (wctrlFlags & WHERE_OR_SUBCLAUSE)!=0 ){ /* This is one term of an OR-optimization using the PRIMARY KEY of a ** WITHOUT ROWID table. No need for a separate index */ @@ -4477,7 +4477,7 @@ WhereInfo *sqlite3WhereBegin( } op = OP_OpenWrite; pWInfo->aiCurOnePass[1] = iIndexCur; - }else if( iAuxArg && (wctrlFlags & WHERE_ONETABLE_ONLY)!=0 ){ + }else if( iAuxArg && (wctrlFlags & WHERE_OR_SUBCLAUSE)!=0 ){ iIndexCur = iAuxArg; op = OP_ReopenIdx; }else{ @@ -4541,7 +4541,7 @@ WhereInfo *sqlite3WhereBegin( pLevel->addrBody = sqlite3VdbeCurrentAddr(v); notReady = sqlite3WhereCodeOneLoopStart(pWInfo, ii, notReady); pWInfo->iContinue = pLevel->addrCont; - if( (wsFlags&WHERE_MULTI_OR)==0 && (wctrlFlags&WHERE_ONETABLE_ONLY)==0 ){ + if( (wsFlags&WHERE_MULTI_OR)==0 && (wctrlFlags&WHERE_OR_SUBCLAUSE)==0 ){ sqlite3WhereAddScanStatus(v, pTabList, pLevel, addrExplain); } } @@ -4664,12 +4664,12 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ /* Close all of the cursors that were opened by sqlite3WhereBegin. ** Except, do not close cursors that will be reused by the OR optimization - ** (WHERE_OMIT_OPEN_CLOSE). And do not close the OP_OpenWrite cursors + ** (WHERE_OR_SUBCLAUSE). And do not close the OP_OpenWrite cursors ** created for the ONEPASS optimization. */ if( (pTab->tabFlags & TF_Ephemeral)==0 && pTab->pSelect==0 - && (pWInfo->wctrlFlags & WHERE_OMIT_OPEN_CLOSE)==0 + && (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0 ){ int ws = pLoop->wsFlags; if( pWInfo->eOnePass==ONEPASS_OFF && (ws & WHERE_IDX_ONLY)==0 ){ diff --git a/src/wherecode.c b/src/wherecode.c index a42fa1f843..054b1b1078 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -126,7 +126,7 @@ int sqlite3WhereExplainOneScan( pLoop = pLevel->pWLoop; flags = pLoop->wsFlags; - if( (flags&WHERE_MULTI_OR) || (wctrlFlags&WHERE_ONETABLE_ONLY) ) return 0; + if( (flags&WHERE_MULTI_OR) || (wctrlFlags&WHERE_OR_SUBCLAUSE) ) return 0; isSearch = (flags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))!=0 || ((flags&WHERE_VIRTUALTABLE)==0 && (pLoop->u.btree.nEq>0)) @@ -776,7 +776,7 @@ static void codeDeferredSeek( assert( pIdx->aiColumn[pIdx->nColumn-1]==-1 ); sqlite3VdbeAddOp3(v, OP_Seek, iIdxCur, 0, iCur); - if( (pWInfo->wctrlFlags & WHERE_FORCE_TABLE) + if( (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE) && DbMaskAllZero(sqlite3ParseToplevel(pParse)->writeMask) ){ int i; @@ -831,7 +831,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( pLevel->notReady = notReady & ~sqlite3WhereGetMask(&pWInfo->sMaskSet, iCur); bRev = (pWInfo->revMask>>iLevel)&1; omitTable = (pLoop->wsFlags & WHERE_IDX_ONLY)!=0 - && (pWInfo->wctrlFlags & WHERE_FORCE_TABLE)==0; + && (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0; VdbeModuleComment((v, "Begin WHERE-loop%d: %s",iLevel,pTabItem->pTab->zName)); /* Create labels for the "break" and "continue" instructions @@ -1517,11 +1517,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( ** eliminating duplicates from other WHERE clauses, the action for each ** sub-WHERE clause is to to invoke the main loop body as a subroutine. */ - wctrlFlags = WHERE_OMIT_OPEN_CLOSE - | WHERE_FORCE_TABLE - | WHERE_ONETABLE_ONLY - | WHERE_NO_AUTOINDEX - | (pWInfo->wctrlFlags & WHERE_SEEK_TABLE); + wctrlFlags = WHERE_OR_SUBCLAUSE | (pWInfo->wctrlFlags & WHERE_SEEK_TABLE); for(ii=0; iinTerm; ii++){ WhereTerm *pOrTerm = &pOrWc->a[ii]; if( pOrTerm->leftCursor==iCur || (pOrTerm->eOperator & WO_AND)!=0 ){ @@ -1690,7 +1686,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue; if( (pTerm->prereqAll & pLevel->notReady)!=0 ){ testcase( pWInfo->untestedTerms==0 - && (pWInfo->wctrlFlags & WHERE_ONETABLE_ONLY)!=0 ); + && (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)!=0 ); pWInfo->untestedTerms = 1; continue; } From bc5eac00c2a093597cbb743891d8fbbb6312a50e Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 19 May 2016 19:31:30 +0000 Subject: [PATCH 0433/1484] Fixup comments on wctrlFlags value definitions. FossilOrigin-Name: 58b516e8c0b00a41bc0364eab267bc2ecb9efeff --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/sqliteInt.h | 5 +++-- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 9444553652..89053f9deb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Clean\sup\sthe\sWHERE_*\smacros\sused\sfor\sthe\swctrlFlags\sparameter\son\sthe\s\nsqlite3WhereBegin()\sinterface,\sfreeing\sup\ssome\sbits\sto\sbe\sused\sfor\sother\sthings. -D 2016-05-19T18:56:33.988 +C Fixup\scomments\son\swctrlFlags\svalue\sdefinitions. +D 2016-05-19T19:31:30.127 F Makefile.in f59e0763ff448719fc1bd25513882b0567286317 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7 @@ -383,7 +383,7 @@ F src/shell.c 14ff7f660530a52b117d110ba3390b7b2eb719b6 F src/sqlite.h.in 9984129d86243424b765fcb3f147c697bd20bb54 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 98f72cbfe00169c39089115427d06ea05fe4b4a2 -F src/sqliteInt.h 36ad4f5a86e1bef5e34c301b60bb24837f87d662 +F src/sqliteInt.h 19de316bfce65ff074b379a67b493a446f3cf8ee F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 @@ -1489,7 +1489,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P cf2737415aff7de7e133da174b645324c99d5758 -R b3dd248e38fe4d745483b43457d811f8 +P d01305841da94b2d47e32744802f69525bf590df +R be830660ecf90ba00189952af638cb97 U drh -Z 077055ad654ddf765f85d8f018c402ea +Z 54bddff0ee366139e2fb13081e6cf75a diff --git a/manifest.uuid b/manifest.uuid index 3688ab723e..177ef2d35a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d01305841da94b2d47e32744802f69525bf590df \ No newline at end of file +58b516e8c0b00a41bc0364eab267bc2ecb9efeff \ No newline at end of file diff --git a/src/sqliteInt.h b/src/sqliteInt.h index a232e7b894..c795036666 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2533,7 +2533,8 @@ struct SrcList { #define WHERE_ONEPASS_DESIRED 0x0004 /* Want to do one-pass UPDATE/DELETE */ #define WHERE_ONEPASS_MULTIROW 0x0008 /* ONEPASS is ok with multiple rows */ #define WHERE_DUPLICATES_OK 0x0010 /* Ok to return a row more than once */ -#define WHERE_OR_SUBCLAUSE 0x0020 /* Sub-WHERE for an OR term */ +#define WHERE_OR_SUBCLAUSE 0x0020 /* Processing a sub-WHERE as part of + ** the OR optimization */ #define WHERE_GROUPBY 0x0040 /* pOrderBy is really a GROUP BY */ #define WHERE_DISTINCTBY 0x0080 /* pOrderby is really a DISTINCT clause */ #define WHERE_WANT_DISTINCT 0x0100 /* All output needs to be distinct */ @@ -2542,7 +2543,7 @@ struct SrcList { /* 0x0800 not currently used */ /* 0x1000 not currently used */ /* 0x2000 not currently used */ -#define WHERE_USE_LIMIT 0x4000 /* There is a constant LIMIT clause */ +#define WHERE_USE_LIMIT 0x4000 /* Use the LIMIT in cost estimates */ /* 0x8000 not currently used */ /* Allowed return values from sqlite3WhereIsDistinct() From a536df4e7ffedd6a3169d44b854fc40c3af4d354 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 19 May 2016 22:13:37 +0000 Subject: [PATCH 0434/1484] In a query with both ORDER BY and LIMIT, if the inner loop satisfies the ORDER BY then try to cut short each invocation of the inner loop once the LIMIT has been satisfied. This check-in is a partial implementation only. FossilOrigin-Name: 852d1eda6ecca1171f6ed800b06f5b4854672002 --- manifest | 21 ++++++++++++--------- manifest.uuid | 2 +- src/select.c | 22 ++++++++++++++++++++++ src/sqliteInt.h | 1 + src/where.c | 16 +++++++++++++++- src/whereInt.h | 3 ++- 6 files changed, 53 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 89053f9deb..d01cdd7db8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fixup\scomments\son\swctrlFlags\svalue\sdefinitions. -D 2016-05-19T19:31:30.127 +C In\sa\squery\swith\sboth\sORDER\sBY\sand\sLIMIT,\sif\sthe\sinner\sloop\ssatisfies\sthe\s\nORDER\sBY\sthen\stry\sto\scut\sshort\seach\sinvocation\sof\sthe\sinner\sloop\sonce\sthe\nLIMIT\shas\sbeen\ssatisfied.\s\sThis\scheck-in\sis\sa\spartial\simplementation\sonly. +D 2016-05-19T22:13:37.318 F Makefile.in f59e0763ff448719fc1bd25513882b0567286317 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7 @@ -378,12 +378,12 @@ F src/printf.c a5f0ca08ddede803c241266abb46356ec748ded1 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c cca3aa77b95706df5d635a2141a4d1de60ae6598 F src/rowset.c 49eb91c588a2bab36647368e031dc5b66928149d -F src/select.c fd4a7ce2937497181063cfedb92058ac89491a5d +F src/select.c 131eeddfcaf3777c4acd4727bf742b98af8183b5 F src/shell.c 14ff7f660530a52b117d110ba3390b7b2eb719b6 F src/sqlite.h.in 9984129d86243424b765fcb3f147c697bd20bb54 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 98f72cbfe00169c39089115427d06ea05fe4b4a2 -F src/sqliteInt.h 19de316bfce65ff074b379a67b493a446f3cf8ee +F src/sqliteInt.h 863cf0d421611ccfa30541ee5ffe761c896ffa5b F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 @@ -458,8 +458,8 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 4db22ed7e77bcf672b1a685d6ddeffba8d5be302 F src/wal.h 2f7c831cf3b071fa548bf2d5cac640846a7ff19c F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354 -F src/where.c 72fd2e1258625c1aee8e33a529914aea2d487422 -F src/whereInt.h 3b1fc240e322613ba4e9dc857ca9c7c3390acc74 +F src/where.c a7454e62ca13f1ff54892339022f8cb0a8bb3728 +F src/whereInt.h 6e18240be400bef8e4dbafea605251707c5dbf49 F src/wherecode.c e3f18fcda2d7f8218a09dc33cf495dca0efa6e3e F src/whereexpr.c eacc0e60d029a082b4fc0cc42ea98544add1319e F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 @@ -1489,7 +1489,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d01305841da94b2d47e32744802f69525bf590df -R be830660ecf90ba00189952af638cb97 +P 58b516e8c0b00a41bc0364eab267bc2ecb9efeff +R 766495aa6109f75a3c3b0e829e8d3b47 +T *branch * orderby-limit +T *sym-orderby-limit * +T -sym-trunk * U drh -Z 54bddff0ee366139e2fb13081e6cf75a +Z 1f191cc43f073ab10b6b672b5a12f950 diff --git a/manifest.uuid b/manifest.uuid index 177ef2d35a..ec9b410bfa 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -58b516e8c0b00a41bc0364eab267bc2ecb9efeff \ No newline at end of file +852d1eda6ecca1171f6ed800b06f5b4854672002 \ No newline at end of file diff --git a/src/select.c b/src/select.c index eb37536b6f..080ccf3480 100644 --- a/src/select.c +++ b/src/select.c @@ -56,6 +56,7 @@ struct SortCtx { int addrSortIndex; /* Address of the OP_SorterOpen or OP_OpenEphemeral */ int labelDone; /* Jump here when done, ex: LIMIT reached */ u8 sortFlags; /* Zero or more SORTFLAG_* bits */ + u8 bOrderedInnerLoop; /* ORDER BY correctly sorts the inner loop */ }; #define SORTFLAG_UseSorter 0x01 /* Use SorterOpen instead of OpenEphemeral */ @@ -589,9 +590,29 @@ static void pushOntoSorter( sqlite3VdbeAddOp2(v, op, pSort->iECursor, regRecord); if( iLimit ){ int addr; + int r1 = 0; + /* Fill the sorter until it contains LIMIT+OFFSET entries. (The iLimit + ** register is initialized with value of LIMIT+OFFSET.) After the sorter + ** fills up, delete the least entry in the sorter after each insert. + ** Thus we never hold more than the LIMIT+OFFSET rows in memory at once */ addr = sqlite3VdbeAddOp3(v, OP_IfNotZero, iLimit, 0, 1); VdbeCoverage(v); sqlite3VdbeAddOp1(v, OP_Last, pSort->iECursor); + if( pSort->bOrderedInnerLoop ){ + r1 = ++pParse->nMem; + sqlite3VdbeAddOp3(v, OP_Column, pSort->iECursor, nExpr, r1); + VdbeComment((v, "seq")); + } sqlite3VdbeAddOp1(v, OP_Delete, pSort->iECursor); + if( pSort->bOrderedInnerLoop ){ + /* If the inner loop is driven by an index such that values from + ** the same iteration of the inner loop are in sorted order, then + ** immediately jump to the next iteration of an inner loop if the + ** entry from the current iteration does not fit into the top + ** LIMIT+OFFSET entries of the sorter. */ + int iBrk = sqlite3VdbeCurrentAddr(v) + 2; + sqlite3VdbeAddOp3(v, OP_Eq, regBase+nExpr, iBrk, r1); + VdbeCoverage(v); + } sqlite3VdbeJumpHere(v, addr); } } @@ -5176,6 +5197,7 @@ int sqlite3Select( } if( sSort.pOrderBy ){ sSort.nOBSat = sqlite3WhereIsOrdered(pWInfo); + sSort.bOrderedInnerLoop = sqlite3WhereOrderedInnerLoop(pWInfo); if( sSort.nOBSat==sSort.pOrderBy->nExpr ){ sSort.pOrderBy = 0; } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index c795036666..7adfd3779b 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3637,6 +3637,7 @@ void sqlite3WhereEnd(WhereInfo*); LogEst sqlite3WhereOutputRowCount(WhereInfo*); int sqlite3WhereIsDistinct(WhereInfo*); int sqlite3WhereIsOrdered(WhereInfo*); +int sqlite3WhereOrderedInnerLoop(WhereInfo*); int sqlite3WhereIsSorted(WhereInfo*); int sqlite3WhereContinueLabel(WhereInfo*); int sqlite3WhereBreakLabel(WhereInfo*); diff --git a/src/where.c b/src/where.c index f6f6f68eab..521d2e19ec 100644 --- a/src/where.c +++ b/src/where.c @@ -51,6 +51,18 @@ int sqlite3WhereIsOrdered(WhereInfo *pWInfo){ return pWInfo->nOBSat; } +/* +** Return TRUE if the innermost loop of the WHERE clause implementation +** returns rows in ORDER BY order for complete run of the inner loop. +** +** Across multiple iterations of outer loops, the output rows need not be +** sorted. As long as rows are sorted for just the innermost loop, this +** routine can return TRUE. +*/ +int sqlite3WhereOrderedInnerLoop(WhereInfo *pWInfo){ + return pWInfo->bOrderedInnerLoop; +} + /* ** Return the VDBE address or label to jump to in order to continue ** immediately with the next row of a WHERE clause. @@ -3898,8 +3910,10 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ } }else{ pWInfo->nOBSat = pFrom->isOrdered; - if( pWInfo->nOBSat<0 ) pWInfo->nOBSat = 0; pWInfo->revMask = pFrom->revLoop; + if( pWInfo->nOBSat<=0 ){ + pWInfo->nOBSat = 0; + } } if( (pWInfo->wctrlFlags & WHERE_SORTBYGROUP) && pWInfo->nOBSat==pWInfo->pOrderBy->nExpr && nLoop>0 diff --git a/src/whereInt.h b/src/whereInt.h index d33d995af1..ed6b198e4b 100644 --- a/src/whereInt.h +++ b/src/whereInt.h @@ -418,8 +418,9 @@ struct WhereInfo { u8 sorted; /* True if really sorted (not just grouped) */ u8 eOnePass; /* ONEPASS_OFF, or _SINGLE, or _MULTI */ u8 untestedTerms; /* Not all WHERE terms resolved by outer loop */ - u8 eDistinct; /* One of the WHERE_DISTINCT_* values below */ + u8 eDistinct; /* One of the WHERE_DISTINCT_* values */ u8 nLevel; /* Number of nested loop */ + u8 bOrderedInnerLoop; /* True if only the inner-most loop is ordered */ int iTop; /* The very beginning of the WHERE loop */ int iContinue; /* Jump here to continue with next record */ int iBreak; /* Jump here to break out of the loop */ From d711e522292566c8ef055da3af8f095dabea6781 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 19 May 2016 22:40:04 +0000 Subject: [PATCH 0435/1484] Appears to work now. Needs test cases, more comments, and code optimization. FossilOrigin-Name: 990fe50c9182f74c9b54a12602c4c30d891273e6 --- manifest | 17 +++++++---------- manifest.uuid | 2 +- src/sqliteInt.h | 2 +- src/where.c | 29 ++++++++++++++++++++++++----- 4 files changed, 33 insertions(+), 17 deletions(-) diff --git a/manifest b/manifest index d01cdd7db8..39cec630ce 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\sa\squery\swith\sboth\sORDER\sBY\sand\sLIMIT,\sif\sthe\sinner\sloop\ssatisfies\sthe\s\nORDER\sBY\sthen\stry\sto\scut\sshort\seach\sinvocation\sof\sthe\sinner\sloop\sonce\sthe\nLIMIT\shas\sbeen\ssatisfied.\s\sThis\scheck-in\sis\sa\spartial\simplementation\sonly. -D 2016-05-19T22:13:37.318 +C Appears\sto\swork\snow.\s\sNeeds\stest\scases,\smore\scomments,\sand\scode\soptimization. +D 2016-05-19T22:40:04.862 F Makefile.in f59e0763ff448719fc1bd25513882b0567286317 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7 @@ -383,7 +383,7 @@ F src/shell.c 14ff7f660530a52b117d110ba3390b7b2eb719b6 F src/sqlite.h.in 9984129d86243424b765fcb3f147c697bd20bb54 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 98f72cbfe00169c39089115427d06ea05fe4b4a2 -F src/sqliteInt.h 863cf0d421611ccfa30541ee5ffe761c896ffa5b +F src/sqliteInt.h 09621b4b7dba808b24262c2480ea75b045001853 F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 @@ -458,7 +458,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 4db22ed7e77bcf672b1a685d6ddeffba8d5be302 F src/wal.h 2f7c831cf3b071fa548bf2d5cac640846a7ff19c F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354 -F src/where.c a7454e62ca13f1ff54892339022f8cb0a8bb3728 +F src/where.c 0e54a03d11d4e99ad25528f42ff4c9a6fa7a23da F src/whereInt.h 6e18240be400bef8e4dbafea605251707c5dbf49 F src/wherecode.c e3f18fcda2d7f8218a09dc33cf495dca0efa6e3e F src/whereexpr.c eacc0e60d029a082b4fc0cc42ea98544add1319e @@ -1489,10 +1489,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 58b516e8c0b00a41bc0364eab267bc2ecb9efeff -R 766495aa6109f75a3c3b0e829e8d3b47 -T *branch * orderby-limit -T *sym-orderby-limit * -T -sym-trunk * +P 852d1eda6ecca1171f6ed800b06f5b4854672002 +R 664cd7ecddde2637b78c890f65cd5e15 U drh -Z 1f191cc43f073ab10b6b672b5a12f950 +Z a9319f97e8df1737542ca3813ad100bc diff --git a/manifest.uuid b/manifest.uuid index ec9b410bfa..2ec1166f5a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -852d1eda6ecca1171f6ed800b06f5b4854672002 \ No newline at end of file +990fe50c9182f74c9b54a12602c4c30d891273e6 \ No newline at end of file diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 7adfd3779b..b15d788093 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2540,7 +2540,7 @@ struct SrcList { #define WHERE_WANT_DISTINCT 0x0100 /* All output needs to be distinct */ #define WHERE_SORTBYGROUP 0x0200 /* Support sqlite3WhereIsSorted() */ #define WHERE_SEEK_TABLE 0x0400 /* Do not defer seeks on main table */ - /* 0x0800 not currently used */ +#define WHERE_ORDERBY_LIMIT 0x0800 /* ORDERBY+LIMIT on the inner loop */ /* 0x1000 not currently used */ /* 0x2000 not currently used */ #define WHERE_USE_LIMIT 0x4000 /* Use the LIMIT in cost estimates */ diff --git a/src/where.c b/src/where.c index 521d2e19ec..cb008b7df4 100644 --- a/src/where.c +++ b/src/where.c @@ -3262,7 +3262,7 @@ static i8 wherePathSatisfiesOrderBy( WhereInfo *pWInfo, /* The WHERE clause */ ExprList *pOrderBy, /* ORDER BY or GROUP BY or DISTINCT clause to check */ WherePath *pPath, /* The WherePath to check */ - u16 wctrlFlags, /* Might contain WHERE_GROUPBY or WHERE_DISTINCTBY */ + u16 wctrlFlags, /* WHERE_GROUPBY or _DISTINCTBY or _ORDERBY_LIMIT */ u16 nLoop, /* Number of entries in pPath->aLoop[] */ WhereLoop *pLast, /* Add this WhereLoop to the end of pPath->aLoop[] */ Bitmask *pRevMask /* OUT: Mask of WhereLoops to run in reverse order */ @@ -3273,6 +3273,7 @@ static i8 wherePathSatisfiesOrderBy( u8 isOrderDistinct; /* All prior WhereLoops are order-distinct */ u8 distinctColumns; /* True if the loop has UNIQUE NOT NULL columns */ u8 isMatch; /* iColumn matches a term of the ORDER BY clause */ + u16 eqOpMask; /* Allowed equality operators */ u16 nKeyCol; /* Number of key columns in pIndex */ u16 nColumn; /* Total number of ordered columns in the index */ u16 nOrderBy; /* Number terms in the ORDER BY clause */ @@ -3323,9 +3324,16 @@ static i8 wherePathSatisfiesOrderBy( obDone = MASKBIT(nOrderBy)-1; orderDistinctMask = 0; ready = 0; + eqOpMask = WO_EQ | WO_IS | WO_ISNULL; + if( wctrlFlags & WHERE_ORDERBY_LIMIT ) eqOpMask |= WO_IN; for(iLoop=0; isOrderDistinct && obSat0 ) ready |= pLoop->maskSelf; - pLoop = iLoopaLoop[iLoop] : pLast; + if( iLoopaLoop[iLoop]; + if( wctrlFlags & WHERE_ORDERBY_LIMIT ) continue; + }else{ + pLoop = pLast; + } if( pLoop->wsFlags & WHERE_VIRTUALTABLE ){ if( pLoop->u.vtab.isOrdered ) obSat = obDone; break; @@ -3343,7 +3351,7 @@ static i8 wherePathSatisfiesOrderBy( if( pOBExpr->op!=TK_COLUMN ) continue; if( pOBExpr->iTable!=iCur ) continue; pTerm = sqlite3WhereFindTerm(&pWInfo->sWC, iCur, pOBExpr->iColumn, - ~ready, WO_EQ|WO_ISNULL|WO_IS, 0); + ~ready, eqOpMask, 0); if( pTerm==0 ) continue; if( (pTerm->eOperator&(WO_EQ|WO_IS))!=0 && pOBExpr->iColumn>=0 ){ const char *z1, *z2; @@ -3383,10 +3391,12 @@ static i8 wherePathSatisfiesOrderBy( for(j=0; ju.btree.nEq && pLoop->nSkip==0 - && ((i = pLoop->aLTerm[j]->eOperator) & (WO_EQ|WO_ISNULL|WO_IS))!=0 + && ((i = pLoop->aLTerm[j]->eOperator) & eqOpMask)!=0 ){ if( i & WO_ISNULL ){ testcase( isOrderDistinct ); @@ -3913,6 +3923,15 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ pWInfo->revMask = pFrom->revLoop; if( pWInfo->nOBSat<=0 ){ pWInfo->nOBSat = 0; + if( nLoop>0 ){ + Bitmask m; + int rc = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pOrderBy, pFrom, + WHERE_ORDERBY_LIMIT, nLoop-1, pFrom->aLoop[nLoop-1], &m); + if( rc==pWInfo->pOrderBy->nExpr ){ + pWInfo->bOrderedInnerLoop = 1; + pWInfo->revMask = m; + } + } } } if( (pWInfo->wctrlFlags & WHERE_SORTBYGROUP) From 73fa4737ce3c357b6b4a96e83944af8f8019f53b Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 20 May 2016 00:21:42 +0000 Subject: [PATCH 0436/1484] A few simple test cases for the ORDER BY LIMIT optimization. FossilOrigin-Name: 08849eab0f6ef29eaf6d2ce9c692de9b953dbd27 --- manifest | 11 ++++--- manifest.uuid | 2 +- test/limit2.test | 82 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 89 insertions(+), 6 deletions(-) create mode 100644 test/limit2.test diff --git a/manifest b/manifest index 39cec630ce..3f35f82e00 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Appears\sto\swork\snow.\s\sNeeds\stest\scases,\smore\scomments,\sand\scode\soptimization. -D 2016-05-19T22:40:04.862 +C A\sfew\ssimple\stest\scases\sfor\sthe\sORDER\sBY\sLIMIT\soptimization. +D 2016-05-20T00:21:42.961 F Makefile.in f59e0763ff448719fc1bd25513882b0567286317 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7 @@ -878,6 +878,7 @@ F test/like.test 81632c437a947bf1f7130b19537da6a1a844806a F test/like2.test 3b2ee13149ba4a8a60b59756f4e5d345573852da F test/like3.test 3608a2042b6f922f900fbfd5d3ce4e7eca57f7c4 F test/limit.test 0c99a27a87b14c646a9d583c7c89fd06c352663e +F test/limit2.test 55c9f4d08c89311e00afd75045ee1a2aca205cb4 F test/loadext.test 42a3b8166dfcadcb0e0c8710dc520d97c31a8b98 F test/loadext2.test 0408380b57adca04004247179837a18e866a74f7 F test/lock.test be4fe08118fb988fed741f429b7dd5d65e1c90db @@ -1489,7 +1490,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 852d1eda6ecca1171f6ed800b06f5b4854672002 -R 664cd7ecddde2637b78c890f65cd5e15 +P 990fe50c9182f74c9b54a12602c4c30d891273e6 +R b3508f6593a9fbd22c3973de159c4a41 U drh -Z a9319f97e8df1737542ca3813ad100bc +Z 1bcf9218783f46102cc72fd7dcd4a1fb diff --git a/manifest.uuid b/manifest.uuid index 2ec1166f5a..277784dcaf 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -990fe50c9182f74c9b54a12602c4c30d891273e6 \ No newline at end of file +08849eab0f6ef29eaf6d2ce9c692de9b953dbd27 \ No newline at end of file diff --git a/test/limit2.test b/test/limit2.test new file mode 100644 index 0000000000..f415f3263b --- /dev/null +++ b/test/limit2.test @@ -0,0 +1,82 @@ +# 2016-05-20 +# +# 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 regression tests for SQLite library. The +# focus of this file is testing the LIMIT in combination with ORDER BY +# and in particular, the optimizations in the inner loop that cause an +# early exit of the inner loop when the LIMIT is reached and the inner +# loop is emitting rows in ORDER BY order. + + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +do_execsql_test limit2-100 { + CREATE TABLE t1(a,b); + WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<1000) + INSERT INTO t1(a,b) SELECT 1, (x*17)%1000 + 1000 FROM c; + INSERT INTO t1(a,b) VALUES(2,2),(3,1006),(4,4),(5,9999); + CREATE INDEX t1ab ON t1(a,b); +} +set sqlite_search_count 0 +do_execsql_test limit2-100.1 { + SELECT a, b, '|' FROM t1 WHERE a IN (2,4,5,3,1) ORDER BY b LIMIT 5; +} {2 2 | 4 4 | 1 1000 | 1 1001 | 1 1002 |} +set fast_count $sqlite_search_count +set sqlite_search_count 0 +do_execsql_test limit2-100.2 { + SELECT a, b, '|' FROM t1 WHERE a IN (2,4,5,3,1) ORDER BY +b LIMIT 5; +} {2 2 | 4 4 | 1 1000 | 1 1001 | 1 1002 |} +do_test limit2-100.3 { + set slow_count $sqlite_search_count + expr {$fast_count < 0.02*$slow_count} +} {1} + +do_execsql_test limit2-110 { + CREATE TABLE t2(x,y); + INSERT INTO t2(x,y) VALUES('a',1),('a',2),('a',3),('a',4); + INSERT INTO t2(x,y) VALUES('b',1),('c',2),('d',3),('e',4); + CREATE INDEX t2xy ON t2(x,y); +} +set sqlite_search_count 0 +do_execsql_test limit2-110.1 { + SELECT a, b, '|' FROM t2, t1 WHERE t2.x='a' AND t1.a=t2.y ORDER BY t1.b LIMIT 5; +} {2 2 | 4 4 | 1 1000 | 1 1001 | 1 1002 |} +set fast_count $sqlite_search_count +set sqlite_search_count 0 +do_execsql_test limit2-110.2 { + SELECT a, b, '|' FROM t2, t1 WHERE t2.x='a' AND t1.a=t2.y ORDER BY +t1.b LIMIT 5; +} {2 2 | 4 4 | 1 1000 | 1 1001 | 1 1002 |} +set slow_count $sqlite_search_count +do_test limit2-110.3 { + expr {$fast_count < 0.02*$slow_count} +} {1} + +do_execsql_test limit2-120 { + DROP INDEX t1ab; + CREATE INDEX t1ab ON t1(a,b DESC); +} +set sqlite_search_count 0 +do_execsql_test limit2-120.1 { + SELECT a, b, '|' FROM t1 WHERE a IN (2,4,5,3,1) ORDER BY b DESC LIMIT 5; +} {5 9999 | 1 1999 | 1 1998 | 1 1997 | 1 1996 |} +set fast_count $sqlite_search_count +set sqlite_search_count 0 +do_execsql_test limit2-120.2 { + SELECT a, b, '|' FROM t1 WHERE a IN (2,4,5,3,1) ORDER BY +b DESC LIMIT 5; +} {5 9999 | 1 1999 | 1 1998 | 1 1997 | 1 1996 |} +do_test limit2-120.3 { + set slow_count $sqlite_search_count + expr {$fast_count < 0.02*$slow_count} +} {1} + + + +finish_test From 17e0c4736839a3f9db7832ad8d997c89444a60ff Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 20 May 2016 12:22:16 +0000 Subject: [PATCH 0437/1484] Autoconf configure.ac adjustment to try to get it to look for both editline and readline automatically. FossilOrigin-Name: 645bd696dfd86d8c93080f6ebfddbc9639ec088b --- autoconf/configure.ac | 5 +++-- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/autoconf/configure.ac b/autoconf/configure.ac index 6b37a0517a..01f8b0d03d 100644 --- a/autoconf/configure.ac +++ b/autoconf/configure.ac @@ -41,14 +41,15 @@ AC_ARG_ENABLE(editline, [AS_HELP_STRING( AC_ARG_ENABLE(readline, [AS_HELP_STRING( [--enable-readline], [use readline])], - [], [enable_readline=no]) + [], [enable_readline=yes]) if test x"$enable_editline" != xno ; then sLIBS=$LIBS LIBS="" AC_SEARCH_LIBS([readline],[edit],[enable_readline=no],[enable_editline=no]) READLINE_LIBS=$LIBS if test x"$LIBS" != "x"; then - AC_DEFINE([HAVE_EDITLINE],1,Define to use BSD editline) + AC_DEFINE([HAVE_EDITLINE],1,Define to use BSD editline) + enable_readline=no else unset ac_cv_search_readline fi diff --git a/manifest b/manifest index 89053f9deb..21af3597e4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fixup\scomments\son\swctrlFlags\svalue\sdefinitions. -D 2016-05-19T19:31:30.127 +C Autoconf\sconfigure.ac\sadjustment\sto\stry\sto\sget\sit\sto\slook\sfor\sboth\seditline\nand\sreadline\sautomatically. +D 2016-05-20T12:22:16.170 F Makefile.in f59e0763ff448719fc1bd25513882b0567286317 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7 @@ -14,7 +14,7 @@ F autoconf/Makefile.am 1a47d071e3d5435f8f7ebff7eb6703848bbd65d4 F autoconf/Makefile.msc 0eca137c12542bd76c253a2d24380f29ade59b95 F autoconf/README.first 6c4f34fe115ff55d4e8dbfa3cecf04a0188292f7 F autoconf/README.txt 4f04b0819303aabaa35fff5f7b257fb0c1ef95f1 -F autoconf/configure.ac ad7001cdde3d6ae6053bc0b66009869d7c5012a8 +F autoconf/configure.ac 7754404e955900cfdeba08862cdfa802eca5b0af F autoconf/tea/Makefile.in b438a7020446c8a8156e8d97c8914a04833da6fd F autoconf/tea/README 3e9a3c060f29a44344ab50aec506f4db903fb873 F autoconf/tea/aclocal.m4 52c47aac44ce0ddb1f918b6993e8beb8eee88f43 @@ -1489,7 +1489,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d01305841da94b2d47e32744802f69525bf590df -R be830660ecf90ba00189952af638cb97 +P 58b516e8c0b00a41bc0364eab267bc2ecb9efeff +R 1ccdb41fa76e9f52d7032b7d9c7cb950 U drh -Z 54bddff0ee366139e2fb13081e6cf75a +Z 54717b5e62279adb2d1cf6e8a28ff9fe diff --git a/manifest.uuid b/manifest.uuid index 177ef2d35a..d3cfa1aab3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -58b516e8c0b00a41bc0364eab267bc2ecb9efeff \ No newline at end of file +645bd696dfd86d8c93080f6ebfddbc9639ec088b \ No newline at end of file From 6326d9f6f14620a10b4254febcd5ae53f181e8f5 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 20 May 2016 13:44:58 +0000 Subject: [PATCH 0438/1484] Set the NULLEQ flag on the sequence counter comparison in the ORDER BY LIMIT optimization, to avoid coverage complaints about not testing the NULL case. FossilOrigin-Name: ed1b30dc932a7c03e173b130c5f55f9989c7e0b4 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/select.c | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 3f35f82e00..7eaabf0f13 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C A\sfew\ssimple\stest\scases\sfor\sthe\sORDER\sBY\sLIMIT\soptimization. -D 2016-05-20T00:21:42.961 +C Set\sthe\sNULLEQ\sflag\son\sthe\ssequence\scounter\scomparison\sin\sthe\sORDER\sBY\sLIMIT\noptimization,\sto\savoid\scoverage\scomplaints\sabout\snot\stesting\sthe\sNULL\scase. +D 2016-05-20T13:44:58.389 F Makefile.in f59e0763ff448719fc1bd25513882b0567286317 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7 @@ -378,7 +378,7 @@ F src/printf.c a5f0ca08ddede803c241266abb46356ec748ded1 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c cca3aa77b95706df5d635a2141a4d1de60ae6598 F src/rowset.c 49eb91c588a2bab36647368e031dc5b66928149d -F src/select.c 131eeddfcaf3777c4acd4727bf742b98af8183b5 +F src/select.c a0c4abf54bc6bd3a9c77a36ef3d1676045706cb2 F src/shell.c 14ff7f660530a52b117d110ba3390b7b2eb719b6 F src/sqlite.h.in 9984129d86243424b765fcb3f147c697bd20bb54 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1490,7 +1490,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 990fe50c9182f74c9b54a12602c4c30d891273e6 -R b3508f6593a9fbd22c3973de159c4a41 +P 08849eab0f6ef29eaf6d2ce9c692de9b953dbd27 +R 8c75a4632edf1c4d959356bd614336cd U drh -Z 1bcf9218783f46102cc72fd7dcd4a1fb +Z 54e2cd90f1a7f48806580b84bc51f48b diff --git a/manifest.uuid b/manifest.uuid index 277784dcaf..65694bee6c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -08849eab0f6ef29eaf6d2ce9c692de9b953dbd27 \ No newline at end of file +ed1b30dc932a7c03e173b130c5f55f9989c7e0b4 \ No newline at end of file diff --git a/src/select.c b/src/select.c index 080ccf3480..495d47e20b 100644 --- a/src/select.c +++ b/src/select.c @@ -611,6 +611,7 @@ static void pushOntoSorter( ** LIMIT+OFFSET entries of the sorter. */ int iBrk = sqlite3VdbeCurrentAddr(v) + 2; sqlite3VdbeAddOp3(v, OP_Eq, regBase+nExpr, iBrk, r1); + sqlite3VdbeChangeP5(v, SQLITE_NULLEQ); VdbeCoverage(v); } sqlite3VdbeJumpHere(v, addr); From b982bfea377ca0dd015022d942d768b7603b5e27 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 20 May 2016 14:54:54 +0000 Subject: [PATCH 0439/1484] Optimizations to link list merge sort code in vdbesort.c, pcache.c, and rowset.c. Resulting binaries are 10 bytes smaller and use 0.03% fewer CPU cycles. FossilOrigin-Name: 9033afbb31b28a8ad6856ac1f773d8e83bc9ec1c --- manifest | 17 ++++++++--------- manifest.uuid | 2 +- src/pcache.c | 21 ++++++++++++--------- src/rowset.c | 37 ++++++++++++++++++------------------- src/vdbesort.c | 25 ++++++++++++++++--------- 5 files changed, 55 insertions(+), 47 deletions(-) diff --git a/manifest b/manifest index 018cac9cb3..d2da250b48 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C For\squeries\swith\sboth\sORDER\sBY\sand\sLIMIT,\sif\sthe\srows\sof\sthe\sinner\sloop\sare\nemitted\sin\sORDER\sBY\sorder\sand\sthe\sLIMIT\shas\sbeen\sreached,\sthen\soptimize\sby\nexiting\sthe\sinner\sloop\sand\scontinuing\swith\sthe\snext\scycle\sof\sthe\sfirst\souter\nloop. -D 2016-05-20T14:11:37.786 +C Optimizations\sto\slink\slist\smerge\ssort\scode\sin\svdbesort.c,\spcache.c,\sand\nrowset.c.\s\sResulting\sbinaries\sare\s10\sbytes\ssmaller\sand\suse\s0.03%\sfewer\sCPU\ncycles. +D 2016-05-20T14:54:54.663 F Makefile.in f59e0763ff448719fc1bd25513882b0567286317 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7 @@ -368,7 +368,7 @@ F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c 3910579bfbe323dfabed2b95d201159b61b8ef42 F src/pager.h 329bdf078a4e0a3b35084534d58625d21fd03681 F src/parse.y 10eb2f3fb62341291528c7984498054731f9d31e -F src/pcache.c f398c0084399e7481482cbc6a578a3cc4c3675f3 +F src/pcache.c 50fb5728dbfb92461f89f8763ff8b60d0dbeba2c F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 F src/pcache1.c 7f51d2b541aab57596adf62db2c4bb025d34f04d F src/pragma.c faf42922bb7ab2f6672cb550356c1967abae3c84 @@ -377,7 +377,7 @@ F src/prepare.c 22df6171aec1d86904ed2ad30c2348a5748aa04e F src/printf.c a5f0ca08ddede803c241266abb46356ec748ded1 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c cca3aa77b95706df5d635a2141a4d1de60ae6598 -F src/rowset.c 49eb91c588a2bab36647368e031dc5b66928149d +F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c a0c4abf54bc6bd3a9c77a36ef3d1676045706cb2 F src/shell.c 14ff7f660530a52b117d110ba3390b7b2eb719b6 F src/sqlite.h.in 9984129d86243424b765fcb3f147c697bd20bb54 @@ -451,7 +451,7 @@ F src/vdbeapi.c ba85b78fe08dc4a9ce747e62c89a2b4a4547e74c F src/vdbeaux.c ace1875da40b7185e604586768d5ac90de7e4f7f F src/vdbeblob.c c9f2f494b911c6fa34efd9803f0a10807da80f77 F src/vdbemem.c 5cfef60e60e19cab6275d1b975bf4c791d575beb -F src/vdbesort.c 0a8f98366ae794442e6d1ef71d9553226d885d19 +F src/vdbesort.c 91fda3909326860382b0ca8aa251e609c6a9d62c F src/vdbetrace.c f75c5455d8cf389ef86a8bfdfd3177e0e3692484 F src/vtab.c 23b6cdfa996152d43b390504ed4a942c8caf3a00 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 @@ -1490,8 +1490,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 645bd696dfd86d8c93080f6ebfddbc9639ec088b ed1b30dc932a7c03e173b130c5f55f9989c7e0b4 -R b166646a4114a46c17faadb7ecf63948 -T +closed ed1b30dc932a7c03e173b130c5f55f9989c7e0b4 +P 559733b09e9630fac9d9318a7ecbaba9134e9160 +R db641f928488147ea4b353a0a8e4e73d U drh -Z aa696592564772ea00c367935ddfa343 +Z 8f08ede060795a413d5c246d730b7a0d diff --git a/manifest.uuid b/manifest.uuid index 048e943fec..9b60eaacba 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -559733b09e9630fac9d9318a7ecbaba9134e9160 \ No newline at end of file +9033afbb31b28a8ad6856ac1f773d8e83bc9ec1c \ No newline at end of file diff --git a/src/pcache.c b/src/pcache.c index d628320334..ad9fa4f46b 100644 --- a/src/pcache.c +++ b/src/pcache.c @@ -692,24 +692,26 @@ void sqlite3PcacheClear(PCache *pCache){ static PgHdr *pcacheMergeDirtyList(PgHdr *pA, PgHdr *pB){ PgHdr result, *pTail; pTail = &result; - while( pA && pB ){ + assert( pA!=0 && pB!=0 ); + for(;;){ if( pA->pgnopgno ){ pTail->pDirty = pA; pTail = pA; pA = pA->pDirty; + if( pA==0 ){ + pTail->pDirty = pB; + break; + } }else{ pTail->pDirty = pB; pTail = pB; pB = pB->pDirty; + if( pB==0 ){ + pTail->pDirty = pA; + break; + } } } - if( pA ){ - pTail->pDirty = pA; - }else if( pB ){ - pTail->pDirty = pB; - }else{ - pTail->pDirty = 0; - } return result.pDirty; } @@ -750,7 +752,8 @@ static PgHdr *pcacheSortDirtyList(PgHdr *pIn){ } p = a[0]; for(i=1; ipRight==0 || pA->v<=pA->pRight->v ); assert( pB->pRight==0 || pB->v<=pB->pRight->v ); - if( pA->vv ){ - pTail->pRight = pA; + if( pA->v<=pB->v ){ + if( pA->vv ) pTail = pTail->pRight = pA; pA = pA->pRight; - pTail = pTail->pRight; - }else if( pB->vv ){ - pTail->pRight = pB; - pB = pB->pRight; - pTail = pTail->pRight; + if( pA==0 ){ + pTail->pRight = pB; + break; + } }else{ - pA = pA->pRight; + pTail = pTail->pRight = pB; + pB = pB->pRight; + if( pB==0 ){ + pTail->pRight = pA; + break; + } } } - if( pA ){ - assert( pA->pRight==0 || pA->v<=pA->pRight->v ); - pTail->pRight = pA; - }else{ - assert( pB==0 || pB->pRight==0 || pB->v<=pB->pRight->v ); - pTail->pRight = pB; - } return head.pRight; } @@ -286,9 +284,10 @@ static struct RowSetEntry *rowSetEntrySort(struct RowSetEntry *pIn){ aBucket[i] = pIn; pIn = pNext; } - pIn = 0; - for(i=0; ixCompare( pTask, &bCached, SRVAL(p1), p1->nVal, SRVAL(p2), p2->nVal @@ -1364,15 +1363,22 @@ static void vdbeSorterMerge( *pp = p1; pp = &p1->u.pNext; p1 = p1->u.pNext; + if( p1==0 ){ + *pp = p2; + break; + } }else{ *pp = p2; pp = &p2->u.pNext; p2 = p2->u.pNext; bCached = 0; + if( p2==0 ){ + *pp = p1; + break; + } } } - *pp = p1 ? p1 : p2; - *ppOut = pFinal; + return pFinal; } /* @@ -1425,7 +1431,7 @@ static int vdbeSorterSort(SortSubtask *pTask, SorterList *pList){ p->u.pNext = 0; for(i=0; aSlot[i]; i++){ - vdbeSorterMerge(pTask, p, aSlot[i], &p); + p = vdbeSorterMerge(pTask, p, aSlot[i]); aSlot[i] = 0; } aSlot[i] = p; @@ -1434,7 +1440,8 @@ static int vdbeSorterSort(SortSubtask *pTask, SorterList *pList){ p = 0; for(i=0; i<64; i++){ - vdbeSorterMerge(pTask, p, aSlot[i], &p); + if( aSlot[i]==0 ) continue; + p = p ? vdbeSorterMerge(pTask, p, aSlot[i]) : aSlot[i]; } pList->pList = p; From 01c736db40121708554723c753e8cb46db569908 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 20 May 2016 15:15:07 +0000 Subject: [PATCH 0440/1484] Use sqlite3VdbeAddOp0() to code OP_Expire, to save a few bytes. FossilOrigin-Name: 3d55d24dcb27f07d1e645738ee4707e4df923036 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/build.c | 2 +- src/pragma.c | 2 +- src/vtab.c | 2 +- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index d2da250b48..b57bbea74a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Optimizations\sto\slink\slist\smerge\ssort\scode\sin\svdbesort.c,\spcache.c,\sand\nrowset.c.\s\sResulting\sbinaries\sare\s10\sbytes\ssmaller\sand\suse\s0.03%\sfewer\sCPU\ncycles. -D 2016-05-20T14:54:54.663 +C Use\ssqlite3VdbeAddOp0()\sto\scode\sOP_Expire,\sto\ssave\sa\sfew\sbytes. +D 2016-05-20T15:15:07.708 F Makefile.in f59e0763ff448719fc1bd25513882b0567286317 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7 @@ -325,7 +325,7 @@ F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 F src/btree.c e53a01547d61a3d567daf7a7acc30122fe071aef F src/btree.h a5008b9afe56e8e54ade6c436a910f112defcca9 F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 -F src/build.c d65be62254ca9df36e1e1c433324f0333f80009c +F src/build.c 785fa789319d93c6ae20efbd01d4da9ce8f8a793 F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 60e135af364d777a9ab41c97e5e89cd224da6198 @@ -371,7 +371,7 @@ F src/parse.y 10eb2f3fb62341291528c7984498054731f9d31e F src/pcache.c 50fb5728dbfb92461f89f8763ff8b60d0dbeba2c F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 F src/pcache1.c 7f51d2b541aab57596adf62db2c4bb025d34f04d -F src/pragma.c faf42922bb7ab2f6672cb550356c1967abae3c84 +F src/pragma.c 9fdce031ddcb57f0f56e4a8b421b7e7a77de73b0 F src/pragma.h 64c78a648751b9f4f297276c4eb7507b14b4628c F src/prepare.c 22df6171aec1d86904ed2ad30c2348a5748aa04e F src/printf.c a5f0ca08ddede803c241266abb46356ec748ded1 @@ -453,7 +453,7 @@ F src/vdbeblob.c c9f2f494b911c6fa34efd9803f0a10807da80f77 F src/vdbemem.c 5cfef60e60e19cab6275d1b975bf4c791d575beb F src/vdbesort.c 91fda3909326860382b0ca8aa251e609c6a9d62c F src/vdbetrace.c f75c5455d8cf389ef86a8bfdfd3177e0e3692484 -F src/vtab.c 23b6cdfa996152d43b390504ed4a942c8caf3a00 +F src/vtab.c ce0f2ebb589b459b32c640b33af64bfa5b29aaf8 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 4db22ed7e77bcf672b1a685d6ddeffba8d5be302 F src/wal.h 2f7c831cf3b071fa548bf2d5cac640846a7ff19c @@ -1490,7 +1490,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 559733b09e9630fac9d9318a7ecbaba9134e9160 -R db641f928488147ea4b353a0a8e4e73d +P 9033afbb31b28a8ad6856ac1f773d8e83bc9ec1c +R 1cd6e2cbb63bca846e6fd848dfba7f80 U drh -Z 8f08ede060795a413d5c246d730b7a0d +Z cefb033da9b34db496e79185da92ee9c diff --git a/manifest.uuid b/manifest.uuid index 9b60eaacba..8722763d5a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9033afbb31b28a8ad6856ac1f773d8e83bc9ec1c \ No newline at end of file +3d55d24dcb27f07d1e645738ee4707e4df923036 \ No newline at end of file diff --git a/src/build.c b/src/build.c index 2fa4e3102f..565101356a 100644 --- a/src/build.c +++ b/src/build.c @@ -3365,7 +3365,7 @@ Index *sqlite3CreateIndex( sqlite3ChangeCookie(pParse, iDb); sqlite3VdbeAddParseSchemaOp(v, iDb, sqlite3MPrintf(db, "name='%q' AND type='index'", pIndex->zName)); - sqlite3VdbeAddOp1(v, OP_Expire, 0); + sqlite3VdbeAddOp0(v, OP_Expire); } sqlite3VdbeJumpHere(v, pIndex->tnum); diff --git a/src/pragma.c b/src/pragma.c index e0a0255ec0..330e999090 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -1030,7 +1030,7 @@ void sqlite3Pragma( ** compiler (eg. count_changes). So add an opcode to expire all ** compiled SQL statements after modifying a pragma value. */ - sqlite3VdbeAddOp2(v, OP_Expire, 0, 0); + sqlite3VdbeAddOp0(v, OP_Expire); setAllPagerFlags(db); } break; diff --git a/src/vtab.c b/src/vtab.c index 802a8cac3a..2fe105a296 100644 --- a/src/vtab.c +++ b/src/vtab.c @@ -418,7 +418,7 @@ void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){ v = sqlite3GetVdbe(pParse); sqlite3ChangeCookie(pParse, iDb); - sqlite3VdbeAddOp2(v, OP_Expire, 0, 0); + sqlite3VdbeAddOp0(v, OP_Expire); zWhere = sqlite3MPrintf(db, "name='%q' AND type='table'", pTab->zName); sqlite3VdbeAddParseSchemaOp(v, iDb, zWhere); From c0a195b88578326a7e20b981b9f368357fce55c0 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 20 May 2016 15:24:14 +0000 Subject: [PATCH 0441/1484] Increase the version number to 3.14.0 since we are already making significant code changes. FossilOrigin-Name: 1a0d05765fa2e69ccd4c98782cf9f5c5b2897719 --- VERSION | 2 +- configure | 18 +++++++++--------- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/VERSION b/VERSION index 4eba2a62eb..f982feb41b 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.13.0 +3.14.0 diff --git a/configure b/configure index 3b746fedbb..22a646c2b6 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.13.0. +# Generated by GNU Autoconf 2.69 for sqlite 3.14.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.13.0' -PACKAGE_STRING='sqlite 3.13.0' +PACKAGE_VERSION='3.14.0' +PACKAGE_STRING='sqlite 3.14.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1461,7 +1461,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.13.0 to adapt to many kinds of systems. +\`configure' configures sqlite 3.14.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1526,7 +1526,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of sqlite 3.13.0:";; + short | recursive ) echo "Configuration of sqlite 3.14.0:";; esac cat <<\_ACEOF @@ -1648,7 +1648,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -sqlite configure 3.13.0 +sqlite configure 3.14.0 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2067,7 +2067,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.13.0, which was +It was created by sqlite $as_me 3.14.0, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -12095,7 +12095,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.13.0, which was +This file was extended by sqlite $as_me 3.14.0, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -12161,7 +12161,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.13.0 +sqlite config.status 3.14.0 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/manifest b/manifest index b57bbea74a..6ef842be89 100644 --- a/manifest +++ b/manifest @@ -1,10 +1,10 @@ -C Use\ssqlite3VdbeAddOp0()\sto\scode\sOP_Expire,\sto\ssave\sa\sfew\sbytes. -D 2016-05-20T15:15:07.708 +C Increase\sthe\sversion\snumber\sto\s3.14.0\ssince\swe\sare\salready\smaking\ssignificant\ncode\schanges. +D 2016-05-20T15:24:14.463 F Makefile.in f59e0763ff448719fc1bd25513882b0567286317 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7 F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7 -F VERSION 5d234da9b5dae329fab75ff75884cfe0a9cb3fda +F VERSION cb29eb11e493dd85b3eeec4053c03949bf98478e F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 @@ -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 df9f793ad47eaeb3648a9090fbc0b96955e88b5a x +F configure 96fdf3870e30c6f60c6a56d27f5f6e4159b9bdc6 x F configure.ac 02b972db825685b4b0cca0234b2aa97f71bd15a5 F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad F doc/lemon.html e2118945e5f07ed146b45c9cd2b2dd6eabb8ebf2 @@ -1490,7 +1490,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 9033afbb31b28a8ad6856ac1f773d8e83bc9ec1c -R 1cd6e2cbb63bca846e6fd848dfba7f80 +P 3d55d24dcb27f07d1e645738ee4707e4df923036 +R 89664580415a847eedcfc718be56bf0d U drh -Z cefb033da9b34db496e79185da92ee9c +Z 8bf855953d20db149698d180b3489eaf diff --git a/manifest.uuid b/manifest.uuid index 8722763d5a..1aa0fd4a5f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3d55d24dcb27f07d1e645738ee4707e4df923036 \ No newline at end of file +1a0d05765fa2e69ccd4c98782cf9f5c5b2897719 \ No newline at end of file From f431a87c7cb50114aad67b893811ce122dabc88e Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 20 May 2016 15:53:47 +0000 Subject: [PATCH 0442/1484] Performance optimization and size reduction on the freeP4() routine. FossilOrigin-Name: 4dc56e8684e0c74fb311c7f0ef1c367da8c7bf70 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbeaux.c | 18 ++++++++++++------ 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 6ef842be89..72e47730ac 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Increase\sthe\sversion\snumber\sto\s3.14.0\ssince\swe\sare\salready\smaking\ssignificant\ncode\schanges. -D 2016-05-20T15:24:14.463 +C Performance\soptimization\sand\ssize\sreduction\son\sthe\sfreeP4()\sroutine. +D 2016-05-20T15:53:47.755 F Makefile.in f59e0763ff448719fc1bd25513882b0567286317 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7 @@ -448,7 +448,7 @@ F src/vdbe.c d71b935d2b21bef874680c34329adedc3b021101 F src/vdbe.h 5591b5add447096e31288b5a0a78ec5d7b5c5170 F src/vdbeInt.h ddb157974436d87652de7dc641f7191496d9a8cd F src/vdbeapi.c ba85b78fe08dc4a9ce747e62c89a2b4a4547e74c -F src/vdbeaux.c ace1875da40b7185e604586768d5ac90de7e4f7f +F src/vdbeaux.c 1d6b9a979d1036db7bc39990e9e683f19520bc5c F src/vdbeblob.c c9f2f494b911c6fa34efd9803f0a10807da80f77 F src/vdbemem.c 5cfef60e60e19cab6275d1b975bf4c791d575beb F src/vdbesort.c 91fda3909326860382b0ca8aa251e609c6a9d62c @@ -1490,7 +1490,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 3d55d24dcb27f07d1e645738ee4707e4df923036 -R 89664580415a847eedcfc718be56bf0d +P 1a0d05765fa2e69ccd4c98782cf9f5c5b2897719 +R 734aa09fb2d1f30b69a973bc3d2e2b77 U drh -Z 8bf855953d20db149698d180b3489eaf +Z d36b58bb8581f51b9b8f33e10b0489c2 diff --git a/manifest.uuid b/manifest.uuid index 1aa0fd4a5f..da9f09cbad 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1a0d05765fa2e69ccd4c98782cf9f5c5b2897719 \ No newline at end of file +4dc56e8684e0c74fb311c7f0ef1c367da8c7bf70 \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 0f9dab8e19..bce676f10c 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -791,7 +791,7 @@ void sqlite3VdbeJumpHere(Vdbe *p, int addr){ ** the FuncDef is not ephermal, then do nothing. */ static void freeEphemeralFunction(sqlite3 *db, FuncDef *pDef){ - if( ALWAYS(pDef) && (pDef->funcFlags & SQLITE_FUNC_EPHEM)!=0 ){ + if( (pDef->funcFlags & SQLITE_FUNC_EPHEM)!=0 ){ sqlite3DbFree(db, pDef); } } @@ -801,12 +801,20 @@ static void vdbeFreeOpArray(sqlite3 *, Op *, int); /* ** Delete a P4 value if necessary. */ +static SQLITE_NOINLINE void freeP4Mem(sqlite3 *db, Mem *p){ + if( p->szMalloc ) sqlite3DbFree(db, p->zMalloc); + sqlite3DbFree(db, p); +} +static SQLITE_NOINLINE void freeP4FuncCtx(sqlite3 *db, sqlite3_context *p){ + freeEphemeralFunction(db, p->pFunc); + sqlite3DbFree(db, p); +} static void freeP4(sqlite3 *db, int p4type, void *p4){ assert( db ); switch( p4type ){ case P4_FUNCCTX: { - freeEphemeralFunction(db, ((sqlite3_context*)p4)->pFunc); - /* Fall through into the next case */ + freeP4FuncCtx(db, (sqlite3_context*)p4); + break; } case P4_REAL: case P4_INT64: @@ -837,9 +845,7 @@ static void freeP4(sqlite3 *db, int p4type, void *p4){ if( db->pnBytesFreed==0 ){ sqlite3ValueFree((sqlite3_value*)p4); }else{ - Mem *p = (Mem*)p4; - if( p->szMalloc ) sqlite3DbFree(db, p->zMalloc); - sqlite3DbFree(db, p); + freeP4Mem(db, (Mem*)p4); } break; } From d20b2a41094ff53858415ad788a09ebfedad01ff Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 20 May 2016 18:09:01 +0000 Subject: [PATCH 0443/1484] Remove the sqlite3PagerClearCache() routine, which does not accomplish anything useful. FossilOrigin-Name: f250166bb3c1b0c58e703b334825cf6210758fda --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/backup.c | 2 -- src/pager.c | 10 ---------- src/pager.h | 1 - 5 files changed, 9 insertions(+), 22 deletions(-) diff --git a/manifest b/manifest index 72e47730ac..264470f9ab 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Performance\soptimization\sand\ssize\sreduction\son\sthe\sfreeP4()\sroutine. -D 2016-05-20T15:53:47.755 +C Remove\sthe\ssqlite3PagerClearCache()\sroutine,\swhich\sdoes\snot\saccomplish\sanything\nuseful. +D 2016-05-20T18:09:01.269 F Makefile.in f59e0763ff448719fc1bd25513882b0567286317 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7 @@ -319,7 +319,7 @@ F src/alter.c 1bb0709b3048e24217b80ec6bd78a3e99a47c01b F src/analyze.c 37fedc80ac966ce1745811746e68e4d8fa64c7fe F src/attach.c 771153bd1f4ab0b97a44a13dde2c7e5e1efeba22 F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240 -F src/backup.c f60f0aa55d25d853ffde53d0b0370a7bb7ee41ce +F src/backup.c 6df65fdd569c901a418887a1a76f82ec35044556 F src/bitvec.c 3ee4c8b2c94ed3a7377256e18199e6ff5cf33f63 F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 F src/btree.c e53a01547d61a3d567daf7a7acc30122fe071aef @@ -365,8 +365,8 @@ F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa F src/os_unix.c a9443cdab41d7f3cdf0df3a5aab62fd6e1c9b234 F src/os_win.c 852fc2ff6084296348ed3739c548b2cf32df394e F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca -F src/pager.c 3910579bfbe323dfabed2b95d201159b61b8ef42 -F src/pager.h 329bdf078a4e0a3b35084534d58625d21fd03681 +F src/pager.c c368634b888b1c8740aea83b36bfd266f2443e60 +F src/pager.h 8ab6b6feeee4bc0439bfde7ee59ba99df98b9bc3 F src/parse.y 10eb2f3fb62341291528c7984498054731f9d31e F src/pcache.c 50fb5728dbfb92461f89f8763ff8b60d0dbeba2c F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 @@ -1490,7 +1490,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 1a0d05765fa2e69ccd4c98782cf9f5c5b2897719 -R 734aa09fb2d1f30b69a973bc3d2e2b77 +P 4dc56e8684e0c74fb311c7f0ef1c367da8c7bf70 +R f1ca77b965b4fac61acdc31594820a52 U drh -Z d36b58bb8581f51b9b8f33e10b0489c2 +Z c5c16d4ca102bc8075809f03a41e82f3 diff --git a/manifest.uuid b/manifest.uuid index da9f09cbad..e1934ce2a2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4dc56e8684e0c74fb311c7f0ef1c367da8c7bf70 \ No newline at end of file +f250166bb3c1b0c58e703b334825cf6210758fda \ No newline at end of file diff --git a/src/backup.c b/src/backup.c index 455671a1ad..3df56e5384 100644 --- a/src/backup.c +++ b/src/backup.c @@ -784,8 +784,6 @@ int sqlite3BtreeCopyFile(Btree *pTo, Btree *pFrom){ rc = sqlite3_backup_finish(&b); if( rc==SQLITE_OK ){ pTo->pBt->btsFlags &= ~BTS_PAGESIZE_FIXED; - }else{ - sqlite3PagerClearCache(sqlite3BtreePager(b.pDest)); } assert( sqlite3BtreeIsInTrans(pTo)==0 ); diff --git a/src/pager.c b/src/pager.c index b24267e58a..1ae831d148 100644 --- a/src/pager.c +++ b/src/pager.c @@ -7157,16 +7157,6 @@ sqlite3_backup **sqlite3PagerBackupPtr(Pager *pPager){ return &pPager->pBackup; } -#ifndef SQLITE_OMIT_VACUUM -/* -** Unless this is an in-memory or temporary database, clear the pager cache. -*/ -void sqlite3PagerClearCache(Pager *pPager){ - assert( MEMDB==0 || pPager->tempFile ); - if( pPager->tempFile==0 ) pager_reset(pPager); -} -#endif - #ifndef SQLITE_OMIT_WAL /* ** This function is called when the user invokes "PRAGMA wal_checkpoint", diff --git a/src/pager.h b/src/pager.h index 077fcd8b7f..69d3bb4435 100644 --- a/src/pager.h +++ b/src/pager.h @@ -203,7 +203,6 @@ const char *sqlite3PagerJournalname(Pager*); void *sqlite3PagerTempSpace(Pager*); int sqlite3PagerIsMemdb(Pager*); void sqlite3PagerCacheStat(Pager *, int, int, int *); -void sqlite3PagerClearCache(Pager *); int sqlite3SectorSize(sqlite3_file *); /* Functions used to truncate the database file. */ From a1851efc5d4807178198ca9bbc344ae2a33ef495 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 20 May 2016 19:51:28 +0000 Subject: [PATCH 0444/1484] Slight performance improvement in the OP_Column opcode. FossilOrigin-Name: 5c157474391f90f24e8867c77fbc6564c7955ecc --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 7 +++++-- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 264470f9ab..9f9a5c97ad 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sthe\ssqlite3PagerClearCache()\sroutine,\swhich\sdoes\snot\saccomplish\sanything\nuseful. -D 2016-05-20T18:09:01.269 +C Slight\sperformance\simprovement\sin\sthe\sOP_Column\sopcode. +D 2016-05-20T19:51:28.931 F Makefile.in f59e0763ff448719fc1bd25513882b0567286317 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7 @@ -444,7 +444,7 @@ F src/update.c 4f05ea8cddfa367d045e03589756c02199e8f9bd F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 810ec3f22e2d1b62e66c30fe3621ebdedd23584d F src/vacuum.c feb1eabb20987983d9350cad98299b21fa811f52 -F src/vdbe.c d71b935d2b21bef874680c34329adedc3b021101 +F src/vdbe.c 9d0872c73555b335d7e658bb9b6fd69798ba551c F src/vdbe.h 5591b5add447096e31288b5a0a78ec5d7b5c5170 F src/vdbeInt.h ddb157974436d87652de7dc641f7191496d9a8cd F src/vdbeapi.c ba85b78fe08dc4a9ce747e62c89a2b4a4547e74c @@ -1490,7 +1490,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 4dc56e8684e0c74fb311c7f0ef1c367da8c7bf70 -R f1ca77b965b4fac61acdc31594820a52 +P f250166bb3c1b0c58e703b334825cf6210758fda +R 67f498d524675be2828322b33e8cc61d U drh -Z c5c16d4ca102bc8075809f03a41e82f3 +Z 6bf519f6e91709086e486df141738a73 diff --git a/manifest.uuid b/manifest.uuid index e1934ce2a2..5befa41016 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f250166bb3c1b0c58e703b334825cf6210758fda \ No newline at end of file +5c157474391f90f24e8867c77fbc6564c7955ecc \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 6d96f85548..9f36a3feb2 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2575,9 +2575,10 @@ case OP_Column: { assert( p2nHdrParsed ); assert( rc==SQLITE_OK ); assert( sqlite3VdbeCheckMemInvariants(pDest) ); - if( VdbeMemDynamic(pDest) ) sqlite3VdbeMemSetNull(pDest); + if( VdbeMemDynamic(pDest) ){ + sqlite3VdbeMemSetNull(pDest); + } assert( t==pC->aType[p2] ); - pDest->enc = encoding; if( pC->szRow>=aOffset[p2+1] ){ /* This is the common case where the desired content fits on the original ** page - where the content is not on an overflow page */ @@ -2591,6 +2592,7 @@ case OP_Column: { */ static const u16 aFlag[] = { MEM_Blob, MEM_Str|MEM_Term }; pDest->n = len = (t-12)/2; + pDest->enc = encoding; if( pDest->szMalloc < len+2 ){ pDest->flags = MEM_Null; if( sqlite3VdbeMemGrow(pDest, len+2, 0) ) goto no_mem; @@ -2603,6 +2605,7 @@ case OP_Column: { pDest->flags = aFlag[t&1]; } }else{ + pDest->enc = encoding; /* This branch happens only when content is on overflow pages */ if( ((pOp->p5 & (OPFLAG_LENGTHARG|OPFLAG_TYPEOFARG))!=0 && ((t>=12 && (t&1)==0) || (pOp->p5 & OPFLAG_TYPEOFARG)!=0)) From 2380f3f1d04e9dd1abf2c20517aba61b174e98bd Mon Sep 17 00:00:00 2001 From: mistachkin Date: Fri, 20 May 2016 20:58:30 +0000 Subject: [PATCH 0445/1484] Fix typo in comment. FossilOrigin-Name: 9db8f2147339ba519c4ec32e34068e9f4a25e099 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/pcache.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 9f9a5c97ad..59b91454b0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Slight\sperformance\simprovement\sin\sthe\sOP_Column\sopcode. -D 2016-05-20T19:51:28.931 +C Fix\stypo\sin\scomment. +D 2016-05-20T20:58:30.520 F Makefile.in f59e0763ff448719fc1bd25513882b0567286317 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7 @@ -368,7 +368,7 @@ F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c c368634b888b1c8740aea83b36bfd266f2443e60 F src/pager.h 8ab6b6feeee4bc0439bfde7ee59ba99df98b9bc3 F src/parse.y 10eb2f3fb62341291528c7984498054731f9d31e -F src/pcache.c 50fb5728dbfb92461f89f8763ff8b60d0dbeba2c +F src/pcache.c 5583c8ade4b05075a60ba953ef471d1c1a9c05df F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 F src/pcache1.c 7f51d2b541aab57596adf62db2c4bb025d34f04d F src/pragma.c 9fdce031ddcb57f0f56e4a8b421b7e7a77de73b0 @@ -1490,7 +1490,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P f250166bb3c1b0c58e703b334825cf6210758fda -R 67f498d524675be2828322b33e8cc61d -U drh -Z 6bf519f6e91709086e486df141738a73 +P 5c157474391f90f24e8867c77fbc6564c7955ecc +R 24d15d6cfb006c0761a9dcc11f99e304 +U mistachkin +Z 03dddc8d9c707d4b35ca07d5a2fcd8f4 diff --git a/manifest.uuid b/manifest.uuid index 5befa41016..7ce09e7144 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5c157474391f90f24e8867c77fbc6564c7955ecc \ No newline at end of file +9db8f2147339ba519c4ec32e34068e9f4a25e099 \ No newline at end of file diff --git a/src/pcache.c b/src/pcache.c index ad9fa4f46b..ccbcc96cd0 100644 --- a/src/pcache.c +++ b/src/pcache.c @@ -687,7 +687,7 @@ void sqlite3PcacheClear(PCache *pCache){ /* ** Merge two lists of pages connected by pDirty and in pgno order. -** Do not both fixing the pDirtyPrev pointers. +** Do not bother fixing the pDirtyPrev pointers. */ static PgHdr *pcacheMergeDirtyList(PgHdr *pA, PgHdr *pB){ PgHdr result, *pTail; From 170c27662386424490d8a73130b8c71c86a10a32 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 20 May 2016 21:40:11 +0000 Subject: [PATCH 0446/1484] Another optimization on the OP_Column opcode. FossilOrigin-Name: 1765672c2599eb03d39c52cd2dc32ea1e5ee069e --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/vdbe.c | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 59b91454b0..1cd3edacb4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\stypo\sin\scomment. -D 2016-05-20T20:58:30.520 +C Another\soptimization\son\sthe\sOP_Column\sopcode. +D 2016-05-20T21:40:11.890 F Makefile.in f59e0763ff448719fc1bd25513882b0567286317 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7 @@ -444,7 +444,7 @@ F src/update.c 4f05ea8cddfa367d045e03589756c02199e8f9bd F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 810ec3f22e2d1b62e66c30fe3621ebdedd23584d F src/vacuum.c feb1eabb20987983d9350cad98299b21fa811f52 -F src/vdbe.c 9d0872c73555b335d7e658bb9b6fd69798ba551c +F src/vdbe.c 975ac1d3d326bcb36b4e99255daeaf81ff6659d1 F src/vdbe.h 5591b5add447096e31288b5a0a78ec5d7b5c5170 F src/vdbeInt.h ddb157974436d87652de7dc641f7191496d9a8cd F src/vdbeapi.c ba85b78fe08dc4a9ce747e62c89a2b4a4547e74c @@ -1490,7 +1490,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 5c157474391f90f24e8867c77fbc6564c7955ecc -R 24d15d6cfb006c0761a9dcc11f99e304 -U mistachkin -Z 03dddc8d9c707d4b35ca07d5a2fcd8f4 +P 9db8f2147339ba519c4ec32e34068e9f4a25e099 +R b59019073443c960ff19359461f0425d +U drh +Z be39c49e0fa0986f111ad70cd504ec49 diff --git a/manifest.uuid b/manifest.uuid index 7ce09e7144..f85b5caaae 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9db8f2147339ba519c4ec32e34068e9f4a25e099 \ No newline at end of file +1765672c2599eb03d39c52cd2dc32ea1e5ee069e \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 9f36a3feb2..36c014a7d0 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2531,9 +2531,7 @@ case OP_Column: { pC->aType[i++] = t; aOffset[i] = (u32)(offset64 & 0xffffffff); }while( i<=p2 && zHdrnHdrParsed = i; - pC->iHdrOffset = (u32)(zHdr - zData); - + /* The record is corrupt if any of the following are true: ** (1) the bytes of the header extend past the declared header size ** (2) the entire header was used but not all data was used @@ -2546,8 +2544,10 @@ case OP_Column: { rc = SQLITE_CORRUPT_BKPT; goto abort_due_to_error; } - if( pC->aRow==0 ) sqlite3VdbeMemRelease(&sMem); + pC->nHdrParsed = i; + pC->iHdrOffset = (u32)(zHdr - zData); + if( pC->aRow==0 ) sqlite3VdbeMemRelease(&sMem); }else{ t = 0; } From 860a95fd017588038a35e105b185f1f6654b79d5 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 20 May 2016 23:51:14 +0000 Subject: [PATCH 0447/1484] Add a simple TCL script for summing cachegrind information for each VDBE opcdoe. FossilOrigin-Name: 96cf821b6a69e2e8df33271b7bb674bd12a1ef7b --- manifest | 11 ++++++----- manifest.uuid | 2 +- tool/opcodesum.tcl | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 41 insertions(+), 6 deletions(-) create mode 100644 tool/opcodesum.tcl diff --git a/manifest b/manifest index 1cd3edacb4..d563744dae 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Another\soptimization\son\sthe\sOP_Column\sopcode. -D 2016-05-20T21:40:11.890 +C Add\sa\ssimple\sTCL\sscript\sfor\ssumming\scachegrind\sinformation\sfor\seach\sVDBE\nopcdoe. +D 2016-05-20T23:51:14.900 F Makefile.in f59e0763ff448719fc1bd25513882b0567286317 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7 @@ -1439,6 +1439,7 @@ F tool/mksqlite3internalh.tcl eb994013e833359137eb53a55acdad0b5ae1049b F tool/mkvsix.tcl 4abcaf3267171b2faadaf9b82a0dfbaa6e98f8b7 F tool/offsets.c fe4262fdfa378e8f5499a42136d17bf3b98f6091 F tool/omittest.tcl 34d7ac01fe4fd18e3637f64abe12c40eca0f6b97 +F tool/opcodesum.tcl 740ed206ba8c5040018988129abbf3089a0ccf4a F tool/pagesig.c ff0ca355fd3c2398e933da5e22439bbff89b803b F tool/replace.tcl 7727c60a04299b65a92f5e1590896fea0f25b9e0 F tool/restore_jrnl.tcl 6957a34f8f1f0f8285e07536225ec3b292a9024a @@ -1490,7 +1491,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 9db8f2147339ba519c4ec32e34068e9f4a25e099 -R b59019073443c960ff19359461f0425d +P 1765672c2599eb03d39c52cd2dc32ea1e5ee069e +R 247c58a1e4c62949bc3249c61dcdd977 U drh -Z be39c49e0fa0986f111ad70cd504ec49 +Z 3e7f8cdf9cdb094239005245e5b11ebd diff --git a/manifest.uuid b/manifest.uuid index f85b5caaae..1f418b0d95 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1765672c2599eb03d39c52cd2dc32ea1e5ee069e \ No newline at end of file +96cf821b6a69e2e8df33271b7bb674bd12a1ef7b \ No newline at end of file diff --git a/tool/opcodesum.tcl b/tool/opcodesum.tcl new file mode 100644 index 0000000000..47dff32b90 --- /dev/null +++ b/tool/opcodesum.tcl @@ -0,0 +1,34 @@ +#!/usr/bin/tclsh +# +# Run this script, redirecting input from cachegrind output, to compute the +# number of CPU cycles used by each VDBE opcode. +# +# The cachegrind output should be configured so that it reports a single +# column of Ir at the left margin. Ex: +# +# cg_annotation --show=Ir --auto=yes cachegrind.out.* | tclsh opcodesum.tcl +# +set currentop x +set ncycle(x) 0 +while {![eof stdin]} { + set line [string map {\173 x \175 x \042 x} [gets stdin]] + if {[regexp { \. case OP_.*:} $line]} { + regexp {OP_(.+):} $line all currentop + set ncycle($currentop) 0 + } elseif {[lindex $line 1]=="default:" + && [regexp {really OP_Noop and OP_Explain} $line]} { + break + } elseif {[lindex $line 0]!="."} { + regsub -all {[^0-9]} [lindex $line 0] {} n + if {$n!=""} {incr ncycle($currentop) $n} + } +} +unset ncycle(x) +set results {} +foreach op [lsort [array names ncycle]] { + if {$ncycle($op)==0} continue + lappend results [list $ncycle($op) $op] +} +foreach entry [lsort -index 0 -int -decr $results] { + puts [format {%-16s %10d} [lindex $entry 1] [lindex $entry 0]] +} From ed90a4676e533d0887cb4d729304264ad15b2e24 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 21 May 2016 00:45:54 +0000 Subject: [PATCH 0448/1484] Add the shell-script used for routine performance testing. FossilOrigin-Name: 8e366f18f5bbd594390e7b091083e99639de324e --- manifest | 11 ++--- manifest.uuid | 2 +- tool/speed-check.sh | 105 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 112 insertions(+), 6 deletions(-) create mode 100644 tool/speed-check.sh diff --git a/manifest b/manifest index d563744dae..03a75c80e4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sa\ssimple\sTCL\sscript\sfor\ssumming\scachegrind\sinformation\sfor\seach\sVDBE\nopcdoe. -D 2016-05-20T23:51:14.900 +C Add\sthe\sshell-script\sused\sfor\sroutine\sperformance\stesting. +D 2016-05-21T00:45:54.756 F Makefile.in f59e0763ff448719fc1bd25513882b0567286317 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7 @@ -1452,6 +1452,7 @@ F tool/showstat4.c bda40d6e395df7edb6e9ea630784d3d762c35b4b F tool/showwal.c ec79959834f7b21f1e0a2aa52bb7c056d2203977 F tool/soak1.tcl 8d407956e1a45b485a8e072470a3e629a27037fe F tool/spaceanal.tcl 85d90e6674d8298e3eaf82dbcef3abc2d5317f3e +F tool/speed-check.sh 45d3bf861b009993ff401f0d00e34a4cc937fce4 F tool/speedtest.tcl 06c76698485ccf597b9e7dbb1ac70706eb873355 F tool/speedtest16.c ecb6542862151c3e6509bbc00509b234562ae81e F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff @@ -1491,7 +1492,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 1765672c2599eb03d39c52cd2dc32ea1e5ee069e -R 247c58a1e4c62949bc3249c61dcdd977 +P 96cf821b6a69e2e8df33271b7bb674bd12a1ef7b +R ca27df5abd7cea75d52374965a3f09f5 U drh -Z 3e7f8cdf9cdb094239005245e5b11ebd +Z 7380639ab417b2bbe053c05d7bd1cc2b diff --git a/manifest.uuid b/manifest.uuid index 1f418b0d95..4fc75f4fe0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -96cf821b6a69e2e8df33271b7bb674bd12a1ef7b \ No newline at end of file +8e366f18f5bbd594390e7b091083e99639de324e \ No newline at end of file diff --git a/tool/speed-check.sh b/tool/speed-check.sh new file mode 100644 index 0000000000..d10f172d59 --- /dev/null +++ b/tool/speed-check.sh @@ -0,0 +1,105 @@ +#!/bin/bash +# +# This is a template for a script used for day-to-day size and +# performance monitoring of SQLite. Typical usage: +# +# sh run-speed-test.sh trunk # Baseline measurement of trunk +# sh run-speed-test.sh x1 # Measure some experimental change +# fossil test-diff --tk cout-trunk.txt cout-x1.txt # View chanages +# +# There are multiple output files, all with a base name given by +# the first argument: +# +# summary-$BASE.txt # Copy of standard output +# cout-$BASE.txt # cachegrind output +# explain-$BASE.txt # EXPLAIN listings (only with --explain) +# +if test "$1" = "" +then + echo "Usage: $0 OUTPUTFILE [OPTIONS]" + exit +fi +NAME=$1 +shift +CC_OPTS="-DSQLITE_ENABLE_RTREE -DSQLITE_ENABLE_MEMSYS5" +SPEEDTEST_OPTS="--shrink-memory --reprepare --heap 10000000 64" +SIZE=5 +doExplain=0 +doCachegrind=1 +while test "$1" != ""; do + case $1 in + --reprepare) + SPEEDTEST_OPTS="$SPEEDTEST_OPTS $1" + ;; + --autovacuum) + SPEEDTEST_OPTS="$SPEEDTEST_OPTS $1" + ;; + --utf16be) + SPEEDTEST_OPTS="$SPEEDTEST_OPTS $1" + ;; + --stats) + SPEEDTEST_OPTS="$SPEEDTEST_OPTS $1" + ;; + --without-rowid) + SPEEDTEST_OPTS="$SPEEDTEST_OPTS $1" + ;; + --nomemstat) + SPEEDTEST_OPTS="$SPEEDTEST_OPTS $1" + ;; + --temp) + SPEEDTEST_OPTS="$SPEEDTEST_OPTS --temp 6" + ;; + --wal) + SPEEDTEST_OPTS="$SPEEDTEST_OPTS --journal wal" + ;; + --size) + shift; SIZE=$1 + ;; + --explain) + doExplain=1 + ;; + --vdbeprofile) + rm -f vdbe_profile.out + CC_OPTS="$CC_OPTS -DVDBE_PROFILE" + doCachegrind=0 + ;; + --heap) + CC_OPTS="$CC_OPTS -DSQLITE_ENABLE_MEMSYS5" + shift; + SPEEDTEST_OPTS="$SPEEDTEST_OPTS --heap $1 64" + ;; + *) + CC_OPTS="$CC_OPTS $1" + ;; + esac + shift +done +SPEEDTEST_OPTS="$SPEEDTEST_OPTS --size $SIZE" +echo "NAME = $NAME" | tee summary-$NAME.txt +echo "SPEEDTEST_OPTS = $SPEEDTEST_OPTS" | tee -a summary-$NAME.txt +echo "CC_OPTS = $CC_OPTS" | tee -a summary-$NAME.txt +rm -f cachegrind.out.* speedtest1 speedtest1.db sqlite3.o +gcc -g -Os -Wall -I. $CC_OPTS -c sqlite3.c +size sqlite3.o | tee -a summary-$NAME.txt +if test $doExplain -eq 1; then + gcc -g -Os -Wall -I. $CC_OPTS \ + -DSQLITE_ENABLE_EXPLAIN_COMMENTS \ + ./shell.c ./sqlite3.c -o sqlite3 -ldl -lpthread +fi +SRC=./speedtest1.c +gcc -g -Os -Wall -I. $CC_OPTS $SRC ./sqlite3.o -o speedtest1 -ldl -lpthread +ls -l speedtest1 | tee -a summary-$NAME.txt +if test $doCachegrind -eq 1; then + valgrind --tool=cachegrind ./speedtest1 speedtest1.db \ + $SPEEDTEST_OPTS 2>&1 | tee -a summary-$NAME.txt +else + ./speedtest1 speedtest1.db $SPEEDTEST_OPTS 2>&1 | tee -a summary-$NAME.txt +fi +size sqlite3.o | tee -a summary-$NAME.txt +wc sqlite3.c +if test $doCachegrind -eq 1; then + cg_anno.tcl cachegrind.out.* >cout-$NAME.txt +fi +if test $doExplain -eq 1; then + ./speedtest1 --explain $SPEEDTEST_OPTS | ./sqlite3 >explain-$NAME.txt +fi From cb89f4aba8e226adca32c5dad02a21220b80f177 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 21 May 2016 11:23:26 +0000 Subject: [PATCH 0449/1484] Small size reduction and performance increase in the sqlite3BtreeInsert() logic. FossilOrigin-Name: 656aa1ecf5129ae43c56a990e95038b5d8cbdcee --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btree.c | 15 ++++++++++----- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 03a75c80e4..836b8184c2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sshell-script\sused\sfor\sroutine\sperformance\stesting. -D 2016-05-21T00:45:54.756 +C Small\ssize\sreduction\sand\sperformance\sincrease\sin\sthe\ssqlite3BtreeInsert()\nlogic. +D 2016-05-21T11:23:26.914 F Makefile.in f59e0763ff448719fc1bd25513882b0567286317 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7 @@ -322,7 +322,7 @@ F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240 F src/backup.c 6df65fdd569c901a418887a1a76f82ec35044556 F src/bitvec.c 3ee4c8b2c94ed3a7377256e18199e6ff5cf33f63 F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 -F src/btree.c e53a01547d61a3d567daf7a7acc30122fe071aef +F src/btree.c ab4ab00fa42b9f31a3c4f4232ab7dffe15a37728 F src/btree.h a5008b9afe56e8e54ade6c436a910f112defcca9 F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 F src/build.c 785fa789319d93c6ae20efbd01d4da9ce8f8a793 @@ -1492,7 +1492,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 96cf821b6a69e2e8df33271b7bb674bd12a1ef7b -R ca27df5abd7cea75d52374965a3f09f5 +P 8e366f18f5bbd594390e7b091083e99639de324e +R 59f3ac52df516414b0292061ce466d2b U drh -Z 7380639ab417b2bbe053c05d7bd1cc2b +Z 1ed41a6ca1c9810f6f5090ac3b0958c0 diff --git a/manifest.uuid b/manifest.uuid index 4fc75f4fe0..6b45ee4bc0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8e366f18f5bbd594390e7b091083e99639de324e \ No newline at end of file +656aa1ecf5129ae43c56a990e95038b5d8cbdcee \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 7e6b050f83..033d9c24c3 100644 --- a/src/btree.c +++ b/src/btree.c @@ -6310,6 +6310,8 @@ static void dropCell(MemPage *pPage, int idx, int sz, int *pRC){ ** in pTemp or the original pCell) and also record its index. ** Allocating a new entry in pPage->aCell[] implies that ** pPage->nOverflow is incremented. +** +** *pRC must be SQLITE_OK when this routine is called. */ static void insertCell( MemPage *pPage, /* Page into which we are copying */ @@ -6325,8 +6327,7 @@ static void insertCell( u8 *data; /* The content of the whole page */ u8 *pIns; /* The point in pPage->aCellIdx[] where no cell inserted */ - if( *pRC ) return; - + assert( *pRC==SQLITE_OK ); assert( i>=0 && i<=pPage->nCell+pPage->nOverflow ); assert( MX_CELL(pPage->pBt)<=10921 ); assert( pPage->nCell<=MX_CELL(pPage->pBt) || CORRUPT_DB ); @@ -6832,8 +6833,10 @@ static int balance_quick(MemPage *pParent, MemPage *pPage, u8 *pSpace){ while( ((*(pOut++) = *(pCell++))&0x80) && pCellnCell, pSpace, (int)(pOut-pSpace), - 0, pPage->pgno, &rc); + if( rc==SQLITE_OK ){ + insertCell(pParent, pParent->nCell, pSpace, (int)(pOut-pSpace), + 0, pPage->pgno, &rc); + } /* Set the right-child pointer of pParent to point to the new page. */ put4byte(&pParent->aData[pParent->hdrOffset+8], pgnoNew); @@ -8215,7 +8218,9 @@ int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){ pTmp = pBt->pTmpSpace; assert( pTmp!=0 ); rc = sqlite3PagerWrite(pLeaf->pDbPage); - insertCell(pPage, iCellIdx, pCell-4, nCell+4, pTmp, n, &rc); + if( rc==SQLITE_OK ){ + insertCell(pPage, iCellIdx, pCell-4, nCell+4, pTmp, n, &rc); + } dropCell(pLeaf, pLeaf->nCell-1, nCell, &rc); if( rc ) return rc; } From 09a4e92c6da38a43c6cf774d18d101a8d322eb33 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 21 May 2016 12:29:04 +0000 Subject: [PATCH 0450/1484] Yet another minor size reduction and performance increase in the b-tree insert logic. FossilOrigin-Name: 1dbaf7a119edc5150a5d4be1b72f652a574e5bc5 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btree.c | 4 +++- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 836b8184c2..052ef57828 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Small\ssize\sreduction\sand\sperformance\sincrease\sin\sthe\ssqlite3BtreeInsert()\nlogic. -D 2016-05-21T11:23:26.914 +C Yet\sanother\sminor\ssize\sreduction\sand\sperformance\sincrease\sin\sthe\sb-tree\ninsert\slogic. +D 2016-05-21T12:29:04.510 F Makefile.in f59e0763ff448719fc1bd25513882b0567286317 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7 @@ -322,7 +322,7 @@ F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240 F src/backup.c 6df65fdd569c901a418887a1a76f82ec35044556 F src/bitvec.c 3ee4c8b2c94ed3a7377256e18199e6ff5cf33f63 F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 -F src/btree.c ab4ab00fa42b9f31a3c4f4232ab7dffe15a37728 +F src/btree.c da39b19be8a0fad4eb8a3d9e2d95a8ccc3eb8dd1 F src/btree.h a5008b9afe56e8e54ade6c436a910f112defcca9 F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 F src/build.c 785fa789319d93c6ae20efbd01d4da9ce8f8a793 @@ -1492,7 +1492,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 8e366f18f5bbd594390e7b091083e99639de324e -R 59f3ac52df516414b0292061ce466d2b +P 656aa1ecf5129ae43c56a990e95038b5d8cbdcee +R 213b2db355637b4ec446a3f8344f0ebf U drh -Z 1ed41a6ca1c9810f6f5090ac3b0958c0 +Z 69c744da391089b891fa26fe7438d9c6 diff --git a/manifest.uuid b/manifest.uuid index 6b45ee4bc0..d7ffdbf577 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -656aa1ecf5129ae43c56a990e95038b5d8cbdcee \ No newline at end of file +1dbaf7a119edc5150a5d4be1b72f652a574e5bc5 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 033d9c24c3..2e862ff697 100644 --- a/src/btree.c +++ b/src/btree.c @@ -8059,6 +8059,7 @@ int sqlite3BtreeInsert( assert( pPage->leaf ); } insertCell(pPage, idx, newCell, szNew, 0, 0, &rc); + assert( pPage->nOverflow==0 || rc==SQLITE_OK ); assert( rc!=SQLITE_OK || pPage->nCell>0 || pPage->nOverflow>0 ); /* If no error has occurred and pPage has an overflow cell, call balance() @@ -8082,7 +8083,8 @@ int sqlite3BtreeInsert( ** row without seeking the cursor. This can be a big performance boost. */ pCur->info.nSize = 0; - if( rc==SQLITE_OK && pPage->nOverflow ){ + if( pPage->nOverflow ){ + assert( rc==SQLITE_OK ); pCur->curFlags &= ~(BTCF_ValidNKey); rc = balance(pCur); From 16e2b9694a3abcf3f670df5232433bbcfedbb522 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 21 May 2016 19:10:21 +0000 Subject: [PATCH 0451/1484] Remove some unused legacy code from the btree insert logic. FossilOrigin-Name: 2ce1166717ac3c0cec37b2f6d70d8359fbaefc71 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btree.c | 5 ----- 3 files changed, 7 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 052ef57828..e2540ef87b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Yet\sanother\sminor\ssize\sreduction\sand\sperformance\sincrease\sin\sthe\sb-tree\ninsert\slogic. -D 2016-05-21T12:29:04.510 +C Remove\ssome\sunused\slegacy\scode\sfrom\sthe\sbtree\sinsert\slogic. +D 2016-05-21T19:10:21.800 F Makefile.in f59e0763ff448719fc1bd25513882b0567286317 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7 @@ -322,7 +322,7 @@ F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240 F src/backup.c 6df65fdd569c901a418887a1a76f82ec35044556 F src/bitvec.c 3ee4c8b2c94ed3a7377256e18199e6ff5cf33f63 F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 -F src/btree.c da39b19be8a0fad4eb8a3d9e2d95a8ccc3eb8dd1 +F src/btree.c 09df167470e82b34f92d60cdd1a44f397ae8e105 F src/btree.h a5008b9afe56e8e54ade6c436a910f112defcca9 F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 F src/build.c 785fa789319d93c6ae20efbd01d4da9ce8f8a793 @@ -1492,7 +1492,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 656aa1ecf5129ae43c56a990e95038b5d8cbdcee -R 213b2db355637b4ec446a3f8344f0ebf +P 1dbaf7a119edc5150a5d4be1b72f652a574e5bc5 +R 46d65e39155fd1bfd348824fd7a5487b U drh -Z 69c744da391089b891fa26fe7438d9c6 +Z 20edc765018d44eea5900b69fe208cfe diff --git a/manifest.uuid b/manifest.uuid index d7ffdbf577..1710f63d06 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1dbaf7a119edc5150a5d4be1b72f652a574e5bc5 \ No newline at end of file +2ce1166717ac3c0cec37b2f6d70d8359fbaefc71 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 2e862ff697..a747abedb0 100644 --- a/src/btree.c +++ b/src/btree.c @@ -6111,7 +6111,6 @@ static int fillInCell( if( pPage->intKey ){ pSrc = pData; nSrc = nData; - nData = 0; }else{ assert( nKey<=0x7fffffff && pKey!=0 ); nPayload = (int)nKey; @@ -6240,10 +6239,6 @@ static int fillInCell( pSrc += n; nSrc -= n; spaceLeft -= n; - if( nSrc==0 ){ - nSrc = nData; - pSrc = pData; - } } releasePage(pToRelease); return SQLITE_OK; From 8eeb4463d9e1df9cae9d535ad02b491d60b2014e Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 21 May 2016 20:03:42 +0000 Subject: [PATCH 0452/1484] Simplify the sqlite3BtreeInsert() interface by gathering the five arguments describing the content to be inserted into the new BtreePayload structure, and thus reducing the number of parameters from eight to four. FossilOrigin-Name: 55f348cdd24c7812ea4b63345514764b69f64dc8 --- manifest | 18 +++++++------- manifest.uuid | 2 +- src/btree.c | 69 ++++++++++++++++++++++++++------------------------- src/btree.h | 32 +++++++++++++++++++++--- src/test3.c | 16 ++++++------ src/vdbe.c | 39 +++++++++++++++-------------- 6 files changed, 103 insertions(+), 73 deletions(-) diff --git a/manifest b/manifest index e2540ef87b..72aeb9be8e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\ssome\sunused\slegacy\scode\sfrom\sthe\sbtree\sinsert\slogic. -D 2016-05-21T19:10:21.800 +C Simplify\sthe\ssqlite3BtreeInsert()\sinterface\sby\sgathering\sthe\sfive\sarguments\ndescribing\sthe\scontent\sto\sbe\sinserted\sinto\sthe\snew\sBtreePayload\sstructure,\sand\nthus\sreducing\sthe\snumber\sof\sparameters\sfrom\seight\sto\sfour. +D 2016-05-21T20:03:42.980 F Makefile.in f59e0763ff448719fc1bd25513882b0567286317 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7 @@ -322,8 +322,8 @@ F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240 F src/backup.c 6df65fdd569c901a418887a1a76f82ec35044556 F src/bitvec.c 3ee4c8b2c94ed3a7377256e18199e6ff5cf33f63 F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 -F src/btree.c 09df167470e82b34f92d60cdd1a44f397ae8e105 -F src/btree.h a5008b9afe56e8e54ade6c436a910f112defcca9 +F src/btree.c e312cc3fdff31fdcc727b973fa0f195573b86393 +F src/btree.h 1342a9b2cc2089e3534d3ef00204786783f6aea6 F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 F src/build.c 785fa789319d93c6ae20efbd01d4da9ce8f8a793 F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 @@ -390,7 +390,7 @@ F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 F src/tclsqlite.c 9c4c4589d078de37813ded708d8838b338ffb060 F src/test1.c c0e5b69f99e95a2c9f55fdb6e46b44f1a15292d8 F src/test2.c 5586f43fcd9a1be0830793cf9d354082c261b25b -F src/test3.c 0df6f8dbb4cbaa7106397c70a271fa6a43659042 +F src/test3.c d2c9efd2985ff8f5502ffd3253156984778d77d8 F src/test4.c d168f83cc78d02e8d35567bb5630e40dcd85ac1e F src/test5.c 5a34feec76d9b3a86aab30fd4f6cc9c48cbab4c1 F src/test6.c 2c014d4977efd6107ec9eef3dfdec56ac516f824 @@ -444,7 +444,7 @@ F src/update.c 4f05ea8cddfa367d045e03589756c02199e8f9bd F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 810ec3f22e2d1b62e66c30fe3621ebdedd23584d F src/vacuum.c feb1eabb20987983d9350cad98299b21fa811f52 -F src/vdbe.c 975ac1d3d326bcb36b4e99255daeaf81ff6659d1 +F src/vdbe.c f2706d5564d2b2887a27c909e8e1575250029503 F src/vdbe.h 5591b5add447096e31288b5a0a78ec5d7b5c5170 F src/vdbeInt.h ddb157974436d87652de7dc641f7191496d9a8cd F src/vdbeapi.c ba85b78fe08dc4a9ce747e62c89a2b4a4547e74c @@ -1492,7 +1492,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 1dbaf7a119edc5150a5d4be1b72f652a574e5bc5 -R 46d65e39155fd1bfd348824fd7a5487b +P 2ce1166717ac3c0cec37b2f6d70d8359fbaefc71 +R 560ed5c35c4c6718e1a252b0b3f02845 U drh -Z 20edc765018d44eea5900b69fe208cfe +Z ca823f4324bb11c74d57e3f017091386 diff --git a/manifest.uuid b/manifest.uuid index 1710f63d06..bbbac57808 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2ce1166717ac3c0cec37b2f6d70d8359fbaefc71 \ No newline at end of file +55f348cdd24c7812ea4b63345514764b69f64dc8 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index a747abedb0..44b25019d1 100644 --- a/src/btree.c +++ b/src/btree.c @@ -6072,9 +6072,7 @@ static int clearCell( static int fillInCell( MemPage *pPage, /* The page that contains the cell */ unsigned char *pCell, /* Complete text of the cell */ - const void *pKey, i64 nKey, /* The key */ - const void *pData,int nData, /* The data */ - int nZero, /* Extra zero bytes to append to pData */ + const BtreePayload *pX, /* Payload with which to construct the cell */ int *pnSize /* Write cell size here */ ){ int nPayload; @@ -6098,24 +6096,23 @@ static int fillInCell( /* Fill in the header. */ nHeader = pPage->childPtrSize; - nPayload = nData + nZero; + nPayload = pX->nData + pX->nZero; if( pPage->intKeyLeaf ){ nHeader += putVarint32(&pCell[nHeader], nPayload); }else{ - assert( nData==0 ); - assert( nZero==0 ); + assert( pX->nData==0 ); + assert( pX->nZero==0 ); } - nHeader += putVarint(&pCell[nHeader], *(u64*)&nKey); + nHeader += putVarint(&pCell[nHeader], *(u64*)&pX->nKey); - /* Fill in the payload size */ + /* Fill in the payload */ if( pPage->intKey ){ - pSrc = pData; - nSrc = nData; + pSrc = pX->pData; + nSrc = pX->nData; }else{ - assert( nKey<=0x7fffffff && pKey!=0 ); - nPayload = (int)nKey; - pSrc = pKey; - nSrc = (int)nKey; + assert( pX->nKey<=0x7fffffff && pX->pKey!=0 ); + nSrc = nPayload = (int)pX->nKey; + pSrc = pX->pKey; } if( nPayload<=pPage->maxLocal ){ n = nHeader + nPayload; @@ -6154,7 +6151,7 @@ static int fillInCell( CellInfo info; pPage->xParseCell(pPage, pCell, &info); assert( nHeader==(int)(info.pPayload - pCell) ); - assert( info.nKey==nKey ); + assert( info.nKey==pX->nKey ); assert( *pnSize == info.nSize ); assert( spaceLeft == info.nLocal ); } @@ -7923,13 +7920,19 @@ static int balance(BtCursor *pCur){ /* -** Insert a new record into the BTree. The key is given by (pKey,nKey) -** and the data is given by (pData,nData). The cursor is used only to -** define what table the record should be inserted into. The cursor -** is left pointing at a random location. +** Insert a new record into the BTree. The content of the new record +** is described by the pX object. The pCur cursor is used only to +** define what table the record should be inserted into, and is left +** pointing at a random location. ** -** For an INTKEY table, only the nKey value of the key is used. pKey is -** ignored. For a ZERODATA table, the pData and nData are both ignored. +** For a table btree (used for rowid tables), only the pX.nKey value of +** the key is used. The pX.pKey value must be NULL. The pX.nKey is the +** rowid or INTEGER PRIMARY KEY of the row. The pX.nData,pData,nZero fields +** hold the content of the row. +** +** For an index btree (used for indexes and WITHOUT ROWID tables), the +** key is an arbitrary byte sequence stored in pX.pKey,nKey. The +** pX.pData,nData,nZero fields must be zero. ** ** If the seekResult parameter is non-zero, then a successful call to ** MovetoUnpacked() to seek cursor pCur to (pKey, nKey) has already @@ -7946,9 +7949,7 @@ static int balance(BtCursor *pCur){ */ int sqlite3BtreeInsert( BtCursor *pCur, /* Insert data into the table of this cursor */ - const void *pKey, i64 nKey, /* The key of the new record */ - const void *pData, int nData, /* The data of the new record */ - int nZero, /* Number of extra 0 bytes to append to data */ + const BtreePayload *pX, /* Content of the row to be inserted */ int appendBias, /* True if this is likely an append */ int seekResult /* Result of prior MovetoUnpacked() call */ ){ @@ -7978,7 +7979,7 @@ int sqlite3BtreeInsert( ** keys with no associated data. If the cursor was opened expecting an ** intkey table, the caller should be inserting integer keys with a ** blob of associated data. */ - assert( (pKey==0)==(pCur->pKeyInfo==0) ); + assert( (pX->pKey==0)==(pCur->pKeyInfo==0) ); /* Save the positions of any other cursors open on this table. ** @@ -7997,38 +7998,38 @@ int sqlite3BtreeInsert( } if( pCur->pKeyInfo==0 ){ - assert( pKey==0 ); + assert( pX->pKey==0 ); /* If this is an insert into a table b-tree, invalidate any incrblob ** cursors open on the row being replaced */ - invalidateIncrblobCursors(p, nKey, 0); + invalidateIncrblobCursors(p, pX->nKey, 0); /* If the cursor is currently on the last row and we are appending a ** new row onto the end, set the "loc" to avoid an unnecessary ** btreeMoveto() call */ - if( (pCur->curFlags&BTCF_ValidNKey)!=0 && nKey>0 - && pCur->info.nKey==nKey-1 ){ + if( (pCur->curFlags&BTCF_ValidNKey)!=0 && pX->nKey>0 + && pCur->info.nKey==pX->nKey-1 ){ loc = -1; }else if( loc==0 ){ - rc = sqlite3BtreeMovetoUnpacked(pCur, 0, nKey, appendBias, &loc); + rc = sqlite3BtreeMovetoUnpacked(pCur, 0, pX->nKey, appendBias, &loc); if( rc ) return rc; } }else if( loc==0 ){ - rc = btreeMoveto(pCur, pKey, nKey, appendBias, &loc); + rc = btreeMoveto(pCur, pX->pKey, pX->nKey, appendBias, &loc); if( rc ) return rc; } assert( pCur->eState==CURSOR_VALID || (pCur->eState==CURSOR_INVALID && loc) ); pPage = pCur->apPage[pCur->iPage]; - assert( pPage->intKey || nKey>=0 ); + assert( pPage->intKey || pX->nKey>=0 ); assert( pPage->leaf || !pPage->intKey ); TRACE(("INSERT: table=%d nkey=%lld ndata=%d page=%d %s\n", - pCur->pgnoRoot, nKey, nData, pPage->pgno, + pCur->pgnoRoot, pX->nKey, pX->nData, pPage->pgno, loc==0 ? "overwrite" : "new entry")); assert( pPage->isInit ); newCell = pBt->pTmpSpace; assert( newCell!=0 ); - rc = fillInCell(pPage, newCell, pKey, nKey, pData, nData, nZero, &szNew); + rc = fillInCell(pPage, newCell, pX, &szNew); if( rc ) goto end_insert; assert( szNew==pPage->xCellSize(pPage, newCell) ); assert( szNew <= MX_CELL_SIZE(pBt) ); diff --git a/src/btree.h b/src/btree.h index 9ba233ac33..5ac119c40a 100644 --- a/src/btree.h +++ b/src/btree.h @@ -39,6 +39,7 @@ typedef struct Btree Btree; typedef struct BtCursor BtCursor; typedef struct BtShared BtShared; +typedef struct BtreePayload BtreePayload; int sqlite3BtreeOpen( @@ -250,9 +251,34 @@ int sqlite3BtreeDelete(BtCursor*, u8 flags); #define BTREE_SAVEPOSITION 0x02 /* Leave cursor pointing at NEXT or PREV */ #define BTREE_AUXDELETE 0x04 /* not the primary delete operation */ -int sqlite3BtreeInsert(BtCursor*, const void *pKey, i64 nKey, - const void *pData, int nData, - int nZero, int bias, int seekResult); +/* An instance of the BtreePayload object describes the content of a single +** entry in either an index or table btree. +** +** Index btrees (used for indexes and also WITHOUT ROWID tables) contain +** an arbitrary key and no data. These btrees have pKey,nKey set to their +** key and pData,nData,nZero set to zero. +** +** Table btrees (used for rowid tables) contain an integer rowid used as +** the key and passed in the nKey field. The pKey field is zero. +** pData,nData hold the content of the new entry. nZero extra zero bytes +** are appended to the end of the content when constructing the entry. +** +** This object is used to pass information into sqlite3BtreeInsert(). The +** same information used to be passed as five separate parameters. But placing +** the information into this object helps to keep the interface more +** organized and understandable, and it also helps the resulting code to +** run a little faster by using fewer registers for parameter passing. +*/ +struct BtreePayload { + const void *pKey; /* Key content for indexes. NULL for tables */ + sqlite3_int64 nKey; /* Size of pKey for indexes. PRIMARY KEY for tabs */ + const void *pData; /* Data for tables. NULL for indexes */ + int nData; /* Size of pData. 0 if none. */ + int nZero; /* Extra zero data appended after pData,nData */ +}; + +int sqlite3BtreeInsert(BtCursor*, const BtreePayload *pPayload, + int bias, int seekResult); int sqlite3BtreeFirst(BtCursor*, int *pRes); int sqlite3BtreeLast(BtCursor*, int *pRes); int sqlite3BtreeNext(BtCursor*, int *pRes); diff --git a/src/test3.c b/src/test3.c index 817e8a88fd..1e4baf7577 100644 --- a/src/test3.c +++ b/src/test3.c @@ -618,27 +618,27 @@ static int btree_insert( ){ BtCursor *pCur; int rc; - void *pKey = 0; - int nKey = 0; - void *pData = 0; - int nData = 0; + BtreePayload x; if( objc!=4 && objc!=3 ){ Tcl_WrongNumArgs(interp, 1, objv, "?-intkey? CSR KEY VALUE"); return TCL_ERROR; } + memset(&x, 0, sizeof(x)); if( objc==4 ){ - if( Tcl_GetIntFromObj(interp, objv[2], &nKey) ) return TCL_ERROR; - pData = (void*)Tcl_GetByteArrayFromObj(objv[3], &nData); + if( Tcl_GetIntFromObj(interp, objv[2], &rc) ) return TCL_ERROR; + x.nKey = rc; + x.pData = (void*)Tcl_GetByteArrayFromObj(objv[3], &x.nData); }else{ - pKey = (void*)Tcl_GetByteArrayFromObj(objv[2], &nKey); + x.pKey = (void*)Tcl_GetByteArrayFromObj(objv[2], &rc); + x.nKey = rc; } pCur = (BtCursor*)sqlite3TestTextToPtr(Tcl_GetString(objv[1])); sqlite3_mutex_enter(pCur->pBtree->db->mutex); sqlite3BtreeEnter(pCur->pBtree); - rc = sqlite3BtreeInsert(pCur, pKey, nKey, pData, nData, 0, 0, 0); + rc = sqlite3BtreeInsert(pCur, &x, 0, 0); sqlite3BtreeLeave(pCur->pBtree); sqlite3_mutex_leave(pCur->pBtree->db->mutex); diff --git a/src/vdbe.c b/src/vdbe.c index 36c014a7d0..d512c0bc74 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -4285,13 +4285,12 @@ case OP_Insert: case OP_InsertInt: { Mem *pData; /* MEM cell holding data for the record to be inserted */ Mem *pKey; /* MEM cell holding key for the record */ - i64 iKey; /* The integer ROWID or key for the record to be inserted */ VdbeCursor *pC; /* Cursor to table into which insert is written */ - int nZero; /* Number of zero-bytes to append */ int seekResult; /* Result of prior seek or 0 if no USESEEKRESULT flag */ const char *zDb; /* database name - used by the update hook */ Table *pTab; /* Table structure - used by update and pre-update hooks */ int op; /* Opcode for update hook: SQLITE_UPDATE or SQLITE_INSERT */ + BtreePayload x; /* Payload to be inserted */ op = 0; pData = &aMem[pOp->p2]; @@ -4310,10 +4309,10 @@ case OP_InsertInt: { assert( pKey->flags & MEM_Int ); assert( memIsValid(pKey) ); REGISTER_TRACE(pOp->p3, pKey); - iKey = pKey->u.i; + x.nKey = pKey->u.i; }else{ assert( pOp->opcode==OP_InsertInt ); - iKey = pOp->p3; + x.nKey = pOp->p3; } if( pOp->p4type==P4_TABLE && HAS_UPDATE_HOOK(db) ){ @@ -4334,26 +4333,28 @@ case OP_InsertInt: { && pOp->p4type==P4_TABLE && !(pOp->p5 & OPFLAG_ISUPDATE) ){ - sqlite3VdbePreUpdateHook(p, pC, SQLITE_INSERT, zDb, pTab, iKey, pOp->p2); + sqlite3VdbePreUpdateHook(p, pC, SQLITE_INSERT, zDb, pTab, x.nKey, pOp->p2); } #endif if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++; - if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = lastRowid = iKey; + if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = lastRowid = x.nKey; if( pData->flags & MEM_Null ){ - pData->z = 0; - pData->n = 0; + x.pData = 0; + x.nData = 0; }else{ assert( pData->flags & (MEM_Blob|MEM_Str) ); + x.pData = pData->z; + x.nData = pData->n; } seekResult = ((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0); if( pData->flags & MEM_Zero ){ - nZero = pData->u.nZero; + x.nZero = pData->u.nZero; }else{ - nZero = 0; + x.nZero = 0; } - rc = sqlite3BtreeInsert(pC->uc.pCursor, 0, iKey, - pData->z, pData->n, nZero, + x.pKey = 0; + rc = sqlite3BtreeInsert(pC->uc.pCursor, &x, (pOp->p5 & OPFLAG_APPEND)!=0, seekResult ); pC->deferredMoveto = 0; @@ -4362,7 +4363,7 @@ case OP_InsertInt: { /* Invoke the update-hook if required. */ if( rc ) goto abort_due_to_error; if( db->xUpdateCallback && op ){ - db->xUpdateCallback(db->pUpdateArg, op, zDb, pTab->zName, iKey); + db->xUpdateCallback(db->pUpdateArg, op, zDb, pTab->zName, x.nKey); } break; } @@ -4977,8 +4978,7 @@ next_tail: case OP_SorterInsert: /* in2 */ case OP_IdxInsert: { /* in2 */ VdbeCursor *pC; - int nKey; - const char *zKey; + BtreePayload x; assert( pOp->p1>=0 && pOp->p1nCursor ); pC = p->apCsr[pOp->p1]; @@ -4994,9 +4994,12 @@ case OP_IdxInsert: { /* in2 */ if( pOp->opcode==OP_SorterInsert ){ rc = sqlite3VdbeSorterWrite(pC, pIn2); }else{ - nKey = pIn2->n; - zKey = pIn2->z; - rc = sqlite3BtreeInsert(pC->uc.pCursor, zKey, nKey, "", 0, 0, pOp->p3, + x.nKey = pIn2->n; + x.pKey = pIn2->z; + x.nData = 0; + x.nZero = 0; + x.pData = 0; + rc = sqlite3BtreeInsert(pC->uc.pCursor, &x, pOp->p3, ((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0) ); assert( pC->deferredMoveto==0 ); From dfc2daa7c383b1a088c729d1a3f373eda5cc992e Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 21 May 2016 23:25:29 +0000 Subject: [PATCH 0453/1484] More tweaks to improve the performance of the insert logic, slightly. FossilOrigin-Name: dec1307581216e01ad508ffe4455b957e3356654 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btree.c | 19 +++++++++---------- 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/manifest b/manifest index 72aeb9be8e..5a3bac30b0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Simplify\sthe\ssqlite3BtreeInsert()\sinterface\sby\sgathering\sthe\sfive\sarguments\ndescribing\sthe\scontent\sto\sbe\sinserted\sinto\sthe\snew\sBtreePayload\sstructure,\sand\nthus\sreducing\sthe\snumber\sof\sparameters\sfrom\seight\sto\sfour. -D 2016-05-21T20:03:42.980 +C More\stweaks\sto\simprove\sthe\sperformance\sof\sthe\sinsert\slogic,\sslightly. +D 2016-05-21T23:25:29.377 F Makefile.in f59e0763ff448719fc1bd25513882b0567286317 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7 @@ -322,7 +322,7 @@ F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240 F src/backup.c 6df65fdd569c901a418887a1a76f82ec35044556 F src/bitvec.c 3ee4c8b2c94ed3a7377256e18199e6ff5cf33f63 F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 -F src/btree.c e312cc3fdff31fdcc727b973fa0f195573b86393 +F src/btree.c 2128172fc1c420a6fa6878827fa595407795069a F src/btree.h 1342a9b2cc2089e3534d3ef00204786783f6aea6 F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 F src/build.c 785fa789319d93c6ae20efbd01d4da9ce8f8a793 @@ -1492,7 +1492,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 2ce1166717ac3c0cec37b2f6d70d8359fbaefc71 -R 560ed5c35c4c6718e1a252b0b3f02845 +P 55f348cdd24c7812ea4b63345514764b69f64dc8 +R c264a769216b385e0f4c9931cdb639d6 U drh -Z ca823f4324bb11c74d57e3f017091386 +Z 3ab4f00ccff5a15915c6caecbe082e94 diff --git a/manifest.uuid b/manifest.uuid index bbbac57808..ff5538c7f9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -55f348cdd24c7812ea4b63345514764b69f64dc8 \ No newline at end of file +dec1307581216e01ad508ffe4455b957e3356654 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 44b25019d1..7a2b80c23b 100644 --- a/src/btree.c +++ b/src/btree.c @@ -6096,24 +6096,23 @@ static int fillInCell( /* Fill in the header. */ nHeader = pPage->childPtrSize; - nPayload = pX->nData + pX->nZero; - if( pPage->intKeyLeaf ){ + if( pPage->intKey ){ + nPayload = pX->nData + pX->nZero; + pSrc = pX->pData; + nSrc = pX->nData; + assert( pPage->intKeyLeaf ); /* fillInCell() only called for leaves */ nHeader += putVarint32(&pCell[nHeader], nPayload); + nHeader += putVarint(&pCell[nHeader], *(u64*)&pX->nKey); }else{ assert( pX->nData==0 ); assert( pX->nZero==0 ); - } - nHeader += putVarint(&pCell[nHeader], *(u64*)&pX->nKey); - - /* Fill in the payload */ - if( pPage->intKey ){ - pSrc = pX->pData; - nSrc = pX->nData; - }else{ assert( pX->nKey<=0x7fffffff && pX->pKey!=0 ); nSrc = nPayload = (int)pX->nKey; pSrc = pX->pKey; + nHeader += putVarint32(&pCell[nHeader], nPayload); } + + /* Fill in the payload */ if( nPayload<=pPage->maxLocal ){ n = nHeader + nPayload; testcase( n==3 ); From 6831474341d6f532246158a59ed289e15424098a Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 23 May 2016 00:10:58 +0000 Subject: [PATCH 0454/1484] Update the configure script with additional hints on the location of tclConfig.sh, hints needed by the latest versions of Xcode. FossilOrigin-Name: 90411a28168f6dacf08242a25bed7d6269041417 --- configure | 14 ++++++++++++++ configure.ac | 14 ++++++++++++++ manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 36 insertions(+), 8 deletions(-) diff --git a/configure b/configure index 22a646c2b6..f4d4c48077 100755 --- a/configure +++ b/configure @@ -10757,6 +10757,20 @@ else fi fi + # Recent versions of Xcode on Macs hid the tclConfig.sh file + # in a strange place. + if test x"${ac_cv_c_tclconfig}" = x ; then + if test x"$cross_compiling" = xno; then + for i in /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX*.sdk/usr/lib + do + if test -f "$i/tclConfig.sh" ; then + ac_cv_c_tclconfig="$i" + break + fi + done + fi + fi + # then check for a private Tcl installation if test x"${ac_cv_c_tclconfig}" = x ; then for i in \ diff --git a/configure.ac b/configure.ac index 2c97885ade..e5727ea7f2 100644 --- a/configure.ac +++ b/configure.ac @@ -334,6 +334,20 @@ if test "${use_tcl}" = "yes" ; then fi fi + # Recent versions of Xcode on Macs hid the tclConfig.sh file + # in a strange place. + if test x"${ac_cv_c_tclconfig}" = x ; then + if test x"$cross_compiling" = xno; then + for i in /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX*.sdk/usr/lib + do + if test -f "$i/tclConfig.sh" ; then + ac_cv_c_tclconfig="$i" + break + fi + done + fi + fi + # then check for a private Tcl installation if test x"${ac_cv_c_tclconfig}" = x ; then for i in \ diff --git a/manifest b/manifest index 5a3bac30b0..40f21b9ec2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C More\stweaks\sto\simprove\sthe\sperformance\sof\sthe\sinsert\slogic,\sslightly. -D 2016-05-21T23:25:29.377 +C Update\sthe\sconfigure\sscript\swith\sadditional\shints\son\sthe\slocation\sof\ntclConfig.sh,\shints\sneeded\sby\sthe\slatest\sversions\sof\sXcode. +D 2016-05-23T00:10:58.949 F Makefile.in f59e0763ff448719fc1bd25513882b0567286317 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7 @@ -30,8 +30,8 @@ F autoconf/tea/win/rules.vc c511f222b80064096b705dbeb97060ee1d6b6d63 F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977 F config.h.in 6376abec766e9a0785178b1823b5a587e9f1ccbc F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55 -F configure 96fdf3870e30c6f60c6a56d27f5f6e4159b9bdc6 x -F configure.ac 02b972db825685b4b0cca0234b2aa97f71bd15a5 +F configure 25cf7eb52a88846e4c1978016a9db22763c54f41 x +F configure.ac 480e1a17d5316b1751c8edcb15b8e6b8ab0a6cc3 F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad F doc/lemon.html e2118945e5f07ed146b45c9cd2b2dd6eabb8ebf2 F doc/pager-invariants.txt 27fed9a70ddad2088750c4a2b493b63853da2710 @@ -1492,7 +1492,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 55f348cdd24c7812ea4b63345514764b69f64dc8 -R c264a769216b385e0f4c9931cdb639d6 +P dec1307581216e01ad508ffe4455b957e3356654 +R 335eb72f63a6d15e3459420d579ffc36 U drh -Z 3ab4f00ccff5a15915c6caecbe082e94 +Z 180e9fbd5ff0ebef42d9658da1e8cd36 diff --git a/manifest.uuid b/manifest.uuid index ff5538c7f9..68190eb678 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -dec1307581216e01ad508ffe4455b957e3356654 \ No newline at end of file +90411a28168f6dacf08242a25bed7d6269041417 \ No newline at end of file From 711c9810dc0d366b739c3c0f8416b386fc856fa2 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 23 May 2016 14:24:31 +0000 Subject: [PATCH 0455/1484] Fix comment typos and improve clarity of presention in Lemon. The output should be identical. FossilOrigin-Name: b91a5b8297756289d45c8fce0d3399c253517eb0 --- manifest | 12 ++++++------ manifest.uuid | 2 +- tool/lemon.c | 47 +++++++++++++++++++++++++++-------------------- 3 files changed, 34 insertions(+), 27 deletions(-) diff --git a/manifest b/manifest index 40f21b9ec2..6ea5de70eb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\sthe\sconfigure\sscript\swith\sadditional\shints\son\sthe\slocation\sof\ntclConfig.sh,\shints\sneeded\sby\sthe\slatest\sversions\sof\sXcode. -D 2016-05-23T00:10:58.949 +C Fix\scomment\stypos\sand\simprove\sclarity\sof\spresention\sin\sLemon.\s\sThe\soutput\nshould\sbe\sidentical. +D 2016-05-23T14:24:31.372 F Makefile.in f59e0763ff448719fc1bd25513882b0567286317 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7 @@ -1420,7 +1420,7 @@ F tool/fuzzershell.c 94019b185caceffc9f7c7b678a6489e42bc2aefa F tool/genfkey.README cf68fddd4643bbe3ff8e31b8b6d8b0a1b85e20f4 F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5 F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce -F tool/lemon.c f38a55106d79b7a4c063abb958517d6c47dc6ac7 +F tool/lemon.c b622032dd14dc1315fedb81d73f4658354329fca F tool/lempar.c 404ea3dc27dbeed343f0e61b1d36e97b9f5f0fb6 F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862 F tool/logest.c 11346aa019e2e77a00902aa7d0cabd27bd2e8cca @@ -1492,7 +1492,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P dec1307581216e01ad508ffe4455b957e3356654 -R 335eb72f63a6d15e3459420d579ffc36 +P 90411a28168f6dacf08242a25bed7d6269041417 +R 996821eb90ee3795d9bf03c89106b9e7 U drh -Z 180e9fbd5ff0ebef42d9658da1e8cd36 +Z b4115b7928b4702f985a5c5bf63f70fa diff --git a/manifest.uuid b/manifest.uuid index 68190eb678..3a567c6fc6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -90411a28168f6dacf08242a25bed7d6269041417 \ No newline at end of file +b91a5b8297756289d45c8fce0d3399c253517eb0 \ No newline at end of file diff --git a/tool/lemon.c b/tool/lemon.c index 01c8a1da96..2ad36eec4a 100644 --- a/tool/lemon.c +++ b/tool/lemon.c @@ -288,6 +288,8 @@ struct rule { const char *code; /* The code executed when this rule is reduced */ const char *codePrefix; /* Setup code before code[] above */ const char *codeSuffix; /* Breakdown code after code[] above */ + int noCode; /* True if this rule has no associated C code */ + int codeEmitted; /* True if the code has been emitted already */ struct symbol *precsym; /* Precedence symbol for this rule */ int index; /* An index number for this rule */ int iRule; /* Rule number as used in the generated tables */ @@ -349,7 +351,7 @@ struct state { struct config *bp; /* The basis configurations for this state */ struct config *cfp; /* All configurations in this set */ int statenum; /* Sequential number for this state */ - struct action *ap; /* Array of actions for this state */ + struct action *ap; /* List of actions for this state */ int nTknAct, nNtAct; /* Number of actions on terminals and nonterminals */ int iTknOfst, iNtOfst; /* yy_action[] offset for terminals and nonterms */ int iDfltReduce; /* Default action is to REDUCE by this rule */ @@ -1499,7 +1501,7 @@ static void handle_T_option(char *z){ lemon_strcpy(user_templatename, z); } -/* Merge together to lists of rules order by rule.iRule */ +/* Merge together to lists of rules ordered by rule.iRule */ static struct rule *Rule_merge(struct rule *pA, struct rule *pB){ struct rule *pFirst = 0; struct rule **ppPrev = &pFirst; @@ -1642,7 +1644,10 @@ int main(int argc, char **argv) for(i=1; ISUPPER(lem.symbols[i]->name[0]); i++); lem.nterminal = i; - /* Assign sequential rule numbers */ + /* Assign sequential rule numbers. Start with 0. Put rules that have no + ** reduce action C-code associated with them last, so that the switch() + ** statement that selects reduction actions will have a smaller jump table. + */ for(i=0, rp=lem.rule; rp; rp=rp->next){ rp->iRule = rp->code ? i++ : -1; } @@ -2211,6 +2216,7 @@ to follow the previous rule."); }else{ psp->prevrule->line = psp->tokenlineno; psp->prevrule->code = &x[1]; + psp->prevrule->noCode = 0; } }else if( x[0]=='[' ){ psp->state = PRECEDENCE_MARK_1; @@ -2317,6 +2323,7 @@ to follow the previous rule."); rp->lhsalias = psp->lhsalias; rp->nrhs = psp->nrhs; rp->code = 0; + rp->noCode = 1; rp->precsym = 0; rp->index = psp->gp->nrule++; rp->nextlhs = rp->lhs->rule; @@ -3527,9 +3534,8 @@ PRIVATE char *append_str(const char *zText, int n, int p1, int p2){ } /* -** zCode is a string that is the action associated with a rule. Expand -** the symbols in this string so that the refer to elements of the parser -** stack. +** Write and transform the rp->code string so that symbols are expanded. +** Populate the rp->codePrefix and rp->codeSuffix strings, as appropriate. ** ** Return 1 if the expanded code requires that "yylhsminor" local variable ** to be defined. @@ -3553,6 +3559,9 @@ PRIVATE int translate_code(struct lemon *lemp, struct rule *rp){ static char newlinestr[2] = { '\n', '\0' }; rp->code = newlinestr; rp->line = rp->ruleline; + rp->noCode = 1; + }else{ + rp->noCode = 0; } @@ -3568,6 +3577,7 @@ PRIVATE int translate_code(struct lemon *lemp, struct rule *rp){ append_str(" yy_destructor(yypParser,%d,&yymsp[%d].minor);\n", 0, rp->rhs[0]->index,1-rp->nrhs); rp->codePrefix = Strsafe(append_str(0,0,0,0)); + rp->noCode = 0; } }else if( rp->lhsalias==0 ){ /* There is no LHS value symbol. */ @@ -3715,7 +3725,10 @@ PRIVATE int translate_code(struct lemon *lemp, struct rule *rp){ /* Suffix code generation complete */ cp = append_str(0,0,0,0); - if( cp && cp[0] ) rp->codeSuffix = Strsafe(cp); + if( cp && cp[0] ){ + rp->codeSuffix = Strsafe(cp); + rp->noCode = 0; + } return rc; } @@ -4396,13 +4409,9 @@ void ReportTable( /* First output rules other than the default: rule */ for(rp=lemp->rule; rp; rp=rp->next){ struct rule *rp2; /* Other rules with the same action */ - if( rp->code==0 ) continue; - if( rp->code[0]=='\n' - && rp->code[1]==0 - && rp->codePrefix==0 - && rp->codeSuffix==0 - ){ - /* No actions, so this will be part of the "default:" rule */ + if( rp->codeEmitted ) continue; + if( rp->noCode ){ + /* No C code actions, so this will be part of the "default:" rule */ continue; } fprintf(out," case %d: /* ", rp->iRule); @@ -4414,21 +4423,19 @@ void ReportTable( fprintf(out," case %d: /* ", rp2->iRule); writeRuleText(out, rp2); fprintf(out," */ yytestcase(yyruleno==%d);\n", rp2->iRule); lineno++; - rp2->code = 0; + rp2->codeEmitted = 1; } } emit_code(out,rp,lemp,&lineno); fprintf(out," break;\n"); lineno++; - rp->code = 0; + rp->codeEmitted = 1; } /* Finally, output the default: rule. We choose as the default: all ** empty actions. */ fprintf(out," default:\n"); lineno++; for(rp=lemp->rule; rp; rp=rp->next){ - if( rp->code==0 ) continue; - assert( rp->code[0]=='\n' && rp->code[1]==0 ); - assert( rp->codePrefix==0 ); - assert( rp->codeSuffix==0 ); + if( rp->codeEmitted ) continue; + assert( rp->noCode ); fprintf(out," /* (%d) ", rp->iRule); writeRuleText(out, rp); fprintf(out, " */ yytestcase(yyruleno==%d);\n", rp->iRule); lineno++; From c173ad80119821b941a4615133f6f718051cf686 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 23 May 2016 16:15:02 +0000 Subject: [PATCH 0456/1484] Lemon enhancement: avoid unnecessary reduce actions that convert one non-terminal into another but have no side effects. FossilOrigin-Name: a86e782ad1aa6f5a8b2c54f9dcf0fa61960843f3 --- manifest | 12 ++++++------ manifest.uuid | 2 +- tool/lemon.c | 37 ++++++++++++++++++++++++++++++++++++- 3 files changed, 43 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 6ea5de70eb..7893a5758b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\scomment\stypos\sand\simprove\sclarity\sof\spresention\sin\sLemon.\s\sThe\soutput\nshould\sbe\sidentical. -D 2016-05-23T14:24:31.372 +C Lemon\senhancement:\savoid\sunnecessary\sreduce\sactions\sthat\sconvert\sone\nnon-terminal\sinto\sanother\sbut\shave\sno\sside\seffects. +D 2016-05-23T16:15:02.530 F Makefile.in f59e0763ff448719fc1bd25513882b0567286317 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7 @@ -1420,7 +1420,7 @@ F tool/fuzzershell.c 94019b185caceffc9f7c7b678a6489e42bc2aefa F tool/genfkey.README cf68fddd4643bbe3ff8e31b8b6d8b0a1b85e20f4 F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5 F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce -F tool/lemon.c b622032dd14dc1315fedb81d73f4658354329fca +F tool/lemon.c b4da2f0181b4defe538eb437eb96c721cf342d39 F tool/lempar.c 404ea3dc27dbeed343f0e61b1d36e97b9f5f0fb6 F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862 F tool/logest.c 11346aa019e2e77a00902aa7d0cabd27bd2e8cca @@ -1492,7 +1492,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 90411a28168f6dacf08242a25bed7d6269041417 -R 996821eb90ee3795d9bf03c89106b9e7 +P b91a5b8297756289d45c8fce0d3399c253517eb0 +R e62078de0c6378c8386e96fef92b2fe6 U drh -Z b4115b7928b4702f985a5c5bf63f70fa +Z f3f44e1ca319aa39a93bd7b358420b1f diff --git a/manifest.uuid b/manifest.uuid index 3a567c6fc6..4af496871d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b91a5b8297756289d45c8fce0d3399c253517eb0 \ No newline at end of file +a86e782ad1aa6f5a8b2c54f9dcf0fa61960843f3 \ No newline at end of file diff --git a/tool/lemon.c b/tool/lemon.c index 2ad36eec4a..d643b341e4 100644 --- a/tool/lemon.c +++ b/tool/lemon.c @@ -341,6 +341,7 @@ struct action { struct state *stp; /* The new state, if a shift */ struct rule *rp; /* The rule, if a reduce */ } x; + struct symbol *spOpt; /* SHIFTREDUCE optimization to this symbol */ struct action *next; /* Next action for this state */ struct action *collide; /* Next action with the same hash */ }; @@ -532,6 +533,7 @@ void Action_add( *app = newaction; newaction->type = type; newaction->sp = sp; + newaction->spOpt = 0; if( type==SHIFT ){ newaction->x.stp = (struct state *)arg; }else{ @@ -3167,6 +3169,9 @@ int PrintAction( result = 0; break; } + if( result && ap->spOpt ){ + fprintf(fp," /* because %s==%s */", ap->sp->name, ap->spOpt->name); + } return result; } @@ -4509,7 +4514,7 @@ void ReportHeader(struct lemon *lemp) void CompressTables(struct lemon *lemp) { struct state *stp; - struct action *ap, *ap2; + struct action *ap, *ap2, *nextap; struct rule *rp, *rp2, *rbest; int nbest, n; int i; @@ -4586,6 +4591,36 @@ void CompressTables(struct lemon *lemp) } } } + + /* If a SHIFTREDUCE action specifies a rule that has a single RHS term + ** (meaning that the SHIFTREDUCE will land back in the state where it + ** started) and if there is no C-code associated with the reduce action, + ** then we can go ahead and convert the action to be the same as the + ** action for the RHS of the rule. + */ + for(i=0; instate; i++){ + stp = lemp->sorted[i]; + for(ap=stp->ap; ap; ap=nextap){ + nextap = ap->next; + if( ap->type!=SHIFTREDUCE ) continue; + rp = ap->x.rp; + if( rp->noCode==0 ) continue; + if( rp->nrhs!=1 ) continue; +#if 1 + /* Only apply this optimization to non-terminals. It would be OK to + ** apply it to terminal symbols too, but that makes the parser tables + ** larger. */ + if( ap->sp->indexnterminal ) continue; +#endif + /* If we reach this point, it means the optimization can be applied */ + nextap = ap; + for(ap2=stp->ap; ap2 && (ap2==ap || ap2->sp!=rp->lhs); ap2=ap2->next){} + assert( ap2!=0 ); + ap->spOpt = ap2->sp; + ap->type = ap2->type; + ap->x = ap2->x; + } + } } From 5782bc27fa701e827f26cd1140531a1fa6652be5 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 23 May 2016 16:16:13 +0000 Subject: [PATCH 0457/1484] Improve the error messages generated by the rtree module when a constraint fails. FossilOrigin-Name: 3ad2531efb64b7c53b777ddf3681203217052b32 --- ext/rtree/rtree.c | 53 ++++++++++++++++++++++++++++++++++++++++--- ext/rtree/rtree1.test | 20 ++++++++-------- ext/rtree/rtree3.test | 31 ++++++++++++++++++++++++- manifest | 18 +++++++-------- manifest.uuid | 2 +- 5 files changed, 101 insertions(+), 23 deletions(-) diff --git a/ext/rtree/rtree.c b/ext/rtree/rtree.c index 012c48d6d1..311824aa85 100644 --- a/ext/rtree/rtree.c +++ b/ext/rtree/rtree.c @@ -2800,6 +2800,53 @@ static RtreeValue rtreeValueUp(sqlite3_value *v){ } #endif /* !defined(SQLITE_RTREE_INT_ONLY) */ +/* +** A constraint has failed while inserting a row into an rtree table. +** Assuming no OOM error occurs, this function sets the error message +** (at pRtree->base.zErrMsg) to an appropriate value and returns +** SQLITE_CONSTRAINT. +** +** Parameter iCol is the index of the leftmost column involved in the +** constraint failure. If it is 0, then the constraint that failed is +** the unique constraint on the id column. Otherwise, it is the rtree +** (c1<=c2) constraint on columns iCol and iCol+1 that has failed. +** +** If an OOM occurs, SQLITE_NOMEM is returned instead of SQLITE_CONSTRAINT. +*/ +static int rtreeConstraintError(Rtree *pRtree, int iCol){ + sqlite3_stmt *pStmt = 0; + char *zSql; + int rc; + + assert( iCol==0 || iCol%2 ); + zSql = sqlite3_mprintf("SELECT * FROM %Q.%Q", pRtree->zDb, pRtree->zName); + if( zSql ){ + rc = sqlite3_prepare_v2(pRtree->db, zSql, -1, &pStmt, 0); + }else{ + rc = SQLITE_NOMEM; + } + sqlite3_free(zSql); + + if( rc==SQLITE_OK ){ + if( iCol==0 ){ + const char *zCol = sqlite3_column_name(pStmt, 0); + pRtree->base.zErrMsg = sqlite3_mprintf( + "UNIQUE constraint failed: %s.%s", pRtree->zName, zCol + ); + }else{ + const char *zCol1 = sqlite3_column_name(pStmt, iCol); + const char *zCol2 = sqlite3_column_name(pStmt, iCol+1); + pRtree->base.zErrMsg = sqlite3_mprintf( + "rtree constraint failed: %s.(%s<=%s)", pRtree->zName, zCol1, zCol2 + ); + } + } + + sqlite3_finalize(pStmt); + return (rc==SQLITE_OK ? SQLITE_CONSTRAINT : rc); +} + + /* ** The xUpdate method for rtree module virtual tables. @@ -2850,7 +2897,7 @@ static int rtreeUpdate( cell.aCoord[ii].f = rtreeValueDown(azData[ii+3]); cell.aCoord[ii+1].f = rtreeValueUp(azData[ii+4]); if( cell.aCoord[ii].f>cell.aCoord[ii+1].f ){ - rc = SQLITE_CONSTRAINT; + rc = rtreeConstraintError(pRtree, ii+1); goto constraint; } } @@ -2861,7 +2908,7 @@ static int rtreeUpdate( cell.aCoord[ii].i = sqlite3_value_int(azData[ii+3]); cell.aCoord[ii+1].i = sqlite3_value_int(azData[ii+4]); if( cell.aCoord[ii].i>cell.aCoord[ii+1].i ){ - rc = SQLITE_CONSTRAINT; + rc = rtreeConstraintError(pRtree, ii+1); goto constraint; } } @@ -2882,7 +2929,7 @@ static int rtreeUpdate( if( sqlite3_vtab_on_conflict(pRtree->db)==SQLITE_REPLACE ){ rc = rtreeDeleteRowid(pRtree, cell.iRowid); }else{ - rc = SQLITE_CONSTRAINT; + rc = rtreeConstraintError(pRtree, 0); goto constraint; } } diff --git a/ext/rtree/rtree1.test b/ext/rtree/rtree1.test index c9192de192..9dc101a7b2 100644 --- a/ext/rtree/rtree1.test +++ b/ext/rtree/rtree1.test @@ -194,13 +194,13 @@ do_test rtree-2.1.3 { do_test rtree-2.2.1 { catchsql { INSERT INTO t1 VALUES(2, 1, 3, 2, 4) } -} {1 {constraint failed}} +} {1 {UNIQUE constraint failed: t1.ii}} do_test rtree-2.2.2 { catchsql { INSERT INTO t1 VALUES(4, 1, 3, 4, 2) } -} {1 {constraint failed}} +} {1 {rtree constraint failed: t1.(y1<=y2)}} do_test rtree-2.2.3 { catchsql { INSERT INTO t1 VALUES(4, 3, 1, 2, 4) } -} {1 {constraint failed}} +} {1 {rtree constraint failed: t1.(x1<=x2)}} do_test rtree-2.2.4 { execsql { SELECT ii FROM t1 ORDER BY ii } } {1 2 3} @@ -236,7 +236,7 @@ do_test rtree-3.1.3 { # Test the constraint on the coordinates (c[i]<=c[i+1] where (i%2==0)): do_test rtree-3.2.1 { catchsql { INSERT INTO t1 VALUES(7, 2, 6, 4, 3) } -} {1 {constraint failed}} +} {1 {rtree constraint failed: t1.(y1<=y2)}} do_test rtree-3.2.2 { catchsql { INSERT INTO t1 VALUES(8, 2, 6, 3, 3) } } {0 {}} @@ -490,11 +490,11 @@ foreach {tn sql_template testdata} { } 4 "INSERT %CONF% INTO t1 VALUES(2, 7, 6, 7, 7)" { - ROLLBACK 0 1 {1 1 2 3 4 2 2 3 4 5 3 3 4 5 6} - ABORT 0 1 {1 1 2 3 4 2 2 3 4 5 3 3 4 5 6 4 4 5 6 7} + ROLLBACK 0 2 {1 1 2 3 4 2 2 3 4 5 3 3 4 5 6} + ABORT 0 2 {1 1 2 3 4 2 2 3 4 5 3 3 4 5 6 4 4 5 6 7} IGNORE 0 0 {1 1 2 3 4 2 2 3 4 5 3 3 4 5 6 4 4 5 6 7} - FAIL 0 1 {1 1 2 3 4 2 2 3 4 5 3 3 4 5 6 4 4 5 6 7} - REPLACE 0 1 {1 1 2 3 4 2 2 3 4 5 3 3 4 5 6 4 4 5 6 7} + FAIL 0 2 {1 1 2 3 4 2 2 3 4 5 3 3 4 5 6 4 4 5 6 7} + REPLACE 0 2 {1 1 2 3 4 2 2 3 4 5 3 3 4 5 6 4 4 5 6 7} } } { @@ -510,7 +510,9 @@ foreach {tn sql_template testdata} { } set res(0) {0 {}} - set res(1) {1 {constraint failed}} + set res(1) {1 {UNIQUE constraint failed: t1.idx}} + set res(2) {1 {rtree constraint failed: t1.(x1<=x2)}} + do_catchsql_test $testname.1 $sql $res($error) do_test $testname.2 [list sql_uses_stmt db $sql] $uses do_execsql_test $testname.3 { SELECT * FROM t1 ORDER BY idx } $data diff --git a/ext/rtree/rtree3.test b/ext/rtree/rtree3.test index fea5513069..1d863c6cc2 100644 --- a/ext/rtree/rtree3.test +++ b/ext/rtree/rtree3.test @@ -47,7 +47,8 @@ ifcapable !rtree { # # rtree3-8: Test OOM while registering the r-tree module with sqlite. # - +# rtree3-11: OOM following a constraint failure +# do_faultsim_test rtree3-1 -faults oom* -prep { faultsim_delete_and_reopen } -body { @@ -234,4 +235,32 @@ do_faultsim_test rtree3-10 -faults oom-* -prep { faultsim_test_result {0 2} } + +do_test rtree3-11.prep { + faultsim_delete_and_reopen + execsql { + CREATE VIRTUAL TABLE rt USING rtree(ii, x1, x2, y1, y2); + INSERT INTO rt VALUES(1, 2, 3, 4, 5); + } + faultsim_save_and_close +} {} +do_faultsim_test rtree3-10.1 -faults oom-* -prep { + faultsim_restore_and_reopen + execsql { SELECT * FROM rt } +} -body { + execsql { INSERT INTO rt VALUES(1, 2, 3, 4, 5) } +} -test { + faultsim_test_result {1 {UNIQUE constraint failed: rt.ii}} \ + {1 {constraint failed}} +} +do_faultsim_test rtree3-10.2 -faults oom-* -prep { + faultsim_restore_and_reopen + execsql { SELECT * FROM rt } +} -body { + execsql { INSERT INTO rt VALUES(2, 2, 3, 5, 4) } +} -test { + faultsim_test_result {1 {rtree constraint failed: rt.(y1<=y2)}} \ + {1 {constraint failed}} +} + finish_test diff --git a/manifest b/manifest index 7893a5758b..1f97ff1987 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Lemon\senhancement:\savoid\sunnecessary\sreduce\sactions\sthat\sconvert\sone\nnon-terminal\sinto\sanother\sbut\shave\sno\sside\seffects. -D 2016-05-23T16:15:02.530 +C Improve\sthe\serror\smessages\sgenerated\sby\sthe\srtree\smodule\swhen\sa\sconstraint\sfails. +D 2016-05-23T16:16:13.470 F Makefile.in f59e0763ff448719fc1bd25513882b0567286317 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7 @@ -253,11 +253,11 @@ F ext/rbu/sqlite3rbu.c bf36625990c6865ecf08bd844d8097ed2d0a6958 F ext/rbu/sqlite3rbu.h 2acd0a6344a6079de15c8dc9d84d3df83a665930 F ext/rbu/test_rbu.c 9bbdf6bd8efd58fbc4f192698df50569598fbb9e F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 -F ext/rtree/rtree.c 0b870ccb7b58b734a2a8e1e2755a7c0ded070920 +F ext/rtree/rtree.c 7ebca7d18261f402d67de9e151be7fb2ed62b8f5 F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e -F ext/rtree/rtree1.test 96a80c08440c932cd72aac50660e7af2612d2cda +F ext/rtree/rtree1.test 42dadfc7b44a436cd74a1bebc0b9b689e4eaf7ec F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba -F ext/rtree/rtree3.test a494da55c30ee0bc9b01a91c80c81b387b22d2dc +F ext/rtree/rtree3.test 2cafe8265d1ff28f206fce88d114f208349df482 F ext/rtree/rtree4.test c8fe384f60ebd49540a5fecc990041bf452eb6e0 F ext/rtree/rtree5.test 6a510494f12454bf57ef28f45bc7764ea279431e F ext/rtree/rtree6.test 773a90db2dce6a8353dd0d5b64bca69b29761196 @@ -1492,7 +1492,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b91a5b8297756289d45c8fce0d3399c253517eb0 -R e62078de0c6378c8386e96fef92b2fe6 -U drh -Z f3f44e1ca319aa39a93bd7b358420b1f +P a86e782ad1aa6f5a8b2c54f9dcf0fa61960843f3 +R 656cb7a661842081cb14458e0c90ff63 +U dan +Z 1b4990ccdee5b0865b4104871945d857 diff --git a/manifest.uuid b/manifest.uuid index 4af496871d..194d4c4259 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a86e782ad1aa6f5a8b2c54f9dcf0fa61960843f3 \ No newline at end of file +3ad2531efb64b7c53b777ddf3681203217052b32 \ No newline at end of file From daa14559d207528cb76b1b58c32e0a4a479aa41e Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 23 May 2016 18:06:51 +0000 Subject: [PATCH 0458/1484] Remove an extra "finish_test" from the end of rtreeC.test. FossilOrigin-Name: bfbb6dd84b5e1335e1eae857a03fa33a71fd67a5 --- ext/rtree/rtreeC.test | 4 ---- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 8 insertions(+), 12 deletions(-) diff --git a/ext/rtree/rtreeC.test b/ext/rtree/rtreeC.test index 9a64df51d5..a26c401e0d 100644 --- a/ext/rtree/rtreeC.test +++ b/ext/rtree/rtreeC.test @@ -350,7 +350,3 @@ do_eqp_execsql_test 7.4 { } finish_test - - - -finish_test diff --git a/manifest b/manifest index 1f97ff1987..1cbb8b0021 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improve\sthe\serror\smessages\sgenerated\sby\sthe\srtree\smodule\swhen\sa\sconstraint\sfails. -D 2016-05-23T16:16:13.470 +C Remove\san\sextra\s"finish_test"\sfrom\sthe\send\sof\srtreeC.test. +D 2016-05-23T18:06:51.504 F Makefile.in f59e0763ff448719fc1bd25513882b0567286317 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7 @@ -266,7 +266,7 @@ F ext/rtree/rtree8.test db79c812f9e4a11f9b1f3f9934007884610a713a F ext/rtree/rtree9.test b5eb13849545dfd271a54ff16784cb00d8792aea F ext/rtree/rtreeA.test ace05e729a36e342d40cf94e9efc7b4723d9dcdf F ext/rtree/rtreeB.test c85f9ce78766c4e68b8b89fbf2979ee9cfa82b4e -F ext/rtree/rtreeC.test 90aaaffe2fd4f0dcd12289cad5515f6d41f45ffd +F ext/rtree/rtreeC.test c0a9c67f2efa98b6fae12acb8a28348d231a481d F ext/rtree/rtreeD.test 636630357638f5983701550b37f0f5867130d2ca F ext/rtree/rtreeE.test 45a147a64a76306172819562309681d8e90f94bb F ext/rtree/rtreeF.test 66deb9fd1611c7ca2e374adba63debdc2dbb12b4 @@ -1492,7 +1492,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a86e782ad1aa6f5a8b2c54f9dcf0fa61960843f3 -R 656cb7a661842081cb14458e0c90ff63 -U dan -Z 1b4990ccdee5b0865b4104871945d857 +P 3ad2531efb64b7c53b777ddf3681203217052b32 +R 181417728ff7d20d7df6a3bbac1c99fc +U drh +Z a9812f920562a373e5ac292c844442d4 diff --git a/manifest.uuid b/manifest.uuid index 194d4c4259..9fff038e15 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3ad2531efb64b7c53b777ddf3681203217052b32 \ No newline at end of file +bfbb6dd84b5e1335e1eae857a03fa33a71fd67a5 \ No newline at end of file From e62c2fe1795bb87994fbe068e19a5494cd088715 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 23 May 2016 18:12:04 +0000 Subject: [PATCH 0459/1484] Fix RTREE so that it does not run queries against the sqlite_stat1 if that table does not exist. FossilOrigin-Name: 48526a2fe5373e3d19e8b813cc8a342d6b7c9c3d --- ext/rtree/rtree.c | 5 +++++ ext/rtree/rtreeG.test | 34 ++++++++++++++++++++++++++++++++++ manifest | 13 +++++++------ manifest.uuid | 2 +- 4 files changed, 47 insertions(+), 7 deletions(-) create mode 100644 ext/rtree/rtreeG.test diff --git a/ext/rtree/rtree.c b/ext/rtree/rtree.c index 311824aa85..fc69acd6fa 100644 --- a/ext/rtree/rtree.c +++ b/ext/rtree/rtree.c @@ -3012,6 +3012,11 @@ static int rtreeQueryStat1(sqlite3 *db, Rtree *pRtree){ int rc; i64 nRow = 0; + if( sqlite3_table_column_metadata(db,pRtree->zDb,"sqlite_stat1", + 0,0,0,0,0,0)==SQLITE_ERROR ){ + pRtree->nRowEst = RTREE_DEFAULT_ROWEST; + return SQLITE_OK; + } zSql = sqlite3_mprintf(zFmt, pRtree->zDb, pRtree->zName); if( zSql==0 ){ rc = SQLITE_NOMEM; diff --git a/ext/rtree/rtreeG.test b/ext/rtree/rtreeG.test new file mode 100644 index 0000000000..035822e4df --- /dev/null +++ b/ext/rtree/rtreeG.test @@ -0,0 +1,34 @@ +# 2016-05-32 +# +# 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 contains tests for the r-tree module. +# +# Verify that no invalid SQL is run during initialization + +if {![info exists testdir]} { + set testdir [file join [file dirname [info script]] .. .. test] +} +source $testdir/tester.tcl +ifcapable !rtree { finish_test ; return } + +db close +sqlite3_shutdown +test_sqlite3_log [list lappend ::log] +set ::log [list] +sqlite3 db test.db + + +set ::log {} +do_test rtreeG-1.1 { + db eval {CREATE VIRTUAL TABLE t1 USING rtree(a,b,c);} + set ::log +} {} + +finish_test diff --git a/manifest b/manifest index 1cbb8b0021..3d248c5ee4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\san\sextra\s"finish_test"\sfrom\sthe\send\sof\srtreeC.test. -D 2016-05-23T18:06:51.504 +C Fix\sRTREE\sso\sthat\sit\sdoes\snot\srun\squeries\sagainst\sthe\ssqlite_stat1\sif\sthat\ntable\sdoes\snot\sexist. +D 2016-05-23T18:12:04.371 F Makefile.in f59e0763ff448719fc1bd25513882b0567286317 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7 @@ -253,7 +253,7 @@ F ext/rbu/sqlite3rbu.c bf36625990c6865ecf08bd844d8097ed2d0a6958 F ext/rbu/sqlite3rbu.h 2acd0a6344a6079de15c8dc9d84d3df83a665930 F ext/rbu/test_rbu.c 9bbdf6bd8efd58fbc4f192698df50569598fbb9e F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 -F ext/rtree/rtree.c 7ebca7d18261f402d67de9e151be7fb2ed62b8f5 +F ext/rtree/rtree.c d26a815b0df1c412a6881dae8d7fd3c9c08cce68 F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e F ext/rtree/rtree1.test 42dadfc7b44a436cd74a1bebc0b9b689e4eaf7ec F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba @@ -270,6 +270,7 @@ F ext/rtree/rtreeC.test c0a9c67f2efa98b6fae12acb8a28348d231a481d F ext/rtree/rtreeD.test 636630357638f5983701550b37f0f5867130d2ca F ext/rtree/rtreeE.test 45a147a64a76306172819562309681d8e90f94bb F ext/rtree/rtreeF.test 66deb9fd1611c7ca2e374adba63debdc2dbb12b4 +F ext/rtree/rtreeG.test fad67b4ec080cbe41bafb68517361b74ac4632d5 F ext/rtree/rtree_perf.tcl 6c18c1f23cd48e0f948930c98dfdd37dfccb5195 F ext/rtree/rtree_util.tcl 06aab2ed5b826545bf215fff90ecb9255a8647ea F ext/rtree/sqlite3rtree.h 9c5777af3d2921c7b4ae4954e8e5697502289d28 @@ -1492,7 +1493,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 3ad2531efb64b7c53b777ddf3681203217052b32 -R 181417728ff7d20d7df6a3bbac1c99fc +P bfbb6dd84b5e1335e1eae857a03fa33a71fd67a5 +R 917b797124e2db7975ec6ce19d0d3f10 U drh -Z a9812f920562a373e5ac292c844442d4 +Z 1720c00f1c890b6da656d7cb35d019e7 diff --git a/manifest.uuid b/manifest.uuid index 9fff038e15..1a5b947ac2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bfbb6dd84b5e1335e1eae857a03fa33a71fd67a5 \ No newline at end of file +48526a2fe5373e3d19e8b813cc8a342d6b7c9c3d \ No newline at end of file From f1e2c8e1ff8af08e2132dcdf2dd296abd8172b61 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 23 May 2016 18:27:07 +0000 Subject: [PATCH 0460/1484] Fix the rtreeG.test test case. FossilOrigin-Name: 9589e9377118efc356c73ea1aab2d7e6c2f7fc36 --- ext/rtree/rtreeG.test | 36 ++++++++++++++++++++++++++++++++++-- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 41 insertions(+), 9 deletions(-) diff --git a/ext/rtree/rtreeG.test b/ext/rtree/rtreeG.test index 035822e4df..bffd17ecaa 100644 --- a/ext/rtree/rtreeG.test +++ b/ext/rtree/rtreeG.test @@ -26,9 +26,41 @@ sqlite3 db test.db set ::log {} -do_test rtreeG-1.1 { - db eval {CREATE VIRTUAL TABLE t1 USING rtree(a,b,c);} +do_execsql_test rtreeG-1.1 { + CREATE VIRTUAL TABLE t1 USING rtree(id,x0,x1,y0,y1); +} {} +do_test rtreeG-1.1log { set ::log } {} +do_execsql_test rtreeG-1.2 { + INSERT INTO t1 VALUES(1,10,15,5,23),(2,20,21,5,23),(3,10,15,20,30); + SELECT id from t1 WHERE x0>8 AND x1<16 AND y0>2 AND y1<25; +} {1} +do_test rtreeG-1.2log { + set ::log +} {} + +db close +sqlite3 db test.db +do_execsql_test rtreeG-1.3 { + SELECT id from t1 WHERE x0>8 AND x1<16 AND y0>2 AND y1<25; +} {1} +do_test rtreeG-1.3log { + set ::log +} {} + +do_execsql_test rtreeG-1.4 { + DROP TABLE t1; +} {} +do_test rtreeG-1.4log { + set ::log +} {} + +db close +sqlite3_shutdown +test_sqlite3_log +sqlite3_initialize +sqlite3 db test.db + finish_test diff --git a/manifest b/manifest index 3d248c5ee4..92ddb98a9d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sRTREE\sso\sthat\sit\sdoes\snot\srun\squeries\sagainst\sthe\ssqlite_stat1\sif\sthat\ntable\sdoes\snot\sexist. -D 2016-05-23T18:12:04.371 +C Fix\sthe\srtreeG.test\stest\scase. +D 2016-05-23T18:27:07.523 F Makefile.in f59e0763ff448719fc1bd25513882b0567286317 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7 @@ -270,7 +270,7 @@ F ext/rtree/rtreeC.test c0a9c67f2efa98b6fae12acb8a28348d231a481d F ext/rtree/rtreeD.test 636630357638f5983701550b37f0f5867130d2ca F ext/rtree/rtreeE.test 45a147a64a76306172819562309681d8e90f94bb F ext/rtree/rtreeF.test 66deb9fd1611c7ca2e374adba63debdc2dbb12b4 -F ext/rtree/rtreeG.test fad67b4ec080cbe41bafb68517361b74ac4632d5 +F ext/rtree/rtreeG.test 3b185719630795f38594f64cd7d1de86a33f91f1 F ext/rtree/rtree_perf.tcl 6c18c1f23cd48e0f948930c98dfdd37dfccb5195 F ext/rtree/rtree_util.tcl 06aab2ed5b826545bf215fff90ecb9255a8647ea F ext/rtree/sqlite3rtree.h 9c5777af3d2921c7b4ae4954e8e5697502289d28 @@ -1493,7 +1493,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P bfbb6dd84b5e1335e1eae857a03fa33a71fd67a5 -R 917b797124e2db7975ec6ce19d0d3f10 +P 48526a2fe5373e3d19e8b813cc8a342d6b7c9c3d +R f2db7693c08d0e8ea5e5a43c2bcc91ff U drh -Z 1720c00f1c890b6da656d7cb35d019e7 +Z 8e18f408557ba2afd41610ebc5947af3 diff --git a/manifest.uuid b/manifest.uuid index 1a5b947ac2..d9e8077dfc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -48526a2fe5373e3d19e8b813cc8a342d6b7c9c3d \ No newline at end of file +9589e9377118efc356c73ea1aab2d7e6c2f7fc36 \ No newline at end of file From 118ab6585988ff97286fcb49b5500d31d6ddc218 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 23 May 2016 21:56:24 +0000 Subject: [PATCH 0461/1484] Use a pointer to the top of the stack rather than an index into the stack in the Lemon-generated parser template, for about 6.6% parser performance gain. FossilOrigin-Name: 3c2a770549d5bb65fcd6cc684e0a0ae6d641ac68 --- manifest | 13 +++---- manifest.uuid | 2 +- tool/lempar.c | 101 +++++++++++++++++++++++++++----------------------- 3 files changed, 62 insertions(+), 54 deletions(-) diff --git a/manifest b/manifest index f7ff8f22bc..8f4a53f747 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sa\sminor\serror\smessage\swhen\srunning\sRTREE\swithout\san\ssqlite_stat1\stable. -D 2016-05-23T19:02:58.893 +C Use\sa\spointer\sto\sthe\stop\sof\sthe\sstack\srather\sthan\san\sindex\sinto\sthe\sstack\nin\sthe\sLemon-generated\sparser\stemplate,\sfor\sabout\s6.6%\sparser\sperformance\sgain. +D 2016-05-23T21:56:24.427 F Makefile.in f59e0763ff448719fc1bd25513882b0567286317 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7 @@ -1422,7 +1422,7 @@ F tool/genfkey.README cf68fddd4643bbe3ff8e31b8b6d8b0a1b85e20f4 F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5 F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce F tool/lemon.c b4da2f0181b4defe538eb437eb96c721cf342d39 -F tool/lempar.c 404ea3dc27dbeed343f0e61b1d36e97b9f5f0fb6 +F tool/lempar.c 872383ebf36c13fdaff0f3692d4ff60e64ec49e2 F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862 F tool/logest.c 11346aa019e2e77a00902aa7d0cabd27bd2e8cca F tool/mkautoconfamal.sh e855df211ecbcc7131dee817110ff386cfb112f7 @@ -1493,8 +1493,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 3ad2531efb64b7c53b777ddf3681203217052b32 9589e9377118efc356c73ea1aab2d7e6c2f7fc36 -R f2db7693c08d0e8ea5e5a43c2bcc91ff -T +closed 9589e9377118efc356c73ea1aab2d7e6c2f7fc36 +P 276e92f5b4c1ee49eabb738b24d73d7af90fb13c +R f3a217ca3fc6adf56f5cf5443069e03b U drh -Z 97b14e25d3ed8655aacd892bebd6d043 +Z babb89b922e84c6e93d4048989d7622c diff --git a/manifest.uuid b/manifest.uuid index 9ebd599e42..9a4a91d8af 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -276e92f5b4c1ee49eabb738b24d73d7af90fb13c \ No newline at end of file +3c2a770549d5bb65fcd6cc684e0a0ae6d641ac68 \ No newline at end of file diff --git a/tool/lempar.c b/tool/lempar.c index e313904082..b02fd21b77 100644 --- a/tool/lempar.c +++ b/tool/lempar.c @@ -203,9 +203,9 @@ typedef struct yyStackEntry yyStackEntry; /* The state of the parser is completely contained in an instance of ** the following structure */ struct yyParser { - int yyidx; /* Index of top element in stack */ + yyStackEntry *yytos; /* Pointer to top element of the stack */ #ifdef YYTRACKMAXSTACKDEPTH - int yyidxMax; /* Maximum value of yyidx */ + int yyhwm; /* High-water mark of the stack */ #endif #ifndef YYNOERRORRECOVERY int yyerrcnt; /* Shifts left before out of the error */ @@ -317,9 +317,9 @@ void *ParseAlloc(void *(*mallocProc)(YYMALLOCARGTYPE)){ yyParser *pParser; pParser = (yyParser*)(*mallocProc)( (YYMALLOCARGTYPE)sizeof(yyParser) ); if( pParser ){ - pParser->yyidx = -1; + pParser->yytos = 0; #ifdef YYTRACKMAXSTACKDEPTH - pParser->yyidxMax = 0; + pParser->yyhwm = 0; #endif #if YYSTACKDEPTH<=0 pParser->yystack = NULL; @@ -369,8 +369,8 @@ static void yy_destructor( */ static void yy_pop_parser_stack(yyParser *pParser){ yyStackEntry *yytos; - assert( pParser->yyidx>=0 ); - yytos = &pParser->yystack[pParser->yyidx--]; + assert( pParser->yytos!=0 ); + yytos = pParser->yytos--; #ifndef NDEBUG if( yyTraceFILE ){ fprintf(yyTraceFILE,"%sPopping %s\n", @@ -397,7 +397,7 @@ void ParseFree( #ifndef YYPARSEFREENEVERNULL if( pParser==0 ) return; #endif - while( pParser->yyidx>=0 ) yy_pop_parser_stack(pParser); + while( pParser->yytos>=pParser->yystack ) yy_pop_parser_stack(pParser); #if YYSTACKDEPTH<=0 free(pParser->yystack); #endif @@ -410,7 +410,7 @@ void ParseFree( #ifdef YYTRACKMAXSTACKDEPTH int ParseStackPeak(void *p){ yyParser *pParser = (yyParser*)p; - return pParser->yyidxMax; + return pParser->yyhwm; } #endif @@ -423,7 +423,7 @@ static unsigned int yy_find_shift_action( YYCODETYPE iLookAhead /* The look-ahead token */ ){ int i; - int stateno = pParser->yystack[pParser->yyidx].stateno; + int stateno = pParser->yytos->stateno; if( stateno>=YY_MIN_REDUCE ) return stateno; assert( stateno <= YY_SHIFT_COUNT ); @@ -516,13 +516,13 @@ static int yy_find_reduce_action( */ static void yyStackOverflow(yyParser *yypParser){ ParseARG_FETCH; - yypParser->yyidx--; + yypParser->yytos--; #ifndef NDEBUG if( yyTraceFILE ){ fprintf(yyTraceFILE,"%sStack Overflow!\n",yyTracePrompt); } #endif - while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser); + while( yypParser->yytos>=yypParser->yystack ) yy_pop_parser_stack(yypParser); /* Here code is inserted which will execute if the parser ** stack every overflows */ /******** Begin %stack_overflow code ******************************************/ @@ -539,11 +539,11 @@ static void yyTraceShift(yyParser *yypParser, int yyNewState){ if( yyTraceFILE ){ if( yyNewStateyystack[yypParser->yyidx].major], + yyTracePrompt,yyTokenName[yypParser->yytos->major], yyNewState); }else{ fprintf(yyTraceFILE,"%sShift '%s'\n", - yyTracePrompt,yyTokenName[yypParser->yystack[yypParser->yyidx].major]); + yyTracePrompt,yyTokenName[yypParser->yytos->major]); } } } @@ -561,27 +561,28 @@ static void yy_shift( ParseTOKENTYPE yyMinor /* The minor token to shift in */ ){ yyStackEntry *yytos; - yypParser->yyidx++; + yypParser->yytos++; #ifdef YYTRACKMAXSTACKDEPTH - if( yypParser->yyidx>yypParser->yyidxMax ){ - yypParser->yyidxMax = yypParser->yyidx; + if( (int)(yypParser->yytos - yypParser->yystack)>yypParser->yyhwm ){ + yypParser->yyhwm++; + assert( yypParser->yyhwm == (int)(yypParser->yytos - yypParser->yystack) ); } #endif #if YYSTACKDEPTH>0 - if( yypParser->yyidx>=YYSTACKDEPTH ){ + if( yypParser->yytos>=&yypParser->yystack[YYSTACKDEPTH] ){ yyStackOverflow(yypParser); return; } #else - if( yypParser->yyidx>=yypParser->yystksz ){ + if( yypParser->yytos>=&yypParser->yystack[yypParser->yystksz] ){ yyGrowStack(yypParser); - if( yypParser->yyidx>=yypParser->yystksz ){ + if( yypParser->yytos>=&yypParser->yystach[yypParser->yystksz] ){ yyStackOverflow(yypParser); return; } } #endif - yytos = &yypParser->yystack[yypParser->yyidx]; + yytos = yypParser->yytos; yytos->stateno = (YYACTIONTYPE)yyNewState; yytos->major = (YYCODETYPE)yyMajor; yytos->minor.yy0 = yyMinor; @@ -613,7 +614,7 @@ static void yy_reduce( yyStackEntry *yymsp; /* The top of the parser's stack */ int yysize; /* Amount to pop the stack */ ParseARG_FETCH; - yymsp = &yypParser->yystack[yypParser->yyidx]; + yymsp = yypParser->yytos; #ifndef NDEBUG if( yyTraceFILE && yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ){ yysize = yyRuleInfo[yyruleno].nrhs; @@ -627,19 +628,20 @@ static void yy_reduce( ** enough on the stack to push the LHS value */ if( yyRuleInfo[yyruleno].nrhs==0 ){ #ifdef YYTRACKMAXSTACKDEPTH - if( yypParser->yyidx>yypParser->yyidxMax ){ - yypParser->yyidxMax = yypParser->yyidx; + if( (int)(yypParser->yytos - yypParser->yystack)>yypParser->yyhwm ){ + yypParser->yyhwm++; + assert( yypParser->yyhwm == (int)(yypParser->yytos - yypParser->yystack)); } #endif #if YYSTACKDEPTH>0 - if( yypParser->yyidx>=YYSTACKDEPTH-1 ){ + if( yypParser->yytos>=&yypParser->yystack[YYSTACKDEPTH-1] ){ yyStackOverflow(yypParser); return; } #else - if( yypParser->yyidx>=yypParser->yystksz-1 ){ + if( yypParser->yytos>=&yypParser->yystack[yypParser->yystksz-1] ){ yyGrowStack(yypParser); - if( yypParser->yyidx>=yypParser->yystksz-1 ){ + if( yypParser->yytos>=&yypParser->yystack[yypParser->yystksz-1] ){ yyStackOverflow(yypParser); return; } @@ -665,15 +667,17 @@ static void yy_reduce( yysize = yyRuleInfo[yyruleno].nrhs; yyact = yy_find_reduce_action(yymsp[-yysize].stateno,(YYCODETYPE)yygoto); if( yyact <= YY_MAX_SHIFTREDUCE ){ - if( yyact>YY_MAX_SHIFT ) yyact += YY_MIN_REDUCE - YY_MIN_SHIFTREDUCE; - yypParser->yyidx -= yysize - 1; + if( yyact>YY_MAX_SHIFT ){ + yyact += YY_MIN_REDUCE - YY_MIN_SHIFTREDUCE; + } yymsp -= yysize-1; + yypParser->yytos = yymsp; yymsp->stateno = (YYACTIONTYPE)yyact; yymsp->major = (YYCODETYPE)yygoto; yyTraceShift(yypParser, yyact); }else{ assert( yyact == YY_ACCEPT_ACTION ); - yypParser->yyidx -= yysize; + yypParser->yytos -= yysize; yy_accept(yypParser); } } @@ -691,7 +695,8 @@ static void yy_parse_failed( fprintf(yyTraceFILE,"%sFail!\n",yyTracePrompt); } #endif - while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser); + while( yypParser->yytos>=yypParser->yystack ) yy_pop_parser_stack(yypParser); + yypParser->yytos = 0; /* Here code is inserted which will be executed whenever the ** parser fails */ /************ Begin %parse_failure code ***************************************/ @@ -729,7 +734,8 @@ static void yy_accept( fprintf(yyTraceFILE,"%sAccept!\n",yyTracePrompt); } #endif - while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser); + while( yypParser->yytos>=yypParser->yystack ) yy_pop_parser_stack(yypParser); + yypParser->yytos = 0; /* Here code is inserted which will be executed whenever the ** parser accepts */ /*********** Begin %parse_accept code *****************************************/ @@ -775,14 +781,14 @@ void Parse( /* (re)initialize the parser, if necessary */ yypParser = (yyParser*)yyp; - if( yypParser->yyidx<0 ){ + if( yypParser->yytos==0 ){ #if YYSTACKDEPTH<=0 if( yypParser->yystksz <=0 ){ yyStackOverflow(yypParser); return; } #endif - yypParser->yyidx = 0; + yypParser->yytos = yypParser->yystack; #ifndef YYNOERRORRECOVERY yypParser->yyerrcnt = -1; #endif @@ -809,7 +815,9 @@ void Parse( do{ yyact = yy_find_shift_action(yypParser,(YYCODETYPE)yymajor); if( yyact <= YY_MAX_SHIFTREDUCE ){ - if( yyact > YY_MAX_SHIFT ) yyact += YY_MIN_REDUCE - YY_MIN_SHIFTREDUCE; + if( yyact > YY_MAX_SHIFT ){ + yyact += YY_MIN_REDUCE - YY_MIN_SHIFTREDUCE; + } yy_shift(yypParser,yyact,yymajor,yyminor); #ifndef YYNOERRORRECOVERY yypParser->yyerrcnt--; @@ -851,7 +859,7 @@ void Parse( if( yypParser->yyerrcnt<0 ){ yy_syntax_error(yypParser,yymajor,yyminor); } - yymx = yypParser->yystack[yypParser->yyidx].major; + yymx = yypParser->yytos->major; if( yymx==YYERRORSYMBOL || yyerrorhit ){ #ifndef NDEBUG if( yyTraceFILE ){ @@ -862,16 +870,15 @@ void Parse( yy_destructor(yypParser, (YYCODETYPE)yymajor, &yyminorunion); yymajor = YYNOCODE; }else{ - while( - yypParser->yyidx >= 0 && - yymx != YYERRORSYMBOL && - (yyact = yy_find_reduce_action( - yypParser->yystack[yypParser->yyidx].stateno, + while( yypParser->yytos >= &yypParser->yystack + && yymx != YYERRORSYMBOL + && (yyact = yy_find_reduce_action( + yypParser->yytos->stateno, YYERRORSYMBOL)) >= YY_MIN_REDUCE ){ yy_pop_parser_stack(yypParser); } - if( yypParser->yyidx < 0 || yymajor==0 ){ + if( yypParser->yytos < yypParser->yystack || yymajor==0 ){ yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion); yy_parse_failed(yypParser); yymajor = YYNOCODE; @@ -914,14 +921,16 @@ void Parse( yymajor = YYNOCODE; #endif } - }while( yymajor!=YYNOCODE && yypParser->yyidx>=0 ); + }while( yymajor!=YYNOCODE && yypParser->yytos>=yypParser->yystack ); #ifndef NDEBUG if( yyTraceFILE ){ - int i; + yyStackEntry *i; + char cDiv = '['; fprintf(yyTraceFILE,"%sReturn. Stack=",yyTracePrompt); - for(i=1; i<=yypParser->yyidx; i++) - fprintf(yyTraceFILE,"%c%s", i==1 ? '[' : ' ', - yyTokenName[yypParser->yystack[i].major]); + for(i=&yypParser->yystack[1]; i<=yypParser->yytos; i++){ + fprintf(yyTraceFILE,"%c%s", cDiv, yyTokenName[i->major]); + cDiv = ' '; + } fprintf(yyTraceFILE,"]\n"); } #endif From abecc0b883a6afb48a14a0299dd76f39deff60f3 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 24 May 2016 00:40:54 +0000 Subject: [PATCH 0462/1484] Improvements to the initialization of the push-down automoton for the Lemon-generated parser. Smaller and faster. FossilOrigin-Name: 3b28b68e232060f8b2fe2fe6fa478280da2006ff --- manifest | 12 ++++++------ manifest.uuid | 2 +- tool/lempar.c | 41 +++++++++++++---------------------------- 3 files changed, 20 insertions(+), 35 deletions(-) diff --git a/manifest b/manifest index 8f4a53f747..2f83cec788 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Use\sa\spointer\sto\sthe\stop\sof\sthe\sstack\srather\sthan\san\sindex\sinto\sthe\sstack\nin\sthe\sLemon-generated\sparser\stemplate,\sfor\sabout\s6.6%\sparser\sperformance\sgain. -D 2016-05-23T21:56:24.427 +C Improvements\sto\sthe\sinitialization\sof\sthe\spush-down\sautomoton\sfor\sthe\nLemon-generated\sparser.\s\sSmaller\sand\sfaster. +D 2016-05-24T00:40:54.799 F Makefile.in f59e0763ff448719fc1bd25513882b0567286317 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7 @@ -1422,7 +1422,7 @@ F tool/genfkey.README cf68fddd4643bbe3ff8e31b8b6d8b0a1b85e20f4 F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5 F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce F tool/lemon.c b4da2f0181b4defe538eb437eb96c721cf342d39 -F tool/lempar.c 872383ebf36c13fdaff0f3692d4ff60e64ec49e2 +F tool/lempar.c 8569dd3e4c22831e08e441ab7a0eb6bbefa1d38a F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862 F tool/logest.c 11346aa019e2e77a00902aa7d0cabd27bd2e8cca F tool/mkautoconfamal.sh e855df211ecbcc7131dee817110ff386cfb112f7 @@ -1493,7 +1493,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 276e92f5b4c1ee49eabb738b24d73d7af90fb13c -R f3a217ca3fc6adf56f5cf5443069e03b +P 3c2a770549d5bb65fcd6cc684e0a0ae6d641ac68 +R f0cfba4e984837df73820e425fc5291f U drh -Z babb89b922e84c6e93d4048989d7622c +Z 2da99ff99cbfd3def15eb678236b100e diff --git a/manifest.uuid b/manifest.uuid index 9a4a91d8af..0635c8e250 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3c2a770549d5bb65fcd6cc684e0a0ae6d641ac68 \ No newline at end of file +3b28b68e232060f8b2fe2fe6fa478280da2006ff \ No newline at end of file diff --git a/tool/lempar.c b/tool/lempar.c index b02fd21b77..7fb5fe2d0c 100644 --- a/tool/lempar.c +++ b/tool/lempar.c @@ -275,12 +275,15 @@ static const char *const yyRuleName[] = { */ static void yyGrowStack(yyParser *p){ int newSize; + int idx; yyStackEntry *pNew; newSize = p->yystksz*2 + 100; + idx = p->yytos ? (int)(p->yytos - p->yystack) : 0; pNew = realloc(p->yystack, newSize*sizeof(pNew[0])); if( pNew ){ p->yystack = pNew; + p->yytos = &p->yystack[idx]; p->yystksz = newSize; #ifndef NDEBUG if( yyTraceFILE ){ @@ -317,15 +320,18 @@ void *ParseAlloc(void *(*mallocProc)(YYMALLOCARGTYPE)){ yyParser *pParser; pParser = (yyParser*)(*mallocProc)( (YYMALLOCARGTYPE)sizeof(yyParser) ); if( pParser ){ - pParser->yytos = 0; #ifdef YYTRACKMAXSTACKDEPTH pParser->yyhwm = 0; #endif #if YYSTACKDEPTH<=0 + pParser->yytos = NULL; pParser->yystack = NULL; pParser->yystksz = 0; yyGrowStack(pParser); #endif + pParser->yytos = pParser->yystack; + pParser->yystack[0].stateno = 0; + pParser->yystack[0].major = 0; } return pParser; } @@ -397,7 +403,7 @@ void ParseFree( #ifndef YYPARSEFREENEVERNULL if( pParser==0 ) return; #endif - while( pParser->yytos>=pParser->yystack ) yy_pop_parser_stack(pParser); + while( pParser->yytos>pParser->yystack ) yy_pop_parser_stack(pParser); #if YYSTACKDEPTH<=0 free(pParser->yystack); #endif @@ -522,7 +528,7 @@ static void yyStackOverflow(yyParser *yypParser){ fprintf(yyTraceFILE,"%sStack Overflow!\n",yyTracePrompt); } #endif - while( yypParser->yytos>=yypParser->yystack ) yy_pop_parser_stack(yypParser); + while( yypParser->yytos>yypParser->yystack ) yy_pop_parser_stack(yypParser); /* Here code is inserted which will execute if the parser ** stack every overflows */ /******** Begin %stack_overflow code ******************************************/ @@ -695,8 +701,7 @@ static void yy_parse_failed( fprintf(yyTraceFILE,"%sFail!\n",yyTracePrompt); } #endif - while( yypParser->yytos>=yypParser->yystack ) yy_pop_parser_stack(yypParser); - yypParser->yytos = 0; + while( yypParser->yytos>yypParser->yystack ) yy_pop_parser_stack(yypParser); /* Here code is inserted which will be executed whenever the ** parser fails */ /************ Begin %parse_failure code ***************************************/ @@ -734,8 +739,7 @@ static void yy_accept( fprintf(yyTraceFILE,"%sAccept!\n",yyTracePrompt); } #endif - while( yypParser->yytos>=yypParser->yystack ) yy_pop_parser_stack(yypParser); - yypParser->yytos = 0; + while( yypParser->yytos>yypParser->yystack ) yy_pop_parser_stack(yypParser); /* Here code is inserted which will be executed whenever the ** parser accepts */ /*********** Begin %parse_accept code *****************************************/ @@ -781,26 +785,7 @@ void Parse( /* (re)initialize the parser, if necessary */ yypParser = (yyParser*)yyp; - if( yypParser->yytos==0 ){ -#if YYSTACKDEPTH<=0 - if( yypParser->yystksz <=0 ){ - yyStackOverflow(yypParser); - return; - } -#endif - yypParser->yytos = yypParser->yystack; -#ifndef YYNOERRORRECOVERY - yypParser->yyerrcnt = -1; -#endif - yypParser->yystack[0].stateno = 0; - yypParser->yystack[0].major = 0; -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sInitialize. Empty stack. State 0\n", - yyTracePrompt); - } -#endif - } + assert( yypParser->yytos!=0 ); #if !defined(YYERRORSYMBOL) && !defined(YYNOERRORRECOVERY) yyendofinput = (yymajor==0); #endif @@ -921,7 +906,7 @@ void Parse( yymajor = YYNOCODE; #endif } - }while( yymajor!=YYNOCODE && yypParser->yytos>=yypParser->yystack ); + }while( yymajor!=YYNOCODE && yypParser->yytos>yypParser->yystack ); #ifndef NDEBUG if( yyTraceFILE ){ yyStackEntry *i; From fe912510ea1f383574f06919047884617e2d517c Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 24 May 2016 16:20:51 +0000 Subject: [PATCH 0463/1484] Fix an obscure problem with transactions written in "PRAGMA synchronous=full" mode on systems that do not support POWERSAFE_OVERWRITE causing an xSync() call to be omitted if the last frame written by a transaction is aligned to a sector boundary. This means that if a power failure or OS crash occurs very soon after such a transaction is committed, it may be lost following system recovery. FossilOrigin-Name: 37de3eab67f12ae1ce5bc8d5e541c64fc6b1fd80 --- manifest | 17 +++++----- manifest.uuid | 2 +- src/test6.c | 26 +++++++++++++++- src/wal.c | 7 ++++- test/walcrash4.test | 75 +++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 116 insertions(+), 11 deletions(-) create mode 100644 test/walcrash4.test diff --git a/manifest b/manifest index 2f83cec788..f15691dac1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improvements\sto\sthe\sinitialization\sof\sthe\spush-down\sautomoton\sfor\sthe\nLemon-generated\sparser.\s\sSmaller\sand\sfaster. -D 2016-05-24T00:40:54.799 +C Fix\san\sobscure\sproblem\swith\stransactions\swritten\sin\s"PRAGMA\ssynchronous=full"\smode\son\ssystems\sthat\sdo\snot\ssupport\sPOWERSAFE_OVERWRITE\scausing\san\sxSync()\scall\sto\sbe\somitted\sif\sthe\slast\sframe\swritten\sby\sa\stransaction\sis\saligned\sto\sa\ssector\sboundary.\sThis\smeans\sthat\sif\sa\spower\sfailure\sor\sOS\scrash\soccurs\svery\ssoon\safter\ssuch\sa\stransaction\sis\scommitted,\sit\smay\sbe\slost\sfollowing\ssystem\srecovery. +D 2016-05-24T16:20:51.379 F Makefile.in f59e0763ff448719fc1bd25513882b0567286317 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7 @@ -394,7 +394,7 @@ F src/test2.c 5586f43fcd9a1be0830793cf9d354082c261b25b F src/test3.c d2c9efd2985ff8f5502ffd3253156984778d77d8 F src/test4.c d168f83cc78d02e8d35567bb5630e40dcd85ac1e F src/test5.c 5a34feec76d9b3a86aab30fd4f6cc9c48cbab4c1 -F src/test6.c 2c014d4977efd6107ec9eef3dfdec56ac516f824 +F src/test6.c a684b7abd01352ab50cb79c0bf727e6b3f381a3d F src/test7.c 9c89a4f1ed6bb13af0ed805b8d782bd83fcd57e3 F src/test8.c fa262391d3edea6490a71bfaa8fed477ccbbac75 F src/test9.c bea1e8cf52aa93695487badedd6e1886c321ea60 @@ -456,7 +456,7 @@ F src/vdbesort.c 91fda3909326860382b0ca8aa251e609c6a9d62c F src/vdbetrace.c f75c5455d8cf389ef86a8bfdfd3177e0e3692484 F src/vtab.c ce0f2ebb589b459b32c640b33af64bfa5b29aaf8 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 -F src/wal.c 4db22ed7e77bcf672b1a685d6ddeffba8d5be302 +F src/wal.c 02eeecc265f6ffd0597378f5d8ae9070b62a406a F src/wal.h 2f7c831cf3b071fa548bf2d5cac640846a7ff19c F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354 F src/where.c 0e54a03d11d4e99ad25528f42ff4c9a6fa7a23da @@ -1356,6 +1356,7 @@ F test/walcksum.test bb234a1bb42248b3515d992b719708015c384278 F test/walcrash.test 21038858cc552077b0522f50b0fa87e38139306a F test/walcrash2.test a0edab4e5390f03b99a790de89aad15d6ec70b36 F test/walcrash3.test e426aa58122d20f2b9fbe9a507f9eb8cab85b8af +F test/walcrash4.test 2907eaa670156daf41bb865c30a08ad13088262c F test/walfault.test 1f8389f7709877e9b4cc679033d71d6fe529056b F test/walhook.test ed00a40ba7255da22d6b66433ab61fab16a63483 F test/walmode.test 4022fe03ae6e830583672caa101f046438a0473c @@ -1493,7 +1494,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 3c2a770549d5bb65fcd6cc684e0a0ae6d641ac68 -R f0cfba4e984837df73820e425fc5291f -U drh -Z 2da99ff99cbfd3def15eb678236b100e +P 3b28b68e232060f8b2fe2fe6fa478280da2006ff +R 517787a46c326083f1c71f4f2bce6c10 +U dan +Z 8b1bf46b6e26241c0a55d35f24f797fc diff --git a/manifest.uuid b/manifest.uuid index 0635c8e250..374fcadf94 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3b28b68e232060f8b2fe2fe6fa478280da2006ff \ No newline at end of file +37de3eab67f12ae1ce5bc8d5e541c64fc6b1fd80 \ No newline at end of file diff --git a/src/test6.c b/src/test6.c index 2a09122c6c..24fe725f78 100644 --- a/src/test6.c +++ b/src/test6.c @@ -215,7 +215,9 @@ static int writeListSync(CrashFile *pFile, int isCrash){ } #ifdef TRACE_CRASHTEST - printf("Sync %s (is %s crash)\n", pFile->zName, (isCrash?"a":"not a")); + if( pFile ){ + printf("Sync %s (is %s crash)\n", pFile->zName, (isCrash?"a":"not a")); + } #endif ppPtr = &g.pWriteList; @@ -799,6 +801,27 @@ static int processDevSymArgs( return TCL_OK; } +/* +** tclcmd: sqlite3_crash_now +** +** Simulate a crash immediately. This function does not return +** (writeListSync() calls exit(-1)). +*/ +static int crashNowCmd( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + if( objc!=1 ){ + Tcl_WrongNumArgs(interp, 1, objv, ""); + return TCL_ERROR; + } + writeListSync(0, 1); + assert( 0 ); + return TCL_OK; +} + /* ** tclcmd: sqlite_crash_enable ENABLE ** @@ -1034,6 +1057,7 @@ int Sqlitetest6_Init(Tcl_Interp *interp){ #ifndef SQLITE_OMIT_DISKIO Tcl_CreateObjCommand(interp, "sqlite3_crash_enable", crashEnableCmd, 0, 0); Tcl_CreateObjCommand(interp, "sqlite3_crashparams", crashParamsObjCmd, 0, 0); + Tcl_CreateObjCommand(interp, "sqlite3_crash_now", crashNowCmd, 0, 0); Tcl_CreateObjCommand(interp, "sqlite3_simulate_device", devSymObjCmd, 0, 0); Tcl_CreateObjCommand(interp, "unregister_devsim", dsUnregisterObjCmd, 0, 0); Tcl_CreateObjCommand(interp, "register_jt_vfs", jtObjCmd, 0, 0); diff --git a/src/wal.c b/src/wal.c index 98b46be801..235d383e1a 100644 --- a/src/wal.c +++ b/src/wal.c @@ -3109,16 +3109,21 @@ int sqlite3WalFrames( ** past the sector boundary is written after the sync. */ if( isCommit && (sync_flags & WAL_SYNC_TRANSACTIONS)!=0 ){ + int bSync = 1; if( pWal->padToSectorBoundary ){ int sectorSize = sqlite3SectorSize(pWal->pWalFd); w.iSyncPoint = ((iOffset+sectorSize-1)/sectorSize)*sectorSize; + bSync = (w.iSyncPoint==iOffset); + testcase( bSync ); while( iOffset@stdout } msg] + list $r $msg + } {1 {child process exited abnormally}} + + do_execsql_test 1.nExtra=$nExtra.i=$i.2 { + SELECT count(*) FROM t1; + PRAGMA integrity_check; + } {1 ok} + } +} + + +finish_test From f34a25a23bbf51a57c2ccbb6126eba77ecf4ae63 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 24 May 2016 18:50:41 +0000 Subject: [PATCH 0464/1484] Minor change to the walcrash4.test module so that it works when SQLITE_DEFAULT_WAL_SYNCHRONOUS is set to something other than 2. FossilOrigin-Name: 61e239bc4310eff172e1e50d51522ecc75dd997e --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/walcrash4.test | 1 + 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index f15691dac1..8b597e7bf2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\sobscure\sproblem\swith\stransactions\swritten\sin\s"PRAGMA\ssynchronous=full"\smode\son\ssystems\sthat\sdo\snot\ssupport\sPOWERSAFE_OVERWRITE\scausing\san\sxSync()\scall\sto\sbe\somitted\sif\sthe\slast\sframe\swritten\sby\sa\stransaction\sis\saligned\sto\sa\ssector\sboundary.\sThis\smeans\sthat\sif\sa\spower\sfailure\sor\sOS\scrash\soccurs\svery\ssoon\safter\ssuch\sa\stransaction\sis\scommitted,\sit\smay\sbe\slost\sfollowing\ssystem\srecovery. -D 2016-05-24T16:20:51.379 +C Minor\schange\sto\sthe\swalcrash4.test\smodule\sso\sthat\sit\sworks\swhen\nSQLITE_DEFAULT_WAL_SYNCHRONOUS\sis\sset\sto\ssomething\sother\sthan\s2. +D 2016-05-24T18:50:41.162 F Makefile.in f59e0763ff448719fc1bd25513882b0567286317 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7 @@ -1356,7 +1356,7 @@ F test/walcksum.test bb234a1bb42248b3515d992b719708015c384278 F test/walcrash.test 21038858cc552077b0522f50b0fa87e38139306a F test/walcrash2.test a0edab4e5390f03b99a790de89aad15d6ec70b36 F test/walcrash3.test e426aa58122d20f2b9fbe9a507f9eb8cab85b8af -F test/walcrash4.test 2907eaa670156daf41bb865c30a08ad13088262c +F test/walcrash4.test fa7d92ab84fe3ff409e1cda88a622545e2bc2b66 F test/walfault.test 1f8389f7709877e9b4cc679033d71d6fe529056b F test/walhook.test ed00a40ba7255da22d6b66433ab61fab16a63483 F test/walmode.test 4022fe03ae6e830583672caa101f046438a0473c @@ -1494,7 +1494,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 3b28b68e232060f8b2fe2fe6fa478280da2006ff -R 517787a46c326083f1c71f4f2bce6c10 -U dan -Z 8b1bf46b6e26241c0a55d35f24f797fc +P 37de3eab67f12ae1ce5bc8d5e541c64fc6b1fd80 +R a85ab0cafd821231f355609347ddd044 +U drh +Z c6593df9e63293d2b7fb6ab3cfe0f9b0 diff --git a/manifest.uuid b/manifest.uuid index 374fcadf94..0dbb5b2cbc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -37de3eab67f12ae1ce5bc8d5e541c64fc6b1fd80 \ No newline at end of file +61e239bc4310eff172e1e50d51522ecc75dd997e \ No newline at end of file diff --git a/test/walcrash4.test b/test/walcrash4.test index df0f12b510..d2f07730a0 100644 --- a/test/walcrash4.test +++ b/test/walcrash4.test @@ -46,6 +46,7 @@ for {set nExtra 0} {$nExtra < 10} {incr nExtra} { sqlite3_test_control_pending_byte $::sqlite_pending_byte sqlite3 db test.db -vfs crash db eval { + PRAGMA main.synchronous=FULL; BEGIN; CREATE TABLE t1(x UNIQUE); } From 756b41ebd47e2db4dab5de5ba5f57568829e0c31 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 24 May 2016 18:55:08 +0000 Subject: [PATCH 0465/1484] Enhance Lemon and the parser template so that it can once again build parsers that have no unreachable branches. FossilOrigin-Name: 41fd46e2962ba9a1e1f6867567499d1f6f5b8372 --- manifest | 14 +++++++------- manifest.uuid | 2 +- tool/lemon.c | 21 ++++++++++++++++++++- tool/lempar.c | 2 +- 4 files changed, 29 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 8b597e7bf2..a229ea4a91 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Minor\schange\sto\sthe\swalcrash4.test\smodule\sso\sthat\sit\sworks\swhen\nSQLITE_DEFAULT_WAL_SYNCHRONOUS\sis\sset\sto\ssomething\sother\sthan\s2. -D 2016-05-24T18:50:41.162 +C Enhance\sLemon\sand\sthe\sparser\stemplate\sso\sthat\sit\scan\sonce\sagain\sbuild\sparsers\nthat\shave\sno\sunreachable\sbranches. +D 2016-05-24T18:55:08.844 F Makefile.in f59e0763ff448719fc1bd25513882b0567286317 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7 @@ -1422,8 +1422,8 @@ F tool/fuzzershell.c 94019b185caceffc9f7c7b678a6489e42bc2aefa F tool/genfkey.README cf68fddd4643bbe3ff8e31b8b6d8b0a1b85e20f4 F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5 F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce -F tool/lemon.c b4da2f0181b4defe538eb437eb96c721cf342d39 -F tool/lempar.c 8569dd3e4c22831e08e441ab7a0eb6bbefa1d38a +F tool/lemon.c 09a96bed19955697a5e20c49ad863ec2005815a2 +F tool/lempar.c 1f69ad7531e39612915570a3d2c67a3cc1e9bbf0 F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862 F tool/logest.c 11346aa019e2e77a00902aa7d0cabd27bd2e8cca F tool/mkautoconfamal.sh e855df211ecbcc7131dee817110ff386cfb112f7 @@ -1494,7 +1494,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 37de3eab67f12ae1ce5bc8d5e541c64fc6b1fd80 -R a85ab0cafd821231f355609347ddd044 +P 61e239bc4310eff172e1e50d51522ecc75dd997e +R 871f96c4fa63421d837cdbce37a6939a U drh -Z c6593df9e63293d2b7fb6ab3cfe0f9b0 +Z 9f1d9f44ca67035c6f1f764382efebdf diff --git a/manifest.uuid b/manifest.uuid index 0dbb5b2cbc..b7546cc298 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -61e239bc4310eff172e1e50d51522ecc75dd997e \ No newline at end of file +41fd46e2962ba9a1e1f6867567499d1f6f5b8372 \ No newline at end of file diff --git a/tool/lemon.c b/tool/lemon.c index d643b341e4..5f124601db 100644 --- a/tool/lemon.c +++ b/tool/lemon.c @@ -294,6 +294,7 @@ struct rule { int index; /* An index number for this rule */ int iRule; /* Rule number as used in the generated tables */ Boolean canReduce; /* True if this rule is ever reduced */ + Boolean doesReduce; /* Reduce actions occur after optimization */ struct rule *nextlhs; /* Next rule with the same LHS */ struct rule *next; /* Next rule in the global list */ }; @@ -4152,6 +4153,19 @@ void ReportTable( } free(ax); + /* Mark rules that are actually used for reduce actions after all + ** optimizations have been applied + */ + for(rp=lemp->rule; rp; rp=rp->next) rp->doesReduce = LEMON_FALSE; + for(i=0; inxstate; i++){ + struct action *ap; + for(ap=lemp->sorted[i]->ap; ap; ap=ap->next){ + if( ap->type==REDUCE || ap->type==SHIFTREDUCE ){ + ap->x.rp->doesReduce = i; + } + } + } + /* Finish rendering the constants now that the action table has ** been computed */ fprintf(out,"#define YYNSTATE %d\n",lemp->nxstate); lineno++; @@ -4443,7 +4457,12 @@ void ReportTable( assert( rp->noCode ); fprintf(out," /* (%d) ", rp->iRule); writeRuleText(out, rp); - fprintf(out, " */ yytestcase(yyruleno==%d);\n", rp->iRule); lineno++; + if( rp->doesReduce ){ + fprintf(out, " */ yytestcase(yyruleno==%d);\n", rp->iRule); lineno++; + }else{ + fprintf(out, " (OPTIMIZED OUT) */ assert(yyruleno!=%d);\n", + rp->iRule); lineno++; + } } fprintf(out," break;\n"); lineno++; tplt_xfer(lemp->name,in,out,&lineno); diff --git a/tool/lempar.c b/tool/lempar.c index 7fb5fe2d0c..91f3549f31 100644 --- a/tool/lempar.c +++ b/tool/lempar.c @@ -739,7 +739,7 @@ static void yy_accept( fprintf(yyTraceFILE,"%sAccept!\n",yyTracePrompt); } #endif - while( yypParser->yytos>yypParser->yystack ) yy_pop_parser_stack(yypParser); + assert( yypParser->yytos==yypParser->yystack ); /* Here code is inserted which will be executed whenever the ** parser accepts */ /*********** Begin %parse_accept code *****************************************/ From ce3c5011d9325adf3546505c45d40243db6e7eee Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 25 May 2016 18:53:39 +0000 Subject: [PATCH 0466/1484] Add the libvers.c tool in the tool/ subdirectory. FossilOrigin-Name: 2a41f098b2f0523b3d7e6eba6ae91cc0d30752df --- manifest | 11 ++++++----- manifest.uuid | 2 +- tool/libvers.c | 15 +++++++++++++++ 3 files changed, 22 insertions(+), 6 deletions(-) create mode 100644 tool/libvers.c diff --git a/manifest b/manifest index a229ea4a91..6e33cdaa4b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\sLemon\sand\sthe\sparser\stemplate\sso\sthat\sit\scan\sonce\sagain\sbuild\sparsers\nthat\shave\sno\sunreachable\sbranches. -D 2016-05-24T18:55:08.844 +C Add\sthe\slibvers.c\stool\sin\sthe\stool/\ssubdirectory. +D 2016-05-25T18:53:39.049 F Makefile.in f59e0763ff448719fc1bd25513882b0567286317 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7 @@ -1424,6 +1424,7 @@ F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5 F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce F tool/lemon.c 09a96bed19955697a5e20c49ad863ec2005815a2 F tool/lempar.c 1f69ad7531e39612915570a3d2c67a3cc1e9bbf0 +F tool/libvers.c caafc3b689638a1d88d44bc5f526c2278760d9b9 F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862 F tool/logest.c 11346aa019e2e77a00902aa7d0cabd27bd2e8cca F tool/mkautoconfamal.sh e855df211ecbcc7131dee817110ff386cfb112f7 @@ -1494,7 +1495,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 61e239bc4310eff172e1e50d51522ecc75dd997e -R 871f96c4fa63421d837cdbce37a6939a +P 41fd46e2962ba9a1e1f6867567499d1f6f5b8372 +R 871df33bb708dea5ddc1c61eb4854aa7 U drh -Z 9f1d9f44ca67035c6f1f764382efebdf +Z b20c30dd356053a2351766a3c882aef8 diff --git a/manifest.uuid b/manifest.uuid index b7546cc298..b182bd8e82 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -41fd46e2962ba9a1e1f6867567499d1f6f5b8372 \ No newline at end of file +2a41f098b2f0523b3d7e6eba6ae91cc0d30752df \ No newline at end of file diff --git a/tool/libvers.c b/tool/libvers.c new file mode 100644 index 0000000000..6911dbd07e --- /dev/null +++ b/tool/libvers.c @@ -0,0 +1,15 @@ +/* +** Compile this program against an SQLite library of unknown version +** and then run this program, and it will print out the SQLite version +** information. +*/ +#include + +extern const char *sqlite3_libversion(void); +extern const char *sqlite3_sourceid(void); + +int main(int argc, char **argv){ + printf("SQLite version %s\n", sqlite3_libversion()); + printf("SQLite source %s\n", sqlite3_sourceid()); + return 0; +} From eeb9565a3e3397340a4dc79a8b693e35cdecfb7c Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 26 May 2016 20:56:38 +0000 Subject: [PATCH 0467/1484] Add a new OP_SeekRowid opcode, that combines the functions of OP_MustBeInt and OP_NotExists. This makes the code slightly smaller and faster. FossilOrigin-Name: ffe80a1bfa014943a614fc6993c1749b9bfec4c1 --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/expr.c | 3 +-- src/pragma.c | 4 +--- src/vdbe.c | 50 +++++++++++++++++++++++++++++++++++++++++++------ src/wherecode.c | 3 +-- 6 files changed, 57 insertions(+), 23 deletions(-) diff --git a/manifest b/manifest index 6e33cdaa4b..88f7d0cd56 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\slibvers.c\stool\sin\sthe\stool/\ssubdirectory. -D 2016-05-25T18:53:39.049 +C Add\sa\snew\sOP_SeekRowid\sopcode,\sthat\scombines\sthe\sfunctions\sof\sOP_MustBeInt\nand\sOP_NotExists.\s\sThis\smakes\sthe\scode\sslightly\ssmaller\sand\sfaster. +D 2016-05-26T20:56:38.450 F Makefile.in f59e0763ff448719fc1bd25513882b0567286317 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7 @@ -333,7 +333,7 @@ F src/ctime.c 60e135af364d777a9ab41c97e5e89cd224da6198 F src/date.c 1cc9fb516ec9932c6fd4d2a0d2f8bc4480145c39 F src/dbstat.c c845548d4346e606e2f2b7d2e714ace2b8a7dd1b F src/delete.c 4aba4214a377ce8ddde2d2e609777bcc8235200f -F src/expr.c 8796c0739b2ad091e6779253f62aad6e767e2be1 +F src/expr.c 81bd7d87985746313770211183e900ed1ad28381 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 4c0bd09e602b8ae8d36d81e31e4872d0b53c87bb F src/func.c ef4c18c8a66143413ce41a58d582d2c14ddf78e1 @@ -372,7 +372,7 @@ F src/parse.y 10eb2f3fb62341291528c7984498054731f9d31e F src/pcache.c 5583c8ade4b05075a60ba953ef471d1c1a9c05df F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 F src/pcache1.c 7f51d2b541aab57596adf62db2c4bb025d34f04d -F src/pragma.c 9fdce031ddcb57f0f56e4a8b421b7e7a77de73b0 +F src/pragma.c d98039af2deb5a4990f6635462b3f61f325a6c75 F src/pragma.h 64c78a648751b9f4f297276c4eb7507b14b4628c F src/prepare.c 22df6171aec1d86904ed2ad30c2348a5748aa04e F src/printf.c a5f0ca08ddede803c241266abb46356ec748ded1 @@ -445,7 +445,7 @@ F src/update.c 4f05ea8cddfa367d045e03589756c02199e8f9bd F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 810ec3f22e2d1b62e66c30fe3621ebdedd23584d F src/vacuum.c feb1eabb20987983d9350cad98299b21fa811f52 -F src/vdbe.c f2706d5564d2b2887a27c909e8e1575250029503 +F src/vdbe.c 45e4da739187028281e342f79fae0f4145055bec F src/vdbe.h 5591b5add447096e31288b5a0a78ec5d7b5c5170 F src/vdbeInt.h ddb157974436d87652de7dc641f7191496d9a8cd F src/vdbeapi.c ba85b78fe08dc4a9ce747e62c89a2b4a4547e74c @@ -461,7 +461,7 @@ F src/wal.h 2f7c831cf3b071fa548bf2d5cac640846a7ff19c F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354 F src/where.c 0e54a03d11d4e99ad25528f42ff4c9a6fa7a23da F src/whereInt.h 6e18240be400bef8e4dbafea605251707c5dbf49 -F src/wherecode.c e3f18fcda2d7f8218a09dc33cf495dca0efa6e3e +F src/wherecode.c ba71a4e4bada29aa9842200e6299714bf18c812c F src/whereexpr.c eacc0e60d029a082b4fc0cc42ea98544add1319e F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -1495,7 +1495,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 41fd46e2962ba9a1e1f6867567499d1f6f5b8372 -R 871df33bb708dea5ddc1c61eb4854aa7 +P 2a41f098b2f0523b3d7e6eba6ae91cc0d30752df +R 810bd747b437c6e4e76eef1099520866 U drh -Z b20c30dd356053a2351766a3c882aef8 +Z 73ea989f24641ac606e6e6c2f5b60872 diff --git a/manifest.uuid b/manifest.uuid index b182bd8e82..9a103ac06c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2a41f098b2f0523b3d7e6eba6ae91cc0d30752df \ No newline at end of file +ffe80a1bfa014943a614fc6993c1749b9bfec4c1 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 9e3b664e8d..156db96fa1 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2222,8 +2222,7 @@ static void sqlite3ExprCodeIN( if( eType==IN_INDEX_ROWID ){ /* In this case, the RHS is the ROWID of table b-tree */ - sqlite3VdbeAddOp2(v, OP_MustBeInt, r1, destIfFalse); VdbeCoverage(v); - sqlite3VdbeAddOp3(v, OP_NotExists, pExpr->iTable, destIfFalse, r1); + sqlite3VdbeAddOp3(v, OP_SeekRowid, pExpr->iTable, destIfFalse, r1); VdbeCoverage(v); }else{ /* In this case, the RHS is an index b-tree. diff --git a/src/pragma.c b/src/pragma.c index 330e999090..56823c7243 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -1334,12 +1334,10 @@ void sqlite3Pragma( sqlite3VdbeAddOp3(v, OP_Column, 0, iKey, regRow); sqlite3ColumnDefault(v, pTab, iKey, regRow); sqlite3VdbeAddOp2(v, OP_IsNull, regRow, addrOk); VdbeCoverage(v); - sqlite3VdbeAddOp2(v, OP_MustBeInt, regRow, - sqlite3VdbeCurrentAddr(v)+3); VdbeCoverage(v); }else{ sqlite3VdbeAddOp2(v, OP_Rowid, 0, regRow); } - sqlite3VdbeAddOp3(v, OP_NotExists, i, 0, regRow); VdbeCoverage(v); + sqlite3VdbeAddOp3(v, OP_SeekRowid, i, 0, regRow); VdbeCoverage(v); sqlite3VdbeGoto(v, addrOk); sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2); }else{ diff --git a/src/vdbe.c b/src/vdbe.c index d512c0bc74..d4392a89d9 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -4023,6 +4023,30 @@ case OP_Found: { /* jump, in3 */ break; } +/* Opcode: SeekRowid P1 P2 P3 * * +** Synopsis: intkey=r[P3] +** +** P1 is the index of a cursor open on an SQL table btree (with integer +** keys). If register P3 does not contain an integer or if P1 does not +** contain a record with rowid P3 then jump immediately to P2. +** Or, if P2 is 0, raise an SQLITE_CORRUPT error. If P1 does contain +** a record with rowid P3 then +** leave the cursor pointing at that record and fall through to the next +** instruction. +** +** The OP_NotExists opcode performs the same operation, but with OP_NotExists +** the P3 register must be guaranteed to contain an integer value. With this +** opcode, register P3 might not contain an integer. +** +** The OP_NotFound opcode performs the same operation on index btrees +** (with arbitrary multi-value keys). +** +** This opcode leaves the cursor in a state where it cannot be advanced +** in either direction. In other words, the Next and Prev opcodes will +** not work following this opcode. +** +** See also: Found, NotFound, NoConflict, SeekRowid +*/ /* Opcode: NotExists P1 P2 P3 * * ** Synopsis: intkey=r[P3] ** @@ -4033,6 +4057,10 @@ case OP_Found: { /* jump, in3 */ ** leave the cursor pointing at that record and fall through to the next ** instruction. ** +** The OP_SeekRowid opcode performs the same operation but also allows the +** P3 register to contain a non-integer value, in which case the jump is +** always taken. This opcode requires that P3 always contain an integer. +** ** The OP_NotFound opcode performs the same operation on index btrees ** (with arbitrary multi-value keys). ** @@ -4040,14 +4068,21 @@ case OP_Found: { /* jump, in3 */ ** in either direction. In other words, the Next and Prev opcodes will ** not work following this opcode. ** -** See also: Found, NotFound, NoConflict +** See also: Found, NotFound, NoConflict, SeekRowid */ -case OP_NotExists: { /* jump, in3 */ +case OP_SeekRowid: { /* jump, in3 */ VdbeCursor *pC; BtCursor *pCrsr; int res; u64 iKey; + pIn3 = &aMem[pOp->p3]; + if( (pIn3->flags & MEM_Int)==0 ){ + applyAffinity(pIn3, SQLITE_AFF_NUMERIC, encoding); + if( (pIn3->flags & MEM_Int)==0 ) goto jump_to_p2; + } + /* Fall through into OP_NotExists */ +case OP_NotExists: /* jump, in3 */ pIn3 = &aMem[pOp->p3]; assert( pIn3->flags & MEM_Int ); assert( pOp->p1>=0 && pOp->p1nCursor ); @@ -4250,10 +4285,12 @@ case OP_NewRowid: { /* out2 */ ** sqlite3_last_insert_rowid() function (otherwise it is unmodified). ** ** If the OPFLAG_USESEEKRESULT flag of P5 is set and if the result of -** the last seek operation (OP_NotExists) was a success, then this +** the last seek operation (OP_NotExists or OP_SeekRowid) was a success, +** then this ** operation will not attempt to find the appropriate row before doing ** the insert but will instead overwrite the row that the cursor is -** currently pointing to. Presumably, the prior OP_NotExists opcode +** currently pointing to. Presumably, the prior OP_NotExists or +** OP_SeekRowid opcode ** has already positioned the cursor correctly. This is an optimization ** that boosts performance by avoiding redundant seeks. ** @@ -4611,8 +4648,9 @@ case OP_RowData: { pCrsr = pC->uc.pCursor; /* The OP_RowKey and OP_RowData opcodes always follow OP_NotExists or - ** OP_Rewind/Op_Next with no intervening instructions that might invalidate - ** the cursor. If this where not the case, on of the following assert()s + ** OP_SeekRowid or OP_Rewind/Op_Next with no intervening instructions + ** that might invalidate the cursor. + ** If this where not the case, on of the following assert()s ** would fail. Should this ever change (because of changes in the code ** generator) then the fix would be to insert a call to ** sqlite3VdbeCursorMoveto(). diff --git a/src/wherecode.c b/src/wherecode.c index 054b1b1078..83ee48ac66 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -971,8 +971,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( iRowidReg = codeEqualityTerm(pParse, pTerm, pLevel, 0, bRev, iReleaseReg); if( iRowidReg!=iReleaseReg ) sqlite3ReleaseTempReg(pParse, iReleaseReg); addrNxt = pLevel->addrNxt; - sqlite3VdbeAddOp2(v, OP_MustBeInt, iRowidReg, addrNxt); VdbeCoverage(v); - sqlite3VdbeAddOp3(v, OP_NotExists, iCur, addrNxt, iRowidReg); + sqlite3VdbeAddOp3(v, OP_SeekRowid, iCur, addrNxt, iRowidReg); VdbeCoverage(v); sqlite3ExprCacheAffinityChange(pParse, iRowidReg, 1); sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg); From baf254aef9bc88bc152f99422939c7482e83e1c6 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 27 May 2016 01:07:18 +0000 Subject: [PATCH 0468/1484] Fix the Lemon-generated parser so that it compiles with -DYYSTACKDEPTH=0. It does compile now, but there are subtle issues still. FossilOrigin-Name: 28d439f816d2fa5263e1c4ddecf3bf1ac2dd6549 --- manifest | 12 ++++++------ manifest.uuid | 2 +- tool/lempar.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 88f7d0cd56..cfe2236da5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sa\snew\sOP_SeekRowid\sopcode,\sthat\scombines\sthe\sfunctions\sof\sOP_MustBeInt\nand\sOP_NotExists.\s\sThis\smakes\sthe\scode\sslightly\ssmaller\sand\sfaster. -D 2016-05-26T20:56:38.450 +C Fix\sthe\sLemon-generated\sparser\sso\sthat\sit\scompiles\swith\s-DYYSTACKDEPTH=0.\nIt\sdoes\scompile\snow,\sbut\sthere\sare\ssubtle\sissues\sstill. +D 2016-05-27T01:07:18.565 F Makefile.in f59e0763ff448719fc1bd25513882b0567286317 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7 @@ -1423,7 +1423,7 @@ F tool/genfkey.README cf68fddd4643bbe3ff8e31b8b6d8b0a1b85e20f4 F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5 F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce F tool/lemon.c 09a96bed19955697a5e20c49ad863ec2005815a2 -F tool/lempar.c 1f69ad7531e39612915570a3d2c67a3cc1e9bbf0 +F tool/lempar.c 7689ddc408a54f9c23e7f9e17e597752b71fa537 F tool/libvers.c caafc3b689638a1d88d44bc5f526c2278760d9b9 F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862 F tool/logest.c 11346aa019e2e77a00902aa7d0cabd27bd2e8cca @@ -1495,7 +1495,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 2a41f098b2f0523b3d7e6eba6ae91cc0d30752df -R 810bd747b437c6e4e76eef1099520866 +P ffe80a1bfa014943a614fc6993c1749b9bfec4c1 +R 8a7f49776364e838d9d2230beef644f3 U drh -Z 73ea989f24641ac606e6e6c2f5b60872 +Z 81291c1e83b5b57f970177cd78c139d0 diff --git a/manifest.uuid b/manifest.uuid index 9a103ac06c..c2da443b16 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ffe80a1bfa014943a614fc6993c1749b9bfec4c1 \ No newline at end of file +28d439f816d2fa5263e1c4ddecf3bf1ac2dd6549 \ No newline at end of file diff --git a/tool/lempar.c b/tool/lempar.c index 91f3549f31..e96d6c9e7f 100644 --- a/tool/lempar.c +++ b/tool/lempar.c @@ -582,7 +582,7 @@ static void yy_shift( #else if( yypParser->yytos>=&yypParser->yystack[yypParser->yystksz] ){ yyGrowStack(yypParser); - if( yypParser->yytos>=&yypParser->yystach[yypParser->yystksz] ){ + if( yypParser->yytos>=&yypParser->yystack[yypParser->yystksz] ){ yyStackOverflow(yypParser); return; } From 8dc8247eabe32d2b866dc19e8490f04723c9f8ca Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 27 May 2016 04:10:47 +0000 Subject: [PATCH 0469/1484] Fix Lemon so that it actually works with -DYYSTACKDEPTH=0. FossilOrigin-Name: a9be4c2d56d08fea2cd1aab20b19092a45ef7620 --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/misc5.test | 2 ++ tool/lempar.c | 34 ++++++++++++++++++++++------------ 4 files changed, 32 insertions(+), 20 deletions(-) diff --git a/manifest b/manifest index cfe2236da5..fac75fe3b2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\sLemon-generated\sparser\sso\sthat\sit\scompiles\swith\s-DYYSTACKDEPTH=0.\nIt\sdoes\scompile\snow,\sbut\sthere\sare\ssubtle\sissues\sstill. -D 2016-05-27T01:07:18.565 +C Fix\sLemon\sso\sthat\sit\sactually\sworks\swith\s-DYYSTACKDEPTH=0. +D 2016-05-27T04:10:47.610 F Makefile.in f59e0763ff448719fc1bd25513882b0567286317 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7 @@ -929,7 +929,7 @@ F test/misc1.test 6430dabfb4b4fa480633590118964201f94d3ccc F test/misc2.test 00d7de54eda90e237fc9a38b9e5ccc769ebf6d4d F test/misc3.test cf3dda47d5dda3e53fc5804a100d3c82be736c9d F test/misc4.test 0d8be3466adf123a7791a66ba2bc8e8d229e87f3 -F test/misc5.test f96428ea95b3820aafc6f1c50cf48a09e4597ee1 +F test/misc5.test fff0f75e834bc09a39f6079320dd8c37de956f4f F test/misc6.test 953cc693924d88e6117aeba16f46f0bf5abede91 F test/misc7.test edd0b63e2ee29a256900b0514f6fff27e19e9bb2 F test/misc8.test 21ac9d35a5e110279ae9e1588b8914f54de1c60b @@ -1423,7 +1423,7 @@ F tool/genfkey.README cf68fddd4643bbe3ff8e31b8b6d8b0a1b85e20f4 F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5 F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce F tool/lemon.c 09a96bed19955697a5e20c49ad863ec2005815a2 -F tool/lempar.c 7689ddc408a54f9c23e7f9e17e597752b71fa537 +F tool/lempar.c f06b7e98a6b7efb404375b6f4a0c71c85faa1512 F tool/libvers.c caafc3b689638a1d88d44bc5f526c2278760d9b9 F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862 F tool/logest.c 11346aa019e2e77a00902aa7d0cabd27bd2e8cca @@ -1495,7 +1495,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ffe80a1bfa014943a614fc6993c1749b9bfec4c1 -R 8a7f49776364e838d9d2230beef644f3 +P 28d439f816d2fa5263e1c4ddecf3bf1ac2dd6549 +R 8847199d288118b0d192a3b11dedaea9 U drh -Z 81291c1e83b5b57f970177cd78c139d0 +Z bc76551811bb8ec7ccdce96ef01b993f diff --git a/manifest.uuid b/manifest.uuid index c2da443b16..9f517dff20 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -28d439f816d2fa5263e1c4ddecf3bf1ac2dd6549 \ No newline at end of file +a9be4c2d56d08fea2cd1aab20b19092a45ef7620 \ No newline at end of file diff --git a/test/misc5.test b/test/misc5.test index 30176b8082..0e7e34dd16 100644 --- a/test/misc5.test +++ b/test/misc5.test @@ -571,6 +571,8 @@ ifcapable subquery&&compound { # Overflow the lemon parser stack by providing an overly complex # expression. Make sure that the overflow is detected and reported. # +# This test fails when building with -DYYSTACKDEPTH=0 +# do_test misc5-7.1 { execsql {CREATE TABLE t1(x)} set sql "INSERT INTO t1 VALUES(" diff --git a/tool/lempar.c b/tool/lempar.c index e96d6c9e7f..1258c549de 100644 --- a/tool/lempar.c +++ b/tool/lempar.c @@ -214,6 +214,7 @@ struct yyParser { #if YYSTACKDEPTH<=0 int yystksz; /* Current side of the stack */ yyStackEntry *yystack; /* The parser's stack */ + yyStackEntry yystk0; /* First stack entry */ #else yyStackEntry yystack[YYSTACKDEPTH]; /* The parser's stack */ #endif @@ -271,27 +272,34 @@ static const char *const yyRuleName[] = { #if YYSTACKDEPTH<=0 /* -** Try to increase the size of the parser stack. +** Try to increase the size of the parser stack. Return the number +** of errors. Return 0 on success. */ -static void yyGrowStack(yyParser *p){ +static int yyGrowStack(yyParser *p){ int newSize; int idx; yyStackEntry *pNew; newSize = p->yystksz*2 + 100; idx = p->yytos ? (int)(p->yytos - p->yystack) : 0; - pNew = realloc(p->yystack, newSize*sizeof(pNew[0])); + if( p->yystack==&p->yystk0 ){ + pNew = malloc(newSize*sizeof(pNew[0])); + if( pNew ) pNew[0] = p->yystk0; + }else{ + pNew = realloc(p->yystack, newSize*sizeof(pNew[0])); + } if( pNew ){ p->yystack = pNew; p->yytos = &p->yystack[idx]; - p->yystksz = newSize; #ifndef NDEBUG if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sStack grows to %d entries!\n", - yyTracePrompt, p->yystksz); + fprintf(yyTraceFILE,"%sStack grows from %d to %d entries.\n", + yyTracePrompt, p->yystksz, newSize); } #endif + p->yystksz = newSize; } + return pNew==0; } #endif @@ -327,7 +335,10 @@ void *ParseAlloc(void *(*mallocProc)(YYMALLOCARGTYPE)){ pParser->yytos = NULL; pParser->yystack = NULL; pParser->yystksz = 0; - yyGrowStack(pParser); + if( yyGrowStack(pParser) ){ + pParser->yystack = &pParser->yystk0; + pParser->yystksz = 1; + } #endif pParser->yytos = pParser->yystack; pParser->yystack[0].stateno = 0; @@ -405,7 +416,7 @@ void ParseFree( #endif while( pParser->yytos>pParser->yystack ) yy_pop_parser_stack(pParser); #if YYSTACKDEPTH<=0 - free(pParser->yystack); + if( pParser->yystack!=&pParser->yystk0 ) free(pParser->yystack); #endif (*freeProc)((void*)pParser); } @@ -581,8 +592,7 @@ static void yy_shift( } #else if( yypParser->yytos>=&yypParser->yystack[yypParser->yystksz] ){ - yyGrowStack(yypParser); - if( yypParser->yytos>=&yypParser->yystack[yypParser->yystksz] ){ + if( yyGrowStack(yypParser) ){ yyStackOverflow(yypParser); return; } @@ -646,11 +656,11 @@ static void yy_reduce( } #else if( yypParser->yytos>=&yypParser->yystack[yypParser->yystksz-1] ){ - yyGrowStack(yypParser); - if( yypParser->yytos>=&yypParser->yystack[yypParser->yystksz-1] ){ + if( yyGrowStack(yypParser) ){ yyStackOverflow(yypParser); return; } + yymsp = yypParser->yytos; } #endif } From c84a4020efa68962c186aec680f41607fe87e4bd Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 27 May 2016 12:30:20 +0000 Subject: [PATCH 0470/1484] Improvements to WHERE-clause debug tracing. Show TK_MATCH expressions and show more details on WhereTerm traces. FossilOrigin-Name: 71087c12bc75a82f5d1051600a442ef6efc5e899 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/treeview.c | 6 ++++++ src/where.c | 35 ++++++++++++++++++++++++++--------- src/whereInt.h | 3 +++ 5 files changed, 44 insertions(+), 18 deletions(-) diff --git a/manifest b/manifest index fac75fe3b2..8c4974db29 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sLemon\sso\sthat\sit\sactually\sworks\swith\s-DYYSTACKDEPTH=0. -D 2016-05-27T04:10:47.610 +C Improvements\sto\sWHERE-clause\sdebug\stracing.\s\sShow\sTK_MATCH\sexpressions\sand\nshow\smore\sdetails\son\sWhereTerm\straces. +D 2016-05-27T12:30:20.162 F Makefile.in f59e0763ff448719fc1bd25513882b0567286317 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7 @@ -439,7 +439,7 @@ F src/test_windirent.h b12055cab6227f7be10f5c19296f67c60cc5e2a5 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c 3b29883b0ce4a6c6f643965b66b5ca6613178e59 -F src/treeview.c e4b41a37530a191579d3c53142cc44ee2eb99373 +F src/treeview.c c56d6ddbed564efda746236b35bcbb8238daac4b F src/trigger.c e14840ee0c3e549e758ec9bf3e4146e166002280 F src/update.c 4f05ea8cddfa367d045e03589756c02199e8f9bd F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c @@ -459,8 +459,8 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 02eeecc265f6ffd0597378f5d8ae9070b62a406a F src/wal.h 2f7c831cf3b071fa548bf2d5cac640846a7ff19c F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354 -F src/where.c 0e54a03d11d4e99ad25528f42ff4c9a6fa7a23da -F src/whereInt.h 6e18240be400bef8e4dbafea605251707c5dbf49 +F src/where.c b9f5b0ddb14c3827e70b5379e659cf4cfd524c4d +F src/whereInt.h e5b939701a7ceffc5a3a8188a37f9746416ebcd0 F src/wherecode.c ba71a4e4bada29aa9842200e6299714bf18c812c F src/whereexpr.c eacc0e60d029a082b4fc0cc42ea98544add1319e F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 @@ -1495,7 +1495,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 28d439f816d2fa5263e1c4ddecf3bf1ac2dd6549 -R 8847199d288118b0d192a3b11dedaea9 +P a9be4c2d56d08fea2cd1aab20b19092a45ef7620 +R 2beba98fee0a4944905820065cc75fbf U drh -Z bc76551811bb8ec7ccdce96ef01b993f +Z 8d7a3e9d02c8c2b09e27f05110ad65d3 diff --git a/manifest.uuid b/manifest.uuid index 9f517dff20..2f2802b83d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a9be4c2d56d08fea2cd1aab20b19092a45ef7620 \ No newline at end of file +71087c12bc75a82f5d1051600a442ef6efc5e899 \ No newline at end of file diff --git a/src/treeview.c b/src/treeview.c index 907159c06d..27996d46d7 100644 --- a/src/treeview.c +++ b/src/treeview.c @@ -445,6 +445,12 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){ break; } #endif + case TK_MATCH: { + sqlite3TreeViewLine(pView, "MATCH {%d:%d}%s", + pExpr->iTable, pExpr->iColumn, zFlgs); + sqlite3TreeViewExpr(pView, pExpr->pRight, 0); + break; + } default: { sqlite3TreeViewLine(pView, "op=%d", pExpr->op); break; diff --git a/src/where.c b/src/where.c index cb008b7df4..04d0b0190c 100644 --- a/src/where.c +++ b/src/where.c @@ -1648,19 +1648,41 @@ static void whereTermPrint(WhereTerm *pTerm, int iTerm){ sqlite3DebugPrintf("TERM-%-3d NULL\n", iTerm); }else{ char zType[4]; + char zLeft[50]; memcpy(zType, "...", 4); if( pTerm->wtFlags & TERM_VIRTUAL ) zType[0] = 'V'; if( pTerm->eOperator & WO_EQUIV ) zType[1] = 'E'; if( ExprHasProperty(pTerm->pExpr, EP_FromJoin) ) zType[2] = 'L'; + if( pTerm->eOperator & WO_SINGLE ){ + sqlite3_snprintf(sizeof(zLeft),zLeft,"left={%d:%d}", + pTerm->leftCursor, pTerm->u.leftColumn); + }else if( (pTerm->eOperator & WO_OR)!=0 && pTerm->u.pOrInfo!=0 ){ + sqlite3_snprintf(sizeof(zLeft),zLeft,"indexable=0x%lld", + pTerm->u.pOrInfo->indexable); + }else{ + sqlite3_snprintf(sizeof(zLeft),zLeft,"left=%d", pTerm->leftCursor); + } sqlite3DebugPrintf( - "TERM-%-3d %p %s cursor=%-3d prob=%-3d op=0x%03x wtFlags=0x%04x\n", - iTerm, pTerm, zType, pTerm->leftCursor, pTerm->truthProb, + "TERM-%-3d %p %s %-12s prob=%-3d op=0x%03x wtFlags=0x%04x\n", + iTerm, pTerm, zType, zLeft, pTerm->truthProb, pTerm->eOperator, pTerm->wtFlags); sqlite3TreeViewExpr(0, pTerm->pExpr, 0); } } #endif +#ifdef WHERETRACE_ENABLED +/* +** Show the complete content of a WhereClause +*/ +void sqlite3WhereClausePrint(WhereClause *pWC){ + int i; + for(i=0; inTerm; i++){ + whereTermPrint(&pWC->a[i], i); + } +} +#endif + #ifdef WHERETRACE_ENABLED /* ** Print a WhereLoop object for debugging purposes @@ -3124,9 +3146,7 @@ static int whereLoopAddOr( WHERETRACE(0x200, ("OR-term %d of %p has %d subterms:\n", (int)(pOrTerm-pOrWC->a), pTerm, sSubBuild.pWC->nTerm)); if( sqlite3WhereTrace & 0x400 ){ - for(i=0; inTerm; i++){ - whereTermPrint(&sSubBuild.pWC->a[i], i); - } + sqlite3WhereClausePrint(sSubBuild.pWC); } #endif #ifndef SQLITE_OMIT_VIRTUALTABLE @@ -4310,10 +4330,7 @@ WhereInfo *sqlite3WhereBegin( sqlite3DebugPrintf(")\n"); } if( sqlite3WhereTrace & 0x100 ){ /* Display all terms of the WHERE clause */ - int i; - for(i=0; inTerm; i++){ - whereTermPrint(&sWLB.pWC->a[i], i); - } + sqlite3WhereClausePrint(sWLB.pWC); } #endif diff --git a/src/whereInt.h b/src/whereInt.h index ed6b198e4b..075c04e5e5 100644 --- a/src/whereInt.h +++ b/src/whereInt.h @@ -437,6 +437,9 @@ struct WhereInfo { ** where.c: */ Bitmask sqlite3WhereGetMask(WhereMaskSet*,int); +#ifdef WHERETRACE_ENABLED +void sqlite3WhereClausePrint(WhereClause *pWC); +#endif WhereTerm *sqlite3WhereFindTerm( WhereClause *pWC, /* The WHERE clause to be searched */ int iCur, /* Cursor number of LHS */ From 15e2ddeab3c81cbe20c43cdb9643a2e1ca62b874 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Fri, 27 May 2016 18:09:45 +0000 Subject: [PATCH 0471/1484] Add basic compiler information to the results of 'PRAGMA compile_options'. FossilOrigin-Name: d734e2df40d95da74ce0c8dd2da1c14033cad8bb --- manifest | 17 ++++++++++------- manifest.uuid | 2 +- src/ctime.c | 7 +++++++ 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 8c4974db29..970b987929 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improvements\sto\sWHERE-clause\sdebug\stracing.\s\sShow\sTK_MATCH\sexpressions\sand\nshow\smore\sdetails\son\sWhereTerm\straces. -D 2016-05-27T12:30:20.162 +C Add\sbasic\scompiler\sinformation\sto\sthe\sresults\sof\s'PRAGMA\scompile_options'. +D 2016-05-27T18:09:45.039 F Makefile.in f59e0763ff448719fc1bd25513882b0567286317 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7 @@ -329,7 +329,7 @@ F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 F src/build.c 785fa789319d93c6ae20efbd01d4da9ce8f8a793 F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e -F src/ctime.c 60e135af364d777a9ab41c97e5e89cd224da6198 +F src/ctime.c dc03a31584045e0d7ee62659416c557bc35c679e F src/date.c 1cc9fb516ec9932c6fd4d2a0d2f8bc4480145c39 F src/dbstat.c c845548d4346e606e2f2b7d2e714ace2b8a7dd1b F src/delete.c 4aba4214a377ce8ddde2d2e609777bcc8235200f @@ -1495,7 +1495,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a9be4c2d56d08fea2cd1aab20b19092a45ef7620 -R 2beba98fee0a4944905820065cc75fbf -U drh -Z 8d7a3e9d02c8c2b09e27f05110ad65d3 +P 71087c12bc75a82f5d1051600a442ef6efc5e899 +R 5414a76b2e5839d41b19cee14a1187ef +T *branch * ctimeCompiler +T *sym-ctimeCompiler * +T -sym-trunk * +U mistachkin +Z 2c1781ffb1db3ba053f96360f37bbb14 diff --git a/manifest.uuid b/manifest.uuid index 2f2802b83d..bf8c366494 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -71087c12bc75a82f5d1051600a442ef6efc5e899 \ No newline at end of file +d734e2df40d95da74ce0c8dd2da1c14033cad8bb \ No newline at end of file diff --git a/src/ctime.c b/src/ctime.c index f1bb69c16a..f91615f44a 100644 --- a/src/ctime.c +++ b/src/ctime.c @@ -45,6 +45,13 @@ static const char * const azCompileOpt[] = { #if SQLITE_CHECK_PAGES "CHECK_PAGES", #endif +#if defined(_MSC_VER) + "COMPILER=msvc-" CTIMEOPT_VAL(_MSC_VER), +#elif defined(__GNUC__) && defined(__VERSION__) + "COMPILER=gcc-" CTIMEOPT_VAL(__VERSION__), +#elif defined(__clang__) && defined(__clang_version__) + "COMPILER=clang-" CTIMEOPT_VAL(__clang_version__), +#endif #if SQLITE_COVERAGE_TEST "COVERAGE_TEST", #endif From 2b9672e998099c1c7fd96e8b0f621f61cd85cc31 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 27 May 2016 19:34:29 +0000 Subject: [PATCH 0472/1484] Remove surplus quotation marks from the COMPILER= compile_options setting for GCC. FossilOrigin-Name: 664c132dabe4a871d5c39c11b339f871ca3a5d31 --- manifest | 17 +++++++---------- manifest.uuid | 2 +- src/ctime.c | 2 +- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 970b987929..6dcca4db34 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sbasic\scompiler\sinformation\sto\sthe\sresults\sof\s'PRAGMA\scompile_options'. -D 2016-05-27T18:09:45.039 +C Remove\ssurplus\squotation\smarks\sfrom\sthe\sCOMPILER=\scompile_options\ssetting\nfor\sGCC. +D 2016-05-27T19:34:29.738 F Makefile.in f59e0763ff448719fc1bd25513882b0567286317 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7 @@ -329,7 +329,7 @@ F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 F src/build.c 785fa789319d93c6ae20efbd01d4da9ce8f8a793 F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e -F src/ctime.c dc03a31584045e0d7ee62659416c557bc35c679e +F src/ctime.c 7d735d9700670e61f415f0874cee3888515b94db F src/date.c 1cc9fb516ec9932c6fd4d2a0d2f8bc4480145c39 F src/dbstat.c c845548d4346e606e2f2b7d2e714ace2b8a7dd1b F src/delete.c 4aba4214a377ce8ddde2d2e609777bcc8235200f @@ -1495,10 +1495,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 71087c12bc75a82f5d1051600a442ef6efc5e899 -R 5414a76b2e5839d41b19cee14a1187ef -T *branch * ctimeCompiler -T *sym-ctimeCompiler * -T -sym-trunk * -U mistachkin -Z 2c1781ffb1db3ba053f96360f37bbb14 +P d734e2df40d95da74ce0c8dd2da1c14033cad8bb +R ee122ac8c0e3fee0c343c143c0eaf533 +U drh +Z 748a461f334251e4f63154f77f6b9c4a diff --git a/manifest.uuid b/manifest.uuid index bf8c366494..3464a2a6e1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d734e2df40d95da74ce0c8dd2da1c14033cad8bb \ No newline at end of file +664c132dabe4a871d5c39c11b339f871ca3a5d31 \ No newline at end of file diff --git a/src/ctime.c b/src/ctime.c index f91615f44a..0fc1c4cd0c 100644 --- a/src/ctime.c +++ b/src/ctime.c @@ -48,7 +48,7 @@ static const char * const azCompileOpt[] = { #if defined(_MSC_VER) "COMPILER=msvc-" CTIMEOPT_VAL(_MSC_VER), #elif defined(__GNUC__) && defined(__VERSION__) - "COMPILER=gcc-" CTIMEOPT_VAL(__VERSION__), + "COMPILER=gcc-" __VERSION__, #elif defined(__clang__) && defined(__clang_version__) "COMPILER=clang-" CTIMEOPT_VAL(__clang_version__), #endif From 756e09c338a73c807506ce4b4c4e391cb5b69b1e Mon Sep 17 00:00:00 2001 From: mistachkin Date: Fri, 27 May 2016 20:30:02 +0000 Subject: [PATCH 0473/1484] Remove surplus quotation marks from the COMPILER= compile_options setting for Clang. FossilOrigin-Name: 5c966f200018043f5258eb03e043bb25c7766131 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/ctime.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 6dcca4db34..6b25a7bcf8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\ssurplus\squotation\smarks\sfrom\sthe\sCOMPILER=\scompile_options\ssetting\nfor\sGCC. -D 2016-05-27T19:34:29.738 +C Remove\ssurplus\squotation\smarks\sfrom\sthe\sCOMPILER=\scompile_options\ssetting\sfor\sClang. +D 2016-05-27T20:30:02.032 F Makefile.in f59e0763ff448719fc1bd25513882b0567286317 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7 @@ -329,7 +329,7 @@ F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 F src/build.c 785fa789319d93c6ae20efbd01d4da9ce8f8a793 F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e -F src/ctime.c 7d735d9700670e61f415f0874cee3888515b94db +F src/ctime.c 5fffce9c220c2694bdefcc5297d77f14266370b8 F src/date.c 1cc9fb516ec9932c6fd4d2a0d2f8bc4480145c39 F src/dbstat.c c845548d4346e606e2f2b7d2e714ace2b8a7dd1b F src/delete.c 4aba4214a377ce8ddde2d2e609777bcc8235200f @@ -1495,7 +1495,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d734e2df40d95da74ce0c8dd2da1c14033cad8bb -R ee122ac8c0e3fee0c343c143c0eaf533 -U drh -Z 748a461f334251e4f63154f77f6b9c4a +P 664c132dabe4a871d5c39c11b339f871ca3a5d31 +R c95d80b350856738e8dbac827a63287b +U mistachkin +Z 5ee041c65db3cfb46a182fca07281d4b diff --git a/manifest.uuid b/manifest.uuid index 3464a2a6e1..aeff037a85 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -664c132dabe4a871d5c39c11b339f871ca3a5d31 \ No newline at end of file +5c966f200018043f5258eb03e043bb25c7766131 \ No newline at end of file diff --git a/src/ctime.c b/src/ctime.c index 0fc1c4cd0c..a39917af99 100644 --- a/src/ctime.c +++ b/src/ctime.c @@ -50,7 +50,7 @@ static const char * const azCompileOpt[] = { #elif defined(__GNUC__) && defined(__VERSION__) "COMPILER=gcc-" __VERSION__, #elif defined(__clang__) && defined(__clang_version__) - "COMPILER=clang-" CTIMEOPT_VAL(__clang_version__), + "COMPILER=clang-" __clang_version__, #endif #if SQLITE_COVERAGE_TEST "COVERAGE_TEST", From 7ce6cdd51511feeaa45b02451424f64bfabadd50 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Fri, 27 May 2016 21:13:43 +0000 Subject: [PATCH 0474/1484] Check for Clang before GCC. FossilOrigin-Name: 7c2cd4b05f88a759bdf72d3a249db5984fd7105d --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/ctime.c | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 6b25a7bcf8..43de9fbb03 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\ssurplus\squotation\smarks\sfrom\sthe\sCOMPILER=\scompile_options\ssetting\sfor\sClang. -D 2016-05-27T20:30:02.032 +C Check\sfor\sClang\sbefore\sGCC. +D 2016-05-27T21:13:43.995 F Makefile.in f59e0763ff448719fc1bd25513882b0567286317 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7 @@ -329,7 +329,7 @@ F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 F src/build.c 785fa789319d93c6ae20efbd01d4da9ce8f8a793 F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e -F src/ctime.c 5fffce9c220c2694bdefcc5297d77f14266370b8 +F src/ctime.c 89ae9d9959010022a14bb36dea1b360da760b092 F src/date.c 1cc9fb516ec9932c6fd4d2a0d2f8bc4480145c39 F src/dbstat.c c845548d4346e606e2f2b7d2e714ace2b8a7dd1b F src/delete.c 4aba4214a377ce8ddde2d2e609777bcc8235200f @@ -1495,7 +1495,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 664c132dabe4a871d5c39c11b339f871ca3a5d31 -R c95d80b350856738e8dbac827a63287b +P 5c966f200018043f5258eb03e043bb25c7766131 +R f374868f610dd3d0429b813be905b071 U mistachkin -Z 5ee041c65db3cfb46a182fca07281d4b +Z 313307f37a580f7772d82428c7123b20 diff --git a/manifest.uuid b/manifest.uuid index aeff037a85..41c0c8e659 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5c966f200018043f5258eb03e043bb25c7766131 \ No newline at end of file +7c2cd4b05f88a759bdf72d3a249db5984fd7105d \ No newline at end of file diff --git a/src/ctime.c b/src/ctime.c index a39917af99..b33d803ba2 100644 --- a/src/ctime.c +++ b/src/ctime.c @@ -47,10 +47,10 @@ static const char * const azCompileOpt[] = { #endif #if defined(_MSC_VER) "COMPILER=msvc-" CTIMEOPT_VAL(_MSC_VER), -#elif defined(__GNUC__) && defined(__VERSION__) - "COMPILER=gcc-" __VERSION__, #elif defined(__clang__) && defined(__clang_version__) "COMPILER=clang-" __clang_version__, +#elif defined(__GNUC__) && defined(__VERSION__) + "COMPILER=gcc-" __VERSION__, #endif #if SQLITE_COVERAGE_TEST "COVERAGE_TEST", From f35b8f83697d5dfbaab607f1cef7be738fdbaec0 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Sat, 28 May 2016 00:13:21 +0000 Subject: [PATCH 0475/1484] Clang can define _MSC_VER in some circumstances; therefore, check for Clang first. FossilOrigin-Name: 3f710bc3617691fa7432a24f1410d4651ca181b6 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/ctime.c | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 43de9fbb03..b6da3f6920 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Check\sfor\sClang\sbefore\sGCC. -D 2016-05-27T21:13:43.995 +C Clang\scan\sdefine\s_MSC_VER\sin\ssome\scircumstances;\stherefore,\scheck\sfor\sClang\sfirst. +D 2016-05-28T00:13:21.036 F Makefile.in f59e0763ff448719fc1bd25513882b0567286317 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7 @@ -329,7 +329,7 @@ F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 F src/build.c 785fa789319d93c6ae20efbd01d4da9ce8f8a793 F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e -F src/ctime.c 89ae9d9959010022a14bb36dea1b360da760b092 +F src/ctime.c 999a828425b35b8092a8cde25690e71c20906344 F src/date.c 1cc9fb516ec9932c6fd4d2a0d2f8bc4480145c39 F src/dbstat.c c845548d4346e606e2f2b7d2e714ace2b8a7dd1b F src/delete.c 4aba4214a377ce8ddde2d2e609777bcc8235200f @@ -1495,7 +1495,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 5c966f200018043f5258eb03e043bb25c7766131 -R f374868f610dd3d0429b813be905b071 +P 7c2cd4b05f88a759bdf72d3a249db5984fd7105d +R 49f2ff6c03dd42bcf8b96859a75667c2 U mistachkin -Z 313307f37a580f7772d82428c7123b20 +Z 7fd0da57a78dfad092dddeef636c580c diff --git a/manifest.uuid b/manifest.uuid index 41c0c8e659..5f707fe176 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7c2cd4b05f88a759bdf72d3a249db5984fd7105d \ No newline at end of file +3f710bc3617691fa7432a24f1410d4651ca181b6 \ No newline at end of file diff --git a/src/ctime.c b/src/ctime.c index b33d803ba2..589cabc1ab 100644 --- a/src/ctime.c +++ b/src/ctime.c @@ -45,10 +45,10 @@ static const char * const azCompileOpt[] = { #if SQLITE_CHECK_PAGES "CHECK_PAGES", #endif -#if defined(_MSC_VER) - "COMPILER=msvc-" CTIMEOPT_VAL(_MSC_VER), -#elif defined(__clang__) && defined(__clang_version__) +#if defined(__clang__) && defined(__clang_version__) "COMPILER=clang-" __clang_version__, +#elif defined(_MSC_VER) + "COMPILER=msvc-" CTIMEOPT_VAL(_MSC_VER), #elif defined(__GNUC__) && defined(__VERSION__) "COMPILER=gcc-" __VERSION__, #endif From 3c40ae7d3aa982d7f389be43ce11263219dfe1ea Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 28 May 2016 14:53:48 +0000 Subject: [PATCH 0476/1484] Add the vfsstat.c loadable extension - a VFS shim that measures the amount of I/O, and an eponymous virtual table that is used to extract and view the measurements. FossilOrigin-Name: 0987487dd4ebfcf66ddeec8ceca47775216a0887 --- ext/misc/vfsstat.c | 819 +++++++++++++++++++++++++++++++++++++++++++++ manifest | 11 +- manifest.uuid | 2 +- 3 files changed, 826 insertions(+), 6 deletions(-) create mode 100644 ext/misc/vfsstat.c diff --git a/ext/misc/vfsstat.c b/ext/misc/vfsstat.c new file mode 100644 index 0000000000..e519de6341 --- /dev/null +++ b/ext/misc/vfsstat.c @@ -0,0 +1,819 @@ +/* +** 2016-05-27 +** +** 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 contains the implementation of an SQLite vfs shim that +** tracks I/O. Access to the accumulated status counts is provided using +** an eponymous virtual table. +*/ +#include +SQLITE_EXTENSION_INIT1 + +/* +** This module contains code for a wrapper VFS that cause stats for +** most VFS calls to be recorded. +** +** To use this module, first compile it as a loadable extension. See +** https://www.sqlite.org/loadext.html#build for compilations instructions. +** +** After compliing, load this extension, then open database connections to be +** measured. Query usages status using the vfsstat virtual table: +** +** SELECT * FROM vfsstat; +** +** Reset counters using UPDATE statements against vfsstat: +** +** UPDATE vfsstat SET count=0; +** +** EXAMPLE SCRIPT: +** +** .load ./vfsstat +** .open test.db +** DROP TABLE IF EXISTS t1; +** CREATE TABLE t1(x,y); +** INSERT INTO t1 VALUES(123, randomblob(5000)); +** CREATE INDEX t1x ON t1(x); +** DROP TABLE t1; +** VACUUM; +** SELECT * FROM vfsstat WHERE count>0; +** +** LIMITATIONS: +** +** This module increments counters without using mutex protection. So if +** two or more threads try to use this module at the same time, race conditions +** may occur which mess up the counts. This is harmless, other than giving +** incorrect statistics. +*/ +#include +#include +#include + +/* +** File types +*/ +#define VFSSTAT_MAIN 0 /* Main database file */ +#define VFSSTAT_JOURNAL 1 /* Rollback journal */ +#define VFSSTAT_WAL 2 /* Write-ahead log file */ +#define VFSSTAT_MASTERJRNL 3 /* Master journal */ +#define VFSSTAT_SUBJRNL 4 /* Subjournal */ +#define VFSSTAT_TEMPDB 5 /* TEMP database */ +#define VFSSTAT_TEMPJRNL 6 /* Journal for TEMP database */ +#define VFSSTAT_TRANSIENT 7 /* Transient database */ +#define VFSSTAT_ANY 8 /* Unspecified file type */ +#define VFSSTAT_nFile 9 /* This many file types */ + +/* Names of the file types. These are allowed values for the +** first column of the vfsstat virtual table. +*/ +static const char *azFile[] = { + "database", "journal", "wal", "master-journal", "sub-journal", + "temp-database", "temp-journal", "transient-db", "*" +}; + +/* +** Stat types +*/ +#define VFSSTAT_BYTESIN 0 /* Bytes read in */ +#define VFSSTAT_BYTESOUT 1 /* Bytes written out */ +#define VFSSTAT_READ 2 /* Read requests */ +#define VFSSTAT_WRITE 3 /* Write requests */ +#define VFSSTAT_SYNC 4 /* Syncs */ +#define VFSSTAT_OPEN 5 /* File opens */ +#define VFSSTAT_LOCK 6 /* Lock requests */ +#define VFSSTAT_ACCESS 0 /* xAccess calls. filetype==ANY only */ +#define VFSSTAT_DELETE 1 /* xDelete calls. filetype==ANY only */ +#define VFSSTAT_FULLPATH 2 /* xFullPathname calls. ANY only */ +#define VFSSTAT_RANDOM 3 /* xRandomness calls. ANY only */ +#define VFSSTAT_SLEEP 4 /* xSleep calls. ANY only */ +#define VFSSTAT_CURTIME 5 /* xCurrentTime calls. ANY only */ +#define VFSSTAT_nStat 7 /* This many stat types */ + + +/* Names for the second column of the vfsstat virtual table for all +** cases except when the first column is "*" or VFSSTAT_ANY. */ +static const char *azStat[] = { + "bytes-in", "bytes-out", "read", "write", "sync", "open", "lock", +}; +static const char *azStatAny[] = { + "access", "delete", "fullpathname", "randomness", "sleep", "currenttimestamp", + "not-used" +}; + +/* Total number of counters */ +#define VFSSTAT_MXCNT (VFSSTAT_nStat*VFSSTAT_nFile) + +/* +** Performance stats are collected in an instance of the following +** global array. +*/ +static sqlite3_uint64 aVfsCnt[VFSSTAT_MXCNT]; + +/* +** Access to a specific counter +*/ +#define STATCNT(filetype,stat) (aVfsCnt[(filetype)*VFSSTAT_nStat+(stat)]) + +/* +** Forward declaration of objects used by this utility +*/ +typedef struct VStatVfs VStatVfs; +typedef struct VStatFile VStatFile; + +/* An instance of the VFS */ +struct VStatVfs { + sqlite3_vfs base; /* VFS methods */ + sqlite3_vfs *pVfs; /* Parent VFS */ +}; + +/* An open file */ +struct VStatFile { + sqlite3_file base; /* IO methods */ + sqlite3_file *pReal; /* Underlying file handle */ + unsigned char eFiletype; /* What type of file is this */ +}; + +#define REALVFS(p) (((VStatVfs*)(p))->pVfs) + +/* +** Methods for VStatFile +*/ +static int vstatClose(sqlite3_file*); +static int vstatRead(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst); +static int vstatWrite(sqlite3_file*,const void*,int iAmt, sqlite3_int64 iOfst); +static int vstatTruncate(sqlite3_file*, sqlite3_int64 size); +static int vstatSync(sqlite3_file*, int flags); +static int vstatFileSize(sqlite3_file*, sqlite3_int64 *pSize); +static int vstatLock(sqlite3_file*, int); +static int vstatUnlock(sqlite3_file*, int); +static int vstatCheckReservedLock(sqlite3_file*, int *pResOut); +static int vstatFileControl(sqlite3_file*, int op, void *pArg); +static int vstatSectorSize(sqlite3_file*); +static int vstatDeviceCharacteristics(sqlite3_file*); +static int vstatShmMap(sqlite3_file*, int iPg, int pgsz, int, void volatile**); +static int vstatShmLock(sqlite3_file*, int offset, int n, int flags); +static void vstatShmBarrier(sqlite3_file*); +static int vstatShmUnmap(sqlite3_file*, int deleteFlag); +static int vstatFetch(sqlite3_file*, sqlite3_int64 iOfst, int iAmt, void **pp); +static int vstatUnfetch(sqlite3_file*, sqlite3_int64 iOfst, void *p); + +/* +** Methods for VStatVfs +*/ +static int vstatOpen(sqlite3_vfs*, const char *, sqlite3_file*, int , int *); +static int vstatDelete(sqlite3_vfs*, const char *zName, int syncDir); +static int vstatAccess(sqlite3_vfs*, const char *zName, int flags, int *); +static int vstatFullPathname(sqlite3_vfs*, const char *zName, int, char *zOut); +static void *vstatDlOpen(sqlite3_vfs*, const char *zFilename); +static void vstatDlError(sqlite3_vfs*, int nByte, char *zErrMsg); +static void (*vstatDlSym(sqlite3_vfs *pVfs, void *p, const char*zSym))(void); +static void vstatDlClose(sqlite3_vfs*, void*); +static int vstatRandomness(sqlite3_vfs*, int nByte, char *zOut); +static int vstatSleep(sqlite3_vfs*, int microseconds); +static int vstatCurrentTime(sqlite3_vfs*, double*); +static int vstatGetLastError(sqlite3_vfs*, int, char *); +static int vstatCurrentTimeInt64(sqlite3_vfs*, sqlite3_int64*); + +static VStatVfs vstat_vfs = { + { + 2, /* iVersion */ + 0, /* szOsFile (set by register_vstat()) */ + 1024, /* mxPathname */ + 0, /* pNext */ + "vfslog", /* zName */ + 0, /* pAppData */ + vstatOpen, /* xOpen */ + vstatDelete, /* xDelete */ + vstatAccess, /* xAccess */ + vstatFullPathname, /* xFullPathname */ + vstatDlOpen, /* xDlOpen */ + vstatDlError, /* xDlError */ + vstatDlSym, /* xDlSym */ + vstatDlClose, /* xDlClose */ + vstatRandomness, /* xRandomness */ + vstatSleep, /* xSleep */ + vstatCurrentTime, /* xCurrentTime */ + vstatGetLastError, /* xGetLastError */ + vstatCurrentTimeInt64 /* xCurrentTimeInt64 */ + }, + 0 +}; + +static const sqlite3_io_methods vstat_io_methods = { + 3, /* iVersion */ + vstatClose, /* xClose */ + vstatRead, /* xRead */ + vstatWrite, /* xWrite */ + vstatTruncate, /* xTruncate */ + vstatSync, /* xSync */ + vstatFileSize, /* xFileSize */ + vstatLock, /* xLock */ + vstatUnlock, /* xUnlock */ + vstatCheckReservedLock, /* xCheckReservedLock */ + vstatFileControl, /* xFileControl */ + vstatSectorSize, /* xSectorSize */ + vstatDeviceCharacteristics, /* xDeviceCharacteristics */ + vstatShmMap, /* xShmMap */ + vstatShmLock, /* xShmLock */ + vstatShmBarrier, /* xShmBarrier */ + vstatShmUnmap, /* xShmUnmap */ + vstatFetch, /* xFetch */ + vstatUnfetch /* xUnfetch */ +}; + + + +/* +** Close an vstat-file. +*/ +static int vstatClose(sqlite3_file *pFile){ + VStatFile *p = (VStatFile *)pFile; + int rc = SQLITE_OK; + + if( p->pReal->pMethods ){ + rc = p->pReal->pMethods->xClose(p->pReal); + } + return rc; +} + + +/* +** Read data from an vstat-file. +*/ +static int vstatRead( + sqlite3_file *pFile, + void *zBuf, + int iAmt, + sqlite_int64 iOfst +){ + int rc; + VStatFile *p = (VStatFile *)pFile; + + rc = p->pReal->pMethods->xRead(p->pReal, zBuf, iAmt, iOfst); + STATCNT(p->eFiletype,VFSSTAT_READ)++; + if( rc==SQLITE_OK ){ + STATCNT(p->eFiletype,VFSSTAT_BYTESIN) += iAmt; + } + return rc; +} + +/* +** Write data to an vstat-file. +*/ +static int vstatWrite( + sqlite3_file *pFile, + const void *z, + int iAmt, + sqlite_int64 iOfst +){ + int rc; + VStatFile *p = (VStatFile *)pFile; + + rc = p->pReal->pMethods->xWrite(p->pReal, z, iAmt, iOfst); + STATCNT(p->eFiletype,VFSSTAT_WRITE)++; + if( rc==SQLITE_OK ){ + STATCNT(p->eFiletype,VFSSTAT_BYTESOUT) += iAmt; + } + return rc; +} + +/* +** Truncate an vstat-file. +*/ +static int vstatTruncate(sqlite3_file *pFile, sqlite_int64 size){ + int rc; + VStatFile *p = (VStatFile *)pFile; + rc = p->pReal->pMethods->xTruncate(p->pReal, size); + return rc; +} + +/* +** Sync an vstat-file. +*/ +static int vstatSync(sqlite3_file *pFile, int flags){ + int rc; + VStatFile *p = (VStatFile *)pFile; + rc = p->pReal->pMethods->xSync(p->pReal, flags); + STATCNT(p->eFiletype,VFSSTAT_SYNC)++; + return rc; +} + +/* +** Return the current file-size of an vstat-file. +*/ +static int vstatFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){ + int rc; + VStatFile *p = (VStatFile *)pFile; + rc = p->pReal->pMethods->xFileSize(p->pReal, pSize); + return rc; +} + +/* +** Lock an vstat-file. +*/ +static int vstatLock(sqlite3_file *pFile, int eLock){ + int rc; + VStatFile *p = (VStatFile *)pFile; + rc = p->pReal->pMethods->xLock(p->pReal, eLock); + STATCNT(p->eFiletype,VFSSTAT_LOCK)++; + return rc; +} + +/* +** Unlock an vstat-file. +*/ +static int vstatUnlock(sqlite3_file *pFile, int eLock){ + int rc; + VStatFile *p = (VStatFile *)pFile; + rc = p->pReal->pMethods->xUnlock(p->pReal, eLock); + STATCNT(p->eFiletype,VFSSTAT_LOCK)++; + return rc; +} + +/* +** Check if another file-handle holds a RESERVED lock on an vstat-file. +*/ +static int vstatCheckReservedLock(sqlite3_file *pFile, int *pResOut){ + int rc; + VStatFile *p = (VStatFile *)pFile; + rc = p->pReal->pMethods->xCheckReservedLock(p->pReal, pResOut); + STATCNT(p->eFiletype,VFSSTAT_LOCK)++; + return rc; +} + +/* +** File control method. For custom operations on an vstat-file. +*/ +static int vstatFileControl(sqlite3_file *pFile, int op, void *pArg){ + VStatFile *p = (VStatFile *)pFile; + int rc; + rc = p->pReal->pMethods->xFileControl(p->pReal, op, pArg); + if( op==SQLITE_FCNTL_VFSNAME && rc==SQLITE_OK ){ + *(char**)pArg = sqlite3_mprintf("vstat/%z", *(char**)pArg); + } + return rc; +} + +/* +** Return the sector-size in bytes for an vstat-file. +*/ +static int vstatSectorSize(sqlite3_file *pFile){ + int rc; + VStatFile *p = (VStatFile *)pFile; + rc = p->pReal->pMethods->xSectorSize(p->pReal); + return rc; +} + +/* +** Return the device characteristic flags supported by an vstat-file. +*/ +static int vstatDeviceCharacteristics(sqlite3_file *pFile){ + int rc; + VStatFile *p = (VStatFile *)pFile; + rc = p->pReal->pMethods->xDeviceCharacteristics(p->pReal); + return rc; +} + +/* Create a shared memory file mapping */ +static int vstatShmMap( + sqlite3_file *pFile, + int iPg, + int pgsz, + int bExtend, + void volatile **pp +){ + VStatFile *p = (VStatFile *)pFile; + return p->pReal->pMethods->xShmMap(p->pReal, iPg, pgsz, bExtend, pp); +} + +/* Perform locking on a shared-memory segment */ +static int vstatShmLock(sqlite3_file *pFile, int offset, int n, int flags){ + VStatFile *p = (VStatFile *)pFile; + return p->pReal->pMethods->xShmLock(p->pReal, offset, n, flags); +} + +/* Memory barrier operation on shared memory */ +static void vstatShmBarrier(sqlite3_file *pFile){ + VStatFile *p = (VStatFile *)pFile; + return p->pReal->pMethods->xShmBarrier(p->pReal); +} + +/* Unmap a shared memory segment */ +static int vstatShmUnmap(sqlite3_file *pFile, int deleteFlag){ + VStatFile *p = (VStatFile *)pFile; + return p->pReal->pMethods->xShmUnmap(p->pReal, deleteFlag); +} + +/* Fetch a page of a memory-mapped file */ +static int vstatFetch( + sqlite3_file *pFile, + sqlite3_int64 iOfst, + int iAmt, + void **pp +){ + VStatFile *p = (VStatFile *)pFile; + return p->pReal->pMethods->xFetch(p->pReal, iOfst, iAmt, pp); +} + +/* Release a memory-mapped page */ +static int vstatUnfetch(sqlite3_file *pFile, sqlite3_int64 iOfst, void *pPage){ + VStatFile *p = (VStatFile *)pFile; + return p->pReal->pMethods->xUnfetch(p->pReal, iOfst, pPage); +} + +/* +** Open an vstat file handle. +*/ +static int vstatOpen( + sqlite3_vfs *pVfs, + const char *zName, + sqlite3_file *pFile, + int flags, + int *pOutFlags +){ + int rc; + VStatFile *p = (VStatFile*)pFile; + + p->pReal = (sqlite3_file*)&p[1]; + rc = REALVFS(pVfs)->xOpen(REALVFS(pVfs), zName, p->pReal, flags, pOutFlags); + if( flags & SQLITE_OPEN_MAIN_DB ){ + p->eFiletype = VFSSTAT_MAIN; + }else if( flags & SQLITE_OPEN_MAIN_JOURNAL ){ + p->eFiletype = VFSSTAT_JOURNAL; + }else if( flags & SQLITE_OPEN_WAL ){ + p->eFiletype = VFSSTAT_WAL; + }else if( flags & SQLITE_OPEN_MASTER_JOURNAL ){ + p->eFiletype = VFSSTAT_MASTERJRNL; + }else if( flags & SQLITE_OPEN_SUBJOURNAL ){ + p->eFiletype = VFSSTAT_SUBJRNL; + }else if( flags & SQLITE_OPEN_TEMP_DB ){ + p->eFiletype = VFSSTAT_TEMPDB; + }else if( flags & SQLITE_OPEN_TEMP_JOURNAL ){ + p->eFiletype = VFSSTAT_TEMPJRNL; + }else{ + p->eFiletype = VFSSTAT_TRANSIENT; + } + STATCNT(p->eFiletype,VFSSTAT_OPEN)++; + pFile->pMethods = rc ? 0 : &vstat_io_methods; + return rc; +} + +/* +** Delete the file located at zPath. If the dirSync argument is true, +** ensure the file-system modifications are synced to disk before +** returning. +*/ +static int vstatDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){ + int rc; + rc = REALVFS(pVfs)->xDelete(REALVFS(pVfs), zPath, dirSync); + STATCNT(VFSSTAT_ANY,VFSSTAT_DELETE)++; + return rc; +} + +/* +** Test for access permissions. Return true if the requested permission +** is available, or false otherwise. +*/ +static int vstatAccess( + sqlite3_vfs *pVfs, + const char *zPath, + int flags, + int *pResOut +){ + int rc; + rc = REALVFS(pVfs)->xAccess(REALVFS(pVfs), zPath, flags, pResOut); + STATCNT(VFSSTAT_ANY,VFSSTAT_ACCESS)++; + return rc; +} + +/* +** Populate buffer zOut with the full canonical pathname corresponding +** to the pathname in zPath. zOut is guaranteed to point to a buffer +** of at least (INST_MAX_PATHNAME+1) bytes. +*/ +static int vstatFullPathname( + sqlite3_vfs *pVfs, + const char *zPath, + int nOut, + char *zOut +){ + STATCNT(VFSSTAT_ANY,VFSSTAT_FULLPATH)++; + return REALVFS(pVfs)->xFullPathname(REALVFS(pVfs), zPath, nOut, zOut); +} + +/* +** Open the dynamic library located at zPath and return a handle. +*/ +static void *vstatDlOpen(sqlite3_vfs *pVfs, const char *zPath){ + return REALVFS(pVfs)->xDlOpen(REALVFS(pVfs), zPath); +} + +/* +** Populate the buffer zErrMsg (size nByte bytes) with a human readable +** utf-8 string describing the most recent error encountered associated +** with dynamic libraries. +*/ +static void vstatDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){ + REALVFS(pVfs)->xDlError(REALVFS(pVfs), nByte, zErrMsg); +} + +/* +** Return a pointer to the symbol zSymbol in the dynamic library pHandle. +*/ +static void (*vstatDlSym(sqlite3_vfs *pVfs, void *p, const char *zSym))(void){ + return REALVFS(pVfs)->xDlSym(REALVFS(pVfs), p, zSym); +} + +/* +** Close the dynamic library handle pHandle. +*/ +static void vstatDlClose(sqlite3_vfs *pVfs, void *pHandle){ + REALVFS(pVfs)->xDlClose(REALVFS(pVfs), pHandle); +} + +/* +** Populate the buffer pointed to by zBufOut with nByte bytes of +** random data. +*/ +static int vstatRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){ + STATCNT(VFSSTAT_ANY,VFSSTAT_RANDOM)++; + return REALVFS(pVfs)->xRandomness(REALVFS(pVfs), nByte, zBufOut); +} + +/* +** Sleep for nMicro microseconds. Return the number of microseconds +** actually slept. +*/ +static int vstatSleep(sqlite3_vfs *pVfs, int nMicro){ + STATCNT(VFSSTAT_ANY,VFSSTAT_SLEEP)++; + return REALVFS(pVfs)->xSleep(REALVFS(pVfs), nMicro); +} + +/* +** Return the current time as a Julian Day number in *pTimeOut. +*/ +static int vstatCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){ + STATCNT(VFSSTAT_ANY,VFSSTAT_CURTIME)++; + return REALVFS(pVfs)->xCurrentTime(REALVFS(pVfs), pTimeOut); +} + +static int vstatGetLastError(sqlite3_vfs *pVfs, int a, char *b){ + return REALVFS(pVfs)->xGetLastError(REALVFS(pVfs), a, b); +} +static int vstatCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *p){ + STATCNT(VFSSTAT_ANY,VFSSTAT_CURTIME)++; + return REALVFS(pVfs)->xCurrentTimeInt64(REALVFS(pVfs), p); +} + +/* +** A virtual table for accessing the stats collected by this VFS shim +*/ +static int vstattabConnect(sqlite3*, void*, int, const char*const*, + sqlite3_vtab**,char**); +static int vstattabBestIndex(sqlite3_vtab*,sqlite3_index_info*); +static int vstattabDisconnect(sqlite3_vtab*); +static int vstattabOpen(sqlite3_vtab*, sqlite3_vtab_cursor**); +static int vstattabClose(sqlite3_vtab_cursor*); +static int vstattabFilter(sqlite3_vtab_cursor*, int idxNum, const char *idxStr, + int argc, sqlite3_value **argv); +static int vstattabNext(sqlite3_vtab_cursor*); +static int vstattabEof(sqlite3_vtab_cursor*); +static int vstattabColumn(sqlite3_vtab_cursor*,sqlite3_context*,int); +static int vstattabRowid(sqlite3_vtab_cursor*,sqlite3_int64*); +static int vstattabUpdate(sqlite3_vtab*,int,sqlite3_value**,sqlite3_int64*); + +/* A cursor for the vfsstat virtual table */ +typedef struct VfsStatCursor { + sqlite3_vtab_cursor base; /* Base class. Must be first */ + int i; /* Pointing to this aVfsCnt[] value */ +} VfsStatCursor; + + +static int vstattabConnect( + sqlite3 *db, + void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVtab, + char **pzErr +){ + sqlite3_vtab *pNew; + int rc; + +/* Column numbers */ +#define VSTAT_COLUMN_FILE 0 +#define VSTAT_COLUMN_STAT 1 +#define VSTAT_COLUMN_COUNT 2 + + rc = sqlite3_declare_vtab(db,"CREATE TABLE x(file,stat,count)"); + if( rc==SQLITE_OK ){ + pNew = *ppVtab = sqlite3_malloc( sizeof(*pNew) ); + if( pNew==0 ) return SQLITE_NOMEM; + memset(pNew, 0, sizeof(*pNew)); + } + return rc; +} + +/* +** This method is the destructor for vstat table object. +*/ +static int vstattabDisconnect(sqlite3_vtab *pVtab){ + sqlite3_free(pVtab); + return SQLITE_OK; +} + +/* +** Constructor for a new vstat table cursor object. +*/ +static int vstattabOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){ + VfsStatCursor *pCur; + pCur = sqlite3_malloc( sizeof(*pCur) ); + if( pCur==0 ) return SQLITE_NOMEM; + memset(pCur, 0, sizeof(*pCur)); + *ppCursor = &pCur->base; + return SQLITE_OK; +} + + +/* +** Destructor for a VfsStatCursor. +*/ +static int vstattabClose(sqlite3_vtab_cursor *cur){ + sqlite3_free(cur); + return SQLITE_OK; +} + + +/* +** Advance a VfsStatCursor to its next row of output. +*/ +static int vstattabNext(sqlite3_vtab_cursor *cur){ + ((VfsStatCursor*)cur)->i++; + return SQLITE_OK; +} + +/* +** Return values of columns for the row at which the VfsStatCursor +** is currently pointing. +*/ +static int vstattabColumn( + sqlite3_vtab_cursor *cur, /* The cursor */ + sqlite3_context *ctx, /* First argument to sqlite3_result_...() */ + int i /* Which column to return */ +){ + VfsStatCursor *pCur = (VfsStatCursor*)cur; + switch( i ){ + case VSTAT_COLUMN_FILE: { + sqlite3_result_text(ctx, azFile[pCur->i/VFSSTAT_nStat], -1, SQLITE_STATIC); + break; + } + case VSTAT_COLUMN_STAT: { + const char **az; + az = (pCur->i/VFSSTAT_nStat)==VFSSTAT_ANY ? azStatAny : azStat; + sqlite3_result_text(ctx, az[pCur->i%VFSSTAT_nStat], -1, SQLITE_STATIC); + break; + } + case VSTAT_COLUMN_COUNT: { + sqlite3_result_int64(ctx, aVfsCnt[pCur->i]); + break; + } + } + return SQLITE_OK; +} + +/* +** Return the rowid for the current row. +*/ +static int vstattabRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ + VfsStatCursor *pCur = (VfsStatCursor*)cur; + *pRowid = pCur->i; + return SQLITE_OK; +} + +/* +** Return TRUE if the cursor has been moved off of the last +** row of output. +*/ +static int vstattabEof(sqlite3_vtab_cursor *cur){ + VfsStatCursor *pCur = (VfsStatCursor*)cur; + return pCur->i >= VFSSTAT_MXCNT; +} + +/* +** Only a full table scan is supported. So xFilter simply rewinds to +** the beginning. +*/ +static int vstattabFilter( + sqlite3_vtab_cursor *pVtabCursor, + int idxNum, const char *idxStr, + int argc, sqlite3_value **argv +){ + VfsStatCursor *pCur = (VfsStatCursor*)pVtabCursor; + pCur->i = 0; + return SQLITE_OK; +} + +/* +** Only a forwards full table scan is supported. xBestIndex is a no-op. +*/ +static int vstattabBestIndex( + sqlite3_vtab *tab, + sqlite3_index_info *pIdxInfo +){ + return SQLITE_OK; +} + +/* +** Any VSTAT_COLUMN_COUNT can be changed to a positive integer. +** No deletions or insertions are allowed. No changes to other +** columns are allowed. +*/ +static int vstattabUpdate( + sqlite3_vtab *tab, + int argc, sqlite3_value **argv, + sqlite3_int64 *pRowid +){ + sqlite3_int64 iRowid, x; + if( argc==1 ) return SQLITE_ERROR; + if( sqlite3_value_type(argv[0])!=SQLITE_INTEGER ) return SQLITE_ERROR; + iRowid = sqlite3_value_int64(argv[0]); + if( iRowid!=sqlite3_value_int64(argv[1]) ) return SQLITE_ERROR; + if( iRowid<0 || iRowid>=VFSSTAT_MXCNT ) return SQLITE_ERROR; + if( sqlite3_value_type(argv[VSTAT_COLUMN_COUNT+2])!=SQLITE_INTEGER ){ + return SQLITE_ERROR; + } + x = sqlite3_value_int64(argv[VSTAT_COLUMN_COUNT+2]); + if( x<0 ) return SQLITE_ERROR; + aVfsCnt[iRowid] = x; + return SQLITE_OK; +} + +static sqlite3_module VfsStatModule = { + 0, /* iVersion */ + 0, /* xCreate */ + vstattabConnect, /* xConnect */ + vstattabBestIndex, /* xBestIndex */ + vstattabDisconnect, /* xDisconnect */ + 0, /* xDestroy */ + vstattabOpen, /* xOpen - open a cursor */ + vstattabClose, /* xClose - close a cursor */ + vstattabFilter, /* xFilter - configure scan constraints */ + vstattabNext, /* xNext - advance a cursor */ + vstattabEof, /* xEof - check for end of scan */ + vstattabColumn, /* xColumn - read data */ + vstattabRowid, /* xRowid - read data */ + vstattabUpdate, /* xUpdate */ + 0, /* xBegin */ + 0, /* xSync */ + 0, /* xCommit */ + 0, /* xRollback */ + 0, /* xFindMethod */ + 0, /* xRename */ +}; + +/* +** This routine is an sqlite3_auto_extension() callback, invoked to register +** the vfsstat virtual table for all new database connections. +*/ +static int vstatRegister( + sqlite3 *db, + const char **pzErrMsg, + const struct sqlite3_api_routines *pThunk +){ + return sqlite3_create_module(db, "vfsstat", &VfsStatModule, 0); +} + +#ifdef _WIN32 +__declspec(dllexport) +#endif +/* +** This routine is called when the extension is loaded. +** +** Register the new VFS. Make arrangement to register the virtual table +** for each new database connection. +*/ +int sqlite3_vfsstat_init( + sqlite3 *db, + char **pzErrMsg, + const sqlite3_api_routines *pApi +){ + int rc = SQLITE_OK; + VStatVfs *pNew; + SQLITE_EXTENSION_INIT2(pApi); + pNew = sqlite3_malloc(sizeof(vstat_vfs)); + if( pNew==0 ) return SQLITE_NOMEM; + memcpy(&pNew->base, &vstat_vfs, sizeof(vstat_vfs)); + pNew->pVfs = sqlite3_vfs_find(0); + pNew->base.szOsFile = sizeof(VStatFile) + pNew->pVfs->szOsFile; + rc = sqlite3_vfs_register(&pNew->base, 1); + if( rc==SQLITE_OK ){ + rc = sqlite3_auto_extension((void(*)(void))vstatRegister); + } + return rc; +} diff --git a/manifest b/manifest index 8c4974db29..98076dc0c3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improvements\sto\sWHERE-clause\sdebug\stracing.\s\sShow\sTK_MATCH\sexpressions\sand\nshow\smore\sdetails\son\sWhereTerm\straces. -D 2016-05-27T12:30:20.162 +C Add\sthe\svfsstat.c\sloadable\sextension\s-\sa\sVFS\sshim\sthat\smeasures\sthe\samount\nof\sI/O,\sand\san\seponymous\svirtual\stable\sthat\sis\sused\sto\sextract\sand\sview\nthe\smeasurements. +D 2016-05-28T14:53:48.676 F Makefile.in f59e0763ff448719fc1bd25513882b0567286317 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7 @@ -221,6 +221,7 @@ F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52 F ext/misc/spellfix.c bf1b922c2750698e9a3d4c50cce6974adb7e93be F ext/misc/totype.c 4a167594e791abeed95e0a8db028822b5e8fe512 F ext/misc/vfslog.c fe40fab5c077a40477f7e5eba994309ecac6cc95 +F ext/misc/vfsstat.c 318bb69270291bfff3d5bb58b46397ed7b507589 F ext/misc/vtshim.c babb0dc2bf116029e3e7c9a618b8a1377045303e F ext/misc/wholenumber.c 784b12543d60702ebdd47da936e278aa03076212 F ext/rbu/rbu.c b2c0b5e6ae1a89affc0edfc127ebfa5f637a0ce4 @@ -1495,7 +1496,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a9be4c2d56d08fea2cd1aab20b19092a45ef7620 -R 2beba98fee0a4944905820065cc75fbf +P 71087c12bc75a82f5d1051600a442ef6efc5e899 +R 3d452eed48a36d85ceafabad1e13a1b0 U drh -Z 8d7a3e9d02c8c2b09e27f05110ad65d3 +Z 226f41fb99617919dc67fcf97f9a5431 diff --git a/manifest.uuid b/manifest.uuid index 2f2802b83d..4270f95914 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -71087c12bc75a82f5d1051600a442ef6efc5e899 \ No newline at end of file +0987487dd4ebfcf66ddeec8ceca47775216a0887 \ No newline at end of file From 00dae0a3ca0764565d4b3ddb6f336f478bdf517e Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 28 May 2016 15:09:35 +0000 Subject: [PATCH 0477/1484] Update the amalgamation-tarball configure script so that it can use header file "readline/readline.h" with library file "libedit". FossilOrigin-Name: cbf72b04bb0650b62336d86b22ef59315ccdc183 --- autoconf/configure.ac | 74 +++++++++++++++++++++++++------------------ manifest | 14 ++++---- manifest.uuid | 2 +- 3 files changed, 51 insertions(+), 39 deletions(-) diff --git a/autoconf/configure.ac b/autoconf/configure.ac index 01f8b0d03d..b9a11aac8f 100644 --- a/autoconf/configure.ac +++ b/autoconf/configure.ac @@ -30,40 +30,52 @@ AC_FUNC_STRERROR_R AC_CONFIG_FILES([Makefile sqlite3.pc]) AC_SUBST(BUILD_CFLAGS) -#----------------------------------------------------------------------- +#------------------------------------------------------------------------- +# Two options to enable readline compatible libraries: +# # --enable-editline # --enable-readline # -AC_ARG_ENABLE(editline, [AS_HELP_STRING( - [--enable-editline], - [use BSD libedit])], - [], [enable_editline=yes]) -AC_ARG_ENABLE(readline, [AS_HELP_STRING( - [--enable-readline], - [use readline])], - [], [enable_readline=yes]) -if test x"$enable_editline" != xno ; then - sLIBS=$LIBS - LIBS="" - AC_SEARCH_LIBS([readline],[edit],[enable_readline=no],[enable_editline=no]) - READLINE_LIBS=$LIBS - if test x"$LIBS" != "x"; then - AC_DEFINE([HAVE_EDITLINE],1,Define to use BSD editline) - enable_readline=no - else - unset ac_cv_search_readline - fi - LIBS=$sLIBS -fi -if test x"$enable_readline" != xno ; then - sLIBS=$LIBS - LIBS="" - AC_SEARCH_LIBS(tgetent, curses ncurses ncursesw, [], []) - AC_SEARCH_LIBS(readline, readline, [], [enable_readline=no]) - AC_CHECK_FUNCS(readline, [], []) - READLINE_LIBS=$LIBS - LIBS=$sLIBS -fi +# Both are enabled by default. If, after command line processing both are +# still enabled, the script searches for editline first and automatically +# disables readline if it is found. So, to use readline explicitly, the +# user must pass "--disable-editline". To disable command line editing +# support altogether, "--disable-editline --disable-readline". +# +# When searching for either library, check for headers before libraries +# as some distros supply packages that contain libraries but not header +# files, which come as a separate development package. +# +AC_ARG_ENABLE(editline, [AS_HELP_STRING([--enable-editline],[use BSD libedit])]) +AC_ARG_ENABLE(readline, [AS_HELP_STRING([--enable-readline],[use readline])]) + +AS_IF([ test x"$enable_editline" != xno ],[ + AC_CHECK_HEADERS([editline/readline.h],[ + sLIBS=$LIBS + LIBS="" + AC_SEARCH_LIBS([readline],[edit],[ + AC_DEFINE([HAVE_EDITLINE],1,Define to use BSD editline) + READLINE_LIBS=$LIBS + enable_readline=no + ]) + AS_UNSET(ac_cv_search_readline) + LIBS=$sLIBS + ]) +]) + +AS_IF([ test x"$enable_readline" != xno ],[ + AC_CHECK_HEADERS([readline/readline.h],[ + sLIBS=$LIBS + LIBS="" + AC_SEARCH_LIBS(tgetent, termcap curses ncurses ncursesw, [], []) + AC_SEARCH_LIBS(readline,[readline edit], [ + AC_DEFINE([HAVE_READLINE],1,Define to use readline or wrapper) + READLINE_LIBS=$LIBS + ]) + LIBS=$sLIBS + ]) +]) + AC_SUBST(READLINE_LIBS) #----------------------------------------------------------------------- diff --git a/manifest b/manifest index 98076dc0c3..777de8ed6c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\svfsstat.c\sloadable\sextension\s-\sa\sVFS\sshim\sthat\smeasures\sthe\samount\nof\sI/O,\sand\san\seponymous\svirtual\stable\sthat\sis\sused\sto\sextract\sand\sview\nthe\smeasurements. -D 2016-05-28T14:53:48.676 +C Update\sthe\samalgamation-tarball\sconfigure\sscript\sso\sthat\sit\scan\suse\sheader\sfile\s"readline/readline.h"\swith\slibrary\sfile\s"libedit". +D 2016-05-28T15:09:35.313 F Makefile.in f59e0763ff448719fc1bd25513882b0567286317 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7 @@ -14,7 +14,7 @@ F autoconf/Makefile.am 1a47d071e3d5435f8f7ebff7eb6703848bbd65d4 F autoconf/Makefile.msc 0eca137c12542bd76c253a2d24380f29ade59b95 F autoconf/README.first 6c4f34fe115ff55d4e8dbfa3cecf04a0188292f7 F autoconf/README.txt 4f04b0819303aabaa35fff5f7b257fb0c1ef95f1 -F autoconf/configure.ac 7754404e955900cfdeba08862cdfa802eca5b0af +F autoconf/configure.ac cacf2616abf6e4a569bde2ef365c143caeec40bc F autoconf/tea/Makefile.in b438a7020446c8a8156e8d97c8914a04833da6fd F autoconf/tea/README 3e9a3c060f29a44344ab50aec506f4db903fb873 F autoconf/tea/aclocal.m4 52c47aac44ce0ddb1f918b6993e8beb8eee88f43 @@ -1496,7 +1496,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 71087c12bc75a82f5d1051600a442ef6efc5e899 -R 3d452eed48a36d85ceafabad1e13a1b0 -U drh -Z 226f41fb99617919dc67fcf97f9a5431 +P 0987487dd4ebfcf66ddeec8ceca47775216a0887 +R 3c226086b91b471db1b9e5c3998de4c9 +U dan +Z 4323e6121ccb1a6dc1ad24e971c3fe39 diff --git a/manifest.uuid b/manifest.uuid index 4270f95914..e4dcde7a36 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0987487dd4ebfcf66ddeec8ceca47775216a0887 \ No newline at end of file +cbf72b04bb0650b62336d86b22ef59315ccdc183 \ No newline at end of file From c1502e2f4ff34628e7e8bb0a0d8b7c0af3cb51ad Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 28 May 2016 17:23:08 +0000 Subject: [PATCH 0478/1484] Enhance the sqlite3_load_extension() interface to permit extensions to return SQLITE_OK_LOAD_PERMANENTLY which will prevent the extensions from unloading when the database connection closes. FossilOrigin-Name: d3f99a5e8d0486d0917dfe96987c179a6f63b850 --- ext/misc/vfsstat.c | 1 + manifest | 20 +++++++++++--------- manifest.uuid | 2 +- src/loadext.c | 5 ++++- src/sqlite.h.in | 1 + 5 files changed, 18 insertions(+), 11 deletions(-) diff --git a/ext/misc/vfsstat.c b/ext/misc/vfsstat.c index e519de6341..71bea16bd9 100644 --- a/ext/misc/vfsstat.c +++ b/ext/misc/vfsstat.c @@ -815,5 +815,6 @@ int sqlite3_vfsstat_init( if( rc==SQLITE_OK ){ rc = sqlite3_auto_extension((void(*)(void))vstatRegister); } + if( rc==SQLITE_OK ) rc = SQLITE_OK_LOAD_PERMANENTLY; return rc; } diff --git a/manifest b/manifest index d2efa14e2d..eb178318cd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\s"PRAGMA\scompile_options"\sso\sthat\sit\sshows\sthe\sversion\sof\sthe\scompiler\nused\sto\sgenerate\sthe\sexecutable,\sfor\scommon\scompilers. -D 2016-05-28T15:22:33.400 +C Enhance\sthe\ssqlite3_load_extension()\sinterface\sto\spermit\sextensions\sto\nreturn\sSQLITE_OK_LOAD_PERMANENTLY\swhich\swill\sprevent\sthe\sextensions\sfrom\nunloading\swhen\sthe\sdatabase\sconnection\scloses. +D 2016-05-28T17:23:08.946 F Makefile.in f59e0763ff448719fc1bd25513882b0567286317 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7 @@ -221,7 +221,7 @@ F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52 F ext/misc/spellfix.c bf1b922c2750698e9a3d4c50cce6974adb7e93be F ext/misc/totype.c 4a167594e791abeed95e0a8db028822b5e8fe512 F ext/misc/vfslog.c fe40fab5c077a40477f7e5eba994309ecac6cc95 -F ext/misc/vfsstat.c 318bb69270291bfff3d5bb58b46397ed7b507589 +F ext/misc/vfsstat.c 9b41dd28f523f56f688529db12b9a6895a3e6896 F ext/misc/vtshim.c babb0dc2bf116029e3e7c9a618b8a1377045303e F ext/misc/wholenumber.c 784b12543d60702ebdd47da936e278aa03076212 F ext/rbu/rbu.c b2c0b5e6ae1a89affc0edfc127ebfa5f637a0ce4 @@ -344,7 +344,7 @@ F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 F src/insert.c 8f4e9fcbd8e95e85f15647ba8b413b18d556ec2b F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e -F src/loadext.c 8b3a73f0624c5f7cadbd5cb89940783bee1d39a6 +F src/loadext.c 4237fd37ca589f1d90b3ea925dd9df20da8e0c84 F src/main.c 405d13e3a4f7c5add9fb27702ae70ed0a6e32cca F src/malloc.c 1443d1ad95d67c21d77af7ae3f44678252f0efec F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 @@ -382,7 +382,7 @@ F src/resolve.c cca3aa77b95706df5d635a2141a4d1de60ae6598 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c a0c4abf54bc6bd3a9c77a36ef3d1676045706cb2 F src/shell.c 14ff7f660530a52b117d110ba3390b7b2eb719b6 -F src/sqlite.h.in 9984129d86243424b765fcb3f147c697bd20bb54 +F src/sqlite.h.in 5f8113dbec74c6c093ead9930afb8c9fbd9f643d F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 98f72cbfe00169c39089115427d06ea05fe4b4a2 F src/sqliteInt.h 09621b4b7dba808b24262c2480ea75b045001853 @@ -1496,8 +1496,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P cbf72b04bb0650b62336d86b22ef59315ccdc183 3f710bc3617691fa7432a24f1410d4651ca181b6 -R b8a29334efa74a5834e7230ac30a1859 -T +closed 3f710bc3617691fa7432a24f1410d4651ca181b6 +P 6a0f200957ea294a2ae06c0b039a10ac838925f2 +R 6ce9b533604a3edd0071ae2a75774cc3 +T *branch * load-permanently +T *sym-load-permanently * +T -sym-trunk * U drh -Z e6aad793d53e0a92b777c64d70afe184 +Z 6a4e05708813f8abe1e82b227d71ac00 diff --git a/manifest.uuid b/manifest.uuid index ad8620c28e..8814600fda 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6a0f200957ea294a2ae06c0b039a10ac838925f2 \ No newline at end of file +d3f99a5e8d0486d0917dfe96987c179a6f63b850 \ No newline at end of file diff --git a/src/loadext.c b/src/loadext.c index f881d99710..718dae5777 100644 --- a/src/loadext.c +++ b/src/loadext.c @@ -446,6 +446,7 @@ static int sqlite3LoadExtension( void **aHandle; u64 nMsg = 300 + sqlite3Strlen30(zFile); int ii; + int rc; /* Shared library endings to try if zFile cannot be loaded as written */ static const char *azEndings[] = { @@ -548,7 +549,9 @@ static int sqlite3LoadExtension( return SQLITE_ERROR; } sqlite3_free(zAltEntry); - if( xInit(db, &zErrmsg, &sqlite3Apis) ){ + rc = xInit(db, &zErrmsg, &sqlite3Apis); + if( rc ){ + if( rc==SQLITE_OK_LOAD_PERMANENTLY ) return SQLITE_OK; if( pzErrMsg ){ *pzErrMsg = sqlite3_mprintf("error during initialization: %s", zErrmsg); } diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 795236f587..4865f18132 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -506,6 +506,7 @@ int sqlite3_exec( #define SQLITE_NOTICE_RECOVER_ROLLBACK (SQLITE_NOTICE | (2<<8)) #define SQLITE_WARNING_AUTOINDEX (SQLITE_WARNING | (1<<8)) #define SQLITE_AUTH_USER (SQLITE_AUTH | (1<<8)) +#define SQLITE_OK_LOAD_PERMANENTLY (SQLITE_OK | (1<<8)) /* ** CAPI3REF: Flags For File Open Operations From 66bf810467d1734cb7d86552c57fcdefa5a00247 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 28 May 2016 17:45:15 +0000 Subject: [PATCH 0479/1484] Remove an unnecessary malloc from the vfsstat extension. FossilOrigin-Name: 24f258c2392290168cf34622b89a4a406a3dd853 --- ext/misc/vfsstat.c | 10 +++------- manifest | 13 ++++++------- manifest.uuid | 2 +- 3 files changed, 10 insertions(+), 15 deletions(-) diff --git a/ext/misc/vfsstat.c b/ext/misc/vfsstat.c index e519de6341..eefa6ea62b 100644 --- a/ext/misc/vfsstat.c +++ b/ext/misc/vfsstat.c @@ -804,14 +804,10 @@ int sqlite3_vfsstat_init( const sqlite3_api_routines *pApi ){ int rc = SQLITE_OK; - VStatVfs *pNew; SQLITE_EXTENSION_INIT2(pApi); - pNew = sqlite3_malloc(sizeof(vstat_vfs)); - if( pNew==0 ) return SQLITE_NOMEM; - memcpy(&pNew->base, &vstat_vfs, sizeof(vstat_vfs)); - pNew->pVfs = sqlite3_vfs_find(0); - pNew->base.szOsFile = sizeof(VStatFile) + pNew->pVfs->szOsFile; - rc = sqlite3_vfs_register(&pNew->base, 1); + vstat_vfs.pVfs = sqlite3_vfs_find(0); + vstat_vfs.base.szOsFile = sizeof(VStatFile) + pNew->pVfs->szOsFile; + rc = sqlite3_vfs_register(&vstat_vfs.base, 1); if( rc==SQLITE_OK ){ rc = sqlite3_auto_extension((void(*)(void))vstatRegister); } diff --git a/manifest b/manifest index d2efa14e2d..9cfe44a4b4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\s"PRAGMA\scompile_options"\sso\sthat\sit\sshows\sthe\sversion\sof\sthe\scompiler\nused\sto\sgenerate\sthe\sexecutable,\sfor\scommon\scompilers. -D 2016-05-28T15:22:33.400 +C Remove\san\sunnecessary\smalloc\sfrom\sthe\svfsstat\sextension. +D 2016-05-28T17:45:15.304 F Makefile.in f59e0763ff448719fc1bd25513882b0567286317 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7 @@ -221,7 +221,7 @@ F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52 F ext/misc/spellfix.c bf1b922c2750698e9a3d4c50cce6974adb7e93be F ext/misc/totype.c 4a167594e791abeed95e0a8db028822b5e8fe512 F ext/misc/vfslog.c fe40fab5c077a40477f7e5eba994309ecac6cc95 -F ext/misc/vfsstat.c 318bb69270291bfff3d5bb58b46397ed7b507589 +F ext/misc/vfsstat.c 20f206b6d38911dfac4b4db88171204d0373f7df F ext/misc/vtshim.c babb0dc2bf116029e3e7c9a618b8a1377045303e F ext/misc/wholenumber.c 784b12543d60702ebdd47da936e278aa03076212 F ext/rbu/rbu.c b2c0b5e6ae1a89affc0edfc127ebfa5f637a0ce4 @@ -1496,8 +1496,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P cbf72b04bb0650b62336d86b22ef59315ccdc183 3f710bc3617691fa7432a24f1410d4651ca181b6 -R b8a29334efa74a5834e7230ac30a1859 -T +closed 3f710bc3617691fa7432a24f1410d4651ca181b6 +P 6a0f200957ea294a2ae06c0b039a10ac838925f2 +R 829320b2f280fbfaceb9a39efce4a03a U drh -Z e6aad793d53e0a92b777c64d70afe184 +Z aae9a2c9c9808c4a6dec915905c542ff diff --git a/manifest.uuid b/manifest.uuid index ad8620c28e..c667abe35c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6a0f200957ea294a2ae06c0b039a10ac838925f2 \ No newline at end of file +24f258c2392290168cf34622b89a4a406a3dd853 \ No newline at end of file From dbd2dcbd5ec86a795a3af633e4cd16dc26f929a0 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 28 May 2016 18:53:55 +0000 Subject: [PATCH 0480/1484] Experimental change to allow virtual tables to take advantage of LIKE, REGEXP and GLOB terms that are part of OR expressions within WHERE clauses. FossilOrigin-Name: 242507b4ff96bc4c7c7844dbe1c2b8508dbf1d01 --- manifest | 18 +++-- manifest.uuid | 2 +- src/whereexpr.c | 6 +- test/bestindex3.test | 170 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 186 insertions(+), 10 deletions(-) create mode 100644 test/bestindex3.test diff --git a/manifest b/manifest index 9cfe44a4b4..fc8ac69d1e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\san\sunnecessary\smalloc\sfrom\sthe\svfsstat\sextension. -D 2016-05-28T17:45:15.304 +C Experimental\schange\sto\sallow\svirtual\stables\sto\stake\sadvantage\sof\sLIKE,\sREGEXP\sand\sGLOB\sterms\sthat\sare\spart\sof\sOR\sexpressions\swithin\sWHERE\sclauses. +D 2016-05-28T18:53:55.546 F Makefile.in f59e0763ff448719fc1bd25513882b0567286317 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7 @@ -463,7 +463,7 @@ F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354 F src/where.c b9f5b0ddb14c3827e70b5379e659cf4cfd524c4d F src/whereInt.h e5b939701a7ceffc5a3a8188a37f9746416ebcd0 F src/wherecode.c ba71a4e4bada29aa9842200e6299714bf18c812c -F src/whereexpr.c eacc0e60d029a082b4fc0cc42ea98544add1319e +F src/whereexpr.c c32d47085dbaca0b8fd013210f56693c7d220d48 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -526,6 +526,7 @@ F test/badutf2.test f5bc7f2d280670ecd79b9cf4f0f1760c607fe51f F test/bc_common.tcl b5e42d80305be95697e6370e015af571e5333a1c F test/bestindex1.test 0cf1bd2d7b97d3a3a8c10736125274f64765c4ee F test/bestindex2.test 4a06b8922ab2fd09434870da8d1cdf525aaf7060 +F test/bestindex3.test b80da904d23581d233a7ceee7d6bbad2b23a8133 F test/between.test 34d375fb5ce1ae283ffe82b6b233e9f38e84fc6c F test/bigfile.test aa74f4e5db51c8e54a1d9de9fa65d01d1eb20b59 F test/bigfile2.test 1b489a3a39ae90c7f027b79110d6b4e1dbc71bfc @@ -1496,7 +1497,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 6a0f200957ea294a2ae06c0b039a10ac838925f2 -R 829320b2f280fbfaceb9a39efce4a03a -U drh -Z aae9a2c9c9808c4a6dec915905c542ff +P 24f258c2392290168cf34622b89a4a406a3dd853 +R 983129af8245564f55ecb1fc34584518 +T *branch * vtab-experimental +T *sym-vtab-experimental * +T -sym-trunk * +U dan +Z 81d42b1213db363a99013be9cf2ad43d diff --git a/manifest.uuid b/manifest.uuid index c667abe35c..7e28d7946f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -24f258c2392290168cf34622b89a4a406a3dd853 \ No newline at end of file +242507b4ff96bc4c7c7844dbe1c2b8508dbf1d01 \ No newline at end of file diff --git a/src/whereexpr.c b/src/whereexpr.c index ff012281b1..90c4c45965 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -568,7 +568,9 @@ static void exprAnalyzeOrTerm( if( !db->mallocFailed ){ for(j=0, pAndTerm=pAndWC->a; jnTerm; j++, pAndTerm++){ assert( pAndTerm->pExpr ); - if( allowedOp(pAndTerm->pExpr->op) ){ + if( allowedOp(pAndTerm->pExpr->op) + || pAndTerm->eOperator==WO_MATCH + ){ b |= sqlite3WhereGetMask(&pWInfo->sMaskSet, pAndTerm->leftCursor); } } @@ -1122,7 +1124,7 @@ static void exprAnalyze( ** virtual tables. The native query optimizer does not attempt ** to do anything with MATCH functions. */ - if( isMatchOfColumn(pExpr, &eOp2) ){ + if( pWC->op==TK_AND && isMatchOfColumn(pExpr, &eOp2) ){ int idxNew; Expr *pRight, *pLeft; WhereTerm *pNewTerm; diff --git a/test/bestindex3.test b/test/bestindex3.test new file mode 100644 index 0000000000..bb6d5cefd1 --- /dev/null +++ b/test/bestindex3.test @@ -0,0 +1,170 @@ +# 2016 May 29 +# +# 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. +# +#*********************************************************************** + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix bestindex3 + +ifcapable !vtab { + finish_test + return +} + +#------------------------------------------------------------------------- +# Virtual table callback for a virtual table named $tbl. +# +# The table created is: +# +# "CREATE TABLE t1 (a, b, c)" +# +# This virtual table supports both LIKE and = operators on all columns. +# +proc vtab_cmd {bOmit method args} { + switch -- $method { + xConnect { + return "CREATE TABLE t1(a, b, c)" + } + + xBestIndex { + foreach {clist orderby mask} $args {} + + set ret [list] + set use use + if {$bOmit} {set use omit} + + for {set i 0} {$i < [llength $clist]} {incr i} { + array unset C + array set C [lindex $clist $i] + if {$C(usable) && ($C(op)=="like" || $C(op)=="eq")} { + lappend ret $use $i + lappend ret idxstr + lappend ret "[lindex {a b c} $C(column)] [string toupper $C(op)] ?" + break + } + } + + if {$ret==""} { + lappend ret cost 1000000 rows 1000000 + } else { + lappend ret cost 100 rows 10 + } + return $ret + } + + xFilter { + foreach {idxnum idxstr param} $args {} + set where "" + if {$bOmit && $idxstr != ""} { + set where " WHERE [string map [list ? '$param' EQ =] $idxstr]" + } + return [list sql "SELECT rowid, * FROM ttt$where"] + } + } + return "" +} + +register_tcl_module db + +do_execsql_test 1.0 { + CREATE VIRTUAL TABLE t1 USING tcl("vtab_cmd 0"); +} + +do_eqp_test 1.1 { + SELECT * FROM t1 WHERE a LIKE 'abc'; +} { + 0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:a LIKE ?} +} + +do_eqp_test 1.2 { + SELECT * FROM t1 WHERE a = 'abc'; +} { + 0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:a EQ ?} +} + +do_eqp_test 1.3 { + SELECT * FROM t1 WHERE a = 'abc' OR b = 'def'; +} { + 0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:a EQ ?} + 0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:b EQ ?} +} + +do_eqp_test 1.4 { + SELECT * FROM t1 WHERE a LIKE 'abc%' OR b = 'def'; +} { + 0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:a LIKE ?} + 0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:b EQ ?} +} + +do_execsql_test 1.5 { + CREATE TABLE ttt(a, b, c); + + INSERT INTO ttt VALUES(1, 'two', 'three'); + INSERT INTO ttt VALUES(2, 'one', 'two'); + INSERT INTO ttt VALUES(3, 'three', 'one'); + INSERT INTO ttt VALUES(4, 'y', 'one'); + INSERT INTO ttt VALUES(5, 'x', 'two'); + INSERT INTO ttt VALUES(6, 'y', 'three'); +} + +foreach omit {0 1} { + do_execsql_test 1.6.$omit.0 " + DROP TABLE t1; + CREATE VIRTUAL TABLE t1 USING tcl('vtab_cmd $omit'); + " + do_execsql_test 1.6.$omit.1 { + SELECT rowid FROM t1 WHERE c LIKE 'o%' + } {3 4} + + do_execsql_test 1.6.$omit.2 { + SELECT rowid FROM t1 WHERE c LIKE 'o%' OR b='y' + } {3 4 6} + + do_execsql_test 1.6.$omit.3 { + SELECT rowid FROM t1 WHERE c = 'three' OR c LIKE 'o%' + } {1 6 3 4} +} + +#------------------------------------------------------------------------- +# Test the same pattern works with ordinary tables. +# +do_execsql_test 2.1 { + CREATE TABLE t2(x TEXT COLLATE nocase, y TEXT); + CREATE INDEX t2x ON t2(x COLLATE nocase); + CREATE INDEX t2y ON t2(y); +} + +do_eqp_test 2.2 { + SELECT * FROM t2 WHERE x LIKE 'abc%' OR y = 'def' +} { + 0 0 0 {SEARCH TABLE t2 USING INDEX t2x (x>? AND x Date: Mon, 30 May 2016 08:28:21 +0000 Subject: [PATCH 0481/1484] Fix an FTS5 problem (segfault or incorrect query results) with "... MATCH 'x OR y' ORDER BY rank" queries when either token 'x' or 'y' is completely absent from the dataset. FossilOrigin-Name: 64ca1a835a89fd211078d2cd8f9b649e89be528d --- ext/fts5/fts5Int.h | 1 - ext/fts5/fts5_expr.c | 11 ----------- ext/fts5/fts5_main.c | 1 - ext/fts5/test/fts5rank.test | 29 +++++++++++++++++++++++++++++ manifest | 20 ++++++++++---------- manifest.uuid | 2 +- 6 files changed, 40 insertions(+), 24 deletions(-) diff --git a/ext/fts5/fts5Int.h b/ext/fts5/fts5Int.h index c4e7506fb1..c7169a113b 100644 --- a/ext/fts5/fts5Int.h +++ b/ext/fts5/fts5Int.h @@ -686,7 +686,6 @@ int sqlite3Fts5ExprPopulatePoslists( Fts5Config*, Fts5Expr*, Fts5PoslistPopulator*, int, const char*, int ); void sqlite3Fts5ExprCheckPoslists(Fts5Expr*, i64); -void sqlite3Fts5ExprClearEof(Fts5Expr*); int sqlite3Fts5ExprClonePhrase(Fts5Expr*, int, Fts5Expr**); diff --git a/ext/fts5/fts5_expr.c b/ext/fts5/fts5_expr.c index a48fa6e9d0..9119813c85 100644 --- a/ext/fts5/fts5_expr.c +++ b/ext/fts5/fts5_expr.c @@ -2617,17 +2617,6 @@ void sqlite3Fts5ExprCheckPoslists(Fts5Expr *pExpr, i64 iRowid){ fts5ExprCheckPoslists(pExpr->pRoot, iRowid); } -static void fts5ExprClearEof(Fts5ExprNode *pNode){ - int i; - for(i=0; inChild; i++){ - fts5ExprClearEof(pNode->apChild[i]); - } - pNode->bEof = 0; -} -void sqlite3Fts5ExprClearEof(Fts5Expr *pExpr){ - fts5ExprClearEof(pExpr->pRoot); -} - /* ** This function is only called for detail=columns tables. */ diff --git a/ext/fts5/fts5_main.c b/ext/fts5/fts5_main.c index 4feb3e1a2f..384d3dd8f7 100644 --- a/ext/fts5/fts5_main.c +++ b/ext/fts5/fts5_main.c @@ -1186,7 +1186,6 @@ static int fts5FilterMethod( pCsr->ePlan = FTS5_PLAN_SOURCE; pCsr->pExpr = pTab->pSortCsr->pExpr; rc = fts5CursorFirst(pTab, pCsr, bDesc); - sqlite3Fts5ExprClearEof(pCsr->pExpr); }else if( pMatch ){ const char *zExpr = (const char*)sqlite3_value_text(apVal[0]); if( zExpr==0 ) zExpr = ""; diff --git a/ext/fts5/test/fts5rank.test b/ext/fts5/test/fts5rank.test index 4961b42605..e958aea15b 100644 --- a/ext/fts5/test/fts5rank.test +++ b/ext/fts5/test/fts5rank.test @@ -91,9 +91,38 @@ do_test 2.7 { } {1 3 2} +#-------------------------------------------------------------------------- +# At one point there was a problem with queries such as: +# +# ... MATCH 'x OR y' ORDER BY rank; +# +# if there were zero occurrences of token 'y' in the dataset. The +# following tests verify that that problem has been addressed. +# +foreach_detail_mode $::testprefix { + do_execsql_test 3.0 { + CREATE VIRTUAL TABLE y1 USING fts5(z, detail=%DETAIL%); + INSERT INTO y1 VALUES('test xyz'); + INSERT INTO y1 VALUES('test test xyz test'); + INSERT INTO y1 VALUES('test test xyz'); + } + do_execsql_test 3.1 { + SELECT rowid FROM y1('test OR tset'); + } {1 2 3} + do_execsql_test 3.2 { + SELECT rowid FROM y1('test OR tset') ORDER BY bm25(y1) + } {2 3 1} + do_execsql_test 3.3 { + SELECT rowid FROM y1('test OR tset') ORDER BY +rank + } {2 3 1} + + do_execsql_test 3.4 { + SELECT rowid FROM y1('test OR tset') ORDER BY rank + } {2 3 1} +} finish_test diff --git a/manifest b/manifest index 9cfe44a4b4..ce51d87c84 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\san\sunnecessary\smalloc\sfrom\sthe\svfsstat\sextension. -D 2016-05-28T17:45:15.304 +C Fix\san\sFTS5\sproblem\s(segfault\sor\sincorrect\squery\sresults)\swith\s"...\sMATCH\s'x\sOR\sy'\sORDER\sBY\srank"\squeries\swhen\seither\stoken\s'x'\sor\s'y'\sis\scompletely\sabsent\sfrom\sthe\sdataset. +D 2016-05-30T08:28:21.370 F Makefile.in f59e0763ff448719fc1bd25513882b0567286317 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7 @@ -98,14 +98,14 @@ F ext/fts3/unicode/mkunicode.tcl 2debed3f582d77b3fdd0b8830880250021571fd8 F ext/fts3/unicode/parseunicode.tcl da577d1384810fb4e2b209bf3313074353193e95 F ext/fts5/extract_api_docs.tcl a36e54ec777172ddd3f9a88daf593b00848368e0 F ext/fts5/fts5.h b770c5e0a8d2ee071ddffc7ab722dbf3474a8abe -F ext/fts5/fts5Int.h 3677076aecbf645a7f2a019115c6a4ec3272dd78 +F ext/fts5/fts5Int.h 9bd0c7c64285b5b368eca0ac63613185c5ad24ba F ext/fts5/fts5_aux.c daa57fb45216491814520bbb587e97bf81ced458 F ext/fts5/fts5_buffer.c 4c1502d4c956cd092c89ce4480867f9d8bf325cd F ext/fts5/fts5_config.c 5af9c360e99669d29f06492c370892394aba0857 -F ext/fts5/fts5_expr.c da2b33c2aac91e96641c0a7cf2bbaa36eb2667f7 +F ext/fts5/fts5_expr.c bcb238ee4ac1164302ab528487520488516bd030 F ext/fts5/fts5_hash.c 880998e596b60f078348d48732ca4ad9a90caad2 F ext/fts5/fts5_index.c b429e23fabb57506f71e406997cc46b89190dc97 -F ext/fts5/fts5_main.c b4a0fc5bf17f2f1f056ee76cdd7d2af08b360f55 +F ext/fts5/fts5_main.c f85281445dcf8be32d18841c93a6f90fe27dbfe2 F ext/fts5/fts5_storage.c 3309c6a8e34b974513016fd1ef47c83f5898f94c F ext/fts5/fts5_tcl.c f8731e0508299bd43f1a2eff7dbeaac870768966 F ext/fts5/fts5_test_mi.c 783b86697ebf773c18fc109992426c0173a055bc @@ -176,7 +176,7 @@ F ext/fts5/test/fts5porter.test 7cdc07bef301d70eebbfa75dcaf45c3680e1d0e1 F ext/fts5/test/fts5porter2.test 2e65633d58a1c525d5af0f6c01e5a59155bb3487 F ext/fts5/test/fts5prefix.test efd42e00bb8e8a36383f25c838185508681c093f F ext/fts5/test/fts5query.test f5ec25f5f2fbb70033424113cdffc101b1985a40 -F ext/fts5/test/fts5rank.test 7e9e64eac7245637f6f2033aec4b292aaf611aab +F ext/fts5/test/fts5rank.test 3e55e7eeb4c98728e4a3171c9e994e1a2f24eb99 F ext/fts5/test/fts5rebuild.test 03935f617ace91ed23a6099c7c74d905227ff29b F ext/fts5/test/fts5restart.test c17728fdea26e7d0f617d22ad5b4b2862b994c17 F ext/fts5/test/fts5rowid.test 16908a99d6efc9ba21081b4f2b86b3fc699839a6 @@ -1496,7 +1496,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 6a0f200957ea294a2ae06c0b039a10ac838925f2 -R 829320b2f280fbfaceb9a39efce4a03a -U drh -Z aae9a2c9c9808c4a6dec915905c542ff +P 24f258c2392290168cf34622b89a4a406a3dd853 +R 09bf6149ab89919173c2bf6834d1442a +U dan +Z 067d36e8e3bb6a90972bf218c0cabd70 diff --git a/manifest.uuid b/manifest.uuid index c667abe35c..15daff8194 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -24f258c2392290168cf34622b89a4a406a3dd853 \ No newline at end of file +64ca1a835a89fd211078d2cd8f9b649e89be528d \ No newline at end of file From 724b18966deb18ae6b1559c31de419e13fea465d Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 31 May 2016 16:22:48 +0000 Subject: [PATCH 0482/1484] Add the "csv" virtual table for reading CSV files, as an extension in the ext/misc/ subfolder. FossilOrigin-Name: 00d3570c8bb96469c984903e20de589e998d4636 --- ext/misc/csv.c | 622 +++++++++++++++++++++++++++++++++++++++++++++++++ manifest | 13 +- manifest.uuid | 2 +- 3 files changed, 630 insertions(+), 7 deletions(-) create mode 100644 ext/misc/csv.c diff --git a/ext/misc/csv.c b/ext/misc/csv.c new file mode 100644 index 0000000000..62521d81f7 --- /dev/null +++ b/ext/misc/csv.c @@ -0,0 +1,622 @@ +/* +** 2016-05-28 +** +** 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 contains the implementation of an SQLite virtual table for +** reading CSV files. +** +** Usage: +** +** .load ./csv +** CREATE VIRTUAL TABLE temp.csv USING csv(filename=FILENAME); +** SELECT * FROM csv; +** +** The columns are named "c1", "c2", "c3", ... by default. But the +** application can define its own CREATE TABLE statement as an additional +** parameter. For example: +** +** CREATE VIRTUAL TABLE temp.csv2 USING csv( +** filename = "../http.log", +** schema = "CREATE TABLE x(date,ipaddr,url,referrer,userAgent)" +** ); +*/ +#include +SQLITE_EXTENSION_INIT1 +#include +#include +#include +#include +#include +#include + +/* +** A macro to hint to the compiler that a function should not be +** inlined. +*/ +#if defined(__GNUC__) +# define CSV_NOINLINE __attribute__((noinline)) +#elif defined(_MSC_VER) && _MSC_VER>=1310 +# define CSV_NOINLINE __declspec(noinline) +#else +# define CSV_NOINLINE +#endif + + +/* Max size of the error message in a CsvReader */ +#define CSV_MXERR 200 + +/* A context object used when read a CSV file. */ +typedef struct CsvReader CsvReader; +struct CsvReader { + FILE *in; /* Read the CSV text from this input stream */ + char *z; /* Accumulated text for a field */ + int n; /* Number of bytes in z */ + int nAlloc; /* Space allocated for z[] */ + int nLine; /* Current line number */ + int cTerm; /* Character that terminated the most recent field */ + char zErr[CSV_MXERR]; /* Error message */ +}; + +/* Initialize a CsvReader object */ +static void csv_reader_init(CsvReader *p){ + memset(p, 0, sizeof(*p)); +} + +/* Close and reset a CsvReader object */ +static void csv_reader_reset(CsvReader *p){ + if( p->in ) fclose(p->in); + sqlite3_free(p->z); + csv_reader_init(p); +} + +/* Report an error on a CsvReader */ +static void csv_errmsg(CsvReader *p, const char *zFormat, ...){ + va_list ap; + va_start(ap, zFormat); + sqlite3_vsnprintf(CSV_MXERR, p->zErr, zFormat, ap); + va_end(ap); +} + +/* Open the file associated with a CsvReader +** Return the number of errors. +*/ +static int csv_reader_open(CsvReader *p, const char *zFilename){ + p->in = fopen(zFilename, "rb"); + if( p->in==0 ){ + csv_errmsg(p, "cannot open '%s' for reading", zFilename); + return 1; + } + return 0; +} + +/* Increase the size of p->z and append character c to the end. +** Return 0 on success and non-zero if there is an OOM error */ +static CSV_NOINLINE int csv_resize_and_append(CsvReader *p, char c){ + char *zNew; + int nNew = p->nAlloc*2 + 100; + zNew = sqlite3_realloc64(p->z, nNew); + if( zNew ){ + p->z = zNew; + p->nAlloc = nNew; + p->z[p->n++] = c; + return 0; + }else{ + csv_errmsg(p, "out of memory"); + return 1; + } +} + +/* Append a single character to the CsvReader.z[] array. +** Return 0 on success and non-zero if there is an OOM error */ +static int csv_append(CsvReader *p, char c){ + if( p->n>=p->nAlloc-1 ) return csv_resize_and_append(p, c); + p->z[p->n++] = c; + return 0; +} + +/* Read a single field of CSV text. Compatible with rfc4180 and extended +** with the option of having a separator other than ",". +** +** + Input comes from p->in. +** + Store results in p->z of length p->n. Space to hold p->z comes +** from sqlite3_malloc64(). +** + Keep track of the line number in p->nLine. +** + Store the character that terminates the field in p->cTerm. Store +** EOF on end-of-file. +** +** Return "" at EOF. Return 0 on an OOM error. +*/ +static char *csv_read_one_field(CsvReader *p){ + int c; + p->n = 0; + c = fgetc(p->in); + if( c==EOF ){ + p->cTerm = EOF; + return ""; + } + if( c=='"' ){ + int pc, ppc; + int startLine = p->nLine; + int cQuote = c; + pc = ppc = 0; + while( 1 ){ + c = fgetc(p->in); + if( c=='\n' ) p->nLine++; + if( c==cQuote ){ + if( pc==cQuote ){ + pc = 0; + continue; + } + } + if( (c==',' && pc==cQuote) + || (c=='\n' && pc==cQuote) + || (c=='\n' && pc=='\r' && ppc==cQuote) + || (c==EOF && pc==cQuote) + ){ + do{ p->n--; }while( p->z[p->n]!=cQuote ); + p->cTerm = c; + break; + } + if( pc==cQuote && c!='\r' ){ + csv_errmsg(p, "line %d: unescaped %c character", p->nLine, cQuote); + break; + } + if( c==EOF ){ + csv_errmsg(p, "line %d: unterminated %c-quoted field\n", + startLine, cQuote); + p->cTerm = c; + break; + } + if( csv_append(p, (char)c) ) return 0; + ppc = pc; + pc = c; + } + }else{ + while( c!=EOF && c!=',' && c!='\n' ){ + if( csv_append(p, (char)c) ) return 0; + c = fgetc(p->in); + } + if( c=='\n' ){ + p->nLine++; + if( p->n>0 && p->z[p->n-1]=='\r' ) p->n--; + } + p->cTerm = c; + } + if( p->z ) p->z[p->n] = 0; + return p->z; +} + + +/* Forward references to the various virtual table methods implemented +** in this file. */ +static int csvtabCreate(sqlite3*, void*, int, const char*const*, + sqlite3_vtab**,char**); +static int csvtabConnect(sqlite3*, void*, int, const char*const*, + sqlite3_vtab**,char**); +static int csvtabBestIndex(sqlite3_vtab*,sqlite3_index_info*); +static int csvtabDisconnect(sqlite3_vtab*); +static int csvtabOpen(sqlite3_vtab*, sqlite3_vtab_cursor**); +static int csvtabClose(sqlite3_vtab_cursor*); +static int csvtabFilter(sqlite3_vtab_cursor*, int idxNum, const char *idxStr, + int argc, sqlite3_value **argv); +static int csvtabNext(sqlite3_vtab_cursor*); +static int csvtabEof(sqlite3_vtab_cursor*); +static int csvtabColumn(sqlite3_vtab_cursor*,sqlite3_context*,int); +static int csvtabRowid(sqlite3_vtab_cursor*,sqlite3_int64*); + +/* An instance of the CSV virtual table */ +typedef struct CsvTable { + sqlite3_vtab base; /* Base class. Must be first */ + char *zFilename; /* Name of the CSV file */ + long iStart; /* Offset to start of data in zFilename */ + int nCol; /* Number of columns in the CSV file */ +} CsvTable; + +/* A cursor for the CSV virtual table */ +typedef struct CsvCursor { + sqlite3_vtab_cursor base; /* Base class. Must be first */ + CsvReader rdr; /* The CsvReader object */ + char **azVal; /* Value of the current row */ + sqlite3_int64 iRowid; /* The current rowid. Negative for EOF */ +} CsvCursor; + +/* Transfer error message text from a reader into a CsvTable */ +static void csv_xfer_error(CsvTable *pTab, CsvReader *pRdr){ + sqlite3_free(pTab->base.zErrMsg); + pTab->base.zErrMsg = sqlite3_mprintf("%s", pRdr->zErr); +} + +/* +** This method is the destructor fo a CsvTable object. +*/ +static int csvtabDisconnect(sqlite3_vtab *pVtab){ + CsvTable *p = (CsvTable*)pVtab; + sqlite3_free(p->zFilename); + sqlite3_free(p); + return SQLITE_OK; +} + +/* Skip leading whitespace. Return a pointer to the first non-whitespace +** character, or to the zero terminator if the string has only whitespace */ +static const char *csv_skip_whitespace(const char *z){ + while( isspace((unsigned char)z[0]) ) z++; + return z; +} + +/* Remove trailing whitespace from the end of string z[] */ +static void csv_trim_whitespace(char *z){ + size_t n = strlen(z); + while( n>0 && isspace((unsigned char)z[n]) ) n--; + z[n] = 0; +} + +/* Dequote the string */ +static void csv_dequote(char *z){ + int i, j; + char cQuote = z[0]; + size_t n; + + if( cQuote!='\'' && cQuote!='"' ) return; + n = strlen(z); + if( n<2 || z[n-1]!=z[0] ) return; + for(i=1, j=0; i=0 ){ + csv_errmsg(&sRdr, "more than one 'header' parameter"); + goto csvtab_connect_error; + } + x = csv_boolean(zValue); + if( x==1 ){ + bHeader = 1; + }else if( x==0 ){ + bHeader = 0; + }else{ + csv_errmsg(&sRdr, "unrecognized argument to 'header': %s", zValue); + goto csvtab_connect_error; + } + }else + { + csv_errmsg(&sRdr, "unrecognized parameter '%s'", z); + goto csvtab_connect_error; + } + } + if( zFilename==0 ){ + csv_errmsg(&sRdr, "missing 'filename' parameter"); + goto csvtab_connect_error; + } + if( csv_reader_open(&sRdr, zFilename) ){ + goto csvtab_connect_error; + } + pNew = sqlite3_malloc( sizeof(*pNew) ); + *ppVtab = (sqlite3_vtab*)pNew; + if( pNew==0 ) goto csvtab_connect_oom; + memset(pNew, 0, sizeof(*pNew)); + do{ + const char *z = csv_read_one_field(&sRdr); + if( z==0 ) goto csvtab_connect_oom; + pNew->nCol++; + }while( sRdr.cTerm==',' ); + pNew->zFilename = zFilename; + zFilename = 0; + pNew->iStart = bHeader==1 ? ftell(sRdr.in) : 0; + csv_reader_reset(&sRdr); + if( zSchema==0 ){ + char *zSep = ""; + zSchema = sqlite3_mprintf("CREATE TABLE x("); + if( zSchema==0 ) goto csvtab_connect_oom; + for(i=0; inCol; i++){ + zSchema = sqlite3_mprintf("%z%sc%d TEXT",zSchema, zSep, i); + zSep = ","; + } + zSchema = sqlite3_mprintf("%z);", zSchema); + } + rc = sqlite3_declare_vtab(db, zSchema); + if( rc ) goto csvtab_connect_error; + sqlite3_free(zSchema); + return SQLITE_OK; + +csvtab_connect_oom: + rc = SQLITE_NOMEM; + csv_errmsg(&sRdr, "out of memory"); + +csvtab_connect_error: + if( pNew ) csvtabDisconnect(&pNew->base); + sqlite3_free(zFilename); + sqlite3_free(zSchema); + if( sRdr.zErr[0] ){ + sqlite3_free(*pzErr); + *pzErr = sqlite3_mprintf("%s", sRdr.zErr); + } + csv_reader_reset(&sRdr); + return rc; +} + +/* +** Reset the current row content held by a CsvCursor. +*/ +static void csvtabCursorRowReset(CsvCursor *pCur){ + CsvTable *pTab = (CsvTable*)pCur->base.pVtab; + int i; + for(i=0; inCol; i++){ + sqlite3_free(pCur->azVal[i]); + pCur->azVal[i] = 0; + } +} + +/* +** The xConnect and xCreate methods do the same thing, but they must be +** different so that the virtual table is not an eponymous virtual table. +*/ +static int csvtabCreate( + sqlite3 *db, + void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVtab, + char **pzErr +){ + return csvtabConnect(db, pAux, argc, argv, ppVtab, pzErr); +} + +/* +** Destructor for a CsvCursor. +*/ +static int csvtabClose(sqlite3_vtab_cursor *cur){ + CsvCursor *pCur = (CsvCursor*)cur; + csvtabCursorRowReset(pCur); + csv_reader_reset(&pCur->rdr); + sqlite3_free(cur); + return SQLITE_OK; +} + +/* +** Constructor for a new CsvTable cursor object. +*/ +static int csvtabOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){ + CsvTable *pTab = (CsvTable*)p; + CsvCursor *pCur; + pCur = sqlite3_malloc( sizeof(*pCur) * sizeof(char*)*pTab->nCol ); + if( pCur==0 ) return SQLITE_NOMEM; + memset(pCur, 0, sizeof(*pCur) + sizeof(char*)*pTab->nCol ); + pCur->azVal = (char**)&pCur[1]; + *ppCursor = &pCur->base; + if( csv_reader_open(&pCur->rdr, pTab->zFilename) ){ + csv_xfer_error(pTab, &pCur->rdr); + return SQLITE_ERROR; + } + return SQLITE_OK; +} + + +/* +** Advance a CsvCursor to its next row of input. +** Set the EOF marker if we reach the end of input. +*/ +static int csvtabNext(sqlite3_vtab_cursor *cur){ + CsvCursor *pCur = (CsvCursor*)cur; + CsvTable *pTab = (CsvTable*)cur->pVtab; + int i = 0; + char *z; + csvtabCursorRowReset(pCur); + do{ + z = csv_read_one_field(&pCur->rdr); + if( z==0 ){ + csv_xfer_error(pTab, &pCur->rdr); + break; + } + z = sqlite3_mprintf("%s", z); + if( z==0 ){ + csv_errmsg(&pCur->rdr, "out of memory"); + csv_xfer_error(pTab, &pCur->rdr); + break; + } + if( inCol ){ + pCur->azVal[i++] = z; + } + }while( z!=0 && pCur->rdr.cTerm==',' ); + if( z==0 || pCur->rdr.cTerm==EOF ){ + pCur->iRowid = -1; + }else{ + pCur->iRowid++; + } + return SQLITE_OK; +} + +/* +** Return values of columns for the row at which the CsvCursor +** is currently pointing. +*/ +static int csvtabColumn( + sqlite3_vtab_cursor *cur, /* The cursor */ + sqlite3_context *ctx, /* First argument to sqlite3_result_...() */ + int i /* Which column to return */ +){ + CsvCursor *pCur = (CsvCursor*)cur; + CsvTable *pTab = (CsvTable*)cur->pVtab; + if( i>=0 && inCol && pCur->azVal[i]!=0 ){ + sqlite3_result_text(ctx, pCur->azVal[i], -1, SQLITE_STATIC); + } + return SQLITE_OK; +} + +/* +** Return the rowid for the current row. +*/ +static int csvtabRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ + CsvCursor *pCur = (CsvCursor*)cur; + *pRowid = pCur->iRowid; + return SQLITE_OK; +} + +/* +** Return TRUE if the cursor has been moved off of the last +** row of output. +*/ +static int csvtabEof(sqlite3_vtab_cursor *cur){ + CsvCursor *pCur = (CsvCursor*)cur; + return pCur->iRowid<0; +} + +/* +** Only a full table scan is supported. So xFilter simply rewinds to +** the beginning. +*/ +static int csvtabFilter( + sqlite3_vtab_cursor *pVtabCursor, + int idxNum, const char *idxStr, + int argc, sqlite3_value **argv +){ + CsvCursor *pCur = (CsvCursor*)pVtabCursor; + CsvTable *pTab = (CsvTable*)pVtabCursor->pVtab; + pCur->iRowid = 0; + fseek(pCur->rdr.in, pTab->iStart, SEEK_SET); + return csvtabNext(pVtabCursor); +} + +/* +** Only a forwards full table scan is supported. xBestIndex is a no-op. +*/ +static int csvtabBestIndex( + sqlite3_vtab *tab, + sqlite3_index_info *pIdxInfo +){ + return SQLITE_OK; +} + + +static sqlite3_module CsvModule = { + 0, /* iVersion */ + csvtabCreate, /* xCreate */ + csvtabConnect, /* xConnect */ + csvtabBestIndex, /* xBestIndex */ + csvtabDisconnect, /* xDisconnect */ + csvtabDisconnect, /* xDestroy */ + csvtabOpen, /* xOpen - open a cursor */ + csvtabClose, /* xClose - close a cursor */ + csvtabFilter, /* xFilter - configure scan constraints */ + csvtabNext, /* xNext - advance a cursor */ + csvtabEof, /* xEof - check for end of scan */ + csvtabColumn, /* xColumn - read data */ + csvtabRowid, /* xRowid - read data */ + 0, /* xUpdate */ + 0, /* xBegin */ + 0, /* xSync */ + 0, /* xCommit */ + 0, /* xRollback */ + 0, /* xFindMethod */ + 0, /* xRename */ +}; + +#ifdef _WIN32 +__declspec(dllexport) +#endif +/* +** This routine is called when the extension is loaded. The new +** CSV virtual table module is registered with the calling database +** connection. +*/ +int sqlite3_csv_init( + sqlite3 *db, + char **pzErrMsg, + const sqlite3_api_routines *pApi +){ + SQLITE_EXTENSION_INIT2(pApi); + return sqlite3_create_module(db, "csv", &CsvModule, 0); +} diff --git a/manifest b/manifest index ce51d87c84..e2d03ea381 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\sFTS5\sproblem\s(segfault\sor\sincorrect\squery\sresults)\swith\s"...\sMATCH\s'x\sOR\sy'\sORDER\sBY\srank"\squeries\swhen\seither\stoken\s'x'\sor\s'y'\sis\scompletely\sabsent\sfrom\sthe\sdataset. -D 2016-05-30T08:28:21.370 +C Add\sthe\s"csv"\svirtual\stable\sfor\sreading\sCSV\sfiles,\sas\san\sextension\sin\nthe\sext/misc/\ssubfolder. +D 2016-05-31T16:22:48.849 F Makefile.in f59e0763ff448719fc1bd25513882b0567286317 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7 @@ -206,6 +206,7 @@ F ext/icu/sqliteicu.h 728867a802baa5a96de7495e9689a8e01715ef37 F ext/misc/amatch.c 211108e201105e4bb0c076527b8cfd34330fc234 F ext/misc/closure.c 0d2a038df8fbae7f19de42e7c7d71f2e4dc88704 F ext/misc/compress.c 122faa92d25033d6c3f07c39231de074ab3d2e83 +F ext/misc/csv.c 386ea82a7eeac9850000b43913a20453bc816a70 F ext/misc/eval.c f971962e92ebb8b0a4e6b62949463ee454d88fa2 F ext/misc/fileio.c d4171c815d6543a9edef8308aab2951413cd8d0f F ext/misc/fuzzer.c 7c64b8197bb77b7d64eff7cac7848870235d4c25 @@ -1496,7 +1497,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 24f258c2392290168cf34622b89a4a406a3dd853 -R 09bf6149ab89919173c2bf6834d1442a -U dan -Z 067d36e8e3bb6a90972bf218c0cabd70 +P 64ca1a835a89fd211078d2cd8f9b649e89be528d +R b775d969691f2ff7971a8ef71faf9f8c +U drh +Z 58655b63021cdf0ee9fb657659454c01 diff --git a/manifest.uuid b/manifest.uuid index 15daff8194..649908c68d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -64ca1a835a89fd211078d2cd8f9b649e89be528d \ No newline at end of file +00d3570c8bb96469c984903e20de589e998d4636 \ No newline at end of file From abfd272b599c4c4acd1c193822755f0d195dd3f8 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 31 May 2016 18:08:35 +0000 Subject: [PATCH 0483/1484] Add the testflags parameter to the csv extension. FossilOrigin-Name: b93fb2fe0df1b3bea2bc2a4e1528da74ab290593 --- ext/misc/csv.c | 29 ++++++++++++++++++++++++++++- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 35 insertions(+), 8 deletions(-) diff --git a/ext/misc/csv.c b/ext/misc/csv.c index 62521d81f7..d8087664fa 100644 --- a/ext/misc/csv.c +++ b/ext/misc/csv.c @@ -218,8 +218,12 @@ typedef struct CsvTable { char *zFilename; /* Name of the CSV file */ long iStart; /* Offset to start of data in zFilename */ int nCol; /* Number of columns in the CSV file */ + unsigned int tstFlags; /* Bit values used for testing */ } CsvTable; +/* Allowed values for tstFlags */ +#define CSVTEST_FIDX 0x0001 /* Pretend that constrained searchs cost less*/ + /* A cursor for the CSV virtual table */ typedef struct CsvCursor { sqlite3_vtab_cursor base; /* Base class. Must be first */ @@ -314,6 +318,7 @@ static int csv_boolean(const char *z){ ** schema=SCHEMA Optional ** header=YES|NO First row of CSV defines the names of ** columns if "yes". Default "no". +** testflags=N Bitmask of test flags. Optional ** ** If header=no and not columns are listed, then the columns are named ** "c0", "c1", "c2", and so forth. @@ -331,6 +336,7 @@ static int csvtabConnect( int i; char *zFilename = 0; char *zSchema = 0; + int tstFlags = 0; CsvReader sRdr; memset(&sRdr, 0, sizeof(sRdr)); @@ -373,6 +379,9 @@ static int csvtabConnect( goto csvtab_connect_error; } }else + if( (zValue = csv_parameter("testflags",9,z))!=0 ){ + tstFlags = (unsigned int)atoi(zValue); + }else { csv_errmsg(&sRdr, "unrecognized parameter '%s'", z); goto csvtab_connect_error; @@ -395,6 +404,7 @@ static int csvtabConnect( pNew->nCol++; }while( sRdr.cTerm==',' ); pNew->zFilename = zFilename; + pNew->tstFlags = tstFlags; zFilename = 0; pNew->iStart = bHeader==1 ? ftell(sRdr.in) : 0; csv_reader_reset(&sRdr); @@ -426,6 +436,7 @@ csvtab_connect_error: *pzErr = sqlite3_mprintf("%s", sRdr.zErr); } csv_reader_reset(&sRdr); + if( rc==SQLITE_OK ) rc = SQLITE_ERROR; return rc; } @@ -571,12 +582,28 @@ static int csvtabFilter( } /* -** Only a forwards full table scan is supported. xBestIndex is a no-op. +** Only a forwards full table scan is supported. xBestIndex is mostly +** a no-op. If CSVTEST_FIDX is set, then the presence of equality +** constraints lowers the estimated cost, which is fiction, but is useful +** for testing certain kinds of virtual table behavior. */ static int csvtabBestIndex( sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo ){ + CsvTable *pTab = (CsvTable*)tab; + int i; + pIdxInfo->estimatedCost = 1000000; + if( (pTab->tstFlags & CSVTEST_FIDX)==0 ){ + return SQLITE_OK; + } + for(i=0; inConstraint; i++){ + if( pIdxInfo->aConstraint[i].usable==0 ) continue; + if( pIdxInfo->aConstraint[i].op==SQLITE_INDEX_CONSTRAINT_EQ ){ + pIdxInfo->estimatedCost = 10; + break; + } + } return SQLITE_OK; } diff --git a/manifest b/manifest index e2d03ea381..6ea00aab63 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\s"csv"\svirtual\stable\sfor\sreading\sCSV\sfiles,\sas\san\sextension\sin\nthe\sext/misc/\ssubfolder. -D 2016-05-31T16:22:48.849 +C Add\sthe\stestflags\sparameter\sto\sthe\scsv\sextension. +D 2016-05-31T18:08:35.263 F Makefile.in f59e0763ff448719fc1bd25513882b0567286317 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7 @@ -206,7 +206,7 @@ F ext/icu/sqliteicu.h 728867a802baa5a96de7495e9689a8e01715ef37 F ext/misc/amatch.c 211108e201105e4bb0c076527b8cfd34330fc234 F ext/misc/closure.c 0d2a038df8fbae7f19de42e7c7d71f2e4dc88704 F ext/misc/compress.c 122faa92d25033d6c3f07c39231de074ab3d2e83 -F ext/misc/csv.c 386ea82a7eeac9850000b43913a20453bc816a70 +F ext/misc/csv.c d9b1dac6e43891174560abdd7d1d68bac20a2277 F ext/misc/eval.c f971962e92ebb8b0a4e6b62949463ee454d88fa2 F ext/misc/fileio.c d4171c815d6543a9edef8308aab2951413cd8d0f F ext/misc/fuzzer.c 7c64b8197bb77b7d64eff7cac7848870235d4c25 @@ -1497,7 +1497,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 64ca1a835a89fd211078d2cd8f9b649e89be528d -R b775d969691f2ff7971a8ef71faf9f8c +P 00d3570c8bb96469c984903e20de589e998d4636 +R 7c1772dc60b41e0b51f7bd702d450189 U drh -Z 58655b63021cdf0ee9fb657659454c01 +Z ed250383d88d82f9f9e7a2529e3cc23c diff --git a/manifest.uuid b/manifest.uuid index 649908c68d..52e6a805d6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -00d3570c8bb96469c984903e20de589e998d4636 \ No newline at end of file +b93fb2fe0df1b3bea2bc2a4e1528da74ab290593 \ No newline at end of file From 1fc1a0f280e949736d10debf308c79494b16fe77 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 31 May 2016 18:44:33 +0000 Subject: [PATCH 0484/1484] Add the columns=N parameter to the CSV extension. FossilOrigin-Name: 28ebeadd6a4c9ff2ce9fc86a0f0fe2f6cf94d3ac --- ext/misc/csv.c | 69 ++++++++++++++++++++++++++++++++++++-------------- manifest | 12 ++++----- manifest.uuid | 2 +- 3 files changed, 57 insertions(+), 26 deletions(-) diff --git a/ext/misc/csv.c b/ext/misc/csv.c index d8087664fa..81a1d9ff63 100644 --- a/ext/misc/csv.c +++ b/ext/misc/csv.c @@ -315,13 +315,16 @@ static int csv_boolean(const char *z){ /* ** Parameters: ** filename=FILENAME Required -** schema=SCHEMA Optional +** schema=SCHEMA Alternative CSV schema. ** header=YES|NO First row of CSV defines the names of ** columns if "yes". Default "no". +** columns=N Assum the CSV file contains N columns. ** testflags=N Bitmask of test flags. Optional ** -** If header=no and not columns are listed, then the columns are named -** "c0", "c1", "c2", and so forth. +** If schema= is omitted, then the columns are named "c0", "c1", "c2", +** and so forth. If columns=N is omitted, then the file is opened and +** the number of columns in the first row is counted to determine the +** column count. If header=YES, then the first row is skipped. */ static int csvtabConnect( sqlite3 *db, @@ -330,14 +333,16 @@ static int csvtabConnect( sqlite3_vtab **ppVtab, char **pzErr ){ - CsvTable *pNew = 0; - int bHeader = -1; - int rc = SQLITE_OK; - int i; - char *zFilename = 0; - char *zSchema = 0; - int tstFlags = 0; - CsvReader sRdr; + CsvTable *pNew = 0; /* The CsvTable object to construct */ + int bHeader = -1; /* header= flags. -1 means not seen yet */ + int rc = SQLITE_OK; /* Result code from this routine */ + int i; /* Loop counter */ + char *zFilename = 0; /* Value of the filename= parameter */ + char *zSchema = 0; /* Value of the schema= parameter */ + int tstFlags = 0; /* Value of the testflags= parameter */ + int nCol = -99; /* Value of the columns= parameter */ + CsvReader sRdr; /* A CSV file reader used to store an error + ** message and/or to count the number of columns */ memset(&sRdr, 0, sizeof(sRdr)); for(i=3; i0 ){ + csv_errmsg(&sRdr, "more than one 'columns' parameter"); + goto csvtab_connect_error; + } + nCol = atoi(zValue); + if( nCol<=0 ){ + csv_errmsg(&sRdr, "must have at least one column"); + goto csvtab_connect_error; + } + }else { csv_errmsg(&sRdr, "unrecognized parameter '%s'", z); goto csvtab_connect_error; @@ -391,18 +407,22 @@ static int csvtabConnect( csv_errmsg(&sRdr, "missing 'filename' parameter"); goto csvtab_connect_error; } - if( csv_reader_open(&sRdr, zFilename) ){ + if( nCol<=0 && csv_reader_open(&sRdr, zFilename) ){ goto csvtab_connect_error; } pNew = sqlite3_malloc( sizeof(*pNew) ); *ppVtab = (sqlite3_vtab*)pNew; if( pNew==0 ) goto csvtab_connect_oom; memset(pNew, 0, sizeof(*pNew)); - do{ - const char *z = csv_read_one_field(&sRdr); - if( z==0 ) goto csvtab_connect_oom; - pNew->nCol++; - }while( sRdr.cTerm==',' ); + if( nCol>0 ){ + pNew->nCol = nCol; + }else{ + do{ + const char *z = csv_read_one_field(&sRdr); + if( z==0 ) goto csvtab_connect_oom; + pNew->nCol++; + }while( sRdr.cTerm==',' ); + } pNew->zFilename = zFilename; pNew->tstFlags = tstFlags; zFilename = 0; @@ -593,15 +613,26 @@ static int csvtabBestIndex( ){ CsvTable *pTab = (CsvTable*)tab; int i; + int nConst = 0; pIdxInfo->estimatedCost = 1000000; if( (pTab->tstFlags & CSVTEST_FIDX)==0 ){ return SQLITE_OK; } + /* The usual (an sensible) case is to take the "return SQLITE_OK" above. + ** The code below only runs when testflags=1. The following code + ** generates an artifical and unrealistic plan which is useful + ** for testing virtual table logic but is useless for real applications. */ for(i=0; inConstraint; i++){ + unsigned char op; if( pIdxInfo->aConstraint[i].usable==0 ) continue; - if( pIdxInfo->aConstraint[i].op==SQLITE_INDEX_CONSTRAINT_EQ ){ + op = pIdxInfo->aConstraint[i].op; + if( op==SQLITE_INDEX_CONSTRAINT_EQ + || op==SQLITE_INDEX_CONSTRAINT_LIKE + || op==SQLITE_INDEX_CONSTRAINT_GLOB + ){ pIdxInfo->estimatedCost = 10; - break; + pIdxInfo->aConstraintUsage[nConst].argvIndex = nConst+1; + nConst++; } } return SQLITE_OK; diff --git a/manifest b/manifest index 6ea00aab63..db47b84b3f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\stestflags\sparameter\sto\sthe\scsv\sextension. -D 2016-05-31T18:08:35.263 +C Add\sthe\scolumns=N\sparameter\sto\sthe\sCSV\sextension. +D 2016-05-31T18:44:33.835 F Makefile.in f59e0763ff448719fc1bd25513882b0567286317 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7 @@ -206,7 +206,7 @@ F ext/icu/sqliteicu.h 728867a802baa5a96de7495e9689a8e01715ef37 F ext/misc/amatch.c 211108e201105e4bb0c076527b8cfd34330fc234 F ext/misc/closure.c 0d2a038df8fbae7f19de42e7c7d71f2e4dc88704 F ext/misc/compress.c 122faa92d25033d6c3f07c39231de074ab3d2e83 -F ext/misc/csv.c d9b1dac6e43891174560abdd7d1d68bac20a2277 +F ext/misc/csv.c 39060a352f43e43df575484cc0f23ab61091dac3 F ext/misc/eval.c f971962e92ebb8b0a4e6b62949463ee454d88fa2 F ext/misc/fileio.c d4171c815d6543a9edef8308aab2951413cd8d0f F ext/misc/fuzzer.c 7c64b8197bb77b7d64eff7cac7848870235d4c25 @@ -1497,7 +1497,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 00d3570c8bb96469c984903e20de589e998d4636 -R 7c1772dc60b41e0b51f7bd702d450189 +P b93fb2fe0df1b3bea2bc2a4e1528da74ab290593 +R 65e8595850caa2b47ebf66d47e8638e5 U drh -Z ed250383d88d82f9f9e7a2529e3cc23c +Z b14790ed4c9841c10d8b6970f4ae5ca1 diff --git a/manifest.uuid b/manifest.uuid index 52e6a805d6..bc70991975 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b93fb2fe0df1b3bea2bc2a4e1528da74ab290593 \ No newline at end of file +28ebeadd6a4c9ff2ce9fc86a0f0fe2f6cf94d3ac \ No newline at end of file From 62340f849859258cf7ec778d9edd7391f450af62 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 31 May 2016 21:18:15 +0000 Subject: [PATCH 0485/1484] An experimental branch with code that allows virtual tables to be declared as WITHOUT ROWID tables. This might be useful for virtual tables that model external data sources that do not have a convenient way of computing a unique rowid. The current check-in almost works, but there are still serious issues. FossilOrigin-Name: 49638f180e26477974cacc69b79e0be0a5e18b29 --- manifest | 21 +++++++------ manifest.uuid | 2 +- src/build.c | 83 ++++++++++++++++++++++++------------------------- src/parse.y | 8 +++-- src/sqliteInt.h | 4 +-- src/vtab.c | 12 ++++--- 6 files changed, 69 insertions(+), 61 deletions(-) diff --git a/manifest b/manifest index db47b84b3f..d3f3735698 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\scolumns=N\sparameter\sto\sthe\sCSV\sextension. -D 2016-05-31T18:44:33.835 +C An\sexperimental\sbranch\swith\scode\sthat\sallows\svirtual\stables\sto\sbe\sdeclared\nas\sWITHOUT\sROWID\stables.\sThis\smight\sbe\suseful\sfor\svirtual\stables\sthat\smodel\nexternal\sdata\ssources\sthat\sdo\snot\shave\sa\sconvenient\sway\sof\scomputing\sa\sunique\nrowid.\s\sThe\scurrent\scheck-in\salmost\sworks,\sbut\sthere\sare\sstill\sserious\sissues. +D 2016-05-31T21:18:15.834 F Makefile.in f59e0763ff448719fc1bd25513882b0567286317 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7 @@ -328,7 +328,7 @@ F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 F src/btree.c 2128172fc1c420a6fa6878827fa595407795069a F src/btree.h 1342a9b2cc2089e3534d3ef00204786783f6aea6 F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 -F src/build.c 785fa789319d93c6ae20efbd01d4da9ce8f8a793 +F src/build.c 7acc29d0944bd9995864148286e9daeb0cbce742 F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 999a828425b35b8092a8cde25690e71c20906344 @@ -370,7 +370,7 @@ F src/os_win.c 852fc2ff6084296348ed3739c548b2cf32df394e F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c c368634b888b1c8740aea83b36bfd266f2443e60 F src/pager.h 8ab6b6feeee4bc0439bfde7ee59ba99df98b9bc3 -F src/parse.y 10eb2f3fb62341291528c7984498054731f9d31e +F src/parse.y 01b9f37c4c7009ab56fda98bc7db4c42643cecfe F src/pcache.c 5583c8ade4b05075a60ba953ef471d1c1a9c05df F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 F src/pcache1.c 7f51d2b541aab57596adf62db2c4bb025d34f04d @@ -386,7 +386,7 @@ F src/shell.c 14ff7f660530a52b117d110ba3390b7b2eb719b6 F src/sqlite.h.in 9984129d86243424b765fcb3f147c697bd20bb54 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 98f72cbfe00169c39089115427d06ea05fe4b4a2 -F src/sqliteInt.h 09621b4b7dba808b24262c2480ea75b045001853 +F src/sqliteInt.h 801e2a569ea79b09b87d045cd6f00ec88205f1f6 F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 @@ -456,7 +456,7 @@ F src/vdbeblob.c c9f2f494b911c6fa34efd9803f0a10807da80f77 F src/vdbemem.c 5cfef60e60e19cab6275d1b975bf4c791d575beb F src/vdbesort.c 91fda3909326860382b0ca8aa251e609c6a9d62c F src/vdbetrace.c f75c5455d8cf389ef86a8bfdfd3177e0e3692484 -F src/vtab.c ce0f2ebb589b459b32c640b33af64bfa5b29aaf8 +F src/vtab.c 694e444986746b7e3bb9bd3d74e3284dd7209990 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 02eeecc265f6ffd0597378f5d8ae9070b62a406a F src/wal.h 2f7c831cf3b071fa548bf2d5cac640846a7ff19c @@ -1497,7 +1497,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b93fb2fe0df1b3bea2bc2a4e1528da74ab290593 -R 65e8595850caa2b47ebf66d47e8638e5 +P 28ebeadd6a4c9ff2ce9fc86a0f0fe2f6cf94d3ac +R f4a0fccb57a153a0ab74e7b69ae020b2 +T *branch * without-rowid-vtab +T *sym-without-rowid-vtab * +T -sym-trunk * U drh -Z b14790ed4c9841c10d8b6970f4ae5ca1 +Z 938f365203a268d591e6d60732902516 diff --git a/manifest.uuid b/manifest.uuid index bc70991975..06965e9c56 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -28ebeadd6a4c9ff2ce9fc86a0f0fe2f6cf94d3ac \ No newline at end of file +49638f180e26477974cacc69b79e0be0a5e18b29 \ No newline at end of file diff --git a/src/build.c b/src/build.c index 565101356a..5afc32bd5e 100644 --- a/src/build.c +++ b/src/build.c @@ -605,8 +605,11 @@ static void SQLITE_NOINLINE deleteTable(sqlite3 *db, Table *pTable){ /* Delete all indices associated with this table. */ for(pIndex = pTable->pIndex; pIndex; pIndex=pNext){ pNext = pIndex->pNext; - assert( pIndex->pSchema==pTable->pSchema ); - if( !db || db->pnBytesFreed==0 ){ + assert( pIndex->pSchema==pTable->pSchema + || (IsVirtual(pTable) && pIndex->idxType!=SQLITE_IDXTYPE_APPDEF) ); + if( pIndex->idxType==SQLITE_IDXTYPE_APPDEF + && (!db || db->pnBytesFreed==0) + ){ char *zName = pIndex->zName; TESTONLY ( Index *pOld = ) sqlite3HashInsert( &pIndex->pSchema->idxHash, zName, 0 @@ -1288,7 +1291,7 @@ void sqlite3AddPrimaryKey( Column *pCol = 0; int iCol = -1, i; int nTerm; - if( pTab==0 || IN_DECLARE_VTAB ) goto primary_key_exit; + if( pTab==0 ) goto primary_key_exit; if( pTab->tabFlags & TF_HasPrimaryKey ){ sqlite3ErrorMsg(pParse, "table \"%s\" has more than one primary key", pTab->zName); @@ -1334,12 +1337,8 @@ void sqlite3AddPrimaryKey( "INTEGER PRIMARY KEY"); #endif }else{ - Index *p; - p = sqlite3CreateIndex(pParse, 0, 0, 0, pList, onError, 0, - 0, sortOrder, 0); - if( p ){ - p->idxType = SQLITE_IDXTYPE_PRIMARYKEY; - } + sqlite3CreateIndex(pParse, 0, 0, 0, pList, onError, 0, + 0, sortOrder, 0, SQLITE_IDXTYPE_PRIMARYKEY); pList = 0; } @@ -1656,21 +1655,23 @@ static int hasColumn(const i16 *aiCol, int nCol, int x){ ** are appropriate for a WITHOUT ROWID table instead of a rowid table. ** Changes include: ** -** (1) Convert the OP_CreateTable into an OP_CreateIndex. There is +** (1) Set all columns of the PRIMARY KEY schema object to be NOT NULL. +** (2) Convert the OP_CreateTable into an OP_CreateIndex. There is ** no rowid btree for a WITHOUT ROWID. Instead, the canonical ** data storage is a covering index btree. -** (2) Bypass the creation of the sqlite_master table entry +** (3) Bypass the creation of the sqlite_master table entry ** for the PRIMARY KEY as the primary key index is now ** identified by the sqlite_master table entry of the table itself. -** (3) Set the Index.tnum of the PRIMARY KEY Index object in the +** (4) Set the Index.tnum of the PRIMARY KEY Index object in the ** schema to the rootpage from the main table. -** (4) Set all columns of the PRIMARY KEY schema object to be NOT NULL. ** (5) Add all table columns to the PRIMARY KEY Index object ** so that the PRIMARY KEY is a covering index. The surplus ** columns are part of KeyInfo.nXField and are not used for ** sorting or lookup or uniqueness checks. ** (6) Replace the rowid tail on all automatically generated UNIQUE ** indices with the PRIMARY KEY columns. +** +** For virtual tables, only (1) is performed. */ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){ Index *pIdx; @@ -1680,6 +1681,20 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){ sqlite3 *db = pParse->db; Vdbe *v = pParse->pVdbe; + /* Mark every PRIMARY KEY column as NOT NULL (except for imposter tables) + */ + if( !db->init.imposterTable ){ + for(i=0; inCol; i++){ + if( (pTab->aCol[i].colFlags & COLFLAG_PRIMKEY)!=0 ){ + pTab->aCol[i].notNull = OE_Abort; + } + } + } + + /* The remaining transformations only apply to b-tree tables, not to + ** virtual tables */ + if( IN_DECLARE_VTAB ) return; + /* Convert the OP_CreateTable opcode that would normally create the ** root-page for the table into an OP_CreateIndex opcode. The index ** created will become the PRIMARY KEY index. @@ -1701,9 +1716,9 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){ if( pList==0 ) return; pList->a[0].sortOrder = pParse->iPkSortOrder; assert( pParse->pNewTable==pTab ); - pPk = sqlite3CreateIndex(pParse, 0, 0, 0, pList, pTab->keyConf, 0, 0, 0, 0); - if( pPk==0 ) return; - pPk->idxType = SQLITE_IDXTYPE_PRIMARYKEY; + sqlite3CreateIndex(pParse, 0, 0, 0, pList, pTab->keyConf, 0, 0, 0, 0, + SQLITE_IDXTYPE_PRIMARYKEY); + pPk = sqlite3PrimaryKeyIndex(pTab); pTab->iPKey = -1; }else{ pPk = sqlite3PrimaryKeyIndex(pTab); @@ -1731,19 +1746,11 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){ } pPk->nKeyCol = j; } - pPk->isCovering = 1; assert( pPk!=0 ); + pPk->isCovering = 1; + if( !db->init.imposterTable ) pPk->uniqNotNull = 1; nPk = pPk->nKeyCol; - /* Make sure every column of the PRIMARY KEY is NOT NULL. (Except, - ** do not enforce this for imposter tables.) */ - if( !db->init.imposterTable ){ - for(i=0; iaCol[pPk->aiColumn[i]].notNull = OE_Abort; - } - pPk->uniqNotNull = 1; - } - /* The root page of the PRIMARY KEY is the table root page */ pPk->tnum = pTab->tnum; @@ -2868,12 +2875,8 @@ Index *sqlite3AllocateIndexObject( ** pList is a list of columns to be indexed. pList will be NULL if this ** is a primary key or unique-constraint on the most recent column added ** to the table currently under construction. -** -** If the index is created successfully, return a pointer to the new Index -** structure. This is used by sqlite3AddPrimaryKey() to mark the index -** as the tables primary key (Index.idxType==SQLITE_IDXTYPE_PRIMARYKEY) */ -Index *sqlite3CreateIndex( +void sqlite3CreateIndex( Parse *pParse, /* All information about this parse */ Token *pName1, /* First part of index name. May be NULL */ Token *pName2, /* Second part of index name. May be NULL */ @@ -2883,9 +2886,9 @@ Index *sqlite3CreateIndex( Token *pStart, /* The CREATE token that begins this statement */ Expr *pPIWhere, /* WHERE clause for partial indices */ int sortOrder, /* Sort order of primary key when pList==NULL */ - int ifNotExist /* Omit error if index already exists */ + int ifNotExist, /* Omit error if index already exists */ + u8 idxType /* The index type */ ){ - Index *pRet = 0; /* Pointer to return */ Table *pTab = 0; /* Table to be indexed */ Index *pIndex = 0; /* The index to be created */ char *zName = 0; /* Name of the index */ @@ -2903,7 +2906,10 @@ Index *sqlite3CreateIndex( char *zExtra = 0; /* Extra space after the Index object */ Index *pPk = 0; /* PRIMARY KEY index for WITHOUT ROWID tables */ - if( db->mallocFailed || IN_DECLARE_VTAB || pParse->nErr>0 ){ + if( db->mallocFailed || pParse->nErr>0 ){ + goto exit_create_index; + } + if( IN_DECLARE_VTAB && idxType!=SQLITE_IDXTYPE_PRIMARYKEY ){ goto exit_create_index; } if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ @@ -3092,7 +3098,7 @@ Index *sqlite3CreateIndex( pIndex->pTable = pTab; pIndex->onError = (u8)onError; pIndex->uniqNotNull = onError!=OE_None; - pIndex->idxType = pName ? SQLITE_IDXTYPE_APPDEF : SQLITE_IDXTYPE_UNIQUE; + pIndex->idxType = idxType; pIndex->pSchema = db->aDb[iDb].pSchema; pIndex->nKeyCol = pList->nExpr; if( pPIWhere ){ @@ -3272,7 +3278,6 @@ Index *sqlite3CreateIndex( pIdx->onError = pIndex->onError; } } - pRet = pIdx; goto exit_create_index; } } @@ -3390,7 +3395,6 @@ Index *sqlite3CreateIndex( pIndex->pNext = pOther->pNext; pOther->pNext = pIndex; } - pRet = pIndex; pIndex = 0; } @@ -3401,7 +3405,6 @@ exit_create_index: sqlite3ExprListDelete(db, pList); sqlite3SrcListDelete(db, pTblName); sqlite3DbFree(db, zName); - return pRet; } /* @@ -4315,10 +4318,6 @@ void sqlite3Reindex(Parse *pParse, Token *pName1, Token *pName2){ /* ** Return a KeyInfo structure that is appropriate for the given Index. ** -** The KeyInfo structure for an index is cached in the Index object. -** So there might be multiple references to the returned pointer. The -** caller should not try to modify the KeyInfo object. -** ** The caller should invoke sqlite3KeyInfoUnref() on the returned object ** when it has finished using it. */ diff --git a/src/parse.y b/src/parse.y index ae763e46d6..9294a30428 100644 --- a/src/parse.y +++ b/src/parse.y @@ -300,7 +300,8 @@ ccons ::= NULL onconf. ccons ::= NOT NULL onconf(R). {sqlite3AddNotNull(pParse, R);} ccons ::= PRIMARY KEY sortorder(Z) onconf(R) autoinc(I). {sqlite3AddPrimaryKey(pParse,0,R,I,Z);} -ccons ::= UNIQUE onconf(R). {sqlite3CreateIndex(pParse,0,0,0,0,R,0,0,0,0);} +ccons ::= UNIQUE onconf(R). {sqlite3CreateIndex(pParse,0,0,0,0,R,0,0,0,0, + SQLITE_IDXTYPE_UNIQUE);} ccons ::= CHECK LP expr(X) RP. {sqlite3AddCheckConstraint(pParse,X.pExpr);} ccons ::= REFERENCES nm(T) eidlist_opt(TA) refargs(R). {sqlite3CreateForeignKey(pParse,0,&T,TA,R);} @@ -349,7 +350,8 @@ tcons ::= CONSTRAINT nm(X). {pParse->constraintName = X;} tcons ::= PRIMARY KEY LP sortlist(X) autoinc(I) RP onconf(R). {sqlite3AddPrimaryKey(pParse,X,R,I,0);} tcons ::= UNIQUE LP sortlist(X) RP onconf(R). - {sqlite3CreateIndex(pParse,0,0,0,X,R,0,0,0,0);} + {sqlite3CreateIndex(pParse,0,0,0,X,R,0,0,0,0, + SQLITE_IDXTYPE_UNIQUE);} tcons ::= CHECK LP expr(E) RP onconf. {sqlite3AddCheckConstraint(pParse,E.pExpr);} tcons ::= FOREIGN KEY LP eidlist(FA) RP @@ -1198,7 +1200,7 @@ cmd ::= createkw(S) uniqueflag(U) INDEX ifnotexists(NE) nm(X) dbnm(D) ON nm(Y) LP sortlist(Z) RP where_opt(W). { sqlite3CreateIndex(pParse, &X, &D, sqlite3SrcListAppend(pParse->db,0,&Y,0), Z, U, - &S, W, SQLITE_SO_ASC, NE); + &S, W, SQLITE_SO_ASC, NE, SQLITE_IDXTYPE_APPDEF); } %type uniqueflag {int} diff --git a/src/sqliteInt.h b/src/sqliteInt.h index b15d788093..024003afb0 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3617,8 +3617,8 @@ void sqlite3SrcListAssignCursors(Parse*, SrcList*); void sqlite3IdListDelete(sqlite3*, IdList*); void sqlite3SrcListDelete(sqlite3*, SrcList*); Index *sqlite3AllocateIndexObject(sqlite3*,i16,int,char**); -Index *sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*, - Expr*, int, int); +void sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*, + Expr*, int, int, u8); void sqlite3DropIndex(Parse*, SrcList*, int); int sqlite3Select(Parse*, Select*, SelectDest*); Select *sqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*, diff --git a/src/vtab.c b/src/vtab.c index 2fe105a296..01ea9750f5 100644 --- a/src/vtab.c +++ b/src/vtab.c @@ -754,10 +754,14 @@ int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){ && (pParse->pNewTable->tabFlags & TF_Virtual)==0 ){ if( !pTab->aCol ){ - pTab->aCol = pParse->pNewTable->aCol; - pTab->nCol = pParse->pNewTable->nCol; - pParse->pNewTable->nCol = 0; - pParse->pNewTable->aCol = 0; + Table *pNew = pParse->pNewTable; + pTab->aCol = pNew->aCol; + pTab->nCol = pNew->nCol; + pTab->tabFlags |= pNew->tabFlags & TF_WithoutRowid; + pTab->pIndex = pNew->pIndex; + pNew->nCol = 0; + pNew->aCol = 0; + pNew->pIndex = 0; } pCtx->bDeclared = 1; }else{ From 9f6e686f59fff4b7413182980cc3dfa898986ddf Mon Sep 17 00:00:00 2001 From: mistachkin Date: Wed, 1 Jun 2016 05:02:05 +0000 Subject: [PATCH 0486/1484] Fix compilation issues with the VFS stat extension. FossilOrigin-Name: f6e956525b03fa07190e5521edac4758c386cc80 --- ext/misc/vfsstat.c | 4 ++-- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/ext/misc/vfsstat.c b/ext/misc/vfsstat.c index eefa6ea62b..30d4514113 100644 --- a/ext/misc/vfsstat.c +++ b/ext/misc/vfsstat.c @@ -402,7 +402,7 @@ static int vstatShmLock(sqlite3_file *pFile, int offset, int n, int flags){ /* Memory barrier operation on shared memory */ static void vstatShmBarrier(sqlite3_file *pFile){ VStatFile *p = (VStatFile *)pFile; - return p->pReal->pMethods->xShmBarrier(p->pReal); + p->pReal->pMethods->xShmBarrier(p->pReal); } /* Unmap a shared memory segment */ @@ -806,7 +806,7 @@ int sqlite3_vfsstat_init( int rc = SQLITE_OK; SQLITE_EXTENSION_INIT2(pApi); vstat_vfs.pVfs = sqlite3_vfs_find(0); - vstat_vfs.base.szOsFile = sizeof(VStatFile) + pNew->pVfs->szOsFile; + vstat_vfs.base.szOsFile = sizeof(VStatFile) + vstat_vfs.pVfs->szOsFile; rc = sqlite3_vfs_register(&vstat_vfs.base, 1); if( rc==SQLITE_OK ){ rc = sqlite3_auto_extension((void(*)(void))vstatRegister); diff --git a/manifest b/manifest index db47b84b3f..35df2a424c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\scolumns=N\sparameter\sto\sthe\sCSV\sextension. -D 2016-05-31T18:44:33.835 +C Fix\scompilation\sissues\swith\sthe\sVFS\sstat\sextension. +D 2016-06-01T05:02:05.387 F Makefile.in f59e0763ff448719fc1bd25513882b0567286317 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7 @@ -222,7 +222,7 @@ F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52 F ext/misc/spellfix.c bf1b922c2750698e9a3d4c50cce6974adb7e93be F ext/misc/totype.c 4a167594e791abeed95e0a8db028822b5e8fe512 F ext/misc/vfslog.c fe40fab5c077a40477f7e5eba994309ecac6cc95 -F ext/misc/vfsstat.c 20f206b6d38911dfac4b4db88171204d0373f7df +F ext/misc/vfsstat.c aed1f11904f07487d71015c8826885f57e4644b3 F ext/misc/vtshim.c babb0dc2bf116029e3e7c9a618b8a1377045303e F ext/misc/wholenumber.c 784b12543d60702ebdd47da936e278aa03076212 F ext/rbu/rbu.c b2c0b5e6ae1a89affc0edfc127ebfa5f637a0ce4 @@ -1497,7 +1497,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b93fb2fe0df1b3bea2bc2a4e1528da74ab290593 -R 65e8595850caa2b47ebf66d47e8638e5 -U drh -Z b14790ed4c9841c10d8b6970f4ae5ca1 +P 28ebeadd6a4c9ff2ce9fc86a0f0fe2f6cf94d3ac +R 439a7441f751d5eee3dcb1d6f6a64d80 +U mistachkin +Z fb90ffd16972fce7722c3409e726b839 diff --git a/manifest.uuid b/manifest.uuid index bc70991975..f309668697 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -28ebeadd6a4c9ff2ce9fc86a0f0fe2f6cf94d3ac \ No newline at end of file +f6e956525b03fa07190e5521edac4758c386cc80 \ No newline at end of file From 82a1c0e5bb94704c27cd50eddb6a10bc4b8b677d Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 1 Jun 2016 10:37:50 +0000 Subject: [PATCH 0487/1484] Fix an issue preventing RBU vacuum from working with virtual tables. FossilOrigin-Name: 3bd85fa5a9a489fd505c973e37c33a76c1b0e957 --- ext/rbu/rbu_common.tcl | 17 +++++ ext/rbu/rbuvacuum.test | 18 ----- ext/rbu/rbuvacuum2.test | 162 ++++++++++++++++++++++++++++++++++++++++ ext/rbu/sqlite3rbu.c | 6 +- manifest | 19 ++--- manifest.uuid | 2 +- 6 files changed, 194 insertions(+), 30 deletions(-) create mode 100644 ext/rbu/rbuvacuum2.test diff --git a/ext/rbu/rbu_common.tcl b/ext/rbu/rbu_common.tcl index 8190021baf..4a8c5cba9f 100644 --- a/ext/rbu/rbu_common.tcl +++ b/ext/rbu/rbu_common.tcl @@ -36,3 +36,20 @@ proc step_rbu {target rbu} { set rc } +proc do_rbu_vacuum_test {tn step} { + uplevel [list do_test $tn.1 { + if {$step==0} { sqlite3rbu_vacuum rbu test.db state.db } + while 1 { + if {$step==1} { sqlite3rbu_vacuum rbu test.db state.db } + set rc [rbu step] + if {$rc!="SQLITE_OK"} break + if {$step==1} { rbu close } + } + rbu close + } {SQLITE_DONE}] + + uplevel [list do_execsql_test $tn.2 { + PRAGMA integrity_check + } ok] +} + diff --git a/ext/rbu/rbuvacuum.test b/ext/rbu/rbuvacuum.test index 7d82e380d6..86f4aa770e 100644 --- a/ext/rbu/rbuvacuum.test +++ b/ext/rbu/rbuvacuum.test @@ -17,23 +17,6 @@ source [file join [file dirname [info script]] rbu_common.tcl] set ::testprefix rbuvacuum -proc do_rbu_vacuum_test {tn step} { - uplevel [list do_test $tn.1 { - if {$step==0} { sqlite3rbu_vacuum rbu test.db state.db } - while 1 { - if {$step==1} { sqlite3rbu_vacuum rbu test.db state.db } - set rc [rbu step] - if {$rc!="SQLITE_OK"} break - if {$step==1} { rbu close } - } - rbu close - } {SQLITE_DONE}] - - uplevel [list do_execsql_test $tn.2 { - PRAGMA integrity_check - } ok] -} - foreach step {0 1} { set ::testprefix rbuvacuum-step=$step @@ -404,7 +387,6 @@ do_test 3.5 { list [catch { rbu close } msg] $msg } {0 SQLITE_DONE} - catch { db close } finish_test diff --git a/ext/rbu/rbuvacuum2.test b/ext/rbu/rbuvacuum2.test new file mode 100644 index 0000000000..6397751836 --- /dev/null +++ b/ext/rbu/rbuvacuum2.test @@ -0,0 +1,162 @@ +# 2016 June 1 +# +# 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 contains tests for the RBU module. More specifically, it +# contains tests to ensure that the sqlite3rbu_vacuum() API works as +# expected. +# + +source [file join [file dirname [info script]] rbu_common.tcl] + +foreach step {0 1} { + set ::testprefix rbuvacuum2-$step + + #------------------------------------------------------------------------- + # Test that a database that contains fts3 tables can be vacuumed. + # + ifcapable fts3 { + reset_db + do_execsql_test 1.1 { + CREATE VIRTUAL TABLE t1 USING fts3(z, y); + INSERT INTO t1 VALUES('fix this issue', 'at some point'); + } + + do_rbu_vacuum_test 1.2 $step + + do_execsql_test 1.3 { + SELECT * FROM t1; + } {{fix this issue} {at some point}} + + do_execsql_test 1.4 { + SELECT rowid FROM t1 WHERE t1 MATCH 'fix'; + } {1} + + do_execsql_test 1.5 { + INSERT INTO t1 VALUES('a b c', 'd e f'); + INSERT INTO t1 VALUES('l h i', 'd e f'); + DELETE FROM t1 WHERE docid = 2; + INSERT INTO t1 VALUES('a b c', 'x y z'); + } + + do_rbu_vacuum_test 1.6 $step + do_execsql_test 1.7 { + INSERT INTO t1(t1) VALUES('integrity-check'); + SELECT * FROM t1; + } { + {fix this issue} {at some point} + {l h i} {d e f} + {a b c} {x y z} + } + } + + #------------------------------------------------------------------------- + # Test that a database that contains fts5 tables can be vacuumed. + # + ifcapable fts5 { + reset_db + do_execsql_test 2.1 { + CREATE VIRTUAL TABLE t1 USING fts5(z, y); + INSERT INTO t1 VALUES('fix this issue', 'at some point'); + } + + do_rbu_vacuum_test 2.2 $step + + do_execsql_test 2.3 { + SELECT * FROM t1; + } {{fix this issue} {at some point}} + + do_execsql_test 2.4 { + SELECT rowid FROM t1 ('fix'); + } {1} + + do_execsql_test 2.5 { + INSERT INTO t1 VALUES('a b c', 'd e f'); + INSERT INTO t1 VALUES('l h i', 'd e f'); + DELETE FROM t1 WHERE rowid = 2; + INSERT INTO t1 VALUES('a b c', 'x y z'); + } + + do_rbu_vacuum_test 2.6 $step + do_execsql_test 2.7 { + INSERT INTO t1(t1) VALUES('integrity-check'); + SELECT * FROM t1; + } { + {fix this issue} {at some point} + {l h i} {d e f} + {a b c} {x y z} + } + } + + #------------------------------------------------------------------------- + # Test that a database that contains an rtree table can be vacuumed. + # + ifcapable rtree { + reset_db + do_execsql_test 3.1 { + CREATE VIRTUAL TABLE rt USING rtree(id, x1, x2); + INSERT INTO rt VALUES(1, 45, 55); + INSERT INTO rt VALUES(2, 50, 60); + INSERT INTO rt VALUES(3, 55, 65); + } + + do_rbu_vacuum_test 3.2 $step + + do_execsql_test 3.3 { + SELECT * FROM rt; + } {1 45.0 55.0 2 50.0 60.0 3 55.0 65.0} + + do_execsql_test 3.4.1 { + SELECT rowid FROM rt WHERE x2>51 AND x1 < 51 + } {1 2} + do_execsql_test 3.4.2 { + SELECT rowid FROM rt WHERE x2>59 AND x1 < 59 + } {2 3} + + do_rbu_vacuum_test 3.5 $step + + do_execsql_test 3.6.1 { + SELECT rowid FROM rt WHERE x2>51 AND x1 < 51 + } {1 2} + do_execsql_test 3.6.2 { + SELECT rowid FROM rt WHERE x2>59 AND x1 < 59 + } {2 3} + } + + ifcapable trigger { + reset_db + do_execsql_test 4.1 { + CREATE TABLE t1(a, b, c); + INSERT INTO t1 VALUES(1, 2, 3); + CREATE VIEW v1 AS SELECT * FROM t1; + CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN SELECT 1; END; + } + + do_execsql_test 4.2 { + SELECT * FROM sqlite_master; + } { + table t1 t1 2 {CREATE TABLE t1(a, b, c)} + view v1 v1 0 {CREATE VIEW v1 AS SELECT * FROM t1} + trigger tr1 t1 0 {CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN SELECT 1; END} + } + + do_rbu_vacuum_test 4.3 $step + do_execsql_test 4.4 { + SELECT * FROM sqlite_master; + } { + table t1 t1 2 {CREATE TABLE t1(a, b, c)} + view v1 v1 0 {CREATE VIEW v1 AS SELECT * FROM t1} + trigger tr1 t1 0 {CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN SELECT 1; END} + } + } + +} + +finish_test diff --git a/ext/rbu/sqlite3rbu.c b/ext/rbu/sqlite3rbu.c index dc80935ecf..39d31935cb 100644 --- a/ext/rbu/sqlite3rbu.c +++ b/ext/rbu/sqlite3rbu.c @@ -921,12 +921,14 @@ static int rbuObjIterFirst(sqlite3rbu *p, RbuObjIter *pIter){ int rc; memset(pIter, 0, sizeof(RbuObjIter)); - rc = prepareAndCollectError(p->dbRbu, &pIter->pTblIter, &p->zErrmsg, + rc = prepareFreeAndCollectError(p->dbRbu, &pIter->pTblIter, &p->zErrmsg, + sqlite3_mprintf( "SELECT rbu_target_name(name, type='view') AS target, name " "FROM sqlite_master " "WHERE type IN ('table', 'view') AND target IS NOT NULL " + " %s " "ORDER BY name" - ); + , rbuIsVacuum(p) ? "AND rootpage!=0 AND rootpage IS NOT NULL" : "")); if( rc==SQLITE_OK ){ rc = prepareAndCollectError(p->dbMain, &pIter->pIdxIter, &p->zErrmsg, diff --git a/manifest b/manifest index 35df2a424c..28d7551f5d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\scompilation\sissues\swith\sthe\sVFS\sstat\sextension. -D 2016-06-01T05:02:05.387 +C Fix\san\sissue\spreventing\sRBU\svacuum\sfrom\sworking\swith\svirtual\stables. +D 2016-06-01T10:37:50.553 F Makefile.in f59e0763ff448719fc1bd25513882b0567286317 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7 @@ -241,7 +241,7 @@ F ext/rbu/rbu9.test 0806d1772c9f4981774ff028de6656e4183082af F ext/rbu/rbuA.test c1a7b3e2d926b8f8448bb3b4ae787e314ee4b2b3 F ext/rbu/rbuB.test c25bc325b8072a766e56bb76c001866b405925c2 F ext/rbu/rbuC.test efe47db508a0269b683cb2a1913a425ffd39a831 -F ext/rbu/rbu_common.tcl 0398545fed614f807d5f0ba55a85a51f08ba8f1a +F ext/rbu/rbu_common.tcl 3a4b916b6f5dca9c9da9a30863e272fe5ea4414f F ext/rbu/rbucrash.test 8d2ed5d4b05fef6c00c2a6b5f7ead71fa172a695 F ext/rbu/rbudiff.test 2df0a8a7d998ecf81764c21eeda3cde5611c5091 F ext/rbu/rbufault.test cc0be8d5d392d98b0c2d6a51be377ea989250a89 @@ -250,8 +250,9 @@ F ext/rbu/rbufault3.test 54a399888ac4af44c68f9f58afbed23149428bca F ext/rbu/rbufts.test 828cd689da825f0a7b7c53ffc1f6f7fdb6fa5bda F ext/rbu/rbuprogress.test 2023a7df2c523e3df1cb532eff811cda385a789a F ext/rbu/rbusave.test 0f43b6686084f426ddd040b878426452fd2c2f48 -F ext/rbu/rbuvacuum.test 66e02cf299836770e718e95c36686be0b26dbda3 -F ext/rbu/sqlite3rbu.c bf36625990c6865ecf08bd844d8097ed2d0a6958 +F ext/rbu/rbuvacuum.test 4a977447c15c2581ab668781d9ef4294382530e0 +F ext/rbu/rbuvacuum2.test 45009e127c3fb385e5c0fd5a8a63fb922a79d0ab +F ext/rbu/sqlite3rbu.c a37a7dfb225c497171aa60120e81b884954361c7 F ext/rbu/sqlite3rbu.h 2acd0a6344a6079de15c8dc9d84d3df83a665930 F ext/rbu/test_rbu.c 9bbdf6bd8efd58fbc4f192698df50569598fbb9e F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 @@ -1497,7 +1498,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 28ebeadd6a4c9ff2ce9fc86a0f0fe2f6cf94d3ac -R 439a7441f751d5eee3dcb1d6f6a64d80 -U mistachkin -Z fb90ffd16972fce7722c3409e726b839 +P f6e956525b03fa07190e5521edac4758c386cc80 +R e1810942aeafbc52047febcf823bcd33 +U dan +Z 9391b61c89a105fa8d99de95f920a23b diff --git a/manifest.uuid b/manifest.uuid index f309668697..86876cd341 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f6e956525b03fa07190e5521edac4758c386cc80 \ No newline at end of file +3bd85fa5a9a489fd505c973e37c33a76c1b0e957 \ No newline at end of file From 273bfe9f204415a222ece75889dca8c1c17fb8af Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 2 Jun 2016 16:22:53 +0000 Subject: [PATCH 0488/1484] Fix corner cases in the WITHOUT ROWID virtual table logic. FossilOrigin-Name: a393bbb972660c1ffcdda923d0f3564ecfcd2f0a --- manifest | 17 +++++++---------- manifest.uuid | 2 +- src/build.c | 8 ++++---- src/vtab.c | 11 +++++++++-- 4 files changed, 21 insertions(+), 17 deletions(-) diff --git a/manifest b/manifest index d3f3735698..3c0483e6d0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C An\sexperimental\sbranch\swith\scode\sthat\sallows\svirtual\stables\sto\sbe\sdeclared\nas\sWITHOUT\sROWID\stables.\sThis\smight\sbe\suseful\sfor\svirtual\stables\sthat\smodel\nexternal\sdata\ssources\sthat\sdo\snot\shave\sa\sconvenient\sway\sof\scomputing\sa\sunique\nrowid.\s\sThe\scurrent\scheck-in\salmost\sworks,\sbut\sthere\sare\sstill\sserious\sissues. -D 2016-05-31T21:18:15.834 +C Fix\scorner\scases\sin\sthe\sWITHOUT\sROWID\svirtual\stable\slogic. +D 2016-06-02T16:22:53.508 F Makefile.in f59e0763ff448719fc1bd25513882b0567286317 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7 @@ -328,7 +328,7 @@ F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 F src/btree.c 2128172fc1c420a6fa6878827fa595407795069a F src/btree.h 1342a9b2cc2089e3534d3ef00204786783f6aea6 F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 -F src/build.c 7acc29d0944bd9995864148286e9daeb0cbce742 +F src/build.c 555b459d1f25fba6c56266e60bbbdc93bdf5f66a F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 999a828425b35b8092a8cde25690e71c20906344 @@ -456,7 +456,7 @@ F src/vdbeblob.c c9f2f494b911c6fa34efd9803f0a10807da80f77 F src/vdbemem.c 5cfef60e60e19cab6275d1b975bf4c791d575beb F src/vdbesort.c 91fda3909326860382b0ca8aa251e609c6a9d62c F src/vdbetrace.c f75c5455d8cf389ef86a8bfdfd3177e0e3692484 -F src/vtab.c 694e444986746b7e3bb9bd3d74e3284dd7209990 +F src/vtab.c a80b4e40ed8687daa3303e970d938b1f613a3eeb F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 02eeecc265f6ffd0597378f5d8ae9070b62a406a F src/wal.h 2f7c831cf3b071fa548bf2d5cac640846a7ff19c @@ -1497,10 +1497,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 28ebeadd6a4c9ff2ce9fc86a0f0fe2f6cf94d3ac -R f4a0fccb57a153a0ab74e7b69ae020b2 -T *branch * without-rowid-vtab -T *sym-without-rowid-vtab * -T -sym-trunk * +P 49638f180e26477974cacc69b79e0be0a5e18b29 +R cf24c2970498f36ff11e1ac85a33493a U drh -Z 938f365203a268d591e6d60732902516 +Z 5a84619c2e2d24987b3ea5aba48efb6c diff --git a/manifest.uuid b/manifest.uuid index 06965e9c56..154b8a6067 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -49638f180e26477974cacc69b79e0be0a5e18b29 \ No newline at end of file +a393bbb972660c1ffcdda923d0f3564ecfcd2f0a \ No newline at end of file diff --git a/src/build.c b/src/build.c index 5afc32bd5e..092a9973b3 100644 --- a/src/build.c +++ b/src/build.c @@ -607,9 +607,7 @@ static void SQLITE_NOINLINE deleteTable(sqlite3 *db, Table *pTable){ pNext = pIndex->pNext; assert( pIndex->pSchema==pTable->pSchema || (IsVirtual(pTable) && pIndex->idxType!=SQLITE_IDXTYPE_APPDEF) ); - if( pIndex->idxType==SQLITE_IDXTYPE_APPDEF - && (!db || db->pnBytesFreed==0) - ){ + if( (db==0 || db->pnBytesFreed==0) && !IsVirtual(pTable) ){ char *zName = pIndex->zName; TESTONLY ( Index *pOld = ) sqlite3HashInsert( &pIndex->pSchema->idxHash, zName, 0 @@ -1718,6 +1716,7 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){ assert( pParse->pNewTable==pTab ); sqlite3CreateIndex(pParse, 0, 0, 0, pList, pTab->keyConf, 0, 0, 0, 0, SQLITE_IDXTYPE_PRIMARYKEY); + if( db->mallocFailed ) return; pPk = sqlite3PrimaryKeyIndex(pTab); pTab->iPKey = -1; }else{ @@ -3278,6 +3277,7 @@ void sqlite3CreateIndex( pIdx->onError = pIndex->onError; } } + if( idxType==SQLITE_IDXTYPE_PRIMARYKEY ) pIdx->idxType = idxType; goto exit_create_index; } } @@ -3287,7 +3287,7 @@ void sqlite3CreateIndex( ** in-memory database structures. */ assert( pParse->nErr==0 ); - if( db->init.busy ){ + if( db->init.busy && !IN_DECLARE_VTAB ){ Index *p; assert( sqlite3SchemaMutexHeld(db, 0, pIndex->pSchema) ); p = sqlite3HashInsert(&pIndex->pSchema->idxHash, diff --git a/src/vtab.c b/src/vtab.c index 01ea9750f5..b4268536a0 100644 --- a/src/vtab.c +++ b/src/vtab.c @@ -755,13 +755,20 @@ int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){ ){ if( !pTab->aCol ){ Table *pNew = pParse->pNewTable; + Index *pIdx; pTab->aCol = pNew->aCol; pTab->nCol = pNew->nCol; pTab->tabFlags |= pNew->tabFlags & TF_WithoutRowid; - pTab->pIndex = pNew->pIndex; pNew->nCol = 0; pNew->aCol = 0; - pNew->pIndex = 0; + assert( pTab->pIndex==0 ); + pIdx = pNew->pIndex; + if( pIdx ){ + assert( pIdx->pNext==0 ); + pTab->pIndex = pIdx; + pNew->pIndex = 0; + pIdx->pTable = pTab; + } } pCtx->bDeclared = 1; }else{ From adcba64df4f5475e62146f483d53b6d687ef7103 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 2 Jun 2016 17:44:24 +0000 Subject: [PATCH 0489/1484] Add the data= parameter to the CSV virtual table extension. FossilOrigin-Name: 769191042aa14e6eccdfe2391fc1011171d5c9ad --- ext/misc/csv.c | 214 ++++++++++++++++++++++++++++++++++++------------- manifest | 12 +-- manifest.uuid | 2 +- 3 files changed, 165 insertions(+), 63 deletions(-) diff --git a/ext/misc/csv.c b/ext/misc/csv.c index 81a1d9ff63..1b19631772 100644 --- a/ext/misc/csv.c +++ b/ext/misc/csv.c @@ -53,6 +53,9 @@ SQLITE_EXTENSION_INIT1 /* Max size of the error message in a CsvReader */ #define CSV_MXERR 200 +/* Size of the CsvReader input buffer */ +#define CSV_INBUFSZ 1024 + /* A context object used when read a CSV file. */ typedef struct CsvReader CsvReader; struct CsvReader { @@ -61,18 +64,31 @@ struct CsvReader { int n; /* Number of bytes in z */ int nAlloc; /* Space allocated for z[] */ int nLine; /* Current line number */ - int cTerm; /* Character that terminated the most recent field */ + char cTerm; /* Character that terminated the most recent field */ + size_t iIn; /* Next unread character in the input buffer */ + size_t nIn; /* Number of characters in the input buffer */ + char *zIn; /* The input buffer */ char zErr[CSV_MXERR]; /* Error message */ }; /* Initialize a CsvReader object */ static void csv_reader_init(CsvReader *p){ - memset(p, 0, sizeof(*p)); + p->in = 0; + p->z = 0; + p->n = 0; + p->nAlloc = 0; + p->nLine = 0; + p->nIn = 0; + p->zIn = 0; + p->zErr[0] = 0; } /* Close and reset a CsvReader object */ static void csv_reader_reset(CsvReader *p){ - if( p->in ) fclose(p->in); + if( p->in ){ + fclose(p->in); + sqlite3_free(p->zIn); + } sqlite3_free(p->z); csv_reader_init(p); } @@ -88,15 +104,56 @@ static void csv_errmsg(CsvReader *p, const char *zFormat, ...){ /* Open the file associated with a CsvReader ** Return the number of errors. */ -static int csv_reader_open(CsvReader *p, const char *zFilename){ - p->in = fopen(zFilename, "rb"); - if( p->in==0 ){ - csv_errmsg(p, "cannot open '%s' for reading", zFilename); - return 1; +static int csv_reader_open( + CsvReader *p, /* The reader to open */ + const char *zFilename, /* Read from this filename */ + const char *zData /* ... or use this data */ +){ + if( zFilename ){ + p->zIn = sqlite3_malloc( CSV_INBUFSZ ); + if( p->zIn==0 ){ + csv_errmsg(p, "out of memory"); + return 1; + } + p->in = fopen(zFilename, "rb"); + if( p->in==0 ){ + csv_reader_reset(p); + csv_errmsg(p, "cannot open '%s' for reading", zFilename); + return 1; + } + }else{ + assert( p->in==0 ); + p->zIn = (char*)zData; + p->nIn = strlen(zData); } return 0; } +/* The input buffer has overflowed. Refill the input buffer, then +** return the next character +*/ +static CSV_NOINLINE int csv_getc_refill(CsvReader *p){ + size_t got; + + assert( p->iIn>=p->nIn ); /* Only called on an empty input buffer */ + assert( p->in!=0 ); /* Only called if reading froma file */ + + got = fread(p->zIn, 1, CSV_INBUFSZ, p->in); + if( got==0 ) return EOF; + p->nIn = got; + p->iIn = 1; + return p->zIn[0]; +} + +/* Return the next character of input. Return EOF at end of input. */ +static int csv_getc(CsvReader *p){ + if( p->iIn >= p->nIn ){ + if( p->in!=0 ) return csv_getc_refill(p); + return EOF; + } + return p->zIn[p->iIn++]; +} + /* Increase the size of p->z and append character c to the end. ** Return 0 on success and non-zero if there is an OOM error */ static CSV_NOINLINE int csv_resize_and_append(CsvReader *p, char c){ @@ -137,7 +194,7 @@ static int csv_append(CsvReader *p, char c){ static char *csv_read_one_field(CsvReader *p){ int c; p->n = 0; - c = fgetc(p->in); + c = csv_getc(p); if( c==EOF ){ p->cTerm = EOF; return ""; @@ -148,7 +205,7 @@ static char *csv_read_one_field(CsvReader *p){ int cQuote = c; pc = ppc = 0; while( 1 ){ - c = fgetc(p->in); + c = csv_getc(p); if( c=='\n' ) p->nLine++; if( c==cQuote ){ if( pc==cQuote ){ @@ -182,7 +239,7 @@ static char *csv_read_one_field(CsvReader *p){ }else{ while( c!=EOF && c!=',' && c!='\n' ){ if( csv_append(p, (char)c) ) return 0; - c = fgetc(p->in); + c = csv_getc(p); } if( c=='\n' ){ p->nLine++; @@ -216,6 +273,7 @@ static int csvtabRowid(sqlite3_vtab_cursor*,sqlite3_int64*); typedef struct CsvTable { sqlite3_vtab base; /* Base class. Must be first */ char *zFilename; /* Name of the CSV file */ + char *zData; /* Raw CSV data in lieu of zFilename */ long iStart; /* Offset to start of data in zFilename */ int nCol; /* Number of columns in the CSV file */ unsigned int tstFlags; /* Bit values used for testing */ @@ -290,6 +348,37 @@ static const char *csv_parameter(const char *zTag, int nTag, const char *z){ return csv_skip_whitespace(z+1); } +/* Decode a parameter that requires a dequoted string. +** +** Return 1 if the parameter is seen, or 0 if not. 1 is returned +** even if there is an error. If an error occurs, then an error message +** is left in p->zErr. If there are no errors, p->zErr[0]==0. +*/ +static int csv_string_parameter( + CsvReader *p, /* Leave the error message here, if there is one */ + const char *zParam, /* Parameter we are checking for */ + const char *zArg, /* Raw text of the virtual table argment */ + char **pzVal /* Write the dequoted string value here */ +){ + const char *zValue; + zValue = csv_parameter(zParam,strlen(zParam),zArg); + if( zValue==0 ) return 0; + p->zErr[0] = 0; + if( *pzVal ){ + csv_errmsg(p, "more than one '%s' parameter", zParam); + return 1; + } + *pzVal = sqlite3_mprintf("%s", zValue); + if( *pzVal==0 ){ + csv_errmsg(p, "out of memory"); + return 1; + } + csv_trim_whitespace(*pzVal); + csv_dequote(*pzVal); + return 1; +} + + /* Return 0 if the argument is false and 1 if it is true. Return -1 if ** we cannot really tell. */ @@ -314,11 +403,12 @@ static int csv_boolean(const char *z){ /* ** Parameters: -** filename=FILENAME Required +** filename=FILENAME Name of file containing CSV content +** data=TEXT Direct CSV content. ** schema=SCHEMA Alternative CSV schema. ** header=YES|NO First row of CSV defines the names of ** columns if "yes". Default "no". -** columns=N Assum the CSV file contains N columns. +** columns=N Assume the CSV file contains N columns. ** testflags=N Bitmask of test flags. Optional ** ** If schema= is omitted, then the columns are named "c0", "c1", "c2", @@ -336,37 +426,31 @@ static int csvtabConnect( CsvTable *pNew = 0; /* The CsvTable object to construct */ int bHeader = -1; /* header= flags. -1 means not seen yet */ int rc = SQLITE_OK; /* Result code from this routine */ - int i; /* Loop counter */ - char *zFilename = 0; /* Value of the filename= parameter */ - char *zSchema = 0; /* Value of the schema= parameter */ - int tstFlags = 0; /* Value of the testflags= parameter */ + int i, j; /* Loop counters */ + int tstFlags = 0; /* Value for testflags=N parameter */ int nCol = -99; /* Value of the columns= parameter */ CsvReader sRdr; /* A CSV file reader used to store an error ** message and/or to count the number of columns */ + static const char *azParam[] = { + "filename", "data", "schema", + }; + char *azPValue[3]; /* Parameter values */ +# define CSV_FILENAME (azPValue[0]) +# define CSV_DATA (azPValue[1]) +# define CSV_SCHEMA (azPValue[2]) + + assert( sizeof(azPValue)==sizeof(azParam) ); memset(&sRdr, 0, sizeof(sRdr)); + memset(azPValue, 0, sizeof(azPValue)); for(i=3; inCol++; }while( sRdr.cTerm==',' ); } - pNew->zFilename = zFilename; + pNew->zFilename = CSV_FILENAME; CSV_FILENAME = 0; + pNew->zData = CSV_DATA; CSV_DATA = 0; pNew->tstFlags = tstFlags; - zFilename = 0; pNew->iStart = bHeader==1 ? ftell(sRdr.in) : 0; csv_reader_reset(&sRdr); - if( zSchema==0 ){ + if( CSV_SCHEMA==0 ){ char *zSep = ""; - zSchema = sqlite3_mprintf("CREATE TABLE x("); - if( zSchema==0 ) goto csvtab_connect_oom; + CSV_SCHEMA = sqlite3_mprintf("CREATE TABLE x("); + if( CSV_SCHEMA==0 ) goto csvtab_connect_oom; for(i=0; inCol; i++){ - zSchema = sqlite3_mprintf("%z%sc%d TEXT",zSchema, zSep, i); + CSV_SCHEMA = sqlite3_mprintf("%z%sc%d TEXT",CSV_SCHEMA, zSep, i); zSep = ","; } - zSchema = sqlite3_mprintf("%z);", zSchema); + CSV_SCHEMA = sqlite3_mprintf("%z);", CSV_SCHEMA); } - rc = sqlite3_declare_vtab(db, zSchema); + rc = sqlite3_declare_vtab(db, CSV_SCHEMA); if( rc ) goto csvtab_connect_error; - sqlite3_free(zSchema); + for(i=0; ibase); - sqlite3_free(zFilename); - sqlite3_free(zSchema); + for(i=0; inCol ); pCur->azVal = (char**)&pCur[1]; *ppCursor = &pCur->base; - if( csv_reader_open(&pCur->rdr, pTab->zFilename) ){ + if( csv_reader_open(&pCur->rdr, pTab->zFilename, pTab->zData) ){ csv_xfer_error(pTab, &pCur->rdr); return SQLITE_ERROR; } @@ -597,12 +684,20 @@ static int csvtabFilter( CsvCursor *pCur = (CsvCursor*)pVtabCursor; CsvTable *pTab = (CsvTable*)pVtabCursor->pVtab; pCur->iRowid = 0; - fseek(pCur->rdr.in, pTab->iStart, SEEK_SET); + if( pCur->rdr.in==0 ){ + assert( pCur->rdr.zIn==pTab->zData ); + assert( pTab->iStart<=pCur->rdr.nIn ); + pCur->rdr.iIn = pTab->iStart; + }else{ + fseek(pCur->rdr.in, pTab->iStart, SEEK_SET); + pCur->rdr.iIn = 0; + pCur->rdr.nIn = 0; + } return csvtabNext(pVtabCursor); } /* -** Only a forwards full table scan is supported. xBestIndex is mostly +** Only a forward full table scan is supported. xBestIndex is mostly ** a no-op. If CSVTEST_FIDX is set, then the presence of equality ** constraints lowers the estimated cost, which is fiction, but is useful ** for testing certain kinds of virtual table behavior. @@ -618,10 +713,17 @@ static int csvtabBestIndex( if( (pTab->tstFlags & CSVTEST_FIDX)==0 ){ return SQLITE_OK; } - /* The usual (an sensible) case is to take the "return SQLITE_OK" above. - ** The code below only runs when testflags=1. The following code + /* The usual (and sensible) case is to take the "return SQLITE_OK" above. + ** The code below only runs when testflags=1. The code below ** generates an artifical and unrealistic plan which is useful - ** for testing virtual table logic but is useless for real applications. */ + ** for testing virtual table logic but is not helpfulto real applications. + ** + ** Any ==, LIKE, or GLOB constraint is marked as usable by the virtual + ** table (even though it is not) and the cost of running the virtual table + ** is reduced from 1 million to just 10. The constraints are *not* marked + ** as omittable, however, so the query planner should still generate a + ** plan that gives a correct answer, even if they plan is not optimal. + */ for(i=0; inConstraint; i++){ unsigned char op; if( pIdxInfo->aConstraint[i].usable==0 ) continue; diff --git a/manifest b/manifest index 3c0483e6d0..e986c301dd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\scorner\scases\sin\sthe\sWITHOUT\sROWID\svirtual\stable\slogic. -D 2016-06-02T16:22:53.508 +C Add\sthe\sdata=\sparameter\sto\sthe\sCSV\svirtual\stable\sextension. +D 2016-06-02T17:44:24.492 F Makefile.in f59e0763ff448719fc1bd25513882b0567286317 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7 @@ -206,7 +206,7 @@ F ext/icu/sqliteicu.h 728867a802baa5a96de7495e9689a8e01715ef37 F ext/misc/amatch.c 211108e201105e4bb0c076527b8cfd34330fc234 F ext/misc/closure.c 0d2a038df8fbae7f19de42e7c7d71f2e4dc88704 F ext/misc/compress.c 122faa92d25033d6c3f07c39231de074ab3d2e83 -F ext/misc/csv.c 39060a352f43e43df575484cc0f23ab61091dac3 +F ext/misc/csv.c d4f6f0776bcaaed7929d6ef1e1261287b856e0da F ext/misc/eval.c f971962e92ebb8b0a4e6b62949463ee454d88fa2 F ext/misc/fileio.c d4171c815d6543a9edef8308aab2951413cd8d0f F ext/misc/fuzzer.c 7c64b8197bb77b7d64eff7cac7848870235d4c25 @@ -1497,7 +1497,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 49638f180e26477974cacc69b79e0be0a5e18b29 -R cf24c2970498f36ff11e1ac85a33493a +P a393bbb972660c1ffcdda923d0f3564ecfcd2f0a +R 47b04ec69529b5020af652ca946943fd U drh -Z 5a84619c2e2d24987b3ea5aba48efb6c +Z ea4616a356c99262b96b6fda702a53cc diff --git a/manifest.uuid b/manifest.uuid index 154b8a6067..61b0d4ac01 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a393bbb972660c1ffcdda923d0f3564ecfcd2f0a \ No newline at end of file +769191042aa14e6eccdfe2391fc1011171d5c9ad \ No newline at end of file From 35db31b24b3ec27f741da5c8916c5e9dadee4727 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 2 Jun 2016 23:13:21 +0000 Subject: [PATCH 0490/1484] Add the CSV extension to the test fixture. Fix a memory leak in the CSV extension. Add test cases for the CSV extension, including one that uses a WITHOUT ROWID virtual table participating in the OR optimization. FossilOrigin-Name: 95f483e86e30ae68108904400e18ed41d389446b --- Makefile.in | 1 + Makefile.msc | 1 + ext/misc/csv.c | 1 + main.mk | 1 + manifest | 23 +++++++------ manifest.uuid | 2 +- src/expr.c | 2 +- src/test1.c | 2 ++ test/csv01.test | 91 +++++++++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 111 insertions(+), 13 deletions(-) create mode 100644 test/csv01.test diff --git a/Makefile.in b/Makefile.in index 4e10d4e231..115cfac58f 100644 --- a/Makefile.in +++ b/Makefile.in @@ -417,6 +417,7 @@ TESTSRC = \ TESTSRC += \ $(TOP)/ext/misc/amatch.c \ $(TOP)/ext/misc/closure.c \ + $(TOP)/ext/misc/csv.c \ $(TOP)/ext/misc/eval.c \ $(TOP)/ext/misc/fileio.c \ $(TOP)/ext/misc/fuzzer.c \ diff --git a/Makefile.msc b/Makefile.msc index 408a516364..9bf1e4f8fe 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -1293,6 +1293,7 @@ TESTSRC = \ TESTEXT = \ $(TOP)\ext\misc\amatch.c \ $(TOP)\ext\misc\closure.c \ + $(TOP)\ext\misc\csv.c \ $(TOP)\ext\misc\eval.c \ $(TOP)\ext\misc\fileio.c \ $(TOP)\ext\misc\fuzzer.c \ diff --git a/ext/misc/csv.c b/ext/misc/csv.c index 1b19631772..343c866c95 100644 --- a/ext/misc/csv.c +++ b/ext/misc/csv.c @@ -302,6 +302,7 @@ static void csv_xfer_error(CsvTable *pTab, CsvReader *pRdr){ static int csvtabDisconnect(sqlite3_vtab *pVtab){ CsvTable *p = (CsvTable*)pVtab; sqlite3_free(p->zFilename); + sqlite3_free(p->zData); sqlite3_free(p); return SQLITE_OK; } diff --git a/main.mk b/main.mk index e193729b8a..624bf77a06 100644 --- a/main.mk +++ b/main.mk @@ -325,6 +325,7 @@ TESTSRC = \ TESTSRC += \ $(TOP)/ext/misc/amatch.c \ $(TOP)/ext/misc/closure.c \ + $(TOP)/ext/misc/csv.c \ $(TOP)/ext/misc/eval.c \ $(TOP)/ext/misc/fileio.c \ $(TOP)/ext/misc/fuzzer.c \ diff --git a/manifest b/manifest index e986c301dd..2da7d447f7 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -C Add\sthe\sdata=\sparameter\sto\sthe\sCSV\svirtual\stable\sextension. -D 2016-06-02T17:44:24.492 -F Makefile.in f59e0763ff448719fc1bd25513882b0567286317 +C Add\sthe\sCSV\sextension\sto\sthe\stest\sfixture.\s\sFix\sa\smemory\sleak\sin\sthe\sCSV\nextension.\s\sAdd\stest\scases\sfor\sthe\sCSV\sextension,\sincluding\sone\sthat\suses\na\sWITHOUT\sROWID\svirtual\stable\sparticipating\sin\sthe\sOR\soptimization. +D 2016-06-02T23:13:21.510 +F Makefile.in 7321ef0b584224781ec7731408857fa8962c32cc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 -F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7 +F Makefile.msc 831503fc4e988f571590af1405645fff121b5f1e F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7 F VERSION cb29eb11e493dd85b3eeec4053c03949bf98478e F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 @@ -206,7 +206,7 @@ F ext/icu/sqliteicu.h 728867a802baa5a96de7495e9689a8e01715ef37 F ext/misc/amatch.c 211108e201105e4bb0c076527b8cfd34330fc234 F ext/misc/closure.c 0d2a038df8fbae7f19de42e7c7d71f2e4dc88704 F ext/misc/compress.c 122faa92d25033d6c3f07c39231de074ab3d2e83 -F ext/misc/csv.c d4f6f0776bcaaed7929d6ef1e1261287b856e0da +F ext/misc/csv.c 58ad4e9eb25310a2712e0cb78592dc15924f0379 F ext/misc/eval.c f971962e92ebb8b0a4e6b62949463ee454d88fa2 F ext/misc/fileio.c d4171c815d6543a9edef8308aab2951413cd8d0f F ext/misc/fuzzer.c 7c64b8197bb77b7d64eff7cac7848870235d4c25 @@ -306,7 +306,7 @@ F ext/userauth/userauth.c 5fa3bdb492f481bbc1709fc83c91ebd13460c69e F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60 -F main.mk eab7db27ac2a32b1172a85aa850c0b9c3a00524c +F main.mk 2b90646ca027cc21dbae209a0fee68dfedfe0e83 F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 @@ -335,7 +335,7 @@ F src/ctime.c 999a828425b35b8092a8cde25690e71c20906344 F src/date.c 1cc9fb516ec9932c6fd4d2a0d2f8bc4480145c39 F src/dbstat.c c845548d4346e606e2f2b7d2e714ace2b8a7dd1b F src/delete.c 4aba4214a377ce8ddde2d2e609777bcc8235200f -F src/expr.c 81bd7d87985746313770211183e900ed1ad28381 +F src/expr.c 798146ea4c87d723e8a157d88450ac9c43256998 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 4c0bd09e602b8ae8d36d81e31e4872d0b53c87bb F src/func.c ef4c18c8a66143413ce41a58d582d2c14ddf78e1 @@ -391,7 +391,7 @@ F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 F src/tclsqlite.c 9c4c4589d078de37813ded708d8838b338ffb060 -F src/test1.c c0e5b69f99e95a2c9f55fdb6e46b44f1a15292d8 +F src/test1.c 43b37ab2b7338fd3313e74902f0d6c821eae843b F src/test2.c 5586f43fcd9a1be0830793cf9d354082c261b25b F src/test3.c d2c9efd2985ff8f5502ffd3253156984778d77d8 F src/test4.c d168f83cc78d02e8d35567bb5630e40dcd85ac1e @@ -612,6 +612,7 @@ F test/crashM.test d95f59046fa749b0d0822edf18a717788c8f318d F test/crashtest1.c 09c1c7d728ccf4feb9e481671e29dda5669bbcc2 F test/createtab.test b5de160630b209c4b8925bdcbbaf48cc90b67fe8 F test/cse.test 277350a26264495e86b1785f34d2d0c8600e021c +F test/csv01.test 44a9786f6cb4dcf40f3d5d59844dbb88d2265e5d F test/ctime.test 7bd009071e242aac4f18521581536b652b789a47 F test/cursorhint.test 7bc346788390475e77a345da2b92270d04d35856 F test/date.test 984ac1e3e5e031386866f034006148d3972b4a65 @@ -1497,7 +1498,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a393bbb972660c1ffcdda923d0f3564ecfcd2f0a -R 47b04ec69529b5020af652ca946943fd +P 769191042aa14e6eccdfe2391fc1011171d5c9ad +R 7cb009be35227902926fe0d852282f91 U drh -Z ea4616a356c99262b96b6fda702a53cc +Z 7f2a8b3dbd34984ea991a68c56b4587b diff --git a/manifest.uuid b/manifest.uuid index 61b0d4ac01..816aa44fdf 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -769191042aa14e6eccdfe2391fc1011171d5c9ad \ No newline at end of file +95f483e86e30ae68108904400e18ed41d389446b \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 156db96fa1..c6a09d9d9d 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2535,7 +2535,7 @@ void sqlite3ExprCodeGetColumnOfTable( }else{ int op = IsVirtual(pTab) ? OP_VColumn : OP_Column; int x = iCol; - if( !HasRowid(pTab) ){ + if( !HasRowid(pTab) && !IsVirtual(pTab) ){ x = sqlite3ColumnOfIndex(sqlite3PrimaryKeyIndex(pTab), iCol); } sqlite3VdbeAddOp3(v, op, iTabCur, x, regOut); diff --git a/src/test1.c b/src/test1.c index ee71b854b9..0f16d62d85 100644 --- a/src/test1.c +++ b/src/test1.c @@ -6584,6 +6584,7 @@ static int tclLoadStaticExtensionCmd( ){ extern int sqlite3_amatch_init(sqlite3*,char**,const sqlite3_api_routines*); extern int sqlite3_closure_init(sqlite3*,char**,const sqlite3_api_routines*); + extern int sqlite3_csv_init(sqlite3*,char**,const sqlite3_api_routines*); extern int sqlite3_eval_init(sqlite3*,char**,const sqlite3_api_routines*); extern int sqlite3_fileio_init(sqlite3*,char**,const sqlite3_api_routines*); extern int sqlite3_fuzzer_init(sqlite3*,char**,const sqlite3_api_routines*); @@ -6601,6 +6602,7 @@ static int tclLoadStaticExtensionCmd( } aExtension[] = { { "amatch", sqlite3_amatch_init }, { "closure", sqlite3_closure_init }, + { "csv", sqlite3_csv_init }, { "eval", sqlite3_eval_init }, { "fileio", sqlite3_fileio_init }, { "fuzzer", sqlite3_fuzzer_init }, diff --git a/test/csv01.test b/test/csv01.test new file mode 100644 index 0000000000..aaec857992 --- /dev/null +++ b/test/csv01.test @@ -0,0 +1,91 @@ +# 2016-06-02 +# +# 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. +# +#*********************************************************************** +# +# Test cases for CSV virtual table. + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix closure01 + +ifcapable !vtab||!cte { finish_test ; return } + +load_static_extension db csv + +do_execsql_test 1.0 { + CREATE VIRTUAL TABLE temp.t1 USING csv( + data= +'1,2,3,4 +5,6,7,8 +9,10,11,12 +13,14,15,16 +', + columns=4 + ); + SELECT * FROM t1 WHERE c1=10; +} {9 10 11 12} +do_execsql_test 1.1 { + SELECT * FROM t1 WHERE c1='10'; +} {9 10 11 12} +do_execsql_test 1.2 { + SELECT rowid FROM t1; +} {1 2 3 4} + +do_execsql_test 2.0 { + DROP TABLE t1; + CREATE VIRTUAL TABLE temp.t2 USING csv( + data= +'1,2,3,4 +5,6,7,8 +9,10,11,12 +13,14,15,16 +', + columns=4, + schema='CREATE TABLE t2(a INT, b TEXT, c REAL, d BLOB)' + ); + SELECT * FROM t2 WHERE a=9; +} {9 10 11 12} +do_execsql_test 2.1 { + SELECT * FROM t2 WHERE b=10; +} {9 10 11 12} +do_execsql_test 2.2 { + SELECT * FROM t2 WHERE c=11; +} {9 10 11 12} +do_execsql_test 2.3 { + SELECT * FROM t2 WHERE d=12; +} {} +do_execsql_test 2.4 { + SELECT * FROM t2 WHERE d='12'; +} {9 10 11 12} +do_execsql_test 2.5 { + SELECT * FROM t2 WHERE a='9'; +} {9 10 11 12} + +do_execsql_test 3.0 { + DROP TABLE t2; + CREATE VIRTUAL TABLE temp.t3 USING csv( + data= +'1,2,3,4 +5,6,7,8 +9,10,11,12 +13,14,15,16 +', + columns=4, + schema= + 'CREATE TABLE t3(a PRIMARY KEY,b TEXT,c TEXT,d TEXT) WITHOUT ROWID', + testflags=1 + ); + SELECT a FROM t3 WHERE b=6 OR c=7 OR d=12 ORDER BY +a; +} {5 9} +do_execsql_test 3.1 { + SELECT a FROM t3 WHERE +b=6 OR c=7 OR d=12 ORDER BY +a; +} {5 9} + +finish_test From ac9c3d2c1805e7266fe53b9dcb4d75a22fec0335 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 3 Jun 2016 01:01:57 +0000 Subject: [PATCH 0491/1484] Performance optimizations on the CSV virtual table. Disallow WITHOUT ROWID virtual tables that have an xUpdate method, for now. FossilOrigin-Name: 3134b3266c36c9d018e8d365ef46ef638c0792f4 --- ext/misc/csv.c | 210 +++++++++++++++++++++++++++++++++--------------- manifest | 16 ++-- manifest.uuid | 2 +- src/vtab.c | 3 + test/csv01.test | 16 ++++ 5 files changed, 172 insertions(+), 75 deletions(-) diff --git a/ext/misc/csv.c b/ext/misc/csv.c index 343c866c95..c0d8ecd3fc 100644 --- a/ext/misc/csv.c +++ b/ext/misc/csv.c @@ -27,6 +27,17 @@ ** filename = "../http.log", ** schema = "CREATE TABLE x(date,ipaddr,url,referrer,userAgent)" ** ); +** +** Instead of specifying a file, the text of the CSV can be loaded using +** the data= parameter. +** +** If the columns=N parameter is supplied, then the CSV file is assumed to have +** N columns. If the columns parameter is omitted, the CSV file is opened +** as soon as the virtual table is constructed and the first row of the CSV +** is read in order to count the tables. +** +** Some extra debugging features (used for testing virtual tables) are available +** if this module is compiled with -DSQLITE_TEST. */ #include SQLITE_EXTENSION_INIT1 @@ -202,42 +213,43 @@ static char *csv_read_one_field(CsvReader *p){ if( c=='"' ){ int pc, ppc; int startLine = p->nLine; - int cQuote = c; pc = ppc = 0; while( 1 ){ c = csv_getc(p); - if( c=='\n' ) p->nLine++; - if( c==cQuote ){ - if( pc==cQuote ){ - pc = 0; - continue; + if( c<='"' || pc=='"' ){ + if( c=='\n' ) p->nLine++; + if( c=='"' ){ + if( pc=='"' ){ + pc = 0; + continue; + } + } + if( (c==',' && pc=='"') + || (c=='\n' && pc=='"') + || (c=='\n' && pc=='\r' && ppc=='"') + || (c==EOF && pc=='"') + ){ + do{ p->n--; }while( p->z[p->n]!='"' ); + p->cTerm = c; + break; + } + if( pc=='"' && c!='\r' ){ + csv_errmsg(p, "line %d: unescaped %c character", p->nLine, '"'); + break; + } + if( c==EOF ){ + csv_errmsg(p, "line %d: unterminated %c-quoted field\n", + startLine, '"'); + p->cTerm = c; + break; } - } - if( (c==',' && pc==cQuote) - || (c=='\n' && pc==cQuote) - || (c=='\n' && pc=='\r' && ppc==cQuote) - || (c==EOF && pc==cQuote) - ){ - do{ p->n--; }while( p->z[p->n]!=cQuote ); - p->cTerm = c; - break; - } - if( pc==cQuote && c!='\r' ){ - csv_errmsg(p, "line %d: unescaped %c character", p->nLine, cQuote); - break; - } - if( c==EOF ){ - csv_errmsg(p, "line %d: unterminated %c-quoted field\n", - startLine, cQuote); - p->cTerm = c; - break; } if( csv_append(p, (char)c) ) return 0; ppc = pc; pc = c; } }else{ - while( c!=EOF && c!=',' && c!='\n' ){ + while( c>',' || (c!=EOF && c!=',' && c!='\n') ){ if( csv_append(p, (char)c) ) return 0; c = csv_getc(p); } @@ -287,6 +299,7 @@ typedef struct CsvCursor { sqlite3_vtab_cursor base; /* Base class. Must be first */ CsvReader rdr; /* The CsvReader object */ char **azVal; /* Value of the current row */ + int *aLen; /* Length of each entry */ sqlite3_int64 iRowid; /* The current rowid. Negative for EOF */ } CsvCursor; @@ -410,6 +423,9 @@ static int csv_boolean(const char *z){ ** header=YES|NO First row of CSV defines the names of ** columns if "yes". Default "no". ** columns=N Assume the CSV file contains N columns. +** +** Only available if compiled with SQLITE_TEST: +** ** testflags=N Bitmask of test flags. Optional ** ** If schema= is omitted, then the columns are named "c0", "c1", "c2", @@ -428,7 +444,9 @@ static int csvtabConnect( int bHeader = -1; /* header= flags. -1 means not seen yet */ int rc = SQLITE_OK; /* Result code from this routine */ int i, j; /* Loop counters */ +#ifdef SQLITE_TEST int tstFlags = 0; /* Value for testflags=N parameter */ +#endif int nCol = -99; /* Value of the columns= parameter */ CsvReader sRdr; /* A CSV file reader used to store an error ** message and/or to count the number of columns */ @@ -469,9 +487,11 @@ static int csvtabConnect( goto csvtab_connect_error; } }else +#ifdef SQLITE_TEST if( (zValue = csv_parameter("testflags",9,z))!=0 ){ tstFlags = (unsigned int)atoi(zValue); }else +#endif if( (zValue = csv_parameter("columns",7,z))!=0 ){ if( nCol>0 ){ csv_errmsg(&sRdr, "more than one 'columns' parameter"); @@ -510,7 +530,9 @@ static int csvtabConnect( } pNew->zFilename = CSV_FILENAME; CSV_FILENAME = 0; pNew->zData = CSV_DATA; CSV_DATA = 0; +#ifdef SQLITE_TEST pNew->tstFlags = tstFlags; +#endif pNew->iStart = bHeader==1 ? ftell(sRdr.in) : 0; csv_reader_reset(&sRdr); if( CSV_SCHEMA==0 ){ @@ -557,6 +579,7 @@ static void csvtabCursorRowReset(CsvCursor *pCur){ for(i=0; inCol; i++){ sqlite3_free(pCur->azVal[i]); pCur->azVal[i] = 0; + pCur->aLen[i] = 0; } } @@ -591,10 +614,13 @@ static int csvtabClose(sqlite3_vtab_cursor *cur){ static int csvtabOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){ CsvTable *pTab = (CsvTable*)p; CsvCursor *pCur; - pCur = sqlite3_malloc( sizeof(*pCur) * sizeof(char*)*pTab->nCol ); + size_t nByte; + nByte = sizeof(*pCur) + (sizeof(char*)+sizeof(int))*pTab->nCol; + pCur = sqlite3_malloc( nByte ); if( pCur==0 ) return SQLITE_NOMEM; - memset(pCur, 0, sizeof(*pCur) + sizeof(char*)*pTab->nCol ); + memset(pCur, 0, nByte); pCur->azVal = (char**)&pCur[1]; + pCur->aLen = (int*)&pCur->azVal[pTab->nCol]; *ppCursor = &pCur->base; if( csv_reader_open(&pCur->rdr, pTab->zFilename, pTab->zData) ){ csv_xfer_error(pTab, &pCur->rdr); @@ -613,23 +639,33 @@ static int csvtabNext(sqlite3_vtab_cursor *cur){ CsvTable *pTab = (CsvTable*)cur->pVtab; int i = 0; char *z; - csvtabCursorRowReset(pCur); do{ z = csv_read_one_field(&pCur->rdr); if( z==0 ){ csv_xfer_error(pTab, &pCur->rdr); break; } - z = sqlite3_mprintf("%s", z); - if( z==0 ){ - csv_errmsg(&pCur->rdr, "out of memory"); - csv_xfer_error(pTab, &pCur->rdr); - break; - } if( inCol ){ - pCur->azVal[i++] = z; + if( pCur->aLen[i] < pCur->rdr.n+1 ){ + char *zNew = sqlite3_realloc(pCur->azVal[i], pCur->rdr.n+1); + if( zNew==0 ){ + csv_errmsg(&pCur->rdr, "out of memory"); + csv_xfer_error(pTab, &pCur->rdr); + break; + } + pCur->azVal[i] = zNew; + pCur->aLen[i] = pCur->rdr.n+1; + } + memcpy(pCur->azVal[i], z, pCur->rdr.n+1); + i++; } - }while( z!=0 && pCur->rdr.cTerm==',' ); + }while( pCur->rdr.cTerm==',' ); + while( inCol ){ + sqlite3_free(pCur->azVal[i]); + pCur->azVal[i] = 0; + pCur->aLen[i] = 0; + i++; + } if( z==0 || pCur->rdr.cTerm==EOF ){ pCur->iRowid = -1; }else{ @@ -707,37 +743,37 @@ static int csvtabBestIndex( sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo ){ - CsvTable *pTab = (CsvTable*)tab; - int i; - int nConst = 0; pIdxInfo->estimatedCost = 1000000; - if( (pTab->tstFlags & CSVTEST_FIDX)==0 ){ - return SQLITE_OK; - } - /* The usual (and sensible) case is to take the "return SQLITE_OK" above. - ** The code below only runs when testflags=1. The code below - ** generates an artifical and unrealistic plan which is useful - ** for testing virtual table logic but is not helpfulto real applications. - ** - ** Any ==, LIKE, or GLOB constraint is marked as usable by the virtual - ** table (even though it is not) and the cost of running the virtual table - ** is reduced from 1 million to just 10. The constraints are *not* marked - ** as omittable, however, so the query planner should still generate a - ** plan that gives a correct answer, even if they plan is not optimal. - */ - for(i=0; inConstraint; i++){ - unsigned char op; - if( pIdxInfo->aConstraint[i].usable==0 ) continue; - op = pIdxInfo->aConstraint[i].op; - if( op==SQLITE_INDEX_CONSTRAINT_EQ - || op==SQLITE_INDEX_CONSTRAINT_LIKE - || op==SQLITE_INDEX_CONSTRAINT_GLOB - ){ - pIdxInfo->estimatedCost = 10; - pIdxInfo->aConstraintUsage[nConst].argvIndex = nConst+1; - nConst++; +#ifdef SQLITE_TEST + if( (((CsvTable*)tab)->tstFlags & CSVTEST_FIDX)!=0 ){ + /* The usual (and sensible) case is to always do a full table scan. + ** The code in this branch only runs when testflags=1. This code + ** generates an artifical and unrealistic plan which is useful + ** for testing virtual table logic but is not helpful to real applications. + ** + ** Any ==, LIKE, or GLOB constraint is marked as usable by the virtual + ** table (even though it is not) and the cost of running the virtual table + ** is reduced from 1 million to just 10. The constraints are *not* marked + ** as omittable, however, so the query planner should still generate a + ** plan that gives a correct answer, even if they plan is not optimal. + */ + int i; + int nConst = 0; + for(i=0; inConstraint; i++){ + unsigned char op; + if( pIdxInfo->aConstraint[i].usable==0 ) continue; + op = pIdxInfo->aConstraint[i].op; + if( op==SQLITE_INDEX_CONSTRAINT_EQ + || op==SQLITE_INDEX_CONSTRAINT_LIKE + || op==SQLITE_INDEX_CONSTRAINT_GLOB + ){ + pIdxInfo->estimatedCost = 10; + pIdxInfo->aConstraintUsage[nConst].argvIndex = nConst+1; + nConst++; + } } } +#endif return SQLITE_OK; } @@ -765,6 +801,41 @@ static sqlite3_module CsvModule = { 0, /* xRename */ }; +#ifdef SQLITE_TEST +/* +** For virtual table testing, make a version of the CSV virtual table +** available that has an xUpdate function. But the xUpdate always returns +** SQLITE_READONLY since the CSV file is not really writable. +*/ +static int csvtabUpdate(sqlite3_vtab *p,int n,sqlite3_value**v,sqlite3_int64*x){ + return SQLITE_READONLY; +} +static sqlite3_module CsvModuleFauxWrite = { + 0, /* iVersion */ + csvtabCreate, /* xCreate */ + csvtabConnect, /* xConnect */ + csvtabBestIndex, /* xBestIndex */ + csvtabDisconnect, /* xDisconnect */ + csvtabDisconnect, /* xDestroy */ + csvtabOpen, /* xOpen - open a cursor */ + csvtabClose, /* xClose - close a cursor */ + csvtabFilter, /* xFilter - configure scan constraints */ + csvtabNext, /* xNext - advance a cursor */ + csvtabEof, /* xEof - check for end of scan */ + csvtabColumn, /* xColumn - read data */ + csvtabRowid, /* xRowid - read data */ + csvtabUpdate, /* xUpdate */ + 0, /* xBegin */ + 0, /* xSync */ + 0, /* xCommit */ + 0, /* xRollback */ + 0, /* xFindMethod */ + 0, /* xRename */ +}; +#endif /* SQLITE_TEST */ + + + #ifdef _WIN32 __declspec(dllexport) #endif @@ -778,6 +849,13 @@ int sqlite3_csv_init( char **pzErrMsg, const sqlite3_api_routines *pApi ){ + int rc; SQLITE_EXTENSION_INIT2(pApi); - return sqlite3_create_module(db, "csv", &CsvModule, 0); + rc = sqlite3_create_module(db, "csv", &CsvModule, 0); +#ifdef SQLITE_TEST + if( rc==SQLITE_OK ){ + rc = sqlite3_create_module(db, "csv_wr", &CsvModuleFauxWrite, 0); + } +#endif + return rc; } diff --git a/manifest b/manifest index 2da7d447f7..21eb765e24 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sCSV\sextension\sto\sthe\stest\sfixture.\s\sFix\sa\smemory\sleak\sin\sthe\sCSV\nextension.\s\sAdd\stest\scases\sfor\sthe\sCSV\sextension,\sincluding\sone\sthat\suses\na\sWITHOUT\sROWID\svirtual\stable\sparticipating\sin\sthe\sOR\soptimization. -D 2016-06-02T23:13:21.510 +C Performance\soptimizations\son\sthe\sCSV\svirtual\stable.\s\sDisallow\sWITHOUT\sROWID\nvirtual\stables\sthat\shave\san\sxUpdate\smethod,\sfor\snow. +D 2016-06-03T01:01:57.592 F Makefile.in 7321ef0b584224781ec7731408857fa8962c32cc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 831503fc4e988f571590af1405645fff121b5f1e @@ -206,7 +206,7 @@ F ext/icu/sqliteicu.h 728867a802baa5a96de7495e9689a8e01715ef37 F ext/misc/amatch.c 211108e201105e4bb0c076527b8cfd34330fc234 F ext/misc/closure.c 0d2a038df8fbae7f19de42e7c7d71f2e4dc88704 F ext/misc/compress.c 122faa92d25033d6c3f07c39231de074ab3d2e83 -F ext/misc/csv.c 58ad4e9eb25310a2712e0cb78592dc15924f0379 +F ext/misc/csv.c f01126ba170fd4ef7c752b156568a80c912d4441 F ext/misc/eval.c f971962e92ebb8b0a4e6b62949463ee454d88fa2 F ext/misc/fileio.c d4171c815d6543a9edef8308aab2951413cd8d0f F ext/misc/fuzzer.c 7c64b8197bb77b7d64eff7cac7848870235d4c25 @@ -456,7 +456,7 @@ F src/vdbeblob.c c9f2f494b911c6fa34efd9803f0a10807da80f77 F src/vdbemem.c 5cfef60e60e19cab6275d1b975bf4c791d575beb F src/vdbesort.c 91fda3909326860382b0ca8aa251e609c6a9d62c F src/vdbetrace.c f75c5455d8cf389ef86a8bfdfd3177e0e3692484 -F src/vtab.c a80b4e40ed8687daa3303e970d938b1f613a3eeb +F src/vtab.c a9e8175477539660814a4704e8eaba6df3678651 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 02eeecc265f6ffd0597378f5d8ae9070b62a406a F src/wal.h 2f7c831cf3b071fa548bf2d5cac640846a7ff19c @@ -612,7 +612,7 @@ F test/crashM.test d95f59046fa749b0d0822edf18a717788c8f318d F test/crashtest1.c 09c1c7d728ccf4feb9e481671e29dda5669bbcc2 F test/createtab.test b5de160630b209c4b8925bdcbbaf48cc90b67fe8 F test/cse.test 277350a26264495e86b1785f34d2d0c8600e021c -F test/csv01.test 44a9786f6cb4dcf40f3d5d59844dbb88d2265e5d +F test/csv01.test 69aecc17f11f597390b47700aec8d748b8364140 F test/ctime.test 7bd009071e242aac4f18521581536b652b789a47 F test/cursorhint.test 7bc346788390475e77a345da2b92270d04d35856 F test/date.test 984ac1e3e5e031386866f034006148d3972b4a65 @@ -1498,7 +1498,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 769191042aa14e6eccdfe2391fc1011171d5c9ad -R 7cb009be35227902926fe0d852282f91 +P 95f483e86e30ae68108904400e18ed41d389446b +R 110a9ed97c9cb7052ae396116c46b04d U drh -Z 7f2a8b3dbd34984ea991a68c56b4587b +Z 863bf523824cd922d795a07ca8451a6d diff --git a/manifest.uuid b/manifest.uuid index 816aa44fdf..935a081c06 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -95f483e86e30ae68108904400e18ed41d389446b \ No newline at end of file +3134b3266c36c9d018e8d365ef46ef638c0792f4 \ No newline at end of file diff --git a/src/vtab.c b/src/vtab.c index b4268536a0..30cdd43e4b 100644 --- a/src/vtab.c +++ b/src/vtab.c @@ -762,6 +762,9 @@ int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){ pNew->nCol = 0; pNew->aCol = 0; assert( pTab->pIndex==0 ); + if( !HasRowid(pNew) && pCtx->pVTable->pMod->pModule->xUpdate!=0 ){ + rc = SQLITE_ERROR; + } pIdx = pNew->pIndex; if( pIdx ){ assert( pIdx->pNext==0 ); diff --git a/test/csv01.test b/test/csv01.test index aaec857992..ba3a947dfc 100644 --- a/test/csv01.test +++ b/test/csv01.test @@ -88,4 +88,20 @@ do_execsql_test 3.1 { SELECT a FROM t3 WHERE +b=6 OR c=7 OR d=12 ORDER BY +a; } {5 9} +do_catchsql_test 4.0 { + DROP TABLE t3; + CREATE VIRTUAL TABLE temp.t4 USING csv_wr( + data= +'1,2,3,4 +5,6,7,8 +9,10,11,12 +13,14,15,16 +', + columns=4, + schema= + 'CREATE TABLE t3(a PRIMARY KEY,b TEXT,c TEXT,d TEXT) WITHOUT ROWID', + testflags=1 + ); +} {1 {vtable constructor failed: t4}} + finish_test From 7edcf627af2b62cd0914cd25299d704a9751f617 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 3 Jun 2016 17:27:14 +0000 Subject: [PATCH 0492/1484] Disallow access to the rowid column on WITHOUT ROWID virtual tables. FossilOrigin-Name: d31c25972bfb6d04caad05534505698776e7e6d5 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/vtab.c | 2 +- test/csv01.test | 5 +++++ 4 files changed, 14 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 21eb765e24..14b0bedf9c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Performance\soptimizations\son\sthe\sCSV\svirtual\stable.\s\sDisallow\sWITHOUT\sROWID\nvirtual\stables\sthat\shave\san\sxUpdate\smethod,\sfor\snow. -D 2016-06-03T01:01:57.592 +C Disallow\saccess\sto\sthe\srowid\scolumn\son\sWITHOUT\sROWID\svirtual\stables. +D 2016-06-03T17:27:14.741 F Makefile.in 7321ef0b584224781ec7731408857fa8962c32cc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 831503fc4e988f571590af1405645fff121b5f1e @@ -456,7 +456,7 @@ F src/vdbeblob.c c9f2f494b911c6fa34efd9803f0a10807da80f77 F src/vdbemem.c 5cfef60e60e19cab6275d1b975bf4c791d575beb F src/vdbesort.c 91fda3909326860382b0ca8aa251e609c6a9d62c F src/vdbetrace.c f75c5455d8cf389ef86a8bfdfd3177e0e3692484 -F src/vtab.c a9e8175477539660814a4704e8eaba6df3678651 +F src/vtab.c 7a143175f5586d99f78f61b43a563caa03eb4d63 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 02eeecc265f6ffd0597378f5d8ae9070b62a406a F src/wal.h 2f7c831cf3b071fa548bf2d5cac640846a7ff19c @@ -612,7 +612,7 @@ F test/crashM.test d95f59046fa749b0d0822edf18a717788c8f318d F test/crashtest1.c 09c1c7d728ccf4feb9e481671e29dda5669bbcc2 F test/createtab.test b5de160630b209c4b8925bdcbbaf48cc90b67fe8 F test/cse.test 277350a26264495e86b1785f34d2d0c8600e021c -F test/csv01.test 69aecc17f11f597390b47700aec8d748b8364140 +F test/csv01.test 0929a9ce47021519512be92861f29e32d2538e5f F test/ctime.test 7bd009071e242aac4f18521581536b652b789a47 F test/cursorhint.test 7bc346788390475e77a345da2b92270d04d35856 F test/date.test 984ac1e3e5e031386866f034006148d3972b4a65 @@ -1498,7 +1498,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 95f483e86e30ae68108904400e18ed41d389446b -R 110a9ed97c9cb7052ae396116c46b04d +P 3134b3266c36c9d018e8d365ef46ef638c0792f4 +R 6bd90244b320ac429cd2120cdab002d9 U drh -Z 863bf523824cd922d795a07ca8451a6d +Z 5fa00a97540dd1b5ac1a6e73a3f78ebc diff --git a/manifest.uuid b/manifest.uuid index 935a081c06..0f61bc8586 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3134b3266c36c9d018e8d365ef46ef638c0792f4 \ No newline at end of file +d31c25972bfb6d04caad05534505698776e7e6d5 \ No newline at end of file diff --git a/src/vtab.c b/src/vtab.c index 30cdd43e4b..eeef64c67a 100644 --- a/src/vtab.c +++ b/src/vtab.c @@ -758,7 +758,7 @@ int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){ Index *pIdx; pTab->aCol = pNew->aCol; pTab->nCol = pNew->nCol; - pTab->tabFlags |= pNew->tabFlags & TF_WithoutRowid; + pTab->tabFlags |= pNew->tabFlags & (TF_WithoutRowid|TF_NoVisibleRowid); pNew->nCol = 0; pNew->aCol = 0; assert( pTab->pIndex==0 ); diff --git a/test/csv01.test b/test/csv01.test index ba3a947dfc..a6fff81c3f 100644 --- a/test/csv01.test +++ b/test/csv01.test @@ -88,6 +88,11 @@ do_execsql_test 3.1 { SELECT a FROM t3 WHERE +b=6 OR c=7 OR d=12 ORDER BY +a; } {5 9} +# The rowid column is not visible on a WITHOUT ROWID virtual table +do_catchsql_test 3.2 { + SELECT rowid, a FROM t3; +} {1 {no such column: rowid}} + do_catchsql_test 4.0 { DROP TABLE t3; CREATE VIRTUAL TABLE temp.t4 USING csv_wr( From 0b2c140a4d9a12784d2501cc223931a82208a161 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 3 Jun 2016 18:21:04 +0000 Subject: [PATCH 0493/1484] Fix a memory leak when a WITHOUT ROWID eponymous virtual table is used. FossilOrigin-Name: 31b83a7d7e553163eb186fc966a885f237554ec2 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/fkey.c | 3 ++- src/vtab.c | 21 ++++++++++++--------- 4 files changed, 22 insertions(+), 18 deletions(-) diff --git a/manifest b/manifest index 14b0bedf9c..b320ac31b9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Disallow\saccess\sto\sthe\srowid\scolumn\son\sWITHOUT\sROWID\svirtual\stables. -D 2016-06-03T17:27:14.741 +C Fix\sa\smemory\sleak\swhen\sa\sWITHOUT\sROWID\seponymous\svirtual\stable\sis\sused. +D 2016-06-03T18:21:04.549 F Makefile.in 7321ef0b584224781ec7731408857fa8962c32cc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 831503fc4e988f571590af1405645fff121b5f1e @@ -337,7 +337,7 @@ F src/dbstat.c c845548d4346e606e2f2b7d2e714ace2b8a7dd1b F src/delete.c 4aba4214a377ce8ddde2d2e609777bcc8235200f F src/expr.c 798146ea4c87d723e8a157d88450ac9c43256998 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb -F src/fkey.c 4c0bd09e602b8ae8d36d81e31e4872d0b53c87bb +F src/fkey.c bc4145347595b7770f9a598cff1c848302cf5413 F src/func.c ef4c18c8a66143413ce41a58d582d2c14ddf78e1 F src/global.c c45ea22aff29334f6a9ec549235ac3357c970015 F src/hash.c 55b5fb474100cee0b901edaf203e26c970940f36 @@ -456,7 +456,7 @@ F src/vdbeblob.c c9f2f494b911c6fa34efd9803f0a10807da80f77 F src/vdbemem.c 5cfef60e60e19cab6275d1b975bf4c791d575beb F src/vdbesort.c 91fda3909326860382b0ca8aa251e609c6a9d62c F src/vdbetrace.c f75c5455d8cf389ef86a8bfdfd3177e0e3692484 -F src/vtab.c 7a143175f5586d99f78f61b43a563caa03eb4d63 +F src/vtab.c 948d2d4984219eee37a7bf427d6667e21e6eb92e F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 02eeecc265f6ffd0597378f5d8ae9070b62a406a F src/wal.h 2f7c831cf3b071fa548bf2d5cac640846a7ff19c @@ -1498,7 +1498,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 3134b3266c36c9d018e8d365ef46ef638c0792f4 -R 6bd90244b320ac429cd2120cdab002d9 +P d31c25972bfb6d04caad05534505698776e7e6d5 +R 531a893078b3c566412693ad918cbea6 U drh -Z 5fa00a97540dd1b5ac1a6e73a3f78ebc +Z 4ddeb8f309e9f433c6376653796d4760 diff --git a/manifest.uuid b/manifest.uuid index 0f61bc8586..8dbe108de4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d31c25972bfb6d04caad05534505698776e7e6d5 \ No newline at end of file +31b83a7d7e553163eb186fc966a885f237554ec2 \ No newline at end of file diff --git a/src/fkey.c b/src/fkey.c index fa19fbc1ce..25d9f84917 100644 --- a/src/fkey.c +++ b/src/fkey.c @@ -1372,7 +1372,8 @@ void sqlite3FkDelete(sqlite3 *db, Table *pTab){ FKey *pFKey; /* Iterator variable */ FKey *pNext; /* Copy of pFKey->pNextFrom */ - assert( db==0 || sqlite3SchemaMutexHeld(db, 0, pTab->pSchema) ); + assert( db==0 || IsVirtual(pTab) + || sqlite3SchemaMutexHeld(db, 0, pTab->pSchema) ); for(pFKey=pTab->pFKey; pFKey; pFKey=pNext){ /* Remove the FK from the fkeyHash hash table. */ diff --git a/src/vtab.c b/src/vtab.c index eeef64c67a..e81079a050 100644 --- a/src/vtab.c +++ b/src/vtab.c @@ -1101,7 +1101,7 @@ void sqlite3VtabMakeWritable(Parse *pParse, Table *pTab){ } /* -** Check to see if virtual tale module pMod can be have an eponymous +** Check to see if virtual table module pMod can be have an eponymous ** virtual table instance. If it can, create one if one does not already ** exist. Return non-zero if the eponymous virtual table instance exists ** when this routine returns, and return zero if it does not exist. @@ -1118,17 +1118,18 @@ int sqlite3VtabEponymousTableInit(Parse *pParse, Module *pMod){ const sqlite3_module *pModule = pMod->pModule; Table *pTab; char *zErr = 0; - int nName; int rc; sqlite3 *db = pParse->db; if( pMod->pEpoTab ) return 1; if( pModule->xCreate!=0 && pModule->xCreate!=pModule->xConnect ) return 0; - nName = sqlite3Strlen30(pMod->zName) + 1; - pTab = sqlite3DbMallocZero(db, sizeof(Table) + nName); + pTab = sqlite3DbMallocZero(db, sizeof(Table)); if( pTab==0 ) return 0; + pTab->zName = sqlite3DbStrDup(db, pMod->zName); + if( pTab->zName==0 ){ + sqlite3DbFree(db, pTab); + return 0; + } pMod->pEpoTab = pTab; - pTab->zName = (char*)&pTab[1]; - memcpy(pTab->zName, pMod->zName, nName); pTab->nRef = 1; pTab->pSchema = db->aDb[0].pSchema; pTab->tabFlags |= TF_Virtual; @@ -1154,9 +1155,11 @@ int sqlite3VtabEponymousTableInit(Parse *pParse, Module *pMod){ void sqlite3VtabEponymousTableClear(sqlite3 *db, Module *pMod){ Table *pTab = pMod->pEpoTab; if( pTab!=0 ){ - sqlite3DeleteColumnNames(db, pTab); - sqlite3VtabClear(db, pTab); - sqlite3DbFree(db, pTab); + /* Mark the table as Ephemeral prior to deleting it, so that the + ** sqlite3DeleteTable() routine will know that it is not stored in + ** the schema. */ + pTab->tabFlags |= TF_Ephemeral; + sqlite3DeleteTable(db, pTab); pMod->pEpoTab = 0; } } From cc9717381075e58c9d2197b1924d7a77ae4372a4 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 4 Jun 2016 13:57:41 +0000 Subject: [PATCH 0494/1484] Remove an unreachable branch in the UNIQUE constraint parsing. FossilOrigin-Name: 313e990c741d7db082f1d9b9f3f4c65fdd91b812 --- manifest | 13 ++++++------- manifest.uuid | 2 +- src/build.c | 3 ++- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index d7eafa6187..b04a4479b5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C The\sOR\soptimization\sis\susable\son\svirtual\stables\swith\sLIKE,\sREGEXP\sand/or\sGLOB\nterms\sin\sthe\sWHERE\sclause. -D 2016-06-03T18:59:37.684 +C Remove\san\sunreachable\sbranch\sin\sthe\sUNIQUE\sconstraint\sparsing. +D 2016-06-04T13:57:41.807 F Makefile.in 7321ef0b584224781ec7731408857fa8962c32cc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 831503fc4e988f571590af1405645fff121b5f1e @@ -329,7 +329,7 @@ F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 F src/btree.c 2128172fc1c420a6fa6878827fa595407795069a F src/btree.h 1342a9b2cc2089e3534d3ef00204786783f6aea6 F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 -F src/build.c 555b459d1f25fba6c56266e60bbbdc93bdf5f66a +F src/build.c e827e57e4a29c00e8429c5fd4d9d4572cb1b32a4 F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 999a828425b35b8092a8cde25690e71c20906344 @@ -1500,8 +1500,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P aa7e9d0cc15c050205b09d5a50f985e4ade571d0 242507b4ff96bc4c7c7844dbe1c2b8508dbf1d01 -R dfe54e67ed3ff0c24bd7773ed3ea50c6 -T +closed 242507b4ff96bc4c7c7844dbe1c2b8508dbf1d01 +P fa3a89fc0b88d5ad7f5c232198847b3483eef611 +R 792813b3b416caa613200f5d3538ce28 U drh -Z 465e32629738d03f290a2446a78a1b88 +Z d457dbe5f31dc59ad0f374dbed05972f diff --git a/manifest.uuid b/manifest.uuid index 0bd0a43bf5..2ef42a0dcf 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fa3a89fc0b88d5ad7f5c232198847b3483eef611 \ No newline at end of file +313e990c741d7db082f1d9b9f3f4c65fdd91b812 \ No newline at end of file diff --git a/src/build.c b/src/build.c index 092a9973b3..a5931954ad 100644 --- a/src/build.c +++ b/src/build.c @@ -3287,8 +3287,9 @@ void sqlite3CreateIndex( ** in-memory database structures. */ assert( pParse->nErr==0 ); - if( db->init.busy && !IN_DECLARE_VTAB ){ + if( db->init.busy ){ Index *p; + assert( !IN_DECLARE_VTAB ); assert( sqlite3SchemaMutexHeld(db, 0, pIndex->pSchema) ); p = sqlite3HashInsert(&pIndex->pSchema->idxHash, pIndex->zName, pIndex); From 30e3fdf0ee42a94b4932dee03a69845d62f50da3 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 4 Jun 2016 16:33:48 +0000 Subject: [PATCH 0495/1484] Fix up speedtest1.c so that it will compile and run on SQLite versions prior to 3.6.18 (circa 2009-09-11). FossilOrigin-Name: 9583c0fb39f357a76e0c99ea03b034aea3e03c75 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/speedtest1.c | 4 ++++ 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index b04a4479b5..64889ef359 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\san\sunreachable\sbranch\sin\sthe\sUNIQUE\sconstraint\sparsing. -D 2016-06-04T13:57:41.807 +C Fix\sup\sspeedtest1.c\sso\sthat\sit\swill\scompile\sand\srun\son\sSQLite\sversions\sprior\nto\s3.6.18\s(circa\s2009-09-11). +D 2016-06-04T16:33:48.064 F Makefile.in 7321ef0b584224781ec7731408857fa8962c32cc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 831503fc4e988f571590af1405645fff121b5f1e @@ -1093,7 +1093,7 @@ F test/speed3.test d32043614c08c53eafdc80f33191d5bd9b920523 F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715 F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b -F test/speedtest1.c 4476f7030775507f060d27b789e1f4123c5a5866 +F test/speedtest1.c 28221f433d358dd3fcf2ca504ed51409aa66ffaf F test/spellfix.test f9c1f431e2c096c8775fec032952320c0e4700db F test/spellfix2.test dfc8f519a3fc204cb2dfa8b4f29821ae90f6f8c3 F test/spellfix3.test 0f9efaaa502a0e0a09848028518a6fb096c8ad33 @@ -1500,7 +1500,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P fa3a89fc0b88d5ad7f5c232198847b3483eef611 -R 792813b3b416caa613200f5d3538ce28 +P 313e990c741d7db082f1d9b9f3f4c65fdd91b812 +R 0ccf0692aa5b1e3235a74f8650fcfe4f U drh -Z d457dbe5f31dc59ad0f374dbed05972f +Z a2bd3a06dcb83b470b97f0c6e2306afd diff --git a/manifest.uuid b/manifest.uuid index 2ef42a0dcf..12c744c1c5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -313e990c741d7db082f1d9b9f3f4c65fdd91b812 \ No newline at end of file +9583c0fb39f357a76e0c99ea03b034aea3e03c75 \ No newline at end of file diff --git a/test/speedtest1.c b/test/speedtest1.c index 2d337d4705..c69c6d5fc5 100644 --- a/test/speedtest1.c +++ b/test/speedtest1.c @@ -1216,6 +1216,10 @@ static void displayLinuxIoStats(FILE *out){ } #endif +#if SQLITE_VERSION_NUMBER<3006018 +# define sqlite3_sourceid(X) "(before 3.6.18)" +#endif + int main(int argc, char **argv){ int doAutovac = 0; /* True for --autovacuum */ int cacheSize = 0; /* Desired cache size. 0 means default */ From f94fdd832cc7f7ec1764af518edf746cba6a3687 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 4 Jun 2016 17:12:26 +0000 Subject: [PATCH 0496/1484] Allocate KeyInfo objects from lookaside if possible. FossilOrigin-Name: b411107a3609d53af4e147f01e311b858b78420b --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/select.c | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 64889ef359..5cfb3e8240 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sup\sspeedtest1.c\sso\sthat\sit\swill\scompile\sand\srun\son\sSQLite\sversions\sprior\nto\s3.6.18\s(circa\s2009-09-11). -D 2016-06-04T16:33:48.064 +C Allocate\sKeyInfo\sobjects\sfrom\slookaside\sif\spossible. +D 2016-06-04T17:12:26.466 F Makefile.in 7321ef0b584224781ec7731408857fa8962c32cc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 831503fc4e988f571590af1405645fff121b5f1e @@ -382,7 +382,7 @@ F src/printf.c a5f0ca08ddede803c241266abb46356ec748ded1 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c cca3aa77b95706df5d635a2141a4d1de60ae6598 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac -F src/select.c a0c4abf54bc6bd3a9c77a36ef3d1676045706cb2 +F src/select.c f3c6e9065fb34f6a23af27ec7f1f717ffbfc2ee4 F src/shell.c 14ff7f660530a52b117d110ba3390b7b2eb719b6 F src/sqlite.h.in 5f8113dbec74c6c093ead9930afb8c9fbd9f643d F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1500,7 +1500,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 313e990c741d7db082f1d9b9f3f4c65fdd91b812 -R 0ccf0692aa5b1e3235a74f8650fcfe4f +P 9583c0fb39f357a76e0c99ea03b034aea3e03c75 +R 065fce549d6916be91d3267449fff27c U drh -Z a2bd3a06dcb83b470b97f0c6e2306afd +Z 36eef125b8bc40e49e28e0447e72ab1c diff --git a/manifest.uuid b/manifest.uuid index 12c744c1c5..b10b2154c9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9583c0fb39f357a76e0c99ea03b034aea3e03c75 \ No newline at end of file +b411107a3609d53af4e147f01e311b858b78420b \ No newline at end of file diff --git a/src/select.c b/src/select.c index 495d47e20b..e21ac57dc5 100644 --- a/src/select.c +++ b/src/select.c @@ -1028,7 +1028,7 @@ static void selectInnerLoop( */ KeyInfo *sqlite3KeyInfoAlloc(sqlite3 *db, int N, int X){ int nExtra = (N+X)*(sizeof(CollSeq*)+1); - KeyInfo *p = sqlite3Malloc(sizeof(KeyInfo) + nExtra); + KeyInfo *p = sqlite3DbMallocRaw(db, sizeof(KeyInfo) + nExtra); if( p ){ p->aSortOrder = (u8*)&p->aColl[N+X]; p->nField = (u16)N; @@ -1050,7 +1050,7 @@ void sqlite3KeyInfoUnref(KeyInfo *p){ if( p ){ assert( p->nRef>0 ); p->nRef--; - if( p->nRef==0 ) sqlite3DbFree(0, p); + if( p->nRef==0 ) sqlite3DbFree(p->db, p); } } From a7c90c42eaf1badd141ca21bd64669e03de9830c Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 4 Jun 2016 20:37:10 +0000 Subject: [PATCH 0497/1484] Change the sqlite3BtreeKeySize() interface into sqlite3BtreeIntegerKey() and make it only work for table btrees. Change sqlite3BtreeDataSize() into sqlite3BtreePayloadSize() and make it work for all btrees. Combine sqlite3BtreeDataFetch() and sqlite3BtreeKeyFetch() into a single sqlite3BtreePayloadFetch() routine. These changes seem to make the b-tree interface more rational and they reduce both binary size and CPU usage. FossilOrigin-Name: bef35e18dd19732f7859287b097feeb593e5900f --- manifest | 29 +++++++++++++----------- manifest.uuid | 2 +- src/btree.c | 61 +++++++++++++++++--------------------------------- src/btree.h | 7 +++--- src/test3.c | 15 +++---------- src/vdbe.c | 49 +++++++++------------------------------- src/vdbeapi.c | 3 +-- src/vdbeaux.c | 6 ++--- src/vdbeblob.c | 2 +- src/vdbemem.c | 6 +---- 10 files changed, 59 insertions(+), 121 deletions(-) diff --git a/manifest b/manifest index 5cfb3e8240..f5cc249751 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Allocate\sKeyInfo\sobjects\sfrom\slookaside\sif\spossible. -D 2016-06-04T17:12:26.466 +C Change\sthe\ssqlite3BtreeKeySize()\sinterface\sinto\ssqlite3BtreeIntegerKey()\sand\nmake\sit\sonly\swork\sfor\stable\sbtrees.\s\sChange\ssqlite3BtreeDataSize()\sinto\nsqlite3BtreePayloadSize()\sand\smake\sit\swork\sfor\sall\sbtrees.\s\sCombine\nsqlite3BtreeDataFetch()\sand\ssqlite3BtreeKeyFetch()\sinto\sa\ssingle\nsqlite3BtreePayloadFetch()\sroutine.\s\sThese\schanges\sseem\sto\smake\sthe\nb-tree\sinterface\smore\srational\sand\sthey\sreduce\sboth\sbinary\ssize\sand\nCPU\susage. +D 2016-06-04T20:37:10.186 F Makefile.in 7321ef0b584224781ec7731408857fa8962c32cc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 831503fc4e988f571590af1405645fff121b5f1e @@ -326,8 +326,8 @@ F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240 F src/backup.c 6df65fdd569c901a418887a1a76f82ec35044556 F src/bitvec.c 3ee4c8b2c94ed3a7377256e18199e6ff5cf33f63 F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 -F src/btree.c 2128172fc1c420a6fa6878827fa595407795069a -F src/btree.h 1342a9b2cc2089e3534d3ef00204786783f6aea6 +F src/btree.c b55e96857e89734ae0ef2e77ed07b5e55314f1d9 +F src/btree.h 2107a2630e02c8cba58bb12ce14e731e734ea29c F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 F src/build.c e827e57e4a29c00e8429c5fd4d9d4572cb1b32a4 F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 @@ -394,7 +394,7 @@ F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 F src/tclsqlite.c 9c4c4589d078de37813ded708d8838b338ffb060 F src/test1.c 43b37ab2b7338fd3313e74902f0d6c821eae843b F src/test2.c 5586f43fcd9a1be0830793cf9d354082c261b25b -F src/test3.c d2c9efd2985ff8f5502ffd3253156984778d77d8 +F src/test3.c c75c8af0eadb335236c9e61b51044c58a8f7dd59 F src/test4.c d168f83cc78d02e8d35567bb5630e40dcd85ac1e F src/test5.c 5a34feec76d9b3a86aab30fd4f6cc9c48cbab4c1 F src/test6.c a684b7abd01352ab50cb79c0bf727e6b3f381a3d @@ -448,13 +448,13 @@ F src/update.c 4f05ea8cddfa367d045e03589756c02199e8f9bd F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 810ec3f22e2d1b62e66c30fe3621ebdedd23584d F src/vacuum.c feb1eabb20987983d9350cad98299b21fa811f52 -F src/vdbe.c 45e4da739187028281e342f79fae0f4145055bec +F src/vdbe.c f6d37b366fe426637708ad6ad21d93e8b52512e2 F src/vdbe.h 5591b5add447096e31288b5a0a78ec5d7b5c5170 F src/vdbeInt.h ddb157974436d87652de7dc641f7191496d9a8cd -F src/vdbeapi.c ba85b78fe08dc4a9ce747e62c89a2b4a4547e74c -F src/vdbeaux.c 1d6b9a979d1036db7bc39990e9e683f19520bc5c -F src/vdbeblob.c c9f2f494b911c6fa34efd9803f0a10807da80f77 -F src/vdbemem.c 5cfef60e60e19cab6275d1b975bf4c791d575beb +F src/vdbeapi.c 02bcbc2ca5d2004b029088b05b468b394881e103 +F src/vdbeaux.c c90275b0e55a2b32c03dc09314194fe46f2429d8 +F src/vdbeblob.c 83d2d266383157b02e2b809350bb197e89d7895b +F src/vdbemem.c 1ecaa5ee0caff07255f25d04e8dc88befb6f88d1 F src/vdbesort.c 91fda3909326860382b0ca8aa251e609c6a9d62c F src/vdbetrace.c f75c5455d8cf389ef86a8bfdfd3177e0e3692484 F src/vtab.c 948d2d4984219eee37a7bf427d6667e21e6eb92e @@ -1500,7 +1500,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 9583c0fb39f357a76e0c99ea03b034aea3e03c75 -R 065fce549d6916be91d3267449fff27c +P b411107a3609d53af4e147f01e311b858b78420b +R 80a60ad5ffc5ad6e753a2a298aeee05c +T *branch * btree-refactor +T *sym-btree-refactor * +T -sym-trunk * U drh -Z 36eef125b8bc40e49e28e0447e72ab1c +Z 4c3d5b0be019f44c3e1bc23daff07019 diff --git a/manifest.uuid b/manifest.uuid index b10b2154c9..2fca7ce9d8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b411107a3609d53af4e147f01e311b858b78420b \ No newline at end of file +bef35e18dd19732f7859287b097feeb593e5900f \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 7a2b80c23b..4003352a5e 100644 --- a/src/btree.c +++ b/src/btree.c @@ -609,20 +609,17 @@ static void btreeReleaseAllCursorPages(BtCursor *pCur){ ** the key. */ static int saveCursorKey(BtCursor *pCur){ - int rc; + int rc = SQLITE_OK; assert( CURSOR_VALID==pCur->eState ); assert( 0==pCur->pKey ); assert( cursorHoldsMutex(pCur) ); - rc = sqlite3BtreeKeySize(pCur, &pCur->nKey); - assert( rc==SQLITE_OK ); /* KeySize() cannot fail */ - - /* If this is an intKey table, then the above call to BtreeKeySize() - ** stores the integer key in pCur->nKey. In this case this value is - ** all that is required. Otherwise, if pCur is not open on an intKey - ** table, then malloc space for and store the pCur->nKey bytes of key - ** data. */ - if( 0==pCur->curIntKey ){ + if( pCur->curIntKey ){ + /* Only the rowid is required for a table btree */ + pCur->nKey = sqlite3BtreeIntegerKey(pCur); + }else{ + /* For an index btree, save the complete key content */ + pCur->nKey = sqlite3BtreePayloadSize(pCur); void *pKey = sqlite3Malloc( pCur->nKey ); if( pKey ){ rc = sqlite3BtreeKey(pCur, 0, (int)pCur->nKey, pKey); @@ -4262,46 +4259,33 @@ int sqlite3BtreeCursorIsValid(BtCursor *pCur){ #endif /* NDEBUG */ /* -** Set *pSize to the size of the buffer needed to hold the value of -** the key for the current entry. If the cursor is not pointing -** to a valid entry, *pSize is set to 0. -** -** For a table with the INTKEY flag set, this routine returns the key -** itself, not the number of bytes in the key. -** -** The caller must position the cursor prior to invoking this routine. -** -** This routine cannot fail. It always returns SQLITE_OK. +** Return the value of the integer key or "rowid" for a table btree. +** This routine is only valid for a cursor that is pointing into a +** ordinary table btree. If the cursor points to an index btree or +** is invalid, the result of this routine is undefined. */ -int sqlite3BtreeKeySize(BtCursor *pCur, i64 *pSize){ +i64 sqlite3BtreeIntegerKey(BtCursor *pCur){ assert( cursorHoldsMutex(pCur) ); assert( pCur->eState==CURSOR_VALID ); + assert( pCur->curIntKey ); getCellInfo(pCur); - *pSize = pCur->info.nKey; - return SQLITE_OK; + return pCur->info.nKey; } /* -** Set *pSize to the number of bytes of data in the entry the -** cursor currently points to. +** Return the number of bytes of payload for the entry that pCur is +** currently pointing to. For table btrees, this will be the amount +** of data. For index btrees, this will be the size of the key. ** ** The caller must guarantee that the cursor is pointing to a non-NULL ** valid entry. In other words, the calling procedure must guarantee ** that the cursor has Cursor.eState==CURSOR_VALID. -** -** Failure is not possible. This function always returns SQLITE_OK. -** It might just as well be a procedure (returning void) but we continue -** to return an integer result code for historical reasons. */ -int sqlite3BtreeDataSize(BtCursor *pCur, u32 *pSize){ - assert( cursorOwnsBtShared(pCur) ); +u32 sqlite3BtreePayloadSize(BtCursor *pCur){ + assert( cursorHoldsMutex(pCur) ); assert( pCur->eState==CURSOR_VALID ); - assert( pCur->iPage>=0 ); - assert( pCur->iPageapPage[pCur->iPage]->intKeyLeaf==1 ); getCellInfo(pCur); - *pSize = pCur->info.nPayload; - return SQLITE_OK; + return pCur->info.nPayload; } /* @@ -4743,10 +4727,7 @@ static const void *fetchPayload( ** These routines is used to get quick access to key and data ** in the common case where no overflow pages are used. */ -const void *sqlite3BtreeKeyFetch(BtCursor *pCur, u32 *pAmt){ - return fetchPayload(pCur, pAmt); -} -const void *sqlite3BtreeDataFetch(BtCursor *pCur, u32 *pAmt){ +const void *sqlite3BtreePayloadFetch(BtCursor *pCur, u32 *pAmt){ return fetchPayload(pCur, pAmt); } diff --git a/src/btree.h b/src/btree.h index 5ac119c40a..5720df90f7 100644 --- a/src/btree.h +++ b/src/btree.h @@ -284,11 +284,10 @@ int sqlite3BtreeLast(BtCursor*, int *pRes); int sqlite3BtreeNext(BtCursor*, int *pRes); int sqlite3BtreeEof(BtCursor*); int sqlite3BtreePrevious(BtCursor*, int *pRes); -int sqlite3BtreeKeySize(BtCursor*, i64 *pSize); +i64 sqlite3BtreeIntegerKey(BtCursor*); int sqlite3BtreeKey(BtCursor*, u32 offset, u32 amt, void*); -const void *sqlite3BtreeKeyFetch(BtCursor*, u32 *pAmt); -const void *sqlite3BtreeDataFetch(BtCursor*, u32 *pAmt); -int sqlite3BtreeDataSize(BtCursor*, u32 *pSize); +const void *sqlite3BtreePayloadFetch(BtCursor*, u32 *pAmt); +u32 sqlite3BtreePayloadSize(BtCursor*); int sqlite3BtreeData(BtCursor*, u32 offset, u32 amt, void*); char *sqlite3BtreeIntegrityCheck(Btree*, int *aRoot, int nRoot, int, int*); diff --git a/src/test3.c b/src/test3.c index 1e4baf7577..bfd7c30b65 100644 --- a/src/test3.c +++ b/src/test3.c @@ -385,8 +385,7 @@ static int btree_payload_size( const char **argv /* Text of each argument */ ){ BtCursor *pCur; - int n2; - u64 n1; + u32 n; char zBuf[50]; if( argc!=2 ){ @@ -396,17 +395,9 @@ static int btree_payload_size( } pCur = sqlite3TestTextToPtr(argv[1]); sqlite3BtreeEnter(pCur->pBtree); - - /* The cursor may be in "require-seek" state. If this is the case, the - ** call to BtreeDataSize() will fix it. */ - sqlite3BtreeDataSize(pCur, (u32*)&n2); - if( pCur->apPage[pCur->iPage]->intKey ){ - n1 = 0; - }else{ - sqlite3BtreeKeySize(pCur, (i64*)&n1); - } + n = sqlite3BtreePayloadSize(pCur); sqlite3BtreeLeave(pCur->pBtree); - sqlite3_snprintf(sizeof(zBuf),zBuf, "%d", (int)(n1+n2)); + sqlite3_snprintf(sizeof(zBuf),zBuf, "%u", n); Tcl_AppendResult(interp, zBuf, 0); return SQLITE_OK; } diff --git a/src/vdbe.c b/src/vdbe.c index d4392a89d9..356cf52f01 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2380,7 +2380,6 @@ case OP_NotNull: { /* same as TK_NOTNULL, jump, in1 */ ** skipped for length() and all content loading can be skipped for typeof(). */ case OP_Column: { - i64 payloadSize64; /* Number of bytes in the record */ int p2; /* column number to retrieve */ VdbeCursor *pC; /* The VDBE cursor */ BtCursor *pCrsr; /* The BTree cursor */ @@ -2433,22 +2432,9 @@ case OP_Column: { }else{ assert( pC->eCurType==CURTYPE_BTREE ); assert( pCrsr ); - if( pC->isTable==0 ){ - assert( sqlite3BtreeCursorIsValid(pCrsr) ); - VVA_ONLY(rc =) sqlite3BtreeKeySize(pCrsr, &payloadSize64); - assert( rc==SQLITE_OK ); /* True because of CursorMoveto() call above */ - /* sqlite3BtreeParseCellPtr() uses getVarint32() to extract the - ** payload size, so it is impossible for payloadSize64 to be - ** larger than 32 bits. */ - assert( (payloadSize64 & SQLITE_MAX_U32)==(u64)payloadSize64 ); - pC->aRow = sqlite3BtreeKeyFetch(pCrsr, &avail); - pC->payloadSize = (u32)payloadSize64; - }else{ - assert( sqlite3BtreeCursorIsValid(pCrsr) ); - VVA_ONLY(rc =) sqlite3BtreeDataSize(pCrsr, &pC->payloadSize); - assert( rc==SQLITE_OK ); /* DataSize() cannot fail */ - pC->aRow = sqlite3BtreeDataFetch(pCrsr, &avail); - } + assert( sqlite3BtreeCursorIsValid(pCrsr) ); + pC->payloadSize = sqlite3BtreePayloadSize(pCrsr); + pC->aRow = sqlite3BtreePayloadFetch(pCrsr, &avail); assert( avail<=65536 ); /* Maximum page size is 64KiB */ if( pC->payloadSize <= (u32)avail ){ pC->szRow = pC->payloadSize; @@ -4201,8 +4187,7 @@ case OP_NewRowid: { /* out2 */ v = 1; /* IMP: R-61914-48074 */ }else{ assert( sqlite3BtreeCursorIsValid(pC->uc.pCursor) ); - rc = sqlite3BtreeKeySize(pC->uc.pCursor, &v); - assert( rc==SQLITE_OK ); /* Cannot fail following BtreeLast() */ + v = sqlite3BtreeIntegerKey(pC->uc.pCursor); if( v>=MAX_ROWID ){ pC->useRandomRowid = 1; }else{ @@ -4459,8 +4444,7 @@ case OP_Delete: { /* If p5 is zero, the seek operation that positioned the cursor prior to ** OP_Delete will have also set the pC->movetoTarget field to the rowid of ** the row that is being deleted */ - i64 iKey = 0; - sqlite3BtreeKeySize(pC->uc.pCursor, &iKey); + i64 iKey = sqlite3BtreeIntegerKey(pC->uc.pCursor); assert( pC->movetoTarget==iKey ); } #endif @@ -4476,7 +4460,7 @@ case OP_Delete: { zDb = db->aDb[pC->iDb].zName; pTab = pOp->p4.pTab; if( (pOp->p5 & OPFLAG_SAVEPOSITION)!=0 && pC->isTable ){ - sqlite3BtreeKeySize(pC->uc.pCursor, &pC->movetoTarget); + pC->movetoTarget = sqlite3BtreeIntegerKey(pC->uc.pCursor); } }else{ zDb = 0; /* Not needed. Silence a compiler warning. */ @@ -4630,7 +4614,6 @@ case OP_RowData: { VdbeCursor *pC; BtCursor *pCrsr; u32 n; - i64 n64; pOut = &aMem[pOp->p2]; memAboutToChange(p, pOut); @@ -4662,20 +4645,9 @@ case OP_RowData: { if( rc!=SQLITE_OK ) goto abort_due_to_error; #endif - if( pC->isTable==0 ){ - assert( !pC->isTable ); - VVA_ONLY(rc =) sqlite3BtreeKeySize(pCrsr, &n64); - assert( rc==SQLITE_OK ); /* True because of CursorMoveto() call above */ - if( n64>db->aLimit[SQLITE_LIMIT_LENGTH] ){ - goto too_big; - } - n = (u32)n64; - }else{ - VVA_ONLY(rc =) sqlite3BtreeDataSize(pCrsr, &n); - assert( rc==SQLITE_OK ); /* DataSize() cannot fail */ - if( n>(u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){ - goto too_big; - } + n = sqlite3BtreePayloadSize(pCrsr); + if( n>db->aLimit[SQLITE_LIMIT_LENGTH] ){ + goto too_big; } testcase( n==0 ); if( sqlite3VdbeMemClearAndResize(pOut, MAX(n,32)) ){ @@ -4740,8 +4712,7 @@ case OP_Rowid: { /* out2 */ pOut->flags = MEM_Null; break; } - rc = sqlite3BtreeKeySize(pC->uc.pCursor, &v); - assert( rc==SQLITE_OK ); /* Always so because of CursorRestore() above */ + v = sqlite3BtreeIntegerKey(pC->uc.pCursor); } pOut->u.i = v; break; diff --git a/src/vdbeapi.c b/src/vdbeapi.c index 1feecb3e11..83718eae39 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -1650,8 +1650,7 @@ int sqlite3_preupdate_old(sqlite3 *db, int iIdx, sqlite3_value **ppValue){ u32 nRec; u8 *aRec; - rc = sqlite3BtreeDataSize(p->pCsr->uc.pCursor, &nRec); - if( rc!=SQLITE_OK ) goto preupdate_old_out; + nRec = sqlite3BtreePayloadSize(p->pCsr->uc.pCursor); aRec = sqlite3DbMallocRaw(db, nRec); if( !aRec ) goto preupdate_old_out; rc = sqlite3BtreeData(p->pCsr->uc.pCursor, 0, nRec, aRec); diff --git a/src/vdbeaux.c b/src/vdbeaux.c index bce676f10c..63609d72dd 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -4315,8 +4315,7 @@ int sqlite3VdbeIdxRowid(sqlite3 *db, BtCursor *pCur, i64 *rowid){ ** this code can safely assume that nCellKey is 32-bits */ assert( sqlite3BtreeCursorIsValid(pCur) ); - VVA_ONLY(rc =) sqlite3BtreeKeySize(pCur, &nCellKey); - assert( rc==SQLITE_OK ); /* pCur is always valid so KeySize cannot fail */ + nCellKey = sqlite3BtreePayloadSize(pCur); assert( (nCellKey & SQLITE_MAX_U32)==(u64)nCellKey ); /* Read in the complete content of the index entry */ @@ -4393,8 +4392,7 @@ int sqlite3VdbeIdxKeyCompare( assert( pC->eCurType==CURTYPE_BTREE ); pCur = pC->uc.pCursor; assert( sqlite3BtreeCursorIsValid(pCur) ); - VVA_ONLY(rc =) sqlite3BtreeKeySize(pCur, &nCellKey); - assert( rc==SQLITE_OK ); /* pCur is always valid so KeySize cannot fail */ + nCellKey = sqlite3BtreePayloadSize(pCur); /* nCellKey will always be between 0 and 0xffffffff because of the way ** that btreeParseCellPtr() and sqlite3GetVarint32() are implemented */ if( nCellKey<=0 || nCellKey>0x7fffffff ){ diff --git a/src/vdbeblob.c b/src/vdbeblob.c index f2b3ffef2b..01827f94d0 100644 --- a/src/vdbeblob.c +++ b/src/vdbeblob.c @@ -415,7 +415,7 @@ static int blobReadWrite( ** anyhow. */ sqlite3_int64 iKey; - sqlite3BtreeKeySize(p->pCsr, &iKey); + iKey = sqlite3BtreeIntegerKey(p->pCsr); sqlite3VdbePreUpdateHook( v, v->apCsr[0], SQLITE_DELETE, p->zDb, p->pTab, iKey, -1 ); diff --git a/src/vdbemem.c b/src/vdbemem.c index f9396e570c..04cb9c5c63 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -991,11 +991,7 @@ int sqlite3VdbeMemFromBtree( /* Note: the calls to BtreeKeyFetch() and DataFetch() below assert() ** that both the BtShared and database handle mutexes are held. */ assert( (pMem->flags & MEM_RowSet)==0 ); - if( key ){ - zData = (char *)sqlite3BtreeKeyFetch(pCur, &available); - }else{ - zData = (char *)sqlite3BtreeDataFetch(pCur, &available); - } + zData = (char *)sqlite3BtreePayloadFetch(pCur, &available); assert( zData!=0 ); if( offset+amt<=available ){ From d66c4f809d3677d935f5b0c218585457289c2ff6 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 4 Jun 2016 20:58:35 +0000 Subject: [PATCH 0498/1484] Fix a C99-ism and a compiler warning for MSVC. FossilOrigin-Name: aa53a36ea2eb90cc4939e37e6ad320b4211692fd --- manifest | 17 +++++++---------- manifest.uuid | 2 +- src/btree.c | 3 ++- src/vdbe.c | 2 +- 4 files changed, 11 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index f5cc249751..f8c32841be 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sthe\ssqlite3BtreeKeySize()\sinterface\sinto\ssqlite3BtreeIntegerKey()\sand\nmake\sit\sonly\swork\sfor\stable\sbtrees.\s\sChange\ssqlite3BtreeDataSize()\sinto\nsqlite3BtreePayloadSize()\sand\smake\sit\swork\sfor\sall\sbtrees.\s\sCombine\nsqlite3BtreeDataFetch()\sand\ssqlite3BtreeKeyFetch()\sinto\sa\ssingle\nsqlite3BtreePayloadFetch()\sroutine.\s\sThese\schanges\sseem\sto\smake\sthe\nb-tree\sinterface\smore\srational\sand\sthey\sreduce\sboth\sbinary\ssize\sand\nCPU\susage. -D 2016-06-04T20:37:10.186 +C Fix\sa\sC99-ism\sand\sa\scompiler\swarning\sfor\sMSVC. +D 2016-06-04T20:58:35.587 F Makefile.in 7321ef0b584224781ec7731408857fa8962c32cc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 831503fc4e988f571590af1405645fff121b5f1e @@ -326,7 +326,7 @@ F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240 F src/backup.c 6df65fdd569c901a418887a1a76f82ec35044556 F src/bitvec.c 3ee4c8b2c94ed3a7377256e18199e6ff5cf33f63 F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 -F src/btree.c b55e96857e89734ae0ef2e77ed07b5e55314f1d9 +F src/btree.c 579a8160f57db168425ef940276319bed48a95d3 F src/btree.h 2107a2630e02c8cba58bb12ce14e731e734ea29c F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 F src/build.c e827e57e4a29c00e8429c5fd4d9d4572cb1b32a4 @@ -448,7 +448,7 @@ F src/update.c 4f05ea8cddfa367d045e03589756c02199e8f9bd F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 810ec3f22e2d1b62e66c30fe3621ebdedd23584d F src/vacuum.c feb1eabb20987983d9350cad98299b21fa811f52 -F src/vdbe.c f6d37b366fe426637708ad6ad21d93e8b52512e2 +F src/vdbe.c e23a15d352e63b51cf08af8052e678e67c54ec09 F src/vdbe.h 5591b5add447096e31288b5a0a78ec5d7b5c5170 F src/vdbeInt.h ddb157974436d87652de7dc641f7191496d9a8cd F src/vdbeapi.c 02bcbc2ca5d2004b029088b05b468b394881e103 @@ -1500,10 +1500,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b411107a3609d53af4e147f01e311b858b78420b -R 80a60ad5ffc5ad6e753a2a298aeee05c -T *branch * btree-refactor -T *sym-btree-refactor * -T -sym-trunk * +P bef35e18dd19732f7859287b097feeb593e5900f +R 7b13c2762e2abdaed13574cfe801f7ea U drh -Z 4c3d5b0be019f44c3e1bc23daff07019 +Z c33407f01f615b8db559b27222022193 diff --git a/manifest.uuid b/manifest.uuid index 2fca7ce9d8..0b98334436 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bef35e18dd19732f7859287b097feeb593e5900f \ No newline at end of file +aa53a36ea2eb90cc4939e37e6ad320b4211692fd \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 4003352a5e..550beb38aa 100644 --- a/src/btree.c +++ b/src/btree.c @@ -619,8 +619,9 @@ static int saveCursorKey(BtCursor *pCur){ pCur->nKey = sqlite3BtreeIntegerKey(pCur); }else{ /* For an index btree, save the complete key content */ + void *pKey; pCur->nKey = sqlite3BtreePayloadSize(pCur); - void *pKey = sqlite3Malloc( pCur->nKey ); + pKey = sqlite3Malloc( pCur->nKey ); if( pKey ){ rc = sqlite3BtreeKey(pCur, 0, (int)pCur->nKey, pKey); if( rc==SQLITE_OK ){ diff --git a/src/vdbe.c b/src/vdbe.c index 356cf52f01..245c5beb6c 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -4646,7 +4646,7 @@ case OP_RowData: { #endif n = sqlite3BtreePayloadSize(pCrsr); - if( n>db->aLimit[SQLITE_LIMIT_LENGTH] ){ + if( n>(u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){ goto too_big; } testcase( n==0 ); From 5e08d0fcb6574735f2f02803117e7094136856ce Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 4 Jun 2016 21:05:54 +0000 Subject: [PATCH 0499/1484] Improved comment on cursorOwnsBtShared(). No changes to code. FossilOrigin-Name: 5e269c2d2667df65592a32d6bc2fa388fd7eb181 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btree.c | 9 +++++++++ 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index f8c32841be..3a383881e0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sC99-ism\sand\sa\scompiler\swarning\sfor\sMSVC. -D 2016-06-04T20:58:35.587 +C Improved\scomment\son\scursorOwnsBtShared().\s\sNo\schanges\sto\scode. +D 2016-06-04T21:05:54.667 F Makefile.in 7321ef0b584224781ec7731408857fa8962c32cc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 831503fc4e988f571590af1405645fff121b5f1e @@ -326,7 +326,7 @@ F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240 F src/backup.c 6df65fdd569c901a418887a1a76f82ec35044556 F src/bitvec.c 3ee4c8b2c94ed3a7377256e18199e6ff5cf33f63 F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 -F src/btree.c 579a8160f57db168425ef940276319bed48a95d3 +F src/btree.c b8875cff2d98d662a7e25d73483bccc2374d8bdb F src/btree.h 2107a2630e02c8cba58bb12ce14e731e734ea29c F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 F src/build.c e827e57e4a29c00e8429c5fd4d9d4572cb1b32a4 @@ -1500,7 +1500,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P bef35e18dd19732f7859287b097feeb593e5900f -R 7b13c2762e2abdaed13574cfe801f7ea +P aa53a36ea2eb90cc4939e37e6ad320b4211692fd +R 31679baf828d6d3e0ee835dac82e6874 U drh -Z c33407f01f615b8db559b27222022193 +Z bd564a0c26801286c1f95fad1a35ec86 diff --git a/manifest.uuid b/manifest.uuid index 0b98334436..6568d401a5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -aa53a36ea2eb90cc4939e37e6ad320b4211692fd \ No newline at end of file +5e269c2d2667df65592a32d6bc2fa388fd7eb181 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 550beb38aa..5fbd6c4173 100644 --- a/src/btree.c +++ b/src/btree.c @@ -450,6 +450,15 @@ static void releasePage(MemPage *pPage); /* Forward reference */ static int cursorHoldsMutex(BtCursor *p){ return sqlite3_mutex_held(p->pBt->mutex); } + +/* Verify that the cursor and the BtShared agree about what is the current +** database connetion. This is important in shared-cache mode. If the database +** connection pointers get out-of-sync, it is possible for routines like +** btreeInitPage() to reference an stale connection pointer that references a +** a connection that has already closed. This routine is used inside assert() +** statements only and for the purpose of double-checking that the btree code +** does keep the database connection pointers up-to-date. +*/ static int cursorOwnsBtShared(BtCursor *p){ assert( cursorHoldsMutex(p) ); return (p->pBtree->db==p->pBt->db); From c80937a5f5ec900d898603dfd2d3bc7c47af10fe Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 6 Jun 2016 01:48:14 +0000 Subject: [PATCH 0500/1484] Small performance improvement in the LIKE function. FossilOrigin-Name: 5fb0c35459cf7a8662bf8cd84ac345f6fafda6cc --- manifest | 13 ++++++------- manifest.uuid | 2 +- src/func.c | 2 +- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index f32e69180f..c43382d993 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Btree\sinterface\srefactoring:\n(1)\sThe\ssqlite3BtreeKeySize()\sinterface\sis\srenamed\sto\ssqlite3BtreeIntegerKey()\nand\smodified\sto\swork\sonly\sfor\stable\sbtrees\swith\sa\srowid.\n(2)\sThe\ssqlite3BtreeDataSize()\sinterface\sis\srenamed\sto\ssqlite3BtreePayloadSize()\nand\smodified\sto\swork\swith\sany\sbtree.\n(3)\sThe\ssqlite3BtreeDataFetch()\sand\ssqlite3BtreeKeyFetch()\sroutines\sare\ncombined\sinto\sa\ssingle\ssqlite3BtreePayloadFetch()\sroutine.\nThe\sresult\sof\sthese\schanges\sis\sa\ssmaller\sbinary\sand\sfewer\sCPU\scycles\sneeded\nto\srun\squeries. -D 2016-06-06T01:14:08.809 +C Small\sperformance\simprovement\sin\sthe\sLIKE\sfunction. +D 2016-06-06T01:48:14.262 F Makefile.in 7321ef0b584224781ec7731408857fa8962c32cc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 831503fc4e988f571590af1405645fff121b5f1e @@ -339,7 +339,7 @@ F src/delete.c 4aba4214a377ce8ddde2d2e609777bcc8235200f F src/expr.c 798146ea4c87d723e8a157d88450ac9c43256998 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c bc4145347595b7770f9a598cff1c848302cf5413 -F src/func.c ef4c18c8a66143413ce41a58d582d2c14ddf78e1 +F src/func.c 61a4114cf7004f10c542cfabbab9f2bcb9033045 F src/global.c c45ea22aff29334f6a9ec549235ac3357c970015 F src/hash.c 55b5fb474100cee0b901edaf203e26c970940f36 F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094 @@ -1500,8 +1500,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b411107a3609d53af4e147f01e311b858b78420b 5e269c2d2667df65592a32d6bc2fa388fd7eb181 -R 31679baf828d6d3e0ee835dac82e6874 -T +closed 5e269c2d2667df65592a32d6bc2fa388fd7eb181 +P 2d831074cf730dce47de5880d7b4570d04d15fee +R 55f60418d6dcbf8aee4f5a82499e5642 U drh -Z e9c5ee5d96d9c9f1da27014117e66fa4 +Z 55a25f2496cfdeb6e61ef11536fc4f7e diff --git a/manifest.uuid b/manifest.uuid index e4a8777eb9..8076fd6a9e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2d831074cf730dce47de5880d7b4570d04d15fee \ No newline at end of file +5fb0c35459cf7a8662bf8cd84ac345f6fafda6cc \ No newline at end of file diff --git a/src/func.c b/src/func.c index 4feedc7440..78c8806456 100644 --- a/src/func.c +++ b/src/func.c @@ -740,7 +740,7 @@ static int patternCompare( } c2 = Utf8Read(zString); if( c==c2 ) continue; - if( noCase && c<0x80 && c2<0x80 && sqlite3Tolower(c)==sqlite3Tolower(c2) ){ + if( noCase && sqlite3Tolower(c)==sqlite3Tolower(c2) && c<0x80 && c2<0x80 ){ continue; } if( c==matchOne && zPattern!=zEscaped && c2!=0 ) continue; From 05a360913d38e3685a5cc994c4394fe54c131eb0 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 6 Jun 2016 01:54:20 +0000 Subject: [PATCH 0501/1484] Small performance boost and size decrease in sqlite3BtreeMovetoUnpacked(). FossilOrigin-Name: e106a77d85c20ae23ebe49a5acceeaffecb40fc2 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btree.c | 5 +++-- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index c43382d993..eca2ed0fc6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Small\sperformance\simprovement\sin\sthe\sLIKE\sfunction. -D 2016-06-06T01:48:14.262 +C Small\sperformance\sboost\sand\ssize\sdecrease\sin\ssqlite3BtreeMovetoUnpacked(). +D 2016-06-06T01:54:20.047 F Makefile.in 7321ef0b584224781ec7731408857fa8962c32cc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 831503fc4e988f571590af1405645fff121b5f1e @@ -326,7 +326,7 @@ F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240 F src/backup.c 6df65fdd569c901a418887a1a76f82ec35044556 F src/bitvec.c 3ee4c8b2c94ed3a7377256e18199e6ff5cf33f63 F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 -F src/btree.c b8875cff2d98d662a7e25d73483bccc2374d8bdb +F src/btree.c 2781fb1db1e46390a9c27a2162395f371577ac66 F src/btree.h 2107a2630e02c8cba58bb12ce14e731e734ea29c F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 F src/build.c e827e57e4a29c00e8429c5fd4d9d4572cb1b32a4 @@ -1500,7 +1500,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 2d831074cf730dce47de5880d7b4570d04d15fee -R 55f60418d6dcbf8aee4f5a82499e5642 +P 5fb0c35459cf7a8662bf8cd84ac345f6fafda6cc +R 6c89b96783c3d80d21140f4fa1e28558 U drh -Z 55a25f2496cfdeb6e61ef11536fc4f7e +Z fcd58109b062d41d087b764fb431a88f diff --git a/manifest.uuid b/manifest.uuid index 8076fd6a9e..41857ac25e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5fb0c35459cf7a8662bf8cd84ac345f6fafda6cc \ No newline at end of file +e106a77d85c20ae23ebe49a5acceeaffecb40fc2 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 5fbd6c4173..3a95edf007 100644 --- a/src/btree.c +++ b/src/btree.c @@ -5070,11 +5070,12 @@ int sqlite3BtreeMovetoUnpacked( assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); assert( pRes ); assert( (pIdxKey==0)==(pCur->pKeyInfo==0) ); + assert( (pIdxKey==0)==(pCur->curIntKey!=0) || pCur->eState!=CURSOR_VALID ); /* If the cursor is already positioned at the point we are trying ** to move to, then just return without doing any work */ - if( pCur->eState==CURSOR_VALID && (pCur->curFlags & BTCF_ValidNKey)!=0 - && pCur->curIntKey + if( pIdxKey==0 + && pCur->eState==CURSOR_VALID && (pCur->curFlags & BTCF_ValidNKey)!=0 ){ if( pCur->info.nKey==intKey ){ *pRes = 0; From 4335ad05b893cc3ab48796e746dee309a823a7d8 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 6 Jun 2016 13:24:57 +0000 Subject: [PATCH 0502/1484] Initialize the yyerrcnt variable in the lemon parser template. This has no effect on SQLite itself. FossilOrigin-Name: 45531654f7f5be3a08e9ee8598f14efe028245d8 --- manifest | 12 ++++++------ manifest.uuid | 2 +- tool/lempar.c | 3 +++ 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index eca2ed0fc6..e299eaa5ba 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Small\sperformance\sboost\sand\ssize\sdecrease\sin\ssqlite3BtreeMovetoUnpacked(). -D 2016-06-06T01:54:20.047 +C Initialize\sthe\syyerrcnt\svariable\sin\sthe\slemon\sparser\stemplate.\s\sThis\shas\sno\neffect\son\sSQLite\sitself. +D 2016-06-06T13:24:57.848 F Makefile.in 7321ef0b584224781ec7731408857fa8962c32cc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 831503fc4e988f571590af1405645fff121b5f1e @@ -1428,7 +1428,7 @@ F tool/genfkey.README cf68fddd4643bbe3ff8e31b8b6d8b0a1b85e20f4 F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5 F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce F tool/lemon.c 09a96bed19955697a5e20c49ad863ec2005815a2 -F tool/lempar.c f06b7e98a6b7efb404375b6f4a0c71c85faa1512 +F tool/lempar.c 66a16b5e00fefff278b9e6e3aae14037c0246427 F tool/libvers.c caafc3b689638a1d88d44bc5f526c2278760d9b9 F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862 F tool/logest.c 11346aa019e2e77a00902aa7d0cabd27bd2e8cca @@ -1500,7 +1500,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 5fb0c35459cf7a8662bf8cd84ac345f6fafda6cc -R 6c89b96783c3d80d21140f4fa1e28558 +P e106a77d85c20ae23ebe49a5acceeaffecb40fc2 +R 44ddd09e002da6e14637db41834f8d1e U drh -Z fcd58109b062d41d087b764fb431a88f +Z 4d4207228c1d0bca23b591b2a4bc29d5 diff --git a/manifest.uuid b/manifest.uuid index 41857ac25e..a22289fa3a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e106a77d85c20ae23ebe49a5acceeaffecb40fc2 \ No newline at end of file +45531654f7f5be3a08e9ee8598f14efe028245d8 \ No newline at end of file diff --git a/tool/lempar.c b/tool/lempar.c index 1258c549de..5b6e6d77d3 100644 --- a/tool/lempar.c +++ b/tool/lempar.c @@ -339,6 +339,9 @@ void *ParseAlloc(void *(*mallocProc)(YYMALLOCARGTYPE)){ pParser->yystack = &pParser->yystk0; pParser->yystksz = 1; } +#endif +#ifndef YYNOERRORRECOVERY + pParser->yyerrcnt = -1; #endif pParser->yytos = pParser->yystack; pParser->yystack[0].stateno = 0; From 0efd37f28b2918655de43acc8a32d6e75a3f2735 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 6 Jun 2016 18:17:36 +0000 Subject: [PATCH 0503/1484] Fix lempar.c so that the shift-reduce optimization works for error processing. This is a Lemon issue only and has no impact on SQLite. FossilOrigin-Name: 3665a2f554e5b8d2717d952dbaf325a39c637c31 --- manifest | 12 ++++++------ manifest.uuid | 2 +- tool/lempar.c | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index e299eaa5ba..7b75e3ac80 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Initialize\sthe\syyerrcnt\svariable\sin\sthe\slemon\sparser\stemplate.\s\sThis\shas\sno\neffect\son\sSQLite\sitself. -D 2016-06-06T13:24:57.848 +C Fix\slempar.c\sso\sthat\sthe\sshift-reduce\soptimization\sworks\sfor\serror\sprocessing.\nThis\sis\sa\sLemon\sissue\sonly\sand\shas\sno\simpact\son\sSQLite. +D 2016-06-06T18:17:36.269 F Makefile.in 7321ef0b584224781ec7731408857fa8962c32cc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 831503fc4e988f571590af1405645fff121b5f1e @@ -1428,7 +1428,7 @@ F tool/genfkey.README cf68fddd4643bbe3ff8e31b8b6d8b0a1b85e20f4 F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5 F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce F tool/lemon.c 09a96bed19955697a5e20c49ad863ec2005815a2 -F tool/lempar.c 66a16b5e00fefff278b9e6e3aae14037c0246427 +F tool/lempar.c 8c4e9d8517e50da391f1d89a519e743dd4afbc09 F tool/libvers.c caafc3b689638a1d88d44bc5f526c2278760d9b9 F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862 F tool/logest.c 11346aa019e2e77a00902aa7d0cabd27bd2e8cca @@ -1500,7 +1500,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e106a77d85c20ae23ebe49a5acceeaffecb40fc2 -R 44ddd09e002da6e14637db41834f8d1e +P 45531654f7f5be3a08e9ee8598f14efe028245d8 +R ca88b1e538e49deb8a0ada7b00edb9b6 U drh -Z 4d4207228c1d0bca23b591b2a4bc29d5 +Z 8cae88ab86923e6f759f4ae6a119c6f0 diff --git a/manifest.uuid b/manifest.uuid index a22289fa3a..589f699701 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -45531654f7f5be3a08e9ee8598f14efe028245d8 \ No newline at end of file +3665a2f554e5b8d2717d952dbaf325a39c637c31 \ No newline at end of file diff --git a/tool/lempar.c b/tool/lempar.c index 5b6e6d77d3..9b76d6e3c5 100644 --- a/tool/lempar.c +++ b/tool/lempar.c @@ -601,6 +601,9 @@ static void yy_shift( } } #endif + if( yyNewState > YY_MAX_SHIFT ){ + yyNewState += YY_MIN_REDUCE - YY_MIN_SHIFTREDUCE; + } yytos = yypParser->yytos; yytos->stateno = (YYACTIONTYPE)yyNewState; yytos->major = (YYCODETYPE)yyMajor; @@ -813,9 +816,6 @@ void Parse( do{ yyact = yy_find_shift_action(yypParser,(YYCODETYPE)yymajor); if( yyact <= YY_MAX_SHIFTREDUCE ){ - if( yyact > YY_MAX_SHIFT ){ - yyact += YY_MIN_REDUCE - YY_MIN_SHIFTREDUCE; - } yy_shift(yypParser,yyact,yymajor,yyminor); #ifndef YYNOERRORRECOVERY yypParser->yyerrcnt--; From 8a5fd2611686c62c06ac8b5f0bad9c2db2ac5dce Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 6 Jun 2016 20:27:15 +0000 Subject: [PATCH 0504/1484] Translate filenames of the form "/c:/*" into just "c:/*" on WinRT and Cygwin. (SQLite has long done this for Win32/WinNT.) FossilOrigin-Name: f8470ffc49918099820cc0008b9089e5fe8a7dff --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/os_win.c | 14 ++++++++++++++ 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 7b75e3ac80..f4ea0d3997 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\slempar.c\sso\sthat\sthe\sshift-reduce\soptimization\sworks\sfor\serror\sprocessing.\nThis\sis\sa\sLemon\sissue\sonly\sand\shas\sno\simpact\son\sSQLite. -D 2016-06-06T18:17:36.269 +C Translate\sfilenames\sof\sthe\sform\s"/c:/*"\sinto\sjust\s"c:/*"\son\sWinRT\sand\sCygwin.\n(SQLite\shas\slong\sdone\sthis\sfor\sWin32/WinNT.) +D 2016-06-06T20:27:15.051 F Makefile.in 7321ef0b584224781ec7731408857fa8962c32cc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 831503fc4e988f571590af1405645fff121b5f1e @@ -367,7 +367,7 @@ F src/os.h 8e976e59eb4ca1c0fca6d35ee803e38951cb0343 F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85 F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa F src/os_unix.c a9443cdab41d7f3cdf0df3a5aab62fd6e1c9b234 -F src/os_win.c 852fc2ff6084296348ed3739c548b2cf32df394e +F src/os_win.c 59ccd6a22c90c7eb06721060a881484664f67487 F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c c368634b888b1c8740aea83b36bfd266f2443e60 F src/pager.h 8ab6b6feeee4bc0439bfde7ee59ba99df98b9bc3 @@ -1500,7 +1500,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 45531654f7f5be3a08e9ee8598f14efe028245d8 -R ca88b1e538e49deb8a0ada7b00edb9b6 +P 3665a2f554e5b8d2717d952dbaf325a39c637c31 +R 1ce06fe2980795cbe08c14d88bf14c86 U drh -Z 8cae88ab86923e6f759f4ae6a119c6f0 +Z b8067fa7fb955f58e26e08c4eb3e1ea5 diff --git a/manifest.uuid b/manifest.uuid index 589f699701..06742e2e7b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3665a2f554e5b8d2717d952dbaf325a39c637c31 \ No newline at end of file +f8470ffc49918099820cc0008b9089e5fe8a7dff \ No newline at end of file diff --git a/src/os_win.c b/src/os_win.c index 9a34d9a106..6458d283c8 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -5274,6 +5274,13 @@ static int winFullPathname( SimulateIOError( return SQLITE_ERROR ); UNUSED_PARAMETER(nFull); assert( nFull>=pVfs->mxPathname ); + /* If this path name begins with "/X:", where "X" is any alphabetic + ** character, discard the initial "/" from the pathname. + */ + if( zRelative[0]=='/' && winIsDriveLetterAndColon(zRelative+1) ){ + zRelative++; + } + if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){ /* ** NOTE: We are dealing with a relative path name and the data @@ -5329,6 +5336,13 @@ static int winFullPathname( #if (SQLITE_OS_WINCE || SQLITE_OS_WINRT) && !defined(__CYGWIN__) SimulateIOError( return SQLITE_ERROR ); + /* If this path name begins with "/X:", where "X" is any alphabetic + ** character, discard the initial "/" from the pathname. + */ + if( zRelative[0]=='/' && winIsDriveLetterAndColon(zRelative+1) ){ + zRelative++; + } + /* WinCE has no concept of a relative pathname, or so I am told. */ /* WinRT has no way to convert a relative path to an absolute one. */ if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){ From 4a58d5fdf5a298a0b020c7cdd57586220622dc3f Mon Sep 17 00:00:00 2001 From: mistachkin Date: Mon, 6 Jun 2016 20:36:26 +0000 Subject: [PATCH 0505/1484] In winFullPathname, translate '/X:' to 'X:' before doing anything else. FossilOrigin-Name: e404ad705d0e2d96025d05cc88348ffcd0703533 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/os_win.c | 31 +++++++++---------------------- 3 files changed, 17 insertions(+), 30 deletions(-) diff --git a/manifest b/manifest index f4ea0d3997..a8641b80ec 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Translate\sfilenames\sof\sthe\sform\s"/c:/*"\sinto\sjust\s"c:/*"\son\sWinRT\sand\sCygwin.\n(SQLite\shas\slong\sdone\sthis\sfor\sWin32/WinNT.) -D 2016-06-06T20:27:15.051 +C In\swinFullPathname,\stranslate\s'/X:'\sto\s'X:'\sbefore\sdoing\sanything\selse. +D 2016-06-06T20:36:26.843 F Makefile.in 7321ef0b584224781ec7731408857fa8962c32cc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 831503fc4e988f571590af1405645fff121b5f1e @@ -367,7 +367,7 @@ F src/os.h 8e976e59eb4ca1c0fca6d35ee803e38951cb0343 F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85 F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa F src/os_unix.c a9443cdab41d7f3cdf0df3a5aab62fd6e1c9b234 -F src/os_win.c 59ccd6a22c90c7eb06721060a881484664f67487 +F src/os_win.c d4b8faf8896b65818e67070711fdd00d8e620bd6 F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c c368634b888b1c8740aea83b36bfd266f2443e60 F src/pager.h 8ab6b6feeee4bc0439bfde7ee59ba99df98b9bc3 @@ -1500,7 +1500,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 3665a2f554e5b8d2717d952dbaf325a39c637c31 -R 1ce06fe2980795cbe08c14d88bf14c86 -U drh -Z b8067fa7fb955f58e26e08c4eb3e1ea5 +P f8470ffc49918099820cc0008b9089e5fe8a7dff +R c81f8bc1e79df8beab98e4603e5f0a7e +U mistachkin +Z 376528e39cb88246cfc2bf50694a3c28 diff --git a/manifest.uuid b/manifest.uuid index 06742e2e7b..785cf6ce09 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f8470ffc49918099820cc0008b9089e5fe8a7dff \ No newline at end of file +e404ad705d0e2d96025d05cc88348ffcd0703533 \ No newline at end of file diff --git a/src/os_win.c b/src/os_win.c index 6458d283c8..edc182a017 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -5269,11 +5269,12 @@ static int winFullPathname( int nFull, /* Size of output buffer in bytes */ char *zFull /* Output buffer */ ){ +#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && !defined(__CYGWIN__) + DWORD nByte; + void *zConverted; + char *zOut; +#endif -#if defined(__CYGWIN__) - SimulateIOError( return SQLITE_ERROR ); - UNUSED_PARAMETER(nFull); - assert( nFull>=pVfs->mxPathname ); /* If this path name begins with "/X:", where "X" is any alphabetic ** character, discard the initial "/" from the pathname. */ @@ -5281,6 +5282,10 @@ static int winFullPathname( zRelative++; } +#if defined(__CYGWIN__) + SimulateIOError( return SQLITE_ERROR ); + UNUSED_PARAMETER(nFull); + assert( nFull>=pVfs->mxPathname ); if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){ /* ** NOTE: We are dealing with a relative path name and the data @@ -5336,13 +5341,6 @@ static int winFullPathname( #if (SQLITE_OS_WINCE || SQLITE_OS_WINRT) && !defined(__CYGWIN__) SimulateIOError( return SQLITE_ERROR ); - /* If this path name begins with "/X:", where "X" is any alphabetic - ** character, discard the initial "/" from the pathname. - */ - if( zRelative[0]=='/' && winIsDriveLetterAndColon(zRelative+1) ){ - zRelative++; - } - /* WinCE has no concept of a relative pathname, or so I am told. */ /* WinRT has no way to convert a relative path to an absolute one. */ if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){ @@ -5361,17 +5359,6 @@ static int winFullPathname( #endif #if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && !defined(__CYGWIN__) - DWORD nByte; - void *zConverted; - char *zOut; - - /* If this path name begins with "/X:", where "X" is any alphabetic - ** character, discard the initial "/" from the pathname. - */ - if( zRelative[0]=='/' && winIsDriveLetterAndColon(zRelative+1) ){ - zRelative++; - } - /* It's odd to simulate an io-error here, but really this is just ** using the io-error infrastructure to test that SQLite handles this ** function failing. This function could fail if, for example, the From a83a5c3fbcef8b408a5dbfd212ed67950c116d3d Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 7 Jun 2016 20:25:19 +0000 Subject: [PATCH 0506/1484] Fix the walcrash4.test test module so that it works on windows. FossilOrigin-Name: 2091a4c9231c7871f27661adc27dd7df26500f6c --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/walcrash4.test | 10 +++++++++- 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index a8641b80ec..36bb44109e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\swinFullPathname,\stranslate\s'/X:'\sto\s'X:'\sbefore\sdoing\sanything\selse. -D 2016-06-06T20:36:26.843 +C Fix\sthe\swalcrash4.test\stest\smodule\sso\sthat\sit\sworks\son\swindows. +D 2016-06-07T20:25:19.931 F Makefile.in 7321ef0b584224781ec7731408857fa8962c32cc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 831503fc4e988f571590af1405645fff121b5f1e @@ -1361,7 +1361,7 @@ F test/walcksum.test bb234a1bb42248b3515d992b719708015c384278 F test/walcrash.test 21038858cc552077b0522f50b0fa87e38139306a F test/walcrash2.test a0edab4e5390f03b99a790de89aad15d6ec70b36 F test/walcrash3.test e426aa58122d20f2b9fbe9a507f9eb8cab85b8af -F test/walcrash4.test fa7d92ab84fe3ff409e1cda88a622545e2bc2b66 +F test/walcrash4.test 3374d6a0813bfe9d841a973958e0552b545a6423 F test/walfault.test 1f8389f7709877e9b4cc679033d71d6fe529056b F test/walhook.test ed00a40ba7255da22d6b66433ab61fab16a63483 F test/walmode.test 4022fe03ae6e830583672caa101f046438a0473c @@ -1500,7 +1500,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P f8470ffc49918099820cc0008b9089e5fe8a7dff -R c81f8bc1e79df8beab98e4603e5f0a7e -U mistachkin -Z 376528e39cb88246cfc2bf50694a3c28 +P e404ad705d0e2d96025d05cc88348ffcd0703533 +R 17828d50ca8a72aedc66939901a97177 +U drh +Z c43be01e1ddab6118f1ee2a4247dca79 diff --git a/manifest.uuid b/manifest.uuid index 785cf6ce09..459a559a5d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e404ad705d0e2d96025d05cc88348ffcd0703533 \ No newline at end of file +2091a4c9231c7871f27661adc27dd7df26500f6c \ No newline at end of file diff --git a/test/walcrash4.test b/test/walcrash4.test index d2f07730a0..3abc16d1eb 100644 --- a/test/walcrash4.test +++ b/test/walcrash4.test @@ -35,6 +35,14 @@ do_execsql_test 1.0 { faultsim_save_and_close +# The error message is different on unix and windows +# +if {$::tcl_platform(platform)=="windows"} { + set msg "child killed: unknown signal" +} else { + set msg "child process exited abnormally" +} + for {set nExtra 0} {$nExtra < 10} {incr nExtra} { for {set i 0} {$i < 10} {incr i} { do_test 1.nExtra=$nExtra.i=$i.1 { @@ -63,7 +71,7 @@ for {set nExtra 0} {$nExtra < 10} {incr nExtra} { set r [catch { exec [info nameofexec] crash.tcl >@stdout } msg] list $r $msg - } {1 {child process exited abnormally}} + } "1 {$msg}" do_execsql_test 1.nExtra=$nExtra.i=$i.2 { SELECT count(*) FROM t1; From 290fcaa2d130bc488c22e615d37c240186714260 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 8 Jun 2016 01:03:05 +0000 Subject: [PATCH 0507/1484] An initial attempt at a "dbhash" command-line utility. FossilOrigin-Name: 2247649ca215c06205b33b2250eb809baf39263a --- Makefile.in | 7 +- Makefile.msc | 8 +- main.mk | 7 +- manifest | 20 ++- manifest.uuid | 2 +- tool/dbhash.c | 424 ++++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 455 insertions(+), 13 deletions(-) create mode 100644 tool/dbhash.c diff --git a/Makefile.in b/Makefile.in index 115cfac58f..29c9174afa 100644 --- a/Makefile.in +++ b/Makefile.in @@ -539,7 +539,8 @@ TESTPROGS = \ testfixture$(TEXE) \ sqlite3$(TEXE) \ sqlite3_analyzer$(TEXE) \ - sqldiff$(TEXE) + sqldiff$(TEXE) \ + dbhash$(TEXE) # Databases containing fuzzer test cases # @@ -590,6 +591,9 @@ sqlite3$(TEXE): $(TOP)/src/shell.c sqlite3.c sqldiff$(TEXE): $(TOP)/tool/sqldiff.c sqlite3.c sqlite3.h $(LTLINK) -o $@ $(TOP)/tool/sqldiff.c sqlite3.c $(TLIBS) +dbhash$(TEXE): $(TOP)/tool/dbhash.c sqlite3.c sqlite3.h + $(LTLINK) -o $@ $(TOP)/tool/dbhash.c sqlite3.c $(TLIBS) + scrub$(TEXE): $(TOP)/ext/misc/scrub.c sqlite3.o $(LTLINK) -o $@ -I. -DSCRUB_STANDALONE \ $(TOP)/ext/misc/scrub.c sqlite3.o $(TLIBS) @@ -1251,6 +1255,7 @@ clean: rm -f fuzzershell fuzzershell.exe rm -f fuzzcheck fuzzcheck.exe rm -f sqldiff sqldiff.exe + rm -f dbhash dbhash.exe rm -f fts5.* fts5parse.* distclean: clean diff --git a/Makefile.msc b/Makefile.msc index 9bf1e4f8fe..93116cd0dc 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -1378,7 +1378,8 @@ TESTPROGS = \ testfixture.exe \ $(SQLITE3EXE) \ sqlite3_analyzer.exe \ - sqldiff.exe + sqldiff.exe \ + dbhash.exe # Databases containing fuzzer test cases # @@ -1456,6 +1457,9 @@ $(SQLITE3EXE): $(TOP)\src\shell.c $(SHELL_CORE_DEP) $(LIBRESOBJS) $(SHELL_CORE_S sqldiff.exe: $(TOP)\tool\sqldiff.c $(SQLITE3C) $(SQLITE3H) $(LTLINK) $(NO_WARN) $(TOP)\tool\sqldiff.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) +dbhash.exe: $(TOP)\tool\dbhash.c $(SQLITE3C) $(SQLITE3H) + $(LTLINK) $(NO_WARN) $(TOP)\tool\dbhash.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) + scrub.exe: $(TOP)\ext\misc\scrub.c $(SQLITE3C) $(SQLITE3H) $(LTLINK) $(NO_WARN) $(TOP)\ext\misc\scrub.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) @@ -2105,6 +2109,6 @@ clean: del /Q shell.c sqlite3ext.h sqlite3session.h 2>NUL del /Q sqlite3_analyzer.exe sqlite3_analyzer.c 2>NUL del /Q sqlite-*-output.vsix 2>NUL - del /Q fuzzershell.exe fuzzcheck.exe sqldiff.exe 2>NUL + del /Q fuzzershell.exe fuzzcheck.exe sqldiff.exe dbhash.exe 2>NUL del /Q fts5.* fts5parse.* 2>NUL # <> diff --git a/main.mk b/main.mk index 624bf77a06..ba710bfa46 100644 --- a/main.mk +++ b/main.mk @@ -451,7 +451,8 @@ TESTPROGS = \ testfixture$(EXE) \ sqlite3$(EXE) \ sqlite3_analyzer$(EXE) \ - sqldiff$(EXE) + sqldiff$(EXE) \ + dbhash$(EXE) # Databases containing fuzzer test cases # @@ -488,6 +489,10 @@ sqldiff$(EXE): $(TOP)/tool/sqldiff.c sqlite3.c sqlite3.h $(TCCX) -o sqldiff$(EXE) -DSQLITE_THREADSAFE=0 \ $(TOP)/tool/sqldiff.c sqlite3.c $(TLIBS) $(THREADLIB) +dbhash$(EXE): $(TOP)/tool/dbhash.c sqlite3.c sqlite3.h + $(TCCX) -o dbhash$(EXE) -DSQLITE_THREADSAFE=0 \ + $(TOP)/tool/dbhash.c sqlite3.c $(TLIBS) $(THREADLIB) + scrub$(EXE): $(TOP)/ext/misc/scrub.c sqlite3.o $(TCC) -I. -DSCRUB_STANDALONE -o scrub$(EXE) $(TOP)/ext/misc/scrub.c sqlite3.o $(THREADLIB) diff --git a/manifest b/manifest index 36bb44109e..7d7f2a3501 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -C Fix\sthe\swalcrash4.test\stest\smodule\sso\sthat\sit\sworks\son\swindows. -D 2016-06-07T20:25:19.931 -F Makefile.in 7321ef0b584224781ec7731408857fa8962c32cc +C An\sinitial\sattempt\sat\sa\s"dbhash"\scommand-line\sutility. +D 2016-06-08T01:03:05.100 +F Makefile.in f3f7d2060ce03af4584e711ef3a626ef0b1d6340 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 -F Makefile.msc 831503fc4e988f571590af1405645fff121b5f1e +F Makefile.msc 50149765ef72f4e652b9a0f1f6462c4784bb9423 F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7 F VERSION cb29eb11e493dd85b3eeec4053c03949bf98478e F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 @@ -307,7 +307,7 @@ F ext/userauth/userauth.c 5fa3bdb492f481bbc1709fc83c91ebd13460c69e F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60 -F main.mk 2b90646ca027cc21dbae209a0fee68dfedfe0e83 +F main.mk 3f669c06db5c4a53ff21dda639247c6310497180 F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 @@ -1420,6 +1420,7 @@ F tool/build-all-msvc.bat 3e4e4043b53f1aede4308e0d2567bbd773614630 x F tool/build-shell.sh 950f47c6174f1eea171319438b93ba67ff5bf367 F tool/cg_anno.tcl 692ce4b8693d59e3a3de77ca97f4139ecfa641b0 x F tool/checkSpacing.c 810e51703529a204fc4e1eb060e9ab663e3c06d2 +F tool/dbhash.c 11ae59057c1ebbd54ac10bdc59c8fc7e0a43a156 F tool/extract.c 054069d81b095fbdc189a6f5d4466e40380505e2 F tool/fast_vacuum.c 5ba0d6f5963a0a63bdc42840f678bad75b2ebce1 F tool/fragck.tcl 5265a95126abcf6ab357f7efa544787e5963f439 @@ -1500,7 +1501,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e404ad705d0e2d96025d05cc88348ffcd0703533 -R 17828d50ca8a72aedc66939901a97177 +P 2091a4c9231c7871f27661adc27dd7df26500f6c +R 2cb484710443ce45b289f472a9c90e73 +T *branch * dbhash +T *sym-dbhash * +T -sym-trunk * U drh -Z c43be01e1ddab6118f1ee2a4247dca79 +Z 1329a111dd8194eb5ec209c8b1ad3288 diff --git a/manifest.uuid b/manifest.uuid index 459a559a5d..ca0df0561c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2091a4c9231c7871f27661adc27dd7df26500f6c \ No newline at end of file +2247649ca215c06205b33b2250eb809baf39263a \ No newline at end of file diff --git a/tool/dbhash.c b/tool/dbhash.c new file mode 100644 index 0000000000..0e1b02b673 --- /dev/null +++ b/tool/dbhash.c @@ -0,0 +1,424 @@ +/* +** 2016-06-07 +** +** 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 is a utility program that computes a hash on the content +** of an SQLite database. +** +** The hash is computed over just the content of the database. Free +** space inside of the database file, and alternative on-disk representations +** of the same content (ex: UTF8 vs UTF16) do not affect the hash. So, +** for example, the database file page size, encoding, and auto_vacuum setting +** can all be changed without changing the hash. +*/ +#include +#include +#include +#include +#include +#include +#include "sqlite3.h" + +/* Context for the SHA1 hash */ +typedef struct SHA1Context SHA1Context; +struct SHA1Context { + unsigned int state[5]; + unsigned int count[2]; + unsigned char buffer[64]; +}; + +/* +** All global variables are gathered into the "g" singleton. +*/ +struct GlobalVars { + const char *zArgv0; /* Name of program */ + int bSchemaPK; /* Use the schema-defined PK, not the true PK */ + unsigned fDebug; /* Debug flags */ + sqlite3 *db; /* The database connection */ + SHA1Context cx; /* SHA1 hash context */ +} g; + +/****************************************************************************** +** The Hash Engine +** +** Modify these routines (and appropriate state fields in global variable 'g') +** in order to compute a different (better?) hash of the database. +*/ +/* + * blk0() and blk() perform the initial expand. + * I got the idea of expanding during the round function from SSLeay + * + * blk0le() for little-endian and blk0be() for big-endian. + */ +#if __GNUC__ && (defined(__i386__) || defined(__x86_64__)) +/* + * GCC by itself only generates left rotates. Use right rotates if + * possible to be kinder to dinky implementations with iterative rotate + * instructions. + */ +#define SHA_ROT(op, x, k) \ + ({ unsigned int y; asm(op " %1,%0" : "=r" (y) : "I" (k), "0" (x)); y; }) +#define rol(x,k) SHA_ROT("roll", x, k) +#define ror(x,k) SHA_ROT("rorl", x, k) + +#else +/* Generic C equivalent */ +#define SHA_ROT(x,l,r) ((x) << (l) | (x) >> (r)) +#define rol(x,k) SHA_ROT(x,k,32-(k)) +#define ror(x,k) SHA_ROT(x,32-(k),k) +#endif + + +#define blk0le(i) (block[i] = (ror(block[i],8)&0xFF00FF00) \ + |(rol(block[i],8)&0x00FF00FF)) +#define blk0be(i) block[i] +#define blk(i) (block[i&15] = rol(block[(i+13)&15]^block[(i+8)&15] \ + ^block[(i+2)&15]^block[i&15],1)) + +/* + * (R0+R1), R2, R3, R4 are the different operations (rounds) used in SHA1 + * + * Rl0() for little-endian and Rb0() for big-endian. Endianness is + * determined at run-time. + */ +#define Rl0(v,w,x,y,z,i) \ + z+=((w&(x^y))^y)+blk0le(i)+0x5A827999+rol(v,5);w=ror(w,2); +#define Rb0(v,w,x,y,z,i) \ + z+=((w&(x^y))^y)+blk0be(i)+0x5A827999+rol(v,5);w=ror(w,2); +#define R1(v,w,x,y,z,i) \ + z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=ror(w,2); +#define R2(v,w,x,y,z,i) \ + z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=ror(w,2); +#define R3(v,w,x,y,z,i) \ + z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=ror(w,2); +#define R4(v,w,x,y,z,i) \ + z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=ror(w,2); + +/* + * Hash a single 512-bit block. This is the core of the algorithm. + */ +#define a qq[0] +#define b qq[1] +#define c qq[2] +#define d qq[3] +#define e qq[4] + +void SHA1Transform(unsigned int state[5], const unsigned char buffer[64]){ + unsigned int qq[5]; /* a, b, c, d, e; */ + static int one = 1; + unsigned int block[16]; + memcpy(block, buffer, 64); + memcpy(qq,state,5*sizeof(unsigned int)); + + /* Copy g.cx.state[] to working vars */ + /* + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; + */ + + /* 4 rounds of 20 operations each. Loop unrolled. */ + if( 1 == *(unsigned char*)&one ){ + Rl0(a,b,c,d,e, 0); Rl0(e,a,b,c,d, 1); Rl0(d,e,a,b,c, 2); Rl0(c,d,e,a,b, 3); + Rl0(b,c,d,e,a, 4); Rl0(a,b,c,d,e, 5); Rl0(e,a,b,c,d, 6); Rl0(d,e,a,b,c, 7); + Rl0(c,d,e,a,b, 8); Rl0(b,c,d,e,a, 9); Rl0(a,b,c,d,e,10); Rl0(e,a,b,c,d,11); + Rl0(d,e,a,b,c,12); Rl0(c,d,e,a,b,13); Rl0(b,c,d,e,a,14); Rl0(a,b,c,d,e,15); + }else{ + Rb0(a,b,c,d,e, 0); Rb0(e,a,b,c,d, 1); Rb0(d,e,a,b,c, 2); Rb0(c,d,e,a,b, 3); + Rb0(b,c,d,e,a, 4); Rb0(a,b,c,d,e, 5); Rb0(e,a,b,c,d, 6); Rb0(d,e,a,b,c, 7); + Rb0(c,d,e,a,b, 8); Rb0(b,c,d,e,a, 9); Rb0(a,b,c,d,e,10); Rb0(e,a,b,c,d,11); + Rb0(d,e,a,b,c,12); Rb0(c,d,e,a,b,13); Rb0(b,c,d,e,a,14); Rb0(a,b,c,d,e,15); + } + R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); + R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); + R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); + R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); + R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); + R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); + R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); + R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); + R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); + R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); + R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); + R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); + R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); + R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); + R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); + R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); + + /* Add the working vars back into context.state[] */ + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + state[4] += e; +} + + +/* Initialize the SHA1 hash */ +static void hash_init(void){ + /* SHA1 initialization constants */ + g.cx.state[0] = 0x67452301; + g.cx.state[1] = 0xEFCDAB89; + g.cx.state[2] = 0x98BADCFE; + g.cx.state[3] = 0x10325476; + g.cx.state[4] = 0xC3D2E1F0; + g.cx.count[0] = g.cx.count[1] = 0; +} + +/* Add new content to the SHA1 hash */ +static void hash_step(const unsigned char *data, unsigned int len){ + unsigned int i, j; + + j = g.cx.count[0]; + if( (g.cx.count[0] += len << 3) < j ){ + g.cx.count[1] += (len>>29)+1; + } + j = (j >> 3) & 63; + if( (j + len) > 63 ){ + (void)memcpy(&g.cx.buffer[j], data, (i = 64-j)); + SHA1Transform(g.cx.state, g.cx.buffer); + for(; i + 63 < len; i += 64){ + SHA1Transform(g.cx.state, &data[i]); + } + j = 0; + }else{ + i = 0; + } + (void)memcpy(&g.cx.buffer[j], &data[i], len - i); +} + + +/* Add padding and compute and output the message digest. */ +static void hash_finish(void){ + unsigned int i; + unsigned char finalcount[8]; + unsigned char digest[20]; + static const char zEncode[] = "0123456789abcdef"; + char zOut[40]; + + for (i = 0; i < 8; i++){ + finalcount[i] = (unsigned char)((g.cx.count[(i >= 4 ? 0 : 1)] + >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */ + } + hash_step((const unsigned char *)"\200", 1); + while ((g.cx.count[0] & 504) != 448){ + hash_step((const unsigned char *)"\0", 1); + } + hash_step(finalcount, 8); /* Should cause a SHA1Transform() */ + for (i = 0; i < 20; i++){ + digest[i] = (unsigned char)((g.cx.state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); + } + for(i=0; i<20; i++){ + zOut[i*2] = zEncode[(digest[i]>>4)&0xf]; + zOut[i*2+1] = zEncode[digest[i] & 0xf]; + } + zOut[i*2]= 0; + printf("%s\n", zOut); +} +/* End of the hashing logic +*******************************************************************************/ + +/* +** Print an error resulting from faulting command-line arguments and +** abort the program. +*/ +static void cmdlineError(const char *zFormat, ...){ + va_list ap; + fprintf(stderr, "%s: ", g.zArgv0); + va_start(ap, zFormat); + vfprintf(stderr, zFormat, ap); + va_end(ap); + fprintf(stderr, "\n\"%s --help\" for more help\n", g.zArgv0); + exit(1); +} + +/* +** Print an error message for an error that occurs at runtime, then +** abort the program. +*/ +static void runtimeError(const char *zFormat, ...){ + va_list ap; + fprintf(stderr, "%s: ", g.zArgv0); + va_start(ap, zFormat); + vfprintf(stderr, zFormat, ap); + va_end(ap); + fprintf(stderr, "\n"); + exit(1); +} + +/* +** Prepare a new SQL statement. Print an error and abort if anything +** goes wrong. +*/ +static sqlite3_stmt *db_vprepare(const char *zFormat, va_list ap){ + char *zSql; + int rc; + sqlite3_stmt *pStmt; + + zSql = sqlite3_vmprintf(zFormat, ap); + if( zSql==0 ) runtimeError("out of memory"); + rc = sqlite3_prepare_v2(g.db, zSql, -1, &pStmt, 0); + if( rc ){ + runtimeError("SQL statement error: %s\n\"%s\"", sqlite3_errmsg(g.db), + zSql); + } + sqlite3_free(zSql); + return pStmt; +} +static sqlite3_stmt *db_prepare(const char *zFormat, ...){ + va_list ap; + sqlite3_stmt *pStmt; + va_start(ap, zFormat); + pStmt = db_vprepare(zFormat, ap); + va_end(ap); + return pStmt; +} + +/* +** Compute the hash for a single table named zTab +*/ +static void hash_one_table(const char *zTab){ + sqlite3_stmt *pStmt; + int nCol; + int i; + pStmt = db_prepare("SELECT * FROM \"%w\";", zTab); + nCol = sqlite3_column_count(pStmt); + while( SQLITE_ROW==sqlite3_step(pStmt) ){ + for(i=0; i=0; j--){ + x[j] = u & 0xff; + u >>= 8; + } + hash_step((const unsigned char*)"1",1); + hash_step(x,8); + break; + } + case SQLITE_FLOAT: { + sqlite3_uint64 u; + int j; + unsigned char x[8]; + double r = sqlite3_column_double(pStmt,i); + memcpy(&u, &r, 8); + for(j=7; j>=0; j--){ + x[j] = u & 0xff; + u >>= 8; + } + hash_step((const unsigned char*)"2",1); + hash_step(x,8); + break; + } + case SQLITE_TEXT: { + int n = sqlite3_column_bytes(pStmt, i); + const unsigned char *z = sqlite3_column_text(pStmt, i); + hash_step((const unsigned char*)"3", 1); + hash_step(z, n); + break; + } + case SQLITE_BLOB: { + int n = sqlite3_column_bytes(pStmt, i); + const unsigned char *z = sqlite3_column_blob(pStmt, i); + hash_step((const unsigned char*)"4", 1); + hash_step(z, n); + break; + } + } + } + } + sqlite3_finalize(pStmt); +} + + +/* +** Print sketchy documentation for this utility program +*/ +static void showHelp(void){ + printf("Usage: %s DB\n", g.zArgv0); + printf( +"Compute a hash on the content of database DB\n" + ); +} + +int main(int argc, char **argv){ + const char *zDb = 0; + int i; + int rc; + char *zErrMsg; + sqlite3_stmt *pStmt; + + g.zArgv0 = argv[0]; + sqlite3_config(SQLITE_CONFIG_SINGLETHREAD); + for(i=1; i Date: Wed, 8 Jun 2016 13:49:28 +0000 Subject: [PATCH 0508/1484] Fix the dbhash utility so that it ignores the root page number when hashing the sqlite_master table. Add new command-line options. Add the ability to hash multiple databases with a single command. FossilOrigin-Name: 44f157e0f0d5a76ef9002b2592164c4fdae89e34 --- manifest | 15 ++--- manifest.uuid | 2 +- tool/dbhash.c | 170 +++++++++++++++++++++++++++++++++++++------------- 3 files changed, 133 insertions(+), 54 deletions(-) diff --git a/manifest b/manifest index 7d7f2a3501..efda9daef2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C An\sinitial\sattempt\sat\sa\s"dbhash"\scommand-line\sutility. -D 2016-06-08T01:03:05.100 +C Fix\sthe\sdbhash\sutility\sso\sthat\sit\signores\sthe\sroot\spage\snumber\swhen\shashing\nthe\ssqlite_master\stable.\s\sAdd\snew\scommand-line\soptions.\s\sAdd\sthe\sability\sto\nhash\smultiple\sdatabases\swith\sa\ssingle\scommand. +D 2016-06-08T13:49:28.865 F Makefile.in f3f7d2060ce03af4584e711ef3a626ef0b1d6340 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 50149765ef72f4e652b9a0f1f6462c4784bb9423 @@ -1420,7 +1420,7 @@ F tool/build-all-msvc.bat 3e4e4043b53f1aede4308e0d2567bbd773614630 x F tool/build-shell.sh 950f47c6174f1eea171319438b93ba67ff5bf367 F tool/cg_anno.tcl 692ce4b8693d59e3a3de77ca97f4139ecfa641b0 x F tool/checkSpacing.c 810e51703529a204fc4e1eb060e9ab663e3c06d2 -F tool/dbhash.c 11ae59057c1ebbd54ac10bdc59c8fc7e0a43a156 +F tool/dbhash.c 3e7a97ebdaff842f99ee1eab3787717582d665b8 F tool/extract.c 054069d81b095fbdc189a6f5d4466e40380505e2 F tool/fast_vacuum.c 5ba0d6f5963a0a63bdc42840f678bad75b2ebce1 F tool/fragck.tcl 5265a95126abcf6ab357f7efa544787e5963f439 @@ -1501,10 +1501,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 2091a4c9231c7871f27661adc27dd7df26500f6c -R 2cb484710443ce45b289f472a9c90e73 -T *branch * dbhash -T *sym-dbhash * -T -sym-trunk * +P 2247649ca215c06205b33b2250eb809baf39263a +R 8393151ede059e20b861d67944f07343 U drh -Z 1329a111dd8194eb5ec209c8b1ad3288 +Z e6c66d0412cbc063d2ea74dc380f683a diff --git a/manifest.uuid b/manifest.uuid index ca0df0561c..8a0b15bbb6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2247649ca215c06205b33b2250eb809baf39263a \ No newline at end of file +44f157e0f0d5a76ef9002b2592164c4fdae89e34 \ No newline at end of file diff --git a/tool/dbhash.c b/tool/dbhash.c index 0e1b02b673..8873c39c2a 100644 --- a/tool/dbhash.c +++ b/tool/dbhash.c @@ -10,7 +10,7 @@ ** ************************************************************************* ** -** This is a utility program that computes a hash on the content +** This is a utility program that computes an SHA1 hash on the content ** of an SQLite database. ** ** The hash is computed over just the content of the database. Free @@ -40,12 +40,16 @@ struct SHA1Context { */ struct GlobalVars { const char *zArgv0; /* Name of program */ - int bSchemaPK; /* Use the schema-defined PK, not the true PK */ unsigned fDebug; /* Debug flags */ sqlite3 *db; /* The database connection */ SHA1Context cx; /* SHA1 hash context */ } g; +/* +** Debugging flags +*/ +#define DEBUG_FULLTRACE 0x00000001 /* Trace hash to stderr */ + /****************************************************************************** ** The Hash Engine ** @@ -200,7 +204,7 @@ static void hash_step(const unsigned char *data, unsigned int len){ /* Add padding and compute and output the message digest. */ -static void hash_finish(void){ +static void hash_finish(const char *zName){ unsigned int i; unsigned char finalcount[8]; unsigned char digest[20]; @@ -224,7 +228,7 @@ static void hash_finish(void){ zOut[i*2+1] = zEncode[digest[i] & 0xf]; } zOut[i*2]= 0; - printf("%s\n", zOut); + printf("%s %s\n", zOut, zName); } /* End of the hashing logic *******************************************************************************/ @@ -286,19 +290,28 @@ static sqlite3_stmt *db_prepare(const char *zFormat, ...){ } /* -** Compute the hash for a single table named zTab +** Compute the hash for all rows of the query formed from the printf-style +** zFormat and its argument. */ -static void hash_one_table(const char *zTab){ - sqlite3_stmt *pStmt; - int nCol; - int i; - pStmt = db_prepare("SELECT * FROM \"%w\";", zTab); +static void hash_one_query(const char *zFormat, ...){ + va_list ap; + sqlite3_stmt *pStmt; /* The query defined by zFormat and "..." */ + int nCol; /* Number of columns in the result set */ + int i; /* Loop counter */ + + /* Prepare the query defined by zFormat and "..." */ + va_start(ap, zFormat); + pStmt = db_vprepare(zFormat, ap); + va_end(ap); nCol = sqlite3_column_count(pStmt); + + /* Compute a hash over the result of the query */ while( SQLITE_ROW==sqlite3_step(pStmt) ){ for(i=0; i Date: Wed, 8 Jun 2016 13:59:35 +0000 Subject: [PATCH 0509/1484] Fix an undersized buffer in the SHA1 implementation. FossilOrigin-Name: fb2768154c513881886e89801e906bea959197b3 --- manifest | 12 ++++++------ manifest.uuid | 2 +- tool/dbhash.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index efda9daef2..c020071d16 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\sdbhash\sutility\sso\sthat\sit\signores\sthe\sroot\spage\snumber\swhen\shashing\nthe\ssqlite_master\stable.\s\sAdd\snew\scommand-line\soptions.\s\sAdd\sthe\sability\sto\nhash\smultiple\sdatabases\swith\sa\ssingle\scommand. -D 2016-06-08T13:49:28.865 +C Fix\san\sundersized\sbuffer\sin\sthe\sSHA1\simplementation. +D 2016-06-08T13:59:35.817 F Makefile.in f3f7d2060ce03af4584e711ef3a626ef0b1d6340 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 50149765ef72f4e652b9a0f1f6462c4784bb9423 @@ -1420,7 +1420,7 @@ F tool/build-all-msvc.bat 3e4e4043b53f1aede4308e0d2567bbd773614630 x F tool/build-shell.sh 950f47c6174f1eea171319438b93ba67ff5bf367 F tool/cg_anno.tcl 692ce4b8693d59e3a3de77ca97f4139ecfa641b0 x F tool/checkSpacing.c 810e51703529a204fc4e1eb060e9ab663e3c06d2 -F tool/dbhash.c 3e7a97ebdaff842f99ee1eab3787717582d665b8 +F tool/dbhash.c a06228aa21ebc4e6ea8daa486601d938499238a5 F tool/extract.c 054069d81b095fbdc189a6f5d4466e40380505e2 F tool/fast_vacuum.c 5ba0d6f5963a0a63bdc42840f678bad75b2ebce1 F tool/fragck.tcl 5265a95126abcf6ab357f7efa544787e5963f439 @@ -1501,7 +1501,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 2247649ca215c06205b33b2250eb809baf39263a -R 8393151ede059e20b861d67944f07343 +P 44f157e0f0d5a76ef9002b2592164c4fdae89e34 +R 654981991ade95156b7aa25e1b0590de U drh -Z e6c66d0412cbc063d2ea74dc380f683a +Z 0f8b86024c43c03c854a2dd32c154497 diff --git a/manifest.uuid b/manifest.uuid index 8a0b15bbb6..4f4dd55a84 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -44f157e0f0d5a76ef9002b2592164c4fdae89e34 \ No newline at end of file +fb2768154c513881886e89801e906bea959197b3 \ No newline at end of file diff --git a/tool/dbhash.c b/tool/dbhash.c index 8873c39c2a..b1c72b3e36 100644 --- a/tool/dbhash.c +++ b/tool/dbhash.c @@ -209,7 +209,7 @@ static void hash_finish(const char *zName){ unsigned char finalcount[8]; unsigned char digest[20]; static const char zEncode[] = "0123456789abcdef"; - char zOut[40]; + char zOut[41]; for (i = 0; i < 8; i++){ finalcount[i] = (unsigned char)((g.cx.count[(i >= 4 ? 0 : 1)] From 8dc570b6afac593f029a67640ab916278af1ca65 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 8 Jun 2016 18:07:21 +0000 Subject: [PATCH 0510/1484] Prefer to use partial indexes for full table scans when that is possible. FossilOrigin-Name: fe1874321ba31cec9ae65387920c33d8d0178ed8 --- manifest | 17 ++++++++--------- manifest.uuid | 2 +- src/build.c | 7 ++++--- src/where.c | 1 + test/index6.test | 11 +++++++++++ 5 files changed, 25 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index b9ef6e83ef..718d324c20 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\s"dbhash.exe"\sutility\sprogram\sthat\scomputes\sa\sSHA1\shash\sover\sthe\ninvariant\scontent\sof\san\sSQLite\sdatabase\sfile.\s\sFree\sspace\sin\sthe\sfile,\sthe\npage\ssize,\sauto_vacuum\sstatus,\stext\sencoding,\sand\sso\sforth\sdo\snot\schange\sthe\nhash.\s\sOnly\sthe\scontent\smatters. -D 2016-06-08T14:04:50.483 +C Prefer\sto\suse\spartial\sindexes\sfor\sfull\stable\sscans\swhen\sthat\sis\spossible. +D 2016-06-08T18:07:21.900 F Makefile.in f3f7d2060ce03af4584e711ef3a626ef0b1d6340 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 50149765ef72f4e652b9a0f1f6462c4784bb9423 @@ -329,7 +329,7 @@ F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 F src/btree.c 2781fb1db1e46390a9c27a2162395f371577ac66 F src/btree.h 2107a2630e02c8cba58bb12ce14e731e734ea29c F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 -F src/build.c e827e57e4a29c00e8429c5fd4d9d4572cb1b32a4 +F src/build.c 535879738a9f9e351624ebe827bdfb6ef16475ae F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 999a828425b35b8092a8cde25690e71c20906344 @@ -462,7 +462,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 02eeecc265f6ffd0597378f5d8ae9070b62a406a F src/wal.h 2f7c831cf3b071fa548bf2d5cac640846a7ff19c F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354 -F src/where.c b9f5b0ddb14c3827e70b5379e659cf4cfd524c4d +F src/where.c 74f0798525b6306682d7234f230ea93f86959b9b F src/whereInt.h e5b939701a7ceffc5a3a8188a37f9746416ebcd0 F src/wherecode.c ba71a4e4bada29aa9842200e6299714bf18c812c F src/whereexpr.c c32d47085dbaca0b8fd013210f56693c7d220d48 @@ -840,7 +840,7 @@ F test/index2.test f835d5e13ca163bd78c4459ca15fd2e4ed487407 F test/index3.test 81bc47890b8abfb181bc35f8d10b56c069803386 F test/index4.test ab92e736d5946840236cd61ac3191f91a7856bf6 F test/index5.test 8621491915800ec274609e42e02a97d67e9b13e7 -F test/index6.test 7102ec371414c42dfb1d5ca37eb4519aa9edc23a +F test/index6.test 43b4e29258b978fcdab84fc61df4f5212119dd09 F test/index7.test 9c6765a74fc3fcde7aebc5b3bd40d98df14a527c F test/indexedby.test 9c4cd331224e57f79fbf411ae245e6272d415985 F test/indexexpr1.test cb71b6586177b840e28110dd952178bb2bdfedc2 @@ -1501,8 +1501,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 2091a4c9231c7871f27661adc27dd7df26500f6c fb2768154c513881886e89801e906bea959197b3 -R 654981991ade95156b7aa25e1b0590de -T +closed fb2768154c513881886e89801e906bea959197b3 +P f48a4ad33ecd4a86f5529596ff11829ba38b0875 +R f8f1ecf8d68a5747b29b0c8ae33faacb U drh -Z 4625be77e802d56f2b1c496e15a4bd85 +Z bc2339201021198d1e3ee60eab532825 diff --git a/manifest.uuid b/manifest.uuid index 7e4bb144b7..e6930e8d09 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f48a4ad33ecd4a86f5529596ff11829ba38b0875 \ No newline at end of file +fe1874321ba31cec9ae65387920c33d8d0178ed8 \ No newline at end of file diff --git a/src/build.c b/src/build.c index a5931954ad..c32195f655 100644 --- a/src/build.c +++ b/src/build.c @@ -3434,10 +3434,11 @@ void sqlite3DefaultRowEst(Index *pIdx){ int i; /* Set the first entry (number of rows in the index) to the estimated - ** number of rows in the table. Or 10, if the estimated number of rows - ** in the table is less than that. */ + ** number of rows in the table, or half the number of rows in the table + ** for a partial index. But do not let the estimate drop below 10. */ a[0] = pIdx->pTable->nRowLogEst; - if( a[0]<33 ) a[0] = 33; assert( 33==sqlite3LogEst(10) ); + if( pIdx->pPartIdxWhere!=0 ) a[0] -= 10; assert( 10==sqlite3LogEst(2) ); + if( a[0]<33 ) a[0] = 33; assert( 33==sqlite3LogEst(10) ); /* Estimate that a[1] is 10, a[2] is 9, a[3] is 8, a[4] is 7, a[5] is ** 6 and each subsequent value (if any) is 5. */ diff --git a/src/where.c b/src/where.c index 04d0b0190c..e5a476c00a 100644 --- a/src/where.c +++ b/src/where.c @@ -2761,6 +2761,7 @@ static int whereLoopAddBtree( /* Full scan via index */ if( b || !HasRowid(pTab) + || pProbe->pPartIdxWhere!=0 || ( m==0 && pProbe->bUnordered==0 && (pProbe->szIdxRowszTabRow) diff --git a/test/index6.test b/test/index6.test index 33ae3d1cb1..9501a6c864 100644 --- a/test/index6.test +++ b/test/index6.test @@ -376,4 +376,15 @@ do_execsql_test index6-10.3eqp { SELECT e FROM t10 WHERE a=1 AND b=2 ORDER BY d DESC; } {~/USING INDEX t10x/} +# A partial index will be used for a full table scan, where possible +do_execsql_test index6-11.1 { + CREATE TABLE t11(a,b,c); + CREATE INDEX t11x ON t11(a) WHERE b<>99; + EXPLAIN QUERY PLAN SELECT a FROM t11 WHERE b<>99; +} {/USING INDEX t11x/} +do_execsql_test index6-11.2 { + EXPLAIN QUERY PLAN SELECT a FROM t11 WHERE b<>99 AND c<>98; +} {/USING INDEX t11x/} + + finish_test From 4d249e61289c76b41a880126ceb44bf97e14fb8b Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 10 Jun 2016 22:49:01 +0000 Subject: [PATCH 0511/1484] Enhance "PRAGMA table_info" to that it provides information about eponymous virtual tables. FossilOrigin-Name: 53a1e5d51304cb3de700c1807a2c945a40240576 --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/build.c | 21 ++++++++++++--------- src/pragma.c | 2 +- src/sqliteInt.h | 6 ++++-- test/stat.test | 3 +++ 6 files changed, 30 insertions(+), 22 deletions(-) diff --git a/manifest b/manifest index 718d324c20..3aa1a8ed67 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Prefer\sto\suse\spartial\sindexes\sfor\sfull\stable\sscans\swhen\sthat\sis\spossible. -D 2016-06-08T18:07:21.900 +C Enhance\s"PRAGMA\stable_info"\sto\sthat\sit\sprovides\sinformation\sabout\seponymous\nvirtual\stables. +D 2016-06-10T22:49:01.448 F Makefile.in f3f7d2060ce03af4584e711ef3a626ef0b1d6340 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 50149765ef72f4e652b9a0f1f6462c4784bb9423 @@ -329,7 +329,7 @@ F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 F src/btree.c 2781fb1db1e46390a9c27a2162395f371577ac66 F src/btree.h 2107a2630e02c8cba58bb12ce14e731e734ea29c F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 -F src/build.c 535879738a9f9e351624ebe827bdfb6ef16475ae +F src/build.c d1fdfd7ab8f5447e494ef15825973bf0719527c6 F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 999a828425b35b8092a8cde25690e71c20906344 @@ -375,7 +375,7 @@ F src/parse.y 01b9f37c4c7009ab56fda98bc7db4c42643cecfe F src/pcache.c 5583c8ade4b05075a60ba953ef471d1c1a9c05df F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 F src/pcache1.c 7f51d2b541aab57596adf62db2c4bb025d34f04d -F src/pragma.c d98039af2deb5a4990f6635462b3f61f325a6c75 +F src/pragma.c c8b499756658cb8b82cfdbb5845c22cf11f297aa F src/pragma.h 64c78a648751b9f4f297276c4eb7507b14b4628c F src/prepare.c 22df6171aec1d86904ed2ad30c2348a5748aa04e F src/printf.c a5f0ca08ddede803c241266abb46356ec748ded1 @@ -387,7 +387,7 @@ F src/shell.c 14ff7f660530a52b117d110ba3390b7b2eb719b6 F src/sqlite.h.in 5f8113dbec74c6c093ead9930afb8c9fbd9f643d F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 98f72cbfe00169c39089115427d06ea05fe4b4a2 -F src/sqliteInt.h 801e2a569ea79b09b87d045cd6f00ec88205f1f6 +F src/sqliteInt.h b425bb606c14c078b1c9feb7cf72f2f3a35be188 F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 @@ -1100,7 +1100,7 @@ F test/spellfix3.test 0f9efaaa502a0e0a09848028518a6fb096c8ad33 F test/sqldiff1.test 28cd737cf1b0078b1ec1bbf425e674c47785835e F test/sqllimits1.test a74ee2a3740b9f9c2437c246d8fb77354862a142 F test/sqllog.test 6af6cb0b09f4e44e1917e06ce85be7670302517a -F test/stat.test 66e95f97b9f724f9ab921d054ee0db3c2689f1ee +F test/stat.test 8544f219694807400c8fd1830e4ad858f5b1b23f F test/statfault.test f525a7bf633e50afd027700e9a486090684b1ac1 F test/stmt.test 64844332db69cf1a735fcb3e11548557fc95392f F test/subquery.test d7268d193dd33d5505df965399d3a594e76ae13f @@ -1501,7 +1501,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P f48a4ad33ecd4a86f5529596ff11829ba38b0875 -R f8f1ecf8d68a5747b29b0c8ae33faacb +P fe1874321ba31cec9ae65387920c33d8d0178ed8 +R bcb028582306bc8630ca7310032e2582 U drh -Z bc2339201021198d1e3ee60eab532825 +Z 24931a2c89ab34cc35408cff5c484569 diff --git a/manifest.uuid b/manifest.uuid index e6930e8d09..d22ea35143 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fe1874321ba31cec9ae65387920c33d8d0178ed8 \ No newline at end of file +53a1e5d51304cb3de700c1807a2c945a40240576 \ No newline at end of file diff --git a/src/build.c b/src/build.c index c32195f655..52f6f200f8 100644 --- a/src/build.c +++ b/src/build.c @@ -338,7 +338,7 @@ Table *sqlite3FindTable(sqlite3 *db, const char *zName, const char *zDatabase){ */ Table *sqlite3LocateTable( Parse *pParse, /* context in which to report errors */ - int isView, /* True if looking for a VIEW rather than a TABLE */ + u32 flags, /* LOCATE_VIEW or LOCATE_NOERR */ const char *zName, /* Name of the table we are looking for */ const char *zDbase /* Name of the database. Might be NULL */ ){ @@ -352,7 +352,7 @@ Table *sqlite3LocateTable( p = sqlite3FindTable(pParse->db, zName, zDbase); if( p==0 ){ - const char *zMsg = isView ? "no such view" : "no such table"; + const char *zMsg = flags & LOCATE_VIEW ? "no such view" : "no such table"; #ifndef SQLITE_OMIT_VIRTUALTABLE if( sqlite3FindDbName(pParse->db, zDbase)<1 ){ /* If zName is the not the name of a table in the schema created using @@ -364,12 +364,14 @@ Table *sqlite3LocateTable( } } #endif - if( zDbase ){ - sqlite3ErrorMsg(pParse, "%s: %s.%s", zMsg, zDbase, zName); - }else{ - sqlite3ErrorMsg(pParse, "%s: %s", zMsg, zName); + if( (flags & LOCATE_NOERR)==0 ){ + if( zDbase ){ + sqlite3ErrorMsg(pParse, "%s: %s.%s", zMsg, zDbase, zName); + }else{ + sqlite3ErrorMsg(pParse, "%s: %s", zMsg, zName); + } + pParse->checkSchema = 1; } - pParse->checkSchema = 1; } return p; @@ -386,7 +388,7 @@ Table *sqlite3LocateTable( */ Table *sqlite3LocateTableItem( Parse *pParse, - int isView, + u32 flags, struct SrcList_item *p ){ const char *zDb; @@ -397,7 +399,7 @@ Table *sqlite3LocateTableItem( }else{ zDb = p->zDatabase; } - return sqlite3LocateTable(pParse, isView, p->zName, zDb); + return sqlite3LocateTable(pParse, flags, p->zName, zDb); } /* @@ -2504,6 +2506,7 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){ assert( pName->nSrc==1 ); if( sqlite3ReadSchema(pParse) ) goto exit_drop_table; if( noErr ) db->suppressErr++; + assert( isView==0 || isView==LOCATE_VIEW ); pTab = sqlite3LocateTableItem(pParse, isView, &pName->a[0]); if( noErr ) db->suppressErr--; diff --git a/src/pragma.c b/src/pragma.c index 56823c7243..1ee08fbec0 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -1052,7 +1052,7 @@ void sqlite3Pragma( */ case PragTyp_TABLE_INFO: if( zRight ){ Table *pTab; - pTab = sqlite3FindTable(db, zRight, zDb); + pTab = sqlite3LocateTable(pParse, LOCATE_NOERR, zRight, zDb); if( pTab ){ static const char *azCol[] = { "cid", "name", "type", "notnull", "dflt_value", "pk" diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 024003afb0..798523bd1e 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3671,8 +3671,10 @@ void sqlite3ExprIfTrue(Parse*, Expr*, int, int); void sqlite3ExprIfFalse(Parse*, Expr*, int, int); void sqlite3ExprIfFalseDup(Parse*, Expr*, int, int); Table *sqlite3FindTable(sqlite3*,const char*, const char*); -Table *sqlite3LocateTable(Parse*,int isView,const char*, const char*); -Table *sqlite3LocateTableItem(Parse*,int isView,struct SrcList_item *); +#define LOCATE_VIEW 0x01 +#define LOCATE_NOERR 0x02 +Table *sqlite3LocateTable(Parse*,u32 flags,const char*, const char*); +Table *sqlite3LocateTableItem(Parse*,u32 flags,struct SrcList_item *); Index *sqlite3FindIndex(sqlite3*,const char*, const char*); void sqlite3UnlinkAndDeleteTable(sqlite3*,int,const char*); void sqlite3UnlinkAndDeleteIndex(sqlite3*,int,const char*); diff --git a/test/stat.test b/test/stat.test index d106894d71..f77e4d24a3 100644 --- a/test/stat.test +++ b/test/stat.test @@ -32,6 +32,9 @@ db func a_string a_string register_dbstat_vtab db do_execsql_test stat-0.0 { + PRAGMA table_info(dbstat); +} {/0 name STRING .* 1 path INTEGER .* 9 pgsize INTEGER/} +do_execsql_test stat-0.1 { PRAGMA auto_vacuum = OFF; CREATE VIRTUAL TABLE temp.stat USING dbstat; SELECT * FROM stat; From edc4024b9da4374f78d5dfb8e108144415e7467e Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 13 Jun 2016 12:34:38 +0000 Subject: [PATCH 0512/1484] Fix the "onecolumn" and "exists" methods of the TCL interface so that they work in combination with the "profile" callback. FossilOrigin-Name: d362ba157f993fc74a590cf15a9a2fa589278dd7 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/tclsqlite.c | 6 ++++-- test/tclsqlite.test | 33 +++++++++++++++++++++++++++++++++ 4 files changed, 45 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 3aa1a8ed67..b15af5f081 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\s"PRAGMA\stable_info"\sto\sthat\sit\sprovides\sinformation\sabout\seponymous\nvirtual\stables. -D 2016-06-10T22:49:01.448 +C Fix\sthe\s"onecolumn"\sand\s"exists"\smethods\sof\sthe\sTCL\sinterface\sso\sthat\sthey\nwork\sin\scombination\swith\sthe\s"profile"\scallback. +D 2016-06-13T12:34:38.095 F Makefile.in f3f7d2060ce03af4584e711ef3a626ef0b1d6340 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 50149765ef72f4e652b9a0f1f6462c4784bb9423 @@ -391,7 +391,7 @@ F src/sqliteInt.h b425bb606c14c078b1c9feb7cf72f2f3a35be188 F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 -F src/tclsqlite.c 9c4c4589d078de37813ded708d8838b338ffb060 +F src/tclsqlite.c 25fbbbb97f76dbfd113153fb63f52d7ecfac5dd0 F src/test1.c 43b37ab2b7338fd3313e74902f0d6c821eae843b F src/test2.c 5586f43fcd9a1be0830793cf9d354082c261b25b F src/test3.c c75c8af0eadb335236c9e61b51044c58a8f7dd59 @@ -1117,7 +1117,7 @@ F test/tabfunc01.test f977868fa8bb7beb4b2072883190411653473906 F test/table.test b708f3e5fa2542fa51dfab21fc07b36ea445cb2f F test/tableapi.test 2674633fa95d80da917571ebdd759a14d9819126 F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930 -F test/tclsqlite.test e1306001a0ca92250b691ea6d3cecaca5b6342aa +F test/tclsqlite.test cf0d0a3fd03d64892cec2d48aae9fb2f148680a5 F test/tempdb.test bd92eba8f20e16a9136e434e20b280794de3cdb6 F test/tempdb2.test 4fc92055f2a3f7626c0f2eabbb637dc021b311d5 F test/tempfault.test 0c0d349c9a99bf5f374655742577f8712c647900 @@ -1501,7 +1501,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P fe1874321ba31cec9ae65387920c33d8d0178ed8 -R bcb028582306bc8630ca7310032e2582 +P 53a1e5d51304cb3de700c1807a2c945a40240576 +R 728aa3483f448a04bb6de7c432f92c81 U drh -Z 24931a2c89ab34cc35408cff5c484569 +Z f275382679f329597f4cef7fe1c1d3e9 diff --git a/manifest.uuid b/manifest.uuid index d22ea35143..17751de4e1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -53a1e5d51304cb3de700c1807a2c945a40240576 \ No newline at end of file +d362ba157f993fc74a590cf15a9a2fa589278dd7 \ No newline at end of file diff --git a/src/tclsqlite.c b/src/tclsqlite.c index d6a36118c4..476bdf235e 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -2325,6 +2325,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ */ case DB_EXISTS: case DB_ONECOLUMN: { + Tcl_Obj *pResult = 0; DbEvalContext sEval; if( objc!=3 ){ Tcl_WrongNumArgs(interp, 2, objv, "SQL"); @@ -2335,14 +2336,15 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ rc = dbEvalStep(&sEval); if( choice==DB_ONECOLUMN ){ if( rc==TCL_OK ){ - Tcl_SetObjResult(interp, dbEvalColumnValue(&sEval, 0)); + pResult = dbEvalColumnValue(&sEval, 0); }else if( rc==TCL_BREAK ){ Tcl_ResetResult(interp); } }else if( rc==TCL_BREAK || rc==TCL_OK ){ - Tcl_SetObjResult(interp, Tcl_NewBooleanObj(rc==TCL_OK)); + pResult = Tcl_NewBooleanObj(rc==TCL_OK); } dbEvalFinalize(&sEval); + if( pResult ) Tcl_SetObjResult(interp, pResult); if( rc==TCL_BREAK ){ rc = TCL_OK; diff --git a/test/tclsqlite.test b/test/tclsqlite.test index 44d5c5634b..767dd01be2 100644 --- a/test/tclsqlite.test +++ b/test/tclsqlite.test @@ -635,6 +635,39 @@ do_test tcl-14.2 { db one {SELECT x FROM t6 WHERE xCall()!='value'} } {} +# Verify that the "exists" and "onecolumn" methods work when +# a "profile" is registered. +# +catch {db close} +sqlite3 db :memory: +proc noop-profile {args} { + return +} +do_test tcl-15.0 { + db eval {CREATE TABLE t1(a); INSERT INTO t1 VALUES(1),(2),(3);} + db onecolumn {SELECT a FROM t1 WHERE a>2} +} {3} +do_test tcl-15.1 { + db exists {SELECT a FROM t1 WHERE a>2} +} {1} +do_test tcl-15.2 { + db exists {SELECT a FROM t1 WHERE a>3} +} {0} +db profile noop-profile +do_test tcl-15.3 { + db onecolumn {SELECT a FROM t1 WHERE a>2} +} {3} +do_test tcl-15.4 { + db exists {SELECT a FROM t1 WHERE a>2} +} {1} +do_test tcl-15.5 { + db exists {SELECT a FROM t1 WHERE a>3} +} {0} + + + + + finish_test From debaa86c1c3b73de2b1fe4dad5009c717de5b980 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 13 Jun 2016 12:51:20 +0000 Subject: [PATCH 0513/1484] Fix an incorrect assert() in the btree logic. FossilOrigin-Name: fcf6114be94b260641e7c78a58db16a31ac5ab35 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btree.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index b15af5f081..87f091e147 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\s"onecolumn"\sand\s"exists"\smethods\sof\sthe\sTCL\sinterface\sso\sthat\sthey\nwork\sin\scombination\swith\sthe\s"profile"\scallback. -D 2016-06-13T12:34:38.095 +C Fix\san\sincorrect\sassert()\sin\sthe\sbtree\slogic. +D 2016-06-13T12:51:20.365 F Makefile.in f3f7d2060ce03af4584e711ef3a626ef0b1d6340 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 50149765ef72f4e652b9a0f1f6462c4784bb9423 @@ -326,7 +326,7 @@ F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240 F src/backup.c 6df65fdd569c901a418887a1a76f82ec35044556 F src/bitvec.c 3ee4c8b2c94ed3a7377256e18199e6ff5cf33f63 F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 -F src/btree.c 2781fb1db1e46390a9c27a2162395f371577ac66 +F src/btree.c 0621247619df15790f7ed5f14926cfb3925c10b1 F src/btree.h 2107a2630e02c8cba58bb12ce14e731e734ea29c F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 F src/build.c d1fdfd7ab8f5447e494ef15825973bf0719527c6 @@ -1501,7 +1501,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 53a1e5d51304cb3de700c1807a2c945a40240576 -R 728aa3483f448a04bb6de7c432f92c81 +P d362ba157f993fc74a590cf15a9a2fa589278dd7 +R 8b591288ef08b6290802dd112ec0668a U drh -Z f275382679f329597f4cef7fe1c1d3e9 +Z 9ef02259ea1748db703c32ac6cd57aa7 diff --git a/manifest.uuid b/manifest.uuid index 17751de4e1..16b994508c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d362ba157f993fc74a590cf15a9a2fa589278dd7 \ No newline at end of file +fcf6114be94b260641e7c78a58db16a31ac5ab35 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 3a95edf007..f37199276f 100644 --- a/src/btree.c +++ b/src/btree.c @@ -5070,7 +5070,7 @@ int sqlite3BtreeMovetoUnpacked( assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); assert( pRes ); assert( (pIdxKey==0)==(pCur->pKeyInfo==0) ); - assert( (pIdxKey==0)==(pCur->curIntKey!=0) || pCur->eState!=CURSOR_VALID ); + assert( pCur->eState!=CURSOR_VALID || (pIdxKey==0)==(pCur->curIntKey!=0) ); /* If the cursor is already positioned at the point we are trying ** to move to, then just return without doing any work */ From 6c0e41b951ba5bf71bd9e4e4230a82e95f39f8a0 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 13 Jun 2016 15:59:37 +0000 Subject: [PATCH 0514/1484] Fix the declaration of the table implemented by DBSTAT so that it uses correct datatypes. FossilOrigin-Name: a1e1cdc51d1c68502f43ac72c28ba87cb1916a0d --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/dbstat.c | 6 +++--- test/stat.test | 2 +- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 87f091e147..400a0f60d3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\sincorrect\sassert()\sin\sthe\sbtree\slogic. -D 2016-06-13T12:51:20.365 +C Fix\sthe\sdeclaration\sof\sthe\stable\simplemented\sby\sDBSTAT\sso\sthat\sit\suses\ncorrect\sdatatypes. +D 2016-06-13T15:59:37.932 F Makefile.in f3f7d2060ce03af4584e711ef3a626ef0b1d6340 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 50149765ef72f4e652b9a0f1f6462c4784bb9423 @@ -334,7 +334,7 @@ F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 999a828425b35b8092a8cde25690e71c20906344 F src/date.c 1cc9fb516ec9932c6fd4d2a0d2f8bc4480145c39 -F src/dbstat.c c845548d4346e606e2f2b7d2e714ace2b8a7dd1b +F src/dbstat.c 4f6f7f52b49beb9636ffbd517cfe44a402ba4ad0 F src/delete.c 4aba4214a377ce8ddde2d2e609777bcc8235200f F src/expr.c 798146ea4c87d723e8a157d88450ac9c43256998 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb @@ -1100,7 +1100,7 @@ F test/spellfix3.test 0f9efaaa502a0e0a09848028518a6fb096c8ad33 F test/sqldiff1.test 28cd737cf1b0078b1ec1bbf425e674c47785835e F test/sqllimits1.test a74ee2a3740b9f9c2437c246d8fb77354862a142 F test/sqllog.test 6af6cb0b09f4e44e1917e06ce85be7670302517a -F test/stat.test 8544f219694807400c8fd1830e4ad858f5b1b23f +F test/stat.test ab95d28503d0f6d98ffd8ce204643c9da090ebf1 F test/statfault.test f525a7bf633e50afd027700e9a486090684b1ac1 F test/stmt.test 64844332db69cf1a735fcb3e11548557fc95392f F test/subquery.test d7268d193dd33d5505df965399d3a594e76ae13f @@ -1501,7 +1501,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d362ba157f993fc74a590cf15a9a2fa589278dd7 -R 8b591288ef08b6290802dd112ec0668a +P fcf6114be94b260641e7c78a58db16a31ac5ab35 +R 39b9428988b60189530e38dc24c060de U drh -Z 9ef02259ea1748db703c32ac6cd57aa7 +Z 57ee65d1a2a24e95107b0a8e8a3984a2 diff --git a/manifest.uuid b/manifest.uuid index 16b994508c..102fffd27e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fcf6114be94b260641e7c78a58db16a31ac5ab35 \ No newline at end of file +a1e1cdc51d1c68502f43ac72c28ba87cb1916a0d \ No newline at end of file diff --git a/src/dbstat.c b/src/dbstat.c index b8e79b0864..92ce650df1 100644 --- a/src/dbstat.c +++ b/src/dbstat.c @@ -58,10 +58,10 @@ */ #define VTAB_SCHEMA \ "CREATE TABLE xx( " \ - " name STRING, /* Name of table or index */" \ - " path INTEGER, /* Path to page from root */" \ + " name TEXT, /* Name of table or index */" \ + " path TEXT, /* Path to page from root */" \ " pageno INTEGER, /* Page number */" \ - " pagetype STRING, /* 'internal', 'leaf' or 'overflow' */" \ + " pagetype TEXT, /* 'internal', 'leaf' or 'overflow' */" \ " ncell INTEGER, /* Cells on page (0 for overflow) */" \ " payload INTEGER, /* Bytes of payload on this page */" \ " unused INTEGER, /* Bytes of unused space on this page */" \ diff --git a/test/stat.test b/test/stat.test index f77e4d24a3..6a87a629b9 100644 --- a/test/stat.test +++ b/test/stat.test @@ -33,7 +33,7 @@ db func a_string a_string register_dbstat_vtab db do_execsql_test stat-0.0 { PRAGMA table_info(dbstat); -} {/0 name STRING .* 1 path INTEGER .* 9 pgsize INTEGER/} +} {/0 name TEXT .* 1 path TEXT .* 9 pgsize INTEGER/} do_execsql_test stat-0.1 { PRAGMA auto_vacuum = OFF; CREATE VIRTUAL TABLE temp.stat USING dbstat; From c14566aff3cdd0cb0a6acf0e6526a3238b9bbd0c Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 13 Jun 2016 19:58:46 +0000 Subject: [PATCH 0515/1484] Fix RBU so that it builds with -DSQLITE_ENABLE_8_3_NAMES. Fix "PRAGMA compile_options" for SQLITE_ENABLE_8_3_NAMES such that it reports the numeric setting: "1" or "2". FossilOrigin-Name: 0230ca17ba20ecd3d213788ad6891973d52a7b72 --- ext/rbu/sqlite3rbu.c | 4 ++-- manifest | 14 +++++++------- manifest.uuid | 2 +- src/ctime.c | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/ext/rbu/sqlite3rbu.c b/ext/rbu/sqlite3rbu.c index 39d31935cb..1cfb71384f 100644 --- a/ext/rbu/sqlite3rbu.c +++ b/ext/rbu/sqlite3rbu.c @@ -2507,9 +2507,9 @@ static void rbuFileSuffix3(const char *zBase, char *z){ #endif { int i, sz; - sz = sqlite3Strlen30(z); + sz = (int)strlen(z)&0xffffff; for(i=sz-1; i>0 && z[i]!='/' && z[i]!='.'; i--){} - if( z[i]=='.' && ALWAYS(sz>i+4) ) memmove(&z[i+1], &z[sz-3], 4); + if( z[i]=='.' && sz>i+4 ) memmove(&z[i+1], &z[sz-3], 4); } #endif } diff --git a/manifest b/manifest index 400a0f60d3..4f19e2712a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\sdeclaration\sof\sthe\stable\simplemented\sby\sDBSTAT\sso\sthat\sit\suses\ncorrect\sdatatypes. -D 2016-06-13T15:59:37.932 +C Fix\sRBU\sso\sthat\sit\sbuilds\swith\s-DSQLITE_ENABLE_8_3_NAMES.\nFix\s"PRAGMA\scompile_options"\sfor\sSQLITE_ENABLE_8_3_NAMES\ssuch\sthat\sit\sreports\nthe\snumeric\ssetting:\s"1"\sor\s"2". +D 2016-06-13T19:58:46.382 F Makefile.in f3f7d2060ce03af4584e711ef3a626ef0b1d6340 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 50149765ef72f4e652b9a0f1f6462c4784bb9423 @@ -252,7 +252,7 @@ F ext/rbu/rbuprogress.test 2023a7df2c523e3df1cb532eff811cda385a789a F ext/rbu/rbusave.test 0f43b6686084f426ddd040b878426452fd2c2f48 F ext/rbu/rbuvacuum.test 4a977447c15c2581ab668781d9ef4294382530e0 F ext/rbu/rbuvacuum2.test 45009e127c3fb385e5c0fd5a8a63fb922a79d0ab -F ext/rbu/sqlite3rbu.c a37a7dfb225c497171aa60120e81b884954361c7 +F ext/rbu/sqlite3rbu.c 3d35b1dc46f5ca0f0f59db8e6163fe7627ea107c F ext/rbu/sqlite3rbu.h 2acd0a6344a6079de15c8dc9d84d3df83a665930 F ext/rbu/test_rbu.c 9bbdf6bd8efd58fbc4f192698df50569598fbb9e F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 @@ -332,7 +332,7 @@ F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 F src/build.c d1fdfd7ab8f5447e494ef15825973bf0719527c6 F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e -F src/ctime.c 999a828425b35b8092a8cde25690e71c20906344 +F src/ctime.c 61949e83c4c36e37195a8398ebc752780b534d95 F src/date.c 1cc9fb516ec9932c6fd4d2a0d2f8bc4480145c39 F src/dbstat.c 4f6f7f52b49beb9636ffbd517cfe44a402ba4ad0 F src/delete.c 4aba4214a377ce8ddde2d2e609777bcc8235200f @@ -1501,7 +1501,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P fcf6114be94b260641e7c78a58db16a31ac5ab35 -R 39b9428988b60189530e38dc24c060de +P a1e1cdc51d1c68502f43ac72c28ba87cb1916a0d +R c278a2e099b6be15733b154091fd5a26 U drh -Z 57ee65d1a2a24e95107b0a8e8a3984a2 +Z 0e8cfd82e8662e22b8b1a31845a5f102 diff --git a/manifest.uuid b/manifest.uuid index 102fffd27e..731f5db73f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a1e1cdc51d1c68502f43ac72c28ba87cb1916a0d \ No newline at end of file +0230ca17ba20ecd3d213788ad6891973d52a7b72 \ No newline at end of file diff --git a/src/ctime.c b/src/ctime.c index 589cabc1ab..1a7c69f3bf 100644 --- a/src/ctime.c +++ b/src/ctime.c @@ -71,7 +71,7 @@ static const char * const azCompileOpt[] = { "DISABLE_LFS", #endif #if SQLITE_ENABLE_8_3_NAMES - "ENABLE_8_3_NAMES", + "ENABLE_8_3_NAMES=" CTIMEOPT_VAL(SQLITE_ENABLE_8_3_NAMES), #endif #if SQLITE_ENABLE_API_ARMOR "ENABLE_API_ARMOR", From 6b922881198683f958227ca2c5682251dab9cb2a Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 16 Jun 2016 11:16:53 +0000 Subject: [PATCH 0516/1484] Fix a typo in a comment on the SrcList object. FossilOrigin-Name: 48b555c42de1cbc031fb6c2c93ef170e491c7d76 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/sqliteInt.h | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 4f19e2712a..086230a5e9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sRBU\sso\sthat\sit\sbuilds\swith\s-DSQLITE_ENABLE_8_3_NAMES.\nFix\s"PRAGMA\scompile_options"\sfor\sSQLITE_ENABLE_8_3_NAMES\ssuch\sthat\sit\sreports\nthe\snumeric\ssetting:\s"1"\sor\s"2". -D 2016-06-13T19:58:46.382 +C Fix\sa\stypo\sin\sa\scomment\son\sthe\sSrcList\sobject. +D 2016-06-16T11:16:53.415 F Makefile.in f3f7d2060ce03af4584e711ef3a626ef0b1d6340 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 50149765ef72f4e652b9a0f1f6462c4784bb9423 @@ -387,7 +387,7 @@ F src/shell.c 14ff7f660530a52b117d110ba3390b7b2eb719b6 F src/sqlite.h.in 5f8113dbec74c6c093ead9930afb8c9fbd9f643d F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 98f72cbfe00169c39089115427d06ea05fe4b4a2 -F src/sqliteInt.h b425bb606c14c078b1c9feb7cf72f2f3a35be188 +F src/sqliteInt.h 2ac73e9fdd138f4607139d9bd6a1e6dcd01837dc F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 @@ -1501,7 +1501,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a1e1cdc51d1c68502f43ac72c28ba87cb1916a0d -R c278a2e099b6be15733b154091fd5a26 +P 0230ca17ba20ecd3d213788ad6891973d52a7b72 +R 1a1c29c9329c6a84a9521e4c335dbb95 U drh -Z 0e8cfd82e8662e22b8b1a31845a5f102 +Z 2cdcc0a9545b2084d273426178a84d04 diff --git a/manifest.uuid b/manifest.uuid index 731f5db73f..7714859290 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0230ca17ba20ecd3d213788ad6891973d52a7b72 \ No newline at end of file +48b555c42de1cbc031fb6c2c93ef170e491c7d76 \ No newline at end of file diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 798523bd1e..c52cd29927 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2485,7 +2485,7 @@ struct SrcList { int regReturn; /* Register holding return address of addrFillSub */ int regResult; /* Registers holding results of a co-routine */ struct { - u8 jointype; /* Type of join between this able and the previous */ + u8 jointype; /* Type of join between this table and the previous */ unsigned notIndexed :1; /* True if there is a NOT INDEXED clause */ unsigned isIndexedBy :1; /* True if there is an INDEXED BY clause */ unsigned isTabFunc :1; /* True if table-valued-function syntax */ From 3480bfdae9523d3b2e67c4b594e79bab6ca7776b Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 16 Jun 2016 17:14:02 +0000 Subject: [PATCH 0517/1484] Add a missing OP_ColumnsUsed opcode to code for expressions like "? IN (SELECT ...)" in cases where expression can use an index that may contain NULL values. FossilOrigin-Name: 0b1579caf06a2c42433b8bc9dc28c9ad381aa07c --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/expr.c | 5 +++++ 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 086230a5e9..b6450cc841 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\stypo\sin\sa\scomment\son\sthe\sSrcList\sobject. -D 2016-06-16T11:16:53.415 +C Add\sa\smissing\sOP_ColumnsUsed\sopcode\sto\scode\sfor\sexpressions\slike\s"?\sIN\s(SELECT\s...)"\sin\scases\swhere\sexpression\scan\suse\san\sindex\sthat\smay\scontain\sNULL\svalues. +D 2016-06-16T17:14:02.375 F Makefile.in f3f7d2060ce03af4584e711ef3a626ef0b1d6340 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 50149765ef72f4e652b9a0f1f6462c4784bb9423 @@ -336,7 +336,7 @@ F src/ctime.c 61949e83c4c36e37195a8398ebc752780b534d95 F src/date.c 1cc9fb516ec9932c6fd4d2a0d2f8bc4480145c39 F src/dbstat.c 4f6f7f52b49beb9636ffbd517cfe44a402ba4ad0 F src/delete.c 4aba4214a377ce8ddde2d2e609777bcc8235200f -F src/expr.c 798146ea4c87d723e8a157d88450ac9c43256998 +F src/expr.c 523a5b1db2b6d88c6eefb224877bf635a3bcfc92 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c bc4145347595b7770f9a598cff1c848302cf5413 F src/func.c 61a4114cf7004f10c542cfabbab9f2bcb9033045 @@ -1501,7 +1501,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 0230ca17ba20ecd3d213788ad6891973d52a7b72 -R 1a1c29c9329c6a84a9521e4c335dbb95 -U drh -Z 2cdcc0a9545b2084d273426178a84d04 +P 48b555c42de1cbc031fb6c2c93ef170e491c7d76 +R 7c056b92500e212b6fa7144618e1e6e0 +U dan +Z 6cf13efbb72ea4474e244da36e8952f1 diff --git a/manifest.uuid b/manifest.uuid index 7714859290..6347d15d5f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -48b555c42de1cbc031fb6c2c93ef170e491c7d76 \ No newline at end of file +0b1579caf06a2c42433b8bc9dc28c9ad381aa07c \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index c6a09d9d9d..ce3a476561 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1818,6 +1818,11 @@ int sqlite3FindInIndex(Parse *pParse, Expr *pX, u32 inFlags, int *prRhsHasNull){ eType = IN_INDEX_INDEX_ASC + pIdx->aSortOrder[0]; if( prRhsHasNull && !pTab->aCol[iCol].notNull ){ +#ifdef SQLITE_ENABLE_COLUMN_USED_MASK + const i64 sOne = 1; + sqlite3VdbeAddOp4Dup8(v, OP_ColumnsUsed, + iTab, 0, 0, (u8*)&sOne, P4_INT64); +#endif *prRhsHasNull = ++pParse->nMem; sqlite3SetHasNullFlag(v, iTab, *prRhsHasNull); } From 2ad96f5880fd77919571477dc0302cf763e527ff Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 17 Jun 2016 13:01:51 +0000 Subject: [PATCH 0518/1484] Add the json_quote() function to the JSON1 extension. FossilOrigin-Name: 2c3714aebf5e40e3728877a235b3c1f93defa33e --- ext/misc/json1.c | 20 ++++++++++++++++++++ manifest | 19 +++++++++++-------- manifest.uuid | 2 +- test/json101.test | 29 +++++++++++++++++++++++++++++ 4 files changed, 61 insertions(+), 9 deletions(-) diff --git a/ext/misc/json1.c b/ext/misc/json1.c index 99d299c29c..a9452b0191 100644 --- a/ext/misc/json1.c +++ b/ext/misc/json1.c @@ -1211,6 +1211,25 @@ static void jsonTest1Func( ** Scalar SQL function implementations ****************************************************************************/ +/* +** Implementation of the json_QUOTE(VALUE) function. Return a JSON value +** corresponding to the SQL value input. Mostly this means putting +** double-quotes around strings and returning the unquoted string "null" +** when given a NULL input. +*/ +static void jsonQuoteFunc( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv +){ + JsonString jx; + + jsonInit(&jx, ctx); + jsonAppendValue(&jx, argv[0]); + jsonResult(&jx); + sqlite3_result_subtype(ctx, JSON_SUBTYPE); +} + /* ** Implementation of the json_array(VALUE,...) function. Return a JSON ** array that contains all values given in arguments. Or if any argument @@ -2124,6 +2143,7 @@ int sqlite3Json1Init(sqlite3 *db){ { "json_extract", -1, 0, jsonExtractFunc }, { "json_insert", -1, 0, jsonSetFunc }, { "json_object", -1, 0, jsonObjectFunc }, + { "json_quote", 1, 0, jsonQuoteFunc }, { "json_remove", -1, 0, jsonRemoveFunc }, { "json_replace", -1, 0, jsonReplaceFunc }, { "json_set", -1, 1, jsonSetFunc }, diff --git a/manifest b/manifest index b6450cc841..cfd0f94004 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sa\smissing\sOP_ColumnsUsed\sopcode\sto\scode\sfor\sexpressions\slike\s"?\sIN\s(SELECT\s...)"\sin\scases\swhere\sexpression\scan\suse\san\sindex\sthat\smay\scontain\sNULL\svalues. -D 2016-06-16T17:14:02.375 +C Add\sthe\sjson_quote()\sfunction\sto\sthe\sJSON1\sextension. +D 2016-06-17T13:01:51.782 F Makefile.in f3f7d2060ce03af4584e711ef3a626ef0b1d6340 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 50149765ef72f4e652b9a0f1f6462c4784bb9423 @@ -211,7 +211,7 @@ F ext/misc/eval.c f971962e92ebb8b0a4e6b62949463ee454d88fa2 F ext/misc/fileio.c d4171c815d6543a9edef8308aab2951413cd8d0f F ext/misc/fuzzer.c 7c64b8197bb77b7d64eff7cac7848870235d4c25 F ext/misc/ieee754.c f190d0cc5182529acb15babd177781be1ac1718c -F ext/misc/json1.c b9c88d5c3b6ecd8c731ffdd7f5b3d902857f8c96 +F ext/misc/json1.c d51a764ba43a49e191bc3536238bfab3def258ca F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342 F ext/misc/percentile.c bcbee3c061b884eccb80e21651daaae8e1e43c63 F ext/misc/regexp.c a68d25c659bd2d893cd1215667bbf75ecb9dc7d4 @@ -874,7 +874,7 @@ F test/journal3.test ff8af941f9e06161d3db1b46bb9f965ff0e7f307 F test/jrnlmode.test 7864d59cf7f6e552b9b99ba0f38acd167edc10fa F test/jrnlmode2.test 81610545a4e6ed239ea8fa661891893385e23a1d F test/jrnlmode3.test 556b447a05be0e0963f4311e95ab1632b11c9eaa -F test/json101.test ef42283f0b60d8bacbc2243448e7c84988578e52 +F test/json101.test 865776ed8580703e1684fe4b8ee2e473333bb121 F test/json102.test bf3fe7a706d30936a76a0f7a0375e1e8e73aff5a F test/json103.test c5f6b85e69de05f6b3195f9f9d5ce9cd179099a0 F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff @@ -1501,7 +1501,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 48b555c42de1cbc031fb6c2c93ef170e491c7d76 -R 7c056b92500e212b6fa7144618e1e6e0 -U dan -Z 6cf13efbb72ea4474e244da36e8952f1 +P 0b1579caf06a2c42433b8bc9dc28c9ad381aa07c +R d87f9b42ae99ac8ed32dd707e5951481 +T *branch * json_quote +T *sym-json_quote * +T -sym-trunk * +U drh +Z f05f5d0cd323376080196dc4fc41462d diff --git a/manifest.uuid b/manifest.uuid index 6347d15d5f..8de647c48f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0b1579caf06a2c42433b8bc9dc28c9ad381aa07c \ No newline at end of file +2c3714aebf5e40e3728877a235b3c1f93defa33e \ No newline at end of file diff --git a/test/json101.test b/test/json101.test index 9b780a379b..3ee007c1cb 100644 --- a/test/json101.test +++ b/test/json101.test @@ -356,5 +356,34 @@ do_execsql_test json-8.2 { SELECT a=json_extract(b,'$[0]') FROM t8; } {1} +# The json_quote() function transforms an SQL value into a JSON value. +# String values are quoted and interior quotes are escaped. NULL values +# are rendered as the unquoted string "null". +# +do_execsql_test json-9.1 { + SELECT json_quote('abc"xyz'); +} {{"abc\"xyz"}} +do_execsql_test json-9.2 { + SELECT json_quote(3.14159); +} {3.14159} +do_execsql_test json-9.3 { + SELECT json_quote(12345); +} {12345} +do_execsql_test json-9.4 { + SELECT json_quote(null); +} {"null"} +do_catchsql_test json-9.5 { + SELECT json_quote(x'30313233'); +} {1 {JSON cannot hold BLOB values}} +do_catchsql_test json-9.6 { + SELECT json_quote(123,456) +} {1 {wrong number of arguments to function json_quote()}} +do_catchsql_test json-9.7 { + SELECT json_quote() +} {1 {wrong number of arguments to function json_quote()}} + + + + finish_test From b324cf756ea0622b43fb64687223a22451d697f7 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 17 Jun 2016 14:33:32 +0000 Subject: [PATCH 0519/1484] If a table is on the rhs of a LEFT JOIN, include only terms from the joins ON(...) clause in the cursor-hint passed via OP_CursorHint. FossilOrigin-Name: 2a2346b04235c6d0b7a8e64c92ee31018285c29f --- manifest | 16 ++++--- manifest.uuid | 2 +- src/wherecode.c | 35 ++++++++++++--- test/cursorhint2.test | 101 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 142 insertions(+), 12 deletions(-) create mode 100644 test/cursorhint2.test diff --git a/manifest b/manifest index b6450cc841..9af4d76b72 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sa\smissing\sOP_ColumnsUsed\sopcode\sto\scode\sfor\sexpressions\slike\s"?\sIN\s(SELECT\s...)"\sin\scases\swhere\sexpression\scan\suse\san\sindex\sthat\smay\scontain\sNULL\svalues. -D 2016-06-16T17:14:02.375 +C If\sa\stable\sis\son\sthe\srhs\sof\sa\sLEFT\sJOIN,\sinclude\sonly\sterms\sfrom\sthe\sjoins\sON(...)\sclause\sin\sthe\scursor-hint\spassed\svia\sOP_CursorHint. +D 2016-06-17T14:33:32.727 F Makefile.in f3f7d2060ce03af4584e711ef3a626ef0b1d6340 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 50149765ef72f4e652b9a0f1f6462c4784bb9423 @@ -464,7 +464,7 @@ F src/wal.h 2f7c831cf3b071fa548bf2d5cac640846a7ff19c F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354 F src/where.c 74f0798525b6306682d7234f230ea93f86959b9b F src/whereInt.h e5b939701a7ceffc5a3a8188a37f9746416ebcd0 -F src/wherecode.c ba71a4e4bada29aa9842200e6299714bf18c812c +F src/wherecode.c b9d5f7d8ebed2e09376fd785a111ffd9dfd59ffc F src/whereexpr.c c32d47085dbaca0b8fd013210f56693c7d220d48 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -617,6 +617,7 @@ F test/cse.test 277350a26264495e86b1785f34d2d0c8600e021c F test/csv01.test 0929a9ce47021519512be92861f29e32d2538e5f F test/ctime.test 7bd009071e242aac4f18521581536b652b789a47 F test/cursorhint.test 7bc346788390475e77a345da2b92270d04d35856 +F test/cursorhint2.test 532fdc678653f73e30770b59af0a47f9af0124ee F test/date.test 984ac1e3e5e031386866f034006148d3972b4a65 F test/dbstatus.test 8de104bb5606f19537d23cd553b41349b5ab1204 F test/dbstatus2.test e93ab03bfae6d62d4d935f20de928c19ca0ed0ab @@ -1501,7 +1502,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 48b555c42de1cbc031fb6c2c93ef170e491c7d76 -R 7c056b92500e212b6fa7144618e1e6e0 +P 0b1579caf06a2c42433b8bc9dc28c9ad381aa07c +R 2d1831333befb414525bf922ba35c127 +T *branch * cursor-hints +T *sym-cursor-hints * +T -sym-trunk * U dan -Z 6cf13efbb72ea4474e244da36e8952f1 +Z b45fbbd37d7e68d5f1357e6143b6a1f1 diff --git a/manifest.uuid b/manifest.uuid index 6347d15d5f..4e6e68e3f9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0b1579caf06a2c42433b8bc9dc28c9ad381aa07c \ No newline at end of file +2a2346b04235c6d0b7a8e64c92ee31018285c29f \ No newline at end of file diff --git a/src/wherecode.c b/src/wherecode.c index 83ee48ac66..94139b6543 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -678,6 +678,7 @@ static int codeCursorHintFixExpr(Walker *pWalker, Expr *pExpr){ ** Insert an OP_CursorHint instruction if it is appropriate to do so. */ static void codeCursorHint( + struct SrcList_item *pTabItem, /* FROM clause item */ WhereInfo *pWInfo, /* The where clause */ WhereLevel *pLevel, /* Which loop to provide hints for */ WhereTerm *pEndRange /* Hint this end-of-scan boundary term if not NULL */ @@ -708,7 +709,31 @@ static void codeCursorHint( pTerm = &pWC->a[i]; if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue; if( pTerm->prereqAll & pLevel->notReady ) continue; - if( ExprHasProperty(pTerm->pExpr, EP_FromJoin) ) continue; + + /* Any terms specified as part of the ON(...) clause for any LEFT + ** JOIN for which the current table is not the rhs are omitted + ** from the cursor-hint. + ** + ** If this table is the rhs of a LEFT JOIN, only terms that were + ** specified as part of the ON(...) clause may be included in the + ** hint. This is to address the following: + ** + ** SELECT ... t1 LEFT JOIN t2 ON (t1.a=t2.b) WHERE t2.c IS NULL; + ** + ** If the (t2.c IS NULL) constraint is pushed down to the cursor, it + ** might filter out all rows that match (t1.a=t2.b), causing SQLite + ** to add a row of NULL values to the output that should not be + ** present (since the ON clause does actually match rows within t2). + */ + if( pTabItem->fg.jointype & JT_LEFT ){ + if( !ExprHasProperty(pTerm->pExpr, EP_FromJoin) + || pTerm->pExpr->iRightJoinTable!=pTabItem->iCursor + ){ + continue; + } + }else{ + if( ExprHasProperty(pTerm->pExpr, EP_FromJoin) ) continue; + } /* All terms in pWLoop->aLTerm[] except pEndRange are used to initialize ** the cursor. These terms are not needed as hints for a pure range @@ -742,7 +767,7 @@ static void codeCursorHint( } } #else -# define codeCursorHint(A,B,C) /* No-op */ +# define codeCursorHint(A,B,C,D) /* No-op */ #endif /* SQLITE_ENABLE_CURSOR_HINTS */ /* @@ -998,7 +1023,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( pStart = pEnd; pEnd = pTerm; } - codeCursorHint(pWInfo, pLevel, pEnd); + codeCursorHint(pTabItem, pWInfo, pLevel, pEnd); if( pStart ){ Expr *pX; /* The expression that defines the start bound */ int r1, rTemp; /* Registers for holding the start boundary */ @@ -1212,7 +1237,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( ** and store the values of those terms in an array of registers ** starting at regBase. */ - codeCursorHint(pWInfo, pLevel, pRangeEnd); + codeCursorHint(pTabItem, pWInfo, pLevel, pRangeEnd); regBase = codeAllEqualityTerms(pParse,pLevel,bRev,nExtraReg,&zStartAff); assert( zStartAff==0 || sqlite3Strlen30(zStartAff)>=nEq ); if( zStartAff ) cEndAff = zStartAff[nEq]; @@ -1660,7 +1685,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( ** a pseudo-cursor. No need to Rewind or Next such cursors. */ pLevel->op = OP_Noop; }else{ - codeCursorHint(pWInfo, pLevel, 0); + codeCursorHint(pTabItem, pWInfo, pLevel, 0); pLevel->op = aStep[bRev]; pLevel->p1 = iCur; pLevel->p2 = 1 + sqlite3VdbeAddOp2(v, aStart[bRev], iCur, addrBrk); diff --git a/test/cursorhint2.test b/test/cursorhint2.test new file mode 100644 index 0000000000..3909678802 --- /dev/null +++ b/test/cursorhint2.test @@ -0,0 +1,101 @@ +# 2016 June 17 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements regression tests for SQLite library. The +# focus is on testing that cursor-hints are correct for queries +# involving LEFT JOIN. +# + + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set ::testprefix cursorhint2 + +ifcapable !cursorhints { + finish_test + return +} + +proc extract_hints {sql} { + + db eval "SELECT tbl_name, rootpage FROM sqlite_master where rootpage" { + set lookup($rootpage) $tbl_name + } + + set ret [list] + db eval "EXPLAIN $sql" a { + switch -- $a(opcode) { + OpenRead { + set csr($a(p1)) $lookup($a(p2)) + } + CursorHint { + lappend ret $csr($a(p1)) $a(p4) + } + } + } + + set ret +} + +proc do_extract_hints_test {tn sql ret} { + uplevel [list do_test $tn [list extract_hints $sql] [list {*}$ret]] +} + +do_execsql_test 1.0 { + PRAGMA automatic_index = 0; + CREATE TABLE t1(a, b); + CREATE TABLE t2(c, d); + CREATE TABLE t3(e, f); +} + +do_extract_hints_test $tn.1.1 { + SELECT * FROM t1 WHERE a=1; +} { + t1 EQ(c0,1) +} + +do_extract_hints_test $tn.1.2 { + SELECT * FROM t1 CROSS JOIN t2 ON (a=c) WHERE d IS NULL; +} { + t2 {AND(ISNULL(c1),EQ(r[1],c0))} +} + +do_extract_hints_test $tn.1.3 { + SELECT * FROM t1 LEFT JOIN t2 ON (a=c) WHERE d IS NULL; +} { + t2 {EQ(r[2],c0)} +} + +do_extract_hints_test $tn.1.4 { + SELECT * FROM t1 LEFT JOIN t2 ON (a=c AND a=10) WHERE d IS NULL; +} { + t2 {AND(EQ(r[2],c0),EQ(r[3],10))} +} + +do_extract_hints_test $tn.1.5 { + SELECT * FROM t1 CROSS JOIN t2 ON (a=c AND a=10) WHERE d IS NULL; +} { + t1 EQ(c0,10) t2 {AND(ISNULL(c1),EQ(r[3],c0))} +} + +do_extract_hints_test $tn.1.6 { + SELECT * FROM t1 LEFT JOIN t2 ON (a=c) LEFT JOIN t3 ON (d=f); +} { + t2 {EQ(r[2],c0)} t3 {EQ(r[6],c1)} +} + +do_extract_hints_test $tn.1.6 { + SELECT * FROM t1 LEFT JOIN t2 ON (a=c AND d=e) LEFT JOIN t3 ON (d=f); +} { + t2 {EQ(r[2],c0)} t3 {EQ(r[6],c1)} +} + +finish_test + From 419b03c1bbd30e455c709d9a16d9512a99d9544f Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 17 Jun 2016 14:47:37 +0000 Subject: [PATCH 0520/1484] Fix a typo in the cursorhint2.test script. FossilOrigin-Name: c1a5a57cf10dca91082963dcbd3e3ffebc3707ef --- manifest | 15 ++++++--------- manifest.uuid | 2 +- test/cursorhint2.test | 14 +++++++------- 3 files changed, 14 insertions(+), 17 deletions(-) diff --git a/manifest b/manifest index 9af4d76b72..627ec4af45 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C If\sa\stable\sis\son\sthe\srhs\sof\sa\sLEFT\sJOIN,\sinclude\sonly\sterms\sfrom\sthe\sjoins\sON(...)\sclause\sin\sthe\scursor-hint\spassed\svia\sOP_CursorHint. -D 2016-06-17T14:33:32.727 +C Fix\sa\stypo\sin\sthe\scursorhint2.test\sscript. +D 2016-06-17T14:47:37.300 F Makefile.in f3f7d2060ce03af4584e711ef3a626ef0b1d6340 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 50149765ef72f4e652b9a0f1f6462c4784bb9423 @@ -617,7 +617,7 @@ F test/cse.test 277350a26264495e86b1785f34d2d0c8600e021c F test/csv01.test 0929a9ce47021519512be92861f29e32d2538e5f F test/ctime.test 7bd009071e242aac4f18521581536b652b789a47 F test/cursorhint.test 7bc346788390475e77a345da2b92270d04d35856 -F test/cursorhint2.test 532fdc678653f73e30770b59af0a47f9af0124ee +F test/cursorhint2.test c4c49b4b34eabc3d61ff111d477113f5c901d7fa F test/date.test 984ac1e3e5e031386866f034006148d3972b4a65 F test/dbstatus.test 8de104bb5606f19537d23cd553b41349b5ab1204 F test/dbstatus2.test e93ab03bfae6d62d4d935f20de928c19ca0ed0ab @@ -1502,10 +1502,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 0b1579caf06a2c42433b8bc9dc28c9ad381aa07c -R 2d1831333befb414525bf922ba35c127 -T *branch * cursor-hints -T *sym-cursor-hints * -T -sym-trunk * +P 2a2346b04235c6d0b7a8e64c92ee31018285c29f +R f8aa0cb7edf61b31b26c82b3f234b1ab U dan -Z b45fbbd37d7e68d5f1357e6143b6a1f1 +Z ac8df9edec12a135c248b7ca97a78998 diff --git a/manifest.uuid b/manifest.uuid index 4e6e68e3f9..bbdc3674bd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2a2346b04235c6d0b7a8e64c92ee31018285c29f \ No newline at end of file +c1a5a57cf10dca91082963dcbd3e3ffebc3707ef \ No newline at end of file diff --git a/test/cursorhint2.test b/test/cursorhint2.test index 3909678802..3a79596036 100644 --- a/test/cursorhint2.test +++ b/test/cursorhint2.test @@ -55,43 +55,43 @@ do_execsql_test 1.0 { CREATE TABLE t3(e, f); } -do_extract_hints_test $tn.1.1 { +do_extract_hints_test 1.1 { SELECT * FROM t1 WHERE a=1; } { t1 EQ(c0,1) } -do_extract_hints_test $tn.1.2 { +do_extract_hints_test 1.2 { SELECT * FROM t1 CROSS JOIN t2 ON (a=c) WHERE d IS NULL; } { t2 {AND(ISNULL(c1),EQ(r[1],c0))} } -do_extract_hints_test $tn.1.3 { +do_extract_hints_test 1.3 { SELECT * FROM t1 LEFT JOIN t2 ON (a=c) WHERE d IS NULL; } { t2 {EQ(r[2],c0)} } -do_extract_hints_test $tn.1.4 { +do_extract_hints_test 1.4 { SELECT * FROM t1 LEFT JOIN t2 ON (a=c AND a=10) WHERE d IS NULL; } { t2 {AND(EQ(r[2],c0),EQ(r[3],10))} } -do_extract_hints_test $tn.1.5 { +do_extract_hints_test 1.5 { SELECT * FROM t1 CROSS JOIN t2 ON (a=c AND a=10) WHERE d IS NULL; } { t1 EQ(c0,10) t2 {AND(ISNULL(c1),EQ(r[3],c0))} } -do_extract_hints_test $tn.1.6 { +do_extract_hints_test 1.6 { SELECT * FROM t1 LEFT JOIN t2 ON (a=c) LEFT JOIN t3 ON (d=f); } { t2 {EQ(r[2],c0)} t3 {EQ(r[6],c1)} } -do_extract_hints_test $tn.1.6 { +do_extract_hints_test 1.6 { SELECT * FROM t1 LEFT JOIN t2 ON (a=c AND d=e) LEFT JOIN t3 ON (d=f); } { t2 {EQ(r[2],c0)} t3 {EQ(r[6],c1)} From c4974414061f90e2ed8184eefc573e557109df8f Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 17 Jun 2016 14:59:40 +0000 Subject: [PATCH 0521/1484] Fix a duplicate test name in cursorhint2.test. FossilOrigin-Name: fcd12b69cee1335224a65aa6d22c4e302b889398 --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/cursorhint2.test | 2 +- test/where3.test | 4 ++-- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 627ec4af45..788c218d3b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\stypo\sin\sthe\scursorhint2.test\sscript. -D 2016-06-17T14:47:37.300 +C Fix\sa\sduplicate\stest\sname\sin\scursorhint2.test. +D 2016-06-17T14:59:40.619 F Makefile.in f3f7d2060ce03af4584e711ef3a626ef0b1d6340 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 50149765ef72f4e652b9a0f1f6462c4784bb9423 @@ -617,7 +617,7 @@ F test/cse.test 277350a26264495e86b1785f34d2d0c8600e021c F test/csv01.test 0929a9ce47021519512be92861f29e32d2538e5f F test/ctime.test 7bd009071e242aac4f18521581536b652b789a47 F test/cursorhint.test 7bc346788390475e77a345da2b92270d04d35856 -F test/cursorhint2.test c4c49b4b34eabc3d61ff111d477113f5c901d7fa +F test/cursorhint2.test aa52c25d84366531af871f0bed91a7147b2b37e8 F test/date.test 984ac1e3e5e031386866f034006148d3972b4a65 F test/dbstatus.test 8de104bb5606f19537d23cd553b41349b5ab1204 F test/dbstatus2.test e93ab03bfae6d62d4d935f20de928c19ca0ed0ab @@ -1376,7 +1376,7 @@ F test/walslow.test c05c68d4dc2700a982f89133ce103a1a84cc285f F test/walthread.test de8dbaf6d9e41481c460ba31ca61e163d7348f8e F test/where.test f0c325563acde44f2c4ea6ba348e9e29f7121757 F test/where2.test 478d2170637b9211f593120648858593bf2445a1 -F test/where3.test 1ad55ba900bd7747f98b6082e65bd3e442c5004e +F test/where3.test 54cdeb02157acc979de41530b804ae7b09552bf1 F test/where4.test 4a371bfcc607f41d233701bdec33ac2972908ba8 F test/where5.test fdf66f96d29a064b63eb543e28da4dfdccd81ad2 F test/where6.test 5da5a98cec820d488e82708301b96cb8c18a258b @@ -1502,7 +1502,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 2a2346b04235c6d0b7a8e64c92ee31018285c29f -R f8aa0cb7edf61b31b26c82b3f234b1ab +P c1a5a57cf10dca91082963dcbd3e3ffebc3707ef +R ae6a6e72981ae73e95b7048747b6cd4f U dan -Z ac8df9edec12a135c248b7ca97a78998 +Z 130058fba07c74a7ae7dc91c3a4fa1a9 diff --git a/manifest.uuid b/manifest.uuid index bbdc3674bd..8c6ce154cd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c1a5a57cf10dca91082963dcbd3e3ffebc3707ef \ No newline at end of file +fcd12b69cee1335224a65aa6d22c4e302b889398 \ No newline at end of file diff --git a/test/cursorhint2.test b/test/cursorhint2.test index 3a79596036..b6ebda2244 100644 --- a/test/cursorhint2.test +++ b/test/cursorhint2.test @@ -91,7 +91,7 @@ do_extract_hints_test 1.6 { t2 {EQ(r[2],c0)} t3 {EQ(r[6],c1)} } -do_extract_hints_test 1.6 { +do_extract_hints_test 1.7 { SELECT * FROM t1 LEFT JOIN t2 ON (a=c AND d=e) LEFT JOIN t3 ON (d=f); } { t2 {EQ(r[2],c0)} t3 {EQ(r[6],c1)} diff --git a/test/where3.test b/test/where3.test index c2804b5579..6edbe2bcad 100644 --- a/test/where3.test +++ b/test/where3.test @@ -45,7 +45,7 @@ do_test where3-1.1 { } } {222 two 2 222 {} {}} -ifcapable explain { +ifcapable explain&&!cursorhints { do_test where3-1.1.1 { explain_no_trace {SELECT * FROM t1, t2 LEFT JOIN t3 ON q=x WHERE p=2 AND a=q} @@ -86,7 +86,7 @@ do_test where3-1.2 { } } {1 {Value for C1.1} {Value for C2.1} 2 {} {Value for C2.2} 3 {Value for C1.3} {Value for C2.3}} -ifcapable explain { +ifcapable explain&&!cursorhints { do_test where3-1.2.1 { explain_no_trace { SELECT parent1.parent1key, child1.value, child2.value From e6912fd8198b3693932bc0ddaffc423a8cec417f Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 17 Jun 2016 19:27:13 +0000 Subject: [PATCH 0522/1484] Include WHERE terms in the cursor-hint passed to a cursor opened for the rhs of a LEFT JOIN iff we can be sure that those terms will not evaluate to true if the LEFT JOIN generates a row of NULLs. FossilOrigin-Name: 998095aba01b75f685ed981b377e1dfe650d9bbf --- manifest | 14 ++++----- manifest.uuid | 2 +- src/wherecode.c | 56 ++++++++++++++++++++++++++++------- test/cursorhint2.test | 69 ++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 122 insertions(+), 19 deletions(-) diff --git a/manifest b/manifest index 788c218d3b..be6f9cf0da 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sduplicate\stest\sname\sin\scursorhint2.test. -D 2016-06-17T14:59:40.619 +C Include\sWHERE\sterms\sin\sthe\scursor-hint\spassed\sto\sa\scursor\sopened\sfor\sthe\srhs\sof\sa\sLEFT\sJOIN\siff\swe\scan\sbe\ssure\sthat\sthose\sterms\swill\snot\sevaluate\sto\strue\sif\sthe\sLEFT\sJOIN\sgenerates\sa\srow\sof\sNULLs. +D 2016-06-17T19:27:13.114 F Makefile.in f3f7d2060ce03af4584e711ef3a626ef0b1d6340 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 50149765ef72f4e652b9a0f1f6462c4784bb9423 @@ -464,7 +464,7 @@ F src/wal.h 2f7c831cf3b071fa548bf2d5cac640846a7ff19c F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354 F src/where.c 74f0798525b6306682d7234f230ea93f86959b9b F src/whereInt.h e5b939701a7ceffc5a3a8188a37f9746416ebcd0 -F src/wherecode.c b9d5f7d8ebed2e09376fd785a111ffd9dfd59ffc +F src/wherecode.c c1b11ad09468577afd3c36cd8c854fb6dd77f258 F src/whereexpr.c c32d47085dbaca0b8fd013210f56693c7d220d48 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -617,7 +617,7 @@ F test/cse.test 277350a26264495e86b1785f34d2d0c8600e021c F test/csv01.test 0929a9ce47021519512be92861f29e32d2538e5f F test/ctime.test 7bd009071e242aac4f18521581536b652b789a47 F test/cursorhint.test 7bc346788390475e77a345da2b92270d04d35856 -F test/cursorhint2.test aa52c25d84366531af871f0bed91a7147b2b37e8 +F test/cursorhint2.test cef69bab25b9141071b4239fa5c3b4ce18eeafd0 F test/date.test 984ac1e3e5e031386866f034006148d3972b4a65 F test/dbstatus.test 8de104bb5606f19537d23cd553b41349b5ab1204 F test/dbstatus2.test e93ab03bfae6d62d4d935f20de928c19ca0ed0ab @@ -1502,7 +1502,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P c1a5a57cf10dca91082963dcbd3e3ffebc3707ef -R ae6a6e72981ae73e95b7048747b6cd4f +P fcd12b69cee1335224a65aa6d22c4e302b889398 +R aa7c436ce5d8105be03298dc84afa8de U dan -Z 130058fba07c74a7ae7dc91c3a4fa1a9 +Z a2cf93e232f8c6f0bcf6400999626f67 diff --git a/manifest.uuid b/manifest.uuid index 8c6ce154cd..efb8ac0335 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fcd12b69cee1335224a65aa6d22c4e302b889398 \ No newline at end of file +998095aba01b75f685ed981b377e1dfe650d9bbf \ No newline at end of file diff --git a/src/wherecode.c b/src/wherecode.c index 94139b6543..e6294de532 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -626,6 +626,31 @@ static int codeCursorHintCheckExpr(Walker *pWalker, Expr *pExpr){ return WRC_Continue; } +/* +** Test whether or not expression pExpr, which was part of a WHERE clause, +** should be included in the cursor-hint for a table that is on the rhs +** of a LEFT JOIN. Set Walker.eCode to non-zero before returning if the +** expression is not suitable. +** +** An expression is unsuitable if it might evaluate to non NULL even if +** a TK_COLUMN node that does affect the value of the expression is set +** to NULL. For example: +** +** col IS NULL +** col IS NOT NULL +** coalesce(col, 1) +** CASE WHEN col THEN 0 ELSE 1 END +*/ +static int codeCursorHintIsOrFunction(Walker *pWalker, Expr *pExpr){ + if( pExpr->op==TK_IS || pExpr->op==TK_FUNCTION + || pExpr->op==TK_ISNULL || pExpr->op==TK_ISNOT + || pExpr->op==TK_NOTNULL || pExpr->op==TK_CASE + ){ + pWalker->eCode = 1; + } + return WRC_Continue; +} + /* ** This function is called on every node of an expression tree used as an @@ -714,22 +739,33 @@ static void codeCursorHint( ** JOIN for which the current table is not the rhs are omitted ** from the cursor-hint. ** - ** If this table is the rhs of a LEFT JOIN, only terms that were - ** specified as part of the ON(...) clause may be included in the - ** hint. This is to address the following: + ** If this table is the rhs of a LEFT JOIN, "IS" or "IS NULL" terms + ** that were specified as part of the WHERE clause must be excluded. + ** This is to address the following: ** ** SELECT ... t1 LEFT JOIN t2 ON (t1.a=t2.b) WHERE t2.c IS NULL; ** - ** If the (t2.c IS NULL) constraint is pushed down to the cursor, it - ** might filter out all rows that match (t1.a=t2.b), causing SQLite - ** to add a row of NULL values to the output that should not be - ** present (since the ON clause does actually match rows within t2). + ** Say there is a single row in t2 that matches (t1.a=t2.b), but its + ** t2.c values is not NULL. If the (t2.c IS NULL) constraint is + ** pushed down to the cursor, this row is filtered out, causing + ** SQLite to synthesize a row of NULL values. Which does match the + ** WHERE clause, and so the query returns a row. Which is incorrect. + ** + ** For the same reason, WHERE terms such as: + ** + ** WHERE 1 = (t2.c IS NULL) + ** + ** are also excluded. See codeCursorHintIsOrFunction() for details. */ if( pTabItem->fg.jointype & JT_LEFT ){ - if( !ExprHasProperty(pTerm->pExpr, EP_FromJoin) - || pTerm->pExpr->iRightJoinTable!=pTabItem->iCursor + Expr *pExpr = pTerm->pExpr; + if( !ExprHasProperty(pExpr, EP_FromJoin) + || pExpr->iRightJoinTable!=pTabItem->iCursor ){ - continue; + sWalker.eCode = 0; + sWalker.xExprCallback = codeCursorHintIsOrFunction; + sqlite3WalkExpr(&sWalker, pTerm->pExpr); + if( sWalker.eCode ) continue; } }else{ if( ExprHasProperty(pTerm->pExpr, EP_FromJoin) ) continue; diff --git a/test/cursorhint2.test b/test/cursorhint2.test index b6ebda2244..b42227cdfb 100644 --- a/test/cursorhint2.test +++ b/test/cursorhint2.test @@ -94,7 +94,74 @@ do_extract_hints_test 1.6 { do_extract_hints_test 1.7 { SELECT * FROM t1 LEFT JOIN t2 ON (a=c AND d=e) LEFT JOIN t3 ON (d=f); } { - t2 {EQ(r[2],c0)} t3 {EQ(r[6],c1)} + t2 {EQ(r[2],c0)} t3 {AND(EQ(r[6],c0),EQ(r[7],c1))} +} + +#------------------------------------------------------------------------- +# +do_execsql_test 2.0 { + CREATE TABLE x1(x, y); + CREATE TABLE x2(a, b); +} + +do_extract_hints_test 2.1 { + SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE b IS NULL; +} { + x2 {EQ(c0,r[2])} +} + +do_extract_hints_test 2.2 { + SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE b IS +NULL; +} { + x2 {EQ(c0,r[2])} +} + +do_extract_hints_test 2.3 { + SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE 1 = (b IS NULL) +} { + x2 {EQ(c0,r[2])} +} + +do_extract_hints_test 2.4 { + SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE 1 = coalesce(b, 1) +} { + x2 {EQ(c0,r[2])} +} + +do_extract_hints_test 2.5 { + SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE 1 = coalesce(b, 1) +} { + x2 {EQ(c0,r[2])} +} + +do_extract_hints_test 2.6 { + SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE 0 = (b IS NOT NULL) +} { + x2 {EQ(c0,r[2])} +} + +do_extract_hints_test 2.7 { + SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE 0 = (b IS NOT +NULL) +} { + x2 {EQ(c0,r[2])} +} + +do_extract_hints_test 2.8 { + SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE b IS NOT +NULL +} { + x2 {EQ(c0,r[2])} +} + +do_extract_hints_test 2.9 { + SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE CASE b WHEN 0 THEN 0 ELSE 1 END; +} { + x2 {EQ(c0,r[2])} +} + +do_extract_hints_test 2.10 { + SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE x2.b = 32+32 +} { + x2 {AND(EQ(c1,ADD(32,32)),EQ(c0,r[2]))} } finish_test From 2b693d63e43b747169be6dcd4541a678eeb9b860 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 20 Jun 2016 17:22:06 +0000 Subject: [PATCH 0523/1484] Allow LIKE operators that appear in a WHERE clause to be included in the cursor-hint for a cursor on the rhs of a LEFT JOIN. FossilOrigin-Name: 7455d932f5079ffe40462a8c119fc22b8a9bcbcc --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/wherecode.c | 9 ++++++++- test/cursorhint2.test | 12 ++++++++++++ 4 files changed, 28 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index be6f9cf0da..a231acf082 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Include\sWHERE\sterms\sin\sthe\scursor-hint\spassed\sto\sa\scursor\sopened\sfor\sthe\srhs\sof\sa\sLEFT\sJOIN\siff\swe\scan\sbe\ssure\sthat\sthose\sterms\swill\snot\sevaluate\sto\strue\sif\sthe\sLEFT\sJOIN\sgenerates\sa\srow\sof\sNULLs. -D 2016-06-17T19:27:13.114 +C Allow\sLIKE\soperators\sthat\sappear\sin\sa\sWHERE\sclause\sto\sbe\sincluded\sin\sthe\scursor-hint\sfor\sa\scursor\son\sthe\srhs\sof\sa\sLEFT\sJOIN. +D 2016-06-20T17:22:06.973 F Makefile.in f3f7d2060ce03af4584e711ef3a626ef0b1d6340 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 50149765ef72f4e652b9a0f1f6462c4784bb9423 @@ -464,7 +464,7 @@ F src/wal.h 2f7c831cf3b071fa548bf2d5cac640846a7ff19c F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354 F src/where.c 74f0798525b6306682d7234f230ea93f86959b9b F src/whereInt.h e5b939701a7ceffc5a3a8188a37f9746416ebcd0 -F src/wherecode.c c1b11ad09468577afd3c36cd8c854fb6dd77f258 +F src/wherecode.c e20cb381ff621e56a4684c71e31999aca2547ca6 F src/whereexpr.c c32d47085dbaca0b8fd013210f56693c7d220d48 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -617,7 +617,7 @@ F test/cse.test 277350a26264495e86b1785f34d2d0c8600e021c F test/csv01.test 0929a9ce47021519512be92861f29e32d2538e5f F test/ctime.test 7bd009071e242aac4f18521581536b652b789a47 F test/cursorhint.test 7bc346788390475e77a345da2b92270d04d35856 -F test/cursorhint2.test cef69bab25b9141071b4239fa5c3b4ce18eeafd0 +F test/cursorhint2.test 2b45341d32d1aae9991a00ef31ebca339b274255 F test/date.test 984ac1e3e5e031386866f034006148d3972b4a65 F test/dbstatus.test 8de104bb5606f19537d23cd553b41349b5ab1204 F test/dbstatus2.test e93ab03bfae6d62d4d935f20de928c19ca0ed0ab @@ -1502,7 +1502,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P fcd12b69cee1335224a65aa6d22c4e302b889398 -R aa7c436ce5d8105be03298dc84afa8de +P 998095aba01b75f685ed981b377e1dfe650d9bbf +R 6b36cf1cbd5dc0e94253a2a90e40c230 U dan -Z a2cf93e232f8c6f0bcf6400999626f67 +Z 7f5e55d96c0f8c6a30345a5c923b92ab diff --git a/manifest.uuid b/manifest.uuid index efb8ac0335..a65de1e449 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -998095aba01b75f685ed981b377e1dfe650d9bbf \ No newline at end of file +7455d932f5079ffe40462a8c119fc22b8a9bcbcc \ No newline at end of file diff --git a/src/wherecode.c b/src/wherecode.c index e6294de532..a017b40c7d 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -642,12 +642,19 @@ static int codeCursorHintCheckExpr(Walker *pWalker, Expr *pExpr){ ** CASE WHEN col THEN 0 ELSE 1 END */ static int codeCursorHintIsOrFunction(Walker *pWalker, Expr *pExpr){ - if( pExpr->op==TK_IS || pExpr->op==TK_FUNCTION + if( pExpr->op==TK_IS || pExpr->op==TK_ISNULL || pExpr->op==TK_ISNOT || pExpr->op==TK_NOTNULL || pExpr->op==TK_CASE ){ pWalker->eCode = 1; + }else if( pExpr->op==TK_FUNCTION ){ + int d1; + char d2[3]; + if( 0==sqlite3IsLikeFunction(pWalker->pParse->db, pExpr, &d1, d2) ){ + pWalker->eCode = 1; + } } + return WRC_Continue; } diff --git a/test/cursorhint2.test b/test/cursorhint2.test index b42227cdfb..3444fdf441 100644 --- a/test/cursorhint2.test +++ b/test/cursorhint2.test @@ -164,5 +164,17 @@ do_extract_hints_test 2.10 { x2 {AND(EQ(c1,ADD(32,32)),EQ(c0,r[2]))} } +do_extract_hints_test 2.11 { + SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE x2.b LIKE 'abc%' +} { + x2 {AND(expr,EQ(c0,r[2]))} +} + +do_extract_hints_test 2.11 { + SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE coalesce(x2.b, 1) +} { + x2 {EQ(c0,r[2])} +} + finish_test From 9c987a833cf767c7d07c071c25b353623e60ad2a Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 21 Jun 2016 10:34:41 +0000 Subject: [PATCH 0524/1484] Update the sqldiff utility so that if the --vtab switch is specified "rtree", "fts3", "fts4" and "fts5" tables are diff'd directly and the underlying real database tables ignored. Without this switch, all virtual tables are ignored and the diff is performed on the underlying real tables. FossilOrigin-Name: 5d0a9d4c45730e47576bc77373fa7075a74051a5 --- ext/rbu/rbudiff.test | 69 +++++++++++++++++++- manifest | 18 ++--- manifest.uuid | 2 +- tool/sqldiff.c | 152 ++++++++++++++++++++++++++++++++++++++++--- 4 files changed, 221 insertions(+), 20 deletions(-) diff --git a/ext/rbu/rbudiff.test b/ext/rbu/rbudiff.test index 0863f6e807..fa8de319dd 100644 --- a/ext/rbu/rbudiff.test +++ b/ext/rbu/rbudiff.test @@ -25,6 +25,10 @@ proc get_rbudiff_sql {db1 db2} { exec $::PROG --rbu $db1 $db2 } +proc get_vtab_rbudiff_sql {db1 db2} { + exec $::PROG --vtab --rbu $db1 $db2 +} + proc step_rbu {target rbu} { while 1 { sqlite3rbu rbu $target $rbu @@ -44,6 +48,11 @@ proc apply_rbudiff {sql target} { step_rbu $target rbu.db } +proc sqlesc {id} { + set ret "'[string map {' ''} $id]'" + set ret +} + # The only argument is the output of an [sqldiff -rbu] run. This command # tests that the contents of the rbu_count table is correct. An exception # is thrown if it is not. @@ -54,7 +63,7 @@ proc test_rbucount {sql} { tmpdb eval { SELECT name FROM sqlite_master WHERE name LIKE 'data%' AND type='table' } { - set a [tmpdb eval "SELECT count(*) FROM $name"] + set a [tmpdb eval "SELECT count(*) FROM [sqlesc $name]"] set b [tmpdb eval {SELECT cnt FROM rbu_count WHERE tbl = $name}] if {$a != $b} { tmpdb close @@ -71,9 +80,11 @@ proc rbudiff_cksum {db1} { sqlite3 dbtmp $db1 foreach tbl [dbtmp eval {SELECT name FROM sqlite_master WHERE type='table'}] { set cols [list] - dbtmp eval "PRAGMA table_info = $tbl" { lappend cols "quote( $name )" } + dbtmp eval "PRAGMA table_info = [sqlesc $tbl]" { + lappend cols "quote( $name )" + } append txt [dbtmp eval \ - "SELECT [join $cols {||'.'||}] FROM $tbl ORDER BY 1" + "SELECT [join $cols {||'.'||}] FROM [sqlesc $tbl] ORDER BY 1" ] } dbtmp close @@ -159,5 +170,57 @@ foreach {tn init mod} { do_test 1.$tn.5 { rbudiff_cksum test.db } [rbudiff_cksum test.db2] } +#------------------------------------------------------------------------- +# Test that if the --vtab switch is present, [sqldiff] handles virtual +# table types fts[345] and rtree correctly. +# +ifcapable fts3&&fts5&&rtree { + +foreach {tn init mod} { + 1 { + CREATE VIRTUAL TABLE t1 USING fts5(c); + INSERT INTO t1 VALUES('a b c'); + INSERT INTO t1 VALUES('a b c'); + } { + DELETE FROM t1 WHERE rowid = 1; + INSERT INTO t1 VALUES('a b c'); + } + + 2 { + CREATE VIRTUAL TABLE "x y" USING 'rtree'(id, x1, x2); + INSERT INTO "x y" VALUES(1, 2, 3); + INSERT INTO "x y" VALUES(2, 4, 6); + } { + DELETE FROM "x y" WHERE rowid = 1; + INSERT INTO "x y" VALUES(3, 6, 9); + } + + 3 { + CREATE VIRTUAL TABLE 'x''y' USING fts3; + INSERT INTO 'x''y' VALUES('one two three'); + INSERT INTO 'x''y' VALUES('four five six'); + } { + DELETE FROM 'x''y' WHERE rowid = 1; + INSERT INTO 'x''y' VALUES('one two three'); + } + +} { + + forcedelete test.db test.db2 + sqlite3 db test.db + db eval "$init" + sqlite3 db test.db2 + db eval "$init ; $mod" + db close + + do_test 2.$tn.1 { + set sql [get_vtab_rbudiff_sql test.db test.db2] + apply_rbudiff $sql test.db + } {SQLITE_DONE} + do_test 2.$tn.2 { rbudiff_cksum test.db } [rbudiff_cksum test.db2] +} + +} + finish_test diff --git a/manifest b/manifest index f7bf4fc9ff..12c06cd44f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C For\sa\stable\son\sthe\srhs\sof\sa\sLEFT\sJOIN\soperator,\sdo\snot\sinclude\sterms\slike\s"IS\sNULL"\sfrom\sthe\sWHERE\sclause\sin\sthe\scursor-hint.\sThese\smay\sbe\sfalse\sfor\srows\sthat\sthe\scursor\swould\sotherwise\svisit,\sbut\strue\sfor\sa\srow\sof\sall\sNULL\svalues\sgenerated\sby\sthe\sLEFT\sJOIN. -D 2016-06-20T17:25:50.750 +C Update\sthe\ssqldiff\sutility\sso\sthat\sif\sthe\s--vtab\sswitch\sis\sspecified\s"rtree",\s"fts3",\s"fts4"\sand\s"fts5"\stables\sare\sdiff'd\sdirectly\sand\sthe\sunderlying\sreal\sdatabase\stables\signored.\sWithout\sthis\sswitch,\sall\svirtual\stables\sare\signored\sand\sthe\sdiff\sis\sperformed\son\sthe\sunderlying\sreal\stables. +D 2016-06-21T10:34:41.782 F Makefile.in f3f7d2060ce03af4584e711ef3a626ef0b1d6340 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 50149765ef72f4e652b9a0f1f6462c4784bb9423 @@ -243,7 +243,7 @@ F ext/rbu/rbuB.test c25bc325b8072a766e56bb76c001866b405925c2 F ext/rbu/rbuC.test efe47db508a0269b683cb2a1913a425ffd39a831 F ext/rbu/rbu_common.tcl 3a4b916b6f5dca9c9da9a30863e272fe5ea4414f F ext/rbu/rbucrash.test 8d2ed5d4b05fef6c00c2a6b5f7ead71fa172a695 -F ext/rbu/rbudiff.test 2df0a8a7d998ecf81764c21eeda3cde5611c5091 +F ext/rbu/rbudiff.test 4c9f8df6f723f553781d3d117501b7e9d170a145 F ext/rbu/rbufault.test cc0be8d5d392d98b0c2d6a51be377ea989250a89 F ext/rbu/rbufault2.test 9a7f19edd6ea35c4c9f807d8a3db0a03a5670c06 F ext/rbu/rbufault3.test 54a399888ac4af44c68f9f58afbed23149428bca @@ -1469,7 +1469,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 7ce07da76b5e745783e703a834417d725b7d45fd F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c -F tool/sqldiff.c ca315aca4e2d24233e8f2000edea5880c53d1875 +F tool/sqldiff.c 131e9c6e09d3d78e3c4ae8b5fd23451521723aac F tool/srcck1.c 4c39bdfa9a92edd20233ee720df84dbeb2417602 F tool/stack_usage.tcl f8e71b92cdb099a147dad572375595eae55eca43 F tool/symbols-mingw.sh 4dbcea7e74768305384c9fd2ed2b41bbf9f0414d @@ -1502,8 +1502,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 0b1579caf06a2c42433b8bc9dc28c9ad381aa07c 7455d932f5079ffe40462a8c119fc22b8a9bcbcc -R 6b36cf1cbd5dc0e94253a2a90e40c230 -T +closed 7455d932f5079ffe40462a8c119fc22b8a9bcbcc +P 913e595615e2ef40fb431f6e7678f6fc8439782e +R a344dc9988f1497ebec3b8ad168c1397 +T *branch * sqldiff-vtab-support +T *sym-sqldiff-vtab-support * +T -sym-trunk * U dan -Z 537cf80c06fd3994884c97d3059d4966 +Z 6909c0a252ed2326d78857113119f0ab diff --git a/manifest.uuid b/manifest.uuid index 53806979d6..677a251025 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -913e595615e2ef40fb431f6e7678f6fc8439782e \ No newline at end of file +5d0a9d4c45730e47576bc77373fa7075a74051a5 \ No newline at end of file diff --git a/tool/sqldiff.c b/tool/sqldiff.c index 319acafdbd..4a5389c603 100644 --- a/tool/sqldiff.c +++ b/tool/sqldiff.c @@ -33,6 +33,7 @@ struct GlobalVars { const char *zArgv0; /* Name of program */ int bSchemaOnly; /* Only show schema differences */ int bSchemaPK; /* Use the schema-defined PK, not the true PK */ + int bHandleVtab; /* Handle fts3, fts4, fts5 and rtree vtabs */ unsigned fDebug; /* Debug flags */ sqlite3 *db; /* The database connection */ } g; @@ -1735,6 +1736,144 @@ end_changeset_one_table: sqlite3_free(zId); } +/* +** Extract the next SQL keyword or quoted string from buffer zIn and copy it +** (or a prefix of it if it will not fit) into buffer zBuf, size nBuf bytes. +** Return a pointer to the character within zIn immediately following +** the token or quoted string just extracted. +*/ +const char *gobble_token(const char *zIn, char *zBuf, int nBuf){ + const char *p = zIn; + char *pOut = zBuf; + char *pEnd = &pOut[nBuf-1]; + char q = 0; /* quote character, if any */ + + if( p==0 ) return 0; + while( *p==' ' ) p++; + switch( *p ){ + case '"': q = '"'; break; + case '\'': q = '\''; break; + case '`': q = '`'; break; + case '[': q = ']'; break; + } + + if( q ){ + p++; + while( *p && pOut Date: Thu, 23 Jun 2016 12:35:04 +0000 Subject: [PATCH 0525/1484] Fix the build for -DSQLITE_OMIT_VIRTUALTABLE FossilOrigin-Name: 911131424857430d46784b167399ecf192584ca2 --- manifest | 15 +++++++-------- manifest.uuid | 2 +- src/where.c | 5 ++++- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index f7bf4fc9ff..5a9145709f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C For\sa\stable\son\sthe\srhs\sof\sa\sLEFT\sJOIN\soperator,\sdo\snot\sinclude\sterms\slike\s"IS\sNULL"\sfrom\sthe\sWHERE\sclause\sin\sthe\scursor-hint.\sThese\smay\sbe\sfalse\sfor\srows\sthat\sthe\scursor\swould\sotherwise\svisit,\sbut\strue\sfor\sa\srow\sof\sall\sNULL\svalues\sgenerated\sby\sthe\sLEFT\sJOIN. -D 2016-06-20T17:25:50.750 +C Fix\sthe\sbuild\sfor\s-DSQLITE_OMIT_VIRTUALTABLE +D 2016-06-23T12:35:04.863 F Makefile.in f3f7d2060ce03af4584e711ef3a626ef0b1d6340 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 50149765ef72f4e652b9a0f1f6462c4784bb9423 @@ -462,7 +462,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 02eeecc265f6ffd0597378f5d8ae9070b62a406a F src/wal.h 2f7c831cf3b071fa548bf2d5cac640846a7ff19c F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354 -F src/where.c 74f0798525b6306682d7234f230ea93f86959b9b +F src/where.c 0ce4793497af2feb051147a5cc6356f95d3ab381 F src/whereInt.h e5b939701a7ceffc5a3a8188a37f9746416ebcd0 F src/wherecode.c e20cb381ff621e56a4684c71e31999aca2547ca6 F src/whereexpr.c c32d47085dbaca0b8fd013210f56693c7d220d48 @@ -1502,8 +1502,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 0b1579caf06a2c42433b8bc9dc28c9ad381aa07c 7455d932f5079ffe40462a8c119fc22b8a9bcbcc -R 6b36cf1cbd5dc0e94253a2a90e40c230 -T +closed 7455d932f5079ffe40462a8c119fc22b8a9bcbcc -U dan -Z 537cf80c06fd3994884c97d3059d4966 +P 913e595615e2ef40fb431f6e7678f6fc8439782e +R b96a3531b275feb80cf3ff7b27074eda +U drh +Z 55a9839fb9d4bac563e41eaf1345cb2c diff --git a/manifest.uuid b/manifest.uuid index 53806979d6..993a909ccc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -913e595615e2ef40fb431f6e7678f6fc8439782e \ No newline at end of file +911131424857430d46784b167399ecf192584ca2 \ No newline at end of file diff --git a/src/where.c b/src/where.c index e5a476c00a..46fcb4a158 100644 --- a/src/where.c +++ b/src/where.c @@ -3240,6 +3240,7 @@ static int whereLoopAddAll(WhereLoopBuilder *pBuilder){ mPrereq = mPrior; } priorJointype = pItem->fg.jointype; +#ifndef SQLITE_OMIT_VIRTUALTABLE if( IsVirtual(pItem->pTab) ){ struct SrcList_item *p; for(p=&pItem[1]; p Date: Fri, 24 Jun 2016 02:50:44 +0000 Subject: [PATCH 0526/1484] Fix the Makefile.in to avoid unnecessary recompiles of sqlite3.c. FossilOrigin-Name: 67c39e16442d9359b24d60d5f97bd66c19eff16a --- Makefile.in | 22 +++++++++++----------- manifest | 15 +++++++-------- manifest.uuid | 2 +- 3 files changed, 19 insertions(+), 20 deletions(-) diff --git a/Makefile.in b/Makefile.in index 29c9174afa..b9f684e617 100644 --- a/Makefile.in +++ b/Makefile.in @@ -588,15 +588,15 @@ sqlite3$(TEXE): $(TOP)/src/shell.c sqlite3.c $(TOP)/src/shell.c sqlite3.c \ $(LIBREADLINE) $(TLIBS) -rpath "$(libdir)" -sqldiff$(TEXE): $(TOP)/tool/sqldiff.c sqlite3.c sqlite3.h - $(LTLINK) -o $@ $(TOP)/tool/sqldiff.c sqlite3.c $(TLIBS) +sqldiff$(TEXE): $(TOP)/tool/sqldiff.c sqlite3.lo sqlite3.h + $(LTLINK) -o $@ $(TOP)/tool/sqldiff.c sqlite3.lo $(TLIBS) -dbhash$(TEXE): $(TOP)/tool/dbhash.c sqlite3.c sqlite3.h - $(LTLINK) -o $@ $(TOP)/tool/dbhash.c sqlite3.c $(TLIBS) +dbhash$(TEXE): $(TOP)/tool/dbhash.c sqlite3.lo sqlite3.h + $(LTLINK) -o $@ $(TOP)/tool/dbhash.c sqlite3.lo $(TLIBS) -scrub$(TEXE): $(TOP)/ext/misc/scrub.c sqlite3.o +scrub$(TEXE): $(TOP)/ext/misc/scrub.c sqlite3.lo $(LTLINK) -o $@ -I. -DSCRUB_STANDALONE \ - $(TOP)/ext/misc/scrub.c sqlite3.o $(TLIBS) + $(TOP)/ext/misc/scrub.c sqlite3.lo $(TLIBS) srcck1$(BEXE): $(TOP)/tool/srcck1.c $(BCC) -o srcck1$(BEXE) $(TOP)/tool/srcck1.c @@ -611,8 +611,8 @@ fuzzershell$(TEXE): $(TOP)/tool/fuzzershell.c sqlite3.c sqlite3.h fuzzcheck$(TEXE): $(TOP)/test/fuzzcheck.c sqlite3.c sqlite3.h $(LTLINK) -o $@ $(FUZZCHECK_OPT) $(TOP)/test/fuzzcheck.c sqlite3.c $(TLIBS) -mptester$(TEXE): sqlite3.c $(TOP)/mptest/mptest.c - $(LTLINK) -o $@ -I. $(TOP)/mptest/mptest.c sqlite3.c \ +mptester$(TEXE): sqlite3.lo $(TOP)/mptest/mptest.c + $(LTLINK) -o $@ -I. $(TOP)/mptest/mptest.c sqlite3.lo \ $(TLIBS) -rpath "$(libdir)" MPTEST1=./mptester$(TEXE) mptest.db $(TOP)/mptest/crash01.test --repeat 20 @@ -1156,8 +1156,8 @@ rollback-test$(TEXE): $(TOP)/tool/rollback-test.c sqlite3.lo LogEst$(TEXE): $(TOP)/tool/logest.c sqlite3.h $(LTLINK) -I. -o $@ $(TOP)/tool/logest.c -wordcount$(TEXE): $(TOP)/test/wordcount.c sqlite3.c - $(LTLINK) -o $@ $(TOP)/test/wordcount.c sqlite3.c $(TLIBS) +wordcount$(TEXE): $(TOP)/test/wordcount.c sqlite3.lo + $(LTLINK) -o $@ $(TOP)/test/wordcount.c sqlite3.lo $(TLIBS) speedtest1$(TEXE): $(TOP)/test/speedtest1.c sqlite3.lo $(LTLINK) -o $@ $(TOP)/test/speedtest1.c sqlite3.lo $(TLIBS) @@ -1174,7 +1174,7 @@ loadfts$(EXE): $(TOP)/tool/loadfts.c libsqlite3.la # VALIDIDS=' sqlite3(changeset|changegroup|session)?_' checksymbols: sqlite3.lo - nm -g --defined-only sqlite3.o | egrep -v $(VALIDIDS); test $$? -ne 0 + nm -g --defined-only sqlite3.lo | egrep -v $(VALIDIDS); test $$? -ne 0 echo '0 errors out of 1 tests' # Build the amalgamation-autoconf package. The amalamgation-tarball target builds diff --git a/manifest b/manifest index 6ede4001aa..c80dd74edf 100644 --- a/manifest +++ b/manifest @@ -1,6 +1,6 @@ -C Update\sthe\ssqldiff\sutility\sso\sthat\sif\sthe\s--vtab\sswitch\sis\sspecified\s"rtree",\s"fts3",\s"fts4"\sand\s"fts5"\stables\sare\sdiff'd\sdirectly\sand\sthe\sunderlying\sreal\sdatabase\stables\signored.\sWithout\sthis\sswitch,\sall\svirtual\stables\sare\signored\sand\sthe\sdiff\sis\sperformed\son\sthe\sunderlying\sreal\stables. -D 2016-06-23T16:48:35.249 -F Makefile.in f3f7d2060ce03af4584e711ef3a626ef0b1d6340 +C Fix\sthe\sMakefile.in\sto\savoid\sunnecessary\srecompiles\sof\ssqlite3.c. +D 2016-06-24T02:50:44.909 +F Makefile.in bc2b4864a23a4a21c3e26d7b4350f51bab324d45 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 50149765ef72f4e652b9a0f1f6462c4784bb9423 F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7 @@ -1502,8 +1502,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 911131424857430d46784b167399ecf192584ca2 5d0a9d4c45730e47576bc77373fa7075a74051a5 -R 208a102d85ab541408c6c49f684969ef -T +closed 5d0a9d4c45730e47576bc77373fa7075a74051a5 -U dan -Z c85e872c7e55cfaaf069baf7060cb813 +P b8671e9434180878cfe15d70b793fdee69aabccf +R bb5fcfa23277d6cebd22a760da9dcde6 +U drh +Z 138a4cc0f4ecfcd1f7ccb81cfc01b8ef diff --git a/manifest.uuid b/manifest.uuid index e7770916f2..8c3593deb6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b8671e9434180878cfe15d70b793fdee69aabccf \ No newline at end of file +67c39e16442d9359b24d60d5f97bd66c19eff16a \ No newline at end of file From f5fe00399f545bdc2d121472f4e76547f3d2fdb1 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 24 Jun 2016 06:23:13 +0000 Subject: [PATCH 0527/1484] Fix the ctime.test script so that it works with clang. FossilOrigin-Name: 77e4f7a36e6e0ebe842bcb36b2557a5bfba90d3f --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/ctime.test | 5 +++-- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index c80dd74edf..0af6528b9d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\sMakefile.in\sto\savoid\sunnecessary\srecompiles\sof\ssqlite3.c. -D 2016-06-24T02:50:44.909 +C Fix\sthe\sctime.test\sscript\sso\sthat\sit\sworks\swith\sclang. +D 2016-06-24T06:23:13.369 F Makefile.in bc2b4864a23a4a21c3e26d7b4350f51bab324d45 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 50149765ef72f4e652b9a0f1f6462c4784bb9423 @@ -615,7 +615,7 @@ F test/crashtest1.c 09c1c7d728ccf4feb9e481671e29dda5669bbcc2 F test/createtab.test b5de160630b209c4b8925bdcbbaf48cc90b67fe8 F test/cse.test 277350a26264495e86b1785f34d2d0c8600e021c F test/csv01.test 0929a9ce47021519512be92861f29e32d2538e5f -F test/ctime.test 7bd009071e242aac4f18521581536b652b789a47 +F test/ctime.test 0b995accd44a52914bd4744d5c1b6e1a56c7897c F test/cursorhint.test 7bc346788390475e77a345da2b92270d04d35856 F test/cursorhint2.test 2b45341d32d1aae9991a00ef31ebca339b274255 F test/date.test 984ac1e3e5e031386866f034006148d3972b4a65 @@ -1502,7 +1502,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b8671e9434180878cfe15d70b793fdee69aabccf -R bb5fcfa23277d6cebd22a760da9dcde6 +P 67c39e16442d9359b24d60d5f97bd66c19eff16a +R 7e79191b4d7cf82834abc676eac1270e U drh -Z 138a4cc0f4ecfcd1f7ccb81cfc01b8ef +Z 811d7c2149778ab6cb4ca3f8ac5802c8 diff --git a/manifest.uuid b/manifest.uuid index 8c3593deb6..d7b3218dfe 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -67c39e16442d9359b24d60d5f97bd66c19eff16a \ No newline at end of file +77e4f7a36e6e0ebe842bcb36b2557a5bfba90d3f \ No newline at end of file diff --git a/test/ctime.test b/test/ctime.test index e4cb156168..efdf170851 100644 --- a/test/ctime.test +++ b/test/ctime.test @@ -196,9 +196,10 @@ set tc 1 foreach opt $opts { do_test ctime-2.5.$tc { set N [ expr {$tc-1} ] - set ans1 [ catchsql { + set ans1 [catch {db one { SELECT sqlite_compileoption_get($N); - } ] + }} msg] + lappend ans1 $msg set ans2 [ catchsql { SELECT sqlite_compileoption_used($opt); } ] From 4b37cd49a615dc12b39beb8389710f40358da1ac Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 25 Jun 2016 11:43:47 +0000 Subject: [PATCH 0528/1484] Fix the handling of OP_Eq opcodes that compare a register against itself and that require an affinity change. FossilOrigin-Name: 507014e4c7a70cd09410c89c8ed466c8edab39d2 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/vdbe.c | 2 ++ test/selectA.test | 9 +++++++++ 4 files changed, 19 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 0af6528b9d..cd94ec1c26 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\sctime.test\sscript\sso\sthat\sit\sworks\swith\sclang. -D 2016-06-24T06:23:13.369 +C Fix\sthe\shandling\sof\sOP_Eq\sopcodes\sthat\scompare\sa\sregister\sagainst\sitself\nand\sthat\srequire\san\saffinity\schange. +D 2016-06-25T11:43:47.381 F Makefile.in bc2b4864a23a4a21c3e26d7b4350f51bab324d45 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 50149765ef72f4e652b9a0f1f6462c4784bb9423 @@ -448,7 +448,7 @@ F src/update.c 4f05ea8cddfa367d045e03589756c02199e8f9bd F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 810ec3f22e2d1b62e66c30fe3621ebdedd23584d F src/vacuum.c feb1eabb20987983d9350cad98299b21fa811f52 -F src/vdbe.c e23a15d352e63b51cf08af8052e678e67c54ec09 +F src/vdbe.c 22b46c3b725e950e9f2760e2d76953d592600ad4 F src/vdbe.h 5591b5add447096e31288b5a0a78ec5d7b5c5170 F src/vdbeInt.h ddb157974436d87652de7dc641f7191496d9a8cd F src/vdbeapi.c 02bcbc2ca5d2004b029088b05b468b394881e103 @@ -1041,7 +1041,7 @@ F test/select6.test 39eac4a5c03650b2b473c532882273283ee8b7a0 F test/select7.test 95e370c42d47c3c52377d05e9ffc01ccff7c1f61 F test/select8.test 8c8f5ae43894c891efc5755ed905467d1d67ad5d F test/select9.test aebc2bb0c3bc44606125033cbcaac2c8d1f33a95 -F test/selectA.test e452bdb975f488ea46d091382a9185b5853ed2c7 +F test/selectA.test 101e722370ac6e84978c2958b8931c78b10a1709 F test/selectB.test 954e4e49cf1f896d61794e440669e03a27ceea25 F test/selectC.test 871fb55d884d3de5943c4057ebd22c2459e71977 F test/selectD.test b0f02a04ef7737decb24e08be2c39b9664b43394 @@ -1502,7 +1502,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 67c39e16442d9359b24d60d5f97bd66c19eff16a -R 7e79191b4d7cf82834abc676eac1270e +P 77e4f7a36e6e0ebe842bcb36b2557a5bfba90d3f +R 3ef1ee60339b9a478f36c983b60b7e48 U drh -Z 811d7c2149778ab6cb4ca3f8ac5802c8 +Z 7d552df043719cedc46422a9795a23bd diff --git a/manifest.uuid b/manifest.uuid index d7b3218dfe..9ea9790f27 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -77e4f7a36e6e0ebe842bcb36b2557a5bfba90d3f \ No newline at end of file +507014e4c7a70cd09410c89c8ed466c8edab39d2 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 245c5beb6c..6adbcbbec1 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2016,6 +2016,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ if( (flags1 | flags3)&MEM_Str ){ if( (flags1 & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){ applyNumericAffinity(pIn1,0); + flags3 = pIn3->flags; } if( (flags3 & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){ applyNumericAffinity(pIn3,0); @@ -2028,6 +2029,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ sqlite3VdbeMemStringify(pIn1, encoding, 1); testcase( (flags1&MEM_Dyn) != (pIn1->flags&MEM_Dyn) ); flags1 = (pIn1->flags & ~MEM_TypeMask) | (flags1 & MEM_TypeMask); + flags3 = pIn3->flags; } if( (flags3 & MEM_Str)==0 && (flags3 & (MEM_Int|MEM_Real))!=0 ){ testcase( pIn3->flags & MEM_Int ); diff --git a/test/selectA.test b/test/selectA.test index 0338338902..78d04be15d 100644 --- a/test/selectA.test +++ b/test/selectA.test @@ -1434,5 +1434,14 @@ do_catchsql_test 5.4 { SELECT * FROM t8 UNION SELECT * FROM t9 ORDER BY a+b COLLATE NOCASE } {1 {1st ORDER BY term does not match any column in the result set}} +do_execsql_test 6.1 { + DROP TABLE IF EXISTS t1; + DROP TABLE IF EXISTS t2; + CREATE TABLE t1(a INTEGER); + CREATE TABLE t2(b TEXT); + INSERT INTO t2(b) VALUES('12345'); + SELECT * FROM (SELECT a FROM t1 UNION SELECT b FROM t2) WHERE a=a; +} {12345} + finish_test From 05d1bad67458843adb41c9f77dabb22aa6cd0084 Mon Sep 17 00:00:00 2001 From: drh Date: Sun, 26 Jun 2016 04:06:28 +0000 Subject: [PATCH 0529/1484] Prevent the WhereLoop.rSetup cost estimate from going negative on complex queries. FossilOrigin-Name: f81050859170c8708a1b296da8dd3ef0dd314a11 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/where.c | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index cd94ec1c26..2dd253cf30 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\shandling\sof\sOP_Eq\sopcodes\sthat\scompare\sa\sregister\sagainst\sitself\nand\sthat\srequire\san\saffinity\schange. -D 2016-06-25T11:43:47.381 +C Prevent\sthe\sWhereLoop.rSetup\scost\sestimate\sfrom\sgoing\snegative\son\scomplex\nqueries. +D 2016-06-26T04:06:28.081 F Makefile.in bc2b4864a23a4a21c3e26d7b4350f51bab324d45 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 50149765ef72f4e652b9a0f1f6462c4784bb9423 @@ -462,7 +462,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 02eeecc265f6ffd0597378f5d8ae9070b62a406a F src/wal.h 2f7c831cf3b071fa548bf2d5cac640846a7ff19c F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354 -F src/where.c 0ce4793497af2feb051147a5cc6356f95d3ab381 +F src/where.c 48eed8ebe319c6cbc7bf7682018f32af0f5189f5 F src/whereInt.h e5b939701a7ceffc5a3a8188a37f9746416ebcd0 F src/wherecode.c e20cb381ff621e56a4684c71e31999aca2547ca6 F src/whereexpr.c c32d47085dbaca0b8fd013210f56693c7d220d48 @@ -1502,7 +1502,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 77e4f7a36e6e0ebe842bcb36b2557a5bfba90d3f -R 3ef1ee60339b9a478f36c983b60b7e48 +P 507014e4c7a70cd09410c89c8ed466c8edab39d2 +R ae55d782914cbf2db58c75f82f862316 U drh -Z 7d552df043719cedc46422a9795a23bd +Z e21bca843071316b56d3c29d5bf9cc08 diff --git a/manifest.uuid b/manifest.uuid index 9ea9790f27..ee49eb40ac 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -507014e4c7a70cd09410c89c8ed466c8edab39d2 \ No newline at end of file +f81050859170c8708a1b296da8dd3ef0dd314a11 \ No newline at end of file diff --git a/src/where.c b/src/where.c index 46fcb4a158..a65f30968e 100644 --- a/src/where.c +++ b/src/where.c @@ -2701,6 +2701,7 @@ static int whereLoopAddBtree( pNew->rSetup += 24; } ApplyCostMultiplier(pNew->rSetup, pTab->costMult); + if( pNew->rSetup<0 ) pNew->rSetup = 0; /* TUNING: Each index lookup yields 20 rows in the table. This ** is more than the usual guess of 10 rows, since we have no way ** of knowing how selective the index will ultimately be. It would From a2fbe3bec66936b2f542fa6f9c9238aa2ea452b2 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 28 Jun 2016 22:27:56 +0000 Subject: [PATCH 0530/1484] Proposed fix for a problem in the query planner. FossilOrigin-Name: a33d23560959a127e37d8213dc00210cd4b05352 --- manifest | 15 +++++++++------ manifest.uuid | 2 +- src/whereexpr.c | 8 +++----- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 2dd253cf30..2e46c5cb6a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Prevent\sthe\sWhereLoop.rSetup\scost\sestimate\sfrom\sgoing\snegative\son\scomplex\nqueries. -D 2016-06-26T04:06:28.081 +C Proposed\sfix\sfor\sa\sproblem\sin\sthe\squery\splanner. +D 2016-06-28T22:27:56.883 F Makefile.in bc2b4864a23a4a21c3e26d7b4350f51bab324d45 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 50149765ef72f4e652b9a0f1f6462c4784bb9423 @@ -465,7 +465,7 @@ F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354 F src/where.c 48eed8ebe319c6cbc7bf7682018f32af0f5189f5 F src/whereInt.h e5b939701a7ceffc5a3a8188a37f9746416ebcd0 F src/wherecode.c e20cb381ff621e56a4684c71e31999aca2547ca6 -F src/whereexpr.c c32d47085dbaca0b8fd013210f56693c7d220d48 +F src/whereexpr.c d7dcbf14ce1b5876c1f76496162c30fcba669563 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1502,7 +1502,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 507014e4c7a70cd09410c89c8ed466c8edab39d2 -R ae55d782914cbf2db58c75f82f862316 +P f81050859170c8708a1b296da8dd3ef0dd314a11 +R dcdb165f171e6961986899e464931036 +T *branch * planner-fix +T *sym-planner-fix * +T -sym-trunk * U drh -Z e21bca843071316b56d3c29d5bf9cc08 +Z 35245dfa6950894f0d3652717f7690e0 diff --git a/manifest.uuid b/manifest.uuid index ee49eb40ac..f6e2e672d1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f81050859170c8708a1b296da8dd3ef0dd314a11 \ No newline at end of file +a33d23560959a127e37d8213dc00210cd4b05352 \ No newline at end of file diff --git a/src/whereexpr.c b/src/whereexpr.c index 90c4c45965..1cb6be8458 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -785,12 +785,10 @@ static int termIsEquivalence(Parse *pParse, Expr *pExpr){ pColl = sqlite3BinaryCompareCollSeq(pParse, pExpr->pLeft, pExpr->pRight); if( pColl==0 || sqlite3StrICmp(pColl->zName, "BINARY")==0 ) return 1; pColl = sqlite3ExprCollSeq(pParse, pExpr->pLeft); - /* Since pLeft and pRight are both a column references, their collating - ** sequence should always be defined. */ - zColl1 = ALWAYS(pColl) ? pColl->zName : 0; + zColl1 = pColl ? pColl->zName : 0; pColl = sqlite3ExprCollSeq(pParse, pExpr->pRight); - zColl2 = ALWAYS(pColl) ? pColl->zName : 0; - return sqlite3StrICmp(zColl1, zColl2)==0; + zColl2 = pColl ? pColl->zName : 0; + return sqlite3_stricmp(zColl1, zColl2)==0; } /* From 4841624ab991a90dc84cb48cec9abcfe6f885dbf Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 29 Jun 2016 05:00:30 +0000 Subject: [PATCH 0531/1484] Add a prototype intarray($PTR,$N) table valued function. FossilOrigin-Name: 233b33382dc70de45f90b6dfdb5785f20b21489e --- Makefile.in | 1 + ext/misc/array.c | 296 ++++++++++++++++++++++++++++++++++++++++++++ manifest | 20 +-- manifest.uuid | 2 +- src/test1.c | 43 +++++++ test/tabfunc01.test | 22 ++++ 6 files changed, 375 insertions(+), 9 deletions(-) create mode 100644 ext/misc/array.c diff --git a/Makefile.in b/Makefile.in index b9f684e617..ff863ec906 100644 --- a/Makefile.in +++ b/Makefile.in @@ -416,6 +416,7 @@ TESTSRC = \ # TESTSRC += \ $(TOP)/ext/misc/amatch.c \ + $(TOP)/ext/misc/array.c \ $(TOP)/ext/misc/closure.c \ $(TOP)/ext/misc/csv.c \ $(TOP)/ext/misc/eval.c \ diff --git a/ext/misc/array.c b/ext/misc/array.c new file mode 100644 index 0000000000..54b249f90a --- /dev/null +++ b/ext/misc/array.c @@ -0,0 +1,296 @@ +/* +** 2016-06-29 +** +** 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 demonstrates how to create a table-valued-function that +** returns the values in a C-language array. +** Examples: +** +** SELECT * FROM intarray($ptr,5) +** +** The query above returns 5 integers contained in a C-language array +** at the address $ptr. $ptr is a pointer to the array of integers that +** has been cast to an integer. +** +** HOW IT WORKS +** +** The intarray "function" is really a virtual table with the +** following schema: +** +** CREATE FUNCTION intarray( +** value, +** pointer HIDDEN, +** count HIDDEN +** ); +*/ +#include "sqlite3ext.h" +SQLITE_EXTENSION_INIT1 +#include +#include + +#ifndef SQLITE_OMIT_VIRTUALTABLE + + +/* intarray_cursor is a subclass of sqlite3_vtab_cursor which will +** serve as the underlying representation of a cursor that scans +** over rows of the result +*/ +typedef struct intarray_cursor intarray_cursor; +struct intarray_cursor { + sqlite3_vtab_cursor base; /* Base class - must be first */ + int isDesc; /* True to count down rather than up */ + sqlite3_int64 iRowid; /* The rowid */ + sqlite3_int64 iPtr; /* Pointer to array of integers */ + sqlite3_int64 iCnt; /* Number of integers in the array */ +}; + +/* +** The intarrayConnect() method is invoked to create a new +** intarray_vtab that describes the intarray virtual table. +** +** Think of this routine as the constructor for intarray_vtab objects. +** +** All this routine needs to do is: +** +** (1) Allocate the intarray_vtab object and initialize all fields. +** +** (2) Tell SQLite (via the sqlite3_declare_vtab() interface) what the +** result set of queries against intarray will look like. +*/ +static int intarrayConnect( + sqlite3 *db, + void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVtab, + char **pzErr +){ + sqlite3_vtab *pNew; + int rc; + +/* Column numbers */ +#define INTARRAY_COLUMN_VALUE 0 +#define INTARRAY_COLUMN_POINTER 1 +#define INTARRAY_COLUMN_COUNT 2 + + rc = sqlite3_declare_vtab(db, + "CREATE TABLE x(value,pointer hidden,count hidden)"); + if( rc==SQLITE_OK ){ + pNew = *ppVtab = sqlite3_malloc( sizeof(*pNew) ); + if( pNew==0 ) return SQLITE_NOMEM; + memset(pNew, 0, sizeof(*pNew)); + } + return rc; +} + +/* +** This method is the destructor for intarray_cursor objects. +*/ +static int intarrayDisconnect(sqlite3_vtab *pVtab){ + sqlite3_free(pVtab); + return SQLITE_OK; +} + +/* +** Constructor for a new intarray_cursor object. +*/ +static int intarrayOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){ + intarray_cursor *pCur; + pCur = sqlite3_malloc( sizeof(*pCur) ); + if( pCur==0 ) return SQLITE_NOMEM; + memset(pCur, 0, sizeof(*pCur)); + *ppCursor = &pCur->base; + return SQLITE_OK; +} + +/* +** Destructor for a intarray_cursor. +*/ +static int intarrayClose(sqlite3_vtab_cursor *cur){ + sqlite3_free(cur); + return SQLITE_OK; +} + + +/* +** Advance a intarray_cursor to its next row of output. +*/ +static int intarrayNext(sqlite3_vtab_cursor *cur){ + intarray_cursor *pCur = (intarray_cursor*)cur; + pCur->iRowid++; + return SQLITE_OK; +} + +/* +** Return values of columns for the row at which the intarray_cursor +** is currently pointing. +*/ +static int intarrayColumn( + sqlite3_vtab_cursor *cur, /* The cursor */ + sqlite3_context *ctx, /* First argument to sqlite3_result_...() */ + int i /* Which column to return */ +){ + intarray_cursor *pCur = (intarray_cursor*)cur; + sqlite3_int64 x = 0; + switch( i ){ + case INTARRAY_COLUMN_POINTER: x = pCur->iPtr; break; + case INTARRAY_COLUMN_COUNT: x = pCur->iCnt; break; + default: { + int *p = (int*)pCur->iPtr; + x = (int)p[pCur->iRowid-1]; + break; + } + } + sqlite3_result_int64(ctx, x); + return SQLITE_OK; +} + +/* +** Return the rowid for the current row. In this implementation, the +** rowid is the same as the output value. +*/ +static int intarrayRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ + intarray_cursor *pCur = (intarray_cursor*)cur; + *pRowid = pCur->iRowid; + return SQLITE_OK; +} + +/* +** Return TRUE if the cursor has been moved off of the last +** row of output. +*/ +static int intarrayEof(sqlite3_vtab_cursor *cur){ + intarray_cursor *pCur = (intarray_cursor*)cur; + return pCur->iRowid>=pCur->iCnt; +} + +/* +** This method is called to "rewind" the intarray_cursor object back +** to the first row of output. +*/ +static int intarrayFilter( + sqlite3_vtab_cursor *pVtabCursor, + int idxNum, const char *idxStr, + int argc, sqlite3_value **argv +){ + intarray_cursor *pCur = (intarray_cursor *)pVtabCursor; + int i = 0; + if( idxNum ){ + pCur->iPtr = sqlite3_value_int64(argv[0]); + pCur->iCnt = sqlite3_value_int64(argv[1]); + }else{ + pCur->iPtr = 0; + pCur->iCnt = 0; + } + pCur->iRowid = 1; + return SQLITE_OK; +} + +/* +** SQLite will invoke this method one or more times while planning a query +** that uses the intarray virtual table. This routine needs to create +** a query plan for each invocation and compute an estimated cost for that +** plan. +** +** In this implementation idxNum is used to represent the +** query plan. idxStr is unused. +** +** idxNum is 1 if the pointer= and count= constraints exist and is 0 otherwise. +** If idxNum is 0, then intarray becomes an empty table. +*/ +static int intarrayBestIndex( + sqlite3_vtab *tab, + sqlite3_index_info *pIdxInfo +){ + int i; /* Loop over constraints */ + int idxNum = 0; /* The query plan bitmask */ + int ptrIdx = -1; /* Index of the pointer= constraint, or -1 if none */ + int cntIdx = -1; /* Index of the count= constraint, or -1 if none */ + int nArg = 0; /* Number of arguments that intarrayFilter() expects */ + + const struct sqlite3_index_constraint *pConstraint; + pConstraint = pIdxInfo->aConstraint; + for(i=0; inConstraint; i++, pConstraint++){ + if( pConstraint->usable==0 ) continue; + if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue; + switch( pConstraint->iColumn ){ + case INTARRAY_COLUMN_POINTER: + ptrIdx = i; + break; + case INTARRAY_COLUMN_COUNT: + cntIdx = i; + break; + } + } + if( ptrIdx>=0 && cntIdx>=0 ){ + pIdxInfo->aConstraintUsage[ptrIdx].argvIndex = 1; + pIdxInfo->aConstraintUsage[ptrIdx].omit = 1; + pIdxInfo->aConstraintUsage[cntIdx].argvIndex = 2; + pIdxInfo->aConstraintUsage[cntIdx].omit = 1; + pIdxInfo->estimatedCost = (double)1; + pIdxInfo->estimatedRows = (double)100; + pIdxInfo->idxNum = 1; + }else{ + pIdxInfo->estimatedCost = (double)2147483647; + pIdxInfo->estimatedRows = (double)2147483647; + pIdxInfo->idxNum = 0; + } + return SQLITE_OK; +} + +/* +** This following structure defines all the methods for the +** intarray virtual table. +*/ +static sqlite3_module intarrayModule = { + 0, /* iVersion */ + 0, /* xCreate */ + intarrayConnect, /* xConnect */ + intarrayBestIndex, /* xBestIndex */ + intarrayDisconnect, /* xDisconnect */ + 0, /* xDestroy */ + intarrayOpen, /* xOpen - open a cursor */ + intarrayClose, /* xClose - close a cursor */ + intarrayFilter, /* xFilter - configure scan constraints */ + intarrayNext, /* xNext - advance a cursor */ + intarrayEof, /* xEof - check for end of scan */ + intarrayColumn, /* xColumn - read data */ + intarrayRowid, /* xRowid - read data */ + 0, /* xUpdate */ + 0, /* xBegin */ + 0, /* xSync */ + 0, /* xCommit */ + 0, /* xRollback */ + 0, /* xFindMethod */ + 0, /* xRename */ +}; + +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + +#ifdef _WIN32 +__declspec(dllexport) +#endif +int sqlite3_array_init( + sqlite3 *db, + char **pzErrMsg, + const sqlite3_api_routines *pApi +){ + int rc = SQLITE_OK; + SQLITE_EXTENSION_INIT2(pApi); +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( sqlite3_libversion_number()<3008012 ){ + *pzErrMsg = sqlite3_mprintf( + "intarray() requires SQLite 3.8.12 or later"); + return SQLITE_ERROR; + } + rc = sqlite3_create_module(db, "intarray", &intarrayModule, 0); +#endif + return rc; +} diff --git a/manifest b/manifest index 2dd253cf30..f6356d3145 100644 --- a/manifest +++ b/manifest @@ -1,6 +1,6 @@ -C Prevent\sthe\sWhereLoop.rSetup\scost\sestimate\sfrom\sgoing\snegative\son\scomplex\nqueries. -D 2016-06-26T04:06:28.081 -F Makefile.in bc2b4864a23a4a21c3e26d7b4350f51bab324d45 +C Add\sa\sprototype\sintarray($PTR,$N)\stable\svalued\sfunction. +D 2016-06-29T05:00:30.819 +F Makefile.in 541d493154ec3b0b20b2f1d495ec66f55905191e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 50149765ef72f4e652b9a0f1f6462c4784bb9423 F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7 @@ -204,6 +204,7 @@ F ext/icu/README.txt d9fbbad0c2f647c3fdf715fc9fd64af53aedfc43 F ext/icu/icu.c 43df9d8ef2fae7a325100ebd713ab089dc829dd7 F ext/icu/sqliteicu.h 728867a802baa5a96de7495e9689a8e01715ef37 F ext/misc/amatch.c 211108e201105e4bb0c076527b8cfd34330fc234 +F ext/misc/array.c 20af0591e6611755dd8a9d1124e9c9a8cf42761f F ext/misc/closure.c 0d2a038df8fbae7f19de42e7c7d71f2e4dc88704 F ext/misc/compress.c 122faa92d25033d6c3f07c39231de074ab3d2e83 F ext/misc/csv.c f01126ba170fd4ef7c752b156568a80c912d4441 @@ -392,7 +393,7 @@ F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 F src/tclsqlite.c 25fbbbb97f76dbfd113153fb63f52d7ecfac5dd0 -F src/test1.c 43b37ab2b7338fd3313e74902f0d6c821eae843b +F src/test1.c 081e4ed40525590406a51f7e7e4cee31cdb5d029 F src/test2.c 5586f43fcd9a1be0830793cf9d354082c261b25b F src/test3.c c75c8af0eadb335236c9e61b51044c58a8f7dd59 F src/test4.c d168f83cc78d02e8d35567bb5630e40dcd85ac1e @@ -1114,7 +1115,7 @@ F test/symlink.test c9ebe7330d228249e447038276bfc8a7b22f4849 F test/sync.test 2f84bdbc2b2df1fcb0220575b4b9f8cea94b7529 F test/syscall.test f59ba4e25f7ba4a4c031026cc2ef8b6e4b4c639c F test/sysfault.test c9f2b0d8d677558f74de750c75e12a5454719d04 -F test/tabfunc01.test f977868fa8bb7beb4b2072883190411653473906 +F test/tabfunc01.test a1976cbc37cbcdd4b4bd1e52d19a173dd62ab9e0 F test/table.test b708f3e5fa2542fa51dfab21fc07b36ea445cb2f F test/tableapi.test 2674633fa95d80da917571ebdd759a14d9819126 F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930 @@ -1502,7 +1503,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 507014e4c7a70cd09410c89c8ed466c8edab39d2 -R ae55d782914cbf2db58c75f82f862316 +P f81050859170c8708a1b296da8dd3ef0dd314a11 +R 609a6d062299b01b515e433d814c02e8 +T *branch * prototype-int-array +T *sym-prototype-int-array * +T -sym-trunk * U drh -Z e21bca843071316b56d3c29d5bf9cc08 +Z 45472ddb0e35914c318f364b2c8020fb diff --git a/manifest.uuid b/manifest.uuid index ee49eb40ac..2ff393eb58 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f81050859170c8708a1b296da8dd3ef0dd314a11 \ No newline at end of file +233b33382dc70de45f90b6dfdb5785f20b21489e \ No newline at end of file diff --git a/src/test1.c b/src/test1.c index 0f16d62d85..9a73e0e0b5 100644 --- a/src/test1.c +++ b/src/test1.c @@ -3241,6 +3241,46 @@ static int test_bind_int( } +/* +** Usage: sqlite3_bind_intarray STMT N INT ... +** +** Create a C-language array of integers from the arguments. Bind a pointer +** to this array to the NAME parameter of STMT. +*/ +static int test_bind_intarray( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + sqlite3_stmt *pStmt; + int idx; + int i; + static int *p = 0; + + sqlite3_free(p); + p = 0; + if( objc<4 ){ + Tcl_AppendResult(interp, "wrong # args: should be \"", + Tcl_GetStringFromObj(objv[0], 0), " STMT NAME INT...", 0); + return TCL_ERROR; + } + + if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; + if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR; + p = sqlite3_malloc( sizeof(int)*(objc-3) ); + if( p==0 ) return TCL_ERROR; + for(i=0; i Date: Wed, 29 Jun 2016 05:08:01 +0000 Subject: [PATCH 0532/1484] Another test case for the intarray($PTR,$N) virtual table. FossilOrigin-Name: 06e1fab7527c6b4330a58f8d8873afaf2d67ae86 --- manifest | 15 ++++++--------- manifest.uuid | 2 +- test/tabfunc01.test | 23 +++++++++++++++++++++++ 3 files changed, 30 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index f6356d3145..defdea7bc4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sa\sprototype\sintarray($PTR,$N)\stable\svalued\sfunction. -D 2016-06-29T05:00:30.819 +C Another\stest\scase\sfor\sthe\sintarray($PTR,$N)\svirtual\stable. +D 2016-06-29T05:08:01.847 F Makefile.in 541d493154ec3b0b20b2f1d495ec66f55905191e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 50149765ef72f4e652b9a0f1f6462c4784bb9423 @@ -1115,7 +1115,7 @@ F test/symlink.test c9ebe7330d228249e447038276bfc8a7b22f4849 F test/sync.test 2f84bdbc2b2df1fcb0220575b4b9f8cea94b7529 F test/syscall.test f59ba4e25f7ba4a4c031026cc2ef8b6e4b4c639c F test/sysfault.test c9f2b0d8d677558f74de750c75e12a5454719d04 -F test/tabfunc01.test a1976cbc37cbcdd4b4bd1e52d19a173dd62ab9e0 +F test/tabfunc01.test bb0ef0fdf5e807c5bc3438c8c4face4c9887971d F test/table.test b708f3e5fa2542fa51dfab21fc07b36ea445cb2f F test/tableapi.test 2674633fa95d80da917571ebdd759a14d9819126 F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930 @@ -1503,10 +1503,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P f81050859170c8708a1b296da8dd3ef0dd314a11 -R 609a6d062299b01b515e433d814c02e8 -T *branch * prototype-int-array -T *sym-prototype-int-array * -T -sym-trunk * +P 233b33382dc70de45f90b6dfdb5785f20b21489e +R 67bef7ed0b382234904201d45ecddcca U drh -Z 45472ddb0e35914c318f364b2c8020fb +Z bbb146cf4e7f714032732261f87e16f3 diff --git a/manifest.uuid b/manifest.uuid index 2ff393eb58..ba2f320cf9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -233b33382dc70de45f90b6dfdb5785f20b21489e \ No newline at end of file +06e1fab7527c6b4330a58f8d8873afaf2d67ae86 \ No newline at end of file diff --git a/test/tabfunc01.test b/test/tabfunc01.test index 473f3f385c..d0de104d81 100644 --- a/test/tabfunc01.test +++ b/test/tabfunc01.test @@ -155,6 +155,29 @@ do_test tabfunc01-621 { sqlite3_column_int $VM 0 } 22 sqlite3_finalize $VM + +do_test tabfunc01-650 { + db eval { + DROP TABLE IF EXISTS t6; + CREATE TABLE t6(x INTEGER PRIMARY KEY, y BLOB); + WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<100) + INSERT INTO t6(x,y) SELECT x, randomblob(x) FROM c; + } + set TAIL {} + set VM [sqlite3_prepare db { + SELECT length(y) FROM t6 WHERE x IN (SELECT value FROM intarray(?1,3)); + } -1 TAIL] + string trim $TAIL +} {} +do_test tabfunc01-660 { + sqlite3_bind_intarray $VM 1 11 22 33 44 55 + sqlite3_step $VM +} SQLITE_ROW +do_test tabfunc01-661 { + sqlite3_column_int $VM 0 +} 11 +sqlite3_finalize $VM + catch {sqlite3_bind_intarray} finish_test From 2d05331444e0feb269a4651ba2f8c47f4a5ad6e2 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 29 Jun 2016 06:19:19 +0000 Subject: [PATCH 0533/1484] Add the ability to have a table-valued function on the RHS of an IN operator. FossilOrigin-Name: ba1b441b6003808810667d749635fe6b2e8c6165 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/parse.y | 9 +++++++++ test/tabfunc01.test | 16 ++++++++++++++++ 4 files changed, 33 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index defdea7bc4..3973bf7b86 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Another\stest\scase\sfor\sthe\sintarray($PTR,$N)\svirtual\stable. -D 2016-06-29T05:08:01.847 +C Add\sthe\sability\sto\shave\sa\stable-valued\sfunction\son\sthe\sRHS\sof\san\sIN\soperator. +D 2016-06-29T06:19:19.192 F Makefile.in 541d493154ec3b0b20b2f1d495ec66f55905191e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 50149765ef72f4e652b9a0f1f6462c4784bb9423 @@ -372,7 +372,7 @@ F src/os_win.c d4b8faf8896b65818e67070711fdd00d8e620bd6 F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c c368634b888b1c8740aea83b36bfd266f2443e60 F src/pager.h 8ab6b6feeee4bc0439bfde7ee59ba99df98b9bc3 -F src/parse.y 01b9f37c4c7009ab56fda98bc7db4c42643cecfe +F src/parse.y 300a30380bfa73c0a0d2e0ae4c4d0cd844d80199 F src/pcache.c 5583c8ade4b05075a60ba953ef471d1c1a9c05df F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 F src/pcache1.c 7f51d2b541aab57596adf62db2c4bb025d34f04d @@ -1115,7 +1115,7 @@ F test/symlink.test c9ebe7330d228249e447038276bfc8a7b22f4849 F test/sync.test 2f84bdbc2b2df1fcb0220575b4b9f8cea94b7529 F test/syscall.test f59ba4e25f7ba4a4c031026cc2ef8b6e4b4c639c F test/sysfault.test c9f2b0d8d677558f74de750c75e12a5454719d04 -F test/tabfunc01.test bb0ef0fdf5e807c5bc3438c8c4face4c9887971d +F test/tabfunc01.test 32e620a19963c50dcf6958dc5bb352de96d948fb F test/table.test b708f3e5fa2542fa51dfab21fc07b36ea445cb2f F test/tableapi.test 2674633fa95d80da917571ebdd759a14d9819126 F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930 @@ -1503,7 +1503,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 233b33382dc70de45f90b6dfdb5785f20b21489e -R 67bef7ed0b382234904201d45ecddcca +P 06e1fab7527c6b4330a58f8d8873afaf2d67ae86 +R a95030951795f74126be51a632f80a74 U drh -Z bbb146cf4e7f714032732261f87e16f3 +Z 5d31abe2efd2f25b296efdbc945337ef diff --git a/manifest.uuid b/manifest.uuid index ba2f320cf9..6d65c9b627 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -06e1fab7527c6b4330a58f8d8873afaf2d67ae86 \ No newline at end of file +ba1b441b6003808810667d749635fe6b2e8c6165 \ No newline at end of file diff --git a/src/parse.y b/src/parse.y index 9294a30428..d69bd6841a 100644 --- a/src/parse.y +++ b/src/parse.y @@ -1142,6 +1142,15 @@ expr(A) ::= expr(A) between_op(N) expr(X) AND expr(Y). [BETWEEN] { exprNot(pParse, N, &A); A.zEnd = Z.z ? &Z.z[Z.n] : &Y.z[Y.n]; } + expr(A) ::= expr(A) in_op(N) nm(Y) dbnm(Z) LP exprlist(E) RP. [IN] { + SrcList *pSrc = sqlite3SrcListAppend(pParse->db, 0,&Y,&Z); + Select *pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0); + sqlite3SrcListFuncArgs(pParse, pSrc, E); + A.pExpr = sqlite3PExpr(pParse, TK_IN, A.pExpr, 0, 0); + sqlite3PExprAddSelect(pParse, A.pExpr, pSelect); + exprNot(pParse, N, &A); + A.zEnd = Z.z ? &Z.z[Z.n] : &Y.z[Y.n]; + } expr(A) ::= EXISTS(B) LP select(Y) RP(E). { Expr *p; spanSet(&A,&B,&E); /*A-overwrites-B*/ diff --git a/test/tabfunc01.test b/test/tabfunc01.test index d0de104d81..a0aae155bd 100644 --- a/test/tabfunc01.test +++ b/test/tabfunc01.test @@ -178,6 +178,22 @@ do_test tabfunc01-661 { } 11 sqlite3_finalize $VM +do_test tabfunc01-670 { + set TAIL {} + set VM [sqlite3_prepare db { + SELECT length(y) FROM t6 WHERE x IN intarray(?1,3); + } -1 TAIL] + string trim $TAIL +} {} +do_test tabfunc01-671 { + sqlite3_bind_intarray $VM 1 11 22 33 44 55 + sqlite3_step $VM +} SQLITE_ROW +do_test tabfunc01-672 { + sqlite3_column_int $VM 0 +} 11 +sqlite3_finalize $VM + catch {sqlite3_bind_intarray} finish_test From e336b8914c44d341801746e3fd66afadc603b4dc Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 1 Jul 2016 12:39:58 +0000 Subject: [PATCH 0534/1484] Add the sqlite3rbu_state() API. Used to determine the current state (creating OAL, ready to move OAL, incremental-checkpoint, finished or error) of an RBU operation. FossilOrigin-Name: 92e7df0ff5c4c118c63d92a767dc82700438a310 --- ext/rbu/rbu1.test | 44 +++++++++------------ ext/rbu/rbu5.test | 27 +------------ ext/rbu/rbu_common.tcl | 37 ++++++++++++++++++ ext/rbu/sqlite3rbu.c | 87 ++++++++++++++++++++++++++++-------------- ext/rbu/sqlite3rbu.h | 38 ++++++++++++++++++ ext/rbu/test_rbu.c | 14 +++++++ manifest | 27 +++++++------ manifest.uuid | 2 +- 8 files changed, 182 insertions(+), 94 deletions(-) diff --git a/ext/rbu/rbu1.test b/ext/rbu/rbu1.test index 51d2ce8171..cd41728886 100644 --- a/ext/rbu/rbu1.test +++ b/ext/rbu/rbu1.test @@ -10,10 +10,7 @@ #*********************************************************************** # -if {![info exists testdir]} { - set testdir [file join [file dirname [info script]] .. .. test] -} -source $testdir/tester.tcl +source [file join [file dirname [info script]] rbu_common.tcl] set ::testprefix rbu1 db close @@ -96,26 +93,6 @@ proc create_rbu5 {filename} { return $filename } -# Run the RBU in file $rbu on target database $target until completion. -# -proc run_rbu {target rbu} { - sqlite3rbu rbu $target $rbu - while 1 { - set rc [rbu step] - if {$rc!="SQLITE_OK"} break - } - rbu close -} - -proc step_rbu {target rbu} { - while 1 { - sqlite3rbu rbu $target $rbu - set rc [rbu step] - rbu close - if {$rc != "SQLITE_OK"} break - } - set rc -} # Same as [step_rbu], except using a URI to open the target db. # @@ -641,10 +618,25 @@ foreach {tn3 create_vfs destroy_vfs} { # correctly. reset_db forcedelete rbu.db - do_test $tn3.8 { + do_test $tn3.8.1 { list [catch { run_rbu test.db rbu.db } msg] $msg } {0 SQLITE_DONE} - + + # Test that an RBU database containing only empty data_xxx tables is + # also handled correctly. + reset_db + forcedelete rbu.db + do_execsql_test $tn3.8.2.1 { + CREATE TABLE t1(a PRIMARY KEY, b); + INSERT INTO t1 VALUES(1, 2); + ATTACH 'rbu.db' AS rbu; + CREATE TABLE data_t1(a, b, rbu_control); + DETACH rbu; + } + do_test $tn3.8.2.1 { + list [catch { run_rbu test.db rbu.db } msg] $msg + } {0 SQLITE_DONE} + # Test that RBU can update indexes containing NULL values. # reset_db diff --git a/ext/rbu/rbu5.test b/ext/rbu/rbu5.test index 9a0f17bc5d..8e4ae8cb69 100644 --- a/ext/rbu/rbu5.test +++ b/ext/rbu/rbu5.test @@ -12,35 +12,10 @@ # Test some properties of the pager_rbu_mode and rbu_mode pragmas. # -if {![info exists testdir]} { - set testdir [file join [file dirname [info script]] .. .. test] -} -source $testdir/tester.tcl +source [file join [file dirname [info script]] rbu_common.tcl] set ::testprefix rbu5 -# Run the RBU in file $rbu on target database $target until completion. -# -proc run_rbu {target rbu} { - sqlite3rbu rbu $target $rbu - while { [rbu step]=="SQLITE_OK" } {} - rbu close -} - - -# Run the RBU in file $rbu on target database $target one step at a -# time until completion. -# -proc step_rbu {target rbu} { - while 1 { - sqlite3rbu rbu $target $rbu - set rc [rbu step] - rbu close - if {$rc != "SQLITE_OK"} break - } - set rc -} - # Return a list of the primary key columns for table $tbl in the database # opened by database handle $db. # diff --git a/ext/rbu/rbu_common.tcl b/ext/rbu/rbu_common.tcl index 4a8c5cba9f..a58c3aa0a7 100644 --- a/ext/rbu/rbu_common.tcl +++ b/ext/rbu/rbu_common.tcl @@ -15,12 +15,43 @@ if {![info exists testdir]} { } source $testdir/tester.tcl +proc check_prestep_state {target state} { + set oal_exists [file exists $target-oal] + set wal_exists [file exists $target-wal] + set progress [rbu progress] + + if {($progress==0 && $state!="oal" && $state!="done") + || ($oal_exists && $wal_exists) + || ($progress>0 && $state=="oal" && (!$oal_exists || $wal_exists)) + || ($state=="move" && (!$oal_exists || $wal_exists)) + || ($state=="checkpoint" && ($oal_exists || !$wal_exists)) + || ($state=="done" && ($oal_exists && $progress!=0)) + } { + error "B: state=$state progress=$progress oal=$oal_exists wal=$wal_exists" + } +} + +proc check_poststep_state {rc target state} { + if {$rc=="SQLITE_OK" || $rc=="SQLITE_DONE"} { + set oal_exists [file exists $target-oal] + set wal_exists [file exists $target-wal] + if {$state=="move" && ($oal_exists || !$wal_exists)} { + error "A: state=$state progress=$progress oal=$oal_exists wal=$wal_exists" + } + } +} + # Run the RBU in file $rbu on target database $target until completion. # proc run_rbu {target rbu} { sqlite3rbu rbu $target $rbu while 1 { + set state [rbu state] + + check_prestep_state $target $state set rc [rbu step] + check_poststep_state $rc $target $state + if {$rc!="SQLITE_OK"} break } rbu close @@ -29,7 +60,10 @@ proc run_rbu {target rbu} { proc step_rbu {target rbu} { while 1 { sqlite3rbu rbu $target $rbu + set state [rbu state] + check_prestep_state $target $state set rc [rbu step] + check_poststep_state $rc $target $state rbu close if {$rc != "SQLITE_OK"} break } @@ -41,7 +75,10 @@ proc do_rbu_vacuum_test {tn step} { if {$step==0} { sqlite3rbu_vacuum rbu test.db state.db } while 1 { if {$step==1} { sqlite3rbu_vacuum rbu test.db state.db } + set state [rbu state] + check_prestep_state test.db $state set rc [rbu step] + check_poststep_state $rc test.db $state if {$rc!="SQLITE_OK"} break if {$step==1} { rbu close } } diff --git a/ext/rbu/sqlite3rbu.c b/ext/rbu/sqlite3rbu.c index 1cfb71384f..73c6647a2c 100644 --- a/ext/rbu/sqlite3rbu.c +++ b/ext/rbu/sqlite3rbu.c @@ -3555,30 +3555,7 @@ static sqlite3rbu *openRbuHandle( if( p->rc==SQLITE_OK ){ if( p->eStage==RBU_STAGE_OAL ){ sqlite3 *db = p->dbMain; - - if( pState->eStage==0 && rbuIsVacuum(p) ){ - rbuCopyPragma(p, "page_size"); - rbuCopyPragma(p, "auto_vacuum"); - } - - /* Open transactions both databases. The *-oal file is opened or - ** created at this point. */ - if( p->rc==SQLITE_OK ){ - p->rc = sqlite3_exec(db, "BEGIN IMMEDIATE", 0, 0, &p->zErrmsg); - } - if( p->rc==SQLITE_OK ){ - p->rc = sqlite3_exec(p->dbRbu, "BEGIN", 0, 0, &p->zErrmsg); - } - - /* Check if the main database is a zipvfs db. If it is, set the upper - ** level pager to use "journal_mode=off". This prevents it from - ** generating a large journal using a temp file. */ - if( p->rc==SQLITE_OK ){ - int frc = sqlite3_file_control(db, "main", SQLITE_FCNTL_ZIPVFS, 0); - if( frc==SQLITE_OK ){ - p->rc = sqlite3_exec(db, "PRAGMA journal_mode=off",0,0,&p->zErrmsg); - } - } + p->rc = sqlite3_exec(p->dbRbu, "BEGIN", 0, 0, &p->zErrmsg); /* Point the object iterator at the first object */ if( p->rc==SQLITE_OK ){ @@ -3589,12 +3566,34 @@ static sqlite3rbu *openRbuHandle( ** update finished. */ if( p->rc==SQLITE_OK && p->objiter.zTbl==0 ){ p->rc = SQLITE_DONE; - } + p->eStage = RBU_STAGE_DONE; + }else{ + if( p->rc==SQLITE_OK && pState->eStage==0 && rbuIsVacuum(p) ){ + rbuCopyPragma(p, "page_size"); + rbuCopyPragma(p, "auto_vacuum"); + } - if( p->rc==SQLITE_OK ){ - rbuSetupOal(p, pState); - } + /* Open transactions both databases. The *-oal file is opened or + ** created at this point. */ + if( p->rc==SQLITE_OK ){ + p->rc = sqlite3_exec(db, "BEGIN IMMEDIATE", 0, 0, &p->zErrmsg); + } + /* Check if the main database is a zipvfs db. If it is, set the upper + ** level pager to use "journal_mode=off". This prevents it from + ** generating a large journal using a temp file. */ + if( p->rc==SQLITE_OK ){ + int frc = sqlite3_file_control(db, "main", SQLITE_FCNTL_ZIPVFS, 0); + if( frc==SQLITE_OK ){ + p->rc = sqlite3_exec( + db, "PRAGMA journal_mode=off",0,0,&p->zErrmsg); + } + } + + if( p->rc==SQLITE_OK ){ + rbuSetupOal(p, pState); + } + } }else if( p->eStage==RBU_STAGE_MOVE ){ /* no-op */ }else if( p->eStage==RBU_STAGE_CKPT ){ @@ -3761,9 +3760,39 @@ void sqlite3rbu_bp_progress(sqlite3rbu *p, int *pnOne, int *pnTwo){ } } +/* +** Return the current state of the RBU vacuum or update operation. +*/ +int sqlite3rbu_state(sqlite3rbu *p){ + int aRes[] = { + 0, SQLITE_RBU_STATE_OAL, SQLITE_RBU_STATE_MOVE, + 0, SQLITE_RBU_STATE_CHECKPOINT, SQLITE_RBU_STATE_DONE + }; + + assert( RBU_STAGE_OAL==1 ); + assert( RBU_STAGE_MOVE==2 ); + assert( RBU_STAGE_CKPT==4 ); + assert( RBU_STAGE_DONE==5 ); + assert( aRes[RBU_STAGE_OAL]==SQLITE_RBU_STATE_OAL ); + assert( aRes[RBU_STAGE_MOVE]==SQLITE_RBU_STATE_MOVE ); + assert( aRes[RBU_STAGE_CKPT]==SQLITE_RBU_STATE_CHECKPOINT ); + assert( aRes[RBU_STAGE_DONE]==SQLITE_RBU_STATE_DONE ); + + if( p->rc!=SQLITE_OK && p->rc!=SQLITE_DONE ){ + return SQLITE_RBU_STATE_ERROR; + }else{ + assert( p->rc!=SQLITE_DONE || p->eStage==RBU_STAGE_DONE ); + assert( p->eStage==RBU_STAGE_OAL + || p->eStage==RBU_STAGE_MOVE + || p->eStage==RBU_STAGE_CKPT + || p->eStage==RBU_STAGE_DONE + ); + return aRes[p->eStage]; + } +} + int sqlite3rbu_savestate(sqlite3rbu *p){ int rc = p->rc; - if( rc==SQLITE_DONE ) return SQLITE_OK; assert( p->eStage>=RBU_STAGE_OAL && p->eStage<=RBU_STAGE_DONE ); diff --git a/ext/rbu/sqlite3rbu.h b/ext/rbu/sqlite3rbu.h index fce9e493db..9ce39f543c 100644 --- a/ext/rbu/sqlite3rbu.h +++ b/ext/rbu/sqlite3rbu.h @@ -474,6 +474,44 @@ sqlite3_int64 sqlite3rbu_progress(sqlite3rbu *pRbu); */ void sqlite3rbu_bp_progress(sqlite3rbu *pRbu, int *pnOne, int *pnTwo); +/* +** Obtain an indication as to the current stage of an RBU update or vacuum. +** This function always returns one of the SQLITE_RBU_STATE_XXX constants +** defined in this file. Return values should be interpreted as follows: +** +** SQLITE_RBU_STATE_OAL: +** RBU is currently building a *-oal file. The next call to sqlite3rbu_step() +** may either add further data to the *-oal file, or compute data that will +** be added by a subsequent call. +** +** SQLITE_RBU_STATE_MOVE: +** RBU has finished building the *-oal file. The next call to sqlite3rbu_step() +** will move the *-oal file to the equivalent *-wal path. If the current +** operation is an RBU update, then the updated version of the database +** file will become visible to ordinary SQLite clients following the next +** call to sqlite3rbu_step(). +** +** SQLITE_RBU_STATE_CHECKPOINT: +** RBU is currently performing an incremental checkpoint. The next call to +** sqlite3rbu_step() will copy a page of data from the *-wal file into +** the target database file. +** +** SQLITE_RBU_STATE_DONE: +** The RBU operation has finished. Any subsequent calls to sqlite3rbu_step() +** will immediately return SQLITE_DONE. +** +** SQLITE_RBU_STATE_ERROR: +** An error has occurred. Any subsequent calls to sqlite3rbu_step() will +** immediately return the SQLite error code associated with the error. +*/ +#define SQLITE_RBU_STATE_OAL 1 +#define SQLITE_RBU_STATE_MOVE 2 +#define SQLITE_RBU_STATE_CHECKPOINT 3 +#define SQLITE_RBU_STATE_DONE 4 +#define SQLITE_RBU_STATE_ERROR 5 + +int sqlite3rbu_state(sqlite3rbu *pRbu); + /* ** Create an RBU VFS named zName that accesses the underlying file-system ** via existing VFS zParent. Or, if the zParent parameter is passed NULL, diff --git a/ext/rbu/test_rbu.c b/ext/rbu/test_rbu.c index 2d52262c71..6418d30d59 100644 --- a/ext/rbu/test_rbu.c +++ b/ext/rbu/test_rbu.c @@ -69,6 +69,8 @@ static int test_sqlite3rbu_cmd( {"dbMain_eval", 3, "SQL"}, /* 4 */ {"bp_progress", 2, ""}, /* 5 */ {"db", 3, "RBU"}, /* 6 */ + {"state", 2, ""}, /* 7 */ + {"progress", 2, ""}, /* 8 */ {0,0,0} }; int iCmd; @@ -166,6 +168,18 @@ static int test_sqlite3rbu_cmd( } break; } + case 7: /* state */ { + const char *aRes[] = { 0, "oal", "move", "checkpoint", "done", "error" }; + int eState = sqlite3rbu_state(pRbu); + assert( eState>0 && eState<=5 ); + Tcl_SetResult(interp, (char*)aRes[eState], TCL_STATIC); + break; + } + case 8: /* progress */ { + sqlite3_int64 nStep = sqlite3rbu_progress(pRbu); + Tcl_SetObjResult(interp, Tcl_NewWideIntObj(nStep)); + break; + } default: /* seems unlikely */ assert( !"cannot happen" ); diff --git a/manifest b/manifest index 2dd253cf30..20d61b1e4e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Prevent\sthe\sWhereLoop.rSetup\scost\sestimate\sfrom\sgoing\snegative\son\scomplex\nqueries. -D 2016-06-26T04:06:28.081 +C Add\sthe\ssqlite3rbu_state()\sAPI.\sUsed\sto\sdetermine\sthe\scurrent\sstate\s(creating\sOAL,\sready\sto\smove\sOAL,\sincremental-checkpoint,\sfinished\sor\serror)\sof\san\sRBU\soperation. +D 2016-07-01T12:39:58.096 F Makefile.in bc2b4864a23a4a21c3e26d7b4350f51bab324d45 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 50149765ef72f4e652b9a0f1f6462c4784bb9423 @@ -226,14 +226,14 @@ F ext/misc/vfsstat.c 6110aeeaab2f1df17a923c8a8acef3c74f6dc515 F ext/misc/vtshim.c babb0dc2bf116029e3e7c9a618b8a1377045303e F ext/misc/wholenumber.c 784b12543d60702ebdd47da936e278aa03076212 F ext/rbu/rbu.c b2c0b5e6ae1a89affc0edfc127ebfa5f637a0ce4 -F ext/rbu/rbu1.test 42bd835e019eff789ec241017965277baeb658b1 +F ext/rbu/rbu1.test 43836fac8c7179a358eaf38a8a1ef3d6e6285842 F ext/rbu/rbu10.test 046b0980041d30700464a800bbf6733ed2df515d F ext/rbu/rbu11.test 9bc68c2d3dbeb1720153626e3bd0466dcc017702 F ext/rbu/rbu12.test bde22ed0004dd5d1888c72a84ae407e574aeae16 F ext/rbu/rbu13.test 462ff799c4afedc3ef8a47ff818c0ffbf14ae4f2 F ext/rbu/rbu14.test 01f5dcba904aecadbaea69d4ccdc2ea43dd30560 F ext/rbu/rbu3.test 8bd4c6b87367c358981b6a47dc3d654fa60bff90 -F ext/rbu/rbu5.test 2e24fee3e615aecd99bbdd46967935a641e866f7 +F ext/rbu/rbu5.test cf1fa84d6107efd73e292a7be8e1fb31953ca45c F ext/rbu/rbu6.test 32e8ed60631b6facdb6366bd2b5f5f25245e7edb F ext/rbu/rbu7.test fd025d5ba440fcfe151fbb0e3835e1e7fe964fa1 F ext/rbu/rbu8.test 3bbf2c35d71a843c463efe93946f14ad10c3ede0 @@ -241,7 +241,7 @@ F ext/rbu/rbu9.test 0806d1772c9f4981774ff028de6656e4183082af F ext/rbu/rbuA.test c1a7b3e2d926b8f8448bb3b4ae787e314ee4b2b3 F ext/rbu/rbuB.test c25bc325b8072a766e56bb76c001866b405925c2 F ext/rbu/rbuC.test efe47db508a0269b683cb2a1913a425ffd39a831 -F ext/rbu/rbu_common.tcl 3a4b916b6f5dca9c9da9a30863e272fe5ea4414f +F ext/rbu/rbu_common.tcl a38e8e2d4a50fd6aaf151633714c1b1d2fae3ead F ext/rbu/rbucrash.test 8d2ed5d4b05fef6c00c2a6b5f7ead71fa172a695 F ext/rbu/rbudiff.test 4c9f8df6f723f553781d3d117501b7e9d170a145 F ext/rbu/rbufault.test cc0be8d5d392d98b0c2d6a51be377ea989250a89 @@ -252,9 +252,9 @@ F ext/rbu/rbuprogress.test 2023a7df2c523e3df1cb532eff811cda385a789a F ext/rbu/rbusave.test 0f43b6686084f426ddd040b878426452fd2c2f48 F ext/rbu/rbuvacuum.test 4a977447c15c2581ab668781d9ef4294382530e0 F ext/rbu/rbuvacuum2.test 45009e127c3fb385e5c0fd5a8a63fb922a79d0ab -F ext/rbu/sqlite3rbu.c 3d35b1dc46f5ca0f0f59db8e6163fe7627ea107c -F ext/rbu/sqlite3rbu.h 2acd0a6344a6079de15c8dc9d84d3df83a665930 -F ext/rbu/test_rbu.c 9bbdf6bd8efd58fbc4f192698df50569598fbb9e +F ext/rbu/sqlite3rbu.c 948677ee0ec57da51148e6c5f64ac68afcf36ab2 +F ext/rbu/sqlite3rbu.h db8858120c9be14b60c9225f9da28221f5f6b945 +F ext/rbu/test_rbu.c 9f043b74c46c45b231f4313aed1fccb379a76fe6 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 F ext/rtree/rtree.c d26a815b0df1c412a6881dae8d7fd3c9c08cce68 F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e @@ -1502,7 +1502,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 507014e4c7a70cd09410c89c8ed466c8edab39d2 -R ae55d782914cbf2db58c75f82f862316 -U drh -Z e21bca843071316b56d3c29d5bf9cc08 +P f81050859170c8708a1b296da8dd3ef0dd314a11 +R 2c74d9aac55f1cbb7c7d3232cf9071e1 +T *branch * rbu-state-api +T *sym-rbu-state-api * +T -sym-trunk * +U dan +Z b7514d1a78fc46b36ed5446f76a12e50 diff --git a/manifest.uuid b/manifest.uuid index ee49eb40ac..85f8706971 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f81050859170c8708a1b296da8dd3ef0dd314a11 \ No newline at end of file +92e7df0ff5c4c118c63d92a767dc82700438a310 \ No newline at end of file From 883486bada02183e5269e231020d653401886d25 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 1 Jul 2016 19:48:43 +0000 Subject: [PATCH 0535/1484] Add test cases to the transitive constraint fix. FossilOrigin-Name: c952af89c22ddc31491f142b9511608a4c8f9737 --- manifest | 14 +++++------ manifest.uuid | 2 +- test/collateB.test | 63 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+), 9 deletions(-) create mode 100644 test/collateB.test diff --git a/manifest b/manifest index 2e46c5cb6a..a7d0cab6bb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Proposed\sfix\sfor\sa\sproblem\sin\sthe\squery\splanner. -D 2016-06-28T22:27:56.883 +C Add\stest\scases\sto\sthe\stransitive\sconstraint\sfix. +D 2016-07-01T19:48:43.147 F Makefile.in bc2b4864a23a4a21c3e26d7b4350f51bab324d45 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 50149765ef72f4e652b9a0f1f6462c4784bb9423 @@ -574,6 +574,7 @@ F test/collate7.test 8ec29d98f3ee4ccebce6e16ce3863fb6b8c7b868 F test/collate8.test cd9b3d3f999b8520ffaa7cc1647061fc5bab1334 F test/collate9.test 3adcc799229545940df2f25308dd1ad65869145a F test/collateA.test b8218ab90d1fa5c59dcf156efabb1b2599c580d6 +F test/collateB.test 8ec2accd2d7166c1eff0d2a39bc90262c6f89632 F test/colmeta.test 2c765ea61ee37bc43bbe6d6047f89004e6508eb1 F test/colname.test 08948a4809d22817e0e5de89c7c0a8bd90cb551b F test/conflict.test 029faa2d81a0d1cafb5f88614beb663d972c01db @@ -1502,10 +1503,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P f81050859170c8708a1b296da8dd3ef0dd314a11 -R dcdb165f171e6961986899e464931036 -T *branch * planner-fix -T *sym-planner-fix * -T -sym-trunk * +P a33d23560959a127e37d8213dc00210cd4b05352 +R 9c182c2a1bd41d85d1ee54cc469d61e7 U drh -Z 35245dfa6950894f0d3652717f7690e0 +Z ef208312357a37b91bc1f6c737863420 diff --git a/manifest.uuid b/manifest.uuid index f6e2e672d1..7ba7a01a61 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a33d23560959a127e37d8213dc00210cd4b05352 \ No newline at end of file +c952af89c22ddc31491f142b9511608a4c8f9737 \ No newline at end of file diff --git a/test/collateB.test b/test/collateB.test new file mode 100644 index 0000000000..4815de83ee --- /dev/null +++ b/test/collateB.test @@ -0,0 +1,63 @@ +# 2016-07-01 +# +# 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. +# +#*********************************************************************** +# Test cases for a crash bug. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +do_execsql_test collateB-1.1 { + CREATE TABLE t1(a INTEGER PRIMARY KEY); + CREATE TABLE t2(b INTEGER PRIMARY KEY, x1 INT COLLATE NOCASE); + CREATE TABLE t3(x2 INT); + SELECT * FROM t3, t2, t1 WHERE x2=b AND x1=a AND a=1; +} {} +do_execsql_test collateB-1.2 { + INSERT INTO t1(a) VALUES(1),(2),(3); + INSERT INTO t2(b,x1) VALUES(11,1),(22,2),(33,3); + INSERT INTO t3(x2) VALUES(11),(22),(33); + SELECT *,'|' FROM t3, t2, t1 WHERE x2=b AND x1=a AND a=1; +} {11 11 1 1 |} +do_execsql_test collateB-1.3 { + SELECT *,'|' FROM t3, t1, t2 WHERE x2=b AND x1=a AND a=1; +} {11 1 11 1 |} +do_execsql_test collateB-1.4 { + SELECT *,'|' FROM t2, t3, t1 WHERE x2=b AND x1=a AND a=1; +} {11 1 11 1 |} +do_execsql_test collateB-1.5 { + SELECT *,'|' FROM t2, t1, t3 WHERE x2=b AND x1=a AND a=1; +} {11 1 1 11 |} +do_execsql_test collateB-1.6 { + SELECT *,'|' FROM t1, t2, t3 WHERE x2=b AND x1=a AND a=1; +} {1 11 1 11 |} +do_execsql_test collateB-1.7 { + SELECT *,'|' FROM t1, t2, t3 WHERE x2=b AND x1=a AND a=1; +} {1 11 1 11 |} +do_execsql_test collateB-1.12 { + SELECT *,'|' FROM t3, t2, t1 WHERE b=x2 AND a=x1 AND 1=a; +} {11 11 1 1 |} +do_execsql_test collateB-1.13 { + SELECT *,'|' FROM t3, t1, t2 WHERE b=x2 AND a=x1 AND 1=a; +} {11 1 11 1 |} +do_execsql_test collateB-1.14 { + SELECT *,'|' FROM t2, t3, t1 WHERE b=x2 AND a=x1 AND 1=a; +} {11 1 11 1 |} +do_execsql_test collateB-1.15 { + SELECT *,'|' FROM t2, t1, t3 WHERE b=x2 AND a=x1 AND 1=a; +} {11 1 1 11 |} +do_execsql_test collateB-1.16 { + SELECT *,'|' FROM t1, t2, t3 WHERE b=x2 AND a=x1 AND 1=a; +} {1 11 1 11 |} +do_execsql_test collateB-1.17 { + SELECT *,'|' FROM t1, t2, t3 WHERE b=x2 AND a=x1 AND 1=a; +} {1 11 1 11 |} + +finish_test From 5fbab882c040a68ba3c665445e0f4672705f0991 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 2 Jul 2016 12:08:14 +0000 Subject: [PATCH 0536/1484] Add support for table-valued functions on the RHS of an IN operator. FossilOrigin-Name: ac6000f050ff4efcf8a87f0825077dbf4144f073 --- manifest | 15 +++++++-------- manifest.uuid | 2 +- src/parse.y | 11 ++++++++++- test/tabfunc01.test | 9 +++++++++ 4 files changed, 27 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 6abed8d72a..1906e09ab0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\stransitive\sconstraint\slogic\serror\sthat\scan\sresult\sin\sa\snull\spointer\ndereference.\s\sFix\sfor\sticket\s[e8d439c77685eca6]. -D 2016-07-01T20:12:39.149 +C Add\ssupport\sfor\stable-valued\sfunctions\son\sthe\sRHS\sof\san\sIN\soperator. +D 2016-07-02T12:08:14.436 F Makefile.in bc2b4864a23a4a21c3e26d7b4350f51bab324d45 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 50149765ef72f4e652b9a0f1f6462c4784bb9423 @@ -371,7 +371,7 @@ F src/os_win.c d4b8faf8896b65818e67070711fdd00d8e620bd6 F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c c368634b888b1c8740aea83b36bfd266f2443e60 F src/pager.h 8ab6b6feeee4bc0439bfde7ee59ba99df98b9bc3 -F src/parse.y 01b9f37c4c7009ab56fda98bc7db4c42643cecfe +F src/parse.y 3660ab75e7c9212fbe9ca75264d26e6587cd0ae4 F src/pcache.c 5583c8ade4b05075a60ba953ef471d1c1a9c05df F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 F src/pcache1.c 7f51d2b541aab57596adf62db2c4bb025d34f04d @@ -1115,7 +1115,7 @@ F test/symlink.test c9ebe7330d228249e447038276bfc8a7b22f4849 F test/sync.test 2f84bdbc2b2df1fcb0220575b4b9f8cea94b7529 F test/syscall.test f59ba4e25f7ba4a4c031026cc2ef8b6e4b4c639c F test/sysfault.test c9f2b0d8d677558f74de750c75e12a5454719d04 -F test/tabfunc01.test f977868fa8bb7beb4b2072883190411653473906 +F test/tabfunc01.test bb774639915aaaf30417f8d0faf832c3309a3338 F test/table.test b708f3e5fa2542fa51dfab21fc07b36ea445cb2f F test/tableapi.test 2674633fa95d80da917571ebdd759a14d9819126 F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930 @@ -1503,8 +1503,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P f81050859170c8708a1b296da8dd3ef0dd314a11 c952af89c22ddc31491f142b9511608a4c8f9737 -R 9c182c2a1bd41d85d1ee54cc469d61e7 -T +closed c952af89c22ddc31491f142b9511608a4c8f9737 +P 228a7879870f8689e2f9b74fbef2ff93fab7b3c2 +R 1f493f554aeef5ddfd3c1d7c325d64e1 U drh -Z 6ff2c1fb4a902fab6eeb4b75477a29a3 +Z 647695f7bc7b8a80ecfde87fc6913c51 diff --git a/manifest.uuid b/manifest.uuid index 35505c7dd1..7fc1b862dc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -228a7879870f8689e2f9b74fbef2ff93fab7b3c2 \ No newline at end of file +ac6000f050ff4efcf8a87f0825077dbf4144f073 \ No newline at end of file diff --git a/src/parse.y b/src/parse.y index 9294a30428..04dc49d6aa 100644 --- a/src/parse.y +++ b/src/parse.y @@ -1134,9 +1134,10 @@ expr(A) ::= expr(A) between_op(N) expr(X) AND expr(Y). [BETWEEN] { exprNot(pParse, N, &A); A.zEnd = &E.z[E.n]; } - expr(A) ::= expr(A) in_op(N) nm(Y) dbnm(Z). [IN] { + expr(A) ::= expr(A) in_op(N) nm(Y) dbnm(Z) paren_exprlist(E). [IN] { SrcList *pSrc = sqlite3SrcListAppend(pParse->db, 0,&Y,&Z); Select *pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0); + if( E ) sqlite3SrcListFuncArgs(pParse, pSrc, E); A.pExpr = sqlite3PExpr(pParse, TK_IN, A.pExpr, 0, 0); sqlite3PExprAddSelect(pParse, A.pExpr, pSelect); exprNot(pParse, N, &A); @@ -1193,6 +1194,14 @@ nexprlist(A) ::= nexprlist(A) COMMA expr(Y). nexprlist(A) ::= expr(Y). {A = sqlite3ExprListAppend(pParse,0,Y.pExpr); /*A-overwrites-Y*/} +/* A paren_exprlist is an optional expression list contained inside +** of parenthesis */ +%type paren_exprlist {ExprList*} +%destructor paren_exprlist {sqlite3ExprListDelete(pParse->db, $$);} +paren_exprlist(A) ::= . {A = 0;} +paren_exprlist(A) ::= LP exprlist(X) RP. {A = X;} + + ///////////////////////////// The CREATE INDEX command /////////////////////// // diff --git a/test/tabfunc01.test b/test/tabfunc01.test index 879a045b8e..7d32f48387 100644 --- a/test/tabfunc01.test +++ b/test/tabfunc01.test @@ -135,4 +135,13 @@ do_execsql_test tabfunc01-500 { ORDER BY +1; } {1 7 11 17} +# Table-valued functions on the RHS of an IN operator +# +do_execsql_test tabfunc01-600 { + CREATE TABLE t600(a INTEGER PRIMARY KEY, b TEXT); + WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<100) + INSERT INTO t600(a,b) SELECT x, printf('(%03d)',x) FROM c; + SELECT b FROM t600 WHERE a IN generate_series(2,52,10); +} {(002) (012) (022) (032) (042) (052)} + finish_test From 9de4757c9c10c9c36c61501314cf17cdebe81c1a Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 2 Jul 2016 12:33:21 +0000 Subject: [PATCH 0537/1484] Fix a problem in table-valued functions on the RHS of an IN operator that occurs following an OOM error. FossilOrigin-Name: bead151e72215e6ca2a90eb049cfca414dccea04 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/parse.y | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 1906e09ab0..67ebe5290b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\ssupport\sfor\stable-valued\sfunctions\son\sthe\sRHS\sof\san\sIN\soperator. -D 2016-07-02T12:08:14.436 +C Fix\sa\sproblem\sin\stable-valued\sfunctions\son\sthe\sRHS\sof\san\sIN\soperator\sthat\noccurs\sfollowing\san\sOOM\serror. +D 2016-07-02T12:33:21.171 F Makefile.in bc2b4864a23a4a21c3e26d7b4350f51bab324d45 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 50149765ef72f4e652b9a0f1f6462c4784bb9423 @@ -371,7 +371,7 @@ F src/os_win.c d4b8faf8896b65818e67070711fdd00d8e620bd6 F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c c368634b888b1c8740aea83b36bfd266f2443e60 F src/pager.h 8ab6b6feeee4bc0439bfde7ee59ba99df98b9bc3 -F src/parse.y 3660ab75e7c9212fbe9ca75264d26e6587cd0ae4 +F src/parse.y f374ab20106362eb3f5c01b3e6a002f0bbead7ff F src/pcache.c 5583c8ade4b05075a60ba953ef471d1c1a9c05df F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 F src/pcache1.c 7f51d2b541aab57596adf62db2c4bb025d34f04d @@ -1503,7 +1503,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 228a7879870f8689e2f9b74fbef2ff93fab7b3c2 -R 1f493f554aeef5ddfd3c1d7c325d64e1 +P ac6000f050ff4efcf8a87f0825077dbf4144f073 +R 59b18bb8c847f9af40e3580110542be4 U drh -Z 647695f7bc7b8a80ecfde87fc6913c51 +Z 7fb23bc853c489879c3871faac168f56 diff --git a/manifest.uuid b/manifest.uuid index 7fc1b862dc..b49dcbac4b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ac6000f050ff4efcf8a87f0825077dbf4144f073 \ No newline at end of file +bead151e72215e6ca2a90eb049cfca414dccea04 \ No newline at end of file diff --git a/src/parse.y b/src/parse.y index 04dc49d6aa..8a65131e28 100644 --- a/src/parse.y +++ b/src/parse.y @@ -1137,7 +1137,7 @@ expr(A) ::= expr(A) between_op(N) expr(X) AND expr(Y). [BETWEEN] { expr(A) ::= expr(A) in_op(N) nm(Y) dbnm(Z) paren_exprlist(E). [IN] { SrcList *pSrc = sqlite3SrcListAppend(pParse->db, 0,&Y,&Z); Select *pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0); - if( E ) sqlite3SrcListFuncArgs(pParse, pSrc, E); + if( E ) sqlite3SrcListFuncArgs(pParse, pSelect ? pSrc : 0, E); A.pExpr = sqlite3PExpr(pParse, TK_IN, A.pExpr, 0, 0); sqlite3PExprAddSelect(pParse, A.pExpr, pSelect); exprNot(pParse, N, &A); From ba637157cad2aca6a4157d280e9a5559c5ed3a2d Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 2 Jul 2016 20:57:06 +0000 Subject: [PATCH 0538/1484] Fix an off-by-one comparison in the intarray() virtual table. Get the intarray() virtual table tests working using the legacy makefile. FossilOrigin-Name: 7c3d441f2a9f642f3d91dcee854a4d16d298bc34 --- ext/misc/array.c | 7 ++----- main.mk | 1 + manifest | 16 ++++++++-------- manifest.uuid | 2 +- test/tabfunc01.test | 11 +++++++++++ 5 files changed, 23 insertions(+), 14 deletions(-) diff --git a/ext/misc/array.c b/ext/misc/array.c index 54b249f90a..4420dc5178 100644 --- a/ext/misc/array.c +++ b/ext/misc/array.c @@ -25,7 +25,7 @@ ** The intarray "function" is really a virtual table with the ** following schema: ** -** CREATE FUNCTION intarray( +** CREATE TABLE intarray( ** value, ** pointer HIDDEN, ** count HIDDEN @@ -168,7 +168,7 @@ static int intarrayRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ */ static int intarrayEof(sqlite3_vtab_cursor *cur){ intarray_cursor *pCur = (intarray_cursor*)cur; - return pCur->iRowid>=pCur->iCnt; + return pCur->iRowid>pCur->iCnt; } /* @@ -181,7 +181,6 @@ static int intarrayFilter( int argc, sqlite3_value **argv ){ intarray_cursor *pCur = (intarray_cursor *)pVtabCursor; - int i = 0; if( idxNum ){ pCur->iPtr = sqlite3_value_int64(argv[0]); pCur->iCnt = sqlite3_value_int64(argv[1]); @@ -210,10 +209,8 @@ static int intarrayBestIndex( sqlite3_index_info *pIdxInfo ){ int i; /* Loop over constraints */ - int idxNum = 0; /* The query plan bitmask */ int ptrIdx = -1; /* Index of the pointer= constraint, or -1 if none */ int cntIdx = -1; /* Index of the count= constraint, or -1 if none */ - int nArg = 0; /* Number of arguments that intarrayFilter() expects */ const struct sqlite3_index_constraint *pConstraint; pConstraint = pIdxInfo->aConstraint; diff --git a/main.mk b/main.mk index ba710bfa46..9a91625948 100644 --- a/main.mk +++ b/main.mk @@ -324,6 +324,7 @@ TESTSRC = \ # TESTSRC += \ $(TOP)/ext/misc/amatch.c \ + $(TOP)/ext/misc/array.c \ $(TOP)/ext/misc/closure.c \ $(TOP)/ext/misc/csv.c \ $(TOP)/ext/misc/eval.c \ diff --git a/manifest b/manifest index 98382c2ade..f0d5a72bb4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sthe\salternative\stable-valued\sfunction\sRHS\sof\sIN\soperator\simplementation\nfrom\strunk. -D 2016-07-02T20:51:31.298 +C Fix\san\soff-by-one\scomparison\sin\sthe\sintarray()\svirtual\stable.\s\sGet\sthe\nintarray()\svirtual\stable\stests\sworking\susing\sthe\slegacy\smakefile. +D 2016-07-02T20:57:06.871 F Makefile.in 541d493154ec3b0b20b2f1d495ec66f55905191e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 50149765ef72f4e652b9a0f1f6462c4784bb9423 @@ -204,7 +204,7 @@ F ext/icu/README.txt d9fbbad0c2f647c3fdf715fc9fd64af53aedfc43 F ext/icu/icu.c 43df9d8ef2fae7a325100ebd713ab089dc829dd7 F ext/icu/sqliteicu.h 728867a802baa5a96de7495e9689a8e01715ef37 F ext/misc/amatch.c 211108e201105e4bb0c076527b8cfd34330fc234 -F ext/misc/array.c 20af0591e6611755dd8a9d1124e9c9a8cf42761f +F ext/misc/array.c bce2608f123d35eff81ac73e443b0620bed89ca1 F ext/misc/closure.c 0d2a038df8fbae7f19de42e7c7d71f2e4dc88704 F ext/misc/compress.c 122faa92d25033d6c3f07c39231de074ab3d2e83 F ext/misc/csv.c f01126ba170fd4ef7c752b156568a80c912d4441 @@ -308,7 +308,7 @@ F ext/userauth/userauth.c 5fa3bdb492f481bbc1709fc83c91ebd13460c69e F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60 -F main.mk 3f669c06db5c4a53ff21dda639247c6310497180 +F main.mk 162bb978db5519dbcaba141be346247c82b7caa8 F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 @@ -1116,7 +1116,7 @@ F test/symlink.test c9ebe7330d228249e447038276bfc8a7b22f4849 F test/sync.test 2f84bdbc2b2df1fcb0220575b4b9f8cea94b7529 F test/syscall.test f59ba4e25f7ba4a4c031026cc2ef8b6e4b4c639c F test/sysfault.test c9f2b0d8d677558f74de750c75e12a5454719d04 -F test/tabfunc01.test 96e56e22e5be82818d9673e9e993e9f26f80079a +F test/tabfunc01.test ebcfb548b88f874a5ded67e7c85ca0d5ab31f4b5 F test/table.test b708f3e5fa2542fa51dfab21fc07b36ea445cb2f F test/tableapi.test 2674633fa95d80da917571ebdd759a14d9819126 F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930 @@ -1504,7 +1504,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ba1b441b6003808810667d749635fe6b2e8c6165 bead151e72215e6ca2a90eb049cfca414dccea04 -R ab2f6bd04c16fa8193c86a3894a34997 +P 507fdbfb54ce377f0d870260b07d71b797843fcf +R 7bb6d7d8a00bd78e137b76d2018230b6 U drh -Z f71a4b07caffe5df9d8bd19d720e6958 +Z f5dbc3921a51d0860e9141544e9a9fdc diff --git a/manifest.uuid b/manifest.uuid index 2e561b3053..1d82fb3553 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -507fdbfb54ce377f0d870260b07d71b797843fcf \ No newline at end of file +7c3d441f2a9f642f3d91dcee854a4d16d298bc34 \ No newline at end of file diff --git a/test/tabfunc01.test b/test/tabfunc01.test index 044851705d..298872e0ef 100644 --- a/test/tabfunc01.test +++ b/test/tabfunc01.test @@ -201,6 +201,17 @@ do_test tabfunc01-671 { do_test tabfunc01-672 { sqlite3_column_int $VM 0 } 11 +do_test tabfunc01-673 { + sqlite3_step $VM + sqlite3_column_int $VM 0 +} 22 +do_test tabfunc01-674 { + sqlite3_step $VM + sqlite3_column_int $VM 0 +} 33 +do_test tabfunc01-675 { + sqlite3_step $VM +} {SQLITE_DONE} sqlite3_finalize $VM catch {sqlite3_bind_intarray} From 2e3f87ae8493817ceaddc316077b49d081e4e9db Mon Sep 17 00:00:00 2001 From: drh Date: Sun, 3 Jul 2016 02:35:47 +0000 Subject: [PATCH 0539/1484] Change the name of the intarray() extension to carray() and give it an optional third parameter that specifies the datatype as one of 'int32', 'int64', 'double', or 'char*'. 'int32' is the default. FossilOrigin-Name: a204ba99db34b356acb259189158a32d2df25da0 --- Makefile.in | 2 +- Makefile.msc | 1 + ext/misc/array.c | 293 ----------------------------------- ext/misc/carray.c | 369 ++++++++++++++++++++++++++++++++++++++++++++ main.mk | 2 +- manifest | 22 +-- manifest.uuid | 2 +- src/test1.c | 147 +++++++++++++++--- test/tabfunc01.test | 109 ++++++------- 9 files changed, 550 insertions(+), 397 deletions(-) delete mode 100644 ext/misc/array.c create mode 100644 ext/misc/carray.c diff --git a/Makefile.in b/Makefile.in index ff863ec906..fd0ad6b6a7 100644 --- a/Makefile.in +++ b/Makefile.in @@ -416,7 +416,7 @@ TESTSRC = \ # TESTSRC += \ $(TOP)/ext/misc/amatch.c \ - $(TOP)/ext/misc/array.c \ + $(TOP)/ext/misc/carray.c \ $(TOP)/ext/misc/closure.c \ $(TOP)/ext/misc/csv.c \ $(TOP)/ext/misc/eval.c \ diff --git a/Makefile.msc b/Makefile.msc index 93116cd0dc..cd866ce4a4 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -1292,6 +1292,7 @@ TESTSRC = \ # TESTEXT = \ $(TOP)\ext\misc\amatch.c \ + $(TOP)\ext\misc\carray.c \ $(TOP)\ext\misc\closure.c \ $(TOP)\ext\misc\csv.c \ $(TOP)\ext\misc\eval.c \ diff --git a/ext/misc/array.c b/ext/misc/array.c deleted file mode 100644 index 4420dc5178..0000000000 --- a/ext/misc/array.c +++ /dev/null @@ -1,293 +0,0 @@ -/* -** 2016-06-29 -** -** 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 demonstrates how to create a table-valued-function that -** returns the values in a C-language array. -** Examples: -** -** SELECT * FROM intarray($ptr,5) -** -** The query above returns 5 integers contained in a C-language array -** at the address $ptr. $ptr is a pointer to the array of integers that -** has been cast to an integer. -** -** HOW IT WORKS -** -** The intarray "function" is really a virtual table with the -** following schema: -** -** CREATE TABLE intarray( -** value, -** pointer HIDDEN, -** count HIDDEN -** ); -*/ -#include "sqlite3ext.h" -SQLITE_EXTENSION_INIT1 -#include -#include - -#ifndef SQLITE_OMIT_VIRTUALTABLE - - -/* intarray_cursor is a subclass of sqlite3_vtab_cursor which will -** serve as the underlying representation of a cursor that scans -** over rows of the result -*/ -typedef struct intarray_cursor intarray_cursor; -struct intarray_cursor { - sqlite3_vtab_cursor base; /* Base class - must be first */ - int isDesc; /* True to count down rather than up */ - sqlite3_int64 iRowid; /* The rowid */ - sqlite3_int64 iPtr; /* Pointer to array of integers */ - sqlite3_int64 iCnt; /* Number of integers in the array */ -}; - -/* -** The intarrayConnect() method is invoked to create a new -** intarray_vtab that describes the intarray virtual table. -** -** Think of this routine as the constructor for intarray_vtab objects. -** -** All this routine needs to do is: -** -** (1) Allocate the intarray_vtab object and initialize all fields. -** -** (2) Tell SQLite (via the sqlite3_declare_vtab() interface) what the -** result set of queries against intarray will look like. -*/ -static int intarrayConnect( - sqlite3 *db, - void *pAux, - int argc, const char *const*argv, - sqlite3_vtab **ppVtab, - char **pzErr -){ - sqlite3_vtab *pNew; - int rc; - -/* Column numbers */ -#define INTARRAY_COLUMN_VALUE 0 -#define INTARRAY_COLUMN_POINTER 1 -#define INTARRAY_COLUMN_COUNT 2 - - rc = sqlite3_declare_vtab(db, - "CREATE TABLE x(value,pointer hidden,count hidden)"); - if( rc==SQLITE_OK ){ - pNew = *ppVtab = sqlite3_malloc( sizeof(*pNew) ); - if( pNew==0 ) return SQLITE_NOMEM; - memset(pNew, 0, sizeof(*pNew)); - } - return rc; -} - -/* -** This method is the destructor for intarray_cursor objects. -*/ -static int intarrayDisconnect(sqlite3_vtab *pVtab){ - sqlite3_free(pVtab); - return SQLITE_OK; -} - -/* -** Constructor for a new intarray_cursor object. -*/ -static int intarrayOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){ - intarray_cursor *pCur; - pCur = sqlite3_malloc( sizeof(*pCur) ); - if( pCur==0 ) return SQLITE_NOMEM; - memset(pCur, 0, sizeof(*pCur)); - *ppCursor = &pCur->base; - return SQLITE_OK; -} - -/* -** Destructor for a intarray_cursor. -*/ -static int intarrayClose(sqlite3_vtab_cursor *cur){ - sqlite3_free(cur); - return SQLITE_OK; -} - - -/* -** Advance a intarray_cursor to its next row of output. -*/ -static int intarrayNext(sqlite3_vtab_cursor *cur){ - intarray_cursor *pCur = (intarray_cursor*)cur; - pCur->iRowid++; - return SQLITE_OK; -} - -/* -** Return values of columns for the row at which the intarray_cursor -** is currently pointing. -*/ -static int intarrayColumn( - sqlite3_vtab_cursor *cur, /* The cursor */ - sqlite3_context *ctx, /* First argument to sqlite3_result_...() */ - int i /* Which column to return */ -){ - intarray_cursor *pCur = (intarray_cursor*)cur; - sqlite3_int64 x = 0; - switch( i ){ - case INTARRAY_COLUMN_POINTER: x = pCur->iPtr; break; - case INTARRAY_COLUMN_COUNT: x = pCur->iCnt; break; - default: { - int *p = (int*)pCur->iPtr; - x = (int)p[pCur->iRowid-1]; - break; - } - } - sqlite3_result_int64(ctx, x); - return SQLITE_OK; -} - -/* -** Return the rowid for the current row. In this implementation, the -** rowid is the same as the output value. -*/ -static int intarrayRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ - intarray_cursor *pCur = (intarray_cursor*)cur; - *pRowid = pCur->iRowid; - return SQLITE_OK; -} - -/* -** Return TRUE if the cursor has been moved off of the last -** row of output. -*/ -static int intarrayEof(sqlite3_vtab_cursor *cur){ - intarray_cursor *pCur = (intarray_cursor*)cur; - return pCur->iRowid>pCur->iCnt; -} - -/* -** This method is called to "rewind" the intarray_cursor object back -** to the first row of output. -*/ -static int intarrayFilter( - sqlite3_vtab_cursor *pVtabCursor, - int idxNum, const char *idxStr, - int argc, sqlite3_value **argv -){ - intarray_cursor *pCur = (intarray_cursor *)pVtabCursor; - if( idxNum ){ - pCur->iPtr = sqlite3_value_int64(argv[0]); - pCur->iCnt = sqlite3_value_int64(argv[1]); - }else{ - pCur->iPtr = 0; - pCur->iCnt = 0; - } - pCur->iRowid = 1; - return SQLITE_OK; -} - -/* -** SQLite will invoke this method one or more times while planning a query -** that uses the intarray virtual table. This routine needs to create -** a query plan for each invocation and compute an estimated cost for that -** plan. -** -** In this implementation idxNum is used to represent the -** query plan. idxStr is unused. -** -** idxNum is 1 if the pointer= and count= constraints exist and is 0 otherwise. -** If idxNum is 0, then intarray becomes an empty table. -*/ -static int intarrayBestIndex( - sqlite3_vtab *tab, - sqlite3_index_info *pIdxInfo -){ - int i; /* Loop over constraints */ - int ptrIdx = -1; /* Index of the pointer= constraint, or -1 if none */ - int cntIdx = -1; /* Index of the count= constraint, or -1 if none */ - - const struct sqlite3_index_constraint *pConstraint; - pConstraint = pIdxInfo->aConstraint; - for(i=0; inConstraint; i++, pConstraint++){ - if( pConstraint->usable==0 ) continue; - if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue; - switch( pConstraint->iColumn ){ - case INTARRAY_COLUMN_POINTER: - ptrIdx = i; - break; - case INTARRAY_COLUMN_COUNT: - cntIdx = i; - break; - } - } - if( ptrIdx>=0 && cntIdx>=0 ){ - pIdxInfo->aConstraintUsage[ptrIdx].argvIndex = 1; - pIdxInfo->aConstraintUsage[ptrIdx].omit = 1; - pIdxInfo->aConstraintUsage[cntIdx].argvIndex = 2; - pIdxInfo->aConstraintUsage[cntIdx].omit = 1; - pIdxInfo->estimatedCost = (double)1; - pIdxInfo->estimatedRows = (double)100; - pIdxInfo->idxNum = 1; - }else{ - pIdxInfo->estimatedCost = (double)2147483647; - pIdxInfo->estimatedRows = (double)2147483647; - pIdxInfo->idxNum = 0; - } - return SQLITE_OK; -} - -/* -** This following structure defines all the methods for the -** intarray virtual table. -*/ -static sqlite3_module intarrayModule = { - 0, /* iVersion */ - 0, /* xCreate */ - intarrayConnect, /* xConnect */ - intarrayBestIndex, /* xBestIndex */ - intarrayDisconnect, /* xDisconnect */ - 0, /* xDestroy */ - intarrayOpen, /* xOpen - open a cursor */ - intarrayClose, /* xClose - close a cursor */ - intarrayFilter, /* xFilter - configure scan constraints */ - intarrayNext, /* xNext - advance a cursor */ - intarrayEof, /* xEof - check for end of scan */ - intarrayColumn, /* xColumn - read data */ - intarrayRowid, /* xRowid - read data */ - 0, /* xUpdate */ - 0, /* xBegin */ - 0, /* xSync */ - 0, /* xCommit */ - 0, /* xRollback */ - 0, /* xFindMethod */ - 0, /* xRename */ -}; - -#endif /* SQLITE_OMIT_VIRTUALTABLE */ - -#ifdef _WIN32 -__declspec(dllexport) -#endif -int sqlite3_array_init( - sqlite3 *db, - char **pzErrMsg, - const sqlite3_api_routines *pApi -){ - int rc = SQLITE_OK; - SQLITE_EXTENSION_INIT2(pApi); -#ifndef SQLITE_OMIT_VIRTUALTABLE - if( sqlite3_libversion_number()<3008012 ){ - *pzErrMsg = sqlite3_mprintf( - "intarray() requires SQLite 3.8.12 or later"); - return SQLITE_ERROR; - } - rc = sqlite3_create_module(db, "intarray", &intarrayModule, 0); -#endif - return rc; -} diff --git a/ext/misc/carray.c b/ext/misc/carray.c new file mode 100644 index 0000000000..70d226a85f --- /dev/null +++ b/ext/misc/carray.c @@ -0,0 +1,369 @@ +/* +** 2016-06-29 +** +** 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 demonstrates how to create a table-valued-function that +** returns the values in a C-language array. +** Examples: +** +** SELECT * FROM array($ptr,5) +** +** The query above returns 5 integers contained in a C-language array +** at the address $ptr. $ptr is a pointer to the array of integers that +** has been cast to an integer. +** +** There is an optional third parameter to determine the datatype of +** the C-language array. Allowed values of the third parameter are +** 'int32', 'int64', 'double', 'char*'. Example: +** +** SELECT * FROM array($ptr,10,'char*'); +** +** HOW IT WORKS +** +** The carray "function" is really a virtual table with the +** following schema: +** +** CREATE TABLE carray( +** value, +** pointer HIDDEN, +** count HIDDEN, +** ctype TEXT HIDDEN +** ); +** +** If the hidden columns "pointer" and "count" are unconstrained, then +** the virtual table has no rows. Otherwise, the virtual table interprets +** the integer value of "pointer" as a pointer to the array and "count" +** as the number of elements in the array. The virtual table steps through +** the array, element by element. +*/ +#include "sqlite3ext.h" +SQLITE_EXTENSION_INIT1 +#include +#include + +#ifndef SQLITE_OMIT_VIRTUALTABLE + +/* +** Allowed datatypes +*/ +#define CARRAY_INT32 0 +#define CARRAY_INT64 1 +#define CARRAY_DOUBLE 2 +#define CARRAY_TEXT 3 + +/* +** Names of types +*/ +static const char *azType[] = { "int32", "int64", "double", "char*" }; + + +/* carray_cursor is a subclass of sqlite3_vtab_cursor which will +** serve as the underlying representation of a cursor that scans +** over rows of the result +*/ +typedef struct carray_cursor carray_cursor; +struct carray_cursor { + sqlite3_vtab_cursor base; /* Base class - must be first */ + sqlite3_int64 iRowid; /* The rowid */ + sqlite3_int64 iPtr; /* Pointer to array of values */ + sqlite3_int64 iCnt; /* Number of integers in the array */ + unsigned char eType; /* One of the CARRAY_type values */ +}; + +/* +** The carrayConnect() method is invoked to create a new +** carray_vtab that describes the carray virtual table. +** +** Think of this routine as the constructor for carray_vtab objects. +** +** All this routine needs to do is: +** +** (1) Allocate the carray_vtab object and initialize all fields. +** +** (2) Tell SQLite (via the sqlite3_declare_vtab() interface) what the +** result set of queries against carray will look like. +*/ +static int carrayConnect( + sqlite3 *db, + void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVtab, + char **pzErr +){ + sqlite3_vtab *pNew; + int rc; + +/* Column numbers */ +#define CARRAY_COLUMN_VALUE 0 +#define CARRAY_COLUMN_POINTER 1 +#define CARRAY_COLUMN_COUNT 2 +#define CARRAY_COLUMN_CTYPE 3 + + rc = sqlite3_declare_vtab(db, + "CREATE TABLE x(value,pointer hidden,count hidden,ctype hidden)"); + if( rc==SQLITE_OK ){ + pNew = *ppVtab = sqlite3_malloc( sizeof(*pNew) ); + if( pNew==0 ) return SQLITE_NOMEM; + memset(pNew, 0, sizeof(*pNew)); + } + return rc; +} + +/* +** This method is the destructor for carray_cursor objects. +*/ +static int carrayDisconnect(sqlite3_vtab *pVtab){ + sqlite3_free(pVtab); + return SQLITE_OK; +} + +/* +** Constructor for a new carray_cursor object. +*/ +static int carrayOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){ + carray_cursor *pCur; + pCur = sqlite3_malloc( sizeof(*pCur) ); + if( pCur==0 ) return SQLITE_NOMEM; + memset(pCur, 0, sizeof(*pCur)); + *ppCursor = &pCur->base; + return SQLITE_OK; +} + +/* +** Destructor for a carray_cursor. +*/ +static int carrayClose(sqlite3_vtab_cursor *cur){ + sqlite3_free(cur); + return SQLITE_OK; +} + + +/* +** Advance a carray_cursor to its next row of output. +*/ +static int carrayNext(sqlite3_vtab_cursor *cur){ + carray_cursor *pCur = (carray_cursor*)cur; + pCur->iRowid++; + return SQLITE_OK; +} + +/* +** Return values of columns for the row at which the carray_cursor +** is currently pointing. +*/ +static int carrayColumn( + sqlite3_vtab_cursor *cur, /* The cursor */ + sqlite3_context *ctx, /* First argument to sqlite3_result_...() */ + int i /* Which column to return */ +){ + carray_cursor *pCur = (carray_cursor*)cur; + sqlite3_int64 x = 0; + switch( i ){ + case CARRAY_COLUMN_POINTER: x = pCur->iPtr; break; + case CARRAY_COLUMN_COUNT: x = pCur->iCnt; break; + case CARRAY_COLUMN_CTYPE: { + sqlite3_result_text(ctx, azType[pCur->eType], -1, SQLITE_STATIC); + return SQLITE_OK; + } + default: { + switch( pCur->eType ){ + case CARRAY_INT32: { + int *p = (int*)pCur->iPtr; + sqlite3_result_int(ctx, p[pCur->iRowid-1]); + return SQLITE_OK; + } + case CARRAY_INT64: { + sqlite3_int64 *p = (sqlite3_int64*)pCur->iPtr; + sqlite3_result_int64(ctx, p[pCur->iRowid-1]); + return SQLITE_OK; + } + case CARRAY_DOUBLE: { + double *p = (double*)pCur->iPtr; + sqlite3_result_double(ctx, p[pCur->iRowid-1]); + return SQLITE_OK; + } + case CARRAY_TEXT: { + const char **p = (const char**)pCur->iPtr; + sqlite3_result_text(ctx, p[pCur->iRowid-1], -1, SQLITE_TRANSIENT); + return SQLITE_OK; + } + } + } + } + sqlite3_result_int64(ctx, x); + return SQLITE_OK; +} + +/* +** Return the rowid for the current row. In this implementation, the +** rowid is the same as the output value. +*/ +static int carrayRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ + carray_cursor *pCur = (carray_cursor*)cur; + *pRowid = pCur->iRowid; + return SQLITE_OK; +} + +/* +** Return TRUE if the cursor has been moved off of the last +** row of output. +*/ +static int carrayEof(sqlite3_vtab_cursor *cur){ + carray_cursor *pCur = (carray_cursor*)cur; + return pCur->iRowid>pCur->iCnt; +} + +/* +** This method is called to "rewind" the carray_cursor object back +** to the first row of output. +*/ +static int carrayFilter( + sqlite3_vtab_cursor *pVtabCursor, + int idxNum, const char *idxStr, + int argc, sqlite3_value **argv +){ + carray_cursor *pCur = (carray_cursor *)pVtabCursor; + if( idxNum ){ + pCur->iPtr = sqlite3_value_int64(argv[0]); + pCur->iCnt = sqlite3_value_int64(argv[1]); + if( idxNum<3 ){ + pCur->eType = CARRAY_INT32; + }else{ + int i; + const char *zType = (const char*)sqlite3_value_text(argv[2]); + for(i=0; i=sizeof(azType)/sizeof(azType[0]) ){ + pVtabCursor->pVtab->zErrMsg = sqlite3_mprintf( + "unknown datatype: %Q", zType); + return SQLITE_ERROR; + }else{ + pCur->eType = i; + } + } + }else{ + pCur->iPtr = 0; + pCur->iCnt = 0; + } + pCur->iRowid = 1; + return SQLITE_OK; +} + +/* +** SQLite will invoke this method one or more times while planning a query +** that uses the carray virtual table. This routine needs to create +** a query plan for each invocation and compute an estimated cost for that +** plan. +** +** In this implementation idxNum is used to represent the +** query plan. idxStr is unused. +** +** idxNum is 2 if the pointer= and count= constraints exist, +** 3 if the ctype= constraint also exists, and is 0 otherwise. +** If idxNum is 0, then carray becomes an empty table. +*/ +static int carrayBestIndex( + sqlite3_vtab *tab, + sqlite3_index_info *pIdxInfo +){ + int i; /* Loop over constraints */ + int ptrIdx = -1; /* Index of the pointer= constraint, or -1 if none */ + int cntIdx = -1; /* Index of the count= constraint, or -1 if none */ + int ctypeIdx = -1; /* Index of the ctype= constraint, or -1 if none */ + + const struct sqlite3_index_constraint *pConstraint; + pConstraint = pIdxInfo->aConstraint; + for(i=0; inConstraint; i++, pConstraint++){ + if( pConstraint->usable==0 ) continue; + if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue; + switch( pConstraint->iColumn ){ + case CARRAY_COLUMN_POINTER: + ptrIdx = i; + break; + case CARRAY_COLUMN_COUNT: + cntIdx = i; + break; + case CARRAY_COLUMN_CTYPE: + ctypeIdx = i; + break; + } + } + if( ptrIdx>=0 && cntIdx>=0 ){ + pIdxInfo->aConstraintUsage[ptrIdx].argvIndex = 1; + pIdxInfo->aConstraintUsage[ptrIdx].omit = 1; + pIdxInfo->aConstraintUsage[cntIdx].argvIndex = 2; + pIdxInfo->aConstraintUsage[cntIdx].omit = 1; + pIdxInfo->estimatedCost = (double)1; + pIdxInfo->estimatedRows = (double)100; + pIdxInfo->idxNum = 2; + if( ctypeIdx>=0 ){ + pIdxInfo->aConstraintUsage[ctypeIdx].argvIndex = 3; + pIdxInfo->aConstraintUsage[ctypeIdx].omit = 1; + pIdxInfo->idxNum = 3; + } + }else{ + pIdxInfo->estimatedCost = (double)2147483647; + pIdxInfo->estimatedRows = (double)2147483647; + pIdxInfo->idxNum = 0; + } + return SQLITE_OK; +} + +/* +** This following structure defines all the methods for the +** carray virtual table. +*/ +static sqlite3_module carrayModule = { + 0, /* iVersion */ + 0, /* xCreate */ + carrayConnect, /* xConnect */ + carrayBestIndex, /* xBestIndex */ + carrayDisconnect, /* xDisconnect */ + 0, /* xDestroy */ + carrayOpen, /* xOpen - open a cursor */ + carrayClose, /* xClose - close a cursor */ + carrayFilter, /* xFilter - configure scan constraints */ + carrayNext, /* xNext - advance a cursor */ + carrayEof, /* xEof - check for end of scan */ + carrayColumn, /* xColumn - read data */ + carrayRowid, /* xRowid - read data */ + 0, /* xUpdate */ + 0, /* xBegin */ + 0, /* xSync */ + 0, /* xCommit */ + 0, /* xRollback */ + 0, /* xFindMethod */ + 0, /* xRename */ +}; + +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + +#ifdef _WIN32 +__declspec(dllexport) +#endif +int sqlite3_carray_init( + sqlite3 *db, + char **pzErrMsg, + const sqlite3_api_routines *pApi +){ + int rc = SQLITE_OK; + SQLITE_EXTENSION_INIT2(pApi); +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( sqlite3_libversion_number()<3008012 ){ + *pzErrMsg = sqlite3_mprintf( + "carray() requires SQLite 3.8.12 or later"); + return SQLITE_ERROR; + } + rc = sqlite3_create_module(db, "carray", &carrayModule, 0); +#endif + return rc; +} diff --git a/main.mk b/main.mk index 9a91625948..e3da609750 100644 --- a/main.mk +++ b/main.mk @@ -324,7 +324,7 @@ TESTSRC = \ # TESTSRC += \ $(TOP)/ext/misc/amatch.c \ - $(TOP)/ext/misc/array.c \ + $(TOP)/ext/misc/carray.c \ $(TOP)/ext/misc/closure.c \ $(TOP)/ext/misc/csv.c \ $(TOP)/ext/misc/eval.c \ diff --git a/manifest b/manifest index f0d5a72bb4..4f9231b7f5 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -C Fix\san\soff-by-one\scomparison\sin\sthe\sintarray()\svirtual\stable.\s\sGet\sthe\nintarray()\svirtual\stable\stests\sworking\susing\sthe\slegacy\smakefile. -D 2016-07-02T20:57:06.871 -F Makefile.in 541d493154ec3b0b20b2f1d495ec66f55905191e +C Change\sthe\sname\sof\sthe\sintarray()\sextension\sto\scarray()\sand\sgive\sit\san\noptional\sthird\sparameter\sthat\sspecifies\sthe\sdatatype\sas\sone\sof\s'int32',\n'int64',\s'double',\sor\s'char*'.\s\s'int32'\sis\sthe\sdefault. +D 2016-07-03T02:35:47.798 +F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 -F Makefile.msc 50149765ef72f4e652b9a0f1f6462c4784bb9423 +F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7 F VERSION cb29eb11e493dd85b3eeec4053c03949bf98478e F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 @@ -204,7 +204,7 @@ F ext/icu/README.txt d9fbbad0c2f647c3fdf715fc9fd64af53aedfc43 F ext/icu/icu.c 43df9d8ef2fae7a325100ebd713ab089dc829dd7 F ext/icu/sqliteicu.h 728867a802baa5a96de7495e9689a8e01715ef37 F ext/misc/amatch.c 211108e201105e4bb0c076527b8cfd34330fc234 -F ext/misc/array.c bce2608f123d35eff81ac73e443b0620bed89ca1 +F ext/misc/carray.c f1947c7d5bbce17f8244c9a05baae11d5d68467e w ext/misc/array.c F ext/misc/closure.c 0d2a038df8fbae7f19de42e7c7d71f2e4dc88704 F ext/misc/compress.c 122faa92d25033d6c3f07c39231de074ab3d2e83 F ext/misc/csv.c f01126ba170fd4ef7c752b156568a80c912d4441 @@ -308,7 +308,7 @@ F ext/userauth/userauth.c 5fa3bdb492f481bbc1709fc83c91ebd13460c69e F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60 -F main.mk 162bb978db5519dbcaba141be346247c82b7caa8 +F main.mk e9d66f1b1c4874221d12d940be3ce5f397c10741 F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 @@ -393,7 +393,7 @@ F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 F src/tclsqlite.c 25fbbbb97f76dbfd113153fb63f52d7ecfac5dd0 -F src/test1.c 081e4ed40525590406a51f7e7e4cee31cdb5d029 +F src/test1.c 7cbfda741fbfa541ecce305ff2d7c6bb730aa991 F src/test2.c 5586f43fcd9a1be0830793cf9d354082c261b25b F src/test3.c c75c8af0eadb335236c9e61b51044c58a8f7dd59 F src/test4.c d168f83cc78d02e8d35567bb5630e40dcd85ac1e @@ -1116,7 +1116,7 @@ F test/symlink.test c9ebe7330d228249e447038276bfc8a7b22f4849 F test/sync.test 2f84bdbc2b2df1fcb0220575b4b9f8cea94b7529 F test/syscall.test f59ba4e25f7ba4a4c031026cc2ef8b6e4b4c639c F test/sysfault.test c9f2b0d8d677558f74de750c75e12a5454719d04 -F test/tabfunc01.test ebcfb548b88f874a5ded67e7c85ca0d5ab31f4b5 +F test/tabfunc01.test 50a9fb379f9747fd0d40ea6d8fa3a101361bb537 F test/table.test b708f3e5fa2542fa51dfab21fc07b36ea445cb2f F test/tableapi.test 2674633fa95d80da917571ebdd759a14d9819126 F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930 @@ -1504,7 +1504,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 507fdbfb54ce377f0d870260b07d71b797843fcf -R 7bb6d7d8a00bd78e137b76d2018230b6 +P 7c3d441f2a9f642f3d91dcee854a4d16d298bc34 +R 41f36cbba6be0bbd66a667562505a546 U drh -Z f5dbc3921a51d0860e9141544e9a9fdc +Z 31f2105436c0dcfd40b6904e7b94f7b1 diff --git a/manifest.uuid b/manifest.uuid index 1d82fb3553..869a21e73c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7c3d441f2a9f642f3d91dcee854a4d16d298bc34 \ No newline at end of file +a204ba99db34b356acb259189158a32d2df25da0 \ No newline at end of file diff --git a/src/test1.c b/src/test1.c index 9a73e0e0b5..8e8020c043 100644 --- a/src/test1.c +++ b/src/test1.c @@ -3242,41 +3242,137 @@ static int test_bind_int( /* -** Usage: sqlite3_bind_intarray STMT N INT ... +** Usage: intarray_addr INT ... ** -** Create a C-language array of integers from the arguments. Bind a pointer -** to this array to the NAME parameter of STMT. +** Return the address of a C-language array of 32-bit integers. +** +** Space to hold the array is obtained from malloc(). Call this procedure once +** with no arguments in order to release memory. Each call to this procedure +** overwrites the previous array. */ -static int test_bind_intarray( +static int test_intarray_addr( void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ - sqlite3_stmt *pStmt; - int idx; int i; static int *p = 0; sqlite3_free(p); p = 0; - if( objc<4 ){ - Tcl_AppendResult(interp, "wrong # args: should be \"", - Tcl_GetStringFromObj(objv[0], 0), " STMT NAME INT...", 0); - return TCL_ERROR; - } - - if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; - if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR; - p = sqlite3_malloc( sizeof(int)*(objc-3) ); - if( p==0 ) return TCL_ERROR; - for(i=0; i1 ){ + p = sqlite3_malloc( sizeof(p[0])*(objc-1) ); + if( p==0 ) return TCL_ERROR; + for(i=0; i1 ){ + p = sqlite3_malloc( sizeof(p[0])*(objc-1) ); + if( p==0 ) return TCL_ERROR; + for(i=0; i1 ){ + p = sqlite3_malloc( sizeof(p[0])*(objc-1) ); + if( p==0 ) return TCL_ERROR; + for(i=0; i1 ){ + p = sqlite3_malloc( sizeof(p[0])*(objc-1) ); + if( p==0 ) return TCL_ERROR; + for(i=0; i Date: Tue, 5 Jul 2016 12:47:28 +0000 Subject: [PATCH 0540/1484] Attempt to reset the error count in the Lemon-generated parser after a parse failure. FossilOrigin-Name: 91889fa30e84760e0d4b3d429c4abdef5a3f7931 --- manifest | 15 +++++++-------- manifest.uuid | 2 +- tool/lempar.c | 5 ++++- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 0a95c7965f..f3aa7ea38c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\ssqlite3rbu_state()\sAPI.\sUsed\sto\sdetermine\sthe\scurrent\sstate\s(creating\sOAL,\sready\sto\smove\sOAL,\sincremental-checkpoint,\sfinished\sor\serror)\sof\san\sRBU\soperation. -D 2016-07-04T11:47:48.898 +C Attempt\sto\sreset\sthe\serror\scount\sin\sthe\sLemon-generated\sparser\safter\na\sparse\sfailure. +D 2016-07-05T12:47:28.882 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -1432,7 +1432,7 @@ F tool/genfkey.README cf68fddd4643bbe3ff8e31b8b6d8b0a1b85e20f4 F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5 F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce F tool/lemon.c 09a96bed19955697a5e20c49ad863ec2005815a2 -F tool/lempar.c 8c4e9d8517e50da391f1d89a519e743dd4afbc09 +F tool/lempar.c f2c88a13ab6611ce752d176fa8c83318ca715df0 F tool/libvers.c caafc3b689638a1d88d44bc5f526c2278760d9b9 F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862 F tool/logest.c 11346aa019e2e77a00902aa7d0cabd27bd2e8cca @@ -1504,8 +1504,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d8bc6feb99938a2aa06142b217045e4b54c66bf1 92e7df0ff5c4c118c63d92a767dc82700438a310 -R 985e1d1c0fa6ec62417a6fcb0acf4b8c -T +closed 92e7df0ff5c4c118c63d92a767dc82700438a310 -U dan -Z dee206ff16109350ba5a0f9bf08fce29 +P 0357875fbb1bb462feef5121287b2f84da88e497 +R a578f6c3df8fc8ba3d5f62a27a2cbf5b +U drh +Z 5d179a5613158bad283b799b101c68f6 diff --git a/manifest.uuid b/manifest.uuid index 98d13d9075..b21c3982ec 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0357875fbb1bb462feef5121287b2f84da88e497 \ No newline at end of file +91889fa30e84760e0d4b3d429c4abdef5a3f7931 \ No newline at end of file diff --git a/tool/lempar.c b/tool/lempar.c index 9b76d6e3c5..112d0bdaa3 100644 --- a/tool/lempar.c +++ b/tool/lempar.c @@ -390,6 +390,7 @@ static void yy_destructor( static void yy_pop_parser_stack(yyParser *pParser){ yyStackEntry *yytos; assert( pParser->yytos!=0 ); + assert( pParser->yytos > pParser->yystack ); yytos = pParser->yytos--; #ifndef NDEBUG if( yyTraceFILE ){ @@ -799,7 +800,6 @@ void Parse( #endif yyParser *yypParser; /* The parser */ - /* (re)initialize the parser, if necessary */ yypParser = (yyParser*)yyp; assert( yypParser->yytos!=0 ); #if !defined(YYERRORSYMBOL) && !defined(YYNOERRORRECOVERY) @@ -879,6 +879,9 @@ void Parse( if( yypParser->yytos < yypParser->yystack || yymajor==0 ){ yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion); yy_parse_failed(yypParser); +#ifndef YYNOERRORRECOVERY + yypParser->yyerrcnt = -1; +#endif yymajor = YYNOCODE; }else if( yymx!=YYERRORSYMBOL ){ yy_shift(yypParser,yyact,YYERRORSYMBOL,yyminor); From e0a6e0fda0c3b6bda7853305da88a566249cc3a1 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 5 Jul 2016 16:11:26 +0000 Subject: [PATCH 0541/1484] More fixes to Fossil so that it automatically resets its error counter at the end of a parse. FossilOrigin-Name: 2683b375ad1291172fdb47d94e16fcf869c78c8a --- manifest | 12 ++++++------ manifest.uuid | 2 +- tool/lempar.c | 3 +++ 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index f3aa7ea38c..f0b8e863c2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Attempt\sto\sreset\sthe\serror\scount\sin\sthe\sLemon-generated\sparser\safter\na\sparse\sfailure. -D 2016-07-05T12:47:28.882 +C More\sfixes\sto\sFossil\sso\sthat\sit\sautomatically\sresets\sits\serror\scounter\sat\sthe\nend\sof\sa\sparse. +D 2016-07-05T16:11:26.639 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -1432,7 +1432,7 @@ F tool/genfkey.README cf68fddd4643bbe3ff8e31b8b6d8b0a1b85e20f4 F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5 F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce F tool/lemon.c 09a96bed19955697a5e20c49ad863ec2005815a2 -F tool/lempar.c f2c88a13ab6611ce752d176fa8c83318ca715df0 +F tool/lempar.c 072ff9985f36796b95bdc895820f2d77255a7067 F tool/libvers.c caafc3b689638a1d88d44bc5f526c2278760d9b9 F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862 F tool/logest.c 11346aa019e2e77a00902aa7d0cabd27bd2e8cca @@ -1504,7 +1504,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 0357875fbb1bb462feef5121287b2f84da88e497 -R a578f6c3df8fc8ba3d5f62a27a2cbf5b +P 91889fa30e84760e0d4b3d429c4abdef5a3f7931 +R 9a4b1699bf11208d065bcf8cf2e02081 U drh -Z 5d179a5613158bad283b799b101c68f6 +Z a4f82b8f6b61ef506efe9cc9a72c59ae diff --git a/manifest.uuid b/manifest.uuid index b21c3982ec..956c49dd64 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -91889fa30e84760e0d4b3d429c4abdef5a3f7931 \ No newline at end of file +2683b375ad1291172fdb47d94e16fcf869c78c8a \ No newline at end of file diff --git a/tool/lempar.c b/tool/lempar.c index 112d0bdaa3..d7236efa89 100644 --- a/tool/lempar.c +++ b/tool/lempar.c @@ -898,6 +898,9 @@ void Parse( ** they intend to abandon the parse upon the first syntax error seen. */ yy_syntax_error(yypParser,yymajor, yyminor); +#ifndef YYNOERRORRECOVERY + yypParser->yyerrcnt = -1; +#endif yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion); yymajor = YYNOCODE; From 50687436f75e8fc56c495a69d8ac9eaf29b3c97e Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 6 Jul 2016 09:19:14 +0000 Subject: [PATCH 0542/1484] Fix a memory leak in recently added test code. FossilOrigin-Name: 724e4cdc25fc80b8face57b3398cd338994fb23c --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/test1.c | 3 ++- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index f0b8e863c2..2ae741da57 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C More\sfixes\sto\sFossil\sso\sthat\sit\sautomatically\sresets\sits\serror\scounter\sat\sthe\nend\sof\sa\sparse. -D 2016-07-05T16:11:26.639 +C Fix\sa\smemory\sleak\sin\srecently\sadded\stest\scode. +D 2016-07-06T09:19:14.702 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -393,7 +393,7 @@ F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 F src/tclsqlite.c 25fbbbb97f76dbfd113153fb63f52d7ecfac5dd0 -F src/test1.c 7cbfda741fbfa541ecce305ff2d7c6bb730aa991 +F src/test1.c 08faa045c45b1d3f62c28c93cae955f518317f68 F src/test2.c 5586f43fcd9a1be0830793cf9d354082c261b25b F src/test3.c c75c8af0eadb335236c9e61b51044c58a8f7dd59 F src/test4.c d168f83cc78d02e8d35567bb5630e40dcd85ac1e @@ -1504,7 +1504,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 91889fa30e84760e0d4b3d429c4abdef5a3f7931 -R 9a4b1699bf11208d065bcf8cf2e02081 -U drh -Z a4f82b8f6b61ef506efe9cc9a72c59ae +P 2683b375ad1291172fdb47d94e16fcf869c78c8a +R bad3fed306e6177658099344318135b4 +U dan +Z b779329b8bc265169140036a21a84f9f diff --git a/manifest.uuid b/manifest.uuid index 956c49dd64..457a7b2b76 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2683b375ad1291172fdb47d94e16fcf869c78c8a \ No newline at end of file +724e4cdc25fc80b8face57b3398cd338994fb23c \ No newline at end of file diff --git a/src/test1.c b/src/test1.c index 8e8020c043..d4a5cfc3ce 100644 --- a/src/test1.c +++ b/src/test1.c @@ -3371,7 +3371,8 @@ static int test_textarray_addr( for(i=0; i Date: Wed, 6 Jul 2016 10:12:02 +0000 Subject: [PATCH 0543/1484] Add the SQLITE_DBSTATUS_PROPORTIONAL_CACHE_USED sqlite3_db_status() parameter. FossilOrigin-Name: 118321c8b9d88b8f439c952436f42838c3fc80cb --- manifest | 25 ++++++++++++++----------- manifest.uuid | 2 +- src/btree.c | 13 ++++++++++++- src/btree.h | 2 ++ src/sqlite.h.in | 15 ++++++++++++++- src/status.c | 7 ++++++- src/test_malloc.c | 3 ++- test/dbstatus.test | 37 +++++++++++++++++++++++++++++++++++++ 8 files changed, 88 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index 2ae741da57..662bd8b161 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\smemory\sleak\sin\srecently\sadded\stest\scode. -D 2016-07-06T09:19:14.702 +C Add\sthe\sSQLITE_DBSTATUS_PROPORTIONAL_CACHE_USED\ssqlite3_db_status()\sparameter. +D 2016-07-06T10:12:02.240 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -327,8 +327,8 @@ F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240 F src/backup.c 6df65fdd569c901a418887a1a76f82ec35044556 F src/bitvec.c 3ee4c8b2c94ed3a7377256e18199e6ff5cf33f63 F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 -F src/btree.c 0621247619df15790f7ed5f14926cfb3925c10b1 -F src/btree.h 2107a2630e02c8cba58bb12ce14e731e734ea29c +F src/btree.c dc4e5f3e95fd57b610422e36e0913662ecd6814c +F src/btree.h aee84823bb383d6ae3728b068f9130d2b36b71eb F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 F src/build.c d1fdfd7ab8f5447e494ef15825973bf0719527c6 F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 @@ -385,12 +385,12 @@ F src/resolve.c cca3aa77b95706df5d635a2141a4d1de60ae6598 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c f3c6e9065fb34f6a23af27ec7f1f717ffbfc2ee4 F src/shell.c 14ff7f660530a52b117d110ba3390b7b2eb719b6 -F src/sqlite.h.in 5f8113dbec74c6c093ead9930afb8c9fbd9f643d +F src/sqlite.h.in 801a34f86508662fbfc8e014f03ccf0c8bef0b4c F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 98f72cbfe00169c39089115427d06ea05fe4b4a2 F src/sqliteInt.h 2ac73e9fdd138f4607139d9bd6a1e6dcd01837dc F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 -F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba +F src/status.c d92daea3bb48023da57931719f2a2784f5487c0b F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 F src/tclsqlite.c 25fbbbb97f76dbfd113153fb63f52d7ecfac5dd0 F src/test1.c 08faa045c45b1d3f62c28c93cae955f518317f68 @@ -419,7 +419,7 @@ F src/test_intarray.c 870124b95ec4c645d4eb84f15efb7133528fb1a5 F src/test_intarray.h 9dc57417fb65bc7835cc18548852cc08cc062202 F src/test_journal.c d3b83f2bcb7792c709e57abddc456a2b1818643a F src/test_loadext.c 337056bae59f80b9eb00ba82088b39d0f4fe6dfd -F src/test_malloc.c 94c18e88d6df6d471a0d04ddb809f833d1739950 +F src/test_malloc.c 20954ab49e09be3433c8d2fd7a8bd0a0f1c76de7 F src/test_multiplex.c eafc567ebe162e36f17b5062285dfe90461cf8e9 F src/test_multiplex.h c08e4e8f8651f0c5e0509b138ff4d5b43ed1f5d3 F src/test_mutex.c dbdfaff8580071f2212a0deae3325a93a737819c @@ -621,7 +621,7 @@ F test/ctime.test 0b995accd44a52914bd4744d5c1b6e1a56c7897c F test/cursorhint.test 7bc346788390475e77a345da2b92270d04d35856 F test/cursorhint2.test 2b45341d32d1aae9991a00ef31ebca339b274255 F test/date.test 984ac1e3e5e031386866f034006148d3972b4a65 -F test/dbstatus.test 8de104bb5606f19537d23cd553b41349b5ab1204 +F test/dbstatus.test c0c8752043074ab6479d2560341ae02f072ad3b9 F test/dbstatus2.test e93ab03bfae6d62d4d935f20de928c19ca0ed0ab F test/default.test 0cb49b1c315a0d81c81d775e407f66906a2a604d F test/delete.test e1bcdf8926234e27aac24b346ad83d3329ec8b6f @@ -1504,7 +1504,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 2683b375ad1291172fdb47d94e16fcf869c78c8a -R bad3fed306e6177658099344318135b4 +P 724e4cdc25fc80b8face57b3398cd338994fb23c +R 266d0a5d75bc1363b05e057e04a42c8c +T *branch * dbstatus-prop-cache-used +T *sym-dbstatus-prop-cache-used * +T -sym-trunk * U dan -Z b779329b8bc265169140036a21a84f9f +Z d4bd876af7d67d4b270c7d6acc73f5f1 diff --git a/manifest.uuid b/manifest.uuid index 457a7b2b76..412e8ccbff 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -724e4cdc25fc80b8face57b3398cd338994fb23c \ No newline at end of file +118321c8b9d88b8f439c952436f42838c3fc80cb \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index f37199276f..7fc9193dc8 100644 --- a/src/btree.c +++ b/src/btree.c @@ -2337,9 +2337,9 @@ int sqlite3BtreeOpen( #if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO) /* Add the new BtShared object to the linked list sharable BtShareds. */ + pBt->nRef = 1; if( p->sharable ){ MUTEX_LOGIC( sqlite3_mutex *mutexShared; ) - pBt->nRef = 1; MUTEX_LOGIC( mutexShared = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);) if( SQLITE_THREADSAFE && sqlite3GlobalConfig.bCoreMutex ){ pBt->mutex = sqlite3MutexAlloc(SQLITE_MUTEX_FAST); @@ -2410,6 +2410,7 @@ btree_open_out: assert( sqlite3_mutex_held(mutexOpen) ); sqlite3_mutex_leave(mutexOpen); } + assert( rc!=SQLITE_OK || sqlite3BtreeConnectionCount(*ppBtree)>0 ); return rc; } @@ -9698,4 +9699,14 @@ int sqlite3HeaderSizeBtree(void){ return ROUND8(sizeof(MemPage)); } int sqlite3BtreeSharable(Btree *p){ return p->sharable; } + +/* +** Return the number of connections to the BtShared object accessed by +** the Btree handle passed as the only argument. For private caches +** this is always 1. For shared caches it may be 1 or greater. +*/ +int sqlite3BtreeConnectionCount(Btree *p){ + testcase( p->sharable ); + return p->pBt->nRef; +} #endif diff --git a/src/btree.h b/src/btree.h index 5720df90f7..c8b293ef17 100644 --- a/src/btree.h +++ b/src/btree.h @@ -328,11 +328,13 @@ void sqlite3BtreeCursorList(Btree*); void sqlite3BtreeEnterAll(sqlite3*); int sqlite3BtreeSharable(Btree*); void sqlite3BtreeEnterCursor(BtCursor*); + int sqlite3BtreeConnectionCount(Btree*); #else # define sqlite3BtreeEnter(X) # define sqlite3BtreeEnterAll(X) # define sqlite3BtreeSharable(X) 0 # define sqlite3BtreeEnterCursor(X) +# define sqlite3BtreeConnectionCount(X) 1 #endif #if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 4865f18132..e1d16008f9 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -6765,6 +6765,18 @@ int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg); ** memory used by all pager caches associated with the database connection.)^ ** ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_USED is always 0. ** +** [[SQLITE_DBSTATUS_PROPORTIONAL_CACHE_USED]] +** ^(
    SQLITE_DBSTATUS_PROPORTIONAL_CACHE_USED
    +**
    This parameter is similar to DBSTATUS_CACHE_USED, except that if a +** pager cache is shared between two or more connections the bytes of heap +** memory used by that pager cache is divided evenly between the attached +** connections.)^ In other words, if none of the pager caches associated +** with the database connection are shared, this request returns the same +** value as DBSTATUS_CACHE_USED. Or, if one or more or the pager caches are +** shared, the value returned by this call will be smaller than that returned +** by DBSTATUS_CACHE_USED. ^The highwater mark associated with +** SQLITE_DBSTATUS_PROPORTIONAL_CACHE_USED is always 0. +** ** [[SQLITE_DBSTATUS_SCHEMA_USED]] ^(
    SQLITE_DBSTATUS_SCHEMA_USED
    **
    This parameter returns the approximate number of bytes of heap ** memory used to store the schema for all databases associated @@ -6822,7 +6834,8 @@ int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg); #define SQLITE_DBSTATUS_CACHE_MISS 8 #define SQLITE_DBSTATUS_CACHE_WRITE 9 #define SQLITE_DBSTATUS_DEFERRED_FKS 10 -#define SQLITE_DBSTATUS_MAX 10 /* Largest defined DBSTATUS */ +#define SQLITE_DBSTATUS_PROPORTIONAL_CACHE_USED 11 +#define SQLITE_DBSTATUS_MAX 11 /* Largest defined DBSTATUS */ /* diff --git a/src/status.c b/src/status.c index 69f92ff7c6..bf336dfb46 100644 --- a/src/status.c +++ b/src/status.c @@ -219,6 +219,7 @@ int sqlite3_db_status( ** by all pagers associated with the given database connection. The ** highwater mark is meaningless and is returned as zero. */ + case SQLITE_DBSTATUS_PROPORTIONAL_CACHE_USED: case SQLITE_DBSTATUS_CACHE_USED: { int totalUsed = 0; int i; @@ -227,7 +228,11 @@ int sqlite3_db_status( Btree *pBt = db->aDb[i].pBt; if( pBt ){ Pager *pPager = sqlite3BtreePager(pBt); - totalUsed += sqlite3PagerMemUsed(pPager); + int nByte = sqlite3PagerMemUsed(pPager); + if( op==SQLITE_DBSTATUS_PROPORTIONAL_CACHE_USED ){ + nByte = nByte / sqlite3BtreeConnectionCount(pBt); + } + totalUsed += nByte; } } sqlite3BtreeLeaveAll(db); diff --git a/src/test_malloc.c b/src/test_malloc.c index e6be663998..db34924e6b 100644 --- a/src/test_malloc.c +++ b/src/test_malloc.c @@ -1417,7 +1417,8 @@ static int test_db_status( { "CACHE_HIT", SQLITE_DBSTATUS_CACHE_HIT }, { "CACHE_MISS", SQLITE_DBSTATUS_CACHE_MISS }, { "CACHE_WRITE", SQLITE_DBSTATUS_CACHE_WRITE }, - { "DEFERRED_FKS", SQLITE_DBSTATUS_DEFERRED_FKS } + { "DEFERRED_FKS", SQLITE_DBSTATUS_DEFERRED_FKS }, + { "PROPORTIONAL_CACHE_USED", SQLITE_DBSTATUS_PROPORTIONAL_CACHE_USED }, }; Tcl_Obj *pResult; if( objc!=4 ){ diff --git a/test/dbstatus.test b/test/dbstatus.test index 368c6b28e5..fb839b8f13 100644 --- a/test/dbstatus.test +++ b/test/dbstatus.test @@ -14,6 +14,7 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl +set testprefix dbstatus ifcapable !compound { finish_test @@ -24,6 +25,7 @@ ifcapable !compound { db close sqlite3_shutdown sqlite3_config_memstatus 1 +sqlite3_config_uri 1 sqlite3_initialize sqlite3 db test.db @@ -377,4 +379,39 @@ foreach ::lookaside_buffer_size {0 64 120} { } } +#------------------------------------------------------------------------- +# The following tests focus on DBSTATUS_PROPORTIONAL_CACHE_USED +# +ifcapable shared_cache { + proc do_cacheused_test {tn db res} { + set cu [sqlite3_db_status $db SQLITE_DBSTATUS_CACHE_USED 0] + set pcu [sqlite3_db_status $db SQLITE_DBSTATUS_PROPORTIONAL_CACHE_USED 0] + set cu [lindex $cu 1] + set pcu [lindex $pcu 1] + uplevel [list do_test $tn [list list $cu $pcu] [list {*}$res]] + } + reset_db + sqlite3 db file:test.db?cache=shared + + do_execsql_test 4.0 { + CREATE TABLE t1(a, b, c); + INSERT INTO t1 VALUES(1, 2, 3); + } + do_cacheused_test 4.0.1 db { 4568 4568 } + do_execsql_test 4.1 { + CREATE TEMP TABLE tt(a, b, c); + INSERT INTO tt VALUES(1, 2, 3); + } + do_cacheused_test 4.1.1 db { 9000 9000 } + + sqlite3 db2 file:test.db?cache=shared + do_cacheused_test 4.2.1 db2 { 4568 2284 } + do_cacheused_test 4.2.2 db { 9000 6716 } + db close + do_cacheused_test 4.2.3 db2 { 4568 4568 } + sqlite3 db file:test.db?cache=shared + do_cacheused_test 4.2.4 db2 { 4568 2284 } + db2 close +} + finish_test From dc7b7385c9603da2b753d81819555b8788ea2336 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 6 Jul 2016 10:17:43 +0000 Subject: [PATCH 0544/1484] Fix a test script problem causing a test to fail if the ICU extension is enabled. FossilOrigin-Name: 0c228f5d3db1be598ebf5d9170428c19d18e01ad --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/bestindex3.test | 25 +++++++++++++++---------- 3 files changed, 22 insertions(+), 17 deletions(-) diff --git a/manifest b/manifest index 2ae741da57..72d4af2b39 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\smemory\sleak\sin\srecently\sadded\stest\scode. -D 2016-07-06T09:19:14.702 +C Fix\sa\stest\sscript\sproblem\scausing\sa\stest\sto\sfail\sif\sthe\sICU\sextension\sis\senabled. +D 2016-07-06T10:17:43.607 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -529,7 +529,7 @@ F test/badutf2.test f5bc7f2d280670ecd79b9cf4f0f1760c607fe51f F test/bc_common.tcl b5e42d80305be95697e6370e015af571e5333a1c F test/bestindex1.test 0cf1bd2d7b97d3a3a8c10736125274f64765c4ee F test/bestindex2.test 4a06b8922ab2fd09434870da8d1cdf525aaf7060 -F test/bestindex3.test b80da904d23581d233a7ceee7d6bbad2b23a8133 +F test/bestindex3.test dd5fa4f483cd0356549203c4522f8c9e21cb1fc0 F test/between.test 34d375fb5ce1ae283ffe82b6b233e9f38e84fc6c F test/bigfile.test aa74f4e5db51c8e54a1d9de9fa65d01d1eb20b59 F test/bigfile2.test 1b489a3a39ae90c7f027b79110d6b4e1dbc71bfc @@ -1504,7 +1504,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 2683b375ad1291172fdb47d94e16fcf869c78c8a -R bad3fed306e6177658099344318135b4 +P 724e4cdc25fc80b8face57b3398cd338994fb23c +R c62c8dbad784e0483dfc9fa19c59eefb U dan -Z b779329b8bc265169140036a21a84f9f +Z a917ae810e6e02aa96317b48ea0e74c6 diff --git a/manifest.uuid b/manifest.uuid index 457a7b2b76..37cc004d35 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -724e4cdc25fc80b8face57b3398cd338994fb23c \ No newline at end of file +0c228f5d3db1be598ebf5d9170428c19d18e01ad \ No newline at end of file diff --git a/test/bestindex3.test b/test/bestindex3.test index bb6d5cefd1..8baf854254 100644 --- a/test/bestindex3.test +++ b/test/bestindex3.test @@ -135,17 +135,22 @@ foreach omit {0 1} { #------------------------------------------------------------------------- # Test the same pattern works with ordinary tables. # -do_execsql_test 2.1 { - CREATE TABLE t2(x TEXT COLLATE nocase, y TEXT); - CREATE INDEX t2x ON t2(x COLLATE nocase); - CREATE INDEX t2y ON t2(y); -} +# This test does not work if the ICU extension is enabled. ICU overrides +# LIKE - and this optimization only works with the built-in LIKE function. +# +ifcapable !icu { + do_execsql_test 2.1 { + CREATE TABLE t2(x TEXT COLLATE nocase, y TEXT); + CREATE INDEX t2x ON t2(x COLLATE nocase); + CREATE INDEX t2y ON t2(y); + } -do_eqp_test 2.2 { - SELECT * FROM t2 WHERE x LIKE 'abc%' OR y = 'def' -} { - 0 0 0 {SEARCH TABLE t2 USING INDEX t2x (x>? AND x? AND x Date: Wed, 6 Jul 2016 18:12:54 +0000 Subject: [PATCH 0545/1484] Change the name of the SQLITE_DBSTATUS_PROPORTIONAL_CACHE_USED to SQLITE_DBSTATUS_CACHE_USED_SHARED. FossilOrigin-Name: d58401ab26c7c5417eb7d540f47d11c4e49edcb2 --- manifest | 21 +++++++++------------ manifest.uuid | 2 +- src/sqlite.h.in | 8 ++++---- src/status.c | 4 ++-- src/test_malloc.c | 2 +- test/dbstatus.test | 4 ++-- 6 files changed, 19 insertions(+), 22 deletions(-) diff --git a/manifest b/manifest index 662bd8b161..f138ba5137 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sSQLITE_DBSTATUS_PROPORTIONAL_CACHE_USED\ssqlite3_db_status()\sparameter. -D 2016-07-06T10:12:02.240 +C Change\sthe\sname\sof\sthe\sSQLITE_DBSTATUS_PROPORTIONAL_CACHE_USED\sto\sSQLITE_DBSTATUS_CACHE_USED_SHARED. +D 2016-07-06T18:12:54.292 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -385,12 +385,12 @@ F src/resolve.c cca3aa77b95706df5d635a2141a4d1de60ae6598 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c f3c6e9065fb34f6a23af27ec7f1f717ffbfc2ee4 F src/shell.c 14ff7f660530a52b117d110ba3390b7b2eb719b6 -F src/sqlite.h.in 801a34f86508662fbfc8e014f03ccf0c8bef0b4c +F src/sqlite.h.in 5e6785f6d2148b20ecd891039b12e9c7b8c552ca F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 98f72cbfe00169c39089115427d06ea05fe4b4a2 F src/sqliteInt.h 2ac73e9fdd138f4607139d9bd6a1e6dcd01837dc F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 -F src/status.c d92daea3bb48023da57931719f2a2784f5487c0b +F src/status.c 5b18f9526900f61189ab0b83f1ef41d9f871a2ab F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 F src/tclsqlite.c 25fbbbb97f76dbfd113153fb63f52d7ecfac5dd0 F src/test1.c 08faa045c45b1d3f62c28c93cae955f518317f68 @@ -419,7 +419,7 @@ F src/test_intarray.c 870124b95ec4c645d4eb84f15efb7133528fb1a5 F src/test_intarray.h 9dc57417fb65bc7835cc18548852cc08cc062202 F src/test_journal.c d3b83f2bcb7792c709e57abddc456a2b1818643a F src/test_loadext.c 337056bae59f80b9eb00ba82088b39d0f4fe6dfd -F src/test_malloc.c 20954ab49e09be3433c8d2fd7a8bd0a0f1c76de7 +F src/test_malloc.c 6b27e947eeeb70d11aa65406ed28d749e39b6356 F src/test_multiplex.c eafc567ebe162e36f17b5062285dfe90461cf8e9 F src/test_multiplex.h c08e4e8f8651f0c5e0509b138ff4d5b43ed1f5d3 F src/test_mutex.c dbdfaff8580071f2212a0deae3325a93a737819c @@ -621,7 +621,7 @@ F test/ctime.test 0b995accd44a52914bd4744d5c1b6e1a56c7897c F test/cursorhint.test 7bc346788390475e77a345da2b92270d04d35856 F test/cursorhint2.test 2b45341d32d1aae9991a00ef31ebca339b274255 F test/date.test 984ac1e3e5e031386866f034006148d3972b4a65 -F test/dbstatus.test c0c8752043074ab6479d2560341ae02f072ad3b9 +F test/dbstatus.test 254427f026b55ab6eba99bd8493f4edbc370bb13 F test/dbstatus2.test e93ab03bfae6d62d4d935f20de928c19ca0ed0ab F test/default.test 0cb49b1c315a0d81c81d775e407f66906a2a604d F test/delete.test e1bcdf8926234e27aac24b346ad83d3329ec8b6f @@ -1504,10 +1504,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 724e4cdc25fc80b8face57b3398cd338994fb23c -R 266d0a5d75bc1363b05e057e04a42c8c -T *branch * dbstatus-prop-cache-used -T *sym-dbstatus-prop-cache-used * -T -sym-trunk * +P 118321c8b9d88b8f439c952436f42838c3fc80cb +R 05426ca0e9c055af37d1a3ee4a44f5ae U dan -Z d4bd876af7d67d4b270c7d6acc73f5f1 +Z 090646989586e99cb3699b0e8d3a49b5 diff --git a/manifest.uuid b/manifest.uuid index 412e8ccbff..a57c8f34ac 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -118321c8b9d88b8f439c952436f42838c3fc80cb \ No newline at end of file +d58401ab26c7c5417eb7d540f47d11c4e49edcb2 \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index e1d16008f9..55f96dd898 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -6765,8 +6765,8 @@ int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg); ** memory used by all pager caches associated with the database connection.)^ ** ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_USED is always 0. ** -** [[SQLITE_DBSTATUS_PROPORTIONAL_CACHE_USED]] -** ^(
    SQLITE_DBSTATUS_PROPORTIONAL_CACHE_USED
    +** [[SQLITE_DBSTATUS_CACHE_USED_SHARED]] +** ^(
    SQLITE_DBSTATUS_CACHE_USED_SHARED
    **
    This parameter is similar to DBSTATUS_CACHE_USED, except that if a ** pager cache is shared between two or more connections the bytes of heap ** memory used by that pager cache is divided evenly between the attached @@ -6775,7 +6775,7 @@ int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg); ** value as DBSTATUS_CACHE_USED. Or, if one or more or the pager caches are ** shared, the value returned by this call will be smaller than that returned ** by DBSTATUS_CACHE_USED. ^The highwater mark associated with -** SQLITE_DBSTATUS_PROPORTIONAL_CACHE_USED is always 0. +** SQLITE_DBSTATUS_CACHE_USED_SHARED is always 0. ** ** [[SQLITE_DBSTATUS_SCHEMA_USED]] ^(
    SQLITE_DBSTATUS_SCHEMA_USED
    **
    This parameter returns the approximate number of bytes of heap @@ -6834,7 +6834,7 @@ int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg); #define SQLITE_DBSTATUS_CACHE_MISS 8 #define SQLITE_DBSTATUS_CACHE_WRITE 9 #define SQLITE_DBSTATUS_DEFERRED_FKS 10 -#define SQLITE_DBSTATUS_PROPORTIONAL_CACHE_USED 11 +#define SQLITE_DBSTATUS_CACHE_USED_SHARED 11 #define SQLITE_DBSTATUS_MAX 11 /* Largest defined DBSTATUS */ diff --git a/src/status.c b/src/status.c index bf336dfb46..949908ed23 100644 --- a/src/status.c +++ b/src/status.c @@ -219,7 +219,7 @@ int sqlite3_db_status( ** by all pagers associated with the given database connection. The ** highwater mark is meaningless and is returned as zero. */ - case SQLITE_DBSTATUS_PROPORTIONAL_CACHE_USED: + case SQLITE_DBSTATUS_CACHE_USED_SHARED: case SQLITE_DBSTATUS_CACHE_USED: { int totalUsed = 0; int i; @@ -229,7 +229,7 @@ int sqlite3_db_status( if( pBt ){ Pager *pPager = sqlite3BtreePager(pBt); int nByte = sqlite3PagerMemUsed(pPager); - if( op==SQLITE_DBSTATUS_PROPORTIONAL_CACHE_USED ){ + if( op==SQLITE_DBSTATUS_CACHE_USED_SHARED ){ nByte = nByte / sqlite3BtreeConnectionCount(pBt); } totalUsed += nByte; diff --git a/src/test_malloc.c b/src/test_malloc.c index db34924e6b..37612561eb 100644 --- a/src/test_malloc.c +++ b/src/test_malloc.c @@ -1418,7 +1418,7 @@ static int test_db_status( { "CACHE_MISS", SQLITE_DBSTATUS_CACHE_MISS }, { "CACHE_WRITE", SQLITE_DBSTATUS_CACHE_WRITE }, { "DEFERRED_FKS", SQLITE_DBSTATUS_DEFERRED_FKS }, - { "PROPORTIONAL_CACHE_USED", SQLITE_DBSTATUS_PROPORTIONAL_CACHE_USED }, + { "CACHE_USED_SHARED", SQLITE_DBSTATUS_CACHE_USED_SHARED }, }; Tcl_Obj *pResult; if( objc!=4 ){ diff --git a/test/dbstatus.test b/test/dbstatus.test index fb839b8f13..7bc44353b0 100644 --- a/test/dbstatus.test +++ b/test/dbstatus.test @@ -380,12 +380,12 @@ foreach ::lookaside_buffer_size {0 64 120} { } #------------------------------------------------------------------------- -# The following tests focus on DBSTATUS_PROPORTIONAL_CACHE_USED +# The following tests focus on DBSTATUS_CACHE_USED_SHARED # ifcapable shared_cache { proc do_cacheused_test {tn db res} { set cu [sqlite3_db_status $db SQLITE_DBSTATUS_CACHE_USED 0] - set pcu [sqlite3_db_status $db SQLITE_DBSTATUS_PROPORTIONAL_CACHE_USED 0] + set pcu [sqlite3_db_status $db SQLITE_DBSTATUS_CACHE_USED_SHARED 0] set cu [lindex $cu 1] set pcu [lindex $pcu 1] uplevel [list do_test $tn [list list $cu $pcu] [list {*}$res]] From 5225449e5bd7172ad1194d0bc92fa4d27ae5adbd Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 8 Jul 2016 02:14:24 +0000 Subject: [PATCH 0546/1484] In the sqldiff program, make sure the first argument to the db_prepare() utility function is always a valid format string. FossilOrigin-Name: 8bb8d886ffa948cd7bc66c8c62da76bce233be2e --- manifest | 15 +++++++-------- manifest.uuid | 2 +- tool/sqldiff.c | 6 +++--- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index eae430df41..9d64eac700 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sSQLITE_DBSTATUS_CACHE_USED_SHARED\ssqlite3_db_status()\sparameter.\sThis\soption\sis\ssimilar\sto\sDBSTATUS_CACHE_USED,\sexcept\sthat\sit\sdivides\smemory\sused\sby\sshared\scaches\sevenly\sbetween\sall\sconnections. -D 2016-07-06T18:42:34.265 +C In\sthe\ssqldiff\sprogram,\smake\ssure\sthe\sfirst\sargument\sto\sthe\sdb_prepare()\nutility\sfunction\sis\salways\sa\svalid\sformat\sstring. +D 2016-07-08T02:14:24.531 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -1471,7 +1471,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 7ce07da76b5e745783e703a834417d725b7d45fd F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c -F tool/sqldiff.c 131e9c6e09d3d78e3c4ae8b5fd23451521723aac +F tool/sqldiff.c af5d80cdc88a91a0f3cccfaa316b5a27b213568a F tool/srcck1.c 4c39bdfa9a92edd20233ee720df84dbeb2417602 F tool/stack_usage.tcl f8e71b92cdb099a147dad572375595eae55eca43 F tool/symbols-mingw.sh 4dbcea7e74768305384c9fd2ed2b41bbf9f0414d @@ -1504,8 +1504,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 0c228f5d3db1be598ebf5d9170428c19d18e01ad d58401ab26c7c5417eb7d540f47d11c4e49edcb2 -R b82357a7b430039c936434bd64729f72 -T +closed d58401ab26c7c5417eb7d540f47d11c4e49edcb2 -U dan -Z cd4dfb8a318d1cd48c9fef00f9959964 +P 06cf2680588c8dc4f0cbde275a09cfdcb5943268 +R 0ae6fb283ae848ac01b5c1982f5ece36 +U drh +Z fc8cced580b536f398169074b70b6b16 diff --git a/manifest.uuid b/manifest.uuid index 445104cad7..cad934d3a4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -06cf2680588c8dc4f0cbde275a09cfdcb5943268 \ No newline at end of file +8bb8d886ffa948cd7bc66c8c62da76bce233be2e \ No newline at end of file diff --git a/tool/sqldiff.c b/tool/sqldiff.c index 4a5389c603..dbdf726df0 100644 --- a/tool/sqldiff.c +++ b/tool/sqldiff.c @@ -684,7 +684,7 @@ static void diff_one_table(const char *zTab, FILE *out){ /* Run the query and output differences */ if( !g.bSchemaOnly ){ - pStmt = db_prepare(sql.z); + pStmt = db_prepare("%s", sql.z); while( SQLITE_ROW==sqlite3_step(pStmt) ){ int iType = sqlite3_column_int(pStmt, nPk); if( iType==1 || iType==2 ){ @@ -1461,7 +1461,7 @@ static void summarize_one_table(const char *zTab, FILE *out){ } /* Run the query and output difference summary */ - pStmt = db_prepare(sql.z); + pStmt = db_prepare("%s", sql.z); nUpdate = 0; nInsert = 0; nDelete = 0; @@ -2018,7 +2018,7 @@ int main(int argc, char **argv){ xDiff(zTab, out); }else{ /* Handle tables one by one */ - pStmt = db_prepare( all_tables_sql() ); + pStmt = db_prepare("%s", all_tables_sql() ); while( SQLITE_ROW==sqlite3_step(pStmt) ){ xDiff((const char*)sqlite3_column_text(pStmt,0), out); } From d3d4b3c698cbe74662a6e6fbac92e8090068fe18 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 8 Jul 2016 19:54:38 +0000 Subject: [PATCH 0547/1484] Another attempt to fix error handling in Lemon. This change is a no-op for SQLite's usage. FossilOrigin-Name: e1d8ef311cabcb96495a88404991b1416655e4a8 --- manifest | 12 ++++++------ manifest.uuid | 2 +- tool/lempar.c | 3 +++ 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 9d64eac700..0defcbf521 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\sthe\ssqldiff\sprogram,\smake\ssure\sthe\sfirst\sargument\sto\sthe\sdb_prepare()\nutility\sfunction\sis\salways\sa\svalid\sformat\sstring. -D 2016-07-08T02:14:24.531 +C Another\sattempt\sto\sfix\serror\shandling\sin\sLemon.\s\sThis\schange\sis\sa\sno-op\sfor\nSQLite's\susage. +D 2016-07-08T19:54:38.723 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -1432,7 +1432,7 @@ F tool/genfkey.README cf68fddd4643bbe3ff8e31b8b6d8b0a1b85e20f4 F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5 F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce F tool/lemon.c 09a96bed19955697a5e20c49ad863ec2005815a2 -F tool/lempar.c 072ff9985f36796b95bdc895820f2d77255a7067 +F tool/lempar.c 77c685a612526aae9c0d9b3175176e5bcd3854d0 F tool/libvers.c caafc3b689638a1d88d44bc5f526c2278760d9b9 F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862 F tool/logest.c 11346aa019e2e77a00902aa7d0cabd27bd2e8cca @@ -1504,7 +1504,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 06cf2680588c8dc4f0cbde275a09cfdcb5943268 -R 0ae6fb283ae848ac01b5c1982f5ece36 +P 8bb8d886ffa948cd7bc66c8c62da76bce233be2e +R 855944636ee976f5addadf9e5d764c10 U drh -Z fc8cced580b536f398169074b70b6b16 +Z 1b9ee21867274cd5ef77d7b4ebcc2052 diff --git a/manifest.uuid b/manifest.uuid index cad934d3a4..f05a5cef3c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8bb8d886ffa948cd7bc66c8c62da76bce233be2e \ No newline at end of file +e1d8ef311cabcb96495a88404991b1416655e4a8 \ No newline at end of file diff --git a/tool/lempar.c b/tool/lempar.c index d7236efa89..5232565f87 100644 --- a/tool/lempar.c +++ b/tool/lempar.c @@ -921,6 +921,9 @@ void Parse( yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion); if( yyendofinput ){ yy_parse_failed(yypParser); +#ifndef YYNOERRORRECOVERY + yypParser->yyerrcnt = -1; +#endif } yymajor = YYNOCODE; #endif From 1e75483cf06e7012b5a814b8e7eb1b2ca644937a Mon Sep 17 00:00:00 2001 From: mistachkin Date: Fri, 8 Jul 2016 21:14:37 +0000 Subject: [PATCH 0548/1484] Initial work on a Win32 VFS with NOP locking. FossilOrigin-Name: 549abe3f89b55b05a05f267865a5dd84b8cd335d --- manifest | 18 +-- manifest.uuid | 2 +- src/os_win.c | 260 +++++++++++++++++++++++++++++++++--------- test/win32nolock.test | 126 ++++++++++++++++++++ 4 files changed, 345 insertions(+), 61 deletions(-) create mode 100644 test/win32nolock.test diff --git a/manifest b/manifest index 0defcbf521..d1bae33bb1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Another\sattempt\sto\sfix\serror\shandling\sin\sLemon.\s\sThis\schange\sis\sa\sno-op\sfor\nSQLite's\susage. -D 2016-07-08T19:54:38.723 +C Initial\swork\son\sa\sWin32\sVFS\swith\sNOP\slocking. +D 2016-07-08T21:14:37.641 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -368,7 +368,7 @@ F src/os.h 8e976e59eb4ca1c0fca6d35ee803e38951cb0343 F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85 F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa F src/os_unix.c a9443cdab41d7f3cdf0df3a5aab62fd6e1c9b234 -F src/os_win.c d4b8faf8896b65818e67070711fdd00d8e620bd6 +F src/os_win.c 716af57117381c24c0eb43c8dc5a86a6496f98a7 F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c c368634b888b1c8740aea83b36bfd266f2443e60 F src/pager.h 8ab6b6feeee4bc0439bfde7ee59ba99df98b9bc3 @@ -1402,6 +1402,7 @@ F test/wild001.test bca33f499866f04c24510d74baf1e578d4e44b1c F test/win32heap.test ea19770974795cff26e11575e12d422dbd16893c F test/win32lock.test fbf107c91d8f5512be5a5b87c4c42ab9fdd54972 F test/win32longpath.test 169c75a3b2e43481f4a62122510210c67b08f26d +F test/win32nolock.test ac4f08811a562e45a5755e661f45ca85892bdbbc F test/with1.test cef099a491eac9874f2c28bd2dc86394fb3e47b3 F test/with2.test 2b40da883658eb74ad8ad06afabe11a408e7fb87 F test/with3.test 511bacdbe41c49cf34f9fd1bd3245fe1575bca98 @@ -1504,7 +1505,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 8bb8d886ffa948cd7bc66c8c62da76bce233be2e -R 855944636ee976f5addadf9e5d764c10 -U drh -Z 1b9ee21867274cd5ef77d7b4ebcc2052 +P e1d8ef311cabcb96495a88404991b1416655e4a8 +R ba3e2959766a1594f290917f0109fdb1 +T *branch * win32nolock +T *sym-win32nolock * +T -sym-trunk * +U mistachkin +Z 21c6555b60ed7b3a758f8d504d1fa54f diff --git a/manifest.uuid b/manifest.uuid index f05a5cef3c..47a6068e6c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e1d8ef311cabcb96495a88404991b1416655e4a8 \ No newline at end of file +549abe3f89b55b05a05f267865a5dd84b8cd335d \ No newline at end of file diff --git a/src/os_win.c b/src/os_win.c index edc182a017..1c861b0fbd 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -290,6 +290,17 @@ struct winFile { #endif }; +/* +** The winVfsAppData structure is used for the pAppData member for all of the +** Win32 VFS variants. +*/ +typedef struct winVfsAppData winVfsAppData; +struct winVfsAppData { + const sqlite3_io_methods *pMethod; /* The file I/O methods to use. */ + void *pAppData; /* The extra pAppData, if any. */ + BOOL bNoLock; /* Non-zero if locking is disabled. */ +}; + /* ** Allowed values for winFile.ctrlFlags */ @@ -2611,7 +2622,12 @@ static int winClose(sqlite3_file *id){ }while( rc==0 && ++cnt < MX_CLOSE_ATTEMPT && (sqlite3_win32_sleep(100), 1) ); #if SQLITE_OS_WINCE #define WINCE_DELETION_ATTEMPTS 3 - winceDestroyLock(pFile); + { + winVfsAppData *pAppData = (winVfsAppData*)pFile->pVfs->pAppData; + if( pAppData==NULL || !pAppData->bNoLock ){ + winceDestroyLock(pFile); + } + } if( pFile->zDeleteOnClose ){ int cnt = 0; while( @@ -3343,6 +3359,44 @@ static int winUnlock(sqlite3_file *id, int locktype){ return rc; } +/****************************************************************************** +****************************** No-op Locking ********************************** +** +** Of the various locking implementations available, this is by far the +** simplest: locking is ignored. No attempt is made to lock the database +** file for reading or writing. +** +** This locking mode is appropriate for use on read-only databases +** (ex: databases that are burned into CD-ROM, for example.) It can +** also be used if the application employs some external mechanism to +** prevent simultaneous access of the same database by two or more +** database connections. But there is a serious risk of database +** corruption if this locking mode is used in situations where multiple +** database connections are accessing the same database file at the same +** time and one or more of those connections are writing. +*/ + +static int winNolockLock(sqlite3_file *id, int locktype){ + UNUSED_PARAMETER(id); + UNUSED_PARAMETER(locktype); + return SQLITE_OK; +} + +static int winNolockCheckReservedLock(sqlite3_file *id, int *pResOut){ + UNUSED_PARAMETER(id); + UNUSED_PARAMETER(pResOut); + return SQLITE_OK; +} + +static int winNolockUnlock(sqlite3_file *id, int locktype){ + UNUSED_PARAMETER(id); + UNUSED_PARAMETER(locktype); + return SQLITE_OK; +} + +/******************* End of the no-op lock implementation ********************* +******************************************************************************/ + /* ** If *pArg is initially negative then this is a query. Set *pArg to ** 1 or 0 depending on whether or not bit mask of pFile->ctrlFlags is set. @@ -4407,6 +4461,44 @@ static const sqlite3_io_methods winIoMethod = { winUnfetch /* xUnfetch */ }; +/* +** This vector defines all the methods that can operate on an +** sqlite3_file for win32 without performing any locking. +*/ +static const sqlite3_io_methods winIoNolockMethod = { + 3, /* iVersion */ + winClose, /* xClose */ + winRead, /* xRead */ + winWrite, /* xWrite */ + winTruncate, /* xTruncate */ + winSync, /* xSync */ + winFileSize, /* xFileSize */ + winNolockLock, /* xLock */ + winNolockUnlock, /* xUnlock */ + winNolockCheckReservedLock, /* xCheckReservedLock */ + winFileControl, /* xFileControl */ + winSectorSize, /* xSectorSize */ + winDeviceCharacteristics, /* xDeviceCharacteristics */ + winShmMap, /* xShmMap */ + winShmLock, /* xShmLock */ + winShmBarrier, /* xShmBarrier */ + winShmUnmap, /* xShmUnmap */ + winFetch, /* xFetch */ + winUnfetch /* xUnfetch */ +}; + +static winVfsAppData winAppData = { + &winIoMethod, /* pMethod */ + 0, /* pAppData */ + 0 /* bNoLock */ +}; + +static winVfsAppData winNolockAppData = { + &winIoNolockMethod, /* pMethod */ + 0, /* pAppData */ + 1 /* bNoLock */ +}; + /**************************************************************************** **************************** sqlite3_vfs methods **************************** ** @@ -4739,7 +4831,7 @@ static int winIsDir(const void *zConverted){ ** Open a file. */ static int winOpen( - sqlite3_vfs *pVfs, /* Used to get maximum path name length */ + sqlite3_vfs *pVfs, /* Used to get maximum path length and AppData */ const char *zName, /* Name of the file (UTF-8) */ sqlite3_file *id, /* Write the SQLite file handle here */ int flags, /* Open mode flags */ @@ -4754,6 +4846,7 @@ static int winOpen( #if SQLITE_OS_WINCE int isTemp = 0; #endif + winVfsAppData *pAppData; winFile *pFile = (winFile*)id; void *zConverted; /* Filename in OS encoding */ const char *zUtf8Name = zName; /* Filename in UTF-8 encoding */ @@ -4975,15 +5068,20 @@ static int winOpen( "rc=%s\n", h, zUtf8Name, dwDesiredAccess, pOutFlags, pOutFlags ? *pOutFlags : 0, (h==INVALID_HANDLE_VALUE) ? "failed" : "ok")); + pAppData = (winVfsAppData*)pVfs->pAppData; + #if SQLITE_OS_WINCE - if( isReadWrite && eType==SQLITE_OPEN_MAIN_DB - && (rc = winceCreateLock(zName, pFile))!=SQLITE_OK - ){ - osCloseHandle(h); - sqlite3_free(zConverted); - sqlite3_free(zTmpname); - OSTRACE(("OPEN-CE-LOCK name=%s, rc=%s\n", zName, sqlite3ErrName(rc))); - return rc; + { + if( isReadWrite && eType==SQLITE_OPEN_MAIN_DB + && ((pAppData==NULL) || !pAppData->bNoLock) + && (rc = winceCreateLock(zName, pFile))!=SQLITE_OK + ){ + osCloseHandle(h); + sqlite3_free(zConverted); + sqlite3_free(zTmpname); + OSTRACE(("OPEN-CE-LOCK name=%s, rc=%s\n", zName, sqlite3ErrName(rc))); + return rc; + } } if( isTemp ){ pFile->zDeleteOnClose = zConverted; @@ -4994,7 +5092,7 @@ static int winOpen( } sqlite3_free(zTmpname); - pFile->pMethod = &winIoMethod; + pFile->pMethod = pAppData ? pAppData->pMethod : &winIoMethod; pFile->pVfs = pVfs; pFile->h = h; if( isReadonly ){ @@ -5717,53 +5815,103 @@ static int winGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ */ int sqlite3_os_init(void){ static sqlite3_vfs winVfs = { - 3, /* iVersion */ - sizeof(winFile), /* szOsFile */ + 3, /* iVersion */ + sizeof(winFile), /* szOsFile */ SQLITE_WIN32_MAX_PATH_BYTES, /* mxPathname */ - 0, /* pNext */ - "win32", /* zName */ - 0, /* pAppData */ - winOpen, /* xOpen */ - winDelete, /* xDelete */ - winAccess, /* xAccess */ - winFullPathname, /* xFullPathname */ - winDlOpen, /* xDlOpen */ - winDlError, /* xDlError */ - winDlSym, /* xDlSym */ - winDlClose, /* xDlClose */ - winRandomness, /* xRandomness */ - winSleep, /* xSleep */ - winCurrentTime, /* xCurrentTime */ - winGetLastError, /* xGetLastError */ - winCurrentTimeInt64, /* xCurrentTimeInt64 */ - winSetSystemCall, /* xSetSystemCall */ - winGetSystemCall, /* xGetSystemCall */ - winNextSystemCall, /* xNextSystemCall */ + 0, /* pNext */ + "win32", /* zName */ + &winAppData, /* pAppData */ + winOpen, /* xOpen */ + winDelete, /* xDelete */ + winAccess, /* xAccess */ + winFullPathname, /* xFullPathname */ + winDlOpen, /* xDlOpen */ + winDlError, /* xDlError */ + winDlSym, /* xDlSym */ + winDlClose, /* xDlClose */ + winRandomness, /* xRandomness */ + winSleep, /* xSleep */ + winCurrentTime, /* xCurrentTime */ + winGetLastError, /* xGetLastError */ + winCurrentTimeInt64, /* xCurrentTimeInt64 */ + winSetSystemCall, /* xSetSystemCall */ + winGetSystemCall, /* xGetSystemCall */ + winNextSystemCall, /* xNextSystemCall */ }; #if defined(SQLITE_WIN32_HAS_WIDE) static sqlite3_vfs winLongPathVfs = { - 3, /* iVersion */ - sizeof(winFile), /* szOsFile */ + 3, /* iVersion */ + sizeof(winFile), /* szOsFile */ SQLITE_WINNT_MAX_PATH_BYTES, /* mxPathname */ - 0, /* pNext */ - "win32-longpath", /* zName */ - 0, /* pAppData */ - winOpen, /* xOpen */ - winDelete, /* xDelete */ - winAccess, /* xAccess */ - winFullPathname, /* xFullPathname */ - winDlOpen, /* xDlOpen */ - winDlError, /* xDlError */ - winDlSym, /* xDlSym */ - winDlClose, /* xDlClose */ - winRandomness, /* xRandomness */ - winSleep, /* xSleep */ - winCurrentTime, /* xCurrentTime */ - winGetLastError, /* xGetLastError */ - winCurrentTimeInt64, /* xCurrentTimeInt64 */ - winSetSystemCall, /* xSetSystemCall */ - winGetSystemCall, /* xGetSystemCall */ - winNextSystemCall, /* xNextSystemCall */ + 0, /* pNext */ + "win32-longpath", /* zName */ + &winAppData, /* pAppData */ + winOpen, /* xOpen */ + winDelete, /* xDelete */ + winAccess, /* xAccess */ + winFullPathname, /* xFullPathname */ + winDlOpen, /* xDlOpen */ + winDlError, /* xDlError */ + winDlSym, /* xDlSym */ + winDlClose, /* xDlClose */ + winRandomness, /* xRandomness */ + winSleep, /* xSleep */ + winCurrentTime, /* xCurrentTime */ + winGetLastError, /* xGetLastError */ + winCurrentTimeInt64, /* xCurrentTimeInt64 */ + winSetSystemCall, /* xSetSystemCall */ + winGetSystemCall, /* xGetSystemCall */ + winNextSystemCall, /* xNextSystemCall */ + }; +#endif + static sqlite3_vfs winNolockVfs = { + 3, /* iVersion */ + sizeof(winFile), /* szOsFile */ + SQLITE_WIN32_MAX_PATH_BYTES, /* mxPathname */ + 0, /* pNext */ + "win32-none", /* zName */ + &winNolockAppData, /* pAppData */ + winOpen, /* xOpen */ + winDelete, /* xDelete */ + winAccess, /* xAccess */ + winFullPathname, /* xFullPathname */ + winDlOpen, /* xDlOpen */ + winDlError, /* xDlError */ + winDlSym, /* xDlSym */ + winDlClose, /* xDlClose */ + winRandomness, /* xRandomness */ + winSleep, /* xSleep */ + winCurrentTime, /* xCurrentTime */ + winGetLastError, /* xGetLastError */ + winCurrentTimeInt64, /* xCurrentTimeInt64 */ + winSetSystemCall, /* xSetSystemCall */ + winGetSystemCall, /* xGetSystemCall */ + winNextSystemCall, /* xNextSystemCall */ + }; +#if defined(SQLITE_WIN32_HAS_WIDE) + static sqlite3_vfs winLongPathNolockVfs = { + 3, /* iVersion */ + sizeof(winFile), /* szOsFile */ + SQLITE_WINNT_MAX_PATH_BYTES, /* mxPathname */ + 0, /* pNext */ + "win32-longpath-none", /* zName */ + &winNolockAppData, /* pAppData */ + winOpen, /* xOpen */ + winDelete, /* xDelete */ + winAccess, /* xAccess */ + winFullPathname, /* xFullPathname */ + winDlOpen, /* xDlOpen */ + winDlError, /* xDlError */ + winDlSym, /* xDlSym */ + winDlClose, /* xDlClose */ + winRandomness, /* xRandomness */ + winSleep, /* xSleep */ + winCurrentTime, /* xCurrentTime */ + winGetLastError, /* xGetLastError */ + winCurrentTimeInt64, /* xCurrentTimeInt64 */ + winSetSystemCall, /* xSetSystemCall */ + winGetSystemCall, /* xGetSystemCall */ + winNextSystemCall, /* xNextSystemCall */ }; #endif @@ -5787,6 +5935,12 @@ int sqlite3_os_init(void){ sqlite3_vfs_register(&winLongPathVfs, 0); #endif + sqlite3_vfs_register(&winNolockVfs, 0); + +#if defined(SQLITE_WIN32_HAS_WIDE) + sqlite3_vfs_register(&winLongPathNolockVfs, 0); +#endif + return SQLITE_OK; } diff --git a/test/win32nolock.test b/test/win32nolock.test new file mode 100644 index 0000000000..8128860392 --- /dev/null +++ b/test/win32nolock.test @@ -0,0 +1,126 @@ +# 2016 July 8 +# +# 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 regression tests for SQLite library. +# + +if {$tcl_platform(platform)!="windows"} return + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix win32nolock + +do_test win32nolock-1.0 { + sqlite3 db test.db + execsql { + CREATE TABLE t1(a, b); + BEGIN; + INSERT INTO t1 VALUES(1, 2); + } +} {} + +do_test win32nolock-1.1 { + execsql COMMIT + catchsql { SELECT * FROM t1 } +} {0 {1 2}} + +db close + +do_test win32nolock-1.2 { + sqlite3 db test.db -vfs win32-none + sqlite3 db2 test.db -vfs win32-none + execsql { PRAGMA mmap_size = 0 } db2 + execsql { + BEGIN; + INSERT INTO t1 VALUES(3, 4); + } +} {} + +do_test win32nolock-1.3 { + execsql { SELECT * FROM t1 } +} {1 2 3 4} + +do_test win32nolock-1.4 { + execsql { SELECT * FROM t1; } db2 +} {1 2} + +do_test win32nolock-1.5 { + execsql { + BEGIN; + SELECT * FROM t1; + } db2 +} {1 2} + +do_test win32nolock-1.6 { + execsql COMMIT + execsql {SELECT * FROM t1} db2 +} {1 2} + +ifcapable memorymanage { + do_test win32nolock-1.7 { + sqlite3_release_memory 1000000 + execsql {SELECT * FROM t1} db2 + } {1 2 3 4} +} + +do_test win32nolock-1.8 { + db close + db2 close +} {} + +do_test win32nolock-1.9.1 { + sqlite3 db test.db + sqlite3 db2 test.db + list [catchsql { BEGIN EXCLUSIVE; } db] \ + [catchsql { BEGIN EXCLUSIVE; } db2] +} {{0 {}} {1 {database is locked}}} + +do_test win32nolock-1.9.2 { + db close + db2 close +} {} + +do_test win32nolock-1.10.1 { + sqlite3 db test.db -vfs win32-none + sqlite3 db2 test.db + list [catchsql { BEGIN EXCLUSIVE; } db] \ + [catchsql { BEGIN EXCLUSIVE; } db2] +} {{0 {}} {0 {}}} + +do_test win32nolock-1.10.2 { + db close + db2 close +} {} + +do_test win32nolock-1.11.1 { + sqlite3 db test.db + sqlite3 db2 test.db -vfs win32-none + list [catchsql { BEGIN EXCLUSIVE; } db] \ + [catchsql { BEGIN EXCLUSIVE; } db2] +} {{0 {}} {0 {}}} + +do_test win32nolock-1.11.2 { + db close + db2 close +} {} + +do_test win32nolock-1.12.1 { + sqlite3 db test.db -vfs win32-none + sqlite3 db2 test.db -vfs win32-none + list [catchsql { BEGIN EXCLUSIVE; } db] \ + [catchsql { BEGIN EXCLUSIVE; } db2] +} {{0 {}} {0 {}}} + +do_test win32nolock-1.12.2 { + db close + db2 close +} {} + +finish_test From 43f58d6a17e2875e59b72e126c9393f50fe63e79 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 9 Jul 2016 16:14:45 +0000 Subject: [PATCH 0549/1484] Fix various internal #defines to conform to new C-language naming restrictions, specifically that private-use macros names must not begin with "_". FossilOrigin-Name: 5471aca0158851d3fb0a2517306917536deb38bb --- manifest | 44 ++++++++++++++++++++++---------------------- manifest.uuid | 2 +- src/btree.h | 6 +++--- src/hash.h | 6 +++--- src/hwtime.h | 6 +++--- src/msvc.h | 6 +++--- src/os.c | 2 -- src/os_setup.h | 6 +++--- src/os_win.c | 28 ++++++++++++++-------------- src/os_win.h | 6 +++--- src/pager.h | 6 +++--- src/sqlite.h.in | 6 +++--- src/sqlite3ext.h | 6 +++--- src/sqliteInt.h | 6 +++--- src/test_intarray.h | 6 +++--- src/test_multiplex.h | 6 +++--- src/vdbe.h | 6 +++--- src/vdbeInt.h | 6 +++--- src/wal.h | 6 +++--- 19 files changed, 82 insertions(+), 84 deletions(-) diff --git a/manifest b/manifest index 964bfb8a38..eef481b87d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\ssupport\sfor\sthe\swin32-none\sVFS. -D 2016-07-09T00:06:21.171 +C Fix\svarious\sinternal\s#defines\sto\sconform\sto\snew\sC-language\snaming\srestrictions,\nspecifically\sthat\sprivate-use\smacros\snames\smust\snot\sbegin\swith\s"_". +D 2016-07-09T16:14:45.037 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -328,7 +328,7 @@ F src/backup.c 6df65fdd569c901a418887a1a76f82ec35044556 F src/bitvec.c 3ee4c8b2c94ed3a7377256e18199e6ff5cf33f63 F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 F src/btree.c dc4e5f3e95fd57b610422e36e0913662ecd6814c -F src/btree.h aee84823bb383d6ae3728b068f9130d2b36b71eb +F src/btree.h 075c45707c0f8f8af118f739f36df8098a08b7da F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 F src/build.c d1fdfd7ab8f5447e494ef15825973bf0719527c6 F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 @@ -343,8 +343,8 @@ F src/fkey.c bc4145347595b7770f9a598cff1c848302cf5413 F src/func.c 61a4114cf7004f10c542cfabbab9f2bcb9033045 F src/global.c c45ea22aff29334f6a9ec549235ac3357c970015 F src/hash.c 55b5fb474100cee0b901edaf203e26c970940f36 -F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094 -F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 +F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4 +F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da F src/insert.c 8f4e9fcbd8e95e85f15647ba8b413b18d556ec2b F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e F src/loadext.c 4237fd37ca589f1d90b3ea925dd9df20da8e0c84 @@ -356,22 +356,22 @@ F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3 F src/mem3.c 8768ac94694f31ffaf8b4d0ea5dc08af7010a35a F src/mem5.c 9bf955937b07f8c32541c8a9991f33ce3173d944 F src/memjournal.c 95752936c11dc6995672d1dd783cd633eea0cc95 -F src/msvc.h d9ba56c6851227ab44b3f228a35f3f5772296495 +F src/msvc.h 4942752b6a253116baaa8de75256c51a459a5e81 F src/mutex.c 8e45800ee78e0cd1f1f3fe8e398853307f4a085c F src/mutex.h 779d588e3b7756ec3ecf7d78cde1d84aba414f85 F src/mutex_noop.c 9d4309c075ba9cc7249e19412d3d62f7f94839c4 F src/mutex_unix.c 27bb6cc49485ee46711a6580ab7b3f1402211d23 F src/mutex_w32.c 5e6fe1c298fb5a8a15aaed4161d5759311431c17 F src/notify.c 9711a7575036f0d3040ba61bc6e217f13a9888e7 -F src/os.c 4d83917f072ad958fba9235136fa2ed43df47905 +F src/os.c add02933b1dce7a39a005b00a2f5364b763e9a24 F src/os.h 8e976e59eb4ca1c0fca6d35ee803e38951cb0343 F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85 -F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa +F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586 F src/os_unix.c a9443cdab41d7f3cdf0df3a5aab62fd6e1c9b234 -F src/os_win.c 716af57117381c24c0eb43c8dc5a86a6496f98a7 -F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca +F src/os_win.c 520f23475f1de530c435d30b67b7b15fe90874b0 +F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c c368634b888b1c8740aea83b36bfd266f2443e60 -F src/pager.h 8ab6b6feeee4bc0439bfde7ee59ba99df98b9bc3 +F src/pager.h 031a87445e5e0afc85312d1c380e123ad6c7aeaf F src/parse.y f374ab20106362eb3f5c01b3e6a002f0bbead7ff F src/pcache.c 5583c8ade4b05075a60ba953ef471d1c1a9c05df F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 @@ -385,10 +385,10 @@ F src/resolve.c cca3aa77b95706df5d635a2141a4d1de60ae6598 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c f3c6e9065fb34f6a23af27ec7f1f717ffbfc2ee4 F src/shell.c 14ff7f660530a52b117d110ba3390b7b2eb719b6 -F src/sqlite.h.in 5e6785f6d2148b20ecd891039b12e9c7b8c552ca +F src/sqlite.h.in b9ba728c1083b7a8ab5f6a628b25cd2a00325fbf F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 -F src/sqlite3ext.h 98f72cbfe00169c39089115427d06ea05fe4b4a2 -F src/sqliteInt.h 2ac73e9fdd138f4607139d9bd6a1e6dcd01837dc +F src/sqlite3ext.h 2a170163d121095c6ab1ef05ed0413722f391d01 +F src/sqliteInt.h dcf43b8abc5605b70f54ba80f42b6ad054b8ba95 F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c 5b18f9526900f61189ab0b83f1ef41d9f871a2ab F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 @@ -416,12 +416,12 @@ F src/test_func.c 37453d346cfcf118774efd5bf6187f7e6a7e3254 F src/test_hexio.c abfdecb6fa58c354623978efceb088ca18e379cd F src/test_init.c 66b33120ffe9cd853b5a905ec850d51151337b32 F src/test_intarray.c 870124b95ec4c645d4eb84f15efb7133528fb1a5 -F src/test_intarray.h 9dc57417fb65bc7835cc18548852cc08cc062202 +F src/test_intarray.h f3b7672f5d1056eac563c0d6ea8480a660b1475c F src/test_journal.c d3b83f2bcb7792c709e57abddc456a2b1818643a F src/test_loadext.c 337056bae59f80b9eb00ba82088b39d0f4fe6dfd F src/test_malloc.c 6b27e947eeeb70d11aa65406ed28d749e39b6356 F src/test_multiplex.c eafc567ebe162e36f17b5062285dfe90461cf8e9 -F src/test_multiplex.h c08e4e8f8651f0c5e0509b138ff4d5b43ed1f5d3 +F src/test_multiplex.h 5436d03f2d0501d04f3ed50a75819e190495b635 F src/test_mutex.c dbdfaff8580071f2212a0deae3325a93a737819c F src/test_onefile.c 416f87a28d6d673352d33fc4b1c7d39db878e50f F src/test_osinst.c ad0233b1dabb0390e25edded4ebd79a2a61538c6 @@ -450,8 +450,8 @@ F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 810ec3f22e2d1b62e66c30fe3621ebdedd23584d F src/vacuum.c feb1eabb20987983d9350cad98299b21fa811f52 F src/vdbe.c 22b46c3b725e950e9f2760e2d76953d592600ad4 -F src/vdbe.h 5591b5add447096e31288b5a0a78ec5d7b5c5170 -F src/vdbeInt.h ddb157974436d87652de7dc641f7191496d9a8cd +F src/vdbe.h 67bc551f7faf04c33493892e4b378aada823ed10 +F src/vdbeInt.h c59381049af5c7751a83456c39b80d1a6fde1f9d F src/vdbeapi.c 02bcbc2ca5d2004b029088b05b468b394881e103 F src/vdbeaux.c c90275b0e55a2b32c03dc09314194fe46f2429d8 F src/vdbeblob.c 83d2d266383157b02e2b809350bb197e89d7895b @@ -461,7 +461,7 @@ F src/vdbetrace.c f75c5455d8cf389ef86a8bfdfd3177e0e3692484 F src/vtab.c 948d2d4984219eee37a7bf427d6667e21e6eb92e F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 02eeecc265f6ffd0597378f5d8ae9070b62a406a -F src/wal.h 2f7c831cf3b071fa548bf2d5cac640846a7ff19c +F src/wal.h 6dd221ed384afdc204bc61e25c23ef7fd5a511f2 F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354 F src/where.c 48eed8ebe319c6cbc7bf7682018f32af0f5189f5 F src/whereInt.h e5b939701a7ceffc5a3a8188a37f9746416ebcd0 @@ -1505,7 +1505,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e1d8ef311cabcb96495a88404991b1416655e4a8 549abe3f89b55b05a05f267865a5dd84b8cd335d -R ba3e2959766a1594f290917f0109fdb1 +P b5f32a896d0e4010ec67fcf1d635bb9aa797d3c2 +R 1420ae412f251bd23536749aacd8c4fa U drh -Z f61bb876686c2e3e621a4eb92a4f2f5a +Z e116500fbf8eef00f67c7f388726b705 diff --git a/manifest.uuid b/manifest.uuid index 6ef4eda049..a0cf804e45 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b5f32a896d0e4010ec67fcf1d635bb9aa797d3c2 \ No newline at end of file +5471aca0158851d3fb0a2517306917536deb38bb \ No newline at end of file diff --git a/src/btree.h b/src/btree.h index c8b293ef17..b76e2ce214 100644 --- a/src/btree.h +++ b/src/btree.h @@ -13,8 +13,8 @@ ** subsystem. See comments in the source code for a detailed description ** of what each interface routine does. */ -#ifndef _BTREE_H_ -#define _BTREE_H_ +#ifndef SQLITE_BTREE_H +#define SQLITE_BTREE_H /* TODO: This definition is just included so other modules compile. It ** needs to be revisited. @@ -359,4 +359,4 @@ void sqlite3BtreeCursorList(Btree*); #endif -#endif /* _BTREE_H_ */ +#endif /* SQLITE_BTREE_H */ diff --git a/src/hash.h b/src/hash.h index 6dfa4e035c..90540eda50 100644 --- a/src/hash.h +++ b/src/hash.h @@ -12,8 +12,8 @@ ** This is the header file for the generic hash-table implementation ** used in SQLite. */ -#ifndef _SQLITE_HASH_H_ -#define _SQLITE_HASH_H_ +#ifndef SQLITE_HASH_H +#define SQLITE_HASH_H /* Forward declarations of structures. */ typedef struct Hash Hash; @@ -93,4 +93,4 @@ void sqlite3HashClear(Hash*); */ /* #define sqliteHashCount(H) ((H)->count) // NOT USED */ -#endif /* _SQLITE_HASH_H_ */ +#endif /* SQLITE_HASH_H */ diff --git a/src/hwtime.h b/src/hwtime.h index b8bc5a295b..5b209db8af 100644 --- a/src/hwtime.h +++ b/src/hwtime.h @@ -13,8 +13,8 @@ ** This file contains inline asm code for retrieving "high-performance" ** counters for x86 class CPUs. */ -#ifndef _HWTIME_H_ -#define _HWTIME_H_ +#ifndef SQLITE_HWTIME_H +#define SQLITE_HWTIME_H /* ** The following routine only works on pentium-class (or newer) processors. @@ -82,4 +82,4 @@ #endif -#endif /* !defined(_HWTIME_H_) */ +#endif /* !defined(SQLITE_HWTIME_H) */ diff --git a/src/msvc.h b/src/msvc.h index 01ebf2b46f..3914b05bcf 100644 --- a/src/msvc.h +++ b/src/msvc.h @@ -12,8 +12,8 @@ ** ** This file contains code that is specific to MSVC. */ -#ifndef _MSVC_H_ -#define _MSVC_H_ +#ifndef SQLITE_MSVC_H +#define SQLITE_MSVC_H #if defined(_MSC_VER) #pragma warning(disable : 4054) @@ -33,4 +33,4 @@ #pragma warning(disable : 4706) #endif /* defined(_MSC_VER) */ -#endif /* _MSVC_H_ */ +#endif /* SQLITE_MSVC_H */ diff --git a/src/os.c b/src/os.c index 6138bf4f3f..5cf0014794 100644 --- a/src/os.c +++ b/src/os.c @@ -13,9 +13,7 @@ ** This file contains OS interface code that is common to all ** architectures. */ -#define _SQLITE_OS_C_ 1 #include "sqliteInt.h" -#undef _SQLITE_OS_C_ /* ** If we compile with the SQLITE_TEST macro set, then the following block diff --git a/src/os_setup.h b/src/os_setup.h index 68de1446ed..08aaa1195a 100644 --- a/src/os_setup.h +++ b/src/os_setup.h @@ -13,8 +13,8 @@ ** This file contains pre-processor directives related to operating system ** detection and/or setup. */ -#ifndef _OS_SETUP_H_ -#define _OS_SETUP_H_ +#ifndef SQLITE_OS_SETUP_H +#define SQLITE_OS_SETUP_H /* ** Figure out if we are dealing with Unix, Windows, or some other operating @@ -54,4 +54,4 @@ # endif #endif -#endif /* _OS_SETUP_H_ */ +#endif /* SQLITE_OS_SETUP_H */ diff --git a/src/os_win.c b/src/os_win.c index 1c861b0fbd..6224088583 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -3675,12 +3675,12 @@ struct winShm { /* ** Apply advisory locks for all n bytes beginning at ofst. */ -#define _SHM_UNLCK 1 -#define _SHM_RDLCK 2 -#define _SHM_WRLCK 3 +#define WINSHM_UNLCK 1 +#define WINSHM_RDLCK 2 +#define WINSHM_WRLCK 3 static int winShmSystemLock( winShmNode *pFile, /* Apply locks to this open shared-memory segment */ - int lockType, /* _SHM_UNLCK, _SHM_RDLCK, or _SHM_WRLCK */ + int lockType, /* WINSHM_UNLCK, WINSHM_RDLCK, or WINSHM_WRLCK */ int ofst, /* Offset to first byte to be locked/unlocked */ int nByte /* Number of bytes to lock or unlock */ ){ @@ -3693,12 +3693,12 @@ static int winShmSystemLock( pFile->hFile.h, lockType, ofst, nByte)); /* Release/Acquire the system-level lock */ - if( lockType==_SHM_UNLCK ){ + if( lockType==WINSHM_UNLCK ){ rc = winUnlockFile(&pFile->hFile.h, ofst, 0, nByte, 0); }else{ /* Initialize the locking parameters */ DWORD dwFlags = LOCKFILE_FAIL_IMMEDIATELY; - if( lockType == _SHM_WRLCK ) dwFlags |= LOCKFILE_EXCLUSIVE_LOCK; + if( lockType == WINSHM_WRLCK ) dwFlags |= LOCKFILE_EXCLUSIVE_LOCK; rc = winLockFile(&pFile->hFile.h, dwFlags, ofst, 0, nByte, 0); } @@ -3710,7 +3710,7 @@ static int winShmSystemLock( } OSTRACE(("SHM-LOCK file=%p, func=%s, errno=%lu, rc=%s\n", - pFile->hFile.h, (lockType == _SHM_UNLCK) ? "winUnlockFile" : + pFile->hFile.h, (lockType == WINSHM_UNLCK) ? "winUnlockFile" : "winLockFile", pFile->lastErrno, sqlite3ErrName(rc))); return rc; @@ -3838,7 +3838,7 @@ static int winOpenSharedMemory(winFile *pDbFd){ /* Check to see if another process is holding the dead-man switch. ** If not, truncate the file to zero length. */ - if( winShmSystemLock(pShmNode, _SHM_WRLCK, WIN_SHM_DMS, 1)==SQLITE_OK ){ + if( winShmSystemLock(pShmNode, WINSHM_WRLCK, WIN_SHM_DMS, 1)==SQLITE_OK ){ rc = winTruncate((sqlite3_file *)&pShmNode->hFile, 0); if( rc!=SQLITE_OK ){ rc = winLogError(SQLITE_IOERR_SHMOPEN, osGetLastError(), @@ -3846,8 +3846,8 @@ static int winOpenSharedMemory(winFile *pDbFd){ } } if( rc==SQLITE_OK ){ - winShmSystemLock(pShmNode, _SHM_UNLCK, WIN_SHM_DMS, 1); - rc = winShmSystemLock(pShmNode, _SHM_RDLCK, WIN_SHM_DMS, 1); + winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1); + rc = winShmSystemLock(pShmNode, WINSHM_RDLCK, WIN_SHM_DMS, 1); } if( rc ) goto shm_open_err; } @@ -3876,7 +3876,7 @@ static int winOpenSharedMemory(winFile *pDbFd){ /* Jump here on any error */ shm_open_err: - winShmSystemLock(pShmNode, _SHM_UNLCK, WIN_SHM_DMS, 1); + winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1); winShmPurge(pDbFd->pVfs, 0); /* This call frees pShmNode if required */ sqlite3_free(p); sqlite3_free(pNew); @@ -3965,7 +3965,7 @@ static int winShmLock( /* Unlock the system-level locks */ if( (mask & allMask)==0 ){ - rc = winShmSystemLock(pShmNode, _SHM_UNLCK, ofst+WIN_SHM_BASE, n); + rc = winShmSystemLock(pShmNode, WINSHM_UNLCK, ofst+WIN_SHM_BASE, n); }else{ rc = SQLITE_OK; } @@ -3993,7 +3993,7 @@ static int winShmLock( /* Get shared locks at the system level, if necessary */ if( rc==SQLITE_OK ){ if( (allShared & mask)==0 ){ - rc = winShmSystemLock(pShmNode, _SHM_RDLCK, ofst+WIN_SHM_BASE, n); + rc = winShmSystemLock(pShmNode, WINSHM_RDLCK, ofst+WIN_SHM_BASE, n); }else{ rc = SQLITE_OK; } @@ -4018,7 +4018,7 @@ static int winShmLock( ** also mark the local connection as being locked. */ if( rc==SQLITE_OK ){ - rc = winShmSystemLock(pShmNode, _SHM_WRLCK, ofst+WIN_SHM_BASE, n); + rc = winShmSystemLock(pShmNode, WINSHM_WRLCK, ofst+WIN_SHM_BASE, n); if( rc==SQLITE_OK ){ assert( (p->sharedMask & mask)==0 ); p->exclMask |= mask; diff --git a/src/os_win.h b/src/os_win.h index 17d6a2bef4..27714ed079 100644 --- a/src/os_win.h +++ b/src/os_win.h @@ -12,8 +12,8 @@ ** ** This file contains code that is specific to Windows. */ -#ifndef _OS_WIN_H_ -#define _OS_WIN_H_ +#ifndef SQLITE_OS_WIN_H +#define SQLITE_OS_WIN_H /* ** Include the primary Windows SDK header file. @@ -85,4 +85,4 @@ # define SQLITE_OS_WIN_THREADS 0 #endif -#endif /* _OS_WIN_H_ */ +#endif /* SQLITE_OS_WIN_H */ diff --git a/src/pager.h b/src/pager.h index 69d3bb4435..af71d745a8 100644 --- a/src/pager.h +++ b/src/pager.h @@ -14,8 +14,8 @@ ** at a time and provides a journal for rollback. */ -#ifndef _PAGER_H_ -#define _PAGER_H_ +#ifndef SQLITE_PAGER_H +#define SQLITE_PAGER_H /* ** Default maximum size for persistent journal files. A negative @@ -229,4 +229,4 @@ void *sqlite3PagerCodec(DbPage *); # define enable_simulated_io_errors() #endif -#endif /* _PAGER_H_ */ +#endif /* SQLITE_PAGER_H */ diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 55f96dd898..12a07a9b4a 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -30,8 +30,8 @@ ** the version number) and changes its name to "sqlite3.h" as ** part of the build process. */ -#ifndef _SQLITE3_H_ -#define _SQLITE3_H_ +#ifndef SQLITE3_H +#define SQLITE3_H #include /* Needed for the definition of va_list */ /* @@ -8218,4 +8218,4 @@ SQLITE_EXPERIMENTAL int sqlite3_snapshot_cmp( #ifdef __cplusplus } /* End of the 'extern "C"' block */ #endif -#endif /* _SQLITE3_H_ */ +#endif /* SQLITE3_H */ diff --git a/src/sqlite3ext.h b/src/sqlite3ext.h index 20a2fcdf02..2d38e87ae7 100644 --- a/src/sqlite3ext.h +++ b/src/sqlite3ext.h @@ -15,8 +15,8 @@ ** as extensions by SQLite should #include this file instead of ** sqlite3.h. */ -#ifndef _SQLITE3EXT_H_ -#define _SQLITE3EXT_H_ +#ifndef SQLITE3EXT_H +#define SQLITE3EXT_H #include "sqlite3.h" typedef struct sqlite3_api_routines sqlite3_api_routines; @@ -543,4 +543,4 @@ struct sqlite3_api_routines { # define SQLITE_EXTENSION_INIT3 /*no-op*/ #endif -#endif /* _SQLITE3EXT_H_ */ +#endif /* SQLITE3EXT_H */ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index c52cd29927..998a17dac3 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -12,8 +12,8 @@ ** Internal interface definitions for SQLite. ** */ -#ifndef _SQLITEINT_H_ -#define _SQLITEINT_H_ +#ifndef SQLITEINT_H +#define SQLITEINT_H /* Special Comments: ** @@ -4237,4 +4237,4 @@ int sqlite3ThreadJoin(SQLiteThread*, void**); int sqlite3DbstatRegister(sqlite3*); #endif -#endif /* _SQLITEINT_H_ */ +#endif /* SQLITEINT_H */ diff --git a/src/test_intarray.h b/src/test_intarray.h index 84b1f3fe66..cee55b5dae 100644 --- a/src/test_intarray.h +++ b/src/test_intarray.h @@ -75,8 +75,8 @@ ** action to free the intarray objects. */ #include "sqlite3.h" -#ifndef _INTARRAY_H_ -#define _INTARRAY_H_ +#ifndef SQLITE_INTARRAY_H +#define SQLITE_INTARRAY_H /* ** Make sure we can call this stuff from C++. @@ -125,4 +125,4 @@ SQLITE_API int sqlite3_intarray_bind( #ifdef __cplusplus } /* End of the 'extern "C"' block */ #endif -#endif /* _INTARRAY_H_ */ +#endif /* SQLITE_INTARRAY_H */ diff --git a/src/test_multiplex.h b/src/test_multiplex.h index d973e4af27..790c778a35 100644 --- a/src/test_multiplex.h +++ b/src/test_multiplex.h @@ -20,8 +20,8 @@ ** */ -#ifndef _TEST_MULTIPLEX_H -#define _TEST_MULTIPLEX_H +#ifndef SQLITE_TEST_MULTIPLEX_H +#define SQLITE_TEST_MULTIPLEX_H /* ** CAPI: File-control Operations Supported by Multiplex VFS @@ -96,4 +96,4 @@ extern int sqlite3_multiplex_shutdown(int eForce); } /* End of the 'extern "C"' block */ #endif -#endif /* _TEST_MULTIPLEX_H */ +#endif /* SQLITE_TEST_MULTIPLEX_H */ diff --git a/src/vdbe.h b/src/vdbe.h index 3db32c8552..a7bc84cea5 100644 --- a/src/vdbe.h +++ b/src/vdbe.h @@ -15,8 +15,8 @@ ** or VDBE. The VDBE implements an abstract machine that runs a ** simple program to access and modify the underlying database. */ -#ifndef _SQLITE_VDBE_H_ -#define _SQLITE_VDBE_H_ +#ifndef SQLITE_VDBE_H +#define SQLITE_VDBE_H #include /* @@ -309,4 +309,4 @@ void sqlite3VdbeScanStatus(Vdbe*, int, int, int, LogEst, const char*); # define sqlite3VdbeScanStatus(a,b,c,d,e) #endif -#endif +#endif /* SQLITE_VDBE_H */ diff --git a/src/vdbeInt.h b/src/vdbeInt.h index 61561e9dce..ecb4fc5f06 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -15,8 +15,8 @@ ** 6000 lines long) it was split up into several smaller files and ** this header information was factored out. */ -#ifndef _VDBEINT_H_ -#define _VDBEINT_H_ +#ifndef SQLITE_VDBEINT_H +#define SQLITE_VDBEINT_H /* ** The maximum number of times that a statement will try to reparse @@ -558,4 +558,4 @@ int sqlite3VdbeMemHandleBom(Mem *pMem); #define ExpandBlob(P) SQLITE_OK #endif -#endif /* !defined(_VDBEINT_H_) */ +#endif /* !defined(SQLITE_VDBEINT_H) */ diff --git a/src/wal.h b/src/wal.h index 97e6ab4f10..6048e7985c 100644 --- a/src/wal.h +++ b/src/wal.h @@ -14,8 +14,8 @@ ** the implementation of each function in log.c for further details. */ -#ifndef _WAL_H_ -#define _WAL_H_ +#ifndef SQLITE_WAL_H +#define SQLITE_WAL_H #include "sqliteInt.h" @@ -143,4 +143,4 @@ int sqlite3WalFramesize(Wal *pWal); sqlite3_file *sqlite3WalFile(Wal *pWal); #endif /* ifndef SQLITE_OMIT_WAL */ -#endif /* _WAL_H_ */ +#endif /* SQLITE_WAL_H */ From 11499f0ab434e44e00621242bd64a97eaedee800 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 9 Jul 2016 16:38:25 +0000 Subject: [PATCH 0550/1484] Fix compiler warnings on windows. FossilOrigin-Name: 8b22f777a11438ab0baadc7d9e471f415b734d1f --- ext/misc/carray.c | 4 ++-- ext/misc/csv.c | 6 +++--- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/test_bestindex.c | 4 ++-- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/ext/misc/carray.c b/ext/misc/carray.c index 70d226a85f..b0c8be77d3 100644 --- a/ext/misc/carray.c +++ b/ext/misc/carray.c @@ -303,7 +303,7 @@ static int carrayBestIndex( pIdxInfo->aConstraintUsage[cntIdx].argvIndex = 2; pIdxInfo->aConstraintUsage[cntIdx].omit = 1; pIdxInfo->estimatedCost = (double)1; - pIdxInfo->estimatedRows = (double)100; + pIdxInfo->estimatedRows = 100; pIdxInfo->idxNum = 2; if( ctypeIdx>=0 ){ pIdxInfo->aConstraintUsage[ctypeIdx].argvIndex = 3; @@ -312,7 +312,7 @@ static int carrayBestIndex( } }else{ pIdxInfo->estimatedCost = (double)2147483647; - pIdxInfo->estimatedRows = (double)2147483647; + pIdxInfo->estimatedRows = 2147483647; pIdxInfo->idxNum = 0; } return SQLITE_OK; diff --git a/ext/misc/csv.c b/ext/misc/csv.c index c0d8ecd3fc..3a7e32d311 100644 --- a/ext/misc/csv.c +++ b/ext/misc/csv.c @@ -375,7 +375,7 @@ static int csv_string_parameter( char **pzVal /* Write the dequoted string value here */ ){ const char *zValue; - zValue = csv_parameter(zParam,strlen(zParam),zArg); + zValue = csv_parameter(zParam,(int)strlen(zParam),zArg); if( zValue==0 ) return 0; p->zErr[0] = 0; if( *pzVal ){ @@ -616,7 +616,7 @@ static int csvtabOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){ CsvCursor *pCur; size_t nByte; nByte = sizeof(*pCur) + (sizeof(char*)+sizeof(int))*pTab->nCol; - pCur = sqlite3_malloc( nByte ); + pCur = sqlite3_malloc64( nByte ); if( pCur==0 ) return SQLITE_NOMEM; memset(pCur, 0, nByte); pCur->azVal = (char**)&pCur[1]; @@ -647,7 +647,7 @@ static int csvtabNext(sqlite3_vtab_cursor *cur){ } if( inCol ){ if( pCur->aLen[i] < pCur->rdr.n+1 ){ - char *zNew = sqlite3_realloc(pCur->azVal[i], pCur->rdr.n+1); + char *zNew = sqlite3_realloc64(pCur->azVal[i], pCur->rdr.n+1); if( zNew==0 ){ csv_errmsg(&pCur->rdr, "out of memory"); csv_xfer_error(pTab, &pCur->rdr); diff --git a/manifest b/manifest index eef481b87d..3956234549 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\svarious\sinternal\s#defines\sto\sconform\sto\snew\sC-language\snaming\srestrictions,\nspecifically\sthat\sprivate-use\smacros\snames\smust\snot\sbegin\swith\s"_". -D 2016-07-09T16:14:45.037 +C Fix\scompiler\swarnings\son\swindows. +D 2016-07-09T16:38:25.217 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -204,10 +204,10 @@ F ext/icu/README.txt d9fbbad0c2f647c3fdf715fc9fd64af53aedfc43 F ext/icu/icu.c 43df9d8ef2fae7a325100ebd713ab089dc829dd7 F ext/icu/sqliteicu.h 728867a802baa5a96de7495e9689a8e01715ef37 F ext/misc/amatch.c 211108e201105e4bb0c076527b8cfd34330fc234 -F ext/misc/carray.c f1947c7d5bbce17f8244c9a05baae11d5d68467e +F ext/misc/carray.c 29f3b2dbb93b93cedcc571660203d1e24d921bd3 F ext/misc/closure.c 0d2a038df8fbae7f19de42e7c7d71f2e4dc88704 F ext/misc/compress.c 122faa92d25033d6c3f07c39231de074ab3d2e83 -F ext/misc/csv.c f01126ba170fd4ef7c752b156568a80c912d4441 +F ext/misc/csv.c b92692b057707f5b7bb91feaedde790b2e38304e F ext/misc/eval.c f971962e92ebb8b0a4e6b62949463ee454d88fa2 F ext/misc/fileio.c d4171c815d6543a9edef8308aab2951413cd8d0f F ext/misc/fuzzer.c 7c64b8197bb77b7d64eff7cac7848870235d4c25 @@ -405,7 +405,7 @@ F src/test9.c bea1e8cf52aa93695487badedd6e1886c321ea60 F src/test_async.c 21e11293a2f72080eda70e1124e9102044531cd8 F src/test_autoext.c dea8a01a7153b9adc97bd26161e4226329546e12 F src/test_backup.c 2e6e6a081870150f20c526a2e9d0d29cda47d803 -F src/test_bestindex.c 29af3cc3b963ffe5760c85d142b9b3e5302c1e3d +F src/test_bestindex.c f9e6807c52aa532e4775321ce3ed8e47c907ed45 F src/test_blob.c b2551a9b5573232db5f66f292307c37067937239 F src/test_btree.c 2e9978eca99a9a4bfa8cae949efb00886860a64f F src/test_config.c 7003f6f35134de6f19c6588f44783e43390ea277 @@ -1505,7 +1505,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b5f32a896d0e4010ec67fcf1d635bb9aa797d3c2 -R 1420ae412f251bd23536749aacd8c4fa +P 5471aca0158851d3fb0a2517306917536deb38bb +R 51759f55d04de93087e3d229894a3277 U drh -Z e116500fbf8eef00f67c7f388726b705 +Z 7d1dfc3636ab19ed9a6789ae76c95a5f diff --git a/manifest.uuid b/manifest.uuid index a0cf804e45..3c6dd362dc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5471aca0158851d3fb0a2517306917536deb38bb \ No newline at end of file +8b22f777a11438ab0baadc7d9e471f415b734d1f \ No newline at end of file diff --git a/src/test_bestindex.c b/src/test_bestindex.c index a955c2782c..f6f9d3eaf8 100644 --- a/src/test_bestindex.c +++ b/src/test_bestindex.c @@ -179,8 +179,8 @@ static int tclConnect( return SQLITE_ERROR; } - zCmd = sqlite3_malloc(strlen(argv[3])+1); - pTab = (tcl_vtab*)sqlite3_malloc(sizeof(tcl_vtab)); + zCmd = sqlite3_malloc64(strlen(argv[3])+1); + pTab = (tcl_vtab*)sqlite3_malloc64(sizeof(tcl_vtab)); if( zCmd && pTab ){ memcpy(zCmd, argv[3], strlen(argv[3])+1); tclDequote(zCmd); From a912348a196d1dc895cf0fa9c5f6319883d3dfe0 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 9 Jul 2016 17:15:05 +0000 Subject: [PATCH 0551/1484] Fix a compiler warning in test code - in the int64array_addr TCL command. FossilOrigin-Name: 29fb988f1afc3fe623097acee1a5d08bf8386626 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/test1.c | 4 +++- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 3956234549..f7b68ae764 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\scompiler\swarnings\son\swindows. -D 2016-07-09T16:38:25.217 +C Fix\sa\scompiler\swarning\sin\stest\scode\s-\sin\sthe\sint64array_addr\sTCL\scommand. +D 2016-07-09T17:15:05.420 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -393,7 +393,7 @@ F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c 5b18f9526900f61189ab0b83f1ef41d9f871a2ab F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 F src/tclsqlite.c 25fbbbb97f76dbfd113153fb63f52d7ecfac5dd0 -F src/test1.c 08faa045c45b1d3f62c28c93cae955f518317f68 +F src/test1.c 640f862c490c8eee09a9d02d0d128c6a8a75336d F src/test2.c 5586f43fcd9a1be0830793cf9d354082c261b25b F src/test3.c c75c8af0eadb335236c9e61b51044c58a8f7dd59 F src/test4.c d168f83cc78d02e8d35567bb5630e40dcd85ac1e @@ -1505,7 +1505,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 5471aca0158851d3fb0a2517306917536deb38bb -R 51759f55d04de93087e3d229894a3277 +P 8b22f777a11438ab0baadc7d9e471f415b734d1f +R 8809172c97ecd2789d873e485f1080c5 U drh -Z 7d1dfc3636ab19ed9a6789ae76c95a5f +Z b4d622f88577c8bb575918451a798624 diff --git a/manifest.uuid b/manifest.uuid index 3c6dd362dc..0979534540 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8b22f777a11438ab0baadc7d9e471f415b734d1f \ No newline at end of file +29fb988f1afc3fe623097acee1a5d08bf8386626 \ No newline at end of file diff --git a/src/test1.c b/src/test1.c index d4a5cfc3ce..5ce818bf74 100644 --- a/src/test1.c +++ b/src/test1.c @@ -3299,11 +3299,13 @@ static int test_int64array_addr( p = sqlite3_malloc( sizeof(p[0])*(objc-1) ); if( p==0 ) return TCL_ERROR; for(i=0; i Date: Sat, 9 Jul 2016 17:47:01 +0000 Subject: [PATCH 0552/1484] Add the "#/value-list/" style of results for approximate value matching in the do_test command of the test infrastructure. Use this new result style to make the SQLITE_DBSTATUS_CACHE_SIZE_SHARED tests cross-platform. FossilOrigin-Name: c869bf34a8ee42ac6542862e59c7a4b89b042f79 --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/dbstatus.test | 8 ++------ test/tester.tcl | 28 +++++++++++++++++++++++++++- 4 files changed, 37 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index f7b68ae764..679ecd4e0c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\scompiler\swarning\sin\stest\scode\s-\sin\sthe\sint64array_addr\sTCL\scommand. -D 2016-07-09T17:15:05.420 +C Add\sthe\s"#/value-list/"\sstyle\sof\sresults\sfor\sapproximate\svalue\smatching\nin\sthe\sdo_test\scommand\sof\sthe\stest\sinfrastructure.\s\sUse\sthis\snew\sresult\sstyle\nto\smake\sthe\sSQLITE_DBSTATUS_CACHE_SIZE_SHARED\stests\scross-platform. +D 2016-07-09T17:47:01.013 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -621,7 +621,7 @@ F test/ctime.test 0b995accd44a52914bd4744d5c1b6e1a56c7897c F test/cursorhint.test 7bc346788390475e77a345da2b92270d04d35856 F test/cursorhint2.test 2b45341d32d1aae9991a00ef31ebca339b274255 F test/date.test 984ac1e3e5e031386866f034006148d3972b4a65 -F test/dbstatus.test 254427f026b55ab6eba99bd8493f4edbc370bb13 +F test/dbstatus.test 85833ba5bc95262749d080dcd40af87072ea8d5b F test/dbstatus2.test e93ab03bfae6d62d4d935f20de928c19ca0ed0ab F test/default.test 0cb49b1c315a0d81c81d775e407f66906a2a604d F test/delete.test e1bcdf8926234e27aac24b346ad83d3329ec8b6f @@ -1128,7 +1128,7 @@ F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30 F test/temptable2.test cd396beb41117a5302fff61767c35fa4270a0d5e F test/temptable3.test d11a0974e52b347e45ee54ef1923c91ed91e4637 F test/temptrigger.test 8ec228b0db5d7ebc4ee9b458fc28cb9e7873f5e1 -F test/tester.tcl 3ace46dee55f07e28a1e3ab03258b929fefcee5b +F test/tester.tcl a52b5be1bb586afa1c8bcdcd4b86588645e1ae52 F test/thread001.test 9f22fd3525a307ff42a326b6bc7b0465be1745a5 F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58 F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7 @@ -1505,7 +1505,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 8b22f777a11438ab0baadc7d9e471f415b734d1f -R 8809172c97ecd2789d873e485f1080c5 +P 29fb988f1afc3fe623097acee1a5d08bf8386626 +R 767a7d8abd9b9525d1b45069b4c3dba2 U drh -Z b4d622f88577c8bb575918451a798624 +Z df36acb2648e26f22b53c52b73476f6c diff --git a/manifest.uuid b/manifest.uuid index 0979534540..d451076edf 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -29fb988f1afc3fe623097acee1a5d08bf8386626 \ No newline at end of file +c869bf34a8ee42ac6542862e59c7a4b89b042f79 \ No newline at end of file diff --git a/test/dbstatus.test b/test/dbstatus.test index 7bc44353b0..00c5deabd5 100644 --- a/test/dbstatus.test +++ b/test/dbstatus.test @@ -69,16 +69,12 @@ ifcapable stat4||stat3 { set STAT3 0 } -ifcapable malloc_usable_size { - finish_test - return -} - #--------------------------------------------------------------------------- # Run the dbstatus-2 and dbstatus-3 tests with several of different # lookaside buffer sizes. # foreach ::lookaside_buffer_size {0 64 120} { + ifcapable malloc_usable_size break # Do not run any of these tests if there is SQL configured to run # as part of the [sqlite3] command. This prevents the script from @@ -388,7 +384,7 @@ ifcapable shared_cache { set pcu [sqlite3_db_status $db SQLITE_DBSTATUS_CACHE_USED_SHARED 0] set cu [lindex $cu 1] set pcu [lindex $pcu 1] - uplevel [list do_test $tn [list list $cu $pcu] [list {*}$res]] + uplevel [list do_test $tn [list list $cu $pcu] "#/$res/"] } reset_db sqlite3 db file:test.db?cache=shared diff --git a/test/tester.tcl b/test/tester.tcl index 9fbc7b2569..3f1edc32ae 100644 --- a/test/tester.tcl +++ b/test/tester.tcl @@ -720,6 +720,17 @@ proc puts {args} { uplevel puts_override $args } # Invoke the do_test procedure to run a single test # +# The $expected parameter is the expected result. The result is the return +# value from the last TCL command in $cmd. +# +# Normally, $expected must match exactly. But if $expected is of the form +# "/regexp/" then regular expression matching is used. If $expected is +# "~/regexp/" then the regular expression must NOT match. If $expected is +# of the form "#/value-list/" then each term in value-list must be numeric +# and must approximately match the corresponding numeric term in $result. +# Values must match within 10%. Or if the $expected term is A..B then the +# $result term must be in between A and B. +# proc do_test {name cmd expected} { global argv cmdlinearg @@ -753,7 +764,7 @@ proc do_test {name cmd expected} { output2 "\nError: $result" fail_test $name } else { - if {[regexp {^~?/.*/$} $expected]} { + if {[regexp {^[~#]?/.*/$} $expected]} { # "expected" is of the form "/PATTERN/" then the result if correct if # regular expression PATTERN matches the result. "~/PATTERN/" means # the regular expression must not match. @@ -767,6 +778,21 @@ proc do_test {name cmd expected} { set ok [regexp $re $result] } set ok [expr {!$ok}] + } elseif {[string index $expected 0]=="#"} { + # Numeric range value comparison. Each term of the $result is matched + # against one term of $expect. Both $result and $expected terms must be + # numeric. The values must match within 10%. Or if $expected is of the + # form A..B then the $result term must be between A and B. + set e2 [string range $expected 2 end-1] + foreach i $result j $e2 { + if {[regexp {^(-?\d+)\.\.(-?\d)$} $j all A B]} { + set ok [expr {$i+0>=$A && $i+0<=$B}] + } else { + set ok [expr {$i+0>=0.9*$j && $i+0<=1.1*$j}] + } + if {!$ok} break + } + if {$ok && [llength $result]!=[llength $e2]} {set ok 0} } else { set re [string range $expected 1 end-1] if {[string index $re 0]=="*"} { From 71c57db099b331c0c3294e1122448fb732a131bc Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 9 Jul 2016 20:23:55 +0000 Subject: [PATCH 0553/1484] Add some support for using row value constructors in certain parts of SQL expressions. There are many bugs on this branch. FossilOrigin-Name: b2204215b231202aef7a218411cc2ddaecf28f35 --- manifest | 39 +++-- manifest.uuid | 2 +- src/expr.c | 375 ++++++++++++++++++++++++++++++++++++-------- src/parse.y | 9 ++ src/resolve.c | 35 +++++ src/select.c | 35 ++--- src/sqliteInt.h | 6 +- src/vdbe.c | 40 ++++- src/where.c | 65 +++++++- src/whereInt.h | 2 + src/wherecode.c | 60 +++++-- src/whereexpr.c | 49 +++++- test/rowvalue.test | 123 +++++++++++++++ test/rowvalue2.test | 252 +++++++++++++++++++++++++++++ tool/addopcodes.tcl | 1 + 15 files changed, 975 insertions(+), 118 deletions(-) create mode 100644 test/rowvalue.test create mode 100644 test/rowvalue2.test diff --git a/manifest b/manifest index 679ecd4e0c..b5d0802698 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\s"#/value-list/"\sstyle\sof\sresults\sfor\sapproximate\svalue\smatching\nin\sthe\sdo_test\scommand\sof\sthe\stest\sinfrastructure.\s\sUse\sthis\snew\sresult\sstyle\nto\smake\sthe\sSQLITE_DBSTATUS_CACHE_SIZE_SHARED\stests\scross-platform. -D 2016-07-09T17:47:01.013 +C Add\ssome\ssupport\sfor\susing\srow\svalue\sconstructors\sin\scertain\sparts\sof\sSQL\sexpressions.\sThere\sare\smany\sbugs\son\sthis\sbranch. +D 2016-07-09T20:23:55.716 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -337,7 +337,7 @@ F src/ctime.c 61949e83c4c36e37195a8398ebc752780b534d95 F src/date.c 1cc9fb516ec9932c6fd4d2a0d2f8bc4480145c39 F src/dbstat.c 4f6f7f52b49beb9636ffbd517cfe44a402ba4ad0 F src/delete.c 4aba4214a377ce8ddde2d2e609777bcc8235200f -F src/expr.c 523a5b1db2b6d88c6eefb224877bf635a3bcfc92 +F src/expr.c 330854fe9fdea1d244abaef6d680f6b91df07cb4 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c bc4145347595b7770f9a598cff1c848302cf5413 F src/func.c 61a4114cf7004f10c542cfabbab9f2bcb9033045 @@ -372,7 +372,7 @@ F src/os_win.c 520f23475f1de530c435d30b67b7b15fe90874b0 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c c368634b888b1c8740aea83b36bfd266f2443e60 F src/pager.h 031a87445e5e0afc85312d1c380e123ad6c7aeaf -F src/parse.y f374ab20106362eb3f5c01b3e6a002f0bbead7ff +F src/parse.y fa040d742fe4922b219143fe2e04f74061daabcb F src/pcache.c 5583c8ade4b05075a60ba953ef471d1c1a9c05df F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 F src/pcache1.c 7f51d2b541aab57596adf62db2c4bb025d34f04d @@ -381,14 +381,14 @@ F src/pragma.h 64c78a648751b9f4f297276c4eb7507b14b4628c F src/prepare.c 22df6171aec1d86904ed2ad30c2348a5748aa04e F src/printf.c a5f0ca08ddede803c241266abb46356ec748ded1 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 -F src/resolve.c cca3aa77b95706df5d635a2141a4d1de60ae6598 +F src/resolve.c 9680caadd54772699e5a0a8ebd680e014703e4ee F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac -F src/select.c f3c6e9065fb34f6a23af27ec7f1f717ffbfc2ee4 +F src/select.c 0115f5d222f5cf9b5511ec4072088417354d738a F src/shell.c 14ff7f660530a52b117d110ba3390b7b2eb719b6 F src/sqlite.h.in b9ba728c1083b7a8ab5f6a628b25cd2a00325fbf F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 2a170163d121095c6ab1ef05ed0413722f391d01 -F src/sqliteInt.h dcf43b8abc5605b70f54ba80f42b6ad054b8ba95 +F src/sqliteInt.h dd2dd1d880ffd33137d20dc6da21f169836b8f5a F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c 5b18f9526900f61189ab0b83f1ef41d9f871a2ab F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 @@ -449,7 +449,7 @@ F src/update.c 4f05ea8cddfa367d045e03589756c02199e8f9bd F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 810ec3f22e2d1b62e66c30fe3621ebdedd23584d F src/vacuum.c feb1eabb20987983d9350cad98299b21fa811f52 -F src/vdbe.c 22b46c3b725e950e9f2760e2d76953d592600ad4 +F src/vdbe.c 680c118a20b4b496644001e7ff4819c3e3ff8d85 F src/vdbe.h 67bc551f7faf04c33493892e4b378aada823ed10 F src/vdbeInt.h c59381049af5c7751a83456c39b80d1a6fde1f9d F src/vdbeapi.c 02bcbc2ca5d2004b029088b05b468b394881e103 @@ -463,10 +463,10 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 02eeecc265f6ffd0597378f5d8ae9070b62a406a F src/wal.h 6dd221ed384afdc204bc61e25c23ef7fd5a511f2 F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354 -F src/where.c 48eed8ebe319c6cbc7bf7682018f32af0f5189f5 -F src/whereInt.h e5b939701a7ceffc5a3a8188a37f9746416ebcd0 -F src/wherecode.c e20cb381ff621e56a4684c71e31999aca2547ca6 -F src/whereexpr.c d7dcbf14ce1b5876c1f76496162c30fcba669563 +F src/where.c 898a45969bae1298cbaaaf05e6aeacfb45971293 +F src/whereInt.h 1ad3be2a43cb821418e1100476a3a14cd57635c4 +F src/wherecode.c a66c589bdcaa9da45d9576d54663666083e0c109 +F src/whereexpr.c d88ee6ce356cb9fd986d0e81249a2cd66a513093 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1017,6 +1017,8 @@ F test/rollbackfault.test 0e646aeab8840c399cfbfa43daab46fd609cf04a F test/rowallock.test 3f88ec6819489d0b2341c7a7528ae17c053ab7cc F test/rowhash.test 0bc1d31415e4575d10cacf31e1a66b5cc0f8be81 F test/rowid.test 5b7509f384f4f6fae1af3c8c104c8ca299fea18d +F test/rowvalue.test 979738b3d49f1d93e3fee56a71d4446217917abc +F test/rowvalue2.test 8d5dfe75b8f4d1868a2f91f0356f20d36cba64ff F test/rtree.test 0c8d9dd458d6824e59683c19ab2ffa9ef946f798 F test/run-wordcount.sh 891e89c4c2d16e629cd45951d4ed899ad12afc09 F test/savepoint.test c671fdbd34cd3bfe1518a777526ada595180cf8d @@ -1419,7 +1421,7 @@ F test/zerodamage.test e59a56443d6298ecf7435f618f0b27654f0c849e F tool/GetFile.cs a15e08acb5dd7539b75ba23501581d7c2b462cb5 F tool/GetTclKit.bat 629d87562e0487c386db630033931d12d62e6372 F tool/Replace.cs 02c67258801c2fb5f63231e0ac0f220b4b36ba91 -F tool/addopcodes.tcl 2b089684eb8b7d0db64cf9d8e6d2fe1b6d279e8d +F tool/addopcodes.tcl 7d4954564d7d4bfde5ba139ebced25542696fa52 F tool/build-all-msvc.bat 3e4e4043b53f1aede4308e0d2567bbd773614630 x F tool/build-shell.sh 950f47c6174f1eea171319438b93ba67ff5bf367 F tool/cg_anno.tcl 692ce4b8693d59e3a3de77ca97f4139ecfa641b0 x @@ -1505,7 +1507,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 29fb988f1afc3fe623097acee1a5d08bf8386626 -R 767a7d8abd9b9525d1b45069b4c3dba2 -U drh -Z df36acb2648e26f22b53c52b73476f6c +P c869bf34a8ee42ac6542862e59c7a4b89b042f79 +R e70f91ca2d7d2c655198f54d385cd62e +T *branch * rowvalue +T *sym-rowvalue * +T -sym-trunk * +U dan +Z e86f169a98e6cbe5718a428ba6e6f5e0 diff --git a/manifest.uuid b/manifest.uuid index d451076edf..8f187444bd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c869bf34a8ee42ac6542862e59c7a4b89b042f79 \ No newline at end of file +b2204215b231202aef7a218411cc2ddaecf28f35 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index ce3a476561..7941c228fd 100644 --- a/src/expr.c +++ b/src/expr.c @@ -309,6 +309,114 @@ static int codeCompare( return addr; } +int sqlite3ExprVectorSize(Expr *pExpr){ + if( (pExpr->flags & EP_Vector)==0 ) return 1; + if( pExpr->flags & EP_xIsSelect ){ + return pExpr->x.pSelect->pEList->nExpr; + } + return pExpr->x.pList->nExpr; +} + +static Expr *exprVectorField(Expr *pVector, int i){ + if( pVector->flags & EP_xIsSelect ){ + return pVector->x.pSelect->pEList->a[i].pExpr; + } + return pVector->x.pList->a[i].pExpr; +} + +static void codeVectorCompare(Parse *pParse, Expr *pExpr, int dest){ + Vdbe *v = pParse->pVdbe; + Expr *pLeft = pExpr->pLeft; + Expr *pRight = pExpr->pRight; + int nLeft = sqlite3ExprVectorSize(pLeft); + int nRight = sqlite3ExprVectorSize(pRight); + int addr = sqlite3VdbeMakeLabel(v); + + /* Check that both sides of the comparison are vectors, and that + ** both are the same length. */ + if( nLeft!=nRight ){ + sqlite3ErrorMsg(pParse, "invalid use of row value"); + }else{ + int p5 = (pExpr->op==TK_IS || pExpr->op==TK_ISNOT) ? SQLITE_NULLEQ : 0; + int opCmp; + int opTest; + int i; + int p3 = 1; + int regLeft = 0; + int regRight = 0; + + assert( pExpr->op==TK_EQ || pExpr->op==TK_NE + || pExpr->op==TK_IS || pExpr->op==TK_ISNOT + || pExpr->op==TK_LT || pExpr->op==TK_GT + || pExpr->op==TK_LE || pExpr->op==TK_GE + ); + + switch( pExpr->op ){ + case TK_EQ: + case TK_IS: + opTest = OP_IfNot; + opCmp = OP_Eq; + break; + + case TK_NE: + case TK_ISNOT: + opTest = OP_If; + opCmp = OP_Ne; + break; + + case TK_LT: + case TK_LE: + case TK_GT: + case TK_GE: + opCmp = OP_Cmp; + opTest = OP_CmpTest; + p3 = pExpr->op; + break; + } + + if( pLeft->flags & EP_xIsSelect ){ + assert( pLeft->op==TK_SELECT || pLeft->op==TK_REGISTER ); + regLeft = sqlite3ExprCodeTarget(pParse, pLeft, 1); + assert( regLeft!=1 ); + } + if( pRight->flags & EP_xIsSelect ){ + assert( pRight->op==TK_SELECT || pRight->op==TK_REGISTER ); + regRight = sqlite3ExprCodeTarget(pParse, pRight, 1); + assert( regRight!=1 ); + } + if( pParse->nErr ) return; + + for(i=0; ix.pSelect->pEList->a[i].pExpr; + r1 = regLeft+i; + }else{ + pL = pLeft->x.pList->a[i].pExpr; + r1 = sqlite3ExprCodeTemp(pParse, pL, ®Free1); + } + + if( regRight ){ + pR = pRight->x.pSelect->pEList->a[i].pExpr; + r2 = regRight+i; + }else{ + pR = pRight->x.pList->a[i].pExpr; + r2 = sqlite3ExprCodeTemp(pParse, pR, ®Free1); + } + + codeCompare(pParse, pL, pR, opCmp, r1, r2, dest, SQLITE_STOREP2 | p5); + sqlite3VdbeAddOp3(v, opTest, dest, addr, p3); + sqlite3ReleaseTempReg(pParse, regFree1); + sqlite3ReleaseTempReg(pParse, regFree2); + } + } + + sqlite3VdbeResolveLabel(v, addr); +} + #if SQLITE_MAX_EXPR_DEPTH>0 /* ** Check that argument nHeight is less than or equal to the maximum @@ -743,7 +851,7 @@ static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){ if( !ExprHasProperty(p, EP_TokenOnly) ){ /* The Expr.x union is never used at the same time as Expr.pRight */ assert( p->x.pList==0 || p->pRight==0 ); - sqlite3ExprDelete(db, p->pLeft); + if( p->op!=TK_SELECT_COLUMN ) sqlite3ExprDelete(db, p->pLeft); sqlite3ExprDelete(db, p->pRight); if( ExprHasProperty(p, EP_MemToken) ) sqlite3DbFree(db, p->u.zToken); if( ExprHasProperty(p, EP_xIsSelect) ){ @@ -1835,7 +1943,7 @@ int sqlite3FindInIndex(Parse *pParse, Expr *pX, u32 inFlags, int *prRhsHasNull){ /* If no preexisting index is available for the IN clause ** and IN_INDEX_NOOP is an allowed reply ** and the RHS of the IN operator is a list, not a subquery - ** and the RHS is not contant or has two or fewer terms, + ** and the RHS is not constant or has two or fewer terms, ** then it is not worth creating an ephemeral table to evaluate ** the IN operator so return IN_INDEX_NOOP. */ @@ -1872,6 +1980,30 @@ int sqlite3FindInIndex(Parse *pParse, Expr *pX, u32 inFlags, int *prRhsHasNull){ } #endif +static char *exprINAffinity(Parse *pParse, Expr *pExpr){ + Expr *pLeft = pExpr->pLeft; + int nVal = sqlite3ExprVectorSize(pLeft); + char *zRet; + + zRet = sqlite3DbMallocZero(pParse->db, nVal+1); + if( zRet ){ + int i; + for(i=0; ix.pSelect->pEList->a[i].pExpr, a); + } + zRet[nVal] = '\0'; + } + return zRet; +} + /* ** Generate code for scalar subqueries used as a subquery expression, EXISTS, ** or IN operators. Examples: @@ -1939,12 +2071,12 @@ int sqlite3CodeSubselect( switch( pExpr->op ){ case TK_IN: { - char affinity; /* Affinity of the LHS of the IN */ int addr; /* Address of OP_OpenEphemeral instruction */ Expr *pLeft = pExpr->pLeft; /* the LHS of the IN operator */ KeyInfo *pKeyInfo = 0; /* Key information */ - - affinity = sqlite3ExprAffinity(pLeft); + int nVal; /* Size of vector pLeft */ + + nVal = sqlite3ExprVectorSize(pLeft); /* Whether this is an 'x IN(SELECT...)' or an 'x IN()' ** expression it is handled the same way. An ephemeral table is @@ -1960,8 +2092,9 @@ int sqlite3CodeSubselect( ** is used. */ pExpr->iTable = pParse->nTab++; - addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pExpr->iTable, !isRowid); - pKeyInfo = isRowid ? 0 : sqlite3KeyInfoAlloc(pParse->db, 1, 1); + addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, + pExpr->iTable, (isRowid?0:nVal)); + pKeyInfo = isRowid ? 0 : sqlite3KeyInfoAlloc(pParse->db, nVal, 1); if( ExprHasProperty(pExpr, EP_xIsSelect) ){ /* Case 1: expr IN (SELECT ...) @@ -1970,27 +2103,38 @@ int sqlite3CodeSubselect( ** table allocated and opened above. */ Select *pSelect = pExpr->x.pSelect; - SelectDest dest; - ExprList *pEList; + ExprList *pEList = pSelect->pEList; assert( !isRowid ); - sqlite3SelectDestInit(&dest, SRT_Set, pExpr->iTable); - dest.affSdst = (u8)affinity; - assert( (pExpr->iTable&0x0000FFFF)==pExpr->iTable ); - pSelect->iLimit = 0; - testcase( pSelect->selFlags & SF_Distinct ); - testcase( pKeyInfo==0 ); /* Caused by OOM in sqlite3KeyInfoAlloc() */ - if( sqlite3Select(pParse, pSelect, &dest) ){ - sqlite3KeyInfoUnref(pKeyInfo); - return 0; + if( pEList->nExpr!=nVal ){ + sqlite3ErrorMsg(pParse, "SELECT has %d columns - expected %d", + pEList->nExpr, nVal); + }else{ + SelectDest dest; + int i; + sqlite3SelectDestInit(&dest, SRT_Set, pExpr->iTable); + dest.zAffSdst = exprINAffinity(pParse, pExpr); + assert( (pExpr->iTable&0x0000FFFF)==pExpr->iTable ); + pSelect->iLimit = 0; + testcase( pSelect->selFlags & SF_Distinct ); + testcase( pKeyInfo==0 ); /* Caused by OOM in sqlite3KeyInfoAlloc() */ + if( sqlite3Select(pParse, pSelect, &dest) ){ + sqlite3DbFree(pParse->db, dest.zAffSdst); + sqlite3KeyInfoUnref(pKeyInfo); + return 0; + } + sqlite3DbFree(pParse->db, dest.zAffSdst); + assert( pKeyInfo!=0 ); /* OOM will cause exit after sqlite3Select() */ + assert( pEList!=0 ); + assert( pEList->nExpr>0 ); + assert( sqlite3KeyInfoIsWriteable(pKeyInfo) ); + for(i=0; i1) ? exprVectorField(pLeft, i) : pLeft; + pKeyInfo->aColl[i] = sqlite3BinaryCompareCollSeq( + pParse, p, pEList->a[i].pExpr + ); + } } - pEList = pSelect->pEList; - assert( pKeyInfo!=0 ); /* OOM will cause exit after sqlite3Select() */ - assert( pEList!=0 ); - assert( pEList->nExpr>0 ); - assert( sqlite3KeyInfoIsWriteable(pKeyInfo) ); - pKeyInfo->aColl[0] = sqlite3BinaryCompareCollSeq(pParse, pExpr->pLeft, - pEList->a[0].pExpr); }else if( ALWAYS(pExpr->x.pList!=0) ){ /* Case 2: expr IN (exprlist) ** @@ -1999,11 +2143,13 @@ int sqlite3CodeSubselect( ** that columns affinity when building index keys. If is not ** a column, use numeric affinity. */ + char affinity; /* Affinity of the LHS of the IN */ int i; ExprList *pList = pExpr->x.pList; struct ExprList_item *pItem; int r1, r2, r3; + affinity = sqlite3ExprAffinity(pLeft); if( !affinity ){ affinity = SQLITE_AFF_BLOB; } @@ -2067,18 +2213,22 @@ int sqlite3CodeSubselect( */ Select *pSel; /* SELECT statement to encode */ SelectDest dest; /* How to deal with SELECt result */ + int nReg; /* Registers to allocate */ testcase( pExpr->op==TK_EXISTS ); testcase( pExpr->op==TK_SELECT ); assert( pExpr->op==TK_EXISTS || pExpr->op==TK_SELECT ); - assert( ExprHasProperty(pExpr, EP_xIsSelect) ); + pSel = pExpr->x.pSelect; - sqlite3SelectDestInit(&dest, 0, ++pParse->nMem); + nReg = pExpr->op==TK_SELECT ? pSel->pEList->nExpr : 1; + sqlite3SelectDestInit(&dest, 0, pParse->nMem+1); + pParse->nMem += nReg; if( pExpr->op==TK_SELECT ){ dest.eDest = SRT_Mem; dest.iSdst = dest.iSDParm; - sqlite3VdbeAddOp2(v, OP_Null, 0, dest.iSDParm); + dest.nSdst = nReg; + sqlite3VdbeAddOp3(v, OP_Null, 0, dest.iSDParm, dest.iSDParm+nReg-1); VdbeComment((v, "Init subquery result")); }else{ dest.eDest = SRT_Exists; @@ -2112,6 +2262,75 @@ int sqlite3CodeSubselect( } #endif /* SQLITE_OMIT_SUBQUERY */ +#ifndef SQLITE_OMIT_SUBQUERY +void exprCodeVectorIN( + Parse *pParse, /* Parsing and code generating context */ + Expr *pExpr, /* The IN expression */ + int destIfFalse, /* Jump here if LHS is not contained in the RHS */ + int destIfNull /* Jump here if the results are unknown due to NULLs */ +){ + int i; + int addrNext; + int iSkip; + int r1; + int r2 = sqlite3GetTempReg(pParse); + int r3 = sqlite3GetTempReg(pParse); + int r4 = sqlite3GetTempReg(pParse); + int regResult = sqlite3GetTempReg(pParse); + int nVal = sqlite3ExprVectorSize(pExpr->pLeft); + + Expr *pLeft = pExpr->pLeft; + Vdbe *v = pParse->pVdbe; + + /* Code the LHS, the from " IN (...)". Leave the results in + ** an array of nVal registers starting at r1. */ + sqlite3ExprCachePush(pParse); + if( pLeft->flags & EP_xIsSelect ){ + r1 = sqlite3CodeSubselect(pParse, pLeft, 0, 0); + }else{ + r1 = pParse->nMem + 1; + pParse->nMem += nVal; + sqlite3ExprCodeExprList(pParse, pLeft->x.pList, r1, 0, 0); + } + + /* Generate an epheremal index containing the contents of the SELECT + ** to the right of the " IN (SELECT ...)" expression. The cursor + ** number for the epheremal table is left in pExpr->iTable. */ + assert( pExpr->flags & EP_xIsSelect ); + sqlite3CodeSubselect(pParse, pExpr, 0, 0); + + sqlite3VdbeAddOp2(v, OP_Integer, 0, regResult); + + /* Iterate through the ephemeral table just populated */ + addrNext = 1 + sqlite3VdbeAddOp2(v, OP_Rewind, pExpr->iTable, destIfFalse); + for(i=0; iiTable, i, r2); + sqlite3VdbeAddOp4(v, OP_Eq, r1+i, i==0?r3:r4, r2, (void*)pColl,P4_COLLSEQ); + sqlite3VdbeChangeP5(v, SQLITE_STOREP2); + VdbeCoverage(v); + if( i!=0 ){ + sqlite3VdbeAddOp3(v, OP_And, r3, r4, r4); + } + } + sqlite3VdbeAddOp2(v, OP_If, r4, sqlite3VdbeCurrentAddr(v)+6); + sqlite3VdbeAddOp2(v, OP_IfNot, r4, sqlite3VdbeCurrentAddr(v)+2); + sqlite3VdbeAddOp2(v, OP_Null, 0, regResult); + sqlite3VdbeAddOp2(v, OP_Next, pExpr->iTable, addrNext); + sqlite3VdbeAddOp3(v, OP_If, regResult, destIfNull, 1); + sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfFalse); + + sqlite3ReleaseTempReg(pParse, r2); + sqlite3ReleaseTempReg(pParse, r3); + sqlite3ReleaseTempReg(pParse, r4); + sqlite3ReleaseTempReg(pParse, regResult); + sqlite3ExprCachePop(pParse); +} +#endif + #ifndef SQLITE_OMIT_SUBQUERY /* ** Generate code for an IN expression. @@ -2142,6 +2361,10 @@ static void sqlite3ExprCodeIN( int r1; /* Temporary use register */ Vdbe *v; /* Statement under construction */ + if( pExpr->pLeft->flags & EP_Vector ){ + return exprCodeVectorIN(pParse, pExpr, destIfFalse, destIfNull); + } + /* Compute the RHS. After this step, the table with cursor ** pExpr->iTable will contains the values that make up the RHS. */ @@ -2669,6 +2892,8 @@ static void exprToRegister(Expr *p, int iReg){ ExprClearProperty(p, EP_Skip); } +static void exprCodeBetween(Parse*,Expr*,int,void(*)(Parse*,Expr*,int,int),int); + /* ** Generate code into the current Vdbe to evaluate the given ** expression. Attempt to store the results in register "target". @@ -2689,6 +2914,7 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ int r1, r2, r3, r4; /* Various register numbers */ sqlite3 *db = pParse->db; /* The database connection */ Expr tempX; /* Temporary expression node */ + int p5 = 0; assert( target>0 && target<=pParse->nMem ); if( v==0 ){ @@ -2801,39 +3027,34 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ break; } #endif /* SQLITE_OMIT_CAST */ + case TK_IS: + case TK_ISNOT: + op = (op==TK_IS) ? TK_EQ : TK_NE; + p5 = SQLITE_NULLEQ; + /* fall-through */ case TK_LT: case TK_LE: case TK_GT: case TK_GE: case TK_NE: case TK_EQ: { - r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); - r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); - codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, - r1, r2, inReg, SQLITE_STOREP2); - assert(TK_LT==OP_Lt); testcase(op==OP_Lt); VdbeCoverageIf(v,op==OP_Lt); - assert(TK_LE==OP_Le); testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le); - assert(TK_GT==OP_Gt); testcase(op==OP_Gt); VdbeCoverageIf(v,op==OP_Gt); - assert(TK_GE==OP_Ge); testcase(op==OP_Ge); VdbeCoverageIf(v,op==OP_Ge); - assert(TK_EQ==OP_Eq); testcase(op==OP_Eq); VdbeCoverageIf(v,op==OP_Eq); - assert(TK_NE==OP_Ne); testcase(op==OP_Ne); VdbeCoverageIf(v,op==OP_Ne); - testcase( regFree1==0 ); - testcase( regFree2==0 ); - break; - } - case TK_IS: - case TK_ISNOT: { - testcase( op==TK_IS ); - testcase( op==TK_ISNOT ); - r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); - r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); - op = (op==TK_IS) ? TK_EQ : TK_NE; - codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, - r1, r2, inReg, SQLITE_STOREP2 | SQLITE_NULLEQ); - VdbeCoverageIf(v, op==TK_EQ); - VdbeCoverageIf(v, op==TK_NE); - testcase( regFree1==0 ); - testcase( regFree2==0 ); + Expr *pLeft = pExpr->pLeft; + if( (pLeft->flags & EP_Vector) ){ + codeVectorCompare(pParse, pExpr, target); + }else{ + r1 = sqlite3ExprCodeTemp(pParse, pLeft, ®Free1); + r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); + codeCompare(pParse, pLeft, pExpr->pRight, op, + r1, r2, inReg, SQLITE_STOREP2 | p5); + assert(TK_LT==OP_Lt); testcase(op==OP_Lt); VdbeCoverageIf(v,op==OP_Lt); + assert(TK_LE==OP_Le); testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le); + assert(TK_GT==OP_Gt); testcase(op==OP_Gt); VdbeCoverageIf(v,op==OP_Gt); + assert(TK_GE==OP_Ge); testcase(op==OP_Ge); VdbeCoverageIf(v,op==OP_Ge); + assert(TK_EQ==OP_Eq); testcase(op==OP_Eq); VdbeCoverageIf(v,op==OP_Eq); + assert(TK_NE==OP_Ne); testcase(op==OP_Ne); VdbeCoverageIf(v,op==OP_Ne); + testcase( regFree1==0 ); + testcase( regFree2==0 ); + } break; } case TK_AND: @@ -3085,6 +3306,8 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ ** Z is stored in pExpr->pList->a[1].pExpr. */ case TK_BETWEEN: { + exprCodeBetween(pParse, pExpr, target, 0, 0); +#if 0 Expr *pLeft = pExpr->pLeft; struct ExprList_item *pLItem = pExpr->x.pList->a; Expr *pRight = pLItem->pExpr; @@ -3107,6 +3330,7 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ sqlite3VdbeAddOp3(v, OP_And, r3, r4, target); sqlite3ReleaseTempReg(pParse, r3); sqlite3ReleaseTempReg(pParse, r4); +#endif break; } case TK_SPAN: @@ -3172,6 +3396,22 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ break; } + case TK_VECTOR: { + sqlite3ErrorMsg(pParse, "invalid use of row value (1)"); + break; + } + + case TK_SELECT_COLUMN: { + Expr *pLeft = pExpr->pLeft; + assert( pLeft ); + assert( pLeft->op==TK_SELECT || pLeft->op==TK_REGISTER ); + if( pLeft->op==TK_SELECT ){ + pLeft->iTable = sqlite3CodeSubselect(pParse, pLeft, 0, 0); + pLeft->op = TK_REGISTER; + } + inReg = pLeft->iTable + pExpr->iColumn; + break; + } /* ** Form A: @@ -3500,7 +3740,7 @@ static void exprCodeBetween( Parse *pParse, /* Parsing and code generating context */ Expr *pExpr, /* The BETWEEN expression */ int dest, /* Jump here if the jump is taken */ - int jumpIfTrue, /* Take the jump if the BETWEEN is true */ + void (*xJumpIf)(Parse*,Expr*,int,int), int jumpIfNull /* Take the jump if the BETWEEN is NULL */ ){ Expr exprAnd; /* The AND operator in x>=y AND x<=z */ @@ -3509,6 +3749,10 @@ static void exprCodeBetween( Expr exprX; /* The x subexpression */ int regFree1 = 0; /* Temporary use register */ + memset(&compLeft, 0, sizeof(Expr)); + memset(&compRight, 0, sizeof(Expr)); + memset(&exprAnd, 0, sizeof(Expr)); + assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); exprX = *pExpr->pLeft; exprAnd.op = TK_AND; @@ -3520,11 +3764,14 @@ static void exprCodeBetween( compRight.op = TK_LE; compRight.pLeft = &exprX; compRight.pRight = pExpr->x.pList->a[1].pExpr; - exprToRegister(&exprX, sqlite3ExprCodeTemp(pParse, &exprX, ®Free1)); - if( jumpIfTrue ){ - sqlite3ExprIfTrue(pParse, &exprAnd, dest, jumpIfNull); + if( (exprX.flags & EP_Vector)==0 ){ + exprToRegister(&exprX, sqlite3ExprCodeTemp(pParse, &exprX, ®Free1)); + } + if( xJumpIf ){ + xJumpIf(pParse, &exprAnd, dest, jumpIfNull); }else{ - sqlite3ExprIfFalse(pParse, &exprAnd, dest, jumpIfNull); + exprX.flags |= EP_FromJoin; + sqlite3ExprCodeTarget(pParse, &exprAnd, dest); } sqlite3ReleaseTempReg(pParse, regFree1); @@ -3564,7 +3811,7 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ if( NEVER(v==0) ) return; /* Existence of VDBE checked by caller */ if( NEVER(pExpr==0) ) return; /* No way this can happen */ op = pExpr->op; - switch( op ){ + switch( op | (pExpr->pLeft ? (pExpr->pLeft->flags & EP_Vector) : 0)){ case TK_AND: { int d2 = sqlite3VdbeMakeLabel(v); testcase( jumpIfNull==0 ); @@ -3633,7 +3880,7 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ } case TK_BETWEEN: { testcase( jumpIfNull==0 ); - exprCodeBetween(pParse, pExpr, dest, 1, jumpIfNull); + exprCodeBetween(pParse, pExpr, dest, sqlite3ExprIfTrue, jumpIfNull); break; } #ifndef SQLITE_OMIT_SUBQUERY @@ -3716,7 +3963,7 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ assert( pExpr->op!=TK_GT || op==OP_Le ); assert( pExpr->op!=TK_GE || op==OP_Lt ); - switch( pExpr->op ){ + switch( pExpr->op | (pExpr->pLeft ? (pExpr->pLeft->flags & EP_Vector) : 0)){ case TK_AND: { testcase( jumpIfNull==0 ); sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull); @@ -3783,7 +4030,7 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ } case TK_BETWEEN: { testcase( jumpIfNull==0 ); - exprCodeBetween(pParse, pExpr, dest, 0, jumpIfNull); + exprCodeBetween(pParse, pExpr, dest, sqlite3ExprIfFalse, jumpIfNull); break; } #ifndef SQLITE_OMIT_SUBQUERY diff --git a/src/parse.y b/src/parse.y index 8a65131e28..b107057fe0 100644 --- a/src/parse.y +++ b/src/parse.y @@ -217,6 +217,7 @@ columnname(A) ::= nm(A) typetoken(Y). {sqlite3AddColumn(pParse,&A,&Y);} %left CONCAT. %left COLLATE. %right BITNOT. +%right VECTOR. // An IDENTIFIER can be a generic identifier, or one of several // keywords. Any non-standard keyword can also be an identifier. @@ -946,6 +947,14 @@ term(A) ::= CTIME_KW(OP). { } } +expr(A) ::= LP(L) nexprlist(X) COMMA expr(Y) RP(R). { + A.pExpr = sqlite3PExpr(pParse, TK_VECTOR, 0, 0, 0); + if( A.pExpr ){ + A.pExpr->x.pList = sqlite3ExprListAppend(pParse, X, Y.pExpr); + spanSet(&A, &L, &R); + } +} + expr(A) ::= expr(A) AND(OP) expr(Y). {spanBinaryExpr(pParse,@OP,&A,&Y);} expr(A) ::= expr(A) OR(OP) expr(Y). {spanBinaryExpr(pParse,@OP,&A,&Y);} expr(A) ::= expr(A) LT|GT|GE|LE(OP) expr(Y). diff --git a/src/resolve.c b/src/resolve.c index 77ce37f6d7..cd3d714613 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -765,6 +765,17 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ ExprSetProperty(pExpr, EP_VarSelect); pNC->ncFlags |= NC_VarSelect; } + + if( pExpr->op==TK_SELECT && pExpr->x.pSelect->pEList->nExpr>1 ){ + if( !ExprHasProperty(pExpr, EP_VectorOk) ){ + sqlite3ErrorMsg(pParse, "invalid use of row value"); + }else{ + ExprSetProperty(pExpr, EP_Vector); + } + } + if( pExpr->op==TK_IN ){ + ExprSetProperty(pExpr->pLeft, EP_VectorOk); + } } break; } @@ -772,6 +783,30 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ notValid(pParse, pNC, "parameters", NC_IsCheck|NC_PartIdx|NC_IdxExpr); break; } + + case TK_BETWEEN: { + ExprSetProperty(pExpr->pLeft, EP_VectorOk); + ExprSetProperty(pExpr->x.pList->a[0].pExpr, EP_VectorOk); + ExprSetProperty(pExpr->x.pList->a[1].pExpr, EP_VectorOk); + break; + } + + case TK_EQ: case TK_NE: case TK_IS: case TK_ISNOT: + case TK_LE: case TK_LT: case TK_GE: case TK_GT: + { + ExprSetProperty(pExpr->pLeft, EP_VectorOk); + ExprSetProperty(pExpr->pRight, EP_VectorOk); + break; + }; + + case TK_VECTOR: { + if( !ExprHasProperty(pExpr, EP_VectorOk) ){ + sqlite3ErrorMsg(pParse, "invalid use of row value"); + }else{ + ExprSetProperty(pExpr, EP_Vector); + } + break; + } } return (pParse->nErr || pParse->db->mallocFailed) ? WRC_Abort : WRC_Continue; } diff --git a/src/select.c b/src/select.c index e21ac57dc5..f49a5c1fed 100644 --- a/src/select.c +++ b/src/select.c @@ -88,7 +88,7 @@ static void clearSelect(sqlite3 *db, Select *p, int bFree){ void sqlite3SelectDestInit(SelectDest *pDest, int eDest, int iParm){ pDest->eDest = (u8)eDest; pDest->iSDParm = iParm; - pDest->affSdst = 0; + pDest->zAffSdst = 0; pDest->iSdst = 0; pDest->nSdst = 0; } @@ -673,7 +673,7 @@ static int checkForMultiColumnSelectError( int nExpr /* Number of result columns returned by SELECT */ ){ int eDest = pDest->eDest; - if( nExpr>1 && (eDest==SRT_Mem || eDest==SRT_Set) ){ + if( 0 && nExpr>1 && eDest==SRT_Set ){ sqlite3ErrorMsg(pParse, "only a single result allowed for " "a SELECT that is part of an expression"); return 1; @@ -892,9 +892,6 @@ static void selectInnerLoop( ** item into the set table with bogus data. */ case SRT_Set: { - assert( nResultCol==1 ); - pDest->affSdst = - sqlite3CompareAffinity(pEList->a[0].pExpr, pDest->affSdst); if( pSort ){ /* At first glance you would think we could optimize out the ** ORDER BY in this case since the order of entries in the set @@ -903,8 +900,10 @@ static void selectInnerLoop( pushOntoSorter(pParse, pSort, p, regResult, regResult, 1, nPrefixReg); }else{ int r1 = sqlite3GetTempReg(pParse); - sqlite3VdbeAddOp4(v, OP_MakeRecord, regResult,1,r1, &pDest->affSdst, 1); - sqlite3ExprCacheAffinityChange(pParse, regResult, 1); + assert( sqlite3Strlen30(pDest->zAffSdst)==nResultCol ); + sqlite3VdbeAddOp4(v, OP_MakeRecord, regResult, nResultCol, + r1, pDest->zAffSdst, 1); + sqlite3ExprCacheAffinityChange(pParse, regResult, nResultCol); sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, r1); sqlite3ReleaseTempReg(pParse, r1); } @@ -924,9 +923,9 @@ static void selectInnerLoop( ** of the scan loop. */ case SRT_Mem: { - assert( nResultCol==1 ); + assert( nResultCol==pDest->nSdst ); if( pSort ){ - pushOntoSorter(pParse, pSort, p, regResult, regResult, 1, nPrefixReg); + pushOntoSorter(pParse, pSort, p, regResult, regResult, nResultCol, nPrefixReg); }else{ assert( regResult==iParm ); /* The LIMIT clause will jump out of the loop for us */ @@ -1241,7 +1240,7 @@ static void generateSortTail( sqlite3VdbeResolveLabel(v, pSort->labelBkOut); } iTab = pSort->iECursor; - if( eDest==SRT_Output || eDest==SRT_Coroutine ){ + if( eDest==SRT_Output || eDest==SRT_Coroutine || eDest==SRT_Mem ){ regRowid = 0; regRow = pDest->iSdst; nSortData = nColumn; @@ -1283,16 +1282,15 @@ static void generateSortTail( } #ifndef SQLITE_OMIT_SUBQUERY case SRT_Set: { - assert( nColumn==1 ); - sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, 1, regRowid, - &pDest->affSdst, 1); - sqlite3ExprCacheAffinityChange(pParse, regRow, 1); + assert( nColumn==sqlite3Strlen30(pDest->zAffSdst) ); + sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, nColumn, regRowid, + pDest->zAffSdst, 1); + sqlite3ExprCacheAffinityChange(pParse, regRow, nColumn); sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, regRowid); break; } case SRT_Mem: { - assert( nColumn==1 ); - sqlite3ExprCodeMove(pParse, regRow, iParm, 1); + /* sqlite3ExprCodeMove(pParse, regRow, iParm, nColumn); */ /* The LIMIT clause will terminate the loop for us */ break; } @@ -2659,10 +2657,9 @@ static int generateOutputSubroutine( case SRT_Set: { int r1; assert( pIn->nSdst==1 || pParse->nErr>0 ); - pDest->affSdst = - sqlite3CompareAffinity(p->pEList->a[0].pExpr, pDest->affSdst); r1 = sqlite3GetTempReg(pParse); - sqlite3VdbeAddOp4(v, OP_MakeRecord, pIn->iSdst, 1, r1, &pDest->affSdst,1); + sqlite3VdbeAddOp4(v, OP_MakeRecord, pIn->iSdst, pIn->nSdst, + r1, pDest->zAffSdst,1); sqlite3ExprCacheAffinityChange(pParse, pIn->iSdst, 1); sqlite3VdbeAddOp2(v, OP_IdxInsert, pDest->iSDParm, r1); sqlite3ReleaseTempReg(pParse, r1); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 998a17dac3..3caa65d8e3 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2317,6 +2317,8 @@ struct Expr { #define EP_CanBeNull 0x100000 /* Can be null despite NOT NULL constraint */ #define EP_Subquery 0x200000 /* Tree contains a TK_SELECT operator */ #define EP_Alias 0x400000 /* Is an alias for a result set column */ +#define EP_VectorOk 0x800000 /* This expression may be a row value */ +#define EP_Vector 0x1000000/* This expression is a row value */ /* ** Combinations of two or more EP_* flags @@ -2762,7 +2764,7 @@ struct Select { */ struct SelectDest { u8 eDest; /* How to dispose of the results. On of SRT_* above. */ - char affSdst; /* Affinity used when eDest==SRT_Set */ + char *zAffSdst; /* Affinity used when eDest==SRT_Set */ int iSDParm; /* A parameter used by the eDest disposal method */ int iSdst; /* Base register where results are written */ int nSdst; /* Number of registers allocated */ @@ -4237,4 +4239,6 @@ int sqlite3ThreadJoin(SQLiteThread*, void**); int sqlite3DbstatRegister(sqlite3*); #endif +int sqlite3ExprVectorSize(Expr *pExpr); + #endif /* SQLITEINT_H */ diff --git a/src/vdbe.c b/src/vdbe.c index 6adbcbbec1..3f2fdf9cff 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -1958,6 +1958,7 @@ case OP_Cast: { /* in1 */ ** the content of register P3 is greater than or equal to the content of ** register P1. See the Lt opcode for additional information. */ +case OP_Cmp: /* in1, in3 */ case OP_Eq: /* same as TK_EQ, jump, in1, in3 */ case OP_Ne: /* same as TK_NE, jump, in1, in3 */ case OP_Lt: /* same as TK_LT, jump, in1, in3 */ @@ -2056,7 +2057,8 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ case OP_Lt: res = res<0; break; case OP_Le: res = res<=0; break; case OP_Gt: res = res>0; break; - default: res = res>=0; break; + case OP_Ge: res = res>=0; break; + default: assert( pOp->opcode==OP_Cmp ); break; } /* Undo any changes made by applyAffinity() to the input registers. */ @@ -2072,6 +2074,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ pOut->u.i = res; REGISTER_TRACE(pOp->p2, pOut); }else{ + assert( pOp->opcode!=OP_Cmp ); VdbeBranchTaken(res!=0, (pOp->p5 & SQLITE_NULLEQ)?2:3); if( res ){ goto jump_to_p2; @@ -3867,7 +3870,42 @@ seek_not_found: } break; } + +/* Opcode: CmpTest P1 P2 P3 * * +** +** P2 is a jump destination. Register P1 is guaranteed to contain either +** an integer value or a NULL. The jump is taken if P1 contains any value +** other than 0 (i.e. NULL does cause a jump). +** +** If P1 is not NULL, its value is modified to integer value 0 or 1 +** according to the value of the P3 operand: +** +** P3 modification +** -------------------------- +** OP_Lt (P1 = (P1 < 0)) +** OP_Le (P1 = (P1 <= 0)) +** OP_Gt (P1 = (P1 > 0)) +** OP_Ge (P1 = (P1 >= 0)) +*/ +case OP_CmpTest: { /* in1, jump */ + int bJump; + pIn1 = &aMem[pOp->p1]; + if( (pIn1->flags & MEM_Int) ){ + bJump = (pIn1->u.i!=0); + switch( pOp->p3 ){ + case OP_Lt: pIn1->u.i = (pIn1->u.i < 0); break; + case OP_Le: pIn1->u.i = (pIn1->u.i <= 0); break; + case OP_Gt: pIn1->u.i = (pIn1->u.i > 0); break; + default: assert( pOp->p3==OP_Ge ); pIn1->u.i = (pIn1->u.i >= 0); break; + } + }else{ + bJump = 1; + } + + if( bJump ) goto jump_to_p2; + break; +} /* Opcode: Found P1 P2 P3 P4 * ** Synopsis: key=r[P3@P4] diff --git a/src/where.c b/src/where.c index a65f30968e..36bf98b444 100644 --- a/src/where.c +++ b/src/where.c @@ -2187,6 +2187,51 @@ static void whereLoopOutputAdjust( if( pLoop->nOut > nRow-iReduce ) pLoop->nOut = nRow - iReduce; } +/* +** Term pTerm is a vector range comparison operation. The first comparison +** in the vector can be optimized using column nEq of the index. +*/ +int whereRangeVectorLen( + Parse *pParse, int iCur, Index *pIdx, int nEq, WhereTerm *pTerm +){ + int nCmp = sqlite3ExprVectorSize(pTerm->pExpr->pLeft); + int i; + + nCmp = MIN(nCmp, (pIdx->nColumn - nEq)); + for(i=1; ipExpr->pLeft->x.pList->a[i].pExpr; + Expr *pRhs = pTerm->pExpr->pRight; + if( pRhs->flags & EP_xIsSelect ){ + pRhs = pRhs->x.pSelect->pEList->a[i].pExpr; + }else{ + pRhs = pRhs->x.pList->a[i].pExpr; + } + + /* Check that the LHS of the comparison is a column reference to + ** the right column of the right source table. + */ + if( pLhs->op!=TK_COLUMN + || pLhs->iTable!=iCur + || pLhs->iColumn!=pIdx->aiColumn[i+nEq] + ){ + break; + } + + aff = sqlite3CompareAffinity(pRhs, sqlite3ExprAffinity(pLhs)); + idxaff = pIdx->pTable->aCol[pLhs->iColumn].affinity; + if( aff!=idxaff ) break; + + pColl = sqlite3BinaryCompareCollSeq(pParse, pLhs, pRhs); + if( sqlite3StrICmp(pColl->zName, pIdx->azColl[i+nEq]) ) break; + } + return i; +} + /* ** Adjust the cost C by the costMult facter T. This only occurs if ** compiled with -DSQLITE_ENABLE_COSTMULT @@ -2225,6 +2270,8 @@ static int whereLoopAddBtreeIndex( Bitmask saved_prereq; /* Original value of pNew->prereq */ u16 saved_nLTerm; /* Original value of pNew->nLTerm */ u16 saved_nEq; /* Original value of pNew->u.btree.nEq */ + u16 saved_nBtm; /* Original value of pNew->u.btree.nBtm */ + u16 saved_nTop; /* Original value of pNew->u.btree.nTop */ u16 saved_nSkip; /* Original value of pNew->nSkip */ u32 saved_wsFlags; /* Original value of pNew->wsFlags */ LogEst saved_nOut; /* Original value of pNew->nOut */ @@ -2241,6 +2288,7 @@ static int whereLoopAddBtreeIndex( if( pNew->wsFlags & WHERE_BTM_LIMIT ){ opMask = WO_LT|WO_LE; }else{ + assert( pNew->u.btree.nBtm==0 ); opMask = WO_EQ|WO_IN|WO_GT|WO_GE|WO_LT|WO_LE|WO_ISNULL|WO_IS; } if( pProbe->bUnordered ) opMask &= ~(WO_GT|WO_GE|WO_LT|WO_LE); @@ -2248,6 +2296,8 @@ static int whereLoopAddBtreeIndex( assert( pNew->u.btree.nEqnColumn ); saved_nEq = pNew->u.btree.nEq; + saved_nBtm = pNew->u.btree.nBtm; + saved_nTop = pNew->u.btree.nTop; saved_nSkip = pNew->nSkip; saved_nLTerm = pNew->nLTerm; saved_wsFlags = pNew->wsFlags; @@ -2291,6 +2341,8 @@ static int whereLoopAddBtreeIndex( pNew->wsFlags = saved_wsFlags; pNew->u.btree.nEq = saved_nEq; + pNew->u.btree.nBtm = saved_nBtm; + pNew->u.btree.nTop = saved_nTop; pNew->nLTerm = saved_nLTerm; if( whereLoopResize(db, pNew, pNew->nLTerm+1) ) break; /* OOM */ pNew->aLTerm[pNew->nLTerm++] = pTerm; @@ -2334,6 +2386,9 @@ static int whereLoopAddBtreeIndex( testcase( eOp & WO_GT ); testcase( eOp & WO_GE ); pNew->wsFlags |= WHERE_COLUMN_RANGE|WHERE_BTM_LIMIT; + pNew->u.btree.nBtm = whereRangeVectorLen( + pParse, pSrc->iCursor, pProbe, saved_nEq, pTerm + ); pBtm = pTerm; pTop = 0; if( pTerm->wtFlags & TERM_LIKEOPT ){ @@ -2346,12 +2401,16 @@ static int whereLoopAddBtreeIndex( if( whereLoopResize(db, pNew, pNew->nLTerm+1) ) break; /* OOM */ pNew->aLTerm[pNew->nLTerm++] = pTop; pNew->wsFlags |= WHERE_TOP_LIMIT; + pNew->u.btree.nTop = 1; } }else{ assert( eOp & (WO_LT|WO_LE) ); testcase( eOp & WO_LT ); testcase( eOp & WO_LE ); pNew->wsFlags |= WHERE_COLUMN_RANGE|WHERE_TOP_LIMIT; + pNew->u.btree.nTop = whereRangeVectorLen( + pParse, pSrc->iCursor, pProbe, saved_nEq, pTerm + ); pTop = pTerm; pBtm = (pNew->wsFlags & WHERE_BTM_LIMIT)!=0 ? pNew->aLTerm[pNew->nLTerm-2] : 0; @@ -2451,6 +2510,8 @@ static int whereLoopAddBtreeIndex( } pNew->prereq = saved_prereq; pNew->u.btree.nEq = saved_nEq; + pNew->u.btree.nBtm = saved_nBtm; + pNew->u.btree.nTop = saved_nTop; pNew->nSkip = saved_nSkip; pNew->wsFlags = saved_wsFlags; pNew->nOut = saved_nOut; @@ -2572,7 +2633,7 @@ static int whereUsablePartialIndex(int iTab, WhereClause *pWC, Expr *pWhere){ /* ** Add all WhereLoop objects for a single table of the join where the table -** is idenfied by pBuilder->pNew->iTab. That table is guaranteed to be +** is identified by pBuilder->pNew->iTab. That table is guaranteed to be ** a b-tree table, not a virtual table. ** ** The costs (WhereLoop.rRun) of the b-tree loops added by this function @@ -2726,6 +2787,8 @@ static int whereLoopAddBtree( } rSize = pProbe->aiRowLogEst[0]; pNew->u.btree.nEq = 0; + pNew->u.btree.nBtm = 0; + pNew->u.btree.nTop = 0; pNew->nSkip = 0; pNew->nLTerm = 0; pNew->iSortIdx = 0; diff --git a/src/whereInt.h b/src/whereInt.h index 075c04e5e5..d288fa6192 100644 --- a/src/whereInt.h +++ b/src/whereInt.h @@ -122,6 +122,8 @@ struct WhereLoop { union { struct { /* Information for internal btree tables */ u16 nEq; /* Number of equality constraints */ + u16 nBtm; /* Size of BTM vector */ + u16 nTop; /* Size of TOP vector */ Index *pIndex; /* Index used, or NULL */ } btree; struct { /* Information for virtual tables */ diff --git a/src/wherecode.c b/src/wherecode.c index a017b40c7d..3060d8d324 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -861,6 +861,30 @@ static void codeDeferredSeek( } } +static void codeExprOrVector(Parse *pParse, Expr *p, int iReg, int nReg){ + assert( nReg>0 ); + if( p->flags & EP_Vector ){ + int i; + if( (p->flags & EP_xIsSelect)==0 ){ + ExprList *pList = p->x.pList; + assert( nReg<=pList->nExpr ); + for(i=0; ia[i].pExpr, iReg+i); + } + }else{ + Vdbe *v = pParse->pVdbe; + int iSelect = sqlite3CodeSubselect(pParse, p, 0, 0); + sqlite3VdbeAddOp3(v, OP_Copy, iSelect, iReg, nReg-1); + p->op2 = p->op; + p->op = TK_REGISTER; + p->iTable = iSelect; + } + }else{ + assert( nReg==1 ); + sqlite3ExprCode(pParse, p, iReg); + } +} + /* ** Generate code for the start of the iLevel-th loop in the WHERE clause ** implementation described by pWInfo. @@ -1185,6 +1209,8 @@ Bitmask sqlite3WhereCodeOneLoopStart( OP_IdxLT, /* 3: (end_constraints && bRev && endEq) */ }; u16 nEq = pLoop->u.btree.nEq; /* Number of == or IN terms */ + u16 nBtm = pLoop->u.btree.nBtm; /* Length of BTM vector */ + u16 nTop = pLoop->u.btree.nTop; /* Length of TOP vector */ int regBase; /* Base register holding constraint values */ WhereTerm *pRangeStart = 0; /* Inequality constraint at range start */ WhereTerm *pRangeEnd = 0; /* Inequality constraint at range end */ @@ -1231,14 +1257,14 @@ Bitmask sqlite3WhereCodeOneLoopStart( j = nEq; if( pLoop->wsFlags & WHERE_BTM_LIMIT ){ pRangeStart = pLoop->aLTerm[j++]; - nExtraReg = 1; + nExtraReg = MAX(nExtraReg, pLoop->u.btree.nBtm); /* Like optimization range constraints always occur in pairs */ assert( (pRangeStart->wtFlags & TERM_LIKEOPT)==0 || (pLoop->wsFlags & WHERE_TOP_LIMIT)!=0 ); } if( pLoop->wsFlags & WHERE_TOP_LIMIT ){ pRangeEnd = pLoop->aLTerm[j++]; - nExtraReg = 1; + nExtraReg = MAX(nExtraReg, pLoop->u.btree.nTop); #ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS if( (pRangeEnd->wtFlags & TERM_LIKEOPT)!=0 ){ assert( pRangeStart!=0 ); /* LIKE opt constraints */ @@ -1274,6 +1300,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( ){ SWAP(WhereTerm *, pRangeEnd, pRangeStart); SWAP(u8, bSeekPastNull, bStopAtNull); + SWAP(u8, nBtm, nTop); } /* Generate code to evaluate all constraint terms using == or IN @@ -1298,7 +1325,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( nConstraint = nEq; if( pRangeStart ){ Expr *pRight = pRangeStart->pExpr->pRight; - sqlite3ExprCode(pParse, pRight, regBase+nEq); + codeExprOrVector(pParse, pRight, regBase+nEq, nBtm); whereLikeOptimizationStringFixup(v, pLevel, pRangeStart); if( (pRangeStart->wtFlags & TERM_VNULL)==0 && sqlite3ExprCanBeNull(pRight) @@ -1317,8 +1344,13 @@ Bitmask sqlite3WhereCodeOneLoopStart( zStartAff[nEq] = SQLITE_AFF_BLOB; } } - nConstraint++; + nConstraint += nBtm; testcase( pRangeStart->wtFlags & TERM_VIRTUAL ); + if( (pRight->flags & EP_Vector)==0 ){ + disableTerm(pLevel, pRangeStart); + }else{ + startEq = 1; + } }else if( bSeekPastNull ){ sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq); nConstraint++; @@ -1350,7 +1382,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( if( pRangeEnd ){ Expr *pRight = pRangeEnd->pExpr->pRight; sqlite3ExprCacheRemove(pParse, regBase+nEq, 1); - sqlite3ExprCode(pParse, pRight, regBase+nEq); + codeExprOrVector(pParse, pRight, regBase+nEq, nTop); whereLikeOptimizationStringFixup(v, pLevel, pRangeEnd); if( (pRangeEnd->wtFlags & TERM_VNULL)==0 && sqlite3ExprCanBeNull(pRight) @@ -1363,8 +1395,14 @@ Bitmask sqlite3WhereCodeOneLoopStart( ){ codeApplyAffinity(pParse, regBase+nEq, 1, &cEndAff); } - nConstraint++; + nConstraint += nTop; testcase( pRangeEnd->wtFlags & TERM_VIRTUAL ); + + if( (pRight->flags & EP_Vector)==0 ){ + disableTerm(pLevel, pRangeEnd); + }else{ + endEq = 1; + } }else if( bStopAtNull ){ sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq); endEq = 0; @@ -1385,9 +1423,11 @@ Bitmask sqlite3WhereCodeOneLoopStart( testcase( op==OP_IdxLE ); VdbeCoverageIf(v, op==OP_IdxLE ); } + /* Disable the start and end range terms if possible */ + /* disableTerm(pLevel, pRangeStart); */ + /* disableTerm(pLevel, pRangeEnd); */ + /* Seek the table cursor, if required */ - disableTerm(pLevel, pRangeStart); - disableTerm(pLevel, pRangeEnd); if( omitTable ){ /* pIdx is a covering index. No need to access the main table. */ }else if( HasRowid(pIdx->pTable) ){ @@ -1411,9 +1451,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( iRowidReg, pPk->nKeyCol); VdbeCoverage(v); } - /* Record the instruction used to terminate the loop. Disable - ** WHERE clause terms made redundant by the index range scan. - */ + /* Record the instruction used to terminate the loop. */ if( pLoop->wsFlags & WHERE_ONEROW ){ pLevel->op = OP_Noop; }else if( bRev ){ diff --git a/src/whereexpr.c b/src/whereexpr.c index 1cb6be8458..35af70687b 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -95,7 +95,7 @@ static int whereClauseInsert(WhereClause *pWC, Expr *p, u16 wtFlags){ /* ** Return TRUE if the given operator is one of the operators that is ** allowed for an indexable WHERE clause term. The allowed operators are -** "=", "<", ">", "<=", ">=", "IN", and "IS NULL" +** "=", "<", ">", "<=", ">=", "IN", "IS", and "IS NULL" */ static int allowedOp(int op){ assert( TK_GT>TK_EQ && TK_GT, <, >= or <=), perform the processing + ** on the first element of the vector. */ + assert( TK_GT+1==TK_LE && TK_GT+2==TK_LT && TK_GT+3==TK_GE ); + if( (pExpr->flags & (EP_Vector|EP_xIsSelect))==EP_Vector + && (op>=TK_GT && op<=TK_GE) + ){ + pExpr = pExpr->x.pList->a[0].pExpr; + } + if( pExpr->op==TK_COLUMN ){ *piCur = pExpr->iTable; *piColumn = pExpr->iColumn; @@ -862,6 +874,17 @@ static int exprMightBeIndexed( return 0; } +static Expr *exprVectorExpr(Parse *pParse, Expr *p, int iField){ + Expr *pRet; + if( p->flags & EP_xIsSelect ){ + pRet = sqlite3PExpr(pParse, TK_SELECT_COLUMN, p, 0, 0); + if( pRet ) pRet->iColumn = iField; + }else{ + pRet = sqlite3ExprDup(pParse->db, p->x.pList->a[iField].pExpr, 0); + } + return pRet; +} + /* ** The input to this routine is an WhereTerm structure with only the ** "pExpr" field filled in. The job of this routine is to analyze the @@ -937,14 +960,14 @@ static void exprAnalyze( Expr *pLeft = sqlite3ExprSkipCollate(pExpr->pLeft); Expr *pRight = sqlite3ExprSkipCollate(pExpr->pRight); u16 opMask = (pTerm->prereqRight & prereqLeft)==0 ? WO_ALL : WO_EQUIV; - if( exprMightBeIndexed(pSrc, prereqLeft, pLeft, &iCur, &iColumn) ){ + if( exprMightBeIndexed(pSrc, op, prereqLeft, pLeft, &iCur, &iColumn) ){ pTerm->leftCursor = iCur; pTerm->u.leftColumn = iColumn; pTerm->eOperator = operatorMask(op) & opMask; } if( op==TK_IS ) pTerm->wtFlags |= TERM_IS; if( pRight - && exprMightBeIndexed(pSrc, pTerm->prereqRight, pRight, &iCur, &iColumn) + && exprMightBeIndexed(pSrc, op, pTerm->prereqRight, pRight, &iCur,&iColumn) ){ WhereTerm *pNew; Expr *pDup; @@ -1152,6 +1175,26 @@ static void exprAnalyze( } #endif /* SQLITE_OMIT_VIRTUALTABLE */ + if( pWC->op==TK_AND + && (pExpr->op==TK_EQ || pExpr->op==TK_IS) + && (pExpr->pLeft->flags & EP_Vector) + && ( (pExpr->pLeft->flags & EP_xIsSelect)==0 + || (pExpr->pRight->flags & EP_xIsSelect)==0 + )){ + int i; + for(i=0; ipLeft); i++){ + int idxNew; + Expr *pNew; + Expr *pLeft = exprVectorExpr(pParse, pExpr->pLeft, i); + Expr *pRight = exprVectorExpr(pParse, pExpr->pRight, i); + + pNew = sqlite3PExpr(pParse, pExpr->op, pLeft, pRight, 0); + idxNew = whereClauseInsert(pWC, pNew, TERM_VIRTUAL|TERM_DYNAMIC); + exprAnalyze(pSrc, pWC, idxNew); + markTermAsChild(pWC, idxNew, idxTerm); + } + } + #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 /* When sqlite_stat3 histogram data is available an operator of the ** form "x IS NOT NULL" can sometimes be evaluated more efficiently diff --git a/test/rowvalue.test b/test/rowvalue.test new file mode 100644 index 0000000000..3bfcfe2c12 --- /dev/null +++ b/test/rowvalue.test @@ -0,0 +1,123 @@ +# 2016 June 17 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements regression tests for SQLite library. The +# focus of this file is testing the SELECT statement. +# + + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set ::testprefix rowvalue + +do_execsql_test 0.0 { + CREATE TABLE one(o); + INSERT INTO one VALUES(1); +} + +foreach {tn v1 v2 eq ne is isnot} { + 1 "1, 2, 3" "1, 2, 3" 1 0 1 0 + 2 "1, 0, 3" "1, 2, 3" 0 1 0 1 + 3 "1, 2, NULL" "1, 2, 3" {} {} 0 1 + 4 "1, 2, NULL" "1, 2, NULL" {} {} 1 0 + 5 "NULL, NULL, NULL" "NULL, NULL, NULL" {} {} 1 0 +} { + do_execsql_test 1.$tn.eq "SELECT ($v1) == ($v2)" [list $eq] + do_execsql_test 1.$tn.ne "SELECT ($v1) != ($v2)" [list $ne] + + do_execsql_test 1.$tn.is "SELECT ($v1) IS ($v2)" [list $is] + do_execsql_test 1.$tn.isnot "SELECT ($v1) IS NOT ($v2)" [list $isnot] + + do_execsql_test 1.$tn.2.eq "SELECT (SELECT $v1) == (SELECT $v2)" [list $eq] + do_execsql_test 1.$tn.2.ne "SELECT (SELECT $v1) != (SELECT $v2)" [list $ne] +} + +foreach {tn v1 v2 lt gt le ge} { + 1 "(1, 1, 3)" "(1, 2, 3)" 1 0 1 0 + 2 "(1, 2, 3)" "(1, 2, 3)" 0 0 1 1 + 3 "(1, 3, 3)" "(1, 2, 3)" 0 1 0 1 + + 4 "(1, NULL, 3)" "(1, 2, 3)" {} {} {} {} + 5 "(1, 3, 3)" "(1, NULL, 3)" {} {} {} {} + 6 "(1, NULL, 3)" "(1, NULL, 3)" {} {} {} {} +} { + foreach {tn2 expr res} [list \ + 2.$tn.lt "$v1 < $v2" $lt \ + 2.$tn.gt "$v1 > $v2" $gt \ + 2.$tn.le "$v1 <= $v2" $le \ + 2.$tn.ge "$v1 >= $v2" $ge \ + ] { + do_execsql_test $tn2 "SELECT $expr" [list $res] + + set map(0) [list] + set map() [list] + set map(1) [list 1] + do_execsql_test $tn2.where1 "SELECT * FROM one WHERE $expr" $map($res) + + set map(0) [list 1] + set map() [list] + set map(1) [list] + do_execsql_test $tn2.where2 "SELECT * FROM one WHERE NOT $expr" $map($res) + } +} + +do_execsql_test 3.0 { + CREATE TABLE t1(x, y); + INSERT INTO t1 VALUES(1, 1); + INSERT INTO t1 VALUES(1, 2); + INSERT INTO t1 VALUES(2, 3); + INSERT INTO t1 VALUES(2, 4); + INSERT INTO t1 VALUES(3, 5); + INSERT INTO t1 VALUES(3, 6); +} + +foreach {tn r order} { + 1 "(1, 1)" "ORDER BY y" + 2 "(1, 1)" "ORDER BY x, y" + 3 "(1, 2)" "ORDER BY x, y DESC" + 4 "(3, 6)" "ORDER BY x DESC, y DESC" + 5 "((3, 5))" "ORDER BY x DESC, y" + 6 "(SELECT 3, 5)" "ORDER BY x DESC, y" +} { + do_execsql_test 3.$tn.1 "SELECT $r == (SELECT x,y FROM t1 $order)" 1 + do_execsql_test 3.$tn.2 "SELECT $r == (SELECT * FROM t1 $order)" 1 + + do_execsql_test 3.$tn.3 " + SELECT (SELECT * FROM t1 $order) == (SELECT * FROM t1 $order) + " 1 + do_execsql_test 3.$tn.4 " + SELECT (SELECT 0, 0) == (SELECT * FROM t1 $order) + " 0 +} + +foreach {tn expr res} { + 1 {(2, 2) BETWEEN (2, 2) AND (3, 3)} 1 + 2 {(2, 2) BETWEEN (2, NULL) AND (3, 3)} {} + 3 {(2, 2) BETWEEN (3, NULL) AND (3, 3)} 0 +} { + do_execsql_test 4.$tn "SELECT $expr" [list $res] +} + +foreach {tn expr res} { + 1 {(2, 4) IN (SELECT * FROM t1)} 1 + 2 {(3, 4) IN (SELECT * FROM t1)} 0 + + 3 {(NULL, 4) IN (SELECT * FROM t1)} {} + 4 {(NULL, 0) IN (SELECT * FROM t1)} 0 + + 5 {(NULL, 4) NOT IN (SELECT * FROM t1)} {} + 6 {(NULL, 0) NOT IN (SELECT * FROM t1)} 1 +} { + do_execsql_test 5.$tn "SELECT $expr" [list $res] +} + +finish_test + + diff --git a/test/rowvalue2.test b/test/rowvalue2.test new file mode 100644 index 0000000000..c7d061e3e2 --- /dev/null +++ b/test/rowvalue2.test @@ -0,0 +1,252 @@ +# 2016 June 17 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements regression tests for SQLite library. The +# focus of this file is testing the SELECT statement. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set ::testprefix rowvalue2 + +do_execsql_test 1.0 { + CREATE TABLE t1(a, b, c); + INSERT INTO t1 VALUES(0, 0, 0); + INSERT INTO t1 VALUES(0, 1, 1); + INSERT INTO t1 VALUES(1, 0, 2); + INSERT INTO t1 VALUES(1, 1, 3); + + CREATE INDEX i1 ON t1(a, b); +} + +do_execsql_test 1.1.1 { SELECT c FROM t1 WHERE (a, b) >= (1, 0) } {2 3} +do_execsql_test 1.1.2 { SELECT c FROM t1 WHERE (a, b) > (1, 0) } {3} + +#------------------------------------------------------------------------- + +do_execsql_test 2.0.1 { + CREATE TABLE t2(a INTEGER, b INTEGER, c INTEGER, d INTEGER); + CREATE INDEX i2 ON t2(a, b, c); +} +do_test 2.0.2 { + foreach a {0 1 2 3} { + foreach b {0 1 2 3} { + foreach c {0 1 2 3} { + execsql { INSERT INTO t2 VALUES($a, $b, $c, $c + $b*4 + $a*16); } + }}} +} {} + +do_execsql_test 2.1 { + SELECT d FROM t2 WHERE (a, b) > (2, 2); +} [db eval { SELECT d FROM t2 WHERE a>2 OR (a=2 AND b>2) }] + +do_execsql_test 2.2 { + SELECT d FROM t2 WHERE (a, b) >= (2, 2); +} [db eval { SELECT d FROM t2 WHERE a>2 OR (a=2 AND b>=2) }] + +do_execsql_test 2.3 { + SELECT d FROM t2 WHERE a=1 AND (b, c) >= (1, 2); +} [db eval { SELECT d FROM t2 WHERE +a=1 AND (b>1 OR (b==1 AND c>=2)) }] + +do_execsql_test 2.4 { + SELECT d FROM t2 WHERE a=1 AND (b, c) > (1, 2); +} [db eval { SELECT d FROM t2 WHERE +a=1 AND (b>1 OR (b==1 AND c>2)) }] + +#------------------------------------------------------------------------- + +set words { +airfare airfield airfields airflow airfoil +airfoils airframe airframes airily airing +airings airless airlift airlifts airline +airliner airlines airlock airlocks airmail +airmails airman airmen airplane airplanes + +arraignment arraignments arraigns arrange arranged +arrangement arrangements arranger arrangers arranges +arranging arrant array arrayed arrays +arrears arrest arrested arrester arresters +arresting arrestingly arrestor arrestors arrests + +edifices edit edited editing edition +editions editor editorial editorially editorials +editors edits educable educate educated +educates educating education educational educationally +educations educator educators eel eelgrass +} + +do_test 3.0 { + execsql { CREATE TABLE t3(a, b, c, w); } + foreach w $words { + set a [string range $w 0 2] + set b [string range $w 3 5] + set c [string range $w 6 end] + execsql { INSERT INTO t3 VALUES($a, $b, $c, $w) } + } +} {} + + +foreach {tn idx} { + IDX1 {} + IDX2 { CREATE INDEX i3 ON t3(a, b, c); } + IDX3 { CREATE INDEX i3 ON t3(a, b); } + IDX4 { CREATE INDEX i3 ON t3(a); } +} { + execsql { DROP INDEX IF EXISTS i3 } + execsql $idx + + foreach w $words { + set a [string range $w 0 2] + set b [string range $w 3 5] + set c [string range $w 6 end] + + foreach op [list > >= < <= == IS] { + do_execsql_test 3.1.$tn.$w.$op [subst -novar { + SELECT rowid FROM t3 WHERE (a, b, c) [set op] ($a, $b, $c) + ORDER BY +rowid + }] [db eval [subst -novar { + SELECT rowid FROM t3 WHERE w [set op] $w ORDER BY +rowid + }]] + + do_execsql_test 3.1.$tn.$w.$op.subselect [subst -novar { + SELECT rowid FROM t3 WHERE (a, b, c) [set op] ( + SELECT a, b, c FROM t3 WHERE w = $w + ) + ORDER BY +rowid + }] [db eval [subst -novar { + SELECT rowid FROM t3 WHERE w [set op] $w ORDER BY +rowid + }]] + } + + } +} + +#------------------------------------------------------------------------- +# + +do_execsql_test 4.0 { + CREATE TABLE t4(a, b, c); + INSERT INTO t4 VALUES(NULL, NULL, NULL); + INSERT INTO t4 VALUES(NULL, NULL, 0); + INSERT INTO t4 VALUES(NULL, NULL, 1); + INSERT INTO t4 VALUES(NULL, 0, NULL); + INSERT INTO t4 VALUES(NULL, 0, 0); + INSERT INTO t4 VALUES(NULL, 0, 1); + INSERT INTO t4 VALUES(NULL, 1, NULL); + INSERT INTO t4 VALUES(NULL, 1, 0); + INSERT INTO t4 VALUES(NULL, 1, 1); + + INSERT INTO t4 VALUES( 0, NULL, NULL); + INSERT INTO t4 VALUES( 0, NULL, 0); + INSERT INTO t4 VALUES( 0, NULL, 1); + INSERT INTO t4 VALUES( 0, 0, NULL); + INSERT INTO t4 VALUES( 0, 0, 0); + INSERT INTO t4 VALUES( 0, 0, 1); + INSERT INTO t4 VALUES( 0, 1, NULL); + INSERT INTO t4 VALUES( 0, 1, 0); + INSERT INTO t4 VALUES( 0, 1, 1); + + INSERT INTO t4 VALUES( 1, NULL, NULL); + INSERT INTO t4 VALUES( 1, NULL, 0); + INSERT INTO t4 VALUES( 1, NULL, 1); + INSERT INTO t4 VALUES( 1, 0, NULL); + INSERT INTO t4 VALUES( 1, 0, 0); + INSERT INTO t4 VALUES( 1, 0, 1); + INSERT INTO t4 VALUES( 1, 1, NULL); + INSERT INTO t4 VALUES( 1, 1, 0); + INSERT INTO t4 VALUES( 1, 1, 1); +} + +proc make_expr1 {cList vList op} { + return "([join $cList ,]) $op ([join $vList ,])" +} + +proc make_expr3 {cList vList op} { + set n [llength $cList] + + set aList [list] + foreach c [lrange $cList 0 end-1] v [lrange $vList 0 end-1] { + lappend aList "$c == $v" + } + lappend aList "[lindex $cList end] $op [lindex $vList end]" + + return "([join $aList { AND }])" +} + +proc make_expr2 {cList vList op} { + set ret "" + + switch -- $op { + == - IS { + set aList [list] + foreach c $cList v $vList { lappend aList "($c $op $v)" } + set ret [join $aList " AND "] + } + + < - > { + set oList [list] + for {set i 0} {$i < [llength $cList]} {incr i} { + lappend oList [make_expr3 [lrange $cList 0 $i] [lrange $vList 0 $i] $op] + } + set ret [join $oList " OR "] + } + + <= - >= { + set o2 [string range $op 0 0] + set oList [list] + for {set i 0} {$i < [llength $cList]-1} {incr i} { + lappend oList [make_expr3 [lrange $cList 0 $i] [lrange $vList 0 $i] $o2] + } + lappend oList [make_expr3 $cList $vList $op] + set ret [join $oList " OR "] + } + + + default { + error "Unknown op: $op" + } + } + + set ret +} + +foreach {tn idx} { + IDX1 {} + IDX2 { CREATE INDEX i4 ON t4(a, b, c); } + IDX3 { CREATE INDEX i4 ON t4(a, b); } + IDX4 { CREATE INDEX i4 ON t4(a); } +} { + execsql { DROP INDEX IF EXISTS i4 } + execsql $idx + + foreach {tn2 vector} { + 1 {0 0 0} + 2 {1 1 1} + 3 {0 0 NULL} + 4 {0 NULL 0} + 5 {NULL 0 0} + 6 {1 1 NULL} + 7 {1 NULL 1} + 8 {NULL 1 1} + } { + foreach op { IS == < <= > >= } { + set e1 [make_expr1 {a b c} $vector $op] + set e2 [make_expr2 {a b c} $vector $op] + + do_execsql_test 4.$tn.$tn2.$op \ + "SELECT rowid FROM t4 WHERE $e2 ORDER BY +rowid" [ + db eval "SELECT rowid FROM t4 WHERE $e1 ORDER BY +rowid" + ] + } + } +} + + +finish_test + diff --git a/tool/addopcodes.tcl b/tool/addopcodes.tcl index 9b34cf2e03..29409a4900 100644 --- a/tool/addopcodes.tcl +++ b/tool/addopcodes.tcl @@ -37,6 +37,7 @@ set extras { UMINUS UPLUS REGISTER + SELECT_COLUMN ASTERISK SPAN SPACE From e234cfd11f76cff3e7846c56eb1ddaeda3b33ac2 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Sun, 10 Jul 2016 19:35:10 +0000 Subject: [PATCH 0554/1484] Fix typos in comments. No changes to code. FossilOrigin-Name: 77c692a6704cd877ba35d0afb774ab9b46364d59 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/expr.c | 2 +- src/wherecode.c | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 679ecd4e0c..ad5811183a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\s"#/value-list/"\sstyle\sof\sresults\sfor\sapproximate\svalue\smatching\nin\sthe\sdo_test\scommand\sof\sthe\stest\sinfrastructure.\s\sUse\sthis\snew\sresult\sstyle\nto\smake\sthe\sSQLITE_DBSTATUS_CACHE_SIZE_SHARED\stests\scross-platform. -D 2016-07-09T17:47:01.013 +C Fix\stypos\sin\scomments.\s\sNo\schanges\sto\scode. +D 2016-07-10T19:35:10.288 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -337,7 +337,7 @@ F src/ctime.c 61949e83c4c36e37195a8398ebc752780b534d95 F src/date.c 1cc9fb516ec9932c6fd4d2a0d2f8bc4480145c39 F src/dbstat.c 4f6f7f52b49beb9636ffbd517cfe44a402ba4ad0 F src/delete.c 4aba4214a377ce8ddde2d2e609777bcc8235200f -F src/expr.c 523a5b1db2b6d88c6eefb224877bf635a3bcfc92 +F src/expr.c 21b153e1046c624e9387a17d3261f69b461e700c F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c bc4145347595b7770f9a598cff1c848302cf5413 F src/func.c 61a4114cf7004f10c542cfabbab9f2bcb9033045 @@ -465,7 +465,7 @@ F src/wal.h 6dd221ed384afdc204bc61e25c23ef7fd5a511f2 F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354 F src/where.c 48eed8ebe319c6cbc7bf7682018f32af0f5189f5 F src/whereInt.h e5b939701a7ceffc5a3a8188a37f9746416ebcd0 -F src/wherecode.c e20cb381ff621e56a4684c71e31999aca2547ca6 +F src/wherecode.c 11e38f5e2dc5c007143fbf7fdb14bca40a6b74ad F src/whereexpr.c d7dcbf14ce1b5876c1f76496162c30fcba669563 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -1505,7 +1505,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 29fb988f1afc3fe623097acee1a5d08bf8386626 -R 767a7d8abd9b9525d1b45069b4c3dba2 -U drh -Z df36acb2648e26f22b53c52b73476f6c +P c869bf34a8ee42ac6542862e59c7a4b89b042f79 +R e7b82c5fd816fe8e3d4680426d718eac +U mistachkin +Z bc88f0dbd9511ddf1cf929c200555b61 diff --git a/manifest.uuid b/manifest.uuid index d451076edf..d8458f4ae7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c869bf34a8ee42ac6542862e59c7a4b89b042f79 \ No newline at end of file +77c692a6704cd877ba35d0afb774ab9b46364d59 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index ce3a476561..ea52d66253 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1835,7 +1835,7 @@ int sqlite3FindInIndex(Parse *pParse, Expr *pX, u32 inFlags, int *prRhsHasNull){ /* If no preexisting index is available for the IN clause ** and IN_INDEX_NOOP is an allowed reply ** and the RHS of the IN operator is a list, not a subquery - ** and the RHS is not contant or has two or fewer terms, + ** and the RHS is not constant or has two or fewer terms, ** then it is not worth creating an ephemeral table to evaluate ** the IN operator so return IN_INDEX_NOOP. */ diff --git a/src/wherecode.c b/src/wherecode.c index a017b40c7d..0b307761be 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -569,7 +569,7 @@ static int codeAllEqualityTerms( ** expression: "x>='ABC' AND x<'abd'". But this requires that the range ** scan loop run twice, once for strings and a second time for BLOBs. ** The OP_String opcodes on the second pass convert the upper and lower -** bound string contants to blobs. This routine makes the necessary changes +** bound string constants to blobs. This routine makes the necessary changes ** to the OP_String opcodes for that to happen. ** ** Except, of course, if SQLITE_LIKE_DOESNT_MATCH_BLOBS is defined, then From dd703e22a5a0a7314dd75e32b816f51e9f586155 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 12 Jul 2016 19:54:49 +0000 Subject: [PATCH 0555/1484] Fix the error counter reset in Lemon generated parsers. This has no effect on SQLite. FossilOrigin-Name: 3ef93950d30b34d852d6bbc101d433a04112868a --- manifest | 14 +++++++------- manifest.uuid | 2 +- tool/lempar.c | 6 +++--- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index ad5811183a..0e13a77452 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\stypos\sin\scomments.\s\sNo\schanges\sto\scode. -D 2016-07-10T19:35:10.288 +C Fix\sthe\serror\scounter\sreset\sin\sLemon\sgenerated\sparsers.\s\sThis\shas\sno\seffect\non\sSQLite. +D 2016-07-12T19:54:49.418 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -1433,7 +1433,7 @@ F tool/genfkey.README cf68fddd4643bbe3ff8e31b8b6d8b0a1b85e20f4 F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5 F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce F tool/lemon.c 09a96bed19955697a5e20c49ad863ec2005815a2 -F tool/lempar.c 77c685a612526aae9c0d9b3175176e5bcd3854d0 +F tool/lempar.c 57ffa9852901f6abc45981f0d882f31d1ccb06c0 F tool/libvers.c caafc3b689638a1d88d44bc5f526c2278760d9b9 F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862 F tool/logest.c 11346aa019e2e77a00902aa7d0cabd27bd2e8cca @@ -1505,7 +1505,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P c869bf34a8ee42ac6542862e59c7a4b89b042f79 -R e7b82c5fd816fe8e3d4680426d718eac -U mistachkin -Z bc88f0dbd9511ddf1cf929c200555b61 +P 77c692a6704cd877ba35d0afb774ab9b46364d59 +R cb6d43e13605575cc663251c668c01f6 +U drh +Z 3209e04e0b1433ba8d0db8fc637ac637 diff --git a/manifest.uuid b/manifest.uuid index d8458f4ae7..bd8874819e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -77c692a6704cd877ba35d0afb774ab9b46364d59 \ No newline at end of file +3ef93950d30b34d852d6bbc101d433a04112868a \ No newline at end of file diff --git a/tool/lempar.c b/tool/lempar.c index 5232565f87..e0d0e88565 100644 --- a/tool/lempar.c +++ b/tool/lempar.c @@ -755,6 +755,9 @@ static void yy_accept( if( yyTraceFILE ){ fprintf(yyTraceFILE,"%sAccept!\n",yyTracePrompt); } +#endif +#ifndef YYNOERRORRECOVERY + yypParser->yyerrcnt = -1; #endif assert( yypParser->yytos==yypParser->yystack ); /* Here code is inserted which will be executed whenever the @@ -898,9 +901,6 @@ void Parse( ** they intend to abandon the parse upon the first syntax error seen. */ yy_syntax_error(yypParser,yymajor, yyminor); -#ifndef YYNOERRORRECOVERY - yypParser->yyerrcnt = -1; -#endif yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion); yymajor = YYNOCODE; From ce0442edf35bb166db7156bbe71da22e189dce78 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 13 Jul 2016 00:55:28 +0000 Subject: [PATCH 0556/1484] Fix header comments and remove an unnecessary version restriction from the carray() table-valued function implementation. FossilOrigin-Name: 021d0fb8d85e44839d2b4fdb90b15f0e1f2442e6 --- ext/misc/carray.c | 9 ++------- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 14 deletions(-) diff --git a/ext/misc/carray.c b/ext/misc/carray.c index b0c8be77d3..6fdbecf575 100644 --- a/ext/misc/carray.c +++ b/ext/misc/carray.c @@ -14,7 +14,7 @@ ** returns the values in a C-language array. ** Examples: ** -** SELECT * FROM array($ptr,5) +** SELECT * FROM carray($ptr,5) ** ** The query above returns 5 integers contained in a C-language array ** at the address $ptr. $ptr is a pointer to the array of integers that @@ -24,7 +24,7 @@ ** the C-language array. Allowed values of the third parameter are ** 'int32', 'int64', 'double', 'char*'. Example: ** -** SELECT * FROM array($ptr,10,'char*'); +** SELECT * FROM carray($ptr,10,'char*'); ** ** HOW IT WORKS ** @@ -358,11 +358,6 @@ int sqlite3_carray_init( int rc = SQLITE_OK; SQLITE_EXTENSION_INIT2(pApi); #ifndef SQLITE_OMIT_VIRTUALTABLE - if( sqlite3_libversion_number()<3008012 ){ - *pzErrMsg = sqlite3_mprintf( - "carray() requires SQLite 3.8.12 or later"); - return SQLITE_ERROR; - } rc = sqlite3_create_module(db, "carray", &carrayModule, 0); #endif return rc; diff --git a/manifest b/manifest index 0e13a77452..03d606189a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\serror\scounter\sreset\sin\sLemon\sgenerated\sparsers.\s\sThis\shas\sno\seffect\non\sSQLite. -D 2016-07-12T19:54:49.418 +C Fix\sheader\scomments\sand\sremove\san\sunnecessary\sversion\srestriction\sfrom\sthe\ncarray()\stable-valued\sfunction\simplementation. +D 2016-07-13T00:55:28.831 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -204,7 +204,7 @@ F ext/icu/README.txt d9fbbad0c2f647c3fdf715fc9fd64af53aedfc43 F ext/icu/icu.c 43df9d8ef2fae7a325100ebd713ab089dc829dd7 F ext/icu/sqliteicu.h 728867a802baa5a96de7495e9689a8e01715ef37 F ext/misc/amatch.c 211108e201105e4bb0c076527b8cfd34330fc234 -F ext/misc/carray.c 29f3b2dbb93b93cedcc571660203d1e24d921bd3 +F ext/misc/carray.c 214c9e9d909ceaae3b2f5f917cc2204deca85cc6 F ext/misc/closure.c 0d2a038df8fbae7f19de42e7c7d71f2e4dc88704 F ext/misc/compress.c 122faa92d25033d6c3f07c39231de074ab3d2e83 F ext/misc/csv.c b92692b057707f5b7bb91feaedde790b2e38304e @@ -1505,7 +1505,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 77c692a6704cd877ba35d0afb774ab9b46364d59 -R cb6d43e13605575cc663251c668c01f6 +P 3ef93950d30b34d852d6bbc101d433a04112868a +R 51e8986673c5be3a3aaceb79764f3cbc U drh -Z 3209e04e0b1433ba8d0db8fc637ac637 +Z 12b2ac3f05d95585a2345745d9c04f9c diff --git a/manifest.uuid b/manifest.uuid index bd8874819e..f56a99a1c0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3ef93950d30b34d852d6bbc101d433a04112868a \ No newline at end of file +021d0fb8d85e44839d2b4fdb90b15f0e1f2442e6 \ No newline at end of file From a0620acc4a2da6aa017e3ac8b017b63d8a7d01f7 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 13 Jul 2016 13:05:13 +0000 Subject: [PATCH 0557/1484] Fix harmless compiler warnings in shell.c for NetBSD. FossilOrigin-Name: 824b39e54fb9ba562be4d92cc9a54aee1cdf84cb --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/shell.c | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 03d606189a..c9585f19cd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sheader\scomments\sand\sremove\san\sunnecessary\sversion\srestriction\sfrom\sthe\ncarray()\stable-valued\sfunction\simplementation. -D 2016-07-13T00:55:28.831 +C Fix\sharmless\scompiler\swarnings\sin\sshell.c\sfor\sNetBSD. +D 2016-07-13T13:05:13.449 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -384,7 +384,7 @@ F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c cca3aa77b95706df5d635a2141a4d1de60ae6598 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c f3c6e9065fb34f6a23af27ec7f1f717ffbfc2ee4 -F src/shell.c 14ff7f660530a52b117d110ba3390b7b2eb719b6 +F src/shell.c a8a9e392a6a2777fabf5feb536931cb190f235e5 F src/sqlite.h.in b9ba728c1083b7a8ab5f6a628b25cd2a00325fbf F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 2a170163d121095c6ab1ef05ed0413722f391d01 @@ -1505,7 +1505,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 3ef93950d30b34d852d6bbc101d433a04112868a -R 51e8986673c5be3a3aaceb79764f3cbc +P 021d0fb8d85e44839d2b4fdb90b15f0e1f2442e6 +R f2c7097376b33c065f9732879605d098 U drh -Z 12b2ac3f05d95585a2345745d9c04f9c +Z e160e6d632f23e86ebc551e9950cc211 diff --git a/manifest.uuid b/manifest.uuid index f56a99a1c0..6b7a74bfc9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -021d0fb8d85e44839d2b4fdb90b15f0e1f2442e6 \ No newline at end of file +824b39e54fb9ba562be4d92cc9a54aee1cdf84cb \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 5148177372..874782c5f1 100644 --- a/src/shell.c +++ b/src/shell.c @@ -2946,10 +2946,10 @@ static int db_int(ShellState *p, const char *zSql){ /* ** Convert a 2-byte or 4-byte big-endian integer into a native integer */ -unsigned int get2byteInt(unsigned char *a){ +static unsigned int get2byteInt(unsigned char *a){ return (a[0]<<8) + a[1]; } -unsigned int get4byteInt(unsigned char *a){ +static unsigned int get4byteInt(unsigned char *a){ return (a[0]<<24) + (a[1]<<16) + (a[2]<<8) + a[3]; } From cfbb5e82db9f7af586883ea886a927ac5460924a Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 13 Jul 2016 19:48:13 +0000 Subject: [PATCH 0558/1484] Modifications towards better vector IN(...) support on this branch. Not activated yet. FossilOrigin-Name: 34e35c71b25b0aa2d8931040feb260a78cc48c49 --- manifest | 14 +++---- manifest.uuid | 2 +- src/expr.c | 105 ++++++++++++++++++++++++++++++++++++-------------- 3 files changed, 84 insertions(+), 37 deletions(-) diff --git a/manifest b/manifest index 43f53685aa..c71b40dd0d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\scomment\stypo\sfixes\sfrom\strunk. -D 2016-07-10T19:35:45.597 +C Modifications\stowards\sbetter\svector\sIN(...)\ssupport\son\sthis\sbranch.\sNot\sactivated\syet. +D 2016-07-13T19:48:13.115 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -337,7 +337,7 @@ F src/ctime.c 61949e83c4c36e37195a8398ebc752780b534d95 F src/date.c 1cc9fb516ec9932c6fd4d2a0d2f8bc4480145c39 F src/dbstat.c 4f6f7f52b49beb9636ffbd517cfe44a402ba4ad0 F src/delete.c 4aba4214a377ce8ddde2d2e609777bcc8235200f -F src/expr.c 330854fe9fdea1d244abaef6d680f6b91df07cb4 +F src/expr.c 939362d26f5e99a4802ae94ae6e47d4def72b8f3 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c bc4145347595b7770f9a598cff1c848302cf5413 F src/func.c 61a4114cf7004f10c542cfabbab9f2bcb9033045 @@ -1507,7 +1507,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b2204215b231202aef7a218411cc2ddaecf28f35 77c692a6704cd877ba35d0afb774ab9b46364d59 -R 1a7620cc6269220b48a9fcbcbb9b68d1 -U mistachkin -Z cf1dd7dc395b0586dda9fa40ccf71a27 +P 728c5aa436a5f55c86b019c415a2b71d1b0a8fd6 +R 6c0b20cb1573f5c43e78ae5a07a06597 +U dan +Z 35590bc4128842477cd3208768d4edc0 diff --git a/manifest.uuid b/manifest.uuid index b148ca6043..722c9bb7cc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -728c5aa436a5f55c86b019c415a2b71d1b0a8fd6 \ No newline at end of file +34e35c71b25b0aa2d8931040feb260a78cc48c49 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 7941c228fd..c43c6c04de 100644 --- a/src/expr.c +++ b/src/expr.c @@ -309,6 +309,12 @@ static int codeCompare( return addr; } +/* +** If the expression passed as the only argument is of type TK_VECTOR +** return the number of expressions in the vector. Or, if the expression +** is a sub-select, return the number of columns in the sub-select. For +** any other type of expression, return 1. +*/ int sqlite3ExprVectorSize(Expr *pExpr){ if( (pExpr->flags & EP_Vector)==0 ) return 1; if( pExpr->flags & EP_xIsSelect ){ @@ -318,7 +324,10 @@ int sqlite3ExprVectorSize(Expr *pExpr){ } static Expr *exprVectorField(Expr *pVector, int i){ - if( pVector->flags & EP_xIsSelect ){ + if( (pVector->flags & EP_Vector)==0 ){ + assert( i==0 ); + return pVector; + }else if( pVector->flags & EP_xIsSelect ){ return pVector->x.pSelect->pEList->a[i].pExpr; } return pVector->x.pList->a[i].pExpr; @@ -1703,12 +1712,12 @@ int sqlite3IsRowid(const char *z){ ** table, then return NULL. */ #ifndef SQLITE_OMIT_SUBQUERY -static Select *isCandidateForInOpt(Expr *pX){ +static Select *isCandidateForInOpt(Expr *pX, int bNullSensitive){ Select *p; SrcList *pSrc; ExprList *pEList; - Expr *pRes; Table *pTab; + int i; if( !ExprHasProperty(pX, EP_xIsSelect) ) return 0; /* Not a subquery */ if( ExprHasProperty(pX, EP_VarSelect) ) return 0; /* Correlated subq */ p = pX->x.pSelect; @@ -1731,10 +1740,18 @@ static Select *isCandidateForInOpt(Expr *pX){ assert( pTab->pSelect==0 ); /* FROM clause is not a view */ if( IsVirtual(pTab) ) return 0; /* FROM clause not a virtual table */ pEList = p->pEList; - if( pEList->nExpr!=1 ) return 0; /* One column in the result set */ - pRes = pEList->a[0].pExpr; - if( pRes->op!=TK_COLUMN ) return 0; /* Result is a column */ - assert( pRes->iTable==pSrc->a[0].iCursor ); /* Not a correlated subquery */ + + /* All SELECT results must be columns. If the SELECT returns more than + ** one column and the bNullSensitive flag is set, all returned columns + ** must be declared NOT NULL. */ + for(i=0; inExpr; i++){ + Expr *pRes = pEList->a[i].pExpr; + if( pRes->op!=TK_COLUMN ) return 0; + assert( pRes->iTable==pSrc->a[0].iCursor ); /* Not a correlated subquery */ + if( pEList->nExpr>1 && bNullSensitive ){ + if( pTab->aCol[pRes->iColumn].notNull==0 ) return 0; + } + } return p; } #endif /* SQLITE_OMIT_SUBQUERY */ @@ -1867,20 +1884,18 @@ int sqlite3FindInIndex(Parse *pParse, Expr *pX, u32 inFlags, int *prRhsHasNull){ ** satisfy the query. This is preferable to generating a new ** ephemeral table. */ - if( pParse->nErr==0 && (p = isCandidateForInOpt(pX))!=0 ){ + if( pParse->nErr==0 && (p = isCandidateForInOpt(pX, prRhsHasNull!=0))!=0 ){ sqlite3 *db = pParse->db; /* Database connection */ Table *pTab; /* Table . */ - Expr *pExpr; /* Expression */ - i16 iCol; /* Index of column */ + ExprList *pEList = p->pEList; + int nExpr = pEList->nExpr; i16 iDb; /* Database idx for pTab */ assert( p->pEList!=0 ); /* Because of isCandidateForInOpt(p) */ assert( p->pEList->a[0].pExpr!=0 ); /* Because of isCandidateForInOpt(p) */ assert( p->pSrc!=0 ); /* Because of isCandidateForInOpt(p) */ pTab = p->pSrc->a[0].pTab; - pExpr = p->pEList->a[0].pExpr; - iCol = (i16)pExpr->iColumn; - + /* Code an OP_Transaction and OP_TableLock for
    . */ iDb = sqlite3SchemaToIndex(db, pTab->pSchema); sqlite3CodeVerifySchema(pParse, iDb); @@ -1891,7 +1906,7 @@ int sqlite3FindInIndex(Parse *pParse, Expr *pX, u32 inFlags, int *prRhsHasNull){ ** successful here. */ assert(v); - if( iCol<0 ){ + if( nExpr==1 && pEList->a[0].pExpr->iColumn<0 ){ int iAddr = sqlite3CodeOnce(pParse); VdbeCoverage(v); @@ -1901,23 +1916,54 @@ int sqlite3FindInIndex(Parse *pParse, Expr *pX, u32 inFlags, int *prRhsHasNull){ sqlite3VdbeJumpHere(v, iAddr); }else{ Index *pIdx; /* Iterator variable */ + int affinity_ok = 1; + int i; + + /* Check that the affinity that will be used to perform each + ** comparison is the same as the affinity of each column. If + ** it not, it is not possible to use any index. */ + for(i=0; ipLeft, i); + int iCol = pEList->a[i].pExpr->iColumn; + char idxaff = pTab->aCol[iCol].affinity; + char cmpaff = sqlite3CompareAffinity(pLhs, idxaff); + switch( cmpaff ){ + case SQLITE_AFF_BLOB: + break; + case SQLITE_AFF_TEXT: + affinity_ok = (idxaff==SQLITE_AFF_TEXT); + break; + default: + affinity_ok = sqlite3IsNumericAffinity(idxaff); + } + } /* The collation sequence used by the comparison. If an index is to ** be used in place of a temp-table, it must be ordered according ** to this collation sequence. */ - CollSeq *pReq = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pExpr); - - /* Check that the affinity that will be used to perform the - ** comparison is the same as the affinity of the column. If - ** it is not, it is not possible to use any index. - */ - int affinity_ok = sqlite3IndexAffinityOk(pX, pTab->aCol[iCol].affinity); for(pIdx=pTab->pIndex; pIdx && eType==0 && affinity_ok; pIdx=pIdx->pNext){ - if( (pIdx->aiColumn[0]==iCol) - && sqlite3FindCollSeq(db, ENC(db), pIdx->azColl[0], 0)==pReq - && (!mustBeUnique || (pIdx->nKeyCol==1 && IsUniqueIndex(pIdx))) - ){ + if( pIdx->nKeyColnKeyCol!=nExpr || !IsUniqueIndex(pIdx)) ){ + continue; + } + + for(i=0; ipLeft, i); + Expr *pRhs = pEList->a[i].pExpr; + CollSeq *pReq = sqlite3BinaryCompareCollSeq(pParse, pLhs, pRhs); + int j; + + for(j=0; jaiColumn[j]!=pRhs->iColumn ) continue; + assert( pIdx->azColl[j] ); + if( sqlite3StrICmp(pReq->zName, pIdx->azColl[j])!=0 ) continue; + break; + } + if( j==nExpr ) break; + } + + if( i==nExpr ){ int iAddr = sqlite3CodeOnce(pParse); VdbeCoverage(v); sqlite3VdbeAddOp3(v, OP_OpenRead, iTab, pIdx->tnum, iDb); sqlite3VdbeSetP4KeyInfo(pParse, pIdx); @@ -1925,11 +1971,13 @@ int sqlite3FindInIndex(Parse *pParse, Expr *pX, u32 inFlags, int *prRhsHasNull){ assert( IN_INDEX_INDEX_DESC == IN_INDEX_INDEX_ASC+1 ); eType = IN_INDEX_INDEX_ASC + pIdx->aSortOrder[0]; - if( prRhsHasNull && !pTab->aCol[iCol].notNull ){ + if( prRhsHasNull && nExpr==1 + && !pTab->aCol[pEList->a[0].pExpr->iColumn].notNull + ){ #ifdef SQLITE_ENABLE_COLUMN_USED_MASK - const i64 sOne = 1; + i64 mask = (1<nMem; sqlite3SetHasNullFlag(v, iTab, *prRhsHasNull); @@ -1954,7 +2002,6 @@ int sqlite3FindInIndex(Parse *pParse, Expr *pX, u32 inFlags, int *prRhsHasNull){ ){ eType = IN_INDEX_NOOP; } - if( eType==0 ){ /* Could not find an existing table or index to use as the RHS b-tree. From ed916ba02514b2714e61e91eb478e4d2d6f243df Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 13 Jul 2016 21:30:03 +0000 Subject: [PATCH 0559/1484] Interface design for a new sqlite3_trace_v2() method that supersedes sqlite3_trace() and sqlite3_profile(). FossilOrigin-Name: 0c569f759f6c4701321d7fea5e7ccb371743bb6b --- manifest | 15 ++++--- manifest.uuid | 2 +- src/sqlite.h.in | 108 +++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 116 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index c9585f19cd..91d158c9f4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\scompiler\swarnings\sin\sshell.c\sfor\sNetBSD. -D 2016-07-13T13:05:13.449 +C Interface\sdesign\sfor\sa\snew\ssqlite3_trace_v2()\smethod\sthat\ssupersedes\nsqlite3_trace()\sand\ssqlite3_profile(). +D 2016-07-13T21:30:03.340 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -385,7 +385,7 @@ F src/resolve.c cca3aa77b95706df5d635a2141a4d1de60ae6598 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c f3c6e9065fb34f6a23af27ec7f1f717ffbfc2ee4 F src/shell.c a8a9e392a6a2777fabf5feb536931cb190f235e5 -F src/sqlite.h.in b9ba728c1083b7a8ab5f6a628b25cd2a00325fbf +F src/sqlite.h.in 63774172623fe82336ad0757f373343a87bd0b36 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 2a170163d121095c6ab1ef05ed0413722f391d01 F src/sqliteInt.h dcf43b8abc5605b70f54ba80f42b6ad054b8ba95 @@ -1505,7 +1505,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 021d0fb8d85e44839d2b4fdb90b15f0e1f2442e6 -R f2c7097376b33c065f9732879605d098 +P 824b39e54fb9ba562be4d92cc9a54aee1cdf84cb +R eb1a84643390ea5aba50eced8805fb76 +T *branch * sqlite3_trace_v2 +T *sym-sqlite3_trace_v2 * +T -sym-trunk * U drh -Z e160e6d632f23e86ebc551e9950cc211 +Z 6025cf3e994164a26dea4fb0e96d3f78 diff --git a/manifest.uuid b/manifest.uuid index 6b7a74bfc9..42e31abf53 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -824b39e54fb9ba562be4d92cc9a54aee1cdf84cb \ No newline at end of file +0c569f759f6c4701321d7fea5e7ccb371743bb6b \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 12a07a9b4a..a3b8f31f07 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -2755,6 +2755,9 @@ int sqlite3_set_authorizer( ** CAPI3REF: Tracing And Profiling Functions ** METHOD: sqlite3 ** +** These routines are deprecated. Use the [sqlite3_trace_v2()] interface +** instead of the routines described here. +** ** These routines register callback functions that can be used for ** tracing and profiling the execution of SQL statements. ** @@ -2780,10 +2783,111 @@ int sqlite3_set_authorizer( ** sqlite3_profile() function is considered experimental and is ** subject to change in future versions of SQLite. */ -void *sqlite3_trace(sqlite3*, void(*xTrace)(void*,const char*), void*); -SQLITE_EXPERIMENTAL void *sqlite3_profile(sqlite3*, +SQLITE_DEPRECATED void *sqlite3_trace(sqlite3*, + void(*xTrace)(void*,const char*), void*); +SQLITE_DEPRECATED void *sqlite3_profile(sqlite3*, void(*xProfile)(void*,const char*,sqlite3_uint64), void*); +/* +** CAPI3REF: SQL Trace Event Codes +** KEYWORDS: SQLITE_TRACE +** +** These constants identify classes of events that can be monitored +** using the [sqlite3_trace_v2()] tracing logic. The third argument +** to [sqlite3_trace_v2()] is an OR-ed combination of one or more of +** the following constants. The first argument to the trace callback +** is one of the following constants. +** +** New tracing constants may be added in future releases. +** +** A trace callback has four arguments: xCallback(T,C,P,X). +** The T argument is one of the integer type codes above. +** The C argument is a copy of the context pointer passed in as the +** fourth argument to [sqlite3_trace_v2()]. +** The P argument is a pointer whose meaning depends on T. +** The X argument is an unsigned 64-bit integer whose meaning also +** depends on T. +** +**
    +** [[SQLITE_TRACE_SQL]]
    SQLITE_TRACE_SQL
    +**
    An SQLITE_TRACE_SQL callback provides the same functionality +** as the legacy [sqlite3_trace()] callback. +** The P argument is a pointer to the constant UTF-8 string that is text +** describing an SQL statement that is starting to run with all +** [bound parameter] expanded. The X argument is unused. The size +** of the expansion of [bound parameters] is limited by the +** [SQLITE_TRACE_SIZE_LIMIT] compile-time option. +** +** [[SQLITE_TRACE_STMT]]
    SQLITE_TRACE_STMT
    +**
    An SQLITE_TRACE_STMT callback is invoked on the same occasions +** as SQLITE_TRACE_SQL. The difference is that the P argument is a +** pointer to the [prepared statement] rather than an SQL string. +** The X argument is unused. +** +** [[SQLITE_TRACE_PROFILE]]
    SQLITE_TRACE_PROFILE
    +**
    An SQLITE_TRACE_PROFILE callback provides approximately the same +** information as is provided by the [sqlite3_profile()] callback. +** The P argument is a pointer to the [prepared statement] and the +** X argument is an estimate of the number of nanosecond for which +** the prepared statement ran. The SQLITE_TRACE_PROFILE callback is +** invoked when the statement finishes. +** +** [[SQLITE_TRACE_ROW]]
    SQLITE_TRACE_ROW
    +**
    An SQLITE_TRACE_ROW callback is invoked whenever a prepared +** statement generates a single row of result. +** The P argument is a pointer to the [prepared statement] and the +** X argument is unused. +** +** [[SQLITE_TRACE_CLOSE]]
    SQLITE_TRACE_CLOSE
    +**
    An SQLITE_TRACE_CLOSE callback is invoked when a database +** connection closes. +** The P argument is a pointer to the [database connection] object +** and the X argument is unused. +**
    +*/ +#define SQLITE_TRACE_SQL 0x0001 +#define SQLITE_TRACE_STMT 0x0002 +#define SQLITE_TRACE_PROFILE 0x0004 +#define SQLITE_TRACE_ROW 0x0008 +#define SQLITE_TRACE_CLOSE 0x0010 + +/* +** CAPI3REF: SQL Trace Hook +** METHOD: sqlite3 +** +** The sqlite3_trace_v2(D,X,M,P) interface registers a trace callback +** function X against [database connection] D, using property mask M +** and context pointer P. If the X callback is +** NULL or if the M mask is zero, then tracing is disabled. The +** M argument must be one or more of the [SQLITE_TRACE] +** constants. +** +** Each call to either sqlite3_trace() or sqlite3_trace_v2() overrides +** (cancels) any prior calls to sqlite3_trace() or sqlite3_trace_v2(). +** +** The X callback is invoked whenever any of the events identified by +** mask M occur. The integer return value from the callback is currently +** ignored, though this may change in future releases. Callback +** implementations should return zero to ensure future compatibility. +** +** A trace callback is invoked with four arguments: callback(T,C,P,X). +** The T argument is one of the [SQLITE_TRACE] +** constants to indicate why the callback was invoked. +** The C argument is a copy of the context pointer. +** The P and X arguments are a pointer and an unsigned 64-bit integer +** whose meanings depend on T. +** +** The sqlite3_trace_v2() interface is intended to replace the legacy +** interfaces [sqlite3_trace()] and [sqlite3_profile()], both of which +** are deprecated. +*/ +int sqlite3_trace_v2( + sqlite3*, + int(*xCallback)(unsigned,void*,void*,sqlite3_uint64), + unsigned uMask, + void *pCtx +); + /* ** CAPI3REF: Query Progress Callbacks ** METHOD: sqlite3 From 3d2a529df6ce9cc3e9a11e5a2214eabfb35e0b77 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 13 Jul 2016 22:55:01 +0000 Subject: [PATCH 0560/1484] First cut at implementing the new sqlite3_trace_v2() interface. FossilOrigin-Name: cb0062feb018f52689938a58cb76886d431c33f0 --- manifest | 27 ++++++++++++--------------- manifest.uuid | 2 +- src/main.c | 31 ++++++++++++++++++++++++++++++- src/sqlite.h.in | 6 +++--- src/sqlite3ext.h | 5 +++++ src/sqliteInt.h | 12 +++++++++++- src/vacuum.c | 6 +++--- src/vdbe.c | 26 ++++++++++++++++++++++---- src/vdbeapi.c | 14 +++++++++++--- 9 files changed, 98 insertions(+), 31 deletions(-) diff --git a/manifest b/manifest index 91d158c9f4..bfca64b0a8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Interface\sdesign\sfor\sa\snew\ssqlite3_trace_v2()\smethod\sthat\ssupersedes\nsqlite3_trace()\sand\ssqlite3_profile(). -D 2016-07-13T21:30:03.340 +C First\scut\sat\simplementing\sthe\snew\ssqlite3_trace_v2()\sinterface. +D 2016-07-13T22:55:01.845 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -348,7 +348,7 @@ F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da F src/insert.c 8f4e9fcbd8e95e85f15647ba8b413b18d556ec2b F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e F src/loadext.c 4237fd37ca589f1d90b3ea925dd9df20da8e0c84 -F src/main.c 405d13e3a4f7c5add9fb27702ae70ed0a6e32cca +F src/main.c 05658dfa4be5704e4d6542fe0f2452be5b9df09e F src/malloc.c 1443d1ad95d67c21d77af7ae3f44678252f0efec F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b @@ -385,10 +385,10 @@ F src/resolve.c cca3aa77b95706df5d635a2141a4d1de60ae6598 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c f3c6e9065fb34f6a23af27ec7f1f717ffbfc2ee4 F src/shell.c a8a9e392a6a2777fabf5feb536931cb190f235e5 -F src/sqlite.h.in 63774172623fe82336ad0757f373343a87bd0b36 +F src/sqlite.h.in 0fde7379e6a9d900802976de51cb1256f0fdac59 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 -F src/sqlite3ext.h 2a170163d121095c6ab1ef05ed0413722f391d01 -F src/sqliteInt.h dcf43b8abc5605b70f54ba80f42b6ad054b8ba95 +F src/sqlite3ext.h 3875aa5b3c4bb5d8d14c387628c5fe852b2846bf +F src/sqliteInt.h 5b8a3e1dc92e7459b69954cce9f653bd2391deb8 F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c 5b18f9526900f61189ab0b83f1ef41d9f871a2ab F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 @@ -448,11 +448,11 @@ F src/trigger.c e14840ee0c3e549e758ec9bf3e4146e166002280 F src/update.c 4f05ea8cddfa367d045e03589756c02199e8f9bd F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 810ec3f22e2d1b62e66c30fe3621ebdedd23584d -F src/vacuum.c feb1eabb20987983d9350cad98299b21fa811f52 -F src/vdbe.c 22b46c3b725e950e9f2760e2d76953d592600ad4 +F src/vacuum.c 459ff7cb3c589451111ff2d3b6eb31be83a46a54 +F src/vdbe.c c6bb62aa69a6faf1197eee36336c6de99bb4733f F src/vdbe.h 67bc551f7faf04c33493892e4b378aada823ed10 F src/vdbeInt.h c59381049af5c7751a83456c39b80d1a6fde1f9d -F src/vdbeapi.c 02bcbc2ca5d2004b029088b05b468b394881e103 +F src/vdbeapi.c a466743c8e6de100c11e044b693c9469d2cf598a F src/vdbeaux.c c90275b0e55a2b32c03dc09314194fe46f2429d8 F src/vdbeblob.c 83d2d266383157b02e2b809350bb197e89d7895b F src/vdbemem.c 1ecaa5ee0caff07255f25d04e8dc88befb6f88d1 @@ -1505,10 +1505,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 824b39e54fb9ba562be4d92cc9a54aee1cdf84cb -R eb1a84643390ea5aba50eced8805fb76 -T *branch * sqlite3_trace_v2 -T *sym-sqlite3_trace_v2 * -T -sym-trunk * +P 0c569f759f6c4701321d7fea5e7ccb371743bb6b +R eeeb6e6908fe861e59edc045bbf20a73 U drh -Z 6025cf3e994164a26dea4fb0e96d3f78 +Z 1f8408ee484498502acfe0ea8cf0fbae diff --git a/manifest.uuid b/manifest.uuid index 42e31abf53..7db2593897 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0c569f759f6c4701321d7fea5e7ccb371743bb6b \ No newline at end of file +cb0062feb018f52689938a58cb76886d431c33f0 \ No newline at end of file diff --git a/src/main.c b/src/main.c index 30370f8cab..d2f8bf7996 100644 --- a/src/main.c +++ b/src/main.c @@ -1033,6 +1033,9 @@ static int sqlite3Close(sqlite3 *db, int forceZombie){ return SQLITE_MISUSE_BKPT; } sqlite3_mutex_enter(db->mutex); + if( db->mTrace & SQLITE_TRACE_CLOSE ){ + db->xTrace(SQLITE_TRACE_CLOSE, db->pTraceArg, db, 0); + } /* Force xDisconnect calls on all virtual tables */ disconnectAllVtab(db); @@ -1801,6 +1804,7 @@ int sqlite3_overload_function( ** trace is a pointer to a function that is invoked at the start of each ** SQL statement. */ +#ifndef SQLITE_OMIT_DEPRECATED void *sqlite3_trace(sqlite3 *db, void (*xTrace)(void*,const char*), void *pArg){ void *pOld; @@ -1812,11 +1816,36 @@ void *sqlite3_trace(sqlite3 *db, void (*xTrace)(void*,const char*), void *pArg){ #endif sqlite3_mutex_enter(db->mutex); pOld = db->pTraceArg; - db->xTrace = xTrace; + db->mTrace = SQLITE_TRACE_LEGACY; + db->xTrace = (int(*)(u32,void*,void*,i64))xTrace; db->pTraceArg = pArg; sqlite3_mutex_leave(db->mutex); return pOld; } +#endif /* SQLITE_OMIT_DEPRECATED */ + +/* Register a trace callback using the version-2 interface. +*/ +int sqlite3_trace_v2( + sqlite3 *db, /* Trace this connection */ + int(*xTrace)(unsigned,void*,void*,sqlite3_int64), /* Callback to invoke */ + unsigned mTrace, /* OPs to be traced */ + void *pArg /* Context */ +){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + sqlite3_mutex_enter(db->mutex); + db->mTrace = mTrace; + db->xTrace = xTrace; + db->pTraceArg = pArg; + sqlite3_mutex_leave(db->mutex); + return SQLITE_OK; +} + /* ** Register a profile function. The pArg from the previously registered ** profile function is returned. diff --git a/src/sqlite.h.in b/src/sqlite.h.in index a3b8f31f07..07d85b254d 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -2805,7 +2805,7 @@ SQLITE_DEPRECATED void *sqlite3_profile(sqlite3*, ** The C argument is a copy of the context pointer passed in as the ** fourth argument to [sqlite3_trace_v2()]. ** The P argument is a pointer whose meaning depends on T. -** The X argument is an unsigned 64-bit integer whose meaning also +** The X argument is an 64-bit integer whose meaning also ** depends on T. ** **
    @@ -2874,7 +2874,7 @@ SQLITE_DEPRECATED void *sqlite3_profile(sqlite3*, ** The T argument is one of the [SQLITE_TRACE] ** constants to indicate why the callback was invoked. ** The C argument is a copy of the context pointer. -** The P and X arguments are a pointer and an unsigned 64-bit integer +** The P and X arguments are a pointer and a 64-bit integer ** whose meanings depend on T. ** ** The sqlite3_trace_v2() interface is intended to replace the legacy @@ -2883,7 +2883,7 @@ SQLITE_DEPRECATED void *sqlite3_profile(sqlite3*, */ int sqlite3_trace_v2( sqlite3*, - int(*xCallback)(unsigned,void*,void*,sqlite3_uint64), + int(*xCallback)(unsigned,void*,void*,sqlite3_int64), unsigned uMask, void *pCtx ); diff --git a/src/sqlite3ext.h b/src/sqlite3ext.h index 2d38e87ae7..8bcfc68521 100644 --- a/src/sqlite3ext.h +++ b/src/sqlite3ext.h @@ -281,6 +281,9 @@ struct sqlite3_api_routines { int (*db_cacheflush)(sqlite3*); /* Version 3.12.0 and later */ int (*system_errno)(sqlite3*); + /* Version 3.14.0 and later */ + int (*trace_v2)(sqlite3*,int(*)(unsigned,void*,void*,sqlite3_uint64), + unsigned,void*); }; /* @@ -526,6 +529,8 @@ struct sqlite3_api_routines { #define sqlite3_db_cacheflush sqlite3_api->db_cacheflush /* Version 3.12.0 and later */ #define sqlite3_system_errno sqlite3_api->system_errno +/* Version 3.14.0 and later */ +#define sqlite3_trace_v2 sqlite3_api->trace_v2 #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 998a17dac3..225d7b2872 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1241,6 +1241,15 @@ void sqlite3CryptFunc(sqlite3_context*,int,sqlite3_value**); const char*); #endif +#ifndef SQLITE_OMIT_DEPRECATED +/* This is an extra SQLITE_TRACE macro that indicates "legacy" tracing +** in the style of sqlite3_trace() +*/ +#define SQLITE_TRACE_LEGACY 0x80 +#else +#define SQLITE_TRACE_LEGACY 0 +#endif /* SQLITE_OMIT_DEPRECATED */ + /* ** Each database connection is an instance of the following structure. @@ -1270,6 +1279,7 @@ struct sqlite3 { u8 suppressErr; /* Do not issue error messages if true */ u8 vtabOnConflict; /* Value to return for s3_vtab_on_conflict() */ u8 isTransactionSavepoint; /* True if the outermost savepoint is a TS */ + u8 mTrace; /* zero or more SQLITE_TRACE flags */ int nextPagesize; /* Pagesize after VACUUM if >0 */ u32 magic; /* Magic number for detect library misuse */ int nChange; /* Value returned by sqlite3_changes() */ @@ -1290,7 +1300,7 @@ struct sqlite3 { int nVDestroy; /* Number of active OP_VDestroy operations */ int nExtension; /* Number of loaded extensions */ void **aExtension; /* Array of shared library handles */ - void (*xTrace)(void*,const char*); /* Trace function */ + int (*xTrace)(u32,void*,void*,i64); /* Trace function */ void *pTraceArg; /* Argument to the trace function */ void (*xProfile)(void*,const char*,u64); /* Profiling function */ void *pProfileArg; /* Argument to profile function */ diff --git a/src/vacuum.c b/src/vacuum.c index bc7b5831b6..93b438fb1a 100644 --- a/src/vacuum.c +++ b/src/vacuum.c @@ -121,7 +121,7 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){ int saved_flags; /* Saved value of the db->flags */ int saved_nChange; /* Saved value of db->nChange */ int saved_nTotalChange; /* Saved value of db->nTotalChange */ - void (*saved_xTrace)(void*,const char*); /* Saved db->xTrace */ + u8 saved_mTrace; /* Saved trace settings */ Db *pDb = 0; /* Database to detach at end of vacuum */ int isMemDb; /* True if vacuuming a :memory: database */ int nRes; /* Bytes of reserved space at the end of each page */ @@ -142,7 +142,7 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){ saved_flags = db->flags; saved_nChange = db->nChange; saved_nTotalChange = db->nTotalChange; - saved_xTrace = db->xTrace; + saved_mTrace = db->mTrace; db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks | SQLITE_PreferBuiltin; db->flags &= ~(SQLITE_ForeignKeys | SQLITE_ReverseOrder); db->xTrace = 0; @@ -345,7 +345,7 @@ end_of_vacuum: db->flags = saved_flags; db->nChange = saved_nChange; db->nTotalChange = saved_nTotalChange; - db->xTrace = saved_xTrace; + db->mTrace = saved_mTrace; sqlite3BtreeSetPageSize(pMain, -1, -1, 1); /* Currently there is an SQL level transaction open on the vacuum diff --git a/src/vdbe.c b/src/vdbe.c index 6adbcbbec1..7883536028 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -1383,6 +1383,10 @@ case OP_ResultRow: { } if( db->mallocFailed ) goto no_mem; + if( db->mTrace & SQLITE_TRACE_ROW ){ + db->xTrace(SQLITE_TRACE_ROW, db->pTraceArg, p, 0); + } + /* Return SQLITE_ROW */ p->pc = (int)(pOp - aOp) + 1; @@ -6781,13 +6785,27 @@ case OP_Init: { /* jump */ char *z; #ifndef SQLITE_OMIT_TRACE - if( db->xTrace + if( (db->mTrace & (SQLITE_TRACE_SQL|SQLITE_TRACE_STMT|SQLITE_TRACE_LEGACY))!=0 && !p->doingRerun && (zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0 ){ - z = sqlite3VdbeExpandSql(p, zTrace); - db->xTrace(db->pTraceArg, z); - sqlite3DbFree(db, z); + if( db->mTrace & (SQLITE_TRACE_SQL|SQLITE_TRACE_LEGACY) ){ + z = sqlite3VdbeExpandSql(p, zTrace); +#ifndef SQLITE_OMIT_DEPRECATED + if( SQLITE_TRACE_LEGACY ){ + void (*x)(void*,const char*); + x = (void(*)(void*,const char*))db->xTrace; + x(db->pTraceArg, z); + }else +#endif + { + db->xTrace(SQLITE_TRACE_SQL,db->pTraceArg,z,0); + } + sqlite3DbFree(db, z); + } + if( db->mTrace & SQLITE_TRACE_STMT ){ + (void)db->xTrace(SQLITE_TRACE_STMT,db->pTraceArg,p,0); + } } #ifdef SQLITE_USE_FCNTL_TRACE zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql); diff --git a/src/vdbeapi.c b/src/vdbeapi.c index 83718eae39..a602fad383 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -60,12 +60,19 @@ static int vdbeSafetyNotNull(Vdbe *p){ */ static SQLITE_NOINLINE void invokeProfileCallback(sqlite3 *db, Vdbe *p){ sqlite3_int64 iNow; + sqlite3_int64 iElapse; assert( p->startTime>0 ); - assert( db->xProfile!=0 ); + assert( db->xProfile!=0 || (db->mTrace & SQLITE_TRACE_PROFILE)!=0 ); assert( db->init.busy==0 ); assert( p->zSql!=0 ); sqlite3OsCurrentTimeInt64(db->pVfs, &iNow); - db->xProfile(db->pProfileArg, p->zSql, (iNow - p->startTime)*1000000); + iElapse = (iNow - p->startTime)*1000000; + if( db->xProfile ){ + db->xProfile(db->pProfileArg, p->zSql, iElapse); + } + if( db->mTrace & SQLITE_TRACE_PROFILE ){ + db->xTrace(SQLITE_TRACE_PROFILE, db->pTraceArg, p, iElapse); + } p->startTime = 0; } /* @@ -569,7 +576,8 @@ static int sqlite3Step(Vdbe *p){ ); #ifndef SQLITE_OMIT_TRACE - if( db->xProfile && !db->init.busy && p->zSql ){ + if( (db->xProfile || (db->mTrace & SQLITE_TRACE_PROFILE)!=0) + && !db->init.busy && p->zSql ){ sqlite3OsCurrentTimeInt64(db->pVfs, &p->startTime); }else{ assert( p->startTime==0 ); From 1637a5171f25bd6d5eb4e04dc855776c3af2c1da Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 13 Jul 2016 23:18:27 +0000 Subject: [PATCH 0561/1484] Legacy tests now passing. FossilOrigin-Name: f33526a341132435cb4185149a784eef6b3a1a2d --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/main.c | 2 +- src/vacuum.c | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index bfca64b0a8..a7725c09a7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C First\scut\sat\simplementing\sthe\snew\ssqlite3_trace_v2()\sinterface. -D 2016-07-13T22:55:01.845 +C Legacy\stests\snow\spassing. +D 2016-07-13T23:18:27.653 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -348,7 +348,7 @@ F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da F src/insert.c 8f4e9fcbd8e95e85f15647ba8b413b18d556ec2b F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e F src/loadext.c 4237fd37ca589f1d90b3ea925dd9df20da8e0c84 -F src/main.c 05658dfa4be5704e4d6542fe0f2452be5b9df09e +F src/main.c a3be9a816c72fe658838e33e42afabfff93526f2 F src/malloc.c 1443d1ad95d67c21d77af7ae3f44678252f0efec F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b @@ -448,7 +448,7 @@ F src/trigger.c e14840ee0c3e549e758ec9bf3e4146e166002280 F src/update.c 4f05ea8cddfa367d045e03589756c02199e8f9bd F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 810ec3f22e2d1b62e66c30fe3621ebdedd23584d -F src/vacuum.c 459ff7cb3c589451111ff2d3b6eb31be83a46a54 +F src/vacuum.c 544ec90a66a4b0460b7c1baeadbc21b45e6ca0b6 F src/vdbe.c c6bb62aa69a6faf1197eee36336c6de99bb4733f F src/vdbe.h 67bc551f7faf04c33493892e4b378aada823ed10 F src/vdbeInt.h c59381049af5c7751a83456c39b80d1a6fde1f9d @@ -1505,7 +1505,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 0c569f759f6c4701321d7fea5e7ccb371743bb6b -R eeeb6e6908fe861e59edc045bbf20a73 +P cb0062feb018f52689938a58cb76886d431c33f0 +R d7e93f0729616f164eba3e9e1862aa07 U drh -Z 1f8408ee484498502acfe0ea8cf0fbae +Z a0be5e80cc5b797f562ce4c096d88be2 diff --git a/manifest.uuid b/manifest.uuid index 7db2593897..5103610b4f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cb0062feb018f52689938a58cb76886d431c33f0 \ No newline at end of file +f33526a341132435cb4185149a784eef6b3a1a2d \ No newline at end of file diff --git a/src/main.c b/src/main.c index d2f8bf7996..5969738f6b 100644 --- a/src/main.c +++ b/src/main.c @@ -1816,7 +1816,7 @@ void *sqlite3_trace(sqlite3 *db, void (*xTrace)(void*,const char*), void *pArg){ #endif sqlite3_mutex_enter(db->mutex); pOld = db->pTraceArg; - db->mTrace = SQLITE_TRACE_LEGACY; + db->mTrace = xTrace ? SQLITE_TRACE_LEGACY : 0; db->xTrace = (int(*)(u32,void*,void*,i64))xTrace; db->pTraceArg = pArg; sqlite3_mutex_leave(db->mutex); diff --git a/src/vacuum.c b/src/vacuum.c index 93b438fb1a..9ab7f766ee 100644 --- a/src/vacuum.c +++ b/src/vacuum.c @@ -145,7 +145,7 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){ saved_mTrace = db->mTrace; db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks | SQLITE_PreferBuiltin; db->flags &= ~(SQLITE_ForeignKeys | SQLITE_ReverseOrder); - db->xTrace = 0; + db->mTrace = 0; pMain = db->aDb[0].pBt; isMemDb = sqlite3PagerIsMemdb(sqlite3BtreePager(pMain)); From fca760c841227207bb8dd0dd43fb89a100ca18fb Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 14 Jul 2016 01:09:08 +0000 Subject: [PATCH 0562/1484] Add the sqlite3_expanded_sql() interface. Refinements to the sqlite3_trace_v2() interface to make it more useful. FossilOrigin-Name: 99ee7ee58d45b29a0000492306ddc0b90563ff51 --- manifest | 28 +++++++++---------- manifest.uuid | 2 +- src/main.c | 12 ++++---- src/sqlite.h.in | 71 +++++++++++++++++++++++++++--------------------- src/sqlite3ext.h | 5 ++-- src/sqliteInt.h | 2 +- src/test1.c | 21 ++++++++++++++ src/vdbe.c | 24 ++++++---------- src/vdbeapi.c | 2 +- src/vdbeaux.c | 15 ++++++++++ src/vdbetrace.c | 2 +- 11 files changed, 112 insertions(+), 72 deletions(-) diff --git a/manifest b/manifest index a7725c09a7..98c634e400 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Legacy\stests\snow\spassing. -D 2016-07-13T23:18:27.653 +C Add\sthe\ssqlite3_expanded_sql()\sinterface.\s\sRefinements\sto\sthe\nsqlite3_trace_v2()\sinterface\sto\smake\sit\smore\suseful. +D 2016-07-14T01:09:08.369 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -348,7 +348,7 @@ F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da F src/insert.c 8f4e9fcbd8e95e85f15647ba8b413b18d556ec2b F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e F src/loadext.c 4237fd37ca589f1d90b3ea925dd9df20da8e0c84 -F src/main.c a3be9a816c72fe658838e33e42afabfff93526f2 +F src/main.c ade3b39f3bde9212b3fabcff2367d29052002df6 F src/malloc.c 1443d1ad95d67c21d77af7ae3f44678252f0efec F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b @@ -385,15 +385,15 @@ F src/resolve.c cca3aa77b95706df5d635a2141a4d1de60ae6598 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c f3c6e9065fb34f6a23af27ec7f1f717ffbfc2ee4 F src/shell.c a8a9e392a6a2777fabf5feb536931cb190f235e5 -F src/sqlite.h.in 0fde7379e6a9d900802976de51cb1256f0fdac59 +F src/sqlite.h.in 6ba80e88ee17b9071f35121271784ecef60df863 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 -F src/sqlite3ext.h 3875aa5b3c4bb5d8d14c387628c5fe852b2846bf -F src/sqliteInt.h 5b8a3e1dc92e7459b69954cce9f653bd2391deb8 +F src/sqlite3ext.h 6fb1639d41907544cb3905c69a348ee64c5da79e +F src/sqliteInt.h 48cd97eb134665348393dfe277b4c14d1085bfc7 F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c 5b18f9526900f61189ab0b83f1ef41d9f871a2ab F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 F src/tclsqlite.c 25fbbbb97f76dbfd113153fb63f52d7ecfac5dd0 -F src/test1.c 640f862c490c8eee09a9d02d0d128c6a8a75336d +F src/test1.c 5124aff86fba753a6994e9621696ccfdc8bbf24e F src/test2.c 5586f43fcd9a1be0830793cf9d354082c261b25b F src/test3.c c75c8af0eadb335236c9e61b51044c58a8f7dd59 F src/test4.c d168f83cc78d02e8d35567bb5630e40dcd85ac1e @@ -449,15 +449,15 @@ F src/update.c 4f05ea8cddfa367d045e03589756c02199e8f9bd F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 810ec3f22e2d1b62e66c30fe3621ebdedd23584d F src/vacuum.c 544ec90a66a4b0460b7c1baeadbc21b45e6ca0b6 -F src/vdbe.c c6bb62aa69a6faf1197eee36336c6de99bb4733f +F src/vdbe.c 7b5570f77e32766949fd8f9478e4a9bb06e6ab24 F src/vdbe.h 67bc551f7faf04c33493892e4b378aada823ed10 F src/vdbeInt.h c59381049af5c7751a83456c39b80d1a6fde1f9d -F src/vdbeapi.c a466743c8e6de100c11e044b693c9469d2cf598a -F src/vdbeaux.c c90275b0e55a2b32c03dc09314194fe46f2429d8 +F src/vdbeapi.c 460b90f7f0894753d33df377702c1dc9cc5fa21b +F src/vdbeaux.c 6083ff395021ac8c40e1b53798ee6483037e3fb7 F src/vdbeblob.c 83d2d266383157b02e2b809350bb197e89d7895b F src/vdbemem.c 1ecaa5ee0caff07255f25d04e8dc88befb6f88d1 F src/vdbesort.c 91fda3909326860382b0ca8aa251e609c6a9d62c -F src/vdbetrace.c f75c5455d8cf389ef86a8bfdfd3177e0e3692484 +F src/vdbetrace.c d0371769fe66fe4eb85bdcacf82b6f2af50feb9b F src/vtab.c 948d2d4984219eee37a7bf427d6667e21e6eb92e F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 02eeecc265f6ffd0597378f5d8ae9070b62a406a @@ -1505,7 +1505,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P cb0062feb018f52689938a58cb76886d431c33f0 -R d7e93f0729616f164eba3e9e1862aa07 +P f33526a341132435cb4185149a784eef6b3a1a2d +R b996b3134868ad007e1e44124ba2e740 U drh -Z a0be5e80cc5b797f562ce4c096d88be2 +Z 809ea44b43d6348d635e64228e5049a8 diff --git a/manifest.uuid b/manifest.uuid index 5103610b4f..6a7d48edff 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f33526a341132435cb4185149a784eef6b3a1a2d \ No newline at end of file +99ee7ee58d45b29a0000492306ddc0b90563ff51 \ No newline at end of file diff --git a/src/main.c b/src/main.c index 5969738f6b..2e996b5545 100644 --- a/src/main.c +++ b/src/main.c @@ -1805,7 +1805,7 @@ int sqlite3_overload_function( ** SQL statement. */ #ifndef SQLITE_OMIT_DEPRECATED -void *sqlite3_trace(sqlite3 *db, void (*xTrace)(void*,const char*), void *pArg){ +void *sqlite3_trace(sqlite3 *db, void(*xTrace)(void*,const char*), void *pArg){ void *pOld; #ifdef SQLITE_ENABLE_API_ARMOR @@ -1817,7 +1817,7 @@ void *sqlite3_trace(sqlite3 *db, void (*xTrace)(void*,const char*), void *pArg){ sqlite3_mutex_enter(db->mutex); pOld = db->pTraceArg; db->mTrace = xTrace ? SQLITE_TRACE_LEGACY : 0; - db->xTrace = (int(*)(u32,void*,void*,i64))xTrace; + db->xTrace = (int(*)(u32,void*,void*,void*))xTrace; db->pTraceArg = pArg; sqlite3_mutex_leave(db->mutex); return pOld; @@ -1827,10 +1827,10 @@ void *sqlite3_trace(sqlite3 *db, void (*xTrace)(void*,const char*), void *pArg){ /* Register a trace callback using the version-2 interface. */ int sqlite3_trace_v2( - sqlite3 *db, /* Trace this connection */ - int(*xTrace)(unsigned,void*,void*,sqlite3_int64), /* Callback to invoke */ - unsigned mTrace, /* OPs to be traced */ - void *pArg /* Context */ + sqlite3 *db, /* Trace this connection */ + unsigned mTrace, /* Mask of events to be traced */ + int(*xTrace)(unsigned,void*,void*,void*), /* Callback to invoke */ + void *pArg /* Context */ ){ #ifdef SQLITE_ENABLE_API_ARMOR if( !sqlite3SafetyCheckOk(db) ){ diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 07d85b254d..8b9aa7402d 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -2804,33 +2804,25 @@ SQLITE_DEPRECATED void *sqlite3_profile(sqlite3*, ** The T argument is one of the integer type codes above. ** The C argument is a copy of the context pointer passed in as the ** fourth argument to [sqlite3_trace_v2()]. -** The P argument is a pointer whose meaning depends on T. -** The X argument is an 64-bit integer whose meaning also -** depends on T. +** The P and X arguments are pointers whose meanings depend on T. ** **
    -** [[SQLITE_TRACE_SQL]]
    SQLITE_TRACE_SQL
    -**
    An SQLITE_TRACE_SQL callback provides the same functionality -** as the legacy [sqlite3_trace()] callback. -** The P argument is a pointer to the constant UTF-8 string that is text -** describing an SQL statement that is starting to run with all -** [bound parameter] expanded. The X argument is unused. The size -** of the expansion of [bound parameters] is limited by the -** [SQLITE_TRACE_SIZE_LIMIT] compile-time option. -** ** [[SQLITE_TRACE_STMT]]
    SQLITE_TRACE_STMT
    -**
    An SQLITE_TRACE_STMT callback is invoked on the same occasions -** as SQLITE_TRACE_SQL. The difference is that the P argument is a -** pointer to the [prepared statement] rather than an SQL string. -** The X argument is unused. +**
    An SQLITE_TRACE_STMT callback is invoked when a prepared statement +** first begins running and possibly at other times during the +** execution of the prepared statement, such as at the start of each +** trigger subprogram. The P argument is a pointer to the +** [prepared statement]. The X argument is a pointer to a string which +** is the expanded SQL text of the prepared statement or a comment that +** indicates the invocation of a trigger. ** ** [[SQLITE_TRACE_PROFILE]]
    SQLITE_TRACE_PROFILE
    **
    An SQLITE_TRACE_PROFILE callback provides approximately the same ** information as is provided by the [sqlite3_profile()] callback. ** The P argument is a pointer to the [prepared statement] and the -** X argument is an estimate of the number of nanosecond for which -** the prepared statement ran. The SQLITE_TRACE_PROFILE callback is -** invoked when the statement finishes. +** X argument points to a 64-bit integer which is the estimated of +** the number of nanosecond that the prepared statement took to run. +** The SQLITE_TRACE_PROFILE callback is invoked when the statement finishes. ** ** [[SQLITE_TRACE_ROW]]
    SQLITE_TRACE_ROW
    **
    An SQLITE_TRACE_ROW callback is invoked whenever a prepared @@ -2845,17 +2837,16 @@ SQLITE_DEPRECATED void *sqlite3_profile(sqlite3*, ** and the X argument is unused. **
    */ -#define SQLITE_TRACE_SQL 0x0001 -#define SQLITE_TRACE_STMT 0x0002 -#define SQLITE_TRACE_PROFILE 0x0004 -#define SQLITE_TRACE_ROW 0x0008 -#define SQLITE_TRACE_CLOSE 0x0010 +#define SQLITE_TRACE_STMT 0x01 +#define SQLITE_TRACE_PROFILE 0x02 +#define SQLITE_TRACE_ROW 0x04 +#define SQLITE_TRACE_CLOSE 0x08 /* ** CAPI3REF: SQL Trace Hook ** METHOD: sqlite3 ** -** The sqlite3_trace_v2(D,X,M,P) interface registers a trace callback +** The sqlite3_trace_v2(D,M,X,P) interface registers a trace callback ** function X against [database connection] D, using property mask M ** and context pointer P. If the X callback is ** NULL or if the M mask is zero, then tracing is disabled. The @@ -2874,8 +2865,7 @@ SQLITE_DEPRECATED void *sqlite3_profile(sqlite3*, ** The T argument is one of the [SQLITE_TRACE] ** constants to indicate why the callback was invoked. ** The C argument is a copy of the context pointer. -** The P and X arguments are a pointer and a 64-bit integer -** whose meanings depend on T. +** The P and X arguments are pointers whose meanings depend on T. ** ** The sqlite3_trace_v2() interface is intended to replace the legacy ** interfaces [sqlite3_trace()] and [sqlite3_profile()], both of which @@ -2883,8 +2873,8 @@ SQLITE_DEPRECATED void *sqlite3_profile(sqlite3*, */ int sqlite3_trace_v2( sqlite3*, - int(*xCallback)(unsigned,void*,void*,sqlite3_int64), unsigned uMask, + int(*xCallback)(unsigned,void*,void*,void*), void *pCtx ); @@ -3506,11 +3496,30 @@ int sqlite3_prepare16_v2( ** CAPI3REF: Retrieving Statement SQL ** METHOD: sqlite3_stmt ** -** ^This interface can be used to retrieve a saved copy of the original -** SQL text used to create a [prepared statement] if that statement was -** compiled using either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()]. +** ^The sqlite3_sql(P) interface returns a pointer to a copy of the UTF-8 +** SQL text used to create [prepared statement] P if P was +** created by either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()]. +** ^The sqlite3_expanded_sql(P) interface returns a pointer to a UTF-8 +** string containing the SQL text of prepared statement P with +** [bound parameters] expanded. +** +** For example, if a prepared statement is created using the SQL +** text "SELECT $abc,:xyz" and if parameter $abc is bound to integer 2345 +** and parameter :xyz is unbound, then sqlite3_sql() will return +** the original string, "SELECT $abc,:xyz" but sqlite3_expanded_sql() +** will return "SELECT 2345,NULL". +** +** The [SQLITE_TRACE_SIZE_LIMIT] setting limits the size of a +** bound parameter expansion. +** +** ^The string returned by sqlite3_sql(P) is managed by SQLite and is +** automatically freed when the prepared statement is finalized. +** ^The string returned by sqlite3_expanded_sql(P), on the other hand, +** is obtained from [sqlite3_malloc()] and must be free by the application +** by passing it to [sqlite3_free()]. */ const char *sqlite3_sql(sqlite3_stmt *pStmt); +char *sqlite3_expanded_sql(sqlite3_stmt *pStmt); /* ** CAPI3REF: Determine If An SQL Statement Writes The Database diff --git a/src/sqlite3ext.h b/src/sqlite3ext.h index 8bcfc68521..4d5023292b 100644 --- a/src/sqlite3ext.h +++ b/src/sqlite3ext.h @@ -282,8 +282,8 @@ struct sqlite3_api_routines { /* Version 3.12.0 and later */ int (*system_errno)(sqlite3*); /* Version 3.14.0 and later */ - int (*trace_v2)(sqlite3*,int(*)(unsigned,void*,void*,sqlite3_uint64), - unsigned,void*); + int (*trace_v2)(sqlite3*,int(*)(unsigned,void*,void*,void*),unsigned,void*); + char *(*expanded_sql)(sqlite3_stmt*); }; /* @@ -531,6 +531,7 @@ struct sqlite3_api_routines { #define sqlite3_system_errno sqlite3_api->system_errno /* Version 3.14.0 and later */ #define sqlite3_trace_v2 sqlite3_api->trace_v2 +#define sqlite3_expanded_sql sqlite3_api->expanded_sql #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 225d7b2872..0be4947513 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1300,7 +1300,7 @@ struct sqlite3 { int nVDestroy; /* Number of active OP_VDestroy operations */ int nExtension; /* Number of loaded extensions */ void **aExtension; /* Array of shared library handles */ - int (*xTrace)(u32,void*,void*,i64); /* Trace function */ + int (*xTrace)(u32,void*,void*,void*); /* Trace function */ void *pTraceArg; /* Argument to the trace function */ void (*xProfile)(void*,const char*,u64); /* Profiling function */ void *pProfileArg; /* Argument to profile function */ diff --git a/src/test1.c b/src/test1.c index 5ce818bf74..a1fdcb5cfb 100644 --- a/src/test1.c +++ b/src/test1.c @@ -4386,6 +4386,26 @@ static int test_sql( Tcl_SetResult(interp, (char *)sqlite3_sql(pStmt), TCL_VOLATILE); return TCL_OK; } +static int test_ex_sql( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + sqlite3_stmt *pStmt; + char *z; + + if( objc!=2 ){ + Tcl_WrongNumArgs(interp, 1, objv, "STMT"); + return TCL_ERROR; + } + + if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; + z = sqlite3_expanded_sql(pStmt); + Tcl_SetResult(interp, z, TCL_VOLATILE); + sqlite3_free(z); + return TCL_OK; +} /* ** Usage: sqlite3_column_count STMT @@ -7276,6 +7296,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){ { "sqlite3_changes", test_changes ,0 }, { "sqlite3_step", test_step ,0 }, { "sqlite3_sql", test_sql ,0 }, + { "sqlite3_expanded_sql", test_ex_sql ,0 }, { "sqlite3_next_stmt", test_next_stmt ,0 }, { "sqlite3_stmt_readonly", test_stmt_readonly ,0 }, { "sqlite3_stmt_busy", test_stmt_busy ,0 }, diff --git a/src/vdbe.c b/src/vdbe.c index 7883536028..cdbd7301b8 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -6785,27 +6785,21 @@ case OP_Init: { /* jump */ char *z; #ifndef SQLITE_OMIT_TRACE - if( (db->mTrace & (SQLITE_TRACE_SQL|SQLITE_TRACE_STMT|SQLITE_TRACE_LEGACY))!=0 + if( (db->mTrace & (SQLITE_TRACE_STMT|SQLITE_TRACE_LEGACY))!=0 && !p->doingRerun && (zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0 ){ - if( db->mTrace & (SQLITE_TRACE_SQL|SQLITE_TRACE_LEGACY) ){ - z = sqlite3VdbeExpandSql(p, zTrace); + z = sqlite3VdbeExpandSql(p, zTrace); #ifndef SQLITE_OMIT_DEPRECATED - if( SQLITE_TRACE_LEGACY ){ - void (*x)(void*,const char*); - x = (void(*)(void*,const char*))db->xTrace; - x(db->pTraceArg, z); - }else + if( db->mTrace & SQLITE_TRACE_LEGACY ){ + void (*x)(void*,const char*) = (void(*)(void*,const char*))db->xTrace; + x(db->pTraceArg, z); + }else #endif - { - db->xTrace(SQLITE_TRACE_SQL,db->pTraceArg,z,0); - } - sqlite3DbFree(db, z); - } - if( db->mTrace & SQLITE_TRACE_STMT ){ - (void)db->xTrace(SQLITE_TRACE_STMT,db->pTraceArg,p,0); + { + (void)db->xTrace(SQLITE_TRACE_STMT,db->pTraceArg,p,z); } + sqlite3_free(z); } #ifdef SQLITE_USE_FCNTL_TRACE zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql); diff --git a/src/vdbeapi.c b/src/vdbeapi.c index a602fad383..883e5c95bf 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -71,7 +71,7 @@ static SQLITE_NOINLINE void invokeProfileCallback(sqlite3 *db, Vdbe *p){ db->xProfile(db->pProfileArg, p->zSql, iElapse); } if( db->mTrace & SQLITE_TRACE_PROFILE ){ - db->xTrace(SQLITE_TRACE_PROFILE, db->pTraceArg, p, iElapse); + db->xTrace(SQLITE_TRACE_PROFILE, db->pTraceArg, p, (void*)&iElapse); } p->startTime = 0; } diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 63609d72dd..355021e970 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -72,6 +72,21 @@ const char *sqlite3_sql(sqlite3_stmt *pStmt){ return p ? p->zSql : 0; } +/* +** Return the SQL associated with a prepared statement with +** bound parameters expanded. Space to hold the returned string is +** obtained from sqlite3_malloc(). The caller is responsible for +** freeing the returned string by passing it to sqlite3_free(). +** +** The SQLITE_TRACE_SIZE_LIMIT puts an upper bound on the size of +** expanded bound parameters. +*/ +char *sqlite3_expanded_sql(sqlite3_stmt *pStmt){ + Vdbe *p = (Vdbe *)pStmt; + return p ? sqlite3VdbeExpandSql(p, p->zSql) : 0; + if( p->zSql==0 ) return 0; +} + /* ** Swap all content between two VDBE structures. */ diff --git a/src/vdbetrace.c b/src/vdbetrace.c index 07235c931b..7311bc35c6 100644 --- a/src/vdbetrace.c +++ b/src/vdbetrace.c @@ -84,7 +84,7 @@ char *sqlite3VdbeExpandSql( char zBase[100]; /* Initial working space */ db = p->db; - sqlite3StrAccumInit(&out, db, zBase, sizeof(zBase), + sqlite3StrAccumInit(&out, 0, zBase, sizeof(zBase), db->aLimit[SQLITE_LIMIT_LENGTH]); if( db->nVdbeExec>1 ){ while( *zRawSql ){ From c0e2203adb52051f623b6a3ef9a27511ca4ae8b3 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 14 Jul 2016 01:13:36 +0000 Subject: [PATCH 0563/1484] Fix a parameter misordering on sqlite3_trace_v2() in the loadable extension interface. FossilOrigin-Name: 989de2d5b5e7155654d3eebadb9651b23f422c58 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/sqlite3ext.h | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 98c634e400..8c007e6739 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\ssqlite3_expanded_sql()\sinterface.\s\sRefinements\sto\sthe\nsqlite3_trace_v2()\sinterface\sto\smake\sit\smore\suseful. -D 2016-07-14T01:09:08.369 +C Fix\sa\sparameter\smisordering\son\ssqlite3_trace_v2()\sin\sthe\sloadable\sextension\ninterface. +D 2016-07-14T01:13:36.176 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -387,7 +387,7 @@ F src/select.c f3c6e9065fb34f6a23af27ec7f1f717ffbfc2ee4 F src/shell.c a8a9e392a6a2777fabf5feb536931cb190f235e5 F src/sqlite.h.in 6ba80e88ee17b9071f35121271784ecef60df863 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 -F src/sqlite3ext.h 6fb1639d41907544cb3905c69a348ee64c5da79e +F src/sqlite3ext.h 46f300b6e300e0fa916d7d58c44b53415b8471a9 F src/sqliteInt.h 48cd97eb134665348393dfe277b4c14d1085bfc7 F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c 5b18f9526900f61189ab0b83f1ef41d9f871a2ab @@ -1505,7 +1505,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P f33526a341132435cb4185149a784eef6b3a1a2d -R b996b3134868ad007e1e44124ba2e740 +P 99ee7ee58d45b29a0000492306ddc0b90563ff51 +R 2e489e2cf495d4b07e42b94b658ce2d8 U drh -Z 809ea44b43d6348d635e64228e5049a8 +Z d214f48401d2ba878ebf65269a7b92c1 diff --git a/manifest.uuid b/manifest.uuid index 6a7d48edff..b1e5ac35c8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -99ee7ee58d45b29a0000492306ddc0b90563ff51 \ No newline at end of file +989de2d5b5e7155654d3eebadb9651b23f422c58 \ No newline at end of file diff --git a/src/sqlite3ext.h b/src/sqlite3ext.h index 4d5023292b..338e1becd5 100644 --- a/src/sqlite3ext.h +++ b/src/sqlite3ext.h @@ -282,7 +282,7 @@ struct sqlite3_api_routines { /* Version 3.12.0 and later */ int (*system_errno)(sqlite3*); /* Version 3.14.0 and later */ - int (*trace_v2)(sqlite3*,int(*)(unsigned,void*,void*,void*),unsigned,void*); + int (*trace_v2)(sqlite3*,unsigned,int(*)(unsigned,void*,void*,void*),void*); char *(*expanded_sql)(sqlite3_stmt*); }; From 0129a54a167cd10f94cc5830890589e5138de7d5 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Thu, 14 Jul 2016 09:22:16 +0000 Subject: [PATCH 0564/1484] Fix copy/paste typo in the new sqlite3_expanded_sql() function. FossilOrigin-Name: e7d18c70d2b8f09c9f5b978fe3d69d1088e42322 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/vdbeaux.c | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 8c007e6739..0d6dec24f5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sparameter\smisordering\son\ssqlite3_trace_v2()\sin\sthe\sloadable\sextension\ninterface. -D 2016-07-14T01:13:36.176 +C Fix\scopy/paste\stypo\sin\sthe\snew\ssqlite3_expanded_sql()\sfunction. +D 2016-07-14T09:22:16.664 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -453,7 +453,7 @@ F src/vdbe.c 7b5570f77e32766949fd8f9478e4a9bb06e6ab24 F src/vdbe.h 67bc551f7faf04c33493892e4b378aada823ed10 F src/vdbeInt.h c59381049af5c7751a83456c39b80d1a6fde1f9d F src/vdbeapi.c 460b90f7f0894753d33df377702c1dc9cc5fa21b -F src/vdbeaux.c 6083ff395021ac8c40e1b53798ee6483037e3fb7 +F src/vdbeaux.c 08a459b6906dfcce0e921daba3a471a28ea65d41 F src/vdbeblob.c 83d2d266383157b02e2b809350bb197e89d7895b F src/vdbemem.c 1ecaa5ee0caff07255f25d04e8dc88befb6f88d1 F src/vdbesort.c 91fda3909326860382b0ca8aa251e609c6a9d62c @@ -1505,7 +1505,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 99ee7ee58d45b29a0000492306ddc0b90563ff51 -R 2e489e2cf495d4b07e42b94b658ce2d8 -U drh -Z d214f48401d2ba878ebf65269a7b92c1 +P 989de2d5b5e7155654d3eebadb9651b23f422c58 +R 22fe35d8085a083776873f2a488c7041 +U mistachkin +Z 0cf3ee8d7f2e128326cc9e0cdcd59d22 diff --git a/manifest.uuid b/manifest.uuid index b1e5ac35c8..9a4a235af8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -989de2d5b5e7155654d3eebadb9651b23f422c58 \ No newline at end of file +e7d18c70d2b8f09c9f5b978fe3d69d1088e42322 \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 355021e970..72a882c176 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -83,8 +83,8 @@ const char *sqlite3_sql(sqlite3_stmt *pStmt){ */ char *sqlite3_expanded_sql(sqlite3_stmt *pStmt){ Vdbe *p = (Vdbe *)pStmt; - return p ? sqlite3VdbeExpandSql(p, p->zSql) : 0; - if( p->zSql==0 ) return 0; + if( p==0 || p->zSql==0 ) return 0; + return sqlite3VdbeExpandSql(p, p->zSql); } /* From 86396219a31261a0cc1a69a6cded57073040661d Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 14 Jul 2016 19:13:11 +0000 Subject: [PATCH 0565/1484] Fix ALTER TABLE so that it does not promote the schema version past 3, as that will cause DESC indexes to go corrupt. Ticket [f68bf68513a1c]. FossilOrigin-Name: a7db6e45ad45be9b3003f61d4163f543498a7c9d --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/alter.c | 21 ++++++++++++--------- test/alter3.test | 12 ++++++------ test/alter4.test | 19 +++++++++++++++++++ 5 files changed, 46 insertions(+), 24 deletions(-) diff --git a/manifest b/manifest index c9585f19cd..966b26fc0e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\scompiler\swarnings\sin\sshell.c\sfor\sNetBSD. -D 2016-07-13T13:05:13.449 +C Fix\sALTER\sTABLE\sso\sthat\sit\sdoes\snot\spromote\sthe\sschema\sversion\spast\s3,\sas\nthat\swill\scause\sDESC\sindexes\sto\sgo\scorrupt.\nTicket\s[f68bf68513a1c]. +D 2016-07-14T19:13:11.812 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -320,7 +320,7 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a -F src/alter.c 1bb0709b3048e24217b80ec6bd78a3e99a47c01b +F src/alter.c cc28ab933ae615b22add0d609794ffb6596b42ea F src/analyze.c 37fedc80ac966ce1745811746e68e4d8fa64c7fe F src/attach.c 771153bd1f4ab0b97a44a13dde2c7e5e1efeba22 F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240 @@ -475,8 +475,8 @@ F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87 F test/all.test 6ff7b43c2b4b905c74dc4a813d201d0fa64c5783 F test/alter.test 2facdddf08d0d48e75dc6cc312cd2b030f4835dd F test/alter2.test 7ea05c7d92ac99349a802ef7ada17294dd647060 -F test/alter3.test b3568d11c38c4599c92f24242eda34144d78dc10 -F test/alter4.test c461150723ac957f3b2214aa0b11552cd72023ec +F test/alter3.test 4d79934d812eaeacc6f22781a080f8cfe012fdc3 +F test/alter4.test 0c33c542247ba5aee4f4a0133ac44bcf8f97e5e0 F test/altermalloc.test e81ac9657ed25c6c5bb09bebfa5a047cd8e4acfc F test/amatch1.test b5ae7065f042b7f4c1c922933f4700add50cdb9f F test/analyze.test 3eb35a4af972f98422e5dc0586501b17d103d321 @@ -1505,7 +1505,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 021d0fb8d85e44839d2b4fdb90b15f0e1f2442e6 -R f2c7097376b33c065f9732879605d098 +P 824b39e54fb9ba562be4d92cc9a54aee1cdf84cb +R 7d842c7254944c448483c1d7ddff9ad6 U drh -Z e160e6d632f23e86ebc551e9950cc211 +Z f6a6c237e43006b812e6af2a3e69c586 diff --git a/manifest.uuid b/manifest.uuid index 6b7a74bfc9..1fc14b81a9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -824b39e54fb9ba562be4d92cc9a54aee1cdf84cb \ No newline at end of file +a7db6e45ad45be9b3003f61d4163f543498a7c9d \ No newline at end of file diff --git a/src/alter.c b/src/alter.c index 642c1fb677..806ed49172 100644 --- a/src/alter.c +++ b/src/alter.c @@ -601,6 +601,7 @@ void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){ Expr *pDflt; /* Default value for the new column */ sqlite3 *db; /* The database connection; */ Vdbe *v = pParse->pVdbe; /* The prepared statement under construction */ + int r1; /* Temporary registers */ db = pParse->db; if( pParse->nErr || db->mallocFailed ) return; @@ -695,16 +696,18 @@ void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){ db->flags = savedDbFlags; } - /* If the default value of the new column is NULL, then the file - ** format to 2. If the default value of the new column is not NULL, - ** the file format be 3. Back when this feature was first added - ** in 2006, we went to the trouble to upgrade the file format to the - ** minimum support values. But 10-years on, we can assume that all - ** extent versions of SQLite support file-format 4, so we always and - ** unconditionally upgrade to 4. + /* Make sure the schema version is at least 3. But do not upgrade + ** from less than 3 to 4, as that will corrupt any preexisting DESC + ** index. */ - sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, - SQLITE_MAX_FILE_FORMAT); + r1 = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, r1, BTREE_FILE_FORMAT); + sqlite3VdbeUsesBtree(v, iDb); + sqlite3VdbeAddOp2(v, OP_AddImm, r1, -2); + sqlite3VdbeAddOp2(v, OP_IfPos, r1, sqlite3VdbeCurrentAddr(v)+2); + VdbeCoverage(v); + sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, 3); + sqlite3ReleaseTempReg(pParse, r1); /* Reload the schema of the modified table. */ reloadTableSchema(pParse, pTab, pTab->zName); diff --git a/test/alter3.test b/test/alter3.test index f8ebe056f2..44b31c9833 100644 --- a/test/alter3.test +++ b/test/alter3.test @@ -184,7 +184,7 @@ do_test alter3-3.2 { if {!$has_codec} { do_test alter3-3.3 { get_file_format - } {4} + } {3} } ifcapable schema_version { do_test alter3-3.4 { @@ -220,7 +220,7 @@ do_test alter3-4.2 { if {!$has_codec} { do_test alter3-4.3 { get_file_format - } {4} + } {3} } ifcapable schema_version { do_test alter3-4.4 { @@ -270,7 +270,7 @@ ifcapable attach { if {!$has_codec} { do_test alter3-5.5 { list [get_file_format test2.db] [get_file_format] - } {4 4} + } {3 3} } do_test alter3-5.6 { execsql { @@ -347,19 +347,19 @@ if {!$has_codec} { ALTER TABLE abc ADD d DEFAULT NULL; } get_file_format - } {4} + } {3} do_test alter3-7.3 { execsql { ALTER TABLE abc ADD e DEFAULT 10; } get_file_format - } {4} + } {3} do_test alter3-7.4 { execsql { ALTER TABLE abc ADD f DEFAULT NULL; } get_file_format - } {4} + } {3} do_test alter3-7.5 { execsql { VACUUM; diff --git a/test/alter4.test b/test/alter4.test index ac39d614a5..2cd78777a2 100644 --- a/test/alter4.test +++ b/test/alter4.test @@ -355,4 +355,23 @@ do_execsql_test alter4-9.3 { SELECT typeof(c), c FROM t5; } {real 9.22337203685478e+18} +# Confirm that doing an ALTER TABLE on a legacy format database +# does not corrupt DESC indexes. +# +# Ticket https://www.sqlite.org/src/tktview/f68bf68513a1c +# +do_test alter4-10.1 { + db close + sqlite3 db :memory: + db eval { + PRAGMA legacy_file_format=on; + CREATE TABLE t1(a,b,c); + CREATE INDEX t1a ON t1(a DESC); + INSERT INTO t1 VALUES(1,2,3); + INSERT INTO t1 VALUES(2,3,4); + ALTER TABLE t1 ADD COLUMN d; + PRAGMA integrity_check; + } +} {ok} + finish_test From 0b4c042b867e71bfd64a17e62d60ee2923707561 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 14 Jul 2016 19:48:08 +0000 Subject: [PATCH 0566/1484] Minor tweak the the b-tree balancer. FossilOrigin-Name: d2a0af7a37e390439c3001fedb5834f47fb24a1f --- manifest | 15 +++++++++------ manifest.uuid | 2 +- src/btree.c | 2 +- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 966b26fc0e..47fc104dda 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sALTER\sTABLE\sso\sthat\sit\sdoes\snot\spromote\sthe\sschema\sversion\spast\s3,\sas\nthat\swill\scause\sDESC\sindexes\sto\sgo\scorrupt.\nTicket\s[f68bf68513a1c]. -D 2016-07-14T19:13:11.812 +C Minor\stweak\sthe\sthe\sb-tree\sbalancer. +D 2016-07-14T19:48:08.366 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -327,7 +327,7 @@ F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240 F src/backup.c 6df65fdd569c901a418887a1a76f82ec35044556 F src/bitvec.c 3ee4c8b2c94ed3a7377256e18199e6ff5cf33f63 F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 -F src/btree.c dc4e5f3e95fd57b610422e36e0913662ecd6814c +F src/btree.c 6a42efa461cf3a0c33e8755e9d236371ac80d1b3 F src/btree.h 075c45707c0f8f8af118f739f36df8098a08b7da F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 F src/build.c d1fdfd7ab8f5447e494ef15825973bf0719527c6 @@ -1505,7 +1505,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 824b39e54fb9ba562be4d92cc9a54aee1cdf84cb -R 7d842c7254944c448483c1d7ddff9ad6 +P a7db6e45ad45be9b3003f61d4163f543498a7c9d +R cf8c76c330a7fe6ea73db33dfc44a97f +T *branch * btree-tuning +T *sym-btree-tuning * +T -sym-trunk * U drh -Z f6a6c237e43006b812e6af2a3e69c586 +Z 48948e5bf85e9b289f89aa7970884ba4 diff --git a/manifest.uuid b/manifest.uuid index 1fc14b81a9..467d7f99b2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a7db6e45ad45be9b3003f61d4163f543498a7c9d \ No newline at end of file +d2a0af7a37e390439c3001fedb5834f47fb24a1f \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 7fc9193dc8..8ea20b9ad0 100644 --- a/src/btree.c +++ b/src/btree.c @@ -7340,7 +7340,7 @@ static int balance_nonroot( assert( r szLeft-(b.szCell[r]+2)) ){ + && (bBulk || szRight+b.szCell[d]+2 > szLeft-(b.szCell[r]+(i==k-1?0:2)))){ break; } szRight += b.szCell[d] + 2; From b56660f5a4bb4acdcdd21d0dcce6a90daa1e6ee7 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Thu, 14 Jul 2016 21:26:09 +0000 Subject: [PATCH 0567/1484] Initial work on the Tcl API interface to the new sqlite3_trace_v2() function. FossilOrigin-Name: 7b59fa40a01c89cc98414d90a798169c26e04256 --- manifest | 12 +- manifest.uuid | 2 +- src/tclsqlite.c | 303 ++++++++++++++++++++++++++++++++++-------------- 3 files changed, 223 insertions(+), 94 deletions(-) diff --git a/manifest b/manifest index 0d6dec24f5..b880ee391d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\scopy/paste\stypo\sin\sthe\snew\ssqlite3_expanded_sql()\sfunction. -D 2016-07-14T09:22:16.664 +C Initial\swork\son\sthe\sTcl\sAPI\sinterface\sto\sthe\snew\ssqlite3_trace_v2()\sfunction. +D 2016-07-14T21:26:09.090 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -392,7 +392,7 @@ F src/sqliteInt.h 48cd97eb134665348393dfe277b4c14d1085bfc7 F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c 5b18f9526900f61189ab0b83f1ef41d9f871a2ab F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 -F src/tclsqlite.c 25fbbbb97f76dbfd113153fb63f52d7ecfac5dd0 +F src/tclsqlite.c 361167055f0d0d9883b729f1db698edcd3b46065 F src/test1.c 5124aff86fba753a6994e9621696ccfdc8bbf24e F src/test2.c 5586f43fcd9a1be0830793cf9d354082c261b25b F src/test3.c c75c8af0eadb335236c9e61b51044c58a8f7dd59 @@ -1505,7 +1505,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 989de2d5b5e7155654d3eebadb9651b23f422c58 -R 22fe35d8085a083776873f2a488c7041 +P e7d18c70d2b8f09c9f5b978fe3d69d1088e42322 +R 85912bc13f3699d6087855b14808f819 U mistachkin -Z 0cf3ee8d7f2e128326cc9e0cdcd59d22 +Z 312d6409632132f635d6a5f40333e628 diff --git a/manifest.uuid b/manifest.uuid index 9a4a235af8..f5bb4e0461 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e7d18c70d2b8f09c9f5b978fe3d69d1088e42322 \ No newline at end of file +7b59fa40a01c89cc98414d90a798169c26e04256 \ No newline at end of file diff --git a/src/tclsqlite.c b/src/tclsqlite.c index 476bdf235e..bcae05d795 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -133,6 +133,7 @@ struct SqliteDb { char *zBusy; /* The busy callback routine */ char *zCommit; /* The commit hook callback routine */ char *zTrace; /* The trace callback routine */ + char *zTraceV2; /* The trace_v2 callback routine */ char *zProfile; /* The profile callback routine */ char *zProgress; /* The progress callback routine */ char *zAuth; /* The authorization callback routine */ @@ -192,7 +193,7 @@ static void closeIncrblobChannels(SqliteDb *pDb){ for(p=pDb->pIncrblob; p; p=pNext){ pNext = p->pNext; - /* Note: Calling unregister here call Tcl_Close on the incrblob channel, + /* Note: Calling unregister here call Tcl_Close on the incrblob channel, ** which deletes the IncrblobChannel structure at *p. So do not ** call Tcl_Free() here. */ @@ -233,8 +234,8 @@ static int incrblobClose(ClientData instanceData, Tcl_Interp *interp){ ** Read data from an incremental blob channel. */ static int incrblobInput( - ClientData instanceData, - char *buf, + ClientData instanceData, + char *buf, int bufSize, int *errorCodePtr ){ @@ -265,8 +266,8 @@ static int incrblobInput( ** Write data to an incremental blob channel. */ static int incrblobOutput( - ClientData instanceData, - CONST char *buf, + ClientData instanceData, + CONST char *buf, int toWrite, int *errorCodePtr ){ @@ -298,7 +299,7 @@ static int incrblobOutput( ** Seek an incremental blob channel. */ static int incrblobSeek( - ClientData instanceData, + ClientData instanceData, long offset, int seekMode, int *errorCodePtr @@ -323,8 +324,8 @@ static int incrblobSeek( } -static void incrblobWatch(ClientData instanceData, int mode){ - /* NO-OP */ +static void incrblobWatch(ClientData instanceData, int mode){ + /* NO-OP */ } static int incrblobHandle(ClientData instanceData, int dir, ClientData *hPtr){ return TCL_ERROR; @@ -352,11 +353,11 @@ static Tcl_ChannelType IncrblobChannelType = { ** Create a new incrblob channel. */ static int createIncrblobChannel( - Tcl_Interp *interp, - SqliteDb *pDb, + Tcl_Interp *interp, + SqliteDb *pDb, const char *zDb, - const char *zTable, - const char *zColumn, + const char *zTable, + const char *zColumn, sqlite_int64 iRow, int isReadonly ){ @@ -438,7 +439,7 @@ static SqlFunc *findSqlFunc(SqliteDb *pDb, const char *zName){ pNew = (SqlFunc*)Tcl_Alloc( sizeof(*pNew) + nName + 1 ); pNew->zName = (char*)&pNew[1]; memcpy(pNew->zName, zName, nName+1); - for(p=pDb->pFunc; p; p=p->pNext){ + for(p=pDb->pFunc; p; p=p->pNext){ if( sqlite3_stricmp(p->zName, pNew->zName)==0 ){ Tcl_Free((char*)pNew); return p; @@ -508,6 +509,9 @@ static void DbDeleteCmd(void *db){ if( pDb->zTrace ){ Tcl_Free(pDb->zTrace); } + if( pDb->zTraceV2 ){ + Tcl_Free(pDb->zTraceV2); + } if( pDb->zProfile ){ Tcl_Free(pDb->zProfile); } @@ -587,6 +591,82 @@ static void DbTraceHandler(void *cd, const char *zSql){ } #endif +#ifndef SQLITE_OMIT_TRACE +/* +** This routine is called by the SQLite trace_v2 handler whenever a new +** supported event is generated. Unsupported event types are ignored. +** The TCL script in pDb->zTraceV2 is executed, with the arguments for +** the event appended to it (as list elements). +*/ +static int DbTraceV2Handler( + unsigned type, /* One of the SQLITE_TRACE_* event types. */ + void *cd, /* The original context data pointer. */ + void *pd, /* Primary event data, depends on event type. */ + void *xd /* Extra event data, depends on event type. */ +){ + SqliteDb *pDb = (SqliteDb*)cd; + Tcl_Obj *pCmd; + + switch( type ){ + case SQLITE_TRACE_STMT: { + sqlite3_stmt *pStmt = (sqlite3_stmt *)pd; + char *zSql = (char *)xd; + + pCmd = Tcl_NewStringObj(pDb->zTraceV2, -1); + Tcl_IncrRefCount(pCmd); + Tcl_ListObjAppendElement(pDb->interp, pCmd, + Tcl_NewWideIntObj((Tcl_WideInt)pStmt)); + Tcl_ListObjAppendElement(pDb->interp, pCmd, + Tcl_NewStringObj(zSql, -1)); + Tcl_EvalObjEx(pDb->interp, pCmd, TCL_EVAL_DIRECT); + Tcl_DecrRefCount(pCmd); + Tcl_ResetResult(pDb->interp); + break; + } + case SQLITE_TRACE_PROFILE: { + sqlite3_stmt *pStmt = (sqlite3_stmt *)pd; + sqlite3_int64 ns = (sqlite3_int64)xd; + + pCmd = Tcl_NewStringObj(pDb->zTraceV2, -1); + Tcl_IncrRefCount(pCmd); + Tcl_ListObjAppendElement(pDb->interp, pCmd, + Tcl_NewWideIntObj((Tcl_WideInt)pStmt)); + Tcl_ListObjAppendElement(pDb->interp, pCmd, + Tcl_NewWideIntObj((Tcl_WideInt)ns)); + Tcl_EvalObjEx(pDb->interp, pCmd, TCL_EVAL_DIRECT); + Tcl_DecrRefCount(pCmd); + Tcl_ResetResult(pDb->interp); + break; + } + case SQLITE_TRACE_ROW: { + sqlite3_stmt *pStmt = (sqlite3_stmt *)pd; + + pCmd = Tcl_NewStringObj(pDb->zTraceV2, -1); + Tcl_IncrRefCount(pCmd); + Tcl_ListObjAppendElement(pDb->interp, pCmd, + Tcl_NewWideIntObj((Tcl_WideInt)pStmt)); + Tcl_EvalObjEx(pDb->interp, pCmd, TCL_EVAL_DIRECT); + Tcl_DecrRefCount(pCmd); + Tcl_ResetResult(pDb->interp); + break; + } + case SQLITE_TRACE_CLOSE: { + sqlite3 *db = (sqlite3 *)pd; + + pCmd = Tcl_NewStringObj(pDb->zTraceV2, -1); + Tcl_IncrRefCount(pCmd); + Tcl_ListObjAppendElement(pDb->interp, pCmd, + Tcl_NewWideIntObj((Tcl_WideInt)db)); + Tcl_EvalObjEx(pDb->interp, pCmd, TCL_EVAL_DIRECT); + Tcl_DecrRefCount(pCmd); + Tcl_ResetResult(pDb->interp); + break; + } + } + return SQLITE_OK; +} +#endif + #ifndef SQLITE_OMIT_TRACE /* ** This routine is called by the SQLite profile handler after a statement @@ -637,9 +717,9 @@ static void DbRollbackHandler(void *clientData){ ** This procedure handles wal_hook callbacks. */ static int DbWalHandler( - void *clientData, - sqlite3 *db, - const char *zDb, + void *clientData, + sqlite3 *db, + const char *zDb, int nEntry ){ int ret = SQLITE_OK; @@ -653,7 +733,7 @@ static int DbWalHandler( Tcl_IncrRefCount(p); Tcl_ListObjAppendElement(interp, p, Tcl_NewStringObj(zDb, -1)); Tcl_ListObjAppendElement(interp, p, Tcl_NewIntObj(nEntry)); - if( TCL_OK!=Tcl_EvalObjEx(interp, p, 0) + if( TCL_OK!=Tcl_EvalObjEx(interp, p, 0) || TCL_OK!=Tcl_GetIntFromObj(interp, Tcl_GetObjResult(interp), &ret) ){ Tcl_BackgroundError(interp); @@ -695,11 +775,11 @@ static void DbUnlockNotify(void **apArg, int nArg){ ** Pre-update hook callback. */ static void DbPreUpdateHandler( - void *p, + void *p, sqlite3 *db, int op, - const char *zDb, - const char *zTbl, + const char *zDb, + const char *zTbl, sqlite_int64 iKey1, sqlite_int64 iKey2 ){ @@ -727,10 +807,10 @@ static void DbPreUpdateHandler( #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ static void DbUpdateHandler( - void *p, + void *p, int op, - const char *zDb, - const char *zTbl, + const char *zDb, + const char *zTbl, sqlite_int64 rowid ){ SqliteDb *pDb = (SqliteDb *)p; @@ -815,7 +895,7 @@ static void tclSqlFunc(sqlite3_context *context, int argc, sqlite3_value**argv){ ** script object, lappend the arguments, then evaluate the copy. ** ** By "shallow" copy, we mean only the outer list Tcl_Obj is duplicated. - ** The new Tcl_Obj contains pointers to the original list elements. + ** The new Tcl_Obj contains pointers to the original list elements. ** That way, when Tcl_EvalObjv() is run and shimmers the first element ** of the list to tclCmdNameType, that alternate representation will ** be preserved and reused on the next invocation. @@ -823,15 +903,15 @@ static void tclSqlFunc(sqlite3_context *context, int argc, sqlite3_value**argv){ Tcl_Obj **aArg; int nArg; if( Tcl_ListObjGetElements(p->interp, p->pScript, &nArg, &aArg) ){ - sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1); + sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1); return; - } + } pCmd = Tcl_NewListObj(nArg, aArg); Tcl_IncrRefCount(pCmd); for(i=0; iinterp, pCmd, pVal); if( rc ){ Tcl_DecrRefCount(pCmd); - sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1); + sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1); return; } } @@ -881,7 +961,7 @@ static void tclSqlFunc(sqlite3_context *context, int argc, sqlite3_value**argv){ } if( rc && rc!=TCL_RETURN ){ - sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1); + sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1); }else{ Tcl_Obj *pVar = Tcl_GetObjResult(p->interp); int n; @@ -983,7 +1063,7 @@ static int auth_callback( Tcl_DStringAppendElement(&str, zArg4 ? zArg4 : ""); #ifdef SQLITE_USER_AUTHENTICATION Tcl_DStringAppendElement(&str, zArg5 ? zArg5 : ""); -#endif +#endif rc = Tcl_GlobalEval(pDb->interp, Tcl_DStringValue(&str)); Tcl_DStringFree(&str); zReply = rc==TCL_OK ? Tcl_GetStringResult(pDb->interp) : "SQLITE_DENY"; @@ -1075,12 +1155,12 @@ static int DbTransPostCmd( pDb->disableAuth++; if( sqlite3_exec(pDb->db, zEnd, 0, 0, 0) ){ /* This is a tricky scenario to handle. The most likely cause of an - ** error is that the exec() above was an attempt to commit the + ** error is that the exec() above was an attempt to commit the ** top-level transaction that returned SQLITE_BUSY. Or, less likely, ** that an IO-error has occurred. In either case, throw a Tcl exception ** and try to rollback the transaction. ** - ** But it could also be that the user executed one or more BEGIN, + ** But it could also be that the user executed one or more BEGIN, ** COMMIT, SAVEPOINT, RELEASE or ROLLBACK commands that are confusing ** this method's logic. Not clear how this would be best handled. */ @@ -1099,7 +1179,7 @@ static int DbTransPostCmd( ** Unless SQLITE_TEST is defined, this function is a simple wrapper around ** sqlite3_prepare_v2(). If SQLITE_TEST is defined, then it uses either ** sqlite3_prepare_v2() or legacy interface sqlite3_prepare(), depending -** on whether or not the [db_use_legacy_prepare] command has been used to +** on whether or not the [db_use_legacy_prepare] command has been used to ** configure the connection. */ static int dbPrepare( @@ -1155,7 +1235,7 @@ static int dbPrepareAndBind( for(pPreStmt = pDb->stmtList; pPreStmt; pPreStmt=pPreStmt->pNext){ int n = pPreStmt->nSql; - if( nSql>=n + if( nSql>=n && memcmp(pPreStmt->zSql, zSql, n)==0 && (zSql[n]==0 || zSql[n-1]==';') ){ @@ -1181,7 +1261,7 @@ static int dbPrepareAndBind( break; } } - + /* If no prepared statement was found. Compile the SQL text. Also allocate ** a new SqlPreparedStmt structure. */ if( pPreStmt==0 ){ @@ -1227,7 +1307,7 @@ static int dbPrepareAndBind( assert( strlen30(pPreStmt->zSql)==pPreStmt->nSql ); assert( 0==memcmp(pPreStmt->zSql, zSql, pPreStmt->nSql) ); - /* Bind values to parameters that begin with $ or : */ + /* Bind values to parameters that begin with $ or : */ for(i=1; i<=nVar; i++){ const char *zVar = sqlite3_bind_parameter_name(pStmt, i); if( zVar!=0 && (zVar[0]=='$' || zVar[0]==':' || zVar[0]=='@') ){ @@ -1315,8 +1395,8 @@ static void dbReleaseStmt( assert( pDb->nStmt>0 ); } pDb->nStmt++; - - /* If we have too many statement in cache, remove the surplus from + + /* If we have too many statement in cache, remove the surplus from ** the end of the cache list. */ while( pDb->nStmt>pDb->maxStmt ){ SqlPreparedStmt *pLast = pDb->stmtLast; @@ -1370,8 +1450,8 @@ static void dbReleaseColumnNames(DbEvalContext *p){ ** If pArray is not NULL, then it contains the name of a Tcl array ** variable. The "*" member of this array is set to a list containing ** the names of the columns returned by the statement as part of each -** call to dbEvalStep(), in order from left to right. e.g. if the names -** of the returned columns are a, b and c, it does the equivalent of the +** call to dbEvalStep(), in order from left to right. e.g. if the names +** of the returned columns are a, b and c, it does the equivalent of the ** tcl command: ** ** set ${pArray}(*) {a b c} @@ -1492,7 +1572,7 @@ static int dbEvalStep(DbEvalContext *p){ #if SQLITE_TEST if( p->pDb->bLegacyPrepare && rcs==SQLITE_SCHEMA && zPrevSql ){ /* If the runtime error was an SQLITE_SCHEMA, and the database - ** handle is configured to use the legacy sqlite3_prepare() + ** handle is configured to use the legacy sqlite3_prepare() ** interface, retry prepare()/step() on the same SQL statement. ** This only happens once. If there is a second SQLITE_SCHEMA ** error, the error will be returned to the caller. */ @@ -1580,11 +1660,11 @@ static int DbUseNre(void){ return( (major==8 && minor>=6) || major>8 ); } #else -/* +/* ** Compiling using headers earlier than 8.6. In this case NR cannot be ** used, so DbUseNre() to always return zero. Add #defines for the other ** Tcl_NRxxx() functions to prevent them from causing compilation errors, -** even though the only invocations of them are within conditional blocks +** even though the only invocations of them are within conditional blocks ** of the form: ** ** if( DbUseNre() ) { ... } @@ -1630,11 +1710,11 @@ static int DbEvalNextCmd( } } - /* The required interpreter variables are now populated with the data + /* The required interpreter variables are now populated with the data ** from the current row. If using NRE, schedule callbacks to evaluate ** script pScript, then to invoke this function again to fetch the next ** row (or clean up if there is no next row or the script throws an - ** exception). After scheduling the callbacks, return control to the + ** exception). After scheduling the callbacks, return control to the ** caller. ** ** If not using NRE, evaluate pScript directly and continue with the @@ -1659,7 +1739,7 @@ static int DbEvalNextCmd( } /* -** This function is used by the implementations of the following database +** This function is used by the implementations of the following database ** handle sub-commands: ** ** $db update_hook ?SCRIPT? @@ -1726,9 +1806,10 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ "preupdate", "profile", "progress", "rekey", "restore", "rollback_hook", "status", "timeout", "total_changes", - "trace", "transaction", "unlock_notify", - "update_hook", "version", "wal_hook", - 0 + "trace", "trace_v2", "transaction", + "unlock_notify", "update_hook", "version", + "wal_hook", + 0 }; enum DB_enum { DB_AUTHORIZER, DB_BACKUP, DB_BUSY, @@ -1741,8 +1822,9 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ DB_PREUPDATE, DB_PROFILE, DB_PROGRESS, DB_REKEY, DB_RESTORE, DB_ROLLBACK_HOOK, DB_STATUS, DB_TIMEOUT, DB_TOTAL_CHANGES, - DB_TRACE, DB_TRANSACTION, DB_UNLOCK_NOTIFY, - DB_UPDATE_HOOK, DB_VERSION, DB_WAL_HOOK, + DB_TRACE, DB_TRACE_V2, DB_TRANSACTION, + DB_UNLOCK_NOTIFY, DB_UPDATE_HOOK, DB_VERSION, + DB_WAL_HOOK, }; /* don't leave trailing commas on DB_enum, it confuses the AIX xlc compiler */ @@ -1928,7 +2010,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ return TCL_ERROR; }else{ if( TCL_ERROR==Tcl_GetIntFromObj(interp, objv[3], &n) ){ - Tcl_AppendResult( interp, "cannot convert \"", + Tcl_AppendResult( interp, "cannot convert \"", Tcl_GetStringFromObj(objv[3],0), "\" to integer", (char*)0); return TCL_ERROR; }else{ @@ -1942,7 +2024,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ } } }else{ - Tcl_AppendResult( interp, "bad option \"", + Tcl_AppendResult( interp, "bad option \"", Tcl_GetStringFromObj(objv[2],0), "\": must be flush or size", (char*)0); return TCL_ERROR; @@ -1953,7 +2035,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ /* $db changes ** ** Return the number of rows that were modified, inserted, or deleted by - ** the most recent INSERT, UPDATE or DELETE statement, not including + ** the most recent INSERT, UPDATE or DELETE statement, not including ** any changes made by trigger programs. */ case DB_CHANGES: { @@ -2000,7 +2082,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ pCollate->zScript = (char*)&pCollate[1]; pDb->pCollate = pCollate; memcpy(pCollate->zScript, zScript, nScript+1); - if( sqlite3_create_collation(pDb->db, zName, SQLITE_UTF8, + if( sqlite3_create_collation(pDb->db, zName, SQLITE_UTF8, pCollate, tclSqlCollate) ){ Tcl_SetResult(interp, (char *)sqlite3_errmsg(pDb->db), TCL_VOLATILE); return TCL_ERROR; @@ -2126,7 +2208,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ const char *zSep; const char *zNull; if( objc<5 || objc>7 ){ - Tcl_WrongNumArgs(interp, 2, objv, + Tcl_WrongNumArgs(interp, 2, objv, "CONFLICT-ALGORITHM TABLE FILENAME ?SEPARATOR? ?NULLINDICATOR?"); return TCL_ERROR; } @@ -2155,7 +2237,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ strcmp(zConflict, "fail" ) != 0 && strcmp(zConflict, "ignore" ) != 0 && strcmp(zConflict, "replace" ) != 0 ) { - Tcl_AppendResult(interp, "Error: \"", zConflict, + Tcl_AppendResult(interp, "Error: \"", zConflict, "\", conflict-algorithm must be one of: rollback, " "abort, fail, ignore, or replace", (char*)0); return TCL_ERROR; @@ -2244,7 +2326,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ for(i=0; i0 && strcmp(azCol[i], zNull)==0) - || strlen30(azCol[i])==0 + || strlen30(azCol[i])==0 ){ sqlite3_bind_null(pStmt, i+1); }else{ @@ -2323,7 +2405,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ ** The onecolumn method is the equivalent of: ** lindex [$db eval $sql] 0 */ - case DB_EXISTS: + case DB_EXISTS: case DB_ONECOLUMN: { Tcl_Obj *pResult = 0; DbEvalContext sEval; @@ -2351,7 +2433,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ } break; } - + /* ** $db eval $sql ?array? ?{ ...code... }? ** @@ -2397,7 +2479,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ } pScript = objv[objc-1]; Tcl_IncrRefCount(pScript); - + p = (DbEvalContext *)Tcl_Alloc(sizeof(DbEvalContext)); dbEvalInit(p, pDb, objv[2], pArray); @@ -2444,7 +2526,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ if( n>2 && strncmp(z, "-deterministic",n)==0 ){ flags |= SQLITE_DETERMINISTIC; }else{ - Tcl_AppendResult(interp, "bad option \"", z, + Tcl_AppendResult(interp, "bad option \"", z, "\": must be -argcount or -deterministic", 0 ); return TCL_ERROR; @@ -2553,7 +2635,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ } /* - ** $db last_insert_rowid + ** $db last_insert_rowid ** ** Return an integer which is the ROWID for the most recent insert. */ @@ -2575,7 +2657,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ */ /* $db progress ?N CALLBACK? - ** + ** ** Invoke the given callback every N virtual machine opcodes while executing ** queries. */ @@ -2682,7 +2764,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ /* $db restore ?DATABASE? FILENAME ** - ** Open a database file named FILENAME. Transfer the content + ** Open a database file named FILENAME. Transfer the content ** of FILENAME into the local database DATABASE (default: "main"). */ case DB_RESTORE: { @@ -2743,7 +2825,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ /* ** $db status (step|sort|autoindex) ** - ** Display SQLITE_STMTSTATUS_FULLSCAN_STEP or + ** Display SQLITE_STMTSTATUS_FULLSCAN_STEP or ** SQLITE_STMTSTATUS_SORT for the most recent eval. */ case DB_STATUS: { @@ -2761,15 +2843,15 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ }else if( strcmp(zOp, "autoindex")==0 ){ v = pDb->nIndex; }else{ - Tcl_AppendResult(interp, - "bad argument: should be autoindex, step, or sort", + Tcl_AppendResult(interp, + "bad argument: should be autoindex, step, or sort", (char*)0); return TCL_ERROR; } Tcl_SetObjResult(interp, Tcl_NewIntObj(v)); break; } - + /* ** $db timeout MILLESECONDS ** @@ -2785,11 +2867,11 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ sqlite3_busy_timeout(pDb->db, ms); break; } - + /* ** $db total_changes ** - ** Return the number of rows that were modified, inserted, or deleted + ** Return the number of rows that were modified, inserted, or deleted ** since the database handle was created. */ case DB_TOTAL_CHANGES: { @@ -2842,6 +2924,53 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ break; } + /* $db trace_v2 ?CALLBACK? ?MASK? + ** + ** Make arrangements to invoke the CALLBACK routine for each trace event + ** matching the mask that is generated. The parameters are appended to + ** CALLBACK before it is executed. + */ + case DB_TRACE_V2: { + if( objc>4 ){ + Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK? ?MASK?"); + return TCL_ERROR; + }else if( objc==2 ){ + if( pDb->zTraceV2 ){ + Tcl_AppendResult(interp, pDb->zTraceV2, (char*)0); + } + }else{ + Tcl_WideInt wMask; + char *zTraceV2; + int len; + if( objc==4 ){ + if( TCL_OK!=Tcl_GetWideIntFromObj(interp, objv[3], &wMask) ){ + return TCL_ERROR; + } + }else{ + wMask = SQLITE_TRACE_STMT; + } + if( pDb->zTraceV2 ){ + Tcl_Free(pDb->zTraceV2); + } + zTraceV2 = Tcl_GetStringFromObj(objv[2], &len); + if( zTraceV2 && len>0 ){ + pDb->zTraceV2 = Tcl_Alloc( len + 1 ); + memcpy(pDb->zTraceV2, zTraceV2, len+1); + }else{ + pDb->zTraceV2 = 0; + } +#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT) + if( pDb->zTraceV2 ){ + pDb->interp = interp; + sqlite3_trace_v2(pDb->db, (unsigned)wMask, DbTraceV2Handler, pDb); + }else{ + sqlite3_trace_v2(pDb->db, 0, 0, 0); + } +#endif + } + break; + } + /* $db transaction [-deferred|-immediate|-exclusive] SCRIPT ** ** Start a new transaction (if we are not already in the midst of a @@ -2894,7 +3023,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ /* If using NRE, schedule a callback to invoke the script pScript, then ** a second callback to commit (or rollback) the transaction or savepoint ** opened above. If not using NRE, evaluate the script directly, then - ** call function DbTransPostCmd() to commit (or rollback) the transaction + ** call function DbTransPostCmd() to commit (or rollback) the transaction ** or savepoint. */ if( DbUseNre() ){ Tcl_NRAddCallback(interp, DbTransPostCmd, cd, 0, 0, 0); @@ -2925,14 +3054,14 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ Tcl_DecrRefCount(pDb->pUnlockNotify); pDb->pUnlockNotify = 0; } - + if( objc==3 ){ xNotify = DbUnlockNotify; pNotifyArg = (void *)pDb; pDb->pUnlockNotify = objv[2]; Tcl_IncrRefCount(pDb->pUnlockNotify); } - + if( sqlite3_unlock_notify(pDb->db, xNotify, pNotifyArg) ){ Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), (char*)0); rc = TCL_ERROR; @@ -3031,13 +3160,13 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ ** $db update_hook ?script? ** $db rollback_hook ?script? */ - case DB_WAL_HOOK: - case DB_UPDATE_HOOK: + case DB_WAL_HOOK: + case DB_UPDATE_HOOK: case DB_ROLLBACK_HOOK: { - /* set ppHook to point at pUpdateHook or pRollbackHook, depending on + /* set ppHook to point at pUpdateHook or pRollbackHook, depending on ** whether [$db update_hook] or [$db rollback_hook] was invoked. */ - Tcl_Obj **ppHook = 0; + Tcl_Obj **ppHook = 0; if( choice==DB_WAL_HOOK ) ppHook = &pDb->pWalHook; if( choice==DB_UPDATE_HOOK ) ppHook = &pDb->pUpdateHook; if( choice==DB_ROLLBACK_HOOK ) ppHook = &pDb->pRollbackHook; @@ -3198,7 +3327,7 @@ static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ } } if( objc<3 || (objc&1)!=1 ){ - Tcl_WrongNumArgs(interp, 1, objv, + Tcl_WrongNumArgs(interp, 1, objv, "HANDLE FILENAME ?-vfs VFSNAME? ?-readonly BOOLEAN? ?-create BOOLEAN?" " ?-nomutex BOOLEAN? ?-fullmutex BOOLEAN? ?-uri BOOLEAN?" #if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL) @@ -3490,7 +3619,7 @@ static void MD5Init(MD5Context *ctx){ * Update context to reflect the concatenation of another buffer full * of bytes. */ -static +static void MD5Update(MD5Context *ctx, const unsigned char *buf, unsigned int len){ uint32 t; @@ -3536,7 +3665,7 @@ void MD5Update(MD5Context *ctx, const unsigned char *buf, unsigned int len){ } /* - * Final wrapup - pad to 64-byte boundary with the bit pattern + * Final wrapup - pad to 64-byte boundary with the bit pattern * 1 0* (64-bit count of bits processed, MSB-first) */ static void MD5Final(unsigned char digest[16], MD5Context *ctx){ @@ -3612,7 +3741,7 @@ static void MD5DigestToBase10x8(unsigned char digest[16], char zDigest[50]){ /* ** A TCL command for md5. The argument is the text to be hashed. The -** Result is the hash in base64. +** Result is the hash in base64. */ static int md5_cmd(void*cd, Tcl_Interp *interp, int argc, const char **argv){ MD5Context ctx; @@ -3621,7 +3750,7 @@ static int md5_cmd(void*cd, Tcl_Interp *interp, int argc, const char **argv){ void (*converter)(unsigned char*, char*); if( argc!=2 ){ - Tcl_AppendResult(interp,"wrong # args: should be \"", argv[0], + Tcl_AppendResult(interp,"wrong # args: should be \"", argv[0], " TEXT\"", (char*)0); return TCL_ERROR; } @@ -3646,13 +3775,13 @@ static int md5file_cmd(void*cd, Tcl_Interp*interp, int argc, const char **argv){ char zBuf[10240]; if( argc!=2 ){ - Tcl_AppendResult(interp,"wrong # args: should be \"", argv[0], + Tcl_AppendResult(interp,"wrong # args: should be \"", argv[0], " FILENAME\"", (char*)0); return TCL_ERROR; } in = fopen(argv[1],"rb"); if( in==0 ){ - Tcl_AppendResult(interp,"unable to open file \"", argv[1], + Tcl_AppendResult(interp,"unable to open file \"", argv[1], "\" for reading", (char*)0); return TCL_ERROR; } @@ -3719,7 +3848,7 @@ static void md5finalize(sqlite3_context *context){ sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT); } int Md5_Register(sqlite3 *db){ - int rc = sqlite3_create_function(db, "md5sum", -1, SQLITE_UTF8, 0, 0, + int rc = sqlite3_create_function(db, "md5sum", -1, SQLITE_UTF8, 0, 0, md5step, md5finalize); sqlite3_overload_function(db, "md5sum", -1); /* To exercise this API */ return rc; @@ -3870,7 +3999,7 @@ static int db_last_stmt_ptr( ** Configure the interpreter passed as the first argument to have access ** to the commands and linked variables that make up: ** -** * the [sqlite3] extension itself, +** * the [sqlite3] extension itself, ** ** * If SQLITE_TCLMD5 or SQLITE_TEST is defined, the Md5 commands, and ** From b52dcd898936ad3e397d3e696573c8768d8c2422 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Thu, 14 Jul 2016 23:17:03 +0000 Subject: [PATCH 0568/1484] More work on the Tcl interface and tests for the sqlite3_trace_v2() API. FossilOrigin-Name: f3c4aa97d8c10fdb69efc6405b5fa45781f45a61 --- manifest | 13 ++--- manifest.uuid | 2 +- src/tclsqlite.c | 41 ++++++++++++++-- test/trace3.test | 124 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 170 insertions(+), 10 deletions(-) create mode 100644 test/trace3.test diff --git a/manifest b/manifest index b880ee391d..ae6c2d0353 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Initial\swork\son\sthe\sTcl\sAPI\sinterface\sto\sthe\snew\ssqlite3_trace_v2()\sfunction. -D 2016-07-14T21:26:09.090 +C More\swork\son\sthe\sTcl\sinterface\sand\stests\sfor\sthe\ssqlite3_trace_v2()\sAPI. +D 2016-07-14T23:17:03.656 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -392,7 +392,7 @@ F src/sqliteInt.h 48cd97eb134665348393dfe277b4c14d1085bfc7 F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c 5b18f9526900f61189ab0b83f1ef41d9f871a2ab F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 -F src/tclsqlite.c 361167055f0d0d9883b729f1db698edcd3b46065 +F src/tclsqlite.c 573e63c959b314d77486f3565fa79c60cda3df7e F src/test1.c 5124aff86fba753a6994e9621696ccfdc8bbf24e F src/test2.c 5586f43fcd9a1be0830793cf9d354082c261b25b F src/test3.c c75c8af0eadb335236c9e61b51044c58a8f7dd59 @@ -1285,6 +1285,7 @@ F test/tokenize.test ce430a7aed48fc98301611429595883fdfcab5d7 F test/tpch01.test 04adbf8d8300fa60a222f28d901abd76e7be6dd4 F test/trace.test 6f676313e3ebd2a50585036d2f212a3319dd5836 F test/trace2.test f5cb67ad3bc09e0c58e8cca78dfd0b5639259983 +F test/trace3.test bc598719949e59b8ba5152cc42fea75e99766478 F test/trans.test 6e1b4c6a42dba31bd65f8fa5e61a2708e08ddde6 F test/trans2.test 62bd045bfc7a1c14c5ba83ba64d21ade31583f76 F test/trans3.test 91a100e5412b488e22a655fe423a14c26403ab94 @@ -1505,7 +1506,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e7d18c70d2b8f09c9f5b978fe3d69d1088e42322 -R 85912bc13f3699d6087855b14808f819 +P 7b59fa40a01c89cc98414d90a798169c26e04256 +R f3e8ed411550909534d86cfeab7a6746 U mistachkin -Z 312d6409632132f635d6a5f40333e628 +Z 5840e23d72dcfac70e0e20acc9abb290 diff --git a/manifest.uuid b/manifest.uuid index f5bb4e0461..0d1c4fc278 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7b59fa40a01c89cc98414d90a798169c26e04256 \ No newline at end of file +f3c4aa97d8c10fdb69efc6405b5fa45781f45a61 \ No newline at end of file diff --git a/src/tclsqlite.c b/src/tclsqlite.c index bcae05d795..43dfedb727 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -2939,15 +2939,50 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ Tcl_AppendResult(interp, pDb->zTraceV2, (char*)0); } }else{ - Tcl_WideInt wMask; char *zTraceV2; int len; + Tcl_WideInt wMask = 0; if( objc==4 ){ - if( TCL_OK!=Tcl_GetWideIntFromObj(interp, objv[3], &wMask) ){ + static const char *TTYPE_strs[] = { + "statement", "profile", "row", "close", 0 + }; + enum TTYPE_enum { + TTYPE_STMT, TTYPE_PROFILE, TTYPE_ROW, TTYPE_CLOSE + }; + int i; + if( TCL_OK!=Tcl_ListObjLength(interp, objv[3], &len) ){ return TCL_ERROR; } + for(i=0; izTraceV2 ){ Tcl_Free(pDb->zTraceV2); diff --git a/test/trace3.test b/test/trace3.test new file mode 100644 index 0000000000..b9977178ad --- /dev/null +++ b/test/trace3.test @@ -0,0 +1,124 @@ +# 2016 July 14 +# +# 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 regression tests for SQLite library. The focus +# of this test file is the "sqlite3_trace_v2()" API. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +ifcapable !trace { finish_test ; return } +set ::testprefix trace3 + +proc trace_v2_error { args } { + lappend ::stmtlist(error) [string trim $args] + error "trace error"; # this will be ignored. +} +proc trace_v2_record { args } { + lappend ::stmtlist(record) [string trim $args] +} +proc trace_v2_nop { args } {}; # do nothing. + +do_test trace3-1.0 { + execsql { + CREATE TABLE t1(a,b); + INSERT INTO t1 VALUES(1,NULL); + INSERT INTO t1 VALUES(2,-1); + INSERT INTO t1 VALUES(3,0); + INSERT INTO t1 VALUES(4,1); + INSERT INTO t1 VALUES(5,-2147483648); + INSERT INTO t1 VALUES(6,2147483647); + INSERT INTO t1 VALUES(7,-9223372036854775808); + INSERT INTO t1 VALUES(8,9223372036854775807); + INSERT INTO t1 VALUES(9,-1.0); + INSERT INTO t1 VALUES(10,0.0); + INSERT INTO t1 VALUES(11,1.0); + INSERT INTO t1 VALUES(12,''); + INSERT INTO t1 VALUES(13,'1'); + INSERT INTO t1 VALUES(14,'one'); + INSERT INTO t1 VALUES(15,x'abcd0123'); + INSERT INTO t1 VALUES(16,x'4567cdef'); + } +} {} + +do_test trace3-1.1 { + set rc [catch {db trace_v2 1 2 3} msg] + lappend rc $msg +} {1 {wrong # args: should be "db trace_v2 ?CALLBACK? ?MASK?"}} +do_test trace3-1.2 { + set rc [catch {db trace_v2 1 bad} msg] + lappend rc $msg +} {1 {bad trace type "bad": must be statement, profile, row, or close}} + +do_test trace3-2.1 { + db trace_v2 trace_v2_nop + db trace_v2 +} {trace_v2_nop} + +do_test trace3-3.1 { + unset -nocomplain ::stmtlist + db trace_v2 trace_v2_nop + execsql { + SELECT a, b FROM t1 ORDER BY a; + } + array get ::stmtlist +} {} +do_test trace3-3.2 { + set ::stmtlist(error) {} + db trace_v2 trace_v2_error + execsql { + SELECT a, b FROM t1 ORDER BY a; + } + set ::stmtlist(error) +} {/^\{-?\d+ \{SELECT a, b FROM t1 ORDER BY a;\}\}$/} +do_test trace3-3.3 { + set ::stmtlist(record) {} + db trace_v2 trace_v2_record + execsql { + SELECT a, b FROM t1 ORDER BY a; + } + set ::stmtlist(record) +} {/^\{-?\d+ \{SELECT a, b FROM t1 ORDER BY a;\}\}$/} + +do_test trace3-4.1 { + set ::stmtlist(record) {} + db trace_v2 trace_v2_record profile + execsql { + SELECT a, b FROM t1 ORDER BY a; + } + set ::stmtlist(record) +} {/^\{-?\d+ -?\d+\}$/} + +do_test trace3-5.1 { + set ::stmtlist(record) {} + db trace_v2 trace_v2_record row + execsql { + SELECT a, b FROM t1 ORDER BY a; + } + set ::stmtlist(record) +} "/^[string trim [string repeat {\d+ } 16]]\$/" + +do_test trace3-6.1 { + set ::stmtlist(record) {} + db trace_v2 trace_v2_record {profile row} + execsql { + SELECT a, b FROM t1 ORDER BY a; + } + set ::stmtlist(record) +} "/^[string trim [string repeat {-?\d+ } 16]] \\\{-?\\d+ -?\\d+\\\}\$/" + +do_test trace3-7.1 { + set ::stmtlist(record) {} + db trace_v2 trace_v2_record close + db close + set ::stmtlist(record) +} {/^-?\d+$/} + +finish_test From e2f84b403c982d48ed4e9f49677ab40119c7db4b Mon Sep 17 00:00:00 2001 From: mistachkin Date: Fri, 15 Jul 2016 00:07:47 +0000 Subject: [PATCH 0569/1484] Add tests, including some for the sqlite3_expanded_sql() API. FossilOrigin-Name: 8b8c0b749a9a1daca49e7ea9351e253443bb1fc2 --- manifest | 12 ++++----- manifest.uuid | 2 +- test/trace3.test | 64 ++++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 69 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index ae6c2d0353..1075a137e4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C More\swork\son\sthe\sTcl\sinterface\sand\stests\sfor\sthe\ssqlite3_trace_v2()\sAPI. -D 2016-07-14T23:17:03.656 +C Add\stests,\sincluding\ssome\sfor\sthe\ssqlite3_expanded_sql()\sAPI. +D 2016-07-15T00:07:47.847 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -1285,7 +1285,7 @@ F test/tokenize.test ce430a7aed48fc98301611429595883fdfcab5d7 F test/tpch01.test 04adbf8d8300fa60a222f28d901abd76e7be6dd4 F test/trace.test 6f676313e3ebd2a50585036d2f212a3319dd5836 F test/trace2.test f5cb67ad3bc09e0c58e8cca78dfd0b5639259983 -F test/trace3.test bc598719949e59b8ba5152cc42fea75e99766478 +F test/trace3.test fb9242446aeef4f6e559edb126b3d67185b9a1c0 F test/trans.test 6e1b4c6a42dba31bd65f8fa5e61a2708e08ddde6 F test/trans2.test 62bd045bfc7a1c14c5ba83ba64d21ade31583f76 F test/trans3.test 91a100e5412b488e22a655fe423a14c26403ab94 @@ -1506,7 +1506,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 7b59fa40a01c89cc98414d90a798169c26e04256 -R f3e8ed411550909534d86cfeab7a6746 +P f3c4aa97d8c10fdb69efc6405b5fa45781f45a61 +R 433ed72af7d798e30b744dbac703a881 U mistachkin -Z 5840e23d72dcfac70e0e20acc9abb290 +Z c19e7bc180fcaf3fc05253b5c21f7fa0 diff --git a/manifest.uuid b/manifest.uuid index 0d1c4fc278..d877fc43c8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f3c4aa97d8c10fdb69efc6405b5fa45781f45a61 \ No newline at end of file +8b8c0b749a9a1daca49e7ea9351e253443bb1fc2 \ No newline at end of file diff --git a/test/trace3.test b/test/trace3.test index b9977178ad..760fd33fe5 100644 --- a/test/trace3.test +++ b/test/trace3.test @@ -8,8 +8,9 @@ # May you share freely, never taking more than you give. # #*********************************************************************** -# This file implements regression tests for SQLite library. The focus -# of this test file is the "sqlite3_trace_v2()" API. +# This file implements regression tests for SQLite library. The focus of +# this test file is the "sqlite3_trace_v2()" and "sqlite3_expanded_sql()" +# APIs. # set testdir [file dirname $argv0] @@ -113,8 +114,67 @@ do_test trace3-6.1 { } set ::stmtlist(record) } "/^[string trim [string repeat {-?\d+ } 16]] \\\{-?\\d+ -?\\d+\\\}\$/" +do_test trace3-6.2 { + set ::stmtlist(record) {} + db trace_v2 trace_v2_record {statement profile row} + execsql { + SELECT a, b FROM t1 ORDER BY a; + } + set ::stmtlist(record) +} "/^\\\{-?\\d+ \\\{SELECT a, b FROM t1 ORDER BY a;\\\}\\\} [string trim \ +[string repeat {-?\d+ } 16]] \\\{-?\\d+ -?\\d+\\\}\$/" do_test trace3-7.1 { + set DB [sqlite3_connection_pointer db] + + set STMT [sqlite3_prepare_v2 $DB \ + "SELECT a, b FROM t1 WHERE b = ? ORDER BY a;" -1 TAIL] +} {/^[0-9A-F]+$/} + +do_test trace3-8.1 { + list [sqlite3_bind_null $STMT 1] [sqlite3_expanded_sql $STMT] +} {{} {SELECT a, b FROM t1 WHERE b = NULL ORDER BY a;}} +do_test trace3-8.2 { + list [sqlite3_bind_int $STMT 1 123] [sqlite3_expanded_sql $STMT] +} {{} {SELECT a, b FROM t1 WHERE b = 123 ORDER BY a;}} +do_test trace3-8.3 { + list [sqlite3_bind_int64 $STMT 1 123] [sqlite3_expanded_sql $STMT] +} {{} {SELECT a, b FROM t1 WHERE b = 123 ORDER BY a;}} +do_test trace3-8.4 { + list [sqlite3_bind_text $STMT 1 "some string" 11] \ + [sqlite3_expanded_sql $STMT] +} {{} {SELECT a, b FROM t1 WHERE b = 'some string' ORDER BY a;}} +do_test trace3-8.5 { + list [sqlite3_bind_text $STMT 1 "some 'bad' string" 17] \ + [sqlite3_expanded_sql $STMT] +} {{} {SELECT a, b FROM t1 WHERE b = 'some ''bad'' string' ORDER BY a;}} +do_test trace3-8.6 { + list [sqlite3_bind_double $STMT 1 123] [sqlite3_expanded_sql $STMT] +} {{} {SELECT a, b FROM t1 WHERE b = 123.0 ORDER BY a;}} +do_test trace3-8.7 { + list [sqlite3_bind_text16 $STMT 1 \ + [encoding convertto unicode hi\000yall\000] 16] \ + [sqlite3_expanded_sql $STMT] +} {{} {SELECT a, b FROM t1 WHERE b = 'hi' ORDER BY a;}} +do_test trace3-8.8 { + list [sqlite3_bind_blob $STMT 1 "\x12\x34\x56" 3] \ + [sqlite3_expanded_sql $STMT] +} {{} {SELECT a, b FROM t1 WHERE b = x'123456' ORDER BY a;}} + +do_test trace3-9.1 { + db trace_v2 "" + db trace_v2 +} {} +do_test trace3-9.2 { + unset -nocomplain ::stmtlist + db trace_v2 "" {statement profile row} + execsql { + SELECT a, b FROM t1 ORDER BY a; + } + array get ::stmtlist +} {} + +do_test trace3-10.1 { set ::stmtlist(record) {} db trace_v2 trace_v2_record close db close From a8f286a38a1c89bca1af69ff59a38d0cb1c412cc Mon Sep 17 00:00:00 2001 From: mistachkin Date: Fri, 15 Jul 2016 00:09:53 +0000 Subject: [PATCH 0570/1484] Modify one test result to be case-insensitive. FossilOrigin-Name: 5ccbeeea7d7933402f7ccb0b1c9b3038989ca746 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/trace3.test | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 1075a137e4..4323ff299d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\stests,\sincluding\ssome\sfor\sthe\ssqlite3_expanded_sql()\sAPI. -D 2016-07-15T00:07:47.847 +C Modify\sone\stest\sresult\sto\sbe\scase-insensitive. +D 2016-07-15T00:09:53.145 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -1285,7 +1285,7 @@ F test/tokenize.test ce430a7aed48fc98301611429595883fdfcab5d7 F test/tpch01.test 04adbf8d8300fa60a222f28d901abd76e7be6dd4 F test/trace.test 6f676313e3ebd2a50585036d2f212a3319dd5836 F test/trace2.test f5cb67ad3bc09e0c58e8cca78dfd0b5639259983 -F test/trace3.test fb9242446aeef4f6e559edb126b3d67185b9a1c0 +F test/trace3.test 0cb672483450fd430b24bc53eaddd13b2e69ffb7 F test/trans.test 6e1b4c6a42dba31bd65f8fa5e61a2708e08ddde6 F test/trans2.test 62bd045bfc7a1c14c5ba83ba64d21ade31583f76 F test/trans3.test 91a100e5412b488e22a655fe423a14c26403ab94 @@ -1506,7 +1506,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P f3c4aa97d8c10fdb69efc6405b5fa45781f45a61 -R 433ed72af7d798e30b744dbac703a881 +P 8b8c0b749a9a1daca49e7ea9351e253443bb1fc2 +R 4595806197ce86b476490cbf571f56e0 U mistachkin -Z c19e7bc180fcaf3fc05253b5c21f7fa0 +Z b642433aedf1b36843816b1e93dd1f01 diff --git a/manifest.uuid b/manifest.uuid index d877fc43c8..c8129cd085 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8b8c0b749a9a1daca49e7ea9351e253443bb1fc2 \ No newline at end of file +5ccbeeea7d7933402f7ccb0b1c9b3038989ca746 \ No newline at end of file diff --git a/test/trace3.test b/test/trace3.test index 760fd33fe5..eef9198791 100644 --- a/test/trace3.test +++ b/test/trace3.test @@ -129,7 +129,7 @@ do_test trace3-7.1 { set STMT [sqlite3_prepare_v2 $DB \ "SELECT a, b FROM t1 WHERE b = ? ORDER BY a;" -1 TAIL] -} {/^[0-9A-F]+$/} +} {/^[0-9A-Fa-f]+$/} do_test trace3-8.1 { list [sqlite3_bind_null $STMT 1] [sqlite3_expanded_sql $STMT] From 170e9982369e9b80b70fd654003a86f22a79330f Mon Sep 17 00:00:00 2001 From: mistachkin Date: Fri, 15 Jul 2016 00:23:01 +0000 Subject: [PATCH 0571/1484] Corrections and enhancements for the new tests. FossilOrigin-Name: 20e74c638537aa207de41a4f3c932cc05024ea9a --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/trace3.test | 49 ++++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 54 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 4323ff299d..e0b98e55b5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Modify\sone\stest\sresult\sto\sbe\scase-insensitive. -D 2016-07-15T00:09:53.145 +C Corrections\sand\senhancements\sfor\sthe\snew\stests. +D 2016-07-15T00:23:01.539 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -1285,7 +1285,7 @@ F test/tokenize.test ce430a7aed48fc98301611429595883fdfcab5d7 F test/tpch01.test 04adbf8d8300fa60a222f28d901abd76e7be6dd4 F test/trace.test 6f676313e3ebd2a50585036d2f212a3319dd5836 F test/trace2.test f5cb67ad3bc09e0c58e8cca78dfd0b5639259983 -F test/trace3.test 0cb672483450fd430b24bc53eaddd13b2e69ffb7 +F test/trace3.test 7d174e42aab63f528a0d04ea1ddf3b49497a9cf5 F test/trans.test 6e1b4c6a42dba31bd65f8fa5e61a2708e08ddde6 F test/trans2.test 62bd045bfc7a1c14c5ba83ba64d21ade31583f76 F test/trans3.test 91a100e5412b488e22a655fe423a14c26403ab94 @@ -1506,7 +1506,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 8b8c0b749a9a1daca49e7ea9351e253443bb1fc2 -R 4595806197ce86b476490cbf571f56e0 +P 5ccbeeea7d7933402f7ccb0b1c9b3038989ca746 +R 614bfc4ccb78b65b369725b4f27e97e3 U mistachkin -Z b642433aedf1b36843816b1e93dd1f01 +Z a476d2a0aebfb671981b15fc2ac6c121 diff --git a/manifest.uuid b/manifest.uuid index c8129cd085..22e8d58574 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5ccbeeea7d7933402f7ccb0b1c9b3038989ca746 \ No newline at end of file +20e74c638537aa207de41a4f3c932cc05024ea9a \ No newline at end of file diff --git a/test/trace3.test b/test/trace3.test index eef9198791..1149bea3f2 100644 --- a/test/trace3.test +++ b/test/trace3.test @@ -87,6 +87,22 @@ do_test trace3-3.3 { } set ::stmtlist(record) } {/^\{-?\d+ \{SELECT a, b FROM t1 ORDER BY a;\}\}$/} +do_test trace3-3.4 { + set ::stmtlist(record) {} + db trace_v2 trace_v2_record statement + execsql { + SELECT a, b FROM t1 ORDER BY a; + } + set ::stmtlist(record) +} {/^\{-?\d+ \{SELECT a, b FROM t1 ORDER BY a;\}\}$/} +do_test trace3-3.5 { + set ::stmtlist(record) {} + db trace_v2 trace_v2_record 1 + execsql { + SELECT a, b FROM t1 ORDER BY a; + } + set ::stmtlist(record) +} {/^\{-?\d+ \{SELECT a, b FROM t1 ORDER BY a;\}\}$/} do_test trace3-4.1 { set ::stmtlist(record) {} @@ -96,6 +112,14 @@ do_test trace3-4.1 { } set ::stmtlist(record) } {/^\{-?\d+ -?\d+\}$/} +do_test trace3-4.2 { + set ::stmtlist(record) {} + db trace_v2 trace_v2_record 2 + execsql { + SELECT a, b FROM t1 ORDER BY a; + } + set ::stmtlist(record) +} {/^\{-?\d+ -?\d+\}$/} do_test trace3-5.1 { set ::stmtlist(record) {} @@ -105,6 +129,14 @@ do_test trace3-5.1 { } set ::stmtlist(record) } "/^[string trim [string repeat {\d+ } 16]]\$/" +do_test trace3-5.2 { + set ::stmtlist(record) {} + db trace_v2 trace_v2_record 4 + execsql { + SELECT a, b FROM t1 ORDER BY a; + } + set ::stmtlist(record) +} "/^[string trim [string repeat {\d+ } 16]]\$/" do_test trace3-6.1 { set ::stmtlist(record) {} @@ -162,10 +194,14 @@ do_test trace3-8.8 { } {{} {SELECT a, b FROM t1 WHERE b = x'123456' ORDER BY a;}} do_test trace3-9.1 { + sqlite3_finalize $STMT +} {SQLITE_OK} + +do_test trace3-10.1 { db trace_v2 "" db trace_v2 } {} -do_test trace3-9.2 { +do_test trace3-10.2 { unset -nocomplain ::stmtlist db trace_v2 "" {statement profile row} execsql { @@ -174,11 +210,20 @@ do_test trace3-9.2 { array get ::stmtlist } {} -do_test trace3-10.1 { +do_test trace3-11.1 { set ::stmtlist(record) {} db trace_v2 trace_v2_record close db close set ::stmtlist(record) } {/^-?\d+$/} +reset_db + +do_test trace3-11.2 { + set ::stmtlist(record) {} + db trace_v2 trace_v2_record 8 + db close + set ::stmtlist(record) +} {/^-?\d+$/} + finish_test From 283a85ca212d4cc42a115c13011e7d88189d6dac Mon Sep 17 00:00:00 2001 From: mistachkin Date: Fri, 15 Jul 2016 00:39:47 +0000 Subject: [PATCH 0572/1484] Fix typo in sqlite3_trace_v2(). FossilOrigin-Name: 97ccf15fb7e5103c8317d06a1985ba9c88544a60 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/main.c | 3 +-- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index e0b98e55b5..72176f68e4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Corrections\sand\senhancements\sfor\sthe\snew\stests. -D 2016-07-15T00:23:01.539 +C Fix\stypo\sin\ssqlite3_trace_v2(). +D 2016-07-15T00:39:47.683 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -348,7 +348,7 @@ F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da F src/insert.c 8f4e9fcbd8e95e85f15647ba8b413b18d556ec2b F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e F src/loadext.c 4237fd37ca589f1d90b3ea925dd9df20da8e0c84 -F src/main.c ade3b39f3bde9212b3fabcff2367d29052002df6 +F src/main.c 2d3e62a971e7f169a74448e81af9ebde95b07381 F src/malloc.c 1443d1ad95d67c21d77af7ae3f44678252f0efec F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b @@ -1506,7 +1506,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 5ccbeeea7d7933402f7ccb0b1c9b3038989ca746 -R 614bfc4ccb78b65b369725b4f27e97e3 +P 20e74c638537aa207de41a4f3c932cc05024ea9a +R 6a6c93d9b0435cebe88086cbb6537465 U mistachkin -Z a476d2a0aebfb671981b15fc2ac6c121 +Z 470459b5b02059a7c191e033bd2eea7f diff --git a/manifest.uuid b/manifest.uuid index 22e8d58574..8fa3e9fe97 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -20e74c638537aa207de41a4f3c932cc05024ea9a \ No newline at end of file +97ccf15fb7e5103c8317d06a1985ba9c88544a60 \ No newline at end of file diff --git a/src/main.c b/src/main.c index 2e996b5545..5cd1ea7185 100644 --- a/src/main.c +++ b/src/main.c @@ -1834,8 +1834,7 @@ int sqlite3_trace_v2( ){ #ifdef SQLITE_ENABLE_API_ARMOR if( !sqlite3SafetyCheckOk(db) ){ - (void)SQLITE_MISUSE_BKPT; - return 0; + return SQLITE_MISUSE_BKPT; } #endif sqlite3_mutex_enter(db->mutex); From de6fde6af69f9ea2cc0e3a0180cf97a48a0dcb03 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Fri, 15 Jul 2016 01:49:25 +0000 Subject: [PATCH 0573/1484] Modify the Tcl test command 'sqlite3_bind_blob' to make use of the Tcl_GetByteArrayFromObj() API. FossilOrigin-Name: e03c81895e52096ab055d8231841e9070602ca84 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/test1.c | 13 +++++++++++-- test/trace3.test | 4 ++++ 4 files changed, 23 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 72176f68e4..42028828b3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\stypo\sin\ssqlite3_trace_v2(). -D 2016-07-15T00:39:47.683 +C Modify\sthe\sTcl\stest\scommand\s'sqlite3_bind_blob'\sto\smake\suse\sof\sthe\sTcl_GetByteArrayFromObj()\sAPI. +D 2016-07-15T01:49:25.642 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -393,7 +393,7 @@ F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c 5b18f9526900f61189ab0b83f1ef41d9f871a2ab F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 F src/tclsqlite.c 573e63c959b314d77486f3565fa79c60cda3df7e -F src/test1.c 5124aff86fba753a6994e9621696ccfdc8bbf24e +F src/test1.c 4bdfccf93a33453b427fb01cf12dfe26a5dd2cbc F src/test2.c 5586f43fcd9a1be0830793cf9d354082c261b25b F src/test3.c c75c8af0eadb335236c9e61b51044c58a8f7dd59 F src/test4.c d168f83cc78d02e8d35567bb5630e40dcd85ac1e @@ -1285,7 +1285,7 @@ F test/tokenize.test ce430a7aed48fc98301611429595883fdfcab5d7 F test/tpch01.test 04adbf8d8300fa60a222f28d901abd76e7be6dd4 F test/trace.test 6f676313e3ebd2a50585036d2f212a3319dd5836 F test/trace2.test f5cb67ad3bc09e0c58e8cca78dfd0b5639259983 -F test/trace3.test 7d174e42aab63f528a0d04ea1ddf3b49497a9cf5 +F test/trace3.test 01e4111d582c7b20ab1c63156169157d256bc3d5 F test/trans.test 6e1b4c6a42dba31bd65f8fa5e61a2708e08ddde6 F test/trans2.test 62bd045bfc7a1c14c5ba83ba64d21ade31583f76 F test/trans3.test 91a100e5412b488e22a655fe423a14c26403ab94 @@ -1506,7 +1506,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 20e74c638537aa207de41a4f3c932cc05024ea9a -R 6a6c93d9b0435cebe88086cbb6537465 +P 97ccf15fb7e5103c8317d06a1985ba9c88544a60 +R 23f12c56d57425cd5e6978d10e653771 U mistachkin -Z 470459b5b02059a7c191e033bd2eea7f +Z ce44a3acd6ed0a8254df88a4b23a0c52 diff --git a/manifest.uuid b/manifest.uuid index 8fa3e9fe97..4fc1c619aa 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -97ccf15fb7e5103c8317d06a1985ba9c88544a60 \ No newline at end of file +e03c81895e52096ab055d8231841e9070602ca84 \ No newline at end of file diff --git a/src/test1.c b/src/test1.c index a1fdcb5cfb..11cd17e722 100644 --- a/src/test1.c +++ b/src/test1.c @@ -3633,7 +3633,7 @@ static int test_bind_blob( Tcl_Obj *CONST objv[] ){ sqlite3_stmt *pStmt; - int idx; + int len, idx; int bytes; char *value; int rc; @@ -3652,9 +3652,18 @@ static int test_bind_blob( if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR; - value = Tcl_GetString(objv[3]); + + value = Tcl_GetByteArrayFromObj(objv[3], &len); if( Tcl_GetIntFromObj(interp, objv[4], &bytes) ) return TCL_ERROR; + if( bytes>len ){ + char zBuf[200]; + sqlite3_snprintf(sizeof(zBuf), zBuf, + "cannot use %d blob bytes, have %d", bytes, len); + Tcl_AppendResult(interp, zBuf, -1); + return TCL_ERROR; + } + rc = sqlite3_bind_blob(pStmt, idx, value, bytes, xDestructor); if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR; if( rc!=SQLITE_OK ){ diff --git a/test/trace3.test b/test/trace3.test index 1149bea3f2..0809759d80 100644 --- a/test/trace3.test +++ b/test/trace3.test @@ -192,6 +192,10 @@ do_test trace3-8.8 { list [sqlite3_bind_blob $STMT 1 "\x12\x34\x56" 3] \ [sqlite3_expanded_sql $STMT] } {{} {SELECT a, b FROM t1 WHERE b = x'123456' ORDER BY a;}} +do_test trace3-8.9 { + list [sqlite3_bind_blob $STMT 1 "\xAB\xCD\xEF" 3] \ + [sqlite3_expanded_sql $STMT] +} {{} {SELECT a, b FROM t1 WHERE b = x'abcdef' ORDER BY a;}} do_test trace3-9.1 { sqlite3_finalize $STMT From eb5a549ecfb1fb67c66b1061f5db95bae46f4c47 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 15 Jul 2016 02:50:18 +0000 Subject: [PATCH 0574/1484] Disable the CSV extension when virtual tables are disabled. FossilOrigin-Name: ec7180892ac737f0731cf61f2d095a5c1d18ad93 --- ext/misc/csv.c | 7 +++++++ manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/ext/misc/csv.c b/ext/misc/csv.c index 3a7e32d311..a055a8df13 100644 --- a/ext/misc/csv.c +++ b/ext/misc/csv.c @@ -48,6 +48,8 @@ SQLITE_EXTENSION_INIT1 #include #include +#ifndef SQLITE_OMIT_VIRTUALTABLE + /* ** A macro to hint to the compiler that a function should not be ** inlined. @@ -834,6 +836,7 @@ static sqlite3_module CsvModuleFauxWrite = { }; #endif /* SQLITE_TEST */ +#endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) */ #ifdef _WIN32 @@ -849,6 +852,7 @@ int sqlite3_csv_init( char **pzErrMsg, const sqlite3_api_routines *pApi ){ +#ifndef SQLITE_OMIT_VIRTUALTABLE int rc; SQLITE_EXTENSION_INIT2(pApi); rc = sqlite3_create_module(db, "csv", &CsvModule, 0); @@ -858,4 +862,7 @@ int sqlite3_csv_init( } #endif return rc; +#else + return SQLITE_OK; +#endif } diff --git a/manifest b/manifest index 966b26fc0e..3e9a346ef3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sALTER\sTABLE\sso\sthat\sit\sdoes\snot\spromote\sthe\sschema\sversion\spast\s3,\sas\nthat\swill\scause\sDESC\sindexes\sto\sgo\scorrupt.\nTicket\s[f68bf68513a1c]. -D 2016-07-14T19:13:11.812 +C Disable\sthe\sCSV\sextension\swhen\svirtual\stables\sare\sdisabled. +D 2016-07-15T02:50:18.913 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -207,7 +207,7 @@ F ext/misc/amatch.c 211108e201105e4bb0c076527b8cfd34330fc234 F ext/misc/carray.c 214c9e9d909ceaae3b2f5f917cc2204deca85cc6 F ext/misc/closure.c 0d2a038df8fbae7f19de42e7c7d71f2e4dc88704 F ext/misc/compress.c 122faa92d25033d6c3f07c39231de074ab3d2e83 -F ext/misc/csv.c b92692b057707f5b7bb91feaedde790b2e38304e +F ext/misc/csv.c f51b0566ea15e24cce871037e30a4db99ea6cf77 F ext/misc/eval.c f971962e92ebb8b0a4e6b62949463ee454d88fa2 F ext/misc/fileio.c d4171c815d6543a9edef8308aab2951413cd8d0f F ext/misc/fuzzer.c 7c64b8197bb77b7d64eff7cac7848870235d4c25 @@ -1505,7 +1505,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 824b39e54fb9ba562be4d92cc9a54aee1cdf84cb -R 7d842c7254944c448483c1d7ddff9ad6 +P a7db6e45ad45be9b3003f61d4163f543498a7c9d +R ec00a189cb07c46ebd136f03f1e34d37 U drh -Z f6a6c237e43006b812e6af2a3e69c586 +Z 4982072efce5132597470baa33eb57d2 diff --git a/manifest.uuid b/manifest.uuid index 1fc14b81a9..3747973d87 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a7db6e45ad45be9b3003f61d4163f543498a7c9d \ No newline at end of file +ec7180892ac737f0731cf61f2d095a5c1d18ad93 \ No newline at end of file From 8d85364261a96a0e370bce1f1f6b858612e838f0 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 15 Jul 2016 10:01:06 +0000 Subject: [PATCH 0575/1484] The sqlite3_expanded_sql() function compiles, but always returns NULL, when the SQLITE_OMIT_TRACE compile-time option is used. FossilOrigin-Name: 53c25ebe34e6776a12260078852973b1d581d20f --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/sqlite.h.in | 4 +++- src/test1.c | 2 +- src/vdbeaux.c | 4 ++++ 5 files changed, 17 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 373a08e7de..fdc8e8e54c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sfixes\sfrom\strunk.\s\sFix\sthe\stclsqlite.test\sscript. -D 2016-07-15T02:55:51.860 +C The\ssqlite3_expanded_sql()\sfunction\scompiles,\sbut\salways\sreturns\sNULL,\swhen\nthe\sSQLITE_OMIT_TRACE\scompile-time\soption\sis\sused. +D 2016-07-15T10:01:06.596 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -385,7 +385,7 @@ F src/resolve.c cca3aa77b95706df5d635a2141a4d1de60ae6598 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c f3c6e9065fb34f6a23af27ec7f1f717ffbfc2ee4 F src/shell.c a8a9e392a6a2777fabf5feb536931cb190f235e5 -F src/sqlite.h.in 6ba80e88ee17b9071f35121271784ecef60df863 +F src/sqlite.h.in aad252c428329522c4146a8da236e92496b15de5 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 46f300b6e300e0fa916d7d58c44b53415b8471a9 F src/sqliteInt.h 48cd97eb134665348393dfe277b4c14d1085bfc7 @@ -393,7 +393,7 @@ F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c 5b18f9526900f61189ab0b83f1ef41d9f871a2ab F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 F src/tclsqlite.c 573e63c959b314d77486f3565fa79c60cda3df7e -F src/test1.c 4bdfccf93a33453b427fb01cf12dfe26a5dd2cbc +F src/test1.c 186e3b53c402b7a73bcb4ade2b77709675c39fe3 F src/test2.c 5586f43fcd9a1be0830793cf9d354082c261b25b F src/test3.c c75c8af0eadb335236c9e61b51044c58a8f7dd59 F src/test4.c d168f83cc78d02e8d35567bb5630e40dcd85ac1e @@ -453,7 +453,7 @@ F src/vdbe.c 7b5570f77e32766949fd8f9478e4a9bb06e6ab24 F src/vdbe.h 67bc551f7faf04c33493892e4b378aada823ed10 F src/vdbeInt.h c59381049af5c7751a83456c39b80d1a6fde1f9d F src/vdbeapi.c 460b90f7f0894753d33df377702c1dc9cc5fa21b -F src/vdbeaux.c 08a459b6906dfcce0e921daba3a471a28ea65d41 +F src/vdbeaux.c 23df1e66e420a0e591bc877eace43be1f16f0f28 F src/vdbeblob.c 83d2d266383157b02e2b809350bb197e89d7895b F src/vdbemem.c 1ecaa5ee0caff07255f25d04e8dc88befb6f88d1 F src/vdbesort.c 91fda3909326860382b0ca8aa251e609c6a9d62c @@ -1506,7 +1506,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e03c81895e52096ab055d8231841e9070602ca84 ec7180892ac737f0731cf61f2d095a5c1d18ad93 -R 8bd18a5122e19b3b0675d3bc2674a51e +P d2b1fa55e8809ffc25a25f256349b8d08beadab5 +R 62f79e8e18332d747e11f9ca2d1624d9 U drh -Z 68d53222f802b7ae8fc8a7f808e2ed8d +Z 83a3df8e5ff251b53fc0f846b015b7e8 diff --git a/manifest.uuid b/manifest.uuid index af07c18f62..84bd71ab4a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d2b1fa55e8809ffc25a25f256349b8d08beadab5 \ No newline at end of file +53c25ebe34e6776a12260078852973b1d581d20f \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 8b9aa7402d..2a34fb8e9d 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -3510,7 +3510,9 @@ int sqlite3_prepare16_v2( ** will return "SELECT 2345,NULL". ** ** The [SQLITE_TRACE_SIZE_LIMIT] setting limits the size of a -** bound parameter expansion. +** bound parameter expansion. If SQLite is built with the +** [SQLITE_OMIT_TRACE] compile-time option then the sqlite3_expanded_sql() +** interface is non-functional and always returns NULL. ** ** ^The string returned by sqlite3_sql(P) is managed by SQLite and is ** automatically freed when the prepared statement is finalized. diff --git a/src/test1.c b/src/test1.c index 11cd17e722..7d83881139 100644 --- a/src/test1.c +++ b/src/test1.c @@ -3653,7 +3653,7 @@ static int test_bind_blob( if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR; - value = Tcl_GetByteArrayFromObj(objv[3], &len); + value = (char*)Tcl_GetByteArrayFromObj(objv[3], &len); if( Tcl_GetIntFromObj(interp, objv[4], &bytes) ) return TCL_ERROR; if( bytes>len ){ diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 72a882c176..ec702b3c8c 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -82,9 +82,13 @@ const char *sqlite3_sql(sqlite3_stmt *pStmt){ ** expanded bound parameters. */ char *sqlite3_expanded_sql(sqlite3_stmt *pStmt){ +#ifdef SQLITE_OMIT_TRACE + return 0; +#else Vdbe *p = (Vdbe *)pStmt; if( p==0 || p->zSql==0 ) return 0; return sqlite3VdbeExpandSql(p, p->zSql); +#endif } /* From 8414e81359076c73a176627df912ed0e33c46d10 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 15 Jul 2016 19:17:19 +0000 Subject: [PATCH 0576/1484] Add the largely untested SQLITE_FTS5_NO_WITHOUT_ROWID compile time option to fts5. For building a dynamically loadable extension that does not use WITHOUT ROWID. FossilOrigin-Name: d0a1cf1c56c237617fb73cb31f4950365b1f3e9b --- ext/fts5/fts5_storage.c | 6 +++++- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/ext/fts5/fts5_storage.c b/ext/fts5/fts5_storage.c index 90df3396c3..a695887458 100644 --- a/ext/fts5/fts5_storage.c +++ b/ext/fts5/fts5_storage.c @@ -247,7 +247,11 @@ int sqlite3Fts5CreateTable( char *zErr = 0; rc = fts5ExecPrintf(pConfig->db, &zErr, "CREATE TABLE %Q.'%q_%q'(%s)%s", - pConfig->zDb, pConfig->zName, zPost, zDefn, bWithout?" WITHOUT ROWID":"" + pConfig->zDb, pConfig->zName, zPost, zDefn, +#ifndef SQLITE_FTS5_NO_WITHOUT_ROWID + bWithout?" WITHOUT ROWID": +#endif + "" ); if( zErr ){ *pzErr = sqlite3_mprintf( diff --git a/manifest b/manifest index 3e9a346ef3..9a69ac1bf0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Disable\sthe\sCSV\sextension\swhen\svirtual\stables\sare\sdisabled. -D 2016-07-15T02:50:18.913 +C Add\sthe\slargely\suntested\sSQLITE_FTS5_NO_WITHOUT_ROWID\scompile\stime\soption\sto\sfts5.\sFor\sbuilding\sa\sdynamically\sloadable\sextension\sthat\sdoes\snot\suse\sWITHOUT\sROWID. +D 2016-07-15T19:17:19.168 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -106,7 +106,7 @@ F ext/fts5/fts5_expr.c bcb238ee4ac1164302ab528487520488516bd030 F ext/fts5/fts5_hash.c 880998e596b60f078348d48732ca4ad9a90caad2 F ext/fts5/fts5_index.c b429e23fabb57506f71e406997cc46b89190dc97 F ext/fts5/fts5_main.c f85281445dcf8be32d18841c93a6f90fe27dbfe2 -F ext/fts5/fts5_storage.c 3309c6a8e34b974513016fd1ef47c83f5898f94c +F ext/fts5/fts5_storage.c de0ed8a06738bde433afe11e92295ceaffbc4e58 F ext/fts5/fts5_tcl.c f8731e0508299bd43f1a2eff7dbeaac870768966 F ext/fts5/fts5_test_mi.c 783b86697ebf773c18fc109992426c0173a055bc F ext/fts5/fts5_test_tok.c db08af63673c3a7d39f053b36fd6e065017706be @@ -1505,7 +1505,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a7db6e45ad45be9b3003f61d4163f543498a7c9d -R ec00a189cb07c46ebd136f03f1e34d37 -U drh -Z 4982072efce5132597470baa33eb57d2 +P ec7180892ac737f0731cf61f2d095a5c1d18ad93 +R e7e67692a9bf28fabbef5b90b609823b +U dan +Z 6e92686cc60df8d9ecf6a38e315fe4e5 diff --git a/manifest.uuid b/manifest.uuid index 3747973d87..6d86586167 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ec7180892ac737f0731cf61f2d095a5c1d18ad93 \ No newline at end of file +d0a1cf1c56c237617fb73cb31f4950365b1f3e9b \ No newline at end of file From 89441bf185b7d6ee79164bcc4198eaff0e98fe2e Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 21 Jul 2016 16:43:54 +0000 Subject: [PATCH 0577/1484] Add new test file vacuummem.test. To test that any temporary memory used by VACUUM is freed as soon as the VACUUM has finished (not, for example, when sqlite3_close() is finally called). FossilOrigin-Name: 1b1ad0b28c392ade4321734e9b022a545b845b04 --- manifest | 11 ++++----- manifest.uuid | 2 +- test/vacuummem.test | 54 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 61 insertions(+), 6 deletions(-) create mode 100644 test/vacuummem.test diff --git a/manifest b/manifest index 9a69ac1bf0..d47aa8101b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\slargely\suntested\sSQLITE_FTS5_NO_WITHOUT_ROWID\scompile\stime\soption\sto\sfts5.\sFor\sbuilding\sa\sdynamically\sloadable\sextension\sthat\sdoes\snot\suse\sWITHOUT\sROWID. -D 2016-07-15T19:17:19.168 +C Add\snew\stest\sfile\svacuummem.test.\sTo\stest\sthat\sany\stemporary\smemory\sused\sby\sVACUUM\sis\sfreed\sas\ssoon\sas\sthe\sVACUUM\shas\sfinished\s(not,\sfor\sexample,\swhen\ssqlite3_close()\sis\sfinally\scalled). +D 2016-07-21T16:43:54.563 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -1323,6 +1323,7 @@ F test/vacuum.test ce91c39f7f91a4273bf620efad21086b5aa6ef1d F test/vacuum2.test aa048abee196c16c9ba308465494009057b79f9b F test/vacuum3.test 77ecdd54592b45a0bcb133339f99f1ae0ae94d0d F test/vacuum4.test d3f8ecff345f166911568f397d2432c16d2867d9 +F test/vacuummem.test 09c8b72a12405649ed84564367dad729bff88760 F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102 F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661 F test/view.test 765802c7a66d37fabd5ac8e2f2dbe572b43eb9ab @@ -1505,7 +1506,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ec7180892ac737f0731cf61f2d095a5c1d18ad93 -R e7e67692a9bf28fabbef5b90b609823b +P d0a1cf1c56c237617fb73cb31f4950365b1f3e9b +R c861801c1aa1bd5e3e0533101c0a9583 U dan -Z 6e92686cc60df8d9ecf6a38e315fe4e5 +Z 9b35e9b2fd0052d524acf36a9f5b4f2b diff --git a/manifest.uuid b/manifest.uuid index 6d86586167..9af2c82fe3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d0a1cf1c56c237617fb73cb31f4950365b1f3e9b \ No newline at end of file +1b1ad0b28c392ade4321734e9b022a545b845b04 \ No newline at end of file diff --git a/test/vacuummem.test b/test/vacuummem.test new file mode 100644 index 0000000000..967e28cec7 --- /dev/null +++ b/test/vacuummem.test @@ -0,0 +1,54 @@ +# 2005 February 15 +# +# 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 regression tests for SQLite library. The +# focus of this file is testing that the VACUUM statement correctly +# frees any memory used for a temporary cache. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix vacuummem + +proc memory_used {} { + set stat [sqlite3_status SQLITE_STATUS_MEMORY_USED 1] + lindex $stat 1 +} + +do_execsql_test 1.0 { + PRAGMA cache_size = -2000; + CREATE TABLE t1(a, b, c); + + WITH r(i) AS ( + SELECT 1 UNION ALL SELECT i+1 FROM r WHERE i<100000 + ) + INSERT INTO t1 SELECT randomblob(100),randomblob(100),randomblob(100) FROM r; + + CREATE INDEX t1a ON t1(a); + CREATE INDEX t1b ON t1(b); + CREATE INDEX t1c ON t1(c); +} + +do_test 1.1 { memory_used } {#/2300000/} + +do_execsql_test 1.2 VACUUM + +do_test 1.3 { memory_used } {#/2300000/} + +do_execsql_test 1.4 { + SELECT count(*) FROM t1 WHERE +a IS NOT NULL +} {100000} + +do_test 1.5 { memory_used } {#/2300000/} + + + +finish_test + From 033ac6af7e7fd926299e5b2f9a50a727676681b9 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 21 Jul 2016 18:02:20 +0000 Subject: [PATCH 0578/1484] Add extra test cases to verify the fix in [64ca1a835]. FossilOrigin-Name: bf98a2de7ed41a8acca89d7369b353f12182cfb4 --- ext/fts5/test/fts5rank.test | 35 ++++++++++++++++++++++++++++++----- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 37 insertions(+), 12 deletions(-) diff --git a/ext/fts5/test/fts5rank.test b/ext/fts5/test/fts5rank.test index e958aea15b..a70c5d68e3 100644 --- a/ext/fts5/test/fts5rank.test +++ b/ext/fts5/test/fts5rank.test @@ -100,30 +100,55 @@ do_test 2.7 { # following tests verify that that problem has been addressed. # foreach_detail_mode $::testprefix { - do_execsql_test 3.0 { + do_execsql_test 3.1.0 { CREATE VIRTUAL TABLE y1 USING fts5(z, detail=%DETAIL%); INSERT INTO y1 VALUES('test xyz'); INSERT INTO y1 VALUES('test test xyz test'); INSERT INTO y1 VALUES('test test xyz'); } - do_execsql_test 3.1 { + do_execsql_test 3.1.1 { SELECT rowid FROM y1('test OR tset'); } {1 2 3} - do_execsql_test 3.2 { + do_execsql_test 3.1.2 { SELECT rowid FROM y1('test OR tset') ORDER BY bm25(y1) } {2 3 1} - do_execsql_test 3.3 { + do_execsql_test 3.1.3 { SELECT rowid FROM y1('test OR tset') ORDER BY +rank } {2 3 1} - do_execsql_test 3.4 { + do_execsql_test 3.1.4 { SELECT rowid FROM y1('test OR tset') ORDER BY rank } {2 3 1} + + do_execsql_test 3.1.5 { + SELECT rowid FROM y1('test OR xyz') ORDER BY rank + } {3 2 1} + + + do_execsql_test 3.2.1 { + CREATE VIRTUAL TABLE z1 USING fts5(a, detail=%DETAIL%); + INSERT INTO z1 VALUES('wrinkle in time'); + SELECT * FROM z1 WHERE z1 MATCH 'wrinkle in time OR a wrinkle in time'; + } {{wrinkle in time}} } +do_execsql_test 4.1 { + DROP TABLE IF EXISTS VTest; + CREATE virtual TABLE VTest USING FTS5( + Title, AUthor, tokenize ='porter unicode61 remove_diacritics 1', + columnsize='1', detail=full + ); + INSERT INTO VTest (Title, Author) VALUES ('wrinkle in time', 'Bill Smith'); + + SELECT * FROM VTest WHERE + VTest MATCH 'wrinkle in time OR a wrinkle in time' ORDER BY rank; +} {{wrinkle in time} {Bill Smith}} + + + finish_test diff --git a/manifest b/manifest index d47aa8101b..d38d5f0960 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\snew\stest\sfile\svacuummem.test.\sTo\stest\sthat\sany\stemporary\smemory\sused\sby\sVACUUM\sis\sfreed\sas\ssoon\sas\sthe\sVACUUM\shas\sfinished\s(not,\sfor\sexample,\swhen\ssqlite3_close()\sis\sfinally\scalled). -D 2016-07-21T16:43:54.563 +C Add\sextra\stest\scases\sto\sverify\sthe\sfix\sin\s[64ca1a835]. +D 2016-07-21T18:02:20.434 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -176,7 +176,7 @@ F ext/fts5/test/fts5porter.test 7cdc07bef301d70eebbfa75dcaf45c3680e1d0e1 F ext/fts5/test/fts5porter2.test 2e65633d58a1c525d5af0f6c01e5a59155bb3487 F ext/fts5/test/fts5prefix.test efd42e00bb8e8a36383f25c838185508681c093f F ext/fts5/test/fts5query.test f5ec25f5f2fbb70033424113cdffc101b1985a40 -F ext/fts5/test/fts5rank.test 3e55e7eeb4c98728e4a3171c9e994e1a2f24eb99 +F ext/fts5/test/fts5rank.test 2bdc0c5f22ccc1f9dbe9f4d0b82a491dce6f8a32 F ext/fts5/test/fts5rebuild.test 03935f617ace91ed23a6099c7c74d905227ff29b F ext/fts5/test/fts5restart.test c17728fdea26e7d0f617d22ad5b4b2862b994c17 F ext/fts5/test/fts5rowid.test 16908a99d6efc9ba21081b4f2b86b3fc699839a6 @@ -1506,7 +1506,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d0a1cf1c56c237617fb73cb31f4950365b1f3e9b -R c861801c1aa1bd5e3e0533101c0a9583 +P 1b1ad0b28c392ade4321734e9b022a545b845b04 +R 4cf3b663820541379bf632bbc3528bb8 U dan -Z 9b35e9b2fd0052d524acf36a9f5b4f2b +Z d680066d496973101c651a3de727e285 diff --git a/manifest.uuid b/manifest.uuid index 9af2c82fe3..2bc7fd5a25 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1b1ad0b28c392ade4321734e9b022a545b845b04 \ No newline at end of file +bf98a2de7ed41a8acca89d7369b353f12182cfb4 \ No newline at end of file From 12ca5ac3d2da1115b9462ebd65cddb850a550bfd Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 22 Jul 2016 10:09:26 +0000 Subject: [PATCH 0579/1484] Fix a problem with upper case module names in the "sqldiff --vtab" command. FossilOrigin-Name: 87e25fc472604b3978811be53991104c665a95e7 --- ext/rbu/rbudiff.test | 60 +++++++++++++++++++++++++++++++++++++++++++- manifest | 14 +++++------ manifest.uuid | 2 +- tool/sqldiff.c | 2 +- 4 files changed, 68 insertions(+), 10 deletions(-) diff --git a/ext/rbu/rbudiff.test b/ext/rbu/rbudiff.test index fa8de319dd..041a242428 100644 --- a/ext/rbu/rbudiff.test +++ b/ext/rbu/rbudiff.test @@ -203,7 +203,6 @@ foreach {tn init mod} { DELETE FROM 'x''y' WHERE rowid = 1; INSERT INTO 'x''y' VALUES('one two three'); } - } { forcedelete test.db test.db2 @@ -222,5 +221,64 @@ foreach {tn init mod} { } +ifcapable fts5 { + foreach {tn init mod} { + 1 { + CREATE VIRTUAL TABLE t1 USING fts5(c); + INSERT INTO t1 VALUES('a b c'); + INSERT INTO t1 VALUES('a b c'); + } { + DELETE FROM t1 WHERE rowid = 1; + INSERT INTO t1 VALUES('a b c'); + } + + 2 { + CREATE VIRTUAL TABLE t1 USING FTs5(c); + INSERT INTO t1 VALUES('a b c'); + INSERT INTO t1 VALUES('a b c'); + } { + DELETE FROM t1 WHERE rowid = 1; + INSERT INTO t1 VALUES('a b c'); + } + + 3 { + creAte virTUal +tablE t1 USING FTs5(c); + INSERT INTO t1 VALUES('a b c'); + INSERT INTO t1 VALUES('a b c'); + } { + DELETE FROM t1 WHERE rowid = 1; + INSERT INTO t1 VALUES('a b c'); + } + + } { + forcedelete test.db test.db2 + sqlite3 db test.db + db eval "$init" + sqlite3 db test.db2 + db eval "$init ; $mod" + db eval { INSERT INTO t1(t1) VALUES('optimize') } + db close + + do_test 3.$tn.1 { + set sql [get_vtab_rbudiff_sql test.db test.db2] + apply_rbudiff $sql test.db + } {SQLITE_DONE} + + sqlite3 db test.db + sqlite3 db2 test.db2 + do_test 3.$tn.2 { + db2 eval { SELECT * FROM t1 ORDER BY rowid } + } [db eval { SELECT * FROM t1 ORDER BY rowid }] + + do_test 3.$tn.3 { + db2 eval { INSERT INTO t1(t1) VALUES('integrity-check') } + } {} + + db close + db2 close + } +} + finish_test diff --git a/manifest b/manifest index d38d5f0960..15a467b95d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sextra\stest\scases\sto\sverify\sthe\sfix\sin\s[64ca1a835]. -D 2016-07-21T18:02:20.434 +C Fix\sa\sproblem\swith\supper\scase\smodule\snames\sin\sthe\s"sqldiff\s--vtab"\scommand. +D 2016-07-22T10:09:26.990 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -244,7 +244,7 @@ F ext/rbu/rbuB.test c25bc325b8072a766e56bb76c001866b405925c2 F ext/rbu/rbuC.test efe47db508a0269b683cb2a1913a425ffd39a831 F ext/rbu/rbu_common.tcl a38e8e2d4a50fd6aaf151633714c1b1d2fae3ead F ext/rbu/rbucrash.test 8d2ed5d4b05fef6c00c2a6b5f7ead71fa172a695 -F ext/rbu/rbudiff.test 4c9f8df6f723f553781d3d117501b7e9d170a145 +F ext/rbu/rbudiff.test b3c7675810b81de98a930a87fcd40d9ae545619d F ext/rbu/rbufault.test cc0be8d5d392d98b0c2d6a51be377ea989250a89 F ext/rbu/rbufault2.test 9a7f19edd6ea35c4c9f807d8a3db0a03a5670c06 F ext/rbu/rbufault3.test 54a399888ac4af44c68f9f58afbed23149428bca @@ -1473,7 +1473,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 7ce07da76b5e745783e703a834417d725b7d45fd F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c -F tool/sqldiff.c af5d80cdc88a91a0f3cccfaa316b5a27b213568a +F tool/sqldiff.c 4478f0d30230de6adde90bdb0bfe60f68c5ab782 F tool/srcck1.c 4c39bdfa9a92edd20233ee720df84dbeb2417602 F tool/stack_usage.tcl f8e71b92cdb099a147dad572375595eae55eca43 F tool/symbols-mingw.sh 4dbcea7e74768305384c9fd2ed2b41bbf9f0414d @@ -1506,7 +1506,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 1b1ad0b28c392ade4321734e9b022a545b845b04 -R 4cf3b663820541379bf632bbc3528bb8 +P bf98a2de7ed41a8acca89d7369b353f12182cfb4 +R 21feff5d71e42b08ceb5cf54c6ef8c4f U dan -Z d680066d496973101c651a3de727e285 +Z 0597e24d7597ffc51d59928722cf37fa diff --git a/manifest.uuid b/manifest.uuid index 2bc7fd5a25..a48b14490b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bf98a2de7ed41a8acca89d7369b353f12182cfb4 \ No newline at end of file +87e25fc472604b3978811be53991104c665a95e7 \ No newline at end of file diff --git a/tool/sqldiff.c b/tool/sqldiff.c index dbdf726df0..e92e8aab25 100644 --- a/tool/sqldiff.c +++ b/tool/sqldiff.c @@ -1822,7 +1822,7 @@ const char *all_tables_sql(){ int rc; rc = sqlite3_exec(g.db, - "CREATE TEMP TABLE tblmap(module, postfix);" + "CREATE TEMP TABLE tblmap(module COLLATE nocase, postfix);" "INSERT INTO temp.tblmap VALUES" "('fts3', '_content'), ('fts3', '_segments'), ('fts3', '_segdir')," From dec8bc0eb49b5af519ead428296dbfce884ae1cb Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 22 Jul 2016 20:20:53 +0000 Subject: [PATCH 0580/1484] Add requirements marks to the sqlite3_expanded_sql() documentation. FossilOrigin-Name: 409535e6dfc307f26ea3d9f51be51c439b6d7b22 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/sqlite.h.in | 8 ++++---- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index fdc8e8e54c..a198d7e20b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C The\ssqlite3_expanded_sql()\sfunction\scompiles,\sbut\salways\sreturns\sNULL,\swhen\nthe\sSQLITE_OMIT_TRACE\scompile-time\soption\sis\sused. -D 2016-07-15T10:01:06.596 +C Add\srequirements\smarks\sto\sthe\ssqlite3_expanded_sql()\sdocumentation. +D 2016-07-22T20:20:53.758 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -385,7 +385,7 @@ F src/resolve.c cca3aa77b95706df5d635a2141a4d1de60ae6598 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c f3c6e9065fb34f6a23af27ec7f1f717ffbfc2ee4 F src/shell.c a8a9e392a6a2777fabf5feb536931cb190f235e5 -F src/sqlite.h.in aad252c428329522c4146a8da236e92496b15de5 +F src/sqlite.h.in f1e866f8b789391ba7f77f71164e51b7f8b4b111 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 46f300b6e300e0fa916d7d58c44b53415b8471a9 F src/sqliteInt.h 48cd97eb134665348393dfe277b4c14d1085bfc7 @@ -1506,7 +1506,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d2b1fa55e8809ffc25a25f256349b8d08beadab5 -R 62f79e8e18332d747e11f9ca2d1624d9 +P 53c25ebe34e6776a12260078852973b1d581d20f +R d9d54b2d05c15d2014a2ffa7a3228fb1 U drh -Z 83a3df8e5ff251b53fc0f846b015b7e8 +Z 3464c79040c125df7d1b54a6ef5c52ad diff --git a/manifest.uuid b/manifest.uuid index 84bd71ab4a..5369a8751e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -53c25ebe34e6776a12260078852973b1d581d20f \ No newline at end of file +409535e6dfc307f26ea3d9f51be51c439b6d7b22 \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 2a34fb8e9d..5c4c373b80 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -3503,14 +3503,14 @@ int sqlite3_prepare16_v2( ** string containing the SQL text of prepared statement P with ** [bound parameters] expanded. ** -** For example, if a prepared statement is created using the SQL +** ^(For example, if a prepared statement is created using the SQL ** text "SELECT $abc,:xyz" and if parameter $abc is bound to integer 2345 ** and parameter :xyz is unbound, then sqlite3_sql() will return ** the original string, "SELECT $abc,:xyz" but sqlite3_expanded_sql() -** will return "SELECT 2345,NULL". +** will return "SELECT 2345,NULL".)^ ** -** The [SQLITE_TRACE_SIZE_LIMIT] setting limits the size of a -** bound parameter expansion. If SQLite is built with the +** ^The [SQLITE_TRACE_SIZE_LIMIT] setting limits the size of a +** bound parameter expansion. ^If SQLite is built with the ** [SQLITE_OMIT_TRACE] compile-time option then the sqlite3_expanded_sql() ** interface is non-functional and always returns NULL. ** From 9a8b9ec51c3cb0897d8a7311cf6216e9e34df480 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 22 Jul 2016 20:45:03 +0000 Subject: [PATCH 0581/1484] Be sure to hold the database connection mutex while calling sqlite3VdbeExpand() from within sqlite3_expanded_sql(). FossilOrigin-Name: 527b5ba68c0b0185958b945b197f9022951d9379 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbeaux.c | 6 +++++- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index a198d7e20b..cbb93bb180 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\srequirements\smarks\sto\sthe\ssqlite3_expanded_sql()\sdocumentation. -D 2016-07-22T20:20:53.758 +C Be\ssure\sto\shold\sthe\sdatabase\sconnection\smutex\swhile\scalling\ssqlite3VdbeExpand()\nfrom\swithin\ssqlite3_expanded_sql(). +D 2016-07-22T20:45:03.857 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -453,7 +453,7 @@ F src/vdbe.c 7b5570f77e32766949fd8f9478e4a9bb06e6ab24 F src/vdbe.h 67bc551f7faf04c33493892e4b378aada823ed10 F src/vdbeInt.h c59381049af5c7751a83456c39b80d1a6fde1f9d F src/vdbeapi.c 460b90f7f0894753d33df377702c1dc9cc5fa21b -F src/vdbeaux.c 23df1e66e420a0e591bc877eace43be1f16f0f28 +F src/vdbeaux.c 7a09b945ebc4893e3a15bd68c4634d4aff34ebd5 F src/vdbeblob.c 83d2d266383157b02e2b809350bb197e89d7895b F src/vdbemem.c 1ecaa5ee0caff07255f25d04e8dc88befb6f88d1 F src/vdbesort.c 91fda3909326860382b0ca8aa251e609c6a9d62c @@ -1506,7 +1506,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 53c25ebe34e6776a12260078852973b1d581d20f -R d9d54b2d05c15d2014a2ffa7a3228fb1 +P 409535e6dfc307f26ea3d9f51be51c439b6d7b22 +R 2b4fbb49220ef1cdb35ff0cc787c0937 U drh -Z 3464c79040c125df7d1b54a6ef5c52ad +Z 1a401e59c5d6714d520ae3898a7c3c7e diff --git a/manifest.uuid b/manifest.uuid index 5369a8751e..8a31fb63f9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -409535e6dfc307f26ea3d9f51be51c439b6d7b22 \ No newline at end of file +527b5ba68c0b0185958b945b197f9022951d9379 \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index ec702b3c8c..6eeb325b1e 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -86,8 +86,12 @@ char *sqlite3_expanded_sql(sqlite3_stmt *pStmt){ return 0; #else Vdbe *p = (Vdbe *)pStmt; + char *z; if( p==0 || p->zSql==0 ) return 0; - return sqlite3VdbeExpandSql(p, p->zSql); + sqlite3_mutex_enter(p->db->mutex); + z = sqlite3VdbeExpandSql(p, p->zSql); + sqlite3_mutex_leave(p->db->mutex); + return z; #endif } From 80f2b33a12214ca194babd468f2618ed805d2f95 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Fri, 22 Jul 2016 21:26:56 +0000 Subject: [PATCH 0582/1484] Fix harmless compiler warnings seen with MSVC. FossilOrigin-Name: 8bb6e6fcedf7d0ae796b8848593106c921ebf21a --- ext/misc/carray.c | 2 +- ext/misc/csv.c | 13 +++++++------ manifest | 16 ++++++++-------- manifest.uuid | 2 +- 4 files changed, 17 insertions(+), 16 deletions(-) diff --git a/ext/misc/carray.c b/ext/misc/carray.c index 6fdbecf575..3c2398ec45 100644 --- a/ext/misc/carray.c +++ b/ext/misc/carray.c @@ -247,7 +247,7 @@ static int carrayFilter( "unknown datatype: %Q", zType); return SQLITE_ERROR; }else{ - pCur->eType = i; + pCur->eType = (unsigned char)i; } } }else{ diff --git a/ext/misc/csv.c b/ext/misc/csv.c index a055a8df13..2a9463bd6e 100644 --- a/ext/misc/csv.c +++ b/ext/misc/csv.c @@ -232,7 +232,7 @@ static char *csv_read_one_field(CsvReader *p){ || (c==EOF && pc=='"') ){ do{ p->n--; }while( p->z[p->n]!='"' ); - p->cTerm = c; + p->cTerm = (char)c; break; } if( pc=='"' && c!='\r' ){ @@ -242,7 +242,7 @@ static char *csv_read_one_field(CsvReader *p){ if( c==EOF ){ csv_errmsg(p, "line %d: unterminated %c-quoted field\n", startLine, '"'); - p->cTerm = c; + p->cTerm = (char)c; break; } } @@ -259,7 +259,7 @@ static char *csv_read_one_field(CsvReader *p){ p->nLine++; if( p->n>0 && p->z[p->n-1]=='\r' ) p->n--; } - p->cTerm = c; + p->cTerm = (char)c; } if( p->z ) p->z[p->n] = 0; return p->z; @@ -338,9 +338,9 @@ static void csv_trim_whitespace(char *z){ /* Dequote the string */ static void csv_dequote(char *z){ - int i, j; + int j; char cQuote = z[0]; - size_t n; + size_t i, n; if( cQuote!='\'' && cQuote!='"' ) return; n = strlen(z); @@ -725,7 +725,8 @@ static int csvtabFilter( pCur->iRowid = 0; if( pCur->rdr.in==0 ){ assert( pCur->rdr.zIn==pTab->zData ); - assert( pTab->iStart<=pCur->rdr.nIn ); + assert( pTab->iStart>=0 ); + assert( (size_t)pTab->iStart<=pCur->rdr.nIn ); pCur->rdr.iIn = pTab->iStart; }else{ fseek(pCur->rdr.in, pTab->iStart, SEEK_SET); diff --git a/manifest b/manifest index 15a467b95d..718e7796c0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\swith\supper\scase\smodule\snames\sin\sthe\s"sqldiff\s--vtab"\scommand. -D 2016-07-22T10:09:26.990 +C Fix\sharmless\scompiler\swarnings\sseen\swith\sMSVC. +D 2016-07-22T21:26:56.199 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -204,10 +204,10 @@ F ext/icu/README.txt d9fbbad0c2f647c3fdf715fc9fd64af53aedfc43 F ext/icu/icu.c 43df9d8ef2fae7a325100ebd713ab089dc829dd7 F ext/icu/sqliteicu.h 728867a802baa5a96de7495e9689a8e01715ef37 F ext/misc/amatch.c 211108e201105e4bb0c076527b8cfd34330fc234 -F ext/misc/carray.c 214c9e9d909ceaae3b2f5f917cc2204deca85cc6 +F ext/misc/carray.c b0478416ab01368e40c4e9231c4e15c00a6c1c4c F ext/misc/closure.c 0d2a038df8fbae7f19de42e7c7d71f2e4dc88704 F ext/misc/compress.c 122faa92d25033d6c3f07c39231de074ab3d2e83 -F ext/misc/csv.c f51b0566ea15e24cce871037e30a4db99ea6cf77 +F ext/misc/csv.c 816a3715356e4210dae2d242057745e937050896 F ext/misc/eval.c f971962e92ebb8b0a4e6b62949463ee454d88fa2 F ext/misc/fileio.c d4171c815d6543a9edef8308aab2951413cd8d0f F ext/misc/fuzzer.c 7c64b8197bb77b7d64eff7cac7848870235d4c25 @@ -1506,7 +1506,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P bf98a2de7ed41a8acca89d7369b353f12182cfb4 -R 21feff5d71e42b08ceb5cf54c6ef8c4f -U dan -Z 0597e24d7597ffc51d59928722cf37fa +P 87e25fc472604b3978811be53991104c665a95e7 +R 0235f59a00c54f640f61c277b29bcc69 +U mistachkin +Z 015e7c1f4d0390bbef94656d13220477 diff --git a/manifest.uuid b/manifest.uuid index a48b14490b..efdad925f7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -87e25fc472604b3978811be53991104c665a95e7 \ No newline at end of file +8bb6e6fcedf7d0ae796b8848593106c921ebf21a \ No newline at end of file From a4c07346b79cff61782e9bb6eb8812aea156f8ce Mon Sep 17 00:00:00 2001 From: mistachkin Date: Fri, 22 Jul 2016 21:35:38 +0000 Subject: [PATCH 0583/1484] Revise a warning fix from the previous check-in to improve clarity. Also, fix an incorrect test prefix (typo). FossilOrigin-Name: f50a3fd6606c14b82c9b938bfca284d54b6c650f --- ext/misc/carray.c | 4 ++-- manifest | 14 +++++++------- manifest.uuid | 2 +- test/csv01.test | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/ext/misc/carray.c b/ext/misc/carray.c index 3c2398ec45..025eb5db2c 100644 --- a/ext/misc/carray.c +++ b/ext/misc/carray.c @@ -237,7 +237,7 @@ static int carrayFilter( if( idxNum<3 ){ pCur->eType = CARRAY_INT32; }else{ - int i; + unsigned char i; const char *zType = (const char*)sqlite3_value_text(argv[2]); for(i=0; ieType = (unsigned char)i; + pCur->eType = i; } } }else{ diff --git a/manifest b/manifest index 718e7796c0..1a7b6fcb75 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\scompiler\swarnings\sseen\swith\sMSVC. -D 2016-07-22T21:26:56.199 +C Revise\sa\swarning\sfix\sfrom\sthe\sprevious\scheck-in\sto\simprove\sclarity.\s\sAlso,\sfix\san\sincorrect\stest\sprefix\s(typo). +D 2016-07-22T21:35:38.430 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -204,7 +204,7 @@ F ext/icu/README.txt d9fbbad0c2f647c3fdf715fc9fd64af53aedfc43 F ext/icu/icu.c 43df9d8ef2fae7a325100ebd713ab089dc829dd7 F ext/icu/sqliteicu.h 728867a802baa5a96de7495e9689a8e01715ef37 F ext/misc/amatch.c 211108e201105e4bb0c076527b8cfd34330fc234 -F ext/misc/carray.c b0478416ab01368e40c4e9231c4e15c00a6c1c4c +F ext/misc/carray.c 40c27641010a4dc67e3690bdb7c9d36ca58b3c2d F ext/misc/closure.c 0d2a038df8fbae7f19de42e7c7d71f2e4dc88704 F ext/misc/compress.c 122faa92d25033d6c3f07c39231de074ab3d2e83 F ext/misc/csv.c 816a3715356e4210dae2d242057745e937050896 @@ -616,7 +616,7 @@ F test/crashM.test d95f59046fa749b0d0822edf18a717788c8f318d F test/crashtest1.c 09c1c7d728ccf4feb9e481671e29dda5669bbcc2 F test/createtab.test b5de160630b209c4b8925bdcbbaf48cc90b67fe8 F test/cse.test 277350a26264495e86b1785f34d2d0c8600e021c -F test/csv01.test 0929a9ce47021519512be92861f29e32d2538e5f +F test/csv01.test e0ba3caaa57e4c667a0b45977689fb8082f14348 F test/ctime.test 0b995accd44a52914bd4744d5c1b6e1a56c7897c F test/cursorhint.test 7bc346788390475e77a345da2b92270d04d35856 F test/cursorhint2.test 2b45341d32d1aae9991a00ef31ebca339b274255 @@ -1506,7 +1506,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 87e25fc472604b3978811be53991104c665a95e7 -R 0235f59a00c54f640f61c277b29bcc69 +P 8bb6e6fcedf7d0ae796b8848593106c921ebf21a +R 5b6ff2c3db1a5eba26e3cea3eedea20b U mistachkin -Z 015e7c1f4d0390bbef94656d13220477 +Z 074e5835acae805d82010c066036788b diff --git a/manifest.uuid b/manifest.uuid index efdad925f7..2171fc8fa7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8bb6e6fcedf7d0ae796b8848593106c921ebf21a \ No newline at end of file +f50a3fd6606c14b82c9b938bfca284d54b6c650f \ No newline at end of file diff --git a/test/csv01.test b/test/csv01.test index a6fff81c3f..8151c47714 100644 --- a/test/csv01.test +++ b/test/csv01.test @@ -13,7 +13,7 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl -set testprefix closure01 +set testprefix csv01 ifcapable !vtab||!cte { finish_test ; return } From cf1e395acb41d886d72aa77d7e49f08ed1d36317 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 23 Jul 2016 00:43:14 +0000 Subject: [PATCH 0584/1484] Fix sqlite3VdbeExpandSql() so that it handles OOMs by always returning NULL. FossilOrigin-Name: 5a027fe4127d498e0dc0d9439131c6a29085cf0a --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/vdbeaux.c | 14 ++++++++------ src/vdbetrace.c | 13 ++++++++++--- 4 files changed, 26 insertions(+), 17 deletions(-) diff --git a/manifest b/manifest index cbb93bb180..a844004956 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Be\ssure\sto\shold\sthe\sdatabase\sconnection\smutex\swhile\scalling\ssqlite3VdbeExpand()\nfrom\swithin\ssqlite3_expanded_sql(). -D 2016-07-22T20:45:03.857 +C Fix\ssqlite3VdbeExpandSql()\sso\sthat\sit\shandles\sOOMs\sby\salways\sreturning\sNULL. +D 2016-07-23T00:43:14.540 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -453,11 +453,11 @@ F src/vdbe.c 7b5570f77e32766949fd8f9478e4a9bb06e6ab24 F src/vdbe.h 67bc551f7faf04c33493892e4b378aada823ed10 F src/vdbeInt.h c59381049af5c7751a83456c39b80d1a6fde1f9d F src/vdbeapi.c 460b90f7f0894753d33df377702c1dc9cc5fa21b -F src/vdbeaux.c 7a09b945ebc4893e3a15bd68c4634d4aff34ebd5 +F src/vdbeaux.c 8557563e9b0fed6ba05b0ce42e3b3049d93f26fa F src/vdbeblob.c 83d2d266383157b02e2b809350bb197e89d7895b F src/vdbemem.c 1ecaa5ee0caff07255f25d04e8dc88befb6f88d1 F src/vdbesort.c 91fda3909326860382b0ca8aa251e609c6a9d62c -F src/vdbetrace.c d0371769fe66fe4eb85bdcacf82b6f2af50feb9b +F src/vdbetrace.c bea16fb07070b33f6efdece3169c3c4b423894a8 F src/vtab.c 948d2d4984219eee37a7bf427d6667e21e6eb92e F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 02eeecc265f6ffd0597378f5d8ae9070b62a406a @@ -1506,7 +1506,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 409535e6dfc307f26ea3d9f51be51c439b6d7b22 -R 2b4fbb49220ef1cdb35ff0cc787c0937 +P 527b5ba68c0b0185958b945b197f9022951d9379 +R e119b9614fe99fd5a44e65f51db3182b U drh -Z 1a401e59c5d6714d520ae3898a7c3c7e +Z 16700eecfd0a8ed6af44720c8587b7e0 diff --git a/manifest.uuid b/manifest.uuid index 8a31fb63f9..7d4379e1ee 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -527b5ba68c0b0185958b945b197f9022951d9379 \ No newline at end of file +5a027fe4127d498e0dc0d9439131c6a29085cf0a \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 6eeb325b1e..b04a1d23f2 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -85,12 +85,14 @@ char *sqlite3_expanded_sql(sqlite3_stmt *pStmt){ #ifdef SQLITE_OMIT_TRACE return 0; #else - Vdbe *p = (Vdbe *)pStmt; - char *z; - if( p==0 || p->zSql==0 ) return 0; - sqlite3_mutex_enter(p->db->mutex); - z = sqlite3VdbeExpandSql(p, p->zSql); - sqlite3_mutex_leave(p->db->mutex); + char *z = 0; + const char *zSql = sqlite3_sql(pStmt); + if( zSql ){ + Vdbe *p = (Vdbe *)pStmt; + sqlite3_mutex_enter(p->db->mutex); + z = sqlite3VdbeExpandSql(p, zSql); + sqlite3_mutex_leave(p->db->mutex); + } return z; #endif } diff --git a/src/vdbetrace.c b/src/vdbetrace.c index 7311bc35c6..8a1c23bc35 100644 --- a/src/vdbetrace.c +++ b/src/vdbetrace.c @@ -81,6 +81,9 @@ char *sqlite3VdbeExpandSql( int i; /* Loop counter */ Mem *pVar; /* Value of a host parameter */ StrAccum out; /* Accumulate the output here */ +#ifndef SQLITE_OMIT_UTF16 + Mem utf8; /* Used to convert UTF16 parameters into UTF8 for display */ +#endif char zBase[100]; /* Initial working space */ db = p->db; @@ -135,12 +138,16 @@ char *sqlite3VdbeExpandSql( int nOut; /* Number of bytes of the string text to include in output */ #ifndef SQLITE_OMIT_UTF16 u8 enc = ENC(db); - Mem utf8; if( enc!=SQLITE_UTF8 ){ memset(&utf8, 0, sizeof(utf8)); utf8.db = db; - sqlite3VdbeMemSetStr(&utf8, pVar->z, pVar->n, enc, SQLITE_STATIC); - sqlite3VdbeChangeEncoding(&utf8, SQLITE_UTF8); + if( SQLITE_NOMEM== sqlite3VdbeMemSetStr(&utf8,pVar->z,pVar->n,enc,SQLITE_STATIC) + || SQLITE_NOMEM== sqlite3VdbeChangeEncoding(&utf8, SQLITE_UTF8) + ){ + sqlite3StrAccumReset(&out); + sqlite3VdbeMemRelease(&utf8); + return 0; + } pVar = &utf8; } #endif From 557341e8fa72f03a35768a34c33cfb18645f95cd Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 23 Jul 2016 02:07:26 +0000 Subject: [PATCH 0585/1484] Add requirements marks to the sqlite3_trace_v2() interface documentation. FossilOrigin-Name: ebd388e94da4a2b29c2a546f832d359619803ec5 --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/sqlite.h.in | 46 +++++++++++++++++++++++----------------------- src/vdbeapi.c | 33 +++++++++++++++++++++++++++++++++ src/vdbeaux.c | 33 --------------------------------- src/vdbetrace.c | 4 ++-- 6 files changed, 68 insertions(+), 68 deletions(-) diff --git a/manifest b/manifest index a844004956..631dae73d0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\ssqlite3VdbeExpandSql()\sso\sthat\sit\shandles\sOOMs\sby\salways\sreturning\sNULL. -D 2016-07-23T00:43:14.540 +C Add\srequirements\smarks\sto\sthe\ssqlite3_trace_v2()\sinterface\sdocumentation. +D 2016-07-23T02:07:26.475 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -385,7 +385,7 @@ F src/resolve.c cca3aa77b95706df5d635a2141a4d1de60ae6598 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c f3c6e9065fb34f6a23af27ec7f1f717ffbfc2ee4 F src/shell.c a8a9e392a6a2777fabf5feb536931cb190f235e5 -F src/sqlite.h.in f1e866f8b789391ba7f77f71164e51b7f8b4b111 +F src/sqlite.h.in 35e253c3b408157a9edc3306d4f1b770af73a398 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 46f300b6e300e0fa916d7d58c44b53415b8471a9 F src/sqliteInt.h 48cd97eb134665348393dfe277b4c14d1085bfc7 @@ -452,12 +452,12 @@ F src/vacuum.c 544ec90a66a4b0460b7c1baeadbc21b45e6ca0b6 F src/vdbe.c 7b5570f77e32766949fd8f9478e4a9bb06e6ab24 F src/vdbe.h 67bc551f7faf04c33493892e4b378aada823ed10 F src/vdbeInt.h c59381049af5c7751a83456c39b80d1a6fde1f9d -F src/vdbeapi.c 460b90f7f0894753d33df377702c1dc9cc5fa21b -F src/vdbeaux.c 8557563e9b0fed6ba05b0ce42e3b3049d93f26fa +F src/vdbeapi.c c3f6715a99995c11748ecad91d25e93fd9fc390b +F src/vdbeaux.c a32d79aeaa88dc2b97c261172d952d395254a055 F src/vdbeblob.c 83d2d266383157b02e2b809350bb197e89d7895b F src/vdbemem.c 1ecaa5ee0caff07255f25d04e8dc88befb6f88d1 F src/vdbesort.c 91fda3909326860382b0ca8aa251e609c6a9d62c -F src/vdbetrace.c bea16fb07070b33f6efdece3169c3c4b423894a8 +F src/vdbetrace.c 05d1f843117c4fdcc1f8b1e950011bbeef0cef84 F src/vtab.c 948d2d4984219eee37a7bf427d6667e21e6eb92e F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 02eeecc265f6ffd0597378f5d8ae9070b62a406a @@ -1506,7 +1506,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 527b5ba68c0b0185958b945b197f9022951d9379 -R e119b9614fe99fd5a44e65f51db3182b +P 5a027fe4127d498e0dc0d9439131c6a29085cf0a +R 424a44eb6e790a98bbdc6c3248de6bc5 U drh -Z 16700eecfd0a8ed6af44720c8587b7e0 +Z 5a7cc904a805d16230629029b0dc335a diff --git a/manifest.uuid b/manifest.uuid index 7d4379e1ee..4db50f7e69 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5a027fe4127d498e0dc0d9439131c6a29085cf0a \ No newline at end of file +ebd388e94da4a2b29c2a546f832d359619803ec5 \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 5c4c373b80..1308a1122d 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -2795,45 +2795,45 @@ SQLITE_DEPRECATED void *sqlite3_profile(sqlite3*, ** These constants identify classes of events that can be monitored ** using the [sqlite3_trace_v2()] tracing logic. The third argument ** to [sqlite3_trace_v2()] is an OR-ed combination of one or more of -** the following constants. The first argument to the trace callback +** the following constants. ^The first argument to the trace callback ** is one of the following constants. ** ** New tracing constants may be added in future releases. ** -** A trace callback has four arguments: xCallback(T,C,P,X). -** The T argument is one of the integer type codes above. -** The C argument is a copy of the context pointer passed in as the +** ^A trace callback has four arguments: xCallback(T,C,P,X). +** ^The T argument is one of the integer type codes above. +** ^The C argument is a copy of the context pointer passed in as the ** fourth argument to [sqlite3_trace_v2()]. ** The P and X arguments are pointers whose meanings depend on T. ** **
    ** [[SQLITE_TRACE_STMT]]
    SQLITE_TRACE_STMT
    -**
    An SQLITE_TRACE_STMT callback is invoked when a prepared statement +**
    ^An SQLITE_TRACE_STMT callback is invoked when a prepared statement ** first begins running and possibly at other times during the ** execution of the prepared statement, such as at the start of each -** trigger subprogram. The P argument is a pointer to the -** [prepared statement]. The X argument is a pointer to a string which +** trigger subprogram. ^The P argument is a pointer to the +** [prepared statement]. ^The X argument is a pointer to a string which ** is the expanded SQL text of the prepared statement or a comment that ** indicates the invocation of a trigger. ** ** [[SQLITE_TRACE_PROFILE]]
    SQLITE_TRACE_PROFILE
    -**
    An SQLITE_TRACE_PROFILE callback provides approximately the same +**
    ^An SQLITE_TRACE_PROFILE callback provides approximately the same ** information as is provided by the [sqlite3_profile()] callback. -** The P argument is a pointer to the [prepared statement] and the -** X argument points to a 64-bit integer which is the estimated of +** ^The P argument is a pointer to the [prepared statement] and the +** ^X argument points to a 64-bit integer which is the estimated of ** the number of nanosecond that the prepared statement took to run. -** The SQLITE_TRACE_PROFILE callback is invoked when the statement finishes. +** ^The SQLITE_TRACE_PROFILE callback is invoked when the statement finishes. ** ** [[SQLITE_TRACE_ROW]]
    SQLITE_TRACE_ROW
    -**
    An SQLITE_TRACE_ROW callback is invoked whenever a prepared +**
    ^An SQLITE_TRACE_ROW callback is invoked whenever a prepared ** statement generates a single row of result. -** The P argument is a pointer to the [prepared statement] and the +** ^The P argument is a pointer to the [prepared statement] and the ** X argument is unused. ** ** [[SQLITE_TRACE_CLOSE]]
    SQLITE_TRACE_CLOSE
    -**
    An SQLITE_TRACE_CLOSE callback is invoked when a database +**
    ^An SQLITE_TRACE_CLOSE callback is invoked when a database ** connection closes. -** The P argument is a pointer to the [database connection] object +** ^The P argument is a pointer to the [database connection] object ** and the X argument is unused. **
    */ @@ -2846,25 +2846,25 @@ SQLITE_DEPRECATED void *sqlite3_profile(sqlite3*, ** CAPI3REF: SQL Trace Hook ** METHOD: sqlite3 ** -** The sqlite3_trace_v2(D,M,X,P) interface registers a trace callback +** ^The sqlite3_trace_v2(D,M,X,P) interface registers a trace callback ** function X against [database connection] D, using property mask M -** and context pointer P. If the X callback is +** and context pointer P. ^If the X callback is ** NULL or if the M mask is zero, then tracing is disabled. The ** M argument must be one or more of the [SQLITE_TRACE] ** constants. ** -** Each call to either sqlite3_trace() or sqlite3_trace_v2() overrides +** ^Each call to either sqlite3_trace() or sqlite3_trace_v2() overrides ** (cancels) any prior calls to sqlite3_trace() or sqlite3_trace_v2(). ** -** The X callback is invoked whenever any of the events identified by -** mask M occur. The integer return value from the callback is currently +** ^The X callback is invoked whenever any of the events identified by +** mask M occur. ^The integer return value from the callback is currently ** ignored, though this may change in future releases. Callback ** implementations should return zero to ensure future compatibility. ** -** A trace callback is invoked with four arguments: callback(T,C,P,X). -** The T argument is one of the [SQLITE_TRACE] +** ^A trace callback is invoked with four arguments: callback(T,C,P,X). +** ^The T argument is one of the [SQLITE_TRACE] ** constants to indicate why the callback was invoked. -** The C argument is a copy of the context pointer. +** ^The C argument is a copy of the context pointer. ** The P and X arguments are pointers whose meanings depend on T. ** ** The sqlite3_trace_v2() interface is intended to replace the legacy diff --git a/src/vdbeapi.c b/src/vdbeapi.c index 883e5c95bf..b17c0e0a40 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -1612,6 +1612,39 @@ int sqlite3_stmt_status(sqlite3_stmt *pStmt, int op, int resetFlag){ return (int)v; } +/* +** Return the SQL associated with a prepared statement +*/ +const char *sqlite3_sql(sqlite3_stmt *pStmt){ + Vdbe *p = (Vdbe *)pStmt; + return p ? p->zSql : 0; +} + +/* +** Return the SQL associated with a prepared statement with +** bound parameters expanded. Space to hold the returned string is +** obtained from sqlite3_malloc(). The caller is responsible for +** freeing the returned string by passing it to sqlite3_free(). +** +** The SQLITE_TRACE_SIZE_LIMIT puts an upper bound on the size of +** expanded bound parameters. +*/ +char *sqlite3_expanded_sql(sqlite3_stmt *pStmt){ +#ifdef SQLITE_OMIT_TRACE + return 0; +#else + char *z = 0; + const char *zSql = sqlite3_sql(pStmt); + if( zSql ){ + Vdbe *p = (Vdbe *)pStmt; + sqlite3_mutex_enter(p->db->mutex); + z = sqlite3VdbeExpandSql(p, zSql); + sqlite3_mutex_leave(p->db->mutex); + } + return z; +#endif +} + #ifdef SQLITE_ENABLE_PREUPDATE_HOOK /* ** Allocate and populate an UnpackedRecord structure based on the serialized diff --git a/src/vdbeaux.c b/src/vdbeaux.c index b04a1d23f2..992fa4db9e 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -64,39 +64,6 @@ void sqlite3VdbeSetSql(Vdbe *p, const char *z, int n, int isPrepareV2){ p->isPrepareV2 = (u8)isPrepareV2; } -/* -** Return the SQL associated with a prepared statement -*/ -const char *sqlite3_sql(sqlite3_stmt *pStmt){ - Vdbe *p = (Vdbe *)pStmt; - return p ? p->zSql : 0; -} - -/* -** Return the SQL associated with a prepared statement with -** bound parameters expanded. Space to hold the returned string is -** obtained from sqlite3_malloc(). The caller is responsible for -** freeing the returned string by passing it to sqlite3_free(). -** -** The SQLITE_TRACE_SIZE_LIMIT puts an upper bound on the size of -** expanded bound parameters. -*/ -char *sqlite3_expanded_sql(sqlite3_stmt *pStmt){ -#ifdef SQLITE_OMIT_TRACE - return 0; -#else - char *z = 0; - const char *zSql = sqlite3_sql(pStmt); - if( zSql ){ - Vdbe *p = (Vdbe *)pStmt; - sqlite3_mutex_enter(p->db->mutex); - z = sqlite3VdbeExpandSql(p, zSql); - sqlite3_mutex_leave(p->db->mutex); - } - return z; -#endif -} - /* ** Swap all content between two VDBE structures. */ diff --git a/src/vdbetrace.c b/src/vdbetrace.c index 8a1c23bc35..d30cf3acd5 100644 --- a/src/vdbetrace.c +++ b/src/vdbetrace.c @@ -141,8 +141,8 @@ char *sqlite3VdbeExpandSql( if( enc!=SQLITE_UTF8 ){ memset(&utf8, 0, sizeof(utf8)); utf8.db = db; - if( SQLITE_NOMEM== sqlite3VdbeMemSetStr(&utf8,pVar->z,pVar->n,enc,SQLITE_STATIC) - || SQLITE_NOMEM== sqlite3VdbeChangeEncoding(&utf8, SQLITE_UTF8) + if( SQLITE_NOMEM==sqlite3VdbeMemSetStr(&utf8,pVar->z,pVar->n,enc,SQLITE_STATIC) + || SQLITE_NOMEM==sqlite3VdbeChangeEncoding(&utf8, SQLITE_UTF8) ){ sqlite3StrAccumReset(&out); sqlite3VdbeMemRelease(&utf8); From 8afffe7244c9e66c1667e92da35bb258b59ee170 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 23 Jul 2016 04:58:57 +0000 Subject: [PATCH 0586/1484] Improvements to sqlite3_trace_v2() documentation. Fix the sqlite3VdbeExpandSql() routine to respond better to OOM conditions. FossilOrigin-Name: 0400f642d542e62bb428e0bf263964c65691368e --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/sqlite.h.in | 17 ++++++++++------- src/vdbetrace.c | 11 +++++------ 4 files changed, 23 insertions(+), 21 deletions(-) diff --git a/manifest b/manifest index 631dae73d0..1bd6c3bab6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\srequirements\smarks\sto\sthe\ssqlite3_trace_v2()\sinterface\sdocumentation. -D 2016-07-23T02:07:26.475 +C Improvements\sto\ssqlite3_trace_v2()\sdocumentation.\s\sFix\sthe\nsqlite3VdbeExpandSql()\sroutine\sto\srespond\sbetter\sto\sOOM\sconditions. +D 2016-07-23T04:58:57.202 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -385,7 +385,7 @@ F src/resolve.c cca3aa77b95706df5d635a2141a4d1de60ae6598 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c f3c6e9065fb34f6a23af27ec7f1f717ffbfc2ee4 F src/shell.c a8a9e392a6a2777fabf5feb536931cb190f235e5 -F src/sqlite.h.in 35e253c3b408157a9edc3306d4f1b770af73a398 +F src/sqlite.h.in 3dc7317ded4bf66facd845705f45f21d03517940 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 46f300b6e300e0fa916d7d58c44b53415b8471a9 F src/sqliteInt.h 48cd97eb134665348393dfe277b4c14d1085bfc7 @@ -457,7 +457,7 @@ F src/vdbeaux.c a32d79aeaa88dc2b97c261172d952d395254a055 F src/vdbeblob.c 83d2d266383157b02e2b809350bb197e89d7895b F src/vdbemem.c 1ecaa5ee0caff07255f25d04e8dc88befb6f88d1 F src/vdbesort.c 91fda3909326860382b0ca8aa251e609c6a9d62c -F src/vdbetrace.c 05d1f843117c4fdcc1f8b1e950011bbeef0cef84 +F src/vdbetrace.c 41963d5376f0349842b5fc4aaaaacd7d9cdc0834 F src/vtab.c 948d2d4984219eee37a7bf427d6667e21e6eb92e F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 02eeecc265f6ffd0597378f5d8ae9070b62a406a @@ -1506,7 +1506,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 5a027fe4127d498e0dc0d9439131c6a29085cf0a -R 424a44eb6e790a98bbdc6c3248de6bc5 +P ebd388e94da4a2b29c2a546f832d359619803ec5 +R 19a6abe5f5ce376943dab16457333fb2 U drh -Z 5a7cc904a805d16230629029b0dc335a +Z 006f9291eaaf608f3169b0980f613014 diff --git a/manifest.uuid b/manifest.uuid index 4db50f7e69..06586e70c1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ebd388e94da4a2b29c2a546f832d359619803ec5 \ No newline at end of file +0400f642d542e62bb428e0bf263964c65691368e \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 1308a1122d..ed68cf0a13 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -2820,7 +2820,7 @@ SQLITE_DEPRECATED void *sqlite3_profile(sqlite3*, **
    ^An SQLITE_TRACE_PROFILE callback provides approximately the same ** information as is provided by the [sqlite3_profile()] callback. ** ^The P argument is a pointer to the [prepared statement] and the -** ^X argument points to a 64-bit integer which is the estimated of +** X argument points to a 64-bit integer which is the estimated of ** the number of nanosecond that the prepared statement took to run. ** ^The SQLITE_TRACE_PROFILE callback is invoked when the statement finishes. ** @@ -2850,8 +2850,8 @@ SQLITE_DEPRECATED void *sqlite3_profile(sqlite3*, ** function X against [database connection] D, using property mask M ** and context pointer P. ^If the X callback is ** NULL or if the M mask is zero, then tracing is disabled. The -** M argument must be one or more of the [SQLITE_TRACE] -** constants. +** M argument should be the bitwise OR-ed combination of +** zero or more [SQLITE_TRACE] constants. ** ** ^Each call to either sqlite3_trace() or sqlite3_trace_v2() overrides ** (cancels) any prior calls to sqlite3_trace() or sqlite3_trace_v2(). @@ -3509,10 +3509,13 @@ int sqlite3_prepare16_v2( ** the original string, "SELECT $abc,:xyz" but sqlite3_expanded_sql() ** will return "SELECT 2345,NULL".)^ ** -** ^The [SQLITE_TRACE_SIZE_LIMIT] setting limits the size of a -** bound parameter expansion. ^If SQLite is built with the -** [SQLITE_OMIT_TRACE] compile-time option then the sqlite3_expanded_sql() -** interface is non-functional and always returns NULL. +** ^The sqlite3_expanded_sql() interface returns NULL if insufficient memory +** is available to hold the result, or if the result would exceed the +** the maximum string length determined by the [SQLITE_LIMIT_LENGTH]. +** +** ^The [SQLITE_TRACE_SIZE_LIMIT] compile-time option limits the size of +** bound parameter expansions. ^The [SQLITE_OMIT_TRACE] compile-time +** option causes sqlite3_expanded_sql() to always return NULL. ** ** ^The string returned by sqlite3_sql(P) is managed by SQLite and is ** automatically freed when the prepared statement is finalized. diff --git a/src/vdbetrace.c b/src/vdbetrace.c index d30cf3acd5..7b47363991 100644 --- a/src/vdbetrace.c +++ b/src/vdbetrace.c @@ -141,12 +141,10 @@ char *sqlite3VdbeExpandSql( if( enc!=SQLITE_UTF8 ){ memset(&utf8, 0, sizeof(utf8)); utf8.db = db; - if( SQLITE_NOMEM==sqlite3VdbeMemSetStr(&utf8,pVar->z,pVar->n,enc,SQLITE_STATIC) - || SQLITE_NOMEM==sqlite3VdbeChangeEncoding(&utf8, SQLITE_UTF8) - ){ - sqlite3StrAccumReset(&out); - sqlite3VdbeMemRelease(&utf8); - return 0; + sqlite3VdbeMemSetStr(&utf8, pVar->z, pVar->n, enc, SQLITE_STATIC); + if( SQLITE_NOMEM==sqlite3VdbeChangeEncoding(&utf8, SQLITE_UTF8) ){ + out.accError = STRACCUM_NOMEM; + out.nAlloc = 0; } pVar = &utf8; } @@ -189,6 +187,7 @@ char *sqlite3VdbeExpandSql( } } } + if( out.accError ) sqlite3StrAccumReset(&out); return sqlite3StrAccumFinish(&out); } From 49dcd79e7d2d759df3fbe7446b100dbd90cd4bd6 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 23 Jul 2016 14:50:26 +0000 Subject: [PATCH 0587/1484] Fix recently added tests so that they work in all configurations. FossilOrigin-Name: d0bcaf0cd92ae5bbea7ad68537ba89437d5c39e8 --- manifest | 15 +++++++-------- manifest.uuid | 2 +- test/dbstatus.test | 1 + test/vacuummem.test | 7 ++++++- 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index feb1cf9a6e..412a1d98e5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\ssqlite3_expanded_sql()\sand\ssqlite3_trace_v2()\sinterfaces. -D 2016-07-23T05:22:02.142 +C Fix\srecently\sadded\stests\sso\sthat\sthey\swork\sin\sall\sconfigurations. +D 2016-07-23T14:50:26.969 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -621,7 +621,7 @@ F test/ctime.test 0b995accd44a52914bd4744d5c1b6e1a56c7897c F test/cursorhint.test 7bc346788390475e77a345da2b92270d04d35856 F test/cursorhint2.test 2b45341d32d1aae9991a00ef31ebca339b274255 F test/date.test 984ac1e3e5e031386866f034006148d3972b4a65 -F test/dbstatus.test 85833ba5bc95262749d080dcd40af87072ea8d5b +F test/dbstatus.test 2bb4d576f11c0f57f5633dad373ad1a57c2a7195 F test/dbstatus2.test e93ab03bfae6d62d4d935f20de928c19ca0ed0ab F test/default.test 0cb49b1c315a0d81c81d775e407f66906a2a604d F test/delete.test e1bcdf8926234e27aac24b346ad83d3329ec8b6f @@ -1324,7 +1324,7 @@ F test/vacuum.test ce91c39f7f91a4273bf620efad21086b5aa6ef1d F test/vacuum2.test aa048abee196c16c9ba308465494009057b79f9b F test/vacuum3.test 77ecdd54592b45a0bcb133339f99f1ae0ae94d0d F test/vacuum4.test d3f8ecff345f166911568f397d2432c16d2867d9 -F test/vacuummem.test 09c8b72a12405649ed84564367dad729bff88760 +F test/vacuummem.test ae20cc80a4960d3507d27cf0f2f4555988ceb6df F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102 F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661 F test/view.test 765802c7a66d37fabd5ac8e2f2dbe572b43eb9ab @@ -1507,8 +1507,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P f50a3fd6606c14b82c9b938bfca284d54b6c650f 0400f642d542e62bb428e0bf263964c65691368e -R 4a3af12ad9efd4d7dc81ee4ca45f95f6 -T +closed 0400f642d542e62bb428e0bf263964c65691368e +P 99a6c51887d9d78409944c5a028d5a3ac2e066a7 +R dcbad5b66668d4f45eebea8d8e4c4fc1 U drh -Z 2820f9890a85b78d1796850ebe9bb3ba +Z b2cb07cac2703599b169fabec6f383c3 diff --git a/manifest.uuid b/manifest.uuid index 288e6dc899..77b620836b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -99a6c51887d9d78409944c5a028d5a3ac2e066a7 \ No newline at end of file +d0bcaf0cd92ae5bbea7ad68537ba89437d5c39e8 \ No newline at end of file diff --git a/test/dbstatus.test b/test/dbstatus.test index 00c5deabd5..fb4cbe04ba 100644 --- a/test/dbstatus.test +++ b/test/dbstatus.test @@ -390,6 +390,7 @@ ifcapable shared_cache { sqlite3 db file:test.db?cache=shared do_execsql_test 4.0 { + PRAGMA auto_vacuum=NONE; CREATE TABLE t1(a, b, c); INSERT INTO t1 VALUES(1, 2, 3); } diff --git a/test/vacuummem.test b/test/vacuummem.test index 967e28cec7..b0f5cf2038 100644 --- a/test/vacuummem.test +++ b/test/vacuummem.test @@ -17,6 +17,12 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix vacuummem +if {[permutation]=="memsubsys1"} { + finish_test + return +} + + proc memory_used {} { set stat [sqlite3_status SQLITE_STATUS_MEMORY_USED 1] lindex $stat 1 @@ -51,4 +57,3 @@ do_test 1.5 { memory_used } {#/2300000/} finish_test - From ba00e30a3a55e3800ce808373d9604983a4d1df5 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 23 Jul 2016 20:24:06 +0000 Subject: [PATCH 0588/1484] Allow vector IN(SELECT ...) expressions to use an index if either all the indexed columns are declared NOT NULL or if there is no difference between the expression evaluating to 0 and NULL (as in a WHERE clause). FossilOrigin-Name: e2fd6f49b1b145bec09c581cc982b89429643ae9 --- manifest | 17 ++-- manifest.uuid | 2 +- src/expr.c | 217 +++++++++++++++++++++++++------------------- src/sqliteInt.h | 2 +- src/wherecode.c | 2 +- test/rowvalue3.test | 52 +++++++++++ 6 files changed, 188 insertions(+), 104 deletions(-) create mode 100644 test/rowvalue3.test diff --git a/manifest b/manifest index 65a4d1d413..52753bfb10 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\slatest\strunk\schanges\swith\sthis\sbranch. -D 2016-07-22T17:58:05.771 +C Allow\svector\sIN(SELECT\s...)\sexpressions\sto\suse\san\sindex\sif\seither\sall\sthe\sindexed\scolumns\sare\sdeclared\sNOT\sNULL\sor\sif\sthere\sis\sno\sdifference\sbetween\sthe\sexpression\sevaluating\sto\s0\sand\sNULL\s(as\sin\sa\sWHERE\sclause). +D 2016-07-23T20:24:06.382 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -337,7 +337,7 @@ F src/ctime.c 61949e83c4c36e37195a8398ebc752780b534d95 F src/date.c 1cc9fb516ec9932c6fd4d2a0d2f8bc4480145c39 F src/dbstat.c 4f6f7f52b49beb9636ffbd517cfe44a402ba4ad0 F src/delete.c 4aba4214a377ce8ddde2d2e609777bcc8235200f -F src/expr.c 939362d26f5e99a4802ae94ae6e47d4def72b8f3 +F src/expr.c 8ff9d70cc2077020327d1fa551558bb03e267da4 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c bc4145347595b7770f9a598cff1c848302cf5413 F src/func.c 61a4114cf7004f10c542cfabbab9f2bcb9033045 @@ -388,7 +388,7 @@ F src/shell.c a8a9e392a6a2777fabf5feb536931cb190f235e5 F src/sqlite.h.in b9ba728c1083b7a8ab5f6a628b25cd2a00325fbf F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 2a170163d121095c6ab1ef05ed0413722f391d01 -F src/sqliteInt.h dd2dd1d880ffd33137d20dc6da21f169836b8f5a +F src/sqliteInt.h c4877fb0519c13558d18d08775bc8e79476cb56c F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c 5b18f9526900f61189ab0b83f1ef41d9f871a2ab F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 @@ -465,7 +465,7 @@ F src/wal.h 6dd221ed384afdc204bc61e25c23ef7fd5a511f2 F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354 F src/where.c 898a45969bae1298cbaaaf05e6aeacfb45971293 F src/whereInt.h 1ad3be2a43cb821418e1100476a3a14cd57635c4 -F src/wherecode.c 877ceb19cf00a5fd5aeea4e3ff633dcdf173f164 +F src/wherecode.c eb0f5e8700afb110cb96fb873c0e9a015a9f63ff F src/whereexpr.c d88ee6ce356cb9fd986d0e81249a2cd66a513093 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -1019,6 +1019,7 @@ F test/rowhash.test 0bc1d31415e4575d10cacf31e1a66b5cc0f8be81 F test/rowid.test 5b7509f384f4f6fae1af3c8c104c8ca299fea18d F test/rowvalue.test 979738b3d49f1d93e3fee56a71d4446217917abc F test/rowvalue2.test 8d5dfe75b8f4d1868a2f91f0356f20d36cba64ff +F test/rowvalue3.test 72a9fe5ad30df2d422876466e180c148ab88dc42 F test/rtree.test 0c8d9dd458d6824e59683c19ab2ffa9ef946f798 F test/run-wordcount.sh 891e89c4c2d16e629cd45951d4ed899ad12afc09 F test/savepoint.test c671fdbd34cd3bfe1518a777526ada595180cf8d @@ -1508,7 +1509,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 34e35c71b25b0aa2d8931040feb260a78cc48c49 87e25fc472604b3978811be53991104c665a95e7 -R 2fbaab60c614a16797a19958a11968ca +P 60fed5cdd4a44aefa1b4d505adeb7936f2f0b952 +R 1dc4c60c16780168f167fe34d6f77ee9 U dan -Z c65487e55e425163e0e854585a16b213 +Z f82474a4f9b8fbec7649c9e9d834d395 diff --git a/manifest.uuid b/manifest.uuid index 9342dcf6ce..1150e4a104 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -60fed5cdd4a44aefa1b4d505adeb7936f2f0b952 \ No newline at end of file +e2fd6f49b1b145bec09c581cc982b89429643ae9 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index c43c6c04de..5792073228 100644 --- a/src/expr.c +++ b/src/expr.c @@ -323,6 +323,12 @@ int sqlite3ExprVectorSize(Expr *pExpr){ return pExpr->x.pList->nExpr; } +/* +** If the expression passed as the first argument is a TK_VECTOR, return +** a pointer to the i'th field of the vector. Or, if the first argument +** points to a sub-select, return a pointer to the i'th returned column +** value. Otherwise, return a copy of the first argument. +*/ static Expr *exprVectorField(Expr *pVector, int i){ if( (pVector->flags & EP_Vector)==0 ){ assert( i==0 ); @@ -1710,6 +1716,13 @@ int sqlite3IsRowid(const char *z){ ** a pointer to the SELECT statement. If pX is not a SELECT statement, ** or if the SELECT statement needs to be manifested into a transient ** table, then return NULL. +** +** If parameter bNullSensitive is 0, then this operation will be +** used in a context in which there is no difference between a result +** of 0 and one of NULL. For example: +** +** ... WHERE (?,?) IN (SELECT ...) +** */ #ifndef SQLITE_OMIT_SUBQUERY static Select *isCandidateForInOpt(Expr *pX, int bNullSensitive){ @@ -1870,7 +1883,13 @@ static int sqlite3InRhsIsConstant(Expr *pIn){ ** NULL values. */ #ifndef SQLITE_OMIT_SUBQUERY -int sqlite3FindInIndex(Parse *pParse, Expr *pX, u32 inFlags, int *prRhsHasNull){ +int sqlite3FindInIndex( + Parse *pParse, + Expr *pX, + u32 inFlags, + int *prRhsHasNull, + int *aiMap +){ Select *p; /* SELECT to the right of IN operator */ int eType = 0; /* Type of RHS table. IN_INDEX_* */ int iTab = pParse->nTab++; /* Cursor of the RHS table */ @@ -1887,9 +1906,9 @@ int sqlite3FindInIndex(Parse *pParse, Expr *pX, u32 inFlags, int *prRhsHasNull){ if( pParse->nErr==0 && (p = isCandidateForInOpt(pX, prRhsHasNull!=0))!=0 ){ sqlite3 *db = pParse->db; /* Database connection */ Table *pTab; /* Table
    . */ + i16 iDb; /* Database idx for pTab */ ExprList *pEList = p->pEList; int nExpr = pEList->nExpr; - i16 iDb; /* Database idx for pTab */ assert( p->pEList!=0 ); /* Because of isCandidateForInOpt(p) */ assert( p->pEList->a[0].pExpr!=0 ); /* Because of isCandidateForInOpt(p) */ @@ -1961,6 +1980,7 @@ int sqlite3FindInIndex(Parse *pParse, Expr *pX, u32 inFlags, int *prRhsHasNull){ break; } if( j==nExpr ) break; + if( aiMap ) aiMap[i] = j; } if( i==nExpr ){ @@ -2023,6 +2043,12 @@ int sqlite3FindInIndex(Parse *pParse, Expr *pX, u32 inFlags, int *prRhsHasNull){ }else{ pX->iTable = iTab; } + + if( aiMap && eType!=IN_INDEX_INDEX_ASC && eType!=IN_INDEX_INDEX_DESC ){ + int i, n; + n = sqlite3ExprVectorSize(pX->pLeft); + for(i=0; ipLeft); - - Expr *pLeft = pExpr->pLeft; - Vdbe *v = pParse->pVdbe; - - /* Code the LHS, the from " IN (...)". Leave the results in - ** an array of nVal registers starting at r1. */ - sqlite3ExprCachePush(pParse); - if( pLeft->flags & EP_xIsSelect ){ - r1 = sqlite3CodeSubselect(pParse, pLeft, 0, 0); - }else{ - r1 = pParse->nMem + 1; - pParse->nMem += nVal; - sqlite3ExprCodeExprList(pParse, pLeft->x.pList, r1, 0, 0); - } - - /* Generate an epheremal index containing the contents of the SELECT - ** to the right of the " IN (SELECT ...)" expression. The cursor - ** number for the epheremal table is left in pExpr->iTable. */ - assert( pExpr->flags & EP_xIsSelect ); - sqlite3CodeSubselect(pParse, pExpr, 0, 0); - - sqlite3VdbeAddOp2(v, OP_Integer, 0, regResult); - - /* Iterate through the ephemeral table just populated */ - addrNext = 1 + sqlite3VdbeAddOp2(v, OP_Rewind, pExpr->iTable, destIfFalse); - for(i=0; iiTable, i, r2); - sqlite3VdbeAddOp4(v, OP_Eq, r1+i, i==0?r3:r4, r2, (void*)pColl,P4_COLLSEQ); - sqlite3VdbeChangeP5(v, SQLITE_STOREP2); - VdbeCoverage(v); - if( i!=0 ){ - sqlite3VdbeAddOp3(v, OP_And, r3, r4, r4); - } - } - sqlite3VdbeAddOp2(v, OP_If, r4, sqlite3VdbeCurrentAddr(v)+6); - sqlite3VdbeAddOp2(v, OP_IfNot, r4, sqlite3VdbeCurrentAddr(v)+2); - sqlite3VdbeAddOp2(v, OP_Null, 0, regResult); - sqlite3VdbeAddOp2(v, OP_Next, pExpr->iTable, addrNext); - sqlite3VdbeAddOp3(v, OP_If, regResult, destIfNull, 1); - sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfFalse); - - sqlite3ReleaseTempReg(pParse, r2); - sqlite3ReleaseTempReg(pParse, r3); - sqlite3ReleaseTempReg(pParse, r4); - sqlite3ReleaseTempReg(pParse, regResult); - sqlite3ExprCachePop(pParse); -} -#endif - #ifndef SQLITE_OMIT_SUBQUERY /* ** Generate code for an IN expression. @@ -2403,36 +2360,64 @@ static void sqlite3ExprCodeIN( int destIfNull /* Jump here if the results are unknown due to NULLs */ ){ int rRhsHasNull = 0; /* Register that is true if RHS contains NULL values */ - char affinity; /* Comparison affinity to use */ int eType; /* Type of the RHS */ int r1; /* Temporary use register */ Vdbe *v; /* Statement under construction */ + int *aiMap = 0; /* Map from vector field to index column */ + char *zAff = 0; /* Affinity string for comparisons */ + int nVector; /* Size of vectors for this IN(...) op */ + int regSelect = 0; + Expr *pLeft = pExpr->pLeft; + int i; - if( pExpr->pLeft->flags & EP_Vector ){ - return exprCodeVectorIN(pParse, pExpr, destIfFalse, destIfNull); - } + nVector = sqlite3ExprVectorSize(pExpr->pLeft); + aiMap = (int*)sqlite3DbMallocZero( + pParse->db, nVector*(sizeof(int) + sizeof(char)) + 1 + ); + if( !aiMap ) return; + zAff = (char*)&aiMap[nVector]; - /* Compute the RHS. After this step, the table with cursor - ** pExpr->iTable will contains the values that make up the RHS. - */ + /* Attempt to compute the RHS. After this step, if anything other than + ** IN_INDEX_NOOP is returned, the table opened ith cursor pExpr->iTable + ** contains the values that make up the RHS. If IN_INDEX_NOOP is returned, + ** the RHS has not yet been coded. */ v = pParse->pVdbe; assert( v!=0 ); /* OOM detected prior to this routine */ VdbeNoopComment((v, "begin IN expr")); eType = sqlite3FindInIndex(pParse, pExpr, IN_INDEX_MEMBERSHIP | IN_INDEX_NOOP_OK, - destIfFalse==destIfNull ? 0 : &rRhsHasNull); + destIfFalse==destIfNull ? 0 : &rRhsHasNull, aiMap); - /* Figure out the affinity to use to create a key from the results - ** of the expression. affinityStr stores a static string suitable for - ** P4 of OP_MakeRecord. - */ - affinity = comparisonAffinity(pExpr); + assert( pParse->nErr || nVector==1 || eType==IN_INDEX_EPH + || eType==IN_INDEX_INDEX_ASC || eType==IN_INDEX_INDEX_DESC + ); - /* Code the LHS, the from " IN (...)". + /* Code the LHS, the from " IN (...)". If the LHS is a + ** vector, then it is stored in an array of nVector registers starting + ** at r1. */ + r1 = sqlite3GetTempRange(pParse, nVector); sqlite3ExprCachePush(pParse); - r1 = sqlite3GetTempReg(pParse); - sqlite3ExprCode(pParse, pExpr->pLeft, r1); + if( nVector>1 && (pLeft->flags & EP_xIsSelect) ){ + regSelect = sqlite3CodeSubselect(pParse, pLeft, 0, 0); + } + for(i=0; iflags & EP_xIsSelect ){ + zAff[iCol] = sqlite3CompareAffinity( + pExpr->x.pSelect->pEList->a[iCol].pExpr, zAff[iCol] + ); + } + } /* If sqlite3FindInIndex() did not find or create an index that is ** suitable for evaluating the IN operator, then evaluate using a @@ -2460,12 +2445,12 @@ static void sqlite3ExprCodeIN( (void*)pColl, P4_COLLSEQ); VdbeCoverageIf(v, iinExpr-1); VdbeCoverageIf(v, ii==pList->nExpr-1); - sqlite3VdbeChangeP5(v, affinity); + sqlite3VdbeChangeP5(v, zAff[0]); }else{ assert( destIfNull==destIfFalse ); sqlite3VdbeAddOp4(v, OP_Ne, r1, destIfFalse, r2, (void*)pColl, P4_COLLSEQ); VdbeCoverage(v); - sqlite3VdbeChangeP5(v, affinity | SQLITE_JUMPIFNULL); + sqlite3VdbeChangeP5(v, zAff[0] | SQLITE_JUMPIFNULL); } sqlite3ReleaseTempReg(pParse, regToFree); } @@ -2480,7 +2465,7 @@ static void sqlite3ExprCodeIN( /* If the LHS is NULL, then the result is either false or NULL depending ** on whether the RHS is empty or not, respectively. */ - if( sqlite3ExprCanBeNull(pExpr->pLeft) ){ + if( nVector==1 && sqlite3ExprCanBeNull(pExpr->pLeft) ){ if( destIfNull==destIfFalse ){ /* Shortcut for the common case where the false and NULL outcomes are ** the same. */ @@ -2499,10 +2484,50 @@ static void sqlite3ExprCodeIN( */ sqlite3VdbeAddOp3(v, OP_SeekRowid, pExpr->iTable, destIfFalse, r1); VdbeCoverage(v); + }else if( nVector>1 && eType==IN_INDEX_EPH ){ + int regNull = sqlite3GetTempReg(pParse); + int r2 = sqlite3GetTempReg(pParse); + int r3 = sqlite3GetTempReg(pParse); + int r4 = sqlite3GetTempReg(pParse); + int addrNext; + int addrIf; + + if( destIfFalse!=destIfNull ){ + sqlite3VdbeAddOp2(v, OP_Integer, 0, regNull); + } + addrNext = sqlite3VdbeAddOp2(v, OP_Rewind, pExpr->iTable, destIfFalse); + for(i=0; iiTable, i, r2); + sqlite3VdbeAddOp4(v, OP_Eq, r1+i, i?r3:r4, r2, (void*)pColl,P4_COLLSEQ); + sqlite3VdbeChangeP5(v, SQLITE_STOREP2); + if( i!=0 ){ + sqlite3VdbeAddOp3(v, OP_And, r3, r4, r4); + } + } + addrIf = sqlite3VdbeAddOp1(v, OP_If, r4); + if( destIfNull!=destIfFalse ){ + sqlite3VdbeAddOp2(v, OP_IfNot, r4, sqlite3VdbeCurrentAddr(v)+2); + sqlite3VdbeAddOp2(v, OP_Integer, 1, regNull); + } + sqlite3VdbeAddOp2(v, OP_Next, pExpr->iTable, addrNext+1); + if( destIfNull!=destIfFalse ){ + sqlite3VdbeAddOp2(v, OP_If, regNull, destIfNull); + } + sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfFalse); + sqlite3VdbeChangeP2(v, addrIf, sqlite3VdbeCurrentAddr(v)); + sqlite3ReleaseTempReg(pParse, regNull); + sqlite3ReleaseTempReg(pParse, r2); + sqlite3ReleaseTempReg(pParse, r3); + sqlite3ReleaseTempReg(pParse, r4); }else{ /* In this case, the RHS is an index b-tree. */ - sqlite3VdbeAddOp4(v, OP_Affinity, r1, 1, 0, &affinity, 1); + sqlite3VdbeAddOp4(v, OP_Affinity, r1, nVector, 0, zAff, nVector); /* If the set membership test fails, then the result of the ** "x IN (...)" expression must be either 0 or NULL. If the set @@ -2519,7 +2544,9 @@ static void sqlite3ExprCodeIN( ** Also run this branch if NULL is equivalent to FALSE ** for this particular IN operator. */ - sqlite3VdbeAddOp4Int(v, OP_NotFound, pExpr->iTable, destIfFalse, r1, 1); + sqlite3VdbeAddOp4Int( + v, OP_NotFound, pExpr->iTable, destIfFalse, r1, nVector + ); VdbeCoverage(v); }else{ /* In this branch, the RHS of the IN might contain a NULL and @@ -2545,6 +2572,7 @@ static void sqlite3ExprCodeIN( } sqlite3ReleaseTempReg(pParse, r1); sqlite3ExprCachePop(pParse); + sqlite3DbFree(pParse->db, aiMap); VdbeComment((v, "end IN expr")); } #endif /* SQLITE_OMIT_SUBQUERY */ @@ -4010,7 +4038,7 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ assert( pExpr->op!=TK_GT || op==OP_Le ); assert( pExpr->op!=TK_GE || op==OP_Lt ); - switch( pExpr->op | (pExpr->pLeft ? (pExpr->pLeft->flags & EP_Vector) : 0)){ + switch( pExpr->op ){ case TK_AND: { testcase( jumpIfNull==0 ); sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull); @@ -4047,6 +4075,8 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ case TK_GE: case TK_NE: case TK_EQ: { + if( pExpr->pLeft->flags & EP_Vector ) goto default_expr; + testcase( jumpIfNull==0 ); r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); @@ -4093,6 +4123,7 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ } #endif default: { + default_expr: if( exprAlwaysFalse(pExpr) ){ sqlite3VdbeGoto(v, dest); }else if( exprAlwaysTrue(pExpr) ){ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 3caa65d8e3..b8a326cfbc 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -4134,7 +4134,7 @@ const char *sqlite3JournalModename(int); #define IN_INDEX_NOOP_OK 0x0001 /* OK to return IN_INDEX_NOOP */ #define IN_INDEX_MEMBERSHIP 0x0002 /* IN operator used for membership test */ #define IN_INDEX_LOOP 0x0004 /* IN operator used as a loop */ -int sqlite3FindInIndex(Parse *, Expr *, u32, int*); +int sqlite3FindInIndex(Parse *, Expr *, u32, int*, int*); int sqlite3JournalOpen(sqlite3_vfs *, const char *, sqlite3_file *, int, int); int sqlite3JournalSize(sqlite3_vfs *); diff --git a/src/wherecode.c b/src/wherecode.c index e660b35387..0f6d320241 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -379,7 +379,7 @@ static int codeEqualityTerm( } assert( pX->op==TK_IN ); iReg = iTarget; - eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0); + eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, 0); if( eType==IN_INDEX_INDEX_DESC ){ testcase( bRev ); bRev = !bRev; diff --git a/test/rowvalue3.test b/test/rowvalue3.test new file mode 100644 index 0000000000..63f2c8939a --- /dev/null +++ b/test/rowvalue3.test @@ -0,0 +1,52 @@ +# 2016 June 17 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements regression tests for SQLite library. The +# focus of this file is testing "(...) IN (SELECT ...)" expressions +# where the SELECT statement returns more than one column. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set ::testprefix rowvalue3 + + +do_execsql_test 1.0 { + CREATE TABLE t1(a, b, c); + CREATE INDEX i1 ON t1(a, b); + INSERT INTO t1 VALUES(1, 2, 3); + INSERT INTO t1 VALUES(4, 5, 6); + INSERT INTO t1 VALUES(7, 8, 9); +} + +foreach {tn sql res} { + 1 "SELECT 1 WHERE (4, 5) IN (SELECT a, b FROM t1)" 1 + 2 "SELECT 1 WHERE (5, 5) IN (SELECT a, b FROM t1)" {} + 3 "SELECT 1 WHERE (5, 4) IN (SELECT a, b FROM t1)" {} + 4 "SELECT 1 WHERE (5, 4) IN (SELECT b, a FROM t1)" 1 + 5 "SELECT 1 WHERE (SELECT a, b FROM t1 WHERE c=6) IN (SELECT a, b FROM t1)" 1 + 6 "SELECT (5, 4) IN (SELECT a, b FROM t1)" 0 + 7 "SELECT 1 WHERE (5, 4) IN (SELECT +b, +a FROM t1)" 1 + 8 "SELECT (5, 4) IN (SELECT +b, +a FROM t1)" 1 + 9 "SELECT (1, 2) IN (SELECT rowid, b FROM t1)" 1 + 10 "SELECT 1 WHERE (1, 2) IN (SELECT rowid, b FROM t1)" 1 + 11 "SELECT 1 WHERE (1, NULL) IN (SELECT rowid, b FROM t1)" {} +} { + do_execsql_test 1.$tn $sql $res +} + +#explain_i { SELECT (4, NULL) IN (SELECT a, b FROM t1) } +#do_execsql_test 2 { SELECT (4, NULL) IN (SELECT a, b FROM t1) } {} + + + + +finish_test + From 4b363a5130eeb67734da40007eeb46c48c268e9e Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 23 Jul 2016 20:27:41 +0000 Subject: [PATCH 0589/1484] Use sqlite3_trace_v2() instead of sqlite3_trace() in the shell. FossilOrigin-Name: c8e0539b970585cbb3619461a53abb0c3b308a17 --- manifest | 13 ++++++------- manifest.uuid | 2 +- src/shell.c | 13 ++++++++++--- 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 58ad849efb..882bad7357 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sjson_quote()\sfunction\sto\sthe\sJSON1\sextension. -D 2016-07-23T19:34:53.707 +C Use\ssqlite3_trace_v2()\sinstead\sof\ssqlite3_trace()\sin\sthe\sshell. +D 2016-07-23T20:27:41.266 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -384,7 +384,7 @@ F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c cca3aa77b95706df5d635a2141a4d1de60ae6598 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c f3c6e9065fb34f6a23af27ec7f1f717ffbfc2ee4 -F src/shell.c a8a9e392a6a2777fabf5feb536931cb190f235e5 +F src/shell.c ad6375a1cbfb13786bfc7ae28e00d822aedefd35 F src/sqlite.h.in 3dc7317ded4bf66facd845705f45f21d03517940 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 46f300b6e300e0fa916d7d58c44b53415b8471a9 @@ -1507,8 +1507,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 8817dedb75430e6c78ff527f7ded4abb35776cef 2c3714aebf5e40e3728877a235b3c1f93defa33e -R d8b644436fd0d857689e119dadae618e -T +closed 2c3714aebf5e40e3728877a235b3c1f93defa33e +P 269892abf6e59c417729669cc764d1f237e093fd +R 38c94a12899d68429eb06d66defc6359 U drh -Z e34798b2dc952c68e869c2ddf5f79301 +Z 4041e092b34c5d7817e039ca6e44ec6c diff --git a/manifest.uuid b/manifest.uuid index 49e513c3f7..771fe8bf2c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -269892abf6e59c417729669cc764d1f237e093fd \ No newline at end of file +c8e0539b970585cbb3619461a53abb0c3b308a17 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 874782c5f1..4a546ccfef 100644 --- a/src/shell.c +++ b/src/shell.c @@ -2543,13 +2543,20 @@ static FILE *output_file_open(const char *zFile){ /* ** A routine for handling output from sqlite3_trace(). */ -static void sql_trace_callback(void *pArg, const char *z){ +static int sql_trace_callback( + unsigned mType, + void *pArg, + void *pP, + void *pX +){ FILE *f = (FILE*)pArg; if( f ){ + const char *z = (const char*)pX; int i = (int)strlen(z); while( i>0 && z[i-1]==';' ){ i--; } utf8_printf(f, "%.*s;\n", i, z); } + return 0; } /* @@ -4655,9 +4662,9 @@ static int do_meta_command(char *zLine, ShellState *p){ p->traceOut = output_file_open(azArg[1]); #if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT) if( p->traceOut==0 ){ - sqlite3_trace(p->db, 0, 0); + sqlite3_trace_v2(p->db, 0, 0, 0); }else{ - sqlite3_trace(p->db, sql_trace_callback, p->traceOut); + sqlite3_trace_v2(p->db, SQLITE_TRACE_STMT, sql_trace_callback,p->traceOut); } #endif }else From 087ec072ef45e9aaca031a4535cc93b4dbd530f3 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 25 Jul 2016 00:05:56 +0000 Subject: [PATCH 0590/1484] Fix code so that the deprecated sqlite3_trace() and sqlite3_profile() interfaces are not called when SQLITE_OMIT_DEPRECATED is used. FossilOrigin-Name: 1c5baae3c545096a29a093f7d4387771f1db507c --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/loadext.c | 2 +- src/main.c | 2 ++ src/tclsqlite.c | 3 ++- 5 files changed, 14 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 882bad7357..da3ec9d304 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Use\ssqlite3_trace_v2()\sinstead\sof\ssqlite3_trace()\sin\sthe\sshell. -D 2016-07-23T20:27:41.266 +C Fix\scode\sso\sthat\sthe\sdeprecated\ssqlite3_trace()\sand\ssqlite3_profile()\s\ninterfaces\sare\snot\scalled\swhen\sSQLITE_OMIT_DEPRECATED\sis\sused. +D 2016-07-25T00:05:56.727 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -347,8 +347,8 @@ F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4 F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da F src/insert.c 8f4e9fcbd8e95e85f15647ba8b413b18d556ec2b F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e -F src/loadext.c 4237fd37ca589f1d90b3ea925dd9df20da8e0c84 -F src/main.c 2d3e62a971e7f169a74448e81af9ebde95b07381 +F src/loadext.c 5dd8b5a67d32a98bb75657c2a9e48b2cedbf13a4 +F src/main.c 16c1b2114eae8804caf3a8de8cb47bf2c6d83ad3 F src/malloc.c 1443d1ad95d67c21d77af7ae3f44678252f0efec F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b @@ -392,7 +392,7 @@ F src/sqliteInt.h 48cd97eb134665348393dfe277b4c14d1085bfc7 F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c 5b18f9526900f61189ab0b83f1ef41d9f871a2ab F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 -F src/tclsqlite.c 573e63c959b314d77486f3565fa79c60cda3df7e +F src/tclsqlite.c 5c213bf5fee084390f632df2328cf0821d483799 F src/test1.c 186e3b53c402b7a73bcb4ade2b77709675c39fe3 F src/test2.c 5586f43fcd9a1be0830793cf9d354082c261b25b F src/test3.c c75c8af0eadb335236c9e61b51044c58a8f7dd59 @@ -1507,7 +1507,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 269892abf6e59c417729669cc764d1f237e093fd -R 38c94a12899d68429eb06d66defc6359 +P c8e0539b970585cbb3619461a53abb0c3b308a17 +R d97169b5da173af1e8c3e0989fc5f73b U drh -Z 4041e092b34c5d7817e039ca6e44ec6c +Z 74b666fd406733750b5703b09cc23966 diff --git a/manifest.uuid b/manifest.uuid index 771fe8bf2c..5edb03d00b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c8e0539b970585cbb3619461a53abb0c3b308a17 \ No newline at end of file +1c5baae3c545096a29a093f7d4387771f1db507c \ No newline at end of file diff --git a/src/loadext.c b/src/loadext.c index 718dae5777..ce1f5317c6 100644 --- a/src/loadext.c +++ b/src/loadext.c @@ -91,7 +91,7 @@ # define sqlite3_enable_shared_cache 0 #endif -#ifdef SQLITE_OMIT_TRACE +#if defined(SQLITE_OMIT_TRACE) || defined(SQLITE_OMIT_DEPRECATED) # define sqlite3_profile 0 # define sqlite3_trace 0 #endif diff --git a/src/main.c b/src/main.c index 5cd1ea7185..f31f865818 100644 --- a/src/main.c +++ b/src/main.c @@ -1845,6 +1845,7 @@ int sqlite3_trace_v2( return SQLITE_OK; } +#ifndef SQLITE_OMIT_DEPRECATED /* ** Register a profile function. The pArg from the previously registered ** profile function is returned. @@ -1873,6 +1874,7 @@ void *sqlite3_profile( sqlite3_mutex_leave(db->mutex); return pOld; } +#endif /* SQLITE_OMIT_DEPRECATED */ #endif /* SQLITE_OMIT_TRACE */ /* diff --git a/src/tclsqlite.c b/src/tclsqlite.c index 43dfedb727..2de88f41f4 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -2912,7 +2912,8 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ }else{ pDb->zTrace = 0; } -#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT) +#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT) \ + && !defined(SQLITE_OMIT_DEPRECATED) if( pDb->zTrace ){ pDb->interp = interp; sqlite3_trace(pDb->db, DbTraceHandler, pDb); From bd441f77009be56eb5c815a3accd578f03c609b7 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 25 Jul 2016 02:31:48 +0000 Subject: [PATCH 0591/1484] Change SQLITE_TRACE_STMT to return unexpanded SQL text in the X argument. Add documentation on how and when to use sqlite3_expanded_sql(P) to compute the expanded text for legacy sqlite3_trace() compatibility. FossilOrigin-Name: 163e15229d837a5471007cffb8d41faafd081737 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/sqlite.h.in | 7 +++++-- src/vdbe.c | 9 ++++++--- tool/srcck1.c | 2 +- 5 files changed, 21 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index da3ec9d304..819e488286 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\scode\sso\sthat\sthe\sdeprecated\ssqlite3_trace()\sand\ssqlite3_profile()\s\ninterfaces\sare\snot\scalled\swhen\sSQLITE_OMIT_DEPRECATED\sis\sused. -D 2016-07-25T00:05:56.727 +C Change\sSQLITE_TRACE_STMT\sto\sreturn\sunexpanded\sSQL\stext\sin\sthe\sX\sargument.\nAdd\sdocumentation\son\show\sand\swhen\sto\suse\ssqlite3_expanded_sql(P)\sto\scompute\nthe\sexpanded\stext\sfor\slegacy\ssqlite3_trace()\scompatibility. +D 2016-07-25T02:31:48.358 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -385,7 +385,7 @@ F src/resolve.c cca3aa77b95706df5d635a2141a4d1de60ae6598 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c f3c6e9065fb34f6a23af27ec7f1f717ffbfc2ee4 F src/shell.c ad6375a1cbfb13786bfc7ae28e00d822aedefd35 -F src/sqlite.h.in 3dc7317ded4bf66facd845705f45f21d03517940 +F src/sqlite.h.in c6e68a4a47610631822a4f8f83a44c9f75339331 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 46f300b6e300e0fa916d7d58c44b53415b8471a9 F src/sqliteInt.h 48cd97eb134665348393dfe277b4c14d1085bfc7 @@ -449,7 +449,7 @@ F src/update.c 4f05ea8cddfa367d045e03589756c02199e8f9bd F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 810ec3f22e2d1b62e66c30fe3621ebdedd23584d F src/vacuum.c 544ec90a66a4b0460b7c1baeadbc21b45e6ca0b6 -F src/vdbe.c 7b5570f77e32766949fd8f9478e4a9bb06e6ab24 +F src/vdbe.c 7718d72427fd3abae6603a7a225e3eec12137d4a F src/vdbe.h 67bc551f7faf04c33493892e4b378aada823ed10 F src/vdbeInt.h c59381049af5c7751a83456c39b80d1a6fde1f9d F src/vdbeapi.c c3f6715a99995c11748ecad91d25e93fd9fc390b @@ -1475,7 +1475,7 @@ F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 7ce07da76b5e745783e703a834417d725b7d45fd F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c F tool/sqldiff.c 4478f0d30230de6adde90bdb0bfe60f68c5ab782 -F tool/srcck1.c 4c39bdfa9a92edd20233ee720df84dbeb2417602 +F tool/srcck1.c 371de5363b70154012955544f86fdee8f6e5326f F tool/stack_usage.tcl f8e71b92cdb099a147dad572375595eae55eca43 F tool/symbols-mingw.sh 4dbcea7e74768305384c9fd2ed2b41bbf9f0414d F tool/symbols.sh c5a617b8c61a0926747a56c65f5671ef8ac0e148 @@ -1507,7 +1507,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P c8e0539b970585cbb3619461a53abb0c3b308a17 -R d97169b5da173af1e8c3e0989fc5f73b +P 1c5baae3c545096a29a093f7d4387771f1db507c +R 287171615483ae1144a14be35a6974e0 U drh -Z 74b666fd406733750b5703b09cc23966 +Z fb84b0dd7373ed024b44202f95be044f diff --git a/manifest.uuid b/manifest.uuid index 5edb03d00b..6cdf0fb62f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1c5baae3c545096a29a093f7d4387771f1db507c \ No newline at end of file +163e15229d837a5471007cffb8d41faafd081737 \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index ed68cf0a13..e8f5d24845 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -2813,8 +2813,11 @@ SQLITE_DEPRECATED void *sqlite3_profile(sqlite3*, ** execution of the prepared statement, such as at the start of each ** trigger subprogram. ^The P argument is a pointer to the ** [prepared statement]. ^The X argument is a pointer to a string which -** is the expanded SQL text of the prepared statement or a comment that -** indicates the invocation of a trigger. +** is the unexpanded SQL text of the prepared statement or an SQL comment +** that indicates the invocation of a trigger. ^The callback can compute +** the same text that would have been returned by the legacy [sqlite3_trace()] +** interface by using the X argument when X begins with "--" and invoking +** [sqlite3_expanded_sql(P)] otherwise. ** ** [[SQLITE_TRACE_PROFILE]]
    SQLITE_TRACE_PROFILE
    **
    ^An SQLITE_TRACE_PROFILE callback provides approximately the same diff --git a/src/vdbe.c b/src/vdbe.c index cdbd7301b8..d198d1ff8c 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -6785,21 +6785,24 @@ case OP_Init: { /* jump */ char *z; #ifndef SQLITE_OMIT_TRACE + /* If the P4 argument is not NULL, then it must be an SQL comment string. + ** The "--" string is broken up to prevent false-positives with srcck1.c */ + assert( pOp->p4.z==0 || strncmp(pOp->p4.z, "-" "- ", 3)==0 ); if( (db->mTrace & (SQLITE_TRACE_STMT|SQLITE_TRACE_LEGACY))!=0 && !p->doingRerun && (zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0 ){ - z = sqlite3VdbeExpandSql(p, zTrace); #ifndef SQLITE_OMIT_DEPRECATED if( db->mTrace & SQLITE_TRACE_LEGACY ){ void (*x)(void*,const char*) = (void(*)(void*,const char*))db->xTrace; + z = sqlite3VdbeExpandSql(p, zTrace); x(db->pTraceArg, z); + sqlite3_free(z); }else #endif { - (void)db->xTrace(SQLITE_TRACE_STMT,db->pTraceArg,p,z); + (void)db->xTrace(SQLITE_TRACE_STMT, db->pTraceArg, p, zTrace); } - sqlite3_free(z); } #ifdef SQLITE_USE_FCNTL_TRACE zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql); diff --git a/tool/srcck1.c b/tool/srcck1.c index e95765185f..20084ac47f 100644 --- a/tool/srcck1.c +++ b/tool/srcck1.c @@ -58,7 +58,7 @@ static char *readFile(const char *zFilename){ return z; } -/* Change the C code in the argument to see if it might have +/* Check the C code in the argument to see if it might have ** side effects. The only accurate way to know this is to do a full ** parse of the C code, which this routine does not do. This routine ** uses a simple heuristic of looking for: From 5fe63bfb93ebccf1f00b8a8e1c9d2ed82f0bd86f Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 25 Jul 2016 02:42:22 +0000 Subject: [PATCH 0592/1484] Evidence marks and code reformatting for SQLITE_TRACE_STMT operation. FossilOrigin-Name: e1e022383114525241454f63ea8b9768fb7ec657 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 17 ++++++++++++----- 3 files changed, 19 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 819e488286..9f9642d316 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sSQLITE_TRACE_STMT\sto\sreturn\sunexpanded\sSQL\stext\sin\sthe\sX\sargument.\nAdd\sdocumentation\son\show\sand\swhen\sto\suse\ssqlite3_expanded_sql(P)\sto\scompute\nthe\sexpanded\stext\sfor\slegacy\ssqlite3_trace()\scompatibility. -D 2016-07-25T02:31:48.358 +C Evidence\smarks\sand\scode\sreformatting\sfor\sSQLITE_TRACE_STMT\soperation. +D 2016-07-25T02:42:22.338 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -449,7 +449,7 @@ F src/update.c 4f05ea8cddfa367d045e03589756c02199e8f9bd F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 810ec3f22e2d1b62e66c30fe3621ebdedd23584d F src/vacuum.c 544ec90a66a4b0460b7c1baeadbc21b45e6ca0b6 -F src/vdbe.c 7718d72427fd3abae6603a7a225e3eec12137d4a +F src/vdbe.c ea260b61e73b11a71e70b28a8e25866e2899e5da F src/vdbe.h 67bc551f7faf04c33493892e4b378aada823ed10 F src/vdbeInt.h c59381049af5c7751a83456c39b80d1a6fde1f9d F src/vdbeapi.c c3f6715a99995c11748ecad91d25e93fd9fc390b @@ -1507,7 +1507,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 1c5baae3c545096a29a093f7d4387771f1db507c -R 287171615483ae1144a14be35a6974e0 +P 163e15229d837a5471007cffb8d41faafd081737 +R 54f5b446e83fdc6cfb9e4fb83bcacd6b U drh -Z fb84b0dd7373ed024b44202f95be044f +Z cd50dce290ecc3f8f1fad92c2e3b32fc diff --git a/manifest.uuid b/manifest.uuid index 6cdf0fb62f..be4af97fc7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -163e15229d837a5471007cffb8d41faafd081737 \ No newline at end of file +e1e022383114525241454f63ea8b9768fb7ec657 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index d198d1ff8c..5d21ad064c 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -6782,12 +6782,19 @@ case OP_MaxPgcnt: { /* out2 */ */ case OP_Init: { /* jump */ char *zTrace; - char *z; + + /* If the P4 argument is not NULL, then it must be an SQL comment string. + ** The "--" string is broken up to prevent false-positives with srcck1.c. + ** + ** This assert() provides evidence for: + ** EVIDENCE-OF: R-50676-09860 The callback can compute the same text that + ** would have been returned by the legacy sqlite3_trace() interface by + ** using the X argument when X begins with "--" and invoking + ** sqlite3_expanded_sql(P) otherwise. + */ + assert( pOp->p4.z==0 || strncmp(pOp->p4.z, "-" "- ", 3)==0 ); #ifndef SQLITE_OMIT_TRACE - /* If the P4 argument is not NULL, then it must be an SQL comment string. - ** The "--" string is broken up to prevent false-positives with srcck1.c */ - assert( pOp->p4.z==0 || strncmp(pOp->p4.z, "-" "- ", 3)==0 ); if( (db->mTrace & (SQLITE_TRACE_STMT|SQLITE_TRACE_LEGACY))!=0 && !p->doingRerun && (zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0 @@ -6795,7 +6802,7 @@ case OP_Init: { /* jump */ #ifndef SQLITE_OMIT_DEPRECATED if( db->mTrace & SQLITE_TRACE_LEGACY ){ void (*x)(void*,const char*) = (void(*)(void*,const char*))db->xTrace; - z = sqlite3VdbeExpandSql(p, zTrace); + char *z = sqlite3VdbeExpandSql(p, zTrace); x(db->pTraceArg, z); sqlite3_free(z); }else From c530b9c65bab03a581a9f898151256ecf2680649 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 25 Jul 2016 11:27:22 +0000 Subject: [PATCH 0593/1484] Add --enable-memsys3 and --enable-memsys5 options to the configure script. FossilOrigin-Name: 67e1dc9842dc8a6ae5edef21bdb2ef6d3f4a17b7 --- configure | 73 +++++++++++++++++++++++++++++++++++++++++---------- configure.ac | 24 +++++++++++++++++ manifest | 16 +++++------ manifest.uuid | 2 +- src/shell.c | 2 ++ 5 files changed, 94 insertions(+), 23 deletions(-) diff --git a/configure b/configure index f4d4c48077..ee62dcc9bd 100755 --- a/configure +++ b/configure @@ -772,6 +772,7 @@ LIBOBJS BUILD_CFLAGS USE_GCOV OPT_FEATURE_FLAGS +SQLITE_MEMSYS5 USE_AMALGAMATION TARGET_DEBUG TARGET_HAVE_EDITLINE @@ -903,6 +904,8 @@ with_readline_inc enable_debug enable_amalgamation enable_load_extension +enable_memsys3 +enable_memsys5 enable_fts3 enable_fts4 enable_fts5 @@ -1552,6 +1555,8 @@ Optional Features: separately --disable-load-extension Disable loading of external extensions + --enable-memsys3 Enable MEMSYS3 + --enable-memsys5 Enable MEMSYS5 --enable-fts3 Enable the FTS3 extension --enable-fts4 Enable the FTS4 extension --enable-fts5 Enable the FTS5 extension @@ -3925,13 +3930,13 @@ if ${lt_cv_nm_interface+:} false; then : else lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext - (eval echo "\"\$as_me:3928: $ac_compile\"" >&5) + (eval echo "\"\$as_me:3933: $ac_compile\"" >&5) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&5 - (eval echo "\"\$as_me:3931: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval echo "\"\$as_me:3936: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&5 - (eval echo "\"\$as_me:3934: output\"" >&5) + (eval echo "\"\$as_me:3939: output\"" >&5) cat conftest.out >&5 if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" @@ -5137,7 +5142,7 @@ ia64-*-hpux*) ;; *-*-irix6*) # Find out which ABI we are using. - echo '#line 5140 "configure"' > conftest.$ac_ext + echo '#line 5145 "configure"' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? @@ -6662,11 +6667,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:6665: $lt_compile\"" >&5) + (eval echo "\"\$as_me:6670: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:6669: \$? = $ac_status" >&5 + echo "$as_me:6674: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -7001,11 +7006,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7004: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7009: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:7008: \$? = $ac_status" >&5 + echo "$as_me:7013: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -7106,11 +7111,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7109: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7114: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:7113: \$? = $ac_status" >&5 + echo "$as_me:7118: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -7161,11 +7166,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7164: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7169: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:7168: \$? = $ac_status" >&5 + echo "$as_me:7173: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -9541,7 +9546,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 9544 "configure" +#line 9549 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -9637,7 +9642,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 9640 "configure" +#line 9645 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -11339,6 +11344,46 @@ else OPT_FEATURE_FLAGS="-DSQLITE_OMIT_LOAD_EXTENSION=1" fi +########## +# Do we want to support memsys3 and/or memsys5 +# +# Check whether --enable-memsys3 was given. +if test "${enable_memsys3+set}" = set; then : + enableval=$enable_memsys3; +else + enable_memsys3=yes +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support MEMSYS3" >&5 +$as_echo_n "checking whether to support MEMSYS3... " >&6; } +if test "$enable_memsys3" = "yes"; then + SQLITE_ENABLE_MEMSYS3=1 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + +# Check whether --enable-memsys5 was given. +if test "${enable_memsys5+set}" = set; then : + enableval=$enable_memsys5; +else + enable_memsys3=yes +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support MEMSYS5" >&5 +$as_echo_n "checking whether to support MEMSYS5... " >&6; } +if test "$enable_memsys5" = "yes"; then + SQLITE_ENABLE_MEMSYS5=1 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + ######### # See whether we should enable Full Text Search extensions # Check whether --enable-fts3 was given. diff --git a/configure.ac b/configure.ac index e5727ea7f2..7ab6bf9024 100644 --- a/configure.ac +++ b/configure.ac @@ -588,6 +588,30 @@ else OPT_FEATURE_FLAGS="-DSQLITE_OMIT_LOAD_EXTENSION=1" fi +########## +# Do we want to support memsys3 and/or memsys5 +# +AC_ARG_ENABLE(memsys3, +AC_HELP_STRING([--enable-memsys3],[Enable MEMSYS3]),,enable_memsys3=yes) +AC_MSG_CHECKING([whether to support MEMSYS3]) +if test "$enable_memsys3" = "yes"; then + SQLITE_ENABLE_MEMSYS3=1 + AC_MSG_RESULT([yes]) +else + AC_MSG_RESULT([no]) +fi +AC_SUBST(SQLITE_MEMSYS5) +AC_ARG_ENABLE(memsys5, +AC_HELP_STRING([--enable-memsys5],[Enable MEMSYS5]),,enable_memsys3=yes) +AC_MSG_CHECKING([whether to support MEMSYS5]) +if test "$enable_memsys5" = "yes"; then + SQLITE_ENABLE_MEMSYS5=1 + AC_MSG_RESULT([yes]) +else + AC_MSG_RESULT([no]) +fi +AC_SUBST(SQLITE_MEMSYS5) + ######### # See whether we should enable Full Text Search extensions AC_ARG_ENABLE(fts3, AC_HELP_STRING([--enable-fts3], diff --git a/manifest b/manifest index 9f9642d316..6391e1baa3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Evidence\smarks\sand\scode\sreformatting\sfor\sSQLITE_TRACE_STMT\soperation. -D 2016-07-25T02:42:22.338 +C Add\s--enable-memsys3\sand\s--enable-memsys5\soptions\sto\sthe\sconfigure\sscript. +D 2016-07-25T11:27:22.245 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -30,8 +30,8 @@ F autoconf/tea/win/rules.vc c511f222b80064096b705dbeb97060ee1d6b6d63 F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977 F config.h.in 6376abec766e9a0785178b1823b5a587e9f1ccbc F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55 -F configure 25cf7eb52a88846e4c1978016a9db22763c54f41 x -F configure.ac 480e1a17d5316b1751c8edcb15b8e6b8ab0a6cc3 +F configure 7f1096018e7277653bdccbc3522763950716c04e x +F configure.ac 312a1d5cee98d125c4d5af63ae244d1d4d4e61ae F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad F doc/lemon.html e2118945e5f07ed146b45c9cd2b2dd6eabb8ebf2 F doc/pager-invariants.txt 27fed9a70ddad2088750c4a2b493b63853da2710 @@ -384,7 +384,7 @@ F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c cca3aa77b95706df5d635a2141a4d1de60ae6598 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c f3c6e9065fb34f6a23af27ec7f1f717ffbfc2ee4 -F src/shell.c ad6375a1cbfb13786bfc7ae28e00d822aedefd35 +F src/shell.c 9351fc6de11e1d908648c0a92d85627138e3dee5 F src/sqlite.h.in c6e68a4a47610631822a4f8f83a44c9f75339331 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 46f300b6e300e0fa916d7d58c44b53415b8471a9 @@ -1507,7 +1507,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 163e15229d837a5471007cffb8d41faafd081737 -R 54f5b446e83fdc6cfb9e4fb83bcacd6b +P e1e022383114525241454f63ea8b9768fb7ec657 +R f029b1d7e77fec56f765d45dc22f3d18 U drh -Z cd50dce290ecc3f8f1fad92c2e3b32fc +Z 774059649b6fa0105cfafff42cfa581a diff --git a/manifest.uuid b/manifest.uuid index be4af97fc7..3b4218203e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e1e022383114525241454f63ea8b9768fb7ec657 \ No newline at end of file +67e1dc9842dc8a6ae5edef21bdb2ef6d3f4a17b7 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 4a546ccfef..e8d215b95a 100644 --- a/src/shell.c +++ b/src/shell.c @@ -5324,6 +5324,8 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ szHeap = integerValue(zSize); if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000; sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64); +#else + (void)cmdline_option_value(argc, argv, ++i); #endif }else if( strcmp(z,"-scratch")==0 ){ int n, sz; From 26197d1b62c26a5f13a720e478238af4e3b8ee1b Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 25 Jul 2016 11:32:09 +0000 Subject: [PATCH 0594/1484] Fix the --enable-memsysN options in configure so that they actually work. FossilOrigin-Name: 679552550e085497b98478bbe28056d99fe4aab4 --- configure | 12 ++++++------ configure.ac | 10 ++++++---- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 20 insertions(+), 18 deletions(-) diff --git a/configure b/configure index ee62dcc9bd..de3dfdd49d 100755 --- a/configure +++ b/configure @@ -11349,14 +11349,14 @@ fi # # Check whether --enable-memsys3 was given. if test "${enable_memsys3+set}" = set; then : - enableval=$enable_memsys3; + enableval=$enable_memsys3; enable_memsys3=yes else - enable_memsys3=yes + enable_memsys3=no fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support MEMSYS3" >&5 $as_echo_n "checking whether to support MEMSYS3... " >&6; } -if test "$enable_memsys3" = "yes"; then +if test "${enable_memsys3}" = "yes"; then SQLITE_ENABLE_MEMSYS3=1 { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } @@ -11367,14 +11367,14 @@ fi # Check whether --enable-memsys5 was given. if test "${enable_memsys5+set}" = set; then : - enableval=$enable_memsys5; + enableval=$enable_memsys5; enable_memsys5=yes else - enable_memsys3=yes + enable_memsys5=no fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support MEMSYS5" >&5 $as_echo_n "checking whether to support MEMSYS5... " >&6; } -if test "$enable_memsys5" = "yes"; then +if test "${enable_memsys5}" = "yes"; then SQLITE_ENABLE_MEMSYS5=1 { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } diff --git a/configure.ac b/configure.ac index 7ab6bf9024..da8d7db09f 100644 --- a/configure.ac +++ b/configure.ac @@ -592,9 +592,10 @@ fi # Do we want to support memsys3 and/or memsys5 # AC_ARG_ENABLE(memsys3, -AC_HELP_STRING([--enable-memsys3],[Enable MEMSYS3]),,enable_memsys3=yes) + AC_HELP_STRING([--enable-memsys3],[Enable MEMSYS3]), + [enable_memsys3=yes],[enable_memsys3=no]) AC_MSG_CHECKING([whether to support MEMSYS3]) -if test "$enable_memsys3" = "yes"; then +if test "${enable_memsys3}" = "yes"; then SQLITE_ENABLE_MEMSYS3=1 AC_MSG_RESULT([yes]) else @@ -602,9 +603,10 @@ else fi AC_SUBST(SQLITE_MEMSYS5) AC_ARG_ENABLE(memsys5, -AC_HELP_STRING([--enable-memsys5],[Enable MEMSYS5]),,enable_memsys3=yes) + AC_HELP_STRING([--enable-memsys5],[Enable MEMSYS5]), + [enable_memsys5=yes],[enable_memsys5=no]) AC_MSG_CHECKING([whether to support MEMSYS5]) -if test "$enable_memsys5" = "yes"; then +if test "${enable_memsys5}" = "yes"; then SQLITE_ENABLE_MEMSYS5=1 AC_MSG_RESULT([yes]) else diff --git a/manifest b/manifest index 6391e1baa3..2f9c340bb9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\s--enable-memsys3\sand\s--enable-memsys5\soptions\sto\sthe\sconfigure\sscript. -D 2016-07-25T11:27:22.245 +C Fix\sthe\s--enable-memsysN\soptions\sin\sconfigure\sso\sthat\sthey\sactually\swork. +D 2016-07-25T11:32:09.826 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -30,8 +30,8 @@ F autoconf/tea/win/rules.vc c511f222b80064096b705dbeb97060ee1d6b6d63 F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977 F config.h.in 6376abec766e9a0785178b1823b5a587e9f1ccbc F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55 -F configure 7f1096018e7277653bdccbc3522763950716c04e x -F configure.ac 312a1d5cee98d125c4d5af63ae244d1d4d4e61ae +F configure 71e6c9bb642ef53357cb8dbc858fc84998f3bc6d x +F configure.ac b67f6fc9f3e22edabd4be3911289400423e5ffa9 F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad F doc/lemon.html e2118945e5f07ed146b45c9cd2b2dd6eabb8ebf2 F doc/pager-invariants.txt 27fed9a70ddad2088750c4a2b493b63853da2710 @@ -1507,7 +1507,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e1e022383114525241454f63ea8b9768fb7ec657 -R f029b1d7e77fec56f765d45dc22f3d18 +P 67e1dc9842dc8a6ae5edef21bdb2ef6d3f4a17b7 +R bb2ee4817e32d59609fbb5b8d40bbd12 U drh -Z 774059649b6fa0105cfafff42cfa581a +Z dcc29f2a3f4c1199964573b0937d7a95 diff --git a/manifest.uuid b/manifest.uuid index 3b4218203e..faaef17b8e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -67e1dc9842dc8a6ae5edef21bdb2ef6d3f4a17b7 \ No newline at end of file +679552550e085497b98478bbe28056d99fe4aab4 \ No newline at end of file From 6fe4c184fb593a593d690f34cb0e1591ac5715a2 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 25 Jul 2016 11:39:24 +0000 Subject: [PATCH 0595/1484] Another attempt at getting --enable-memsysN working. FossilOrigin-Name: 5f40e6ad599eea59a5adc3a11d6f7998872736b4 --- configure | 35 ++++++++++++++++------------------- configure.ac | 6 ++---- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 26 insertions(+), 31 deletions(-) diff --git a/configure b/configure index de3dfdd49d..85d56a1ede 100755 --- a/configure +++ b/configure @@ -772,7 +772,6 @@ LIBOBJS BUILD_CFLAGS USE_GCOV OPT_FEATURE_FLAGS -SQLITE_MEMSYS5 USE_AMALGAMATION TARGET_DEBUG TARGET_HAVE_EDITLINE @@ -3930,13 +3929,13 @@ if ${lt_cv_nm_interface+:} false; then : else lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext - (eval echo "\"\$as_me:3933: $ac_compile\"" >&5) + (eval echo "\"\$as_me:3932: $ac_compile\"" >&5) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&5 - (eval echo "\"\$as_me:3936: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval echo "\"\$as_me:3935: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&5 - (eval echo "\"\$as_me:3939: output\"" >&5) + (eval echo "\"\$as_me:3938: output\"" >&5) cat conftest.out >&5 if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" @@ -5142,7 +5141,7 @@ ia64-*-hpux*) ;; *-*-irix6*) # Find out which ABI we are using. - echo '#line 5145 "configure"' > conftest.$ac_ext + echo '#line 5144 "configure"' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? @@ -6667,11 +6666,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:6670: $lt_compile\"" >&5) + (eval echo "\"\$as_me:6669: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:6674: \$? = $ac_status" >&5 + echo "$as_me:6673: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -7006,11 +7005,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7009: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7008: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:7013: \$? = $ac_status" >&5 + echo "$as_me:7012: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -7111,11 +7110,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7114: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7113: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:7118: \$? = $ac_status" >&5 + echo "$as_me:7117: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -7166,11 +7165,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7169: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7168: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:7173: \$? = $ac_status" >&5 + echo "$as_me:7172: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -9546,7 +9545,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 9549 "configure" +#line 9548 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -9642,7 +9641,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 9645 "configure" +#line 9644 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -11357,14 +11356,13 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support MEMSYS3" >&5 $as_echo_n "checking whether to support MEMSYS3... " >&6; } if test "${enable_memsys3}" = "yes"; then - SQLITE_ENABLE_MEMSYS3=1 + OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_MEMSYS3" { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi - # Check whether --enable-memsys5 was given. if test "${enable_memsys5+set}" = set; then : enableval=$enable_memsys5; enable_memsys5=yes @@ -11375,7 +11373,7 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support MEMSYS5" >&5 $as_echo_n "checking whether to support MEMSYS5... " >&6; } if test "${enable_memsys5}" = "yes"; then - SQLITE_ENABLE_MEMSYS5=1 + OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_MEMSYS5" { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else @@ -11383,7 +11381,6 @@ else $as_echo "no" >&6; } fi - ######### # See whether we should enable Full Text Search extensions # Check whether --enable-fts3 was given. diff --git a/configure.ac b/configure.ac index da8d7db09f..07dd3cb88a 100644 --- a/configure.ac +++ b/configure.ac @@ -596,23 +596,21 @@ AC_ARG_ENABLE(memsys3, [enable_memsys3=yes],[enable_memsys3=no]) AC_MSG_CHECKING([whether to support MEMSYS3]) if test "${enable_memsys3}" = "yes"; then - SQLITE_ENABLE_MEMSYS3=1 + OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_MEMSYS3" AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) fi -AC_SUBST(SQLITE_MEMSYS5) AC_ARG_ENABLE(memsys5, AC_HELP_STRING([--enable-memsys5],[Enable MEMSYS5]), [enable_memsys5=yes],[enable_memsys5=no]) AC_MSG_CHECKING([whether to support MEMSYS5]) if test "${enable_memsys5}" = "yes"; then - SQLITE_ENABLE_MEMSYS5=1 + OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_MEMSYS5" AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) fi -AC_SUBST(SQLITE_MEMSYS5) ######### # See whether we should enable Full Text Search extensions diff --git a/manifest b/manifest index 2f9c340bb9..8310f7e4f2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\s--enable-memsysN\soptions\sin\sconfigure\sso\sthat\sthey\sactually\swork. -D 2016-07-25T11:32:09.826 +C Another\sattempt\sat\sgetting\s--enable-memsysN\sworking. +D 2016-07-25T11:39:24.067 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -30,8 +30,8 @@ F autoconf/tea/win/rules.vc c511f222b80064096b705dbeb97060ee1d6b6d63 F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977 F config.h.in 6376abec766e9a0785178b1823b5a587e9f1ccbc F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55 -F configure 71e6c9bb642ef53357cb8dbc858fc84998f3bc6d x -F configure.ac b67f6fc9f3e22edabd4be3911289400423e5ffa9 +F configure f62e6614b26418ce81392b2c28b2a6cf268f1d5d x +F configure.ac 83c4e53031a3582d0b9200dcb3700189a24f1b1c F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad F doc/lemon.html e2118945e5f07ed146b45c9cd2b2dd6eabb8ebf2 F doc/pager-invariants.txt 27fed9a70ddad2088750c4a2b493b63853da2710 @@ -1507,7 +1507,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 67e1dc9842dc8a6ae5edef21bdb2ef6d3f4a17b7 -R bb2ee4817e32d59609fbb5b8d40bbd12 +P 679552550e085497b98478bbe28056d99fe4aab4 +R 5c303973b5bb214411149d73b1469581 U drh -Z dcc29f2a3f4c1199964573b0937d7a95 +Z 6145af1bb509746e3a2a7850c862eafe diff --git a/manifest.uuid b/manifest.uuid index faaef17b8e..8d55876e78 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -679552550e085497b98478bbe28056d99fe4aab4 \ No newline at end of file +5f40e6ad599eea59a5adc3a11d6f7998872736b4 \ No newline at end of file From 5d513ba08ca3b60dceb0b1223acf42ef0d443c1e Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 25 Jul 2016 11:57:21 +0000 Subject: [PATCH 0596/1484] If both MEMSYS3 and MEMSYS5 are enabled, than automatically disable MEMSYS3. FossilOrigin-Name: ccc22e14dc5d910d632807f49484be54dc2fde83 --- configure | 38 +++++++++++++++++++------------------- configure.ac | 20 ++++++++++---------- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/sqliteInt.h | 10 +++++++--- test/releasetest.tcl | 1 - 6 files changed, 46 insertions(+), 43 deletions(-) diff --git a/configure b/configure index 85d56a1ede..fbcf7309b1 100755 --- a/configure +++ b/configure @@ -903,8 +903,8 @@ with_readline_inc enable_debug enable_amalgamation enable_load_extension -enable_memsys3 enable_memsys5 +enable_memsys3 enable_fts3 enable_fts4 enable_fts5 @@ -1554,8 +1554,8 @@ Optional Features: separately --disable-load-extension Disable loading of external extensions - --enable-memsys3 Enable MEMSYS3 --enable-memsys5 Enable MEMSYS5 + --enable-memsys3 Enable MEMSYS3 --enable-fts3 Enable the FTS3 extension --enable-fts4 Enable the FTS4 extension --enable-fts5 Enable the FTS5 extension @@ -11346,23 +11346,6 @@ fi ########## # Do we want to support memsys3 and/or memsys5 # -# Check whether --enable-memsys3 was given. -if test "${enable_memsys3+set}" = set; then : - enableval=$enable_memsys3; enable_memsys3=yes -else - enable_memsys3=no -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support MEMSYS3" >&5 -$as_echo_n "checking whether to support MEMSYS3... " >&6; } -if test "${enable_memsys3}" = "yes"; then - OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_MEMSYS3" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi # Check whether --enable-memsys5 was given. if test "${enable_memsys5+set}" = set; then : enableval=$enable_memsys5; enable_memsys5=yes @@ -11380,6 +11363,23 @@ else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi +# Check whether --enable-memsys3 was given. +if test "${enable_memsys3+set}" = set; then : + enableval=$enable_memsys3; enable_memsys3=yes +else + enable_memsys3=no +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support MEMSYS3" >&5 +$as_echo_n "checking whether to support MEMSYS3... " >&6; } +if test "${enable_memsys3}" = "yes" -a "${enable_memsys5}" = "no"; then + OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_MEMSYS3" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi ######### # See whether we should enable Full Text Search extensions diff --git a/configure.ac b/configure.ac index 07dd3cb88a..c9e3af9220 100644 --- a/configure.ac +++ b/configure.ac @@ -591,16 +591,6 @@ fi ########## # Do we want to support memsys3 and/or memsys5 # -AC_ARG_ENABLE(memsys3, - AC_HELP_STRING([--enable-memsys3],[Enable MEMSYS3]), - [enable_memsys3=yes],[enable_memsys3=no]) -AC_MSG_CHECKING([whether to support MEMSYS3]) -if test "${enable_memsys3}" = "yes"; then - OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_MEMSYS3" - AC_MSG_RESULT([yes]) -else - AC_MSG_RESULT([no]) -fi AC_ARG_ENABLE(memsys5, AC_HELP_STRING([--enable-memsys5],[Enable MEMSYS5]), [enable_memsys5=yes],[enable_memsys5=no]) @@ -611,6 +601,16 @@ if test "${enable_memsys5}" = "yes"; then else AC_MSG_RESULT([no]) fi +AC_ARG_ENABLE(memsys3, + AC_HELP_STRING([--enable-memsys3],[Enable MEMSYS3]), + [enable_memsys3=yes],[enable_memsys3=no]) +AC_MSG_CHECKING([whether to support MEMSYS3]) +if test "${enable_memsys3}" = "yes" -a "${enable_memsys5}" = "no"; then + OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_MEMSYS3" + AC_MSG_RESULT([yes]) +else + AC_MSG_RESULT([no]) +fi ######### # See whether we should enable Full Text Search extensions diff --git a/manifest b/manifest index 8310f7e4f2..6a45ebc22e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Another\sattempt\sat\sgetting\s--enable-memsysN\sworking. -D 2016-07-25T11:39:24.067 +C If\sboth\sMEMSYS3\sand\sMEMSYS5\sare\senabled,\sthan\sautomatically\sdisable\sMEMSYS3. +D 2016-07-25T11:57:21.222 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -30,8 +30,8 @@ F autoconf/tea/win/rules.vc c511f222b80064096b705dbeb97060ee1d6b6d63 F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977 F config.h.in 6376abec766e9a0785178b1823b5a587e9f1ccbc F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55 -F configure f62e6614b26418ce81392b2c28b2a6cf268f1d5d x -F configure.ac 83c4e53031a3582d0b9200dcb3700189a24f1b1c +F configure 35ce04a15ca046262bf9baaa2ced9337708cc653 x +F configure.ac b5d3df43161374f8dffd2e5f4b88fbb51685b975 F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad F doc/lemon.html e2118945e5f07ed146b45c9cd2b2dd6eabb8ebf2 F doc/pager-invariants.txt 27fed9a70ddad2088750c4a2b493b63853da2710 @@ -388,7 +388,7 @@ F src/shell.c 9351fc6de11e1d908648c0a92d85627138e3dee5 F src/sqlite.h.in c6e68a4a47610631822a4f8f83a44c9f75339331 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 46f300b6e300e0fa916d7d58c44b53415b8471a9 -F src/sqliteInt.h 48cd97eb134665348393dfe277b4c14d1085bfc7 +F src/sqliteInt.h 49081ceab08eda9943d555aee57392c5b35d1c60 F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c 5b18f9526900f61189ab0b83f1ef41d9f871a2ab F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 @@ -1009,7 +1009,7 @@ F test/rdonly.test 64e2696c322e3538df0b1ed624e21f9a23ed9ff8 F test/regexp1.test 497ea812f264d12b6198d6e50a76be4a1973a9d8 F test/regexp2.test aa7ffcc21350007a78361b82bcf3b74d12227144 F test/reindex.test 44edd3966b474468b823d481eafef0c305022254 -F test/releasetest.tcl 7d80014d0245b3f9d02d393d420bf03ca155aec0 +F test/releasetest.tcl 3a66c7b8fbe55bcd97c907217c3d812d1d3c6b93 F test/resolver01.test f4022acafda7f4d40eca94dbf16bc5fc4ac30ceb F test/rollback.test 458fe73eb3ffdfdf9f6ba3e9b7350a6220414dea F test/rollback2.test 8435d6ff0f13f51d2a4181c232e706005fa90fc5 @@ -1507,7 +1507,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 679552550e085497b98478bbe28056d99fe4aab4 -R 5c303973b5bb214411149d73b1469581 +P 5f40e6ad599eea59a5adc3a11d6f7998872736b4 +R b01daae186a7f9a051c9362d4aae0591 U drh -Z 6145af1bb509746e3a2a7850c862eafe +Z d2602db348bfa53fd2c4a084ddf1dc40 diff --git a/manifest.uuid b/manifest.uuid index 8d55876e78..9bc4c35374 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5f40e6ad599eea59a5adc3a11d6f7998872736b4 \ No newline at end of file +ccc22e14dc5d910d632807f49484be54dc2fde83 \ No newline at end of file diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 0be4947513..879e6703ca 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3440,11 +3440,15 @@ int sqlite3HeapNearlyFull(void); # define sqlite3StackFree(D,P) sqlite3DbFree(D,P) #endif -#ifdef SQLITE_ENABLE_MEMSYS3 -const sqlite3_mem_methods *sqlite3MemGetMemsys3(void); -#endif +/* Do not allow both MEMSYS5 and MEMSYS3 to be defined together. If they +** are, disable MEMSYS3 +*/ #ifdef SQLITE_ENABLE_MEMSYS5 const sqlite3_mem_methods *sqlite3MemGetMemsys5(void); +#undef SQLITE_ENABLE_MEMSYS3 +#endif +#ifdef SQLITE_ENABLE_MEMSYS3 +const sqlite3_mem_methods *sqlite3MemGetMemsys3(void); #endif diff --git a/test/releasetest.tcl b/test/releasetest.tcl index 2961fc385d..e13a3d7340 100644 --- a/test/releasetest.tcl +++ b/test/releasetest.tcl @@ -120,7 +120,6 @@ array set ::Configs [strip_comments { -DSQLITE_ENABLE_FTS3=1 -DSQLITE_ENABLE_RTREE=1 -DSQLITE_ENABLE_MEMSYS5=1 - -DSQLITE_ENABLE_MEMSYS3=1 -DSQLITE_ENABLE_COLUMN_METADATA=1 -DSQLITE_ENABLE_STAT4 -DSQLITE_ENABLE_HIDDEN_COLUMNS From 26fe413be6d02028d56ce8e4970ab3655af2132c Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 25 Jul 2016 12:01:18 +0000 Subject: [PATCH 0597/1484] Update the vacuummem.test script so that it works on mac as well as on linux. FossilOrigin-Name: ea7fb98b96f13f7dc5ed83ec5e8ad8857e20e06e --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/vacuummem.test | 7 ++++--- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 6a45ebc22e..9cd5c96943 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C If\sboth\sMEMSYS3\sand\sMEMSYS5\sare\senabled,\sthan\sautomatically\sdisable\sMEMSYS3. -D 2016-07-25T11:57:21.222 +C Update\sthe\svacuummem.test\sscript\sso\sthat\sit\sworks\son\smac\sas\swell\sas\son\slinux. +D 2016-07-25T12:01:18.862 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -1324,7 +1324,7 @@ F test/vacuum.test ce91c39f7f91a4273bf620efad21086b5aa6ef1d F test/vacuum2.test aa048abee196c16c9ba308465494009057b79f9b F test/vacuum3.test 77ecdd54592b45a0bcb133339f99f1ae0ae94d0d F test/vacuum4.test d3f8ecff345f166911568f397d2432c16d2867d9 -F test/vacuummem.test ae20cc80a4960d3507d27cf0f2f4555988ceb6df +F test/vacuummem.test e53a3fdca4612a99c515e1afe7934728a2383764 F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102 F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661 F test/view.test 765802c7a66d37fabd5ac8e2f2dbe572b43eb9ab @@ -1507,7 +1507,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 5f40e6ad599eea59a5adc3a11d6f7998872736b4 -R b01daae186a7f9a051c9362d4aae0591 +P ccc22e14dc5d910d632807f49484be54dc2fde83 +R f8760ea1979a3d1e72e54c3ea906ea99 U drh -Z d2602db348bfa53fd2c4a084ddf1dc40 +Z 5b9cf50a9e82d7593d62c569e8fac940 diff --git a/manifest.uuid b/manifest.uuid index 9bc4c35374..9f906f5e5e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ccc22e14dc5d910d632807f49484be54dc2fde83 \ No newline at end of file +ea7fb98b96f13f7dc5ed83ec5e8ad8857e20e06e \ No newline at end of file diff --git a/test/vacuummem.test b/test/vacuummem.test index b0f5cf2038..b214c83b3d 100644 --- a/test/vacuummem.test +++ b/test/vacuummem.test @@ -41,18 +41,19 @@ do_execsql_test 1.0 { CREATE INDEX t1b ON t1(b); CREATE INDEX t1c ON t1(c); } +set ans "#/[memory_used]/" -do_test 1.1 { memory_used } {#/2300000/} +do_test 1.1 { memory_used } $ans do_execsql_test 1.2 VACUUM -do_test 1.3 { memory_used } {#/2300000/} +do_test 1.3 { memory_used } $ans do_execsql_test 1.4 { SELECT count(*) FROM t1 WHERE +a IS NOT NULL } {100000} -do_test 1.5 { memory_used } {#/2300000/} +do_test 1.5 { memory_used } $ans From 2aed97959263530f211c80bb70fe3c55cca09787 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 25 Jul 2016 12:10:25 +0000 Subject: [PATCH 0598/1484] Disable the DBSTATUS_CACHE_USED_SHARED tests on mac when memsys3/5 is disabled due to differences in the allocation sizes for the Darwin memory allocator. FossilOrigin-Name: d6f6c87c9c0acf609a9d5bea818bb7a5437109a1 --- manifest | 12 ++++----- manifest.uuid | 2 +- test/dbstatus.test | 62 ++++++++++++++++++++++++---------------------- 3 files changed, 40 insertions(+), 36 deletions(-) diff --git a/manifest b/manifest index 9cd5c96943..7e15c062ff 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\sthe\svacuummem.test\sscript\sso\sthat\sit\sworks\son\smac\sas\swell\sas\son\slinux. -D 2016-07-25T12:01:18.862 +C Disable\sthe\sDBSTATUS_CACHE_USED_SHARED\stests\son\smac\swhen\smemsys3/5\sis\sdisabled\ndue\sto\sdifferences\sin\sthe\sallocation\ssizes\sfor\sthe\sDarwin\smemory\sallocator. +D 2016-07-25T12:10:25.504 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -621,7 +621,7 @@ F test/ctime.test 0b995accd44a52914bd4744d5c1b6e1a56c7897c F test/cursorhint.test 7bc346788390475e77a345da2b92270d04d35856 F test/cursorhint2.test 2b45341d32d1aae9991a00ef31ebca339b274255 F test/date.test 984ac1e3e5e031386866f034006148d3972b4a65 -F test/dbstatus.test 2bb4d576f11c0f57f5633dad373ad1a57c2a7195 +F test/dbstatus.test 58b31ba1dee1a6524189666c5882ab145d1f229b F test/dbstatus2.test e93ab03bfae6d62d4d935f20de928c19ca0ed0ab F test/default.test 0cb49b1c315a0d81c81d775e407f66906a2a604d F test/delete.test e1bcdf8926234e27aac24b346ad83d3329ec8b6f @@ -1507,7 +1507,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ccc22e14dc5d910d632807f49484be54dc2fde83 -R f8760ea1979a3d1e72e54c3ea906ea99 +P ea7fb98b96f13f7dc5ed83ec5e8ad8857e20e06e +R 3485ec1f1845ad365519b5b860f50dc5 U drh -Z 5b9cf50a9e82d7593d62c569e8fac940 +Z 3712e6b13d05abd58f12d65f644b4035 diff --git a/manifest.uuid b/manifest.uuid index 9f906f5e5e..1d8d5dc41a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ea7fb98b96f13f7dc5ed83ec5e8ad8857e20e06e \ No newline at end of file +d6f6c87c9c0acf609a9d5bea818bb7a5437109a1 \ No newline at end of file diff --git a/test/dbstatus.test b/test/dbstatus.test index fb4cbe04ba..a3518e9b6f 100644 --- a/test/dbstatus.test +++ b/test/dbstatus.test @@ -379,36 +379,40 @@ foreach ::lookaside_buffer_size {0 64 120} { # The following tests focus on DBSTATUS_CACHE_USED_SHARED # ifcapable shared_cache { - proc do_cacheused_test {tn db res} { - set cu [sqlite3_db_status $db SQLITE_DBSTATUS_CACHE_USED 0] - set pcu [sqlite3_db_status $db SQLITE_DBSTATUS_CACHE_USED_SHARED 0] - set cu [lindex $cu 1] - set pcu [lindex $pcu 1] - uplevel [list do_test $tn [list list $cu $pcu] "#/$res/"] + if {[permutation]=="memsys3" + || [permutation]=="memsys5" + || $::tcl_platform(os)!="Darwin"} { + proc do_cacheused_test {tn db res} { + set cu [sqlite3_db_status $db SQLITE_DBSTATUS_CACHE_USED 0] + set pcu [sqlite3_db_status $db SQLITE_DBSTATUS_CACHE_USED_SHARED 0] + set cu [lindex $cu 1] + set pcu [lindex $pcu 1] + uplevel [list do_test $tn [list list $cu $pcu] "#/$res/"] + } + reset_db + sqlite3 db file:test.db?cache=shared + + do_execsql_test 4.0 { + PRAGMA auto_vacuum=NONE; + CREATE TABLE t1(a, b, c); + INSERT INTO t1 VALUES(1, 2, 3); + } + do_cacheused_test 4.0.1 db { 4568 4568 } + do_execsql_test 4.1 { + CREATE TEMP TABLE tt(a, b, c); + INSERT INTO tt VALUES(1, 2, 3); + } + do_cacheused_test 4.1.1 db { 9000 9000 } + + sqlite3 db2 file:test.db?cache=shared + do_cacheused_test 4.2.1 db2 { 4568 2284 } + do_cacheused_test 4.2.2 db { 9000 6716 } + db close + do_cacheused_test 4.2.3 db2 { 4568 4568 } + sqlite3 db file:test.db?cache=shared + do_cacheused_test 4.2.4 db2 { 4568 2284 } + db2 close } - reset_db - sqlite3 db file:test.db?cache=shared - - do_execsql_test 4.0 { - PRAGMA auto_vacuum=NONE; - CREATE TABLE t1(a, b, c); - INSERT INTO t1 VALUES(1, 2, 3); - } - do_cacheused_test 4.0.1 db { 4568 4568 } - do_execsql_test 4.1 { - CREATE TEMP TABLE tt(a, b, c); - INSERT INTO tt VALUES(1, 2, 3); - } - do_cacheused_test 4.1.1 db { 9000 9000 } - - sqlite3 db2 file:test.db?cache=shared - do_cacheused_test 4.2.1 db2 { 4568 2284 } - do_cacheused_test 4.2.2 db { 9000 6716 } - db close - do_cacheused_test 4.2.3 db2 { 4568 4568 } - sqlite3 db file:test.db?cache=shared - do_cacheused_test 4.2.4 db2 { 4568 2284 } - db2 close } finish_test From 017256802b4ca58df779e7a7d32abc5373fa3175 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 25 Jul 2016 14:20:01 +0000 Subject: [PATCH 0599/1484] Changes to test scripts to get them all running on OpenBSD. FossilOrigin-Name: 9e7bedeee444cbf0b1a9165e88928c5d85088de1 --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/dbstatus.test | 2 +- test/shell1.test | 1 + 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 7e15c062ff..621866c6f1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Disable\sthe\sDBSTATUS_CACHE_USED_SHARED\stests\son\smac\swhen\smemsys3/5\sis\sdisabled\ndue\sto\sdifferences\sin\sthe\sallocation\ssizes\sfor\sthe\sDarwin\smemory\sallocator. -D 2016-07-25T12:10:25.504 +C Changes\sto\stest\sscripts\sto\sget\sthem\sall\srunning\son\sOpenBSD. +D 2016-07-25T14:20:01.353 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -621,7 +621,7 @@ F test/ctime.test 0b995accd44a52914bd4744d5c1b6e1a56c7897c F test/cursorhint.test 7bc346788390475e77a345da2b92270d04d35856 F test/cursorhint2.test 2b45341d32d1aae9991a00ef31ebca339b274255 F test/date.test 984ac1e3e5e031386866f034006148d3972b4a65 -F test/dbstatus.test 58b31ba1dee1a6524189666c5882ab145d1f229b +F test/dbstatus.test 73149851b3aff14fc6db478e58f9083a66422cf5 F test/dbstatus2.test e93ab03bfae6d62d4d935f20de928c19ca0ed0ab F test/default.test 0cb49b1c315a0d81c81d775e407f66906a2a604d F test/delete.test e1bcdf8926234e27aac24b346ad83d3329ec8b6f @@ -1064,7 +1064,7 @@ F test/sharedA.test 0cdf1a76dfa00e6beee66af5b534b1e8df2720f5 F test/sharedB.test 16cc7178e20965d75278f410943109b77b2e645e F test/shared_err.test 2f2aee20db294b9924e81f6ccbe60f19e21e8506 F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304 -F test/shell1.test c90b0415cea6eeefb86b4ab1651b06247922ca52 +F test/shell1.test 77896b65f1cde4ee79e38b2c0ed8578a8f4000e5 F test/shell2.test e242a9912f44f4c23c3d1d802a83e934e84c853b F test/shell3.test da513d522ef6f01cee8475dcf8332bff8982b3dd F test/shell4.test 69995ee1cc278eb149aa8746ce1f935f4eaf98b9 @@ -1507,7 +1507,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ea7fb98b96f13f7dc5ed83ec5e8ad8857e20e06e -R 3485ec1f1845ad365519b5b860f50dc5 +P d6f6c87c9c0acf609a9d5bea818bb7a5437109a1 +R f74cc55ec1e76de02d5d11db76d4d3f2 U drh -Z 3712e6b13d05abd58f12d65f644b4035 +Z 27b5d9cc228b8d41a7c82f29fd5cd771 diff --git a/manifest.uuid b/manifest.uuid index 1d8d5dc41a..83360d7bd0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d6f6c87c9c0acf609a9d5bea818bb7a5437109a1 \ No newline at end of file +9e7bedeee444cbf0b1a9165e88928c5d85088de1 \ No newline at end of file diff --git a/test/dbstatus.test b/test/dbstatus.test index a3518e9b6f..711d66ebb3 100644 --- a/test/dbstatus.test +++ b/test/dbstatus.test @@ -381,7 +381,7 @@ foreach ::lookaside_buffer_size {0 64 120} { ifcapable shared_cache { if {[permutation]=="memsys3" || [permutation]=="memsys5" - || $::tcl_platform(os)!="Darwin"} { + || $::tcl_platform(os)=="Linux"} { proc do_cacheused_test {tn db res} { set cu [sqlite3_db_status $db SQLITE_DBSTATUS_CACHE_USED 0] set pcu [sqlite3_db_status $db SQLITE_DBSTATUS_CACHE_USED_SHARED 0] diff --git a/test/shell1.test b/test/shell1.test index 498cd64a9f..03c2dee1d1 100644 --- a/test/shell1.test +++ b/test/shell1.test @@ -870,6 +870,7 @@ do_test shell1-5.0 { if {$i==0x0D || ($tcl_platform(platform)=="windows" && $i==0x1A)} { continue } + if {$i>=0xE0 && $tcl_platform(os)=="OpenBSD"} continue set hex [format %02X $i] set char [subst \\x$hex]; set oldChar $char set escapes [list] From a522473c65f6705a8d18023208dbebea41a9b79f Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 25 Jul 2016 14:40:43 +0000 Subject: [PATCH 0600/1484] Add a new %ifdef to parse.y so that the build works with SQLITE_OMIT_SUBQUERY. FossilOrigin-Name: 38a48cfb9a8212970c4a4f8458643c22ed067e8b --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/parse.y | 3 ++- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 621866c6f1..bd35ced110 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Changes\sto\stest\sscripts\sto\sget\sthem\sall\srunning\son\sOpenBSD. -D 2016-07-25T14:20:01.353 +C Add\sa\snew\s%ifdef\sto\sparse.y\sso\sthat\sthe\sbuild\sworks\swith\sSQLITE_OMIT_SUBQUERY. +D 2016-07-25T14:40:43.866 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -372,7 +372,7 @@ F src/os_win.c 520f23475f1de530c435d30b67b7b15fe90874b0 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c c368634b888b1c8740aea83b36bfd266f2443e60 F src/pager.h 031a87445e5e0afc85312d1c380e123ad6c7aeaf -F src/parse.y f374ab20106362eb3f5c01b3e6a002f0bbead7ff +F src/parse.y 99b676e6fc2f4e331ab93e76b3987cffdbd28efa F src/pcache.c 5583c8ade4b05075a60ba953ef471d1c1a9c05df F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 F src/pcache1.c 7f51d2b541aab57596adf62db2c4bb025d34f04d @@ -1507,7 +1507,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d6f6c87c9c0acf609a9d5bea818bb7a5437109a1 -R f74cc55ec1e76de02d5d11db76d4d3f2 +P 9e7bedeee444cbf0b1a9165e88928c5d85088de1 +R 235239c649979125e6dc80ee3d149e81 U drh -Z 27b5d9cc228b8d41a7c82f29fd5cd771 +Z 63a00886286115a66584905bc421be70 diff --git a/manifest.uuid b/manifest.uuid index 83360d7bd0..b1d3af8c41 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9e7bedeee444cbf0b1a9165e88928c5d85088de1 \ No newline at end of file +38a48cfb9a8212970c4a4f8458643c22ed067e8b \ No newline at end of file diff --git a/src/parse.y b/src/parse.y index 8a65131e28..087c52c839 100644 --- a/src/parse.y +++ b/src/parse.y @@ -1194,13 +1194,14 @@ nexprlist(A) ::= nexprlist(A) COMMA expr(Y). nexprlist(A) ::= expr(Y). {A = sqlite3ExprListAppend(pParse,0,Y.pExpr); /*A-overwrites-Y*/} +%ifndef SQLITE_OMIT_SUBQUERY /* A paren_exprlist is an optional expression list contained inside ** of parenthesis */ %type paren_exprlist {ExprList*} %destructor paren_exprlist {sqlite3ExprListDelete(pParse->db, $$);} paren_exprlist(A) ::= . {A = 0;} paren_exprlist(A) ::= LP exprlist(X) RP. {A = X;} - +%endif SQLITE_OMIT_SUBQUERY ///////////////////////////// The CREATE INDEX command /////////////////////// From 422dded5a9f9fe9aa26da20c5565be903609a83f Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 25 Jul 2016 16:10:43 +0000 Subject: [PATCH 0601/1484] Minor test infrastructure changes to better support SEE testing. FossilOrigin-Name: 8dcb9d506b5eef3a21d97877217e0df69966a915 --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/tester.tcl | 1 + test/walcrash4.test | 1 + 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index bd35ced110..d28b4841ce 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sa\snew\s%ifdef\sto\sparse.y\sso\sthat\sthe\sbuild\sworks\swith\sSQLITE_OMIT_SUBQUERY. -D 2016-07-25T14:40:43.866 +C Minor\stest\sinfrastructure\schanges\sto\sbetter\ssupport\sSEE\stesting. +D 2016-07-25T16:10:43.028 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -1128,7 +1128,7 @@ F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30 F test/temptable2.test cd396beb41117a5302fff61767c35fa4270a0d5e F test/temptable3.test d11a0974e52b347e45ee54ef1923c91ed91e4637 F test/temptrigger.test 8ec228b0db5d7ebc4ee9b458fc28cb9e7873f5e1 -F test/tester.tcl a52b5be1bb586afa1c8bcdcd4b86588645e1ae52 +F test/tester.tcl 949b4a73bd0324b7c796818d0d6a6715712932b3 F test/thread001.test 9f22fd3525a307ff42a326b6bc7b0465be1745a5 F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58 F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7 @@ -1366,7 +1366,7 @@ F test/walcksum.test bb234a1bb42248b3515d992b719708015c384278 F test/walcrash.test 21038858cc552077b0522f50b0fa87e38139306a F test/walcrash2.test a0edab4e5390f03b99a790de89aad15d6ec70b36 F test/walcrash3.test e426aa58122d20f2b9fbe9a507f9eb8cab85b8af -F test/walcrash4.test 3374d6a0813bfe9d841a973958e0552b545a6423 +F test/walcrash4.test e7b6e7639a950a0cca8e210e248c8dad4d63bf20 F test/walfault.test 1f8389f7709877e9b4cc679033d71d6fe529056b F test/walhook.test ed00a40ba7255da22d6b66433ab61fab16a63483 F test/walmode.test 4022fe03ae6e830583672caa101f046438a0473c @@ -1507,7 +1507,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 9e7bedeee444cbf0b1a9165e88928c5d85088de1 -R 235239c649979125e6dc80ee3d149e81 +P 38a48cfb9a8212970c4a4f8458643c22ed067e8b +R abfe7130c6ed9b2d2a4c15502875beef U drh -Z 63a00886286115a66584905bc421be70 +Z 61654b6f48f562a527ce39380211aaf2 diff --git a/manifest.uuid b/manifest.uuid index b1d3af8c41..ccfb379c00 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -38a48cfb9a8212970c4a4f8458643c22ed067e8b \ No newline at end of file +8dcb9d506b5eef3a21d97877217e0df69966a915 \ No newline at end of file diff --git a/test/tester.tcl b/test/tester.tcl index 3f1edc32ae..3fe84c641f 100644 --- a/test/tester.tcl +++ b/test/tester.tcl @@ -373,6 +373,7 @@ proc do_not_use_codec {} { set ::do_not_use_codec 1 reset_db } +unset -nocomplain do_not_use_codec # Return true if the "reserved_bytes" integer on database files is non-zero. # diff --git a/test/walcrash4.test b/test/walcrash4.test index 3abc16d1eb..80839b39e5 100644 --- a/test/walcrash4.test +++ b/test/walcrash4.test @@ -17,6 +17,7 @@ source $testdir/lock_common.tcl source $testdir/wal_common.tcl ifcapable !wal {finish_test ; return } set testprefix walcrash4 +do_not_use_codec #------------------------------------------------------------------------- # At one point, if "PRAGMA synchronous=full" is set and the platform From 07d9a031870a5eacb5cb31fdf67138ff5579acab Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 25 Jul 2016 21:11:53 +0000 Subject: [PATCH 0602/1484] Fix a test case in FTS5 to make it compatible with Tcl 8.5. FossilOrigin-Name: a495f8e77e14241150f79e746c7303284f04621a --- ext/fts5/test/fts5simple.test | 2 +- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/ext/fts5/test/fts5simple.test b/ext/fts5/test/fts5simple.test index 2bc02cf49a..5ac413c885 100644 --- a/ext/fts5/test/fts5simple.test +++ b/ext/fts5/test/fts5simple.test @@ -265,7 +265,7 @@ do_test 11.0 { execsql " INSERT INTO t4 VALUES('a b c \x1A'); INSERT INTO t4 VALUES('a b c d\x1A'); - INSERT INTO t4 VALUES('a b c \x1Ad'); + INSERT INTO t4 VALUES('a b c \x1Ag'); INSERT INTO t4 VALUES('a b c d'); " } {} diff --git a/manifest b/manifest index d28b4841ce..e46a5f0762 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Minor\stest\sinfrastructure\schanges\sto\sbetter\ssupport\sSEE\stesting. -D 2016-07-25T16:10:43.028 +C Fix\sa\stest\scase\sin\sFTS5\sto\smake\sit\scompatible\swith\sTcl\s8.5. +D 2016-07-25T21:11:53.996 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -180,7 +180,7 @@ F ext/fts5/test/fts5rank.test 2bdc0c5f22ccc1f9dbe9f4d0b82a491dce6f8a32 F ext/fts5/test/fts5rebuild.test 03935f617ace91ed23a6099c7c74d905227ff29b F ext/fts5/test/fts5restart.test c17728fdea26e7d0f617d22ad5b4b2862b994c17 F ext/fts5/test/fts5rowid.test 16908a99d6efc9ba21081b4f2b86b3fc699839a6 -F ext/fts5/test/fts5simple.test cd23d4072ea095d652c9b6db12284cc642e49c98 +F ext/fts5/test/fts5simple.test 5da9b15ed534eb0be9f279d8a2bb2e24d30e4e38 F ext/fts5/test/fts5simple2.test 98377ae1ff7749a42c21fe1a139c1ed312522c46 F ext/fts5/test/fts5simple3.test 8e71733b3d1b0e695011d02c68ebc5ca40b6124e F ext/fts5/test/fts5synonym.test 6475d189c2e20d60795808f83e36bf9318708d48 @@ -1507,7 +1507,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 38a48cfb9a8212970c4a4f8458643c22ed067e8b -R abfe7130c6ed9b2d2a4c15502875beef +P 8dcb9d506b5eef3a21d97877217e0df69966a915 +R 39b75cd52198f904a29885025a5d8665 U drh -Z 61654b6f48f562a527ce39380211aaf2 +Z ed1d5b465897ee96bacfa15f366335db diff --git a/manifest.uuid b/manifest.uuid index ccfb379c00..9a340b022c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8dcb9d506b5eef3a21d97877217e0df69966a915 \ No newline at end of file +a495f8e77e14241150f79e746c7303284f04621a \ No newline at end of file From 2b62b5def80c984918d197631723ea583a215efb Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 25 Jul 2016 22:40:12 +0000 Subject: [PATCH 0603/1484] In the VACUUM command, set the cache_size of the transient vacuum_db database to be the same as the database being vacuumed. FossilOrigin-Name: b78d99548ac53ac10dcc38368cc4b29c8cbcb09b --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vacuum.c | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index e46a5f0762..e225d5909f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\stest\scase\sin\sFTS5\sto\smake\sit\scompatible\swith\sTcl\s8.5. -D 2016-07-25T21:11:53.996 +C In\sthe\sVACUUM\scommand,\sset\sthe\scache_size\sof\sthe\stransient\svacuum_db\sdatabase\nto\sbe\sthe\ssame\sas\sthe\sdatabase\sbeing\svacuumed. +D 2016-07-25T22:40:12.561 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -448,7 +448,7 @@ F src/trigger.c e14840ee0c3e549e758ec9bf3e4146e166002280 F src/update.c 4f05ea8cddfa367d045e03589756c02199e8f9bd F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 810ec3f22e2d1b62e66c30fe3621ebdedd23584d -F src/vacuum.c 544ec90a66a4b0460b7c1baeadbc21b45e6ca0b6 +F src/vacuum.c 7949183a9ce2270fc76503384b1159fcb1e39723 F src/vdbe.c ea260b61e73b11a71e70b28a8e25866e2899e5da F src/vdbe.h 67bc551f7faf04c33493892e4b378aada823ed10 F src/vdbeInt.h c59381049af5c7751a83456c39b80d1a6fde1f9d @@ -1507,7 +1507,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 8dcb9d506b5eef3a21d97877217e0df69966a915 -R 39b75cd52198f904a29885025a5d8665 +P a495f8e77e14241150f79e746c7303284f04621a +R 8704dbefb85fb183a067d36d9af66cac U drh -Z ed1d5b465897ee96bacfa15f366335db +Z 422685421478fa78357b95bed0587f82 diff --git a/manifest.uuid b/manifest.uuid index 9a340b022c..3c7462248c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a495f8e77e14241150f79e746c7303284f04621a \ No newline at end of file +b78d99548ac53ac10dcc38368cc4b29c8cbcb09b \ No newline at end of file diff --git a/src/vacuum.c b/src/vacuum.c index 9ab7f766ee..16c4be01c0 100644 --- a/src/vacuum.c +++ b/src/vacuum.c @@ -197,6 +197,7 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){ } #endif + sqlite3BtreeSetCacheSize(pTemp, db->aDb[0].pSchema->cache_size); rc = execSql(db, pzErrMsg, "PRAGMA vacuum_db.synchronous=OFF"); if( rc!=SQLITE_OK ) goto end_of_vacuum; From 426f4ab0092550430f76bb73bebc0b9f49c052b3 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 26 Jul 2016 04:31:14 +0000 Subject: [PATCH 0604/1484] Make sure affinity is applied correctly on lower-bound range constraints in the min() optimization. Fix for ticket [a0bac8b3c3d1bb]. FossilOrigin-Name: b819bace9c2a0b0159122b26db96a8f50a6f0eac --- manifest | 15 ++++++++------- manifest.uuid | 2 +- src/wherecode.c | 1 + test/minmax.test | 14 ++++++++++++++ 4 files changed, 24 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index e225d5909f..287421d143 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\sthe\sVACUUM\scommand,\sset\sthe\scache_size\sof\sthe\stransient\svacuum_db\sdatabase\nto\sbe\sthe\ssame\sas\sthe\sdatabase\sbeing\svacuumed. -D 2016-07-25T22:40:12.561 +C Make\ssure\saffinity\sis\sapplied\scorrectly\son\slower-bound\srange\sconstraints\nin\sthe\smin()\soptimization.\s\sFix\sfor\sticket\s[a0bac8b3c3d1bb]. +D 2016-07-26T04:31:14.412 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -465,7 +465,7 @@ F src/wal.h 6dd221ed384afdc204bc61e25c23ef7fd5a511f2 F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354 F src/where.c 48eed8ebe319c6cbc7bf7682018f32af0f5189f5 F src/whereInt.h e5b939701a7ceffc5a3a8188a37f9746416ebcd0 -F src/wherecode.c 11e38f5e2dc5c007143fbf7fdb14bca40a6b74ad +F src/wherecode.c 99707d11907c71d289ee9553d2d1a22f1fd8ba41 F src/whereexpr.c d7dcbf14ce1b5876c1f76496162c30fcba669563 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -929,7 +929,7 @@ F test/memdb.test c1f2a343ad14398d5d6debda6ea33e80d0dafcc7 F test/memleak.test 10b9c6c57e19fc68c32941495e9ba1c50123f6e2 F test/memsubsys1.test 6d268d0ae90f8d61a2356a1838665654d83de518 F test/memsubsys2.test 3e4a8d0c05fd3e5fa92017c64666730a520c7e08 -F test/minmax.test 42fbad0e81afaa6e0de41c960329f2b2c3526efd +F test/minmax.test 6751e87b409fe11b02e70a306d846fa544e25a41 F test/minmax2.test b44bae787fc7b227597b01b0ca5575c7cb54d3bc F test/minmax3.test cc1e8b010136db0d01a6f2a29ba5a9f321034354 F test/minmax4.test 936941484ebdceb8adec7c86b6cd9b6e5e897c1f @@ -1507,7 +1507,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 a495f8e77e14241150f79e746c7303284f04621a -R 8704dbefb85fb183a067d36d9af66cac +P b78d99548ac53ac10dcc38368cc4b29c8cbcb09b +Q +0e9f534fef72ca142a4296ab5285c82aada38ba7 +R b5725dd72810ef0d52d5b0abd989daf2 U drh -Z 422685421478fa78357b95bed0587f82 +Z a046c0beaad1d7947f30a6bdc44927b5 diff --git a/manifest.uuid b/manifest.uuid index 3c7462248c..989f1b27ca 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b78d99548ac53ac10dcc38368cc4b29c8cbcb09b \ No newline at end of file +b819bace9c2a0b0159122b26db96a8f50a6f0eac \ No newline at end of file diff --git a/src/wherecode.c b/src/wherecode.c index 0b307761be..d78982f5b5 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -1319,6 +1319,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( } nConstraint++; testcase( pRangeStart->wtFlags & TERM_VIRTUAL ); + bSeekPastNull = 0; }else if( bSeekPastNull ){ sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq); nConstraint++; diff --git a/test/minmax.test b/test/minmax.test index fb9bbb383a..04a3f06dff 100644 --- a/test/minmax.test +++ b/test/minmax.test @@ -628,5 +628,19 @@ do_test_13_noopt 13.7 { SELECT min(c), count(c) FROM t1 WHERE a='a'; } {1 5} +# 2016-07-26. https://www.sqlite.org/src/info/a0bac8b3c3d1bb75 +# Incorrect result on a min() query after a CREATE INDEX. +# +do_execsql_test 14.1 { + CREATE TABLE t14(a INTEGER, b INTEGER); + INSERT INTO t14(a,b) VALUES(100,2),(200,2),(300,2),(400,1),(500,2); + SELECT min(a) FROM t14 WHERE b='2' AND a>'50'; +} {100} +do_execsql_test 14.2 { + CREATE INDEX t14ba ON t14(b,a); + SELECT min(a) FROM t14 WHERE b='2' AND a>'50'; +} {100} + + finish_test From 9d608759016b18d532a5a8e6bb17840f05e4b7d8 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 26 Jul 2016 04:49:43 +0000 Subject: [PATCH 0605/1484] Copy the cache_spill setting from the main database over to the vacuum_db transient database when running a VACUUM. FossilOrigin-Name: c0e7d98ef2a13ede5ae865083ede1aaffdf43310 --- manifest | 13 ++++++------- manifest.uuid | 2 +- src/vacuum.c | 1 + 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 287421d143..8ca4a9cd2c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\ssure\saffinity\sis\sapplied\scorrectly\son\slower-bound\srange\sconstraints\nin\sthe\smin()\soptimization.\s\sFix\sfor\sticket\s[a0bac8b3c3d1bb]. -D 2016-07-26T04:31:14.412 +C Copy\sthe\scache_spill\ssetting\sfrom\sthe\smain\sdatabase\sover\sto\sthe\nvacuum_db\stransient\sdatabase\swhen\srunning\sa\sVACUUM. +D 2016-07-26T04:49:43.617 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -448,7 +448,7 @@ F src/trigger.c e14840ee0c3e549e758ec9bf3e4146e166002280 F src/update.c 4f05ea8cddfa367d045e03589756c02199e8f9bd F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 810ec3f22e2d1b62e66c30fe3621ebdedd23584d -F src/vacuum.c 7949183a9ce2270fc76503384b1159fcb1e39723 +F src/vacuum.c 9dd2f5d276bc6094d8f1d85ecd41b30c1a002a43 F src/vdbe.c ea260b61e73b11a71e70b28a8e25866e2899e5da F src/vdbe.h 67bc551f7faf04c33493892e4b378aada823ed10 F src/vdbeInt.h c59381049af5c7751a83456c39b80d1a6fde1f9d @@ -1507,8 +1507,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b78d99548ac53ac10dcc38368cc4b29c8cbcb09b -Q +0e9f534fef72ca142a4296ab5285c82aada38ba7 -R b5725dd72810ef0d52d5b0abd989daf2 +P b819bace9c2a0b0159122b26db96a8f50a6f0eac +R 2279949c9ee671e45067af58637c4ef8 U drh -Z a046c0beaad1d7947f30a6bdc44927b5 +Z ef49efbba33d277501e077ba267218c2 diff --git a/manifest.uuid b/manifest.uuid index 989f1b27ca..59d5af71df 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b819bace9c2a0b0159122b26db96a8f50a6f0eac \ No newline at end of file +c0e7d98ef2a13ede5ae865083ede1aaffdf43310 \ No newline at end of file diff --git a/src/vacuum.c b/src/vacuum.c index 16c4be01c0..b72663c066 100644 --- a/src/vacuum.c +++ b/src/vacuum.c @@ -198,6 +198,7 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){ #endif sqlite3BtreeSetCacheSize(pTemp, db->aDb[0].pSchema->cache_size); + sqlite3BtreeSetSpillSize(pTemp, sqlite3BtreeSetSpillSize(pMain,0)); rc = execSql(db, pzErrMsg, "PRAGMA vacuum_db.synchronous=OFF"); if( rc!=SQLITE_OK ) goto end_of_vacuum; From 2900a6222f475f4d495c302aa5d5aab3dc1f0237 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 26 Jul 2016 10:46:21 +0000 Subject: [PATCH 0606/1484] Ensure that the sqlite3_scrub_backup() extension creates a backup database at least as large as indicated by the database header, even if the last page of the input database is a free-list leaf. FossilOrigin-Name: 483994a54dee3c7a3801e0e9d3c96fa9dbd8d2fd --- ext/misc/scrub.c | 16 ++++++++++++++++ manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/ext/misc/scrub.c b/ext/misc/scrub.c index 1d21fc5389..92718e23d1 100644 --- a/ext/misc/scrub.c +++ b/ext/misc/scrub.c @@ -74,6 +74,7 @@ struct ScrubState { u32 szPage; /* Page size */ u32 szUsable; /* Usable bytes on each page */ u32 nPage; /* Number of pages */ + u32 iLastPage; /* Page number of last page written so far*/ u8 *page1; /* Content of page 1 */ }; @@ -130,6 +131,7 @@ static void scrubBackupWrite(ScrubState *p, int pgno, const u8 *pData){ scrubBackupErr(p, "write failed for page %d", pgno); p->rcErr = SQLITE_IOERR; } + if( pgno>p->iLastPage ) p->iLastPage = pgno; } /* Prepare a statement against the "db" database. */ @@ -541,6 +543,20 @@ int sqlite3_scrub_backup( } sqlite3_finalize(pStmt); + /* If the last page of the input db file is a free-list leaf, then the + ** backup file on disk is still smaller than the size indicated within + ** the database header. In this case, write a page of zeroes to the + ** last page of the backup database so that SQLite does not mistakenly + ** think the db is corrupt. */ + if( s.iLastPage Date: Tue, 26 Jul 2016 18:06:08 +0000 Subject: [PATCH 0607/1484] Fix where.c handling of "IN (SELECT ...)" expressions when the SELECT returns more than one result column. Also error handling for other row value constructor cases. FossilOrigin-Name: 061b8006034f06a0311b4304c8b14d2c8b0153df --- manifest | 34 +++++++++--------- manifest.uuid | 2 +- src/expr.c | 50 ++++++++++++++++++-------- src/resolve.c | 2 +- src/where.c | 10 +++--- src/whereInt.h | 1 + src/wherecode.c | 85 +++++++++++++++++++++++++++++++++++++++------ src/whereexpr.c | 19 ++++++++++ test/e_expr.test | 4 +-- test/in.test | 15 ++++---- test/rowvalue3.test | 49 ++++++++++++++++++++++++-- test/select7.test | 12 +++---- test/subselect.test | 2 +- test/tester.tcl | 18 ++++++++-- 14 files changed, 233 insertions(+), 70 deletions(-) diff --git a/manifest b/manifest index 52753bfb10..c0f2b89a0d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Allow\svector\sIN(SELECT\s...)\sexpressions\sto\suse\san\sindex\sif\seither\sall\sthe\sindexed\scolumns\sare\sdeclared\sNOT\sNULL\sor\sif\sthere\sis\sno\sdifference\sbetween\sthe\sexpression\sevaluating\sto\s0\sand\sNULL\s(as\sin\sa\sWHERE\sclause). -D 2016-07-23T20:24:06.382 +C Fix\swhere.c\shandling\sof\s"IN\s(SELECT\s...)"\sexpressions\swhen\sthe\sSELECT\sreturns\smore\sthan\sone\sresult\scolumn.\sAlso\serror\shandling\sfor\sother\srow\svalue\sconstructor\scases. +D 2016-07-26T18:06:08.100 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -337,7 +337,7 @@ F src/ctime.c 61949e83c4c36e37195a8398ebc752780b534d95 F src/date.c 1cc9fb516ec9932c6fd4d2a0d2f8bc4480145c39 F src/dbstat.c 4f6f7f52b49beb9636ffbd517cfe44a402ba4ad0 F src/delete.c 4aba4214a377ce8ddde2d2e609777bcc8235200f -F src/expr.c 8ff9d70cc2077020327d1fa551558bb03e267da4 +F src/expr.c f84861eaaf557df45bb8f4513a78a05fbb0ad368 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c bc4145347595b7770f9a598cff1c848302cf5413 F src/func.c 61a4114cf7004f10c542cfabbab9f2bcb9033045 @@ -381,7 +381,7 @@ F src/pragma.h 64c78a648751b9f4f297276c4eb7507b14b4628c F src/prepare.c 22df6171aec1d86904ed2ad30c2348a5748aa04e F src/printf.c a5f0ca08ddede803c241266abb46356ec748ded1 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 -F src/resolve.c 9680caadd54772699e5a0a8ebd680e014703e4ee +F src/resolve.c 5c4d301a855d0245ddcc27365ddcbddd2f244665 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c 0115f5d222f5cf9b5511ec4072088417354d738a F src/shell.c a8a9e392a6a2777fabf5feb536931cb190f235e5 @@ -463,10 +463,10 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 02eeecc265f6ffd0597378f5d8ae9070b62a406a F src/wal.h 6dd221ed384afdc204bc61e25c23ef7fd5a511f2 F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354 -F src/where.c 898a45969bae1298cbaaaf05e6aeacfb45971293 -F src/whereInt.h 1ad3be2a43cb821418e1100476a3a14cd57635c4 -F src/wherecode.c eb0f5e8700afb110cb96fb873c0e9a015a9f63ff -F src/whereexpr.c d88ee6ce356cb9fd986d0e81249a2cd66a513093 +F src/where.c e7054b2c1fe31fef5136e5735d7958f5c2c7707d +F src/whereInt.h 14dd243e13b81cbb0a66063d38b70f93a7d6e613 +F src/wherecode.c 03fbaa63909d7e4b8af986595b811ae591032240 +F src/whereexpr.c b896f8ff6a53cbd3daaee84ec33e39098762bb46 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -643,7 +643,7 @@ F test/e_createtable.test d4c6059d44dcd4b636de9aae322766062b471844 F test/e_delete.test ab39084f26ae1f033c940b70ebdbbd523dc4962e F test/e_droptrigger.test 3cd080807622c13e5bbb61fc9a57bd7754da2412 F test/e_dropview.test 0c9f7f60989164a70a67a9d9c26d1083bc808306 -F test/e_expr.test 03a84a6fa9bd3472112d6bd4599f5269f5f74803 +F test/e_expr.test 3f9e639b5df18de36c0aa700703589cd65281174 F test/e_fkey.test a1783fe1f759e1990e6a11adfcf0702dac4d0707 F test/e_fts3.test 5c02288842e4f941896fd44afdef564dd5fc1459 F test/e_insert.test 3de217e95094d3d165992a6de1164bbc4bd92dc7 @@ -822,7 +822,7 @@ F test/hook.test 3b7b99d0eece6d279812c2aef6fa08bdfabc633e F test/icu.test 73956798bace8982909c00476b216714a6d0559a F test/ieee754.test 806fc0ce7f305f57e3331eaceeddcfec9339e607 F test/imposter1.test c3f1db2d3db2c24611a6596a3fc0ffc14f1466c8 -F test/in.test 61a24ae38d4b64ec69f06ccdf022992f68a98176 +F test/in.test 41d18d4bcd27c55d0bc6b6ddc8ff9e85e91728a4 F test/in2.test 5d4c61d17493c832f7d2d32bef785119e87bde75 F test/in3.test 3cbf58c87f4052cee3a58b37b6389777505aa0c0 F test/in4.test d2b38cba404bc4320f4fe1b595b3d163f212c068 @@ -1019,7 +1019,7 @@ F test/rowhash.test 0bc1d31415e4575d10cacf31e1a66b5cc0f8be81 F test/rowid.test 5b7509f384f4f6fae1af3c8c104c8ca299fea18d F test/rowvalue.test 979738b3d49f1d93e3fee56a71d4446217917abc F test/rowvalue2.test 8d5dfe75b8f4d1868a2f91f0356f20d36cba64ff -F test/rowvalue3.test 72a9fe5ad30df2d422876466e180c148ab88dc42 +F test/rowvalue3.test eeec47b4de27217a012dd142956b01af4e9bd6f2 F test/rtree.test 0c8d9dd458d6824e59683c19ab2ffa9ef946f798 F test/run-wordcount.sh 891e89c4c2d16e629cd45951d4ed899ad12afc09 F test/savepoint.test c671fdbd34cd3bfe1518a777526ada595180cf8d @@ -1043,7 +1043,7 @@ F test/select3.test 2ce595f8fb8e2ac10071d3b4e424cadd4634a054 F test/select4.test 5389d9895968d1196c457d59b3ee6515d771d328 F test/select5.test e758b8ef94f69b111df4cb819008856655dcd535 F test/select6.test 39eac4a5c03650b2b473c532882273283ee8b7a0 -F test/select7.test 95e370c42d47c3c52377d05e9ffc01ccff7c1f61 +F test/select7.test f659f231489349e8c5734e610803d7654207318f F test/select8.test 8c8f5ae43894c891efc5755ed905467d1d67ad5d F test/select9.test aebc2bb0c3bc44606125033cbcaac2c8d1f33a95 F test/selectA.test 101e722370ac6e84978c2958b8931c78b10a1709 @@ -1111,7 +1111,7 @@ F test/statfault.test f525a7bf633e50afd027700e9a486090684b1ac1 F test/stmt.test 64844332db69cf1a735fcb3e11548557fc95392f F test/subquery.test d7268d193dd33d5505df965399d3a594e76ae13f F test/subquery2.test 438f8a7da1457277b22e4176510f7659b286995f -F test/subselect.test d24fd8757daf97dafd2e889c73ea4c4272dcf4e4 +F test/subselect.test ccec43f85d488c6c4b6f98ea2dfa95b6086871c0 F test/substr.test 18f57c4ca8a598805c4d64e304c418734d843c1a F test/subtype1.test 7fe09496352f97053af1437150751be2d0a0cae8 F test/superlock.test ec94f0556b6488d97f71c79f9061ae08d9ab8f12 @@ -1131,7 +1131,7 @@ F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30 F test/temptable2.test cd396beb41117a5302fff61767c35fa4270a0d5e F test/temptable3.test d11a0974e52b347e45ee54ef1923c91ed91e4637 F test/temptrigger.test 8ec228b0db5d7ebc4ee9b458fc28cb9e7873f5e1 -F test/tester.tcl a52b5be1bb586afa1c8bcdcd4b86588645e1ae52 +F test/tester.tcl e1379282de5810a047c75d84eb6c914e00743b7e F test/thread001.test 9f22fd3525a307ff42a326b6bc7b0465be1745a5 F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58 F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7 @@ -1509,7 +1509,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 60fed5cdd4a44aefa1b4d505adeb7936f2f0b952 -R 1dc4c60c16780168f167fe34d6f77ee9 +P e2fd6f49b1b145bec09c581cc982b89429643ae9 +R a369e1eed01f702cd78474a2d1d557f1 U dan -Z f82474a4f9b8fbec7649c9e9d834d395 +Z 9143269c80fa998d2598183a7a999846 diff --git a/manifest.uuid b/manifest.uuid index 1150e4a104..5c153725ad 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e2fd6f49b1b145bec09c581cc982b89429643ae9 \ No newline at end of file +061b8006034f06a0311b4304c8b14d2c8b0153df \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 5792073228..f35ac56f80 100644 --- a/src/expr.c +++ b/src/expr.c @@ -339,6 +339,19 @@ static Expr *exprVectorField(Expr *pVector, int i){ return pVector->x.pList->a[i].pExpr; } +static int exprVectorSubselect(Parse *pParse, Expr *pExpr){ + int reg = 0; + if( pExpr->flags & EP_xIsSelect ){ + assert( pExpr->op==TK_REGISTER || pExpr->op==TK_SELECT ); + if( pExpr->op==TK_REGISTER ){ + reg = pExpr->iTable; + }else{ + reg = sqlite3CodeSubselect(pParse, pExpr, 0, 0); + } + } + return reg; +} + static void codeVectorCompare(Parse *pParse, Expr *pExpr, int dest){ Vdbe *v = pParse->pVdbe; Expr *pLeft = pExpr->pLeft; @@ -389,16 +402,8 @@ static void codeVectorCompare(Parse *pParse, Expr *pExpr, int dest){ break; } - if( pLeft->flags & EP_xIsSelect ){ - assert( pLeft->op==TK_SELECT || pLeft->op==TK_REGISTER ); - regLeft = sqlite3ExprCodeTarget(pParse, pLeft, 1); - assert( regLeft!=1 ); - } - if( pRight->flags & EP_xIsSelect ){ - assert( pRight->op==TK_SELECT || pRight->op==TK_REGISTER ); - regRight = sqlite3ExprCodeTarget(pParse, pRight, 1); - assert( regRight!=1 ); - } + regLeft = exprVectorSubselect(pParse, pLeft); + regRight = exprVectorSubselect(pParse, pRight); if( pParse->nErr ) return; for(i=0; inExpr!=nVal ){ - sqlite3ErrorMsg(pParse, "SELECT has %d columns - expected %d", - pEList->nExpr, nVal); + sqlite3SubselectError(pParse, pEList->nExpr, nVal); }else{ SelectDest dest; int i; @@ -3350,9 +3367,14 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ #ifndef SQLITE_OMIT_SUBQUERY case TK_EXISTS: case TK_SELECT: { + int nCol; testcase( op==TK_EXISTS ); testcase( op==TK_SELECT ); - inReg = sqlite3CodeSubselect(pParse, pExpr, 0, 0); + if( op==TK_SELECT && (nCol = pExpr->x.pSelect->pEList->nExpr)!=1 ){ + sqlite3SubselectError(pParse, nCol, 1); + }else{ + inReg = sqlite3CodeSubselect(pParse, pExpr, 0, 0); + } break; } case TK_IN: { diff --git a/src/resolve.c b/src/resolve.c index cd3d714613..cb9f2fbaa6 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -767,7 +767,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ } if( pExpr->op==TK_SELECT && pExpr->x.pSelect->pEList->nExpr>1 ){ - if( !ExprHasProperty(pExpr, EP_VectorOk) ){ + if( !ExprHasProperty(pExpr, EP_VectorOk) && 0 ){ sqlite3ErrorMsg(pParse, "invalid use of row value"); }else{ ExprSetProperty(pExpr, EP_Vector); diff --git a/src/where.c b/src/where.c index 36bf98b444..095891842f 100644 --- a/src/where.c +++ b/src/where.c @@ -4713,10 +4713,12 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ sqlite3VdbeResolveLabel(v, pLevel->addrNxt); for(j=pLevel->u.in.nIn, pIn=&pLevel->u.in.aInLoop[j-1]; j>0; j--, pIn--){ sqlite3VdbeJumpHere(v, pIn->addrInTop+1); - sqlite3VdbeAddOp2(v, pIn->eEndLoopOp, pIn->iCur, pIn->addrInTop); - VdbeCoverage(v); - VdbeCoverageIf(v, pIn->eEndLoopOp==OP_PrevIfOpen); - VdbeCoverageIf(v, pIn->eEndLoopOp==OP_NextIfOpen); + if( pIn->eEndLoopOp!=OP_Noop ){ + sqlite3VdbeAddOp2(v, pIn->eEndLoopOp, pIn->iCur, pIn->addrInTop); + VdbeCoverage(v); + VdbeCoverageIf(v, pIn->eEndLoopOp==OP_PrevIfOpen); + VdbeCoverageIf(v, pIn->eEndLoopOp==OP_NextIfOpen); + } sqlite3VdbeJumpHere(v, pIn->addrInTop-1); } } diff --git a/src/whereInt.h b/src/whereInt.h index d288fa6192..d86373ecd5 100644 --- a/src/whereInt.h +++ b/src/whereInt.h @@ -248,6 +248,7 @@ struct WhereTerm { Expr *pExpr; /* Pointer to the subexpression that is this term */ int iParent; /* Disable pWC->a[iParent] when this term disabled */ int leftCursor; /* Cursor number of X in "X " */ + int iField; /* Field in (?,?,?) IN (SELECT...) vector */ union { int leftColumn; /* Column number of X in "X " */ WhereOrInfo *pOrInfo; /* Extra information if (eOperator & WO_OR)!=0 */ diff --git a/src/wherecode.c b/src/wherecode.c index 0f6d320241..69dd2e97fb 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -356,6 +356,7 @@ static int codeEqualityTerm( Vdbe *v = pParse->pVdbe; int iReg; /* Register holding results */ + assert( pLevel->pWLoop->aLTerm[iEq]==pTerm ); assert( iTarget>0 ); if( pX->op==TK_EQ || pX->op==TK_IS ){ iReg = sqlite3ExprCodeTarget(pParse, pX->pRight, iTarget); @@ -368,6 +369,9 @@ static int codeEqualityTerm( int iTab; struct InLoop *pIn; WhereLoop *pLoop = pLevel->pWLoop; + int i; + int nEq = 0; + int *aiMap = 0; if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 && pLoop->u.btree.pIndex!=0 @@ -379,7 +383,52 @@ static int codeEqualityTerm( } assert( pX->op==TK_IN ); iReg = iTarget; - eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, 0); + + for(i=0; iaLTerm[i] && pLoop->aLTerm[i]->pExpr==pX ){ + disableTerm(pLevel, pTerm); + return iTarget; + } + } + for(i=iEq;inLTerm; i++){ + if( pLoop->aLTerm[i] && pLoop->aLTerm[i]->pExpr==pX ) nEq++; + } + + if( nEq>1 ){ + aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int) * nEq); + if( !aiMap ) return 0; + } + + if( (pX->flags & EP_xIsSelect)==0 || pX->x.pSelect->pEList->nExpr==1 ){ + eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, 0); + }else{ + sqlite3 *db = pParse->db; + ExprList *pOrigRhs = pX->x.pSelect->pEList; + ExprList *pOrigLhs = pX->pLeft->x.pList; + ExprList *pRhs = 0; /* New Select.pEList for RHS */ + ExprList *pLhs = 0; /* New pX->pLeft vector */ + + for(i=iEq;inLTerm; i++){ + if( pLoop->aLTerm[i]->pExpr==pX ){ + int iField = pLoop->aLTerm[i]->iField - 1; + Expr *pNewRhs = sqlite3ExprDup(db, pOrigRhs->a[iField].pExpr, 0); + Expr *pNewLhs = sqlite3ExprDup(db, pOrigLhs->a[iField].pExpr, 0); + + pRhs = sqlite3ExprListAppend(pParse, pRhs, pNewRhs); + pLhs = sqlite3ExprListAppend(pParse, pLhs, pNewLhs); + } + } + + pX->x.pSelect->pEList = pRhs; + pX->pLeft->x.pList = pLhs; + + eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap); + pX->x.pSelect->pEList = pOrigRhs; + pX->pLeft->x.pList = pOrigLhs; + sqlite3ExprListDelete(pParse->db, pLhs); + sqlite3ExprListDelete(pParse->db, pRhs); + } + if( eType==IN_INDEX_INDEX_DESC ){ testcase( bRev ); bRev = !bRev; @@ -389,28 +438,44 @@ static int codeEqualityTerm( VdbeCoverageIf(v, bRev); VdbeCoverageIf(v, !bRev); assert( (pLoop->wsFlags & WHERE_MULTI_OR)==0 ); + pLoop->wsFlags |= WHERE_IN_ABLE; if( pLevel->u.in.nIn==0 ){ pLevel->addrNxt = sqlite3VdbeMakeLabel(v); } - pLevel->u.in.nIn++; + + i = pLevel->u.in.nIn; + pLevel->u.in.nIn += nEq; pLevel->u.in.aInLoop = sqlite3DbReallocOrFree(pParse->db, pLevel->u.in.aInLoop, sizeof(pLevel->u.in.aInLoop[0])*pLevel->u.in.nIn); pIn = pLevel->u.in.aInLoop; if( pIn ){ - pIn += pLevel->u.in.nIn - 1; - pIn->iCur = iTab; - if( eType==IN_INDEX_ROWID ){ - pIn->addrInTop = sqlite3VdbeAddOp2(v, OP_Rowid, iTab, iReg); - }else{ - pIn->addrInTop = sqlite3VdbeAddOp3(v, OP_Column, iTab, 0, iReg); + int iMap = 0; /* Index in aiMap[] */ + pIn += i; + for(i=iEq;inLTerm; i++, pIn++){ + if( pLoop->aLTerm[i]->pExpr==pX ){ + if( eType==IN_INDEX_ROWID ){ + assert( nEq==1 && i==iEq ); + pIn->addrInTop = sqlite3VdbeAddOp2(v, OP_Rowid, iTab, iReg); + }else{ + int iCol = aiMap ? aiMap[iMap++] : 0; + int iOut = iReg + i - iEq; + pIn->addrInTop = sqlite3VdbeAddOp3(v,OP_Column,iTab, iCol, iOut); + } + if( i==iEq ){ + pIn->iCur = iTab; + pIn->eEndLoopOp = bRev ? OP_PrevIfOpen : OP_NextIfOpen; + }else{ + pIn->eEndLoopOp = OP_Noop; + } + } + sqlite3VdbeAddOp1(v, OP_IsNull, iReg); VdbeCoverage(v); } - pIn->eEndLoopOp = bRev ? OP_PrevIfOpen : OP_NextIfOpen; - sqlite3VdbeAddOp1(v, OP_IsNull, iReg); VdbeCoverage(v); }else{ pLevel->u.in.nIn = 0; } + sqlite3DbFree(pParse->db, aiMap); #endif } disableTerm(pLevel, pTerm); diff --git a/src/whereexpr.c b/src/whereexpr.c index 35af70687b..67b2e67baa 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -960,6 +960,12 @@ static void exprAnalyze( Expr *pLeft = sqlite3ExprSkipCollate(pExpr->pLeft); Expr *pRight = sqlite3ExprSkipCollate(pExpr->pRight); u16 opMask = (pTerm->prereqRight & prereqLeft)==0 ? WO_ALL : WO_EQUIV; + + if( op==TK_IN && pTerm->iField>0 ){ + assert( pLeft->op==TK_VECTOR ); + pLeft = pLeft->x.pList->a[pTerm->iField-1].pExpr; + } + if( exprMightBeIndexed(pSrc, op, prereqLeft, pLeft, &iCur, &iColumn) ){ pTerm->leftCursor = iCur; pTerm->u.leftColumn = iColumn; @@ -1195,6 +1201,19 @@ static void exprAnalyze( } } + if( pWC->op==TK_AND && pExpr->op==TK_IN && pTerm->iField==0 + && pExpr->pLeft->op==TK_VECTOR + ){ + int i; + for(i=0; ipLeft); i++){ + int idxNew; + idxNew = whereClauseInsert(pWC, pExpr, TERM_VIRTUAL); + pWC->a[idxNew].iField = i+1; + exprAnalyze(pSrc, pWC, idxNew); + markTermAsChild(pWC, idxNew, idxTerm); + } + } + #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 /* When sqlite_stat3 histogram data is available an operator of the ** form "x IS NOT NULL" can sometimes be evaluated more efficiently diff --git a/test/e_expr.test b/test/e_expr.test index 8c0957f8d3..6ef55ce8a6 100644 --- a/test/e_expr.test +++ b/test/e_expr.test @@ -1809,7 +1809,7 @@ do_expr_test e_expr-35.1.6 { # The following block tests that errors are returned in a bunch of cases # where a subquery returns more than one column. # -set M {only a single result allowed for a SELECT that is part of an expression} +set M {/1 {sub-select returns [23] columns - expected 1}/} foreach {tn sql} { 1 { SELECT (SELECT * FROM t2 UNION SELECT a+1, b+1 FROM t2) } 2 { SELECT (SELECT * FROM t2 UNION SELECT a+1, b+1 FROM t2 ORDER BY 1) } @@ -1818,7 +1818,7 @@ foreach {tn sql} { 5 { SELECT (SELECT * FROM t2) } 6 { SELECT (SELECT * FROM (SELECT 1, 2, 3)) } } { - do_catchsql_test e_expr-35.2.$tn $sql [list 1 $M] + do_catchsql_test e_expr-35.2.$tn $sql $M } # EVIDENCE-OF: R-35764-28041 The result of the expression is the value diff --git a/test/in.test b/test/in.test index 3a42e84b9a..c88a4a6952 100644 --- a/test/in.test +++ b/test/in.test @@ -314,7 +314,7 @@ do_test in-9.4 { catchsql { SELECT b FROM t1 WHERE a NOT IN tb; } -} {1 {only a single result allowed for a SELECT that is part of an expression}} +} {1 {sub-select returns 2 columns - expected 1}} # IN clauses in CHECK constraints. Ticket #1645 # @@ -391,28 +391,28 @@ do_test in-12.2 { SELECT a, b FROM t3 UNION ALL SELECT a, b FROM t2 ); } -} {1 {only a single result allowed for a SELECT that is part of an expression}} +} {1 {sub-select returns 2 columns - expected 1}} do_test in-12.3 { catchsql { SELECT * FROM t2 WHERE a IN ( SELECT a, b FROM t3 UNION SELECT a, b FROM t2 ); } -} {1 {only a single result allowed for a SELECT that is part of an expression}} +} {1 {sub-select returns 2 columns - expected 1}} do_test in-12.4 { catchsql { SELECT * FROM t2 WHERE a IN ( SELECT a, b FROM t3 EXCEPT SELECT a, b FROM t2 ); } -} {1 {only a single result allowed for a SELECT that is part of an expression}} +} {1 {sub-select returns 2 columns - expected 1}} do_test in-12.5 { catchsql { SELECT * FROM t2 WHERE a IN ( SELECT a, b FROM t3 INTERSECT SELECT a, b FROM t2 ); } -} {1 {only a single result allowed for a SELECT that is part of an expression}} +} {1 {sub-select returns 2 columns - expected 1}} do_test in-12.6 { catchsql { SELECT * FROM t2 WHERE a IN ( @@ -478,7 +478,7 @@ do_test in-12.14 { SELECT a, b FROM t3 UNION ALL SELECT a, b FROM t2 ); } -} {1 {only a single result allowed for a SELECT that is part of an expression}} +} {1 {sub-select returns 2 columns - expected 1}} do_test in-12.15 { catchsql { SELECT * FROM t2 WHERE a IN ( @@ -629,11 +629,12 @@ do_test in-13.14 { } } {} +breakpoint do_test in-13.15 { catchsql { SELECT 0 WHERE (SELECT 0,0) OR (0 IN (1,2)); } -} {1 {only a single result allowed for a SELECT that is part of an expression}} +} {1 {sub-select returns 2 columns - expected 1}} do_test in-13.X { diff --git a/test/rowvalue3.test b/test/rowvalue3.test index 63f2c8939a..78bf21b615 100644 --- a/test/rowvalue3.test +++ b/test/rowvalue3.test @@ -42,11 +42,56 @@ foreach {tn sql res} { do_execsql_test 1.$tn $sql $res } -#explain_i { SELECT (4, NULL) IN (SELECT a, b FROM t1) } -#do_execsql_test 2 { SELECT (4, NULL) IN (SELECT a, b FROM t1) } {} +#------------------------------------------------------------------------- +do_execsql_test 2.0 { + CREATE TABLE z1(x, y, z); + CREATE TABLE kk(a, b); + INSERT INTO z1 VALUES('a', 'b', 'c'); + INSERT INTO z1 VALUES('d', 'e', 'f'); + INSERT INTO z1 VALUES('g', 'h', 'i'); + -- INSERT INTO kk VALUES('y', 'y'); + INSERT INTO kk VALUES('d', 'e'); + -- INSERT INTO kk VALUES('x', 'x'); + +} + +foreach {tn idx} { + 1 { } + 2 { CREATE INDEX z1idx ON z1(x, y) } + 3 { CREATE UNIQUE INDEX z1idx ON z1(x, y) } +} { + execsql "DROP INDEX IF EXISTS z1idx" + execsql $idx + + do_execsql_test 2.$tn.1 { + SELECT * FROM z1 WHERE x IN (SELECT a FROM kk) + } {d e f} + + do_execsql_test 2.$tn.2 { + SELECT * FROM z1 WHERE (x,y) IN (SELECT a, b FROM kk) + } {d e f} + + do_execsql_test 2.$tn.3 { + SELECT * FROM z1 WHERE (x, +y) IN (SELECT a, b FROM kk) + } {d e f} + + do_execsql_test 2.$tn.4 { + SELECT * FROM z1 WHERE (x, +y) IN (SELECT a, b||'x' FROM kk) + } {} + + do_execsql_test 2.$tn.5 { + SELECT * FROM z1 WHERE (+x, y) IN (SELECT a, b FROM kk) + } {d e f} +} + +explain_i { + SELECT * FROM z1 WHERE (x, y) IN (SELECT a, b FROM kk) +} finish_test + + diff --git a/test/select7.test b/test/select7.test index 0df84e13d9..d705ebfaf4 100644 --- a/test/select7.test +++ b/test/select7.test @@ -114,26 +114,22 @@ ifcapable {subquery && compound} { CREATE TABLE t2(a,b); SELECT 5 IN (SELECT a,b FROM t2); } - } [list 1 \ - {only a single result allowed for a SELECT that is part of an expression}] + } {1 {sub-select returns 2 columns - expected 1}} do_test select7-5.2 { catchsql { SELECT 5 IN (SELECT * FROM t2); } - } [list 1 \ - {only a single result allowed for a SELECT that is part of an expression}] + } {1 {sub-select returns 2 columns - expected 1}} do_test select7-5.3 { catchsql { SELECT 5 IN (SELECT a,b FROM t2 UNION SELECT b,a FROM t2); } - } [list 1 \ - {only a single result allowed for a SELECT that is part of an expression}] + } {1 {sub-select returns 2 columns - expected 1}} do_test select7-5.4 { catchsql { SELECT 5 IN (SELECT * FROM t2 UNION SELECT * FROM t2); } - } [list 1 \ - {only a single result allowed for a SELECT that is part of an expression}] + } {1 {sub-select returns 2 columns - expected 1}} } # Verify that an error occurs if you have too many terms on a diff --git a/test/subselect.test b/test/subselect.test index 247f68ee80..fc1c103085 100644 --- a/test/subselect.test +++ b/test/subselect.test @@ -40,7 +40,7 @@ do_test subselect-1.1 { do_test subselect-1.2 { set v [catch {execsql {SELECT * FROM t1 WHERE a = (SELECT * FROM t1)}} msg] lappend v $msg -} {1 {only a single result allowed for a SELECT that is part of an expression}} +} {1 {sub-select returns 2 columns - expected 1}} # A subselect without an aggregate. # diff --git a/test/tester.tcl b/test/tester.tcl index 3f1edc32ae..f258425c47 100644 --- a/test/tester.tcl +++ b/test/tester.tcl @@ -1288,9 +1288,9 @@ proc explain_i {sql {db db}} { set D "" } foreach opcode { - Seek SeekGe SeekGt SeekLe SeekLt NotFound Last Rewind + Seek SeekGE SeekGT SeekLE SeekLT NotFound Last Rewind NoConflict Next Prev VNext VPrev VFilter - SorterSort SorterNext + SorterSort SorterNext NextIfOpen } { set color($opcode) $B } @@ -1311,9 +1311,15 @@ proc explain_i {sql {db db}} { set bSeenGoto 1 } + if {$opcode=="Once"} { + for {set i $addr} {$i<$p2} {incr i} { + set star($i) $addr + } + } + if {$opcode=="Next" || $opcode=="Prev" || $opcode=="VNext" || $opcode=="VPrev" - || $opcode=="SorterNext" + || $opcode=="SorterNext" || $opcode=="NextIfOpen" } { for {set i $p2} {$i<$addr} {incr i} { incr x($i) 2 @@ -1337,6 +1343,12 @@ proc explain_i {sql {db db}} { } set I [string repeat " " $x($addr)] + if {[info exists star($addr)]} { + set ii [expr $x($star($addr))] + append I " " + set I [string replace $I $ii $ii *] + } + set col "" catch { set col $color($opcode) } From d93ba6271b2d9e592dd27796f78bebdec09875ca Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 27 Jul 2016 16:03:54 +0000 Subject: [PATCH 0608/1484] Initialize a variable in where.c to avoid a valgrind warning. FossilOrigin-Name: 4d59df02d3713b3e3804e1a88e676749b2794286 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/where.c | 2 +- test/in.test | 11 +++++++++++ 4 files changed, 20 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 7f897eb954..185e06b3cc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Ensure\sthat\sthe\ssqlite3_scrub_backup()\sextension\screates\sa\sbackup\sdatabase\sat\sleast\sas\slarge\sas\sindicated\sby\sthe\sdatabase\sheader,\seven\sif\sthe\slast\spage\sof\sthe\sinput\sdatabase\sis\sa\sfree-list\sleaf. -D 2016-07-26T10:46:21.988 +C Initialize\sa\svariable\sin\swhere.c\sto\savoid\sa\svalgrind\swarning. +D 2016-07-27T16:03:54.108 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -463,7 +463,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 02eeecc265f6ffd0597378f5d8ae9070b62a406a F src/wal.h 6dd221ed384afdc204bc61e25c23ef7fd5a511f2 F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354 -F src/where.c 48eed8ebe319c6cbc7bf7682018f32af0f5189f5 +F src/where.c 9981707ac01438baea5caa0ca6108237be6630da F src/whereInt.h e5b939701a7ceffc5a3a8188a37f9746416ebcd0 F src/wherecode.c 99707d11907c71d289ee9553d2d1a22f1fd8ba41 F src/whereexpr.c d7dcbf14ce1b5876c1f76496162c30fcba669563 @@ -822,7 +822,7 @@ F test/hook.test 3b7b99d0eece6d279812c2aef6fa08bdfabc633e F test/icu.test 73956798bace8982909c00476b216714a6d0559a F test/ieee754.test 806fc0ce7f305f57e3331eaceeddcfec9339e607 F test/imposter1.test c3f1db2d3db2c24611a6596a3fc0ffc14f1466c8 -F test/in.test 61a24ae38d4b64ec69f06ccdf022992f68a98176 +F test/in.test 61d940ced6817bee66e4e0b09d5bc8608f57134b F test/in2.test 5d4c61d17493c832f7d2d32bef785119e87bde75 F test/in3.test 3cbf58c87f4052cee3a58b37b6389777505aa0c0 F test/in4.test d2b38cba404bc4320f4fe1b595b3d163f212c068 @@ -1507,7 +1507,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P c0e7d98ef2a13ede5ae865083ede1aaffdf43310 -R 783c6677056c1c6297ef166e24fadbce +P 483994a54dee3c7a3801e0e9d3c96fa9dbd8d2fd +R d3646a4fd33e16c76415db60501a55b1 U dan -Z 42a389186c57610d077ea553714cade1 +Z 64999ea9da24ca9027e2e455a4d899cc diff --git a/manifest.uuid b/manifest.uuid index 1e810448d2..83f63152b3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -483994a54dee3c7a3801e0e9d3c96fa9dbd8d2fd \ No newline at end of file +4d59df02d3713b3e3804e1a88e676749b2794286 \ No newline at end of file diff --git a/src/where.c b/src/where.c index a65f30968e..23ec21c160 100644 --- a/src/where.c +++ b/src/where.c @@ -3949,7 +3949,7 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ if( pWInfo->nOBSat<=0 ){ pWInfo->nOBSat = 0; if( nLoop>0 ){ - Bitmask m; + Bitmask m = 0; int rc = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pOrderBy, pFrom, WHERE_ORDERBY_LIMIT, nLoop-1, pFrom->aLoop[nLoop-1], &m); if( rc==pWInfo->pOrderBy->nExpr ){ diff --git a/test/in.test b/test/in.test index 3a42e84b9a..3c87a2a86f 100644 --- a/test/in.test +++ b/test/in.test @@ -640,4 +640,15 @@ do_test in-13.X { db nullvalue "" } {} +# At one point the following was causing valgrind to report a "jump +# depends on unitialized location" problem. +# +do_execsql_test in-14.0 { + CREATE TABLE c1(a); + INSERT INTO c1 VALUES(1), (2), (4), (3); +} +do_execsql_test in-14.1 { + SELECT * FROM c1 WHERE a IN (SELECT a FROM c1) ORDER BY 1 +} {1 2 3 4} + finish_test From 2409f8a11232ff4e2999168f01e954502f189f02 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 27 Jul 2016 18:27:02 +0000 Subject: [PATCH 0609/1484] When estimating the cost of an index scan, factor in the cost savings of being able to use the index to evaluate some WHERE clause terms without having to do a table lookup. FossilOrigin-Name: a59b5622f7cc6e502d71aabc12c053582cd03609 --- manifest | 21 +++++++++++-------- manifest.uuid | 2 +- src/expr.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++ src/sqliteInt.h | 2 ++ src/where.c | 29 +++++++++++++++++++++++--- 5 files changed, 96 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 7f897eb954..0e15122481 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Ensure\sthat\sthe\ssqlite3_scrub_backup()\sextension\screates\sa\sbackup\sdatabase\sat\sleast\sas\slarge\sas\sindicated\sby\sthe\sdatabase\sheader,\seven\sif\sthe\slast\spage\sof\sthe\sinput\sdatabase\sis\sa\sfree-list\sleaf. -D 2016-07-26T10:46:21.988 +C When\sestimating\sthe\scost\sof\san\sindex\sscan,\sfactor\sin\sthe\scost\ssavings\sof\nbeing\sable\sto\suse\sthe\sindex\sto\sevaluate\ssome\sWHERE\sclause\sterms\swithout\nhaving\sto\sdo\sa\stable\slookup. +D 2016-07-27T18:27:02.556 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -337,7 +337,7 @@ F src/ctime.c 61949e83c4c36e37195a8398ebc752780b534d95 F src/date.c 1cc9fb516ec9932c6fd4d2a0d2f8bc4480145c39 F src/dbstat.c 4f6f7f52b49beb9636ffbd517cfe44a402ba4ad0 F src/delete.c 4aba4214a377ce8ddde2d2e609777bcc8235200f -F src/expr.c 21b153e1046c624e9387a17d3261f69b461e700c +F src/expr.c 3347e66d4e27ec5f3ec7573b9a5f899bbd7d1df8 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c bc4145347595b7770f9a598cff1c848302cf5413 F src/func.c 61a4114cf7004f10c542cfabbab9f2bcb9033045 @@ -388,7 +388,7 @@ F src/shell.c 9351fc6de11e1d908648c0a92d85627138e3dee5 F src/sqlite.h.in c6e68a4a47610631822a4f8f83a44c9f75339331 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 46f300b6e300e0fa916d7d58c44b53415b8471a9 -F src/sqliteInt.h 49081ceab08eda9943d555aee57392c5b35d1c60 +F src/sqliteInt.h d25c18c1272a7811e2569c39bfc2fca96156eead F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c 5b18f9526900f61189ab0b83f1ef41d9f871a2ab F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 @@ -463,7 +463,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 02eeecc265f6ffd0597378f5d8ae9070b62a406a F src/wal.h 6dd221ed384afdc204bc61e25c23ef7fd5a511f2 F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354 -F src/where.c 48eed8ebe319c6cbc7bf7682018f32af0f5189f5 +F src/where.c 7e4d676b5ac4434e5f93606a744d396dc40d9977 F src/whereInt.h e5b939701a7ceffc5a3a8188a37f9746416ebcd0 F src/wherecode.c 99707d11907c71d289ee9553d2d1a22f1fd8ba41 F src/whereexpr.c d7dcbf14ce1b5876c1f76496162c30fcba669563 @@ -1507,7 +1507,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P c0e7d98ef2a13ede5ae865083ede1aaffdf43310 -R 783c6677056c1c6297ef166e24fadbce -U dan -Z 42a389186c57610d077ea553714cade1 +P 483994a54dee3c7a3801e0e9d3c96fa9dbd8d2fd +R 9e4bd013f5c2cf2171d472668aed0d1c +T *branch * improved-index-scan +T *sym-improved-index-scan * +T -sym-trunk * +U drh +Z 8f3398744130761f466da0e8b7212fe4 diff --git a/manifest.uuid b/manifest.uuid index 1e810448d2..6da37e4d78 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -483994a54dee3c7a3801e0e9d3c96fa9dbd8d2fd \ No newline at end of file +a59b5622f7cc6e502d71aabc12c053582cd03609 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index ea52d66253..c027cf02a4 100644 --- a/src/expr.c +++ b/src/expr.c @@ -3965,6 +3965,61 @@ int sqlite3ExprImpliesExpr(Expr *pE1, Expr *pE2, int iTab){ return 0; } +/* +** An instance of the following structure is used by the tree walker +** to determine if an expression can be evaluated by reference to the +** index only, without having to do a search for the corresponding +** table entry. The IdxCover.pIdx field is the index. IdxCover.iCur +** is the cursor for the table. +*/ +struct IdxCover { + Index *pIdx; /* The index to be tested for coverage */ + int iCur; /* Cursor number for the table corresponding to the index */ +}; + +/* +** Check to see if there are references to columns in table +** pWalker->u.pIdxCover->iCur can be satisfied using the index +** pWalker->u.pIdxCover->pIdx. +*/ +static int exprIdxCover(Walker *pWalker, Expr *pExpr){ + if( pExpr->op==TK_COLUMN + && pExpr->iTable==pWalker->u.pIdxCover->iCur + && sqlite3ColumnOfIndex(pWalker->u.pIdxCover->pIdx, pExpr->iColumn)<0 + ){ + pWalker->eCode = 1; + return WRC_Abort; + } + return WRC_Continue; +} + +/* +** Determine if an index on table iCur that contains the columns in +** Bitmask m will cover the expression pExpr. Return true if the index +** does cover the expression and false if the expression references +** table columns that are not found in the index. +** +** An index covering an expression means that the expression can be +** evaluated using only the index and without having to lookup the +** corresponding table entry. +*/ +int sqlite3ExprCoveredByIndex( + Expr *pExpr, /* The index to be tested */ + int iCur, /* The cursor number for the corresponding table */ + Index *pIdx /* The index that might be used for coverage */ +){ + Walker w; + struct IdxCover xcov; + memset(&w, 0, sizeof(w)); + xcov.iCur = iCur; + xcov.pIdx = pIdx; + w.xExprCallback = exprIdxCover; + w.u.pIdxCover = &xcov; + sqlite3WalkExpr(&w, pExpr); + return !w.eCode; +} + + /* ** An instance of the following structure is used by the tree walker ** to count references to table columns in the arguments of an diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 879e6703ca..c5b1eccc03 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3257,6 +3257,7 @@ struct Walker { struct SrcCount *pSrcCount; /* Counting column references */ struct CCurHint *pCCurHint; /* Used by codeCursorHint() */ int *aiCol; /* array of column indexes */ + struct IdxCover *pIdxCover; /* Check for index coverage */ } u; }; @@ -3700,6 +3701,7 @@ int sqlite3ExprListCompare(ExprList*, ExprList*, int); int sqlite3ExprImpliesExpr(Expr*, Expr*, int); void sqlite3ExprAnalyzeAggregates(NameContext*, Expr*); void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*); +int sqlite3ExprCoveredByIndex(Expr*, int iCur, Index *pIdx); int sqlite3FunctionUsesThisSrc(Expr*, SrcList*); Vdbe *sqlite3GetVdbe(Parse*); #ifndef SQLITE_OMIT_BUILTIN_TEST diff --git a/src/where.c b/src/where.c index a65f30968e..6a02574921 100644 --- a/src/where.c +++ b/src/where.c @@ -2775,11 +2775,34 @@ static int whereLoopAddBtree( /* The cost of visiting the index rows is N*K, where K is ** between 1.1 and 3.0, depending on the relative sizes of the - ** index and table rows. If this is a non-covering index scan, - ** also add the cost of visiting table rows (N*3.0). */ + ** index and table rows. */ pNew->rRun = rSize + 1 + (15*pProbe->szIdxRow)/pTab->szTabRow; if( m!=0 ){ - pNew->rRun = sqlite3LogEstAdd(pNew->rRun, rSize+16); + /* If this is a non-covering index scan, add in the cost of + ** doing table lookups. The cost will be 3x the number of + ** lookups. Take into account WHERE clause terms that can be + ** satisfied using just the index, and that do not require a + ** table lookup. */ + LogEst nLookup = rSize + 16; /* Base cost: N*3 */ + int ii; + int iCur = pSrc->iCursor; + WhereClause *pWC = &pWInfo->sWC; + for(ii=0; iinTerm; ii++){ + WhereTerm *pTerm = &pWC->a[ii]; + if( !sqlite3ExprCoveredByIndex(pTerm->pExpr, iCur, pProbe) ){ + break; + } + /* pTerm can be evaluated using just the index. So reduce + ** the expected number of table lookups accordingly */ + if( pTerm->truthProb<=0 ){ + nLookup += pTerm->truthProb; + }else{ + nLookup--; + if( pTerm->eOperator & (WO_EQ|WO_IS) ) nLookup -= 19; + } + } + + pNew->rRun = sqlite3LogEstAdd(pNew->rRun, nLookup); } ApplyCostMultiplier(pNew->rRun, pTab->costMult); whereLoopOutputAdjust(pWC, pNew, rSize); From e604ec0be02b4e550883c0998c5872a2ba2459ce Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 27 Jul 2016 19:20:58 +0000 Subject: [PATCH 0610/1484] Add test cases and fix a comment. FossilOrigin-Name: 50f8ea37fb9647c4a9da2c269a4d6f54b10ce96b --- manifest | 20 +++++++-------- manifest.uuid | 2 +- src/expr.c | 8 +++--- src/where.c | 4 +-- test/index8.test | 60 ++++++++++++++++++++++++++++++++++++++++++++ test/scanstatus.test | 4 +-- 6 files changed, 78 insertions(+), 20 deletions(-) create mode 100644 test/index8.test diff --git a/manifest b/manifest index 0e15122481..b810c2000b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C When\sestimating\sthe\scost\sof\san\sindex\sscan,\sfactor\sin\sthe\scost\ssavings\sof\nbeing\sable\sto\suse\sthe\sindex\sto\sevaluate\ssome\sWHERE\sclause\sterms\swithout\nhaving\sto\sdo\sa\stable\slookup. -D 2016-07-27T18:27:02.556 +C Add\stest\scases\sand\sfix\sa\scomment. +D 2016-07-27T19:20:58.611 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -337,7 +337,7 @@ F src/ctime.c 61949e83c4c36e37195a8398ebc752780b534d95 F src/date.c 1cc9fb516ec9932c6fd4d2a0d2f8bc4480145c39 F src/dbstat.c 4f6f7f52b49beb9636ffbd517cfe44a402ba4ad0 F src/delete.c 4aba4214a377ce8ddde2d2e609777bcc8235200f -F src/expr.c 3347e66d4e27ec5f3ec7573b9a5f899bbd7d1df8 +F src/expr.c fbc17c717a80b5b61158ea8f25b5af6f8cad66f8 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c bc4145347595b7770f9a598cff1c848302cf5413 F src/func.c 61a4114cf7004f10c542cfabbab9f2bcb9033045 @@ -463,7 +463,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 02eeecc265f6ffd0597378f5d8ae9070b62a406a F src/wal.h 6dd221ed384afdc204bc61e25c23ef7fd5a511f2 F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354 -F src/where.c 7e4d676b5ac4434e5f93606a744d396dc40d9977 +F src/where.c 66a290310e71491ffc9c74108413176438aa8718 F src/whereInt.h e5b939701a7ceffc5a3a8188a37f9746416ebcd0 F src/wherecode.c 99707d11907c71d289ee9553d2d1a22f1fd8ba41 F src/whereexpr.c d7dcbf14ce1b5876c1f76496162c30fcba669563 @@ -845,6 +845,7 @@ F test/index4.test ab92e736d5946840236cd61ac3191f91a7856bf6 F test/index5.test 8621491915800ec274609e42e02a97d67e9b13e7 F test/index6.test 43b4e29258b978fcdab84fc61df4f5212119dd09 F test/index7.test 9c6765a74fc3fcde7aebc5b3bd40d98df14a527c +F test/index8.test bc2e3db70e8e62459aaa1bd7e4a9b39664f8f9d7 F test/indexedby.test 9c4cd331224e57f79fbf411ae245e6272d415985 F test/indexexpr1.test cb71b6586177b840e28110dd952178bb2bdfedc2 F test/indexfault.test 31d4ab9a7d2f6e9616933eb079722362a883eb1d @@ -1026,7 +1027,7 @@ F test/savepoint5.test 0735db177e0ebbaedc39812c8d065075d563c4fd F test/savepoint6.test f41279c5e137139fa5c21485773332c7adb98cd7 F test/savepoint7.test cde525ea3075283eb950cdcdefe23ead4f700daa F test/savepointfault.test f044eac64b59f09746c7020ee261734de82bf9b2 -F test/scanstatus.test 5253c219e331318a437f436268e0e82345700285 +F test/scanstatus.test 030acbbdcea6a3fc676fee99edc84f6f16c0cf92 F test/schema.test 8f7999be894260f151adf15c2c7540f1c6d6a481 F test/schema2.test 906408621ea881fdb496d878b1822572a34e32c5 F test/schema3.test 1bc1008e1f8cb5654b248c55f27249366eb7ed38 @@ -1507,10 +1508,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 483994a54dee3c7a3801e0e9d3c96fa9dbd8d2fd -R 9e4bd013f5c2cf2171d472668aed0d1c -T *branch * improved-index-scan -T *sym-improved-index-scan * -T -sym-trunk * +P a59b5622f7cc6e502d71aabc12c053582cd03609 +R f515f9eadedb75a99af064851213e82e U drh -Z 8f3398744130761f466da0e8b7212fe4 +Z 99f5c72d7c6c2cd0c635c52258200786 diff --git a/manifest.uuid b/manifest.uuid index 6da37e4d78..213abdc7d3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a59b5622f7cc6e502d71aabc12c053582cd03609 \ No newline at end of file +50f8ea37fb9647c4a9da2c269a4d6f54b10ce96b \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index c027cf02a4..c6d74cfd32 100644 --- a/src/expr.c +++ b/src/expr.c @@ -3994,10 +3994,10 @@ static int exprIdxCover(Walker *pWalker, Expr *pExpr){ } /* -** Determine if an index on table iCur that contains the columns in -** Bitmask m will cover the expression pExpr. Return true if the index -** does cover the expression and false if the expression references -** table columns that are not found in the index. +** Determine if an index pIdx on table with cursor iCur contains will +** the expression pExpr. Return true if the index does cover the +** expression and false if the pExpr expression references table columns +** that are not found in the index pIdx. ** ** An index covering an expression means that the expression can be ** evaluated using only the index and without having to lookup the diff --git a/src/where.c b/src/where.c index 6a02574921..699dc2a614 100644 --- a/src/where.c +++ b/src/where.c @@ -2478,11 +2478,11 @@ static int whereLoopAddBtreeIndex( pNew->nSkip++; pNew->aLTerm[pNew->nLTerm++] = 0; pNew->wsFlags |= WHERE_SKIPSCAN; - nIter = pProbe->aiRowLogEst[saved_nEq] - pProbe->aiRowLogEst[saved_nEq+1]; + nIter = pProbe->aiRowLogEst[saved_nEq]+1 - pProbe->aiRowLogEst[saved_nEq+1]; pNew->nOut -= nIter; /* TUNING: Because uncertainties in the estimates for skip-scan queries, ** add a 1.375 fudge factor to make skip-scan slightly less likely. */ - nIter += 5; + nIter += 4; whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nIter + nInMul); pNew->nOut = saved_nOut; pNew->u.btree.nEq = saved_nEq; diff --git a/test/index8.test b/test/index8.test new file mode 100644 index 0000000000..bb58228527 --- /dev/null +++ b/test/index8.test @@ -0,0 +1,60 @@ +# 2016-07-27 +# +# 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. +# +#*********************************************************************** +# +# Test cases for ORDER BY and LIMIT on an index scan. +# + + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +# Performance regression reported at +# http://www.mail-archive.com/sqlite-users@mailinglists.sqlite.org/msg98615.html +# +# Caused by the ORDER BY LIMIT optionation for check-in +# https://sqlite.org/src/info/bf46179d44843769 +# +# Fixed on approximately 2016-07-27 by changes that compute a better score +# for index scans by taking into account WHERE clause constraints that can +# be handled by the index and do not require a table lookup. +# +do_execsql_test 1.0 { + CREATE TABLE t1(a,b,c,d); + WITH RECURSIVE c(x) AS (VALUES(0) UNION ALL SELECT x+1 FROM c WHERE x<100) + INSERT INTO t1(a,b,c,d) + SELECT x/10, x%10, x%19, x FROM c; + CREATE INDEX t1abc ON t1(a,b,c); + SELECT * FROM t1 WHERE c=4 ORDER BY a, b LIMIT 2; +} {0 4 4 4 2 3 4 23} + +# Prior to the fix, the following EQP would show a table scan and a sort +# rather than an index scan. +# +do_execsql_test 1.0eqp { + EXPLAIN QUERY PLAN + SELECT * FROM t1 WHERE c=4 ORDER BY a, b LIMIT 2; +} {/SCAN TABLE t1 USING INDEX t1abc/} + +# If we change the index so that it no longer covers the WHERE clause, +# then we should (correctly) revert to using a table scan. +# +do_execsql_test 1.1 { + DROP INDEX t1abc; + CREATE INDEX t1abd ON t1(a,b,d); + SELECT * FROM t1 WHERE c=4 ORDER BY a, b LIMIT 2; +} {0 4 4 4 2 3 4 23} +do_execsql_test 1.1eqp { + EXPLAIN QUERY PLAN + SELECT * FROM t1 WHERE c=4 ORDER BY a, b LIMIT 2; +} {~/USING INDEX/} + + +finish_test diff --git a/test/scanstatus.test b/test/scanstatus.test index ed24d97437..48365a8794 100644 --- a/test/scanstatus.test +++ b/test/scanstatus.test @@ -333,7 +333,7 @@ do_execsql_test 5.3.2 { SELECT count(*) FROM t2 WHERE y = 'j'; } {19} do_scanstatus_test 5.3.3 { - nLoop 1 nVisit 19 nEst 56.0 zName t2xy zExplain + nLoop 1 nVisit 19 nEst 52.0 zName t2xy zExplain {SEARCH TABLE t2 USING COVERING INDEX t2xy (ANY(x) AND y=?)} } @@ -349,7 +349,7 @@ do_execsql_test 5.4.2 { do_scanstatus_test 5.4.3 { nLoop 1 nVisit 10 nEst 10.0 zName t1bc zExplain {SCAN TABLE t1 USING COVERING INDEX t1bc} - nLoop 10 nVisit 200 nEst 56.0 zName t2xy + nLoop 10 nVisit 200 nEst 52.0 zName t2xy zExplain {SEARCH TABLE t2 USING COVERING INDEX t2xy (ANY(x) AND y=?)} } From 69def7ff2f872b3c7579d93843ba504e61dc2b2f Mon Sep 17 00:00:00 2001 From: mistachkin Date: Thu, 28 Jul 2016 04:14:37 +0000 Subject: [PATCH 0611/1484] Work in progress on setting a calling convention for all callback functions. FossilOrigin-Name: 02b8040e1add02734d2dbc6c59737ab74ff8fb18 --- Makefile.msc | 13 +- autoconf/Makefile.msc | 8 +- ext/misc/percentile.c | 2 +- ext/misc/spellfix.c | 2 +- manifest | 36 ++-- manifest.uuid | 2 +- src/sqlite.h.in | 339 +++++++++++++++++++++----------------- src/tclsqlite.c | 2 +- src/test1.c | 2 +- tool/mksqlite3c-noext.tcl | 2 +- tool/mksqlite3c.tcl | 2 +- tool/mksqlite3h.tcl | 2 +- 12 files changed, 230 insertions(+), 182 deletions(-) diff --git a/Makefile.msc b/Makefile.msc index cd866ce4a4..7220f71cd4 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -464,20 +464,24 @@ RCC = $(RC) -DSQLITE_OS_WIN=1 -I. -I$(TOP) -I$(TOP)\src $(RCOPTS) $(RCCOPTS) # !IF $(USE_STDCALL)!=0 || $(FOR_WIN10)!=0 !IF "$(PLATFORM)"=="x86" -CORE_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_STDCALL=__stdcall -SHELL_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_STDCALL=__stdcall +CORE_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall +SHELL_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall +TEST_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall !ELSE !IFNDEF PLATFORM -CORE_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_STDCALL=__stdcall -SHELL_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_STDCALL=__stdcall +CORE_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall +SHELL_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall +TEST_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall !ELSE CORE_CCONV_OPTS = SHELL_CCONV_OPTS = +TEST_CCONV_OPTS = !ENDIF !ENDIF !ELSE CORE_CCONV_OPTS = SHELL_CCONV_OPTS = +TEST_CCONV_OPTS = !ENDIF # These are additional compiler options used for the core library. @@ -1960,6 +1964,7 @@ TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_SERVER=1 -DSQLITE_PRIVATE="" TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_CORE $(NO_WARN) TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_SERIES_CONSTRAINT_VERIFY=1 TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_DEFAULT_PAGE_SIZE=1024 +TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) $(TEST_CCONV_OPTS) TESTFIXTURE_SRC0 = $(TESTEXT) $(TESTSRC2) TESTFIXTURE_SRC1 = $(TESTEXT) $(SQLITE3C) diff --git a/autoconf/Makefile.msc b/autoconf/Makefile.msc index 7f62bcb129..2f7447383f 100644 --- a/autoconf/Makefile.msc +++ b/autoconf/Makefile.msc @@ -449,12 +449,12 @@ RCC = $(RC) -DSQLITE_OS_WIN=1 -I. -I$(TOP) $(RCOPTS) $(RCCOPTS) # !IF $(USE_STDCALL)!=0 || $(FOR_WIN10)!=0 !IF "$(PLATFORM)"=="x86" -CORE_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_STDCALL=__stdcall -SHELL_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_STDCALL=__stdcall +CORE_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall +SHELL_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall !ELSE !IFNDEF PLATFORM -CORE_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_STDCALL=__stdcall -SHELL_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_STDCALL=__stdcall +CORE_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall +SHELL_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall !ELSE CORE_CCONV_OPTS = SHELL_CCONV_OPTS = diff --git a/ext/misc/percentile.c b/ext/misc/percentile.c index 74a4c9d12b..a5d7e84913 100644 --- a/ext/misc/percentile.c +++ b/ext/misc/percentile.c @@ -167,7 +167,7 @@ static void percentStep(sqlite3_context *pCtx, int argc, sqlite3_value **argv){ /* ** Compare to doubles for sorting using qsort() */ -static int doubleCmp(const void *pA, const void *pB){ +static int SQLITE_CDECL doubleCmp(const void *pA, const void *pB){ double a = *(double*)pA; double b = *(double*)pB; if( a==b ) return 0; diff --git a/ext/misc/spellfix.c b/ext/misc/spellfix.c index cbcf8b7c5d..1ac1712f4e 100644 --- a/ext/misc/spellfix.c +++ b/ext/misc/spellfix.c @@ -2231,7 +2231,7 @@ static int spellfix1Score(int iDistance, int iRank){ ** Compare two spellfix1_row objects for sorting purposes in qsort() such ** that they sort in order of increasing distance. */ -static int spellfix1RowCompare(const void *A, const void *B){ +static int SQLITE_CDECL spellfix1RowCompare(const void *A, const void *B){ const struct spellfix1_row *a = (const struct spellfix1_row*)A; const struct spellfix1_row *b = (const struct spellfix1_row*)B; return a->iScore - b->iScore; diff --git a/manifest b/manifest index d0e7b14e54..a174c165d9 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -C Enhance\sthe\squery\splanner\scost\sestimation\sfor\sindex\sscans\sto\stake\sinto\saccount\nWHERE\sclause\sterms\sthat\scan\sbe\scomputed\susing\sonly\sthe\sindex\sand\sthat\sdo\snot\nrequire\slooking\sup\srows\sin\sthe\soriginal\stable.\s\sThis\sfixes\san\sobscure\nperformance\sregression\sthat\sarose\swhen\sthe\sORDER\sBY\sLIMIT\soptimization\swas\nadded\sby\scheck-in\s[bf46179d44843]. -D 2016-07-27T19:30:53.586 +C Work\sin\sprogress\son\ssetting\sa\scalling\sconvention\sfor\sall\scallback\sfunctions. +D 2016-07-28T04:14:37.455 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 -F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a +F Makefile.msc 843c563182b26a358674c520d7b8d40b832e9436 F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7 F VERSION cb29eb11e493dd85b3eeec4053c03949bf98478e F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 @@ -11,7 +11,7 @@ F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am 1a47d071e3d5435f8f7ebff7eb6703848bbd65d4 -F autoconf/Makefile.msc 0eca137c12542bd76c253a2d24380f29ade59b95 +F autoconf/Makefile.msc 05a99e98a8895461574ccb9604444d9e97c1f0b6 F autoconf/README.first 6c4f34fe115ff55d4e8dbfa3cecf04a0188292f7 F autoconf/README.txt 4f04b0819303aabaa35fff5f7b257fb0c1ef95f1 F autoconf/configure.ac cacf2616abf6e4a569bde2ef365c143caeec40bc @@ -214,13 +214,13 @@ F ext/misc/fuzzer.c 7c64b8197bb77b7d64eff7cac7848870235d4c25 F ext/misc/ieee754.c f190d0cc5182529acb15babd177781be1ac1718c F ext/misc/json1.c d51a764ba43a49e191bc3536238bfab3def258ca F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342 -F ext/misc/percentile.c bcbee3c061b884eccb80e21651daaae8e1e43c63 +F ext/misc/percentile.c 92699c8cd7d517ff610e6037e56506f8904dae2e F ext/misc/regexp.c a68d25c659bd2d893cd1215667bbf75ecb9dc7d4 F ext/misc/rot13.c 1ac6f95f99b575907b9b09c81a349114cf9be45a F ext/misc/scrub.c 1c5bfb8b0cd18b602fcb55755e84abf0023ac2fb F ext/misc/series.c e11e534ada797d5b816d7e7a93c022306563ca35 F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52 -F ext/misc/spellfix.c bf1b922c2750698e9a3d4c50cce6974adb7e93be +F ext/misc/spellfix.c a4723b6aff748a417b5091b68a46443265c40f0d F ext/misc/totype.c 4a167594e791abeed95e0a8db028822b5e8fe512 F ext/misc/vfslog.c fe40fab5c077a40477f7e5eba994309ecac6cc95 F ext/misc/vfsstat.c 6110aeeaab2f1df17a923c8a8acef3c74f6dc515 @@ -385,15 +385,15 @@ F src/resolve.c cca3aa77b95706df5d635a2141a4d1de60ae6598 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c f3c6e9065fb34f6a23af27ec7f1f717ffbfc2ee4 F src/shell.c 9351fc6de11e1d908648c0a92d85627138e3dee5 -F src/sqlite.h.in c6e68a4a47610631822a4f8f83a44c9f75339331 +F src/sqlite.h.in a0760a3f7b1939e395a3e74d245e5bb03cd54fb1 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 46f300b6e300e0fa916d7d58c44b53415b8471a9 F src/sqliteInt.h d25c18c1272a7811e2569c39bfc2fca96156eead F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c 5b18f9526900f61189ab0b83f1ef41d9f871a2ab F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 -F src/tclsqlite.c 5c213bf5fee084390f632df2328cf0821d483799 -F src/test1.c 186e3b53c402b7a73bcb4ade2b77709675c39fe3 +F src/tclsqlite.c 53274d5bbd66e7246c573a6b48026781d42c7efe +F src/test1.c 5ec959d088af063cac44cf1685455f3fcddecc8c F src/test2.c 5586f43fcd9a1be0830793cf9d354082c261b25b F src/test3.c c75c8af0eadb335236c9e61b51044c58a8f7dd59 F src/test4.c d168f83cc78d02e8d35567bb5630e40dcd85ac1e @@ -1448,9 +1448,9 @@ F tool/mkopcodeh.tcl a01d2c1d8a6205b03fc635adf3735b4c523befd3 F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e F tool/mkpragmatab.tcl f0d5bb266d1d388cf86fce5ba01a891e95d72d41 F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 -F tool/mksqlite3c-noext.tcl 87240b09c20042999b41d5fabe091b7111287835 -F tool/mksqlite3c.tcl 63af8429841f08552e6da1d93b3dee4a93ff8071 -F tool/mksqlite3h.tcl e7b106fc4f29fbc258e8ba9b88d9108332ea2ade +F tool/mksqlite3c-noext.tcl aa58ea3be311c81821c2cd3209f55e46b07ab656 +F tool/mksqlite3c.tcl a52ead27e2ac5d4b616e945a0601f628f4328329 +F tool/mksqlite3h.tcl fab97967314e63384a3ed23fd35f0d8188352400 F tool/mksqlite3internalh.tcl eb994013e833359137eb53a55acdad0b5ae1049b F tool/mkvsix.tcl 4abcaf3267171b2faadaf9b82a0dfbaa6e98f8b7 F tool/offsets.c fe4262fdfa378e8f5499a42136d17bf3b98f6091 @@ -1508,8 +1508,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 4d59df02d3713b3e3804e1a88e676749b2794286 50f8ea37fb9647c4a9da2c269a4d6f54b10ce96b -R a589b595bdfe9868de18def836f199ce -T +closed 50f8ea37fb9647c4a9da2c269a4d6f54b10ce96b -U drh -Z 994e8dc5cbb7e25d0e8cc4a952504fbd +P 9e2b26811452a5011d0a97a689636fa4409da856 +R 6c56defa4f9211ce028bec2ac1e13231 +T *branch * callbackConv +T *sym-callbackConv * +T -sym-trunk * +U mistachkin +Z d50c4a0ba4b8e38dec3c91619f068656 diff --git a/manifest.uuid b/manifest.uuid index 9b63447ecc..57781e18c1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9e2b26811452a5011d0a97a689636fa4409da856 \ No newline at end of file +02b8040e1add02734d2dbc6c59737ab74ff8fb18 \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index e8f5d24845..009f080a86 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -54,9 +54,19 @@ extern "C" { #ifndef SQLITE_CDECL # define SQLITE_CDECL #endif -#ifndef SQLITE_STDCALL -# define SQLITE_STDCALL +#ifndef SQLITE_APICALL +# define SQLITE_APICALL #endif +#ifndef SQLITE_STDCALL +# define SQLITE_STDCALL SQLITE_APICALL +#endif +#ifndef SQLITE_CALLBACK +# define SQLITE_CALLBACK +#endif +#ifndef SQLITE_SYSAPI +# define SQLITE_SYSAPI +#endif + /* ** These no-op macros are used in front of interfaces to mark those @@ -318,7 +328,7 @@ int sqlite3_close_v2(sqlite3*); ** This is legacy and deprecated. It is included for historical ** compatibility and is not documented. */ -typedef int (*sqlite3_callback)(void*,int,char**, char**); +typedef int (SQLITE_CALLBACK *sqlite3_callback)(void*,int,char**, char**); /* ** CAPI3REF: One-Step Query Execution Interface @@ -385,7 +395,7 @@ typedef int (*sqlite3_callback)(void*,int,char**, char**); int sqlite3_exec( sqlite3*, /* An open database */ const char *sql, /* SQL to be evaluated */ - int (*callback)(void*,int,char**,char**), /* Callback function */ + int (SQLITE_CALLBACK *callback)(void*,int,char**,char**), /* Callback func */ void *, /* 1st argument to callback */ char **errmsg /* Error msg written here */ ); @@ -733,26 +743,30 @@ struct sqlite3_file { typedef struct sqlite3_io_methods sqlite3_io_methods; struct sqlite3_io_methods { int iVersion; - int (*xClose)(sqlite3_file*); - int (*xRead)(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst); - int (*xWrite)(sqlite3_file*, const void*, int iAmt, sqlite3_int64 iOfst); - int (*xTruncate)(sqlite3_file*, sqlite3_int64 size); - int (*xSync)(sqlite3_file*, int flags); - int (*xFileSize)(sqlite3_file*, sqlite3_int64 *pSize); - int (*xLock)(sqlite3_file*, int); - int (*xUnlock)(sqlite3_file*, int); - int (*xCheckReservedLock)(sqlite3_file*, int *pResOut); - int (*xFileControl)(sqlite3_file*, int op, void *pArg); - int (*xSectorSize)(sqlite3_file*); - int (*xDeviceCharacteristics)(sqlite3_file*); + int (SQLITE_CALLBACK *xClose)(sqlite3_file*); + int (SQLITE_CALLBACK *xRead)(sqlite3_file*, void*, int iAmt, + sqlite3_int64 iOfst); + int (SQLITE_CALLBACK *xWrite)(sqlite3_file*, const void*, int iAmt, + sqlite3_int64 iOfst); + int (SQLITE_CALLBACK *xTruncate)(sqlite3_file*, sqlite3_int64 size); + int (SQLITE_CALLBACK *xSync)(sqlite3_file*, int flags); + int (SQLITE_CALLBACK *xFileSize)(sqlite3_file*, sqlite3_int64 *pSize); + int (SQLITE_CALLBACK *xLock)(sqlite3_file*, int); + int (SQLITE_CALLBACK *xUnlock)(sqlite3_file*, int); + int (SQLITE_CALLBACK *xCheckReservedLock)(sqlite3_file*, int *pResOut); + int (SQLITE_CALLBACK *xFileControl)(sqlite3_file*, int op, void *pArg); + int (SQLITE_CALLBACK *xSectorSize)(sqlite3_file*); + int (SQLITE_CALLBACK *xDeviceCharacteristics)(sqlite3_file*); /* Methods above are valid for version 1 */ - int (*xShmMap)(sqlite3_file*, int iPg, int pgsz, int, void volatile**); - int (*xShmLock)(sqlite3_file*, int offset, int n, int flags); - void (*xShmBarrier)(sqlite3_file*); - int (*xShmUnmap)(sqlite3_file*, int deleteFlag); + int (SQLITE_CALLBACK *xShmMap)(sqlite3_file*, int iPg, int pgsz, int, + void volatile**); + int (SQLITE_CALLBACK *xShmLock)(sqlite3_file*, int offset, int n, int flags); + void (SQLITE_CALLBACK *xShmBarrier)(sqlite3_file*); + int (SQLITE_CALLBACK *xShmUnmap)(sqlite3_file*, int deleteFlag); /* Methods above are valid for version 2 */ - int (*xFetch)(sqlite3_file*, sqlite3_int64 iOfst, int iAmt, void **pp); - int (*xUnfetch)(sqlite3_file*, sqlite3_int64 iOfst, void *p); + int (SQLITE_CALLBACK *xFetch)(sqlite3_file*, sqlite3_int64 iOfst, int iAmt, + void **pp); + int (SQLITE_CALLBACK *xUnfetch)(sqlite3_file*, sqlite3_int64 iOfst, void *p); /* Methods above are valid for version 3 */ /* Additional methods may be added in future releases */ }; @@ -1194,7 +1208,7 @@ typedef struct sqlite3_mutex sqlite3_mutex; ** any of these methods if the iVersion of the VFS is less than 3. */ typedef struct sqlite3_vfs sqlite3_vfs; -typedef void (*sqlite3_syscall_ptr)(void); +typedef void (SQLITE_SYSAPI *sqlite3_syscall_ptr)(void); struct sqlite3_vfs { int iVersion; /* Structure version number (currently 3) */ int szOsFile; /* Size of subclassed sqlite3_file */ @@ -1202,31 +1216,37 @@ struct sqlite3_vfs { sqlite3_vfs *pNext; /* Next registered VFS */ const char *zName; /* Name of this virtual file system */ void *pAppData; /* Pointer to application-specific data */ - int (*xOpen)(sqlite3_vfs*, const char *zName, sqlite3_file*, + int (SQLITE_CALLBACK *xOpen)(sqlite3_vfs*, const char *zName, sqlite3_file*, int flags, int *pOutFlags); - int (*xDelete)(sqlite3_vfs*, const char *zName, int syncDir); - int (*xAccess)(sqlite3_vfs*, const char *zName, int flags, int *pResOut); - int (*xFullPathname)(sqlite3_vfs*, const char *zName, int nOut, char *zOut); - void *(*xDlOpen)(sqlite3_vfs*, const char *zFilename); - void (*xDlError)(sqlite3_vfs*, int nByte, char *zErrMsg); - void (*(*xDlSym)(sqlite3_vfs*,void*, const char *zSymbol))(void); - void (*xDlClose)(sqlite3_vfs*, void*); - int (*xRandomness)(sqlite3_vfs*, int nByte, char *zOut); - int (*xSleep)(sqlite3_vfs*, int microseconds); - int (*xCurrentTime)(sqlite3_vfs*, double*); - int (*xGetLastError)(sqlite3_vfs*, int, char *); + int (SQLITE_CALLBACK *xDelete)(sqlite3_vfs*, const char *zName, int syncDir); + int (SQLITE_CALLBACK *xAccess)(sqlite3_vfs*, const char *zName, int flags, + int *pResOut); + int (SQLITE_CALLBACK *xFullPathname)(sqlite3_vfs*, const char *zName, + int nOut, char *zOut); + void *(SQLITE_CALLBACK *xDlOpen)(sqlite3_vfs*, const char *zFilename); + void (SQLITE_CALLBACK *xDlError)(sqlite3_vfs*, int nByte, char *zErrMsg); + void (*(SQLITE_CALLBACK *xDlSym)(sqlite3_vfs*,void*, + const char *zSymbol))(void); + void (SQLITE_CALLBACK *xDlClose)(sqlite3_vfs*, void*); + int (SQLITE_CALLBACK *xRandomness)(sqlite3_vfs*, int nByte, char *zOut); + int (SQLITE_CALLBACK *xSleep)(sqlite3_vfs*, int microseconds); + int (SQLITE_CALLBACK *xCurrentTime)(sqlite3_vfs*, double*); + int (SQLITE_CALLBACK *xGetLastError)(sqlite3_vfs*, int, char *); /* ** The methods above are in version 1 of the sqlite_vfs object ** definition. Those that follow are added in version 2 or later */ - int (*xCurrentTimeInt64)(sqlite3_vfs*, sqlite3_int64*); + int (SQLITE_CALLBACK *xCurrentTimeInt64)(sqlite3_vfs*, sqlite3_int64*); /* ** The methods above are in versions 1 and 2 of the sqlite_vfs object. ** Those below are for version 3 and greater. */ - int (*xSetSystemCall)(sqlite3_vfs*, const char *zName, sqlite3_syscall_ptr); - sqlite3_syscall_ptr (*xGetSystemCall)(sqlite3_vfs*, const char *zName); - const char *(*xNextSystemCall)(sqlite3_vfs*, const char *zName); + int (SQLITE_CALLBACK *xSetSystemCall)(sqlite3_vfs*, const char *zName, + sqlite3_syscall_ptr); + sqlite3_syscall_ptr (SQLITE_CALLBACK *xGetSystemCall)(sqlite3_vfs*, + const char *zName); + const char *(SQLITE_CALLBACK *xNextSystemCall)(sqlite3_vfs*, + const char *zName); /* ** The methods above are in versions 1 through 3 of the sqlite_vfs object. ** New fields may be appended in future versions. The iVersion @@ -1493,13 +1513,13 @@ int sqlite3_db_config(sqlite3*, int op, ...); */ typedef struct sqlite3_mem_methods sqlite3_mem_methods; struct sqlite3_mem_methods { - void *(*xMalloc)(int); /* Memory allocation function */ - void (*xFree)(void*); /* Free a prior allocation */ - void *(*xRealloc)(void*,int); /* Resize an allocation */ - int (*xSize)(void*); /* Return the size of an allocation */ - int (*xRoundup)(int); /* Round up request size to allocation size */ - int (*xInit)(void*); /* Initialize the memory allocator */ - void (*xShutdown)(void*); /* Deinitialize the memory allocator */ + void *(SQLITE_CALLBACK *xMalloc)(int); /* Memory allocation function */ + void (SQLITE_CALLBACK *xFree)(void*); /* Free a prior allocation */ + void *(SQLITE_CALLBACK *xRealloc)(void*,int); /* Resize an allocation */ + int (SQLITE_CALLBACK *xSize)(void*); /* Return the size of an allocation */ + int (SQLITE_CALLBACK *xRoundup)(int); /* Round up size to allocation size */ + int (SQLITE_CALLBACK *xInit)(void*); /* Initialize the memory allocator */ + void (SQLITE_CALLBACK *xShutdown)(void*); /* Deinitialize memory allocator */ void *pAppData; /* Argument to xInit() and xShutdown() */ }; @@ -2233,7 +2253,7 @@ int sqlite3_complete16(const void *sql); ** A busy handler must not close the database connection ** or [prepared statement] that invoked the busy handler. */ -int sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*); +int sqlite3_busy_handler(sqlite3*, int(SQLITE_CALLBACK *)(void*,int), void*); /* ** CAPI3REF: Set A Busy Timeout @@ -2677,7 +2697,8 @@ void sqlite3_randomness(int N, void *P); */ int sqlite3_set_authorizer( sqlite3*, - int (*xAuth)(void*,int,const char*,const char*,const char*,const char*), + int (SQLITE_CALLBACK *xAuth)(void*,int,const char*,const char*,const char*, + const char*), void *pUserData ); @@ -2784,9 +2805,9 @@ int sqlite3_set_authorizer( ** subject to change in future versions of SQLite. */ SQLITE_DEPRECATED void *sqlite3_trace(sqlite3*, - void(*xTrace)(void*,const char*), void*); + void(SQLITE_CALLBACK *xTrace)(void*,const char*), void*); SQLITE_DEPRECATED void *sqlite3_profile(sqlite3*, - void(*xProfile)(void*,const char*,sqlite3_uint64), void*); + void(SQLITE_CALLBACK *xProfile)(void*,const char*,sqlite3_uint64), void*); /* ** CAPI3REF: SQL Trace Event Codes @@ -2877,7 +2898,7 @@ SQLITE_DEPRECATED void *sqlite3_profile(sqlite3*, int sqlite3_trace_v2( sqlite3*, unsigned uMask, - int(*xCallback)(unsigned,void*,void*,void*), + int(SQLITE_CALLBACK *xCallback)(unsigned,void*,void*,void*), void *pCtx ); @@ -2913,7 +2934,7 @@ int sqlite3_trace_v2( ** database connections for the meaning of "modify" in this paragraph. ** */ -void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); +void sqlite3_progress_handler(sqlite3*,int,int(SQLITE_CALLBACK *)(void*),void*); /* ** CAPI3REF: Opening A New Database Connection @@ -3744,17 +3765,20 @@ typedef struct sqlite3_context sqlite3_context; ** See also: [sqlite3_bind_parameter_count()], ** [sqlite3_bind_parameter_name()], and [sqlite3_bind_parameter_index()]. */ -int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*)); +int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, + void(SQLITE_CALLBACK *)(void*)); int sqlite3_bind_blob64(sqlite3_stmt*, int, const void*, sqlite3_uint64, - void(*)(void*)); + void(SQLITE_CALLBACK *)(void*)); int sqlite3_bind_double(sqlite3_stmt*, int, double); int sqlite3_bind_int(sqlite3_stmt*, int, int); int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64); int sqlite3_bind_null(sqlite3_stmt*, int); -int sqlite3_bind_text(sqlite3_stmt*,int,const char*,int,void(*)(void*)); -int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*)); +int sqlite3_bind_text(sqlite3_stmt*,int,const char*,int, + void(SQLITE_CALLBACK *)(void*)); +int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, + void(SQLITE_CALLBACK *)(void*)); int sqlite3_bind_text64(sqlite3_stmt*, int, const char*, sqlite3_uint64, - void(*)(void*), unsigned char encoding); + void(SQLITE_CALLBACK *)(void*), unsigned char encoding); int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*); int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n); int sqlite3_bind_zeroblob64(sqlite3_stmt*, int, sqlite3_uint64); @@ -4422,9 +4446,9 @@ int sqlite3_create_function( int nArg, int eTextRep, void *pApp, - void (*xFunc)(sqlite3_context*,int,sqlite3_value**), - void (*xStep)(sqlite3_context*,int,sqlite3_value**), - void (*xFinal)(sqlite3_context*) + void (SQLITE_CALLBACK *xFunc)(sqlite3_context*,int,sqlite3_value**), + void (SQLITE_CALLBACK *xStep)(sqlite3_context*,int,sqlite3_value**), + void (SQLITE_CALLBACK *xFinal)(sqlite3_context*) ); int sqlite3_create_function16( sqlite3 *db, @@ -4432,9 +4456,9 @@ int sqlite3_create_function16( int nArg, int eTextRep, void *pApp, - void (*xFunc)(sqlite3_context*,int,sqlite3_value**), - void (*xStep)(sqlite3_context*,int,sqlite3_value**), - void (*xFinal)(sqlite3_context*) + void (SQLITE_CALLBACK *xFunc)(sqlite3_context*,int,sqlite3_value**), + void (SQLITE_CALLBACK *xStep)(sqlite3_context*,int,sqlite3_value**), + void (SQLITE_CALLBACK *xFinal)(sqlite3_context*) ); int sqlite3_create_function_v2( sqlite3 *db, @@ -4442,10 +4466,10 @@ int sqlite3_create_function_v2( int nArg, int eTextRep, void *pApp, - void (*xFunc)(sqlite3_context*,int,sqlite3_value**), - void (*xStep)(sqlite3_context*,int,sqlite3_value**), - void (*xFinal)(sqlite3_context*), - void(*xDestroy)(void*) + void (SQLITE_CALLBACK *xFunc)(sqlite3_context*,int,sqlite3_value**), + void (SQLITE_CALLBACK *xStep)(sqlite3_context*,int,sqlite3_value**), + void (SQLITE_CALLBACK *xFinal)(sqlite3_context*), + void (SQLITE_CALLBACK *xDestroy)(void*) ); /* @@ -4487,8 +4511,9 @@ SQLITE_DEPRECATED int sqlite3_expired(sqlite3_stmt*); SQLITE_DEPRECATED int sqlite3_transfer_bindings(sqlite3_stmt*, sqlite3_stmt*); SQLITE_DEPRECATED int sqlite3_global_recover(void); SQLITE_DEPRECATED void sqlite3_thread_cleanup(void); -SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int), - void*,sqlite3_int64); +SQLITE_DEPRECATED int sqlite3_memory_alarm( + void(SQLITE_CALLBACK *)(void*,sqlite3_int64,int), + void*,sqlite3_int64); #endif /* @@ -4707,7 +4732,8 @@ sqlite3 *sqlite3_context_db_handle(sqlite3_context*); ** the SQL function is running. */ void *sqlite3_get_auxdata(sqlite3_context*, int N); -void sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(void*)); +void sqlite3_set_auxdata(sqlite3_context*, int N, void*, + void (SQLITE_CALLBACK *)(void*)); /* @@ -4724,7 +4750,7 @@ void sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(void*)); ** The typedef is necessary to work around problems in certain ** C++ compilers. */ -typedef void (*sqlite3_destructor_type)(void*); +typedef void (SQLITE_CALLBACK *sqlite3_destructor_type)(void*); #define SQLITE_STATIC ((sqlite3_destructor_type)0) #define SQLITE_TRANSIENT ((sqlite3_destructor_type)-1) @@ -4843,9 +4869,10 @@ typedef void (*sqlite3_destructor_type)(void*); ** than the one containing the application-defined function that received ** the [sqlite3_context] pointer, the results are undefined. */ -void sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*)); +void sqlite3_result_blob(sqlite3_context*, const void*, int, + void(SQLITE_CALLBACK *)(void*)); void sqlite3_result_blob64(sqlite3_context*,const void*, - sqlite3_uint64,void(*)(void*)); + sqlite3_uint64,void(SQLITE_CALLBACK *)(void*)); void sqlite3_result_double(sqlite3_context*, double); void sqlite3_result_error(sqlite3_context*, const char*, int); void sqlite3_result_error16(sqlite3_context*, const void*, int); @@ -4855,12 +4882,17 @@ void sqlite3_result_error_code(sqlite3_context*, int); void sqlite3_result_int(sqlite3_context*, int); void sqlite3_result_int64(sqlite3_context*, sqlite3_int64); void sqlite3_result_null(sqlite3_context*); -void sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*)); +void sqlite3_result_text(sqlite3_context*, const char*, int, + void(SQLITE_CALLBACK *)(void*)); void sqlite3_result_text64(sqlite3_context*, const char*,sqlite3_uint64, - void(*)(void*), unsigned char encoding); -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(SQLITE_CALLBACK *)(void*), + unsigned char encoding); +void sqlite3_result_text16(sqlite3_context*, const void*, int, + void(SQLITE_CALLBACK *)(void*)); +void sqlite3_result_text16le(sqlite3_context*, const void*, int, + void(SQLITE_CALLBACK *)(void*)); +void sqlite3_result_text16be(sqlite3_context*, const void*, int, + void(SQLITE_CALLBACK *)(void*)); void sqlite3_result_value(sqlite3_context*, sqlite3_value*); void sqlite3_result_zeroblob(sqlite3_context*, int n); int sqlite3_result_zeroblob64(sqlite3_context*, sqlite3_uint64 n); @@ -4965,22 +4997,22 @@ int sqlite3_create_collation( const char *zName, int eTextRep, void *pArg, - int(*xCompare)(void*,int,const void*,int,const void*) + int(SQLITE_CALLBACK *xCompare)(void*,int,const void*,int,const void*) ); int sqlite3_create_collation_v2( sqlite3*, const char *zName, int eTextRep, void *pArg, - int(*xCompare)(void*,int,const void*,int,const void*), - void(*xDestroy)(void*) + int(SQLITE_CALLBACK *xCompare)(void*,int,const void*,int,const void*), + void(SQLITE_CALLBACK *xDestroy)(void*) ); int sqlite3_create_collation16( sqlite3*, const void *zName, int eTextRep, void *pArg, - int(*xCompare)(void*,int,const void*,int,const void*) + int(SQLITE_CALLBACK *xCompare)(void*,int,const void*,int,const void*) ); /* @@ -5013,12 +5045,12 @@ int sqlite3_create_collation16( int sqlite3_collation_needed( sqlite3*, void*, - void(*)(void*,sqlite3*,int eTextRep,const char*) + void(SQLITE_CALLBACK *)(void*,sqlite3*,int eTextRep,const char*) ); int sqlite3_collation_needed16( sqlite3*, void*, - void(*)(void*,sqlite3*,int eTextRep,const void*) + void(SQLITE_CALLBACK *)(void*,sqlite3*,int eTextRep,const void*) ); #ifdef SQLITE_HAS_CODEC @@ -5317,8 +5349,8 @@ sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt); ** ** See also the [sqlite3_update_hook()] interface. */ -void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*); -void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*); +void *sqlite3_commit_hook(sqlite3*, int(SQLITE_CALLBACK *)(void*), void*); +void *sqlite3_rollback_hook(sqlite3*, void(SQLITE_CALLBACK *)(void *), void*); /* ** CAPI3REF: Data Change Notification Callbacks @@ -5371,7 +5403,7 @@ void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*); */ void *sqlite3_update_hook( sqlite3*, - void(*)(void *,int ,char const *,char const *,sqlite3_int64), + void(SQLITE_CALLBACK *)(void *,int ,char const *,char const *,sqlite3_int64), void* ); @@ -5698,7 +5730,7 @@ int sqlite3_enable_load_extension(sqlite3 *db, int onoff); ** See also: [sqlite3_reset_auto_extension()] ** and [sqlite3_cancel_auto_extension()] */ -int sqlite3_auto_extension(void (*xEntryPoint)(void)); +int sqlite3_auto_extension(void (SQLITE_CALLBACK *xEntryPoint)(void)); /* ** CAPI3REF: Cancel Automatic Extension Loading @@ -5710,7 +5742,7 @@ int sqlite3_auto_extension(void (*xEntryPoint)(void)); ** unregistered and it returns 0 if X was not on the list of initialization ** routines. */ -int sqlite3_cancel_auto_extension(void (*xEntryPoint)(void)); +int sqlite3_cancel_auto_extension(void (SQLITE_CALLBACK *xEntryPoint)(void)); /* ** CAPI3REF: Reset Automatic Extension Loading @@ -5755,37 +5787,41 @@ typedef struct sqlite3_module sqlite3_module; */ struct sqlite3_module { int iVersion; - int (*xCreate)(sqlite3*, void *pAux, + int (SQLITE_CALLBACK *xCreate)(sqlite3*, void *pAux, int argc, const char *const*argv, sqlite3_vtab **ppVTab, char**); - int (*xConnect)(sqlite3*, void *pAux, + int (SQLITE_CALLBACK *xConnect)(sqlite3*, void *pAux, int argc, const char *const*argv, sqlite3_vtab **ppVTab, char**); - int (*xBestIndex)(sqlite3_vtab *pVTab, sqlite3_index_info*); - int (*xDisconnect)(sqlite3_vtab *pVTab); - int (*xDestroy)(sqlite3_vtab *pVTab); - int (*xOpen)(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor); - int (*xClose)(sqlite3_vtab_cursor*); - int (*xFilter)(sqlite3_vtab_cursor*, int idxNum, const char *idxStr, - int argc, sqlite3_value **argv); - int (*xNext)(sqlite3_vtab_cursor*); - int (*xEof)(sqlite3_vtab_cursor*); - int (*xColumn)(sqlite3_vtab_cursor*, sqlite3_context*, int); - int (*xRowid)(sqlite3_vtab_cursor*, sqlite3_int64 *pRowid); - int (*xUpdate)(sqlite3_vtab *, int, sqlite3_value **, sqlite3_int64 *); - int (*xBegin)(sqlite3_vtab *pVTab); - int (*xSync)(sqlite3_vtab *pVTab); - int (*xCommit)(sqlite3_vtab *pVTab); - int (*xRollback)(sqlite3_vtab *pVTab); - int (*xFindFunction)(sqlite3_vtab *pVtab, int nArg, const char *zName, - void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), - void **ppArg); - int (*xRename)(sqlite3_vtab *pVtab, const char *zNew); + int (SQLITE_CALLBACK *xBestIndex)(sqlite3_vtab *pVTab, sqlite3_index_info*); + int (SQLITE_CALLBACK *xDisconnect)(sqlite3_vtab *pVTab); + int (SQLITE_CALLBACK *xDestroy)(sqlite3_vtab *pVTab); + int (SQLITE_CALLBACK *xOpen)(sqlite3_vtab *pVTab, + sqlite3_vtab_cursor **ppCursor); + int (SQLITE_CALLBACK *xClose)(sqlite3_vtab_cursor*); + int (SQLITE_CALLBACK *xFilter)(sqlite3_vtab_cursor*, + int idxNum, const char *idxStr, + int argc, sqlite3_value **argv); + int (SQLITE_CALLBACK *xNext)(sqlite3_vtab_cursor*); + int (SQLITE_CALLBACK *xEof)(sqlite3_vtab_cursor*); + int (SQLITE_CALLBACK *xColumn)(sqlite3_vtab_cursor*, sqlite3_context*, int); + int (SQLITE_CALLBACK *xRowid)(sqlite3_vtab_cursor*, sqlite3_int64 *pRowid); + int (SQLITE_CALLBACK *xUpdate)(sqlite3_vtab *, int, sqlite3_value **, + sqlite3_int64 *); + int (SQLITE_CALLBACK *xBegin)(sqlite3_vtab *pVTab); + int (SQLITE_CALLBACK *xSync)(sqlite3_vtab *pVTab); + int (SQLITE_CALLBACK *xCommit)(sqlite3_vtab *pVTab); + int (SQLITE_CALLBACK *xRollback)(sqlite3_vtab *pVTab); + int (SQLITE_CALLBACK *xFindFunction)(sqlite3_vtab *pVtab, + int nArg, const char *zName, + void (SQLITE_CALLBACK **pxFunc)(sqlite3_context*,int,sqlite3_value**), + void **ppArg); + int (SQLITE_CALLBACK *xRename)(sqlite3_vtab *pVtab, const char *zNew); /* The methods above are in version 1 of the sqlite_module object. Those ** below are for version 2 and greater. */ - int (*xSavepoint)(sqlite3_vtab *pVTab, int); - int (*xRelease)(sqlite3_vtab *pVTab, int); - int (*xRollbackTo)(sqlite3_vtab *pVTab, int); + int (SQLITE_CALLBACK *xSavepoint)(sqlite3_vtab *pVTab, int); + int (SQLITE_CALLBACK *xRelease)(sqlite3_vtab *pVTab, int); + int (SQLITE_CALLBACK *xRollbackTo)(sqlite3_vtab *pVTab, int); }; /* @@ -5974,7 +6010,7 @@ int sqlite3_create_module_v2( const char *zName, /* Name of the module */ const sqlite3_module *p, /* Methods for the module */ void *pClientData, /* Client data for xCreate/xConnect */ - void(*xDestroy)(void*) /* Module destructor function */ + void(SQLITE_CALLBACK *xDestroy)(void*) /* Module destructor function */ ); /* @@ -6515,15 +6551,15 @@ void sqlite3_mutex_leave(sqlite3_mutex*); */ typedef struct sqlite3_mutex_methods sqlite3_mutex_methods; struct sqlite3_mutex_methods { - int (*xMutexInit)(void); - int (*xMutexEnd)(void); - sqlite3_mutex *(*xMutexAlloc)(int); - void (*xMutexFree)(sqlite3_mutex *); - void (*xMutexEnter)(sqlite3_mutex *); - int (*xMutexTry)(sqlite3_mutex *); - void (*xMutexLeave)(sqlite3_mutex *); - int (*xMutexHeld)(sqlite3_mutex *); - int (*xMutexNotheld)(sqlite3_mutex *); + int (SQLITE_CALLBACK *xMutexInit)(void); + int (SQLITE_CALLBACK *xMutexEnd)(void); + sqlite3_mutex *(SQLITE_CALLBACK *xMutexAlloc)(int); + void (SQLITE_CALLBACK *xMutexFree)(sqlite3_mutex *); + void (SQLITE_CALLBACK *xMutexEnter)(sqlite3_mutex *); + int (SQLITE_CALLBACK *xMutexTry)(sqlite3_mutex *); + void (SQLITE_CALLBACK *xMutexLeave)(sqlite3_mutex *); + int (SQLITE_CALLBACK *xMutexHeld)(sqlite3_mutex *); + int (SQLITE_CALLBACK *xMutexNotheld)(sqlite3_mutex *); }; /* @@ -7219,18 +7255,21 @@ typedef struct sqlite3_pcache_methods2 sqlite3_pcache_methods2; struct sqlite3_pcache_methods2 { int iVersion; void *pArg; - int (*xInit)(void*); - void (*xShutdown)(void*); - sqlite3_pcache *(*xCreate)(int szPage, int szExtra, int bPurgeable); - void (*xCachesize)(sqlite3_pcache*, int nCachesize); - int (*xPagecount)(sqlite3_pcache*); - sqlite3_pcache_page *(*xFetch)(sqlite3_pcache*, unsigned key, int createFlag); - void (*xUnpin)(sqlite3_pcache*, sqlite3_pcache_page*, int discard); - void (*xRekey)(sqlite3_pcache*, sqlite3_pcache_page*, - unsigned oldKey, unsigned newKey); - void (*xTruncate)(sqlite3_pcache*, unsigned iLimit); - void (*xDestroy)(sqlite3_pcache*); - void (*xShrink)(sqlite3_pcache*); + int (SQLITE_CALLBACK *xInit)(void*); + void (SQLITE_CALLBACK *xShutdown)(void*); + sqlite3_pcache *(SQLITE_CALLBACK *xCreate)(int szPage, int szExtra, + int bPurgeable); + void (SQLITE_CALLBACK *xCachesize)(sqlite3_pcache*, int nCachesize); + int (SQLITE_CALLBACK *xPagecount)(sqlite3_pcache*); + sqlite3_pcache_page *(SQLITE_CALLBACK *xFetch)(sqlite3_pcache*, unsigned key, + int createFlag); + void (SQLITE_CALLBACK *xUnpin)(sqlite3_pcache*, sqlite3_pcache_page*, + int discard); + void (SQLITE_CALLBACK *xRekey)(sqlite3_pcache*, sqlite3_pcache_page*, + unsigned oldKey, unsigned newKey); + void (SQLITE_CALLBACK *xTruncate)(sqlite3_pcache*, unsigned iLimit); + void (SQLITE_CALLBACK *xDestroy)(sqlite3_pcache*); + void (SQLITE_CALLBACK *xShrink)(sqlite3_pcache*); }; /* @@ -7241,16 +7280,18 @@ struct sqlite3_pcache_methods2 { typedef struct sqlite3_pcache_methods sqlite3_pcache_methods; struct sqlite3_pcache_methods { void *pArg; - int (*xInit)(void*); - void (*xShutdown)(void*); - sqlite3_pcache *(*xCreate)(int szPage, int bPurgeable); - void (*xCachesize)(sqlite3_pcache*, int nCachesize); - int (*xPagecount)(sqlite3_pcache*); - void *(*xFetch)(sqlite3_pcache*, unsigned key, int createFlag); - void (*xUnpin)(sqlite3_pcache*, void*, int discard); - void (*xRekey)(sqlite3_pcache*, void*, unsigned oldKey, unsigned newKey); - void (*xTruncate)(sqlite3_pcache*, unsigned iLimit); - void (*xDestroy)(sqlite3_pcache*); + int (SQLITE_CALLBACK *xInit)(void*); + void (SQLITE_CALLBACK *xShutdown)(void*); + sqlite3_pcache *(SQLITE_CALLBACK *xCreate)(int szPage, int bPurgeable); + void (SQLITE_CALLBACK *xCachesize)(sqlite3_pcache*, int nCachesize); + int (SQLITE_CALLBACK *xPagecount)(sqlite3_pcache*); + void *(SQLITE_CALLBACK *xFetch)(sqlite3_pcache*, unsigned key, + int createFlag); + void (SQLITE_CALLBACK *xUnpin)(sqlite3_pcache*, void*, int discard); + void (SQLITE_CALLBACK *xRekey)(sqlite3_pcache*, void*, unsigned oldKey, + unsigned newKey); + void (SQLITE_CALLBACK *xTruncate)(sqlite3_pcache*, unsigned iLimit); + void (SQLITE_CALLBACK *xDestroy)(sqlite3_pcache*); }; @@ -7580,7 +7621,7 @@ int sqlite3_backup_pagecount(sqlite3_backup *p); */ int sqlite3_unlock_notify( sqlite3 *pBlocked, /* Waiting connection */ - void (*xNotify)(void **apArg, int nArg), /* Callback function to invoke */ + void (SQLITE_CALLBACK *xNotify)(void **apArg, int nArg), /* Callback func */ void *pNotifyArg /* Argument to pass to xNotify */ ); @@ -7695,7 +7736,7 @@ void sqlite3_log(int iErrCode, const char *zFormat, ...); */ void *sqlite3_wal_hook( sqlite3*, - int(*)(void *,sqlite3*,const char*,int), + int(SQLITE_CALLBACK *)(void *,sqlite3*,const char*,int), void* ); @@ -8168,7 +8209,7 @@ int sqlite3_db_cacheflush(sqlite3*); */ SQLITE_EXPERIMENTAL void *sqlite3_preupdate_hook( sqlite3 *db, - void(*xPreUpdate)( + void(SQLITE_CALLBACK *xPreUpdate)( void *pCtx, /* Copy of third arg to preupdate_hook() */ sqlite3 *db, /* Database handle */ int op, /* SQLITE_UPDATE, DELETE or INSERT */ diff --git a/src/tclsqlite.c b/src/tclsqlite.c index 2de88f41f4..e559043c08 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -4167,7 +4167,7 @@ static void init_all(Tcl_Interp *interp){ #endif #define TCLSH_MAIN main /* Needed to fake out mktclapp */ -int TCLSH_MAIN(int argc, char **argv){ +int SQLITE_CDECL TCLSH_MAIN(int argc, char **argv){ Tcl_Interp *interp; #if !defined(_WIN32_WCE) diff --git a/src/test1.c b/src/test1.c index 7d83881139..35c43d0ef9 100644 --- a/src/test1.c +++ b/src/test1.c @@ -6444,7 +6444,7 @@ struct win32FileLocker { /* ** The background thread that does file locking. */ -static void win32_file_locker(void *pAppData){ +static void SQLITE_CDECL win32_file_locker(void *pAppData){ struct win32FileLocker *p = (struct win32FileLocker*)pAppData; if( p->evName ){ HANDLE ev = OpenEvent(EVENT_MODIFY_STATE, FALSE, p->evName); diff --git a/tool/mksqlite3c-noext.tcl b/tool/mksqlite3c-noext.tcl index 601b8cce8c..fad6c9e584 100644 --- a/tool/mksqlite3c-noext.tcl +++ b/tool/mksqlite3c-noext.tcl @@ -220,7 +220,7 @@ proc copy_file {filename} { if {[lsearch -exact $cdecllist $funcname] >= 0} { append line SQLITE_CDECL } else { - append line SQLITE_STDCALL + append line SQLITE_APICALL } append line " " $funcname $rest puts $out $line diff --git a/tool/mksqlite3c.tcl b/tool/mksqlite3c.tcl index 7e8558d2ab..b7561cfa5b 100644 --- a/tool/mksqlite3c.tcl +++ b/tool/mksqlite3c.tcl @@ -232,7 +232,7 @@ proc copy_file {filename} { if {[lsearch -exact $cdecllist $funcname] >= 0} { append line SQLITE_CDECL } else { - append line SQLITE_STDCALL + append line SQLITE_APICALL } append line " " $funcname $rest puts $out $line diff --git a/tool/mksqlite3h.tcl b/tool/mksqlite3h.tcl index 1af6d75730..d0ddba9cfa 100644 --- a/tool/mksqlite3h.tcl +++ b/tool/mksqlite3h.tcl @@ -120,7 +120,7 @@ foreach file $filelist { if {[lsearch -exact $cdecllist $funcname] >= 0} { append line SQLITE_CDECL } else { - append line SQLITE_STDCALL + append line SQLITE_APICALL } append line " " $funcname $rest } From 4aff119f3a270e6b453cd32f0226a09bc1c4cd24 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 28 Jul 2016 12:52:30 +0000 Subject: [PATCH 0612/1484] New test case to insure legacy CREATE TABLE syntax is supported. FossilOrigin-Name: 6feff15cae8f0427be790355841d49c479c1c586 --- manifest | 13 ++++++------- manifest.uuid | 2 +- test/parser1.test | 23 +++++++++++++++++++++++ 3 files changed, 30 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index d0e7b14e54..d4a4aa1bdd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\sthe\squery\splanner\scost\sestimation\sfor\sindex\sscans\sto\stake\sinto\saccount\nWHERE\sclause\sterms\sthat\scan\sbe\scomputed\susing\sonly\sthe\sindex\sand\sthat\sdo\snot\nrequire\slooking\sup\srows\sin\sthe\soriginal\stable.\s\sThis\sfixes\san\sobscure\nperformance\sregression\sthat\sarose\swhen\sthe\sORDER\sBY\sLIMIT\soptimization\swas\nadded\sby\scheck-in\s[bf46179d44843]. -D 2016-07-27T19:30:53.586 +C New\stest\scase\sto\sinsure\slegacy\sCREATE\sTABLE\ssyntax\sis\ssupported. +D 2016-07-28T12:52:30.552 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -985,7 +985,7 @@ F test/pagerfault2.test caf4c7facb914fd3b03a17b31ae2b180c8d6ca1f F test/pagerfault3.test 1003fcda009bf48a8e22a516e193b6ef0dd1bbd8 F test/pageropt.test 84e4cc5cbca285357f7906e99b21be4f2bf5abc0 F test/pagesize.test 5769fc62d8c890a83a503f67d47508dfdc543305 -F test/parser1.test 222b5cbf3e2e659fec1bf7d723488c8b9c94f1d0 +F test/parser1.test 391b9bf9a229547a129c61ac345ed1a6f5eb1854 F test/pcache.test c8acbedd3b6fd0f9a7ca887a83b11d24a007972b F test/pcache2.test af7f3deb1a819f77a6d0d81534e97d1cf62cd442 F test/percentile.test 4243af26b8f3f4555abe166f723715a1f74c77ff @@ -1508,8 +1508,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 4d59df02d3713b3e3804e1a88e676749b2794286 50f8ea37fb9647c4a9da2c269a4d6f54b10ce96b -R a589b595bdfe9868de18def836f199ce -T +closed 50f8ea37fb9647c4a9da2c269a4d6f54b10ce96b +P 9e2b26811452a5011d0a97a689636fa4409da856 +R d76a2fc86bbf1915af6bf1dd54a28237 U drh -Z 994e8dc5cbb7e25d0e8cc4a952504fbd +Z 803b725d666d5af434be7409c67eabe6 diff --git a/manifest.uuid b/manifest.uuid index 9b63447ecc..f4495ea5c1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9e2b26811452a5011d0a97a689636fa4409da856 \ No newline at end of file +6feff15cae8f0427be790355841d49c479c1c586 \ No newline at end of file diff --git a/test/parser1.test b/test/parser1.test index 78c1a40c63..c708dded1f 100644 --- a/test/parser1.test +++ b/test/parser1.test @@ -76,4 +76,27 @@ do_catchsql_test parser1-2.2 { SELECT x FROM c; } {1 {syntax error after column name "x"}} +# Verify that the comma between multiple table constraints is +# optional. +# +# The missing comma is technically a syntax error. But we have to support +# it because there might be legacy databases that omit the commas in their +# sqlite_master tables. +# +do_execsql_test parser1-3.1 { + CREATE TABLE t300(id INTEGER PRIMARY KEY); + CREATE TABLE t301( + id INTEGER PRIMARY KEY, + c1 INTEGER NOT NULL, + c2 INTEGER NOT NULL, + c3 BOOLEAN NOT NULL DEFAULT 0, + FOREIGN KEY(c1) REFERENCES t300(id) ON DELETE CASCADE ON UPDATE RESTRICT + /* no comma */ + FOREIGN KEY(c2) REFERENCES t300(id) ON DELETE CASCADE ON UPDATE RESTRICT + /* no comma */ + UNIQUE(c1, c2) + ); + PRAGMA foreign_key_list(t301); +} {0 0 t300 c2 id RESTRICT CASCADE NONE 1 0 t300 c1 id RESTRICT CASCADE NONE} + finish_test From 52b1dbb5fc949a629d7213661c968c722b9e5029 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Thu, 28 Jul 2016 14:37:04 +0000 Subject: [PATCH 0613/1484] Allow the 'testfixture.exe' target to be compiled with the __stdcall calling convention. FossilOrigin-Name: e8be3dfeabaa31b3490793cf8230faae1204be15 --- Makefile.msc | 32 +++++++++--- ext/fts2/fts2_tokenizer.c | 6 ++- ext/fts3/fts3_test.c | 6 ++- ext/fts3/fts3_tokenizer.c | 6 ++- ext/fts5/fts5_tcl.c | 6 ++- ext/rbu/test_rbu.c | 12 ++++- ext/session/test_session.c | 6 ++- manifest | 99 ++++++++++++++++++-------------------- manifest.uuid | 2 +- src/tclsqlite.c | 10 ++-- src/test1.c | 6 ++- src/test2.c | 6 ++- src/test3.c | 6 ++- src/test4.c | 6 ++- src/test5.c | 6 ++- src/test6.c | 6 ++- src/test7.c | 6 ++- src/test8.c | 6 ++- src/test9.c | 6 ++- src/test_async.c | 6 ++- src/test_autoext.c | 6 ++- src/test_backup.c | 6 ++- src/test_bestindex.c | 6 ++- src/test_blob.c | 6 ++- src/test_btree.c | 6 ++- src/test_config.c | 6 ++- src/test_demovfs.c | 6 ++- src/test_fs.c | 6 ++- src/test_func.c | 6 ++- src/test_hexio.c | 6 ++- src/test_init.c | 6 ++- src/test_intarray.c | 6 ++- src/test_malloc.c | 6 ++- src/test_multiplex.c | 6 ++- src/test_mutex.c | 6 ++- src/test_osinst.c | 6 ++- src/test_quota.c | 6 ++- src/test_rtree.c | 12 ++++- src/test_schema.c | 10 ++-- src/test_superlock.c | 6 ++- src/test_syscall.c | 6 ++- src/test_tclvar.c | 6 ++- src/test_thread.c | 6 ++- src/test_vfs.c | 6 ++- tool/replace.tcl | 3 +- 45 files changed, 294 insertions(+), 108 deletions(-) diff --git a/Makefile.msc b/Makefile.msc index 7220f71cd4..c3f7f3a2b0 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -466,12 +466,12 @@ RCC = $(RC) -DSQLITE_OS_WIN=1 -I. -I$(TOP) -I$(TOP)\src $(RCOPTS) $(RCCOPTS) !IF "$(PLATFORM)"=="x86" CORE_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall SHELL_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall -TEST_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall +TEST_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall -DINCLUDE_SQLITE_TCL_H=1 -DSQLITE_TCLAPI=__cdecl !ELSE !IFNDEF PLATFORM CORE_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall SHELL_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall -TEST_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall +TEST_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall -DINCLUDE_SQLITE_TCL_H=1 -DSQLITE_TCLAPI=__cdecl !ELSE CORE_CCONV_OPTS = SHELL_CCONV_OPTS = @@ -1239,6 +1239,12 @@ SRC11 = \ parse.h \ $(SQLITE3H) +# Generated Tcl header files +# +SRC12 = \ + sqlite_tcl.h \ + sqlite_tclDecls.h + # All source code files. # SRC = $(SRC00) $(SRC01) $(SRC02) $(SRC03) $(SRC04) $(SRC05) $(SRC06) $(SRC07) $(SRC08) $(SRC09) $(SRC10) $(SRC11) @@ -1503,7 +1509,7 @@ mptest: mptester.exe # files are automatically generated. This target takes care of # all that automatic generation. # -.target_source: $(SRC) $(TOP)\tool\vdbe-compress.tcl fts5.c +.target_source: $(SRC) $(TOP)\tool\vdbe-compress.tcl fts5.c sqlite_tcl.h -rmdir /Q/S tsrc 2>NUL -mkdir tsrc for %i in ($(SRC00)) do copy /Y %i tsrc @@ -1518,6 +1524,7 @@ mptest: mptester.exe for %i in ($(SRC09)) do copy /Y %i tsrc for %i in ($(SRC10)) do copy /Y %i tsrc for %i in ($(SRC11)) do copy /Y %i tsrc + for %i in ($(SRC12)) do copy /Y %i tsrc copy /Y fts5.c tsrc copy /Y fts5.h tsrc del /Q tsrc\sqlite.h.in tsrc\parse.y 2>NUL @@ -1799,10 +1806,10 @@ wherecode.lo: $(TOP)\src\wherecode.c $(HDR) whereexpr.lo: $(TOP)\src\whereexpr.c $(HDR) $(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\whereexpr.c -tclsqlite.lo: $(TOP)\src\tclsqlite.c $(HDR) +tclsqlite.lo: $(TOP)\src\tclsqlite.c $(HDR) sqlite_tcl.h $(LTCOMPILE) $(NO_WARN) -DUSE_TCL_STUBS=1 -DBUILD_sqlite -I$(TCLINCDIR) -c $(TOP)\src\tclsqlite.c -tclsqlite-shell.lo: $(TOP)\src\tclsqlite.c $(HDR) +tclsqlite-shell.lo: $(TOP)\src\tclsqlite.c $(HDR) sqlite_tcl.h $(LTCOMPILE) $(NO_WARN) -DTCLSH=1 -DBUILD_sqlite -I$(TCLINCDIR) -c $(TOP)\src\tclsqlite.c tclsqlite3.exe: tclsqlite-shell.lo $(SQLITE3C) $(SQLITE3H) $(LIBRESOBJS) @@ -1974,7 +1981,16 @@ TESTFIXTURE_SRC = $(TESTSRC) $(TOP)\src\tclsqlite.c $(TESTFIXTURE_SRC0) TESTFIXTURE_SRC = $(TESTSRC) $(TOP)\src\tclsqlite.c $(TESTFIXTURE_SRC1) !ENDIF -testfixture.exe: $(TESTFIXTURE_SRC) $(SQLITE3H) $(LIBRESOBJS) $(HDR) +sqlite_tclDecls.h: + echo #ifndef SQLITE_TCLAPI > sqlite_tclDecls.h + echo # define SQLITE_TCLAPI __cdecl >> sqlite_tclDecls.h + echo #endif >> sqlite_tclDecls.h + type "$(TCLINCDIR)\tclDecls.h" | $(TCLSH_CMD) $(TOP)\tool\replace.tcl regsub "^(EXTERN\s+?.*?\s+?)Tcl_" "\1 SQLITE_TCLAPI Tcl_" | $(TCLSH_CMD) $(TOP)\tool\replace.tcl regsub "^(EXTERN\s+?(?:void|VOID)\s+?)TclFreeObj" "\1 SQLITE_TCLAPI TclFreeObj" >> sqlite_tclDecls.h + +sqlite_tcl.h: sqlite_tclDecls.h + type "$(TCLINCDIR)\tcl.h" | $(TCLSH_CMD) $(TOP)\tool\replace.tcl exact tclDecls.h sqlite_tclDecls.h >> sqlite_tcl.h + +testfixture.exe: $(TESTFIXTURE_SRC) $(SQLITE3H) $(LIBRESOBJS) $(HDR) sqlite_tcl.h $(LTLINK) -DSQLITE_NO_SYNC=1 $(TESTFIXTURE_FLAGS) \ -DBUILD_sqlite -I$(TCLINCDIR) \ $(TESTFIXTURE_SRC) \ @@ -2023,7 +2039,7 @@ smoketest: $(TESTPROGS) @set PATH=$(LIBTCLPATH);$(PATH) .\testfixture.exe $(TOP)\test\main.test $(TESTOPTS) -sqlite3_analyzer.c: $(SQLITE3C) $(SQLITE3H) $(TOP)\src\tclsqlite.c $(TOP)\tool\spaceanal.tcl +sqlite3_analyzer.c: $(SQLITE3C) $(SQLITE3H) $(TOP)\src\tclsqlite.c $(TOP)\tool\spaceanal.tcl sqlite_tcl.h echo #define TCLSH 2 > $@ echo #define SQLITE_ENABLE_DBSTAT_VTAB 1 >> $@ copy $@ + $(SQLITE3C) + $(TOP)\src\tclsqlite.c $@ @@ -2103,7 +2119,7 @@ clean: -rmdir /Q/S .libs 2>NUL -rmdir /Q/S tsrc 2>NUL del /Q .target_source 2>NUL - del /Q tclsqlite3.exe 2>NUL + del /Q tclsqlite3.exe sqlite_tcl.h sqlite_tclDecls.h 2>NUL del /Q testloadext.dll 2>NUL del /Q testfixture.exe test.db 2>NUL del /Q LogEst.exe fts3view.exe rollback-test.exe showdb.exe 2>NUL diff --git a/ext/fts2/fts2_tokenizer.c b/ext/fts2/fts2_tokenizer.c index a3d6a6312a..dda33a72d2 100644 --- a/ext/fts2/fts2_tokenizer.c +++ b/ext/fts2/fts2_tokenizer.c @@ -99,7 +99,11 @@ static void scalarFunc( #ifdef SQLITE_TEST -#include +#if defined(INCLUDE_SQLITE_TCL_H) +# include "sqlite_tcl.h" +#else +# include "tcl.h" +#endif #include /* diff --git a/ext/fts3/fts3_test.c b/ext/fts3/fts3_test.c index 2596e6dec7..c3b71284ec 100644 --- a/ext/fts3/fts3_test.c +++ b/ext/fts3/fts3_test.c @@ -18,7 +18,11 @@ ** that the sqlite3_tokenizer_module.xLanguage() method is invoked correctly. */ -#include +#if defined(INCLUDE_SQLITE_TCL_H) +# include "sqlite_tcl.h" +#else +# include "tcl.h" +#endif #include #include diff --git a/ext/fts3/fts3_tokenizer.c b/ext/fts3/fts3_tokenizer.c index b7d9d2b3b2..bfc36af3e3 100644 --- a/ext/fts3/fts3_tokenizer.c +++ b/ext/fts3/fts3_tokenizer.c @@ -224,7 +224,11 @@ int sqlite3Fts3InitTokenizer( #ifdef SQLITE_TEST -#include +#if defined(INCLUDE_SQLITE_TCL_H) +# include "sqlite_tcl.h" +#else +# include "tcl.h" +#endif #include /* diff --git a/ext/fts5/fts5_tcl.c b/ext/fts5/fts5_tcl.c index 72db65777f..dee9bc7f18 100644 --- a/ext/fts5/fts5_tcl.c +++ b/ext/fts5/fts5_tcl.c @@ -14,7 +14,11 @@ #ifdef SQLITE_TEST -#include +#if defined(INCLUDE_SQLITE_TCL_H) +# include "sqlite_tcl.h" +#else +# include "tcl.h" +#endif #ifdef SQLITE_ENABLE_FTS5 diff --git a/ext/rbu/test_rbu.c b/ext/rbu/test_rbu.c index 6418d30d59..671f16c553 100644 --- a/ext/rbu/test_rbu.c +++ b/ext/rbu/test_rbu.c @@ -17,7 +17,11 @@ #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_RBU) #include "sqlite3rbu.h" -#include +#if defined(INCLUDE_SQLITE_TCL_H) +# include "sqlite_tcl.h" +#else +# include "tcl.h" +#endif #include /* From main.c */ @@ -347,7 +351,11 @@ int SqliteRbu_Init(Tcl_Interp *interp){ } #else -#include +#if defined(INCLUDE_SQLITE_TCL_H) +# include "sqlite_tcl.h" +#else +# include "tcl.h" +#endif int SqliteRbu_Init(Tcl_Interp *interp){ return TCL_OK; } #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_RBU) */ #endif /* defined(SQLITE_TEST) */ diff --git a/ext/session/test_session.c b/ext/session/test_session.c index 1aa63b74ed..9f6bc3f70d 100644 --- a/ext/session/test_session.c +++ b/ext/session/test_session.c @@ -5,7 +5,11 @@ #include "sqlite3session.h" #include #include -#include +#if defined(INCLUDE_SQLITE_TCL_H) +# include "sqlite_tcl.h" +#else +# include "tcl.h" +#endif typedef struct TestSession TestSession; struct TestSession { diff --git a/manifest b/manifest index a174c165d9..8f0151d5f2 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -C Work\sin\sprogress\son\ssetting\sa\scalling\sconvention\sfor\sall\scallback\sfunctions. -D 2016-07-28T04:14:37.455 +C Allow\sthe\s'testfixture.exe'\starget\sto\sbe\scompiled\swith\sthe\s__stdcall\scalling\sconvention. +D 2016-07-28T14:37:04.758 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 -F Makefile.msc 843c563182b26a358674c520d7b8d40b832e9436 +F Makefile.msc da4c9f5bc46f6f12d7313d12be18a2d2c55e06c0 F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7 F VERSION cb29eb11e493dd85b3eeec4053c03949bf98478e F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 @@ -62,7 +62,7 @@ F ext/fts2/fts2_hash.c 011a1d32de45bb1b519a1fd0048e857d6a843558 F ext/fts2/fts2_hash.h 1824b99dfd8d0225facbdb26a2c87289b2e7dcf8 F ext/fts2/fts2_icu.c 51c5cd3c04954badd329fa738c95fcdb717b5188 F ext/fts2/fts2_porter.c 2cd4a507bf3c3085fe66f59b0f2a325f65aaacf5 -F ext/fts2/fts2_tokenizer.c 3dbe8058e97afb55fff3ea844120ce3208b114cc +F ext/fts2/fts2_tokenizer.c b529493d55e55497213c37e1f31680a77746be26 F ext/fts2/fts2_tokenizer.h 27a1a99ca2d615cf7e142839b8d79e8751b4529e F ext/fts2/fts2_tokenizer1.c 07e223eecb483d448313b5f1553a4f299a7fb7a1 F ext/fts2/mkfts2amal.tcl 974d5d438cb3f7c4a652639262f82418c1e4cff0 @@ -81,9 +81,9 @@ F ext/fts3/fts3_icu.c deb46f7020d87ea7a14a433fb7a7f4bef42a9652 F ext/fts3/fts3_porter.c 3565faf04b626cddf85f03825e86056a4562c009 F ext/fts3/fts3_snippet.c 68ae118b0f834ea53d2b89e4087fc0f0b8c4ee4e F ext/fts3/fts3_term.c 88c55a6fa1a51ab494e33dced0401a6c28791fd7 -F ext/fts3/fts3_test.c a940cf104d545ad1abf926956ce65db2aa5af0cf +F ext/fts3/fts3_test.c 7d8c9e17bc11cc245c91585ef5a47ee4a600f7b2 F ext/fts3/fts3_tokenize_vtab.c a27593ab19657166f6fa5ec073b678cc29a75860 -F ext/fts3/fts3_tokenizer.c 3cf21cd2212db17a88d4ef7da0fd8a80275979a1 +F ext/fts3/fts3_tokenizer.c a22bf311a71f3efa9d7012d8cc48fc9b0f3dace7 F ext/fts3/fts3_tokenizer.h 64c6ef6c5272c51ebe60fc607a896e84288fcbc3 F ext/fts3/fts3_tokenizer1.c 5c98225a53705e5ee34824087478cf477bdb7004 F ext/fts3/fts3_unicode.c a93f5edc0aff44ef8b06d7cb55b52026541ca145 @@ -107,7 +107,7 @@ F ext/fts5/fts5_hash.c 880998e596b60f078348d48732ca4ad9a90caad2 F ext/fts5/fts5_index.c b429e23fabb57506f71e406997cc46b89190dc97 F ext/fts5/fts5_main.c f85281445dcf8be32d18841c93a6f90fe27dbfe2 F ext/fts5/fts5_storage.c de0ed8a06738bde433afe11e92295ceaffbc4e58 -F ext/fts5/fts5_tcl.c f8731e0508299bd43f1a2eff7dbeaac870768966 +F ext/fts5/fts5_tcl.c b41f04600936a2b910b5dff179e8bd050ccb34c7 F ext/fts5/fts5_test_mi.c 783b86697ebf773c18fc109992426c0173a055bc F ext/fts5/fts5_test_tok.c db08af63673c3a7d39f053b36fd6e065017706be F ext/fts5/fts5_tokenize.c 2ce7b44183538ec46b7907726262ee43ffdd39a8 @@ -255,7 +255,7 @@ F ext/rbu/rbuvacuum.test 4a977447c15c2581ab668781d9ef4294382530e0 F ext/rbu/rbuvacuum2.test 45009e127c3fb385e5c0fd5a8a63fb922a79d0ab F ext/rbu/sqlite3rbu.c 948677ee0ec57da51148e6c5f64ac68afcf36ab2 F ext/rbu/sqlite3rbu.h db8858120c9be14b60c9225f9da28221f5f6b945 -F ext/rbu/test_rbu.c 9f043b74c46c45b231f4313aed1fccb379a76fe6 +F ext/rbu/test_rbu.c c2c1859dfd69f1a55125d38009d0d49e36895780 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 F ext/rtree/rtree.c d26a815b0df1c412a6881dae8d7fd3c9c08cce68 F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e @@ -301,7 +301,7 @@ F ext/session/sessionfault.test da273f2712b6411e85e71465a1733b8501dbf6f7 F ext/session/sessionfault2.test 04aa0bc9aa70ea43d8de82c4f648db4de1e990b0 F ext/session/sqlite3session.c 37485891b4add26cf61495df193c419f36556a32 F ext/session/sqlite3session.h 69bf73cfd71e58f2ae5d2aa935b2c1a541aee555 -F ext/session/test_session.c 464f2c8bf502795d95969387eb8e93f68c513c15 +F ext/session/test_session.c ebf9acf2bd70885e6245512427f800693b65dc9c F ext/userauth/sqlite3userauth.h 19cb6f0e31316d0ee4afdfb7a85ef9da3333a220 F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04 F ext/userauth/userauth.c 5fa3bdb492f481bbc1709fc83c91ebd13460c69e @@ -392,51 +392,51 @@ F src/sqliteInt.h d25c18c1272a7811e2569c39bfc2fca96156eead F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c 5b18f9526900f61189ab0b83f1ef41d9f871a2ab F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 -F src/tclsqlite.c 53274d5bbd66e7246c573a6b48026781d42c7efe -F src/test1.c 5ec959d088af063cac44cf1685455f3fcddecc8c -F src/test2.c 5586f43fcd9a1be0830793cf9d354082c261b25b -F src/test3.c c75c8af0eadb335236c9e61b51044c58a8f7dd59 -F src/test4.c d168f83cc78d02e8d35567bb5630e40dcd85ac1e -F src/test5.c 5a34feec76d9b3a86aab30fd4f6cc9c48cbab4c1 -F src/test6.c a684b7abd01352ab50cb79c0bf727e6b3f381a3d -F src/test7.c 9c89a4f1ed6bb13af0ed805b8d782bd83fcd57e3 -F src/test8.c fa262391d3edea6490a71bfaa8fed477ccbbac75 -F src/test9.c bea1e8cf52aa93695487badedd6e1886c321ea60 -F src/test_async.c 21e11293a2f72080eda70e1124e9102044531cd8 -F src/test_autoext.c dea8a01a7153b9adc97bd26161e4226329546e12 -F src/test_backup.c 2e6e6a081870150f20c526a2e9d0d29cda47d803 -F src/test_bestindex.c f9e6807c52aa532e4775321ce3ed8e47c907ed45 -F src/test_blob.c b2551a9b5573232db5f66f292307c37067937239 -F src/test_btree.c 2e9978eca99a9a4bfa8cae949efb00886860a64f -F src/test_config.c 7003f6f35134de6f19c6588f44783e43390ea277 -F src/test_demovfs.c 0de72c2c89551629f58486fde5734b7d90758852 +F src/tclsqlite.c e348648c28fcaa04ab8da98bf7e8a37b3629e634 +F src/test1.c a625e4d2857e0b08a9d66bdb737ce95b02326a9f +F src/test2.c ce1e56fd0983866df1dbaf6c0558f3ad726ec222 +F src/test3.c 68b6b3b17df3028deda0a79607af70ff4ac5fc52 +F src/test4.c a305bb93783fa0db03b9e5e899ec5367cf139903 +F src/test5.c 3ca6874d52d658607d2f25bb6ed88fd03ad78a6c +F src/test6.c 4fc2c870b4f41d46f11a24b5c7dcff89486442b8 +F src/test7.c 57b6dae963ff12cb6ef8389285427f07e8b042ff +F src/test8.c 33cefbf2911e12c74c6adb798cc0c8ee3287a58d +F src/test9.c 6b9792e8a692a67fcce77dfe4a2ca4744c4ece54 +F src/test_async.c 233536b7e364a4a95597d6aa6fdf07fa9351de67 +F src/test_autoext.c 2a2343174ff46477dd081b7582dc1e72c69330bc +F src/test_backup.c 7fe86c0be6c1a05a254b845a6aa32294dbdab012 +F src/test_bestindex.c 832b9968bf15d60029c1700905d56cefeb0f5dd7 +F src/test_blob.c 6af2552a059f326a107214fb13917f31a1606caf +F src/test_btree.c 3d2abd96336f1cbb760c7c5a758e74eaae98aed6 +F src/test_config.c 4d3d4a886416f369771d69a6dba926866deda788 +F src/test_demovfs.c ed337b14964a5f5ba08bf9472c94c64e88c547a7 F src/test_devsym.c 4e58dec2602d8e139ca08659f62a62450587cb58 -F src/test_fs.c f10f840ca4f8c72e4837908bd8347ac4bcab074b -F src/test_func.c 37453d346cfcf118774efd5bf6187f7e6a7e3254 -F src/test_hexio.c abfdecb6fa58c354623978efceb088ca18e379cd -F src/test_init.c 66b33120ffe9cd853b5a905ec850d51151337b32 -F src/test_intarray.c 870124b95ec4c645d4eb84f15efb7133528fb1a5 +F src/test_fs.c 39086f99413e73f60afe2280a0ff27dfab63ab47 +F src/test_func.c 4197173afb7d8453d3d0c7f7b109226dcef52997 +F src/test_hexio.c 2ab200d91f77085bd69c721dcb2b649f036d608b +F src/test_init.c a55015461868ca979d819f8db72aa682ba068185 +F src/test_intarray.c 9fee7f930ff988dd0fc20315da4c762f77f01a78 F src/test_intarray.h f3b7672f5d1056eac563c0d6ea8480a660b1475c F src/test_journal.c d3b83f2bcb7792c709e57abddc456a2b1818643a F src/test_loadext.c 337056bae59f80b9eb00ba82088b39d0f4fe6dfd -F src/test_malloc.c 6b27e947eeeb70d11aa65406ed28d749e39b6356 -F src/test_multiplex.c eafc567ebe162e36f17b5062285dfe90461cf8e9 +F src/test_malloc.c 90cbc63ebab11d16b440d394e77bc26629829f11 +F src/test_multiplex.c a0bcea72bc981f64c9c71edf22cc503cf83e0348 F src/test_multiplex.h 5436d03f2d0501d04f3ed50a75819e190495b635 -F src/test_mutex.c dbdfaff8580071f2212a0deae3325a93a737819c +F src/test_mutex.c 85021f2ffe67cdb4dfa6089f3f55f5e01cd76aea F src/test_onefile.c 416f87a28d6d673352d33fc4b1c7d39db878e50f -F src/test_osinst.c ad0233b1dabb0390e25edded4ebd79a2a61538c6 +F src/test_osinst.c 4e21c7b2709955f9907b80bfc874afb81ce1b4a7 F src/test_pcache.c a5cd24730cb43c5b18629043314548c9169abb00 -F src/test_quota.c 180813f43683be5725458fc1ff13ac455d8e722d +F src/test_quota.c 7c2bb6d302f9cab9d4782b1a37dd01f0c7bde071 F src/test_quota.h 2a8ad1952d1d2ca9af0ce0465e56e6c023b5e15d -F src/test_rtree.c 43fff4c5a01576d6d213f27472598801a247890c -F src/test_schema.c 2bdba21b82f601da69793e1f1d11bf481a79b091 +F src/test_rtree.c 0aad72f4854b01957b20c3c325eecd8512e9731d +F src/test_schema.c ab94aeab8a94486de3d2ce06567b7ee35f3a59b8 F src/test_server.c a2615049954cbb9cfb4a62e18e2f0616e4dc38fe F src/test_sqllog.c 0d138a8180a312bf996b37fa66da5c5799d4d57b -F src/test_superlock.c 06797157176eb7085027d9dd278c0d7a105e3ec9 -F src/test_syscall.c 268c072541162564a882c57f54a6fee12ef4a4d2 -F src/test_tclvar.c d86412527da65468ee6fa1b8607c65d0af736bc4 -F src/test_thread.c af391ec03d23486dffbcc250b7e58e073f172af9 -F src/test_vfs.c 4d02f38bfb8f7f273da7ba84bfe000f5babf206c +F src/test_superlock.c 9389ee2aa8f8fa7487ea2e3bf01c033c65eaf21a +F src/test_syscall.c 8313aa5d43989913c2dfd42b987e6ed29d6b8770 +F src/test_tclvar.c 0239df9e83f9adc7b21ae01dce20229dd8592e71 +F src/test_thread.c 30ae6818d21a168ef8cbceb9456411751c714cd9 +F src/test_vfs.c 2edd39d413301baf15c1d7384f21c2e8b3fca2dd F src/test_vfstrace.c bab9594adc976cbe696ff3970728830b4c5ed698 F src/test_windirent.c 8f5fada630348558d5745b334702f301da1ffc61 F src/test_windirent.h b12055cab6227f7be10f5c19296f67c60cc5e2a5 @@ -1457,7 +1457,7 @@ F tool/offsets.c fe4262fdfa378e8f5499a42136d17bf3b98f6091 F tool/omittest.tcl 34d7ac01fe4fd18e3637f64abe12c40eca0f6b97 F tool/opcodesum.tcl 740ed206ba8c5040018988129abbf3089a0ccf4a F tool/pagesig.c ff0ca355fd3c2398e933da5e22439bbff89b803b -F tool/replace.tcl 7727c60a04299b65a92f5e1590896fea0f25b9e0 +F tool/replace.tcl 3856f87247dde5418d16dac92fa4060813431778 F tool/restore_jrnl.tcl 6957a34f8f1f0f8285e07536225ec3b292a9024a F tool/rollback-test.c 9fc98427d1e23e84429d7e6d07d9094fbdec65a5 F tool/run-speed-test.sh f95d19fd669b68c4c38b6b475242841d47c66076 @@ -1508,10 +1508,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 9e2b26811452a5011d0a97a689636fa4409da856 -R 6c56defa4f9211ce028bec2ac1e13231 -T *branch * callbackConv -T *sym-callbackConv * -T -sym-trunk * +P 02b8040e1add02734d2dbc6c59737ab74ff8fb18 +R ccdbec6a43a33ea0f78bbd174bf27dd8 U mistachkin -Z d50c4a0ba4b8e38dec3c91619f068656 +Z 9a093adb6bae045a3c1e5e0de6859957 diff --git a/manifest.uuid b/manifest.uuid index 57781e18c1..8d4ac6e27c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -02b8040e1add02734d2dbc6c59737ab74ff8fb18 \ No newline at end of file +e8be3dfeabaa31b3490793cf8230faae1204be15 \ No newline at end of file diff --git a/src/tclsqlite.c b/src/tclsqlite.c index e559043c08..d26c622859 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -30,10 +30,14 @@ ** If requested, include the SQLite compiler options file for MSVC. */ #if defined(INCLUDE_MSVC_H) -#include "msvc.h" +# include "msvc.h" #endif -#include "tcl.h" +#if defined(INCLUDE_SQLITE_TCL_H) +# include "sqlite_tcl.h" +#else +# include "tcl.h" +#endif #include /* @@ -4123,7 +4127,7 @@ static void init_all(Tcl_Interp *interp){ Sqlitetesttclvar_Init(interp); Sqlitetestfs_Init(interp); SqlitetestThread_Init(interp); - SqlitetestOnefile_Init(interp); + SqlitetestOnefile_Init(); SqlitetestOsinst_Init(interp); Sqlitetestbackup_Init(interp); Sqlitetestintarray_Init(interp); diff --git a/src/test1.c b/src/test1.c index 35c43d0ef9..e1b4fc0f31 100644 --- a/src/test1.c +++ b/src/test1.c @@ -19,7 +19,11 @@ #endif #include "vdbeInt.h" -#include "tcl.h" +#if defined(INCLUDE_SQLITE_TCL_H) +# include "sqlite_tcl.h" +#else +# include "tcl.h" +#endif #include #include diff --git a/src/test2.c b/src/test2.c index d16ba5016a..8946196ff3 100644 --- a/src/test2.c +++ b/src/test2.c @@ -14,7 +14,11 @@ ** testing of the SQLite library. */ #include "sqliteInt.h" -#include "tcl.h" +#if defined(INCLUDE_SQLITE_TCL_H) +# include "sqlite_tcl.h" +#else +# include "tcl.h" +#endif #include #include #include diff --git a/src/test3.c b/src/test3.c index bfd7c30b65..f1b9f37924 100644 --- a/src/test3.c +++ b/src/test3.c @@ -15,7 +15,11 @@ */ #include "sqliteInt.h" #include "btreeInt.h" -#include "tcl.h" +#if defined(INCLUDE_SQLITE_TCL_H) +# include "sqlite_tcl.h" +#else +# include "tcl.h" +#endif #include #include diff --git a/src/test4.c b/src/test4.c index d689030303..85b521b060 100644 --- a/src/test4.c +++ b/src/test4.c @@ -12,7 +12,11 @@ ** Code for testing the SQLite library in a multithreaded environment. */ #include "sqliteInt.h" -#include "tcl.h" +#if defined(INCLUDE_SQLITE_TCL_H) +# include "sqlite_tcl.h" +#else +# include "tcl.h" +#endif #if SQLITE_OS_UNIX && SQLITE_THREADSAFE #include #include diff --git a/src/test5.c b/src/test5.c index 952e3325e5..2b49e408b6 100644 --- a/src/test5.c +++ b/src/test5.c @@ -17,7 +17,11 @@ */ #include "sqliteInt.h" #include "vdbeInt.h" -#include "tcl.h" +#if defined(INCLUDE_SQLITE_TCL_H) +# include "sqlite_tcl.h" +#else +# include "tcl.h" +#endif #include #include diff --git a/src/test6.c b/src/test6.c index 24fe725f78..e6eabf996a 100644 --- a/src/test6.c +++ b/src/test6.c @@ -16,7 +16,11 @@ */ #if SQLITE_TEST /* This file is used for testing only */ #include "sqliteInt.h" -#include "tcl.h" +#if defined(INCLUDE_SQLITE_TCL_H) +# include "sqlite_tcl.h" +#else +# include "tcl.h" +#endif #ifndef SQLITE_OMIT_DISKIO /* This file is a no-op if disk I/O is disabled */ diff --git a/src/test7.c b/src/test7.c index 6ba3631b41..d3b789e967 100644 --- a/src/test7.c +++ b/src/test7.c @@ -13,7 +13,11 @@ ** Derived from test4.c. */ #include "sqliteInt.h" -#include "tcl.h" +#if defined(INCLUDE_SQLITE_TCL_H) +# include "sqlite_tcl.h" +#else +# include "tcl.h" +#endif /* ** This test only works on UNIX with a SQLITE_THREADSAFE build that includes diff --git a/src/test8.c b/src/test8.c index fb781ac8fd..e635d5ed2c 100644 --- a/src/test8.c +++ b/src/test8.c @@ -14,7 +14,11 @@ ** testing of the SQLite library. */ #include "sqliteInt.h" -#include "tcl.h" +#if defined(INCLUDE_SQLITE_TCL_H) +# include "sqlite_tcl.h" +#else +# include "tcl.h" +#endif #include #include diff --git a/src/test9.c b/src/test9.c index e5993e8ff7..3c3629c0a7 100644 --- a/src/test9.c +++ b/src/test9.c @@ -15,7 +15,11 @@ ** as there is not much point in binding to Tcl. */ #include "sqliteInt.h" -#include "tcl.h" +#if defined(INCLUDE_SQLITE_TCL_H) +# include "sqlite_tcl.h" +#else +# include "tcl.h" +#endif #include #include diff --git a/src/test_async.c b/src/test_async.c index b0b943185b..8389e75dbd 100644 --- a/src/test_async.c +++ b/src/test_async.c @@ -15,7 +15,11 @@ */ #define TCL_THREADS -#include +#if defined(INCLUDE_SQLITE_TCL_H) +# include "sqlite_tcl.h" +#else +# include "tcl.h" +#endif #ifdef SQLITE_ENABLE_ASYNCIO diff --git a/src/test_autoext.c b/src/test_autoext.c index a5236d2390..b536cd7321 100644 --- a/src/test_autoext.c +++ b/src/test_autoext.c @@ -11,7 +11,11 @@ ************************************************************************* ** Test extension for testing the sqlite3_auto_extension() function. */ -#include "tcl.h" +#if defined(INCLUDE_SQLITE_TCL_H) +# include "sqlite_tcl.h" +#else +# include "tcl.h" +#endif #include "sqlite3ext.h" #ifndef SQLITE_OMIT_LOAD_EXTENSION diff --git a/src/test_backup.c b/src/test_backup.c index 6b4d6b9b1c..3e91f1f219 100644 --- a/src/test_backup.c +++ b/src/test_backup.c @@ -13,7 +13,11 @@ ** */ -#include "tcl.h" +#if defined(INCLUDE_SQLITE_TCL_H) +# include "sqlite_tcl.h" +#else +# include "tcl.h" +#endif #include "sqlite3.h" #include diff --git a/src/test_bestindex.c b/src/test_bestindex.c index f6f9d3eaf8..8e0ff00b52 100644 --- a/src/test_bestindex.c +++ b/src/test_bestindex.c @@ -93,7 +93,11 @@ #include "sqliteInt.h" -#include "tcl.h" +#if defined(INCLUDE_SQLITE_TCL_H) +# include "sqlite_tcl.h" +#else +# include "tcl.h" +#endif #ifndef SQLITE_OMIT_VIRTUALTABLE diff --git a/src/test_blob.c b/src/test_blob.c index ec2227bb39..703664190b 100644 --- a/src/test_blob.c +++ b/src/test_blob.c @@ -12,7 +12,11 @@ ** */ #include "sqliteInt.h" -#include "tcl.h" +#if defined(INCLUDE_SQLITE_TCL_H) +# include "sqlite_tcl.h" +#else +# include "tcl.h" +#endif #include #include #include diff --git a/src/test_btree.c b/src/test_btree.c index dfe77051b6..46860afb30 100644 --- a/src/test_btree.c +++ b/src/test_btree.c @@ -14,7 +14,11 @@ ** testing of the SQLite library. */ #include "btreeInt.h" -#include +#if defined(INCLUDE_SQLITE_TCL_H) +# include "sqlite_tcl.h" +#else +# include "tcl.h" +#endif /* ** Usage: sqlite3_shared_cache_report diff --git a/src/test_config.c b/src/test_config.c index 9ce9bfcaca..1e68e58d8d 100644 --- a/src/test_config.c +++ b/src/test_config.c @@ -24,7 +24,11 @@ # include "os_win.h" #endif -#include "tcl.h" +#if defined(INCLUDE_SQLITE_TCL_H) +# include "sqlite_tcl.h" +#else +# include "tcl.h" +#endif #include #include diff --git a/src/test_demovfs.c b/src/test_demovfs.c index 9410a309a6..9cc0eb0309 100644 --- a/src/test_demovfs.c +++ b/src/test_demovfs.c @@ -641,7 +641,11 @@ sqlite3_vfs *sqlite3_demovfs(void){ #ifdef SQLITE_TEST -#include +#if defined(INCLUDE_SQLITE_TCL_H) +# include "sqlite_tcl.h" +#else +# include "tcl.h" +#endif #if SQLITE_OS_UNIX static int register_demovfs( diff --git a/src/test_fs.c b/src/test_fs.c index 32026d0f38..329594a5ab 100644 --- a/src/test_fs.c +++ b/src/test_fs.c @@ -62,7 +62,11 @@ ** SELECT * FROM fstree WHERE path LIKE '/home/dan/sqlite/%' */ #include "sqliteInt.h" -#include "tcl.h" +#if defined(INCLUDE_SQLITE_TCL_H) +# include "sqlite_tcl.h" +#else +# include "tcl.h" +#endif #include #include diff --git a/src/test_func.c b/src/test_func.c index 579177b70c..08ea98fb7a 100644 --- a/src/test_func.c +++ b/src/test_func.c @@ -13,7 +13,11 @@ ** implements new SQL functions used by the test scripts. */ #include "sqlite3.h" -#include "tcl.h" +#if defined(INCLUDE_SQLITE_TCL_H) +# include "sqlite_tcl.h" +#else +# include "tcl.h" +#endif #include #include #include diff --git a/src/test_hexio.c b/src/test_hexio.c index b20b5ce730..88f5ed7bfa 100644 --- a/src/test_hexio.c +++ b/src/test_hexio.c @@ -18,7 +18,11 @@ ** easier and safer to build our own mechanism. */ #include "sqliteInt.h" -#include "tcl.h" +#if defined(INCLUDE_SQLITE_TCL_H) +# include "sqlite_tcl.h" +#else +# include "tcl.h" +#endif #include #include #include diff --git a/src/test_init.c b/src/test_init.c index 502d95c052..c66b5785d0 100644 --- a/src/test_init.c +++ b/src/test_init.c @@ -27,7 +27,11 @@ #include "sqliteInt.h" #include -#include +#if defined(INCLUDE_SQLITE_TCL_H) +# include "sqlite_tcl.h" +#else +# include "tcl.h" +#endif static struct Wrapped { sqlite3_pcache_methods2 pcache; diff --git a/src/test_intarray.c b/src/test_intarray.c index 70e34db3e1..c27b4597c0 100644 --- a/src/test_intarray.c +++ b/src/test_intarray.c @@ -270,7 +270,11 @@ SQLITE_API int sqlite3_intarray_bind( ** Everything below is interface for testing this module. */ #ifdef SQLITE_TEST -#include +#if defined(INCLUDE_SQLITE_TCL_H) +# include "sqlite_tcl.h" +#else +# include "tcl.h" +#endif /* ** Routines to encode and decode pointers diff --git a/src/test_malloc.c b/src/test_malloc.c index 37612561eb..66d8a881ba 100644 --- a/src/test_malloc.c +++ b/src/test_malloc.c @@ -14,7 +14,11 @@ ** memory allocation subsystem. */ #include "sqliteInt.h" -#include "tcl.h" +#if defined(INCLUDE_SQLITE_TCL_H) +# include "sqlite_tcl.h" +#else +# include "tcl.h" +#endif #include #include #include diff --git a/src/test_multiplex.c b/src/test_multiplex.c index ba4e61b090..dffdb44941 100644 --- a/src/test_multiplex.c +++ b/src/test_multiplex.c @@ -1229,7 +1229,11 @@ int sqlite3_multiplex_shutdown(int eForce){ /***************************** Test Code ***********************************/ #ifdef SQLITE_TEST -#include +#if defined(INCLUDE_SQLITE_TCL_H) +# include "sqlite_tcl.h" +#else +# include "tcl.h" +#endif extern const char *sqlite3ErrName(int); diff --git a/src/test_mutex.c b/src/test_mutex.c index 995b89a4c6..22375197b7 100644 --- a/src/test_mutex.c +++ b/src/test_mutex.c @@ -12,7 +12,11 @@ ** This file contains test logic for the sqlite3_mutex interfaces. */ -#include "tcl.h" +#if defined(INCLUDE_SQLITE_TCL_H) +# include "sqlite_tcl.h" +#else +# include "tcl.h" +#endif #include "sqlite3.h" #include "sqliteInt.h" #include diff --git a/src/test_osinst.c b/src/test_osinst.c index e51ce77ef8..5ab8ed5c93 100644 --- a/src/test_osinst.c +++ b/src/test_osinst.c @@ -1104,7 +1104,11 @@ int sqlite3_vfslog_register(sqlite3 *db){ #if defined(SQLITE_TEST) || defined(TCLSH) -#include +#if defined(INCLUDE_SQLITE_TCL_H) +# include "sqlite_tcl.h" +#else +# include "tcl.h" +#endif static int test_vfslog( void *clientData, diff --git a/src/test_quota.c b/src/test_quota.c index e8e0b34072..8ea48e5b53 100644 --- a/src/test_quota.c +++ b/src/test_quota.c @@ -1278,7 +1278,11 @@ int sqlite3_quota_remove(const char *zFilename){ /***************************** Test Code ***********************************/ #ifdef SQLITE_TEST -#include +#if defined(INCLUDE_SQLITE_TCL_H) +# include "sqlite_tcl.h" +#else +# include "tcl.h" +#endif /* ** Argument passed to a TCL quota-over-limit callback. diff --git a/src/test_rtree.c b/src/test_rtree.c index 797ec0026c..1f15566f97 100644 --- a/src/test_rtree.c +++ b/src/test_rtree.c @@ -14,7 +14,11 @@ */ #include "sqlite3.h" -#include +#if defined(INCLUDE_SQLITE_TCL_H) +# include "sqlite_tcl.h" +#else +# include "tcl.h" +#endif /* Solely for the UNUSED_PARAMETER() macro. */ #include "sqliteInt.h" @@ -353,7 +357,11 @@ static int bfs_query_func(sqlite3_rtree_query_info *p){ *************************************************************************/ #include -#include "tcl.h" +#if defined(INCLUDE_SQLITE_TCL_H) +# include "sqlite_tcl.h" +#else +# include "tcl.h" +#endif typedef struct Cube Cube; struct Cube { diff --git a/src/test_schema.c b/src/test_schema.c index 4ee18193b0..f2bd3b3520 100644 --- a/src/test_schema.c +++ b/src/test_schema.c @@ -35,10 +35,14 @@ ** to be compiled into an sqlite dynamic extension. */ #ifdef SQLITE_TEST - #include "sqliteInt.h" - #include "tcl.h" +# include "sqliteInt.h" +# if defined(INCLUDE_SQLITE_TCL_H) +# include "sqlite_tcl.h" +# else +# include "tcl.h" +# endif #else - #include "sqlite3ext.h" +# include "sqlite3ext.h" SQLITE_EXTENSION_INIT1 #endif diff --git a/src/test_superlock.c b/src/test_superlock.c index cac789842d..cad5b51f0f 100644 --- a/src/test_superlock.c +++ b/src/test_superlock.c @@ -256,7 +256,11 @@ int sqlite3demo_superlock( #ifdef SQLITE_TEST -#include +#if defined(INCLUDE_SQLITE_TCL_H) +# include "sqlite_tcl.h" +#else +# include "tcl.h" +#endif struct InterpAndScript { Tcl_Interp *interp; diff --git a/src/test_syscall.c b/src/test_syscall.c index f1d5c61bc3..eab9895186 100644 --- a/src/test_syscall.c +++ b/src/test_syscall.c @@ -76,7 +76,11 @@ #include "sqliteInt.h" #include "sqlite3.h" -#include "tcl.h" +#if defined(INCLUDE_SQLITE_TCL_H) +# include "sqlite_tcl.h" +#else +# include "tcl.h" +#endif #include #include #include diff --git a/src/test_tclvar.c b/src/test_tclvar.c index 63ed394734..95a065c853 100644 --- a/src/test_tclvar.c +++ b/src/test_tclvar.c @@ -17,7 +17,11 @@ ** access to TCL variables. */ #include "sqliteInt.h" -#include "tcl.h" +#if defined(INCLUDE_SQLITE_TCL_H) +# include "sqlite_tcl.h" +#else +# include "tcl.h" +#endif #include #include diff --git a/src/test_thread.c b/src/test_thread.c index a4d96e1942..1fd646e769 100644 --- a/src/test_thread.c +++ b/src/test_thread.c @@ -16,7 +16,11 @@ */ #include "sqliteInt.h" -#include +#if defined(INCLUDE_SQLITE_TCL_H) +# include "sqlite_tcl.h" +#else +# include "tcl.h" +#endif #if SQLITE_THREADSAFE diff --git a/src/test_vfs.c b/src/test_vfs.c index b476a42cb4..acc1c6682e 100644 --- a/src/test_vfs.c +++ b/src/test_vfs.c @@ -28,7 +28,11 @@ #include "sqlite3.h" #include "sqliteInt.h" -#include +#if defined(INCLUDE_SQLITE_TCL_H) +# include "sqlite_tcl.h" +#else +# include "tcl.h" +#endif typedef struct Testvfs Testvfs; typedef struct TestvfsShm TestvfsShm; diff --git a/tool/replace.tcl b/tool/replace.tcl index b01a83accb..1ecc6dc7b5 100644 --- a/tool/replace.tcl +++ b/tool/replace.tcl @@ -7,13 +7,14 @@ set mode [string tolower [lindex $argv 0]] set from [lindex $argv 1] set to [lindex $argv 2] -if {$mode ni [list exact include]} {exit 1} +if {$mode ni [list exact regsub include]} {exit 1} if {[string length $from]==0} {exit 2} while {![eof stdin]} { set line [gets stdin] if {[eof stdin]} break switch -exact $mode { exact {set line [string map [list $from $to] $line]} + regsub {regsub -all -- $from $line $to line} include {if {[regsub -all -- $from $line $to line]==0} continue} } puts stdout $line From 4194ff65989d436a22699faac29e6f98d1beb414 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 28 Jul 2016 15:09:02 +0000 Subject: [PATCH 0614/1484] Change mksqlite3h.tcl to automatically insert the SQLITE_CALLBACK calling convention macros. FossilOrigin-Name: 11ab9c9ab562df98c20abf126a8bac178aef77a8 --- manifest | 16 +-- manifest.uuid | 2 +- src/sqlite.h.in | 326 ++++++++++++++++++++------------------------ tool/mksqlite3h.tcl | 3 + 4 files changed, 159 insertions(+), 188 deletions(-) diff --git a/manifest b/manifest index 8f0151d5f2..49f48174ea 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Allow\sthe\s'testfixture.exe'\starget\sto\sbe\scompiled\swith\sthe\s__stdcall\scalling\sconvention. -D 2016-07-28T14:37:04.758 +C Change\smksqlite3h.tcl\sto\sautomatically\sinsert\sthe\sSQLITE_CALLBACK\scalling\nconvention\smacros. +D 2016-07-28T15:09:02.696 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc da4c9f5bc46f6f12d7313d12be18a2d2c55e06c0 @@ -385,7 +385,7 @@ F src/resolve.c cca3aa77b95706df5d635a2141a4d1de60ae6598 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c f3c6e9065fb34f6a23af27ec7f1f717ffbfc2ee4 F src/shell.c 9351fc6de11e1d908648c0a92d85627138e3dee5 -F src/sqlite.h.in a0760a3f7b1939e395a3e74d245e5bb03cd54fb1 +F src/sqlite.h.in a03063e698a43cc5c996cd341f39439a6ce58304 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 46f300b6e300e0fa916d7d58c44b53415b8471a9 F src/sqliteInt.h d25c18c1272a7811e2569c39bfc2fca96156eead @@ -1450,7 +1450,7 @@ F tool/mkpragmatab.tcl f0d5bb266d1d388cf86fce5ba01a891e95d72d41 F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 F tool/mksqlite3c-noext.tcl aa58ea3be311c81821c2cd3209f55e46b07ab656 F tool/mksqlite3c.tcl a52ead27e2ac5d4b616e945a0601f628f4328329 -F tool/mksqlite3h.tcl fab97967314e63384a3ed23fd35f0d8188352400 +F tool/mksqlite3h.tcl abaf6af11e184c0b69f117fc47ecfa351d81c219 F tool/mksqlite3internalh.tcl eb994013e833359137eb53a55acdad0b5ae1049b F tool/mkvsix.tcl 4abcaf3267171b2faadaf9b82a0dfbaa6e98f8b7 F tool/offsets.c fe4262fdfa378e8f5499a42136d17bf3b98f6091 @@ -1508,7 +1508,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 02b8040e1add02734d2dbc6c59737ab74ff8fb18 -R ccdbec6a43a33ea0f78bbd174bf27dd8 -U mistachkin -Z 9a093adb6bae045a3c1e5e0de6859957 +P e8be3dfeabaa31b3490793cf8230faae1204be15 +R 44253432508e9739e51133f1558c85ed +U drh +Z 863aa68feeed694e590c235a245cfae1 diff --git a/manifest.uuid b/manifest.uuid index 8d4ac6e27c..617643d254 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e8be3dfeabaa31b3490793cf8230faae1204be15 \ No newline at end of file +11ab9c9ab562df98c20abf126a8bac178aef77a8 \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 009f080a86..02ae22c346 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -67,7 +67,6 @@ extern "C" { # define SQLITE_SYSAPI #endif - /* ** These no-op macros are used in front of interfaces to mark those ** interfaces as either deprecated or experimental. New applications @@ -328,7 +327,7 @@ int sqlite3_close_v2(sqlite3*); ** This is legacy and deprecated. It is included for historical ** compatibility and is not documented. */ -typedef int (SQLITE_CALLBACK *sqlite3_callback)(void*,int,char**, char**); +typedef int (*sqlite3_callback)(void*,int,char**, char**); /* ** CAPI3REF: One-Step Query Execution Interface @@ -395,7 +394,7 @@ typedef int (SQLITE_CALLBACK *sqlite3_callback)(void*,int,char**, char**); int sqlite3_exec( sqlite3*, /* An open database */ const char *sql, /* SQL to be evaluated */ - int (SQLITE_CALLBACK *callback)(void*,int,char**,char**), /* Callback func */ + int (*callback)(void*,int,char**,char**), /* Callback function */ void *, /* 1st argument to callback */ char **errmsg /* Error msg written here */ ); @@ -743,30 +742,26 @@ struct sqlite3_file { typedef struct sqlite3_io_methods sqlite3_io_methods; struct sqlite3_io_methods { int iVersion; - int (SQLITE_CALLBACK *xClose)(sqlite3_file*); - int (SQLITE_CALLBACK *xRead)(sqlite3_file*, void*, int iAmt, - sqlite3_int64 iOfst); - int (SQLITE_CALLBACK *xWrite)(sqlite3_file*, const void*, int iAmt, - sqlite3_int64 iOfst); - int (SQLITE_CALLBACK *xTruncate)(sqlite3_file*, sqlite3_int64 size); - int (SQLITE_CALLBACK *xSync)(sqlite3_file*, int flags); - int (SQLITE_CALLBACK *xFileSize)(sqlite3_file*, sqlite3_int64 *pSize); - int (SQLITE_CALLBACK *xLock)(sqlite3_file*, int); - int (SQLITE_CALLBACK *xUnlock)(sqlite3_file*, int); - int (SQLITE_CALLBACK *xCheckReservedLock)(sqlite3_file*, int *pResOut); - int (SQLITE_CALLBACK *xFileControl)(sqlite3_file*, int op, void *pArg); - int (SQLITE_CALLBACK *xSectorSize)(sqlite3_file*); - int (SQLITE_CALLBACK *xDeviceCharacteristics)(sqlite3_file*); + int (*xClose)(sqlite3_file*); + int (*xRead)(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst); + int (*xWrite)(sqlite3_file*, const void*, int iAmt, sqlite3_int64 iOfst); + int (*xTruncate)(sqlite3_file*, sqlite3_int64 size); + int (*xSync)(sqlite3_file*, int flags); + int (*xFileSize)(sqlite3_file*, sqlite3_int64 *pSize); + int (*xLock)(sqlite3_file*, int); + int (*xUnlock)(sqlite3_file*, int); + int (*xCheckReservedLock)(sqlite3_file*, int *pResOut); + int (*xFileControl)(sqlite3_file*, int op, void *pArg); + int (*xSectorSize)(sqlite3_file*); + int (*xDeviceCharacteristics)(sqlite3_file*); /* Methods above are valid for version 1 */ - int (SQLITE_CALLBACK *xShmMap)(sqlite3_file*, int iPg, int pgsz, int, - void volatile**); - int (SQLITE_CALLBACK *xShmLock)(sqlite3_file*, int offset, int n, int flags); - void (SQLITE_CALLBACK *xShmBarrier)(sqlite3_file*); - int (SQLITE_CALLBACK *xShmUnmap)(sqlite3_file*, int deleteFlag); + int (*xShmMap)(sqlite3_file*, int iPg, int pgsz, int, void volatile**); + int (*xShmLock)(sqlite3_file*, int offset, int n, int flags); + void (*xShmBarrier)(sqlite3_file*); + int (*xShmUnmap)(sqlite3_file*, int deleteFlag); /* Methods above are valid for version 2 */ - int (SQLITE_CALLBACK *xFetch)(sqlite3_file*, sqlite3_int64 iOfst, int iAmt, - void **pp); - int (SQLITE_CALLBACK *xUnfetch)(sqlite3_file*, sqlite3_int64 iOfst, void *p); + int (*xFetch)(sqlite3_file*, sqlite3_int64 iOfst, int iAmt, void **pp); + int (*xUnfetch)(sqlite3_file*, sqlite3_int64 iOfst, void *p); /* Methods above are valid for version 3 */ /* Additional methods may be added in future releases */ }; @@ -1208,7 +1203,7 @@ typedef struct sqlite3_mutex sqlite3_mutex; ** any of these methods if the iVersion of the VFS is less than 3. */ typedef struct sqlite3_vfs sqlite3_vfs; -typedef void (SQLITE_SYSAPI *sqlite3_syscall_ptr)(void); +typedef void (*sqlite3_syscall_ptr)(void); struct sqlite3_vfs { int iVersion; /* Structure version number (currently 3) */ int szOsFile; /* Size of subclassed sqlite3_file */ @@ -1216,37 +1211,31 @@ struct sqlite3_vfs { sqlite3_vfs *pNext; /* Next registered VFS */ const char *zName; /* Name of this virtual file system */ void *pAppData; /* Pointer to application-specific data */ - int (SQLITE_CALLBACK *xOpen)(sqlite3_vfs*, const char *zName, sqlite3_file*, + int (*xOpen)(sqlite3_vfs*, const char *zName, sqlite3_file*, int flags, int *pOutFlags); - int (SQLITE_CALLBACK *xDelete)(sqlite3_vfs*, const char *zName, int syncDir); - int (SQLITE_CALLBACK *xAccess)(sqlite3_vfs*, const char *zName, int flags, - int *pResOut); - int (SQLITE_CALLBACK *xFullPathname)(sqlite3_vfs*, const char *zName, - int nOut, char *zOut); - void *(SQLITE_CALLBACK *xDlOpen)(sqlite3_vfs*, const char *zFilename); - void (SQLITE_CALLBACK *xDlError)(sqlite3_vfs*, int nByte, char *zErrMsg); - void (*(SQLITE_CALLBACK *xDlSym)(sqlite3_vfs*,void*, - const char *zSymbol))(void); - void (SQLITE_CALLBACK *xDlClose)(sqlite3_vfs*, void*); - int (SQLITE_CALLBACK *xRandomness)(sqlite3_vfs*, int nByte, char *zOut); - int (SQLITE_CALLBACK *xSleep)(sqlite3_vfs*, int microseconds); - int (SQLITE_CALLBACK *xCurrentTime)(sqlite3_vfs*, double*); - int (SQLITE_CALLBACK *xGetLastError)(sqlite3_vfs*, int, char *); + int (*xDelete)(sqlite3_vfs*, const char *zName, int syncDir); + int (*xAccess)(sqlite3_vfs*, const char *zName, int flags, int *pResOut); + int (*xFullPathname)(sqlite3_vfs*, const char *zName, int nOut, char *zOut); + void *(*xDlOpen)(sqlite3_vfs*, const char *zFilename); + void (*xDlError)(sqlite3_vfs*, int nByte, char *zErrMsg); + void (*(*xDlSym)(sqlite3_vfs*,void*, const char *zSymbol))(void); + void (*xDlClose)(sqlite3_vfs*, void*); + int (*xRandomness)(sqlite3_vfs*, int nByte, char *zOut); + int (*xSleep)(sqlite3_vfs*, int microseconds); + int (*xCurrentTime)(sqlite3_vfs*, double*); + int (*xGetLastError)(sqlite3_vfs*, int, char *); /* ** The methods above are in version 1 of the sqlite_vfs object ** definition. Those that follow are added in version 2 or later */ - int (SQLITE_CALLBACK *xCurrentTimeInt64)(sqlite3_vfs*, sqlite3_int64*); + int (*xCurrentTimeInt64)(sqlite3_vfs*, sqlite3_int64*); /* ** The methods above are in versions 1 and 2 of the sqlite_vfs object. ** Those below are for version 3 and greater. */ - int (SQLITE_CALLBACK *xSetSystemCall)(sqlite3_vfs*, const char *zName, - sqlite3_syscall_ptr); - sqlite3_syscall_ptr (SQLITE_CALLBACK *xGetSystemCall)(sqlite3_vfs*, - const char *zName); - const char *(SQLITE_CALLBACK *xNextSystemCall)(sqlite3_vfs*, - const char *zName); + int (*xSetSystemCall)(sqlite3_vfs*, const char *zName, sqlite3_syscall_ptr); + sqlite3_syscall_ptr (*xGetSystemCall)(sqlite3_vfs*, const char *zName); + const char *(*xNextSystemCall)(sqlite3_vfs*, const char *zName); /* ** The methods above are in versions 1 through 3 of the sqlite_vfs object. ** New fields may be appended in future versions. The iVersion @@ -1513,13 +1502,13 @@ int sqlite3_db_config(sqlite3*, int op, ...); */ typedef struct sqlite3_mem_methods sqlite3_mem_methods; struct sqlite3_mem_methods { - void *(SQLITE_CALLBACK *xMalloc)(int); /* Memory allocation function */ - void (SQLITE_CALLBACK *xFree)(void*); /* Free a prior allocation */ - void *(SQLITE_CALLBACK *xRealloc)(void*,int); /* Resize an allocation */ - int (SQLITE_CALLBACK *xSize)(void*); /* Return the size of an allocation */ - int (SQLITE_CALLBACK *xRoundup)(int); /* Round up size to allocation size */ - int (SQLITE_CALLBACK *xInit)(void*); /* Initialize the memory allocator */ - void (SQLITE_CALLBACK *xShutdown)(void*); /* Deinitialize memory allocator */ + void *(*xMalloc)(int); /* Memory allocation function */ + void (*xFree)(void*); /* Free a prior allocation */ + void *(*xRealloc)(void*,int); /* Resize an allocation */ + int (*xSize)(void*); /* Return the size of an allocation */ + int (*xRoundup)(int); /* Round up request size to allocation size */ + int (*xInit)(void*); /* Initialize the memory allocator */ + void (*xShutdown)(void*); /* Deinitialize the memory allocator */ void *pAppData; /* Argument to xInit() and xShutdown() */ }; @@ -2253,7 +2242,7 @@ int sqlite3_complete16(const void *sql); ** A busy handler must not close the database connection ** or [prepared statement] that invoked the busy handler. */ -int sqlite3_busy_handler(sqlite3*, int(SQLITE_CALLBACK *)(void*,int), void*); +int sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*); /* ** CAPI3REF: Set A Busy Timeout @@ -2697,8 +2686,7 @@ void sqlite3_randomness(int N, void *P); */ int sqlite3_set_authorizer( sqlite3*, - int (SQLITE_CALLBACK *xAuth)(void*,int,const char*,const char*,const char*, - const char*), + int (*xAuth)(void*,int,const char*,const char*,const char*,const char*), void *pUserData ); @@ -2805,9 +2793,9 @@ int sqlite3_set_authorizer( ** subject to change in future versions of SQLite. */ SQLITE_DEPRECATED void *sqlite3_trace(sqlite3*, - void(SQLITE_CALLBACK *xTrace)(void*,const char*), void*); + void(*xTrace)(void*,const char*), void*); SQLITE_DEPRECATED void *sqlite3_profile(sqlite3*, - void(SQLITE_CALLBACK *xProfile)(void*,const char*,sqlite3_uint64), void*); + void(*xProfile)(void*,const char*,sqlite3_uint64), void*); /* ** CAPI3REF: SQL Trace Event Codes @@ -2898,7 +2886,7 @@ SQLITE_DEPRECATED void *sqlite3_profile(sqlite3*, int sqlite3_trace_v2( sqlite3*, unsigned uMask, - int(SQLITE_CALLBACK *xCallback)(unsigned,void*,void*,void*), + int(*xCallback)(unsigned,void*,void*,void*), void *pCtx ); @@ -2934,7 +2922,7 @@ int sqlite3_trace_v2( ** database connections for the meaning of "modify" in this paragraph. ** */ -void sqlite3_progress_handler(sqlite3*,int,int(SQLITE_CALLBACK *)(void*),void*); +void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); /* ** CAPI3REF: Opening A New Database Connection @@ -3765,20 +3753,17 @@ typedef struct sqlite3_context sqlite3_context; ** See also: [sqlite3_bind_parameter_count()], ** [sqlite3_bind_parameter_name()], and [sqlite3_bind_parameter_index()]. */ -int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, - void(SQLITE_CALLBACK *)(void*)); +int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*)); int sqlite3_bind_blob64(sqlite3_stmt*, int, const void*, sqlite3_uint64, - void(SQLITE_CALLBACK *)(void*)); + void(*)(void*)); int sqlite3_bind_double(sqlite3_stmt*, int, double); int sqlite3_bind_int(sqlite3_stmt*, int, int); int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64); int sqlite3_bind_null(sqlite3_stmt*, int); -int sqlite3_bind_text(sqlite3_stmt*,int,const char*,int, - void(SQLITE_CALLBACK *)(void*)); -int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, - void(SQLITE_CALLBACK *)(void*)); +int sqlite3_bind_text(sqlite3_stmt*,int,const char*,int,void(*)(void*)); +int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*)); int sqlite3_bind_text64(sqlite3_stmt*, int, const char*, sqlite3_uint64, - void(SQLITE_CALLBACK *)(void*), unsigned char encoding); + void(*)(void*), unsigned char encoding); int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*); int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n); int sqlite3_bind_zeroblob64(sqlite3_stmt*, int, sqlite3_uint64); @@ -4446,9 +4431,9 @@ int sqlite3_create_function( int nArg, int eTextRep, void *pApp, - void (SQLITE_CALLBACK *xFunc)(sqlite3_context*,int,sqlite3_value**), - void (SQLITE_CALLBACK *xStep)(sqlite3_context*,int,sqlite3_value**), - void (SQLITE_CALLBACK *xFinal)(sqlite3_context*) + void (*xFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*) ); int sqlite3_create_function16( sqlite3 *db, @@ -4456,9 +4441,9 @@ int sqlite3_create_function16( int nArg, int eTextRep, void *pApp, - void (SQLITE_CALLBACK *xFunc)(sqlite3_context*,int,sqlite3_value**), - void (SQLITE_CALLBACK *xStep)(sqlite3_context*,int,sqlite3_value**), - void (SQLITE_CALLBACK *xFinal)(sqlite3_context*) + void (*xFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*) ); int sqlite3_create_function_v2( sqlite3 *db, @@ -4466,10 +4451,10 @@ int sqlite3_create_function_v2( int nArg, int eTextRep, void *pApp, - void (SQLITE_CALLBACK *xFunc)(sqlite3_context*,int,sqlite3_value**), - void (SQLITE_CALLBACK *xStep)(sqlite3_context*,int,sqlite3_value**), - void (SQLITE_CALLBACK *xFinal)(sqlite3_context*), - void (SQLITE_CALLBACK *xDestroy)(void*) + void (*xFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*), + void(*xDestroy)(void*) ); /* @@ -4511,9 +4496,8 @@ SQLITE_DEPRECATED int sqlite3_expired(sqlite3_stmt*); SQLITE_DEPRECATED int sqlite3_transfer_bindings(sqlite3_stmt*, sqlite3_stmt*); SQLITE_DEPRECATED int sqlite3_global_recover(void); SQLITE_DEPRECATED void sqlite3_thread_cleanup(void); -SQLITE_DEPRECATED int sqlite3_memory_alarm( - void(SQLITE_CALLBACK *)(void*,sqlite3_int64,int), - void*,sqlite3_int64); +SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int), + void*,sqlite3_int64); #endif /* @@ -4732,8 +4716,7 @@ sqlite3 *sqlite3_context_db_handle(sqlite3_context*); ** the SQL function is running. */ void *sqlite3_get_auxdata(sqlite3_context*, int N); -void sqlite3_set_auxdata(sqlite3_context*, int N, void*, - void (SQLITE_CALLBACK *)(void*)); +void sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(void*)); /* @@ -4750,7 +4733,7 @@ void sqlite3_set_auxdata(sqlite3_context*, int N, void*, ** The typedef is necessary to work around problems in certain ** C++ compilers. */ -typedef void (SQLITE_CALLBACK *sqlite3_destructor_type)(void*); +typedef void (*sqlite3_destructor_type)(void*); #define SQLITE_STATIC ((sqlite3_destructor_type)0) #define SQLITE_TRANSIENT ((sqlite3_destructor_type)-1) @@ -4869,10 +4852,9 @@ typedef void (SQLITE_CALLBACK *sqlite3_destructor_type)(void*); ** than the one containing the application-defined function that received ** the [sqlite3_context] pointer, the results are undefined. */ -void sqlite3_result_blob(sqlite3_context*, const void*, int, - void(SQLITE_CALLBACK *)(void*)); +void sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*)); void sqlite3_result_blob64(sqlite3_context*,const void*, - sqlite3_uint64,void(SQLITE_CALLBACK *)(void*)); + sqlite3_uint64,void(*)(void*)); void sqlite3_result_double(sqlite3_context*, double); void sqlite3_result_error(sqlite3_context*, const char*, int); void sqlite3_result_error16(sqlite3_context*, const void*, int); @@ -4882,17 +4864,12 @@ void sqlite3_result_error_code(sqlite3_context*, int); void sqlite3_result_int(sqlite3_context*, int); void sqlite3_result_int64(sqlite3_context*, sqlite3_int64); void sqlite3_result_null(sqlite3_context*); -void sqlite3_result_text(sqlite3_context*, const char*, int, - void(SQLITE_CALLBACK *)(void*)); +void sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*)); void sqlite3_result_text64(sqlite3_context*, const char*,sqlite3_uint64, - void(SQLITE_CALLBACK *)(void*), - unsigned char encoding); -void sqlite3_result_text16(sqlite3_context*, const void*, int, - void(SQLITE_CALLBACK *)(void*)); -void sqlite3_result_text16le(sqlite3_context*, const void*, int, - void(SQLITE_CALLBACK *)(void*)); -void sqlite3_result_text16be(sqlite3_context*, const void*, int, - void(SQLITE_CALLBACK *)(void*)); + void(*)(void*), unsigned char encoding); +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_zeroblob(sqlite3_context*, int n); int sqlite3_result_zeroblob64(sqlite3_context*, sqlite3_uint64 n); @@ -4997,22 +4974,22 @@ int sqlite3_create_collation( const char *zName, int eTextRep, void *pArg, - int(SQLITE_CALLBACK *xCompare)(void*,int,const void*,int,const void*) + int(*xCompare)(void*,int,const void*,int,const void*) ); int sqlite3_create_collation_v2( sqlite3*, const char *zName, int eTextRep, void *pArg, - int(SQLITE_CALLBACK *xCompare)(void*,int,const void*,int,const void*), - void(SQLITE_CALLBACK *xDestroy)(void*) + int(*xCompare)(void*,int,const void*,int,const void*), + void(*xDestroy)(void*) ); int sqlite3_create_collation16( sqlite3*, const void *zName, int eTextRep, void *pArg, - int(SQLITE_CALLBACK *xCompare)(void*,int,const void*,int,const void*) + int(*xCompare)(void*,int,const void*,int,const void*) ); /* @@ -5045,12 +5022,12 @@ int sqlite3_create_collation16( int sqlite3_collation_needed( sqlite3*, void*, - void(SQLITE_CALLBACK *)(void*,sqlite3*,int eTextRep,const char*) + void(*)(void*,sqlite3*,int eTextRep,const char*) ); int sqlite3_collation_needed16( sqlite3*, void*, - void(SQLITE_CALLBACK *)(void*,sqlite3*,int eTextRep,const void*) + void(*)(void*,sqlite3*,int eTextRep,const void*) ); #ifdef SQLITE_HAS_CODEC @@ -5349,8 +5326,8 @@ sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt); ** ** See also the [sqlite3_update_hook()] interface. */ -void *sqlite3_commit_hook(sqlite3*, int(SQLITE_CALLBACK *)(void*), void*); -void *sqlite3_rollback_hook(sqlite3*, void(SQLITE_CALLBACK *)(void *), void*); +void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*); +void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*); /* ** CAPI3REF: Data Change Notification Callbacks @@ -5403,7 +5380,7 @@ void *sqlite3_rollback_hook(sqlite3*, void(SQLITE_CALLBACK *)(void *), void*); */ void *sqlite3_update_hook( sqlite3*, - void(SQLITE_CALLBACK *)(void *,int ,char const *,char const *,sqlite3_int64), + void(*)(void *,int ,char const *,char const *,sqlite3_int64), void* ); @@ -5730,7 +5707,7 @@ int sqlite3_enable_load_extension(sqlite3 *db, int onoff); ** See also: [sqlite3_reset_auto_extension()] ** and [sqlite3_cancel_auto_extension()] */ -int sqlite3_auto_extension(void (SQLITE_CALLBACK *xEntryPoint)(void)); +int sqlite3_auto_extension(void (*xEntryPoint)(void)); /* ** CAPI3REF: Cancel Automatic Extension Loading @@ -5742,7 +5719,7 @@ int sqlite3_auto_extension(void (SQLITE_CALLBACK *xEntryPoint)(void)); ** unregistered and it returns 0 if X was not on the list of initialization ** routines. */ -int sqlite3_cancel_auto_extension(void (SQLITE_CALLBACK *xEntryPoint)(void)); +int sqlite3_cancel_auto_extension(void (*xEntryPoint)(void)); /* ** CAPI3REF: Reset Automatic Extension Loading @@ -5787,41 +5764,37 @@ typedef struct sqlite3_module sqlite3_module; */ struct sqlite3_module { int iVersion; - int (SQLITE_CALLBACK *xCreate)(sqlite3*, void *pAux, + int (*xCreate)(sqlite3*, void *pAux, int argc, const char *const*argv, sqlite3_vtab **ppVTab, char**); - int (SQLITE_CALLBACK *xConnect)(sqlite3*, void *pAux, + int (*xConnect)(sqlite3*, void *pAux, int argc, const char *const*argv, sqlite3_vtab **ppVTab, char**); - int (SQLITE_CALLBACK *xBestIndex)(sqlite3_vtab *pVTab, sqlite3_index_info*); - int (SQLITE_CALLBACK *xDisconnect)(sqlite3_vtab *pVTab); - int (SQLITE_CALLBACK *xDestroy)(sqlite3_vtab *pVTab); - int (SQLITE_CALLBACK *xOpen)(sqlite3_vtab *pVTab, - sqlite3_vtab_cursor **ppCursor); - int (SQLITE_CALLBACK *xClose)(sqlite3_vtab_cursor*); - int (SQLITE_CALLBACK *xFilter)(sqlite3_vtab_cursor*, - int idxNum, const char *idxStr, - int argc, sqlite3_value **argv); - int (SQLITE_CALLBACK *xNext)(sqlite3_vtab_cursor*); - int (SQLITE_CALLBACK *xEof)(sqlite3_vtab_cursor*); - int (SQLITE_CALLBACK *xColumn)(sqlite3_vtab_cursor*, sqlite3_context*, int); - int (SQLITE_CALLBACK *xRowid)(sqlite3_vtab_cursor*, sqlite3_int64 *pRowid); - int (SQLITE_CALLBACK *xUpdate)(sqlite3_vtab *, int, sqlite3_value **, - sqlite3_int64 *); - int (SQLITE_CALLBACK *xBegin)(sqlite3_vtab *pVTab); - int (SQLITE_CALLBACK *xSync)(sqlite3_vtab *pVTab); - int (SQLITE_CALLBACK *xCommit)(sqlite3_vtab *pVTab); - int (SQLITE_CALLBACK *xRollback)(sqlite3_vtab *pVTab); - int (SQLITE_CALLBACK *xFindFunction)(sqlite3_vtab *pVtab, - int nArg, const char *zName, - void (SQLITE_CALLBACK **pxFunc)(sqlite3_context*,int,sqlite3_value**), - void **ppArg); - int (SQLITE_CALLBACK *xRename)(sqlite3_vtab *pVtab, const char *zNew); + int (*xBestIndex)(sqlite3_vtab *pVTab, sqlite3_index_info*); + int (*xDisconnect)(sqlite3_vtab *pVTab); + int (*xDestroy)(sqlite3_vtab *pVTab); + int (*xOpen)(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor); + int (*xClose)(sqlite3_vtab_cursor*); + int (*xFilter)(sqlite3_vtab_cursor*, int idxNum, const char *idxStr, + int argc, sqlite3_value **argv); + int (*xNext)(sqlite3_vtab_cursor*); + int (*xEof)(sqlite3_vtab_cursor*); + int (*xColumn)(sqlite3_vtab_cursor*, sqlite3_context*, int); + int (*xRowid)(sqlite3_vtab_cursor*, sqlite3_int64 *pRowid); + int (*xUpdate)(sqlite3_vtab *, int, sqlite3_value **, sqlite3_int64 *); + int (*xBegin)(sqlite3_vtab *pVTab); + int (*xSync)(sqlite3_vtab *pVTab); + int (*xCommit)(sqlite3_vtab *pVTab); + int (*xRollback)(sqlite3_vtab *pVTab); + int (*xFindFunction)(sqlite3_vtab *pVtab, int nArg, const char *zName, + void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), + void **ppArg); + int (*xRename)(sqlite3_vtab *pVtab, const char *zNew); /* The methods above are in version 1 of the sqlite_module object. Those ** below are for version 2 and greater. */ - int (SQLITE_CALLBACK *xSavepoint)(sqlite3_vtab *pVTab, int); - int (SQLITE_CALLBACK *xRelease)(sqlite3_vtab *pVTab, int); - int (SQLITE_CALLBACK *xRollbackTo)(sqlite3_vtab *pVTab, int); + int (*xSavepoint)(sqlite3_vtab *pVTab, int); + int (*xRelease)(sqlite3_vtab *pVTab, int); + int (*xRollbackTo)(sqlite3_vtab *pVTab, int); }; /* @@ -6010,7 +5983,7 @@ int sqlite3_create_module_v2( const char *zName, /* Name of the module */ const sqlite3_module *p, /* Methods for the module */ void *pClientData, /* Client data for xCreate/xConnect */ - void(SQLITE_CALLBACK *xDestroy)(void*) /* Module destructor function */ + void(*xDestroy)(void*) /* Module destructor function */ ); /* @@ -6551,15 +6524,15 @@ void sqlite3_mutex_leave(sqlite3_mutex*); */ typedef struct sqlite3_mutex_methods sqlite3_mutex_methods; struct sqlite3_mutex_methods { - int (SQLITE_CALLBACK *xMutexInit)(void); - int (SQLITE_CALLBACK *xMutexEnd)(void); - sqlite3_mutex *(SQLITE_CALLBACK *xMutexAlloc)(int); - void (SQLITE_CALLBACK *xMutexFree)(sqlite3_mutex *); - void (SQLITE_CALLBACK *xMutexEnter)(sqlite3_mutex *); - int (SQLITE_CALLBACK *xMutexTry)(sqlite3_mutex *); - void (SQLITE_CALLBACK *xMutexLeave)(sqlite3_mutex *); - int (SQLITE_CALLBACK *xMutexHeld)(sqlite3_mutex *); - int (SQLITE_CALLBACK *xMutexNotheld)(sqlite3_mutex *); + int (*xMutexInit)(void); + int (*xMutexEnd)(void); + sqlite3_mutex *(*xMutexAlloc)(int); + void (*xMutexFree)(sqlite3_mutex *); + void (*xMutexEnter)(sqlite3_mutex *); + int (*xMutexTry)(sqlite3_mutex *); + void (*xMutexLeave)(sqlite3_mutex *); + int (*xMutexHeld)(sqlite3_mutex *); + int (*xMutexNotheld)(sqlite3_mutex *); }; /* @@ -7255,21 +7228,18 @@ typedef struct sqlite3_pcache_methods2 sqlite3_pcache_methods2; struct sqlite3_pcache_methods2 { int iVersion; void *pArg; - int (SQLITE_CALLBACK *xInit)(void*); - void (SQLITE_CALLBACK *xShutdown)(void*); - sqlite3_pcache *(SQLITE_CALLBACK *xCreate)(int szPage, int szExtra, - int bPurgeable); - void (SQLITE_CALLBACK *xCachesize)(sqlite3_pcache*, int nCachesize); - int (SQLITE_CALLBACK *xPagecount)(sqlite3_pcache*); - sqlite3_pcache_page *(SQLITE_CALLBACK *xFetch)(sqlite3_pcache*, unsigned key, - int createFlag); - void (SQLITE_CALLBACK *xUnpin)(sqlite3_pcache*, sqlite3_pcache_page*, - int discard); - void (SQLITE_CALLBACK *xRekey)(sqlite3_pcache*, sqlite3_pcache_page*, - unsigned oldKey, unsigned newKey); - void (SQLITE_CALLBACK *xTruncate)(sqlite3_pcache*, unsigned iLimit); - void (SQLITE_CALLBACK *xDestroy)(sqlite3_pcache*); - void (SQLITE_CALLBACK *xShrink)(sqlite3_pcache*); + int (*xInit)(void*); + void (*xShutdown)(void*); + sqlite3_pcache *(*xCreate)(int szPage, int szExtra, int bPurgeable); + void (*xCachesize)(sqlite3_pcache*, int nCachesize); + int (*xPagecount)(sqlite3_pcache*); + sqlite3_pcache_page *(*xFetch)(sqlite3_pcache*, unsigned key, int createFlag); + void (*xUnpin)(sqlite3_pcache*, sqlite3_pcache_page*, int discard); + void (*xRekey)(sqlite3_pcache*, sqlite3_pcache_page*, + unsigned oldKey, unsigned newKey); + void (*xTruncate)(sqlite3_pcache*, unsigned iLimit); + void (*xDestroy)(sqlite3_pcache*); + void (*xShrink)(sqlite3_pcache*); }; /* @@ -7280,18 +7250,16 @@ struct sqlite3_pcache_methods2 { typedef struct sqlite3_pcache_methods sqlite3_pcache_methods; struct sqlite3_pcache_methods { void *pArg; - int (SQLITE_CALLBACK *xInit)(void*); - void (SQLITE_CALLBACK *xShutdown)(void*); - sqlite3_pcache *(SQLITE_CALLBACK *xCreate)(int szPage, int bPurgeable); - void (SQLITE_CALLBACK *xCachesize)(sqlite3_pcache*, int nCachesize); - int (SQLITE_CALLBACK *xPagecount)(sqlite3_pcache*); - void *(SQLITE_CALLBACK *xFetch)(sqlite3_pcache*, unsigned key, - int createFlag); - void (SQLITE_CALLBACK *xUnpin)(sqlite3_pcache*, void*, int discard); - void (SQLITE_CALLBACK *xRekey)(sqlite3_pcache*, void*, unsigned oldKey, - unsigned newKey); - void (SQLITE_CALLBACK *xTruncate)(sqlite3_pcache*, unsigned iLimit); - void (SQLITE_CALLBACK *xDestroy)(sqlite3_pcache*); + int (*xInit)(void*); + void (*xShutdown)(void*); + sqlite3_pcache *(*xCreate)(int szPage, int bPurgeable); + void (*xCachesize)(sqlite3_pcache*, int nCachesize); + int (*xPagecount)(sqlite3_pcache*); + void *(*xFetch)(sqlite3_pcache*, unsigned key, int createFlag); + void (*xUnpin)(sqlite3_pcache*, void*, int discard); + void (*xRekey)(sqlite3_pcache*, void*, unsigned oldKey, unsigned newKey); + void (*xTruncate)(sqlite3_pcache*, unsigned iLimit); + void (*xDestroy)(sqlite3_pcache*); }; @@ -7621,7 +7589,7 @@ int sqlite3_backup_pagecount(sqlite3_backup *p); */ int sqlite3_unlock_notify( sqlite3 *pBlocked, /* Waiting connection */ - void (SQLITE_CALLBACK *xNotify)(void **apArg, int nArg), /* Callback func */ + void (*xNotify)(void **apArg, int nArg), /* Callback function to invoke */ void *pNotifyArg /* Argument to pass to xNotify */ ); @@ -7736,7 +7704,7 @@ void sqlite3_log(int iErrCode, const char *zFormat, ...); */ void *sqlite3_wal_hook( sqlite3*, - int(SQLITE_CALLBACK *)(void *,sqlite3*,const char*,int), + int(*)(void *,sqlite3*,const char*,int), void* ); @@ -8209,7 +8177,7 @@ int sqlite3_db_cacheflush(sqlite3*); */ SQLITE_EXPERIMENTAL void *sqlite3_preupdate_hook( sqlite3 *db, - void(SQLITE_CALLBACK *xPreUpdate)( + void(*xPreUpdate)( void *pCtx, /* Copy of third arg to preupdate_hook() */ sqlite3 *db, /* Database handle */ int op, /* SQLITE_UPDATE, DELETE or INSERT */ diff --git a/tool/mksqlite3h.tcl b/tool/mksqlite3h.tcl index d0ddba9cfa..4b7d10b69f 100644 --- a/tool/mksqlite3h.tcl +++ b/tool/mksqlite3h.tcl @@ -21,6 +21,8 @@ # formatted as an integer (e.g. "3006017"). # 5) Replaces the string --SOURCE-ID-- with the date and time and sha1 # hash of the fossil-scm manifest for the source tree. +# 6) Adds the SQLITE_CALLBACK calling convention macro in front of all +# callback declarations. # # This script outputs to stdout. # @@ -125,6 +127,7 @@ foreach file $filelist { append line " " $funcname $rest } } + regsub {\(\*} $line {(SQLITE_CALLBACK *} line puts $line } close $in From fe0c0d2088cedf1c2e46d2ddf85938251fcb52de Mon Sep 17 00:00:00 2001 From: mistachkin Date: Thu, 28 Jul 2016 15:38:34 +0000 Subject: [PATCH 0615/1484] Modify the mksqlite3h.tcl tool to handle the syscall typedef specially. FossilOrigin-Name: 478a84efa6ea13629227ba8970c8ef8545d31074 --- manifest | 14 +++++++------- manifest.uuid | 2 +- tool/mksqlite3h.tcl | 2 ++ 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 49f48174ea..3195058bae 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\smksqlite3h.tcl\sto\sautomatically\sinsert\sthe\sSQLITE_CALLBACK\scalling\nconvention\smacros. -D 2016-07-28T15:09:02.696 +C Modify\sthe\smksqlite3h.tcl\stool\sto\shandle\sthe\ssyscall\stypedef\sspecially. +D 2016-07-28T15:38:34.103 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc da4c9f5bc46f6f12d7313d12be18a2d2c55e06c0 @@ -1450,7 +1450,7 @@ F tool/mkpragmatab.tcl f0d5bb266d1d388cf86fce5ba01a891e95d72d41 F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 F tool/mksqlite3c-noext.tcl aa58ea3be311c81821c2cd3209f55e46b07ab656 F tool/mksqlite3c.tcl a52ead27e2ac5d4b616e945a0601f628f4328329 -F tool/mksqlite3h.tcl abaf6af11e184c0b69f117fc47ecfa351d81c219 +F tool/mksqlite3h.tcl cf5cd68028e69a51ed5c76042672664201f0f756 F tool/mksqlite3internalh.tcl eb994013e833359137eb53a55acdad0b5ae1049b F tool/mkvsix.tcl 4abcaf3267171b2faadaf9b82a0dfbaa6e98f8b7 F tool/offsets.c fe4262fdfa378e8f5499a42136d17bf3b98f6091 @@ -1508,7 +1508,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e8be3dfeabaa31b3490793cf8230faae1204be15 -R 44253432508e9739e51133f1558c85ed -U drh -Z 863aa68feeed694e590c235a245cfae1 +P 11ab9c9ab562df98c20abf126a8bac178aef77a8 +R a69c68c4276ee266722a065a80ccdc75 +U mistachkin +Z 9a266ac1c40bfd5d57e83258cb2d1dad diff --git a/manifest.uuid b/manifest.uuid index 617643d254..f316f522bd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -11ab9c9ab562df98c20abf126a8bac178aef77a8 \ No newline at end of file +478a84efa6ea13629227ba8970c8ef8545d31074 \ No newline at end of file diff --git a/tool/mksqlite3h.tcl b/tool/mksqlite3h.tcl index 4b7d10b69f..9a4e7d2985 100644 --- a/tool/mksqlite3h.tcl +++ b/tool/mksqlite3h.tcl @@ -127,6 +127,8 @@ foreach file $filelist { append line " " $funcname $rest } } + set line [string map [list (*sqlite3_syscall_ptr) \ + "(SQLITE_SYSAPI *sqlite3_syscall_ptr)"] $line] regsub {\(\*} $line {(SQLITE_CALLBACK *} line puts $line } From f27a80cf185c97e66a5808e2634d41fe30942fed Mon Sep 17 00:00:00 2001 From: mistachkin Date: Thu, 28 Jul 2016 16:09:52 +0000 Subject: [PATCH 0616/1484] More work on getting the 'testfixture.exe' target to work correctly. FossilOrigin-Name: 36b72fd609cf151f3db0e65b450d7cd515f2ac49 --- Makefile.msc | 22 +++++++++++++++++++--- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 26 insertions(+), 10 deletions(-) diff --git a/Makefile.msc b/Makefile.msc index c3f7f3a2b0..4a8283731d 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -466,22 +466,30 @@ RCC = $(RC) -DSQLITE_OS_WIN=1 -I. -I$(TOP) -I$(TOP)\src $(RCOPTS) $(RCCOPTS) !IF "$(PLATFORM)"=="x86" CORE_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall SHELL_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall +# <> TEST_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall -DINCLUDE_SQLITE_TCL_H=1 -DSQLITE_TCLAPI=__cdecl +# <> !ELSE !IFNDEF PLATFORM CORE_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall SHELL_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall +# <> TEST_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall -DINCLUDE_SQLITE_TCL_H=1 -DSQLITE_TCLAPI=__cdecl +# <> !ELSE CORE_CCONV_OPTS = SHELL_CCONV_OPTS = +# <> TEST_CCONV_OPTS = +# <> !ENDIF !ENDIF !ELSE CORE_CCONV_OPTS = SHELL_CCONV_OPTS = +# <> TEST_CCONV_OPTS = +# <> !ENDIF # These are additional compiler options used for the core library. @@ -1983,12 +1991,20 @@ TESTFIXTURE_SRC = $(TESTSRC) $(TOP)\src\tclsqlite.c $(TESTFIXTURE_SRC1) sqlite_tclDecls.h: echo #ifndef SQLITE_TCLAPI > sqlite_tclDecls.h - echo # define SQLITE_TCLAPI __cdecl >> sqlite_tclDecls.h + echo # define SQLITE_TCLAPI >> sqlite_tclDecls.h echo #endif >> sqlite_tclDecls.h - type "$(TCLINCDIR)\tclDecls.h" | $(TCLSH_CMD) $(TOP)\tool\replace.tcl regsub "^(EXTERN\s+?.*?\s+?)Tcl_" "\1 SQLITE_TCLAPI Tcl_" | $(TCLSH_CMD) $(TOP)\tool\replace.tcl regsub "^(EXTERN\s+?(?:void|VOID)\s+?)TclFreeObj" "\1 SQLITE_TCLAPI TclFreeObj" >> sqlite_tclDecls.h + type "$(TCLINCDIR)\tclDecls.h" \ + | $(TCLSH_CMD) $(TOP)\tool\replace.tcl regsub "^(EXTERN\s+?.*?\s+?)Tcl_" "\1 SQLITE_TCLAPI Tcl_" \ + | $(TCLSH_CMD) $(TOP)\tool\replace.tcl regsub "^(EXTERN\s+?(?:void|VOID)\s+?)TclFreeObj" "\1 SQLITE_TCLAPI TclFreeObj" \ + | $(TCLSH_CMD) $(TOP)\tool\replace.tcl regsub "\(\*tcl_" "(SQLITE_TCLAPI *tcl_" \ + | $(TCLSH_CMD) $(TOP)\tool\replace.tcl regsub "\(\*tclFreeObj" "(SQLITE_TCLAPI *tclFreeObj" >> sqlite_tclDecls.h sqlite_tcl.h: sqlite_tclDecls.h - type "$(TCLINCDIR)\tcl.h" | $(TCLSH_CMD) $(TOP)\tool\replace.tcl exact tclDecls.h sqlite_tclDecls.h >> sqlite_tcl.h + type "$(TCLINCDIR)\tcl.h" | $(TCLSH_CMD) $(TOP)\tool\replace.tcl exact tclDecls.h sqlite_tclDecls.h \ + | $(TCLSH_CMD) $(TOP)\tool\replace.tcl regsub "typedef (.*?)\(Tcl_" "typedef \1 (SQLITE_TCLAPI Tcl_" \ + | $(TCLSH_CMD) $(TOP)\tool\replace.tcl exact "void (*freeProc)" "void (SQLITE_TCLAPI *freeProc)" \ + | $(TCLSH_CMD) $(TOP)\tool\replace.tcl exact "Tcl_HashEntry *(*findProc)" "Tcl_HashEntry *(SQLITE_TCLAPI *findProc)" \ + | $(TCLSH_CMD) $(TOP)\tool\replace.tcl exact "Tcl_HashEntry *(*createProc)" "Tcl_HashEntry *(SQLITE_TCLAPI *createProc)" >> sqlite_tcl.h testfixture.exe: $(TESTFIXTURE_SRC) $(SQLITE3H) $(LIBRESOBJS) $(HDR) sqlite_tcl.h $(LTLINK) -DSQLITE_NO_SYNC=1 $(TESTFIXTURE_FLAGS) \ diff --git a/manifest b/manifest index 3195058bae..cb678be722 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -C Modify\sthe\smksqlite3h.tcl\stool\sto\shandle\sthe\ssyscall\stypedef\sspecially. -D 2016-07-28T15:38:34.103 +C More\swork\son\sgetting\sthe\s'testfixture.exe'\starget\sto\swork\scorrectly. +D 2016-07-28T16:09:52.017 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 -F Makefile.msc da4c9f5bc46f6f12d7313d12be18a2d2c55e06c0 +F Makefile.msc 1e5399407885d69150e2659f4710b5712a1e6cef F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7 F VERSION cb29eb11e493dd85b3eeec4053c03949bf98478e F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 @@ -1508,7 +1508,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 11ab9c9ab562df98c20abf126a8bac178aef77a8 -R a69c68c4276ee266722a065a80ccdc75 +P 478a84efa6ea13629227ba8970c8ef8545d31074 +R 88324b2461565133820c548ccb01cb7e U mistachkin -Z 9a266ac1c40bfd5d57e83258cb2d1dad +Z 92e347019c063e4a6ca0b5b196166511 diff --git a/manifest.uuid b/manifest.uuid index f316f522bd..132e64c427 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -478a84efa6ea13629227ba8970c8ef8545d31074 \ No newline at end of file +36b72fd609cf151f3db0e65b450d7cd515f2ac49 \ No newline at end of file From 7617e4a8a4564689a839cf116dae0012b4753a65 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Thu, 28 Jul 2016 17:11:20 +0000 Subject: [PATCH 0617/1484] Make sure the SQLITE_TCLAPI macro is always defined. FossilOrigin-Name: f2f1323cc4d2ad2d6794dbfae8d50b747213e85d --- ext/fts3/fts3_test.c | 11 +- manifest | 82 +++++----- manifest.uuid | 2 +- src/sqliteInt.h | 8 + src/tclsqlite.c | 47 ++++-- src/test1.c | 360 +++++++++++++++++++++---------------------- src/test2.c | 40 ++--- src/test3.c | 30 ++-- src/test4.c | 30 ++-- src/test5.c | 8 +- src/test6.c | 14 +- src/test7.c | 26 ++-- src/test8.c | 4 +- src/test9.c | 6 +- src/test_async.c | 13 +- src/test_autoext.c | 17 +- src/test_backup.c | 9 +- src/test_bestindex.c | 2 +- src/test_blob.c | 10 +- src/test_btree.c | 2 +- src/test_demovfs.c | 7 +- src/test_fs.c | 2 +- src/test_func.c | 4 +- src/test_hexio.c | 14 +- src/test_init.c | 8 +- src/test_intarray.c | 7 +- src/test_malloc.c | 64 ++++---- src/test_multiplex.c | 11 +- src/test_mutex.c | 22 +-- src/test_osinst.c | 5 +- src/test_quota.c | 73 ++++----- src/test_rtree.c | 4 +- src/test_schema.c | 2 +- src/test_superlock.c | 9 +- src/test_syscall.c | 20 +-- src/test_tclvar.c | 2 +- src/test_thread.c | 18 +-- src/test_vfs.c | 6 +- 38 files changed, 530 insertions(+), 469 deletions(-) diff --git a/ext/fts3/fts3_test.c b/ext/fts3/fts3_test.c index c3b71284ec..a48a556c98 100644 --- a/ext/fts3/fts3_test.c +++ b/ext/fts3/fts3_test.c @@ -22,6 +22,9 @@ # include "sqlite_tcl.h" #else # include "tcl.h" +# ifndef SQLITE_TCLAPI +# define SQLITE_TCLAPI +# endif #endif #include #include @@ -147,7 +150,7 @@ static int nm_match_count( /* ** Tclcmd: fts3_near_match DOCUMENT EXPR ?OPTIONS? */ -static int fts3_near_match_cmd( +static int SQLITE_TCLAPI fts3_near_match_cmd( ClientData clientData, Tcl_Interp *interp, int objc, @@ -282,7 +285,7 @@ static int fts3_near_match_cmd( ** # Restore initial incr-load settings: ** eval fts3_configure_incr_load $cfg */ -static int fts3_configure_incr_load_cmd( +static int SQLITE_TCLAPI fts3_configure_incr_load_cmd( ClientData clientData, Tcl_Interp *interp, int objc, @@ -492,7 +495,7 @@ static int testTokenizerLanguage( } #endif -static int fts3_test_tokenizer_cmd( +static int SQLITE_TCLAPI fts3_test_tokenizer_cmd( ClientData clientData, Tcl_Interp *interp, int objc, @@ -521,7 +524,7 @@ static int fts3_test_tokenizer_cmd( return TCL_OK; } -static int fts3_test_varint_cmd( +static int SQLITE_TCLAPI fts3_test_varint_cmd( ClientData clientData, Tcl_Interp *interp, int objc, diff --git a/manifest b/manifest index cb678be722..1be1262c7e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C More\swork\son\sgetting\sthe\s'testfixture.exe'\starget\sto\swork\scorrectly. -D 2016-07-28T16:09:52.017 +C Make\ssure\sthe\sSQLITE_TCLAPI\smacro\sis\salways\sdefined. +D 2016-07-28T17:11:20.162 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1e5399407885d69150e2659f4710b5712a1e6cef @@ -81,7 +81,7 @@ F ext/fts3/fts3_icu.c deb46f7020d87ea7a14a433fb7a7f4bef42a9652 F ext/fts3/fts3_porter.c 3565faf04b626cddf85f03825e86056a4562c009 F ext/fts3/fts3_snippet.c 68ae118b0f834ea53d2b89e4087fc0f0b8c4ee4e F ext/fts3/fts3_term.c 88c55a6fa1a51ab494e33dced0401a6c28791fd7 -F ext/fts3/fts3_test.c 7d8c9e17bc11cc245c91585ef5a47ee4a600f7b2 +F ext/fts3/fts3_test.c 79f2a7fbb3f672fa032e5a432ca274ea3ee93c34 F ext/fts3/fts3_tokenize_vtab.c a27593ab19657166f6fa5ec073b678cc29a75860 F ext/fts3/fts3_tokenizer.c a22bf311a71f3efa9d7012d8cc48fc9b0f3dace7 F ext/fts3/fts3_tokenizer.h 64c6ef6c5272c51ebe60fc607a896e84288fcbc3 @@ -388,55 +388,55 @@ F src/shell.c 9351fc6de11e1d908648c0a92d85627138e3dee5 F src/sqlite.h.in a03063e698a43cc5c996cd341f39439a6ce58304 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 46f300b6e300e0fa916d7d58c44b53415b8471a9 -F src/sqliteInt.h d25c18c1272a7811e2569c39bfc2fca96156eead +F src/sqliteInt.h 14516943867eb2c30ce0e3670299958f59ade052 F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c 5b18f9526900f61189ab0b83f1ef41d9f871a2ab F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 -F src/tclsqlite.c e348648c28fcaa04ab8da98bf7e8a37b3629e634 -F src/test1.c a625e4d2857e0b08a9d66bdb737ce95b02326a9f -F src/test2.c ce1e56fd0983866df1dbaf6c0558f3ad726ec222 -F src/test3.c 68b6b3b17df3028deda0a79607af70ff4ac5fc52 -F src/test4.c a305bb93783fa0db03b9e5e899ec5367cf139903 -F src/test5.c 3ca6874d52d658607d2f25bb6ed88fd03ad78a6c -F src/test6.c 4fc2c870b4f41d46f11a24b5c7dcff89486442b8 -F src/test7.c 57b6dae963ff12cb6ef8389285427f07e8b042ff -F src/test8.c 33cefbf2911e12c74c6adb798cc0c8ee3287a58d -F src/test9.c 6b9792e8a692a67fcce77dfe4a2ca4744c4ece54 -F src/test_async.c 233536b7e364a4a95597d6aa6fdf07fa9351de67 -F src/test_autoext.c 2a2343174ff46477dd081b7582dc1e72c69330bc -F src/test_backup.c 7fe86c0be6c1a05a254b845a6aa32294dbdab012 -F src/test_bestindex.c 832b9968bf15d60029c1700905d56cefeb0f5dd7 -F src/test_blob.c 6af2552a059f326a107214fb13917f31a1606caf -F src/test_btree.c 3d2abd96336f1cbb760c7c5a758e74eaae98aed6 +F src/tclsqlite.c a9c6e33c44efa93d176ce5e0887d5d533c98b429 +F src/test1.c 906a04b649c7139e943193a3905d583e325c30c7 +F src/test2.c b7174313e993754303a8b33c43df7c44b46857ab +F src/test3.c 1339a40be39650ae83894b6578f971dc7f96ea8a +F src/test4.c 18ec393bb4d0ad1de729f0b94da7267270f3d8e6 +F src/test5.c 328aae2c010c57a9829d255dc099d6899311672d +F src/test6.c 55aa2775c154415dcf4ed7cd1e19a193122b3a02 +F src/test7.c 5612e9aecf934d6df7bba6ce861fdf5ba5456010 +F src/test8.c 4f4904721167b32f7a4fa8c7b32a07a673d6cc86 +F src/test9.c 12e5ba554d2d1cbe0158f6ab3f7ffcd7a86ee4e5 +F src/test_async.c 195ab49da082053fdb0f949c114b806a49ca770a +F src/test_autoext.c 6c8fe00caa3f38396f0990467179e9d1adb39ddd +F src/test_backup.c bf5da90c9926df0a4b941f2d92825a01bbe090a0 +F src/test_bestindex.c d23f80d334c59662af69191854c76b8d3d0c8c96 +F src/test_blob.c a0f7ad49a0c9d4b72f693fe2a71c58d7e507174d +F src/test_btree.c 8b2dc8b8848cf3a4db93f11578f075e82252a274 F src/test_config.c 4d3d4a886416f369771d69a6dba926866deda788 -F src/test_demovfs.c ed337b14964a5f5ba08bf9472c94c64e88c547a7 +F src/test_demovfs.c a0c3bdd45ed044115c2c9f7779e56eafff18741e F src/test_devsym.c 4e58dec2602d8e139ca08659f62a62450587cb58 -F src/test_fs.c 39086f99413e73f60afe2280a0ff27dfab63ab47 -F src/test_func.c 4197173afb7d8453d3d0c7f7b109226dcef52997 -F src/test_hexio.c 2ab200d91f77085bd69c721dcb2b649f036d608b -F src/test_init.c a55015461868ca979d819f8db72aa682ba068185 -F src/test_intarray.c 9fee7f930ff988dd0fc20315da4c762f77f01a78 +F src/test_fs.c ac62ce7d5c0c23aa6932891cad5746945564c91c +F src/test_func.c 9cea6fee7ece5f46aa26e060b35e10dc6ba708cf +F src/test_hexio.c 1d4469ca61ab202a1fcec6543f584d2407205e8d +F src/test_init.c 4413c211a94b62157ca4c145b3f27c497f03c664 +F src/test_intarray.c 988fc61cb0ff539f4172c0d95f15287c92516f64 F src/test_intarray.h f3b7672f5d1056eac563c0d6ea8480a660b1475c F src/test_journal.c d3b83f2bcb7792c709e57abddc456a2b1818643a F src/test_loadext.c 337056bae59f80b9eb00ba82088b39d0f4fe6dfd -F src/test_malloc.c 90cbc63ebab11d16b440d394e77bc26629829f11 -F src/test_multiplex.c a0bcea72bc981f64c9c71edf22cc503cf83e0348 +F src/test_malloc.c c05f6c40bd6c8bfe5f1718212f81fd5687f91766 +F src/test_multiplex.c af2792ec4436d442d1bd00b8803470a25111bad3 F src/test_multiplex.h 5436d03f2d0501d04f3ed50a75819e190495b635 -F src/test_mutex.c 85021f2ffe67cdb4dfa6089f3f55f5e01cd76aea +F src/test_mutex.c 7f4337ba23ee6b1d2ec81c189653608cb069926a F src/test_onefile.c 416f87a28d6d673352d33fc4b1c7d39db878e50f -F src/test_osinst.c 4e21c7b2709955f9907b80bfc874afb81ce1b4a7 +F src/test_osinst.c 98ef31ff03d55497829ca0f6c74a9f4e1aa48690 F src/test_pcache.c a5cd24730cb43c5b18629043314548c9169abb00 -F src/test_quota.c 7c2bb6d302f9cab9d4782b1a37dd01f0c7bde071 +F src/test_quota.c 6cb9297115b551f433a9ad1741817a9831abed99 F src/test_quota.h 2a8ad1952d1d2ca9af0ce0465e56e6c023b5e15d -F src/test_rtree.c 0aad72f4854b01957b20c3c325eecd8512e9731d -F src/test_schema.c ab94aeab8a94486de3d2ce06567b7ee35f3a59b8 +F src/test_rtree.c 671f3fae50ff116ef2e32a3bf1fe21b5615b4b7b +F src/test_schema.c f575932cb6274d12147a77e13ea4b49d52408513 F src/test_server.c a2615049954cbb9cfb4a62e18e2f0616e4dc38fe F src/test_sqllog.c 0d138a8180a312bf996b37fa66da5c5799d4d57b -F src/test_superlock.c 9389ee2aa8f8fa7487ea2e3bf01c033c65eaf21a -F src/test_syscall.c 8313aa5d43989913c2dfd42b987e6ed29d6b8770 -F src/test_tclvar.c 0239df9e83f9adc7b21ae01dce20229dd8592e71 -F src/test_thread.c 30ae6818d21a168ef8cbceb9456411751c714cd9 -F src/test_vfs.c 2edd39d413301baf15c1d7384f21c2e8b3fca2dd +F src/test_superlock.c 4839644b9201da822f181c5bc406c0b2385f672e +F src/test_syscall.c 1073306ba2e9bfc886771871a13d3de281ed3939 +F src/test_tclvar.c df9fe1213c2634687a9ca0b0bec0d2119d359ae3 +F src/test_thread.c c7c40494b7a0603ebb6eb97c904545c0dceca5ff +F src/test_vfs.c f0186261a24de2671d080bcd8050732f0cb64f6e F src/test_vfstrace.c bab9594adc976cbe696ff3970728830b4c5ed698 F src/test_windirent.c 8f5fada630348558d5745b334702f301da1ffc61 F src/test_windirent.h b12055cab6227f7be10f5c19296f67c60cc5e2a5 @@ -1508,7 +1508,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 478a84efa6ea13629227ba8970c8ef8545d31074 -R 88324b2461565133820c548ccb01cb7e +P 36b72fd609cf151f3db0e65b450d7cd515f2ac49 +R cb104ece8c53bb381905efecad762caf U mistachkin -Z 92e347019c063e4a6ca0b5b196166511 +Z 5c80ddf3854cd75da2e73aafdf02283f diff --git a/manifest.uuid b/manifest.uuid index 132e64c427..1a85a325af 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -36b72fd609cf151f3db0e65b450d7cd515f2ac49 \ No newline at end of file +f2f1323cc4d2ad2d6794dbfae8d50b747213e85d \ No newline at end of file diff --git a/src/sqliteInt.h b/src/sqliteInt.h index c5b1eccc03..35be76dfb0 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -42,6 +42,14 @@ ** asterisks and the comment text. */ +/* +** Make sure the Tcl calling convention macro is defined. This macro is +** only used by test code and Tcl integration code. +*/ +#ifndef SQLITE_TCLAPI +# define SQLITE_TCLAPI +#endif + /* ** Make sure that rand_s() is available on Windows systems with MSVC 2005 ** or higher. diff --git a/src/tclsqlite.c b/src/tclsqlite.c index d26c622859..527dc488ee 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -37,6 +37,9 @@ # include "sqlite_tcl.h" #else # include "tcl.h" +# ifndef SQLITE_TCLAPI +# define SQLITE_TCLAPI +# endif #endif #include @@ -208,7 +211,10 @@ static void closeIncrblobChannels(SqliteDb *pDb){ /* ** Close an incremental blob channel. */ -static int incrblobClose(ClientData instanceData, Tcl_Interp *interp){ +static int SQLITE_TCLAPI incrblobClose( + ClientData instanceData, + Tcl_Interp *interp +){ IncrblobChannel *p = (IncrblobChannel *)instanceData; int rc = sqlite3_blob_close(p->pBlob); sqlite3 *db = p->pDb->db; @@ -237,7 +243,7 @@ static int incrblobClose(ClientData instanceData, Tcl_Interp *interp){ /* ** Read data from an incremental blob channel. */ -static int incrblobInput( +static int SQLITE_TCLAPI incrblobInput( ClientData instanceData, char *buf, int bufSize, @@ -269,7 +275,7 @@ static int incrblobInput( /* ** Write data to an incremental blob channel. */ -static int incrblobOutput( +static int SQLITE_TCLAPI incrblobOutput( ClientData instanceData, CONST char *buf, int toWrite, @@ -302,7 +308,7 @@ static int incrblobOutput( /* ** Seek an incremental blob channel. */ -static int incrblobSeek( +static int SQLITE_TCLAPI incrblobSeek( ClientData instanceData, long offset, int seekMode, @@ -328,10 +334,17 @@ static int incrblobSeek( } -static void incrblobWatch(ClientData instanceData, int mode){ +static void SQLITE_TCLAPI incrblobWatch( + ClientData instanceData, + int mode +){ /* NO-OP */ } -static int incrblobHandle(ClientData instanceData, int dir, ClientData *hPtr){ +static int SQLITE_TCLAPI incrblobHandle( + ClientData instanceData, + int dir, + ClientData *hPtr +){ return TCL_ERROR; } @@ -490,7 +503,7 @@ static void flushStmtCache(SqliteDb *pDb){ ** TCL calls this procedure when an sqlite3 database command is ** deleted. */ -static void DbDeleteCmd(void *db){ +static void SQLITE_TCLAPI DbDeleteCmd(void *db){ SqliteDb *pDb = (SqliteDb*)db; flushStmtCache(pDb); closeIncrblobChannels(pDb); @@ -1795,7 +1808,12 @@ static void DbHookCmd( ** and calls that connection "db1". The second command causes this ** subroutine to be invoked. */ -static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ +static int SQLITE_TCLAPI DbObjCmd( + void *cd, + Tcl_Interp *interp, + int objc, + Tcl_Obj *const*objv +){ SqliteDb *pDb = (SqliteDb*)cd; int choice; int rc = TCL_OK; @@ -3263,7 +3281,12 @@ static int DbObjCmdAdaptor( ** The second argument is the name of the database file. ** */ -static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ +static int SQLITE_TCLAPI DbMain( + void *cd, + Tcl_Interp *interp, + int objc, + Tcl_Obj *const*objv +){ SqliteDb *p; const char *zArg; char *zErrMsg; @@ -3935,7 +3958,7 @@ static const char *tclsh_main_loop(void); #ifdef SQLITE_TEST static void init_all(Tcl_Interp *); -static int init_all_cmd( +static int SQLITE_TCLAPI init_all_cmd( ClientData cd, Tcl_Interp *interp, int objc, @@ -3965,7 +3988,7 @@ static int init_all_cmd( ** to use the sqlite3_prepare_v2() function to prepare statements. If it ** is false, sqlite3_prepare(). */ -static int db_use_legacy_prepare_cmd( +static int SQLITE_TCLAPI db_use_legacy_prepare_cmd( ClientData cd, Tcl_Interp *interp, int objc, @@ -4002,7 +4025,7 @@ static int db_use_legacy_prepare_cmd( ** return the text representation of the most recently used statement ** handle. */ -static int db_last_stmt_ptr( +static int SQLITE_TCLAPI db_last_stmt_ptr( ClientData cd, Tcl_Interp *interp, int objc, diff --git a/src/test1.c b/src/test1.c index e1b4fc0f31..ec6d8ecff3 100644 --- a/src/test1.c +++ b/src/test1.c @@ -79,7 +79,7 @@ void *sqlite3TestTextToPtr(const char *z){ ** for an sqlite connection instance. Bad things happen if the ** input is not an sqlite connection. */ -static int get_sqlite_pointer( +static int SQLITE_TCLAPI get_sqlite_pointer( void * clientData, Tcl_Interp *interp, int objc, @@ -225,7 +225,7 @@ static void io_trace_callback(const char *zFormat, ...){ ** I/O tracing begins going into FILENAME. If FILENAME is an empty ** string, I/O tracing is turned off. */ -static int test_io_trace( +static int SQLITE_TCLAPI test_io_trace( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -266,7 +266,7 @@ static int test_io_trace( ** ** Also return true if the OMIT_MISUSE environment variable exists. */ -static int clang_sanitize_address( +static int SQLITE_TCLAPI clang_sanitize_address( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -293,7 +293,7 @@ static int clang_sanitize_address( ** DB. The SQL is the string FORMAT. The format string should contain ** one %s or %q. STRING is the value inserted into %s or %q. */ -static int test_exec_printf( +static int SQLITE_TCLAPI test_exec_printf( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -331,7 +331,7 @@ static int test_exec_printf( ** HEX into ASCII. Most characters are translated as is. %HH becomes ** a hex character. */ -static int test_exec_hex( +static int SQLITE_TCLAPI test_exec_hex( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -377,7 +377,7 @@ static int test_exec_hex( ** ** Enter or leave the mutex on a database connection. */ -static int db_enter( +static int SQLITE_TCLAPI db_enter( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -393,7 +393,7 @@ static int db_enter( sqlite3_mutex_enter(db->mutex); return TCL_OK; } -static int db_leave( +static int SQLITE_TCLAPI db_leave( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -415,7 +415,7 @@ static int db_leave( ** ** Invoke the sqlite3_exec interface using the open database DB */ -static int test_exec( +static int SQLITE_TCLAPI test_exec( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -462,7 +462,7 @@ static int test_exec( ** Invoke the sqlite3_exec interface using the open database DB. Discard ** all results */ -static int test_exec_nr( +static int SQLITE_TCLAPI test_exec_nr( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -489,7 +489,7 @@ static int test_exec_nr( ** concatenate arg0 through argn using separator as the separator. ** Return the result. */ -static int test_mprintf_z( +static int SQLITE_TCLAPI test_mprintf_z( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -512,7 +512,7 @@ static int test_mprintf_z( ** Test the %n format of sqlite_mprintf(). Return the length of the ** input string. */ -static int test_mprintf_n( +static int SQLITE_TCLAPI test_mprintf_n( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -536,7 +536,7 @@ static int test_mprintf_n( ** You pass in a format string that requires more than one argument, ** bad things will happen. */ -static int test_snprintf_int( +static int SQLITE_TCLAPI test_snprintf_int( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -562,7 +562,7 @@ static int test_snprintf_int( ** DB. The SQL is the string FORMAT. The format string should contain ** one %s or %q. STRING is the value inserted into %s or %q. */ -static int test_get_table_printf( +static int SQLITE_TCLAPI test_get_table_printf( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -625,7 +625,7 @@ static int test_get_table_printf( ** ** Returns the integer ROWID of the most recent insert. */ -static int test_last_rowid( +static int SQLITE_TCLAPI test_last_rowid( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -649,7 +649,7 @@ static int test_last_rowid( ** ** Set the codec key. */ -static int test_key( +static int SQLITE_TCLAPI test_key( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -677,7 +677,7 @@ static int test_key( ** ** Change the codec key. */ -static int test_rekey( +static int SQLITE_TCLAPI test_rekey( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -705,7 +705,7 @@ static int test_rekey( ** ** Closes the database opened by sqlite3_open. */ -static int sqlite_test_close( +static int SQLITE_TCLAPI sqlite_test_close( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -729,7 +729,7 @@ static int sqlite_test_close( ** ** Closes the database opened by sqlite3_open. */ -static int sqlite_test_close_v2( +static int SQLITE_TCLAPI sqlite_test_close_v2( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -1013,7 +1013,7 @@ static void nondeterministicFunction( ** sqlite3_create_function function while a query is in progress in order ** to test the SQLITE_MISUSE detection logic. */ -static int test_create_function( +static int SQLITE_TCLAPI test_create_function( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -1170,7 +1170,7 @@ static void legacyCountFinalize(sqlite3_context *context){ ** "legacy_count()" with the supplied database handle. This is used ** to test the deprecated sqlite3_aggregate_count() API. */ -static int test_create_aggregate( +static int SQLITE_TCLAPI test_create_aggregate( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -1211,7 +1211,7 @@ static int test_create_aggregate( ** Puts uses a separate buffer and debugging statements will be out of ** sequence if it is used. */ -static int test_printf( +static int SQLITE_TCLAPI test_printf( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -1233,7 +1233,7 @@ static int test_printf( ** ** Call mprintf with three integer arguments */ -static int sqlite3_mprintf_int( +static int SQLITE_TCLAPI sqlite3_mprintf_int( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -1260,7 +1260,7 @@ static int sqlite3_mprintf_int( ** ** Call mprintf with three 64-bit integer arguments */ -static int sqlite3_mprintf_int64( +static int SQLITE_TCLAPI sqlite3_mprintf_int64( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -1293,7 +1293,7 @@ static int sqlite3_mprintf_int64( ** same as sqlite3_mprintf_int or sqlite3_mprintf_int64, depending on ** platform. */ -static int sqlite3_mprintf_long( +static int SQLITE_TCLAPI sqlite3_mprintf_long( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -1324,7 +1324,7 @@ static int sqlite3_mprintf_long( ** ** Call mprintf with two integer arguments and one string argument */ -static int sqlite3_mprintf_str( +static int SQLITE_TCLAPI sqlite3_mprintf_str( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -1351,7 +1351,7 @@ static int sqlite3_mprintf_str( ** ** Call mprintf with two integer arguments and one string argument */ -static int sqlite3_snprintf_str( +static int SQLITE_TCLAPI sqlite3_snprintf_str( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -1385,7 +1385,7 @@ static int sqlite3_snprintf_str( ** ** Call mprintf with two integer arguments and one double argument */ -static int sqlite3_mprintf_double( +static int SQLITE_TCLAPI sqlite3_mprintf_double( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -1416,7 +1416,7 @@ static int sqlite3_mprintf_double( ** two arguments given above. This is used to generate overflow and underflow ** doubles to test that they are converted properly. */ -static int sqlite3_mprintf_scaled( +static int SQLITE_TCLAPI sqlite3_mprintf_scaled( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -1446,7 +1446,7 @@ static int sqlite3_mprintf_scaled( ** two arguments given above. This is used to generate overflow and underflow ** doubles to test that they are converted properly. */ -static int sqlite3_mprintf_stronly( +static int SQLITE_TCLAPI sqlite3_mprintf_stronly( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -1470,7 +1470,7 @@ static int sqlite3_mprintf_stronly( ** Call mprintf with a single double argument which is derived from the ** hexadecimal encoding of an IEEE double. */ -static int sqlite3_mprintf_hexdouble( +static int SQLITE_TCLAPI sqlite3_mprintf_hexdouble( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -1503,7 +1503,7 @@ static int sqlite3_mprintf_hexdouble( ** */ #if !defined(SQLITE_OMIT_SHARED_CACHE) -static int test_enable_shared( +static int SQLITE_TCLAPI test_enable_shared( ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ @@ -1540,7 +1540,7 @@ static int test_enable_shared( ** Usage: sqlite3_extended_result_codes DB BOOLEAN ** */ -static int test_extended_result_codes( +static int SQLITE_TCLAPI test_extended_result_codes( ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ @@ -1563,7 +1563,7 @@ static int test_extended_result_codes( ** Usage: sqlite3_libversion_number ** */ -static int test_libversion_number( +static int SQLITE_TCLAPI test_libversion_number( ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ @@ -1577,7 +1577,7 @@ static int test_libversion_number( ** Usage: sqlite3_table_column_metadata DB dbname tblname colname ** */ -static int test_table_column_metadata( +static int SQLITE_TCLAPI test_table_column_metadata( ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ @@ -1628,7 +1628,7 @@ static int test_table_column_metadata( #ifndef SQLITE_OMIT_INCRBLOB -static int blobHandleFromObj( +static int SQLITE_TCLAPI blobHandleFromObj( Tcl_Interp *interp, Tcl_Obj *pObj, sqlite3_blob **ppBlob @@ -1657,7 +1657,7 @@ static int blobHandleFromObj( return TCL_OK; } -static int test_blob_reopen( +static int SQLITE_TCLAPI test_blob_reopen( ClientData clientData, /* Not used */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ @@ -1733,7 +1733,7 @@ static int testCreateCollationCmp( return iRes; } -static int test_create_collation_v2( +static int SQLITE_TCLAPI test_create_collation_v2( ClientData clientData, /* Not used */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ @@ -1808,7 +1808,7 @@ static void cf2Destroy(void *pUser){ if( p->pDestroy ) Tcl_DecrRefCount(p->pDestroy); sqlite3_free(p); } -static int test_create_function_v2( +static int SQLITE_TCLAPI test_create_function_v2( ClientData clientData, /* Not used */ Tcl_Interp *interp, /* The invoking TCL interpreter */ int objc, /* Number of arguments */ @@ -1896,7 +1896,7 @@ static int test_create_function_v2( /* ** Usage: sqlite3_load_extension DB-HANDLE FILE ?PROC? */ -static int test_load_extension( +static int SQLITE_TCLAPI test_load_extension( ClientData clientData, /* Not used */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ @@ -1954,7 +1954,7 @@ static int test_load_extension( /* ** Usage: sqlite3_enable_load_extension DB-HANDLE ONOFF */ -static int test_enable_load( +static int SQLITE_TCLAPI test_enable_load( ClientData clientData, /* Not used */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ @@ -2000,7 +2000,7 @@ static int test_enable_load( ** This command is used to test the recoverability of a database in ** the event of a program crash. */ -static int sqlite_abort( +static int SQLITE_TCLAPI sqlite_abort( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -2059,7 +2059,7 @@ error_out: ** ** Register the test SQL function on the database DB under the name NAME. */ -static int test_register_func( +static int SQLITE_TCLAPI test_register_func( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -2088,7 +2088,7 @@ static int test_register_func( ** ** Finalize a statement handle. */ -static int test_finalize( +static int SQLITE_TCLAPI test_finalize( void * clientData, Tcl_Interp *interp, int objc, @@ -2120,7 +2120,7 @@ static int test_finalize( ** ** Get the value of a status counter from a statement. */ -static int test_stmt_status( +static int SQLITE_TCLAPI test_stmt_status( void * clientData, Tcl_Interp *interp, int objc, @@ -2165,7 +2165,7 @@ static int test_stmt_status( /* ** Usage: sqlite3_stmt_scanstatus STMT IDX */ -static int test_stmt_scanstatus( +static int SQLITE_TCLAPI test_stmt_scanstatus( void * clientData, Tcl_Interp *interp, int objc, @@ -2215,7 +2215,7 @@ static int test_stmt_scanstatus( /* ** Usage: sqlite3_stmt_scanstatus_reset STMT */ -static int test_stmt_scanstatus_reset( +static int SQLITE_TCLAPI test_stmt_scanstatus_reset( void * clientData, Tcl_Interp *interp, int objc, @@ -2238,7 +2238,7 @@ static int test_stmt_scanstatus_reset( ** ** Zero the SQLITE_CONFIG_SQLLOG configuration */ -static int test_config_sqllog( +static int SQLITE_TCLAPI test_config_sqllog( void * clientData, Tcl_Interp *interp, int objc, @@ -2258,7 +2258,7 @@ static int test_config_sqllog( ** ** Return the value returned by the default VFS's xCurrentTimeInt64 method. */ -static int vfsCurrentTimeInt64( +static int SQLITE_TCLAPI vfsCurrentTimeInt64( void * clientData, Tcl_Interp *interp, int objc, @@ -2279,7 +2279,7 @@ static int vfsCurrentTimeInt64( /* ** Usage: sqlite3_snapshot_get DB DBNAME */ -static int test_snapshot_get( +static int SQLITE_TCLAPI test_snapshot_get( void * clientData, Tcl_Interp *interp, int objc, @@ -2314,7 +2314,7 @@ static int test_snapshot_get( /* ** Usage: sqlite3_snapshot_open DB DBNAME SNAPSHOT */ -static int test_snapshot_open( +static int SQLITE_TCLAPI test_snapshot_open( void * clientData, Tcl_Interp *interp, int objc, @@ -2346,7 +2346,7 @@ static int test_snapshot_open( /* ** Usage: sqlite3_snapshot_free SNAPSHOT */ -static int test_snapshot_free( +static int SQLITE_TCLAPI test_snapshot_free( void * clientData, Tcl_Interp *interp, int objc, @@ -2367,7 +2367,7 @@ static int test_snapshot_free( /* ** Usage: sqlite3_snapshot_cmp SNAPSHOT1 SNAPSHOT2 */ -static int test_snapshot_cmp( +static int SQLITE_TCLAPI test_snapshot_cmp( void * clientData, Tcl_Interp *interp, int objc, @@ -2393,7 +2393,7 @@ static int test_snapshot_cmp( ** ** Return the next statment in sequence after STMT. */ -static int test_next_stmt( +static int SQLITE_TCLAPI test_next_stmt( void * clientData, Tcl_Interp *interp, int objc, @@ -2425,7 +2425,7 @@ static int test_next_stmt( ** Return true if STMT is a NULL pointer or a pointer to a statement ** that is guaranteed to leave the database unmodified. */ -static int test_stmt_readonly( +static int SQLITE_TCLAPI test_stmt_readonly( void * clientData, Tcl_Interp *interp, int objc, @@ -2452,7 +2452,7 @@ static int test_stmt_readonly( ** Return true if STMT is a non-NULL pointer to a statement ** that has been stepped but not to completion. */ -static int test_stmt_busy( +static int SQLITE_TCLAPI test_stmt_busy( void * clientData, Tcl_Interp *interp, int objc, @@ -2478,7 +2478,7 @@ static int test_stmt_busy( ** ** Return true if STMT uses a statement journal. */ -static int uses_stmt_journal( +static int SQLITE_TCLAPI uses_stmt_journal( void * clientData, Tcl_Interp *interp, int objc, @@ -2504,7 +2504,7 @@ static int uses_stmt_journal( ** ** Reset a statement handle. */ -static int test_reset( +static int SQLITE_TCLAPI test_reset( void * clientData, Tcl_Interp *interp, int objc, @@ -2539,7 +2539,7 @@ static int test_reset( ** ** Return TRUE if a recompilation of the statement is recommended. */ -static int test_expired( +static int SQLITE_TCLAPI test_expired( void * clientData, Tcl_Interp *interp, int objc, @@ -2563,7 +2563,7 @@ static int test_expired( ** ** Transfer all bindings from FROMSTMT over to TOSTMT */ -static int test_transfer_bind( +static int SQLITE_TCLAPI test_transfer_bind( void * clientData, Tcl_Interp *interp, int objc, @@ -2590,7 +2590,7 @@ static int test_transfer_bind( ** Return the number of changes made to the database by the last SQL ** execution. */ -static int test_changes( +static int SQLITE_TCLAPI test_changes( void * clientData, Tcl_Interp *interp, int objc, @@ -2625,7 +2625,7 @@ static int sqlite_static_bind_nbyte = 0; ** of the VALUE is made. If FLAGS=="blob10" then a VALUE is ignored ** an a 10-byte blob "abc\000xyz\000pq" is inserted. */ -static int test_bind( +static int SQLITE_TCLAPI test_bind( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -2747,7 +2747,7 @@ static int test_collate_func( Tcl_GetIntFromObj(i, Tcl_GetObjResult(i), &res); return res; } -static int test_collate( +static int SQLITE_TCLAPI test_collate( void * clientData, Tcl_Interp *interp, int objc, @@ -2821,7 +2821,7 @@ static int test_utf16bin_collate_func( if( res==0 ) res = nA - nB; return res; } -static int test_utf16bin_collate( +static int SQLITE_TCLAPI test_utf16bin_collate( void * clientData, Tcl_Interp *interp, int objc, @@ -2878,7 +2878,7 @@ static void test_collate_needed_cb( /* ** Usage: add_test_collate_needed DB */ -static int test_collate_needed( +static int SQLITE_TCLAPI test_collate_needed( void * clientData, Tcl_Interp *interp, int objc, @@ -2929,7 +2929,7 @@ static int alignmentCollFunc( } return rc; } -static int add_alignment_test_collations( +static int SQLITE_TCLAPI add_alignment_test_collations( void * clientData, Tcl_Interp *interp, int objc, @@ -3047,7 +3047,7 @@ static void test_function_utf16be( sqlite3ValueFree(pVal); } #endif /* SQLITE_OMIT_UTF16 */ -static int test_function( +static int SQLITE_TCLAPI test_function( void * clientData, Tcl_Interp *interp, int objc, @@ -3092,7 +3092,7 @@ bad_args: ** The result is a list of two elements, the string representation of the ** error code and the english language explanation. */ -static int test_errstr( +static int SQLITE_TCLAPI test_errstr( void * clientData, Tcl_Interp *interp, int objc, @@ -3125,7 +3125,7 @@ static int test_errstr( ** Then run testfixture in the debugger and wait for the breakpoint to ** fire. Then additional breakpoints can be set to trace down the bug. */ -static int test_breakpoint( +static int SQLITE_TCLAPI test_breakpoint( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -3141,7 +3141,7 @@ static int test_breakpoint( ** IDX is the index of a wildcard in the prepared statement. This command ** binds a N-byte zero-filled BLOB to the wildcard. */ -static int test_bind_zeroblob( +static int SQLITE_TCLAPI test_bind_zeroblob( void * clientData, Tcl_Interp *interp, int objc, @@ -3177,7 +3177,7 @@ static int test_bind_zeroblob( ** IDX is the index of a wildcard in the prepared statement. This command ** binds a N-byte zero-filled BLOB to the wildcard. */ -static int test_bind_zeroblob64( +static int SQLITE_TCLAPI test_bind_zeroblob64( void * clientData, Tcl_Interp *interp, int objc, @@ -3214,7 +3214,7 @@ static int test_bind_zeroblob64( ** N is the index of a wildcard in the prepared statement. This command ** binds a 32-bit integer VALUE to that wildcard. */ -static int test_bind_int( +static int SQLITE_TCLAPI test_bind_int( void * clientData, Tcl_Interp *interp, int objc, @@ -3254,7 +3254,7 @@ static int test_bind_int( ** with no arguments in order to release memory. Each call to this procedure ** overwrites the previous array. */ -static int test_intarray_addr( +static int SQLITE_TCLAPI test_intarray_addr( void * clientData, Tcl_Interp *interp, int objc, @@ -3288,7 +3288,7 @@ static int test_intarray_addr( ** with no arguments in order to release memory. Each call to this procedure ** overwrites the previous array. */ -static int test_int64array_addr( +static int SQLITE_TCLAPI test_int64array_addr( void * clientData, Tcl_Interp *interp, int objc, @@ -3324,7 +3324,7 @@ static int test_int64array_addr( ** with no arguments in order to release memory. Each call to this procedure ** overwrites the previous array. */ -static int test_doublearray_addr( +static int SQLITE_TCLAPI test_doublearray_addr( void * clientData, Tcl_Interp *interp, int objc, @@ -3358,7 +3358,7 @@ static int test_doublearray_addr( ** with no arguments in order to release memory. Each call to this procedure ** overwrites the previous array. */ -static int test_textarray_addr( +static int SQLITE_TCLAPI test_textarray_addr( void * clientData, Tcl_Interp *interp, int objc, @@ -3391,7 +3391,7 @@ static int test_textarray_addr( ** N is the index of a wildcard in the prepared statement. This command ** binds a 64-bit integer VALUE to that wildcard. */ -static int test_bind_int64( +static int SQLITE_TCLAPI test_bind_int64( void * clientData, Tcl_Interp *interp, int objc, @@ -3429,7 +3429,7 @@ static int test_bind_int64( ** N is the index of a wildcard in the prepared statement. This command ** binds a 64-bit integer VALUE to that wildcard. */ -static int test_bind_double( +static int SQLITE_TCLAPI test_bind_double( void * clientData, Tcl_Interp *interp, int objc, @@ -3505,7 +3505,7 @@ static int test_bind_double( ** N is the index of a wildcard in the prepared statement. This command ** binds a NULL to the wildcard. */ -static int test_bind_null( +static int SQLITE_TCLAPI test_bind_null( void * clientData, Tcl_Interp *interp, int objc, @@ -3541,7 +3541,7 @@ static int test_bind_null( ** binds a UTF-8 string STRING to the wildcard. The string is BYTES bytes ** long. */ -static int test_bind_text( +static int SQLITE_TCLAPI test_bind_text( void * clientData, Tcl_Interp *interp, int objc, @@ -3582,7 +3582,7 @@ static int test_bind_text( ** binds a UTF-16 string STRING to the wildcard. The string is BYTES bytes ** long. */ -static int test_bind_text16( +static int SQLITE_TCLAPI test_bind_text16( void * clientData, Tcl_Interp *interp, int objc, @@ -3630,7 +3630,7 @@ static int test_bind_text16( ** N is the index of a wildcard in the prepared statement. This command ** binds a BLOB to the wildcard. The BLOB is BYTES bytes in size. */ -static int test_bind_blob( +static int SQLITE_TCLAPI test_bind_blob( void * clientData, Tcl_Interp *interp, int objc, @@ -3682,7 +3682,7 @@ static int test_bind_blob( ** ** Return the number of wildcards in the given statement. */ -static int test_bind_parameter_count( +static int SQLITE_TCLAPI test_bind_parameter_count( void * clientData, Tcl_Interp *interp, int objc, @@ -3706,7 +3706,7 @@ static int test_bind_parameter_count( ** An empty string is returned if N is out of range or if the wildcard ** is nameless. */ -static int test_bind_parameter_name( +static int SQLITE_TCLAPI test_bind_parameter_name( void * clientData, Tcl_Interp *interp, int objc, @@ -3733,7 +3733,7 @@ static int test_bind_parameter_name( ** Return the index of the wildcard called NAME. Return 0 if there is ** no such wildcard. */ -static int test_bind_parameter_index( +static int SQLITE_TCLAPI test_bind_parameter_index( void * clientData, Tcl_Interp *interp, int objc, @@ -3758,7 +3758,7 @@ static int test_bind_parameter_index( ** Usage: sqlite3_clear_bindings STMT ** */ -static int test_clear_bindings( +static int SQLITE_TCLAPI test_clear_bindings( void * clientData, Tcl_Interp *interp, int objc, @@ -3778,7 +3778,7 @@ static int test_clear_bindings( /* ** Usage: sqlite3_sleep MILLISECONDS */ -static int test_sleep( +static int SQLITE_TCLAPI test_sleep( void * clientData, Tcl_Interp *interp, int objc, @@ -3803,7 +3803,7 @@ static int test_sleep( ** Return the string representation of the most recent sqlite3_* API ** error code. e.g. "SQLITE_ERROR". */ -static int test_ex_errcode( +static int SQLITE_TCLAPI test_ex_errcode( void * clientData, Tcl_Interp *interp, int objc, @@ -3830,7 +3830,7 @@ static int test_ex_errcode( ** Return the string representation of the most recent sqlite3_* API ** error code. e.g. "SQLITE_ERROR". */ -static int test_errcode( +static int SQLITE_TCLAPI test_errcode( void * clientData, Tcl_Interp *interp, int objc, @@ -3856,7 +3856,7 @@ static int test_errcode( ** Returns the UTF-8 representation of the error message string for the ** most recent sqlite3_* API call. */ -static int test_errmsg( +static int SQLITE_TCLAPI test_errmsg( void * clientData, Tcl_Interp *interp, int objc, @@ -3885,7 +3885,7 @@ static int test_errmsg( ** level, and it includes the 0x00 0x00 terminator bytes at the end of the ** UTF-16 string. */ -static int test_errmsg16( +static int SQLITE_TCLAPI test_errmsg16( void * clientData, Tcl_Interp *interp, int objc, @@ -3922,7 +3922,7 @@ static int test_errmsg16( ** variable that is set to the unused portion of (if any). A ** STMT handle is returned. */ -static int test_prepare( +static int SQLITE_TCLAPI test_prepare( void * clientData, Tcl_Interp *interp, int objc, @@ -3979,7 +3979,7 @@ static int test_prepare( ** variable that is set to the unused portion of (if any). A ** STMT handle is returned. */ -static int test_prepare_v2( +static int SQLITE_TCLAPI test_prepare_v2( void * clientData, Tcl_Interp *interp, int objc, @@ -4047,7 +4047,7 @@ static int test_prepare_v2( ** Generate a prepared statement for a zero-byte string as a test ** for ticket #3134. The string should be preceded by a zero byte. */ -static int test_prepare_tkt3134( +static int SQLITE_TCLAPI test_prepare_tkt3134( void * clientData, Tcl_Interp *interp, int objc, @@ -4090,7 +4090,7 @@ static int test_prepare_tkt3134( ** variable that is set to the unused portion of (if any). A ** STMT handle is returned. */ -static int test_prepare16( +static int SQLITE_TCLAPI test_prepare16( void * clientData, Tcl_Interp *interp, int objc, @@ -4150,7 +4150,7 @@ static int test_prepare16( ** variable that is set to the unused portion of (if any). A ** STMT handle is returned. */ -static int test_prepare16_v2( +static int SQLITE_TCLAPI test_prepare16_v2( void * clientData, Tcl_Interp *interp, int objc, @@ -4205,7 +4205,7 @@ static int test_prepare16_v2( /* ** Usage: sqlite3_open filename ?options-list? */ -static int test_open( +static int SQLITE_TCLAPI test_open( void * clientData, Tcl_Interp *interp, int objc, @@ -4232,7 +4232,7 @@ static int test_open( /* ** Usage: sqlite3_open_v2 FILENAME FLAGS VFS */ -static int test_open_v2( +static int SQLITE_TCLAPI test_open_v2( void * clientData, Tcl_Interp *interp, int objc, @@ -4302,7 +4302,7 @@ static int test_open_v2( /* ** Usage: sqlite3_open16 filename options */ -static int test_open16( +static int SQLITE_TCLAPI test_open16( void * clientData, Tcl_Interp *interp, int objc, @@ -4334,7 +4334,7 @@ static int test_open16( ** Return 1 if the supplied argument is a complete SQL statement, or zero ** otherwise. */ -static int test_complete16( +static int SQLITE_TCLAPI test_complete16( void * clientData, Tcl_Interp *interp, int objc, @@ -4359,7 +4359,7 @@ static int test_complete16( ** ** Advance the statement to the next row. */ -static int test_step( +static int SQLITE_TCLAPI test_step( void * clientData, Tcl_Interp *interp, int objc, @@ -4382,7 +4382,7 @@ static int test_step( return TCL_OK; } -static int test_sql( +static int SQLITE_TCLAPI test_sql( void * clientData, Tcl_Interp *interp, int objc, @@ -4399,7 +4399,7 @@ static int test_sql( Tcl_SetResult(interp, (char *)sqlite3_sql(pStmt), TCL_VOLATILE); return TCL_OK; } -static int test_ex_sql( +static int SQLITE_TCLAPI test_ex_sql( void * clientData, Tcl_Interp *interp, int objc, @@ -4425,7 +4425,7 @@ static int test_ex_sql( ** ** Return the number of columns returned by the sql statement STMT. */ -static int test_column_count( +static int SQLITE_TCLAPI test_column_count( void * clientData, Tcl_Interp *interp, int objc, @@ -4450,7 +4450,7 @@ static int test_column_count( ** ** Return the type of the data in column 'column' of the current row. */ -static int test_column_type( +static int SQLITE_TCLAPI test_column_type( void * clientData, Tcl_Interp *interp, int objc, @@ -4499,7 +4499,7 @@ static int test_column_type( ** Return the data in column 'column' of the current row cast as an ** wide (64-bit) integer. */ -static int test_column_int64( +static int SQLITE_TCLAPI test_column_int64( void * clientData, Tcl_Interp *interp, int objc, @@ -4526,7 +4526,7 @@ static int test_column_int64( /* ** Usage: sqlite3_column_blob STMT column */ -static int test_column_blob( +static int SQLITE_TCLAPI test_column_blob( void * clientData, Tcl_Interp *interp, int objc, @@ -4558,7 +4558,7 @@ static int test_column_blob( ** ** Return the data in column 'column' of the current row cast as a double. */ -static int test_column_double( +static int SQLITE_TCLAPI test_column_double( void * clientData, Tcl_Interp *interp, int objc, @@ -4587,7 +4587,7 @@ static int test_column_double( ** ** Return the number of columns returned by the sql statement STMT. */ -static int test_data_count( +static int SQLITE_TCLAPI test_data_count( void * clientData, Tcl_Interp *interp, int objc, @@ -4614,7 +4614,7 @@ static int test_data_count( ** ** Usage: sqlite3_column_name STMT column */ -static int test_stmt_utf8( +static int SQLITE_TCLAPI test_stmt_utf8( void * clientData, /* Pointer to SQLite API function to be invoke */ Tcl_Interp *interp, int objc, @@ -4641,7 +4641,7 @@ static int test_stmt_utf8( return TCL_OK; } -static int test_global_recover( +static int SQLITE_TCLAPI test_global_recover( void * clientData, Tcl_Interp *interp, int objc, @@ -4666,7 +4666,7 @@ static int test_global_recover( ** ** Usage: sqlite3_column_name STMT column */ -static int test_stmt_utf16( +static int SQLITE_TCLAPI test_stmt_utf16( void * clientData, /* Pointer to SQLite API function to be invoked */ Tcl_Interp *interp, int objc, @@ -4710,7 +4710,7 @@ static int test_stmt_utf16( ** Usage: sqlite3_column_bytes16 STMT column ** */ -static int test_stmt_int( +static int SQLITE_TCLAPI test_stmt_int( void * clientData, /* Pointer to SQLite API function to be invoked */ Tcl_Interp *interp, int objc, @@ -4739,7 +4739,7 @@ static int test_stmt_int( ** ** Set the db->magic value. This is used to test error recovery logic. */ -static int sqlite_set_magic( +static int SQLITE_TCLAPI sqlite_set_magic( void * clientData, Tcl_Interp *interp, int argc, @@ -4771,7 +4771,7 @@ static int sqlite_set_magic( ** ** Trigger an interrupt on DB */ -static int test_interrupt( +static int SQLITE_TCLAPI test_interrupt( void * clientData, Tcl_Interp *interp, int argc, @@ -4812,7 +4812,7 @@ u64 sqlite3StackDepth(void){ ** ** Try to measure the amount of stack space used by a call to sqlite3_exec */ -static int test_stack_used( +static int SQLITE_TCLAPI test_stack_used( void * clientData, Tcl_Interp *interp, int argc, @@ -4840,7 +4840,7 @@ static int test_stack_used( ** is assumed that the user function was created as UTF8, any number of ** arguments (the way the TCL interface does it). */ -static int delete_function( +static int SQLITE_TCLAPI delete_function( void * clientData, Tcl_Interp *interp, int argc, @@ -4866,7 +4866,7 @@ static int delete_function( ** DB. It is assumed that the collation sequence was created as UTF8 (the ** way the TCL interface does it). */ -static int delete_collation( +static int SQLITE_TCLAPI delete_collation( void * clientData, Tcl_Interp *interp, int argc, @@ -4891,7 +4891,7 @@ static int delete_collation( ** Return true if the database DB is currently in auto-commit mode. ** Return false if not. */ -static int get_autocommit( +static int SQLITE_TCLAPI get_autocommit( void * clientData, Tcl_Interp *interp, int argc, @@ -4917,7 +4917,7 @@ static int get_autocommit( ** method of the TCL interface. But we need a way to test the case ** where it returns SQLITE_MISUSE. */ -static int test_busy_timeout( +static int SQLITE_TCLAPI test_busy_timeout( void * clientData, Tcl_Interp *interp, int argc, @@ -4943,7 +4943,7 @@ static int test_busy_timeout( ** Return the name of the internal representation for the ** value of the given variable. */ -static int tcl_variable_type( +static int SQLITE_TCLAPI tcl_variable_type( void * clientData, Tcl_Interp *interp, int objc, @@ -4969,7 +4969,7 @@ static int tcl_variable_type( ** The integer N is the number of bytes we are trying to release. The ** return value is the amount of memory actually released. */ -static int test_release_memory( +static int SQLITE_TCLAPI test_release_memory( void * clientData, Tcl_Interp *interp, int objc, @@ -5000,7 +5000,7 @@ static int test_release_memory( ** Attempt to release memory currently held by database DB. Return the ** result code (which in the current implementation is always zero). */ -static int test_db_release_memory( +static int SQLITE_TCLAPI test_db_release_memory( void * clientData, Tcl_Interp *interp, int objc, @@ -5023,7 +5023,7 @@ static int test_db_release_memory( ** ** Attempt to flush any dirty pages to disk. */ -static int test_db_cacheflush( +static int SQLITE_TCLAPI test_db_cacheflush( void * clientData, Tcl_Interp *interp, int objc, @@ -5051,7 +5051,7 @@ static int test_db_cacheflush( ** ** Return the low-level system errno value. */ -static int test_system_errno( +static int SQLITE_TCLAPI test_system_errno( void * clientData, Tcl_Interp *interp, int objc, @@ -5074,7 +5074,7 @@ static int test_system_errno( ** ** Return the name of a file associated with a database. */ -static int test_db_filename( +static int SQLITE_TCLAPI test_db_filename( void * clientData, Tcl_Interp *interp, int objc, @@ -5098,7 +5098,7 @@ static int test_db_filename( ** Return 1 or 0 if DBNAME is readonly or not. Return -1 if DBNAME does ** not exist. */ -static int test_db_readonly( +static int SQLITE_TCLAPI test_db_readonly( void * clientData, Tcl_Interp *interp, int objc, @@ -5123,7 +5123,7 @@ static int test_db_readonly( ** limit is only changed if the N is present. The previous limit ** is returned. */ -static int test_soft_heap_limit( +static int SQLITE_TCLAPI test_soft_heap_limit( void * clientData, Tcl_Interp *interp, int objc, @@ -5148,7 +5148,7 @@ static int test_soft_heap_limit( ** ** Call the sqlite3_thread_cleanup API. */ -static int test_thread_cleanup( +static int SQLITE_TCLAPI test_thread_cleanup( void * clientData, Tcl_Interp *interp, int objc, @@ -5166,7 +5166,7 @@ static int test_thread_cleanup( ** Return a list of numbers which are the PagerRefcount for all ** pagers on each database connection. */ -static int test_pager_refcounts( +static int SQLITE_TCLAPI test_pager_refcounts( void * clientData, Tcl_Interp *interp, int objc, @@ -5212,7 +5212,7 @@ static int test_pager_refcounts( ** and that the errors they are seeing in the test scripts might be ** a result of their defective TCL rather than problems in SQLite. */ -static int working_64bit_int( +static int SQLITE_TCLAPI working_64bit_int( ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ @@ -5237,7 +5237,7 @@ static int working_64bit_int( ** VFS when none are previously registered, and the ability to ** unregister the only available VFS. Ticket #2738 */ -static int vfs_unlink_test( +static int SQLITE_TCLAPI vfs_unlink_test( ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ @@ -5339,7 +5339,7 @@ static int vfs_unlink_test( ** This TCL command attempts to vfs_find and vfs_register when the ** sqlite3_initialize() interface is failing. All calls should fail. */ -static int vfs_initfail_test( +static int SQLITE_TCLAPI vfs_initfail_test( ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ @@ -5367,7 +5367,7 @@ static int nVfs = 0; ** ** Unregister all VFSes. */ -static int vfs_unregister_all( +static int SQLITE_TCLAPI vfs_unregister_all( ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ @@ -5389,7 +5389,7 @@ static int vfs_unregister_all( ** care to put the linked list back together in the same order as it was ** in before vfs_unregister_all was invoked. */ -static int vfs_reregister_all( +static int SQLITE_TCLAPI vfs_reregister_all( ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ @@ -5409,7 +5409,7 @@ static int vfs_reregister_all( ** This TCL command runs the sqlite3_file_control interface and ** verifies correct operation of the same. */ -static int file_control_test( +static int SQLITE_TCLAPI file_control_test( ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ @@ -5444,7 +5444,7 @@ static int file_control_test( ** This TCL command runs the sqlite3_file_control interface and ** verifies correct operation of the SQLITE_LAST_ERRNO verb. */ -static int file_control_lasterrno_test( +static int SQLITE_TCLAPI file_control_lasterrno_test( ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ @@ -5482,7 +5482,7 @@ static int file_control_lasterrno_test( ** verifies correct operation of the SQLITE_GET_LOCKPROXYFILE and ** SQLITE_SET_LOCKPROXYFILE verbs. */ -static int file_control_chunksize_test( +static int SQLITE_TCLAPI file_control_chunksize_test( ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ @@ -5519,7 +5519,7 @@ static int file_control_chunksize_test( ** This TCL command runs the sqlite3_file_control interface ** with SQLITE_FCNTL_SIZE_HINT */ -static int file_control_sizehint_test( +static int SQLITE_TCLAPI file_control_sizehint_test( ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ @@ -5557,7 +5557,7 @@ static int file_control_sizehint_test( ** verifies correct operation of the SQLITE_GET_LOCKPROXYFILE and ** SQLITE_SET_LOCKPROXYFILE verbs. */ -static int file_control_lockproxy_test( +static int SQLITE_TCLAPI file_control_lockproxy_test( ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ @@ -5627,7 +5627,7 @@ static int file_control_lockproxy_test( ** This TCL command runs the sqlite3_file_control interface with ** the SQLITE_FCNTL_WIN32_AV_RETRY opcode. */ -static int file_control_win32_av_retry( +static int SQLITE_TCLAPI file_control_win32_av_retry( ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ @@ -5660,7 +5660,7 @@ static int file_control_win32_av_retry( ** This TCL command runs the sqlite3_file_control interface with ** the SQLITE_FCNTL_WIN32_SET_HANDLE opcode. */ -static int file_control_win32_set_handle( +static int SQLITE_TCLAPI file_control_win32_set_handle( ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ @@ -5696,7 +5696,7 @@ static int file_control_win32_set_handle( ** This TCL command runs the sqlite3_file_control interface with ** the SQLITE_FCNTL_PERSIST_WAL opcode. */ -static int file_control_persist_wal( +static int SQLITE_TCLAPI file_control_persist_wal( ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ @@ -5728,7 +5728,7 @@ static int file_control_persist_wal( ** This TCL command runs the sqlite3_file_control interface with ** the SQLITE_FCNTL_POWERSAFE_OVERWRITE opcode. */ -static int file_control_powersafe_overwrite( +static int SQLITE_TCLAPI file_control_powersafe_overwrite( ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ @@ -5760,7 +5760,7 @@ static int file_control_powersafe_overwrite( ** ** Return a string that describes the stack of VFSes. */ -static int file_control_vfsname( +static int SQLITE_TCLAPI file_control_vfsname( ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ @@ -5792,7 +5792,7 @@ static int file_control_vfsname( ** ** Return a string that is a temporary filename */ -static int file_control_tempfilename( +static int SQLITE_TCLAPI file_control_tempfilename( ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ @@ -5825,7 +5825,7 @@ static int file_control_tempfilename( ** ** Return a tcl list containing the names of all registered vfs's. */ -static int vfs_list( +static int SQLITE_TCLAPI vfs_list( ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ @@ -5850,7 +5850,7 @@ static int vfs_list( ** This TCL command runs the sqlite3_limit interface and ** verifies correct operation of the same. */ -static int test_limit( +static int SQLITE_TCLAPI test_limit( ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ @@ -5913,7 +5913,7 @@ static int test_limit( ** At the same time, verify that sqlite3_test_control works even when ** called with an out-of-range opcode. */ -static int save_prng_state( +static int SQLITE_TCLAPI save_prng_state( ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ @@ -5929,7 +5929,7 @@ static int save_prng_state( /* ** tclcmd: restore_prng_state */ -static int restore_prng_state( +static int SQLITE_TCLAPI restore_prng_state( ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ @@ -5941,7 +5941,7 @@ static int restore_prng_state( /* ** tclcmd: reset_prng_state */ -static int reset_prng_state( +static int SQLITE_TCLAPI reset_prng_state( ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ @@ -5957,7 +5957,7 @@ static int reset_prng_state( ** Indicate that database files might be corrupt. In other words, set the normal ** state of operation. */ -static int database_may_be_corrupt( +static int SQLITE_TCLAPI database_may_be_corrupt( ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ @@ -5972,7 +5972,7 @@ static int database_may_be_corrupt( ** Indicate that database files are always well-formed. This enables extra assert() ** statements that test conditions that are always true for well-formed databases. */ -static int database_never_corrupt( +static int SQLITE_TCLAPI database_never_corrupt( ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ @@ -5985,7 +5985,7 @@ static int database_never_corrupt( /* ** tclcmd: pcache_stats */ -static int test_pcache_stats( +static int SQLITE_TCLAPI test_pcache_stats( ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ @@ -6027,7 +6027,7 @@ static void test_unlock_notify_cb(void **aArg, int nArg){ ** tclcmd: sqlite3_unlock_notify db */ #ifdef SQLITE_ENABLE_UNLOCK_NOTIFY -static int test_unlock_notify( +static int SQLITE_TCLAPI test_unlock_notify( ClientData clientData, /* Unused */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ @@ -6053,7 +6053,7 @@ static int test_unlock_notify( /* ** tclcmd: sqlite3_wal_checkpoint db ?NAME? */ -static int test_wal_checkpoint( +static int SQLITE_TCLAPI test_wal_checkpoint( ClientData clientData, /* Unused */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ @@ -6097,7 +6097,7 @@ static int test_wal_checkpoint( ** the number of frames in the log and the number of frames in the log ** that have been checkpointed. */ -static int test_wal_checkpoint_v2( +static int SQLITE_TCLAPI test_wal_checkpoint_v2( ClientData clientData, /* Unused */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ @@ -6153,7 +6153,7 @@ static int test_wal_checkpoint_v2( /* ** tclcmd: sqlite3_wal_autocheckpoint db VALUE */ -static int test_wal_autocheckpoint( +static int SQLITE_TCLAPI test_wal_autocheckpoint( ClientData clientData, /* Unused */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ @@ -6204,7 +6204,7 @@ static void xLogcallback(void *unused, int err, char *zMsg){ Tcl_EvalObjEx(logcallback.pInterp, pNew, TCL_EVAL_GLOBAL|TCL_EVAL_DIRECT); Tcl_DecrRefCount(pNew); } -static int test_sqlite3_log( +static int SQLITE_TCLAPI test_sqlite3_log( ClientData clientData, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ @@ -6235,7 +6235,7 @@ static int test_sqlite3_log( ** Run a TCL command using its objProc interface. Throw an error if ** the command has no objProc interface. */ -static int runAsObjProc( +static int SQLITE_TCLAPI runAsObjProc( void * clientData, Tcl_Interp *interp, int objc, @@ -6298,7 +6298,7 @@ int printExplainQueryPlan(sqlite3_stmt *pStmt){ return sqlite3_finalize(pExplain); } -static int test_print_eqp( +static int SQLITE_TCLAPI test_print_eqp( void * clientData, Tcl_Interp *interp, int objc, @@ -6326,7 +6326,7 @@ static int test_print_eqp( /* ** sqlite3_test_control VERB ARGS... */ -static int test_test_control( +static int SQLITE_TCLAPI test_test_control( void * clientData, Tcl_Interp *interp, int objc, @@ -6405,7 +6405,7 @@ static int test_test_control( #include #include -static int test_getrusage( +static int SQLITE_TCLAPI test_getrusage( void * clientData, Tcl_Interp *interp, int objc, @@ -6479,7 +6479,7 @@ static void SQLITE_CDECL win32_file_locker(void *pAppData){ ** Get an exclusive manditory lock on file for DELAY2 milliseconds. ** Wait DELAY1 milliseconds before acquiring the lock. */ -static int win32_file_lock( +static int SQLITE_TCLAPI win32_file_lock( void * clientData, Tcl_Interp *interp, int objc, @@ -6543,7 +6543,7 @@ static int win32_file_lock( ** Returns non-zero if the specified path exists, whose fully qualified name ** may exceed 260 characters if it is prefixed with "\\?\". */ -static int win32_exists_path( +static int SQLITE_TCLAPI win32_exists_path( void *clientData, Tcl_Interp *interp, int objc, @@ -6565,7 +6565,7 @@ static int win32_exists_path( ** whose fully qualified name may exceed 248 characters if it is prefixed with ** "\\?\". */ -static int win32_find_file( +static int SQLITE_TCLAPI win32_find_file( void *clientData, Tcl_Interp *interp, int objc, @@ -6610,7 +6610,7 @@ static int win32_find_file( ** Deletes the specified file, whose fully qualified name may exceed 260 ** characters if it is prefixed with "\\?\". */ -static int win32_delete_file( +static int SQLITE_TCLAPI win32_delete_file( void *clientData, Tcl_Interp *interp, int objc, @@ -6634,7 +6634,7 @@ static int win32_delete_file( ** Creates the specified directory, whose fully qualified name may exceed 248 ** characters if it is prefixed with "\\?\". */ -static int win32_mkdir( +static int SQLITE_TCLAPI win32_mkdir( void *clientData, Tcl_Interp *interp, int objc, @@ -6658,7 +6658,7 @@ static int win32_mkdir( ** Removes the specified directory, whose fully qualified name may exceed 248 ** characters if it is prefixed with "\\?\". */ -static int win32_rmdir( +static int SQLITE_TCLAPI win32_rmdir( void *clientData, Tcl_Interp *interp, int objc, @@ -6685,7 +6685,7 @@ static int win32_rmdir( ** interface. Disable if BOOLEAN is false and enable if BOOLEAN is true. ** OPT is the name of the optimization to be disabled. */ -static int optimization_control( +static int SQLITE_TCLAPI optimization_control( void * clientData, Tcl_Interp *interp, int objc, @@ -6748,7 +6748,7 @@ typedef struct sqlite3_api_routines sqlite3_api_routines; ** ** Load one or more statically linked extensions. */ -static int tclLoadStaticExtensionCmd( +static int SQLITE_TCLAPI tclLoadStaticExtensionCmd( void * clientData, Tcl_Interp *interp, int objc, @@ -6826,7 +6826,7 @@ static int tclLoadStaticExtensionCmd( ** sorter_test_fakeheap BOOL ** */ -static int sorter_test_fakeheap( +static int SQLITE_TCLAPI sorter_test_fakeheap( void * clientData, Tcl_Interp *interp, int objc, @@ -6866,7 +6866,7 @@ static int sorter_test_fakeheap( ** Then execute statement $SQL2. Check that the statement returns the same ** set of integers in the same order as in the previous step (using $SQL1). */ -static int sorter_test_sort4_helper( +static int SQLITE_TCLAPI sorter_test_sort4_helper( void * clientData, Tcl_Interp *interp, int objc, @@ -6935,7 +6935,7 @@ static int sorter_test_sort4_helper( /* ** tclcmd: sqlite3_user_authenticate DB USERNAME PASSWORD */ -static int test_user_authenticate( +static int SQLITE_TCLAPI test_user_authenticate( ClientData clientData, /* Unused */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ @@ -6966,7 +6966,7 @@ static int test_user_authenticate( /* ** tclcmd: sqlite3_user_add DB USERNAME PASSWORD ISADMIN */ -static int test_user_add( +static int SQLITE_TCLAPI test_user_add( ClientData clientData, /* Unused */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ @@ -6999,7 +6999,7 @@ static int test_user_add( /* ** tclcmd: sqlite3_user_change DB USERNAME PASSWORD ISADMIN */ -static int test_user_change( +static int SQLITE_TCLAPI test_user_change( ClientData clientData, /* Unused */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ @@ -7032,7 +7032,7 @@ static int test_user_change( /* ** tclcmd: sqlite3_user_delete DB USERNAME */ -static int test_user_delete( +static int SQLITE_TCLAPI test_user_delete( ClientData clientData, /* Unused */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ @@ -7069,7 +7069,7 @@ static int test_user_delete( ** 3 Read after free ** 4 Panic */ -static int test_bad_behavior( +static int SQLITE_TCLAPI test_bad_behavior( ClientData clientData, /* Pointer to an integer containing zero */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ @@ -7119,7 +7119,7 @@ static int test_bad_behavior( ** ** Cause the dbstat virtual table to be available on the connection DB */ -static int test_register_dbstat_vtab( +static int SQLITE_TCLAPI test_register_dbstat_vtab( void *clientData, Tcl_Interp *interp, int objc, @@ -7153,7 +7153,7 @@ static int test_register_dbstat_vtab( ** ** Invoke sqlite3_db_config() for one of the setting values. */ -static int test_sqlite3_db_config( +static int SQLITE_TCLAPI test_sqlite3_db_config( void *clientData, Tcl_Interp *interp, int objc, @@ -7210,7 +7210,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){ extern int sqlite3_hostid_num; #endif extern int sqlite3_max_blobsize; - extern int sqlite3BtreeSharedCacheReport(void*, + extern int SQLITE_TCLAPI sqlite3BtreeSharedCacheReport(void*, Tcl_Interp*,int,Tcl_Obj*CONST*); static int iZero = 0; static struct { diff --git a/src/test2.c b/src/test2.c index 8946196ff3..dfca1d2b31 100644 --- a/src/test2.c +++ b/src/test2.c @@ -42,7 +42,7 @@ static void pager_test_reiniter(DbPage *pNotUsed){ ** ** Open a new pager */ -static int pager_open( +static int SQLITE_TCLAPI pager_open( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -79,7 +79,7 @@ static int pager_open( ** ** Close the given pager. */ -static int pager_close( +static int SQLITE_TCLAPI pager_close( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -106,7 +106,7 @@ static int pager_close( ** ** Rollback changes */ -static int pager_rollback( +static int SQLITE_TCLAPI pager_rollback( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -133,7 +133,7 @@ static int pager_rollback( ** ** Commit all changes */ -static int pager_commit( +static int SQLITE_TCLAPI pager_commit( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -165,7 +165,7 @@ static int pager_commit( ** ** Start a new checkpoint. */ -static int pager_stmt_begin( +static int SQLITE_TCLAPI pager_stmt_begin( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -192,7 +192,7 @@ static int pager_stmt_begin( ** ** Rollback changes to a checkpoint */ -static int pager_stmt_rollback( +static int SQLITE_TCLAPI pager_stmt_rollback( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -220,7 +220,7 @@ static int pager_stmt_rollback( ** ** Commit changes to a checkpoint */ -static int pager_stmt_commit( +static int SQLITE_TCLAPI pager_stmt_commit( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -247,7 +247,7 @@ static int pager_stmt_commit( ** ** Return pager statistics. */ -static int pager_stats( +static int SQLITE_TCLAPI pager_stats( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -280,7 +280,7 @@ static int pager_stats( ** ** Return the size of the database file. */ -static int pager_pagecount( +static int SQLITE_TCLAPI pager_pagecount( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -306,7 +306,7 @@ static int pager_pagecount( ** ** Return a pointer to a page from the database. */ -static int page_get( +static int SQLITE_TCLAPI page_get( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -343,7 +343,7 @@ static int page_get( ** Return a pointer to a page if the page is already in cache. ** If not in cache, return an empty string. */ -static int page_lookup( +static int SQLITE_TCLAPI page_lookup( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -371,7 +371,7 @@ static int page_lookup( /* ** Usage: pager_truncate ID PGNO */ -static int pager_truncate( +static int SQLITE_TCLAPI pager_truncate( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -396,7 +396,7 @@ static int pager_truncate( ** ** Drop a pointer to a page. */ -static int page_unref( +static int SQLITE_TCLAPI page_unref( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -418,7 +418,7 @@ static int page_unref( ** ** Return the content of a page */ -static int page_read( +static int SQLITE_TCLAPI page_read( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -442,7 +442,7 @@ static int page_read( ** ** Return the page number for a page. */ -static int page_number( +static int SQLITE_TCLAPI page_number( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -466,7 +466,7 @@ static int page_number( ** ** Write something into a page. */ -static int page_write( +static int SQLITE_TCLAPI page_write( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -502,7 +502,7 @@ static int page_write( ** new pages after N. If N is 2096 or bigger, this will test the ** ability of SQLite to write to large files. */ -static int fake_big_file( +static int SQLITE_TCLAPI fake_big_file( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -555,7 +555,7 @@ static int fake_big_file( ** ** Set the PENDING_BYTE using the sqlite3_test_control() interface. */ -static int testPendingByte( +static int SQLITE_TCLAPI testPendingByte( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -620,7 +620,7 @@ static int faultSimCallback(int x){ ** appended, whenever sqlite3FaultSim() is called. Or, if SCRIPT is the ** empty string, cancel the sqlite3FaultSim() callback. */ -static int faultInstallCmd( +static int SQLITE_TCLAPI faultInstallCmd( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -663,7 +663,7 @@ static int faultInstallCmd( ** Invoke the SQLITE_TESTCTRL_BITVEC_TEST operator on test_control. ** See comments on sqlite3BitvecBuiltinTest() for additional information. */ -static int testBitvecBuiltinTest( +static int SQLITE_TCLAPI testBitvecBuiltinTest( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ diff --git a/src/test3.c b/src/test3.c index f1b9f37924..6995684c29 100644 --- a/src/test3.c +++ b/src/test3.c @@ -37,7 +37,7 @@ static int nRefSqlite3 = 0; ** ** Open a new database */ -static int btree_open( +static int SQLITE_TCLAPI btree_open( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -83,7 +83,7 @@ static int btree_open( ** ** Close the given database. */ -static int btree_close( +static int SQLITE_TCLAPI btree_close( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -118,7 +118,7 @@ static int btree_close( ** ** Start a new transaction */ -static int btree_begin_transaction( +static int SQLITE_TCLAPI btree_begin_transaction( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -147,7 +147,7 @@ static int btree_begin_transaction( ** ** Returns pager statistics */ -static int btree_pager_stats( +static int SQLITE_TCLAPI btree_pager_stats( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -197,7 +197,7 @@ static int btree_pager_stats( ** ** Create a new cursor. Return the ID for the cursor. */ -static int btree_cursor( +static int SQLITE_TCLAPI btree_cursor( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -246,7 +246,7 @@ static int btree_cursor( ** ** Close a cursor opened using btree_cursor. */ -static int btree_close_cursor( +static int SQLITE_TCLAPI btree_close_cursor( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -283,7 +283,7 @@ static int btree_close_cursor( ** or 1 if the cursor was already on the last entry in the table or if ** the table is empty. */ -static int btree_next( +static int SQLITE_TCLAPI btree_next( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -318,7 +318,7 @@ static int btree_next( ** Move the cursor to the first entry in the table. Return 0 if the ** cursor was left point to something and 1 if the table is empty. */ -static int btree_first( +static int SQLITE_TCLAPI btree_first( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -353,7 +353,7 @@ static int btree_first( ** Return TRUE if the given cursor is not pointing at a valid entry. ** Return FALSE if the cursor does point to a valid entry. */ -static int btree_eof( +static int SQLITE_TCLAPI btree_eof( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -382,7 +382,7 @@ static int btree_eof( ** ** Return the number of bytes of payload */ -static int btree_payload_size( +static int SQLITE_TCLAPI btree_payload_size( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -420,7 +420,7 @@ static int btree_payload_size( ** This command returns nothing if it works. It returns an error message ** if something goes wrong. */ -static int btree_varint_test( +static int SQLITE_TCLAPI btree_varint_test( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -504,7 +504,7 @@ static int btree_varint_test( ** sqlite3 db test.db ** set bt [btree_from_db db] */ -static int btree_from_db( +static int SQLITE_TCLAPI btree_from_db( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -544,7 +544,7 @@ static int btree_from_db( ** ** Return true if the B-Tree is currently stored entirely in memory. */ -static int btree_ismemdb( +static int SQLITE_TCLAPI btree_ismemdb( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -575,7 +575,7 @@ static int btree_ismemdb( ** ** Set the size of the cache used by btree $ID. */ -static int btree_set_cache_size( +static int SQLITE_TCLAPI btree_set_cache_size( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -605,7 +605,7 @@ static int btree_set_cache_size( ** ** Set the size of the cache used by btree $ID. */ -static int btree_insert( +static int SQLITE_TCLAPI btree_insert( ClientData clientData, Tcl_Interp *interp, int objc, diff --git a/src/test4.c b/src/test4.c index 85b521b060..c5b5ec12cc 100644 --- a/src/test4.c +++ b/src/test4.c @@ -125,7 +125,7 @@ static int parse_thread_id(Tcl_Interp *interp, const char *zArg){ ** NAME should be an upper case letter. Start the thread running with ** an open connection to the given database. */ -static int tcl_thread_create( +static int SQLITE_TCLAPI tcl_thread_create( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -174,7 +174,7 @@ static void thread_wait(Thread *p){ ** ** Wait on thread ID to reach its idle state. */ -static int tcl_thread_wait( +static int SQLITE_TCLAPI tcl_thread_wait( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -218,7 +218,7 @@ static void stop_thread(Thread *p){ ** Cause a thread to shut itself down. Wait for the shutdown to be ** completed. If ID is "*" then stop all threads. */ -static int tcl_thread_halt( +static int SQLITE_TCLAPI tcl_thread_halt( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -253,7 +253,7 @@ static int tcl_thread_halt( ** Wait on the most recent thread_step to complete, then return the ** number of columns in the result set. */ -static int tcl_thread_argc( +static int SQLITE_TCLAPI tcl_thread_argc( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -285,7 +285,7 @@ static int tcl_thread_argc( ** Wait on the most recent thread_step to complete, then return the ** value of the N-th columns in the result set. */ -static int tcl_thread_argv( +static int SQLITE_TCLAPI tcl_thread_argv( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -321,7 +321,7 @@ static int tcl_thread_argv( ** Wait on the most recent thread_step to complete, then return the ** name of the N-th columns in the result set. */ -static int tcl_thread_colname( +static int SQLITE_TCLAPI tcl_thread_colname( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -357,7 +357,7 @@ static int tcl_thread_colname( ** Wait on the most recent operation to complete, then return the ** result code from that operation. */ -static int tcl_thread_result( +static int SQLITE_TCLAPI tcl_thread_result( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -389,7 +389,7 @@ static int tcl_thread_result( ** Wait on the most recent operation to complete, then return the ** error string. */ -static int tcl_thread_error( +static int SQLITE_TCLAPI tcl_thread_error( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -434,7 +434,7 @@ static void do_compile(Thread *p){ ** ** Compile a new virtual machine. */ -static int tcl_thread_compile( +static int SQLITE_TCLAPI tcl_thread_compile( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -487,7 +487,7 @@ static void do_step(Thread *p){ ** ** Advance the virtual machine by one step */ -static int tcl_thread_step( +static int SQLITE_TCLAPI tcl_thread_step( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -529,7 +529,7 @@ static void do_finalize(Thread *p){ ** ** Finalize the virtual machine. */ -static int tcl_thread_finalize( +static int SQLITE_TCLAPI tcl_thread_finalize( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -560,7 +560,7 @@ static int tcl_thread_finalize( ** ** Interchange the sqlite* pointer between two threads. */ -static int tcl_thread_swap( +static int SQLITE_TCLAPI tcl_thread_swap( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -600,7 +600,7 @@ static int tcl_thread_swap( ** remove the pointer from the thread itself. Afterwards, the thread ** can be stopped and the connection can be used by the main thread. */ -static int tcl_thread_db_get( +static int SQLITE_TCLAPI tcl_thread_db_get( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -631,7 +631,7 @@ static int tcl_thread_db_get( ** Usage: thread_db_put ID DB ** */ -static int tcl_thread_db_put( +static int SQLITE_TCLAPI tcl_thread_db_put( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -663,7 +663,7 @@ static int tcl_thread_db_put( ** Return the database stmt pointer for the given thread. Then ** remove the pointer from the thread itself. */ -static int tcl_thread_stmt_get( +static int SQLITE_TCLAPI tcl_thread_stmt_get( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ diff --git a/src/test5.c b/src/test5.c index 2b49e408b6..0d9242862b 100644 --- a/src/test5.c +++ b/src/test5.c @@ -30,7 +30,7 @@ ** object with the encoded representation of the string, including ** the NULL terminator. */ -static int binarize( +static int SQLITE_TCLAPI binarize( void * clientData, Tcl_Interp *interp, int objc, @@ -58,7 +58,7 @@ static int binarize( ** If is 0, then the calls to sqlite3_value_text() are not ** actually made. */ -static int test_value_overhead( +static int SQLITE_TCLAPI test_value_overhead( void * clientData, Tcl_Interp *interp, int objc, @@ -122,7 +122,7 @@ static u8 name_to_enc(Tcl_Interp *interp, Tcl_Obj *pObj){ ** Usage: test_translate ?? ** */ -static int test_translate( +static int SQLITE_TCLAPI test_translate( void * clientData, Tcl_Interp *interp, int objc, @@ -186,7 +186,7 @@ static int test_translate( ** translation. If there is a problem an assert() will fail. **/ void sqlite3UtfSelfTest(void); -static int test_translate_selftest( +static int SQLITE_TCLAPI test_translate_selftest( void * clientData, Tcl_Interp *interp, int objc, diff --git a/src/test6.c b/src/test6.c index e6eabf996a..5304bcc31f 100644 --- a/src/test6.c +++ b/src/test6.c @@ -811,7 +811,7 @@ static int processDevSymArgs( ** Simulate a crash immediately. This function does not return ** (writeListSync() calls exit(-1)). */ -static int crashNowCmd( +static int SQLITE_TCLAPI crashNowCmd( void * clientData, Tcl_Interp *interp, int objc, @@ -832,7 +832,7 @@ static int crashNowCmd( ** Parameter ENABLE must be a boolean value. If true, then the "crash" ** vfs is added to the system. If false, it is removed. */ -static int crashEnableCmd( +static int SQLITE_TCLAPI crashEnableCmd( void * clientData, Tcl_Interp *interp, int objc, @@ -907,7 +907,7 @@ static int crashEnableCmd( ** sqlite_crashparams -sect 1024 -char {atomic sequential} ./test.db 1 ** */ -static int crashParamsObjCmd( +static int SQLITE_TCLAPI crashParamsObjCmd( void * clientData, Tcl_Interp *interp, int objc, @@ -954,7 +954,7 @@ error: return TCL_ERROR; } -static int devSymObjCmd( +static int SQLITE_TCLAPI devSymObjCmd( void * clientData, Tcl_Interp *interp, int objc, @@ -977,7 +977,7 @@ static int devSymObjCmd( /* ** tclcmd: unregister_devsim */ -static int dsUnregisterObjCmd( +static int SQLITE_TCLAPI dsUnregisterObjCmd( void * clientData, Tcl_Interp *interp, int objc, @@ -997,7 +997,7 @@ static int dsUnregisterObjCmd( /* ** tclcmd: register_jt_vfs ?-default? PARENT-VFS */ -static int jtObjCmd( +static int SQLITE_TCLAPI jtObjCmd( void * clientData, Tcl_Interp *interp, int objc, @@ -1035,7 +1035,7 @@ static int jtObjCmd( /* ** tclcmd: unregister_jt_vfs */ -static int jtUnregisterObjCmd( +static int SQLITE_TCLAPI jtUnregisterObjCmd( void * clientData, Tcl_Interp *interp, int objc, diff --git a/src/test7.c b/src/test7.c index d3b789e967..d57e4b826b 100644 --- a/src/test7.c +++ b/src/test7.c @@ -153,7 +153,7 @@ static int parse_client_id(Tcl_Interp *interp, const char *zArg){ ** NAME should be an upper case letter. Start the thread running with ** an open connection to the given database. */ -static int tcl_client_create( +static int SQLITE_TCLAPI tcl_client_create( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -206,7 +206,7 @@ static void client_wait(Thread *p){ ** ** Wait on thread ID to reach its idle state. */ -static int tcl_client_wait( +static int SQLITE_TCLAPI tcl_client_wait( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -250,7 +250,7 @@ static void stop_thread(Thread *p){ ** Cause a client thread to shut itself down. Wait for the shutdown to be ** completed. If ID is "*" then stop all client threads. */ -static int tcl_client_halt( +static int SQLITE_TCLAPI tcl_client_halt( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -298,7 +298,7 @@ static int tcl_client_halt( ** Wait on the most recent client_step to complete, then return the ** number of columns in the result set. */ -static int tcl_client_argc( +static int SQLITE_TCLAPI tcl_client_argc( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -330,7 +330,7 @@ static int tcl_client_argc( ** Wait on the most recent client_step to complete, then return the ** value of the N-th columns in the result set. */ -static int tcl_client_argv( +static int SQLITE_TCLAPI tcl_client_argv( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -366,7 +366,7 @@ static int tcl_client_argv( ** Wait on the most recent client_step to complete, then return the ** name of the N-th columns in the result set. */ -static int tcl_client_colname( +static int SQLITE_TCLAPI tcl_client_colname( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -404,7 +404,7 @@ extern const char *sqlite3ErrName(int); ** Wait on the most recent operation to complete, then return the ** result code from that operation. */ -static int tcl_client_result( +static int SQLITE_TCLAPI tcl_client_result( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -436,7 +436,7 @@ static int tcl_client_result( ** Wait on the most recent operation to complete, then return the ** error string. */ -static int tcl_client_error( +static int SQLITE_TCLAPI tcl_client_error( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -481,7 +481,7 @@ static void do_compile(Thread *p){ ** ** Compile a new virtual machine. */ -static int tcl_client_compile( +static int SQLITE_TCLAPI tcl_client_compile( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -534,7 +534,7 @@ static void do_step(Thread *p){ ** ** Advance the virtual machine by one step */ -static int tcl_client_step( +static int SQLITE_TCLAPI tcl_client_step( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -576,7 +576,7 @@ static void do_finalize(Thread *p){ ** ** Finalize the virtual machine. */ -static int tcl_client_finalize( +static int SQLITE_TCLAPI tcl_client_finalize( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -620,7 +620,7 @@ static void do_reset(Thread *p){ ** ** Finalize the virtual machine. */ -static int tcl_client_reset( +static int SQLITE_TCLAPI tcl_client_reset( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -651,7 +651,7 @@ static int tcl_client_reset( ** ** Interchange the sqlite* pointer between two threads. */ -static int tcl_client_swap( +static int SQLITE_TCLAPI tcl_client_swap( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ diff --git a/src/test8.c b/src/test8.c index e635d5ed2c..daab504e4e 100644 --- a/src/test8.c +++ b/src/test8.c @@ -1357,7 +1357,7 @@ static void moduleDestroy(void *p){ /* ** Register the echo virtual table module. */ -static int register_echo_module( +static int SQLITE_TCLAPI register_echo_module( ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ @@ -1397,7 +1397,7 @@ static int register_echo_module( ** ** sqlite3_declare_vtab DB SQL */ -static int declare_vtab( +static int SQLITE_TCLAPI declare_vtab( ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ diff --git a/src/test9.c b/src/test9.c index 3c3629c0a7..5b139e8a56 100644 --- a/src/test9.c +++ b/src/test9.c @@ -26,7 +26,7 @@ /* ** c_collation_test */ -static int c_collation_test( +static int SQLITE_TCLAPI c_collation_test( ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ @@ -67,7 +67,7 @@ error_out: /* ** c_realloc_test */ -static int c_realloc_test( +static int SQLITE_TCLAPI c_realloc_test( ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ @@ -108,7 +108,7 @@ error_out: /* ** c_misuse_test */ -static int c_misuse_test( +static int SQLITE_TCLAPI c_misuse_test( ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ diff --git a/src/test_async.c b/src/test_async.c index 8389e75dbd..c32c74c660 100644 --- a/src/test_async.c +++ b/src/test_async.c @@ -19,6 +19,9 @@ # include "sqlite_tcl.h" #else # include "tcl.h" +# ifndef SQLITE_TCLAPI +# define SQLITE_TCLAPI +# endif #endif #ifdef SQLITE_ENABLE_ASYNCIO @@ -40,7 +43,7 @@ TCL_DECLARE_MUTEX(testasync_g_writerMutex); /* ** sqlite3async_initialize PARENT-VFS ISDEFAULT */ -static int testAsyncInit( +static int SQLITE_TCLAPI testAsyncInit( void * clientData, Tcl_Interp *interp, int objc, @@ -73,7 +76,7 @@ static int testAsyncInit( /* ** sqlite3async_shutdown */ -static int testAsyncShutdown( +static int SQLITE_TCLAPI testAsyncShutdown( void * clientData, Tcl_Interp *interp, int objc, @@ -97,7 +100,7 @@ static Tcl_ThreadCreateType tclWriterThread(ClientData pIsStarted){ ** ** Start a new writer thread. */ -static int testAsyncStart( +static int SQLITE_TCLAPI testAsyncStart( void * clientData, Tcl_Interp *interp, int objc, @@ -129,7 +132,7 @@ static int testAsyncStart( ** If the current writer thread is set to run forever then this ** command would block forever. To prevent that, an error is returned. */ -static int testAsyncWait( +static int SQLITE_TCLAPI testAsyncWait( void * clientData, Tcl_Interp *interp, int objc, @@ -155,7 +158,7 @@ static int testAsyncWait( /* ** sqlite3async_control OPTION ?VALUE? */ -static int testAsyncControl( +static int SQLITE_TCLAPI testAsyncControl( void * clientData, Tcl_Interp *interp, int objc, diff --git a/src/test_autoext.c b/src/test_autoext.c index b536cd7321..94a3223e65 100644 --- a/src/test_autoext.c +++ b/src/test_autoext.c @@ -15,6 +15,9 @@ # include "sqlite_tcl.h" #else # include "tcl.h" +# ifndef SQLITE_TCLAPI +# define SQLITE_TCLAPI +# endif #endif #include "sqlite3ext.h" @@ -91,7 +94,7 @@ static int broken_init( ** ** Register the "sqr" extension to be loaded automatically. */ -static int autoExtSqrObjCmd( +static int SQLITE_TCLAPI autoExtSqrObjCmd( void * clientData, Tcl_Interp *interp, int objc, @@ -107,7 +110,7 @@ static int autoExtSqrObjCmd( ** ** Unregister the "sqr" extension. */ -static int cancelAutoExtSqrObjCmd( +static int SQLITE_TCLAPI cancelAutoExtSqrObjCmd( void * clientData, Tcl_Interp *interp, int objc, @@ -123,7 +126,7 @@ static int cancelAutoExtSqrObjCmd( ** ** Register the "cube" extension to be loaded automatically. */ -static int autoExtCubeObjCmd( +static int SQLITE_TCLAPI autoExtCubeObjCmd( void * clientData, Tcl_Interp *interp, int objc, @@ -139,7 +142,7 @@ static int autoExtCubeObjCmd( ** ** Unregister the "cube" extension. */ -static int cancelAutoExtCubeObjCmd( +static int SQLITE_TCLAPI cancelAutoExtCubeObjCmd( void * clientData, Tcl_Interp *interp, int objc, @@ -155,7 +158,7 @@ static int cancelAutoExtCubeObjCmd( ** ** Register the broken extension to be loaded automatically. */ -static int autoExtBrokenObjCmd( +static int SQLITE_TCLAPI autoExtBrokenObjCmd( void * clientData, Tcl_Interp *interp, int objc, @@ -171,7 +174,7 @@ static int autoExtBrokenObjCmd( ** ** Unregister the broken extension. */ -static int cancelAutoExtBrokenObjCmd( +static int SQLITE_TCLAPI cancelAutoExtBrokenObjCmd( void * clientData, Tcl_Interp *interp, int objc, @@ -190,7 +193,7 @@ static int cancelAutoExtBrokenObjCmd( ** ** Reset all auto-extensions */ -static int resetAutoExtObjCmd( +static int SQLITE_TCLAPI resetAutoExtObjCmd( void * clientData, Tcl_Interp *interp, int objc, diff --git a/src/test_backup.c b/src/test_backup.c index 3e91f1f219..9b684a28f6 100644 --- a/src/test_backup.c +++ b/src/test_backup.c @@ -17,6 +17,9 @@ # include "sqlite_tcl.h" #else # include "tcl.h" +# ifndef SQLITE_TCLAPI +# define SQLITE_TCLAPI +# endif #endif #include "sqlite3.h" #include @@ -27,7 +30,7 @@ extern const char *sqlite3ErrName(int); /* These functions are implemented in test1.c. */ extern int getDbPointer(Tcl_Interp *, const char *, sqlite3 **); -static int backupTestCmd( +static int SQLITE_TCLAPI backupTestCmd( ClientData clientData, Tcl_Interp *interp, int objc, @@ -102,7 +105,7 @@ static int backupTestCmd( return TCL_OK; } -static void backupTestFinish(ClientData clientData){ +static void SQLITE_TCLAPI backupTestFinish(ClientData clientData){ sqlite3_backup *pBackup = (sqlite3_backup *)clientData; sqlite3_backup_finish(pBackup); } @@ -111,7 +114,7 @@ static void backupTestFinish(ClientData clientData){ ** sqlite3_backup CMDNAME DESTHANDLE DESTNAME SRCHANDLE SRCNAME ** */ -static int backupTestInit( +static int SQLITE_TCLAPI backupTestInit( ClientData clientData, Tcl_Interp *interp, int objc, diff --git a/src/test_bestindex.c b/src/test_bestindex.c index 8e0ff00b52..94017f0349 100644 --- a/src/test_bestindex.c +++ b/src/test_bestindex.c @@ -567,7 +567,7 @@ extern int getDbPointer(Tcl_Interp *interp, const char *zA, sqlite3 **ppDb); /* ** Register the echo virtual table module. */ -static int register_tcl_module( +static int SQLITE_TCLAPI register_tcl_module( ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ diff --git a/src/test_blob.c b/src/test_blob.c index 703664190b..3ac6c11421 100644 --- a/src/test_blob.c +++ b/src/test_blob.c @@ -99,7 +99,7 @@ static char *blobStringFromObj(Tcl_Obj *pObj){ ** ** Tcl test harness for the sqlite3_blob_open() function. */ -static int test_blob_open( +static int SQLITE_TCLAPI test_blob_open( ClientData clientData, /* Not used */ Tcl_Interp *interp, /* Calling TCL interpreter */ int objc, /* Number of arguments */ @@ -150,7 +150,7 @@ static int test_blob_open( /* ** sqlite3_blob_close HANDLE */ -static int test_blob_close( +static int SQLITE_TCLAPI test_blob_close( ClientData clientData, /* Not used */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ @@ -178,7 +178,7 @@ static int test_blob_close( /* ** sqlite3_blob_bytes HANDLE */ -static int test_blob_bytes( +static int SQLITE_TCLAPI test_blob_bytes( ClientData clientData, /* Not used */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ @@ -214,7 +214,7 @@ static int test_blob_bytes( ** text representation of the returned error code (i.e. "SQLITE_NOMEM") ** and a Tcl exception is thrown. */ -static int test_blob_read( +static int SQLITE_TCLAPI test_blob_read( ClientData clientData, /* Not used */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ @@ -266,7 +266,7 @@ static int test_blob_read( ** result is set to the text representation of the returned error code ** (i.e. "SQLITE_NOMEM") and a Tcl exception is thrown. */ -static int test_blob_write( +static int SQLITE_TCLAPI test_blob_write( ClientData clientData, /* Not used */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ diff --git a/src/test_btree.c b/src/test_btree.c index 46860afb30..03b8b207c9 100644 --- a/src/test_btree.c +++ b/src/test_btree.c @@ -26,7 +26,7 @@ ** Return a list of file that are shared and the number of ** references to each file. */ -int sqlite3BtreeSharedCacheReport( +int SQLITE_TCLAPI sqlite3BtreeSharedCacheReport( void * clientData, Tcl_Interp *interp, int objc, diff --git a/src/test_demovfs.c b/src/test_demovfs.c index 9cc0eb0309..ba7af863cd 100644 --- a/src/test_demovfs.c +++ b/src/test_demovfs.c @@ -645,10 +645,13 @@ sqlite3_vfs *sqlite3_demovfs(void){ # include "sqlite_tcl.h" #else # include "tcl.h" +# ifndef SQLITE_TCLAPI +# define SQLITE_TCLAPI +# endif #endif #if SQLITE_OS_UNIX -static int register_demovfs( +static int SQLITE_TCLAPI register_demovfs( ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ @@ -657,7 +660,7 @@ static int register_demovfs( sqlite3_vfs_register(sqlite3_demovfs(), 1); return TCL_OK; } -static int unregister_demovfs( +static int SQLITE_TCLAPI unregister_demovfs( ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ diff --git a/src/test_fs.c b/src/test_fs.c index 329594a5ab..87088bdae7 100644 --- a/src/test_fs.c +++ b/src/test_fs.c @@ -875,7 +875,7 @@ extern int getDbPointer(Tcl_Interp *interp, const char *zA, sqlite3 **ppDb); /* ** Register the echo virtual table module. */ -static int register_fs_module( +static int SQLITE_TCLAPI register_fs_module( ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ diff --git a/src/test_func.c b/src/test_func.c index 08ea98fb7a..6a714ef3eb 100644 --- a/src/test_func.c +++ b/src/test_func.c @@ -693,7 +693,7 @@ static int registerTestFunctions(sqlite3 *db){ ** the standard set of test functions to be loaded into each new ** database connection. */ -static int autoinstall_test_funcs( +static int SQLITE_TCLAPI autoinstall_test_funcs( void * clientData, Tcl_Interp *interp, int objc, @@ -721,7 +721,7 @@ static void tFinal(sqlite3_context *a){} ** Make various calls to sqlite3_create_function that do not have valid ** parameters. Verify that the error condition is detected and reported. */ -static int abuse_create_function( +static int SQLITE_TCLAPI abuse_create_function( void * clientData, Tcl_Interp *interp, int objc, diff --git a/src/test_hexio.c b/src/test_hexio.c index 88f5ed7bfa..7b62ea08bc 100644 --- a/src/test_hexio.c +++ b/src/test_hexio.c @@ -98,7 +98,7 @@ int sqlite3TestHexToBin(const unsigned char *zIn, int N, unsigned char *aOut){ ** beginning of the file. Convert that information to hexadecimal ** and return the resulting HEX string. */ -static int hexio_read( +static int SQLITE_TCLAPI hexio_read( void * clientData, Tcl_Interp *interp, int objc, @@ -148,7 +148,7 @@ static int hexio_read( ** Write DATA into file FILENAME beginning at OFFSET from the ** beginning of the file. DATA is expressed in hexadecimal. */ -static int hexio_write( +static int SQLITE_TCLAPI hexio_write( void * clientData, Tcl_Interp *interp, int objc, @@ -196,7 +196,7 @@ static int hexio_write( ** the value of that integer. HEXDATA can contain between 2 and 8 ** hexadecimal digits. */ -static int hexio_get_int( +static int SQLITE_TCLAPI hexio_get_int( void * clientData, Tcl_Interp *interp, int objc, @@ -236,7 +236,7 @@ static int hexio_get_int( ** ** Render INTEGER has a 16-bit big-endian integer in hexadecimal. */ -static int hexio_render_int16( +static int SQLITE_TCLAPI hexio_render_int16( void * clientData, Tcl_Interp *interp, int objc, @@ -263,7 +263,7 @@ static int hexio_render_int16( ** ** Render INTEGER has a 32-bit big-endian integer in hexadecimal. */ -static int hexio_render_int32( +static int SQLITE_TCLAPI hexio_render_int32( void * clientData, Tcl_Interp *interp, int objc, @@ -293,7 +293,7 @@ static int hexio_render_int32( ** The UTF8 might not be well-formed. Run this string through ** sqlite3Utf8to8() convert it back to hex and return the result. */ -static int utf8_to_utf8( +static int SQLITE_TCLAPI utf8_to_utf8( void * clientData, Tcl_Interp *interp, int objc, @@ -344,7 +344,7 @@ static int getFts3Varint(const char *p, sqlite_int64 *v){ ** Read a varint from the start of BLOB. Set variable VARNAME to contain ** the interpreted value. Return the number of bytes of BLOB consumed. */ -static int read_fts3varint( +static int SQLITE_TCLAPI read_fts3varint( void * clientData, Tcl_Interp *interp, int objc, diff --git a/src/test_init.c b/src/test_init.c index c66b5785d0..58465785d8 100644 --- a/src/test_init.c +++ b/src/test_init.c @@ -188,7 +188,7 @@ static void installInitWrappers(void){ sqlite3_config(SQLITE_CONFIG_PCACHE2, &pcachemethods); } -static int init_wrapper_install( +static int SQLITE_TCLAPI init_wrapper_install( ClientData clientData, /* Unused */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ @@ -212,7 +212,7 @@ static int init_wrapper_install( return TCL_OK; } -static int init_wrapper_uninstall( +static int SQLITE_TCLAPI init_wrapper_uninstall( ClientData clientData, /* Unused */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ @@ -230,7 +230,7 @@ static int init_wrapper_uninstall( return TCL_OK; } -static int init_wrapper_clear( +static int SQLITE_TCLAPI init_wrapper_clear( ClientData clientData, /* Unused */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ @@ -247,7 +247,7 @@ static int init_wrapper_clear( return TCL_OK; } -static int init_wrapper_query( +static int SQLITE_TCLAPI init_wrapper_query( ClientData clientData, /* Unused */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ diff --git a/src/test_intarray.c b/src/test_intarray.c index c27b4597c0..ddfb13fe20 100644 --- a/src/test_intarray.c +++ b/src/test_intarray.c @@ -274,6 +274,9 @@ SQLITE_API int sqlite3_intarray_bind( # include "sqlite_tcl.h" #else # include "tcl.h" +# ifndef SQLITE_TCLAPI +# define SQLITE_TCLAPI +# endif #endif /* @@ -290,7 +293,7 @@ extern const char *sqlite3ErrName(int); ** Invoke the sqlite3_intarray_create interface. A string that becomes ** the first parameter to sqlite3_intarray_bind. */ -static int test_intarray_create( +static int SQLITE_TCLAPI test_intarray_create( ClientData clientData, /* Not used */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ @@ -326,7 +329,7 @@ static int test_intarray_create( ** ** Invoke the sqlite3_intarray_bind interface on the given array of integers. */ -static int test_intarray_bind( +static int SQLITE_TCLAPI test_intarray_bind( ClientData clientData, /* Not used */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ diff --git a/src/test_malloc.c b/src/test_malloc.c index 66d8a881ba..e8c248f958 100644 --- a/src/test_malloc.c +++ b/src/test_malloc.c @@ -310,7 +310,7 @@ static int textToPointer(const char *z, void **pp){ ** ** Raw test interface for sqlite3_malloc(). */ -static int test_malloc( +static int SQLITE_TCLAPI test_malloc( void * clientData, Tcl_Interp *interp, int objc, @@ -335,7 +335,7 @@ static int test_malloc( ** ** Raw test interface for sqlite3_realloc(). */ -static int test_realloc( +static int SQLITE_TCLAPI test_realloc( void * clientData, Tcl_Interp *interp, int objc, @@ -364,7 +364,7 @@ static int test_realloc( ** ** Raw test interface for sqlite3_free(). */ -static int test_free( +static int SQLITE_TCLAPI test_free( void * clientData, Tcl_Interp *interp, int objc, @@ -395,7 +395,7 @@ int sqlite3TestBinToHex(char*,int); ** Set a chunk of memory (obtained from malloc, probably) to a ** specified hex pattern. */ -static int test_memset( +static int SQLITE_TCLAPI test_memset( void * clientData, Tcl_Interp *interp, int objc, @@ -441,7 +441,7 @@ static int test_memset( ** ** Return memory as hexadecimal text. */ -static int test_memget( +static int SQLITE_TCLAPI test_memget( void * clientData, Tcl_Interp *interp, int objc, @@ -488,7 +488,7 @@ static int test_memget( ** ** Raw test interface for sqlite3_memory_used(). */ -static int test_memory_used( +static int SQLITE_TCLAPI test_memory_used( void * clientData, Tcl_Interp *interp, int objc, @@ -503,7 +503,7 @@ static int test_memory_used( ** ** Raw test interface for sqlite3_memory_highwater(). */ -static int test_memory_highwater( +static int SQLITE_TCLAPI test_memory_highwater( void * clientData, Tcl_Interp *interp, int objc, @@ -528,7 +528,7 @@ static int test_memory_highwater( ** Set the depth of backtracing. If SQLITE_MEMDEBUG is not defined ** then this routine is a no-op. */ -static int test_memdebug_backtrace( +static int SQLITE_TCLAPI test_memdebug_backtrace( void * clientData, Tcl_Interp *interp, int objc, @@ -554,7 +554,7 @@ static int test_memdebug_backtrace( ** ** Write a summary of unfreed memory to FILENAME. */ -static int test_memdebug_dump( +static int SQLITE_TCLAPI test_memdebug_dump( void * clientData, Tcl_Interp *interp, int objc, @@ -579,7 +579,7 @@ static int test_memdebug_dump( ** ** Return the total number of times malloc() has been called. */ -static int test_memdebug_malloc_count( +static int SQLITE_TCLAPI test_memdebug_malloc_count( void * clientData, Tcl_Interp *interp, int objc, @@ -619,7 +619,7 @@ static int test_memdebug_malloc_count( ** ** To disable simulated failures, use a COUNTER of -1. */ -static int test_memdebug_fail( +static int SQLITE_TCLAPI test_memdebug_fail( void * clientData, Tcl_Interp *interp, int objc, @@ -685,7 +685,7 @@ static int test_memdebug_fail( ** simulated failure occurs. A negative return value indicates that ** no malloc() failure is scheduled. */ -static int test_memdebug_pending( +static int SQLITE_TCLAPI test_memdebug_pending( void * clientData, Tcl_Interp *interp, int objc, @@ -718,7 +718,7 @@ static int sqlite3_memdebug_title_count = 0; ** ** Each title overwrite the previous. */ -static int test_memdebug_settitle( +static int SQLITE_TCLAPI test_memdebug_settitle( void * clientData, Tcl_Interp *interp, int objc, @@ -799,7 +799,7 @@ static void test_memdebug_log_clear(void){ Tcl_InitHashTable(&aMallocLog, MALLOC_LOG_KEYINTS); } -static int test_memdebug_log( +static int SQLITE_TCLAPI test_memdebug_log( void * clientData, Tcl_Interp *interp, int objc, @@ -897,7 +897,7 @@ static int test_memdebug_log( ** ** A negative SIZE causes the buffer pointer to be NULL. */ -static int test_config_scratch( +static int SQLITE_TCLAPI test_config_scratch( void * clientData, Tcl_Interp *interp, int objc, @@ -937,7 +937,7 @@ static int test_config_scratch( ** ** A negative SIZE causes the buffer pointer to be NULL. */ -static int test_config_pagecache( +static int SQLITE_TCLAPI test_config_pagecache( void * clientData, Tcl_Interp *interp, int objc, @@ -980,7 +980,7 @@ static int test_config_pagecache( ** is certainty. 0 is never. PRNG_SEED is the pseudo-random number generator ** seed. */ -static int test_alt_pcache( +static int SQLITE_TCLAPI test_alt_pcache( void * clientData, Tcl_Interp *interp, int objc, @@ -1021,7 +1021,7 @@ static int test_alt_pcache( ** ** Enable or disable memory status reporting using SQLITE_CONFIG_MEMSTATUS. */ -static int test_config_memstatus( +static int SQLITE_TCLAPI test_config_memstatus( void * clientData, Tcl_Interp *interp, int objc, @@ -1042,7 +1042,7 @@ static int test_config_memstatus( ** Usage: sqlite3_config_lookaside SIZE COUNT ** */ -static int test_config_lookaside( +static int SQLITE_TCLAPI test_config_lookaside( void * clientData, Tcl_Interp *interp, int objc, @@ -1076,7 +1076,7 @@ static int test_config_lookaside( ** is 10KB in size. A BUFID of 0 indicates that the buffer should be NULL ** which will cause sqlite3_db_config() to allocate space on its own. */ -static int test_db_config_lookaside( +static int SQLITE_TCLAPI test_db_config_lookaside( void * clientData, Tcl_Interp *interp, int objc, @@ -1111,7 +1111,7 @@ static int test_db_config_lookaside( /* ** Usage: sqlite3_config_heap NBYTE NMINALLOC */ -static int test_config_heap( +static int SQLITE_TCLAPI test_config_heap( void * clientData, Tcl_Interp *interp, int objc, @@ -1148,7 +1148,7 @@ static int test_config_heap( /* ** Usage: sqlite3_config_heap_size NBYTE */ -static int test_config_heap_size( +static int SQLITE_TCLAPI test_config_heap_size( void * clientData, Tcl_Interp *interp, int objc, @@ -1178,7 +1178,7 @@ static int test_config_heap_size( ** Invoke sqlite3_config() or sqlite3_db_config() with invalid ** opcodes and verify that they return errors. */ -static int test_config_error( +static int SQLITE_TCLAPI test_config_error( void * clientData, Tcl_Interp *interp, int objc, @@ -1216,7 +1216,7 @@ static int test_config_error( ** Enables or disables interpretation of URI parameters by default using ** SQLITE_CONFIG_URI. */ -static int test_config_uri( +static int SQLITE_TCLAPI test_config_uri( void * clientData, Tcl_Interp *interp, int objc, @@ -1245,7 +1245,7 @@ static int test_config_uri( ** Enables or disables the use of the covering-index scan optimization. ** SQLITE_CONFIG_COVERING_INDEX_SCAN. */ -static int test_config_cis( +static int SQLITE_TCLAPI test_config_cis( void * clientData, Tcl_Interp *interp, int objc, @@ -1273,7 +1273,7 @@ static int test_config_cis( ** ** Set the minimum PMA size. */ -static int test_config_pmasz( +static int SQLITE_TCLAPI test_config_pmasz( void * clientData, Tcl_Interp *interp, int objc, @@ -1303,7 +1303,7 @@ static int test_config_pmasz( ** ** Write a summary of unfreed memsys3 allocations to FILENAME. */ -static int test_dump_memsys3( +static int SQLITE_TCLAPI test_dump_memsys3( void * clientData, Tcl_Interp *interp, int objc, @@ -1339,7 +1339,7 @@ static int test_dump_memsys3( ** Return a list of three elements which are the sqlite3_status() return ** code, the current value, and the high-water mark value. */ -static int test_status( +static int SQLITE_TCLAPI test_status( void * clientData, Tcl_Interp *interp, int objc, @@ -1396,7 +1396,7 @@ static int test_status( ** Return a list of three elements which are the sqlite3_db_status() return ** code, the current value, and the high-water mark value. */ -static int test_db_status( +static int SQLITE_TCLAPI test_db_status( void * clientData, Tcl_Interp *interp, int objc, @@ -1457,7 +1457,7 @@ static int test_db_status( /* ** install_malloc_faultsim BOOLEAN */ -static int test_install_malloc_faultsim( +static int SQLITE_TCLAPI test_install_malloc_faultsim( void * clientData, Tcl_Interp *interp, int objc, @@ -1481,7 +1481,7 @@ static int test_install_malloc_faultsim( /* ** sqlite3_install_memsys3 */ -static int test_install_memsys3( +static int SQLITE_TCLAPI test_install_memsys3( void * clientData, Tcl_Interp *interp, int objc, @@ -1496,7 +1496,7 @@ static int test_install_memsys3( return TCL_OK; } -static int test_vfs_oom_test( +static int SQLITE_TCLAPI test_vfs_oom_test( void * clientData, Tcl_Interp *interp, int objc, diff --git a/src/test_multiplex.c b/src/test_multiplex.c index dffdb44941..e7ffa63a56 100644 --- a/src/test_multiplex.c +++ b/src/test_multiplex.c @@ -1233,6 +1233,9 @@ int sqlite3_multiplex_shutdown(int eForce){ # include "sqlite_tcl.h" #else # include "tcl.h" +# ifndef SQLITE_TCLAPI +# define SQLITE_TCLAPI +# endif #endif extern const char *sqlite3ErrName(int); @@ -1240,7 +1243,7 @@ extern const char *sqlite3ErrName(int); /* ** tclcmd: sqlite3_multiplex_initialize NAME MAKEDEFAULT */ -static int test_multiplex_initialize( +static int SQLITE_TCLAPI test_multiplex_initialize( void * clientData, Tcl_Interp *interp, int objc, @@ -1271,7 +1274,7 @@ static int test_multiplex_initialize( /* ** tclcmd: sqlite3_multiplex_shutdown */ -static int test_multiplex_shutdown( +static int SQLITE_TCLAPI test_multiplex_shutdown( void * clientData, Tcl_Interp *interp, int objc, @@ -1299,7 +1302,7 @@ static int test_multiplex_shutdown( /* ** tclcmd: sqlite3_multiplex_dump */ -static int test_multiplex_dump( +static int SQLITE_TCLAPI test_multiplex_dump( void * clientData, Tcl_Interp *interp, int objc, @@ -1354,7 +1357,7 @@ static int test_multiplex_dump( /* ** Tclcmd: test_multiplex_control HANDLE DBNAME SUB-COMMAND ?INT-VALUE? */ -static int test_multiplex_control( +static int SQLITE_TCLAPI test_multiplex_control( ClientData cd, Tcl_Interp *interp, int objc, diff --git a/src/test_mutex.c b/src/test_mutex.c index 22375197b7..8f43e5ad30 100644 --- a/src/test_mutex.c +++ b/src/test_mutex.c @@ -156,7 +156,7 @@ static void counterMutexLeave(sqlite3_mutex *p){ /* ** sqlite3_shutdown */ -static int test_shutdown( +static int SQLITE_TCLAPI test_shutdown( void * clientData, Tcl_Interp *interp, int objc, @@ -177,7 +177,7 @@ static int test_shutdown( /* ** sqlite3_initialize */ -static int test_initialize( +static int SQLITE_TCLAPI test_initialize( void * clientData, Tcl_Interp *interp, int objc, @@ -198,7 +198,7 @@ static int test_initialize( /* ** install_mutex_counters BOOLEAN */ -static int test_install_mutex_counters( +static int SQLITE_TCLAPI test_install_mutex_counters( void * clientData, Tcl_Interp *interp, int objc, @@ -259,7 +259,7 @@ static int test_install_mutex_counters( /* ** read_mutex_counters */ -static int test_read_mutex_counters( +static int SQLITE_TCLAPI test_read_mutex_counters( void * clientData, Tcl_Interp *interp, int objc, @@ -288,7 +288,7 @@ static int test_read_mutex_counters( /* ** clear_mutex_counters */ -static int test_clear_mutex_counters( +static int SQLITE_TCLAPI test_clear_mutex_counters( void * clientData, Tcl_Interp *interp, int objc, @@ -312,7 +312,7 @@ static int test_clear_mutex_counters( ** will be invalid since the mutex has already been freed. The ** return pointer just checks to see if the mutex really was allocated. */ -static int test_alloc_mutex( +static int SQLITE_TCLAPI test_alloc_mutex( void * clientData, Tcl_Interp *interp, int objc, @@ -339,7 +339,7 @@ static int test_alloc_mutex( ** ** Or OPTION can be an raw integer. */ -static int test_config( +static int SQLITE_TCLAPI test_config( void * clientData, Tcl_Interp *interp, int objc, @@ -401,7 +401,7 @@ static sqlite3_mutex *getStaticMutexPointer( return counterMutexAlloc(iMutex); } -static int test_enter_static_mutex( +static int SQLITE_TCLAPI test_enter_static_mutex( void * clientData, Tcl_Interp *interp, int objc, @@ -420,7 +420,7 @@ static int test_enter_static_mutex( return TCL_OK; } -static int test_leave_static_mutex( +static int SQLITE_TCLAPI test_leave_static_mutex( void * clientData, Tcl_Interp *interp, int objc, @@ -439,7 +439,7 @@ static int test_leave_static_mutex( return TCL_OK; } -static int test_enter_db_mutex( +static int SQLITE_TCLAPI test_enter_db_mutex( void * clientData, Tcl_Interp *interp, int objc, @@ -458,7 +458,7 @@ static int test_enter_db_mutex( return TCL_OK; } -static int test_leave_db_mutex( +static int SQLITE_TCLAPI test_leave_db_mutex( void * clientData, Tcl_Interp *interp, int objc, diff --git a/src/test_osinst.c b/src/test_osinst.c index 5ab8ed5c93..a008baba45 100644 --- a/src/test_osinst.c +++ b/src/test_osinst.c @@ -1108,9 +1108,12 @@ int sqlite3_vfslog_register(sqlite3 *db){ # include "sqlite_tcl.h" #else # include "tcl.h" +# ifndef SQLITE_TCLAPI +# define SQLITE_TCLAPI +# endif #endif -static int test_vfslog( +static int SQLITE_TCLAPI test_vfslog( void *clientData, Tcl_Interp *interp, int objc, diff --git a/src/test_quota.c b/src/test_quota.c index 8ea48e5b53..e87e9772f6 100644 --- a/src/test_quota.c +++ b/src/test_quota.c @@ -111,7 +111,7 @@ struct quotaFile { /* ** An instance of the following object represents each open connection -** to a file that participates in quota tracking. This object is a +** to a file that participates in quota tracking. This object is a ** subclass of sqlite3_file. The sqlite3_file object for the underlying ** VFS is appended to this structure. */ @@ -154,11 +154,11 @@ static struct { */ sqlite3_vfs sThisVfs; - /* The sIoMethods defines the methods used by sqlite3_file objects + /* The sIoMethods defines the methods used by sqlite3_file objects ** associated with this shim. It is initialized at start-time and does ** not require a mutex. ** - ** When the underlying VFS is called to open a file, it might return + ** When the underlying VFS is called to open a file, it might return ** either a version 1 or a version 2 sqlite3_file object. This shim ** has to create a wrapper sqlite3_file of the same version. Hence ** there are two I/O method structures, one for version 1 and the other @@ -190,7 +190,7 @@ static struct { static void quotaEnter(void){ sqlite3_mutex_enter(gQuota.pMutex); } static void quotaLeave(void){ sqlite3_mutex_leave(gQuota.pMutex); } -/* Count the number of open files in a quotaGroup +/* Count the number of open files in a quotaGroup */ static int quotaGroupOpenFileCount(quotaGroup *pGroup){ int N = 0; @@ -399,7 +399,7 @@ static char *quota_utf8_to_mbcs(const char *zUtf8){ return zMbcs; #else return (char*)zUtf8; /* No-op on unix */ -#endif +#endif } /* @@ -410,7 +410,7 @@ static void quota_mbcs_free(char *zOld){ sqlite3_free(zOld); #else /* No-op on unix */ -#endif +#endif } /************************* VFS Method Wrappers *****************************/ @@ -428,7 +428,7 @@ static int quotaOpen( int flags, /* Flags to control the opening */ int *pOutFlags /* Flags showing results of opening */ ){ - int rc; /* Result code */ + int rc; /* Result code */ quotaConn *pQuotaOpen; /* The new quota file descriptor */ quotaFile *pFile; /* Corresponding quotaFile obj */ quotaGroup *pGroup; /* The group file belongs to */ @@ -488,7 +488,7 @@ static int quotaDelete( const char *zName, /* Name of file to be deleted */ int syncDir /* Do a directory sync after deleting */ ){ - int rc; /* Result code */ + int rc; /* Result code */ quotaFile *pFile; /* Files in the quota */ quotaGroup *pGroup; /* The group file belongs to */ sqlite3_vfs *pOrigVfs = gQuota.pOrigVfs; /* Real VFS */ @@ -581,7 +581,7 @@ static int quotaWrite( szNew = pGroup->iSize - pFile->iSize + iEnd; if( szNew>pGroup->iLimit && pGroup->iLimit>0 ){ if( pGroup->xCallback ){ - pGroup->xCallback(pFile->zFilename, &pGroup->iLimit, szNew, + pGroup->xCallback(pFile->zFilename, &pGroup->iLimit, szNew, pGroup->pArg); } if( szNew>pGroup->iLimit && pGroup->iLimit>0 ){ @@ -738,7 +738,7 @@ static int quotaShmUnmap(sqlite3_file *pConn, int deleteFlag){ /* ** Initialize the quota VFS shim. Use the VFS named zOrigVfsName ** as the VFS that does the actual work. Use the default if -** zOrigVfsName==NULL. +** zOrigVfsName==NULL. ** ** The quota VFS shim is named "quota". It will become the default ** VFS if makeDefault is non-zero. @@ -908,7 +908,7 @@ int sqlite3_quota_file(const char *zFilename){ if( rc==SQLITE_OK ){ zFull[strlen(zFull)+1] = '\0'; - rc = quotaOpen(&gQuota.sThisVfs, zFull, fd, + rc = quotaOpen(&gQuota.sThisVfs, zFull, fd, SQLITE_OPEN_READONLY | SQLITE_OPEN_MAIN_DB, &outFlags); if( rc==SQLITE_OK ){ fd->pMethods->xFileSize(fd, &iSize); @@ -1016,7 +1016,7 @@ size_t sqlite3_quota_fwrite( szNew = pGroup->iSize - pFile->iSize + iEnd; if( szNew>pGroup->iLimit && pGroup->iLimit>0 ){ if( pGroup->xCallback ){ - pGroup->xCallback(pFile->zFilename, &pGroup->iLimit, szNew, + pGroup->xCallback(pFile->zFilename, &pGroup->iLimit, szNew, pGroup->pArg); } if( szNew>pGroup->iLimit && pGroup->iLimit>0 ){ @@ -1203,7 +1203,7 @@ sqlite3_int64 sqlite3_quota_file_truesize(quota_FILE *p){ sqlite3_int64 sqlite3_quota_file_size(quota_FILE *p){ return p->pFile ? p->pFile->iSize : -1; } - + /* ** Determine the amount of data in bytes available for reading ** in the given file. @@ -1275,13 +1275,16 @@ int sqlite3_quota_remove(const char *zFilename){ sqlite3_free(zFull); return rc; } - + /***************************** Test Code ***********************************/ #ifdef SQLITE_TEST #if defined(INCLUDE_SQLITE_TCL_H) # include "sqlite_tcl.h" #else # include "tcl.h" +# ifndef SQLITE_TCLAPI +# define SQLITE_TCLAPI +# endif #endif /* @@ -1354,7 +1357,7 @@ static void tclCallbackDestructor(void *pObj){ /* ** tclcmd: sqlite3_quota_initialize NAME MAKEDEFAULT */ -static int test_quota_initialize( +static int SQLITE_TCLAPI test_quota_initialize( void * clientData, Tcl_Interp *interp, int objc, @@ -1383,7 +1386,7 @@ static int test_quota_initialize( /* ** tclcmd: sqlite3_quota_shutdown */ -static int test_quota_shutdown( +static int SQLITE_TCLAPI test_quota_shutdown( void * clientData, Tcl_Interp *interp, int objc, @@ -1406,7 +1409,7 @@ static int test_quota_shutdown( /* ** tclcmd: sqlite3_quota_set PATTERN LIMIT SCRIPT */ -static int test_quota_set( +static int SQLITE_TCLAPI test_quota_set( void * clientData, Tcl_Interp *interp, int objc, @@ -1460,7 +1463,7 @@ static int test_quota_set( /* ** tclcmd: sqlite3_quota_file FILENAME */ -static int test_quota_file( +static int SQLITE_TCLAPI test_quota_file( void * clientData, Tcl_Interp *interp, int objc, @@ -1486,7 +1489,7 @@ static int test_quota_file( /* ** tclcmd: sqlite3_quota_dump */ -static int test_quota_dump( +static int SQLITE_TCLAPI test_quota_dump( void * clientData, Tcl_Interp *interp, int objc, @@ -1534,7 +1537,7 @@ static int test_quota_dump( /* ** tclcmd: sqlite3_quota_fopen FILENAME MODE */ -static int test_quota_fopen( +static int SQLITE_TCLAPI test_quota_fopen( void * clientData, Tcl_Interp *interp, int objc, @@ -1564,7 +1567,7 @@ extern void *sqlite3TestTextToPtr(const char*); /* ** tclcmd: sqlite3_quota_fread HANDLE SIZE NELEM */ -static int test_quota_fread( +static int SQLITE_TCLAPI test_quota_fread( void * clientData, Tcl_Interp *interp, int objc, @@ -1598,7 +1601,7 @@ static int test_quota_fread( /* ** tclcmd: sqlite3_quota_fwrite HANDLE SIZE NELEM CONTENT */ -static int test_quota_fwrite( +static int SQLITE_TCLAPI test_quota_fwrite( void * clientData, Tcl_Interp *interp, int objc, @@ -1626,7 +1629,7 @@ static int test_quota_fwrite( /* ** tclcmd: sqlite3_quota_fclose HANDLE */ -static int test_quota_fclose( +static int SQLITE_TCLAPI test_quota_fclose( void * clientData, Tcl_Interp *interp, int objc, @@ -1648,7 +1651,7 @@ static int test_quota_fclose( /* ** tclcmd: sqlite3_quota_fflush HANDLE ?HARDSYNC? */ -static int test_quota_fflush( +static int SQLITE_TCLAPI test_quota_fflush( void * clientData, Tcl_Interp *interp, int objc, @@ -1674,7 +1677,7 @@ static int test_quota_fflush( /* ** tclcmd: sqlite3_quota_fseek HANDLE OFFSET WHENCE */ -static int test_quota_fseek( +static int SQLITE_TCLAPI test_quota_fseek( void * clientData, Tcl_Interp *interp, int objc, @@ -1712,7 +1715,7 @@ static int test_quota_fseek( /* ** tclcmd: sqlite3_quota_rewind HANDLE */ -static int test_quota_rewind( +static int SQLITE_TCLAPI test_quota_rewind( void * clientData, Tcl_Interp *interp, int objc, @@ -1731,7 +1734,7 @@ static int test_quota_rewind( /* ** tclcmd: sqlite3_quota_ftell HANDLE */ -static int test_quota_ftell( +static int SQLITE_TCLAPI test_quota_ftell( void * clientData, Tcl_Interp *interp, int objc, @@ -1752,7 +1755,7 @@ static int test_quota_ftell( /* ** tclcmd: sqlite3_quota_ftruncate HANDLE SIZE */ -static int test_quota_ftruncate( +static int SQLITE_TCLAPI test_quota_ftruncate( void * clientData, Tcl_Interp *interp, int objc, @@ -1777,7 +1780,7 @@ static int test_quota_ftruncate( /* ** tclcmd: sqlite3_quota_file_size HANDLE */ -static int test_quota_file_size( +static int SQLITE_TCLAPI test_quota_file_size( void * clientData, Tcl_Interp *interp, int objc, @@ -1798,7 +1801,7 @@ static int test_quota_file_size( /* ** tclcmd: sqlite3_quota_file_truesize HANDLE */ -static int test_quota_file_truesize( +static int SQLITE_TCLAPI test_quota_file_truesize( void * clientData, Tcl_Interp *interp, int objc, @@ -1819,7 +1822,7 @@ static int test_quota_file_truesize( /* ** tclcmd: sqlite3_quota_file_mtime HANDLE */ -static int test_quota_file_mtime( +static int SQLITE_TCLAPI test_quota_file_mtime( void * clientData, Tcl_Interp *interp, int objc, @@ -1842,7 +1845,7 @@ static int test_quota_file_mtime( /* ** tclcmd: sqlite3_quota_remove FILENAME */ -static int test_quota_remove( +static int SQLITE_TCLAPI test_quota_remove( void * clientData, Tcl_Interp *interp, int objc, @@ -1866,7 +1869,7 @@ static int test_quota_remove( ** Test the glob pattern matching. Return 1 if TEXT matches PATTERN ** and return 0 if it does not. */ -static int test_quota_glob( +static int SQLITE_TCLAPI test_quota_glob( void * clientData, Tcl_Interp *interp, int objc, @@ -1892,7 +1895,7 @@ static int test_quota_glob( ** Return the number of bytes from the current file point to the end of ** the file. */ -static int test_quota_file_available( +static int SQLITE_TCLAPI test_quota_file_available( void * clientData, Tcl_Interp *interp, int objc, @@ -1915,7 +1918,7 @@ static int test_quota_file_available( ** ** Return true if the file handle is in the error state. */ -static int test_quota_ferror( +static int SQLITE_TCLAPI test_quota_ferror( void * clientData, Tcl_Interp *interp, int objc, diff --git a/src/test_rtree.c b/src/test_rtree.c index 1f15566f97..0c6dbf3cd7 100644 --- a/src/test_rtree.c +++ b/src/test_rtree.c @@ -440,7 +440,7 @@ static int cube_geom( } #endif /* SQLITE_ENABLE_RTREE */ -static int register_cube_geom( +static int SQLITE_TCLAPI register_cube_geom( void * clientData, Tcl_Interp *interp, int objc, @@ -468,7 +468,7 @@ static int register_cube_geom( return TCL_OK; } -static int register_circle_geom( +static int SQLITE_TCLAPI register_circle_geom( void * clientData, Tcl_Interp *interp, int objc, diff --git a/src/test_schema.c b/src/test_schema.c index f2bd3b3520..cdf085797f 100644 --- a/src/test_schema.c +++ b/src/test_schema.c @@ -306,7 +306,7 @@ extern int getDbPointer(Tcl_Interp *interp, const char *zA, sqlite3 **ppDb); /* ** Register the schema virtual table module. */ -static int register_schema_module( +static int SQLITE_TCLAPI register_schema_module( ClientData clientData, /* Not used */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ diff --git a/src/test_superlock.c b/src/test_superlock.c index cad5b51f0f..45d0d623a0 100644 --- a/src/test_superlock.c +++ b/src/test_superlock.c @@ -260,6 +260,9 @@ int sqlite3demo_superlock( # include "sqlite_tcl.h" #else # include "tcl.h" +# ifndef SQLITE_TCLAPI +# define SQLITE_TCLAPI +# endif #endif struct InterpAndScript { @@ -268,11 +271,11 @@ struct InterpAndScript { }; typedef struct InterpAndScript InterpAndScript; -static void superunlock_del(ClientData cd){ +static void SQLITE_TCLAPI superunlock_del(ClientData cd){ sqlite3demo_superunlock((void *)cd); } -static int superunlock_cmd( +static int SQLITE_TCLAPI superunlock_cmd( ClientData cd, Tcl_Interp *interp, int objc, @@ -304,7 +307,7 @@ static int superlock_busy(void *pCtx, int nBusy){ /* ** Tclcmd: sqlite3demo_superlock CMDNAME PATH VFS BUSY-HANDLER-SCRIPT */ -static int superlock_cmd( +static int SQLITE_TCLAPI superlock_cmd( ClientData cd, Tcl_Interp *interp, int objc, diff --git a/src/test_syscall.c b/src/test_syscall.c index eab9895186..947f9a9d9d 100644 --- a/src/test_syscall.c +++ b/src/test_syscall.c @@ -422,7 +422,7 @@ static void *ts_mremap(void *a, size_t b, size_t c, int d, ...){ return orig_mremap(a, b, c, d, pArg); } -static int test_syscall_install( +static int SQLITE_TCLAPI test_syscall_install( void * clientData, Tcl_Interp *interp, int objc, @@ -458,7 +458,7 @@ static int test_syscall_install( return TCL_OK; } -static int test_syscall_uninstall( +static int SQLITE_TCLAPI test_syscall_uninstall( void * clientData, Tcl_Interp *interp, int objc, @@ -482,7 +482,7 @@ static int test_syscall_uninstall( return TCL_OK; } -static int test_syscall_reset( +static int SQLITE_TCLAPI test_syscall_reset( void * clientData, Tcl_Interp *interp, int objc, @@ -520,7 +520,7 @@ static int test_syscall_reset( return TCL_OK; } -static int test_syscall_exists( +static int SQLITE_TCLAPI test_syscall_exists( void * clientData, Tcl_Interp *interp, int objc, @@ -541,7 +541,7 @@ static int test_syscall_exists( return TCL_OK; } -static int test_syscall_fault( +static int SQLITE_TCLAPI test_syscall_fault( void * clientData, Tcl_Interp *interp, int objc, @@ -570,7 +570,7 @@ static int test_syscall_fault( return TCL_OK; } -static int test_syscall_errno( +static int SQLITE_TCLAPI test_syscall_errno( void * clientData, Tcl_Interp *interp, int objc, @@ -616,7 +616,7 @@ static int test_syscall_errno( return TCL_OK; } -static int test_syscall_list( +static int SQLITE_TCLAPI test_syscall_list( void * clientData, Tcl_Interp *interp, int objc, @@ -646,7 +646,7 @@ static int test_syscall_list( return TCL_OK; } -static int test_syscall_defaultvfs( +static int SQLITE_TCLAPI test_syscall_defaultvfs( void * clientData, Tcl_Interp *interp, int objc, @@ -668,7 +668,7 @@ static int ts_getpagesize(void){ return gSyscall.pgsz; } -static int test_syscall_pagesize( +static int SQLITE_TCLAPI test_syscall_pagesize( void * clientData, Tcl_Interp *interp, int objc, @@ -703,7 +703,7 @@ static int test_syscall_pagesize( return TCL_OK; } -static int test_syscall( +static int SQLITE_TCLAPI test_syscall( void * clientData, Tcl_Interp *interp, int objc, diff --git a/src/test_tclvar.c b/src/test_tclvar.c index 95a065c853..8f7352112d 100644 --- a/src/test_tclvar.c +++ b/src/test_tclvar.c @@ -411,7 +411,7 @@ extern int getDbPointer(Tcl_Interp *interp, const char *zA, sqlite3 **ppDb); /* ** Register the echo virtual table module. */ -static int register_tclvar_module( +static int SQLITE_TCLAPI register_tclvar_module( ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ diff --git a/src/test_thread.c b/src/test_thread.c index 1fd646e769..d67b4be10b 100644 --- a/src/test_thread.c +++ b/src/test_thread.c @@ -76,7 +76,7 @@ extern int sqlite3TestErrCode(Tcl_Interp *, sqlite3 *, int); /* ** Handler for events of type EvalEvent. */ -static int tclScriptEvent(Tcl_Event *evPtr, int flags){ +static int SQLITE_TCLAPI tclScriptEvent(Tcl_Event *evPtr, int flags){ int rc; EvalEvent *p = (EvalEvent *)evPtr; rc = Tcl_Eval(p->interp, p->zScript); @@ -171,7 +171,7 @@ static Tcl_ThreadCreateType tclScriptThread(ClientData pSqlThread){ ** ** The caller can wait for the script to terminate using [vwait VARNAME]. */ -static int sqlthread_spawn( +static int SQLITE_TCLAPI sqlthread_spawn( ClientData clientData, Tcl_Interp *interp, int objc, @@ -224,7 +224,7 @@ static int sqlthread_spawn( ** ** NOTE: At the moment, this doesn't work. FIXME. */ -static int sqlthread_parent( +static int SQLITE_TCLAPI sqlthread_parent( ClientData clientData, Tcl_Interp *interp, int objc, @@ -269,7 +269,7 @@ static int xBusy(void *pArg, int nBusy){ ** Open a database handle and return the string representation of ** the pointer value. */ -static int sqlthread_open( +static int SQLITE_TCLAPI sqlthread_open( ClientData clientData, Tcl_Interp *interp, int objc, @@ -319,7 +319,7 @@ static int sqlthread_open( ** Return the current thread-id (Tcl_GetCurrentThread()) cast to ** an integer. */ -static int sqlthread_id( +static int SQLITE_TCLAPI sqlthread_id( ClientData clientData, Tcl_Interp *interp, int objc, @@ -337,7 +337,7 @@ static int sqlthread_id( /* ** Dispatch routine for the sub-commands of [sqlthread]. */ -static int sqlthread_proc( +static int SQLITE_TCLAPI sqlthread_proc( ClientData clientData, Tcl_Interp *interp, int objc, @@ -385,7 +385,7 @@ static int sqlthread_proc( ** implemented as a script in Tcl 8.5, it is not usually available to ** testfixture. */ -static int clock_seconds_proc( +static int SQLITE_TCLAPI clock_seconds_proc( ClientData clientData, Tcl_Interp *interp, int objc, @@ -547,7 +547,7 @@ int sqlite3_blocking_prepare_v2( ** ** Advance the statement to the next row. */ -static int blocking_step_proc( +static int SQLITE_TCLAPI blocking_step_proc( void * clientData, Tcl_Interp *interp, int objc, @@ -573,7 +573,7 @@ static int blocking_step_proc( ** Usage: sqlite3_blocking_prepare_v2 DB sql bytes ?tailvar? ** Usage: sqlite3_nonblocking_prepare_v2 DB sql bytes ?tailvar? */ -static int blocking_prepare_v2_proc( +static int SQLITE_TCLAPI blocking_prepare_v2_proc( void * clientData, Tcl_Interp *interp, int objc, diff --git a/src/test_vfs.c b/src/test_vfs.c index acc1c6682e..fb987a6163 100644 --- a/src/test_vfs.c +++ b/src/test_vfs.c @@ -1040,7 +1040,7 @@ static int tvfsUnfetch(sqlite3_file *pFile, sqlite3_int64 iOfst, void *p){ return sqlite3OsUnfetch(pFd->pReal, iOfst, p); } -static int testvfs_obj_cmd( +static int SQLITE_TCLAPI testvfs_obj_cmd( ClientData cd, Tcl_Interp *interp, int objc, @@ -1352,7 +1352,7 @@ static int testvfs_obj_cmd( return TCL_OK; } -static void testvfs_obj_del(ClientData cd){ +static void SQLITE_TCLAPI testvfs_obj_del(ClientData cd){ Testvfs *p = (Testvfs *)cd; if( p->pScript ) Tcl_DecrRefCount(p->pScript); sqlite3_vfs_unregister(p->pVfs); @@ -1395,7 +1395,7 @@ static void testvfs_obj_del(ClientData cd){ ** ** where LOCK is of the form "OFFSET NBYTE lock/unlock shared/exclusive" */ -static int testvfs_cmd( +static int SQLITE_TCLAPI testvfs_cmd( ClientData cd, Tcl_Interp *interp, int objc, From aa0325872fa725d1c2622d3bd4f8b87a7c137bc3 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 28 Jul 2016 17:24:16 +0000 Subject: [PATCH 0618/1484] Improvements to the way the COMPILER compile-time option is set when compiling with Clang. FossilOrigin-Name: 81f9cf86c48f3cd43755ded4dc97388ec650f8af --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/ctime.c | 6 ++++-- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index d4a4aa1bdd..c71c10048d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C New\stest\scase\sto\sinsure\slegacy\sCREATE\sTABLE\ssyntax\sis\ssupported. -D 2016-07-28T12:52:30.552 +C Improvements\sto\sthe\sway\sthe\sCOMPILER\scompile-time\soption\sis\sset\swhen\scompiling\nwith\sClang. +D 2016-07-28T17:24:16.495 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -333,7 +333,7 @@ F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 F src/build.c d1fdfd7ab8f5447e494ef15825973bf0719527c6 F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e -F src/ctime.c 61949e83c4c36e37195a8398ebc752780b534d95 +F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7 F src/date.c 1cc9fb516ec9932c6fd4d2a0d2f8bc4480145c39 F src/dbstat.c 4f6f7f52b49beb9636ffbd517cfe44a402ba4ad0 F src/delete.c 4aba4214a377ce8ddde2d2e609777bcc8235200f @@ -1508,7 +1508,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 9e2b26811452a5011d0a97a689636fa4409da856 -R d76a2fc86bbf1915af6bf1dd54a28237 +P 6feff15cae8f0427be790355841d49c479c1c586 +R 675b3da4289ec2d84ea94ee475054664 U drh -Z 803b725d666d5af434be7409c67eabe6 +Z 0881f39f36c917424fb94c651f3aec11 diff --git a/manifest.uuid b/manifest.uuid index f4495ea5c1..060502d932 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6feff15cae8f0427be790355841d49c479c1c586 \ No newline at end of file +81f9cf86c48f3cd43755ded4dc97388ec650f8af \ No newline at end of file diff --git a/src/ctime.c b/src/ctime.c index 1a7c69f3bf..09587ea88e 100644 --- a/src/ctime.c +++ b/src/ctime.c @@ -45,8 +45,10 @@ static const char * const azCompileOpt[] = { #if SQLITE_CHECK_PAGES "CHECK_PAGES", #endif -#if defined(__clang__) && defined(__clang_version__) - "COMPILER=clang-" __clang_version__, +#if defined(__clang__) && defined(__clang_major__) + "COMPILER=clang-" CTIMEOPT_VAL(__clang_major__) "." + CTIMEOPT_VAL(__clang_minor__) "." + CTIMEOPT_VAL(__clang_patchlevel__), #elif defined(_MSC_VER) "COMPILER=msvc-" CTIMEOPT_VAL(_MSC_VER), #elif defined(__GNUC__) && defined(__VERSION__) From a121cc7c60e13e5dae02176631a72e3333f70302 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Thu, 28 Jul 2016 18:06:52 +0000 Subject: [PATCH 0619/1484] Adjustments to get 'testfixture.exe' compiling with Tcl 8.6 when __stdcall is enabled. FossilOrigin-Name: 90e89ec9c8efff057a9e43c612427fc5c97ab52d --- Makefile.msc | 2 +- manifest | 14 +++++++------- manifest.uuid | 2 +- src/tclsqlite.c | 6 +++--- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Makefile.msc b/Makefile.msc index 4a8283731d..ca3e19aab8 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -1994,7 +1994,7 @@ sqlite_tclDecls.h: echo # define SQLITE_TCLAPI >> sqlite_tclDecls.h echo #endif >> sqlite_tclDecls.h type "$(TCLINCDIR)\tclDecls.h" \ - | $(TCLSH_CMD) $(TOP)\tool\replace.tcl regsub "^(EXTERN\s+?.*?\s+?)Tcl_" "\1 SQLITE_TCLAPI Tcl_" \ + | $(TCLSH_CMD) $(TOP)\tool\replace.tcl regsub "^(EXTERN(?: CONST\d+?)?\s+?[^\(]*?\s+?)Tcl_" "\1 SQLITE_TCLAPI Tcl_" \ | $(TCLSH_CMD) $(TOP)\tool\replace.tcl regsub "^(EXTERN\s+?(?:void|VOID)\s+?)TclFreeObj" "\1 SQLITE_TCLAPI TclFreeObj" \ | $(TCLSH_CMD) $(TOP)\tool\replace.tcl regsub "\(\*tcl_" "(SQLITE_TCLAPI *tcl_" \ | $(TCLSH_CMD) $(TOP)\tool\replace.tcl regsub "\(\*tclFreeObj" "(SQLITE_TCLAPI *tclFreeObj" >> sqlite_tclDecls.h diff --git a/manifest b/manifest index 1be1262c7e..4e202a429f 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -C Make\ssure\sthe\sSQLITE_TCLAPI\smacro\sis\salways\sdefined. -D 2016-07-28T17:11:20.162 +C Adjustments\sto\sget\s'testfixture.exe'\scompiling\swith\sTcl\s8.6\swhen\s__stdcall\sis\senabled. +D 2016-07-28T18:06:52.992 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 -F Makefile.msc 1e5399407885d69150e2659f4710b5712a1e6cef +F Makefile.msc c7934e2d3ef07c440ad48e2233c0cc8364e72aff F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7 F VERSION cb29eb11e493dd85b3eeec4053c03949bf98478e F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 @@ -392,7 +392,7 @@ F src/sqliteInt.h 14516943867eb2c30ce0e3670299958f59ade052 F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c 5b18f9526900f61189ab0b83f1ef41d9f871a2ab F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 -F src/tclsqlite.c a9c6e33c44efa93d176ce5e0887d5d533c98b429 +F src/tclsqlite.c 342379845d52c62a778c76c3dd0a2695af723e04 F src/test1.c 906a04b649c7139e943193a3905d583e325c30c7 F src/test2.c b7174313e993754303a8b33c43df7c44b46857ab F src/test3.c 1339a40be39650ae83894b6578f971dc7f96ea8a @@ -1508,7 +1508,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 36b72fd609cf151f3db0e65b450d7cd515f2ac49 -R cb104ece8c53bb381905efecad762caf +P f2f1323cc4d2ad2d6794dbfae8d50b747213e85d +R f48b462f2c7e74ed51a21c0e6f026658 U mistachkin -Z 5c80ddf3854cd75da2e73aafdf02283f +Z 339efe4a28b4c084d0a9150e8c742a8a diff --git a/manifest.uuid b/manifest.uuid index 1a85a325af..e9bf450c4c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f2f1323cc4d2ad2d6794dbfae8d50b747213e85d \ No newline at end of file +90e89ec9c8efff057a9e43c612427fc5c97ab52d \ No newline at end of file diff --git a/src/tclsqlite.c b/src/tclsqlite.c index 527dc488ee..bc94a5ff7f 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -1151,7 +1151,7 @@ static char *local_getline(char *zPrompt, FILE *in){ ** It is invoked after evaluating the script SCRIPT to commit or rollback ** the transaction or savepoint opened by the [transaction] command. */ -static int DbTransPostCmd( +static int SQLITE_TCLAPI DbTransPostCmd( ClientData data[], /* data[0] is the Sqlite3Db* for $db */ Tcl_Interp *interp, /* Tcl interpreter */ int result /* Result of evaluating SCRIPT */ @@ -1698,7 +1698,7 @@ static int DbUseNre(void){ ** ** $db eval SQL ?ARRAYNAME? SCRIPT */ -static int DbEvalNextCmd( +static int SQLITE_TCLAPI DbEvalNextCmd( ClientData data[], /* data[0] is the (DbEvalContext*) */ Tcl_Interp *interp, /* Tcl interpreter */ int result /* Result so far */ @@ -3256,7 +3256,7 @@ static int SQLITE_TCLAPI DbObjCmd( ** Adaptor that provides an objCmd interface to the NRE-enabled ** interface implementation. */ -static int DbObjCmdAdaptor( +static int SQLITE_TCLAPI DbObjCmdAdaptor( void *cd, Tcl_Interp *interp, int objc, From 7c60b266913db65ced9210a9cc4e50d15356f48c Mon Sep 17 00:00:00 2001 From: mistachkin Date: Thu, 28 Jul 2016 18:18:53 +0000 Subject: [PATCH 0620/1484] Fixup reserved function pointers in the Tcl stubs table and several macros containing Tcl function pointers. FossilOrigin-Name: 959cd0131a5c717679b6e250229794679efe7f69 --- Makefile.msc | 3 ++- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/Makefile.msc b/Makefile.msc index ca3e19aab8..1257ce2ba3 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -1997,7 +1997,8 @@ sqlite_tclDecls.h: | $(TCLSH_CMD) $(TOP)\tool\replace.tcl regsub "^(EXTERN(?: CONST\d+?)?\s+?[^\(]*?\s+?)Tcl_" "\1 SQLITE_TCLAPI Tcl_" \ | $(TCLSH_CMD) $(TOP)\tool\replace.tcl regsub "^(EXTERN\s+?(?:void|VOID)\s+?)TclFreeObj" "\1 SQLITE_TCLAPI TclFreeObj" \ | $(TCLSH_CMD) $(TOP)\tool\replace.tcl regsub "\(\*tcl_" "(SQLITE_TCLAPI *tcl_" \ - | $(TCLSH_CMD) $(TOP)\tool\replace.tcl regsub "\(\*tclFreeObj" "(SQLITE_TCLAPI *tclFreeObj" >> sqlite_tclDecls.h + | $(TCLSH_CMD) $(TOP)\tool\replace.tcl regsub "\(\*tclFreeObj" "(SQLITE_TCLAPI *tclFreeObj" \ + | $(TCLSH_CMD) $(TOP)\tool\replace.tcl regsub "\(\*" "(SQLITE_TCLAPI *" >> sqlite_tclDecls.h sqlite_tcl.h: sqlite_tclDecls.h type "$(TCLINCDIR)\tcl.h" | $(TCLSH_CMD) $(TOP)\tool\replace.tcl exact tclDecls.h sqlite_tclDecls.h \ diff --git a/manifest b/manifest index 4e202a429f..990660b97b 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -C Adjustments\sto\sget\s'testfixture.exe'\scompiling\swith\sTcl\s8.6\swhen\s__stdcall\sis\senabled. -D 2016-07-28T18:06:52.992 +C Fixup\sreserved\sfunction\spointers\sin\sthe\sTcl\sstubs\stable\sand\sseveral\smacros\scontaining\sTcl\sfunction\spointers. +D 2016-07-28T18:18:53.411 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 -F Makefile.msc c7934e2d3ef07c440ad48e2233c0cc8364e72aff +F Makefile.msc 959d56a9c117c3dc6f407a71aaa9fbad2df0b3c7 F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7 F VERSION cb29eb11e493dd85b3eeec4053c03949bf98478e F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 @@ -1508,7 +1508,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P f2f1323cc4d2ad2d6794dbfae8d50b747213e85d -R f48b462f2c7e74ed51a21c0e6f026658 +P 90e89ec9c8efff057a9e43c612427fc5c97ab52d +R d171dcc0a06f2c3b789ca76207152f9d U mistachkin -Z 339efe4a28b4c084d0a9150e8c742a8a +Z 48ca1d4dc91e624fdf594bf2bfd310c3 diff --git a/manifest.uuid b/manifest.uuid index e9bf450c4c..1992938c42 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -90e89ec9c8efff057a9e43c612427fc5c97ab52d \ No newline at end of file +959cd0131a5c717679b6e250229794679efe7f69 \ No newline at end of file From a8914faaaa981c87f193eb62477e7ba7d0affeed Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 28 Jul 2016 18:38:13 +0000 Subject: [PATCH 0621/1484] Disable the authorizer callback when reparsing the schema. This avoids undesirable authorization failures following an ALTER TABLE. FossilOrigin-Name: 805d01cdabb48a69eb986a7f084e53eb25d76b7f --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/auth.c | 1 + test/auth2.test | 12 ------------ test/auth3.test | 21 +++++++++++++++++++-- 5 files changed, 29 insertions(+), 23 deletions(-) diff --git a/manifest b/manifest index c71c10048d..b3d969ce87 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improvements\sto\sthe\sway\sthe\sCOMPILER\scompile-time\soption\sis\sset\swhen\scompiling\nwith\sClang. -D 2016-07-28T17:24:16.495 +C Disable\sthe\sauthorizer\scallback\swhen\sreparsing\sthe\sschema.\s\sThis\savoids\nundesirable\sauthorization\sfailures\sfollowing\san\sALTER\sTABLE. +D 2016-07-28T18:38:13.187 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -323,7 +323,7 @@ F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F src/alter.c cc28ab933ae615b22add0d609794ffb6596b42ea F src/analyze.c 37fedc80ac966ce1745811746e68e4d8fa64c7fe F src/attach.c 771153bd1f4ab0b97a44a13dde2c7e5e1efeba22 -F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240 +F src/auth.c 5c8e0f37f785f935f589496801edd19840485853 F src/backup.c 6df65fdd569c901a418887a1a76f82ec35044556 F src/bitvec.c 3ee4c8b2c94ed3a7377256e18199e6ff5cf33f63 F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 @@ -506,8 +506,8 @@ F test/attach3.test 359eb65d00102cdfcef6fa4e81dc1648f8f80b27 F test/attach4.test 53bf502f17647c6d6c5add46dda6bac8b6f4665c F test/attachmalloc.test 3a4bfca9545bfe906a8d2e622de10fbac5b711b0 F test/auth.test 872a122b3977c1d1bb9fd637dc20016e5c01880f -F test/auth2.test 264c6af53cad9aba5218c68bbe18036e39007bfa -F test/auth3.test 5cfa94ed90c6617c42b7ba4b133fd79678b251c7 +F test/auth2.test 9eb7fce9f34bf1f50d3f366fb3e606be5a2000a1 +F test/auth3.test b810826b193831929951c0d50783a200e5ef6b72 F test/autoinc.test c58912526998a39e11f66b533e23cfabea7f25b7 F test/autoindex1.test 14b63a9f1e405fe6d5bfc8c8d00249c2ebaf13ea F test/autoindex2.test 12ef578928102baaa0dc23ad397601a2f4ecb0df @@ -1508,7 +1508,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 6feff15cae8f0427be790355841d49c479c1c586 -R 675b3da4289ec2d84ea94ee475054664 +P 81f9cf86c48f3cd43755ded4dc97388ec650f8af +R ae8bfc7314166cec8de9b44e7e9859e8 U drh -Z 0881f39f36c917424fb94c651f3aec11 +Z 7b0f6930a62d02daa8f4147d6dafd3a6 diff --git a/manifest.uuid b/manifest.uuid index 060502d932..53827a1161 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -81f9cf86c48f3cd43755ded4dc97388ec650f8af \ No newline at end of file +805d01cdabb48a69eb986a7f084e53eb25d76b7f \ No newline at end of file diff --git a/src/auth.c b/src/auth.c index 9768fc2fc0..8a3f8e7d08 100644 --- a/src/auth.c +++ b/src/auth.c @@ -111,6 +111,7 @@ int sqlite3AuthReadCol( char *zDb = db->aDb[iDb].zName; /* Name of attached database */ int rc; /* Auth callback return code */ + if( db->init.busy ) return SQLITE_OK; rc = db->xAuth(db->pAuthArg, SQLITE_READ, zTab,zCol,zDb,pParse->zAuthContext #ifdef SQLITE_USER_AUTHENTICATION ,db->auth.zAuthUser diff --git a/test/auth2.test b/test/auth2.test index a9d64d08af..08d46cac57 100644 --- a/test/auth2.test +++ b/test/auth2.test @@ -98,12 +98,6 @@ SQLITE_UPDATE sqlite_master tbl_name main {} SQLITE_UPDATE sqlite_master rootpage main {} SQLITE_UPDATE sqlite_master sql main {} SQLITE_READ sqlite_master ROWID main {} -SQLITE_READ sqlite_master name main {} -SQLITE_READ sqlite_master rootpage main {} -SQLITE_READ sqlite_master sql main {} -SQLITE_READ sqlite_master tbl_name main {} -SQLITE_READ sqlite_master type main {} -SQLITE_READ sqlite_master ROWID main {} } do_test auth2-2.2 { set ::authargs {} @@ -119,12 +113,6 @@ SQLITE_UPDATE sqlite_master tbl_name main {} SQLITE_UPDATE sqlite_master rootpage main {} SQLITE_UPDATE sqlite_master sql main {} SQLITE_READ sqlite_master ROWID main {} -SQLITE_READ sqlite_master name main {} -SQLITE_READ sqlite_master rootpage main {} -SQLITE_READ sqlite_master sql main {} -SQLITE_READ sqlite_master tbl_name main {} -SQLITE_READ sqlite_master type main {} -SQLITE_READ sqlite_master ROWID main {} } do_test auth2-2.3 { set ::authargs {} diff --git a/test/auth3.test b/test/auth3.test index eef10b398f..ca7e16c84c 100644 --- a/test/auth3.test +++ b/test/auth3.test @@ -12,8 +12,7 @@ # Test that the truncate optimization is disabled if the SQLITE_DELETE # authorization callback returns SQLITE_IGNORE. # -# $Id: auth3.test,v 1.2 2009/05/04 01:58:31 drh Exp $ -# +# Test that authorizer is disabled during schema parsing. set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -108,4 +107,22 @@ do_test auth3-2.2 { set sqlite_search_count } {1} +# 2016-07-28. A problem report from a private client complaining about +# an authorizer failure during an ALTER TABLE. The solution (I think) is +# to disable the authorizer during schema parsing. +# +proc auth {code args} { + if {$code=="SQLITE_READ" && [regexp {DoNotRead} $args]} { + return SQLITE_DENY + } + return SQLITE_OK +} +do_execsql_test auth3-3.0 { + CREATE TEMPORARY TABLE TempTable ( + key TEXT NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT REPLACE, + value TEXT NOT NULL ON CONFLICT FAIL); + ALTER TABLE TempTable RENAME TO DoNotRead; + SELECT name FROM sqlite_temp_master; +} {DoNotRead sqlite_autoindex_DoNotRead_1} + finish_test From c0bebc1dcfe7711b80d3a3333d35c991849785ed Mon Sep 17 00:00:00 2001 From: mistachkin Date: Thu, 28 Jul 2016 18:49:20 +0000 Subject: [PATCH 0622/1484] All SQLite API functions and callbacks in the 'sqlite3ext.h' header file must be decorated with the calling convention. FossilOrigin-Name: 97fc6e4328fe72cdd10f11a4b4bc9ce14bdc537f --- Makefile.msc | 3 ++- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/Makefile.msc b/Makefile.msc index 1257ce2ba3..d2c53a0385 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -1846,7 +1846,8 @@ $(SQLITE3H): $(TOP)\src\sqlite.h.in $(TOP)\manifest.uuid $(TOP)\VERSION $(TCLSH_CMD) $(TOP)\tool\mksqlite3h.tcl $(TOP:\=/) > $(SQLITE3H) sqlite3ext.h: .target_source - copy tsrc\sqlite3ext.h . + type tsrc\sqlite3ext.h | $(TCLSH_CMD) $(TOP)\tool\replace.tcl regsub "\(\*\)" "(SQLITE_CALLBACK *)" \ + | $(TCLSH_CMD) $(TOP)\tool\replace.tcl regsub "\(\*" "(SQLITE_APICALL *" > sqlite3ext.h mkkeywordhash.exe: $(TOP)\tool\mkkeywordhash.c $(BCC) $(NO_WARN) -Fe$@ $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS) $(EXT_FEATURE_FLAGS) $(OPTS) \ diff --git a/manifest b/manifest index 990660b97b..bcfd6a51fa 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -C Fixup\sreserved\sfunction\spointers\sin\sthe\sTcl\sstubs\stable\sand\sseveral\smacros\scontaining\sTcl\sfunction\spointers. -D 2016-07-28T18:18:53.411 +C All\sSQLite\sAPI\sfunctions\sand\scallbacks\sin\sthe\s'sqlite3ext.h'\sheader\sfile\smust\sbe\sdecorated\swith\sthe\scalling\sconvention. +D 2016-07-28T18:49:20.480 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 -F Makefile.msc 959d56a9c117c3dc6f407a71aaa9fbad2df0b3c7 +F Makefile.msc b8894e579e4a5f32d61eb9309dbdbd7c883d2e87 F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7 F VERSION cb29eb11e493dd85b3eeec4053c03949bf98478e F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 @@ -1508,7 +1508,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 90e89ec9c8efff057a9e43c612427fc5c97ab52d -R d171dcc0a06f2c3b789ca76207152f9d +P 959cd0131a5c717679b6e250229794679efe7f69 +R 5c0ac8119f9b9a2ca4c809f0833a7b7c U mistachkin -Z 48ca1d4dc91e624fdf594bf2bfd310c3 +Z 4646b26f0f26be9837f9ae84f1defbff diff --git a/manifest.uuid b/manifest.uuid index 1992938c42..d28a372fd5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -959cd0131a5c717679b6e250229794679efe7f69 \ No newline at end of file +97fc6e4328fe72cdd10f11a4b4bc9ce14bdc537f \ No newline at end of file From e37f7397c97c75bc9c124564568f12253ee4533d Mon Sep 17 00:00:00 2001 From: mistachkin Date: Thu, 28 Jul 2016 19:28:35 +0000 Subject: [PATCH 0623/1484] The 'sqlite3ext.h' content should be processed before being included in the amalgamation. FossilOrigin-Name: cbe1de4799df4d512bc175f51ed99c6ec6d5a4d1 --- Makefile.msc | 3 ++- manifest | 17 ++++++++--------- manifest.uuid | 2 +- tool/mksqlite3c.tcl | 1 - 4 files changed, 11 insertions(+), 12 deletions(-) diff --git a/Makefile.msc b/Makefile.msc index d2c53a0385..b4cb94a5b8 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -1359,7 +1359,7 @@ HDR = \ parse.h \ $(TOP)\src\pragma.h \ $(SQLITE3H) \ - $(TOP)\src\sqlite3ext.h \ + sqlite3ext.h \ $(TOP)\src\sqliteInt.h \ $(TOP)\src\sqliteLimit.h \ $(TOP)\src\vdbe.h \ @@ -1848,6 +1848,7 @@ $(SQLITE3H): $(TOP)\src\sqlite.h.in $(TOP)\manifest.uuid $(TOP)\VERSION sqlite3ext.h: .target_source type tsrc\sqlite3ext.h | $(TCLSH_CMD) $(TOP)\tool\replace.tcl regsub "\(\*\)" "(SQLITE_CALLBACK *)" \ | $(TCLSH_CMD) $(TOP)\tool\replace.tcl regsub "\(\*" "(SQLITE_APICALL *" > sqlite3ext.h + copy /Y sqlite3ext.h tsrc\sqlite3ext.h mkkeywordhash.exe: $(TOP)\tool\mkkeywordhash.c $(BCC) $(NO_WARN) -Fe$@ $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS) $(EXT_FEATURE_FLAGS) $(OPTS) \ diff --git a/manifest b/manifest index 7b451988d9..4df76977b0 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -C Decorate\sall\sinterfaces\swith\scalling\sconvention\smacros. -D 2016-07-28T18:55:57.809 +C The\s'sqlite3ext.h'\scontent\sshould\sbe\sprocessed\sbefore\sbeing\sincluded\sin\sthe\samalgamation. +D 2016-07-28T19:28:35.475 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 -F Makefile.msc b8894e579e4a5f32d61eb9309dbdbd7c883d2e87 +F Makefile.msc eefec7a26bf73bb04f2241058e23a3ec8a43f656 F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7 F VERSION cb29eb11e493dd85b3eeec4053c03949bf98478e F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 @@ -1449,7 +1449,7 @@ F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e F tool/mkpragmatab.tcl f0d5bb266d1d388cf86fce5ba01a891e95d72d41 F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 F tool/mksqlite3c-noext.tcl aa58ea3be311c81821c2cd3209f55e46b07ab656 -F tool/mksqlite3c.tcl a52ead27e2ac5d4b616e945a0601f628f4328329 +F tool/mksqlite3c.tcl 655181fb25f69b3524b30efd0750c43513415216 F tool/mksqlite3h.tcl cf5cd68028e69a51ed5c76042672664201f0f756 F tool/mksqlite3internalh.tcl eb994013e833359137eb53a55acdad0b5ae1049b F tool/mkvsix.tcl 4abcaf3267171b2faadaf9b82a0dfbaa6e98f8b7 @@ -1508,8 +1508,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 805d01cdabb48a69eb986a7f084e53eb25d76b7f 97fc6e4328fe72cdd10f11a4b4bc9ce14bdc537f -R 8897711bcf29ba23a6ba0e1e7c3853bd -T +closed 97fc6e4328fe72cdd10f11a4b4bc9ce14bdc537f -U drh -Z 6ec050f366e0cbc18c7d1fd514c95e5b +P fd784887e125bf95f4799ad09cbcba6795173487 +R 159053f8c66afb3fed693021893388d2 +U mistachkin +Z 1fc3620b6fdad23d7ecfea7d673497bf diff --git a/manifest.uuid b/manifest.uuid index 76c400fd3d..ad3e416aac 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fd784887e125bf95f4799ad09cbcba6795173487 \ No newline at end of file +cbe1de4799df4d512bc175f51ed99c6ec6d5a4d1 \ No newline at end of file diff --git a/tool/mksqlite3c.tcl b/tool/mksqlite3c.tcl index b7561cfa5b..c5f765ed1c 100644 --- a/tool/mksqlite3c.tcl +++ b/tool/mksqlite3c.tcl @@ -112,7 +112,6 @@ foreach hdr { pragma.h rtree.h sqlite3session.h - sqlite3ext.h sqlite3.h sqlite3ext.h sqlite3rbu.h From 7b35a77b1a389d87cb5df356266b400e07d55afb Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 28 Jul 2016 19:47:15 +0000 Subject: [PATCH 0624/1484] Fix further issues with multi-column IN(...) operators. Also some error handling cases surrounding row values. FossilOrigin-Name: cc3f6542bec99b00d2698889bcea2aa0b587efa0 --- manifest | 15 +-- manifest.uuid | 2 +- src/expr.c | 218 ++++++++++++++++++++++++-------------------- src/whereexpr.c | 1 + test/rowvalue4.test | 48 ++++++++++ 5 files changed, 175 insertions(+), 109 deletions(-) create mode 100644 test/rowvalue4.test diff --git a/manifest b/manifest index 98dcf120d9..a1321d1be1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\slatest\strunk\schanges\sinto\sthis\sbranch. -D 2016-07-28T13:59:21.728 +C Fix\sfurther\sissues\swith\smulti-column\sIN(...)\soperators.\sAlso\ssome\serror\shandling\scases\ssurrounding\srow\svalues. +D 2016-07-28T19:47:15.803 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -337,7 +337,7 @@ F src/ctime.c 61949e83c4c36e37195a8398ebc752780b534d95 F src/date.c 1cc9fb516ec9932c6fd4d2a0d2f8bc4480145c39 F src/dbstat.c 4f6f7f52b49beb9636ffbd517cfe44a402ba4ad0 F src/delete.c 4aba4214a377ce8ddde2d2e609777bcc8235200f -F src/expr.c 82bc40bb27bc68b45303b560ab14eb16e39786a7 +F src/expr.c 473ce0ac25868b750f3bf9f59bbe7e8f06a0bdd5 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c bc4145347595b7770f9a598cff1c848302cf5413 F src/func.c 61a4114cf7004f10c542cfabbab9f2bcb9033045 @@ -466,7 +466,7 @@ F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354 F src/where.c df58d6ad7878a08aa96c652ccbc6d0949f8fa472 F src/whereInt.h 14dd243e13b81cbb0a66063d38b70f93a7d6e613 F src/wherecode.c 3aff7683566af3428f865904aafa7efb1fbd8701 -F src/whereexpr.c b896f8ff6a53cbd3daaee84ec33e39098762bb46 +F src/whereexpr.c bc85d04c6751ca40cab99a10de308e44893c76b9 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1021,6 +1021,7 @@ F test/rowid.test 5b7509f384f4f6fae1af3c8c104c8ca299fea18d F test/rowvalue.test 979738b3d49f1d93e3fee56a71d4446217917abc F test/rowvalue2.test 8d5dfe75b8f4d1868a2f91f0356f20d36cba64ff F test/rowvalue3.test 587c1056016fa6b7a40a9bf6cb85d5443fa47d96 +F test/rowvalue4.test 4480898d62d6813e3e38d9d38c02b9a0be5f94be F test/rtree.test 0c8d9dd458d6824e59683c19ab2ffa9ef946f798 F test/run-wordcount.sh 891e89c4c2d16e629cd45951d4ed899ad12afc09 F test/savepoint.test c671fdbd34cd3bfe1518a777526ada595180cf8d @@ -1511,7 +1512,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 719a3b2035a335ca8b9704646b1d641011e3ea0e 6feff15cae8f0427be790355841d49c479c1c586 -R 3c287799720eaa100d938a8b5fd4645d +P 9685880f7baeb670739fdcf2d9df08e22abaa699 +R 66ab918b4b1a726fe3dea7b50bb8fdb0 U dan -Z 3b75e2ba5b9150b77f0261ae152b7ba4 +Z 5baa8fdab10ded1fdce6b30d35067148 diff --git a/manifest.uuid b/manifest.uuid index 88af2bcaa6..c951167b81 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9685880f7baeb670739fdcf2d9df08e22abaa699 \ No newline at end of file +cc3f6542bec99b00d2698889bcea2aa0b587efa0 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 26587309f2..2921898d35 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1730,7 +1730,7 @@ int sqlite3IsRowid(const char *z){ ** */ #ifndef SQLITE_OMIT_SUBQUERY -static Select *isCandidateForInOpt(Expr *pX, int bNullSensitive){ +static Select *isCandidateForInOpt(Expr *pX){ Select *p; SrcList *pSrc; ExprList *pEList; @@ -1759,16 +1759,11 @@ static Select *isCandidateForInOpt(Expr *pX, int bNullSensitive){ if( IsVirtual(pTab) ) return 0; /* FROM clause not a virtual table */ pEList = p->pEList; - /* All SELECT results must be columns. If the SELECT returns more than - ** one column and the bNullSensitive flag is set, all returned columns - ** must be declared NOT NULL. */ + /* All SELECT results must be columns. */ for(i=0; inExpr; i++){ Expr *pRes = pEList->a[i].pExpr; if( pRes->op!=TK_COLUMN ) return 0; assert( pRes->iTable==pSrc->a[0].iCursor ); /* Not a correlated subquery */ - if( pEList->nExpr>1 && bNullSensitive ){ - if( pTab->aCol[pRes->iColumn].notNull==0 ) return 0; - } } return p; } @@ -1904,11 +1899,27 @@ int sqlite3FindInIndex( assert( pX->op==TK_IN ); mustBeUnique = (inFlags & IN_INDEX_LOOP)!=0; + /* If the RHS of this IN(...) operator is a SELECT, and if it matters + ** whether or not the SELECT result contains NULL values, check whether + ** or not NULL is actuall possible (it may not be, for example, due + ** to NOT NULL constraints in the schema). If no NULL values are possible, + ** set prRhsHasNull to 0 before continuing. + */ + if( prRhsHasNull && (pX->flags & EP_xIsSelect) ){ + int i; + ExprList *pEList = pX->x.pSelect->pEList; + for(i=0; inExpr; i++){ + if( sqlite3ExprCanBeNull(pEList->a[i].pExpr) ) break; + } + if( i==pEList->nExpr ){ + prRhsHasNull = 0; + } + } + /* Check to see if an existing table or index can be used to ** satisfy the query. This is preferable to generating a new - ** ephemeral table. - */ - if( pParse->nErr==0 && (p = isCandidateForInOpt(pX, prRhsHasNull!=0))!=0 ){ + ** ephemeral table. */ + if( pParse->nErr==0 && (p = isCandidateForInOpt(pX))!=0 ){ sqlite3 *db = pParse->db; /* Database connection */ Table *pTab; /* Table
    . */ i16 iDb; /* Database idx for pTab */ @@ -1996,16 +2007,16 @@ int sqlite3FindInIndex( assert( IN_INDEX_INDEX_DESC == IN_INDEX_INDEX_ASC+1 ); eType = IN_INDEX_INDEX_ASC + pIdx->aSortOrder[0]; - if( prRhsHasNull && nExpr==1 - && !pTab->aCol[pEList->a[0].pExpr->iColumn].notNull - ){ + if( prRhsHasNull ){ + *prRhsHasNull = ++pParse->nMem; #ifdef SQLITE_ENABLE_COLUMN_USED_MASK i64 mask = (1<nMem; - sqlite3SetHasNullFlag(v, iTab, *prRhsHasNull); + if( nExpr==1 ){ + sqlite3SetHasNullFlag(v, iTab, *prRhsHasNull); + } } sqlite3VdbeJumpHere(v, iAddr); } @@ -2352,6 +2363,32 @@ int sqlite3CodeSubselect( } #endif /* SQLITE_OMIT_SUBQUERY */ +#ifndef SQLITE_OMIT_SUBQUERY +/* +** Expr pIn is an IN(...) expression. This function checks that the +** sub-select on the RHS of the IN() operator has the same number of +** columns as the vector on the LHS. Or, if the RHS of the IN() is not +** a sub-query, that the LHS is a vector of size 1. +*/ +int sqlite3ExprCheckIN(Parse *pParse, Expr *pIn){ + int nVector = sqlite3ExprVectorSize(pIn->pLeft); + if( (pIn->flags & EP_xIsSelect) ){ + if( nVector!=pIn->x.pSelect->pEList->nExpr ){ + sqlite3SubselectError(pParse, pIn->x.pSelect->pEList->nExpr, nVector); + return 1; + } + }else if( nVector!=1 ){ + if( (pIn->pLeft->flags & EP_xIsSelect) ){ + sqlite3SubselectError(pParse, nVector, 1); + }else{ + sqlite3ErrorMsg(pParse, "invalid use of row value"); + } + return 1; + } + return 0; +} +#endif + #ifndef SQLITE_OMIT_SUBQUERY /* ** Generate code for an IN expression. @@ -2387,6 +2424,7 @@ static void sqlite3ExprCodeIN( Expr *pLeft = pExpr->pLeft; int i; + if( sqlite3ExprCheckIN(pParse, pExpr) ) return; nVector = sqlite3ExprVectorSize(pExpr->pLeft); aiMap = (int*)sqlite3DbMallocZero( pParse->db, nVector*(sizeof(int) + sizeof(char)) + 1 @@ -2394,6 +2432,7 @@ static void sqlite3ExprCodeIN( if( !aiMap ) return; zAff = (char*)&aiMap[nVector]; + /* Attempt to compute the RHS. After this step, if anything other than ** IN_INDEX_NOOP is returned, the table opened ith cursor pExpr->iTable ** contains the values that make up the RHS. If IN_INDEX_NOOP is returned, @@ -2479,8 +2518,15 @@ static void sqlite3ExprCodeIN( sqlite3ReleaseTempReg(pParse, regCkNull); }else{ - /* If the LHS is NULL, then the result is either false or NULL depending - ** on whether the RHS is empty or not, respectively. */ + /* If any value on the LHS is NULL, the result of the IN(...) operator + ** must be either false or NULL. If these two are handled identically, + ** test the LHS for NULLs and jump directly to destIfNull if any are + ** found. + ** + ** Otherwise, if NULL and false are handled differently, and the + ** IN(...) operation is not a vector operation, and the LHS of the + ** operator is NULL, then the result is false if the index is + ** completely empty, or NULL otherwise. */ if( destIfNull==destIfFalse ){ for(i=0; ipLeft, i); @@ -2497,70 +2543,62 @@ static void sqlite3ExprCodeIN( } if( eType==IN_INDEX_ROWID ){ - /* In this case, the RHS is the ROWID of table b-tree - */ + /* In this case, the RHS is the ROWID of table b-tree */ sqlite3VdbeAddOp3(v, OP_SeekRowid, pExpr->iTable, destIfFalse, r1); VdbeCoverage(v); - }else if( nVector>1 && eType==IN_INDEX_EPH && destIfNull!=destIfFalse ){ - int regNull = sqlite3GetTempReg(pParse); - int r2 = sqlite3GetTempReg(pParse); - int r3 = sqlite3GetTempReg(pParse); - int r4 = sqlite3GetTempReg(pParse); - int addrNext; - int addrIf; - - if( destIfFalse!=destIfNull ){ - sqlite3VdbeAddOp2(v, OP_Integer, 0, regNull); - } - addrNext = sqlite3VdbeAddOp2(v, OP_Rewind, pExpr->iTable, destIfFalse); - for(i=0; iiTable, i, r2); - sqlite3VdbeAddOp4(v, OP_Eq, r1+i, i?r3:r4, r2, (void*)pColl,P4_COLLSEQ); - sqlite3VdbeChangeP5(v, SQLITE_STOREP2); - if( i!=0 ){ - sqlite3VdbeAddOp3(v, OP_And, r3, r4, r4); - } - } - addrIf = sqlite3VdbeAddOp1(v, OP_If, r4); - if( destIfNull!=destIfFalse ){ - sqlite3VdbeAddOp2(v, OP_IfNot, r4, sqlite3VdbeCurrentAddr(v)+2); - sqlite3VdbeAddOp2(v, OP_Integer, 1, regNull); - } - sqlite3VdbeAddOp2(v, OP_Next, pExpr->iTable, addrNext+1); - if( destIfNull!=destIfFalse ){ - sqlite3VdbeAddOp2(v, OP_If, regNull, destIfNull); - } - sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfFalse); - sqlite3VdbeChangeP2(v, addrIf, sqlite3VdbeCurrentAddr(v)); - sqlite3ReleaseTempReg(pParse, regNull); - sqlite3ReleaseTempReg(pParse, r2); - sqlite3ReleaseTempReg(pParse, r3); - sqlite3ReleaseTempReg(pParse, r4); }else{ - /* In this case, the RHS is an index b-tree. - */ + /* In this case, the RHS is an index b-tree. Apply the comparison + ** affinities to each value on the LHS of the operator. */ sqlite3VdbeAddOp4(v, OP_Affinity, r1, nVector, 0, zAff, nVector); - - /* If the set membership test fails, then the result of the - ** "x IN (...)" expression must be either 0 or NULL. If the set - ** contains no NULL values, then the result is 0. If the set - ** contains one or more NULL values, then the result of the - ** expression is also NULL. - */ - assert( destIfFalse!=destIfNull || rRhsHasNull==0 ); - if( rRhsHasNull==0 ){ + + if( nVector>1 && destIfNull!=destIfFalse ){ + int iIdx = pExpr->iTable; + int addr; + int addrNext; + + /* Search the index for the key. */ + addr = sqlite3VdbeAddOp4Int(v, OP_Found, iIdx, 0, r1, nVector); + + /* At this point the specified key is not present in the index, + ** so the result of the IN(..) operator must be either NULL or + ** 0. The vdbe code generated below figures out which. */ + addrNext = 1+sqlite3VdbeAddOp2(v, OP_Rewind, iIdx, destIfFalse); + + for(i=0; ipLeft, i); + if( sqlite3ExprCanBeNull(p) ){ + sqlite3VdbeAddOp2(v, OP_IsNull, r1+aiMap[i], destIfNull); + } + } + + }else if( rRhsHasNull==0 ){ /* This branch runs if it is known at compile time that the RHS - ** cannot contain NULL values. This happens as the result - ** of a "NOT NULL" constraint in the database schema. + ** cannot contain NULL values. This happens as a result + ** of "NOT NULL" constraints in the database schema. ** ** Also run this branch if NULL is equivalent to FALSE - ** for this particular IN operator. - */ + ** for this particular IN operator. */ sqlite3VdbeAddOp4Int( v, OP_NotFound, pExpr->iTable, destIfFalse, r1, nVector ); @@ -2571,7 +2609,7 @@ static void sqlite3ExprCodeIN( ** outcome. */ int addr1; - + /* First check to see if the LHS is contained in the RHS. If so, ** then the answer is TRUE the presence of NULLs in the RHS does ** not matter. If the LHS is not contained in the RHS, then the @@ -3003,7 +3041,7 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ int inReg = target; /* Results stored in register inReg */ int regFree1 = 0; /* If non-zero free this temporary register */ int regFree2 = 0; /* If non-zero free this temporary register */ - int r1, r2, r3, r4; /* Various register numbers */ + int r1, r2; /* Various register numbers */ sqlite3 *db = pParse->db; /* The database connection */ Expr tempX; /* Temporary expression node */ int p5 = 0; @@ -3404,30 +3442,6 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ */ case TK_BETWEEN: { exprCodeBetween(pParse, pExpr, target, 0, 0); -#if 0 - Expr *pLeft = pExpr->pLeft; - struct ExprList_item *pLItem = pExpr->x.pList->a; - Expr *pRight = pLItem->pExpr; - - r1 = sqlite3ExprCodeTemp(pParse, pLeft, ®Free1); - r2 = sqlite3ExprCodeTemp(pParse, pRight, ®Free2); - testcase( regFree1==0 ); - testcase( regFree2==0 ); - r3 = sqlite3GetTempReg(pParse); - r4 = sqlite3GetTempReg(pParse); - codeCompare(pParse, pLeft, pRight, OP_Ge, - r1, r2, r3, SQLITE_STOREP2); VdbeCoverage(v); - pLItem++; - pRight = pLItem->pExpr; - sqlite3ReleaseTempReg(pParse, regFree2); - r2 = sqlite3ExprCodeTemp(pParse, pRight, ®Free2); - testcase( regFree2==0 ); - codeCompare(pParse, pLeft, pRight, OP_Le, r1, r2, r4, SQLITE_STOREP2); - VdbeCoverage(v); - sqlite3VdbeAddOp3(v, OP_And, r3, r4, target); - sqlite3ReleaseTempReg(pParse, r3); - sqlite3ReleaseTempReg(pParse, r4); -#endif break; } case TK_SPAN: @@ -3908,7 +3922,7 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ if( NEVER(v==0) ) return; /* Existence of VDBE checked by caller */ if( NEVER(pExpr==0) ) return; /* No way this can happen */ op = pExpr->op; - switch( op | (pExpr->pLeft ? (pExpr->pLeft->flags & EP_Vector) : 0)){ + switch( op ){ case TK_AND: { int d2 = sqlite3VdbeMakeLabel(v); testcase( jumpIfNull==0 ); @@ -3945,6 +3959,7 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ case TK_GE: case TK_NE: case TK_EQ: { + if( pExpr->pLeft->flags & EP_Vector ) goto default_expr; testcase( jumpIfNull==0 ); r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); @@ -3991,6 +4006,7 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ } #endif default: { + default_expr: if( exprAlwaysTrue(pExpr) ){ sqlite3VdbeGoto(v, dest); }else if( exprAlwaysFalse(pExpr) ){ diff --git a/src/whereexpr.c b/src/whereexpr.c index 67b2e67baa..9c9be99039 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -934,6 +934,7 @@ static void exprAnalyze( op = pExpr->op; if( op==TK_IN ){ assert( pExpr->pRight==0 ); + if( sqlite3ExprCheckIN(pParse, pExpr) ) return; if( ExprHasProperty(pExpr, EP_xIsSelect) ){ pTerm->prereqRight = exprSelectUsage(pMaskSet, pExpr->x.pSelect); }else{ diff --git a/test/rowvalue4.test b/test/rowvalue4.test new file mode 100644 index 0000000000..1dfcfb903a --- /dev/null +++ b/test/rowvalue4.test @@ -0,0 +1,48 @@ +# 2016 July 29 +# +# 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 regression tests for SQLite library. The +# focus of this file is syntax errors involving row-value constructors +# and sub-selects that return multiple arguments. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set ::testprefix rowvalue4 + +do_execsql_test 0 { + CREATE TABLE t1(a, b, c); + CREATE INDEX t1bac ON t1(b, a, c); +} + +foreach {tn e} { + 1 "(1, 2, 3)" + 2 "1 + (1, 2)" + 3 "(1,2,3) == (1, 2)" +} { + do_catchsql_test 1.$tn "SELECT $e" {1 {invalid use of row value}} +} + +foreach {tn s error} { + 1 "SELECT * FROM t1 WHERE a = (1, 2)" {invalid use of row value} + 2 "SELECT * FROM t1 WHERE b = (1, 2)" {invalid use of row value} + 3 "SELECT * FROM t1 WHERE NOT (b = (1, 2))" {invalid use of row value} + 4 "SELECT * FROM t1 LIMIT (1, 2)" {invalid use of row value} + 5 "SELECT (a, b) IN (SELECT * FROM t1) FROM t1" + {sub-select returns 3 columns - expected 2} + + 6 "SELECT * FROM t1 WHERE (a, b) IN (SELECT * FROM t1)" + {sub-select returns 3 columns - expected 2} +} { + do_catchsql_test 2.$tn "$s" [list 1 $error] +} + +finish_test + From 44e95d4f028e537c411e746e312af658b6153dff Mon Sep 17 00:00:00 2001 From: mistachkin Date: Thu, 28 Jul 2016 22:23:26 +0000 Subject: [PATCH 0625/1484] Make the extension auto-loading mechanism work with the __stdcall calling convention. Also, fix a couple Tcl command calling conventions missed in the previous check-in. FossilOrigin-Name: 3ea567c4b07b2a7a027b9b5cb8250ab687803698 --- Makefile.msc | 11 +++++++++++ ext/misc/vfsstat.c | 2 +- manifest | 30 +++++++++++++++--------------- manifest.uuid | 2 +- src/loadext.c | 44 ++++++++++++++++++++++++++++++-------------- src/sqlite.h.in | 8 ++++++-- src/sqlite3ext.h | 14 ++++++++++++-- src/tclsqlite.c | 20 +++++++++++++++++--- src/test_autoext.c | 12 ++++++------ src/test_func.c | 18 +++++++++++------- src/test_multiplex.c | 2 +- src/test_thread.c | 4 ++-- 12 files changed, 113 insertions(+), 54 deletions(-) diff --git a/Makefile.msc b/Makefile.msc index b4cb94a5b8..527efd8f7d 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -24,6 +24,13 @@ USE_AMALGAMATION = 1 USE_FULLWARN = 0 !ENDIF +# Set this non-0 to enable full runtime error checks (-RTC1, etc). This +# has no effect if (any) optimizations are enabled. +# +!IFNDEF USE_RUNTIME_CHECKS +USE_RUNTIME_CHECKS = 0 +!ENDIF + # Set this non-0 to use "stdcall" calling convention for the core library # and shell executable. # @@ -847,6 +854,10 @@ RCC = $(RCC) -D_DEBUG !IF $(DEBUG)>1 || $(OPTIMIZATIONS)==0 TCC = $(TCC) -Od BCC = $(BCC) -Od +!IF $(USE_RUNTIME_CHECKS)!=0 +TCC = $(TCC) -RTC1 +BCC = $(BCC) -RTC1 +!ENDIF !ELSEIF $(OPTIMIZATIONS)>=3 TCC = $(TCC) -Ox BCC = $(BCC) -Ox diff --git a/ext/misc/vfsstat.c b/ext/misc/vfsstat.c index af088d6655..14753d277d 100644 --- a/ext/misc/vfsstat.c +++ b/ext/misc/vfsstat.c @@ -809,7 +809,7 @@ int sqlite3_vfsstat_init( vstat_vfs.base.szOsFile = sizeof(VStatFile) + vstat_vfs.pVfs->szOsFile; rc = sqlite3_vfs_register(&vstat_vfs.base, 1); if( rc==SQLITE_OK ){ - rc = sqlite3_auto_extension((void(*)(void))vstatRegister); + rc = sqlite3_auto_extension(vstatRegister); } if( rc==SQLITE_OK ) rc = SQLITE_OK_LOAD_PERMANENTLY; return rc; diff --git a/manifest b/manifest index 4df76977b0..36d529bb7a 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -C The\s'sqlite3ext.h'\scontent\sshould\sbe\sprocessed\sbefore\sbeing\sincluded\sin\sthe\samalgamation. -D 2016-07-28T19:28:35.475 +C Make\sthe\sextension\sauto-loading\smechanism\swork\swith\sthe\s__stdcall\scalling\sconvention.\s\sAlso,\sfix\sa\scouple\sTcl\scommand\scalling\sconventions\smissed\sin\sthe\sprevious\scheck-in. +D 2016-07-28T22:23:26.522 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 -F Makefile.msc eefec7a26bf73bb04f2241058e23a3ec8a43f656 +F Makefile.msc 3340e479e5221f06c3d61726f8f7efff885e4233 F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7 F VERSION cb29eb11e493dd85b3eeec4053c03949bf98478e F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 @@ -223,7 +223,7 @@ F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52 F ext/misc/spellfix.c a4723b6aff748a417b5091b68a46443265c40f0d F ext/misc/totype.c 4a167594e791abeed95e0a8db028822b5e8fe512 F ext/misc/vfslog.c fe40fab5c077a40477f7e5eba994309ecac6cc95 -F ext/misc/vfsstat.c 6110aeeaab2f1df17a923c8a8acef3c74f6dc515 +F ext/misc/vfsstat.c bf10ef0bc51e1ad6756629e1edb142f7a8db1178 F ext/misc/vtshim.c babb0dc2bf116029e3e7c9a618b8a1377045303e F ext/misc/wholenumber.c 784b12543d60702ebdd47da936e278aa03076212 F ext/rbu/rbu.c b2c0b5e6ae1a89affc0edfc127ebfa5f637a0ce4 @@ -347,7 +347,7 @@ F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4 F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da F src/insert.c 8f4e9fcbd8e95e85f15647ba8b413b18d556ec2b F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e -F src/loadext.c 5dd8b5a67d32a98bb75657c2a9e48b2cedbf13a4 +F src/loadext.c 4e26039f8d2e91acd57e55fcc31477aa37a3aa80 F src/main.c 16c1b2114eae8804caf3a8de8cb47bf2c6d83ad3 F src/malloc.c 1443d1ad95d67c21d77af7ae3f44678252f0efec F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 @@ -385,14 +385,14 @@ F src/resolve.c cca3aa77b95706df5d635a2141a4d1de60ae6598 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c f3c6e9065fb34f6a23af27ec7f1f717ffbfc2ee4 F src/shell.c 9351fc6de11e1d908648c0a92d85627138e3dee5 -F src/sqlite.h.in a03063e698a43cc5c996cd341f39439a6ce58304 +F src/sqlite.h.in 856ab22cfcec0ba94d2f0139a72a9797343687b3 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 -F src/sqlite3ext.h 46f300b6e300e0fa916d7d58c44b53415b8471a9 +F src/sqlite3ext.h 978c062d3fa59a22c6d57305b9f290e3a26110c3 F src/sqliteInt.h 14516943867eb2c30ce0e3670299958f59ade052 F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c 5b18f9526900f61189ab0b83f1ef41d9f871a2ab F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 -F src/tclsqlite.c 342379845d52c62a778c76c3dd0a2695af723e04 +F src/tclsqlite.c 2ca362fa9c9762f705169aa5b2e75d688f4391f7 F src/test1.c 906a04b649c7139e943193a3905d583e325c30c7 F src/test2.c b7174313e993754303a8b33c43df7c44b46857ab F src/test3.c 1339a40be39650ae83894b6578f971dc7f96ea8a @@ -403,7 +403,7 @@ F src/test7.c 5612e9aecf934d6df7bba6ce861fdf5ba5456010 F src/test8.c 4f4904721167b32f7a4fa8c7b32a07a673d6cc86 F src/test9.c 12e5ba554d2d1cbe0158f6ab3f7ffcd7a86ee4e5 F src/test_async.c 195ab49da082053fdb0f949c114b806a49ca770a -F src/test_autoext.c 6c8fe00caa3f38396f0990467179e9d1adb39ddd +F src/test_autoext.c cc69375c006b7bac6094ec602f52525350fd5229 F src/test_backup.c bf5da90c9926df0a4b941f2d92825a01bbe090a0 F src/test_bestindex.c d23f80d334c59662af69191854c76b8d3d0c8c96 F src/test_blob.c a0f7ad49a0c9d4b72f693fe2a71c58d7e507174d @@ -412,7 +412,7 @@ F src/test_config.c 4d3d4a886416f369771d69a6dba926866deda788 F src/test_demovfs.c a0c3bdd45ed044115c2c9f7779e56eafff18741e F src/test_devsym.c 4e58dec2602d8e139ca08659f62a62450587cb58 F src/test_fs.c ac62ce7d5c0c23aa6932891cad5746945564c91c -F src/test_func.c 9cea6fee7ece5f46aa26e060b35e10dc6ba708cf +F src/test_func.c 7dceef0e0556933a751af9b73478519b6dc12f0f F src/test_hexio.c 1d4469ca61ab202a1fcec6543f584d2407205e8d F src/test_init.c 4413c211a94b62157ca4c145b3f27c497f03c664 F src/test_intarray.c 988fc61cb0ff539f4172c0d95f15287c92516f64 @@ -420,7 +420,7 @@ F src/test_intarray.h f3b7672f5d1056eac563c0d6ea8480a660b1475c F src/test_journal.c d3b83f2bcb7792c709e57abddc456a2b1818643a F src/test_loadext.c 337056bae59f80b9eb00ba82088b39d0f4fe6dfd F src/test_malloc.c c05f6c40bd6c8bfe5f1718212f81fd5687f91766 -F src/test_multiplex.c af2792ec4436d442d1bd00b8803470a25111bad3 +F src/test_multiplex.c 371d3874fd6365f18468d1c131e153e5c9abe95e F src/test_multiplex.h 5436d03f2d0501d04f3ed50a75819e190495b635 F src/test_mutex.c 7f4337ba23ee6b1d2ec81c189653608cb069926a F src/test_onefile.c 416f87a28d6d673352d33fc4b1c7d39db878e50f @@ -435,7 +435,7 @@ F src/test_sqllog.c 0d138a8180a312bf996b37fa66da5c5799d4d57b F src/test_superlock.c 4839644b9201da822f181c5bc406c0b2385f672e F src/test_syscall.c 1073306ba2e9bfc886771871a13d3de281ed3939 F src/test_tclvar.c df9fe1213c2634687a9ca0b0bec0d2119d359ae3 -F src/test_thread.c c7c40494b7a0603ebb6eb97c904545c0dceca5ff +F src/test_thread.c a122592c2b857c79eb4ee4bacb62a5a6c8fe4c6f F src/test_vfs.c f0186261a24de2671d080bcd8050732f0cb64f6e F src/test_vfstrace.c bab9594adc976cbe696ff3970728830b4c5ed698 F src/test_windirent.c 8f5fada630348558d5745b334702f301da1ffc61 @@ -1508,7 +1508,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P fd784887e125bf95f4799ad09cbcba6795173487 -R 159053f8c66afb3fed693021893388d2 +P cbe1de4799df4d512bc175f51ed99c6ec6d5a4d1 +R bda25e48e90849454c6e864127930d74 U mistachkin -Z 1fc3620b6fdad23d7ecfea7d673497bf +Z 008c4b78efecf8010a475c91e6246b39 diff --git a/manifest.uuid b/manifest.uuid index ad3e416aac..0a08bdb4e1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cbe1de4799df4d512bc175f51ed99c6ec6d5a4d1 \ No newline at end of file +3ea567c4b07b2a7a027b9b5cb8250ab687803698 \ No newline at end of file diff --git a/src/loadext.c b/src/loadext.c index ce1f5317c6..525272d7fe 100644 --- a/src/loadext.c +++ b/src/loadext.c @@ -21,6 +21,14 @@ #include #ifndef SQLITE_OMIT_LOAD_EXTENSION +/* +** This is the function signature used for all extension entry points. +*/ +typedef int (*sqlite3_loadext_entry)( + sqlite3 *db, /* Handle to the database. */ + char **pzErrMsg, /* Used to set error string on failure. */ + const sqlite3_api_routines *pThunk /* Extension API function pointers. */ +); /* ** Some API routines are omitted when various features are @@ -111,6 +119,10 @@ #define sqlite3_blob_reopen 0 #endif +#if defined(SQLITE_OMIT_TRACE) +# define sqlite3_trace_v2 0 +#endif + /* ** The following structure contains pointers to all SQLite API routines. ** A pointer to this structure is passed into extensions when they are @@ -416,7 +428,10 @@ static const sqlite3_api_routines sqlite3Apis = { sqlite3_strlike, sqlite3_db_cacheflush, /* Version 3.12.0 and later */ - sqlite3_system_errno + sqlite3_system_errno, + /* Version 3.14.0 and later */ + sqlite3_trace_v2, + sqlite3_expanded_sql }; /* @@ -439,7 +454,7 @@ static int sqlite3LoadExtension( ){ sqlite3_vfs *pVfs = db->pVfs; void *handle; - int (*xInit)(sqlite3*,char**,const sqlite3_api_routines*); + sqlite3_loadext_entry xInit; char *zErrmsg = 0; const char *zEntry; char *zAltEntry = 0; @@ -498,8 +513,7 @@ static int sqlite3LoadExtension( } return SQLITE_ERROR; } - xInit = (int(*)(sqlite3*,char**,const sqlite3_api_routines*)) - sqlite3OsDlSym(pVfs, handle, zEntry); + xInit = (sqlite3_loadext_entry)sqlite3OsDlSym(pVfs, handle, zEntry); /* If no entry point was specified and the default legacy ** entry point name "sqlite3_extension_init" was not found, then @@ -531,8 +545,7 @@ static int sqlite3LoadExtension( } memcpy(zAltEntry+iEntry, "_init", 6); zEntry = zAltEntry; - xInit = (int(*)(sqlite3*,char**,const sqlite3_api_routines*)) - sqlite3OsDlSym(pVfs, handle, zEntry); + xInit = (sqlite3_loadext_entry)sqlite3OsDlSym(pVfs, handle, zEntry); } if( xInit==0 ){ if( pzErrMsg ){ @@ -662,7 +675,9 @@ static SQLITE_WSD struct sqlite3AutoExtList { ** Register a statically linked extension that is automatically ** loaded by every new database connection. */ -int sqlite3_auto_extension(void (*xInit)(void)){ +int sqlite3_auto_extension( + void (*xInit)(sqlite3 *, char **, const void *) /* Extension entry point */ +){ int rc = SQLITE_OK; #ifndef SQLITE_OMIT_AUTOINIT rc = sqlite3_initialize(); @@ -678,7 +693,7 @@ int sqlite3_auto_extension(void (*xInit)(void)){ wsdAutoextInit; sqlite3_mutex_enter(mutex); for(i=0; i=0; i--){ - if( wsdAutoext.aExt[i]==xInit ){ + if( wsdAutoext.aExt[i]==(void*)xInit ){ wsdAutoext.nExt--; wsdAutoext.aExt[i] = wsdAutoext.aExt[wsdAutoext.nExt]; n++; @@ -756,7 +773,7 @@ void sqlite3AutoLoadExtensions(sqlite3 *db){ u32 i; int go = 1; int rc; - int (*xInit)(sqlite3*,char**,const sqlite3_api_routines*); + sqlite3_loadext_entry xInit; wsdAutoextInit; if( wsdAutoext.nExt==0 ){ @@ -773,8 +790,7 @@ void sqlite3AutoLoadExtensions(sqlite3 *db){ xInit = 0; go = 0; }else{ - xInit = (int(*)(sqlite3*,char**,const sqlite3_api_routines*)) - wsdAutoext.aExt[i]; + xInit = (sqlite3_loadext_entry)wsdAutoext.aExt[i]; } sqlite3_mutex_leave(mutex); zErrmsg = 0; diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 02ae22c346..104e465467 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -5707,7 +5707,9 @@ int sqlite3_enable_load_extension(sqlite3 *db, int onoff); ** See also: [sqlite3_reset_auto_extension()] ** and [sqlite3_cancel_auto_extension()] */ -int sqlite3_auto_extension(void (*xEntryPoint)(void)); +int sqlite3_auto_extension( + void (*xEntryPoint)(sqlite3 *, char **, const void *) +); /* ** CAPI3REF: Cancel Automatic Extension Loading @@ -5719,7 +5721,9 @@ int sqlite3_auto_extension(void (*xEntryPoint)(void)); ** unregistered and it returns 0 if X was not on the list of initialization ** routines. */ -int sqlite3_cancel_auto_extension(void (*xEntryPoint)(void)); +int sqlite3_cancel_auto_extension( + void (*xEntryPoint)(sqlite3 *, char **, const void *) +); /* ** CAPI3REF: Reset Automatic Extension Loading diff --git a/src/sqlite3ext.h b/src/sqlite3ext.h index 338e1becd5..d79ca826de 100644 --- a/src/sqlite3ext.h +++ b/src/sqlite3ext.h @@ -251,12 +251,12 @@ struct sqlite3_api_routines { char *(*vsnprintf)(int,char*,const char*,va_list); int (*wal_checkpoint_v2)(sqlite3*,const char*,int,int*,int*); /* Version 3.8.7 and later */ - int (*auto_extension)(void(*)(void)); + int (*auto_extension)(void(*)(sqlite3*,char**,const void*)); int (*bind_blob64)(sqlite3_stmt*,int,const void*,sqlite3_uint64, void(*)(void*)); int (*bind_text64)(sqlite3_stmt*,int,const char*,sqlite3_uint64, void(*)(void*),unsigned char); - int (*cancel_auto_extension)(void(*)(void)); + int (*cancel_auto_extension)(void(*)(sqlite3*,char**,const void*)); int (*load_extension)(sqlite3*,const char*,const char*,char**); void *(*malloc64)(sqlite3_uint64); sqlite3_uint64 (*msize)(void*); @@ -286,6 +286,16 @@ struct sqlite3_api_routines { char *(*expanded_sql)(sqlite3_stmt*); }; +/* +** This is the function signature used for all extension entry points. It +** is also defined in the file "loadext.c". +*/ +typedef int (*sqlite3_loadext_entry)( + sqlite3 *db, /* Handle to the database. */ + char **pzErrMsg, /* Used to set error string on failure. */ + const sqlite3_api_routines *pThunk /* Extension API function pointers. */ +); + /* ** The following macros redefine the API routines so that they are ** redirected through the global sqlite3_api structure. diff --git a/src/tclsqlite.c b/src/tclsqlite.c index bc94a5ff7f..dd4e42e8a9 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -3806,7 +3806,12 @@ static void MD5DigestToBase10x8(unsigned char digest[16], char zDigest[50]){ ** A TCL command for md5. The argument is the text to be hashed. The ** Result is the hash in base64. */ -static int md5_cmd(void*cd, Tcl_Interp *interp, int argc, const char **argv){ +static int SQLITE_TCLAPI md5_cmd( + void*cd, + Tcl_Interp *interp, + int argc, + const char **argv +){ MD5Context ctx; unsigned char digest[16]; char zBuf[50]; @@ -3830,7 +3835,12 @@ static int md5_cmd(void*cd, Tcl_Interp *interp, int argc, const char **argv){ ** A TCL command to take the md5 hash of a file. The argument is the ** name of the file. */ -static int md5file_cmd(void*cd, Tcl_Interp*interp, int argc, const char **argv){ +static int SQLITE_TCLAPI md5file_cmd( + void*cd, + Tcl_Interp *interp, + int argc, + const char **argv +){ FILE *in; MD5Context ctx; void (*converter)(unsigned char*, char*); @@ -3910,7 +3920,11 @@ static void md5finalize(sqlite3_context *context){ MD5DigestToBase16(digest, zBuf); sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT); } -int Md5_Register(sqlite3 *db){ +int Md5_Register( + sqlite3 *db, + char **pzErrMsg, + const void *pThunk +){ int rc = sqlite3_create_function(db, "md5sum", -1, SQLITE_UTF8, 0, 0, md5step, md5finalize); sqlite3_overload_function(db, "md5sum", -1); /* To exercise this API */ diff --git a/src/test_autoext.c b/src/test_autoext.c index 94a3223e65..f962a51d6b 100644 --- a/src/test_autoext.c +++ b/src/test_autoext.c @@ -100,7 +100,7 @@ static int SQLITE_TCLAPI autoExtSqrObjCmd( int objc, Tcl_Obj *CONST objv[] ){ - int rc = sqlite3_auto_extension((void*)sqr_init); + int rc = sqlite3_auto_extension(sqr_init); Tcl_SetObjResult(interp, Tcl_NewIntObj(rc)); return SQLITE_OK; } @@ -116,7 +116,7 @@ static int SQLITE_TCLAPI cancelAutoExtSqrObjCmd( int objc, Tcl_Obj *CONST objv[] ){ - int rc = sqlite3_cancel_auto_extension((void*)sqr_init); + int rc = sqlite3_cancel_auto_extension(sqr_init); Tcl_SetObjResult(interp, Tcl_NewIntObj(rc)); return SQLITE_OK; } @@ -132,7 +132,7 @@ static int SQLITE_TCLAPI autoExtCubeObjCmd( int objc, Tcl_Obj *CONST objv[] ){ - int rc = sqlite3_auto_extension((void*)cube_init); + int rc = sqlite3_auto_extension(cube_init); Tcl_SetObjResult(interp, Tcl_NewIntObj(rc)); return SQLITE_OK; } @@ -148,7 +148,7 @@ static int SQLITE_TCLAPI cancelAutoExtCubeObjCmd( int objc, Tcl_Obj *CONST objv[] ){ - int rc = sqlite3_cancel_auto_extension((void*)cube_init); + int rc = sqlite3_cancel_auto_extension(cube_init); Tcl_SetObjResult(interp, Tcl_NewIntObj(rc)); return SQLITE_OK; } @@ -164,7 +164,7 @@ static int SQLITE_TCLAPI autoExtBrokenObjCmd( int objc, Tcl_Obj *CONST objv[] ){ - int rc = sqlite3_auto_extension((void*)broken_init); + int rc = sqlite3_auto_extension(broken_init); Tcl_SetObjResult(interp, Tcl_NewIntObj(rc)); return SQLITE_OK; } @@ -180,7 +180,7 @@ static int SQLITE_TCLAPI cancelAutoExtBrokenObjCmd( int objc, Tcl_Obj *CONST objv[] ){ - int rc = sqlite3_cancel_auto_extension((void*)broken_init); + int rc = sqlite3_cancel_auto_extension(broken_init); Tcl_SetObjResult(interp, Tcl_NewIntObj(rc)); return SQLITE_OK; } diff --git a/src/test_func.c b/src/test_func.c index 6a714ef3eb..fff1990128 100644 --- a/src/test_func.c +++ b/src/test_func.c @@ -644,7 +644,11 @@ static void test_setsubtype( sqlite3_result_subtype(context, (unsigned int)sqlite3_value_int(argv[1])); } -static int registerTestFunctions(sqlite3 *db){ +static int registerTestFunctions( + sqlite3 *db, + char **pzErrMsg, + const void *pThunk +){ static const struct { char *zName; signed char nArg; @@ -699,10 +703,10 @@ static int SQLITE_TCLAPI autoinstall_test_funcs( int objc, Tcl_Obj *CONST objv[] ){ - extern int Md5_Register(sqlite3*); - int rc = sqlite3_auto_extension((void*)registerTestFunctions); + extern int Md5_Register(sqlite3 *, char **, const void *); + int rc = sqlite3_auto_extension(registerTestFunctions); if( rc==SQLITE_OK ){ - rc = sqlite3_auto_extension((void*)Md5_Register); + rc = sqlite3_auto_extension(Md5_Register); } Tcl_SetObjResult(interp, Tcl_NewIntObj(rc)); return TCL_OK; @@ -799,13 +803,13 @@ int Sqlitetest_func_Init(Tcl_Interp *interp){ { "abuse_create_function", abuse_create_function }, }; int i; - extern int Md5_Register(sqlite3*); + extern int Md5_Register(sqlite3 *, char **, const void *); for(i=0; i Date: Thu, 28 Jul 2016 22:38:31 +0000 Subject: [PATCH 0626/1484] Make sure all the auto-extension mechanism function signatures match up precisely. FossilOrigin-Name: 87ba69b5ca4a8e4ef2bbaaf07a0ff13fc5cd4721 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/loadext.c | 4 ++-- src/sqlite.h.in | 5 +++-- src/sqlite3ext.h | 5 +++-- 5 files changed, 17 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index 36d529bb7a..0fd8b5e7cf 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\sthe\sextension\sauto-loading\smechanism\swork\swith\sthe\s__stdcall\scalling\sconvention.\s\sAlso,\sfix\sa\scouple\sTcl\scommand\scalling\sconventions\smissed\sin\sthe\sprevious\scheck-in. -D 2016-07-28T22:23:26.522 +C Make\ssure\sall\sthe\sauto-extension\smechanism\sfunction\ssignatures\smatch\sup\sprecisely. +D 2016-07-28T22:38:31.788 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 3340e479e5221f06c3d61726f8f7efff885e4233 @@ -347,7 +347,7 @@ F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4 F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da F src/insert.c 8f4e9fcbd8e95e85f15647ba8b413b18d556ec2b F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e -F src/loadext.c 4e26039f8d2e91acd57e55fcc31477aa37a3aa80 +F src/loadext.c 74a66e96c9b6beafbbc345d9045727e2bd7fd483 F src/main.c 16c1b2114eae8804caf3a8de8cb47bf2c6d83ad3 F src/malloc.c 1443d1ad95d67c21d77af7ae3f44678252f0efec F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 @@ -385,9 +385,9 @@ F src/resolve.c cca3aa77b95706df5d635a2141a4d1de60ae6598 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c f3c6e9065fb34f6a23af27ec7f1f717ffbfc2ee4 F src/shell.c 9351fc6de11e1d908648c0a92d85627138e3dee5 -F src/sqlite.h.in 856ab22cfcec0ba94d2f0139a72a9797343687b3 +F src/sqlite.h.in acd078b5b18d7ceecd9f2bbffc30109a758a73b0 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 -F src/sqlite3ext.h 978c062d3fa59a22c6d57305b9f290e3a26110c3 +F src/sqlite3ext.h ebbcfcc6200d04f04b4e2252327b14c50cd9d49a F src/sqliteInt.h 14516943867eb2c30ce0e3670299958f59ade052 F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c 5b18f9526900f61189ab0b83f1ef41d9f871a2ab @@ -1508,7 +1508,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P cbe1de4799df4d512bc175f51ed99c6ec6d5a4d1 -R bda25e48e90849454c6e864127930d74 +P 3ea567c4b07b2a7a027b9b5cb8250ab687803698 +R 51ed71c50a5a0dd10fef4650340d6be2 U mistachkin -Z 008c4b78efecf8010a475c91e6246b39 +Z 81fd56db162c30680657ddae99c1b31b diff --git a/manifest.uuid b/manifest.uuid index 0a08bdb4e1..428fb337c6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3ea567c4b07b2a7a027b9b5cb8250ab687803698 \ No newline at end of file +87ba69b5ca4a8e4ef2bbaaf07a0ff13fc5cd4721 \ No newline at end of file diff --git a/src/loadext.c b/src/loadext.c index 525272d7fe..c3d91eed33 100644 --- a/src/loadext.c +++ b/src/loadext.c @@ -676,7 +676,7 @@ static SQLITE_WSD struct sqlite3AutoExtList { ** loaded by every new database connection. */ int sqlite3_auto_extension( - void (*xInit)(sqlite3 *, char **, const void *) /* Extension entry point */ + void (*xInit)(sqlite3 *, char **, const sqlite3_api_routines *) ){ int rc = SQLITE_OK; #ifndef SQLITE_OMIT_AUTOINIT @@ -723,7 +723,7 @@ int sqlite3_auto_extension( ** was not on the list. */ int sqlite3_cancel_auto_extension( - void (*xInit)(sqlite3 *, char **, const void *) /* Extension entry point */ + void (*xInit)(sqlite3 *, char **, const sqlite3_api_routines *) ){ #if SQLITE_THREADSAFE sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 104e465467..9fec987d8c 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -5707,8 +5707,9 @@ int sqlite3_enable_load_extension(sqlite3 *db, int onoff); ** See also: [sqlite3_reset_auto_extension()] ** and [sqlite3_cancel_auto_extension()] */ +typedef struct sqlite3_api_routines sqlite3_api_routines; int sqlite3_auto_extension( - void (*xEntryPoint)(sqlite3 *, char **, const void *) + void (*xEntryPoint)(sqlite3 *, char **, const sqlite3_api_routines *) ); /* @@ -5722,7 +5723,7 @@ int sqlite3_auto_extension( ** routines. */ int sqlite3_cancel_auto_extension( - void (*xEntryPoint)(sqlite3 *, char **, const void *) + void (*xEntryPoint)(sqlite3 *, char **, const sqlite3_api_routines *) ); /* diff --git a/src/sqlite3ext.h b/src/sqlite3ext.h index d79ca826de..8ee8e2d576 100644 --- a/src/sqlite3ext.h +++ b/src/sqlite3ext.h @@ -251,12 +251,13 @@ struct sqlite3_api_routines { char *(*vsnprintf)(int,char*,const char*,va_list); int (*wal_checkpoint_v2)(sqlite3*,const char*,int,int*,int*); /* Version 3.8.7 and later */ - int (*auto_extension)(void(*)(sqlite3*,char**,const void*)); + int (*auto_extension)(void(*)(sqlite3*,char**,const sqlite3_api_routines*)); int (*bind_blob64)(sqlite3_stmt*,int,const void*,sqlite3_uint64, void(*)(void*)); int (*bind_text64)(sqlite3_stmt*,int,const char*,sqlite3_uint64, void(*)(void*),unsigned char); - int (*cancel_auto_extension)(void(*)(sqlite3*,char**,const void*)); + int (*cancel_auto_extension)(void(*)(sqlite3*,char**, + const sqlite3_api_routines*)); int (*load_extension)(sqlite3*,const char*,const char*,char**); void *(*malloc64)(sqlite3_uint64); sqlite3_uint64 (*msize)(void*); From 78d5e02f99c1e555212da6e8699eead360cf314c Mon Sep 17 00:00:00 2001 From: mistachkin Date: Thu, 28 Jul 2016 22:46:53 +0000 Subject: [PATCH 0627/1484] The return type used by the auto-extension entry points is 'int', not 'void'. FossilOrigin-Name: bf9c86c74f30136a106f37603a6c7dcc76caf41d --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/loadext.c | 4 ++-- src/sqlite.h.in | 4 ++-- src/sqlite3ext.h | 4 ++-- 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index 0fd8b5e7cf..17a1dd2ca9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\ssure\sall\sthe\sauto-extension\smechanism\sfunction\ssignatures\smatch\sup\sprecisely. -D 2016-07-28T22:38:31.788 +C The\sreturn\stype\sused\sby\sthe\sauto-extension\sentry\spoints\sis\s'int',\snot\s'void'. +D 2016-07-28T22:46:53.241 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 3340e479e5221f06c3d61726f8f7efff885e4233 @@ -347,7 +347,7 @@ F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4 F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da F src/insert.c 8f4e9fcbd8e95e85f15647ba8b413b18d556ec2b F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e -F src/loadext.c 74a66e96c9b6beafbbc345d9045727e2bd7fd483 +F src/loadext.c c3c2a37e4ce940d17c73971738754d412c79e09d F src/main.c 16c1b2114eae8804caf3a8de8cb47bf2c6d83ad3 F src/malloc.c 1443d1ad95d67c21d77af7ae3f44678252f0efec F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 @@ -385,9 +385,9 @@ F src/resolve.c cca3aa77b95706df5d635a2141a4d1de60ae6598 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c f3c6e9065fb34f6a23af27ec7f1f717ffbfc2ee4 F src/shell.c 9351fc6de11e1d908648c0a92d85627138e3dee5 -F src/sqlite.h.in acd078b5b18d7ceecd9f2bbffc30109a758a73b0 +F src/sqlite.h.in cd10e4206b91c4bf03f121ab9209a14af0b48f14 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 -F src/sqlite3ext.h ebbcfcc6200d04f04b4e2252327b14c50cd9d49a +F src/sqlite3ext.h f4206565eb5f5cef9a1544d32a076b5f47af1bdc F src/sqliteInt.h 14516943867eb2c30ce0e3670299958f59ade052 F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c 5b18f9526900f61189ab0b83f1ef41d9f871a2ab @@ -1508,7 +1508,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 3ea567c4b07b2a7a027b9b5cb8250ab687803698 -R 51ed71c50a5a0dd10fef4650340d6be2 +P 87ba69b5ca4a8e4ef2bbaaf07a0ff13fc5cd4721 +R fe55b3414e54e3c3fe825e99e626bb4c U mistachkin -Z 81fd56db162c30680657ddae99c1b31b +Z 6282b6a783a4676d4515222e105ea01c diff --git a/manifest.uuid b/manifest.uuid index 428fb337c6..b5a2549c02 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -87ba69b5ca4a8e4ef2bbaaf07a0ff13fc5cd4721 \ No newline at end of file +bf9c86c74f30136a106f37603a6c7dcc76caf41d \ No newline at end of file diff --git a/src/loadext.c b/src/loadext.c index c3d91eed33..163141bf73 100644 --- a/src/loadext.c +++ b/src/loadext.c @@ -676,7 +676,7 @@ static SQLITE_WSD struct sqlite3AutoExtList { ** loaded by every new database connection. */ int sqlite3_auto_extension( - void (*xInit)(sqlite3 *, char **, const sqlite3_api_routines *) + int (*xInit)(sqlite3 *, char **, const sqlite3_api_routines *) ){ int rc = SQLITE_OK; #ifndef SQLITE_OMIT_AUTOINIT @@ -723,7 +723,7 @@ int sqlite3_auto_extension( ** was not on the list. */ int sqlite3_cancel_auto_extension( - void (*xInit)(sqlite3 *, char **, const sqlite3_api_routines *) + int (*xInit)(sqlite3 *, char **, const sqlite3_api_routines *) ){ #if SQLITE_THREADSAFE sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 9fec987d8c..9d28cdc05a 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -5709,7 +5709,7 @@ int sqlite3_enable_load_extension(sqlite3 *db, int onoff); */ typedef struct sqlite3_api_routines sqlite3_api_routines; int sqlite3_auto_extension( - void (*xEntryPoint)(sqlite3 *, char **, const sqlite3_api_routines *) + int (*xEntryPoint)(sqlite3 *, char **, const sqlite3_api_routines *) ); /* @@ -5723,7 +5723,7 @@ int sqlite3_auto_extension( ** routines. */ int sqlite3_cancel_auto_extension( - void (*xEntryPoint)(sqlite3 *, char **, const sqlite3_api_routines *) + int (*xEntryPoint)(sqlite3 *, char **, const sqlite3_api_routines *) ); /* diff --git a/src/sqlite3ext.h b/src/sqlite3ext.h index 8ee8e2d576..689a5c4856 100644 --- a/src/sqlite3ext.h +++ b/src/sqlite3ext.h @@ -251,12 +251,12 @@ struct sqlite3_api_routines { char *(*vsnprintf)(int,char*,const char*,va_list); int (*wal_checkpoint_v2)(sqlite3*,const char*,int,int*,int*); /* Version 3.8.7 and later */ - int (*auto_extension)(void(*)(sqlite3*,char**,const sqlite3_api_routines*)); + int (*auto_extension)(int(*)(sqlite3*,char**,const sqlite3_api_routines*)); int (*bind_blob64)(sqlite3_stmt*,int,const void*,sqlite3_uint64, void(*)(void*)); int (*bind_text64)(sqlite3_stmt*,int,const char*,sqlite3_uint64, void(*)(void*),unsigned char); - int (*cancel_auto_extension)(void(*)(sqlite3*,char**, + int (*cancel_auto_extension)(int(*)(sqlite3*,char**, const sqlite3_api_routines*)); int (*load_extension)(sqlite3*,const char*,const char*,char**); void *(*malloc64)(sqlite3_uint64); From 85bd982ba02750aa927c2b80e5d7f888d58fb2fb Mon Sep 17 00:00:00 2001 From: mistachkin Date: Thu, 28 Jul 2016 22:53:10 +0000 Subject: [PATCH 0628/1484] More compiler warning fixes for GCC related to the auto-extension mechanism. FossilOrigin-Name: b8218129bc848c61fa6910feae4141dac6ad86fc --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/tclsqlite.c | 2 +- src/test_func.c | 6 +++--- src/test_thread.c | 2 +- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index 17a1dd2ca9..07a36a9f51 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C The\sreturn\stype\sused\sby\sthe\sauto-extension\sentry\spoints\sis\s'int',\snot\s'void'. -D 2016-07-28T22:46:53.241 +C More\scompiler\swarning\sfixes\sfor\sGCC\srelated\sto\sthe\sauto-extension\smechanism. +D 2016-07-28T22:53:10.716 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 3340e479e5221f06c3d61726f8f7efff885e4233 @@ -392,7 +392,7 @@ F src/sqliteInt.h 14516943867eb2c30ce0e3670299958f59ade052 F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c 5b18f9526900f61189ab0b83f1ef41d9f871a2ab F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 -F src/tclsqlite.c 2ca362fa9c9762f705169aa5b2e75d688f4391f7 +F src/tclsqlite.c bdae822f21e229b6daced15938b6343ce44ef454 F src/test1.c 906a04b649c7139e943193a3905d583e325c30c7 F src/test2.c b7174313e993754303a8b33c43df7c44b46857ab F src/test3.c 1339a40be39650ae83894b6578f971dc7f96ea8a @@ -412,7 +412,7 @@ F src/test_config.c 4d3d4a886416f369771d69a6dba926866deda788 F src/test_demovfs.c a0c3bdd45ed044115c2c9f7779e56eafff18741e F src/test_devsym.c 4e58dec2602d8e139ca08659f62a62450587cb58 F src/test_fs.c ac62ce7d5c0c23aa6932891cad5746945564c91c -F src/test_func.c 7dceef0e0556933a751af9b73478519b6dc12f0f +F src/test_func.c 6f34b19ae097e3cf0b0fe5d6904cb9900e67f2ff F src/test_hexio.c 1d4469ca61ab202a1fcec6543f584d2407205e8d F src/test_init.c 4413c211a94b62157ca4c145b3f27c497f03c664 F src/test_intarray.c 988fc61cb0ff539f4172c0d95f15287c92516f64 @@ -435,7 +435,7 @@ F src/test_sqllog.c 0d138a8180a312bf996b37fa66da5c5799d4d57b F src/test_superlock.c 4839644b9201da822f181c5bc406c0b2385f672e F src/test_syscall.c 1073306ba2e9bfc886771871a13d3de281ed3939 F src/test_tclvar.c df9fe1213c2634687a9ca0b0bec0d2119d359ae3 -F src/test_thread.c a122592c2b857c79eb4ee4bacb62a5a6c8fe4c6f +F src/test_thread.c 89f0e47dac64e7ab15ca0a4fc87e0882c495ae21 F src/test_vfs.c f0186261a24de2671d080bcd8050732f0cb64f6e F src/test_vfstrace.c bab9594adc976cbe696ff3970728830b4c5ed698 F src/test_windirent.c 8f5fada630348558d5745b334702f301da1ffc61 @@ -1508,7 +1508,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 87ba69b5ca4a8e4ef2bbaaf07a0ff13fc5cd4721 -R fe55b3414e54e3c3fe825e99e626bb4c +P bf9c86c74f30136a106f37603a6c7dcc76caf41d +R 664c66de93f8212f17433a2724631f1d U mistachkin -Z 6282b6a783a4676d4515222e105ea01c +Z 34c982f036e48065c3f321d45916961b diff --git a/manifest.uuid b/manifest.uuid index b5a2549c02..2806d535ae 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bf9c86c74f30136a106f37603a6c7dcc76caf41d \ No newline at end of file +b8218129bc848c61fa6910feae4141dac6ad86fc \ No newline at end of file diff --git a/src/tclsqlite.c b/src/tclsqlite.c index dd4e42e8a9..3db4a32c4d 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -3923,7 +3923,7 @@ static void md5finalize(sqlite3_context *context){ int Md5_Register( sqlite3 *db, char **pzErrMsg, - const void *pThunk + const sqlite3_api_routines *pThunk ){ int rc = sqlite3_create_function(db, "md5sum", -1, SQLITE_UTF8, 0, 0, md5step, md5finalize); diff --git a/src/test_func.c b/src/test_func.c index fff1990128..6bfa862464 100644 --- a/src/test_func.c +++ b/src/test_func.c @@ -647,7 +647,7 @@ static void test_setsubtype( static int registerTestFunctions( sqlite3 *db, char **pzErrMsg, - const void *pThunk + const sqlite3_api_routines *pThunk ){ static const struct { char *zName; @@ -703,7 +703,7 @@ static int SQLITE_TCLAPI autoinstall_test_funcs( int objc, Tcl_Obj *CONST objv[] ){ - extern int Md5_Register(sqlite3 *, char **, const void *); + extern int Md5_Register(sqlite3 *, char **, const sqlite3_api_routines *); int rc = sqlite3_auto_extension(registerTestFunctions); if( rc==SQLITE_OK ){ rc = sqlite3_auto_extension(Md5_Register); @@ -803,7 +803,7 @@ int Sqlitetest_func_Init(Tcl_Interp *interp){ { "abuse_create_function", abuse_create_function }, }; int i; - extern int Md5_Register(sqlite3 *, char **, const void *); + extern int Md5_Register(sqlite3 *, char **, const sqlite3_api_routines *); for(i=0; i Date: Thu, 28 Jul 2016 23:54:45 +0000 Subject: [PATCH 0629/1484] Use the SQLITE_TCLAPI macro in several extensions that were missed in the previous check-in. FossilOrigin-Name: df2543652b835353c03956dfbd3e35e5b191372e --- ext/fts5/fts5_tcl.c | 20 ++++++++++---------- ext/rbu/test_rbu.c | 12 ++++++------ ext/session/test_session.c | 14 +++++++------- manifest | 16 ++++++++-------- manifest.uuid | 2 +- 5 files changed, 32 insertions(+), 32 deletions(-) diff --git a/ext/fts5/fts5_tcl.c b/ext/fts5/fts5_tcl.c index dee9bc7f18..9a7077b61d 100644 --- a/ext/fts5/fts5_tcl.c +++ b/ext/fts5/fts5_tcl.c @@ -82,7 +82,7 @@ static int f5tResultToErrorCode(const char *zRes){ return SQLITE_ERROR; } -static int f5tDbAndApi( +static int SQLITE_TCLAPI f5tDbAndApi( Tcl_Interp *interp, Tcl_Obj *pObj, sqlite3 **ppDb, @@ -213,7 +213,7 @@ static void xSetAuxdataDestructor(void *p){ ** ** Description... */ -static int xF5tApi( +static int SQLITE_TCLAPI xF5tApi( void * clientData, Tcl_Interp *interp, int objc, @@ -606,7 +606,7 @@ static void xF5tDestroy(void *pCtx){ ** ** Description... */ -static int f5tCreateFunction( +static int SQLITE_TCLAPI f5tCreateFunction( void * clientData, Tcl_Interp *interp, int objc, @@ -676,7 +676,7 @@ static int xTokenizeCb2( ** ** Description... */ -static int f5tTokenize( +static int SQLITE_TCLAPI f5tTokenize( void * clientData, Tcl_Interp *interp, int objc, @@ -882,7 +882,7 @@ static int f5tTokenizerTokenize( /* ** sqlite3_fts5_token ?-colocated? TEXT START END */ -static int f5tTokenizerReturn( +static int SQLITE_TCLAPI f5tTokenizerReturn( void * clientData, Tcl_Interp *interp, int objc, @@ -953,7 +953,7 @@ static void f5tDelTokenizer(void *pCtx){ ** SCRIPT2 should invoke the [sqlite3_fts5_token] command once for each ** token within the tokenized text. */ -static int f5tCreateTokenizer( +static int SQLITE_TCLAPI f5tCreateTokenizer( ClientData clientData, Tcl_Interp *interp, int objc, @@ -1005,7 +1005,7 @@ static void xF5tFree(ClientData clientData){ ** ** Set or clear the global "may-be-corrupt" flag. Return the old value. */ -static int f5tMayBeCorrupt( +static int SQLITE_TCLAPI f5tMayBeCorrupt( void * clientData, Tcl_Interp *interp, int objc, @@ -1037,7 +1037,7 @@ static unsigned int f5t_fts5HashKey(int nSlot, const char *p, int n){ return (h % nSlot); } -static int f5tTokenHash( +static int SQLITE_TCLAPI f5tTokenHash( void * clientData, Tcl_Interp *interp, int objc, @@ -1062,7 +1062,7 @@ static int f5tTokenHash( return TCL_OK; } -static int f5tRegisterMatchinfo( +static int SQLITE_TCLAPI f5tRegisterMatchinfo( void * clientData, Tcl_Interp *interp, int objc, @@ -1087,7 +1087,7 @@ static int f5tRegisterMatchinfo( return TCL_OK; } -static int f5tRegisterTok( +static int SQLITE_TCLAPI f5tRegisterTok( void * clientData, Tcl_Interp *interp, int objc, diff --git a/ext/rbu/test_rbu.c b/ext/rbu/test_rbu.c index 671f16c553..548954d7f1 100644 --- a/ext/rbu/test_rbu.c +++ b/ext/rbu/test_rbu.c @@ -53,7 +53,7 @@ void test_rbu_delta(sqlite3_context *pCtx, int nArg, sqlite3_value **apVal){ } -static int test_sqlite3rbu_cmd( +static int SQLITE_TCLAPI test_sqlite3rbu_cmd( ClientData clientData, Tcl_Interp *interp, int objc, @@ -196,7 +196,7 @@ static int test_sqlite3rbu_cmd( /* ** Tclcmd: sqlite3rbu CMD ?? */ -static int test_sqlite3rbu( +static int SQLITE_TCLAPI test_sqlite3rbu( ClientData clientData, Tcl_Interp *interp, int objc, @@ -226,7 +226,7 @@ static int test_sqlite3rbu( /* ** Tclcmd: sqlite3rbu_vacuum CMD */ -static int test_sqlite3rbu_vacuum( +static int SQLITE_TCLAPI test_sqlite3rbu_vacuum( ClientData clientData, Tcl_Interp *interp, int objc, @@ -254,7 +254,7 @@ static int test_sqlite3rbu_vacuum( /* ** Tclcmd: sqlite3rbu_create_vfs ?-default? NAME PARENT */ -static int test_sqlite3rbu_create_vfs( +static int SQLITE_TCLAPI test_sqlite3rbu_create_vfs( ClientData clientData, Tcl_Interp *interp, int objc, @@ -289,7 +289,7 @@ static int test_sqlite3rbu_create_vfs( /* ** Tclcmd: sqlite3rbu_destroy_vfs NAME */ -static int test_sqlite3rbu_destroy_vfs( +static int SQLITE_TCLAPI test_sqlite3rbu_destroy_vfs( ClientData clientData, Tcl_Interp *interp, int objc, @@ -310,7 +310,7 @@ static int test_sqlite3rbu_destroy_vfs( /* ** Tclcmd: sqlite3rbu_internal_test */ -static int test_sqlite3rbu_internal_test( +static int SQLITE_TCLAPI test_sqlite3rbu_internal_test( ClientData clientData, Tcl_Interp *interp, int objc, diff --git a/ext/session/test_session.c b/ext/session/test_session.c index 9f6bc3f70d..b273565455 100644 --- a/ext/session/test_session.c +++ b/ext/session/test_session.c @@ -111,7 +111,7 @@ static int testStreamOutput( ** $session patchset ** $session table_filter SCRIPT */ -static int test_session_cmd( +static int SQLITE_TCLAPI test_session_cmd( void *clientData, Tcl_Interp *interp, int objc, @@ -254,7 +254,7 @@ static void test_session_del(void *clientData){ /* ** Tclcmd: sqlite3session CMD DB-HANDLE DB-NAME */ -static int test_sqlite3session( +static int SQLITE_TCLAPI test_sqlite3session( void * clientData, Tcl_Interp *interp, int objc, @@ -610,7 +610,7 @@ static int testStreamInput( /* ** sqlite3changeset_apply DB CHANGESET CONFLICT-SCRIPT ?FILTER-SCRIPT? */ -static int test_sqlite3changeset_apply( +static int SQLITE_TCLAPI test_sqlite3changeset_apply( void * clientData, Tcl_Interp *interp, int objc, @@ -665,7 +665,7 @@ static int test_sqlite3changeset_apply( /* ** sqlite3changeset_apply_replace_all DB CHANGESET */ -static int test_sqlite3changeset_apply_replace_all( +static int SQLITE_TCLAPI test_sqlite3changeset_apply_replace_all( void * clientData, Tcl_Interp *interp, int objc, @@ -700,7 +700,7 @@ static int test_sqlite3changeset_apply_replace_all( /* ** sqlite3changeset_invert CHANGESET */ -static int test_sqlite3changeset_invert( +static int SQLITE_TCLAPI test_sqlite3changeset_invert( void * clientData, Tcl_Interp *interp, int objc, @@ -739,7 +739,7 @@ static int test_sqlite3changeset_invert( /* ** sqlite3changeset_concat LEFT RIGHT */ -static int test_sqlite3changeset_concat( +static int SQLITE_TCLAPI test_sqlite3changeset_concat( void * clientData, Tcl_Interp *interp, int objc, @@ -787,7 +787,7 @@ static int test_sqlite3changeset_concat( /* ** sqlite3session_foreach VARNAME CHANGESET SCRIPT */ -static int test_sqlite3session_foreach( +static int SQLITE_TCLAPI test_sqlite3session_foreach( void * clientData, Tcl_Interp *interp, int objc, diff --git a/manifest b/manifest index 07a36a9f51..4738abe8bf 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C More\scompiler\swarning\sfixes\sfor\sGCC\srelated\sto\sthe\sauto-extension\smechanism. -D 2016-07-28T22:53:10.716 +C Use\sthe\sSQLITE_TCLAPI\smacro\sin\sseveral\sextensions\sthat\swere\smissed\sin\sthe\sprevious\scheck-in. +D 2016-07-28T23:54:45.174 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 3340e479e5221f06c3d61726f8f7efff885e4233 @@ -107,7 +107,7 @@ F ext/fts5/fts5_hash.c 880998e596b60f078348d48732ca4ad9a90caad2 F ext/fts5/fts5_index.c b429e23fabb57506f71e406997cc46b89190dc97 F ext/fts5/fts5_main.c f85281445dcf8be32d18841c93a6f90fe27dbfe2 F ext/fts5/fts5_storage.c de0ed8a06738bde433afe11e92295ceaffbc4e58 -F ext/fts5/fts5_tcl.c b41f04600936a2b910b5dff179e8bd050ccb34c7 +F ext/fts5/fts5_tcl.c caede54ed5eade83e1f455356e6dd2b849e1c703 F ext/fts5/fts5_test_mi.c 783b86697ebf773c18fc109992426c0173a055bc F ext/fts5/fts5_test_tok.c db08af63673c3a7d39f053b36fd6e065017706be F ext/fts5/fts5_tokenize.c 2ce7b44183538ec46b7907726262ee43ffdd39a8 @@ -255,7 +255,7 @@ F ext/rbu/rbuvacuum.test 4a977447c15c2581ab668781d9ef4294382530e0 F ext/rbu/rbuvacuum2.test 45009e127c3fb385e5c0fd5a8a63fb922a79d0ab F ext/rbu/sqlite3rbu.c 948677ee0ec57da51148e6c5f64ac68afcf36ab2 F ext/rbu/sqlite3rbu.h db8858120c9be14b60c9225f9da28221f5f6b945 -F ext/rbu/test_rbu.c c2c1859dfd69f1a55125d38009d0d49e36895780 +F ext/rbu/test_rbu.c fc84cd6aae50cfd8b2b2d5e9cdfc85e1925c303c F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 F ext/rtree/rtree.c d26a815b0df1c412a6881dae8d7fd3c9c08cce68 F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e @@ -301,7 +301,7 @@ F ext/session/sessionfault.test da273f2712b6411e85e71465a1733b8501dbf6f7 F ext/session/sessionfault2.test 04aa0bc9aa70ea43d8de82c4f648db4de1e990b0 F ext/session/sqlite3session.c 37485891b4add26cf61495df193c419f36556a32 F ext/session/sqlite3session.h 69bf73cfd71e58f2ae5d2aa935b2c1a541aee555 -F ext/session/test_session.c ebf9acf2bd70885e6245512427f800693b65dc9c +F ext/session/test_session.c 5f9b1da42c5771fbe5948acd816ae9e8ae781353 F ext/userauth/sqlite3userauth.h 19cb6f0e31316d0ee4afdfb7a85ef9da3333a220 F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04 F ext/userauth/userauth.c 5fa3bdb492f481bbc1709fc83c91ebd13460c69e @@ -1508,7 +1508,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P bf9c86c74f30136a106f37603a6c7dcc76caf41d -R 664c66de93f8212f17433a2724631f1d +P b8218129bc848c61fa6910feae4141dac6ad86fc +R 66ac7539129e9f0d2a57c9cf5f4708c1 U mistachkin -Z 34c982f036e48065c3f321d45916961b +Z abcb763c1fb15cc18b4555018b76e16c diff --git a/manifest.uuid b/manifest.uuid index 2806d535ae..b5d59b835c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b8218129bc848c61fa6910feae4141dac6ad86fc \ No newline at end of file +df2543652b835353c03956dfbd3e35e5b191372e \ No newline at end of file From 2d45d7bfab45fc3488017f9573e2ccae423d5828 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Thu, 28 Jul 2016 23:58:25 +0000 Subject: [PATCH 0630/1484] Missed a couple Tcl command deletion callbacks. FossilOrigin-Name: fc5c187602acceedf7152b6927616d134f779a8f --- ext/fts5/fts5_tcl.c | 4 ++-- ext/session/test_session.c | 2 +- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/ext/fts5/fts5_tcl.c b/ext/fts5/fts5_tcl.c index 9a7077b61d..77e4a6cf35 100644 --- a/ext/fts5/fts5_tcl.c +++ b/ext/fts5/fts5_tcl.c @@ -168,7 +168,7 @@ static int xTokenizeCb( return rc; } -static int xF5tApi(void*, Tcl_Interp*, int, Tcl_Obj *CONST []); +static int SQLITE_TCLAPI xF5tApi(void*, Tcl_Interp*, int, Tcl_Obj *CONST []); static int xQueryPhraseCb( const Fts5ExtensionApi *pApi, @@ -996,7 +996,7 @@ static int SQLITE_TCLAPI f5tCreateTokenizer( return TCL_OK; } -static void xF5tFree(ClientData clientData){ +static void SQLITE_TCLAPI xF5tFree(ClientData clientData){ ckfree(clientData); } diff --git a/ext/session/test_session.c b/ext/session/test_session.c index b273565455..df34d84445 100644 --- a/ext/session/test_session.c +++ b/ext/session/test_session.c @@ -244,7 +244,7 @@ static int SQLITE_TCLAPI test_session_cmd( return TCL_OK; } -static void test_session_del(void *clientData){ +static void SQLITE_TCLAPI test_session_del(void *clientData){ TestSession *p = (TestSession*)clientData; if( p->pFilterScript ) Tcl_DecrRefCount(p->pFilterScript); sqlite3session_delete(p->pSession); diff --git a/manifest b/manifest index 4738abe8bf..74d5fa504c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Use\sthe\sSQLITE_TCLAPI\smacro\sin\sseveral\sextensions\sthat\swere\smissed\sin\sthe\sprevious\scheck-in. -D 2016-07-28T23:54:45.174 +C Missed\sa\scouple\sTcl\scommand\sdeletion\scallbacks. +D 2016-07-28T23:58:25.315 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 3340e479e5221f06c3d61726f8f7efff885e4233 @@ -107,7 +107,7 @@ F ext/fts5/fts5_hash.c 880998e596b60f078348d48732ca4ad9a90caad2 F ext/fts5/fts5_index.c b429e23fabb57506f71e406997cc46b89190dc97 F ext/fts5/fts5_main.c f85281445dcf8be32d18841c93a6f90fe27dbfe2 F ext/fts5/fts5_storage.c de0ed8a06738bde433afe11e92295ceaffbc4e58 -F ext/fts5/fts5_tcl.c caede54ed5eade83e1f455356e6dd2b849e1c703 +F ext/fts5/fts5_tcl.c 6805005886d6d9c83bb9b68bb69d32af4b37797e F ext/fts5/fts5_test_mi.c 783b86697ebf773c18fc109992426c0173a055bc F ext/fts5/fts5_test_tok.c db08af63673c3a7d39f053b36fd6e065017706be F ext/fts5/fts5_tokenize.c 2ce7b44183538ec46b7907726262ee43ffdd39a8 @@ -301,7 +301,7 @@ F ext/session/sessionfault.test da273f2712b6411e85e71465a1733b8501dbf6f7 F ext/session/sessionfault2.test 04aa0bc9aa70ea43d8de82c4f648db4de1e990b0 F ext/session/sqlite3session.c 37485891b4add26cf61495df193c419f36556a32 F ext/session/sqlite3session.h 69bf73cfd71e58f2ae5d2aa935b2c1a541aee555 -F ext/session/test_session.c 5f9b1da42c5771fbe5948acd816ae9e8ae781353 +F ext/session/test_session.c d0754c65952cc7c729efd63374e3d61fbd1ae94c F ext/userauth/sqlite3userauth.h 19cb6f0e31316d0ee4afdfb7a85ef9da3333a220 F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04 F ext/userauth/userauth.c 5fa3bdb492f481bbc1709fc83c91ebd13460c69e @@ -1508,7 +1508,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b8218129bc848c61fa6910feae4141dac6ad86fc -R 66ac7539129e9f0d2a57c9cf5f4708c1 +P df2543652b835353c03956dfbd3e35e5b191372e +R 4f030271e7adab35739e0e6bab6a4279 U mistachkin -Z abcb763c1fb15cc18b4555018b76e16c +Z 7e68b7e2d6cc6fdfea65df6524031184 diff --git a/manifest.uuid b/manifest.uuid index b5d59b835c..ff4fc72f71 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -df2543652b835353c03956dfbd3e35e5b191372e \ No newline at end of file +fc5c187602acceedf7152b6927616d134f779a8f \ No newline at end of file From c08556844e97b3b1c3ee19eca99e6cc98ff537ac Mon Sep 17 00:00:00 2001 From: mistachkin Date: Fri, 29 Jul 2016 01:31:49 +0000 Subject: [PATCH 0631/1484] Add macro necessary for building several extensions when the __stdcall calling convention is not in use. FossilOrigin-Name: bc8c9b55ddf5227dc6b2116486f4a19bf54fce2b --- ext/fts5/fts5_tcl.c | 3 +++ ext/rbu/test_rbu.c | 3 +++ ext/session/test_session.c | 3 +++ manifest | 16 ++++++++-------- manifest.uuid | 2 +- 5 files changed, 18 insertions(+), 9 deletions(-) diff --git a/ext/fts5/fts5_tcl.c b/ext/fts5/fts5_tcl.c index 77e4a6cf35..5fe690f6b7 100644 --- a/ext/fts5/fts5_tcl.c +++ b/ext/fts5/fts5_tcl.c @@ -18,6 +18,9 @@ # include "sqlite_tcl.h" #else # include "tcl.h" +# ifndef SQLITE_TCLAPI +# define SQLITE_TCLAPI +# endif #endif #ifdef SQLITE_ENABLE_FTS5 diff --git a/ext/rbu/test_rbu.c b/ext/rbu/test_rbu.c index 548954d7f1..bc4c800331 100644 --- a/ext/rbu/test_rbu.c +++ b/ext/rbu/test_rbu.c @@ -21,6 +21,9 @@ # include "sqlite_tcl.h" #else # include "tcl.h" +# ifndef SQLITE_TCLAPI +# define SQLITE_TCLAPI +# endif #endif #include diff --git a/ext/session/test_session.c b/ext/session/test_session.c index df34d84445..103a1c2d7a 100644 --- a/ext/session/test_session.c +++ b/ext/session/test_session.c @@ -9,6 +9,9 @@ # include "sqlite_tcl.h" #else # include "tcl.h" +# ifndef SQLITE_TCLAPI +# define SQLITE_TCLAPI +# endif #endif typedef struct TestSession TestSession; diff --git a/manifest b/manifest index 74d5fa504c..3a567d4deb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Missed\sa\scouple\sTcl\scommand\sdeletion\scallbacks. -D 2016-07-28T23:58:25.315 +C Add\smacro\snecessary\sfor\sbuilding\sseveral\sextensions\swhen\sthe\s__stdcall\scalling\sconvention\sis\snot\sin\suse. +D 2016-07-29T01:31:49.222 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 3340e479e5221f06c3d61726f8f7efff885e4233 @@ -107,7 +107,7 @@ F ext/fts5/fts5_hash.c 880998e596b60f078348d48732ca4ad9a90caad2 F ext/fts5/fts5_index.c b429e23fabb57506f71e406997cc46b89190dc97 F ext/fts5/fts5_main.c f85281445dcf8be32d18841c93a6f90fe27dbfe2 F ext/fts5/fts5_storage.c de0ed8a06738bde433afe11e92295ceaffbc4e58 -F ext/fts5/fts5_tcl.c 6805005886d6d9c83bb9b68bb69d32af4b37797e +F ext/fts5/fts5_tcl.c 4a901f00c8553740dba63511603f5527d741c26a F ext/fts5/fts5_test_mi.c 783b86697ebf773c18fc109992426c0173a055bc F ext/fts5/fts5_test_tok.c db08af63673c3a7d39f053b36fd6e065017706be F ext/fts5/fts5_tokenize.c 2ce7b44183538ec46b7907726262ee43ffdd39a8 @@ -255,7 +255,7 @@ F ext/rbu/rbuvacuum.test 4a977447c15c2581ab668781d9ef4294382530e0 F ext/rbu/rbuvacuum2.test 45009e127c3fb385e5c0fd5a8a63fb922a79d0ab F ext/rbu/sqlite3rbu.c 948677ee0ec57da51148e6c5f64ac68afcf36ab2 F ext/rbu/sqlite3rbu.h db8858120c9be14b60c9225f9da28221f5f6b945 -F ext/rbu/test_rbu.c fc84cd6aae50cfd8b2b2d5e9cdfc85e1925c303c +F ext/rbu/test_rbu.c 1a6bbc6982e32485a48df111d0bb1934d537eabd F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 F ext/rtree/rtree.c d26a815b0df1c412a6881dae8d7fd3c9c08cce68 F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e @@ -301,7 +301,7 @@ F ext/session/sessionfault.test da273f2712b6411e85e71465a1733b8501dbf6f7 F ext/session/sessionfault2.test 04aa0bc9aa70ea43d8de82c4f648db4de1e990b0 F ext/session/sqlite3session.c 37485891b4add26cf61495df193c419f36556a32 F ext/session/sqlite3session.h 69bf73cfd71e58f2ae5d2aa935b2c1a541aee555 -F ext/session/test_session.c d0754c65952cc7c729efd63374e3d61fbd1ae94c +F ext/session/test_session.c 2caed9a659586428c63ca46e4900347b374487d4 F ext/userauth/sqlite3userauth.h 19cb6f0e31316d0ee4afdfb7a85ef9da3333a220 F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04 F ext/userauth/userauth.c 5fa3bdb492f481bbc1709fc83c91ebd13460c69e @@ -1508,7 +1508,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P df2543652b835353c03956dfbd3e35e5b191372e -R 4f030271e7adab35739e0e6bab6a4279 +P fc5c187602acceedf7152b6927616d134f779a8f +R d16dc76cf59643dacfea9f5d3d7324b6 U mistachkin -Z 7e68b7e2d6cc6fdfea65df6524031184 +Z 029d2b66c80fad0a70d5e0c29c8d9e88 diff --git a/manifest.uuid b/manifest.uuid index ff4fc72f71..3703d2538c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fc5c187602acceedf7152b6927616d134f779a8f \ No newline at end of file +bc8c9b55ddf5227dc6b2116486f4a19bf54fce2b \ No newline at end of file From 99bbcc8287832d65fc954f29c5c340e1226292d5 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 29 Jul 2016 01:32:36 +0000 Subject: [PATCH 0632/1484] Undo some unhelpful changes to skip-scan scoring that were added by the check-in [9e2b2681] that improved scoring of index scan. FossilOrigin-Name: c7d51934a4f30d096bb79fc509fc9dd0df5d89a4 --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/where.c | 4 ++-- test/scanstatus.test | 4 ++-- test/skipscan1.test | 16 ++++++++-------- 5 files changed, 22 insertions(+), 22 deletions(-) diff --git a/manifest b/manifest index 4df76977b0..fdc9dbc32a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C The\s'sqlite3ext.h'\scontent\sshould\sbe\sprocessed\sbefore\sbeing\sincluded\sin\sthe\samalgamation. -D 2016-07-28T19:28:35.475 +C Undo\ssome\sunhelpful\schanges\sto\sskip-scan\sscoring\sthat\swere\sadded\nby\sthe\scheck-in\s[9e2b2681]\sthat\simproved\sscoring\sof\sindex\sscan. +D 2016-07-29T01:32:36.387 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc eefec7a26bf73bb04f2241058e23a3ec8a43f656 @@ -463,7 +463,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 02eeecc265f6ffd0597378f5d8ae9070b62a406a F src/wal.h 6dd221ed384afdc204bc61e25c23ef7fd5a511f2 F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354 -F src/where.c 8ccc01f9227d41bfaf09360f108583be4a36d3b1 +F src/where.c fcaa38d19c2a7bb450cc57810bdc3d4eb36e00b0 F src/whereInt.h e5b939701a7ceffc5a3a8188a37f9746416ebcd0 F src/wherecode.c 99707d11907c71d289ee9553d2d1a22f1fd8ba41 F src/whereexpr.c d7dcbf14ce1b5876c1f76496162c30fcba669563 @@ -1027,7 +1027,7 @@ F test/savepoint5.test 0735db177e0ebbaedc39812c8d065075d563c4fd F test/savepoint6.test f41279c5e137139fa5c21485773332c7adb98cd7 F test/savepoint7.test cde525ea3075283eb950cdcdefe23ead4f700daa F test/savepointfault.test f044eac64b59f09746c7020ee261734de82bf9b2 -F test/scanstatus.test 030acbbdcea6a3fc676fee99edc84f6f16c0cf92 +F test/scanstatus.test 5253c219e331318a437f436268e0e82345700285 F test/schema.test 8f7999be894260f151adf15c2c7540f1c6d6a481 F test/schema2.test 906408621ea881fdb496d878b1822572a34e32c5 F test/schema3.test 1bc1008e1f8cb5654b248c55f27249366eb7ed38 @@ -1074,7 +1074,7 @@ F test/shortread1.test bb591ef20f0fd9ed26d0d12e80eee6d7ac8897a3 F test/show_speedtest1_rtree.tcl 32e6c5f073d7426148a6936a0408f4b5b169aba5 F test/shrink.test 1b4330b1fd9e818c04726d45cb28db73087535ce F test/sidedelete.test f0ad71abe6233e3b153100f3b8d679b19a488329 -F test/skipscan1.test d37a75b4be4eb9dedeb69b4f38b1d0a74b5021d7 +F test/skipscan1.test f2d4482f195f018c3732374d3985fc34bcc3ae1a F test/skipscan2.test d1d1450952b7275f0b0a3a981f0230532743951a F test/skipscan3.test ec5bab3f81c7038b43450e7b3062e04a198bdbb5 F test/skipscan5.test 67817a4b6857c47e0e33ba3e506da6f23ef68de2 @@ -1508,7 +1508,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P fd784887e125bf95f4799ad09cbcba6795173487 -R 159053f8c66afb3fed693021893388d2 -U mistachkin -Z 1fc3620b6fdad23d7ecfea7d673497bf +P cbe1de4799df4d512bc175f51ed99c6ec6d5a4d1 +R 69cbd4ac65697876502fdf627dd430d9 +U drh +Z b3c6b81889b1e6498dbf215474f399c6 diff --git a/manifest.uuid b/manifest.uuid index ad3e416aac..e200b2ca41 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cbe1de4799df4d512bc175f51ed99c6ec6d5a4d1 \ No newline at end of file +c7d51934a4f30d096bb79fc509fc9dd0df5d89a4 \ No newline at end of file diff --git a/src/where.c b/src/where.c index ca406a8172..da41c142fa 100644 --- a/src/where.c +++ b/src/where.c @@ -2478,11 +2478,11 @@ static int whereLoopAddBtreeIndex( pNew->nSkip++; pNew->aLTerm[pNew->nLTerm++] = 0; pNew->wsFlags |= WHERE_SKIPSCAN; - nIter = pProbe->aiRowLogEst[saved_nEq]+1 - pProbe->aiRowLogEst[saved_nEq+1]; + nIter = pProbe->aiRowLogEst[saved_nEq] - pProbe->aiRowLogEst[saved_nEq+1]; pNew->nOut -= nIter; /* TUNING: Because uncertainties in the estimates for skip-scan queries, ** add a 1.375 fudge factor to make skip-scan slightly less likely. */ - nIter += 4; + nIter += 5; whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nIter + nInMul); pNew->nOut = saved_nOut; pNew->u.btree.nEq = saved_nEq; diff --git a/test/scanstatus.test b/test/scanstatus.test index 48365a8794..ed24d97437 100644 --- a/test/scanstatus.test +++ b/test/scanstatus.test @@ -333,7 +333,7 @@ do_execsql_test 5.3.2 { SELECT count(*) FROM t2 WHERE y = 'j'; } {19} do_scanstatus_test 5.3.3 { - nLoop 1 nVisit 19 nEst 52.0 zName t2xy zExplain + nLoop 1 nVisit 19 nEst 56.0 zName t2xy zExplain {SEARCH TABLE t2 USING COVERING INDEX t2xy (ANY(x) AND y=?)} } @@ -349,7 +349,7 @@ do_execsql_test 5.4.2 { do_scanstatus_test 5.4.3 { nLoop 1 nVisit 10 nEst 10.0 zName t1bc zExplain {SCAN TABLE t1 USING COVERING INDEX t1bc} - nLoop 10 nVisit 200 nEst 52.0 zName t2xy + nLoop 10 nVisit 200 nEst 56.0 zName t2xy zExplain {SEARCH TABLE t2 USING COVERING INDEX t2xy (ANY(x) AND y=?)} } diff --git a/test/skipscan1.test b/test/skipscan1.test index ac26711603..6d77e63498 100644 --- a/test/skipscan1.test +++ b/test/skipscan1.test @@ -43,23 +43,23 @@ do_execsql_test skipscan1-1.2 { } {abc 345 7 8 | def 345 9 10 |} do_execsql_test skipscan1-1.2eqp { EXPLAIN QUERY PLAN - SELECT a,b,c,d,'|' FROM t1 WHERE b=345 ORDER BY a; + SELECT a,b,c,d,'|' FROM t1 WHERE d<>99 AND b=345 ORDER BY a; } {/* USING INDEX t1abc (ANY(a) AND b=?)*/} do_execsql_test skipscan1-1.2sort { EXPLAIN QUERY PLAN - SELECT a,b,c,d,'|' FROM t1 WHERE b=345 ORDER BY a; + SELECT a,b,c,d,'|' FROM t1 WHERE d<>99 AND b=345 ORDER BY a; } {~/*ORDER BY*/} do_execsql_test skipscan1-1.3 { - SELECT a,b,c,d,'|' FROM t1 WHERE b=345 ORDER BY a DESC; + SELECT a,b,c,d,'|' FROM t1 WHERE d<>99 AND b=345 ORDER BY a DESC; } {def 345 9 10 | abc 345 7 8 |} do_execsql_test skipscan1-1.3eqp { EXPLAIN QUERY PLAN - SELECT a,b,c,d,'|' FROM t1 WHERE b=345 ORDER BY a; + SELECT a,b,c,d,'|' FROM t1 WHERE d<>99 AND b=345 ORDER BY a DESC; } {/* USING INDEX t1abc (ANY(a) AND b=?)*/} do_execsql_test skipscan1-1.3sort { EXPLAIN QUERY PLAN - SELECT a,b,c,d,'|' FROM t1 WHERE b=345 ORDER BY a; + SELECT a,b,c,d,'|' FROM t1 WHERE d<>99 AND b=345 ORDER BY a DESC; } {~/*ORDER BY*/} do_execsql_test skipscan1-1.4 { @@ -150,15 +150,15 @@ do_execsql_test skipscan1-2.1 { } {} do_execsql_test skipscan1-2.2 { - SELECT a,b,c,d,'|' FROM t2 WHERE b=345 ORDER BY a; + SELECT a,b,c,d,'|' FROM t2 WHERE d<>99 AND b=345 ORDER BY a; } {abc 345 7 8 | def 345 9 10 |} do_execsql_test skipscan1-2.2eqp { EXPLAIN QUERY PLAN - SELECT a,b,c,d,'|' FROM t2 WHERE b=345 ORDER BY a; + SELECT a,b,c,d,'|' FROM t2 WHERE d<>99 AND b=345 ORDER BY a; } {/* USING INDEX sqlite_autoindex_t2_1 (ANY(a) AND b=?)*/} do_execsql_test skipscan1-2.2sort { EXPLAIN QUERY PLAN - SELECT a,b,c,d,'|' FROM t2 WHERE b=345 ORDER BY a; + SELECT a,b,c,d,'|' FROM t2 WHERE d<>99 AND b=345 ORDER BY a; } {~/*ORDER BY*/} From fefe82876c71bb9433a2474236916d95997ec2e3 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Fri, 29 Jul 2016 01:46:57 +0000 Subject: [PATCH 0633/1484] Update the autoconf makefile for MSVC. FossilOrigin-Name: 2daf20980d4cb9ed36372778ae1f3e595e503549 --- autoconf/Makefile.msc | 11 +++++++++++ manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/autoconf/Makefile.msc b/autoconf/Makefile.msc index 2f7447383f..d3bbc6b4d2 100644 --- a/autoconf/Makefile.msc +++ b/autoconf/Makefile.msc @@ -24,6 +24,13 @@ TOP = . USE_FULLWARN = 0 !ENDIF +# Set this non-0 to enable full runtime error checks (-RTC1, etc). This +# has no effect if (any) optimizations are enabled. +# +!IFNDEF USE_RUNTIME_CHECKS +USE_RUNTIME_CHECKS = 0 +!ENDIF + # Set this non-0 to use "stdcall" calling convention for the core library # and shell executable. # @@ -740,6 +747,10 @@ RCC = $(RCC) -D_DEBUG !IF $(DEBUG)>1 || $(OPTIMIZATIONS)==0 TCC = $(TCC) -Od BCC = $(BCC) -Od +!IF $(USE_RUNTIME_CHECKS)!=0 +TCC = $(TCC) -RTC1 +BCC = $(BCC) -RTC1 +!ENDIF !ELSEIF $(OPTIMIZATIONS)>=3 TCC = $(TCC) -Ox BCC = $(BCC) -Ox diff --git a/manifest b/manifest index 3a567d4deb..02ee3f6e46 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\smacro\snecessary\sfor\sbuilding\sseveral\sextensions\swhen\sthe\s__stdcall\scalling\sconvention\sis\snot\sin\suse. -D 2016-07-29T01:31:49.222 +C Update\sthe\sautoconf\smakefile\sfor\sMSVC. +D 2016-07-29T01:46:57.427 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 3340e479e5221f06c3d61726f8f7efff885e4233 @@ -11,7 +11,7 @@ F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am 1a47d071e3d5435f8f7ebff7eb6703848bbd65d4 -F autoconf/Makefile.msc 05a99e98a8895461574ccb9604444d9e97c1f0b6 +F autoconf/Makefile.msc 7a909aa9b538138a21c0626e3ffc4b1f4519f50e F autoconf/README.first 6c4f34fe115ff55d4e8dbfa3cecf04a0188292f7 F autoconf/README.txt 4f04b0819303aabaa35fff5f7b257fb0c1ef95f1 F autoconf/configure.ac cacf2616abf6e4a569bde2ef365c143caeec40bc @@ -1508,7 +1508,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P fc5c187602acceedf7152b6927616d134f779a8f -R d16dc76cf59643dacfea9f5d3d7324b6 +P bc8c9b55ddf5227dc6b2116486f4a19bf54fce2b +R 81c2da6dd9132e2ceb1da7d33d25fdb6 U mistachkin -Z 029d2b66c80fad0a70d5e0c29c8d9e88 +Z 72b9cccf5e1018e731ec3108866ee753 diff --git a/manifest.uuid b/manifest.uuid index 3703d2538c..b2d11c5e33 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bc8c9b55ddf5227dc6b2116486f4a19bf54fce2b \ No newline at end of file +2daf20980d4cb9ed36372778ae1f3e595e503549 \ No newline at end of file From d62c07d42ebd9b12db27c89019a596745548e399 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Fri, 29 Jul 2016 02:04:36 +0000 Subject: [PATCH 0634/1484] Fix typo in a test file interactive output string. FossilOrigin-Name: 4fedd7902371935e1374ca7df3ffd4c4cf93959b --- manifest | 15 +++++++-------- manifest.uuid | 2 +- test/walprotocol.test | 2 +- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index da1d23e9ba..37d9dc7dd2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sadditional\slinkage\smacro\schanges\sfrom\sthe\sbranch. -D 2016-07-29T01:55:42.841 +C Fix\stypo\sin\sa\stest\sfile\sinteractive\soutput\sstring. +D 2016-07-29T02:04:36.873 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 3340e479e5221f06c3d61726f8f7efff885e4233 @@ -1374,7 +1374,7 @@ F test/walmode.test 4022fe03ae6e830583672caa101f046438a0473c F test/walnoshm.test 84ca10c544632a756467336b7c3b864d493ee496 F test/waloverwrite.test dad2f26567f1b45174e54fbf9a8dc1cb876a7f03 F test/walpersist.test 8c6b7e3ec1ba91b5e4dc4e0921d6d3f87cd356a6 -F test/walprotocol.test 059cb75484a1ecf6357a2c1b3324b8156749221e +F test/walprotocol.test 0b92feb132ccebd855494d917d3f6c2d717ace20 F test/walro.test 4ab7ac01b77c2f894235c699d59e3e3c7f15a160 F test/walshared.test 0befc811dcf0b287efae21612304d15576e35417 F test/walslow.test c05c68d4dc2700a982f89133ce103a1a84cc285f @@ -1508,8 +1508,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 45588de385d2a721b3e9f04beb6c7b789dd27d42 71ffa195f5a48280ee522d80ab82e8cdea636961 -R 092b06ead5aa5690fab5536515621278 -T +closed 71ffa195f5a48280ee522d80ab82e8cdea636961 -U drh -Z 3d26d07289768bac8aea9d48f7d64298 +P 8b0eb22ee12b23421dcb8dbeb46909d813788a0b +R 1c5c6cdbf6280e0f07ddb24f0c5484bf +U mistachkin +Z 2e0de3b0c7e8ecb85c119417abdb6170 diff --git a/manifest.uuid b/manifest.uuid index e13e9140e9..becc573de8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8b0eb22ee12b23421dcb8dbeb46909d813788a0b \ No newline at end of file +4fedd7902371935e1374ca7df3ffd4c4cf93959b \ No newline at end of file diff --git a/test/walprotocol.test b/test/walprotocol.test index d658de9d7c..ee8d0b72a5 100644 --- a/test/walprotocol.test +++ b/test/walprotocol.test @@ -69,7 +69,7 @@ proc lock_callback {method filename handle lock} { if {$lock == "1 7 lock exclusive"} { return SQLITE_BUSY } return SQLITE_OK } -puts "# Warning: This next test case causes SQLite to call xSlee(1) 100 times." +puts "# Warning: This next test case causes SQLite to call xSleep(1) 100 times." puts "# Normally this equates to a delay of roughly 10 seconds, but if SQLite" puts "# is built on unix without HAVE_USLEEP defined, it may be much longer." do_test 1.3 { From be56ad31b742d21496863b4b4105b137e7df712e Mon Sep 17 00:00:00 2001 From: mistachkin Date: Fri, 29 Jul 2016 04:12:18 +0000 Subject: [PATCH 0635/1484] For test 'shell1-5.0', disable round-trip testing for characters in the range 0xE0 to 0xEF on Linux, due to intermittent shell portability issues. FossilOrigin-Name: 544c990afd3b64064cc4d970ec5d7eb23eeb9914 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/shell1.test | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 37d9dc7dd2..4056580492 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\stypo\sin\sa\stest\sfile\sinteractive\soutput\sstring. -D 2016-07-29T02:04:36.873 +C For\stest\s'shell1-5.0',\sdisable\sround-trip\stesting\sfor\scharacters\sin\sthe\srange\s0xE0\sto\s0xEF\son\sLinux,\sdue\sto\sintermittent\sshell\sportability\sissues. +D 2016-07-29T04:12:18.810 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 3340e479e5221f06c3d61726f8f7efff885e4233 @@ -1065,7 +1065,7 @@ F test/sharedA.test 0cdf1a76dfa00e6beee66af5b534b1e8df2720f5 F test/sharedB.test 16cc7178e20965d75278f410943109b77b2e645e F test/shared_err.test 2f2aee20db294b9924e81f6ccbe60f19e21e8506 F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304 -F test/shell1.test 77896b65f1cde4ee79e38b2c0ed8578a8f4000e5 +F test/shell1.test 65b10cd8a90cda9b5af9100a45689a57dcc01a31 F test/shell2.test e242a9912f44f4c23c3d1d802a83e934e84c853b F test/shell3.test da513d522ef6f01cee8475dcf8332bff8982b3dd F test/shell4.test 69995ee1cc278eb149aa8746ce1f935f4eaf98b9 @@ -1508,7 +1508,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 8b0eb22ee12b23421dcb8dbeb46909d813788a0b -R 1c5c6cdbf6280e0f07ddb24f0c5484bf +P 4fedd7902371935e1374ca7df3ffd4c4cf93959b +R 85f77acfa5a811a346c23b19da557acb U mistachkin -Z 2e0de3b0c7e8ecb85c119417abdb6170 +Z a69746948670b38e6b2794c69171ee54 diff --git a/manifest.uuid b/manifest.uuid index becc573de8..3a0d9eb7fe 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4fedd7902371935e1374ca7df3ffd4c4cf93959b \ No newline at end of file +544c990afd3b64064cc4d970ec5d7eb23eeb9914 \ No newline at end of file diff --git a/test/shell1.test b/test/shell1.test index 03c2dee1d1..9a966fd8db 100644 --- a/test/shell1.test +++ b/test/shell1.test @@ -871,6 +871,7 @@ do_test shell1-5.0 { continue } if {$i>=0xE0 && $tcl_platform(os)=="OpenBSD"} continue + if {$i>=0xE0 && $i<=0xEF && $tcl_platform(os)=="Linux"} continue set hex [format %02X $i] set char [subst \\x$hex]; set oldChar $char set escapes [list] From 11f69b879c5b9f4dcd566fda776e03bc23c94147 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Fri, 29 Jul 2016 17:36:27 +0000 Subject: [PATCH 0636/1484] Using the header file 'intrin.h' requires MSVC 2005 or later. FossilOrigin-Name: 9fae75c08b7d3b3e13734193ad8398ef6971cbac --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/sqliteInt.h | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 4056580492..ddf53b746a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C For\stest\s'shell1-5.0',\sdisable\sround-trip\stesting\sfor\scharacters\sin\sthe\srange\s0xE0\sto\s0xEF\son\sLinux,\sdue\sto\sintermittent\sshell\sportability\sissues. -D 2016-07-29T04:12:18.810 +C Using\sthe\sheader\sfile\s'intrin.h'\srequires\sMSVC\s2005\sor\slater. +D 2016-07-29T17:36:27.088 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 3340e479e5221f06c3d61726f8f7efff885e4233 @@ -388,7 +388,7 @@ F src/shell.c 9351fc6de11e1d908648c0a92d85627138e3dee5 F src/sqlite.h.in cd10e4206b91c4bf03f121ab9209a14af0b48f14 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h f4206565eb5f5cef9a1544d32a076b5f47af1bdc -F src/sqliteInt.h 14516943867eb2c30ce0e3670299958f59ade052 +F src/sqliteInt.h d6f221a5bd572df935140beda82f357c2185a77c F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c 5b18f9526900f61189ab0b83f1ef41d9f871a2ab F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 @@ -1508,7 +1508,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 4fedd7902371935e1374ca7df3ffd4c4cf93959b -R 85f77acfa5a811a346c23b19da557acb +P 544c990afd3b64064cc4d970ec5d7eb23eeb9914 +R ceef2b71453325469cbc16ff7674c4c9 U mistachkin -Z a69746948670b38e6b2794c69171ee54 +Z 0275ffb3719041525e752ce514a5292f diff --git a/manifest.uuid b/manifest.uuid index 3a0d9eb7fe..5827550e55 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -544c990afd3b64064cc4d970ec5d7eb23eeb9914 \ No newline at end of file +9fae75c08b7d3b3e13734193ad8398ef6971cbac \ No newline at end of file diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 35be76dfb0..0ce56ceab1 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -234,7 +234,7 @@ ** the SQLITE_DISABLE_INTRINSIC define. */ #if !defined(SQLITE_DISABLE_INTRINSIC) -# if defined(_MSC_VER) && _MSC_VER>=1300 +# if defined(_MSC_VER) && _MSC_VER>=1400 # if !defined(_WIN32_WCE) # include # pragma intrinsic(_byteswap_ushort) From 145b4ea519b7826e7905628c479549994e405b0b Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 29 Jul 2016 18:12:12 +0000 Subject: [PATCH 0637/1484] Change the way "(a, b) = (SELECT *)" expressions are handled in where.c if there is an index on one of the columns only. FossilOrigin-Name: 4dfebff2924f46284d5b9cda69175f79b29d6028 --- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- src/expr.c | 12 ------------ src/sqliteInt.h | 3 ++- src/wherecode.c | 32 ++++++++++++++++++++++++++------ src/whereexpr.c | 4 +++- test/rowvalue3.test | 3 +++ 7 files changed, 45 insertions(+), 31 deletions(-) diff --git a/manifest b/manifest index a1321d1be1..4ed47839f9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sfurther\sissues\swith\smulti-column\sIN(...)\soperators.\sAlso\ssome\serror\shandling\scases\ssurrounding\srow\svalues. -D 2016-07-28T19:47:15.803 +C Change\sthe\sway\s"(a,\sb)\s=\s(SELECT\s*)"\sexpressions\sare\shandled\sin\swhere.c\sif\sthere\sis\san\sindex\son\sone\sof\sthe\scolumns\sonly. +D 2016-07-29T18:12:12.900 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -337,7 +337,7 @@ F src/ctime.c 61949e83c4c36e37195a8398ebc752780b534d95 F src/date.c 1cc9fb516ec9932c6fd4d2a0d2f8bc4480145c39 F src/dbstat.c 4f6f7f52b49beb9636ffbd517cfe44a402ba4ad0 F src/delete.c 4aba4214a377ce8ddde2d2e609777bcc8235200f -F src/expr.c 473ce0ac25868b750f3bf9f59bbe7e8f06a0bdd5 +F src/expr.c d21255d0b778cf819d74092463df7630bbcd9fe7 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c bc4145347595b7770f9a598cff1c848302cf5413 F src/func.c 61a4114cf7004f10c542cfabbab9f2bcb9033045 @@ -388,7 +388,7 @@ F src/shell.c 9351fc6de11e1d908648c0a92d85627138e3dee5 F src/sqlite.h.in c6e68a4a47610631822a4f8f83a44c9f75339331 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 46f300b6e300e0fa916d7d58c44b53415b8471a9 -F src/sqliteInt.h 65cf752e1a62cedb2430ecc0547a09833ea13616 +F src/sqliteInt.h 65473a83bccce3556425f764900cb1b716b6cfa1 F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c 5b18f9526900f61189ab0b83f1ef41d9f871a2ab F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 @@ -465,8 +465,8 @@ F src/wal.h 6dd221ed384afdc204bc61e25c23ef7fd5a511f2 F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354 F src/where.c df58d6ad7878a08aa96c652ccbc6d0949f8fa472 F src/whereInt.h 14dd243e13b81cbb0a66063d38b70f93a7d6e613 -F src/wherecode.c 3aff7683566af3428f865904aafa7efb1fbd8701 -F src/whereexpr.c bc85d04c6751ca40cab99a10de308e44893c76b9 +F src/wherecode.c e259a0b9b0eed28a9b4f5085fa1dfef4c3145361 +F src/whereexpr.c a58e878dad5cad54c100792eb8bafb9840d699f5 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1020,7 +1020,7 @@ F test/rowhash.test 0bc1d31415e4575d10cacf31e1a66b5cc0f8be81 F test/rowid.test 5b7509f384f4f6fae1af3c8c104c8ca299fea18d F test/rowvalue.test 979738b3d49f1d93e3fee56a71d4446217917abc F test/rowvalue2.test 8d5dfe75b8f4d1868a2f91f0356f20d36cba64ff -F test/rowvalue3.test 587c1056016fa6b7a40a9bf6cb85d5443fa47d96 +F test/rowvalue3.test 5127afb4414bf62546161497c04840c46e371770 F test/rowvalue4.test 4480898d62d6813e3e38d9d38c02b9a0be5f94be F test/rtree.test 0c8d9dd458d6824e59683c19ab2ffa9ef946f798 F test/run-wordcount.sh 891e89c4c2d16e629cd45951d4ed899ad12afc09 @@ -1512,7 +1512,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 9685880f7baeb670739fdcf2d9df08e22abaa699 -R 66ab918b4b1a726fe3dea7b50bb8fdb0 +P cc3f6542bec99b00d2698889bcea2aa0b587efa0 +R 02d8106109a69b80c3fcb6354dcce9eb U dan -Z 5baa8fdab10ded1fdce6b30d35067148 +Z 1ebe0c81a88c1eb2162a3b6fe26c472e diff --git a/manifest.uuid b/manifest.uuid index c951167b81..0edf69435d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cc3f6542bec99b00d2698889bcea2aa0b587efa0 \ No newline at end of file +4dfebff2924f46284d5b9cda69175f79b29d6028 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 2921898d35..3dcb73ff10 100644 --- a/src/expr.c +++ b/src/expr.c @@ -3512,18 +3512,6 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ break; } - case TK_SELECT_COLUMN: { - Expr *pLeft = pExpr->pLeft; - assert( pLeft ); - assert( pLeft->op==TK_SELECT || pLeft->op==TK_REGISTER ); - if( pLeft->op==TK_SELECT ){ - pLeft->iTable = sqlite3CodeSubselect(pParse, pLeft, 0, 0); - pLeft->op = TK_REGISTER; - } - inReg = pLeft->iTable + pExpr->iColumn; - break; - } - /* ** Form A: ** CASE x WHEN e1 THEN r1 WHEN e2 THEN r2 ... WHEN eN THEN rN ELSE y END diff --git a/src/sqliteInt.h b/src/sqliteInt.h index ea41e65755..9dfc0bcaa9 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3936,7 +3936,8 @@ void sqlite3AlterRenameTable(Parse*, SrcList*, Token*); int sqlite3GetToken(const unsigned char *, int *); void sqlite3NestedParse(Parse*, const char*, ...); void sqlite3ExpirePreparedStatements(sqlite3*); -int sqlite3CodeSubselect(Parse *, Expr *, int, int); +int sqlite3CodeSubselect(Parse*, Expr *, int, int); +int sqlite3ExprCheckIN(Parse*, Expr*); void sqlite3SelectPrep(Parse*, Select*, NameContext*); void sqlite3SelectWrongNumTermsError(Parse *pParse, Select *p); int sqlite3MatchSpanName(const char*, const char*, const char*, const char*); diff --git a/src/wherecode.c b/src/wherecode.c index 892831d821..9db4a0146a 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -359,7 +359,31 @@ static int codeEqualityTerm( assert( pLevel->pWLoop->aLTerm[iEq]==pTerm ); assert( iTarget>0 ); if( pX->op==TK_EQ || pX->op==TK_IS ){ - iReg = sqlite3ExprCodeTarget(pParse, pX->pRight, iTarget); + Expr *pRight = pX->pRight; + if( pRight->op==TK_SELECT_COLUMN ){ + /* This case occurs for expressions like "(a, b) == (SELECT ...)". */ + WhereLoop *pLoop = pLevel->pWLoop; + int i; + Expr *pSub = pRight->pLeft; + assert( pSub->op==TK_SELECT ); + for(i=pLoop->nSkip; iaLTerm[i]->pExpr->pRight; + if( pExpr && pExpr->op==TK_SELECT_COLUMN && pExpr->pLeft==pSub ) break; + } + + if( i==iEq ){ + iReg = sqlite3CodeSubselect(pParse, pSub, 0, 0); + for(/*no-op*/; inLTerm; i++){ + Expr *pExpr = pLoop->aLTerm[i]->pExpr->pRight; + if( pExpr && pExpr->op==TK_SELECT_COLUMN && pExpr->pLeft==pSub ){ + sqlite3VdbeAddOp2(v, OP_Copy, iReg+pExpr->iColumn, iTarget-iEq+i); + } + } + } + iReg = iTarget; + }else{ + iReg = sqlite3ExprCodeTarget(pParse, pRight, iTarget); + } }else if( pX->op==TK_ISNULL ){ iReg = iTarget; sqlite3VdbeAddOp2(v, OP_Null, 0, iReg); @@ -1489,10 +1513,6 @@ Bitmask sqlite3WhereCodeOneLoopStart( testcase( op==OP_IdxLE ); VdbeCoverageIf(v, op==OP_IdxLE ); } - /* Disable the start and end range terms if possible */ - /* disableTerm(pLevel, pRangeStart); */ - /* disableTerm(pLevel, pRangeEnd); */ - /* Seek the table cursor, if required */ if( omitTable ){ /* pIdx is a covering index. No need to access the main table. */ @@ -1594,7 +1614,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( u16 wctrlFlags; /* Flags for sub-WHERE clause */ Expr *pAndExpr = 0; /* An ".. AND (...)" expression */ Table *pTab = pTabItem->pTab; - + pTerm = pLoop->aLTerm[0]; assert( pTerm!=0 ); assert( pTerm->eOperator & WO_OR ); diff --git a/src/whereexpr.c b/src/whereexpr.c index 9c9be99039..4b96e2faa4 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -962,7 +962,8 @@ static void exprAnalyze( Expr *pRight = sqlite3ExprSkipCollate(pExpr->pRight); u16 opMask = (pTerm->prereqRight & prereqLeft)==0 ? WO_ALL : WO_EQUIV; - if( op==TK_IN && pTerm->iField>0 ){ + if( pTerm->iField>0 ){ + assert( op==TK_IN ); assert( pLeft->op==TK_VECTOR ); pLeft = pLeft->x.pList->a[pTerm->iField-1].pExpr; } @@ -979,6 +980,7 @@ static void exprAnalyze( WhereTerm *pNew; Expr *pDup; u16 eExtraOp = 0; /* Extra bits for pNew->eOperator */ + assert( pTerm->iField==0 ); if( pTerm->leftCursor>=0 ){ int idxNew; pDup = sqlite3ExprDup(db, pExpr, 0); diff --git a/test/rowvalue3.test b/test/rowvalue3.test index 32c86251d0..2da141ec72 100644 --- a/test/rowvalue3.test +++ b/test/rowvalue3.test @@ -46,6 +46,7 @@ foreach {tn sql res} { 9 "SELECT (1, 2) IN (SELECT rowid, b FROM t1)" 1 10 "SELECT 1 WHERE (1, 2) IN (SELECT rowid, b FROM t1)" 1 11 "SELECT 1 WHERE (1, NULL) IN (SELECT rowid, b FROM t1)" {} + 12 "SELECT 1 FROM t1 WHERE (a, b) = (SELECT +a, +b FROM t1)" {1} } { do_execsql_test 1.$tn $sql $res } @@ -208,6 +209,8 @@ foreach {tn idx} { } } +#------------------------------------------------------------------------- + finish_test From 19ff12dd76b7b57cd9feed6298a399fc5d8f9cec Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 29 Jul 2016 20:58:19 +0000 Subject: [PATCH 0638/1484] Fix some issues with vector range constraints and the column cache. Also vector range constraints and rowid columns. FossilOrigin-Name: 42607366bfc2dceb1013797a973b3b8df75dcb4d --- manifest | 18 +++++------ manifest.uuid | 2 +- src/expr.c | 2 ++ src/wherecode.c | 21 ++++++++----- src/whereexpr.c | 23 ++++++++------ test/rowvalue.test | 76 +++++++++++++++++++++++++++++++++++++++++++++- 6 files changed, 113 insertions(+), 29 deletions(-) diff --git a/manifest b/manifest index 4ed47839f9..2dae50f85a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sthe\sway\s"(a,\sb)\s=\s(SELECT\s*)"\sexpressions\sare\shandled\sin\swhere.c\sif\sthere\sis\san\sindex\son\sone\sof\sthe\scolumns\sonly. -D 2016-07-29T18:12:12.900 +C Fix\ssome\sissues\swith\svector\srange\sconstraints\sand\sthe\scolumn\scache.\sAlso\svector\srange\sconstraints\sand\srowid\scolumns. +D 2016-07-29T20:58:19.781 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -337,7 +337,7 @@ F src/ctime.c 61949e83c4c36e37195a8398ebc752780b534d95 F src/date.c 1cc9fb516ec9932c6fd4d2a0d2f8bc4480145c39 F src/dbstat.c 4f6f7f52b49beb9636ffbd517cfe44a402ba4ad0 F src/delete.c 4aba4214a377ce8ddde2d2e609777bcc8235200f -F src/expr.c d21255d0b778cf819d74092463df7630bbcd9fe7 +F src/expr.c d904598a807ec20500a987566b453307cf2552cd F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c bc4145347595b7770f9a598cff1c848302cf5413 F src/func.c 61a4114cf7004f10c542cfabbab9f2bcb9033045 @@ -465,8 +465,8 @@ F src/wal.h 6dd221ed384afdc204bc61e25c23ef7fd5a511f2 F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354 F src/where.c df58d6ad7878a08aa96c652ccbc6d0949f8fa472 F src/whereInt.h 14dd243e13b81cbb0a66063d38b70f93a7d6e613 -F src/wherecode.c e259a0b9b0eed28a9b4f5085fa1dfef4c3145361 -F src/whereexpr.c a58e878dad5cad54c100792eb8bafb9840d699f5 +F src/wherecode.c e3159b1d6ecd2d39f99f3ec7926d02c1f04f3053 +F src/whereexpr.c c63e0e48fe32eeb99c0d32e4130ae56af80fcbf5 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1018,7 +1018,7 @@ F test/rollbackfault.test 0e646aeab8840c399cfbfa43daab46fd609cf04a F test/rowallock.test 3f88ec6819489d0b2341c7a7528ae17c053ab7cc F test/rowhash.test 0bc1d31415e4575d10cacf31e1a66b5cc0f8be81 F test/rowid.test 5b7509f384f4f6fae1af3c8c104c8ca299fea18d -F test/rowvalue.test 979738b3d49f1d93e3fee56a71d4446217917abc +F test/rowvalue.test 8656a46fac138f2a964aebbc37fc256d0a956b9c F test/rowvalue2.test 8d5dfe75b8f4d1868a2f91f0356f20d36cba64ff F test/rowvalue3.test 5127afb4414bf62546161497c04840c46e371770 F test/rowvalue4.test 4480898d62d6813e3e38d9d38c02b9a0be5f94be @@ -1512,7 +1512,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P cc3f6542bec99b00d2698889bcea2aa0b587efa0 -R 02d8106109a69b80c3fcb6354dcce9eb +P 4dfebff2924f46284d5b9cda69175f79b29d6028 +R 6db81bb19ebb4412c650189f8ab65d8e U dan -Z 1ebe0c81a88c1eb2162a3b6fe26c472e +Z 49cec86004a136f8782fa45723e38de1 diff --git a/manifest.uuid b/manifest.uuid index 0edf69435d..38cde2bfda 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4dfebff2924f46284d5b9cda69175f79b29d6028 \ No newline at end of file +42607366bfc2dceb1013797a973b3b8df75dcb4d \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 3dcb73ff10..264f27dbfd 100644 --- a/src/expr.c +++ b/src/expr.c @@ -411,6 +411,7 @@ static void codeVectorCompare(Parse *pParse, Expr *pExpr, int dest){ Expr *pL, *pR; int r1, r2; + if( i ) sqlite3ExprCachePush(pParse); if( regLeft ){ pL = pLeft->x.pSelect->pEList->a[i].pExpr; r1 = regLeft+i; @@ -431,6 +432,7 @@ static void codeVectorCompare(Parse *pParse, Expr *pExpr, int dest){ sqlite3VdbeAddOp3(v, opTest, dest, addr, p3); sqlite3ReleaseTempReg(pParse, regFree1); sqlite3ReleaseTempReg(pParse, regFree2); + if( i ) sqlite3ExprCachePop(pParse); } } diff --git a/src/wherecode.c b/src/wherecode.c index 9db4a0146a..5eb520eb3c 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -964,9 +964,6 @@ static void codeExprOrVector(Parse *pParse, Expr *p, int iReg, int nReg){ Vdbe *v = pParse->pVdbe; int iSelect = sqlite3CodeSubselect(pParse, p, 0, 0); sqlite3VdbeAddOp3(v, OP_Copy, iSelect, iReg, nReg-1); - p->op2 = p->op; - p->op = TK_REGISTER; - p->iTable = iSelect; } }else{ assert( nReg==1 ); @@ -1183,6 +1180,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( if( pStart ){ Expr *pX; /* The expression that defines the start bound */ int r1, rTemp; /* Registers for holding the start boundary */ + int op; /* Cursor seek operation */ /* The following constant maps TK_xx codes into corresponding ** seek opcodes. It depends on a particular ordering of TK_xx @@ -1202,8 +1200,16 @@ Bitmask sqlite3WhereCodeOneLoopStart( pX = pStart->pExpr; assert( pX!=0 ); testcase( pStart->leftCursor!=iCur ); /* transitive constraints */ - r1 = sqlite3ExprCodeTemp(pParse, pX->pRight, &rTemp); - sqlite3VdbeAddOp3(v, aMoveOp[pX->op-TK_GT], iCur, addrBrk, r1); + if( pX->pRight->flags & EP_Vector ){ + r1 = rTemp = sqlite3GetTempReg(pParse); + codeExprOrVector(pParse, pX->pRight, r1, 1); + op = aMoveOp[(pX->op - TK_GT) | 0x0001]; + }else{ + r1 = sqlite3ExprCodeTemp(pParse, pX->pRight, &rTemp); + disableTerm(pLevel, pStart); + op = aMoveOp[(pX->op - TK_GT)]; + } + sqlite3VdbeAddOp3(v, op, iCur, addrBrk, r1); VdbeComment((v, "pk")); VdbeCoverageIf(v, pX->op==TK_GT); VdbeCoverageIf(v, pX->op==TK_LE); @@ -1211,7 +1217,6 @@ Bitmask sqlite3WhereCodeOneLoopStart( VdbeCoverageIf(v, pX->op==TK_GE); sqlite3ExprCacheAffinityChange(pParse, r1, 1); sqlite3ReleaseTempReg(pParse, rTemp); - disableTerm(pLevel, pStart); }else{ sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iCur, addrBrk); VdbeCoverageIf(v, bRev==0); @@ -1225,8 +1230,8 @@ Bitmask sqlite3WhereCodeOneLoopStart( testcase( pEnd->leftCursor!=iCur ); /* Transitive constraints */ testcase( pEnd->wtFlags & TERM_VIRTUAL ); memEndValue = ++pParse->nMem; - sqlite3ExprCode(pParse, pX->pRight, memEndValue); - if( pX->op==TK_LT || pX->op==TK_GT ){ + codeExprOrVector(pParse, pX->pRight, memEndValue, 1); + if( !(pX->pRight->flags&EP_Vector) && (pX->op==TK_LT || pX->op==TK_GT) ){ testOp = bRev ? OP_Le : OP_Ge; }else{ testOp = bRev ? OP_Lt : OP_Gt; diff --git a/src/whereexpr.c b/src/whereexpr.c index 4b96e2faa4..93908e6d32 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -1190,17 +1190,20 @@ static void exprAnalyze( && ( (pExpr->pLeft->flags & EP_xIsSelect)==0 || (pExpr->pRight->flags & EP_xIsSelect)==0 )){ - int i; - for(i=0; ipLeft); i++){ - int idxNew; - Expr *pNew; - Expr *pLeft = exprVectorExpr(pParse, pExpr->pLeft, i); - Expr *pRight = exprVectorExpr(pParse, pExpr->pRight, i); + int nLeft = sqlite3ExprVectorSize(pExpr->pLeft); + if( nLeft==sqlite3ExprVectorSize(pExpr->pRight) ){ + int i; + for(i=0; ipLeft); i++){ + int idxNew; + Expr *pNew; + Expr *pLeft = exprVectorExpr(pParse, pExpr->pLeft, i); + Expr *pRight = exprVectorExpr(pParse, pExpr->pRight, i); - pNew = sqlite3PExpr(pParse, pExpr->op, pLeft, pRight, 0); - idxNew = whereClauseInsert(pWC, pNew, TERM_VIRTUAL|TERM_DYNAMIC); - exprAnalyze(pSrc, pWC, idxNew); - markTermAsChild(pWC, idxNew, idxTerm); + pNew = sqlite3PExpr(pParse, pExpr->op, pLeft, pRight, 0); + idxNew = whereClauseInsert(pWC, pNew, TERM_VIRTUAL|TERM_DYNAMIC); + exprAnalyze(pSrc, pWC, idxNew); + markTermAsChild(pWC, idxNew, idxTerm); + } } } diff --git a/test/rowvalue.test b/test/rowvalue.test index 3bfcfe2c12..3989c39513 100644 --- a/test/rowvalue.test +++ b/test/rowvalue.test @@ -118,6 +118,80 @@ foreach {tn expr res} { do_execsql_test 5.$tn "SELECT $expr" [list $res] } +do_execsql_test 6.0 { + CREATE TABLE hh(a, b, c); + INSERT INTO hh VALUES('abc', 1, 'i'); + INSERT INTO hh VALUES('ABC', 1, 'ii'); + INSERT INTO hh VALUES('def', 2, 'iii'); + INSERT INTO hh VALUES('DEF', 2, 'iv'); + INSERT INTO hh VALUES('GHI', 3, 'v'); + INSERT INTO hh VALUES('ghi', 3, 'vi'); + + CREATE INDEX hh_ab ON hh(a, b); +} + +do_execsql_test 6.1 { + SELECT c FROM hh WHERE (a, b) = (SELECT 'abc', 1); +} {i} +do_execsql_test 6.2 { + SELECT c FROM hh WHERE (a, b) = (SELECT 'abc' COLLATE nocase, 1); +} {i} +do_execsql_test 6.3 { + SELECT c FROM hh WHERE a = (SELECT 'abc' COLLATE nocase) AND b = (SELECT 1); +} {i} +do_execsql_test 6.4 { + SELECT c FROM hh WHERE +a = (SELECT 'abc' COLLATE nocase) AND b = (SELECT 1); +} {i} +do_execsql_test 6.5 { + SELECT c FROM hh WHERE a = (SELECT 'abc') COLLATE nocase AND b = (SELECT 1); +} {i ii} +do_catchsql_test 6.6 { + SELECT c FROM hh WHERE (a, b) = (SELECT 'abc', 1) COLLATE nocase; +} {1 {invalid use of row value}} +do_catchsql_test 6.7 { + SELECT c FROM hh WHERE (a, b) = 1; +} {1 {invalid use of row value}} +do_execsql_test 6.8 { + SELECT c FROM hh WHERE (a COLLATE nocase, b) = (SELECT 'def', 2); +} {iii iv} +do_execsql_test 6.9 { + SELECT c FROM hh WHERE (a COLLATE nocase, b) IS NOT (SELECT 'def', 2); +} {i ii v vi} +do_execsql_test 6.10 { + SELECT c FROM hh WHERE (b, a) = (SELECT 2, 'def'); +} {iii} + +do_execsql_test 7.0 { + CREATE TABLE xy(i INTEGER PRIMARY KEY, j, k); + INSERT INTO xy VALUES(1, 1, 1); + INSERT INTO xy VALUES(2, 2, 2); + INSERT INTO xy VALUES(3, 3, 3); + INSERT INTO xy VALUES(4, 4, 4); +} + + +foreach {tn sql res eqp} { + 1 "SELECT * FROM xy WHERE (i, j) IS (2, 2)" {2 2 2} + "0 0 0 {SEARCH TABLE xy USING INTEGER PRIMARY KEY (rowid=?)}" + + 2 "SELECT * FROM xy WHERE (k, j) < (2, 3)" {1 1 1 2 2 2} + "0 0 0 {SCAN TABLE xy}" + + 3 "SELECT * FROM xy WHERE (i, j) < (2, 3)" {1 1 1 2 2 2} + "0 0 0 {SEARCH TABLE xy USING INTEGER PRIMARY KEY (rowid (2, 1)" {2 2 2 3 3 3 4 4 4} + "0 0 0 {SEARCH TABLE xy USING INTEGER PRIMARY KEY (rowid>?)}" + + 5 "SELECT * FROM xy WHERE (i, j) > ('2', 1)" {2 2 2 3 3 3 4 4 4} + "0 0 0 {SEARCH TABLE xy USING INTEGER PRIMARY KEY (rowid>?)}" + +} { + do_eqp_test 7.$tn.1 $sql $eqp + do_execsql_test 7.$tn.2 $sql $res +} + + + finish_test - From 625015e0c99a689eb362853c03123aa8eabd032e Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 30 Jul 2016 16:39:28 +0000 Subject: [PATCH 0639/1484] Remove the EP_Vector expression flag. FossilOrigin-Name: e9d9c6d46b46160fad6aa6e3441a65a09157515f --- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- src/expr.c | 23 ++++++++++++++++------- src/resolve.c | 9 --------- src/sqliteInt.h | 2 +- src/wherecode.c | 12 +++++++----- src/whereexpr.c | 6 ++---- 7 files changed, 37 insertions(+), 37 deletions(-) diff --git a/manifest b/manifest index 2dae50f85a..c185b508a4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\ssome\sissues\swith\svector\srange\sconstraints\sand\sthe\scolumn\scache.\sAlso\svector\srange\sconstraints\sand\srowid\scolumns. -D 2016-07-29T20:58:19.781 +C Remove\sthe\sEP_Vector\sexpression\sflag. +D 2016-07-30T16:39:28.446 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -337,7 +337,7 @@ F src/ctime.c 61949e83c4c36e37195a8398ebc752780b534d95 F src/date.c 1cc9fb516ec9932c6fd4d2a0d2f8bc4480145c39 F src/dbstat.c 4f6f7f52b49beb9636ffbd517cfe44a402ba4ad0 F src/delete.c 4aba4214a377ce8ddde2d2e609777bcc8235200f -F src/expr.c d904598a807ec20500a987566b453307cf2552cd +F src/expr.c 4e79d7a355a59d5d0635f0a718a07abf21fe69bc F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c bc4145347595b7770f9a598cff1c848302cf5413 F src/func.c 61a4114cf7004f10c542cfabbab9f2bcb9033045 @@ -381,14 +381,14 @@ F src/pragma.h 64c78a648751b9f4f297276c4eb7507b14b4628c F src/prepare.c 22df6171aec1d86904ed2ad30c2348a5748aa04e F src/printf.c a5f0ca08ddede803c241266abb46356ec748ded1 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 -F src/resolve.c d5516a3818748c50f98c18e4601a746e90929f1c +F src/resolve.c cca3aa77b95706df5d635a2141a4d1de60ae6598 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c 0115f5d222f5cf9b5511ec4072088417354d738a F src/shell.c 9351fc6de11e1d908648c0a92d85627138e3dee5 F src/sqlite.h.in c6e68a4a47610631822a4f8f83a44c9f75339331 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 46f300b6e300e0fa916d7d58c44b53415b8471a9 -F src/sqliteInt.h 65473a83bccce3556425f764900cb1b716b6cfa1 +F src/sqliteInt.h 618346a0ad21589a177aeaa3725a6dfe0b2dbcf3 F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c 5b18f9526900f61189ab0b83f1ef41d9f871a2ab F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 @@ -465,8 +465,8 @@ F src/wal.h 6dd221ed384afdc204bc61e25c23ef7fd5a511f2 F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354 F src/where.c df58d6ad7878a08aa96c652ccbc6d0949f8fa472 F src/whereInt.h 14dd243e13b81cbb0a66063d38b70f93a7d6e613 -F src/wherecode.c e3159b1d6ecd2d39f99f3ec7926d02c1f04f3053 -F src/whereexpr.c c63e0e48fe32eeb99c0d32e4130ae56af80fcbf5 +F src/wherecode.c 6131be0cb19702665c3decbf243dae58ecc15937 +F src/whereexpr.c 82196ee82ca9de9d133ae742786bb89cf6ee890d F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1512,7 +1512,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 4dfebff2924f46284d5b9cda69175f79b29d6028 -R 6db81bb19ebb4412c650189f8ab65d8e +P 42607366bfc2dceb1013797a973b3b8df75dcb4d +R eaef7077e544c307dde0b934686aad76 U dan -Z 49cec86004a136f8782fa45723e38de1 +Z c4dca5e01854a7cf15bed46750135eb4 diff --git a/manifest.uuid b/manifest.uuid index 38cde2bfda..1b7e127455 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -42607366bfc2dceb1013797a973b3b8df75dcb4d \ No newline at end of file +e9d9c6d46b46160fad6aa6e3441a65a09157515f \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 264f27dbfd..5f5e1d058c 100644 --- a/src/expr.c +++ b/src/expr.c @@ -316,13 +316,23 @@ static int codeCompare( ** any other type of expression, return 1. */ int sqlite3ExprVectorSize(Expr *pExpr){ - if( (pExpr->flags & EP_Vector)==0 ) return 1; + if( sqlite3ExprIsVector(pExpr)==0 ) return 1; if( pExpr->flags & EP_xIsSelect ){ return pExpr->x.pSelect->pEList->nExpr; } return pExpr->x.pList->nExpr; } +/* +** Return true if expression pExpr is a vector, or false otherwise. +*/ +int sqlite3ExprIsVector(Expr *pExpr){ + return ( + pExpr->op==TK_VECTOR + || (pExpr->op==TK_SELECT && pExpr->x.pSelect->pEList->nExpr>1) + ); +} + /* ** If the expression passed as the first argument is a TK_VECTOR, return ** a pointer to the i'th field of the vector. Or, if the first argument @@ -330,7 +340,7 @@ int sqlite3ExprVectorSize(Expr *pExpr){ ** value. Otherwise, return a copy of the first argument. */ static Expr *exprVectorField(Expr *pVector, int i){ - if( (pVector->flags & EP_Vector)==0 ){ + if( sqlite3ExprIsVector(pVector)==0 ){ assert( i==0 ); return pVector; }else if( pVector->flags & EP_xIsSelect ){ @@ -3171,7 +3181,7 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ case TK_NE: case TK_EQ: { Expr *pLeft = pExpr->pLeft; - if( (pLeft->flags & EP_Vector) ){ + if( sqlite3ExprIsVector(pLeft) ){ codeVectorCompare(pParse, pExpr, target); }else{ r1 = sqlite3ExprCodeTemp(pParse, pLeft, ®Free1); @@ -3865,7 +3875,7 @@ static void exprCodeBetween( compRight.op = TK_LE; compRight.pLeft = &exprX; compRight.pRight = pExpr->x.pList->a[1].pExpr; - if( (exprX.flags & EP_Vector)==0 ){ + if( sqlite3ExprIsVector(&exprX)==0 ){ exprToRegister(&exprX, sqlite3ExprCodeTemp(pParse, &exprX, ®Free1)); } if( xJumpIf ){ @@ -3949,7 +3959,7 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ case TK_GE: case TK_NE: case TK_EQ: { - if( pExpr->pLeft->flags & EP_Vector ) goto default_expr; + if( sqlite3ExprIsVector(pExpr->pLeft) ) goto default_expr; testcase( jumpIfNull==0 ); r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); @@ -4103,8 +4113,7 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ case TK_GE: case TK_NE: case TK_EQ: { - if( pExpr->pLeft->flags & EP_Vector ) goto default_expr; - + if( sqlite3ExprIsVector(pExpr->pLeft) ) goto default_expr; testcase( jumpIfNull==0 ); r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); diff --git a/src/resolve.c b/src/resolve.c index 4d8873963a..77ce37f6d7 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -765,10 +765,6 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ ExprSetProperty(pExpr, EP_VarSelect); pNC->ncFlags |= NC_VarSelect; } - - if( pExpr->op==TK_SELECT && pExpr->x.pSelect->pEList->nExpr>1 ){ - ExprSetProperty(pExpr, EP_Vector); - } } break; } @@ -776,11 +772,6 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ notValid(pParse, pNC, "parameters", NC_IsCheck|NC_PartIdx|NC_IdxExpr); break; } - - case TK_VECTOR: { - ExprSetProperty(pExpr, EP_Vector); - break; - } } return (pParse->nErr || pParse->db->mallocFailed) ? WRC_Abort : WRC_Continue; } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 9dfc0bcaa9..5b3826586e 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2327,7 +2327,6 @@ struct Expr { #define EP_CanBeNull 0x100000 /* Can be null despite NOT NULL constraint */ #define EP_Subquery 0x200000 /* Tree contains a TK_SELECT operator */ #define EP_Alias 0x400000 /* Is an alias for a result set column */ -#define EP_Vector 0x800000 /* This expression is a row value */ /* ** Combinations of two or more EP_* flags @@ -4256,5 +4255,6 @@ int sqlite3DbstatRegister(sqlite3*); #endif int sqlite3ExprVectorSize(Expr *pExpr); +int sqlite3ExprIsVector(Expr *pExpr); #endif /* SQLITEINT_H */ diff --git a/src/wherecode.c b/src/wherecode.c index 5eb520eb3c..4f4f141123 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -952,7 +952,7 @@ static void codeDeferredSeek( static void codeExprOrVector(Parse *pParse, Expr *p, int iReg, int nReg){ assert( nReg>0 ); - if( p->flags & EP_Vector ){ + if( sqlite3ExprIsVector(p) ){ int i; if( (p->flags & EP_xIsSelect)==0 ){ ExprList *pList = p->x.pList; @@ -1200,7 +1200,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( pX = pStart->pExpr; assert( pX!=0 ); testcase( pStart->leftCursor!=iCur ); /* transitive constraints */ - if( pX->pRight->flags & EP_Vector ){ + if( sqlite3ExprIsVector(pX->pRight) ){ r1 = rTemp = sqlite3GetTempReg(pParse); codeExprOrVector(pParse, pX->pRight, r1, 1); op = aMoveOp[(pX->op - TK_GT) | 0x0001]; @@ -1231,7 +1231,9 @@ Bitmask sqlite3WhereCodeOneLoopStart( testcase( pEnd->wtFlags & TERM_VIRTUAL ); memEndValue = ++pParse->nMem; codeExprOrVector(pParse, pX->pRight, memEndValue, 1); - if( !(pX->pRight->flags&EP_Vector) && (pX->op==TK_LT || pX->op==TK_GT) ){ + if( 0==sqlite3ExprIsVector(pX->pRight) + && (pX->op==TK_LT || pX->op==TK_GT) + ){ testOp = bRev ? OP_Le : OP_Ge; }else{ testOp = bRev ? OP_Lt : OP_Gt; @@ -1440,7 +1442,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( } nConstraint += nBtm; testcase( pRangeStart->wtFlags & TERM_VIRTUAL ); - if( (pRight->flags & EP_Vector)==0 ){ + if( sqlite3ExprIsVector(pRight)==0 ){ disableTerm(pLevel, pRangeStart); }else{ startEq = 1; @@ -1493,7 +1495,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( nConstraint += nTop; testcase( pRangeEnd->wtFlags & TERM_VIRTUAL ); - if( (pRight->flags & EP_Vector)==0 ){ + if( sqlite3ExprIsVector(pRight)==0 ){ disableTerm(pLevel, pRangeEnd); }else{ endEq = 1; diff --git a/src/whereexpr.c b/src/whereexpr.c index 93908e6d32..5997da1e3a 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -845,9 +845,7 @@ static int exprMightBeIndexed( ** inequality constraint (>, <, >= or <=), perform the processing ** on the first element of the vector. */ assert( TK_GT+1==TK_LE && TK_GT+2==TK_LT && TK_GT+3==TK_GE ); - if( (pExpr->flags & (EP_Vector|EP_xIsSelect))==EP_Vector - && (op>=TK_GT && op<=TK_GE) - ){ + if( pExpr->op==TK_VECTOR && (op>=TK_GT && op<=TK_GE) ){ pExpr = pExpr->x.pList->a[0].pExpr; } @@ -1186,7 +1184,7 @@ static void exprAnalyze( if( pWC->op==TK_AND && (pExpr->op==TK_EQ || pExpr->op==TK_IS) - && (pExpr->pLeft->flags & EP_Vector) + && sqlite3ExprIsVector(pExpr->pLeft) && ( (pExpr->pLeft->flags & EP_xIsSelect)==0 || (pExpr->pRight->flags & EP_xIsSelect)==0 )){ From 19e76b2a7cf4b1b42f2d90ef27ea852603206bb2 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Sat, 30 Jul 2016 18:54:54 +0000 Subject: [PATCH 0640/1484] Fix harmless compiler warning seen with MSVC. FossilOrigin-Name: 390a38a142d36d2c57b3f21aab72edcde450125d --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/where.c | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index ddf53b746a..9657203bbb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Using\sthe\sheader\sfile\s'intrin.h'\srequires\sMSVC\s2005\sor\slater. -D 2016-07-29T17:36:27.088 +C Fix\sharmless\scompiler\swarning\sseen\swith\sMSVC. +D 2016-07-30T18:54:54.989 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 3340e479e5221f06c3d61726f8f7efff885e4233 @@ -463,7 +463,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 02eeecc265f6ffd0597378f5d8ae9070b62a406a F src/wal.h 6dd221ed384afdc204bc61e25c23ef7fd5a511f2 F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354 -F src/where.c fcaa38d19c2a7bb450cc57810bdc3d4eb36e00b0 +F src/where.c bb1444f6ae6bc3cbd086cc61cd9c6e3a6168d89b F src/whereInt.h e5b939701a7ceffc5a3a8188a37f9746416ebcd0 F src/wherecode.c 99707d11907c71d289ee9553d2d1a22f1fd8ba41 F src/whereexpr.c d7dcbf14ce1b5876c1f76496162c30fcba669563 @@ -1508,7 +1508,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 544c990afd3b64064cc4d970ec5d7eb23eeb9914 -R ceef2b71453325469cbc16ff7674c4c9 +P 9fae75c08b7d3b3e13734193ad8398ef6971cbac +R 20430021b7d310aa0691f2edba10b981 U mistachkin -Z 0275ffb3719041525e752ce514a5292f +Z 1a5ea8a378b7c26f7d4d45026b5640de diff --git a/manifest.uuid b/manifest.uuid index 5827550e55..dedb9c60d3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9fae75c08b7d3b3e13734193ad8398ef6971cbac \ No newline at end of file +390a38a142d36d2c57b3f21aab72edcde450125d \ No newline at end of file diff --git a/src/where.c b/src/where.c index da41c142fa..9b3c281efc 100644 --- a/src/where.c +++ b/src/where.c @@ -2786,9 +2786,9 @@ static int whereLoopAddBtree( LogEst nLookup = rSize + 16; /* Base cost: N*3 */ int ii; int iCur = pSrc->iCursor; - WhereClause *pWC = &pWInfo->sWC; - for(ii=0; iinTerm; ii++){ - WhereTerm *pTerm = &pWC->a[ii]; + WhereClause *pWC2 = &pWInfo->sWC; + for(ii=0; iinTerm; ii++){ + WhereTerm *pTerm = &pWC2->a[ii]; if( !sqlite3ExprCoveredByIndex(pTerm->pExpr, iCur, pProbe) ){ break; } From 5c288b929a80fb532c00e74853f097b267eff860 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 30 Jul 2016 21:02:33 +0000 Subject: [PATCH 0641/1484] Fix problems with vector == comparisons and NULL values. FossilOrigin-Name: 059d0d05354e6efab7892c97b339ffa0b5303587 --- manifest | 16 ++--- manifest.uuid | 2 +- src/expr.c | 146 +++++++++++++++++++++++++++++---------------- src/vdbe.c | 63 ++++++++++++++----- test/rowvalue.test | 3 + 5 files changed, 154 insertions(+), 76 deletions(-) diff --git a/manifest b/manifest index fdb83a0054..6cdc700a0e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\slatest\strunk\swith\sthis\sbranch. -D 2016-07-30T17:59:39.678 +C Fix\sproblems\swith\svector\s==\scomparisons\sand\sNULL\svalues. +D 2016-07-30T21:02:33.694 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 3340e479e5221f06c3d61726f8f7efff885e4233 @@ -337,7 +337,7 @@ F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7 F src/date.c 1cc9fb516ec9932c6fd4d2a0d2f8bc4480145c39 F src/dbstat.c 4f6f7f52b49beb9636ffbd517cfe44a402ba4ad0 F src/delete.c 4aba4214a377ce8ddde2d2e609777bcc8235200f -F src/expr.c 4e79d7a355a59d5d0635f0a718a07abf21fe69bc +F src/expr.c f33dcbaf364c5c54a2f1aab7cf1de9fbd0c88f3d F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c bc4145347595b7770f9a598cff1c848302cf5413 F src/func.c 61a4114cf7004f10c542cfabbab9f2bcb9033045 @@ -449,7 +449,7 @@ F src/update.c 4f05ea8cddfa367d045e03589756c02199e8f9bd F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 810ec3f22e2d1b62e66c30fe3621ebdedd23584d F src/vacuum.c 9dd2f5d276bc6094d8f1d85ecd41b30c1a002a43 -F src/vdbe.c 44d75e3585d93bf56c72de5e2ec4c5a16cd40370 +F src/vdbe.c 9f15129214a55044f918a983e1560fd87b0130a8 F src/vdbe.h 67bc551f7faf04c33493892e4b378aada823ed10 F src/vdbeInt.h c59381049af5c7751a83456c39b80d1a6fde1f9d F src/vdbeapi.c c3f6715a99995c11748ecad91d25e93fd9fc390b @@ -1018,7 +1018,7 @@ F test/rollbackfault.test 0e646aeab8840c399cfbfa43daab46fd609cf04a F test/rowallock.test 3f88ec6819489d0b2341c7a7528ae17c053ab7cc F test/rowhash.test 0bc1d31415e4575d10cacf31e1a66b5cc0f8be81 F test/rowid.test 5b7509f384f4f6fae1af3c8c104c8ca299fea18d -F test/rowvalue.test 8656a46fac138f2a964aebbc37fc256d0a956b9c +F test/rowvalue.test f4c06c37d8e3212156435495da453e12bdeef7e5 F test/rowvalue2.test 8d5dfe75b8f4d1868a2f91f0356f20d36cba64ff F test/rowvalue3.test 5127afb4414bf62546161497c04840c46e371770 F test/rowvalue4.test 4480898d62d6813e3e38d9d38c02b9a0be5f94be @@ -1512,7 +1512,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e9d9c6d46b46160fad6aa6e3441a65a09157515f 9fae75c08b7d3b3e13734193ad8398ef6971cbac -R 9891078e76bc1592d3c3f0175b7e1e59 +P 63ae02d084a332250ff6fd8d8c80e53bf5422a68 +R 27dbfd24654b70fef0137ceb387adc85 U dan -Z b42ff5e1f9b23663ffe713255f8923fa +Z 07f670f92b12ec2bcc84d4a9aa33539d diff --git a/manifest.uuid b/manifest.uuid index b26f57e106..f6c7658784 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -63ae02d084a332250ff6fd8d8c80e53bf5422a68 \ No newline at end of file +059d0d05354e6efab7892c97b339ffa0b5303587 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 5f5e1d058c..5acce2f0c7 100644 --- a/src/expr.c +++ b/src/expr.c @@ -349,19 +349,59 @@ static Expr *exprVectorField(Expr *pVector, int i){ return pVector->x.pList->a[i].pExpr; } -static int exprVectorSubselect(Parse *pParse, Expr *pExpr){ +/* +** If expression pExpr is of type TK_SELECT, generate code to evaluate +** it. Return the register in which the result is stored (or, if the +** sub-select returns more than one column, the first in an array +** of registers in which the result is stored). +** +** If pExpr is not a TK_SELECT expression, return 0. +*/ +static int exprCodeSubselect(Parse *pParse, Expr *pExpr){ int reg = 0; - if( pExpr->flags & EP_xIsSelect ){ - assert( pExpr->op==TK_REGISTER || pExpr->op==TK_SELECT ); - if( pExpr->op==TK_REGISTER ){ - reg = pExpr->iTable; - }else{ - reg = sqlite3CodeSubselect(pParse, pExpr, 0, 0); - } + if( pExpr->op==TK_SELECT ){ + reg = sqlite3CodeSubselect(pParse, pExpr, 0, 0); } return reg; } +/* +** Argument pVector points to a vector expression - either a TK_VECTOR +** or TK_SELECT that returns more than one column. This function generates +** code to evaluate expression iElem of the vector. The number of the +** register containing the result is returned. +** +** Before returning, output parameter (*ppExpr) is set to point to the +** Expr object corresponding to element iElem of the vector. +** +** If pVector is a TK_SELECT expression, then argument regSelect is +** passed the first in an array of registers that contain the results +** of the sub-select. +** +** If output parameter (*pRegFree) is set to a non-zero value by this +** function, it is the value of a temporary register that should be +** freed by the caller. +*/ +static int exprVectorRegister( + Parse *pParse, /* Parse context */ + Expr *pVector, /* Vector to extract element from */ + int iElem, /* Element to extract from pVector */ + int regSelect, /* First in array of registers */ + Expr **ppExpr, /* OUT: Expression element */ + int *pRegFree /* OUT: Temp register to free */ +){ + if( regSelect ){ + *ppExpr = pVector->x.pSelect->pEList->a[iElem].pExpr; + return regSelect+iElem; + } + *ppExpr = pVector->x.pList->a[iElem].pExpr; + return sqlite3ExprCodeTemp(pParse, *ppExpr, pRegFree); +} + +/* +** Expression pExpr is a comparison between two vector values. Compute +** the result of the comparison and write it to register dest. +*/ static void codeVectorCompare(Parse *pParse, Expr *pExpr, int dest){ Vdbe *v = pParse->pVdbe; Expr *pLeft = pExpr->pLeft; @@ -377,11 +417,12 @@ static void codeVectorCompare(Parse *pParse, Expr *pExpr, int dest){ }else{ int p5 = (pExpr->op==TK_IS || pExpr->op==TK_ISNOT) ? SQLITE_NULLEQ : 0; int opCmp; - int opTest; int i; - int p3 = 1; + int p3 = 0; + int p4 = 0; int regLeft = 0; int regRight = 0; + int regTmp = 0; assert( pExpr->op==TK_EQ || pExpr->op==TK_NE || pExpr->op==TK_IS || pExpr->op==TK_ISNOT @@ -389,61 +430,64 @@ static void codeVectorCompare(Parse *pParse, Expr *pExpr, int dest){ || pExpr->op==TK_LE || pExpr->op==TK_GE ); - switch( pExpr->op ){ - case TK_EQ: - case TK_IS: - opTest = OP_IfNot; - opCmp = OP_Eq; - break; - - case TK_NE: - case TK_ISNOT: - opTest = OP_If; - opCmp = OP_Ne; - break; - - case TK_LT: - case TK_LE: - case TK_GT: - case TK_GE: - opCmp = OP_Cmp; - opTest = OP_CmpTest; - p3 = pExpr->op; - break; + if( pExpr->op==TK_EQ || pExpr->op==TK_NE ){ + regTmp = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp2(v, OP_Integer, (pExpr->op==TK_EQ), dest); } - regLeft = exprVectorSubselect(pParse, pLeft); - regRight = exprVectorSubselect(pParse, pRight); - if( pParse->nErr ) return; + regLeft = exprCodeSubselect(pParse, pLeft); + regRight = exprCodeSubselect(pParse, pRight); for(i=0; ix.pSelect->pEList->a[i].pExpr; - r1 = regLeft+i; - }else{ - pL = pLeft->x.pList->a[i].pExpr; - r1 = sqlite3ExprCodeTemp(pParse, pL, ®Free1); + r1 = exprVectorRegister(pParse, pLeft, i, regLeft, &pL, ®Free1); + r2 = exprVectorRegister(pParse, pRight, i, regRight, &pR, ®Free2); + + switch( pExpr->op ){ + case TK_IS: + codeCompare( + pParse, pL, pR, OP_Eq, r1, r2, dest, SQLITE_STOREP2|SQLITE_NULLEQ + ); + sqlite3VdbeAddOp3(v, OP_IfNot, dest, addr, 1); + VdbeCoverage(v); + break; + + case TK_ISNOT: + codeCompare( + pParse, pL, pR, OP_Ne, r1, r2, dest, SQLITE_STOREP2|SQLITE_NULLEQ + ); + sqlite3VdbeAddOp3(v, OP_If, dest, addr, 1); + VdbeCoverage(v); + break; + + case TK_EQ: + case TK_NE: + codeCompare(pParse, pL, pR, OP_Cmp, r1, r2, regTmp,SQLITE_STOREP2|p5); + sqlite3VdbeAddOp4Int( + v, OP_CmpTest, regTmp, addr, dest, pExpr->op==TK_NE + ); + VdbeCoverage(v); + break; + + case TK_LT: + case TK_LE: + case TK_GT: + case TK_GE: + codeCompare(pParse, pL, pR, OP_Cmp, r1, r2, dest, SQLITE_STOREP2|p5); + sqlite3VdbeAddOp4Int(v, OP_CmpTest, dest, addr, 0, pExpr->op); + VdbeCoverage(v); + break; } - if( regRight ){ - pR = pRight->x.pSelect->pEList->a[i].pExpr; - r2 = regRight+i; - }else{ - pR = pRight->x.pList->a[i].pExpr; - r2 = sqlite3ExprCodeTemp(pParse, pR, ®Free1); - } - - codeCompare(pParse, pL, pR, opCmp, r1, r2, dest, SQLITE_STOREP2 | p5); - sqlite3VdbeAddOp3(v, opTest, dest, addr, p3); sqlite3ReleaseTempReg(pParse, regFree1); sqlite3ReleaseTempReg(pParse, regFree2); if( i ) sqlite3ExprCachePop(pParse); } + + sqlite3ReleaseTempReg(pParse, regTmp); } sqlite3VdbeResolveLabel(v, addr); diff --git a/src/vdbe.c b/src/vdbe.c index e2e1afb504..054f1997f3 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -1961,6 +1961,15 @@ case OP_Cast: { /* in1 */ ** This works just like the Lt opcode except that the jump is taken if ** the content of register P3 is greater than or equal to the content of ** register P1. See the Lt opcode for additional information. +** +** Opcode: Cmp P1 P2 P3 P4 P5 +** Synopsis: P2 = cmp(P1, P3) +** +** The SQLITE_STOREP2 flag must be set for this opcode. It compares the +** values in registers P1 and P3 and stores the result of the comparison +** in register P2. The results is NULL if either of the two operands are +** NULL. Otherwise, it is an integer value less than zero, zero or greater +** than zero if P3 is less than, equal to or greater than P1, respectively. */ case OP_Cmp: /* in1, in3 */ case OP_Eq: /* same as TK_EQ, jump, in1, in3 */ @@ -1974,6 +1983,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ u16 flags1; /* Copy of initial value of pIn1->flags */ u16 flags3; /* Copy of initial value of pIn3->flags */ + assert( pOp->opcode!=OP_Cmp || (pOp->p5 & SQLITE_STOREP2) ); pIn1 = &aMem[pOp->p1]; pIn3 = &aMem[pOp->p3]; flags1 = pIn1->flags; @@ -3875,16 +3885,21 @@ seek_not_found: break; } -/* Opcode: CmpTest P1 P2 P3 * * +/* Opcode: CmpTest P1 P2 P3 P4 * ** ** P2 is a jump destination. Register P1 is guaranteed to contain either -** an integer value or a NULL. The jump is taken if P1 contains any value -** other than 0 (i.e. NULL does cause a jump). -** -** If P1 is not NULL, its value is modified to integer value 0 or 1 -** according to the value of the P3 operand: +** an integer value or a NULL. ** -** P3 modification +** If P3 is non-zero, it identifies an output register. In this case, if +** P1 is NULL, P3 is also set to NULL. Or, if P1 is any integer value +** other than 0, P3 is set to the value of P4 and a jump to P2 is taken. +** +** If P3 is 0, the jump is taken if P1 contains any value other than 0 (i.e. +** NULL does cause a jump). Additionally, if P1 is not NULL, its value is +** modified to integer value 0 or 1 according to the value of the P4 integer +** operand: +** +** P4 modification ** -------------------------- ** OP_Lt (P1 = (P1 < 0)) ** OP_Le (P1 = (P1 <= 0)) @@ -3893,18 +3908,34 @@ seek_not_found: */ case OP_CmpTest: { /* in1, jump */ int bJump; - pIn1 = &aMem[pOp->p1]; - if( (pIn1->flags & MEM_Int) ){ - bJump = (pIn1->u.i!=0); - switch( pOp->p3 ){ - case OP_Lt: pIn1->u.i = (pIn1->u.i < 0); break; - case OP_Le: pIn1->u.i = (pIn1->u.i <= 0); break; - case OP_Gt: pIn1->u.i = (pIn1->u.i > 0); break; - default: assert( pOp->p3==OP_Ge ); pIn1->u.i = (pIn1->u.i >= 0); break; + + if( pOp->p3 ){ + bJump = 0; + if( pIn1->flags & MEM_Null ){ + memAboutToChange(p, &aMem[pOp->p3]); + MemSetTypeFlag(&aMem[pOp->p3], MEM_Null); + }else if( pIn1->u.i!=0 ){ + memAboutToChange(p, &aMem[pOp->p3]); + MemSetTypeFlag(&aMem[pOp->p3], MEM_Int); + aMem[pOp->p3].u.i = pOp->p4.i; + bJump = 1; } }else{ - bJump = 1; + if( (pIn1->flags & MEM_Int) ){ + bJump = (pIn1->u.i!=0); + switch( pOp->p4.i ){ + case OP_Lt: pIn1->u.i = (pIn1->u.i < 0); break; + case OP_Le: pIn1->u.i = (pIn1->u.i <= 0); break; + case OP_Gt: pIn1->u.i = (pIn1->u.i > 0); break; + default: + assert( pOp->p4.i==OP_Ge ); + pIn1->u.i = (pIn1->u.i >= 0); + break; + } + }else{ + bJump = 1; + } } if( bJump ) goto jump_to_p2; diff --git a/test/rowvalue.test b/test/rowvalue.test index 3989c39513..efa870009f 100644 --- a/test/rowvalue.test +++ b/test/rowvalue.test @@ -28,6 +28,9 @@ foreach {tn v1 v2 eq ne is isnot} { 3 "1, 2, NULL" "1, 2, 3" {} {} 0 1 4 "1, 2, NULL" "1, 2, NULL" {} {} 1 0 5 "NULL, NULL, NULL" "NULL, NULL, NULL" {} {} 1 0 + + 6 "1, NULL, 1" "1, 1, 1" {} {} 0 1 + 7 "1, NULL, 1" "1, 1, 2" 0 1 0 1 } { do_execsql_test 1.$tn.eq "SELECT ($v1) == ($v2)" [list $eq] do_execsql_test 1.$tn.ne "SELECT ($v1) != ($v2)" [list $ne] From 32c83c8b9e4fc3a5af99856ae6db15694dbe0414 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 1 Aug 2016 14:35:48 +0000 Subject: [PATCH 0642/1484] Avoid making unnecessary changes to the signatures of the sqlite3_auto_extension() and sqlite3_cancel_auto_extension() interfaces. FossilOrigin-Name: b6ea2f21f602031ef4dbd47462ac11b0bb0d5de6 --- manifest | 28 ++++++++++++++-------------- manifest.uuid | 2 +- src/loadext.c | 4 ++-- src/sqlite.h.in | 23 ++++++++++++++--------- src/sqlite3ext.h | 7 ++----- src/test1.c | 1 - src/test_autoext.c | 12 ++++++------ src/test_func.c | 10 +++++----- src/test_multiplex.c | 2 +- src/test_thread.c | 2 +- 10 files changed, 46 insertions(+), 45 deletions(-) diff --git a/manifest b/manifest index 9657203bbb..76e84155ee 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\scompiler\swarning\sseen\swith\sMSVC. -D 2016-07-30T18:54:54.989 +C Avoid\smaking\sunnecessary\schanges\sto\sthe\ssignatures\sof\sthe\nsqlite3_auto_extension()\sand\ssqlite3_cancel_auto_extension()\sinterfaces. +D 2016-08-01T14:35:48.519 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 3340e479e5221f06c3d61726f8f7efff885e4233 @@ -347,7 +347,7 @@ F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4 F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da F src/insert.c 8f4e9fcbd8e95e85f15647ba8b413b18d556ec2b F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e -F src/loadext.c c3c2a37e4ce940d17c73971738754d412c79e09d +F src/loadext.c 0ac0030646e4ec3c775b5c40d1818ec9a7e1ca95 F src/main.c 16c1b2114eae8804caf3a8de8cb47bf2c6d83ad3 F src/malloc.c 1443d1ad95d67c21d77af7ae3f44678252f0efec F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 @@ -385,15 +385,15 @@ F src/resolve.c cca3aa77b95706df5d635a2141a4d1de60ae6598 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c f3c6e9065fb34f6a23af27ec7f1f717ffbfc2ee4 F src/shell.c 9351fc6de11e1d908648c0a92d85627138e3dee5 -F src/sqlite.h.in cd10e4206b91c4bf03f121ab9209a14af0b48f14 +F src/sqlite.h.in b41cf2d1deb59db570f20e8ed7ade4716c6dc613 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 -F src/sqlite3ext.h f4206565eb5f5cef9a1544d32a076b5f47af1bdc +F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae F src/sqliteInt.h d6f221a5bd572df935140beda82f357c2185a77c F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c 5b18f9526900f61189ab0b83f1ef41d9f871a2ab F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 F src/tclsqlite.c bdae822f21e229b6daced15938b6343ce44ef454 -F src/test1.c 906a04b649c7139e943193a3905d583e325c30c7 +F src/test1.c 0a0909cf7962d2359db329c08d15b90b4b6e724f F src/test2.c b7174313e993754303a8b33c43df7c44b46857ab F src/test3.c 1339a40be39650ae83894b6578f971dc7f96ea8a F src/test4.c 18ec393bb4d0ad1de729f0b94da7267270f3d8e6 @@ -403,7 +403,7 @@ F src/test7.c 5612e9aecf934d6df7bba6ce861fdf5ba5456010 F src/test8.c 4f4904721167b32f7a4fa8c7b32a07a673d6cc86 F src/test9.c 12e5ba554d2d1cbe0158f6ab3f7ffcd7a86ee4e5 F src/test_async.c 195ab49da082053fdb0f949c114b806a49ca770a -F src/test_autoext.c cc69375c006b7bac6094ec602f52525350fd5229 +F src/test_autoext.c 915d245e736652a219a907909bb6710f0d587871 F src/test_backup.c bf5da90c9926df0a4b941f2d92825a01bbe090a0 F src/test_bestindex.c d23f80d334c59662af69191854c76b8d3d0c8c96 F src/test_blob.c a0f7ad49a0c9d4b72f693fe2a71c58d7e507174d @@ -412,7 +412,7 @@ F src/test_config.c 4d3d4a886416f369771d69a6dba926866deda788 F src/test_demovfs.c a0c3bdd45ed044115c2c9f7779e56eafff18741e F src/test_devsym.c 4e58dec2602d8e139ca08659f62a62450587cb58 F src/test_fs.c ac62ce7d5c0c23aa6932891cad5746945564c91c -F src/test_func.c 6f34b19ae097e3cf0b0fe5d6904cb9900e67f2ff +F src/test_func.c a2b4993da973b0ea60dd5d51a7066238ede8c329 F src/test_hexio.c 1d4469ca61ab202a1fcec6543f584d2407205e8d F src/test_init.c 4413c211a94b62157ca4c145b3f27c497f03c664 F src/test_intarray.c 988fc61cb0ff539f4172c0d95f15287c92516f64 @@ -420,7 +420,7 @@ F src/test_intarray.h f3b7672f5d1056eac563c0d6ea8480a660b1475c F src/test_journal.c d3b83f2bcb7792c709e57abddc456a2b1818643a F src/test_loadext.c 337056bae59f80b9eb00ba82088b39d0f4fe6dfd F src/test_malloc.c c05f6c40bd6c8bfe5f1718212f81fd5687f91766 -F src/test_multiplex.c 371d3874fd6365f18468d1c131e153e5c9abe95e +F src/test_multiplex.c 7c5b218d855cd0505a43185d55283b3fc257c8da F src/test_multiplex.h 5436d03f2d0501d04f3ed50a75819e190495b635 F src/test_mutex.c 7f4337ba23ee6b1d2ec81c189653608cb069926a F src/test_onefile.c 416f87a28d6d673352d33fc4b1c7d39db878e50f @@ -435,7 +435,7 @@ F src/test_sqllog.c 0d138a8180a312bf996b37fa66da5c5799d4d57b F src/test_superlock.c 4839644b9201da822f181c5bc406c0b2385f672e F src/test_syscall.c 1073306ba2e9bfc886771871a13d3de281ed3939 F src/test_tclvar.c df9fe1213c2634687a9ca0b0bec0d2119d359ae3 -F src/test_thread.c 89f0e47dac64e7ab15ca0a4fc87e0882c495ae21 +F src/test_thread.c 911d15fb14e19c0c542bdc8aabf981c2f10a4858 F src/test_vfs.c f0186261a24de2671d080bcd8050732f0cb64f6e F src/test_vfstrace.c bab9594adc976cbe696ff3970728830b4c5ed698 F src/test_windirent.c 8f5fada630348558d5745b334702f301da1ffc61 @@ -1508,7 +1508,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 9fae75c08b7d3b3e13734193ad8398ef6971cbac -R 20430021b7d310aa0691f2edba10b981 -U mistachkin -Z 1a5ea8a378b7c26f7d4d45026b5640de +P 390a38a142d36d2c57b3f21aab72edcde450125d +R 65e7d16d0e1a0cbde00eb39308479bd3 +U drh +Z ed98f4241335140747349246aea331ad diff --git a/manifest.uuid b/manifest.uuid index dedb9c60d3..6b01792124 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -390a38a142d36d2c57b3f21aab72edcde450125d \ No newline at end of file +b6ea2f21f602031ef4dbd47462ac11b0bb0d5de6 \ No newline at end of file diff --git a/src/loadext.c b/src/loadext.c index 163141bf73..26ba7e6491 100644 --- a/src/loadext.c +++ b/src/loadext.c @@ -676,7 +676,7 @@ static SQLITE_WSD struct sqlite3AutoExtList { ** loaded by every new database connection. */ int sqlite3_auto_extension( - int (*xInit)(sqlite3 *, char **, const sqlite3_api_routines *) + void (*xInit)(void) ){ int rc = SQLITE_OK; #ifndef SQLITE_OMIT_AUTOINIT @@ -723,7 +723,7 @@ int sqlite3_auto_extension( ** was not on the list. */ int sqlite3_cancel_auto_extension( - int (*xInit)(sqlite3 *, char **, const sqlite3_api_routines *) + void (*xInit)(void) ){ #if SQLITE_THREADSAFE sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 9d28cdc05a..27ca6ef4ad 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -1045,6 +1045,16 @@ struct sqlite3_io_methods { */ typedef struct sqlite3_mutex sqlite3_mutex; +/* +** CAPI3REF: Loadable Extension Thunk +** +** A pointer to the opaque sqlite3_api_routines structure is passed as +** the third parameter to entry points of [loadable extensions]. This +** structure must be typedefed in order to work around compiler warnings +** on some platforms. +*/ +typedef struct sqlite3_api_routines sqlite3_api_routines; + /* ** CAPI3REF: OS Interface Object ** @@ -2242,7 +2252,7 @@ int sqlite3_complete16(const void *sql); ** A busy handler must not close the database connection ** or [prepared statement] that invoked the busy handler. */ -int sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*); +int sqlite3_busy_handler(sqlite3*,int(*)(void*,int),void*); /* ** CAPI3REF: Set A Busy Timeout @@ -5681,7 +5691,7 @@ int sqlite3_enable_load_extension(sqlite3 *db, int onoff); ** ** ^(Even though the function prototype shows that xEntryPoint() takes ** no arguments and returns void, SQLite invokes xEntryPoint() with three -** arguments and expects and integer result as if the signature of the +** arguments and expects an integer result as if the signature of the ** entry point where as follows: ** **
    @@ -5707,10 +5717,7 @@ int sqlite3_enable_load_extension(sqlite3 *db, int onoff);
     ** See also: [sqlite3_reset_auto_extension()]
     ** and [sqlite3_cancel_auto_extension()]
     */
    -typedef struct sqlite3_api_routines sqlite3_api_routines;
    -int sqlite3_auto_extension(
    -  int (*xEntryPoint)(sqlite3 *, char **, const sqlite3_api_routines *)
    -);
    +int sqlite3_auto_extension(void(*xEntryPoint)(void));
     
     /*
     ** CAPI3REF: Cancel Automatic Extension Loading
    @@ -5722,9 +5729,7 @@ int sqlite3_auto_extension(
     ** unregistered and it returns 0 if X was not on the list of initialization
     ** routines.
     */
    -int sqlite3_cancel_auto_extension(
    -  int (*xEntryPoint)(sqlite3 *, char **, const sqlite3_api_routines *)
    -);
    +int sqlite3_cancel_auto_extension(void(*xEntryPoint)(void));
     
     /*
     ** CAPI3REF: Reset Automatic Extension Loading
    diff --git a/src/sqlite3ext.h b/src/sqlite3ext.h
    index 689a5c4856..ce87e74690 100644
    --- a/src/sqlite3ext.h
    +++ b/src/sqlite3ext.h
    @@ -19,8 +19,6 @@
     #define SQLITE3EXT_H
     #include "sqlite3.h"
     
    -typedef struct sqlite3_api_routines sqlite3_api_routines;
    -
     /*
     ** The following structure holds pointers to all of the SQLite API
     ** routines.
    @@ -251,13 +249,12 @@ struct sqlite3_api_routines {
       char *(*vsnprintf)(int,char*,const char*,va_list);
       int (*wal_checkpoint_v2)(sqlite3*,const char*,int,int*,int*);
       /* Version 3.8.7 and later */
    -  int (*auto_extension)(int(*)(sqlite3*,char**,const sqlite3_api_routines*));
    +  int (*auto_extension)(void(*)(void));
       int (*bind_blob64)(sqlite3_stmt*,int,const void*,sqlite3_uint64,
                          void(*)(void*));
       int (*bind_text64)(sqlite3_stmt*,int,const char*,sqlite3_uint64,
                           void(*)(void*),unsigned char);
    -  int (*cancel_auto_extension)(int(*)(sqlite3*,char**,
    -                                       const sqlite3_api_routines*));
    +  int (*cancel_auto_extension)(void(*)(void));
       int (*load_extension)(sqlite3*,const char*,const char*,char**);
       void *(*malloc64)(sqlite3_uint64);
       sqlite3_uint64 (*msize)(void*);
    diff --git a/src/test1.c b/src/test1.c
    index ec6d8ecff3..aced552173 100644
    --- a/src/test1.c
    +++ b/src/test1.c
    @@ -6742,7 +6742,6 @@ static int SQLITE_TCLAPI optimization_control(
       return TCL_OK;
     }
     
    -typedef struct sqlite3_api_routines sqlite3_api_routines;
     /*
     **     load_static_extension DB NAME ...
     **
    diff --git a/src/test_autoext.c b/src/test_autoext.c
    index f962a51d6b..e23e41a08a 100644
    --- a/src/test_autoext.c
    +++ b/src/test_autoext.c
    @@ -100,7 +100,7 @@ static int SQLITE_TCLAPI autoExtSqrObjCmd(
       int objc,
       Tcl_Obj *CONST objv[]
     ){
    -  int rc = sqlite3_auto_extension(sqr_init);
    +  int rc = sqlite3_auto_extension((void(*)(void))sqr_init);
       Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
       return SQLITE_OK;
     }
    @@ -116,7 +116,7 @@ static int SQLITE_TCLAPI cancelAutoExtSqrObjCmd(
       int objc,
       Tcl_Obj *CONST objv[]
     ){
    -  int rc = sqlite3_cancel_auto_extension(sqr_init);
    +  int rc = sqlite3_cancel_auto_extension((void(*)(void))sqr_init);
       Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
       return SQLITE_OK;
     }
    @@ -132,7 +132,7 @@ static int SQLITE_TCLAPI autoExtCubeObjCmd(
       int objc,
       Tcl_Obj *CONST objv[]
     ){
    -  int rc = sqlite3_auto_extension(cube_init);
    +  int rc = sqlite3_auto_extension((void(*)(void))cube_init);
       Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
       return SQLITE_OK;
     }
    @@ -148,7 +148,7 @@ static int SQLITE_TCLAPI cancelAutoExtCubeObjCmd(
       int objc,
       Tcl_Obj *CONST objv[]
     ){
    -  int rc = sqlite3_cancel_auto_extension(cube_init);
    +  int rc = sqlite3_cancel_auto_extension((void(*)(void))cube_init);
       Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
       return SQLITE_OK;
     }
    @@ -164,7 +164,7 @@ static int SQLITE_TCLAPI autoExtBrokenObjCmd(
       int objc,
       Tcl_Obj *CONST objv[]
     ){
    -  int rc = sqlite3_auto_extension(broken_init);
    +  int rc = sqlite3_auto_extension((void(*)(void))broken_init);
       Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
       return SQLITE_OK;
     }
    @@ -180,7 +180,7 @@ static int SQLITE_TCLAPI cancelAutoExtBrokenObjCmd(
       int objc,
       Tcl_Obj *CONST objv[]
     ){
    -  int rc = sqlite3_cancel_auto_extension(broken_init);
    +  int rc = sqlite3_cancel_auto_extension((void(*)(void))broken_init);
       Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
       return SQLITE_OK;
     }
    diff --git a/src/test_func.c b/src/test_func.c
    index 6bfa862464..26f0d369ef 100644
    --- a/src/test_func.c
    +++ b/src/test_func.c
    @@ -25,7 +25,6 @@
     #include "sqliteInt.h"
     #include "vdbeInt.h"
     
    -
     /*
     ** Allocate nByte bytes of space using sqlite3_malloc(). If the
     ** allocation fails, call sqlite3_result_error_nomem() to notify
    @@ -704,9 +703,9 @@ static int SQLITE_TCLAPI autoinstall_test_funcs(
       Tcl_Obj *CONST objv[]
     ){
       extern int Md5_Register(sqlite3 *, char **, const sqlite3_api_routines *);
    -  int rc = sqlite3_auto_extension(registerTestFunctions);
    +  int rc = sqlite3_auto_extension((void(*)(void))registerTestFunctions);
       if( rc==SQLITE_OK ){
    -    rc = sqlite3_auto_extension(Md5_Register);
    +    rc = sqlite3_auto_extension((void(*)(void))Md5_Register);
       }
       Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
       return TCL_OK;
    @@ -791,6 +790,7 @@ abuse_err:
       return TCL_ERROR;
     }
     
    +
     /*
     ** Register commands with the TCL interpreter.
     */
    @@ -809,7 +809,7 @@ int Sqlitetest_func_Init(Tcl_Interp *interp){
         Tcl_CreateObjCommand(interp, aObjCmd[i].zName, aObjCmd[i].xProc, 0, 0);
       }
       sqlite3_initialize();
    -  sqlite3_auto_extension(registerTestFunctions);
    -  sqlite3_auto_extension(Md5_Register);
    +  sqlite3_auto_extension((void(*)(void))registerTestFunctions);
    +  sqlite3_auto_extension((void(*)(void))Md5_Register);
       return TCL_OK;
     }
    diff --git a/src/test_multiplex.c b/src/test_multiplex.c
    index a7820975d6..1027aa1326 100644
    --- a/src/test_multiplex.c
    +++ b/src/test_multiplex.c
    @@ -1197,7 +1197,7 @@ int sqlite3_multiplex_initialize(const char *zOrigVfsName, int makeDefault){
       gMultiplex.sIoMethodsV2.xShmUnmap = multiplexShmUnmap;
       sqlite3_vfs_register(&gMultiplex.sThisVfs, makeDefault);
     
    -  sqlite3_auto_extension(multiplexFuncInit);
    +  sqlite3_auto_extension((void(*)(void))multiplexFuncInit);
     
       return SQLITE_OK;
     }
    diff --git a/src/test_thread.c b/src/test_thread.c
    index 927fee1f56..20b4cf148b 100644
    --- a/src/test_thread.c
    +++ b/src/test_thread.c
    @@ -280,7 +280,7 @@ static int SQLITE_TCLAPI sqlthread_open(
       const char *zFilename;
       sqlite3 *db;
       char zBuf[100];
    -  extern int Md5_Register(sqlite3 *, char **, const sqlite3_api_routines *);
    +  extern int Md5_Register(sqlite3*,char**,const sqlite3_api_routines*);
     
       UNUSED_PARAMETER(clientData);
       UNUSED_PARAMETER(objc);
    
    From 8ef24b8debb430e0f22d65ffeba018e576be4ee6 Mon Sep 17 00:00:00 2001
    From: drh 
    Date: Mon, 1 Aug 2016 15:00:00 +0000
    Subject: [PATCH 0643/1484] Update releasetest.tcl to automatically do one
     round of tests with USE_STDCALL=1 when running on Windows with MSVC.
    
    FossilOrigin-Name: a6a112de485eb9d15f6fa75568dcb876f00abb64
    ---
     manifest             | 12 ++++++------
     manifest.uuid        |  2 +-
     test/releasetest.tcl |  9 +++++++++
     3 files changed, 16 insertions(+), 7 deletions(-)
    
    diff --git a/manifest b/manifest
    index 76e84155ee..67dc23aac2 100644
    --- a/manifest
    +++ b/manifest
    @@ -1,5 +1,5 @@
    -C Avoid\smaking\sunnecessary\schanges\sto\sthe\ssignatures\sof\sthe\nsqlite3_auto_extension()\sand\ssqlite3_cancel_auto_extension()\sinterfaces.
    -D 2016-08-01T14:35:48.519
    +C Update\sreleasetest.tcl\sto\sautomatically\sdo\sone\sround\sof\stests\swith\nUSE_STDCALL=1\swhen\srunning\son\sWindows\swith\sMSVC.
    +D 2016-08-01T15:00:00.879
     F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db
     F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
     F Makefile.msc 3340e479e5221f06c3d61726f8f7efff885e4233
    @@ -1010,7 +1010,7 @@ F test/rdonly.test 64e2696c322e3538df0b1ed624e21f9a23ed9ff8
     F test/regexp1.test 497ea812f264d12b6198d6e50a76be4a1973a9d8
     F test/regexp2.test aa7ffcc21350007a78361b82bcf3b74d12227144
     F test/reindex.test 44edd3966b474468b823d481eafef0c305022254
    -F test/releasetest.tcl 3a66c7b8fbe55bcd97c907217c3d812d1d3c6b93
    +F test/releasetest.tcl 53560b838b79c468ec9973e0dfa3d8892628887f
     F test/resolver01.test f4022acafda7f4d40eca94dbf16bc5fc4ac30ceb
     F test/rollback.test 458fe73eb3ffdfdf9f6ba3e9b7350a6220414dea
     F test/rollback2.test 8435d6ff0f13f51d2a4181c232e706005fa90fc5
    @@ -1508,7 +1508,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
     F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
     F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
     F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
    -P 390a38a142d36d2c57b3f21aab72edcde450125d
    -R 65e7d16d0e1a0cbde00eb39308479bd3
    +P b6ea2f21f602031ef4dbd47462ac11b0bb0d5de6
    +R 8c53f29684f1c5a6b809ef407293ad87
     U drh
    -Z ed98f4241335140747349246aea331ad
    +Z efd5176c6b70600d1d70a952504ac1b9
    diff --git a/manifest.uuid b/manifest.uuid
    index 6b01792124..45a5d2cc7d 100644
    --- a/manifest.uuid
    +++ b/manifest.uuid
    @@ -1 +1 @@
    -b6ea2f21f602031ef4dbd47462ac11b0bb0d5de6
    \ No newline at end of file
    +a6a112de485eb9d15f6fa75568dcb876f00abb64
    \ No newline at end of file
    diff --git a/test/releasetest.tcl b/test/releasetest.tcl
    index e13a3d7340..f670c8bef4 100644
    --- a/test/releasetest.tcl
    +++ b/test/releasetest.tcl
    @@ -58,6 +58,10 @@ array set ::Configs [strip_comments {
         -DSQLITE_ENABLE_STAT4
         --enable-session
       }
    +  "Stdcall" {
    +    -DUSE_STDCALL=1
    +    -O2
    +  }
       "Have-Not" {
         # The "Have-Not" configuration sets all possible -UHAVE_feature options
         # in order to verify that the code works even on platforms that lack
    @@ -298,10 +302,12 @@ array set ::Platforms [strip_comments {
         "Apple"                   "threadtest fulltest"
       }
       "Windows NT-intel" {
    +    "Stdcall"                 test
         "Have-Not"                test
         "Default"                 "mptest fulltestonly"
       }
       "Windows NT-amd64" {
    +    "Stdcall"                 test
         "Have-Not"                test
         "Default"                 "mptest fulltestonly"
       }
    @@ -725,6 +731,9 @@ proc makeCommand { targets makeOpts cflags opts } {
         set nmakeDir [file nativename $::SRCDIR]
         set nmakeFile [file nativename [file join $nmakeDir Makefile.msc]]
         lappend result nmake /f $nmakeFile TOP=$nmakeDir
    +    if {[regexp {USE_STDCALL=1} $cflags]} {
    +      lappend result USE_STDCALL=1
    +    }
       } else {
         lappend result make
       }
    
    From 870a0705feb00a9c60c3442431beeeff37ca0c6b Mon Sep 17 00:00:00 2001
    From: dan 
    Date: Mon, 1 Aug 2016 16:37:43 +0000
    Subject: [PATCH 0644/1484] Fix a problem with IN(...) constraints where the
     LHS is a sub-select that is an aggregate query.
    
    FossilOrigin-Name: 1f4dba87da4a44ad26223ad965731164c0d9bad9
    ---
     manifest           | 18 +++++-----
     manifest.uuid      |  2 +-
     src/expr.c         | 86 +++++++++++++++++++++-------------------------
     src/select.c       | 41 +++-------------------
     src/whereexpr.c    | 24 +++++++++----
     test/rowvalue.test |  6 ++++
     6 files changed, 78 insertions(+), 99 deletions(-)
    
    diff --git a/manifest b/manifest
    index 6cdc700a0e..ea0371ab19 100644
    --- a/manifest
    +++ b/manifest
    @@ -1,5 +1,5 @@
    -C Fix\sproblems\swith\svector\s==\scomparisons\sand\sNULL\svalues.
    -D 2016-07-30T21:02:33.694
    +C Fix\sa\sproblem\swith\sIN(...)\sconstraints\swhere\sthe\sLHS\sis\sa\ssub-select\sthat\sis\san\saggregate\squery.
    +D 2016-08-01T16:37:43.292
     F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db
     F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
     F Makefile.msc 3340e479e5221f06c3d61726f8f7efff885e4233
    @@ -337,7 +337,7 @@ F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7
     F src/date.c 1cc9fb516ec9932c6fd4d2a0d2f8bc4480145c39
     F src/dbstat.c 4f6f7f52b49beb9636ffbd517cfe44a402ba4ad0
     F src/delete.c 4aba4214a377ce8ddde2d2e609777bcc8235200f
    -F src/expr.c f33dcbaf364c5c54a2f1aab7cf1de9fbd0c88f3d
    +F src/expr.c cdde4d3ed7f7cf1911b961141d61a4f06e6f7ebd
     F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
     F src/fkey.c bc4145347595b7770f9a598cff1c848302cf5413
     F src/func.c 61a4114cf7004f10c542cfabbab9f2bcb9033045
    @@ -383,7 +383,7 @@ F src/printf.c a5f0ca08ddede803c241266abb46356ec748ded1
     F src/random.c ba2679f80ec82c4190062d756f22d0c358180696
     F src/resolve.c cca3aa77b95706df5d635a2141a4d1de60ae6598
     F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac
    -F src/select.c 0115f5d222f5cf9b5511ec4072088417354d738a
    +F src/select.c bb2a1583fddbf8c2bbba2abbe411882b89e14a12
     F src/shell.c 9351fc6de11e1d908648c0a92d85627138e3dee5
     F src/sqlite.h.in cd10e4206b91c4bf03f121ab9209a14af0b48f14
     F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
    @@ -466,7 +466,7 @@ F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354
     F src/where.c 61db3a409b6b89383abd0e746965da424676f8ea
     F src/whereInt.h 14dd243e13b81cbb0a66063d38b70f93a7d6e613
     F src/wherecode.c 6131be0cb19702665c3decbf243dae58ecc15937
    -F src/whereexpr.c 82196ee82ca9de9d133ae742786bb89cf6ee890d
    +F src/whereexpr.c 3f5d76b585ab193bb9ae15aadb8deb94346c93e7
     F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
     F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd
     F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
    @@ -1018,7 +1018,7 @@ F test/rollbackfault.test 0e646aeab8840c399cfbfa43daab46fd609cf04a
     F test/rowallock.test 3f88ec6819489d0b2341c7a7528ae17c053ab7cc
     F test/rowhash.test 0bc1d31415e4575d10cacf31e1a66b5cc0f8be81
     F test/rowid.test 5b7509f384f4f6fae1af3c8c104c8ca299fea18d
    -F test/rowvalue.test f4c06c37d8e3212156435495da453e12bdeef7e5
    +F test/rowvalue.test 5f00f33fb1aa9259b35b44261b651361580d5a34
     F test/rowvalue2.test 8d5dfe75b8f4d1868a2f91f0356f20d36cba64ff
     F test/rowvalue3.test 5127afb4414bf62546161497c04840c46e371770
     F test/rowvalue4.test 4480898d62d6813e3e38d9d38c02b9a0be5f94be
    @@ -1512,7 +1512,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
     F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
     F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
     F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
    -P 63ae02d084a332250ff6fd8d8c80e53bf5422a68
    -R 27dbfd24654b70fef0137ceb387adc85
    +P 059d0d05354e6efab7892c97b339ffa0b5303587
    +R b99b47b8f7c934c8cffa76149cc68eeb
     U dan
    -Z 07f670f92b12ec2bcc84d4a9aa33539d
    +Z 9e6109253ab0bc1e8a84d8639e4d1848
    diff --git a/manifest.uuid b/manifest.uuid
    index f6c7658784..7f308a68d6 100644
    --- a/manifest.uuid
    +++ b/manifest.uuid
    @@ -1 +1 @@
    -059d0d05354e6efab7892c97b339ffa0b5303587
    \ No newline at end of file
    +1f4dba87da4a44ad26223ad965731164c0d9bad9
    \ No newline at end of file
    diff --git a/src/expr.c b/src/expr.c
    index 5acce2f0c7..3bbd015fd1 100644
    --- a/src/expr.c
    +++ b/src/expr.c
    @@ -309,6 +309,15 @@ static int codeCompare(
       return addr;
     }
     
    +/*
    +** Return true if expression pExpr is a vector, or false otherwise.
    +*/
    +int sqlite3ExprIsVector(Expr *pExpr){
    +  return ( (pExpr->op==TK_VECTOR)
    +        || (pExpr->op==TK_SELECT && pExpr->x.pSelect->pEList->nExpr>1)
    +  );
    +}
    +
     /*
     ** If the expression passed as the only argument is of type TK_VECTOR 
     ** return the number of expressions in the vector. Or, if the expression
    @@ -323,30 +332,23 @@ int sqlite3ExprVectorSize(Expr *pExpr){
       return pExpr->x.pList->nExpr;
     }
     
    -/*
    -** Return true if expression pExpr is a vector, or false otherwise.
    -*/
    -int sqlite3ExprIsVector(Expr *pExpr){
    -  return (
    -      pExpr->op==TK_VECTOR 
    -   || (pExpr->op==TK_SELECT && pExpr->x.pSelect->pEList->nExpr>1)
    -  );
    -}
    -
     /*
     ** If the expression passed as the first argument is a TK_VECTOR, return
     ** a pointer to the i'th field of the vector. Or, if the first argument
    -** points to a sub-select, return a pointer to the i'th returned column 
    -** value. Otherwise, return a copy of the first argument.
    +** points to a sub-select that returns more than one column, return a 
    +** pointer to the i'th returned column value. Otherwise, return a copy 
    +** of the first argument.
     */
     static Expr *exprVectorField(Expr *pVector, int i){
    -  if( sqlite3ExprIsVector(pVector)==0 ){
    -    assert( i==0 );
    -    return pVector;
    -  }else if( pVector->flags & EP_xIsSelect ){
    -    return pVector->x.pSelect->pEList->a[i].pExpr;
    +  assert( iop==TK_SELECT ){
    +      return pVector->x.pSelect->pEList->a[i].pExpr;
    +    }else{
    +      return pVector->x.pList->a[i].pExpr;
    +    }
       }
    -  return pVector->x.pList->a[i].pExpr;
    +  return pVector;
     }
     
     /*
    @@ -367,34 +369,37 @@ static int exprCodeSubselect(Parse *pParse, Expr *pExpr){
     
     /*
     ** Argument pVector points to a vector expression - either a TK_VECTOR
    -** or TK_SELECT that returns more than one column. This function generates
    -** code to evaluate expression iElem of the vector. The number of the
    -** register containing the result is returned. 
    +** or TK_SELECT that returns more than one column. This function returns
    +** the register number of a register that contains the value of
    +** element iField of the vector.
    +**
    +** If pVector is a TK_SELECT expression, then code for it must have 
    +** already been generated using the exprCodeSubselect() routine. In this
    +** case parameter regSelect should be the first in an array of registers
    +** containing the results of the sub-select. 
    +**
    +** If pVector is of type TK_VECTOR, then code for the requested field
    +** is generated. In this case (*pRegFree) may be set to the number of
    +** a temporary register to be freed by the caller before returning.
     **
     ** Before returning, output parameter (*ppExpr) is set to point to the
     ** Expr object corresponding to element iElem of the vector.
    -**
    -** If pVector is a TK_SELECT expression, then argument regSelect is 
    -** passed the first in an array of registers that contain the results
    -** of the sub-select. 
    -**
    -** If output parameter (*pRegFree) is set to a non-zero value by this
    -** function, it is the value of a temporary register that should be
    -** freed by the caller.
     */
     static int exprVectorRegister(
       Parse *pParse,                  /* Parse context */
       Expr *pVector,                  /* Vector to extract element from */
    -  int iElem,                      /* Element to extract from pVector */
    +  int iField,                     /* Field to extract from pVector */
       int regSelect,                  /* First in array of registers */
       Expr **ppExpr,                  /* OUT: Expression element */
       int *pRegFree                   /* OUT: Temp register to free */
     ){
    +  assert( pVector->op==TK_VECTOR || pVector->op==TK_SELECT );
    +  assert( (pVector->op==TK_VECTOR)==(regSelect==0) );
       if( regSelect ){
    -    *ppExpr = pVector->x.pSelect->pEList->a[iElem].pExpr;
    -     return regSelect+iElem;
    +    *ppExpr = pVector->x.pSelect->pEList->a[iField].pExpr;
    +     return regSelect+iField;
       }
    -  *ppExpr = pVector->x.pList->a[iElem].pExpr;
    +  *ppExpr = pVector->x.pList->a[iField].pExpr;
       return sqlite3ExprCodeTemp(pParse, *ppExpr, pRegFree);
     }
     
    @@ -416,10 +421,7 @@ static void codeVectorCompare(Parse *pParse, Expr *pExpr, int dest){
         sqlite3ErrorMsg(pParse, "invalid use of row value");
       }else{
         int p5 = (pExpr->op==TK_IS || pExpr->op==TK_ISNOT) ? SQLITE_NULLEQ : 0;
    -    int opCmp;
         int i;
    -    int p3 = 0;
    -    int p4 = 0;
         int regLeft = 0;
         int regRight = 0;
         int regTmp = 0;
    @@ -1777,13 +1779,6 @@ int sqlite3IsRowid(const char *z){
     ** a pointer to the SELECT statement.  If pX is not a SELECT statement,
     ** or if the SELECT statement needs to be manifested into a transient
     ** table, then return NULL.
    -** 
    -** If parameter bNullSensitive is 0, then this operation will be
    -** used in a context in which there is no difference between a result
    -** of 0 and one of NULL. For example:
    -**
    -**     ... WHERE (?,?) IN (SELECT ...)
    -**
     */
     #ifndef SQLITE_OMIT_SUBQUERY
     static Select *isCandidateForInOpt(Expr *pX){
    @@ -1957,10 +1952,9 @@ int sqlite3FindInIndex(
     
       /* If the RHS of this IN(...) operator is a SELECT, and if it matters 
       ** whether or not the SELECT result contains NULL values, check whether
    -  ** or not NULL is actuall possible (it may not be, for example, due 
    +  ** or not NULL is actually possible (it may not be, for example, due 
       ** to NOT NULL constraints in the schema). If no NULL values are possible,
    -  ** set prRhsHasNull to 0 before continuing.
    -  */
    +  ** set prRhsHasNull to 0 before continuing.  */
       if( prRhsHasNull && (pX->flags & EP_xIsSelect) ){
         int i;
         ExprList *pEList = pX->x.pSelect->pEList;
    diff --git a/src/select.c b/src/select.c
    index f49a5c1fed..fb7217c1b4 100644
    --- a/src/select.c
    +++ b/src/select.c
    @@ -659,30 +659,6 @@ static void codeDistinct(
       sqlite3ReleaseTempReg(pParse, r1);
     }
     
    -#ifndef SQLITE_OMIT_SUBQUERY
    -/*
    -** Generate an error message when a SELECT is used within a subexpression
    -** (example:  "a IN (SELECT * FROM table)") but it has more than 1 result
    -** column.  We do this in a subroutine because the error used to occur
    -** in multiple places.  (The error only occurs in one place now, but we
    -** retain the subroutine to minimize code disruption.)
    -*/
    -static int checkForMultiColumnSelectError(
    -  Parse *pParse,       /* Parse context. */
    -  SelectDest *pDest,   /* Destination of SELECT results */
    -  int nExpr            /* Number of result columns returned by SELECT */
    -){
    -  int eDest = pDest->eDest;
    -  if( 0 && nExpr>1 && eDest==SRT_Set ){
    -    sqlite3ErrorMsg(pParse, "only a single result allowed for "
    -       "a SELECT that is part of an expression");
    -    return 1;
    -  }else{
    -    return 0;
    -  }
    -}
    -#endif
    -
     /*
     ** This routine generates the code for the inside of the inner loop
     ** of a SELECT.
    @@ -919,13 +895,14 @@ static void selectInnerLoop(
         }
     
         /* If this is a scalar select that is part of an expression, then
    -    ** store the results in the appropriate memory cell and break out
    -    ** of the scan loop.
    +    ** store the results in the appropriate memory cell or array of 
    +    ** memory cells and break out of the scan loop.
         */
         case SRT_Mem: {
           assert( nResultCol==pDest->nSdst );
           if( pSort ){
    -        pushOntoSorter(pParse, pSort, p, regResult, regResult, nResultCol, nPrefixReg);
    +        pushOntoSorter(
    +            pParse, pSort, p, regResult, regResult, nResultCol, nPrefixReg);
           }else{
             assert( regResult==iParm );
             /* The LIMIT clause will jump out of the loop for us */
    @@ -4894,16 +4871,6 @@ int sqlite3Select(
       }
     #endif
     
    -
    -  /* If writing to memory or generating a set
    -  ** only a single column may be output.
    -  */
    -#ifndef SQLITE_OMIT_SUBQUERY
    -  if( checkForMultiColumnSelectError(pParse, pDest, p->pEList->nExpr) ){
    -    goto select_end;
    -  }
    -#endif
    -
       /* Try to flatten subqueries in the FROM clause up into the main query
       */
     #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
    diff --git a/src/whereexpr.c b/src/whereexpr.c
    index 5997da1e3a..33ce7edb38 100644
    --- a/src/whereexpr.c
    +++ b/src/whereexpr.c
    @@ -872,13 +872,25 @@ static int exprMightBeIndexed(
       return 0;
     }
     
    -static Expr *exprVectorExpr(Parse *pParse, Expr *p, int iField){
    +/*
    +** The expression passed as the second argument is a vector (either a 
    +** TK_VECTOR node or a TK_SELECT that returns more than one column). This
    +** function returns a pointer to a new expression object representing
    +** field iField of the vector.
    +**
    +** If pVector is of type TK_VECTOR, the returned object is just a copy of
    +** the iField'th element of the vector. Or, if pVector is of type TK_SELECT,
    +** the return value points to a new expression object of type 
    +** TK_SELECT_COLUMN.
    +*/
    +static Expr *exprExtractVectorField(Parse *pParse, Expr *pVector, int iField){
       Expr *pRet;
    -  if( p->flags & EP_xIsSelect ){
    -    pRet = sqlite3PExpr(pParse, TK_SELECT_COLUMN, p, 0, 0);
    +  assert( sqlite3ExprIsVector(pVector) );
    +  if( pVector->flags & EP_xIsSelect ){
    +    pRet = sqlite3PExpr(pParse, TK_SELECT_COLUMN, pVector, 0, 0);
         if( pRet ) pRet->iColumn = iField;
       }else{
    -    pRet = sqlite3ExprDup(pParse->db, p->x.pList->a[iField].pExpr, 0);
    +    pRet = sqlite3ExprDup(pParse->db, pVector->x.pList->a[iField].pExpr, 0);
       }
       return pRet;
     }
    @@ -1194,8 +1206,8 @@ static void exprAnalyze(
           for(i=0; ipLeft); i++){
             int idxNew;
             Expr *pNew;
    -        Expr *pLeft = exprVectorExpr(pParse, pExpr->pLeft, i);
    -        Expr *pRight = exprVectorExpr(pParse, pExpr->pRight, i);
    +        Expr *pLeft = exprExtractVectorField(pParse, pExpr->pLeft, i);
    +        Expr *pRight = exprExtractVectorField(pParse, pExpr->pRight, i);
     
             pNew = sqlite3PExpr(pParse, pExpr->op, pLeft, pRight, 0);
             idxNew = whereClauseInsert(pWC, pNew, TERM_VIRTUAL|TERM_DYNAMIC);
    diff --git a/test/rowvalue.test b/test/rowvalue.test
    index efa870009f..d8231563dc 100644
    --- a/test/rowvalue.test
    +++ b/test/rowvalue.test
    @@ -194,6 +194,12 @@ foreach {tn sql res eqp} {
       do_execsql_test 7.$tn.2 $sql $res
     }
     
    +do_execsql_test 8.0 {
    +  CREATE TABLE j1(a);
    +}
    +do_execsql_test 8.1 {
    +  SELECT * FROM j1 WHERE (select min(a) FROM j1) IN (?, ?, ?)
    +}
     
     
     finish_test
    
    From d7d19b7137b659537dc4bc0622f6cc88384e008f Mon Sep 17 00:00:00 2001
    From: dan 
    Date: Mon, 1 Aug 2016 16:50:50 +0000
    Subject: [PATCH 0645/1484] Add an extra compiler switch to loadext.test to
     ensure that it picks up the correct version of sqlite3.h when building a test
     extension.
    
    FossilOrigin-Name: e57fa6af32a1d1bf7be64b26850730f7e714b6c6
    ---
     manifest          | 14 +++++++-------
     manifest.uuid     |  2 +-
     test/loadext.test |  2 +-
     3 files changed, 9 insertions(+), 9 deletions(-)
    
    diff --git a/manifest b/manifest
    index 67dc23aac2..ad8c64f8c0 100644
    --- a/manifest
    +++ b/manifest
    @@ -1,5 +1,5 @@
    -C Update\sreleasetest.tcl\sto\sautomatically\sdo\sone\sround\sof\stests\swith\nUSE_STDCALL=1\swhen\srunning\son\sWindows\swith\sMSVC.
    -D 2016-08-01T15:00:00.879
    +C Add\san\sextra\scompiler\sswitch\sto\sloadext.test\sto\sensure\sthat\sit\spicks\sup\sthe\scorrect\sversion\sof\ssqlite3.h\swhen\sbuilding\sa\stest\sextension.
    +D 2016-08-01T16:50:50.941
     F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db
     F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
     F Makefile.msc 3340e479e5221f06c3d61726f8f7efff885e4233
    @@ -889,7 +889,7 @@ F test/like2.test 3b2ee13149ba4a8a60b59756f4e5d345573852da
     F test/like3.test 3608a2042b6f922f900fbfd5d3ce4e7eca57f7c4
     F test/limit.test 0c99a27a87b14c646a9d583c7c89fd06c352663e
     F test/limit2.test 55c9f4d08c89311e00afd75045ee1a2aca205cb4
    -F test/loadext.test 42a3b8166dfcadcb0e0c8710dc520d97c31a8b98
    +F test/loadext.test d077450695ddb5c1ea3ad7d48e5f5850fe732ad9
     F test/loadext2.test 0408380b57adca04004247179837a18e866a74f7
     F test/lock.test be4fe08118fb988fed741f429b7dd5d65e1c90db
     F test/lock2.test 5242d8ac4e2d59c403aebff606af449b455aceff
    @@ -1508,7 +1508,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
     F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
     F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
     F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
    -P b6ea2f21f602031ef4dbd47462ac11b0bb0d5de6
    -R 8c53f29684f1c5a6b809ef407293ad87
    -U drh
    -Z efd5176c6b70600d1d70a952504ac1b9
    +P a6a112de485eb9d15f6fa75568dcb876f00abb64
    +R b52843774fa6a1a75de37b3a2fbcc9cb
    +U dan
    +Z 4c7b22bb74a34454d19b7a6d615357b5
    diff --git a/manifest.uuid b/manifest.uuid
    index 45a5d2cc7d..309a3154e8 100644
    --- a/manifest.uuid
    +++ b/manifest.uuid
    @@ -1 +1 @@
    -a6a112de485eb9d15f6fa75568dcb876f00abb64
    \ No newline at end of file
    +e57fa6af32a1d1bf7be64b26850730f7e714b6c6
    \ No newline at end of file
    diff --git a/test/loadext.test b/test/loadext.test
    index e6ba21e187..24ee7a6802 100644
    --- a/test/loadext.test
    +++ b/test/loadext.test
    @@ -81,7 +81,7 @@ if {![file exists $testextension]} {
       set testextsrc $srcdir/test_loadext.c
     
       set cmdline [concat exec gcc $gcc_shared]
    -  lappend cmdline -Wall -I$srcdir -I. -g $testextsrc -o $testextension
    +  lappend cmdline -Wall -I$srcdir -I. -I.. -g $testextsrc -o $testextension
       
       if {[catch $cmdline msg]} {
         puts "Skipping loadext tests: Test extension not built..."
    
    From 4df049faec84a2287f9ec3b556da4da3f703b23d Mon Sep 17 00:00:00 2001
    From: dan 
    Date: Mon, 1 Aug 2016 16:57:30 +0000
    Subject: [PATCH 0646/1484] Remove a duplicate typedef from loadext.c
     (remaining copy is in sqlite3ext.h).
    
    FossilOrigin-Name: fd184e5a8f4577aa9a817eb55e771d8d1021b946
    ---
     manifest      | 12 ++++++------
     manifest.uuid |  2 +-
     src/loadext.c |  9 ---------
     3 files changed, 7 insertions(+), 16 deletions(-)
    
    diff --git a/manifest b/manifest
    index ad8c64f8c0..12abe5c148 100644
    --- a/manifest
    +++ b/manifest
    @@ -1,5 +1,5 @@
    -C Add\san\sextra\scompiler\sswitch\sto\sloadext.test\sto\sensure\sthat\sit\spicks\sup\sthe\scorrect\sversion\sof\ssqlite3.h\swhen\sbuilding\sa\stest\sextension.
    -D 2016-08-01T16:50:50.941
    +C Remove\sa\sduplicate\stypedef\sfrom\sloadext.c\s(remaining\scopy\sis\sin\ssqlite3ext.h).
    +D 2016-08-01T16:57:30.301
     F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db
     F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
     F Makefile.msc 3340e479e5221f06c3d61726f8f7efff885e4233
    @@ -347,7 +347,7 @@ F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4
     F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da
     F src/insert.c 8f4e9fcbd8e95e85f15647ba8b413b18d556ec2b
     F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e
    -F src/loadext.c 0ac0030646e4ec3c775b5c40d1818ec9a7e1ca95
    +F src/loadext.c ab2870487f4313a69816f15cb66d6c116051d895
     F src/main.c 16c1b2114eae8804caf3a8de8cb47bf2c6d83ad3
     F src/malloc.c 1443d1ad95d67c21d77af7ae3f44678252f0efec
     F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
    @@ -1508,7 +1508,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
     F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
     F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
     F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
    -P a6a112de485eb9d15f6fa75568dcb876f00abb64
    -R b52843774fa6a1a75de37b3a2fbcc9cb
    +P e57fa6af32a1d1bf7be64b26850730f7e714b6c6
    +R 95d57e7a20ef51e72dadff0e39b4eac0
     U dan
    -Z 4c7b22bb74a34454d19b7a6d615357b5
    +Z dd3eec4e4b9fe5243b233856e0e2f91d
    diff --git a/manifest.uuid b/manifest.uuid
    index 309a3154e8..564b2f8413 100644
    --- a/manifest.uuid
    +++ b/manifest.uuid
    @@ -1 +1 @@
    -e57fa6af32a1d1bf7be64b26850730f7e714b6c6
    \ No newline at end of file
    +fd184e5a8f4577aa9a817eb55e771d8d1021b946
    \ No newline at end of file
    diff --git a/src/loadext.c b/src/loadext.c
    index 26ba7e6491..c2125f35e2 100644
    --- a/src/loadext.c
    +++ b/src/loadext.c
    @@ -21,15 +21,6 @@
     #include 
     
     #ifndef SQLITE_OMIT_LOAD_EXTENSION
    -/*
    -** This is the function signature used for all extension entry points.
    -*/
    -typedef int (*sqlite3_loadext_entry)(
    -  sqlite3 *db,                       /* Handle to the database. */
    -  char **pzErrMsg,                   /* Used to set error string on failure. */
    -  const sqlite3_api_routines *pThunk /* Extension API function pointers. */
    -);
    -
     /*
     ** Some API routines are omitted when various features are
     ** excluded from a build of SQLite.  Substitute a NULL pointer
    
    From b0df540d7a5537ba239d00911444096474f28ed0 Mon Sep 17 00:00:00 2001
    From: drh 
    Date: Mon, 1 Aug 2016 17:06:44 +0000
    Subject: [PATCH 0647/1484] Fix other harmless compiler warnings.
    
    FossilOrigin-Name: 90d2c490fc2ed4e073711b84f989ca4d496dcfb5
    ---
     ext/misc/json1.c |  1 +
     manifest         | 18 +++++++++---------
     manifest.uuid    |  2 +-
     src/loadext.c    |  6 +++---
     src/shell.c      |  2 ++
     5 files changed, 16 insertions(+), 13 deletions(-)
    
    diff --git a/ext/misc/json1.c b/ext/misc/json1.c
    index a9452b0191..61c52ebe61 100644
    --- a/ext/misc/json1.c
    +++ b/ext/misc/json1.c
    @@ -1223,6 +1223,7 @@ static void jsonQuoteFunc(
       sqlite3_value **argv
     ){
       JsonString jx;
    +  UNUSED_PARAM(argc);
     
       jsonInit(&jx, ctx);
       jsonAppendValue(&jx, argv[0]);
    diff --git a/manifest b/manifest
    index 12abe5c148..fc5ee826f4 100644
    --- a/manifest
    +++ b/manifest
    @@ -1,5 +1,5 @@
    -C Remove\sa\sduplicate\stypedef\sfrom\sloadext.c\s(remaining\scopy\sis\sin\ssqlite3ext.h).
    -D 2016-08-01T16:57:30.301
    +C Fix\sother\sharmless\scompiler\swarnings.
    +D 2016-08-01T17:06:44.553
     F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db
     F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
     F Makefile.msc 3340e479e5221f06c3d61726f8f7efff885e4233
    @@ -212,7 +212,7 @@ F ext/misc/eval.c f971962e92ebb8b0a4e6b62949463ee454d88fa2
     F ext/misc/fileio.c d4171c815d6543a9edef8308aab2951413cd8d0f
     F ext/misc/fuzzer.c 7c64b8197bb77b7d64eff7cac7848870235d4c25
     F ext/misc/ieee754.c f190d0cc5182529acb15babd177781be1ac1718c
    -F ext/misc/json1.c d51a764ba43a49e191bc3536238bfab3def258ca
    +F ext/misc/json1.c 9799e4252b305edcbe659329eec3ca80ed85f968
     F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342
     F ext/misc/percentile.c 92699c8cd7d517ff610e6037e56506f8904dae2e
     F ext/misc/regexp.c a68d25c659bd2d893cd1215667bbf75ecb9dc7d4
    @@ -347,7 +347,7 @@ F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4
     F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da
     F src/insert.c 8f4e9fcbd8e95e85f15647ba8b413b18d556ec2b
     F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e
    -F src/loadext.c ab2870487f4313a69816f15cb66d6c116051d895
    +F src/loadext.c dd7a2b77902cc66c22555aef02e1a682554b7aec
     F src/main.c 16c1b2114eae8804caf3a8de8cb47bf2c6d83ad3
     F src/malloc.c 1443d1ad95d67c21d77af7ae3f44678252f0efec
     F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
    @@ -384,7 +384,7 @@ F src/random.c ba2679f80ec82c4190062d756f22d0c358180696
     F src/resolve.c cca3aa77b95706df5d635a2141a4d1de60ae6598
     F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac
     F src/select.c f3c6e9065fb34f6a23af27ec7f1f717ffbfc2ee4
    -F src/shell.c 9351fc6de11e1d908648c0a92d85627138e3dee5
    +F src/shell.c 79dda477be6c96eba6e952a934957ad36f87acc7
     F src/sqlite.h.in b41cf2d1deb59db570f20e8ed7ade4716c6dc613
     F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
     F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae
    @@ -1508,7 +1508,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
     F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
     F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
     F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
    -P e57fa6af32a1d1bf7be64b26850730f7e714b6c6
    -R 95d57e7a20ef51e72dadff0e39b4eac0
    -U dan
    -Z dd3eec4e4b9fe5243b233856e0e2f91d
    +P fd184e5a8f4577aa9a817eb55e771d8d1021b946
    +R ee6ea998e955e1020bf52b2850224f49
    +U drh
    +Z 082f7342c6c06c2add554ab4b05f638a
    diff --git a/manifest.uuid b/manifest.uuid
    index 564b2f8413..0a3df4be92 100644
    --- a/manifest.uuid
    +++ b/manifest.uuid
    @@ -1 +1 @@
    -fd184e5a8f4577aa9a817eb55e771d8d1021b946
    \ No newline at end of file
    +90d2c490fc2ed4e073711b84f989ca4d496dcfb5
    \ No newline at end of file
    diff --git a/src/loadext.c b/src/loadext.c
    index c2125f35e2..9feabbd045 100644
    --- a/src/loadext.c
    +++ b/src/loadext.c
    @@ -684,7 +684,7 @@ int sqlite3_auto_extension(
         wsdAutoextInit;
         sqlite3_mutex_enter(mutex);
         for(i=0; i=0; i--){
    -    if( wsdAutoext.aExt[i]==(void*)xInit ){
    +    if( wsdAutoext.aExt[i]==xInit ){
           wsdAutoext.nExt--;
           wsdAutoext.aExt[i] = wsdAutoext.aExt[wsdAutoext.nExt];
           n++;
    diff --git a/src/shell.c b/src/shell.c
    index e8d215b95a..18c6ef7197 100644
    --- a/src/shell.c
    +++ b/src/shell.c
    @@ -2550,6 +2550,8 @@ static int sql_trace_callback(
       void *pX
     ){
       FILE *f = (FILE*)pArg;
    +  UNUSED_PARAMETER(mType);
    +  UNUSED_PARAMETER(pP);
       if( f ){
         const char *z = (const char*)pX;
         int i = (int)strlen(z);
    
    From 553168c7067589478a72219b974c7b0824e00f58 Mon Sep 17 00:00:00 2001
    From: dan 
    Date: Mon, 1 Aug 2016 20:14:31 +0000
    Subject: [PATCH 0648/1484] Fix a problem with vector range constraints
     involving the rowid column. And other issues.
    
    FossilOrigin-Name: 3ef75d45ebcd8ede91596d69e55fe7d685008a60
    ---
     manifest           | 20 +++++------
     manifest.uuid      |  2 +-
     src/expr.c         | 85 ++++++++++++++++++++++++++--------------------
     src/select.c       |  5 ++-
     src/where.c        | 15 +++++++-
     src/wherecode.c    | 13 ++++++-
     test/rowvalue.test | 18 ++++++++++
     7 files changed, 106 insertions(+), 52 deletions(-)
    
    diff --git a/manifest b/manifest
    index ea0371ab19..cf088bf8f1 100644
    --- a/manifest
    +++ b/manifest
    @@ -1,5 +1,5 @@
    -C Fix\sa\sproblem\swith\sIN(...)\sconstraints\swhere\sthe\sLHS\sis\sa\ssub-select\sthat\sis\san\saggregate\squery.
    -D 2016-08-01T16:37:43.292
    +C Fix\sa\sproblem\swith\svector\srange\sconstraints\sinvolving\sthe\srowid\scolumn.\sAnd\sother\sissues.
    +D 2016-08-01T20:14:31.976
     F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db
     F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
     F Makefile.msc 3340e479e5221f06c3d61726f8f7efff885e4233
    @@ -337,7 +337,7 @@ F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7
     F src/date.c 1cc9fb516ec9932c6fd4d2a0d2f8bc4480145c39
     F src/dbstat.c 4f6f7f52b49beb9636ffbd517cfe44a402ba4ad0
     F src/delete.c 4aba4214a377ce8ddde2d2e609777bcc8235200f
    -F src/expr.c cdde4d3ed7f7cf1911b961141d61a4f06e6f7ebd
    +F src/expr.c 4db65a0c33003a00314fb56dca32d9cdbb6448a6
     F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
     F src/fkey.c bc4145347595b7770f9a598cff1c848302cf5413
     F src/func.c 61a4114cf7004f10c542cfabbab9f2bcb9033045
    @@ -383,7 +383,7 @@ F src/printf.c a5f0ca08ddede803c241266abb46356ec748ded1
     F src/random.c ba2679f80ec82c4190062d756f22d0c358180696
     F src/resolve.c cca3aa77b95706df5d635a2141a4d1de60ae6598
     F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac
    -F src/select.c bb2a1583fddbf8c2bbba2abbe411882b89e14a12
    +F src/select.c 952aa1b4148ed4c0024586e9049b8742a765c6f9
     F src/shell.c 9351fc6de11e1d908648c0a92d85627138e3dee5
     F src/sqlite.h.in cd10e4206b91c4bf03f121ab9209a14af0b48f14
     F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
    @@ -463,9 +463,9 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
     F src/wal.c 02eeecc265f6ffd0597378f5d8ae9070b62a406a
     F src/wal.h 6dd221ed384afdc204bc61e25c23ef7fd5a511f2
     F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354
    -F src/where.c 61db3a409b6b89383abd0e746965da424676f8ea
    +F src/where.c a1c2fde60e806f1e045fdf745bfa449e3be82f55
     F src/whereInt.h 14dd243e13b81cbb0a66063d38b70f93a7d6e613
    -F src/wherecode.c 6131be0cb19702665c3decbf243dae58ecc15937
    +F src/wherecode.c c01c8af9311b5d6d65de311101f72d94a11ae506
     F src/whereexpr.c 3f5d76b585ab193bb9ae15aadb8deb94346c93e7
     F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
     F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd
    @@ -1018,7 +1018,7 @@ F test/rollbackfault.test 0e646aeab8840c399cfbfa43daab46fd609cf04a
     F test/rowallock.test 3f88ec6819489d0b2341c7a7528ae17c053ab7cc
     F test/rowhash.test 0bc1d31415e4575d10cacf31e1a66b5cc0f8be81
     F test/rowid.test 5b7509f384f4f6fae1af3c8c104c8ca299fea18d
    -F test/rowvalue.test 5f00f33fb1aa9259b35b44261b651361580d5a34
    +F test/rowvalue.test 56b34d31d91340a6e922e753b798880170cc1aa7
     F test/rowvalue2.test 8d5dfe75b8f4d1868a2f91f0356f20d36cba64ff
     F test/rowvalue3.test 5127afb4414bf62546161497c04840c46e371770
     F test/rowvalue4.test 4480898d62d6813e3e38d9d38c02b9a0be5f94be
    @@ -1512,7 +1512,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
     F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
     F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
     F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
    -P 059d0d05354e6efab7892c97b339ffa0b5303587
    -R b99b47b8f7c934c8cffa76149cc68eeb
    +P 1f4dba87da4a44ad26223ad965731164c0d9bad9
    +R 4b01df8319f11080e804e7c115ca8550
     U dan
    -Z 9e6109253ab0bc1e8a84d8639e4d1848
    +Z c86f923fed6f969ee44eaf1f0098c9a2
    diff --git a/manifest.uuid b/manifest.uuid
    index 7f308a68d6..1477f7e016 100644
    --- a/manifest.uuid
    +++ b/manifest.uuid
    @@ -1 +1 @@
    -1f4dba87da4a44ad26223ad965731164c0d9bad9
    \ No newline at end of file
    +3ef75d45ebcd8ede91596d69e55fe7d685008a60
    \ No newline at end of file
    diff --git a/src/expr.c b/src/expr.c
    index 3bbd015fd1..53c00952f3 100644
    --- a/src/expr.c
    +++ b/src/expr.c
    @@ -1888,7 +1888,7 @@ static int sqlite3InRhsIsConstant(Expr *pIn){
     ** An existing b-tree might be used if the RHS expression pX is a simple
     ** subquery such as:
     **
    -**     SELECT  FROM 
    +** SELECT , ... FROM
    ** ** If the RHS of the IN operator is a list or a more complex subquery, then ** an ephemeral table might need to be generated from the RHS and then @@ -1904,14 +1904,14 @@ static int sqlite3InRhsIsConstant(Expr *pIn){ ** ** When IN_INDEX_LOOP is used (and the b-tree will be used to iterate ** through the set members) then the b-tree must not contain duplicates. -** An epheremal table must be used unless the selected is guaranteed -** to be unique - either because it is an INTEGER PRIMARY KEY or it -** has a UNIQUE constraint or UNIQUE index. +** An epheremal table must be used unless the selected columns are guaranteed +** to be unique - either because it is an INTEGER PRIMARY KEY or due to +** a UNIQUE constraint or index. ** ** When IN_INDEX_MEMBERSHIP is used (and the b-tree will be used ** for fast set membership tests) then an epheremal table must -** be used unless is an INTEGER PRIMARY KEY or an index can -** be found with as its left-most column. +** be used unless is a single INTEGER PRIMARY KEY column or an +** index can be found with the specified as its left-most. ** ** If the IN_INDEX_NOOP_OK and IN_INDEX_MEMBERSHIP are both set and ** if the RHS of the IN operator is a list (not a subquery) then this @@ -1932,6 +1932,17 @@ static int sqlite3InRhsIsConstant(Expr *pIn){ ** the value in that register will be NULL if the b-tree contains one or more ** NULL values, and it will be some non-NULL value if the b-tree contains no ** NULL values. +** +** If the aiMap parameter is not NULL, it must point to an array containing +** one element for each column returned by the SELECT statement on the RHS +** of the IN(...) operator. The i'th entry of the array is populated with the +** offset of the index column that matches the i'th column returned by the +** SELECT. For example, if the expression and selected index are: +** +** (?,?,?) IN (SELECT a, b, c FROM t1) +** CREATE INDEX i1 ON t1(b, c, a); +** +** then aiMap[] is populated with {2, 0, 1}. */ #ifndef SQLITE_OMIT_SUBQUERY int sqlite3FindInIndex( @@ -2119,24 +2130,32 @@ int sqlite3FindInIndex( } #endif +/* +** Argument pExpr is an (?, ?...) IN(...) expression. This +** function allocates and returns a nul-terminated string containing +** the affinities to be used for each column of the comparison. +** +** It is the responsibility of the caller to ensure that the returned +** string is eventually freed using sqlite3DbFree(). +*/ static char *exprINAffinity(Parse *pParse, Expr *pExpr){ Expr *pLeft = pExpr->pLeft; int nVal = sqlite3ExprVectorSize(pLeft); + Select *pSelect = (pExpr->flags & EP_xIsSelect) ? pExpr->x.pSelect : 0; char *zRet; + assert( pExpr->op==TK_IN ); zRet = sqlite3DbMallocZero(pParse->db, nVal+1); if( zRet ){ int i; for(i=0; ipEList->a[i].pExpr, a); + }else{ + zRet[i] = a; } - a = sqlite3ExprAffinity(pA); - zRet[i] = sqlite3CompareAffinity(pExpr->x.pSelect->pEList->a[i].pExpr, a); } zRet[nVal] = '\0'; } @@ -2229,11 +2248,12 @@ int sqlite3CodeSubselect( int nVal; /* Size of vector pLeft */ nVal = sqlite3ExprVectorSize(pLeft); + assert( !isRowid || nVal==1 ); /* Whether this is an 'x IN(SELECT...)' or an 'x IN()' ** expression it is handled the same way. An ephemeral table is - ** filled with single-field index keys representing the results - ** from the SELECT or the . + ** filled with index keys representing the results from the + ** SELECT or the . ** ** If the 'x' expression is a column value, or the SELECT... ** statement returns a column value, then the affinity of that @@ -2470,18 +2490,19 @@ static void sqlite3ExprCodeIN( int *aiMap = 0; /* Map from vector field to index column */ char *zAff = 0; /* Affinity string for comparisons */ int nVector; /* Size of vectors for this IN(...) op */ - int regSelect = 0; Expr *pLeft = pExpr->pLeft; int i; if( sqlite3ExprCheckIN(pParse, pExpr) ) return; + zAff = exprINAffinity(pParse, pExpr); nVector = sqlite3ExprVectorSize(pExpr->pLeft); aiMap = (int*)sqlite3DbMallocZero( pParse->db, nVector*(sizeof(int) + sizeof(char)) + 1 ); - if( !aiMap ) return; - zAff = (char*)&aiMap[nVector]; - + if( !zAff || !aiMap ){ + sqlite3DbFree(pParse->db, aiMap); + return; + } /* Attempt to compute the RHS. After this step, if anything other than ** IN_INDEX_NOOP is returned, the table opened ith cursor pExpr->iTable @@ -2505,23 +2526,14 @@ static void sqlite3ExprCodeIN( r1 = sqlite3GetTempRange(pParse, nVector); sqlite3ExprCachePush(pParse); if( nVector>1 && (pLeft->flags & EP_xIsSelect) ){ - regSelect = sqlite3CodeSubselect(pParse, pLeft, 0, 0); - } - for(i=0; iflags & EP_xIsSelect ){ - zAff[iCol] = sqlite3CompareAffinity( - pExpr->x.pSelect->pEList->a[iCol].pExpr, zAff[iCol] - ); + }else{ + for(i=0; idb, aiMap); + sqlite3DbFree(pParse->db, zAff); VdbeComment((v, "end IN expr")); } #endif /* SQLITE_OMIT_SUBQUERY */ diff --git a/src/select.c b/src/select.c index fb7217c1b4..6aba96730a 100644 --- a/src/select.c +++ b/src/select.c @@ -878,7 +878,7 @@ static void selectInnerLoop( int r1 = sqlite3GetTempReg(pParse); assert( sqlite3Strlen30(pDest->zAffSdst)==nResultCol ); sqlite3VdbeAddOp4(v, OP_MakeRecord, regResult, nResultCol, - r1, pDest->zAffSdst, 1); + r1, pDest->zAffSdst, nResultCol); sqlite3ExprCacheAffinityChange(pParse, regResult, nResultCol); sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, r1); sqlite3ReleaseTempReg(pParse, r1); @@ -1261,13 +1261,12 @@ static void generateSortTail( case SRT_Set: { assert( nColumn==sqlite3Strlen30(pDest->zAffSdst) ); sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, nColumn, regRowid, - pDest->zAffSdst, 1); + pDest->zAffSdst, nColumn); sqlite3ExprCacheAffinityChange(pParse, regRow, nColumn); sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, regRowid); break; } case SRT_Mem: { - /* sqlite3ExprCodeMove(pParse, regRow, iParm, nColumn); */ /* The LIMIT clause will terminate the loop for us */ break; } diff --git a/src/where.c b/src/where.c index 588ae8cb04..346614fe7e 100644 --- a/src/where.c +++ b/src/where.c @@ -2189,7 +2189,20 @@ static void whereLoopOutputAdjust( /* ** Term pTerm is a vector range comparison operation. The first comparison -** in the vector can be optimized using column nEq of the index. +** in the vector can be optimized using column nEq of the index. This +** function returns the total number of vector elements that can be used +** as part of the range comparison. +** +** For example, if the query is: +** +** WHERE a = ? AND (b, c, d) > (?, ?, ?) +** +** and the index: +** +** CREATE INDEX ... ON (a, b, c, d, e) +** +** then this function would be invoked with nEq=1. The value returned in +** this case is 3. */ int whereRangeVectorLen( Parse *pParse, int iCur, Index *pIdx, int nEq, WhereTerm *pTerm diff --git a/src/wherecode.c b/src/wherecode.c index 4f4f141123..11e9bbda34 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -950,6 +950,15 @@ static void codeDeferredSeek( } } +/* +** If the expression passed as the second argument is a vector, generate +** code to write the first nReg elements of the vector into an array +** of registers starting with iReg. +** +** If the expression is not a vector, then nReg must be passed 1. In +** this case, generate code to evaluate the expression and leave the +** result in register iReg. +*/ static void codeExprOrVector(Parse *pParse, Expr *p, int iReg, int nReg){ assert( nReg>0 ); if( sqlite3ExprIsVector(p) ){ @@ -1238,7 +1247,9 @@ Bitmask sqlite3WhereCodeOneLoopStart( }else{ testOp = bRev ? OP_Lt : OP_Gt; } - disableTerm(pLevel, pEnd); + if( 0==sqlite3ExprIsVector(pX->pRight) ){ + disableTerm(pLevel, pEnd); + } } start = sqlite3VdbeCurrentAddr(v); pLevel->op = bRev ? OP_Prev : OP_Next; diff --git a/test/rowvalue.test b/test/rowvalue.test index d8231563dc..a1faba97ab 100644 --- a/test/rowvalue.test +++ b/test/rowvalue.test @@ -201,6 +201,24 @@ do_execsql_test 8.1 { SELECT * FROM j1 WHERE (select min(a) FROM j1) IN (?, ?, ?) } +do_execsql_test 9.0 { + CREATE TABLE t2(a INTEGER PRIMARY KEY, b, c); + INSERT INTO t2 VALUES(1, 1, 1); + INSERT INTO t2 VALUES(2, 2, 2); + INSERT INTO t2 VALUES(3, 3, 3); + INSERT INTO t2 VALUES(4, 4, 4); + INSERT INTO t2 VALUES(5, 5, 5); +} + +foreach {tn q res} { + 1 "(a, b) > (2, 1)" {2 3 4 5} + 2 "(a, b) > (2, 2)" {3 4 5} + 3 "(a, b) < (4, 5)" {1 2 3 4} + 4 "(a, b) < (4, 3)" {1 2 3} +} { + do_execsql_test 9.$tn "SELECT c FROM t2 WHERE $q" $res +} + finish_test From 19eb77bbe044fec2f74ec411b745ed83598b7551 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 1 Aug 2016 21:17:53 +0000 Subject: [PATCH 0649/1484] Update the wordcount.c test program and add a new script "time-wordcount.sh" for additional performance testing. FossilOrigin-Name: d8ef9f58643f13dd3d16dcde0d829ae08324f04b --- manifest | 13 +++++----- manifest.uuid | 2 +- test/time-wordcount.sh | 34 ++++++++++++++++++++++++++ test/wordcount.c | 54 ++++++++++++++++++++++++------------------ 4 files changed, 73 insertions(+), 30 deletions(-) create mode 100644 test/time-wordcount.sh diff --git a/manifest b/manifest index fc5ee826f4..15cc8e1381 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sother\sharmless\scompiler\swarnings. -D 2016-08-01T17:06:44.553 +C Update\sthe\swordcount.c\stest\sprogram\sand\sadd\sa\snew\sscript\s"time-wordcount.sh"\nfor\sadditional\sperformance\stesting. +D 2016-08-01T21:17:53.023 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 3340e479e5221f06c3d61726f8f7efff885e4233 @@ -1142,6 +1142,7 @@ F test/threadtest1.c 6029d9c5567db28e6dc908a0c63099c3ba6c383b F test/threadtest2.c a70a8e94bef23339d34226eb9521015ef99f4df8 F test/threadtest3.c 38a612ea62854349ed66372f330a40d73c5cf956 F test/threadtest4.c c1e67136ceb6c7ec8184e56ac61db28f96bd2925 +F test/time-wordcount.sh 8e0b0f8109367827ad5d58f5cc849705731e4b90 F test/tkt-02a8e81d44.test 6c80d9c7514e2a42d4918bf87bf6bc54f379110c F test/tkt-26ff0c2d1e.test 888324e751512972c6e0d1a09df740d8f5aaf660 F test/tkt-2a5629202f.test 0521bd25658428baa26665aa53ffed9367d33af2 @@ -1416,7 +1417,7 @@ F test/without_rowid3.test aad4f9d383e199349b6c7e508a778f7dff5dff79 F test/without_rowid4.test 4e08bcbaee0399f35d58b5581881e7a6243d458a F test/without_rowid5.test 89b1c587bd92a0590e440da33e7666bf4891572a F test/without_rowid6.test 1f99644e6508447fb050f73697350c7ceca3392e -F test/wordcount.c 2a0a6c0d0e8e8bbbac1f06d72a6791828c37c0cf +F test/wordcount.c 97856eec21fd00d77da720007b1888c383f63dcf F test/zeroblob.test 3857870fe681b8185654414a9bccfde80b62a0fa F test/zerodamage.test e59a56443d6298ecf7435f618f0b27654f0c849e F tool/GetFile.cs a15e08acb5dd7539b75ba23501581d7c2b462cb5 @@ -1508,7 +1509,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P fd184e5a8f4577aa9a817eb55e771d8d1021b946 -R ee6ea998e955e1020bf52b2850224f49 +P 90d2c490fc2ed4e073711b84f989ca4d496dcfb5 +R 785c152fa91bad6599d646e4e2f00927 U drh -Z 082f7342c6c06c2add554ab4b05f638a +Z e82d6de7fe92cf55ce862dce0d383efb diff --git a/manifest.uuid b/manifest.uuid index 0a3df4be92..a4b3d0224f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -90d2c490fc2ed4e073711b84f989ca4d496dcfb5 \ No newline at end of file +d8ef9f58643f13dd3d16dcde0d829ae08324f04b \ No newline at end of file diff --git a/test/time-wordcount.sh b/test/time-wordcount.sh new file mode 100644 index 0000000000..df9edc6f2c --- /dev/null +++ b/test/time-wordcount.sh @@ -0,0 +1,34 @@ +#!/bin/sh +# +# This script runs the wordcount program in different ways and generates +# an output useful for performance comparisons. +# + +# Select the source text to be analyzed. +# +if test "x$1" = "x"; +then echo "Usage: $0 FILENAME [ARGS...]"; exit 1; +fi + +# Do test runs +# +rm -f wcdb1.db +./wordcount --tag A: --timer --summary wcdb1.db $* --insert +rm -f wcdb2.db +./wordcount --tag B: --timer --summary wcdb2.db $* --insert --without-rowid +rm -f wcdb1.db +./wordcount --tag C: --timer --summary wcdb1.db $* --replace +rm -f wcdb2.db +./wordcount --tag D: --timer --summary wcdb2.db $* --replace --without-rowid +rm -f wcdb1.db +./wordcount --tag E: --timer --summary wcdb1.db $* --select +rm -f wcdb2.db +./wordcount --tag F: --timer --summary wcdb2.db $* --select --without-rowid +./wordcount --tag G: --timer --summary wcdb1.db $* --query +./wordcount --tag H: --timer --summary wcdb1.db $* --query --without-rowid +./wordcount --tag I: --timer --summary wcdb1.db $* --delete +./wordcount --tag J: --timer --summary wcdb2.db $* --delete --without-rowid + +# Clean up temporary files created. +# +rm -f wcdb1.db wcdb2.db diff --git a/test/wordcount.c b/test/wordcount.c index 72aa6b2f0b..5002918c5e 100644 --- a/test/wordcount.c +++ b/test/wordcount.c @@ -30,6 +30,7 @@ ** --nosync Use PRAGMA synchronous=OFF ** --journal MMMM Use PRAGMA journal_mode=MMMM ** --timer Time the operation of this program +** --tag NAME Tag all output using NAME. Use only stdout. ** ** Modes: ** @@ -82,6 +83,9 @@ #include "sqlite3.h" #define ISALPHA(X) isalpha((unsigned char)(X)) +/* Output tag */ +char *zTag = "--"; + /* Return the current wall-clock time */ static sqlite3_int64 realTime(void){ static sqlite3_vfs *clockVfs = 0; @@ -115,7 +119,7 @@ static void traceCallback(void *NotUsed, const char *zSql){ ** each column separated by a single space. */ static int printResult(void *NotUsed, int nArg, char **azArg, char **azNm){ int i; - printf("--"); + printf("%s", zTag); for(i=0; i Date: Tue, 2 Aug 2016 08:45:26 +0000 Subject: [PATCH 0650/1484] Fix harmless compiler warnings in sqlite3_status(). FossilOrigin-Name: 7c38a79cdd42aaa45715aea330d10ca859098837 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/status.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 15cc8e1381..02f0e10029 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\sthe\swordcount.c\stest\sprogram\sand\sadd\sa\snew\sscript\s"time-wordcount.sh"\nfor\sadditional\sperformance\stesting. -D 2016-08-01T21:17:53.023 +C Fix\sharmless\scompiler\swarnings\sin\ssqlite3_status(). +D 2016-08-02T08:45:26.626 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 3340e479e5221f06c3d61726f8f7efff885e4233 @@ -390,7 +390,7 @@ F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae F src/sqliteInt.h d6f221a5bd572df935140beda82f357c2185a77c F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 -F src/status.c 5b18f9526900f61189ab0b83f1ef41d9f871a2ab +F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 F src/tclsqlite.c bdae822f21e229b6daced15938b6343ce44ef454 F src/test1.c 0a0909cf7962d2359db329c08d15b90b4b6e724f @@ -1509,7 +1509,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 90d2c490fc2ed4e073711b84f989ca4d496dcfb5 -R 785c152fa91bad6599d646e4e2f00927 +P d8ef9f58643f13dd3d16dcde0d829ae08324f04b +R 043c924e3262ae632c6a04160549d94d U drh -Z e82d6de7fe92cf55ce862dce0d383efb +Z c53a56bb9efce70acc3af43de2ff893c diff --git a/manifest.uuid b/manifest.uuid index a4b3d0224f..a43f3794d8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d8ef9f58643f13dd3d16dcde0d829ae08324f04b \ No newline at end of file +7c38a79cdd42aaa45715aea330d10ca859098837 \ No newline at end of file diff --git a/src/status.c b/src/status.c index 949908ed23..24dcad4572 100644 --- a/src/status.c +++ b/src/status.c @@ -158,7 +158,7 @@ int sqlite3_status64( return SQLITE_OK; } int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag){ - sqlite3_int64 iCur, iHwtr; + sqlite3_int64 iCur = 0, iHwtr = 0; int rc; #ifdef SQLITE_ENABLE_API_ARMOR if( pCurrent==0 || pHighwater==0 ) return SQLITE_MISUSE_BKPT; From 914b7e4238a6d777c54d26e6b75a6893dd1b95fc Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 2 Aug 2016 11:29:16 +0000 Subject: [PATCH 0651/1484] Fix a problem introduced by [77948b5eceab92a7] causing duplicate calls to be made to the xSavepoint() method of virtual tables under some circumstances. FossilOrigin-Name: e64a4173d2899acf13b73e6e28f2e164fd638a75 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/vtab.c | 5 ++++- test/fts3conf.test | 38 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 51 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 02f0e10029..79a50d4114 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\scompiler\swarnings\sin\ssqlite3_status(). -D 2016-08-02T08:45:26.626 +C Fix\sa\sproblem\sintroduced\sby\s[77948b5eceab92a7]\scausing\sduplicate\scalls\sto\sbe\smade\sto\sthe\sxSavepoint()\smethod\sof\svirtual\stables\sunder\ssome\scircumstances. +D 2016-08-02T11:29:16.818 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 3340e479e5221f06c3d61726f8f7efff885e4233 @@ -458,7 +458,7 @@ F src/vdbeblob.c 83d2d266383157b02e2b809350bb197e89d7895b F src/vdbemem.c 1ecaa5ee0caff07255f25d04e8dc88befb6f88d1 F src/vdbesort.c 91fda3909326860382b0ca8aa251e609c6a9d62c F src/vdbetrace.c 41963d5376f0349842b5fc4aaaaacd7d9cdc0834 -F src/vtab.c 948d2d4984219eee37a7bf427d6667e21e6eb92e +F src/vtab.c 6fece06fdd50eb2b0673e37e627ce6710e4af5be F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 02eeecc265f6ffd0597378f5d8ae9070b62a406a F src/wal.h 6dd221ed384afdc204bc61e25c23ef7fd5a511f2 @@ -746,7 +746,7 @@ F test/fts3aux2.test 7ae2b2c13aefdf4169279a27a5f51780ce57f6ba F test/fts3b.test e93bbb653e52afde110ad53bbd793f14fe7a8984 F test/fts3c.test fc723a9cf10b397fdfc2b32e73c53c8b1ec02958 F test/fts3comp1.test a0f5b16a2df44dd0b15751787130af2183167c0c -F test/fts3conf.test 1c8b8adb0ab28a41b68d1514df44380bd7353402 +F test/fts3conf.test 60317efd562080e198b5bdc9fcd222ce32cf01d7 F test/fts3corrupt.test 2710b77983cc7789295ddbffea52c1d3b7506dbb F test/fts3corrupt2.test 6d96efae2f8a6af3eeaf283aba437e6d0e5447ba F test/fts3cov.test e0fb00d8b715ddae4a94c305992dfc3ef70353d7 @@ -1509,7 +1509,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d8ef9f58643f13dd3d16dcde0d829ae08324f04b -R 043c924e3262ae632c6a04160549d94d -U drh -Z c53a56bb9efce70acc3af43de2ff893c +P 7c38a79cdd42aaa45715aea330d10ca859098837 +R dce642e9ffc5d2b7ba510a82ce70adfa +U dan +Z 723af27ecacb58bb0a83305d88f4583f diff --git a/manifest.uuid b/manifest.uuid index a43f3794d8..003f16e3e2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7c38a79cdd42aaa45715aea330d10ca859098837 \ No newline at end of file +e64a4173d2899acf13b73e6e28f2e164fd638a75 \ No newline at end of file diff --git a/src/vtab.c b/src/vtab.c index e81079a050..f37eb261aa 100644 --- a/src/vtab.c +++ b/src/vtab.c @@ -947,7 +947,10 @@ int sqlite3VtabBegin(sqlite3 *db, VTable *pVTab){ if( rc==SQLITE_OK ){ int iSvpt = db->nStatement + db->nSavepoint; addToVTrans(db, pVTab); - if( iSvpt ) rc = sqlite3VtabSavepoint(db, SAVEPOINT_BEGIN, iSvpt-1); + if( iSvpt && pModule->xSavepoint ){ + pVTab->iSavepoint = iSvpt; + rc = pModule->xSavepoint(pVTab->pVtab, iSvpt-1); + } } } } diff --git a/test/fts3conf.test b/test/fts3conf.test index f9698770cc..6766a95408 100644 --- a/test/fts3conf.test +++ b/test/fts3conf.test @@ -211,4 +211,42 @@ do_execsql_test 4.2.2 { INSERT INTO t01(t01) VALUES('integrity-check'); } {} +do_execsql_test 4.3.1 { + CREATE VIRTUAL TABLE t02 USING fts4; + INSERT INTO t01 VALUES('1 1 1'); + INSERT INTO t02 VALUES('2 2 2'); + BEGIN; + SAVEPOINT abc; + INSERT INTO t01 VALUES('a b c'); + INSERT INTO t02 VALUES('a b c'); + ROLLBACK TO abc; + COMMIT; +} +do_execsql_test 4.3.2 { + SELECT * FROM t01 WHERE t01 MATCH 'b'; + INSERT INTO t01(t01) VALUES('integrity-check'); +} {} + +do_execsql_test 4.4.1 { + CREATE TABLE A(ID INTEGER PRIMARY KEY, AnotherID INTEGER, Notes TEXT); + CREATE VIRTUAL TABLE AFTS USING FTS4 (Notes); + CREATE TRIGGER A_DeleteTrigger AFTER DELETE ON A FOR EACH ROW BEGIN + DELETE FROM AFTS WHERE rowid=OLD.ID; + END; + CREATE TABLE B(ID INTEGER PRIMARY KEY,Notes TEXT); + CREATE VIRTUAL TABLE BFTS USING FTS3 (Notes); + CREATE TRIGGER B_DeleteTrigger AFTER DELETE ON B FOR EACH ROW BEGIN + DELETE FROM BFTS WHERE rowid=OLD.ID; + END; +} + +do_execsql_test 4.4.2 { + BEGIN TRANSACTION; + DELETE FROM A WHERE AnotherID=1; + DELETE FROM B WHERE ID=1; + COMMIT; +} + + + finish_test From b7203cde291ec15324bf0150484df81ba7b8bced Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 2 Aug 2016 13:26:34 +0000 Subject: [PATCH 0652/1484] Updates to requirements marks. No changes to code. FossilOrigin-Name: b23c10ac8f65bc88a6c7d88e140217222eb4cbe5 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/sqlite.h.in | 17 +++++++++-------- 3 files changed, 17 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index 79a50d4114..dcecb8eb96 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\sintroduced\sby\s[77948b5eceab92a7]\scausing\sduplicate\scalls\sto\sbe\smade\sto\sthe\sxSavepoint()\smethod\sof\svirtual\stables\sunder\ssome\scircumstances. -D 2016-08-02T11:29:16.818 +C Updates\sto\srequirements\smarks.\s\sNo\schanges\sto\scode. +D 2016-08-02T13:26:34.987 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 3340e479e5221f06c3d61726f8f7efff885e4233 @@ -385,7 +385,7 @@ F src/resolve.c cca3aa77b95706df5d635a2141a4d1de60ae6598 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c f3c6e9065fb34f6a23af27ec7f1f717ffbfc2ee4 F src/shell.c 79dda477be6c96eba6e952a934957ad36f87acc7 -F src/sqlite.h.in b41cf2d1deb59db570f20e8ed7ade4716c6dc613 +F src/sqlite.h.in e011dcc3942e6ddc8dd7b894e9e6702e4269161e F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae F src/sqliteInt.h d6f221a5bd572df935140beda82f357c2185a77c @@ -1509,7 +1509,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 7c38a79cdd42aaa45715aea330d10ca859098837 -R dce642e9ffc5d2b7ba510a82ce70adfa -U dan -Z 723af27ecacb58bb0a83305d88f4583f +P e64a4173d2899acf13b73e6e28f2e164fd638a75 +R 2f7c4e993e0eb7bb61a5a37266251c67 +U drh +Z 9edc5e5cd5ca93c7d8faa216313b72e1 diff --git a/manifest.uuid b/manifest.uuid index 003f16e3e2..ac57330bc6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e64a4173d2899acf13b73e6e28f2e164fd638a75 \ No newline at end of file +b23c10ac8f65bc88a6c7d88e140217222eb4cbe5 \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 27ca6ef4ad..f60ccaf55c 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -4704,12 +4704,13 @@ sqlite3 *sqlite3_context_db_handle(sqlite3_context*); ** SQLite will invoke the destructor function X with parameter P exactly ** once, when the metadata is discarded. ** SQLite is free to discard the metadata at any time, including:
      -**
    • when the corresponding function parameter changes, or -**
    • when [sqlite3_reset()] or [sqlite3_finalize()] is called for the -** SQL statement, or -**
    • when sqlite3_set_auxdata() is invoked again on the same parameter, or -**
    • during the original sqlite3_set_auxdata() call when a memory -** allocation error occurs.
    )^ +**
  • ^(when the corresponding function parameter changes)^, or +**
  • ^(when [sqlite3_reset()] or [sqlite3_finalize()] is called for the +** SQL statement)^, or +**
  • ^(when sqlite3_set_auxdata() is invoked again on the same +** parameter)^, or +**
  • ^(during the original sqlite3_set_auxdata() call when a memory +** allocation error occurs.)^ ** ** Note the last bullet in particular. The destructor X in ** sqlite3_set_auxdata(C,N,P,X) might be called immediately, before the @@ -5670,8 +5671,8 @@ int sqlite3_load_extension( ** ** ^This interface enables or disables both the C-API ** [sqlite3_load_extension()] and the SQL function [load_extension()]. -** Use [sqlite3_db_config](db,[SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION],..) -** to enable or disable only the C-API. +** ^(Use [sqlite3_db_config](db,[SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION],..) +** to enable or disable only the C-API.)^ ** ** Security warning: It is recommended that extension loading ** be disabled using the [SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION] method From 95a08c065a4111099fd0f330be8c5b4a6152da83 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 2 Aug 2016 16:18:35 +0000 Subject: [PATCH 0653/1484] Add missing comments and make some code on this branch clearer. FossilOrigin-Name: 6937677cc2c2db6b21f997559f88a339466cd15b --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/whereexpr.c | 11 ++++++++++- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index cf088bf8f1..12d2b31833 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\swith\svector\srange\sconstraints\sinvolving\sthe\srowid\scolumn.\sAnd\sother\sissues. -D 2016-08-01T20:14:31.976 +C Add\smissing\scomments\sand\smake\ssome\scode\son\sthis\sbranch\sclearer. +D 2016-08-02T16:18:35.278 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 3340e479e5221f06c3d61726f8f7efff885e4233 @@ -466,7 +466,7 @@ F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354 F src/where.c a1c2fde60e806f1e045fdf745bfa449e3be82f55 F src/whereInt.h 14dd243e13b81cbb0a66063d38b70f93a7d6e613 F src/wherecode.c c01c8af9311b5d6d65de311101f72d94a11ae506 -F src/whereexpr.c 3f5d76b585ab193bb9ae15aadb8deb94346c93e7 +F src/whereexpr.c 4a8cefc7c122132ac9f3ed125c61629a0e3de094 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1512,7 +1512,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 1f4dba87da4a44ad26223ad965731164c0d9bad9 -R 4b01df8319f11080e804e7c115ca8550 +P 3ef75d45ebcd8ede91596d69e55fe7d685008a60 +R ede02eaf849a0a0aa8962160f6f4e818 U dan -Z c86f923fed6f969ee44eaf1f0098c9a2 +Z d2db5fc489c89774ca610a9face0568f diff --git a/manifest.uuid b/manifest.uuid index 1477f7e016..026bb0a0e8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3ef75d45ebcd8ede91596d69e55fe7d685008a60 \ No newline at end of file +6937677cc2c2db6b21f997559f88a339466cd15b \ No newline at end of file diff --git a/src/whereexpr.c b/src/whereexpr.c index 33ce7edb38..6366133577 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -831,7 +831,7 @@ static Bitmask exprSelectUsage(WhereMaskSet *pMaskSet, Select *pS){ */ static int exprMightBeIndexed( SrcList *pFrom, /* The FROM clause */ - int op, + int op, /* The specific comparison operator */ Bitmask mPrereq, /* Bitmask of FROM clause terms referenced by pExpr */ Expr *pExpr, /* An operand of a comparison operator */ int *piCur, /* Write the referenced table cursor number here */ @@ -1194,6 +1194,10 @@ static void exprAnalyze( } #endif /* SQLITE_OMIT_VIRTUALTABLE */ + /* If there is a vector == or IS term - e.g. "(a, b) == (?, ?)" - create + ** a virtual term for each component comparison - "a = ?" and "b = ?". + ** This is only required if at least one side of the comparison operation + ** is not a sub-select. */ if( pWC->op==TK_AND && (pExpr->op==TK_EQ || pExpr->op==TK_IS) && sqlite3ExprIsVector(pExpr->pLeft) @@ -1217,6 +1221,11 @@ static void exprAnalyze( } } + /* If there is a vector IN term - e.g. "(a, b) IN (SELECT ...)" - create + ** a virtual term for each vector component. The expression object + ** used by each such virtual term is pExpr (the full vector IN(...) + ** expression). The WhereTerm.iField variable identifies the index within + ** the vector on the LHS that the virtual term represents. */ if( pWC->op==TK_AND && pExpr->op==TK_IN && pTerm->iField==0 && pExpr->pLeft->op==TK_VECTOR ){ From d05a7144cd7bcdbe5f5274198198e5120e846703 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 2 Aug 2016 17:07:51 +0000 Subject: [PATCH 0654/1484] Fix a problem with vector range constraints and mixed ASC/DESC indexes. FossilOrigin-Name: e2ad30c8b5366fd8e50f36c62345ed03ec613c47 --- manifest | 18 ++++++------- manifest.uuid | 2 +- src/where.c | 6 +++-- test/rowvalue3.test | 9 ------- test/rowvalue4.test | 64 ++++++++++++++++++++++++++++++++++++++++++++- test/tester.tcl | 11 ++++++++ 6 files changed, 88 insertions(+), 22 deletions(-) diff --git a/manifest b/manifest index b50f6287da..ba89d2088a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\slatest\strunk\schanges\sinto\sthis\sbranch. -D 2016-08-02T16:24:10.101 +C Fix\sa\sproblem\swith\svector\srange\sconstraints\sand\smixed\sASC/DESC\sindexes. +D 2016-08-02T17:07:51.146 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 3340e479e5221f06c3d61726f8f7efff885e4233 @@ -463,7 +463,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 02eeecc265f6ffd0597378f5d8ae9070b62a406a F src/wal.h 6dd221ed384afdc204bc61e25c23ef7fd5a511f2 F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354 -F src/where.c 9dcbc1be0e8e84b1d323dae55983bbb902a6c484 +F src/where.c 25eae2e051809c75a8a1a23288f335382ac0215f F src/whereInt.h 14dd243e13b81cbb0a66063d38b70f93a7d6e613 F src/wherecode.c c01c8af9311b5d6d65de311101f72d94a11ae506 F src/whereexpr.c 4a8cefc7c122132ac9f3ed125c61629a0e3de094 @@ -1020,8 +1020,8 @@ F test/rowhash.test 0bc1d31415e4575d10cacf31e1a66b5cc0f8be81 F test/rowid.test 5b7509f384f4f6fae1af3c8c104c8ca299fea18d F test/rowvalue.test 56b34d31d91340a6e922e753b798880170cc1aa7 F test/rowvalue2.test 8d5dfe75b8f4d1868a2f91f0356f20d36cba64ff -F test/rowvalue3.test 5127afb4414bf62546161497c04840c46e371770 -F test/rowvalue4.test 4480898d62d6813e3e38d9d38c02b9a0be5f94be +F test/rowvalue3.test dbe935260851b197dfbbbcb0ac2a15cb5f324fd4 +F test/rowvalue4.test 9e720652d4db9ef3bea50227c69e33d7e64801c6 F test/rtree.test 0c8d9dd458d6824e59683c19ab2ffa9ef946f798 F test/run-wordcount.sh 891e89c4c2d16e629cd45951d4ed899ad12afc09 F test/savepoint.test c671fdbd34cd3bfe1518a777526ada595180cf8d @@ -1133,7 +1133,7 @@ F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30 F test/temptable2.test cd396beb41117a5302fff61767c35fa4270a0d5e F test/temptable3.test d11a0974e52b347e45ee54ef1923c91ed91e4637 F test/temptrigger.test 8ec228b0db5d7ebc4ee9b458fc28cb9e7873f5e1 -F test/tester.tcl 542e38e307a6c1c362122d186f580ec3e58a288c +F test/tester.tcl 4ce5afd5e192db4cae178e1a983b060e0f08c5d6 F test/thread001.test 9f22fd3525a307ff42a326b6bc7b0465be1745a5 F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58 F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7 @@ -1513,7 +1513,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 6937677cc2c2db6b21f997559f88a339466cd15b b23c10ac8f65bc88a6c7d88e140217222eb4cbe5 -R bdbd7298ee0fa9cbc2f39cf393323b85 +P d468101b421e073e9debd7381bde1d36af31369e +R e4db8db490358e0865afed7cef96935f U dan -Z eb5884061bde99d3b56b31ee8ac9fde1 +Z 8c6bb4cf90fd1cc092b885dc43b4c6ef diff --git a/manifest.uuid b/manifest.uuid index 5800b91b48..9c30fb99ac 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d468101b421e073e9debd7381bde1d36af31369e \ No newline at end of file +e2ad30c8b5366fd8e50f36c62345ed03ec613c47 \ No newline at end of file diff --git a/src/where.c b/src/where.c index 43445c08a2..3e8dea70a1 100644 --- a/src/where.c +++ b/src/where.c @@ -2226,11 +2226,13 @@ int whereRangeVectorLen( } /* Check that the LHS of the comparison is a column reference to - ** the right column of the right source table. - */ + ** the right column of the right source table. And that the sort + ** order of the index column is the same as the sort order of the + ** leftmost index column. */ if( pLhs->op!=TK_COLUMN || pLhs->iTable!=iCur || pLhs->iColumn!=pIdx->aiColumn[i+nEq] + || pIdx->aSortOrder[i]!=pIdx->aSortOrder[0] ){ break; } diff --git a/test/rowvalue3.test b/test/rowvalue3.test index 2da141ec72..17bf96a0f4 100644 --- a/test/rowvalue3.test +++ b/test/rowvalue3.test @@ -17,15 +17,6 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl set ::testprefix rowvalue3 -# Drop all auxiliary indexes from the main database opened by handle [db]. -# -proc drop_all_indexes {} { - set L [db eval { - SELECT name FROM sqlite_master WHERE type='index' AND sql LIKE 'create%' - }] - foreach idx $L { db eval "DROP INDEX $idx" } -} - do_execsql_test 1.0 { CREATE TABLE t1(a, b, c); CREATE INDEX i1 ON t1(a, b); diff --git a/test/rowvalue4.test b/test/rowvalue4.test index 1dfcfb903a..ccae0498e1 100644 --- a/test/rowvalue4.test +++ b/test/rowvalue4.test @@ -17,7 +17,14 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl set ::testprefix rowvalue4 -do_execsql_test 0 { +#------------------------------------------------------------------------- +# Test some error conditions: +# +# * row values used where they are not supported, +# * row values or sub-selects that contain/return the wrong number +# of elements. +# +do_execsql_test 1.0 { CREATE TABLE t1(a, b, c); CREATE INDEX t1bac ON t1(b, a, c); } @@ -44,5 +51,60 @@ foreach {tn s error} { do_catchsql_test 2.$tn "$s" [list 1 $error] } +#------------------------------------------------------------------------- +do_execsql_test 2.0 { + CREATE TABLE t2(a, b, c, d); + INSERT INTO t2 VALUES(1, 1, 1, 1); + INSERT INTO t2 VALUES(1, 1, 2, 2); + INSERT INTO t2 VALUES(1, 1, 3, 3); + INSERT INTO t2 VALUES(1, 2, 1, 4); + INSERT INTO t2 VALUES(1, 2, 2, 5); + INSERT INTO t2 VALUES(1, 2, 3, 6); + INSERT INTO t2 VALUES(1, 3, 1, 7); + INSERT INTO t2 VALUES(1, 3, 2, 8); + INSERT INTO t2 VALUES(1, 3, 3, 9); + + INSERT INTO t2 VALUES(2, 1, 1, 10); + INSERT INTO t2 VALUES(2, 1, 2, 11); + INSERT INTO t2 VALUES(2, 1, 3, 12); + INSERT INTO t2 VALUES(2, 2, 1, 13); + INSERT INTO t2 VALUES(2, 2, 2, 14); + INSERT INTO t2 VALUES(2, 2, 3, 15); + INSERT INTO t2 VALUES(2, 3, 1, 16); + INSERT INTO t2 VALUES(2, 3, 2, 17); + INSERT INTO t2 VALUES(2, 3, 3, 18); + + INSERT INTO t2 VALUES(3, 1, 1, 19); + INSERT INTO t2 VALUES(3, 1, 2, 20); + INSERT INTO t2 VALUES(3, 1, 3, 21); + INSERT INTO t2 VALUES(3, 2, 1, 22); + INSERT INTO t2 VALUES(3, 2, 2, 23); + INSERT INTO t2 VALUES(3, 2, 3, 24); + INSERT INTO t2 VALUES(3, 3, 1, 25); + INSERT INTO t2 VALUES(3, 3, 2, 26); + INSERT INTO t2 VALUES(3, 3, 3, 27); +} + +foreach {nm idx} { + idx1 {} + idx2 { CREATE INDEX t2abc ON t2(a, b, c); } + idx3 { CREATE INDEX t2abc ON t2(a, b DESC, c); } + idx4 { CREATE INDEX t2abc ON t2(a DESC, b DESC, c DESC); } + idx5 { CREATE INDEX t2abc ON t2(a ASC, b ASC, c ASC); } + idx6 { CREATE INDEX t2abc ON t2(a DESC, b, c); } +} { + drop_all_indexes + execsql $idx + + foreach {tn where res} { + 1 "(a, b, c) < (2, 2, 2)" {1 2 3 4 5 6 7 8 9 10 11 12 13} + 2 "(a, b, c) <= (2, 2, 2)" {1 2 3 4 5 6 7 8 9 10 11 12 13 14} + 3 "(a, b, c) > (2, 2, 2)" {15 16 17 18 19 20 21 22 23 24 25 26 27} + 4 "(a, b, c) >= (2, 2, 2)" {14 15 16 17 18 19 20 21 22 23 24 25 26 27} + } { + set result [db eval "SELECT d FROM t2 WHERE $where"] + do_test 2.$nm.$tn { lsort -integer $result } $res + } +} finish_test diff --git a/test/tester.tcl b/test/tester.tcl index 8e470cc9e3..814788ba45 100644 --- a/test/tester.tcl +++ b/test/tester.tcl @@ -25,6 +25,7 @@ # copy_file FROM TO # delete_file FILENAME # drop_all_tables ?DB? +# drop_all_indexes ?DB? # forcecopy FROM TO # forcedelete FILENAME # @@ -1951,6 +1952,16 @@ proc drop_all_tables {{db db}} { } } +# Drop all auxiliary indexes from the main database opened by handle [db]. +# +proc drop_all_indexes {{db db}} { + set L [$db eval { + SELECT name FROM sqlite_master WHERE type='index' AND sql LIKE 'create%' + }] + foreach idx $L { $db eval "DROP INDEX $idx" } +} + + #------------------------------------------------------------------------- # If a test script is executed with global variable $::G(perm:name) set to # "wal", then the tests are run in WAL mode. Otherwise, they should be run From f9b2e05c75e55ca795caa825bfcba1c0760ea35f Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 2 Aug 2016 17:45:00 +0000 Subject: [PATCH 0655/1484] Fix SQLITE_OMIT_SUBQUERY builds. FossilOrigin-Name: 339f85f414a484e44d2502d1ff7281caf9b7c838 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/expr.c | 8 ++++++++ src/sqliteInt.h | 7 ++++++- src/wherecode.c | 20 +++++++++++++------- 5 files changed, 36 insertions(+), 17 deletions(-) diff --git a/manifest b/manifest index ba89d2088a..c6971b1622 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\swith\svector\srange\sconstraints\sand\smixed\sASC/DESC\sindexes. -D 2016-08-02T17:07:51.146 +C Fix\sSQLITE_OMIT_SUBQUERY\sbuilds. +D 2016-08-02T17:45:00.556 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 3340e479e5221f06c3d61726f8f7efff885e4233 @@ -337,7 +337,7 @@ F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7 F src/date.c 1cc9fb516ec9932c6fd4d2a0d2f8bc4480145c39 F src/dbstat.c 4f6f7f52b49beb9636ffbd517cfe44a402ba4ad0 F src/delete.c 4aba4214a377ce8ddde2d2e609777bcc8235200f -F src/expr.c 4db65a0c33003a00314fb56dca32d9cdbb6448a6 +F src/expr.c 200cad2bc4eaaea03d36d1a13c47a90f6595154d F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c bc4145347595b7770f9a598cff1c848302cf5413 F src/func.c 61a4114cf7004f10c542cfabbab9f2bcb9033045 @@ -388,7 +388,7 @@ F src/shell.c 79dda477be6c96eba6e952a934957ad36f87acc7 F src/sqlite.h.in e011dcc3942e6ddc8dd7b894e9e6702e4269161e F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae -F src/sqliteInt.h ccfffd24330a373a971fee69b6b06a9b7e9ddced +F src/sqliteInt.h 9d6623807cc94dfa49d0eab6380ad77091e97019 F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 @@ -465,7 +465,7 @@ F src/wal.h 6dd221ed384afdc204bc61e25c23ef7fd5a511f2 F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354 F src/where.c 25eae2e051809c75a8a1a23288f335382ac0215f F src/whereInt.h 14dd243e13b81cbb0a66063d38b70f93a7d6e613 -F src/wherecode.c c01c8af9311b5d6d65de311101f72d94a11ae506 +F src/wherecode.c c2392fa30bcb0c555a8ae402d646b357ca428ad6 F src/whereexpr.c 4a8cefc7c122132ac9f3ed125c61629a0e3de094 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -1513,7 +1513,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d468101b421e073e9debd7381bde1d36af31369e -R e4db8db490358e0865afed7cef96935f +P e2ad30c8b5366fd8e50f36c62345ed03ec613c47 +R 4d69da3a911755cf5dde753475b8adf2 U dan -Z 8c6bb4cf90fd1cc092b885dc43b4c6ef +Z aa590e568ce86faba8eaef4a3eef0582 diff --git a/manifest.uuid b/manifest.uuid index 9c30fb99ac..fc2a84a3ab 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e2ad30c8b5366fd8e50f36c62345ed03ec613c47 \ No newline at end of file +339f85f414a484e44d2502d1ff7281caf9b7c838 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 53c00952f3..c469b463e2 100644 --- a/src/expr.c +++ b/src/expr.c @@ -332,6 +332,7 @@ int sqlite3ExprVectorSize(Expr *pExpr){ return pExpr->x.pList->nExpr; } +#ifndef SQLITE_OMIT_SUBQUERY /* ** If the expression passed as the first argument is a TK_VECTOR, return ** a pointer to the i'th field of the vector. Or, if the first argument @@ -350,6 +351,7 @@ static Expr *exprVectorField(Expr *pVector, int i){ } return pVector; } +#endif /* ** If expression pExpr is of type TK_SELECT, generate code to evaluate @@ -361,9 +363,11 @@ static Expr *exprVectorField(Expr *pVector, int i){ */ static int exprCodeSubselect(Parse *pParse, Expr *pExpr){ int reg = 0; +#ifndef SQLITE_OMIT_SUBQUERY if( pExpr->op==TK_SELECT ){ reg = sqlite3CodeSubselect(pParse, pExpr, 0, 0); } +#endif return reg; } @@ -1829,6 +1833,7 @@ int sqlite3CodeOnce(Parse *pParse){ return sqlite3VdbeAddOp1(v, OP_Once, pParse->nOnce++); } +#ifndef SQLITE_OMIT_SUBQUERY /* ** Generate code that checks the left-most column of index table iCur to see if ** it contains any NULL entries. Cause the register at regHasNull to be set @@ -1844,6 +1849,7 @@ static void sqlite3SetHasNullFlag(Vdbe *v, int iCur, int regHasNull){ VdbeComment((v, "first_entry_in(%d)", iCur)); sqlite3VdbeJumpHere(v, addr1); } +#endif #ifndef SQLITE_OMIT_SUBQUERY @@ -2130,6 +2136,7 @@ int sqlite3FindInIndex( } #endif +#ifndef SQLITE_OMIT_SUBQUERY /* ** Argument pExpr is an (?, ?...) IN(...) expression. This ** function allocates and returns a nul-terminated string containing @@ -2161,6 +2168,7 @@ static char *exprINAffinity(Parse *pParse, Expr *pExpr){ } return zRet; } +#endif #ifndef SQLITE_OMIT_SUBQUERY /* diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 4c91d4657d..56da61a2aa 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3944,7 +3944,6 @@ int sqlite3GetToken(const unsigned char *, int *); void sqlite3NestedParse(Parse*, const char*, ...); void sqlite3ExpirePreparedStatements(sqlite3*); int sqlite3CodeSubselect(Parse*, Expr *, int, int); -int sqlite3ExprCheckIN(Parse*, Expr*); void sqlite3SelectPrep(Parse*, Select*, NameContext*); void sqlite3SelectWrongNumTermsError(Parse *pParse, Select *p); int sqlite3MatchSpanName(const char*, const char*, const char*, const char*); @@ -3999,6 +3998,12 @@ Expr *sqlite3CreateColumnExpr(sqlite3 *, SrcList *, int, int); void sqlite3BackupRestart(sqlite3_backup *); void sqlite3BackupUpdate(sqlite3_backup *, Pgno, const u8 *); +#ifndef SQLITE_OMIT_SUBQUERY +int sqlite3ExprCheckIN(Parse*, Expr*); +#else +# define sqlite3ExprCheckIN(x,y) SQLITE_OK +#endif + #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 void sqlite3AnalyzeFunctions(void); int sqlite3Stat4ProbeSetValue(Parse*,Index*,UnpackedRecord**,Expr*,u8,int,int*); diff --git a/src/wherecode.c b/src/wherecode.c index 11e9bbda34..9aafa83665 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -360,6 +360,7 @@ static int codeEqualityTerm( assert( iTarget>0 ); if( pX->op==TK_EQ || pX->op==TK_IS ){ Expr *pRight = pX->pRight; +#ifndef SQLITE_OMIT_SUBQUERY if( pRight->op==TK_SELECT_COLUMN ){ /* This case occurs for expressions like "(a, b) == (SELECT ...)". */ WhereLoop *pLoop = pLevel->pWLoop; @@ -381,7 +382,9 @@ static int codeEqualityTerm( } } iReg = iTarget; - }else{ + }else +#endif + { iReg = sqlite3ExprCodeTarget(pParse, pRight, iTarget); } }else if( pX->op==TK_ISNULL ){ @@ -962,17 +965,20 @@ static void codeDeferredSeek( static void codeExprOrVector(Parse *pParse, Expr *p, int iReg, int nReg){ assert( nReg>0 ); if( sqlite3ExprIsVector(p) ){ - int i; - if( (p->flags & EP_xIsSelect)==0 ){ +#ifndef SQLITE_OMIT_SUBQUERY + if( (p->flags & EP_xIsSelect) ){ + Vdbe *v = pParse->pVdbe; + int iSelect = sqlite3CodeSubselect(pParse, p, 0, 0); + sqlite3VdbeAddOp3(v, OP_Copy, iSelect, iReg, nReg-1); + }else +#endif + { + int i; ExprList *pList = p->x.pList; assert( nReg<=pList->nExpr ); for(i=0; ia[i].pExpr, iReg+i); } - }else{ - Vdbe *v = pParse->pVdbe; - int iSelect = sqlite3CodeSubselect(pParse, p, 0, 0); - sqlite3VdbeAddOp3(v, OP_Copy, iSelect, iReg, nReg-1); } }else{ assert( nReg==1 ); From 51d82d1d2443c55669c60630ed28d55ae03a57b0 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 2 Aug 2016 18:50:15 +0000 Subject: [PATCH 0656/1484] Add tests and fixes for vector operations that use sub-queries with different combinations of LIMIT, OFFSET and ORDER BY clauses. FossilOrigin-Name: 092b1c5ff53c9f3cfed079c46e3353d93f99303e --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/select.c | 13 +++++++++++-- test/rowvalue4.test | 40 +++++++++++++++++++++++++++++++++++++++- 4 files changed, 58 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index c6971b1622..b7b01adb06 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sSQLITE_OMIT_SUBQUERY\sbuilds. -D 2016-08-02T17:45:00.556 +C Add\stests\sand\sfixes\sfor\svector\soperations\sthat\suse\ssub-queries\swith\sdifferent\scombinations\sof\sLIMIT,\sOFFSET\sand\sORDER\sBY\sclauses. +D 2016-08-02T18:50:15.542 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 3340e479e5221f06c3d61726f8f7efff885e4233 @@ -383,7 +383,7 @@ F src/printf.c a5f0ca08ddede803c241266abb46356ec748ded1 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c cca3aa77b95706df5d635a2141a4d1de60ae6598 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac -F src/select.c 952aa1b4148ed4c0024586e9049b8742a765c6f9 +F src/select.c 228eec644a778a31763b3d384d1ee1a5e3cf2349 F src/shell.c 79dda477be6c96eba6e952a934957ad36f87acc7 F src/sqlite.h.in e011dcc3942e6ddc8dd7b894e9e6702e4269161e F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1021,7 +1021,7 @@ F test/rowid.test 5b7509f384f4f6fae1af3c8c104c8ca299fea18d F test/rowvalue.test 56b34d31d91340a6e922e753b798880170cc1aa7 F test/rowvalue2.test 8d5dfe75b8f4d1868a2f91f0356f20d36cba64ff F test/rowvalue3.test dbe935260851b197dfbbbcb0ac2a15cb5f324fd4 -F test/rowvalue4.test 9e720652d4db9ef3bea50227c69e33d7e64801c6 +F test/rowvalue4.test 9aa6a5efe6069b34bcbefe004bb481cdaaca0dc5 F test/rtree.test 0c8d9dd458d6824e59683c19ab2ffa9ef946f798 F test/run-wordcount.sh 891e89c4c2d16e629cd45951d4ed899ad12afc09 F test/savepoint.test c671fdbd34cd3bfe1518a777526ada595180cf8d @@ -1513,7 +1513,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e2ad30c8b5366fd8e50f36c62345ed03ec613c47 -R 4d69da3a911755cf5dde753475b8adf2 +P 339f85f414a484e44d2502d1ff7281caf9b7c838 +R c52410c242ecf248d644374975097b8c U dan -Z aa590e568ce86faba8eaef4a3eef0582 +Z 38a047c096aac032ca966b61ad2f4616 diff --git a/manifest.uuid b/manifest.uuid index fc2a84a3ab..eacf0abe20 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -339f85f414a484e44d2502d1ff7281caf9b7c838 \ No newline at end of file +092b1c5ff53c9f3cfed079c46e3353d93f99303e \ No newline at end of file diff --git a/src/select.c b/src/select.c index 6aba96730a..7bcf3eca16 100644 --- a/src/select.c +++ b/src/select.c @@ -873,7 +873,8 @@ static void selectInnerLoop( ** ORDER BY in this case since the order of entries in the set ** does not matter. But there might be a LIMIT clause, in which ** case the order does matter */ - pushOntoSorter(pParse, pSort, p, regResult, regResult, 1, nPrefixReg); + pushOntoSorter( + pParse, pSort, p, regResult, regResult, nResultCol, nPrefixReg); }else{ int r1 = sqlite3GetTempReg(pParse); assert( sqlite3Strlen30(pDest->zAffSdst)==nResultCol ); @@ -1221,6 +1222,10 @@ static void generateSortTail( regRowid = 0; regRow = pDest->iSdst; nSortData = nColumn; + }else if( eDest==SRT_Set ){ + regRowid = sqlite3GetTempReg(pParse); + regRow = sqlite3GetTempRange(pParse, nColumn); + nSortData = nColumn; }else{ regRowid = sqlite3GetTempReg(pParse); regRow = sqlite3GetTempReg(pParse); @@ -1285,7 +1290,11 @@ static void generateSortTail( } } if( regRowid ){ - sqlite3ReleaseTempReg(pParse, regRow); + if( eDest==SRT_Set ){ + sqlite3ReleaseTempRange(pParse, regRow, nColumn); + }else{ + sqlite3ReleaseTempReg(pParse, regRow); + } sqlite3ReleaseTempReg(pParse, regRowid); } /* The bottom of the loop diff --git a/test/rowvalue4.test b/test/rowvalue4.test index ccae0498e1..c0e0933ebd 100644 --- a/test/rowvalue4.test +++ b/test/rowvalue4.test @@ -92,6 +92,9 @@ foreach {nm idx} { idx4 { CREATE INDEX t2abc ON t2(a DESC, b DESC, c DESC); } idx5 { CREATE INDEX t2abc ON t2(a ASC, b ASC, c ASC); } idx6 { CREATE INDEX t2abc ON t2(a DESC, b, c); } + idx7 { CREATE INDEX t2abc ON t2(a DESC, b DESC) } + idx8 { CREATE INDEX t2abc ON t2(c, b, a); } + idx9 { CREATE INDEX t2d ON t2(d); } } { drop_all_indexes execsql $idx @@ -101,10 +104,45 @@ foreach {nm idx} { 2 "(a, b, c) <= (2, 2, 2)" {1 2 3 4 5 6 7 8 9 10 11 12 13 14} 3 "(a, b, c) > (2, 2, 2)" {15 16 17 18 19 20 21 22 23 24 25 26 27} 4 "(a, b, c) >= (2, 2, 2)" {14 15 16 17 18 19 20 21 22 23 24 25 26 27} + 5 "(a, b, c) >= (2, 2, NULL)" {16 17 18 19 20 21 22 23 24 25 26 27} + 6 "(a, b, c) <= (2, 2, NULL)" {1 2 3 4 5 6 7 8 9 10 11 12} + 7 "(a, b, c) >= (2, NULL, NULL)" {19 20 21 22 23 24 25 26 27} + 8 "(a, b, c) <= (2, NULL, NULL)" {1 2 3 4 5 6 7 8 9} + + 9 "(a, b, c) < (SELECT a, b, c FROM t2 WHERE d=14)" + {1 2 3 4 5 6 7 8 9 10 11 12 13} + + 10 "(a, b, c) = (SELECT a, b, c FROM t2 WHERE d=14)" 14 } { set result [db eval "SELECT d FROM t2 WHERE $where"] - do_test 2.$nm.$tn { lsort -integer $result } $res + do_test 2.1.$nm.$tn { lsort -integer $result } $res + } + + foreach {tn e res} { + 1 "(2, 1) IN (SELECT a, b FROM t2)" 1 + 2 "(2, 1) IN (SELECT a, b FROM t2 ORDER BY d)" 1 + 3 "(2, 1) IN (SELECT a, b FROM t2 ORDER BY d LIMIT 9)" 0 + 4 "(2, 1) IN (SELECT a, b FROM t2 ORDER BY d LIMIT 10)" 1 + + 5 "(3, 3) = (SELECT a, b FROM t2 ORDER BY d DESC LIMIT 1)" 1 + 6 "(3, 3) = (SELECT a, b FROM t2 ORDER BY d ASC LIMIT 1)" 0 + 7 "(1, NULL) = (SELECT a, b FROM t2 ORDER BY d ASC LIMIT 1)" {{}} + + 8 "(3, 1) = (SELECT b, c FROM t2 ORDER BY d DESC LIMIT 1 OFFSET 2)" 1 + 9 "(3, 1) = (SELECT b, c FROM t2 ORDER BY d ASC LIMIT 1 OFFSET 2)" 0 + 10 "(1, NULL) = (SELECT b, c FROM t2 ORDER BY d ASC LIMIT 1 OFFSET 2)" {{}} + + 11 "(3, 3) = (SELECT max(a), max(b) FROM t2)" 1 + 12 "(3, 1) = (SELECT max(a), min(b) FROM t2)" 1 + 13 "(NULL, NULL) = (SELECT max(a), min(b) FROM t2)" {{}} + + 14 "(2, 1) IN (SELECT a, b FROM t2 ORDER BY d LIMIT 5 OFFSET 11)" 1 + 15 "(2, 1) IN (SELECT a, b FROM t2 ORDER BY d LIMIT 5 OFFSET 12)" 0 + } { + do_execsql_test 2.2.$nm.$tn "SELECT $e" $res } } + + finish_test From 3dffcf911fbda3b84a902e716ed0b8db6647d6df Mon Sep 17 00:00:00 2001 From: mistachkin Date: Tue, 2 Aug 2016 19:29:56 +0000 Subject: [PATCH 0657/1484] The 'replace.tcl' tool should use Unix line-endings. FossilOrigin-Name: 50de96314f75494dc1f5b14d62c595a70c4e0638 --- manifest | 14 +++++++------- manifest.uuid | 2 +- tool/replace.tcl | 2 ++ 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index dcecb8eb96..b092c43c87 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Updates\sto\srequirements\smarks.\s\sNo\schanges\sto\scode. -D 2016-08-02T13:26:34.987 +C The\s'replace.tcl'\stool\sshould\suse\sUnix\sline-endings. +D 2016-08-02T19:29:56.543 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 3340e479e5221f06c3d61726f8f7efff885e4233 @@ -1458,7 +1458,7 @@ F tool/offsets.c fe4262fdfa378e8f5499a42136d17bf3b98f6091 F tool/omittest.tcl 34d7ac01fe4fd18e3637f64abe12c40eca0f6b97 F tool/opcodesum.tcl 740ed206ba8c5040018988129abbf3089a0ccf4a F tool/pagesig.c ff0ca355fd3c2398e933da5e22439bbff89b803b -F tool/replace.tcl 3856f87247dde5418d16dac92fa4060813431778 +F tool/replace.tcl 60f91e8dd06ab81f74d213ecbd9c9945f32ac048 F tool/restore_jrnl.tcl 6957a34f8f1f0f8285e07536225ec3b292a9024a F tool/rollback-test.c 9fc98427d1e23e84429d7e6d07d9094fbdec65a5 F tool/run-speed-test.sh f95d19fd669b68c4c38b6b475242841d47c66076 @@ -1509,7 +1509,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e64a4173d2899acf13b73e6e28f2e164fd638a75 -R 2f7c4e993e0eb7bb61a5a37266251c67 -U drh -Z 9edc5e5cd5ca93c7d8faa216313b72e1 +P b23c10ac8f65bc88a6c7d88e140217222eb4cbe5 +R c637e4e7f2506406f1e6f5b4d9531797 +U mistachkin +Z d4fd0c8d72e7f688d1f1613e04849643 diff --git a/manifest.uuid b/manifest.uuid index ac57330bc6..f5829a3ed7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b23c10ac8f65bc88a6c7d88e140217222eb4cbe5 \ No newline at end of file +50de96314f75494dc1f5b14d62c595a70c4e0638 \ No newline at end of file diff --git a/tool/replace.tcl b/tool/replace.tcl index 1ecc6dc7b5..5a1ac5983c 100644 --- a/tool/replace.tcl +++ b/tool/replace.tcl @@ -4,6 +4,8 @@ # only lines successfully modified with a regular # expression. # +fconfigure stdout -translation binary -encoding binary +fconfigure stderr -translation binary -encoding binary set mode [string tolower [lindex $argv 0]] set from [lindex $argv 1] set to [lindex $argv 2] From c330887291f376837c13a54abd4b9f593085d0bf Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 2 Aug 2016 20:42:24 +0000 Subject: [PATCH 0658/1484] Fix a unused variable that comes up with -DSQLITE_OMIT_DATETIME_FUNCS. FossilOrigin-Name: e2f9919e34c70761e4e275eeffca8ccf9159223c --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/date.c | 1 - 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index b092c43c87..592c083bb1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C The\s'replace.tcl'\stool\sshould\suse\sUnix\sline-endings. -D 2016-08-02T19:29:56.543 +C Fix\sa\sunused\svariable\sthat\scomes\sup\swith\s-DSQLITE_OMIT_DATETIME_FUNCS. +D 2016-08-02T20:42:24.701 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 3340e479e5221f06c3d61726f8f7efff885e4233 @@ -334,7 +334,7 @@ F src/build.c d1fdfd7ab8f5447e494ef15825973bf0719527c6 F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7 -F src/date.c 1cc9fb516ec9932c6fd4d2a0d2f8bc4480145c39 +F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b F src/dbstat.c 4f6f7f52b49beb9636ffbd517cfe44a402ba4ad0 F src/delete.c 4aba4214a377ce8ddde2d2e609777bcc8235200f F src/expr.c fbc17c717a80b5b61158ea8f25b5af6f8cad66f8 @@ -1509,7 +1509,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b23c10ac8f65bc88a6c7d88e140217222eb4cbe5 -R c637e4e7f2506406f1e6f5b4d9531797 -U mistachkin -Z d4fd0c8d72e7f688d1f1613e04849643 +P 50de96314f75494dc1f5b14d62c595a70c4e0638 +R bccad16ef0c054ea297f2741dafcd976 +U drh +Z 284a9c0bc53e79a17d5b080e8200faff diff --git a/manifest.uuid b/manifest.uuid index f5829a3ed7..9ebb47b886 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -50de96314f75494dc1f5b14d62c595a70c4e0638 \ No newline at end of file +e2f9919e34c70761e4e275eeffca8ccf9159223c \ No newline at end of file diff --git a/src/date.c b/src/date.c index cce16305a3..8b2f2fa717 100644 --- a/src/date.c +++ b/src/date.c @@ -1112,7 +1112,6 @@ static void currentTimeFunc( ){ time_t t; char *zFormat = (char *)sqlite3_user_data(context); - sqlite3 *db; sqlite3_int64 iT; struct tm *pTm; struct tm sNow; From 78f9bb6c717275422a25dadd67df1bb3a2e3f971 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 2 Aug 2016 20:45:56 +0000 Subject: [PATCH 0659/1484] Add new test file rowvaluefault.test. FossilOrigin-Name: e496b2d63984311e6ae117677e6c2417ae24b6bc --- manifest | 11 ++++--- manifest.uuid | 2 +- test/rowvaluefault.test | 72 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 79 insertions(+), 6 deletions(-) create mode 100644 test/rowvaluefault.test diff --git a/manifest b/manifest index b7b01adb06..0b758663bc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\stests\sand\sfixes\sfor\svector\soperations\sthat\suse\ssub-queries\swith\sdifferent\scombinations\sof\sLIMIT,\sOFFSET\sand\sORDER\sBY\sclauses. -D 2016-08-02T18:50:15.542 +C Add\snew\stest\sfile\srowvaluefault.test. +D 2016-08-02T20:45:56.795 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 3340e479e5221f06c3d61726f8f7efff885e4233 @@ -1022,6 +1022,7 @@ F test/rowvalue.test 56b34d31d91340a6e922e753b798880170cc1aa7 F test/rowvalue2.test 8d5dfe75b8f4d1868a2f91f0356f20d36cba64ff F test/rowvalue3.test dbe935260851b197dfbbbcb0ac2a15cb5f324fd4 F test/rowvalue4.test 9aa6a5efe6069b34bcbefe004bb481cdaaca0dc5 +F test/rowvaluefault.test 7b16485e3f2b371f3e3d05455b8ded6d0c090244 F test/rtree.test 0c8d9dd458d6824e59683c19ab2ffa9ef946f798 F test/run-wordcount.sh 891e89c4c2d16e629cd45951d4ed899ad12afc09 F test/savepoint.test c671fdbd34cd3bfe1518a777526ada595180cf8d @@ -1513,7 +1514,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 339f85f414a484e44d2502d1ff7281caf9b7c838 -R c52410c242ecf248d644374975097b8c +P 092b1c5ff53c9f3cfed079c46e3353d93f99303e +R 7575cd5084e4e0e048e98a52c8b1c879 U dan -Z 38a047c096aac032ca966b61ad2f4616 +Z 1ac631fd43d573ba36f8f7688c8dc1d7 diff --git a/manifest.uuid b/manifest.uuid index eacf0abe20..4cf8fbb9bc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -092b1c5ff53c9f3cfed079c46e3353d93f99303e \ No newline at end of file +e496b2d63984311e6ae117677e6c2417ae24b6bc \ No newline at end of file diff --git a/test/rowvaluefault.test b/test/rowvaluefault.test new file mode 100644 index 0000000000..0a4da6ba47 --- /dev/null +++ b/test/rowvaluefault.test @@ -0,0 +1,72 @@ +# 2016 June 17 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements regression tests for SQLite library. +# + + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +source $testdir/malloc_common.tcl +set ::testprefix rowvaluefault + +do_execsql_test 1.0 { + CREATE TABLE xyz(one, two, thr, fou); + INSERT INTO xyz VALUES('A', 'A', 'A', 1); + INSERT INTO xyz VALUES('B', 'B', 'B', 2); + INSERT INTO xyz VALUES('C', 'C', 'C', 3); + INSERT INTO xyz VALUES('D', 'D', 'D', 4); + + CREATE UNIQUE INDEX xyz_one_two ON xyz(one, two); +} + +do_faultsim_test 1 -faults oom* -body { + execsql { SELECT fou FROM xyz WHERE (one, two, thr) = ('B', 'B', 'B') } +} -test { + faultsim_test_result {0 2} +} + +do_faultsim_test 2 -faults oom* -body { + execsql { SELECT fou FROM xyz WHERE (two, thr) IS ('C', 'C') } +} -test { + faultsim_test_result {0 3} +} + +do_faultsim_test 3 -faults oom* -body { + execsql { SELECT fou FROM xyz WHERE (one, two, thr) > ('B', 'B', 'B') } +} -test { + faultsim_test_result {0 {3 4}} +} + +do_faultsim_test 4 -faults oom* -body { + execsql { SELECT fou FROM xyz WHERE (one, two) IN (SELECT one, two FROM xyz) } +} -test { + faultsim_test_result {0 {1 2 3 4}} +} + +do_faultsim_test 5 -faults oom* -body { + execsql { + SELECT fou FROM xyz + WHERE (one, two, thr) IN (SELECT one, two, thr FROM xyz) + } +} -test { + faultsim_test_result {0 {1 2 3 4}} +} + +do_faultsim_test 6 -faults oom* -body { + execsql { + SELECT fou FROM xyz + WHERE (one, two, thr) BETWEEN ('B', 'B', 'B') AND ('C', 'C', 'C') } +} -test { + faultsim_test_result {0 {2 3}} +} + +finish_test + From a36e01a7723ebb700fec0b9e3d428d24998e0035 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 3 Aug 2016 13:40:54 +0000 Subject: [PATCH 0660/1484] Fix the --help output on fuzzcheck so that it fix in an 80-character window. FossilOrigin-Name: b91444b5db8465f09d112455e722c888b3f94329 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/fuzzcheck.c | 34 +++++++++++++++++----------------- 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/manifest b/manifest index 592c083bb1..5028978397 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sunused\svariable\sthat\scomes\sup\swith\s-DSQLITE_OMIT_DATETIME_FUNCS. -D 2016-08-02T20:42:24.701 +C Fix\sthe\s--help\soutput\son\sfuzzcheck\sso\sthat\sit\sfix\sin\san\s80-character\swindow. +D 2016-08-03T13:40:54.644 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 3340e479e5221f06c3d61726f8f7efff885e4233 @@ -807,7 +807,7 @@ F test/fuzz2.test 76dc35b32b6d6f965259508508abce75a6c4d7e1 F test/fuzz3.test b47377143f0c80f91ed29d722861077ff34415d5 F test/fuzz_common.tcl a87dfbb88c2a6b08a38e9a070dabd129e617b45b F test/fuzz_malloc.test 328f70aaca63adf29b4c6f06505ed0cf57ca7c26 -F test/fuzzcheck.c f01d432d001ba29e7916df8411be7d4e7cddc574 +F test/fuzzcheck.c f2e8102f7829f7b946ebdb6f1a16c6f942d9de66 F test/fuzzdata1.db 7ee3227bad0e7ccdeb08a9e6822916777073c664 F test/fuzzdata2.db f03a420d3b822cc82e4f894ca957618fbe9c4973 F test/fuzzdata3.db c6586d3e3cef0fbc18108f9bb649aa77bfc38aba @@ -1509,7 +1509,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 50de96314f75494dc1f5b14d62c595a70c4e0638 -R bccad16ef0c054ea297f2741dafcd976 +P e2f9919e34c70761e4e275eeffca8ccf9159223c +R 6ce4351ec9908162cf69cba24dd464d6 U drh -Z 284a9c0bc53e79a17d5b080e8200faff +Z fde490c34eba36f3f6bb820fe63440a5 diff --git a/manifest.uuid b/manifest.uuid index 9ebb47b886..f473a8f752 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e2f9919e34c70761e4e275eeffca8ccf9159223c \ No newline at end of file +b91444b5db8465f09d112455e722c888b3f94329 \ No newline at end of file diff --git a/test/fuzzcheck.c b/test/fuzzcheck.c index 1d11b2986f..fec65881ce 100644 --- a/test/fuzzcheck.c +++ b/test/fuzzcheck.c @@ -782,23 +782,23 @@ static void showHelp(void){ "Read databases and SQL scripts from SOURCE-DB and execute each script against\n" "each database, checking for crashes and memory leaks.\n" "Options:\n" -" --cell-size-check Set the PRAGMA cell_size_check=ON\n" -" --dbid N Use only the database where dbid=N\n" -" --export-db DIR Write databases to files(s) in DIR. Works with --dbid\n" -" --export-sql DIR Write SQL to file(s) in DIR. Also works with --sqlid\n" -" --help Show this help text\n" -" -q|--quiet Reduced output\n" -" --limit-mem N Limit memory used by test SQLite instance to N bytes\n" -" --limit-vdbe Panic if an sync SQL runs for more than 100,000 cycles\n" -" --load-sql ARGS... Load SQL scripts fro files into SOURCE-DB\n" -" --load-db ARGS... Load template databases from files into SOURCE_DB\n" -" -m TEXT Add a description to the database\n" -" --native-vfs Use the native VFS for initially empty database files\n" -" --rebuild Rebuild and vacuum the database file\n" -" --result-trace Show the results of each SQL command\n" -" --sqlid N Use only SQL where sqlid=N\n" -" --timeout N Abort if any single test case needs more than N seconds\n" -" -v|--verbose Increased output. Repeat for more output.\n" +" --cell-size-check Set the PRAGMA cell_size_check=ON\n" +" --dbid N Use only the database where dbid=N\n" +" --export-db DIR Write databases to files(s) in DIR. Works with --dbid\n" +" --export-sql DIR Write SQL to file(s) in DIR. Also works with --sqlid\n" +" --help Show this help text\n" +" -q|--quiet Reduced output\n" +" --limit-mem N Limit memory used by test SQLite instance to N bytes\n" +" --limit-vdbe Panic if any test runs for more than 100,000 cycles\n" +" --load-sql ARGS... Load SQL scripts fro files into SOURCE-DB\n" +" --load-db ARGS... Load template databases from files into SOURCE_DB\n" +" -m TEXT Add a description to the database\n" +" --native-vfs Use the native VFS for initially empty database files\n" +" --rebuild Rebuild and vacuum the database file\n" +" --result-trace Show the results of each SQL command\n" +" --sqlid N Use only SQL where sqlid=N\n" +" --timeout N Abort if any single test needs more than N seconds\n" +" -v|--verbose Increased output. Repeat for more output.\n" ); } From c0d269e96ca1591110c67ce08958588582abc3cc Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 3 Aug 2016 14:51:16 +0000 Subject: [PATCH 0661/1484] Fix a typo in a comment in btree.c. No changes to code. FossilOrigin-Name: 722c12816347ee9fce7a090cfebef2c5841e7445 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btree.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 5028978397..558a3d8e2d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\s--help\soutput\son\sfuzzcheck\sso\sthat\sit\sfix\sin\san\s80-character\swindow. -D 2016-08-03T13:40:54.644 +C Fix\sa\stypo\sin\sa\scomment\sin\sbtree.c.\s\s\sNo\schanges\sto\scode. +D 2016-08-03T14:51:16.394 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 3340e479e5221f06c3d61726f8f7efff885e4233 @@ -327,7 +327,7 @@ F src/auth.c 5c8e0f37f785f935f589496801edd19840485853 F src/backup.c 6df65fdd569c901a418887a1a76f82ec35044556 F src/bitvec.c 3ee4c8b2c94ed3a7377256e18199e6ff5cf33f63 F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 -F src/btree.c 6a42efa461cf3a0c33e8755e9d236371ac80d1b3 +F src/btree.c 2551bd3ecb8b8988fb8b23aabadfb214dbc38e46 F src/btree.h 075c45707c0f8f8af118f739f36df8098a08b7da F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 F src/build.c d1fdfd7ab8f5447e494ef15825973bf0719527c6 @@ -1509,7 +1509,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e2f9919e34c70761e4e275eeffca8ccf9159223c -R 6ce4351ec9908162cf69cba24dd464d6 +P b91444b5db8465f09d112455e722c888b3f94329 +R aa712e9e7089879865bbb38d4c2c515d U drh -Z fde490c34eba36f3f6bb820fe63440a5 +Z 2b4f8b48b03032bd1efbc47f9457218f diff --git a/manifest.uuid b/manifest.uuid index f473a8f752..a6f1d523fa 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b91444b5db8465f09d112455e722c888b3f94329 \ No newline at end of file +722c12816347ee9fce7a090cfebef2c5841e7445 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 8ea20b9ad0..841aee9463 100644 --- a/src/btree.c +++ b/src/btree.c @@ -6385,7 +6385,7 @@ static void insertCell( /* ** A CellArray object contains a cache of pointers and sizes for a -** consecutive sequence of cells that might be held multiple pages. +** consecutive sequence of cells that might be held on multiple pages. */ typedef struct CellArray CellArray; struct CellArray { From d66e5794d1507ca44e9874401a59c081fec3132c Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 3 Aug 2016 16:14:33 +0000 Subject: [PATCH 0662/1484] Fix stat4-based cost estimates for vector range constraints. FossilOrigin-Name: 18af74abc8ceae47ab9fbee3e3e5bb37db8fcba5 --- manifest | 20 +++++++------- manifest.uuid | 2 +- src/expr.c | 18 ++++++------- src/sqliteInt.h | 5 +++- src/vdbemem.c | 53 +++++++++++++++++++++++-------------- src/where.c | 32 ++++++++++++----------- test/rowvalue4.test | 64 +++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 139 insertions(+), 55 deletions(-) diff --git a/manifest b/manifest index 0b758663bc..6c59839b10 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\snew\stest\sfile\srowvaluefault.test. -D 2016-08-02T20:45:56.795 +C Fix\sstat4-based\scost\sestimates\sfor\svector\srange\sconstraints. +D 2016-08-03T16:14:33.444 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 3340e479e5221f06c3d61726f8f7efff885e4233 @@ -337,7 +337,7 @@ F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7 F src/date.c 1cc9fb516ec9932c6fd4d2a0d2f8bc4480145c39 F src/dbstat.c 4f6f7f52b49beb9636ffbd517cfe44a402ba4ad0 F src/delete.c 4aba4214a377ce8ddde2d2e609777bcc8235200f -F src/expr.c 200cad2bc4eaaea03d36d1a13c47a90f6595154d +F src/expr.c 9539a6e0941248b63d631757406e089f48bea50c F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c bc4145347595b7770f9a598cff1c848302cf5413 F src/func.c 61a4114cf7004f10c542cfabbab9f2bcb9033045 @@ -388,7 +388,7 @@ F src/shell.c 79dda477be6c96eba6e952a934957ad36f87acc7 F src/sqlite.h.in e011dcc3942e6ddc8dd7b894e9e6702e4269161e F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae -F src/sqliteInt.h 9d6623807cc94dfa49d0eab6380ad77091e97019 +F src/sqliteInt.h a1cf00afd6a5666a160e81c7a600418a3b59a8a6 F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 @@ -455,7 +455,7 @@ F src/vdbeInt.h c59381049af5c7751a83456c39b80d1a6fde1f9d F src/vdbeapi.c c3f6715a99995c11748ecad91d25e93fd9fc390b F src/vdbeaux.c a32d79aeaa88dc2b97c261172d952d395254a055 F src/vdbeblob.c 83d2d266383157b02e2b809350bb197e89d7895b -F src/vdbemem.c 1ecaa5ee0caff07255f25d04e8dc88befb6f88d1 +F src/vdbemem.c 77d6505956bf4e45c328ab3ebef6b461334cab5d F src/vdbesort.c 91fda3909326860382b0ca8aa251e609c6a9d62c F src/vdbetrace.c 41963d5376f0349842b5fc4aaaaacd7d9cdc0834 F src/vtab.c 6fece06fdd50eb2b0673e37e627ce6710e4af5be @@ -463,7 +463,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 02eeecc265f6ffd0597378f5d8ae9070b62a406a F src/wal.h 6dd221ed384afdc204bc61e25c23ef7fd5a511f2 F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354 -F src/where.c 25eae2e051809c75a8a1a23288f335382ac0215f +F src/where.c 21095414c4bf8d5fdf05f3be790bf8b65e370f94 F src/whereInt.h 14dd243e13b81cbb0a66063d38b70f93a7d6e613 F src/wherecode.c c2392fa30bcb0c555a8ae402d646b357ca428ad6 F src/whereexpr.c 4a8cefc7c122132ac9f3ed125c61629a0e3de094 @@ -1021,7 +1021,7 @@ F test/rowid.test 5b7509f384f4f6fae1af3c8c104c8ca299fea18d F test/rowvalue.test 56b34d31d91340a6e922e753b798880170cc1aa7 F test/rowvalue2.test 8d5dfe75b8f4d1868a2f91f0356f20d36cba64ff F test/rowvalue3.test dbe935260851b197dfbbbcb0ac2a15cb5f324fd4 -F test/rowvalue4.test 9aa6a5efe6069b34bcbefe004bb481cdaaca0dc5 +F test/rowvalue4.test 86a04529ab1da3879d6ef56defe15446e4575b3d F test/rowvaluefault.test 7b16485e3f2b371f3e3d05455b8ded6d0c090244 F test/rtree.test 0c8d9dd458d6824e59683c19ab2ffa9ef946f798 F test/run-wordcount.sh 891e89c4c2d16e629cd45951d4ed899ad12afc09 @@ -1514,7 +1514,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 092b1c5ff53c9f3cfed079c46e3353d93f99303e -R 7575cd5084e4e0e048e98a52c8b1c879 +P e496b2d63984311e6ae117677e6c2417ae24b6bc +R 2ab02159e20122e5dc19c46ffdea23b5 U dan -Z 1ac631fd43d573ba36f8f7688c8dc1d7 +Z 1b607e01edb5341321c1446f2f3437dc diff --git a/manifest.uuid b/manifest.uuid index 4cf8fbb9bc..61422f33d0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e496b2d63984311e6ae117677e6c2417ae24b6bc \ No newline at end of file +18af74abc8ceae47ab9fbee3e3e5bb37db8fcba5 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index c469b463e2..70f7326935 100644 --- a/src/expr.c +++ b/src/expr.c @@ -340,7 +340,7 @@ int sqlite3ExprVectorSize(Expr *pExpr){ ** pointer to the i'th returned column value. Otherwise, return a copy ** of the first argument. */ -static Expr *exprVectorField(Expr *pVector, int i){ +Expr *sqlite3ExprVectorField(Expr *pVector, int i){ assert( iop==TK_SELECT ){ @@ -2025,7 +2025,7 @@ int sqlite3FindInIndex( ** comparison is the same as the affinity of each column. If ** it not, it is not possible to use any index. */ for(i=0; ipLeft, i); + Expr *pLhs = sqlite3ExprVectorField(pX->pLeft, i); int iCol = pEList->a[i].pExpr->iColumn; char idxaff = pTab->aCol[iCol].affinity; char cmpaff = sqlite3CompareAffinity(pLhs, idxaff); @@ -2051,7 +2051,7 @@ int sqlite3FindInIndex( } for(i=0; ipLeft, i); + Expr *pLhs = sqlite3ExprVectorField(pX->pLeft, i); Expr *pRhs = pEList->a[i].pExpr; CollSeq *pReq = sqlite3BinaryCompareCollSeq(pParse, pLhs, pRhs); int j; @@ -2156,7 +2156,7 @@ static char *exprINAffinity(Parse *pParse, Expr *pExpr){ if( zRet ){ int i; for(i=0; ipEList->a[i].pExpr, a); @@ -2308,7 +2308,7 @@ int sqlite3CodeSubselect( assert( pEList->nExpr>0 ); assert( sqlite3KeyInfoIsWriteable(pKeyInfo) ); for(i=0; i1) ? exprVectorField(pLeft, i) : pLeft; + Expr *p = (nVal>1) ? sqlite3ExprVectorField(pLeft, i) : pLeft; pKeyInfo->aColl[i] = sqlite3BinaryCompareCollSeq( pParse, p, pEList->a[i].pExpr ); @@ -2540,7 +2540,7 @@ static void sqlite3ExprCodeIN( } }else{ for(i=0; ipLeft, i); + Expr *p = sqlite3ExprVectorField(pExpr->pLeft, i); if( sqlite3ExprCanBeNull(p) ){ sqlite3VdbeAddOp2(v, OP_IsNull, r1+aiMap[i], destIfNull); } @@ -2638,7 +2638,7 @@ static void sqlite3ExprCodeIN( Expr *p; CollSeq *pColl; int r2 = sqlite3GetTempReg(pParse); - p = exprVectorField(pLeft, i); + p = sqlite3ExprVectorField(pLeft, i); pColl = sqlite3ExprCollSeq(pParse, p); sqlite3VdbeAddOp3(v, OP_Column, iIdx, i, r2); @@ -2656,7 +2656,7 @@ static void sqlite3ExprCodeIN( ** result is 1. */ sqlite3VdbeJumpHere(v, addr); for(i=0; ipLeft, i); + Expr *p = sqlite3ExprVectorField(pExpr->pLeft, i); if( sqlite3ExprCanBeNull(p) ){ sqlite3VdbeAddOp2(v, OP_IsNull, r1+aiMap[i], destIfNull); } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 56da61a2aa..a9061b2833 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -4006,10 +4006,12 @@ int sqlite3ExprCheckIN(Parse*, Expr*); #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 void sqlite3AnalyzeFunctions(void); -int sqlite3Stat4ProbeSetValue(Parse*,Index*,UnpackedRecord**,Expr*,u8,int,int*); +int sqlite3Stat4ProbeSetValue( + Parse*,Index*,UnpackedRecord**,Expr*,int,int,int*); int sqlite3Stat4ValueFromExpr(Parse*, Expr*, u8, sqlite3_value**); void sqlite3Stat4ProbeFree(UnpackedRecord*); int sqlite3Stat4Column(sqlite3*, const void*, int, int, sqlite3_value**); +char sqlite3IndexColumnAffinity(sqlite3*, Index*, int); #endif /* @@ -4269,5 +4271,6 @@ int sqlite3DbstatRegister(sqlite3*); int sqlite3ExprVectorSize(Expr *pExpr); int sqlite3ExprIsVector(Expr *pExpr); +Expr *sqlite3ExprVectorField(Expr*, int); #endif /* SQLITEINT_H */ diff --git a/src/vdbemem.c b/src/vdbemem.c index 04cb9c5c63..0709527634 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -1520,9 +1520,9 @@ static int stat4ValueFromExpr( ** structures intended to be compared against sample index keys stored ** in the sqlite_stat4 table. ** -** A single call to this function attempts to populates field iVal (leftmost -** is 0 etc.) of the unpacked record with a value extracted from expression -** pExpr. Extraction of values is possible if: +** A single call to this function populates zero or more fields of the +** record starting with field iVal (fields are numbered from left to +** right starting with 0). A single field is populated if: ** ** * (pExpr==0). In this case the value is assumed to be an SQL NULL, ** @@ -1531,10 +1531,14 @@ static int stat4ValueFromExpr( ** * The sqlite3ValueFromExpr() function is able to extract a value ** from the expression (i.e. the expression is a literal value). ** -** If a value can be extracted, the affinity passed as the 5th argument -** is applied to it before it is copied into the UnpackedRecord. Output -** parameter *pbOk is set to true if a value is extracted, or false -** otherwise. +** Or, if pExpr is a TK_VECTOR, one field is populated for each of the +** vector components that match either of the two latter criteria listed +** above. +** +** Before any value is appended to the record, the affinity of the +** corresponding column within index pIdx is applied to it. Before +** this function returns, output parameter *pnExtract is set to the +** number of values appended to the record. ** ** When this function is called, *ppRec must either point to an object ** allocated by an earlier call to this function, or must be NULL. If it @@ -1550,22 +1554,33 @@ int sqlite3Stat4ProbeSetValue( Index *pIdx, /* Index being probed */ UnpackedRecord **ppRec, /* IN/OUT: Probe record */ Expr *pExpr, /* The expression to extract a value from */ - u8 affinity, /* Affinity to use */ + int nElem, /* Maximum number of values to append */ int iVal, /* Array element to populate */ - int *pbOk /* OUT: True if value was extracted */ + int *pnExtract /* OUT: Values appended to the record */ ){ - int rc; - sqlite3_value *pVal = 0; - struct ValueNewStat4Ctx alloc; + int rc = SQLITE_OK; + int nExtract = 0; - alloc.pParse = pParse; - alloc.pIdx = pIdx; - alloc.ppRec = ppRec; - alloc.iVal = iVal; + if( pExpr==0 || pExpr->op!=TK_SELECT ){ + int i; + struct ValueNewStat4Ctx alloc; - rc = stat4ValueFromExpr(pParse, pExpr, affinity, &alloc, &pVal); - assert( pVal==0 || pVal->db==pParse->db ); - *pbOk = (pVal!=0); + alloc.pParse = pParse; + alloc.pIdx = pIdx; + alloc.ppRec = ppRec; + + for(i=0; idb, pIdx, iVal+i); + alloc.iVal = iVal+i; + rc = stat4ValueFromExpr(pParse, pElem, aff, &alloc, &pVal); + if( !pVal ) break; + nExtract++; + } + } + + *pnExtract = nExtract; return rc; } diff --git a/src/where.c b/src/where.c index 3e8dea70a1..a37ab1bbfe 100644 --- a/src/where.c +++ b/src/where.c @@ -1207,7 +1207,7 @@ static LogEst whereRangeAdjust(WhereTerm *pTerm, LogEst nNew){ /* ** Return the affinity for a single column of an index. */ -static char sqlite3IndexColumnAffinity(sqlite3 *db, Index *pIdx, int iCol){ +char sqlite3IndexColumnAffinity(sqlite3 *db, Index *pIdx, int iCol){ assert( iCol>=0 && iColnColumn ); if( !pIdx->zColAff ){ if( sqlite3IndexAffinityStr(db, pIdx)==0 ) return SQLITE_AFF_BLOB; @@ -1384,7 +1384,8 @@ static int whereRangeScanEst( if( nEq==pBuilder->nRecValid ){ UnpackedRecord *pRec = pBuilder->pRec; tRowcnt a[2]; - u8 aff; + int nBtm = pLoop->u.btree.nBtm; + int nTop = pLoop->u.btree.nTop; /* Variable iLower will be set to the estimate of the number of rows in ** the index that are less than the lower bound of the range query. The @@ -1414,8 +1415,6 @@ static int whereRangeScanEst( testcase( pRec->nField!=pBuilder->nRecValid ); pRec->nField = pBuilder->nRecValid; } - aff = sqlite3IndexColumnAffinity(pParse->db, p, nEq); - assert( nEq!=p->nKeyCol || aff==SQLITE_AFF_INTEGER ); /* Determine iLower and iUpper using ($P) only. */ if( nEq==0 ){ iLower = 0; @@ -1434,17 +1433,20 @@ static int whereRangeScanEst( if( p->aSortOrder[nEq] ){ /* The roles of pLower and pUpper are swapped for a DESC index */ SWAP(WhereTerm*, pLower, pUpper); + SWAP(int, nBtm, nTop); } /* If possible, improve on the iLower estimate using ($P:$L). */ if( pLower ){ - int bOk; /* True if value is extracted from pExpr */ + int n; /* Values extracted from pExpr */ Expr *pExpr = pLower->pExpr->pRight; - rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq, &bOk); - if( rc==SQLITE_OK && bOk ){ + rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, nBtm, nEq, &n); + if( rc==SQLITE_OK && n ){ tRowcnt iNew; + u16 mask = WO_GT|WO_LE; + if( sqlite3ExprVectorSize(pExpr)>n ) mask = (WO_LE|WO_LT); iLwrIdx = whereKeyStats(pParse, p, pRec, 0, a); - iNew = a[0] + ((pLower->eOperator & (WO_GT|WO_LE)) ? a[1] : 0); + iNew = a[0] + ((pLower->eOperator & mask) ? a[1] : 0); if( iNew>iLower ) iLower = iNew; nOut--; pLower = 0; @@ -1453,13 +1455,15 @@ static int whereRangeScanEst( /* If possible, improve on the iUpper estimate using ($P:$U). */ if( pUpper ){ - int bOk; /* True if value is extracted from pExpr */ + int n; /* Values extracted from pExpr */ Expr *pExpr = pUpper->pExpr->pRight; - rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq, &bOk); - if( rc==SQLITE_OK && bOk ){ + rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, nTop, nEq, &n); + if( rc==SQLITE_OK && n ){ tRowcnt iNew; + u16 mask = WO_GT|WO_LE; + if( sqlite3ExprVectorSize(pExpr)>n ) mask = (WO_LE|WO_LT); iUprIdx = whereKeyStats(pParse, p, pRec, 1, a); - iNew = a[0] + ((pUpper->eOperator & (WO_GT|WO_LE)) ? a[1] : 0); + iNew = a[0] + ((pUpper->eOperator & mask) ? a[1] : 0); if( iNewpNew->u.btree.pIndex; int nEq = pBuilder->pNew->u.btree.nEq; UnpackedRecord *pRec = pBuilder->pRec; - u8 aff; /* Column affinity */ int rc; /* Subfunction return code */ tRowcnt a[2]; /* Statistics */ int bOk; @@ -1573,8 +1576,7 @@ static int whereEqualScanEst( return SQLITE_OK; } - aff = sqlite3IndexColumnAffinity(pParse->db, p, nEq-1); - rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq-1, &bOk); + rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, 1, nEq-1, &bOk); pBuilder->pRec = pRec; if( rc!=SQLITE_OK ) return rc; if( bOk==0 ) return SQLITE_NOTFOUND; diff --git a/test/rowvalue4.test b/test/rowvalue4.test index c0e0933ebd..b02ee169f7 100644 --- a/test/rowvalue4.test +++ b/test/rowvalue4.test @@ -143,6 +143,70 @@ foreach {nm idx} { } } +ifcapable stat4 { + do_execsql_test 3.0 { + CREATE TABLE c1(a, b, c, d); + INSERT INTO c1(a, b) VALUES(1, 'a'); + INSERT INTO c1(a, b) VALUES(1, 'b'); + INSERT INTO c1(a, b) VALUES(1, 'c'); + INSERT INTO c1(a, b) VALUES(1, 'd'); + INSERT INTO c1(a, b) VALUES(1, 'e'); + INSERT INTO c1(a, b) VALUES(1, 'f'); + INSERT INTO c1(a, b) VALUES(1, 'g'); + INSERT INTO c1(a, b) VALUES(1, 'h'); + INSERT INTO c1(a, b) VALUES(1, 'i'); + INSERT INTO c1(a, b) VALUES(1, 'j'); + INSERT INTO c1(a, b) VALUES(1, 'k'); + INSERT INTO c1(a, b) VALUES(1, 'l'); + INSERT INTO c1(a, b) VALUES(1, 'm'); + INSERT INTO c1(a, b) VALUES(1, 'n'); + INSERT INTO c1(a, b) VALUES(1, 'o'); + INSERT INTO c1(a, b) VALUES(1, 'p'); + INSERT INTO c1(a, b) VALUES(2, 'a'); + INSERT INTO c1(a, b) VALUES(2, 'b'); + INSERT INTO c1(a, b) VALUES(2, 'c'); + INSERT INTO c1(a, b) VALUES(2, 'd'); + INSERT INTO c1(a, b) VALUES(2, 'e'); + INSERT INTO c1(a, b) VALUES(2, 'f'); + INSERT INTO c1(a, b) VALUES(2, 'g'); + INSERT INTO c1(a, b) VALUES(2, 'h'); + + INSERT INTO c1(c, d) SELECT a, b FROM c1; + + CREATE INDEX c1ab ON c1(a, b); + CREATE INDEX c1cd ON c1(c, d); + ANALYZE; + } + + do_eqp_test 3.1.1 { SELECT * FROM c1 WHERE a=1 AND c=2 } { + 0 0 0 {SEARCH TABLE c1 USING INDEX c1cd (c=?)} + } + do_eqp_test 3.1.2 { SELECT * FROM c1 WHERE a=1 AND b>'d' AND c=2 } { + 0 0 0 {SEARCH TABLE c1 USING INDEX c1cd (c=?)} + } + do_eqp_test 3.1.3 { SELECT * FROM c1 WHERE a=1 AND b>'l' AND c=2 } { + 0 0 0 {SEARCH TABLE c1 USING INDEX c1ab (a=? AND b>?)} + } + + do_eqp_test 3.2.1 { SELECT * FROM c1 WHERE a=1 AND c>1 } { + 0 0 0 {SEARCH TABLE c1 USING INDEX c1cd (c>?)} + } + do_eqp_test 3.2.2 { SELECT * FROM c1 WHERE a=1 AND c>0 } { + 0 0 0 {SEARCH TABLE c1 USING INDEX c1ab (a=?)} + } + do_eqp_test 3.2.3 { SELECT * FROM c1 WHERE a=1 AND c>=1 } { + 0 0 0 {SEARCH TABLE c1 USING INDEX c1ab (a=?)} + } + do_eqp_test 3.2.4 { SELECT * FROM c1 WHERE a=1 AND (c, d)>(1, 'c') } { + 0 0 0 {SEARCH TABLE c1 USING INDEX c1ab (a=?)} + } + do_eqp_test 3.2.5 { SELECT * FROM c1 WHERE a=1 AND (c, d)>(1, 'o') } { + 0 0 0 {SEARCH TABLE c1 USING INDEX c1cd (c>?)} + } + do_eqp_test 3.2.6 { SELECT * FROM c1 WHERE a=1 AND (c, +b)>(1, 'c') } { + 0 0 0 {SEARCH TABLE c1 USING INDEX c1ab (a=?)} + } +} finish_test From 2c628ea9d9c015ad9fd70510ee228c8e43e3aa9c Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 3 Aug 2016 16:39:04 +0000 Subject: [PATCH 0663/1484] Fix another problem involving vector range constraints and mixed ASC/DESC indexes. FossilOrigin-Name: 1559f4c43473e107f7196eea3ee91c53ede22999 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/where.c | 2 +- test/rowvalue4.test | 4 ++++ 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 6c59839b10..bd4c8f2896 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sstat4-based\scost\sestimates\sfor\svector\srange\sconstraints. -D 2016-08-03T16:14:33.444 +C Fix\sanother\sproblem\sinvolving\svector\srange\sconstraints\sand\smixed\sASC/DESC\sindexes. +D 2016-08-03T16:39:04.109 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 3340e479e5221f06c3d61726f8f7efff885e4233 @@ -463,7 +463,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 02eeecc265f6ffd0597378f5d8ae9070b62a406a F src/wal.h 6dd221ed384afdc204bc61e25c23ef7fd5a511f2 F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354 -F src/where.c 21095414c4bf8d5fdf05f3be790bf8b65e370f94 +F src/where.c 8bd54861755e2ca54bc36b0dbc655834f363c5ec F src/whereInt.h 14dd243e13b81cbb0a66063d38b70f93a7d6e613 F src/wherecode.c c2392fa30bcb0c555a8ae402d646b357ca428ad6 F src/whereexpr.c 4a8cefc7c122132ac9f3ed125c61629a0e3de094 @@ -1021,7 +1021,7 @@ F test/rowid.test 5b7509f384f4f6fae1af3c8c104c8ca299fea18d F test/rowvalue.test 56b34d31d91340a6e922e753b798880170cc1aa7 F test/rowvalue2.test 8d5dfe75b8f4d1868a2f91f0356f20d36cba64ff F test/rowvalue3.test dbe935260851b197dfbbbcb0ac2a15cb5f324fd4 -F test/rowvalue4.test 86a04529ab1da3879d6ef56defe15446e4575b3d +F test/rowvalue4.test b902e053544469e06148f504962abf9afb28be65 F test/rowvaluefault.test 7b16485e3f2b371f3e3d05455b8ded6d0c090244 F test/rtree.test 0c8d9dd458d6824e59683c19ab2ffa9ef946f798 F test/run-wordcount.sh 891e89c4c2d16e629cd45951d4ed899ad12afc09 @@ -1514,7 +1514,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e496b2d63984311e6ae117677e6c2417ae24b6bc -R 2ab02159e20122e5dc19c46ffdea23b5 +P 18af74abc8ceae47ab9fbee3e3e5bb37db8fcba5 +R 411ee4bf09cf9ee92d07e741a8c6b68c U dan -Z 1b607e01edb5341321c1446f2f3437dc +Z eb44e2dff5400ed92495955ac9fc17ab diff --git a/manifest.uuid b/manifest.uuid index 61422f33d0..97e702c730 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -18af74abc8ceae47ab9fbee3e3e5bb37db8fcba5 \ No newline at end of file +1559f4c43473e107f7196eea3ee91c53ede22999 \ No newline at end of file diff --git a/src/where.c b/src/where.c index a37ab1bbfe..a80054b1c7 100644 --- a/src/where.c +++ b/src/where.c @@ -2234,7 +2234,7 @@ int whereRangeVectorLen( if( pLhs->op!=TK_COLUMN || pLhs->iTable!=iCur || pLhs->iColumn!=pIdx->aiColumn[i+nEq] - || pIdx->aSortOrder[i]!=pIdx->aSortOrder[0] + || pIdx->aSortOrder[i+nEq]!=pIdx->aSortOrder[nEq] ){ break; } diff --git a/test/rowvalue4.test b/test/rowvalue4.test index b02ee169f7..d615aa8e2e 100644 --- a/test/rowvalue4.test +++ b/test/rowvalue4.test @@ -95,6 +95,7 @@ foreach {nm idx} { idx7 { CREATE INDEX t2abc ON t2(a DESC, b DESC) } idx8 { CREATE INDEX t2abc ON t2(c, b, a); } idx9 { CREATE INDEX t2d ON t2(d); } + idx10 { CREATE INDEX t2abc ON t2(a DESC, b, c DESC); } } { drop_all_indexes execsql $idx @@ -113,6 +114,9 @@ foreach {nm idx} { {1 2 3 4 5 6 7 8 9 10 11 12 13} 10 "(a, b, c) = (SELECT a, b, c FROM t2 WHERE d=14)" 14 + + 11 "a = 2 AND (b, c) > (2, 2)" {15 16 17 18} + 12 "a = 2 AND (b, c) < (3, 3) AND (b, c) > (1, 1)" {11 12 13 14 15 16 17} } { set result [db eval "SELECT d FROM t2 WHERE $where"] do_test 2.1.$nm.$tn { lsort -integer $result } $res From 3d1fb1dd758781bd6bcffbdb0f3738a7e1c0d2cf Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 3 Aug 2016 18:00:49 +0000 Subject: [PATCH 0664/1484] Fix a problem with estimating the number of rows visited by a query that uses a multi-column IN(SELECT...) constraint. FossilOrigin-Name: 3c2f908f5b7312570cfa74afcf4252a857cb5237 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/where.c | 15 ++++++++++++--- test/rowvalue4.test | 28 ++++++++++++++++++++++++++++ 4 files changed, 48 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index bd4c8f2896..bcec45f458 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sanother\sproblem\sinvolving\svector\srange\sconstraints\sand\smixed\sASC/DESC\sindexes. -D 2016-08-03T16:39:04.109 +C Fix\sa\sproblem\swith\sestimating\sthe\snumber\sof\srows\svisited\sby\sa\squery\sthat\suses\sa\smulti-column\sIN(SELECT...)\sconstraint. +D 2016-08-03T18:00:49.612 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 3340e479e5221f06c3d61726f8f7efff885e4233 @@ -463,7 +463,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 02eeecc265f6ffd0597378f5d8ae9070b62a406a F src/wal.h 6dd221ed384afdc204bc61e25c23ef7fd5a511f2 F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354 -F src/where.c 8bd54861755e2ca54bc36b0dbc655834f363c5ec +F src/where.c 0a0b8af3920f88467d93019acdf570c4f4192f26 F src/whereInt.h 14dd243e13b81cbb0a66063d38b70f93a7d6e613 F src/wherecode.c c2392fa30bcb0c555a8ae402d646b357ca428ad6 F src/whereexpr.c 4a8cefc7c122132ac9f3ed125c61629a0e3de094 @@ -1021,7 +1021,7 @@ F test/rowid.test 5b7509f384f4f6fae1af3c8c104c8ca299fea18d F test/rowvalue.test 56b34d31d91340a6e922e753b798880170cc1aa7 F test/rowvalue2.test 8d5dfe75b8f4d1868a2f91f0356f20d36cba64ff F test/rowvalue3.test dbe935260851b197dfbbbcb0ac2a15cb5f324fd4 -F test/rowvalue4.test b902e053544469e06148f504962abf9afb28be65 +F test/rowvalue4.test 1f0fa2d6e4485c2c35cdb997ba57f572fd9919e0 F test/rowvaluefault.test 7b16485e3f2b371f3e3d05455b8ded6d0c090244 F test/rtree.test 0c8d9dd458d6824e59683c19ab2ffa9ef946f798 F test/run-wordcount.sh 891e89c4c2d16e629cd45951d4ed899ad12afc09 @@ -1514,7 +1514,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 18af74abc8ceae47ab9fbee3e3e5bb37db8fcba5 -R 411ee4bf09cf9ee92d07e741a8c6b68c +P 1559f4c43473e107f7196eea3ee91c53ede22999 +R f540153e91f079ff5413a490814ad157 U dan -Z eb44e2dff5400ed92495955ac9fc17ab +Z 1ca41c3e8d4f391ec12438826156b785 diff --git a/manifest.uuid b/manifest.uuid index 97e702c730..d136916990 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1559f4c43473e107f7196eea3ee91c53ede22999 \ No newline at end of file +3c2f908f5b7312570cfa74afcf4252a857cb5237 \ No newline at end of file diff --git a/src/where.c b/src/where.c index a80054b1c7..877ca72ad1 100644 --- a/src/where.c +++ b/src/where.c @@ -2376,14 +2376,23 @@ static int whereLoopAddBtreeIndex( pNew->wsFlags |= WHERE_COLUMN_IN; if( ExprHasProperty(pExpr, EP_xIsSelect) ){ /* "x IN (SELECT ...)": TUNING: the SELECT returns 25 rows */ + int i; nIn = 46; assert( 46==sqlite3LogEst(25) ); + + /* The expression may actually be of the form (x, y) IN (SELECT...). + ** In this case there is a separate term for each of (x) and (y). + ** However, the nIn multiplier should only be applied once, not once + ** for each such term. The following loop checks that pTerm is the + ** first such term in use, and sets nIn back to 0 if it is not. */ + for(i=0; inLTerm-1; i++){ + if( pNew->aLTerm[i]->pExpr==pExpr ) nIn = 0; + } }else if( ALWAYS(pExpr->x.pList && pExpr->x.pList->nExpr) ){ /* "x IN (value, value, ...)" */ nIn = sqlite3LogEst(pExpr->x.pList->nExpr); + assert( nIn>0 ); /* RHS always has 2 or more terms... The parser + ** changes "x IN (?)" into "x=?". */ } - assert( nIn>0 ); /* RHS always has 2 or more terms... The parser - ** changes "x IN (?)" into "x=?". */ - }else if( eOp & (WO_EQ|WO_IS) ){ int iCol = pProbe->aiColumn[saved_nEq]; pNew->wsFlags |= WHERE_COLUMN_EQ; diff --git a/test/rowvalue4.test b/test/rowvalue4.test index d615aa8e2e..a187063081 100644 --- a/test/rowvalue4.test +++ b/test/rowvalue4.test @@ -212,5 +212,33 @@ ifcapable stat4 { } } +#------------------------------------------------------------------------ + +do_execsql_test 5.0 { + CREATE TABLE d1(x, y); + CREATE TABLE d2(a, b, c); + CREATE INDEX d2ab ON d2(a, b); + CREATE INDEX d2c ON d2(c); + + WITH i(i) AS ( + VALUES(1) UNION ALL SELECT i+1 FROM i WHERE i<1000 + ) + INSERT INTO d2 SELECT i/3, i%3, i/3 FROM i; + ANALYZE; +} + +do_eqp_test 5.1 { + SELECT * FROM d2 WHERE + (a, b) IN (SELECT x, y FROM d1) AND + (c) IN (SELECT y FROM d1) +} { + 0 0 0 {SEARCH TABLE d2 USING INDEX d2ab (a=? AND b=?)} + 0 0 0 {EXECUTE LIST SUBQUERY 1} + 1 0 0 {SCAN TABLE d1} + 0 0 0 {EXECUTE LIST SUBQUERY 2} + 2 0 0 {SCAN TABLE d1} +} + + finish_test From dd545d3bf219c13f839cfb21d0bc122c3b431d2b Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 4 Aug 2016 09:09:44 +0000 Subject: [PATCH 0665/1484] Make sure the ORDER BY LIMIT optimization is not applied if the inner-most loop can only have a single iteration and is hence not really a loop. FossilOrigin-Name: 13e3bd3de6b434b6182ef36be108d7ee0be8ca53 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/where.c | 2 +- test/limit2.test | 22 ++++++++++++++++++++++ 4 files changed, 31 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 558a3d8e2d..3ea36916cc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\stypo\sin\sa\scomment\sin\sbtree.c.\s\s\sNo\schanges\sto\scode. -D 2016-08-03T14:51:16.394 +C Make\ssure\sthe\sORDER\sBY\sLIMIT\soptimization\sis\snot\sapplied\sif\sthe\sinner-most\nloop\scan\sonly\shave\sa\ssingle\siteration\sand\sis\shence\snot\sreally\sa\sloop. +D 2016-08-04T09:09:44.760 F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 3340e479e5221f06c3d61726f8f7efff885e4233 @@ -463,7 +463,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 02eeecc265f6ffd0597378f5d8ae9070b62a406a F src/wal.h 6dd221ed384afdc204bc61e25c23ef7fd5a511f2 F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354 -F src/where.c bb1444f6ae6bc3cbd086cc61cd9c6e3a6168d89b +F src/where.c 5c9df42d50888be8274a5a0eb062eb0629869bd3 F src/whereInt.h e5b939701a7ceffc5a3a8188a37f9746416ebcd0 F src/wherecode.c 99707d11907c71d289ee9553d2d1a22f1fd8ba41 F src/whereexpr.c d7dcbf14ce1b5876c1f76496162c30fcba669563 @@ -888,7 +888,7 @@ F test/like.test 81632c437a947bf1f7130b19537da6a1a844806a F test/like2.test 3b2ee13149ba4a8a60b59756f4e5d345573852da F test/like3.test 3608a2042b6f922f900fbfd5d3ce4e7eca57f7c4 F test/limit.test 0c99a27a87b14c646a9d583c7c89fd06c352663e -F test/limit2.test 55c9f4d08c89311e00afd75045ee1a2aca205cb4 +F test/limit2.test 40e79f3d95f2077742aa5b7676f58c9af1735d83 F test/loadext.test d077450695ddb5c1ea3ad7d48e5f5850fe732ad9 F test/loadext2.test 0408380b57adca04004247179837a18e866a74f7 F test/lock.test be4fe08118fb988fed741f429b7dd5d65e1c90db @@ -1509,7 +1509,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b91444b5db8465f09d112455e722c888b3f94329 -R aa712e9e7089879865bbb38d4c2c515d +P 722c12816347ee9fce7a090cfebef2c5841e7445 +R fd11dfb179ebaeb65493cf49055d4419 U drh -Z 2b4f8b48b03032bd1efbc47f9457218f +Z c8d986adc7b509414bb3aed9ed932c87 diff --git a/manifest.uuid b/manifest.uuid index a6f1d523fa..832eed621e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -722c12816347ee9fce7a090cfebef2c5841e7445 \ No newline at end of file +13e3bd3de6b434b6182ef36be108d7ee0be8ca53 \ No newline at end of file diff --git a/src/where.c b/src/where.c index 9b3c281efc..c2706dc5dd 100644 --- a/src/where.c +++ b/src/where.c @@ -3971,7 +3971,7 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ pWInfo->revMask = pFrom->revLoop; if( pWInfo->nOBSat<=0 ){ pWInfo->nOBSat = 0; - if( nLoop>0 ){ + if( nLoop>0 && (pFrom->aLoop[nLoop-1]->wsFlags & WHERE_ONEROW)==0 ){ Bitmask m = 0; int rc = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pOrderBy, pFrom, WHERE_ORDERBY_LIMIT, nLoop-1, pFrom->aLoop[nLoop-1], &m); diff --git a/test/limit2.test b/test/limit2.test index f415f3263b..fb4c89644f 100644 --- a/test/limit2.test +++ b/test/limit2.test @@ -77,6 +77,28 @@ do_test limit2-120.3 { expr {$fast_count < 0.02*$slow_count} } {1} +# Bug report against the new ORDER BY LIMIT optimization just prior to +# release. (Unreleased so there is no ticket). +# +# Make sure the optimization is not applied if the inner loop can only +# provide a single row of output. +# +do_execsql_test limit2-200 { + CREATE TABLE t200(a, b); + WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<1000) + INSERT INTO t200(a,b) SELECT x, x FROM c; + CREATE TABLE t201(x INTEGER PRIMARY KEY, y); + INSERT INTO t201(x,y) VALUES(2,12345); + + SELECT *, '|' FROM t200, t201 WHERE x=b ORDER BY y LIMIT 3; +} {2 2 2 12345 |} +do_execsql_test limit2-210 { + SELECT *, '|' FROM t200 LEFT JOIN t201 ON x=b ORDER BY y LIMIT 3; +} {1 1 {} {} | 3 3 {} {} | 4 4 {} {} |} + + + + finish_test From cc15313cc9a8b6713dc9f995ccc4d4c088da55d7 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 4 Aug 2016 12:35:17 +0000 Subject: [PATCH 0666/1484] Add the experimental SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION compile-time option. When enabled, the "unknown function" error is suppressed for EXPLAIN and a no-op function named "unknown()" is substituted. This facilitiates using the command-line shell to analyze queries from applications that contain many application-defined functions that are not normally available to the shell. FossilOrigin-Name: b7f30a9ff20d580fdaecdcf2b644d09ad6c2575e --- Makefile.in | 2 ++ Makefile.msc | 5 ++++- main.mk | 2 ++ manifest | 23 ++++++++++++----------- manifest.uuid | 2 +- src/expr.c | 5 +++++ src/func.c | 29 ++++++++++++++++++++++++++--- src/resolve.c | 6 +++++- 8 files changed, 57 insertions(+), 17 deletions(-) diff --git a/Makefile.in b/Makefile.in index fd0ad6b6a7..9b2fe86cf4 100644 --- a/Makefile.in +++ b/Makefile.in @@ -558,7 +558,9 @@ TESTOPTS = --verbose=file --output=test-out.txt # Extra compiler options for various shell tools # SHELL_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS4 +# SHELL_OPT += -DSQLITE_ENABLE_FTS5 SHELL_OPT += -DSQLITE_ENABLE_EXPLAIN_COMMENTS +SHELL_OPT += -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1 FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 diff --git a/Makefile.msc b/Makefile.msc index 527efd8f7d..5f7643978c 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -1424,7 +1424,10 @@ FUZZDATA = \ # 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 +# SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_FTS5 +SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_EXPLAIN_COMMENTS +SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION !ENDIF # <> diff --git a/main.mk b/main.mk index e3da609750..451837ffff 100644 --- a/main.mk +++ b/main.mk @@ -470,6 +470,8 @@ TESTOPTS = --verbose=file --output=test-out.txt # Extra compiler options for various shell tools # SHELL_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS5 +SHELL_OPT += -DSQLITE_ENABLE_EXPLAIN_COMMENTS +SHELL_OPT += -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1 FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 diff --git a/manifest b/manifest index 3ea36916cc..c4a95c5def 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -C Make\ssure\sthe\sORDER\sBY\sLIMIT\soptimization\sis\snot\sapplied\sif\sthe\sinner-most\nloop\scan\sonly\shave\sa\ssingle\siteration\sand\sis\shence\snot\sreally\sa\sloop. -D 2016-08-04T09:09:44.760 -F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db +C Add\sthe\sexperimental\sSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION\scompile-time\soption.\nWhen\senabled,\sthe\s"unknown\sfunction"\serror\sis\ssuppressed\sfor\sEXPLAIN\sand\na\sno-op\sfunction\snamed\s"unknown()"\sis\ssubstituted.\s\sThis\sfacilitiates\susing\nthe\scommand-line\sshell\sto\sanalyze\squeries\sfrom\sapplications\sthat\scontain\nmany\sapplication-defined\sfunctions\sthat\sare\snot\snormally\savailable\sto\sthe\nshell. +D 2016-08-04T12:35:17.002 +F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 -F Makefile.msc 3340e479e5221f06c3d61726f8f7efff885e4233 +F Makefile.msc 817e65faf9ad66a8d462e5b5e645be600213efb8 F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7 F VERSION cb29eb11e493dd85b3eeec4053c03949bf98478e F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 @@ -308,7 +308,7 @@ F ext/userauth/userauth.c 5fa3bdb492f481bbc1709fc83c91ebd13460c69e F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60 -F main.mk e9d66f1b1c4874221d12d940be3ce5f397c10741 +F main.mk 1883ecab643b136e8ab3fdc33785e6ea8b5ceb46 F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 @@ -337,10 +337,10 @@ F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7 F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b F src/dbstat.c 4f6f7f52b49beb9636ffbd517cfe44a402ba4ad0 F src/delete.c 4aba4214a377ce8ddde2d2e609777bcc8235200f -F src/expr.c fbc17c717a80b5b61158ea8f25b5af6f8cad66f8 +F src/expr.c 9c5eca8602f6c496e8d4eefefe2aae3d831dd510 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c bc4145347595b7770f9a598cff1c848302cf5413 -F src/func.c 61a4114cf7004f10c542cfabbab9f2bcb9033045 +F src/func.c 29cc9acb170ec1387b9f63eb52cd85f8de96c771 F src/global.c c45ea22aff29334f6a9ec549235ac3357c970015 F src/hash.c 55b5fb474100cee0b901edaf203e26c970940f36 F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4 @@ -381,7 +381,7 @@ F src/pragma.h 64c78a648751b9f4f297276c4eb7507b14b4628c F src/prepare.c 22df6171aec1d86904ed2ad30c2348a5748aa04e F src/printf.c a5f0ca08ddede803c241266abb46356ec748ded1 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 -F src/resolve.c cca3aa77b95706df5d635a2141a4d1de60ae6598 +F src/resolve.c 0392c6686586b1d4dac9a4106959f03ddd70e9aa F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c f3c6e9065fb34f6a23af27ec7f1f717ffbfc2ee4 F src/shell.c 79dda477be6c96eba6e952a934957ad36f87acc7 @@ -1509,7 +1509,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 722c12816347ee9fce7a090cfebef2c5841e7445 -R fd11dfb179ebaeb65493cf49055d4419 +P 13e3bd3de6b434b6182ef36be108d7ee0be8ca53 +Q +4ada023ca075628fdafc3bc4520239b9789cff29 +R f1859801c403afb60ddad5424514cd57 U drh -Z c8d986adc7b509414bb3aed9ed932c87 +Z 688b79edff11cfb7031a01d005983417 diff --git a/manifest.uuid b/manifest.uuid index 832eed621e..ee38509af6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -13e3bd3de6b434b6182ef36be108d7ee0be8ca53 \ No newline at end of file +b7f30a9ff20d580fdaecdcf2b644d09ad6c2575e \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index c6d74cfd32..74f09bbee9 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2943,6 +2943,11 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ assert( !ExprHasProperty(pExpr, EP_IntValue) ); zId = pExpr->u.zToken; pDef = sqlite3FindFunction(db, zId, nFarg, enc, 0); +#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION + if( pDef==0 && pParse->explain ){ + pDef = sqlite3FindFunction(db, "unknown", nFarg, enc, 0); + } +#endif if( pDef==0 || pDef->xFinalize!=0 ){ sqlite3ErrorMsg(pParse, "unknown function: %s()", zId); break; diff --git a/src/func.c b/src/func.c index 78c8806456..79bb1e3dd2 100644 --- a/src/func.c +++ b/src/func.c @@ -1316,6 +1316,26 @@ static void trimFunc( } +#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION +/* +** The "unknown" function is automatically substituted in place of +** any unrecognized function name when doing an EXPLAIN or EXPLAIN QUERY PLAN +** when the SQLITE_ENABLE_UNKNOWN_FUNCTION compile-time option is used. +** When the "sqlite3" command-line shell is built using this functionality, +** that allows an EXPLAIN or EXPLAIN QUERY PLAN for complex queries +** involving application-defined functions to be examined in a generic +** sqlite3 shell. +*/ +static void unknownFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + /* no-op */ +} +#endif /*SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION*/ + + /* IMP: R-25361-16150 This function is omitted from SQLite by default. It ** is only available if the SQLITE_SOUNDEX compile-time option is used ** when SQLite is built. @@ -1786,13 +1806,16 @@ void sqlite3RegisterBuiltinFunctions(void){ AGGREGATE(group_concat, 2, 0, 0, groupConcatStep, groupConcatFinalize), LIKEFUNC(glob, 2, &globInfo, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE), - #ifdef SQLITE_CASE_SENSITIVE_LIKE +#ifdef SQLITE_CASE_SENSITIVE_LIKE LIKEFUNC(like, 2, &likeInfoAlt, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE), LIKEFUNC(like, 3, &likeInfoAlt, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE), - #else +#else LIKEFUNC(like, 2, &likeInfoNorm, SQLITE_FUNC_LIKE), LIKEFUNC(like, 3, &likeInfoNorm, SQLITE_FUNC_LIKE), - #endif +#endif +#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION + FUNCTION(unknown, -1, 0, 0, unknownFunc ), +#endif FUNCTION(coalesce, 1, 0, 0, 0 ), FUNCTION(coalesce, 0, 0, 0, 0 ), FUNCTION2(coalesce, -1, 0, 0, noopFunc, SQLITE_FUNC_COALESCE), diff --git a/src/resolve.c b/src/resolve.c index 77ce37f6d7..8ae7f0919c 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -718,7 +718,11 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ sqlite3ErrorMsg(pParse, "misuse of aggregate function %.*s()", nId,zId); pNC->nErr++; is_agg = 0; - }else if( no_such_func && pParse->db->init.busy==0 ){ + }else if( no_such_func && pParse->db->init.busy==0 +#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION + && pParse->explain==0 +#endif + ){ sqlite3ErrorMsg(pParse, "no such function: %.*s", nId, zId); pNC->nErr++; }else if( wrong_num_args ){ From 70ae0e93ec253557ac9a7379b61c917ddb4786aa Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 4 Aug 2016 13:23:28 +0000 Subject: [PATCH 0667/1484] Revert the SQLITE_APICALL changes for now. That changes needs further research before it is released. Deferred until 3.15. FossilOrigin-Name: 9adda385267d1a0ecff259b42a284913668441a2 --- Makefile.msc | 80 ++++++++------------------------------------- manifest | 17 +++++----- manifest.uuid | 2 +- tool/mksqlite3c.tcl | 3 +- tool/mksqlite3h.tcl | 7 +--- 5 files changed, 25 insertions(+), 84 deletions(-) diff --git a/Makefile.msc b/Makefile.msc index 5f7643978c..cd866ce4a4 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -24,13 +24,6 @@ USE_AMALGAMATION = 1 USE_FULLWARN = 0 !ENDIF -# Set this non-0 to enable full runtime error checks (-RTC1, etc). This -# has no effect if (any) optimizations are enabled. -# -!IFNDEF USE_RUNTIME_CHECKS -USE_RUNTIME_CHECKS = 0 -!ENDIF - # Set this non-0 to use "stdcall" calling convention for the core library # and shell executable. # @@ -471,32 +464,20 @@ RCC = $(RC) -DSQLITE_OS_WIN=1 -I. -I$(TOP) -I$(TOP)\src $(RCOPTS) $(RCCOPTS) # !IF $(USE_STDCALL)!=0 || $(FOR_WIN10)!=0 !IF "$(PLATFORM)"=="x86" -CORE_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall -SHELL_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall -# <> -TEST_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall -DINCLUDE_SQLITE_TCL_H=1 -DSQLITE_TCLAPI=__cdecl -# <> +CORE_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_STDCALL=__stdcall +SHELL_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_STDCALL=__stdcall !ELSE !IFNDEF PLATFORM -CORE_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall -SHELL_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall -# <> -TEST_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall -DINCLUDE_SQLITE_TCL_H=1 -DSQLITE_TCLAPI=__cdecl -# <> +CORE_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_STDCALL=__stdcall +SHELL_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_STDCALL=__stdcall !ELSE CORE_CCONV_OPTS = SHELL_CCONV_OPTS = -# <> -TEST_CCONV_OPTS = -# <> !ENDIF !ENDIF !ELSE CORE_CCONV_OPTS = SHELL_CCONV_OPTS = -# <> -TEST_CCONV_OPTS = -# <> !ENDIF # These are additional compiler options used for the core library. @@ -854,10 +835,6 @@ RCC = $(RCC) -D_DEBUG !IF $(DEBUG)>1 || $(OPTIMIZATIONS)==0 TCC = $(TCC) -Od BCC = $(BCC) -Od -!IF $(USE_RUNTIME_CHECKS)!=0 -TCC = $(TCC) -RTC1 -BCC = $(BCC) -RTC1 -!ENDIF !ELSEIF $(OPTIMIZATIONS)>=3 TCC = $(TCC) -Ox BCC = $(BCC) -Ox @@ -1258,12 +1235,6 @@ SRC11 = \ parse.h \ $(SQLITE3H) -# Generated Tcl header files -# -SRC12 = \ - sqlite_tcl.h \ - sqlite_tclDecls.h - # All source code files. # SRC = $(SRC00) $(SRC01) $(SRC02) $(SRC03) $(SRC04) $(SRC05) $(SRC06) $(SRC07) $(SRC08) $(SRC09) $(SRC10) $(SRC11) @@ -1370,7 +1341,7 @@ HDR = \ parse.h \ $(TOP)\src\pragma.h \ $(SQLITE3H) \ - sqlite3ext.h \ + $(TOP)\src\sqlite3ext.h \ $(TOP)\src\sqliteInt.h \ $(TOP)\src\sqliteLimit.h \ $(TOP)\src\vdbe.h \ @@ -1424,10 +1395,7 @@ FUZZDATA = \ # 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 -# SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_FTS5 -SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_EXPLAIN_COMMENTS -SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION +SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_SHELL_JSON1 -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS !ENDIF # <> @@ -1531,7 +1499,7 @@ mptest: mptester.exe # files are automatically generated. This target takes care of # all that automatic generation. # -.target_source: $(SRC) $(TOP)\tool\vdbe-compress.tcl fts5.c sqlite_tcl.h +.target_source: $(SRC) $(TOP)\tool\vdbe-compress.tcl fts5.c -rmdir /Q/S tsrc 2>NUL -mkdir tsrc for %i in ($(SRC00)) do copy /Y %i tsrc @@ -1546,7 +1514,6 @@ mptest: mptester.exe for %i in ($(SRC09)) do copy /Y %i tsrc for %i in ($(SRC10)) do copy /Y %i tsrc for %i in ($(SRC11)) do copy /Y %i tsrc - for %i in ($(SRC12)) do copy /Y %i tsrc copy /Y fts5.c tsrc copy /Y fts5.h tsrc del /Q tsrc\sqlite.h.in tsrc\parse.y 2>NUL @@ -1828,10 +1795,10 @@ wherecode.lo: $(TOP)\src\wherecode.c $(HDR) whereexpr.lo: $(TOP)\src\whereexpr.c $(HDR) $(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\whereexpr.c -tclsqlite.lo: $(TOP)\src\tclsqlite.c $(HDR) sqlite_tcl.h +tclsqlite.lo: $(TOP)\src\tclsqlite.c $(HDR) $(LTCOMPILE) $(NO_WARN) -DUSE_TCL_STUBS=1 -DBUILD_sqlite -I$(TCLINCDIR) -c $(TOP)\src\tclsqlite.c -tclsqlite-shell.lo: $(TOP)\src\tclsqlite.c $(HDR) sqlite_tcl.h +tclsqlite-shell.lo: $(TOP)\src\tclsqlite.c $(HDR) $(LTCOMPILE) $(NO_WARN) -DTCLSH=1 -DBUILD_sqlite -I$(TCLINCDIR) -c $(TOP)\src\tclsqlite.c tclsqlite3.exe: tclsqlite-shell.lo $(SQLITE3C) $(SQLITE3H) $(LIBRESOBJS) @@ -1860,9 +1827,7 @@ $(SQLITE3H): $(TOP)\src\sqlite.h.in $(TOP)\manifest.uuid $(TOP)\VERSION $(TCLSH_CMD) $(TOP)\tool\mksqlite3h.tcl $(TOP:\=/) > $(SQLITE3H) sqlite3ext.h: .target_source - type tsrc\sqlite3ext.h | $(TCLSH_CMD) $(TOP)\tool\replace.tcl regsub "\(\*\)" "(SQLITE_CALLBACK *)" \ - | $(TCLSH_CMD) $(TOP)\tool\replace.tcl regsub "\(\*" "(SQLITE_APICALL *" > sqlite3ext.h - copy /Y sqlite3ext.h tsrc\sqlite3ext.h + copy tsrc\sqlite3ext.h . mkkeywordhash.exe: $(TOP)\tool\mkkeywordhash.c $(BCC) $(NO_WARN) -Fe$@ $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS) $(EXT_FEATURE_FLAGS) $(OPTS) \ @@ -1995,7 +1960,6 @@ TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_SERVER=1 -DSQLITE_PRIVATE="" TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_CORE $(NO_WARN) TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_SERIES_CONSTRAINT_VERIFY=1 TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_DEFAULT_PAGE_SIZE=1024 -TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) $(TEST_CCONV_OPTS) TESTFIXTURE_SRC0 = $(TESTEXT) $(TESTSRC2) TESTFIXTURE_SRC1 = $(TESTEXT) $(SQLITE3C) @@ -2005,25 +1969,7 @@ TESTFIXTURE_SRC = $(TESTSRC) $(TOP)\src\tclsqlite.c $(TESTFIXTURE_SRC0) TESTFIXTURE_SRC = $(TESTSRC) $(TOP)\src\tclsqlite.c $(TESTFIXTURE_SRC1) !ENDIF -sqlite_tclDecls.h: - echo #ifndef SQLITE_TCLAPI > sqlite_tclDecls.h - echo # define SQLITE_TCLAPI >> sqlite_tclDecls.h - echo #endif >> sqlite_tclDecls.h - type "$(TCLINCDIR)\tclDecls.h" \ - | $(TCLSH_CMD) $(TOP)\tool\replace.tcl regsub "^(EXTERN(?: CONST\d+?)?\s+?[^\(]*?\s+?)Tcl_" "\1 SQLITE_TCLAPI Tcl_" \ - | $(TCLSH_CMD) $(TOP)\tool\replace.tcl regsub "^(EXTERN\s+?(?:void|VOID)\s+?)TclFreeObj" "\1 SQLITE_TCLAPI TclFreeObj" \ - | $(TCLSH_CMD) $(TOP)\tool\replace.tcl regsub "\(\*tcl_" "(SQLITE_TCLAPI *tcl_" \ - | $(TCLSH_CMD) $(TOP)\tool\replace.tcl regsub "\(\*tclFreeObj" "(SQLITE_TCLAPI *tclFreeObj" \ - | $(TCLSH_CMD) $(TOP)\tool\replace.tcl regsub "\(\*" "(SQLITE_TCLAPI *" >> sqlite_tclDecls.h - -sqlite_tcl.h: sqlite_tclDecls.h - type "$(TCLINCDIR)\tcl.h" | $(TCLSH_CMD) $(TOP)\tool\replace.tcl exact tclDecls.h sqlite_tclDecls.h \ - | $(TCLSH_CMD) $(TOP)\tool\replace.tcl regsub "typedef (.*?)\(Tcl_" "typedef \1 (SQLITE_TCLAPI Tcl_" \ - | $(TCLSH_CMD) $(TOP)\tool\replace.tcl exact "void (*freeProc)" "void (SQLITE_TCLAPI *freeProc)" \ - | $(TCLSH_CMD) $(TOP)\tool\replace.tcl exact "Tcl_HashEntry *(*findProc)" "Tcl_HashEntry *(SQLITE_TCLAPI *findProc)" \ - | $(TCLSH_CMD) $(TOP)\tool\replace.tcl exact "Tcl_HashEntry *(*createProc)" "Tcl_HashEntry *(SQLITE_TCLAPI *createProc)" >> sqlite_tcl.h - -testfixture.exe: $(TESTFIXTURE_SRC) $(SQLITE3H) $(LIBRESOBJS) $(HDR) sqlite_tcl.h +testfixture.exe: $(TESTFIXTURE_SRC) $(SQLITE3H) $(LIBRESOBJS) $(HDR) $(LTLINK) -DSQLITE_NO_SYNC=1 $(TESTFIXTURE_FLAGS) \ -DBUILD_sqlite -I$(TCLINCDIR) \ $(TESTFIXTURE_SRC) \ @@ -2072,7 +2018,7 @@ smoketest: $(TESTPROGS) @set PATH=$(LIBTCLPATH);$(PATH) .\testfixture.exe $(TOP)\test\main.test $(TESTOPTS) -sqlite3_analyzer.c: $(SQLITE3C) $(SQLITE3H) $(TOP)\src\tclsqlite.c $(TOP)\tool\spaceanal.tcl sqlite_tcl.h +sqlite3_analyzer.c: $(SQLITE3C) $(SQLITE3H) $(TOP)\src\tclsqlite.c $(TOP)\tool\spaceanal.tcl echo #define TCLSH 2 > $@ echo #define SQLITE_ENABLE_DBSTAT_VTAB 1 >> $@ copy $@ + $(SQLITE3C) + $(TOP)\src\tclsqlite.c $@ @@ -2152,7 +2098,7 @@ clean: -rmdir /Q/S .libs 2>NUL -rmdir /Q/S tsrc 2>NUL del /Q .target_source 2>NUL - del /Q tclsqlite3.exe sqlite_tcl.h sqlite_tclDecls.h 2>NUL + del /Q tclsqlite3.exe 2>NUL del /Q testloadext.dll 2>NUL del /Q testfixture.exe test.db 2>NUL del /Q LogEst.exe fts3view.exe rollback-test.exe showdb.exe 2>NUL diff --git a/manifest b/manifest index c4a95c5def..5b9bd0d8e5 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -C Add\sthe\sexperimental\sSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION\scompile-time\soption.\nWhen\senabled,\sthe\s"unknown\sfunction"\serror\sis\ssuppressed\sfor\sEXPLAIN\sand\na\sno-op\sfunction\snamed\s"unknown()"\sis\ssubstituted.\s\sThis\sfacilitiates\susing\nthe\scommand-line\sshell\sto\sanalyze\squeries\sfrom\sapplications\sthat\scontain\nmany\sapplication-defined\sfunctions\sthat\sare\snot\snormally\savailable\sto\sthe\nshell. -D 2016-08-04T12:35:17.002 +C Revert\sthe\sSQLITE_APICALL\schanges\sfor\snow.\s\sThat\schanges\sneeds\sfurther\nresearch\sbefore\sit\sis\sreleased.\s\sDeferred\suntil\s3.15. +D 2016-08-04T13:23:28.286 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 -F Makefile.msc 817e65faf9ad66a8d462e5b5e645be600213efb8 +F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7 F VERSION cb29eb11e493dd85b3eeec4053c03949bf98478e F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 @@ -1450,8 +1450,8 @@ F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e F tool/mkpragmatab.tcl f0d5bb266d1d388cf86fce5ba01a891e95d72d41 F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 F tool/mksqlite3c-noext.tcl aa58ea3be311c81821c2cd3209f55e46b07ab656 -F tool/mksqlite3c.tcl 655181fb25f69b3524b30efd0750c43513415216 -F tool/mksqlite3h.tcl cf5cd68028e69a51ed5c76042672664201f0f756 +F tool/mksqlite3c.tcl 63af8429841f08552e6da1d93b3dee4a93ff8071 +F tool/mksqlite3h.tcl e7b106fc4f29fbc258e8ba9b88d9108332ea2ade F tool/mksqlite3internalh.tcl eb994013e833359137eb53a55acdad0b5ae1049b F tool/mkvsix.tcl 4abcaf3267171b2faadaf9b82a0dfbaa6e98f8b7 F tool/offsets.c fe4262fdfa378e8f5499a42136d17bf3b98f6091 @@ -1509,8 +1509,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 13e3bd3de6b434b6182ef36be108d7ee0be8ca53 -Q +4ada023ca075628fdafc3bc4520239b9789cff29 -R f1859801c403afb60ddad5424514cd57 +P b7f30a9ff20d580fdaecdcf2b644d09ad6c2575e +R 54afa4c645a3de150c21fe8a3504aa0b U drh -Z 688b79edff11cfb7031a01d005983417 +Z 5a54570e253d8550ab3d18086a0dcdce diff --git a/manifest.uuid b/manifest.uuid index ee38509af6..3bacaad736 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b7f30a9ff20d580fdaecdcf2b644d09ad6c2575e \ No newline at end of file +9adda385267d1a0ecff259b42a284913668441a2 \ No newline at end of file diff --git a/tool/mksqlite3c.tcl b/tool/mksqlite3c.tcl index c5f765ed1c..7e8558d2ab 100644 --- a/tool/mksqlite3c.tcl +++ b/tool/mksqlite3c.tcl @@ -112,6 +112,7 @@ foreach hdr { pragma.h rtree.h sqlite3session.h + sqlite3ext.h sqlite3.h sqlite3ext.h sqlite3rbu.h @@ -231,7 +232,7 @@ proc copy_file {filename} { if {[lsearch -exact $cdecllist $funcname] >= 0} { append line SQLITE_CDECL } else { - append line SQLITE_APICALL + append line SQLITE_STDCALL } append line " " $funcname $rest puts $out $line diff --git a/tool/mksqlite3h.tcl b/tool/mksqlite3h.tcl index 9a4e7d2985..1af6d75730 100644 --- a/tool/mksqlite3h.tcl +++ b/tool/mksqlite3h.tcl @@ -21,8 +21,6 @@ # formatted as an integer (e.g. "3006017"). # 5) Replaces the string --SOURCE-ID-- with the date and time and sha1 # hash of the fossil-scm manifest for the source tree. -# 6) Adds the SQLITE_CALLBACK calling convention macro in front of all -# callback declarations. # # This script outputs to stdout. # @@ -122,14 +120,11 @@ foreach file $filelist { if {[lsearch -exact $cdecllist $funcname] >= 0} { append line SQLITE_CDECL } else { - append line SQLITE_APICALL + append line SQLITE_STDCALL } append line " " $funcname $rest } } - set line [string map [list (*sqlite3_syscall_ptr) \ - "(SQLITE_SYSAPI *sqlite3_syscall_ptr)"] $line] - regsub {\(\*} $line {(SQLITE_CALLBACK *} line puts $line } close $in From 0aafa9c89c543b6f9bb5c81346bd196d062e05a8 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 5 Aug 2016 14:35:47 +0000 Subject: [PATCH 0668/1484] Fix a very obscure problem following OOM in sqlite3_declare_vtab(). FossilOrigin-Name: 68eac74874d0646369bef3650c6cb271cca62ab4 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/build.c | 7 +++++++ 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 5b9bd0d8e5..ad19c3dbd6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Revert\sthe\sSQLITE_APICALL\schanges\sfor\snow.\s\sThat\schanges\sneeds\sfurther\nresearch\sbefore\sit\sis\sreleased.\s\sDeferred\suntil\s3.15. -D 2016-08-04T13:23:28.286 +C Fix\sa\svery\sobscure\sproblem\sfollowing\sOOM\sin\ssqlite3_declare_vtab(). +D 2016-08-05T14:35:47.568 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -330,7 +330,7 @@ F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 F src/btree.c 2551bd3ecb8b8988fb8b23aabadfb214dbc38e46 F src/btree.h 075c45707c0f8f8af118f739f36df8098a08b7da F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 -F src/build.c d1fdfd7ab8f5447e494ef15825973bf0719527c6 +F src/build.c 7c3c780b703c09314032c8f6e4e7c1d80241a818 F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7 @@ -1509,7 +1509,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b7f30a9ff20d580fdaecdcf2b644d09ad6c2575e -R 54afa4c645a3de150c21fe8a3504aa0b +P 9adda385267d1a0ecff259b42a284913668441a2 +R 36d01c6d4e5d55fe676a3ca2e553d6b8 U drh -Z 5a54570e253d8550ab3d18086a0dcdce +Z 0d50083da402e96d80dd6dfcbaebaad9 diff --git a/manifest.uuid b/manifest.uuid index 3bacaad736..6bcb510d7d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9adda385267d1a0ecff259b42a284913668441a2 \ No newline at end of file +68eac74874d0646369bef3650c6cb271cca62ab4 \ No newline at end of file diff --git a/src/build.c b/src/build.c index 52f6f200f8..b14e6f2fc2 100644 --- a/src/build.c +++ b/src/build.c @@ -3037,6 +3037,13 @@ void sqlite3CreateIndex( if( zName==0 ){ goto exit_create_index; } + + /* Automatic index names generated from within sqlite3_declare_vtab() + ** must have names that are distinct from normal automatic index names. + ** The following statement converts "sqlite3_autoindex..." into + ** "sqlite3_butoindex..." in order to make the names distinct. + ** The "vtab_err.test" test demonstrates the need of this statement. */ + if( IN_DECLARE_VTAB ) zName[7]++; } /* Check for authorization to create an index. From 5360b55c6cc2298b72174871adfe3caabf20bf98 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 5 Aug 2016 15:34:42 +0000 Subject: [PATCH 0669/1484] Remove an incorrect ALWAYS() statement and add a test case to show when the condition is sometimes false. FossilOrigin-Name: 0f57effa3642e66a863f32cc7fba86d167084af3 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/vtab.c | 2 +- test/stat.test | 13 +++++++++++++ 4 files changed, 22 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index ad19c3dbd6..ec9b78cea8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\svery\sobscure\sproblem\sfollowing\sOOM\sin\ssqlite3_declare_vtab(). -D 2016-08-05T14:35:47.568 +C Remove\san\sincorrect\sALWAYS()\sstatement\sand\sadd\sa\stest\scase\sto\sshow\swhen\nthe\scondition\sis\ssometimes\sfalse. +D 2016-08-05T15:34:42.171 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -458,7 +458,7 @@ F src/vdbeblob.c 83d2d266383157b02e2b809350bb197e89d7895b F src/vdbemem.c 1ecaa5ee0caff07255f25d04e8dc88befb6f88d1 F src/vdbesort.c 91fda3909326860382b0ca8aa251e609c6a9d62c F src/vdbetrace.c 41963d5376f0349842b5fc4aaaaacd7d9cdc0834 -F src/vtab.c 6fece06fdd50eb2b0673e37e627ce6710e4af5be +F src/vtab.c 6b3cfaff7e4397739d6b48511e777ca58c6d06d4 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 02eeecc265f6ffd0597378f5d8ae9070b62a406a F src/wal.h 6dd221ed384afdc204bc61e25c23ef7fd5a511f2 @@ -1104,7 +1104,7 @@ F test/spellfix3.test 0f9efaaa502a0e0a09848028518a6fb096c8ad33 F test/sqldiff1.test 28cd737cf1b0078b1ec1bbf425e674c47785835e F test/sqllimits1.test a74ee2a3740b9f9c2437c246d8fb77354862a142 F test/sqllog.test 6af6cb0b09f4e44e1917e06ce85be7670302517a -F test/stat.test ab95d28503d0f6d98ffd8ce204643c9da090ebf1 +F test/stat.test f8f1279ffffabe6df825723af18cc6e0ae70a893 F test/statfault.test f525a7bf633e50afd027700e9a486090684b1ac1 F test/stmt.test 64844332db69cf1a735fcb3e11548557fc95392f F test/subquery.test d7268d193dd33d5505df965399d3a594e76ae13f @@ -1509,7 +1509,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 9adda385267d1a0ecff259b42a284913668441a2 -R 36d01c6d4e5d55fe676a3ca2e553d6b8 +P 68eac74874d0646369bef3650c6cb271cca62ab4 +R 8d5524e3947549ded2372df1ac699079 U drh -Z 0d50083da402e96d80dd6dfcbaebaad9 +Z 5feee06a3e8967a54a24fbeb2c1f3aea diff --git a/manifest.uuid b/manifest.uuid index 6bcb510d7d..64c0aece9a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -68eac74874d0646369bef3650c6cb271cca62ab4 \ No newline at end of file +0f57effa3642e66a863f32cc7fba86d167084af3 \ No newline at end of file diff --git a/src/vtab.c b/src/vtab.c index f37eb261aa..45c5e79abd 100644 --- a/src/vtab.c +++ b/src/vtab.c @@ -807,7 +807,7 @@ int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab){ Table *pTab; pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zName); - if( ALWAYS(pTab!=0 && pTab->pVTable!=0) ){ + if( pTab!=0 && ALWAYS(pTab->pVTable!=0) ){ VTable *p; int (*xDestroy)(sqlite3_vtab *); for(p=pTab->pVTable; p; p=p->pNext){ diff --git a/test/stat.test b/test/stat.test index 6a87a629b9..66ca5e2f2b 100644 --- a/test/stat.test +++ b/test/stat.test @@ -34,12 +34,25 @@ register_dbstat_vtab db do_execsql_test stat-0.0 { PRAGMA table_info(dbstat); } {/0 name TEXT .* 1 path TEXT .* 9 pgsize INTEGER/} + +# Attempts to drop an eponymous virtual table are a no-op. do_execsql_test stat-0.1 { + DROP TABLE dbstat; + PRAGMA table_info=dbstat; +} {/0 name TEXT .* 1 path TEXT .* 9 pgsize INTEGER/} + +db close +forcedelete test.db +sqlite3 db test.db +db func a_string a_string +register_dbstat_vtab db +do_execsql_test stat-0.2 { PRAGMA auto_vacuum = OFF; CREATE VIRTUAL TABLE temp.stat USING dbstat; SELECT * FROM stat; } {} + if {[wal_is_capable]} { do_execsql_test stat-0.1 { PRAGMA journal_mode = WAL; From 43c1ce390f25a6d988fb40ef95c2ef1afb1b7182 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 5 Aug 2016 16:16:26 +0000 Subject: [PATCH 0670/1484] Undo commit [f250166bb]. It is required to handle IO and other errors that occur within a VACUUM of a Zipvfs database. FossilOrigin-Name: ae72513af37cd806a6d94aaa7c47a740e119d3b1 --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/backup.c | 6 ++++-- src/pager.c | 12 +++++++++++- src/pager.h | 1 + 5 files changed, 26 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index ec9b78cea8..eab6773070 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\san\sincorrect\sALWAYS()\sstatement\sand\sadd\sa\stest\scase\sto\sshow\swhen\nthe\scondition\sis\ssometimes\sfalse. -D 2016-08-05T15:34:42.171 +C Undo\scommit\s[f250166bb].\sIt\sis\srequired\sto\shandle\sIO\sand\sother\serrors\sthat\soccur\swithin\sa\sVACUUM\sof\sa\sZipvfs\sdatabase. +D 2016-08-05T16:16:26.624 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -324,7 +324,7 @@ F src/alter.c cc28ab933ae615b22add0d609794ffb6596b42ea F src/analyze.c 37fedc80ac966ce1745811746e68e4d8fa64c7fe F src/attach.c 771153bd1f4ab0b97a44a13dde2c7e5e1efeba22 F src/auth.c 5c8e0f37f785f935f589496801edd19840485853 -F src/backup.c 6df65fdd569c901a418887a1a76f82ec35044556 +F src/backup.c 17cd25a36d49330df2bacd2cadf2a61f3b525976 F src/bitvec.c 3ee4c8b2c94ed3a7377256e18199e6ff5cf33f63 F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 F src/btree.c 2551bd3ecb8b8988fb8b23aabadfb214dbc38e46 @@ -370,8 +370,8 @@ F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586 F src/os_unix.c a9443cdab41d7f3cdf0df3a5aab62fd6e1c9b234 F src/os_win.c 520f23475f1de530c435d30b67b7b15fe90874b0 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a -F src/pager.c c368634b888b1c8740aea83b36bfd266f2443e60 -F src/pager.h 031a87445e5e0afc85312d1c380e123ad6c7aeaf +F src/pager.c 40928c450320da78bb4bd3ae82818f4239e19b7e +F src/pager.h 966d2769e76ae347c8a32c4165faf6e6cb64546d F src/parse.y 99b676e6fc2f4e331ab93e76b3987cffdbd28efa F src/pcache.c 5583c8ade4b05075a60ba953ef471d1c1a9c05df F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 @@ -1509,7 +1509,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 68eac74874d0646369bef3650c6cb271cca62ab4 -R 8d5524e3947549ded2372df1ac699079 -U drh -Z 5feee06a3e8967a54a24fbeb2c1f3aea +P 0f57effa3642e66a863f32cc7fba86d167084af3 +R 7173910e7a14fcd3861af608a7447a5a +U dan +Z 5568e465afb61eecd4219a0cc50c6e2e diff --git a/manifest.uuid b/manifest.uuid index 64c0aece9a..4b900d08a6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0f57effa3642e66a863f32cc7fba86d167084af3 \ No newline at end of file +ae72513af37cd806a6d94aaa7c47a740e119d3b1 \ No newline at end of file diff --git a/src/backup.c b/src/backup.c index 3df56e5384..19c3b2a647 100644 --- a/src/backup.c +++ b/src/backup.c @@ -777,13 +777,15 @@ int sqlite3BtreeCopyFile(Btree *pTo, Btree *pFrom){ ** sqlite3_backup_step(), we can guarantee that the copy finishes ** within a single call (unless an error occurs). The assert() statement ** checks this assumption - (p->rc) should be set to either SQLITE_DONE - ** or an error code. - */ + ** or an error code. */ sqlite3_backup_step(&b, 0x7FFFFFFF); assert( b.rc!=SQLITE_OK ); + rc = sqlite3_backup_finish(&b); if( rc==SQLITE_OK ){ pTo->pBt->btsFlags &= ~BTS_PAGESIZE_FIXED; + }else{ + sqlite3PagerClearCache(sqlite3BtreePager(b.pDest)); } assert( sqlite3BtreeIsInTrans(pTo)==0 ); diff --git a/src/pager.c b/src/pager.c index 1ae831d148..cd8d1204b3 100644 --- a/src/pager.c +++ b/src/pager.c @@ -7157,6 +7157,17 @@ sqlite3_backup **sqlite3PagerBackupPtr(Pager *pPager){ return &pPager->pBackup; } +#ifndef SQLITE_OMIT_VACUUM +/* +** Unless this is an in-memory or temporary database, clear the pager cache. +*/ +void sqlite3PagerClearCache(Pager *pPager){ + assert( MEMDB==0 || pPager->tempFile ); + if( pPager->tempFile==0 ) pager_reset(pPager); +} +#endif + + #ifndef SQLITE_OMIT_WAL /* ** This function is called when the user invokes "PRAGMA wal_checkpoint", @@ -7382,5 +7393,4 @@ int sqlite3PagerWalFramesize(Pager *pPager){ } #endif - #endif /* SQLITE_OMIT_DISKIO */ diff --git a/src/pager.h b/src/pager.h index af71d745a8..1046670912 100644 --- a/src/pager.h +++ b/src/pager.h @@ -203,6 +203,7 @@ const char *sqlite3PagerJournalname(Pager*); void *sqlite3PagerTempSpace(Pager*); int sqlite3PagerIsMemdb(Pager*); void sqlite3PagerCacheStat(Pager *, int, int, int *); +void sqlite3PagerClearCache(Pager*); int sqlite3SectorSize(sqlite3_file *); /* Functions used to truncate the database file. */ From e099b67c204286eb7ff45e07169001786dc35971 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 5 Aug 2016 20:54:45 +0000 Subject: [PATCH 0671/1484] Have the TEA package build without SQLITE_OMIT_DEPRECATED. As it uses recently deprecated interfaces sqlite3_profile() and sqlite3_trace(). FossilOrigin-Name: 95578898835b933901603bd4d5e063f1219a016f --- autoconf/tea/configure.ac | 1 - manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/autoconf/tea/configure.ac b/autoconf/tea/configure.ac index 8df0af6195..7fca05b2e7 100644 --- a/autoconf/tea/configure.ac +++ b/autoconf/tea/configure.ac @@ -78,7 +78,6 @@ TEA_ADD_LIBS([]) TEA_ADD_CFLAGS([-DSQLITE_ENABLE_FTS3=1]) TEA_ADD_CFLAGS([-DSQLITE_3_SUFFIX_ONLY=1]) TEA_ADD_CFLAGS([-DSQLITE_ENABLE_RTREE=1]) -TEA_ADD_CFLAGS([-DSQLITE_OMIT_DEPRECATED=1]) TEA_ADD_STUB_SOURCES([]) TEA_ADD_TCL_SOURCES([]) diff --git a/manifest b/manifest index eab6773070..8f590c5751 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Undo\scommit\s[f250166bb].\sIt\sis\srequired\sto\shandle\sIO\sand\sother\serrors\sthat\soccur\swithin\sa\sVACUUM\sof\sa\sZipvfs\sdatabase. -D 2016-08-05T16:16:26.624 +C Have\sthe\sTEA\spackage\sbuild\swithout\sSQLITE_OMIT_DEPRECATED.\sAs\sit\suses\srecently\sdeprecated\sinterfaces\ssqlite3_profile()\sand\ssqlite3_trace(). +D 2016-08-05T20:54:45.205 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -18,7 +18,7 @@ F autoconf/configure.ac cacf2616abf6e4a569bde2ef365c143caeec40bc F autoconf/tea/Makefile.in b438a7020446c8a8156e8d97c8914a04833da6fd F autoconf/tea/README 3e9a3c060f29a44344ab50aec506f4db903fb873 F autoconf/tea/aclocal.m4 52c47aac44ce0ddb1f918b6993e8beb8eee88f43 -F autoconf/tea/configure.ac 93d43c79e936fb16556e22498177d7e8571efa04 +F autoconf/tea/configure.ac 8aa16e3f0a5ca7959d4af198f46934ec187d395f F autoconf/tea/doc/sqlite3.n e1fe45d4f5286ee3d0ccc877aca2a0def488e9bb F autoconf/tea/license.terms 13bd403c9610fd2b76ece0ab50c4c5eda933d523 F autoconf/tea/pkgIndex.tcl.in 3ef61715cf1c7bdcff56947ffadb26bc991ca39d @@ -1509,7 +1509,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 0f57effa3642e66a863f32cc7fba86d167084af3 -R 7173910e7a14fcd3861af608a7447a5a +P ae72513af37cd806a6d94aaa7c47a740e119d3b1 +R 40e4a12455b009781006c09c1ead4d48 U dan -Z 5568e465afb61eecd4219a0cc50c6e2e +Z 73dc717651276499651d605bdf75c66a diff --git a/manifest.uuid b/manifest.uuid index 4b900d08a6..a4b041f403 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ae72513af37cd806a6d94aaa7c47a740e119d3b1 \ No newline at end of file +95578898835b933901603bd4d5e063f1219a016f \ No newline at end of file From 6da466e4f46d820f2751ccbd4d7a685107fcf2b1 Mon Sep 17 00:00:00 2001 From: drh Date: Sun, 7 Aug 2016 18:52:11 +0000 Subject: [PATCH 0672/1484] Fix documentation typos. No changes to code. FossilOrigin-Name: ebc396a19fa79bea208ecda277ffff5d02166d0b --- ext/fts5/fts5.h | 3 +-- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/sqlite.h.in | 6 +++--- 4 files changed, 13 insertions(+), 14 deletions(-) diff --git a/ext/fts5/fts5.h b/ext/fts5/fts5.h index b32e2132dd..a45c145d38 100644 --- a/ext/fts5/fts5.h +++ b/ext/fts5/fts5.h @@ -318,7 +318,7 @@ struct Fts5ExtensionApi { ** behaviour. The structure methods are expected to function as follows: ** ** xCreate: -** This function is used to allocate and inititalize a tokenizer instance. +** This function is used to allocate and initialize a tokenizer instance. ** A tokenizer instance is required to actually tokenize text. ** ** The first argument passed to this function is a copy of the (void*) @@ -577,4 +577,3 @@ struct fts5_api { #endif #endif /* _FTS5_H */ - diff --git a/manifest b/manifest index 8f590c5751..dd20d64d7b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Have\sthe\sTEA\spackage\sbuild\swithout\sSQLITE_OMIT_DEPRECATED.\sAs\sit\suses\srecently\sdeprecated\sinterfaces\ssqlite3_profile()\sand\ssqlite3_trace(). -D 2016-08-05T20:54:45.205 +C Fix\sdocumentation\stypos.\s\sNo\schanges\sto\scode. +D 2016-08-07T18:52:11.690 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -97,7 +97,7 @@ F ext/fts3/unicode/UnicodeData.txt cd07314edb62d49fde34debdaf92fa2aa69011e7 F ext/fts3/unicode/mkunicode.tcl 2debed3f582d77b3fdd0b8830880250021571fd8 F ext/fts3/unicode/parseunicode.tcl da577d1384810fb4e2b209bf3313074353193e95 F ext/fts5/extract_api_docs.tcl a36e54ec777172ddd3f9a88daf593b00848368e0 -F ext/fts5/fts5.h b770c5e0a8d2ee071ddffc7ab722dbf3474a8abe +F ext/fts5/fts5.h 62f3e33ceeb9a428db139f9c012186b371da1cc7 F ext/fts5/fts5Int.h 9bd0c7c64285b5b368eca0ac63613185c5ad24ba F ext/fts5/fts5_aux.c daa57fb45216491814520bbb587e97bf81ced458 F ext/fts5/fts5_buffer.c 4c1502d4c956cd092c89ce4480867f9d8bf325cd @@ -385,7 +385,7 @@ F src/resolve.c 0392c6686586b1d4dac9a4106959f03ddd70e9aa F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c f3c6e9065fb34f6a23af27ec7f1f717ffbfc2ee4 F src/shell.c 79dda477be6c96eba6e952a934957ad36f87acc7 -F src/sqlite.h.in e011dcc3942e6ddc8dd7b894e9e6702e4269161e +F src/sqlite.h.in 0f7580280d1b009b507d8beec1ff0f197ba0cc99 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae F src/sqliteInt.h d6f221a5bd572df935140beda82f357c2185a77c @@ -1509,7 +1509,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ae72513af37cd806a6d94aaa7c47a740e119d3b1 -R 40e4a12455b009781006c09c1ead4d48 -U dan -Z 73dc717651276499651d605bdf75c66a +P 95578898835b933901603bd4d5e063f1219a016f +R e7962d3372d6a1e29e3980753a6f0162 +U drh +Z 69a694206e64a93c59f8e06cf497782d diff --git a/manifest.uuid b/manifest.uuid index a4b041f403..fc541c54b5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -95578898835b933901603bd4d5e063f1219a016f \ No newline at end of file +ebc396a19fa79bea208ecda277ffff5d02166d0b \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index f60ccaf55c..1ee39b6799 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -1959,7 +1959,7 @@ struct sqlite3_mem_methods { ** C-API [sqlite3_load_extension()] and the SQL function [load_extension()]. ** There should be two additional arguments. ** When the first argument to this interface is 1, then only the C-API is -** enabled and the SQL function remains disabled. If the first argment to +** enabled and the SQL function remains disabled. If the first argument to ** this interface is 0, then both the C-API and the SQL function are disabled. ** If the first argument is -1, then no changes are made to state of either the ** C-API or the SQL function. @@ -5537,7 +5537,7 @@ SQLITE_DEPRECATED void sqlite3_soft_heap_limit(int N); ** column exists. ^The sqlite3_table_column_metadata() interface returns ** SQLITE_ERROR and if the specified column does not exist. ** ^If the column-name parameter to sqlite3_table_column_metadata() is a -** NULL pointer, then this routine simply checks for the existance of the +** NULL pointer, then this routine simply checks for the existence of the ** table and returns SQLITE_OK if the table exists and SQLITE_ERROR if it ** does not. ** @@ -8132,7 +8132,7 @@ int sqlite3_db_cacheflush(sqlite3*); ** ^The second parameter to the preupdate callback is a pointer to ** the [database connection] that registered the preupdate hook. ** ^The third parameter to the preupdate callback is one of the constants -** [SQLITE_INSERT], [SQLITE_DELETE], or [SQLITE_UPDATE] to indentify the +** [SQLITE_INSERT], [SQLITE_DELETE], or [SQLITE_UPDATE] to identify the ** kind of update operation that is about to occur. ** ^(The fourth parameter to the preupdate callback is the name of the ** database within the database connection that is being modified. This From e22c375659d073c435a49635c05f1fcd86aeb815 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 8 Aug 2016 13:40:27 +0000 Subject: [PATCH 0673/1484] Version 3.14 FossilOrigin-Name: d5e98057028abcf7217d0d2b2e29bbbcdf09d6de --- manifest | 11 +++++++---- manifest.uuid | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/manifest b/manifest index dd20d64d7b..9d5c14e49e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sdocumentation\stypos.\s\sNo\schanges\sto\scode. -D 2016-08-07T18:52:11.690 +C Version\s3.14 +D 2016-08-08T13:40:27.974 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -1509,7 +1509,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 95578898835b933901603bd4d5e063f1219a016f +P ebc396a19fa79bea208ecda277ffff5d02166d0b R e7962d3372d6a1e29e3980753a6f0162 +T +bgcolor * #d0c0ff +T +sym-release * +T +sym-version-3.14.0 * U drh -Z 69a694206e64a93c59f8e06cf497782d +Z ecb9b7072c2b71d36f58909f83563ec2 diff --git a/manifest.uuid b/manifest.uuid index fc541c54b5..732a4af61b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ebc396a19fa79bea208ecda277ffff5d02166d0b \ No newline at end of file +d5e98057028abcf7217d0d2b2e29bbbcdf09d6de \ No newline at end of file From 1d9bc9b7a044eb8a2fccc8aaea108bc84a4e3c00 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 8 Aug 2016 18:42:08 +0000 Subject: [PATCH 0674/1484] Fix the EXPLAIN QUERY PLAN output for row value range constaints that use an index. FossilOrigin-Name: bb60651163553c5e46bf7b2805490570cea647b8 --- manifest | 14 ++++++------ manifest.uuid | 2 +- src/wherecode.c | 56 ++++++++++++++++++++++++++++++--------------- test/rowvalue4.test | 36 ++++++++++++++++++++++++++++- 4 files changed, 80 insertions(+), 28 deletions(-) diff --git a/manifest b/manifest index 3a589e9726..eaaf4038b5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\strunk\schanges\swith\sthis\sbranch. -D 2016-08-08T16:52:11.472 +C Fix\sthe\sEXPLAIN\sQUERY\sPLAN\soutput\sfor\srow\svalue\srange\sconstaints\sthat\suse\san\sindex. +D 2016-08-08T18:42:08.741 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -465,7 +465,7 @@ F src/wal.h 6dd221ed384afdc204bc61e25c23ef7fd5a511f2 F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354 F src/where.c f60310d9fa2dd275698f3a768d2c63917353f22d F src/whereInt.h 14dd243e13b81cbb0a66063d38b70f93a7d6e613 -F src/wherecode.c c2392fa30bcb0c555a8ae402d646b357ca428ad6 +F src/wherecode.c c24645572eba538c04c5ff8b8f6e9c0278107563 F src/whereexpr.c 4a8cefc7c122132ac9f3ed125c61629a0e3de094 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -1021,7 +1021,7 @@ F test/rowid.test 5b7509f384f4f6fae1af3c8c104c8ca299fea18d F test/rowvalue.test 56b34d31d91340a6e922e753b798880170cc1aa7 F test/rowvalue2.test 8d5dfe75b8f4d1868a2f91f0356f20d36cba64ff F test/rowvalue3.test dbe935260851b197dfbbbcb0ac2a15cb5f324fd4 -F test/rowvalue4.test 1f0fa2d6e4485c2c35cdb997ba57f572fd9919e0 +F test/rowvalue4.test 8d3b26c7ab26314b625cd2b113d782b011b91851 F test/rowvaluefault.test 7b16485e3f2b371f3e3d05455b8ded6d0c090244 F test/rtree.test 0c8d9dd458d6824e59683c19ab2ffa9ef946f798 F test/run-wordcount.sh 891e89c4c2d16e629cd45951d4ed899ad12afc09 @@ -1514,7 +1514,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 3c2f908f5b7312570cfa74afcf4252a857cb5237 d5e98057028abcf7217d0d2b2e29bbbcdf09d6de -R e29053a139f99493b32e4ec805317c91 +P 0e927a7e0250a65fd8e97b322cd69e93fadd13f0 +R c87cf26a8b83e76d6d485dba242f3437 U dan -Z c05c70937976285652f33ed04f5e8c75 +Z eb833a77a96d41ac0d9eabbd9e7d8788 diff --git a/manifest.uuid b/manifest.uuid index d3debee4c2..460e690f37 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0e927a7e0250a65fd8e97b322cd69e93fadd13f0 \ No newline at end of file +bb60651163553c5e46bf7b2805490570cea647b8 \ No newline at end of file diff --git a/src/wherecode.c b/src/wherecode.c index 9aafa83665..901fafecaa 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -21,6 +21,17 @@ #include "whereInt.h" #ifndef SQLITE_OMIT_EXPLAIN + +/* +** Return the name of the i-th column of the pIdx index. +*/ +static const char *explainIndexColumnName(Index *pIdx, int i){ + i = pIdx->aiColumn[i]; + if( i==XN_EXPR ) return ""; + if( i==XN_ROWID ) return "rowid"; + return pIdx->pTable->aCol[i].zName; +} + /* ** This routine is a helper for explainIndexRange() below ** @@ -31,24 +42,32 @@ */ static void explainAppendTerm( StrAccum *pStr, /* The text expression being built */ - int iTerm, /* Index of this term. First is zero */ - const char *zColumn, /* Name of the column */ + Index *pIdx, /* Index to read column names from */ + int nTerm, /* Number of terms */ + int iTerm, /* Zero-based index of first term. */ + int bAnd, /* Non-zero to append " AND " */ const char *zOp /* Name of the operator */ ){ - if( iTerm ) sqlite3StrAccumAppend(pStr, " AND ", 5); - sqlite3StrAccumAppendAll(pStr, zColumn); - sqlite3StrAccumAppend(pStr, zOp, 1); - sqlite3StrAccumAppend(pStr, "?", 1); -} + int i; -/* -** Return the name of the i-th column of the pIdx index. -*/ -static const char *explainIndexColumnName(Index *pIdx, int i){ - i = pIdx->aiColumn[i]; - if( i==XN_EXPR ) return ""; - if( i==XN_ROWID ) return "rowid"; - return pIdx->pTable->aCol[i].zName; + assert( nTerm>=1 ); + if( bAnd ) sqlite3StrAccumAppend(pStr, " AND ", 5); + + if( nTerm>1 ) sqlite3StrAccumAppend(pStr, "(", 1); + for(i=0; i1 ) sqlite3StrAccumAppend(pStr, ")", 1); + + sqlite3StrAccumAppend(pStr, zOp, 1); + + if( nTerm>1 ) sqlite3StrAccumAppend(pStr, "(", 1); + for(i=0; i1 ) sqlite3StrAccumAppend(pStr, ")", 1); } /* @@ -81,12 +100,11 @@ static void explainIndexRange(StrAccum *pStr, WhereLoop *pLoop){ j = i; if( pLoop->wsFlags&WHERE_BTM_LIMIT ){ - const char *z = explainIndexColumnName(pIndex, i); - explainAppendTerm(pStr, i++, z, ">"); + explainAppendTerm(pStr, pIndex, pLoop->u.btree.nBtm, j, i, ">"); + i = 1; } if( pLoop->wsFlags&WHERE_TOP_LIMIT ){ - const char *z = explainIndexColumnName(pIndex, j); - explainAppendTerm(pStr, i, z, "<"); + explainAppendTerm(pStr, pIndex, pLoop->u.btree.nTop, j, i, "<"); } sqlite3StrAccumAppend(pStr, ")", 1); } diff --git a/test/rowvalue4.test b/test/rowvalue4.test index a187063081..5530f8f5ca 100644 --- a/test/rowvalue4.test +++ b/test/rowvalue4.test @@ -205,7 +205,7 @@ ifcapable stat4 { 0 0 0 {SEARCH TABLE c1 USING INDEX c1ab (a=?)} } do_eqp_test 3.2.5 { SELECT * FROM c1 WHERE a=1 AND (c, d)>(1, 'o') } { - 0 0 0 {SEARCH TABLE c1 USING INDEX c1cd (c>?)} + 0 0 0 {SEARCH TABLE c1 USING INDEX c1cd ((c,d)>(?,?))} } do_eqp_test 3.2.6 { SELECT * FROM c1 WHERE a=1 AND (c, +b)>(1, 'c') } { 0 0 0 {SEARCH TABLE c1 USING INDEX c1ab (a=?)} @@ -239,6 +239,40 @@ do_eqp_test 5.1 { 2 0 0 {SCAN TABLE d1} } +do_execsql_test 6.0 { + CREATE TABLE e1(a, b, c, d, e); + CREATE INDEX e1ab ON e1(a, b); + CREATE INDEX e1cde ON e1(c, d, e); +} + +do_eqp_test 6.1 { + SELECT * FROM e1 WHERE (a, b) > (?, ?) +} { + 0 0 0 {SEARCH TABLE e1 USING INDEX e1ab ((a,b)>(?,?))} +} +do_eqp_test 6.2 { + SELECT * FROM e1 WHERE (a, b) < (?, ?) +} { + 0 0 0 {SEARCH TABLE e1 USING INDEX e1ab ((a,b)<(?,?))} +} +do_eqp_test 6.3 { + SELECT * FROM e1 WHERE c = ? AND (d, e) > (?, ?) +} { + 0 0 0 {SEARCH TABLE e1 USING INDEX e1cde (c=? AND (d,e)>(?,?))} +} +do_eqp_test 6.4 { + SELECT * FROM e1 WHERE c = ? AND (d, e) < (?, ?) +} { + 0 0 0 {SEARCH TABLE e1 USING INDEX e1cde (c=? AND (d,e)<(?,?))} +} + +do_eqp_test 6.5 { + SELECT * FROM e1 WHERE (d, e) BETWEEN (?, ?) AND (?, ?) AND c = ? +} { + 0 0 0 + {SEARCH TABLE e1 USING INDEX e1cde (c=? AND (d,e)>(?,?) AND (d,e)<(?,?))} +} + finish_test From 6256c1c2427a4f9867589a7f4204c0b2fe8028c9 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 8 Aug 2016 20:15:41 +0000 Subject: [PATCH 0675/1484] Fix some cases involving row values and virtual tables. FossilOrigin-Name: 156a41f30a0afd9a70e6c26470dcc468a11bd402 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/where.c | 34 +++++++++++++++++++++++++++------- src/wherecode.c | 7 ++++++- 4 files changed, 41 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index eaaf4038b5..b187cc2dd9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\sEXPLAIN\sQUERY\sPLAN\soutput\sfor\srow\svalue\srange\sconstaints\sthat\suse\san\sindex. -D 2016-08-08T18:42:08.741 +C Fix\ssome\scases\sinvolving\srow\svalues\sand\svirtual\stables. +D 2016-08-08T20:15:41.766 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -463,9 +463,9 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 02eeecc265f6ffd0597378f5d8ae9070b62a406a F src/wal.h 6dd221ed384afdc204bc61e25c23ef7fd5a511f2 F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354 -F src/where.c f60310d9fa2dd275698f3a768d2c63917353f22d +F src/where.c 457a2c8cd94a1dbe8d2e5113f6078f2e6b9067d5 F src/whereInt.h 14dd243e13b81cbb0a66063d38b70f93a7d6e613 -F src/wherecode.c c24645572eba538c04c5ff8b8f6e9c0278107563 +F src/wherecode.c 92202261a6e41f897a595417c5b0c75c8acf713d F src/whereexpr.c 4a8cefc7c122132ac9f3ed125c61629a0e3de094 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -1514,7 +1514,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 0e927a7e0250a65fd8e97b322cd69e93fadd13f0 -R c87cf26a8b83e76d6d485dba242f3437 +P bb60651163553c5e46bf7b2805490570cea647b8 +R 874f48b6764b2a2fd58ccae5d488cbf6 U dan -Z eb833a77a96d41ac0d9eabbd9e7d8788 +Z 25cd4c4731603d2ae10da74afc2be17b diff --git a/manifest.uuid b/manifest.uuid index 460e690f37..0e8e885da4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bb60651163553c5e46bf7b2805490570cea647b8 \ No newline at end of file +156a41f30a0afd9a70e6c26470dcc468a11bd402 \ No newline at end of file diff --git a/src/where.c b/src/where.c index 577a1147cb..9faec64bc1 100644 --- a/src/where.c +++ b/src/where.c @@ -826,7 +826,8 @@ static sqlite3_index_info *allocateIndexInfo( WhereClause *pWC, Bitmask mUnusable, /* Ignore terms with these prereqs */ struct SrcList_item *pSrc, - ExprList *pOrderBy + ExprList *pOrderBy, + u16 *pmNoOmit /* Mask of terms not to omit */ ){ int i, j; int nTerm; @@ -836,6 +837,7 @@ static sqlite3_index_info *allocateIndexInfo( WhereTerm *pTerm; int nOrderBy; sqlite3_index_info *pIdxInfo; + u16 mNoOmit = 0; /* Count the number of possible WHERE clause constraints referring ** to this virtual table */ @@ -924,6 +926,15 @@ static sqlite3_index_info *allocateIndexInfo( assert( WO_GE==SQLITE_INDEX_CONSTRAINT_GE ); assert( WO_MATCH==SQLITE_INDEX_CONSTRAINT_MATCH ); assert( pTerm->eOperator & (WO_IN|WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE|WO_MATCH) ); + + if( op & (WO_LT|WO_LE|WO_GT|WO_GE) + && sqlite3ExprIsVector(pTerm->pExpr->pRight) + ){ + if( i<16 ) mNoOmit |= (1 << i); + if( op==WO_LT ) pIdxCons[j].op = WO_LE; + if( op==WO_GT ) pIdxCons[j].op = WO_GE; + } + j++; } for(i=0; ia[i].sortOrder; } + *pmNoOmit = mNoOmit; return pIdxInfo; } @@ -2943,6 +2955,7 @@ static int whereLoopAddVirtualOne( Bitmask mUsable, /* Mask of usable tables */ u16 mExclude, /* Exclude terms using these operators */ sqlite3_index_info *pIdxInfo, /* Populated object for xBestIndex */ + u16 mNoOmit, /* Do not omit these constraints */ int *pbIn /* OUT: True if plan uses an IN(...) op */ ){ WhereClause *pWC = pBuilder->pWC; @@ -3031,6 +3044,7 @@ static int whereLoopAddVirtualOne( } } } + pNew->u.vtab.omitMask &= ~mNoOmit; pNew->nLTerm = mxTerm+1; assert( pNew->nLTerm<=pNew->nLSlot ); @@ -3104,6 +3118,7 @@ static int whereLoopAddVirtual( int bIn; /* True if plan uses IN(...) operator */ WhereLoop *pNew; Bitmask mBest; /* Tables used by best possible plan */ + u16 mNoOmit; assert( (mPrereq & mUnusable)==0 ); pWInfo = pBuilder->pWInfo; @@ -3112,7 +3127,8 @@ static int whereLoopAddVirtual( pNew = pBuilder->pNew; pSrc = &pWInfo->pTabList->a[pNew->iTab]; assert( IsVirtual(pSrc->pTab) ); - p = allocateIndexInfo(pParse, pWC, mUnusable, pSrc, pBuilder->pOrderBy); + p = allocateIndexInfo(pParse, pWC, mUnusable, pSrc, pBuilder->pOrderBy, + &mNoOmit); if( p==0 ) return SQLITE_NOMEM_BKPT; pNew->rSetup = 0; pNew->wsFlags = WHERE_VIRTUALTABLE; @@ -3126,7 +3142,7 @@ static int whereLoopAddVirtual( /* First call xBestIndex() with all constraints usable. */ WHERETRACE(0x40, (" VirtualOne: all usable\n")); - rc = whereLoopAddVirtualOne(pBuilder, mPrereq, ALLBITS, 0, p, &bIn); + rc = whereLoopAddVirtualOne(pBuilder, mPrereq, ALLBITS, 0, p, mNoOmit, &bIn); /* If the call to xBestIndex() with all terms enabled produced a plan ** that does not require any source tables (IOW: a plan with mBest==0), @@ -3143,7 +3159,8 @@ static int whereLoopAddVirtual( ** xBestIndex again, this time with IN(...) terms disabled. */ if( bIn ){ WHERETRACE(0x40, (" VirtualOne: all usable w/o IN\n")); - rc = whereLoopAddVirtualOne(pBuilder, mPrereq, ALLBITS, WO_IN, p, &bIn); + rc = whereLoopAddVirtualOne( + pBuilder, mPrereq, ALLBITS, WO_IN, p, mNoOmit, &bIn); assert( bIn==0 ); mBestNoIn = pNew->prereq & ~mPrereq; if( mBestNoIn==0 ){ @@ -3169,7 +3186,8 @@ static int whereLoopAddVirtual( if( mNext==mBest || mNext==mBestNoIn ) continue; WHERETRACE(0x40, (" VirtualOne: mPrev=%04llx mNext=%04llx\n", (sqlite3_uint64)mPrev, (sqlite3_uint64)mNext)); - rc = whereLoopAddVirtualOne(pBuilder, mPrereq, mNext|mPrereq, 0, p, &bIn); + rc = whereLoopAddVirtualOne( + pBuilder, mPrereq, mNext|mPrereq, 0, p, mNoOmit, &bIn); if( pNew->prereq==mPrereq ){ seenZero = 1; if( bIn==0 ) seenZeroNoIN = 1; @@ -3181,7 +3199,8 @@ static int whereLoopAddVirtual( ** usable), make a call here with all source tables disabled */ if( rc==SQLITE_OK && seenZero==0 ){ WHERETRACE(0x40, (" VirtualOne: all disabled\n")); - rc = whereLoopAddVirtualOne(pBuilder, mPrereq, mPrereq, 0, p, &bIn); + rc = whereLoopAddVirtualOne( + pBuilder, mPrereq, mPrereq, 0, p, mNoOmit, &bIn); if( bIn==0 ) seenZeroNoIN = 1; } @@ -3190,7 +3209,8 @@ static int whereLoopAddVirtual( ** operator, make a final call to obtain one here. */ if( rc==SQLITE_OK && seenZeroNoIN==0 ){ WHERETRACE(0x40, (" VirtualOne: all disabled and w/o IN\n")); - rc = whereLoopAddVirtualOne(pBuilder, mPrereq, mPrereq, WO_IN, p, &bIn); + rc = whereLoopAddVirtualOne( + pBuilder, mPrereq, mPrereq, WO_IN, p, mNoOmit, &bIn); } } diff --git a/src/wherecode.c b/src/wherecode.c index 901fafecaa..80de8a7e54 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -1099,7 +1099,12 @@ Bitmask sqlite3WhereCodeOneLoopStart( codeEqualityTerm(pParse, pTerm, pLevel, j, bRev, iTarget); addrNotFound = pLevel->addrNxt; }else{ - sqlite3ExprCode(pParse, pTerm->pExpr->pRight, iTarget); + Expr *pRight = pTerm->pExpr->pRight; + if( pRight->op==TK_SELECT_COLUMN ){ + codeEqualityTerm(pParse, pTerm, pLevel, j, bRev, iTarget); + }else{ + codeExprOrVector(pParse, pRight, iTarget, 1); + } } } sqlite3VdbeAddOp2(v, OP_Integer, pLoop->u.vtab.idxNum, iReg); From 9cd4933ec11db313936e1627c83fdc2d9465acf7 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 9 Aug 2016 05:48:40 +0000 Subject: [PATCH 0676/1484] Add rowvalue5.test, which should have been part of the previous commit on this branch. FossilOrigin-Name: ea03e219ced87777f0c3c6bbb0274078dbb829e2 --- manifest | 11 +++-- manifest.uuid | 2 +- test/rowvalue5.test | 113 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 120 insertions(+), 6 deletions(-) create mode 100644 test/rowvalue5.test diff --git a/manifest b/manifest index b187cc2dd9..db8399f339 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\ssome\scases\sinvolving\srow\svalues\sand\svirtual\stables. -D 2016-08-08T20:15:41.766 +C Add\srowvalue5.test,\swhich\sshould\shave\sbeen\spart\sof\sthe\sprevious\scommit\son\sthis\sbranch. +D 2016-08-09T05:48:40.637 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -1022,6 +1022,7 @@ F test/rowvalue.test 56b34d31d91340a6e922e753b798880170cc1aa7 F test/rowvalue2.test 8d5dfe75b8f4d1868a2f91f0356f20d36cba64ff F test/rowvalue3.test dbe935260851b197dfbbbcb0ac2a15cb5f324fd4 F test/rowvalue4.test 8d3b26c7ab26314b625cd2b113d782b011b91851 +F test/rowvalue5.test 01c7e0bc4048f30b58e6eb27ecd26e5bd312635e F test/rowvaluefault.test 7b16485e3f2b371f3e3d05455b8ded6d0c090244 F test/rtree.test 0c8d9dd458d6824e59683c19ab2ffa9ef946f798 F test/run-wordcount.sh 891e89c4c2d16e629cd45951d4ed899ad12afc09 @@ -1514,7 +1515,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P bb60651163553c5e46bf7b2805490570cea647b8 -R 874f48b6764b2a2fd58ccae5d488cbf6 +P 156a41f30a0afd9a70e6c26470dcc468a11bd402 +R c38c81cb8ebb8c1f60f796251d669e34 U dan -Z 25cd4c4731603d2ae10da74afc2be17b +Z f2cc02b61092cf3b9735f66f5f90cbf0 diff --git a/manifest.uuid b/manifest.uuid index 0e8e885da4..293e4dd8a1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -156a41f30a0afd9a70e6c26470dcc468a11bd402 \ No newline at end of file +ea03e219ced87777f0c3c6bbb0274078dbb829e2 \ No newline at end of file diff --git a/test/rowvalue5.test b/test/rowvalue5.test new file mode 100644 index 0000000000..c961cf7424 --- /dev/null +++ b/test/rowvalue5.test @@ -0,0 +1,113 @@ +# 2016 July 29 +# +# 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 regression tests for SQLite library. The +# focus of this file is syntax errors involving row-values and +# virtual tables. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set ::testprefix rowvalue5 + +proc vtab_command {method args} { + switch -- $method { + xConnect { + return "CREATE TABLE t1(a, b, c, d, expr)" + } + + xBestIndex { + set COL(0) a + set COL(1) b + set COL(2) c + set COL(3) d + set COL(4) expr + + set OP(eq) = + set OP(ne) != + set OP(gt) > + set OP(le) <= + set OP(lt) < + set OP(ge) >= + set OP(match) MATCH + set OP(like) LIKE + set OP(glob) GLOB + set OP(regexp) REGEXP + + set clist [lindex $args 0] + set ret [list] + set elist [list] + set i 0 + foreach c $clist { + array set C $c + if {$C(usable)} { + lappend ret omit $i + lappend elist "$COL($C(column)) $OP($C(op)) %$i%" + } + incr i + } + + lappend ret idxstr [join $elist " AND "] + #puts "xBestIndex: $ret" + return $ret + } + + xFilter { + foreach {idxnum idxstr arglist} $args {} + set i 0 + set ee $idxstr + foreach a $arglist { + if {[string is double $a]==0} { + set a "'[string map {' ''} $a]'" + } + set ee [string map [list "%$i%" $a] $ee] + incr i + } + set ee [string map [list "'" "''"] $ee] + + set ret [list sql "SELECT 1, 'a', 'b', 'c', 'd', '$ee'"] + #puts "xFilter: $ret" + return $ret + } + } + + return {} +} + +register_tcl_module db +do_execsql_test 1.0 { + CREATE VIRTUAL TABLE x1 USING tcl(vtab_command); +} {} + + +foreach {tn where res} { + 1 "1" {{}} + 2 "a=1" {{a = 1}} + 3 "a=1 AND 4 = b" {{a = 1 AND b = 4}} + 4 "c>'hello'" {{c > 'hello'}} + 5 "c<='hel''lo'" {{c <= 'hel''lo'}} + 6 "(a, b) = (SELECT 9, 10)" {{a = 9 AND b = 10}} + 7 "(+a, b) = (SELECT 'a', 'b')" {{b = 'b'}} + 8 "(a, +b) = (SELECT 'a', 'b')" {{a = 'a'}} + 10 "(a, b) IN (SELECT 9, 10 UNION SELECT 11, 12)" + {{a = 9 AND b = 10} {a = 11 AND b = 12}} + 11 "(+a, b) IN (SELECT 'a', 'b')" {{b = 'b'}} + 12 "(a, +b) IN (SELECT 'a', 'b')" {{a = 'a'}} + + 13 "(a, b) < ('d', 'e')" {{a <= 'd'}} + 14 "(a, b) < ('a', 'c')" {{a <= 'a'}} + 15 "(a, b) <= ('a', 'b')" {{a <= 'a'}} + 16 "(a, b) < ('a', 'b')" {} +} { + do_execsql_test 1.$tn "SELECT expr FROM x1 WHERE $where" $res +} + +finish_test + From 882ef0b8c08fd475df3785b37094b00b4173eeb2 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 9 Aug 2016 19:26:57 +0000 Subject: [PATCH 0677/1484] Have fts5 interpret column lists that begin with a "-" character as "match any column except" lists. FossilOrigin-Name: e517545650631d1e8a7ee63c6646a8b183a0a894 --- ext/fts5/fts5Int.h | 1 + ext/fts5/fts5_expr.c | 61 +++++++++++++++++++++++++++++++++++ ext/fts5/fts5_index.c | 12 +++++++ ext/fts5/fts5parse.y | 11 ++++++- ext/fts5/test/fts5colset.test | 59 +++++++++++++++++++++++++++++++++ manifest | 24 +++++++------- manifest.uuid | 2 +- 7 files changed, 155 insertions(+), 15 deletions(-) create mode 100644 ext/fts5/test/fts5colset.test diff --git a/ext/fts5/fts5Int.h b/ext/fts5/fts5Int.h index c7169a113b..9b1316d454 100644 --- a/ext/fts5/fts5Int.h +++ b/ext/fts5/fts5Int.h @@ -737,6 +737,7 @@ void sqlite3Fts5ParseNodeFree(Fts5ExprNode*); void sqlite3Fts5ParseSetDistance(Fts5Parse*, Fts5ExprNearset*, Fts5Token*); void sqlite3Fts5ParseSetColset(Fts5Parse*, Fts5ExprNearset*, Fts5Colset*); +void sqlite3Fts5ParseColsetNegative(Fts5Parse*, int); void sqlite3Fts5ParseFinished(Fts5Parse *pParse, Fts5ExprNode *p); void sqlite3Fts5ParseNear(Fts5Parse *pParse, Fts5Token*); diff --git a/ext/fts5/fts5_expr.c b/ext/fts5/fts5_expr.c index 9119813c85..be6d768a68 100644 --- a/ext/fts5/fts5_expr.c +++ b/ext/fts5/fts5_expr.c @@ -124,6 +124,7 @@ struct Fts5Parse { char *zErr; int rc; int nPhrase; /* Size of apPhrase array */ + int bNegativeCollist; /* Column list being parsed started with - */ Fts5ExprPhrase **apPhrase; /* Array of all phrases */ Fts5ExprNode *pExpr; /* Result of a successful parse */ }; @@ -167,6 +168,7 @@ static int fts5ExprGetToken( case ',': tok = FTS5_COMMA; break; case '+': tok = FTS5_PLUS; break; case '*': tok = FTS5_STAR; break; + case '-': tok = FTS5_MINUS; break; case '\0': tok = FTS5_EOF; break; case '"': { @@ -1793,6 +1795,53 @@ static Fts5Colset *fts5ParseColset( return pNew; } +/* +** The second argument passed to this function may be NULL, or it may be +** an existing Fts5Colset object. If it is passed NULL, this function +** returns a pointer to a new Fts5Colset object containing entries for +** all table columns except column iCol. If an OOM error occurs trying to +** allocate the Fts5Colset object, an error code is stored in pParse and +** NULL returned. +** +** If the second argument is not NULL, a copy of it is returned. Before +** returning, any entry for column iCol is removed. It is not an error +** if the Fts5Colset object does not contain an entry for column iCol +** when this function is called. +*/ +static Fts5Colset *fts5ParseNegativeColset( + Fts5Parse *pParse, /* Store SQLITE_NOMEM here if required */ + Fts5Colset *p, /* Existing colset object */ + int iCol /* New column to add to colset object */ +){ + int i; + Fts5Colset *pRet = p; + + if( pRet==0 ){ + int nCol = pParse->pConfig->nCol; + pRet = (Fts5Colset*)sqlite3Fts5MallocZero(&pParse->rc, + sizeof(Fts5Colset) + sizeof(int)*nCol + ); + if( pRet==0 ) return 0; + pRet->nCol = nCol; + for(i=0; iaiCol[i] = i; + } + } + + for(i=0; inCol; i++){ + if( pRet->aiCol[i]==iCol ){ + int nByte = sizeof(int)*(pRet->nCol-i-1); + if( nByte ){ + memmove(&pRet->aiCol[i], &pRet->aiCol[i+1], nByte); + } + pRet->nCol--; + break; + } + } + + return pRet; +} + Fts5Colset *sqlite3Fts5ParseColset( Fts5Parse *pParse, /* Store SQLITE_NOMEM here if required */ Fts5Colset *pColset, /* Existing colset object */ @@ -1811,6 +1860,8 @@ Fts5Colset *sqlite3Fts5ParseColset( } if( iCol==pConfig->nCol ){ sqlite3Fts5ParseError(pParse, "no such column: %s", z); + }else if( pParse->bNegativeCollist ){ + pRet = fts5ParseNegativeColset(pParse, pColset, iCol); }else{ pRet = fts5ParseColset(pParse, pColset, iCol); } @@ -1825,6 +1876,16 @@ Fts5Colset *sqlite3Fts5ParseColset( return pRet; } +/* +** Set (bVal==1) or clear (bVal==0) the Fts5Parse.bNegativeCollist flag. +** +** The parser calls this function as it begins to parse a colset (Fts5Colset +** object) with bVal set to 1 if the colset begins with a "-" or 0 otherwise. +*/ +void sqlite3Fts5ParseColsetNegative(Fts5Parse *pParse, int bVal){ + pParse->bNegativeCollist = bVal; +} + void sqlite3Fts5ParseSetColset( Fts5Parse *pParse, Fts5ExprNearset *pNear, diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index 1d5ebe1428..52fdc634a5 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -3195,6 +3195,14 @@ static void fts5IterSetOutputs_Nocolset(Fts5Iter *pIter, Fts5SegIter *pSeg){ } } +/* +** xSetOutputs callback used when the Fts5Colset object has nCol==0 (match +** against no columns at all). +*/ +static void fts5IterSetOutputs_ZeroColset(Fts5Iter *pIter, Fts5SegIter *pSeg){ + pIter->base.nData = 0; +} + /* ** xSetOutputs callback used by detail=col when there is a column filter ** and there are 100 or more columns. Also called as a fallback from @@ -3300,6 +3308,10 @@ static void fts5IterSetOutputCb(int *pRc, Fts5Iter *pIter){ pIter->xSetOutputs = fts5IterSetOutputs_Nocolset; } + else if( pIter->pColset->nCol==0 ){ + pIter->xSetOutputs = fts5IterSetOutputs_ZeroColset; + } + else if( pConfig->eDetail==FTS5_DETAIL_FULL ){ pIter->xSetOutputs = fts5IterSetOutputs_Full; } diff --git a/ext/fts5/fts5parse.y b/ext/fts5/fts5parse.y index 1607d3846a..8bc95f7364 100644 --- a/ext/fts5/fts5parse.y +++ b/ext/fts5/fts5parse.y @@ -119,18 +119,27 @@ cnearset(A) ::= colset(X) COLON nearset(Y). { %destructor colset { sqlite3_free($$); } %type colsetlist {Fts5Colset*} %destructor colsetlist { sqlite3_free($$); } +%type minus_opt {int} colset(A) ::= LCP colsetlist(X) RCP. { A = X; } +colset(A) ::= MINUS STRING(X). { + sqlite3Fts5ParseColsetNegative(pParse, 1); + A = sqlite3Fts5ParseColset(pParse, 0, &X); +} colset(A) ::= STRING(X). { + sqlite3Fts5ParseColsetNegative(pParse, 0); A = sqlite3Fts5ParseColset(pParse, 0, &X); } colsetlist(A) ::= colsetlist(Y) STRING(X). { A = sqlite3Fts5ParseColset(pParse, Y, &X); } -colsetlist(A) ::= STRING(X). { +colsetlist(A) ::= minus_opt(M) STRING(X). { + sqlite3Fts5ParseColsetNegative(pParse, M); A = sqlite3Fts5ParseColset(pParse, 0, &X); } +minus_opt(A) ::= MINUS. { A = 1; } +minus_opt(A) ::= . { A = 0; } %type nearset {Fts5ExprNearset*} %type nearphrases {Fts5ExprNearset*} diff --git a/ext/fts5/test/fts5colset.test b/ext/fts5/test/fts5colset.test new file mode 100644 index 0000000000..c09974a742 --- /dev/null +++ b/ext/fts5/test/fts5colset.test @@ -0,0 +1,59 @@ +# 2016 August 10 +# +# 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 regression tests for SQLite library. The +# focus of this script is testing the FTS5 module. +# + +source [file join [file dirname [info script]] fts5_common.tcl] +set testprefix fts5colset + +# If SQLITE_ENABLE_FTS5 is not defined, omit this file. +ifcapable !fts5 { + finish_test + return +} + +foreach_detail_mode $::testprefix { + if {[detail_is_none]} continue + + do_execsql_test 1.0 { + CREATE VIRTUAL TABLE t1 USING fts5(a, b, c, d, detail=%DETAIL%); + INSERT INTO t1 VALUES('a', 'b', 'c', 'd'); -- 1 + INSERT INTO t1 VALUES('d', 'a', 'b', 'c'); -- 2 + INSERT INTO t1 VALUES('c', 'd', 'a', 'b'); -- 3 + INSERT INTO t1 VALUES('b', 'c', 'd', 'a'); -- 4 + } + + foreach {tn q res} { + 1 "a" {1 2 3 4} + 2 "{a} : a" {1} + 3 "{-a} : a" {2 3 4} + 4 "{-a c} : a" {2 4} + 5 "{-d d c} : a" {1 2} + 6 "{-d c b a} : a" {} + 7 "{-\"a\"} : b" {1 2 3} + 8 "- c : a" {1 2 4} + 9 "-c : a" {1 2 4} + 10 "-\"c\" : a" {1 2 4} + } { + breakpoint + do_execsql_test 1.$tn { + SELECT rowid FROM t1($q) + } $res + } + + +} + + +finish_test + + diff --git a/manifest b/manifest index 9d5c14e49e..df25caa15d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Version\s3.14 -D 2016-08-08T13:40:27.974 +C Have\sfts5\sinterpret\scolumn\slists\sthat\sbegin\swith\sa\s"-"\scharacter\sas\s"match\sany\scolumn\sexcept"\slists. +D 2016-08-09T19:26:57.822 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -98,13 +98,13 @@ F ext/fts3/unicode/mkunicode.tcl 2debed3f582d77b3fdd0b8830880250021571fd8 F ext/fts3/unicode/parseunicode.tcl da577d1384810fb4e2b209bf3313074353193e95 F ext/fts5/extract_api_docs.tcl a36e54ec777172ddd3f9a88daf593b00848368e0 F ext/fts5/fts5.h 62f3e33ceeb9a428db139f9c012186b371da1cc7 -F ext/fts5/fts5Int.h 9bd0c7c64285b5b368eca0ac63613185c5ad24ba +F ext/fts5/fts5Int.h 51eb867d9afbd1a4130fde00c39acf9aacabe1b6 F ext/fts5/fts5_aux.c daa57fb45216491814520bbb587e97bf81ced458 F ext/fts5/fts5_buffer.c 4c1502d4c956cd092c89ce4480867f9d8bf325cd F ext/fts5/fts5_config.c 5af9c360e99669d29f06492c370892394aba0857 -F ext/fts5/fts5_expr.c bcb238ee4ac1164302ab528487520488516bd030 +F ext/fts5/fts5_expr.c 8e975ae07dbff244adea3a3697f027fa5387a991 F ext/fts5/fts5_hash.c 880998e596b60f078348d48732ca4ad9a90caad2 -F ext/fts5/fts5_index.c b429e23fabb57506f71e406997cc46b89190dc97 +F ext/fts5/fts5_index.c e25ac419fc66f412e6044595b20b4bf8f7cea284 F ext/fts5/fts5_main.c f85281445dcf8be32d18841c93a6f90fe27dbfe2 F ext/fts5/fts5_storage.c de0ed8a06738bde433afe11e92295ceaffbc4e58 F ext/fts5/fts5_tcl.c 4a901f00c8553740dba63511603f5527d741c26a @@ -114,7 +114,7 @@ F ext/fts5/fts5_tokenize.c 2ce7b44183538ec46b7907726262ee43ffdd39a8 F ext/fts5/fts5_unicode2.c b450b209b157d598f7b9df9f837afb75a14c24bf F ext/fts5/fts5_varint.c a5aceacda04dafcbae725413d7a16818ecd65738 F ext/fts5/fts5_vocab.c dba72ca393d71c2588548b51380387f6b44c77a8 -F ext/fts5/fts5parse.y fcc5e92e570d38cab38488b2109cbf67468923b2 +F ext/fts5/fts5parse.y bc2f2d9a726e69443ca58a5c0164283a63da819e F ext/fts5/mkportersteps.tcl 5acf962d2e0074f701620bb5308155fa1e4a63ba F ext/fts5/test/fts5_common.tcl b01c584144b5064f30e6c648145a2dd6bc440841 F ext/fts5/test/fts5aa.test bd2d88182b9f7f30d300044048ad14683306b745 @@ -135,6 +135,7 @@ F ext/fts5/test/fts5aux.test 5dd158a1e7869e27e9762a2a452b189c728d1be3 F ext/fts5/test/fts5auxdata.test 141a7cbffcceb1bd2799b4b29c183ff8780d586e F ext/fts5/test/fts5bigpl.test 04ee0d7eebbebf17c31f5a0b5c5f9494eac3a0cb F ext/fts5/test/fts5bigtok.test 017a9397b14e7598883a6328ead4a6539b42d59a +F ext/fts5/test/fts5colset.test ad686cc648264f0334d2cc11b842e99f6e2bc10a F ext/fts5/test/fts5columnsize.test a8cfef21ffa1c264b9f670a7d94eeaccb5341c07 F ext/fts5/test/fts5config.test 7788b9c058074d640dfcdd81d97b6a9480000368 F ext/fts5/test/fts5conflict.test 26f4e46c4d31e16221794832a990dc4e30e18de5 @@ -1509,10 +1510,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ebc396a19fa79bea208ecda277ffff5d02166d0b -R e7962d3372d6a1e29e3980753a6f0162 -T +bgcolor * #d0c0ff -T +sym-release * -T +sym-version-3.14.0 * -U drh -Z ecb9b7072c2b71d36f58909f83563ec2 +P d5e98057028abcf7217d0d2b2e29bbbcdf09d6de +R bd788c6a4ffbd14fc48e3960d75681eb +U dan +Z 8eb6c4d9289f254e7f02b4786ea43ed2 diff --git a/manifest.uuid b/manifest.uuid index 732a4af61b..0c0e3e4b5b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d5e98057028abcf7217d0d2b2e29bbbcdf09d6de \ No newline at end of file +e517545650631d1e8a7ee63c6646a8b183a0a894 \ No newline at end of file From ccf03677a38901d7d21fdd04a9338a31a8b850ab Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 9 Aug 2016 19:48:37 +0000 Subject: [PATCH 0678/1484] Minor update to the way fts5 column filters are parsed. FossilOrigin-Name: 14864f2b8470fe98dbd17f59963bf1be8d4962f9 --- ext/fts5/fts5Int.h | 1 + ext/fts5/fts5_expr.c | 66 +++++++++-------------------------- ext/fts5/fts5parse.y | 17 ++++----- ext/fts5/test/fts5colset.test | 10 +++--- manifest | 18 +++++----- manifest.uuid | 2 +- 6 files changed, 40 insertions(+), 74 deletions(-) diff --git a/ext/fts5/fts5Int.h b/ext/fts5/fts5Int.h index 9b1316d454..273b5bba29 100644 --- a/ext/fts5/fts5Int.h +++ b/ext/fts5/fts5Int.h @@ -738,6 +738,7 @@ void sqlite3Fts5ParseNodeFree(Fts5ExprNode*); void sqlite3Fts5ParseSetDistance(Fts5Parse*, Fts5ExprNearset*, Fts5Token*); void sqlite3Fts5ParseSetColset(Fts5Parse*, Fts5ExprNearset*, Fts5Colset*); void sqlite3Fts5ParseColsetNegative(Fts5Parse*, int); +Fts5Colset *sqlite3Fts5ParseColsetInvert(Fts5Parse*, Fts5Colset*); void sqlite3Fts5ParseFinished(Fts5Parse *pParse, Fts5ExprNode *p); void sqlite3Fts5ParseNear(Fts5Parse *pParse, Fts5Token*); diff --git a/ext/fts5/fts5_expr.c b/ext/fts5/fts5_expr.c index be6d768a68..ca795a6b35 100644 --- a/ext/fts5/fts5_expr.c +++ b/ext/fts5/fts5_expr.c @@ -124,7 +124,6 @@ struct Fts5Parse { char *zErr; int rc; int nPhrase; /* Size of apPhrase array */ - int bNegativeCollist; /* Column list being parsed started with - */ Fts5ExprPhrase **apPhrase; /* Array of all phrases */ Fts5ExprNode *pExpr; /* Result of a successful parse */ }; @@ -1796,49 +1795,30 @@ static Fts5Colset *fts5ParseColset( } /* -** The second argument passed to this function may be NULL, or it may be -** an existing Fts5Colset object. If it is passed NULL, this function -** returns a pointer to a new Fts5Colset object containing entries for -** all table columns except column iCol. If an OOM error occurs trying to -** allocate the Fts5Colset object, an error code is stored in pParse and -** NULL returned. -** -** If the second argument is not NULL, a copy of it is returned. Before -** returning, any entry for column iCol is removed. It is not an error -** if the Fts5Colset object does not contain an entry for column iCol -** when this function is called. +** Allocate and return an Fts5Colset object specifying the inverse of +** the colset passed as the second argument. Free the colset passed +** as the second argument before returning. */ -static Fts5Colset *fts5ParseNegativeColset( - Fts5Parse *pParse, /* Store SQLITE_NOMEM here if required */ - Fts5Colset *p, /* Existing colset object */ - int iCol /* New column to add to colset object */ -){ - int i; - Fts5Colset *pRet = p; +Fts5Colset *sqlite3Fts5ParseColsetInvert(Fts5Parse *pParse, Fts5Colset *p){ + Fts5Colset *pRet; + int nCol = pParse->pConfig->nCol; - if( pRet==0 ){ - int nCol = pParse->pConfig->nCol; - pRet = (Fts5Colset*)sqlite3Fts5MallocZero(&pParse->rc, - sizeof(Fts5Colset) + sizeof(int)*nCol - ); - if( pRet==0 ) return 0; - pRet->nCol = nCol; + pRet = (Fts5Colset*)sqlite3Fts5MallocZero(&pParse->rc, + sizeof(Fts5Colset) + sizeof(int)*nCol + ); + if( pRet ){ + int i; + int iOld = 0; for(i=0; iaiCol[i] = i; - } - } - - for(i=0; inCol; i++){ - if( pRet->aiCol[i]==iCol ){ - int nByte = sizeof(int)*(pRet->nCol-i-1); - if( nByte ){ - memmove(&pRet->aiCol[i], &pRet->aiCol[i+1], nByte); + if( iOld>=p->nCol || p->aiCol[iOld]!=i ){ + pRet->aiCol[pRet->nCol++] = i; + }else{ + iOld++; } - pRet->nCol--; - break; } } + sqlite3_free(p); return pRet; } @@ -1860,8 +1840,6 @@ Fts5Colset *sqlite3Fts5ParseColset( } if( iCol==pConfig->nCol ){ sqlite3Fts5ParseError(pParse, "no such column: %s", z); - }else if( pParse->bNegativeCollist ){ - pRet = fts5ParseNegativeColset(pParse, pColset, iCol); }else{ pRet = fts5ParseColset(pParse, pColset, iCol); } @@ -1876,16 +1854,6 @@ Fts5Colset *sqlite3Fts5ParseColset( return pRet; } -/* -** Set (bVal==1) or clear (bVal==0) the Fts5Parse.bNegativeCollist flag. -** -** The parser calls this function as it begins to parse a colset (Fts5Colset -** object) with bVal set to 1 if the colset begins with a "-" or 0 otherwise. -*/ -void sqlite3Fts5ParseColsetNegative(Fts5Parse *pParse, int bVal){ - pParse->bNegativeCollist = bVal; -} - void sqlite3Fts5ParseSetColset( Fts5Parse *pParse, Fts5ExprNearset *pNear, diff --git a/ext/fts5/fts5parse.y b/ext/fts5/fts5parse.y index 8bc95f7364..1cc4b88e18 100644 --- a/ext/fts5/fts5parse.y +++ b/ext/fts5/fts5parse.y @@ -119,28 +119,25 @@ cnearset(A) ::= colset(X) COLON nearset(Y). { %destructor colset { sqlite3_free($$); } %type colsetlist {Fts5Colset*} %destructor colsetlist { sqlite3_free($$); } -%type minus_opt {int} +colset(A) ::= MINUS LCP colsetlist(X) RCP. { + A = sqlite3Fts5ParseColsetInvert(pParse, X); +} colset(A) ::= LCP colsetlist(X) RCP. { A = X; } -colset(A) ::= MINUS STRING(X). { - sqlite3Fts5ParseColsetNegative(pParse, 1); +colset(A) ::= STRING(X). { A = sqlite3Fts5ParseColset(pParse, 0, &X); } -colset(A) ::= STRING(X). { - sqlite3Fts5ParseColsetNegative(pParse, 0); +colset(A) ::= MINUS STRING(X). { A = sqlite3Fts5ParseColset(pParse, 0, &X); + A = sqlite3Fts5ParseColsetInvert(pParse, A); } colsetlist(A) ::= colsetlist(Y) STRING(X). { A = sqlite3Fts5ParseColset(pParse, Y, &X); } -colsetlist(A) ::= minus_opt(M) STRING(X). { - sqlite3Fts5ParseColsetNegative(pParse, M); +colsetlist(A) ::= STRING(X). { A = sqlite3Fts5ParseColset(pParse, 0, &X); } -minus_opt(A) ::= MINUS. { A = 1; } -minus_opt(A) ::= . { A = 0; } - %type nearset {Fts5ExprNearset*} %type nearphrases {Fts5ExprNearset*} %destructor nearset { sqlite3Fts5ParseNearsetFree($$); } diff --git a/ext/fts5/test/fts5colset.test b/ext/fts5/test/fts5colset.test index c09974a742..e3333241ee 100644 --- a/ext/fts5/test/fts5colset.test +++ b/ext/fts5/test/fts5colset.test @@ -35,11 +35,11 @@ foreach_detail_mode $::testprefix { foreach {tn q res} { 1 "a" {1 2 3 4} 2 "{a} : a" {1} - 3 "{-a} : a" {2 3 4} - 4 "{-a c} : a" {2 4} - 5 "{-d d c} : a" {1 2} - 6 "{-d c b a} : a" {} - 7 "{-\"a\"} : b" {1 2 3} + 3 "-{a} : a" {2 3 4} + 4 "- {a c} : a" {2 4} + 5 " - {d d c} : a" {1 2} + 6 "- {d c b a} : a" {} + 7 "-{\"a\"} : b" {1 2 3} 8 "- c : a" {1 2 4} 9 "-c : a" {1 2 4} 10 "-\"c\" : a" {1 2 4} diff --git a/manifest b/manifest index df25caa15d..ce75d33797 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Have\sfts5\sinterpret\scolumn\slists\sthat\sbegin\swith\sa\s"-"\scharacter\sas\s"match\sany\scolumn\sexcept"\slists. -D 2016-08-09T19:26:57.822 +C Minor\supdate\sto\sthe\sway\sfts5\scolumn\sfilters\sare\sparsed. +D 2016-08-09T19:48:37.555 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -98,11 +98,11 @@ F ext/fts3/unicode/mkunicode.tcl 2debed3f582d77b3fdd0b8830880250021571fd8 F ext/fts3/unicode/parseunicode.tcl da577d1384810fb4e2b209bf3313074353193e95 F ext/fts5/extract_api_docs.tcl a36e54ec777172ddd3f9a88daf593b00848368e0 F ext/fts5/fts5.h 62f3e33ceeb9a428db139f9c012186b371da1cc7 -F ext/fts5/fts5Int.h 51eb867d9afbd1a4130fde00c39acf9aacabe1b6 +F ext/fts5/fts5Int.h 17d72c55d6e0d23cd6a3936312a5fd8cddcbd962 F ext/fts5/fts5_aux.c daa57fb45216491814520bbb587e97bf81ced458 F ext/fts5/fts5_buffer.c 4c1502d4c956cd092c89ce4480867f9d8bf325cd F ext/fts5/fts5_config.c 5af9c360e99669d29f06492c370892394aba0857 -F ext/fts5/fts5_expr.c 8e975ae07dbff244adea3a3697f027fa5387a991 +F ext/fts5/fts5_expr.c df0004b5bffcbe34c329f2992669c6352443f415 F ext/fts5/fts5_hash.c 880998e596b60f078348d48732ca4ad9a90caad2 F ext/fts5/fts5_index.c e25ac419fc66f412e6044595b20b4bf8f7cea284 F ext/fts5/fts5_main.c f85281445dcf8be32d18841c93a6f90fe27dbfe2 @@ -114,7 +114,7 @@ F ext/fts5/fts5_tokenize.c 2ce7b44183538ec46b7907726262ee43ffdd39a8 F ext/fts5/fts5_unicode2.c b450b209b157d598f7b9df9f837afb75a14c24bf F ext/fts5/fts5_varint.c a5aceacda04dafcbae725413d7a16818ecd65738 F ext/fts5/fts5_vocab.c dba72ca393d71c2588548b51380387f6b44c77a8 -F ext/fts5/fts5parse.y bc2f2d9a726e69443ca58a5c0164283a63da819e +F ext/fts5/fts5parse.y e51b375403421b8b37428a89b095d00597129aae F ext/fts5/mkportersteps.tcl 5acf962d2e0074f701620bb5308155fa1e4a63ba F ext/fts5/test/fts5_common.tcl b01c584144b5064f30e6c648145a2dd6bc440841 F ext/fts5/test/fts5aa.test bd2d88182b9f7f30d300044048ad14683306b745 @@ -135,7 +135,7 @@ F ext/fts5/test/fts5aux.test 5dd158a1e7869e27e9762a2a452b189c728d1be3 F ext/fts5/test/fts5auxdata.test 141a7cbffcceb1bd2799b4b29c183ff8780d586e F ext/fts5/test/fts5bigpl.test 04ee0d7eebbebf17c31f5a0b5c5f9494eac3a0cb F ext/fts5/test/fts5bigtok.test 017a9397b14e7598883a6328ead4a6539b42d59a -F ext/fts5/test/fts5colset.test ad686cc648264f0334d2cc11b842e99f6e2bc10a +F ext/fts5/test/fts5colset.test 1cdf56e079316005aabda790059aee86f2222ee4 F ext/fts5/test/fts5columnsize.test a8cfef21ffa1c264b9f670a7d94eeaccb5341c07 F ext/fts5/test/fts5config.test 7788b9c058074d640dfcdd81d97b6a9480000368 F ext/fts5/test/fts5conflict.test 26f4e46c4d31e16221794832a990dc4e30e18de5 @@ -1510,7 +1510,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d5e98057028abcf7217d0d2b2e29bbbcdf09d6de -R bd788c6a4ffbd14fc48e3960d75681eb +P e517545650631d1e8a7ee63c6646a8b183a0a894 +R da20bee26e7c2a9f4b1bf24d21e0ff86 U dan -Z 8eb6c4d9289f254e7f02b4786ea43ed2 +Z a6c95b8c36e7e9259f54069259e2a828 diff --git a/manifest.uuid b/manifest.uuid index 0c0e3e4b5b..7cd334dbf2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e517545650631d1e8a7ee63c6646a8b183a0a894 \ No newline at end of file +14864f2b8470fe98dbd17f59963bf1be8d4962f9 \ No newline at end of file From 8d57d7af23f942dd44b16dea77c0045701cc6e5e Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 9 Aug 2016 21:01:52 +0000 Subject: [PATCH 0679/1484] Fix harmless compiler warning. FossilOrigin-Name: 9a5a4f6e3bc265fecf79a7f63d14abbf239da636 --- ext/fts5/fts5Int.h | 1 - manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/ext/fts5/fts5Int.h b/ext/fts5/fts5Int.h index 273b5bba29..9ef338e821 100644 --- a/ext/fts5/fts5Int.h +++ b/ext/fts5/fts5Int.h @@ -737,7 +737,6 @@ void sqlite3Fts5ParseNodeFree(Fts5ExprNode*); void sqlite3Fts5ParseSetDistance(Fts5Parse*, Fts5ExprNearset*, Fts5Token*); void sqlite3Fts5ParseSetColset(Fts5Parse*, Fts5ExprNearset*, Fts5Colset*); -void sqlite3Fts5ParseColsetNegative(Fts5Parse*, int); Fts5Colset *sqlite3Fts5ParseColsetInvert(Fts5Parse*, Fts5Colset*); void sqlite3Fts5ParseFinished(Fts5Parse *pParse, Fts5ExprNode *p); void sqlite3Fts5ParseNear(Fts5Parse *pParse, Fts5Token*); diff --git a/manifest b/manifest index ce75d33797..850a297904 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Minor\supdate\sto\sthe\sway\sfts5\scolumn\sfilters\sare\sparsed. -D 2016-08-09T19:48:37.555 +C Fix\sharmless\scompiler\swarning. +D 2016-08-09T21:01:52.333 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -98,7 +98,7 @@ F ext/fts3/unicode/mkunicode.tcl 2debed3f582d77b3fdd0b8830880250021571fd8 F ext/fts3/unicode/parseunicode.tcl da577d1384810fb4e2b209bf3313074353193e95 F ext/fts5/extract_api_docs.tcl a36e54ec777172ddd3f9a88daf593b00848368e0 F ext/fts5/fts5.h 62f3e33ceeb9a428db139f9c012186b371da1cc7 -F ext/fts5/fts5Int.h 17d72c55d6e0d23cd6a3936312a5fd8cddcbd962 +F ext/fts5/fts5Int.h b2eda36e0f224365c8e23dc8f559311834f1c13f F ext/fts5/fts5_aux.c daa57fb45216491814520bbb587e97bf81ced458 F ext/fts5/fts5_buffer.c 4c1502d4c956cd092c89ce4480867f9d8bf325cd F ext/fts5/fts5_config.c 5af9c360e99669d29f06492c370892394aba0857 @@ -1510,7 +1510,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e517545650631d1e8a7ee63c6646a8b183a0a894 -R da20bee26e7c2a9f4b1bf24d21e0ff86 -U dan -Z a6c95b8c36e7e9259f54069259e2a828 +P 14864f2b8470fe98dbd17f59963bf1be8d4962f9 +R 3c3d32515aedcf447480f55f3548a5e0 +U drh +Z 4951f1f9d58f89a54689c68080c6d7fb diff --git a/manifest.uuid b/manifest.uuid index 7cd334dbf2..a3c154d615 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -14864f2b8470fe98dbd17f59963bf1be8d4962f9 \ No newline at end of file +9a5a4f6e3bc265fecf79a7f63d14abbf239da636 \ No newline at end of file From 6bada27205b214a5fda8200b1bceacca59d8ec41 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 9 Aug 2016 21:08:42 +0000 Subject: [PATCH 0680/1484] Prototype for the remember(V,PTR) extension function. FossilOrigin-Name: f0942c362f45ca1e986e142dbdd3ad957626dfb1 --- Makefile.in | 1 + Makefile.msc | 1 + ext/misc/remember.c | 68 +++++++++++++++++++++++++++++++++++++++++++++ main.mk | 1 + manifest | 24 +++++++++------- manifest.uuid | 2 +- src/test1.c | 2 ++ test/tabfunc01.test | 14 ++++++++++ 8 files changed, 102 insertions(+), 11 deletions(-) create mode 100644 ext/misc/remember.c diff --git a/Makefile.in b/Makefile.in index 9b2fe86cf4..852d023356 100644 --- a/Makefile.in +++ b/Makefile.in @@ -429,6 +429,7 @@ TESTSRC += \ $(TOP)/ext/misc/nextchar.c \ $(TOP)/ext/misc/percentile.c \ $(TOP)/ext/misc/regexp.c \ + $(TOP)/ext/misc/remember.c \ $(TOP)/ext/misc/series.c \ $(TOP)/ext/misc/spellfix.c \ $(TOP)/ext/misc/totype.c \ diff --git a/Makefile.msc b/Makefile.msc index cd866ce4a4..d696df7551 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -1305,6 +1305,7 @@ TESTEXT = \ $(TOP)\ext\misc\nextchar.c \ $(TOP)\ext\misc\percentile.c \ $(TOP)\ext\misc\regexp.c \ + $(TOP)\ext\misc\remember.c \ $(TOP)\ext\misc\series.c \ $(TOP)\ext\misc\spellfix.c \ $(TOP)\ext\misc\totype.c \ diff --git a/ext/misc/remember.c b/ext/misc/remember.c new file mode 100644 index 0000000000..aa3eff8a3f --- /dev/null +++ b/ext/misc/remember.c @@ -0,0 +1,68 @@ +/* +** 2016-08-09 +** +** 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 demonstrates how to create an SQL function that is a pass-through +** for integer values (it returns a copy of its argument) but also saves the +** value that is passed through into a C-language variable. The address of +** the C-language variable is supplied as the second argument. +** +** This allows, for example, a counter to incremented and the original +** value retrieved, atomically, using a single statement: +** +** UPDATE counterTab SET cnt=remember(cnt,$PTR)+1 WHERE id=$ID +** +** Prepare the above statement once. Then to use it, bind the address +** of the output variable to $PTR and the id of the counter to $ID and +** run the prepared statement. +** +** One can imagine doing similar things with floating-point values and +** strings, but this demonstration extension will stick to using just +** integers. +*/ +#include "sqlite3ext.h" +SQLITE_EXTENSION_INIT1 +#include + +/* +** remember(V,PTR) +** +** Return the integer value V. Also save the value of V in a +** C-language variable whose address is PTR. +*/ +static void rememberFunc( + sqlite3_context *pCtx, + int argc, + sqlite3_value **argv +){ + sqlite3_int64 v; + sqlite3_int64 ptr; + assert( argc==2 ); + v = sqlite3_value_int64(argv[0]); + ptr = sqlite3_value_int64(argv[1]); + *((sqlite3_int64*)ptr) = v; + sqlite3_result_int64(pCtx, v); +} + +#ifdef _WIN32 +__declspec(dllexport) +#endif +int sqlite3_remember_init( + sqlite3 *db, + char **pzErrMsg, + const sqlite3_api_routines *pApi +){ + int rc = SQLITE_OK; + SQLITE_EXTENSION_INIT2(pApi); + rc = sqlite3_create_function(db, "remember", 2, SQLITE_UTF8, 0, + rememberFunc, 0, 0); + return rc; +} diff --git a/main.mk b/main.mk index 451837ffff..6c8afbef59 100644 --- a/main.mk +++ b/main.mk @@ -334,6 +334,7 @@ TESTSRC += \ $(TOP)/ext/misc/nextchar.c \ $(TOP)/ext/misc/percentile.c \ $(TOP)/ext/misc/regexp.c \ + $(TOP)/ext/misc/remember.c \ $(TOP)/ext/misc/series.c \ $(TOP)/ext/misc/spellfix.c \ $(TOP)/ext/misc/totype.c \ diff --git a/manifest b/manifest index 850a297904..87310ef875 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -C Fix\sharmless\scompiler\swarning. -D 2016-08-09T21:01:52.333 -F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 +C Prototype\sfor\sthe\sremember(V,PTR)\sextension\sfunction. +D 2016-08-09T21:08:42.832 +F Makefile.in 6b7b3d1c441dd80a22cf0103061fc0815ca86294 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 -F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a +F Makefile.msc 7ec77041ea6d86996c7b9f8ad2cf463e1eb24846 F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7 F VERSION cb29eb11e493dd85b3eeec4053c03949bf98478e F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 @@ -217,6 +217,7 @@ F ext/misc/json1.c 9799e4252b305edcbe659329eec3ca80ed85f968 F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342 F ext/misc/percentile.c 92699c8cd7d517ff610e6037e56506f8904dae2e F ext/misc/regexp.c a68d25c659bd2d893cd1215667bbf75ecb9dc7d4 +F ext/misc/remember.c 8440f8d0b452c5cdefb62b57135ccd1267aa729d F ext/misc/rot13.c 1ac6f95f99b575907b9b09c81a349114cf9be45a F ext/misc/scrub.c 1c5bfb8b0cd18b602fcb55755e84abf0023ac2fb F ext/misc/series.c e11e534ada797d5b816d7e7a93c022306563ca35 @@ -309,7 +310,7 @@ F ext/userauth/userauth.c 5fa3bdb492f481bbc1709fc83c91ebd13460c69e F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60 -F main.mk 1883ecab643b136e8ab3fdc33785e6ea8b5ceb46 +F main.mk e9a25e0027df155957ea88ef317a7c80b1372537 F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 @@ -394,7 +395,7 @@ F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 F src/tclsqlite.c bdae822f21e229b6daced15938b6343ce44ef454 -F src/test1.c 0a0909cf7962d2359db329c08d15b90b4b6e724f +F src/test1.c 4276cd840acf0fc5f2b04250c9343b209cc60e1b F src/test2.c b7174313e993754303a8b33c43df7c44b46857ab F src/test3.c 1339a40be39650ae83894b6578f971dc7f96ea8a F src/test4.c 18ec393bb4d0ad1de729f0b94da7267270f3d8e6 @@ -1118,7 +1119,7 @@ F test/symlink.test c9ebe7330d228249e447038276bfc8a7b22f4849 F test/sync.test 2f84bdbc2b2df1fcb0220575b4b9f8cea94b7529 F test/syscall.test f59ba4e25f7ba4a4c031026cc2ef8b6e4b4c639c F test/sysfault.test c9f2b0d8d677558f74de750c75e12a5454719d04 -F test/tabfunc01.test 50a9fb379f9747fd0d40ea6d8fa3a101361bb537 +F test/tabfunc01.test 8b2ef53caa37854864c89e1e57e8a10efd4f5e43 F test/table.test b708f3e5fa2542fa51dfab21fc07b36ea445cb2f F test/tableapi.test 2674633fa95d80da917571ebdd759a14d9819126 F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930 @@ -1510,7 +1511,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 14864f2b8470fe98dbd17f59963bf1be8d4962f9 -R 3c3d32515aedcf447480f55f3548a5e0 +P 9a5a4f6e3bc265fecf79a7f63d14abbf239da636 +R a4aeba273d85b5b6518de32b9203944f +T *branch * rememberFunc +T *sym-rememberFunc * +T -sym-trunk * U drh -Z 4951f1f9d58f89a54689c68080c6d7fb +Z c510cdb1fe7f1007d6a0bc0b22076879 diff --git a/manifest.uuid b/manifest.uuid index a3c154d615..71390237f6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9a5a4f6e3bc265fecf79a7f63d14abbf239da636 \ No newline at end of file +f0942c362f45ca1e986e142dbdd3ad957626dfb1 \ No newline at end of file diff --git a/src/test1.c b/src/test1.c index aced552173..b4197ef73d 100644 --- a/src/test1.c +++ b/src/test1.c @@ -6764,6 +6764,7 @@ static int SQLITE_TCLAPI tclLoadStaticExtensionCmd( extern int sqlite3_nextchar_init(sqlite3*,char**,const sqlite3_api_routines*); extern int sqlite3_percentile_init(sqlite3*,char**,const sqlite3_api_routines*); extern int sqlite3_regexp_init(sqlite3*,char**,const sqlite3_api_routines*); + extern int sqlite3_remember_init(sqlite3*,char**,const sqlite3_api_routines*); extern int sqlite3_series_init(sqlite3*,char**,const sqlite3_api_routines*); extern int sqlite3_spellfix_init(sqlite3*,char**,const sqlite3_api_routines*); extern int sqlite3_totype_init(sqlite3*,char**,const sqlite3_api_routines*); @@ -6783,6 +6784,7 @@ static int SQLITE_TCLAPI tclLoadStaticExtensionCmd( { "nextchar", sqlite3_nextchar_init }, { "percentile", sqlite3_percentile_init }, { "regexp", sqlite3_regexp_init }, + { "remember", sqlite3_remember_init }, { "series", sqlite3_series_init }, { "spellfix", sqlite3_spellfix_init }, { "totype", sqlite3_totype_init }, diff --git a/test/tabfunc01.test b/test/tabfunc01.test index 19d3cc66d5..f25d070847 100644 --- a/test/tabfunc01.test +++ b/test/tabfunc01.test @@ -23,6 +23,7 @@ ifcapable !vtab { } load_static_extension db series load_static_extension db carray +load_static_extension db remember do_execsql_test tabfunc01-1.1 { SELECT *, '|' FROM generate_series WHERE start=1 AND stop=9 AND step=2; @@ -172,6 +173,19 @@ do_test tabfunc01-720 { SELECT b FROM t600, carray($PTR,5,'int64') WHERE a=value; } } {(005) (007) (013) (017) (023)} +do_test tabfunc01-721 { + db eval { + SELECT remember(123,$PTR); + SELECT value FROM carray($PTR,5,'int64'); + } +} {123 123 7 13 17 23} +do_test tabfunc01-722 { + set PTR2 [expr {$PTR+16}] + db eval { + SELECT remember(987,$PTR2); + SELECT value FROM carray($PTR,5,'int64'); + } +} {987 123 7 987 17 23} do_test tabfunc01-730 { set PTR [doublearray_addr 5.0 7.0 13.0 17.0 23.0] From c83db9e4e1c0cba15effedb4bf5411653b5c9005 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 10 Aug 2016 01:43:30 +0000 Subject: [PATCH 0681/1484] Performance optimization in the yy_find_shift_action() routine of the Lemon-generated parser. FossilOrigin-Name: ba6663beefcc8060e6f3be6ab37c13fdbb08b7de --- manifest | 12 ++++++------ manifest.uuid | 2 +- tool/lempar.c | 53 ++++++++++++++++++++++++--------------------------- 3 files changed, 32 insertions(+), 35 deletions(-) diff --git a/manifest b/manifest index 850a297904..679af7eda6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\scompiler\swarning. -D 2016-08-09T21:01:52.333 +C Performance\soptimization\sin\sthe\syy_find_shift_action()\sroutine\sof\sthe\nLemon-generated\sparser. +D 2016-08-10T01:43:30.837 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -1438,7 +1438,7 @@ F tool/genfkey.README cf68fddd4643bbe3ff8e31b8b6d8b0a1b85e20f4 F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5 F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce F tool/lemon.c 09a96bed19955697a5e20c49ad863ec2005815a2 -F tool/lempar.c 57ffa9852901f6abc45981f0d882f31d1ccb06c0 +F tool/lempar.c 321ebbf1c85ab5435434042590eca0616da24b3d F tool/libvers.c caafc3b689638a1d88d44bc5f526c2278760d9b9 F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862 F tool/logest.c 11346aa019e2e77a00902aa7d0cabd27bd2e8cca @@ -1510,7 +1510,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 14864f2b8470fe98dbd17f59963bf1be8d4962f9 -R 3c3d32515aedcf447480f55f3548a5e0 +P 9a5a4f6e3bc265fecf79a7f63d14abbf239da636 +R fb6cb5f47404a4ca8ae3044e53622029 U drh -Z 4951f1f9d58f89a54689c68080c6d7fb +Z 1ed24d5681cad4ee5c357b2d89914ae1 diff --git a/manifest.uuid b/manifest.uuid index a3c154d615..f5266c615d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9a5a4f6e3bc265fecf79a7f63d14abbf239da636 \ No newline at end of file +ba6663beefcc8060e6f3be6ab37c13fdbb08b7de \ No newline at end of file diff --git a/tool/lempar.c b/tool/lempar.c index e0d0e88565..74906ae17f 100644 --- a/tool/lempar.c +++ b/tool/lempar.c @@ -450,50 +450,47 @@ static unsigned int yy_find_shift_action( assert( stateno <= YY_SHIFT_COUNT ); do{ i = yy_shift_ofst[stateno]; - if( i==YY_SHIFT_USE_DFLT ) return yy_default[stateno]; assert( iLookAhead!=YYNOCODE ); i += iLookAhead; if( i<0 || i>=YY_ACTTAB_COUNT || yy_lookahead[i]!=iLookAhead ){ - if( iLookAhead>0 ){ #ifdef YYFALLBACK - YYCODETYPE iFallback; /* Fallback token */ - if( iLookAhead %s\n", - yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[iFallback]); - } -#endif - assert( yyFallback[iFallback]==0 ); /* Fallback loop must terminate */ - iLookAhead = iFallback; - continue; + if( yyTraceFILE ){ + fprintf(yyTraceFILE, "%sFALLBACK %s => %s\n", + yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[iFallback]); } +#endif + assert( yyFallback[iFallback]==0 ); /* Fallback loop must terminate */ + iLookAhead = iFallback; + continue; + } #endif #ifdef YYWILDCARD - { - int j = i - iLookAhead + YYWILDCARD; - if( + { + int j = i - iLookAhead + YYWILDCARD; + if( #if YY_SHIFT_MIN+YYWILDCARD<0 - j>=0 && + j>=0 && #endif #if YY_SHIFT_MAX+YYWILDCARD>=YY_ACTTAB_COUNT - j0 + ){ #ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE, "%sWILDCARD %s => %s\n", - yyTracePrompt, yyTokenName[iLookAhead], - yyTokenName[YYWILDCARD]); - } -#endif /* NDEBUG */ - return yy_action[j]; + if( yyTraceFILE ){ + fprintf(yyTraceFILE, "%sWILDCARD %s => %s\n", + yyTracePrompt, yyTokenName[iLookAhead], + yyTokenName[YYWILDCARD]); } +#endif /* NDEBUG */ + return yy_action[j]; } -#endif /* YYWILDCARD */ } +#endif /* YYWILDCARD */ return yy_default[stateno]; }else{ return yy_action[i]; From d9fabbcc5beff63ef8eb29d36dee0ffae55b67b6 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 10 Aug 2016 11:50:12 +0000 Subject: [PATCH 0682/1484] Fix pcache1TruncateUnsafe() run faster for the case where iLimit is very close to iMaxKey. FossilOrigin-Name: b07a26df06a2ffb946ff8a1cc7f43eaf701a94b5 --- manifest | 13 +++++++------ manifest.uuid | 2 +- src/pcache1.c | 34 +++++++++++++++++++++++++++------- 3 files changed, 35 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index 679af7eda6..316b95fb86 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Performance\soptimization\sin\sthe\syy_find_shift_action()\sroutine\sof\sthe\nLemon-generated\sparser. -D 2016-08-10T01:43:30.837 +C Fix\spcache1TruncateUnsafe()\srun\sfaster\sfor\sthe\scase\swhere\siLimit\sis\nvery\sclose\sto\siMaxKey. +D 2016-08-10T11:50:12.345 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -376,7 +376,7 @@ F src/pager.h 966d2769e76ae347c8a32c4165faf6e6cb64546d F src/parse.y 99b676e6fc2f4e331ab93e76b3987cffdbd28efa F src/pcache.c 5583c8ade4b05075a60ba953ef471d1c1a9c05df F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 -F src/pcache1.c 7f51d2b541aab57596adf62db2c4bb025d34f04d +F src/pcache1.c dc8a6052e5136d6b5e6afe51f37485145646f5ab F src/pragma.c c8b499756658cb8b82cfdbb5845c22cf11f297aa F src/pragma.h 64c78a648751b9f4f297276c4eb7507b14b4628c F src/prepare.c 22df6171aec1d86904ed2ad30c2348a5748aa04e @@ -1510,7 +1510,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 9a5a4f6e3bc265fecf79a7f63d14abbf239da636 -R fb6cb5f47404a4ca8ae3044e53622029 +P ba6663beefcc8060e6f3be6ab37c13fdbb08b7de +Q +9ab53605d562a926c5620cba9dc96a3b812a432f +R 045183d4dc58e68027bf139105903731 U drh -Z 1ed24d5681cad4ee5c357b2d89914ae1 +Z 7fb6739dae3ac730e38720df5d5c1de9 diff --git a/manifest.uuid b/manifest.uuid index f5266c615d..5bb9a78a83 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ba6663beefcc8060e6f3be6ab37c13fdbb08b7de \ No newline at end of file +b07a26df06a2ffb946ff8a1cc7f43eaf701a94b5 \ No newline at end of file diff --git a/src/pcache1.c b/src/pcache1.c index 5fe963ad05..1af1ef5bb7 100644 --- a/src/pcache1.c +++ b/src/pcache1.c @@ -632,12 +632,30 @@ static void pcache1TruncateUnsafe( PCache1 *pCache, /* The cache to truncate */ unsigned int iLimit /* Drop pages with this pgno or larger */ ){ - TESTONLY( unsigned int nPage = 0; ) /* To assert pCache->nPage is correct */ - unsigned int h; + TESTONLY( int nPage = 0; ) /* To assert pCache->nPage is correct */ + unsigned int h, iStop; assert( sqlite3_mutex_held(pCache->pGroup->mutex) ); - for(h=0; hnHash; h++){ - PgHdr1 **pp = &pCache->apHash[h]; + assert( pCache->iMaxKey >= iLimit ); + assert( pCache->nHash > 0 ); + if( pCache->iMaxKey - iLimit < pCache->nHash/2 ){ + /* If we are just shaving the last few pages off the end of the + ** cache, then there is no point in scanning the entire hash table. + ** Only scan those hash slots that might contain pages that need to + ** be removed. */ + iStop = iLimit % pCache->nHash; + h = pCache->iMaxKey % pCache->nHash; + TESTONLY( nPage = -10; ) /* Disable the pCache->nPage validity check */ + }else{ + /* This is the general case where many pages are being removed. + ** It is necessary to scan the entire hash table */ + iStop = 0; + h = pCache->nHash - 1; + } + for(;;){ + PgHdr1 **pp; PgHdr1 *pPage; + assert( hnHash ); + pp = &pCache->apHash[h]; while( (pPage = *pp)!=0 ){ if( pPage->iKey>=iLimit ){ pCache->nPage--; @@ -646,11 +664,13 @@ static void pcache1TruncateUnsafe( pcache1FreePage(pPage); }else{ pp = &pPage->pNext; - TESTONLY( nPage++; ) + TESTONLY( if( nPage>=0 ) nPage++; ) } } + if( h==iStop ) break; + h = h ? h-1 : pCache->nHash - 1; } - assert( pCache->nPage==nPage ); + assert( nPage<0 || pCache->nPage==(unsigned)nPage ); } /******************************************************************************/ @@ -1127,7 +1147,7 @@ static void pcache1Destroy(sqlite3_pcache *p){ PGroup *pGroup = pCache->pGroup; assert( pCache->bPurgeable || (pCache->nMax==0 && pCache->nMin==0) ); pcache1EnterMutex(pGroup); - pcache1TruncateUnsafe(pCache, 0); + if( pCache->nPage ) pcache1TruncateUnsafe(pCache, 0); assert( pGroup->nMaxPage >= pCache->nMax ); pGroup->nMaxPage -= pCache->nMax; assert( pGroup->nMinPage >= pCache->nMin ); From 701b68879c06620e0e4b7dcbb644fbeb951867ba Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 10 Aug 2016 13:30:43 +0000 Subject: [PATCH 0683/1484] Improved comments on the lempar.c parser template. Adjust the YY_SHIFT_USE_DFLT constant in the Lemon-generated parser tables so as to guarantee that it is always out of range of the yy_lookahead[] table. FossilOrigin-Name: 83622f3f50030e4d6abafb99d99742928aaf157c --- manifest | 15 +++++++-------- manifest.uuid | 2 +- tool/lemon.c | 13 +++++++------ tool/lempar.c | 20 ++++++++++++-------- 4 files changed, 27 insertions(+), 23 deletions(-) diff --git a/manifest b/manifest index 316b95fb86..a0534bfabe 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\spcache1TruncateUnsafe()\srun\sfaster\sfor\sthe\scase\swhere\siLimit\sis\nvery\sclose\sto\siMaxKey. -D 2016-08-10T11:50:12.345 +C Improved\scomments\son\sthe\slempar.c\sparser\stemplate.\s\sAdjust\sthe\nYY_SHIFT_USE_DFLT\sconstant\sin\sthe\sLemon-generated\sparser\stables\sso\sas\nto\sguarantee\sthat\sit\sis\salways\sout\sof\srange\sof\sthe\syy_lookahead[]\stable. +D 2016-08-10T13:30:43.279 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -1437,8 +1437,8 @@ F tool/fuzzershell.c 94019b185caceffc9f7c7b678a6489e42bc2aefa F tool/genfkey.README cf68fddd4643bbe3ff8e31b8b6d8b0a1b85e20f4 F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5 F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce -F tool/lemon.c 09a96bed19955697a5e20c49ad863ec2005815a2 -F tool/lempar.c 321ebbf1c85ab5435434042590eca0616da24b3d +F tool/lemon.c e3aa9ba3469804d7cae13b5e041aab192b7b381a +F tool/lempar.c 147e42a5cd83ce38275fde0d07a5df3330cb9b3b F tool/libvers.c caafc3b689638a1d88d44bc5f526c2278760d9b9 F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862 F tool/logest.c 11346aa019e2e77a00902aa7d0cabd27bd2e8cca @@ -1510,8 +1510,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ba6663beefcc8060e6f3be6ab37c13fdbb08b7de -Q +9ab53605d562a926c5620cba9dc96a3b812a432f -R 045183d4dc58e68027bf139105903731 +P b07a26df06a2ffb946ff8a1cc7f43eaf701a94b5 +R f8409033fe00bbe724670b3d36a1f97d U drh -Z 7fb6739dae3ac730e38720df5d5c1de9 +Z c9080bc44cd5d5b39b4e8d736cb94a4a diff --git a/manifest.uuid b/manifest.uuid index 5bb9a78a83..d2f3f5ca4a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b07a26df06a2ffb946ff8a1cc7f43eaf701a94b5 \ No newline at end of file +83622f3f50030e4d6abafb99d99742928aaf157c \ No newline at end of file diff --git a/tool/lemon.c b/tool/lemon.c index 5f124601db..df758a5da6 100644 --- a/tool/lemon.c +++ b/tool/lemon.c @@ -4231,20 +4231,21 @@ void ReportTable( fprintf(out, "};\n"); lineno++; /* Output the yy_shift_ofst[] table */ - fprintf(out, "#define YY_SHIFT_USE_DFLT (%d)\n", mnTknOfst-1); lineno++; n = lemp->nxstate; while( n>0 && lemp->sorted[n-1]->iTknOfst==NO_OFFSET ) n--; - fprintf(out, "#define YY_SHIFT_COUNT (%d)\n", n-1); lineno++; - fprintf(out, "#define YY_SHIFT_MIN (%d)\n", mnTknOfst); lineno++; - fprintf(out, "#define YY_SHIFT_MAX (%d)\n", mxTknOfst); lineno++; + fprintf(out, "#define YY_SHIFT_USE_DFLT (%d)\n", lemp->nactiontab); lineno++; + fprintf(out, "#define YY_SHIFT_COUNT (%d)\n", n-1); lineno++; + fprintf(out, "#define YY_SHIFT_MIN (%d)\n", mnTknOfst); lineno++; + fprintf(out, "#define YY_SHIFT_MAX (%d)\n", mxTknOfst); lineno++; fprintf(out, "static const %s yy_shift_ofst[] = {\n", - minimum_size_type(mnTknOfst-1, mxTknOfst, &sz)); lineno++; + minimum_size_type(mnTknOfst, lemp->nterminal+lemp->nactiontab, &sz)); + lineno++; lemp->tablesize += n*sz; for(i=j=0; isorted[i]; ofst = stp->iTknOfst; - if( ofst==NO_OFFSET ) ofst = mnTknOfst - 1; + if( ofst==NO_OFFSET ) ofst = lemp->nactiontab; if( j==0 ) fprintf(out," /* %5d */ ", i); fprintf(out, " %4d,", ofst); if( j==9 || i==n-1 ){ diff --git a/tool/lempar.c b/tool/lempar.c index 74906ae17f..61d19451e9 100644 --- a/tool/lempar.c +++ b/tool/lempar.c @@ -116,7 +116,7 @@ ** ** N between YY_MIN_REDUCE Reduce by rule N-YY_MIN_REDUCE ** and YY_MAX_REDUCE - +** ** N == YY_ERROR_ACTION A syntax error has occurred. ** ** N == YY_ACCEPT_ACTION The parser accepts its input. @@ -125,16 +125,20 @@ ** slots in the yy_action[] table. ** ** The action table is constructed as a single large table named yy_action[]. -** Given state S and lookahead X, the action is computed as +** Given state S and lookahead X, the action is computed as either: ** -** yy_action[ yy_shift_ofst[S] + X ] +** (A) N = yy_action[ yy_shift_ofst[S] + X ] +** (B) N = yy_default[S] ** -** If the index value yy_shift_ofst[S]+X is out of range or if the value -** yy_lookahead[yy_shift_ofst[S]+X] is not equal to X or if yy_shift_ofst[S] -** is equal to YY_SHIFT_USE_DFLT, it means that the action is not in the table -** and that yy_default[S] should be used instead. +** The (A) formula is preferred. The B formula is used instead if: +** (1) The yy_shift_ofst[S]+X value is out of range, or +** (2) yy_lookahead[yy_shift_ofst[S]+X] is not equal to X, or +** (3) yy_shift_ofst[S] equal YY_SHIFT_USE_DFLT. +** (Implementation note: YY_SHIFT_USE_DFLT is chosen so that +** YY_SHIFT_USE_DFLT+X will be out of range for all possible lookaheads X. +** Hence only tests (1) and (2) need to be evaluated.) ** -** The formula above is for computing the action when the lookahead is +** The formulas above are for computing the action when the lookahead is ** a terminal symbol. If the lookahead is a non-terminal (as occurs after ** a reduce action) then the yy_reduce_ofst[] array is used in place of ** the yy_shift_ofst[] array and YY_REDUCE_USE_DFLT is used in place of From 765fecf0103292e1dec8117bf4dff134cbbc58fc Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 10 Aug 2016 13:34:16 +0000 Subject: [PATCH 0684/1484] Increment the version number to 3.15. FossilOrigin-Name: 8c2701e70ab2553d7a586ff5fe7afa02d8c63199 --- VERSION | 2 +- configure | 18 +++++++++--------- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/VERSION b/VERSION index f982feb41b..f02113fe87 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.14.0 +3.15.0 diff --git a/configure b/configure index fbcf7309b1..75c7a3720d 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.14.0. +# Generated by GNU Autoconf 2.69 for sqlite 3.15.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.14.0' -PACKAGE_STRING='sqlite 3.14.0' +PACKAGE_VERSION='3.15.0' +PACKAGE_STRING='sqlite 3.15.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.14.0 to adapt to many kinds of systems. +\`configure' configures sqlite 3.15.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.14.0:";; + short | recursive ) echo "Configuration of sqlite 3.15.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.14.0 +sqlite configure 3.15.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.14.0, which was +It was created by sqlite $as_me 3.15.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.14.0, which was +This file was extended by sqlite $as_me 3.15.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.14.0 +sqlite config.status 3.15.0 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/manifest b/manifest index a0534bfabe..3a6e935e56 100644 --- a/manifest +++ b/manifest @@ -1,10 +1,10 @@ -C Improved\scomments\son\sthe\slempar.c\sparser\stemplate.\s\sAdjust\sthe\nYY_SHIFT_USE_DFLT\sconstant\sin\sthe\sLemon-generated\sparser\stables\sso\sas\nto\sguarantee\sthat\sit\sis\salways\sout\sof\srange\sof\sthe\syy_lookahead[]\stable. -D 2016-08-10T13:30:43.279 +C Increment\sthe\sversion\snumber\sto\s3.15. +D 2016-08-10T13:34:16.502 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7 -F VERSION cb29eb11e493dd85b3eeec4053c03949bf98478e +F VERSION 25e2e333adeff5965520bc8db999c658898c972d F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 @@ -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 35ce04a15ca046262bf9baaa2ced9337708cc653 x +F configure 3f44893bc0e51c30653e02b0fd4dc2ab585e446a x F configure.ac b5d3df43161374f8dffd2e5f4b88fbb51685b975 F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad F doc/lemon.html e2118945e5f07ed146b45c9cd2b2dd6eabb8ebf2 @@ -1510,7 +1510,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b07a26df06a2ffb946ff8a1cc7f43eaf701a94b5 -R f8409033fe00bbe724670b3d36a1f97d +P 83622f3f50030e4d6abafb99d99742928aaf157c +R d9d741532efbea2110f3ccf4d8076cf7 U drh -Z c9080bc44cd5d5b39b4e8d736cb94a4a +Z 14b0337226a0ad8779ef18ae936fbfbf diff --git a/manifest.uuid b/manifest.uuid index d2f3f5ca4a..14b26b5a65 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -83622f3f50030e4d6abafb99d99742928aaf157c \ No newline at end of file +8c2701e70ab2553d7a586ff5fe7afa02d8c63199 \ No newline at end of file From 167fbbe195c67fbc2b26bd75fc7c167820ff11c4 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 10 Aug 2016 14:40:00 +0000 Subject: [PATCH 0685/1484] Rearrange the code inside sqlite3RunParser() routine so that sqlite3Parser() is only called from a single place. This allows sqlite3Parser() to be in-lined, which results in a 0.25% overall performance gain. FossilOrigin-Name: 25d1d02b3ea126ade22b2a72649ae55509aa1777 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/tokenize.c | 35 +++++++++++++++++++---------------- 3 files changed, 26 insertions(+), 23 deletions(-) diff --git a/manifest b/manifest index 3a6e935e56..65d4efd170 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Increment\sthe\sversion\snumber\sto\s3.15. -D 2016-08-10T13:34:16.502 +C Rearrange\sthe\scode\sinside\ssqlite3RunParser()\sroutine\sso\sthat\ssqlite3Parser()\nis\sonly\scalled\sfrom\sa\ssingle\splace.\s\sThis\sallows\ssqlite3Parser()\sto\sbe\nin-lined,\swhich\sresults\sin\sa\s0.25%\soverall\sperformance\sgain. +D 2016-08-10T14:40:00.773 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -443,7 +443,7 @@ F src/test_windirent.c 8f5fada630348558d5745b334702f301da1ffc61 F src/test_windirent.h b12055cab6227f7be10f5c19296f67c60cc5e2a5 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c -F src/tokenize.c 3b29883b0ce4a6c6f643965b66b5ca6613178e59 +F src/tokenize.c 78c8085bc7af1922aa687f0f4bbd716821330de5 F src/treeview.c c56d6ddbed564efda746236b35bcbb8238daac4b F src/trigger.c e14840ee0c3e549e758ec9bf3e4146e166002280 F src/update.c 4f05ea8cddfa367d045e03589756c02199e8f9bd @@ -1510,7 +1510,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 83622f3f50030e4d6abafb99d99742928aaf157c -R d9d741532efbea2110f3ccf4d8076cf7 +P 8c2701e70ab2553d7a586ff5fe7afa02d8c63199 +R d55f09ced5a54b7cb7985c5709f82b8d U drh -Z 14b0337226a0ad8779ef18ae936fbfbf +Z f780132273cb4e2f41bbf55d6f67764f diff --git a/manifest.uuid b/manifest.uuid index 14b26b5a65..806e1635fa 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8c2701e70ab2553d7a586ff5fe7afa02d8c63199 \ No newline at end of file +25d1d02b3ea126ade22b2a72649ae55509aa1777 \ No newline at end of file diff --git a/src/tokenize.c b/src/tokenize.c index 62e770b79c..9230da2a0f 100644 --- a/src/tokenize.c +++ b/src/tokenize.c @@ -502,14 +502,26 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){ assert( pParse->nVar==0 ); assert( pParse->nzVar==0 ); assert( pParse->azVar==0 ); - while( zSql[i]!=0 ){ + while( 1 ){ assert( i>=0 ); - pParse->sLastToken.z = &zSql[i]; - pParse->sLastToken.n = sqlite3GetToken((unsigned char*)&zSql[i],&tokenType); - i += pParse->sLastToken.n; - if( i>mxSqlLen ){ - pParse->rc = SQLITE_TOOBIG; - break; + if( zSql[i]!=0 ){ + pParse->sLastToken.z = &zSql[i]; + pParse->sLastToken.n = sqlite3GetToken((u8*)&zSql[i],&tokenType); + i += pParse->sLastToken.n; + if( i>mxSqlLen ){ + pParse->rc = SQLITE_TOOBIG; + break; + } + }else{ + /* Upon reaching the end of input, call the parser two more times + ** with tokens TK_SEMI and 0, in that order. */ + if( lastTokenParsed==TK_SEMI ){ + tokenType = 0; + }else if( lastTokenParsed==0 ){ + break; + }else{ + tokenType = TK_SEMI; + } } if( tokenType>=TK_SPACE ){ assert( tokenType==TK_SPACE || tokenType==TK_ILLEGAL ); @@ -530,15 +542,6 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){ } assert( nErr==0 ); pParse->zTail = &zSql[i]; - if( pParse->rc==SQLITE_OK && db->mallocFailed==0 ){ - assert( zSql[i]==0 ); - if( lastTokenParsed!=TK_SEMI ){ - sqlite3Parser(pEngine, TK_SEMI, pParse->sLastToken, pParse); - } - if( pParse->rc==SQLITE_OK && db->mallocFailed==0 ){ - sqlite3Parser(pEngine, 0, pParse->sLastToken, pParse); - } - } #ifdef YYTRACKMAXSTACKDEPTH sqlite3_mutex_enter(sqlite3MallocMutex()); sqlite3StatusHighwater(SQLITE_STATUS_PARSER_STACK, From f5dbe7f8d8486f79f0ee1be6ff16176d14156ac4 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 10 Aug 2016 15:02:49 +0000 Subject: [PATCH 0686/1484] Tweaks to pcache1TruncateUnsafe() to make it slightly smaller and faster and easier to test. FossilOrigin-Name: 059f4e2efefb7b9deaf539110c19bceaeb10c6ce --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/pcache1.c | 12 ++++++------ 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 65d4efd170..40aa0f764a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Rearrange\sthe\scode\sinside\ssqlite3RunParser()\sroutine\sso\sthat\ssqlite3Parser()\nis\sonly\scalled\sfrom\sa\ssingle\splace.\s\sThis\sallows\ssqlite3Parser()\sto\sbe\nin-lined,\swhich\sresults\sin\sa\s0.25%\soverall\sperformance\sgain. -D 2016-08-10T14:40:00.773 +C Tweaks\sto\spcache1TruncateUnsafe()\sto\smake\sit\sslightly\ssmaller\sand\sfaster\sand\neasier\sto\stest. +D 2016-08-10T15:02:49.189 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -376,7 +376,7 @@ F src/pager.h 966d2769e76ae347c8a32c4165faf6e6cb64546d F src/parse.y 99b676e6fc2f4e331ab93e76b3987cffdbd28efa F src/pcache.c 5583c8ade4b05075a60ba953ef471d1c1a9c05df F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 -F src/pcache1.c dc8a6052e5136d6b5e6afe51f37485145646f5ab +F src/pcache1.c 4bb7a6a5300c67d0b033d25adb509c120c03e812 F src/pragma.c c8b499756658cb8b82cfdbb5845c22cf11f297aa F src/pragma.h 64c78a648751b9f4f297276c4eb7507b14b4628c F src/prepare.c 22df6171aec1d86904ed2ad30c2348a5748aa04e @@ -1510,7 +1510,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 8c2701e70ab2553d7a586ff5fe7afa02d8c63199 -R d55f09ced5a54b7cb7985c5709f82b8d +P 25d1d02b3ea126ade22b2a72649ae55509aa1777 +R 828a3811914080064b74ae479ed3b60e U drh -Z f780132273cb4e2f41bbf55d6f67764f +Z 4a1a54abd34521e8d97a121a8de840a3 diff --git a/manifest.uuid b/manifest.uuid index 806e1635fa..3afecdeb57 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -25d1d02b3ea126ade22b2a72649ae55509aa1777 \ No newline at end of file +059f4e2efefb7b9deaf539110c19bceaeb10c6ce \ No newline at end of file diff --git a/src/pcache1.c b/src/pcache1.c index 1af1ef5bb7..1b1971a399 100644 --- a/src/pcache1.c +++ b/src/pcache1.c @@ -637,19 +637,19 @@ static void pcache1TruncateUnsafe( assert( sqlite3_mutex_held(pCache->pGroup->mutex) ); assert( pCache->iMaxKey >= iLimit ); assert( pCache->nHash > 0 ); - if( pCache->iMaxKey - iLimit < pCache->nHash/2 ){ + if( pCache->iMaxKey - iLimit < pCache->nHash ){ /* If we are just shaving the last few pages off the end of the ** cache, then there is no point in scanning the entire hash table. ** Only scan those hash slots that might contain pages that need to ** be removed. */ - iStop = iLimit % pCache->nHash; - h = pCache->iMaxKey % pCache->nHash; + h = iLimit % pCache->nHash; + iStop = pCache->iMaxKey % pCache->nHash; TESTONLY( nPage = -10; ) /* Disable the pCache->nPage validity check */ }else{ /* This is the general case where many pages are being removed. ** It is necessary to scan the entire hash table */ - iStop = 0; - h = pCache->nHash - 1; + h = pCache->nHash/2; + iStop = h - 1; } for(;;){ PgHdr1 **pp; @@ -668,7 +668,7 @@ static void pcache1TruncateUnsafe( } } if( h==iStop ) break; - h = h ? h-1 : pCache->nHash - 1; + h = (h+1) % pCache->nHash; } assert( nPage<0 || pCache->nPage==(unsigned)nPage ); } From 922802c44e912e9d854408afa9f7e48f8ff1208a Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 10 Aug 2016 18:56:32 +0000 Subject: [PATCH 0687/1484] Performance enhancement in the expression walker. FossilOrigin-Name: ebccbd96094ac64de39dbd0d220d3a7afd8cd40e --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/walker.c | 18 ++++++++---------- 3 files changed, 15 insertions(+), 17 deletions(-) diff --git a/manifest b/manifest index 40aa0f764a..5d7ed0ac68 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Tweaks\sto\spcache1TruncateUnsafe()\sto\smake\sit\sslightly\ssmaller\sand\sfaster\sand\neasier\sto\stest. -D 2016-08-10T15:02:49.189 +C Performance\senhancement\sin\sthe\sexpression\swalker. +D 2016-08-10T18:56:32.070 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -463,7 +463,7 @@ F src/vtab.c 6b3cfaff7e4397739d6b48511e777ca58c6d06d4 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 02eeecc265f6ffd0597378f5d8ae9070b62a406a F src/wal.h 6dd221ed384afdc204bc61e25c23ef7fd5a511f2 -F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354 +F src/walker.c 2d2cc7fb0f320f7f415215d7247f3c584141ac09 F src/where.c 5c9df42d50888be8274a5a0eb062eb0629869bd3 F src/whereInt.h e5b939701a7ceffc5a3a8188a37f9746416ebcd0 F src/wherecode.c 99707d11907c71d289ee9553d2d1a22f1fd8ba41 @@ -1510,7 +1510,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 25d1d02b3ea126ade22b2a72649ae55509aa1777 -R 828a3811914080064b74ae479ed3b60e +P 059f4e2efefb7b9deaf539110c19bceaeb10c6ce +R e10ecf5680d55c2be7b6807b82221bef U drh -Z 4a1a54abd34521e8d97a121a8de840a3 +Z 07228f4a19a0e884d96dc70fff71df0f diff --git a/manifest.uuid b/manifest.uuid index 3afecdeb57..821d79b57b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -059f4e2efefb7b9deaf539110c19bceaeb10c6ce \ No newline at end of file +ebccbd96094ac64de39dbd0d220d3a7afd8cd40e \ No newline at end of file diff --git a/src/walker.c b/src/walker.c index 1e0ad32871..82aae67a61 100644 --- a/src/walker.c +++ b/src/walker.c @@ -41,17 +41,15 @@ static SQLITE_NOINLINE int walkExpr(Walker *pWalker, Expr *pExpr){ testcase( ExprHasProperty(pExpr, EP_TokenOnly) ); testcase( ExprHasProperty(pExpr, EP_Reduced) ); rc = pWalker->xExprCallback(pWalker, pExpr); - if( rc==WRC_Continue - && !ExprHasProperty(pExpr,EP_TokenOnly) ){ - if( sqlite3WalkExpr(pWalker, pExpr->pLeft) ) return WRC_Abort; - if( sqlite3WalkExpr(pWalker, pExpr->pRight) ) return WRC_Abort; - if( ExprHasProperty(pExpr, EP_xIsSelect) ){ - if( sqlite3WalkSelect(pWalker, pExpr->x.pSelect) ) return WRC_Abort; - }else{ - if( sqlite3WalkExprList(pWalker, pExpr->x.pList) ) return WRC_Abort; - } + if( rc || ExprHasProperty(pExpr,EP_TokenOnly) ) return rc & WRC_Abort; + if( pExpr->pLeft && walkExpr(pWalker, pExpr->pLeft) ) return WRC_Abort; + if( pExpr->pRight && walkExpr(pWalker, pExpr->pRight) ) return WRC_Abort; + if( ExprHasProperty(pExpr, EP_xIsSelect) ){ + if( sqlite3WalkSelect(pWalker, pExpr->x.pSelect) ) return WRC_Abort; + }else{ + if( sqlite3WalkExprList(pWalker, pExpr->x.pList) ) return WRC_Abort; } - return rc & WRC_Abort; + return WRC_Continue; } int sqlite3WalkExpr(Walker *pWalker, Expr *pExpr){ return pExpr ? walkExpr(pWalker,pExpr) : WRC_Continue; From e104dd3cc301c0fe79e59502b13a953f6369c6dc Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 10 Aug 2016 19:43:29 +0000 Subject: [PATCH 0688/1484] List of MATCH operator names in isMatchOfColumn() should be constant. FossilOrigin-Name: 7319d676aaf95ba7391379f4cdf193b6aa898893 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/whereexpr.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 5d7ed0ac68..d87a893d49 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Performance\senhancement\sin\sthe\sexpression\swalker. -D 2016-08-10T18:56:32.070 +C List\sof\sMATCH\soperator\snames\sin\sisMatchOfColumn()\sshould\sbe\sconstant. +D 2016-08-10T19:43:29.424 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -467,7 +467,7 @@ F src/walker.c 2d2cc7fb0f320f7f415215d7247f3c584141ac09 F src/where.c 5c9df42d50888be8274a5a0eb062eb0629869bd3 F src/whereInt.h e5b939701a7ceffc5a3a8188a37f9746416ebcd0 F src/wherecode.c 99707d11907c71d289ee9553d2d1a22f1fd8ba41 -F src/whereexpr.c d7dcbf14ce1b5876c1f76496162c30fcba669563 +F src/whereexpr.c 600e6c619d69f5455dd99c69fec8c42ac44e5c9d F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1510,7 +1510,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 059f4e2efefb7b9deaf539110c19bceaeb10c6ce -R e10ecf5680d55c2be7b6807b82221bef +P ebccbd96094ac64de39dbd0d220d3a7afd8cd40e +R fac33bc7c9b64529fad9a6567bc0fbba U drh -Z 07228f4a19a0e884d96dc70fff71df0f +Z d9cf90e53680d487c9bbc0ab8247d4aa diff --git a/manifest.uuid b/manifest.uuid index 821d79b57b..1286c1b8bf 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ebccbd96094ac64de39dbd0d220d3a7afd8cd40e \ No newline at end of file +7319d676aaf95ba7391379f4cdf193b6aa898893 \ No newline at end of file diff --git a/src/whereexpr.c b/src/whereexpr.c index 1cb6be8458..2461d1ddf8 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -290,7 +290,7 @@ static int isMatchOfColumn( Expr *pExpr, /* Test this expression */ unsigned char *peOp2 /* OUT: 0 for MATCH, or else an op2 value */ ){ - struct Op2 { + static const struct Op2 { const char *zOp; unsigned char eOp2; } aOp[] = { From 93ca3933d17bca3cd5dbad1731d722c6d0108bf0 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 10 Aug 2016 20:02:21 +0000 Subject: [PATCH 0689/1484] Optimization to sqlite3WhereExprUsage(). FossilOrigin-Name: 95493058fcf40306727a281f21c5a2a0011b7d02 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/whereexpr.c | 5 +++-- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index d87a893d49..842f885dfd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C List\sof\sMATCH\soperator\snames\sin\sisMatchOfColumn()\sshould\sbe\sconstant. -D 2016-08-10T19:43:29.424 +C Optimization\sto\ssqlite3WhereExprUsage(). +D 2016-08-10T20:02:21.519 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -467,7 +467,7 @@ F src/walker.c 2d2cc7fb0f320f7f415215d7247f3c584141ac09 F src/where.c 5c9df42d50888be8274a5a0eb062eb0629869bd3 F src/whereInt.h e5b939701a7ceffc5a3a8188a37f9746416ebcd0 F src/wherecode.c 99707d11907c71d289ee9553d2d1a22f1fd8ba41 -F src/whereexpr.c 600e6c619d69f5455dd99c69fec8c42ac44e5c9d +F src/whereexpr.c 98ce9f3b8d92b6f741b9f3498f9619695739256e F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1510,7 +1510,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ebccbd96094ac64de39dbd0d220d3a7afd8cd40e -R fac33bc7c9b64529fad9a6567bc0fbba +P 7319d676aaf95ba7391379f4cdf193b6aa898893 +R 35b146f4e31088e5d413861ddde93f74 U drh -Z d9cf90e53680d487c9bbc0ab8247d4aa +Z 2c745f38c120984510a4f6c92123cc21 diff --git a/manifest.uuid b/manifest.uuid index 1286c1b8bf..99c25a4923 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7319d676aaf95ba7391379f4cdf193b6aa898893 \ No newline at end of file +95493058fcf40306727a281f21c5a2a0011b7d02 \ No newline at end of file diff --git a/src/whereexpr.c b/src/whereexpr.c index 2461d1ddf8..2768428e2d 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -1275,13 +1275,14 @@ void sqlite3WhereClauseClear(WhereClause *pWC){ ** tree. */ Bitmask sqlite3WhereExprUsage(WhereMaskSet *pMaskSet, Expr *p){ - Bitmask mask = 0; + Bitmask mask; if( p==0 ) return 0; if( p->op==TK_COLUMN ){ mask = sqlite3WhereGetMask(pMaskSet, p->iTable); return mask; } - mask = sqlite3WhereExprUsage(pMaskSet, p->pRight); + assert( !ExprHasProperty(p, EP_TokenOnly) ); + mask = p->pRight ? sqlite3WhereExprUsage(pMaskSet, p->pRight) : 0; if( p->pLeft ) mask |= sqlite3WhereExprUsage(pMaskSet, p->pLeft); if( ExprHasProperty(p, EP_xIsSelect) ){ mask |= exprSelectUsage(pMaskSet, p->x.pSelect); From c73bd0a5ccba807c7f18673063326f9929702473 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 11 Aug 2016 01:24:56 +0000 Subject: [PATCH 0690/1484] Fix a harmless compiler warning in FTS5. FossilOrigin-Name: 2ea0c8b46eefd4874f021f8dfd344be751f2034f --- ext/fts5/fts5_index.c | 1 + manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index 52fdc634a5..65b92a2b99 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -3200,6 +3200,7 @@ static void fts5IterSetOutputs_Nocolset(Fts5Iter *pIter, Fts5SegIter *pSeg){ ** against no columns at all). */ static void fts5IterSetOutputs_ZeroColset(Fts5Iter *pIter, Fts5SegIter *pSeg){ + UNUSED_PARAM(pSeg); pIter->base.nData = 0; } diff --git a/manifest b/manifest index 842f885dfd..4c405c8749 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Optimization\sto\ssqlite3WhereExprUsage(). -D 2016-08-10T20:02:21.519 +C Fix\sa\sharmless\scompiler\swarning\sin\sFTS5. +D 2016-08-11T01:24:56.314 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -104,7 +104,7 @@ F ext/fts5/fts5_buffer.c 4c1502d4c956cd092c89ce4480867f9d8bf325cd F ext/fts5/fts5_config.c 5af9c360e99669d29f06492c370892394aba0857 F ext/fts5/fts5_expr.c df0004b5bffcbe34c329f2992669c6352443f415 F ext/fts5/fts5_hash.c 880998e596b60f078348d48732ca4ad9a90caad2 -F ext/fts5/fts5_index.c e25ac419fc66f412e6044595b20b4bf8f7cea284 +F ext/fts5/fts5_index.c 05386732609221d066d204b22c4a5275a0225ed4 F ext/fts5/fts5_main.c f85281445dcf8be32d18841c93a6f90fe27dbfe2 F ext/fts5/fts5_storage.c de0ed8a06738bde433afe11e92295ceaffbc4e58 F ext/fts5/fts5_tcl.c 4a901f00c8553740dba63511603f5527d741c26a @@ -1510,7 +1510,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 7319d676aaf95ba7391379f4cdf193b6aa898893 -R 35b146f4e31088e5d413861ddde93f74 +P 95493058fcf40306727a281f21c5a2a0011b7d02 +R 62963055338ff8dad6eebc29c29c9140 U drh -Z 2c745f38c120984510a4f6c92123cc21 +Z e11e1549fddd90a07d1f00ccb39e8b50 diff --git a/manifest.uuid b/manifest.uuid index 99c25a4923..88d3f117ad 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -95493058fcf40306727a281f21c5a2a0011b7d02 \ No newline at end of file +2ea0c8b46eefd4874f021f8dfd344be751f2034f \ No newline at end of file From 6ff4627d5ddbaa2fc96945f2a1e042313de1097a Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 11 Aug 2016 09:55:55 +0000 Subject: [PATCH 0691/1484] Fix a 1 byte buffer overwrite in the "sqldiff --rbu" command. FossilOrigin-Name: ab83d7077da80ddbcf399d0797d79e964dc64f0e --- manifest | 14 +++++++------- manifest.uuid | 2 +- tool/sqldiff.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 4c405c8749..7c618d61d7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sharmless\scompiler\swarning\sin\sFTS5. -D 2016-08-11T01:24:56.314 +C Fix\sa\s1\sbyte\sbuffer\soverwrite\sin\sthe\s"sqldiff\s--rbu"\scommand. +D 2016-08-11T09:55:55.485 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -1477,7 +1477,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 7ce07da76b5e745783e703a834417d725b7d45fd F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c -F tool/sqldiff.c 4478f0d30230de6adde90bdb0bfe60f68c5ab782 +F tool/sqldiff.c c965d49bf2677db06103854b47e105484b5b1b84 F tool/srcck1.c 371de5363b70154012955544f86fdee8f6e5326f F tool/stack_usage.tcl f8e71b92cdb099a147dad572375595eae55eca43 F tool/symbols-mingw.sh 4dbcea7e74768305384c9fd2ed2b41bbf9f0414d @@ -1510,7 +1510,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 95493058fcf40306727a281f21c5a2a0011b7d02 -R 62963055338ff8dad6eebc29c29c9140 -U drh -Z e11e1549fddd90a07d1f00ccb39e8b50 +P 2ea0c8b46eefd4874f021f8dfd344be751f2034f +R 26e854b22e510a9651c111418b0d5f03 +U dan +Z 78ea492cf13c3fac64589b27f22aa44b diff --git a/manifest.uuid b/manifest.uuid index 88d3f117ad..22f2d26d97 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2ea0c8b46eefd4874f021f8dfd344be751f2034f \ No newline at end of file +ab83d7077da80ddbcf399d0797d79e964dc64f0e \ No newline at end of file diff --git a/tool/sqldiff.c b/tool/sqldiff.c index e92e8aab25..b1363bb341 100644 --- a/tool/sqldiff.c +++ b/tool/sqldiff.c @@ -1302,7 +1302,7 @@ static void rbudiff_one_table(const char *zTab, FILE *out){ char *zOtaControl; int nOtaControl = sqlite3_column_bytes(pStmt, nCol); - zOtaControl = (char*)sqlite3_malloc(nOtaControl); + zOtaControl = (char*)sqlite3_malloc(nOtaControl+1); memcpy(zOtaControl, sqlite3_column_text(pStmt, nCol), nOtaControl+1); for(i=0; i Date: Thu, 11 Aug 2016 12:01:52 +0000 Subject: [PATCH 0692/1484] Fix some problems with handling "no such collation sequence" errors. FossilOrigin-Name: 8278be06fa69e3266866220bdaf5be45a5fcfa23 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/expr.c | 3 +++ src/where.c | 2 +- test/rowvalue4.test | 18 ++++++++++++++++++ 5 files changed, 31 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index db8399f339..96a9786372 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\srowvalue5.test,\swhich\sshould\shave\sbeen\spart\sof\sthe\sprevious\scommit\son\sthis\sbranch. -D 2016-08-09T05:48:40.637 +C Fix\ssome\sproblems\swith\shandling\s"no\ssuch\scollation\ssequence"\serrors. +D 2016-08-11T12:01:52.255 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -337,7 +337,7 @@ F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7 F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b F src/dbstat.c 4f6f7f52b49beb9636ffbd517cfe44a402ba4ad0 F src/delete.c 4aba4214a377ce8ddde2d2e609777bcc8235200f -F src/expr.c 94b3d94696e86840f2d0d038c638eefde57c2a40 +F src/expr.c dfc2275726e0a4916f10fe6b5b4f45fff835e790 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c bc4145347595b7770f9a598cff1c848302cf5413 F src/func.c 29cc9acb170ec1387b9f63eb52cd85f8de96c771 @@ -463,7 +463,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 02eeecc265f6ffd0597378f5d8ae9070b62a406a F src/wal.h 6dd221ed384afdc204bc61e25c23ef7fd5a511f2 F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354 -F src/where.c 457a2c8cd94a1dbe8d2e5113f6078f2e6b9067d5 +F src/where.c 5bee250c8233c43bd7f53897d12b8468004f63db F src/whereInt.h 14dd243e13b81cbb0a66063d38b70f93a7d6e613 F src/wherecode.c 92202261a6e41f897a595417c5b0c75c8acf713d F src/whereexpr.c 4a8cefc7c122132ac9f3ed125c61629a0e3de094 @@ -1021,7 +1021,7 @@ F test/rowid.test 5b7509f384f4f6fae1af3c8c104c8ca299fea18d F test/rowvalue.test 56b34d31d91340a6e922e753b798880170cc1aa7 F test/rowvalue2.test 8d5dfe75b8f4d1868a2f91f0356f20d36cba64ff F test/rowvalue3.test dbe935260851b197dfbbbcb0ac2a15cb5f324fd4 -F test/rowvalue4.test 8d3b26c7ab26314b625cd2b113d782b011b91851 +F test/rowvalue4.test ed3f7974099f0fc508c9f95df55d37c49f43be65 F test/rowvalue5.test 01c7e0bc4048f30b58e6eb27ecd26e5bd312635e F test/rowvaluefault.test 7b16485e3f2b371f3e3d05455b8ded6d0c090244 F test/rtree.test 0c8d9dd458d6824e59683c19ab2ffa9ef946f798 @@ -1515,7 +1515,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 156a41f30a0afd9a70e6c26470dcc468a11bd402 -R c38c81cb8ebb8c1f60f796251d669e34 +P ea03e219ced87777f0c3c6bbb0274078dbb829e2 +R 3327e29017db82c17326a5b9067bf8a5 U dan -Z f2cc02b61092cf3b9735f66f5f90cbf0 +Z 2191ed49fb7f045b414ebf34ab584005 diff --git a/manifest.uuid b/manifest.uuid index 293e4dd8a1..b4dbc8b833 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ea03e219ced87777f0c3c6bbb0274078dbb829e2 \ No newline at end of file +8278be06fa69e3266866220bdaf5be45a5fcfa23 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index a0e4e5cb18..8303c5f784 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2056,6 +2056,9 @@ int sqlite3FindInIndex( CollSeq *pReq = sqlite3BinaryCompareCollSeq(pParse, pLhs, pRhs); int j; + assert( pReq || pParse->nErr ); + if( pReq==0 ) break; + for(j=0; jaiColumn[j]!=pRhs->iColumn ) continue; assert( pIdx->azColl[j] ); diff --git a/src/where.c b/src/where.c index 9faec64bc1..f084b93701 100644 --- a/src/where.c +++ b/src/where.c @@ -2256,7 +2256,7 @@ int whereRangeVectorLen( if( aff!=idxaff ) break; pColl = sqlite3BinaryCompareCollSeq(pParse, pLhs, pRhs); - if( sqlite3StrICmp(pColl->zName, pIdx->azColl[i+nEq]) ) break; + if( pColl==0 || sqlite3StrICmp(pColl->zName, pIdx->azColl[i+nEq]) ) break; } return i; } diff --git a/test/rowvalue4.test b/test/rowvalue4.test index 5530f8f5ca..55401aa8a3 100644 --- a/test/rowvalue4.test +++ b/test/rowvalue4.test @@ -273,6 +273,24 @@ do_eqp_test 6.5 { {SEARCH TABLE e1 USING INDEX e1cde (c=? AND (d,e)>(?,?) AND (d,e)<(?,?))} } +#------------------------------------------------------------------------- + +do_execsql_test 7.1 { + CREATE TABLE f1(a, b, c); + CREATE INDEX f1ab ON f1(a, b); +} + +do_catchsql_test 7.2 { + SELECT (a COLLATE nocase, b) IN (SELECT a, b FROM f1) FROM f1; +} {0 {}} + +do_catchsql_test 7.3 { + SELECT (a COLLATE nose, b) IN (SELECT a, b FROM f1) FROM f1; +} {1 {no such collation sequence: nose}} + +do_catchsql_test 7.4 { + SELECT * FROM f1 WHERE (?, ? COLLATE nose) > (a, b); +} {1 {no such collation sequence: nose}} finish_test From 1bf4ca7c42ed8fdd484221a6d42c626cc9f361ef Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 11 Aug 2016 18:05:47 +0000 Subject: [PATCH 0693/1484] Add the "modeof=" URI parameter to os_unix.c - used to specify a file to copy permissions from when a new database is created. Also allow passing NULL as the second parameter to sqlite3rbu_vacuum(). FossilOrigin-Name: ed406d31ff54ee3de8db91690a966e5c561f8f94 --- ext/rbu/rbuprogress.test | 2 ++ ext/rbu/rbuvacuum2.test | 42 ++++++++++++++++++++++++++++++++++++++++ ext/rbu/sqlite3rbu.c | 32 +++++++++++++++++++++++------- ext/rbu/sqlite3rbu.h | 16 ++++++++++----- ext/rbu/test_rbu.c | 6 +++--- manifest | 22 ++++++++++----------- manifest.uuid | 2 +- src/os_unix.c | 39 +++++++++++++++++++++++++++++-------- 8 files changed, 126 insertions(+), 35 deletions(-) diff --git a/ext/rbu/rbuprogress.test b/ext/rbu/rbuprogress.test index 6afbffe8ed..af202829c1 100644 --- a/ext/rbu/rbuprogress.test +++ b/ext/rbu/rbuprogress.test @@ -361,6 +361,8 @@ foreach {bReopen} { 0 1 } { } } { + if {$tn=="vtab"} { ifcapable !fts5 break } + foreach {tn2 rbusql r1 r2} { 1 { CREATE TABLE data0_t1(a, b, c, rbu_rowid, rbu_control); diff --git a/ext/rbu/rbuvacuum2.test b/ext/rbu/rbuvacuum2.test index 6397751836..bd38660320 100644 --- a/ext/rbu/rbuvacuum2.test +++ b/ext/rbu/rbuvacuum2.test @@ -156,7 +156,49 @@ foreach step {0 1} { trigger tr1 t1 0 {CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN SELECT 1; END} } } +} + +#------------------------------------------------------------------------- +# Test that passing a NULL value as the second argument to +# sqlite3rbu_vacuum() causes it to: +# +# * Use -vacuum as the state db, and +# * Set the state db permissions to the same as those on the db file. +# +db close +if {$::tcl_platform(platform)=="unix"} { + forcedelete test.db + sqlite3 db test.db + do_execsql_test 5.0 { + CREATE TABLE t1(a, b); + INSERT INTO t1 VALUES(1, 2); + INSERT INTO t1 VALUES(3, 4); + INSERT INTO t1 VALUES(5, 6); + INSERT INTO t1 VALUES(7, 8); + } + db close + + foreach {tn perm} { + 1 00755 + 2 00666 + 3 00644 + 4 00444 + } { + forcedelete test.db-vacuum + + do_test 5.$tn.1 { + file attributes test.db -permissions $perm + sqlite3rbu_vacuum rbu test.db + rbu step + } {SQLITE_OK} + + do_test 5.$tn.2 { file exists test.db-vacuum } 1 + do_test 5.$tn.3 { file attributes test.db-vacuum -permissions} $perm + rbu close + } } + finish_test + diff --git a/ext/rbu/sqlite3rbu.c b/ext/rbu/sqlite3rbu.c index 73c6647a2c..746469a8af 100644 --- a/ext/rbu/sqlite3rbu.c +++ b/ext/rbu/sqlite3rbu.c @@ -2334,15 +2334,18 @@ static RbuState *rbuLoadState(sqlite3rbu *p){ ** error occurs, leave an error code and message in the RBU handle. */ static void rbuOpenDatabase(sqlite3rbu *p){ - assert( p->rc==SQLITE_OK ); - assert( p->dbMain==0 && p->dbRbu==0 ); - assert( rbuIsVacuum(p) || p->zTarget!=0 ); + assert( p->rc || (p->dbMain==0 && p->dbRbu==0) ); + assert( p->rc || rbuIsVacuum(p) || p->zTarget!=0 ); /* Open the RBU database */ p->dbRbu = rbuOpenDbhandle(p, p->zRbu, 1); if( p->rc==SQLITE_OK && rbuIsVacuum(p) ){ sqlite3_file_control(p->dbRbu, "main", SQLITE_FCNTL_RBUCNT, (void*)p); + if( p->zState==0 ){ + const char *zFile = sqlite3_db_filename(p->dbRbu, "main"); + p->zState = rbuMPrintf(p, "file://%s-vacuum?modeof=%s", zFile, zFile); + } } /* If using separate RBU and state databases, attach the state database to @@ -3477,8 +3480,7 @@ static sqlite3rbu *openRbuHandle( sqlite3rbu *p; size_t nTarget = zTarget ? strlen(zTarget) : 0; size_t nRbu = strlen(zRbu); - size_t nState = zState ? strlen(zState) : 0; - size_t nByte = sizeof(sqlite3rbu) + nTarget+1 + nRbu+1+ nState+1; + size_t nByte = sizeof(sqlite3rbu) + nTarget+1 + nRbu+1; p = (sqlite3rbu*)sqlite3_malloc64(nByte); if( p ){ @@ -3500,8 +3502,7 @@ static sqlite3rbu *openRbuHandle( memcpy(p->zRbu, zRbu, nRbu+1); pCsr += nRbu+1; if( zState ){ - p->zState = pCsr; - memcpy(p->zState, zState, nState+1); + p->zState = rbuMPrintf(p, "%s", zState); } rbuOpenDatabase(p); } @@ -3611,6 +3612,20 @@ static sqlite3rbu *openRbuHandle( return p; } +/* +** Allocate and return an RBU handle with all fields zeroed except for the +** error code, which is set to SQLITE_MISUSE. +*/ +static sqlite3rbu *rbuMisuseError(void){ + sqlite3rbu *pRet; + pRet = sqlite3_malloc64(sizeof(sqlite3rbu)); + if( pRet ){ + memset(pRet, 0, sizeof(sqlite3rbu)); + pRet->rc = SQLITE_MISUSE; + } + return pRet; +} + /* ** Open and return a new RBU handle. */ @@ -3619,6 +3634,7 @@ sqlite3rbu *sqlite3rbu_open( const char *zRbu, const char *zState ){ + if( zTarget==0 || zRbu==0 ){ return rbuMisuseError(); } /* TODO: Check that zTarget and zRbu are non-NULL */ return openRbuHandle(zTarget, zRbu, zState); } @@ -3630,6 +3646,7 @@ sqlite3rbu *sqlite3rbu_vacuum( const char *zTarget, const char *zState ){ + if( zTarget==0 ){ return rbuMisuseError(); } /* TODO: Check that both arguments are non-NULL */ return openRbuHandle(0, zTarget, zState); } @@ -3707,6 +3724,7 @@ int sqlite3rbu_close(sqlite3rbu *p, char **pzErrmsg){ rbuEditErrmsg(p); rc = p->rc; *pzErrmsg = p->zErrmsg; + sqlite3_free(p->zState); sqlite3_free(p); }else{ rc = SQLITE_NOMEM; diff --git a/ext/rbu/sqlite3rbu.h b/ext/rbu/sqlite3rbu.h index 9ce39f543c..3f5f29a8e6 100644 --- a/ext/rbu/sqlite3rbu.h +++ b/ext/rbu/sqlite3rbu.h @@ -319,16 +319,22 @@ sqlite3rbu *sqlite3rbu_open( ** An RBU vacuum is similar to SQLite's built-in VACUUM command, except ** that it can be suspended and resumed like an RBU update. ** -** The second argument to this function, which may not be NULL, identifies -** a database in which to store the state of the RBU vacuum operation if -** it is suspended. The first time sqlite3rbu_vacuum() is called, to start -** an RBU vacuum operation, the state database should either not exist or -** be empty (contain no tables). If an RBU vacuum is suspended by calling +** The second argument to this function identifies a database in which +** to store the state of the RBU vacuum operation if it is suspended. The +** first time sqlite3rbu_vacuum() is called, to start an RBU vacuum +** operation, the state database should either not exist or be empty +** (contain no tables). If an RBU vacuum is suspended by calling ** sqlite3rbu_close() on the RBU handle before sqlite3rbu_step() has ** returned SQLITE_DONE, the vacuum state is stored in the state database. ** The vacuum can be resumed by calling this function to open a new RBU ** handle specifying the same target and state databases. ** +** If the second argument passed to this function is NULL, then the +** name of the state database is "-vacuum", where +** is the name of the target database file. In this case, on UNIX, if the +** state database is not already present in the file-system, it is created +** with the same permissions as the target db is made. +** ** This function does not delete the state database after an RBU vacuum ** is completed, even if it created it. However, if the call to ** sqlite3rbu_close() returns any value other than SQLITE_OK, the contents diff --git a/ext/rbu/test_rbu.c b/ext/rbu/test_rbu.c index bc4c800331..b1a2252741 100644 --- a/ext/rbu/test_rbu.c +++ b/ext/rbu/test_rbu.c @@ -240,13 +240,13 @@ static int SQLITE_TCLAPI test_sqlite3rbu_vacuum( const char *zTarget; const char *zStateDb = 0; - if( objc!=4 ){ - Tcl_WrongNumArgs(interp, 1, objv, "NAME TARGET-DB STATE-DB"); + if( objc!=3 && objc!=4 ){ + Tcl_WrongNumArgs(interp, 1, objv, "NAME TARGET-DB ?STATE-DB?"); return TCL_ERROR; } zCmd = Tcl_GetString(objv[1]); zTarget = Tcl_GetString(objv[2]); - zStateDb = Tcl_GetString(objv[3]); + if( objc==4 ) zStateDb = Tcl_GetString(objv[3]); pRbu = sqlite3rbu_vacuum(zTarget, zStateDb); Tcl_CreateObjCommand(interp, zCmd, test_sqlite3rbu_cmd, (ClientData)pRbu, 0); diff --git a/manifest b/manifest index 7c618d61d7..3d5a0dd058 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\s1\sbyte\sbuffer\soverwrite\sin\sthe\s"sqldiff\s--rbu"\scommand. -D 2016-08-11T09:55:55.485 +C Add\sthe\s"modeof="\sURI\sparameter\sto\sos_unix.c\s-\sused\sto\sspecify\sa\sfile\sto\scopy\spermissions\sfrom\swhen\sa\snew\sdatabase\sis\screated.\sAlso\sallow\spassing\sNULL\sas\sthe\ssecond\sparameter\sto\ssqlite3rbu_vacuum(). +D 2016-08-11T18:05:47.763 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -250,13 +250,13 @@ F ext/rbu/rbufault.test cc0be8d5d392d98b0c2d6a51be377ea989250a89 F ext/rbu/rbufault2.test 9a7f19edd6ea35c4c9f807d8a3db0a03a5670c06 F ext/rbu/rbufault3.test 54a399888ac4af44c68f9f58afbed23149428bca F ext/rbu/rbufts.test 828cd689da825f0a7b7c53ffc1f6f7fdb6fa5bda -F ext/rbu/rbuprogress.test 2023a7df2c523e3df1cb532eff811cda385a789a +F ext/rbu/rbuprogress.test e3e25fb7622641b8f2df7c6b7a7eb6fddfc46a4b F ext/rbu/rbusave.test 0f43b6686084f426ddd040b878426452fd2c2f48 F ext/rbu/rbuvacuum.test 4a977447c15c2581ab668781d9ef4294382530e0 -F ext/rbu/rbuvacuum2.test 45009e127c3fb385e5c0fd5a8a63fb922a79d0ab -F ext/rbu/sqlite3rbu.c 948677ee0ec57da51148e6c5f64ac68afcf36ab2 -F ext/rbu/sqlite3rbu.h db8858120c9be14b60c9225f9da28221f5f6b945 -F ext/rbu/test_rbu.c 1a6bbc6982e32485a48df111d0bb1934d537eabd +F ext/rbu/rbuvacuum2.test 2569205b74ff40fbf3bda2fce33a58eb40eebdcc +F ext/rbu/sqlite3rbu.c e074c38798b90591f7f0cf0032d62f152ce5a95e +F ext/rbu/sqlite3rbu.h 1d91c5b7d066645bd1ff8e4b85c2b9b5dd29fb05 +F ext/rbu/test_rbu.c 5aa22616afac6f71ebd3d9bc9bf1006cfabcca88 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 F ext/rtree/rtree.c d26a815b0df1c412a6881dae8d7fd3c9c08cce68 F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e @@ -368,7 +368,7 @@ F src/os.c add02933b1dce7a39a005b00a2f5364b763e9a24 F src/os.h 8e976e59eb4ca1c0fca6d35ee803e38951cb0343 F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85 F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586 -F src/os_unix.c a9443cdab41d7f3cdf0df3a5aab62fd6e1c9b234 +F src/os_unix.c be9ca0f901a2b6c1bc93dc338f4863675180c189 F src/os_win.c 520f23475f1de530c435d30b67b7b15fe90874b0 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c 40928c450320da78bb4bd3ae82818f4239e19b7e @@ -1510,7 +1510,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 2ea0c8b46eefd4874f021f8dfd344be751f2034f -R 26e854b22e510a9651c111418b0d5f03 +P ab83d7077da80ddbcf399d0797d79e964dc64f0e +R 753cf0ce0fc5b95ce832a2f13995ee3e U dan -Z 78ea492cf13c3fac64589b27f22aa44b +Z 87571942a0f33f54e925f9d7f08d0ded diff --git a/manifest.uuid b/manifest.uuid index 22f2d26d97..32f13a7c5d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ab83d7077da80ddbcf399d0797d79e964dc64f0e \ No newline at end of file +ed406d31ff54ee3de8db91690a966e5c561f8f94 \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index f5b01e9958..08d4cb5d11 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -5529,6 +5529,27 @@ static UnixUnusedFd *findReusableFd(const char *zPath, int flags){ return pUnused; } +/* +** Find the mode, uid and gid of file zFile. +*/ +static int getFileMode( + const char *zFile, /* File name */ + mode_t *pMode, /* OUT: Permissions of zFile */ + uid_t *pUid, /* OUT: uid of zFile. */ + gid_t *pGid /* OUT: gid of zFile. */ +){ + struct stat sStat; /* Output of stat() on database file */ + int rc = SQLITE_OK; + if( 0==osStat(zFile, &sStat) ){ + *pMode = sStat.st_mode & 0777; + *pUid = sStat.st_uid; + *pGid = sStat.st_gid; + }else{ + rc = SQLITE_IOERR_FSTAT; + } + return rc; +} + /* ** This function is called by unixOpen() to determine the unix permissions ** to create new files with. If no error occurs, then SQLITE_OK is returned @@ -5564,7 +5585,6 @@ static int findCreateFileMode( if( flags & (SQLITE_OPEN_WAL|SQLITE_OPEN_MAIN_JOURNAL) ){ char zDb[MAX_PATHNAME+1]; /* Database file path */ int nDb; /* Number of valid bytes in zDb */ - struct stat sStat; /* Output of stat() on database file */ /* zPath is a path to a WAL or journal file. The following block derives ** the path to the associated database file from zPath. This block handles @@ -5595,15 +5615,18 @@ static int findCreateFileMode( memcpy(zDb, zPath, nDb); zDb[nDb] = '\0'; - if( 0==osStat(zDb, &sStat) ){ - *pMode = sStat.st_mode & 0777; - *pUid = sStat.st_uid; - *pGid = sStat.st_gid; - }else{ - rc = SQLITE_IOERR_FSTAT; - } + rc = getFileMode(zDb, pMode, pUid, pGid); }else if( flags & SQLITE_OPEN_DELETEONCLOSE ){ *pMode = 0600; + }else if( flags & SQLITE_OPEN_URI ){ + /* If this is a main database file and the file was opened using a URI + ** filename, check for the "modeof" parameter. If present, interpret + ** its value as a filename and try to copy the mode, uid and gid from + ** that file. */ + const char *z = sqlite3_uri_parameter(zPath, "modeof"); + if( z ){ + rc = getFileMode(z, pMode, pUid, pGid); + } } return rc; } From a48d7e77496b1463c2bea902b331b049bbcaeb01 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 12 Aug 2016 11:01:20 +0000 Subject: [PATCH 0694/1484] Fix a post-OOM memory leak. FossilOrigin-Name: 14009b32b955b42cfd5f0c2ce7d4b3ce19ce201e --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/expr.c | 5 +++-- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 37624e38f2..47aec35253 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\srecent\schanges\sfrom\strunk. -D 2016-08-11T12:31:21.178 +C Fix\sa\spost-OOM\smemory\sleak. +D 2016-08-12T11:01:20.692 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -338,7 +338,7 @@ F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7 F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b F src/dbstat.c 4f6f7f52b49beb9636ffbd517cfe44a402ba4ad0 F src/delete.c 4aba4214a377ce8ddde2d2e609777bcc8235200f -F src/expr.c dfc2275726e0a4916f10fe6b5b4f45fff835e790 +F src/expr.c 04b320c93f61ddc24ee032dd83317179c5f78a8b F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c bc4145347595b7770f9a598cff1c848302cf5413 F src/func.c 29cc9acb170ec1387b9f63eb52cd85f8de96c771 @@ -1516,7 +1516,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 8278be06fa69e3266866220bdaf5be45a5fcfa23 ab83d7077da80ddbcf399d0797d79e964dc64f0e -R 8a0bc19d70d02f930372e2439d9171fd +P 959677b97ba15f786936c762e2e68df1151d7ed0 +R a5cbb9bafc9fbcda9f99cc259b487bcb U drh -Z 019cf0a70c3da3c6f133d37b0001aac6 +Z b67a6933488c39df334f580c3bf48fca diff --git a/manifest.uuid b/manifest.uuid index 8c6670f9ff..847f607ac3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -959677b97ba15f786936c762e2e68df1151d7ed0 \ No newline at end of file +14009b32b955b42cfd5f0c2ce7d4b3ce19ce201e \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 8303c5f784..5ef692a440 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2506,12 +2506,13 @@ static void sqlite3ExprCodeIN( if( sqlite3ExprCheckIN(pParse, pExpr) ) return; zAff = exprINAffinity(pParse, pExpr); + if( zAff==0 ) return; nVector = sqlite3ExprVectorSize(pExpr->pLeft); aiMap = (int*)sqlite3DbMallocZero( pParse->db, nVector*(sizeof(int) + sizeof(char)) + 1 ); - if( !zAff || !aiMap ){ - sqlite3DbFree(pParse->db, aiMap); + if( aiMap==0 ){ + sqlite3DbFree(pParse->db, zAff); return; } From 471b4b92bdb2a203d048f2c87fb53d8d83381c0b Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 12 Aug 2016 11:25:49 +0000 Subject: [PATCH 0695/1484] Add VdbeCoverage() macros on newly added VDBE branch operations. FossilOrigin-Name: 381aa73141db8ec59adbcb09e71af660ee4ae5ce --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/expr.c | 6 ++++++ 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 47aec35253..ca1fac3357 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\spost-OOM\smemory\sleak. -D 2016-08-12T11:01:20.692 +C Add\sVdbeCoverage()\smacros\son\snewly\sadded\sVDBE\sbranch\soperations. +D 2016-08-12T11:25:49.567 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -338,7 +338,7 @@ F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7 F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b F src/dbstat.c 4f6f7f52b49beb9636ffbd517cfe44a402ba4ad0 F src/delete.c 4aba4214a377ce8ddde2d2e609777bcc8235200f -F src/expr.c 04b320c93f61ddc24ee032dd83317179c5f78a8b +F src/expr.c d05cc249f8615bd4655f839ee57c24d11d005dde F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c bc4145347595b7770f9a598cff1c848302cf5413 F src/func.c 29cc9acb170ec1387b9f63eb52cd85f8de96c771 @@ -1516,7 +1516,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 959677b97ba15f786936c762e2e68df1151d7ed0 -R a5cbb9bafc9fbcda9f99cc259b487bcb +P 14009b32b955b42cfd5f0c2ce7d4b3ce19ce201e +R 57be00fa8f04c7e5888f286343bb13cf U drh -Z b67a6933488c39df334f580c3bf48fca +Z c05ca00f4c6d3d32267dd4171ca3bdf0 diff --git a/manifest.uuid b/manifest.uuid index 847f607ac3..e0b19abe4c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -14009b32b955b42cfd5f0c2ce7d4b3ce19ce201e \ No newline at end of file +381aa73141db8ec59adbcb09e71af660ee4ae5ce \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 5ef692a440..3faeae79d2 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2606,6 +2606,7 @@ static void sqlite3ExprCodeIN( Expr *p = sqlite3ExprVectorField(pExpr->pLeft, i); if( sqlite3ExprCanBeNull(p) ){ sqlite3VdbeAddOp2(v, OP_IsNull, r1+aiMap[i], destIfNull); + VdbeCoverage(v); } } }else if( nVector==1 && sqlite3ExprCanBeNull(pExpr->pLeft) ){ @@ -2632,11 +2633,13 @@ static void sqlite3ExprCodeIN( /* Search the index for the key. */ addr = sqlite3VdbeAddOp4Int(v, OP_Found, iIdx, 0, r1, nVector); + VdbeCoverage(v); /* At this point the specified key is not present in the index, ** so the result of the IN(..) operator must be either NULL or ** 0. The vdbe code generated below figures out which. */ addrNext = 1+sqlite3VdbeAddOp2(v, OP_Rewind, iIdx, destIfFalse); + VdbeCoverage(v); for(i=0; ipLeft, i); if( sqlite3ExprCanBeNull(p) ){ sqlite3VdbeAddOp2(v, OP_IsNull, r1+aiMap[i], destIfNull); + VdbeCoverage(v); } } From 7fb89906880271b5b548a2c3ba5cfba7602daf9d Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 12 Aug 2016 16:21:15 +0000 Subject: [PATCH 0696/1484] Have wal file checkpoints exit early if the sqlite3_interrupt() API function is called. FossilOrigin-Name: 8a5f41c7b1718507524adef1a2730e99cf53270a --- manifest | 30 +++++---- manifest.uuid | 2 +- src/btree.c | 6 +- src/main.c | 7 ++ src/pager.c | 19 ++++-- src/pager.h | 6 +- src/test2.c | 2 +- src/vdbe.c | 2 +- src/wal.c | 13 +++- src/wal.h | 7 +- test/interrupt2.test | 154 +++++++++++++++++++++++++++++++++++++++++++ 11 files changed, 214 insertions(+), 34 deletions(-) create mode 100644 test/interrupt2.test diff --git a/manifest b/manifest index 3d5a0dd058..f170842c22 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\s"modeof="\sURI\sparameter\sto\sos_unix.c\s-\sused\sto\sspecify\sa\sfile\sto\scopy\spermissions\sfrom\swhen\sa\snew\sdatabase\sis\screated.\sAlso\sallow\spassing\sNULL\sas\sthe\ssecond\sparameter\sto\ssqlite3rbu_vacuum(). -D 2016-08-11T18:05:47.763 +C Have\swal\sfile\scheckpoints\sexit\searly\sif\sthe\ssqlite3_interrupt()\sAPI\sfunction\sis\scalled. +D 2016-08-12T16:21:15.202 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -328,7 +328,7 @@ F src/auth.c 5c8e0f37f785f935f589496801edd19840485853 F src/backup.c 17cd25a36d49330df2bacd2cadf2a61f3b525976 F src/bitvec.c 3ee4c8b2c94ed3a7377256e18199e6ff5cf33f63 F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 -F src/btree.c 2551bd3ecb8b8988fb8b23aabadfb214dbc38e46 +F src/btree.c 7aa56fb3545b9b84199987ba26e6316ae1abd769 F src/btree.h 075c45707c0f8f8af118f739f36df8098a08b7da F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 F src/build.c 7c3c780b703c09314032c8f6e4e7c1d80241a818 @@ -349,7 +349,7 @@ F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da F src/insert.c 8f4e9fcbd8e95e85f15647ba8b413b18d556ec2b F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e F src/loadext.c dd7a2b77902cc66c22555aef02e1a682554b7aec -F src/main.c 16c1b2114eae8804caf3a8de8cb47bf2c6d83ad3 +F src/main.c 52dad7971461bd1bdaa78c375016ebd883e11608 F src/malloc.c 1443d1ad95d67c21d77af7ae3f44678252f0efec F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b @@ -371,8 +371,8 @@ F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586 F src/os_unix.c be9ca0f901a2b6c1bc93dc338f4863675180c189 F src/os_win.c 520f23475f1de530c435d30b67b7b15fe90874b0 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a -F src/pager.c 40928c450320da78bb4bd3ae82818f4239e19b7e -F src/pager.h 966d2769e76ae347c8a32c4165faf6e6cb64546d +F src/pager.c 3d3ab7cb526615189750420e673d90689a9592a1 +F src/pager.h 0a19b1e212d0f5d0507f186ae1cca4e523d09d1a F src/parse.y 99b676e6fc2f4e331ab93e76b3987cffdbd28efa F src/pcache.c 5583c8ade4b05075a60ba953ef471d1c1a9c05df F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 @@ -395,7 +395,7 @@ F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 F src/tclsqlite.c bdae822f21e229b6daced15938b6343ce44ef454 F src/test1.c 0a0909cf7962d2359db329c08d15b90b4b6e724f -F src/test2.c b7174313e993754303a8b33c43df7c44b46857ab +F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5 F src/test3.c 1339a40be39650ae83894b6578f971dc7f96ea8a F src/test4.c 18ec393bb4d0ad1de729f0b94da7267270f3d8e6 F src/test5.c 328aae2c010c57a9829d255dc099d6899311672d @@ -450,7 +450,7 @@ F src/update.c 4f05ea8cddfa367d045e03589756c02199e8f9bd F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 810ec3f22e2d1b62e66c30fe3621ebdedd23584d F src/vacuum.c 9dd2f5d276bc6094d8f1d85ecd41b30c1a002a43 -F src/vdbe.c ea260b61e73b11a71e70b28a8e25866e2899e5da +F src/vdbe.c 94c114b3cc72098ea783f04f7a21d7f6b3e1dc73 F src/vdbe.h 67bc551f7faf04c33493892e4b378aada823ed10 F src/vdbeInt.h c59381049af5c7751a83456c39b80d1a6fde1f9d F src/vdbeapi.c c3f6715a99995c11748ecad91d25e93fd9fc390b @@ -461,8 +461,8 @@ F src/vdbesort.c 91fda3909326860382b0ca8aa251e609c6a9d62c F src/vdbetrace.c 41963d5376f0349842b5fc4aaaaacd7d9cdc0834 F src/vtab.c 6b3cfaff7e4397739d6b48511e777ca58c6d06d4 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 -F src/wal.c 02eeecc265f6ffd0597378f5d8ae9070b62a406a -F src/wal.h 6dd221ed384afdc204bc61e25c23ef7fd5a511f2 +F src/wal.c 0b44e89742024d3b6992bf404d2ab692113e1e60 +F src/wal.h bf03a23da3100ab25e5c0363450233cfee09cfc2 F src/walker.c 2d2cc7fb0f320f7f415215d7247f3c584141ac09 F src/where.c 5c9df42d50888be8274a5a0eb062eb0629869bd3 F src/whereInt.h e5b939701a7ceffc5a3a8188a37f9746416ebcd0 @@ -859,6 +859,7 @@ F test/insert5.test 394f96728d1258f406fe5f5aeb0aaf29487c39a6 F test/instr.test 737bbf80685232033f3abedc6ae92f75860b5dd2 F test/intarray.test 066b7d7ac38d25bf96f87f1b017bfc687551cdd4 F test/interrupt.test dfe9a67a94b0b2d8f70545ba1a6cca10780d71cc +F test/interrupt2.test 829b06f9e20a6c378d8bd121b26c337f4dfa36e5 F test/intpkey.test ac71107a49a06492b69b82aafaf225400598d3c8 F test/io.test f95bca1783b01ea7761671560d023360d2dfa4cc F test/ioerr.test 2a24bd6ed5a8b062e64bfe1f6cf94fb25e92210d @@ -1510,7 +1511,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ab83d7077da80ddbcf399d0797d79e964dc64f0e -R 753cf0ce0fc5b95ce832a2f13995ee3e +P ed406d31ff54ee3de8db91690a966e5c561f8f94 +R fe020edefec096b26ead32b9e5eecd82 +T *branch * interruptible-checkpoint +T *sym-interruptible-checkpoint * +T -sym-trunk * U dan -Z 87571942a0f33f54e925f9d7f08d0ded +Z f50973b5d64203bd29a6b71f91836967 diff --git a/manifest.uuid b/manifest.uuid index 32f13a7c5d..ee026b5b57 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ed406d31ff54ee3de8db91690a966e5c561f8f94 \ No newline at end of file +8a5f41c7b1718507524adef1a2730e99cf53270a \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 841aee9463..c25c594046 100644 --- a/src/btree.c +++ b/src/btree.c @@ -2392,7 +2392,7 @@ int sqlite3BtreeOpen( btree_open_out: if( rc!=SQLITE_OK ){ if( pBt && pBt->pPager ){ - sqlite3PagerClose(pBt->pPager); + sqlite3PagerClose(pBt->pPager, 0); } sqlite3_free(pBt); sqlite3_free(p); @@ -2534,7 +2534,7 @@ int sqlite3BtreeClose(Btree *p){ ** Clean out and delete the BtShared object. */ assert( !pBt->pCursor ); - sqlite3PagerClose(pBt->pPager); + sqlite3PagerClose(pBt->pPager, p->db); if( pBt->xFreeSchema && pBt->pSchema ){ pBt->xFreeSchema(pBt->pSchema); } @@ -9476,7 +9476,7 @@ int sqlite3BtreeCheckpoint(Btree *p, int eMode, int *pnLog, int *pnCkpt){ if( pBt->inTransaction!=TRANS_NONE ){ rc = SQLITE_LOCKED; }else{ - rc = sqlite3PagerCheckpoint(pBt->pPager, eMode, pnLog, pnCkpt); + rc = sqlite3PagerCheckpoint(pBt->pPager, p->db, eMode, pnLog, pnCkpt); } sqlite3BtreeLeave(p); } diff --git a/src/main.c b/src/main.c index f31f865818..77808f497f 100644 --- a/src/main.c +++ b/src/main.c @@ -2099,6 +2099,13 @@ int sqlite3_wal_checkpoint_v2( sqlite3Error(db, rc); } rc = sqlite3ApiExit(db, rc); + + /* If there are no active statements, clear the interrupt flag at this + ** point. */ + if( db->nVdbeActive==0 ){ + db->u1.isInterrupted = 0; + } + sqlite3_mutex_leave(db->mutex); return rc; #endif diff --git a/src/pager.c b/src/pager.c index cd8d1204b3..56c4329a16 100644 --- a/src/pager.c +++ b/src/pager.c @@ -4021,9 +4021,10 @@ static void pagerFreeMapHdrs(Pager *pPager){ ** a hot journal may be left in the filesystem but no error is returned ** to the caller. */ -int sqlite3PagerClose(Pager *pPager){ +int sqlite3PagerClose(Pager *pPager, sqlite3 *db){ u8 *pTmp = (u8 *)pPager->pTmpSpace; + assert( db || pagerUseWal(pPager)==0 ); assert( assert_pager_state(pPager) ); disable_simulated_io_errors(); sqlite3BeginBenignMalloc(); @@ -4031,7 +4032,7 @@ int sqlite3PagerClose(Pager *pPager){ /* pPager->errCode = 0; */ pPager->exclusiveMode = 0; #ifndef SQLITE_OMIT_WAL - sqlite3WalClose(pPager->pWal, pPager->ckptSyncFlags, pPager->pageSize, pTmp); + sqlite3WalClose(pPager->pWal,db,pPager->ckptSyncFlags,pPager->pageSize,pTmp); pPager->pWal = 0; #endif pager_reset(pPager); @@ -7176,10 +7177,16 @@ void sqlite3PagerClearCache(Pager *pPager){ ** ** Parameter eMode is one of SQLITE_CHECKPOINT_PASSIVE, FULL or RESTART. */ -int sqlite3PagerCheckpoint(Pager *pPager, int eMode, int *pnLog, int *pnCkpt){ +int sqlite3PagerCheckpoint( + Pager *pPager, /* Checkpoint on this pager */ + sqlite3 *db, /* Db handle used to check for interrupts */ + int eMode, /* Type of checkpoint */ + int *pnLog, /* OUT: Final number of frames in log */ + int *pnCkpt /* OUT: Final number of checkpointed frames */ +){ int rc = SQLITE_OK; if( pPager->pWal ){ - rc = sqlite3WalCheckpoint(pPager->pWal, eMode, + rc = sqlite3WalCheckpoint(pPager->pWal, db, eMode, (eMode==SQLITE_CHECKPOINT_PASSIVE ? 0 : pPager->xBusyHandler), pPager->pBusyHandlerArg, pPager->ckptSyncFlags, pPager->pageSize, (u8 *)pPager->pTmpSpace, @@ -7311,7 +7318,7 @@ int sqlite3PagerOpenWal( ** error (SQLITE_BUSY) is returned and the log connection is not closed. ** If successful, the EXCLUSIVE lock is not released before returning. */ -int sqlite3PagerCloseWal(Pager *pPager){ +int sqlite3PagerCloseWal(Pager *pPager, sqlite3 *db){ int rc = SQLITE_OK; assert( pPager->journalMode==PAGER_JOURNALMODE_WAL ); @@ -7339,7 +7346,7 @@ int sqlite3PagerCloseWal(Pager *pPager){ if( rc==SQLITE_OK && pPager->pWal ){ rc = pagerExclusiveLock(pPager); if( rc==SQLITE_OK ){ - rc = sqlite3WalClose(pPager->pWal, pPager->ckptSyncFlags, + rc = sqlite3WalClose(pPager->pWal, db, pPager->ckptSyncFlags, pPager->pageSize, (u8*)pPager->pTmpSpace); pPager->pWal = 0; pagerFixMaplimit(pPager); diff --git a/src/pager.h b/src/pager.h index 1046670912..68f2c06cae 100644 --- a/src/pager.h +++ b/src/pager.h @@ -122,7 +122,7 @@ int sqlite3PagerOpen( int, void(*)(DbPage*) ); -int sqlite3PagerClose(Pager *pPager); +int sqlite3PagerClose(Pager *pPager, sqlite3*); int sqlite3PagerReadFileheader(Pager*, int, unsigned char*); /* Functions used to configure a Pager object. */ @@ -173,11 +173,11 @@ int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint); int sqlite3PagerSharedLock(Pager *pPager); #ifndef SQLITE_OMIT_WAL - int sqlite3PagerCheckpoint(Pager *pPager, int, int*, int*); + int sqlite3PagerCheckpoint(Pager *pPager, sqlite3*, int, int*, int*); int sqlite3PagerWalSupported(Pager *pPager); int sqlite3PagerWalCallback(Pager *pPager); int sqlite3PagerOpenWal(Pager *pPager, int *pisOpen); - int sqlite3PagerCloseWal(Pager *pPager); + int sqlite3PagerCloseWal(Pager *pPager, sqlite3*); # ifdef SQLITE_ENABLE_SNAPSHOT int sqlite3PagerSnapshotGet(Pager *pPager, sqlite3_snapshot **ppSnapshot); int sqlite3PagerSnapshotOpen(Pager *pPager, sqlite3_snapshot *pSnapshot); diff --git a/src/test2.c b/src/test2.c index dfca1d2b31..850e1e1a04 100644 --- a/src/test2.c +++ b/src/test2.c @@ -93,7 +93,7 @@ static int SQLITE_TCLAPI pager_close( return TCL_ERROR; } pPager = sqlite3TestTextToPtr(argv[1]); - rc = sqlite3PagerClose(pPager); + rc = sqlite3PagerClose(pPager, 0); if( rc!=SQLITE_OK ){ Tcl_AppendResult(interp, sqlite3ErrName(rc), 0); return TCL_ERROR; diff --git a/src/vdbe.c b/src/vdbe.c index 5d21ad064c..c7b0abf38c 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -6227,7 +6227,7 @@ case OP_JournalMode: { /* out2 */ ** file. An EXCLUSIVE lock may still be held on the database file ** after a successful return. */ - rc = sqlite3PagerCloseWal(pPager); + rc = sqlite3PagerCloseWal(pPager, db); if( rc==SQLITE_OK ){ sqlite3PagerSetJournalMode(pPager, eNew); } diff --git a/src/wal.c b/src/wal.c index 235d383e1a..8da7639535 100644 --- a/src/wal.c +++ b/src/wal.c @@ -1723,6 +1723,7 @@ static void walRestartHdr(Wal *pWal, u32 salt1){ */ static int walCheckpoint( Wal *pWal, /* Wal connection */ + sqlite3 *db, /* Check for interrupts on this handle */ int eMode, /* One of PASSIVE, FULL or RESTART */ int (*xBusy)(void*), /* Function to call when busy */ void *pBusyArg, /* Context argument for xBusyHandler */ @@ -1817,6 +1818,10 @@ static int walCheckpoint( while( rc==SQLITE_OK && 0==walIteratorNext(pIter, &iDbpage, &iFrame) ){ i64 iOffset; assert( walFramePgno(pWal, iFrame)==iDbpage ); + if( db->u1.isInterrupted ){ + rc = db->mallocFailed ? SQLITE_NOMEM_BKPT : SQLITE_INTERRUPT; + break; + } if( iFrame<=nBackfill || iFrame>mxSafeFrame || iDbpage>mxPage ){ continue; } @@ -1921,6 +1926,7 @@ static void walLimitSize(Wal *pWal, i64 nMax){ */ int sqlite3WalClose( Wal *pWal, /* Wal to close */ + sqlite3 *db, /* For interrupt flag */ int sync_flags, /* Flags to pass to OsSync() (or 0) */ int nBuf, u8 *zBuf /* Buffer of at least nBuf bytes */ @@ -1942,8 +1948,8 @@ int sqlite3WalClose( if( pWal->exclusiveMode==WAL_NORMAL_MODE ){ pWal->exclusiveMode = WAL_EXCLUSIVE_MODE; } - rc = sqlite3WalCheckpoint( - pWal, SQLITE_CHECKPOINT_PASSIVE, 0, 0, sync_flags, nBuf, zBuf, 0, 0 + rc = sqlite3WalCheckpoint(pWal, db, + SQLITE_CHECKPOINT_PASSIVE, 0, 0, sync_flags, nBuf, zBuf, 0, 0 ); if( rc==SQLITE_OK ){ int bPersist = -1; @@ -3191,6 +3197,7 @@ int sqlite3WalFrames( */ int sqlite3WalCheckpoint( Wal *pWal, /* Wal connection */ + sqlite3 *db, /* Check this handle's interrupt flag */ int eMode, /* PASSIVE, FULL, RESTART, or TRUNCATE */ int (*xBusy)(void*), /* Function to call when busy */ void *pBusyArg, /* Context argument for xBusyHandler */ @@ -3265,7 +3272,7 @@ int sqlite3WalCheckpoint( if( pWal->hdr.mxFrame && walPagesize(pWal)!=nBuf ){ rc = SQLITE_CORRUPT_BKPT; }else{ - rc = walCheckpoint(pWal, eMode2, xBusy2, pBusyArg, sync_flags, zBuf); + rc = walCheckpoint(pWal, db, eMode2, xBusy2, pBusyArg, sync_flags, zBuf); } /* If no error occurred, set the output variables. */ diff --git a/src/wal.h b/src/wal.h index 6048e7985c..16d9d6e0d4 100644 --- a/src/wal.h +++ b/src/wal.h @@ -28,7 +28,7 @@ #ifdef SQLITE_OMIT_WAL # define sqlite3WalOpen(x,y,z) 0 # define sqlite3WalLimit(x,y) -# define sqlite3WalClose(w,x,y,z) 0 +# define sqlite3WalClose(v,w,x,y,z) 0 # define sqlite3WalBeginReadTransaction(y,z) 0 # define sqlite3WalEndReadTransaction(z) # define sqlite3WalDbsize(y) 0 @@ -38,7 +38,7 @@ # define sqlite3WalSavepoint(y,z) # define sqlite3WalSavepointUndo(y,z) 0 # define sqlite3WalFrames(u,v,w,x,y,z) 0 -# define sqlite3WalCheckpoint(r,s,t,u,v,w,x,y,z) 0 +# define sqlite3WalCheckpoint(q,r,s,t,u,v,w,x,y,z) 0 # define sqlite3WalCallback(z) 0 # define sqlite3WalExclusiveMode(y,z) 0 # define sqlite3WalHeapMemory(z) 0 @@ -56,7 +56,7 @@ typedef struct Wal Wal; /* Open and close a connection to a write-ahead log. */ int sqlite3WalOpen(sqlite3_vfs*, sqlite3_file*, const char *, int, i64, Wal**); -int sqlite3WalClose(Wal *pWal, int sync_flags, int, u8 *); +int sqlite3WalClose(Wal *pWal, sqlite3*, int sync_flags, int, u8 *); /* Set the limiting size of a WAL file. */ void sqlite3WalLimit(Wal*, i64); @@ -99,6 +99,7 @@ int sqlite3WalFrames(Wal *pWal, int, PgHdr *, Pgno, int, int); /* Copy pages from the log to the database file */ int sqlite3WalCheckpoint( Wal *pWal, /* Write-ahead log connection */ + sqlite3 *db, /* Check this handle's interrupt flag */ int eMode, /* One of PASSIVE, FULL and RESTART */ int (*xBusy)(void*), /* Function to call when busy */ void *pBusyArg, /* Context argument for xBusyHandler */ diff --git a/test/interrupt2.test b/test/interrupt2.test new file mode 100644 index 0000000000..59ad7b3893 --- /dev/null +++ b/test/interrupt2.test @@ -0,0 +1,154 @@ +# 2016 Aug 12 +# +# 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 regression tests for SQLite library. The +# focus of this script is using the sqlite_interrupt() API to +# interrupt WAL checkpoint operations. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +source $testdir/wal_common.tcl +set testprefix interrupt2 + +db close +testvfs tvfs -default 1 + +tvfs filter xWrite +tvfs script write_cb + +set ::trigger_interrupt 0 +proc write_cb {method args} { + set filename [lindex $args 0] + if {[file tail $filename]=="test.db" && $::trigger_interrupt} { + if {$::trigger_interrupt} { + incr ::trigger_interrupt -1 + if {$::trigger_interrupt==0} { sqlite3_interrupt db } + } + } + return 0 +} + +sqlite3 db test.db +do_execsql_test 1.0 { + CREATE TABLE t1(a, b); + CREATE INDEX t1a ON t1(a); + CREATE INDEX t1b ON t1(b); + PRAGMA journal_mode = wal; + + WITH ii(i) AS ( VALUES(1) UNION ALL SELECT i+1 FROM ii WHERE i<1000 ) + INSERT INTO t1 SELECT i, i FROM ii; +} {wal} + +foreach idelay { + 5 + 10 + 15 + 20 +} { + + set ::trigger_interrupt $idelay + do_catchsql_test 1.$idelay.1 { PRAGMA wal_checkpoint; } {1 interrupted} + do_execsql_test 1.$idelay.2 { SELECT count(*) FROM t1 } 1000 + + set ::trigger_interrupt $idelay + do_test 1.$idelay.3 { + list [catch { sqlite3_wal_checkpoint_v2 db truncate } msg] $msg + } {1 {SQLITE_INTERRUPT - interrupted}} + do_execsql_test 1.$idelay.4 { SELECT count(*) FROM t1 } 1000 +} + +#------------------------------------------------------------------------- +# Check that if there are other SQL statements running, a checkpoint does +# not clear the isInterrupted flag. +# +do_execsql_test 2.0 { + CREATE TEMP TABLE z1(a, b); + INSERT INTO z1 SELECT * FROM t1; +} + +do_test 2.1 { + set i 10 + set res [list [catch { + set i 10 + db eval {SELECT * FROM z1} { + incr i -1 + if {$i==0} { + set ::trigger_interrupt 10 + set cres [catch { sqlite3_wal_checkpoint_v2 db truncate } msg] + lappend cres $msg + } + } + } msg] $msg] + + list $cres $res +} {{1 {SQLITE_INTERRUPT - interrupted}} {1 interrupted}} + +do_execsql_test 2.0 { + SELECT count(*) FROM t1 + UNION ALL + SELECT count(*) FROM z1 +} {1000 1000} + +#------------------------------------------------------------------------- +# Check the effect of an interrupt during sqlite3_close(). +# +db_save_and_close + +db_restore_and_reopen +do_test 3.1.1 { + set ::trigger_interrupt 10 + db eval { SELECT * FROM sqlite_master } + db close + set {} {} +} {} +do_test 3.1.2 { + list [file exists test.db] [file exists test.db-wal] +} {1 1} + +db_restore_and_reopen +do_test 3.2.1 { + db eval { SELECT * FROM sqlite_master } + db close + set {} {} +} {} +do_test 3.2.2 { + list [file exists test.db] [file exists test.db-wal] +} {1 0} + +#------------------------------------------------------------------------- +# Check the effect of an interrupt during an automatic checkpoint +# +db_restore_and_reopen +do_test 4.0 { + execsql { PRAGMA wal_autocheckpoint = 10 } + set ::trigger_interrupt 10 + execsql { CREATE TABLE t2(x, y) } +} {} + +# The auto-checkpoint in test 4.0 should have been interrupted. So this +# db write should cause the wal file to grow. +do_test 4.1 { + set nFrame1 [wal_frame_count test.db-wal 1024] + execsql { CREATE TABLE t3(x, y) } + set nFrame2 [wal_frame_count test.db-wal 1024] + expr $nFrame2 > $nFrame1 +} {1} + +# The auto-checkpoint in test 4.0 should not have been interrupted. So +# this db write should not cause the wal file to grow. +do_test 4.2 { + set nFrame1 [wal_frame_count test.db-wal 1024] + execsql { CREATE TABLE t4(x, y) } + set nFrame2 [wal_frame_count test.db-wal 1024] + expr $nFrame2 == $nFrame1 +} {1} + +finish_test From 3b96d1e2e4009668060d35c14bbf3c637de9ce33 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 13 Aug 2016 06:38:31 +0000 Subject: [PATCH 0697/1484] Fix a buffer overread in fts5. FossilOrigin-Name: fcfbee6c7d33a9ae7feb46044a0c2fe680460d39 --- ext/fts5/fts5_expr.c | 2 +- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/ext/fts5/fts5_expr.c b/ext/fts5/fts5_expr.c index ca795a6b35..c8f649c7fd 100644 --- a/ext/fts5/fts5_expr.c +++ b/ext/fts5/fts5_expr.c @@ -1659,7 +1659,7 @@ int sqlite3Fts5ExprClonePhrase( if( rc==SQLITE_OK ){ Fts5Colset *pColsetOrig = pOrig->pNode->pNear->pColset; if( pColsetOrig ){ - int nByte = sizeof(Fts5Colset) + pColsetOrig->nCol * sizeof(int); + int nByte = sizeof(Fts5Colset) + (pColsetOrig->nCol-1) * sizeof(int); Fts5Colset *pColset = (Fts5Colset*)sqlite3Fts5MallocZero(&rc, nByte); if( pColset ){ memcpy(pColset, pColsetOrig, nByte); diff --git a/manifest b/manifest index 3d5a0dd058..a564676413 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\s"modeof="\sURI\sparameter\sto\sos_unix.c\s-\sused\sto\sspecify\sa\sfile\sto\scopy\spermissions\sfrom\swhen\sa\snew\sdatabase\sis\screated.\sAlso\sallow\spassing\sNULL\sas\sthe\ssecond\sparameter\sto\ssqlite3rbu_vacuum(). -D 2016-08-11T18:05:47.763 +C Fix\sa\sbuffer\soverread\sin\sfts5. +D 2016-08-13T06:38:31.533 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -102,7 +102,7 @@ F ext/fts5/fts5Int.h b2eda36e0f224365c8e23dc8f559311834f1c13f F ext/fts5/fts5_aux.c daa57fb45216491814520bbb587e97bf81ced458 F ext/fts5/fts5_buffer.c 4c1502d4c956cd092c89ce4480867f9d8bf325cd F ext/fts5/fts5_config.c 5af9c360e99669d29f06492c370892394aba0857 -F ext/fts5/fts5_expr.c df0004b5bffcbe34c329f2992669c6352443f415 +F ext/fts5/fts5_expr.c 1ee97156421919e497595bfa962bb88ad1665401 F ext/fts5/fts5_hash.c 880998e596b60f078348d48732ca4ad9a90caad2 F ext/fts5/fts5_index.c 05386732609221d066d204b22c4a5275a0225ed4 F ext/fts5/fts5_main.c f85281445dcf8be32d18841c93a6f90fe27dbfe2 @@ -1510,7 +1510,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ab83d7077da80ddbcf399d0797d79e964dc64f0e -R 753cf0ce0fc5b95ce832a2f13995ee3e +P ed406d31ff54ee3de8db91690a966e5c561f8f94 +R c7f71e9982fe95b86462907f7307b757 U dan -Z 87571942a0f33f54e925f9d7f08d0ded +Z faa5a19931d7d3892f5c4860f7744222 diff --git a/manifest.uuid b/manifest.uuid index 32f13a7c5d..b2e843f3ec 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ed406d31ff54ee3de8db91690a966e5c561f8f94 \ No newline at end of file +fcfbee6c7d33a9ae7feb46044a0c2fe680460d39 \ No newline at end of file From 79752b6e63c03a18fd93817c6e9580d7445a7ce9 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 13 Aug 2016 10:02:17 +0000 Subject: [PATCH 0698/1484] Attempt to simplify the logic and generated code for vector comparisons. Basic comparison operators are working, but there are many indexing test failures still to be worked through. FossilOrigin-Name: dfc028cfbe7657d20727a2670ecadb1575eb8cbb --- manifest | 19 +++-- manifest.uuid | 2 +- src/expr.c | 109 ++++++++++++++------------- src/sqliteInt.h | 1 + src/vdbe.c | 195 ++++++++++++++++++++---------------------------- 5 files changed, 150 insertions(+), 176 deletions(-) diff --git a/manifest b/manifest index ca1fac3357..1a0b48fa4a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sVdbeCoverage()\smacros\son\snewly\sadded\sVDBE\sbranch\soperations. -D 2016-08-12T11:25:49.567 +C Attempt\sto\ssimplify\sthe\slogic\sand\sgenerated\scode\sfor\svector\scomparisons.\nBasic\scomparison\soperators\sare\sworking,\sbut\sthere\sare\smany\sindexing\stest\nfailures\sstill\sto\sbe\sworked\sthrough. +D 2016-08-13T10:02:17.801 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -338,7 +338,7 @@ F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7 F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b F src/dbstat.c 4f6f7f52b49beb9636ffbd517cfe44a402ba4ad0 F src/delete.c 4aba4214a377ce8ddde2d2e609777bcc8235200f -F src/expr.c d05cc249f8615bd4655f839ee57c24d11d005dde +F src/expr.c 375de68ad2daf3bd339f79074ced5a6db77e2f62 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c bc4145347595b7770f9a598cff1c848302cf5413 F src/func.c 29cc9acb170ec1387b9f63eb52cd85f8de96c771 @@ -389,7 +389,7 @@ F src/shell.c 79dda477be6c96eba6e952a934957ad36f87acc7 F src/sqlite.h.in 0f7580280d1b009b507d8beec1ff0f197ba0cc99 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae -F src/sqliteInt.h a1cf00afd6a5666a160e81c7a600418a3b59a8a6 +F src/sqliteInt.h 98d9ccfa30c0d4b1b886ed61f409dc6b307e9b0f F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 @@ -450,7 +450,7 @@ F src/update.c 4f05ea8cddfa367d045e03589756c02199e8f9bd F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 810ec3f22e2d1b62e66c30fe3621ebdedd23584d F src/vacuum.c 9dd2f5d276bc6094d8f1d85ecd41b30c1a002a43 -F src/vdbe.c 9f15129214a55044f918a983e1560fd87b0130a8 +F src/vdbe.c 9816bc4f89e4d58340f3cf3354fd062e2da11f8a F src/vdbe.h 67bc551f7faf04c33493892e4b378aada823ed10 F src/vdbeInt.h c59381049af5c7751a83456c39b80d1a6fde1f9d F src/vdbeapi.c c3f6715a99995c11748ecad91d25e93fd9fc390b @@ -1516,7 +1516,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 14009b32b955b42cfd5f0c2ce7d4b3ce19ce201e -R 57be00fa8f04c7e5888f286343bb13cf +P 381aa73141db8ec59adbcb09e71af660ee4ae5ce +R b082d1240e853643b05ab20adb3ffc1b +T *branch * vector-compare +T *sym-vector-compare * +T -sym-rowvalue * U drh -Z c05ca00f4c6d3d32267dd4171ca3bdf0 +Z 873e26b27a2fd221371ad3338313919b diff --git a/manifest.uuid b/manifest.uuid index e0b19abe4c..617135c700 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -381aa73141db8ec59adbcb09e71af660ee4ae5ce \ No newline at end of file +dfc028cfbe7657d20727a2670ecadb1575eb8cbb \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 3faeae79d2..54bf0dfaba 100644 --- a/src/expr.c +++ b/src/expr.c @@ -409,37 +409,52 @@ static int exprVectorRegister( /* ** Expression pExpr is a comparison between two vector values. Compute -** the result of the comparison and write it to register dest. +** the result of the comparison (1, 0, or NULL) and write that +** result into register dest. +** +** The caller must satisfy the following preconditions: +** +** if pExpr->op==TK_IS: op==TK_EQ and p5==SQLITE_NULLEQ +** if pExpr->op==TK_ISNOT: op==TK_NE and p5==SQLITE_NULLEQ +** otherwise: op==pExpr->op and p5==0 */ -static void codeVectorCompare(Parse *pParse, Expr *pExpr, int dest){ +static void codeVectorCompare( + Parse *pParse, /* Code generator context */ + Expr *pExpr, /* The comparison operation */ + int dest, /* Write results into this register */ + u8 op, /* Comparison operator */ + u8 p5 /* SQLITE_NULLEQ or zero */ +){ Vdbe *v = pParse->pVdbe; Expr *pLeft = pExpr->pLeft; Expr *pRight = pExpr->pRight; int nLeft = sqlite3ExprVectorSize(pLeft); int nRight = sqlite3ExprVectorSize(pRight); - int addr = sqlite3VdbeMakeLabel(v); /* Check that both sides of the comparison are vectors, and that ** both are the same length. */ if( nLeft!=nRight ){ sqlite3ErrorMsg(pParse, "invalid use of row value"); }else{ - int p5 = (pExpr->op==TK_IS || pExpr->op==TK_ISNOT) ? SQLITE_NULLEQ : 0; int i; int regLeft = 0; int regRight = 0; - int regTmp = 0; + u8 opx = op; + int addrDone = sqlite3VdbeMakeLabel(v); assert( pExpr->op==TK_EQ || pExpr->op==TK_NE || pExpr->op==TK_IS || pExpr->op==TK_ISNOT || pExpr->op==TK_LT || pExpr->op==TK_GT || pExpr->op==TK_LE || pExpr->op==TK_GE ); + assert( pExpr->op==op || (pExpr->op==TK_IS && op==TK_EQ) + || (pExpr->op==TK_ISNOT && op==TK_NE) ); + assert( p5==0 || pExpr->op!=op ); + assert( p5==SQLITE_NULLEQ || pExpr->op==op ); - if( pExpr->op==TK_EQ || pExpr->op==TK_NE ){ - regTmp = sqlite3GetTempReg(pParse); - sqlite3VdbeAddOp2(v, OP_Integer, (pExpr->op==TK_EQ), dest); - } + p5 |= SQLITE_STOREP2; + if( opx==TK_LE ) opx = TK_LT; + if( opx==TK_GE ) opx = TK_GT; regLeft = exprCodeSubselect(pParse, pLeft); regRight = exprCodeSubselect(pParse, pRight); @@ -448,55 +463,43 @@ static void codeVectorCompare(Parse *pParse, Expr *pExpr, int dest){ int regFree1 = 0, regFree2 = 0; Expr *pL, *pR; int r1, r2; - if( i ) sqlite3ExprCachePush(pParse); + if( i>0 ) sqlite3ExprCachePush(pParse); r1 = exprVectorRegister(pParse, pLeft, i, regLeft, &pL, ®Free1); r2 = exprVectorRegister(pParse, pRight, i, regRight, &pR, ®Free2); - - switch( pExpr->op ){ - case TK_IS: - codeCompare( - pParse, pL, pR, OP_Eq, r1, r2, dest, SQLITE_STOREP2|SQLITE_NULLEQ - ); - sqlite3VdbeAddOp3(v, OP_IfNot, dest, addr, 1); - VdbeCoverage(v); - break; - - case TK_ISNOT: - codeCompare( - pParse, pL, pR, OP_Ne, r1, r2, dest, SQLITE_STOREP2|SQLITE_NULLEQ - ); - sqlite3VdbeAddOp3(v, OP_If, dest, addr, 1); - VdbeCoverage(v); - break; - - case TK_EQ: - case TK_NE: - codeCompare(pParse, pL, pR, OP_Cmp, r1, r2, regTmp,SQLITE_STOREP2|p5); - sqlite3VdbeAddOp4Int( - v, OP_CmpTest, regTmp, addr, dest, pExpr->op==TK_NE - ); - VdbeCoverage(v); - break; - - case TK_LT: - case TK_LE: - case TK_GT: - case TK_GE: - codeCompare(pParse, pL, pR, OP_Cmp, r1, r2, dest, SQLITE_STOREP2|p5); - sqlite3VdbeAddOp4Int(v, OP_CmpTest, dest, addr, 0, pExpr->op); - VdbeCoverage(v); - break; - } - + codeCompare(pParse, pL, pR, opx, r1, r2, dest, p5); + testcase(op==OP_Lt); VdbeCoverageIf(v,op==OP_Lt); + testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le); + testcase(op==OP_Gt); VdbeCoverageIf(v,op==OP_Gt); + testcase(op==OP_Ge); VdbeCoverageIf(v,op==OP_Ge); + testcase(op==OP_Eq); VdbeCoverageIf(v,op==OP_Eq); + testcase(op==OP_Ne); VdbeCoverageIf(v,op==OP_Ne); sqlite3ReleaseTempReg(pParse, regFree1); sqlite3ReleaseTempReg(pParse, regFree2); - if( i ) sqlite3ExprCachePop(pParse); + if( i>0 ) sqlite3ExprCachePop(pParse); + if( i==nLeft-1 ){ + break; + } + if( opx==TK_EQ ){ + sqlite3VdbeAddOp2(v, OP_IfNot, dest, addrDone); VdbeCoverage(v); + p5 |= SQLITE_KEEPNULL; + }else if( opx==TK_NE ){ + sqlite3VdbeAddOp2(v, OP_If, dest, addrDone); VdbeCoverage(v); + p5 |= SQLITE_KEEPNULL; + }else if( opx==op ){ + assert( op==TK_LT || op==TK_GT ); + sqlite3VdbeAddOp3(v, OP_If, dest, addrDone, 1); + VdbeCoverageIf(v, op==TK_LT); + VdbeCoverageIf(v, op==TK_GT); + }else{ + assert( op==TK_LE || op==TK_GE ); + sqlite3VdbeAddOp2(v, OP_ElseNotEq, 0, addrDone); + VdbeCoverageIf(v, op==TK_LE); + VdbeCoverageIf(v, op==TK_GE); + if( i==nLeft-2 ) opx = op; + } } - - sqlite3ReleaseTempReg(pParse, regTmp); + sqlite3VdbeResolveLabel(v, addrDone); } - - sqlite3VdbeResolveLabel(v, addr); } #if SQLITE_MAX_EXPR_DEPTH>0 @@ -3251,7 +3254,7 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ case TK_EQ: { Expr *pLeft = pExpr->pLeft; if( sqlite3ExprIsVector(pLeft) ){ - codeVectorCompare(pParse, pExpr, target); + codeVectorCompare(pParse, pExpr, target, op, p5); }else{ r1 = sqlite3ExprCodeTemp(pParse, pLeft, ®Free1); r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index a9061b2833..4c6554367f 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1733,6 +1733,7 @@ struct CollSeq { ** operator is NULL. It is added to certain comparison operators to ** prove that the operands are always NOT NULL. */ +#define SQLITE_KEEPNULL 0x08 /* Used by vector == or <> */ #define SQLITE_JUMPIFNULL 0x10 /* jumps if either operand is NULL */ #define SQLITE_STOREP2 0x20 /* Store result in reg[P2] rather than jump */ #define SQLITE_NULLEQ 0x80 /* NULL=NULL */ diff --git a/src/vdbe.c b/src/vdbe.c index 054f1997f3..be5ca79ed5 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -585,6 +585,7 @@ int sqlite3VdbeExec( Mem *pOut = 0; /* Output operand */ int *aPermute = 0; /* Permutation of columns for OP_Compare */ i64 lastRowid = db->lastRowid; /* Saved value of the last insert ROWID */ + int cmpRes; /* Result of last comparison operation */ #ifdef VDBE_PROFILE u64 start; /* CPU clock count at start of opcode */ #endif @@ -1880,14 +1881,59 @@ case OP_Cast: { /* in1 */ } #endif /* SQLITE_OMIT_CAST */ +/* Opcode: Eq P1 P2 P3 P4 P5 +** Synopsis: if r[P1]==r[P3] goto P2 +** +** Compare the values in register P1 and P3. If reg(P3)==reg(P1) then +** jump to address P2. Or if the SQLITE_STOREP2 flag is set in P5, then +** store the result of comparison in register P2. +** +** The SQLITE_AFF_MASK portion of P5 must be an affinity character - +** SQLITE_AFF_TEXT, SQLITE_AFF_INTEGER, and so forth. An attempt is made +** to coerce both inputs according to this affinity before the +** comparison is made. If the SQLITE_AFF_MASK is 0x00, then numeric +** affinity is used. Note that the affinity conversions are stored +** back into the input registers P1 and P3. So this opcode can cause +** persistent changes to registers P1 and P3. +** +** Once any conversions have taken place, and neither value is NULL, +** the values are compared. If both values are blobs then memcmp() is +** used to determine the results of the comparison. If both values +** are text, then the appropriate collating function specified in +** P4 is used to do the comparison. If P4 is not specified then +** memcmp() is used to compare text string. If both values are +** numeric, then a numeric comparison is used. If the two values +** are of different types, then numbers are considered less than +** strings and strings are considered less than blobs. +** +** If SQLITE_NULLEQ is set in P5 then the result of comparison is always either +** true or false and is never NULL. If both operands are NULL then the result +** of comparison is true. If either operand is NULL then the result is false. +** If neither operand is NULL the result is the same as it would be if +** the SQLITE_NULLEQ flag were omitted from P5. +** +** If both SQLITE_STOREP2 and SQLITE_KEEPNULL flags are set then the +** content of r[P2] is only set to 1 (true) if it was not previously NULL. +*/ +/* Opcode: Ne P1 P2 P3 P4 P5 +** Synopsis: if r[P1]!=r[P3] goto P2 +** +** This works just like the Eq opcode except that the jump is taken if +** the operands in registers P1 and P3 are not equal. See the Eq opcode for +** additional information. +** +** If both SQLITE_STOREP2 and SQLITE_KEEPNULL flags are set then the +** content of r[P2] is only set to 0 (false) if it was not previously NULL. +*/ /* Opcode: Lt P1 P2 P3 P4 P5 ** Synopsis: if r[P1]flags */ u16 flags3; /* Copy of initial value of pIn3->flags */ - assert( pOp->opcode!=OP_Cmp || (pOp->p5 & SQLITE_STOREP2) ); pIn1 = &aMem[pOp->p1]; pIn3 = &aMem[pOp->p3]; flags1 = pIn1->flags; @@ -2002,15 +2004,16 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ && (flags3&MEM_Null)!=0 && (flags3&MEM_Cleared)==0 ){ - res = 0; /* Results are equal */ + cmpRes = 0; /* Results are equal */ }else{ - res = 1; /* Results are not equal */ + cmpRes = 1; /* Results are not equal */ } }else{ /* SQLITE_NULLEQ is clear and at least one operand is NULL, ** then the result is always NULL. ** The jump is taken if the SQLITE_JUMPIFNULL bit is set. */ + cmpRes = 1; if( pOp->p5 & SQLITE_STOREP2 ){ pOut = &aMem[pOp->p2]; memAboutToChange(p, pOut); @@ -2063,16 +2066,15 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ sqlite3VdbeMemExpandBlob(pIn3); flags3 &= ~MEM_Zero; } - res = sqlite3MemCompare(pIn3, pIn1, pOp->p4.pColl); + cmpRes = sqlite3MemCompare(pIn3, pIn1, pOp->p4.pColl); } switch( pOp->opcode ){ - case OP_Eq: res = res==0; break; - case OP_Ne: res = res!=0; break; - case OP_Lt: res = res<0; break; - case OP_Le: res = res<=0; break; - case OP_Gt: res = res>0; break; - case OP_Ge: res = res>=0; break; - default: assert( pOp->opcode==OP_Cmp ); break; + case OP_Eq: res = cmpRes==0; break; + case OP_Ne: res = cmpRes!=0; break; + case OP_Lt: res = cmpRes<0; break; + case OP_Le: res = cmpRes<=0; break; + case OP_Gt: res = cmpRes>0; break; + case OP_Ge: res = cmpRes>=0; break; } /* Undo any changes made by applyAffinity() to the input registers. */ @@ -2083,12 +2085,18 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ if( pOp->p5 & SQLITE_STOREP2 ){ pOut = &aMem[pOp->p2]; + if( (pOp->p5 & SQLITE_KEEPNULL)!=0 && (pOut->flags & MEM_Null)!=0 ){ + /* The KEEPNULL flag prevents OP_Eq from overwriting a NULL with 1 + ** and prevents OP_Ne from overwriting NULL with 0. */ + assert( pOp->opcode==OP_Ne || pOp->opcode==OP_Eq ); + assert( res==0 || res==1 ); + if( (pOp->opcode==OP_Eq)==res ) break; + } memAboutToChange(p, pOut); MemSetTypeFlag(pOut, MEM_Int); pOut->u.i = res; REGISTER_TRACE(pOp->p2, pOut); }else{ - assert( pOp->opcode!=OP_Cmp ); VdbeBranchTaken(res!=0, (pOp->p5 & SQLITE_NULLEQ)?2:3); if( res ){ goto jump_to_p2; @@ -2097,6 +2105,22 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ break; } +/* Opcode: ElseNotEq * P2 * * * +** +** This opcode must immediately follow an Lt or Gt comparison operator. +** If the operands in that previous comparison are not equal (possibly +** because one or the other is NULL) then jump to P2. If the two operands +** of the prior comparison are equal, fall through. +*/ +case OP_ElseNotEq: { /* same as TK_ESCAPE, jump */ + assert( pOp>aOp ); + assert( pOp[-1].opcode==OP_Lt || pOp[-1].opcode==OP_Gt ); + VdbeBranchTaken(cmpRes!=0, 2); + if( cmpRes!=0 ) goto jump_to_p2; + break; +} + + /* Opcode: Permutation * * * P4 * ** ** Set the permutation used by the OP_Compare operator to be the array @@ -3885,63 +3909,6 @@ seek_not_found: break; } -/* Opcode: CmpTest P1 P2 P3 P4 * -** -** P2 is a jump destination. Register P1 is guaranteed to contain either -** an integer value or a NULL. -** -** If P3 is non-zero, it identifies an output register. In this case, if -** P1 is NULL, P3 is also set to NULL. Or, if P1 is any integer value -** other than 0, P3 is set to the value of P4 and a jump to P2 is taken. -** -** If P3 is 0, the jump is taken if P1 contains any value other than 0 (i.e. -** NULL does cause a jump). Additionally, if P1 is not NULL, its value is -** modified to integer value 0 or 1 according to the value of the P4 integer -** operand: -** -** P4 modification -** -------------------------- -** OP_Lt (P1 = (P1 < 0)) -** OP_Le (P1 = (P1 <= 0)) -** OP_Gt (P1 = (P1 > 0)) -** OP_Ge (P1 = (P1 >= 0)) -*/ -case OP_CmpTest: { /* in1, jump */ - int bJump; - pIn1 = &aMem[pOp->p1]; - - if( pOp->p3 ){ - bJump = 0; - if( pIn1->flags & MEM_Null ){ - memAboutToChange(p, &aMem[pOp->p3]); - MemSetTypeFlag(&aMem[pOp->p3], MEM_Null); - }else if( pIn1->u.i!=0 ){ - memAboutToChange(p, &aMem[pOp->p3]); - MemSetTypeFlag(&aMem[pOp->p3], MEM_Int); - aMem[pOp->p3].u.i = pOp->p4.i; - bJump = 1; - } - }else{ - if( (pIn1->flags & MEM_Int) ){ - bJump = (pIn1->u.i!=0); - switch( pOp->p4.i ){ - case OP_Lt: pIn1->u.i = (pIn1->u.i < 0); break; - case OP_Le: pIn1->u.i = (pIn1->u.i <= 0); break; - case OP_Gt: pIn1->u.i = (pIn1->u.i > 0); break; - default: - assert( pOp->p4.i==OP_Ge ); - pIn1->u.i = (pIn1->u.i >= 0); - break; - } - }else{ - bJump = 1; - } - } - - if( bJump ) goto jump_to_p2; - break; -} - /* Opcode: Found P1 P2 P3 P4 * ** Synopsis: key=r[P3@P4] ** From 460d38f15e20079c0edf47316b9ea2279a879198 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 13 Aug 2016 10:34:12 +0000 Subject: [PATCH 0699/1484] Fix an fts5 problem with corrupt database handling found by address-sanitizer. FossilOrigin-Name: e22252e1da4cd9e41b970970a1c4f466aa6cc133 --- ext/fts5/fts5_index.c | 23 +++++++++++++++++++---- ext/fts5/test/fts5corrupt2.test | 6 +++--- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 30 insertions(+), 15 deletions(-) diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index 65b92a2b99..ef36e007df 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -702,7 +702,6 @@ static Fts5Data *fts5DataRead(Fts5Index *p, i64 iRowid){ return pRet; } - /* ** Release a reference to data record returned by an earlier call to ** fts5DataRead(). @@ -711,6 +710,18 @@ static void fts5DataRelease(Fts5Data *pData){ sqlite3_free(pData); } +static Fts5Data *fts5LeafRead(Fts5Index *p, i64 iRowid){ + Fts5Data *pRet = fts5DataRead(p, iRowid); + if( pRet ){ + if( pRet->szLeaf>pRet->nn ){ + p->rc = FTS5_CORRUPT; + fts5DataRelease(pRet); + pRet = 0; + } + } + return pRet; +} + static int fts5IndexPrepareStmt( Fts5Index *p, sqlite3_stmt **ppStmt, @@ -1519,7 +1530,7 @@ static void fts5SegIterNextPage( pIter->pLeaf = pIter->pNextLeaf; pIter->pNextLeaf = 0; }else if( pIter->iLeafPgno<=pSeg->pgnoLast ){ - pIter->pLeaf = fts5DataRead(p, + pIter->pLeaf = fts5LeafRead(p, FTS5_SEGMENT_ROWID(pSeg->iSegid, pIter->iLeafPgno) ); }else{ @@ -2022,9 +2033,8 @@ static void fts5SegIterNext( if( pLeaf->nn>pLeaf->szLeaf ){ pIter->iPgidxOff = pLeaf->szLeaf + fts5GetVarint32( &pLeaf->p[pLeaf->szLeaf], pIter->iEndofDoclist - ); + ); } - } else if( pLeaf->nn>pLeaf->szLeaf ){ pIter->iPgidxOff = pLeaf->szLeaf + fts5GetVarint32( @@ -2269,6 +2279,11 @@ static void fts5LeafSeek( iTermOff += nKeep; iOff = iTermOff; + if( iOff>=n ){ + p->rc = FTS5_CORRUPT; + return; + } + /* Read the nKeep field of the next term. */ fts5FastGetVarint32(a, iOff, nKeep); } diff --git a/ext/fts5/test/fts5corrupt2.test b/ext/fts5/test/fts5corrupt2.test index 3a4fcfaaed..c10017a266 100644 --- a/ext/fts5/test/fts5corrupt2.test +++ b/ext/fts5/test/fts5corrupt2.test @@ -37,7 +37,7 @@ do_execsql_test 1.0 { } set mask [expr 31 << 31] -if 1 { +if 0 { # Test 1: # @@ -84,6 +84,8 @@ foreach {tno stmt} { } } +} + # Using the same database as the 1.* tests. # # Run N-1 tests, where N is the number of bytes in the rightmost leaf page @@ -212,8 +214,6 @@ foreach {tn nCut} { # do_test 4.$tn.x { expr $nCorrupt>0 } 1 } -} - set doc [string repeat "A B C " 1000] do_execsql_test 5.0 { CREATE VIRTUAL TABLE x5 USING fts5(tt); diff --git a/manifest b/manifest index a564676413..6436f4369f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sbuffer\soverread\sin\sfts5. -D 2016-08-13T06:38:31.533 +C Fix\san\sfts5\sproblem\swith\scorrupt\sdatabase\shandling\sfound\sby\saddress-sanitizer. +D 2016-08-13T10:34:12.755 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -104,7 +104,7 @@ F ext/fts5/fts5_buffer.c 4c1502d4c956cd092c89ce4480867f9d8bf325cd F ext/fts5/fts5_config.c 5af9c360e99669d29f06492c370892394aba0857 F ext/fts5/fts5_expr.c 1ee97156421919e497595bfa962bb88ad1665401 F ext/fts5/fts5_hash.c 880998e596b60f078348d48732ca4ad9a90caad2 -F ext/fts5/fts5_index.c 05386732609221d066d204b22c4a5275a0225ed4 +F ext/fts5/fts5_index.c 2d146d5c547f60d22d6fc4014d5e2b64248cd7c4 F ext/fts5/fts5_main.c f85281445dcf8be32d18841c93a6f90fe27dbfe2 F ext/fts5/fts5_storage.c de0ed8a06738bde433afe11e92295ceaffbc4e58 F ext/fts5/fts5_tcl.c 4a901f00c8553740dba63511603f5527d741c26a @@ -141,7 +141,7 @@ F ext/fts5/test/fts5config.test 7788b9c058074d640dfcdd81d97b6a9480000368 F ext/fts5/test/fts5conflict.test 26f4e46c4d31e16221794832a990dc4e30e18de5 F ext/fts5/test/fts5content.test 9a952c95518a14182dc3b59e3c8fa71cda82a4e1 F ext/fts5/test/fts5corrupt.test c2ad090192708150d50d961278df10ae7a4b8b62 -F ext/fts5/test/fts5corrupt2.test 26c0a39dd9ff73207e6229f83b50b21d37c7658c +F ext/fts5/test/fts5corrupt2.test 128eb6e2d26b09f4da339e581f424b3321e0fdaa F ext/fts5/test/fts5corrupt3.test f77f65e386231daf62902466b40ff998b2c8ce4f F ext/fts5/test/fts5detail.test ef5c690535a797413acaf5ad9b8ab5d49972df69 F ext/fts5/test/fts5determin.test 10648edb75ef1e196b10978fd21a9be0c31e09c3 @@ -1510,7 +1510,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ed406d31ff54ee3de8db91690a966e5c561f8f94 -R c7f71e9982fe95b86462907f7307b757 +P fcfbee6c7d33a9ae7feb46044a0c2fe680460d39 +R ca2c772c8f9b99e461286a4305c18761 U dan -Z faa5a19931d7d3892f5c4860f7744222 +Z c72588ab1f18a0198f4aa8645b38264f diff --git a/manifest.uuid b/manifest.uuid index b2e843f3ec..5e6595cd5e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fcfbee6c7d33a9ae7feb46044a0c2fe680460d39 \ No newline at end of file +e22252e1da4cd9e41b970970a1c4f466aa6cc133 \ No newline at end of file From a2f629251f764e86120dfd0bf800f8e237605a64 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 13 Aug 2016 12:37:47 +0000 Subject: [PATCH 0700/1484] Fix to the vector less-than operator. All legacy tests passing now. FossilOrigin-Name: ec70a67ebc997f457be4d52d8affc37e142dc3ff --- manifest | 17 +++++++---------- manifest.uuid | 2 +- src/expr.c | 9 +++------ test/rowvalue2.test | 1 - 4 files changed, 11 insertions(+), 18 deletions(-) diff --git a/manifest b/manifest index 1a0b48fa4a..b2cbce9bc1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Attempt\sto\ssimplify\sthe\slogic\sand\sgenerated\scode\sfor\svector\scomparisons.\nBasic\scomparison\soperators\sare\sworking,\sbut\sthere\sare\smany\sindexing\stest\nfailures\sstill\sto\sbe\sworked\sthrough. -D 2016-08-13T10:02:17.801 +C Fix\sto\sthe\svector\sless-than\soperator.\s\sAll\slegacy\stests\spassing\snow. +D 2016-08-13T12:37:47.521 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -338,7 +338,7 @@ F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7 F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b F src/dbstat.c 4f6f7f52b49beb9636ffbd517cfe44a402ba4ad0 F src/delete.c 4aba4214a377ce8ddde2d2e609777bcc8235200f -F src/expr.c 375de68ad2daf3bd339f79074ced5a6db77e2f62 +F src/expr.c d79a02ba0f5b44c3319154641247979c48eec637 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c bc4145347595b7770f9a598cff1c848302cf5413 F src/func.c 29cc9acb170ec1387b9f63eb52cd85f8de96c771 @@ -1020,7 +1020,7 @@ F test/rowallock.test 3f88ec6819489d0b2341c7a7528ae17c053ab7cc F test/rowhash.test 0bc1d31415e4575d10cacf31e1a66b5cc0f8be81 F test/rowid.test 5b7509f384f4f6fae1af3c8c104c8ca299fea18d F test/rowvalue.test 56b34d31d91340a6e922e753b798880170cc1aa7 -F test/rowvalue2.test 8d5dfe75b8f4d1868a2f91f0356f20d36cba64ff +F test/rowvalue2.test 875068299fd4dd50ef0a47786462c8e1f4065f9a F test/rowvalue3.test dbe935260851b197dfbbbcb0ac2a15cb5f324fd4 F test/rowvalue4.test ed3f7974099f0fc508c9f95df55d37c49f43be65 F test/rowvalue5.test 01c7e0bc4048f30b58e6eb27ecd26e5bd312635e @@ -1516,10 +1516,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 381aa73141db8ec59adbcb09e71af660ee4ae5ce -R b082d1240e853643b05ab20adb3ffc1b -T *branch * vector-compare -T *sym-vector-compare * -T -sym-rowvalue * +P dfc028cfbe7657d20727a2670ecadb1575eb8cbb +R 051307c8175981bed144504907ca38ff U drh -Z 873e26b27a2fd221371ad3338313919b +Z bf986d41b4b86a5837f36c1caf70f646 diff --git a/manifest.uuid b/manifest.uuid index 617135c700..b233b1a33d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -dfc028cfbe7657d20727a2670ecadb1575eb8cbb \ No newline at end of file +ec70a67ebc997f457be4d52d8affc37e142dc3ff \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 54bf0dfaba..4f02c98c45 100644 --- a/src/expr.c +++ b/src/expr.c @@ -485,14 +485,11 @@ static void codeVectorCompare( }else if( opx==TK_NE ){ sqlite3VdbeAddOp2(v, OP_If, dest, addrDone); VdbeCoverage(v); p5 |= SQLITE_KEEPNULL; - }else if( opx==op ){ - assert( op==TK_LT || op==TK_GT ); - sqlite3VdbeAddOp3(v, OP_If, dest, addrDone, 1); + }else{ + assert( op==TK_LT || op==TK_GT || op==TK_LE || op==TK_GE ); + sqlite3VdbeAddOp2(v, OP_ElseNotEq, 0, addrDone); VdbeCoverageIf(v, op==TK_LT); VdbeCoverageIf(v, op==TK_GT); - }else{ - assert( op==TK_LE || op==TK_GE ); - sqlite3VdbeAddOp2(v, OP_ElseNotEq, 0, addrDone); VdbeCoverageIf(v, op==TK_LE); VdbeCoverageIf(v, op==TK_GE); if( i==nLeft-2 ) opx = op; diff --git a/test/rowvalue2.test b/test/rowvalue2.test index c7d061e3e2..b385b23ce2 100644 --- a/test/rowvalue2.test +++ b/test/rowvalue2.test @@ -249,4 +249,3 @@ foreach {tn idx} { finish_test - From af69eda63efbb5461a86cfddd871a39134eef8e4 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 13 Aug 2016 13:03:46 +0000 Subject: [PATCH 0701/1484] Improvements to commits. No code changes. FossilOrigin-Name: 18f5a3bee4f870be4644a6042a20081c46edb7d0 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 13 +++++++------ 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index b2cbce9bc1..23cd1d16e7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sto\sthe\svector\sless-than\soperator.\s\sAll\slegacy\stests\spassing\snow. -D 2016-08-13T12:37:47.521 +C Improvements\sto\scommits.\s\sNo\scode\schanges. +D 2016-08-13T13:03:46.411 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -450,7 +450,7 @@ F src/update.c 4f05ea8cddfa367d045e03589756c02199e8f9bd F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 810ec3f22e2d1b62e66c30fe3621ebdedd23584d F src/vacuum.c 9dd2f5d276bc6094d8f1d85ecd41b30c1a002a43 -F src/vdbe.c 9816bc4f89e4d58340f3cf3354fd062e2da11f8a +F src/vdbe.c 3961408d1e4507b468b6297b79307bd3eee51988 F src/vdbe.h 67bc551f7faf04c33493892e4b378aada823ed10 F src/vdbeInt.h c59381049af5c7751a83456c39b80d1a6fde1f9d F src/vdbeapi.c c3f6715a99995c11748ecad91d25e93fd9fc390b @@ -1516,7 +1516,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P dfc028cfbe7657d20727a2670ecadb1575eb8cbb -R 051307c8175981bed144504907ca38ff +P ec70a67ebc997f457be4d52d8affc37e142dc3ff +R 247af002c746a42b304e23bb96c4f14d U drh -Z bf986d41b4b86a5837f36c1caf70f646 +Z 092630ac00e90be639ed64dcd2fc60ce diff --git a/manifest.uuid b/manifest.uuid index b233b1a33d..efc7c5409f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ec70a67ebc997f457be4d52d8affc37e142dc3ff \ No newline at end of file +18f5a3bee4f870be4644a6042a20081c46edb7d0 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index be5ca79ed5..f401f65bcd 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2004,16 +2004,16 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ && (flags3&MEM_Null)!=0 && (flags3&MEM_Cleared)==0 ){ - cmpRes = 0; /* Results are equal */ + cmpRes = 0; /* Operands are equal */ }else{ - cmpRes = 1; /* Results are not equal */ + cmpRes = 1; /* Operands are not equal */ } }else{ /* SQLITE_NULLEQ is clear and at least one operand is NULL, ** then the result is always NULL. ** The jump is taken if the SQLITE_JUMPIFNULL bit is set. */ - cmpRes = 1; + cmpRes = 1; /* Operands are not equal */ if( pOp->p5 & SQLITE_STOREP2 ){ pOut = &aMem[pOp->p2]; memAboutToChange(p, pOut); @@ -2108,9 +2108,10 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ /* Opcode: ElseNotEq * P2 * * * ** ** This opcode must immediately follow an Lt or Gt comparison operator. -** If the operands in that previous comparison are not equal (possibly -** because one or the other is NULL) then jump to P2. If the two operands -** of the prior comparison are equal, fall through. +** If the operands in that previous comparison had been used with an Eq +** operator and if the result of that Eq would be NULL or false (0), then +** then jump to P2. If the result of comparing the two previous operands +** using Eq would have been true (1), then fall through. */ case OP_ElseNotEq: { /* same as TK_ESCAPE, jump */ assert( pOp>aOp ); From 0f825a7e264f8c058d7865dce67203c033d3098b Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 13 Aug 2016 14:17:02 +0000 Subject: [PATCH 0702/1484] Remove an unnecessary stack variable from sqlite3VdbeExec(). FossilOrigin-Name: c54bd9c82dd34951dc87848c0b19fcccaef928db --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 27 +++++++++++++-------------- 3 files changed, 20 insertions(+), 21 deletions(-) diff --git a/manifest b/manifest index 23cd1d16e7..032853f761 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improvements\sto\scommits.\s\sNo\scode\schanges. -D 2016-08-13T13:03:46.411 +C Remove\san\sunnecessary\sstack\svariable\sfrom\ssqlite3VdbeExec(). +D 2016-08-13T14:17:02.223 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -450,7 +450,7 @@ F src/update.c 4f05ea8cddfa367d045e03589756c02199e8f9bd F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 810ec3f22e2d1b62e66c30fe3621ebdedd23584d F src/vacuum.c 9dd2f5d276bc6094d8f1d85ecd41b30c1a002a43 -F src/vdbe.c 3961408d1e4507b468b6297b79307bd3eee51988 +F src/vdbe.c 1b66646c30ae83db67edce52f62801e6204a6e47 F src/vdbe.h 67bc551f7faf04c33493892e4b378aada823ed10 F src/vdbeInt.h c59381049af5c7751a83456c39b80d1a6fde1f9d F src/vdbeapi.c c3f6715a99995c11748ecad91d25e93fd9fc390b @@ -1516,7 +1516,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ec70a67ebc997f457be4d52d8affc37e142dc3ff -R 247af002c746a42b304e23bb96c4f14d +P 18f5a3bee4f870be4644a6042a20081c46edb7d0 +R 4db42b6f0c7885d63148768f55fefe94 U drh -Z 092630ac00e90be639ed64dcd2fc60ce +Z 3f3cd455e86203369782a9bcddee8cc7 diff --git a/manifest.uuid b/manifest.uuid index efc7c5409f..c50c6baf38 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -18f5a3bee4f870be4644a6042a20081c46edb7d0 \ No newline at end of file +c54bd9c82dd34951dc87848c0b19fcccaef928db \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index f401f65bcd..1578d2d87e 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -573,7 +573,7 @@ int sqlite3VdbeExec( sqlite3 *db = p->db; /* The database */ u8 resetSchemaOnFault = 0; /* Reset schema after an error if positive */ u8 encoding = ENC(db); /* The database encoding */ - int iCompare = 0; /* Result of last OP_Compare operation */ + int iCompare = 0; /* Result of last comparison */ unsigned nVmStep = 0; /* Number of virtual machine steps */ #ifndef SQLITE_OMIT_PROGRESS_CALLBACK unsigned nProgressLimit = 0;/* Invoke xProgress() when nVmStep reaches this */ @@ -585,7 +585,6 @@ int sqlite3VdbeExec( Mem *pOut = 0; /* Output operand */ int *aPermute = 0; /* Permutation of columns for OP_Compare */ i64 lastRowid = db->lastRowid; /* Saved value of the last insert ROWID */ - int cmpRes; /* Result of last comparison operation */ #ifdef VDBE_PROFILE u64 start; /* CPU clock count at start of opcode */ #endif @@ -2004,16 +2003,16 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ && (flags3&MEM_Null)!=0 && (flags3&MEM_Cleared)==0 ){ - cmpRes = 0; /* Operands are equal */ + iCompare = 0; /* Operands are equal */ }else{ - cmpRes = 1; /* Operands are not equal */ + iCompare = 1; /* Operands are not equal */ } }else{ /* SQLITE_NULLEQ is clear and at least one operand is NULL, ** then the result is always NULL. ** The jump is taken if the SQLITE_JUMPIFNULL bit is set. */ - cmpRes = 1; /* Operands are not equal */ + iCompare = 1; /* Operands are not equal */ if( pOp->p5 & SQLITE_STOREP2 ){ pOut = &aMem[pOp->p2]; memAboutToChange(p, pOut); @@ -2066,15 +2065,15 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ sqlite3VdbeMemExpandBlob(pIn3); flags3 &= ~MEM_Zero; } - cmpRes = sqlite3MemCompare(pIn3, pIn1, pOp->p4.pColl); + iCompare = sqlite3MemCompare(pIn3, pIn1, pOp->p4.pColl); } switch( pOp->opcode ){ - case OP_Eq: res = cmpRes==0; break; - case OP_Ne: res = cmpRes!=0; break; - case OP_Lt: res = cmpRes<0; break; - case OP_Le: res = cmpRes<=0; break; - case OP_Gt: res = cmpRes>0; break; - case OP_Ge: res = cmpRes>=0; break; + case OP_Eq: res = iCompare==0; break; + case OP_Ne: res = iCompare!=0; break; + case OP_Lt: res = iCompare<0; break; + case OP_Le: res = iCompare<=0; break; + case OP_Gt: res = iCompare>0; break; + default: res = iCompare>=0; break; } /* Undo any changes made by applyAffinity() to the input registers. */ @@ -2116,8 +2115,8 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ case OP_ElseNotEq: { /* same as TK_ESCAPE, jump */ assert( pOp>aOp ); assert( pOp[-1].opcode==OP_Lt || pOp[-1].opcode==OP_Gt ); - VdbeBranchTaken(cmpRes!=0, 2); - if( cmpRes!=0 ) goto jump_to_p2; + VdbeBranchTaken(iCompare!=0, 2); + if( iCompare!=0 ) goto jump_to_p2; break; } From 0f5a186c4c52f87ffc31d2f6ac06e88e7a76b334 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 13 Aug 2016 14:30:23 +0000 Subject: [PATCH 0703/1484] Questionable changes to support interruptible checkpoint in ZipVFS. FossilOrigin-Name: c7a9f26d118c7a453d45fa73efa4d1ab79301659 --- manifest | 17 +++++++---------- manifest.uuid | 2 +- src/btree.c | 7 +++++++ src/sqlite.h.in | 1 + 4 files changed, 16 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index f170842c22..dba9d4bbe2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Have\swal\sfile\scheckpoints\sexit\searly\sif\sthe\ssqlite3_interrupt()\sAPI\sfunction\sis\scalled. -D 2016-08-12T16:21:15.202 +C Questionable\schanges\sto\ssupport\sinterruptible\scheckpoint\sin\sZipVFS. +D 2016-08-13T14:30:23.488 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -328,7 +328,7 @@ F src/auth.c 5c8e0f37f785f935f589496801edd19840485853 F src/backup.c 17cd25a36d49330df2bacd2cadf2a61f3b525976 F src/bitvec.c 3ee4c8b2c94ed3a7377256e18199e6ff5cf33f63 F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 -F src/btree.c 7aa56fb3545b9b84199987ba26e6316ae1abd769 +F src/btree.c a4a3ac603c88e04c1fde62b58800cd57bf536534 F src/btree.h 075c45707c0f8f8af118f739f36df8098a08b7da F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 F src/build.c 7c3c780b703c09314032c8f6e4e7c1d80241a818 @@ -386,7 +386,7 @@ F src/resolve.c 0392c6686586b1d4dac9a4106959f03ddd70e9aa F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c f3c6e9065fb34f6a23af27ec7f1f717ffbfc2ee4 F src/shell.c 79dda477be6c96eba6e952a934957ad36f87acc7 -F src/sqlite.h.in 0f7580280d1b009b507d8beec1ff0f197ba0cc99 +F src/sqlite.h.in 47e4df9bae9d474991a7e1468aab5cb1b6d49def F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae F src/sqliteInt.h d6f221a5bd572df935140beda82f357c2185a77c @@ -1511,10 +1511,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ed406d31ff54ee3de8db91690a966e5c561f8f94 -R fe020edefec096b26ead32b9e5eecd82 -T *branch * interruptible-checkpoint -T *sym-interruptible-checkpoint * -T -sym-trunk * +P 8a5f41c7b1718507524adef1a2730e99cf53270a +R 849b04c7250237751d57f7138163050e U dan -Z f50973b5d64203bd29a6b71f91836967 +Z ee26012ae6b15aa5080b28eefbd3549a diff --git a/manifest.uuid b/manifest.uuid index ee026b5b57..5e6d740c1e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8a5f41c7b1718507524adef1a2730e99cf53270a \ No newline at end of file +c7a9f26d118c7a453d45fa73efa4d1ab79301659 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index c25c594046..a32745834e 100644 --- a/src/btree.c +++ b/src/btree.c @@ -2398,6 +2398,8 @@ btree_open_out: sqlite3_free(p); *ppBtree = 0; }else{ + sqlite3_file *pFile; + /* If the B-Tree was successfully opened, set the pager-cache size to the ** default value. Except, when opening on an existing shared pager-cache, ** do not change the pager-cache size. @@ -2405,6 +2407,11 @@ btree_open_out: if( sqlite3BtreeSchema(p, 0, 0)==0 ){ sqlite3PagerSetCachesize(p->pBt->pPager, SQLITE_DEFAULT_CACHE_SIZE); } + + pFile = sqlite3PagerFile(pBt->pPager); + if( pFile->pMethods ){ + sqlite3OsFileControlHint(pFile, SQLITE_FCNTL_PDB, (void*)&pBt->db); + } } if( mutexOpen ){ assert( sqlite3_mutex_held(mutexOpen) ); diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 1ee39b6799..31e6427b12 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -1026,6 +1026,7 @@ struct sqlite3_io_methods { #define SQLITE_FCNTL_RBU 26 #define SQLITE_FCNTL_VFS_POINTER 27 #define SQLITE_FCNTL_JOURNAL_POINTER 28 +#define SQLITE_FCNTL_PDB 29 /* deprecated names */ #define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE From 0f832ddc0632d6fdfcbfd8ee62c0c8d6782ad7e6 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 16 Aug 2016 16:46:40 +0000 Subject: [PATCH 0704/1484] Fix a bug in destructor processing of Lemon. That has no impact on the SQLite grammar. The bug was introduced by prior work to optimize the Lemon-generated parser used by SQLite. FossilOrigin-Name: f9035b8e2ea331801402bcb62b203ab092949770 --- manifest | 14 +++++++------- manifest.uuid | 2 +- tool/lemon.c | 6 ++++-- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 6436f4369f..4c9f4827ce 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\sfts5\sproblem\swith\scorrupt\sdatabase\shandling\sfound\sby\saddress-sanitizer. -D 2016-08-13T10:34:12.755 +C Fix\sa\sbug\sin\sdestructor\sprocessing\sof\sLemon.\s\sThat\shas\sno\simpact\son\sthe\nSQLite\sgrammar.\s\sThe\sbug\swas\sintroduced\sby\sprior\swork\sto\soptimize\sthe\nLemon-generated\sparser\sused\sby\sSQLite. +D 2016-08-16T16:46:40.445 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -1437,7 +1437,7 @@ F tool/fuzzershell.c 94019b185caceffc9f7c7b678a6489e42bc2aefa F tool/genfkey.README cf68fddd4643bbe3ff8e31b8b6d8b0a1b85e20f4 F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5 F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce -F tool/lemon.c e3aa9ba3469804d7cae13b5e041aab192b7b381a +F tool/lemon.c e4fb7d888873ac88f20a41c84a7d1e61f5209a6d F tool/lempar.c 147e42a5cd83ce38275fde0d07a5df3330cb9b3b F tool/libvers.c caafc3b689638a1d88d44bc5f526c2278760d9b9 F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862 @@ -1510,7 +1510,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P fcfbee6c7d33a9ae7feb46044a0c2fe680460d39 -R ca2c772c8f9b99e461286a4305c18761 -U dan -Z c72588ab1f18a0198f4aa8645b38264f +P e22252e1da4cd9e41b970970a1c4f466aa6cc133 +R ee584211cd54ecf77179973501b275db +U drh +Z fc8c107a10d6a0e11da9056db2b5413b diff --git a/manifest.uuid b/manifest.uuid index 5e6595cd5e..cf08f8aea6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e22252e1da4cd9e41b970970a1c4f466aa6cc133 \ No newline at end of file +f9035b8e2ea331801402bcb62b203ab092949770 \ No newline at end of file diff --git a/tool/lemon.c b/tool/lemon.c index df758a5da6..0fa3d63b4e 100644 --- a/tool/lemon.c +++ b/tool/lemon.c @@ -263,7 +263,8 @@ struct symbol { int useCnt; /* Number of times used */ char *destructor; /* Code which executes whenever this symbol is ** popped from the stack during error processing */ - int destLineno; /* Line number for start of destructor */ + int destLineno; /* Line number for start of destructor. Set to + ** -1 for duplicate destructors. */ char *datatype; /* The data type of information held by this ** object. Only used if type==NONTERMINAL */ int dtnum; /* The data type number. In the parser, the value @@ -4385,6 +4386,7 @@ void ReportTable( for(i=0; insymbol; i++){ struct symbol *sp = lemp->symbols[i]; if( sp==0 || sp->type==TERMINAL || sp->destructor==0 ) continue; + if( sp->destLineno<0 ) continue; /* Already emitted */ fprintf(out," case %d: /* %s */\n", sp->index, sp->name); lineno++; /* Combine duplicate destructors into a single case */ @@ -4395,7 +4397,7 @@ void ReportTable( && strcmp(sp->destructor,sp2->destructor)==0 ){ fprintf(out," case %d: /* %s */\n", sp2->index, sp2->name); lineno++; - sp2->destructor = 0; + sp2->destLineno = -1; /* Avoid emitting this destructor again */ } } From 8c2b1fde584b096460c95f9e3abf8b5dc452b5d0 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 17 Aug 2016 11:14:39 +0000 Subject: [PATCH 0705/1484] Fix a problem in the fts5 snippet() auxiliary function. FossilOrigin-Name: a861713cc6a3868a1c89240e8340bc7b2b9559da --- ext/fts5/fts5_aux.c | 9 ++++++++- ext/fts5/test/fts5af.test | 3 +++ manifest | 16 ++++++++-------- manifest.uuid | 2 +- 4 files changed, 20 insertions(+), 10 deletions(-) diff --git a/ext/fts5/fts5_aux.c b/ext/fts5/fts5_aux.c index 836de8a0f0..d8147f8111 100644 --- a/ext/fts5/fts5_aux.c +++ b/ext/fts5/fts5_aux.c @@ -189,7 +189,7 @@ static int fts5HighlightCb( if( p->iRangeEnd>0 && iPos==p->iRangeEnd ){ fts5HighlightAppend(&rc, p, &p->zIn[p->iOff], iEndOff - p->iOff); p->iOff = iEndOff; - if( iPositer.iEnd ){ + if( iPos>=p->iter.iStart && iPositer.iEnd ){ fts5HighlightAppend(&rc, p, p->zClose, -1); } } @@ -350,6 +350,13 @@ static void fts5SnippetFunction( if( iBestStart>0 ){ fts5HighlightAppend(&rc, &ctx, zEllips, -1); } + + /* Advance iterator ctx.iter so that it points to the first coalesced + ** phrase instance at or following position iBestStart. */ + while( ctx.iter.iStart>=0 && ctx.iter.iStartxTokenize(pFts, ctx.zIn, ctx.nIn, (void*)&ctx,fts5HighlightCb); } diff --git a/ext/fts5/test/fts5af.test b/ext/fts5/test/fts5af.test index d6b2241568..21854662d3 100644 --- a/ext/fts5/test/fts5af.test +++ b/ext/fts5/test/fts5af.test @@ -108,6 +108,9 @@ foreach {tn doc res} { 7.4 {o o o X o o X o o} {...o [X] o o [X] o o} 7.5 {o o o o X o o X o} {...o o [X] o o [X] o} 7.6 {o o o o o X o o X} {...o o o [X] o o [X]} + + 8.1 {o o o o X o o o o o o o o o o o o o o o o o o o o o X X X o o o} + {...o o [X] [X] [X] o o...} } { do_snippet_test 1.$tn $doc X $res } diff --git a/manifest b/manifest index 4c9f4827ce..2dccb1db29 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sbug\sin\sdestructor\sprocessing\sof\sLemon.\s\sThat\shas\sno\simpact\son\sthe\nSQLite\sgrammar.\s\sThe\sbug\swas\sintroduced\sby\sprior\swork\sto\soptimize\sthe\nLemon-generated\sparser\sused\sby\sSQLite. -D 2016-08-16T16:46:40.445 +C Fix\sa\sproblem\sin\sthe\sfts5\ssnippet()\sauxiliary\sfunction. +D 2016-08-17T11:14:39.949 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -99,7 +99,7 @@ F ext/fts3/unicode/parseunicode.tcl da577d1384810fb4e2b209bf3313074353193e95 F ext/fts5/extract_api_docs.tcl a36e54ec777172ddd3f9a88daf593b00848368e0 F ext/fts5/fts5.h 62f3e33ceeb9a428db139f9c012186b371da1cc7 F ext/fts5/fts5Int.h b2eda36e0f224365c8e23dc8f559311834f1c13f -F ext/fts5/fts5_aux.c daa57fb45216491814520bbb587e97bf81ced458 +F ext/fts5/fts5_aux.c e4bec077c5190946dbaac72c6555defd823724ca F ext/fts5/fts5_buffer.c 4c1502d4c956cd092c89ce4480867f9d8bf325cd F ext/fts5/fts5_config.c 5af9c360e99669d29f06492c370892394aba0857 F ext/fts5/fts5_expr.c 1ee97156421919e497595bfa962bb88ad1665401 @@ -122,7 +122,7 @@ F ext/fts5/test/fts5ab.test 30325a89453280160106be411bba3acf138e6d1b F ext/fts5/test/fts5ac.test 55cad4275a1f5acabfe14d8442a8046b47e49e5f F ext/fts5/test/fts5ad.test 36995f0586f30f5602074e012b9224c71ec5171c F ext/fts5/test/fts5ae.test 612dcb51f4069226791ff14c17dbfb3138c56f20 -F ext/fts5/test/fts5af.test be858a96b1f5de66ba6d64f0021bd8b2408e126c +F ext/fts5/test/fts5af.test b6afd7c28ad62d546c30f387fb971f3aaebaac0d F ext/fts5/test/fts5ag.test 27180de76c03036be75ee80b93d8c5f540014071 F ext/fts5/test/fts5ah.test dfb7897711dbcda1dacb038aec310daca139fcf5 F ext/fts5/test/fts5ai.test 3909d0b949b2afcaae4d5795cd79153da75381df @@ -1510,7 +1510,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e22252e1da4cd9e41b970970a1c4f466aa6cc133 -R ee584211cd54ecf77179973501b275db -U drh -Z fc8c107a10d6a0e11da9056db2b5413b +P f9035b8e2ea331801402bcb62b203ab092949770 +R c6d38a9772924d9b143e2aa32916b131 +U dan +Z c5e29b567d02bec227e0b49d5b8a188c diff --git a/manifest.uuid b/manifest.uuid index cf08f8aea6..77bfe841ee 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f9035b8e2ea331801402bcb62b203ab092949770 \ No newline at end of file +a861713cc6a3868a1c89240e8340bc7b2b9559da \ No newline at end of file From e7036202bcc2bae5420332388dee8a74fce969a1 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 17 Aug 2016 19:05:12 +0000 Subject: [PATCH 0706/1484] Bias the fts5 snippet() function to return snippets that look like they start at the start of sentences. FossilOrigin-Name: 60de159476edbd48dc363f7f77f09c32ea68422f --- ext/fts5/fts5_aux.c | 209 +++++++++++++++++++++++++------- ext/fts5/test/fts5af.test | 5 +- ext/fts5/test/fts5unicode2.test | 4 +- manifest | 16 +-- manifest.uuid | 2 +- 5 files changed, 181 insertions(+), 55 deletions(-) diff --git a/ext/fts5/fts5_aux.c b/ext/fts5/fts5_aux.c index d8147f8111..ca55fd6b01 100644 --- a/ext/fts5/fts5_aux.c +++ b/ext/fts5/fts5_aux.c @@ -246,6 +246,115 @@ static void fts5HighlightFunction( ** End of highlight() implementation. **************************************************************************/ +/* +** Context object passed to the fts5SentenceFinderCb() function. +*/ +typedef struct Fts5SFinder Fts5SFinder; +struct Fts5SFinder { + int iPos; /* Current token position */ + int nFirstAlloc; /* Allocated size of aFirst[] */ + int nFirst; /* Number of entries in aFirst[] */ + int *aFirst; /* Array of first token in each sentence */ + const char *zDoc; /* Document being tokenized */ +}; + +/* +** Add an entry to the Fts5SFinder.aFirst[] array. Grow the array if +** necessary. Return SQLITE_OK if successful, or SQLITE_NOMEM if an +** error occurs. +*/ +static int fts5SentenceFinderAdd(Fts5SFinder *p, int iAdd){ + if( p->nFirstAlloc==p->nFirst ){ + int nNew = p->nFirstAlloc ? p->nFirstAlloc*2 : 64; + int *aNew; + + aNew = (int*)sqlite3_realloc(p->aFirst, nNew*sizeof(int)); + if( aNew==0 ) return SQLITE_NOMEM; + p->aFirst = aNew; + p->nFirstAlloc = nNew; + } + p->aFirst[p->nFirst++] = iAdd; + return SQLITE_OK; +} + +/* +** This function is an xTokenize() callback used by the auxiliary snippet() +** function. Its job is to identify tokens that are the first in a sentence. +** For each such token, an entry is added to the SFinder.aFirst[] array. +*/ +static int fts5SentenceFinderCb( + void *pContext, /* Pointer to HighlightContext object */ + int tflags, /* Mask of FTS5_TOKEN_* flags */ + const char *pToken, /* Buffer containing token */ + int nToken, /* Size of token in bytes */ + int iStartOff, /* Start offset of token */ + int iEndOff /* End offset of token */ +){ + int rc = SQLITE_OK; + + if( (tflags & FTS5_TOKEN_COLOCATED)==0 ){ + Fts5SFinder *p = (Fts5SFinder*)pContext; + if( p->iPos>0 ){ + int i; + char c = 0; + for(i=iStartOff-1; i>=0; i--){ + c = p->zDoc[i]; + if( c!=' ' && c!='\t' && c!='\n' && c!='\r' ) break; + } + if( i!=iStartOff-1 && (c=='.' || c==':') ){ + rc = fts5SentenceFinderAdd(p, p->iPos); + } + }else{ + rc = fts5SentenceFinderAdd(p, 0); + } + p->iPos++; + } + return rc; +} + +static int fts5SnippetScore( + const Fts5ExtensionApi *pApi, /* API offered by current FTS version */ + Fts5Context *pFts, /* First arg to pass to pApi functions */ + int nDocsize, /* Size of column in tokens */ + unsigned char *aSeen, /* Array with one element per query phrase */ + int iCol, /* Column to score */ + int iPos, /* Starting offset to score */ + int nToken, /* Max tokens per snippet */ + int *pnScore, /* OUT: Score */ + int *piPos /* OUT: Adjusted offset */ +){ + int rc; + int i; + int ip = 0; + int ic = 0; + int iOff = 0; + int iFirst = -1; + int nInst; + int nScore = 0; + + rc = pApi->xInstCount(pFts, &nInst); + for(i=0; ixInst(pFts, i, &ip, &ic, &iOff); + if( rc==SQLITE_OK && ic==iCol && iOff>=iPos && iOff<(iPos+nToken) ){ + nScore += (aSeen[ip] ? 1 : 1000); + aSeen[ip] = 1; + if( iFirst<0 ) iFirst = iOff; + } + } + + *pnScore = nScore; + if( piPos ){ + int iLast = iOff + pApi->xPhraseSize(pFts, ip); + int iAdj = iFirst - (nToken - (iLast-iFirst)) / 2; + + if( (iAdj+nToken)>nDocsize ) iAdj = nDocsize - nToken; + if( iAdj<0 ) iAdj = 0; + *piPos = iAdj; + } + + return rc; +} + /* ** Implementation of snippet() function. */ @@ -267,9 +376,10 @@ static void fts5SnippetFunction( unsigned char *aSeen; /* Array of "seen instance" flags */ int iBestCol; /* Column containing best snippet */ int iBestStart = 0; /* First token of best snippet */ - int iBestLast; /* Last token of best snippet */ int nBestScore = 0; /* Score of best snippet */ int nColSize = 0; /* Total size of iBestCol in tokens */ + Fts5SFinder sFinder; /* Used to find the beginnings of sentences */ + int nCol; if( nVal!=5 ){ const char *zErr = "wrong number of arguments to function snippet()"; @@ -277,13 +387,13 @@ static void fts5SnippetFunction( return; } + nCol = pApi->xColumnCount(pFts); memset(&ctx, 0, sizeof(HighlightContext)); iCol = sqlite3_value_int(apVal[0]); ctx.zOpen = (const char*)sqlite3_value_text(apVal[1]); ctx.zClose = (const char*)sqlite3_value_text(apVal[2]); zEllips = (const char*)sqlite3_value_text(apVal[3]); nToken = sqlite3_value_int(apVal[4]); - iBestLast = nToken-1; iBestCol = (iCol>=0 ? iCol : 0); nPhrase = pApi->xPhraseCount(pFts); @@ -291,43 +401,64 @@ static void fts5SnippetFunction( if( aSeen==0 ){ rc = SQLITE_NOMEM; } - if( rc==SQLITE_OK ){ rc = pApi->xInstCount(pFts, &nInst); } - for(i=0; rc==SQLITE_OK && ixInst(pFts, i, &ip, &iSnippetCol, &iStart); - if( rc==SQLITE_OK && (iCol<0 || iSnippetCol==iCol) ){ - int nScore = 1000; - int iLast = iStart - 1 + pApi->xPhraseSize(pFts, ip); - int j; - aSeen[ip] = 1; - for(j=i+1; rc==SQLITE_OK && jxInst(pFts, j, &ip, &ic, &io); - iFinal = io + pApi->xPhraseSize(pFts, ip) - 1; - if( rc==SQLITE_OK && ic==iSnippetCol && iLastiLast ) iLast = iFinal; + memset(&sFinder, 0, sizeof(Fts5SFinder)); + for(i=0; ixColumnText(pFts, i, &sFinder.zDoc, &nDoc); + if( rc!=SQLITE_OK ) break; + rc = pApi->xTokenize(pFts, + sFinder.zDoc, nDoc, (void*)&sFinder,fts5SentenceFinderCb + ); + if( rc!=SQLITE_OK ) break; + rc = pApi->xColumnSize(pFts, i, &nDocsize); + if( rc!=SQLITE_OK ) break; + + for(ii=0; rc==SQLITE_OK && iinBestScore ){ + nBestScore = nScore; + iBestCol = i; + iBestStart = sFinder.aFirst[ii]; + nColSize = nDocsize; } } - if( rc==SQLITE_OK && nScore>nBestScore ){ - iBestCol = iSnippetCol; - iBestStart = iStart; - iBestLast = iLast; - nBestScore = nScore; + for(ii=0; rc==SQLITE_OK && iixInst(pFts, ii, &ip, &ic, &io); + if( ic!=i || rc!=SQLITE_OK ) continue; + memset(aSeen, 0, nPhrase); + rc = fts5SnippetScore(pApi, pFts, nDocsize, aSeen, i, + io, nToken, &nScore, &io + ); + if( rc==SQLITE_OK && nScore>nBestScore ){ + nBestScore = nScore; + iBestCol = i; + iBestStart = io; + nColSize = nDocsize; + } } } } - if( rc==SQLITE_OK ){ - rc = pApi->xColumnSize(pFts, iBestCol, &nColSize); - } if( rc==SQLITE_OK ){ rc = pApi->xColumnText(pFts, iBestCol, &ctx.zIn, &ctx.nIn); } @@ -336,14 +467,6 @@ static void fts5SnippetFunction( rc = fts5CInstIterInit(pApi, pFts, iBestCol, &ctx.iter); } - if( (iBestStart+nToken-1)>iBestLast ){ - iBestStart -= (iBestStart+nToken-1-iBestLast) / 2; - } - if( iBestStart+nToken>nColSize ){ - iBestStart = nColSize - nToken; - } - if( iBestStart<0 ) iBestStart = 0; - ctx.iRangeStart = iBestStart; ctx.iRangeEnd = iBestStart + nToken - 1; @@ -365,15 +488,15 @@ static void fts5SnippetFunction( }else{ fts5HighlightAppend(&rc, &ctx, zEllips, -1); } - - if( rc==SQLITE_OK ){ - sqlite3_result_text(pCtx, (const char*)ctx.zOut, -1, SQLITE_TRANSIENT); - }else{ - sqlite3_result_error_code(pCtx, rc); - } - sqlite3_free(ctx.zOut); } + if( rc==SQLITE_OK ){ + sqlite3_result_text(pCtx, (const char*)ctx.zOut, -1, SQLITE_TRANSIENT); + }else{ + sqlite3_result_error_code(pCtx, rc); + } + sqlite3_free(ctx.zOut); sqlite3_free(aSeen); + sqlite3_free(sFinder.aFirst); } /************************************************************************/ diff --git a/ext/fts5/test/fts5af.test b/ext/fts5/test/fts5af.test index 21854662d3..903dd2910f 100644 --- a/ext/fts5/test/fts5af.test +++ b/ext/fts5/test/fts5af.test @@ -59,7 +59,6 @@ proc do_snippet_test {tn doc match res} { foreach {tn doc res} { - 1.1 {X o o o o o o} {[X] o o o o o o} 1.2 {o X o o o o o} {o [X] o o o o o} 1.3 {o o X o o o o} {o o [X] o o o o} @@ -111,6 +110,10 @@ foreach {tn doc res} { 8.1 {o o o o X o o o o o o o o o o o o o o o o o o o o o X X X o o o} {...o o [X] [X] [X] o o...} + 8.2 {o o o o. X o o o o o o o o o o o o o o o o o o o o o X X X o o o} + {...[X] o o o o o o...} + + } { do_snippet_test 1.$tn $doc X $res } diff --git a/ext/fts5/test/fts5unicode2.test b/ext/fts5/test/fts5unicode2.test index d3ff5128da..9fead57c07 100644 --- a/ext/fts5/test/fts5unicode2.test +++ b/ext/fts5/test/fts5unicode2.test @@ -160,11 +160,11 @@ foreach {tn query snippet} { the maximum x value. } 4 "rollback" { - ...[ROLLBACK]. Instead, the pending statement + ...Instead, the pending statement will return SQLITE_ABORT upon next access after the [ROLLBACK]. } 5 "rOllback" { - ...[ROLLBACK]. Instead, the pending statement + ...Instead, the pending statement will return SQLITE_ABORT upon next access after the [ROLLBACK]. } 6 "lang*" { diff --git a/manifest b/manifest index 2dccb1db29..4fbf53dc5a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\sin\sthe\sfts5\ssnippet()\sauxiliary\sfunction. -D 2016-08-17T11:14:39.949 +C Bias\sthe\sfts5\ssnippet()\sfunction\sto\sreturn\ssnippets\sthat\slook\slike\sthey\sstart\sat\sthe\sstart\sof\ssentences. +D 2016-08-17T19:05:12.783 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -99,7 +99,7 @@ F ext/fts3/unicode/parseunicode.tcl da577d1384810fb4e2b209bf3313074353193e95 F ext/fts5/extract_api_docs.tcl a36e54ec777172ddd3f9a88daf593b00848368e0 F ext/fts5/fts5.h 62f3e33ceeb9a428db139f9c012186b371da1cc7 F ext/fts5/fts5Int.h b2eda36e0f224365c8e23dc8f559311834f1c13f -F ext/fts5/fts5_aux.c e4bec077c5190946dbaac72c6555defd823724ca +F ext/fts5/fts5_aux.c 5921bbef4c78b86159111335135837a867f1ff8a F ext/fts5/fts5_buffer.c 4c1502d4c956cd092c89ce4480867f9d8bf325cd F ext/fts5/fts5_config.c 5af9c360e99669d29f06492c370892394aba0857 F ext/fts5/fts5_expr.c 1ee97156421919e497595bfa962bb88ad1665401 @@ -122,7 +122,7 @@ F ext/fts5/test/fts5ab.test 30325a89453280160106be411bba3acf138e6d1b F ext/fts5/test/fts5ac.test 55cad4275a1f5acabfe14d8442a8046b47e49e5f F ext/fts5/test/fts5ad.test 36995f0586f30f5602074e012b9224c71ec5171c F ext/fts5/test/fts5ae.test 612dcb51f4069226791ff14c17dbfb3138c56f20 -F ext/fts5/test/fts5af.test b6afd7c28ad62d546c30f387fb971f3aaebaac0d +F ext/fts5/test/fts5af.test 38bfc8c3f2fd4687a37ae3a0d4d64e029273df36 F ext/fts5/test/fts5ag.test 27180de76c03036be75ee80b93d8c5f540014071 F ext/fts5/test/fts5ah.test dfb7897711dbcda1dacb038aec310daca139fcf5 F ext/fts5/test/fts5ai.test 3909d0b949b2afcaae4d5795cd79153da75381df @@ -190,7 +190,7 @@ F ext/fts5/test/fts5tok1.test beb894c6f3468f10a574302f69ebe4436b0287c7 F ext/fts5/test/fts5tok2.test dcacb32d4a2a3f0dd3215d4a3987f78ae4be21a2 F ext/fts5/test/fts5tokenizer.test ea4df698b35cc427ebf2ba22829d0e28386d8c89 F ext/fts5/test/fts5unicode.test fbef8d8a3b4b88470536cc57604a82ca52e51841 -F ext/fts5/test/fts5unicode2.test c1dd890ba32b7609adba78e420faa847abe43b59 +F ext/fts5/test/fts5unicode2.test cb4918278514eeb6f398a28ce71ba52934f50ce5 F ext/fts5/test/fts5unicode3.test 35c3d02aa7acf7d43d8de3bfe32c15ba96e8928e F ext/fts5/test/fts5unindexed.test e9539d5b78c677315e7ed8ea911d4fd25437c680 F ext/fts5/test/fts5update.test 57c7012a7919889048947addae10e0613df45529 @@ -1510,7 +1510,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P f9035b8e2ea331801402bcb62b203ab092949770 -R c6d38a9772924d9b143e2aa32916b131 +P a861713cc6a3868a1c89240e8340bc7b2b9559da +R ddec9217c48a760254ac22da18301cf5 U dan -Z c5e29b567d02bec227e0b49d5b8a188c +Z 28e0d85dd23359fe591994acb5271e6f diff --git a/manifest.uuid b/manifest.uuid index 77bfe841ee..cfefaabd19 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a861713cc6a3868a1c89240e8340bc7b2b9559da \ No newline at end of file +60de159476edbd48dc363f7f77f09c32ea68422f \ No newline at end of file From 69c338263abbd1bf5aa2621daddda708feb80beb Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 18 Aug 2016 14:33:11 +0000 Subject: [PATCH 0707/1484] Rename the Db.zName field to Db.zDbSName to make it more descriptive and to distinguish it from all of the other "zName" variables scattered throughout the code. FossilOrigin-Name: 92a22f01343a898455fd61c3b8e7d7c954f5b569 --- manifest | 56 ++++++++++++++++++++++++------------------------- manifest.uuid | 2 +- src/alter.c | 4 ++-- src/analyze.c | 12 +++++------ src/attach.c | 10 ++++----- src/auth.c | 6 +++--- src/build.c | 53 +++++++++++++++++++++++----------------------- src/dbstat.c | 4 ++-- src/delete.c | 4 ++-- src/fkey.c | 2 +- src/insert.c | 2 +- src/main.c | 6 +++--- src/pragma.c | 14 ++++++------- src/prepare.c | 6 +++--- src/resolve.c | 4 ++-- src/select.c | 2 +- src/sqliteInt.h | 2 +- src/trigger.c | 16 +++++++------- src/update.c | 2 +- src/vacuum.c | 2 +- src/vdbe.c | 8 +++---- src/vdbeapi.c | 2 +- src/vdbeblob.c | 2 +- src/vtab.c | 10 ++++----- 24 files changed, 117 insertions(+), 114 deletions(-) diff --git a/manifest b/manifest index 2dccb1db29..28fe5360f6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\sin\sthe\sfts5\ssnippet()\sauxiliary\sfunction. -D 2016-08-17T11:14:39.949 +C Rename\sthe\sDb.zName\sfield\sto\sDb.zDbSName\sto\smake\sit\smore\sdescriptive\sand\sto\ndistinguish\sit\sfrom\sall\sof\sthe\sother\s"zName"\svariables\sscattered\sthroughout\nthe\scode. +D 2016-08-18T14:33:11.816 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -321,35 +321,35 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a -F src/alter.c cc28ab933ae615b22add0d609794ffb6596b42ea -F src/analyze.c 37fedc80ac966ce1745811746e68e4d8fa64c7fe -F src/attach.c 771153bd1f4ab0b97a44a13dde2c7e5e1efeba22 -F src/auth.c 5c8e0f37f785f935f589496801edd19840485853 +F src/alter.c 299117695b1f21ac62dfc5b608588810ba22ed0d +F src/analyze.c 8b62b2cf4da85451534ac0af82cafc418d837f68 +F src/attach.c 4711ff365df4072b8c3dcd55db5d12dcf8ffa0c6 +F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792 F src/backup.c 17cd25a36d49330df2bacd2cadf2a61f3b525976 F src/bitvec.c 3ee4c8b2c94ed3a7377256e18199e6ff5cf33f63 F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 F src/btree.c 2551bd3ecb8b8988fb8b23aabadfb214dbc38e46 F src/btree.h 075c45707c0f8f8af118f739f36df8098a08b7da F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 -F src/build.c 7c3c780b703c09314032c8f6e4e7c1d80241a818 +F src/build.c c38fd92a8d886a5b9397267bf63b76ebad05c4d5 F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7 F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b -F src/dbstat.c 4f6f7f52b49beb9636ffbd517cfe44a402ba4ad0 -F src/delete.c 4aba4214a377ce8ddde2d2e609777bcc8235200f +F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d +F src/delete.c 76c084f0265f4a3cd1ecf17eee112a94f1ccbc05 F src/expr.c 9c5eca8602f6c496e8d4eefefe2aae3d831dd510 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb -F src/fkey.c bc4145347595b7770f9a598cff1c848302cf5413 +F src/fkey.c e2be0968c1adc679c87e467aa5b4f167588f38a8 F src/func.c 29cc9acb170ec1387b9f63eb52cd85f8de96c771 F src/global.c c45ea22aff29334f6a9ec549235ac3357c970015 F src/hash.c 55b5fb474100cee0b901edaf203e26c970940f36 F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4 F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da -F src/insert.c 8f4e9fcbd8e95e85f15647ba8b413b18d556ec2b +F src/insert.c d5cd8315c0577e86e17dda9239b45cffa81022c0 F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e F src/loadext.c dd7a2b77902cc66c22555aef02e1a682554b7aec -F src/main.c 16c1b2114eae8804caf3a8de8cb47bf2c6d83ad3 +F src/main.c 8dc7adfeace35ee1f4c489b503ee8fe6bc1fa802 F src/malloc.c 1443d1ad95d67c21d77af7ae3f44678252f0efec F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b @@ -377,19 +377,19 @@ F src/parse.y 99b676e6fc2f4e331ab93e76b3987cffdbd28efa F src/pcache.c 5583c8ade4b05075a60ba953ef471d1c1a9c05df F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 F src/pcache1.c 4bb7a6a5300c67d0b033d25adb509c120c03e812 -F src/pragma.c c8b499756658cb8b82cfdbb5845c22cf11f297aa +F src/pragma.c d932ba278654617cdd281f88a790a3185fca7c44 F src/pragma.h 64c78a648751b9f4f297276c4eb7507b14b4628c -F src/prepare.c 22df6171aec1d86904ed2ad30c2348a5748aa04e +F src/prepare.c a668988f324961397305b8352cf6bd87776fb347 F src/printf.c a5f0ca08ddede803c241266abb46356ec748ded1 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 -F src/resolve.c 0392c6686586b1d4dac9a4106959f03ddd70e9aa +F src/resolve.c d67b9a5cc33339256e2088c5a722745fc2ff5219 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac -F src/select.c f3c6e9065fb34f6a23af27ec7f1f717ffbfc2ee4 +F src/select.c 890c32eab22061b57eb2bddcbb55d6af87db7d12 F src/shell.c 79dda477be6c96eba6e952a934957ad36f87acc7 F src/sqlite.h.in 0f7580280d1b009b507d8beec1ff0f197ba0cc99 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae -F src/sqliteInt.h d6f221a5bd572df935140beda82f357c2185a77c +F src/sqliteInt.h f81e279da1bae217d9afcc60d5580a0d4615727e F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 @@ -445,21 +445,21 @@ F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c 78c8085bc7af1922aa687f0f4bbd716821330de5 F src/treeview.c c56d6ddbed564efda746236b35bcbb8238daac4b -F src/trigger.c e14840ee0c3e549e758ec9bf3e4146e166002280 -F src/update.c 4f05ea8cddfa367d045e03589756c02199e8f9bd +F src/trigger.c 11e20b3b12c847b3b9055594c0f1631266bb53fc +F src/update.c 8179e699dbd45b92934fd02d3d8e3732e8da8802 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 810ec3f22e2d1b62e66c30fe3621ebdedd23584d -F src/vacuum.c 9dd2f5d276bc6094d8f1d85ecd41b30c1a002a43 -F src/vdbe.c ea260b61e73b11a71e70b28a8e25866e2899e5da +F src/vacuum.c f6f10c88f8af5feb6b3632e5e4133e4482819c4f +F src/vdbe.c 6242a21f22a68899db5e758c69a32cad163585e2 F src/vdbe.h 67bc551f7faf04c33493892e4b378aada823ed10 F src/vdbeInt.h c59381049af5c7751a83456c39b80d1a6fde1f9d -F src/vdbeapi.c c3f6715a99995c11748ecad91d25e93fd9fc390b +F src/vdbeapi.c a32d61b7dd05e6890d8fd44d2805f55e2f5ba9f3 F src/vdbeaux.c a32d79aeaa88dc2b97c261172d952d395254a055 -F src/vdbeblob.c 83d2d266383157b02e2b809350bb197e89d7895b +F src/vdbeblob.c 3e82a797b60c3b9fed7b8de8c539ca7607874937 F src/vdbemem.c 1ecaa5ee0caff07255f25d04e8dc88befb6f88d1 F src/vdbesort.c 91fda3909326860382b0ca8aa251e609c6a9d62c F src/vdbetrace.c 41963d5376f0349842b5fc4aaaaacd7d9cdc0834 -F src/vtab.c 6b3cfaff7e4397739d6b48511e777ca58c6d06d4 +F src/vtab.c 5ca4fa8b028f9e2ed4793ee1670911a83cfcefd8 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 02eeecc265f6ffd0597378f5d8ae9070b62a406a F src/wal.h 6dd221ed384afdc204bc61e25c23ef7fd5a511f2 @@ -1510,7 +1510,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P f9035b8e2ea331801402bcb62b203ab092949770 -R c6d38a9772924d9b143e2aa32916b131 -U dan -Z c5e29b567d02bec227e0b49d5b8a188c +P a861713cc6a3868a1c89240e8340bc7b2b9559da +R 99cc7186f7854d08151b32f71928925d +U drh +Z 208eab983f2b557e0d2dff78ec685958 diff --git a/manifest.uuid b/manifest.uuid index 77bfe841ee..7bc875b985 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a861713cc6a3868a1c89240e8340bc7b2b9559da \ No newline at end of file +92a22f01343a898455fd61c3b8e7d7c954f5b569 \ No newline at end of file diff --git a/src/alter.c b/src/alter.c index 806ed49172..2c86a8bac2 100644 --- a/src/alter.c +++ b/src/alter.c @@ -413,7 +413,7 @@ void sqlite3AlterRenameTable( pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]); if( !pTab ) goto exit_rename_table; iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); - zDb = db->aDb[iDb].zName; + zDb = db->aDb[iDb].zDbSName; db->flags |= SQLITE_PreferBuiltin; /* Get a NULL terminated version of the new table name. */ @@ -611,7 +611,7 @@ void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){ assert( sqlite3BtreeHoldsAllMutexes(db) ); iDb = sqlite3SchemaToIndex(db, pNew->pSchema); - zDb = db->aDb[iDb].zName; + zDb = db->aDb[iDb].zDbSName; zTab = &pNew->zName[16]; /* Skip the "sqlite_altertab_" prefix on the name */ pCol = &pNew->aCol[pNew->nCol-1]; pDflt = pCol->pDflt; diff --git a/src/analyze.c b/src/analyze.c index 3a81c93245..e3955f3022 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -210,14 +210,14 @@ static void openStatTable( for(i=0; izName))==0 ){ + if( (pStat = sqlite3FindTable(db, zTab, pDb->zDbSName))==0 ){ if( aTable[i].zCols ){ /* The sqlite_statN table does not exist. Create it. Note that a ** side-effect of the CREATE TABLE statement is to leave the rootpage ** of the new table in register pParse->regRoot. This is important ** because the OpenWrite opcode below will be needing it. */ sqlite3NestedParse(pParse, - "CREATE TABLE %Q.%s(%s)", pDb->zName, zTab, aTable[i].zCols + "CREATE TABLE %Q.%s(%s)", pDb->zDbSName, zTab, aTable[i].zCols ); aRoot[i] = pParse->regRoot; aCreateTbl[i] = OPFLAG_P2ISREG; @@ -232,7 +232,7 @@ static void openStatTable( if( zWhere ){ sqlite3NestedParse(pParse, "DELETE FROM %Q.%s WHERE %s=%Q", - pDb->zName, zTab, zWhereType, zWhere + pDb->zDbSName, zTab, zWhereType, zWhere ); }else{ /* The sqlite_stat[134] table already exists. Delete all rows. */ @@ -994,7 +994,7 @@ static void analyzeOneTable( assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); #ifndef SQLITE_OMIT_AUTHORIZATION if( sqlite3AuthCheck(pParse, SQLITE_ANALYZE, pTab->zName, 0, - db->aDb[iDb].zName ) ){ + db->aDb[iDb].zDbSName ) ){ return; } #endif @@ -1384,7 +1384,7 @@ void sqlite3Analyze(Parse *pParse, Token *pName1, Token *pName2){ /* Form 3: Analyze the fully qualified table name */ iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pTableName); if( iDb>=0 ){ - zDb = db->aDb[iDb].zName; + zDb = db->aDb[iDb].zDbSName; z = sqlite3NameFromToken(db, pTableName); if( z ){ if( (pIdx = sqlite3FindIndex(db, z, zDb))!=0 ){ @@ -1844,7 +1844,7 @@ int sqlite3AnalysisLoad(sqlite3 *db, int iDb){ /* Load new statistics out of the sqlite_stat1 table */ sInfo.db = db; - sInfo.zDatabase = db->aDb[iDb].zName; + sInfo.zDatabase = db->aDb[iDb].zDbSName; if( sqlite3FindTable(db, "sqlite_stat1", sInfo.zDatabase)!=0 ){ zSql = sqlite3MPrintf(db, "SELECT tbl,idx,stat FROM %Q.sqlite_stat1", sInfo.zDatabase); diff --git a/src/attach.c b/src/attach.c index ea378a40a2..5d2a55278d 100644 --- a/src/attach.c +++ b/src/attach.c @@ -97,7 +97,7 @@ static void attachFunc( goto attach_error; } for(i=0; inDb; i++){ - char *z = db->aDb[i].zName; + char *z = db->aDb[i].zDbSName; assert( z && zName ); if( sqlite3StrICmp(z, zName)==0 ){ zErrDyn = sqlite3MPrintf(db, "database %s is already in use", zName); @@ -162,8 +162,8 @@ static void attachFunc( sqlite3BtreeLeave(aNew->pBt); } aNew->safety_level = SQLITE_DEFAULT_SYNCHRONOUS+1; - aNew->zName = sqlite3DbStrDup(db, zName); - if( rc==SQLITE_OK && aNew->zName==0 ){ + aNew->zDbSName = sqlite3DbStrDup(db, zName); + if( rc==SQLITE_OK && aNew->zDbSName==0 ){ rc = SQLITE_NOMEM_BKPT; } @@ -275,7 +275,7 @@ static void detachFunc( for(i=0; inDb; i++){ pDb = &db->aDb[i]; if( pDb->pBt==0 ) continue; - if( sqlite3StrICmp(pDb->zName, zName)==0 ) break; + if( sqlite3StrICmp(pDb->zDbSName, zName)==0 ) break; } if( i>=db->nDb ){ @@ -433,7 +433,7 @@ void sqlite3FixInit( db = pParse->db; assert( db->nDb>iDb ); pFix->pParse = pParse; - pFix->zDb = db->aDb[iDb].zName; + pFix->zDb = db->aDb[iDb].zDbSName; pFix->pSchema = db->aDb[iDb].pSchema; pFix->zType = zType; pFix->pName = pName; diff --git a/src/auth.c b/src/auth.c index 8a3f8e7d08..77a95d4a8f 100644 --- a/src/auth.c +++ b/src/auth.c @@ -107,9 +107,9 @@ int sqlite3AuthReadCol( const char *zCol, /* Column name */ int iDb /* Index of containing database. */ ){ - sqlite3 *db = pParse->db; /* Database handle */ - char *zDb = db->aDb[iDb].zName; /* Name of attached database */ - int rc; /* Auth callback return code */ + sqlite3 *db = pParse->db; /* Database handle */ + char *zDb = db->aDb[iDb].zDbSName; /* Schema name of attached database */ + int rc; /* Auth callback return code */ if( db->init.busy ) return SQLITE_OK; rc = db->xAuth(db->pAuthArg, SQLITE_READ, zTab,zCol,zDb,pParse->zAuthContext diff --git a/src/build.c b/src/build.c index b14e6f2fc2..bf7080ed49 100644 --- a/src/build.c +++ b/src/build.c @@ -318,10 +318,11 @@ Table *sqlite3FindTable(sqlite3 *db, const char *zName, const char *zDatabase){ #endif for(i=OMIT_TEMPDB; inDb; i++){ int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */ - if( zDatabase!=0 && sqlite3StrICmp(zDatabase, db->aDb[j].zName) ) continue; - assert( sqlite3SchemaMutexHeld(db, j, 0) ); - p = sqlite3HashFind(&db->aDb[j].pSchema->tblHash, zName); - if( p ) break; + if( zDatabase==0 || sqlite3StrICmp(zDatabase, db->aDb[j].zDbSName)==0 ){ + assert( sqlite3SchemaMutexHeld(db, j, 0) ); + p = sqlite3HashFind(&db->aDb[j].pSchema->tblHash, zName); + if( p ) break; + } } return p; } @@ -395,7 +396,7 @@ Table *sqlite3LocateTableItem( assert( p->pSchema==0 || p->zDatabase==0 ); if( p->pSchema ){ int iDb = sqlite3SchemaToIndex(pParse->db, p->pSchema); - zDb = pParse->db->aDb[iDb].zName; + zDb = pParse->db->aDb[iDb].zDbSName; }else{ zDb = p->zDatabase; } @@ -423,7 +424,7 @@ Index *sqlite3FindIndex(sqlite3 *db, const char *zName, const char *zDb){ int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */ Schema *pSchema = db->aDb[j].pSchema; assert( pSchema ); - if( zDb && sqlite3StrICmp(zDb, db->aDb[j].zName) ) continue; + if( zDb && sqlite3StrICmp(zDb, db->aDb[j].zDbSName) ) continue; assert( sqlite3SchemaMutexHeld(db, j, 0) ); p = sqlite3HashFind(&pSchema->idxHash, zName); if( p ) break; @@ -492,8 +493,8 @@ void sqlite3CollapseDatabaseArray(sqlite3 *db){ for(i=j=2; inDb; i++){ struct Db *pDb = &db->aDb[i]; if( pDb->pBt==0 ){ - sqlite3DbFree(db, pDb->zName); - pDb->zName = 0; + sqlite3DbFree(db, pDb->zDbSName); + pDb->zDbSName = 0; continue; } if( jnDb-1), pDb=&db->aDb[i]; i>=0; i--, pDb--){ - if( 0==sqlite3StrICmp(pDb->zName, zName) ) break; + if( 0==sqlite3StrICmp(pDb->zDbSName, zName) ) break; } } return i; @@ -883,7 +884,7 @@ void sqlite3StartTable( SQLITE_CREATE_VIEW, SQLITE_CREATE_TEMP_VIEW }; - char *zDb = db->aDb[iDb].zName; + char *zDb = db->aDb[iDb].zDbSName; if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(isTemp), 0, zDb) ){ goto begin_table_error; } @@ -902,7 +903,7 @@ void sqlite3StartTable( ** collisions. */ if( !IN_DECLARE_VTAB ){ - char *zDb = db->aDb[iDb].zName; + char *zDb = db->aDb[iDb].zDbSName; if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ goto begin_table_error; } @@ -1995,7 +1996,7 @@ void sqlite3EndTable( "UPDATE %Q.%s " "SET type='%s', name=%Q, tbl_name=%Q, rootpage=#%d, sql=%Q " "WHERE rowid=#%d", - db->aDb[iDb].zName, SCHEMA_TABLE(iDb), + db->aDb[iDb].zDbSName, SCHEMA_TABLE(iDb), zType, p->zName, p->zName, @@ -2016,7 +2017,7 @@ void sqlite3EndTable( if( pDb->pSchema->pSeqTab==0 ){ sqlite3NestedParse(pParse, "CREATE TABLE %Q.sqlite_sequence(name,seq)", - pDb->zName + pDb->zDbSName ); } } @@ -2330,7 +2331,7 @@ static void destroyRootPage(Parse *pParse, int iTable, int iDb){ */ sqlite3NestedParse(pParse, "UPDATE %Q.%s SET rootpage=%d WHERE #%d AND rootpage=#%d", - pParse->db->aDb[iDb].zName, SCHEMA_TABLE(iDb), iTable, r1, r1); + pParse->db->aDb[iDb].zDbSName, SCHEMA_TABLE(iDb), iTable, r1, r1); #endif sqlite3ReleaseTempReg(pParse, r1); } @@ -2406,7 +2407,7 @@ static void sqlite3ClearStatTables( const char *zName /* Name of index or table */ ){ int i; - const char *zDbName = pParse->db->aDb[iDb].zName; + const char *zDbName = pParse->db->aDb[iDb].zDbSName; for(i=1; i<=4; i++){ char zTab[24]; sqlite3_snprintf(sizeof(zTab),zTab,"sqlite_stat%d",i); @@ -2459,7 +2460,7 @@ void sqlite3CodeDropTable(Parse *pParse, Table *pTab, int iDb, int isView){ if( pTab->tabFlags & TF_Autoincrement ){ sqlite3NestedParse(pParse, "DELETE FROM %Q.sqlite_sequence WHERE name=%Q", - pDb->zName, pTab->zName + pDb->zDbSName, pTab->zName ); } #endif @@ -2473,7 +2474,7 @@ void sqlite3CodeDropTable(Parse *pParse, Table *pTab, int iDb, int isView){ */ sqlite3NestedParse(pParse, "DELETE FROM %Q.%s WHERE tbl_name=%Q and type!='trigger'", - pDb->zName, SCHEMA_TABLE(iDb), pTab->zName); + pDb->zDbSName, SCHEMA_TABLE(iDb), pTab->zName); if( !isView && !IsVirtual(pTab) ){ destroyTable(pParse, pTab); } @@ -2527,7 +2528,7 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){ { int code; const char *zTab = SCHEMA_TABLE(iDb); - const char *zDb = db->aDb[iDb].zName; + const char *zDb = db->aDb[iDb].zDbSName; const char *zArg2 = 0; if( sqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb)){ goto exit_drop_table; @@ -2768,7 +2769,7 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){ #ifndef SQLITE_OMIT_AUTHORIZATION if( sqlite3AuthCheck(pParse, SQLITE_REINDEX, pIndex->zName, 0, - db->aDb[iDb].zName ) ){ + db->aDb[iDb].zDbSName ) ){ return; } #endif @@ -3020,7 +3021,7 @@ void sqlite3CreateIndex( goto exit_create_index; } } - if( sqlite3FindIndex(db, zName, pDb->zName)!=0 ){ + if( sqlite3FindIndex(db, zName, pDb->zDbSName)!=0 ){ if( !ifNotExist ){ sqlite3ErrorMsg(pParse, "index %s already exists", zName); }else{ @@ -3050,7 +3051,7 @@ void sqlite3CreateIndex( */ #ifndef SQLITE_OMIT_AUTHORIZATION { - const char *zDb = pDb->zName; + const char *zDb = pDb->zDbSName; if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(iDb), 0, zDb) ){ goto exit_create_index; } @@ -3365,7 +3366,7 @@ void sqlite3CreateIndex( */ sqlite3NestedParse(pParse, "INSERT INTO %Q.%s VALUES('index',%Q,%Q,#%d,%Q);", - db->aDb[iDb].zName, SCHEMA_TABLE(iDb), + db->aDb[iDb].zDbSName, SCHEMA_TABLE(iDb), pIndex->zName, pTab->zName, iMem, @@ -3499,7 +3500,7 @@ void sqlite3DropIndex(Parse *pParse, SrcList *pName, int ifExists){ { int code = SQLITE_DROP_INDEX; Table *pTab = pIndex->pTable; - const char *zDb = db->aDb[iDb].zName; + const char *zDb = db->aDb[iDb].zDbSName; const char *zTab = SCHEMA_TABLE(iDb); if( sqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb) ){ goto exit_drop_index; @@ -3517,7 +3518,7 @@ void sqlite3DropIndex(Parse *pParse, SrcList *pName, int ifExists){ sqlite3BeginWriteOperation(pParse, 1, iDb); sqlite3NestedParse(pParse, "DELETE FROM %Q.%s WHERE name=%Q AND type='index'", - db->aDb[iDb].zName, SCHEMA_TABLE(iDb), pIndex->zName + db->aDb[iDb].zDbSName, SCHEMA_TABLE(iDb), pIndex->zName ); sqlite3ClearStatTables(pParse, iDb, "idx", pIndex->zName); sqlite3ChangeCookie(pParse, iDb); @@ -4062,7 +4063,7 @@ void sqlite3CodeVerifyNamedSchema(Parse *pParse, const char *zDb){ int i; for(i=0; inDb; i++){ Db *pDb = &db->aDb[i]; - if( pDb->pBt && (!zDb || 0==sqlite3StrICmp(zDb, pDb->zName)) ){ + if( pDb->pBt && (!zDb || 0==sqlite3StrICmp(zDb, pDb->zDbSName)) ){ sqlite3CodeVerifySchema(pParse, i); } } @@ -4309,7 +4310,7 @@ void sqlite3Reindex(Parse *pParse, Token *pName1, Token *pName2){ if( iDb<0 ) return; z = sqlite3NameFromToken(db, pObjName); if( z==0 ) return; - zDb = db->aDb[iDb].zName; + zDb = db->aDb[iDb].zDbSName; pTab = sqlite3FindTable(db, z, zDb); if( pTab ){ reindexTable(pParse, pTab, 0); diff --git a/src/dbstat.c b/src/dbstat.c index 92ce650df1..13974bb979 100644 --- a/src/dbstat.c +++ b/src/dbstat.c @@ -602,7 +602,7 @@ static int statFilter( " UNION ALL " "SELECT name, rootpage, type" " FROM \"%w\".%s WHERE rootpage!=0" - " ORDER BY name", pTab->db->aDb[pCsr->iDb].zName, zMaster); + " ORDER BY name", pTab->db->aDb[pCsr->iDb].zDbSName, zMaster); if( zSql==0 ){ return SQLITE_NOMEM_BKPT; }else{ @@ -656,7 +656,7 @@ static int statColumn( default: { /* schema */ sqlite3 *db = sqlite3_context_db_handle(ctx); int iDb = pCsr->iDb; - sqlite3_result_text(ctx, db->aDb[iDb].zName, -1, SQLITE_STATIC); + sqlite3_result_text(ctx, db->aDb[iDb].zDbSName, -1, SQLITE_STATIC); break; } } diff --git a/src/delete.c b/src/delete.c index e9e669e21c..3d9360e925 100644 --- a/src/delete.c +++ b/src/delete.c @@ -102,7 +102,7 @@ void sqlite3MaterializeView( if( pFrom ){ assert( pFrom->nSrc==1 ); pFrom->a[0].zName = sqlite3DbStrDup(db, pView->zName); - pFrom->a[0].zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zName); + pFrom->a[0].zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zDbSName); assert( pFrom->a[0].pOn==0 ); assert( pFrom->a[0].pUsing==0 ); } @@ -289,7 +289,7 @@ void sqlite3DeleteFrom( } iDb = sqlite3SchemaToIndex(db, pTab->pSchema); assert( iDbnDb ); - zDb = db->aDb[iDb].zName; + zDb = db->aDb[iDb].zDbSName; rcauth = sqlite3AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, zDb); assert( rcauth==SQLITE_OK || rcauth==SQLITE_DENY || rcauth==SQLITE_IGNORE ); if( rcauth==SQLITE_DENY ){ diff --git a/src/fkey.c b/src/fkey.c index 25d9f84917..609c3c6017 100644 --- a/src/fkey.c +++ b/src/fkey.c @@ -871,7 +871,7 @@ void sqlite3FkCheck( if( (db->flags&SQLITE_ForeignKeys)==0 ) return; iDb = sqlite3SchemaToIndex(db, pTab->pSchema); - zDb = db->aDb[iDb].zName; + zDb = db->aDb[iDb].zDbSName; /* Loop through all the foreign key constraints for which pTab is the ** child table (the table that the foreign key definition is part of). */ diff --git a/src/insert.c b/src/insert.c index 5dc045ab69..dacd37c7f1 100644 --- a/src/insert.c +++ b/src/insert.c @@ -547,7 +547,7 @@ void sqlite3Insert( iDb = sqlite3SchemaToIndex(db, pTab->pSchema); assert( iDbnDb ); pDb = &db->aDb[iDb]; - zDb = pDb->zName; + zDb = pDb->zDbSName; if( sqlite3AuthCheck(pParse, SQLITE_INSERT, pTab->zName, 0, zDb) ){ goto insert_cleanup; } diff --git a/src/main.c b/src/main.c index f31f865818..e719e76289 100644 --- a/src/main.c +++ b/src/main.c @@ -2932,9 +2932,9 @@ static int openDatabase( /* The default safety_level for the main database is FULL; for the temp ** database it is OFF. This matches the pager layer defaults. */ - db->aDb[0].zName = "main"; + db->aDb[0].zDbSName = "main"; db->aDb[0].safety_level = SQLITE_DEFAULT_SYNCHRONOUS+1; - db->aDb[1].zName = "temp"; + db->aDb[1].zDbSName = "temp"; db->aDb[1].safety_level = PAGER_SYNCHRONOUS_OFF; db->magic = SQLITE_MAGIC_OPEN; @@ -3895,7 +3895,7 @@ Btree *sqlite3DbNameToBtree(sqlite3 *db, const char *zDbName){ int i; for(i=0; inDb; i++){ if( db->aDb[i].pBt - && (zDbName==0 || sqlite3StrICmp(zDbName, db->aDb[i].zName)==0) + && (zDbName==0 || sqlite3StrICmp(zDbName, db->aDb[i].zDbSName)==0) ){ return db->aDb[i].pBt; } diff --git a/src/pragma.c b/src/pragma.c index 1ee08fbec0..e774de3421 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -338,7 +338,7 @@ void sqlite3Pragma( } assert( pId2 ); - zDb = pId2->n>0 ? pDb->zName : 0; + zDb = pId2->n>0 ? pDb->zDbSName : 0; if( sqlite3AuthCheck(pParse, SQLITE_PRAGMA, zLeft, zRight, zDb) ){ goto pragma_out; } @@ -1191,10 +1191,10 @@ void sqlite3Pragma( setAllColumnNames(v, 3, azCol); assert( 3==ArraySize(azCol) ); for(i=0; inDb; i++){ if( db->aDb[i].pBt==0 ) continue; - assert( db->aDb[i].zName!=0 ); + assert( db->aDb[i].zDbSName!=0 ); sqlite3VdbeMultiLoad(v, 1, "iss", i, - db->aDb[i].zName, + db->aDb[i].zDbSName, sqlite3BtreeGetFilename(db->aDb[i].pBt)); sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 3); } @@ -1483,7 +1483,7 @@ void sqlite3Pragma( sqlite3VdbeChangeP5(v, (u8)i); addr = sqlite3VdbeAddOp1(v, OP_IsNull, 2); VdbeCoverage(v); sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, - sqlite3MPrintf(db, "*** in database %s ***\n", db->aDb[i].zName), + sqlite3MPrintf(db, "*** in database %s ***\n", db->aDb[i].zDbSName), P4_DYNAMIC); sqlite3VdbeAddOp3(v, OP_Move, 2, 4, 1); sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 2); @@ -1922,15 +1922,15 @@ void sqlite3Pragma( Btree *pBt; const char *zState = "unknown"; int j; - if( db->aDb[i].zName==0 ) continue; + if( db->aDb[i].zDbSName==0 ) continue; pBt = db->aDb[i].pBt; if( pBt==0 || sqlite3BtreePager(pBt)==0 ){ zState = "closed"; - }else if( sqlite3_file_control(db, i ? db->aDb[i].zName : 0, + }else if( sqlite3_file_control(db, i ? db->aDb[i].zDbSName : 0, SQLITE_FCNTL_LOCKSTATE, &j)==SQLITE_OK ){ zState = azLockName[j]; } - sqlite3VdbeMultiLoad(v, 1, "ss", db->aDb[i].zName, zState); + sqlite3VdbeMultiLoad(v, 1, "ss", db->aDb[i].zDbSName, zState); sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 2); } break; diff --git a/src/prepare.c b/src/prepare.c index 6685dfeaf7..e193c54665 100644 --- a/src/prepare.c +++ b/src/prepare.c @@ -107,7 +107,7 @@ int sqlite3InitCallback(void *pInit, int argc, char **argv, char **NotUsed){ ** to do here is record the root page number for that index. */ Index *pIndex; - pIndex = sqlite3FindIndex(db, argv[0], db->aDb[iDb].zName); + pIndex = sqlite3FindIndex(db, argv[0], db->aDb[iDb].zDbSName); if( pIndex==0 ){ /* This can occur if there exists an index on a TEMP table which ** has the same name as another index on a permanent index. Since @@ -286,7 +286,7 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ char *zSql; zSql = sqlite3MPrintf(db, "SELECT name, rootpage, sql FROM \"%w\".%s ORDER BY rowid", - db->aDb[iDb].zName, zMasterName); + db->aDb[iDb].zDbSName, zMasterName); #ifndef SQLITE_OMIT_AUTHORIZATION { sqlite3_xauth xAuth; @@ -561,7 +561,7 @@ static int sqlite3Prepare( assert( sqlite3BtreeHoldsMutex(pBt) ); rc = sqlite3BtreeSchemaLocked(pBt); if( rc ){ - const char *zDb = db->aDb[i].zName; + const char *zDb = db->aDb[i].zDbSName; sqlite3ErrorWithMsg(db, rc, "database schema is locked: %s", zDb); testcase( db->flags & SQLITE_ReadUncommitted ); goto end_prepare; diff --git a/src/resolve.c b/src/resolve.c index 8ae7f0919c..206015fcfa 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -221,8 +221,8 @@ static int lookupName( zDb = 0; }else{ for(i=0; inDb; i++){ - assert( db->aDb[i].zName ); - if( sqlite3StrICmp(db->aDb[i].zName,zDb)==0 ){ + assert( db->aDb[i].zDbSName ); + if( sqlite3StrICmp(db->aDb[i].zDbSName,zDb)==0 ){ pSchema = db->aDb[i].pSchema; break; } diff --git a/src/select.c b/src/select.c index e21ac57dc5..064ae2a324 100644 --- a/src/select.c +++ b/src/select.c @@ -4414,7 +4414,7 @@ static int selectExpander(Walker *pWalker, Select *p){ continue; } iDb = sqlite3SchemaToIndex(db, pTab->pSchema); - zSchemaName = iDb>=0 ? db->aDb[iDb].zName : "*"; + zSchemaName = iDb>=0 ? db->aDb[iDb].zDbSName : "*"; } for(j=0; jnCol; j++){ char *zName = pTab->aCol[j].zName; diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 0ce56ceab1..17f3efc6d0 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1097,7 +1097,7 @@ typedef struct With With; ** databases may be attached. */ struct Db { - char *zName; /* Name of this database */ + char *zDbSName; /* Name of this database. (schema name, not filename) */ Btree *pBt; /* The B*Tree structure for this database file */ u8 safety_level; /* How aggressive at syncing data to disk */ u8 bSyncSet; /* True if "PRAGMA synchronous=N" has been run */ diff --git a/src/trigger.c b/src/trigger.c index 72c31eb2a3..a1c16dd354 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -214,8 +214,8 @@ void sqlite3BeginTrigger( #ifndef SQLITE_OMIT_AUTHORIZATION { int code = SQLITE_CREATE_TRIGGER; - const char *zDb = db->aDb[iTabDb].zName; - const char *zDbTrig = isTemp ? db->aDb[1].zName : zDb; + const char *zDb = db->aDb[iTabDb].zDbSName; + const char *zDbTrig = isTemp ? db->aDb[1].zDbSName : zDb; if( iTabDb==1 || isTemp ) code = SQLITE_CREATE_TEMP_TRIGGER; if( sqlite3AuthCheck(pParse, code, zName, pTab->zName, zDbTrig) ){ goto trigger_cleanup; @@ -309,7 +309,7 @@ void sqlite3FinishTrigger( z = sqlite3DbStrNDup(db, (char*)pAll->z, pAll->n); sqlite3NestedParse(pParse, "INSERT INTO %Q.%s VALUES('trigger',%Q,%Q,0,'CREATE TRIGGER %q')", - db->aDb[iDb].zName, SCHEMA_TABLE(iDb), zName, + db->aDb[iDb].zDbSName, SCHEMA_TABLE(iDb), zName, pTrig->table, z); sqlite3DbFree(db, z); sqlite3ChangeCookie(pParse, iDb); @@ -498,7 +498,7 @@ void sqlite3DropTrigger(Parse *pParse, SrcList *pName, int noErr){ assert( zDb!=0 || sqlite3BtreeHoldsAllMutexes(db) ); for(i=OMIT_TEMPDB; inDb; i++){ int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */ - if( zDb && sqlite3StrICmp(db->aDb[j].zName, zDb) ) continue; + if( zDb && sqlite3StrICmp(db->aDb[j].zDbSName, zDb) ) continue; assert( sqlite3SchemaMutexHeld(db, j, 0) ); pTrigger = sqlite3HashFind(&(db->aDb[j].pSchema->trigHash), zName); if( pTrigger ) break; @@ -544,7 +544,7 @@ void sqlite3DropTriggerPtr(Parse *pParse, Trigger *pTrigger){ #ifndef SQLITE_OMIT_AUTHORIZATION { int code = SQLITE_DROP_TRIGGER; - const char *zDb = db->aDb[iDb].zName; + const char *zDb = db->aDb[iDb].zDbSName; const char *zTab = SCHEMA_TABLE(iDb); if( iDb==1 ) code = SQLITE_DROP_TEMP_TRIGGER; if( sqlite3AuthCheck(pParse, code, pTrigger->zName, pTable->zName, zDb) || @@ -560,7 +560,7 @@ void sqlite3DropTriggerPtr(Parse *pParse, Trigger *pTrigger){ if( (v = sqlite3GetVdbe(pParse))!=0 ){ sqlite3NestedParse(pParse, "DELETE FROM %Q.%s WHERE name=%Q AND type='trigger'", - db->aDb[iDb].zName, SCHEMA_TABLE(iDb), pTrigger->zName + db->aDb[iDb].zDbSName, SCHEMA_TABLE(iDb), pTrigger->zName ); sqlite3ChangeCookie(pParse, iDb); sqlite3VdbeAddOp4(v, OP_DropTrigger, iDb, 0, 0, pTrigger->zName, 0); @@ -663,8 +663,10 @@ static SrcList *targetSrcList( pSrc->a[pSrc->nSrc-1].zName = sqlite3DbStrDup(db, pStep->zTarget); iDb = sqlite3SchemaToIndex(db, pStep->pTrig->pSchema); if( iDb==0 || iDb>=2 ){ + const char *zDb; assert( iDbnDb ); - pSrc->a[pSrc->nSrc-1].zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zName); + zDb = db->aDb[iDb].zDbSName; + pSrc->a[pSrc->nSrc-1].zDatabase = sqlite3DbStrDup(db, zDb); } } return pSrc; diff --git a/src/update.c b/src/update.c index 1436501264..15e58e34c5 100644 --- a/src/update.c +++ b/src/update.c @@ -249,7 +249,7 @@ void sqlite3Update( int rc; rc = sqlite3AuthCheck(pParse, SQLITE_UPDATE, pTab->zName, j<0 ? "ROWID" : pTab->aCol[j].zName, - db->aDb[iDb].zName); + db->aDb[iDb].zDbSName); if( rc==SQLITE_DENY ){ goto update_cleanup; }else if( rc==SQLITE_IGNORE ){ diff --git a/src/vacuum.c b/src/vacuum.c index b72663c066..eb07664c88 100644 --- a/src/vacuum.c +++ b/src/vacuum.c @@ -173,7 +173,7 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){ rc = execSql(db, pzErrMsg, zSql); if( db->nDb>nDb ){ pDb = &db->aDb[db->nDb-1]; - assert( strcmp(pDb->zName,"vacuum_db")==0 ); + assert( strcmp(pDb->zDbSName,"vacuum_db")==0 ); } if( rc!=SQLITE_OK ) goto end_of_vacuum; pTemp = db->aDb[db->nDb-1].pBt; diff --git a/src/vdbe.c b/src/vdbe.c index 5d21ad064c..e8fd26f5ce 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -4346,7 +4346,7 @@ case OP_InsertInt: { if( pOp->p4type==P4_TABLE && HAS_UPDATE_HOOK(db) ){ assert( pC->isTable ); assert( pC->iDb>=0 ); - zDb = db->aDb[pC->iDb].zName; + zDb = db->aDb[pC->iDb].zDbSName; pTab = pOp->p4.pTab; assert( HasRowid(pTab) ); op = ((pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT); @@ -4463,7 +4463,7 @@ case OP_Delete: { if( pOp->p4type==P4_TABLE && HAS_UPDATE_HOOK(db) ){ assert( pC->iDb>=0 ); assert( pOp->p4.pTab!=0 ); - zDb = db->aDb[pC->iDb].zName; + zDb = db->aDb[pC->iDb].zDbSName; pTab = pOp->p4.pTab; if( (pOp->p5 & OPFLAG_SAVEPOSITION)!=0 && pC->isTable ){ pC->movetoTarget = sqlite3BtreeIntegerKey(pC->uc.pCursor); @@ -5433,7 +5433,7 @@ case OP_ParseSchema: { initData.pzErrMsg = &p->zErrMsg; zSql = sqlite3MPrintf(db, "SELECT name, rootpage, sql FROM '%q'.%s WHERE %s ORDER BY rowid", - db->aDb[iDb].zName, zMaster, pOp->p4.z); + db->aDb[iDb].zDbSName, zMaster, pOp->p4.z); if( zSql==0 ){ rc = SQLITE_NOMEM_BKPT; }else{ @@ -6817,7 +6817,7 @@ case OP_Init: { /* jump */ int i; for(i=0; inDb; i++){ if( DbMaskTest(p->btreeMask, i)==0 ) continue; - sqlite3_file_control(db, db->aDb[i].zName, SQLITE_FCNTL_TRACE, zTrace); + sqlite3_file_control(db, db->aDb[i].zDbSName, SQLITE_FCNTL_TRACE, zTrace); } } #endif /* SQLITE_USE_FCNTL_TRACE */ diff --git a/src/vdbeapi.c b/src/vdbeapi.c index b17c0e0a40..3d36413bc4 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -499,7 +499,7 @@ static int doWalCallbacks(sqlite3 *db){ nEntry = sqlite3PagerWalCallback(sqlite3BtreePager(pBt)); sqlite3BtreeLeave(pBt); if( db->xWalCallback && nEntry>0 && rc==SQLITE_OK ){ - rc = db->xWalCallback(db->pWalArg, db, db->aDb[i].zName, nEntry); + rc = db->xWalCallback(db->pWalArg, db, db->aDb[i].zDbSName, nEntry); } } } diff --git a/src/vdbeblob.c b/src/vdbeblob.c index 01827f94d0..570e253fdb 100644 --- a/src/vdbeblob.c +++ b/src/vdbeblob.c @@ -176,7 +176,7 @@ int sqlite3_blob_open( goto blob_open_out; } pBlob->pTab = pTab; - pBlob->zDb = db->aDb[sqlite3SchemaToIndex(db, pTab->pSchema)].zName; + pBlob->zDb = db->aDb[sqlite3SchemaToIndex(db, pTab->pSchema)].zDbSName; /* Now search pTab for the exact column. */ for(iCol=0; iColnCol; iCol++) { diff --git a/src/vtab.c b/src/vtab.c index 45c5e79abd..53800dd40e 100644 --- a/src/vtab.c +++ b/src/vtab.c @@ -344,7 +344,7 @@ void sqlite3VtabBeginParse( */ if( pTable->azModuleArg ){ sqlite3AuthCheck(pParse, SQLITE_CREATE_VTABLE, pTable->zName, - pTable->azModuleArg[0], pParse->db->aDb[iDb].zName); + pTable->azModuleArg[0], pParse->db->aDb[iDb].zDbSName); } #endif } @@ -408,7 +408,7 @@ void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){ "UPDATE %Q.%s " "SET type='table', name=%Q, tbl_name=%Q, rootpage=0, sql=%Q " "WHERE rowid=#%d", - db->aDb[iDb].zName, SCHEMA_TABLE(iDb), + db->aDb[iDb].zDbSName, SCHEMA_TABLE(iDb), pTab->zName, pTab->zName, zStmt, @@ -518,7 +518,7 @@ static int vtabCallConstructor( pVTable->pMod = pMod; iDb = sqlite3SchemaToIndex(db, pTab->pSchema); - pTab->azModuleArg[1] = db->aDb[iDb].zName; + pTab->azModuleArg[1] = db->aDb[iDb].zDbSName; /* Invoke the virtual table constructor */ assert( &db->pVtabCtx ); @@ -682,7 +682,7 @@ int sqlite3VtabCallCreate(sqlite3 *db, int iDb, const char *zTab, char **pzErr){ Module *pMod; const char *zMod; - pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zName); + pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zDbSName); assert( pTab && (pTab->tabFlags & TF_Virtual)!=0 && !pTab->pVTable ); /* Locate the required virtual table module */ @@ -806,7 +806,7 @@ int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab){ int rc = SQLITE_OK; Table *pTab; - pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zName); + pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zDbSName); if( pTab!=0 && ALWAYS(pTab->pVTable!=0) ){ VTable *p; int (*xDestroy)(sqlite3_vtab *); From b39a5ac22946a1de8b70e48260d02d6bd4598d0c Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 18 Aug 2016 14:47:48 +0000 Subject: [PATCH 0708/1484] Adjust some tests to account for recent changes to the fts5 snippet function. FossilOrigin-Name: 184ecbe9c0c3280a22cdeda5c7836a7b280c3e1f --- ext/fts5/test/fts5af.test | 76 ++++++++++++++++++--------------- ext/fts5/test/fts5unicode2.test | 8 ++-- manifest | 14 +++--- manifest.uuid | 2 +- 4 files changed, 54 insertions(+), 46 deletions(-) diff --git a/ext/fts5/test/fts5af.test b/ext/fts5/test/fts5af.test index 903dd2910f..3b71a9ff5f 100644 --- a/ext/fts5/test/fts5af.test +++ b/ext/fts5/test/fts5af.test @@ -59,6 +59,7 @@ proc do_snippet_test {tn doc match res} { foreach {tn doc res} { + 1.1 {X o o o o o o} {[X] o o o o o o} 1.2 {o X o o o o o} {o [X] o o o o o} 1.3 {o o X o o o o} {o o [X] o o o o} @@ -71,49 +72,56 @@ foreach {tn doc res} { 2.2 {o X o o o o o o} {o [X] o o o o o...} 2.3 {o o X o o o o o} {o o [X] o o o o...} 2.4 {o o o X o o o o} {o o o [X] o o o...} - 2.5 {o o o o X o o o} {...o o o [X] o o o} - 2.6 {o o o o o X o o} {...o o o o [X] o o} - 2.7 {o o o o o o X o} {...o o o o o [X] o} + 2.5 {o o o o X o o o} {o o o o [X] o o...} + 2.6 {o o o o o X o o} {o o o o o [X] o...} + 2.7 {o o o o o o X o} {o o o o o o [X]...} 2.8 {o o o o o o o X} {...o o o o o o [X]} + 2.9 {o o o o o o o X o} {...o o o o o [X] o} + 2.10 {o o o o o o o X o o} {...o o o o [X] o o} + 2.11 {o o o o o o o X o o o} {...o o o [X] o o o} + 2.12 {o o o o o o o X o o o o} {...o o o [X] o o o...} + + 3.1 {X o o o o o o o o} {[X] o o o o o o...} 3.2 {o X o o o o o o o} {o [X] o o o o o...} 3.3 {o o X o o o o o o} {o o [X] o o o o...} 3.4 {o o o X o o o o o} {o o o [X] o o o...} - 3.5 {o o o o X o o o o} {...o o o [X] o o o...} - 3.6 {o o o o o X o o o} {...o o o [X] o o o} - 3.7 {o o o o o o X o o} {...o o o o [X] o o} - 3.8 {o o o o o o o X o} {...o o o o o [X] o} - 3.9 {o o o o o o o o X} {...o o o o o o [X]} + + 3.5 {o o o o o o o X o o o o} {...o o o [X] o o o...} + 3.6 {o o o o o o o o X o o o} {...o o o [X] o o o} + 3.7 {o o o o o o o o o X o o} {...o o o o [X] o o} + 3.8 {o o o o o o o o o o X o} {...o o o o o [X] o} + 3.9 {o o o o o o o o o o o X} {...o o o o o o [X]} 4.1 {X o o o o o X o o} {[X] o o o o o [X]...} - 4.2 {o X o o o o o X o} {...[X] o o o o o [X]...} - 4.3 {o o X o o o o o X} {...[X] o o o o o [X]} + 4.2 {o o o o o o o X o o o o o X o} {...[X] o o o o o [X]...} + 4.3 {o o o o o o o o X o o o o o X} {...[X] o o o o o [X]} 5.1 {X o o o o X o o o} {[X] o o o o [X] o...} - 5.2 {o X o o o o X o o} {...[X] o o o o [X] o...} - 5.3 {o o X o o o o X o} {...[X] o o o o [X] o} - 5.4 {o o o X o o o o X} {...o [X] o o o o [X]} + 5.2 {o o o o o o o X o o o o X o o} {...[X] o o o o [X] o...} + 5.3 {o o o o o o o o X o o o o X o} {...[X] o o o o [X] o} + 5.4 {o o o o o o o o o X o o o o X} {...o [X] o o o o [X]} 6.1 {X o o o X o o o} {[X] o o o [X] o o...} 6.2 {o X o o o X o o o} {o [X] o o o [X] o...} - 6.3 {o o X o o o X o o} {...o [X] o o o [X] o...} - 6.4 {o o o X o o o X o} {...o [X] o o o [X] o} - 6.5 {o o o o X o o o X} {...o o [X] o o o [X]} + 6.3 {o o o o o o o X o o o X o o} {...o [X] o o o [X] o...} + 6.4 {o o o o o o o o X o o o X o} {...o [X] o o o [X] o} + 6.5 {o o o o o o o o o X o o o X} {...o o [X] o o o [X]} 7.1 {X o o X o o o o o} {[X] o o [X] o o o...} 7.2 {o X o o X o o o o} {o [X] o o [X] o o...} - 7.3 {o o X o o X o o o} {...o [X] o o [X] o o...} - 7.4 {o o o X o o X o o} {...o [X] o o [X] o o} - 7.5 {o o o o X o o X o} {...o o [X] o o [X] o} - 7.6 {o o o o o X o o X} {...o o o [X] o o [X]} + 7.3 {o o o o o o o X o o X o o o} {...o [X] o o [X] o o...} + 7.4 {o o o o o o o o X o o X o o} {...o [X] o o [X] o o} + 7.5 {o o o o o o o o o X o o X o} {...o o [X] o o [X] o} + 7.6 {o o o o o o o o o o X o o X} {...o o o [X] o o [X]} - 8.1 {o o o o X o o o o o o o o o o o o o o o o o o o o o X X X o o o} + 8.1 {o o o o o o o o o X o o o o o o o o o o o o o o o o X X X o o o} {...o o [X] [X] [X] o o...} - 8.2 {o o o o. X o o o o o o o o o o o o o o o o o o o o o X X X o o o} - {...[X] o o o o o o...} - - + 8.2 {o o o o o o o. o o X o o o o o o o o o o o o o o o o X X X o o o} + {...o o [X] o o o o...} + 8.3 {o o o o X o o o o o o o o o o o o o o o o o o o o o X X X o o o} + {o o o o [X] o o...} } { do_snippet_test 1.$tn $doc X $res } @@ -130,19 +138,19 @@ if {[detail_is_full]} { 2.1 {X Y o o o o o o} {[X Y] o o o o o...} 2.2 {o X Y o o o o o} {o [X Y] o o o o...} 2.3 {o o X Y o o o o} {o o [X Y] o o o...} - 2.4 {o o o X Y o o o} {...o o [X Y] o o o} - 2.5 {o o o o X Y o o} {...o o o [X Y] o o} - 2.6 {o o o o o X Y o} {...o o o o [X Y] o} - 2.7 {o o o o o o X Y} {...o o o o o [X Y]} + 2.4 {o o o o o o o X Y o o o} {...o o [X Y] o o o} + 2.5 {o o o o o o o o X Y o o} {...o o o [X Y] o o} + 2.6 {o o o o o o o o o X Y o} {...o o o o [X Y] o} + 2.7 {o o o o o o o o o o X Y} {...o o o o o [X Y]} 3.1 {X Y o o o o o o o} {[X Y] o o o o o...} 3.2 {o X Y o o o o o o} {o [X Y] o o o o...} 3.3 {o o X Y o o o o o} {o o [X Y] o o o...} - 3.4 {o o o X Y o o o o} {...o o [X Y] o o o...} - 3.5 {o o o o X Y o o o} {...o o [X Y] o o o} - 3.6 {o o o o o X Y o o} {...o o o [X Y] o o} - 3.7 {o o o o o o X Y o} {...o o o o [X Y] o} - 3.8 {o o o o o o o X Y} {...o o o o o [X Y]} + 3.4 {o o o o o o o X Y o o o o} {...o o [X Y] o o o...} + 3.5 {o o o o o o o o X Y o o o} {...o o [X Y] o o o} + 3.6 {o o o o o o o o o X Y o o} {...o o o [X Y] o o} + 3.7 {o o o o o o o o o o X Y o} {...o o o o [X Y] o} + 3.8 {o o o o o o o o o o o X Y} {...o o o o o [X Y]} } { do_snippet_test 2.$tn $doc "X + Y" $res } diff --git a/ext/fts5/test/fts5unicode2.test b/ext/fts5/test/fts5unicode2.test index 9fead57c07..8e5bb8e22b 100644 --- a/ext/fts5/test/fts5unicode2.test +++ b/ext/fts5/test/fts5unicode2.test @@ -160,12 +160,12 @@ foreach {tn query snippet} { the maximum x value. } 4 "rollback" { - ...Instead, the pending statement - will return SQLITE_ABORT upon next access after the [ROLLBACK]. + Pending statements no longer block [ROLLBACK]. Instead, the pending + statement will return SQLITE_ABORT upon... } 5 "rOllback" { - ...Instead, the pending statement - will return SQLITE_ABORT upon next access after the [ROLLBACK]. + Pending statements no longer block [ROLLBACK]. Instead, the pending + statement will return SQLITE_ABORT upon... } 6 "lang*" { Added support for the FTS4 [languageid] option. diff --git a/manifest b/manifest index 4fbf53dc5a..9749b2bf53 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Bias\sthe\sfts5\ssnippet()\sfunction\sto\sreturn\ssnippets\sthat\slook\slike\sthey\sstart\sat\sthe\sstart\sof\ssentences. -D 2016-08-17T19:05:12.783 +C Adjust\ssome\stests\sto\saccount\sfor\srecent\schanges\sto\sthe\sfts5\ssnippet\sfunction. +D 2016-08-18T14:47:48.448 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -122,7 +122,7 @@ F ext/fts5/test/fts5ab.test 30325a89453280160106be411bba3acf138e6d1b F ext/fts5/test/fts5ac.test 55cad4275a1f5acabfe14d8442a8046b47e49e5f F ext/fts5/test/fts5ad.test 36995f0586f30f5602074e012b9224c71ec5171c F ext/fts5/test/fts5ae.test 612dcb51f4069226791ff14c17dbfb3138c56f20 -F ext/fts5/test/fts5af.test 38bfc8c3f2fd4687a37ae3a0d4d64e029273df36 +F ext/fts5/test/fts5af.test b601bbab5a35ca15dd3d1069ee7075a859567073 F ext/fts5/test/fts5ag.test 27180de76c03036be75ee80b93d8c5f540014071 F ext/fts5/test/fts5ah.test dfb7897711dbcda1dacb038aec310daca139fcf5 F ext/fts5/test/fts5ai.test 3909d0b949b2afcaae4d5795cd79153da75381df @@ -190,7 +190,7 @@ F ext/fts5/test/fts5tok1.test beb894c6f3468f10a574302f69ebe4436b0287c7 F ext/fts5/test/fts5tok2.test dcacb32d4a2a3f0dd3215d4a3987f78ae4be21a2 F ext/fts5/test/fts5tokenizer.test ea4df698b35cc427ebf2ba22829d0e28386d8c89 F ext/fts5/test/fts5unicode.test fbef8d8a3b4b88470536cc57604a82ca52e51841 -F ext/fts5/test/fts5unicode2.test cb4918278514eeb6f398a28ce71ba52934f50ce5 +F ext/fts5/test/fts5unicode2.test 529ac7e8648c943bc87bfed1e427128a2f3f9e33 F ext/fts5/test/fts5unicode3.test 35c3d02aa7acf7d43d8de3bfe32c15ba96e8928e F ext/fts5/test/fts5unindexed.test e9539d5b78c677315e7ed8ea911d4fd25437c680 F ext/fts5/test/fts5update.test 57c7012a7919889048947addae10e0613df45529 @@ -1510,7 +1510,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a861713cc6a3868a1c89240e8340bc7b2b9559da -R ddec9217c48a760254ac22da18301cf5 +P 60de159476edbd48dc363f7f77f09c32ea68422f +R 8546174dc7a44b2b80755efe3cb03b8a U dan -Z 28e0d85dd23359fe591994acb5271e6f +Z b3f4b9f04ef4ae0622fcf2d28707aee5 diff --git a/manifest.uuid b/manifest.uuid index cfefaabd19..eb9043217f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -60de159476edbd48dc363f7f77f09c32ea68422f \ No newline at end of file +184ecbe9c0c3280a22cdeda5c7836a7b280c3e1f \ No newline at end of file From c8d0b0b9d46a374a4859bffe230b658656524a53 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 18 Aug 2016 15:36:03 +0000 Subject: [PATCH 0709/1484] Since the TK_VECTOR token is not actually used by the parser, make it an extra token code added by the tool/addopcodes.tcl script during parser build. FossilOrigin-Name: b40b202c1f82808d2240e87b22f1e78b2208cb26 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/parse.y | 1 - tool/addopcodes.tcl | 1 + 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 22c5f502bf..5dd783a497 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\srecent\senhancements\sfrom\strunk. -D 2016-08-18T15:21:16.759 +C Since\sthe\sTK_VECTOR\stoken\sis\snot\sactually\sused\sby\sthe\sparser,\smake\sit\san\nextra\stoken\scode\sadded\sby\sthe\stool/addopcodes.tcl\sscript\sduring\sparser\sbuild. +D 2016-08-18T15:36:03.992 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -373,7 +373,7 @@ F src/os_win.c 520f23475f1de530c435d30b67b7b15fe90874b0 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c 40928c450320da78bb4bd3ae82818f4239e19b7e F src/pager.h 966d2769e76ae347c8a32c4165faf6e6cb64546d -F src/parse.y a7402dff6fe8238795f15ca194e1f1b734d169f4 +F src/parse.y d240b1518fa9c5cb02b222e1fac8e07d950c9ed9 F src/pcache.c 5583c8ade4b05075a60ba953ef471d1c1a9c05df F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 F src/pcache1.c 4bb7a6a5300c67d0b033d25adb509c120c03e812 @@ -1430,7 +1430,7 @@ F test/zerodamage.test e59a56443d6298ecf7435f618f0b27654f0c849e F tool/GetFile.cs a15e08acb5dd7539b75ba23501581d7c2b462cb5 F tool/GetTclKit.bat 629d87562e0487c386db630033931d12d62e6372 F tool/Replace.cs 02c67258801c2fb5f63231e0ac0f220b4b36ba91 -F tool/addopcodes.tcl 7d4954564d7d4bfde5ba139ebced25542696fa52 +F tool/addopcodes.tcl 10c889c4a65ec6c5604e4a47306fa77ff57ae189 F tool/build-all-msvc.bat 3e4e4043b53f1aede4308e0d2567bbd773614630 x F tool/build-shell.sh 950f47c6174f1eea171319438b93ba67ff5bf367 F tool/cg_anno.tcl 692ce4b8693d59e3a3de77ca97f4139ecfa641b0 x @@ -1516,7 +1516,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e2ad0b5d8e1e83118c12889150aca2f2a6b2bdde 92a22f01343a898455fd61c3b8e7d7c954f5b569 -R a3d6c4bcdda8d18e3de85b224695f9f6 +P 4768a1066cb9c7627064d7efec44188d6755cb03 +R ad89bbe968192719b16d3d08af2d0d65 U drh -Z 554fed64519eb39711e06c16c9610431 +Z f8279b18447d0a73aa27340aaf051f41 diff --git a/manifest.uuid b/manifest.uuid index a8a1479273..790d0fe829 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4768a1066cb9c7627064d7efec44188d6755cb03 \ No newline at end of file +b40b202c1f82808d2240e87b22f1e78b2208cb26 \ No newline at end of file diff --git a/src/parse.y b/src/parse.y index fffc7fa352..752a4ef599 100644 --- a/src/parse.y +++ b/src/parse.y @@ -217,7 +217,6 @@ columnname(A) ::= nm(A) typetoken(Y). {sqlite3AddColumn(pParse,&A,&Y);} %left CONCAT. %left COLLATE. %right BITNOT. -%right VECTOR. // An IDENTIFIER can be a generic identifier, or one of several // keywords. Any non-standard keyword can also be an identifier. diff --git a/tool/addopcodes.tcl b/tool/addopcodes.tcl index 29409a4900..a6c58f1a25 100644 --- a/tool/addopcodes.tcl +++ b/tool/addopcodes.tcl @@ -37,6 +37,7 @@ set extras { UMINUS UPLUS REGISTER + VECTOR SELECT_COLUMN ASTERISK SPAN From db97e56217e4bf10ffd115088002ab73a949b498 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 18 Aug 2016 17:55:57 +0000 Subject: [PATCH 0710/1484] Display VECTOR expressions in .wheretrace and .selecttrace debugging output. FossilOrigin-Name: 157347e2580e5078c4081d602e9d1a82d194e719 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/sqliteInt.h | 1 + src/treeview.c | 20 ++++++++++++++++---- 4 files changed, 25 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 5dd783a497..0491eac610 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Since\sthe\sTK_VECTOR\stoken\sis\snot\sactually\sused\sby\sthe\sparser,\smake\sit\san\nextra\stoken\scode\sadded\sby\sthe\stool/addopcodes.tcl\sscript\sduring\sparser\sbuild. -D 2016-08-18T15:36:03.992 +C Display\sVECTOR\sexpressions\sin\s.wheretrace\sand\s.selecttrace\sdebugging\soutput. +D 2016-08-18T17:55:57.954 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -389,7 +389,7 @@ F src/shell.c 79dda477be6c96eba6e952a934957ad36f87acc7 F src/sqlite.h.in 0f7580280d1b009b507d8beec1ff0f197ba0cc99 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae -F src/sqliteInt.h 1b51d9e1ae63476fbe69423d531afdefab8aa18f +F src/sqliteInt.h f4079dcc83ec216d34531792626206a1a35463bc F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 @@ -444,7 +444,7 @@ F src/test_windirent.h b12055cab6227f7be10f5c19296f67c60cc5e2a5 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c 78c8085bc7af1922aa687f0f4bbd716821330de5 -F src/treeview.c c56d6ddbed564efda746236b35bcbb8238daac4b +F src/treeview.c 0ec6101f55829005fae5f83d33c666224a275e1b F src/trigger.c 11e20b3b12c847b3b9055594c0f1631266bb53fc F src/update.c 8179e699dbd45b92934fd02d3d8e3732e8da8802 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c @@ -1516,7 +1516,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 4768a1066cb9c7627064d7efec44188d6755cb03 -R ad89bbe968192719b16d3d08af2d0d65 +P b40b202c1f82808d2240e87b22f1e78b2208cb26 +R 977869bee47fcdc239ba588f810a1009 U drh -Z f8279b18447d0a73aa27340aaf051f41 +Z 61690ef4bbd764846f05c0b7918f3dcb diff --git a/manifest.uuid b/manifest.uuid index 790d0fe829..051933d3ad 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b40b202c1f82808d2240e87b22f1e78b2208cb26 \ No newline at end of file +157347e2580e5078c4081d602e9d1a82d194e719 \ No newline at end of file diff --git a/src/sqliteInt.h b/src/sqliteInt.h index f1d29c643e..0c5fb9ce86 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3513,6 +3513,7 @@ char *sqlite3VMPrintf(sqlite3*,const char*, va_list); #if defined(SQLITE_DEBUG) void sqlite3TreeViewExpr(TreeView*, const Expr*, u8); + void sqlite3TreeViewBareExprList(TreeView*, const ExprList*, const char*); void sqlite3TreeViewExprList(TreeView*, const ExprList*, u8, const char*); void sqlite3TreeViewSelect(TreeView*, const Select*, u8); void sqlite3TreeViewWith(TreeView*, const With*, u8); diff --git a/src/treeview.c b/src/treeview.c index 27996d46d7..6101af5771 100644 --- a/src/treeview.c +++ b/src/treeview.c @@ -451,6 +451,10 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){ sqlite3TreeViewExpr(pView, pExpr->pRight, 0); break; } + case TK_VECTOR: { + sqlite3TreeViewBareExprList(pView, pExpr->x.pList, "VECTOR"); + break; + } default: { sqlite3TreeViewLine(pView, "op=%d", pExpr->op); break; @@ -467,21 +471,20 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){ sqlite3TreeViewPop(pView); } + /* ** Generate a human-readable explanation of an expression list. */ -void sqlite3TreeViewExprList( +void sqlite3TreeViewBareExprList( TreeView *pView, const ExprList *pList, - u8 moreToFollow, const char *zLabel ){ - int i; - pView = sqlite3TreeViewPush(pView, moreToFollow); if( zLabel==0 || zLabel[0]==0 ) zLabel = "LIST"; if( pList==0 ){ sqlite3TreeViewLine(pView, "%s (empty)", zLabel); }else{ + int i; sqlite3TreeViewLine(pView, "%s", zLabel); for(i=0; inExpr; i++){ int j = pList->a[i].u.x.iOrderByCol; @@ -493,6 +496,15 @@ void sqlite3TreeViewExprList( if( j ) sqlite3TreeViewPop(pView); } } +} +void sqlite3TreeViewExprList( + TreeView *pView, + const ExprList *pList, + u8 moreToFollow, + const char *zLabel +){ + pView = sqlite3TreeViewPush(pView, moreToFollow); + sqlite3TreeViewBareExprList(pView, pList, zLabel); sqlite3TreeViewPop(pView); } From 48cb3a76004bab66c4228bb66c83b15fd05f1663 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 18 Aug 2016 18:09:10 +0000 Subject: [PATCH 0711/1484] Display SELECT_COLUMN expressions in the .wheretrace debugging output. FossilOrigin-Name: 3b27a5da100037f75a4efc15e0354a6aa94194f8 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/treeview.c | 5 +++++ 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 0491eac610..8253bd4b1d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Display\sVECTOR\sexpressions\sin\s.wheretrace\sand\s.selecttrace\sdebugging\soutput. -D 2016-08-18T17:55:57.954 +C Display\sSELECT_COLUMN\sexpressions\sin\sthe\s.wheretrace\sdebugging\soutput. +D 2016-08-18T18:09:10.155 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -444,7 +444,7 @@ F src/test_windirent.h b12055cab6227f7be10f5c19296f67c60cc5e2a5 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c 78c8085bc7af1922aa687f0f4bbd716821330de5 -F src/treeview.c 0ec6101f55829005fae5f83d33c666224a275e1b +F src/treeview.c 15406fc49bd7fb1616b4c19b8d1d9fd85211ca8b F src/trigger.c 11e20b3b12c847b3b9055594c0f1631266bb53fc F src/update.c 8179e699dbd45b92934fd02d3d8e3732e8da8802 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c @@ -1516,7 +1516,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b40b202c1f82808d2240e87b22f1e78b2208cb26 -R 977869bee47fcdc239ba588f810a1009 +P 157347e2580e5078c4081d602e9d1a82d194e719 +R c8603389dbe05aeaf19e13f4475b9214 U drh -Z 61690ef4bbd764846f05c0b7918f3dcb +Z 94f649f5f1dae565622eac65874f963e diff --git a/manifest.uuid b/manifest.uuid index 051933d3ad..8229b6d241 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -157347e2580e5078c4081d602e9d1a82d194e719 \ No newline at end of file +3b27a5da100037f75a4efc15e0354a6aa94194f8 \ No newline at end of file diff --git a/src/treeview.c b/src/treeview.c index 6101af5771..2311957184 100644 --- a/src/treeview.c +++ b/src/treeview.c @@ -455,6 +455,11 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){ sqlite3TreeViewBareExprList(pView, pExpr->x.pList, "VECTOR"); break; } + case TK_SELECT_COLUMN: { + sqlite3TreeViewLine(pView, "SELECT-COLUMN %d", pExpr->iColumn); + sqlite3TreeViewSelect(pView, pExpr->pLeft->x.pSelect, 0); + break; + } default: { sqlite3TreeViewLine(pView, "op=%d", pExpr->op); break; From 03181c8c272003b3680096077737f41ba0f1041d Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 18 Aug 2016 19:04:57 +0000 Subject: [PATCH 0712/1484] Fix a SQL NULL handling bug in the vector IN operator code generation. FossilOrigin-Name: 936146b12e27784f15a68fe65732c6d92c3a12f3 --- manifest | 13 +++++++------ manifest.uuid | 2 +- src/wherecode.c | 5 +++-- test/rowvalue6.test | 36 ++++++++++++++++++++++++++++++++++++ 4 files changed, 47 insertions(+), 9 deletions(-) create mode 100644 test/rowvalue6.test diff --git a/manifest b/manifest index 8253bd4b1d..edfe85439e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Display\sSELECT_COLUMN\sexpressions\sin\sthe\s.wheretrace\sdebugging\soutput. -D 2016-08-18T18:09:10.155 +C Fix\sa\sSQL\sNULL\shandling\sbug\sin\sthe\svector\sIN\soperator\scode\sgeneration. +D 2016-08-18T19:04:57.401 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -466,7 +466,7 @@ F src/wal.h 6dd221ed384afdc204bc61e25c23ef7fd5a511f2 F src/walker.c 2d2cc7fb0f320f7f415215d7247f3c584141ac09 F src/where.c 5bee250c8233c43bd7f53897d12b8468004f63db F src/whereInt.h 14dd243e13b81cbb0a66063d38b70f93a7d6e613 -F src/wherecode.c 92202261a6e41f897a595417c5b0c75c8acf713d +F src/wherecode.c 916b451003afef5f3a0265e62a22d7ca527656fe F src/whereexpr.c 8d9903d16ae45d15736745f7b75df2340c729782 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -1024,6 +1024,7 @@ F test/rowvalue2.test 875068299fd4dd50ef0a47786462c8e1f4065f9a F test/rowvalue3.test dbe935260851b197dfbbbcb0ac2a15cb5f324fd4 F test/rowvalue4.test ed3f7974099f0fc508c9f95df55d37c49f43be65 F test/rowvalue5.test 01c7e0bc4048f30b58e6eb27ecd26e5bd312635e +F test/rowvalue6.test d19b54feb604d5601f8614b15e214e0774c01087 F test/rowvaluefault.test 7b16485e3f2b371f3e3d05455b8ded6d0c090244 F test/rtree.test 0c8d9dd458d6824e59683c19ab2ffa9ef946f798 F test/run-wordcount.sh 891e89c4c2d16e629cd45951d4ed899ad12afc09 @@ -1516,7 +1517,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 157347e2580e5078c4081d602e9d1a82d194e719 -R c8603389dbe05aeaf19e13f4475b9214 +P 3b27a5da100037f75a4efc15e0354a6aa94194f8 +R cb7673431cbb14ee2064b1a631b51486 U drh -Z 94f649f5f1dae565622eac65874f963e +Z e68c3ca3548a25a2524e065bf2465c19 diff --git a/manifest.uuid b/manifest.uuid index 8229b6d241..105e0106d8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3b27a5da100037f75a4efc15e0354a6aa94194f8 \ No newline at end of file +936146b12e27784f15a68fe65732c6d92c3a12f3 \ No newline at end of file diff --git a/src/wherecode.c b/src/wherecode.c index 80de8a7e54..d84ace1922 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -499,15 +499,17 @@ static int codeEqualityTerm( int iMap = 0; /* Index in aiMap[] */ pIn += i; for(i=iEq;inLTerm; i++, pIn++){ + int iOut = iReg; if( pLoop->aLTerm[i]->pExpr==pX ){ if( eType==IN_INDEX_ROWID ){ assert( nEq==1 && i==iEq ); pIn->addrInTop = sqlite3VdbeAddOp2(v, OP_Rowid, iTab, iReg); }else{ int iCol = aiMap ? aiMap[iMap++] : 0; - int iOut = iReg + i - iEq; + iOut = iReg + i - iEq; pIn->addrInTop = sqlite3VdbeAddOp3(v,OP_Column,iTab, iCol, iOut); } + sqlite3VdbeAddOp1(v, OP_IsNull, iOut); VdbeCoverage(v); if( i==iEq ){ pIn->iCur = iTab; pIn->eEndLoopOp = bRev ? OP_PrevIfOpen : OP_NextIfOpen; @@ -515,7 +517,6 @@ static int codeEqualityTerm( pIn->eEndLoopOp = OP_Noop; } } - sqlite3VdbeAddOp1(v, OP_IsNull, iReg); VdbeCoverage(v); } }else{ pLevel->u.in.nIn = 0; diff --git a/test/rowvalue6.test b/test/rowvalue6.test new file mode 100644 index 0000000000..d90e61c811 --- /dev/null +++ b/test/rowvalue6.test @@ -0,0 +1,36 @@ +# 2016-08-18 +# +# 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. +# +#*********************************************************************** +# The focus of this file is handling of NULL values in row-value IN +# expressions. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set ::testprefix rowvalue6 + +do_execsql_test 1.1 { + CREATE TABLE t1(a,b,c); + CREATE INDEX t1x1 ON t1(a,b); + INSERT INTO t1 VALUES(1,NULL,200); + + CREATE TABLE t2(x,y,z); + INSERT INTO t2 VALUES(1,NULL,55); + + SELECT c FROM t1 WHERE (a,b) IN (SELECT x,y FROM t2 WHERE z==55); +} {} +do_execsql_test 1.2 { + INSERT INTO t1 VALUES(2,3,400); + INSERT INTO t2 VALUES(2,3,55); + + SELECT c FROM t1 WHERE (a,b) IN (SELECT x,y FROM t2 WHERE z==55); +} {400} + +finish_test From e59be0107260149e2d83579548e00510cb4d4f37 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 18 Aug 2016 20:56:39 +0000 Subject: [PATCH 0713/1484] Fix a zName to zDbSName conversion missed in the previous check-in. FossilOrigin-Name: d7cf423cdccada2b0a4b7cc79ccf5f35d6f43212 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/select.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 28fe5360f6..0c5e8fe2f5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Rename\sthe\sDb.zName\sfield\sto\sDb.zDbSName\sto\smake\sit\smore\sdescriptive\sand\sto\ndistinguish\sit\sfrom\sall\sof\sthe\sother\s"zName"\svariables\sscattered\sthroughout\nthe\scode. -D 2016-08-18T14:33:11.816 +C Fix\sa\szName\sto\szDbSName\sconversion\smissed\sin\sthe\sprevious\scheck-in. +D 2016-08-18T20:56:39.177 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -384,7 +384,7 @@ F src/printf.c a5f0ca08ddede803c241266abb46356ec748ded1 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c d67b9a5cc33339256e2088c5a722745fc2ff5219 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac -F src/select.c 890c32eab22061b57eb2bddcbb55d6af87db7d12 +F src/select.c fda7fd24b4d8e75479ae581329db0a0b0bf76633 F src/shell.c 79dda477be6c96eba6e952a934957ad36f87acc7 F src/sqlite.h.in 0f7580280d1b009b507d8beec1ff0f197ba0cc99 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1510,7 +1510,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a861713cc6a3868a1c89240e8340bc7b2b9559da -R 99cc7186f7854d08151b32f71928925d +P 92a22f01343a898455fd61c3b8e7d7c954f5b569 +R 448d737617983f02db48ab96b9c54357 U drh -Z 208eab983f2b557e0d2dff78ec685958 +Z dfc7211840822334f717825f8c6da4ce diff --git a/manifest.uuid b/manifest.uuid index 7bc875b985..fce1dbf5e1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -92a22f01343a898455fd61c3b8e7d7c954f5b569 \ No newline at end of file +d7cf423cdccada2b0a4b7cc79ccf5f35d6f43212 \ No newline at end of file diff --git a/src/select.c b/src/select.c index 064ae2a324..394e5ee8a3 100644 --- a/src/select.c +++ b/src/select.c @@ -1458,7 +1458,7 @@ static const char *columnTypeImpl( zOrigTab = pTab->zName; if( pNC->pParse ){ int iDb = sqlite3SchemaToIndex(pNC->pParse->db, pTab->pSchema); - zOrigDb = pNC->pParse->db->aDb[iDb].zName; + zOrigDb = pNC->pParse->db->aDb[iDb].zDbSName; } #else if( iCol<0 ){ From da84dcae54cbfb1a58b4762986c260c5aed29c3e Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 18 Aug 2016 22:44:22 +0000 Subject: [PATCH 0714/1484] Add the SQLITE_DBCONFIG_MAINDBNAME interface. FossilOrigin-Name: d6e3d5796c9991ca0af45ed92ce36f55efc02348 --- manifest | 22 ++++++++++++---------- manifest.uuid | 2 +- src/main.c | 5 +++++ src/sqlite.h.in | 10 ++++++++++ src/test1.c | 24 ++++++++++++++++++++++++ test/misc8.test | 26 ++++++++++++++++++++++++++ 6 files changed, 78 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index d69c4a6a04..3ece311687 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sthe\sname\sof\sDb.zName\sto\sDb.zDbSName\sfor\simproved\slong-term\scode\nmaintainability. -D 2016-08-18T22:19:03.467 +C Add\sthe\sSQLITE_DBCONFIG_MAINDBNAME\sinterface. +D 2016-08-18T22:44:22.865 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -349,7 +349,7 @@ F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da F src/insert.c d5cd8315c0577e86e17dda9239b45cffa81022c0 F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e F src/loadext.c dd7a2b77902cc66c22555aef02e1a682554b7aec -F src/main.c 8dc7adfeace35ee1f4c489b503ee8fe6bc1fa802 +F src/main.c 4dba24a78c9797c4005521107905f42217668b86 F src/malloc.c 1443d1ad95d67c21d77af7ae3f44678252f0efec F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b @@ -386,7 +386,7 @@ F src/resolve.c d67b9a5cc33339256e2088c5a722745fc2ff5219 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c fda7fd24b4d8e75479ae581329db0a0b0bf76633 F src/shell.c 79dda477be6c96eba6e952a934957ad36f87acc7 -F src/sqlite.h.in 0f7580280d1b009b507d8beec1ff0f197ba0cc99 +F src/sqlite.h.in 4a030e254e204570444b34bf7d40fb4a5416089e F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae F src/sqliteInt.h f81e279da1bae217d9afcc60d5580a0d4615727e @@ -394,7 +394,7 @@ F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 F src/tclsqlite.c bdae822f21e229b6daced15938b6343ce44ef454 -F src/test1.c 0a0909cf7962d2359db329c08d15b90b4b6e724f +F src/test1.c 8574e41c1bf103727909b37351b3690cc07bc8a7 F src/test2.c b7174313e993754303a8b33c43df7c44b46857ab F src/test3.c 1339a40be39650ae83894b6578f971dc7f96ea8a F src/test4.c 18ec393bb4d0ad1de729f0b94da7267270f3d8e6 @@ -942,7 +942,7 @@ F test/misc4.test 0d8be3466adf123a7791a66ba2bc8e8d229e87f3 F test/misc5.test fff0f75e834bc09a39f6079320dd8c37de956f4f F test/misc6.test 953cc693924d88e6117aeba16f46f0bf5abede91 F test/misc7.test edd0b63e2ee29a256900b0514f6fff27e19e9bb2 -F test/misc8.test 21ac9d35a5e110279ae9e1588b8914f54de1c60b +F test/misc8.test ba03aaa08f02d62fbb8d3b2f5595c1b33aa9bbc5 F test/misuse.test 3c34719944ba045cc6c188a4852ba04680728912 F test/mmap1.test d2cfc1635171c434dcff0ece2f1c8e0a658807ce F test/mmap2.test 9d6dd9ddb4ad2379f29cc78f38ce1e63ed418022 @@ -1510,8 +1510,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a861713cc6a3868a1c89240e8340bc7b2b9559da d7cf423cdccada2b0a4b7cc79ccf5f35d6f43212 -R 448d737617983f02db48ab96b9c54357 -T +closed d7cf423cdccada2b0a4b7cc79ccf5f35d6f43212 +P cb9865e14db1c0076618f13400151112f84960cb +R 2f06ec82e9a3f57e0b8d261a230c1531 +T *branch * dbconfig_maindbname +T *sym-dbconfig_maindbname * +T -sym-trunk * U drh -Z 152d854e5f3b61891883eac72f93d117 +Z 8066580a45fc98ac9d9fef6e64c8a3cf diff --git a/manifest.uuid b/manifest.uuid index 86f4d39538..c0332cdd38 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cb9865e14db1c0076618f13400151112f84960cb \ No newline at end of file +d6e3d5796c9991ca0af45ed92ce36f55efc02348 \ No newline at end of file diff --git a/src/main.c b/src/main.c index e719e76289..2b82e331a0 100644 --- a/src/main.c +++ b/src/main.c @@ -789,6 +789,11 @@ int sqlite3_db_config(sqlite3 *db, int op, ...){ int rc; va_start(ap, op); switch( op ){ + case SQLITE_DBCONFIG_MAINDBNAME: { + db->aDb[0].zDbSName = va_arg(ap,char*); + rc = SQLITE_OK; + break; + } case SQLITE_DBCONFIG_LOOKASIDE: { void *pBuf = va_arg(ap, void*); /* IMP: R-26835-10964 */ int sz = va_arg(ap, int); /* IMP: R-47871-25994 */ diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 1ee39b6799..73c908272d 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -1969,8 +1969,18 @@ struct sqlite3_mem_methods { ** be a NULL pointer, in which case the new setting is not reported back. ** ** +**
    SQLITE_DBCONFIG_MAINDBNAME
    +**
    ^This option is used to change the name of the "main" database +** schema. ^The sole argument is a pointer to a constant UTF8 string +** which will become the new schema name in place of "main". ^SQLite +** does not make a copy of the new main schema name string, so the application +** must ensure that the argument passed into this DBCONFIG option is unchanged +** until after the database connection closes. +**
    +** ** */ +#define SQLITE_DBCONFIG_MAINDBNAME 1000 /* const char* */ #define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */ #define SQLITE_DBCONFIG_ENABLE_FKEY 1002 /* int int* */ #define SQLITE_DBCONFIG_ENABLE_TRIGGER 1003 /* int int* */ diff --git a/src/test1.c b/src/test1.c index aced552173..367bcc1f7b 100644 --- a/src/test1.c +++ b/src/test1.c @@ -7195,6 +7195,29 @@ static int SQLITE_TCLAPI test_sqlite3_db_config( return TCL_OK; } +/* +** Change the name of the main database schema from "main" to "icecube". +*/ +static int SQLITE_TCLAPI test_dbconfig_maindbname_icecube( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + int rc; + sqlite3 *db; + extern int getDbPointer(Tcl_Interp*, const char*, sqlite3**); + if( objc!=2 ){ + Tcl_WrongNumArgs(interp, 1, objv, "DB"); + return TCL_ERROR; + }else{ + if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; + rc = sqlite3_db_config(db, SQLITE_DBCONFIG_MAINDBNAME, "icecube"); + Tcl_SetObjResult(interp, Tcl_NewIntObj(rc)); + return TCL_OK; + } +} + /* ** Register commands with the TCL interpreter. */ @@ -7328,6 +7351,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){ { "sqlite3_enable_load_extension", test_enable_load, 0}, { "sqlite3_extended_result_codes", test_extended_result_codes, 0}, { "sqlite3_limit", test_limit, 0}, + { "dbconfig_maindbname_icecube", test_dbconfig_maindbname_icecube }, { "save_prng_state", save_prng_state, 0 }, { "restore_prng_state", restore_prng_state, 0 }, diff --git a/test/misc8.test b/test/misc8.test index 3817cadf94..b639dd1463 100644 --- a/test/misc8.test +++ b/test/misc8.test @@ -108,4 +108,30 @@ do_execsql_test misc8-3.0 { ORDER BY 1; } {0 1 6 0 1 7} +# The SQLITE_DBCONFIG_MAINDBNAME interface +# +db close +forcedelete test.db test2.db +sqlite3 db test.db +do_execsql_test misc8-4.0 { + CREATE TABLE t1(a,b,c); + INSERT INTO t1 VALUES(1,2,3); + ATTACH 'test2.db' AS aux2; + CREATE TABLE aux2.t2(c,d,e); + INSERT INTO t2 VALUES(4,5,6); + SELECT * FROM t1, t2; +} {1 2 3 4 5 6} +do_execsql_test misc8-4.1 { + PRAGMA database_list; +} {/0 main .* 2 aux2/} +dbconfig_maindbname_icecube db +do_execsql_test misc8-4.2 { + SELECT name FROM icecube.sqlite_master; +} {t1} +do_execsql_test misc8-4.3 { + PRAGMA database_list; +} {/0 icecube .* 2 aux2/} + + + finish_test From 9ef5e7708a4c37710d4093f7730141c842d1f643 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 19 Aug 2016 14:20:56 +0000 Subject: [PATCH 0715/1484] Add the capability to VACUUM an attached database by specifying the schema name as an argument to the VACUUM command. Since version 2.0, VACUUM has accepted an argument which was silently ignored. Now it has meaning. FossilOrigin-Name: 29d63059b4d2bb612523ac55ebfef040d054a64f --- manifest | 31 ++++---- manifest.uuid | 2 +- src/build.c | 4 +- src/insert.c | 8 +- src/parse.y | 4 +- src/prepare.c | 4 +- src/sqliteInt.h | 4 +- src/vacuum.c | 183 +++++++++++++++++++-------------------------- src/vdbe.c | 9 +-- test/e_vacuum.test | 6 +- test/vacuum5.test | 111 +++++++++++++++++++++++++++ 11 files changed, 228 insertions(+), 138 deletions(-) create mode 100644 test/vacuum5.test diff --git a/manifest b/manifest index d69c4a6a04..fea0d6a17b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sthe\sname\sof\sDb.zName\sto\sDb.zDbSName\sfor\simproved\slong-term\scode\nmaintainability. -D 2016-08-18T22:19:03.467 +C Add\sthe\scapability\sto\sVACUUM\san\sattached\sdatabase\sby\sspecifying\sthe\sschema\nname\sas\san\sargument\sto\sthe\sVACUUM\scommand.\s\sSince\sversion\s2.0,\sVACUUM\shas\naccepted\san\sargument\swhich\swas\ssilently\signored.\s\sNow\sit\shas\smeaning. +D 2016-08-19T14:20:56.900 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -331,7 +331,7 @@ F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 F src/btree.c 2551bd3ecb8b8988fb8b23aabadfb214dbc38e46 F src/btree.h 075c45707c0f8f8af118f739f36df8098a08b7da F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 -F src/build.c c38fd92a8d886a5b9397267bf63b76ebad05c4d5 +F src/build.c d32cacbb59a403b68e1c2ec962ca31b6f3aad4fc F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7 @@ -346,7 +346,7 @@ F src/global.c c45ea22aff29334f6a9ec549235ac3357c970015 F src/hash.c 55b5fb474100cee0b901edaf203e26c970940f36 F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4 F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da -F src/insert.c d5cd8315c0577e86e17dda9239b45cffa81022c0 +F src/insert.c a255eb795cf475e7a0659297144fc80f70eb4e30 F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e F src/loadext.c dd7a2b77902cc66c22555aef02e1a682554b7aec F src/main.c 8dc7adfeace35ee1f4c489b503ee8fe6bc1fa802 @@ -373,13 +373,13 @@ F src/os_win.c 520f23475f1de530c435d30b67b7b15fe90874b0 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c 40928c450320da78bb4bd3ae82818f4239e19b7e F src/pager.h 966d2769e76ae347c8a32c4165faf6e6cb64546d -F src/parse.y 99b676e6fc2f4e331ab93e76b3987cffdbd28efa +F src/parse.y ed6990c2d41eb0302eda90d5009c51fec792c850 F src/pcache.c 5583c8ade4b05075a60ba953ef471d1c1a9c05df F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 F src/pcache1.c 4bb7a6a5300c67d0b033d25adb509c120c03e812 F src/pragma.c d932ba278654617cdd281f88a790a3185fca7c44 F src/pragma.h 64c78a648751b9f4f297276c4eb7507b14b4628c -F src/prepare.c a668988f324961397305b8352cf6bd87776fb347 +F src/prepare.c 0fcf16eaacc90c1059055519a76b75b516a59a88 F src/printf.c a5f0ca08ddede803c241266abb46356ec748ded1 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c d67b9a5cc33339256e2088c5a722745fc2ff5219 @@ -389,7 +389,7 @@ F src/shell.c 79dda477be6c96eba6e952a934957ad36f87acc7 F src/sqlite.h.in 0f7580280d1b009b507d8beec1ff0f197ba0cc99 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae -F src/sqliteInt.h f81e279da1bae217d9afcc60d5580a0d4615727e +F src/sqliteInt.h 153099746007418dfa03a99c8355c8d47b0a1cc9 F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 @@ -449,8 +449,8 @@ F src/trigger.c 11e20b3b12c847b3b9055594c0f1631266bb53fc F src/update.c 8179e699dbd45b92934fd02d3d8e3732e8da8802 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 810ec3f22e2d1b62e66c30fe3621ebdedd23584d -F src/vacuum.c f6f10c88f8af5feb6b3632e5e4133e4482819c4f -F src/vdbe.c 6242a21f22a68899db5e758c69a32cad163585e2 +F src/vacuum.c 0fecf4ba5ae91a2f1d601345f976b028888803d4 +F src/vdbe.c 15376952b0c5dc0afbac6cd8791579dd19ff0a01 F src/vdbe.h 67bc551f7faf04c33493892e4b378aada823ed10 F src/vdbeInt.h c59381049af5c7751a83456c39b80d1a6fde1f9d F src/vdbeapi.c a32d61b7dd05e6890d8fd44d2805f55e2f5ba9f3 @@ -655,7 +655,7 @@ F test/e_select2.test aceb80ab927d46fba5ce7586ebabf23e2bb0604f F test/e_totalchanges.test b12ee5809d3e63aeb83238dd501a7bca7fd72c10 F test/e_update.test f46c2554d915c9197548681e8d8c33a267e84528 F test/e_uri.test 25385396082b67fd02ae0038b95a3b3575fe0519 -F test/e_vacuum.test 120f29ea56bdce4d43279527ece894ab5d1729d3 +F test/e_vacuum.test 9e5e47e4059a779c777f47e0f560fc82c99336df F test/e_wal.test ae9a593207a77d711443ee69ffe081fda9243625 F test/e_walauto.test 248af31e73c98df23476a22bdb815524c9dc3ba8 F test/e_walckpt.test 28c371a6bb5e5fe7f31679c1df1763a19d19e8a0 @@ -1327,6 +1327,7 @@ F test/vacuum.test ce91c39f7f91a4273bf620efad21086b5aa6ef1d F test/vacuum2.test aa048abee196c16c9ba308465494009057b79f9b F test/vacuum3.test 77ecdd54592b45a0bcb133339f99f1ae0ae94d0d F test/vacuum4.test d3f8ecff345f166911568f397d2432c16d2867d9 +F test/vacuum5.test 99d4a0629252f9ef2fc642caefe92436a744db3a F test/vacuummem.test e53a3fdca4612a99c515e1afe7934728a2383764 F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102 F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661 @@ -1510,8 +1511,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a861713cc6a3868a1c89240e8340bc7b2b9559da d7cf423cdccada2b0a4b7cc79ccf5f35d6f43212 -R 448d737617983f02db48ab96b9c54357 -T +closed d7cf423cdccada2b0a4b7cc79ccf5f35d6f43212 +P cb9865e14db1c0076618f13400151112f84960cb +R d22b71c0b6e2dcfd7355ff82dbeacb9a +T *branch * vacuum-attached-db +T *sym-vacuum-attached-db * +T -sym-trunk * U drh -Z 152d854e5f3b61891883eac72f93d117 +Z 9021190c8e1ac254dada8dc6dfa393f1 diff --git a/manifest.uuid b/manifest.uuid index 86f4d39538..e1b549e940 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cb9865e14db1c0076618f13400151112f84960cb \ No newline at end of file +29d63059b4d2bb612523ac55ebfef040d054a64f \ No newline at end of file diff --git a/src/build.c b/src/build.c index bf7080ed49..15c005f4ea 100644 --- a/src/build.c +++ b/src/build.c @@ -773,7 +773,7 @@ int sqlite3TwoPartName( return -1; } }else{ - assert( db->init.iDb==0 || db->init.busy ); + assert( db->init.iDb==0 || db->init.busy || (db->flags & SQLITE_Vacuum)!=0); iDb = db->init.iDb; *pUnqual = pName1; } @@ -2011,7 +2011,7 @@ void sqlite3EndTable( /* Check to see if we need to create an sqlite_sequence table for ** keeping track of autoincrement keys. */ - if( p->tabFlags & TF_Autoincrement ){ + if( (p->tabFlags & TF_Autoincrement)!=0 ){ Db *pDb = &db->aDb[iDb]; assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); if( pDb->pSchema->pSeqTab==0 ){ diff --git a/src/insert.c b/src/insert.c index dacd37c7f1..caab0f1d65 100644 --- a/src/insert.c +++ b/src/insert.c @@ -200,7 +200,9 @@ static int readsTable(Parse *p, int iDb, Table *pTab){ /* ** Locate or create an AutoincInfo structure associated with table pTab ** which is in database iDb. Return the register number for the register -** that holds the maximum rowid. +** that holds the maximum rowid. Return zero if pTab is not an AUTOINCREMENT +** table. (Also return zero when doing a VACUUM since we do not want to +** update the AUTOINCREMENT counters during a VACUUM.) ** ** There is at most one AutoincInfo structure per table even if the ** same table is autoincremented multiple times due to inserts within @@ -223,7 +225,9 @@ static int autoIncBegin( Table *pTab /* The table we are writing to */ ){ int memId = 0; /* Register holding maximum rowid */ - if( pTab->tabFlags & TF_Autoincrement ){ + if( (pTab->tabFlags & TF_Autoincrement)!=0 + && (pParse->db->flags & SQLITE_Vacuum)==0 + ){ Parse *pToplevel = sqlite3ParseToplevel(pParse); AutoincInfo *pInfo; diff --git a/src/parse.y b/src/parse.y index 087c52c839..153bc9a2bc 100644 --- a/src/parse.y +++ b/src/parse.y @@ -1285,8 +1285,8 @@ cmd ::= DROP INDEX ifexists(E) fullname(X). {sqlite3DropIndex(pParse, X, E);} // %ifndef SQLITE_OMIT_VACUUM %ifndef SQLITE_OMIT_ATTACH -cmd ::= VACUUM. {sqlite3Vacuum(pParse);} -cmd ::= VACUUM nm. {sqlite3Vacuum(pParse);} +cmd ::= VACUUM. {sqlite3Vacuum(pParse,0);} +cmd ::= VACUUM nm(X). {sqlite3Vacuum(pParse,&X);} %endif SQLITE_OMIT_ATTACH %endif SQLITE_OMIT_VACUUM diff --git a/src/prepare.c b/src/prepare.c index e193c54665..1f7f84a020 100644 --- a/src/prepare.c +++ b/src/prepare.c @@ -73,6 +73,7 @@ int sqlite3InitCallback(void *pInit, int argc, char **argv, char **NotUsed){ ** structures that describe the table, index, or view. */ int rc; + u8 saved_iDb = db->init.iDb; sqlite3_stmt *pStmt; TESTONLY(int rcp); /* Return code from sqlite3_prepare() */ @@ -83,7 +84,8 @@ int sqlite3InitCallback(void *pInit, int argc, char **argv, char **NotUsed){ TESTONLY(rcp = ) sqlite3_prepare(db, argv[2], -1, &pStmt, 0); rc = db->errCode; assert( (rc&0xFF)==(rcp&0xFF) ); - db->init.iDb = 0; + db->init.iDb = saved_iDb; + assert( saved_iDb==0 || (db->flags & SQLITE_Vacuum)!=0 ); if( SQLITE_OK!=rc ){ if( db->init.orphanTrigger ){ assert( iDb==1 ); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 17f3efc6d0..3a5953b384 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3701,8 +3701,8 @@ Table *sqlite3LocateTableItem(Parse*,u32 flags,struct SrcList_item *); Index *sqlite3FindIndex(sqlite3*,const char*, const char*); void sqlite3UnlinkAndDeleteTable(sqlite3*,int,const char*); void sqlite3UnlinkAndDeleteIndex(sqlite3*,int,const char*); -void sqlite3Vacuum(Parse*); -int sqlite3RunVacuum(char**, sqlite3*); +void sqlite3Vacuum(Parse*,Token*); +int sqlite3RunVacuum(char**, sqlite3*, int); char *sqlite3NameFromToken(sqlite3*, Token*); int sqlite3ExprCompare(Expr*, Expr*, int); int sqlite3ExprListCompare(ExprList*, ExprList*, int); diff --git a/src/vacuum.c b/src/vacuum.c index eb07664c88..56e74fdd11 100644 --- a/src/vacuum.c +++ b/src/vacuum.c @@ -18,57 +18,51 @@ #include "vdbeInt.h" #if !defined(SQLITE_OMIT_VACUUM) && !defined(SQLITE_OMIT_ATTACH) -/* -** Finalize a prepared statement. If there was an error, store the -** text of the error message in *pzErrMsg. Return the result code. -*/ -static int vacuumFinalize(sqlite3 *db, sqlite3_stmt *pStmt, char **pzErrMsg){ - int rc; - rc = sqlite3VdbeFinalize((Vdbe*)pStmt); - if( rc ){ - sqlite3SetString(pzErrMsg, db, sqlite3_errmsg(db)); - } - return rc; -} /* -** Execute zSql on database db. Return an error code. +** Execute zSql on database db. +** +** If zSql begins with 'S' (if it is a SELECT statement) then +** take each row of result and call execSql() again recursively. +** It is guaranteed that each row will have only one column that +** does not begin with 'S'. +** +** The execSqlF() routine does the same thing, except it accepts +** a format string as its third argument */ static int execSql(sqlite3 *db, char **pzErrMsg, const char *zSql){ - sqlite3_stmt *pStmt; - VVA_ONLY( int rc; ) - if( !zSql ){ - return SQLITE_NOMEM_BKPT; - } - if( SQLITE_OK!=sqlite3_prepare(db, zSql, -1, &pStmt, 0) ){ - sqlite3SetString(pzErrMsg, db, sqlite3_errmsg(db)); - return sqlite3_errcode(db); - } - VVA_ONLY( rc = ) sqlite3_step(pStmt); - assert( rc!=SQLITE_ROW || (db->flags&SQLITE_CountRows) ); - return vacuumFinalize(db, pStmt, pzErrMsg); -} - -/* -** Execute zSql on database db. The statement returns exactly -** one column. Execute this as SQL on the same database. -*/ -static int execExecSql(sqlite3 *db, char **pzErrMsg, const char *zSql){ sqlite3_stmt *pStmt; int rc; - rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0); + /* printf("SQL: [%s]\n", zSql); fflush(stdout); */ + rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); if( rc!=SQLITE_OK ) return rc; - - while( SQLITE_ROW==sqlite3_step(pStmt) ){ - rc = execSql(db, pzErrMsg, (char*)sqlite3_column_text(pStmt, 0)); - if( rc!=SQLITE_OK ){ - vacuumFinalize(db, pStmt, pzErrMsg); - return rc; + while( SQLITE_ROW==(rc = sqlite3_step(pStmt)) && zSql[0]=='S' ){ + const char *zSubSql = (const char*)sqlite3_column_text(pStmt,0); + if( zSubSql ){ + assert( zSubSql[0]!='S' ); + rc = execSql(db, pzErrMsg, zSubSql); + if( rc!=SQLITE_OK ) break; } } - - return vacuumFinalize(db, pStmt, pzErrMsg); + if( rc==SQLITE_ROW || rc==SQLITE_DONE ) rc = SQLITE_OK; + if( rc ){ + sqlite3SetString(pzErrMsg, db, sqlite3_errmsg(db)); + } + (void)sqlite3_finalize(pStmt); + return rc; +} +static int execSqlF(sqlite3 *db, char **pzErrMsg, const char *zSql, ...){ + char *z; + va_list ap; + int rc; + va_start(ap, zSql); + z = sqlite3VMPrintf(db, zSql, ap); + va_end(ap); + if( z==0 ) return SQLITE_NOMEM; + rc = execSql(db, pzErrMsg, z); + sqlite3DbFree(db, z); + return rc; } /* @@ -101,11 +95,12 @@ static int execExecSql(sqlite3 *db, char **pzErrMsg, const char *zSql){ ** transient would cause the database file to appear to be deleted ** following reboot. */ -void sqlite3Vacuum(Parse *pParse){ +void sqlite3Vacuum(Parse *pParse, Token *pNm){ Vdbe *v = sqlite3GetVdbe(pParse); - if( v ){ - sqlite3VdbeAddOp2(v, OP_Vacuum, 0, 0); - sqlite3VdbeUsesBtree(v, 0); + int iDb = pNm ? sqlite3TwoPartName(pParse, pNm, pNm, &pNm) : 0; + if( v && (iDb>=2 || iDb==0) ){ + sqlite3VdbeAddOp1(v, OP_Vacuum, iDb); + sqlite3VdbeUsesBtree(v, iDb); } return; } @@ -113,11 +108,10 @@ void sqlite3Vacuum(Parse *pParse){ /* ** This routine implements the OP_Vacuum opcode of the VDBE. */ -int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){ +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 */ - char *zSql = 0; /* SQL statements */ int saved_flags; /* Saved value of the db->flags */ int saved_nChange; /* Saved value of db->nChange */ int saved_nTotalChange; /* Saved value of db->nTotalChange */ @@ -126,6 +120,7 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){ int isMemDb; /* True if vacuuming a :memory: database */ int nRes; /* Bytes of reserved space at the end of each page */ int nDb; /* Number of attached databases */ + const char *zDbMain; /* Schema name of database to vacuum */ if( !db->autoCommit ){ sqlite3SetString(pzErrMsg, db, "cannot VACUUM from within a transaction"); @@ -143,11 +138,13 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){ saved_nChange = db->nChange; saved_nTotalChange = db->nTotalChange; saved_mTrace = db->mTrace; - db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks | SQLITE_PreferBuiltin; + db->flags |= (SQLITE_WriteSchema | SQLITE_IgnoreChecks + | SQLITE_PreferBuiltin | SQLITE_Vacuum); db->flags &= ~(SQLITE_ForeignKeys | SQLITE_ReverseOrder); db->mTrace = 0; - pMain = db->aDb[0].pBt; + zDbMain = db->aDb[iDb].zDbSName; + pMain = db->aDb[iDb].pBt; isMemDb = sqlite3PagerIsMemdb(sqlite3BtreePager(pMain)); /* Attach the temporary database as 'vacuum_db'. The synchronous pragma @@ -165,18 +162,12 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){ ** to write the journal header file. */ nDb = db->nDb; - if( sqlite3TempInMemory(db) ){ - zSql = "ATTACH ':memory:' AS vacuum_db;"; - }else{ - zSql = "ATTACH '' AS vacuum_db;"; - } - rc = execSql(db, pzErrMsg, zSql); - if( db->nDb>nDb ){ - pDb = &db->aDb[db->nDb-1]; - assert( strcmp(pDb->zDbSName,"vacuum_db")==0 ); - } + rc = execSql(db, pzErrMsg, "ATTACH''AS vacuum_db"); if( rc!=SQLITE_OK ) goto end_of_vacuum; - pTemp = db->aDb[db->nDb-1].pBt; + assert( (db->nDb-1)==nDb ); + pDb = &db->aDb[nDb]; + assert( strcmp(pDb->zDbSName,"vacuum_db")==0 ); + pTemp = pDb->pBt; /* The call to execSql() to attach the temp database has left the file ** locked (as there was more than one active statement when the transaction @@ -197,16 +188,15 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){ } #endif - sqlite3BtreeSetCacheSize(pTemp, db->aDb[0].pSchema->cache_size); + sqlite3BtreeSetCacheSize(pTemp, db->aDb[iDb].pSchema->cache_size); sqlite3BtreeSetSpillSize(pTemp, sqlite3BtreeSetSpillSize(pMain,0)); - rc = execSql(db, pzErrMsg, "PRAGMA vacuum_db.synchronous=OFF"); - if( rc!=SQLITE_OK ) goto end_of_vacuum; + sqlite3BtreeSetPagerFlags(pTemp, PAGER_SYNCHRONOUS_OFF); /* Begin a transaction and take an exclusive lock on the main database ** file. This is done before the sqlite3BtreeGetPageSize(pMain) call below, ** to ensure that we do not try to change the page-size on a WAL database. */ - rc = execSql(db, pzErrMsg, "BEGIN;"); + rc = execSql(db, pzErrMsg, "BEGIN"); if( rc!=SQLITE_OK ) goto end_of_vacuum; rc = sqlite3BtreeBeginTrans(pMain, 2); if( rc!=SQLITE_OK ) goto end_of_vacuum; @@ -233,64 +223,48 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){ /* Query the schema of the main database. Create a mirror schema ** in the temporary database. */ - rc = execExecSql(db, pzErrMsg, - "SELECT 'CREATE TABLE vacuum_db.' || substr(sql,14) " - " FROM sqlite_master WHERE type='table' AND name!='sqlite_sequence'" - " AND coalesce(rootpage,1)>0" + db->init.iDb = nDb; /* force new CREATE statements into vacuum_db */ + rc = execSqlF(db, pzErrMsg, + "SELECT sql FROM \"%w\".sqlite_master" + " WHERE type='table'AND name<>'sqlite_sequence'" + " AND coalesce(rootpage,1)>0", + zDbMain ); if( rc!=SQLITE_OK ) goto end_of_vacuum; - rc = execExecSql(db, pzErrMsg, - "SELECT 'CREATE INDEX vacuum_db.' || substr(sql,14)" - " FROM sqlite_master WHERE sql LIKE 'CREATE INDEX %' "); - if( rc!=SQLITE_OK ) goto end_of_vacuum; - rc = execExecSql(db, pzErrMsg, - "SELECT 'CREATE UNIQUE INDEX vacuum_db.' || substr(sql,21) " - " FROM sqlite_master WHERE sql LIKE 'CREATE UNIQUE INDEX %'"); + rc = execSqlF(db, pzErrMsg, + "SELECT sql FROM \"%w\".sqlite_master" + " WHERE type='index' AND length(sql)>10", + zDbMain + ); if( rc!=SQLITE_OK ) goto end_of_vacuum; + db->init.iDb = 0; /* Loop through the tables in the main database. For each, do ** an "INSERT INTO vacuum_db.xxx SELECT * FROM main.xxx;" to copy ** the contents to the temporary database. */ - assert( (db->flags & SQLITE_Vacuum)==0 ); - db->flags |= SQLITE_Vacuum; - rc = execExecSql(db, pzErrMsg, - "SELECT 'INSERT INTO vacuum_db.' || quote(name) " - "|| ' SELECT * FROM main.' || quote(name) || ';'" - "FROM main.sqlite_master " - "WHERE type = 'table' AND name!='sqlite_sequence' " - " AND coalesce(rootpage,1)>0" + rc = execSqlF(db, pzErrMsg, + "SELECT'INSERT INTO vacuum_db.'||quote(name)" + "||' SELECT*FROM\"%w\".'||quote(name)" + "FROM vacuum_db.sqlite_master " + "WHERE type='table'AND coalesce(rootpage,1)>0", + zDbMain ); assert( (db->flags & SQLITE_Vacuum)!=0 ); db->flags &= ~SQLITE_Vacuum; if( rc!=SQLITE_OK ) goto end_of_vacuum; - /* Copy over the sequence table - */ - rc = execExecSql(db, pzErrMsg, - "SELECT 'DELETE FROM vacuum_db.' || quote(name) || ';' " - "FROM vacuum_db.sqlite_master WHERE name='sqlite_sequence' " - ); - if( rc!=SQLITE_OK ) goto end_of_vacuum; - rc = execExecSql(db, pzErrMsg, - "SELECT 'INSERT INTO vacuum_db.' || quote(name) " - "|| ' SELECT * FROM main.' || quote(name) || ';' " - "FROM vacuum_db.sqlite_master WHERE name=='sqlite_sequence';" - ); - if( rc!=SQLITE_OK ) goto end_of_vacuum; - - /* Copy the triggers, views, and virtual tables from the main database ** over to the temporary database. None of these objects has any ** associated storage, so all we have to do is copy their entries ** from the SQLITE_MASTER table. */ - rc = execSql(db, pzErrMsg, - "INSERT INTO vacuum_db.sqlite_master " - " SELECT type, name, tbl_name, rootpage, sql" - " FROM main.sqlite_master" - " WHERE type='view' OR type='trigger'" - " OR (type='table' AND rootpage=0)" + rc = execSqlF(db, pzErrMsg, + "INSERT INTO vacuum_db.sqlite_master" + " SELECT*FROM \"%w\".sqlite_master" + " WHERE type IN('view','trigger')" + " OR(type='table'AND rootpage=0)", + zDbMain ); if( rc ) goto end_of_vacuum; @@ -344,6 +318,7 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){ end_of_vacuum: /* Restore the original value of db->flags */ + db->init.iDb = 0; db->flags = saved_flags; db->nChange = saved_nChange; db->nTotalChange = saved_nTotalChange; diff --git a/src/vdbe.c b/src/vdbe.c index e8fd26f5ce..d5a5886326 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -6262,15 +6262,14 @@ case OP_JournalMode: { /* out2 */ #endif /* SQLITE_OMIT_PRAGMA */ #if !defined(SQLITE_OMIT_VACUUM) && !defined(SQLITE_OMIT_ATTACH) -/* Opcode: Vacuum * * * * * +/* Opcode: Vacuum P1 * * * * ** -** Vacuum the entire database. This opcode will cause other virtual -** machines to be created and run. It may not be called from within -** a transaction. +** Vacuum the entire database P1. P1 is 0 for "main", and 2 or more +** for an attached database. The "temp" database may not be vacuumed. */ case OP_Vacuum: { assert( p->readOnly==0 ); - rc = sqlite3RunVacuum(&p->zErrMsg, db); + rc = sqlite3RunVacuum(&p->zErrMsg, db, pOp->p1); if( rc ) goto abort_due_to_error; break; } diff --git a/test/e_vacuum.test b/test/e_vacuum.test index c3e517a892..5bb2e9dbf0 100644 --- a/test/e_vacuum.test +++ b/test/e_vacuum.test @@ -202,12 +202,8 @@ do_execsql_test e_vacuum-2.1.1 { } {} set original_size [file size test.db2] -# Try everything we can think of to get the aux database vacuumed: +# Vacuuming the main database does not affect aux do_execsql_test e_vacuum-2.1.3 { VACUUM } {} -do_execsql_test e_vacuum-2.1.4 { VACUUM aux } {} -do_execsql_test e_vacuum-2.1.5 { VACUUM 'test.db2' } {} - -# Despite our efforts, space in the aux database has not been reclaimed: do_test e_vacuum-2.1.6 { expr {[file size test.db2]==$::original_size} } 1 # EVIDENCE-OF: R-17495-17419 The VACUUM command may change the ROWIDs of diff --git a/test/vacuum5.test b/test/vacuum5.test new file mode 100644 index 0000000000..4a5aecc796 --- /dev/null +++ b/test/vacuum5.test @@ -0,0 +1,111 @@ +# 2016-08-19 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# This file implements a test for VACUUM on attached databases. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +# If the VACUUM statement is disabled in the current build, skip all +# the tests in this file. +# +ifcapable !vacuum { + finish_test + return +} + +forcedelete test2.db test3.db +do_execsql_test vacuum5-1.1 { + CREATE TABLE main.t1(a,b); + WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<1000) + INSERT INTO t1(a,b) SELECT x, randomblob(1000) FROM c; + CREATE TEMP TABLE ttemp(x,y); + INSERT INTO ttemp SELECT * FROM t1; + ATTACH 'test2.db' AS x2; + ATTACH 'test3.db' AS x3; + CREATE TABLE x2.t2(c,d); + INSERT INTO t2 SELECT * FROM t1; + CREATE TABLE x3.t3(e,f); + INSERT INTO t3 SELECT * FROM t1; + DELETE FROM t1 WHERE (rowid%3)!=0; + DELETE FROM t2 WHERE (rowid%4)!=0; + DELETE FROM t3 WHERE (rowid%5)!=0; + PRAGMA main.integrity_check; + PRAGMA x2.integrity_check; + PRAGMA x3.integrity_check; +} {ok ok ok} +set size1 [file size test.db] +set size2 [file size test2.db] +set size3 [file size test3.db] + +do_execsql_test vacuum5-1.2.1 { + VACUUM main; +} {} +do_test vacuum5-1.2.2 { + expr {[file size test.db]<$size1} +} {1} +do_test vacuum5-1.2.3 { + file size test2.db +} $size2 +do_test vacuum5-1.2.4 { + file size test3.db +} $size3 +set size1 [file size test.db] +do_execsql_test vacuum-1.2.5 { + DELETE FROM t1; + PRAGMA main.integrity_check; +} {ok} + +do_execsql_test vacuum5-1.3.1 { + VACUUM x2; +} {} +do_test vacuum5-1.3.2 { + file size test.db +} $size1 +do_test vacuum5-1.3.3 { + expr {[file size test2.db]<$size2} +} 1 +do_test vacuum5-1.3.4 { + file size test3.db +} $size3 +set size2 [file size test2.db] +do_execsql_test vacuum-1.3.5 { + DELETE FROM t2; + PRAGMA x2.integrity_check; +} {ok} + +do_execsql_test vacuum5-1.4.1 { + VACUUM x3; +} {} +do_test vacuum5-1.3.2 { + file size test.db +} $size1 +do_test vacuum5-1.3.3 { + file size test2.db +} $size2 +do_test vacuum5-1.3.4 { + expr {[file size test3.db]<$size3} +} 1 + +# VACUUM is a no-op on the TEMP table +# +set sizeTemp [db one {PRAGMA temp.page_count}] +do_execsql_test vacuum5-1.4.1 { + VACUUM temp; +} {} +do_execsql_test vacuum5-1.4.2 { + PRAGMA temp.page_count; +} $sizeTemp + +do_catchsql_test vacuum5-2.0 { + VACUUM olaf; +} {1 {unknown database olaf}} From 7ca1ea16ff99968db8994405c2d1c542e9a9d22f Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 19 Aug 2016 14:25:38 +0000 Subject: [PATCH 0716/1484] Have the fts5 snippet() function avoid favouring snippets that begin with sentences that do not contain search terms. Add an extra bias in favour of the first sentence in the document. FossilOrigin-Name: d8180af2adfc101dfce95a0498b5cd7b30643b30 --- ext/fts5/fts5_aux.c | 47 ++++++++++++++++++++++++++------------------- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 34 insertions(+), 27 deletions(-) diff --git a/ext/fts5/fts5_aux.c b/ext/fts5/fts5_aux.c index ca55fd6b01..8efe05968e 100644 --- a/ext/fts5/fts5_aux.c +++ b/ext/fts5/fts5_aux.c @@ -422,39 +422,46 @@ static void fts5SnippetFunction( rc = pApi->xColumnSize(pFts, i, &nDocsize); if( rc!=SQLITE_OK ) break; - for(ii=0; rc==SQLITE_OK && iinBestScore ){ - nBestScore = nScore; - iBestCol = i; - iBestStart = sFinder.aFirst[ii]; - nColSize = nDocsize; - } - } - for(ii=0; rc==SQLITE_OK && iixInst(pFts, ii, &ip, &ic, &io); if( ic!=i || rc!=SQLITE_OK ) continue; memset(aSeen, 0, nPhrase); rc = fts5SnippetScore(pApi, pFts, nDocsize, aSeen, i, - io, nToken, &nScore, &io + io, nToken, &nScore, &iAdj ); if( rc==SQLITE_OK && nScore>nBestScore ){ nBestScore = nScore; iBestCol = i; - iBestStart = io; + iBestStart = iAdj; nColSize = nDocsize; } + + if( rc==SQLITE_OK && sFinder.nFirst ){ + for(jj=0; jj<(sFinder.nFirst-1); jj++){ + if( sFinder.aFirst[jj+1]>io ) break; + } + + if( sFinder.aFirst[jj]nBestScore ){ + nBestScore = nScore; + iBestCol = i; + iBestStart = sFinder.aFirst[jj]; + nColSize = nDocsize; + } + } + } } } } diff --git a/manifest b/manifest index 9749b2bf53..f261342285 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Adjust\ssome\stests\sto\saccount\sfor\srecent\schanges\sto\sthe\sfts5\ssnippet\sfunction. -D 2016-08-18T14:47:48.448 +C Have\sthe\sfts5\ssnippet()\sfunction\savoid\sfavouring\ssnippets\sthat\sbegin\swith\ssentences\sthat\sdo\snot\scontain\ssearch\sterms.\sAdd\san\sextra\sbias\sin\sfavour\sof\sthe\sfirst\ssentence\sin\sthe\sdocument. +D 2016-08-19T14:25:38.928 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -99,7 +99,7 @@ F ext/fts3/unicode/parseunicode.tcl da577d1384810fb4e2b209bf3313074353193e95 F ext/fts5/extract_api_docs.tcl a36e54ec777172ddd3f9a88daf593b00848368e0 F ext/fts5/fts5.h 62f3e33ceeb9a428db139f9c012186b371da1cc7 F ext/fts5/fts5Int.h b2eda36e0f224365c8e23dc8f559311834f1c13f -F ext/fts5/fts5_aux.c 5921bbef4c78b86159111335135837a867f1ff8a +F ext/fts5/fts5_aux.c 26a2b7e5f02cdc6b7322b85f473e488de452a5be F ext/fts5/fts5_buffer.c 4c1502d4c956cd092c89ce4480867f9d8bf325cd F ext/fts5/fts5_config.c 5af9c360e99669d29f06492c370892394aba0857 F ext/fts5/fts5_expr.c 1ee97156421919e497595bfa962bb88ad1665401 @@ -1510,7 +1510,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 60de159476edbd48dc363f7f77f09c32ea68422f -R 8546174dc7a44b2b80755efe3cb03b8a +P 184ecbe9c0c3280a22cdeda5c7836a7b280c3e1f +R 1ef5a5b8d26eab21fbb58bf0464e61ed U dan -Z b3f4b9f04ef4ae0622fcf2d28707aee5 +Z ed743fa5b6cead3848c470a1b5a47844 diff --git a/manifest.uuid b/manifest.uuid index eb9043217f..c3129c10b9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -184ecbe9c0c3280a22cdeda5c7836a7b280c3e1f \ No newline at end of file +d8180af2adfc101dfce95a0498b5cd7b30643b30 \ No newline at end of file From 6a754dc76765ff0069f8e803b1c601422e663b84 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 19 Aug 2016 15:12:38 +0000 Subject: [PATCH 0717/1484] Disable row counting on queries run while doing a VACUUM. FossilOrigin-Name: ad35ef116296e5d6aaeb9ef260bf35bee3bd6d20 --- manifest | 15 ++++++--------- manifest.uuid | 2 +- src/vacuum.c | 15 ++++++++------- 3 files changed, 15 insertions(+), 17 deletions(-) diff --git a/manifest b/manifest index fea0d6a17b..1f7557a84d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\scapability\sto\sVACUUM\san\sattached\sdatabase\sby\sspecifying\sthe\sschema\nname\sas\san\sargument\sto\sthe\sVACUUM\scommand.\s\sSince\sversion\s2.0,\sVACUUM\shas\naccepted\san\sargument\swhich\swas\ssilently\signored.\s\sNow\sit\shas\smeaning. -D 2016-08-19T14:20:56.900 +C Disable\srow\scounting\son\squeries\srun\swhile\sdoing\sa\sVACUUM. +D 2016-08-19T15:12:38.157 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -449,7 +449,7 @@ F src/trigger.c 11e20b3b12c847b3b9055594c0f1631266bb53fc F src/update.c 8179e699dbd45b92934fd02d3d8e3732e8da8802 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 810ec3f22e2d1b62e66c30fe3621ebdedd23584d -F src/vacuum.c 0fecf4ba5ae91a2f1d601345f976b028888803d4 +F src/vacuum.c 913970b9d86dd6c2b8063ef1af421880f1464ec3 F src/vdbe.c 15376952b0c5dc0afbac6cd8791579dd19ff0a01 F src/vdbe.h 67bc551f7faf04c33493892e4b378aada823ed10 F src/vdbeInt.h c59381049af5c7751a83456c39b80d1a6fde1f9d @@ -1511,10 +1511,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P cb9865e14db1c0076618f13400151112f84960cb -R d22b71c0b6e2dcfd7355ff82dbeacb9a -T *branch * vacuum-attached-db -T *sym-vacuum-attached-db * -T -sym-trunk * +P 29d63059b4d2bb612523ac55ebfef040d054a64f +R abd29f9f3d87c2af53d085425233b2a6 U drh -Z 9021190c8e1ac254dada8dc6dfa393f1 +Z 5800f169232e621dbe2100315fb2f1aa diff --git a/manifest.uuid b/manifest.uuid index e1b549e940..bc4fefd82a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -29d63059b4d2bb612523ac55ebfef040d054a64f \ No newline at end of file +ad35ef116296e5d6aaeb9ef260bf35bee3bd6d20 \ No newline at end of file diff --git a/src/vacuum.c b/src/vacuum.c index 56e74fdd11..295beb6752 100644 --- a/src/vacuum.c +++ b/src/vacuum.c @@ -22,10 +22,9 @@ /* ** Execute zSql on database db. ** -** If zSql begins with 'S' (if it is a SELECT statement) then -** take each row of result and call execSql() again recursively. -** It is guaranteed that each row will have only one column that -** does not begin with 'S'. +** If zSql returns rows, then each row will have exactly one +** column. (This will only happen if zSql begins with "SELECT".) +** Take each row of result and call execSql() again recursively. ** ** The execSqlF() routine does the same thing, except it accepts ** a format string as its third argument @@ -37,15 +36,17 @@ static int execSql(sqlite3 *db, char **pzErrMsg, const char *zSql){ /* printf("SQL: [%s]\n", zSql); fflush(stdout); */ rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); if( rc!=SQLITE_OK ) return rc; - while( SQLITE_ROW==(rc = sqlite3_step(pStmt)) && zSql[0]=='S' ){ + while( SQLITE_ROW==(rc = sqlite3_step(pStmt)) ){ const char *zSubSql = (const char*)sqlite3_column_text(pStmt,0); + assert( sqlite3_strnicmp(zSql,"SELECT",6)==0 ); if( zSubSql ){ assert( zSubSql[0]!='S' ); rc = execSql(db, pzErrMsg, zSubSql); if( rc!=SQLITE_OK ) break; } } - if( rc==SQLITE_ROW || rc==SQLITE_DONE ) rc = SQLITE_OK; + assert( rc!=SQLITE_ROW ); + if( rc==SQLITE_DONE ) rc = SQLITE_OK; if( rc ){ sqlite3SetString(pzErrMsg, db, sqlite3_errmsg(db)); } @@ -140,7 +141,7 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db, int iDb){ saved_mTrace = db->mTrace; db->flags |= (SQLITE_WriteSchema | SQLITE_IgnoreChecks | SQLITE_PreferBuiltin | SQLITE_Vacuum); - db->flags &= ~(SQLITE_ForeignKeys | SQLITE_ReverseOrder); + db->flags &= ~(SQLITE_ForeignKeys | SQLITE_ReverseOrder | SQLITE_CountRows); db->mTrace = 0; zDbMain = db->aDb[iDb].zDbSName; From 4602b8e89d6949617f01f8e1f0cc0f2fb1d6bd18 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 19 Aug 2016 18:28:00 +0000 Subject: [PATCH 0718/1484] Fix an obsolete comment on codeEqualityTerm(). No changes to code. FossilOrigin-Name: d07be5afb0a915769382dfd815403f8832cb3eec --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/wherecode.c | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 23b276d0a0..17fe1e24a2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\srecent\senhancements\sfrom\strunk. -D 2016-08-19T15:41:24.228 +C Fix\san\sobsolete\scomment\son\scodeEqualityTerm().\s\sNo\schanges\sto\scode. +D 2016-08-19T18:28:00.523 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -466,7 +466,7 @@ F src/wal.h 6dd221ed384afdc204bc61e25c23ef7fd5a511f2 F src/walker.c 2d2cc7fb0f320f7f415215d7247f3c584141ac09 F src/where.c 5bee250c8233c43bd7f53897d12b8468004f63db F src/whereInt.h 14dd243e13b81cbb0a66063d38b70f93a7d6e613 -F src/wherecode.c 916b451003afef5f3a0265e62a22d7ca527656fe +F src/wherecode.c f3fd16b9b4cef1345330d22cf3f1628f87a56456 F src/whereexpr.c 8d9903d16ae45d15736745f7b75df2340c729782 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -1518,7 +1518,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 936146b12e27784f15a68fe65732c6d92c3a12f3 083f9e6270fa4faa402b91231271da4f3915c79f -R b0cf551e47740f01d348f132bf9f7791 +P b17872363b60edab05a5d382a44038aad91e4d9f +R 81462375f5cd0ff256194ab35ae61f4d U drh -Z 4f11e98ced958b5a8510961832e75233 +Z 0138a28f257e6cf64f3bd77d61380c55 diff --git a/manifest.uuid b/manifest.uuid index 64c87f47eb..a0b848e9d3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b17872363b60edab05a5d382a44038aad91e4d9f \ No newline at end of file +d07be5afb0a915769382dfd815403f8832cb3eec \ No newline at end of file diff --git a/src/wherecode.c b/src/wherecode.c index d84ace1922..dd15b5893c 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -358,8 +358,8 @@ static void codeApplyAffinity(Parse *pParse, int base, int n, char *zAff){ ** ** The current value for the constraint is left in register iReg. ** -** For a constraint of the form X=expr, the expression is evaluated and its -** result is left on the stack. For constraints of the form X IN (...) +** For a constraint of the form X=expr, the expression is evaluated in +** straight-line code. For constraints of the form X IN (...) ** this routine sets up a loop that will iterate over all values of X. */ static int codeEqualityTerm( From c9e75fb23abf0a7ba620bbc886efa63d9fefd8b0 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 19 Aug 2016 18:37:35 +0000 Subject: [PATCH 0719/1484] Register any built-in fts5 module before loading automatic extensions. This allows automatic extensions to register fts5 tokenizers and auxiliary functions. FossilOrigin-Name: b10e31dce8e590e1ba30f512374a8c16656bcc72 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/main.c | 17 ++++++++++------- 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index f261342285..a68dc1c021 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Have\sthe\sfts5\ssnippet()\sfunction\savoid\sfavouring\ssnippets\sthat\sbegin\swith\ssentences\sthat\sdo\snot\scontain\ssearch\sterms.\sAdd\san\sextra\sbias\sin\sfavour\sof\sthe\sfirst\ssentence\sin\sthe\sdocument. -D 2016-08-19T14:25:38.928 +C Register\sany\sbuilt-in\sfts5\smodule\sbefore\sloading\sautomatic\sextensions.\sThis\sallows\sautomatic\sextensions\sto\sregister\sfts5\stokenizers\sand\sauxiliary\sfunctions. +D 2016-08-19T18:37:35.386 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -349,7 +349,7 @@ F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da F src/insert.c 8f4e9fcbd8e95e85f15647ba8b413b18d556ec2b F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e F src/loadext.c dd7a2b77902cc66c22555aef02e1a682554b7aec -F src/main.c 16c1b2114eae8804caf3a8de8cb47bf2c6d83ad3 +F src/main.c 4f29b8d1b705fc3b73b26f892e85df2bfca31cff F src/malloc.c 1443d1ad95d67c21d77af7ae3f44678252f0efec F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b @@ -1510,7 +1510,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 184ecbe9c0c3280a22cdeda5c7836a7b280c3e1f -R 1ef5a5b8d26eab21fbb58bf0464e61ed +P d8180af2adfc101dfce95a0498b5cd7b30643b30 +R 60073adaf70faac8deb27fa21c3071ec U dan -Z ed743fa5b6cead3848c470a1b5a47844 +Z db6d5df26cfba25421660b26226c4ab6 diff --git a/manifest.uuid b/manifest.uuid index c3129c10b9..674031237c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d8180af2adfc101dfce95a0498b5cd7b30643b30 \ No newline at end of file +b10e31dce8e590e1ba30f512374a8c16656bcc72 \ No newline at end of file diff --git a/src/main.c b/src/main.c index f31f865818..4e4836238b 100644 --- a/src/main.c +++ b/src/main.c @@ -2948,11 +2948,20 @@ static int openDatabase( */ sqlite3Error(db, SQLITE_OK); sqlite3RegisterPerConnectionBuiltinFunctions(db); + rc = sqlite3_errcode(db); + +#ifdef SQLITE_ENABLE_FTS5 + /* Register any built-in FTS5 module before loading the automatic + ** extensions. This allows automatic extensions to register FTS5 + ** tokenizers and auxiliary functions. */ + if( !db->mallocFailed && rc==SQLITE_OK ){ + rc = sqlite3Fts5Init(db); + } +#endif /* Load automatic extensions - extensions that have been registered ** using the sqlite3_automatic_extension() API. */ - rc = sqlite3_errcode(db); if( rc==SQLITE_OK ){ sqlite3AutoLoadExtensions(db); rc = sqlite3_errcode(db); @@ -2981,12 +2990,6 @@ static int openDatabase( } #endif -#ifdef SQLITE_ENABLE_FTS5 - if( !db->mallocFailed && rc==SQLITE_OK ){ - rc = sqlite3Fts5Init(db); - } -#endif - #ifdef SQLITE_ENABLE_ICU if( !db->mallocFailed && rc==SQLITE_OK ){ rc = sqlite3IcuInit(db); From a15a8bc822a32bb376c1b76e3fc0baafe7933965 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 19 Aug 2016 18:40:17 +0000 Subject: [PATCH 0720/1484] Show the WhereTerm.iField value on debugging output, when it is non-zero. FossilOrigin-Name: 931c95358d8bc02f3e3d8ee4e545a07b2d2c97e8 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/where.c | 7 ++++++- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 17fe1e24a2..2d1e3df464 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\sobsolete\scomment\son\scodeEqualityTerm().\s\sNo\schanges\sto\scode. -D 2016-08-19T18:28:00.523 +C Show\sthe\sWhereTerm.iField\svalue\son\sdebugging\soutput,\swhen\sit\sis\snon-zero. +D 2016-08-19T18:40:17.138 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -464,7 +464,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 02eeecc265f6ffd0597378f5d8ae9070b62a406a F src/wal.h 6dd221ed384afdc204bc61e25c23ef7fd5a511f2 F src/walker.c 2d2cc7fb0f320f7f415215d7247f3c584141ac09 -F src/where.c 5bee250c8233c43bd7f53897d12b8468004f63db +F src/where.c c7cdfd54f383090bb801cdd50d36de1a24684bb2 F src/whereInt.h 14dd243e13b81cbb0a66063d38b70f93a7d6e613 F src/wherecode.c f3fd16b9b4cef1345330d22cf3f1628f87a56456 F src/whereexpr.c 8d9903d16ae45d15736745f7b75df2340c729782 @@ -1518,7 +1518,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b17872363b60edab05a5d382a44038aad91e4d9f -R 81462375f5cd0ff256194ab35ae61f4d +P d07be5afb0a915769382dfd815403f8832cb3eec +R 8b996d549f6c06da9085faa1b04f9847 U drh -Z 0138a28f257e6cf64f3bd77d61380c55 +Z 5690c4429160dd9b0cc8734ae0e94c60 diff --git a/manifest.uuid b/manifest.uuid index a0b848e9d3..6105e3743f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d07be5afb0a915769382dfd815403f8832cb3eec \ No newline at end of file +931c95358d8bc02f3e3d8ee4e545a07b2d2c97e8 \ No newline at end of file diff --git a/src/where.c b/src/where.c index f084b93701..30854ee422 100644 --- a/src/where.c +++ b/src/where.c @@ -1677,9 +1677,14 @@ static void whereTermPrint(WhereTerm *pTerm, int iTerm){ sqlite3_snprintf(sizeof(zLeft),zLeft,"left=%d", pTerm->leftCursor); } sqlite3DebugPrintf( - "TERM-%-3d %p %s %-12s prob=%-3d op=0x%03x wtFlags=0x%04x\n", + "TERM-%-3d %p %s %-12s prob=%-3d op=0x%03x wtFlags=0x%04x", iTerm, pTerm, zType, zLeft, pTerm->truthProb, pTerm->eOperator, pTerm->wtFlags); + if( pTerm->iField ){ + sqlite3DebugPrintf(" iField=%d\n", pTerm->iField); + }else{ + sqlite3DebugPrintf("\n"); + } sqlite3TreeViewExpr(0, pTerm->pExpr, 0); } } From 39a11819f3fc48e0e85e95dadb7ebabfafaa96f5 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 19 Aug 2016 19:12:58 +0000 Subject: [PATCH 0721/1484] Improved comments on sqlite3CodeSubquery(). No changes to code. FossilOrigin-Name: acea4ee136def4815d22eec240c5903a72bde9bd --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/expr.c | 27 ++++++++++++++++++--------- 3 files changed, 25 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index 2d1e3df464..75bb629cc6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Show\sthe\sWhereTerm.iField\svalue\son\sdebugging\soutput,\swhen\sit\sis\snon-zero. -D 2016-08-19T18:40:17.138 +C Improved\scomments\son\ssqlite3CodeSubquery().\s\sNo\schanges\sto\scode. +D 2016-08-19T19:12:58.298 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -338,7 +338,7 @@ F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7 F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c 76c084f0265f4a3cd1ecf17eee112a94f1ccbc05 -F src/expr.c d79a02ba0f5b44c3319154641247979c48eec637 +F src/expr.c e139851835a8532e3974ca4bc8f6b0e5aef0e06f F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c e2be0968c1adc679c87e467aa5b4f167588f38a8 F src/func.c 29cc9acb170ec1387b9f63eb52cd85f8de96c771 @@ -1518,7 +1518,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d07be5afb0a915769382dfd815403f8832cb3eec -R 8b996d549f6c06da9085faa1b04f9847 +P 931c95358d8bc02f3e3d8ee4e545a07b2d2c97e8 +R 041e4a08027e633fe8c3ceee8cf4a385 U drh -Z 5690c4429160dd9b0cc8734ae0e94c60 +Z b93c8a041c20867db97a84e58d7255a6 diff --git a/manifest.uuid b/manifest.uuid index 6105e3743f..715e015f26 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -931c95358d8bc02f3e3d8ee4e545a07b2d2c97e8 \ No newline at end of file +acea4ee136def4815d22eec240c5903a72bde9bd \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 4f02c98c45..1949be50af 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2211,7 +2211,9 @@ void sqlite3SubselectError(Parse *pParse, int nActual, int nExpect){ ** value to non-NULL if the RHS is NULL-free. ** ** For a SELECT or EXISTS operator, return the register that holds the -** result. For IN operators or if an error occurs, the return value is 0. +** result. For a multi-column SELECT, the result is stored in a contiguous +** array of registers and the return value is the register of the left-most +** result column. Return 0 for IN operators or if an error occurs. */ #ifndef SQLITE_OMIT_SUBQUERY int sqlite3CodeSubselect( @@ -2226,8 +2228,8 @@ int sqlite3CodeSubselect( if( NEVER(v==0) ) return 0; sqlite3ExprCachePush(pParse); - /* This code must be run in its entirety every time it is encountered - ** if any of the following is true: + /* The evaluation of the IN/EXISTS/SELECT must be repeated every time it + ** is encountered if any of the following is true: ** ** * The right-hand side is a correlated subquery ** * The right-hand side is an expression list containing variables @@ -2387,14 +2389,21 @@ int sqlite3CodeSubselect( case TK_EXISTS: case TK_SELECT: default: { - /* If this has to be a scalar SELECT. Generate code to put the - ** value of this select in a memory cell and record the number - ** of the memory cell in iColumn. If this is an EXISTS, write - ** an integer 0 (not exists) or 1 (exists) into a memory cell - ** and record that memory cell in iColumn. + /* Case 3: (SELECT ... FROM ...) + ** or: EXISTS(SELECT ... FROM ...) + ** + ** For a SELECT, generate code to put the values for all columns of + ** the first row into an array of registers and return the index of + ** the first register. + ** + ** If this is an EXISTS, write an integer 0 (not exists) or 1 (exists) + ** into a register and return that register number. + ** + ** In both cases, the query is augmented with "LIMIT 1". Any + ** preexisting limit is discarded in place of the new LIMIT 1. */ Select *pSel; /* SELECT statement to encode */ - SelectDest dest; /* How to deal with SELECt result */ + SelectDest dest; /* How to deal with SELECT result */ int nReg; /* Registers to allocate */ testcase( pExpr->op==TK_EXISTS ); From 8d25cb90cdc01b79eb368299c24846388c4e7866 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 19 Aug 2016 19:58:06 +0000 Subject: [PATCH 0722/1484] Replace the magic number (-2) with its symbol XN_EXPR in the exprMightBeIndexed() routine. No logic changes. FossilOrigin-Name: d4a5af69cc3bde6f8c02075c07b4d47a0252392d --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/whereexpr.c | 7 ++++--- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 75bb629cc6..760f93473c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improved\scomments\son\ssqlite3CodeSubquery().\s\sNo\schanges\sto\scode. -D 2016-08-19T19:12:58.298 +C Replace\sthe\smagic\snumber\s(-2)\swith\sits\ssymbol\sXN_EXPR\sin\sthe\nexprMightBeIndexed()\sroutine.\s\sNo\slogic\schanges. +D 2016-08-19T19:58:06.626 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -467,7 +467,7 @@ F src/walker.c 2d2cc7fb0f320f7f415215d7247f3c584141ac09 F src/where.c c7cdfd54f383090bb801cdd50d36de1a24684bb2 F src/whereInt.h 14dd243e13b81cbb0a66063d38b70f93a7d6e613 F src/wherecode.c f3fd16b9b4cef1345330d22cf3f1628f87a56456 -F src/whereexpr.c 8d9903d16ae45d15736745f7b75df2340c729782 +F src/whereexpr.c bb22074cc2712c5013ecacdf7d652e7568a47bc3 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1518,7 +1518,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 931c95358d8bc02f3e3d8ee4e545a07b2d2c97e8 -R 041e4a08027e633fe8c3ceee8cf4a385 +P acea4ee136def4815d22eec240c5903a72bde9bd +R 223c403e8b392fa16a54efbf6c58e1ba U drh -Z b93c8a041c20867db97a84e58d7255a6 +Z b5c0cabb5688d369770dffa65d09a7da diff --git a/manifest.uuid b/manifest.uuid index 715e015f26..95b5affc2d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -acea4ee136def4815d22eec240c5903a72bde9bd \ No newline at end of file +d4a5af69cc3bde6f8c02075c07b4d47a0252392d \ No newline at end of file diff --git a/src/whereexpr.c b/src/whereexpr.c index 23efed9761..2fc903ce6e 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -823,7 +823,8 @@ static Bitmask exprSelectUsage(WhereMaskSet *pMaskSet, Select *pS){ ** in any index. Return TRUE (1) if pExpr is an indexed term and return ** FALSE (0) if not. If TRUE is returned, also set *piCur to the cursor ** number of the table that is indexed and *piColumn to the column number -** of the column that is indexed, or -2 if an expression is being indexed. +** of the column that is indexed, or XN_EXPR (-2) if an expression is being +** indexed. ** ** If pExpr is a TK_COLUMN column reference, then this routine always returns ** true even if that particular column is not indexed, because the column @@ -861,10 +862,10 @@ static int exprMightBeIndexed( for(pIdx=pFrom->a[i].pTab->pIndex; pIdx; pIdx=pIdx->pNext){ if( pIdx->aColExpr==0 ) continue; for(i=0; inKeyCol; i++){ - if( pIdx->aiColumn[i]!=(-2) ) continue; + if( pIdx->aiColumn[i]!=XN_EXPR ) continue; if( sqlite3ExprCompare(pExpr, pIdx->aColExpr->a[i].pExpr, iCur)==0 ){ *piCur = iCur; - *piColumn = -2; + *piColumn = XN_EXPR; return 1; } } From fc7f27b9d2e4083faba332a9a15d182549f68cb2 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 20 Aug 2016 00:07:01 +0000 Subject: [PATCH 0723/1484] Change the way TK_SELECT_COLUMN is handled so that the subquery is only generated once even if part of the vector comparison is used for indexing and the other part is now. This change also is a pathway to vector assignment in UPDATE statements. FossilOrigin-Name: d8feea7dcde83179bff303072426561cfe825e58 --- manifest | 20 +++++------ manifest.uuid | 2 +- src/expr.c | 95 +++++++++++++++++++++++++++++++++++++++++-------- src/sqliteInt.h | 9 +++-- src/vdbemem.c | 2 +- src/wherecode.c | 35 ++---------------- src/whereexpr.c | 32 ++++------------- 7 files changed, 106 insertions(+), 89 deletions(-) diff --git a/manifest b/manifest index 760f93473c..52c2870784 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Replace\sthe\smagic\snumber\s(-2)\swith\sits\ssymbol\sXN_EXPR\sin\sthe\nexprMightBeIndexed()\sroutine.\s\sNo\slogic\schanges. -D 2016-08-19T19:58:06.626 +C Change\sthe\sway\sTK_SELECT_COLUMN\sis\shandled\sso\sthat\sthe\ssubquery\sis\sonly\ngenerated\sonce\seven\sif\spart\sof\sthe\svector\scomparison\sis\sused\sfor\sindexing\nand\sthe\sother\spart\sis\snow.\s\sThis\schange\salso\sis\sa\spathway\sto\svector\sassignment\nin\sUPDATE\sstatements. +D 2016-08-20T00:07:01.602 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -338,7 +338,7 @@ F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7 F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c 76c084f0265f4a3cd1ecf17eee112a94f1ccbc05 -F src/expr.c e139851835a8532e3974ca4bc8f6b0e5aef0e06f +F src/expr.c ff73eb6cae76c2423928d46ceff6f2fdc379a568 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c e2be0968c1adc679c87e467aa5b4f167588f38a8 F src/func.c 29cc9acb170ec1387b9f63eb52cd85f8de96c771 @@ -389,7 +389,7 @@ F src/shell.c 79dda477be6c96eba6e952a934957ad36f87acc7 F src/sqlite.h.in 0f7580280d1b009b507d8beec1ff0f197ba0cc99 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae -F src/sqliteInt.h 02b7f4bd9f945fbc46b05f7914b9c43d89517c59 +F src/sqliteInt.h 84f32ad3a5bfaf698b82bf5a9c6939f3e3d79ee0 F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 @@ -456,7 +456,7 @@ F src/vdbeInt.h c59381049af5c7751a83456c39b80d1a6fde1f9d F src/vdbeapi.c a32d61b7dd05e6890d8fd44d2805f55e2f5ba9f3 F src/vdbeaux.c a32d79aeaa88dc2b97c261172d952d395254a055 F src/vdbeblob.c 3e82a797b60c3b9fed7b8de8c539ca7607874937 -F src/vdbemem.c 77d6505956bf4e45c328ab3ebef6b461334cab5d +F src/vdbemem.c e67dc6d8177fd1830efb5d15e17793408251a187 F src/vdbesort.c 91fda3909326860382b0ca8aa251e609c6a9d62c F src/vdbetrace.c 41963d5376f0349842b5fc4aaaaacd7d9cdc0834 F src/vtab.c 5ca4fa8b028f9e2ed4793ee1670911a83cfcefd8 @@ -466,8 +466,8 @@ F src/wal.h 6dd221ed384afdc204bc61e25c23ef7fd5a511f2 F src/walker.c 2d2cc7fb0f320f7f415215d7247f3c584141ac09 F src/where.c c7cdfd54f383090bb801cdd50d36de1a24684bb2 F src/whereInt.h 14dd243e13b81cbb0a66063d38b70f93a7d6e613 -F src/wherecode.c f3fd16b9b4cef1345330d22cf3f1628f87a56456 -F src/whereexpr.c bb22074cc2712c5013ecacdf7d652e7568a47bc3 +F src/wherecode.c 0c790c422ea5ecb6c83d6a78f2c4ebc036eea90e +F src/whereexpr.c 021469f11930cc705a26f7f31ec37640588df1d4 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1518,7 +1518,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P acea4ee136def4815d22eec240c5903a72bde9bd -R 223c403e8b392fa16a54efbf6c58e1ba +P d4a5af69cc3bde6f8c02075c07b4d47a0252392d +R 8a9288690d2190168e2ddd79f5078350 U drh -Z b5c0cabb5688d369770dffa65d09a7da +Z 663c48e63b0d59d8fc6b403d2678eeeb diff --git a/manifest.uuid b/manifest.uuid index 95b5affc2d..a8cf8cf3bc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d4a5af69cc3bde6f8c02075c07b4d47a0252392d \ No newline at end of file +d8feea7dcde83179bff303072426561cfe825e58 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 1949be50af..de2c7a6a26 100644 --- a/src/expr.c +++ b/src/expr.c @@ -334,13 +334,21 @@ int sqlite3ExprVectorSize(Expr *pExpr){ #ifndef SQLITE_OMIT_SUBQUERY /* -** If the expression passed as the first argument is a TK_VECTOR, return -** a pointer to the i'th field of the vector. Or, if the first argument -** points to a sub-select that returns more than one column, return a -** pointer to the i'th returned column value. Otherwise, return a copy -** of the first argument. +** Interpret the pVector input as a vector expression. If pVector is +** an ordinary scalar expression, treat it as a vector of size 1. +** +** Return a pointer to a subexpression of pVector that is the i-th +** column of the vector (numbered starting with 0). The caller must +** ensure that i is within range. +** +** pVector retains ownership of the returned subexpression. +** +** If the vector is a (SELECT ...) then the expression returned is +** just the expression for the i-th term of the result set, and is +** necessarily ready to be evaluated because the table cursor might +** not have been positioned yet. */ -Expr *sqlite3ExprVectorField(Expr *pVector, int i){ +Expr *sqlite3VectorFieldSubexpr(Expr *pVector, int i){ assert( iop==TK_SELECT ){ @@ -351,7 +359,57 @@ Expr *sqlite3ExprVectorField(Expr *pVector, int i){ } return pVector; } -#endif +#endif /* !defined(SQLITE_OMIT_SUBQUERY) */ + +#ifndef SQLITE_OMIT_SUBQUERY +/* +** Compute and return a new Expr object which when passed to +** sqlite3ExprCode() will generate all necessary code to compute +** the iField-th column of the vector expression pVector. +** +** The caller owns the returned Expr object and is responsible for +** ensuring that the returned value eventually gets freed. +** +** Ownership of pVector is controlled by the takeOwnership parameter. If +** takeOwnership is true, this routine takes responsibility for freeing +** pVector, and may do so before returning, hence the caller must not reference +** pVector again. If takeOwnership is false, then the caller takes +** responsibility for freeing pVector and must ensure the pVector remains +** valid as long as the returned value remains in use. +*/ +Expr *sqlite3ExprForVectorField( + Parse *pParse, /* Parsing context */ + Expr *pVector, /* The vector. List of expressions or a sub-SELECT */ + int iField, /* Which column of the vector to return */ + int takeOwnership /* True to take ownership of pVector before returning */ +){ + Expr *pRet; + assert( sqlite3ExprIsVector(pVector) ); + /* FIXME: Add support for takeOwnership!=0 */ assert( takeOwnership==0 ); + if( pVector->flags & EP_xIsSelect ){ + /* The TK_SELECT_COLUMN Expr node: + ** + ** pLeft: pVector containing TK_SELECT + ** pRight: pVector if ownership taken + ** iColumn: Index of a column in pVector + ** pLeft->iTable: First in an array of register holding result, or 0 + ** if the result is not yet computed. + ** + ** sqlite3ExprDelete() specifically skips the recursive delete of + ** pLeft on TK_SELECT_COLUMN nodes. But pRight is followed, so pVector + ** is included on pRight if ownership is taken. Typically there will + ** be multiple TK_SELECT_COLUMN nodes with the same pLeft pointer to + ** the pVector, but only one of them will own the pVector. + */ + pRet = sqlite3PExpr(pParse, TK_SELECT_COLUMN, pVector, 0, 0); + if( pRet ) pRet->iColumn = iField; + assert( pRet==0 || pRet->iTable==0 ); + }else{ + pRet = sqlite3ExprDup(pParse->db, pVector->x.pList->a[iField].pExpr, 0); + } + return pRet; +} +#endif /* !define(SQLITE_OMIT_SUBQUERY) */ /* ** If expression pExpr is of type TK_SELECT, generate code to evaluate @@ -2025,7 +2083,7 @@ int sqlite3FindInIndex( ** comparison is the same as the affinity of each column. If ** it not, it is not possible to use any index. */ for(i=0; ipLeft, i); + Expr *pLhs = sqlite3VectorFieldSubexpr(pX->pLeft, i); int iCol = pEList->a[i].pExpr->iColumn; char idxaff = pTab->aCol[iCol].affinity; char cmpaff = sqlite3CompareAffinity(pLhs, idxaff); @@ -2051,7 +2109,7 @@ int sqlite3FindInIndex( } for(i=0; ipLeft, i); + Expr *pLhs = sqlite3VectorFieldSubexpr(pX->pLeft, i); Expr *pRhs = pEList->a[i].pExpr; CollSeq *pReq = sqlite3BinaryCompareCollSeq(pParse, pLhs, pRhs); int j; @@ -2159,7 +2217,7 @@ static char *exprINAffinity(Parse *pParse, Expr *pExpr){ if( zRet ){ int i; for(i=0; ipEList->a[i].pExpr, a); @@ -2313,7 +2371,7 @@ int sqlite3CodeSubselect( assert( pEList->nExpr>0 ); assert( sqlite3KeyInfoIsWriteable(pKeyInfo) ); for(i=0; i1) ? sqlite3ExprVectorField(pLeft, i) : pLeft; + Expr *p = (nVal>1) ? sqlite3VectorFieldSubexpr(pLeft, i) : pLeft; pKeyInfo->aColl[i] = sqlite3BinaryCompareCollSeq( pParse, p, pEList->a[i].pExpr ); @@ -2553,7 +2611,7 @@ static void sqlite3ExprCodeIN( } }else{ for(i=0; ipLeft, i); + Expr *p = sqlite3VectorFieldSubexpr(pExpr->pLeft, i); if( sqlite3ExprCanBeNull(p) ){ sqlite3VdbeAddOp2(v, OP_IsNull, r1+aiMap[i], destIfNull); VdbeCoverage(v); @@ -2654,7 +2712,7 @@ static void sqlite3ExprCodeIN( Expr *p; CollSeq *pColl; int r2 = sqlite3GetTempReg(pParse); - p = sqlite3ExprVectorField(pLeft, i); + p = sqlite3VectorFieldSubexpr(pLeft, i); pColl = sqlite3ExprCollSeq(pParse, p); sqlite3VdbeAddOp3(v, OP_Column, iIdx, i, r2); @@ -2674,7 +2732,7 @@ static void sqlite3ExprCodeIN( ** result is 1. */ sqlite3VdbeJumpHere(v, addr); for(i=0; ipLeft, i); + Expr *p = sqlite3VectorFieldSubexpr(pExpr->pLeft, i); if( sqlite3ExprCanBeNull(p) ){ sqlite3VdbeAddOp2(v, OP_IsNull, r1+aiMap[i], destIfNull); VdbeCoverage(v); @@ -3510,6 +3568,13 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ } break; } + case TK_SELECT_COLUMN: { + if( pExpr->pLeft->iTable==0 ){ + pExpr->pLeft->iTable = sqlite3CodeSubselect(pParse, pExpr->pLeft, 0, 0); + } + inReg = pExpr->pLeft->iTable + pExpr->iColumn; + break; + } case TK_IN: { int destIfFalse = sqlite3VdbeMakeLabel(v); int destIfNull = sqlite3VdbeMakeLabel(v); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 7b37b030cd..7651ff69e4 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2298,9 +2298,11 @@ struct Expr { int iTable; /* TK_COLUMN: cursor number of table holding column ** TK_REGISTER: register number ** TK_TRIGGER: 1 -> new, 0 -> old - ** EP_Unlikely: 134217728 times likelihood */ + ** EP_Unlikely: 134217728 times likelihood + ** TK_SELECT: 1st register of result vector */ ynVar iColumn; /* TK_COLUMN: column index. -1 for rowid. - ** TK_VARIABLE: variable number (always >= 1). */ + ** TK_VARIABLE: variable number (always >= 1). + ** TK_SELECT_COLUMN: column of the result vector */ i16 iAgg; /* Which entry in pAggInfo->aCol[] or ->aFunc[] */ i16 iRightJoinTable; /* If EP_FromJoin, the right table of the join */ u8 op2; /* TK_REGISTER: original value of Expr.op @@ -4273,6 +4275,7 @@ int sqlite3DbstatRegister(sqlite3*); int sqlite3ExprVectorSize(Expr *pExpr); int sqlite3ExprIsVector(Expr *pExpr); -Expr *sqlite3ExprVectorField(Expr*, int); +Expr *sqlite3VectorFieldSubexpr(Expr*, int); +Expr *sqlite3ExprForVectorField(Parse*,Expr*,int,int); #endif /* SQLITEINT_H */ diff --git a/src/vdbemem.c b/src/vdbemem.c index 0709527634..bc08042000 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -1571,7 +1571,7 @@ int sqlite3Stat4ProbeSetValue( for(i=0; idb, pIdx, iVal+i); alloc.iVal = iVal+i; rc = stat4ValueFromExpr(pParse, pElem, aff, &alloc, &pVal); diff --git a/src/wherecode.c b/src/wherecode.c index dd15b5893c..2ef9a46b5d 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -377,34 +377,7 @@ static int codeEqualityTerm( assert( pLevel->pWLoop->aLTerm[iEq]==pTerm ); assert( iTarget>0 ); if( pX->op==TK_EQ || pX->op==TK_IS ){ - Expr *pRight = pX->pRight; -#ifndef SQLITE_OMIT_SUBQUERY - if( pRight->op==TK_SELECT_COLUMN ){ - /* This case occurs for expressions like "(a, b) == (SELECT ...)". */ - WhereLoop *pLoop = pLevel->pWLoop; - int i; - Expr *pSub = pRight->pLeft; - assert( pSub->op==TK_SELECT ); - for(i=pLoop->nSkip; iaLTerm[i]->pExpr->pRight; - if( pExpr && pExpr->op==TK_SELECT_COLUMN && pExpr->pLeft==pSub ) break; - } - - if( i==iEq ){ - iReg = sqlite3CodeSubselect(pParse, pSub, 0, 0); - for(/*no-op*/; inLTerm; i++){ - Expr *pExpr = pLoop->aLTerm[i]->pExpr->pRight; - if( pExpr && pExpr->op==TK_SELECT_COLUMN && pExpr->pLeft==pSub ){ - sqlite3VdbeAddOp2(v, OP_Copy, iReg+pExpr->iColumn, iTarget-iEq+i); - } - } - } - iReg = iTarget; - }else -#endif - { - iReg = sqlite3ExprCodeTarget(pParse, pRight, iTarget); - } + iReg = sqlite3ExprCodeTarget(pParse, pX->pRight, iTarget); }else if( pX->op==TK_ISNULL ){ iReg = iTarget; sqlite3VdbeAddOp2(v, OP_Null, 0, iReg); @@ -1101,11 +1074,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( addrNotFound = pLevel->addrNxt; }else{ Expr *pRight = pTerm->pExpr->pRight; - if( pRight->op==TK_SELECT_COLUMN ){ - codeEqualityTerm(pParse, pTerm, pLevel, j, bRev, iTarget); - }else{ - codeExprOrVector(pParse, pRight, iTarget, 1); - } + codeExprOrVector(pParse, pRight, iTarget, 1); } } sqlite3VdbeAddOp2(v, OP_Integer, pLoop->u.vtab.idxNum, iReg); diff --git a/src/whereexpr.c b/src/whereexpr.c index 2fc903ce6e..55a4cf568a 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -873,29 +873,6 @@ static int exprMightBeIndexed( return 0; } -/* -** The expression passed as the second argument is a vector (either a -** TK_VECTOR node or a TK_SELECT that returns more than one column). This -** function returns a pointer to a new expression object representing -** field iField of the vector. -** -** If pVector is of type TK_VECTOR, the returned object is just a copy of -** the iField'th element of the vector. Or, if pVector is of type TK_SELECT, -** the return value points to a new expression object of type -** TK_SELECT_COLUMN. -*/ -static Expr *exprExtractVectorField(Parse *pParse, Expr *pVector, int iField){ - Expr *pRet; - assert( sqlite3ExprIsVector(pVector) ); - if( pVector->flags & EP_xIsSelect ){ - pRet = sqlite3PExpr(pParse, TK_SELECT_COLUMN, pVector, 0, 0); - if( pRet ) pRet->iColumn = iField; - }else{ - pRet = sqlite3ExprDup(pParse->db, pVector->x.pList->a[iField].pExpr, 0); - } - return pRet; -} - /* ** The input to this routine is an WhereTerm structure with only the ** "pExpr" field filled in. The job of this routine is to analyze the @@ -1211,14 +1188,17 @@ static void exprAnalyze( for(i=0; ipLeft); i++){ int idxNew; Expr *pNew; - Expr *pLeft = exprExtractVectorField(pParse, pExpr->pLeft, i); - Expr *pRight = exprExtractVectorField(pParse, pExpr->pRight, i); + Expr *pLeft = sqlite3ExprForVectorField(pParse, pExpr->pLeft, i, 0); + Expr *pRight = sqlite3ExprForVectorField(pParse, pExpr->pRight, i, 0); pNew = sqlite3PExpr(pParse, pExpr->op, pLeft, pRight, 0); - idxNew = whereClauseInsert(pWC, pNew, TERM_VIRTUAL|TERM_DYNAMIC); + idxNew = whereClauseInsert(pWC, pNew, TERM_DYNAMIC); exprAnalyze(pSrc, pWC, idxNew); markTermAsChild(pWC, idxNew, idxTerm); } + pTerm = &pWC->a[idxTerm]; + pTerm->wtFlags = TERM_CODED; + pTerm->eOperator = 0; } } From a1251bc40d7f825a764e558717a8c348eb94ca1b Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 20 Aug 2016 00:51:37 +0000 Subject: [PATCH 0724/1484] Add support for vector assignments in the SET clause of an UPDATE statement. FossilOrigin-Name: f320d47d6b7b08d9552c8444004bc256348bda90 --- manifest | 19 +++++++------ manifest.uuid | 2 +- src/expr.c | 68 +++++++++++++++++++++++++++++++++++++-------- src/parse.y | 6 ++++ src/sqliteInt.h | 3 +- src/whereexpr.c | 4 +-- test/rowvalue7.test | 58 ++++++++++++++++++++++++++++++++++++++ 7 files changed, 135 insertions(+), 25 deletions(-) create mode 100644 test/rowvalue7.test diff --git a/manifest b/manifest index 52c2870784..122bc50e37 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sthe\sway\sTK_SELECT_COLUMN\sis\shandled\sso\sthat\sthe\ssubquery\sis\sonly\ngenerated\sonce\seven\sif\spart\sof\sthe\svector\scomparison\sis\sused\sfor\sindexing\nand\sthe\sother\spart\sis\snow.\s\sThis\schange\salso\sis\sa\spathway\sto\svector\sassignment\nin\sUPDATE\sstatements. -D 2016-08-20T00:07:01.602 +C Add\ssupport\sfor\svector\sassignments\sin\sthe\sSET\sclause\sof\san\sUPDATE\sstatement. +D 2016-08-20T00:51:37.333 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -338,7 +338,7 @@ F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7 F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c 76c084f0265f4a3cd1ecf17eee112a94f1ccbc05 -F src/expr.c ff73eb6cae76c2423928d46ceff6f2fdc379a568 +F src/expr.c bdc98d3301358bac9b19e23a22375f5220a77274 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c e2be0968c1adc679c87e467aa5b4f167588f38a8 F src/func.c 29cc9acb170ec1387b9f63eb52cd85f8de96c771 @@ -373,7 +373,7 @@ F src/os_win.c 520f23475f1de530c435d30b67b7b15fe90874b0 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c 40928c450320da78bb4bd3ae82818f4239e19b7e F src/pager.h 966d2769e76ae347c8a32c4165faf6e6cb64546d -F src/parse.y 3d02d64f333c4371c4f08fbd79a64964fa27b576 +F src/parse.y 9895eddbbb03c4a47cd760ff4f51cb8d139884d2 F src/pcache.c 5583c8ade4b05075a60ba953ef471d1c1a9c05df F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 F src/pcache1.c 4bb7a6a5300c67d0b033d25adb509c120c03e812 @@ -389,7 +389,7 @@ F src/shell.c 79dda477be6c96eba6e952a934957ad36f87acc7 F src/sqlite.h.in 0f7580280d1b009b507d8beec1ff0f197ba0cc99 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae -F src/sqliteInt.h 84f32ad3a5bfaf698b82bf5a9c6939f3e3d79ee0 +F src/sqliteInt.h db8aa0c875b1a3cdb26e1cee47662c30a34882fd F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 @@ -467,7 +467,7 @@ F src/walker.c 2d2cc7fb0f320f7f415215d7247f3c584141ac09 F src/where.c c7cdfd54f383090bb801cdd50d36de1a24684bb2 F src/whereInt.h 14dd243e13b81cbb0a66063d38b70f93a7d6e613 F src/wherecode.c 0c790c422ea5ecb6c83d6a78f2c4ebc036eea90e -F src/whereexpr.c 021469f11930cc705a26f7f31ec37640588df1d4 +F src/whereexpr.c 706b539d9fcc884b1b9d4692a87c78019fb59fd2 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1025,6 +1025,7 @@ F test/rowvalue3.test dbe935260851b197dfbbbcb0ac2a15cb5f324fd4 F test/rowvalue4.test ed3f7974099f0fc508c9f95df55d37c49f43be65 F test/rowvalue5.test 01c7e0bc4048f30b58e6eb27ecd26e5bd312635e F test/rowvalue6.test d19b54feb604d5601f8614b15e214e0774c01087 +F test/rowvalue7.test 3c9a127954d3da309a271babdfc43dbcc5c4da7f F test/rowvaluefault.test 7b16485e3f2b371f3e3d05455b8ded6d0c090244 F test/rtree.test 0c8d9dd458d6824e59683c19ab2ffa9ef946f798 F test/run-wordcount.sh 891e89c4c2d16e629cd45951d4ed899ad12afc09 @@ -1518,7 +1519,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d4a5af69cc3bde6f8c02075c07b4d47a0252392d -R 8a9288690d2190168e2ddd79f5078350 +P d8feea7dcde83179bff303072426561cfe825e58 +R d0cc8110f72472ebd6ad961310b5fb0d U drh -Z 663c48e63b0d59d8fc6b403d2678eeeb +Z 375b2bf2a6add0d9f506b37662f21e95 diff --git a/manifest.uuid b/manifest.uuid index a8cf8cf3bc..653a21c0af 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d8feea7dcde83179bff303072426561cfe825e58 \ No newline at end of file +f320d47d6b7b08d9552c8444004bc256348bda90 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index de2c7a6a26..d8737c075e 100644 --- a/src/expr.c +++ b/src/expr.c @@ -370,23 +370,17 @@ Expr *sqlite3VectorFieldSubexpr(Expr *pVector, int i){ ** The caller owns the returned Expr object and is responsible for ** ensuring that the returned value eventually gets freed. ** -** Ownership of pVector is controlled by the takeOwnership parameter. If -** takeOwnership is true, this routine takes responsibility for freeing -** pVector, and may do so before returning, hence the caller must not reference -** pVector again. If takeOwnership is false, then the caller takes -** responsibility for freeing pVector and must ensure the pVector remains -** valid as long as the returned value remains in use. +** The caller retains ownership of pVector and must ensure that pVector +** remains valid as long as the returned value is in use. */ Expr *sqlite3ExprForVectorField( Parse *pParse, /* Parsing context */ Expr *pVector, /* The vector. List of expressions or a sub-SELECT */ - int iField, /* Which column of the vector to return */ - int takeOwnership /* True to take ownership of pVector before returning */ + int iField /* Which column of the vector to return */ ){ Expr *pRet; - assert( sqlite3ExprIsVector(pVector) ); - /* FIXME: Add support for takeOwnership!=0 */ assert( takeOwnership==0 ); - if( pVector->flags & EP_xIsSelect ){ + if( pVector->op==TK_SELECT ){ + assert( pVector->flags & EP_xIsSelect ); /* The TK_SELECT_COLUMN Expr node: ** ** pLeft: pVector containing TK_SELECT @@ -405,7 +399,8 @@ Expr *sqlite3ExprForVectorField( if( pRet ) pRet->iColumn = iField; assert( pRet==0 || pRet->iTable==0 ); }else{ - pRet = sqlite3ExprDup(pParse->db, pVector->x.pList->a[iField].pExpr, 0); + if( pVector->op==TK_VECTOR ) pVector = pVector->x.pList->a[iField].pExpr; + pRet = sqlite3ExprDup(pParse->db, pVector, 0); } return pRet; } @@ -1440,6 +1435,55 @@ no_mem: return 0; } +/* +** pColumns and pExpr for a vector assignment, like this: +** +** (a,b,c) = (expr1,expr2,expr3) +** Or: (a,b,c) = (SELECT x,y,z FROM ....) +** +** For each term of the vector assignment, append new entries to the +** expression list. In the case of a subquery on the LHS, append +** TK_SELECT_COLUMN expressions. +*/ +ExprList *sqlite3ExprListAppendVector( + Parse *pParse, /* Parsing context */ + ExprList *pList, /* List to which to append. Might be NULL */ + IdList *pColumns, /* List of names of LHS of the assignment */ + Expr *pExpr /* Vector expression to be appended. Might be NULL */ +){ + sqlite3 *db = pParse->db; + int n; + int i; + if( pColumns==0 ) goto vector_append_error; + if( pExpr==0 ) goto vector_append_error; + n = sqlite3ExprVectorSize(pExpr); + if( pColumns->nId!=n ){ + sqlite3ErrorMsg(pParse, "%d columns assigned %d values", + pColumns->nId, n); + goto vector_append_error; + } + for(i=0; ia[pList->nExpr-1].zName = pColumns->a[i].zName; + pColumns->a[i].zName = 0; + } + } + if( pExpr->op==TK_SELECT ){ + if( pList && pList->a[0].pExpr ){ + assert( pList->a[0].pExpr->op==TK_SELECT_COLUMN ); + pList->a[0].pExpr->pRight = pExpr; + pExpr = 0; + } + } + +vector_append_error: + sqlite3ExprDelete(db, pExpr); + sqlite3IdListDelete(db, pColumns); + return pList; +} + /* ** Set the sort order for the last element on the given ExprList. */ diff --git a/src/parse.y b/src/parse.y index bf15d3d5a7..c175b02867 100644 --- a/src/parse.y +++ b/src/parse.y @@ -789,10 +789,16 @@ setlist(A) ::= setlist(A) COMMA nm(X) EQ expr(Y). { A = sqlite3ExprListAppend(pParse, A, Y.pExpr); sqlite3ExprListSetName(pParse, A, &X, 1); } +setlist(A) ::= setlist(A) COMMA LP idlist(X) RP EQ expr(Y). { + A = sqlite3ExprListAppendVector(pParse, A, X, Y.pExpr); +} setlist(A) ::= nm(X) EQ expr(Y). { A = sqlite3ExprListAppend(pParse, 0, Y.pExpr); sqlite3ExprListSetName(pParse, A, &X, 1); } +setlist(A) ::= LP idlist(X) RP EQ expr(Y). { + A = sqlite3ExprListAppendVector(pParse, 0, X, Y.pExpr); +} ////////////////////////// The INSERT command ///////////////////////////////// // diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 7651ff69e4..d5ba007724 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3547,6 +3547,7 @@ Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*); void sqlite3ExprAssignVarNumber(Parse*, Expr*); void sqlite3ExprDelete(sqlite3*, Expr*); ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*); +ExprList *sqlite3ExprListAppendVector(Parse*,ExprList*,IdList*,Expr*); void sqlite3ExprListSetSortOrder(ExprList*,int); void sqlite3ExprListSetName(Parse*,ExprList*,Token*,int); void sqlite3ExprListSetSpan(Parse*,ExprList*,ExprSpan*); @@ -4276,6 +4277,6 @@ int sqlite3DbstatRegister(sqlite3*); int sqlite3ExprVectorSize(Expr *pExpr); int sqlite3ExprIsVector(Expr *pExpr); Expr *sqlite3VectorFieldSubexpr(Expr*, int); -Expr *sqlite3ExprForVectorField(Parse*,Expr*,int,int); +Expr *sqlite3ExprForVectorField(Parse*,Expr*,int); #endif /* SQLITEINT_H */ diff --git a/src/whereexpr.c b/src/whereexpr.c index 55a4cf568a..c49ff50f35 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -1188,8 +1188,8 @@ static void exprAnalyze( for(i=0; ipLeft); i++){ int idxNew; Expr *pNew; - Expr *pLeft = sqlite3ExprForVectorField(pParse, pExpr->pLeft, i, 0); - Expr *pRight = sqlite3ExprForVectorField(pParse, pExpr->pRight, i, 0); + Expr *pLeft = sqlite3ExprForVectorField(pParse, pExpr->pLeft, i); + Expr *pRight = sqlite3ExprForVectorField(pParse, pExpr->pRight, i); pNew = sqlite3PExpr(pParse, pExpr->op, pLeft, pRight, 0); idxNew = whereClauseInsert(pWC, pNew, TERM_DYNAMIC); diff --git a/test/rowvalue7.test b/test/rowvalue7.test new file mode 100644 index 0000000000..a90e235ce2 --- /dev/null +++ b/test/rowvalue7.test @@ -0,0 +1,58 @@ +# 2016-08-18 +# +# 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. +# +#*********************************************************************** +# The focus of this file is vector assignments in the SET clause of +# an UPDATE statement. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set ::testprefix rowvalue7 + +do_execsql_test 1.1 { + CREATE TABLE t1(a,b,c,d); + CREATE INDEX t1x ON t1(a,b); + INSERT INTO t1(a,b,c,d) VALUES(1,2,0,0),(3,4,0,0),(5,6,0,0); + CREATE TABLE t2(w,x,y,z); + CREATE INDEX t2x ON t2(w,x); + INSERT INTO t2(w,x,y,z) VALUES(1,2,11,22),(8,9,88,99),(3,5,33,55),(5,6,55,66); + + SELECT *,'|' FROM t1 ORDER BY a; +} {1 2 0 0 | 3 4 0 0 | 5 6 0 0 |} + +do_execsql_test 1.2 { + UPDATE t1 SET (c,d) = (SELECT y,z FROM t2 WHERE (w,x)=(a,b)); + SELECT *,'|' FROM t1 ORDER BY a; +} {1 2 11 22 | 3 4 {} {} | 5 6 55 66 |} + +do_execsql_test 1.3 { + UPDATE t1 SET (c,d) = (SELECT y,z FROM t2 WHERE w=a); + SELECT *,'|' FROM t1 ORDER BY a; +} {1 2 11 22 | 3 4 33 55 | 5 6 55 66 |} + +do_execsql_test 1.4 { + UPDATE t1 SET (c) = 99 WHERE a=3; + SELECT *,'|' FROM t1 ORDER BY a; +} {1 2 11 22 | 3 4 99 55 | 5 6 55 66 |} + +do_execsql_test 1.5 { + UPDATE t1 SET b = 8, (c,d) = (123,456) WHERE a=3; + SELECT *,'|' FROM t1 ORDER BY a; +} {1 2 11 22 | 3 8 123 456 | 5 6 55 66 |} + +do_catchsql_test 2.1 { + UPDATE t1 SET (c,d) = (SELECT x,y,z FROM t2 WHERE w=a); +} {1 {2 columns assigned 3 values}} + +do_catchsql_test 2.2 { + UPDATE t1 SET (b,c,d) = (SELECT x,y FROM t2 WHERE w=a); +} {1 {3 columns assigned 2 values}} + +finish_test From 8762ec19356cced5e3f3d3647912ed9f7507ae64 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 20 Aug 2016 01:06:22 +0000 Subject: [PATCH 0725/1484] Improvements to comments. No code changes. FossilOrigin-Name: 4165d20f64d778a4e48f511a37cfced8579d4dbe --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/expr.c | 28 ++++++++++++++++++++-------- 3 files changed, 27 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index 122bc50e37..c056b2c63e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\ssupport\sfor\svector\sassignments\sin\sthe\sSET\sclause\sof\san\sUPDATE\sstatement. -D 2016-08-20T00:51:37.333 +C Improvements\sto\scomments.\s\sNo\scode\schanges. +D 2016-08-20T01:06:22.412 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -338,7 +338,7 @@ F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7 F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c 76c084f0265f4a3cd1ecf17eee112a94f1ccbc05 -F src/expr.c bdc98d3301358bac9b19e23a22375f5220a77274 +F src/expr.c d5cffb307d4e812c41a6fb1f6bc94e6b0801e3e8 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c e2be0968c1adc679c87e467aa5b4f167588f38a8 F src/func.c 29cc9acb170ec1387b9f63eb52cd85f8de96c771 @@ -1519,7 +1519,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d8feea7dcde83179bff303072426561cfe825e58 -R d0cc8110f72472ebd6ad961310b5fb0d +P f320d47d6b7b08d9552c8444004bc256348bda90 +R d44ef1061d1c50d06d327d2ef8a626d9 U drh -Z 375b2bf2a6add0d9f506b37662f21e95 +Z fa86522a92bb8bcf293bd50750ba2b7b diff --git a/manifest.uuid b/manifest.uuid index 653a21c0af..f9c4d10372 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f320d47d6b7b08d9552c8444004bc256348bda90 \ No newline at end of file +4165d20f64d778a4e48f511a37cfced8579d4dbe \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index d8737c075e..5a5afe5ff3 100644 --- a/src/expr.c +++ b/src/expr.c @@ -367,11 +367,21 @@ Expr *sqlite3VectorFieldSubexpr(Expr *pVector, int i){ ** sqlite3ExprCode() will generate all necessary code to compute ** the iField-th column of the vector expression pVector. ** +** It is ok for pVector to be a scalar (as long as iField==0). +** In that case, this routine works like sqlite3ExprDup(). +** ** The caller owns the returned Expr object and is responsible for ** ensuring that the returned value eventually gets freed. ** -** The caller retains ownership of pVector and must ensure that pVector -** remains valid as long as the returned value is in use. +** The caller retains ownership of pVector. If pVector is a TK_SELECT, +** then the return value will reference pVector and so pVector must remain +** valid for the life of the returned object. If pVector is a TK_VECTOR +** or a scalar expression, then it can be deleted as soon as this routine +** routines. +** +** A trick to cause a TK_SELECT pVector to be deleted together with +** the returned Expr object is to attach the pVector to the pRight field +** of the returned TK_SELECT_COLUMN Expr object. */ Expr *sqlite3ExprForVectorField( Parse *pParse, /* Parsing context */ @@ -384,16 +394,17 @@ Expr *sqlite3ExprForVectorField( /* The TK_SELECT_COLUMN Expr node: ** ** pLeft: pVector containing TK_SELECT - ** pRight: pVector if ownership taken + ** pRight: not used. But recursively deleted. ** iColumn: Index of a column in pVector ** pLeft->iTable: First in an array of register holding result, or 0 ** if the result is not yet computed. ** ** sqlite3ExprDelete() specifically skips the recursive delete of ** pLeft on TK_SELECT_COLUMN nodes. But pRight is followed, so pVector - ** is included on pRight if ownership is taken. Typically there will - ** be multiple TK_SELECT_COLUMN nodes with the same pLeft pointer to - ** the pVector, but only one of them will own the pVector. + ** can be attached to pRight to cause this node to take ownership of + ** pVector. Typically there will be multiple TK_SELECT_COLUMN nodes + ** with the same pLeft pointer to the pVector, but only one of them + ** will own the pVector. */ pRet = sqlite3PExpr(pParse, TK_SELECT_COLUMN, pVector, 0, 0); if( pRet ) pRet->iColumn = iField; @@ -1436,13 +1447,14 @@ no_mem: } /* -** pColumns and pExpr for a vector assignment, like this: +** pColumns and pExpr form a vector assignment which is part of the SET +** clause of an UPDATE statement. Like this: ** ** (a,b,c) = (expr1,expr2,expr3) ** Or: (a,b,c) = (SELECT x,y,z FROM ....) ** ** For each term of the vector assignment, append new entries to the -** expression list. In the case of a subquery on the LHS, append +** expression list pList. In the case of a subquery on the LHS, append ** TK_SELECT_COLUMN expressions. */ ExprList *sqlite3ExprListAppendVector( From 9e730f0bb8f06ca83ab6afa54c4224957f673606 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 20 Aug 2016 12:00:05 +0000 Subject: [PATCH 0726/1484] Improvements to the vector comparison splitter in exprAnalyze(). FossilOrigin-Name: a3ffd283bc931b04170ef737e56bced33d27f06d --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/whereexpr.c | 8 +++++--- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index c056b2c63e..04b3482aed 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improvements\sto\scomments.\s\sNo\scode\schanges. -D 2016-08-20T01:06:22.412 +C Improvements\sto\sthe\svector\scomparison\ssplitter\sin\sexprAnalyze(). +D 2016-08-20T12:00:05.657 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -467,7 +467,7 @@ F src/walker.c 2d2cc7fb0f320f7f415215d7247f3c584141ac09 F src/where.c c7cdfd54f383090bb801cdd50d36de1a24684bb2 F src/whereInt.h 14dd243e13b81cbb0a66063d38b70f93a7d6e613 F src/wherecode.c 0c790c422ea5ecb6c83d6a78f2c4ebc036eea90e -F src/whereexpr.c 706b539d9fcc884b1b9d4692a87c78019fb59fd2 +F src/whereexpr.c aa54bf11adf6bc7e52f56281f436ab5fd421ce16 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1519,7 +1519,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P f320d47d6b7b08d9552c8444004bc256348bda90 -R d44ef1061d1c50d06d327d2ef8a626d9 +P 4165d20f64d778a4e48f511a37cfced8579d4dbe +R 29e91d5826d73f7831f4580f57f08037 U drh -Z fa86522a92bb8bcf293bd50750ba2b7b +Z 96272366ac5b1657f908e6772496984c diff --git a/manifest.uuid b/manifest.uuid index f9c4d10372..72cde1cebc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4165d20f64d778a4e48f511a37cfced8579d4dbe \ No newline at end of file +a3ffd283bc931b04170ef737e56bced33d27f06d \ No newline at end of file diff --git a/src/whereexpr.c b/src/whereexpr.c index c49ff50f35..823a2df235 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -1173,7 +1173,10 @@ static void exprAnalyze( #endif /* SQLITE_OMIT_VIRTUALTABLE */ /* If there is a vector == or IS term - e.g. "(a, b) == (?, ?)" - create - ** a virtual term for each component comparison - "a = ?" and "b = ?". + ** new terms for each component comparison - "a = ?" and "b = ?". The + ** new terms completely replace the original vector comparison, which is + ** no longer used. + ** ** This is only required if at least one side of the comparison operation ** is not a sub-select. */ if( pWC->op==TK_AND @@ -1194,10 +1197,9 @@ static void exprAnalyze( pNew = sqlite3PExpr(pParse, pExpr->op, pLeft, pRight, 0); idxNew = whereClauseInsert(pWC, pNew, TERM_DYNAMIC); exprAnalyze(pSrc, pWC, idxNew); - markTermAsChild(pWC, idxNew, idxTerm); } pTerm = &pWC->a[idxTerm]; - pTerm->wtFlags = TERM_CODED; + pTerm->wtFlags = TERM_CODED|TERM_VIRTUAL; /* Disable the original */ pTerm->eOperator = 0; } } From f358009a93556ba3f2b71de5354168bd65c49452 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 20 Aug 2016 15:01:24 +0000 Subject: [PATCH 0727/1484] Fix a segfault that could occur if a query that used a vector comparison contained certain types of syntax errors. FossilOrigin-Name: 203f07c5e140e74cf91d0c1e20135c21236f0fc1 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/expr.c | 4 ++-- test/rowvalue4.test | 16 ++++++++++++++++ 4 files changed, 27 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 04b3482aed..9c5692d524 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improvements\sto\sthe\svector\scomparison\ssplitter\sin\sexprAnalyze(). -D 2016-08-20T12:00:05.657 +C Fix\sa\ssegfault\sthat\scould\soccur\sif\sa\squery\sthat\sused\sa\svector\scomparison\scontained\scertain\stypes\sof\ssyntax\serrors. +D 2016-08-20T15:01:24.921 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -338,7 +338,7 @@ F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7 F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c 76c084f0265f4a3cd1ecf17eee112a94f1ccbc05 -F src/expr.c d5cffb307d4e812c41a6fb1f6bc94e6b0801e3e8 +F src/expr.c f1d9c4374246955b9a93edddfc3abfd3297d1455 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c e2be0968c1adc679c87e467aa5b4f167588f38a8 F src/func.c 29cc9acb170ec1387b9f63eb52cd85f8de96c771 @@ -1022,7 +1022,7 @@ F test/rowid.test 5b7509f384f4f6fae1af3c8c104c8ca299fea18d F test/rowvalue.test 56b34d31d91340a6e922e753b798880170cc1aa7 F test/rowvalue2.test 875068299fd4dd50ef0a47786462c8e1f4065f9a F test/rowvalue3.test dbe935260851b197dfbbbcb0ac2a15cb5f324fd4 -F test/rowvalue4.test ed3f7974099f0fc508c9f95df55d37c49f43be65 +F test/rowvalue4.test 318cdd40e66dfae686537eea581ae49cbb01195d F test/rowvalue5.test 01c7e0bc4048f30b58e6eb27ecd26e5bd312635e F test/rowvalue6.test d19b54feb604d5601f8614b15e214e0774c01087 F test/rowvalue7.test 3c9a127954d3da309a271babdfc43dbcc5c4da7f @@ -1519,7 +1519,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 4165d20f64d778a4e48f511a37cfced8579d4dbe -R 29e91d5826d73f7831f4580f57f08037 -U drh -Z 96272366ac5b1657f908e6772496984c +P a3ffd283bc931b04170ef737e56bced33d27f06d +R b7a3d3965778241daed9250312140835 +U dan +Z 9e9f2920cf64cc9378d276416e2ee3f8 diff --git a/manifest.uuid b/manifest.uuid index 72cde1cebc..6e35ee275b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a3ffd283bc931b04170ef737e56bced33d27f06d \ No newline at end of file +203f07c5e140e74cf91d0c1e20135c21236f0fc1 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 5a5afe5ff3..0412919a24 100644 --- a/src/expr.c +++ b/src/expr.c @@ -462,8 +462,8 @@ static int exprVectorRegister( int *pRegFree /* OUT: Temp register to free */ ){ assert( pVector->op==TK_VECTOR || pVector->op==TK_SELECT ); - assert( (pVector->op==TK_VECTOR)==(regSelect==0) ); - if( regSelect ){ + assert( pParse->nErr || (pVector->op==TK_VECTOR)==(regSelect==0) ); + if( pVector->op==TK_SELECT ){ *ppExpr = pVector->x.pSelect->pEList->a[iField].pExpr; return regSelect+iField; } diff --git a/test/rowvalue4.test b/test/rowvalue4.test index 55401aa8a3..c4581d5562 100644 --- a/test/rowvalue4.test +++ b/test/rowvalue4.test @@ -292,5 +292,21 @@ do_catchsql_test 7.4 { SELECT * FROM f1 WHERE (?, ? COLLATE nose) > (a, b); } {1 {no such collation sequence: nose}} +#------------------------------------------------------------------------- +drop_all_tables +do_execsql_test 8.1 { + CREATE TABLE c1(x, y); + CREATE TABLE c2(a, b, c); + CREATE INDEX c2ab ON c2(a, b); + CREATE INDEX c2c ON c2(c); + + CREATE TABLE c3(d); +} +do_catchsql_test 8.2 { + SELECT * FROM c2 CROSS JOIN c3 WHERE + ( (a, b) == (SELECT x, y FROM c1) AND c3.d = c ) OR + ( c == (SELECT x, y FROM c1) AND c3.d = c ) +} {1 {sub-select returns 2 columns - expected 1}} + finish_test From 9854260bcaa2c049e9d323a39a44f7d75365c820 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 20 Aug 2016 17:00:16 +0000 Subject: [PATCH 0728/1484] Do not duplicate the Expr.pLeft subtree of a TK_SELECT_COLUMN node. FossilOrigin-Name: 8384c77ebb3f65fbc54c199885926f2066f0b140 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/expr.c | 6 +++++- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 9c5692d524..2f60c39a03 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\ssegfault\sthat\scould\soccur\sif\sa\squery\sthat\sused\sa\svector\scomparison\scontained\scertain\stypes\sof\ssyntax\serrors. -D 2016-08-20T15:01:24.921 +C Do\snot\sduplicate\sthe\sExpr.pLeft\ssubtree\sof\sa\sTK_SELECT_COLUMN\snode. +D 2016-08-20T17:00:16.608 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -338,7 +338,7 @@ F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7 F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c 76c084f0265f4a3cd1ecf17eee112a94f1ccbc05 -F src/expr.c f1d9c4374246955b9a93edddfc3abfd3297d1455 +F src/expr.c 8e1288b32f542dd8e8a2e21c30e936112968a4ab F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c e2be0968c1adc679c87e467aa5b4f167588f38a8 F src/func.c 29cc9acb170ec1387b9f63eb52cd85f8de96c771 @@ -1519,7 +1519,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a3ffd283bc931b04170ef737e56bced33d27f06d -R b7a3d3965778241daed9250312140835 -U dan -Z 9e9f2920cf64cc9378d276416e2ee3f8 +P 203f07c5e140e74cf91d0c1e20135c21236f0fc1 +R 753238d9341a2b18b0026dcf708bc835 +U drh +Z d423421ba92880810032946cac8ccbb5 diff --git a/manifest.uuid b/manifest.uuid index 6e35ee275b..3459023db3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -203f07c5e140e74cf91d0c1e20135c21236f0fc1 \ No newline at end of file +8384c77ebb3f65fbc54c199885926f2066f0b140 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 0412919a24..bd2426addb 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1205,7 +1205,11 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int dupFlags, u8 **pzBuffer){ } }else{ if( !ExprHasProperty(p, EP_TokenOnly) ){ - pNew->pLeft = sqlite3ExprDup(db, p->pLeft, 0); + if( pNew->op==TK_SELECT_COLUMN ){ + pNew->pLeft = p->pLeft; + }else{ + pNew->pLeft = sqlite3ExprDup(db, p->pLeft, 0); + } pNew->pRight = sqlite3ExprDup(db, p->pRight, 0); } } From 783e778f3865bb86a5dfcd1bc830f746ed2705bb Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 20 Aug 2016 17:23:45 +0000 Subject: [PATCH 0729/1484] Fix other minor problems with the fts5 snippet() function. FossilOrigin-Name: b56b2a85cf377686727f3929208ede43f797cf76 --- ext/fts5/fts5_aux.c | 5 ++++- ext/fts5/test/fts5af.test | 8 ++++++++ manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 20 insertions(+), 9 deletions(-) diff --git a/ext/fts5/fts5_aux.c b/ext/fts5/fts5_aux.c index 8efe05968e..f2aacbff20 100644 --- a/ext/fts5/fts5_aux.c +++ b/ext/fts5/fts5_aux.c @@ -441,7 +441,7 @@ static void fts5SnippetFunction( nColSize = nDocsize; } - if( rc==SQLITE_OK && sFinder.nFirst ){ + if( rc==SQLITE_OK && sFinder.nFirst && nDocsize>nToken ){ for(jj=0; jj<(sFinder.nFirst-1); jj++){ if( sFinder.aFirst[jj+1]>io ) break; } @@ -469,6 +469,9 @@ static void fts5SnippetFunction( if( rc==SQLITE_OK ){ rc = pApi->xColumnText(pFts, iBestCol, &ctx.zIn, &ctx.nIn); } + if( rc==SQLITE_OK && nColSize==0 ){ + rc = pApi->xColumnSize(pFts, iBestCol, &nColSize); + } if( ctx.zIn ){ if( rc==SQLITE_OK ){ rc = fts5CInstIterInit(pApi, pFts, iBestCol, &ctx.iter); diff --git a/ext/fts5/test/fts5af.test b/ext/fts5/test/fts5af.test index 3b71a9ff5f..c8f815dfda 100644 --- a/ext/fts5/test/fts5af.test +++ b/ext/fts5/test/fts5af.test @@ -156,6 +156,14 @@ if {[detail_is_full]} { } } +do_execsql_test 4.0 { + CREATE VIRTUAL TABLE x1 USING fts5(a, b); + INSERT INTO x1 VALUES('xyz', '1 2 3 4 5 6 7 8 9 10 11 12 13'); + SELECT snippet(x1, 1, '[', ']', '...', 5) FROM x1('xyz'); +} { + {1 2 3 4 5...} +} + } ;# foreach_detail_mode finish_test diff --git a/manifest b/manifest index a68dc1c021..9d9fddff14 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Register\sany\sbuilt-in\sfts5\smodule\sbefore\sloading\sautomatic\sextensions.\sThis\sallows\sautomatic\sextensions\sto\sregister\sfts5\stokenizers\sand\sauxiliary\sfunctions. -D 2016-08-19T18:37:35.386 +C Fix\sother\sminor\sproblems\swith\sthe\sfts5\ssnippet()\sfunction. +D 2016-08-20T17:23:45.034 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -99,7 +99,7 @@ F ext/fts3/unicode/parseunicode.tcl da577d1384810fb4e2b209bf3313074353193e95 F ext/fts5/extract_api_docs.tcl a36e54ec777172ddd3f9a88daf593b00848368e0 F ext/fts5/fts5.h 62f3e33ceeb9a428db139f9c012186b371da1cc7 F ext/fts5/fts5Int.h b2eda36e0f224365c8e23dc8f559311834f1c13f -F ext/fts5/fts5_aux.c 26a2b7e5f02cdc6b7322b85f473e488de452a5be +F ext/fts5/fts5_aux.c 13246759ce03614a3b214894fa4b0f76891e97c0 F ext/fts5/fts5_buffer.c 4c1502d4c956cd092c89ce4480867f9d8bf325cd F ext/fts5/fts5_config.c 5af9c360e99669d29f06492c370892394aba0857 F ext/fts5/fts5_expr.c 1ee97156421919e497595bfa962bb88ad1665401 @@ -122,7 +122,7 @@ F ext/fts5/test/fts5ab.test 30325a89453280160106be411bba3acf138e6d1b F ext/fts5/test/fts5ac.test 55cad4275a1f5acabfe14d8442a8046b47e49e5f F ext/fts5/test/fts5ad.test 36995f0586f30f5602074e012b9224c71ec5171c F ext/fts5/test/fts5ae.test 612dcb51f4069226791ff14c17dbfb3138c56f20 -F ext/fts5/test/fts5af.test b601bbab5a35ca15dd3d1069ee7075a859567073 +F ext/fts5/test/fts5af.test b21abd9455c7351a9ef872b650d16f9dd8db2c49 F ext/fts5/test/fts5ag.test 27180de76c03036be75ee80b93d8c5f540014071 F ext/fts5/test/fts5ah.test dfb7897711dbcda1dacb038aec310daca139fcf5 F ext/fts5/test/fts5ai.test 3909d0b949b2afcaae4d5795cd79153da75381df @@ -1510,7 +1510,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d8180af2adfc101dfce95a0498b5cd7b30643b30 -R 60073adaf70faac8deb27fa21c3071ec +P b10e31dce8e590e1ba30f512374a8c16656bcc72 +R adacbf86d42eaec5a7639c5010230497 U dan -Z db6d5df26cfba25421660b26226c4ab6 +Z 520e1a56589636baad586098a109d286 diff --git a/manifest.uuid b/manifest.uuid index 674031237c..eda24ca294 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b10e31dce8e590e1ba30f512374a8c16656bcc72 \ No newline at end of file +b56b2a85cf377686727f3929208ede43f797cf76 \ No newline at end of file From 8bd0d58e1c5e66c5109435bf86c24f9d0b71130f Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 20 Aug 2016 18:06:14 +0000 Subject: [PATCH 0730/1484] Fixes for problems following OOM errors. FossilOrigin-Name: 9041ee4a6f0e8389297f887f1431ab5cfe783390 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/expr.c | 10 +++++++--- src/parse.y | 7 +++++-- 4 files changed, 20 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 2f60c39a03..15b48703cd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Do\snot\sduplicate\sthe\sExpr.pLeft\ssubtree\sof\sa\sTK_SELECT_COLUMN\snode. -D 2016-08-20T17:00:16.608 +C Fixes\sfor\sproblems\sfollowing\sOOM\serrors. +D 2016-08-20T18:06:14.286 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -338,7 +338,7 @@ F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7 F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c 76c084f0265f4a3cd1ecf17eee112a94f1ccbc05 -F src/expr.c 8e1288b32f542dd8e8a2e21c30e936112968a4ab +F src/expr.c e96f29a02a3927b2afaca1f86fc84e80cac50ca7 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c e2be0968c1adc679c87e467aa5b4f167588f38a8 F src/func.c 29cc9acb170ec1387b9f63eb52cd85f8de96c771 @@ -373,7 +373,7 @@ F src/os_win.c 520f23475f1de530c435d30b67b7b15fe90874b0 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c 40928c450320da78bb4bd3ae82818f4239e19b7e F src/pager.h 966d2769e76ae347c8a32c4165faf6e6cb64546d -F src/parse.y 9895eddbbb03c4a47cd760ff4f51cb8d139884d2 +F src/parse.y 0e0b6d46a990d01e4ca1e9d7e1d2d9b5a98f6bcb F src/pcache.c 5583c8ade4b05075a60ba953ef471d1c1a9c05df F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 F src/pcache1.c 4bb7a6a5300c67d0b033d25adb509c120c03e812 @@ -1519,7 +1519,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 203f07c5e140e74cf91d0c1e20135c21236f0fc1 -R 753238d9341a2b18b0026dcf708bc835 +P 8384c77ebb3f65fbc54c199885926f2066f0b140 +R d29ab3049f2812696918a926abccb285 U drh -Z d423421ba92880810032946cac8ccbb5 +Z 08f6ec095045e30304bec0161a676b54 diff --git a/manifest.uuid b/manifest.uuid index 3459023db3..be0615edf6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8384c77ebb3f65fbc54c199885926f2066f0b140 \ No newline at end of file +9041ee4a6f0e8389297f887f1431ab5cfe783390 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index bd2426addb..ac67eca691 100644 --- a/src/expr.c +++ b/src/expr.c @@ -406,8 +406,11 @@ Expr *sqlite3ExprForVectorField( ** with the same pLeft pointer to the pVector, but only one of them ** will own the pVector. */ - pRet = sqlite3PExpr(pParse, TK_SELECT_COLUMN, pVector, 0, 0); - if( pRet ) pRet->iColumn = iField; + pRet = sqlite3PExpr(pParse, TK_SELECT_COLUMN, 0, 0, 0); + if( pRet ){ + pRet->iColumn = iField; + pRet->pLeft = pVector; + } assert( pRet==0 || pRet->iTable==0 ); }else{ if( pVector->op==TK_VECTOR ) pVector = pVector->x.pList->a[iField].pExpr; @@ -462,7 +465,8 @@ static int exprVectorRegister( int *pRegFree /* OUT: Temp register to free */ ){ assert( pVector->op==TK_VECTOR || pVector->op==TK_SELECT ); - assert( pParse->nErr || (pVector->op==TK_VECTOR)==(regSelect==0) ); + assert( pParse->nErr || pParse->db->mallocFailed + || (pVector->op==TK_VECTOR)==(regSelect==0) ); if( pVector->op==TK_SELECT ){ *ppExpr = pVector->x.pSelect->pEList->a[iField].pExpr; return regSelect+iField; diff --git a/src/parse.y b/src/parse.y index c175b02867..51bdcff691 100644 --- a/src/parse.y +++ b/src/parse.y @@ -952,11 +952,14 @@ term(A) ::= CTIME_KW(OP). { } } -expr(A) ::= LP(L) nexprlist(X) COMMA expr(Y) RP(R). { +expr(A) ::= LP(L) nexprlist(X) COMMA expr(Y) RP(R). { + ExprList *pList = sqlite3ExprListAppend(pParse, X, Y.pExpr); A.pExpr = sqlite3PExpr(pParse, TK_VECTOR, 0, 0, 0); if( A.pExpr ){ - A.pExpr->x.pList = sqlite3ExprListAppend(pParse, X, Y.pExpr); + A.pExpr->x.pList = pList; spanSet(&A, &L, &R); + }else{ + sqlite3ExprListDelete(pParse->db, pList); } } From 76dbe7a8d0feac9a600e6425274f65187d378cbd Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 20 Aug 2016 21:02:38 +0000 Subject: [PATCH 0731/1484] Clarification of code comments in expr.c. Clean up the implementations of sqlite3ExprIsVector() and sqlite3ExprVectorSize() slightly. FossilOrigin-Name: 4fb66d6592b141a4a71359250dbd1ac454569cb9 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/expr.c | 28 ++++++++++++++-------------- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/manifest b/manifest index 15b48703cd..63e0795631 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fixes\sfor\sproblems\sfollowing\sOOM\serrors. -D 2016-08-20T18:06:14.286 +C Clarification\sof\scode\scomments\sin\sexpr.c.\s\sClean\sup\sthe\simplementations\nof\ssqlite3ExprIsVector()\sand\ssqlite3ExprVectorSize()\sslightly. +D 2016-08-20T21:02:38.224 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -338,7 +338,7 @@ F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7 F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c 76c084f0265f4a3cd1ecf17eee112a94f1ccbc05 -F src/expr.c e96f29a02a3927b2afaca1f86fc84e80cac50ca7 +F src/expr.c 4adf875e1bfc155b107ee8e35e7cb1c5599f955b F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c e2be0968c1adc679c87e467aa5b4f167588f38a8 F src/func.c 29cc9acb170ec1387b9f63eb52cd85f8de96c771 @@ -1519,7 +1519,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 8384c77ebb3f65fbc54c199885926f2066f0b140 -R d29ab3049f2812696918a926abccb285 +P 9041ee4a6f0e8389297f887f1431ab5cfe783390 +R bba779342591015bf7eda1fee0ab13af U drh -Z 08f6ec095045e30304bec0161a676b54 +Z 030a18789c82832c6d203bdc6c28c7db diff --git a/manifest.uuid b/manifest.uuid index be0615edf6..d9ffa9fb0c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9041ee4a6f0e8389297f887f1431ab5cfe783390 \ No newline at end of file +4fb66d6592b141a4a71359250dbd1ac454569cb9 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index ac67eca691..69754fada6 100644 --- a/src/expr.c +++ b/src/expr.c @@ -313,9 +313,7 @@ static int codeCompare( ** Return true if expression pExpr is a vector, or false otherwise. */ int sqlite3ExprIsVector(Expr *pExpr){ - return ( (pExpr->op==TK_VECTOR) - || (pExpr->op==TK_SELECT && pExpr->x.pSelect->pEList->nExpr>1) - ); + return sqlite3ExprVectorSize(pExpr)>1; } /* @@ -325,28 +323,30 @@ int sqlite3ExprIsVector(Expr *pExpr){ ** any other type of expression, return 1. */ int sqlite3ExprVectorSize(Expr *pExpr){ - if( sqlite3ExprIsVector(pExpr)==0 ) return 1; - if( pExpr->flags & EP_xIsSelect ){ + if( pExpr->op==TK_VECTOR ){ + return pExpr->x.pList->nExpr; + }else if( pExpr->op==TK_SELECT ){ return pExpr->x.pSelect->pEList->nExpr; + }else{ + return 1; } - return pExpr->x.pList->nExpr; } #ifndef SQLITE_OMIT_SUBQUERY /* -** Interpret the pVector input as a vector expression. If pVector is -** an ordinary scalar expression, treat it as a vector of size 1. -** ** Return a pointer to a subexpression of pVector that is the i-th ** column of the vector (numbered starting with 0). The caller must ** ensure that i is within range. ** +** If pVector is really a scalar (and "scalar" here includes subqueries +** that return a single column!) then return pVector unmodified. +** ** pVector retains ownership of the returned subexpression. ** ** If the vector is a (SELECT ...) then the expression returned is -** just the expression for the i-th term of the result set, and is -** necessarily ready to be evaluated because the table cursor might -** not have been positioned yet. +** just the expression for the i-th term of the result set, and may +** not be ready for evaluation because the table cursor has not yet +** been positioned. */ Expr *sqlite3VectorFieldSubexpr(Expr *pVector, int i){ assert( i Date: Sat, 20 Aug 2016 21:11:25 +0000 Subject: [PATCH 0732/1484] Further comment enhancements. No changes to code. FossilOrigin-Name: d4562a9e7b1eaff41466210e3a0caaf374ec5a92 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/expr.c | 6 ++++++ 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 63e0795631..256fcbf510 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Clarification\sof\scode\scomments\sin\sexpr.c.\s\sClean\sup\sthe\simplementations\nof\ssqlite3ExprIsVector()\sand\ssqlite3ExprVectorSize()\sslightly. -D 2016-08-20T21:02:38.224 +C Further\scomment\senhancements.\s\sNo\schanges\sto\scode. +D 2016-08-20T21:11:25.815 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -338,7 +338,7 @@ F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7 F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c 76c084f0265f4a3cd1ecf17eee112a94f1ccbc05 -F src/expr.c 4adf875e1bfc155b107ee8e35e7cb1c5599f955b +F src/expr.c b6f0592292944a1700b503d00f588932f5683d67 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c e2be0968c1adc679c87e467aa5b4f167588f38a8 F src/func.c 29cc9acb170ec1387b9f63eb52cd85f8de96c771 @@ -1519,7 +1519,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 9041ee4a6f0e8389297f887f1431ab5cfe783390 -R bba779342591015bf7eda1fee0ab13af +P 4fb66d6592b141a4a71359250dbd1ac454569cb9 +R 560b79caaccb19afcc4a2c629096a4bc U drh -Z 030a18789c82832c6d203bdc6c28c7db +Z f5ddde0143384b43283a729a6b1d1670 diff --git a/manifest.uuid b/manifest.uuid index d9ffa9fb0c..1bfd374437 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4fb66d6592b141a4a71359250dbd1ac454569cb9 \ No newline at end of file +d4562a9e7b1eaff41466210e3a0caaf374ec5a92 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 69754fada6..c92179d5e4 100644 --- a/src/expr.c +++ b/src/expr.c @@ -311,6 +311,12 @@ static int codeCompare( /* ** Return true if expression pExpr is a vector, or false otherwise. +** +** A vector is defined as any expression that results in two or more +** columns of result. Every TK_VECTOR node is an vector because the +** parser will not generate a TK_VECTOR with fewer than two entries. +** But a TK_SELECT might be either a vector or a scalar. It is only +** considered a vector if it has two or more result columns. */ int sqlite3ExprIsVector(Expr *pExpr){ return sqlite3ExprVectorSize(pExpr)>1; From 84b19a3da16ebfd784fea1a42ea90c3473444ddb Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 20 Aug 2016 22:49:28 +0000 Subject: [PATCH 0733/1484] The docs promise the in "x BETWEEN y AND z" the x expression is only evaluated once. That is no longer true, and so some tests are failing. This needs to be fixed before merging to trunk. FossilOrigin-Name: e50d264fdc2f08d19202c68f73f18df301cb233d --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/expr.c | 47 +++++++++++++++++++++++------------------------ 3 files changed, 30 insertions(+), 31 deletions(-) diff --git a/manifest b/manifest index 256fcbf510..826481de0f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Further\scomment\senhancements.\s\sNo\schanges\sto\scode. -D 2016-08-20T21:11:25.815 +C The\sdocs\spromise\sthe\sin\s"x\sBETWEEN\sy\sAND\sz"\sthe\sx\sexpression\sis\sonly\sevaluated\nonce.\s\sThat\sis\sno\slonger\strue,\sand\sso\ssome\stests\sare\sfailing.\s\sThis\sneeds\sto\nbe\sfixed\sbefore\smerging\sto\strunk. +D 2016-08-20T22:49:28.330 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -338,7 +338,7 @@ F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7 F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c 76c084f0265f4a3cd1ecf17eee112a94f1ccbc05 -F src/expr.c b6f0592292944a1700b503d00f588932f5683d67 +F src/expr.c 157f2aa7e573c8d354ccfea9955dac2842467b0e F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c e2be0968c1adc679c87e467aa5b4f167588f38a8 F src/func.c 29cc9acb170ec1387b9f63eb52cd85f8de96c771 @@ -1519,7 +1519,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 4fb66d6592b141a4a71359250dbd1ac454569cb9 -R 560b79caaccb19afcc4a2c629096a4bc +P d4562a9e7b1eaff41466210e3a0caaf374ec5a92 +R 79bb83cf9bac81ae1bf4f01bc53e554b U drh -Z f5ddde0143384b43283a729a6b1d1670 +Z 762069ce8b935adb1e168884e493813e diff --git a/manifest.uuid b/manifest.uuid index 1bfd374437..d9c935329d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d4562a9e7b1eaff41466210e3a0caaf374ec5a92 \ No newline at end of file +e50d264fdc2f08d19202c68f73f18df301cb233d \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index c92179d5e4..ea8ca32fdb 100644 --- a/src/expr.c +++ b/src/expr.c @@ -4064,55 +4064,54 @@ int sqlite3ExprCodeExprList( ** ** Code it as such, taking care to do the common subexpression ** elimination of x. +** +** The xJumpIf parameter determines details: +** +** NULL: Store the boolean result in reg[dest] +** sqlite3ExprIfTrue: Jump to dest if true +** sqlite3ExprIfFalse: Jump to dest if false +** +** The jumpIfNull parameter is ignored if xJumpIf is NULL. */ static void exprCodeBetween( Parse *pParse, /* Parsing and code generating context */ Expr *pExpr, /* The BETWEEN expression */ - int dest, /* Jump here if the jump is taken */ - void (*xJumpIf)(Parse*,Expr*,int,int), + int dest, /* Jump destination or storage location */ + void (*xJump)(Parse*,Expr*,int,int), /* Action to take */ int jumpIfNull /* Take the jump if the BETWEEN is NULL */ ){ Expr exprAnd; /* The AND operator in x>=y AND x<=z */ Expr compLeft; /* The x>=y term */ Expr compRight; /* The x<=z term */ - Expr exprX; /* The x subexpression */ - int regFree1 = 0; /* Temporary use register */ + + assert( xJump==0 || xJump==sqlite3ExprIfTrue || xJump==sqlite3ExprIfFalse ); + assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); memset(&compLeft, 0, sizeof(Expr)); memset(&compRight, 0, sizeof(Expr)); memset(&exprAnd, 0, sizeof(Expr)); - - assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); - exprX = *pExpr->pLeft; exprAnd.op = TK_AND; exprAnd.pLeft = &compLeft; exprAnd.pRight = &compRight; compLeft.op = TK_GE; - compLeft.pLeft = &exprX; + compLeft.pLeft = pExpr->pLeft; compLeft.pRight = pExpr->x.pList->a[0].pExpr; compRight.op = TK_LE; - compRight.pLeft = &exprX; + compRight.pLeft = pExpr->pLeft; compRight.pRight = pExpr->x.pList->a[1].pExpr; - if( sqlite3ExprIsVector(&exprX)==0 ){ - exprToRegister(&exprX, sqlite3ExprCodeTemp(pParse, &exprX, ®Free1)); - } - if( xJumpIf ){ - xJumpIf(pParse, &exprAnd, dest, jumpIfNull); + if( xJump ){ + xJump(pParse, &exprAnd, dest, jumpIfNull); }else{ - exprX.flags |= EP_FromJoin; + /*exprX.flags |= EP_FromJoin;*/ sqlite3ExprCodeTarget(pParse, &exprAnd, dest); } - sqlite3ReleaseTempReg(pParse, regFree1); /* Ensure adequate test coverage */ - testcase( jumpIfTrue==0 && jumpIfNull==0 && regFree1==0 ); - testcase( jumpIfTrue==0 && jumpIfNull==0 && regFree1!=0 ); - testcase( jumpIfTrue==0 && jumpIfNull!=0 && regFree1==0 ); - testcase( jumpIfTrue==0 && jumpIfNull!=0 && regFree1!=0 ); - testcase( jumpIfTrue!=0 && jumpIfNull==0 && regFree1==0 ); - testcase( jumpIfTrue!=0 && jumpIfNull==0 && regFree1!=0 ); - testcase( jumpIfTrue!=0 && jumpIfNull!=0 && regFree1==0 ); - testcase( jumpIfTrue!=0 && jumpIfNull!=0 && regFree1!=0 ); + testcase( xJump==sqlite3ExprIfTrue && jumpIfNull==0 ); + testcase( xJump==sqlite3ExprIfTrue && jumpIfNull!=0 ); + testcase( xJump==sqlite3ExprIfFalse && jumpIfNull==0 ); + testcase( xJump==sqlite3ExprIfFalse && jumpIfNull!=0 ); + testcase( xJump==0 ); } /* From db45bd5e826505fb6f8a02dd28c805a85c349f59 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 22 Aug 2016 00:48:58 +0000 Subject: [PATCH 0734/1484] Reinstate the mechanism in BETWEEN that avoids evaluating the first expression more than once, but fix the affinity extractor so that it works with this mechanism. The de-duplication of the first expression still does not work for vector expressions, though. FossilOrigin-Name: 2f39987f21bd6dae8d2be610a1fd5f06f8878e9e --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/expr.c | 38 +++++++++++++++++++++++--------------- 3 files changed, 30 insertions(+), 22 deletions(-) diff --git a/manifest b/manifest index 826481de0f..ac59fb1a27 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C The\sdocs\spromise\sthe\sin\s"x\sBETWEEN\sy\sAND\sz"\sthe\sx\sexpression\sis\sonly\sevaluated\nonce.\s\sThat\sis\sno\slonger\strue,\sand\sso\ssome\stests\sare\sfailing.\s\sThis\sneeds\sto\nbe\sfixed\sbefore\smerging\sto\strunk. -D 2016-08-20T22:49:28.330 +C Reinstate\sthe\smechanism\sin\sBETWEEN\sthat\savoids\sevaluating\sthe\sfirst\sexpression\nmore\sthan\sonce,\sbut\sfix\sthe\saffinity\sextractor\sso\sthat\sit\sworks\swith\sthis\nmechanism.\s\sThe\sde-duplication\sof\sthe\sfirst\sexpression\sstill\sdoes\snot\swork\nfor\svector\sexpressions,\sthough. +D 2016-08-22T00:48:58.062 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -338,7 +338,7 @@ F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7 F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c 76c084f0265f4a3cd1ecf17eee112a94f1ccbc05 -F src/expr.c 157f2aa7e573c8d354ccfea9955dac2842467b0e +F src/expr.c 77215e927ab39426e19340b2e109267f62abe398 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c e2be0968c1adc679c87e467aa5b4f167588f38a8 F src/func.c 29cc9acb170ec1387b9f63eb52cd85f8de96c771 @@ -1519,7 +1519,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d4562a9e7b1eaff41466210e3a0caaf374ec5a92 -R 79bb83cf9bac81ae1bf4f01bc53e554b +P e50d264fdc2f08d19202c68f73f18df301cb233d +R 333f2c163d1312925e2511fcd28df52d U drh -Z 762069ce8b935adb1e168884e493813e +Z ca2741b6fe90555773b217749c459f72 diff --git a/manifest.uuid b/manifest.uuid index d9c935329d..20c785fdca 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e50d264fdc2f08d19202c68f73f18df301cb233d \ No newline at end of file +2f39987f21bd6dae8d2be610a1fd5f06f8878e9e \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index ea8ca32fdb..88ff3e40f0 100644 --- a/src/expr.c +++ b/src/expr.c @@ -39,17 +39,14 @@ char sqlite3ExprAffinity(Expr *pExpr){ assert( pExpr->flags&EP_xIsSelect ); return sqlite3ExprAffinity(pExpr->x.pSelect->pEList->a[0].pExpr); } + if( op==TK_REGISTER ) op = pExpr->op2; #ifndef SQLITE_OMIT_CAST if( op==TK_CAST ){ assert( !ExprHasProperty(pExpr, EP_IntValue) ); return sqlite3AffinityType(pExpr->u.zToken, 0); } #endif - if( (op==TK_AGG_COLUMN || op==TK_COLUMN || op==TK_REGISTER) - && pExpr->pTab!=0 - ){ - /* op==TK_REGISTER && pExpr->pTab!=0 happens when pExpr was originally - ** a TK_COLUMN but was previously evaluated and cached in a register */ + if( (op==TK_AGG_COLUMN || op==TK_COLUMN) && pExpr->pTab!=0 ){ int j = pExpr->iColumn; if( j<0 ) return SQLITE_AFF_INTEGER; assert( pExpr->pTab && jpTab->nCol ); @@ -4080,37 +4077,48 @@ static void exprCodeBetween( void (*xJump)(Parse*,Expr*,int,int), /* Action to take */ int jumpIfNull /* Take the jump if the BETWEEN is NULL */ ){ - Expr exprAnd; /* The AND operator in x>=y AND x<=z */ + Expr exprAnd; /* The AND operator in x>=y AND x<=z */ Expr compLeft; /* The x>=y term */ Expr compRight; /* The x<=z term */ + Expr exprX; /* The x subexpression */ + int regFree1 = 0; /* Temporary use register */ - assert( xJump==0 || xJump==sqlite3ExprIfTrue || xJump==sqlite3ExprIfFalse ); - assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); memset(&compLeft, 0, sizeof(Expr)); memset(&compRight, 0, sizeof(Expr)); memset(&exprAnd, 0, sizeof(Expr)); + + assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); + exprX = *pExpr->pLeft; exprAnd.op = TK_AND; exprAnd.pLeft = &compLeft; exprAnd.pRight = &compRight; compLeft.op = TK_GE; - compLeft.pLeft = pExpr->pLeft; + compLeft.pLeft = &exprX; compLeft.pRight = pExpr->x.pList->a[0].pExpr; compRight.op = TK_LE; - compRight.pLeft = pExpr->pLeft; + compRight.pLeft = &exprX; compRight.pRight = pExpr->x.pList->a[1].pExpr; + if( sqlite3ExprIsVector(&exprX)==0 ){ + exprToRegister(&exprX, sqlite3ExprCodeTemp(pParse, &exprX, ®Free1)); + } if( xJump ){ xJump(pParse, &exprAnd, dest, jumpIfNull); }else{ - /*exprX.flags |= EP_FromJoin;*/ + exprX.flags |= EP_FromJoin; sqlite3ExprCodeTarget(pParse, &exprAnd, dest); } + sqlite3ReleaseTempReg(pParse, regFree1); /* Ensure adequate test coverage */ - testcase( xJump==sqlite3ExprIfTrue && jumpIfNull==0 ); - testcase( xJump==sqlite3ExprIfTrue && jumpIfNull!=0 ); - testcase( xJump==sqlite3ExprIfFalse && jumpIfNull==0 ); - testcase( xJump==sqlite3ExprIfFalse && jumpIfNull!=0 ); + testcase( xJump==sqlite3ExprIfTrue && jumpIfNull==0 && regFree1==0 ); + testcase( xJump==sqlite3ExprIfTrue && jumpIfNull==0 && regFree1!=0 ); + testcase( xJump==sqlite3ExprIfTrue && jumpIfNull!=0 && regFree1==0 ); + testcase( xJump==sqlite3ExprIfTrue && jumpIfNull!=0 && regFree1!=0 ); + testcase( xJump==sqlite3ExprIfFalse && jumpIfNull==0 && regFree1==0 ); + testcase( xJump==sqlite3ExprIfFalse && jumpIfNull==0 && regFree1!=0 ); + testcase( xJump==sqlite3ExprIfFalse && jumpIfNull!=0 && regFree1==0 ); + testcase( xJump==sqlite3ExprIfFalse && jumpIfNull!=0 && regFree1!=0 ); testcase( xJump==0 ); } From 12abf408ff0f89efce2405c172f130e7b2ea011d Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 22 Aug 2016 14:30:05 +0000 Subject: [PATCH 0735/1484] Fix the vector BETWEEN operator so that it only evaluates the left-most vector expression once. Add support for vector comparisons in the CASE operator. FossilOrigin-Name: 07e69f43a294d35b5145a2b0242ee42d50adab14 --- manifest | 15 ++++---- manifest.uuid | 2 +- src/expr.c | 84 ++++++++++++++++++++++++++++++++------------- test/e_expr.test | 3 ++ test/rowvalue8.test | 59 +++++++++++++++++++++++++++++++ 5 files changed, 131 insertions(+), 32 deletions(-) create mode 100644 test/rowvalue8.test diff --git a/manifest b/manifest index ac59fb1a27..21dcf79efe 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Reinstate\sthe\smechanism\sin\sBETWEEN\sthat\savoids\sevaluating\sthe\sfirst\sexpression\nmore\sthan\sonce,\sbut\sfix\sthe\saffinity\sextractor\sso\sthat\sit\sworks\swith\sthis\nmechanism.\s\sThe\sde-duplication\sof\sthe\sfirst\sexpression\sstill\sdoes\snot\swork\nfor\svector\sexpressions,\sthough. -D 2016-08-22T00:48:58.062 +C Fix\sthe\svector\sBETWEEN\soperator\sso\sthat\sit\sonly\sevaluates\sthe\sleft-most\nvector\sexpression\sonce.\s\sAdd\ssupport\sfor\svector\scomparisons\sin\sthe\sCASE\noperator. +D 2016-08-22T14:30:05.854 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -338,7 +338,7 @@ F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7 F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c 76c084f0265f4a3cd1ecf17eee112a94f1ccbc05 -F src/expr.c 77215e927ab39426e19340b2e109267f62abe398 +F src/expr.c 575d6767abc4d38362bb54599dbb72a09946c5be F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c e2be0968c1adc679c87e467aa5b4f167588f38a8 F src/func.c 29cc9acb170ec1387b9f63eb52cd85f8de96c771 @@ -644,7 +644,7 @@ F test/e_createtable.test d4c6059d44dcd4b636de9aae322766062b471844 F test/e_delete.test ab39084f26ae1f033c940b70ebdbbd523dc4962e F test/e_droptrigger.test 3cd080807622c13e5bbb61fc9a57bd7754da2412 F test/e_dropview.test 0c9f7f60989164a70a67a9d9c26d1083bc808306 -F test/e_expr.test 3f9e639b5df18de36c0aa700703589cd65281174 +F test/e_expr.test 1ffa8866d38e7becc76893a8829e9432050e5716 F test/e_fkey.test a1783fe1f759e1990e6a11adfcf0702dac4d0707 F test/e_fts3.test 5c02288842e4f941896fd44afdef564dd5fc1459 F test/e_insert.test 3de217e95094d3d165992a6de1164bbc4bd92dc7 @@ -1026,6 +1026,7 @@ F test/rowvalue4.test 318cdd40e66dfae686537eea581ae49cbb01195d F test/rowvalue5.test 01c7e0bc4048f30b58e6eb27ecd26e5bd312635e F test/rowvalue6.test d19b54feb604d5601f8614b15e214e0774c01087 F test/rowvalue7.test 3c9a127954d3da309a271babdfc43dbcc5c4da7f +F test/rowvalue8.test 5900eddad9e2c3c2e26f1a95f74aafc1232ee5e0 F test/rowvaluefault.test 7b16485e3f2b371f3e3d05455b8ded6d0c090244 F test/rtree.test 0c8d9dd458d6824e59683c19ab2ffa9ef946f798 F test/run-wordcount.sh 891e89c4c2d16e629cd45951d4ed899ad12afc09 @@ -1519,7 +1520,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e50d264fdc2f08d19202c68f73f18df301cb233d -R 333f2c163d1312925e2511fcd28df52d +P 2f39987f21bd6dae8d2be610a1fd5f06f8878e9e +R 46b91546c6e852a3d13f61b9c8a6f99f U drh -Z ca2741b6fe90555773b217749c459f72 +Z cdfb95caa6cbc00a53a66a6c4e92b927 diff --git a/manifest.uuid b/manifest.uuid index 20c785fdca..e35c310130 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2f39987f21bd6dae8d2be610a1fd5f06f8878e9e \ No newline at end of file +07e69f43a294d35b5145a2b0242ee42d50adab14 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 88ff3e40f0..b304e27835 100644 --- a/src/expr.c +++ b/src/expr.c @@ -14,6 +14,11 @@ */ #include "sqliteInt.h" +/* Forward declarations */ +static void exprCodeBetween(Parse*,Expr*,int,void(*)(Parse*,Expr*,int,int),int); +static int exprCodeVector(Parse *pParse, Expr *p, int *piToFree); + + /* ** Return the 'affinity' of the expression pExpr if any. ** @@ -326,9 +331,11 @@ int sqlite3ExprIsVector(Expr *pExpr){ ** any other type of expression, return 1. */ int sqlite3ExprVectorSize(Expr *pExpr){ - if( pExpr->op==TK_VECTOR ){ + u8 op = pExpr->op; + if( op==TK_REGISTER ) op = pExpr->op2; + if( op==TK_VECTOR ){ return pExpr->x.pList->nExpr; - }else if( pExpr->op==TK_SELECT ){ + }else if( op==TK_SELECT ){ return pExpr->x.pSelect->pEList->nExpr; }else{ return 1; @@ -354,7 +361,9 @@ int sqlite3ExprVectorSize(Expr *pExpr){ Expr *sqlite3VectorFieldSubexpr(Expr *pVector, int i){ assert( iop==TK_SELECT ){ + if( pVector->op==TK_SELECT + || (pVector->op==TK_REGISTER && pVector->op2==TK_SELECT) + ){ return pVector->x.pSelect->pEList->a[i].pExpr; }else{ return pVector->x.pList->a[i].pExpr; @@ -467,10 +476,13 @@ static int exprVectorRegister( Expr **ppExpr, /* OUT: Expression element */ int *pRegFree /* OUT: Temp register to free */ ){ - assert( pVector->op==TK_VECTOR || pVector->op==TK_SELECT ); - assert( pParse->nErr || pParse->db->mallocFailed - || (pVector->op==TK_VECTOR)==(regSelect==0) ); - if( pVector->op==TK_SELECT ){ + u8 op = pVector->op; + assert( op==TK_VECTOR || op==TK_SELECT || op==TK_REGISTER ); + if( op==TK_REGISTER ){ + *ppExpr = sqlite3VectorFieldSubexpr(pVector, iField); + return pVector->iTable+iField; + } + if( op==TK_SELECT ){ *ppExpr = pVector->x.pSelect->pEList->a[iField].pExpr; return regSelect+iField; } @@ -2630,11 +2642,12 @@ static void sqlite3ExprCodeIN( ){ int rRhsHasNull = 0; /* Register that is true if RHS contains NULL values */ int eType; /* Type of the RHS */ - int r1; /* Temporary use register */ + int r1, r2; /* Temporary use registers */ Vdbe *v; /* Statement under construction */ int *aiMap = 0; /* Map from vector field to index column */ char *zAff = 0; /* Affinity string for comparisons */ int nVector; /* Size of vectors for this IN(...) op */ + int iDummy; /* Dummy parameter to exprCodeVector() */ Expr *pLeft = pExpr->pLeft; int i; @@ -2671,16 +2684,9 @@ static void sqlite3ExprCodeIN( */ r1 = sqlite3GetTempRange(pParse, nVector); sqlite3ExprCachePush(pParse); - if( nVector>1 && (pLeft->flags & EP_xIsSelect) ){ - int regSelect = sqlite3CodeSubselect(pParse, pLeft, 0, 0); - for(i=0; iop2 = p->op; @@ -3237,7 +3245,37 @@ static void exprToRegister(Expr *p, int iReg){ ExprClearProperty(p, EP_Skip); } -static void exprCodeBetween(Parse*,Expr*,int,void(*)(Parse*,Expr*,int,int),int); +/* +** Evaluate an expression (either a vector or a scalar expression) and store +** the result in continguous temporary registers. Return the index of +** the first register used to store the result. +** +** If the returned result register is a temporary scalar, then also write +** that register number into *piFreeable. If the returned result register +** is not a temporary or if the expression is a vector set *piFreeable +** to 0. +*/ +static int exprCodeVector(Parse *pParse, Expr *p, int *piFreeable){ + int iResult; + int nResult = sqlite3ExprVectorSize(p); + if( nResult==1 ){ + iResult = sqlite3ExprCodeTemp(pParse, p, piFreeable); + }else{ + *piFreeable = 0; + if( p->op==TK_SELECT ){ + iResult = sqlite3CodeSubselect(pParse, p, 0, 0); + }else{ + int i; + iResult = pParse->nMem+1; + pParse->nMem += nResult; + for(i=0; ix.pList->a[i].pExpr, i+iResult); + } + } + } + return iResult; +} + /* ** Generate code into the current Vdbe to evaluate the given @@ -3781,7 +3819,7 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ if( (pX = pExpr->pLeft)!=0 ){ tempX = *pX; testcase( pX->op==TK_COLUMN ); - exprToRegister(&tempX, sqlite3ExprCodeTemp(pParse, pX, ®Free1)); + exprToRegister(&tempX, exprCodeVector(pParse, &tempX, ®Free1)); testcase( regFree1==0 ); opCompare.op = TK_EQ; opCompare.pLeft = &tempX; @@ -4099,9 +4137,7 @@ static void exprCodeBetween( compRight.op = TK_LE; compRight.pLeft = &exprX; compRight.pRight = pExpr->x.pList->a[1].pExpr; - if( sqlite3ExprIsVector(&exprX)==0 ){ - exprToRegister(&exprX, sqlite3ExprCodeTemp(pParse, &exprX, ®Free1)); - } + exprToRegister(&exprX, exprCodeVector(pParse, &exprX, ®Free1)); if( xJump ){ xJump(pParse, &exprAnd, dest, jumpIfNull); }else{ diff --git a/test/e_expr.test b/test/e_expr.test index 6ef55ce8a6..6165aa3588 100644 --- a/test/e_expr.test +++ b/test/e_expr.test @@ -847,6 +847,9 @@ foreach {tn x expr res nEval} { 3 5 "x() >= 5 AND x() <= 5" 1 2 4 5 "x() BETWEEN 5 AND 5" 1 1 + + 5 9 "(x(),8) >= (9,7) AND (x(),8)<=(9,10)" 1 2 + 6 9 "(x(),8) BETWEEN (9,7) AND (9,10)" 1 1 } { do_test e_expr-13.1.$tn { set ::xcount 0 diff --git a/test/rowvalue8.test b/test/rowvalue8.test new file mode 100644 index 0000000000..432dad1278 --- /dev/null +++ b/test/rowvalue8.test @@ -0,0 +1,59 @@ +# 2016-08-22 +# +# 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. +# +#*********************************************************************** +# Use of row values in CASE statements. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set ::testprefix rowvalue8 + +do_execsql_test 1.1 { + CREATE TABLE t1(a INTEGER PRIMARY KEY,b,c,d); + INSERT INTO t1(a,b,c,d) VALUES + (1,1,2,3), + (2,2,3,4), + (3,1,2,4), + (4,2,3,5), + (5,3,4,6), + (6,4,5,9); + SELECT a, CASE (b,c) WHEN (1,2) THEN 'aleph' + WHEN (2,3) THEN 'bet' + WHEN (3,4) THEN 'gimel' + ELSE '-' END, + '|' + FROM t1 + ORDER BY a; +} {1 aleph | 2 bet | 3 aleph | 4 bet | 5 gimel | 6 - |} +do_execsql_test 1.2 { + SELECT a, CASE (b,c,d) WHEN (1,2,3) THEN 'aleph' + WHEN (2,3,4) THEN 'bet' + WHEN (3,4,6) THEN 'gimel' + ELSE '-' END, + '|' + FROM t1 + ORDER BY a; +} {1 aleph | 2 bet | 3 - | 4 - | 5 gimel | 6 - |} + +do_execsql_test 2.1 { + CREATE TABLE t2(x INTEGER PRIMARY KEY, y); + INSERT INTO t2(x,y) VALUES(1,6),(2,5),(3,4),(4,3),(5,2),(6,1); + SELECT x, CASE (SELECT b,c FROM t1 WHERE a=y) + WHEN (1,2) THEN 'aleph' + WHEN (2,3) THEN 'bet' + WHEN (3,4) THEN 'gimel' + ELSE '-' END, + '|' + FROM t2 + ORDER BY +x; +} {1 - | 2 gimel | 3 bet | 4 aleph | 5 bet | 6 aleph |} + + +finish_test From 6ae3ab00368c04d370eb3004e6580cf4f6791541 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 23 Aug 2016 14:42:15 +0000 Subject: [PATCH 0736/1484] Fix the SQLITE_USER_AUTHENTICATION login check so that the SQLITE_AUTH_USER error code correctly propagates and is not overwritten by SQLITE_ERROR. FossilOrigin-Name: c640489db2037f1a284d7b85fa753ccdac1b8f79 --- manifest | 13 ++++++------- manifest.uuid | 2 +- src/build.c | 2 +- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index f6da52a9f5..eb702b7169 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\ssupport\sfor\sthe\sSQLITE_DBCONFIG_MAINDBNAME\sconfiguration\soption. -D 2016-08-22T20:10:01.543 +C Fix\sthe\sSQLITE_USER_AUTHENTICATION\slogin\scheck\sso\sthat\sthe\sSQLITE_AUTH_USER\nerror\scode\scorrectly\spropagates\sand\sis\snot\soverwritten\sby\sSQLITE_ERROR. +D 2016-08-23T14:42:15.107 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -331,7 +331,7 @@ F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 F src/btree.c 2551bd3ecb8b8988fb8b23aabadfb214dbc38e46 F src/btree.h 075c45707c0f8f8af118f739f36df8098a08b7da F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 -F src/build.c d32cacbb59a403b68e1c2ec962ca31b6f3aad4fc +F src/build.c c2ccfcdd99e18894a8750e215b8d9c5398a3c073 F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7 @@ -1511,8 +1511,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 083f9e6270fa4faa402b91231271da4f3915c79f 12d5e38d269ede27cd38a031a395915301fffe56 -R a6e4b4d3ce0ef3f2cf848bb14d9b8323 -T +closed 12d5e38d269ede27cd38a031a395915301fffe56 +P 7839519349c7371cdb4e16a215eacd27004cbc62 +R 9d6fb42ced27e9f36e142aa6e0d35f69 U drh -Z 7e1aff0002b8c240c3859f075858093c +Z 4b4f28634d508607542ad65188ee7936 diff --git a/manifest.uuid b/manifest.uuid index b5392b6178..4b339d677c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7839519349c7371cdb4e16a215eacd27004cbc62 \ No newline at end of file +c640489db2037f1a284d7b85fa753ccdac1b8f79 \ No newline at end of file diff --git a/src/build.c b/src/build.c index 15c005f4ea..ca4802cd0a 100644 --- a/src/build.c +++ b/src/build.c @@ -153,8 +153,8 @@ void sqlite3FinishCoding(Parse *pParse){ if( pParse->nTableLock>0 && db->init.busy==0 ){ sqlite3UserAuthInit(db); if( db->auth.authLevelrc = SQLITE_AUTH_USER; sqlite3ErrorMsg(pParse, "user not authenticated"); + pParse->rc = SQLITE_AUTH_USER; return; } } From abb9d5f18972f48fe9b461c44fc615b2d3366fbe Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 23 Aug 2016 17:30:55 +0000 Subject: [PATCH 0737/1484] Fix an uninitialized variable in CASE expression code generation. FossilOrigin-Name: c8ffae05e13033ec7425bf0f002df31f550bb7f1 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/expr.c | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 21dcf79efe..7a34078a6c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\svector\sBETWEEN\soperator\sso\sthat\sit\sonly\sevaluates\sthe\sleft-most\nvector\sexpression\sonce.\s\sAdd\ssupport\sfor\svector\scomparisons\sin\sthe\sCASE\noperator. -D 2016-08-22T14:30:05.854 +C Fix\san\suninitialized\svariable\sin\sCASE\sexpression\scode\sgeneration. +D 2016-08-23T17:30:55.883 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -338,7 +338,7 @@ F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7 F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c 76c084f0265f4a3cd1ecf17eee112a94f1ccbc05 -F src/expr.c 575d6767abc4d38362bb54599dbb72a09946c5be +F src/expr.c 511768687886e4e55b586678ab4111e49a4a346e F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c e2be0968c1adc679c87e467aa5b4f167588f38a8 F src/func.c 29cc9acb170ec1387b9f63eb52cd85f8de96c771 @@ -1520,7 +1520,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 2f39987f21bd6dae8d2be610a1fd5f06f8878e9e -R 46b91546c6e852a3d13f61b9c8a6f99f +P 07e69f43a294d35b5145a2b0242ee42d50adab14 +R 4aa2c65fcf3b3b47ff0ca17ab554bdbd U drh -Z cdfb95caa6cbc00a53a66a6c4e92b927 +Z 4308f4ee8b9a3cd69479e48fad7b9733 diff --git a/manifest.uuid b/manifest.uuid index e35c310130..c7f5a16ecd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -07e69f43a294d35b5145a2b0242ee42d50adab14 \ No newline at end of file +c8ffae05e13033ec7425bf0f002df31f550bb7f1 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index b304e27835..829afc4cd6 100644 --- a/src/expr.c +++ b/src/expr.c @@ -3821,6 +3821,7 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ testcase( pX->op==TK_COLUMN ); exprToRegister(&tempX, exprCodeVector(pParse, &tempX, ®Free1)); testcase( regFree1==0 ); + memset(&opCompare, 0, sizeof(opCompare)); opCompare.op = TK_EQ; opCompare.pLeft = &tempX; pTest = &opCompare; From 66860af3dd71fc0242ce5ef89124f3f7deaa0e48 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 23 Aug 2016 18:30:10 +0000 Subject: [PATCH 0738/1484] Fix a problem with rowvalue UPDATE when the rowvalue is not the left-most and the RHS is a multi-column subquery. FossilOrigin-Name: e149e6b93a9afb3d574309c0db60e221e24078f7 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/expr.c | 8 +++++--- test/rowvalue7.test | 2 +- 4 files changed, 14 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 7a34078a6c..d4c268de95 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\suninitialized\svariable\sin\sCASE\sexpression\scode\sgeneration. -D 2016-08-23T17:30:55.883 +C Fix\sa\sproblem\swith\srowvalue\sUPDATE\swhen\sthe\srowvalue\sis\snot\sthe\sleft-most\sand\nthe\sRHS\sis\sa\smulti-column\ssubquery. +D 2016-08-23T18:30:10.697 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -338,7 +338,7 @@ F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7 F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c 76c084f0265f4a3cd1ecf17eee112a94f1ccbc05 -F src/expr.c 511768687886e4e55b586678ab4111e49a4a346e +F src/expr.c 3d3cc24386929991ff0c4264a8dde45b298c599e F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c e2be0968c1adc679c87e467aa5b4f167588f38a8 F src/func.c 29cc9acb170ec1387b9f63eb52cd85f8de96c771 @@ -1025,7 +1025,7 @@ F test/rowvalue3.test dbe935260851b197dfbbbcb0ac2a15cb5f324fd4 F test/rowvalue4.test 318cdd40e66dfae686537eea581ae49cbb01195d F test/rowvalue5.test 01c7e0bc4048f30b58e6eb27ecd26e5bd312635e F test/rowvalue6.test d19b54feb604d5601f8614b15e214e0774c01087 -F test/rowvalue7.test 3c9a127954d3da309a271babdfc43dbcc5c4da7f +F test/rowvalue7.test 5d06ff19d9e6969e574a2e662a531dd0c67801a8 F test/rowvalue8.test 5900eddad9e2c3c2e26f1a95f74aafc1232ee5e0 F test/rowvaluefault.test 7b16485e3f2b371f3e3d05455b8ded6d0c090244 F test/rtree.test 0c8d9dd458d6824e59683c19ab2ffa9ef946f798 @@ -1520,7 +1520,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 07e69f43a294d35b5145a2b0242ee42d50adab14 -R 4aa2c65fcf3b3b47ff0ca17ab554bdbd +P c8ffae05e13033ec7425bf0f002df31f550bb7f1 +R 8c42685900faf8a76ebfa8d4883d872e U drh -Z 4308f4ee8b9a3cd69479e48fad7b9733 +Z b8c84bcbf71dd1d1d9c9f62200ebb8ca diff --git a/manifest.uuid b/manifest.uuid index c7f5a16ecd..bd556e03a8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c8ffae05e13033ec7425bf0f002df31f550bb7f1 \ No newline at end of file +e149e6b93a9afb3d574309c0db60e221e24078f7 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 829afc4cd6..2e09d07982 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1489,6 +1489,7 @@ ExprList *sqlite3ExprListAppendVector( sqlite3 *db = pParse->db; int n; int i; + int iFirst = pList ? pList->nExpr : 0; if( pColumns==0 ) goto vector_append_error; if( pExpr==0 ) goto vector_append_error; n = sqlite3ExprVectorSize(pExpr); @@ -1501,14 +1502,15 @@ ExprList *sqlite3ExprListAppendVector( Expr *pSubExpr = sqlite3ExprForVectorField(pParse, pExpr, i); pList = sqlite3ExprListAppend(pParse, pList, pSubExpr); if( pList ){ + assert( pList->nExpr==iFirst+i+1 ); pList->a[pList->nExpr-1].zName = pColumns->a[i].zName; pColumns->a[i].zName = 0; } } if( pExpr->op==TK_SELECT ){ - if( pList && pList->a[0].pExpr ){ - assert( pList->a[0].pExpr->op==TK_SELECT_COLUMN ); - pList->a[0].pExpr->pRight = pExpr; + if( pList && pList->a[iFirst].pExpr ){ + assert( pList->a[iFirst].pExpr->op==TK_SELECT_COLUMN ); + pList->a[iFirst].pExpr->pRight = pExpr; pExpr = 0; } } diff --git a/test/rowvalue7.test b/test/rowvalue7.test index a90e235ce2..f6764f301e 100644 --- a/test/rowvalue7.test +++ b/test/rowvalue7.test @@ -43,7 +43,7 @@ do_execsql_test 1.4 { } {1 2 11 22 | 3 4 99 55 | 5 6 55 66 |} do_execsql_test 1.5 { - UPDATE t1 SET b = 8, (c,d) = (123,456) WHERE a=3; + UPDATE t1 SET b = 8, (c,d) = (SELECT 123,456) WHERE a=3; SELECT *,'|' FROM t1 ORDER BY a; } {1 2 11 22 | 3 8 123 456 | 5 6 55 66 |} From e835bc1285ca3688d8f92c4c972edb876382a2e7 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 23 Aug 2016 19:02:55 +0000 Subject: [PATCH 0739/1484] Simplify the row value misuse error message. FossilOrigin-Name: 838c50a5bf46fd0340839d577fa28ba02b4f2034 --- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- src/expr.c | 6 +++--- test/rowvalue.test | 5 ++--- test/rowvalue3.test | 2 -- test/rowvalue4.test | 11 +++++------ test/rowvalue5.test | 1 - 7 files changed, 21 insertions(+), 26 deletions(-) diff --git a/manifest b/manifest index d4c268de95..90d05b40fd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\swith\srowvalue\sUPDATE\swhen\sthe\srowvalue\sis\snot\sthe\sleft-most\sand\nthe\sRHS\sis\sa\smulti-column\ssubquery. -D 2016-08-23T18:30:10.697 +C Simplify\sthe\srow\svalue\smisuse\serror\smessage. +D 2016-08-23T19:02:55.746 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -338,7 +338,7 @@ F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7 F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c 76c084f0265f4a3cd1ecf17eee112a94f1ccbc05 -F src/expr.c 3d3cc24386929991ff0c4264a8dde45b298c599e +F src/expr.c e67849c475435a2d8268a660aaeff7d1df505a2f F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c e2be0968c1adc679c87e467aa5b4f167588f38a8 F src/func.c 29cc9acb170ec1387b9f63eb52cd85f8de96c771 @@ -1019,11 +1019,11 @@ F test/rollbackfault.test 0e646aeab8840c399cfbfa43daab46fd609cf04a F test/rowallock.test 3f88ec6819489d0b2341c7a7528ae17c053ab7cc F test/rowhash.test 0bc1d31415e4575d10cacf31e1a66b5cc0f8be81 F test/rowid.test 5b7509f384f4f6fae1af3c8c104c8ca299fea18d -F test/rowvalue.test 56b34d31d91340a6e922e753b798880170cc1aa7 +F test/rowvalue.test c2b4d043f4253711c8a2c6aa126a3f6d71182969 F test/rowvalue2.test 875068299fd4dd50ef0a47786462c8e1f4065f9a -F test/rowvalue3.test dbe935260851b197dfbbbcb0ac2a15cb5f324fd4 -F test/rowvalue4.test 318cdd40e66dfae686537eea581ae49cbb01195d -F test/rowvalue5.test 01c7e0bc4048f30b58e6eb27ecd26e5bd312635e +F test/rowvalue3.test 01399b7bf150b0d41abce76c18072da777c2500c +F test/rowvalue4.test 9b40c9be9bdde30fc66cddbfdf6a5af37de4ccac +F test/rowvalue5.test a440d490c8c0bf606034c09d5c6bbf7840b98f95 F test/rowvalue6.test d19b54feb604d5601f8614b15e214e0774c01087 F test/rowvalue7.test 5d06ff19d9e6969e574a2e662a531dd0c67801a8 F test/rowvalue8.test 5900eddad9e2c3c2e26f1a95f74aafc1232ee5e0 @@ -1520,7 +1520,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P c8ffae05e13033ec7425bf0f002df31f550bb7f1 -R 8c42685900faf8a76ebfa8d4883d872e +P e149e6b93a9afb3d574309c0db60e221e24078f7 +R 4cb3db3c4cfd8c4158ffeb6116b28260 U drh -Z b8c84bcbf71dd1d1d9c9f62200ebb8ca +Z 62ec580862aeb7b6a1de73caa33d9d9e diff --git a/manifest.uuid b/manifest.uuid index bd556e03a8..f1ac3fff86 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e149e6b93a9afb3d574309c0db60e221e24078f7 \ No newline at end of file +838c50a5bf46fd0340839d577fa28ba02b4f2034 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 2e09d07982..8c0d8b3cce 100644 --- a/src/expr.c +++ b/src/expr.c @@ -517,7 +517,7 @@ static void codeVectorCompare( /* Check that both sides of the comparison are vectors, and that ** both are the same length. */ if( nLeft!=nRight ){ - sqlite3ErrorMsg(pParse, "invalid use of row value"); + sqlite3ErrorMsg(pParse, "row value misused"); }else{ int i; int regLeft = 0; @@ -2610,7 +2610,7 @@ int sqlite3ExprCheckIN(Parse *pParse, Expr *pIn){ if( (pIn->pLeft->flags & EP_xIsSelect) ){ sqlite3SubselectError(pParse, nVector, 1); }else{ - sqlite3ErrorMsg(pParse, "invalid use of row value"); + sqlite3ErrorMsg(pParse, "row value misused"); } return 1; } @@ -3775,7 +3775,7 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ } case TK_VECTOR: { - sqlite3ErrorMsg(pParse, "invalid use of row value"); + sqlite3ErrorMsg(pParse, "row value misused"); break; } diff --git a/test/rowvalue.test b/test/rowvalue.test index a1faba97ab..642a7843aa 100644 --- a/test/rowvalue.test +++ b/test/rowvalue.test @@ -150,10 +150,10 @@ do_execsql_test 6.5 { } {i ii} do_catchsql_test 6.6 { SELECT c FROM hh WHERE (a, b) = (SELECT 'abc', 1) COLLATE nocase; -} {1 {invalid use of row value}} +} {1 {row value misused}} do_catchsql_test 6.7 { SELECT c FROM hh WHERE (a, b) = 1; -} {1 {invalid use of row value}} +} {1 {row value misused}} do_execsql_test 6.8 { SELECT c FROM hh WHERE (a COLLATE nocase, b) = (SELECT 'def', 2); } {iii iv} @@ -221,4 +221,3 @@ foreach {tn q res} { finish_test - diff --git a/test/rowvalue3.test b/test/rowvalue3.test index 17bf96a0f4..b050e70dde 100644 --- a/test/rowvalue3.test +++ b/test/rowvalue3.test @@ -204,5 +204,3 @@ foreach {tn idx} { finish_test - - diff --git a/test/rowvalue4.test b/test/rowvalue4.test index c4581d5562..a30edcc262 100644 --- a/test/rowvalue4.test +++ b/test/rowvalue4.test @@ -34,14 +34,14 @@ foreach {tn e} { 2 "1 + (1, 2)" 3 "(1,2,3) == (1, 2)" } { - do_catchsql_test 1.$tn "SELECT $e" {1 {invalid use of row value}} + do_catchsql_test 1.$tn "SELECT $e" {1 {row value misused}} } foreach {tn s error} { - 1 "SELECT * FROM t1 WHERE a = (1, 2)" {invalid use of row value} - 2 "SELECT * FROM t1 WHERE b = (1, 2)" {invalid use of row value} - 3 "SELECT * FROM t1 WHERE NOT (b = (1, 2))" {invalid use of row value} - 4 "SELECT * FROM t1 LIMIT (1, 2)" {invalid use of row value} + 1 "SELECT * FROM t1 WHERE a = (1, 2)" {row value misused} + 2 "SELECT * FROM t1 WHERE b = (1, 2)" {row value misused} + 3 "SELECT * FROM t1 WHERE NOT (b = (1, 2))" {row value misused} + 4 "SELECT * FROM t1 LIMIT (1, 2)" {row value misused} 5 "SELECT (a, b) IN (SELECT * FROM t1) FROM t1" {sub-select returns 3 columns - expected 2} @@ -309,4 +309,3 @@ do_catchsql_test 8.2 { } {1 {sub-select returns 2 columns - expected 1}} finish_test - diff --git a/test/rowvalue5.test b/test/rowvalue5.test index c961cf7424..d5976ccb89 100644 --- a/test/rowvalue5.test +++ b/test/rowvalue5.test @@ -110,4 +110,3 @@ foreach {tn where res} { } finish_test - From 894241c8473aa2079a73a82debf3f81eb7cac74b Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 24 Aug 2016 00:25:27 +0000 Subject: [PATCH 0740/1484] Avoid a potential null-pointer dereference following an OOM. FossilOrigin-Name: 25f6ed8de4df9c9890d4a352a6d11084433e82ea --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/expr.c | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 90d05b40fd..ce1c2ee88c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Simplify\sthe\srow\svalue\smisuse\serror\smessage. -D 2016-08-23T19:02:55.746 +C Avoid\sa\spotential\snull-pointer\sdereference\sfollowing\san\sOOM. +D 2016-08-24T00:25:27.492 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -338,7 +338,7 @@ F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7 F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c 76c084f0265f4a3cd1ecf17eee112a94f1ccbc05 -F src/expr.c e67849c475435a2d8268a660aaeff7d1df505a2f +F src/expr.c be8772ac5019400096eea179c1bfd5acc420bde9 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c e2be0968c1adc679c87e467aa5b4f167588f38a8 F src/func.c 29cc9acb170ec1387b9f63eb52cd85f8de96c771 @@ -1520,7 +1520,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e149e6b93a9afb3d574309c0db60e221e24078f7 -R 4cb3db3c4cfd8c4158ffeb6116b28260 +P 838c50a5bf46fd0340839d577fa28ba02b4f2034 +R 960a362fd9424a163c5a4d069783cdea U drh -Z 62ec580862aeb7b6a1de73caa33d9d9e +Z 2276dcfeffa9ab927fd9ef765fca4810 diff --git a/manifest.uuid b/manifest.uuid index f1ac3fff86..7ec267fc1e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -838c50a5bf46fd0340839d577fa28ba02b4f2034 \ No newline at end of file +25f6ed8de4df9c9890d4a352a6d11084433e82ea \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 8c0d8b3cce..0f59970311 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2103,6 +2103,7 @@ int sqlite3FindInIndex( int mustBeUnique; /* True if RHS must be unique */ Vdbe *v = sqlite3GetVdbe(pParse); /* Virtual machine being coded */ + if( pParse->db->mallocFailed ) return IN_INDEX_NOOP; assert( pX->op==TK_IN ); mustBeUnique = (inFlags & IN_INDEX_LOOP)!=0; From ac6b47d164a73101d700f244384a2339f31a8e5b Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 24 Aug 2016 00:51:48 +0000 Subject: [PATCH 0741/1484] The previous OOM fix was bad. Back it out and replace it with a better one. FossilOrigin-Name: 1e3bc3698a4b779e6af8e3c727929c4dbddf3edb --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/expr.c | 2 +- src/wherecode.c | 16 ++++++++-------- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/manifest b/manifest index ce1c2ee88c..c7b9d98ca9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sa\spotential\snull-pointer\sdereference\sfollowing\san\sOOM. -D 2016-08-24T00:25:27.492 +C The\sprevious\sOOM\sfix\swas\sbad.\s\sBack\sit\sout\sand\sreplace\sit\swith\sa\sbetter\sone. +D 2016-08-24T00:51:48.043 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -338,7 +338,7 @@ F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7 F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c 76c084f0265f4a3cd1ecf17eee112a94f1ccbc05 -F src/expr.c be8772ac5019400096eea179c1bfd5acc420bde9 +F src/expr.c f433feeeaa43d52a4e029066a1af02bac9ed5f1a F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c e2be0968c1adc679c87e467aa5b4f167588f38a8 F src/func.c 29cc9acb170ec1387b9f63eb52cd85f8de96c771 @@ -466,7 +466,7 @@ F src/wal.h 6dd221ed384afdc204bc61e25c23ef7fd5a511f2 F src/walker.c 2d2cc7fb0f320f7f415215d7247f3c584141ac09 F src/where.c c7cdfd54f383090bb801cdd50d36de1a24684bb2 F src/whereInt.h 14dd243e13b81cbb0a66063d38b70f93a7d6e613 -F src/wherecode.c 0c790c422ea5ecb6c83d6a78f2c4ebc036eea90e +F src/wherecode.c 0c99e2e97c23ec0b0d64071b3590d3a5e6091a96 F src/whereexpr.c aa54bf11adf6bc7e52f56281f436ab5fd421ce16 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -1520,7 +1520,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 838c50a5bf46fd0340839d577fa28ba02b4f2034 -R 960a362fd9424a163c5a4d069783cdea +P 25f6ed8de4df9c9890d4a352a6d11084433e82ea +R 19a9e7a69bf070f3aad327c389d879a1 U drh -Z 2276dcfeffa9ab927fd9ef765fca4810 +Z c33731cf7b01c5dd25f3f1c4114950f7 diff --git a/manifest.uuid b/manifest.uuid index 7ec267fc1e..6e72ba55fc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -25f6ed8de4df9c9890d4a352a6d11084433e82ea \ No newline at end of file +1e3bc3698a4b779e6af8e3c727929c4dbddf3edb \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 0f59970311..572edaa541 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1952,6 +1952,7 @@ static Select *isCandidateForInOpt(Expr *pX){ assert( pTab->pSelect==0 ); /* FROM clause is not a view */ if( IsVirtual(pTab) ) return 0; /* FROM clause not a virtual table */ pEList = p->pEList; + assert( pEList!=0 ); /* All SELECT results must be columns. */ for(i=0; inExpr; i++){ @@ -2103,7 +2104,6 @@ int sqlite3FindInIndex( int mustBeUnique; /* True if RHS must be unique */ Vdbe *v = sqlite3GetVdbe(pParse); /* Virtual machine being coded */ - if( pParse->db->mallocFailed ) return IN_INDEX_NOOP; assert( pX->op==TK_IN ); mustBeUnique = (inFlags & IN_INDEX_LOOP)!=0; diff --git a/src/wherecode.c b/src/wherecode.c index 2ef9a46b5d..fbf6ad1946 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -383,7 +383,7 @@ static int codeEqualityTerm( sqlite3VdbeAddOp2(v, OP_Null, 0, iReg); #ifndef SQLITE_OMIT_SUBQUERY }else{ - int eType; + int eType = IN_INDEX_NOOP; int iTab; struct InLoop *pIn; WhereLoop *pLoop = pLevel->pWLoop; @@ -436,13 +436,13 @@ static int codeEqualityTerm( pLhs = sqlite3ExprListAppend(pParse, pLhs, pNewLhs); } } - - pX->x.pSelect->pEList = pRhs; - pX->pLeft->x.pList = pLhs; - - eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap); - pX->x.pSelect->pEList = pOrigRhs; - pX->pLeft->x.pList = pOrigLhs; + if( !db->mallocFailed ){ + pX->x.pSelect->pEList = pRhs; + pX->pLeft->x.pList = pLhs; + eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap); + pX->x.pSelect->pEList = pOrigRhs; + pX->pLeft->x.pList = pOrigLhs; + } sqlite3ExprListDelete(pParse->db, pLhs); sqlite3ExprListDelete(pParse->db, pRhs); } From 7887d7f24d176b75a77dd8a86abcdbb70a83b957 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 24 Aug 2016 12:22:17 +0000 Subject: [PATCH 0742/1484] Fix a buffer overrun in the code for handling IN(...) operators when the LHS of the operator contains indexed columns or expressions. FossilOrigin-Name: f41a0391b732a8c4ad188163f34a0f4a22237bb5 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/wherecode.c | 3 ++- test/rowvalue.test | 9 +++++++++ 4 files changed, 20 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index c7b9d98ca9..b6792e8020 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C The\sprevious\sOOM\sfix\swas\sbad.\s\sBack\sit\sout\sand\sreplace\sit\swith\sa\sbetter\sone. -D 2016-08-24T00:51:48.043 +C Fix\sa\sbuffer\soverrun\sin\sthe\scode\sfor\shandling\sIN(...)\soperators\swhen\sthe\sLHS\sof\sthe\soperator\scontains\sindexed\scolumns\sor\sexpressions. +D 2016-08-24T12:22:17.962 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -466,7 +466,7 @@ F src/wal.h 6dd221ed384afdc204bc61e25c23ef7fd5a511f2 F src/walker.c 2d2cc7fb0f320f7f415215d7247f3c584141ac09 F src/where.c c7cdfd54f383090bb801cdd50d36de1a24684bb2 F src/whereInt.h 14dd243e13b81cbb0a66063d38b70f93a7d6e613 -F src/wherecode.c 0c99e2e97c23ec0b0d64071b3590d3a5e6091a96 +F src/wherecode.c 5a5528c39be09593cada6ae465d7a0f48db0077f F src/whereexpr.c aa54bf11adf6bc7e52f56281f436ab5fd421ce16 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -1019,7 +1019,7 @@ F test/rollbackfault.test 0e646aeab8840c399cfbfa43daab46fd609cf04a F test/rowallock.test 3f88ec6819489d0b2341c7a7528ae17c053ab7cc F test/rowhash.test 0bc1d31415e4575d10cacf31e1a66b5cc0f8be81 F test/rowid.test 5b7509f384f4f6fae1af3c8c104c8ca299fea18d -F test/rowvalue.test c2b4d043f4253711c8a2c6aa126a3f6d71182969 +F test/rowvalue.test 7d8482dde9023973615eaaca65647f33d70c1f01 F test/rowvalue2.test 875068299fd4dd50ef0a47786462c8e1f4065f9a F test/rowvalue3.test 01399b7bf150b0d41abce76c18072da777c2500c F test/rowvalue4.test 9b40c9be9bdde30fc66cddbfdf6a5af37de4ccac @@ -1520,7 +1520,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 25f6ed8de4df9c9890d4a352a6d11084433e82ea -R 19a9e7a69bf070f3aad327c389d879a1 -U drh -Z c33731cf7b01c5dd25f3f1c4114950f7 +P 1e3bc3698a4b779e6af8e3c727929c4dbddf3edb +R 66ed27e8c4688d763f7b5bcfa14b1684 +U dan +Z b0da933895eae6df1437a965446c74bb diff --git a/manifest.uuid b/manifest.uuid index 6e72ba55fc..14c9bf29a3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1e3bc3698a4b779e6af8e3c727929c4dbddf3edb \ No newline at end of file +f41a0391b732a8c4ad188163f34a0f4a22237bb5 \ No newline at end of file diff --git a/src/wherecode.c b/src/wherecode.c index fbf6ad1946..65079872e1 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -471,7 +471,7 @@ static int codeEqualityTerm( if( pIn ){ int iMap = 0; /* Index in aiMap[] */ pIn += i; - for(i=iEq;inLTerm; i++, pIn++){ + for(i=iEq;inLTerm; i++){ int iOut = iReg; if( pLoop->aLTerm[i]->pExpr==pX ){ if( eType==IN_INDEX_ROWID ){ @@ -489,6 +489,7 @@ static int codeEqualityTerm( }else{ pIn->eEndLoopOp = OP_Noop; } + pIn++; } } }else{ diff --git a/test/rowvalue.test b/test/rowvalue.test index 642a7843aa..f716c26c8b 100644 --- a/test/rowvalue.test +++ b/test/rowvalue.test @@ -219,5 +219,14 @@ foreach {tn q res} { do_execsql_test 9.$tn "SELECT c FROM t2 WHERE $q" $res } +do_execsql_test 10.0 { + CREATE TABLE dual(dummy); INSERT INTO dual(dummy) VALUES('X'); + CREATE TABLE t3(a TEXT,b TEXT,c TEXT,d TEXT,e TEXT,f TEXT); + CREATE INDEX t3x ON t3(b,c,d,e,f); + + SELECT a FROM t3 + WHERE (c,d) IN (SELECT 'c','d' FROM dual) + AND (a,b,e) IN (SELECT 'a','b','d' FROM dual); +} finish_test From d0b67a8654809493d07bff62e2d9ce480be7b4df Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 24 Aug 2016 15:37:31 +0000 Subject: [PATCH 0743/1484] Add a NEVER() on an unreachable branch in comparisonAffinity(). FossilOrigin-Name: 505a2f20eac62d4e170f003255c8984e4f3b0918 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/expr.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index b6792e8020..9cd230d12f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sbuffer\soverrun\sin\sthe\scode\sfor\shandling\sIN(...)\soperators\swhen\sthe\sLHS\sof\sthe\soperator\scontains\sindexed\scolumns\sor\sexpressions. -D 2016-08-24T12:22:17.962 +C Add\sa\sNEVER()\son\san\sunreachable\sbranch\sin\scomparisonAffinity(). +D 2016-08-24T15:37:31.592 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -338,7 +338,7 @@ F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7 F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c 76c084f0265f4a3cd1ecf17eee112a94f1ccbc05 -F src/expr.c f433feeeaa43d52a4e029066a1af02bac9ed5f1a +F src/expr.c c2d3844fb18e7659653e482060ee0c5d3ec5ed10 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c e2be0968c1adc679c87e467aa5b4f167588f38a8 F src/func.c 29cc9acb170ec1387b9f63eb52cd85f8de96c771 @@ -1520,7 +1520,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 1e3bc3698a4b779e6af8e3c727929c4dbddf3edb -R 66ed27e8c4688d763f7b5bcfa14b1684 -U dan -Z b0da933895eae6df1437a965446c74bb +P f41a0391b732a8c4ad188163f34a0f4a22237bb5 +R b0541cab67b62c886354064e8f5cfc4d +U drh +Z e7d2fda8d9703a6fa7987d8b8853c395 diff --git a/manifest.uuid b/manifest.uuid index 14c9bf29a3..4a04b24187 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f41a0391b732a8c4ad188163f34a0f4a22237bb5 \ No newline at end of file +505a2f20eac62d4e170f003255c8984e4f3b0918 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 572edaa541..37f778b29e 100644 --- a/src/expr.c +++ b/src/expr.c @@ -221,7 +221,7 @@ static char comparisonAffinity(Expr *pExpr){ aff = sqlite3CompareAffinity(pExpr->pRight, aff); }else if( ExprHasProperty(pExpr, EP_xIsSelect) ){ aff = sqlite3CompareAffinity(pExpr->x.pSelect->pEList->a[0].pExpr, aff); - }else if( !aff ){ + }else if( NEVER(aff==0) ){ aff = SQLITE_AFF_BLOB; } return aff; From 321e828d035d72c80e90d82f06d413658185805a Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 24 Aug 2016 17:49:07 +0000 Subject: [PATCH 0744/1484] Fix more unreachable branches. FossilOrigin-Name: 6099c180db55396d6307538a5428ae5ef1b82d10 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/expr.c | 7 +++++-- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 9cd230d12f..51920f87c0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sa\sNEVER()\son\san\sunreachable\sbranch\sin\scomparisonAffinity(). -D 2016-08-24T15:37:31.592 +C Fix\smore\sunreachable\sbranches. +D 2016-08-24T17:49:07.427 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -338,7 +338,7 @@ F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7 F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c 76c084f0265f4a3cd1ecf17eee112a94f1ccbc05 -F src/expr.c c2d3844fb18e7659653e482060ee0c5d3ec5ed10 +F src/expr.c 57b6d994d88d390a76ccb0ef81ea7b3bccf06fec F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c e2be0968c1adc679c87e467aa5b4f167588f38a8 F src/func.c 29cc9acb170ec1387b9f63eb52cd85f8de96c771 @@ -1520,7 +1520,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P f41a0391b732a8c4ad188163f34a0f4a22237bb5 -R b0541cab67b62c886354064e8f5cfc4d +P 505a2f20eac62d4e170f003255c8984e4f3b0918 +R 3bf744e7d3187456751558defe5b0a1e U drh -Z e7d2fda8d9703a6fa7987d8b8853c395 +Z 0d5e4686e1b28bbfaea275d793f60f16 diff --git a/manifest.uuid b/manifest.uuid index 4a04b24187..55daf21f48 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -505a2f20eac62d4e170f003255c8984e4f3b0918 \ No newline at end of file +6099c180db55396d6307538a5428ae5ef1b82d10 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 37f778b29e..56affdfeaa 100644 --- a/src/expr.c +++ b/src/expr.c @@ -542,10 +542,11 @@ static void codeVectorCompare( regLeft = exprCodeSubselect(pParse, pLeft); regRight = exprCodeSubselect(pParse, pRight); - for(i=0; i=0 && i0 ) sqlite3ExprCachePush(pParse); r1 = exprVectorRegister(pParse, pLeft, i, regLeft, &pL, ®Free1); r2 = exprVectorRegister(pParse, pRight, i, regRight, &pR, ®Free2); @@ -1490,7 +1491,9 @@ ExprList *sqlite3ExprListAppendVector( int n; int i; int iFirst = pList ? pList->nExpr : 0; - if( pColumns==0 ) goto vector_append_error; + /* pColumns can only be NULL due to an OOM but an OOM will cause an + ** exit prior to this routine being invoked */ + if( NEVER(pColumns==0) ) goto vector_append_error; if( pExpr==0 ) goto vector_append_error; n = sqlite3ExprVectorSize(pExpr); if( pColumns->nId!=n ){ From 24b6b81cb0768f131efdb3c3adeb8e929640f50d Mon Sep 17 00:00:00 2001 From: mistachkin Date: Wed, 24 Aug 2016 18:21:58 +0000 Subject: [PATCH 0745/1484] Sync up the MSVC autoconf makefile. FossilOrigin-Name: 77f7c31a3aa44798cfa5f557242caffb593ce7af --- Makefile.msc | 11 +++++++++++ autoconf/Makefile.msc | 8 ++++---- manifest | 16 ++++++++-------- manifest.uuid | 2 +- 4 files changed, 24 insertions(+), 13 deletions(-) diff --git a/Makefile.msc b/Makefile.msc index cd866ce4a4..6c7211651d 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -24,6 +24,13 @@ USE_AMALGAMATION = 1 USE_FULLWARN = 0 !ENDIF +# Set this non-0 to enable full runtime error checks (-RTC1, etc). This +# has no effect if (any) optimizations are enabled. +# +!IFNDEF USE_RUNTIME_CHECKS +USE_RUNTIME_CHECKS = 0 +!ENDIF + # Set this non-0 to use "stdcall" calling convention for the core library # and shell executable. # @@ -835,6 +842,10 @@ RCC = $(RCC) -D_DEBUG !IF $(DEBUG)>1 || $(OPTIMIZATIONS)==0 TCC = $(TCC) -Od BCC = $(BCC) -Od +!IF $(USE_RUNTIME_CHECKS)!=0 +TCC = $(TCC) -RTC1 +BCC = $(BCC) -RTC1 +!ENDIF !ELSEIF $(OPTIMIZATIONS)>=3 TCC = $(TCC) -Ox BCC = $(BCC) -Ox diff --git a/autoconf/Makefile.msc b/autoconf/Makefile.msc index d3bbc6b4d2..46c1e2671e 100644 --- a/autoconf/Makefile.msc +++ b/autoconf/Makefile.msc @@ -456,12 +456,12 @@ RCC = $(RC) -DSQLITE_OS_WIN=1 -I. -I$(TOP) $(RCOPTS) $(RCCOPTS) # !IF $(USE_STDCALL)!=0 || $(FOR_WIN10)!=0 !IF "$(PLATFORM)"=="x86" -CORE_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall -SHELL_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall +CORE_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_STDCALL=__stdcall +SHELL_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_STDCALL=__stdcall !ELSE !IFNDEF PLATFORM -CORE_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall -SHELL_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_APICALL=__stdcall -DSQLITE_CALLBACK=__stdcall -DSQLITE_SYSAPI=__stdcall +CORE_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_STDCALL=__stdcall +SHELL_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_STDCALL=__stdcall !ELSE CORE_CCONV_OPTS = SHELL_CCONV_OPTS = diff --git a/manifest b/manifest index eb702b7169..7dc1924e05 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -C Fix\sthe\sSQLITE_USER_AUTHENTICATION\slogin\scheck\sso\sthat\sthe\sSQLITE_AUTH_USER\nerror\scode\scorrectly\spropagates\sand\sis\snot\soverwritten\sby\sSQLITE_ERROR. -D 2016-08-23T14:42:15.107 +C Sync\sup\sthe\sMSVC\sautoconf\smakefile. +D 2016-08-24T18:21:58.857 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 -F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a +F Makefile.msc 5017381e4853b1472e01d5bb926be1268eba429c F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7 F VERSION 25e2e333adeff5965520bc8db999c658898c972d F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 @@ -11,7 +11,7 @@ F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am 1a47d071e3d5435f8f7ebff7eb6703848bbd65d4 -F autoconf/Makefile.msc 7a909aa9b538138a21c0626e3ffc4b1f4519f50e +F autoconf/Makefile.msc a535edafb6165629715b0ba8e21c98ab80732e80 F autoconf/README.first 6c4f34fe115ff55d4e8dbfa3cecf04a0188292f7 F autoconf/README.txt 4f04b0819303aabaa35fff5f7b257fb0c1ef95f1 F autoconf/configure.ac cacf2616abf6e4a569bde2ef365c143caeec40bc @@ -1511,7 +1511,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 7839519349c7371cdb4e16a215eacd27004cbc62 -R 9d6fb42ced27e9f36e142aa6e0d35f69 -U drh -Z 4b4f28634d508607542ad65188ee7936 +P c640489db2037f1a284d7b85fa753ccdac1b8f79 +R 959092fa640b62161f63260898254ab1 +U mistachkin +Z d96a1e74a14d6dd8b06850bfa4844a5e diff --git a/manifest.uuid b/manifest.uuid index 4b339d677c..630410a19c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c640489db2037f1a284d7b85fa753ccdac1b8f79 \ No newline at end of file +77f7c31a3aa44798cfa5f557242caffb593ce7af \ No newline at end of file From 37ff4d4c77662a01c7b1902486827426317142dd Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 24 Aug 2016 18:50:47 +0000 Subject: [PATCH 0746/1484] Fix a bug in the fts5 snippet function causing it to return text containing zero phrase instances. FossilOrigin-Name: b174ed2bde43a1872374ce18b85ac9f067e86fbb --- ext/fts5/fts5_aux.c | 4 ++-- ext/fts5/test/fts5af.test | 11 +++++++++++ manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 21 insertions(+), 10 deletions(-) diff --git a/ext/fts5/fts5_aux.c b/ext/fts5/fts5_aux.c index f2aacbff20..e171233050 100644 --- a/ext/fts5/fts5_aux.c +++ b/ext/fts5/fts5_aux.c @@ -331,6 +331,7 @@ static int fts5SnippetScore( int iFirst = -1; int nInst; int nScore = 0; + int iLast = 0; rc = pApi->xInstCount(pFts, &nInst); for(i=0; ixPhraseSize(pFts, ip); } } *pnScore = nScore; if( piPos ){ - int iLast = iOff + pApi->xPhraseSize(pFts, ip); int iAdj = iFirst - (nToken - (iLast-iFirst)) / 2; - if( (iAdj+nToken)>nDocsize ) iAdj = nDocsize - nToken; if( iAdj<0 ) iAdj = 0; *piPos = iAdj; diff --git a/ext/fts5/test/fts5af.test b/ext/fts5/test/fts5af.test index c8f815dfda..6aab55a557 100644 --- a/ext/fts5/test/fts5af.test +++ b/ext/fts5/test/fts5af.test @@ -164,6 +164,17 @@ do_execsql_test 4.0 { {1 2 3 4 5...} } +do_execsql_test 5.0 { + CREATE VIRTUAL TABLE p1 USING fts5(a, b); + INSERT INTO p1 VALUES( + 'x a a a a a a a a a a', + 'a a a a a a a a a a a a a a a a a a a x' + ); +} +do_execsql_test 5.1 { + SELECT snippet(p1, 0, '[', ']', '...', 6) FROM p1('x'); +} {{[x] a a a a a...}} + } ;# foreach_detail_mode finish_test diff --git a/manifest b/manifest index 9d9fddff14..6ce61f548e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sother\sminor\sproblems\swith\sthe\sfts5\ssnippet()\sfunction. -D 2016-08-20T17:23:45.034 +C Fix\sa\sbug\sin\sthe\sfts5\ssnippet\sfunction\scausing\sit\sto\sreturn\stext\scontaining\szero\sphrase\sinstances. +D 2016-08-24T18:50:47.193 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -99,7 +99,7 @@ F ext/fts3/unicode/parseunicode.tcl da577d1384810fb4e2b209bf3313074353193e95 F ext/fts5/extract_api_docs.tcl a36e54ec777172ddd3f9a88daf593b00848368e0 F ext/fts5/fts5.h 62f3e33ceeb9a428db139f9c012186b371da1cc7 F ext/fts5/fts5Int.h b2eda36e0f224365c8e23dc8f559311834f1c13f -F ext/fts5/fts5_aux.c 13246759ce03614a3b214894fa4b0f76891e97c0 +F ext/fts5/fts5_aux.c 2f20784a344701d4c72986e2e692062dd47d568c F ext/fts5/fts5_buffer.c 4c1502d4c956cd092c89ce4480867f9d8bf325cd F ext/fts5/fts5_config.c 5af9c360e99669d29f06492c370892394aba0857 F ext/fts5/fts5_expr.c 1ee97156421919e497595bfa962bb88ad1665401 @@ -122,7 +122,7 @@ F ext/fts5/test/fts5ab.test 30325a89453280160106be411bba3acf138e6d1b F ext/fts5/test/fts5ac.test 55cad4275a1f5acabfe14d8442a8046b47e49e5f F ext/fts5/test/fts5ad.test 36995f0586f30f5602074e012b9224c71ec5171c F ext/fts5/test/fts5ae.test 612dcb51f4069226791ff14c17dbfb3138c56f20 -F ext/fts5/test/fts5af.test b21abd9455c7351a9ef872b650d16f9dd8db2c49 +F ext/fts5/test/fts5af.test c92825778ed2adc80014832762c056bbe968ef88 F ext/fts5/test/fts5ag.test 27180de76c03036be75ee80b93d8c5f540014071 F ext/fts5/test/fts5ah.test dfb7897711dbcda1dacb038aec310daca139fcf5 F ext/fts5/test/fts5ai.test 3909d0b949b2afcaae4d5795cd79153da75381df @@ -1510,7 +1510,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b10e31dce8e590e1ba30f512374a8c16656bcc72 -R adacbf86d42eaec5a7639c5010230497 +P b56b2a85cf377686727f3929208ede43f797cf76 +R d95861b85eb0fcd438ce646b06ec5daf U dan -Z 520e1a56589636baad586098a109d286 +Z 1e5d85bd62c3d7d96772d546309a0d7d diff --git a/manifest.uuid b/manifest.uuid index eda24ca294..3fabbae740 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b56b2a85cf377686727f3929208ede43f797cf76 \ No newline at end of file +b174ed2bde43a1872374ce18b85ac9f067e86fbb \ No newline at end of file From 62659b2a806146dfb91a58b7f9e5f3649caa66c5 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 24 Aug 2016 18:51:23 +0000 Subject: [PATCH 0747/1484] In sqlite3FindInIndex(), improve internal comments and avoid an unreachable branch. FossilOrigin-Name: 55945fc12f8157e32e6850e41575c0c6422d29e7 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/expr.c | 16 ++++++++++++---- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 51920f87c0..daccb4786d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\smore\sunreachable\sbranches. -D 2016-08-24T17:49:07.427 +C In\ssqlite3FindInIndex(),\simprove\sinternal\scomments\sand\savoid\san\nunreachable\sbranch. +D 2016-08-24T18:51:23.484 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -338,7 +338,7 @@ F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7 F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c 76c084f0265f4a3cd1ecf17eee112a94f1ccbc05 -F src/expr.c 57b6d994d88d390a76ccb0ef81ea7b3bccf06fec +F src/expr.c 3dc226ccd9eebee600253eba07b8d97534e49337 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c e2be0968c1adc679c87e467aa5b4f167588f38a8 F src/func.c 29cc9acb170ec1387b9f63eb52cd85f8de96c771 @@ -1520,7 +1520,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 505a2f20eac62d4e170f003255c8984e4f3b0918 -R 3bf744e7d3187456751558defe5b0a1e +P 6099c180db55396d6307538a5428ae5ef1b82d10 +R fa8e14e08c5acfaa4521c63ce095c576 U drh -Z 0d5e4686e1b28bbfaea275d793f60f16 +Z 500a8a58193db1f42f4b49dd37f14aa8 diff --git a/manifest.uuid b/manifest.uuid index 55daf21f48..879b23070a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6099c180db55396d6307538a5428ae5ef1b82d10 \ No newline at end of file +55945fc12f8157e32e6850e41575c0c6422d29e7 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 56affdfeaa..63958b0d25 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2152,6 +2152,7 @@ int sqlite3FindInIndex( */ assert(v); if( nExpr==1 && pEList->a[0].pExpr->iColumn<0 ){ + /* The "x IN (SELECT rowid FROM table)" case */ int iAddr = sqlite3CodeOnce(pParse); VdbeCoverage(v); @@ -2165,18 +2166,25 @@ int sqlite3FindInIndex( int i; /* Check that the affinity that will be used to perform each - ** comparison is the same as the affinity of each column. If - ** it not, it is not possible to use any index. */ + ** comparison is the same as the affinity of each column in table + ** on the RHS of the IN operator. If it not, it is not possible to + ** use any index of the RHS table. */ for(i=0; ipLeft, i); int iCol = pEList->a[i].pExpr->iColumn; - char idxaff = pTab->aCol[iCol].affinity; + char idxaff = pTab->aCol[iCol].affinity; /* RHS table affinity */ char cmpaff = sqlite3CompareAffinity(pLhs, idxaff); + testcase( cmpaff==SQLITE_AFF_BLOB ); + testcase( cmpaff==SQLITE_AFF_TEXT ); switch( cmpaff ){ case SQLITE_AFF_BLOB: break; case SQLITE_AFF_TEXT: - affinity_ok = (idxaff==SQLITE_AFF_TEXT); + /* sqlite3CompareAffinity() only returns TEXT if one side or the + ** other has no affinity and the other side is TEXT. Hence, + ** the only way for cmpaff to be TEXT is for idxaff to be TEXT + ** and for the term on the LHS of the IN to have no affinity. */ + assert( idxaff==SQLITE_AFF_TEXT ); break; default: affinity_ok = sqlite3IsNumericAffinity(idxaff); From 4ef916e233eeaaba1e895e28a97bb63fb1833cd5 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Wed, 24 Aug 2016 19:58:46 +0000 Subject: [PATCH 0748/1484] Modularize all use of the calling convention macros based on the USE_STDCALL nmake macro. FossilOrigin-Name: e4a56197b08546601bd6a623f667b43f50d603be --- Makefile.msc | 99 ++++++++++++++++++++++++++++++++------- manifest | 18 +++---- manifest.uuid | 2 +- tool/mksqlite3c-noext.tcl | 57 +++++++++++++--------- tool/mksqlite3c.tcl | 27 ++++++----- tool/mksqlite3h.tcl | 36 +++++++++----- 6 files changed, 166 insertions(+), 73 deletions(-) diff --git a/Makefile.msc b/Makefile.msc index 527efd8f7d..1569487aa3 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -31,6 +31,13 @@ USE_FULLWARN = 0 USE_RUNTIME_CHECKS = 0 !ENDIF +# Set this non-0 to create a SQLite amalgamation file that excludes the +# various built-in extensions. +# +!IFNDEF MINIMAL_AMALGAMATION +MINIMAL_AMALGAMATION = 0 +!ENDIF + # Set this non-0 to use "stdcall" calling convention for the core library # and shell executable. # @@ -270,12 +277,37 @@ SQLITE3EXEPDB = /pdb:sqlite3sh.pdb !ENDIF !ENDIF +# These are the names of the customized Tcl header files used by various parts +# of this makefile when the stdcall calling convention is in use. It is not +# used for any other purpose. +# +!IFNDEF SQLITETCLH +SQLITETCLH = sqlite_tcl.h +!ENDIF + +!IFNDEF SQLITETCLDECLSH +SQLITETCLDECLSH = sqlite_tclDecls.h +!ENDIF + +# These are the additional targets that the targets that integrate with the +# Tcl library should depend on when compiling, etc. +# +!IFNDEF SQLITE_TCL_DEP +!IF $(USE_STDCALL)!=0 || $(FOR_WIN10)!=0 +SQLITE_TCL_DEP = $(SQLITETCLDECLSH) $(SQLITETCLH) +!ELSE +SQLITE_TCL_DEP = +!ENDIF +!ENDIF + # These are the "standard" SQLite compilation options used when compiling for # the Windows platform. # !IFNDEF OPT_FEATURE_FLAGS +!IF $(MINIMAL_AMALGAMATION)==0 OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_FTS3=1 OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_RTREE=1 +!ENDIF OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_COLUMN_METADATA=1 !ENDIF @@ -649,12 +681,35 @@ RCC = $(RCC) -I$(TOP)\ext\session # options are necessary in order to allow debugging symbols to # work correctly with Visual Studio when using the amalgamation. # +!IFNDEF MKSQLITE3C_TOOL +!IF $(MINIMAL_AMALGAMATION)!=0 +MKSQLITE3C_TOOL = $(TOP)\tool\mksqlite3c-noext.tcl +!ELSE +MKSQLITE3C_TOOL = $(TOP)\tool\mksqlite3c.tcl +!ENDIF +!ENDIF + !IFNDEF MKSQLITE3C_ARGS !IF $(DEBUG)>1 MKSQLITE3C_ARGS = --linemacros !ELSE MKSQLITE3C_ARGS = !ENDIF +!IF $(USE_STDCALL)!=0 || $(FOR_WIN10)!=0 +MKSQLITE3C_ARGS = $(MKSQLITE3C_ARGS) --useapicall +!ENDIF +!ENDIF + +# The mksqlite3h.tcl script accepts some options on the command line. +# When compiling with stdcall support, some of these options are +# necessary. +# +!IFNDEF MKSQLITE3H_ARGS +!IF $(USE_STDCALL)!=0 || $(FOR_WIN10)!=0 +MKSQLITE3H_ARGS = --useapicall +!ELSE +MKSQLITE3H_ARGS = +!ENDIF !ENDIF # <
    > @@ -1260,9 +1315,13 @@ SRC11 = \ # Generated Tcl header files # +!IF $(USE_STDCALL)!=0 || $(FOR_WIN10)!=0 SRC12 = \ - sqlite_tcl.h \ - sqlite_tclDecls.h + $(SQLITETCLH) \ + $(SQLITETCLDECLSH) +!ELSE +SRC12 = +!ENDIF # All source code files. # @@ -1528,7 +1587,7 @@ mptest: mptester.exe # files are automatically generated. This target takes care of # all that automatic generation. # -.target_source: $(SRC) $(TOP)\tool\vdbe-compress.tcl fts5.c sqlite_tcl.h +.target_source: $(SRC) $(TOP)\tool\vdbe-compress.tcl fts5.c $(SQLITE_TCL_DEP) -rmdir /Q/S tsrc 2>NUL -mkdir tsrc for %i in ($(SRC00)) do copy /Y %i tsrc @@ -1551,8 +1610,8 @@ mptest: mptester.exe move vdbe.new tsrc\vdbe.c echo > .target_source -sqlite3.c: .target_source sqlite3ext.h $(TOP)\tool\mksqlite3c.tcl - $(TCLSH_CMD) $(TOP)\tool\mksqlite3c.tcl $(MKSQLITE3C_ARGS) +sqlite3.c: .target_source sqlite3ext.h $(MKSQLITE3C_TOOL) + $(TCLSH_CMD) $(MKSQLITE3C_TOOL) $(MKSQLITE3C_ARGS) copy tsrc\shell.c . copy $(TOP)\ext\session\sqlite3session.h . @@ -1825,10 +1884,10 @@ wherecode.lo: $(TOP)\src\wherecode.c $(HDR) whereexpr.lo: $(TOP)\src\whereexpr.c $(HDR) $(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\whereexpr.c -tclsqlite.lo: $(TOP)\src\tclsqlite.c $(HDR) sqlite_tcl.h +tclsqlite.lo: $(TOP)\src\tclsqlite.c $(HDR) $(SQLITE_TCL_DEP) $(LTCOMPILE) $(NO_WARN) -DUSE_TCL_STUBS=1 -DBUILD_sqlite -I$(TCLINCDIR) -c $(TOP)\src\tclsqlite.c -tclsqlite-shell.lo: $(TOP)\src\tclsqlite.c $(HDR) sqlite_tcl.h +tclsqlite-shell.lo: $(TOP)\src\tclsqlite.c $(HDR) $(SQLITE_TCL_DEP) $(LTCOMPILE) $(NO_WARN) -DTCLSH=1 -DBUILD_sqlite -I$(TCLINCDIR) -c $(TOP)\src\tclsqlite.c tclsqlite3.exe: tclsqlite-shell.lo $(SQLITE3C) $(SQLITE3H) $(LIBRESOBJS) @@ -1854,12 +1913,16 @@ parse.c: $(TOP)\src\parse.y lemon.exe $(TOP)\tool\addopcodes.tcl $(TCLSH_CMD) $(TOP)\tool\addopcodes.tcl parse.h.temp > parse.h $(SQLITE3H): $(TOP)\src\sqlite.h.in $(TOP)\manifest.uuid $(TOP)\VERSION - $(TCLSH_CMD) $(TOP)\tool\mksqlite3h.tcl $(TOP:\=/) > $(SQLITE3H) + $(TCLSH_CMD) $(TOP)\tool\mksqlite3h.tcl $(TOP:\=/) > $(SQLITE3H) $(MKSQLITE3H_ARGS) sqlite3ext.h: .target_source +!IF $(USE_STDCALL)!=0 || $(FOR_WIN10)!=0 type tsrc\sqlite3ext.h | $(TCLSH_CMD) $(TOP)\tool\replace.tcl regsub "\(\*\)" "(SQLITE_CALLBACK *)" \ | $(TCLSH_CMD) $(TOP)\tool\replace.tcl regsub "\(\*" "(SQLITE_APICALL *" > sqlite3ext.h copy /Y sqlite3ext.h tsrc\sqlite3ext.h +!ELSE + copy /Y tsrc\sqlite3ext.h sqlite3ext.h +!ENDIF mkkeywordhash.exe: $(TOP)\tool\mkkeywordhash.c $(BCC) $(NO_WARN) -Fe$@ $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS) $(EXT_FEATURE_FLAGS) $(OPTS) \ @@ -2002,25 +2065,27 @@ TESTFIXTURE_SRC = $(TESTSRC) $(TOP)\src\tclsqlite.c $(TESTFIXTURE_SRC0) TESTFIXTURE_SRC = $(TESTSRC) $(TOP)\src\tclsqlite.c $(TESTFIXTURE_SRC1) !ENDIF +!IF $(USE_STDCALL)!=0 || $(FOR_WIN10)!=0 sqlite_tclDecls.h: - echo #ifndef SQLITE_TCLAPI > sqlite_tclDecls.h - echo # define SQLITE_TCLAPI >> sqlite_tclDecls.h - echo #endif >> sqlite_tclDecls.h + echo #ifndef SQLITE_TCLAPI > $(SQLITETCLDECLSH) + echo # define SQLITE_TCLAPI >> $(SQLITETCLDECLSH) + echo #endif >> $(SQLITETCLDECLSH) type "$(TCLINCDIR)\tclDecls.h" \ | $(TCLSH_CMD) $(TOP)\tool\replace.tcl regsub "^(EXTERN(?: CONST\d+?)?\s+?[^\(]*?\s+?)Tcl_" "\1 SQLITE_TCLAPI Tcl_" \ | $(TCLSH_CMD) $(TOP)\tool\replace.tcl regsub "^(EXTERN\s+?(?:void|VOID)\s+?)TclFreeObj" "\1 SQLITE_TCLAPI TclFreeObj" \ | $(TCLSH_CMD) $(TOP)\tool\replace.tcl regsub "\(\*tcl_" "(SQLITE_TCLAPI *tcl_" \ | $(TCLSH_CMD) $(TOP)\tool\replace.tcl regsub "\(\*tclFreeObj" "(SQLITE_TCLAPI *tclFreeObj" \ - | $(TCLSH_CMD) $(TOP)\tool\replace.tcl regsub "\(\*" "(SQLITE_TCLAPI *" >> sqlite_tclDecls.h + | $(TCLSH_CMD) $(TOP)\tool\replace.tcl regsub "\(\*" "(SQLITE_TCLAPI *" >> $(SQLITETCLDECLSH) -sqlite_tcl.h: sqlite_tclDecls.h +sqlite_tcl.h: type "$(TCLINCDIR)\tcl.h" | $(TCLSH_CMD) $(TOP)\tool\replace.tcl exact tclDecls.h sqlite_tclDecls.h \ | $(TCLSH_CMD) $(TOP)\tool\replace.tcl regsub "typedef (.*?)\(Tcl_" "typedef \1 (SQLITE_TCLAPI Tcl_" \ | $(TCLSH_CMD) $(TOP)\tool\replace.tcl exact "void (*freeProc)" "void (SQLITE_TCLAPI *freeProc)" \ | $(TCLSH_CMD) $(TOP)\tool\replace.tcl exact "Tcl_HashEntry *(*findProc)" "Tcl_HashEntry *(SQLITE_TCLAPI *findProc)" \ - | $(TCLSH_CMD) $(TOP)\tool\replace.tcl exact "Tcl_HashEntry *(*createProc)" "Tcl_HashEntry *(SQLITE_TCLAPI *createProc)" >> sqlite_tcl.h + | $(TCLSH_CMD) $(TOP)\tool\replace.tcl exact "Tcl_HashEntry *(*createProc)" "Tcl_HashEntry *(SQLITE_TCLAPI *createProc)" >> $(SQLITETCLH) +!ENDIF -testfixture.exe: $(TESTFIXTURE_SRC) $(SQLITE3H) $(LIBRESOBJS) $(HDR) sqlite_tcl.h +testfixture.exe: $(TESTFIXTURE_SRC) $(SQLITE3H) $(LIBRESOBJS) $(HDR) $(SQLITE_TCL_DEP) $(LTLINK) -DSQLITE_NO_SYNC=1 $(TESTFIXTURE_FLAGS) \ -DBUILD_sqlite -I$(TCLINCDIR) \ $(TESTFIXTURE_SRC) \ @@ -2069,7 +2134,7 @@ smoketest: $(TESTPROGS) @set PATH=$(LIBTCLPATH);$(PATH) .\testfixture.exe $(TOP)\test\main.test $(TESTOPTS) -sqlite3_analyzer.c: $(SQLITE3C) $(SQLITE3H) $(TOP)\src\tclsqlite.c $(TOP)\tool\spaceanal.tcl sqlite_tcl.h +sqlite3_analyzer.c: $(SQLITE3C) $(SQLITE3H) $(TOP)\src\tclsqlite.c $(TOP)\tool\spaceanal.tcl $(SQLITE_TCL_DEP) echo #define TCLSH 2 > $@ echo #define SQLITE_ENABLE_DBSTAT_VTAB 1 >> $@ copy $@ + $(SQLITE3C) + $(TOP)\src\tclsqlite.c $@ @@ -2149,7 +2214,7 @@ clean: -rmdir /Q/S .libs 2>NUL -rmdir /Q/S tsrc 2>NUL del /Q .target_source 2>NUL - del /Q tclsqlite3.exe sqlite_tcl.h sqlite_tclDecls.h 2>NUL + del /Q tclsqlite3.exe $(SQLITETCLH) $(SQLITETCLDECLSH) 2>NUL del /Q testloadext.dll 2>NUL del /Q testfixture.exe test.db 2>NUL del /Q LogEst.exe fts3view.exe rollback-test.exe showdb.exe 2>NUL diff --git a/manifest b/manifest index 31ab0fb601..e72fee2001 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -C Merge\supdates\sfrom\strunk. -D 2016-08-24T18:49:20.476 +C Modularize\sall\suse\sof\sthe\scalling\sconvention\smacros\sbased\son\sthe\sUSE_STDCALL\snmake\smacro. +D 2016-08-24T19:58:46.902 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 -F Makefile.msc 3340e479e5221f06c3d61726f8f7efff885e4233 +F Makefile.msc 2a8f135e10f383a31f1106cf42edabf3a18a3d08 F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7 F VERSION 25e2e333adeff5965520bc8db999c658898c972d F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 @@ -1451,9 +1451,9 @@ F tool/mkopcodeh.tcl a01d2c1d8a6205b03fc635adf3735b4c523befd3 F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e F tool/mkpragmatab.tcl f0d5bb266d1d388cf86fce5ba01a891e95d72d41 F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 -F tool/mksqlite3c-noext.tcl aa58ea3be311c81821c2cd3209f55e46b07ab656 -F tool/mksqlite3c.tcl a52ead27e2ac5d4b616e945a0601f628f4328329 -F tool/mksqlite3h.tcl cf5cd68028e69a51ed5c76042672664201f0f756 +F tool/mksqlite3c-noext.tcl e241889b12b7f857bc7c361776ef113d826e0c28 +F tool/mksqlite3c.tcl b076d24348a84dffd41aab01bc4e19a1ba17581a +F tool/mksqlite3h.tcl 22fa51b3dc04bef7cc55546c94b8b05478e081f8 F tool/mksqlite3internalh.tcl eb994013e833359137eb53a55acdad0b5ae1049b F tool/mkvsix.tcl 4abcaf3267171b2faadaf9b82a0dfbaa6e98f8b7 F tool/offsets.c fe4262fdfa378e8f5499a42136d17bf3b98f6091 @@ -1511,7 +1511,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 71ffa195f5a48280ee522d80ab82e8cdea636961 77f7c31a3aa44798cfa5f557242caffb593ce7af -R 6639d7ca813b34dc442dce0c70a8d49a +P 428fc38d95dd88b90655a97133d0ad1214c9f176 +R 8fcf2f6bc8929252e1f73eaeed6c2ff1 U mistachkin -Z fc90dd7d8c306741e4a70346c0bad323 +Z 8acb335e007f8a860d6f64c92d2219b8 diff --git a/manifest.uuid b/manifest.uuid index bce9ac3fde..60aed0f8b1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -428fc38d95dd88b90655a97133d0ad1214c9f176 \ No newline at end of file +e4a56197b08546601bd6a623f667b43f50d603be \ No newline at end of file diff --git a/tool/mksqlite3c-noext.tcl b/tool/mksqlite3c-noext.tcl index fad6c9e584..a55e93ff16 100644 --- a/tool/mksqlite3c-noext.tcl +++ b/tool/mksqlite3c-noext.tcl @@ -1,7 +1,7 @@ #!/usr/bin/tclsh # # To build a single huge source file holding all of SQLite (or at -# least the core components - the test harness, shell, and TCL +# least the core components - the test harness, shell, and TCL # interface are omitted.) first do # # make target_source @@ -11,7 +11,7 @@ # there and will not work if they are not found.) There are a few # generated C code files that are also added to the tsrc directory. # For example, the "parse.c" and "parse.h" files to implement the -# the parser are derived from "parse.y" using lemon. And the +# the parser are derived from "parse.y" using lemon. And the # "keywordhash.h" files is generated by a program named "mkkeywordhash". # # After the "tsrc" directory has been created and populated, run @@ -26,15 +26,20 @@ # from in this file. The version number is needed to generate the header # comment of the amalgamation. # -if {[lsearch $argv --nostatic]>=0} { - set addstatic 0 -} else { - set addstatic 1 -} -if {[lsearch $argv --linemacros]>=0} { - set linemacros 1 -} else { - set linemacros 0 +set addstatic 1 +set linemacros 0 +set useapicall 0 +for {set i 0} {$i<[llength $argv]} {incr i} { + set x [lindex $argv $i] + if {[regexp {^-+nostatic$} $x]} { + set addstatic 0 + } elseif {[regexp {^-+linemacros} $x]} { + set linemacros 1 + } elseif {[regexp {^-+useapicall} $x]} { + set useapicall 1 + } else { + error "unknown command-line option: $x" + } } set in [open tsrc/sqlite3.h] set cnt 0 @@ -57,7 +62,7 @@ set today [clock format [clock seconds] -format "%Y-%m-%d %H:%M:%S UTC" -gmt 1] puts $out [subst \ {/****************************************************************************** ** This file is an amalgamation of many separate C source files from SQLite -** version $VERSION. By combining all the individual C code files into this +** version $VERSION. By combining all the individual C code files into this ** single large file, the entire code can be compiled as a single translation ** unit. This allows many compilers to do optimizations that would not be ** possible if the files were compiled separately. Performance improvements @@ -66,7 +71,7 @@ puts $out [subst \ ** ** This file is all you need to compile SQLite. To use SQLite in other ** programs, you need this file and the "sqlite3.h" header file that defines -** the programming interface to the SQLite library. (If you do not have +** the programming interface to the SQLite library. (If you do not have ** the "sqlite3.h" header file at hand, you will find a copy embedded within ** the text of this file. Search for "Begin file sqlite3.h" to find the start ** of the embedded sqlite3.h header file.) Additional code files may be needed @@ -83,7 +88,7 @@ if {$addstatic} { #endif} } -# These are the header files used by SQLite. The first time any of these +# These are the header files used by SQLite. The first time any of these # files are seen in a #include statement in the C code, include the complete # text of the file in-line. The file only needs to be included once. # @@ -104,8 +109,8 @@ foreach hdr { parse.h pcache.h pragma.h - sqlite3ext.h sqlite3.h + sqlite3ext.h sqliteicu.h sqliteInt.h sqliteLimit.h @@ -155,7 +160,8 @@ proc section_comment {text} { # process them appropriately. # proc copy_file {filename} { - global seen_hdr available_hdr varonly_hdr cdecllist out addstatic linemacros + global seen_hdr available_hdr varonly_hdr cdecllist out + global addstatic linemacros useapicall set ln 0 set tail [file tail $filename] section_comment "Begin file $tail" @@ -203,7 +209,8 @@ proc copy_file {filename} { puts $out "#if 0" } elseif {!$linemacros && [regexp {^#line} $line]} { # Skip #line directives. - } elseif {$addstatic && ![regexp {^(static|typedef)} $line]} { + } elseif {$addstatic + && ![regexp {^(static|typedef|SQLITE_PRIVATE)} $line]} { # Skip adding the SQLITE_PRIVATE or SQLITE_API keyword before # functions if this header file does not need it. if {![info exists varonly_hdr($tail)] @@ -211,16 +218,18 @@ proc copy_file {filename} { regsub {^SQLITE_API } $line {} line # Add the SQLITE_PRIVATE or SQLITE_API keyword before functions. # so that linkage can be modified at compile-time. - if {[regexp {^sqlite3_} $funcname]} { + if {[regexp {^sqlite3[a-z]*_} $funcname]} { set line SQLITE_API append line " " [string trim $rettype] if {[string index $rettype end] ne "*"} { append line " " } - if {[lsearch -exact $cdecllist $funcname] >= 0} { - append line SQLITE_CDECL - } else { - append line SQLITE_APICALL + if {$useapicall} { + if {[lsearch -exact $cdecllist $funcname] >= 0} { + append line SQLITE_CDECL + } else { + append line SQLITE_APICALL + } } append line " " $funcname $rest puts $out $line @@ -285,6 +294,7 @@ foreach file { mutex_w32.c malloc.c printf.c + treeview.c random.c threads.c utf.c @@ -313,7 +323,6 @@ foreach file { vdbe.c vdbeblob.c vdbesort.c - journal.c memjournal.c walker.c @@ -339,6 +348,8 @@ foreach file { update.c vacuum.c vtab.c + wherecode.c + whereexpr.c where.c parse.c diff --git a/tool/mksqlite3c.tcl b/tool/mksqlite3c.tcl index b7561cfa5b..9938ed14e4 100644 --- a/tool/mksqlite3c.tcl +++ b/tool/mksqlite3c.tcl @@ -1,7 +1,7 @@ #!/usr/bin/tclsh # # To build a single huge source file holding all of SQLite (or at -# least the core components - the test harness, shell, and TCL +# least the core components - the test harness, shell, and TCL # interface are omitted.) first do # # make target_source @@ -11,7 +11,7 @@ # there and will not work if they are not found.) There are a few # generated C code files that are also added to the tsrc directory. # For example, the "parse.c" and "parse.h" files to implement the -# the parser are derived from "parse.y" using lemon. And the +# the parser are derived from "parse.y" using lemon. And the # "keywordhash.h" files is generated by a program named "mkkeywordhash". # # After the "tsrc" directory has been created and populated, run @@ -28,12 +28,15 @@ # set addstatic 1 set linemacros 0 +set useapicall 0 for {set i 0} {$i<[llength $argv]} {incr i} { set x [lindex $argv $i] if {[regexp {^-+nostatic$} $x]} { set addstatic 0 } elseif {[regexp {^-+linemacros} $x]} { set linemacros 1 + } elseif {[regexp {^-+useapicall} $x]} { + set useapicall 1 } else { error "unknown command-line option: $x" } @@ -59,7 +62,7 @@ set today [clock format [clock seconds] -format "%Y-%m-%d %H:%M:%S UTC" -gmt 1] puts $out [subst \ {/****************************************************************************** ** This file is an amalgamation of many separate C source files from SQLite -** version $VERSION. By combining all the individual C code files into this +** version $VERSION. By combining all the individual C code files into this ** single large file, the entire code can be compiled as a single translation ** unit. This allows many compilers to do optimizations that would not be ** possible if the files were compiled separately. Performance improvements @@ -68,7 +71,7 @@ puts $out [subst \ ** ** This file is all you need to compile SQLite. To use SQLite in other ** programs, you need this file and the "sqlite3.h" header file that defines -** the programming interface to the SQLite library. (If you do not have +** the programming interface to the SQLite library. (If you do not have ** the "sqlite3.h" header file at hand, you will find a copy embedded within ** the text of this file. Search for "Begin file sqlite3.h" to find the start ** of the embedded sqlite3.h header file.) Additional code files may be needed @@ -85,7 +88,7 @@ if {$addstatic} { #endif} } -# These are the header files used by SQLite. The first time any of these +# These are the header files used by SQLite. The first time any of these # files are seen in a #include statement in the C code, include the complete # text of the file in-line. The file only needs to be included once. # @@ -112,7 +115,6 @@ foreach hdr { pragma.h rtree.h sqlite3session.h - sqlite3ext.h sqlite3.h sqlite3ext.h sqlite3rbu.h @@ -166,7 +168,8 @@ proc section_comment {text} { # process them appropriately. # proc copy_file {filename} { - global seen_hdr available_hdr varonly_hdr cdecllist out addstatic linemacros + global seen_hdr available_hdr varonly_hdr cdecllist out + global addstatic linemacros useapicall set ln 0 set tail [file tail $filename] section_comment "Begin file $tail" @@ -229,10 +232,12 @@ proc copy_file {filename} { if {[string index $rettype end] ne "*"} { append line " " } - if {[lsearch -exact $cdecllist $funcname] >= 0} { - append line SQLITE_CDECL - } else { - append line SQLITE_APICALL + if {$useapicall} { + if {[lsearch -exact $cdecllist $funcname] >= 0} { + append line SQLITE_CDECL + } else { + append line SQLITE_APICALL + } } append line " " $funcname $rest puts $out $line diff --git a/tool/mksqlite3h.tcl b/tool/mksqlite3h.tcl index 9a4e7d2985..c620eb630d 100644 --- a/tool/mksqlite3h.tcl +++ b/tool/mksqlite3h.tcl @@ -10,16 +10,16 @@ # # Run this script by specifying the root directory of the source tree # on the command-line. -# +# # This script performs processing on src/sqlite.h.in. It: # # 1) Adds SQLITE_EXTERN in front of the declaration of global variables, # 2) Adds SQLITE_API in front of the declaration of API functions, -# 3) Replaces the string --VERS-- with the current library version, +# 3) Replaces the string --VERS-- with the current library version, # formatted as a string (e.g. "3.6.17"), and # 4) Replaces the string --VERSION-NUMBER-- with current library version, # formatted as an integer (e.g. "3006017"). -# 5) Replaces the string --SOURCE-ID-- with the date and time and sha1 +# 5) Replaces the string --SOURCE-ID-- with the date and time and sha1 # hash of the fossil-scm manifest for the source tree. # 6) Adds the SQLITE_CALLBACK calling convention macro in front of all # callback declarations. @@ -36,6 +36,14 @@ # set TOP [lindex $argv 0] +# Enable use of SQLITE_APICALL macros at the right points? +# +set useapicall 0 + +if {[lsearch -regexp [lrange $argv 1 end] {^-+useapicall}] != -1} { + set useapicall 1 +} + # Get the SQLite version number (ex: 3.6.18) from the $TOP/VERSION file. # set in [open $TOP/VERSION] @@ -98,14 +106,14 @@ foreach file $filelist { puts "/******** Begin file [file tail $file] *********/" } while {![eof $in]} { - + set line [gets $in] # File sqlite3rtree.h contains a line "#include ". Omit this # line when copying sqlite3rtree.h into sqlite3.h. # if {[string match {*#include*[<"]sqlite3.h[>"]*} $line]} continue - + regsub -- --VERS-- $line $zVersion line regsub -- --VERSION-NUMBER-- $line $nVersion line regsub -- --SOURCE-ID-- $line "$zDate $zUuid" line @@ -119,17 +127,21 @@ foreach file $filelist { if {[string index $rettype end] ne "*"} { append line " " } - if {[lsearch -exact $cdecllist $funcname] >= 0} { - append line SQLITE_CDECL - } else { - append line SQLITE_APICALL + if {$useapicall} { + if {[lsearch -exact $cdecllist $funcname] >= 0} { + append line SQLITE_CDECL + } else { + append line SQLITE_APICALL + } } append line " " $funcname $rest } } - set line [string map [list (*sqlite3_syscall_ptr) \ - "(SQLITE_SYSAPI *sqlite3_syscall_ptr)"] $line] - regsub {\(\*} $line {(SQLITE_CALLBACK *} line + if {$useapicall} { + set line [string map [list (*sqlite3_syscall_ptr) \ + "(SQLITE_SYSAPI *sqlite3_syscall_ptr)"] $line] + regsub {\(\*} $line {(SQLITE_CALLBACK *} line + } puts $line } close $in From 72e26dec860e739ba6be30fcfb438dd0c7fa878e Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 24 Aug 2016 21:24:04 +0000 Subject: [PATCH 0749/1484] Improved extended comments of comparison operators when the SQLITE_STOREP2 flags is set on P5. No changes to non-debug code. FossilOrigin-Name: bbc1b016164ed0793e07302614384d52119463e0 --- manifest | 14 ++++++------- manifest.uuid | 2 +- src/vdbe.c | 58 +++++++++++++++++++++++++-------------------------- src/vdbeaux.c | 9 ++++++++ 4 files changed, 46 insertions(+), 37 deletions(-) diff --git a/manifest b/manifest index daccb4786d..f6f42159d3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\ssqlite3FindInIndex(),\simprove\sinternal\scomments\sand\savoid\san\nunreachable\sbranch. -D 2016-08-24T18:51:23.484 +C Improved\sextended\scomments\sof\scomparison\soperators\swhen\sthe\sSQLITE_STOREP2\nflags\sis\sset\son\sP5.\s\sNo\schanges\sto\snon-debug\scode. +D 2016-08-24T21:24:04.787 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -450,11 +450,11 @@ F src/update.c 8179e699dbd45b92934fd02d3d8e3732e8da8802 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 810ec3f22e2d1b62e66c30fe3621ebdedd23584d F src/vacuum.c 913970b9d86dd6c2b8063ef1af421880f1464ec3 -F src/vdbe.c 766d363ef6520c671eef165098a24c0c6ef36d89 +F src/vdbe.c 68d56c11d5c5e704dde6d2d8748750a2f6352a09 F src/vdbe.h 67bc551f7faf04c33493892e4b378aada823ed10 F src/vdbeInt.h c59381049af5c7751a83456c39b80d1a6fde1f9d F src/vdbeapi.c a32d61b7dd05e6890d8fd44d2805f55e2f5ba9f3 -F src/vdbeaux.c a32d79aeaa88dc2b97c261172d952d395254a055 +F src/vdbeaux.c 83458783d241cfd6691141c8a105832ee50258e5 F src/vdbeblob.c 3e82a797b60c3b9fed7b8de8c539ca7607874937 F src/vdbemem.c e67dc6d8177fd1830efb5d15e17793408251a187 F src/vdbesort.c 91fda3909326860382b0ca8aa251e609c6a9d62c @@ -1520,7 +1520,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 6099c180db55396d6307538a5428ae5ef1b82d10 -R fa8e14e08c5acfaa4521c63ce095c576 +P 55945fc12f8157e32e6850e41575c0c6422d29e7 +R d8287dc165c2512db536a01f0275f112 U drh -Z 500a8a58193db1f42f4b49dd37f14aa8 +Z f51d93eb7238381398d31778d751851b diff --git a/manifest.uuid b/manifest.uuid index 879b23070a..dc4716aac1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -55945fc12f8157e32e6850e41575c0c6422d29e7 \ No newline at end of file +bbc1b016164ed0793e07302614384d52119463e0 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 4477f6dfb9..24828ace3b 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -905,7 +905,7 @@ case OP_Yield: { /* in1, jump */ } /* Opcode: HaltIfNull P1 P2 P3 P4 P5 -** Synopsis: if r[P3]=null halt +** Synopsis: if r[P3]=null halt ** ** Check the value in register P3. If it is NULL then Halt using ** parameter P1, P2, and P4 as if this were a Halt instruction. If the @@ -1118,7 +1118,7 @@ case OP_String: { /* out2 */ } /* Opcode: Null P1 P2 P3 * * -** Synopsis: r[P2..P3]=NULL +** Synopsis: r[P2..P3]=NULL ** ** Write a NULL into registers P2. If P3 greater than P2, then also write ** NULL into register P3 and every register in between P2 and P3. If P3 @@ -1147,7 +1147,7 @@ case OP_Null: { /* out2 */ } /* Opcode: SoftNull P1 * * * * -** Synopsis: r[P1]=NULL +** Synopsis: r[P1]=NULL ** ** Set register P1 to have the value NULL as seen by the OP_MakeRecord ** instruction, but do not free any string or blob memory associated with @@ -1200,7 +1200,7 @@ case OP_Variable: { /* out2 */ } /* Opcode: Move P1 P2 P3 * * -** Synopsis: r[P2@P3]=r[P1@P3] +** Synopsis: r[P2@P3]=r[P1@P3] ** ** Move the P3 values in register P1..P1+P3-1 over into ** registers P2..P2+P3-1. Registers P1..P1+P3-1 are @@ -1310,7 +1310,7 @@ case OP_IntCopy: { /* out2 */ } /* Opcode: ResultRow P1 P2 * * * -** Synopsis: output=r[P1@P2] +** Synopsis: output=r[P1@P2] ** ** The registers P1 through P1+P2-1 contain a single row of ** results. This opcode causes the sqlite3_step() call to terminate @@ -1443,14 +1443,14 @@ case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */ } /* Opcode: Add P1 P2 P3 * * -** Synopsis: r[P3]=r[P1]+r[P2] +** Synopsis: r[P3]=r[P1]+r[P2] ** ** Add the value in register P1 to the value in register P2 ** and store the result in register P3. ** If either input is NULL, the result is NULL. */ /* Opcode: Multiply P1 P2 P3 * * -** Synopsis: r[P3]=r[P1]*r[P2] +** Synopsis: r[P3]=r[P1]*r[P2] ** ** ** Multiply the value in register P1 by the value in register P2 @@ -1458,14 +1458,14 @@ case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */ ** If either input is NULL, the result is NULL. */ /* Opcode: Subtract P1 P2 P3 * * -** Synopsis: r[P3]=r[P2]-r[P1] +** Synopsis: r[P3]=r[P2]-r[P1] ** ** Subtract the value in register P1 from the value in register P2 ** and store the result in register P3. ** If either input is NULL, the result is NULL. */ /* Opcode: Divide P1 P2 P3 * * -** Synopsis: r[P3]=r[P2]/r[P1] +** Synopsis: r[P3]=r[P2]/r[P1] ** ** Divide the value in register P1 by the value in register P2 ** and store the result in register P3 (P3=P2/P1). If the value in @@ -1473,7 +1473,7 @@ case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */ ** NULL, the result is NULL. */ /* Opcode: Remainder P1 P2 P3 * * -** Synopsis: r[P3]=r[P2]%r[P1] +** Synopsis: r[P3]=r[P2]%r[P1] ** ** Compute the remainder after integer register P2 is divided by ** register P1 and store the result in register P3. @@ -1706,21 +1706,21 @@ case OP_Function: { } /* Opcode: BitAnd P1 P2 P3 * * -** Synopsis: r[P3]=r[P1]&r[P2] +** Synopsis: r[P3]=r[P1]&r[P2] ** ** Take the bit-wise AND of the values in register P1 and P2 and ** store the result in register P3. ** If either input is NULL, the result is NULL. */ /* Opcode: BitOr P1 P2 P3 * * -** Synopsis: r[P3]=r[P1]|r[P2] +** Synopsis: r[P3]=r[P1]|r[P2] ** ** Take the bit-wise OR of the values in register P1 and P2 and ** store the result in register P3. ** If either input is NULL, the result is NULL. */ /* Opcode: ShiftLeft P1 P2 P3 * * -** Synopsis: r[P3]=r[P2]<>r[P1] +** Synopsis: r[P3]=r[P2]>>r[P1] ** ** Shift the integer value in register P2 to the right by the ** number of bits specified by the integer in register P1. @@ -1788,7 +1788,7 @@ case OP_ShiftRight: { /* same as TK_RSHIFT, in1, in2, out3 */ } /* Opcode: AddImm P1 P2 * * * -** Synopsis: r[P1]=r[P1]+P2 +** Synopsis: r[P1]=r[P1]+P2 ** ** Add the constant P2 to the value in register P1. ** The result is always an integer. @@ -1881,7 +1881,7 @@ case OP_Cast: { /* in1 */ #endif /* SQLITE_OMIT_CAST */ /* Opcode: Eq P1 P2 P3 P4 P5 -** Synopsis: if r[P1]==r[P3] goto P2 +** Synopsis: IF r[P1]==r[P3] ** ** Compare the values in register P1 and P3. If reg(P3)==reg(P1) then ** jump to address P2. Or if the SQLITE_STOREP2 flag is set in P5, then @@ -1915,7 +1915,7 @@ case OP_Cast: { /* in1 */ ** content of r[P2] is only set to 1 (true) if it was not previously NULL. */ /* Opcode: Ne P1 P2 P3 P4 P5 -** Synopsis: if r[P1]!=r[P3] goto P2 +** Synopsis: IF r[P1]!=r[P3] ** ** This works just like the Eq opcode except that the jump is taken if ** the operands in registers P1 and P3 are not equal. See the Eq opcode for @@ -1925,7 +1925,7 @@ case OP_Cast: { /* in1 */ ** content of r[P2] is only set to 0 (false) if it was not previously NULL. */ /* Opcode: Lt P1 P2 P3 P4 P5 -** Synopsis: if r[P1]r[P3] goto P2 +** Synopsis: IF r[P1]>r[P3] ** ** This works just like the Lt opcode except that the jump is taken if ** the content of register P3 is greater than the content of ** register P1. See the Lt opcode for additional information. */ /* Opcode: Ge P1 P2 P3 P4 P5 -** Synopsis: if r[P1]>=r[P3] goto P2 +** Synopsis: IF r[P1]>=r[P3] ** ** This works just like the Lt opcode except that the jump is taken if ** the content of register P3 is greater than or equal to the content of @@ -2370,7 +2370,7 @@ case OP_IfNot: { /* jump, in1 */ } /* Opcode: IsNull P1 P2 * * * -** Synopsis: if r[P1]==NULL goto P2 +** Synopsis: if r[P1]==NULL goto P2 ** ** Jump to P2 if the value in register P1 is NULL. */ @@ -2398,7 +2398,7 @@ case OP_NotNull: { /* same as TK_NOTNULL, jump, in1 */ } /* Opcode: Column P1 P2 P3 P4 P5 -** Synopsis: r[P3]=PX +** Synopsis: r[P3]=PX ** ** Interpret the data that cursor P1 points to as a structure built using ** the MakeRecord instruction. (See the MakeRecord opcode for additional @@ -4340,7 +4340,7 @@ case OP_NewRowid: { /* out2 */ ** for indices is OP_IdxInsert. */ /* Opcode: InsertInt P1 P2 P3 P4 P5 -** Synopsis: intkey=P3 data=r[P2] +** Synopsis: intkey=P3 data=r[P2] ** ** This works exactly like OP_Insert except that the key is the ** integer value P3, not the value of the integer stored in register P3. @@ -4571,7 +4571,7 @@ case OP_ResetCount: { } /* Opcode: SorterCompare P1 P2 P3 P4 -** Synopsis: if key(P1)!=trim(r[P3],P4) goto P2 +** Synopsis: if key(P1)!=trim(r[P3],P4) goto P2 ** ** P1 is a sorter cursor. This instruction compares a prefix of the ** record blob in register P3 against a prefix of the entry that @@ -5098,7 +5098,7 @@ case OP_IdxDelete: { } /* Opcode: Seek P1 * P3 P4 * -** Synopsis: Move P3 to P1.rowid +** Synopsis: Move P3 to P1.rowid ** ** P1 is an open index cursor and P3 is a cursor on the corresponding ** table. This opcode does a deferred seek of the P3 table cursor @@ -5605,7 +5605,7 @@ case OP_IntegrityCk: { #endif /* SQLITE_OMIT_INTEGRITY_CHECK */ /* Opcode: RowSetAdd P1 P2 * * * -** Synopsis: rowset(P1)=r[P2] +** Synopsis: rowset(P1)=r[P2] ** ** Insert the integer value held by register P2 into a boolean index ** held in register P1. @@ -5625,7 +5625,7 @@ case OP_RowSetAdd: { /* in1, in2 */ } /* Opcode: RowSetRead P1 P2 P3 * * -** Synopsis: r[P3]=rowset(P1) +** Synopsis: r[P3]=rowset(P1) ** ** Extract the smallest value from boolean index P1 and put that value into ** register P3. Or, if boolean index P1 is initially empty, leave P3 @@ -6804,7 +6804,7 @@ case OP_MaxPgcnt: { /* out2 */ /* Opcode: Init * P2 * P4 * -** Synopsis: Start at P2 +** Synopsis: Start at P2 ** ** Programs contain a single instance of this opcode as the very first ** opcode. diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 992fa4db9e..963833cce5 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -1094,12 +1094,21 @@ static int displayComment( const char *zSynopsis; int nOpName; int ii, jj; + char zAlt[50]; zOpName = sqlite3OpcodeName(pOp->opcode); nOpName = sqlite3Strlen30(zOpName); if( zOpName[nOpName+1] ){ int seenCom = 0; char c; zSynopsis = zOpName += nOpName + 1; + if( strncmp(zSynopsis,"IF ",3)==0 ){ + if( pOp->p5 & SQLITE_STOREP2 ){ + sqlite3_snprintf(sizeof(zAlt), zAlt, "r[P2] = (%s)", zSynopsis+3); + }else{ + sqlite3_snprintf(sizeof(zAlt), zAlt, "if %s goto P2", zSynopsis+3); + } + zSynopsis = zAlt; + } for(ii=jj=0; jj Date: Wed, 24 Aug 2016 21:54:47 +0000 Subject: [PATCH 0750/1484] Simplified VDBE code for the vector NOT IN null-scanning loop. FossilOrigin-Name: 7ae504e62e9bbbbd85a676f3c3922b7fd0cc73d2 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/expr.c | 22 ++++++++++++---------- 3 files changed, 19 insertions(+), 17 deletions(-) diff --git a/manifest b/manifest index f6f42159d3..105c9bfbb2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improved\sextended\scomments\sof\scomparison\soperators\swhen\sthe\sSQLITE_STOREP2\nflags\sis\sset\son\sP5.\s\sNo\schanges\sto\snon-debug\scode. -D 2016-08-24T21:24:04.787 +C Simplified\sVDBE\scode\sfor\sthe\svector\sNOT\sIN\snull-scanning\sloop. +D 2016-08-24T21:54:47.055 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -338,7 +338,7 @@ F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7 F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c 76c084f0265f4a3cd1ecf17eee112a94f1ccbc05 -F src/expr.c 3dc226ccd9eebee600253eba07b8d97534e49337 +F src/expr.c 866bcb6e85806beb0f96e651e9d17811e1ecbda5 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c e2be0968c1adc679c87e467aa5b4f167588f38a8 F src/func.c 29cc9acb170ec1387b9f63eb52cd85f8de96c771 @@ -1520,7 +1520,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 55945fc12f8157e32e6850e41575c0c6422d29e7 -R d8287dc165c2512db536a01f0275f112 +P bbc1b016164ed0793e07302614384d52119463e0 +R 5a565b60b3cfcc2e549e66fdc0e5eedc U drh -Z f51d93eb7238381398d31778d751851b +Z 08a1319918b046fa6beb913b7de3f092 diff --git a/manifest.uuid b/manifest.uuid index dc4716aac1..0459a673e1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bbc1b016164ed0793e07302614384d52119463e0 \ No newline at end of file +7ae504e62e9bbbbd85a676f3c3922b7fd0cc73d2 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 63958b0d25..16f74d785e 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2782,18 +2782,20 @@ static void sqlite3ExprCodeIN( if( nVector>1 && destIfNull!=destIfFalse ){ int iIdx = pExpr->iTable; - int addr; + int addrTop; int addrNext; + int addrFound; /* Search the index for the key. */ - addr = sqlite3VdbeAddOp4Int(v, OP_Found, iIdx, 0, r1, nVector); + addrFound = sqlite3VdbeAddOp4Int(v, OP_Found, iIdx, 0, r1, nVector); VdbeCoverage(v); /* At this point the specified key is not present in the index, ** so the result of the IN(..) operator must be either NULL or ** 0. The vdbe code generated below figures out which. */ - addrNext = 1+sqlite3VdbeAddOp2(v, OP_Rewind, iIdx, destIfFalse); + addrTop = 1+sqlite3VdbeAddOp2(v, OP_Rewind, iIdx, destIfFalse); VdbeCoverage(v); + addrNext = sqlite3VdbeMakeLabel(v); for(i=0; ipLeft, i); if( sqlite3ExprCanBeNull(p) ){ From 539f2fef03004a11476235a942615fb49f1ce48a Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 25 Aug 2016 14:00:15 +0000 Subject: [PATCH 0751/1484] Add notes on the implementation of the IN operator. FossilOrigin-Name: d256b2caeb9e3eb5dd88bb569ec71f91e9991c81 --- manifest | 11 ++--- manifest.uuid | 2 +- src/in-operator.md | 105 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 112 insertions(+), 6 deletions(-) create mode 100644 src/in-operator.md diff --git a/manifest b/manifest index 105c9bfbb2..b69115a5fc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Simplified\sVDBE\scode\sfor\sthe\svector\sNOT\sIN\snull-scanning\sloop. -D 2016-08-24T21:54:47.055 +C Add\snotes\son\sthe\simplementation\sof\sthe\sIN\soperator. +D 2016-08-25T14:00:15.437 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -346,6 +346,7 @@ F src/global.c c45ea22aff29334f6a9ec549235ac3357c970015 F src/hash.c 55b5fb474100cee0b901edaf203e26c970940f36 F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4 F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da +F src/in-operator.md 8176075ceca5b1a0564d4aff1e415ff6f9037280 F src/insert.c a255eb795cf475e7a0659297144fc80f70eb4e30 F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e F src/loadext.c dd7a2b77902cc66c22555aef02e1a682554b7aec @@ -1520,7 +1521,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P bbc1b016164ed0793e07302614384d52119463e0 -R 5a565b60b3cfcc2e549e66fdc0e5eedc +P 7ae504e62e9bbbbd85a676f3c3922b7fd0cc73d2 +R 85a14e909442e83b4fd5e48b00047186 U drh -Z 08a1319918b046fa6beb913b7de3f092 +Z fb24d479cf53b7630adc4dea69c62760 diff --git a/manifest.uuid b/manifest.uuid index 0459a673e1..0fc9cd5be3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7ae504e62e9bbbbd85a676f3c3922b7fd0cc73d2 \ No newline at end of file +d256b2caeb9e3eb5dd88bb569ec71f91e9991c81 \ No newline at end of file diff --git a/src/in-operator.md b/src/in-operator.md new file mode 100644 index 0000000000..76002b8597 --- /dev/null +++ b/src/in-operator.md @@ -0,0 +1,105 @@ +IN-Operator Implementation Notes +================================ + +## Definitions: + +An IN operator has one of the following formats: + +> + x IN (list) + x IN (subquery) + +The "x" is referred to as the LHS (left-hand side). The list or subquery +on the right is called the RHS (right-hand side). If the RHS is a list +it must be a non-empty list. But if the RHS is a subquery, it can be an +empty set. + +Both the LHS and RHS can be scalars or vectors. The two must match. +In other words, they must both be scalar or else they must both be +vectors of the same length. + +NULL values can occur in either or both of the LHS and RHS. +If the LHS contains only +NULL values then we say that it is a "total-NULL". If the LHS contains +some NULL values and some non-NULL values, then it is a "partial-NULL". +For a scalar, there is no difference between a partial-NULL and a total-NULL. +The RHS is a partial-NULL if any row contains a NULL value. The RHS is +a total-NULL if it contains one or more rows that contain only NULL values. +The LHS is called "non-NULL" if it contains no NULL values. The RHS is +called "non-NULL" if it contains no NULL values in any row. + +The result of an IN operator is one of TRUE, FALSE, or NULL. A NULL result +means that it cannot be determined if the LHS is contained in the RHS due +to the presence of NULL values. In some contexts (for example, when the IN +operator occurs in a WHERE clause) +the system only needs a binary result: TRUE or NOT-TRUE. One can also +to define a binary result of FALSE and NOT-FALSE, but +it turns out that no extra optimizations are possible in that case, so if +the FALSE/NOT-FALSE binary is needed, we have to compute the three-state +TRUE/FALSE/NULL result and then combine the TRUE and NULL values into +NOT-FALSE. + +A "NOT IN" operator is computed by first computing the equivalent IN +operator, then interchanging the TRUE and FALSE results. + +## Simple Full-Scan Algorithm + +The following algorithm always compute the correct answer. However, this +algorithm is suboptimal, especially if there are many rows on the RHS. + + 1. Set the null-flag to false + 2. For each row in the RHS: +
      +
    1. Compare the LHS against the RHS +
    2. If the LHS exactly matches the RHS, immediately return TRUE +
    3. If the comparison result is NULL, set the null-flag to true +
    + 3. If the null-flag is true, return NULL. + 4. Return FALSE + +## Optimized Algorithm + +The following procedure computes the same answer as the simple full-scan +algorithm, though it does so with less work in the common case. This +is the algorithm that is implemented in SQLite. The steps must occur +in the order specified. Except for the INDEX_NOOP optimization of step 1, +none of the steps can be skipped. + + 1. If the RHS is a constant list of length 1 or 2, then rewrite the + IN operator as a simple expression. Implement + + x IN (y1,y2) + + as if it were + + x=y1 OR x=y2 + + This is the INDEX_NOOP optimization and is only undertaken if the + IN operator is used for membership testing. If the IN operator is + driving a loop, then skip this step entirely. + + 2. If the RHS is empty, return FALSE. + + 3. If the LHS is a total-NULL or if the RHS contains a total-NULL, + then return NULL. + + 4. If the LHS is non-NULL, then use the LHS as a probe in a binary + search of the RHS + +
      +
    1. If the binary search finds an exact match, return TRUE + +
    2. If the RHS is known to be not-null, return FALSE +
    + + 5. At this point, it is known that the result cannot be TRUE. All + that remains is to distinguish between NULL and FALSE. + If a NOT-TRUE result is acceptable, then return NOT-TRUE now. + + 6. For each row in the RHS, compare that row against the LHS and + if the result is NULL, immediately return NULL. This step is + essentially the "Simple Full-scan Algorithm" above with the + tests for TRUE removed, since we know that the result cannot be + TRUE at this point. + + 7. Return FALSE. From ee0f22fd3b273a852f5ed32f0f624f369845e6fa Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 25 Aug 2016 14:23:59 +0000 Subject: [PATCH 0752/1484] Corrections to the IN-operator notes. FossilOrigin-Name: 25033ee94538289ba7e0147da30a18300047123f --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/in-operator.md | 13 +++++-------- 3 files changed, 12 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index b69115a5fc..2c01a256ff 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\snotes\son\sthe\simplementation\sof\sthe\sIN\soperator. -D 2016-08-25T14:00:15.437 +C Corrections\sto\sthe\sIN-operator\snotes. +D 2016-08-25T14:23:59.673 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -346,7 +346,7 @@ F src/global.c c45ea22aff29334f6a9ec549235ac3357c970015 F src/hash.c 55b5fb474100cee0b901edaf203e26c970940f36 F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4 F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da -F src/in-operator.md 8176075ceca5b1a0564d4aff1e415ff6f9037280 +F src/in-operator.md 973fe4522b871fb8cf683d8453760f4f19ac68c8 F src/insert.c a255eb795cf475e7a0659297144fc80f70eb4e30 F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e F src/loadext.c dd7a2b77902cc66c22555aef02e1a682554b7aec @@ -1521,7 +1521,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 7ae504e62e9bbbbd85a676f3c3922b7fd0cc73d2 -R 85a14e909442e83b4fd5e48b00047186 +P d256b2caeb9e3eb5dd88bb569ec71f91e9991c81 +R e83420368d9fa99d84d7c5701ecba45b U drh -Z fb24d479cf53b7630adc4dea69c62760 +Z a8948efc181e8ffaf5af6c9f4ff55b46 diff --git a/manifest.uuid b/manifest.uuid index 0fc9cd5be3..b1c505cee1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d256b2caeb9e3eb5dd88bb569ec71f91e9991c81 \ No newline at end of file +25033ee94538289ba7e0147da30a18300047123f \ No newline at end of file diff --git a/src/in-operator.md b/src/in-operator.md index 76002b8597..0c9480234d 100644 --- a/src/in-operator.md +++ b/src/in-operator.md @@ -62,8 +62,8 @@ algorithm is suboptimal, especially if there are many rows on the RHS. The following procedure computes the same answer as the simple full-scan algorithm, though it does so with less work in the common case. This is the algorithm that is implemented in SQLite. The steps must occur -in the order specified. Except for the INDEX_NOOP optimization of step 1, -none of the steps can be skipped. +in the order specified. Steps 1 and 3 are optional. All other steps +are required for correctness. 1. If the RHS is a constant list of length 1 or 2, then rewrite the IN operator as a simple expression. Implement @@ -80,17 +80,14 @@ none of the steps can be skipped. 2. If the RHS is empty, return FALSE. - 3. If the LHS is a total-NULL or if the RHS contains a total-NULL, - then return NULL. + 3. If the LHS is a total-NULL, then return NULL. 4. If the LHS is non-NULL, then use the LHS as a probe in a binary search of the RHS -
      -
    1. If the binary search finds an exact match, return TRUE + 4-A. If the binary search finds an exact match, return TRUE -
    2. If the RHS is known to be not-null, return FALSE -
    + 4-B. If the RHS is known to be not-null, return FALSE 5. At this point, it is known that the result cannot be TRUE. All that remains is to distinguish between NULL and FALSE. From ecb87ac88d6cac19eb68cab7c5944fcb1d2a372e Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 25 Aug 2016 15:46:25 +0000 Subject: [PATCH 0753/1484] Improvements to IN operator code generator comments. Avoid unnecessary Copy operations on the LHS of the IN operator. FossilOrigin-Name: b6344298783a1207cba3f635939ddc9ba922ab67 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/expr.c | 54 +++++++++++++++++++++++++++++++++------------------ 3 files changed, 42 insertions(+), 26 deletions(-) diff --git a/manifest b/manifest index 2c01a256ff..cd1f8ff071 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Corrections\sto\sthe\sIN-operator\snotes. -D 2016-08-25T14:23:59.673 +C Improvements\sto\sIN\soperator\scode\sgenerator\scomments.\s\sAvoid\sunnecessary\nCopy\soperations\son\sthe\sLHS\sof\sthe\sIN\soperator. +D 2016-08-25T15:46:25.026 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -338,7 +338,7 @@ F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7 F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c 76c084f0265f4a3cd1ecf17eee112a94f1ccbc05 -F src/expr.c 866bcb6e85806beb0f96e651e9d17811e1ecbda5 +F src/expr.c 1c003fcb9c5a6f8c54f6392378225d578be2a086 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c e2be0968c1adc679c87e467aa5b4f167588f38a8 F src/func.c 29cc9acb170ec1387b9f63eb52cd85f8de96c771 @@ -1521,7 +1521,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d256b2caeb9e3eb5dd88bb569ec71f91e9991c81 -R e83420368d9fa99d84d7c5701ecba45b +P 25033ee94538289ba7e0147da30a18300047123f +R e1cedb5c8edd4d27c5fcda8527491fbe U drh -Z a8948efc181e8ffaf5af6c9f4ff55b46 +Z c3029179ef3a13ce81541f0730bc01a8 diff --git a/manifest.uuid b/manifest.uuid index b1c505cee1..f23c36e283 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -25033ee94538289ba7e0147da30a18300047123f \ No newline at end of file +b6344298783a1207cba3f635939ddc9ba922ab67 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 16f74d785e..385e808917 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2637,16 +2637,19 @@ int sqlite3ExprCheckIN(Parse *pParse, Expr *pIn){ ** x IN (SELECT ...) ** x IN (value, value, ...) ** -** The left-hand side (LHS) is a scalar expression. The right-hand side (RHS) -** is an array of zero or more values. The expression is true if the LHS is -** contained within the RHS. The value of the expression is unknown (NULL) -** if the LHS is NULL or if the LHS is not contained within the RHS and the -** RHS contains one or more NULL values. +** The left-hand side (LHS) is a scalar or vector expression. The +** right-hand side (RHS) is an array of zero or more values. The IN operator +** is true if the LHS is contained within the RHS. The result is false +** if the LHS is definitely not in the RHS. The result is NULL if the presence +** of the LHS in the RHS cannot be determined due to NULLs. ** ** This routine generates code that jumps to destIfFalse if the LHS is not ** contained within the RHS. If due to NULLs we cannot determine if the LHS ** is contained in the RHS then jump to destIfNull. If the LHS is contained ** within the RHS then fall through. +** +** See the separate in-operator.md documentation file in the canonical +** SQLite source tree for additional information. */ static void sqlite3ExprCodeIN( Parse *pParse, /* Parsing and code generating context */ @@ -2660,22 +2663,18 @@ static void sqlite3ExprCodeIN( Vdbe *v; /* Statement under construction */ int *aiMap = 0; /* Map from vector field to index column */ char *zAff = 0; /* Affinity string for comparisons */ - int nVector; /* Size of vectors for this IN(...) op */ - int iDummy; /* Dummy parameter to exprCodeVector() */ - Expr *pLeft = pExpr->pLeft; - int i; + int nVector; /* Size of vectors for this IN operator */ + int iDummy; /* Dummy parameter to exprCodeVector() */ + Expr *pLeft = pExpr->pLeft; /* The LHS of the IN operator */ + int i; /* loop counter */ if( sqlite3ExprCheckIN(pParse, pExpr) ) return; zAff = exprINAffinity(pParse, pExpr); - if( zAff==0 ) return; nVector = sqlite3ExprVectorSize(pExpr->pLeft); aiMap = (int*)sqlite3DbMallocZero( pParse->db, nVector*(sizeof(int) + sizeof(char)) + 1 ); - if( aiMap==0 ){ - sqlite3DbFree(pParse->db, zAff); - return; - } + if( pParse->db->mallocFailed ) goto end_code_IN_op; /* Attempt to compute the RHS. After this step, if anything other than ** IN_INDEX_NOOP is returned, the table opened ith cursor pExpr->iTable @@ -2691,16 +2690,32 @@ static void sqlite3ExprCodeIN( assert( pParse->nErr || nVector==1 || eType==IN_INDEX_EPH || eType==IN_INDEX_INDEX_ASC || eType==IN_INDEX_INDEX_DESC ); +#ifdef SQLITE_DEBUG + /* Confirm that aiMap[] contains nVector integer values between 0 and + ** nVector-1. */ + for(i=0; i from " IN (...)". If the LHS is a ** vector, then it is stored in an array of nVector registers starting ** at r1. */ - r1 = sqlite3GetTempRange(pParse, nVector); sqlite3ExprCachePush(pParse); r2 = exprCodeVector(pParse, pLeft, &iDummy); - for(i=0; idb, aiMap); sqlite3DbFree(pParse->db, zAff); - VdbeComment((v, "end IN expr")); } #endif /* SQLITE_OMIT_SUBQUERY */ From 1373c3a8c52ea8f2ba2877f223476cbe61c729b7 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 25 Aug 2016 17:40:32 +0000 Subject: [PATCH 0754/1484] Further refinement of the in-operator.md documentation. FossilOrigin-Name: df0648373a50006ca18d692e12552d1d53d549e3 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/in-operator.md | 30 ++++++++++++------------------ 3 files changed, 19 insertions(+), 25 deletions(-) diff --git a/manifest b/manifest index cd1f8ff071..9f1b129892 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improvements\sto\sIN\soperator\scode\sgenerator\scomments.\s\sAvoid\sunnecessary\nCopy\soperations\son\sthe\sLHS\sof\sthe\sIN\soperator. -D 2016-08-25T15:46:25.026 +C Further\srefinement\sof\sthe\sin-operator.md\sdocumentation. +D 2016-08-25T17:40:32.626 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -346,7 +346,7 @@ F src/global.c c45ea22aff29334f6a9ec549235ac3357c970015 F src/hash.c 55b5fb474100cee0b901edaf203e26c970940f36 F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4 F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da -F src/in-operator.md 973fe4522b871fb8cf683d8453760f4f19ac68c8 +F src/in-operator.md 9627b332c40228c0cb756eff1d84471b397539be F src/insert.c a255eb795cf475e7a0659297144fc80f70eb4e30 F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e F src/loadext.c dd7a2b77902cc66c22555aef02e1a682554b7aec @@ -1521,7 +1521,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 25033ee94538289ba7e0147da30a18300047123f -R e1cedb5c8edd4d27c5fcda8527491fbe +P b6344298783a1207cba3f635939ddc9ba922ab67 +R 0bc7dc0041a27b5ec53385d0f7163e25 U drh -Z c3029179ef3a13ce81541f0730bc01a8 +Z 0df057355417cbdb73d372028cbbe733 diff --git a/manifest.uuid b/manifest.uuid index f23c36e283..fa403130a1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b6344298783a1207cba3f635939ddc9ba922ab67 \ No newline at end of file +df0648373a50006ca18d692e12552d1d53d549e3 \ No newline at end of file diff --git a/src/in-operator.md b/src/in-operator.md index 0c9480234d..ecd0b97e3a 100644 --- a/src/in-operator.md +++ b/src/in-operator.md @@ -61,9 +61,7 @@ algorithm is suboptimal, especially if there are many rows on the RHS. The following procedure computes the same answer as the simple full-scan algorithm, though it does so with less work in the common case. This -is the algorithm that is implemented in SQLite. The steps must occur -in the order specified. Steps 1 and 3 are optional. All other steps -are required for correctness. +is the algorithm that is implemented in SQLite. 1. If the RHS is a constant list of length 1 or 2, then rewrite the IN operator as a simple expression. Implement @@ -78,25 +76,21 @@ are required for correctness. IN operator is used for membership testing. If the IN operator is driving a loop, then skip this step entirely. - 2. If the RHS is empty, return FALSE. + 2. Check the LHS to see if it is a partial-NULL and if it is, jump + ahead to step 4. - 3. If the LHS is a total-NULL, then return NULL. + 3. Do a binary search for the RHS using the LHS as a probe. If + an exact match is found, return TRUE. - 4. If the LHS is non-NULL, then use the LHS as a probe in a binary - search of the RHS + 4. If we do not need to distingish between FALSE and NULL, + then return FALSE. - 4-A. If the binary search finds an exact match, return TRUE - - 4-B. If the RHS is known to be not-null, return FALSE - - 5. At this point, it is known that the result cannot be TRUE. All - that remains is to distinguish between NULL and FALSE. - If a NOT-TRUE result is acceptable, then return NOT-TRUE now. + 5. If the RHS is non-NULL then return FALSE. 6. For each row in the RHS, compare that row against the LHS and - if the result is NULL, immediately return NULL. This step is - essentially the "Simple Full-scan Algorithm" above with the - tests for TRUE removed, since we know that the result cannot be - TRUE at this point. + if the result is NULL, immediately return NULL. In the case + of a scalar IN operator, we only need to look at the very first + row the RHS because for a scalar RHS, all NULLs will always come + first. If the RHS is empty, this step is a no-op. 7. Return FALSE. From 0a1082aec2a46e1189a6ccf8ca1edfc10c6681be Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 25 Aug 2016 17:47:36 +0000 Subject: [PATCH 0755/1484] Another fix in the IN-operator algorithm description. FossilOrigin-Name: f474aeac4fa62d87e73189868d7c7a295ffb7265 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/in-operator.md | 12 ++++++------ 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 9f1b129892..6410765471 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Further\srefinement\sof\sthe\sin-operator.md\sdocumentation. -D 2016-08-25T17:40:32.626 +C Another\sfix\sin\sthe\sIN-operator\salgorithm\sdescription. +D 2016-08-25T17:47:36.711 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -346,7 +346,7 @@ F src/global.c c45ea22aff29334f6a9ec549235ac3357c970015 F src/hash.c 55b5fb474100cee0b901edaf203e26c970940f36 F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4 F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da -F src/in-operator.md 9627b332c40228c0cb756eff1d84471b397539be +F src/in-operator.md e74c3dbd32b765c22c0bfc023f3b867e841a292b F src/insert.c a255eb795cf475e7a0659297144fc80f70eb4e30 F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e F src/loadext.c dd7a2b77902cc66c22555aef02e1a682554b7aec @@ -1521,7 +1521,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b6344298783a1207cba3f635939ddc9ba922ab67 -R 0bc7dc0041a27b5ec53385d0f7163e25 +P df0648373a50006ca18d692e12552d1d53d549e3 +R 5563c2646a49e89461278dffc729d682 U drh -Z 0df057355417cbdb73d372028cbbe733 +Z f4cbbe9a35f7af77488dc4e4d3d948a7 diff --git a/manifest.uuid b/manifest.uuid index fa403130a1..53efcbce1d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -df0648373a50006ca18d692e12552d1d53d549e3 \ No newline at end of file +f474aeac4fa62d87e73189868d7c7a295ffb7265 \ No newline at end of file diff --git a/src/in-operator.md b/src/in-operator.md index ecd0b97e3a..ff691864b0 100644 --- a/src/in-operator.md +++ b/src/in-operator.md @@ -77,16 +77,16 @@ is the algorithm that is implemented in SQLite. driving a loop, then skip this step entirely. 2. Check the LHS to see if it is a partial-NULL and if it is, jump - ahead to step 4. + ahead to step 5. - 3. Do a binary search for the RHS using the LHS as a probe. If + 3. Do a binary search of the RHS using the LHS as a probe. If an exact match is found, return TRUE. - 4. If we do not need to distingish between FALSE and NULL, + 4. If the RHS is non-NULL then return FALSE. + + 5. If we do not need to distingish between FALSE and NULL, then return FALSE. - - 5. If the RHS is non-NULL then return FALSE. - + 6. For each row in the RHS, compare that row against the LHS and if the result is NULL, immediately return NULL. In the case of a scalar IN operator, we only need to look at the very first From e347d3e8132c56ef59b12889605a4f3f0ad082ec Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 25 Aug 2016 21:14:34 +0000 Subject: [PATCH 0756/1484] Refactor the sqlite3ExprCodeIN() routine for improved maintainability. FossilOrigin-Name: b56705ae6374db9db82613ef89faa1a1e6b00a18 --- manifest | 14 +-- manifest.uuid | 2 +- src/expr.c | 271 +++++++++++++++++++++++---------------------- src/in-operator.md | 21 +++- 4 files changed, 161 insertions(+), 147 deletions(-) diff --git a/manifest b/manifest index 6410765471..5805cde823 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Another\sfix\sin\sthe\sIN-operator\salgorithm\sdescription. -D 2016-08-25T17:47:36.711 +C Refactor\sthe\ssqlite3ExprCodeIN()\sroutine\sfor\simproved\smaintainability. +D 2016-08-25T21:14:34.728 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a @@ -338,7 +338,7 @@ F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7 F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c 76c084f0265f4a3cd1ecf17eee112a94f1ccbc05 -F src/expr.c 1c003fcb9c5a6f8c54f6392378225d578be2a086 +F src/expr.c 45f814e52d2279914bd7a9141d92a26cb71b1533 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c e2be0968c1adc679c87e467aa5b4f167588f38a8 F src/func.c 29cc9acb170ec1387b9f63eb52cd85f8de96c771 @@ -346,7 +346,7 @@ F src/global.c c45ea22aff29334f6a9ec549235ac3357c970015 F src/hash.c 55b5fb474100cee0b901edaf203e26c970940f36 F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4 F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da -F src/in-operator.md e74c3dbd32b765c22c0bfc023f3b867e841a292b +F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 F src/insert.c a255eb795cf475e7a0659297144fc80f70eb4e30 F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e F src/loadext.c dd7a2b77902cc66c22555aef02e1a682554b7aec @@ -1521,7 +1521,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P df0648373a50006ca18d692e12552d1d53d549e3 -R 5563c2646a49e89461278dffc729d682 +P f474aeac4fa62d87e73189868d7c7a295ffb7265 +R 015c67366edd8d396f4d5202834c4796 U drh -Z f4cbbe9a35f7af77488dc4e4d3d948a7 +Z ec6ee7d7de4c92376a0d667aef9d24cc diff --git a/manifest.uuid b/manifest.uuid index 53efcbce1d..b8c92ac025 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f474aeac4fa62d87e73189868d7c7a295ffb7265 \ No newline at end of file +b56705ae6374db9db82613ef89faa1a1e6b00a18 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 385e808917..ab0349dcb7 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2638,10 +2638,15 @@ int sqlite3ExprCheckIN(Parse *pParse, Expr *pIn){ ** x IN (value, value, ...) ** ** The left-hand side (LHS) is a scalar or vector expression. The -** right-hand side (RHS) is an array of zero or more values. The IN operator -** is true if the LHS is contained within the RHS. The result is false -** if the LHS is definitely not in the RHS. The result is NULL if the presence -** of the LHS in the RHS cannot be determined due to NULLs. +** right-hand side (RHS) is an array of zero or more scalar values, or a +** subquery. If the RHS is a subquery, the number of result columns must +** match the number of columns in the vector on the LHS. If the RHS is +** a list of values, the LHS must be a scalar. +** +** The IN operator is true if the LHS value is contained within the RHS. +** The result is false if the LHS is definitely not in the RHS. The +** result is NULL if the presence of the LHS in the RHS cannot be +** determined due to NULLs. ** ** This routine generates code that jumps to destIfFalse if the LHS is not ** contained within the RHS. If due to NULLs we cannot determine if the LHS @@ -2659,22 +2664,29 @@ static void sqlite3ExprCodeIN( ){ int rRhsHasNull = 0; /* Register that is true if RHS contains NULL values */ int eType; /* Type of the RHS */ - int r1, r2; /* Temporary use registers */ + int rLhs; /* Register(s) holding the LHS values */ + int rLhsOrig; /* LHS values prior to reordering by aiMap[] */ Vdbe *v; /* Statement under construction */ int *aiMap = 0; /* Map from vector field to index column */ char *zAff = 0; /* Affinity string for comparisons */ - int nVector; /* Size of vectors for this IN operator */ - int iDummy; /* Dummy parameter to exprCodeVector() */ - Expr *pLeft = pExpr->pLeft; /* The LHS of the IN operator */ - int i; /* loop counter */ + int nVector; /* Size of vectors for this IN operator */ + int iDummy; /* Dummy parameter to exprCodeVector() */ + Expr *pLeft; /* The LHS of the IN operator */ + int i; /* loop counter */ + int destStep2; /* Where to jump when NULLs seen in step 2 */ + int destStep6 = 0; /* Start of code for Step 6 */ + int addrTruthOp; /* Address of opcode that determines the IN is true */ + int destNotNull; /* Jump here if a comparison is not true in step 6 */ + int addrTop; /* Top of the step-6 loop */ + pLeft = pExpr->pLeft; if( sqlite3ExprCheckIN(pParse, pExpr) ) return; zAff = exprINAffinity(pParse, pExpr); nVector = sqlite3ExprVectorSize(pExpr->pLeft); aiMap = (int*)sqlite3DbMallocZero( pParse->db, nVector*(sizeof(int) + sizeof(char)) + 1 ); - if( pParse->db->mallocFailed ) goto end_code_IN_op; + if( pParse->db->mallocFailed ) goto sqlite3ExprCodeIN_oom_error; /* Attempt to compute the RHS. After this step, if anything other than ** IN_INDEX_NOOP is returned, the table opened ith cursor pExpr->iTable @@ -2703,24 +2715,31 @@ static void sqlite3ExprCodeIN( /* Code the LHS, the from " IN (...)". If the LHS is a ** vector, then it is stored in an array of nVector registers starting ** at r1. + ** + ** sqlite3FindInIndex() might have reordered the fields of the LHS vector + ** so that the fields are in the same order as an existing index. The + ** aiMap[] array contains a mapping from the original LHS field order to + ** the field order that matches the RHS index. */ sqlite3ExprCachePush(pParse); - r2 = exprCodeVector(pParse, pLeft, &iDummy); - for(i=0; ix.pList; @@ -2732,7 +2751,7 @@ static void sqlite3ExprCodeIN( assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); if( destIfNull!=destIfFalse ){ regCkNull = sqlite3GetTempReg(pParse); - sqlite3VdbeAddOp3(v, OP_BitAnd, r1, r1, regCkNull); + sqlite3VdbeAddOp3(v, OP_BitAnd, rLhs, rLhs, regCkNull); } for(ii=0; iinExpr; ii++){ r2 = sqlite3ExprCodeTemp(pParse, pList->a[ii].pExpr, ®ToFree); @@ -2740,14 +2759,14 @@ static void sqlite3ExprCodeIN( sqlite3VdbeAddOp3(v, OP_BitAnd, regCkNull, r2, regCkNull); } if( iinExpr-1 || destIfNull!=destIfFalse ){ - sqlite3VdbeAddOp4(v, OP_Eq, r1, labelOk, r2, + sqlite3VdbeAddOp4(v, OP_Eq, rLhs, labelOk, r2, (void*)pColl, P4_COLLSEQ); VdbeCoverageIf(v, iinExpr-1); VdbeCoverageIf(v, ii==pList->nExpr-1); sqlite3VdbeChangeP5(v, zAff[0]); }else{ assert( destIfNull==destIfFalse ); - sqlite3VdbeAddOp4(v, OP_Ne, r1, destIfFalse, r2, + sqlite3VdbeAddOp4(v, OP_Ne, rLhs, destIfFalse, r2, (void*)pColl, P4_COLLSEQ); VdbeCoverage(v); sqlite3VdbeChangeP5(v, zAff[0] | SQLITE_JUMPIFNULL); } @@ -2759,127 +2778,111 @@ static void sqlite3ExprCodeIN( } sqlite3VdbeResolveLabel(v, labelOk); sqlite3ReleaseTempReg(pParse, regCkNull); + goto sqlite3ExprCodeIN_finished; + } + + /* Step 2: Check to see if the LHS contains any NULL columns. If the + ** LHS does contain NULLs then the result must be either FALSE or NULL. + ** We will then skip the binary search of the RHS. + */ + if( destIfNull==destIfFalse ){ + destStep2 = destIfFalse; }else{ - - /* If any value on the LHS is NULL, the result of the IN(...) operator - ** must be either false or NULL. If these two are handled identically, - ** test the LHS for NULLs and jump directly to destIfNull if any are - ** found. - ** - ** Otherwise, if NULL and false are handled differently, and the - ** IN(...) operation is not a vector operation, and the LHS of the - ** operator is NULL, then the result is false if the index is - ** completely empty, or NULL otherwise. */ - if( destIfNull==destIfFalse ){ - for(i=0; ipLeft, i); - if( sqlite3ExprCanBeNull(p) ){ - sqlite3VdbeAddOp2(v, OP_IsNull, r1+aiMap[i], destIfNull); - VdbeCoverage(v); - } - } - }else if( nVector==1 && sqlite3ExprCanBeNull(pExpr->pLeft) ){ - int addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, r1); VdbeCoverage(v); - sqlite3VdbeAddOp2(v, OP_Rewind, pExpr->iTable, destIfFalse); + destStep2 = destStep6 = sqlite3VdbeMakeLabel(v); + } + for(i=0; ipLeft, i); + if( sqlite3ExprCanBeNull(p) ){ + sqlite3VdbeAddOp2(v, OP_IsNull, rLhs+i, destStep2); VdbeCoverage(v); - sqlite3VdbeGoto(v, destIfNull); - sqlite3VdbeJumpHere(v, addr1); - } - - if( eType==IN_INDEX_ROWID ){ - /* In this case, the RHS is the ROWID of table b-tree */ - sqlite3VdbeAddOp3(v, OP_SeekRowid, pExpr->iTable, destIfFalse, r1); - VdbeCoverage(v); - }else{ - /* In this case, the RHS is an index b-tree. Apply the comparison - ** affinities to each value on the LHS of the operator. */ - sqlite3VdbeAddOp4(v, OP_Affinity, r1, nVector, 0, zAff, nVector); - - if( nVector>1 && destIfNull!=destIfFalse ){ - int iIdx = pExpr->iTable; - int addrTop; - int addrNext; - int addrFound; - - /* Search the index for the key. */ - addrFound = sqlite3VdbeAddOp4Int(v, OP_Found, iIdx, 0, r1, nVector); - VdbeCoverage(v); - - /* At this point the specified key is not present in the index, - ** so the result of the IN(..) operator must be either NULL or - ** 0. The vdbe code generated below figures out which. */ - addrTop = 1+sqlite3VdbeAddOp2(v, OP_Rewind, iIdx, destIfFalse); - VdbeCoverage(v); - addrNext = sqlite3VdbeMakeLabel(v); - - for(i=0; ipLeft, i); - if( sqlite3ExprCanBeNull(p) ){ - sqlite3VdbeAddOp2(v, OP_IsNull, r1+aiMap[i], destIfNull); - VdbeCoverage(v); - } - } - - }else if( rRhsHasNull==0 ){ - /* This branch runs if it is known at compile time that the RHS - ** cannot contain NULL values. This happens as a result - ** of "NOT NULL" constraints in the database schema. - ** - ** Also run this branch if NULL is equivalent to FALSE - ** for this particular IN operator. */ - sqlite3VdbeAddOp4Int( - v, OP_NotFound, pExpr->iTable, destIfFalse, r1, nVector - ); - VdbeCoverage(v); - }else{ - /* In this branch, the RHS of the IN might contain a NULL and - ** the presence of a NULL on the RHS makes a difference in the - ** outcome. - */ - int addr1; - - /* First check to see if the LHS is contained in the RHS. If so, - ** then the answer is TRUE the presence of NULLs in the RHS does - ** not matter. If the LHS is not contained in the RHS, then the - ** answer is NULL if the RHS contains NULLs and the answer is - ** FALSE if the RHS is NULL-free. - */ - addr1 = sqlite3VdbeAddOp4Int(v, OP_Found, pExpr->iTable, 0, r1, 1); - VdbeCoverage(v); - sqlite3VdbeAddOp2(v, OP_IsNull, rRhsHasNull, destIfNull); - VdbeCoverage(v); - sqlite3VdbeGoto(v, destIfFalse); - sqlite3VdbeJumpHere(v, addr1); - } } } - if( r2!=r1 ) sqlite3ReleaseTempReg(pParse, r1); + + /* Step 3. The LHS is now known to be non-NULL. Do the binary search + ** of the RHS using the LHS as a probe. If found, the result is + ** true. + */ + if( eType==IN_INDEX_ROWID ){ + /* In this case, the RHS is the ROWID of table b-tree and so we also + ** know that the RHS is non-NULL. Hence, we combine steps 3 and 4 + ** into a single opcode. */ + sqlite3VdbeAddOp3(v, OP_SeekRowid, pExpr->iTable, destIfFalse, rLhs); + VdbeCoverage(v); + addrTruthOp = sqlite3VdbeAddOp0(v, OP_Goto); /* Return True */ + }else{ + sqlite3VdbeAddOp4(v, OP_Affinity, rLhs, nVector, 0, zAff, nVector); + if( destIfFalse==destIfNull ){ + /* Combine Step 3 and Step 5 into a single opcode */ + sqlite3VdbeAddOp4Int(v, OP_NotFound, pExpr->iTable, destIfFalse, + rLhs, nVector); VdbeCoverage(v); + goto sqlite3ExprCodeIN_finished; + } + /* Ordinary Step 3, for the case where FALSE and NULL are distinct */ + addrTruthOp = sqlite3VdbeAddOp4Int(v, OP_Found, pExpr->iTable, 0, + rLhs, nVector); VdbeCoverage(v); + } + + /* Step 4. If the RHS is known to be non-NULL and we did not find + ** an match on the search above, then the result must be FALSE. + */ + if( rRhsHasNull && nVector==1 ){ + sqlite3VdbeAddOp2(v, OP_NotNull, rRhsHasNull, destIfFalse); + VdbeCoverage(v); + } + + /* Step 5. If we do not care about the difference between NULL and + ** FALSE, then just return false. + */ + if( destIfFalse==destIfNull ) sqlite3VdbeGoto(v, destIfFalse); + + /* Step 6: Loop through rows of the RHS. Compare each row to the LHS. + ** If any comparison is NULL, then the result is NULL. If all + ** comparisons are FALSE then the final result is FALSE. + ** + ** For a scalar LHS, it is sufficient to check just the first row + ** of the RHS. + */ + if( destStep6 ) sqlite3VdbeResolveLabel(v, destStep6); + addrTop = sqlite3VdbeAddOp2(v, OP_Rewind, pExpr->iTable, destIfFalse); + VdbeCoverage(v); + if( nVector>1 ){ + destNotNull = sqlite3VdbeMakeLabel(v); + }else{ + /* For nVector==1, combine steps 6 and 7 by immediately returning + ** FALSE if the first comparison is not NULL */ + destNotNull = destIfFalse; + } + for(i=0; iiTable, i, r3); + sqlite3VdbeAddOp4(v, OP_Ne, rLhs+i, destNotNull, r3, + (void*)pColl, P4_COLLSEQ); + VdbeCoverage(v); + sqlite3ReleaseTempReg(pParse, r3); + } + sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfNull); + if( nVector>1 ){ + sqlite3VdbeResolveLabel(v, destNotNull); + sqlite3VdbeAddOp2(v, OP_Next, pExpr->iTable, addrTop+1); + VdbeCoverage(v); + + /* Step 7: If we reach this point, we know that the result must + ** be false. */ + sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfFalse); + } + + /* Jumps here in order to return true. */ + sqlite3VdbeJumpHere(v, addrTruthOp); + +sqlite3ExprCodeIN_finished: + if( rLhs!=rLhsOrig ) sqlite3ReleaseTempReg(pParse, rLhs); sqlite3ExprCachePop(pParse); VdbeComment((v, "end IN expr")); -end_code_IN_op: +sqlite3ExprCodeIN_oom_error: sqlite3DbFree(pParse->db, aiMap); sqlite3DbFree(pParse->db, zAff); } diff --git a/src/in-operator.md b/src/in-operator.md index ff691864b0..e9ad2101aa 100644 --- a/src/in-operator.md +++ b/src/in-operator.md @@ -6,7 +6,7 @@ IN-Operator Implementation Notes An IN operator has one of the following formats: > - x IN (list) + x IN (y1,y2,y3,...,yN) x IN (subquery) The "x" is referred to as the LHS (left-hand side). The list or subquery @@ -14,9 +14,20 @@ on the right is called the RHS (right-hand side). If the RHS is a list it must be a non-empty list. But if the RHS is a subquery, it can be an empty set. -Both the LHS and RHS can be scalars or vectors. The two must match. -In other words, they must both be scalar or else they must both be -vectors of the same length. +The LHS can be a scalar (a single quantity) or a vector (a list of +two or or more values) or a subquery that returns one or more columns. +We use the term "vector" to mean an actually list of values or a +subquery that returns two or more columns. An isolated value or +a subquery that returns a single columns is called a scalar. + +The RHS can be a subquery that returns a single column, a subquery +that returns two or more columns, or a list of scalars. It is not +currently support for the RHS to be a list of vectors. + +The number of columns for LHS must match the number of columns for +the RHS. If the RHS is a list of values, then the LHS must be a +scalar. If the RHS is a subquery returning N columns, then the LHS +must be a vector of size N. NULL values can occur in either or both of the LHS and RHS. If the LHS contains only @@ -84,7 +95,7 @@ is the algorithm that is implemented in SQLite. 4. If the RHS is non-NULL then return FALSE. - 5. If we do not need to distingish between FALSE and NULL, + 5. If we do not need to distinguish between FALSE and NULL, then return FALSE. 6. For each row in the RHS, compare that row against the LHS and From fb82820a3807a51b7fd93676826e4f5f6b4f7acf Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 25 Aug 2016 22:06:37 +0000 Subject: [PATCH 0757/1484] Fix the sqlite3_trace_v2() interface so that it goes disabled if either the callback or mask arguments are zero, in accordance with the documentation. FossilOrigin-Name: 37e6c54b1afc634844026b3fe874dd2d550c6558 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/main.c | 2 ++ 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 7dc1924e05..2a732336ae 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Sync\sup\sthe\sMSVC\sautoconf\smakefile. -D 2016-08-24T18:21:58.857 +C Fix\sthe\ssqlite3_trace_v2()\sinterface\sso\sthat\sit\sgoes\sdisabled\sif\seither\sthe\ncallback\sor\smask\sarguments\sare\szero,\sin\saccordance\swith\sthe\sdocumentation. +D 2016-08-25T22:06:37.897 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5017381e4853b1472e01d5bb926be1268eba429c @@ -349,7 +349,7 @@ F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da F src/insert.c a255eb795cf475e7a0659297144fc80f70eb4e30 F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e F src/loadext.c dd7a2b77902cc66c22555aef02e1a682554b7aec -F src/main.c 4dba24a78c9797c4005521107905f42217668b86 +F src/main.c 0bfcf1a5b612dddb4dd0fd04b53ef08ace0f48ff F src/malloc.c 1443d1ad95d67c21d77af7ae3f44678252f0efec F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b @@ -1511,7 +1511,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P c640489db2037f1a284d7b85fa753ccdac1b8f79 -R 959092fa640b62161f63260898254ab1 -U mistachkin -Z d96a1e74a14d6dd8b06850bfa4844a5e +P 77f7c31a3aa44798cfa5f557242caffb593ce7af +R e30f608edda41eef799f7d696f256071 +U drh +Z 8b647e4b12a24ec47b73225bc510e869 diff --git a/manifest.uuid b/manifest.uuid index 630410a19c..3d13389a96 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -77f7c31a3aa44798cfa5f557242caffb593ce7af \ No newline at end of file +37e6c54b1afc634844026b3fe874dd2d550c6558 \ No newline at end of file diff --git a/src/main.c b/src/main.c index 2b82e331a0..a46b5aded6 100644 --- a/src/main.c +++ b/src/main.c @@ -1843,6 +1843,8 @@ int sqlite3_trace_v2( } #endif sqlite3_mutex_enter(db->mutex); + if( mTrace==0 ) xTrace = 0; + if( xTrace==0 ) mTrace = 0; db->mTrace = mTrace; db->xTrace = xTrace; db->pTraceArg = pArg; From f10122d53520c1472d163a5821d7b859b1adb15e Mon Sep 17 00:00:00 2001 From: mistachkin Date: Thu, 25 Aug 2016 23:24:09 +0000 Subject: [PATCH 0758/1484] Fix typos in 'vtabF.test' file. No changes to code. FossilOrigin-Name: a8546feec9388d96934b16e516a165cd37d32ce9 --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/vtabF.test | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 2a732336ae..5a4774568c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\ssqlite3_trace_v2()\sinterface\sso\sthat\sit\sgoes\sdisabled\sif\seither\sthe\ncallback\sor\smask\sarguments\sare\szero,\sin\saccordance\swith\sthe\sdocumentation. -D 2016-08-25T22:06:37.897 +C Fix\stypos\sin\s'vtabF.test'\sfile.\s\sNo\schanges\sto\scode. +D 2016-08-25T23:24:09.049 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5017381e4853b1472e01d5bb926be1268eba429c @@ -1346,7 +1346,7 @@ F test/vtabB.test 04df5dc531b9f44d9ca65b9c1b79f12b5922a796 F test/vtabC.test 4528f459a13136f982e75614d120aef165f17292 F test/vtabD.test 05b3f1d77117271671089e48719524b676842e96 F test/vtabE.test d5024aa42754962f6bb0afd261681686488e7afe -F test/vtabF.test fd5ad376f5a34fe0891df1f3cddb4fe7c3eb077e +F test/vtabF.test 1918844c7c902f6a16c8dacf1ec8f84886d6e78b F test/vtabH.test 5f5157a1501d9889ec35c1a1832f69612dd31444 F test/vtabI.test 751b07636700dbdea328e4265b6077ccd6811a3f F test/vtab_alter.test 9e374885248f69e251bdaacf480b04a197f125e5 @@ -1511,7 +1511,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 77f7c31a3aa44798cfa5f557242caffb593ce7af -R e30f608edda41eef799f7d696f256071 -U drh -Z 8b647e4b12a24ec47b73225bc510e869 +P 37e6c54b1afc634844026b3fe874dd2d550c6558 +R 4cab9f7d7896757fe3fc8a8951123595 +U mistachkin +Z 99aab80e5b18ffff2a9e94c7e8fbdfe4 diff --git a/manifest.uuid b/manifest.uuid index 3d13389a96..f043dbdac4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -37e6c54b1afc634844026b3fe874dd2d550c6558 \ No newline at end of file +a8546feec9388d96934b16e516a165cd37d32ce9 \ No newline at end of file diff --git a/test/vtabF.test b/test/vtabF.test index b9341ea597..7b11cb8c71 100644 --- a/test/vtabF.test +++ b/test/vtabF.test @@ -21,7 +21,7 @@ ifcapable !vtab||!schema_pragmas { finish_test ; return } # Register the echo module register_echo_module [sqlite3_connection_pointer db] -do_test vtabE-1.1 { +do_test vtabF-1.1 { execsql { CREATE TABLE t1(a, b); CREATE INDEX i1 ON t1(a); @@ -37,7 +37,7 @@ do_test vtabE-1.1 { SELECT b FROM t1 WHERE a IS NOT NULL; } } {110 111 112 113} -do_test vtabE-1.2 { +do_test vtabF-1.2 { execsql {SELECT b FROM tv1 WHERE a IS NOT NULL} } {110 111 112 113} From a28f85b076be5ca68ef53b59291feab0153dc735 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 26 Aug 2016 01:02:09 +0000 Subject: [PATCH 0759/1484] Remove an unreachable branch from sqlite3ExprAffinity() FossilOrigin-Name: 9d96f61481704e5ec399ee425f0ebb246902ecc5 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/expr.c | 3 ++- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 5713d84932..ceeeb74f30 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\srecent\schanges\sfrom\strunk. -D 2016-08-25T22:31:44.503 +C Remove\san\sunreachable\sbranch\sfrom\ssqlite3ExprAffinity() +D 2016-08-26T01:02:09.972 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5017381e4853b1472e01d5bb926be1268eba429c @@ -338,7 +338,7 @@ F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7 F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c 76c084f0265f4a3cd1ecf17eee112a94f1ccbc05 -F src/expr.c 45f814e52d2279914bd7a9141d92a26cb71b1533 +F src/expr.c 2fe35bc5e93ac4c692b0b8c563ed6fc022247ed4 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c e2be0968c1adc679c87e467aa5b4f167588f38a8 F src/func.c 29cc9acb170ec1387b9f63eb52cd85f8de96c771 @@ -1521,7 +1521,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b56705ae6374db9db82613ef89faa1a1e6b00a18 37e6c54b1afc634844026b3fe874dd2d550c6558 -R 2a905e6de196a1adbfb5e3026f93f057 +P 5789aab8ef59ae1cdfdae123b078ee03da6e08ed +R 9ebda3b476f4e068ca78a071831449eb U drh -Z 71128db26f4e518aa8ba75a034627d25 +Z ef957217ed40f2345a57bc50f3f65b90 diff --git a/manifest.uuid b/manifest.uuid index d27311b40f..d803bb5d8a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5789aab8ef59ae1cdfdae123b078ee03da6e08ed \ No newline at end of file +9d96f61481704e5ec399ee425f0ebb246902ecc5 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index ab0349dcb7..982605d196 100644 --- a/src/expr.c +++ b/src/expr.c @@ -51,8 +51,9 @@ char sqlite3ExprAffinity(Expr *pExpr){ return sqlite3AffinityType(pExpr->u.zToken, 0); } #endif - if( (op==TK_AGG_COLUMN || op==TK_COLUMN) && pExpr->pTab!=0 ){ + if( op==TK_AGG_COLUMN || op==TK_COLUMN ){ int j = pExpr->iColumn; + assert( pExpr->pTab!=0 ); if( j<0 ) return SQLITE_AFF_INTEGER; assert( pExpr->pTab && jpTab->nCol ); return pExpr->pTab->aCol[j].affinity; From 7dd7d98bbf6d4b49e67df0ac6553def4f0a4cf7a Mon Sep 17 00:00:00 2001 From: mistachkin Date: Fri, 26 Aug 2016 01:17:12 +0000 Subject: [PATCH 0760/1484] Support running the fstree tests in 'vtabH.test' on Windows when not using the system drive. FossilOrigin-Name: 3680f95ff34fdcf6a18a99268678a56e4be5a023 --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/test_fs.c | 8 ++++++-- src/test_windirent.c | 30 +++++++++++++++++++++++++++++- src/test_windirent.h | 7 +++++++ test/vtabH.test | 25 +++++++++++++++++++++++-- 6 files changed, 75 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index 5a4774568c..6980de4b90 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\stypos\sin\s'vtabF.test'\sfile.\s\sNo\schanges\sto\scode. -D 2016-08-25T23:24:09.049 +C Support\srunning\sthe\sfstree\stests\sin\s'vtabH.test'\son\sWindows\swhen\snot\susing\sthe\ssystem\sdrive. +D 2016-08-26T01:17:12.349 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5017381e4853b1472e01d5bb926be1268eba429c @@ -412,7 +412,7 @@ F src/test_btree.c 8b2dc8b8848cf3a4db93f11578f075e82252a274 F src/test_config.c 4d3d4a886416f369771d69a6dba926866deda788 F src/test_demovfs.c a0c3bdd45ed044115c2c9f7779e56eafff18741e F src/test_devsym.c 4e58dec2602d8e139ca08659f62a62450587cb58 -F src/test_fs.c ac62ce7d5c0c23aa6932891cad5746945564c91c +F src/test_fs.c e16cbe68d3b107e00a907c20a9a02629870eb69b F src/test_func.c a2b4993da973b0ea60dd5d51a7066238ede8c329 F src/test_hexio.c 1d4469ca61ab202a1fcec6543f584d2407205e8d F src/test_init.c 4413c211a94b62157ca4c145b3f27c497f03c664 @@ -439,8 +439,8 @@ F src/test_tclvar.c df9fe1213c2634687a9ca0b0bec0d2119d359ae3 F src/test_thread.c 911d15fb14e19c0c542bdc8aabf981c2f10a4858 F src/test_vfs.c f0186261a24de2671d080bcd8050732f0cb64f6e F src/test_vfstrace.c bab9594adc976cbe696ff3970728830b4c5ed698 -F src/test_windirent.c 8f5fada630348558d5745b334702f301da1ffc61 -F src/test_windirent.h b12055cab6227f7be10f5c19296f67c60cc5e2a5 +F src/test_windirent.c 600398db0198ca1c77ca183831bf456746b6f5c4 +F src/test_windirent.h 7edc57e2faa727026dbd5d010dd0e2e665d5aa01 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c 78c8085bc7af1922aa687f0f4bbd716821330de5 @@ -1347,7 +1347,7 @@ F test/vtabC.test 4528f459a13136f982e75614d120aef165f17292 F test/vtabD.test 05b3f1d77117271671089e48719524b676842e96 F test/vtabE.test d5024aa42754962f6bb0afd261681686488e7afe F test/vtabF.test 1918844c7c902f6a16c8dacf1ec8f84886d6e78b -F test/vtabH.test 5f5157a1501d9889ec35c1a1832f69612dd31444 +F test/vtabH.test c7a029dc54ee0e1f21f78c7a6c93a706703bea6d F test/vtabI.test 751b07636700dbdea328e4265b6077ccd6811a3f F test/vtab_alter.test 9e374885248f69e251bdaacf480b04a197f125e5 F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8 @@ -1511,7 +1511,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 37e6c54b1afc634844026b3fe874dd2d550c6558 -R 4cab9f7d7896757fe3fc8a8951123595 +P a8546feec9388d96934b16e516a165cd37d32ce9 +R 66d6b55dfecea97ee12f2bdebb86bb76 U mistachkin -Z 99aab80e5b18ffff2a9e94c7e8fbdfe4 +Z 5d798dae32bcc32e75e6cc95a57c626f diff --git a/manifest.uuid b/manifest.uuid index f043dbdac4..59101f59c6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a8546feec9388d96934b16e516a165cd37d32ce9 \ No newline at end of file +3680f95ff34fdcf6a18a99268678a56e4be5a023 \ No newline at end of file diff --git a/src/test_fs.c b/src/test_fs.c index 87088bdae7..dd590a6623 100644 --- a/src/test_fs.c +++ b/src/test_fs.c @@ -499,9 +499,13 @@ static int fstreeFilter( char aWild[2] = { '\0', '\0' }; #if SQLITE_OS_WIN - zRoot = sqlite3_mprintf("%s%c", getenv("SystemDrive"), '/'); + const char *zDrive = windirent_getenv("fstreeDrive"); + if( zDrive==0 ){ + zDrive = windirent_getenv("SystemDrive"); + } + zRoot = sqlite3_mprintf("%s%c", zDrive, '/'); nRoot = sqlite3Strlen30(zRoot); - zPrefix = sqlite3_mprintf("%s", getenv("SystemDrive")); + zPrefix = sqlite3_mprintf("%s", zDrive); nPrefix = sqlite3Strlen30(zPrefix); #else zRoot = "/"; diff --git a/src/test_windirent.c b/src/test_windirent.c index 11d7dc07d0..044bc7f414 100644 --- a/src/test_windirent.c +++ b/src/test_windirent.c @@ -17,6 +17,34 @@ #include "test_windirent.h" +/* +** Implementation of the POSIX getenv() function using the Win32 API. +** This function is not thread-safe. +*/ +const char *windirent_getenv( + const char *name +){ + static char value[32768]; /* Maximum length, per MSDN */ + DWORD dwSize = sizeof(value) / sizeof(char); /* Size in chars */ + DWORD dwRet; /* Value returned by GetEnvironmentVariableA() */ + + memset(value, 0, sizeof(value)); + dwRet = GetEnvironmentVariableA(name, value, dwSize); + if( dwRet==0 || dwRet>dwSize ){ + /* + ** The function call to GetEnvironmentVariableA() failed -OR- + ** the buffer is not large enough. Either way, return NULL. + */ + return 0; + }else{ + /* + ** The function call to GetEnvironmentVariableA() succeeded + ** -AND- the buffer contains the entire value. + */ + return value; + } +} + /* ** Implementation of the POSIX opendir() function using the MSVCRT. */ @@ -32,7 +60,7 @@ LPDIR opendir( /* TODO: Remove this if Unix-style root paths are not used. */ if( sqlite3_stricmp(dirname, "/")==0 ){ - dirname = getenv("SystemDrive"); + dirname = windirent_getenv("SystemDrive"); } _snprintf(data.name, namesize, "%s\\*", dirname); diff --git a/src/test_windirent.h b/src/test_windirent.h index 0b8d1a7b51..be454988e3 100644 --- a/src/test_windirent.h +++ b/src/test_windirent.h @@ -92,6 +92,13 @@ struct DIR { DIRENT d_next; /* DIRENT constructed based on "_findnext". */ }; +/* +** Provide the function prototype for the POSIX compatiable getenv() +** function. This function is not thread-safe. +*/ + +extern const char *windirent_getenv(const char *name); + /* ** Finally, we can provide the function prototypes for the opendir(), ** readdir(), readdir_r(), and closedir() POSIX functions. diff --git a/test/vtabH.test b/test/vtabH.test index d16db13674..7e3ba41d64 100644 --- a/test/vtabH.test +++ b/test/vtabH.test @@ -108,7 +108,12 @@ foreach ::tclvar_set_omit {0 1} { #------------------------------------------------------------------------- # -if {1} { +if {$tcl_platform(platform)=="windows"} { + set drive [string range [pwd] 0 1] + set ::env(fstreeDrive) $drive +} +if {$tcl_platform(platform)!="windows" || \ + [regexp -nocase -- {^[A-Z]:} $drive]} { reset_db register_fs_module db do_execsql_test 3.0 { @@ -119,7 +124,7 @@ if {1} { proc list_root_files {} { if {$::tcl_platform(platform) eq "windows"} { set res [list] - foreach name [glob -directory $::env(SystemDrive)/ -- *] { + foreach name [glob -directory $::env(fstreeDrive)/ -- *] { if {[string index [file tail $name] 0] eq "."} continue lappend res $name } @@ -142,6 +147,22 @@ if {1} { } } + # Read the first 5 entries from the root directory. Except, ignore + # files that contain the "$" character in their names as these are + # special files on some Windows platforms. + # + set res [list] + foreach p [lrange [list_root_files] 0 4] { + if {$::tcl_platform(platform) eq "windows"} { + if {![regexp {\$} $p]} {lappend res $p} + } else { + lappend res "/$p" + } + } + do_execsql_test 3.1 { + SELECT path FROM fstree WHERE path NOT GLOB '*$*' LIMIT 5; + } $res + # Read all entries in the current directory. # proc contents {pattern} { From 0a9428d0a70470632ec40e529aff668b8acf637d Mon Sep 17 00:00:00 2001 From: mistachkin Date: Fri, 26 Aug 2016 01:47:22 +0000 Subject: [PATCH 0761/1484] Make the test 'vtabH-3.1' work when there are less than 5 top-level items. FossilOrigin-Name: 328f79bb5713abbecaeb0ef3fb37f56a0946b915 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/vtabH.test | 11 +++++++---- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 6980de4b90..2992ea4ce2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Support\srunning\sthe\sfstree\stests\sin\s'vtabH.test'\son\sWindows\swhen\snot\susing\sthe\ssystem\sdrive. -D 2016-08-26T01:17:12.349 +C Make\sthe\stest\s'vtabH-3.1'\swork\swhen\sthere\sare\sless\sthan\s5\stop-level\sitems. +D 2016-08-26T01:47:22.955 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5017381e4853b1472e01d5bb926be1268eba429c @@ -1347,7 +1347,7 @@ F test/vtabC.test 4528f459a13136f982e75614d120aef165f17292 F test/vtabD.test 05b3f1d77117271671089e48719524b676842e96 F test/vtabE.test d5024aa42754962f6bb0afd261681686488e7afe F test/vtabF.test 1918844c7c902f6a16c8dacf1ec8f84886d6e78b -F test/vtabH.test c7a029dc54ee0e1f21f78c7a6c93a706703bea6d +F test/vtabH.test e2d597b61f06e74b7ec0e6366f10eab6a6404cd8 F test/vtabI.test 751b07636700dbdea328e4265b6077ccd6811a3f F test/vtab_alter.test 9e374885248f69e251bdaacf480b04a197f125e5 F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8 @@ -1511,7 +1511,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a8546feec9388d96934b16e516a165cd37d32ce9 -R 66d6b55dfecea97ee12f2bdebb86bb76 +P 3680f95ff34fdcf6a18a99268678a56e4be5a023 +R 43a3970ddbdab96e60099ba72556b24c U mistachkin -Z 5d798dae32bcc32e75e6cc95a57c626f +Z 62b5f3e99eda63df5de3a56bf43d82d6 diff --git a/manifest.uuid b/manifest.uuid index 59101f59c6..a4ff000932 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3680f95ff34fdcf6a18a99268678a56e4be5a023 \ No newline at end of file +328f79bb5713abbecaeb0ef3fb37f56a0946b915 \ No newline at end of file diff --git a/test/vtabH.test b/test/vtabH.test index 7e3ba41d64..d3f298e210 100644 --- a/test/vtabH.test +++ b/test/vtabH.test @@ -152,16 +152,19 @@ if {$tcl_platform(platform)!="windows" || \ # special files on some Windows platforms. # set res [list] - foreach p [lrange [list_root_files] 0 4] { + set root_files [list_root_files] + set num_root_files [llength $root_files] + set lim_root_files [expr {$num_root_files > 5 ? 5 : $num_root_files}] + foreach p [lrange $root_files 0 [expr {$lim_root_files - 1}]] { if {$::tcl_platform(platform) eq "windows"} { if {![regexp {\$} $p]} {lappend res $p} } else { lappend res "/$p" } } - do_execsql_test 3.1 { - SELECT path FROM fstree WHERE path NOT GLOB '*$*' LIMIT 5; - } $res + do_execsql_test 3.1 [subst { + SELECT path FROM fstree WHERE path NOT GLOB '*\$*' LIMIT $lim_root_files; + }] $res # Read all entries in the current directory. # From 975c800dd8f44a8dd54c1e9f212a368323074c62 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Fri, 26 Aug 2016 02:10:50 +0000 Subject: [PATCH 0762/1484] Adapt the special case of '$' in item names for test 'vtabH-3.1' as well. FossilOrigin-Name: e4aeaa2bc73b57f1ef134cc4f54e2a652a20b5c9 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/vtabH.test | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 2992ea4ce2..ec927214e4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\sthe\stest\s'vtabH-3.1'\swork\swhen\sthere\sare\sless\sthan\s5\stop-level\sitems. -D 2016-08-26T01:47:22.955 +C Adapt\sthe\sspecial\scase\sof\s'$'\sin\sitem\snames\sfor\stest\s'vtabH-3.1'\sas\swell. +D 2016-08-26T02:10:50.317 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5017381e4853b1472e01d5bb926be1268eba429c @@ -1347,7 +1347,7 @@ F test/vtabC.test 4528f459a13136f982e75614d120aef165f17292 F test/vtabD.test 05b3f1d77117271671089e48719524b676842e96 F test/vtabE.test d5024aa42754962f6bb0afd261681686488e7afe F test/vtabF.test 1918844c7c902f6a16c8dacf1ec8f84886d6e78b -F test/vtabH.test e2d597b61f06e74b7ec0e6366f10eab6a6404cd8 +F test/vtabH.test 97f61b0253260831af6232163f7852e2653baed6 F test/vtabI.test 751b07636700dbdea328e4265b6077ccd6811a3f F test/vtab_alter.test 9e374885248f69e251bdaacf480b04a197f125e5 F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8 @@ -1511,7 +1511,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 3680f95ff34fdcf6a18a99268678a56e4be5a023 -R 43a3970ddbdab96e60099ba72556b24c +P 328f79bb5713abbecaeb0ef3fb37f56a0946b915 +R dade750024fe6ad04559f56926a096ca U mistachkin -Z 62b5f3e99eda63df5de3a56bf43d82d6 +Z 8b0930f7f9116d652fcf85daf416c55f diff --git a/manifest.uuid b/manifest.uuid index a4ff000932..89b707eee1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -328f79bb5713abbecaeb0ef3fb37f56a0946b915 \ No newline at end of file +e4aeaa2bc73b57f1ef134cc4f54e2a652a20b5c9 \ No newline at end of file diff --git a/test/vtabH.test b/test/vtabH.test index d3f298e210..f2a116f350 100644 --- a/test/vtabH.test +++ b/test/vtabH.test @@ -157,7 +157,7 @@ if {$tcl_platform(platform)!="windows" || \ set lim_root_files [expr {$num_root_files > 5 ? 5 : $num_root_files}] foreach p [lrange $root_files 0 [expr {$lim_root_files - 1}]] { if {$::tcl_platform(platform) eq "windows"} { - if {![regexp {\$} $p]} {lappend res $p} + if {[regexp {\$} $p]} {incr lim_root_files -1} else {lappend res $p} } else { lappend res "/$p" } From 64bcb8cfbb6898d4554de7d88c1ed42dca2c2709 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 26 Aug 2016 03:42:57 +0000 Subject: [PATCH 0763/1484] Comment improvements. Put ALWAYS and NEVER macros on three unreachable branches. FossilOrigin-Name: 397617009e07004596476d6f5644fdf84c376f54 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/expr.c | 6 +++--- src/where.c | 15 ++++++++++++--- src/whereexpr.c | 4 +++- 5 files changed, 27 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index ceeeb74f30..0ab7cba655 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\san\sunreachable\sbranch\sfrom\ssqlite3ExprAffinity() -D 2016-08-26T01:02:09.972 +C Comment\simprovements.\s\sPut\sALWAYS\sand\sNEVER\smacros\son\sthree\sunreachable\nbranches. +D 2016-08-26T03:42:57.323 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5017381e4853b1472e01d5bb926be1268eba429c @@ -338,7 +338,7 @@ F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7 F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c 76c084f0265f4a3cd1ecf17eee112a94f1ccbc05 -F src/expr.c 2fe35bc5e93ac4c692b0b8c563ed6fc022247ed4 +F src/expr.c bca7140549a34c8a71a4cf0605666403af390477 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c e2be0968c1adc679c87e467aa5b4f167588f38a8 F src/func.c 29cc9acb170ec1387b9f63eb52cd85f8de96c771 @@ -465,10 +465,10 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 02eeecc265f6ffd0597378f5d8ae9070b62a406a F src/wal.h 6dd221ed384afdc204bc61e25c23ef7fd5a511f2 F src/walker.c 2d2cc7fb0f320f7f415215d7247f3c584141ac09 -F src/where.c c7cdfd54f383090bb801cdd50d36de1a24684bb2 +F src/where.c 2f60a506364b22c48371b8b94089c4028a694a0a F src/whereInt.h 14dd243e13b81cbb0a66063d38b70f93a7d6e613 F src/wherecode.c 5a5528c39be09593cada6ae465d7a0f48db0077f -F src/whereexpr.c aa54bf11adf6bc7e52f56281f436ab5fd421ce16 +F src/whereexpr.c 7f9ada866d48d15d09754ae819c1c40efe3b2aff F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1521,7 +1521,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 5789aab8ef59ae1cdfdae123b078ee03da6e08ed -R 9ebda3b476f4e068ca78a071831449eb +P 9d96f61481704e5ec399ee425f0ebb246902ecc5 +R 0b547643c3844e6bc7fc81ff0189aeeb U drh -Z ef957217ed40f2345a57bc50f3f65b90 +Z e947ea7de839ffcabb8c6e9f9aa97cfb diff --git a/manifest.uuid b/manifest.uuid index d803bb5d8a..559f8ba56e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9d96f61481704e5ec399ee425f0ebb246902ecc5 \ No newline at end of file +397617009e07004596476d6f5644fdf84c376f54 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 982605d196..f0670799e8 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2443,9 +2443,9 @@ int sqlite3CodeSubselect( ExprList *pEList = pSelect->pEList; assert( !isRowid ); - if( pEList->nExpr!=nVal ){ - sqlite3SubselectError(pParse, pEList->nExpr, nVal); - }else{ + /* If the LHS and RHS of the IN operator do not match, that + ** error will have been caught long before we reach this point. */ + if( ALWAYS(pEList->nExpr==nVal) ){ SelectDest dest; int i; sqlite3SelectDestInit(&dest, SRT_Set, pExpr->iTable); diff --git a/src/where.c b/src/where.c index 30854ee422..74da4089a8 100644 --- a/src/where.c +++ b/src/where.c @@ -2224,7 +2224,11 @@ static void whereLoopOutputAdjust( ** this case is 3. */ int whereRangeVectorLen( - Parse *pParse, int iCur, Index *pIdx, int nEq, WhereTerm *pTerm + Parse *pParse, /* Parsing context */ + int iCur, /* Cursor open on pIdx */ + Index *pIdx, /* The index to be used for a inequality constraint */ + int nEq, /* Number of prior equality constraints on same index */ + WhereTerm *pTerm /* The vector inequality constraint */ ){ int nCmp = sqlite3ExprVectorSize(pTerm->pExpr->pLeft); int i; @@ -2261,7 +2265,8 @@ int whereRangeVectorLen( if( aff!=idxaff ) break; pColl = sqlite3BinaryCompareCollSeq(pParse, pLhs, pRhs); - if( pColl==0 || sqlite3StrICmp(pColl->zName, pIdx->azColl[i+nEq]) ) break; + if( NEVER(pColl==0) ) break; + if( sqlite3StrICmp(pColl->zName, pIdx->azColl[i+nEq]) ) break; } return i; } @@ -3573,7 +3578,11 @@ static i8 wherePathSatisfiesOrderBy( isOrderDistinct = 0; } continue; - }else if( eOp & WO_IN ){ + }else if( ALWAYS(eOp & WO_IN) ){ + /* ALWAYS() justification: eOp is an equality operator due to the + ** ju.btree.nEq constraint above. Any equality other + ** than WO_IN is captured by the previous "if". So this one + ** always has to be WO_IN. */ Expr *pX = pLoop->aLTerm[j]->pExpr; for(i=j+1; iu.btree.nEq; i++){ if( pLoop->aLTerm[i]->pExpr==pX ){ diff --git a/src/whereexpr.c b/src/whereexpr.c index 823a2df235..00328989e7 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -846,7 +846,9 @@ static int exprMightBeIndexed( ** inequality constraint (>, <, >= or <=), perform the processing ** on the first element of the vector. */ assert( TK_GT+1==TK_LE && TK_GT+2==TK_LT && TK_GT+3==TK_GE ); - if( pExpr->op==TK_VECTOR && (op>=TK_GT && op<=TK_GE) ){ + assert( TK_ISop==TK_VECTOR && (op>=TK_GT && ALWAYS(op<=TK_GE)) ){ pExpr = pExpr->x.pList->a[0].pExpr; } From 8e16b2d3e675663b3282f4dfcdf7aea0debb8e78 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Fri, 26 Aug 2016 04:32:59 +0000 Subject: [PATCH 0764/1484] Rename a test procedure in 'speed3.test' to avoid a name collision. FossilOrigin-Name: 84de17bc688f1df2be1a34420470d1b16f8f4e56 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/speed3.test | 8 ++++---- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index ec927214e4..62a14c34f4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Adapt\sthe\sspecial\scase\sof\s'$'\sin\sitem\snames\sfor\stest\s'vtabH-3.1'\sas\swell. -D 2016-08-26T02:10:50.317 +C Rename\sa\stest\sprocedure\sin\s'speed3.test'\sto\savoid\sa\sname\scollision. +D 2016-08-26T04:32:59.825 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5017381e4853b1472e01d5bb926be1268eba429c @@ -1094,7 +1094,7 @@ F test/speed1.test f2974a91d79f58507ada01864c0e323093065452 F test/speed1p.explain d841e650a04728b39e6740296b852dccdca9b2cb F test/speed1p.test b180e98609c7677382cf618c0ec9b69f789033a8 F test/speed2.test 53177056baf6556dcbdcf032bbdfc41c1aa74ded -F test/speed3.test d32043614c08c53eafdc80f33191d5bd9b920523 +F test/speed3.test 694affeb9100526007436334cf7d08f3d74b85ef F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715 F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b @@ -1511,7 +1511,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 328f79bb5713abbecaeb0ef3fb37f56a0946b915 -R dade750024fe6ad04559f56926a096ca +P e4aeaa2bc73b57f1ef134cc4f54e2a652a20b5c9 +R 66a24ec1ff987ca240e2459c8e68c102 U mistachkin -Z 8b0930f7f9116d652fcf85daf416c55f +Z c2fe0f98a34be9a6c1038d1c5b4a377d diff --git a/manifest.uuid b/manifest.uuid index 89b707eee1..24ef17190b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e4aeaa2bc73b57f1ef134cc4f54e2a652a20b5c9 \ No newline at end of file +84de17bc688f1df2be1a34420470d1b16f8f4e56 \ No newline at end of file diff --git a/test/speed3.test b/test/speed3.test index 1beaeb74f3..4aa90943ba 100644 --- a/test/speed3.test +++ b/test/speed3.test @@ -105,7 +105,7 @@ proc io_log {db} { puts "Normal : Read $stats2(read), wrote $stats2(write)" } -proc reset_db {} { +proc speed3_reset_db {} { db close sqlite3 db test.db db eval { @@ -117,7 +117,7 @@ proc reset_db {} { } forcedelete test2.db test2.db-journal -reset_db +speed3_reset_db # Set up a database in auto-vacuum mode and create a database schema. # @@ -154,7 +154,7 @@ do_test speed3-0.4 { # Delete all content in a table, one row at a time. # #io_log db -reset_db +speed3_reset_db speed_trial speed3-1.incrvacuum $::NROW row {DELETE FROM main.t1 WHERE 1} speed_trial speed3-1.normal $::NROW row {DELETE FROM aux.t1 WHERE 1} io_log db @@ -164,7 +164,7 @@ io_log db # #db eval {PRAGMA incremental_vacuum(500000)} populate_t1 db -reset_db +speed3_reset_db speed_trial speed3-2.incrvacuum $::NROW row {SELECT c FROM main.t1} speed_trial speed3-2.normal $::NROW row {SELECT c FROM aux.t1} io_log db From 61441c3493d91f377ad1dbc1557ee0d800a4ba90 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 26 Aug 2016 12:00:50 +0000 Subject: [PATCH 0765/1484] Fix a problem in internal function sqlite3OpenTableAndIndices causing an operand of an unrelated VM instruction to be overwritten. Fix for [ef360601]. FossilOrigin-Name: 7090147903337864d54ecfb2cd84a3f823973167 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/insert.c | 10 +++++----- test/delete.test | 14 ++++++++++++++ 4 files changed, 28 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index 62a14c34f4..b1fcb027e7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Rename\sa\stest\sprocedure\sin\s'speed3.test'\sto\savoid\sa\sname\scollision. -D 2016-08-26T04:32:59.825 +C Fix\sa\sproblem\sin\sinternal\sfunction\ssqlite3OpenTableAndIndices\scausing\san\soperand\sof\san\sunrelated\sVM\sinstruction\sto\sbe\soverwritten.\sFix\sfor\s[ef360601]. +D 2016-08-26T12:00:50.136 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5017381e4853b1472e01d5bb926be1268eba429c @@ -346,7 +346,7 @@ F src/global.c c45ea22aff29334f6a9ec549235ac3357c970015 F src/hash.c 55b5fb474100cee0b901edaf203e26c970940f36 F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4 F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da -F src/insert.c a255eb795cf475e7a0659297144fc80f70eb4e30 +F src/insert.c 3edb5a1bda44df13531fedfcde5fbcc2fc04c222 F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e F src/loadext.c dd7a2b77902cc66c22555aef02e1a682554b7aec F src/main.c 0bfcf1a5b612dddb4dd0fd04b53ef08ace0f48ff @@ -625,7 +625,7 @@ F test/date.test 984ac1e3e5e031386866f034006148d3972b4a65 F test/dbstatus.test 73149851b3aff14fc6db478e58f9083a66422cf5 F test/dbstatus2.test e93ab03bfae6d62d4d935f20de928c19ca0ed0ab F test/default.test 0cb49b1c315a0d81c81d775e407f66906a2a604d -F test/delete.test e1bcdf8926234e27aac24b346ad83d3329ec8b6f +F test/delete.test acc38fca8ee4851467705b1c2cfea64cd26667e5 F test/delete2.test 3a03f2cca1f9a67ec469915cb8babd6485db43fa F test/delete3.test 555e84a00a99230b7d049d477a324a631126a6ab F test/delete4.test 21d2113217eeaacac2d99defe14fe6611615ae86 @@ -1511,7 +1511,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e4aeaa2bc73b57f1ef134cc4f54e2a652a20b5c9 -R 66a24ec1ff987ca240e2459c8e68c102 -U mistachkin -Z c2fe0f98a34be9a6c1038d1c5b4a377d +P 84de17bc688f1df2be1a34420470d1b16f8f4e56 +R 02c9439418cd024199aa5b773e0f5efc +U dan +Z 9ffa92187a35e8ff63e92d723d120b65 diff --git a/manifest.uuid b/manifest.uuid index 24ef17190b..f2e7e86c6d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -84de17bc688f1df2be1a34420470d1b16f8f4e56 \ No newline at end of file +7090147903337864d54ecfb2cd84a3f823973167 \ No newline at end of file diff --git a/src/insert.c b/src/insert.c index caab0f1d65..f7dec3ca24 100644 --- a/src/insert.c +++ b/src/insert.c @@ -1781,15 +1781,15 @@ int sqlite3OpenTableAndIndices( for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){ int iIdxCur = iBase++; assert( pIdx->pSchema==pTab->pSchema ); + if( IsPrimaryKeyIndex(pIdx) && !HasRowid(pTab) ){ + if( piDataCur ) *piDataCur = iIdxCur; + p5 = 0; + } if( aToOpen==0 || aToOpen[i+1] ){ sqlite3VdbeAddOp3(v, op, iIdxCur, pIdx->tnum, iDb); sqlite3VdbeSetP4KeyInfo(pParse, pIdx); - VdbeComment((v, "%s", pIdx->zName)); - } - if( IsPrimaryKeyIndex(pIdx) && !HasRowid(pTab) ){ - if( piDataCur ) *piDataCur = iIdxCur; - }else{ sqlite3VdbeChangeP5(v, p5); + VdbeComment((v, "%s", pIdx->zName)); } } if( iBase>pParse->nTab ) pParse->nTab = iBase; diff --git a/test/delete.test b/test/delete.test index d2dc106495..8e84ed4665 100644 --- a/test/delete.test +++ b/test/delete.test @@ -389,5 +389,19 @@ do_test delete-9.5 { set res } {1 a b 1 c d 2 a b 2 c d} +do_execsql_test delete-10.0 { + CREATE TABLE t1(a INT UNIQUE, b INT); + INSERT INTO t1(a,b) VALUES('1','2'); + SELECT * FROM t1 WHERE a='1' AND b='2'; +} {1 2} + +do_execsql_test delete-10.1 { + DELETE FROM t1 WHERE a='1' AND b='2'; +} + +do_execsql_test delete-10.2 { + SELECT * FROM t1 WHERE a='1' AND b='2'; +} + finish_test From 0dfa4f6fcc8b442797dccda5c3409fec20c91b87 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 26 Aug 2016 13:19:49 +0000 Subject: [PATCH 0766/1484] Allow ROWID values in indexed vector comparisons. FossilOrigin-Name: b0cc6be4eb81f21b11796e1f14d4412bf21dea6e --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/expr.c | 16 +++++++++------- src/sqliteInt.h | 1 + src/where.c | 4 ++-- 5 files changed, 21 insertions(+), 18 deletions(-) diff --git a/manifest b/manifest index 0ab7cba655..1bca06079a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Comment\simprovements.\s\sPut\sALWAYS\sand\sNEVER\smacros\son\sthree\sunreachable\nbranches. -D 2016-08-26T03:42:57.323 +C Allow\sROWID\svalues\sin\sindexed\svector\scomparisons. +D 2016-08-26T13:19:49.916 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5017381e4853b1472e01d5bb926be1268eba429c @@ -338,7 +338,7 @@ F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7 F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c 76c084f0265f4a3cd1ecf17eee112a94f1ccbc05 -F src/expr.c bca7140549a34c8a71a4cf0605666403af390477 +F src/expr.c 1f2ddbec8bf6de323cc0da3ff73e80b0ad21769d F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c e2be0968c1adc679c87e467aa5b4f167588f38a8 F src/func.c 29cc9acb170ec1387b9f63eb52cd85f8de96c771 @@ -390,7 +390,7 @@ F src/shell.c 79dda477be6c96eba6e952a934957ad36f87acc7 F src/sqlite.h.in 4a030e254e204570444b34bf7d40fb4a5416089e F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae -F src/sqliteInt.h db8aa0c875b1a3cdb26e1cee47662c30a34882fd +F src/sqliteInt.h c9e010a79ab4ed7bdc910a24d8f08f3c6d5f822c F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 @@ -465,7 +465,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 02eeecc265f6ffd0597378f5d8ae9070b62a406a F src/wal.h 6dd221ed384afdc204bc61e25c23ef7fd5a511f2 F src/walker.c 2d2cc7fb0f320f7f415215d7247f3c584141ac09 -F src/where.c 2f60a506364b22c48371b8b94089c4028a694a0a +F src/where.c bad93f9bc5e62c38d2e0d2f572dd01d359c8d4cb F src/whereInt.h 14dd243e13b81cbb0a66063d38b70f93a7d6e613 F src/wherecode.c 5a5528c39be09593cada6ae465d7a0f48db0077f F src/whereexpr.c 7f9ada866d48d15d09754ae819c1c40efe3b2aff @@ -1521,7 +1521,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 9d96f61481704e5ec399ee425f0ebb246902ecc5 -R 0b547643c3844e6bc7fc81ff0189aeeb +P 397617009e07004596476d6f5644fdf84c376f54 +R bebe23f740f385ed54a0790b48a77a67 U drh -Z e947ea7de839ffcabb8c6e9f9aa97cfb +Z b30339a1eb9e7f2b74488db2fab0ab4b diff --git a/manifest.uuid b/manifest.uuid index 559f8ba56e..f2f928f54a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -397617009e07004596476d6f5644fdf84c376f54 \ No newline at end of file +b0cc6be4eb81f21b11796e1f14d4412bf21dea6e \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index f0670799e8..a62538c556 100644 --- a/src/expr.c +++ b/src/expr.c @@ -18,6 +18,13 @@ static void exprCodeBetween(Parse*,Expr*,int,void(*)(Parse*,Expr*,int,int),int); static int exprCodeVector(Parse *pParse, Expr *p, int *piToFree); +/* +** Return the affinity character for a single column of a table. +*/ +char sqlite3TableColumnAffinity(Table *pTab, int iCol){ + assert( iColnCol ); + return iCol>=0 ? pTab->aCol[iCol].affinity : SQLITE_AFF_INTEGER; +} /* ** Return the 'affinity' of the expression pExpr if any. @@ -52,11 +59,7 @@ char sqlite3ExprAffinity(Expr *pExpr){ } #endif if( op==TK_AGG_COLUMN || op==TK_COLUMN ){ - int j = pExpr->iColumn; - assert( pExpr->pTab!=0 ); - if( j<0 ) return SQLITE_AFF_INTEGER; - assert( pExpr->pTab && jpTab->nCol ); - return pExpr->pTab->aCol[j].affinity; + return sqlite3TableColumnAffinity(pExpr->pTab, pExpr->iColumn); } return pExpr->affinity; } @@ -2173,7 +2176,7 @@ int sqlite3FindInIndex( for(i=0; ipLeft, i); int iCol = pEList->a[i].pExpr->iColumn; - char idxaff = pTab->aCol[iCol].affinity; /* RHS table affinity */ + char idxaff = sqlite3TableColumnAffinity(pTab,iCol); /* RHS table */ char cmpaff = sqlite3CompareAffinity(pLhs, idxaff); testcase( cmpaff==SQLITE_AFF_BLOB ); testcase( cmpaff==SQLITE_AFF_TEXT ); @@ -2208,7 +2211,6 @@ int sqlite3FindInIndex( CollSeq *pReq = sqlite3BinaryCompareCollSeq(pParse, pLhs, pRhs); int j; - assert( pReq || pParse->nErr ); if( pReq==0 ) break; for(j=0; jpTable->aCol[pLhs->iColumn].affinity; + idxaff = sqlite3TableColumnAffinity(pIdx->pTable, pLhs->iColumn); if( aff!=idxaff ) break; pColl = sqlite3BinaryCompareCollSeq(pParse, pLhs, pRhs); - if( NEVER(pColl==0) ) break; + if( pColl==0 ) break; if( sqlite3StrICmp(pColl->zName, pIdx->azColl[i+nEq]) ) break; } return i; From b7ca2177d7ddcf5dbf06d1b210fa92750324249b Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 26 Aug 2016 17:54:46 +0000 Subject: [PATCH 0767/1484] Fix a problem with affinity changes and vector range comparisons. FossilOrigin-Name: b34413ac7e34369b4420e57b0132249dca68a7b0 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/wherecode.c | 50 +++++++++++++++++++++++++++++++++---------------- 3 files changed, 42 insertions(+), 24 deletions(-) diff --git a/manifest b/manifest index 1bca06079a..cb2c5f28b5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Allow\sROWID\svalues\sin\sindexed\svector\scomparisons. -D 2016-08-26T13:19:49.916 +C Fix\sa\sproblem\swith\saffinity\schanges\sand\svector\srange\scomparisons. +D 2016-08-26T17:54:46.350 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5017381e4853b1472e01d5bb926be1268eba429c @@ -467,7 +467,7 @@ F src/wal.h 6dd221ed384afdc204bc61e25c23ef7fd5a511f2 F src/walker.c 2d2cc7fb0f320f7f415215d7247f3c584141ac09 F src/where.c bad93f9bc5e62c38d2e0d2f572dd01d359c8d4cb F src/whereInt.h 14dd243e13b81cbb0a66063d38b70f93a7d6e613 -F src/wherecode.c 5a5528c39be09593cada6ae465d7a0f48db0077f +F src/wherecode.c 71de4d2d36fa3afe6160e98334f1a717c226ee86 F src/whereexpr.c 7f9ada866d48d15d09754ae819c1c40efe3b2aff F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -1521,7 +1521,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 397617009e07004596476d6f5644fdf84c376f54 -R bebe23f740f385ed54a0790b48a77a67 -U drh -Z b30339a1eb9e7f2b74488db2fab0ab4b +P b0cc6be4eb81f21b11796e1f14d4412bf21dea6e +R 0bd9bba299be3b1c19235baf0c5a546b +U dan +Z 7b1a4a5a11db26063e955544de8c89fc diff --git a/manifest.uuid b/manifest.uuid index f2f928f54a..ab39b9341f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b0cc6be4eb81f21b11796e1f14d4412bf21dea6e \ No newline at end of file +b34413ac7e34369b4420e57b0132249dca68a7b0 \ No newline at end of file diff --git a/src/wherecode.c b/src/wherecode.c index 65079872e1..34894fe1bb 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -350,6 +350,32 @@ static void codeApplyAffinity(Parse *pParse, int base, int n, char *zAff){ } } +/* +** Expression pRight, which is the RHS of a comparison operation, is +** either a vector of n elements or, if n==1, a scalar expression. +** Before the comparison operation, affinity zAff is to be applied +** to the pRight values. This function modifies characters within the +** affinity string to SQLITE_AFF_BLOB if either: +** +** * the comparison will be performed with no affinity, or +** * the affinity change in zAff is guaranteed not to change the value. +*/ +static void updateRangeAffinityStr( + Parse *pParse, /* Parse context */ + Expr *pRight, /* RHS of comparison */ + int n, /* Number of vector elements in comparison */ + char *zAff /* Affinity string to modify */ +){ + int i; + for(i=0; i=nEq ); - if( zStartAff ) cEndAff = zStartAff[nEq]; + if( zStartAff && nTop ){ + zEndAff = sqlite3DbStrDup(db, &zStartAff[nEq]); + } addrNxt = pLevel->addrNxt; testcase( pRangeStart && (pRangeStart->eOperator & WO_LE)!=0 ); @@ -1441,15 +1469,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( VdbeCoverage(v); } if( zStartAff ){ - if( sqlite3CompareAffinity(pRight, zStartAff[nEq])==SQLITE_AFF_BLOB){ - /* Since the comparison is to be performed with no conversions - ** applied to the operands, set the affinity to apply to pRight to - ** SQLITE_AFF_BLOB. */ - zStartAff[nEq] = SQLITE_AFF_BLOB; - } - if( sqlite3ExprNeedsNoAffinityChange(pRight, zStartAff[nEq]) ){ - zStartAff[nEq] = SQLITE_AFF_BLOB; - } + updateRangeAffinityStr(pParse, pRight, nBtm, &zStartAff[nEq]); } nConstraint += nBtm; testcase( pRangeStart->wtFlags & TERM_VIRTUAL ); @@ -1498,11 +1518,8 @@ Bitmask sqlite3WhereCodeOneLoopStart( sqlite3VdbeAddOp2(v, OP_IsNull, regBase+nEq, addrNxt); VdbeCoverage(v); } - if( sqlite3CompareAffinity(pRight, cEndAff)!=SQLITE_AFF_BLOB - && !sqlite3ExprNeedsNoAffinityChange(pRight, cEndAff) - ){ - codeApplyAffinity(pParse, regBase+nEq, 1, &cEndAff); - } + updateRangeAffinityStr(pParse, pRight, nTop, zEndAff); + codeApplyAffinity(pParse, regBase+nEq, nTop, zEndAff); nConstraint += nTop; testcase( pRangeEnd->wtFlags & TERM_VIRTUAL ); @@ -1517,6 +1534,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( nConstraint++; } sqlite3DbFree(db, zStartAff); + sqlite3DbFree(db, zEndAff); /* Top of the loop body */ pLevel->p2 = sqlite3VdbeCurrentAddr(v); From 0c36fca004ee51ef626a3df0e74d191fbdc609fe Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 26 Aug 2016 18:17:08 +0000 Subject: [PATCH 0768/1484] Fix a post-OOM crash in updateRangeAffinityStr(). Add several ALWAYS() macros on unreachable branches. FossilOrigin-Name: 87d40195ae5cc2abd9bae45073a615db81263285 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/where.c | 1 + src/wherecode.c | 12 ++++++++---- 4 files changed, 18 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index cb2c5f28b5..59c570e2f8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\swith\saffinity\schanges\sand\svector\srange\scomparisons. -D 2016-08-26T17:54:46.350 +C Fix\sa\spost-OOM\scrash\sin\supdateRangeAffinityStr().\s\sAdd\sseveral\sALWAYS()\nmacros\son\sunreachable\sbranches. +D 2016-08-26T18:17:08.713 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5017381e4853b1472e01d5bb926be1268eba429c @@ -465,9 +465,9 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 02eeecc265f6ffd0597378f5d8ae9070b62a406a F src/wal.h 6dd221ed384afdc204bc61e25c23ef7fd5a511f2 F src/walker.c 2d2cc7fb0f320f7f415215d7247f3c584141ac09 -F src/where.c bad93f9bc5e62c38d2e0d2f572dd01d359c8d4cb +F src/where.c 48d705e5196a0611a7be90698eade455ee238536 F src/whereInt.h 14dd243e13b81cbb0a66063d38b70f93a7d6e613 -F src/wherecode.c 71de4d2d36fa3afe6160e98334f1a717c226ee86 +F src/wherecode.c ee7b5353ff5f63548c206e3ecb4423ff0857d766 F src/whereexpr.c 7f9ada866d48d15d09754ae819c1c40efe3b2aff F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -1521,7 +1521,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b0cc6be4eb81f21b11796e1f14d4412bf21dea6e -R 0bd9bba299be3b1c19235baf0c5a546b -U dan -Z 7b1a4a5a11db26063e955544de8c89fc +P b34413ac7e34369b4420e57b0132249dca68a7b0 +R e94f28a1c30d92b873747a9f1cb33b94 +U drh +Z a3a8a387b6b2455df60af55b1e2df964 diff --git a/manifest.uuid b/manifest.uuid index ab39b9341f..1ac92a55f8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b34413ac7e34369b4420e57b0132249dca68a7b0 \ No newline at end of file +87d40195ae5cc2abd9bae45073a615db81263285 \ No newline at end of file diff --git a/src/where.c b/src/where.c index 5c004ca0c2..f60d5be6da 100644 --- a/src/where.c +++ b/src/where.c @@ -2260,6 +2260,7 @@ int whereRangeVectorLen( break; } + testcase( pLhs->iColumn==XN_ROWID ); aff = sqlite3CompareAffinity(pRhs, sqlite3ExprAffinity(pLhs)); idxaff = sqlite3TableColumnAffinity(pIdx->pTable, pLhs->iColumn); if( aff!=idxaff ) break; diff --git a/src/wherecode.c b/src/wherecode.c index 34894fe1bb..16ffb89db1 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -294,7 +294,7 @@ void sqlite3WhereAddScanStatus( */ static void disableTerm(WhereLevel *pLevel, WhereTerm *pTerm){ int nLoop = 0; - while( pTerm + while( ALWAYS(pTerm!=0) && (pTerm->wtFlags & TERM_CODED)==0 && (pLevel->iLeftJoin==0 || ExprHasProperty(pTerm->pExpr, EP_FromJoin)) && (pLevel->notReady & pTerm->prereqAll)==0 @@ -435,7 +435,7 @@ static int codeEqualityTerm( } } for(i=iEq;inLTerm; i++){ - if( pLoop->aLTerm[i] && pLoop->aLTerm[i]->pExpr==pX ) nEq++; + if( ALWAYS(pLoop->aLTerm[i]) && pLoop->aLTerm[i]->pExpr==pX ) nEq++; } if( nEq>1 ){ @@ -1518,8 +1518,12 @@ Bitmask sqlite3WhereCodeOneLoopStart( sqlite3VdbeAddOp2(v, OP_IsNull, regBase+nEq, addrNxt); VdbeCoverage(v); } - updateRangeAffinityStr(pParse, pRight, nTop, zEndAff); - codeApplyAffinity(pParse, regBase+nEq, nTop, zEndAff); + if( zEndAff ){ + updateRangeAffinityStr(pParse, pRight, nTop, zEndAff); + codeApplyAffinity(pParse, regBase+nEq, nTop, zEndAff); + }else{ + assert( pParse->db->mallocFailed ); + } nConstraint += nTop; testcase( pRangeEnd->wtFlags & TERM_VIRTUAL ); From 6fc8f364908faf289d19ebd349c0a4c2995bcd95 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 26 Aug 2016 19:31:29 +0000 Subject: [PATCH 0769/1484] Enhance sqlite3FindInIndex() so that it is able to make use of the primary keys at the end of an index. FossilOrigin-Name: 4b589fbfcc4265902de0f552961d2df497a184da --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/expr.c | 24 ++++++++++++++---------- 3 files changed, 21 insertions(+), 17 deletions(-) diff --git a/manifest b/manifest index 59c570e2f8..55a6113c35 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\spost-OOM\scrash\sin\supdateRangeAffinityStr().\s\sAdd\sseveral\sALWAYS()\nmacros\son\sunreachable\sbranches. -D 2016-08-26T18:17:08.713 +C Enhance\ssqlite3FindInIndex()\sso\sthat\sit\sis\sable\sto\smake\suse\sof\sthe\nprimary\skeys\sat\sthe\send\sof\san\sindex. +D 2016-08-26T19:31:29.011 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5017381e4853b1472e01d5bb926be1268eba429c @@ -338,7 +338,7 @@ F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7 F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c 76c084f0265f4a3cd1ecf17eee112a94f1ccbc05 -F src/expr.c 1f2ddbec8bf6de323cc0da3ff73e80b0ad21769d +F src/expr.c 192dac6da7ff380fde35861d3f9d40bab39fab2c F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c e2be0968c1adc679c87e467aa5b4f167588f38a8 F src/func.c 29cc9acb170ec1387b9f63eb52cd85f8de96c771 @@ -1521,7 +1521,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b34413ac7e34369b4420e57b0132249dca68a7b0 -R e94f28a1c30d92b873747a9f1cb33b94 +P 87d40195ae5cc2abd9bae45073a615db81263285 +R c0ed51d5af8253a23448fcfb693a50e8 U drh -Z a3a8a387b6b2455df60af55b1e2df964 +Z 3b9104524847b85ed5a08921e98408a8 diff --git a/manifest.uuid b/manifest.uuid index 1ac92a55f8..3562568838 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -87d40195ae5cc2abd9bae45073a615db81263285 \ No newline at end of file +4b589fbfcc4265902de0f552961d2df497a184da \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index a62538c556..3a5075719e 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2099,11 +2099,11 @@ static int sqlite3InRhsIsConstant(Expr *pIn){ */ #ifndef SQLITE_OMIT_SUBQUERY int sqlite3FindInIndex( - Parse *pParse, - Expr *pX, - u32 inFlags, - int *prRhsHasNull, - int *aiMap + Parse *pParse, /* Parsing context */ + Expr *pX, /* The right-hand side (RHS) of the IN operator */ + u32 inFlags, /* IN_INDEX_LOOP, _MEMBERSHIP, and/or _NOOP_OK */ + int *prRhsHasNull, /* Register holding NULL status. See notes */ + int *aiMap /* Mapping from Index fields to RHS fields */ ){ Select *p; /* SELECT to the right of IN operator */ int eType = 0; /* Type of RHS table. IN_INDEX_* */ @@ -2200,9 +2200,13 @@ int sqlite3FindInIndex( ** to this collation sequence. */ for(pIdx=pTab->pIndex; pIdx && eType==0 && affinity_ok; pIdx=pIdx->pNext){ - if( pIdx->nKeyColnKeyCol!=nExpr || !IsUniqueIndex(pIdx)) ){ - continue; + if( pIdx->nColumnnKeyCol>nExpr + ||(pIdx->nColumn>nExpr && !IsUniqueIndex(pIdx)) + ){ + continue; + } } for(i=0; iiColumn==XN_ROWID || pParse->nErr ); for(j=0; jaiColumn[j]!=pRhs->iColumn ) continue; assert( pIdx->azColl[j] ); + if( pReq==0 ) continue; if( sqlite3StrICmp(pReq->zName, pIdx->azColl[j])!=0 ) continue; break; } From 4b4f51148ae48c263027f2c269ff53e6bea1b8d9 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 26 Aug 2016 19:47:30 +0000 Subject: [PATCH 0770/1484] Add test cases to rowvalue2.test. FossilOrigin-Name: 078bb69e99891ba3b76a39ac974990714c43908f --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/rowvalue2.test | 28 ++++++++++++++++++++++++++++ 3 files changed, 36 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 55a6113c35..8bf9f54ae7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\ssqlite3FindInIndex()\sso\sthat\sit\sis\sable\sto\smake\suse\sof\sthe\nprimary\skeys\sat\sthe\send\sof\san\sindex. -D 2016-08-26T19:31:29.011 +C Add\stest\scases\sto\srowvalue2.test. +D 2016-08-26T19:47:30.838 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5017381e4853b1472e01d5bb926be1268eba429c @@ -1021,7 +1021,7 @@ F test/rowallock.test 3f88ec6819489d0b2341c7a7528ae17c053ab7cc F test/rowhash.test 0bc1d31415e4575d10cacf31e1a66b5cc0f8be81 F test/rowid.test 5b7509f384f4f6fae1af3c8c104c8ca299fea18d F test/rowvalue.test 7d8482dde9023973615eaaca65647f33d70c1f01 -F test/rowvalue2.test 875068299fd4dd50ef0a47786462c8e1f4065f9a +F test/rowvalue2.test 060d238b7e5639a7c5630cb5e63e311b44efef2b F test/rowvalue3.test 01399b7bf150b0d41abce76c18072da777c2500c F test/rowvalue4.test 9b40c9be9bdde30fc66cddbfdf6a5af37de4ccac F test/rowvalue5.test a440d490c8c0bf606034c09d5c6bbf7840b98f95 @@ -1521,7 +1521,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 87d40195ae5cc2abd9bae45073a615db81263285 -R c0ed51d5af8253a23448fcfb693a50e8 -U drh -Z 3b9104524847b85ed5a08921e98408a8 +P 4b589fbfcc4265902de0f552961d2df497a184da +R 2639cfd9d35718211068678a56d30d2c +U dan +Z 1bf9a10eeccbff62da890e6c842f5df6 diff --git a/manifest.uuid b/manifest.uuid index 3562568838..54b588e6c5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4b589fbfcc4265902de0f552961d2df497a184da \ No newline at end of file +078bb69e99891ba3b76a39ac974990714c43908f \ No newline at end of file diff --git a/test/rowvalue2.test b/test/rowvalue2.test index b385b23ce2..1502e31a54 100644 --- a/test/rowvalue2.test +++ b/test/rowvalue2.test @@ -247,5 +247,33 @@ foreach {tn idx} { } } +do_execsql_test 5.0 { + CREATE TABLE r1(a TEXT, iB TEXT); + CREATE TABLE r2(x TEXT, zY INTEGER); + CREATE INDEX r1ab ON r1(a, iB); + + INSERT INTO r1 VALUES(35, 35); + INSERT INTO r2 VALUES(35, 36); + INSERT INTO r2 VALUES(35, 4); + INSERT INTO r2 VALUES(35, 35); +} {} + +foreach {tn lhs rhs} { + 1 {x +zY} {a iB} + 2 {x zY} {a iB} + 3 {x zY} {a +iB} + 4 {+x zY} {a iB} + 5 {x zY} {+a iB} +} { + foreach op { IS == < <= > >= } { + set e1 [make_expr1 $lhs $rhs $op] + set e2 [make_expr2 $lhs $rhs $op] + do_execsql_test 5.$tn.$op \ + "SELECT * FROM r1, r2 WHERE $e2 ORDER BY iB" [db eval \ + "SELECT * FROM r1, r2 WHERE $e1 ORDER BY iB" + ] + } +} + finish_test From 363fb95bc38825f49317532fe90241a172e1cf45 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 26 Aug 2016 19:54:12 +0000 Subject: [PATCH 0771/1484] Add an EXPLAIN QUERY PLAN line for when a index is used to implement an IN operator. FossilOrigin-Name: 171aa833a2e1650c3d9cf9bd6438ae46f6c35871 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/expr.c | 5 +++++ 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 8bf9f54ae7..e112f421dc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\stest\scases\sto\srowvalue2.test. -D 2016-08-26T19:47:30.838 +C Add\san\sEXPLAIN\sQUERY\sPLAN\sline\sfor\swhen\sa\sindex\sis\sused\sto\simplement\nan\sIN\soperator. +D 2016-08-26T19:54:12.433 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5017381e4853b1472e01d5bb926be1268eba429c @@ -338,7 +338,7 @@ F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7 F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c 76c084f0265f4a3cd1ecf17eee112a94f1ccbc05 -F src/expr.c 192dac6da7ff380fde35861d3f9d40bab39fab2c +F src/expr.c 935366a02ad0c33e7cd19ff382ef9bcdfa1aa7a9 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c e2be0968c1adc679c87e467aa5b4f167588f38a8 F src/func.c 29cc9acb170ec1387b9f63eb52cd85f8de96c771 @@ -1521,7 +1521,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 4b589fbfcc4265902de0f552961d2df497a184da -R 2639cfd9d35718211068678a56d30d2c -U dan -Z 1bf9a10eeccbff62da890e6c842f5df6 +P 078bb69e99891ba3b76a39ac974990714c43908f +R 155df167db2a04d38d0a374ab683c0e3 +U drh +Z d9ed9721b1e3c6348d8b59f53fc4268d diff --git a/manifest.uuid b/manifest.uuid index 54b588e6c5..5d43906475 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -078bb69e99891ba3b76a39ac974990714c43908f \ No newline at end of file +171aa833a2e1650c3d9cf9bd6438ae46f6c35871 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 3a5075719e..08b72fed80 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2229,6 +2229,11 @@ int sqlite3FindInIndex( if( i==nExpr ){ int iAddr = sqlite3CodeOnce(pParse); VdbeCoverage(v); +#ifndef SQLITE_OMIT_EXPLAIN + sqlite3VdbeAddOp4(v, OP_Explain, 0, 0, 0, + sqlite3MPrintf(db, "USING INDEX %s FOR IN-OPERATOR", pIdx->zName), + P4_DYNAMIC); +#endif sqlite3VdbeAddOp3(v, OP_OpenRead, iTab, pIdx->tnum, iDb); sqlite3VdbeSetP4KeyInfo(pParse, pIdx); VdbeComment((v, "%s", pIdx->zName)); From a84a283d180a4ffa54b1fb615572709dfe0f7b25 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 26 Aug 2016 21:15:35 +0000 Subject: [PATCH 0772/1484] Fix the sqlite3FindInIndex() to ensure that it always uses a prefix of the index and uses no repeated columns. Enhanced comments. FossilOrigin-Name: b9fc89e432fbe4e5b41959a42797641907e075e3 --- manifest | 12 ++--- manifest.uuid | 2 +- src/expr.c | 137 ++++++++++++++++++++++++++------------------------ 3 files changed, 79 insertions(+), 72 deletions(-) diff --git a/manifest b/manifest index e112f421dc..05accaa53d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\san\sEXPLAIN\sQUERY\sPLAN\sline\sfor\swhen\sa\sindex\sis\sused\sto\simplement\nan\sIN\soperator. -D 2016-08-26T19:54:12.433 +C Fix\sthe\ssqlite3FindInIndex()\sto\sensure\sthat\sit\salways\suses\sa\sprefix\sof\nthe\sindex\sand\suses\sno\srepeated\scolumns.\s\sEnhanced\scomments. +D 2016-08-26T21:15:35.199 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5017381e4853b1472e01d5bb926be1268eba429c @@ -338,7 +338,7 @@ F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7 F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c 76c084f0265f4a3cd1ecf17eee112a94f1ccbc05 -F src/expr.c 935366a02ad0c33e7cd19ff382ef9bcdfa1aa7a9 +F src/expr.c 4c80148f83127862f69ff509fb0aa261396df24e F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c e2be0968c1adc679c87e467aa5b4f167588f38a8 F src/func.c 29cc9acb170ec1387b9f63eb52cd85f8de96c771 @@ -1521,7 +1521,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 078bb69e99891ba3b76a39ac974990714c43908f -R 155df167db2a04d38d0a374ab683c0e3 +P 171aa833a2e1650c3d9cf9bd6438ae46f6c35871 +R 94dfe8764b4b5e69457ee17a8ecdc781 U drh -Z d9ed9721b1e3c6348d8b59f53fc4268d +Z ef81f77fdd077e1b395585c253a1bf6f diff --git a/manifest.uuid b/manifest.uuid index 5d43906475..e5a0ab8485 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -171aa833a2e1650c3d9cf9bd6438ae46f6c35871 \ No newline at end of file +b9fc89e432fbe4e5b41959a42797641907e075e3 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 08b72fed80..8ede47731f 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1960,7 +1960,6 @@ static Select *isCandidateForInOpt(Expr *pX){ if( IsVirtual(pTab) ) return 0; /* FROM clause not a virtual table */ pEList = p->pEList; assert( pEList!=0 ); - /* All SELECT results must be columns. */ for(i=0; inExpr; i++){ Expr *pRes = pEList->a[i].pExpr; @@ -2150,11 +2149,7 @@ int sqlite3FindInIndex( sqlite3CodeVerifySchema(pParse, iDb); sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); - /* This function is only called from two places. In both cases the vdbe - ** has already been allocated. So assume sqlite3GetVdbe() is always - ** successful here. - */ - assert(v); + assert(v); /* sqlite3GetVdbe() has always been previously called */ if( nExpr==1 && pEList->a[0].pExpr->iColumn<0 ){ /* The "x IN (SELECT rowid FROM table)" case */ int iAddr = sqlite3CodeOnce(pParse); @@ -2195,67 +2190,79 @@ int sqlite3FindInIndex( } } - /* The collation sequence used by the comparison. If an index is to - ** be used in place of a temp-table, it must be ordered according - ** to this collation sequence. */ - - for(pIdx=pTab->pIndex; pIdx && eType==0 && affinity_ok; pIdx=pIdx->pNext){ - if( pIdx->nColumnnKeyCol>nExpr - ||(pIdx->nColumn>nExpr && !IsUniqueIndex(pIdx)) - ){ - continue; - } - } - - for(i=0; ipLeft, i); - Expr *pRhs = pEList->a[i].pExpr; - CollSeq *pReq = sqlite3BinaryCompareCollSeq(pParse, pLhs, pRhs); - int j; - - assert( pReq!=0 || pRhs->iColumn==XN_ROWID || pParse->nErr ); - for(j=0; jaiColumn[j]!=pRhs->iColumn ) continue; - assert( pIdx->azColl[j] ); - if( pReq==0 ) continue; - if( sqlite3StrICmp(pReq->zName, pIdx->azColl[j])!=0 ) continue; - break; - } - if( j==nExpr ) break; - if( aiMap ) aiMap[i] = j; - } - - if( i==nExpr ){ - int iAddr = sqlite3CodeOnce(pParse); VdbeCoverage(v); -#ifndef SQLITE_OMIT_EXPLAIN - sqlite3VdbeAddOp4(v, OP_Explain, 0, 0, 0, - sqlite3MPrintf(db, "USING INDEX %s FOR IN-OPERATOR", pIdx->zName), - P4_DYNAMIC); -#endif - sqlite3VdbeAddOp3(v, OP_OpenRead, iTab, pIdx->tnum, iDb); - sqlite3VdbeSetP4KeyInfo(pParse, pIdx); - VdbeComment((v, "%s", pIdx->zName)); - assert( IN_INDEX_INDEX_DESC == IN_INDEX_INDEX_ASC+1 ); - eType = IN_INDEX_INDEX_ASC + pIdx->aSortOrder[0]; - - if( prRhsHasNull ){ - *prRhsHasNull = ++pParse->nMem; -#ifdef SQLITE_ENABLE_COLUMN_USED_MASK - i64 mask = (1<pIndex; pIdx && eType==0; pIdx=pIdx->pNext){ + Bitmask colUsed; /* Columns of the index used */ + Bitmask mCol; /* Mask for the current column */ + if( pIdx->nColumnnColumn==BMS-2 ); + testcase( pIdx->nColumn==BMS-1 ); + if( pIdx->nColumn>=BMS-1 ) continue; + if( mustBeUnique ){ + if( pIdx->nKeyCol>nExpr + ||(pIdx->nColumn>nExpr && !IsUniqueIndex(pIdx)) + ){ + continue; /* This index is not unique over the IN RHS columns */ } } - sqlite3VdbeJumpHere(v, iAddr); - } - } - } - } + + colUsed = 0; /* Columns of index used so far */ + for(i=0; ipLeft, i); + Expr *pRhs = pEList->a[i].pExpr; + CollSeq *pReq = sqlite3BinaryCompareCollSeq(pParse, pLhs, pRhs); + int j; + + assert( pReq!=0 || pRhs->iColumn==XN_ROWID || pParse->nErr ); + for(j=0; jaiColumn[j]!=pRhs->iColumn ) continue; + assert( pIdx->azColl[j] ); + if( pReq==0 ) continue; + if( sqlite3StrICmp(pReq->zName, pIdx->azColl[j])!=0 ) continue; + break; + } + if( j==nExpr ) break; + mCol = MASKBIT(j); + if( mCol & colUsed ) break; /* Each column used only once */ + colUsed |= mCol; + if( aiMap ) aiMap[i] = j; + } + + assert( i==nExpr || colUsed!=(MASKBIT(nExpr)-1) ); + if( colUsed==(MASKBIT(nExpr)-1) ){ + /* If we reach this point, that means the index pIdx is usable */ + int iAddr = sqlite3CodeOnce(pParse); VdbeCoverage(v); + #ifndef SQLITE_OMIT_EXPLAIN + sqlite3VdbeAddOp4(v, OP_Explain, 0, 0, 0, + sqlite3MPrintf(db, "USING INDEX %s FOR IN-OPERATOR",pIdx->zName), + P4_DYNAMIC); + #endif + sqlite3VdbeAddOp3(v, OP_OpenRead, iTab, pIdx->tnum, iDb); + sqlite3VdbeSetP4KeyInfo(pParse, pIdx); + VdbeComment((v, "%s", pIdx->zName)); + assert( IN_INDEX_INDEX_DESC == IN_INDEX_INDEX_ASC+1 ); + eType = IN_INDEX_INDEX_ASC + pIdx->aSortOrder[0]; + + if( prRhsHasNull ){ + *prRhsHasNull = ++pParse->nMem; + #ifdef SQLITE_ENABLE_COLUMN_USED_MASK + i64 mask = (1< Date: Fri, 26 Aug 2016 22:09:01 +0000 Subject: [PATCH 0773/1484] Fix a minor problem in sqlite3FindInIndex() related to rowids being used as part of the index. FossilOrigin-Name: 829f802be7d4647dd815b739bbc9e1d1ac6a224d --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/expr.c | 5 +++-- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 05accaa53d..f0a6286386 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\ssqlite3FindInIndex()\sto\sensure\sthat\sit\salways\suses\sa\sprefix\sof\nthe\sindex\sand\suses\sno\srepeated\scolumns.\s\sEnhanced\scomments. -D 2016-08-26T21:15:35.199 +C Fix\sa\sminor\sproblem\sin\ssqlite3FindInIndex()\srelated\sto\srowids\sbeing\sused\nas\spart\sof\sthe\sindex. +D 2016-08-26T22:09:01.711 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5017381e4853b1472e01d5bb926be1268eba429c @@ -338,7 +338,7 @@ F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7 F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c 76c084f0265f4a3cd1ecf17eee112a94f1ccbc05 -F src/expr.c 4c80148f83127862f69ff509fb0aa261396df24e +F src/expr.c 6ac2955b85fb32934b5505904da3d4be39d5d877 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c e2be0968c1adc679c87e467aa5b4f167588f38a8 F src/func.c 29cc9acb170ec1387b9f63eb52cd85f8de96c771 @@ -1521,7 +1521,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 171aa833a2e1650c3d9cf9bd6438ae46f6c35871 -R 94dfe8764b4b5e69457ee17a8ecdc781 +P b9fc89e432fbe4e5b41959a42797641907e075e3 +R 4de3e6777e68cb197039afe2926927d7 U drh -Z ef81f77fdd077e1b395585c253a1bf6f +Z 2cb9a82dfc67b60efaaa214dda6ee177 diff --git a/manifest.uuid b/manifest.uuid index e5a0ab8485..407491af35 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b9fc89e432fbe4e5b41959a42797641907e075e3 \ No newline at end of file +829f802be7d4647dd815b739bbc9e1d1ac6a224d \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 8ede47731f..8e74fff61b 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2220,8 +2220,9 @@ int sqlite3FindInIndex( for(j=0; jaiColumn[j]!=pRhs->iColumn ) continue; assert( pIdx->azColl[j] ); - if( pReq==0 ) continue; - if( sqlite3StrICmp(pReq->zName, pIdx->azColl[j])!=0 ) continue; + if( pReq!=0 && sqlite3StrICmp(pReq->zName, pIdx->azColl[j])!=0 ){ + continue; + } break; } if( j==nExpr ) break; From 88e665fd0bf40251472a6349faf9e6fbf04b1511 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 27 Aug 2016 01:41:53 +0000 Subject: [PATCH 0774/1484] Fix the "Synopsis" on the OP_Lt, OP_Le, OP_Gt, and OP_Ge opcodes, which has been backwards for time out of mind. FossilOrigin-Name: f51248dcfa22e989dacde41021e96a65f12c5ca8 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 12 ++++++------ 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index f0a6286386..ec178d85bc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sminor\sproblem\sin\ssqlite3FindInIndex()\srelated\sto\srowids\sbeing\sused\nas\spart\sof\sthe\sindex. -D 2016-08-26T22:09:01.711 +C Fix\sthe\s"Synopsis"\son\sthe\sOP_Lt,\sOP_Le,\sOP_Gt,\sand\sOP_Ge\sopcodes,\swhich\nhas\sbeen\sbackwards\sfor\stime\sout\sof\smind. +D 2016-08-27T01:41:53.133 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5017381e4853b1472e01d5bb926be1268eba429c @@ -451,7 +451,7 @@ F src/update.c 8179e699dbd45b92934fd02d3d8e3732e8da8802 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 810ec3f22e2d1b62e66c30fe3621ebdedd23584d F src/vacuum.c 913970b9d86dd6c2b8063ef1af421880f1464ec3 -F src/vdbe.c 68d56c11d5c5e704dde6d2d8748750a2f6352a09 +F src/vdbe.c 4be39068ea1412a21a2566c71007c87b67928d67 F src/vdbe.h 67bc551f7faf04c33493892e4b378aada823ed10 F src/vdbeInt.h c59381049af5c7751a83456c39b80d1a6fde1f9d F src/vdbeapi.c a32d61b7dd05e6890d8fd44d2805f55e2f5ba9f3 @@ -1521,7 +1521,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b9fc89e432fbe4e5b41959a42797641907e075e3 -R 4de3e6777e68cb197039afe2926927d7 +P 829f802be7d4647dd815b739bbc9e1d1ac6a224d +R 90bb9a2e80849dad7e38b09045c0c98d U drh -Z 2cb9a82dfc67b60efaaa214dda6ee177 +Z ce5881477602b96772cc87ff99cdf3de diff --git a/manifest.uuid b/manifest.uuid index 407491af35..cc0a3022ca 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -829f802be7d4647dd815b739bbc9e1d1ac6a224d \ No newline at end of file +f51248dcfa22e989dacde41021e96a65f12c5ca8 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 24828ace3b..b640e0b4f5 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -1881,7 +1881,7 @@ case OP_Cast: { /* in1 */ #endif /* SQLITE_OMIT_CAST */ /* Opcode: Eq P1 P2 P3 P4 P5 -** Synopsis: IF r[P1]==r[P3] +** Synopsis: IF r[P3]==r[P1] ** ** Compare the values in register P1 and P3. If reg(P3)==reg(P1) then ** jump to address P2. Or if the SQLITE_STOREP2 flag is set in P5, then @@ -1915,7 +1915,7 @@ case OP_Cast: { /* in1 */ ** content of r[P2] is only set to 1 (true) if it was not previously NULL. */ /* Opcode: Ne P1 P2 P3 P4 P5 -** Synopsis: IF r[P1]!=r[P3] +** Synopsis: IF r[P3]!=r[P1] ** ** This works just like the Eq opcode except that the jump is taken if ** the operands in registers P1 and P3 are not equal. See the Eq opcode for @@ -1925,7 +1925,7 @@ case OP_Cast: { /* in1 */ ** content of r[P2] is only set to 0 (false) if it was not previously NULL. */ /* Opcode: Lt P1 P2 P3 P4 P5 -** Synopsis: IF r[P1]r[P3] +** Synopsis: IF r[P3]>r[P1] ** ** This works just like the Lt opcode except that the jump is taken if ** the content of register P3 is greater than the content of ** register P1. See the Lt opcode for additional information. */ /* Opcode: Ge P1 P2 P3 P4 P5 -** Synopsis: IF r[P1]>=r[P3] +** Synopsis: IF r[P3]>=r[P1] ** ** This works just like the Lt opcode except that the jump is taken if ** the content of register P3 is greater than or equal to the content of From 1ad78c57914956c8ae2da2549b1af9d4e7f58f8a Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 27 Aug 2016 14:05:12 +0000 Subject: [PATCH 0775/1484] Fix the extra comments (added with -DSQLITE_ENABLE_EXPLAIN_COMMENTS) so that the sense of <, <=, >, and >= tests is correct and so that the SQLITE_STOREP2 version is shown correctly. These changes are already in the rowvalue branch but are added here since they are technically unrelated to rowvalue. FossilOrigin-Name: 4d43c4698eef4e3db7556813f0274b4018c7c2b9 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/vdbe.c | 12 ++++++------ src/vdbeaux.c | 9 +++++++++ 4 files changed, 24 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index b1fcb027e7..d84e65cf09 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\sin\sinternal\sfunction\ssqlite3OpenTableAndIndices\scausing\san\soperand\sof\san\sunrelated\sVM\sinstruction\sto\sbe\soverwritten.\sFix\sfor\s[ef360601]. -D 2016-08-26T12:00:50.136 +C Fix\sthe\sextra\scomments\s(added\swith\s-DSQLITE_ENABLE_EXPLAIN_COMMENTS)\sso\sthat\nthe\ssense\sof\s<,\s<=,\s>,\sand\s>=\stests\sis\scorrect\sand\sso\sthat\sthe\nSQLITE_STOREP2\sversion\sis\sshown\scorrectly.\s\sThese\schanges\sare\salready\sin\sthe\nrowvalue\sbranch\sbut\sare\sadded\shere\ssince\sthey\sare\stechnically\sunrelated\sto\nrowvalue. +D 2016-08-27T14:05:12.248 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5017381e4853b1472e01d5bb926be1268eba429c @@ -450,11 +450,11 @@ F src/update.c 8179e699dbd45b92934fd02d3d8e3732e8da8802 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 810ec3f22e2d1b62e66c30fe3621ebdedd23584d F src/vacuum.c 913970b9d86dd6c2b8063ef1af421880f1464ec3 -F src/vdbe.c 15376952b0c5dc0afbac6cd8791579dd19ff0a01 +F src/vdbe.c 751dd0a177615388f95123d723ce82395b938ce9 F src/vdbe.h 67bc551f7faf04c33493892e4b378aada823ed10 F src/vdbeInt.h c59381049af5c7751a83456c39b80d1a6fde1f9d F src/vdbeapi.c a32d61b7dd05e6890d8fd44d2805f55e2f5ba9f3 -F src/vdbeaux.c a32d79aeaa88dc2b97c261172d952d395254a055 +F src/vdbeaux.c 83458783d241cfd6691141c8a105832ee50258e5 F src/vdbeblob.c 3e82a797b60c3b9fed7b8de8c539ca7607874937 F src/vdbemem.c 1ecaa5ee0caff07255f25d04e8dc88befb6f88d1 F src/vdbesort.c 91fda3909326860382b0ca8aa251e609c6a9d62c @@ -1511,7 +1511,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 84de17bc688f1df2be1a34420470d1b16f8f4e56 -R 02c9439418cd024199aa5b773e0f5efc -U dan -Z 9ffa92187a35e8ff63e92d723d120b65 +P 7090147903337864d54ecfb2cd84a3f823973167 +R ad53b888d897b0241520026ffdb78d22 +U drh +Z c3f9980f15e4ee005b5e39955b2d9131 diff --git a/manifest.uuid b/manifest.uuid index f2e7e86c6d..a97e000e26 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7090147903337864d54ecfb2cd84a3f823973167 \ No newline at end of file +4d43c4698eef4e3db7556813f0274b4018c7c2b9 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index d5a5886326..78873ef293 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -1881,7 +1881,7 @@ case OP_Cast: { /* in1 */ #endif /* SQLITE_OMIT_CAST */ /* Opcode: Lt P1 P2 P3 P4 P5 -** Synopsis: if r[P1]r[P3] goto P2 +** Synopsis: IF r[P3]>r[P1] ** ** This works just like the Lt opcode except that the jump is taken if ** the content of register P3 is greater than the content of ** register P1. See the Lt opcode for additional information. */ /* Opcode: Ge P1 P2 P3 P4 P5 -** Synopsis: if r[P1]>=r[P3] goto P2 +** Synopsis: IF r[P3]>=r[P1] ** ** This works just like the Lt opcode except that the jump is taken if ** the content of register P3 is greater than or equal to the content of diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 992fa4db9e..963833cce5 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -1094,12 +1094,21 @@ static int displayComment( const char *zSynopsis; int nOpName; int ii, jj; + char zAlt[50]; zOpName = sqlite3OpcodeName(pOp->opcode); nOpName = sqlite3Strlen30(zOpName); if( zOpName[nOpName+1] ){ int seenCom = 0; char c; zSynopsis = zOpName += nOpName + 1; + if( strncmp(zSynopsis,"IF ",3)==0 ){ + if( pOp->p5 & SQLITE_STOREP2 ){ + sqlite3_snprintf(sizeof(zAlt), zAlt, "r[P2] = (%s)", zSynopsis+3); + }else{ + sqlite3_snprintf(sizeof(zAlt), zAlt, "if %s goto P2", zSynopsis+3); + } + zSynopsis = zAlt; + } for(ii=jj=0; jj Date: Sat, 27 Aug 2016 18:35:55 +0000 Subject: [PATCH 0776/1484] Fix some comments in sqlite3session.h. No changes to code. FossilOrigin-Name: 78cd64e202fcbe9ce69070b0f48ccd0c6b48538d --- ext/session/sqlite3session.h | 10 +++++++--- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/ext/session/sqlite3session.h b/ext/session/sqlite3session.h index 23d9a33aef..140138f36d 100644 --- a/ext/session/sqlite3session.h +++ b/ext/session/sqlite3session.h @@ -727,12 +727,12 @@ int sqlite3changeset_concat( /* -** Changegroup handle. +** CAPI3REF: Changegroup Handle */ typedef struct sqlite3_changegroup sqlite3_changegroup; /* -** CAPI3REF: Combine two or more changesets into a single changeset. +** CAPI3REF: Create A New Changegroup Object ** ** An sqlite3_changegroup object is used to combine two or more changesets ** (or patchsets) into a single changeset (or patchset). A single changegroup @@ -769,6 +769,8 @@ typedef struct sqlite3_changegroup sqlite3_changegroup; int sqlite3changegroup_new(sqlite3_changegroup **pp); /* +** CAPI3REF: Add A Changeset To A Changegroup +** ** Add all changes within the changeset (or patchset) in buffer pData (size ** nData bytes) to the changegroup. ** @@ -844,6 +846,8 @@ int sqlite3changegroup_new(sqlite3_changegroup **pp); int sqlite3changegroup_add(sqlite3_changegroup*, int nData, void *pData); /* +** CAPI3REF: Obtain A Composite Changeset From A Changegroup +** ** Obtain a buffer containing a changeset (or patchset) representing the ** current contents of the changegroup. If the inputs to the changegroup ** were themselves changesets, the output is a changeset. Or, if the @@ -872,7 +876,7 @@ int sqlite3changegroup_output( ); /* -** Delete a changegroup object. +** CAPI3REF: Delete A Changegroup Object */ void sqlite3changegroup_delete(sqlite3_changegroup*); diff --git a/manifest b/manifest index 6ec9fe1671..365264a60f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fixes\sto\sfts5\ssnippet()\sfunction. -D 2016-08-27T18:34:06.238 +C Fix\ssome\scomments\sin\ssqlite3session.h.\sNo\schanges\sto\scode. +D 2016-08-27T18:35:55.201 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5017381e4853b1472e01d5bb926be1268eba429c @@ -301,7 +301,7 @@ F ext/session/session_common.tcl a1293167d14774b5e728836720497f40fe4ea596 F ext/session/sessionfault.test da273f2712b6411e85e71465a1733b8501dbf6f7 F ext/session/sessionfault2.test 04aa0bc9aa70ea43d8de82c4f648db4de1e990b0 F ext/session/sqlite3session.c 37485891b4add26cf61495df193c419f36556a32 -F ext/session/sqlite3session.h 69bf73cfd71e58f2ae5d2aa935b2c1a541aee555 +F ext/session/sqlite3session.h 7b9037818ee61f7429ca83e9866885ca6de5f764 F ext/session/test_session.c 2caed9a659586428c63ca46e4900347b374487d4 F ext/userauth/sqlite3userauth.h 19cb6f0e31316d0ee4afdfb7a85ef9da3333a220 F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04 @@ -1511,7 +1511,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 4d43c4698eef4e3db7556813f0274b4018c7c2b9 b174ed2bde43a1872374ce18b85ac9f067e86fbb -R 1806c129c8fa52174952b67042480d44 +P d464a7b18d212720a4f4e2fa4e204f1aca99c837 +R b7e47d608375b4083f5b5619e523e8d7 U dan -Z 3f2d594eefc4bc080c151857cd7756e9 +Z 37c50abb5bb55673ed9c9ae92f5f1ddb diff --git a/manifest.uuid b/manifest.uuid index aa38fb6b68..af58d2d485 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d464a7b18d212720a4f4e2fa4e204f1aca99c837 \ No newline at end of file +78cd64e202fcbe9ce69070b0f48ccd0c6b48538d \ No newline at end of file From 2e5c5052fd745dce7a09c7bce2c0fc97fcf04316 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 27 Aug 2016 20:21:51 +0000 Subject: [PATCH 0777/1484] Fix typos in comments. No changes to running code. FossilOrigin-Name: a07269f2a0f87e0b736127f528f6caf3b63f9052 --- ext/rbu/sqlite3rbu.h | 2 +- ext/rtree/rtree.c | 2 +- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- src/treeview.c | 2 +- src/vtab.c | 2 +- 6 files changed, 15 insertions(+), 15 deletions(-) diff --git a/ext/rbu/sqlite3rbu.h b/ext/rbu/sqlite3rbu.h index 3f5f29a8e6..12112c14e1 100644 --- a/ext/rbu/sqlite3rbu.h +++ b/ext/rbu/sqlite3rbu.h @@ -104,7 +104,7 @@ ** may also be named data_, where is any sequence ** of zero or more numeric characters (0-9). This can be significant because ** tables within the RBU database are always processed in order sorted by -** name. By judicious selection of the the portion of the names +** name. By judicious selection of the portion of the names ** of the RBU tables the user can therefore control the order in which they ** are processed. This can be useful, for example, to ensure that "external ** content" FTS4 tables are updated before their underlying content tables. diff --git a/ext/rtree/rtree.c b/ext/rtree/rtree.c index fc69acd6fa..2301e6816f 100644 --- a/ext/rtree/rtree.c +++ b/ext/rtree/rtree.c @@ -1542,7 +1542,7 @@ static int rtreeFilter( if( idxNum==1 ){ /* Special case - lookup by rowid. */ RtreeNode *pLeaf; /* Leaf on which the required cell resides */ - RtreeSearchPoint *p; /* Search point for the the leaf */ + RtreeSearchPoint *p; /* Search point for the leaf */ i64 iRowid = sqlite3_value_int64(argv[0]); i64 iNode = 0; rc = findLeafNode(pRtree, iRowid, &pLeaf, &iNode); diff --git a/manifest b/manifest index 365264a60f..669a25cf06 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\ssome\scomments\sin\ssqlite3session.h.\sNo\schanges\sto\scode. -D 2016-08-27T18:35:55.201 +C Fix\stypos\sin\scomments.\s\sNo\schanges\sto\srunning\scode. +D 2016-08-27T20:21:51.309 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5017381e4853b1472e01d5bb926be1268eba429c @@ -255,10 +255,10 @@ F ext/rbu/rbusave.test 0f43b6686084f426ddd040b878426452fd2c2f48 F ext/rbu/rbuvacuum.test 4a977447c15c2581ab668781d9ef4294382530e0 F ext/rbu/rbuvacuum2.test 2569205b74ff40fbf3bda2fce33a58eb40eebdcc F ext/rbu/sqlite3rbu.c e074c38798b90591f7f0cf0032d62f152ce5a95e -F ext/rbu/sqlite3rbu.h 1d91c5b7d066645bd1ff8e4b85c2b9b5dd29fb05 +F ext/rbu/sqlite3rbu.h 6fb6294c34a9ca93b5894a33bca530c6f08decba F ext/rbu/test_rbu.c 5aa22616afac6f71ebd3d9bc9bf1006cfabcca88 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 -F ext/rtree/rtree.c d26a815b0df1c412a6881dae8d7fd3c9c08cce68 +F ext/rtree/rtree.c 0b450226001c8ae4622e382b2aff79127581a763 F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e F ext/rtree/rtree1.test 42dadfc7b44a436cd74a1bebc0b9b689e4eaf7ec F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba @@ -444,7 +444,7 @@ F src/test_windirent.h 7edc57e2faa727026dbd5d010dd0e2e665d5aa01 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c 78c8085bc7af1922aa687f0f4bbd716821330de5 -F src/treeview.c c56d6ddbed564efda746236b35bcbb8238daac4b +F src/treeview.c 70329ef46b86f94b16a98aacced793e0692217b5 F src/trigger.c 11e20b3b12c847b3b9055594c0f1631266bb53fc F src/update.c 8179e699dbd45b92934fd02d3d8e3732e8da8802 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c @@ -459,7 +459,7 @@ F src/vdbeblob.c 3e82a797b60c3b9fed7b8de8c539ca7607874937 F src/vdbemem.c 1ecaa5ee0caff07255f25d04e8dc88befb6f88d1 F src/vdbesort.c 91fda3909326860382b0ca8aa251e609c6a9d62c F src/vdbetrace.c 41963d5376f0349842b5fc4aaaaacd7d9cdc0834 -F src/vtab.c 5ca4fa8b028f9e2ed4793ee1670911a83cfcefd8 +F src/vtab.c e02cacb5c7ae742631edeb9ae9f53d399f093fd8 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 02eeecc265f6ffd0597378f5d8ae9070b62a406a F src/wal.h 6dd221ed384afdc204bc61e25c23ef7fd5a511f2 @@ -1511,7 +1511,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d464a7b18d212720a4f4e2fa4e204f1aca99c837 -R b7e47d608375b4083f5b5619e523e8d7 -U dan -Z 37c50abb5bb55673ed9c9ae92f5f1ddb +P 78cd64e202fcbe9ce69070b0f48ccd0c6b48538d +R 3fe3d686aa6a61df97c243454c02cd64 +U drh +Z 90feb3c09ae2ca31e13afbfbff662667 diff --git a/manifest.uuid b/manifest.uuid index af58d2d485..640141a0eb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -78cd64e202fcbe9ce69070b0f48ccd0c6b48538d \ No newline at end of file +a07269f2a0f87e0b736127f528f6caf3b63f9052 \ No newline at end of file diff --git a/src/treeview.c b/src/treeview.c index 27996d46d7..4382c3ca25 100644 --- a/src/treeview.c +++ b/src/treeview.c @@ -120,7 +120,7 @@ void sqlite3TreeViewWith(TreeView *pView, const With *pWith, u8 moreToFollow){ /* -** Generate a human-readable description of a the Select object. +** Generate a human-readable description of a Select object. */ void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){ int n = 0; diff --git a/src/vtab.c b/src/vtab.c index 53800dd40e..c54dc65742 100644 --- a/src/vtab.c +++ b/src/vtab.c @@ -672,7 +672,7 @@ static void addToVTrans(sqlite3 *db, VTable *pVTab){ ** This function is invoked by the vdbe to call the xCreate method ** of the virtual table named zTab in database iDb. ** -** If an error occurs, *pzErr is set to point an an English language +** If an error occurs, *pzErr is set to point to an English language ** description of the error and an SQLITE_XXX error code is returned. ** In this case the caller must call sqlite3DbFree(db, ) on *pzErr. */ From a87070a2716fde5569db592c0cebfd7d3578f968 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 29 Aug 2016 14:18:18 +0000 Subject: [PATCH 0778/1484] Use some of the example code from the sessions documenatation in the sessions test cases. FossilOrigin-Name: 6602974d17536bcb904a794bddedffd58926794b --- ext/session/session_common.tcl | 3 + ext/session/test_session.c | 138 +++++++++++++++++++++++++++++---- manifest | 16 ++-- manifest.uuid | 2 +- 4 files changed, 133 insertions(+), 26 deletions(-) diff --git a/ext/session/session_common.tcl b/ext/session/session_common.tcl index 38eebec0a0..06b05509b1 100644 --- a/ext/session/session_common.tcl +++ b/ext/session/session_common.tcl @@ -75,6 +75,9 @@ proc do_common_sql {sql} { } proc changeset_from_sql {sql {dbname main}} { + if {$dbname == "main"} { + return [sql_exec_changeset db $sql] + } set rc [catch { sqlite3session S db $dbname db eval "SELECT name FROM $dbname.sqlite_master WHERE type = 'table'" { diff --git a/ext/session/test_session.c b/ext/session/test_session.c index 103a1c2d7a..411354cc02 100644 --- a/ext/session/test_session.c +++ b/ext/session/test_session.c @@ -29,6 +29,107 @@ struct TestStreamInput { int iData; /* Bytes of data already read by sessions */ }; +/* +** Extract an sqlite3* db handle from the object passed as the second +** argument. If successful, set *pDb to point to the db handle and return +** TCL_OK. Otherwise, return TCL_ERROR. +*/ +static int dbHandleFromObj(Tcl_Interp *interp, Tcl_Obj *pObj, sqlite3 **pDb){ + Tcl_CmdInfo info; + if( 0==Tcl_GetCommandInfo(interp, Tcl_GetString(pObj), &info) ){ + Tcl_AppendResult(interp, "no such handle: ", Tcl_GetString(pObj), 0); + return TCL_ERROR; + } + + *pDb = *(sqlite3 **)info.objClientData; + return TCL_OK; +} + +/************************************************************************* +** The following code is copied byte-for-byte from the sessions module +** documentation. It is used by some of the sessions modules tests to +** ensure that the example in the documentation does actually work. +*/ +/* +** Argument zSql points to a buffer containing an SQL script to execute +** against the database handle passed as the first argument. As well as +** executing the SQL script, this function collects a changeset recording +** all changes made to the "main" database file. Assuming no error occurs, +** output variables (*ppChangeset) and (*pnChangeset) are set to point +** to a buffer containing the changeset and the size of the changeset in +** bytes before returning SQLITE_OK. In this case it is the responsibility +** of the caller to eventually free the changeset blob by passing it to +** the sqlite3_free function. +** +** Or, if an error does occur, return an SQLite error code. The final +** value of (*pChangeset) and (*pnChangeset) are undefined in this case. +*/ +int sql_exec_changeset( + sqlite3 *db, /* Database handle */ + const char *zSql, /* SQL script to execute */ + int *pnChangeset, /* OUT: Size of changeset blob in bytes */ + void **ppChangeset /* OUT: Pointer to changeset blob */ +){ + sqlite3_session *pSession = 0; + int rc; + + /* Create a new session object */ + rc = sqlite3session_create(db, "main", &pSession); + + /* Configure the session object to record changes to all tables */ + if( rc==SQLITE_OK ) rc = sqlite3session_attach(pSession, NULL); + + /* Execute the SQL script */ + if( rc==SQLITE_OK ) rc = sqlite3_exec(db, zSql, 0, 0, 0); + + /* Collect the changeset */ + if( rc==SQLITE_OK ){ + rc = sqlite3session_changeset(pSession, pnChangeset, ppChangeset); + } + + /* Delete the session object */ + sqlite3session_delete(pSession); + + return rc; +} +/************************************************************************/ + +/* +** Tclcmd: sql_exec_changeset DB SQL +*/ +static int SQLITE_TCLAPI test_sql_exec_changeset( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + const char *zSql; + sqlite3 *db; + void *pChangeset; + int nChangeset; + int rc; + + if( objc!=3 ){ + Tcl_WrongNumArgs(interp, 1, objv, "DB SQL"); + return TCL_ERROR; + } + if( dbHandleFromObj(interp, objv[1], &db) ) return TCL_ERROR; + zSql = (const char*)Tcl_GetString(objv[2]); + + rc = sql_exec_changeset(db, zSql, &nChangeset, &pChangeset); + if( rc!=SQLITE_OK ){ + Tcl_ResetResult(interp); + Tcl_AppendResult(interp, "error in sql_exec_changeset()", 0); + return TCL_ERROR; + } + + Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(pChangeset, nChangeset)); + sqlite3_free(pChangeset); + return TCL_OK; +} + + + #define SESSION_STREAM_TCL_VAR "sqlite3session_streams" /* @@ -919,23 +1020,26 @@ static int SQLITE_TCLAPI test_sqlite3session_foreach( } int TestSession_Init(Tcl_Interp *interp){ - Tcl_CreateObjCommand(interp, "sqlite3session", test_sqlite3session, 0, 0); - Tcl_CreateObjCommand( - interp, "sqlite3session_foreach", test_sqlite3session_foreach, 0, 0 - ); - Tcl_CreateObjCommand( - interp, "sqlite3changeset_invert", test_sqlite3changeset_invert, 0, 0 - ); - Tcl_CreateObjCommand( - interp, "sqlite3changeset_concat", test_sqlite3changeset_concat, 0, 0 - ); - Tcl_CreateObjCommand( - interp, "sqlite3changeset_apply", test_sqlite3changeset_apply, 0, 0 - ); - Tcl_CreateObjCommand( - interp, "sqlite3changeset_apply_replace_all", - test_sqlite3changeset_apply_replace_all, 0, 0 - ); + struct Cmd { + const char *zCmd; + Tcl_ObjCmdProc *xProc; + } aCmd[] = { + { "sqlite3session", test_sqlite3session }, + { "sqlite3session_foreach", test_sqlite3session_foreach }, + { "sqlite3changeset_invert", test_sqlite3changeset_invert }, + { "sqlite3changeset_concat", test_sqlite3changeset_concat }, + { "sqlite3changeset_apply", test_sqlite3changeset_apply }, + { "sqlite3changeset_apply_replace_all", + test_sqlite3changeset_apply_replace_all }, + { "sql_exec_changeset", test_sql_exec_changeset }, + }; + int i; + + for(i=0; izCmd, p->xProc, 0, 0); + } + return TCL_OK; } diff --git a/manifest b/manifest index 669a25cf06..be047d09d2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\stypos\sin\scomments.\s\sNo\schanges\sto\srunning\scode. -D 2016-08-27T20:21:51.309 +C Use\ssome\sof\sthe\sexample\scode\sfrom\sthe\ssessions\sdocumenatation\sin\sthe\ssessions\stest\scases. +D 2016-08-29T14:18:18.207 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5017381e4853b1472e01d5bb926be1268eba429c @@ -297,12 +297,12 @@ F ext/session/sessionD.test d4744c78334162851d2a2f285c7e603e31b49aa2 F ext/session/sessionE.test e60a238c47f0feb3bb707e7f35e22be09c7e8f26 F ext/session/sessionF.test c2f178d4dfd723a5fd94a730ea2ccb44c669e3ce F ext/session/sessionG.test 01ef705096a9d3984eebdcca79807a211dee1b60 -F ext/session/session_common.tcl a1293167d14774b5e728836720497f40fe4ea596 +F ext/session/session_common.tcl 9b696a341cf1d3744823715ed92bb19749b6c3d4 F ext/session/sessionfault.test da273f2712b6411e85e71465a1733b8501dbf6f7 F ext/session/sessionfault2.test 04aa0bc9aa70ea43d8de82c4f648db4de1e990b0 F ext/session/sqlite3session.c 37485891b4add26cf61495df193c419f36556a32 F ext/session/sqlite3session.h 7b9037818ee61f7429ca83e9866885ca6de5f764 -F ext/session/test_session.c 2caed9a659586428c63ca46e4900347b374487d4 +F ext/session/test_session.c eb0bd6c1ea791c1d66ee4ef94c16500dad936386 F ext/userauth/sqlite3userauth.h 19cb6f0e31316d0ee4afdfb7a85ef9da3333a220 F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04 F ext/userauth/userauth.c 5fa3bdb492f481bbc1709fc83c91ebd13460c69e @@ -1511,7 +1511,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 78cd64e202fcbe9ce69070b0f48ccd0c6b48538d -R 3fe3d686aa6a61df97c243454c02cd64 -U drh -Z 90feb3c09ae2ca31e13afbfbff662667 +P a07269f2a0f87e0b736127f528f6caf3b63f9052 +R e338ebda27cef4eaa61a39e0a172ba0c +U dan +Z 11041cb022515aa05751c4e3c90843c8 diff --git a/manifest.uuid b/manifest.uuid index 640141a0eb..5cc9198912 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a07269f2a0f87e0b736127f528f6caf3b63f9052 \ No newline at end of file +6602974d17536bcb904a794bddedffd58926794b \ No newline at end of file From d0d49b9ca3c106e972ca724c7202a81182f4260f Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 1 Sep 2016 09:35:20 +0000 Subject: [PATCH 0779/1484] If SQLITE_ENABLE_ZIPVFS is defined, journal_mode=off is configured and a savepoint or statement rollback is attempted, move the pager into the error state to prevent the transaction from being committed. This makes it safe to use journal_mode=off with zipvfs under some conditions. FossilOrigin-Name: 38d31e189e7c7899e14455f2c083aa676ce4d4c0 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/pager.c | 20 +++++++++++++++++++- 3 files changed, 26 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index be047d09d2..c4f3856500 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Use\ssome\sof\sthe\sexample\scode\sfrom\sthe\ssessions\sdocumenatation\sin\sthe\ssessions\stest\scases. -D 2016-08-29T14:18:18.207 +C If\sSQLITE_ENABLE_ZIPVFS\sis\sdefined,\sjournal_mode=off\sis\sconfigured\sand\sa\ssavepoint\sor\sstatement\srollback\sis\sattempted,\smove\sthe\spager\sinto\sthe\serror\sstate\sto\sprevent\sthe\stransaction\sfrom\sbeing\scommitted.\sThis\smakes\sit\ssafe\sto\suse\sjournal_mode=off\swith\szipvfs\sunder\ssome\sconditions. +D 2016-09-01T09:35:20.703 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5017381e4853b1472e01d5bb926be1268eba429c @@ -371,7 +371,7 @@ F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586 F src/os_unix.c be9ca0f901a2b6c1bc93dc338f4863675180c189 F src/os_win.c 520f23475f1de530c435d30b67b7b15fe90874b0 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a -F src/pager.c 40928c450320da78bb4bd3ae82818f4239e19b7e +F src/pager.c bf5b71bde3e9b6110e7d6990607db881f6a471a2 F src/pager.h 966d2769e76ae347c8a32c4165faf6e6cb64546d F src/parse.y ed6990c2d41eb0302eda90d5009c51fec792c850 F src/pcache.c 5583c8ade4b05075a60ba953ef471d1c1a9c05df @@ -1511,7 +1511,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a07269f2a0f87e0b736127f528f6caf3b63f9052 -R e338ebda27cef4eaa61a39e0a172ba0c +P 6602974d17536bcb904a794bddedffd58926794b +R 78dc0041209a92fe8b940a2665fbfc99 U dan -Z 11041cb022515aa05751c4e3c90843c8 +Z f1c8273131a5d41903cfd86ae1fce8b9 diff --git a/manifest.uuid b/manifest.uuid index 5cc9198912..d765505e05 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6602974d17536bcb904a794bddedffd58926794b \ No newline at end of file +38d31e189e7c7899e14455f2c083aa676ce4d4c0 \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index cd8d1204b3..dfa512b485 100644 --- a/src/pager.c +++ b/src/pager.c @@ -6656,7 +6656,11 @@ int sqlite3PagerOpenSavepoint(Pager *pPager, int nSavepoint){ ** savepoint. If no errors occur, SQLITE_OK is returned. */ int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint){ - int rc = pPager->errCode; /* Return code */ + int rc = pPager->errCode; + +#ifdef SQLITE_ENABLE_ZIPVFS + if( op==SAVEPOINT_RELEASE ) rc = SQLITE_OK; +#endif assert( op==SAVEPOINT_RELEASE || op==SAVEPOINT_ROLLBACK ); assert( iSavepoint>=0 || op==SAVEPOINT_ROLLBACK ); @@ -6697,6 +6701,20 @@ int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint){ rc = pagerPlaybackSavepoint(pPager, pSavepoint); assert(rc!=SQLITE_DONE); } + +#ifdef SQLITE_ENABLE_ZIPVFS + /* If the cache has been modified but the savepoint cannot be rolled + ** back journal_mode=off, put the pager in the error state. This way, + ** if the VFS used by this pager includes ZipVFS, the entire transaction + ** can be rolled back at the ZipVFS level. */ + else if( + pPager->journalMode==PAGER_JOURNALMODE_OFF + && pPager->eState>=PAGER_WRITER_CACHEMOD + ){ + pPager->errCode = SQLITE_ABORT; + pPager->eState = PAGER_ERROR; + } +#endif } return rc; From e5a0cfa161a77e8ab674fc53f30154c9129eff70 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 1 Sep 2016 14:03:28 +0000 Subject: [PATCH 0780/1484] Have "sqldiff --rbu" ignore rows with NULL values in primary key fields. RBU can't handle such rows and the documentation already says sqldiff ignores them. Because the code now uses "=" instead of "IS" to filter on primary key columns, diffs on virtual tables are faster now too. FossilOrigin-Name: f4ba894a86aa195bcbe2fa69e91cd870ec3fb577 --- ext/rbu/rbudiff.test | 10 ++++++++++ manifest | 14 +++++++------- manifest.uuid | 2 +- tool/sqldiff.c | 12 +++++++----- 4 files changed, 25 insertions(+), 13 deletions(-) diff --git a/ext/rbu/rbudiff.test b/ext/rbu/rbudiff.test index 041a242428..4a32009230 100644 --- a/ext/rbu/rbudiff.test +++ b/ext/rbu/rbudiff.test @@ -140,6 +140,15 @@ foreach {tn init mod} { ); } + 4 { + CREATE TABLE x1(a, b, c, PRIMARY KEY(a, b, c)); + INSERT INTO x1 VALUES('u', 'v', NULL); + INSERT INTO x1 VALUES('x', 'y', 'z'); + INSERT INTO x1 VALUES('a', NULL, 'b'); + } { + INSERT INTO x1 VALUES('a', 'b', 'c'); + } + } { catch { db close } @@ -280,5 +289,6 @@ tablE t1 USING FTs5(c); } } + finish_test diff --git a/manifest b/manifest index c4f3856500..ed5afd047d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C If\sSQLITE_ENABLE_ZIPVFS\sis\sdefined,\sjournal_mode=off\sis\sconfigured\sand\sa\ssavepoint\sor\sstatement\srollback\sis\sattempted,\smove\sthe\spager\sinto\sthe\serror\sstate\sto\sprevent\sthe\stransaction\sfrom\sbeing\scommitted.\sThis\smakes\sit\ssafe\sto\suse\sjournal_mode=off\swith\szipvfs\sunder\ssome\sconditions. -D 2016-09-01T09:35:20.703 +C Have\s"sqldiff\s--rbu"\signore\srows\swith\sNULL\svalues\sin\sprimary\skey\sfields.\sRBU\scan't\shandle\ssuch\srows\sand\sthe\sdocumentation\salready\ssays\ssqldiff\signores\sthem.\sBecause\sthe\scode\snow\suses\s"="\sinstead\sof\s"IS"\sto\sfilter\son\sprimary\skey\scolumns,\sdiffs\son\svirtual\stables\sare\sfaster\snow\stoo. +D 2016-09-01T14:03:28.041 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5017381e4853b1472e01d5bb926be1268eba429c @@ -245,7 +245,7 @@ F ext/rbu/rbuB.test c25bc325b8072a766e56bb76c001866b405925c2 F ext/rbu/rbuC.test efe47db508a0269b683cb2a1913a425ffd39a831 F ext/rbu/rbu_common.tcl a38e8e2d4a50fd6aaf151633714c1b1d2fae3ead F ext/rbu/rbucrash.test 8d2ed5d4b05fef6c00c2a6b5f7ead71fa172a695 -F ext/rbu/rbudiff.test b3c7675810b81de98a930a87fcd40d9ae545619d +F ext/rbu/rbudiff.test d099b56b073a737cfe1b8e9f67b77940130719cb F ext/rbu/rbufault.test cc0be8d5d392d98b0c2d6a51be377ea989250a89 F ext/rbu/rbufault2.test 9a7f19edd6ea35c4c9f807d8a3db0a03a5670c06 F ext/rbu/rbufault3.test 54a399888ac4af44c68f9f58afbed23149428bca @@ -1478,7 +1478,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 7ce07da76b5e745783e703a834417d725b7d45fd F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c -F tool/sqldiff.c c965d49bf2677db06103854b47e105484b5b1b84 +F tool/sqldiff.c 7f567367d87fdb493e3e65169569a10d9f330c3f F tool/srcck1.c 371de5363b70154012955544f86fdee8f6e5326f F tool/stack_usage.tcl f8e71b92cdb099a147dad572375595eae55eca43 F tool/symbols-mingw.sh 4dbcea7e74768305384c9fd2ed2b41bbf9f0414d @@ -1511,7 +1511,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 6602974d17536bcb904a794bddedffd58926794b -R 78dc0041209a92fe8b940a2665fbfc99 +P 38d31e189e7c7899e14455f2c083aa676ce4d4c0 +R ca589e025240033a5748a5eba7e4950c U dan -Z f1c8273131a5d41903cfd86ae1fce8b9 +Z 28ca6847fc75deee037b1b39928043e8 diff --git a/manifest.uuid b/manifest.uuid index d765505e05..78d594bd6c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -38d31e189e7c7899e14455f2c083aa676ce4d4c0 \ No newline at end of file +f4ba894a86aa195bcbe2fa69e91cd870ec3fb577 \ No newline at end of file diff --git a/tool/sqldiff.c b/tool/sqldiff.c index b1363bb341..cbb57e7774 100644 --- a/tool/sqldiff.c +++ b/tool/sqldiff.c @@ -1179,8 +1179,9 @@ static void getRbudiffQuery( strPrintf(pSql, " FROM aux.%Q AS n WHERE NOT EXISTS (\n", zTab); strPrintf(pSql, " SELECT 1 FROM ", zTab); strPrintf(pSql, " main.%Q AS o WHERE ", zTab); - strPrintfArray(pSql, " AND ", "(n.%Q IS o.%Q)", azCol, nPK); - strPrintf(pSql, "\n)"); + strPrintfArray(pSql, " AND ", "(n.%Q = o.%Q)", azCol, nPK); + strPrintf(pSql, "\n) AND "); + strPrintfArray(pSql, " AND ", "(n.%Q IS NOT NULL)", azCol, nPK); /* Deleted rows: */ strPrintf(pSql, "\nUNION ALL\nSELECT "); @@ -1194,8 +1195,9 @@ static void getRbudiffQuery( strPrintf(pSql, " FROM main.%Q AS n WHERE NOT EXISTS (\n", zTab); strPrintf(pSql, " SELECT 1 FROM ", zTab); strPrintf(pSql, " aux.%Q AS o WHERE ", zTab); - strPrintfArray(pSql, " AND ", "(n.%Q IS o.%Q)", azCol, nPK); - strPrintf(pSql, "\n) "); + strPrintfArray(pSql, " AND ", "(n.%Q = o.%Q)", azCol, nPK); + strPrintf(pSql, "\n) AND "); + strPrintfArray(pSql, " AND ", "(n.%Q IS NOT NULL)", azCol, nPK); /* Updated rows. If all table columns are part of the primary key, there ** can be no updates. In this case this part of the compound SELECT can @@ -1226,7 +1228,7 @@ static void getRbudiffQuery( ); strPrintf(pSql, "\nFROM main.%Q AS o, aux.%Q AS n\nWHERE ", zTab, zTab); - strPrintfArray(pSql, " AND ", "(n.%Q IS o.%Q)", azCol, nPK); + strPrintfArray(pSql, " AND ", "(n.%Q = o.%Q)", azCol, nPK); strPrintf(pSql, " AND ota_control LIKE '%%x%%'"); } From 033564cca9d64f67ce6cb0df1b1ddf53d4a74f49 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 2 Sep 2016 17:18:20 +0000 Subject: [PATCH 0781/1484] Within a backup operation, ensure that a read-transaction is opened on the source database before its page size is read. This ensures the page-size used to write to the backup database is the same as its actual page-size, which is important for ZipVFS databases. FossilOrigin-Name: 7908fc604991d81140c182b97981fd724ad126ae --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/backup.c | 25 ++++++++++++++++--------- 3 files changed, 23 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index ed5afd047d..f6d9f3788a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Have\s"sqldiff\s--rbu"\signore\srows\swith\sNULL\svalues\sin\sprimary\skey\sfields.\sRBU\scan't\shandle\ssuch\srows\sand\sthe\sdocumentation\salready\ssays\ssqldiff\signores\sthem.\sBecause\sthe\scode\snow\suses\s"="\sinstead\sof\s"IS"\sto\sfilter\son\sprimary\skey\scolumns,\sdiffs\son\svirtual\stables\sare\sfaster\snow\stoo. -D 2016-09-01T14:03:28.041 +C Within\sa\sbackup\soperation,\sensure\sthat\sa\sread-transaction\sis\sopened\son\sthe\ssource\sdatabase\sbefore\sits\spage\ssize\sis\sread.\sThis\sensures\sthe\spage-size\sused\sto\swrite\sto\sthe\sbackup\sdatabase\sis\sthe\ssame\sas\sits\sactual\spage-size,\swhich\sis\simportant\sfor\sZipVFS\sdatabases. +D 2016-09-02T17:18:20.100 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5017381e4853b1472e01d5bb926be1268eba429c @@ -325,7 +325,7 @@ F src/alter.c 299117695b1f21ac62dfc5b608588810ba22ed0d F src/analyze.c 8b62b2cf4da85451534ac0af82cafc418d837f68 F src/attach.c 4711ff365df4072b8c3dcd55db5d12dcf8ffa0c6 F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792 -F src/backup.c 17cd25a36d49330df2bacd2cadf2a61f3b525976 +F src/backup.c 7d986927896b70c29a313b9954ab36576aff113d F src/bitvec.c 3ee4c8b2c94ed3a7377256e18199e6ff5cf33f63 F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 F src/btree.c 2551bd3ecb8b8988fb8b23aabadfb214dbc38e46 @@ -1511,7 +1511,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 38d31e189e7c7899e14455f2c083aa676ce4d4c0 -R ca589e025240033a5748a5eba7e4950c +P f4ba894a86aa195bcbe2fa69e91cd870ec3fb577 +R 6268e0964e35cc05a56dd4669fe54aba U dan -Z 28ca6847fc75deee037b1b39928043e8 +Z 246b0cb12b0fcdaba66d59db5334a074 diff --git a/manifest.uuid b/manifest.uuid index 78d594bd6c..a145bb5aba 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f4ba894a86aa195bcbe2fa69e91cd870ec3fb577 \ No newline at end of file +7908fc604991d81140c182b97981fd724ad126ae \ No newline at end of file diff --git a/src/backup.c b/src/backup.c index 19c3b2a647..0a236700b2 100644 --- a/src/backup.c +++ b/src/backup.c @@ -196,7 +196,6 @@ sqlite3_backup *sqlite3_backup_init( p->isAttached = 0; if( 0==p->pSrc || 0==p->pDest - || setDestPgsz(p)==SQLITE_NOMEM || checkReadTransaction(pDestDb, p->pDest)!=SQLITE_OK ){ /* One (or both) of the named databases did not exist or an OOM @@ -384,14 +383,6 @@ int sqlite3_backup_step(sqlite3_backup *p, int nPage){ rc = SQLITE_OK; } - /* Lock the destination database, if it is not locked already. */ - if( SQLITE_OK==rc && p->bDestLocked==0 - && SQLITE_OK==(rc = sqlite3BtreeBeginTrans(p->pDest, 2)) - ){ - p->bDestLocked = 1; - sqlite3BtreeGetMeta(p->pDest, BTREE_SCHEMA_VERSION, &p->iDestSchema); - } - /* If there is no open read-transaction on the source database, open ** one now. If a transaction is opened here, then it will be closed ** before this function exits. @@ -401,6 +392,22 @@ int sqlite3_backup_step(sqlite3_backup *p, int nPage){ bCloseTrans = 1; } + /* If the destination database has not yet been locked (i.e. if this + ** is the first call to backup_step() for the current backup operation), + ** try to set its page size to the same as the source database. This + ** is especially important on ZipVFS systems, as in that case it is + ** not possible to create a database file that uses one page size by + ** writing to it with another. */ + if( p->bDestLocked==0 ) setDestPgsz(p); + + /* Lock the destination database, if it is not locked already. */ + if( SQLITE_OK==rc && p->bDestLocked==0 + && SQLITE_OK==(rc = sqlite3BtreeBeginTrans(p->pDest, 2)) + ){ + p->bDestLocked = 1; + sqlite3BtreeGetMeta(p->pDest, BTREE_SCHEMA_VERSION, &p->iDestSchema); + } + /* Do not allow backup if the destination database is in WAL mode ** and the page sizes are different between source and destination */ pgszSrc = sqlite3BtreeGetPageSize(p->pSrc); From 76729ed4be600448eac38af45aafacdff116500f Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 2 Sep 2016 21:17:51 +0000 Subject: [PATCH 0782/1484] Correctly detect an OOM occurring in the setDestPgsz() subroutine of backup. FossilOrigin-Name: d9d8a048d4b621435870b4f8dd13b2938ac2f8fd --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/backup.c | 4 +++- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index f6d9f3788a..4b8ebb6ca8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Within\sa\sbackup\soperation,\sensure\sthat\sa\sread-transaction\sis\sopened\son\sthe\ssource\sdatabase\sbefore\sits\spage\ssize\sis\sread.\sThis\sensures\sthe\spage-size\sused\sto\swrite\sto\sthe\sbackup\sdatabase\sis\sthe\ssame\sas\sits\sactual\spage-size,\swhich\sis\simportant\sfor\sZipVFS\sdatabases. -D 2016-09-02T17:18:20.100 +C Correctly\sdetect\san\sOOM\soccurring\sin\sthe\ssetDestPgsz()\ssubroutine\sof\nbackup. +D 2016-09-02T21:17:51.499 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5017381e4853b1472e01d5bb926be1268eba429c @@ -325,7 +325,7 @@ F src/alter.c 299117695b1f21ac62dfc5b608588810ba22ed0d F src/analyze.c 8b62b2cf4da85451534ac0af82cafc418d837f68 F src/attach.c 4711ff365df4072b8c3dcd55db5d12dcf8ffa0c6 F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792 -F src/backup.c 7d986927896b70c29a313b9954ab36576aff113d +F src/backup.c 92c2e3b5fcb47626413717138617f4d32f08aea4 F src/bitvec.c 3ee4c8b2c94ed3a7377256e18199e6ff5cf33f63 F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 F src/btree.c 2551bd3ecb8b8988fb8b23aabadfb214dbc38e46 @@ -1511,7 +1511,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P f4ba894a86aa195bcbe2fa69e91cd870ec3fb577 -R 6268e0964e35cc05a56dd4669fe54aba -U dan -Z 246b0cb12b0fcdaba66d59db5334a074 +P 7908fc604991d81140c182b97981fd724ad126ae +R 927ab162f03d57784d15e59a76583f84 +U drh +Z 3a29e1d29c21b4d8169c8797b79e666a diff --git a/manifest.uuid b/manifest.uuid index a145bb5aba..a3366a05c1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7908fc604991d81140c182b97981fd724ad126ae \ No newline at end of file +d9d8a048d4b621435870b4f8dd13b2938ac2f8fd \ No newline at end of file diff --git a/src/backup.c b/src/backup.c index 0a236700b2..eb8f15cc7e 100644 --- a/src/backup.c +++ b/src/backup.c @@ -398,7 +398,9 @@ int sqlite3_backup_step(sqlite3_backup *p, int nPage){ ** is especially important on ZipVFS systems, as in that case it is ** not possible to create a database file that uses one page size by ** writing to it with another. */ - if( p->bDestLocked==0 ) setDestPgsz(p); + if( p->bDestLocked==0 && rc==SQLITE_OK && setDestPgsz(p)==SQLITE_NOMEM ){ + rc = SQLITE_NOMEM; + } /* Lock the destination database, if it is not locked already. */ if( SQLITE_OK==rc && p->bDestLocked==0 From c6952addf7c2c22c7345d5ae8564ab762a1bdb1b Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 2 Sep 2016 21:34:17 +0000 Subject: [PATCH 0783/1484] Add a test case for the OOM handled by the previous commit. FossilOrigin-Name: 9bdf7ca1b317fe0ba7efea38fb395bf6130ac89a --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/backup_malloc.test | 31 +++++++++++++++++++++++++++++++ 3 files changed, 39 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 4b8ebb6ca8..c643135037 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Correctly\sdetect\san\sOOM\soccurring\sin\sthe\ssetDestPgsz()\ssubroutine\sof\nbackup. -D 2016-09-02T21:17:51.499 +C Add\sa\stest\scase\sfor\sthe\sOOM\shandled\sby\sthe\sprevious\scommit. +D 2016-09-02T21:34:17.199 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5017381e4853b1472e01d5bb926be1268eba429c @@ -524,7 +524,7 @@ F test/backup2.test 34986ef926ea522911a51dfdb2f8e99b7b75ebcf F test/backup4.test 8f6fd48e0dfde77b9a3bb26dc471ede3e101df32 F test/backup5.test ee5da6d7fe5082f5b9b0bbfa31d016f52412a2e4 F test/backup_ioerr.test 4c3c7147cee85b024ecf6e150e090c32fdbb5135 -F test/backup_malloc.test 7162d604ec2b4683c4b3799a48657fb8b5e2d450 +F test/backup_malloc.test 833d1b90561a6dbab00079b9591bd4fc90b7c2e1 F test/badutf.test d5360fc31f643d37a973ab0d8b4fb85799c3169f F test/badutf2.test f5bc7f2d280670ecd79b9cf4f0f1760c607fe51f F test/bc_common.tcl b5e42d80305be95697e6370e015af571e5333a1c @@ -1511,7 +1511,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 7908fc604991d81140c182b97981fd724ad126ae -R 927ab162f03d57784d15e59a76583f84 -U drh -Z 3a29e1d29c21b4d8169c8797b79e666a +P d9d8a048d4b621435870b4f8dd13b2938ac2f8fd +R b03bceee349e62c9e4b232e967e75375 +U dan +Z 94198719997091b0b262fcfd62b5468a diff --git a/manifest.uuid b/manifest.uuid index a3366a05c1..33cb4d6b33 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d9d8a048d4b621435870b4f8dd13b2938ac2f8fd \ No newline at end of file +9bdf7ca1b317fe0ba7efea38fb395bf6130ac89a \ No newline at end of file diff --git a/test/backup_malloc.test b/test/backup_malloc.test index f556861fb1..45cac44f18 100644 --- a/test/backup_malloc.test +++ b/test/backup_malloc.test @@ -84,4 +84,35 @@ do_malloc_test backup_malloc-2 -tclprep { db2 close } +reset_db +do_execsql_test 3.0 { + PRAGMA page_size = 16384; + BEGIN; + CREATE TABLE t1(a, b); + INSERT INTO t1 VALUES(1, 2); + COMMIT; +} + +do_faultsim_test 3 -faults oom* -prep { + catch { db close } + + forcedelete test2.db + sqlite3 db2 test2.db + sqlite3 db test.db + sqlite3_backup B db2 main db main +} -body { + + set rc [B step 50] + if {$rc == "SQLITE_NOMEM" || $rc == "SQLITE_IOERR_NOMEM"} { + error "out of memory" + } + +} -test { + faultsim_test_result {0 {}} + faultsim_integrity_check + + # Finalize the backup. + catch { B finish } +} + finish_test From 4910a76d4501b11fdc639c01e531d5100401b444 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 3 Sep 2016 01:46:15 +0000 Subject: [PATCH 0784/1484] Performance optimizations. FossilOrigin-Name: f1d06c49ba0d814dc7ffb538aac3f4e6251fd8f0 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/expr.c | 2 +- src/select.c | 2 +- src/vdbe.c | 37 ++++++++++++++++++++----------------- 5 files changed, 31 insertions(+), 28 deletions(-) diff --git a/manifest b/manifest index 0d346f639b..e6005476d0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\srecent\schanges\sfrom\strunk. -D 2016-09-02T23:56:32.342 +C Performance\soptimizations. +D 2016-09-03T01:46:15.276 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5017381e4853b1472e01d5bb926be1268eba429c @@ -338,7 +338,7 @@ F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7 F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c 76c084f0265f4a3cd1ecf17eee112a94f1ccbc05 -F src/expr.c 6ac2955b85fb32934b5505904da3d4be39d5d877 +F src/expr.c 7e0470e2b82af8d6544132d81da18990d9b9c09d F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c e2be0968c1adc679c87e467aa5b4f167588f38a8 F src/func.c 29cc9acb170ec1387b9f63eb52cd85f8de96c771 @@ -385,7 +385,7 @@ F src/printf.c a5f0ca08ddede803c241266abb46356ec748ded1 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c d67b9a5cc33339256e2088c5a722745fc2ff5219 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac -F src/select.c cf90abce32567023c940ecabf5707c4714c61c92 +F src/select.c 38216d0b2d42a0f475abf86a84c3499e6421ba29 F src/shell.c 79dda477be6c96eba6e952a934957ad36f87acc7 F src/sqlite.h.in 4a030e254e204570444b34bf7d40fb4a5416089e F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -451,7 +451,7 @@ F src/update.c 8179e699dbd45b92934fd02d3d8e3732e8da8802 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 810ec3f22e2d1b62e66c30fe3621ebdedd23584d F src/vacuum.c 913970b9d86dd6c2b8063ef1af421880f1464ec3 -F src/vdbe.c 4be39068ea1412a21a2566c71007c87b67928d67 +F src/vdbe.c d8fb59a3ef10636df2447f55c1e82be7b8ad1604 F src/vdbe.h 67bc551f7faf04c33493892e4b378aada823ed10 F src/vdbeInt.h c59381049af5c7751a83456c39b80d1a6fde1f9d F src/vdbeapi.c a32d61b7dd05e6890d8fd44d2805f55e2f5ba9f3 @@ -1521,7 +1521,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 082fd5f8ac227dbb983da0a772485268af40a484 9bdf7ca1b317fe0ba7efea38fb395bf6130ac89a -R 5ef4ae610db43c409abf4a916ff574b9 +P c7271fbde1aebb15daaedb7f1fa75fe410fd46f6 +R 617c8c8681735b3b6f061557d07c266d U drh -Z 8a1867c9ed1b748f87443a20db67a6e2 +Z dbe31dcf0712b654c7c10b1471579b28 diff --git a/manifest.uuid b/manifest.uuid index f54ff68f8f..eb5bf868a4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c7271fbde1aebb15daaedb7f1fa75fe410fd46f6 \ No newline at end of file +f1d06c49ba0d814dc7ffb538aac3f4e6251fd8f0 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 8e74fff61b..31df95c057 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1021,7 +1021,7 @@ static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){ if( !ExprHasProperty(p, EP_TokenOnly) ){ /* The Expr.x union is never used at the same time as Expr.pRight */ assert( p->x.pList==0 || p->pRight==0 ); - if( p->op!=TK_SELECT_COLUMN ) sqlite3ExprDelete(db, p->pLeft); + if( p->pLeft && p->op!=TK_SELECT_COLUMN ) sqlite3ExprDeleteNN(db, p->pLeft); sqlite3ExprDelete(db, p->pRight); if( ExprHasProperty(p, EP_MemToken) ) sqlite3DbFree(db, p->u.zToken); if( ExprHasProperty(p, EP_xIsSelect) ){ diff --git a/src/select.c b/src/select.c index 6e51494f77..809285ea89 100644 --- a/src/select.c +++ b/src/select.c @@ -1796,7 +1796,7 @@ Table *sqlite3ResultSetOfSelect(Parse *pParse, Select *pSelect){ */ static SQLITE_NOINLINE Vdbe *allocVdbe(Parse *pParse){ Vdbe *v = pParse->pVdbe = sqlite3VdbeCreate(pParse); - if( v ) sqlite3VdbeAddOp0(v, OP_Init); + if( v ) sqlite3VdbeAddOp2(v, OP_Init, 0, 1); if( pParse->pToplevel==0 && OptimizationEnabled(pParse->db,SQLITE_FactorOutConst) ){ diff --git a/src/vdbe.c b/src/vdbe.c index b640e0b4f5..443ecbce1d 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -1980,7 +1980,7 @@ case OP_Lt: /* same as TK_LT, jump, in1, in3 */ case OP_Le: /* same as TK_LE, jump, in1, in3 */ case OP_Gt: /* same as TK_GT, jump, in1, in3 */ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ - int res; /* Result of the comparison of pIn1 against pIn3 */ + int res, res2; /* Result of the comparison of pIn1 against pIn3 */ char affinity; /* Affinity to use for comparison */ u16 flags1; /* Copy of initial value of pIn1->flags */ u16 flags3; /* Copy of initial value of pIn3->flags */ @@ -2003,18 +2003,18 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ && (flags3&MEM_Null)!=0 && (flags3&MEM_Cleared)==0 ){ - iCompare = 0; /* Operands are equal */ + res = 0; /* Operands are equal */ }else{ - iCompare = 1; /* Operands are not equal */ + res = 1; /* Operands are not equal */ } }else{ /* SQLITE_NULLEQ is clear and at least one operand is NULL, ** then the result is always NULL. ** The jump is taken if the SQLITE_JUMPIFNULL bit is set. */ - iCompare = 1; /* Operands are not equal */ if( pOp->p5 & SQLITE_STOREP2 ){ pOut = &aMem[pOp->p2]; + iCompare = 1; /* Operands are not equal */ memAboutToChange(p, pOut); MemSetTypeFlag(pOut, MEM_Null); REGISTER_TRACE(pOp->p2, pOut); @@ -2065,15 +2065,15 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ sqlite3VdbeMemExpandBlob(pIn3); flags3 &= ~MEM_Zero; } - iCompare = sqlite3MemCompare(pIn3, pIn1, pOp->p4.pColl); + res = sqlite3MemCompare(pIn3, pIn1, pOp->p4.pColl); } switch( pOp->opcode ){ - case OP_Eq: res = iCompare==0; break; - case OP_Ne: res = iCompare!=0; break; - case OP_Lt: res = iCompare<0; break; - case OP_Le: res = iCompare<=0; break; - case OP_Gt: res = iCompare>0; break; - default: res = iCompare>=0; break; + case OP_Eq: res2 = res==0; break; + case OP_Ne: res2 = res; break; + case OP_Lt: res2 = res<0; break; + case OP_Le: res2 = res<=0; break; + case OP_Gt: res2 = res>0; break; + default: res2 = res>=0; break; } /* Undo any changes made by applyAffinity() to the input registers. */ @@ -2084,20 +2084,22 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ if( pOp->p5 & SQLITE_STOREP2 ){ pOut = &aMem[pOp->p2]; + iCompare = res; + res2 = res2!=0; /* For this path res2 must be exactly 0 or 1 */ if( (pOp->p5 & SQLITE_KEEPNULL)!=0 && (pOut->flags & MEM_Null)!=0 ){ /* The KEEPNULL flag prevents OP_Eq from overwriting a NULL with 1 ** and prevents OP_Ne from overwriting NULL with 0. */ assert( pOp->opcode==OP_Ne || pOp->opcode==OP_Eq ); - assert( res==0 || res==1 ); - if( (pOp->opcode==OP_Eq)==res ) break; + assert( res2==0 || res2==1 ); + if( (pOp->opcode==OP_Eq)==res2 ) break; } memAboutToChange(p, pOut); MemSetTypeFlag(pOut, MEM_Int); - pOut->u.i = res; + pOut->u.i = res2; REGISTER_TRACE(pOp->p2, pOut); }else{ VdbeBranchTaken(res!=0, (pOp->p5 & SQLITE_NULLEQ)?2:3); - if( res ){ + if( res2 ){ goto jump_to_p2; } } @@ -2115,6 +2117,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ case OP_ElseNotEq: { /* same as TK_ESCAPE, jump */ assert( pOp>aOp ); assert( pOp[-1].opcode==OP_Lt || pOp[-1].opcode==OP_Gt ); + assert( pOp[-1].p5 & SQLITE_STOREP2 ); VdbeBranchTaken(iCompare!=0, 2); if( iCompare!=0 ) goto jump_to_p2; break; @@ -6864,8 +6867,8 @@ case OP_Init: { /* jump */ } #endif /* SQLITE_DEBUG */ #endif /* SQLITE_OMIT_TRACE */ - if( pOp->p2 ) goto jump_to_p2; - break; + assert( pOp->p2>0 ); + goto jump_to_p2; } #ifdef SQLITE_ENABLE_CURSOR_HINTS From 271896031628a161bc0c3937dc90af01029e8bdf Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 3 Sep 2016 15:31:20 +0000 Subject: [PATCH 0785/1484] Consider the affinity of "b" when using an "a IN (SELECT b ...)" expression with an index on "a". Fix for [199df416]. FossilOrigin-Name: f5e49855412e389a8a410db5d7ffb2e3634c5fa3 --- manifest | 15 ++--- manifest.uuid | 2 +- src/wherecode.c | 20 ++++-- test/rowvalue9.test | 144 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 167 insertions(+), 14 deletions(-) create mode 100644 test/rowvalue9.test diff --git a/manifest b/manifest index e6005476d0..fdd02d717d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Performance\soptimizations. -D 2016-09-03T01:46:15.276 +C Consider\sthe\saffinity\sof\s"b"\swhen\susing\san\s"a\sIN\s(SELECT\sb\s...)"\sexpression\swith\san\sindex\son\s"a".\sFix\sfor\s[199df416]. +D 2016-09-03T15:31:20.197 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5017381e4853b1472e01d5bb926be1268eba429c @@ -467,7 +467,7 @@ F src/wal.h 6dd221ed384afdc204bc61e25c23ef7fd5a511f2 F src/walker.c 2d2cc7fb0f320f7f415215d7247f3c584141ac09 F src/where.c 48d705e5196a0611a7be90698eade455ee238536 F src/whereInt.h 14dd243e13b81cbb0a66063d38b70f93a7d6e613 -F src/wherecode.c ee7b5353ff5f63548c206e3ecb4423ff0857d766 +F src/wherecode.c 8a9a53cb52dd8a75e07c85e3bc12c1604c735954 F src/whereexpr.c 7f9ada866d48d15d09754ae819c1c40efe3b2aff F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -1028,6 +1028,7 @@ F test/rowvalue5.test a440d490c8c0bf606034c09d5c6bbf7840b98f95 F test/rowvalue6.test d19b54feb604d5601f8614b15e214e0774c01087 F test/rowvalue7.test 5d06ff19d9e6969e574a2e662a531dd0c67801a8 F test/rowvalue8.test 5900eddad9e2c3c2e26f1a95f74aafc1232ee5e0 +F test/rowvalue9.test ca4e07da993e455e2c34a11800cd5eecfa25dbea F test/rowvaluefault.test 7b16485e3f2b371f3e3d05455b8ded6d0c090244 F test/rtree.test 0c8d9dd458d6824e59683c19ab2ffa9ef946f798 F test/run-wordcount.sh 891e89c4c2d16e629cd45951d4ed899ad12afc09 @@ -1521,7 +1522,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P c7271fbde1aebb15daaedb7f1fa75fe410fd46f6 -R 617c8c8681735b3b6f061557d07c266d -U drh -Z dbe31dcf0712b654c7c10b1471579b28 +P f1d06c49ba0d814dc7ffb538aac3f4e6251fd8f0 +R 7e510355146cbd1276c808b956f1d4a6 +U dan +Z 2c951e6f5da67796ee0d56ffce2dd993 diff --git a/manifest.uuid b/manifest.uuid index eb5bf868a4..2759fbda66 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f1d06c49ba0d814dc7ffb538aac3f4e6251fd8f0 \ No newline at end of file +f5e49855412e389a8a410db5d7ffb2e3634c5fa3 \ No newline at end of file diff --git a/src/wherecode.c b/src/wherecode.c index 16ffb89db1..896509bc32 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -649,13 +649,21 @@ static int codeAllEqualityTerms( } testcase( pTerm->eOperator & WO_ISNULL ); testcase( pTerm->eOperator & WO_IN ); - if( (pTerm->eOperator & (WO_ISNULL|WO_IN))==0 ){ - Expr *pRight = pTerm->pExpr->pRight; - if( (pTerm->wtFlags & TERM_IS)==0 && sqlite3ExprCanBeNull(pRight) ){ - sqlite3VdbeAddOp2(v, OP_IsNull, regBase+j, pLevel->addrBrk); - VdbeCoverage(v); + if( (pTerm->eOperator & WO_ISNULL)==0 ){ + Expr *pRight = 0; + if( pTerm->eOperator & WO_IN ){ + if( pTerm->pExpr->flags & EP_xIsSelect ){ + int iField = pTerm->iField ? pTerm->iField-1 : 0; + pRight = pTerm->pExpr->x.pSelect->pEList->a[iField].pExpr; + } + }else{ + pRight = pTerm->pExpr->pRight; + if( (pTerm->wtFlags & TERM_IS)==0 && sqlite3ExprCanBeNull(pRight) ){ + sqlite3VdbeAddOp2(v, OP_IsNull, regBase+j, pLevel->addrBrk); + VdbeCoverage(v); + } } - if( zAff ){ + if( pRight && zAff ){ if( sqlite3CompareAffinity(pRight, zAff[j])==SQLITE_AFF_BLOB ){ zAff[j] = SQLITE_AFF_BLOB; } diff --git a/test/rowvalue9.test b/test/rowvalue9.test new file mode 100644 index 0000000000..9e01e08932 --- /dev/null +++ b/test/rowvalue9.test @@ -0,0 +1,144 @@ +# 2016 September 3 +# +# 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 regression tests for SQLite library. The +# focus of this file is testing SQL statements that use row value +# constructors. +# + + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set ::testprefix rowvalue9 + +do_execsql_test 1.0.1 { + CREATE TABLE a1(c, b INTEGER, a TEXT, PRIMARY KEY(a, b)); + + INSERT INTO a1 (rowid, c, b, a) VALUES(3, '0x03', 1, 1); + INSERT INTO a1 (rowid, c, b, a) VALUES(14, '0x0E', 2, 2); + INSERT INTO a1 (rowid, c, b, a) VALUES(15, '0x0F', 3, 3); + INSERT INTO a1 (rowid, c, b, a) VALUES(92, '0x5C', 4, 4); + + CREATE TABLE a2(x BLOB, y BLOB); + INSERT INTO a2(x, y) VALUES(1, 1); + INSERT INTO a2(x, y) VALUES(2, '2'); + INSERT INTO a2(x, y) VALUES('3', 3); + INSERT INTO a2(x, y) VALUES('4', '4'); +} + +do_execsql_test 1.0.2 { + SELECT x, typeof(x), y, typeof(y) FROM a2 ORDER BY rowid +} { + 1 integer 1 integer + 2 integer 2 text + 3 text 3 integer + 4 text 4 text +} + +do_execsql_test 1.1.1 { + SELECT (SELECT rowid FROM a1 WHERE a=x AND b=y) FROM a2 +} {{} {} 15 92} +do_execsql_test 1.1.2 { + SELECT (SELECT rowid FROM a1 WHERE (a, b) = (x, y)) FROM a2 +} {{} {} 15 92} + +do_execsql_test 1.2.3 { + SELECT a1.rowid FROM a1, a2 WHERE a=x AND b=y; +} {15 92} +do_execsql_test 1.2.4 { + SELECT a1.rowid FROM a1, a2 WHERE (a, b) = (x, y) +} {15 92} + + +do_execsql_test 1.3.1 { + SELECT a1.rowid FROM a1, a2 WHERE coalesce(NULL,x)=a AND coalesce(NULL,y)=b +} {3 14 15 92} +do_execsql_test 1.3.2 { + SELECT a1.rowid FROM a1, a2 + WHERE (coalesce(NULL,x), coalesce(NULL,y)) = (a, b) +} {3 14 15 92} + +do_execsql_test 1.4.1 { + SELECT a1.rowid FROM a1, a2 WHERE +x=a AND +y=b +} {3 14 15 92} +do_execsql_test 1.4.2 { + SELECT a1.rowid FROM a1, a2 WHERE (+x, +y) = (a, b) +} {3 14 15 92} + +do_execsql_test 1.5.1 { + SELECT (SELECT rowid FROM a1 WHERE a=+x AND b=+y) FROM a2 +} {3 14 15 92} +do_execsql_test 1.5.2 { + SELECT (SELECT rowid FROM a1 WHERE (a, b) = (+x, +y)) FROM a2 +} {3 14 15 92} +do_execsql_test 1.5.3 { + SELECT (SELECT rowid FROM a1 WHERE (+x, +y) = (a, b)) FROM a2 +} {3 14 15 92} + +do_execsql_test 1.6.1 { + SELECT a1.rowid FROM a1 WHERE (a, b) IN (SELECT x, y FROM a2) +} {15 92} + +do_execsql_test 1.6.2 { + SELECT a1.rowid FROM a1, a2 WHERE EXISTS ( + SELECT 1 FROM a1 WHERE a=x AND b=y + ) +} {3 14 15 92 3 14 15 92} + +do_execsql_test 2.1 { + CREATE TABLE b1(a TEXT); + CREATE TABLE b2(x BLOB); + + INSERT INTO b1 VALUES(1); + INSERT INTO b2 VALUES(1); +} + +do_execsql_test 2.2 { SELECT * FROM b1, b2 WHERE a=x; } {} +do_execsql_test 2.3 { SELECT * FROM b1 WHERE a IN (SELECT x FROM b2) } {} + +do_execsql_test 2.4 { + CREATE UNIQUE INDEX b1a ON b1(a); +} +do_execsql_test 2.5 { SELECT * FROM b1 WHERE a IN (SELECT x FROM b2) } {} + +do_execsql_test 3.1 { + CREATE TABLE c1(a INTEGER, b TEXT); + INSERT INTO c1 VALUES(1, 1); + + CREATE TABLE c2(x BLOB, y BLOB); + INSERT INTO c2 VALUES(1, 1); +} +do_execsql_test 3.2 { + SELECT * FROM c1 WHERE (a, b) IN (SELECT x, y FROM c2) +} {} +do_execsql_test 3.3 { + CREATE UNIQUE INDEX c1ab ON c1(a, b); + SELECT * FROM c1 WHERE (a, b) IN (SELECT x, y FROM c2) +} {} + +do_execsql_test 4.0 { + CREATE TABLE d1(a TEXT); + CREATE TABLE d2(x BLOB); + INSERT INTO d1 VALUES(1); + INSERT INTO d2 VALUES(1); +} +do_execsql_test 4.1 { + SELECT * FROM d1 WHERE a IN (SELECT x FROM b2) +} {} +do_execsql_test 4.2 { + CREATE UNIQUE INDEX d1a ON d1(a); +} +do_execsql_test 4.3 { + SELECT * FROM d1 WHERE a IN (SELECT x FROM d2) +} {} + + +finish_test + From 9f6dd025ba84d927c654b290bb23fa9a1630badc Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 3 Sep 2016 16:23:42 +0000 Subject: [PATCH 0786/1484] Build the generate_series(START,END,STEP) table-valued function into fuzzershell, to make it easier to construct compact test cases that contain actual data. FossilOrigin-Name: 672c21bcf09c5bfb67e061456a56be45409c4f34 --- manifest | 14 +- manifest.uuid | 2 +- tool/fuzzershell.c | 321 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 329 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index c643135037..60518ebe7c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sa\stest\scase\sfor\sthe\sOOM\shandled\sby\sthe\sprevious\scommit. -D 2016-09-02T21:34:17.199 +C Build\sthe\sgenerate_series(START,END,STEP)\stable-valued\sfunction\sinto\nfuzzershell,\sto\smake\sit\seasier\sto\sconstruct\scompact\stest\scases\sthat\scontain\nactual\sdata. +D 2016-09-03T16:23:42.901 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5017381e4853b1472e01d5bb926be1268eba429c @@ -1434,7 +1434,7 @@ F tool/dbhash.c a06228aa21ebc4e6ea8daa486601d938499238a5 F tool/extract.c 054069d81b095fbdc189a6f5d4466e40380505e2 F tool/fast_vacuum.c 5ba0d6f5963a0a63bdc42840f678bad75b2ebce1 F tool/fragck.tcl 5265a95126abcf6ab357f7efa544787e5963f439 -F tool/fuzzershell.c 94019b185caceffc9f7c7b678a6489e42bc2aefa +F tool/fuzzershell.c f294ca67a10e87db76af130d75b2c94be36359c6 F tool/genfkey.README cf68fddd4643bbe3ff8e31b8b6d8b0a1b85e20f4 F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5 F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce @@ -1511,7 +1511,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d9d8a048d4b621435870b4f8dd13b2938ac2f8fd -R b03bceee349e62c9e4b232e967e75375 -U dan -Z 94198719997091b0b262fcfd62b5468a +P 9bdf7ca1b317fe0ba7efea38fb395bf6130ac89a +R f234dfb8eb81560f8891406102139ec1 +U drh +Z 8e05ee287619d9d44d13c4eb0cda4de7 diff --git a/manifest.uuid b/manifest.uuid index 33cb4d6b33..900a733d95 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9bdf7ca1b317fe0ba7efea38fb395bf6130ac89a \ No newline at end of file +672c21bcf09c5bfb67e061456a56be45409c4f34 \ No newline at end of file diff --git a/tool/fuzzershell.c b/tool/fuzzershell.c index 2c778bce6e..d19139d984 100644 --- a/tool/fuzzershell.c +++ b/tool/fuzzershell.c @@ -312,6 +312,326 @@ static void sqlEvalFunc( /* End of the eval() implementation ******************************************************************************/ +/****************************************************************************** +** The generate_series(START,END,STEP) eponymous table-valued function. +** +** This code is copy/pasted from ext/misc/series.c in the SQLite source tree. +*/ +/* series_cursor is a subclass of sqlite3_vtab_cursor which will +** serve as the underlying representation of a cursor that scans +** over rows of the result +*/ +typedef struct series_cursor series_cursor; +struct series_cursor { + sqlite3_vtab_cursor base; /* Base class - must be first */ + int isDesc; /* True to count down rather than up */ + sqlite3_int64 iRowid; /* The rowid */ + sqlite3_int64 iValue; /* Current value ("value") */ + sqlite3_int64 mnValue; /* Mimimum value ("start") */ + sqlite3_int64 mxValue; /* Maximum value ("stop") */ + sqlite3_int64 iStep; /* Increment ("step") */ +}; + +/* +** The seriesConnect() method is invoked to create a new +** series_vtab that describes the generate_series virtual table. +** +** Think of this routine as the constructor for series_vtab objects. +** +** All this routine needs to do is: +** +** (1) Allocate the series_vtab object and initialize all fields. +** +** (2) Tell SQLite (via the sqlite3_declare_vtab() interface) what the +** result set of queries against generate_series will look like. +*/ +static int seriesConnect( + sqlite3 *db, + void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVtab, + char **pzErr +){ + sqlite3_vtab *pNew; + int rc; + +/* Column numbers */ +#define SERIES_COLUMN_VALUE 0 +#define SERIES_COLUMN_START 1 +#define SERIES_COLUMN_STOP 2 +#define SERIES_COLUMN_STEP 3 + + rc = sqlite3_declare_vtab(db, + "CREATE TABLE x(value,start hidden,stop hidden,step hidden)"); + if( rc==SQLITE_OK ){ + pNew = *ppVtab = sqlite3_malloc( sizeof(*pNew) ); + if( pNew==0 ) return SQLITE_NOMEM; + memset(pNew, 0, sizeof(*pNew)); + } + return rc; +} + +/* +** This method is the destructor for series_cursor objects. +*/ +static int seriesDisconnect(sqlite3_vtab *pVtab){ + sqlite3_free(pVtab); + return SQLITE_OK; +} + +/* +** Constructor for a new series_cursor object. +*/ +static int seriesOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){ + series_cursor *pCur; + pCur = sqlite3_malloc( sizeof(*pCur) ); + if( pCur==0 ) return SQLITE_NOMEM; + memset(pCur, 0, sizeof(*pCur)); + *ppCursor = &pCur->base; + return SQLITE_OK; +} + +/* +** Destructor for a series_cursor. +*/ +static int seriesClose(sqlite3_vtab_cursor *cur){ + sqlite3_free(cur); + return SQLITE_OK; +} + + +/* +** Advance a series_cursor to its next row of output. +*/ +static int seriesNext(sqlite3_vtab_cursor *cur){ + series_cursor *pCur = (series_cursor*)cur; + if( pCur->isDesc ){ + pCur->iValue -= pCur->iStep; + }else{ + pCur->iValue += pCur->iStep; + } + pCur->iRowid++; + return SQLITE_OK; +} + +/* +** Return values of columns for the row at which the series_cursor +** is currently pointing. +*/ +static int seriesColumn( + sqlite3_vtab_cursor *cur, /* The cursor */ + sqlite3_context *ctx, /* First argument to sqlite3_result_...() */ + int i /* Which column to return */ +){ + series_cursor *pCur = (series_cursor*)cur; + sqlite3_int64 x = 0; + switch( i ){ + case SERIES_COLUMN_START: x = pCur->mnValue; break; + case SERIES_COLUMN_STOP: x = pCur->mxValue; break; + case SERIES_COLUMN_STEP: x = pCur->iStep; break; + default: x = pCur->iValue; break; + } + sqlite3_result_int64(ctx, x); + return SQLITE_OK; +} + +/* +** Return the rowid for the current row. In this implementation, the +** rowid is the same as the output value. +*/ +static int seriesRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ + series_cursor *pCur = (series_cursor*)cur; + *pRowid = pCur->iRowid; + return SQLITE_OK; +} + +/* +** Return TRUE if the cursor has been moved off of the last +** row of output. +*/ +static int seriesEof(sqlite3_vtab_cursor *cur){ + series_cursor *pCur = (series_cursor*)cur; + if( pCur->isDesc ){ + return pCur->iValue < pCur->mnValue; + }else{ + return pCur->iValue > pCur->mxValue; + } +} + +/* True to cause run-time checking of the start=, stop=, and/or step= +** parameters. The only reason to do this is for testing the +** constraint checking logic for virtual tables in the SQLite core. +*/ +#ifndef SQLITE_SERIES_CONSTRAINT_VERIFY +# define SQLITE_SERIES_CONSTRAINT_VERIFY 0 +#endif + +/* +** This method is called to "rewind" the series_cursor object back +** to the first row of output. This method is always called at least +** once prior to any call to seriesColumn() or seriesRowid() or +** seriesEof(). +** +** The query plan selected by seriesBestIndex is passed in the idxNum +** parameter. (idxStr is not used in this implementation.) idxNum +** is a bitmask showing which constraints are available: +** +** 1: start=VALUE +** 2: stop=VALUE +** 4: step=VALUE +** +** Also, if bit 8 is set, that means that the series should be output +** in descending order rather than in ascending order. +** +** This routine should initialize the cursor and position it so that it +** is pointing at the first row, or pointing off the end of the table +** (so that seriesEof() will return true) if the table is empty. +*/ +static int seriesFilter( + sqlite3_vtab_cursor *pVtabCursor, + int idxNum, const char *idxStr, + int argc, sqlite3_value **argv +){ + series_cursor *pCur = (series_cursor *)pVtabCursor; + int i = 0; + if( idxNum & 1 ){ + pCur->mnValue = sqlite3_value_int64(argv[i++]); + }else{ + pCur->mnValue = 0; + } + if( idxNum & 2 ){ + pCur->mxValue = sqlite3_value_int64(argv[i++]); + }else{ + pCur->mxValue = 0xffffffff; + } + if( idxNum & 4 ){ + pCur->iStep = sqlite3_value_int64(argv[i++]); + if( pCur->iStep<1 ) pCur->iStep = 1; + }else{ + pCur->iStep = 1; + } + if( idxNum & 8 ){ + pCur->isDesc = 1; + pCur->iValue = pCur->mxValue; + if( pCur->iStep>0 ){ + pCur->iValue -= (pCur->mxValue - pCur->mnValue)%pCur->iStep; + } + }else{ + pCur->isDesc = 0; + pCur->iValue = pCur->mnValue; + } + pCur->iRowid = 1; + return SQLITE_OK; +} + +/* +** SQLite will invoke this method one or more times while planning a query +** that uses the generate_series virtual table. This routine needs to create +** a query plan for each invocation and compute an estimated cost for that +** plan. +** +** In this implementation idxNum is used to represent the +** query plan. idxStr is unused. +** +** The query plan is represented by bits in idxNum: +** +** (1) start = $value -- constraint exists +** (2) stop = $value -- constraint exists +** (4) step = $value -- constraint exists +** (8) output in descending order +*/ +static int seriesBestIndex( + sqlite3_vtab *tab, + sqlite3_index_info *pIdxInfo +){ + int i; /* Loop over constraints */ + int idxNum = 0; /* The query plan bitmask */ + int startIdx = -1; /* Index of the start= constraint, or -1 if none */ + int stopIdx = -1; /* Index of the stop= constraint, or -1 if none */ + int stepIdx = -1; /* Index of the step= constraint, or -1 if none */ + int nArg = 0; /* Number of arguments that seriesFilter() expects */ + + const struct sqlite3_index_constraint *pConstraint; + pConstraint = pIdxInfo->aConstraint; + for(i=0; inConstraint; i++, pConstraint++){ + if( pConstraint->usable==0 ) continue; + if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue; + switch( pConstraint->iColumn ){ + case SERIES_COLUMN_START: + startIdx = i; + idxNum |= 1; + break; + case SERIES_COLUMN_STOP: + stopIdx = i; + idxNum |= 2; + break; + case SERIES_COLUMN_STEP: + stepIdx = i; + idxNum |= 4; + break; + } + } + if( startIdx>=0 ){ + pIdxInfo->aConstraintUsage[startIdx].argvIndex = ++nArg; + pIdxInfo->aConstraintUsage[startIdx].omit= !SQLITE_SERIES_CONSTRAINT_VERIFY; + } + if( stopIdx>=0 ){ + pIdxInfo->aConstraintUsage[stopIdx].argvIndex = ++nArg; + pIdxInfo->aConstraintUsage[stopIdx].omit = !SQLITE_SERIES_CONSTRAINT_VERIFY; + } + if( stepIdx>=0 ){ + pIdxInfo->aConstraintUsage[stepIdx].argvIndex = ++nArg; + pIdxInfo->aConstraintUsage[stepIdx].omit = !SQLITE_SERIES_CONSTRAINT_VERIFY; + } + if( (idxNum & 3)==3 ){ + /* Both start= and stop= boundaries are available. This is the + ** the preferred case */ + pIdxInfo->estimatedCost = (double)(2 - ((idxNum&4)!=0)); + pIdxInfo->estimatedRows = 1000; + if( pIdxInfo->nOrderBy==1 ){ + if( pIdxInfo->aOrderBy[0].desc ) idxNum |= 8; + pIdxInfo->orderByConsumed = 1; + } + }else{ + /* If either boundary is missing, we have to generate a huge span + ** of numbers. Make this case very expensive so that the query + ** planner will work hard to avoid it. */ + pIdxInfo->estimatedCost = (double)2147483647; + pIdxInfo->estimatedRows = 2147483647; + } + pIdxInfo->idxNum = idxNum; + return SQLITE_OK; +} + +/* +** This following structure defines all the methods for the +** generate_series virtual table. +*/ +static sqlite3_module seriesModule = { + 0, /* iVersion */ + 0, /* xCreate */ + seriesConnect, /* xConnect */ + seriesBestIndex, /* xBestIndex */ + seriesDisconnect, /* xDisconnect */ + 0, /* xDestroy */ + seriesOpen, /* xOpen - open a cursor */ + seriesClose, /* xClose - close a cursor */ + seriesFilter, /* xFilter - configure scan constraints */ + seriesNext, /* xNext - advance a cursor */ + seriesEof, /* xEof - check for end of scan */ + seriesColumn, /* xColumn - read data */ + seriesRowid, /* xRowid - read data */ + 0, /* xUpdate */ + 0, /* xBegin */ + 0, /* xSync */ + 0, /* xCommit */ + 0, /* xRollback */ + 0, /* xFindMethod */ + 0, /* xRename */ +}; +/* END the generate_series(START,END,STEP) implementation +*********************************************************************************/ + /* ** Print sketchy documentation for this utility program */ @@ -729,6 +1049,7 @@ int main(int argc, char **argv){ #endif sqlite3_create_function(db, "eval", 1, SQLITE_UTF8, 0, sqlEvalFunc, 0, 0); sqlite3_create_function(db, "eval", 2, SQLITE_UTF8, 0, sqlEvalFunc, 0, 0); + sqlite3_create_module(db, "generate_series", &seriesModule, 0); sqlite3_limit(db, SQLITE_LIMIT_LENGTH, 1000000); if( zEncoding ) sqlexec(db, "PRAGMA encoding=%s", zEncoding); if( pageSize ) sqlexec(db, "PRAGMA pagesize=%d", pageSize); From 80aa545337b65289a0db4e73c97d763c357aad53 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 3 Sep 2016 19:52:12 +0000 Subject: [PATCH 0787/1484] Fix a problem causing the affinity of sub-select row-value elements to be ignored in some contextes. FossilOrigin-Name: 7d9bd22c0715ede2592ee1fa7ebc215aded1ca1b --- manifest | 18 ++++---- manifest.uuid | 2 +- src/expr.c | 6 +++ test/rowvalue9.test | 110 +++++++++++++++++++++++++++++++++++--------- test/types2.test | 2 +- 5 files changed, 105 insertions(+), 33 deletions(-) diff --git a/manifest b/manifest index 8837f64701..045ff79cbf 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sthe\sfuzzershell\senhancement\sfrom\strunk. -D 2016-09-03T16:24:43.721 +C Fix\sa\sproblem\scausing\sthe\saffinity\sof\ssub-select\srow-value\selements\sto\sbe\signored\sin\ssome\scontextes. +D 2016-09-03T19:52:12.432 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5017381e4853b1472e01d5bb926be1268eba429c @@ -338,7 +338,7 @@ F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7 F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c 76c084f0265f4a3cd1ecf17eee112a94f1ccbc05 -F src/expr.c 7e0470e2b82af8d6544132d81da18990d9b9c09d +F src/expr.c 23b595cc6e2b609d53c72343b3fe16ce8b5e446d F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c e2be0968c1adc679c87e467aa5b4f167588f38a8 F src/func.c 29cc9acb170ec1387b9f63eb52cd85f8de96c771 @@ -1028,7 +1028,7 @@ F test/rowvalue5.test a440d490c8c0bf606034c09d5c6bbf7840b98f95 F test/rowvalue6.test d19b54feb604d5601f8614b15e214e0774c01087 F test/rowvalue7.test 5d06ff19d9e6969e574a2e662a531dd0c67801a8 F test/rowvalue8.test 5900eddad9e2c3c2e26f1a95f74aafc1232ee5e0 -F test/rowvalue9.test ca4e07da993e455e2c34a11800cd5eecfa25dbea +F test/rowvalue9.test 749a471f237f3fcfdfbd902f850adff2d9963560 F test/rowvaluefault.test 7b16485e3f2b371f3e3d05455b8ded6d0c090244 F test/rtree.test 0c8d9dd458d6824e59683c19ab2ffa9ef946f798 F test/run-wordcount.sh 891e89c4c2d16e629cd45951d4ed899ad12afc09 @@ -1324,7 +1324,7 @@ F test/tt3_lookaside1.c 0377e202c3c2a50d688cb65ba203afeda6fafeb9 F test/tt3_stress.c c57d804716165811d979d4a719e05baccd79277f F test/tt3_vacuum.c 1753f45917699c9c1f66b64c717a717c9379f776 F test/types.test bf816ce73c7dfcfe26b700c19f97ef4050d194ff -F test/types2.test 3555aacf8ed8dc883356e59efc314707e6247a84 +F test/types2.test 1aeb81976841a91eef292723649b5c4fe3bc3cac F test/types3.test 99e009491a54f4dc02c06bdbc0c5eea56ae3e25a F test/unique.test 93f8b2ef5ea51b9495f8d6493429b1fd0f465264 F test/unique2.test 3674e9f2a3f1fbbfd4772ac74b7a97090d0f77d2 @@ -1522,7 +1522,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P f5e49855412e389a8a410db5d7ffb2e3634c5fa3 672c21bcf09c5bfb67e061456a56be45409c4f34 -R 66aa92e29e4f871901eff534f575b0fe -U drh -Z af3091527994ed297383eb80433196df +P ed206048484667e4fe6aaeadd65882537d74bd35 +R ebdd3ea482059f46220cc36bb6b2e41e +U dan +Z 13aac770e03afb07d71bee955ff12a59 diff --git a/manifest.uuid b/manifest.uuid index 1b53160d31..7dd209be18 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ed206048484667e4fe6aaeadd65882537d74bd35 \ No newline at end of file +7d9bd22c0715ede2592ee1fa7ebc215aded1ca1b \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 31df95c057..76f0d49081 100644 --- a/src/expr.c +++ b/src/expr.c @@ -61,6 +61,12 @@ char sqlite3ExprAffinity(Expr *pExpr){ if( op==TK_AGG_COLUMN || op==TK_COLUMN ){ return sqlite3TableColumnAffinity(pExpr->pTab, pExpr->iColumn); } + if( op==TK_SELECT_COLUMN ){ + assert( pExpr->pLeft->flags&EP_xIsSelect ); + return sqlite3ExprAffinity( + pExpr->pLeft->x.pSelect->pEList->a[pExpr->iColumn].pExpr + ); + } return pExpr->affinity; } diff --git a/test/rowvalue9.test b/test/rowvalue9.test index 9e01e08932..214eaccb7e 100644 --- a/test/rowvalue9.test +++ b/test/rowvalue9.test @@ -85,33 +85,31 @@ do_execsql_test 1.5.3 { do_execsql_test 1.6.1 { SELECT a1.rowid FROM a1 WHERE (a, b) IN (SELECT x, y FROM a2) } {15 92} - do_execsql_test 1.6.2 { SELECT a1.rowid FROM a1, a2 WHERE EXISTS ( SELECT 1 FROM a1 WHERE a=x AND b=y ) } {3 14 15 92 3 14 15 92} +# Test that [199df416] is fixed. +# do_execsql_test 2.1 { CREATE TABLE b1(a TEXT); CREATE TABLE b2(x BLOB); - INSERT INTO b1 VALUES(1); INSERT INTO b2 VALUES(1); } - do_execsql_test 2.2 { SELECT * FROM b1, b2 WHERE a=x; } {} do_execsql_test 2.3 { SELECT * FROM b1 WHERE a IN (SELECT x FROM b2) } {} - -do_execsql_test 2.4 { - CREATE UNIQUE INDEX b1a ON b1(a); -} +do_execsql_test 2.4 { CREATE UNIQUE INDEX b1a ON b1(a); } do_execsql_test 2.5 { SELECT * FROM b1 WHERE a IN (SELECT x FROM b2) } {} +# Test that a multi-column version of the query that revealed problem +# [199df416] also works. +# do_execsql_test 3.1 { CREATE TABLE c1(a INTEGER, b TEXT); INSERT INTO c1 VALUES(1, 1); - CREATE TABLE c2(x BLOB, y BLOB); INSERT INTO c2 VALUES(1, 1); } @@ -122,23 +120,91 @@ do_execsql_test 3.3 { CREATE UNIQUE INDEX c1ab ON c1(a, b); SELECT * FROM c1 WHERE (a, b) IN (SELECT x, y FROM c2) } {} +do_execsql_test 3.4 { + SELECT * FROM c1 WHERE (a, +b) IN (SELECT x, y FROM c2) +} {} +do_execsql_test 3.5 { + SELECT c1.rowid FROM c1 WHERE b = (SELECT y FROM c2); +} {} +do_execsql_test 3.6 { + SELECT c1.rowid FROM c1 WHERE (a, b) = (SELECT x, y FROM c2); +} {} + + +#------------------------------------------------------------------------- +# do_execsql_test 4.0 { - CREATE TABLE d1(a TEXT); - CREATE TABLE d2(x BLOB); - INSERT INTO d1 VALUES(1); - INSERT INTO d2 VALUES(1); -} -do_execsql_test 4.1 { - SELECT * FROM d1 WHERE a IN (SELECT x FROM b2) -} {} -do_execsql_test 4.2 { - CREATE UNIQUE INDEX d1a ON d1(a); -} -do_execsql_test 4.3 { - SELECT * FROM d1 WHERE a IN (SELECT x FROM d2) -} {} + CREATE TABLE d1(a TEXT, b INTEGER, c NUMERIC); + CREATE TABLE d2(x BLOB, y BLOB); + INSERT INTO d1 VALUES(1, 1, 1); + INSERT INTO d1 VALUES(2, 2, 2); + INSERT INTO d1 VALUES(3, 3, 3); + INSERT INTO d1 VALUES(4, 4, 4); + + INSERT INTO d2 VALUES (1, 1); + INSERT INTO d2 VALUES (2, '2'); + INSERT INTO d2 VALUES ('3', 3); + INSERT INTO d2 VALUES ('4', '4'); +} + +foreach {tn idx} { + 1 {} + 2 { CREATE INDEX idx ON d1(a) } + 3 { CREATE INDEX idx ON d1(a, c) } + 4 { CREATE INDEX idx ON d1(c) } + 5 { CREATE INDEX idx ON d1(c, a) } + + 6 { + CREATE INDEX idx ON d1(c, a) ; + CREATE INDEX idx1 ON d2(x, y); + } + + 7 { + CREATE INDEX idx ON d1(c, a) ; + CREATE UNIQUE INDEX idx2 ON d2(x, y) ; + } + + 8 { + CREATE INDEX idx ON d1(c) ; + CREATE UNIQUE INDEX idx2 ON d2(x); + } + +} { + execsql { DROP INDEX IF EXISTS idx } + execsql { DROP INDEX IF EXISTS idx2 } + execsql { DROP INDEX IF EXISTS idx3 } + execsql $idx + + do_execsql_test 4.$tn.1 { + SELECT rowid FROM d1 WHERE (a, c) IN (SELECT x, y FROM d2); + } {3 4} + + do_execsql_test 4.$tn.2 { + SELECT rowid FROM d1 WHERE (c, a) IN (SELECT x, y FROM d2); + } {2 4} + + do_execsql_test 4.$tn.3 { + SELECT rowid FROM d1 WHERE (+c, a) IN (SELECT x, y FROM d2); + } {2} + + do_execsql_test 4.$tn.4 { + SELECT rowid FROM d1 WHERE (c, a) = ( + SELECT x, y FROM d2 WHERE d2.rowid=d1.rowid + ); + } {2 4} + + do_execsql_test 4.$tn.5 { + SELECT d1.rowid FROM d1, d2 WHERE a = y; + } {2 4} + + do_execsql_test 4.$tn.6 { + SELECT d1.rowid FROM d1 WHERE a = ( + SELECT y FROM d2 where d2.rowid=d1.rowid + ); + } {2 4} +} finish_test diff --git a/test/types2.test b/test/types2.test index 4a70aa5fe2..d6d84e65b5 100644 --- a/test/types2.test +++ b/test/types2.test @@ -333,7 +333,7 @@ ifcapable subquery { test_boolset types2-8.8 {o IN (SELECT t FROM t4)} {7} test_boolset types2-8.9 {i IN (SELECT o FROM t4)} {9 10 11 12} test_boolset types2-8.6 {n IN (SELECT o FROM t4)} {9 10 11 12} - test_boolset types2-8.7 {t IN (SELECT o FROM t4)} {9 11} + test_boolset types2-8.7 {t IN (SELECT o FROM t4)} {} test_boolset types2-8.8 {o IN (SELECT o FROM t4)} {9 10} } From 5c3340bd4781d346c7f401ea800f68c6ecce1885 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 5 Sep 2016 09:44:45 +0000 Subject: [PATCH 0788/1484] Fix a crash that could occur under certain circumstances if the vectors on either side of a comparison operator were of a different size. FossilOrigin-Name: 42670935aba152ba774c2a8bdcbe72b943309d68 --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/expr.c | 32 +++++++++++++++++++++++++------- src/sqliteInt.h | 1 + src/whereexpr.c | 4 ++++ test/rowvalue4.test | 2 ++ 6 files changed, 42 insertions(+), 17 deletions(-) diff --git a/manifest b/manifest index 045ff79cbf..a3cbab4faf 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\scausing\sthe\saffinity\sof\ssub-select\srow-value\selements\sto\sbe\signored\sin\ssome\scontextes. -D 2016-09-03T19:52:12.432 +C Fix\sa\scrash\sthat\scould\soccur\sunder\scertain\scircumstances\sif\sthe\svectors\son\seither\sside\sof\sa\scomparison\soperator\swere\sof\sa\sdifferent\ssize. +D 2016-09-05T09:44:45.878 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5017381e4853b1472e01d5bb926be1268eba429c @@ -338,7 +338,7 @@ F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7 F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c 76c084f0265f4a3cd1ecf17eee112a94f1ccbc05 -F src/expr.c 23b595cc6e2b609d53c72343b3fe16ce8b5e446d +F src/expr.c 750ed16649d655fef117c6d983c7382acd625bfd F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c e2be0968c1adc679c87e467aa5b4f167588f38a8 F src/func.c 29cc9acb170ec1387b9f63eb52cd85f8de96c771 @@ -390,7 +390,7 @@ F src/shell.c 79dda477be6c96eba6e952a934957ad36f87acc7 F src/sqlite.h.in 4a030e254e204570444b34bf7d40fb4a5416089e F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae -F src/sqliteInt.h c9e010a79ab4ed7bdc910a24d8f08f3c6d5f822c +F src/sqliteInt.h e7afbfaa4033a4c1cf2aa7bbdd0eb27e4663ab3a F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 @@ -468,7 +468,7 @@ F src/walker.c 2d2cc7fb0f320f7f415215d7247f3c584141ac09 F src/where.c 48d705e5196a0611a7be90698eade455ee238536 F src/whereInt.h 14dd243e13b81cbb0a66063d38b70f93a7d6e613 F src/wherecode.c 8a9a53cb52dd8a75e07c85e3bc12c1604c735954 -F src/whereexpr.c 7f9ada866d48d15d09754ae819c1c40efe3b2aff +F src/whereexpr.c 571597ac8d761505f626e597884b2a03494053cd F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1023,7 +1023,7 @@ F test/rowid.test 5b7509f384f4f6fae1af3c8c104c8ca299fea18d F test/rowvalue.test 7d8482dde9023973615eaaca65647f33d70c1f01 F test/rowvalue2.test 060d238b7e5639a7c5630cb5e63e311b44efef2b F test/rowvalue3.test 01399b7bf150b0d41abce76c18072da777c2500c -F test/rowvalue4.test 9b40c9be9bdde30fc66cddbfdf6a5af37de4ccac +F test/rowvalue4.test 29494f1c66e73329d90027619ee6d22e7ffe0ebf F test/rowvalue5.test a440d490c8c0bf606034c09d5c6bbf7840b98f95 F test/rowvalue6.test d19b54feb604d5601f8614b15e214e0774c01087 F test/rowvalue7.test 5d06ff19d9e6969e574a2e662a531dd0c67801a8 @@ -1522,7 +1522,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ed206048484667e4fe6aaeadd65882537d74bd35 -R ebdd3ea482059f46220cc36bb6b2e41e +P 7d9bd22c0715ede2592ee1fa7ebc215aded1ca1b +R 26e65ef1f9dc6647fee64756ced37096 U dan -Z 13aac770e03afb07d71bee955ff12a59 +Z c125d50595ea7cb48721a8bf5a5398c8 diff --git a/manifest.uuid b/manifest.uuid index 7dd209be18..d05b3e11b2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7d9bd22c0715ede2592ee1fa7ebc215aded1ca1b \ No newline at end of file +42670935aba152ba774c2a8bdcbe72b943309d68 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 76f0d49081..cba90b8757 100644 --- a/src/expr.c +++ b/src/expr.c @@ -521,14 +521,9 @@ static void codeVectorCompare( Vdbe *v = pParse->pVdbe; Expr *pLeft = pExpr->pLeft; Expr *pRight = pExpr->pRight; - int nLeft = sqlite3ExprVectorSize(pLeft); - int nRight = sqlite3ExprVectorSize(pRight); - /* Check that both sides of the comparison are vectors, and that - ** both are the same length. */ - if( nLeft!=nRight ){ - sqlite3ErrorMsg(pParse, "row value misused"); - }else{ + if( sqlite3ExprCheckComparison(pParse, pLeft, pRight)==0 ){ + int nLeft = sqlite3ExprVectorSize(pLeft); int i; int regLeft = 0; int regRight = 0; @@ -2656,6 +2651,29 @@ int sqlite3ExprCheckIN(Parse *pParse, Expr *pIn){ } #endif +/* +** Expressions pLeft and pRight are the left and right sides of a comparison +** operator. If either pLeft or pRight is a vector and the other is not, or +** if they are both vectors but of a different size, leave an error message +** in the Parse object and return non-zero. Or, if there is no problem, +** return 0. +*/ +int sqlite3ExprCheckComparison(Parse *pParse, Expr *pLeft, Expr *pRight){ + int nLeft = sqlite3ExprVectorSize(pLeft); + int nRight = sqlite3ExprVectorSize(pRight); + if( nLeft!=nRight ){ + if( (pRight->flags & EP_xIsSelect) ){ + sqlite3SubselectError(pParse, nRight, nLeft); + }else if( pLeft->flags & EP_xIsSelect ){ + sqlite3SubselectError(pParse, nLeft, nRight); + }else{ + sqlite3ErrorMsg(pParse, "row value misused"); + } + return 1; + } + return 0; +} + #ifndef SQLITE_OMIT_SUBQUERY /* ** Generate code for an IN expression. diff --git a/src/sqliteInt.h b/src/sqliteInt.h index dbb18a7458..c2a49b08e3 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -4009,6 +4009,7 @@ int sqlite3ExprCheckIN(Parse*, Expr*); #else # define sqlite3ExprCheckIN(x,y) SQLITE_OK #endif +int sqlite3ExprCheckComparison(Parse*, Expr*, Expr*); #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 void sqlite3AnalyzeFunctions(void); diff --git a/src/whereexpr.c b/src/whereexpr.c index 00328989e7..582b42b0cf 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -952,6 +952,10 @@ static void exprAnalyze( Expr *pRight = sqlite3ExprSkipCollate(pExpr->pRight); u16 opMask = (pTerm->prereqRight & prereqLeft)==0 ? WO_ALL : WO_EQUIV; + if( pRight && sqlite3ExprCheckComparison(pParse, pLeft, pRight) ){ + return; + } + if( pTerm->iField>0 ){ assert( op==TK_IN ); assert( pLeft->op==TK_VECTOR ); diff --git a/test/rowvalue4.test b/test/rowvalue4.test index a30edcc262..f6a34f7260 100644 --- a/test/rowvalue4.test +++ b/test/rowvalue4.test @@ -47,6 +47,8 @@ foreach {tn s error} { 6 "SELECT * FROM t1 WHERE (a, b) IN (SELECT * FROM t1)" {sub-select returns 3 columns - expected 2} + 7 "SELECT * FROM t1 WHERE (c, c) <= 1" {row value misused} + 8 "SELECT * FROM t1 WHERE (b, b) <= 1" {row value misused} } { do_catchsql_test 2.$tn "$s" [list 1 $error] } From b29e60c4487b6abc55acd8e0fe1694c590f18412 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 5 Sep 2016 12:02:34 +0000 Subject: [PATCH 0789/1484] Catch vector size mismatch problems during name resolution to avoid later problems. FossilOrigin-Name: 56562a0346170cf7b72445976864b058437a8ac3 --- manifest | 27 +++++----- manifest.uuid | 2 +- src/expr.c | 119 +++++++++++++++++++++----------------------- src/resolve.c | 27 ++++++++++ src/whereexpr.c | 27 +++++----- test/rowvalue.test | 27 ++++++++++ test/rowvalue4.test | 2 +- test/subselect.test | 2 +- 8 files changed, 141 insertions(+), 92 deletions(-) diff --git a/manifest b/manifest index 045ff79cbf..e3076e225f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\scausing\sthe\saffinity\sof\ssub-select\srow-value\selements\sto\sbe\signored\sin\ssome\scontextes. -D 2016-09-03T19:52:12.432 +C Catch\svector\ssize\smismatch\sproblems\sduring\sname\sresolution\sto\savoid\slater\nproblems. +D 2016-09-05T12:02:34.649 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5017381e4853b1472e01d5bb926be1268eba429c @@ -338,7 +338,7 @@ F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7 F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c 76c084f0265f4a3cd1ecf17eee112a94f1ccbc05 -F src/expr.c 23b595cc6e2b609d53c72343b3fe16ce8b5e446d +F src/expr.c 942c417e84e835ce51c6b732afa0b4572110e1c1 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c e2be0968c1adc679c87e467aa5b4f167588f38a8 F src/func.c 29cc9acb170ec1387b9f63eb52cd85f8de96c771 @@ -383,7 +383,7 @@ F src/pragma.h 64c78a648751b9f4f297276c4eb7507b14b4628c F src/prepare.c 0fcf16eaacc90c1059055519a76b75b516a59a88 F src/printf.c a5f0ca08ddede803c241266abb46356ec748ded1 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 -F src/resolve.c d67b9a5cc33339256e2088c5a722745fc2ff5219 +F src/resolve.c 24f40fd0c3475821d1ad762a3f2c3455cc839b42 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c 38216d0b2d42a0f475abf86a84c3499e6421ba29 F src/shell.c 79dda477be6c96eba6e952a934957ad36f87acc7 @@ -468,7 +468,7 @@ F src/walker.c 2d2cc7fb0f320f7f415215d7247f3c584141ac09 F src/where.c 48d705e5196a0611a7be90698eade455ee238536 F src/whereInt.h 14dd243e13b81cbb0a66063d38b70f93a7d6e613 F src/wherecode.c 8a9a53cb52dd8a75e07c85e3bc12c1604c735954 -F src/whereexpr.c 7f9ada866d48d15d09754ae819c1c40efe3b2aff +F src/whereexpr.c c5ec87e234faf62ac2d4e7f7ce18fb1f4bd475ff F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1020,10 +1020,10 @@ F test/rollbackfault.test 0e646aeab8840c399cfbfa43daab46fd609cf04a F test/rowallock.test 3f88ec6819489d0b2341c7a7528ae17c053ab7cc F test/rowhash.test 0bc1d31415e4575d10cacf31e1a66b5cc0f8be81 F test/rowid.test 5b7509f384f4f6fae1af3c8c104c8ca299fea18d -F test/rowvalue.test 7d8482dde9023973615eaaca65647f33d70c1f01 +F test/rowvalue.test 753eb744b7efeb5ac643d35d6e1e5066452ccf79 F test/rowvalue2.test 060d238b7e5639a7c5630cb5e63e311b44efef2b F test/rowvalue3.test 01399b7bf150b0d41abce76c18072da777c2500c -F test/rowvalue4.test 9b40c9be9bdde30fc66cddbfdf6a5af37de4ccac +F test/rowvalue4.test 9b60544dcd0231a9fcbe1ec095edb16cdaa7ae13 F test/rowvalue5.test a440d490c8c0bf606034c09d5c6bbf7840b98f95 F test/rowvalue6.test d19b54feb604d5601f8614b15e214e0774c01087 F test/rowvalue7.test 5d06ff19d9e6969e574a2e662a531dd0c67801a8 @@ -1121,7 +1121,7 @@ F test/statfault.test f525a7bf633e50afd027700e9a486090684b1ac1 F test/stmt.test 64844332db69cf1a735fcb3e11548557fc95392f F test/subquery.test d7268d193dd33d5505df965399d3a594e76ae13f F test/subquery2.test 438f8a7da1457277b22e4176510f7659b286995f -F test/subselect.test ccec43f85d488c6c4b6f98ea2dfa95b6086871c0 +F test/subselect.test 0966aa8e720224dbd6a5e769a3ec2a723e332303 F test/substr.test 18f57c4ca8a598805c4d64e304c418734d843c1a F test/subtype1.test 7fe09496352f97053af1437150751be2d0a0cae8 F test/superlock.test ec94f0556b6488d97f71c79f9061ae08d9ab8f12 @@ -1522,7 +1522,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ed206048484667e4fe6aaeadd65882537d74bd35 -R ebdd3ea482059f46220cc36bb6b2e41e -U dan -Z 13aac770e03afb07d71bee955ff12a59 +P 7d9bd22c0715ede2592ee1fa7ebc215aded1ca1b +R 9a7c982f4a8ba0874174ff495f80018e +T *branch * early-vector-size-check +T *sym-early-vector-size-check * +T -sym-rowvalue * +U drh +Z 17a06585da7241edb65fdad418303946 diff --git a/manifest.uuid b/manifest.uuid index 7dd209be18..474117a10b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7d9bd22c0715ede2592ee1fa7ebc215aded1ca1b \ No newline at end of file +56562a0346170cf7b72445976864b058437a8ac3 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 76f0d49081..f604ae4fe2 100644 --- a/src/expr.c +++ b/src/expr.c @@ -522,75 +522,68 @@ static void codeVectorCompare( Expr *pLeft = pExpr->pLeft; Expr *pRight = pExpr->pRight; int nLeft = sqlite3ExprVectorSize(pLeft); - int nRight = sqlite3ExprVectorSize(pRight); + int i; + int regLeft = 0; + int regRight = 0; + u8 opx = op; + int addrDone = sqlite3VdbeMakeLabel(v); - /* Check that both sides of the comparison are vectors, and that - ** both are the same length. */ - if( nLeft!=nRight ){ - sqlite3ErrorMsg(pParse, "row value misused"); - }else{ - int i; - int regLeft = 0; - int regRight = 0; - u8 opx = op; - int addrDone = sqlite3VdbeMakeLabel(v); + assert( nLeft==sqlite3ExprVectorSize(pRight) ); + assert( pExpr->op==TK_EQ || pExpr->op==TK_NE + || pExpr->op==TK_IS || pExpr->op==TK_ISNOT + || pExpr->op==TK_LT || pExpr->op==TK_GT + || pExpr->op==TK_LE || pExpr->op==TK_GE + ); + assert( pExpr->op==op || (pExpr->op==TK_IS && op==TK_EQ) + || (pExpr->op==TK_ISNOT && op==TK_NE) ); + assert( p5==0 || pExpr->op!=op ); + assert( p5==SQLITE_NULLEQ || pExpr->op==op ); - assert( pExpr->op==TK_EQ || pExpr->op==TK_NE - || pExpr->op==TK_IS || pExpr->op==TK_ISNOT - || pExpr->op==TK_LT || pExpr->op==TK_GT - || pExpr->op==TK_LE || pExpr->op==TK_GE - ); - assert( pExpr->op==op || (pExpr->op==TK_IS && op==TK_EQ) - || (pExpr->op==TK_ISNOT && op==TK_NE) ); - assert( p5==0 || pExpr->op!=op ); - assert( p5==SQLITE_NULLEQ || pExpr->op==op ); + p5 |= SQLITE_STOREP2; + if( opx==TK_LE ) opx = TK_LT; + if( opx==TK_GE ) opx = TK_GT; - p5 |= SQLITE_STOREP2; - if( opx==TK_LE ) opx = TK_LT; - if( opx==TK_GE ) opx = TK_GT; + regLeft = exprCodeSubselect(pParse, pLeft); + regRight = exprCodeSubselect(pParse, pRight); - regLeft = exprCodeSubselect(pParse, pLeft); - regRight = exprCodeSubselect(pParse, pRight); - - for(i=0; 1 /*Loop exits by "break"*/; i++){ - int regFree1 = 0, regFree2 = 0; - Expr *pL, *pR; - int r1, r2; - assert( i>=0 && i0 ) sqlite3ExprCachePush(pParse); - r1 = exprVectorRegister(pParse, pLeft, i, regLeft, &pL, ®Free1); - r2 = exprVectorRegister(pParse, pRight, i, regRight, &pR, ®Free2); - codeCompare(pParse, pL, pR, opx, r1, r2, dest, p5); - testcase(op==OP_Lt); VdbeCoverageIf(v,op==OP_Lt); - testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le); - testcase(op==OP_Gt); VdbeCoverageIf(v,op==OP_Gt); - testcase(op==OP_Ge); VdbeCoverageIf(v,op==OP_Ge); - testcase(op==OP_Eq); VdbeCoverageIf(v,op==OP_Eq); - testcase(op==OP_Ne); VdbeCoverageIf(v,op==OP_Ne); - sqlite3ReleaseTempReg(pParse, regFree1); - sqlite3ReleaseTempReg(pParse, regFree2); - if( i>0 ) sqlite3ExprCachePop(pParse); - if( i==nLeft-1 ){ - break; - } - if( opx==TK_EQ ){ - sqlite3VdbeAddOp2(v, OP_IfNot, dest, addrDone); VdbeCoverage(v); - p5 |= SQLITE_KEEPNULL; - }else if( opx==TK_NE ){ - sqlite3VdbeAddOp2(v, OP_If, dest, addrDone); VdbeCoverage(v); - p5 |= SQLITE_KEEPNULL; - }else{ - assert( op==TK_LT || op==TK_GT || op==TK_LE || op==TK_GE ); - sqlite3VdbeAddOp2(v, OP_ElseNotEq, 0, addrDone); - VdbeCoverageIf(v, op==TK_LT); - VdbeCoverageIf(v, op==TK_GT); - VdbeCoverageIf(v, op==TK_LE); - VdbeCoverageIf(v, op==TK_GE); - if( i==nLeft-2 ) opx = op; - } + for(i=0; 1 /*Loop exits by "break"*/; i++){ + int regFree1 = 0, regFree2 = 0; + Expr *pL, *pR; + int r1, r2; + assert( i>=0 && i0 ) sqlite3ExprCachePush(pParse); + r1 = exprVectorRegister(pParse, pLeft, i, regLeft, &pL, ®Free1); + r2 = exprVectorRegister(pParse, pRight, i, regRight, &pR, ®Free2); + codeCompare(pParse, pL, pR, opx, r1, r2, dest, p5); + testcase(op==OP_Lt); VdbeCoverageIf(v,op==OP_Lt); + testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le); + testcase(op==OP_Gt); VdbeCoverageIf(v,op==OP_Gt); + testcase(op==OP_Ge); VdbeCoverageIf(v,op==OP_Ge); + testcase(op==OP_Eq); VdbeCoverageIf(v,op==OP_Eq); + testcase(op==OP_Ne); VdbeCoverageIf(v,op==OP_Ne); + sqlite3ReleaseTempReg(pParse, regFree1); + sqlite3ReleaseTempReg(pParse, regFree2); + if( i>0 ) sqlite3ExprCachePop(pParse); + if( i==nLeft-1 ){ + break; + } + if( opx==TK_EQ ){ + sqlite3VdbeAddOp2(v, OP_IfNot, dest, addrDone); VdbeCoverage(v); + p5 |= SQLITE_KEEPNULL; + }else if( opx==TK_NE ){ + sqlite3VdbeAddOp2(v, OP_If, dest, addrDone); VdbeCoverage(v); + p5 |= SQLITE_KEEPNULL; + }else{ + assert( op==TK_LT || op==TK_GT || op==TK_LE || op==TK_GE ); + sqlite3VdbeAddOp2(v, OP_ElseNotEq, 0, addrDone); + VdbeCoverageIf(v, op==TK_LT); + VdbeCoverageIf(v, op==TK_GT); + VdbeCoverageIf(v, op==TK_LE); + VdbeCoverageIf(v, op==TK_GE); + if( i==nLeft-2 ) opx = op; } - sqlite3VdbeResolveLabel(v, addrDone); } + sqlite3VdbeResolveLabel(v, addrDone); } #if SQLITE_MAX_EXPR_DEPTH>0 diff --git a/src/resolve.c b/src/resolve.c index 206015fcfa..a5cc06b919 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -776,6 +776,33 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ notValid(pParse, pNC, "parameters", NC_IsCheck|NC_PartIdx|NC_IdxExpr); break; } + case TK_EQ: + case TK_NE: + case TK_LT: + case TK_LE: + case TK_GT: + case TK_GE: + case TK_IS: + case TK_ISNOT: { + int nLeft, nRight; + if( pParse->db->mallocFailed ) break; + assert( pExpr->pRight!=0 ); + assert( pExpr->pLeft!=0 ); + nLeft = sqlite3ExprVectorSize(pExpr->pLeft); + nRight = sqlite3ExprVectorSize(pExpr->pRight); + if( nLeft!=nRight ){ + testcase( pExpr->op==TK_EQ ); + testcase( pExpr->op==TK_NE ); + testcase( pExpr->op==TK_LT ); + testcase( pExpr->op==TK_LE ); + testcase( pExpr->op==TK_GT ); + testcase( pExpr->op==TK_GE ); + testcase( pExpr->op==TK_IS ); + testcase( pExpr->op==TK_ISNOT ); + sqlite3ErrorMsg(pParse, "row value misused"); + } + break; + } } return (pParse->nErr || pParse->db->mallocFailed) ? WRC_Abort : WRC_Continue; } diff --git a/src/whereexpr.c b/src/whereexpr.c index 00328989e7..92aed29bbc 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -1188,22 +1188,21 @@ static void exprAnalyze( || (pExpr->pRight->flags & EP_xIsSelect)==0 )){ int nLeft = sqlite3ExprVectorSize(pExpr->pLeft); - if( nLeft==sqlite3ExprVectorSize(pExpr->pRight) ){ - int i; - for(i=0; ipLeft); i++){ - int idxNew; - Expr *pNew; - Expr *pLeft = sqlite3ExprForVectorField(pParse, pExpr->pLeft, i); - Expr *pRight = sqlite3ExprForVectorField(pParse, pExpr->pRight, i); + int i; + assert( nLeft==sqlite3ExprVectorSize(pExpr->pRight) ); + for(i=0; ipLeft, i); + Expr *pRight = sqlite3ExprForVectorField(pParse, pExpr->pRight, i); - pNew = sqlite3PExpr(pParse, pExpr->op, pLeft, pRight, 0); - idxNew = whereClauseInsert(pWC, pNew, TERM_DYNAMIC); - exprAnalyze(pSrc, pWC, idxNew); - } - pTerm = &pWC->a[idxTerm]; - pTerm->wtFlags = TERM_CODED|TERM_VIRTUAL; /* Disable the original */ - pTerm->eOperator = 0; + pNew = sqlite3PExpr(pParse, pExpr->op, pLeft, pRight, 0); + idxNew = whereClauseInsert(pWC, pNew, TERM_DYNAMIC); + exprAnalyze(pSrc, pWC, idxNew); } + pTerm = &pWC->a[idxTerm]; + pTerm->wtFlags = TERM_CODED|TERM_VIRTUAL; /* Disable the original */ + pTerm->eOperator = 0; } /* If there is a vector IN term - e.g. "(a, b) IN (SELECT ...)" - create diff --git a/test/rowvalue.test b/test/rowvalue.test index f716c26c8b..f53d5328ca 100644 --- a/test/rowvalue.test +++ b/test/rowvalue.test @@ -229,4 +229,31 @@ do_execsql_test 10.0 { AND (a,b,e) IN (SELECT 'a','b','d' FROM dual); } +do_catchsql_test 11.1 { + CREATE TABLE t11(a); + SELECT * FROM t11 WHERE (a,a)<=1; +} {1 {row value misused}} +do_catchsql_test 11.2 { + SELECT * FROM t11 WHERE (a,a)<1; +} {1 {row value misused}} +do_catchsql_test 11.3 { + SELECT * FROM t11 WHERE (a,a)>=1; +} {1 {row value misused}} +do_catchsql_test 11.4 { + SELECT * FROM t11 WHERE (a,a)>1; +} {1 {row value misused}} +do_catchsql_test 11.5 { + SELECT * FROM t11 WHERE (a,a)==1; +} {1 {row value misused}} +do_catchsql_test 11.6 { + SELECT * FROM t11 WHERE (a,a)<>1; +} {1 {row value misused}} +do_catchsql_test 11.7 { + SELECT * FROM t11 WHERE (a,a) IS 1; +} {1 {row value misused}} +do_catchsql_test 11.8 { + SELECT * FROM t11 WHERE (a,a) IS NOT 1; +} {1 {row value misused}} + + finish_test diff --git a/test/rowvalue4.test b/test/rowvalue4.test index a30edcc262..d3d5e46c7e 100644 --- a/test/rowvalue4.test +++ b/test/rowvalue4.test @@ -306,6 +306,6 @@ do_catchsql_test 8.2 { SELECT * FROM c2 CROSS JOIN c3 WHERE ( (a, b) == (SELECT x, y FROM c1) AND c3.d = c ) OR ( c == (SELECT x, y FROM c1) AND c3.d = c ) -} {1 {sub-select returns 2 columns - expected 1}} +} {1 {row value misused}} finish_test diff --git a/test/subselect.test b/test/subselect.test index fc1c103085..4d0efde47a 100644 --- a/test/subselect.test +++ b/test/subselect.test @@ -40,7 +40,7 @@ do_test subselect-1.1 { do_test subselect-1.2 { set v [catch {execsql {SELECT * FROM t1 WHERE a = (SELECT * FROM t1)}} msg] lappend v $msg -} {1 {sub-select returns 2 columns - expected 1}} +} {1 {row value misused}} # A subselect without an aggregate. # From 3fffbf932719916b9a6564280b1254ce4f6c5012 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 5 Sep 2016 15:02:41 +0000 Subject: [PATCH 0790/1484] Simplifications to the SQLITE_KEEPNULL flag on VDBE comparison operators. FossilOrigin-Name: 96269f0179a7d8fa44ee278cef362962368c59ef --- manifest | 13 ++++++------- manifest.uuid | 2 +- src/vdbe.c | 19 +++++++++++++++---- 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 22dc90908e..050f3253f6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Do\svector\scomparison\ssize\schecking\searly\s-\sat\sname\sresolution\stime\s-\sto\nforestall\sfuture\sproblems. -D 2016-09-05T12:12:56.221 +C Simplifications\sto\sthe\sSQLITE_KEEPNULL\sflag\son\sVDBE\scomparison\soperators. +D 2016-09-05T15:02:41.820 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5017381e4853b1472e01d5bb926be1268eba429c @@ -451,7 +451,7 @@ F src/update.c 8179e699dbd45b92934fd02d3d8e3732e8da8802 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 810ec3f22e2d1b62e66c30fe3621ebdedd23584d F src/vacuum.c 913970b9d86dd6c2b8063ef1af421880f1464ec3 -F src/vdbe.c d8fb59a3ef10636df2447f55c1e82be7b8ad1604 +F src/vdbe.c 3148d5d47816c5ad2ed3c62beb3086cbbcaab107 F src/vdbe.h 67bc551f7faf04c33493892e4b378aada823ed10 F src/vdbeInt.h c59381049af5c7751a83456c39b80d1a6fde1f9d F src/vdbeapi.c a32d61b7dd05e6890d8fd44d2805f55e2f5ba9f3 @@ -1522,8 +1522,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 42670935aba152ba774c2a8bdcbe72b943309d68 56562a0346170cf7b72445976864b058437a8ac3 -R 9ea9c6d7e55a2e73634a9a6491229b09 -T +closed 56562a0346170cf7b72445976864b058437a8ac3 +P ae127bcc0a5827786853f47b229021435d6098d7 +R b6639bee17b9273a45c7e5e2da3019f4 U drh -Z c545a18fc0ce61b83efad3cc467f4a6a +Z a8418630f7d7128d87f9b291fb48ec92 diff --git a/manifest.uuid b/manifest.uuid index a64a078eae..1973c3697e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ae127bcc0a5827786853f47b229021435d6098d7 \ No newline at end of file +96269f0179a7d8fa44ee278cef362962368c59ef \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 443ecbce1d..c3c9c607cb 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -1912,7 +1912,8 @@ case OP_Cast: { /* in1 */ ** the SQLITE_NULLEQ flag were omitted from P5. ** ** If both SQLITE_STOREP2 and SQLITE_KEEPNULL flags are set then the -** content of r[P2] is only set to 1 (true) if it was not previously NULL. +** content of r[P2] is only changed if the new value is NULL or 0 (false). +** In other words, a prior r[P2] value will not be overwritten by 1 (true). */ /* Opcode: Ne P1 P2 P3 P4 P5 ** Synopsis: IF r[P3]!=r[P1] @@ -1922,7 +1923,8 @@ case OP_Cast: { /* in1 */ ** additional information. ** ** If both SQLITE_STOREP2 and SQLITE_KEEPNULL flags are set then the -** content of r[P2] is only set to 0 (false) if it was not previously NULL. +** content of r[P2] is only changed if the new value is NULL or 1 (true). +** In other words, a prior r[P2] value will not be overwritten by 0 (false). */ /* Opcode: Lt P1 P2 P3 P4 P5 ** Synopsis: IF r[P3]p2]; iCompare = res; res2 = res2!=0; /* For this path res2 must be exactly 0 or 1 */ - if( (pOp->p5 & SQLITE_KEEPNULL)!=0 && (pOut->flags & MEM_Null)!=0 ){ + if( (pOp->p5 & SQLITE_KEEPNULL)!=0 ){ /* The KEEPNULL flag prevents OP_Eq from overwriting a NULL with 1 - ** and prevents OP_Ne from overwriting NULL with 0. */ + ** and prevents OP_Ne from overwriting NULL with 0. This flag + ** is only used in contexts where either: + ** (1) op==OP_Eq && (r[P2]==NULL || r[P2]==0) + ** (2) op==OP_Ne && (r[P2]==NULL || r[P2]==1) + ** Therefore it is not necessary to check the content of r[P2] for + ** NULL. */ assert( pOp->opcode==OP_Ne || pOp->opcode==OP_Eq ); assert( res2==0 || res2==1 ); + testcase( res2==0 && pOp->opcode==OP_Eq ); + testcase( res2==1 && pOp->opcode==OP_Eq ); + testcase( res2==0 && pOp->opcode==OP_Ne ); + testcase( res2==1 && pOp->opcode==OP_Ne ); if( (pOp->opcode==OP_Eq)==res2 ) break; } memAboutToChange(p, pOut); From c1bcd9cc3e9913acec4d8b04178d52826f82eb2d Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 5 Sep 2016 19:57:46 +0000 Subject: [PATCH 0791/1484] Fix an assert() so that it does C-compiler does not combine an assert() conditional with a production code conditional and thereby confuse the mutation testing script. FossilOrigin-Name: 2fa5288a7ef43f1fb26037c1b5e84b7b90400623 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/expr.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 050f3253f6..a7e3009364 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Simplifications\sto\sthe\sSQLITE_KEEPNULL\sflag\son\sVDBE\scomparison\soperators. -D 2016-09-05T15:02:41.820 +C Fix\san\sassert()\sso\sthat\sit\sdoes\sC-compiler\sdoes\snot\scombine\san\sassert()\nconditional\swith\sa\sproduction\scode\sconditional\sand\sthereby\sconfuse\sthe\smutation\ntesting\sscript. +D 2016-09-05T19:57:46.769 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5017381e4853b1472e01d5bb926be1268eba429c @@ -338,7 +338,7 @@ F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7 F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c 76c084f0265f4a3cd1ecf17eee112a94f1ccbc05 -F src/expr.c 942c417e84e835ce51c6b732afa0b4572110e1c1 +F src/expr.c 48b18962e32c22be92eb00ef941499f4c80efd2c F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c e2be0968c1adc679c87e467aa5b4f167588f38a8 F src/func.c 29cc9acb170ec1387b9f63eb52cd85f8de96c771 @@ -1522,7 +1522,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ae127bcc0a5827786853f47b229021435d6098d7 -R b6639bee17b9273a45c7e5e2da3019f4 +P 96269f0179a7d8fa44ee278cef362962368c59ef +R 2715120448e06410de8fb9d7dcf49e0c U drh -Z a8418630f7d7128d87f9b291fb48ec92 +Z 8e9c25e5732d609d10738e0bb4ef6b76 diff --git a/manifest.uuid b/manifest.uuid index 1973c3697e..9849952ab4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -96269f0179a7d8fa44ee278cef362962368c59ef \ No newline at end of file +2fa5288a7ef43f1fb26037c1b5e84b7b90400623 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index f604ae4fe2..517034ca39 100644 --- a/src/expr.c +++ b/src/expr.c @@ -487,7 +487,7 @@ static int exprVectorRegister( int *pRegFree /* OUT: Temp register to free */ ){ u8 op = pVector->op; - assert( op==TK_VECTOR || op==TK_SELECT || op==TK_REGISTER ); + assert( op==TK_VECTOR || op==TK_REGISTER || op==TK_SELECT ); if( op==TK_REGISTER ){ *ppExpr = sqlite3VectorFieldSubexpr(pVector, iField); return pVector->iTable+iField; From cc0164b5dfb47438c3bbfce5903e064a4b93d9e1 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Mon, 5 Sep 2016 20:46:02 +0000 Subject: [PATCH 0792/1484] Sync up the MSVC makefiles. FossilOrigin-Name: f66d0d8cf6976c62f7bc0e9390b09fb9976178c1 --- Makefile.msc | 2 ++ autoconf/Makefile.msc | 10 ++++++++++ manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 20 insertions(+), 8 deletions(-) diff --git a/Makefile.msc b/Makefile.msc index 1569487aa3..9dd06b599a 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -277,6 +277,7 @@ SQLITE3EXEPDB = /pdb:sqlite3sh.pdb !ENDIF !ENDIF +# <> # These are the names of the customized Tcl header files used by various parts # of this makefile when the stdcall calling convention is in use. It is not # used for any other purpose. @@ -299,6 +300,7 @@ SQLITE_TCL_DEP = $(SQLITETCLDECLSH) $(SQLITETCLH) SQLITE_TCL_DEP = !ENDIF !ENDIF +# <> # These are the "standard" SQLite compilation options used when compiling for # the Windows platform. diff --git a/autoconf/Makefile.msc b/autoconf/Makefile.msc index d3bbc6b4d2..b53e2370eb 100644 --- a/autoconf/Makefile.msc +++ b/autoconf/Makefile.msc @@ -31,6 +31,13 @@ USE_FULLWARN = 0 USE_RUNTIME_CHECKS = 0 !ENDIF +# Set this non-0 to create a SQLite amalgamation file that excludes the +# various built-in extensions. +# +!IFNDEF MINIMAL_AMALGAMATION +MINIMAL_AMALGAMATION = 0 +!ENDIF + # Set this non-0 to use "stdcall" calling convention for the core library # and shell executable. # @@ -255,12 +262,15 @@ SQLITE3EXEPDB = /pdb:sqlite3sh.pdb !ENDIF !ENDIF + # These are the "standard" SQLite compilation options used when compiling for # the Windows platform. # !IFNDEF OPT_FEATURE_FLAGS +!IF $(MINIMAL_AMALGAMATION)==0 OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_FTS3=1 OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_RTREE=1 +!ENDIF OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_COLUMN_METADATA=1 !ENDIF diff --git a/manifest b/manifest index 516b49f189..c87e7a94c8 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -C Merge\supdates\sfrom\strunk. -D 2016-09-05T20:40:38.608 +C Sync\sup\sthe\sMSVC\smakefiles. +D 2016-09-05T20:46:02.202 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 -F Makefile.msc 2a8f135e10f383a31f1106cf42edabf3a18a3d08 +F Makefile.msc 6fef1e10792656c94fe1393092de6c8ba6ea1c88 F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7 F VERSION 25e2e333adeff5965520bc8db999c658898c972d F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 @@ -11,7 +11,7 @@ F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am 1a47d071e3d5435f8f7ebff7eb6703848bbd65d4 -F autoconf/Makefile.msc 7a909aa9b538138a21c0626e3ffc4b1f4519f50e +F autoconf/Makefile.msc b6d27f735911fd09a589d3c966936c47a5850c17 F autoconf/README.first 6c4f34fe115ff55d4e8dbfa3cecf04a0188292f7 F autoconf/README.txt 4f04b0819303aabaa35fff5f7b257fb0c1ef95f1 F autoconf/configure.ac cacf2616abf6e4a569bde2ef365c143caeec40bc @@ -1511,7 +1511,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e4a56197b08546601bd6a623f667b43f50d603be 672c21bcf09c5bfb67e061456a56be45409c4f34 -R 1646f6bcd29be808598c5eaef7cdbbd2 +P ea635bf97edb35b95b34adcb63f726f3573b1c4d +R d8ebd39537a766e051577a29d6825c19 U mistachkin -Z 0df7884935e73ff5e3ea057f23c7e834 +Z 1961d7bb5f7d90748e74759804c9ac8c diff --git a/manifest.uuid b/manifest.uuid index 57dde5220f..a4d0903718 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ea635bf97edb35b95b34adcb63f726f3573b1c4d \ No newline at end of file +f66d0d8cf6976c62f7bc0e9390b09fb9976178c1 \ No newline at end of file From 9f24b53dcccf022ee9290f7c38872e288b1eaaa3 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 5 Sep 2016 22:50:48 +0000 Subject: [PATCH 0793/1484] Simplified logic to extract a column from a row value. FossilOrigin-Name: e8f105c3009e9b667db2afc0088b020a2b94d370 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/expr.c | 5 ++--- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index a7e3009364..dbde222f9f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\sassert()\sso\sthat\sit\sdoes\sC-compiler\sdoes\snot\scombine\san\sassert()\nconditional\swith\sa\sproduction\scode\sconditional\sand\sthereby\sconfuse\sthe\smutation\ntesting\sscript. -D 2016-09-05T19:57:46.769 +C Simplified\slogic\sto\sextract\sa\scolumn\sfrom\sa\srow\svalue. +D 2016-09-05T22:50:48.311 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5017381e4853b1472e01d5bb926be1268eba429c @@ -338,7 +338,7 @@ F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7 F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c 76c084f0265f4a3cd1ecf17eee112a94f1ccbc05 -F src/expr.c 48b18962e32c22be92eb00ef941499f4c80efd2c +F src/expr.c 32bbbf7ef8d0e49e346612b1832a51a3dcf41818 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c e2be0968c1adc679c87e467aa5b4f167588f38a8 F src/func.c 29cc9acb170ec1387b9f63eb52cd85f8de96c771 @@ -1522,7 +1522,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 96269f0179a7d8fa44ee278cef362962368c59ef -R 2715120448e06410de8fb9d7dcf49e0c +P 2fa5288a7ef43f1fb26037c1b5e84b7b90400623 +R 7603658287e131d43381ef690aa890bc U drh -Z 8e9c25e5732d609d10738e0bb4ef6b76 +Z 751e7d4fc1004371a10bd2fdff652b35 diff --git a/manifest.uuid b/manifest.uuid index 9849952ab4..b0fd78e535 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2fa5288a7ef43f1fb26037c1b5e84b7b90400623 \ No newline at end of file +e8f105c3009e9b667db2afc0088b020a2b94d370 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 517034ca39..a21ca05d51 100644 --- a/src/expr.c +++ b/src/expr.c @@ -371,9 +371,8 @@ int sqlite3ExprVectorSize(Expr *pExpr){ Expr *sqlite3VectorFieldSubexpr(Expr *pVector, int i){ assert( iop==TK_SELECT - || (pVector->op==TK_REGISTER && pVector->op2==TK_SELECT) - ){ + assert( pVector->op2==0 || pVector->op==TK_REGISTER ); + if( pVector->op==TK_SELECT || pVector->op2==TK_SELECT ){ return pVector->x.pSelect->pEList->a[i].pExpr; }else{ return pVector->x.pList->a[i].pExpr; From fad0e70c637cd210cd1696693e5c64ed64ce2cd3 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 6 Sep 2016 12:04:50 +0000 Subject: [PATCH 0794/1484] Fix a typo in a comment in expr.c. FossilOrigin-Name: 288e934f356ff6276b3e7581ac0f998ca6e93610 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/expr.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index dbde222f9f..8e1a6947e5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Simplified\slogic\sto\sextract\sa\scolumn\sfrom\sa\srow\svalue. -D 2016-09-05T22:50:48.311 +C Fix\sa\stypo\sin\sa\scomment\sin\sexpr.c. +D 2016-09-06T12:04:50.217 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5017381e4853b1472e01d5bb926be1268eba429c @@ -338,7 +338,7 @@ F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7 F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c 76c084f0265f4a3cd1ecf17eee112a94f1ccbc05 -F src/expr.c 32bbbf7ef8d0e49e346612b1832a51a3dcf41818 +F src/expr.c 17af5dc7326543ce395503adc1b88b0a722fcee3 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c e2be0968c1adc679c87e467aa5b4f167588f38a8 F src/func.c 29cc9acb170ec1387b9f63eb52cd85f8de96c771 @@ -1522,7 +1522,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 2fa5288a7ef43f1fb26037c1b5e84b7b90400623 -R 7603658287e131d43381ef690aa890bc -U drh -Z 751e7d4fc1004371a10bd2fdff652b35 +P e8f105c3009e9b667db2afc0088b020a2b94d370 +R 48ea3338c1b6c2a2aac4971ca7c78062 +U dan +Z 231ae31b564ec961477419ce2ce3ecda diff --git a/manifest.uuid b/manifest.uuid index b0fd78e535..ea64ef4497 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e8f105c3009e9b667db2afc0088b020a2b94d370 \ No newline at end of file +288e934f356ff6276b3e7581ac0f998ca6e93610 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index a21ca05d51..f0bfdb0a7a 100644 --- a/src/expr.c +++ b/src/expr.c @@ -395,7 +395,7 @@ Expr *sqlite3VectorFieldSubexpr(Expr *pVector, int i){ ** ensuring that the returned value eventually gets freed. ** ** The caller retains ownership of pVector. If pVector is a TK_SELECT, -** then the returne object will reference pVector and so pVector must remain +** then the returned object will reference pVector and so pVector must remain ** valid for the life of the returned object. If pVector is a TK_VECTOR ** or a scalar expression, then it can be deleted as soon as this routine ** returns. From ed24da4b16fe235e0a5e9c41f92bfb45b5f3448e Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 6 Sep 2016 14:37:05 +0000 Subject: [PATCH 0795/1484] Enhance the sqlite3GetTempRange() and sqlite3ReleaseTempRange() internal routines so that they use sqlite3GetTempReg() and sqlite3ReleaseTempReg() when nReg==1. FossilOrigin-Name: 4071da2f87a2f24a279ac3bced8c794ad374b47c --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/expr.c | 7 ++++++- src/select.c | 6 +----- 4 files changed, 16 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index 8e1a6947e5..3f3f165fd4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\stypo\sin\sa\scomment\sin\sexpr.c. -D 2016-09-06T12:04:50.217 +C Enhance\sthe\ssqlite3GetTempRange()\sand\ssqlite3ReleaseTempRange()\sinternal\nroutines\sso\sthat\sthey\suse\ssqlite3GetTempReg()\sand\ssqlite3ReleaseTempReg()\nwhen\snReg==1. +D 2016-09-06T14:37:05.419 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5017381e4853b1472e01d5bb926be1268eba429c @@ -338,7 +338,7 @@ F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7 F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c 76c084f0265f4a3cd1ecf17eee112a94f1ccbc05 -F src/expr.c 17af5dc7326543ce395503adc1b88b0a722fcee3 +F src/expr.c 4c2b9886927fb6628560ad40d14b04946d71abbd F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c e2be0968c1adc679c87e467aa5b4f167588f38a8 F src/func.c 29cc9acb170ec1387b9f63eb52cd85f8de96c771 @@ -385,7 +385,7 @@ F src/printf.c a5f0ca08ddede803c241266abb46356ec748ded1 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c 24f40fd0c3475821d1ad762a3f2c3455cc839b42 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac -F src/select.c 38216d0b2d42a0f475abf86a84c3499e6421ba29 +F src/select.c 4ccfc554a2d2313b0ac364120b1db9b74c41b248 F src/shell.c 79dda477be6c96eba6e952a934957ad36f87acc7 F src/sqlite.h.in 4a030e254e204570444b34bf7d40fb4a5416089e F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1522,7 +1522,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e8f105c3009e9b667db2afc0088b020a2b94d370 -R 48ea3338c1b6c2a2aac4971ca7c78062 -U dan -Z 231ae31b564ec961477419ce2ce3ecda +P 288e934f356ff6276b3e7581ac0f998ca6e93610 +R 373bd5ec1c7378267f0ce69533be2f50 +U drh +Z c12fde59fd4c6cc2e37d73169853128b diff --git a/manifest.uuid b/manifest.uuid index ea64ef4497..aeeeb90ec5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -288e934f356ff6276b3e7581ac0f998ca6e93610 \ No newline at end of file +4071da2f87a2f24a279ac3bced8c794ad374b47c \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index f0bfdb0a7a..a83ede6cb5 100644 --- a/src/expr.c +++ b/src/expr.c @@ -4991,10 +4991,11 @@ void sqlite3ReleaseTempReg(Parse *pParse, int iReg){ } /* -** Allocate or deallocate a block of nReg consecutive registers +** Allocate or deallocate a block of nReg consecutive registers. */ int sqlite3GetTempRange(Parse *pParse, int nReg){ int i, n; + if( nReg==1 ) return sqlite3GetTempReg(pParse); i = pParse->iRangeReg; n = pParse->nRangeReg; if( nReg<=n ){ @@ -5008,6 +5009,10 @@ int sqlite3GetTempRange(Parse *pParse, int nReg){ return i; } void sqlite3ReleaseTempRange(Parse *pParse, int iReg, int nReg){ + if( nReg==1 ){ + sqlite3ReleaseTempReg(pParse, iReg); + return; + } sqlite3ExprCacheRemove(pParse, iReg, nReg); if( nReg>pParse->nRangeReg ){ pParse->nRangeReg = nReg; diff --git a/src/select.c b/src/select.c index 809285ea89..e5bb4a748a 100644 --- a/src/select.c +++ b/src/select.c @@ -1222,14 +1222,10 @@ static void generateSortTail( regRowid = 0; regRow = pDest->iSdst; nSortData = nColumn; - }else if( eDest==SRT_Set ){ + }else{ regRowid = sqlite3GetTempReg(pParse); regRow = sqlite3GetTempRange(pParse, nColumn); nSortData = nColumn; - }else{ - regRowid = sqlite3GetTempReg(pParse); - regRow = sqlite3GetTempReg(pParse); - nSortData = 1; } nKey = pOrderBy->nExpr - pSort->nOBSat; if( pSort->sortFlags & SORTFLAG_UseSorter ){ From 83c434e68d61531902d32a42d28a8a0d240c47f8 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 6 Sep 2016 14:58:15 +0000 Subject: [PATCH 0796/1484] Fix a problem handling (a, b) IN (SELECT ...) expressions when there is an index on just one of "a" or "b". FossilOrigin-Name: 231c72d9f651f3a70d5c8af080f3ff181b89d939 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/wherecode.c | 13 +++++++++++-- test/rowvalue9.test | 30 ++++++++++++++++++++++++++++++ 4 files changed, 50 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 3f3f165fd4..63b1c19384 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\sthe\ssqlite3GetTempRange()\sand\ssqlite3ReleaseTempRange()\sinternal\nroutines\sso\sthat\sthey\suse\ssqlite3GetTempReg()\sand\ssqlite3ReleaseTempReg()\nwhen\snReg==1. -D 2016-09-06T14:37:05.419 +C Fix\sa\sproblem\shandling\s(a,\sb)\sIN\s(SELECT\s...)\sexpressions\swhen\sthere\sis\san\sindex\son\sjust\sone\sof\s"a"\sor\s"b". +D 2016-09-06T14:58:15.417 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5017381e4853b1472e01d5bb926be1268eba429c @@ -467,7 +467,7 @@ F src/wal.h 6dd221ed384afdc204bc61e25c23ef7fd5a511f2 F src/walker.c 2d2cc7fb0f320f7f415215d7247f3c584141ac09 F src/where.c 48d705e5196a0611a7be90698eade455ee238536 F src/whereInt.h 14dd243e13b81cbb0a66063d38b70f93a7d6e613 -F src/wherecode.c 8a9a53cb52dd8a75e07c85e3bc12c1604c735954 +F src/wherecode.c 7279bb68e2f947ac5fe4c1fc655757b24878d541 F src/whereexpr.c c5ec87e234faf62ac2d4e7f7ce18fb1f4bd475ff F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -1028,7 +1028,7 @@ F test/rowvalue5.test a440d490c8c0bf606034c09d5c6bbf7840b98f95 F test/rowvalue6.test d19b54feb604d5601f8614b15e214e0774c01087 F test/rowvalue7.test 5d06ff19d9e6969e574a2e662a531dd0c67801a8 F test/rowvalue8.test 5900eddad9e2c3c2e26f1a95f74aafc1232ee5e0 -F test/rowvalue9.test 749a471f237f3fcfdfbd902f850adff2d9963560 +F test/rowvalue9.test 480c60654941bebdc2d0caa0104df7ca358cbed2 F test/rowvaluefault.test 7b16485e3f2b371f3e3d05455b8ded6d0c090244 F test/rtree.test 0c8d9dd458d6824e59683c19ab2ffa9ef946f798 F test/run-wordcount.sh 891e89c4c2d16e629cd45951d4ed899ad12afc09 @@ -1522,7 +1522,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 288e934f356ff6276b3e7581ac0f998ca6e93610 -R 373bd5ec1c7378267f0ce69533be2f50 -U drh -Z c12fde59fd4c6cc2e37d73169853128b +P 4071da2f87a2f24a279ac3bced8c794ad374b47c +R 57b76f412decde1968bde74dac3d47dc +U dan +Z 9ca614bd00458fc036a54c6c73063696 diff --git a/manifest.uuid b/manifest.uuid index aeeeb90ec5..81e40c5b8e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4071da2f87a2f24a279ac3bced8c794ad374b47c \ No newline at end of file +231c72d9f651f3a70d5c8af080f3ff181b89d939 \ No newline at end of file diff --git a/src/wherecode.c b/src/wherecode.c index 896509bc32..2de1d3ca96 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -463,11 +463,20 @@ static int codeEqualityTerm( } } if( !db->mallocFailed ){ + Expr *pLeft = pX->pLeft; + /* Take care here not to generate a TK_VECTOR containing only a + ** single value. Since the parser never creates such a vector, some + ** of the subroutines do not handle this case. */ + if( pLhs->nExpr==1 ){ + pX->pLeft = pLhs->a[0].pExpr; + }else{ + pLeft->x.pList = pLhs; + } pX->x.pSelect->pEList = pRhs; - pX->pLeft->x.pList = pLhs; eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap); pX->x.pSelect->pEList = pOrigRhs; - pX->pLeft->x.pList = pOrigLhs; + pLeft->x.pList = pOrigLhs; + pX->pLeft = pLeft; } sqlite3ExprListDelete(pParse->db, pLhs); sqlite3ExprListDelete(pParse->db, pRhs); diff --git a/test/rowvalue9.test b/test/rowvalue9.test index 214eaccb7e..a906c4e67c 100644 --- a/test/rowvalue9.test +++ b/test/rowvalue9.test @@ -18,6 +18,19 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl set ::testprefix rowvalue9 +# Tests: +# +# 1.*: Test that affinities are handled correctly by various row-value +# operations without indexes. +# +# 2.*: Test an affinity bug that came up during testing. +# +# 3.*: Test a row-value version of the bug tested by 2.*. +# +# 4.*: Test that affinities are handled correctly by various row-value +# operations with assorted indexes. +# + do_execsql_test 1.0.1 { CREATE TABLE a1(c, b INTEGER, a TEXT, PRIMARY KEY(a, b)); @@ -206,5 +219,22 @@ foreach {tn idx} { } {2 4} } +do_execsql_test 5.0 { + CREATE TABLE e1(a TEXT, c NUMERIC); + CREATE TABLE e2(x BLOB, y BLOB); + + INSERT INTO e1 VALUES(2, 2); + + INSERT INTO e2 VALUES ('2', 2); + INSERT INTO e2 VALUES ('2', '2'); + INSERT INTO e2 VALUES ('2', '2.0'); + + CREATE INDEX e1c ON e1(c); +} + +do_execsql_test 5.1 { + SELECT rowid FROM e1 WHERE (a, c) IN (SELECT x, y FROM e2); +} {1} + finish_test From 099a0f5f54ee8108b4b131fecc5f20a0005cdd58 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 6 Sep 2016 15:25:53 +0000 Subject: [PATCH 0797/1484] Fix the header comment on codeEqualityTerm(). FossilOrigin-Name: b7e710e406ed22bcc316099b5e200b6bb2d9c872 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/wherecode.c | 6 +++++- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 63b1c19384..756ea13b46 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\shandling\s(a,\sb)\sIN\s(SELECT\s...)\sexpressions\swhen\sthere\sis\san\sindex\son\sjust\sone\sof\s"a"\sor\s"b". -D 2016-09-06T14:58:15.417 +C Fix\sthe\sheader\scomment\son\scodeEqualityTerm(). +D 2016-09-06T15:25:53.108 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5017381e4853b1472e01d5bb926be1268eba429c @@ -467,7 +467,7 @@ F src/wal.h 6dd221ed384afdc204bc61e25c23ef7fd5a511f2 F src/walker.c 2d2cc7fb0f320f7f415215d7247f3c584141ac09 F src/where.c 48d705e5196a0611a7be90698eade455ee238536 F src/whereInt.h 14dd243e13b81cbb0a66063d38b70f93a7d6e613 -F src/wherecode.c 7279bb68e2f947ac5fe4c1fc655757b24878d541 +F src/wherecode.c 49125c4db8fbbf1a7013aa261d0d55230ae1b71a F src/whereexpr.c c5ec87e234faf62ac2d4e7f7ce18fb1f4bd475ff F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -1522,7 +1522,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 4071da2f87a2f24a279ac3bced8c794ad374b47c -R 57b76f412decde1968bde74dac3d47dc -U dan -Z 9ca614bd00458fc036a54c6c73063696 +P 231c72d9f651f3a70d5c8af080f3ff181b89d939 +R f1724dce64a0910d56689218d8ab18df +U drh +Z ba82e808b5a71f302b7f5c7627019f3d diff --git a/manifest.uuid b/manifest.uuid index 81e40c5b8e..b81d39b24f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -231c72d9f651f3a70d5c8af080f3ff181b89d939 \ No newline at end of file +b7e710e406ed22bcc316099b5e200b6bb2d9c872 \ No newline at end of file diff --git a/src/wherecode.c b/src/wherecode.c index 2de1d3ca96..03d1ac16df 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -382,7 +382,11 @@ static void updateRangeAffinityStr( ** term can be either X=expr or X IN (...). pTerm is the term to be ** coded. ** -** The current value for the constraint is left in register iReg. +** The current value for the constraint is left in a register, the index +** of which is returned. An attempt is made store the result in iTarget but +** this is only guaranteed for TK_ISNULL and TK_IN constraints. If the +** constraint is a TK_EQ or TK_IS, then the current value might be left in +** some other register and it is the caller's responsibility to compensate. ** ** For a constraint of the form X=expr, the expression is evaluated in ** straight-line code. For constraints of the form X IN (...) From 1c12657f9a5527a72986ce4fc0487ea5f5915401 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 6 Sep 2016 16:33:24 +0000 Subject: [PATCH 0798/1484] Simplify the fix in commit [7d9bd22c]. FossilOrigin-Name: bd5a342008575bf66f63881a0bebf43741f2a67b --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/wherecode.c | 24 +++++++++++++----------- 3 files changed, 21 insertions(+), 19 deletions(-) diff --git a/manifest b/manifest index 756ea13b46..97b5702545 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\sheader\scomment\son\scodeEqualityTerm(). -D 2016-09-06T15:25:53.108 +C Simplify\sthe\sfix\sin\scommit\s[7d9bd22c]. +D 2016-09-06T16:33:24.850 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5017381e4853b1472e01d5bb926be1268eba429c @@ -467,7 +467,7 @@ F src/wal.h 6dd221ed384afdc204bc61e25c23ef7fd5a511f2 F src/walker.c 2d2cc7fb0f320f7f415215d7247f3c584141ac09 F src/where.c 48d705e5196a0611a7be90698eade455ee238536 F src/whereInt.h 14dd243e13b81cbb0a66063d38b70f93a7d6e613 -F src/wherecode.c 49125c4db8fbbf1a7013aa261d0d55230ae1b71a +F src/wherecode.c ea92c232f9de5bf8a719356f8a5b028e7a287d93 F src/whereexpr.c c5ec87e234faf62ac2d4e7f7ce18fb1f4bd475ff F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -1522,7 +1522,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 231c72d9f651f3a70d5c8af080f3ff181b89d939 -R f1724dce64a0910d56689218d8ab18df -U drh -Z ba82e808b5a71f302b7f5c7627019f3d +P b7e710e406ed22bcc316099b5e200b6bb2d9c872 +R 7abdcc30d48bf004d77a6f8aa0e43c0f +U dan +Z 63aca3ea6fe182a1ada6faadbb0dd4d6 diff --git a/manifest.uuid b/manifest.uuid index b81d39b24f..233e543061 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b7e710e406ed22bcc316099b5e200b6bb2d9c872 \ No newline at end of file +bd5a342008575bf66f63881a0bebf43741f2a67b \ No newline at end of file diff --git a/src/wherecode.c b/src/wherecode.c index 03d1ac16df..13904c9c8e 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -663,25 +663,27 @@ static int codeAllEqualityTerms( testcase( pTerm->eOperator & WO_ISNULL ); testcase( pTerm->eOperator & WO_IN ); if( (pTerm->eOperator & WO_ISNULL)==0 ){ - Expr *pRight = 0; if( pTerm->eOperator & WO_IN ){ if( pTerm->pExpr->flags & EP_xIsSelect ){ - int iField = pTerm->iField ? pTerm->iField-1 : 0; - pRight = pTerm->pExpr->x.pSelect->pEList->a[iField].pExpr; + /* No affinity ever needs to be (or should be) applied to a value + ** from the RHS of an "? IN (SELECT ...)" expression. The + ** sqlite3FindInIndex() routine has already ensured that the + ** affinity of the comparison has been applied to the value. */ + zAff[j] = SQLITE_AFF_BLOB; } }else{ - pRight = pTerm->pExpr->pRight; + Expr *pRight = pTerm->pExpr->pRight; if( (pTerm->wtFlags & TERM_IS)==0 && sqlite3ExprCanBeNull(pRight) ){ sqlite3VdbeAddOp2(v, OP_IsNull, regBase+j, pLevel->addrBrk); VdbeCoverage(v); } - } - if( pRight && zAff ){ - if( sqlite3CompareAffinity(pRight, zAff[j])==SQLITE_AFF_BLOB ){ - zAff[j] = SQLITE_AFF_BLOB; - } - if( sqlite3ExprNeedsNoAffinityChange(pRight, zAff[j]) ){ - zAff[j] = SQLITE_AFF_BLOB; + if( zAff ){ + if( sqlite3CompareAffinity(pRight, zAff[j])==SQLITE_AFF_BLOB ){ + zAff[j] = SQLITE_AFF_BLOB; + } + if( sqlite3ExprNeedsNoAffinityChange(pRight, zAff[j]) ){ + zAff[j] = SQLITE_AFF_BLOB; + } } } } From aaf8a0643e46e6c4a7ca5b83f0b779c21499b542 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 6 Sep 2016 16:53:53 +0000 Subject: [PATCH 0799/1484] Avoid a NULL pointer deref in codeAllEqualityConstraints() following an OOM. FossilOrigin-Name: c6e528c1c0f17c69c7745b018afa36694118258f --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/wherecode.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 97b5702545..15e35ee022 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Simplify\sthe\sfix\sin\scommit\s[7d9bd22c]. -D 2016-09-06T16:33:24.850 +C Avoid\sa\sNULL\spointer\sderef\sin\scodeAllEqualityConstraints()\sfollowing\san\sOOM. +D 2016-09-06T16:53:53.727 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5017381e4853b1472e01d5bb926be1268eba429c @@ -467,7 +467,7 @@ F src/wal.h 6dd221ed384afdc204bc61e25c23ef7fd5a511f2 F src/walker.c 2d2cc7fb0f320f7f415215d7247f3c584141ac09 F src/where.c 48d705e5196a0611a7be90698eade455ee238536 F src/whereInt.h 14dd243e13b81cbb0a66063d38b70f93a7d6e613 -F src/wherecode.c ea92c232f9de5bf8a719356f8a5b028e7a287d93 +F src/wherecode.c 4bd3e4c3c9f441a9d1fbd8fb13528f9c1c2c8528 F src/whereexpr.c c5ec87e234faf62ac2d4e7f7ce18fb1f4bd475ff F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -1522,7 +1522,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b7e710e406ed22bcc316099b5e200b6bb2d9c872 -R 7abdcc30d48bf004d77a6f8aa0e43c0f -U dan -Z 63aca3ea6fe182a1ada6faadbb0dd4d6 +P bd5a342008575bf66f63881a0bebf43741f2a67b +R fcb091661f586511d74c9857242646c5 +U drh +Z 30f14ba82e1e5f327ee9c3b7b6a25371 diff --git a/manifest.uuid b/manifest.uuid index 233e543061..b0f1c15887 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bd5a342008575bf66f63881a0bebf43741f2a67b \ No newline at end of file +c6e528c1c0f17c69c7745b018afa36694118258f \ No newline at end of file diff --git a/src/wherecode.c b/src/wherecode.c index 13904c9c8e..0b1165f024 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -669,7 +669,7 @@ static int codeAllEqualityTerms( ** from the RHS of an "? IN (SELECT ...)" expression. The ** sqlite3FindInIndex() routine has already ensured that the ** affinity of the comparison has been applied to the value. */ - zAff[j] = SQLITE_AFF_BLOB; + if( zAff ) zAff[j] = SQLITE_AFF_BLOB; } }else{ Expr *pRight = pTerm->pExpr->pRight; From c7a77ae1c61f66a2ec94de49a4a92872faf4f0c9 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 6 Sep 2016 17:13:40 +0000 Subject: [PATCH 0800/1484] Avoid unnecessary memory allocations for aiMap in codeEqualityConstraints. FossilOrigin-Name: 70319c3d76abd1e403fcf2a62668736b92a5f3d5 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/wherecode.c | 8 +++----- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 15e35ee022..5f69a2d824 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sa\sNULL\spointer\sderef\sin\scodeAllEqualityConstraints()\sfollowing\san\sOOM. -D 2016-09-06T16:53:53.727 +C Avoid\sunnecessary\smemory\sallocations\sfor\saiMap\sin\scodeEqualityConstraints. +D 2016-09-06T17:13:40.420 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5017381e4853b1472e01d5bb926be1268eba429c @@ -467,7 +467,7 @@ F src/wal.h 6dd221ed384afdc204bc61e25c23ef7fd5a511f2 F src/walker.c 2d2cc7fb0f320f7f415215d7247f3c584141ac09 F src/where.c 48d705e5196a0611a7be90698eade455ee238536 F src/whereInt.h 14dd243e13b81cbb0a66063d38b70f93a7d6e613 -F src/wherecode.c 4bd3e4c3c9f441a9d1fbd8fb13528f9c1c2c8528 +F src/wherecode.c b0d4febdd9de07ad68faadeacb30df9785f9b979 F src/whereexpr.c c5ec87e234faf62ac2d4e7f7ce18fb1f4bd475ff F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -1522,7 +1522,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P bd5a342008575bf66f63881a0bebf43741f2a67b -R fcb091661f586511d74c9857242646c5 +P c6e528c1c0f17c69c7745b018afa36694118258f +R 71337de042abb55d5e21dbccb2bcc3d7 U drh -Z 30f14ba82e1e5f327ee9c3b7b6a25371 +Z ad68562def745ab96bb3491072f1a7f4 diff --git a/manifest.uuid b/manifest.uuid index b0f1c15887..728933c62b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c6e528c1c0f17c69c7745b018afa36694118258f \ No newline at end of file +70319c3d76abd1e403fcf2a62668736b92a5f3d5 \ No newline at end of file diff --git a/src/wherecode.c b/src/wherecode.c index 0b1165f024..0524ae2771 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -442,11 +442,6 @@ static int codeEqualityTerm( if( ALWAYS(pLoop->aLTerm[i]) && pLoop->aLTerm[i]->pExpr==pX ) nEq++; } - if( nEq>1 ){ - aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int) * nEq); - if( !aiMap ) return 0; - } - if( (pX->flags & EP_xIsSelect)==0 || pX->x.pSelect->pEList->nExpr==1 ){ eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, 0); }else{ @@ -475,9 +470,12 @@ static int codeEqualityTerm( pX->pLeft = pLhs->a[0].pExpr; }else{ pLeft->x.pList = pLhs; + aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int) * nEq); + testcase( aiMap==0 ); } pX->x.pSelect->pEList = pRhs; eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap); + testcase( aiMap!=0 && aiMap[0]!=0 ); pX->x.pSelect->pEList = pOrigRhs; pLeft->x.pList = pOrigLhs; pX->pLeft = pLeft; From 773d3afaa3780149cf7482a01f1609520ebcee34 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 6 Sep 2016 17:21:17 +0000 Subject: [PATCH 0801/1484] Remove an unnecessary branch from expr.c. FossilOrigin-Name: 7cc9746c5414e02012efb8180f9eca2646800e74 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/expr.c | 2 +- test/rowvalue9.test | 6 ++++++ 4 files changed, 16 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 5f69a2d824..378bf07279 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sunnecessary\smemory\sallocations\sfor\saiMap\sin\scodeEqualityConstraints. -D 2016-09-06T17:13:40.420 +C Remove\san\sunnecessary\sbranch\sfrom\sexpr.c. +D 2016-09-06T17:21:17.043 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5017381e4853b1472e01d5bb926be1268eba429c @@ -338,7 +338,7 @@ F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7 F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c 76c084f0265f4a3cd1ecf17eee112a94f1ccbc05 -F src/expr.c 4c2b9886927fb6628560ad40d14b04946d71abbd +F src/expr.c 028c34005cb804abe8f73453ac08baa44f4b63f9 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c e2be0968c1adc679c87e467aa5b4f167588f38a8 F src/func.c 29cc9acb170ec1387b9f63eb52cd85f8de96c771 @@ -1028,7 +1028,7 @@ F test/rowvalue5.test a440d490c8c0bf606034c09d5c6bbf7840b98f95 F test/rowvalue6.test d19b54feb604d5601f8614b15e214e0774c01087 F test/rowvalue7.test 5d06ff19d9e6969e574a2e662a531dd0c67801a8 F test/rowvalue8.test 5900eddad9e2c3c2e26f1a95f74aafc1232ee5e0 -F test/rowvalue9.test 480c60654941bebdc2d0caa0104df7ca358cbed2 +F test/rowvalue9.test 03a5edc94ab5983b98820f6541c62b43560cd84c F test/rowvaluefault.test 7b16485e3f2b371f3e3d05455b8ded6d0c090244 F test/rtree.test 0c8d9dd458d6824e59683c19ab2ffa9ef946f798 F test/run-wordcount.sh 891e89c4c2d16e629cd45951d4ed899ad12afc09 @@ -1522,7 +1522,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P c6e528c1c0f17c69c7745b018afa36694118258f -R 71337de042abb55d5e21dbccb2bcc3d7 -U drh -Z ad68562def745ab96bb3491072f1a7f4 +P 70319c3d76abd1e403fcf2a62668736b92a5f3d5 +R e9d987800340c93d5c8b755d8bc8e3a7 +U dan +Z f81283c76e744b298a5230c53cc06749 diff --git a/manifest.uuid b/manifest.uuid index 728933c62b..a94fb71aeb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -70319c3d76abd1e403fcf2a62668736b92a5f3d5 \ No newline at end of file +7cc9746c5414e02012efb8180f9eca2646800e74 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index a83ede6cb5..80497be111 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2482,7 +2482,7 @@ int sqlite3CodeSubselect( assert( pEList->nExpr>0 ); assert( sqlite3KeyInfoIsWriteable(pKeyInfo) ); for(i=0; i1) ? sqlite3VectorFieldSubexpr(pLeft, i) : pLeft; + Expr *p = sqlite3VectorFieldSubexpr(pLeft, i); pKeyInfo->aColl[i] = sqlite3BinaryCompareCollSeq( pParse, p, pEList->a[i].pExpr ); diff --git a/test/rowvalue9.test b/test/rowvalue9.test index a906c4e67c..570a5b98a8 100644 --- a/test/rowvalue9.test +++ b/test/rowvalue9.test @@ -235,6 +235,12 @@ do_execsql_test 5.0 { do_execsql_test 5.1 { SELECT rowid FROM e1 WHERE (a, c) IN (SELECT x, y FROM e2); } {1} +do_execsql_test 5.2 { + SELECT rowid FROM e2 WHERE rowid IN (SELECT +c FROM e1); +} {2} +do_execsql_test 5.3 { + SELECT rowid FROM e2 WHERE rowid IN (SELECT 0+c FROM e1); +} {2} finish_test From 1431807a0bd52a544b9a31d6f7324f8be7e7150c Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 6 Sep 2016 18:51:25 +0000 Subject: [PATCH 0802/1484] Fix corer cases of vector IN operators where the RHS is a compound SELECT that includes an ORDER BY clause. FossilOrigin-Name: 8329ac6f8d1edcc19c3e0559abe9a8011dbe1497 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/select.c | 10 ++++------ src/whereexpr.c | 6 +++++- 4 files changed, 18 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index 378bf07279..8def3253ea 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\san\sunnecessary\sbranch\sfrom\sexpr.c. -D 2016-09-06T17:21:17.043 +C Fix\scorer\scases\sof\svector\sIN\soperators\swhere\sthe\sRHS\sis\sa\scompound\sSELECT\nthat\sincludes\san\sORDER\sBY\sclause. +D 2016-09-06T18:51:25.666 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5017381e4853b1472e01d5bb926be1268eba429c @@ -385,7 +385,7 @@ F src/printf.c a5f0ca08ddede803c241266abb46356ec748ded1 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c 24f40fd0c3475821d1ad762a3f2c3455cc839b42 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac -F src/select.c 4ccfc554a2d2313b0ac364120b1db9b74c41b248 +F src/select.c d6c1a6463a5e34352691e77f1475a63406c3984f F src/shell.c 79dda477be6c96eba6e952a934957ad36f87acc7 F src/sqlite.h.in 4a030e254e204570444b34bf7d40fb4a5416089e F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -468,7 +468,7 @@ F src/walker.c 2d2cc7fb0f320f7f415215d7247f3c584141ac09 F src/where.c 48d705e5196a0611a7be90698eade455ee238536 F src/whereInt.h 14dd243e13b81cbb0a66063d38b70f93a7d6e613 F src/wherecode.c b0d4febdd9de07ad68faadeacb30df9785f9b979 -F src/whereexpr.c c5ec87e234faf62ac2d4e7f7ce18fb1f4bd475ff +F src/whereexpr.c e3db778ed205e982f31960896db71c50612ae009 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1522,7 +1522,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 70319c3d76abd1e403fcf2a62668736b92a5f3d5 -R e9d987800340c93d5c8b755d8bc8e3a7 -U dan -Z f81283c76e744b298a5230c53cc06749 +P 7cc9746c5414e02012efb8180f9eca2646800e74 +R 36f92754f7a81ed3dc243351ed6e664e +U drh +Z 50c7e7d129c621501eed665f9216f5e0 diff --git a/manifest.uuid b/manifest.uuid index a94fb71aeb..6e1c09ed3d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7cc9746c5414e02012efb8180f9eca2646800e74 \ No newline at end of file +8329ac6f8d1edcc19c3e0559abe9a8011dbe1497 \ No newline at end of file diff --git a/src/select.c b/src/select.c index e5bb4a748a..aa714ceb48 100644 --- a/src/select.c +++ b/src/select.c @@ -2631,17 +2631,15 @@ static int generateOutputSubroutine( } #ifndef SQLITE_OMIT_SUBQUERY - /* If we are creating a set for an "expr IN (SELECT ...)" construct, - ** then there should be a single item on the stack. Write this - ** item into the set table with bogus data. + /* If we are creating a set for an "expr IN (SELECT ...)". */ case SRT_Set: { int r1; - assert( pIn->nSdst==1 || pParse->nErr>0 ); + testcase( pIn->nSdst>1 && pParse->nErr==0 ); r1 = sqlite3GetTempReg(pParse); sqlite3VdbeAddOp4(v, OP_MakeRecord, pIn->iSdst, pIn->nSdst, - r1, pDest->zAffSdst,1); - sqlite3ExprCacheAffinityChange(pParse, pIn->iSdst, 1); + r1, pDest->zAffSdst, pIn->nSdst); + sqlite3ExprCacheAffinityChange(pParse, pIn->iSdst, pIn->nSdst); sqlite3VdbeAddOp2(v, OP_IdxInsert, pDest->iSDParm, r1); sqlite3ReleaseTempReg(pParse, r1); break; diff --git a/src/whereexpr.c b/src/whereexpr.c index 92aed29bbc..e1059f73b4 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -1209,9 +1209,13 @@ static void exprAnalyze( ** a virtual term for each vector component. The expression object ** used by each such virtual term is pExpr (the full vector IN(...) ** expression). The WhereTerm.iField variable identifies the index within - ** the vector on the LHS that the virtual term represents. */ + ** the vector on the LHS that the virtual term represents. + ** + ** This only works if the RHS is a simple SELECT, not a compound + */ if( pWC->op==TK_AND && pExpr->op==TK_IN && pTerm->iField==0 && pExpr->pLeft->op==TK_VECTOR + && pExpr->x.pSelect->pPrior==0 ){ int i; for(i=0; ipLeft); i++){ From 63cecc41735c42f0fa42dd5a6e5fe7e0f69cc7be Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 6 Sep 2016 19:08:21 +0000 Subject: [PATCH 0803/1484] Remove obsolete vector-IN test cases. Fix a bad testcase() macro. FossilOrigin-Name: ab3f8f193a7ec36018bf26c9231a1a6a58b6a523 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/select.c | 2 +- test/rowvalue5.test | 14 ++++++-------- 4 files changed, 15 insertions(+), 17 deletions(-) diff --git a/manifest b/manifest index 8def3253ea..b6583d963c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\scorer\scases\sof\svector\sIN\soperators\swhere\sthe\sRHS\sis\sa\scompound\sSELECT\nthat\sincludes\san\sORDER\sBY\sclause. -D 2016-09-06T18:51:25.666 +C Remove\sobsolete\svector-IN\stest\scases.\s\sFix\sa\sbad\stestcase()\smacro. +D 2016-09-06T19:08:21.705 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5017381e4853b1472e01d5bb926be1268eba429c @@ -385,7 +385,7 @@ F src/printf.c a5f0ca08ddede803c241266abb46356ec748ded1 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c 24f40fd0c3475821d1ad762a3f2c3455cc839b42 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac -F src/select.c d6c1a6463a5e34352691e77f1475a63406c3984f +F src/select.c 244f9cc5e4662987cd2ef5c22d1b7027560f3425 F src/shell.c 79dda477be6c96eba6e952a934957ad36f87acc7 F src/sqlite.h.in 4a030e254e204570444b34bf7d40fb4a5416089e F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1024,7 +1024,7 @@ F test/rowvalue.test 753eb744b7efeb5ac643d35d6e1e5066452ccf79 F test/rowvalue2.test 060d238b7e5639a7c5630cb5e63e311b44efef2b F test/rowvalue3.test 01399b7bf150b0d41abce76c18072da777c2500c F test/rowvalue4.test 4b556d7de161a0dd8cff095c336e913986398bea -F test/rowvalue5.test a440d490c8c0bf606034c09d5c6bbf7840b98f95 +F test/rowvalue5.test c1adfb2ea104e181f70d55bbd80d803b9917b22b F test/rowvalue6.test d19b54feb604d5601f8614b15e214e0774c01087 F test/rowvalue7.test 5d06ff19d9e6969e574a2e662a531dd0c67801a8 F test/rowvalue8.test 5900eddad9e2c3c2e26f1a95f74aafc1232ee5e0 @@ -1522,7 +1522,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 7cc9746c5414e02012efb8180f9eca2646800e74 -R 36f92754f7a81ed3dc243351ed6e664e +P 8329ac6f8d1edcc19c3e0559abe9a8011dbe1497 +R c63acfebc9bb94150dde03620f804079 U drh -Z 50c7e7d129c621501eed665f9216f5e0 +Z 4492b1886315f856574968e31e230cb0 diff --git a/manifest.uuid b/manifest.uuid index 6e1c09ed3d..130764cfa2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8329ac6f8d1edcc19c3e0559abe9a8011dbe1497 \ No newline at end of file +ab3f8f193a7ec36018bf26c9231a1a6a58b6a523 \ No newline at end of file diff --git a/src/select.c b/src/select.c index aa714ceb48..2d4e901ba4 100644 --- a/src/select.c +++ b/src/select.c @@ -2635,7 +2635,7 @@ static int generateOutputSubroutine( */ case SRT_Set: { int r1; - testcase( pIn->nSdst>1 && pParse->nErr==0 ); + testcase( pIn->nSdst>1 ); r1 = sqlite3GetTempReg(pParse); sqlite3VdbeAddOp4(v, OP_MakeRecord, pIn->iSdst, pIn->nSdst, r1, pDest->zAffSdst, pIn->nSdst); diff --git a/test/rowvalue5.test b/test/rowvalue5.test index d5976ccb89..45d501b55a 100644 --- a/test/rowvalue5.test +++ b/test/rowvalue5.test @@ -96,15 +96,13 @@ foreach {tn where res} { 6 "(a, b) = (SELECT 9, 10)" {{a = 9 AND b = 10}} 7 "(+a, b) = (SELECT 'a', 'b')" {{b = 'b'}} 8 "(a, +b) = (SELECT 'a', 'b')" {{a = 'a'}} - 10 "(a, b) IN (SELECT 9, 10 UNION SELECT 11, 12)" - {{a = 9 AND b = 10} {a = 11 AND b = 12}} - 11 "(+a, b) IN (SELECT 'a', 'b')" {{b = 'b'}} - 12 "(a, +b) IN (SELECT 'a', 'b')" {{a = 'a'}} + 11 "(+a, b) IN (SELECT 'a', 'b')" {{b = 'b'}} + 12 "(a, +b) IN (SELECT 'a', 'b')" {{a = 'a'}} - 13 "(a, b) < ('d', 'e')" {{a <= 'd'}} - 14 "(a, b) < ('a', 'c')" {{a <= 'a'}} - 15 "(a, b) <= ('a', 'b')" {{a <= 'a'}} - 16 "(a, b) < ('a', 'b')" {} + 13 "(a, b) < ('d', 'e')" {{a <= 'd'}} + 14 "(a, b) < ('a', 'c')" {{a <= 'a'}} + 15 "(a, b) <= ('a', 'b')" {{a <= 'a'}} + 16 "(a, b) < ('a', 'b')" {} } { do_execsql_test 1.$tn "SELECT expr FROM x1 WHERE $where" $res } From 57a8c615015de9f6d49fb259093db818735fe28c Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 7 Sep 2016 01:51:46 +0000 Subject: [PATCH 0804/1484] The ORDER BY LIMIT optimization is not valid unless the inner-most IN operator loop is actually used by the query plan. Fix for ticket [0c4df46116e90f92]. FossilOrigin-Name: 820644b886f81e991fceb5f1c3290b8959b34528 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/where.c | 8 ++++++++ test/limit2.test | 13 ++++++++++++- 4 files changed, 28 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 60518ebe7c..473cb475df 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Build\sthe\sgenerate_series(START,END,STEP)\stable-valued\sfunction\sinto\nfuzzershell,\sto\smake\sit\seasier\sto\sconstruct\scompact\stest\scases\sthat\scontain\nactual\sdata. -D 2016-09-03T16:23:42.901 +C The\sORDER\sBY\sLIMIT\soptimization\sis\snot\svalid\sunless\sthe\sinner-most\sIN\soperator\nloop\sis\sactually\sused\sby\sthe\squery\splan.\nFix\sfor\sticket\s[0c4df46116e90f92]. +D 2016-09-07T01:51:46.818 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5017381e4853b1472e01d5bb926be1268eba429c @@ -464,7 +464,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 02eeecc265f6ffd0597378f5d8ae9070b62a406a F src/wal.h 6dd221ed384afdc204bc61e25c23ef7fd5a511f2 F src/walker.c 2d2cc7fb0f320f7f415215d7247f3c584141ac09 -F src/where.c 5c9df42d50888be8274a5a0eb062eb0629869bd3 +F src/where.c 4bbc3f1dcda64c96ed5f0ffe51be7c0d7adb6c62 F src/whereInt.h e5b939701a7ceffc5a3a8188a37f9746416ebcd0 F src/wherecode.c 99707d11907c71d289ee9553d2d1a22f1fd8ba41 F src/whereexpr.c 98ce9f3b8d92b6f741b9f3498f9619695739256e @@ -889,7 +889,7 @@ F test/like.test 81632c437a947bf1f7130b19537da6a1a844806a F test/like2.test 3b2ee13149ba4a8a60b59756f4e5d345573852da F test/like3.test 3608a2042b6f922f900fbfd5d3ce4e7eca57f7c4 F test/limit.test 0c99a27a87b14c646a9d583c7c89fd06c352663e -F test/limit2.test 40e79f3d95f2077742aa5b7676f58c9af1735d83 +F test/limit2.test ac97b8d07060a0280162ba4159e4c0c765861127 F test/loadext.test d077450695ddb5c1ea3ad7d48e5f5850fe732ad9 F test/loadext2.test 0408380b57adca04004247179837a18e866a74f7 F test/lock.test be4fe08118fb988fed741f429b7dd5d65e1c90db @@ -1511,7 +1511,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 9bdf7ca1b317fe0ba7efea38fb395bf6130ac89a -R f234dfb8eb81560f8891406102139ec1 +P 672c21bcf09c5bfb67e061456a56be45409c4f34 +R 8295a9e9a92e0badbb544219a9ddd5bb U drh -Z 8e05ee287619d9d44d13c4eb0cda4de7 +Z aeaed53bf1e0bb67e40593d62a24bb76 diff --git a/manifest.uuid b/manifest.uuid index 900a733d95..3fe32cf2b8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -672c21bcf09c5bfb67e061456a56be45409c4f34 \ No newline at end of file +820644b886f81e991fceb5f1c3290b8959b34528 \ No newline at end of file diff --git a/src/where.c b/src/where.c index c2706dc5dd..c18c09d7f4 100644 --- a/src/where.c +++ b/src/where.c @@ -3401,6 +3401,14 @@ static i8 wherePathSatisfiesOrderBy( pTerm = sqlite3WhereFindTerm(&pWInfo->sWC, iCur, pOBExpr->iColumn, ~ready, eqOpMask, 0); if( pTerm==0 ) continue; + if( pTerm->eOperator==WO_IN ){ + /* IN terms are only valid for sorting in the ORDER BY LIMIT + ** optimization, and then only if they are actually used + ** by the query plan */ + assert( wctrlFlags & WHERE_ORDERBY_LIMIT ); + for(j=0; jnLTerm && pTerm!=pLoop->aLTerm[j]; j++){} + if( j>=pLoop->nLTerm ) continue; + } if( (pTerm->eOperator&(WO_EQ|WO_IS))!=0 && pOBExpr->iColumn>=0 ){ const char *z1, *z2; pColl = sqlite3ExprCollSeq(pWInfo->pParse, pOrderBy->a[i].pExpr); diff --git a/test/limit2.test b/test/limit2.test index fb4c89644f..0f82ab8d55 100644 --- a/test/limit2.test +++ b/test/limit2.test @@ -96,7 +96,18 @@ do_execsql_test limit2-210 { SELECT *, '|' FROM t200 LEFT JOIN t201 ON x=b ORDER BY y LIMIT 3; } {1 1 {} {} | 3 3 {} {} | 4 4 {} {} |} - +# Bug in the ORDER BY LIMIT optimization reported on 2016-09-06. +# Ticket https://www.sqlite.org/src/info/559733b09e96 +# +do_execsql_test limit2-300 { + CREATE TABLE t300(a,b,c); + CREATE INDEX t300x ON t300(a,b,c); + INSERT INTO t300 VALUES(0,1,99),(0,1,0),(0,0,0); + SELECT *,'.' FROM t300 WHERE a=0 AND (c=0 OR c=99) ORDER BY c DESC; +} {0 1 99 . 0 0 0 . 0 1 0 .} +do_execsql_test limit2-310 { + SELECT *,'.' FROM t300 WHERE a=0 AND (c=0 OR c=99) ORDER BY c DESC LIMIT 1; +} {0 1 99 .} From fc8b40f2f6b77acc7a46375937b1a372f849ffab Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 7 Sep 2016 10:10:18 +0000 Subject: [PATCH 0805/1484] Fix the ".read" command in the command-line shell so that it understands that the input is not interactive. FossilOrigin-Name: d8451fe84d09db6ec7e1bd5f0708ea1b5e85f3d6 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/shell.c | 4 ++-- test/shell4.test | 13 +++++++++++++ 4 files changed, 23 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 473cb475df..0fd8b95f0c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C The\sORDER\sBY\sLIMIT\soptimization\sis\snot\svalid\sunless\sthe\sinner-most\sIN\soperator\nloop\sis\sactually\sused\sby\sthe\squery\splan.\nFix\sfor\sticket\s[0c4df46116e90f92]. -D 2016-09-07T01:51:46.818 +C Fix\sthe\s".read"\scommand\sin\sthe\scommand-line\sshell\sso\sthat\sit\sunderstands\nthat\sthe\sinput\sis\snot\sinteractive. +D 2016-09-07T10:10:18.461 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5017381e4853b1472e01d5bb926be1268eba429c @@ -385,7 +385,7 @@ F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c d67b9a5cc33339256e2088c5a722745fc2ff5219 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c fda7fd24b4d8e75479ae581329db0a0b0bf76633 -F src/shell.c 79dda477be6c96eba6e952a934957ad36f87acc7 +F src/shell.c de7c7e98846cacbfbe062cbd98bca899dfb720e3 F src/sqlite.h.in 4a030e254e204570444b34bf7d40fb4a5416089e F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae @@ -1069,7 +1069,7 @@ F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304 F test/shell1.test 65b10cd8a90cda9b5af9100a45689a57dcc01a31 F test/shell2.test e242a9912f44f4c23c3d1d802a83e934e84c853b F test/shell3.test da513d522ef6f01cee8475dcf8332bff8982b3dd -F test/shell4.test 69995ee1cc278eb149aa8746ce1f935f4eaf98b9 +F test/shell4.test 89ad573879a745974ff2df20ff97c5d6ffffbd5d F test/shell5.test 50a732c1c2158b1cd62cf53975ce1ea7ce6b9dc9 F test/shortread1.test bb591ef20f0fd9ed26d0d12e80eee6d7ac8897a3 F test/show_speedtest1_rtree.tcl 32e6c5f073d7426148a6936a0408f4b5b169aba5 @@ -1511,7 +1511,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 672c21bcf09c5bfb67e061456a56be45409c4f34 -R 8295a9e9a92e0badbb544219a9ddd5bb +P 820644b886f81e991fceb5f1c3290b8959b34528 +R 2932afc8980d7b223aaea98945be0e61 U drh -Z aeaed53bf1e0bb67e40593d62a24bb76 +Z 5c5e9ed55e639316842989db4edd69d1 diff --git a/manifest.uuid b/manifest.uuid index 3fe32cf2b8..342aced9e7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -820644b886f81e991fceb5f1c3290b8959b34528 \ No newline at end of file +d8451fe84d09db6ec7e1bd5f0708ea1b5e85f3d6 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 18c6ef7197..21cba66b1c 100644 --- a/src/shell.c +++ b/src/shell.c @@ -524,7 +524,7 @@ static char *local_getline(char *zLine, FILE *in){ #if defined(_WIN32) || defined(WIN32) /* For interactive input on Windows systems, translate the ** multi-byte characterset characters into UTF-8. */ - if( stdin_is_interactive ){ + if( stdin_is_interactive && in==stdin ){ char *zTrans = sqlite3_win32_mbcs_to_utf8_v2(zLine, 0); if( zTrans ){ int nTrans = strlen30(zTrans)+1; @@ -4905,7 +4905,7 @@ static int process_input(ShellState *p, FILE *in){ zLine = one_input_line(in, zLine, nSql>0); if( zLine==0 ){ /* End of input */ - if( stdin_is_interactive ) printf("\n"); + if( in==0 && stdin_is_interactive ) printf("\n"); break; } if( seenInterrupt ){ diff --git a/test/shell4.test b/test/shell4.test index 3e4ae55816..88e5e69a28 100644 --- a/test/shell4.test +++ b/test/shell4.test @@ -18,6 +18,7 @@ # # shell4-1.*: Basic tests specific to the "stats" command. # shell4-2.*: Basic tests for ".trace" +# shell4-3.*: The ".read" command takes the shell out of interactive mode # set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -124,5 +125,17 @@ do_test shell4-2.5 { } {0 {SELECT * FROM t1;}} } +do_test shell4-3.1 { + set fd [open t1.txt wb] + puts $fd "SELECT 'squirrel';" + close $fd + exec $::CLI :memory: --interactive ".read t1.txt" +} {squirrel} +do_test shell4-3.2 { + set fd [open t1.txt wb] + puts $fd "SELECT 'pound: \302\243';" + close $fd + exec $::CLI :memory: --interactive ".read t1.txt" +} {pound: £} finish_test From c097e122b90fceccc510049eb1cb438fc0bec5e7 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 7 Sep 2016 13:30:40 +0000 Subject: [PATCH 0806/1484] Simplify the affinity handling logic in codeAllEqualityTerms(). Logically the same, just a little easier to read and understand. FossilOrigin-Name: bbab9621f512b04684163b98b6fc669c68038044 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/wherecode.c | 42 +++++++++++++++++++----------------------- 3 files changed, 26 insertions(+), 30 deletions(-) diff --git a/manifest b/manifest index d9dec4830b..2b16d0533f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sfixes\sfrom\strunk. -D 2016-09-07T13:12:13.158 +C Simplify\sthe\saffinity\shandling\slogic\sin\scodeAllEqualityTerms().\s\sLogically\nthe\ssame,\sjust\sa\slittle\seasier\sto\sread\sand\sunderstand. +D 2016-09-07T13:30:40.808 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5017381e4853b1472e01d5bb926be1268eba429c @@ -467,7 +467,7 @@ F src/wal.h 6dd221ed384afdc204bc61e25c23ef7fd5a511f2 F src/walker.c 2d2cc7fb0f320f7f415215d7247f3c584141ac09 F src/where.c edbd73a87ba2e186928e9bfc14348b1bbb2628c5 F src/whereInt.h 14dd243e13b81cbb0a66063d38b70f93a7d6e613 -F src/wherecode.c b0d4febdd9de07ad68faadeacb30df9785f9b979 +F src/wherecode.c 43522ac811e2e0374603f9fc9a3dda4e1a81f470 F src/whereexpr.c e3db778ed205e982f31960896db71c50612ae009 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -1522,7 +1522,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ab3f8f193a7ec36018bf26c9231a1a6a58b6a523 d8451fe84d09db6ec7e1bd5f0708ea1b5e85f3d6 -R 9be49f79015d1d1f29328535fe4e7eb6 +P 193f036c87857bd77577ceb462af5034c7cc77da +R 5310dec13b5e77c999328204c9245316 U drh -Z 2891e6cf4d042c296a4853701a08d60f +Z 06433047ae27fe630ae84491904304f6 diff --git a/manifest.uuid b/manifest.uuid index c5b7f13bc8..e850f3a033 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -193f036c87857bd77577ceb462af5034c7cc77da \ No newline at end of file +bbab9621f512b04684163b98b6fc669c68038044 \ No newline at end of file diff --git a/src/wherecode.c b/src/wherecode.c index 0524ae2771..fdb986cbdf 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -658,30 +658,26 @@ static int codeAllEqualityTerms( sqlite3VdbeAddOp2(v, OP_SCopy, r1, regBase+j); } } - testcase( pTerm->eOperator & WO_ISNULL ); - testcase( pTerm->eOperator & WO_IN ); - if( (pTerm->eOperator & WO_ISNULL)==0 ){ - if( pTerm->eOperator & WO_IN ){ - if( pTerm->pExpr->flags & EP_xIsSelect ){ - /* No affinity ever needs to be (or should be) applied to a value - ** from the RHS of an "? IN (SELECT ...)" expression. The - ** sqlite3FindInIndex() routine has already ensured that the - ** affinity of the comparison has been applied to the value. */ - if( zAff ) zAff[j] = SQLITE_AFF_BLOB; + if( pTerm->eOperator & WO_IN ){ + if( pTerm->pExpr->flags & EP_xIsSelect ){ + /* No affinity ever needs to be (or should be) applied to a value + ** from the RHS of an "? IN (SELECT ...)" expression. The + ** sqlite3FindInIndex() routine has already ensured that the + ** affinity of the comparison has been applied to the value. */ + if( zAff ) zAff[j] = SQLITE_AFF_BLOB; + } + }else if( (pTerm->eOperator & WO_ISNULL)==0 ){ + Expr *pRight = pTerm->pExpr->pRight; + if( (pTerm->wtFlags & TERM_IS)==0 && sqlite3ExprCanBeNull(pRight) ){ + sqlite3VdbeAddOp2(v, OP_IsNull, regBase+j, pLevel->addrBrk); + VdbeCoverage(v); + } + if( zAff ){ + if( sqlite3CompareAffinity(pRight, zAff[j])==SQLITE_AFF_BLOB ){ + zAff[j] = SQLITE_AFF_BLOB; } - }else{ - Expr *pRight = pTerm->pExpr->pRight; - if( (pTerm->wtFlags & TERM_IS)==0 && sqlite3ExprCanBeNull(pRight) ){ - sqlite3VdbeAddOp2(v, OP_IsNull, regBase+j, pLevel->addrBrk); - VdbeCoverage(v); - } - if( zAff ){ - if( sqlite3CompareAffinity(pRight, zAff[j])==SQLITE_AFF_BLOB ){ - zAff[j] = SQLITE_AFF_BLOB; - } - if( sqlite3ExprNeedsNoAffinityChange(pRight, zAff[j]) ){ - zAff[j] = SQLITE_AFF_BLOB; - } + if( sqlite3ExprNeedsNoAffinityChange(pRight, zAff[j]) ){ + zAff[j] = SQLITE_AFF_BLOB; } } } From d609bdb9d37d9e74cb2b7b97e8a8db10c33a542e Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 7 Sep 2016 18:11:11 +0000 Subject: [PATCH 0807/1484] Add the ext/misc/memvfs.c extension that implements a VFS for read-only database files contained in memory. FossilOrigin-Name: 12b7782a9af91eab913e159149cb28b3f5a6557c --- ext/misc/memvfs.c | 491 ++++++++++++++++++++++++++++++++++++++++++++++ manifest | 11 +- manifest.uuid | 2 +- 3 files changed, 498 insertions(+), 6 deletions(-) create mode 100644 ext/misc/memvfs.c diff --git a/ext/misc/memvfs.c b/ext/misc/memvfs.c new file mode 100644 index 0000000000..62a8a033d7 --- /dev/null +++ b/ext/misc/memvfs.c @@ -0,0 +1,491 @@ +/* +** 2016-09-07 +** +** 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 is an in-memory read-only VFS implementation. The application +** supplies a block of memory which is the database file, and this VFS +** uses that block of memory. +** +** Because there is no place to store journals and no good way to lock +** the "file", this VFS is read-only. +** +** USAGE: +** +** sqlite3_open_v2("file:/whatever?ptr=0xf05538&sz=14336", &db, +** SQLITE_OPEN_READONLY | SQLITE_OPEN_URI, +** "memvfs"); +** +** The ptr= and sz= query parameters are required or the open will fail. +** The ptr= parameter gives the memory address of the buffer holding the +** read-only database and sz= gives the size of the database. The parameter +** values may be in hexadecimal or decimal. The filename is ignored. +*/ +#include +SQLITE_EXTENSION_INIT1 +#include +#include + + +/* +** Forward declaration of objects used by this utility +*/ +typedef struct sqlite3_vfs MemVfs; +typedef struct MemFile MemFile; + +/* Access to a lower-level VFS that (might) implement dynamic loading, +** access to randomness, etc. +*/ +#define ORIGVFS(p) ((sqlite3_vfs*)((p)->pAppData)) + +/* An open file */ +struct MemFile { + sqlite3_file base; /* IO methods */ + sqlite3_int64 sz; /* Size of the file */ + unsigned char *aData; /* content of the file */ +}; + +/* +** Methods for MemFile +*/ +static int memClose(sqlite3_file*); +static int memRead(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst); +static int memWrite(sqlite3_file*,const void*,int iAmt, sqlite3_int64 iOfst); +static int memTruncate(sqlite3_file*, sqlite3_int64 size); +static int memSync(sqlite3_file*, int flags); +static int memFileSize(sqlite3_file*, sqlite3_int64 *pSize); +static int memLock(sqlite3_file*, int); +static int memUnlock(sqlite3_file*, int); +static int memCheckReservedLock(sqlite3_file*, int *pResOut); +static int memFileControl(sqlite3_file*, int op, void *pArg); +static int memSectorSize(sqlite3_file*); +static int memDeviceCharacteristics(sqlite3_file*); +static int memShmMap(sqlite3_file*, int iPg, int pgsz, int, void volatile**); +static int memShmLock(sqlite3_file*, int offset, int n, int flags); +static void memShmBarrier(sqlite3_file*); +static int memShmUnmap(sqlite3_file*, int deleteFlag); +static int memFetch(sqlite3_file*, sqlite3_int64 iOfst, int iAmt, void **pp); +static int memUnfetch(sqlite3_file*, sqlite3_int64 iOfst, void *p); + +/* +** Methods for MemVfs +*/ +static int memOpen(sqlite3_vfs*, const char *, sqlite3_file*, int , int *); +static int memDelete(sqlite3_vfs*, const char *zName, int syncDir); +static int memAccess(sqlite3_vfs*, const char *zName, int flags, int *); +static int memFullPathname(sqlite3_vfs*, const char *zName, int, char *zOut); +static void *memDlOpen(sqlite3_vfs*, const char *zFilename); +static void memDlError(sqlite3_vfs*, int nByte, char *zErrMsg); +static void (*memDlSym(sqlite3_vfs *pVfs, void *p, const char*zSym))(void); +static void memDlClose(sqlite3_vfs*, void*); +static int memRandomness(sqlite3_vfs*, int nByte, char *zOut); +static int memSleep(sqlite3_vfs*, int microseconds); +static int memCurrentTime(sqlite3_vfs*, double*); +static int memGetLastError(sqlite3_vfs*, int, char *); +static int memCurrentTimeInt64(sqlite3_vfs*, sqlite3_int64*); + +static sqlite3_vfs mem_vfs = { + 2, /* iVersion */ + 0, /* szOsFile (set when registered) */ + 1024, /* mxPathname */ + 0, /* pNext */ + "memvfs", /* zName */ + 0, /* pAppData (set when registered) */ + memOpen, /* xOpen */ + memDelete, /* xDelete */ + memAccess, /* xAccess */ + memFullPathname, /* xFullPathname */ + memDlOpen, /* xDlOpen */ + memDlError, /* xDlError */ + memDlSym, /* xDlSym */ + memDlClose, /* xDlClose */ + memRandomness, /* xRandomness */ + memSleep, /* xSleep */ + memCurrentTime, /* xCurrentTime */ + memGetLastError, /* xGetLastError */ + memCurrentTimeInt64 /* xCurrentTimeInt64 */ +}; + +static const sqlite3_io_methods mem_io_methods = { + 3, /* iVersion */ + memClose, /* xClose */ + memRead, /* xRead */ + memWrite, /* xWrite */ + memTruncate, /* xTruncate */ + memSync, /* xSync */ + memFileSize, /* xFileSize */ + memLock, /* xLock */ + memUnlock, /* xUnlock */ + memCheckReservedLock, /* xCheckReservedLock */ + memFileControl, /* xFileControl */ + memSectorSize, /* xSectorSize */ + memDeviceCharacteristics, /* xDeviceCharacteristics */ + memShmMap, /* xShmMap */ + memShmLock, /* xShmLock */ + memShmBarrier, /* xShmBarrier */ + memShmUnmap, /* xShmUnmap */ + memFetch, /* xFetch */ + memUnfetch /* xUnfetch */ +}; + + + +/* +** Close an mem-file. +** +** The pData pointer is owned by the application, so there is nothing +** to free. +*/ +static int memClose(sqlite3_file *pFile){ + return SQLITE_OK; +} + +/* +** Read data from an mem-file. +*/ +static int memRead( + sqlite3_file *pFile, + void *zBuf, + int iAmt, + sqlite_int64 iOfst +){ + MemFile *p = (MemFile *)pFile; + memcpy(zBuf, p->aData+iOfst, iAmt); + return SQLITE_OK; +} + +/* +** Write data to an mem-file. +*/ +static int memWrite( + sqlite3_file *pFile, + const void *z, + int iAmt, + sqlite_int64 iOfst +){ + return SQLITE_READONLY; +} + +/* +** Truncate an mem-file. +*/ +static int memTruncate(sqlite3_file *pFile, sqlite_int64 size){ + return SQLITE_READONLY; +} + +/* +** Sync an mem-file. +*/ +static int memSync(sqlite3_file *pFile, int flags){ + return SQLITE_READONLY; +} + +/* +** Return the current file-size of an mem-file. +*/ +static int memFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){ + MemFile *p = (MemFile *)pFile; + *pSize = p->sz; + return SQLITE_OK; +} + +/* +** Lock an mem-file. +*/ +static int memLock(sqlite3_file *pFile, int eLock){ + return SQLITE_READONLY; +} + +/* +** Unlock an mem-file. +*/ +static int memUnlock(sqlite3_file *pFile, int eLock){ + return SQLITE_OK; +} + +/* +** Check if another file-handle holds a RESERVED lock on an mem-file. +*/ +static int memCheckReservedLock(sqlite3_file *pFile, int *pResOut){ + *pResOut = 0; + return SQLITE_OK; +} + +/* +** File control method. For custom operations on an mem-file. +*/ +static int memFileControl(sqlite3_file *pFile, int op, void *pArg){ + MemFile *p = (MemFile *)pFile; + int rc = SQLITE_NOTFOUND; + if( op==SQLITE_FCNTL_VFSNAME ){ + *(char**)pArg = sqlite3_mprintf("mem(%p,%lld)", p->aData, p->sz); + rc = SQLITE_OK; + } + return rc; +} + +/* +** Return the sector-size in bytes for an mem-file. +*/ +static int memSectorSize(sqlite3_file *pFile){ + return 1024; +} + +/* +** Return the device characteristic flags supported by an mem-file. +*/ +static int memDeviceCharacteristics(sqlite3_file *pFile){ + return SQLITE_IOCAP_IMMUTABLE; +} + +/* Create a shared memory file mapping */ +static int memShmMap( + sqlite3_file *pFile, + int iPg, + int pgsz, + int bExtend, + void volatile **pp +){ + return SQLITE_READONLY; +} + +/* Perform locking on a shared-memory segment */ +static int memShmLock(sqlite3_file *pFile, int offset, int n, int flags){ + return SQLITE_READONLY; +} + +/* Memory barrier operation on shared memory */ +static void memShmBarrier(sqlite3_file *pFile){ + return; +} + +/* Unmap a shared memory segment */ +static int memShmUnmap(sqlite3_file *pFile, int deleteFlag){ + return SQLITE_OK; +} + +/* Fetch a page of a memory-mapped file */ +static int memFetch( + sqlite3_file *pFile, + sqlite3_int64 iOfst, + int iAmt, + void **pp +){ + MemFile *p = (MemFile *)pFile; + *pp = (void*)(p->aData + iOfst); + return SQLITE_OK; +} + +/* Release a memory-mapped page */ +static int memUnfetch(sqlite3_file *pFile, sqlite3_int64 iOfst, void *pPage){ + return SQLITE_OK; +} + +/* +** Open an mem file handle. +*/ +static int memOpen( + sqlite3_vfs *pVfs, + const char *zName, + sqlite3_file *pFile, + int flags, + int *pOutFlags +){ + MemFile *p = (MemFile*)pFile; + memset(p, 0, sizeof(*p)); + if( (flags & SQLITE_OPEN_MAIN_DB)==0 ) return SQLITE_CANTOPEN; + p->aData = (unsigned char*)sqlite3_uri_int64(zName,"ptr",0); + if( p->aData==0 ) return SQLITE_CANTOPEN; + p->sz = sqlite3_uri_int64(zName,"sz",0); + if( p->sz<0 ) return SQLITE_CANTOPEN; + pFile->pMethods = &mem_io_methods; + return SQLITE_OK; +} + +/* +** Delete the file located at zPath. If the dirSync argument is true, +** ensure the file-system modifications are synced to disk before +** returning. +*/ +static int memDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){ + return SQLITE_READONLY; +} + +/* +** Test for access permissions. Return true if the requested permission +** is available, or false otherwise. +*/ +static int memAccess( + sqlite3_vfs *pVfs, + const char *zPath, + int flags, + int *pResOut +){ + /* The spec says there are three possible values for flags. But only + ** two of them are actually used */ + assert( flags==SQLITE_ACCESS_EXISTS || flags==SQLITE_ACCESS_READWRITE ); + if( flags==SQLITE_ACCESS_READWRITE ){ + *pResOut = 0; + }else{ + *pResOut = 1; + } + return SQLITE_OK; +} + +/* +** Populate buffer zOut with the full canonical pathname corresponding +** to the pathname in zPath. zOut is guaranteed to point to a buffer +** of at least (INST_MAX_PATHNAME+1) bytes. +*/ +static int memFullPathname( + sqlite3_vfs *pVfs, + const char *zPath, + int nOut, + char *zOut +){ + sqlite3_snprintf(nOut, zOut, "%s", zPath); + return SQLITE_OK; +} + +/* +** Open the dynamic library located at zPath and return a handle. +*/ +static void *memDlOpen(sqlite3_vfs *pVfs, const char *zPath){ + return ORIGVFS(pVfs)->xDlOpen(ORIGVFS(pVfs), zPath); +} + +/* +** Populate the buffer zErrMsg (size nByte bytes) with a human readable +** utf-8 string describing the most recent error encountered associated +** with dynamic libraries. +*/ +static void memDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){ + ORIGVFS(pVfs)->xDlError(ORIGVFS(pVfs), nByte, zErrMsg); +} + +/* +** Return a pointer to the symbol zSymbol in the dynamic library pHandle. +*/ +static void (*memDlSym(sqlite3_vfs *pVfs, void *p, const char *zSym))(void){ + return ORIGVFS(pVfs)->xDlSym(ORIGVFS(pVfs), p, zSym); +} + +/* +** Close the dynamic library handle pHandle. +*/ +static void memDlClose(sqlite3_vfs *pVfs, void *pHandle){ + ORIGVFS(pVfs)->xDlClose(ORIGVFS(pVfs), pHandle); +} + +/* +** Populate the buffer pointed to by zBufOut with nByte bytes of +** random data. +*/ +static int memRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){ + return ORIGVFS(pVfs)->xRandomness(ORIGVFS(pVfs), nByte, zBufOut); +} + +/* +** Sleep for nMicro microseconds. Return the number of microseconds +** actually slept. +*/ +static int memSleep(sqlite3_vfs *pVfs, int nMicro){ + return ORIGVFS(pVfs)->xSleep(ORIGVFS(pVfs), nMicro); +} + +/* +** Return the current time as a Julian Day number in *pTimeOut. +*/ +static int memCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){ + return ORIGVFS(pVfs)->xCurrentTime(ORIGVFS(pVfs), pTimeOut); +} + +static int memGetLastError(sqlite3_vfs *pVfs, int a, char *b){ + return ORIGVFS(pVfs)->xGetLastError(ORIGVFS(pVfs), a, b); +} +static int memCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *p){ + return ORIGVFS(pVfs)->xCurrentTimeInt64(ORIGVFS(pVfs), p); +} + +#ifdef MEMVFS_TEST +/* +** memload(FILENAME) +** +** This an SQL function used to help in testing the memvfs VFS. The +** function reads the content of a file into memory and then returns +** a string that gives the locate and size of the in-memory buffer. +*/ +#include +static void memvfsMemloadFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + unsigned char *p; + sqlite3_int64 sz; + FILE *in; + const char *zFilename = (const char*)sqlite3_value_text(argv[0]); + char zReturn[100]; + + if( zFilename==0 ) return; + in = fopen(zFilename, "rb"); + if( in==0 ) return; + fseek(in, 0, SEEK_END); + sz = ftell(in); + rewind(in); + p = sqlite3_malloc( sz ); + if( p==0 ){ + fclose(in); + sqlite3_result_error_nomem(context); + return; + } + fread(p, sz, 1, in); + fclose(in); + sqlite3_snprintf(sizeof(zReturn),zReturn,"ptr=%lld&sz=%lld", + (sqlite3_int64)p, sz); + sqlite3_result_text(context, zReturn, -1, SQLITE_TRANSIENT); +} +/* Called for each new database connection */ +static int memvfsRegister( + sqlite3 *db, + const char **pzErrMsg, + const struct sqlite3_api_routines *pThunk +){ + return sqlite3_create_function(db, "memload", 1, SQLITE_UTF8, 0, + memvfsMemloadFunc, 0, 0); +} +#endif /* MEMVFS_TEST */ + + +#ifdef _WIN32 +__declspec(dllexport) +#endif +/* +** This routine is called when the extension is loaded. +** Register the new VFS. +*/ +int sqlite3_memvfs_init( + sqlite3 *db, + char **pzErrMsg, + const sqlite3_api_routines *pApi +){ + int rc = SQLITE_OK; + SQLITE_EXTENSION_INIT2(pApi); + mem_vfs.pAppData = sqlite3_vfs_find(0); + mem_vfs.szOsFile = sizeof(MemFile); + rc = sqlite3_vfs_register(&mem_vfs, 1); +#ifdef MEMVFS_TEST + if( rc==SQLITE_OK ){ + rc = sqlite3_auto_extension((void(*)(void))memvfsRegister); + } +#endif + if( rc==SQLITE_OK ) rc = SQLITE_OK_LOAD_PERMANENTLY; + return rc; +} diff --git a/manifest b/manifest index 0fd8b95f0c..0d41570cd8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\s".read"\scommand\sin\sthe\scommand-line\sshell\sso\sthat\sit\sunderstands\nthat\sthe\sinput\sis\snot\sinteractive. -D 2016-09-07T10:10:18.461 +C Add\sthe\sext/misc/memvfs.c\sextension\sthat\simplements\sa\sVFS\sfor\sread-only\ndatabase\sfiles\scontained\sin\smemory. +D 2016-09-07T18:11:11.252 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5017381e4853b1472e01d5bb926be1268eba429c @@ -214,6 +214,7 @@ F ext/misc/fileio.c d4171c815d6543a9edef8308aab2951413cd8d0f F ext/misc/fuzzer.c 7c64b8197bb77b7d64eff7cac7848870235d4c25 F ext/misc/ieee754.c f190d0cc5182529acb15babd177781be1ac1718c F ext/misc/json1.c 9799e4252b305edcbe659329eec3ca80ed85f968 +F ext/misc/memvfs.c e5225bc22e79dde6b28380f3a068ddf600683a33 F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342 F ext/misc/percentile.c 92699c8cd7d517ff610e6037e56506f8904dae2e F ext/misc/regexp.c a68d25c659bd2d893cd1215667bbf75ecb9dc7d4 @@ -1511,7 +1512,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 820644b886f81e991fceb5f1c3290b8959b34528 -R 2932afc8980d7b223aaea98945be0e61 +P d8451fe84d09db6ec7e1bd5f0708ea1b5e85f3d6 +R 40828d7c09ecd4e3a6b5df17d516ba22 U drh -Z 5c5e9ed55e639316842989db4edd69d1 +Z f7bf016242cf820d90b7abae39af230e diff --git a/manifest.uuid b/manifest.uuid index 342aced9e7..824ab0842b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d8451fe84d09db6ec7e1bd5f0708ea1b5e85f3d6 \ No newline at end of file +12b7782a9af91eab913e159149cb28b3f5a6557c \ No newline at end of file From 26c8d0ca21d2254b9906ac3dcc02cb82ac0604b7 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 7 Sep 2016 19:37:20 +0000 Subject: [PATCH 0808/1484] Fix a problem handling expressions like "(a, b) IN (SELECT ... ORDER BY 1, 2)" when there is an index on "a" but not "b". FossilOrigin-Name: 7f2c5c9ee3628c968306a5ab2e5a9a761f1b8055 --- manifest | 16 ++++++------- manifest.uuid | 2 +- src/wherecode.c | 22 +++++++++++++++--- test/rowvalue9.test | 56 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 84 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 2b16d0533f..274df7eb97 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Simplify\sthe\saffinity\shandling\slogic\sin\scodeAllEqualityTerms().\s\sLogically\nthe\ssame,\sjust\sa\slittle\seasier\sto\sread\sand\sunderstand. -D 2016-09-07T13:30:40.808 +C Fix\sa\sproblem\shandling\sexpressions\slike\s"(a,\sb)\sIN\s(SELECT\s...\sORDER\sBY\s1,\s2)"\swhen\sthere\sis\san\sindex\son\s"a"\sbut\snot\s"b". +D 2016-09-07T19:37:20.043 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5017381e4853b1472e01d5bb926be1268eba429c @@ -467,7 +467,7 @@ F src/wal.h 6dd221ed384afdc204bc61e25c23ef7fd5a511f2 F src/walker.c 2d2cc7fb0f320f7f415215d7247f3c584141ac09 F src/where.c edbd73a87ba2e186928e9bfc14348b1bbb2628c5 F src/whereInt.h 14dd243e13b81cbb0a66063d38b70f93a7d6e613 -F src/wherecode.c 43522ac811e2e0374603f9fc9a3dda4e1a81f470 +F src/wherecode.c d172dcf99932ba698dd304edc9a368cd52b4b2e5 F src/whereexpr.c e3db778ed205e982f31960896db71c50612ae009 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -1028,7 +1028,7 @@ F test/rowvalue5.test c1adfb2ea104e181f70d55bbd80d803b9917b22b F test/rowvalue6.test d19b54feb604d5601f8614b15e214e0774c01087 F test/rowvalue7.test 5d06ff19d9e6969e574a2e662a531dd0c67801a8 F test/rowvalue8.test 5900eddad9e2c3c2e26f1a95f74aafc1232ee5e0 -F test/rowvalue9.test 03a5edc94ab5983b98820f6541c62b43560cd84c +F test/rowvalue9.test e24f9eb02baffc6a67b6eed9e40d4c612c98079d F test/rowvaluefault.test 7b16485e3f2b371f3e3d05455b8ded6d0c090244 F test/rtree.test 0c8d9dd458d6824e59683c19ab2ffa9ef946f798 F test/run-wordcount.sh 891e89c4c2d16e629cd45951d4ed899ad12afc09 @@ -1522,7 +1522,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 193f036c87857bd77577ceb462af5034c7cc77da -R 5310dec13b5e77c999328204c9245316 -U drh -Z 06433047ae27fe630ae84491904304f6 +P bbab9621f512b04684163b98b6fc669c68038044 +R 09b192e18dc26d97d5a589656b60205f +U dan +Z 3d9ebf68fced17edbc91ddfab98198fe diff --git a/manifest.uuid b/manifest.uuid index e850f3a033..a5783a2c58 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bbab9621f512b04684163b98b6fc669c68038044 \ No newline at end of file +7f2c5c9ee3628c968306a5ab2e5a9a761f1b8055 \ No newline at end of file diff --git a/src/wherecode.c b/src/wherecode.c index fdb986cbdf..c440c56de3 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -445,8 +445,9 @@ static int codeEqualityTerm( if( (pX->flags & EP_xIsSelect)==0 || pX->x.pSelect->pEList->nExpr==1 ){ eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, 0); }else{ + Select *pSelect = pX->x.pSelect; sqlite3 *db = pParse->db; - ExprList *pOrigRhs = pX->x.pSelect->pEList; + ExprList *pOrigRhs = pSelect->pEList; ExprList *pOrigLhs = pX->pLeft->x.pList; ExprList *pRhs = 0; /* New Select.pEList for RHS */ ExprList *pLhs = 0; /* New pX->pLeft vector */ @@ -463,6 +464,21 @@ static int codeEqualityTerm( } if( !db->mallocFailed ){ Expr *pLeft = pX->pLeft; + + if( pSelect->pOrderBy ){ + /* If the SELECT statement has an ORDER BY clause, zero the + ** iOrderByCol variables. These are set to non-zero when an + ** ORDER BY term exactly matches one of the terms of the + ** result-set. Since the result-set of the SELECT statement may + ** have been modified or reordered, these variables are no longer + ** set correctly. Since setting them is just an optimization, + ** it's easiest just to zero them here. */ + ExprList *pOrderBy = pSelect->pOrderBy; + for(i=0; inExpr; i++){ + pOrderBy->a[i].u.x.iOrderByCol = 0; + } + } + /* Take care here not to generate a TK_VECTOR containing only a ** single value. Since the parser never creates such a vector, some ** of the subroutines do not handle this case. */ @@ -473,10 +489,10 @@ static int codeEqualityTerm( aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int) * nEq); testcase( aiMap==0 ); } - pX->x.pSelect->pEList = pRhs; + pSelect->pEList = pRhs; eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap); testcase( aiMap!=0 && aiMap[0]!=0 ); - pX->x.pSelect->pEList = pOrigRhs; + pSelect->pEList = pOrigRhs; pLeft->x.pList = pOrigLhs; pX->pLeft = pLeft; } diff --git a/test/rowvalue9.test b/test/rowvalue9.test index 570a5b98a8..ce324f0b42 100644 --- a/test/rowvalue9.test +++ b/test/rowvalue9.test @@ -242,5 +242,61 @@ do_execsql_test 5.3 { SELECT rowid FROM e2 WHERE rowid IN (SELECT 0+c FROM e1); } {2} +#------------------------------------------------------------------------- +# +do_execsql_test 6.0 { + CREATE TABLE f1(a, b); + CREATE TABLE f2(c, d); + CREATE TABLE f3(e, f); +} + +do_execsql_test 6.1 { + SELECT * FROM f3 WHERE (e, f) IN ( + SELECT a, b FROM f1 UNION ALL SELECT c, d FROM f2 + ); +} +do_execsql_test 6.2 { + CREATE INDEX f3e ON f3(e); + SELECT * FROM f3 WHERE (e, f) IN ( + SELECT a, b FROM f1 UNION ALL SELECT c, d FROM f2 + ); +} + + +#------------------------------------------------------------------------- +# +do_execsql_test 7.0 { + CREATE TABLE g1(a, b); + INSERT INTO g1 VALUES + (1, 1), (1, 2), (1, 3), (1, 'i'), (1, 'j'), + (1, 6), (1, 7), (1, 8), (1, 9), (1, 10), + (1, 4), (1, 5); + + CREATE TABLE g2(x, y); + CREATE INDEX g2x ON g2(x); + + INSERT INTO g2 VALUES(1, 4); + INSERT INTO g2 VALUES(1, 5); +} + +do_execsql_test 7.1 { + SELECT * FROM g2 WHERE (x, y) IN ( + SELECT a, b FROM g1 ORDER BY +a, +b LIMIT 10 + ); +} { 1 4 1 5 } + +do_execsql_test 7.2 { + SELECT * FROM g2 WHERE (x, y) IN ( + SELECT a, b FROM g1 ORDER BY a, b LIMIT 10 + ); +} { 1 4 1 5 } + +do_execsql_test 7.3 { + SELECT * FROM g2 WHERE (x, y) IN ( + SELECT a, b FROM g1 ORDER BY 1, 2 LIMIT 10 + ); +} { 1 4 1 5 } + + finish_test From 1fbd008cf4d342124f608d9db64e25fa6914e70c Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 8 Sep 2016 23:12:08 +0000 Subject: [PATCH 0809/1484] Issue a warning and prompt the user to continue if the releasetest.tcl script is run in a checkout with uncommitted changes. FossilOrigin-Name: 30e917fff05b02ce2cb1f1c871d638200fbe5716 --- manifest | 13 ++++++------- manifest.uuid | 2 +- test/releasetest.tcl | 16 ++++++++++++++++ 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index ef9ea10c49..f17e658096 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\ssupport\sfor\srow-value\scomparisons,\sincluding\sIN\soperators,\sand\nrow-value\supdates\sin\sthe\sUPDATE\sstatement. -D 2016-09-07T19:54:24.437 +C Issue\sa\swarning\sand\sprompt\sthe\suser\sto\scontinue\sif\sthe\sreleasetest.tcl\sscript\nis\srun\sin\sa\scheckout\swith\suncommitted\schanges. +D 2016-09-08T23:12:08.268 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5017381e4853b1472e01d5bb926be1268eba429c @@ -1013,7 +1013,7 @@ F test/rdonly.test 64e2696c322e3538df0b1ed624e21f9a23ed9ff8 F test/regexp1.test 497ea812f264d12b6198d6e50a76be4a1973a9d8 F test/regexp2.test aa7ffcc21350007a78361b82bcf3b74d12227144 F test/reindex.test 44edd3966b474468b823d481eafef0c305022254 -F test/releasetest.tcl 53560b838b79c468ec9973e0dfa3d8892628887f +F test/releasetest.tcl 43a4a0c4607d43f4c6d8acf75a1ff39454785c94 F test/resolver01.test f4022acafda7f4d40eca94dbf16bc5fc4ac30ceb F test/rollback.test 458fe73eb3ffdfdf9f6ba3e9b7350a6220414dea F test/rollback2.test 8435d6ff0f13f51d2a4181c232e706005fa90fc5 @@ -1523,8 +1523,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 12b7782a9af91eab913e159149cb28b3f5a6557c 7f2c5c9ee3628c968306a5ab2e5a9a761f1b8055 -R 751b4792e244c0de84e03a1b48f5b06d -T +closed 7f2c5c9ee3628c968306a5ab2e5a9a761f1b8055 +P ddb5f0558c44569913d22781ab78f3e9b58d7aea +R 3e19300302271db9c0a9ac444e4e7cc4 U drh -Z 8852ee27cbc1c9d45a2ebb8e532166b1 +Z 9a4b9802acab37aa737bc2f82c43cc8f diff --git a/manifest.uuid b/manifest.uuid index c02863b07f..3011d0abfb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ddb5f0558c44569913d22781ab78f3e9b58d7aea \ No newline at end of file +30e917fff05b02ce2cb1f1c871d638200fbe5716 \ No newline at end of file diff --git a/test/releasetest.tcl b/test/releasetest.tcl index f670c8bef4..d40ec3a6ab 100644 --- a/test/releasetest.tcl +++ b/test/releasetest.tcl @@ -926,6 +926,21 @@ proc process_options {argv} { PUTS "" } +# Check to see if there are changes in the checkout. If there are +# prompt the user to see if he wants to continue. +# +proc check_uncommitted {} { + if {[catch {exec fossil changes} res]==0 && [string trim $res]!=""} { + puts "The check-out contains uncommitted changes:" + puts $res + puts -nonewline "Run test anyhow (y/N)? " + flush stdout + set in [gets stdin] + if {$in!="y"} exit + } +} + + # Main routine. # proc main {argv} { @@ -933,6 +948,7 @@ proc main {argv} { # Process any command line options. set ::EXTRACONFIG {} process_options $argv + if {!$::DRYRUN} check_uncommitted PUTS [string repeat * 79] set ::NERR 0 From 0e4125a311116b7b3d5ad56ce752c8304468170a Mon Sep 17 00:00:00 2001 From: mistachkin Date: Thu, 8 Sep 2016 23:16:02 +0000 Subject: [PATCH 0810/1484] Remove an extra space before function names in the amalgamation. FossilOrigin-Name: 20f3c7436f6a8a7bab3968adc010c7c8325e4618 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- tool/mksqlite3c-noext.tcl | 6 +++--- tool/mksqlite3c.tcl | 6 +++--- tool/mksqlite3h.tcl | 6 +++--- 5 files changed, 18 insertions(+), 18 deletions(-) diff --git a/manifest b/manifest index c87e7a94c8..a3ab2bd2aa 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Sync\sup\sthe\sMSVC\smakefiles. -D 2016-09-05T20:46:02.202 +C Remove\san\sextra\sspace\sbefore\sfunction\snames\sin\sthe\samalgamation. +D 2016-09-08T23:16:02.556 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 6fef1e10792656c94fe1393092de6c8ba6ea1c88 @@ -1451,9 +1451,9 @@ F tool/mkopcodeh.tcl a01d2c1d8a6205b03fc635adf3735b4c523befd3 F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e F tool/mkpragmatab.tcl f0d5bb266d1d388cf86fce5ba01a891e95d72d41 F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 -F tool/mksqlite3c-noext.tcl e241889b12b7f857bc7c361776ef113d826e0c28 -F tool/mksqlite3c.tcl b076d24348a84dffd41aab01bc4e19a1ba17581a -F tool/mksqlite3h.tcl 22fa51b3dc04bef7cc55546c94b8b05478e081f8 +F tool/mksqlite3c-noext.tcl fef88397668ae83166735c41af99d79f56afaabb +F tool/mksqlite3c.tcl 06b2e6a0f21cc0a5d70fbbd136b3e0a96470645e +F tool/mksqlite3h.tcl c006c4e5da57c649b24b689511dcd270dd7b0249 F tool/mksqlite3internalh.tcl eb994013e833359137eb53a55acdad0b5ae1049b F tool/mkvsix.tcl 4abcaf3267171b2faadaf9b82a0dfbaa6e98f8b7 F tool/offsets.c fe4262fdfa378e8f5499a42136d17bf3b98f6091 @@ -1511,7 +1511,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ea635bf97edb35b95b34adcb63f726f3573b1c4d -R d8ebd39537a766e051577a29d6825c19 +P f66d0d8cf6976c62f7bc0e9390b09fb9976178c1 +R fa000513563ca36d44c377600d4e0d8c U mistachkin -Z 1961d7bb5f7d90748e74759804c9ac8c +Z e1e69ed364aa2ee4f40d4db15b985daf diff --git a/manifest.uuid b/manifest.uuid index a4d0903718..f0f9df083e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f66d0d8cf6976c62f7bc0e9390b09fb9976178c1 \ No newline at end of file +20f3c7436f6a8a7bab3968adc010c7c8325e4618 \ No newline at end of file diff --git a/tool/mksqlite3c-noext.tcl b/tool/mksqlite3c-noext.tcl index a55e93ff16..a16b0591eb 100644 --- a/tool/mksqlite3c-noext.tcl +++ b/tool/mksqlite3c-noext.tcl @@ -226,12 +226,12 @@ proc copy_file {filename} { } if {$useapicall} { if {[lsearch -exact $cdecllist $funcname] >= 0} { - append line SQLITE_CDECL + append line SQLITE_CDECL " " } else { - append line SQLITE_APICALL + append line SQLITE_APICALL " " } } - append line " " $funcname $rest + append line $funcname $rest puts $out $line } else { puts $out "SQLITE_PRIVATE $line" diff --git a/tool/mksqlite3c.tcl b/tool/mksqlite3c.tcl index 9938ed14e4..55179c4b80 100644 --- a/tool/mksqlite3c.tcl +++ b/tool/mksqlite3c.tcl @@ -234,12 +234,12 @@ proc copy_file {filename} { } if {$useapicall} { if {[lsearch -exact $cdecllist $funcname] >= 0} { - append line SQLITE_CDECL + append line SQLITE_CDECL " " } else { - append line SQLITE_APICALL + append line SQLITE_APICALL " " } } - append line " " $funcname $rest + append line $funcname $rest puts $out $line } else { puts $out "SQLITE_PRIVATE $line" diff --git a/tool/mksqlite3h.tcl b/tool/mksqlite3h.tcl index c620eb630d..4f8a1fd497 100644 --- a/tool/mksqlite3h.tcl +++ b/tool/mksqlite3h.tcl @@ -129,12 +129,12 @@ foreach file $filelist { } if {$useapicall} { if {[lsearch -exact $cdecllist $funcname] >= 0} { - append line SQLITE_CDECL + append line SQLITE_CDECL " " } else { - append line SQLITE_APICALL + append line SQLITE_APICALL " " } } - append line " " $funcname $rest + append line $funcname $rest } } if {$useapicall} { From eedeb92caa78cb0170f592eb62189e8dbe2f9164 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 9 Sep 2016 12:29:57 +0000 Subject: [PATCH 0811/1484] In releasetest.tcl: Improved testing for uncommitted changes. If uncommitted changes are seen, exit immediately unless the --force option is used. FossilOrigin-Name: 9a14e6c46cdda9f10151ee96a0540798573edcf2 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/releasetest.tcl | 33 +++++++++++++++++++++------------ 3 files changed, 28 insertions(+), 19 deletions(-) diff --git a/manifest b/manifest index f17e658096..9cf1c97fce 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Issue\sa\swarning\sand\sprompt\sthe\suser\sto\scontinue\sif\sthe\sreleasetest.tcl\sscript\nis\srun\sin\sa\scheckout\swith\suncommitted\schanges. -D 2016-09-08T23:12:08.268 +C In\sreleasetest.tcl:\nImproved\stesting\sfor\suncommitted\schanges.\s\sIf\suncommitted\schanges\sare\sseen,\nexit\simmediately\sunless\sthe\s--force\soption\sis\sused. +D 2016-09-09T12:29:57.587 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5017381e4853b1472e01d5bb926be1268eba429c @@ -1013,7 +1013,7 @@ F test/rdonly.test 64e2696c322e3538df0b1ed624e21f9a23ed9ff8 F test/regexp1.test 497ea812f264d12b6198d6e50a76be4a1973a9d8 F test/regexp2.test aa7ffcc21350007a78361b82bcf3b74d12227144 F test/reindex.test 44edd3966b474468b823d481eafef0c305022254 -F test/releasetest.tcl 43a4a0c4607d43f4c6d8acf75a1ff39454785c94 +F test/releasetest.tcl 96c3c995276502ed161fba048db11bf609d06401 F test/resolver01.test f4022acafda7f4d40eca94dbf16bc5fc4ac30ceb F test/rollback.test 458fe73eb3ffdfdf9f6ba3e9b7350a6220414dea F test/rollback2.test 8435d6ff0f13f51d2a4181c232e706005fa90fc5 @@ -1523,7 +1523,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ddb5f0558c44569913d22781ab78f3e9b58d7aea -R 3e19300302271db9c0a9ac444e4e7cc4 +P 30e917fff05b02ce2cb1f1c871d638200fbe5716 +R 45edd926e90edddd4f4fdfd05cd3a2d6 U drh -Z 9a4b9802acab37aa737bc2f82c43cc8f +Z 4b0b0b85746acf466aacffff9e5b1376 diff --git a/manifest.uuid b/manifest.uuid index 3011d0abfb..a00fc4e9a0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -30e917fff05b02ce2cb1f1c871d638200fbe5716 \ No newline at end of file +9a14e6c46cdda9f10151ee96a0540798573edcf2 \ No newline at end of file diff --git a/test/releasetest.tcl b/test/releasetest.tcl index d40ec3a6ab..5beecd1cfa 100644 --- a/test/releasetest.tcl +++ b/test/releasetest.tcl @@ -9,18 +9,19 @@ This Tcl script is used to test the various configurations required before releasing a new version. Supported command line options (all optional) are: - --srcdir TOP-OF-SQLITE-TREE (see below) - --platform PLATFORM (see below) - --config CONFIGNAME (Run only CONFIGNAME) - --quick (Run "veryquick.test" only) - --veryquick (Run "make smoketest" only) - --msvc (Use MSVC as the compiler) --buildonly (Just build testfixture - do not run) + --config CONFIGNAME (Run only CONFIGNAME) --dryrun (Print what would have happened) + -f|--force (Run even if uncommitted changes) --info (Show diagnostic info) - --with-tcl=DIR (Use TCL build at DIR) --jobs N (Use N processes - default 1) + --msvc (Use MSVC as the compiler) + --platform PLATFORM (see below) --progress (Show progress messages) + --quick (Run "veryquick.test" only) + --srcdir TOP-OF-SQLITE-TREE (see below) + --veryquick (Run "make smoketest" only) + --with-tcl=DIR (Use TCL build at DIR) The default value for --srcdir is the parent of the directory holding this script. @@ -778,6 +779,7 @@ proc process_options {argv} { set ::JOBS 1 set ::PROGRESS_MSGS 0 set ::WITHTCL {} + set ::FORCE 0 set config {} set platform $::tcl_platform(os)-$::tcl_platform(machine) @@ -833,6 +835,11 @@ proc process_options {argv} { set ::DRYRUN 1 } + -force - + -f { + set ::FORCE 1 + } + -trace { set ::TRACE 1 } @@ -930,14 +937,16 @@ proc process_options {argv} { # prompt the user to see if he wants to continue. # proc check_uncommitted {} { + if {$::FORCE} return + set pwd [pwd] + cd $::SRCDIR if {[catch {exec fossil changes} res]==0 && [string trim $res]!=""} { - puts "The check-out contains uncommitted changes:" + puts "ERROR: The check-out contains uncommitted changes:" puts $res - puts -nonewline "Run test anyhow (y/N)? " - flush stdout - set in [gets stdin] - if {$in!="y"} exit + puts "Use the -f or --force options to override" + exit 1 } + cd $pwd } From 2c33183d11abc61b5f01622bbbdf3cfab856af99 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 9 Sep 2016 13:17:26 +0000 Subject: [PATCH 0812/1484] Fix an obsolete comment in the releasetest.tcl source code. FossilOrigin-Name: afaaa276b256f56adf63cb568e486cb3315c3ec2 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/releasetest.tcl | 6 ++++-- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 9cf1c97fce..513fe5f2d6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\sreleasetest.tcl:\nImproved\stesting\sfor\suncommitted\schanges.\s\sIf\suncommitted\schanges\sare\sseen,\nexit\simmediately\sunless\sthe\s--force\soption\sis\sused. -D 2016-09-09T12:29:57.587 +C Fix\san\sobsolete\scomment\sin\sthe\sreleasetest.tcl\ssource\scode. +D 2016-09-09T13:17:26.104 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5017381e4853b1472e01d5bb926be1268eba429c @@ -1013,7 +1013,7 @@ F test/rdonly.test 64e2696c322e3538df0b1ed624e21f9a23ed9ff8 F test/regexp1.test 497ea812f264d12b6198d6e50a76be4a1973a9d8 F test/regexp2.test aa7ffcc21350007a78361b82bcf3b74d12227144 F test/reindex.test 44edd3966b474468b823d481eafef0c305022254 -F test/releasetest.tcl 96c3c995276502ed161fba048db11bf609d06401 +F test/releasetest.tcl 46e73e306efd6bc1739efead3583ea0e2003f4d9 F test/resolver01.test f4022acafda7f4d40eca94dbf16bc5fc4ac30ceb F test/rollback.test 458fe73eb3ffdfdf9f6ba3e9b7350a6220414dea F test/rollback2.test 8435d6ff0f13f51d2a4181c232e706005fa90fc5 @@ -1523,7 +1523,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 30e917fff05b02ce2cb1f1c871d638200fbe5716 -R 45edd926e90edddd4f4fdfd05cd3a2d6 +P 9a14e6c46cdda9f10151ee96a0540798573edcf2 +R 7940b5c2f77005fa33fade550bc3d89e U drh -Z 4b0b0b85746acf466aacffff9e5b1376 +Z 45010a2c3dad5e8a3c02935127df2fd0 diff --git a/manifest.uuid b/manifest.uuid index a00fc4e9a0..8098499d71 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9a14e6c46cdda9f10151ee96a0540798573edcf2 \ No newline at end of file +afaaa276b256f56adf63cb568e486cb3315c3ec2 \ No newline at end of file diff --git a/test/releasetest.tcl b/test/releasetest.tcl index 5beecd1cfa..342c5f3036 100644 --- a/test/releasetest.tcl +++ b/test/releasetest.tcl @@ -933,8 +933,10 @@ proc process_options {argv} { PUTS "" } -# Check to see if there are changes in the checkout. If there are -# prompt the user to see if he wants to continue. +# Check to see if there are uncommitted changes in the SQLite source +# checkout. Exit if there are. Except: Do nothing if the --force +# flag is used. Also, ignore this test if the fossil binary is +# unavailable, or if the source tree is not a valid fossil checkout. # proc check_uncommitted {} { if {$::FORCE} return From fe3765828a709ef730b667de42353cce5bca26f9 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 9 Sep 2016 13:23:36 +0000 Subject: [PATCH 0813/1484] In releasetest.tcl, the --srcdir option is automatic, so no need to mention it in the --help output. FossilOrigin-Name: 2bdd838e2c434f1d26b1836ef39fa938ef93131d --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/releasetest.tcl | 10 ++++++---- 3 files changed, 13 insertions(+), 11 deletions(-) mode change 100644 => 100755 test/releasetest.tcl diff --git a/manifest b/manifest index 513fe5f2d6..efa540c97c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\sobsolete\scomment\sin\sthe\sreleasetest.tcl\ssource\scode. -D 2016-09-09T13:17:26.104 +C In\sreleasetest.tcl,\sthe\s--srcdir\soption\sis\sautomatic,\sso\sno\sneed\sto\smention\nit\sin\sthe\s--help\soutput. +D 2016-09-09T13:23:36.137 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5017381e4853b1472e01d5bb926be1268eba429c @@ -1013,7 +1013,7 @@ F test/rdonly.test 64e2696c322e3538df0b1ed624e21f9a23ed9ff8 F test/regexp1.test 497ea812f264d12b6198d6e50a76be4a1973a9d8 F test/regexp2.test aa7ffcc21350007a78361b82bcf3b74d12227144 F test/reindex.test 44edd3966b474468b823d481eafef0c305022254 -F test/releasetest.tcl 46e73e306efd6bc1739efead3583ea0e2003f4d9 +F test/releasetest.tcl ce72fb81a76beb81dab4d83e20ada2d68a078361 x F test/resolver01.test f4022acafda7f4d40eca94dbf16bc5fc4ac30ceb F test/rollback.test 458fe73eb3ffdfdf9f6ba3e9b7350a6220414dea F test/rollback2.test 8435d6ff0f13f51d2a4181c232e706005fa90fc5 @@ -1523,7 +1523,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 9a14e6c46cdda9f10151ee96a0540798573edcf2 -R 7940b5c2f77005fa33fade550bc3d89e +P afaaa276b256f56adf63cb568e486cb3315c3ec2 +R d307f78f7d85e383c9266a539201664c U drh -Z 45010a2c3dad5e8a3c02935127df2fd0 +Z 810b7b5c52fdba9d6e7019ea79310fb8 diff --git a/manifest.uuid b/manifest.uuid index 8098499d71..f2bca13730 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -afaaa276b256f56adf63cb568e486cb3315c3ec2 \ No newline at end of file +2bdd838e2c434f1d26b1836ef39fa938ef93131d \ No newline at end of file diff --git a/test/releasetest.tcl b/test/releasetest.tcl old mode 100644 new mode 100755 index 342c5f3036..82d695b038 --- a/test/releasetest.tcl +++ b/test/releasetest.tcl @@ -19,13 +19,9 @@ optional) are: --platform PLATFORM (see below) --progress (Show progress messages) --quick (Run "veryquick.test" only) - --srcdir TOP-OF-SQLITE-TREE (see below) --veryquick (Run "make smoketest" only) --with-tcl=DIR (Use TCL build at DIR) -The default value for --srcdir is the parent of the directory holding -this script. - The script determines the default value for --platform using the $tcl_platform(os) and $tcl_platform(machine) variables. Supported platforms are "Linux-x86", "Linux-x86_64", "Darwin-i386", @@ -792,6 +788,12 @@ proc process_options {argv} { exit } + # Undocumented legacy option: --srcdir DIRECTORY + # + # DIRECTORY is the root of the SQLite checkout. This sets the + # SRCDIR global variable. But that variable is already set + # automatically so there really is no reason to have this option. + # -srcdir { incr i set ::SRCDIR [file normalize [lindex $argv $i]] From b80dbdc2f740dd016a760e31f5835ecd48ab6579 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 9 Sep 2016 15:12:41 +0000 Subject: [PATCH 0814/1484] Fix a out-of-order variable declaration for some compile-time configurations. FossilOrigin-Name: 6ac932c92a61cd68cc5b1816216e4748a5c7b3cd --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/expr.c | 10 +++++----- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index efa540c97c..0c8f1e22eb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\sreleasetest.tcl,\sthe\s--srcdir\soption\sis\sautomatic,\sso\sno\sneed\sto\smention\nit\sin\sthe\s--help\soutput. -D 2016-09-09T13:23:36.137 +C Fix\sa\sout-of-order\svariable\sdeclaration\sfor\ssome\scompile-time\sconfigurations. +D 2016-09-09T15:12:41.801 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5017381e4853b1472e01d5bb926be1268eba429c @@ -339,7 +339,7 @@ F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7 F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c 76c084f0265f4a3cd1ecf17eee112a94f1ccbc05 -F src/expr.c 028c34005cb804abe8f73453ac08baa44f4b63f9 +F src/expr.c c1de78269522de39f6ad877ab0810a5d48f91f34 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c e2be0968c1adc679c87e467aa5b4f167588f38a8 F src/func.c 29cc9acb170ec1387b9f63eb52cd85f8de96c771 @@ -1523,7 +1523,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P afaaa276b256f56adf63cb568e486cb3315c3ec2 -R d307f78f7d85e383c9266a539201664c +P 2bdd838e2c434f1d26b1836ef39fa938ef93131d +R cdaf391119a3a76bb49bf405a13f8694 U drh -Z 810b7b5c52fdba9d6e7019ea79310fb8 +Z f913482662ff429e344c363b85d81ce9 diff --git a/manifest.uuid b/manifest.uuid index f2bca13730..163d453923 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2bdd838e2c434f1d26b1836ef39fa938ef93131d \ No newline at end of file +6ac932c92a61cd68cc5b1816216e4748a5c7b3cd \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 80497be111..abae812ea5 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2234,11 +2234,11 @@ int sqlite3FindInIndex( if( colUsed==(MASKBIT(nExpr)-1) ){ /* If we reach this point, that means the index pIdx is usable */ int iAddr = sqlite3CodeOnce(pParse); VdbeCoverage(v); - #ifndef SQLITE_OMIT_EXPLAIN +#ifndef SQLITE_OMIT_EXPLAIN sqlite3VdbeAddOp4(v, OP_Explain, 0, 0, 0, sqlite3MPrintf(db, "USING INDEX %s FOR IN-OPERATOR",pIdx->zName), P4_DYNAMIC); - #endif +#endif sqlite3VdbeAddOp3(v, OP_OpenRead, iTab, pIdx->tnum, iDb); sqlite3VdbeSetP4KeyInfo(pParse, pIdx); VdbeComment((v, "%s", pIdx->zName)); @@ -2246,12 +2246,12 @@ int sqlite3FindInIndex( eType = IN_INDEX_INDEX_ASC + pIdx->aSortOrder[0]; if( prRhsHasNull ){ - *prRhsHasNull = ++pParse->nMem; - #ifdef SQLITE_ENABLE_COLUMN_USED_MASK +#ifdef SQLITE_ENABLE_COLUMN_USED_MASK i64 mask = (1<nMem; if( nExpr==1 ){ sqlite3SetHasNullFlag(v, iTab, *prRhsHasNull); } From 64caee40865a8edc3d1ea2f86a63859bb2c5cdb5 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 9 Sep 2016 19:33:00 +0000 Subject: [PATCH 0815/1484] Performance improvements to the comparison operators in the bytecode engine. FossilOrigin-Name: 37803b19d219f4107f29b240d5d314600e4bd236 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/vdbe.c | 19 +++++++++++-------- src/vdbeaux.c | 36 ++++++++++++++++++++++++++++++++++-- 4 files changed, 53 insertions(+), 18 deletions(-) diff --git a/manifest b/manifest index 0c8f1e22eb..e10c5a254b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sout-of-order\svariable\sdeclaration\sfor\ssome\scompile-time\sconfigurations. -D 2016-09-09T15:12:41.801 +C Performance\simprovements\sto\sthe\scomparison\soperators\sin\sthe\sbytecode\sengine. +D 2016-09-09T19:33:00.624 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5017381e4853b1472e01d5bb926be1268eba429c @@ -452,11 +452,11 @@ F src/update.c 8179e699dbd45b92934fd02d3d8e3732e8da8802 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 810ec3f22e2d1b62e66c30fe3621ebdedd23584d F src/vacuum.c 913970b9d86dd6c2b8063ef1af421880f1464ec3 -F src/vdbe.c 3148d5d47816c5ad2ed3c62beb3086cbbcaab107 +F src/vdbe.c 2087dfd6f013a9c808c92f8713fd8c7c62be2857 F src/vdbe.h 67bc551f7faf04c33493892e4b378aada823ed10 F src/vdbeInt.h c59381049af5c7751a83456c39b80d1a6fde1f9d F src/vdbeapi.c a32d61b7dd05e6890d8fd44d2805f55e2f5ba9f3 -F src/vdbeaux.c 83458783d241cfd6691141c8a105832ee50258e5 +F src/vdbeaux.c 230b6826656144bcdca6d9c09d38da9d927739be F src/vdbeblob.c 3e82a797b60c3b9fed7b8de8c539ca7607874937 F src/vdbemem.c e67dc6d8177fd1830efb5d15e17793408251a187 F src/vdbesort.c 91fda3909326860382b0ca8aa251e609c6a9d62c @@ -1523,7 +1523,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 2bdd838e2c434f1d26b1836ef39fa938ef93131d -R cdaf391119a3a76bb49bf405a13f8694 +P 6ac932c92a61cd68cc5b1816216e4748a5c7b3cd +R f1fdb6c44ee59a1a70f4ca210b22ee73 U drh -Z f913482662ff429e344c363b85d81ce9 +Z 14efbbb4d9b59bda04ac0672b03a8c5e diff --git a/manifest.uuid b/manifest.uuid index 163d453923..da37ec616c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6ac932c92a61cd68cc5b1816216e4748a5c7b3cd \ No newline at end of file +37803b19d219f4107f29b240d5d314600e4bd236 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index c3c9c607cb..91ff5bc900 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2035,12 +2035,21 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ if( (flags1 | flags3)&MEM_Str ){ if( (flags1 & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){ applyNumericAffinity(pIn1,0); + testcase( flags3!=pIn3->flags ); /* Possible if pIn1==pIn3 */ flags3 = pIn3->flags; } if( (flags3 & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){ applyNumericAffinity(pIn3,0); } } + /* Handle the common case of integer comparison here, as an + ** optimization, to avoid a call to sqlite3MemCompare() */ + if( (pIn1->flags & pIn3->flags & MEM_Int)!=0 ){ + if( pIn3->u.i > pIn1->u.i ){ res = +1; goto compare_op; } + if( pIn3->u.i < pIn1->u.i ){ res = -1; goto compare_op; } + res = 0; + goto compare_op; + } }else if( affinity==SQLITE_AFF_TEXT ){ if( (flags1 & MEM_Str)==0 && (flags1 & (MEM_Int|MEM_Real))!=0 ){ testcase( pIn1->flags & MEM_Int ); @@ -2048,6 +2057,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ sqlite3VdbeMemStringify(pIn1, encoding, 1); testcase( (flags1&MEM_Dyn) != (pIn1->flags&MEM_Dyn) ); flags1 = (pIn1->flags & ~MEM_TypeMask) | (flags1 & MEM_TypeMask); + testcase( flags3!=pIn3->flags ); /* Possible if pIn1==pIn3 */ flags3 = pIn3->flags; } if( (flags3 & MEM_Str)==0 && (flags3 & (MEM_Int|MEM_Real))!=0 ){ @@ -2059,16 +2069,9 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ } } assert( pOp->p4type==P4_COLLSEQ || pOp->p4.pColl==0 ); - if( flags1 & MEM_Zero ){ - sqlite3VdbeMemExpandBlob(pIn1); - flags1 &= ~MEM_Zero; - } - if( flags3 & MEM_Zero ){ - sqlite3VdbeMemExpandBlob(pIn3); - flags3 &= ~MEM_Zero; - } res = sqlite3MemCompare(pIn3, pIn1, pOp->p4.pColl); } +compare_op: switch( pOp->opcode ){ case OP_Eq: res2 = res==0; break; case OP_Ne: res2 = res; break; diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 963833cce5..710ce84b97 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -3716,15 +3716,47 @@ static int vdbeCompareMemString( } } +/* +** The input pBlob is guaranteed to be a Blob that is not marked +** with MEM_Zero. Return true if it could be a zero-blob. +*/ +static int isZeroBlob(const Mem *pBlob){ + int i; + for(i=0; in && pBlob->z[i]==0; i++){} + return i==pBlob->n; +} + /* ** Compare two blobs. Return negative, zero, or positive if the first ** is less than, equal to, or greater than the second, respectively. ** If one blob is a prefix of the other, then the shorter is the lessor. */ static SQLITE_NOINLINE int sqlite3BlobCompare(const Mem *pB1, const Mem *pB2){ - int c = memcmp(pB1->z, pB2->z, pB1->n>pB2->n ? pB2->n : pB1->n); + int c; + int n1 = pB1->n; + int n2 = pB2->n; + + /* It is possible to have a Blob value that has some non-zero content + ** followed by zero content. But that only comes up for Blobs formed + ** by the OP_MakeRecord opcode, and such Blobs never get passed into + ** sqlite3MemCompare(). */ + assert( (pB1->flags & MEM_Zero)==0 || n1==0 ); + assert( (pB2->flags & MEM_Zero)==0 || n2==0 ); + + if( (pB1->flags|pB2->flags) & MEM_Zero ){ + if( pB1->flags & pB2->flags & MEM_Zero ){ + return pB1->u.nZero - pB2->u.nZero; + }else if( pB1->flags & MEM_Zero ){ + if( !isZeroBlob(pB2) ) return -1; + return pB1->u.nZero - n2; + }else{ + if( !isZeroBlob(pB1) ) return +1; + return n1 - pB2->u.nZero; + } + } + c = memcmp(pB1->z, pB2->z, n1>n2 ? n2 : n1); if( c ) return c; - return pB1->n - pB2->n; + return n1 - n2; } /* From 000f95b1ba8760b3d8859395ed360b9933634ae3 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 9 Sep 2016 20:00:40 +0000 Subject: [PATCH 0816/1484] Add new file test_delete.c, containing test code for deleting an sqlite database. FossilOrigin-Name: fb0b95e9405a3180d13c6318409af361e9df7632 --- Makefile.in | 1 + Makefile.msc | 1 + main.mk | 1 + manifest | 25 +++--- manifest.uuid | 2 +- src/test1.c | 24 +++++ src/test_delete.c | 136 ++++++++++++++++++++++++++++ test/delete_db.test | 214 ++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 393 insertions(+), 11 deletions(-) create mode 100644 src/test_delete.c create mode 100644 test/delete_db.test diff --git a/Makefile.in b/Makefile.in index 9b2fe86cf4..bb1f14b6ab 100644 --- a/Makefile.in +++ b/Makefile.in @@ -382,6 +382,7 @@ TESTSRC = \ $(TOP)/src/test_blob.c \ $(TOP)/src/test_btree.c \ $(TOP)/src/test_config.c \ + $(TOP)/src/test_delete.c \ $(TOP)/src/test_demovfs.c \ $(TOP)/src/test_devsym.c \ $(TOP)/src/test_fs.c \ diff --git a/Makefile.msc b/Makefile.msc index 6c7211651d..931e1836b3 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -1269,6 +1269,7 @@ TESTSRC = \ $(TOP)\src\test_blob.c \ $(TOP)\src\test_btree.c \ $(TOP)\src\test_config.c \ + $(TOP)\src\test_delete.c \ $(TOP)\src\test_demovfs.c \ $(TOP)\src\test_devsym.c \ $(TOP)\src\test_fs.c \ diff --git a/main.mk b/main.mk index 451837ffff..a5a50d205d 100644 --- a/main.mk +++ b/main.mk @@ -293,6 +293,7 @@ TESTSRC = \ $(TOP)/src/test_blob.c \ $(TOP)/src/test_btree.c \ $(TOP)/src/test_config.c \ + $(TOP)/src/test_delete.c \ $(TOP)/src/test_demovfs.c \ $(TOP)/src/test_devsym.c \ $(TOP)/src/test_fs.c \ diff --git a/manifest b/manifest index 0c8f1e22eb..8bece82eaf 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -C Fix\sa\sout-of-order\svariable\sdeclaration\sfor\ssome\scompile-time\sconfigurations. -D 2016-09-09T15:12:41.801 -F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 +C Add\snew\sfile\stest_delete.c,\scontaining\stest\scode\sfor\sdeleting\san\ssqlite\sdatabase. +D 2016-09-09T20:00:40.358 +F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 -F Makefile.msc 5017381e4853b1472e01d5bb926be1268eba429c +F Makefile.msc e1aa788e84f926e42239ee167c53f785bedacacd F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7 F VERSION 25e2e333adeff5965520bc8db999c658898c972d F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 @@ -310,7 +310,7 @@ F ext/userauth/userauth.c 5fa3bdb492f481bbc1709fc83c91ebd13460c69e F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60 -F main.mk 1883ecab643b136e8ab3fdc33785e6ea8b5ceb46 +F main.mk 06dc0b1a9c9e2d05c9275937dd5b894bfe7d17d8 F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 @@ -396,7 +396,7 @@ F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 F src/tclsqlite.c bdae822f21e229b6daced15938b6343ce44ef454 -F src/test1.c 8574e41c1bf103727909b37351b3690cc07bc8a7 +F src/test1.c 61a08ed5861f3396ea4ff83931387696b692e1f8 F src/test2.c b7174313e993754303a8b33c43df7c44b46857ab F src/test3.c 1339a40be39650ae83894b6578f971dc7f96ea8a F src/test4.c 18ec393bb4d0ad1de729f0b94da7267270f3d8e6 @@ -412,6 +412,7 @@ F src/test_bestindex.c d23f80d334c59662af69191854c76b8d3d0c8c96 F src/test_blob.c a0f7ad49a0c9d4b72f693fe2a71c58d7e507174d F src/test_btree.c 8b2dc8b8848cf3a4db93f11578f075e82252a274 F src/test_config.c 4d3d4a886416f369771d69a6dba926866deda788 +F src/test_delete.c 3e7c7223fd78da017569aea5521696a2d203d2ba F src/test_demovfs.c a0c3bdd45ed044115c2c9f7779e56eafff18741e F src/test_devsym.c 4e58dec2602d8e139ca08659f62a62450587cb58 F src/test_fs.c e16cbe68d3b107e00a907c20a9a02629870eb69b @@ -631,6 +632,7 @@ F test/delete.test acc38fca8ee4851467705b1c2cfea64cd26667e5 F test/delete2.test 3a03f2cca1f9a67ec469915cb8babd6485db43fa F test/delete3.test 555e84a00a99230b7d049d477a324a631126a6ab F test/delete4.test 21d2113217eeaacac2d99defe14fe6611615ae86 +F test/delete_db.test 906fb709bd71443c2484dcf24b05a21d125d149f F test/descidx1.test 6d03b44c8538fe0eb4924e19fba10cdd8f3c9240 F test/descidx2.test 9f1a0c83fd57f8667c82310ca21b30a350888b5d F test/descidx3.test 09ddbe3f5295f482d2f8b687cf6db8bad7acd9a2 @@ -1523,7 +1525,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 2bdd838e2c434f1d26b1836ef39fa938ef93131d -R cdaf391119a3a76bb49bf405a13f8694 -U drh -Z f913482662ff429e344c363b85d81ce9 +P 6ac932c92a61cd68cc5b1816216e4748a5c7b3cd +R 49c1be8b151a3311317589c820143e41 +T *branch * test_delete +T *sym-test_delete * +T -sym-trunk * +U dan +Z b08ae969e8f18eb5dd37e3842872bc5d diff --git a/manifest.uuid b/manifest.uuid index 163d453923..ad51945639 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6ac932c92a61cd68cc5b1816216e4748a5c7b3cd \ No newline at end of file +fb0b95e9405a3180d13c6318409af361e9df7632 \ No newline at end of file diff --git a/src/test1.c b/src/test1.c index 367bcc1f7b..a7d20be45d 100644 --- a/src/test1.c +++ b/src/test1.c @@ -2388,6 +2388,29 @@ static int SQLITE_TCLAPI test_snapshot_cmp( } #endif /* SQLITE_ENABLE_SNAPSHOT */ +/* +** Usage: sqlite3_delete_database FILENAME +*/ +int sqlite3_delete_database(const char*); /* in test_delete.c */ +static int SQLITE_TCLAPI test_delete_database( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + int rc; + const char *zFile; + if( objc!=2 ){ + Tcl_WrongNumArgs(interp, 1, objv, "FILE"); + return TCL_ERROR; + } + zFile = (const char*)Tcl_GetString(objv[1]); + rc = sqlite3_delete_database(zFile); + + Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1)); + return TCL_OK; +} + /* ** Usage: sqlite3_next_stmt DB STMT ** @@ -7483,6 +7506,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){ { "sqlite3_snapshot_free", test_snapshot_free, 0 }, { "sqlite3_snapshot_cmp", test_snapshot_cmp, 0 }, #endif + { "sqlite3_delete_database", test_delete_database, 0 }, }; static int bitmask_size = sizeof(Bitmask)*8; static int longdouble_size = sizeof(LONGDOUBLE_TYPE); diff --git a/src/test_delete.c b/src/test_delete.c new file mode 100644 index 0000000000..6d5c353dea --- /dev/null +++ b/src/test_delete.c @@ -0,0 +1,136 @@ +/* +** 2016 September 10 +** +** 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 contains test code to delete an SQLite database and all +** of its associated files. Associated files include: +** +** * The journal file. +** * The wal file. +** * The SQLITE_ENABLE_8_3_NAMES version of the db, journal or wal files. +** * Files created by the test_multiplex.c module to extend any of the +** above. +*/ + + +#include +#include +#include +#include "sqlite3.h" + +/* The following #defines are copied from test_multiplex.c */ +#ifndef MX_CHUNK_NUMBER +# define MX_CHUNK_NUMBER 299 +#endif +#ifndef SQLITE_MULTIPLEX_JOURNAL_8_3_OFFSET +# define SQLITE_MULTIPLEX_JOURNAL_8_3_OFFSET 400 +#endif +#ifndef SQLITE_MULTIPLEX_WAL_8_3_OFFSET +# define SQLITE_MULTIPLEX_WAL_8_3_OFFSET 700 +#endif + +/* +** This routine is a copy of (most of) the code from SQLite function +** sqlite3FileSuffix3(). It modifies the filename in buffer z in the +** same way as SQLite does when in 8.3 filenames mode. +*/ +static void sqlite3Delete83Name(char *z){ + int i, sz; + sz = strlen(z); + for(i=sz-1; i>0 && z[i]!='/' && z[i]!='.'; i--){} + if( z[i]=='.' && (sz>i+4) ) memmove(&z[i+1], &z[sz-3], 4); +} + +/* +** zFile is a filename. Assuming no error occurs, if this file exists, +** set *pbExists to true and unlink it. Or, if the file does not exist, +** set *pbExists to false before returning. +** +** If an error occurs, the value of errno is returned. Or, if no error +** occurs, zero is returned. +*/ +static int sqlite3DeleteUnlinkIfExists(const char *zFile, int *pbExists){ + int rc; + rc = access(zFile, F_OK); + if( rc ){ + if( errno==ENOENT ){ + if( pbExists ) *pbExists = 0; + return 0; + } + return errno; + } + if( pbExists ) *pbExists = 1; + rc = unlink(zFile); + if( rc ) return errno; + return 0; +} + +/* +** Delete the database file identified by the string argument passed to this +** function. The string must contain a filename, not an SQLite URI. +*/ +int sqlite3_delete_database( + const char *zFile /* File to delete */ +){ + char *zBuf; /* Buffer to sprintf() filenames to */ + int nBuf; /* Size of buffer in bytes */ + int rc; /* System error code */ + int i; /* Iterate through azFmt[] and aMFile[] */ + + const char *azFmt[] = { "%s", "%s-journal", "%s-wal", "%s-shm" }; + + struct MFile { + const char *zFmt; + int iOffset; + int b83; + } aMFile[] = { + { "%s%03d", 0, 0 }, + { "%s-journal%03d", 0, 0 }, + { "%s-wal%03d", 0, 0 }, + { "%s%03d", 0, 1 }, + { "%s-journal%03d", SQLITE_MULTIPLEX_JOURNAL_8_3_OFFSET, 1 }, + { "%s-wal%03d", SQLITE_MULTIPLEX_WAL_8_3_OFFSET, 1 }, + }; + + /* Allocate a buffer large enough for any of the files that need to be + ** deleted. */ + nBuf = strlen(zFile) + 100; + zBuf = (char*)sqlite3_malloc(nBuf); + if( zBuf==0 ) return SQLITE_NOMEM; + + /* Delete both the regular and 8.3 filenames versions of the database, + ** journal, wal and shm files. */ + for(i=0; rc==0 && izFmt, zFile, iChunk+p->iOffset); + if( p->b83 ) sqlite3Delete83Name(zBuf); + rc = sqlite3DeleteUnlinkIfExists(zBuf, &bExists); + if( bExists==0 || rc!=0 ) break; + } + } + + sqlite3_free(zBuf); + return (rc ? SQLITE_ERROR : SQLITE_OK); +} + + diff --git a/test/delete_db.test b/test/delete_db.test new file mode 100644 index 0000000000..520d4f94b3 --- /dev/null +++ b/test/delete_db.test @@ -0,0 +1,214 @@ +# 2016 September 10 +# +# 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 regression tests for SQLite library. The +# focus of this file is testing the DELETE FROM statement. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix delete_db + +proc delete_all {} { + foreach f [glob -nocomplain test2*] { file delete $f } + foreach f [glob -nocomplain test3*] { file delete $f } +} + +proc copydb {} { + foreach f [glob -nocomplain test3*] { file delete $f } + foreach f [glob -nocomplain test2*] { + set p [string range $f 5 end] + file copy "test2$p" "test3$p" + } +} + +proc files {} { + lsort [glob -nocomplain test3*] +} + +db close +delete_all +sqlite3 db test2.database + +#------------------------------------------------------------------------- +# +# 1.1: Journal files. +# 1.2: Wal files. +# 1.3: Multiplexor with journal file. +# 1.4: Multiplexor with wal file. +# +# 2.* are a copy of 1.* with the multiplexor enabled. +# +# 3.* tests errors. +# + +do_test 1.1.0 { + execsql { + CREATE TABLE t1(x, y); + BEGIN; + INSERT INTO t1 VALUES(1, 2); + } + copydb + files +} {test3.database test3.database-journal} + +do_test 1.1.1 { + sqlite3_delete_database test3.database + files +} {} + +do_test 1.2.0 { + execsql { + COMMIT; + PRAGMA journal_mode = wal; + INSERT INTO t1 VALUES(3, 4); + } + copydb + files +} {test3.database test3.database-shm test3.database-wal} +do_test 1.2.1 { + sqlite3_delete_database test3.database + files +} {} + +db close +delete_all +sqlite3_multiplex_initialize "" 0 +sqlite3 db test2.database -vfs multiplex +sqlite3_multiplex_control db "main" chunk_size 32768 + +do_test 1.3.0 { + execsql { + CREATE TABLE x1(a, b); + WITH s(i) AS ( VALUES(1) UNION ALL SELECT i+1 FROM s WHERE i<1000 ) + INSERT INTO x1 SELECT randomblob(100), randomblob(100) FROM s; + BEGIN; + UPDATE x1 SET a=randomblob(101) + } + copydb + files +} [list {*}{ + test3.database test3.database-journal test3.database001 + test3.database002 test3.database003 +}] +do_test 1.3.1 { + sqlite3_delete_database test3.database + files +} {} + + +do_test 1.4.0 { + execsql { + COMMIT; + PRAGMA journal_mode = wal; + UPDATE x1 SET a=randomblob(102) + } + copydb + files +} [list {*}{ + test3.database test3.database-shm test3.database-wal test3.database001 + test3.database002 test3.database003 +}] +do_test 1.4.1 { + sqlite3_delete_database test3.database + files +} {} + + +ifcapable 8_3_names { + db close + delete_all + sqlite3 db file:test2.db?8_3_names=1 -uri 1 + + do_test 2.1.0 { + execsql { + CREATE TABLE t1(x, y); + BEGIN; + INSERT INTO t1 VALUES(1, 2); + } + copydb + files + } {test3.db test3.nal} + + do_test 2.1.1 { + sqlite3_delete_database test3.db + files + } {} + + do_test 2.2.0 { + execsql { + COMMIT; + PRAGMA journal_mode = wal; + INSERT INTO t1 VALUES(3, 4); + } + copydb + files + } {test3.db test3.shm test3.wal} + do_test 2.2.1 { + sqlite3_delete_database test3.db + files + } {} + + + db close + delete_all + sqlite3_multiplex_initialize "" 0 + sqlite3 db file:test2.db?8_3_names=1 -uri 1 -vfs multiplex + sqlite3_multiplex_control db "main" chunk_size 32768 + + do_test 2.3.0 { + execsql { + CREATE TABLE x1(a, b); + WITH s(i) AS ( VALUES(1) UNION ALL SELECT i+1 FROM s WHERE i<1000 ) + INSERT INTO x1 SELECT randomblob(100), randomblob(100) FROM s; + BEGIN; + UPDATE x1 SET a=randomblob(101) + } + copydb + files + } [list {*}{ + test3.001 test3.002 test3.003 test3.db test3.nal + }] + do_test 2.3.1 { + sqlite3_delete_database test3.db + files + } {} + + + do_test 2.4.0 { + execsql { + COMMIT; + PRAGMA journal_mode = wal; + UPDATE x1 SET a=randomblob(102) + } + copydb + files + } [list {*}{ + test3.001 test3.002 test3.003 test3.db test3.db-shm test3.wal + }] + do_test 2.4.1 { + sqlite3_delete_database test3.db + files + } {} +} + +db close +delete_all +sqlite3_multiplex_shutdown + +do_test 3.0 { + file mkdir dir2.db + sqlite3_delete_database dir2.db +} {SQLITE_ERROR} +do_test 3.1 { + sqlite3_delete_database dir2.db/test.db +} {SQLITE_OK} + +finish_test From 27fe1c3fccb63e10c8aaeaa0720d64755d264803 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 9 Sep 2016 20:23:59 +0000 Subject: [PATCH 0817/1484] Remove an unnecessary call to sqlite3VdbeMemExpandBlob() when casting to text. FossilOrigin-Name: 19e2e5950541f1a93eed994cc2b1eaf64b68e858 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbemem.c | 5 +---- 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index e10c5a254b..9611891b26 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Performance\simprovements\sto\sthe\scomparison\soperators\sin\sthe\sbytecode\sengine. -D 2016-09-09T19:33:00.624 +C Remove\san\sunnecessary\scall\sto\ssqlite3VdbeMemExpandBlob()\swhen\scasting\sto\ntext. +D 2016-09-09T20:23:59.911 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5017381e4853b1472e01d5bb926be1268eba429c @@ -458,7 +458,7 @@ F src/vdbeInt.h c59381049af5c7751a83456c39b80d1a6fde1f9d F src/vdbeapi.c a32d61b7dd05e6890d8fd44d2805f55e2f5ba9f3 F src/vdbeaux.c 230b6826656144bcdca6d9c09d38da9d927739be F src/vdbeblob.c 3e82a797b60c3b9fed7b8de8c539ca7607874937 -F src/vdbemem.c e67dc6d8177fd1830efb5d15e17793408251a187 +F src/vdbemem.c 1f28b306cd3ea8c74c1783b1f112ee2b16ebff1f F src/vdbesort.c 91fda3909326860382b0ca8aa251e609c6a9d62c F src/vdbetrace.c 41963d5376f0349842b5fc4aaaaacd7d9cdc0834 F src/vtab.c e02cacb5c7ae742631edeb9ae9f53d399f093fd8 @@ -1523,7 +1523,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 6ac932c92a61cd68cc5b1816216e4748a5c7b3cd -R f1fdb6c44ee59a1a70f4ca210b22ee73 +P 37803b19d219f4107f29b240d5d314600e4bd236 +R db00fc0ef8aa68ef9774861c5c367c7d U drh -Z 14efbbb4d9b59bda04ac0672b03a8c5e +Z 32bad86ea2ad95fbb246e2b38f8691c3 diff --git a/manifest.uuid b/manifest.uuid index da37ec616c..3f54976cfd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -37803b19d219f4107f29b240d5d314600e4bd236 \ No newline at end of file +19e2e5950541f1a93eed994cc2b1eaf64b68e858 \ No newline at end of file diff --git a/src/vdbemem.c b/src/vdbemem.c index bc08042000..1a41ec0f1e 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -575,7 +575,7 @@ int sqlite3VdbeMemNumerify(Mem *pMem){ } } assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))!=0 ); - pMem->flags &= ~(MEM_Str|MEM_Blob); + pMem->flags &= ~(MEM_Str|MEM_Blob|MEM_Zero); return SQLITE_OK; } @@ -1018,9 +1018,6 @@ static SQLITE_NOINLINE const void *valueToText(sqlite3_value* pVal, u8 enc){ assert( (pVal->flags & (MEM_Null))==0 ); if( pVal->flags & (MEM_Blob|MEM_Str) ){ pVal->flags |= MEM_Str; - if( pVal->flags & MEM_Zero ){ - sqlite3VdbeMemExpandBlob(pVal); - } if( pVal->enc != (enc & ~SQLITE_UTF16_ALIGNED) ){ sqlite3VdbeChangeEncoding(pVal, enc & ~SQLITE_UTF16_ALIGNED); } From 35cd8b1eb513c505522580f14b7889a4e732383a Mon Sep 17 00:00:00 2001 From: mistachkin Date: Fri, 9 Sep 2016 20:26:27 +0000 Subject: [PATCH 0818/1484] Make the new file test_delete.c portable to MSVC on Windows. FossilOrigin-Name: 0e3ace39f234c204649ec69c6a69fb0e062c58f7 --- manifest | 17 +++++++---------- manifest.uuid | 2 +- src/test_delete.c | 10 +++++++--- 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index 8bece82eaf..2a8796474a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\snew\sfile\stest_delete.c,\scontaining\stest\scode\sfor\sdeleting\san\ssqlite\sdatabase. -D 2016-09-09T20:00:40.358 +C Make\sthe\snew\sfile\stest_delete.c\sportable\sto\sMSVC\son\sWindows. +D 2016-09-09T20:26:27.991 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e1aa788e84f926e42239ee167c53f785bedacacd @@ -412,7 +412,7 @@ F src/test_bestindex.c d23f80d334c59662af69191854c76b8d3d0c8c96 F src/test_blob.c a0f7ad49a0c9d4b72f693fe2a71c58d7e507174d F src/test_btree.c 8b2dc8b8848cf3a4db93f11578f075e82252a274 F src/test_config.c 4d3d4a886416f369771d69a6dba926866deda788 -F src/test_delete.c 3e7c7223fd78da017569aea5521696a2d203d2ba +F src/test_delete.c f4920c10d7208ac55ee03882de9709cf39a83fec F src/test_demovfs.c a0c3bdd45ed044115c2c9f7779e56eafff18741e F src/test_devsym.c 4e58dec2602d8e139ca08659f62a62450587cb58 F src/test_fs.c e16cbe68d3b107e00a907c20a9a02629870eb69b @@ -1525,10 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 6ac932c92a61cd68cc5b1816216e4748a5c7b3cd -R 49c1be8b151a3311317589c820143e41 -T *branch * test_delete -T *sym-test_delete * -T -sym-trunk * -U dan -Z b08ae969e8f18eb5dd37e3842872bc5d +P fb0b95e9405a3180d13c6318409af361e9df7632 +R 636d380fec130f84b51bc39cdc46924e +U mistachkin +Z 84ac5c96a27a266c4f9b67a83c54b319 diff --git a/manifest.uuid b/manifest.uuid index ad51945639..67ee1e922b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fb0b95e9405a3180d13c6318409af361e9df7632 \ No newline at end of file +0e3ace39f234c204649ec69c6a69fb0e062c58f7 \ No newline at end of file diff --git a/src/test_delete.c b/src/test_delete.c index 6d5c353dea..d82c022b75 100644 --- a/src/test_delete.c +++ b/src/test_delete.c @@ -19,8 +19,12 @@ ** above. */ - -#include +#if SQLITE_OS_WIN +# include +# define F_OK 0 +#else +# include +#endif #include #include #include "sqlite3.h" @@ -81,7 +85,7 @@ int sqlite3_delete_database( ){ char *zBuf; /* Buffer to sprintf() filenames to */ int nBuf; /* Size of buffer in bytes */ - int rc; /* System error code */ + int rc = 0; /* System error code */ int i; /* Iterate through azFmt[] and aMFile[] */ const char *azFmt[] = { "%s", "%s-journal", "%s-wal", "%s-shm" }; From 2eb22af03dfbf55703fa3ccaaa3001e3efbe4132 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 10 Sep 2016 19:51:40 +0000 Subject: [PATCH 0819/1484] Changes to give a warning-free build with SQLITE_OMIT_INCRBLOB and SQLITE_OMIT_SHARED_CACHE. FossilOrigin-Name: 711c59171b22df04224183a713e6c36e0bb3bba8 --- manifest | 23 +++++++++++------------ manifest.uuid | 2 +- src/btree.h | 4 ++++ src/tclsqlite.c | 13 ++++++++----- src/test3.c | 17 +++++++++++------ src/vdbe.c | 6 +++--- src/vdbemem.c | 2 +- 7 files changed, 39 insertions(+), 28 deletions(-) diff --git a/manifest b/manifest index 96cffd816b..695a399135 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\stest\scode\sto\sdelete\san\sSQLite\sdatabase\sand\sits\sauxiliary\sfiles. -D 2016-09-10T14:43:07.292 +C Changes\sto\sgive\sa\swarning-free\sbuild\swith\sSQLITE_OMIT_INCRBLOB\sand\nSQLITE_OMIT_SHARED_CACHE. +D 2016-09-10T19:51:40.868 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e1aa788e84f926e42239ee167c53f785bedacacd @@ -330,7 +330,7 @@ F src/backup.c 92c2e3b5fcb47626413717138617f4d32f08aea4 F src/bitvec.c 3ee4c8b2c94ed3a7377256e18199e6ff5cf33f63 F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 F src/btree.c 2551bd3ecb8b8988fb8b23aabadfb214dbc38e46 -F src/btree.h 075c45707c0f8f8af118f739f36df8098a08b7da +F src/btree.h d05b2fcc290991a8a3d9ea1816ddd55a4359dcde F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 F src/build.c c2ccfcdd99e18894a8750e215b8d9c5398a3c073 F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 @@ -395,10 +395,10 @@ F src/sqliteInt.h c9e010a79ab4ed7bdc910a24d8f08f3c6d5f822c F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 -F src/tclsqlite.c bdae822f21e229b6daced15938b6343ce44ef454 +F src/tclsqlite.c aef87dcd8cb66564d560ab48d43d19ac812a1eab F src/test1.c 61a08ed5861f3396ea4ff83931387696b692e1f8 F src/test2.c b7174313e993754303a8b33c43df7c44b46857ab -F src/test3.c 1339a40be39650ae83894b6578f971dc7f96ea8a +F src/test3.c d03f5b5da9a2410b7a91c64b0d3306ed28ab6fee F src/test4.c 18ec393bb4d0ad1de729f0b94da7267270f3d8e6 F src/test5.c 328aae2c010c57a9829d255dc099d6899311672d F src/test6.c 55aa2775c154415dcf4ed7cd1e19a193122b3a02 @@ -453,13 +453,13 @@ F src/update.c 8179e699dbd45b92934fd02d3d8e3732e8da8802 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 810ec3f22e2d1b62e66c30fe3621ebdedd23584d F src/vacuum.c 913970b9d86dd6c2b8063ef1af421880f1464ec3 -F src/vdbe.c 2087dfd6f013a9c808c92f8713fd8c7c62be2857 +F src/vdbe.c bac0b2ed0ceb7efcbfb1a3c0731937c23a5ddfc8 F src/vdbe.h 67bc551f7faf04c33493892e4b378aada823ed10 F src/vdbeInt.h c59381049af5c7751a83456c39b80d1a6fde1f9d F src/vdbeapi.c a32d61b7dd05e6890d8fd44d2805f55e2f5ba9f3 F src/vdbeaux.c 230b6826656144bcdca6d9c09d38da9d927739be F src/vdbeblob.c 3e82a797b60c3b9fed7b8de8c539ca7607874937 -F src/vdbemem.c 1f28b306cd3ea8c74c1783b1f112ee2b16ebff1f +F src/vdbemem.c 357caac1a404f37ee6087b17613f92107c13f733 F src/vdbesort.c 91fda3909326860382b0ca8aa251e609c6a9d62c F src/vdbetrace.c 41963d5376f0349842b5fc4aaaaacd7d9cdc0834 F src/vtab.c e02cacb5c7ae742631edeb9ae9f53d399f093fd8 @@ -1525,8 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 19e2e5950541f1a93eed994cc2b1eaf64b68e858 0e3ace39f234c204649ec69c6a69fb0e062c58f7 -R 024543a45b4f17dba023932165fefef1 -T +closed 0e3ace39f234c204649ec69c6a69fb0e062c58f7 -U dan -Z df256d05aba4cb5f3d126d4e91c30d89 +P 8a9d128119fde36c175735be56876d30e5c8586f +R 2ee1cf2f5a2187396df115af39b9bf82 +U drh +Z cef02d90fc649c97d5e20753bc980470 diff --git a/manifest.uuid b/manifest.uuid index b41408b0d3..5896145178 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8a9d128119fde36c175735be56876d30e5c8586f \ No newline at end of file +711c59171b22df04224183a713e6c36e0bb3bba8 \ No newline at end of file diff --git a/src/btree.h b/src/btree.h index b76e2ce214..0df98a3a64 100644 --- a/src/btree.h +++ b/src/btree.h @@ -90,7 +90,9 @@ int sqlite3BtreeIsInReadTrans(Btree*); int sqlite3BtreeIsInBackup(Btree*); void *sqlite3BtreeSchema(Btree *, int, void(*)(void *)); int sqlite3BtreeSchemaLocked(Btree *pBtree); +#ifndef SQLITE_OMIT_SHARED_CACHE int sqlite3BtreeLockTable(Btree *pBtree, int iTab, u8 isWriteLock); +#endif int sqlite3BtreeSavepoint(Btree *, int, int); const char *sqlite3BtreeGetFilename(Btree *); @@ -293,8 +295,10 @@ int sqlite3BtreeData(BtCursor*, u32 offset, u32 amt, void*); char *sqlite3BtreeIntegrityCheck(Btree*, int *aRoot, int nRoot, int, int*); struct Pager *sqlite3BtreePager(Btree*); +#ifndef SQLITE_OMIT_INCRBLOB int sqlite3BtreePutData(BtCursor*, u32 offset, u32 amt, void*); void sqlite3BtreeIncrblobCursor(BtCursor *); +#endif void sqlite3BtreeClearCursor(BtCursor *); int sqlite3BtreeSetVersion(Btree *pBt, int iVersion); int sqlite3BtreeCursorHasHint(BtCursor*, unsigned int mask); diff --git a/src/tclsqlite.c b/src/tclsqlite.c index 3db4a32c4d..b2f13bd5ed 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -590,7 +590,8 @@ static int DbProgressHandler(void *cd){ } #endif -#ifndef SQLITE_OMIT_TRACE +#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT) && \ + !defined(SQLITE_OMIT_DEPRECATED) /* ** This routine is called by the SQLite trace handler whenever a new ** block of SQL is executed. The TCL script in pDb->zTrace is executed. @@ -684,7 +685,8 @@ static int DbTraceV2Handler( } #endif -#ifndef SQLITE_OMIT_TRACE +#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT) && \ + !defined(SQLITE_OMIT_DEPRECATED) /* ** This routine is called by the SQLite profile handler after a statement ** SQL has executed. The TCL script in pDb->zProfile is evaluated. @@ -2747,7 +2749,8 @@ static int SQLITE_TCLAPI DbObjCmd( }else{ pDb->zProfile = 0; } -#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT) +#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT) && \ + !defined(SQLITE_OMIT_DEPRECATED) if( pDb->zProfile ){ pDb->interp = interp; sqlite3_profile(pDb->db, DbProfileHandler, pDb); @@ -2934,8 +2937,8 @@ static int SQLITE_TCLAPI DbObjCmd( }else{ pDb->zTrace = 0; } -#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT) \ - && !defined(SQLITE_OMIT_DEPRECATED) +#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT) && \ + !defined(SQLITE_OMIT_DEPRECATED) if( pDb->zTrace ){ pDb->interp = interp; sqlite3_trace(pDb->db, DbTraceHandler, pDb); diff --git a/src/test3.c b/src/test3.c index 6995684c29..6b4bfedbd9 100644 --- a/src/test3.c +++ b/src/test3.c @@ -253,7 +253,6 @@ static int SQLITE_TCLAPI btree_close_cursor( const char **argv /* Text of each argument */ ){ BtCursor *pCur; - Btree *pBt; int rc; if( argc!=2 ){ @@ -262,12 +261,18 @@ static int SQLITE_TCLAPI btree_close_cursor( return TCL_ERROR; } pCur = sqlite3TestTextToPtr(argv[1]); - pBt = pCur->pBtree; - sqlite3_mutex_enter(pBt->db->mutex); - sqlite3BtreeEnter(pBt); +#if SQLITE_THREADSAFE>0 + { + Btree *pBt = pCur->pBtree; + sqlite3_mutex_enter(pBt->db->mutex); + sqlite3BtreeEnter(pBt); + rc = sqlite3BtreeCloseCursor(pCur); + sqlite3BtreeLeave(pBt); + sqlite3_mutex_leave(pBt->db->mutex); + } +#else rc = sqlite3BtreeCloseCursor(pCur); - sqlite3BtreeLeave(pBt); - sqlite3_mutex_leave(pBt->db->mutex); +#endif ckfree((char *)pCur); if( rc ){ Tcl_AppendResult(interp, sqlite3ErrName(rc), 0); diff --git a/src/vdbe.c b/src/vdbe.c index 91ff5bc900..63b78697a7 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -3877,7 +3877,7 @@ case OP_SeekGT: { /* jump, in3 */ #ifdef SQLITE_DEBUG { int i; for(i=0; iuc.pCursor, &r, 0, 0, &res); if( rc!=SQLITE_OK ){ @@ -4020,7 +4020,7 @@ case OP_Found: { /* jump, in3 */ r.aMem = pIn3; for(ii=0; iip3+ii, &r.aMem[ii]); #endif @@ -4032,7 +4032,7 @@ case OP_Found: { /* jump, in3 */ ); if( pIdxKey==0 ) goto no_mem; assert( pIn3->flags & MEM_Blob ); - ExpandBlob(pIn3); + (void)ExpandBlob(pIn3); sqlite3VdbeRecordUnpack(pC->pKeyInfo, pIn3->n, pIn3->z, pIdxKey); } pIdxKey->default_rc = 0; diff --git a/src/vdbemem.c b/src/vdbemem.c index 1a41ec0f1e..ca6e480d13 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -192,7 +192,7 @@ int sqlite3VdbeMemMakeWriteable(Mem *pMem){ int f; assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); assert( (pMem->flags&MEM_RowSet)==0 ); - ExpandBlob(pMem); + (void)ExpandBlob(pMem); f = pMem->flags; if( (f&(MEM_Str|MEM_Blob)) && (pMem->szMalloc==0 || pMem->z!=pMem->zMalloc) ){ if( sqlite3VdbeMemGrow(pMem, pMem->n + 2, 1) ){ From d562ec277cc3fdffeb515b3a1b9d980ecf872e98 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 12 Sep 2016 09:28:21 +0000 Subject: [PATCH 0820/1484] Have releasetest.tcl delete all test files except for "testfixture", "testfixture.exe", "sqlite3", "sqlite3.exe", "test.log" and "test-out.txt" after each test run is finished. Passing the "--keep" option restores the old behaviour. FossilOrigin-Name: e0e042dca98f29c060f76db079afecb3200ffae5 --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/releasetest.tcl | 38 +++++++++++++++++++++++++++++++++++--- 3 files changed, 43 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 695a399135..937b016c05 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Changes\sto\sgive\sa\swarning-free\sbuild\swith\sSQLITE_OMIT_INCRBLOB\sand\nSQLITE_OMIT_SHARED_CACHE. -D 2016-09-10T19:51:40.868 +C Have\sreleasetest.tcl\sdelete\sall\stest\sfiles\sexcept\sfor\s"testfixture",\s"testfixture.exe",\s"sqlite3",\s"sqlite3.exe",\s"test.log"\sand\s"test-out.txt"\safter\seach\stest\srun\sis\sfinished.\sPassing\sthe\s"--keep"\soption\srestores\sthe\sold\sbehaviour. +D 2016-09-12T09:28:21.479 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e1aa788e84f926e42239ee167c53f785bedacacd @@ -1015,7 +1015,7 @@ F test/rdonly.test 64e2696c322e3538df0b1ed624e21f9a23ed9ff8 F test/regexp1.test 497ea812f264d12b6198d6e50a76be4a1973a9d8 F test/regexp2.test aa7ffcc21350007a78361b82bcf3b74d12227144 F test/reindex.test 44edd3966b474468b823d481eafef0c305022254 -F test/releasetest.tcl ce72fb81a76beb81dab4d83e20ada2d68a078361 x +F test/releasetest.tcl cb06c4df0de4872e65b178316f8a87ccf7624d59 x F test/resolver01.test f4022acafda7f4d40eca94dbf16bc5fc4ac30ceb F test/rollback.test 458fe73eb3ffdfdf9f6ba3e9b7350a6220414dea F test/rollback2.test 8435d6ff0f13f51d2a4181c232e706005fa90fc5 @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 8a9d128119fde36c175735be56876d30e5c8586f -R 2ee1cf2f5a2187396df115af39b9bf82 -U drh -Z cef02d90fc649c97d5e20753bc980470 +P 711c59171b22df04224183a713e6c36e0bb3bba8 +R 37a1645525cbcb2689722b270f6e3aaf +U dan +Z e67cc646551efb1e3646dc171a703649 diff --git a/manifest.uuid b/manifest.uuid index 5896145178..ac97cfec54 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -711c59171b22df04224183a713e6c36e0bb3bba8 \ No newline at end of file +e0e042dca98f29c060f76db079afecb3200ffae5 \ No newline at end of file diff --git a/test/releasetest.tcl b/test/releasetest.tcl index 82d695b038..99823e3b1c 100755 --- a/test/releasetest.tcl +++ b/test/releasetest.tcl @@ -15,6 +15,7 @@ optional) are: -f|--force (Run even if uncommitted changes) --info (Show diagnostic info) --jobs N (Use N processes - default 1) + --keep (Delete no files after each test run) --msvc (Use MSVC as the compiler) --platform PLATFORM (see below) --progress (Show progress messages) @@ -467,14 +468,15 @@ proc count_tests_and_errors {logfile rcVar errmsgVar} { proc run_slave_test {} { # Read global vars configuration from stdin. set V [gets stdin] - foreach {::TRACE ::MSVC ::DRYRUN} $V {} + foreach {::TRACE ::MSVC ::DRYRUN ::KEEPFILES} $V {} # Read the test-suite configuration from stdin. set T [gets stdin] foreach {title dir configOpts testtarget makeOpts cflags opts} $T {} # Create and switch to the test directory. - set ::env(SQLITE_TMPDIR) [file normalize $dir] + set normaldir [file normalize $dir] + set ::env(SQLITE_TMPDIR) $normaldir trace_cmd file mkdir $dir trace_cmd cd $dir catch {file delete core} @@ -498,6 +500,9 @@ proc run_slave_test {} { } } + # Clean up lots of extra files if --keep was not specified. + if {$::KEEPFILES==0} { cleanup $normaldir } + # Exis successfully if the test passed, or with a non-zero error code # otherwise. exit $rc @@ -597,7 +602,7 @@ proc run_all_test_suites {alltests} { set fd [open "|[info nameofexecutable] $script --slave" r+] fconfigure $fd -blocking 0 fileevent $fd readable [list slave_fileevent $fd $T $tm1] - puts $fd [list $::TRACE $::MSVC $::DRYRUN] + puts $fd [list $::TRACE $::MSVC $::DRYRUN $::KEEPFILES] puts $fd [list {*}$T] flush $fd } @@ -776,6 +781,7 @@ proc process_options {argv} { set ::PROGRESS_MSGS 0 set ::WITHTCL {} set ::FORCE 0 + set ::KEEPFILES 0 ;# Keep extra files after test run set config {} set platform $::tcl_platform(os)-$::tcl_platform(machine) @@ -874,6 +880,10 @@ proc process_options {argv} { lappend ::EXTRACONFIG [lindex $argv $i] } + -keep { + set ::KEEPFILES 1 + } + -with-tcl=* { set ::WITHTCL -$x } @@ -953,6 +963,28 @@ proc check_uncommitted {} { cd $pwd } +# A test run has just finished in directory $dir. This command deletes all +# non-essential files from the directory. Specifically, everything except +# +# * The "testfixture" and "sqlite3" binaries, +# * The "test-out.log" and "test.log" log files. +# +proc cleanup {dir} { + set K(testfixture) 1 + set K(testfixture.exe) 1 + set K(sqlite3) 1 + set K(sqlite3.exe) 1 + set K(test-out.txt) 1 + set K(test.log) 1 + + foreach f [glob -nocomplain [file join $dir *]] { + set tail [file tail $f] + if {[info exists K($tail)]==0} { + file delete -force $f + } + } +} + # Main routine. # From ff02e200c0f649607e49c3d74ae4d931986cb941 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 12 Sep 2016 13:32:37 +0000 Subject: [PATCH 0821/1484] Add missing "finish_test" command to vacuum5.test. FossilOrigin-Name: 02f40c3b934ba79f2d45eae3781f2bea0c69c95f --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/vacuum5.test | 2 ++ 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 937b016c05..958295dff4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Have\sreleasetest.tcl\sdelete\sall\stest\sfiles\sexcept\sfor\s"testfixture",\s"testfixture.exe",\s"sqlite3",\s"sqlite3.exe",\s"test.log"\sand\s"test-out.txt"\safter\seach\stest\srun\sis\sfinished.\sPassing\sthe\s"--keep"\soption\srestores\sthe\sold\sbehaviour. -D 2016-09-12T09:28:21.479 +C Add\smissing\s"finish_test"\scommand\sto\svacuum5.test. +D 2016-09-12T13:32:37.608 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e1aa788e84f926e42239ee167c53f785bedacacd @@ -1341,7 +1341,7 @@ F test/vacuum.test ce91c39f7f91a4273bf620efad21086b5aa6ef1d F test/vacuum2.test aa048abee196c16c9ba308465494009057b79f9b F test/vacuum3.test 77ecdd54592b45a0bcb133339f99f1ae0ae94d0d F test/vacuum4.test d3f8ecff345f166911568f397d2432c16d2867d9 -F test/vacuum5.test 99d4a0629252f9ef2fc642caefe92436a744db3a +F test/vacuum5.test d233412f76026a3ea2244aef36e5eb1bac15f8ad F test/vacuummem.test e53a3fdca4612a99c515e1afe7934728a2383764 F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102 F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661 @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 711c59171b22df04224183a713e6c36e0bb3bba8 -R 37a1645525cbcb2689722b270f6e3aaf +P e0e042dca98f29c060f76db079afecb3200ffae5 +R 8609acd55843aeec5673875597fa9b85 U dan -Z e67cc646551efb1e3646dc171a703649 +Z 45148f2e6cf322dfee572c56eb21852c diff --git a/manifest.uuid b/manifest.uuid index ac97cfec54..5ada040e4c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e0e042dca98f29c060f76db079afecb3200ffae5 \ No newline at end of file +02f40c3b934ba79f2d45eae3781f2bea0c69c95f \ No newline at end of file diff --git a/test/vacuum5.test b/test/vacuum5.test index 4a5aecc796..6d28686107 100644 --- a/test/vacuum5.test +++ b/test/vacuum5.test @@ -109,3 +109,5 @@ do_execsql_test vacuum5-1.4.2 { do_catchsql_test vacuum5-2.0 { VACUUM olaf; } {1 {unknown database olaf}} + +finish_test From 12c56aa452588ca3a8efc2321fe9c15853bc5850 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 12 Sep 2016 14:23:51 +0000 Subject: [PATCH 0822/1484] Fix a bug in sqldiff causing it to confuse blobs zero bytes in size with NULL values. FossilOrigin-Name: 264e9c75875796cad773d39b775d4604546bc57a --- ext/rbu/rbudiff.test | 9 +++++++++ manifest | 14 +++++++------- manifest.uuid | 2 +- tool/sqldiff.c | 3 ++- 4 files changed, 19 insertions(+), 9 deletions(-) diff --git a/ext/rbu/rbudiff.test b/ext/rbu/rbudiff.test index 4a32009230..6f6af82804 100644 --- a/ext/rbu/rbudiff.test +++ b/ext/rbu/rbudiff.test @@ -149,6 +149,15 @@ foreach {tn init mod} { INSERT INTO x1 VALUES('a', 'b', 'c'); } + 5 { + CREATE TABLE t1(a PRIMARY KEY, b); + INSERT INTO t1 VALUES(1, NULL); + INSERT INTO t1 VALUES(2, X''); + } { + UPDATE t1 SET b = X'' WHERE a=1; + UPDATE t1 SET b = NULL WHERE a=2; + } + } { catch { db close } diff --git a/manifest b/manifest index 958295dff4..1dd36aff2d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\smissing\s"finish_test"\scommand\sto\svacuum5.test. -D 2016-09-12T13:32:37.608 +C Fix\sa\sbug\sin\ssqldiff\scausing\sit\sto\sconfuse\sblobs\szero\sbytes\sin\ssize\swith\sNULL\svalues. +D 2016-09-12T14:23:51.714 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e1aa788e84f926e42239ee167c53f785bedacacd @@ -246,7 +246,7 @@ F ext/rbu/rbuB.test c25bc325b8072a766e56bb76c001866b405925c2 F ext/rbu/rbuC.test efe47db508a0269b683cb2a1913a425ffd39a831 F ext/rbu/rbu_common.tcl a38e8e2d4a50fd6aaf151633714c1b1d2fae3ead F ext/rbu/rbucrash.test 8d2ed5d4b05fef6c00c2a6b5f7ead71fa172a695 -F ext/rbu/rbudiff.test d099b56b073a737cfe1b8e9f67b77940130719cb +F ext/rbu/rbudiff.test 3e605cf624d00d04d0fb1316a3acec4fbe3b3ac5 F ext/rbu/rbufault.test cc0be8d5d392d98b0c2d6a51be377ea989250a89 F ext/rbu/rbufault2.test 9a7f19edd6ea35c4c9f807d8a3db0a03a5670c06 F ext/rbu/rbufault3.test 54a399888ac4af44c68f9f58afbed23149428bca @@ -1492,7 +1492,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 7ce07da76b5e745783e703a834417d725b7d45fd F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c -F tool/sqldiff.c 7f567367d87fdb493e3e65169569a10d9f330c3f +F tool/sqldiff.c 3fb48a6c6669d2d2c59a7f072a410dd2583579b4 F tool/srcck1.c 371de5363b70154012955544f86fdee8f6e5326f F tool/stack_usage.tcl f8e71b92cdb099a147dad572375595eae55eca43 F tool/symbols-mingw.sh 4dbcea7e74768305384c9fd2ed2b41bbf9f0414d @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e0e042dca98f29c060f76db079afecb3200ffae5 -R 8609acd55843aeec5673875597fa9b85 +P 02f40c3b934ba79f2d45eae3781f2bea0c69c95f +R e0ea306c3e0718c77bd18c92a1e2cd7b U dan -Z 45148f2e6cf322dfee572c56eb21852c +Z a9d272d3a5fd3dd4a60c313976b5c5f7 diff --git a/manifest.uuid b/manifest.uuid index 5ada040e4c..b915e902d6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -02f40c3b934ba79f2d45eae3781f2bea0c69c95f \ No newline at end of file +264e9c75875796cad773d39b775d4604546bc57a \ No newline at end of file diff --git a/tool/sqldiff.c b/tool/sqldiff.c index cbb57e7774..67f3197bbf 100644 --- a/tool/sqldiff.c +++ b/tool/sqldiff.c @@ -403,7 +403,8 @@ static void printQuoted(FILE *out, sqlite3_value *X){ } fprintf(out, "'"); }else{ - fprintf(out, "NULL"); + /* Could be an OOM, could be a zero-byte blob */ + fprintf(out, "X''"); } break; } From 481fd50cb47e439987011af5ed300537997183ac Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 14 Sep 2016 18:56:20 +0000 Subject: [PATCH 0823/1484] Update comments used to generate API documentation to include the new "[dateof:3.X.Y]" notation for dates of release where appropriate. No changes to code. FossilOrigin-Name: 55f7f8ee5b1c13aa219198b7ae66f59b3730f4c3 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/sqlite.h.in | 21 ++++++++++++++------- 3 files changed, 22 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index 1dd36aff2d..0b8a9e1e0f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sbug\sin\ssqldiff\scausing\sit\sto\sconfuse\sblobs\szero\sbytes\sin\ssize\swith\sNULL\svalues. -D 2016-09-12T14:23:51.714 +C Update\scomments\sused\sto\sgenerate\sAPI\sdocumentation\sto\sinclude\sthe\snew\n"[dateof:3.X.Y]"\snotation\sfor\sdates\sof\srelease\swhere\sappropriate.\nNo\schanges\sto\scode. +D 2016-09-14T18:56:20.941 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e1aa788e84f926e42239ee167c53f785bedacacd @@ -388,7 +388,7 @@ F src/resolve.c 24f40fd0c3475821d1ad762a3f2c3455cc839b42 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c 244f9cc5e4662987cd2ef5c22d1b7027560f3425 F src/shell.c de7c7e98846cacbfbe062cbd98bca899dfb720e3 -F src/sqlite.h.in 4a030e254e204570444b34bf7d40fb4a5416089e +F src/sqlite.h.in 2584a78ee1809028bfa570a06a3dbaeafead441e F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae F src/sqliteInt.h c9e010a79ab4ed7bdc910a24d8f08f3c6d5f822c @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 02f40c3b934ba79f2d45eae3781f2bea0c69c95f -R e0ea306c3e0718c77bd18c92a1e2cd7b -U dan -Z a9d272d3a5fd3dd4a60c313976b5c5f7 +P 264e9c75875796cad773d39b775d4604546bc57a +R b1e3f8232eee350db0410c710888dff8 +U drh +Z 087f0415d92b6ff31fb36e89ba19e93b diff --git a/manifest.uuid b/manifest.uuid index b915e902d6..581082a381 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -264e9c75875796cad773d39b775d4604546bc57a \ No newline at end of file +55f7f8ee5b1c13aa219198b7ae66f59b3730f4c3 \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 73c908272d..73cba9d521 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -108,7 +108,8 @@ extern "C" { ** be held constant and Z will be incremented or else Y will be incremented ** and Z will be reset to zero. ** -** Since version 3.6.18, SQLite source code has been stored in the +** Since [version 3.6.18] ([dateof:3.6.18]), +** SQLite source code has been stored in the ** Fossil configuration management ** system. ^The SQLITE_SOURCE_ID macro evaluates to ** a string which identifies a particular check-in of SQLite @@ -452,7 +453,8 @@ int sqlite3_exec( ** [result codes]. However, experience has shown that many of ** these result codes are too coarse-grained. They do not provide as ** much information about problems as programmers might like. In an effort to -** address this, newer versions of SQLite (version 3.3.8 and later) include +** address this, newer versions of SQLite (version 3.3.8 [dateof:3.3.8] +** and later) include ** support for additional result codes that provide more detailed information ** about errors. These [extended result codes] are enabled or disabled ** on a per database connection basis using the @@ -4051,7 +4053,8 @@ const void *sqlite3_column_decltype16(sqlite3_stmt*,int); ** other than [SQLITE_ROW] before any subsequent invocation of ** sqlite3_step(). Failure to reset the prepared statement using ** [sqlite3_reset()] would result in an [SQLITE_MISUSE] return from -** sqlite3_step(). But after version 3.6.23.1, sqlite3_step() began +** sqlite3_step(). But after [version 3.6.23.1] ([dateof:3.6.23.1], +** sqlite3_step() began ** calling [sqlite3_reset()] automatically in this circumstance rather ** than returning [SQLITE_MISUSE]. This is not considered a compatibility ** break because any application that ever receives an SQLITE_MISUSE error @@ -5414,7 +5417,8 @@ void *sqlite3_update_hook( ** and disabled if the argument is false.)^ ** ** ^Cache sharing is enabled and disabled for an entire process. -** This is a change as of SQLite version 3.5.0. In prior versions of SQLite, +** This is a change as of SQLite [version 3.5.0] ([dateof:3.5.0]). +** In prior versions of SQLite, ** sharing was enabled or disabled for each thread separately. ** ** ^(The cache sharing mode set by this interface effects all subsequent @@ -5508,7 +5512,8 @@ int sqlite3_db_release_memory(sqlite3*); ** from the heap. ** )^ ** -** Beginning with SQLite version 3.7.3, the soft heap limit is enforced +** Beginning with SQLite [version 3.7.3] ([dateof:3.7.3]), +** the soft heap limit is enforced ** regardless of whether or not the [SQLITE_ENABLE_MEMORY_MANAGEMENT] ** compile-time option is invoked. With [SQLITE_ENABLE_MEMORY_MANAGEMENT], ** the soft heap limit is enforced on every memory allocation. Without @@ -5902,13 +5907,15 @@ struct sqlite3_module { ** the xUpdate method are automatically rolled back by SQLite. ** ** IMPORTANT: The estimatedRows field was added to the sqlite3_index_info -** structure for SQLite version 3.8.2. If a virtual table extension is +** structure for SQLite [version 3.8.2] ([dateof:3.8.2]). +** If a virtual table extension is ** used with an SQLite version earlier than 3.8.2, the results of attempting ** to read or write the estimatedRows field are undefined (but are likely ** to included crashing the application). The estimatedRows field should ** therefore only be used if [sqlite3_libversion_number()] returns a ** value greater than or equal to 3008002. Similarly, the idxFlags field -** was added for version 3.9.0. It may therefore only be used if +** was added for [version 3.9.0] ([dateof:3.9.0]). +** It may therefore only be used if ** sqlite3_libversion_number() returns a value greater than or equal to ** 3009000. */ From 5f6eb1a0dc0b8b6813a977e142778ccfd3a2fbc4 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 15 Sep 2016 00:04:46 +0000 Subject: [PATCH 0824/1484] Optimization to vdbeRecordCompareInt() makes it slightly smaller and faster. FossilOrigin-Name: 5a2a7712cb8e0b686942dfab4e9e67b5ea7b2be3 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbeaux.c | 3 ++- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 0b8a9e1e0f..16cb06510b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\scomments\sused\sto\sgenerate\sAPI\sdocumentation\sto\sinclude\sthe\snew\n"[dateof:3.X.Y]"\snotation\sfor\sdates\sof\srelease\swhere\sappropriate.\nNo\schanges\sto\scode. -D 2016-09-14T18:56:20.941 +C Optimization\sto\svdbeRecordCompareInt()\smakes\sit\sslightly\ssmaller\sand\sfaster. +D 2016-09-15T00:04:46.412 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e1aa788e84f926e42239ee167c53f785bedacacd @@ -457,7 +457,7 @@ F src/vdbe.c bac0b2ed0ceb7efcbfb1a3c0731937c23a5ddfc8 F src/vdbe.h 67bc551f7faf04c33493892e4b378aada823ed10 F src/vdbeInt.h c59381049af5c7751a83456c39b80d1a6fde1f9d F src/vdbeapi.c a32d61b7dd05e6890d8fd44d2805f55e2f5ba9f3 -F src/vdbeaux.c 230b6826656144bcdca6d9c09d38da9d927739be +F src/vdbeaux.c 4fbd4f523cb1777b9f9def8bb95741bc2a23df15 F src/vdbeblob.c 3e82a797b60c3b9fed7b8de8c539ca7607874937 F src/vdbemem.c 357caac1a404f37ee6087b17613f92107c13f733 F src/vdbesort.c 91fda3909326860382b0ca8aa251e609c6a9d62c @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 264e9c75875796cad773d39b775d4604546bc57a -R b1e3f8232eee350db0410c710888dff8 +P 55f7f8ee5b1c13aa219198b7ae66f59b3730f4c3 +R 099c616727c5eff5ff55b94090783a15 U drh -Z 087f0415d92b6ff31fb36e89ba19e93b +Z e0ac7cade838dc53109b734ea49fc780 diff --git a/manifest.uuid b/manifest.uuid index 581082a381..73dc00155b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -55f7f8ee5b1c13aa219198b7ae66f59b3730f4c3 \ No newline at end of file +5a2a7712cb8e0b686942dfab4e9e67b5ea7b2be3 \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 710ce84b97..c74e5c63f4 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -4143,7 +4143,7 @@ static int vdbeRecordCompareInt( int res; u32 y; u64 x; - i64 v = pPKey2->aMem[0].u.i; + i64 v; i64 lhs; vdbeAssertFieldCountWithinLimits(nKey1, pKey1, pPKey2->pKeyInfo); @@ -4202,6 +4202,7 @@ static int vdbeRecordCompareInt( return sqlite3VdbeRecordCompare(nKey1, pKey1, pPKey2); } + v = pPKey2->aMem[0].u.i; if( v>lhs ){ res = pPKey2->r1; }else if( v Date: Thu, 15 Sep 2016 00:32:42 +0000 Subject: [PATCH 0825/1484] Slight size reduction and performance increase in sqlite3VdbeHalt(). FossilOrigin-Name: 5990a1bdb4a0734ff23015ada71cf02d0cb1381f --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbeaux.c | 4 +++- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 16cb06510b..b24bad5c70 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Optimization\sto\svdbeRecordCompareInt()\smakes\sit\sslightly\ssmaller\sand\sfaster. -D 2016-09-15T00:04:46.412 +C Slight\ssize\sreduction\sand\sperformance\sincrease\sin\ssqlite3VdbeHalt(). +D 2016-09-15T00:32:42.176 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e1aa788e84f926e42239ee167c53f785bedacacd @@ -457,7 +457,7 @@ F src/vdbe.c bac0b2ed0ceb7efcbfb1a3c0731937c23a5ddfc8 F src/vdbe.h 67bc551f7faf04c33493892e4b378aada823ed10 F src/vdbeInt.h c59381049af5c7751a83456c39b80d1a6fde1f9d F src/vdbeapi.c a32d61b7dd05e6890d8fd44d2805f55e2f5ba9f3 -F src/vdbeaux.c 4fbd4f523cb1777b9f9def8bb95741bc2a23df15 +F src/vdbeaux.c 12831f89de66a23d575d129dc1bda543a09a80c7 F src/vdbeblob.c 3e82a797b60c3b9fed7b8de8c539ca7607874937 F src/vdbemem.c 357caac1a404f37ee6087b17613f92107c13f733 F src/vdbesort.c 91fda3909326860382b0ca8aa251e609c6a9d62c @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 55f7f8ee5b1c13aa219198b7ae66f59b3730f4c3 -R 099c616727c5eff5ff55b94090783a15 +P 5a2a7712cb8e0b686942dfab4e9e67b5ea7b2be3 +R c4d626707db93f22b9a341ed091c5be2 U drh -Z e0ac7cade838dc53109b734ea49fc780 +Z 45d9e586cdaa671f37537b02e0dbe0f4 diff --git a/manifest.uuid b/manifest.uuid index 73dc00155b..3cc2208344 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5a2a7712cb8e0b686942dfab4e9e67b5ea7b2be3 \ No newline at end of file +5990a1bdb4a0734ff23015ada71cf02d0cb1381f \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index c74e5c63f4..56f00efcfd 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -2569,10 +2569,12 @@ int sqlite3VdbeHalt(Vdbe *p){ ** one, or the complete transaction if there is no statement transaction. */ + assert( p->aOnceFlag!=0 || db->mallocFailed ); if( db->mallocFailed ){ p->rc = SQLITE_NOMEM_BKPT; + }else{ + memset(p->aOnceFlag, 0, p->nOnceFlag); } - if( p->aOnceFlag ) memset(p->aOnceFlag, 0, p->nOnceFlag); closeAllCursors(p); if( p->magic!=VDBE_MAGIC_RUN ){ return SQLITE_OK; From 95489c58f7f65f53c3ce5a8e9c35a9e1d65da53d Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 15 Sep 2016 05:47:00 +0000 Subject: [PATCH 0826/1484] Fix a typo in a comment in sqlite.h.in. No changes to code. FossilOrigin-Name: 12df7152109ffce4b3e0ee233c5ea8103edb902a --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/sqlite.h.in | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index b24bad5c70..40edf4512a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Slight\ssize\sreduction\sand\sperformance\sincrease\sin\ssqlite3VdbeHalt(). -D 2016-09-15T00:32:42.176 +C Fix\sa\stypo\sin\sa\scomment\sin\ssqlite.h.in.\sNo\schanges\sto\scode. +D 2016-09-15T05:47:00.658 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e1aa788e84f926e42239ee167c53f785bedacacd @@ -388,7 +388,7 @@ F src/resolve.c 24f40fd0c3475821d1ad762a3f2c3455cc839b42 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c 244f9cc5e4662987cd2ef5c22d1b7027560f3425 F src/shell.c de7c7e98846cacbfbe062cbd98bca899dfb720e3 -F src/sqlite.h.in 2584a78ee1809028bfa570a06a3dbaeafead441e +F src/sqlite.h.in 46ed821aeed0ba45559fb15597d9a400083154a2 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae F src/sqliteInt.h c9e010a79ab4ed7bdc910a24d8f08f3c6d5f822c @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 5a2a7712cb8e0b686942dfab4e9e67b5ea7b2be3 -R c4d626707db93f22b9a341ed091c5be2 -U drh -Z 45d9e586cdaa671f37537b02e0dbe0f4 +P 5990a1bdb4a0734ff23015ada71cf02d0cb1381f +R b4583e048ef3b20a2bc8fdee50fd352e +U dan +Z 612771189b9f1d70deeb6e8a6f7394ca diff --git a/manifest.uuid b/manifest.uuid index 3cc2208344..27bca0b9ff 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5990a1bdb4a0734ff23015ada71cf02d0cb1381f \ No newline at end of file +12df7152109ffce4b3e0ee233c5ea8103edb902a \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 73cba9d521..52b58370dd 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -6613,7 +6613,7 @@ int sqlite3_mutex_notheld(sqlite3_mutex*); #define SQLITE_MUTEX_STATIC_MEM 3 /* sqlite3_malloc() */ #define SQLITE_MUTEX_STATIC_MEM2 4 /* NOT USED */ #define SQLITE_MUTEX_STATIC_OPEN 4 /* sqlite3BtreeOpen() */ -#define SQLITE_MUTEX_STATIC_PRNG 5 /* sqlite3_random() */ +#define SQLITE_MUTEX_STATIC_PRNG 5 /* sqlite3_randomness() */ #define SQLITE_MUTEX_STATIC_LRU 6 /* lru page list */ #define SQLITE_MUTEX_STATIC_LRU2 7 /* NOT USED */ #define SQLITE_MUTEX_STATIC_PMEM 7 /* sqlite3PageMalloc() */ From 21e19b44f0f999da21ff7f8c9be8223efe0d926e Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 15 Sep 2016 14:54:51 +0000 Subject: [PATCH 0827/1484] Remove no-op code (adding an assert() to prove that the code was no-op) in the text affinity logic of the bytecode engine comparison operators. FossilOrigin-Name: b9f5bdbf40ac6382e48f09ebcd53cc908e065527 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/vdbe.c | 3 +-- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 40edf4512a..c7c8aefbf6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\stypo\sin\sa\scomment\sin\ssqlite.h.in.\sNo\schanges\sto\scode. -D 2016-09-15T05:47:00.658 +C Remove\sno-op\scode\s(adding\san\sassert()\sto\sprove\sthat\sthe\scode\swas\sno-op)\nin\sthe\stext\saffinity\slogic\sof\sthe\sbytecode\sengine\scomparison\soperators. +D 2016-09-15T14:54:51.441 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e1aa788e84f926e42239ee167c53f785bedacacd @@ -453,7 +453,7 @@ F src/update.c 8179e699dbd45b92934fd02d3d8e3732e8da8802 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 810ec3f22e2d1b62e66c30fe3621ebdedd23584d F src/vacuum.c 913970b9d86dd6c2b8063ef1af421880f1464ec3 -F src/vdbe.c bac0b2ed0ceb7efcbfb1a3c0731937c23a5ddfc8 +F src/vdbe.c 31a17090bf658c1e6ba4e58f7a08e8ce4c2e7d7f F src/vdbe.h 67bc551f7faf04c33493892e4b378aada823ed10 F src/vdbeInt.h c59381049af5c7751a83456c39b80d1a6fde1f9d F src/vdbeapi.c a32d61b7dd05e6890d8fd44d2805f55e2f5ba9f3 @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 5990a1bdb4a0734ff23015ada71cf02d0cb1381f -R b4583e048ef3b20a2bc8fdee50fd352e -U dan -Z 612771189b9f1d70deeb6e8a6f7394ca +P 12df7152109ffce4b3e0ee233c5ea8103edb902a +R 6b884a026aa6fc5e3121f8fd54dbd58f +U drh +Z a5246499f87a7576d63b6cd54f036979 diff --git a/manifest.uuid b/manifest.uuid index 27bca0b9ff..6179fb4208 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -12df7152109ffce4b3e0ee233c5ea8103edb902a \ No newline at end of file +b9f5bdbf40ac6382e48f09ebcd53cc908e065527 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 63b78697a7..552da6fd96 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2057,8 +2057,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ sqlite3VdbeMemStringify(pIn1, encoding, 1); testcase( (flags1&MEM_Dyn) != (pIn1->flags&MEM_Dyn) ); flags1 = (pIn1->flags & ~MEM_TypeMask) | (flags1 & MEM_TypeMask); - testcase( flags3!=pIn3->flags ); /* Possible if pIn1==pIn3 */ - flags3 = pIn3->flags; + assert( pIn1!=pIn3 ); } if( (flags3 & MEM_Str)==0 && (flags3 & (MEM_Int|MEM_Real))!=0 ){ testcase( pIn3->flags & MEM_Int ); From 98365be030d46d010361954f56ccc1fb108a2dc2 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 15 Sep 2016 19:15:19 +0000 Subject: [PATCH 0828/1484] Omit the sqlite3Apis constant object when compiling with SQLITE_OMIT_LOAD_EXTENSION, since it is not used. FossilOrigin-Name: 7b10461370828b9c57acaaaea518031d53986fa3 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/loadext.c | 20 +++++++------------- 3 files changed, 14 insertions(+), 20 deletions(-) diff --git a/manifest b/manifest index c7c8aefbf6..2adb407a89 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sno-op\scode\s(adding\san\sassert()\sto\sprove\sthat\sthe\scode\swas\sno-op)\nin\sthe\stext\saffinity\slogic\sof\sthe\sbytecode\sengine\scomparison\soperators. -D 2016-09-15T14:54:51.441 +C Omit\sthe\ssqlite3Apis\sconstant\sobject\swhen\scompiling\swith\nSQLITE_OMIT_LOAD_EXTENSION,\ssince\sit\sis\snot\sused. +D 2016-09-15T19:15:19.226 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e1aa788e84f926e42239ee167c53f785bedacacd @@ -350,7 +350,7 @@ F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 F src/insert.c 3edb5a1bda44df13531fedfcde5fbcc2fc04c222 F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e -F src/loadext.c dd7a2b77902cc66c22555aef02e1a682554b7aec +F src/loadext.c 5d6642d141c07d366e43d359e94ec9de47add41d F src/main.c 9821bb4d2399bc5a0b8a5dfc06bede2d1520255c F src/malloc.c 1443d1ad95d67c21d77af7ae3f44678252f0efec F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 12df7152109ffce4b3e0ee233c5ea8103edb902a -R 6b884a026aa6fc5e3121f8fd54dbd58f +P b9f5bdbf40ac6382e48f09ebcd53cc908e065527 +R 1e31cb38dfd2c7bbbb492df3fcbfb729 U drh -Z a5246499f87a7576d63b6cd54f036979 +Z 8ce374e092d6c15d6e5f3b801f1063a4 diff --git a/manifest.uuid b/manifest.uuid index 6179fb4208..7241c19155 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b9f5bdbf40ac6382e48f09ebcd53cc908e065527 \ No newline at end of file +7b10461370828b9c57acaaaea518031d53986fa3 \ No newline at end of file diff --git a/src/loadext.c b/src/loadext.c index 9feabbd045..6011fd2bf8 100644 --- a/src/loadext.c +++ b/src/loadext.c @@ -620,18 +620,7 @@ int sqlite3_enable_load_extension(sqlite3 *db, int onoff){ return SQLITE_OK; } -#endif /* SQLITE_OMIT_LOAD_EXTENSION */ - -/* -** The auto-extension code added regardless of whether or not extension -** loading is supported. We need a dummy sqlite3Apis pointer for that -** code if regular extension loading is not available. This is that -** dummy pointer. -*/ -#ifdef SQLITE_OMIT_LOAD_EXTENSION -static const sqlite3_api_routines sqlite3Apis = { 0 }; -#endif - +#endif /* !defined(SQLITE_OMIT_LOAD_EXTENSION) */ /* ** The following object holds the list of automatically loaded @@ -775,6 +764,11 @@ void sqlite3AutoLoadExtensions(sqlite3 *db){ char *zErrmsg; #if SQLITE_THREADSAFE sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); +#endif +#ifdef SQLITE_OMIT_LOAD_EXTENSION + const sqlite3_api_routines *pThunk = 0; +#else + const sqlite3_api_routines *pThunk = &sqlite3Apis; #endif sqlite3_mutex_enter(mutex); if( i>=wsdAutoext.nExt ){ @@ -785,7 +779,7 @@ void sqlite3AutoLoadExtensions(sqlite3 *db){ } sqlite3_mutex_leave(mutex); zErrmsg = 0; - if( xInit && (rc = xInit(db, &zErrmsg, &sqlite3Apis))!=0 ){ + if( xInit && (rc = xInit(db, &zErrmsg, pThunk))!=0 ){ sqlite3ErrorWithMsg(db, rc, "automatic extension loading failed: %s", zErrmsg); go = 0; From 2db8211526f3af3e6ef96aa1482c931472375638 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 15 Sep 2016 21:35:24 +0000 Subject: [PATCH 0829/1484] Add the ".testcase" and ".check" dot-commands in the shell, when compiled using SQLITE_DEBUG. FossilOrigin-Name: 62289f27ee276090a855982bd8216a465e7d0a27 --- manifest | 12 ++-- manifest.uuid | 2 +- src/shell.c | 181 ++++++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 174 insertions(+), 21 deletions(-) diff --git a/manifest b/manifest index 2adb407a89..2812980f69 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Omit\sthe\ssqlite3Apis\sconstant\sobject\swhen\scompiling\swith\nSQLITE_OMIT_LOAD_EXTENSION,\ssince\sit\sis\snot\sused. -D 2016-09-15T19:15:19.226 +C Add\sthe\s".testcase"\sand\s".check"\sdot-commands\sin\sthe\sshell,\swhen\scompiled\nusing\sSQLITE_DEBUG. +D 2016-09-15T21:35:24.532 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e1aa788e84f926e42239ee167c53f785bedacacd @@ -387,7 +387,7 @@ F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c 24f40fd0c3475821d1ad762a3f2c3455cc839b42 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c 244f9cc5e4662987cd2ef5c22d1b7027560f3425 -F src/shell.c de7c7e98846cacbfbe062cbd98bca899dfb720e3 +F src/shell.c 89a3adbfcaac17070372ce631161bbbf21ec2010 F src/sqlite.h.in 46ed821aeed0ba45559fb15597d9a400083154a2 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b9f5bdbf40ac6382e48f09ebcd53cc908e065527 -R 1e31cb38dfd2c7bbbb492df3fcbfb729 +P 7b10461370828b9c57acaaaea518031d53986fa3 +R 1d8691a695a03272769e683d2ed4d0b4 U drh -Z 8ce374e092d6c15d6e5f3b801f1063a4 +Z 15bb0e2011d42f4d3abf5a593439e046 diff --git a/manifest.uuid b/manifest.uuid index 7241c19155..d6648be1c2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7b10461370828b9c57acaaaea518031d53986fa3 \ No newline at end of file +62289f27ee276090a855982bd8216a465e7d0a27 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 21cba66b1c..2991e7c13f 100644 --- a/src/shell.c +++ b/src/shell.c @@ -2136,6 +2136,9 @@ static char zHelp[] = ".bail on|off Stop after hitting an error. Default OFF\n" ".binary on|off Turn binary output on or off. Default OFF\n" ".changes on|off Show number of rows changed by SQL\n" +#ifdef SQLITE_DEBUG + ".check GLOB Fail if output since .testcase does not match\n" +#endif ".clone NEWDB Clone data into NEWDB from the existing database\n" ".databases List names and files of attached databases\n" ".dbinfo ?DB? Show status information about the database\n" @@ -2196,6 +2199,9 @@ static char zHelp[] = ".tables ?TABLE? List names of tables\n" " If TABLE specified, only list tables matching\n" " LIKE pattern TABLE.\n" +#ifdef SQLITE_DEBUG + ".testcase Begin redirecting output to 'testcase-out.txt'\n" +#endif ".timeout MS Try opening locked tables for MS milliseconds\n" ".timer on|off Turn SQL timer on or off\n" ".trace FILE|off Output each SQL statement as it is run\n" @@ -2232,6 +2238,31 @@ void session_help(ShellState *p){ /* Forward reference */ static int process_input(ShellState *p, FILE *in); + + +/* +** Read the content of a file into memory obtained from sqlite3_malloc64(). +** The caller is responsible for freeing the memory. +** +** NULL is returned if any error is encountered. +*/ +static char *readFile(const char *zName){ + FILE *in = fopen(zName, "rb"); + long nIn; + char *pBuf; + if( in==0 ) return 0; + fseek(in, 0, SEEK_END); + nIn = ftell(in); + rewind(in); + pBuf = sqlite3_malloc64( nIn ); + if( pBuf==0 ) return 0; + if( 1!=fread(pBuf, nIn, 1, in) ){ + sqlite3_free(pBuf); + return 0; + } + return pBuf; +} + /* ** Implementation of the "readfile(X)" SQL function. The entire content ** of the file named X is read and returned as a BLOB. NULL is returned @@ -2243,25 +2274,13 @@ static void readfileFunc( sqlite3_value **argv ){ const char *zName; - FILE *in; - long nIn; void *pBuf; UNUSED_PARAMETER(argc); zName = (const char*)sqlite3_value_text(argv[0]); if( zName==0 ) return; - in = fopen(zName, "rb"); - if( in==0 ) return; - fseek(in, 0, SEEK_END); - nIn = ftell(in); - rewind(in); - pBuf = sqlite3_malloc64( nIn ); - if( pBuf && 1==fread(pBuf, nIn, 1, in) ){ - sqlite3_result_blob(context, pBuf, nIn, sqlite3_free); - }else{ - sqlite3_free(pBuf); - } - fclose(in); + pBuf = readFile(zName); + if( pBuf ) sqlite3_result_blob(context, pBuf, -1, sqlite3_free); } /* @@ -3063,6 +3082,106 @@ static int shellNomemError(void){ return 1; } +#ifdef SQLITE_DEBUG +/* +** Compare the pattern in zGlob[] against the text in z[]. Return TRUE +** if they match and FALSE (0) if they do not match. +** +** Globbing rules: +** +** '*' Matches any sequence of zero or more characters. +** +** '?' Matches exactly one character. +** +** [...] Matches one character from the enclosed list of +** characters. +** +** [^...] Matches one character not in the enclosed list. +** +** '#' Matches any sequence of one or more digits with an +** optional + or - sign in front +** +** ' ' Any span of whitespace matches any other span of +** whitespace. +** +** Extra whitespace at the end of z[] is ignored. +*/ +static int testcase_glob(const char *zGlob, const char *z){ + int c, c2; + int invert; + int seen; + + while( (c = (*(zGlob++)))!=0 ){ + if( IsSpace(c) ){ + if( !IsSpace(*z) ) return 0; + while( IsSpace(*zGlob) ) zGlob++; + while( IsSpace(*z) ) z++; + }else if( c=='*' ){ + while( (c=(*(zGlob++))) == '*' || c=='?' ){ + if( c=='?' && (*(z++))==0 ) return 0; + } + if( c==0 ){ + return 1; + }else if( c=='[' ){ + while( *z && testcase_glob(zGlob-1,z)==0 ){ + z++; + } + return (*z)!=0; + } + while( (c2 = (*(z++)))!=0 ){ + while( c2!=c ){ + c2 = *(z++); + if( c2==0 ) return 0; + } + if( testcase_glob(zGlob,z) ) return 1; + } + return 0; + }else if( c=='?' ){ + if( (*(z++))==0 ) return 0; + }else if( c=='[' ){ + int prior_c = 0; + seen = 0; + invert = 0; + c = *(z++); + if( c==0 ) return 0; + c2 = *(zGlob++); + if( c2=='^' ){ + invert = 1; + c2 = *(zGlob++); + } + if( c2==']' ){ + if( c==']' ) seen = 1; + c2 = *(zGlob++); + } + while( c2 && c2!=']' ){ + if( c2=='-' && zGlob[0]!=']' && zGlob[0]!=0 && prior_c>0 ){ + c2 = *(zGlob++); + if( c>=prior_c && c<=c2 ) seen = 1; + prior_c = 0; + }else{ + if( c==c2 ){ + seen = 1; + } + prior_c = c2; + } + c2 = *(zGlob++); + } + if( c2==0 || (seen ^ invert)==0 ) return 0; + }else if( c=='#' ){ + if( (z[0]=='-' || z[0]=='+') && IsDigit(z[1]) ) z++; + if( !IsDigit(z[0]) ) return 0; + z++; + while( IsDigit(z[0]) ){ z++; } + }else{ + if( c!=(*(z++)) ) return 0; + } + } + while( IsSpace(*z) ){ z++; } + return *z==0; +} +#endif /* defined(SQLITE_DEBUG) */ + + /* ** Compare the string as a command-line option with either one or two ** initial "-" characters. @@ -3225,6 +3344,29 @@ static int do_meta_command(char *zLine, ShellState *p){ } }else +#ifdef SQLITE_DEBUG + /* Cancel output redirection, if it is currently set (by .testcase) + ** Then read the content of the testcase-out.txt file and compare against + ** azArg[1]. If there are differences, report an error and exit. + */ + if( c=='c' && n>=3 && strncmp(azArg[0], "check", n)==0 ){ + char *zRes = 0; + output_reset(p); + if( nArg!=2 ){ + raw_printf(stderr, "Usage: .check GLOB-PATTERN\n"); + rc = 1; + }else if( (zRes = readFile("testcase-out.txt"))==0 ){ + raw_printf(stderr, "Error: cannot read 'testcase-out.txt'\n"); + rc = 2; + }else if( testcase_glob(azArg[1],zRes)==0 ){ + raw_printf(stderr, ".check failed\n Expected: [%s]\n Got: [%s]\n", + azArg[1], zRes); + rc = 2; + } + sqlite3_free(zRes); + }else +#endif + if( c=='c' && strncmp(azArg[0], "clone", n)==0 ){ if( nArg==2 ){ tryToClone(p, azArg[1]); @@ -4495,6 +4637,17 @@ static int do_meta_command(char *zLine, ShellState *p){ sqlite3_free(azResult); }else +#ifdef SQLITE_DEBUG + /* Begin redirecting output to the file "testcase-out.txt" */ + if( c=='t' && strcmp(azArg[0],"testcase")==0 ){ + output_reset(p); + p->out = output_file_open("testcase-out.txt"); + if( p->out==0 ){ + utf8_printf(stderr, "Error: cannot open 'testcase-out.txt'\n"); + } + }else +#endif + if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){ static const struct { const char *zCtrlName; /* Name of a test-control option */ From cd0509e2562bf34f506aead29200bac7ae1bbf2f Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 16 Sep 2016 00:26:08 +0000 Subject: [PATCH 0830/1484] In the command-line shell, add the --new option to the ".open" command. Also, report the current database filename as part of the ".show" command. FossilOrigin-Name: 8e5c92039128a430e0509f4f06ea80ba39c35bda --- manifest | 12 +++++----- manifest.uuid | 2 +- src/shell.c | 63 ++++++++++++++++++++++++++++++++++++++------------- 3 files changed, 54 insertions(+), 23 deletions(-) diff --git a/manifest b/manifest index 2812980f69..d7517fc830 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\s".testcase"\sand\s".check"\sdot-commands\sin\sthe\sshell,\swhen\scompiled\nusing\sSQLITE_DEBUG. -D 2016-09-15T21:35:24.532 +C In\sthe\scommand-line\sshell,\sadd\sthe\s--new\soption\sto\sthe\s".open"\scommand.\nAlso,\sreport\sthe\scurrent\sdatabase\sfilename\sas\spart\sof\sthe\s".show"\scommand. +D 2016-09-16T00:26:08.684 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e1aa788e84f926e42239ee167c53f785bedacacd @@ -387,7 +387,7 @@ F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c 24f40fd0c3475821d1ad762a3f2c3455cc839b42 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c 244f9cc5e4662987cd2ef5c22d1b7027560f3425 -F src/shell.c 89a3adbfcaac17070372ce631161bbbf21ec2010 +F src/shell.c 1de20c816872f5443a104bdae238ff142e887f9e F src/sqlite.h.in 46ed821aeed0ba45559fb15597d9a400083154a2 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 7b10461370828b9c57acaaaea518031d53986fa3 -R 1d8691a695a03272769e683d2ed4d0b4 +P 62289f27ee276090a855982bd8216a465e7d0a27 +R d4e2f1f820d6f2b9a8e052f36c44661c U drh -Z 15bb0e2011d42f4d3abf5a593439e046 +Z d98a4b3e23d9525e29325cc221e2ffa0 diff --git a/manifest.uuid b/manifest.uuid index d6648be1c2..1013449e87 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -62289f27ee276090a855982bd8216a465e7d0a27 \ No newline at end of file +8e5c92039128a430e0509f4f06ea80ba39c35bda \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 2991e7c13f..6c9bf7cd32 100644 --- a/src/shell.c +++ b/src/shell.c @@ -2176,7 +2176,8 @@ static char zHelp[] = " tcl TCL list elements\n" ".nullvalue STRING Use STRING in place of NULL values\n" ".once FILENAME Output for the next SQL command only to FILENAME\n" - ".open ?FILENAME? Close existing database and reopen FILENAME\n" + ".open ?-new? ?FILE? Close existing database and reopen FILE\n" + " The --new starts with an empty file\n" ".output ?FILENAME? Send output to FILENAME or stdout\n" ".print STRING... Print literal STRING\n" ".prompt MAIN CONTINUE Replace the standard prompts\n" @@ -3193,6 +3194,21 @@ static int optionMatch(const char *zStr, const char *zOpt){ return strcmp(zStr, zOpt)==0; } +/* +** Delete a file. +*/ +int shellDeleteFile(const char *zFilename){ + int rc; +#ifdef _WIN32 + wchar_t *z = sqlite3_utf8_to_path(zFilename, 0); + rc = _wunlink(z); + sqlite3_free(z); +#else + rc = unlink(zFilename); +#endif + return rc; +} + /* ** If an input line begins with "." then invoke this routine to ** process that line. @@ -3975,22 +3991,35 @@ static int do_meta_command(char *zLine, ShellState *p){ }else if( c=='o' && strncmp(azArg[0], "open", n)==0 && n>=2 ){ - sqlite3 *savedDb = p->db; - const char *zSavedFilename = p->zDbFilename; - char *zNewFilename = 0; + char *zNewFilename; /* Name of the database file to open */ + int iName = 1; /* Index in azArg[] of the filename */ + /* Close the existing database */ + session_close_all(p); + sqlite3_close(p->db); p->db = 0; - if( nArg>=2 ) zNewFilename = sqlite3_mprintf("%s", azArg[1]); - p->zDbFilename = zNewFilename; - open_db(p, 1); - if( p->db!=0 ){ - session_close_all(p); - sqlite3_close(savedDb); - sqlite3_free(p->zFreeOnClose); - p->zFreeOnClose = zNewFilename; - }else{ - sqlite3_free(zNewFilename); - p->db = savedDb; - p->zDbFilename = zSavedFilename; + sqlite3_free(p->zFreeOnClose); + p->zFreeOnClose = 0; + /* Start a new database file if the --new flag is present */ + if( nArg>2 && optionMatch(azArg[1],"new") ){ + iName++; + if( nArg>iName ) shellDeleteFile(azArg[iName]); + } + /* If a filename is specified, try to open it first */ + zNewFilename = nArg>iName ? sqlite3_mprintf("%s", azArg[iName]) : 0; + if( zNewFilename ){ + p->zDbFilename = zNewFilename; + open_db(p, 1); + if( p->db==0 ){ + utf8_printf(stderr, "Error: cannot open '%s'\n", zNewFilename); + sqlite3_free(zNewFilename); + }else{ + p->zFreeOnClose = zNewFilename; + } + } + if( p->db==0 ){ + /* As a fall-back open a TEMP database */ + p->zDbFilename = 0; + open_db(p, 0); } }else @@ -4520,6 +4549,8 @@ static int do_meta_command(char *zLine, ShellState *p){ raw_printf(p->out, "%d ", p->colWidth[i]); } raw_printf(p->out, "\n"); + utf8_printf(p->out, "%12.12s: %s\n", "filename", + p->zDbFilename ? p->zDbFilename : ""); }else if( c=='s' && strncmp(azArg[0], "stats", n)==0 ){ From 760c8162fffd53f660adf4b3cdaf7aee7070d845 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 16 Sep 2016 02:52:22 +0000 Subject: [PATCH 0831/1484] In the shell, make ".testcase" and ".check" available in all configurations, not just SQLITE_DEBUG. All testcases to be named. Show the result of each testcase on stdout. FossilOrigin-Name: 792afefa9c750910082fd102f1ccd10309759dfc --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/shell.c | 42 ++++++++++++++++++++++++++---------------- 3 files changed, 33 insertions(+), 23 deletions(-) diff --git a/manifest b/manifest index d7517fc830..2ce97c3919 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\sthe\scommand-line\sshell,\sadd\sthe\s--new\soption\sto\sthe\s".open"\scommand.\nAlso,\sreport\sthe\scurrent\sdatabase\sfilename\sas\spart\sof\sthe\s".show"\scommand. -D 2016-09-16T00:26:08.684 +C In\sthe\sshell,\smake\s".testcase"\sand\s".check"\savailable\sin\sall\sconfigurations,\nnot\sjust\sSQLITE_DEBUG.\s\sAll\stestcases\sto\sbe\snamed.\s\sShow\sthe\sresult\sof\seach\ntestcase\son\sstdout. +D 2016-09-16T02:52:22.198 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e1aa788e84f926e42239ee167c53f785bedacacd @@ -387,7 +387,7 @@ F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c 24f40fd0c3475821d1ad762a3f2c3455cc839b42 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c 244f9cc5e4662987cd2ef5c22d1b7027560f3425 -F src/shell.c 1de20c816872f5443a104bdae238ff142e887f9e +F src/shell.c 2c558e83e0961de364570182c0ff26395d7aaba0 F src/sqlite.h.in 46ed821aeed0ba45559fb15597d9a400083154a2 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 62289f27ee276090a855982bd8216a465e7d0a27 -R d4e2f1f820d6f2b9a8e052f36c44661c +P 8e5c92039128a430e0509f4f06ea80ba39c35bda +R 46d709a281b0ceda3453ac789078f257 U drh -Z d98a4b3e23d9525e29325cc221e2ffa0 +Z 03a0324123b8a87d967c8d29c327e230 diff --git a/manifest.uuid b/manifest.uuid index 1013449e87..354fefec67 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8e5c92039128a430e0509f4f06ea80ba39c35bda \ No newline at end of file +792afefa9c750910082fd102f1ccd10309759dfc \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 6c9bf7cd32..e1a4089bb0 100644 --- a/src/shell.c +++ b/src/shell.c @@ -626,8 +626,10 @@ struct ShellState { int normalMode; /* Output mode before ".explain on" */ int writableSchema; /* True if PRAGMA writable_schema=ON */ int showHeader; /* True to show column names in List or Column mode */ + int nCheck; /* Number of ".check" commands run */ unsigned shellFlgs; /* Various flags */ char *zDestTable; /* Name of destination table when MODE_Insert */ + char zTestcase[30]; /* Name of current test case */ char colSeparator[20]; /* Column separator character for several modes */ char rowSeparator[20]; /* Row separator character for MODE_Ascii */ int colWidth[100]; /* Requested width of each column when in column mode*/ @@ -2136,9 +2138,7 @@ static char zHelp[] = ".bail on|off Stop after hitting an error. Default OFF\n" ".binary on|off Turn binary output on or off. Default OFF\n" ".changes on|off Show number of rows changed by SQL\n" -#ifdef SQLITE_DEBUG ".check GLOB Fail if output since .testcase does not match\n" -#endif ".clone NEWDB Clone data into NEWDB from the existing database\n" ".databases List names and files of attached databases\n" ".dbinfo ?DB? Show status information about the database\n" @@ -2200,9 +2200,7 @@ static char zHelp[] = ".tables ?TABLE? List names of tables\n" " If TABLE specified, only list tables matching\n" " LIKE pattern TABLE.\n" -#ifdef SQLITE_DEBUG - ".testcase Begin redirecting output to 'testcase-out.txt'\n" -#endif + ".testcase NAME Begin redirecting output to 'testcase-out.txt'\n" ".timeout MS Try opening locked tables for MS milliseconds\n" ".timer on|off Turn SQL timer on or off\n" ".trace FILE|off Output each SQL statement as it is run\n" @@ -3360,7 +3358,6 @@ static int do_meta_command(char *zLine, ShellState *p){ } }else -#ifdef SQLITE_DEBUG /* Cancel output redirection, if it is currently set (by .testcase) ** Then read the content of the testcase-out.txt file and compare against ** azArg[1]. If there are differences, report an error and exit. @@ -3370,18 +3367,21 @@ static int do_meta_command(char *zLine, ShellState *p){ output_reset(p); if( nArg!=2 ){ raw_printf(stderr, "Usage: .check GLOB-PATTERN\n"); - rc = 1; + rc = 2; }else if( (zRes = readFile("testcase-out.txt"))==0 ){ raw_printf(stderr, "Error: cannot read 'testcase-out.txt'\n"); rc = 2; }else if( testcase_glob(azArg[1],zRes)==0 ){ - raw_printf(stderr, ".check failed\n Expected: [%s]\n Got: [%s]\n", - azArg[1], zRes); + raw_printf(stderr, + "testcase-%s FAILED\n Expected: [%s]\n Got: [%s]\n", + p->zTestcase, azArg[1], zRes); rc = 2; + }else{ + raw_printf(stdout, "testcase-%s ok\n", p->zTestcase); + p->nCheck++; } sqlite3_free(zRes); }else -#endif if( c=='c' && strncmp(azArg[0], "clone", n)==0 ){ if( nArg==2 ){ @@ -3993,20 +3993,27 @@ static int do_meta_command(char *zLine, ShellState *p){ if( c=='o' && strncmp(azArg[0], "open", n)==0 && n>=2 ){ char *zNewFilename; /* Name of the database file to open */ int iName = 1; /* Index in azArg[] of the filename */ + int newFlag = 0; /* True to delete file before opening */ /* Close the existing database */ session_close_all(p); sqlite3_close(p->db); p->db = 0; sqlite3_free(p->zFreeOnClose); p->zFreeOnClose = 0; - /* Start a new database file if the --new flag is present */ - if( nArg>2 && optionMatch(azArg[1],"new") ){ - iName++; - if( nArg>iName ) shellDeleteFile(azArg[iName]); + /* Check for command-line arguments */ + for(iName=1; iNameiName ? sqlite3_mprintf("%s", azArg[iName]) : 0; if( zNewFilename ){ + if( newFlag ) shellDeleteFile(zNewFilename); p->zDbFilename = zNewFilename; open_db(p, 1); if( p->db==0 ){ @@ -4668,7 +4675,6 @@ static int do_meta_command(char *zLine, ShellState *p){ sqlite3_free(azResult); }else -#ifdef SQLITE_DEBUG /* Begin redirecting output to the file "testcase-out.txt" */ if( c=='t' && strcmp(azArg[0],"testcase")==0 ){ output_reset(p); @@ -4676,8 +4682,12 @@ static int do_meta_command(char *zLine, ShellState *p){ if( p->out==0 ){ utf8_printf(stderr, "Error: cannot open 'testcase-out.txt'\n"); } + if( nArg>=2 ){ + sqlite3_snprintf(sizeof(p->zTestcase), p->zTestcase, "%s", azArg[1]); + }else{ + sqlite3_snprintf(sizeof(p->zTestcase), p->zTestcase, "?"); + } }else -#endif if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){ static const struct { From a0daa751f85d7150e8fe4b143253d6f771204d46 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 16 Sep 2016 11:53:10 +0000 Subject: [PATCH 0832/1484] Fix SQLITE_OMIT_AUTHORIZATION so that it compiles cleanly. FossilOrigin-Name: a3e3b3e1c57178ccd38fc7375ec1de8e8ae45372 --- manifest | 22 +++++++++++----------- manifest.uuid | 2 +- src/build.c | 2 ++ src/delete.c | 5 ++--- src/insert.c | 7 ++----- src/resolve.c | 19 ++++++++++--------- src/shell.c | 6 ++++++ src/trigger.c | 3 +-- 8 files changed, 35 insertions(+), 31 deletions(-) diff --git a/manifest b/manifest index 2ce97c3919..65e8cf72c6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\sthe\sshell,\smake\s".testcase"\sand\s".check"\savailable\sin\sall\sconfigurations,\nnot\sjust\sSQLITE_DEBUG.\s\sAll\stestcases\sto\sbe\snamed.\s\sShow\sthe\sresult\sof\seach\ntestcase\son\sstdout. -D 2016-09-16T02:52:22.198 +C Fix\sSQLITE_OMIT_AUTHORIZATION\sso\sthat\sit\scompiles\scleanly. +D 2016-09-16T11:53:10.715 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e1aa788e84f926e42239ee167c53f785bedacacd @@ -332,13 +332,13 @@ F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 F src/btree.c 2551bd3ecb8b8988fb8b23aabadfb214dbc38e46 F src/btree.h d05b2fcc290991a8a3d9ea1816ddd55a4359dcde F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 -F src/build.c c2ccfcdd99e18894a8750e215b8d9c5398a3c073 +F src/build.c 7438b6dae3022818100a79ebbad707b5c65f9344 F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7 F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d -F src/delete.c 76c084f0265f4a3cd1ecf17eee112a94f1ccbc05 +F src/delete.c e91a11e0e86a13ce1917ca5ad7cf14c37ba31e59 F src/expr.c c1de78269522de39f6ad877ab0810a5d48f91f34 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c e2be0968c1adc679c87e467aa5b4f167588f38a8 @@ -348,7 +348,7 @@ F src/hash.c 55b5fb474100cee0b901edaf203e26c970940f36 F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4 F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 -F src/insert.c 3edb5a1bda44df13531fedfcde5fbcc2fc04c222 +F src/insert.c 427e96ff168b6b187a52c3d06b9f9e41f6ffb212 F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e F src/loadext.c 5d6642d141c07d366e43d359e94ec9de47add41d F src/main.c 9821bb4d2399bc5a0b8a5dfc06bede2d1520255c @@ -384,10 +384,10 @@ F src/pragma.h 64c78a648751b9f4f297276c4eb7507b14b4628c F src/prepare.c 0fcf16eaacc90c1059055519a76b75b516a59a88 F src/printf.c a5f0ca08ddede803c241266abb46356ec748ded1 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 -F src/resolve.c 24f40fd0c3475821d1ad762a3f2c3455cc839b42 +F src/resolve.c 3c3cf0dc719cd2a32ab5c1e10c26481dd565492e F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c 244f9cc5e4662987cd2ef5c22d1b7027560f3425 -F src/shell.c 2c558e83e0961de364570182c0ff26395d7aaba0 +F src/shell.c ae7058efb5084b4b9576dc5485bb3d2870b1974a F src/sqlite.h.in 46ed821aeed0ba45559fb15597d9a400083154a2 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae @@ -448,7 +448,7 @@ F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c 78c8085bc7af1922aa687f0f4bbd716821330de5 F src/treeview.c f51b75a28b377adde9f79bc3deb6c7770bcf97c0 -F src/trigger.c 11e20b3b12c847b3b9055594c0f1631266bb53fc +F src/trigger.c cae81f6c65c4977bc2cbd27d43bfee478710853c F src/update.c 8179e699dbd45b92934fd02d3d8e3732e8da8802 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 810ec3f22e2d1b62e66c30fe3621ebdedd23584d @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 8e5c92039128a430e0509f4f06ea80ba39c35bda -R 46d709a281b0ceda3453ac789078f257 +P 792afefa9c750910082fd102f1ccd10309759dfc +R 8c1833647015caee904c1e0d3421d795 U drh -Z 03a0324123b8a87d967c8d29c327e230 +Z 8c6311e2ea32e5d653d9fa56ba1b62fa diff --git a/manifest.uuid b/manifest.uuid index 354fefec67..ff2403cfc1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -792afefa9c750910082fd102f1ccd10309759dfc \ No newline at end of file +a3e3b3e1c57178ccd38fc7375ec1de8e8ae45372 \ No newline at end of file diff --git a/src/build.c b/src/build.c index ca4802cd0a..3384e6db85 100644 --- a/src/build.c +++ b/src/build.c @@ -2141,7 +2141,9 @@ int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ int nErr = 0; /* Number of errors encountered */ int n; /* Temporarily holds the number of cursors assigned */ sqlite3 *db = pParse->db; /* Database connection for malloc errors */ +#ifndef SQLITE_OMIT_AUTHORIZATION sqlite3_xauth xAuth; /* Saved xAuth pointer */ +#endif assert( pTable ); diff --git a/src/delete.c b/src/delete.c index 3d9360e925..74ffd584a1 100644 --- a/src/delete.c +++ b/src/delete.c @@ -212,7 +212,6 @@ void sqlite3DeleteFrom( ){ Vdbe *v; /* The virtual database engine */ Table *pTab; /* The table from which records will be deleted */ - const char *zDb; /* Name of database holding pTab */ int i; /* Loop counter */ WhereInfo *pWInfo; /* Information about the WHERE clause */ Index *pIdx; /* For looping over indices of the table */ @@ -289,8 +288,8 @@ void sqlite3DeleteFrom( } iDb = sqlite3SchemaToIndex(db, pTab->pSchema); assert( iDbnDb ); - zDb = db->aDb[iDb].zDbSName; - rcauth = sqlite3AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, zDb); + rcauth = sqlite3AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, + db->aDb[iDb].zDbSName); assert( rcauth==SQLITE_OK || rcauth==SQLITE_DENY || rcauth==SQLITE_IGNORE ); if( rcauth==SQLITE_DENY ){ goto delete_from_cleanup; diff --git a/src/insert.c b/src/insert.c index f7dec3ca24..9525d823b0 100644 --- a/src/insert.c +++ b/src/insert.c @@ -485,7 +485,6 @@ void sqlite3Insert( sqlite3 *db; /* The main database structure */ Table *pTab; /* The table to insert into. aka TABLE */ char *zTab; /* Name of the table into which we are inserting */ - const char *zDb; /* Name of the database holding this table */ int i, j, idx; /* Loop counters */ Vdbe *v; /* Generate code into this virtual machine */ Index *pIdx; /* For looping over indices of the table */ @@ -500,7 +499,6 @@ void sqlite3Insert( int addrCont = 0; /* Top of insert loop. Label "C" in templates 3 and 4 */ SelectDest dest; /* Destination for SELECT on rhs of INSERT */ int iDb; /* Index of database holding TABLE */ - Db *pDb; /* The database containing table being inserted into */ u8 useTempTable = 0; /* Store SELECT results in intermediate table */ u8 appendFlag = 0; /* True if the insert is likely to be an append */ u8 withoutRowid; /* 0 for normal table. 1 for WITHOUT ROWID table */ @@ -550,9 +548,8 @@ void sqlite3Insert( } iDb = sqlite3SchemaToIndex(db, pTab->pSchema); assert( iDbnDb ); - pDb = &db->aDb[iDb]; - zDb = pDb->zDbSName; - if( sqlite3AuthCheck(pParse, SQLITE_INSERT, pTab->zName, 0, zDb) ){ + if( sqlite3AuthCheck(pParse, SQLITE_INSERT, pTab->zName, 0, + db->aDb[iDb].zDbSName) ){ goto insert_cleanup; } withoutRowid = !HasRowid(pTab); diff --git a/src/resolve.c b/src/resolve.c index a5cc06b919..2171533ef3 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -646,7 +646,6 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ int no_such_func = 0; /* True if no such function exists */ int wrong_num_args = 0; /* True if wrong number of arguments */ int is_agg = 0; /* True if is an aggregate function */ - int auth; /* Authorization to use the function */ int nId; /* Number of characters in function name */ const char *zId; /* The function name. */ FuncDef *pDef; /* Information about the function */ @@ -690,15 +689,17 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ } } #ifndef SQLITE_OMIT_AUTHORIZATION - auth = sqlite3AuthCheck(pParse, SQLITE_FUNCTION, 0, pDef->zName, 0); - if( auth!=SQLITE_OK ){ - if( auth==SQLITE_DENY ){ - sqlite3ErrorMsg(pParse, "not authorized to use function: %s", - pDef->zName); - pNC->nErr++; + { + int auth = sqlite3AuthCheck(pParse, SQLITE_FUNCTION, 0,pDef->zName,0); + if( auth!=SQLITE_OK ){ + if( auth==SQLITE_DENY ){ + sqlite3ErrorMsg(pParse, "not authorized to use function: %s", + pDef->zName); + pNC->nErr++; + } + pExpr->op = TK_NULL; + return WRC_Prune; } - pExpr->op = TK_NULL; - return WRC_Prune; } #endif if( pDef->funcFlags & (SQLITE_FUNC_CONSTANT|SQLITE_FUNC_SLOCHNG) ){ diff --git a/src/shell.c b/src/shell.c index e1a4089bb0..9b5030bb39 100644 --- a/src/shell.c +++ b/src/shell.c @@ -896,6 +896,7 @@ static void interrupt_handler(int NotUsed){ } #endif +#ifndef SQLITE_OMIT_AUTHORIZATION /* ** When the ".auth ON" is set, the following authorizer callback is ** invoked. It always returns SQLITE_OK. @@ -940,6 +941,7 @@ static int shellAuth( raw_printf(p->out, "\n"); return SQLITE_OK; } +#endif /* @@ -2133,7 +2135,9 @@ static int run_schema_dump_query( ** Text of a help message */ static char zHelp[] = +#ifndef SQLITE_OMIT_AUTHORIZATION ".auth ON|OFF Show authorizer callbacks\n" +#endif ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n" ".bail on|off Stop after hitting an error. Default OFF\n" ".binary on|off Turn binary output on or off. Default OFF\n" @@ -3250,6 +3254,7 @@ static int do_meta_command(char *zLine, ShellState *p){ n = strlen30(azArg[0]); c = azArg[0][0]; +#ifndef SQLITE_OMIT_AUTHORIZATION if( c=='a' && strncmp(azArg[0], "auth", n)==0 ){ if( nArg!=2 ){ raw_printf(stderr, "Usage: .auth ON|OFF\n"); @@ -3263,6 +3268,7 @@ static int do_meta_command(char *zLine, ShellState *p){ sqlite3_set_authorizer(p->db, 0, 0); } }else +#endif if( (c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0) || (c=='s' && n>=3 && strncmp(azArg[0], "save", n)==0) diff --git a/src/trigger.c b/src/trigger.c index a1c16dd354..5c80560114 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -96,7 +96,6 @@ void sqlite3BeginTrigger( int iDb; /* The database to store the trigger in */ Token *pName; /* The unqualified db name */ DbFixer sFix; /* State vector for the DB fixer */ - int iTabDb; /* Index of the database holding pTab */ assert( pName1!=0 ); /* pName1->z might be NULL, but not pName1 itself */ assert( pName2!=0 ); @@ -209,10 +208,10 @@ void sqlite3BeginTrigger( " trigger on table: %S", pTableName, 0); goto trigger_cleanup; } - iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema); #ifndef SQLITE_OMIT_AUTHORIZATION { + int iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema); int code = SQLITE_CREATE_TRIGGER; const char *zDb = db->aDb[iTabDb].zDbSName; const char *zDbTrig = isTemp ? db->aDb[1].zDbSName : zDb; From 4313f045c2a473dcd5cee1adc4475db1a2181bfc Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 16 Sep 2016 14:50:38 +0000 Subject: [PATCH 0833/1484] Add WHERETRACE macros showing every entry and exit from whereLoopAddBtreeIndex(). FossilOrigin-Name: e7653decdcee161d379ced40aa1b27246337b000 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/where.c | 4 ++++ 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 65e8cf72c6..1049290a29 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sSQLITE_OMIT_AUTHORIZATION\sso\sthat\sit\scompiles\scleanly. -D 2016-09-16T11:53:10.715 +C Add\sWHERETRACE\smacros\sshowing\severy\sentry\sand\sexit\sfrom\nwhereLoopAddBtreeIndex(). +D 2016-09-16T14:50:38.605 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e1aa788e84f926e42239ee167c53f785bedacacd @@ -467,7 +467,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 02eeecc265f6ffd0597378f5d8ae9070b62a406a F src/wal.h 6dd221ed384afdc204bc61e25c23ef7fd5a511f2 F src/walker.c 2d2cc7fb0f320f7f415215d7247f3c584141ac09 -F src/where.c edbd73a87ba2e186928e9bfc14348b1bbb2628c5 +F src/where.c d0ca1b5e1c56249e7725cea66ce4e172c5845dec F src/whereInt.h 14dd243e13b81cbb0a66063d38b70f93a7d6e613 F src/wherecode.c d172dcf99932ba698dd304edc9a368cd52b4b2e5 F src/whereexpr.c e3db778ed205e982f31960896db71c50612ae009 @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 792afefa9c750910082fd102f1ccd10309759dfc -R 8c1833647015caee904c1e0d3421d795 +P a3e3b3e1c57178ccd38fc7375ec1de8e8ae45372 +R e3303608d5424eda671e1d828f84ecf6 U drh -Z 8c6311e2ea32e5d653d9fa56ba1b62fa +Z cc222b0997065c7a36fcdb84d3a6e5ff diff --git a/manifest.uuid b/manifest.uuid index ff2403cfc1..c069927d03 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a3e3b3e1c57178ccd38fc7375ec1de8e8ae45372 \ No newline at end of file +e7653decdcee161d379ced40aa1b27246337b000 \ No newline at end of file diff --git a/src/where.c b/src/where.c index 1785107244..527698320f 100644 --- a/src/where.c +++ b/src/where.c @@ -2322,6 +2322,8 @@ static int whereLoopAddBtreeIndex( pNew = pBuilder->pNew; if( db->mallocFailed ) return SQLITE_NOMEM_BKPT; + WHERETRACE(0x800, ("BEGIN addBtreeIdx(%s), nEq=%d\n", + pProbe->zName, pNew->u.btree.nEq)); assert( (pNew->wsFlags & WHERE_VIRTUALTABLE)==0 ); assert( (pNew->wsFlags & WHERE_TOP_LIMIT)==0 ); @@ -2600,6 +2602,8 @@ static int whereLoopAddBtreeIndex( pNew->wsFlags = saved_wsFlags; } + WHERETRACE(0x800, ("END addBtreeIdx(%s), nEq=%d, rc=%d\n", + pProbe->zName, saved_nEq, rc)); return rc; } From 72d5003ed84567b84589f1ea0807d25275fe9e4d Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 16 Sep 2016 15:42:17 +0000 Subject: [PATCH 0834/1484] Replace a faulty assert() with a testcase() to assure the condition is tested. FossilOrigin-Name: a49bc0a8244feb08b83e716d81c2a9512c184539 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/wherecode.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 1049290a29..a471df077b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sWHERETRACE\smacros\sshowing\severy\sentry\sand\sexit\sfrom\nwhereLoopAddBtreeIndex(). -D 2016-09-16T14:50:38.605 +C Replace\sa\sfaulty\sassert()\swith\sa\stestcase()\sto\sassure\sthe\scondition\sis\ntested. +D 2016-09-16T15:42:17.759 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e1aa788e84f926e42239ee167c53f785bedacacd @@ -469,7 +469,7 @@ F src/wal.h 6dd221ed384afdc204bc61e25c23ef7fd5a511f2 F src/walker.c 2d2cc7fb0f320f7f415215d7247f3c584141ac09 F src/where.c d0ca1b5e1c56249e7725cea66ce4e172c5845dec F src/whereInt.h 14dd243e13b81cbb0a66063d38b70f93a7d6e613 -F src/wherecode.c d172dcf99932ba698dd304edc9a368cd52b4b2e5 +F src/wherecode.c c23f9b26fbcdf3f1e3ff2bcd4377057ffc14e063 F src/whereexpr.c e3db778ed205e982f31960896db71c50612ae009 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a3e3b3e1c57178ccd38fc7375ec1de8e8ae45372 -R e3303608d5424eda671e1d828f84ecf6 +P e7653decdcee161d379ced40aa1b27246337b000 +R ba1360097229bdefefc2984ae83db820 U drh -Z cc222b0997065c7a36fcdb84d3a6e5ff +Z 4ae8145ebc191fbb330e31aa85de1aa5 diff --git a/manifest.uuid b/manifest.uuid index c069927d03..25cc139173 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e7653decdcee161d379ced40aa1b27246337b000 \ No newline at end of file +a49bc0a8244feb08b83e716d81c2a9512c184539 \ No newline at end of file diff --git a/src/wherecode.c b/src/wherecode.c index c440c56de3..c4ce2024c6 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -528,7 +528,7 @@ static int codeEqualityTerm( int iOut = iReg; if( pLoop->aLTerm[i]->pExpr==pX ){ if( eType==IN_INDEX_ROWID ){ - assert( nEq==1 && i==iEq ); + testcase( nEq>1 ); /* Happens with a UNIQUE index on ROWID */ pIn->addrInTop = sqlite3VdbeAddOp2(v, OP_Rowid, iTab, iReg); }else{ int iCol = aiMap ? aiMap[iMap++] : 0; From edc3537c613af5725492a4601cddd4f67f77c2e8 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 16 Sep 2016 16:30:57 +0000 Subject: [PATCH 0835/1484] Fix a problem causing incorrect code to be generated for IN constraints like "a IN (1, 2, 3)" where column "a" is a rowid column with an extra UNIQUE index created on it. Ticket [0eab1ac759]. FossilOrigin-Name: a92aee5520cfaf85ae896365a7e42bdd981f828d --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/wherecode.c | 5 ++--- test/in5.test | 23 +++++++++++++++++++++-- 4 files changed, 32 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index a471df077b..f3a72f1e93 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Replace\sa\sfaulty\sassert()\swith\sa\stestcase()\sto\sassure\sthe\scondition\sis\ntested. -D 2016-09-16T15:42:17.759 +C Fix\sa\sproblem\scausing\sincorrect\scode\sto\sbe\sgenerated\sfor\sIN\sconstraints\slike\s"a\sIN\s(1,\s2,\s3)"\swhere\scolumn\s"a"\sis\sa\srowid\scolumn\swith\san\sextra\sUNIQUE\sindex\screated\son\sit.\sTicket\s[0eab1ac759]. +D 2016-09-16T16:30:57.249 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e1aa788e84f926e42239ee167c53f785bedacacd @@ -469,7 +469,7 @@ F src/wal.h 6dd221ed384afdc204bc61e25c23ef7fd5a511f2 F src/walker.c 2d2cc7fb0f320f7f415215d7247f3c584141ac09 F src/where.c d0ca1b5e1c56249e7725cea66ce4e172c5845dec F src/whereInt.h 14dd243e13b81cbb0a66063d38b70f93a7d6e613 -F src/wherecode.c c23f9b26fbcdf3f1e3ff2bcd4377057ffc14e063 +F src/wherecode.c e412e09abad1eea213d85594cf46db9f877db56d F src/whereexpr.c e3db778ed205e982f31960896db71c50612ae009 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -831,7 +831,7 @@ F test/in.test 20c5529986998949908f889c8208b2cd894b2cc9 F test/in2.test 5d4c61d17493c832f7d2d32bef785119e87bde75 F test/in3.test 3cbf58c87f4052cee3a58b37b6389777505aa0c0 F test/in4.test d2b38cba404bc4320f4fe1b595b3d163f212c068 -F test/in5.test acc710c12af118df5f8645eaba9479f5619eed81 +F test/in5.test 6c006e0bcd7351b69350ef566e65f244023489e9 F test/incrblob.test c9b96afc292aeff43d6687bcb09b0280aa599822 F test/incrblob2.test a5ce5ed1d0b01e2ed347245a21170372528af0a5 F test/incrblob3.test d8d036fde015d4a159cd3cbae9d29003b37227a4 @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e7653decdcee161d379ced40aa1b27246337b000 -R ba1360097229bdefefc2984ae83db820 -U drh -Z 4ae8145ebc191fbb330e31aa85de1aa5 +P a49bc0a8244feb08b83e716d81c2a9512c184539 +R 6f0469103fd0ee7eefefaa24af917500 +U dan +Z 752f0595c26528c23b738c8e2fc1f9ad diff --git a/manifest.uuid b/manifest.uuid index 25cc139173..6a719c5d9c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a49bc0a8244feb08b83e716d81c2a9512c184539 \ No newline at end of file +a92aee5520cfaf85ae896365a7e42bdd981f828d \ No newline at end of file diff --git a/src/wherecode.c b/src/wherecode.c index c4ce2024c6..0948dce4e6 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -525,14 +525,13 @@ static int codeEqualityTerm( int iMap = 0; /* Index in aiMap[] */ pIn += i; for(i=iEq;inLTerm; i++){ - int iOut = iReg; if( pLoop->aLTerm[i]->pExpr==pX ){ + int iOut = iReg + i - iEq; if( eType==IN_INDEX_ROWID ){ testcase( nEq>1 ); /* Happens with a UNIQUE index on ROWID */ - pIn->addrInTop = sqlite3VdbeAddOp2(v, OP_Rowid, iTab, iReg); + pIn->addrInTop = sqlite3VdbeAddOp2(v, OP_Rowid, iTab, iOut); }else{ int iCol = aiMap ? aiMap[iMap++] : 0; - iOut = iReg + i - iEq; pIn->addrInTop = sqlite3VdbeAddOp3(v,OP_Column,iTab, iCol, iOut); } sqlite3VdbeAddOp1(v, OP_IsNull, iOut); VdbeCoverage(v); diff --git a/test/in5.test b/test/in5.test index b49c93e15b..ac60cfe58e 100644 --- a/test/in5.test +++ b/test/in5.test @@ -214,8 +214,27 @@ do_execsql_test 7.3.2 { SELECT a FROM y1 WHERE b IN (SELECT a FROM y2); } {two} -finish_test - +#------------------------------------------------------------------------- +# Tests to confirm that indexes on the rowid column do not confuse +# the query planner. See ticket [0eab1ac7591f511d]. +# +do_execsql_test 8.0 { + CREATE TABLE n1(a INTEGER PRIMARY KEY, b VARCHAR(500)); + CREATE UNIQUE INDEX n1a ON n1(a); +} +do_execsql_test 8.1 { + SELECT count(*) FROM n1 WHERE a IN (1, 2, 3) +} 0 +do_execsql_test 8.2 { + SELECT count(*) FROM n1 WHERE a IN (SELECT +a FROM n1) +} 0 +do_execsql_test 8.3 { + INSERT INTO n1 VALUES(1, NULL), (2, NULL), (3, NULL); + SELECT count(*) FROM n1 WHERE a IN (1, 2, 3) +} 3 +do_execsql_test 8.4 { + SELECT count(*) FROM n1 WHERE a IN (SELECT +a FROM n1) +} 3 finish_test From 0882da8001911e33bd2f27404ed70d6f03fa2ebf Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 16 Sep 2016 18:53:42 +0000 Subject: [PATCH 0836/1484] Remove the #ifdef SQLITE_DEBUG from around the testcase_glob() routine in the command-line shell. FossilOrigin-Name: 9885dac4b98693c4d2ed643022127f1452f19dc6 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/shell.c | 2 -- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index f3a72f1e93..7e4f14716b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\scausing\sincorrect\scode\sto\sbe\sgenerated\sfor\sIN\sconstraints\slike\s"a\sIN\s(1,\s2,\s3)"\swhere\scolumn\s"a"\sis\sa\srowid\scolumn\swith\san\sextra\sUNIQUE\sindex\screated\son\sit.\sTicket\s[0eab1ac759]. -D 2016-09-16T16:30:57.249 +C Remove\sthe\s#ifdef\sSQLITE_DEBUG\sfrom\saround\sthe\stestcase_glob()\sroutine\nin\sthe\scommand-line\sshell. +D 2016-09-16T18:53:42.407 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e1aa788e84f926e42239ee167c53f785bedacacd @@ -387,7 +387,7 @@ F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c 3c3cf0dc719cd2a32ab5c1e10c26481dd565492e F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c 244f9cc5e4662987cd2ef5c22d1b7027560f3425 -F src/shell.c ae7058efb5084b4b9576dc5485bb3d2870b1974a +F src/shell.c 6fbbb69f5377550b9c00932077c09fde86dad0f7 F src/sqlite.h.in 46ed821aeed0ba45559fb15597d9a400083154a2 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a49bc0a8244feb08b83e716d81c2a9512c184539 -R 6f0469103fd0ee7eefefaa24af917500 -U dan -Z 752f0595c26528c23b738c8e2fc1f9ad +P a92aee5520cfaf85ae896365a7e42bdd981f828d +R ee0cf31a4951ba6f76f2503b1e8b6ac4 +U drh +Z 869e33134584b23a4d21c5bff81dceaf diff --git a/manifest.uuid b/manifest.uuid index 6a719c5d9c..21cf26c1c4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a92aee5520cfaf85ae896365a7e42bdd981f828d \ No newline at end of file +9885dac4b98693c4d2ed643022127f1452f19dc6 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 9b5030bb39..cd148e6de3 100644 --- a/src/shell.c +++ b/src/shell.c @@ -3085,7 +3085,6 @@ static int shellNomemError(void){ return 1; } -#ifdef SQLITE_DEBUG /* ** Compare the pattern in zGlob[] against the text in z[]. Return TRUE ** if they match and FALSE (0) if they do not match. @@ -3182,7 +3181,6 @@ static int testcase_glob(const char *zGlob, const char *z){ while( IsSpace(*z) ){ z++; } return *z==0; } -#endif /* defined(SQLITE_DEBUG) */ /* From d145915a598a5c410b6288070904d4b00b1961e5 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 16 Sep 2016 19:11:03 +0000 Subject: [PATCH 0837/1484] Fix problems with the fileRead() function in the command-line shell. Fix a harmless memory leak in the command-line shell, to make validation testing easier. FossilOrigin-Name: e660402e5e654b7f37ad2ce201df5cbb2b9eb9a6 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/shell.c | 20 +++++++++++++++----- 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 7e4f14716b..ba74c6d21a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sthe\s#ifdef\sSQLITE_DEBUG\sfrom\saround\sthe\stestcase_glob()\sroutine\nin\sthe\scommand-line\sshell. -D 2016-09-16T18:53:42.407 +C Fix\sproblems\swith\sthe\sfileRead()\sfunction\sin\sthe\scommand-line\sshell.\s\sFix\na\sharmless\smemory\sleak\sin\sthe\scommand-line\sshell,\sto\smake\svalidation\stesting\neasier. +D 2016-09-16T19:11:03.888 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e1aa788e84f926e42239ee167c53f785bedacacd @@ -387,7 +387,7 @@ F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c 3c3cf0dc719cd2a32ab5c1e10c26481dd565492e F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c 244f9cc5e4662987cd2ef5c22d1b7027560f3425 -F src/shell.c 6fbbb69f5377550b9c00932077c09fde86dad0f7 +F src/shell.c 131978e994157b3925efd6fdf0e0c4ed9ab2cf91 F src/sqlite.h.in 46ed821aeed0ba45559fb15597d9a400083154a2 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a92aee5520cfaf85ae896365a7e42bdd981f828d -R ee0cf31a4951ba6f76f2503b1e8b6ac4 +P 9885dac4b98693c4d2ed643022127f1452f19dc6 +R 88f539d71fa2571070b5d308155e3cfc U drh -Z 869e33134584b23a4d21c5bff81dceaf +Z 09ffb02e347dfbb4f5f38eddcacdd3ba diff --git a/manifest.uuid b/manifest.uuid index 21cf26c1c4..ac0e0ae411 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9885dac4b98693c4d2ed643022127f1452f19dc6 \ No newline at end of file +e660402e5e654b7f37ad2ce201df5cbb2b9eb9a6 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index cd148e6de3..1dad6d9c2a 100644 --- a/src/shell.c +++ b/src/shell.c @@ -2252,17 +2252,21 @@ static int process_input(ShellState *p, FILE *in); static char *readFile(const char *zName){ FILE *in = fopen(zName, "rb"); long nIn; + size_t nRead; char *pBuf; if( in==0 ) return 0; fseek(in, 0, SEEK_END); nIn = ftell(in); rewind(in); - pBuf = sqlite3_malloc64( nIn ); + pBuf = sqlite3_malloc64( nIn+1 ); if( pBuf==0 ) return 0; - if( 1!=fread(pBuf, nIn, 1, in) ){ + nRead = fread(pBuf, nIn, 1, in); + fclose(in); + if( nRead!=1 ){ sqlite3_free(pBuf); return 0; } + pBuf[nIn] = 0; return pBuf; } @@ -5203,8 +5207,13 @@ static int process_input(ShellState *p, FILE *in){ ** Return a pathname which is the user's home directory. A ** 0 return indicates an error of some kind. */ -static char *find_home_dir(void){ +static char *find_home_dir(int clearFlag){ static char *home_dir = NULL; + if( clearFlag ){ + free(home_dir); + home_dir = 0; + return 0; + } if( home_dir ) return home_dir; #if !defined(_WIN32) && !defined(WIN32) && !defined(_WIN32_WCE) \ @@ -5279,7 +5288,7 @@ static void process_sqliterc( FILE *in = NULL; if (sqliterc == NULL) { - home_dir = find_home_dir(); + home_dir = find_home_dir(0); if( home_dir==0 ){ raw_printf(stderr, "-- warning: cannot find home directory;" " cannot read ~/.sqliterc\n"); @@ -5767,7 +5776,7 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ printf(".\nUse \".open FILENAME\" to reopen on a " "persistent database.\n"); } - zHome = find_home_dir(); + zHome = find_home_dir(0); if( zHome ){ nHistory = strlen30(zHome) + 20; if( (zHistory = malloc(nHistory))!=0 ){ @@ -5791,6 +5800,7 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ sqlite3_close(data.db); } sqlite3_free(data.zFreeOnClose); + find_home_dir(1); #if !SQLITE_SHELL_IS_UTF8 for(i=0; i Date: Fri, 16 Sep 2016 19:42:47 +0000 Subject: [PATCH 0838/1484] If no KEY is specified on ATTACH, copy the main schema key if the key size is non-zero. In other words, allow for -1 as a valid key size in support of the --textkey to SEE. FossilOrigin-Name: 03573887dbf357f8aa54e4a1cd03b82b0ded8139 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/attach.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index ba74c6d21a..1e49e4a711 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sproblems\swith\sthe\sfileRead()\sfunction\sin\sthe\scommand-line\sshell.\s\sFix\na\sharmless\smemory\sleak\sin\sthe\scommand-line\sshell,\sto\smake\svalidation\stesting\neasier. -D 2016-09-16T19:11:03.888 +C If\sno\sKEY\sis\sspecified\son\sATTACH,\scopy\sthe\smain\sschema\skey\sif\sthe\skey\ssize\nis\snon-zero.\s\sIn\sother\swords,\sallow\sfor\s-1\sas\sa\svalid\skey\ssize\sin\ssupport\nof\sthe\s--textkey\sto\sSEE. +D 2016-09-16T19:42:47.592 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e1aa788e84f926e42239ee167c53f785bedacacd @@ -324,7 +324,7 @@ F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F src/alter.c 299117695b1f21ac62dfc5b608588810ba22ed0d F src/analyze.c 8b62b2cf4da85451534ac0af82cafc418d837f68 -F src/attach.c 4711ff365df4072b8c3dcd55db5d12dcf8ffa0c6 +F src/attach.c 3e78d38abb5a4e3e0048a16ab662e6ffa323687c F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792 F src/backup.c 92c2e3b5fcb47626413717138617f4d32f08aea4 F src/bitvec.c 3ee4c8b2c94ed3a7377256e18199e6ff5cf33f63 @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 9885dac4b98693c4d2ed643022127f1452f19dc6 -R 88f539d71fa2571070b5d308155e3cfc +P e660402e5e654b7f37ad2ce201df5cbb2b9eb9a6 +R 229c67ed88dfee6249671d401c7e5ca7 U drh -Z 09ffb02e347dfbb4f5f38eddcacdd3ba +Z 23da9c0621ec24a2fd4b8d5523827e43 diff --git a/manifest.uuid b/manifest.uuid index ac0e0ae411..4fa5c6b9b9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e660402e5e654b7f37ad2ce201df5cbb2b9eb9a6 \ No newline at end of file +03573887dbf357f8aa54e4a1cd03b82b0ded8139 \ No newline at end of file diff --git a/src/attach.c b/src/attach.c index 5d2a55278d..a9fdc36761 100644 --- a/src/attach.c +++ b/src/attach.c @@ -192,7 +192,7 @@ static void attachFunc( case SQLITE_NULL: /* No key specified. Use the key from the main database */ sqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey); - if( nKey>0 || sqlite3BtreeGetOptimalReserve(db->aDb[0].pBt)>0 ){ + if( nKey || sqlite3BtreeGetOptimalReserve(db->aDb[0].pBt)>0 ){ rc = sqlite3CodecAttach(db, db->nDb-1, zKey, nKey); } break; From 8145fc6eda4753158fd2779063405c285752eda6 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Fri, 16 Sep 2016 20:39:21 +0000 Subject: [PATCH 0839/1484] Fix typo in the name of a Win32 string conversion routine. Replace several uses of raw_printf() with utf8_printf() in the shell. FossilOrigin-Name: 6fc95dd7a0b44212f30e657a850892a85a12715c --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/shell.c | 16 +++++++++------- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index 1e49e4a711..ad58bc0102 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C If\sno\sKEY\sis\sspecified\son\sATTACH,\scopy\sthe\smain\sschema\skey\sif\sthe\skey\ssize\nis\snon-zero.\s\sIn\sother\swords,\sallow\sfor\s-1\sas\sa\svalid\skey\ssize\sin\ssupport\nof\sthe\s--textkey\sto\sSEE. -D 2016-09-16T19:42:47.592 +C Fix\stypo\sin\sthe\sname\sof\sa\sWin32\sstring\sconversion\sroutine.\s\sReplace\sseveral\suses\sof\sraw_printf()\swith\sutf8_printf()\sin\sthe\sshell. +D 2016-09-16T20:39:21.872 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e1aa788e84f926e42239ee167c53f785bedacacd @@ -387,7 +387,7 @@ F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c 3c3cf0dc719cd2a32ab5c1e10c26481dd565492e F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c 244f9cc5e4662987cd2ef5c22d1b7027560f3425 -F src/shell.c 131978e994157b3925efd6fdf0e0c4ed9ab2cf91 +F src/shell.c b80396d2fadce4681397707e30078bf416e1dec2 F src/sqlite.h.in 46ed821aeed0ba45559fb15597d9a400083154a2 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e660402e5e654b7f37ad2ce201df5cbb2b9eb9a6 -R 229c67ed88dfee6249671d401c7e5ca7 -U drh -Z 23da9c0621ec24a2fd4b8d5523827e43 +P 03573887dbf357f8aa54e4a1cd03b82b0ded8139 +R cbd23b2be6d6c200e751cfcfa4ecc2e3 +U mistachkin +Z d5990f30391f700f012fd4fd2aa1ad1b diff --git a/manifest.uuid b/manifest.uuid index 4fa5c6b9b9..f9b71348c8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -03573887dbf357f8aa54e4a1cd03b82b0ded8139 \ No newline at end of file +6fc95dd7a0b44212f30e657a850892a85a12715c \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 1dad6d9c2a..732ef62832 100644 --- a/src/shell.c +++ b/src/shell.c @@ -143,6 +143,7 @@ extern char *sqlite3_win32_unicode_to_utf8(LPCWSTR); extern char *sqlite3_win32_mbcs_to_utf8_v2(const char *, int); extern char *sqlite3_win32_utf8_to_mbcs_v2(const char *, int); +extern LPWSTR sqlite3_win32_utf8_to_unicode(const char *zText); #endif /* On Windows, we normally run with output mode of TEXT so that \n characters @@ -929,7 +930,7 @@ static int shellAuth( az[1] = zA2; az[2] = zA3; az[3] = zA4; - raw_printf(p->out, "authorizer: %s", azAction[op]); + utf8_printf(p->out, "authorizer: %s", azAction[op]); for(i=0; i<4; i++){ raw_printf(p->out, " "); if( az[i] ){ @@ -942,7 +943,7 @@ static int shellAuth( return SQLITE_OK; } #endif - + /* ** This is the callback routine that the shell @@ -1446,7 +1447,7 @@ static void displayLinuxIoStats(FILE *out){ for(i=0; izTestcase, azArg[1], zRes); rc = 2; }else{ - raw_printf(stdout, "testcase-%s ok\n", p->zTestcase); + utf8_printf(stdout, "testcase-%s ok\n", p->zTestcase); p->nCheck++; } sqlite3_free(zRes); @@ -4016,6 +4017,7 @@ static int do_meta_command(char *zLine, ShellState *p){ }else if( z[0]=='-' ){ utf8_printf(stderr, "unknown option: %s\n", z); rc = 1; + goto meta_command_exit; } } /* If a filename is specified, try to open it first */ From fd7459e0aa15642bb3bf816b52d3bf336d3244c1 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 17 Sep 2016 17:39:01 +0000 Subject: [PATCH 0840/1484] Improved description of the ElseNotEq opcode in comments. No changes to code. FossilOrigin-Name: e011435e2f57ddfe315d5da48e93185d6789fc80 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/vdbe.c | 10 +++++----- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index ad58bc0102..1adebbd453 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\stypo\sin\sthe\sname\sof\sa\sWin32\sstring\sconversion\sroutine.\s\sReplace\sseveral\suses\sof\sraw_printf()\swith\sutf8_printf()\sin\sthe\sshell. -D 2016-09-16T20:39:21.872 +C Improved\sdescription\sof\sthe\sElseNotEq\sopcode\sin\scomments.\s\sNo\schanges\sto\scode. +D 2016-09-17T17:39:01.590 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e1aa788e84f926e42239ee167c53f785bedacacd @@ -453,7 +453,7 @@ F src/update.c 8179e699dbd45b92934fd02d3d8e3732e8da8802 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 810ec3f22e2d1b62e66c30fe3621ebdedd23584d F src/vacuum.c 913970b9d86dd6c2b8063ef1af421880f1464ec3 -F src/vdbe.c 31a17090bf658c1e6ba4e58f7a08e8ce4c2e7d7f +F src/vdbe.c bd7e890b2d6e2c93c808e5cf0f8e9fb26198d0fc F src/vdbe.h 67bc551f7faf04c33493892e4b378aada823ed10 F src/vdbeInt.h c59381049af5c7751a83456c39b80d1a6fde1f9d F src/vdbeapi.c a32d61b7dd05e6890d8fd44d2805f55e2f5ba9f3 @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 03573887dbf357f8aa54e4a1cd03b82b0ded8139 -R cbd23b2be6d6c200e751cfcfa4ecc2e3 -U mistachkin -Z d5990f30391f700f012fd4fd2aa1ad1b +P 6fc95dd7a0b44212f30e657a850892a85a12715c +R 562a09a50cde79cd40aa8ed06ba4df04 +U drh +Z 32468d94216159db676195bbafc35d3f diff --git a/manifest.uuid b/manifest.uuid index f9b71348c8..15f3d66f4a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6fc95dd7a0b44212f30e657a850892a85a12715c \ No newline at end of file +e011435e2f57ddfe315d5da48e93185d6789fc80 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 552da6fd96..4aa26d006e 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2121,11 +2121,11 @@ compare_op: /* Opcode: ElseNotEq * P2 * * * ** -** This opcode must immediately follow an Lt or Gt comparison operator. -** If the operands in that previous comparison had been used with an Eq -** operator and if the result of that Eq would be NULL or false (0), then -** then jump to P2. If the result of comparing the two previous operands -** using Eq would have been true (1), then fall through. +** This opcode must immediately follow an OP_Lt or OP_Gt comparison operator. +** If result of an OP_Eq comparison on the same two operands +** would have be NULL or false (0), then then jump to P2. +** If the result of an OP_Eq comparison on the two previous operands +** would have been true (1), then fall through. */ case OP_ElseNotEq: { /* same as TK_ESCAPE, jump */ assert( pOp>aOp ); From 85f071b8505e16d3cfba5a1b8747ea33084bfba6 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 17 Sep 2016 19:34:32 +0000 Subject: [PATCH 0841/1484] Small performance optimization in the freeSpace() routine of btree.c. FossilOrigin-Name: 63962e2a927963575be74c3ce11f39f722c07c72 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btree.c | 7 +++++-- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 1adebbd453..c6423c99e6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improved\sdescription\sof\sthe\sElseNotEq\sopcode\sin\scomments.\s\sNo\schanges\sto\scode. -D 2016-09-17T17:39:01.590 +C Small\sperformance\soptimization\sin\sthe\sfreeSpace()\sroutine\sof\sbtree.c. +D 2016-09-17T19:34:32.434 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e1aa788e84f926e42239ee167c53f785bedacacd @@ -329,7 +329,7 @@ F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792 F src/backup.c 92c2e3b5fcb47626413717138617f4d32f08aea4 F src/bitvec.c 3ee4c8b2c94ed3a7377256e18199e6ff5cf33f63 F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 -F src/btree.c 2551bd3ecb8b8988fb8b23aabadfb214dbc38e46 +F src/btree.c 56e1732ecfb3731efcb216266ec26b1b96e5e8c9 F src/btree.h d05b2fcc290991a8a3d9ea1816ddd55a4359dcde F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 F src/build.c 7438b6dae3022818100a79ebbad707b5c65f9344 @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 6fc95dd7a0b44212f30e657a850892a85a12715c -R 562a09a50cde79cd40aa8ed06ba4df04 +P e011435e2f57ddfe315d5da48e93185d6789fc80 +R 1118d76ecd8c2e7b5eef8b1643f57d9c U drh -Z 32468d94216159db676195bbafc35d3f +Z f339d94adbbc4640c3413f9f33dceacc diff --git a/manifest.uuid b/manifest.uuid index 15f3d66f4a..1984ef5697 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e011435e2f57ddfe315d5da48e93185d6789fc80 \ No newline at end of file +63962e2a927963575be74c3ce11f39f722c07c72 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 841aee9463..681285ac99 100644 --- a/src/btree.c +++ b/src/btree.c @@ -1605,8 +1605,11 @@ static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){ if( data[iPtr+1]==0 && data[iPtr]==0 ){ iFreeBlk = 0; /* Shortcut for the case when the freelist is empty */ }else{ - while( (iFreeBlk = get2byte(&data[iPtr]))>0 && iFreeBlkiLast ) return SQLITE_CORRUPT_BKPT; From 598f7c59e140c244d616b8f7c882b7d17229f02c Mon Sep 17 00:00:00 2001 From: mistachkin Date: Sat, 17 Sep 2016 22:46:13 +0000 Subject: [PATCH 0842/1484] Minor enhancement to the TclKit batch tool: it should download the TclKit EXE alone when the TCLKIT_NOENV environment variable is set. FossilOrigin-Name: baceb988c6f4e93134e6a63173e846af2b73531a --- manifest | 14 +++++++------- manifest.uuid | 2 +- tool/GetTclKit.bat | 10 ++++++++-- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index c6423c99e6..0a11d0dc7a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Small\sperformance\soptimization\sin\sthe\sfreeSpace()\sroutine\sof\sbtree.c. -D 2016-09-17T19:34:32.434 +C Minor\senhancement\sto\sthe\sTclKit\sbatch\stool:\sit\sshould\sdownload\sthe\sTclKit\sEXE\salone\swhen\sthe\sTCLKIT_NOENV\senvironment\svariable\sis\sset. +D 2016-09-17T22:46:13.833 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e1aa788e84f926e42239ee167c53f785bedacacd @@ -1437,7 +1437,7 @@ F test/wordcount.c 97856eec21fd00d77da720007b1888c383f63dcf F test/zeroblob.test 3857870fe681b8185654414a9bccfde80b62a0fa F test/zerodamage.test e59a56443d6298ecf7435f618f0b27654f0c849e F tool/GetFile.cs a15e08acb5dd7539b75ba23501581d7c2b462cb5 -F tool/GetTclKit.bat 629d87562e0487c386db630033931d12d62e6372 +F tool/GetTclKit.bat f94784e3bdc2f50c539266f5467cbf1f27612cb3 F tool/Replace.cs 02c67258801c2fb5f63231e0ac0f220b4b36ba91 F tool/addopcodes.tcl 10c889c4a65ec6c5604e4a47306fa77ff57ae189 F tool/build-all-msvc.bat 3e4e4043b53f1aede4308e0d2567bbd773614630 x @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e011435e2f57ddfe315d5da48e93185d6789fc80 -R 1118d76ecd8c2e7b5eef8b1643f57d9c -U drh -Z f339d94adbbc4640c3413f9f33dceacc +P 63962e2a927963575be74c3ce11f39f722c07c72 +R a636a72a27c00683275c0e840ed0e183 +U mistachkin +Z c511a2952b921071fe5b6c44565784ab diff --git a/manifest.uuid b/manifest.uuid index 1984ef5697..5867b37be4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -63962e2a927963575be74c3ce11f39f722c07c72 \ No newline at end of file +baceb988c6f4e93134e6a63173e846af2b73531a \ No newline at end of file diff --git a/tool/GetTclKit.bat b/tool/GetTclKit.bat index 84235cf97a..8764b195dd 100644 --- a/tool/GetTclKit.bat +++ b/tool/GetTclKit.bat @@ -77,6 +77,7 @@ IF /I "%PROCESSOR%" == "x86" ( %_VECHO% TclKitVersion = '%TCLKIT_VERSION%' %_VECHO% TclKitPatchLevel = '%TCLKIT_PATCHLEVEL%' +%_VECHO% TclKitNoEnv = '%TCLKIT_NOENV%' %_VECHO% TclKitNoSdk = '%TCLKIT_NOSDK%' %_VECHO% TclKitExe = '%TCLKIT_EXE%' %_VECHO% TclKitLib = '%TCLKIT_LIB%' @@ -147,6 +148,7 @@ FOR %%F IN (%TCLKIT_FILES%) DO ( ) ) +IF DEFINED TCLKIT_NOENV GOTO skip_sdkUnZip IF DEFINED TCLKIT_NOSDK GOTO skip_sdkUnZip IF NOT EXIST "%TEMP%\%TCLKIT_SDK%" ( @@ -167,6 +169,8 @@ IF ERRORLEVEL 1 ( :skip_sdkUnZip +IF DEFINED TCLKIT_NOENV GOTO skip_sdkEnvironment + %__ECHO% ECHO SET TCLSH_CMD=%TEMP%\%TCLKIT_EXE%%OVERWRITE%"%ROOT%\SetTclKitEnv.bat" IF DEFINED TCLKIT_NOSDK GOTO skip_sdkVariables @@ -184,6 +188,8 @@ ECHO Wrote "%ROOT%\SetTclKitEnv.bat". ECHO Please run it to set the necessary Tcl environment variables. ECHO. +:skip_sdkEnvironment + GOTO no_errors :fn_TclKitX86Variables @@ -198,7 +204,7 @@ GOTO no_errors SET TCLKIT_SDK=libtclkit-sdk-x86-%TCLKIT_PATCHLEVEL% SET TCLKIT_SDK_ZIP=%TCLKIT_SDK%.zip SET TCLKIT_FILES=%TCLKIT_EXE% - IF NOT DEFINED TCLKIT_NOSDK ( + IF NOT DEFINED TCLKIT_NOENV IF NOT DEFINED TCLKIT_NOSDK ( SET TCLKIT_FILES=%TCLKIT_FILES% unzip.exe %TCLKIT_SDK_ZIP% ) GOTO :EOF @@ -223,7 +229,7 @@ GOTO no_errors SET TCLKIT_SDK=libtclkit-sdk-x64-%TCLKIT_PATCHLEVEL% SET TCLKIT_SDK_ZIP=%TCLKIT_SDK%.zip SET TCLKIT_FILES=%TCLKIT_EXE% - IF NOT DEFINED TCLKIT_NOSDK ( + IF NOT DEFINED TCLKIT_NOENV IF NOT DEFINED TCLKIT_NOSDK ( SET TCLKIT_FILES=%TCLKIT_FILES% unzip.exe %TCLKIT_SDK_ZIP% ) GOTO :EOF From 9e5eb9c8cc66320ec01298cc2e76ae6a1e29515a Mon Sep 17 00:00:00 2001 From: drh Date: Sun, 18 Sep 2016 16:08:10 +0000 Subject: [PATCH 0843/1484] Revise the implementation of OP_Once so that it is smaller, faster, and uses less memory. This also fixes an obscure bug introduced 3 days ago by check-in [5990a1bdb4a073]. FossilOrigin-Name: 6bf5ba10d28f1b0a32aa9a560ae3143a1235eadb --- manifest | 32 ++++++++++++++++---------------- manifest.uuid | 2 +- src/expr.c | 2 +- src/global.c | 3 ++- src/main.c | 9 +++++++++ src/sqlite.h.in | 1 + src/sqliteInt.h | 2 +- src/trigger.c | 1 - src/vdbe.c | 42 ++++++++++++++++++++++-------------------- src/vdbe.h | 1 - src/vdbeInt.h | 4 ---- src/vdbeaux.c | 10 ---------- 12 files changed, 53 insertions(+), 56 deletions(-) diff --git a/manifest b/manifest index 0a11d0dc7a..8b2cc6c428 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Minor\senhancement\sto\sthe\sTclKit\sbatch\stool:\sit\sshould\sdownload\sthe\sTclKit\sEXE\salone\swhen\sthe\sTCLKIT_NOENV\senvironment\svariable\sis\sset. -D 2016-09-17T22:46:13.833 +C Revise\sthe\simplementation\sof\sOP_Once\sso\sthat\sit\sis\ssmaller,\sfaster,\sand\suses\nless\smemory.\s\sThis\salso\sfixes\san\sobscure\sbug\sintroduced\s3\sdays\sago\sby\scheck-in\n[5990a1bdb4a073]. +D 2016-09-18T16:08:10.162 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e1aa788e84f926e42239ee167c53f785bedacacd @@ -339,11 +339,11 @@ F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7 F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c e91a11e0e86a13ce1917ca5ad7cf14c37ba31e59 -F src/expr.c c1de78269522de39f6ad877ab0810a5d48f91f34 +F src/expr.c 5f6c8263b021853aef5a43e920efebd0b94de394 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c e2be0968c1adc679c87e467aa5b4f167588f38a8 F src/func.c 29cc9acb170ec1387b9f63eb52cd85f8de96c771 -F src/global.c c45ea22aff29334f6a9ec549235ac3357c970015 +F src/global.c 2917bbc488201b791e5f5dd43d8d2a3ccc315da7 F src/hash.c 55b5fb474100cee0b901edaf203e26c970940f36 F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4 F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da @@ -351,7 +351,7 @@ F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 F src/insert.c 427e96ff168b6b187a52c3d06b9f9e41f6ffb212 F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e F src/loadext.c 5d6642d141c07d366e43d359e94ec9de47add41d -F src/main.c 9821bb4d2399bc5a0b8a5dfc06bede2d1520255c +F src/main.c 14fb66eeb2eea477f9e79434fde3cca3aff0ea5c F src/malloc.c 1443d1ad95d67c21d77af7ae3f44678252f0efec F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b @@ -388,10 +388,10 @@ F src/resolve.c 3c3cf0dc719cd2a32ab5c1e10c26481dd565492e F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c 244f9cc5e4662987cd2ef5c22d1b7027560f3425 F src/shell.c b80396d2fadce4681397707e30078bf416e1dec2 -F src/sqlite.h.in 46ed821aeed0ba45559fb15597d9a400083154a2 +F src/sqlite.h.in 2683a291ed8db5228024267be6421f0de507b80e F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae -F src/sqliteInt.h c9e010a79ab4ed7bdc910a24d8f08f3c6d5f822c +F src/sqliteInt.h 1abb4501bbc28c9badf0ebc1e99bd66585ba04f0 F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 @@ -448,16 +448,16 @@ F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c 78c8085bc7af1922aa687f0f4bbd716821330de5 F src/treeview.c f51b75a28b377adde9f79bc3deb6c7770bcf97c0 -F src/trigger.c cae81f6c65c4977bc2cbd27d43bfee478710853c +F src/trigger.c 3419bb9862983d84d70735fb4c94b21b934cd0c5 F src/update.c 8179e699dbd45b92934fd02d3d8e3732e8da8802 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 810ec3f22e2d1b62e66c30fe3621ebdedd23584d F src/vacuum.c 913970b9d86dd6c2b8063ef1af421880f1464ec3 -F src/vdbe.c bd7e890b2d6e2c93c808e5cf0f8e9fb26198d0fc -F src/vdbe.h 67bc551f7faf04c33493892e4b378aada823ed10 -F src/vdbeInt.h c59381049af5c7751a83456c39b80d1a6fde1f9d +F src/vdbe.c cdac9f8c53e2992816809a45910ff33b6122c191 +F src/vdbe.h c044be7050ac6bf596eecc6ab159f5dbc020a3b7 +F src/vdbeInt.h d21f14721dd87975dc9e3bcdbf504f9c098cf611 F src/vdbeapi.c a32d61b7dd05e6890d8fd44d2805f55e2f5ba9f3 -F src/vdbeaux.c 12831f89de66a23d575d129dc1bda543a09a80c7 +F src/vdbeaux.c 66054df369ca76530b6b84e6fce2f847dc99a9b1 F src/vdbeblob.c 3e82a797b60c3b9fed7b8de8c539ca7607874937 F src/vdbemem.c 357caac1a404f37ee6087b17613f92107c13f733 F src/vdbesort.c 91fda3909326860382b0ca8aa251e609c6a9d62c @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 63962e2a927963575be74c3ce11f39f722c07c72 -R a636a72a27c00683275c0e840ed0e183 -U mistachkin -Z c511a2952b921071fe5b6c44565784ab +P baceb988c6f4e93134e6a63173e846af2b73531a +R 305c67fde695fcddb65717c9957658ad +U drh +Z 45869286482c6f2c4387b12de5cab0cb diff --git a/manifest.uuid b/manifest.uuid index 5867b37be4..f8b9f2bf1b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -baceb988c6f4e93134e6a63173e846af2b73531a \ No newline at end of file +6bf5ba10d28f1b0a32aa9a560ae3143a1235eadb \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index abae812ea5..14bde45bb0 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1974,7 +1974,7 @@ static Select *isCandidateForInOpt(Expr *pX){ */ int sqlite3CodeOnce(Parse *pParse){ Vdbe *v = sqlite3GetVdbe(pParse); /* Virtual machine being coded */ - return sqlite3VdbeAddOp1(v, OP_Once, pParse->nOnce++); + return sqlite3VdbeAddOp0(v, OP_Once); } #ifndef SQLITE_OMIT_SUBQUERY diff --git a/src/global.c b/src/global.c index 76901a89b1..8b676ef66f 100644 --- a/src/global.c +++ b/src/global.c @@ -225,7 +225,8 @@ SQLITE_WSD struct Sqlite3Config sqlite3Config = { #ifndef SQLITE_OMIT_BUILTIN_TEST 0, /* xTestCallback */ #endif - 0 /* bLocaltimeFault */ + 0, /* bLocaltimeFault */ + 0x7ffffffe /* iOnceResetThreshold */ }; /* diff --git a/src/main.c b/src/main.c index c3700cd413..9c161d0ef5 100644 --- a/src/main.c +++ b/src/main.c @@ -3784,6 +3784,15 @@ int sqlite3_test_control(int op, ...){ break; } + /* Set the threshold at which OP_Once counters reset back to zero. + ** By default this is 0xfffffffe (over 2 billion), but that value is + ** too big to test in a reasonable amount of time, so this control is + ** provided to set a small and easily reachable reset value. + */ + case SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD: { + sqlite3GlobalConfig.iOnceResetThreshold = va_arg(ap, int); + break; + } /* sqlite3_test_control(SQLITE_TESTCTRL_VDBE_COVERAGE, xCallback, ptr); ** diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 52b58370dd..778d53d3d6 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -6717,6 +6717,7 @@ int sqlite3_test_control(int op, ...); #define SQLITE_TESTCTRL_SCRATCHMALLOC 17 #define SQLITE_TESTCTRL_LOCALTIME_FAULT 18 #define SQLITE_TESTCTRL_EXPLAIN_STMT 19 /* NOT USED */ +#define SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD 19 #define SQLITE_TESTCTRL_NEVER_CORRUPT 20 #define SQLITE_TESTCTRL_VDBE_COVERAGE 21 #define SQLITE_TESTCTRL_BYTEORDER 22 diff --git a/src/sqliteInt.h b/src/sqliteInt.h index dbb18a7458..ebae7e54ab 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2896,7 +2896,6 @@ struct Parse { int nTab; /* Number of previously allocated VDBE cursors */ int nMem; /* Number of memory cells used so far */ int nSet; /* Number of sets used so far */ - int nOnce; /* Number of OP_Once instructions so far */ int nOpAlloc; /* Number of slots allocated for Vdbe.aOp[] */ int szOpAlloc; /* Bytes of memory space allocated for Vdbe.aOp[] */ int iFixedOp; /* Never back out opcodes iFixedOp-1 or earlier */ @@ -3230,6 +3229,7 @@ struct Sqlite3Config { int (*xTestCallback)(int); /* Invoked by sqlite3FaultSim() */ #endif int bLocaltimeFault; /* True to fail localtime() calls */ + int iOnceResetThreshold; /* When to reset OP_Once counters */ }; /* diff --git a/src/trigger.c b/src/trigger.c index 5c80560114..7eb14bcf8d 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -879,7 +879,6 @@ static TriggerPrg *codeRowTrigger( } pProgram->nMem = pSubParse->nMem; pProgram->nCsr = pSubParse->nTab; - pProgram->nOnce = pSubParse->nOnce; pProgram->token = (void *)pTrigger; pPrg->aColmask[0] = pSubParse->oldmask; pPrg->aColmask[1] = pSubParse->newmask; diff --git a/src/vdbe.c b/src/vdbe.c index 4aa26d006e..51092cfedb 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2332,22 +2332,18 @@ case OP_BitNot: { /* same as TK_BITNOT, in1, out2 */ /* Opcode: Once P1 P2 * * * ** -** Check the "once" flag number P1. If it is set, jump to instruction P2. -** Otherwise, set the flag and fall through to the next instruction. -** In other words, this opcode causes all following opcodes up through P2 -** (but not including P2) to run just once and to be skipped on subsequent -** times through the loop. -** -** All "once" flags are initially cleared whenever a prepared statement -** first begins to run. +** If the P1 value is equal to the P1 value on the OP_Init opcode at +** instruction 0, then jump to P2. If the two P1 values differ, then +** set the P1 value on this opcode to equal the P1 value on the OP_Init +** and fall through. */ case OP_Once: { /* jump */ - assert( pOp->p1nOnceFlag ); - VdbeBranchTaken(p->aOnceFlag[pOp->p1]!=0, 2); - if( p->aOnceFlag[pOp->p1] ){ + assert( p->aOp[0].opcode==OP_Init ); + VdbeBranchTaken(p->aOp[0].p1==pOp->p1, 2); + if( p->aOp[0].p1==pOp->p1 ){ goto jump_to_p2; }else{ - p->aOnceFlag[pOp->p1] = 1; + pOp->p1 = p->aOp[0].p1; } break; } @@ -5790,8 +5786,7 @@ case OP_Program: { /* jump */ if( pProgram->nCsr==0 ) nMem++; nByte = ROUND8(sizeof(VdbeFrame)) + nMem * sizeof(Mem) - + pProgram->nCsr * sizeof(VdbeCursor *) - + pProgram->nOnce * sizeof(u8); + + pProgram->nCsr * sizeof(VdbeCursor *); pFrame = sqlite3DbMallocZero(db, nByte); if( !pFrame ){ goto no_mem; @@ -5811,8 +5806,6 @@ case OP_Program: { /* jump */ pFrame->aOp = p->aOp; pFrame->nOp = p->nOp; pFrame->token = pProgram->token; - pFrame->aOnceFlag = p->aOnceFlag; - pFrame->nOnceFlag = p->nOnceFlag; #ifdef SQLITE_ENABLE_STMT_SCANSTATUS pFrame->anExec = p->anExec; #endif @@ -5846,13 +5839,10 @@ case OP_Program: { /* jump */ p->apCsr = (VdbeCursor **)&aMem[p->nMem]; p->aOp = aOp = pProgram->aOp; p->nOp = pProgram->nOp; - p->aOnceFlag = (u8 *)&p->apCsr[p->nCursor]; - p->nOnceFlag = pProgram->nOnce; #ifdef SQLITE_ENABLE_STMT_SCANSTATUS p->anExec = 0; #endif pOp = &aOp[-1]; - memset(p->aOnceFlag, 0, p->nOnceFlag); break; } @@ -6819,7 +6809,7 @@ case OP_MaxPgcnt: { /* out2 */ #endif -/* Opcode: Init * P2 * P4 * +/* Opcode: Init P1 P2 * P4 * ** Synopsis: Start at P2 ** ** Programs contain a single instance of this opcode as the very first @@ -6830,9 +6820,13 @@ case OP_MaxPgcnt: { /* out2 */ ** Or if P4 is blank, use the string returned by sqlite3_sql(). ** ** If P2 is not zero, jump to instruction P2. +** +** Increment the value of P1 so that OP_Once opcodes will jump the +** first time they are evaluated for this run. */ case OP_Init: { /* jump */ char *zTrace; + int i; /* If the P4 argument is not NULL, then it must be an SQL comment string. ** The "--" string is broken up to prevent false-positives with srcck1.c. @@ -6844,6 +6838,7 @@ case OP_Init: { /* jump */ ** sqlite3_expanded_sql(P) otherwise. */ assert( pOp->p4.z==0 || strncmp(pOp->p4.z, "-" "- ", 3)==0 ); + assert( pOp==p->aOp ); /* Always instruction 0 */ #ifndef SQLITE_OMIT_TRACE if( (db->mTrace & (SQLITE_TRACE_STMT|SQLITE_TRACE_LEGACY))!=0 @@ -6881,6 +6876,13 @@ case OP_Init: { /* jump */ #endif /* SQLITE_DEBUG */ #endif /* SQLITE_OMIT_TRACE */ assert( pOp->p2>0 ); + if( pOp->p1>=sqlite3GlobalConfig.iOnceResetThreshold ){ + for(i=1; inOp; i++){ + if( p->aOp[i].opcode==OP_Once ) p->aOp[i].p1 = 0; + } + pOp->p1 = 0; + } + pOp->p1++; goto jump_to_p2; } diff --git a/src/vdbe.h b/src/vdbe.h index a7bc84cea5..ecb2b0e3f4 100644 --- a/src/vdbe.h +++ b/src/vdbe.h @@ -88,7 +88,6 @@ struct SubProgram { int nOp; /* Elements in aOp[] */ int nMem; /* Number of memory cells required */ int nCsr; /* Number of cursors required */ - int nOnce; /* Number of OP_Once instructions */ void *token; /* id that may be used to recursive triggers */ SubProgram *pNext; /* Next sub-program already visited */ }; diff --git a/src/vdbeInt.h b/src/vdbeInt.h index ecb4fc5f06..b1d7717a0b 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -157,7 +157,6 @@ struct VdbeFrame { Op *aOp; /* Program instructions for parent frame */ i64 *anExec; /* Event counters from parent frame */ Mem *aMem; /* Array of memory cells for parent frame */ - u8 *aOnceFlag; /* Array of OP_Once flags for parent frame */ VdbeCursor **apCsr; /* Array of Vdbe cursors for parent frame */ void *token; /* Copy of SubProgram.token */ i64 lastRowid; /* Last insert rowid (sqlite3.lastRowid) */ @@ -166,7 +165,6 @@ struct VdbeFrame { int pc; /* Program Counter in parent (calling) frame */ int nOp; /* Size of aOp array */ int nMem; /* Number of entries in aMem */ - int nOnceFlag; /* Number of entries in aOnceFlag */ int nChildMem; /* Number of memory cells for child frame */ int nChildCsr; /* Number of cursors for child frame */ int nChange; /* Statement changes (Vdbe.nChange) */ @@ -410,8 +408,6 @@ struct Vdbe { int nFrame; /* Number of frames in pFrame list */ u32 expmask; /* Binding to these vars invalidates VM */ SubProgram *pProgram; /* Linked list of all sub-programs used by VM */ - int nOnceFlag; /* Size of array aOnceFlag[] */ - u8 *aOnceFlag; /* Flags for OP_Once */ AuxData *pAuxData; /* Linked list of auxdata allocations */ #ifdef SQLITE_ENABLE_STMT_SCANSTATUS i64 *anExec; /* Number of times each op has been executed */ diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 56f00efcfd..838a8f0446 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -1869,7 +1869,6 @@ void sqlite3VdbeMakeReady( int nMem; /* Number of VM memory registers */ int nCursor; /* Number of cursors required */ int nArg; /* Number of arguments in subprograms */ - int nOnce; /* Number of OP_Once instructions */ int n; /* Loop counter */ struct ReusableSpace x; /* Reusable bulk memory */ @@ -1884,8 +1883,6 @@ void sqlite3VdbeMakeReady( nMem = pParse->nMem; nCursor = pParse->nTab; nArg = pParse->nMaxArg; - nOnce = pParse->nOnce; - if( nOnce==0 ) nOnce = 1; /* Ensure at least one byte in p->aOnceFlag[] */ /* Each cursor uses a memory cell. The first cursor (cursor 0) can ** use aMem[0] which is not otherwise used by the VDBE program. Allocate @@ -1932,7 +1929,6 @@ void sqlite3VdbeMakeReady( p->aVar = allocSpace(&x, p->aVar, nVar*sizeof(Mem)); p->apArg = allocSpace(&x, p->apArg, nArg*sizeof(Mem*)); p->apCsr = allocSpace(&x, p->apCsr, nCursor*sizeof(VdbeCursor*)); - p->aOnceFlag = allocSpace(&x, p->aOnceFlag, nOnce); #ifdef SQLITE_ENABLE_STMT_SCANSTATUS p->anExec = allocSpace(&x, p->anExec, p->nOp*sizeof(i64)); #endif @@ -1942,7 +1938,6 @@ void sqlite3VdbeMakeReady( }while( !db->mallocFailed ); p->nCursor = nCursor; - p->nOnceFlag = nOnce; if( p->aVar ){ p->nVar = (ynVar)nVar; for(n=0; nanExec = pFrame->anExec; #endif - v->aOnceFlag = pFrame->aOnceFlag; - v->nOnceFlag = pFrame->nOnceFlag; v->aOp = pFrame->aOp; v->nOp = pFrame->nOp; v->aMem = pFrame->aMem; @@ -2569,11 +2562,8 @@ int sqlite3VdbeHalt(Vdbe *p){ ** one, or the complete transaction if there is no statement transaction. */ - assert( p->aOnceFlag!=0 || db->mallocFailed ); if( db->mallocFailed ){ p->rc = SQLITE_NOMEM_BKPT; - }else{ - memset(p->aOnceFlag, 0, p->nOnceFlag); } closeAllCursors(p); if( p->magic!=VDBE_MAGIC_RUN ){ From d43075bcaf7f427ee8124dc6cf43fb5971c64d3a Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 19 Sep 2016 02:19:00 +0000 Subject: [PATCH 0844/1484] Small performance optimization in the expression walker. FossilOrigin-Name: c6e6afb9391704d9119335f2ce17df3968acb514 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/walker.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 8b2cc6c428..addc2705a4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Revise\sthe\simplementation\sof\sOP_Once\sso\sthat\sit\sis\ssmaller,\sfaster,\sand\suses\nless\smemory.\s\sThis\salso\sfixes\san\sobscure\sbug\sintroduced\s3\sdays\sago\sby\scheck-in\n[5990a1bdb4a073]. -D 2016-09-18T16:08:10.162 +C Small\sperformance\soptimization\sin\sthe\sexpression\swalker. +D 2016-09-19T02:19:00.600 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e1aa788e84f926e42239ee167c53f785bedacacd @@ -466,7 +466,7 @@ F src/vtab.c e02cacb5c7ae742631edeb9ae9f53d399f093fd8 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 02eeecc265f6ffd0597378f5d8ae9070b62a406a F src/wal.h 6dd221ed384afdc204bc61e25c23ef7fd5a511f2 -F src/walker.c 2d2cc7fb0f320f7f415215d7247f3c584141ac09 +F src/walker.c 83042807db1a27175fcb39be8f3e2a839dbdddb2 F src/where.c d0ca1b5e1c56249e7725cea66ce4e172c5845dec F src/whereInt.h 14dd243e13b81cbb0a66063d38b70f93a7d6e613 F src/wherecode.c e412e09abad1eea213d85594cf46db9f877db56d @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P baceb988c6f4e93134e6a63173e846af2b73531a -R 305c67fde695fcddb65717c9957658ad +P 6bf5ba10d28f1b0a32aa9a560ae3143a1235eadb +R 3576b7fe8bd045656543b2a44b86fd72 U drh -Z 45869286482c6f2c4387b12de5cab0cb +Z 8bd385e2bfe7ba512e577302650c0d2b diff --git a/manifest.uuid b/manifest.uuid index f8b9f2bf1b..65b44f476e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6bf5ba10d28f1b0a32aa9a560ae3143a1235eadb \ No newline at end of file +c6e6afb9391704d9119335f2ce17df3968acb514 \ No newline at end of file diff --git a/src/walker.c b/src/walker.c index 82aae67a61..5abc3b9add 100644 --- a/src/walker.c +++ b/src/walker.c @@ -46,7 +46,7 @@ static SQLITE_NOINLINE int walkExpr(Walker *pWalker, Expr *pExpr){ if( pExpr->pRight && walkExpr(pWalker, pExpr->pRight) ) return WRC_Abort; if( ExprHasProperty(pExpr, EP_xIsSelect) ){ if( sqlite3WalkSelect(pWalker, pExpr->x.pSelect) ) return WRC_Abort; - }else{ + }else if( pExpr->x.pList ){ if( sqlite3WalkExprList(pWalker, pExpr->x.pList) ) return WRC_Abort; } return WRC_Continue; From c332cc30d9bb539d23329744779769827b189275 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 19 Sep 2016 10:24:19 +0000 Subject: [PATCH 0845/1484] Improved performance in sqlite3ExprCodeTarget(). FossilOrigin-Name: 75146165dcc1ae1faab46b1a7333ef795d5eeac5 --- manifest | 12 +++++------ manifest.uuid | 2 +- src/expr.c | 55 ++++++++++++++++++++++----------------------------- 3 files changed, 31 insertions(+), 38 deletions(-) diff --git a/manifest b/manifest index addc2705a4..46e31f7f79 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Small\sperformance\soptimization\sin\sthe\sexpression\swalker. -D 2016-09-19T02:19:00.600 +C Improved\sperformance\sin\ssqlite3ExprCodeTarget(). +D 2016-09-19T10:24:19.052 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e1aa788e84f926e42239ee167c53f785bedacacd @@ -339,7 +339,7 @@ F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7 F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c e91a11e0e86a13ce1917ca5ad7cf14c37ba31e59 -F src/expr.c 5f6c8263b021853aef5a43e920efebd0b94de394 +F src/expr.c f35e6c250bceaadc6a65e0c344e8f8bc398119e6 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c e2be0968c1adc679c87e467aa5b4f167588f38a8 F src/func.c 29cc9acb170ec1387b9f63eb52cd85f8de96c771 @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 6bf5ba10d28f1b0a32aa9a560ae3143a1235eadb -R 3576b7fe8bd045656543b2a44b86fd72 +P c6e6afb9391704d9119335f2ce17df3968acb514 +R 5e8eb1549d648015d64d5983cb2b67d7 U drh -Z 8bd385e2bfe7ba512e577302650c0d2b +Z f9a9936a11469969054ab3df81b2204c diff --git a/manifest.uuid b/manifest.uuid index 65b44f476e..fb2a91730a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c6e6afb9391704d9119335f2ce17df3968acb514 \ No newline at end of file +75146165dcc1ae1faab46b1a7333ef795d5eeac5 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 14bde45bb0..60eff846d0 100644 --- a/src/expr.c +++ b/src/expr.c @@ -3348,7 +3348,6 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ int regFree1 = 0; /* If non-zero free this temporary register */ int regFree2 = 0; /* If non-zero free this temporary register */ int r1, r2; /* Various register numbers */ - sqlite3 *db = pParse->db; /* The database connection */ Expr tempX; /* Temporary expression node */ int p5 = 0; @@ -3369,12 +3368,11 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ struct AggInfo_col *pCol = &pAggInfo->aCol[pExpr->iAgg]; if( !pAggInfo->directMode ){ assert( pCol->iMem>0 ); - inReg = pCol->iMem; - break; + return pCol->iMem; }else if( pAggInfo->useSortingIdx ){ sqlite3VdbeAddOp3(v, OP_Column, pAggInfo->sortingIdxPTab, pCol->iSorterColumn, target); - break; + return target; } /* Otherwise, fall thru into the TK_COLUMN case */ } @@ -3383,38 +3381,36 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ if( iTab<0 ){ if( pParse->ckBase>0 ){ /* Generating CHECK constraints or inserting into partial index */ - inReg = pExpr->iColumn + pParse->ckBase; - break; + return pExpr->iColumn + pParse->ckBase; }else{ /* Coding an expression that is part of an index where column names ** in the index refer to the table to which the index belongs */ iTab = pParse->iSelfTab; } } - inReg = sqlite3ExprCodeGetColumn(pParse, pExpr->pTab, + return sqlite3ExprCodeGetColumn(pParse, pExpr->pTab, pExpr->iColumn, iTab, target, pExpr->op2); - break; } case TK_INTEGER: { codeInteger(pParse, pExpr, 0, target); - break; + return target; } #ifndef SQLITE_OMIT_FLOATING_POINT case TK_FLOAT: { assert( !ExprHasProperty(pExpr, EP_IntValue) ); codeReal(v, pExpr->u.zToken, 0, target); - break; + return target; } #endif case TK_STRING: { assert( !ExprHasProperty(pExpr, EP_IntValue) ); sqlite3VdbeLoadString(v, target, pExpr->u.zToken); - break; + return target; } case TK_NULL: { sqlite3VdbeAddOp2(v, OP_Null, 0, target); - break; + return target; } #ifndef SQLITE_OMIT_BLOB_LITERAL case TK_BLOB: { @@ -3429,7 +3425,7 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ assert( z[n]=='\'' ); zBlob = sqlite3HexToBlob(sqlite3VdbeDb(v), z, n); sqlite3VdbeAddOp4(v, OP_Blob, n/2, target, 0, zBlob, P4_DYNAMIC); - break; + return target; } #endif case TK_VARIABLE: { @@ -3442,11 +3438,10 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ || strcmp(pExpr->u.zToken, pParse->azVar[pExpr->iColumn-1])==0 ); sqlite3VdbeChangeP4(v, -1, pParse->azVar[pExpr->iColumn-1], P4_STATIC); } - break; + return target; } case TK_REGISTER: { - inReg = pExpr->iTable; - break; + return pExpr->iTable; } #ifndef SQLITE_OMIT_CAST case TK_CAST: { @@ -3460,7 +3455,7 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ sqlite3AffinityType(pExpr->u.zToken, 0)); testcase( usedAsColumnCache(pParse, inReg, inReg) ); sqlite3ExprCacheAffinityChange(pParse, inReg, 1); - break; + return inReg; } #endif /* SQLITE_OMIT_CAST */ case TK_IS: @@ -3528,10 +3523,12 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ assert( pLeft ); if( pLeft->op==TK_INTEGER ){ codeInteger(pParse, pLeft, 1, target); + return target; #ifndef SQLITE_OMIT_FLOATING_POINT }else if( pLeft->op==TK_FLOAT ){ assert( !ExprHasProperty(pExpr, EP_IntValue) ); codeReal(v, pLeft->u.zToken, 1, target); + return target; #endif }else{ tempX.op = TK_INTEGER; @@ -3542,7 +3539,6 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ sqlite3VdbeAddOp3(v, OP_Subtract, r2, r1, target); testcase( regFree2==0 ); } - inReg = target; break; } case TK_BITNOT: @@ -3551,7 +3547,6 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ assert( TK_NOT==OP_Not ); testcase( op==TK_NOT ); r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); testcase( regFree1==0 ); - inReg = target; sqlite3VdbeAddOp2(v, op, r1, inReg); break; } @@ -3576,7 +3571,7 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ assert( !ExprHasProperty(pExpr, EP_IntValue) ); sqlite3ErrorMsg(pParse, "misuse of aggregate: %s()", pExpr->u.zToken); }else{ - inReg = pInfo->aFunc[pExpr->iAgg].iMem; + return pInfo->aFunc[pExpr->iAgg].iMem; } break; } @@ -3587,6 +3582,7 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ const char *zId; /* The function name */ u32 constMask = 0; /* Mask of function arguments that are constant */ int i; /* Loop counter */ + sqlite3 *db = pParse->db; /* The database connection */ u8 enc = ENC(db); /* The text encoding used by this database */ CollSeq *pColl = 0; /* A collating sequence */ @@ -3635,8 +3631,7 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ */ if( pDef->funcFlags & SQLITE_FUNC_UNLIKELY ){ assert( nFarg>=1 ); - inReg = sqlite3ExprCodeTarget(pParse, pFarg->a[0].pExpr, target); - break; + return sqlite3ExprCodeTarget(pParse, pFarg->a[0].pExpr, target); } for(i=0; ix.pSelect->pEList->nExpr)!=1 ){ sqlite3SubselectError(pParse, nCol, 1); }else{ - inReg = sqlite3CodeSubselect(pParse, pExpr, 0, 0); + return sqlite3CodeSubselect(pParse, pExpr, 0, 0); } break; } @@ -3730,8 +3725,7 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ if( pExpr->pLeft->iTable==0 ){ pExpr->pLeft->iTable = sqlite3CodeSubselect(pParse, pExpr->pLeft, 0, 0); } - inReg = pExpr->pLeft->iTable + pExpr->iColumn; - break; + return pExpr->pLeft->iTable + pExpr->iColumn; } case TK_IN: { int destIfFalse = sqlite3VdbeMakeLabel(v); @@ -3742,7 +3736,7 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ sqlite3VdbeResolveLabel(v, destIfFalse); sqlite3VdbeAddOp2(v, OP_AddImm, target, 0); sqlite3VdbeResolveLabel(v, destIfNull); - break; + return target; } #endif /* SQLITE_OMIT_SUBQUERY */ @@ -3760,13 +3754,12 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ */ case TK_BETWEEN: { exprCodeBetween(pParse, pExpr, target, 0, 0); - break; + return target; } case TK_SPAN: case TK_COLLATE: case TK_UPLUS: { - inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target); - break; + return sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target); } case TK_TRIGGER: { @@ -3908,7 +3901,7 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ }else{ sqlite3VdbeAddOp2(v, OP_Null, 0, target); } - assert( db->mallocFailed || pParse->nErr>0 + assert( pParse->db->mallocFailed || pParse->nErr>0 || pParse->iCacheLevel==iCacheLevel ); sqlite3VdbeResolveLabel(v, endLabel); break; From 9a2e5169a4c8c3fa75537733993961584084ae42 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 19 Sep 2016 11:00:42 +0000 Subject: [PATCH 0846/1484] Fix a segfault introduced by the row-value enhancement that comes up on a skip-scan where the first term of the index is unconstrained and the second term is of the form "columm IN (SELECT...)". FossilOrigin-Name: 2401ea5acfeee8042489d1db38036ff86e8a6916 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/where.c | 2 +- test/skipscan1.test | 15 +++++++++++++++ 4 files changed, 24 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 46e31f7f79..4cfe2cc045 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improved\sperformance\sin\ssqlite3ExprCodeTarget(). -D 2016-09-19T10:24:19.052 +C Fix\sa\ssegfault\sintroduced\sby\sthe\srow-value\senhancement\sthat\scomes\sup\son\na\sskip-scan\swhere\sthe\sfirst\sterm\sof\sthe\sindex\sis\sunconstrained\sand\sthe\nsecond\sterm\sis\sof\sthe\sform\s"columm\sIN\s(SELECT...)". +D 2016-09-19T11:00:42.662 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e1aa788e84f926e42239ee167c53f785bedacacd @@ -467,7 +467,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 02eeecc265f6ffd0597378f5d8ae9070b62a406a F src/wal.h 6dd221ed384afdc204bc61e25c23ef7fd5a511f2 F src/walker.c 83042807db1a27175fcb39be8f3e2a839dbdddb2 -F src/where.c d0ca1b5e1c56249e7725cea66ce4e172c5845dec +F src/where.c e4140408b81539cf9298355138a3749164dfd6a2 F src/whereInt.h 14dd243e13b81cbb0a66063d38b70f93a7d6e613 F src/wherecode.c e412e09abad1eea213d85594cf46db9f877db56d F src/whereexpr.c e3db778ed205e982f31960896db71c50612ae009 @@ -1089,7 +1089,7 @@ F test/shortread1.test bb591ef20f0fd9ed26d0d12e80eee6d7ac8897a3 F test/show_speedtest1_rtree.tcl 32e6c5f073d7426148a6936a0408f4b5b169aba5 F test/shrink.test 1b4330b1fd9e818c04726d45cb28db73087535ce F test/sidedelete.test f0ad71abe6233e3b153100f3b8d679b19a488329 -F test/skipscan1.test f2d4482f195f018c3732374d3985fc34bcc3ae1a +F test/skipscan1.test 8ab5d2c7c5cd3fe7f172d366e6e74e887cb33cb4 F test/skipscan2.test d1d1450952b7275f0b0a3a981f0230532743951a F test/skipscan3.test ec5bab3f81c7038b43450e7b3062e04a198bdbb5 F test/skipscan5.test 67817a4b6857c47e0e33ba3e506da6f23ef68de2 @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P c6e6afb9391704d9119335f2ce17df3968acb514 -R 5e8eb1549d648015d64d5983cb2b67d7 +P 75146165dcc1ae1faab46b1a7333ef795d5eeac5 +R 6570c4faac186baff77a196a1b23d589 U drh -Z f9a9936a11469969054ab3df81b2204c +Z c8f046879d40b5e9b9c03ef1eccd7de3 diff --git a/manifest.uuid b/manifest.uuid index fb2a91730a..316a029f4b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -75146165dcc1ae1faab46b1a7333ef795d5eeac5 \ No newline at end of file +2401ea5acfeee8042489d1db38036ff86e8a6916 \ No newline at end of file diff --git a/src/where.c b/src/where.c index 527698320f..0af935ff02 100644 --- a/src/where.c +++ b/src/where.c @@ -2410,7 +2410,7 @@ static int whereLoopAddBtreeIndex( ** for each such term. The following loop checks that pTerm is the ** first such term in use, and sets nIn back to 0 if it is not. */ for(i=0; inLTerm-1; i++){ - if( pNew->aLTerm[i]->pExpr==pExpr ) nIn = 0; + if( pNew->aLTerm[i] && pNew->aLTerm[i]->pExpr==pExpr ) nIn = 0; } }else if( ALWAYS(pExpr->x.pList && pExpr->x.pList->nExpr) ){ /* "x IN (value, value, ...)" */ diff --git a/test/skipscan1.test b/test/skipscan1.test index 6d77e63498..6cdeed5439 100644 --- a/test/skipscan1.test +++ b/test/skipscan1.test @@ -322,4 +322,19 @@ do_execsql_test skipscan1-8.2 { ORDER BY +x; } {1 AB 2 CD} +# Segfault reported on the mailing list by Keith Medcalf on 2016-09-18. +# A skip-scan with a "column IN (SELECT ...)" on the second term of the +# index. +# +do_execsql_test skipscan1-9.2 { + CREATE TABLE t9a(a,b,c); + CREATE INDEX t9a_ab ON t9a(a,b); + CREATE TABLE t9b(x,y); + ANALYZE sqlite_master; + INSERT INTO sqlite_stat1 VALUES('t9a','t9a_ab','1000000 250000 1'); + ANALYZE sqlite_master; + EXPLAIN QUERY PLAN + SELECT * FROM t9a WHERE b IN (SELECT x FROM t9b WHERE y!=5); +} {/USING INDEX t9a_ab .ANY.a. AND b=./} + finish_test From fadd2b197216f5a708029f709db4751db48b8212 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 19 Sep 2016 23:39:34 +0000 Subject: [PATCH 0847/1484] Very small optimization in the bytecode engine. FossilOrigin-Name: 46002511e52518bae14f210157f231c814c77c9e --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 10 +++++----- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 4cfe2cc045..666dc578cf 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\ssegfault\sintroduced\sby\sthe\srow-value\senhancement\sthat\scomes\sup\son\na\sskip-scan\swhere\sthe\sfirst\sterm\sof\sthe\sindex\sis\sunconstrained\sand\sthe\nsecond\sterm\sis\sof\sthe\sform\s"columm\sIN\s(SELECT...)". -D 2016-09-19T11:00:42.662 +C Very\ssmall\soptimization\sin\sthe\sbytecode\sengine. +D 2016-09-19T23:39:34.157 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e1aa788e84f926e42239ee167c53f785bedacacd @@ -453,7 +453,7 @@ F src/update.c 8179e699dbd45b92934fd02d3d8e3732e8da8802 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 810ec3f22e2d1b62e66c30fe3621ebdedd23584d F src/vacuum.c 913970b9d86dd6c2b8063ef1af421880f1464ec3 -F src/vdbe.c cdac9f8c53e2992816809a45910ff33b6122c191 +F src/vdbe.c c21ff59ffcd6e3e208d1e9525f58ae1fc373c8f4 F src/vdbe.h c044be7050ac6bf596eecc6ab159f5dbc020a3b7 F src/vdbeInt.h d21f14721dd87975dc9e3bcdbf504f9c098cf611 F src/vdbeapi.c a32d61b7dd05e6890d8fd44d2805f55e2f5ba9f3 @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 75146165dcc1ae1faab46b1a7333ef795d5eeac5 -R 6570c4faac186baff77a196a1b23d589 +P 2401ea5acfeee8042489d1db38036ff86e8a6916 +R 683f7035193075e0587f69a387a06ae5 U drh -Z c8f046879d40b5e9b9c03ef1eccd7de3 +Z 09002a4c4dfbbe09b9e7daa54e91e112 diff --git a/manifest.uuid b/manifest.uuid index 316a029f4b..ffc0180f5a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2401ea5acfeee8042489d1db38036ff86e8a6916 \ No newline at end of file +46002511e52518bae14f210157f231c814c77c9e \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 51092cfedb..13c20c462e 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -3176,12 +3176,12 @@ case OP_Transaction: { rc = sqlite3BtreeBeginTrans(pBt, pOp->p2); testcase( rc==SQLITE_BUSY_SNAPSHOT ); testcase( rc==SQLITE_BUSY_RECOVERY ); - if( (rc&0xff)==SQLITE_BUSY ){ - p->pc = (int)(pOp - aOp); - p->rc = rc; - goto vdbe_return; - } if( rc!=SQLITE_OK ){ + if( (rc&0xff)==SQLITE_BUSY ){ + p->pc = (int)(pOp - aOp); + p->rc = rc; + goto vdbe_return; + } goto abort_due_to_error; } From 8aaf7bcc8d7cbd03d66f34202f6f25a9c19bf8be Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 20 Sep 2016 01:19:18 +0000 Subject: [PATCH 0848/1484] Avoid unnecessary calls to ExpandBlob() for smaller and faster code. FossilOrigin-Name: 5e196fd18169e84806cd45dd1a8190339323e772 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/vdbe.c | 7 +++---- src/vdbeaux.c | 19 ++++++++++++++----- src/vdbemem.c | 18 +++++++++--------- 5 files changed, 35 insertions(+), 27 deletions(-) diff --git a/manifest b/manifest index 666dc578cf..e95af47544 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Very\ssmall\soptimization\sin\sthe\sbytecode\sengine. -D 2016-09-19T23:39:34.157 +C Avoid\sunnecessary\scalls\sto\sExpandBlob()\sfor\ssmaller\sand\sfaster\scode. +D 2016-09-20T01:19:18.064 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e1aa788e84f926e42239ee167c53f785bedacacd @@ -453,13 +453,13 @@ F src/update.c 8179e699dbd45b92934fd02d3d8e3732e8da8802 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 810ec3f22e2d1b62e66c30fe3621ebdedd23584d F src/vacuum.c 913970b9d86dd6c2b8063ef1af421880f1464ec3 -F src/vdbe.c c21ff59ffcd6e3e208d1e9525f58ae1fc373c8f4 +F src/vdbe.c 373b186a945cb69acfd6b3f53d43a3e72120ac8f F src/vdbe.h c044be7050ac6bf596eecc6ab159f5dbc020a3b7 F src/vdbeInt.h d21f14721dd87975dc9e3bcdbf504f9c098cf611 F src/vdbeapi.c a32d61b7dd05e6890d8fd44d2805f55e2f5ba9f3 -F src/vdbeaux.c 66054df369ca76530b6b84e6fce2f847dc99a9b1 +F src/vdbeaux.c b9772e4134a17f5b42d32761f5119467815c2458 F src/vdbeblob.c 3e82a797b60c3b9fed7b8de8c539ca7607874937 -F src/vdbemem.c 357caac1a404f37ee6087b17613f92107c13f733 +F src/vdbemem.c 813e7847fdbf165ab3fcb5ff4f6f04a0b0cca166 F src/vdbesort.c 91fda3909326860382b0ca8aa251e609c6a9d62c F src/vdbetrace.c 41963d5376f0349842b5fc4aaaaacd7d9cdc0834 F src/vtab.c e02cacb5c7ae742631edeb9ae9f53d399f093fd8 @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 2401ea5acfeee8042489d1db38036ff86e8a6916 -R 683f7035193075e0587f69a387a06ae5 +P 46002511e52518bae14f210157f231c814c77c9e +R 571b30401865528a2fb45b091bacd258 U drh -Z 09002a4c4dfbbe09b9e7daa54e91e112 +Z a7955a17fb1911f183df0a2e3aedb1bf diff --git a/manifest.uuid b/manifest.uuid index ffc0180f5a..248399f0c0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -46002511e52518bae14f210157f231c814c77c9e \ No newline at end of file +5e196fd18169e84806cd45dd1a8190339323e772 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 13c20c462e..0cd0147f5e 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -3872,7 +3872,6 @@ case OP_SeekGT: { /* jump, in3 */ #ifdef SQLITE_DEBUG { int i; for(i=0; iuc.pCursor, &r, 0, 0, &res); if( rc!=SQLITE_OK ){ @@ -4013,13 +4012,13 @@ case OP_Found: { /* jump, in3 */ r.pKeyInfo = pC->pKeyInfo; r.nField = (u16)pOp->p4.i; r.aMem = pIn3; +#ifdef SQLITE_DEBUG for(ii=0; iip3+ii, &r.aMem[ii]); -#endif } +#endif pIdxKey = &r; }else{ pIdxKey = sqlite3VdbeAllocUnpackedRecord( diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 838a8f0446..43f235c7bd 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -3712,10 +3712,12 @@ static int vdbeCompareMemString( ** The input pBlob is guaranteed to be a Blob that is not marked ** with MEM_Zero. Return true if it could be a zero-blob. */ -static int isZeroBlob(const Mem *pBlob){ +static int isAllZero(const char *z, int n){ int i; - for(i=0; in && pBlob->z[i]==0; i++){} - return i==pBlob->n; + for(i=0; iflags & pB2->flags & MEM_Zero ){ return pB1->u.nZero - pB2->u.nZero; }else if( pB1->flags & MEM_Zero ){ - if( !isZeroBlob(pB2) ) return -1; + if( !isAllZero(pB2->z, pB2->n) ) return -1; return pB1->u.nZero - n2; }else{ - if( !isZeroBlob(pB1) ) return +1; + if( !isAllZero(pB1->z, pB1->n) ) return +1; return n1 - pB2->u.nZero; } } @@ -4054,6 +4056,7 @@ int sqlite3VdbeRecordCompareWithSkip( /* RHS is a blob */ else if( pRhs->flags & MEM_Blob ){ + assert( (pRhs->flags & MEM_Zero)==0 || pRhs->n==0 ); getVarint32(&aKey1[idx1], serial_type); testcase( serial_type==12 ); if( serial_type<12 || (serial_type & 0x01) ){ @@ -4065,6 +4068,12 @@ int sqlite3VdbeRecordCompareWithSkip( if( (d1+nStr) > (unsigned)nKey1 ){ pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT; return 0; /* Corruption */ + }else if( pRhs->flags & MEM_Zero ){ + if( !isAllZero((const char*)&aKey1[d1],nStr) ){ + rc = 1; + }else{ + rc = nStr - pRhs->u.nZero; + } }else{ int nCmp = MIN(nStr, pRhs->n); rc = memcmp(&aKey1[d1], pRhs->z, nCmp); diff --git a/src/vdbemem.c b/src/vdbemem.c index ca6e480d13..efc4a97220 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -189,18 +189,18 @@ int sqlite3VdbeMemClearAndResize(Mem *pMem, int szNew){ ** Return SQLITE_OK on success or SQLITE_NOMEM if malloc fails. */ int sqlite3VdbeMemMakeWriteable(Mem *pMem){ - int f; assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); assert( (pMem->flags&MEM_RowSet)==0 ); - (void)ExpandBlob(pMem); - f = pMem->flags; - if( (f&(MEM_Str|MEM_Blob)) && (pMem->szMalloc==0 || pMem->z!=pMem->zMalloc) ){ - if( sqlite3VdbeMemGrow(pMem, pMem->n + 2, 1) ){ - return SQLITE_NOMEM_BKPT; + if( (pMem->flags & (MEM_Str|MEM_Blob))!=0 ){ + if( ExpandBlob(pMem) ) return SQLITE_NOMEM; + if( pMem->szMalloc==0 || pMem->z!=pMem->zMalloc ){ + if( sqlite3VdbeMemGrow(pMem, pMem->n + 2, 1) ){ + return SQLITE_NOMEM_BKPT; + } + pMem->z[pMem->n] = 0; + pMem->z[pMem->n+1] = 0; + pMem->flags |= MEM_Term; } - pMem->z[pMem->n] = 0; - pMem->z[pMem->n+1] = 0; - pMem->flags |= MEM_Term; } pMem->flags &= ~MEM_Ephem; #ifdef SQLITE_DEBUG From ff535a2499dd11e7ba31dfc2454d0e70538e8fde Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 20 Sep 2016 01:46:15 +0000 Subject: [PATCH 0849/1484] Further performance enhancements in zeroblob() handling. FossilOrigin-Name: 21b0e3b75c531a5ce33a1503f9bf647d56f56a5b --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/vdbeapi.c | 4 ++-- src/vdbemem.c | 33 ++++++++++++++++----------------- 4 files changed, 26 insertions(+), 27 deletions(-) diff --git a/manifest b/manifest index e95af47544..effd7a0084 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sunnecessary\scalls\sto\sExpandBlob()\sfor\ssmaller\sand\sfaster\scode. -D 2016-09-20T01:19:18.064 +C Further\sperformance\senhancements\sin\szeroblob()\shandling. +D 2016-09-20T01:46:15.590 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e1aa788e84f926e42239ee167c53f785bedacacd @@ -456,10 +456,10 @@ F src/vacuum.c 913970b9d86dd6c2b8063ef1af421880f1464ec3 F src/vdbe.c 373b186a945cb69acfd6b3f53d43a3e72120ac8f F src/vdbe.h c044be7050ac6bf596eecc6ab159f5dbc020a3b7 F src/vdbeInt.h d21f14721dd87975dc9e3bcdbf504f9c098cf611 -F src/vdbeapi.c a32d61b7dd05e6890d8fd44d2805f55e2f5ba9f3 +F src/vdbeapi.c 1e0505f6a5495c47180eb2e3535a9779f42e72d6 F src/vdbeaux.c b9772e4134a17f5b42d32761f5119467815c2458 F src/vdbeblob.c 3e82a797b60c3b9fed7b8de8c539ca7607874937 -F src/vdbemem.c 813e7847fdbf165ab3fcb5ff4f6f04a0b0cca166 +F src/vdbemem.c 07874c2ac7c05f7df1ededc6ec6650c1339b2cad F src/vdbesort.c 91fda3909326860382b0ca8aa251e609c6a9d62c F src/vdbetrace.c 41963d5376f0349842b5fc4aaaaacd7d9cdc0834 F src/vtab.c e02cacb5c7ae742631edeb9ae9f53d399f093fd8 @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 46002511e52518bae14f210157f231c814c77c9e -R 571b30401865528a2fb45b091bacd258 +P 5e196fd18169e84806cd45dd1a8190339323e772 +R ee2363badf872b5d247f72b61c66fd19 U drh -Z a7955a17fb1911f183df0a2e3aedb1bf +Z c2808bd7f59f43e75d8ebdcaeda29a11 diff --git a/manifest.uuid b/manifest.uuid index 248399f0c0..95cc9b7c55 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5e196fd18169e84806cd45dd1a8190339323e772 \ No newline at end of file +21b0e3b75c531a5ce33a1503f9bf647d56f56a5b \ No newline at end of file diff --git a/src/vdbeapi.c b/src/vdbeapi.c index 3d36413bc4..937424843c 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -169,7 +169,7 @@ int sqlite3_clear_bindings(sqlite3_stmt *pStmt){ const void *sqlite3_value_blob(sqlite3_value *pVal){ Mem *p = (Mem*)pVal; if( p->flags & (MEM_Blob|MEM_Str) ){ - if( sqlite3VdbeMemExpandBlob(p)!=SQLITE_OK ){ + if( ExpandBlob(p)!=SQLITE_OK ){ assert( p->flags==MEM_Null && p->z==0 ); return 0; } @@ -1775,7 +1775,7 @@ int sqlite3_preupdate_new(sqlite3 *db, int iIdx, sqlite3_value **ppValue){ UnpackedRecord *pUnpack = p->pNewUnpacked; if( !pUnpack ){ Mem *pData = &p->v->aMem[p->iNewReg]; - rc = sqlite3VdbeMemExpandBlob(pData); + rc = ExpandBlob(pData); if( rc!=SQLITE_OK ) goto preupdate_new_out; pUnpack = vdbeUnpackRecord(&p->keyinfo, pData->n, pData->z); if( !pUnpack ){ diff --git a/src/vdbemem.c b/src/vdbemem.c index efc4a97220..b03aa49702 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -216,25 +216,24 @@ int sqlite3VdbeMemMakeWriteable(Mem *pMem){ */ #ifndef SQLITE_OMIT_INCRBLOB int sqlite3VdbeMemExpandBlob(Mem *pMem){ - if( pMem->flags & MEM_Zero ){ - int nByte; - assert( pMem->flags&MEM_Blob ); - assert( (pMem->flags&MEM_RowSet)==0 ); - assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); + int nByte; + assert( pMem->flags & MEM_Zero ); + assert( pMem->flags&MEM_Blob ); + assert( (pMem->flags&MEM_RowSet)==0 ); + assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); - /* Set nByte to the number of bytes required to store the expanded blob. */ - nByte = pMem->n + pMem->u.nZero; - if( nByte<=0 ){ - nByte = 1; - } - if( sqlite3VdbeMemGrow(pMem, nByte, 1) ){ - return SQLITE_NOMEM_BKPT; - } - - memset(&pMem->z[pMem->n], 0, pMem->u.nZero); - pMem->n += pMem->u.nZero; - pMem->flags &= ~(MEM_Zero|MEM_Term); + /* Set nByte to the number of bytes required to store the expanded blob. */ + nByte = pMem->n + pMem->u.nZero; + if( nByte<=0 ){ + nByte = 1; } + if( sqlite3VdbeMemGrow(pMem, nByte, 1) ){ + return SQLITE_NOMEM_BKPT; + } + + memset(&pMem->z[pMem->n], 0, pMem->u.nZero); + pMem->n += pMem->u.nZero; + pMem->flags &= ~(MEM_Zero|MEM_Term); return SQLITE_OK; } #endif From e0736da15af7900b2b02a94b1c473b256ba0148b Mon Sep 17 00:00:00 2001 From: mistachkin Date: Tue, 20 Sep 2016 17:38:27 +0000 Subject: [PATCH 0850/1484] Fix typo in comment. FossilOrigin-Name: bd3ecbb5c1977744321f4bbac79fd7e2e7c1b5ba --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/main.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index effd7a0084..fd4ac3aec7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Further\sperformance\senhancements\sin\szeroblob()\shandling. -D 2016-09-20T01:46:15.590 +C Fix\stypo\sin\scomment. +D 2016-09-20T17:38:27.015 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e1aa788e84f926e42239ee167c53f785bedacacd @@ -351,7 +351,7 @@ F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 F src/insert.c 427e96ff168b6b187a52c3d06b9f9e41f6ffb212 F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e F src/loadext.c 5d6642d141c07d366e43d359e94ec9de47add41d -F src/main.c 14fb66eeb2eea477f9e79434fde3cca3aff0ea5c +F src/main.c c9e49e376820bccca55fa9bf2ca321a51725db91 F src/malloc.c 1443d1ad95d67c21d77af7ae3f44678252f0efec F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 5e196fd18169e84806cd45dd1a8190339323e772 -R ee2363badf872b5d247f72b61c66fd19 -U drh -Z c2808bd7f59f43e75d8ebdcaeda29a11 +P 21b0e3b75c531a5ce33a1503f9bf647d56f56a5b +R fbaf699c28d2338be6d855595b47c382 +U mistachkin +Z 7b8f55268a7563995859b0e14fe9f0a8 diff --git a/manifest.uuid b/manifest.uuid index 95cc9b7c55..2bc2f07a64 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -21b0e3b75c531a5ce33a1503f9bf647d56f56a5b \ No newline at end of file +bd3ecbb5c1977744321f4bbac79fd7e2e7c1b5ba \ No newline at end of file diff --git a/src/main.c b/src/main.c index 9c161d0ef5..392a0042e9 100644 --- a/src/main.c +++ b/src/main.c @@ -3785,7 +3785,7 @@ int sqlite3_test_control(int op, ...){ } /* Set the threshold at which OP_Once counters reset back to zero. - ** By default this is 0xfffffffe (over 2 billion), but that value is + ** By default this is 0x7ffffffe (over 2 billion), but that value is ** too big to test in a reasonable amount of time, so this control is ** provided to set a small and easily reachable reset value. */ From d8992cef36568fcc8b42e5c3c6e4bc7999d8b7db Mon Sep 17 00:00:00 2001 From: mistachkin Date: Tue, 20 Sep 2016 17:49:01 +0000 Subject: [PATCH 0851/1484] Fix harmless compiler warning. FossilOrigin-Name: 72429063956614975d90cae2a829cfa4296694da --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 8 ++++---- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index fd4ac3aec7..01075f300f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\stypo\sin\scomment. -D 2016-09-20T17:38:27.015 +C Fix\sharmless\scompiler\swarning. +D 2016-09-20T17:49:01.524 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e1aa788e84f926e42239ee167c53f785bedacacd @@ -453,7 +453,7 @@ F src/update.c 8179e699dbd45b92934fd02d3d8e3732e8da8802 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 810ec3f22e2d1b62e66c30fe3621ebdedd23584d F src/vacuum.c 913970b9d86dd6c2b8063ef1af421880f1464ec3 -F src/vdbe.c 373b186a945cb69acfd6b3f53d43a3e72120ac8f +F src/vdbe.c 0f87994593787575a4a23f932d27cb4588477436 F src/vdbe.h c044be7050ac6bf596eecc6ab159f5dbc020a3b7 F src/vdbeInt.h d21f14721dd87975dc9e3bcdbf504f9c098cf611 F src/vdbeapi.c 1e0505f6a5495c47180eb2e3535a9779f42e72d6 @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 21b0e3b75c531a5ce33a1503f9bf647d56f56a5b -R fbaf699c28d2338be6d855595b47c382 +P bd3ecbb5c1977744321f4bbac79fd7e2e7c1b5ba +R 9c6c154d94d3544c30252d0eac8d5092 U mistachkin -Z 7b8f55268a7563995859b0e14fe9f0a8 +Z a981fdc618d99724c0721b182be1e085 diff --git a/manifest.uuid b/manifest.uuid index 2bc2f07a64..66c1131d07 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bd3ecbb5c1977744321f4bbac79fd7e2e7c1b5ba \ No newline at end of file +72429063956614975d90cae2a829cfa4296694da \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 0cd0147f5e..3965a012fa 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -6859,10 +6859,10 @@ case OP_Init: { /* jump */ #ifdef SQLITE_USE_FCNTL_TRACE zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql); if( zTrace ){ - int i; - for(i=0; inDb; i++){ - if( DbMaskTest(p->btreeMask, i)==0 ) continue; - sqlite3_file_control(db, db->aDb[i].zDbSName, SQLITE_FCNTL_TRACE, zTrace); + int j; + for(j=0; jnDb; j++){ + if( DbMaskTest(p->btreeMask, j)==0 ) continue; + sqlite3_file_control(db, db->aDb[j].zDbSName, SQLITE_FCNTL_TRACE, zTrace); } } #endif /* SQLITE_USE_FCNTL_TRACE */ From 09952c6490fb1004055bd4a1c83d85fa781da1f2 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 20 Sep 2016 22:04:05 +0000 Subject: [PATCH 0852/1484] Improved implementation of 64-bit signed integer multiply that correctly detects overflow (and promotes to floating-point) in some corner cases. Fix for ticket [1ec41379c9c1e400] FossilOrigin-Name: db3ebd7c52cfc5fcc7be00f52e9d7c84719f7b93 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/util.c | 37 +++++++++++-------------------------- test/expr.test | 27 +++++++++++++++++++++++++++ 4 files changed, 47 insertions(+), 35 deletions(-) diff --git a/manifest b/manifest index 01075f300f..df03ff132c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\scompiler\swarning. -D 2016-09-20T17:49:01.524 +C Improved\simplementation\sof\s64-bit\ssigned\sinteger\smultiply\sthat\scorrectly\ndetects\soverflow\s(and\spromotes\sto\sfloating-point)\sin\ssome\scorner\scases.\nFix\sfor\sticket\s[1ec41379c9c1e400] +D 2016-09-20T22:04:05.970 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e1aa788e84f926e42239ee167c53f785bedacacd @@ -451,7 +451,7 @@ F src/treeview.c f51b75a28b377adde9f79bc3deb6c7770bcf97c0 F src/trigger.c 3419bb9862983d84d70735fb4c94b21b934cd0c5 F src/update.c 8179e699dbd45b92934fd02d3d8e3732e8da8802 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c -F src/util.c 810ec3f22e2d1b62e66c30fe3621ebdedd23584d +F src/util.c 3e2da6101888d073e79ecc6af5e0a2f70fa1e498 F src/vacuum.c 913970b9d86dd6c2b8063ef1af421880f1464ec3 F src/vdbe.c 0f87994593787575a4a23f932d27cb4588477436 F src/vdbe.h c044be7050ac6bf596eecc6ab159f5dbc020a3b7 @@ -675,7 +675,7 @@ F test/exclusive.test 9a57bd66e39144b888ca75c309914fcdefb4e3f9 F test/exclusive2.test 32798111aae78a5deec980eee383213f189df308 F test/exec.test e949714dc127eaa5ecc7d723efec1ec27118fdd7 F test/exists.test 79a75323c78f02bbe9c251ea502a092f9ef63dac -F test/expr.test 79c3e7502d9e571553b85f0ecc8ff2ac7d0e4931 +F test/expr.test 66a2c9ac34f74f036faa4092f5402c7d3162fc93 F test/extension01.test 00d13cec817f331a687a243e0e5a2d87b0e358c9 F test/extraquick.test cb254400bd42bfb777ff675356aabf3287978f79 F test/fallocate.test 3e979af17dfa7e5e9dda5eba1a696c04fa9d47f7 @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P bd3ecbb5c1977744321f4bbac79fd7e2e7c1b5ba -R 9c6c154d94d3544c30252d0eac8d5092 -U mistachkin -Z a981fdc618d99724c0721b182be1e085 +P 72429063956614975d90cae2a829cfa4296694da +R 91d60e6e7ebec7104f81d972c645f360 +U drh +Z 545cfa3e1675ae70fe7fd8b14cbd5249 diff --git a/manifest.uuid b/manifest.uuid index 66c1131d07..55a4112105 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -72429063956614975d90cae2a829cfa4296694da \ No newline at end of file +db3ebd7c52cfc5fcc7be00f52e9d7c84719f7b93 \ No newline at end of file diff --git a/src/util.c b/src/util.c index db6163c3c7..e18b847578 100644 --- a/src/util.c +++ b/src/util.c @@ -1305,36 +1305,21 @@ int sqlite3SubInt64(i64 *pA, i64 iB){ return sqlite3AddInt64(pA, -iB); } } -#define TWOPOWER32 (((i64)1)<<32) -#define TWOPOWER31 (((i64)1)<<31) int sqlite3MulInt64(i64 *pA, i64 iB){ i64 iA = *pA; - i64 iA1, iA0, iB1, iB0, r; - - iA1 = iA/TWOPOWER32; - iA0 = iA % TWOPOWER32; - iB1 = iB/TWOPOWER32; - iB0 = iB % TWOPOWER32; - if( iA1==0 ){ - if( iB1==0 ){ - *pA *= iB; - return 0; + if( iB>0 ){ + if( iA>LARGEST_INT64/iB ) return 1; + if( iA0 ){ + if( iBLARGEST_INT64/-iB ) return 1; } - r = iA0*iB1; - }else if( iB1==0 ){ - r = iA1*iB0; - }else{ - /* If both iA1 and iB1 are non-zero, overflow will result */ - return 1; } - testcase( r==(-TWOPOWER31)-1 ); - testcase( r==(-TWOPOWER31) ); - testcase( r==TWOPOWER31 ); - testcase( r==TWOPOWER31-1 ); - if( r<(-TWOPOWER31) || r>=TWOPOWER31 ) return 1; - r *= TWOPOWER32; - if( sqlite3AddInt64(&r, iA0*iB0) ) return 1; - *pA = r; + *pA = iA*iB; return 0; } diff --git a/test/expr.test b/test/expr.test index 7d7b8ce5a7..7a6d477259 100644 --- a/test/expr.test +++ b/test/expr.test @@ -308,6 +308,33 @@ ifcapable floatingpoint {if {[working_64bit_int]} { test_realnum_expr expr-1.257\ {i1=-4294967296, i2=-2147483647} {i1*i2} 9223372032559808512 + test_realnum_expr expr-1.260\ + {i1=3037000500, i2=3037000500} {i1*i2} 9.22337203700025e+18 + test_realnum_expr expr-1.261\ + {i1=3037000500, i2=-3037000500} {i1*i2} -9.22337203700025e+18 + test_realnum_expr expr-1.262\ + {i1=-3037000500, i2=3037000500} {i1*i2} -9.22337203700025e+18 + test_realnum_expr expr-1.263\ + {i1=-3037000500, i2=-3037000500} {i1*i2} 9.22337203700025e+18 + + test_realnum_expr expr-1.264\ + {i1=3037000500, i2=3037000499} {i1*i2} 9223372033963249500 + test_realnum_expr expr-1.265\ + {i1=3037000500, i2=-3037000499} {i1*i2} -9223372033963249500 + test_realnum_expr expr-1.266\ + {i1=-3037000500, i2=3037000499} {i1*i2} -9223372033963249500 + test_realnum_expr expr-1.267\ + {i1=-3037000500, i2=-3037000499} {i1*i2} 9223372033963249500 + + test_realnum_expr expr-1.268\ + {i1=3037000499, i2=3037000500} {i1*i2} 9223372033963249500 + test_realnum_expr expr-1.269\ + {i1=3037000499, i2=-3037000500} {i1*i2} -9223372033963249500 + test_realnum_expr expr-1.270\ + {i1=-3037000499, i2=3037000500} {i1*i2} -9223372033963249500 + test_realnum_expr expr-1.271\ + {i1=-3037000499, i2=-3037000500} {i1*i2} 9223372033963249500 + }} ifcapable floatingpoint { From 48a72ebfa3c1587b5de7ec2809791dbf1e3f3936 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 21 Sep 2016 14:41:09 +0000 Subject: [PATCH 0853/1484] Update the fts5vocab table to handle "ORDER BY term" efficiently. FossilOrigin-Name: d4928fb5cd63a72808f01778fa5a11395385dedf --- ext/fts5/fts5_vocab.c | 13 +++++++++++- ext/fts5/test/fts5vocab.test | 38 +++++++++++++++++++++++++++++++++++- manifest | 16 +++++++-------- manifest.uuid | 2 +- 4 files changed, 58 insertions(+), 11 deletions(-) diff --git a/ext/fts5/fts5_vocab.c b/ext/fts5/fts5_vocab.c index f3a2381cc1..82c7dc9056 100644 --- a/ext/fts5/fts5_vocab.c +++ b/ext/fts5/fts5_vocab.c @@ -279,8 +279,19 @@ static int fts5VocabBestIndexMethod( } } - pInfo->idxNum = idxNum; + /* This virtual table always delivers results in ascending order of + ** the "term" column (column 0). So if the user has requested this + ** specifically - "ORDER BY term" or "ORDER BY term ASC" - set the + ** sqlite3_index_info.orderByConsumed flag to tell the core the results + ** are already in sorted order. */ + if( pInfo->nOrderBy==1 + && pInfo->aOrderBy[0].iColumn==0 + && pInfo->aOrderBy[0].desc==0 + ){ + pInfo->orderByConsumed = 1; + } + pInfo->idxNum = idxNum; return SQLITE_OK; } diff --git a/ext/fts5/test/fts5vocab.test b/ext/fts5/test/fts5vocab.test index f7278dd5c1..5e0499fbf9 100644 --- a/ext/fts5/test/fts5vocab.test +++ b/ext/fts5/test/fts5vocab.test @@ -442,8 +442,44 @@ if {[detail_is_none]} { } sqlite3_fts5_may_be_corrupt 0 - } +#------------------------------------------------------------------------- +# Test that both "ORDER BY term" and "ORDER BY term DESC" work. +# +reset_db +do_execsql_test 9.1 { + CREATE VIRTUAL TABLE x1 USING fts5(x); + INSERT INTO x1 VALUES('def ABC ghi'); + INSERT INTO x1 VALUES('DEF abc GHI'); +} + +do_execsql_test 9.2 { + CREATE VIRTUAL TABLE rrr USING fts5vocab(x1, row); + SELECT * FROM rrr +} { + abc 2 2 def 2 2 ghi 2 2 +} +do_execsql_test 9.3 { + SELECT * FROM rrr ORDER BY term ASC +} { + abc 2 2 def 2 2 ghi 2 2 +} +do_execsql_test 9.4 { + SELECT * FROM rrr ORDER BY term DESC +} { + ghi 2 2 def 2 2 abc 2 2 +} +do_test 9.5 { + set e2 [db eval { EXPLAIN SELECT * FROM rrr ORDER BY term ASC }] + expr [lsearch $e2 SorterSort]<0 +} 1 +do_test 9.6 { + set e2 [db eval { EXPLAIN SELECT * FROM rrr ORDER BY term DESC }] + expr [lsearch $e2 SorterSort]<0 +} 0 + + + finish_test diff --git a/manifest b/manifest index df03ff132c..9a46ee79a8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improved\simplementation\sof\s64-bit\ssigned\sinteger\smultiply\sthat\scorrectly\ndetects\soverflow\s(and\spromotes\sto\sfloating-point)\sin\ssome\scorner\scases.\nFix\sfor\sticket\s[1ec41379c9c1e400] -D 2016-09-20T22:04:05.970 +C Update\sthe\sfts5vocab\stable\sto\shandle\s"ORDER\sBY\sterm"\sefficiently. +D 2016-09-21T14:41:09.595 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e1aa788e84f926e42239ee167c53f785bedacacd @@ -113,7 +113,7 @@ F ext/fts5/fts5_test_tok.c db08af63673c3a7d39f053b36fd6e065017706be F ext/fts5/fts5_tokenize.c 2ce7b44183538ec46b7907726262ee43ffdd39a8 F ext/fts5/fts5_unicode2.c b450b209b157d598f7b9df9f837afb75a14c24bf F ext/fts5/fts5_varint.c a5aceacda04dafcbae725413d7a16818ecd65738 -F ext/fts5/fts5_vocab.c dba72ca393d71c2588548b51380387f6b44c77a8 +F ext/fts5/fts5_vocab.c e44fefa7f0c1db252998af071daf06a7147e17e7 F ext/fts5/fts5parse.y e51b375403421b8b37428a89b095d00597129aae F ext/fts5/mkportersteps.tcl 5acf962d2e0074f701620bb5308155fa1e4a63ba F ext/fts5/test/fts5_common.tcl b01c584144b5064f30e6c648145a2dd6bc440841 @@ -195,7 +195,7 @@ F ext/fts5/test/fts5unicode3.test 35c3d02aa7acf7d43d8de3bfe32c15ba96e8928e F ext/fts5/test/fts5unindexed.test e9539d5b78c677315e7ed8ea911d4fd25437c680 F ext/fts5/test/fts5update.test 57c7012a7919889048947addae10e0613df45529 F ext/fts5/test/fts5version.test 978f59541d8cef7e8591f8be2115ec5ccb863e2e -F ext/fts5/test/fts5vocab.test 480d780aa6b699816c5066225fbd86f3a0239477 +F ext/fts5/test/fts5vocab.test 026799f8d24befc452cbddda79822f5ae8d5f4eb F ext/fts5/tool/fts5speed.tcl b0056f91a55b2d1a3684ec05729de92b042e2f85 F ext/fts5/tool/fts5txt2db.tcl 526a9979c963f1c54fd50976a05a502e533a4c59 F ext/fts5/tool/loadfts5.tcl 95b03429ee6b138645703c6ca192c3ac96eaf093 @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 72429063956614975d90cae2a829cfa4296694da -R 91d60e6e7ebec7104f81d972c645f360 -U drh -Z 545cfa3e1675ae70fe7fd8b14cbd5249 +P db3ebd7c52cfc5fcc7be00f52e9d7c84719f7b93 +R b069306c2d67148a9ccacc36a85fb205 +U dan +Z 47d40874d45f38572688cc85bd002b66 diff --git a/manifest.uuid b/manifest.uuid index 55a4112105..adc77774f6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -db3ebd7c52cfc5fcc7be00f52e9d7c84719f7b93 \ No newline at end of file +d4928fb5cd63a72808f01778fa5a11395385dedf \ No newline at end of file From b3906816227ff8469014ce255f6becfa63b331f6 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 21 Sep 2016 17:47:59 +0000 Subject: [PATCH 0854/1484] Do not run test "delete_db.test" with either the journaltest or inmemoryjournal permutations. Ensure that the multiplexor tests in delete_db.test are performed in non-autovacuum mode. FossilOrigin-Name: 46b7d19e0282ecd7622344aafad8c2feb83c9658 --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/delete_db.test | 5 ++++- test/permutations.test | 4 ++++ 4 files changed, 16 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 9a46ee79a8..229d6af165 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\sthe\sfts5vocab\stable\sto\shandle\s"ORDER\sBY\sterm"\sefficiently. -D 2016-09-21T14:41:09.595 +C Do\snot\srun\stest\s"delete_db.test"\swith\seither\sthe\sjournaltest\sor\sinmemoryjournal\spermutations.\sEnsure\sthat\sthe\smultiplexor\stests\sin\sdelete_db.test\sare\sperformed\sin\snon-autovacuum\smode. +D 2016-09-21T17:47:59.373 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e1aa788e84f926e42239ee167c53f785bedacacd @@ -632,7 +632,7 @@ F test/delete.test acc38fca8ee4851467705b1c2cfea64cd26667e5 F test/delete2.test 3a03f2cca1f9a67ec469915cb8babd6485db43fa F test/delete3.test 555e84a00a99230b7d049d477a324a631126a6ab F test/delete4.test 21d2113217eeaacac2d99defe14fe6611615ae86 -F test/delete_db.test 906fb709bd71443c2484dcf24b05a21d125d149f +F test/delete_db.test c70a43629dd4d3e1dd03fdaf7a22153af6a69d92 F test/descidx1.test 6d03b44c8538fe0eb4924e19fba10cdd8f3c9240 F test/descidx2.test 9f1a0c83fd57f8667c82310ca21b30a350888b5d F test/descidx3.test 09ddbe3f5295f482d2f8b687cf6db8bad7acd9a2 @@ -994,7 +994,7 @@ F test/parser1.test 391b9bf9a229547a129c61ac345ed1a6f5eb1854 F test/pcache.test c8acbedd3b6fd0f9a7ca887a83b11d24a007972b F test/pcache2.test af7f3deb1a819f77a6d0d81534e97d1cf62cd442 F test/percentile.test 4243af26b8f3f4555abe166f723715a1f74c77ff -F test/permutations.test 544a2f317fc5045bc512ae432f89eae303c0d640 +F test/permutations.test cd0b7bc04bf5e50d3a993d24c834d591f7d4f5fe F test/pragma.test 1e94755164a3a3264cd39836de4bebcb7809e5f8 F test/pragma2.test e5d5c176360c321344249354c0c16aec46214c9f F test/pragma3.test 14c12bc5352b1e100e0b6b44f371053a81ccf8ed @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P db3ebd7c52cfc5fcc7be00f52e9d7c84719f7b93 -R b069306c2d67148a9ccacc36a85fb205 +P d4928fb5cd63a72808f01778fa5a11395385dedf +R 655565020380644d43819ad1f36a9dcb U dan -Z 47d40874d45f38572688cc85bd002b66 +Z a8ea3044081061bc4f0bce028e9eb24e diff --git a/manifest.uuid b/manifest.uuid index adc77774f6..684dc2a297 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d4928fb5cd63a72808f01778fa5a11395385dedf \ No newline at end of file +46b7d19e0282ecd7622344aafad8c2feb83c9658 \ No newline at end of file diff --git a/test/delete_db.test b/test/delete_db.test index 520d4f94b3..09c44ff9f3 100644 --- a/test/delete_db.test +++ b/test/delete_db.test @@ -9,7 +9,8 @@ # #*********************************************************************** # This file implements regression tests for SQLite library. The -# focus of this file is testing the DELETE FROM statement. +# focus of this file is testing the code in test_delete.c (the +# sqlite3_delete_database() API). # set testdir [file dirname $argv0] @@ -85,6 +86,7 @@ sqlite3 db test2.database -vfs multiplex sqlite3_multiplex_control db "main" chunk_size 32768 do_test 1.3.0 { + execsql { PRAGMA auto_vacuum = 0; } execsql { CREATE TABLE x1(a, b); WITH s(i) AS ( VALUES(1) UNION ALL SELECT i+1 FROM s WHERE i<1000 ) @@ -164,6 +166,7 @@ ifcapable 8_3_names { sqlite3_multiplex_control db "main" chunk_size 32768 do_test 2.3.0 { + execsql { PRAGMA auto_vacuum = 0; } execsql { CREATE TABLE x1(a, b); WITH s(i) AS ( VALUES(1) UNION ALL SELECT i+1 FROM s WHERE i<1000 ) diff --git a/test/permutations.test b/test/permutations.test index f4784cfcee..f8880da225 100644 --- a/test/permutations.test +++ b/test/permutations.test @@ -751,6 +751,9 @@ test_suite "inmemory_journal" -description { # statement switches the database out of wal mode at inopportune # times. snapshot_fault.test + + # This test assumes a journal file is created on disk. + delete_db.test }] ifcapable mem3 { @@ -950,6 +953,7 @@ test_suite "journaltest" -description { async4.test bigfile.test backcompat.test e_wal* fstat.test mmap2.test pager1.test syscall.test tkt3457.test *malloc* mmap* multiplex* nolock* pager2.test *fault* rowal* snapshot* superlock* symlink.test + delete_db.test }] if {[info commands register_demovfs] != ""} { From b6ea12cc05dc96da371a810b3162a6007c19a2a2 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 21 Sep 2016 17:53:47 +0000 Subject: [PATCH 0855/1484] Avoid running vacuum5.test in auto-vacuum mode. FossilOrigin-Name: be184befa09ef0a670a2a6d9c037b9a27bcf16d8 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/vacuum5.test | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 229d6af165..2cc2486a1f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Do\snot\srun\stest\s"delete_db.test"\swith\seither\sthe\sjournaltest\sor\sinmemoryjournal\spermutations.\sEnsure\sthat\sthe\smultiplexor\stests\sin\sdelete_db.test\sare\sperformed\sin\snon-autovacuum\smode. -D 2016-09-21T17:47:59.373 +C Avoid\srunning\svacuum5.test\sin\sauto-vacuum\smode. +D 2016-09-21T17:53:47.044 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e1aa788e84f926e42239ee167c53f785bedacacd @@ -1341,7 +1341,7 @@ F test/vacuum.test ce91c39f7f91a4273bf620efad21086b5aa6ef1d F test/vacuum2.test aa048abee196c16c9ba308465494009057b79f9b F test/vacuum3.test 77ecdd54592b45a0bcb133339f99f1ae0ae94d0d F test/vacuum4.test d3f8ecff345f166911568f397d2432c16d2867d9 -F test/vacuum5.test d233412f76026a3ea2244aef36e5eb1bac15f8ad +F test/vacuum5.test 0b7ac80c64eed657b4ce2dd6535092c0d6afec6c F test/vacuummem.test e53a3fdca4612a99c515e1afe7934728a2383764 F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102 F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661 @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d4928fb5cd63a72808f01778fa5a11395385dedf -R 655565020380644d43819ad1f36a9dcb +P 46b7d19e0282ecd7622344aafad8c2feb83c9658 +R 52ea72a55c53720654feb8ce2a5edfe7 U dan -Z a8ea3044081061bc4f0bce028e9eb24e +Z ff2ee29d4ccdec9258ea2f36b3b3b38f diff --git a/manifest.uuid b/manifest.uuid index 684dc2a297..7e83fdad9e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -46b7d19e0282ecd7622344aafad8c2feb83c9658 \ No newline at end of file +be184befa09ef0a670a2a6d9c037b9a27bcf16d8 \ No newline at end of file diff --git a/test/vacuum5.test b/test/vacuum5.test index 6d28686107..16b15b64a1 100644 --- a/test/vacuum5.test +++ b/test/vacuum5.test @@ -25,6 +25,7 @@ ifcapable !vacuum { forcedelete test2.db test3.db do_execsql_test vacuum5-1.1 { + PRAGMA auto_vacuum = 0; CREATE TABLE main.t1(a,b); WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<1000) INSERT INTO t1(a,b) SELECT x, randomblob(1000) FROM c; From fb04a36c201cd757f54327ade1e06913ab7c2667 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 21 Sep 2016 18:18:57 +0000 Subject: [PATCH 0856/1484] Fix obsolete requirements marks. Add new tests for VACUUM of attached databases. FossilOrigin-Name: 2b44f9aa7d4e2089dacd6bfcf526dae9309b7af3 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- test/e_fkey.test | 8 ++++---- test/e_vacuum.test | 15 ++++++++++----- 4 files changed, 23 insertions(+), 18 deletions(-) diff --git a/manifest b/manifest index 2cc2486a1f..287b43b575 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\srunning\svacuum5.test\sin\sauto-vacuum\smode. -D 2016-09-21T17:53:47.044 +C Fix\sobsolete\srequirements\smarks.\s\sAdd\snew\stests\sfor\sVACUUM\sof\sattached\ndatabases. +D 2016-09-21T18:18:57.867 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e1aa788e84f926e42239ee167c53f785bedacacd @@ -649,7 +649,7 @@ F test/e_delete.test ab39084f26ae1f033c940b70ebdbbd523dc4962e F test/e_droptrigger.test 3cd080807622c13e5bbb61fc9a57bd7754da2412 F test/e_dropview.test 0c9f7f60989164a70a67a9d9c26d1083bc808306 F test/e_expr.test 1ffa8866d38e7becc76893a8829e9432050e5716 -F test/e_fkey.test a1783fe1f759e1990e6a11adfcf0702dac4d0707 +F test/e_fkey.test 54cc0046d2d952d6c42b0dd94414e7a8f75f79f4 F test/e_fts3.test 5c02288842e4f941896fd44afdef564dd5fc1459 F test/e_insert.test 3de217e95094d3d165992a6de1164bbc4bd92dc7 F test/e_reindex.test 2bebf7b393e519198b7c654407221cf171a439b8 @@ -659,7 +659,7 @@ F test/e_select2.test aceb80ab927d46fba5ce7586ebabf23e2bb0604f F test/e_totalchanges.test b12ee5809d3e63aeb83238dd501a7bca7fd72c10 F test/e_update.test f46c2554d915c9197548681e8d8c33a267e84528 F test/e_uri.test 25385396082b67fd02ae0038b95a3b3575fe0519 -F test/e_vacuum.test 9e5e47e4059a779c777f47e0f560fc82c99336df +F test/e_vacuum.test 1b8b4772d05374aa1b8958669138bbb4213ee26a F test/e_wal.test ae9a593207a77d711443ee69ffe081fda9243625 F test/e_walauto.test 248af31e73c98df23476a22bdb815524c9dc3ba8 F test/e_walckpt.test 28c371a6bb5e5fe7f31679c1df1763a19d19e8a0 @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 46b7d19e0282ecd7622344aafad8c2feb83c9658 -R 52ea72a55c53720654feb8ce2a5edfe7 -U dan -Z ff2ee29d4ccdec9258ea2f36b3b3b38f +P be184befa09ef0a670a2a6d9c037b9a27bcf16d8 +R 917601953ec7e55d80d40cade2c4b996 +U drh +Z b7cd3201e204cce2362e565e0603d566 diff --git a/manifest.uuid b/manifest.uuid index 7e83fdad9e..6077f76f84 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -be184befa09ef0a670a2a6d9c037b9a27bcf16d8 \ No newline at end of file +2b44f9aa7d4e2089dacd6bfcf526dae9309b7af3 \ No newline at end of file diff --git a/test/e_fkey.test b/test/e_fkey.test index 09756505c3..99f1ae8e62 100644 --- a/test/e_fkey.test +++ b/test/e_fkey.test @@ -52,11 +52,11 @@ ifcapable trigger&&foreignkey { #------------------------------------------------------------------------- # Test the effects of defining OMIT_TRIGGER but not OMIT_FOREIGN_KEY. # -# EVIDENCE-OF: R-44697-61543 If SQLITE_OMIT_TRIGGER is defined but +# EVIDENCE-OF: R-10109-20452 If SQLITE_OMIT_TRIGGER is defined but # SQLITE_OMIT_FOREIGN_KEY is not, then SQLite behaves as it did prior to -# version 3.6.19 - foreign key definitions are parsed and may be queried -# using PRAGMA foreign_key_list, but foreign key constraints are not -# enforced. +# version 3.6.19 (2009-10-14) - foreign key definitions are parsed and +# may be queried using PRAGMA foreign_key_list, but foreign key +# constraints are not enforced. # # Specifically, test that "PRAGMA foreign_keys" is a no-op in this case. # When using the pragma to query the current setting, 0 rows are returned. diff --git a/test/e_vacuum.test b/test/e_vacuum.test index 5bb2e9dbf0..3fd34afd43 100644 --- a/test/e_vacuum.test +++ b/test/e_vacuum.test @@ -190,8 +190,8 @@ if {![nonzero_reserved_bytes]} { } } -# EVIDENCE-OF: R-38001-03952 VACUUM only works on the main database. It -# is not possible to VACUUM an attached database file. +# EVIDENCE-OF: R-55119-57913 By default, VACUUM only works only on the +# main database. forcedelete test.db2 create_db { PRAGMA auto_vacuum = NONE } do_execsql_test e_vacuum-2.1.1 { @@ -206,6 +206,11 @@ set original_size [file size test.db2] do_execsql_test e_vacuum-2.1.3 { VACUUM } {} do_test e_vacuum-2.1.6 { expr {[file size test.db2]==$::original_size} } 1 +# EVIDENCE-OF: R-36598-60500 Attached databases can be vacuumed by +# appending the appropriate schema-name to the VACUUM statement. +do_execsql_test e_vacuum-2.1.7 { VACUUM aux; } {} +do_test e_vacuum-2.1.8 { expr {[file size test.db2]<$::original_size} } 1 + # EVIDENCE-OF: R-17495-17419 The VACUUM command may change the ROWIDs of # entries in any tables that do not have an explicit INTEGER PRIMARY # KEY. @@ -267,9 +272,9 @@ do_test e_vacuum-3.2.2.1 { } {1 {cannot VACUUM - SQL statements in progress}} -# EVIDENCE-OF: R-38735-12540 As of SQLite version 3.1, an alternative to -# using the VACUUM command to reclaim space after data has been deleted -# is auto-vacuum mode, enabled using the auto_vacuum pragma. +# EVIDENCE-OF: R-55138-13241 An alternative to using the VACUUM command +# to reclaim space after data has been deleted is auto-vacuum mode, +# enabled using the auto_vacuum pragma. # do_test e_vacuum-3.3.1 { create_db { PRAGMA auto_vacuum = FULL } From 30f8c23657a60561c84e2cacc2c1503d4d741fc0 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 21 Sep 2016 19:00:37 +0000 Subject: [PATCH 0857/1484] Do not run vacuummem.test if ENABLE_MEMORY_MANAGEMENT is defined. FossilOrigin-Name: 4a613d856433ac48e8ee0cd7f0e774e484e8acf6 --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/vacuummem.test | 13 +++++++++++++ 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 287b43b575..d38a8e9735 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sobsolete\srequirements\smarks.\s\sAdd\snew\stests\sfor\sVACUUM\sof\sattached\ndatabases. -D 2016-09-21T18:18:57.867 +C Do\snot\srun\svacuummem.test\sif\sENABLE_MEMORY_MANAGEMENT\sis\sdefined. +D 2016-09-21T19:00:37.910 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e1aa788e84f926e42239ee167c53f785bedacacd @@ -1342,7 +1342,7 @@ F test/vacuum2.test aa048abee196c16c9ba308465494009057b79f9b F test/vacuum3.test 77ecdd54592b45a0bcb133339f99f1ae0ae94d0d F test/vacuum4.test d3f8ecff345f166911568f397d2432c16d2867d9 F test/vacuum5.test 0b7ac80c64eed657b4ce2dd6535092c0d6afec6c -F test/vacuummem.test e53a3fdca4612a99c515e1afe7934728a2383764 +F test/vacuummem.test 7b42abb3208bd82dd23a7536588396f295a314f2 F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102 F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661 F test/view.test 765802c7a66d37fabd5ac8e2f2dbe572b43eb9ab @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P be184befa09ef0a670a2a6d9c037b9a27bcf16d8 -R 917601953ec7e55d80d40cade2c4b996 -U drh -Z b7cd3201e204cce2362e565e0603d566 +P 2b44f9aa7d4e2089dacd6bfcf526dae9309b7af3 +R db79f70a5622e7667604a8f395c4feab +U dan +Z 3cf2a9a4785a48ab2e27ceae8a5f7a0d diff --git a/manifest.uuid b/manifest.uuid index 6077f76f84..9d88275fc2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2b44f9aa7d4e2089dacd6bfcf526dae9309b7af3 \ No newline at end of file +4a613d856433ac48e8ee0cd7f0e774e484e8acf6 \ No newline at end of file diff --git a/test/vacuummem.test b/test/vacuummem.test index b214c83b3d..0f77c1b400 100644 --- a/test/vacuummem.test +++ b/test/vacuummem.test @@ -22,6 +22,19 @@ if {[permutation]=="memsubsys1"} { return } +# If ENABLE_MEMORY_MANAGEMENT is defined, when VACUUM is run the temp db +# is able to borrow space from the main db (and it does, because the +# temp db is configure with a very small cache). When the VACUUM is +# finished and the temp db closed, all the page-cache memory currently +# assigned to the temp db is freed. If ENABLE_MEMORY_MANAGEMENT is defined +# this causes the total memory usage to drop much more than expected, +# causing tests in this file to fail. +# +ifcapable memorymanage { + finish_test + return +} + proc memory_used {} { set stat [sqlite3_status SQLITE_STATUS_MEMORY_USED 1] From 49377a8fb74528d8acb4346161aca5264e1b29c6 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 21 Sep 2016 19:43:34 +0000 Subject: [PATCH 0858/1484] Fix a problem with the fts5 auxiliary function API causing a crash when a query contained a phrase of zero terms. FossilOrigin-Name: 0741812d7fcd558479e4849fbb3ba8d03738d018 --- ext/fts5/fts5_expr.c | 39 ++++++++++++++++++++++----------------- ext/fts5/test/fts5eb.test | 17 +++++++++++++++++ manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 47 insertions(+), 25 deletions(-) diff --git a/ext/fts5/fts5_expr.c b/ext/fts5/fts5_expr.c index c8f649c7fd..ac3913d4e3 100644 --- a/ext/fts5/fts5_expr.c +++ b/ext/fts5/fts5_expr.c @@ -754,6 +754,7 @@ static int fts5ExprNearInitAll( Fts5ExprNearset *pNear = pNode->pNear; int i, j; int rc = SQLITE_OK; + int bEof = 1; assert( pNode->bNomatch==0 ); for(i=0; rc==SQLITE_OK && inPhrase; i++){ @@ -761,7 +762,6 @@ static int fts5ExprNearInitAll( for(j=0; jnTerm; j++){ Fts5ExprTerm *pTerm = &pPhrase->aTerm[j]; Fts5ExprTerm *p; - int bEof = 1; for(p=pTerm; p && rc==SQLITE_OK; p=p->pSynonym){ if( p->pIter ){ @@ -781,13 +781,12 @@ static int fts5ExprNearInitAll( } } - if( bEof ){ - pNode->bEof = 1; - return rc; - } + if( bEof ) break; } + if( bEof ) break; } + pNode->bEof = bEof; return rc; } @@ -1638,7 +1637,6 @@ int sqlite3Fts5ExprClonePhrase( ){ int rc = SQLITE_OK; /* Return code */ Fts5ExprPhrase *pOrig; /* The phrase extracted from pExpr */ - int i; /* Used to iterate through phrase terms */ Fts5Expr *pNew = 0; /* Expression to return via *ppNew */ TokenCtx sCtx = {0,0}; /* Context object for fts5ParseTokenize */ @@ -1668,18 +1666,25 @@ int sqlite3Fts5ExprClonePhrase( } } - for(i=0; rc==SQLITE_OK && inTerm; i++){ - int tflags = 0; - Fts5ExprTerm *p; - for(p=&pOrig->aTerm[i]; p && rc==SQLITE_OK; p=p->pSynonym){ - const char *zTerm = p->zTerm; - rc = fts5ParseTokenize((void*)&sCtx, tflags, zTerm, (int)strlen(zTerm), - 0, 0); - tflags = FTS5_TOKEN_COLOCATED; - } - if( rc==SQLITE_OK ){ - sCtx.pPhrase->aTerm[i].bPrefix = pOrig->aTerm[i].bPrefix; + if( pOrig->nTerm ){ + int i; /* Used to iterate through phrase terms */ + for(i=0; rc==SQLITE_OK && inTerm; i++){ + int tflags = 0; + Fts5ExprTerm *p; + for(p=&pOrig->aTerm[i]; p && rc==SQLITE_OK; p=p->pSynonym){ + const char *zTerm = p->zTerm; + rc = fts5ParseTokenize((void*)&sCtx, tflags, zTerm, (int)strlen(zTerm), + 0, 0); + tflags = FTS5_TOKEN_COLOCATED; + } + if( rc==SQLITE_OK ){ + sCtx.pPhrase->aTerm[i].bPrefix = pOrig->aTerm[i].bPrefix; + } } + }else{ + /* This happens when parsing a token or quoted phrase that contains + ** no token characters at all. (e.g ... MATCH '""'). */ + sCtx.pPhrase = sqlite3Fts5MallocZero(&rc, sizeof(Fts5ExprPhrase)); } if( rc==SQLITE_OK ){ diff --git a/ext/fts5/test/fts5eb.test b/ext/fts5/test/fts5eb.test index 69418aae63..510a0d790c 100644 --- a/ext/fts5/test/fts5eb.test +++ b/ext/fts5/test/fts5eb.test @@ -63,6 +63,23 @@ do_catchsql_test 2.1 { SELECT fts5_expr_tcl() } {1 {wrong number of arguments to function fts5_expr_tcl}} + +do_execsql_test 3.0 { + CREATE VIRTUAL TABLE e1 USING fts5(text, tokenize = 'porter unicode61'); + INSERT INTO e1 VALUES ("just a few words with a / inside"); +} +do_execsql_test 3.1 { + SELECT rowid, bm25(e1) FROM e1 WHERE e1 MATCH '"just"' ORDER BY rank; +} {1 -1e-06} +do_execsql_test 3.2 { + SELECT rowid FROM e1 WHERE e1 MATCH '"/" OR "just"' +} 1 +do_execsql_test 3.3 { + SELECT rowid, bm25(e1) FROM e1 WHERE e1 MATCH '"/" OR "just"' ORDER BY rank; +} {1 -1e-06} + + + finish_test diff --git a/manifest b/manifest index d38a8e9735..9ff357b93c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Do\snot\srun\svacuummem.test\sif\sENABLE_MEMORY_MANAGEMENT\sis\sdefined. -D 2016-09-21T19:00:37.910 +C Fix\sa\sproblem\swith\sthe\sfts5\sauxiliary\sfunction\sAPI\scausing\sa\scrash\swhen\sa\squery\scontained\sa\sphrase\sof\szero\sterms. +D 2016-09-21T19:43:34.002 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e1aa788e84f926e42239ee167c53f785bedacacd @@ -102,7 +102,7 @@ F ext/fts5/fts5Int.h b2eda36e0f224365c8e23dc8f559311834f1c13f F ext/fts5/fts5_aux.c 2f20784a344701d4c72986e2e692062dd47d568c F ext/fts5/fts5_buffer.c 4c1502d4c956cd092c89ce4480867f9d8bf325cd F ext/fts5/fts5_config.c 5af9c360e99669d29f06492c370892394aba0857 -F ext/fts5/fts5_expr.c 1ee97156421919e497595bfa962bb88ad1665401 +F ext/fts5/fts5_expr.c c65c5629f4b3a49850fd84ea0731dee2360e144f F ext/fts5/fts5_hash.c 880998e596b60f078348d48732ca4ad9a90caad2 F ext/fts5/fts5_index.c 2d146d5c547f60d22d6fc4014d5e2b64248cd7c4 F ext/fts5/fts5_main.c f85281445dcf8be32d18841c93a6f90fe27dbfe2 @@ -148,7 +148,7 @@ F ext/fts5/test/fts5determin.test 10648edb75ef1e196b10978fd21a9be0c31e09c3 F ext/fts5/test/fts5dlidx.test 007e9390c94638760797dbec2990c97c3fa08dfe F ext/fts5/test/fts5doclist.test 8edb5b57e5f144030ed74ec00ef6fa4294fed79b F ext/fts5/test/fts5ea.test b01e3a18cdfabbff8104a96a5242a06a68a998a0 -F ext/fts5/test/fts5eb.test c516ae0c934be6fd29ec95ea8b5f11f461311535 +F ext/fts5/test/fts5eb.test 14597b5ecc9b2b7039ac5e0b0fca0311a7d22005 F ext/fts5/test/fts5fault1.test e09040d3e17b8c0837101e8c79c8a874c4376fb7 F ext/fts5/test/fts5fault2.test d8c6c7f916ccbdfc10b2c69530e9dd3bc8313232 F ext/fts5/test/fts5fault3.test d6e9577d4312e331a913c72931bf131704efc8f3 @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 2b44f9aa7d4e2089dacd6bfcf526dae9309b7af3 -R db79f70a5622e7667604a8f395c4feab +P 4a613d856433ac48e8ee0cd7f0e774e484e8acf6 +R b3b313c63559d3f43c5fcc9e87b2dba1 U dan -Z 3cf2a9a4785a48ab2e27ceae8a5f7a0d +Z ee8b7750ac92f9eff66f8bc864927c4a diff --git a/manifest.uuid b/manifest.uuid index 9d88275fc2..fd49af75a4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4a613d856433ac48e8ee0cd7f0e774e484e8acf6 \ No newline at end of file +0741812d7fcd558479e4849fbb3ba8d03738d018 \ No newline at end of file From 98ef26b0d4476c5f97ac6b46c9526fbf3e39118f Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 21 Sep 2016 23:58:49 +0000 Subject: [PATCH 0859/1484] Fix speedtest1.c so that it works with SQLITE_OMIT_DEPRECATED. Add the --lean and --cachesize options to speed-check.sh. FossilOrigin-Name: 7785b3a25778cc19861c01f4148f72e0f724f55d --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- test/speedtest1.c | 4 ++++ tool/speed-check.sh | 19 +++++++++++++++++-- 4 files changed, 30 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 9ff357b93c..898a209040 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\swith\sthe\sfts5\sauxiliary\sfunction\sAPI\scausing\sa\scrash\swhen\sa\squery\scontained\sa\sphrase\sof\szero\sterms. -D 2016-09-21T19:43:34.002 +C Fix\sspeedtest1.c\sso\sthat\sit\sworks\swith\sSQLITE_OMIT_DEPRECATED.\nAdd\sthe\s--lean\sand\s--cachesize\soptions\sto\sspeed-check.sh. +D 2016-09-21T23:58:49.145 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e1aa788e84f926e42239ee167c53f785bedacacd @@ -1112,7 +1112,7 @@ F test/speed3.test 694affeb9100526007436334cf7d08f3d74b85ef F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715 F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b -F test/speedtest1.c 28221f433d358dd3fcf2ca504ed51409aa66ffaf +F test/speedtest1.c 43b25ae8e303bcada98e00be036e710de17d346a F test/spellfix.test f9c1f431e2c096c8775fec032952320c0e4700db F test/spellfix2.test dfc8f519a3fc204cb2dfa8b4f29821ae90f6f8c3 F test/spellfix3.test 0f9efaaa502a0e0a09848028518a6fb096c8ad33 @@ -1485,7 +1485,7 @@ F tool/showstat4.c bda40d6e395df7edb6e9ea630784d3d762c35b4b F tool/showwal.c ec79959834f7b21f1e0a2aa52bb7c056d2203977 F tool/soak1.tcl 8d407956e1a45b485a8e072470a3e629a27037fe F tool/spaceanal.tcl 85d90e6674d8298e3eaf82dbcef3abc2d5317f3e -F tool/speed-check.sh 45d3bf861b009993ff401f0d00e34a4cc937fce4 +F tool/speed-check.sh b6f8540db91bfd1fcfb53646bf657cf53ee03cd0 F tool/speedtest.tcl 06c76698485ccf597b9e7dbb1ac70706eb873355 F tool/speedtest16.c ecb6542862151c3e6509bbc00509b234562ae81e F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 4a613d856433ac48e8ee0cd7f0e774e484e8acf6 -R b3b313c63559d3f43c5fcc9e87b2dba1 -U dan -Z ee8b7750ac92f9eff66f8bc864927c4a +P 0741812d7fcd558479e4849fbb3ba8d03738d018 +R cbecff860fb3e1e414a3a9d25ae007ae +U drh +Z 82b45269186e0ae095502a5cdd8c1032 diff --git a/manifest.uuid b/manifest.uuid index fd49af75a4..a471e220b7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0741812d7fcd558479e4849fbb3ba8d03738d018 \ No newline at end of file +7785b3a25778cc19861c01f4148f72e0f724f55d \ No newline at end of file diff --git a/test/speedtest1.c b/test/speedtest1.c index c69c6d5fc5..7ae6739fff 100644 --- a/test/speedtest1.c +++ b/test/speedtest1.c @@ -421,12 +421,14 @@ void speedtest1_run(void){ speedtest1_shrink_memory(); } +#ifndef SQLITE_OMIT_DEPRECATED /* The sqlite3_trace() callback function */ static void traceCallback(void *NotUsed, const char *zSql){ int n = (int)strlen(zSql); while( n>0 && (zSql[n-1]==';' || ISSPACE(zSql[n-1])) ) n--; fprintf(stderr,"%.*s;\n", n, zSql); } +#endif /* SQLITE_OMIT_DEPRECATED */ /* Substitute random() function that gives the same random ** sequence on each run, for repeatability. */ @@ -1416,7 +1418,9 @@ int main(int argc, char **argv){ /* Set database connection options */ sqlite3_create_function(g.db, "random", 0, SQLITE_UTF8, 0, randomFunc, 0, 0); +#ifndef SQLITE_OMIT_DEPRECATED if( doTrace ) sqlite3_trace(g.db, traceCallback, 0); +#endif speedtest1_exec("PRAGMA threads=%d", nThread); if( zKey ){ speedtest1_exec("PRAGMA key('%s')", zKey); diff --git a/tool/speed-check.sh b/tool/speed-check.sh index d10f172d59..72753b9149 100644 --- a/tool/speed-check.sh +++ b/tool/speed-check.sh @@ -21,9 +21,18 @@ then fi NAME=$1 shift -CC_OPTS="-DSQLITE_ENABLE_RTREE -DSQLITE_ENABLE_MEMSYS5" -SPEEDTEST_OPTS="--shrink-memory --reprepare --heap 10000000 64" +#CC_OPTS="-DSQLITE_ENABLE_RTREE -DSQLITE_ENABLE_MEMSYS5" +CC_OPTS="-DSQLITE_ENABLE_MEMSYS5" +SPEEDTEST_OPTS="--shrink-memory --reprepare --stats --heap 10000000 64" SIZE=5 +LEAN_OPTS="-DSQLITE_THREADSAFE=0" +LEAN_OPTS="$LEAN_OPTS -DSQLITE_DEFAULT_MEMSTATUS=0" +LEAN_OPTS="$LEAN_OPTS -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1" +LEAN_OPTS="$LEAN_OPTS -DSQLITE_LIKE_DOESNT_MATCH_BLOB" +LEAN_OPTS="$LEAN_OPTS -DSQLITE_OMIT_DECLTYPE" +LEAN_OPTS="$LEAN_OPTS -DSQLITE_OMIT_DEPRECATED" +LEAN_OPTS="$LEAN_OPTS -DSQLITE_OMIT_PROGRESS_CALLBACK" +LEAN_OPTS="$LEAN_OPTS -DSQLITE_OMIT_SHARED_CACHE" doExplain=0 doCachegrind=1 while test "$1" != ""; do @@ -55,6 +64,9 @@ while test "$1" != ""; do --size) shift; SIZE=$1 ;; + --cachesize) + shift; SPEEDTEST_OPTS="$SPEEDTEST_OPTS --cachesize $1" + ;; --explain) doExplain=1 ;; @@ -63,6 +75,9 @@ while test "$1" != ""; do CC_OPTS="$CC_OPTS -DVDBE_PROFILE" doCachegrind=0 ;; + --lean) + CC_OPTS="$CC_OPTS $LEAN_OPTS" + ;; --heap) CC_OPTS="$CC_OPTS -DSQLITE_ENABLE_MEMSYS5" shift; From 511f9e8d29925fd2b68318df516102b8662f4778 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 22 Sep 2016 18:53:13 +0000 Subject: [PATCH 0860/1484] Remove the internal sqlite3CodeOnce() interface, replacing it with a direct call to sqlite3VdbeAddOp0(v,OP_Once). Slightly smaller and faster. FossilOrigin-Name: c3774c6a5fe48af91fda28e9e18c6ed9053ea992 --- manifest | 23 +++++++++++------------ manifest.uuid | 2 +- src/delete.c | 2 +- src/expr.c | 15 +++------------ src/select.c | 4 ++-- src/sqliteInt.h | 1 - src/where.c | 2 +- 7 files changed, 19 insertions(+), 30 deletions(-) diff --git a/manifest b/manifest index 2528c3d19e..ec0fb230b0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Makefile\schanges\sto\ssupport\sbuilding\swinsqlite3.dll\susing\sSTDCALL\srather\sthan\sCDECL. -D 2016-09-22T18:46:38.171 +C Remove\sthe\sinternal\ssqlite3CodeOnce()\sinterface,\sreplacing\sit\swith\sa\ndirect\scall\sto\ssqlite3VdbeAddOp0(v,OP_Once).\s\sSlightly\ssmaller\sand\sfaster. +D 2016-09-22T18:53:13.560 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -338,8 +338,8 @@ F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7 F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d -F src/delete.c e91a11e0e86a13ce1917ca5ad7cf14c37ba31e59 -F src/expr.c f35e6c250bceaadc6a65e0c344e8f8bc398119e6 +F src/delete.c cb3f6300df24c26c609778b2731f82644b5532ec +F src/expr.c 471ca87aa3b176548814a332172848015f13d823 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c e2be0968c1adc679c87e467aa5b4f167588f38a8 F src/func.c 29cc9acb170ec1387b9f63eb52cd85f8de96c771 @@ -386,12 +386,12 @@ F src/printf.c a5f0ca08ddede803c241266abb46356ec748ded1 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c 3c3cf0dc719cd2a32ab5c1e10c26481dd565492e F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac -F src/select.c 244f9cc5e4662987cd2ef5c22d1b7027560f3425 +F src/select.c fb9da69a36382cf9cf57fb7a93247bf3de5a81ae F src/shell.c b80396d2fadce4681397707e30078bf416e1dec2 F src/sqlite.h.in 2683a291ed8db5228024267be6421f0de507b80e F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae -F src/sqliteInt.h 1abb4501bbc28c9badf0ebc1e99bd66585ba04f0 +F src/sqliteInt.h e7c39dc148cd38b947cbdd482986afba3fe9ef22 F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 @@ -467,7 +467,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 02eeecc265f6ffd0597378f5d8ae9070b62a406a F src/wal.h 6dd221ed384afdc204bc61e25c23ef7fd5a511f2 F src/walker.c 83042807db1a27175fcb39be8f3e2a839dbdddb2 -F src/where.c e4140408b81539cf9298355138a3749164dfd6a2 +F src/where.c 5f91be9fe122e847c4e72d54d3989eb32a927981 F src/whereInt.h 14dd243e13b81cbb0a66063d38b70f93a7d6e613 F src/wherecode.c e412e09abad1eea213d85594cf46db9f877db56d F src/whereexpr.c e3db778ed205e982f31960896db71c50612ae009 @@ -1525,8 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 7785b3a25778cc19861c01f4148f72e0f724f55d 20f3c7436f6a8a7bab3968adc010c7c8325e4618 -R 72cc550b3f8e650b8595781f4d1f9482 -T +closed 20f3c7436f6a8a7bab3968adc010c7c8325e4618 -U mistachkin -Z ffa47cef2805fb0d684496ef32d8ed25 +P 5e892d60935e5c82234d1bfaef4c5026061acceb +R 4a98fd5ad20cf7ad4821bfd13a964ce7 +U drh +Z 0d81e518bb5c5c1a02f800fff5730756 diff --git a/manifest.uuid b/manifest.uuid index 414281e5da..3aff546e20 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5e892d60935e5c82234d1bfaef4c5026061acceb \ No newline at end of file +c3774c6a5fe48af91fda28e9e18c6ed9053ea992 \ No newline at end of file diff --git a/src/delete.c b/src/delete.c index 74ffd584a1..ec85718246 100644 --- a/src/delete.c +++ b/src/delete.c @@ -473,7 +473,7 @@ void sqlite3DeleteFrom( if( !isView ){ int iAddrOnce = 0; if( eOnePass==ONEPASS_MULTI ){ - iAddrOnce = sqlite3CodeOnce(pParse); VdbeCoverage(v); + iAddrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); } testcase( IsVirtual(pTab) ); sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, OPFLAG_FORDELETE, diff --git a/src/expr.c b/src/expr.c index 60eff846d0..195fe43955 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1968,15 +1968,6 @@ static Select *isCandidateForInOpt(Expr *pX){ } #endif /* SQLITE_OMIT_SUBQUERY */ -/* -** Code an OP_Once instruction and allocate space for its flag. Return the -** address of the new instruction. -*/ -int sqlite3CodeOnce(Parse *pParse){ - Vdbe *v = sqlite3GetVdbe(pParse); /* Virtual machine being coded */ - return sqlite3VdbeAddOp0(v, OP_Once); -} - #ifndef SQLITE_OMIT_SUBQUERY /* ** Generate code that checks the left-most column of index table iCur to see if @@ -2150,7 +2141,7 @@ int sqlite3FindInIndex( assert(v); /* sqlite3GetVdbe() has always been previously called */ if( nExpr==1 && pEList->a[0].pExpr->iColumn<0 ){ /* The "x IN (SELECT rowid FROM table)" case */ - int iAddr = sqlite3CodeOnce(pParse); + int iAddr = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead); @@ -2233,7 +2224,7 @@ int sqlite3FindInIndex( assert( i==nExpr || colUsed!=(MASKBIT(nExpr)-1) ); if( colUsed==(MASKBIT(nExpr)-1) ){ /* If we reach this point, that means the index pIdx is usable */ - int iAddr = sqlite3CodeOnce(pParse); VdbeCoverage(v); + int iAddr = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); #ifndef SQLITE_OMIT_EXPLAIN sqlite3VdbeAddOp4(v, OP_Explain, 0, 0, 0, sqlite3MPrintf(db, "USING INDEX %s FOR IN-OPERATOR",pIdx->zName), @@ -2408,7 +2399,7 @@ int sqlite3CodeSubselect( ** save the results, and reuse the same result on subsequent invocations. */ if( !ExprHasProperty(pExpr, EP_VarSelect) ){ - jmpIfDynamic = sqlite3CodeOnce(pParse); VdbeCoverage(v); + jmpIfDynamic = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); } #ifndef SQLITE_OMIT_EXPLAIN diff --git a/src/select.c b/src/select.c index 2d4e901ba4..6e4f4b99ed 100644 --- a/src/select.c +++ b/src/select.c @@ -1232,7 +1232,7 @@ static void generateSortTail( int regSortOut = ++pParse->nMem; iSortTab = pParse->nTab++; if( pSort->labelBkOut ){ - addrOnce = sqlite3CodeOnce(pParse); VdbeCoverage(v); + addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); } sqlite3VdbeAddOp3(v, OP_OpenPseudo, iSortTab, regSortOut, nKey+1+nSortData); if( addrOnce ) sqlite3VdbeJumpHere(v, addrOnce); @@ -5027,7 +5027,7 @@ int sqlite3Select( /* If the subquery is not correlated and if we are not inside of ** a trigger, then we only need to compute the value of the subquery ** once. */ - onceAddr = sqlite3CodeOnce(pParse); VdbeCoverage(v); + onceAddr = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); VdbeComment((v, "materialize \"%s\"", pItem->pTab->zName)); }else{ VdbeNoopComment((v, "materialize \"%s\"", pItem->pTab->zName)); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index ebae7e54ab..6d736b47a6 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3583,7 +3583,6 @@ void sqlite3EndTable(Parse*,Token*,Token*,u8,Select*); int sqlite3ParseUri(const char*,const char*,unsigned int*, sqlite3_vfs**,char**,char **); Btree *sqlite3DbNameToBtree(sqlite3*,const char*); -int sqlite3CodeOnce(Parse *); #ifdef SQLITE_OMIT_BUILTIN_TEST # define sqlite3FaultSim(X) SQLITE_OK diff --git a/src/where.c b/src/where.c index 0af935ff02..785c13be78 100644 --- a/src/where.c +++ b/src/where.c @@ -651,7 +651,7 @@ static void constructAutomaticIndex( ** transient index on 2nd and subsequent iterations of the loop. */ v = pParse->pVdbe; assert( v!=0 ); - addrInit = sqlite3CodeOnce(pParse); VdbeCoverage(v); + addrInit = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); /* Count the number of columns that will be added to the index ** and used to match WHERE clause constraints */ From 28f17017ee2ffdc6e52452b1b8f473c38e5e14ab Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 22 Sep 2016 21:37:18 +0000 Subject: [PATCH 0861/1484] Fix a potential null-pointer dereference and crash in the case where one thread is calling sqlite3_column_text() and another thread is calling sqlite3_step() on the same prepared statement at the same instant. FossilOrigin-Name: ee1382a36303eff8d94275ac3b12e5ce398ee620 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbeapi.c | 13 +++++++------ 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index ec0fb230b0..31f00c98b9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sthe\sinternal\ssqlite3CodeOnce()\sinterface,\sreplacing\sit\swith\sa\ndirect\scall\sto\ssqlite3VdbeAddOp0(v,OP_Once).\s\sSlightly\ssmaller\sand\sfaster. -D 2016-09-22T18:53:13.560 +C Fix\sa\spotential\snull-pointer\sdereference\sand\scrash\sin\sthe\scase\swhere\sone\nthread\sis\scalling\ssqlite3_column_text()\sand\sanother\sthread\sis\scalling\nsqlite3_step()\son\sthe\ssame\sprepared\sstatement\sat\sthe\ssame\sinstant. +D 2016-09-22T21:37:18.049 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -456,7 +456,7 @@ F src/vacuum.c 913970b9d86dd6c2b8063ef1af421880f1464ec3 F src/vdbe.c 0f87994593787575a4a23f932d27cb4588477436 F src/vdbe.h c044be7050ac6bf596eecc6ab159f5dbc020a3b7 F src/vdbeInt.h d21f14721dd87975dc9e3bcdbf504f9c098cf611 -F src/vdbeapi.c 1e0505f6a5495c47180eb2e3535a9779f42e72d6 +F src/vdbeapi.c 794f80669e9e3b9b3edc78d80c15968985c7bf21 F src/vdbeaux.c b9772e4134a17f5b42d32761f5119467815c2458 F src/vdbeblob.c 3e82a797b60c3b9fed7b8de8c539ca7607874937 F src/vdbemem.c 07874c2ac7c05f7df1ededc6ec6650c1339b2cad @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 5e892d60935e5c82234d1bfaef4c5026061acceb -R 4a98fd5ad20cf7ad4821bfd13a964ce7 +P c3774c6a5fe48af91fda28e9e18c6ed9053ea992 +R 6375993a9d5ddbf71b5ded7742ff83bd U drh -Z 0d81e518bb5c5c1a02f800fff5730756 +Z 824a3b47745c16899f3e858caef9c3bd diff --git a/manifest.uuid b/manifest.uuid index 3aff546e20..bd5435edc8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c3774c6a5fe48af91fda28e9e18c6ed9053ea992 \ No newline at end of file +ee1382a36303eff8d94275ac3b12e5ce398ee620 \ No newline at end of file diff --git a/src/vdbeapi.c b/src/vdbeapi.c index 937424843c..e37eeef2af 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -952,14 +952,13 @@ static Mem *columnMem(sqlite3_stmt *pStmt, int i){ Mem *pOut; pVm = (Vdbe *)pStmt; - if( pVm && pVm->pResultSet!=0 && inResColumn && i>=0 ){ - sqlite3_mutex_enter(pVm->db->mutex); + if( pVm==0 ) return (Mem*)columnNullValue(); + assert( pVm->db ); + sqlite3_mutex_enter(pVm->db->mutex); + if( pVm->pResultSet!=0 && inResColumn && i>=0 ){ pOut = &pVm->pResultSet[i]; }else{ - if( pVm && ALWAYS(pVm->db) ){ - sqlite3_mutex_enter(pVm->db->mutex); - sqlite3Error(pVm->db, SQLITE_RANGE); - } + sqlite3Error(pVm->db, SQLITE_RANGE); pOut = (Mem*)columnNullValue(); } return pOut; @@ -992,6 +991,8 @@ static void columnMallocFailure(sqlite3_stmt *pStmt) */ Vdbe *p = (Vdbe *)pStmt; if( p ){ + assert( p->db!=0 ); + assert( sqlite3_mutex_held(p->db->mutex) ); p->rc = sqlite3ApiExit(p->db, p->rc); sqlite3_mutex_leave(p->db->mutex); } From 8dd099bbaa84abf5e240a5b0acef78bccbef54cb Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 23 Sep 2016 18:13:01 +0000 Subject: [PATCH 0862/1484] New test case for the ORDER BY LIMIT optimization. FossilOrigin-Name: 9a5a489d0d344274d0fc9fb9303503a454f42844 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/limit2.test | 12 ++++++++++-- 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 31f00c98b9..0d78852826 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\spotential\snull-pointer\sdereference\sand\scrash\sin\sthe\scase\swhere\sone\nthread\sis\scalling\ssqlite3_column_text()\sand\sanother\sthread\sis\scalling\nsqlite3_step()\son\sthe\ssame\sprepared\sstatement\sat\sthe\ssame\sinstant. -D 2016-09-22T21:37:18.049 +C New\stest\scase\sfor\sthe\sORDER\sBY\sLIMIT\soptimization. +D 2016-09-23T18:13:01.106 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -893,7 +893,7 @@ F test/like.test 81632c437a947bf1f7130b19537da6a1a844806a F test/like2.test 3b2ee13149ba4a8a60b59756f4e5d345573852da F test/like3.test 3608a2042b6f922f900fbfd5d3ce4e7eca57f7c4 F test/limit.test 0c99a27a87b14c646a9d583c7c89fd06c352663e -F test/limit2.test ac97b8d07060a0280162ba4159e4c0c765861127 +F test/limit2.test 7e7744cc548d7e4c92e1dd3edc30dd0f86adafd5 F test/loadext.test d077450695ddb5c1ea3ad7d48e5f5850fe732ad9 F test/loadext2.test 0408380b57adca04004247179837a18e866a74f7 F test/lock.test be4fe08118fb988fed741f429b7dd5d65e1c90db @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P c3774c6a5fe48af91fda28e9e18c6ed9053ea992 -R 6375993a9d5ddbf71b5ded7742ff83bd +P ee1382a36303eff8d94275ac3b12e5ce398ee620 +R 414a8fb536c6a3f96976785b914f6d34 U drh -Z 824a3b47745c16899f3e858caef9c3bd +Z d5fb1d24e590d07d2266646af9025a8e diff --git a/manifest.uuid b/manifest.uuid index bd5435edc8..b0cfffb335 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ee1382a36303eff8d94275ac3b12e5ce398ee620 \ No newline at end of file +9a5a489d0d344274d0fc9fb9303503a454f42844 \ No newline at end of file diff --git a/test/limit2.test b/test/limit2.test index 0f82ab8d55..4d03180729 100644 --- a/test/limit2.test +++ b/test/limit2.test @@ -109,7 +109,15 @@ do_execsql_test limit2-310 { SELECT *,'.' FROM t300 WHERE a=0 AND (c=0 OR c=99) ORDER BY c DESC LIMIT 1; } {0 1 99 .} - - +# Make sure the SELECT loop is ordered correctly for the direction of +# the ORDER BY +# +do_execsql_test limit2-400 { + CREATE TABLE t400(a,b); + CREATE INDEX t400_ab ON t400(a,b); + INSERT INTO t400(a,b) VALUES(1,90),(1,40),(2,80),(2,30),(3,70),(3,20); + SELECT *,'x' FROM t400 WHERE a IN (1,2,3) ORDER BY b DESC LIMIT 3; + SELECT *,'y' FROM t400 WHERE a IN (1,2,3) ORDER BY +b DESC LIMIT 3; +} {1 90 x 2 80 x 3 70 x 1 90 y 2 80 y 3 70 y} finish_test From e1c03b62339203d373b12dfcc4b06940f1bbea0c Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 23 Sep 2016 20:59:31 +0000 Subject: [PATCH 0863/1484] Use sqlite3ExprAlloc() instead of sqlite3PExpr() for leaf nodes in the expression tree, where appropriate. This is both smaller and faster. FossilOrigin-Name: afac0709cec577a7851e3711730712cf12eeb6af --- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- src/expr.c | 4 ++-- src/fkey.c | 4 ++-- src/parse.y | 2 +- src/test_delete.c | 2 -- src/whereexpr.c | 4 ++-- 7 files changed, 18 insertions(+), 20 deletions(-) diff --git a/manifest b/manifest index 0d78852826..17b20f9f71 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C New\stest\scase\sfor\sthe\sORDER\sBY\sLIMIT\soptimization. -D 2016-09-23T18:13:01.106 +C Use\ssqlite3ExprAlloc()\sinstead\sof\ssqlite3PExpr()\sfor\sleaf\snodes\sin\sthe\nexpression\stree,\swhere\sappropriate.\s\sThis\sis\sboth\ssmaller\sand\sfaster. +D 2016-09-23T20:59:31.640 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -339,9 +339,9 @@ F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7 F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c cb3f6300df24c26c609778b2731f82644b5532ec -F src/expr.c 471ca87aa3b176548814a332172848015f13d823 +F src/expr.c 13bc043a6a6cfde48a7d551242e721af79f7837d F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb -F src/fkey.c e2be0968c1adc679c87e467aa5b4f167588f38a8 +F src/fkey.c b9ca262f6ad4d030a3cab737ebf9b0b3c8b4ac80 F src/func.c 29cc9acb170ec1387b9f63eb52cd85f8de96c771 F src/global.c 2917bbc488201b791e5f5dd43d8d2a3ccc315da7 F src/hash.c 55b5fb474100cee0b901edaf203e26c970940f36 @@ -375,7 +375,7 @@ F src/os_win.c 520f23475f1de530c435d30b67b7b15fe90874b0 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c bf5b71bde3e9b6110e7d6990607db881f6a471a2 F src/pager.h 966d2769e76ae347c8a32c4165faf6e6cb64546d -F src/parse.y 0e0b6d46a990d01e4ca1e9d7e1d2d9b5a98f6bcb +F src/parse.y 2e0ac10d159ae28378d760e1284672dc83c12e59 F src/pcache.c 5583c8ade4b05075a60ba953ef471d1c1a9c05df F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 F src/pcache1.c 4bb7a6a5300c67d0b033d25adb509c120c03e812 @@ -412,7 +412,7 @@ F src/test_bestindex.c d23f80d334c59662af69191854c76b8d3d0c8c96 F src/test_blob.c a0f7ad49a0c9d4b72f693fe2a71c58d7e507174d F src/test_btree.c 8b2dc8b8848cf3a4db93f11578f075e82252a274 F src/test_config.c 4d3d4a886416f369771d69a6dba926866deda788 -F src/test_delete.c f4920c10d7208ac55ee03882de9709cf39a83fec +F src/test_delete.c 32690ea215abf29dda589a580cd1b790389759b6 F src/test_demovfs.c a0c3bdd45ed044115c2c9f7779e56eafff18741e F src/test_devsym.c 4e58dec2602d8e139ca08659f62a62450587cb58 F src/test_fs.c e16cbe68d3b107e00a907c20a9a02629870eb69b @@ -470,7 +470,7 @@ F src/walker.c 83042807db1a27175fcb39be8f3e2a839dbdddb2 F src/where.c 5f91be9fe122e847c4e72d54d3989eb32a927981 F src/whereInt.h 14dd243e13b81cbb0a66063d38b70f93a7d6e613 F src/wherecode.c e412e09abad1eea213d85594cf46db9f877db56d -F src/whereexpr.c e3db778ed205e982f31960896db71c50612ae009 +F src/whereexpr.c 3d8813ef320f10bd27e6c0d784abe1669cfb514e F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ee1382a36303eff8d94275ac3b12e5ce398ee620 -R 414a8fb536c6a3f96976785b914f6d34 +P 9a5a489d0d344274d0fc9fb9303503a454f42844 +R 4f7e383818869f5430685b55e782c0cb U drh -Z d5fb1d24e590d07d2266646af9025a8e +Z 80e3136d01cf534e1ff43bad67f7dd75 diff --git a/manifest.uuid b/manifest.uuid index b0cfffb335..1c3ed882bc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9a5a489d0d344274d0fc9fb9303503a454f42844 \ No newline at end of file +afac0709cec577a7851e3711730712cf12eeb6af \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 195fe43955..ee2ad2f59d 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2587,8 +2587,8 @@ int sqlite3CodeSubselect( VdbeComment((v, "Init EXISTS result")); } sqlite3ExprDelete(pParse->db, pSel->pLimit); - pSel->pLimit = sqlite3PExpr(pParse, TK_INTEGER, 0, 0, - &sqlite3IntTokens[1]); + pSel->pLimit = sqlite3ExprAlloc(pParse->db, TK_INTEGER, + &sqlite3IntTokens[1], 0); pSel->iLimit = 0; pSel->selFlags &= ~SF_MultiValue; if( sqlite3Select(pParse, pSel, &dest) ){ diff --git a/src/fkey.c b/src/fkey.c index 609c3c6017..883cc6411e 100644 --- a/src/fkey.c +++ b/src/fkey.c @@ -1242,10 +1242,10 @@ static Trigger *fkActionTrigger( if( pDflt ){ pNew = sqlite3ExprDup(db, pDflt, 0); }else{ - pNew = sqlite3PExpr(pParse, TK_NULL, 0, 0, 0); + pNew = sqlite3ExprAlloc(db, TK_NULL, 0, 0); } }else{ - pNew = sqlite3PExpr(pParse, TK_NULL, 0, 0, 0); + pNew = sqlite3ExprAlloc(db, TK_NULL, 0, 0); } pList = sqlite3ExprListAppend(pParse, pList, pNew); sqlite3ExprListSetName(pParse, pList, &tFromCol, 0); diff --git a/src/parse.y b/src/parse.y index 51bdcff691..f15f2f59a7 100644 --- a/src/parse.y +++ b/src/parse.y @@ -851,7 +851,7 @@ idlist(A) ::= nm(Y). ** that created the expression. */ static void spanExpr(ExprSpan *pOut, Parse *pParse, int op, Token t){ - pOut->pExpr = sqlite3PExpr(pParse, op, 0, 0, &t); + pOut->pExpr = sqlite3ExprAlloc(pParse->db, op, &t, 1); pOut->zStart = t.z; pOut->zEnd = &t.z[t.n]; } diff --git a/src/test_delete.c b/src/test_delete.c index d82c022b75..6b3d9e85a1 100644 --- a/src/test_delete.c +++ b/src/test_delete.c @@ -136,5 +136,3 @@ int sqlite3_delete_database( sqlite3_free(zBuf); return (rc ? SQLITE_ERROR : SQLITE_OK); } - - diff --git a/src/whereexpr.c b/src/whereexpr.c index e1059f73b4..c0c9192af4 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -1247,7 +1247,7 @@ static void exprAnalyze( pNewExpr = sqlite3PExpr(pParse, TK_GT, sqlite3ExprDup(db, pLeft, 0), - sqlite3PExpr(pParse, TK_NULL, 0, 0, 0), 0); + sqlite3ExprAlloc(db, TK_NULL, 0, 0), 0); idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC|TERM_VNULL); @@ -1425,7 +1425,7 @@ void sqlite3WhereTabFuncArgs( pTab->zName, j); return; } - pColRef = sqlite3PExpr(pParse, TK_COLUMN, 0, 0, 0); + pColRef = sqlite3ExprAlloc(pParse->db, TK_COLUMN, 0, 0); if( pColRef==0 ) return; pColRef->iTable = pItem->iCursor; pColRef->iColumn = k++; From 209bc522b0222a805b12657c7253479756c32ca5 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 23 Sep 2016 21:36:24 +0000 Subject: [PATCH 0864/1484] Add the EP_Leaf flag bit to the Expr.flags field to indicate Expr nodes that do not have substructure. Use that bit to avoid unnecessary recursion. FossilOrigin-Name: 8a6ea455cd1bf42ae0a7f1f1789baf88d782db13 --- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- src/attach.c | 2 +- src/expr.c | 17 ++++++++++++----- src/parse.y | 1 + src/sqliteInt.h | 1 + src/walker.c | 4 +++- 7 files changed, 29 insertions(+), 18 deletions(-) diff --git a/manifest b/manifest index 17b20f9f71..143d93ba31 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Use\ssqlite3ExprAlloc()\sinstead\sof\ssqlite3PExpr()\sfor\sleaf\snodes\sin\sthe\nexpression\stree,\swhere\sappropriate.\s\sThis\sis\sboth\ssmaller\sand\sfaster. -D 2016-09-23T20:59:31.640 +C Add\sthe\sEP_Leaf\sflag\sbit\sto\sthe\sExpr.flags\sfield\sto\sindicate\sExpr\nnodes\sthat\sdo\snot\shave\ssubstructure.\s\sUse\sthat\sbit\sto\savoid\sunnecessary\nrecursion. +D 2016-09-23T21:36:24.016 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -324,7 +324,7 @@ F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F src/alter.c 299117695b1f21ac62dfc5b608588810ba22ed0d F src/analyze.c 8b62b2cf4da85451534ac0af82cafc418d837f68 -F src/attach.c 3e78d38abb5a4e3e0048a16ab662e6ffa323687c +F src/attach.c 8c19066b4b5357b5d66154e856c61df01e71203a F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792 F src/backup.c 92c2e3b5fcb47626413717138617f4d32f08aea4 F src/bitvec.c 3ee4c8b2c94ed3a7377256e18199e6ff5cf33f63 @@ -339,7 +339,7 @@ F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7 F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c cb3f6300df24c26c609778b2731f82644b5532ec -F src/expr.c 13bc043a6a6cfde48a7d551242e721af79f7837d +F src/expr.c a27090ab1d9d9901c64974c43588a38a486d6a55 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c b9ca262f6ad4d030a3cab737ebf9b0b3c8b4ac80 F src/func.c 29cc9acb170ec1387b9f63eb52cd85f8de96c771 @@ -375,7 +375,7 @@ F src/os_win.c 520f23475f1de530c435d30b67b7b15fe90874b0 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c bf5b71bde3e9b6110e7d6990607db881f6a471a2 F src/pager.h 966d2769e76ae347c8a32c4165faf6e6cb64546d -F src/parse.y 2e0ac10d159ae28378d760e1284672dc83c12e59 +F src/parse.y 028b531b442f06fd6f0177f6197f3384c7e6e538 F src/pcache.c 5583c8ade4b05075a60ba953ef471d1c1a9c05df F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 F src/pcache1.c 4bb7a6a5300c67d0b033d25adb509c120c03e812 @@ -391,7 +391,7 @@ F src/shell.c b80396d2fadce4681397707e30078bf416e1dec2 F src/sqlite.h.in 2683a291ed8db5228024267be6421f0de507b80e F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae -F src/sqliteInt.h e7c39dc148cd38b947cbdd482986afba3fe9ef22 +F src/sqliteInt.h 1137559f2e6f4e55d26ec83ce94ef57aa3748c8f F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 @@ -466,7 +466,7 @@ F src/vtab.c e02cacb5c7ae742631edeb9ae9f53d399f093fd8 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 02eeecc265f6ffd0597378f5d8ae9070b62a406a F src/wal.h 6dd221ed384afdc204bc61e25c23ef7fd5a511f2 -F src/walker.c 83042807db1a27175fcb39be8f3e2a839dbdddb2 +F src/walker.c 91a6df7435827e41cff6bb7df50ea00934ee78b0 F src/where.c 5f91be9fe122e847c4e72d54d3989eb32a927981 F src/whereInt.h 14dd243e13b81cbb0a66063d38b70f93a7d6e613 F src/wherecode.c e412e09abad1eea213d85594cf46db9f877db56d @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 9a5a489d0d344274d0fc9fb9303503a454f42844 -R 4f7e383818869f5430685b55e782c0cb +P afac0709cec577a7851e3711730712cf12eeb6af +R 1f3656e4b134bb6d596c11b8715739cb U drh -Z 80e3136d01cf534e1ff43bad67f7dd75 +Z aee870d3bef9f3e934093d2e8b8d0981 diff --git a/manifest.uuid b/manifest.uuid index 1c3ed882bc..2923794dec 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -afac0709cec577a7851e3711730712cf12eeb6af \ No newline at end of file +8a6ea455cd1bf42ae0a7f1f1789baf88d782db13 \ No newline at end of file diff --git a/src/attach.c b/src/attach.c index a9fdc36761..507b9c1238 100644 --- a/src/attach.c +++ b/src/attach.c @@ -530,7 +530,7 @@ int sqlite3FixExpr( return 1; } } - if( ExprHasProperty(pExpr, EP_TokenOnly) ) break; + if( ExprHasProperty(pExpr, EP_TokenOnly|EP_Leaf) ) break; if( ExprHasProperty(pExpr, EP_xIsSelect) ){ if( sqlite3FixSelect(pFix, pExpr->x.pSelect) ) return 1; }else{ diff --git a/src/expr.c b/src/expr.c index ee2ad2f59d..e8c245ec4d 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1016,18 +1016,25 @@ static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){ assert( p!=0 ); /* Sanity check: Assert that the IntValue is non-negative if it exists */ assert( !ExprHasProperty(p, EP_IntValue) || p->u.iValue>=0 ); - if( !ExprHasProperty(p, EP_TokenOnly) ){ +#ifdef SQLITE_DEBUG + if( ExprHasProperty(p, EP_Leaf) && !ExprHasProperty(p, EP_TokenOnly) ){ + assert( p->pLeft==0 ); + assert( p->pRight==0 ); + assert( p->x.pSelect==0 ); + } +#endif + if( !ExprHasProperty(p, (EP_TokenOnly|EP_Leaf)) ){ /* The Expr.x union is never used at the same time as Expr.pRight */ assert( p->x.pList==0 || p->pRight==0 ); if( p->pLeft && p->op!=TK_SELECT_COLUMN ) sqlite3ExprDeleteNN(db, p->pLeft); sqlite3ExprDelete(db, p->pRight); - if( ExprHasProperty(p, EP_MemToken) ) sqlite3DbFree(db, p->u.zToken); if( ExprHasProperty(p, EP_xIsSelect) ){ sqlite3SelectDelete(db, p->x.pSelect); }else{ sqlite3ExprListDelete(db, p->x.pList); } } + if( ExprHasProperty(p, EP_MemToken) ) sqlite3DbFree(db, p->u.zToken); if( !ExprHasProperty(p, EP_Static) ){ sqlite3DbFree(db, p); } @@ -1204,7 +1211,7 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int dupFlags, u8 **pzBuffer){ memcpy(zToken, p->u.zToken, nToken); } - if( 0==((p->flags|pNew->flags) & EP_TokenOnly) ){ + if( 0==((p->flags|pNew->flags) & (EP_TokenOnly|EP_Leaf)) ){ /* Fill in the pNew->x.pSelect or pNew->x.pList member. */ if( ExprHasProperty(p, EP_xIsSelect) ){ pNew->x.pSelect = sqlite3SelectDup(db, p->x.pSelect, dupFlags); @@ -1216,7 +1223,7 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int dupFlags, u8 **pzBuffer){ /* Fill in pNew->pLeft and pNew->pRight. */ if( ExprHasProperty(pNew, EP_Reduced|EP_TokenOnly) ){ zAlloc += dupedExprNodeSize(p, dupFlags); - if( ExprHasProperty(pNew, EP_Reduced) ){ + if( !ExprHasProperty(pNew, EP_TokenOnly|EP_Leaf) ){ pNew->pLeft = p->pLeft ? exprDup(db, p->pLeft, EXPRDUP_REDUCE, &zAlloc) : 0; pNew->pRight = p->pRight ? @@ -1226,7 +1233,7 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int dupFlags, u8 **pzBuffer){ *pzBuffer = zAlloc; } }else{ - if( !ExprHasProperty(p, EP_TokenOnly) ){ + if( !ExprHasProperty(p, EP_TokenOnly|EP_Leaf) ){ if( pNew->op==TK_SELECT_COLUMN ){ pNew->pLeft = p->pLeft; }else{ diff --git a/src/parse.y b/src/parse.y index f15f2f59a7..19d28c4e65 100644 --- a/src/parse.y +++ b/src/parse.y @@ -854,6 +854,7 @@ idlist(A) ::= nm(Y). pOut->pExpr = sqlite3ExprAlloc(pParse->db, op, &t, 1); pOut->zStart = t.z; pOut->zEnd = &t.z[t.n]; + if( pOut->pExpr ) pOut->pExpr->flags |= EP_Leaf; } } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 6d736b47a6..cba894db05 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2338,6 +2338,7 @@ struct Expr { #define EP_CanBeNull 0x100000 /* Can be null despite NOT NULL constraint */ #define EP_Subquery 0x200000 /* Tree contains a TK_SELECT operator */ #define EP_Alias 0x400000 /* Is an alias for a result set column */ +#define EP_Leaf 0x800000 /* Expr.pLeft, .pRight, .u.pSelect all NULL */ /* ** Combinations of two or more EP_* flags diff --git a/src/walker.c b/src/walker.c index 5abc3b9add..d1b1e96a2d 100644 --- a/src/walker.c +++ b/src/walker.c @@ -41,7 +41,9 @@ static SQLITE_NOINLINE int walkExpr(Walker *pWalker, Expr *pExpr){ testcase( ExprHasProperty(pExpr, EP_TokenOnly) ); testcase( ExprHasProperty(pExpr, EP_Reduced) ); rc = pWalker->xExprCallback(pWalker, pExpr); - if( rc || ExprHasProperty(pExpr,EP_TokenOnly) ) return rc & WRC_Abort; + if( rc || ExprHasProperty(pExpr,(EP_TokenOnly|EP_Leaf)) ){ + return rc & WRC_Abort; + } if( pExpr->pLeft && walkExpr(pWalker, pExpr->pLeft) ) return WRC_Abort; if( pExpr->pRight && walkExpr(pWalker, pExpr->pRight) ) return WRC_Abort; if( ExprHasProperty(pExpr, EP_xIsSelect) ){ From 87f0e9863d08cc9a1db0fb54bbe1d020f153d8e8 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 24 Sep 2016 01:41:59 +0000 Subject: [PATCH 0865/1484] Add -DSQLITE_MAX_EXPR_DEPTH=0 to the --lean option on speed-check.sh. FossilOrigin-Name: a8cb1390fc1234b2e925090c4d770cca5d587bea --- manifest | 12 ++++++------ manifest.uuid | 2 +- tool/speed-check.sh | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 143d93ba31..7eadd2bba2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sEP_Leaf\sflag\sbit\sto\sthe\sExpr.flags\sfield\sto\sindicate\sExpr\nnodes\sthat\sdo\snot\shave\ssubstructure.\s\sUse\sthat\sbit\sto\savoid\sunnecessary\nrecursion. -D 2016-09-23T21:36:24.016 +C Add\s-DSQLITE_MAX_EXPR_DEPTH=0\sto\sthe\s--lean\soption\son\sspeed-check.sh. +D 2016-09-24T01:41:59.614 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -1485,7 +1485,7 @@ F tool/showstat4.c bda40d6e395df7edb6e9ea630784d3d762c35b4b F tool/showwal.c ec79959834f7b21f1e0a2aa52bb7c056d2203977 F tool/soak1.tcl 8d407956e1a45b485a8e072470a3e629a27037fe F tool/spaceanal.tcl 85d90e6674d8298e3eaf82dbcef3abc2d5317f3e -F tool/speed-check.sh b6f8540db91bfd1fcfb53646bf657cf53ee03cd0 +F tool/speed-check.sh a57ee04157ad548a5059c642e251a841af04b1d7 F tool/speedtest.tcl 06c76698485ccf597b9e7dbb1ac70706eb873355 F tool/speedtest16.c ecb6542862151c3e6509bbc00509b234562ae81e F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P afac0709cec577a7851e3711730712cf12eeb6af -R 1f3656e4b134bb6d596c11b8715739cb +P 8a6ea455cd1bf42ae0a7f1f1789baf88d782db13 +R c2a1fbf434060e5ae670df791d65f59d U drh -Z aee870d3bef9f3e934093d2e8b8d0981 +Z e4f27d74e807f7370bdb607111a612f9 diff --git a/manifest.uuid b/manifest.uuid index 2923794dec..6ccbee05d3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8a6ea455cd1bf42ae0a7f1f1789baf88d782db13 \ No newline at end of file +a8cb1390fc1234b2e925090c4d770cca5d587bea \ No newline at end of file diff --git a/tool/speed-check.sh b/tool/speed-check.sh index 72753b9149..ffb067d246 100644 --- a/tool/speed-check.sh +++ b/tool/speed-check.sh @@ -29,6 +29,7 @@ LEAN_OPTS="-DSQLITE_THREADSAFE=0" LEAN_OPTS="$LEAN_OPTS -DSQLITE_DEFAULT_MEMSTATUS=0" LEAN_OPTS="$LEAN_OPTS -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1" LEAN_OPTS="$LEAN_OPTS -DSQLITE_LIKE_DOESNT_MATCH_BLOB" +LEAN_OPTS="$LEAN_OPTS -DSQLITE_MAX_EXPR_DEPTH=0" LEAN_OPTS="$LEAN_OPTS -DSQLITE_OMIT_DECLTYPE" LEAN_OPTS="$LEAN_OPTS -DSQLITE_OMIT_DEPRECATED" LEAN_OPTS="$LEAN_OPTS -DSQLITE_OMIT_PROGRESS_CALLBACK" From 410c301feaf5bf73f47965c6f142c9e684fbe0e1 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 24 Sep 2016 17:42:43 +0000 Subject: [PATCH 0866/1484] Omit the LikeOp object from the parser. Change more sqlite3PExpr() calls into sqlite3ExprAlloc() calls. FossilOrigin-Name: 795454a3fa5f9ccc486593b5e16e8fad38c934fb --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/parse.y | 42 ++++++++++++++++-------------------------- 3 files changed, 23 insertions(+), 33 deletions(-) diff --git a/manifest b/manifest index 7eadd2bba2..ed564101c5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\s-DSQLITE_MAX_EXPR_DEPTH=0\sto\sthe\s--lean\soption\son\sspeed-check.sh. -D 2016-09-24T01:41:59.614 +C Omit\sthe\sLikeOp\sobject\sfrom\sthe\sparser.\s\sChange\smore\ssqlite3PExpr()\scalls\sinto\nsqlite3ExprAlloc()\scalls. +D 2016-09-24T17:42:43.549 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -375,7 +375,7 @@ F src/os_win.c 520f23475f1de530c435d30b67b7b15fe90874b0 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c bf5b71bde3e9b6110e7d6990607db881f6a471a2 F src/pager.h 966d2769e76ae347c8a32c4165faf6e6cb64546d -F src/parse.y 028b531b442f06fd6f0177f6197f3384c7e6e538 +F src/parse.y b556d432d8e03104d8a8dfe13641416fd894b314 F src/pcache.c 5583c8ade4b05075a60ba953ef471d1c1a9c05df F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 F src/pcache1.c 4bb7a6a5300c67d0b033d25adb509c120c03e812 @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 8a6ea455cd1bf42ae0a7f1f1789baf88d782db13 -R c2a1fbf434060e5ae670df791d65f59d +P a8cb1390fc1234b2e925090c4d770cca5d587bea +R fa7d3ec531d0706f5c7953317248a4f0 U drh -Z e4f27d74e807f7370bdb607111a612f9 +Z 1cbaf1fb8c7d4606c6693d2bf847d929 diff --git a/manifest.uuid b/manifest.uuid index 6ccbee05d3..2c6e94a8b6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a8cb1390fc1234b2e925090c4d770cca5d587bea \ No newline at end of file +795454a3fa5f9ccc486593b5e16e8fad38c934fb \ No newline at end of file diff --git a/src/parse.y b/src/parse.y index 19d28c4e65..cf79a5fc7a 100644 --- a/src/parse.y +++ b/src/parse.y @@ -80,15 +80,6 @@ struct LimitVal { Expr *pOffset; /* The OFFSET expression. NULL if there is none */ }; -/* -** An instance of this structure is used to store the LIKE, -** GLOB, NOT LIKE, and NOT GLOB operators. -*/ -struct LikeOp { - Token eOperator; /* "like" or "glob" or "regexp" */ - int bNot; /* True if the NOT keyword is present */ -}; - /* ** An instance of the following structure describes the event of a ** TRIGGER. "a" is the event type, one of TK_UPDATE, TK_INSERT, @@ -100,11 +91,6 @@ struct LikeOp { */ struct TrigEvent { int a; IdList * b; }; -/* -** An instance of this structure holds the ATTACH key and the key type. -*/ -struct AttachKey { int type; Token key; }; - /* ** Disable lookaside memory allocation for objects that might be ** shared across database connections. @@ -865,15 +851,15 @@ term(A) ::= NULL(X). {spanExpr(&A,pParse,@X,X);/*A-overwrites-X*/} expr(A) ::= id(X). {spanExpr(&A,pParse,TK_ID,X); /*A-overwrites-X*/} expr(A) ::= JOIN_KW(X). {spanExpr(&A,pParse,TK_ID,X); /*A-overwrites-X*/} expr(A) ::= nm(X) DOT nm(Y). { - Expr *temp1 = sqlite3PExpr(pParse, TK_ID, 0, 0, &X); - Expr *temp2 = sqlite3PExpr(pParse, TK_ID, 0, 0, &Y); + Expr *temp1 = sqlite3ExprAlloc(pParse->db, TK_ID, &X, 1); + Expr *temp2 = sqlite3ExprAlloc(pParse->db, TK_ID, &Y, 1); spanSet(&A,&X,&Y); /*A-overwrites-X*/ A.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp2, 0); } expr(A) ::= nm(X) DOT nm(Y) DOT nm(Z). { - Expr *temp1 = sqlite3PExpr(pParse, TK_ID, 0, 0, &X); - Expr *temp2 = sqlite3PExpr(pParse, TK_ID, 0, 0, &Y); - Expr *temp3 = sqlite3PExpr(pParse, TK_ID, 0, 0, &Z); + Expr *temp1 = sqlite3ExprAlloc(pParse->db, TK_ID, &X, 1); + Expr *temp2 = sqlite3ExprAlloc(pParse->db, TK_ID, &Y, 1); + Expr *temp3 = sqlite3ExprAlloc(pParse->db, TK_ID, &Z, 1); Expr *temp4 = sqlite3PExpr(pParse, TK_DOT, temp2, temp3, 0); spanSet(&A,&X,&Z); /*A-overwrites-X*/ A.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp4, 0); @@ -976,25 +962,29 @@ expr(A) ::= expr(A) PLUS|MINUS(OP) expr(Y). expr(A) ::= expr(A) STAR|SLASH|REM(OP) expr(Y). {spanBinaryExpr(pParse,@OP,&A,&Y);} expr(A) ::= expr(A) CONCAT(OP) expr(Y). {spanBinaryExpr(pParse,@OP,&A,&Y);} -%type likeop {struct LikeOp} -likeop(A) ::= LIKE_KW|MATCH(X). {A.eOperator = X; A.bNot = 0;/*A-overwrites-X*/} -likeop(A) ::= NOT LIKE_KW|MATCH(X). {A.eOperator = X; A.bNot = 1;} +%type likeop {Token} +likeop(A) ::= LIKE_KW|MATCH(X). {A=X;/*A-overwrites-X*/} +likeop(A) ::= NOT LIKE_KW|MATCH(X). {A=X; A.n|=0x80000000; /*A-overwrite-X*/} expr(A) ::= expr(A) likeop(OP) expr(Y). [LIKE_KW] { ExprList *pList; + int bNot = OP.n & 0x80000000; + OP.n &= 0x7fffffff; pList = sqlite3ExprListAppend(pParse,0, Y.pExpr); pList = sqlite3ExprListAppend(pParse,pList, A.pExpr); - A.pExpr = sqlite3ExprFunction(pParse, pList, &OP.eOperator); - exprNot(pParse, OP.bNot, &A); + A.pExpr = sqlite3ExprFunction(pParse, pList, &OP); + exprNot(pParse, bNot, &A); A.zEnd = Y.zEnd; if( A.pExpr ) A.pExpr->flags |= EP_InfixFunc; } expr(A) ::= expr(A) likeop(OP) expr(Y) ESCAPE expr(E). [LIKE_KW] { ExprList *pList; + int bNot = OP.n & 0x80000000; + OP.n &= 0x7fffffff; pList = sqlite3ExprListAppend(pParse,0, Y.pExpr); pList = sqlite3ExprListAppend(pParse,pList, A.pExpr); pList = sqlite3ExprListAppend(pParse,pList, E.pExpr); - A.pExpr = sqlite3ExprFunction(pParse, pList, &OP.eOperator); - exprNot(pParse, OP.bNot, &A); + A.pExpr = sqlite3ExprFunction(pParse, pList, &OP); + exprNot(pParse, bNot, &A); A.zEnd = E.zEnd; if( A.pExpr ) A.pExpr->flags |= EP_InfixFunc; } From 0cd874bd5723fd95ffe69ab7f843ad7cfdc3671f Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 26 Sep 2016 12:38:22 +0000 Subject: [PATCH 0867/1484] Inline the relevent parts of sqlite3ExprAlloc() into spanExpr(), for a performance improvement. FossilOrigin-Name: fe89225eab777c2c9cb1cbc31092b9e39f516842 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/parse.y | 36 +++++++++++++++++++++++++++++------- 3 files changed, 36 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index ed564101c5..c63bc38f9d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Omit\sthe\sLikeOp\sobject\sfrom\sthe\sparser.\s\sChange\smore\ssqlite3PExpr()\scalls\sinto\nsqlite3ExprAlloc()\scalls. -D 2016-09-24T17:42:43.549 +C Inline\sthe\srelevent\sparts\sof\ssqlite3ExprAlloc()\sinto\sspanExpr(),\sfor\sa\nperformance\simprovement. +D 2016-09-26T12:38:22.166 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -375,7 +375,7 @@ F src/os_win.c 520f23475f1de530c435d30b67b7b15fe90874b0 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c bf5b71bde3e9b6110e7d6990607db881f6a471a2 F src/pager.h 966d2769e76ae347c8a32c4165faf6e6cb64546d -F src/parse.y b556d432d8e03104d8a8dfe13641416fd894b314 +F src/parse.y 6ad22b8f4a673de775d68c5c306dddd15839c45f F src/pcache.c 5583c8ade4b05075a60ba953ef471d1c1a9c05df F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 F src/pcache1.c 4bb7a6a5300c67d0b033d25adb509c120c03e812 @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a8cb1390fc1234b2e925090c4d770cca5d587bea -R fa7d3ec531d0706f5c7953317248a4f0 +P 795454a3fa5f9ccc486593b5e16e8fad38c934fb +R 0064134bdfbafdb61f074a12abc7c569 U drh -Z 1cbaf1fb8c7d4606c6693d2bf847d929 +Z 916f6b7f03e59b6765f98d6400d7b198 diff --git a/manifest.uuid b/manifest.uuid index 2c6e94a8b6..771d6a8e05 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -795454a3fa5f9ccc486593b5e16e8fad38c934fb \ No newline at end of file +fe89225eab777c2c9cb1cbc31092b9e39f516842 \ No newline at end of file diff --git a/src/parse.y b/src/parse.y index cf79a5fc7a..5c5e450f31 100644 --- a/src/parse.y +++ b/src/parse.y @@ -542,8 +542,8 @@ selcollist(A) ::= sclp(A) STAR. { Expr *p = sqlite3Expr(pParse->db, TK_ASTERISK, 0); A = sqlite3ExprListAppend(pParse, A, p); } -selcollist(A) ::= sclp(A) nm(X) DOT STAR(Y). { - Expr *pRight = sqlite3PExpr(pParse, TK_ASTERISK, 0, 0, &Y); +selcollist(A) ::= sclp(A) nm(X) DOT STAR. { + Expr *pRight = sqlite3PExpr(pParse, TK_ASTERISK, 0, 0, 0); Expr *pLeft = sqlite3PExpr(pParse, TK_ID, 0, 0, &X); Expr *pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight, 0); A = sqlite3ExprListAppend(pParse,A, pDot); @@ -837,10 +837,26 @@ idlist(A) ::= nm(Y). ** that created the expression. */ static void spanExpr(ExprSpan *pOut, Parse *pParse, int op, Token t){ - pOut->pExpr = sqlite3ExprAlloc(pParse->db, op, &t, 1); + Expr *p = sqlite3DbMallocRawNN(pParse->db, sizeof(Expr)+t.n+1); + if( p ){ + memset(p, 0, sizeof(Expr)); + p->op = (u8)op; + p->flags = EP_Leaf; + p->iAgg = -1; + p->u.zToken = (char*)&p[1]; + memcpy(p->u.zToken, t.z, t.n); + p->u.zToken[t.n] = 0; + if( sqlite3Isquote(p->u.zToken[0]) ){ + if( p->u.zToken[0]=='"' ) p->flags |= EP_DblQuoted; + sqlite3Dequote(p->u.zToken); + } +#if SQLITE_MAX_EXPR_DEPTH>0 + p->nHeight = 1; +#endif + } + pOut->pExpr = p; pOut->zStart = t.z; pOut->zEnd = &t.z[t.n]; - if( pOut->pExpr ) pOut->pExpr->flags |= EP_Leaf; } } @@ -864,8 +880,14 @@ expr(A) ::= nm(X) DOT nm(Y) DOT nm(Z). { spanSet(&A,&X,&Z); /*A-overwrites-X*/ A.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp4, 0); } -term(A) ::= INTEGER|FLOAT|BLOB(X). {spanExpr(&A,pParse,@X,X);/*A-overwrites-X*/} -term(A) ::= STRING(X). {spanExpr(&A,pParse,@X,X);/*A-overwrites-X*/} +term(A) ::= FLOAT|BLOB(X). {spanExpr(&A,pParse,@X,X);/*A-overwrites-X*/} +term(A) ::= STRING(X). {spanExpr(&A,pParse,@X,X);/*A-overwrites-X*/} +term(A) ::= INTEGER(X). { + A.pExpr = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &X, 1); + A.zStart = X.z; + A.zEnd = X.z + X.n; + if( A.pExpr ) A.pExpr->flags |= EP_Leaf; +} expr(A) ::= VARIABLE(X). { if( !(X.z[0]=='#' && sqlite3Isdigit(X.z[1])) ){ spanExpr(&A, pParse, TK_VARIABLE, X); @@ -881,7 +903,7 @@ expr(A) ::= VARIABLE(X). { sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &t); A.pExpr = 0; }else{ - A.pExpr = sqlite3PExpr(pParse, TK_REGISTER, 0, 0, &t); + A.pExpr = sqlite3PExpr(pParse, TK_REGISTER, 0, 0, 0); if( A.pExpr ) sqlite3GetInt32(&t.z[1], &A.pExpr->iTable); } } From 4c5ebee0b569bc0063ca76c35193454844a81adb Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 26 Sep 2016 14:39:05 +0000 Subject: [PATCH 0868/1484] =?UTF-8?q?When=20flattening=20a=20query=20of=20?= =?UTF-8?q?the=20form=20"SELECT=20*=20FROM=20(SELECT=20*=20FROM=20tbl=20WH?= =?UTF-8?q?ERE=20x=3D=3F)=20WHERE=20y=3D=3F",=20ensure=20that=20the=20fina?= =?UTF-8?q?l=20WHERE=20clause=20is=20"x=3D=3F=20AND=20y=3D=3F"=20instead?= =?UTF-8?q?=20of=20"y=3D=3F=20AND=20x=3D=3F".=20Although=20it=20is=20still?= =?UTF-8?q?=20not=20guaranteed,=20this=20makes=20the=20order=20in=20which?= =?UTF-8?q?=20WHERE=20clause=20terms=20are=20processed=20comport=20more=20?= =?UTF-8?q?closely=20to=20users=20expectations.?= FossilOrigin-Name: cf7f9e6d5abff273dd2f8a8dce27d52e1449b3be --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/select.c | 7 ++++--- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index c63bc38f9d..b465f9514b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Inline\sthe\srelevent\sparts\sof\ssqlite3ExprAlloc()\sinto\sspanExpr(),\sfor\sa\nperformance\simprovement. -D 2016-09-26T12:38:22.166 +C When\sflattening\sa\squery\sof\sthe\sform\s"SELECT\s*\sFROM\s(SELECT\s*\sFROM\stbl\sWHERE\sx=?)\sWHERE\sy=?",\sensure\sthat\sthe\sfinal\sWHERE\sclause\sis\s"x=?\sAND\sy=?"\sinstead\sof\s"y=?\sAND\sx=?".\sAlthough\sit\sis\sstill\snot\sguaranteed,\sthis\smakes\sthe\sorder\sin\swhich\sWHERE\sclause\sterms\sare\sprocessed\scomport\smore\sclosely\sto\susers\sexpectations. +D 2016-09-26T14:39:05.023 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -386,7 +386,7 @@ F src/printf.c a5f0ca08ddede803c241266abb46356ec748ded1 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c 3c3cf0dc719cd2a32ab5c1e10c26481dd565492e F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac -F src/select.c fb9da69a36382cf9cf57fb7a93247bf3de5a81ae +F src/select.c 6dede310d202f7a0da7f4ac1921f153707fa3d4f F src/shell.c b80396d2fadce4681397707e30078bf416e1dec2 F src/sqlite.h.in 2683a291ed8db5228024267be6421f0de507b80e F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 795454a3fa5f9ccc486593b5e16e8fad38c934fb -R 0064134bdfbafdb61f074a12abc7c569 -U drh -Z 916f6b7f03e59b6765f98d6400d7b198 +P fe89225eab777c2c9cb1cbc31092b9e39f516842 +R bd1b8b7597a40edc8cdb78ec48a115d9 +U dan +Z c695e6aeed2069a364c17cb8286df68b diff --git a/manifest.uuid b/manifest.uuid index 771d6a8e05..3e2a0bc1b0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fe89225eab777c2c9cb1cbc31092b9e39f516842 \ No newline at end of file +cf7f9e6d5abff273dd2f8a8dce27d52e1449b3be \ No newline at end of file diff --git a/src/select.c b/src/select.c index 6e4f4b99ed..a3badd12b5 100644 --- a/src/select.c +++ b/src/select.c @@ -3695,12 +3695,13 @@ static int flattenSubquery( assert( pParent->pHaving==0 ); pParent->pHaving = pParent->pWhere; pParent->pWhere = pWhere; - pParent->pHaving = sqlite3ExprAnd(db, pParent->pHaving, - sqlite3ExprDup(db, pSub->pHaving, 0)); + pParent->pHaving = sqlite3ExprAnd(db, + sqlite3ExprDup(db, pSub->pHaving, 0), pParent->pHaving + ); assert( pParent->pGroupBy==0 ); pParent->pGroupBy = sqlite3ExprListDup(db, pSub->pGroupBy, 0); }else{ - pParent->pWhere = sqlite3ExprAnd(db, pParent->pWhere, pWhere); + pParent->pWhere = sqlite3ExprAnd(db, pWhere, pParent->pWhere); } substSelect(db, pParent, iParent, pSub->pEList, 0); From 2e343265558557102bfacc983ba95bd5e08c4c06 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 27 Sep 2016 00:03:25 +0000 Subject: [PATCH 0869/1484] Fix FTS3 test cases due to the flattener change of the previous check-in. FossilOrigin-Name: 0c8b9b211f4285e2ab77cf5e0820088ef10e05c4 --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/fts3aux1.test | 6 +++--- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index b465f9514b..c21d0bf96d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C When\sflattening\sa\squery\sof\sthe\sform\s"SELECT\s*\sFROM\s(SELECT\s*\sFROM\stbl\sWHERE\sx=?)\sWHERE\sy=?",\sensure\sthat\sthe\sfinal\sWHERE\sclause\sis\s"x=?\sAND\sy=?"\sinstead\sof\s"y=?\sAND\sx=?".\sAlthough\sit\sis\sstill\snot\sguaranteed,\sthis\smakes\sthe\sorder\sin\swhich\sWHERE\sclause\sterms\sare\sprocessed\scomport\smore\sclosely\sto\susers\sexpectations. -D 2016-09-26T14:39:05.023 +C Fix\sFTS3\stest\scases\sdue\sto\sthe\sflattener\schange\sof\sthe\sprevious\scheck-in. +D 2016-09-27T00:03:25.212 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -746,7 +746,7 @@ F test/fts3an.test a49ccadc07a2f7d646ec1b81bc09da2d85a85b18 F test/fts3ao.test 3e4e3d5e75c076520341d0bdf4eb17c00e8cbde2 F test/fts3atoken.test 4b4c16fdcfc972f2cdbba212375a060a86ccf5f1 F test/fts3auto.test b981fea19b132b4e6878f50d7c1f369b28f68eb9 -F test/fts3aux1.test f8f287a4a73f381f8fa15b6a70f36245f903d221 +F test/fts3aux1.test ca32c138aa777b476271df2da2c5538b7a43ada1 F test/fts3aux2.test 7ae2b2c13aefdf4169279a27a5f51780ce57f6ba F test/fts3b.test e93bbb653e52afde110ad53bbd793f14fe7a8984 F test/fts3c.test fc723a9cf10b397fdfc2b32e73c53c8b1ec02958 @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P fe89225eab777c2c9cb1cbc31092b9e39f516842 -R bd1b8b7597a40edc8cdb78ec48a115d9 -U dan -Z c695e6aeed2069a364c17cb8286df68b +P cf7f9e6d5abff273dd2f8a8dce27d52e1449b3be +R df2b68a7640c290e9abf22bab0ae371c +U drh +Z b1604297e065dc768a551aec0598a153 diff --git a/manifest.uuid b/manifest.uuid index 3e2a0bc1b0..8ebab9a692 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cf7f9e6d5abff273dd2f8a8dce27d52e1449b3be \ No newline at end of file +0c8b9b211f4285e2ab77cf5e0820088ef10e05c4 \ No newline at end of file diff --git a/test/fts3aux1.test b/test/fts3aux1.test index d17ac85df5..b6111f8470 100644 --- a/test/fts3aux1.test +++ b/test/fts3aux1.test @@ -117,12 +117,12 @@ do_test 2.1.2.1 { set cnt 0 execsql { SELECT * FROM terms_v WHERE rec('cnt', term) AND term='braid' } set cnt -} {2} +} {1} do_test 2.1.2.2 { set cnt 0 execsql { SELECT * FROM terms_v WHERE rec('cnt', term) AND +term='braid' } set cnt -} {38} +} {19} # Similar to the test immediately above, but using a term ("breakfast") that # is not featured in the dataset. @@ -136,7 +136,7 @@ do_test 2.1.3.2 { set cnt 0 execsql { SELECT * FROM terms_v WHERE rec('cnt', term) AND +term='breakfast' } set cnt -} {38} +} {19} do_execsql_test 2.1.4.1 { SELECT * FROM terms_v WHERE term='braid' } {braid 1 1} do_execsql_test 2.1.4.2 { SELECT * FROM terms_v WHERE +term='braid'} {braid 1 1} From 96fdcb40af5c0842870a281aee6c1203357fc01a Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 27 Sep 2016 00:09:33 +0000 Subject: [PATCH 0870/1484] Update requirements marks due to improvements in the wording of documentation. No changes to code. FossilOrigin-Name: bf903b2ecac5d7b25c9cc899cae41f1d69aafe4e --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/build.c | 3 +++ src/vdbe.c | 7 +++---- 4 files changed, 14 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index c21d0bf96d..80568850e0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sFTS3\stest\scases\sdue\sto\sthe\sflattener\schange\sof\sthe\sprevious\scheck-in. -D 2016-09-27T00:03:25.212 +C Update\srequirements\smarks\sdue\sto\simprovements\sin\sthe\swording\sof\sdocumentation.\nNo\schanges\sto\scode. +D 2016-09-27T00:09:33.561 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -332,7 +332,7 @@ F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 F src/btree.c 56e1732ecfb3731efcb216266ec26b1b96e5e8c9 F src/btree.h d05b2fcc290991a8a3d9ea1816ddd55a4359dcde F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 -F src/build.c 7438b6dae3022818100a79ebbad707b5c65f9344 +F src/build.c 9a1f228cfa0aec70e2b4eba1fcf141ca4b499f6e F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7 @@ -453,7 +453,7 @@ F src/update.c 8179e699dbd45b92934fd02d3d8e3732e8da8802 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 3e2da6101888d073e79ecc6af5e0a2f70fa1e498 F src/vacuum.c 913970b9d86dd6c2b8063ef1af421880f1464ec3 -F src/vdbe.c 0f87994593787575a4a23f932d27cb4588477436 +F src/vdbe.c 8ceb206967b58ea5397d1c3255ac8bf3ad45dc4b F src/vdbe.h c044be7050ac6bf596eecc6ab159f5dbc020a3b7 F src/vdbeInt.h d21f14721dd87975dc9e3bcdbf504f9c098cf611 F src/vdbeapi.c 794f80669e9e3b9b3edc78d80c15968985c7bf21 @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P cf7f9e6d5abff273dd2f8a8dce27d52e1449b3be -R df2b68a7640c290e9abf22bab0ae371c +P 0c8b9b211f4285e2ab77cf5e0820088ef10e05c4 +R 2790d47b3cb1c09143225834f9ceab40 U drh -Z b1604297e065dc768a551aec0598a153 +Z fa709185b4fcfa4bfb5550b3343a5618 diff --git a/manifest.uuid b/manifest.uuid index 8ebab9a692..b96c54fd42 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0c8b9b211f4285e2ab77cf5e0820088ef10e05c4 \ No newline at end of file +bf903b2ecac5d7b25c9cc899cae41f1d69aafe4e \ No newline at end of file diff --git a/src/build.c b/src/build.c index 3384e6db85..2302fc20b1 100644 --- a/src/build.c +++ b/src/build.c @@ -1458,6 +1458,9 @@ CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char *zName){ ** set back to prior value. But schema changes are infrequent ** and the probability of hitting the same cookie value is only ** 1 chance in 2^32. So we're safe enough. +** +** IMPLEMENTATION-OF: R-34230-56049 SQLite automatically increments +** the schema-version whenever the schema changes. */ void sqlite3ChangeCookie(Parse *pParse, int iDb){ sqlite3 *db = pParse->db; diff --git a/src/vdbe.c b/src/vdbe.c index 3965a012fa..915bf2dda0 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -3208,10 +3208,9 @@ case OP_Transaction: { } /* Gather the schema version number for checking: - ** IMPLEMENTATION-OF: R-32195-19465 The schema version is used by SQLite - ** each time a query is executed to ensure that the internal cache of the - ** schema used when compiling the SQL query matches the schema of the - ** database against which the compiled query is actually executed. + ** IMPLEMENTATION-OF: R-03189-51135 As each SQL statement runs, the schema + ** version is checked to ensure that the schema has not changed since the + ** SQL statement was prepared. */ sqlite3BtreeGetMeta(pBt, BTREE_SCHEMA_VERSION, (u32 *)&iMeta); iGen = db->aDb[pOp->p1].pSchema->iGeneration; From ed204d1f446338f2096c2f0c7130899a946888c2 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 28 Sep 2016 16:04:22 +0000 Subject: [PATCH 0871/1484] Fix typos in comments. No code changes. FossilOrigin-Name: 5bbd071d57a8048e2ca17bf97761e4f27fc5a6bf --- ext/session/sqlite3session.h | 4 ++-- manifest | 14 +++++++------- manifest.uuid | 2 +- src/vdbe.c | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/ext/session/sqlite3session.h b/ext/session/sqlite3session.h index 140138f36d..2507347251 100644 --- a/ext/session/sqlite3session.h +++ b/ext/session/sqlite3session.h @@ -157,7 +157,7 @@ int sqlite3session_attach( ** CAPI3REF: Set a table filter on a Session Object. ** ** The second argument (xFilter) is the "filter callback". For changes to rows -** in tables that are not attached to the Session oject, the filter is called +** in tables that are not attached to the Session object, the filter is called ** to determine whether changes to the table's rows should be tracked or not. ** If xFilter returns 0, changes is not tracked. Note that once a table is ** attached, xFilter will not be called again. @@ -510,7 +510,7 @@ int sqlite3changeset_op( ** 0x01 if the corresponding column is part of the tables primary key, or ** 0x00 if it is not. ** -** If argumet pnCol is not NULL, then *pnCol is set to the number of columns +** If argument pnCol is not NULL, then *pnCol is set to the number of columns ** in the table. ** ** If this function is called when the iterator does not point to a valid diff --git a/manifest b/manifest index 80568850e0..8347c9b49c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\srequirements\smarks\sdue\sto\simprovements\sin\sthe\swording\sof\sdocumentation.\nNo\schanges\sto\scode. -D 2016-09-27T00:09:33.561 +C Fix\stypos\sin\scomments.\s\sNo\scode\schanges. +D 2016-09-28T16:04:22.705 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -302,7 +302,7 @@ F ext/session/session_common.tcl 9b696a341cf1d3744823715ed92bb19749b6c3d4 F ext/session/sessionfault.test da273f2712b6411e85e71465a1733b8501dbf6f7 F ext/session/sessionfault2.test 04aa0bc9aa70ea43d8de82c4f648db4de1e990b0 F ext/session/sqlite3session.c 37485891b4add26cf61495df193c419f36556a32 -F ext/session/sqlite3session.h 7b9037818ee61f7429ca83e9866885ca6de5f764 +F ext/session/sqlite3session.h 7608f94340a6f7441cd6e618690644bb07b68127 F ext/session/test_session.c eb0bd6c1ea791c1d66ee4ef94c16500dad936386 F ext/userauth/sqlite3userauth.h 19cb6f0e31316d0ee4afdfb7a85ef9da3333a220 F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04 @@ -453,7 +453,7 @@ F src/update.c 8179e699dbd45b92934fd02d3d8e3732e8da8802 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 3e2da6101888d073e79ecc6af5e0a2f70fa1e498 F src/vacuum.c 913970b9d86dd6c2b8063ef1af421880f1464ec3 -F src/vdbe.c 8ceb206967b58ea5397d1c3255ac8bf3ad45dc4b +F src/vdbe.c 8b2e9f8846540ffcbda54d29172ed6ed1c8cb6d3 F src/vdbe.h c044be7050ac6bf596eecc6ab159f5dbc020a3b7 F src/vdbeInt.h d21f14721dd87975dc9e3bcdbf504f9c098cf611 F src/vdbeapi.c 794f80669e9e3b9b3edc78d80c15968985c7bf21 @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 0c8b9b211f4285e2ab77cf5e0820088ef10e05c4 -R 2790d47b3cb1c09143225834f9ceab40 +P bf903b2ecac5d7b25c9cc899cae41f1d69aafe4e +R 5c7411c7a827679142aabebf874123be U drh -Z fa709185b4fcfa4bfb5550b3343a5618 +Z 6ce2a81d24fa25965c47db489fd948d3 diff --git a/manifest.uuid b/manifest.uuid index b96c54fd42..065a325cc5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bf903b2ecac5d7b25c9cc899cae41f1d69aafe4e \ No newline at end of file +5bbd071d57a8048e2ca17bf97761e4f27fc5a6bf \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 915bf2dda0..5520ad7de7 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -4466,7 +4466,7 @@ case OP_InsertInt: { ** P1 must not be pseudo-table. It has to be a real table with ** multiple rows. ** -** If P4 is not NULL then it points to a Table struture. In this case either +** If P4 is not NULL then it points to a Table structure. In this case either ** the update or pre-update hook, or both, may be invoked. The P1 cursor must ** have been positioned using OP_NotFound prior to invoking this opcode in ** this case. Specifically, if one is configured, the pre-update hook is From 5e769a50ad8a3e3e9a831f22556075ae74e0af3c Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 28 Sep 2016 16:05:53 +0000 Subject: [PATCH 0872/1484] Two more typo fixes in comments. FossilOrigin-Name: 40c0fb0af678797c39a99853f9f4102464c16f4b --- ext/session/sqlite3session.h | 4 ++-- manifest | 14 +++++++------- manifest.uuid | 2 +- src/vdbe.c | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/ext/session/sqlite3session.h b/ext/session/sqlite3session.h index 2507347251..c995d4ec28 100644 --- a/ext/session/sqlite3session.h +++ b/ext/session/sqlite3session.h @@ -423,7 +423,7 @@ int sqlite3session_isempty(sqlite3_session *pSession); ** [sqlite3changeset_invert()] functions, all changes within the changeset ** that apply to a single table are grouped together. This means that when ** an application iterates through a changeset using an iterator created by -** this function, all changes that relate to a single table are visted +** this function, all changes that relate to a single table are visited ** consecutively. There is no chance that the iterator will visit a change ** the applies to table X, then one for table Y, and then later on visit ** another change for table X. @@ -785,7 +785,7 @@ int sqlite3changegroup_new(sqlite3_changegroup **pp); ** apply to the same row as a change already present in the changegroup if ** the two rows have the same primary key. ** -** Changes to rows that that do not already appear in the changegroup are +** Changes to rows that do not already appear in the changegroup are ** simply copied into it. Or, if both the new changeset and the changegroup ** contain changes that apply to a single row, the final contents of the ** changegroup depends on the type of each change, as follows: diff --git a/manifest b/manifest index 8347c9b49c..9899126ad2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\stypos\sin\scomments.\s\sNo\scode\schanges. -D 2016-09-28T16:04:22.705 +C Two\smore\stypo\sfixes\sin\scomments. +D 2016-09-28T16:05:53.347 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -302,7 +302,7 @@ F ext/session/session_common.tcl 9b696a341cf1d3744823715ed92bb19749b6c3d4 F ext/session/sessionfault.test da273f2712b6411e85e71465a1733b8501dbf6f7 F ext/session/sessionfault2.test 04aa0bc9aa70ea43d8de82c4f648db4de1e990b0 F ext/session/sqlite3session.c 37485891b4add26cf61495df193c419f36556a32 -F ext/session/sqlite3session.h 7608f94340a6f7441cd6e618690644bb07b68127 +F ext/session/sqlite3session.h 9345166bd8f80562145586cf817f707de5ecada2 F ext/session/test_session.c eb0bd6c1ea791c1d66ee4ef94c16500dad936386 F ext/userauth/sqlite3userauth.h 19cb6f0e31316d0ee4afdfb7a85ef9da3333a220 F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04 @@ -453,7 +453,7 @@ F src/update.c 8179e699dbd45b92934fd02d3d8e3732e8da8802 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 3e2da6101888d073e79ecc6af5e0a2f70fa1e498 F src/vacuum.c 913970b9d86dd6c2b8063ef1af421880f1464ec3 -F src/vdbe.c 8b2e9f8846540ffcbda54d29172ed6ed1c8cb6d3 +F src/vdbe.c 6781329737f4bb140834cd32b15e93b83d60858e F src/vdbe.h c044be7050ac6bf596eecc6ab159f5dbc020a3b7 F src/vdbeInt.h d21f14721dd87975dc9e3bcdbf504f9c098cf611 F src/vdbeapi.c 794f80669e9e3b9b3edc78d80c15968985c7bf21 @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P bf903b2ecac5d7b25c9cc899cae41f1d69aafe4e -R 5c7411c7a827679142aabebf874123be +P 5bbd071d57a8048e2ca17bf97761e4f27fc5a6bf +R bf0761c46088be2deeef7ae66a06e596 U drh -Z 6ce2a81d24fa25965c47db489fd948d3 +Z f28f9e255c7712d05cf98e2e813edaa6 diff --git a/manifest.uuid b/manifest.uuid index 065a325cc5..dd204bcb38 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5bbd071d57a8048e2ca17bf97761e4f27fc5a6bf \ No newline at end of file +40c0fb0af678797c39a99853f9f4102464c16f4b \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 5520ad7de7..c32e0ea43e 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -4466,7 +4466,7 @@ case OP_InsertInt: { ** P1 must not be pseudo-table. It has to be a real table with ** multiple rows. ** -** If P4 is not NULL then it points to a Table structure. In this case either +** If P4 is not NULL then it points to a Table object. In this case either ** the update or pre-update hook, or both, may be invoked. The P1 cursor must ** have been positioned using OP_NotFound prior to invoking this opcode in ** this case. Specifically, if one is configured, the pre-update hook is From 5f33eaa6a4855461d8b596235d66c432ef2ce77c Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 28 Sep 2016 20:42:31 +0000 Subject: [PATCH 0873/1484] Use Knuth multiplicative hashing for the symbol table. FossilOrigin-Name: cc29ddd6be60bdbf107f285c9eb57d5896ebca2d --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/hash.c | 6 +++++- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 9899126ad2..600ed2a364 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Two\smore\stypo\sfixes\sin\scomments. -D 2016-09-28T16:05:53.347 +C Use\sKnuth\smultiplicative\shashing\sfor\sthe\ssymbol\stable. +D 2016-09-28T20:42:31.903 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -344,7 +344,7 @@ F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c b9ca262f6ad4d030a3cab737ebf9b0b3c8b4ac80 F src/func.c 29cc9acb170ec1387b9f63eb52cd85f8de96c771 F src/global.c 2917bbc488201b791e5f5dd43d8d2a3ccc315da7 -F src/hash.c 55b5fb474100cee0b901edaf203e26c970940f36 +F src/hash.c 63d0ee752a3b92d4695b2b1f5259c4621b2cfebd F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4 F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 5bbd071d57a8048e2ca17bf97761e4f27fc5a6bf -R bf0761c46088be2deeef7ae66a06e596 +P 40c0fb0af678797c39a99853f9f4102464c16f4b +R 781c8f4e56859d80db856b6e4a37be8a U drh -Z f28f9e255c7712d05cf98e2e813edaa6 +Z f77949e5354e55e63daf682f77676620 diff --git a/manifest.uuid b/manifest.uuid index dd204bcb38..58819f70c4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -40c0fb0af678797c39a99853f9f4102464c16f4b \ No newline at end of file +cc29ddd6be60bdbf107f285c9eb57d5896ebca2d \ No newline at end of file diff --git a/src/hash.c b/src/hash.c index eea2dd1ac2..62b695a1bb 100644 --- a/src/hash.c +++ b/src/hash.c @@ -56,7 +56,11 @@ static unsigned int strHash(const char *z){ unsigned int h = 0; unsigned char c; while( (c = (unsigned char)*z++)!=0 ){ /*OPTIMIZATION-IF-TRUE*/ - h = (h<<3) ^ h ^ sqlite3UpperToLower[c]; + /* Knuth multiplicative hashing. (Sorting & Searching, p. 510). + ** 0x9e3779b1 is 2654435761 which is the closest prime number to + ** (2**32)*golden_ratio, where golden_ratio = (sqrt(5) - 1)/2. */ + h += sqlite3UpperToLower[c]; + h *= 0x9e3779b1; } return h; } From 22fa36dc0448d5793efea5b5b635846a48239236 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 29 Sep 2016 15:53:28 +0000 Subject: [PATCH 0874/1484] Clarification and typo-fixes in comments. No changes to code. FossilOrigin-Name: e2cd79aa3104c51035bf29c548c322564731b75f --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/global.c | 11 ++++------- src/vdbeInt.h | 26 ++++++-------------------- 4 files changed, 18 insertions(+), 35 deletions(-) diff --git a/manifest b/manifest index 600ed2a364..6db27f934a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Use\sKnuth\smultiplicative\shashing\sfor\sthe\ssymbol\stable. -D 2016-09-28T20:42:31.903 +C Clarification\sand\stypo-fixes\sin\scomments.\s\sNo\schanges\sto\scode. +D 2016-09-29T15:53:28.199 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -343,7 +343,7 @@ F src/expr.c a27090ab1d9d9901c64974c43588a38a486d6a55 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c b9ca262f6ad4d030a3cab737ebf9b0b3c8b4ac80 F src/func.c 29cc9acb170ec1387b9f63eb52cd85f8de96c771 -F src/global.c 2917bbc488201b791e5f5dd43d8d2a3ccc315da7 +F src/global.c 9da4ca5d74b90715f0ec4957f3d17a4749009f34 F src/hash.c 63d0ee752a3b92d4695b2b1f5259c4621b2cfebd F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4 F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da @@ -455,7 +455,7 @@ F src/util.c 3e2da6101888d073e79ecc6af5e0a2f70fa1e498 F src/vacuum.c 913970b9d86dd6c2b8063ef1af421880f1464ec3 F src/vdbe.c 6781329737f4bb140834cd32b15e93b83d60858e F src/vdbe.h c044be7050ac6bf596eecc6ab159f5dbc020a3b7 -F src/vdbeInt.h d21f14721dd87975dc9e3bcdbf504f9c098cf611 +F src/vdbeInt.h 581b737c2f6e413c555469480efe31796a71bcad F src/vdbeapi.c 794f80669e9e3b9b3edc78d80c15968985c7bf21 F src/vdbeaux.c b9772e4134a17f5b42d32761f5119467815c2458 F src/vdbeblob.c 3e82a797b60c3b9fed7b8de8c539ca7607874937 @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 40c0fb0af678797c39a99853f9f4102464c16f4b -R 781c8f4e56859d80db856b6e4a37be8a +P cc29ddd6be60bdbf107f285c9eb57d5896ebca2d +R 647685f38d2c1b34b7290eda763c0ba3 U drh -Z f77949e5354e55e63daf682f77676620 +Z 99ca7352da532b6b28eade6076b7309c diff --git a/manifest.uuid b/manifest.uuid index 58819f70c4..f79940d5cf 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cc29ddd6be60bdbf107f285c9eb57d5896ebca2d \ No newline at end of file +e2cd79aa3104c51035bf29c548c322564731b75f \ No newline at end of file diff --git a/src/global.c b/src/global.c index 8b676ef66f..f7865c9522 100644 --- a/src/global.c +++ b/src/global.c @@ -79,16 +79,13 @@ const unsigned char sqlite3UpperToLower[] = { ** ** (x & ~(map[x]&0x20)) ** -** Standard function tolower() is implemented using the sqlite3UpperToLower[] +** The equivalent of tolower() is implemented using the sqlite3UpperToLower[] ** array. tolower() is used more often than toupper() by SQLite. ** -** Bit 0x40 is set if the character non-alphanumeric and can be used in an +** Bit 0x40 is set if the character is non-alphanumeric and can be used in an ** SQLite identifier. Identifiers are alphanumerics, "_", "$", and any ** non-ASCII UTF character. Hence the test for whether or not a character is ** part of an identifier is 0x46. -** -** SQLite's versions are identical to the standard versions assuming a -** locale of "C". They are implemented as macros in sqliteInt.h. */ #ifdef SQLITE_ASCII const unsigned char sqlite3CtypeMap[256] = { @@ -161,7 +158,7 @@ const unsigned char sqlite3CtypeMap[256] = { #endif /* Statement journals spill to disk when their size exceeds the following -** threashold (in bytes). 0 means that statement journals are created and +** threshold (in bytes). 0 means that statement journals are created and ** written to disk immediately (the default behavior for SQLite versions ** before 3.12.0). -1 means always keep the entire statement journal in ** memory. (The statement journal is also always held entirely in memory @@ -249,7 +246,7 @@ const Token sqlite3IntTokens[] = { ** The value of the "pending" byte must be 0x40000000 (1 byte past the ** 1-gibabyte boundary) in a compatible database. SQLite never uses ** the database page that contains the pending byte. It never attempts -** to read or write that page. The pending byte page is set assign +** to read or write that page. The pending byte page is set aside ** for use by the VFS layers as space for managing file locks. ** ** During testing, it is often desirable to move the pending byte to diff --git a/src/vdbeInt.h b/src/vdbeInt.h index b1d7717a0b..353abc6877 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -52,9 +52,6 @@ typedef unsigned Bool; /* Opaque type used by code in vdbesort.c */ typedef struct VdbeSorter VdbeSorter; -/* Opaque type used by the explainer */ -typedef struct Explain Explain; - /* Elements of the linked list at Vdbe.pAuxData */ typedef struct AuxData AuxData; @@ -129,6 +126,12 @@ struct VdbeCursor { ** aType[] and nField+1 array slots for aOffset[] */ }; + +/* +** A value for VdbeCursor.cacheStatus that means the cache is always invalid. +*/ +#define CACHE_STALE 0 + /* ** When a sub-program is executed (OP_Program), a structure of this type ** is allocated to store the current value of the program counter, as @@ -173,11 +176,6 @@ struct VdbeFrame { #define VdbeFrameMem(p) ((Mem *)&((u8 *)p)[ROUND8(sizeof(VdbeFrame))]) -/* -** A value for VdbeCursor.cacheValid that means the cache is always invalid. -*/ -#define CACHE_STALE 0 - /* ** Internally, the vdbe manipulates nearly all SQL values as Mem ** structures. Each Mem struct may cache multiple representations (string, @@ -318,18 +316,6 @@ struct sqlite3_context { sqlite3_value *argv[1]; /* Argument set */ }; -/* -** An Explain object accumulates indented output which is helpful -** in describing recursive data structures. -*/ -struct Explain { - Vdbe *pVdbe; /* Attach the explanation to this Vdbe */ - StrAccum str; /* The string being accumulated */ - int nIndent; /* Number of elements in aIndent */ - u16 aIndent[100]; /* Levels of indentation */ - char zBase[100]; /* Initial space */ -}; - /* A bitfield type for use inside of structures. Always follow with :N where ** N is the number of bits. */ From 42735c7d302dadc356f6e5ed7692e3e223b0a9ba Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 29 Sep 2016 19:27:16 +0000 Subject: [PATCH 0875/1484] Size and performance optimization to sqlite3ValueFromExpr() FossilOrigin-Name: 945f82bc44c5a431c0fef0d36cf016671d7ade1e --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbemem.c | 7 ++----- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 6db27f934a..2a85770633 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Clarification\sand\stypo-fixes\sin\scomments.\s\sNo\schanges\sto\scode. -D 2016-09-29T15:53:28.199 +C Size\sand\sperformance\soptimization\sto\ssqlite3ValueFromExpr() +D 2016-09-29T19:27:16.222 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -459,7 +459,7 @@ F src/vdbeInt.h 581b737c2f6e413c555469480efe31796a71bcad F src/vdbeapi.c 794f80669e9e3b9b3edc78d80c15968985c7bf21 F src/vdbeaux.c b9772e4134a17f5b42d32761f5119467815c2458 F src/vdbeblob.c 3e82a797b60c3b9fed7b8de8c539ca7607874937 -F src/vdbemem.c 07874c2ac7c05f7df1ededc6ec6650c1339b2cad +F src/vdbemem.c 1b8d5b770a9a3c6d8ed3463104a382bffa6f15c2 F src/vdbesort.c 91fda3909326860382b0ca8aa251e609c6a9d62c F src/vdbetrace.c 41963d5376f0349842b5fc4aaaaacd7d9cdc0834 F src/vtab.c e02cacb5c7ae742631edeb9ae9f53d399f093fd8 @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P cc29ddd6be60bdbf107f285c9eb57d5896ebca2d -R 647685f38d2c1b34b7290eda763c0ba3 +P e2cd79aa3104c51035bf29c548c322564731b75f +R ced10222d4b6fcbb24f085bf78455885 U drh -Z 99ca7352da532b6b28eade6076b7309c +Z 527ba3ca85dfce0ba6019f348119d7e0 diff --git a/manifest.uuid b/manifest.uuid index f79940d5cf..098948e590 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e2cd79aa3104c51035bf29c548c322564731b75f \ No newline at end of file +945f82bc44c5a431c0fef0d36cf016671d7ade1e \ No newline at end of file diff --git a/src/vdbemem.c b/src/vdbemem.c index b03aa49702..fb4f704f5d 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -1269,10 +1269,7 @@ static int valueFromExpr( const char *zNeg = ""; int rc = SQLITE_OK; - if( !pExpr ){ - *ppVal = 0; - return SQLITE_OK; - } + assert( pExpr!=0 ); while( (op = pExpr->op)==TK_UPLUS || op==TK_SPAN ) pExpr = pExpr->pLeft; if( NEVER(op==TK_REGISTER) ) op = pExpr->op2; @@ -1396,7 +1393,7 @@ int sqlite3ValueFromExpr( u8 affinity, /* Affinity to use */ sqlite3_value **ppVal /* Write the new value here */ ){ - return valueFromExpr(db, pExpr, enc, affinity, ppVal, 0); + return pExpr ? valueFromExpr(db, pExpr, enc, affinity, ppVal, 0) : 0; } #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 From 2831c4d12340d1e8bd0a6013aeaab4a6a3e93a72 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 29 Sep 2016 19:50:02 +0000 Subject: [PATCH 0876/1484] Remove the peep-hole optimization of removing OP_Close opcodes that come before OP_Halt, as the extra work of removing those opcodes uses more cycles than just running them. FossilOrigin-Name: 984a96d79656c1b095aba1f88aca4bb787ba0bd8 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/build.c | 1 - src/sqliteInt.h | 1 - src/vdbeaux.c | 4 +--- 5 files changed, 10 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index 2a85770633..21be3d686a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Size\sand\sperformance\soptimization\sto\ssqlite3ValueFromExpr() -D 2016-09-29T19:27:16.222 +C Remove\sthe\speep-hole\soptimization\sof\sremoving\sOP_Close\sopcodes\sthat\scome\nbefore\sOP_Halt,\sas\sthe\sextra\swork\sof\sremoving\sthose\sopcodes\suses\smore\scycles\nthan\sjust\srunning\sthem. +D 2016-09-29T19:50:02.416 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -332,7 +332,7 @@ F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 F src/btree.c 56e1732ecfb3731efcb216266ec26b1b96e5e8c9 F src/btree.h d05b2fcc290991a8a3d9ea1816ddd55a4359dcde F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 -F src/build.c 9a1f228cfa0aec70e2b4eba1fcf141ca4b499f6e +F src/build.c ab95712203bfbd83d65c878934201624f778e469 F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7 @@ -391,7 +391,7 @@ F src/shell.c b80396d2fadce4681397707e30078bf416e1dec2 F src/sqlite.h.in 2683a291ed8db5228024267be6421f0de507b80e F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae -F src/sqliteInt.h 1137559f2e6f4e55d26ec83ce94ef57aa3748c8f +F src/sqliteInt.h 2599e8cc7e74733bd980b1c58712f975f914ef01 F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 @@ -457,7 +457,7 @@ F src/vdbe.c 6781329737f4bb140834cd32b15e93b83d60858e F src/vdbe.h c044be7050ac6bf596eecc6ab159f5dbc020a3b7 F src/vdbeInt.h 581b737c2f6e413c555469480efe31796a71bcad F src/vdbeapi.c 794f80669e9e3b9b3edc78d80c15968985c7bf21 -F src/vdbeaux.c b9772e4134a17f5b42d32761f5119467815c2458 +F src/vdbeaux.c 2fc9c59009dfb63732c2c89b18aaeb3ca172f7b3 F src/vdbeblob.c 3e82a797b60c3b9fed7b8de8c539ca7607874937 F src/vdbemem.c 1b8d5b770a9a3c6d8ed3463104a382bffa6f15c2 F src/vdbesort.c 91fda3909326860382b0ca8aa251e609c6a9d62c @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e2cd79aa3104c51035bf29c548c322564731b75f -R ced10222d4b6fcbb24f085bf78455885 +P 945f82bc44c5a431c0fef0d36cf016671d7ade1e +R 20b3d4fe5709ed2dfc36e6f20fdfd324 U drh -Z 527ba3ca85dfce0ba6019f348119d7e0 +Z e13d1f1073df22720e2a91e1bec2d09c diff --git a/manifest.uuid b/manifest.uuid index 098948e590..760c9eeef6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -945f82bc44c5a431c0fef0d36cf016671d7ade1e \ No newline at end of file +984a96d79656c1b095aba1f88aca4bb787ba0bd8 \ No newline at end of file diff --git a/src/build.c b/src/build.c index 2302fc20b1..34073d1a3b 100644 --- a/src/build.c +++ b/src/build.c @@ -146,7 +146,6 @@ void sqlite3FinishCoding(Parse *pParse){ assert( !pParse->isMultiWrite || sqlite3VdbeAssertMayAbort(v, pParse->mayAbort)); if( v ){ - while( sqlite3VdbeDeletePriorOpcode(v, OP_Close) ){} sqlite3VdbeAddOp0(v, OP_Halt); #if SQLITE_USER_AUTHENTICATION diff --git a/src/sqliteInt.h b/src/sqliteInt.h index cba894db05..579685245f 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2899,7 +2899,6 @@ struct Parse { int nSet; /* Number of sets used so far */ int nOpAlloc; /* Number of slots allocated for Vdbe.aOp[] */ int szOpAlloc; /* Bytes of memory space allocated for Vdbe.aOp[] */ - int iFixedOp; /* Never back out opcodes iFixedOp-1 or earlier */ int ckBase; /* Base register of data during check constraints */ int iSelfTab; /* Table of an index whose exprs are being coded */ int iCacheLevel; /* ColCache valid when aColCache[].iLevel<=iCacheLevel */ diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 43f235c7bd..8e34a480ca 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -374,7 +374,6 @@ void sqlite3VdbeResolveLabel(Vdbe *v, int x){ if( p->aLabel ){ p->aLabel[j] = v->nOp; } - p->iFixedOp = v->nOp - 1; } /* @@ -773,7 +772,6 @@ void sqlite3VdbeChangeP5(Vdbe *p, u8 p5){ ** the address of the next instruction to be coded. */ void sqlite3VdbeJumpHere(Vdbe *p, int addr){ - p->pParse->iFixedOp = p->nOp - 1; sqlite3VdbeChangeP2(p, addr, p->nOp); } @@ -896,7 +894,7 @@ int sqlite3VdbeChangeToNoop(Vdbe *p, int addr){ ** then remove it. Return true if and only if an opcode was removed. */ int sqlite3VdbeDeletePriorOpcode(Vdbe *p, u8 op){ - if( (p->nOp-1)>(p->pParse->iFixedOp) && p->aOp[p->nOp-1].opcode==op ){ + if( p->nOp>0 && p->aOp[p->nOp-1].opcode==op ){ return sqlite3VdbeChangeToNoop(p, p->nOp-1); }else{ return 0; From dd3bfe8648d60444e3e4292470cf36fe618ee923 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 29 Sep 2016 20:28:34 +0000 Subject: [PATCH 0877/1484] Small size and performance optimization to sqlite3VdbeChangeP5(). FossilOrigin-Name: 3c93c8f5bbf54ed2a331079b28fdd94eb0e59e69 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbeaux.c | 3 ++- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 21be3d686a..f7124aa631 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sthe\speep-hole\soptimization\sof\sremoving\sOP_Close\sopcodes\sthat\scome\nbefore\sOP_Halt,\sas\sthe\sextra\swork\sof\sremoving\sthose\sopcodes\suses\smore\scycles\nthan\sjust\srunning\sthem. -D 2016-09-29T19:50:02.416 +C Small\ssize\sand\sperformance\soptimization\sto\ssqlite3VdbeChangeP5(). +D 2016-09-29T20:28:34.145 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -457,7 +457,7 @@ F src/vdbe.c 6781329737f4bb140834cd32b15e93b83d60858e F src/vdbe.h c044be7050ac6bf596eecc6ab159f5dbc020a3b7 F src/vdbeInt.h 581b737c2f6e413c555469480efe31796a71bcad F src/vdbeapi.c 794f80669e9e3b9b3edc78d80c15968985c7bf21 -F src/vdbeaux.c 2fc9c59009dfb63732c2c89b18aaeb3ca172f7b3 +F src/vdbeaux.c 041dd9dd28dfe57dc0104a98c067cadd808a059c F src/vdbeblob.c 3e82a797b60c3b9fed7b8de8c539ca7607874937 F src/vdbemem.c 1b8d5b770a9a3c6d8ed3463104a382bffa6f15c2 F src/vdbesort.c 91fda3909326860382b0ca8aa251e609c6a9d62c @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 945f82bc44c5a431c0fef0d36cf016671d7ade1e -R 20b3d4fe5709ed2dfc36e6f20fdfd324 +P 984a96d79656c1b095aba1f88aca4bb787ba0bd8 +R 6df17638e558d58efae8855e65d389dc U drh -Z e13d1f1073df22720e2a91e1bec2d09c +Z 789252daa215e2c9b52dcdaab286dc1e diff --git a/manifest.uuid b/manifest.uuid index 760c9eeef6..e64d038a8f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -984a96d79656c1b095aba1f88aca4bb787ba0bd8 \ No newline at end of file +3c93c8f5bbf54ed2a331079b28fdd94eb0e59e69 \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 8e34a480ca..de7b5d14b1 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -764,7 +764,8 @@ void sqlite3VdbeChangeP3(Vdbe *p, u32 addr, int val){ sqlite3VdbeGetOp(p,addr)->p3 = val; } void sqlite3VdbeChangeP5(Vdbe *p, u8 p5){ - if( !p->db->mallocFailed ) p->aOp[p->nOp-1].p5 = p5; + assert( p->nOp>0 || p->db->mallocFailed ); + if( p->nOp>0 ) p->aOp[p->nOp-1].p5 = p5; } /* From 2a1df937ab0085f7ed038511e2f74a44d1df2e65 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 30 Sep 2016 17:46:44 +0000 Subject: [PATCH 0878/1484] Avoid unnecessary Mem initializations when generating a new sqlite3_stmt object. FossilOrigin-Name: 47ae1cda8dc255d100aeb8cb90ea4c9e449509be --- manifest | 16 +++++++------- manifest.uuid | 2 +- src/vdbe.c | 2 ++ src/vdbeaux.c | 58 ++++++++++++++++++++++++++++----------------------- src/vdbemem.c | 1 + 5 files changed, 44 insertions(+), 35 deletions(-) diff --git a/manifest b/manifest index f7124aa631..6a0491fe98 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Small\ssize\sand\sperformance\soptimization\sto\ssqlite3VdbeChangeP5(). -D 2016-09-29T20:28:34.145 +C Avoid\sunnecessary\sMem\sinitializations\swhen\sgenerating\sa\snew\ssqlite3_stmt\nobject. +D 2016-09-30T17:46:44.827 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -453,13 +453,13 @@ F src/update.c 8179e699dbd45b92934fd02d3d8e3732e8da8802 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 3e2da6101888d073e79ecc6af5e0a2f70fa1e498 F src/vacuum.c 913970b9d86dd6c2b8063ef1af421880f1464ec3 -F src/vdbe.c 6781329737f4bb140834cd32b15e93b83d60858e +F src/vdbe.c 51e754eec26d892abc6279f5e949545af68ec1b3 F src/vdbe.h c044be7050ac6bf596eecc6ab159f5dbc020a3b7 F src/vdbeInt.h 581b737c2f6e413c555469480efe31796a71bcad F src/vdbeapi.c 794f80669e9e3b9b3edc78d80c15968985c7bf21 -F src/vdbeaux.c 041dd9dd28dfe57dc0104a98c067cadd808a059c +F src/vdbeaux.c 240fecf157b6a3deb3c68abe614ae30cb8e884cd F src/vdbeblob.c 3e82a797b60c3b9fed7b8de8c539ca7607874937 -F src/vdbemem.c 1b8d5b770a9a3c6d8ed3463104a382bffa6f15c2 +F src/vdbemem.c 1c330522e6b6e4ddd2ff63c4c0dfafa20c3965a7 F src/vdbesort.c 91fda3909326860382b0ca8aa251e609c6a9d62c F src/vdbetrace.c 41963d5376f0349842b5fc4aaaaacd7d9cdc0834 F src/vtab.c e02cacb5c7ae742631edeb9ae9f53d399f093fd8 @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 984a96d79656c1b095aba1f88aca4bb787ba0bd8 -R 6df17638e558d58efae8855e65d389dc +P 3c93c8f5bbf54ed2a331079b28fdd94eb0e59e69 +R 3cf19b11ac694d678c7ce4092749d94e U drh -Z 789252daa215e2c9b52dcdaab286dc1e +Z 262005117be631ec889db38469ab8967 diff --git a/manifest.uuid b/manifest.uuid index e64d038a8f..bfa720094c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3c93c8f5bbf54ed2a331079b28fdd94eb0e59e69 \ No newline at end of file +47ae1cda8dc255d100aeb8cb90ea4c9e449509be \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index c32e0ea43e..25b507f37f 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -1136,11 +1136,13 @@ case OP_Null: { /* out2 */ cnt = pOp->p3-pOp->p2; assert( pOp->p3<=(p->nMem+1 - p->nCursor) ); pOut->flags = nullFlag = pOp->p1 ? (MEM_Null|MEM_Cleared) : MEM_Null; + pOut->n = 0; while( cnt>0 ){ pOut++; memAboutToChange(p, pOut); sqlite3VdbeMemSetNull(pOut); pOut->flags = nullFlag; + pOut->n = 0; cnt--; } break; diff --git a/src/vdbeaux.c b/src/vdbeaux.c index de7b5d14b1..2e3a4eaaf1 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -1458,6 +1458,21 @@ void sqlite3VdbePrintOp(FILE *pOut, int pc, Op *pOp){ } #endif +/* +** Initialize an array of N Mem element. +*/ +static void initMemArray(Mem *p, int N, sqlite3 *db, u16 flags){ + while( (N--)>0 ){ + p->db = db; + p->flags = flags; + p->szMalloc = 0; +#ifdef SQLITE_DEBUG + p->pScopyFrom = 0; +#endif + p++; + } +} + /* ** Release an array of N Mem elements */ @@ -1669,6 +1684,7 @@ int sqlite3VdbeList( pMem->flags = MEM_Str|MEM_Term; zP4 = displayP4(pOp, pMem->z, pMem->szMalloc); if( zP4!=pMem->z ){ + pMem->n = 0; sqlite3VdbeMemSetStr(pMem, zP4, -1, SQLITE_UTF8, 0); }else{ assert( pMem->z!=0 ); @@ -1900,10 +1916,7 @@ void sqlite3VdbeMakeReady( assert( EIGHT_BYTE_ALIGNMENT(x.pSpace) ); x.nFree = ROUNDDOWN8(pParse->szOpAlloc - n); /* Bytes of unused memory */ assert( x.nFree>=0 ); - if( x.nFree>0 ){ - memset(x.pSpace, 0, x.nFree); - assert( EIGHT_BYTE_ALIGNMENT(&x.pSpace[x.nFree]) ); - } + assert( EIGHT_BYTE_ALIGNMENT(&x.pSpace[x.nFree]) ); resolveP2Values(p, &nArg); p->usesStmtJournal = (u8)(pParse->isMultiWrite && pParse->mayAbort); @@ -1932,30 +1945,27 @@ void sqlite3VdbeMakeReady( p->anExec = allocSpace(&x, p->anExec, p->nOp*sizeof(i64)); #endif if( x.nNeeded==0 ) break; - x.pSpace = p->pFree = sqlite3DbMallocZero(db, x.nNeeded); + x.pSpace = p->pFree = sqlite3DbMallocRawNN(db, x.nNeeded); x.nFree = x.nNeeded; }while( !db->mallocFailed ); - p->nCursor = nCursor; - if( p->aVar ){ - p->nVar = (ynVar)nVar; - for(n=0; naVar[n].flags = MEM_Null; - p->aVar[n].db = db; - } - } p->nzVar = pParse->nzVar; p->azVar = pParse->azVar; pParse->nzVar = 0; pParse->azVar = 0; - if( p->aMem ){ - p->nMem = nMem; - for(n=0; naMem[n].flags = MEM_Undefined; - p->aMem[n].db = db; - } - } p->explain = pParse->explain; + if( db->mallocFailed==0 ){ + p->nCursor = nCursor; + p->nVar = (ynVar)nVar; + initMemArray(p->aVar, nVar, db, MEM_Null); + p->nMem = nMem; + initMemArray(p->aMem, nMem, db, MEM_Undefined); + memset(p->apArg, 0, nArg*sizeof(Mem*)); + memset(p->apCsr, 0, nCursor*sizeof(VdbeCursor*)); +#ifdef SQLITE_ENABLE_STMT_SCANSTATUS + memset(p->anExec, 0, p->nOp*sizeof(i64)); +#endif + } sqlite3VdbeRewind(p); } @@ -2107,13 +2117,9 @@ void sqlite3VdbeSetNumCols(Vdbe *p, int nResColumn){ sqlite3DbFree(db, p->aColName); n = nResColumn*COLNAME_N; p->nResColumn = (u16)nResColumn; - p->aColName = pColName = (Mem*)sqlite3DbMallocZero(db, sizeof(Mem)*n ); + p->aColName = pColName = (Mem*)sqlite3DbMallocRawNN(db, sizeof(Mem)*n ); if( p->aColName==0 ) return; - while( n-- > 0 ){ - pColName->flags = MEM_Null; - pColName->db = p->db; - pColName++; - } + initMemArray(p->aColName, n, p->db, MEM_Null); } /* diff --git a/src/vdbemem.c b/src/vdbemem.c index fb4f704f5d..d009f804df 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -293,6 +293,7 @@ int sqlite3VdbeMemStringify(Mem *pMem, u8 enc, u8 bForce){ if( sqlite3VdbeMemClearAndResize(pMem, nByte) ){ + pMem->enc = 0; return SQLITE_NOMEM_BKPT; } From 1d96cc60d0f7855d1e9362e4b6b61650168fe072 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 30 Sep 2016 18:35:36 +0000 Subject: [PATCH 0879/1484] Remove unnecessary fields from the Parse object. FossilOrigin-Name: 814e41da3563eecf5514811bc8ab2df4f5cc0d4b --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/build.c | 24 +++++++----------------- src/sqliteInt.h | 2 -- 4 files changed, 15 insertions(+), 27 deletions(-) diff --git a/manifest b/manifest index 6a0491fe98..d09c186f8d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sunnecessary\sMem\sinitializations\swhen\sgenerating\sa\snew\ssqlite3_stmt\nobject. -D 2016-09-30T17:46:44.827 +C Remove\sunnecessary\sfields\sfrom\sthe\sParse\sobject. +D 2016-09-30T18:35:36.517 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -332,7 +332,7 @@ F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 F src/btree.c 56e1732ecfb3731efcb216266ec26b1b96e5e8c9 F src/btree.h d05b2fcc290991a8a3d9ea1816ddd55a4359dcde F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 -F src/build.c ab95712203bfbd83d65c878934201624f778e469 +F src/build.c 4d01b74ea76f4295f83910feb8fdb9635952904a F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7 @@ -391,7 +391,7 @@ F src/shell.c b80396d2fadce4681397707e30078bf416e1dec2 F src/sqlite.h.in 2683a291ed8db5228024267be6421f0de507b80e F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae -F src/sqliteInt.h 2599e8cc7e74733bd980b1c58712f975f914ef01 +F src/sqliteInt.h 8bf4d8ac59a393d2db34cd47c1f21e8f3efd49bc F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 3c93c8f5bbf54ed2a331079b28fdd94eb0e59e69 -R 3cf19b11ac694d678c7ce4092749d94e +P 47ae1cda8dc255d100aeb8cb90ea4c9e449509be +R 3a2fcadea5b6198ddf05a323497d9130 U drh -Z 262005117be631ec889db38469ab8967 +Z 7276f26b121b18d3ecda7a3236f1b99c diff --git a/manifest.uuid b/manifest.uuid index bfa720094c..82d4b6b1da 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -47ae1cda8dc255d100aeb8cb90ea4c9e449509be \ No newline at end of file +814e41da3563eecf5514811bc8ab2df4f5cc0d4b \ No newline at end of file diff --git a/src/build.c b/src/build.c index 34073d1a3b..d1fc437844 100644 --- a/src/build.c +++ b/src/build.c @@ -172,14 +172,16 @@ void sqlite3FinishCoding(Parse *pParse){ assert( sqlite3VdbeGetOp(v, 0)->opcode==OP_Init ); sqlite3VdbeJumpHere(v, 0); for(iDb=0; iDbnDb; iDb++){ + Schema *pSchema; if( DbMaskTest(pParse->cookieMask, iDb)==0 ) continue; sqlite3VdbeUsesBtree(v, iDb); + pSchema = db->aDb[iDb].pSchema; sqlite3VdbeAddOp4Int(v, OP_Transaction, /* Opcode */ iDb, /* P1 */ DbMaskTest(pParse->writeMask,iDb), /* P2 */ - pParse->cookieValue[iDb], /* P3 */ - db->aDb[iDb].pSchema->iGeneration /* P4 */ + pSchema->schema_cookie, /* P3 */ + pSchema->iGeneration /* P4 */ ); if( db->init.busy==0 ) sqlite3VdbeChangeP5(v, 1); VdbeComment((v, @@ -230,16 +232,6 @@ void sqlite3FinishCoding(Parse *pParse){ }else{ pParse->rc = SQLITE_ERROR; } - - /* We are done with this Parse object. There is no need to de-initialize it */ -#if 0 - pParse->colNamesSet = 0; - pParse->nTab = 0; - pParse->nMem = 0; - pParse->nSet = 0; - pParse->nVar = 0; - DbMaskZero(pParse->cookieMask); -#endif } /* @@ -4043,15 +4035,13 @@ int sqlite3OpenTempDatabase(Parse *pParse){ */ void sqlite3CodeVerifySchema(Parse *pParse, int iDb){ Parse *pToplevel = sqlite3ParseToplevel(pParse); - sqlite3 *db = pToplevel->db; - assert( iDb>=0 && iDbnDb ); - assert( db->aDb[iDb].pBt!=0 || iDb==1 ); + assert( iDb>=0 && iDbdb->nDb ); + assert( pParse->db->aDb[iDb].pBt!=0 || iDb==1 ); assert( iDbdb, iDb, 0) ); if( DbMaskTest(pToplevel->cookieMask, iDb)==0 ){ DbMaskSet(pToplevel->cookieMask, iDb); - pToplevel->cookieValue[iDb] = db->aDb[iDb].pSchema->schema_cookie; if( !OMIT_TEMPDB && iDb==1 ){ sqlite3OpenTempDatabase(pToplevel); } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 579685245f..cf4a253de7 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2896,7 +2896,6 @@ struct Parse { int nErr; /* Number of errors seen */ int nTab; /* Number of previously allocated VDBE cursors */ int nMem; /* Number of memory cells used so far */ - int nSet; /* Number of sets used so far */ int nOpAlloc; /* Number of slots allocated for Vdbe.aOp[] */ int szOpAlloc; /* Bytes of memory space allocated for Vdbe.aOp[] */ int ckBase; /* Base register of data during check constraints */ @@ -2917,7 +2916,6 @@ struct Parse { Token constraintName;/* Name of the constraint currently being parsed */ yDbMask writeMask; /* Start a write transaction on these databases */ yDbMask cookieMask; /* Bitmask of schema verified databases */ - int cookieValue[SQLITE_MAX_ATTACHED+2]; /* Values of cookies to verify */ int regRowid; /* Register holding rowid of CREATE TABLE entry */ int regRoot; /* Register holding root page number for new objects */ int nMaxArg; /* Max args passed to user function by sub-program */ From e05950d8788b721565043405f26afa3e0a8fdf5c Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 30 Sep 2016 19:14:32 +0000 Subject: [PATCH 0880/1484] Another simplification to the Parse object. FossilOrigin-Name: c1419727f5e4cb3ef63b5853b6ef3b1e53af0651 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/sqliteInt.h | 1 - 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index d09c186f8d..5f89cfbd3e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sunnecessary\sfields\sfrom\sthe\sParse\sobject. -D 2016-09-30T18:35:36.517 +C Another\ssimplification\sto\sthe\sParse\sobject. +D 2016-09-30T19:14:32.049 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -391,7 +391,7 @@ F src/shell.c b80396d2fadce4681397707e30078bf416e1dec2 F src/sqlite.h.in 2683a291ed8db5228024267be6421f0de507b80e F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae -F src/sqliteInt.h 8bf4d8ac59a393d2db34cd47c1f21e8f3efd49bc +F src/sqliteInt.h dea74ebe041661eb9a4924140c80b1731a4b5262 F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 47ae1cda8dc255d100aeb8cb90ea4c9e449509be -R 3a2fcadea5b6198ddf05a323497d9130 +P 814e41da3563eecf5514811bc8ab2df4f5cc0d4b +R 608d1a96b91ee96ffbbec71d9c1f3711 U drh -Z 7276f26b121b18d3ecda7a3236f1b99c +Z 828299b9894d67f8570c817a01bf6c81 diff --git a/manifest.uuid b/manifest.uuid index 82d4b6b1da..585ee1fd87 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -814e41da3563eecf5514811bc8ab2df4f5cc0d4b \ No newline at end of file +c1419727f5e4cb3ef63b5853b6ef3b1e53af0651 \ No newline at end of file diff --git a/src/sqliteInt.h b/src/sqliteInt.h index cf4a253de7..7e8ee31ea7 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2955,7 +2955,6 @@ struct Parse { u8 declareVtab; /* True if inside sqlite3_declare_vtab() */ int nVtabLock; /* Number of virtual tables to lock */ #endif - int nAlias; /* Number of aliased result set columns */ int nHeight; /* Expression tree height of current sub-select */ #ifndef SQLITE_OMIT_EXPLAIN int iSelectId; /* ID of current select for EXPLAIN output */ From 9b40d13f437429abae07b4e03fd18647696c98e4 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 30 Sep 2016 20:22:27 +0000 Subject: [PATCH 0881/1484] Fix the Parse.aColCache column cache so that all of the valid entries are in the first Parse.nColCache slots. FossilOrigin-Name: 6028502059ccbd3699637b7a70a6d8ce1b7c3dad --- manifest | 14 +++--- manifest.uuid | 2 +- src/expr.c | 126 +++++++++++++++++++++----------------------------- src/vdbeaux.c | 3 +- 4 files changed, 61 insertions(+), 84 deletions(-) diff --git a/manifest b/manifest index 5f89cfbd3e..5681d1db00 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Another\ssimplification\sto\sthe\sParse\sobject. -D 2016-09-30T19:14:32.049 +C Fix\sthe\sParse.aColCache\scolumn\scache\sso\sthat\sall\sof\sthe\svalid\sentries\sare\s\nin\sthe\sfirst\sParse.nColCache\sslots. +D 2016-09-30T20:22:27.729 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -339,7 +339,7 @@ F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7 F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c cb3f6300df24c26c609778b2731f82644b5532ec -F src/expr.c a27090ab1d9d9901c64974c43588a38a486d6a55 +F src/expr.c f0ea2e1a7af0047b71e40dfed6902249129710e5 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c b9ca262f6ad4d030a3cab737ebf9b0b3c8b4ac80 F src/func.c 29cc9acb170ec1387b9f63eb52cd85f8de96c771 @@ -457,7 +457,7 @@ F src/vdbe.c 51e754eec26d892abc6279f5e949545af68ec1b3 F src/vdbe.h c044be7050ac6bf596eecc6ab159f5dbc020a3b7 F src/vdbeInt.h 581b737c2f6e413c555469480efe31796a71bcad F src/vdbeapi.c 794f80669e9e3b9b3edc78d80c15968985c7bf21 -F src/vdbeaux.c 240fecf157b6a3deb3c68abe614ae30cb8e884cd +F src/vdbeaux.c 5f97a1aed18b5b064407652654f73f3cd4836a87 F src/vdbeblob.c 3e82a797b60c3b9fed7b8de8c539ca7607874937 F src/vdbemem.c 1c330522e6b6e4ddd2ff63c4c0dfafa20c3965a7 F src/vdbesort.c 91fda3909326860382b0ca8aa251e609c6a9d62c @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 814e41da3563eecf5514811bc8ab2df4f5cc0d4b -R 608d1a96b91ee96ffbbec71d9c1f3711 +P c1419727f5e4cb3ef63b5853b6ef3b1e53af0651 +R 1c5f450e057ea86e47df56b91a0fd28e U drh -Z 828299b9894d67f8570c817a01bf6c81 +Z 0c5e41f0df0638c8d6aea45323876192 diff --git a/manifest.uuid b/manifest.uuid index 585ee1fd87..423c99ffef 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c1419727f5e4cb3ef63b5853b6ef3b1e53af0651 \ No newline at end of file +6028502059ccbd3699637b7a70a6d8ce1b7c3dad \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index e8c245ec4d..0640029cb0 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2964,32 +2964,19 @@ static void codeInteger(Parse *pParse, Expr *pExpr, int negFlag, int iMem){ } } -#if defined(SQLITE_DEBUG) /* -** Verify the consistency of the column cache +** Erase column-cache entry number i */ -static int cacheIsValid(Parse *pParse){ - int i, n; - for(i=n=0; iaColCache[i].iReg>0 ) n++; - } - return n==pParse->nColCache; -} -#endif - -/* -** Clear a cache entry. -*/ -static void cacheEntryClear(Parse *pParse, struct yColCache *p){ - if( p->tempReg ){ +static void cacheEntryClear(Parse *pParse, int i){ + if( pParse->aColCache[i].tempReg ){ if( pParse->nTempRegaTempReg) ){ - pParse->aTempReg[pParse->nTempReg++] = p->iReg; + pParse->aTempReg[pParse->nTempReg++] = pParse->aColCache[i].iReg; } - p->tempReg = 0; } - p->iReg = 0; pParse->nColCache--; - assert( pParse->db->mallocFailed || cacheIsValid(pParse) ); + if( inColCache ){ + pParse->aColCache[i] = pParse->aColCache[pParse->nColCache]; + } } @@ -3019,46 +3006,33 @@ void sqlite3ExprCacheStore(Parse *pParse, int iTab, int iCol, int iReg){ ** that the object will never already be in cache. Verify this guarantee. */ #ifndef NDEBUG - for(i=0, p=pParse->aColCache; iiReg==0 || p->iTable!=iTab || p->iColumn!=iCol ); + for(i=0, p=pParse->aColCache; inColCache; i++, p++){ + assert( p->iTable!=iTab || p->iColumn!=iCol ); } #endif - /* Find an empty slot and replace it */ - for(i=0, p=pParse->aColCache; iiReg==0 ){ - p->iLevel = pParse->iCacheLevel; - p->iTable = iTab; - p->iColumn = iCol; - p->iReg = iReg; - p->tempReg = 0; - p->lru = pParse->iCacheCnt++; - pParse->nColCache++; - assert( pParse->db->mallocFailed || cacheIsValid(pParse) ); - return; + /* If the cache is already full, delete the least recently used entry */ + if( pParse->nColCache>=SQLITE_N_COLCACHE ){ + minLru = 0x7fffffff; + idxLru = -1; + for(i=0, p=pParse->aColCache; ilrulru; + } } + p = &pParse->aColCache[idxLru]; + }else{ + p = &pParse->aColCache[pParse->nColCache++]; } - /* Replace the last recently used */ - minLru = 0x7fffffff; - idxLru = -1; - for(i=0, p=pParse->aColCache; ilrulru; - } - } - if( ALWAYS(idxLru>=0) ){ - p = &pParse->aColCache[idxLru]; - p->iLevel = pParse->iCacheLevel; - p->iTable = iTab; - p->iColumn = iCol; - p->iReg = iReg; - p->tempReg = 0; - p->lru = pParse->iCacheCnt++; - assert( cacheIsValid(pParse) ); - return; - } + /* Add the new entry to the end of the cache */ + p->iLevel = pParse->iCacheLevel; + p->iTable = iTab; + p->iColumn = iCol; + p->iReg = iReg; + p->tempReg = 0; + p->lru = pParse->iCacheCnt++; } /* @@ -3066,13 +3040,14 @@ void sqlite3ExprCacheStore(Parse *pParse, int iTab, int iCol, int iReg){ ** Purge the range of registers from the column cache. */ void sqlite3ExprCacheRemove(Parse *pParse, int iReg, int nReg){ - struct yColCache *p; - if( iReg<=0 || pParse->nColCache==0 ) return; - p = &pParse->aColCache[SQLITE_N_COLCACHE-1]; - while(1){ - if( p->iReg >= iReg && p->iReg < iReg+nReg ) cacheEntryClear(pParse, p); - if( p==pParse->aColCache ) break; - p--; + int i = 0; + while( inColCache ){ + struct yColCache *p = &pParse->aColCache[i]; + if( p->iReg >= iReg && p->iReg < iReg+nReg ){ + cacheEntryClear(pParse, i); + }else{ + i++; + } } } @@ -3096,8 +3071,7 @@ void sqlite3ExprCachePush(Parse *pParse){ ** the cache to the state it was in prior the most recent Push. */ void sqlite3ExprCachePop(Parse *pParse){ - int i; - struct yColCache *p; + int i = 0; assert( pParse->iCacheLevel>=1 ); pParse->iCacheLevel--; #ifdef SQLITE_DEBUG @@ -3105,9 +3079,11 @@ void sqlite3ExprCachePop(Parse *pParse){ printf("POP to %d\n", pParse->iCacheLevel); } #endif - for(i=0, p=pParse->aColCache; iiReg && p->iLevel>pParse->iCacheLevel ){ - cacheEntryClear(pParse, p); + while( inColCache ){ + if( pParse->aColCache[i].iLevel>pParse->iCacheLevel ){ + cacheEntryClear(pParse, i); + }else{ + i++; } } } @@ -3121,7 +3097,7 @@ void sqlite3ExprCachePop(Parse *pParse){ static void sqlite3ExprCachePinRegister(Parse *pParse, int iReg){ int i; struct yColCache *p; - for(i=0, p=pParse->aColCache; iaColCache; inColCache; i++, p++){ if( p->iReg==iReg ){ p->tempReg = 0; } @@ -3199,7 +3175,7 @@ int sqlite3ExprCodeGetColumn( int i; struct yColCache *p; - for(i=0, p=pParse->aColCache; iaColCache; inColCache; i++, p++){ if( p->iReg>0 && p->iTable==iTable && p->iColumn==iColumn ){ p->lru = pParse->iCacheCnt++; sqlite3ExprCachePinRegister(pParse, p->iReg); @@ -3232,18 +3208,20 @@ void sqlite3ExprCodeGetColumnToReg( */ void sqlite3ExprCacheClear(Parse *pParse){ int i; - struct yColCache *p; #if SQLITE_DEBUG if( pParse->db->flags & SQLITE_VdbeAddopTrace ){ printf("CLEAR\n"); } #endif - for(i=0, p=pParse->aColCache; iiReg ){ - cacheEntryClear(pParse, p); + for(i=0; inColCache; i++){ + if( pParse->aColCache[i].tempReg + && pParse->nTempRegaTempReg) + ){ + pParse->aTempReg[pParse->nTempReg++] = pParse->aColCache[i].iReg; } } + pParse->nColCache = 0; } /* @@ -3275,7 +3253,7 @@ void sqlite3ExprCodeMove(Parse *pParse, int iFrom, int iTo, int nReg){ static int usedAsColumnCache(Parse *pParse, int iFrom, int iTo){ int i; struct yColCache *p; - for(i=0, p=pParse->aColCache; iaColCache; inColCache; i++, p++){ int r = p->iReg; if( r>=iFrom && r<=iTo ) return 1; /*NO_TEST*/ } @@ -4971,7 +4949,7 @@ void sqlite3ReleaseTempReg(Parse *pParse, int iReg){ if( iReg && pParse->nTempRegaTempReg) ){ int i; struct yColCache *p; - for(i=0, p=pParse->aColCache; iaColCache; inColCache; i++, p++){ if( p->iReg==iReg ){ p->tempReg = 1; return; diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 2e3a4eaaf1..86f5096a8b 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -184,9 +184,8 @@ int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){ if( p->db->flags & SQLITE_VdbeAddopTrace ){ int jj, kk; Parse *pParse = p->pParse; - for(jj=kk=0; jjnColCache; jj++){ struct yColCache *x = pParse->aColCache + jj; - if( x->iLevel>pParse->iCacheLevel || x->iReg==0 ) continue; printf(" r[%d]={%d:%d}", x->iReg, x->iTable, x->iColumn); kk++; } From 94881d732bba43c72d31e4f53d751bd0f17b359a Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 30 Sep 2016 21:20:37 +0000 Subject: [PATCH 0882/1484] Fix an always-true conditional left over from the previous commit. FossilOrigin-Name: ab12fce3318db447995e1465f34a1e43cd623d6a --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/expr.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 5681d1db00..03624a18e0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\sParse.aColCache\scolumn\scache\sso\sthat\sall\sof\sthe\svalid\sentries\sare\s\nin\sthe\sfirst\sParse.nColCache\sslots. -D 2016-09-30T20:22:27.729 +C Fix\san\salways-true\sconditional\sleft\sover\sfrom\sthe\sprevious\scommit. +D 2016-09-30T21:20:37.770 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -339,7 +339,7 @@ F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7 F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c cb3f6300df24c26c609778b2731f82644b5532ec -F src/expr.c f0ea2e1a7af0047b71e40dfed6902249129710e5 +F src/expr.c ebb5174d26a653a7a6f5f300840352c7db932d86 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c b9ca262f6ad4d030a3cab737ebf9b0b3c8b4ac80 F src/func.c 29cc9acb170ec1387b9f63eb52cd85f8de96c771 @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P c1419727f5e4cb3ef63b5853b6ef3b1e53af0651 -R 1c5f450e057ea86e47df56b91a0fd28e +P 6028502059ccbd3699637b7a70a6d8ce1b7c3dad +R a6256cdf36804c151ce32af7b8e56062 U drh -Z 0c5e41f0df0638c8d6aea45323876192 +Z 3fef1d146c2cf0fe38cc3824ec800a2a diff --git a/manifest.uuid b/manifest.uuid index 423c99ffef..1de6344050 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6028502059ccbd3699637b7a70a6d8ce1b7c3dad \ No newline at end of file +ab12fce3318db447995e1465f34a1e43cd623d6a \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 0640029cb0..31128cc3d4 100644 --- a/src/expr.c +++ b/src/expr.c @@ -3176,7 +3176,7 @@ int sqlite3ExprCodeGetColumn( struct yColCache *p; for(i=0, p=pParse->aColCache; inColCache; i++, p++){ - if( p->iReg>0 && p->iTable==iTable && p->iColumn==iColumn ){ + if( p->iTable==iTable && p->iColumn==iColumn ){ p->lru = pParse->iCacheCnt++; sqlite3ExprCachePinRegister(pParse, p->iReg); return p->iReg; From cd9af608e1385772a3a08b86ac3675ff7d9f8270 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 30 Sep 2016 22:24:29 +0000 Subject: [PATCH 0883/1484] Avoid initializing the column-cache section of the Parse object, since entries in the cache will be initialized as they are used, and avoiding the initial memset() saves many CPU cycles. FossilOrigin-Name: 63cf7eafae5c3c1379edf416c5157010c7c120b5 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/build.c | 9 ++++----- src/prepare.c | 4 +++- src/sqliteInt.h | 30 ++++++++++++++++++++++-------- 5 files changed, 38 insertions(+), 23 deletions(-) diff --git a/manifest b/manifest index 03624a18e0..4d02da0553 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\salways-true\sconditional\sleft\sover\sfrom\sthe\sprevious\scommit. -D 2016-09-30T21:20:37.770 +C Avoid\sinitializing\sthe\scolumn-cache\ssection\sof\sthe\sParse\sobject,\ssince\sentries\nin\sthe\scache\swill\sbe\sinitialized\sas\sthey\sare\sused,\sand\savoiding\sthe\sinitial\nmemset()\ssaves\smany\sCPU\scycles. +D 2016-09-30T22:24:29.959 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -332,7 +332,7 @@ F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 F src/btree.c 56e1732ecfb3731efcb216266ec26b1b96e5e8c9 F src/btree.h d05b2fcc290991a8a3d9ea1816ddd55a4359dcde F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 -F src/build.c 4d01b74ea76f4295f83910feb8fdb9635952904a +F src/build.c 59dcfdc1ee55439d069af301ef7f2e84421b5102 F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7 @@ -381,7 +381,7 @@ F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 F src/pcache1.c 4bb7a6a5300c67d0b033d25adb509c120c03e812 F src/pragma.c d932ba278654617cdd281f88a790a3185fca7c44 F src/pragma.h 64c78a648751b9f4f297276c4eb7507b14b4628c -F src/prepare.c 0fcf16eaacc90c1059055519a76b75b516a59a88 +F src/prepare.c 3c8b1bc8799a794aa2e825db1a977e93487b01d4 F src/printf.c a5f0ca08ddede803c241266abb46356ec748ded1 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c 3c3cf0dc719cd2a32ab5c1e10c26481dd565492e @@ -391,7 +391,7 @@ F src/shell.c b80396d2fadce4681397707e30078bf416e1dec2 F src/sqlite.h.in 2683a291ed8db5228024267be6421f0de507b80e F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae -F src/sqliteInt.h dea74ebe041661eb9a4924140c80b1731a4b5262 +F src/sqliteInt.h 16f22a872a901d4a455a4a65bbbc1658cc2159f4 F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 6028502059ccbd3699637b7a70a6d8ce1b7c3dad -R a6256cdf36804c151ce32af7b8e56062 +P ab12fce3318db447995e1465f34a1e43cd623d6a +R 0a3a2f22297400a0c501bf7a0c2b0caa U drh -Z 3fef1d146c2cf0fe38cc3824ec800a2a +Z fb861c120dabfe63359c1b99efc6b84b diff --git a/manifest.uuid b/manifest.uuid index 1de6344050..e3eee84b50 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ab12fce3318db447995e1465f34a1e43cd623d6a \ No newline at end of file +63cf7eafae5c3c1379edf416c5157010c7c120b5 \ No newline at end of file diff --git a/src/build.c b/src/build.c index d1fc437844..508e747ea6 100644 --- a/src/build.c +++ b/src/build.c @@ -251,8 +251,7 @@ void sqlite3NestedParse(Parse *pParse, const char *zFormat, ...){ char *zSql; char *zErrMsg = 0; sqlite3 *db = pParse->db; -# define SAVE_SZ (sizeof(Parse) - offsetof(Parse,nVar)) - char saveBuf[SAVE_SZ]; + char saveBuf[PARSE_TAIL_SZ]; if( pParse->nErr ) return; assert( pParse->nested<10 ); /* Nesting should only be of limited depth */ @@ -263,12 +262,12 @@ void sqlite3NestedParse(Parse *pParse, const char *zFormat, ...){ return; /* A malloc must have failed */ } pParse->nested++; - memcpy(saveBuf, &pParse->nVar, SAVE_SZ); - memset(&pParse->nVar, 0, SAVE_SZ); + memcpy(saveBuf, PARSE_TAIL(pParse), PARSE_TAIL_SZ); + memset(PARSE_TAIL(pParse), 0, PARSE_TAIL_SZ); sqlite3RunParser(pParse, zSql, &zErrMsg); sqlite3DbFree(db, zErrMsg); sqlite3DbFree(db, zSql); - memcpy(&pParse->nVar, saveBuf, SAVE_SZ); + memcpy(PARSE_TAIL(pParse), saveBuf, PARSE_TAIL_SZ); pParse->nested--; } diff --git a/src/prepare.c b/src/prepare.c index 1f7f84a020..3be1c9b901 100644 --- a/src/prepare.c +++ b/src/prepare.c @@ -524,11 +524,13 @@ static int sqlite3Prepare( int i; /* Loop counter */ /* Allocate the parsing context */ - pParse = sqlite3StackAllocZero(db, sizeof(*pParse)); + pParse = sqlite3StackAllocRaw(db, sizeof(*pParse)); if( pParse==0 ){ rc = SQLITE_NOMEM_BKPT; goto end_prepare; } + memset(pParse, 0, PARSE_HDR_SZ); + memset(PARSE_TAIL(pParse), 0, PARSE_TAIL_SZ); pParse->pReprepare = pReprepare; assert( ppStmt && *ppStmt==0 ); /* assert( !db->mallocFailed ); // not true with SQLITE_USE_ALLOCA */ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 7e8ee31ea7..61a705827e 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2904,14 +2904,6 @@ struct Parse { int iCacheCnt; /* Counter used to generate aColCache[].lru values */ int nLabel; /* Number of labels used */ int *aLabel; /* Space to hold the labels */ - struct yColCache { - int iTable; /* Table cursor number */ - i16 iColumn; /* Table column number */ - u8 tempReg; /* iReg is a temp register that needs to be freed */ - int iLevel; /* Nesting level */ - int iReg; /* Reg with value of this column. 0 means none. */ - int lru; /* Least recently used entry has the smallest value */ - } aColCache[SQLITE_N_COLCACHE]; /* One for each column cache entry */ ExprList *pConstExpr;/* Constant expressions */ Token constraintName;/* Name of the constraint currently being parsed */ yDbMask writeMask; /* Start a write transaction on these databases */ @@ -2940,6 +2932,20 @@ struct Parse { u8 eOrconf; /* Default ON CONFLICT policy for trigger steps */ u8 disableTriggers; /* True to disable triggers */ + /* The column cache comes at the end of the recursive section + ** When initializing a new Parse object, the header above, and + ** the non-recursive part that follows the column cache both need + ** to be zeroed. But the column cache itself does not need zeroing + */ + struct yColCache { + int iTable; /* Table cursor number */ + i16 iColumn; /* Table column number */ + u8 tempReg; /* iReg is a temp register that needs to be freed */ + int iLevel; /* Nesting level */ + int iReg; /* Reg with value of this column. 0 means none. */ + int lru; /* Least recently used entry has the smallest value */ + } aColCache[SQLITE_N_COLCACHE]; /* One for each column cache entry */ + /************************************************************************ ** Above is constant between recursions. Below is reset before and after ** each recursion. The boundary between these two regions is determined @@ -2978,6 +2984,14 @@ struct Parse { With *pWithToFree; /* Free this WITH object at the end of the parse */ }; +/* +** Sizes and pointers of various parts of the Parse object. +*/ +#define PARSE_HDR_SZ offsetof(Parse,aColCache) /* Recursive part w/o aColCache*/ +#define PARSE_RECURSE_SZ offsetof(Parse,nVar) /* Recursive part */ +#define PARSE_TAIL_SZ (sizeof(Parse)-PARSE_RECURSE_SZ) /* Non-recursive part */ +#define PARSE_TAIL(X) (((char*)(X))+PARSE_RECURSE_SZ) /* Pointer to tail */ + /* ** Return true if currently inside an sqlite3_declare_vtab() call. */ From ab3182f7c4ed7b6f8f7cc7394db24d73293ebab5 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 1 Oct 2016 00:37:50 +0000 Subject: [PATCH 0884/1484] Avoid unnecessary zeroing of fields in the Vdbe object when it is allocated. FossilOrigin-Name: 1e21bbe836539e64d24857f4faa3d12cd607dc7e --- manifest | 14 ++++++------- manifest.uuid | 2 +- src/vdbeInt.h | 55 ++++++++++++++++++++++++++++----------------------- src/vdbeaux.c | 17 +++++++++++----- 4 files changed, 50 insertions(+), 38 deletions(-) diff --git a/manifest b/manifest index 4d02da0553..7526f661e6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sinitializing\sthe\scolumn-cache\ssection\sof\sthe\sParse\sobject,\ssince\sentries\nin\sthe\scache\swill\sbe\sinitialized\sas\sthey\sare\sused,\sand\savoiding\sthe\sinitial\nmemset()\ssaves\smany\sCPU\scycles. -D 2016-09-30T22:24:29.959 +C Avoid\sunnecessary\szeroing\sof\sfields\sin\sthe\sVdbe\sobject\swhen\sit\sis\sallocated. +D 2016-10-01T00:37:50.922 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -455,9 +455,9 @@ F src/util.c 3e2da6101888d073e79ecc6af5e0a2f70fa1e498 F src/vacuum.c 913970b9d86dd6c2b8063ef1af421880f1464ec3 F src/vdbe.c 51e754eec26d892abc6279f5e949545af68ec1b3 F src/vdbe.h c044be7050ac6bf596eecc6ab159f5dbc020a3b7 -F src/vdbeInt.h 581b737c2f6e413c555469480efe31796a71bcad +F src/vdbeInt.h 0a18713d0a2fec6807d076bd333d9bf3e57530cd F src/vdbeapi.c 794f80669e9e3b9b3edc78d80c15968985c7bf21 -F src/vdbeaux.c 5f97a1aed18b5b064407652654f73f3cd4836a87 +F src/vdbeaux.c 4c0678a2a2c315534a2609de515d04cccf3990fb F src/vdbeblob.c 3e82a797b60c3b9fed7b8de8c539ca7607874937 F src/vdbemem.c 1c330522e6b6e4ddd2ff63c4c0dfafa20c3965a7 F src/vdbesort.c 91fda3909326860382b0ca8aa251e609c6a9d62c @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ab12fce3318db447995e1465f34a1e43cd623d6a -R 0a3a2f22297400a0c501bf7a0c2b0caa +P 63cf7eafae5c3c1379edf416c5157010c7c120b5 +R 85f9a9479e2ad57a2952b90cd8e20395 U drh -Z fb861c120dabfe63359c1b99efc6b84b +Z e3416eaec67cf3f8ba5f96a2088d495d diff --git a/manifest.uuid b/manifest.uuid index e3eee84b50..2c3cf85d9a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -63cf7eafae5c3c1379edf416c5157010c7c120b5 \ No newline at end of file +1e21bbe836539e64d24857f4faa3d12cd607dc7e \ No newline at end of file diff --git a/src/vdbeInt.h b/src/vdbeInt.h index 353abc6877..1c6ee3f63b 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -340,34 +340,47 @@ struct ScanStatus { */ struct Vdbe { sqlite3 *db; /* The database connection that owns this statement */ + Vdbe *pPrev,*pNext; /* Linked list of VDBEs with the same Vdbe.db */ + Parse *pParse; /* Parsing context used to create this Vdbe */ + ynVar nVar; /* Number of entries in aVar[] */ + ynVar nzVar; /* Number of entries in azVar[] */ + u32 magic; /* Magic number for sanity checking */ + int nMem; /* Number of memory locations currently allocated */ + int nCursor; /* Number of slots in apCsr[] */ + u32 cacheCtr; /* VdbeCursor row cache generation counter */ + int pc; /* The program counter */ + int rc; /* Value to return */ + int nChange; /* Number of db changes made since last reset */ + int iStatement; /* Statement number (or 0 if has not opened stmt) */ + i64 iCurrentTime; /* Value of julianday('now') for this statement */ + i64 nFkConstraint; /* Number of imm. FK constraints this VM */ + i64 nStmtDefCons; /* Number of def. constraints when stmt started */ + i64 nStmtDefImmCons; /* Number of def. imm constraints when stmt started */ + + /* When allocating a new Vdbe object, all of the fields below should be + ** initialized to zero or NULL */ + Op *aOp; /* Space to hold the virtual machine's program */ Mem *aMem; /* The memory locations */ Mem **apArg; /* Arguments to currently executing user function */ Mem *aColName; /* Column names to return */ Mem *pResultSet; /* Pointer to an array of results */ - Parse *pParse; /* Parsing context used to create this Vdbe */ - int nMem; /* Number of memory locations currently allocated */ - int nOp; /* Number of instructions in the program */ - int nCursor; /* Number of slots in apCsr[] */ - u32 magic; /* Magic number for sanity checking */ char *zErrMsg; /* Error message written here */ - Vdbe *pPrev,*pNext; /* Linked list of VDBEs with the same Vdbe.db */ VdbeCursor **apCsr; /* One element of this array for each open cursor */ Mem *aVar; /* Values for the OP_Variable opcode. */ char **azVar; /* Name of variables */ - ynVar nVar; /* Number of entries in aVar[] */ - ynVar nzVar; /* Number of entries in azVar[] */ - u32 cacheCtr; /* VdbeCursor row cache generation counter */ - int pc; /* The program counter */ - int rc; /* Value to return */ +#ifndef SQLITE_OMIT_TRACE + i64 startTime; /* Time when query started - used for profiling */ +#endif + int nOp; /* Number of instructions in the program */ #ifdef SQLITE_DEBUG int rcApp; /* errcode set by sqlite3_result_error_code() */ #endif u16 nResColumn; /* Number of columns in one row of the result set */ u8 errorAction; /* Recovery action to do in case of an error */ + u8 minWriteFileFormat; /* Minimum file format for writable database files */ bft expired:1; /* True if the VM needs to be recompiled */ bft doingRerun:1; /* True if rerunning after an auto-reprepare */ - u8 minWriteFileFormat; /* Minimum file format for writable database files */ bft explain:2; /* True if EXPLAIN present on SQL command */ bft changeCntOn:1; /* True to update the change-counter */ bft runOnlyOnce:1; /* Automatically expire on reset */ @@ -375,18 +388,9 @@ struct Vdbe { bft readOnly:1; /* True for statements that do not write */ bft bIsReader:1; /* True for statements that read */ bft isPrepareV2:1; /* True if prepared with prepare_v2() */ - int nChange; /* Number of db changes made since last reset */ yDbMask btreeMask; /* Bitmask of db->aDb[] entries referenced */ yDbMask lockMask; /* Subset of btreeMask that requires a lock */ - int iStatement; /* Statement number (or 0 if has not opened stmt) */ u32 aCounter[5]; /* Counters used by sqlite3_stmt_status() */ -#ifndef SQLITE_OMIT_TRACE - i64 startTime; /* Time when query started - used for profiling */ -#endif - i64 iCurrentTime; /* Value of julianday('now') for this statement */ - i64 nFkConstraint; /* Number of imm. FK constraints this VM */ - i64 nStmtDefCons; /* Number of def. constraints when stmt started */ - i64 nStmtDefImmCons; /* Number of def. imm constraints when stmt started */ char *zSql; /* Text of the SQL statement that generated this */ void *pFree; /* Free this when deleting the vdbe */ VdbeFrame *pFrame; /* Parent frame */ @@ -405,10 +409,11 @@ struct Vdbe { /* ** The following are allowed values for Vdbe.magic */ -#define VDBE_MAGIC_INIT 0x26bceaa5 /* Building a VDBE program */ -#define VDBE_MAGIC_RUN 0xbdf20da3 /* VDBE is ready to execute */ -#define VDBE_MAGIC_HALT 0x519c2973 /* VDBE has completed execution */ -#define VDBE_MAGIC_DEAD 0xb606c3c8 /* The VDBE has been deallocated */ +#define VDBE_MAGIC_INIT 0x16bceaa5 /* Building a VDBE program */ +#define VDBE_MAGIC_RUN 0x2df20da3 /* VDBE is ready to execute */ +#define VDBE_MAGIC_HALT 0x319c2973 /* VDBE has completed execution */ +#define VDBE_MAGIC_RESET 0x48fa9f76 /* Reset and ready to run again */ +#define VDBE_MAGIC_DEAD 0x5606c3c8 /* The VDBE has been deallocated */ /* ** Structure used to store the context required by the diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 86f5096a8b..26fee27657 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -21,8 +21,9 @@ Vdbe *sqlite3VdbeCreate(Parse *pParse){ sqlite3 *db = pParse->db; Vdbe *p; - p = sqlite3DbMallocZero(db, sizeof(Vdbe) ); + p = sqlite3DbMallocRaw(db, sizeof(Vdbe) ); if( p==0 ) return 0; + memset(&p->aOp, 0, sizeof(Vdbe)-offsetof(Vdbe,aOp)); p->db = db; if( db->pVdbe ){ db->pVdbe->pPrev = p; @@ -1826,7 +1827,7 @@ void sqlite3VdbeRewind(Vdbe *p){ int i; #endif assert( p!=0 ); - assert( p->magic==VDBE_MAGIC_INIT ); + assert( p->magic==VDBE_MAGIC_INIT || p->magic==VDBE_MAGIC_RESET ); /* There should be at least one opcode. */ @@ -1953,7 +1954,11 @@ void sqlite3VdbeMakeReady( pParse->nzVar = 0; pParse->azVar = 0; p->explain = pParse->explain; - if( db->mallocFailed==0 ){ + if( db->mallocFailed ){ + p->nVar = 0; + p->nCursor = 0; + p->nMem = 0; + }else{ p->nCursor = nCursor; p->nVar = (ynVar)nVar; initMemArray(p->aVar, nVar, db, MEM_Null); @@ -2880,7 +2885,7 @@ int sqlite3VdbeReset(Vdbe *p){ } #endif p->iCurrentTime = 0; - p->magic = VDBE_MAGIC_INIT; + p->magic = VDBE_MAGIC_RESET; return p->rc & db->errMask; } @@ -2951,7 +2956,9 @@ void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){ vdbeFreeOpArray(db, pSub->aOp, pSub->nOp); sqlite3DbFree(db, pSub); } - for(i=p->nzVar-1; i>=0; i--) sqlite3DbFree(db, p->azVar[i]); + if( p->magic!=VDBE_MAGIC_INIT ){ + for(i=p->nzVar-1; i>=0; i--) sqlite3DbFree(db, p->azVar[i]); + } sqlite3DbFree(db, p->azVar); vdbeFreeOpArray(db, p->aOp, p->nOp); sqlite3DbFree(db, p->aColName); From 76336d5b9dc8ba68b0f382ee0ecccfa83a550276 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 1 Oct 2016 11:39:53 +0000 Subject: [PATCH 0885/1484] Avoid accessing Vdbe.pc if it is uninitialized. Check Vdbe.magic first. FossilOrigin-Name: 6ac6e4462a08cb2f3d28e4a23218fc1b110a2148 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbeapi.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 7526f661e6..94a65b314b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sunnecessary\szeroing\sof\sfields\sin\sthe\sVdbe\sobject\swhen\sit\sis\sallocated. -D 2016-10-01T00:37:50.922 +C Avoid\saccessing\sVdbe.pc\sif\sit\sis\suninitialized.\s\sCheck\sVdbe.magic\sfirst. +D 2016-10-01T11:39:53.849 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -456,7 +456,7 @@ F src/vacuum.c 913970b9d86dd6c2b8063ef1af421880f1464ec3 F src/vdbe.c 51e754eec26d892abc6279f5e949545af68ec1b3 F src/vdbe.h c044be7050ac6bf596eecc6ab159f5dbc020a3b7 F src/vdbeInt.h 0a18713d0a2fec6807d076bd333d9bf3e57530cd -F src/vdbeapi.c 794f80669e9e3b9b3edc78d80c15968985c7bf21 +F src/vdbeapi.c 8272f9342c39ab8d7eb4b9decc6caa7bc75b7d83 F src/vdbeaux.c 4c0678a2a2c315534a2609de515d04cccf3990fb F src/vdbeblob.c 3e82a797b60c3b9fed7b8de8c539ca7607874937 F src/vdbemem.c 1c330522e6b6e4ddd2ff63c4c0dfafa20c3965a7 @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 63cf7eafae5c3c1379edf416c5157010c7c120b5 -R 85f9a9479e2ad57a2952b90cd8e20395 +P 1e21bbe836539e64d24857f4faa3d12cd607dc7e +R 0e838f96f4e792052b29d3f66ffac855 U drh -Z e3416eaec67cf3f8ba5f96a2088d495d +Z 89ce8b8482fb3b1340ca860c8bea3989 diff --git a/manifest.uuid b/manifest.uuid index 2c3cf85d9a..e25e15e20e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1e21bbe836539e64d24857f4faa3d12cd607dc7e \ No newline at end of file +6ac6e4462a08cb2f3d28e4a23218fc1b110a2148 \ No newline at end of file diff --git a/src/vdbeapi.c b/src/vdbeapi.c index e37eeef2af..5956943af0 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -1569,7 +1569,7 @@ int sqlite3_stmt_readonly(sqlite3_stmt *pStmt){ */ int sqlite3_stmt_busy(sqlite3_stmt *pStmt){ Vdbe *v = (Vdbe*)pStmt; - return v!=0 && v->pc>=0 && v->magic==VDBE_MAGIC_RUN; + return v!=0 && v->magic==VDBE_MAGIC_RUN && v->pc>=0; } /* From 8dfef1175e19aebf05567cb47a86438ffa963886 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 1 Oct 2016 16:53:45 +0000 Subject: [PATCH 0886/1484] Make sure deleting an unused prepared statement does not reference uninitialized fields in the structure. FossilOrigin-Name: 7983eef0422439bfc85950554b000d46a9767ee3 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbeaux.c | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 94a65b314b..5ed9e62719 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\saccessing\sVdbe.pc\sif\sit\sis\suninitialized.\s\sCheck\sVdbe.magic\sfirst. -D 2016-10-01T11:39:53.849 +C Make\ssure\sdeleting\san\sunused\sprepared\sstatement\sdoes\snot\sreference\nuninitialized\sfields\sin\sthe\sstructure. +D 2016-10-01T16:53:45.240 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -457,7 +457,7 @@ F src/vdbe.c 51e754eec26d892abc6279f5e949545af68ec1b3 F src/vdbe.h c044be7050ac6bf596eecc6ab159f5dbc020a3b7 F src/vdbeInt.h 0a18713d0a2fec6807d076bd333d9bf3e57530cd F src/vdbeapi.c 8272f9342c39ab8d7eb4b9decc6caa7bc75b7d83 -F src/vdbeaux.c 4c0678a2a2c315534a2609de515d04cccf3990fb +F src/vdbeaux.c 5da1f049feb4d301c7062d4359dd527b248b2e81 F src/vdbeblob.c 3e82a797b60c3b9fed7b8de8c539ca7607874937 F src/vdbemem.c 1c330522e6b6e4ddd2ff63c4c0dfafa20c3965a7 F src/vdbesort.c 91fda3909326860382b0ca8aa251e609c6a9d62c @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 1e21bbe836539e64d24857f4faa3d12cd607dc7e -R 0e838f96f4e792052b29d3f66ffac855 +P 6ac6e4462a08cb2f3d28e4a23218fc1b110a2148 +R 5b70bdd1179fbf3ea6befa79ac9a9864 U drh -Z 89ce8b8482fb3b1340ca860c8bea3989 +Z b7e8c3f1e612d35f7e8186a20da76741 diff --git a/manifest.uuid b/manifest.uuid index e25e15e20e..ebef99bc78 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6ac6e4462a08cb2f3d28e4a23218fc1b110a2148 \ No newline at end of file +7983eef0422439bfc85950554b000d46a9767ee3 \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 26fee27657..6d1004b389 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -2949,7 +2949,6 @@ void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){ SubProgram *pSub, *pNext; int i; assert( p->db==0 || p->db==db ); - releaseMemArray(p->aVar, p->nVar); releaseMemArray(p->aColName, p->nResColumn*COLNAME_N); for(pSub=p->pProgram; pSub; pSub=pNext){ pNext = pSub->pNext; @@ -2957,13 +2956,14 @@ void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){ sqlite3DbFree(db, pSub); } if( p->magic!=VDBE_MAGIC_INIT ){ + releaseMemArray(p->aVar, p->nVar); for(i=p->nzVar-1; i>=0; i--) sqlite3DbFree(db, p->azVar[i]); + sqlite3DbFree(db, p->azVar); + sqlite3DbFree(db, p->pFree); } - sqlite3DbFree(db, p->azVar); vdbeFreeOpArray(db, p->aOp, p->nOp); sqlite3DbFree(db, p->aColName); sqlite3DbFree(db, p->zSql); - sqlite3DbFree(db, p->pFree); #ifdef SQLITE_ENABLE_STMT_SCANSTATUS for(i=0; inScan; i++){ sqlite3DbFree(db, p->aScan[i].zName); From d8e4b13256187b4c1dfacbd03f324b7b3d159030 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 1 Oct 2016 19:21:56 +0000 Subject: [PATCH 0887/1484] Use sqlite3DbMallocRawNN() where appropriate, instead of sqlite3DbMallocRaw(). FossilOrigin-Name: 54a449a41d8d32da2f8b73689227ced866974a18 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/select.c | 2 +- src/vdbeaux.c | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 5ed9e62719..d8af61daec 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\ssure\sdeleting\san\sunused\sprepared\sstatement\sdoes\snot\sreference\nuninitialized\sfields\sin\sthe\sstructure. -D 2016-10-01T16:53:45.240 +C Use\ssqlite3DbMallocRawNN()\swhere\sappropriate,\sinstead\sof\nsqlite3DbMallocRaw(). +D 2016-10-01T19:21:56.256 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -386,7 +386,7 @@ F src/printf.c a5f0ca08ddede803c241266abb46356ec748ded1 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c 3c3cf0dc719cd2a32ab5c1e10c26481dd565492e F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac -F src/select.c 6dede310d202f7a0da7f4ac1921f153707fa3d4f +F src/select.c ea3af83e2d0f245fef81ea4cf04cb730ce67f722 F src/shell.c b80396d2fadce4681397707e30078bf416e1dec2 F src/sqlite.h.in 2683a291ed8db5228024267be6421f0de507b80e F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -457,7 +457,7 @@ F src/vdbe.c 51e754eec26d892abc6279f5e949545af68ec1b3 F src/vdbe.h c044be7050ac6bf596eecc6ab159f5dbc020a3b7 F src/vdbeInt.h 0a18713d0a2fec6807d076bd333d9bf3e57530cd F src/vdbeapi.c 8272f9342c39ab8d7eb4b9decc6caa7bc75b7d83 -F src/vdbeaux.c 5da1f049feb4d301c7062d4359dd527b248b2e81 +F src/vdbeaux.c a771f17c069b7fa98ea4c7f80414784d0fdc31c8 F src/vdbeblob.c 3e82a797b60c3b9fed7b8de8c539ca7607874937 F src/vdbemem.c 1c330522e6b6e4ddd2ff63c4c0dfafa20c3965a7 F src/vdbesort.c 91fda3909326860382b0ca8aa251e609c6a9d62c @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 6ac6e4462a08cb2f3d28e4a23218fc1b110a2148 -R 5b70bdd1179fbf3ea6befa79ac9a9864 +P 7983eef0422439bfc85950554b000d46a9767ee3 +R 23955f59b163a11f39ff812dd1896e90 U drh -Z b7e8c3f1e612d35f7e8186a20da76741 +Z f211d43218fc47d8bea747f857323931 diff --git a/manifest.uuid b/manifest.uuid index ebef99bc78..116f3c0df8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7983eef0422439bfc85950554b000d46a9767ee3 \ No newline at end of file +54a449a41d8d32da2f8b73689227ced866974a18 \ No newline at end of file diff --git a/src/select.c b/src/select.c index a3badd12b5..199e13f113 100644 --- a/src/select.c +++ b/src/select.c @@ -1005,7 +1005,7 @@ static void selectInnerLoop( */ KeyInfo *sqlite3KeyInfoAlloc(sqlite3 *db, int N, int X){ int nExtra = (N+X)*(sizeof(CollSeq*)+1); - KeyInfo *p = sqlite3DbMallocRaw(db, sizeof(KeyInfo) + nExtra); + KeyInfo *p = sqlite3DbMallocRawNN(db, sizeof(KeyInfo) + nExtra); if( p ){ p->aSortOrder = (u8*)&p->aColl[N+X]; p->nField = (u16)N; diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 6d1004b389..e5bae1afd7 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -21,7 +21,7 @@ Vdbe *sqlite3VdbeCreate(Parse *pParse){ sqlite3 *db = pParse->db; Vdbe *p; - p = sqlite3DbMallocRaw(db, sizeof(Vdbe) ); + p = sqlite3DbMallocRawNN(db, sizeof(Vdbe) ); if( p==0 ) return 0; memset(&p->aOp, 0, sizeof(Vdbe)-offsetof(Vdbe,aOp)); p->db = db; From 230368c30d4f963915a6c86c19ce8a8686306c96 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 1 Oct 2016 19:32:54 +0000 Subject: [PATCH 0888/1484] Remove an unnecessary memset() call. FossilOrigin-Name: a76bff74ce47c9c98106566bde5d781992657e22 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbeaux.c | 1 - 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index d8af61daec..239945775f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Use\ssqlite3DbMallocRawNN()\swhere\sappropriate,\sinstead\sof\nsqlite3DbMallocRaw(). -D 2016-10-01T19:21:56.256 +C Remove\san\sunnecessary\smemset()\scall. +D 2016-10-01T19:32:54.320 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -457,7 +457,7 @@ F src/vdbe.c 51e754eec26d892abc6279f5e949545af68ec1b3 F src/vdbe.h c044be7050ac6bf596eecc6ab159f5dbc020a3b7 F src/vdbeInt.h 0a18713d0a2fec6807d076bd333d9bf3e57530cd F src/vdbeapi.c 8272f9342c39ab8d7eb4b9decc6caa7bc75b7d83 -F src/vdbeaux.c a771f17c069b7fa98ea4c7f80414784d0fdc31c8 +F src/vdbeaux.c 7229203e4e4a3b6eaeeddc807c2287d912c0da74 F src/vdbeblob.c 3e82a797b60c3b9fed7b8de8c539ca7607874937 F src/vdbemem.c 1c330522e6b6e4ddd2ff63c4c0dfafa20c3965a7 F src/vdbesort.c 91fda3909326860382b0ca8aa251e609c6a9d62c @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 7983eef0422439bfc85950554b000d46a9767ee3 -R 23955f59b163a11f39ff812dd1896e90 +P 54a449a41d8d32da2f8b73689227ced866974a18 +R 6fccc2bbb97105584088eb1a80b3a030 U drh -Z f211d43218fc47d8bea747f857323931 +Z 51e223b0b10be817e5db370c9670ed7a diff --git a/manifest.uuid b/manifest.uuid index 116f3c0df8..6dbb71b0ee 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -54a449a41d8d32da2f8b73689227ced866974a18 \ No newline at end of file +a76bff74ce47c9c98106566bde5d781992657e22 \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index e5bae1afd7..df4fb2cdd0 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -1964,7 +1964,6 @@ void sqlite3VdbeMakeReady( initMemArray(p->aVar, nVar, db, MEM_Null); p->nMem = nMem; initMemArray(p->aMem, nMem, db, MEM_Undefined); - memset(p->apArg, 0, nArg*sizeof(Mem*)); memset(p->apCsr, 0, nCursor*sizeof(VdbeCursor*)); #ifdef SQLITE_ENABLE_STMT_SCANSTATUS memset(p->anExec, 0, p->nOp*sizeof(i64)); From 216b70ff82de0d686c01f7ea424386d402e1855f Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 1 Oct 2016 20:43:41 +0000 Subject: [PATCH 0889/1484] Reduce the width of a memset() to avoid double-initializing some variables. FossilOrigin-Name: 34edbfd12d6cfa6bbfa30eef9276a4865eadc869 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/pcache.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 239945775f..ca02dd450c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\san\sunnecessary\smemset()\scall. -D 2016-10-01T19:32:54.320 +C Reduce\sthe\swidth\sof\sa\smemset()\sto\savoid\sdouble-initializing\ssome\svariables. +D 2016-10-01T20:43:41.486 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -376,7 +376,7 @@ F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c bf5b71bde3e9b6110e7d6990607db881f6a471a2 F src/pager.h 966d2769e76ae347c8a32c4165faf6e6cb64546d F src/parse.y 6ad22b8f4a673de775d68c5c306dddd15839c45f -F src/pcache.c 5583c8ade4b05075a60ba953ef471d1c1a9c05df +F src/pcache.c 5ff2a08f76a9c1b22f43eb063b7068fb085465ac F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 F src/pcache1.c 4bb7a6a5300c67d0b033d25adb509c120c03e812 F src/pragma.c d932ba278654617cdd281f88a790a3185fca7c44 @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 54a449a41d8d32da2f8b73689227ced866974a18 -R 6fccc2bbb97105584088eb1a80b3a030 +P a76bff74ce47c9c98106566bde5d781992657e22 +R 9894c16f602bc73182e0b90dfc6c19cc U drh -Z 51e223b0b10be817e5db370c9670ed7a +Z 74b7a0dbeb8f3fe501e0e4424068d2fe diff --git a/manifest.uuid b/manifest.uuid index 6dbb71b0ee..7e97ce5af9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a76bff74ce47c9c98106566bde5d781992657e22 \ No newline at end of file +34edbfd12d6cfa6bbfa30eef9276a4865eadc869 \ No newline at end of file diff --git a/src/pcache.c b/src/pcache.c index ccbcc96cd0..68f4b51dc8 100644 --- a/src/pcache.c +++ b/src/pcache.c @@ -461,7 +461,7 @@ static SQLITE_NOINLINE PgHdr *pcacheFetchFinishWithInit( assert( pPage!=0 ); pPgHdr = (PgHdr*)pPage->pExtra; assert( pPgHdr->pPage==0 ); - memset(pPgHdr, 0, sizeof(PgHdr)); + memset(&pPgHdr->pDirty, 0, sizeof(PgHdr) - offsetof(PgHdr,pDirty)); pPgHdr->pPage = pPage; pPgHdr->pData = pPage->pBuf; pPgHdr->pExtra = (void *)&pPgHdr[1]; From 445f3d564c3f225be477b47cd1c332614113cca7 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 1 Oct 2016 21:43:37 +0000 Subject: [PATCH 0890/1484] Rearrange fields in the Parse object to reduce the amount of initialization required. FossilOrigin-Name: 361940b44dd17bf2b39fc0e0716c0de6b2b7f4f7 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/sqliteInt.h | 20 ++++++++++---------- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/manifest b/manifest index ca02dd450c..21ffdd5597 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Reduce\sthe\swidth\sof\sa\smemset()\sto\savoid\sdouble-initializing\ssome\svariables. -D 2016-10-01T20:43:41.486 +C Rearrange\sfields\sin\sthe\sParse\sobject\sto\sreduce\sthe\samount\sof\sinitialization\nrequired. +D 2016-10-01T21:43:37.888 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -391,7 +391,7 @@ F src/shell.c b80396d2fadce4681397707e30078bf416e1dec2 F src/sqlite.h.in 2683a291ed8db5228024267be6421f0de507b80e F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae -F src/sqliteInt.h 16f22a872a901d4a455a4a65bbbc1658cc2159f4 +F src/sqliteInt.h 5748a35f10c0a03dc546caf8508f41ae3895ee8b F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a76bff74ce47c9c98106566bde5d781992657e22 -R 9894c16f602bc73182e0b90dfc6c19cc +P 34edbfd12d6cfa6bbfa30eef9276a4865eadc869 +R de5ca274755abcf0d716abfc4e191e0a U drh -Z 74b7a0dbeb8f3fe501e0e4424068d2fe +Z f893e5ce9e69907538e2c5169945e4a7 diff --git a/manifest.uuid b/manifest.uuid index 7e97ce5af9..d72e56d3cc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -34edbfd12d6cfa6bbfa30eef9276a4865eadc869 \ No newline at end of file +361940b44dd17bf2b39fc0e0716c0de6b2b7f4f7 \ No newline at end of file diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 61a705827e..fade8a34d0 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2890,7 +2890,6 @@ struct Parse { u8 okConstFactor; /* OK to factor out constants */ u8 disableLookaside; /* Number of times lookaside has been disabled */ u8 nColCache; /* Number of entries in aColCache[] */ - int aTempReg[8]; /* Holding area for temporary registers */ int nRangeReg; /* Size of the temporary register block */ int iRangeReg; /* First register in temporary register block */ int nErr; /* Number of errors seen */ @@ -2920,8 +2919,6 @@ struct Parse { TableLock *aTableLock; /* Required table locks for shared-cache mode */ #endif AutoincInfo *pAinc; /* Information about AUTOINCREMENT counters */ - - /* Information used while coding trigger programs. */ Parse *pToplevel; /* Parse structure for main program (or NULL) */ Table *pTriggerTab; /* Table triggers are being coded for */ int addrCrTab; /* Address of OP_CreateTable opcode on CREATE TABLE */ @@ -2932,11 +2929,13 @@ struct Parse { u8 eOrconf; /* Default ON CONFLICT policy for trigger steps */ u8 disableTriggers; /* True to disable triggers */ - /* The column cache comes at the end of the recursive section - ** When initializing a new Parse object, the header above, and - ** the non-recursive part that follows the column cache both need - ** to be zeroed. But the column cache itself does not need zeroing - */ + /************************************************************************** + ** Fields above must be initialized to zero. The fields that follow, + ** down to the beginning of the recursive section, do not need to be + ** initialized as they will be set before being used. The boundary is + ** determined by offsetof(Parse,aColCache). + **************************************************************************/ + struct yColCache { int iTable; /* Table cursor number */ i16 iColumn; /* Table column number */ @@ -2945,6 +2944,9 @@ struct Parse { int iReg; /* Reg with value of this column. 0 means none. */ int lru; /* Least recently used entry has the smallest value */ } aColCache[SQLITE_N_COLCACHE]; /* One for each column cache entry */ + int aTempReg[8]; /* Holding area for temporary registers */ + Token sNameToken; /* Token with unqualified schema object name */ + Token sLastToken; /* The last token parsed */ /************************************************************************ ** Above is constant between recursions. Below is reset before and after @@ -2972,8 +2974,6 @@ struct Parse { Table *pNewTable; /* A table being constructed by CREATE TABLE */ Trigger *pNewTrigger; /* Trigger under construct by a CREATE TRIGGER */ const char *zAuthContext; /* The 6th parameter to db->xAuth callbacks */ - Token sNameToken; /* Token with unqualified schema object name */ - Token sLastToken; /* The last token parsed */ #ifndef SQLITE_OMIT_VIRTUALTABLE Token sArg; /* Complete text of a module argument */ Table **apVtabLock; /* Pointer to virtual tables needing locking */ From 1a7df58c1aae72f73c183ec7a48a19d773177ccb Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 1 Oct 2016 23:55:23 +0000 Subject: [PATCH 0891/1484] Add SQLITE_USE_ALLOCA to the --lean configuration in speed-check.sh. FossilOrigin-Name: fe07609efc31c4639c40fbda501c55f443756ad2 --- manifest | 12 ++++++------ manifest.uuid | 2 +- tool/speed-check.sh | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 21ffdd5597..a5e8cc9a19 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Rearrange\sfields\sin\sthe\sParse\sobject\sto\sreduce\sthe\samount\sof\sinitialization\nrequired. -D 2016-10-01T21:43:37.888 +C Add\sSQLITE_USE_ALLOCA\sto\sthe\s--lean\sconfiguration\sin\sspeed-check.sh. +D 2016-10-01T23:55:23.573 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -1485,7 +1485,7 @@ F tool/showstat4.c bda40d6e395df7edb6e9ea630784d3d762c35b4b F tool/showwal.c ec79959834f7b21f1e0a2aa52bb7c056d2203977 F tool/soak1.tcl 8d407956e1a45b485a8e072470a3e629a27037fe F tool/spaceanal.tcl 85d90e6674d8298e3eaf82dbcef3abc2d5317f3e -F tool/speed-check.sh a57ee04157ad548a5059c642e251a841af04b1d7 +F tool/speed-check.sh da6ce45957c509ba6343fe3fef167e7e2b306262 F tool/speedtest.tcl 06c76698485ccf597b9e7dbb1ac70706eb873355 F tool/speedtest16.c ecb6542862151c3e6509bbc00509b234562ae81e F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 34edbfd12d6cfa6bbfa30eef9276a4865eadc869 -R de5ca274755abcf0d716abfc4e191e0a +P 361940b44dd17bf2b39fc0e0716c0de6b2b7f4f7 +R 4f860bb3856935aeca97748386fce380 U drh -Z f893e5ce9e69907538e2c5169945e4a7 +Z ab4e3dcba96bb867e3f78f3c2db73961 diff --git a/manifest.uuid b/manifest.uuid index d72e56d3cc..5936785287 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -361940b44dd17bf2b39fc0e0716c0de6b2b7f4f7 \ No newline at end of file +fe07609efc31c4639c40fbda501c55f443756ad2 \ No newline at end of file diff --git a/tool/speed-check.sh b/tool/speed-check.sh index ffb067d246..57f2ca0703 100644 --- a/tool/speed-check.sh +++ b/tool/speed-check.sh @@ -34,6 +34,7 @@ LEAN_OPTS="$LEAN_OPTS -DSQLITE_OMIT_DECLTYPE" LEAN_OPTS="$LEAN_OPTS -DSQLITE_OMIT_DEPRECATED" LEAN_OPTS="$LEAN_OPTS -DSQLITE_OMIT_PROGRESS_CALLBACK" LEAN_OPTS="$LEAN_OPTS -DSQLITE_OMIT_SHARED_CACHE" +LEAN_OPTS="$LEAN_OPTS -DSQLITE_USE_ALLOCA" doExplain=0 doCachegrind=1 while test "$1" != ""; do From cb43a937e57113a21ee0b2ef52a532073c8d3a2d Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 3 Oct 2016 01:21:51 +0000 Subject: [PATCH 0892/1484] Allocate Parse objects off of the stack where appropriate for a substantial performance increase and a size reduction. FossilOrigin-Name: ea8affa9e453b201b479162f621b591e7a65a489 --- manifest | 18 ++++++------- manifest.uuid | 2 +- src/backup.c | 22 ++++++---------- src/btree.c | 2 +- src/prepare.c | 68 ++++++++++++++++++++++--------------------------- src/wherecode.c | 12 +++------ 6 files changed, 53 insertions(+), 71 deletions(-) diff --git a/manifest b/manifest index a5e8cc9a19..0e02fb4af8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sSQLITE_USE_ALLOCA\sto\sthe\s--lean\sconfiguration\sin\sspeed-check.sh. -D 2016-10-01T23:55:23.573 +C Allocate\sParse\sobjects\soff\sof\sthe\sstack\swhere\sappropriate\sfor\sa\ssubstantial\nperformance\sincrease\sand\sa\ssize\sreduction. +D 2016-10-03T01:21:51.273 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -326,10 +326,10 @@ F src/alter.c 299117695b1f21ac62dfc5b608588810ba22ed0d F src/analyze.c 8b62b2cf4da85451534ac0af82cafc418d837f68 F src/attach.c 8c19066b4b5357b5d66154e856c61df01e71203a F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792 -F src/backup.c 92c2e3b5fcb47626413717138617f4d32f08aea4 +F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b F src/bitvec.c 3ee4c8b2c94ed3a7377256e18199e6ff5cf33f63 F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 -F src/btree.c 56e1732ecfb3731efcb216266ec26b1b96e5e8c9 +F src/btree.c a0a80fbbb34a35ca02cd829bad693b7854bee313 F src/btree.h d05b2fcc290991a8a3d9ea1816ddd55a4359dcde F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 F src/build.c 59dcfdc1ee55439d069af301ef7f2e84421b5102 @@ -381,7 +381,7 @@ F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 F src/pcache1.c 4bb7a6a5300c67d0b033d25adb509c120c03e812 F src/pragma.c d932ba278654617cdd281f88a790a3185fca7c44 F src/pragma.h 64c78a648751b9f4f297276c4eb7507b14b4628c -F src/prepare.c 3c8b1bc8799a794aa2e825db1a977e93487b01d4 +F src/prepare.c b1140c3d0cf59bc85ace00ce363153041b424b7a F src/printf.c a5f0ca08ddede803c241266abb46356ec748ded1 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c 3c3cf0dc719cd2a32ab5c1e10c26481dd565492e @@ -469,7 +469,7 @@ F src/wal.h 6dd221ed384afdc204bc61e25c23ef7fd5a511f2 F src/walker.c 91a6df7435827e41cff6bb7df50ea00934ee78b0 F src/where.c 5f91be9fe122e847c4e72d54d3989eb32a927981 F src/whereInt.h 14dd243e13b81cbb0a66063d38b70f93a7d6e613 -F src/wherecode.c e412e09abad1eea213d85594cf46db9f877db56d +F src/wherecode.c 81da7e9b1bf1a882f3ee60b96b750322b83f17fd F src/whereexpr.c 3d8813ef320f10bd27e6c0d784abe1669cfb514e F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 361940b44dd17bf2b39fc0e0716c0de6b2b7f4f7 -R 4f860bb3856935aeca97748386fce380 +P fe07609efc31c4639c40fbda501c55f443756ad2 +R 23db76cc6247870f7cdbd64de85d5b65 U drh -Z ab4e3dcba96bb867e3f78f3c2db73961 +Z 76db15deb9298331c9d3d6c6e8ebd767 diff --git a/manifest.uuid b/manifest.uuid index 5936785287..123398d539 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fe07609efc31c4639c40fbda501c55f443756ad2 \ No newline at end of file +ea8affa9e453b201b479162f621b591e7a65a489 \ No newline at end of file diff --git a/src/backup.c b/src/backup.c index eb8f15cc7e..165144d965 100644 --- a/src/backup.c +++ b/src/backup.c @@ -83,22 +83,16 @@ static Btree *findBtree(sqlite3 *pErrorDb, sqlite3 *pDb, const char *zDb){ int i = sqlite3FindDbName(pDb, zDb); if( i==1 ){ - Parse *pParse; + Parse sParse; int rc = 0; - pParse = sqlite3StackAllocZero(pErrorDb, sizeof(*pParse)); - if( pParse==0 ){ - sqlite3ErrorWithMsg(pErrorDb, SQLITE_NOMEM, "out of memory"); - rc = SQLITE_NOMEM_BKPT; - }else{ - pParse->db = pDb; - if( sqlite3OpenTempDatabase(pParse) ){ - sqlite3ErrorWithMsg(pErrorDb, pParse->rc, "%s", pParse->zErrMsg); - rc = SQLITE_ERROR; - } - sqlite3DbFree(pErrorDb, pParse->zErrMsg); - sqlite3ParserReset(pParse); - sqlite3StackFree(pErrorDb, pParse); + memset(&sParse, 0, sizeof(sParse)); + sParse.db = pDb; + if( sqlite3OpenTempDatabase(&sParse) ){ + sqlite3ErrorWithMsg(pErrorDb, sParse.rc, "%s", sParse.zErrMsg); + rc = SQLITE_ERROR; } + sqlite3DbFree(pErrorDb, sParse.zErrMsg); + sqlite3ParserReset(&sParse); if( rc ){ return 0; } diff --git a/src/btree.c b/src/btree.c index 681285ac99..45b4750b7b 100644 --- a/src/btree.c +++ b/src/btree.c @@ -763,7 +763,7 @@ static int btreeMoveto( ){ int rc; /* Status code */ UnpackedRecord *pIdxKey; /* Unpacked index key */ - char aSpace[200]; /* Temp space for pIdxKey - to avoid a malloc */ + char aSpace[384]; /* Temp space for pIdxKey - to avoid a malloc */ char *pFree = 0; if( pKey ){ diff --git a/src/prepare.c b/src/prepare.c index 3be1c9b901..74127bc76b 100644 --- a/src/prepare.c +++ b/src/prepare.c @@ -518,20 +518,14 @@ static int sqlite3Prepare( sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ const char **pzTail /* OUT: End of parsed string */ ){ - Parse *pParse; /* Parsing context */ char *zErrMsg = 0; /* Error message */ int rc = SQLITE_OK; /* Result code */ int i; /* Loop counter */ + Parse sParse; /* Parsing context */ - /* Allocate the parsing context */ - pParse = sqlite3StackAllocRaw(db, sizeof(*pParse)); - if( pParse==0 ){ - rc = SQLITE_NOMEM_BKPT; - goto end_prepare; - } - memset(pParse, 0, PARSE_HDR_SZ); - memset(PARSE_TAIL(pParse), 0, PARSE_TAIL_SZ); - pParse->pReprepare = pReprepare; + memset(&sParse, 0, PARSE_HDR_SZ); + memset(PARSE_TAIL(&sParse), 0, PARSE_TAIL_SZ); + sParse.pReprepare = pReprepare; assert( ppStmt && *ppStmt==0 ); /* assert( !db->mallocFailed ); // not true with SQLITE_USE_ALLOCA */ assert( sqlite3_mutex_held(db->mutex) ); @@ -575,8 +569,7 @@ static int sqlite3Prepare( sqlite3VtabUnlockList(db); - pParse->db = db; - pParse->nQueryLoop = 0; /* Logarithmic, so 0 really means 1 */ + sParse.db = db; if( nBytes>=0 && (nBytes==0 || zSql[nBytes-1]!=0) ){ char *zSqlCopy; int mxLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH]; @@ -589,61 +582,61 @@ static int sqlite3Prepare( } zSqlCopy = sqlite3DbStrNDup(db, zSql, nBytes); if( zSqlCopy ){ - sqlite3RunParser(pParse, zSqlCopy, &zErrMsg); - pParse->zTail = &zSql[pParse->zTail-zSqlCopy]; + sqlite3RunParser(&sParse, zSqlCopy, &zErrMsg); + sParse.zTail = &zSql[sParse.zTail-zSqlCopy]; sqlite3DbFree(db, zSqlCopy); }else{ - pParse->zTail = &zSql[nBytes]; + sParse.zTail = &zSql[nBytes]; } }else{ - sqlite3RunParser(pParse, zSql, &zErrMsg); + sqlite3RunParser(&sParse, zSql, &zErrMsg); } - assert( 0==pParse->nQueryLoop ); + assert( 0==sParse.nQueryLoop ); - if( pParse->rc==SQLITE_DONE ) pParse->rc = SQLITE_OK; - if( pParse->checkSchema ){ - schemaIsValid(pParse); + if( sParse.rc==SQLITE_DONE ) sParse.rc = SQLITE_OK; + if( sParse.checkSchema ){ + schemaIsValid(&sParse); } if( db->mallocFailed ){ - pParse->rc = SQLITE_NOMEM_BKPT; + sParse.rc = SQLITE_NOMEM_BKPT; } if( pzTail ){ - *pzTail = pParse->zTail; + *pzTail = sParse.zTail; } - rc = pParse->rc; + rc = sParse.rc; #ifndef SQLITE_OMIT_EXPLAIN - if( rc==SQLITE_OK && pParse->pVdbe && pParse->explain ){ + if( rc==SQLITE_OK && sParse.pVdbe && sParse.explain ){ static const char * const azColName[] = { "addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment", "selectid", "order", "from", "detail" }; int iFirst, mx; - if( pParse->explain==2 ){ - sqlite3VdbeSetNumCols(pParse->pVdbe, 4); + if( sParse.explain==2 ){ + sqlite3VdbeSetNumCols(sParse.pVdbe, 4); iFirst = 8; mx = 12; }else{ - sqlite3VdbeSetNumCols(pParse->pVdbe, 8); + sqlite3VdbeSetNumCols(sParse.pVdbe, 8); iFirst = 0; mx = 8; } for(i=iFirst; ipVdbe, i-iFirst, COLNAME_NAME, + sqlite3VdbeSetColName(sParse.pVdbe, i-iFirst, COLNAME_NAME, azColName[i], SQLITE_STATIC); } } #endif if( db->init.busy==0 ){ - Vdbe *pVdbe = pParse->pVdbe; - sqlite3VdbeSetSql(pVdbe, zSql, (int)(pParse->zTail-zSql), saveSqlFlag); + Vdbe *pVdbe = sParse.pVdbe; + sqlite3VdbeSetSql(pVdbe, zSql, (int)(sParse.zTail-zSql), saveSqlFlag); } - if( pParse->pVdbe && (rc!=SQLITE_OK || db->mallocFailed) ){ - sqlite3VdbeFinalize(pParse->pVdbe); + if( sParse.pVdbe && (rc!=SQLITE_OK || db->mallocFailed) ){ + sqlite3VdbeFinalize(sParse.pVdbe); assert(!(*ppStmt)); }else{ - *ppStmt = (sqlite3_stmt*)pParse->pVdbe; + *ppStmt = (sqlite3_stmt*)sParse.pVdbe; } if( zErrMsg ){ @@ -654,16 +647,15 @@ static int sqlite3Prepare( } /* Delete any TriggerPrg structures allocated while parsing this statement. */ - while( pParse->pTriggerPrg ){ - TriggerPrg *pT = pParse->pTriggerPrg; - pParse->pTriggerPrg = pT->pNext; + while( sParse.pTriggerPrg ){ + TriggerPrg *pT = sParse.pTriggerPrg; + sParse.pTriggerPrg = pT->pNext; sqlite3DbFree(db, pT); } end_prepare: - sqlite3ParserReset(pParse); - sqlite3StackFree(db, pParse); + sqlite3ParserReset(&sParse); rc = sqlite3ApiExit(db, rc); assert( (rc&db->errMask)==rc ); return rc; diff --git a/src/wherecode.c b/src/wherecode.c index 0948dce4e6..ec21e0bf67 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -1987,7 +1987,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( ** the implied "t1.a=123" constraint. */ for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){ - Expr *pE, *pEAlt; + Expr *pE, sEAlt; WhereTerm *pAlt; if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue; if( (pTerm->eOperator & (WO_EQ|WO_IS))==0 ) continue; @@ -2005,13 +2005,9 @@ Bitmask sqlite3WhereCodeOneLoopStart( testcase( pAlt->eOperator & WO_IS ); testcase( pAlt->eOperator & WO_IN ); VdbeModuleComment((v, "begin transitive constraint")); - pEAlt = sqlite3StackAllocRaw(db, sizeof(*pEAlt)); - if( pEAlt ){ - *pEAlt = *pAlt->pExpr; - pEAlt->pLeft = pE->pLeft; - sqlite3ExprIfFalse(pParse, pEAlt, addrCont, SQLITE_JUMPIFNULL); - sqlite3StackFree(db, pEAlt); - } + sEAlt = *pAlt->pExpr; + sEAlt.pLeft = pE->pLeft; + sqlite3ExprIfFalse(pParse, &sEAlt, addrCont, SQLITE_JUMPIFNULL); } /* For a LEFT OUTER JOIN, generate code that will record the fact that From 1dd518cfcd832a8468caca7d0be27bd1fc053028 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 3 Oct 2016 02:59:33 +0000 Subject: [PATCH 0893/1484] Make sure the sqlite_sequence table is updated when an optional xfer optimization is used. Fix for ticket [7b3328086a5c1]. FossilOrigin-Name: 81e4d4f897553f6fee540a38c3e83ceac5ba9b78 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/insert.c | 1 + test/autoinc.test | 12 ++++++++++++ 4 files changed, 21 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 0e02fb4af8..4af614a4b0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Allocate\sParse\sobjects\soff\sof\sthe\sstack\swhere\sappropriate\sfor\sa\ssubstantial\nperformance\sincrease\sand\sa\ssize\sreduction. -D 2016-10-03T01:21:51.273 +C Make\ssure\sthe\ssqlite_sequence\stable\sis\supdated\swhen\san\soptional\sxfer\noptimization\sis\sused.\s\sFix\sfor\sticket\s[7b3328086a5c1]. +D 2016-10-03T02:59:33.678 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -348,7 +348,7 @@ F src/hash.c 63d0ee752a3b92d4695b2b1f5259c4621b2cfebd F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4 F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 -F src/insert.c 427e96ff168b6b187a52c3d06b9f9e41f6ffb212 +F src/insert.c 2d5e197f2f60351937b201196965fd14cd88489c F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e F src/loadext.c 5d6642d141c07d366e43d359e94ec9de47add41d F src/main.c c9e49e376820bccca55fa9bf2ca321a51725db91 @@ -512,7 +512,7 @@ F test/attachmalloc.test 3a4bfca9545bfe906a8d2e622de10fbac5b711b0 F test/auth.test 872a122b3977c1d1bb9fd637dc20016e5c01880f F test/auth2.test 9eb7fce9f34bf1f50d3f366fb3e606be5a2000a1 F test/auth3.test b810826b193831929951c0d50783a200e5ef6b72 -F test/autoinc.test c58912526998a39e11f66b533e23cfabea7f25b7 +F test/autoinc.test c3a55c3667f429f4f4c7bed05f67b4d93e89e79d F test/autoindex1.test 14b63a9f1e405fe6d5bfc8c8d00249c2ebaf13ea F test/autoindex2.test 12ef578928102baaa0dc23ad397601a2f4ecb0df F test/autoindex3.test a3be0d1a53a7d2edff208a5e442312957047e972 @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P fe07609efc31c4639c40fbda501c55f443756ad2 -R 23db76cc6247870f7cdbd64de85d5b65 +P ea8affa9e453b201b479162f621b591e7a65a489 +R d26ad0c0cb03510ee8e0623be799ba31 U drh -Z 76db15deb9298331c9d3d6c6e8ebd767 +Z 57e862bebfdfe5c6526219d3c30b4bf5 diff --git a/manifest.uuid b/manifest.uuid index 123398d539..d23e1c1877 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ea8affa9e453b201b479162f621b591e7a65a489 \ No newline at end of file +81e4d4f897553f6fee540a38c3e83ceac5ba9b78 \ No newline at end of file diff --git a/src/insert.c b/src/insert.c index 9525d823b0..8167ff78c5 100644 --- a/src/insert.c +++ b/src/insert.c @@ -2177,6 +2177,7 @@ static int xferOptimization( sqlite3ReleaseTempReg(pParse, regRowid); sqlite3ReleaseTempReg(pParse, regData); if( emptyDestTest ){ + sqlite3AutoincrementEnd(pParse); sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_OK, 0); sqlite3VdbeJumpHere(v, emptyDestTest); sqlite3VdbeAddOp2(v, OP_Close, iDest, 0); diff --git a/test/autoinc.test b/test/autoinc.test index 239600616b..4c108eadd4 100644 --- a/test/autoinc.test +++ b/test/autoinc.test @@ -663,6 +663,18 @@ ifcapable trigger { } {1 124 2 10123} } +# 2016-10-03 ticket https://www.sqlite.org/src/tktview/7b3328086a5c1 +# Make sure autoincrement plays nicely with the xfer optimization +# +do_execsql_test autoinc-10.1 { + DELETE FROM sqlite_sequence; + CREATE TABLE t10a(a INTEGER PRIMARY KEY AUTOINCREMENT, b UNIQUE); + INSERT INTO t10a VALUES(888,9999); + CREATE TABLE t10b(x INTEGER PRIMARY KEY AUTOINCREMENT, y UNIQUE); + INSERT INTO t10b SELECT * FROM t10a; + SELECT * FROM sqlite_sequence; +} {t10a 888 t10b 888} + finish_test From cca8a4ad6fd2546c7558658fed8368ca7eaa135e Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 3 Oct 2016 12:56:48 +0000 Subject: [PATCH 0894/1484] Fix an obsolete comment on a variable definition in expr.c. No code changes. FossilOrigin-Name: 012ff6dd306328f7ea71a6600471c871e7ffe37b --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/expr.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 4af614a4b0..f3228e879f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\ssure\sthe\ssqlite_sequence\stable\sis\supdated\swhen\san\soptional\sxfer\noptimization\sis\sused.\s\sFix\sfor\sticket\s[7b3328086a5c1]. -D 2016-10-03T02:59:33.678 +C Fix\san\sobsolete\scomment\son\sa\svariable\sdefinition\sin\sexpr.c.\s\sNo\scode\schanges. +D 2016-10-03T12:56:48.918 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -339,7 +339,7 @@ F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7 F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c cb3f6300df24c26c609778b2731f82644b5532ec -F src/expr.c ebb5174d26a653a7a6f5f300840352c7db932d86 +F src/expr.c 4f75ec38f99cde0b71d8b9da73c83183a732ae99 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c b9ca262f6ad4d030a3cab737ebf9b0b3c8b4ac80 F src/func.c 29cc9acb170ec1387b9f63eb52cd85f8de96c771 @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ea8affa9e453b201b479162f621b591e7a65a489 -R d26ad0c0cb03510ee8e0623be799ba31 +P 81e4d4f897553f6fee540a38c3e83ceac5ba9b78 +R a1685748756dc7f148637043a7b9fa9a U drh -Z 57e862bebfdfe5c6526219d3c30b4bf5 +Z ff1e460c6ae89ed9a6b73957f71ab3a9 diff --git a/manifest.uuid b/manifest.uuid index d23e1c1877..b1643cb183 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -81e4d4f897553f6fee540a38c3e83ceac5ba9b78 \ No newline at end of file +012ff6dd306328f7ea71a6600471c871e7ffe37b \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 31128cc3d4..942b2467ce 100644 --- a/src/expr.c +++ b/src/expr.c @@ -720,7 +720,7 @@ void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p){ ** is allocated to hold the integer text and the dequote flag is ignored. */ Expr *sqlite3ExprAlloc( - sqlite3 *db, /* Handle for sqlite3DbMallocZero() (may be null) */ + sqlite3 *db, /* Handle for sqlite3DbMallocRawNN() */ int op, /* Expression opcode */ const Token *pToken, /* Token argument. Might be NULL */ int dequote /* True to dequote */ From 87c05f0c58b113fbc51b5e3f3a1ca3ce88430a81 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 3 Oct 2016 14:44:47 +0000 Subject: [PATCH 0895/1484] Avoid unnecessary memset() calls in the query optimizer. FossilOrigin-Name: 5bb7cde0731d23411e9df02a957010f94203397b --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/where.c | 9 ++++++--- src/whereInt.h | 30 +++++++++++++++--------------- src/whereexpr.c | 3 ++- 5 files changed, 32 insertions(+), 28 deletions(-) diff --git a/manifest b/manifest index f3228e879f..35962f1ea8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\sobsolete\scomment\son\sa\svariable\sdefinition\sin\sexpr.c.\s\sNo\scode\schanges. -D 2016-10-03T12:56:48.918 +C Avoid\sunnecessary\smemset()\scalls\sin\sthe\squery\soptimizer. +D 2016-10-03T14:44:47.342 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -467,10 +467,10 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 02eeecc265f6ffd0597378f5d8ae9070b62a406a F src/wal.h 6dd221ed384afdc204bc61e25c23ef7fd5a511f2 F src/walker.c 91a6df7435827e41cff6bb7df50ea00934ee78b0 -F src/where.c 5f91be9fe122e847c4e72d54d3989eb32a927981 -F src/whereInt.h 14dd243e13b81cbb0a66063d38b70f93a7d6e613 +F src/where.c c264ec85d94a7292753c03bdf71a015625c01106 +F src/whereInt.h 2bcc3d176e6091cb8f50a30b65c006e88a73614d F src/wherecode.c 81da7e9b1bf1a882f3ee60b96b750322b83f17fd -F src/whereexpr.c 3d8813ef320f10bd27e6c0d784abe1669cfb514e +F src/whereexpr.c 379d0017fb7bc9e5a4d8cd4b056c747de946430e F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 81e4d4f897553f6fee540a38c3e83ceac5ba9b78 -R a1685748756dc7f148637043a7b9fa9a +P 012ff6dd306328f7ea71a6600471c871e7ffe37b +R dd52011ff9f1bb8837d1755ce7de8828 U drh -Z ff1e460c6ae89ed9a6b73957f71ab3a9 +Z 9037cb2feea122245584ce285587b7bb diff --git a/manifest.uuid b/manifest.uuid index b1643cb183..7728cbefd6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -012ff6dd306328f7ea71a6600471c871e7ffe37b \ No newline at end of file +5bb7cde0731d23411e9df02a957010f94203397b \ No newline at end of file diff --git a/src/where.c b/src/where.c index 785c13be78..32ae7323b4 100644 --- a/src/where.c +++ b/src/where.c @@ -4407,22 +4407,25 @@ WhereInfo *sqlite3WhereBegin( ** some architectures. Hence the ROUND8() below. */ nByteWInfo = ROUND8(sizeof(WhereInfo)+(nTabList-1)*sizeof(WhereLevel)); - pWInfo = sqlite3DbMallocZero(db, nByteWInfo + sizeof(WhereLoop)); + pWInfo = sqlite3DbMallocRawNN(db, nByteWInfo + sizeof(WhereLoop)); if( db->mallocFailed ){ sqlite3DbFree(db, pWInfo); pWInfo = 0; goto whereBeginError; } - pWInfo->aiCurOnePass[0] = pWInfo->aiCurOnePass[1] = -1; - pWInfo->nLevel = nTabList; pWInfo->pParse = pParse; pWInfo->pTabList = pTabList; pWInfo->pOrderBy = pOrderBy; pWInfo->pDistinctSet = pDistinctSet; + pWInfo->aiCurOnePass[0] = pWInfo->aiCurOnePass[1] = -1; + pWInfo->nLevel = nTabList; pWInfo->iBreak = pWInfo->iContinue = sqlite3VdbeMakeLabel(v); pWInfo->wctrlFlags = wctrlFlags; pWInfo->iLimit = iAuxArg; pWInfo->savedNQueryLoop = pParse->nQueryLoop; + memset(&pWInfo->nOBSat, 0, + offsetof(WhereInfo,sWC) - offsetof(WhereInfo,nOBSat)); + memset(&pWInfo->a[0], 0, sizeof(WhereLoop)+nTabList*sizeof(WhereLevel)); assert( pWInfo->eOnePass==ONEPASS_OFF ); /* ONEPASS defaults to OFF */ pMaskSet = &pWInfo->sMaskSet; sWLB.pWInfo = pWInfo; diff --git a/src/whereInt.h b/src/whereInt.h index d86373ecd5..fd6ebe77b4 100644 --- a/src/whereInt.h +++ b/src/whereInt.h @@ -246,6 +246,12 @@ struct WherePath { */ struct WhereTerm { Expr *pExpr; /* Pointer to the subexpression that is this term */ + WhereClause *pWC; /* The clause this term is part of */ + LogEst truthProb; /* Probability of truth for this expression */ + u16 wtFlags; /* TERM_xxx bit flags. See below */ + u16 eOperator; /* A WO_xx value describing */ + u8 nChild; /* Number of children that must disable us */ + u8 eMatchOp; /* Op for vtab MATCH/LIKE/GLOB/REGEXP terms */ int iParent; /* Disable pWC->a[iParent] when this term disabled */ int leftCursor; /* Cursor number of X in "X " */ int iField; /* Field in (?,?,?) IN (SELECT...) vector */ @@ -254,12 +260,6 @@ struct WhereTerm { WhereOrInfo *pOrInfo; /* Extra information if (eOperator & WO_OR)!=0 */ WhereAndInfo *pAndInfo; /* Extra information if (eOperator& WO_AND)!=0 */ } u; - LogEst truthProb; /* Probability of truth for this expression */ - u16 eOperator; /* A WO_xx value describing */ - u16 wtFlags; /* TERM_xxx bit flags. See below */ - u8 nChild; /* Number of children that must disable us */ - u8 eMatchOp; /* Op for vtab MATCH/LIKE/GLOB/REGEXP terms */ - WhereClause *pWC; /* The clause this term is part of */ Bitmask prereqRight; /* Bitmask of tables used by pExpr->pRight */ Bitmask prereqAll; /* Bitmask of tables referenced by pExpr */ }; @@ -412,25 +412,25 @@ struct WhereInfo { SrcList *pTabList; /* List of tables in the join */ ExprList *pOrderBy; /* The ORDER BY clause or NULL */ ExprList *pDistinctSet; /* DISTINCT over all these values */ - WhereLoop *pLoops; /* List of all WhereLoop objects */ - Bitmask revMask; /* Mask of ORDER BY terms that need reversing */ - LogEst nRowOut; /* Estimated number of output rows */ LogEst iLimit; /* LIMIT if wctrlFlags has WHERE_USE_LIMIT */ + int aiCurOnePass[2]; /* OP_OpenWrite cursors for the ONEPASS opt */ + int iContinue; /* Jump here to continue with next record */ + int iBreak; /* Jump here to break out of the loop */ + int savedNQueryLoop; /* pParse->nQueryLoop outside the WHERE loop */ u16 wctrlFlags; /* Flags originally passed to sqlite3WhereBegin() */ + u8 nLevel; /* Number of nested loop */ i8 nOBSat; /* Number of ORDER BY terms satisfied by indices */ u8 sorted; /* True if really sorted (not just grouped) */ u8 eOnePass; /* ONEPASS_OFF, or _SINGLE, or _MULTI */ u8 untestedTerms; /* Not all WHERE terms resolved by outer loop */ u8 eDistinct; /* One of the WHERE_DISTINCT_* values */ - u8 nLevel; /* Number of nested loop */ u8 bOrderedInnerLoop; /* True if only the inner-most loop is ordered */ int iTop; /* The very beginning of the WHERE loop */ - int iContinue; /* Jump here to continue with next record */ - int iBreak; /* Jump here to break out of the loop */ - int savedNQueryLoop; /* pParse->nQueryLoop outside the WHERE loop */ - int aiCurOnePass[2]; /* OP_OpenWrite cursors for the ONEPASS opt */ - WhereMaskSet sMaskSet; /* Map cursor numbers to bitmasks */ + WhereLoop *pLoops; /* List of all WhereLoop objects */ + Bitmask revMask; /* Mask of ORDER BY terms that need reversing */ + LogEst nRowOut; /* Estimated number of output rows */ WhereClause sWC; /* Decomposition of the WHERE clause */ + WhereMaskSet sMaskSet; /* Map cursor numbers to bitmasks */ WhereLevel a[1]; /* Information about each nest loop in WHERE */ }; diff --git a/src/whereexpr.c b/src/whereexpr.c index c0c9192af4..7406a3bf9a 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -77,7 +77,6 @@ static int whereClauseInsert(WhereClause *pWC, Expr *p, u16 wtFlags){ sqlite3DbFree(db, pOld); } pWC->nSlot = sqlite3DbMallocSize(db, pWC->a)/sizeof(pWC->a[0]); - memset(&pWC->a[pWC->nTerm], 0, sizeof(pWC->a[0])*(pWC->nSlot-pWC->nTerm)); } pTerm = &pWC->a[idx = pWC->nTerm++]; if( p && ExprHasProperty(p, EP_Unlikely) ){ @@ -89,6 +88,8 @@ static int whereClauseInsert(WhereClause *pWC, Expr *p, u16 wtFlags){ pTerm->wtFlags = wtFlags; pTerm->pWC = pWC; pTerm->iParent = -1; + memset(&pTerm->eOperator, 0, + sizeof(WhereTerm) - offsetof(WhereTerm,eOperator)); return idx; } From de25a88c507fcd9e60defde4974805ae71a74bc6 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 3 Oct 2016 15:28:24 +0000 Subject: [PATCH 0896/1484] Avoid unnecessary strlen() calls in sqlite3ExprAssignVarNumber() by passing in the token length from the parser. FossilOrigin-Name: d15ae2e530cffea60263f203ac5f89b6790f4bd5 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/expr.c | 4 ++-- src/parse.y | 3 ++- src/sqliteInt.h | 2 +- 5 files changed, 14 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 35962f1ea8..7b46688fd3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sunnecessary\smemset()\scalls\sin\sthe\squery\soptimizer. -D 2016-10-03T14:44:47.342 +C Avoid\sunnecessary\sstrlen()\scalls\sin\ssqlite3ExprAssignVarNumber()\sby\spassing\sin\nthe\stoken\slength\sfrom\sthe\sparser. +D 2016-10-03T15:28:24.522 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -339,7 +339,7 @@ F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7 F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c cb3f6300df24c26c609778b2731f82644b5532ec -F src/expr.c 4f75ec38f99cde0b71d8b9da73c83183a732ae99 +F src/expr.c cf99b1a327b4eb0a85d59f1c01d82bc2a318c544 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c b9ca262f6ad4d030a3cab737ebf9b0b3c8b4ac80 F src/func.c 29cc9acb170ec1387b9f63eb52cd85f8de96c771 @@ -375,7 +375,7 @@ F src/os_win.c 520f23475f1de530c435d30b67b7b15fe90874b0 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c bf5b71bde3e9b6110e7d6990607db881f6a471a2 F src/pager.h 966d2769e76ae347c8a32c4165faf6e6cb64546d -F src/parse.y 6ad22b8f4a673de775d68c5c306dddd15839c45f +F src/parse.y 0338f906b61e311c2b7e11a3f89b0092c780b664 F src/pcache.c 5ff2a08f76a9c1b22f43eb063b7068fb085465ac F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 F src/pcache1.c 4bb7a6a5300c67d0b033d25adb509c120c03e812 @@ -391,7 +391,7 @@ F src/shell.c b80396d2fadce4681397707e30078bf416e1dec2 F src/sqlite.h.in 2683a291ed8db5228024267be6421f0de507b80e F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae -F src/sqliteInt.h 5748a35f10c0a03dc546caf8508f41ae3895ee8b +F src/sqliteInt.h 8d241c2c0a1a7b6611d3e9398f41d69426da850d F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 012ff6dd306328f7ea71a6600471c871e7ffe37b -R dd52011ff9f1bb8837d1755ce7de8828 +P 5bb7cde0731d23411e9df02a957010f94203397b +R ff4f5cc57903ee66db0f97f1966e5988 U drh -Z 9037cb2feea122245584ce285587b7bb +Z 380867cb8aabea21260823e30d45c1c4 diff --git a/manifest.uuid b/manifest.uuid index 7728cbefd6..55acf477e4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5bb7cde0731d23411e9df02a957010f94203397b \ No newline at end of file +d15ae2e530cffea60263f203ac5f89b6790f4bd5 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 942b2467ce..dd0c3cc061 100644 --- a/src/expr.c +++ b/src/expr.c @@ -938,7 +938,7 @@ Expr *sqlite3ExprFunction(Parse *pParse, ExprList *pList, Token *pToken){ ** instance of the wildcard, the next sequential variable number is ** assigned. */ -void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr){ +void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr, u32 n){ sqlite3 *db = pParse->db; const char *z; @@ -947,13 +947,13 @@ void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr){ z = pExpr->u.zToken; assert( z!=0 ); assert( z[0]!=0 ); + assert( n==sqlite3Strlen30(z) ); if( z[1]==0 ){ /* Wildcard of the form "?". Assign the next variable number */ assert( z[0]=='?' ); pExpr->iColumn = (ynVar)(++pParse->nVar); }else{ ynVar x = 0; - u32 n = sqlite3Strlen30(z); if( z[0]=='?' ){ /* Wildcard of the form "?nnn". Convert "nnn" to an integer and ** use it as the variable number */ diff --git a/src/parse.y b/src/parse.y index 5c5e450f31..1eff123d18 100644 --- a/src/parse.y +++ b/src/parse.y @@ -890,8 +890,9 @@ term(A) ::= INTEGER(X). { } expr(A) ::= VARIABLE(X). { if( !(X.z[0]=='#' && sqlite3Isdigit(X.z[1])) ){ + u32 n = X.n; spanExpr(&A, pParse, TK_VARIABLE, X); - sqlite3ExprAssignVarNumber(pParse, A.pExpr); + sqlite3ExprAssignVarNumber(pParse, A.pExpr, n); }else{ /* When doing a nested parse, one can include terms in an expression ** that look like this: #1 #2 ... These terms refer to registers diff --git a/src/sqliteInt.h b/src/sqliteInt.h index fade8a34d0..2d13f2635d 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3555,7 +3555,7 @@ Expr *sqlite3PExpr(Parse*, int, Expr*, Expr*, const Token*); void sqlite3PExprAddSelect(Parse*, Expr*, Select*); Expr *sqlite3ExprAnd(sqlite3*,Expr*, Expr*); Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*); -void sqlite3ExprAssignVarNumber(Parse*, Expr*); +void sqlite3ExprAssignVarNumber(Parse*, Expr*, u32); void sqlite3ExprDelete(sqlite3*, Expr*); ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*); ExprList *sqlite3ExprListAppendVector(Parse*,ExprList*,IdList*,Expr*); From c9b39288aeff95dfc49f8edc247ddb705a502000 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 3 Oct 2016 16:33:14 +0000 Subject: [PATCH 0897/1484] Size and performance optimizations on the sqlite3ExprAssignVarNumber() routine. FossilOrigin-Name: 109852e51e2cc2674940ba3e5097a92e66f88bb8 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/expr.c | 42 ++++++++++++++++++++---------------------- 3 files changed, 27 insertions(+), 29 deletions(-) diff --git a/manifest b/manifest index 7b46688fd3..f923ed6655 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sunnecessary\sstrlen()\scalls\sin\ssqlite3ExprAssignVarNumber()\sby\spassing\sin\nthe\stoken\slength\sfrom\sthe\sparser. -D 2016-10-03T15:28:24.522 +C Size\sand\sperformance\soptimizations\son\sthe\ssqlite3ExprAssignVarNumber()\sroutine. +D 2016-10-03T16:33:14.952 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -339,7 +339,7 @@ F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7 F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c cb3f6300df24c26c609778b2731f82644b5532ec -F src/expr.c cf99b1a327b4eb0a85d59f1c01d82bc2a318c544 +F src/expr.c aac0b8d39373ce8f1d47829ce12c3d7af90c46a6 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c b9ca262f6ad4d030a3cab737ebf9b0b3c8b4ac80 F src/func.c 29cc9acb170ec1387b9f63eb52cd85f8de96c771 @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 5bb7cde0731d23411e9df02a957010f94203397b -R ff4f5cc57903ee66db0f97f1966e5988 +P d15ae2e530cffea60263f203ac5f89b6790f4bd5 +R 02650575d610a64473014408e653c2e2 U drh -Z 380867cb8aabea21260823e30d45c1c4 +Z 400dafa0c844d13dbe01d3e4d393d771 diff --git a/manifest.uuid b/manifest.uuid index 55acf477e4..b497f8d346 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d15ae2e530cffea60263f203ac5f89b6790f4bd5 \ No newline at end of file +109852e51e2cc2674940ba3e5097a92e66f88bb8 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index dd0c3cc061..6d2ec437ff 100644 --- a/src/expr.c +++ b/src/expr.c @@ -953,13 +953,13 @@ void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr, u32 n){ assert( z[0]=='?' ); pExpr->iColumn = (ynVar)(++pParse->nVar); }else{ - ynVar x = 0; + ynVar x; if( z[0]=='?' ){ /* Wildcard of the form "?nnn". Convert "nnn" to an integer and ** use it as the variable number */ i64 i; int bOk = 0==sqlite3Atoi64(&z[1], &i, n-1, SQLITE_UTF8); - pExpr->iColumn = x = (ynVar)i; + x = (ynVar)i; testcase( i==0 ); testcase( i==1 ); testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]-1 ); @@ -967,7 +967,7 @@ void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr, u32 n){ if( bOk==0 || i<1 || i>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){ sqlite3ErrorMsg(pParse, "variable number must be between ?1 and ?%d", db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]); - x = 0; + return; } if( i>pParse->nVar ){ pParse->nVar = (int)i; @@ -978,33 +978,31 @@ void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr, u32 n){ ** has never appeared before, reuse the same variable number */ ynVar i; - for(i=0; inzVar; i++){ + for(i=x=0; inzVar; i++){ if( pParse->azVar[i] && strcmp(pParse->azVar[i],z)==0 ){ - pExpr->iColumn = x = (ynVar)i+1; + x = (ynVar)i+1; break; } } - if( x==0 ) x = pExpr->iColumn = (ynVar)(++pParse->nVar); + if( x==0 ) x = (ynVar)(++pParse->nVar); } - if( x>0 ){ - if( x>pParse->nzVar ){ - char **a; - a = sqlite3DbRealloc(db, pParse->azVar, x*sizeof(a[0])); - if( a==0 ){ - assert( db->mallocFailed ); /* Error reported through mallocFailed */ - return; - } - pParse->azVar = a; - memset(&a[pParse->nzVar], 0, (x-pParse->nzVar)*sizeof(a[0])); - pParse->nzVar = x; - } - if( z[0]!='?' || pParse->azVar[x-1]==0 ){ - sqlite3DbFree(db, pParse->azVar[x-1]); - pParse->azVar[x-1] = sqlite3DbStrNDup(db, z, n); + pExpr->iColumn = x; + if( x>pParse->nzVar ){ + char **a; + a = sqlite3DbRealloc(db, pParse->azVar, x*sizeof(a[0])); + if( a==0 ){ + assert( db->mallocFailed ); /* Error reported through mallocFailed */ + return; } + pParse->azVar = a; + memset(&a[pParse->nzVar], 0, (x-pParse->nzVar)*sizeof(a[0])); + pParse->nzVar = x; + } + if( pParse->azVar[x-1]==0 ){ + pParse->azVar[x-1] = sqlite3DbStrNDup(db, z, n); } } - if( !pParse->nErr && pParse->nVar>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){ + if( pParse->nVar>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){ sqlite3ErrorMsg(pParse, "too many SQL variables"); } } From a71c743aae992593935a8578aa0ac51b58e08fa7 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 3 Oct 2016 18:13:23 +0000 Subject: [PATCH 0898/1484] Allow deterministic functions in the WHERE clause of a partial index. FossilOrigin-Name: c6e9b9421805c904b20900b711fa0e51773aef3e --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/resolve.c | 6 +++--- test/index6.test | 7 +++++-- test/index7.test | 17 +++++++++++++++-- 5 files changed, 32 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index f923ed6655..b70497eb6e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Size\sand\sperformance\soptimizations\son\sthe\ssqlite3ExprAssignVarNumber()\sroutine. -D 2016-10-03T16:33:14.952 +C Allow\sdeterministic\sfunctions\sin\sthe\sWHERE\sclause\sof\sa\spartial\sindex. +D 2016-10-03T18:13:23.577 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -384,7 +384,7 @@ F src/pragma.h 64c78a648751b9f4f297276c4eb7507b14b4628c F src/prepare.c b1140c3d0cf59bc85ace00ce363153041b424b7a F src/printf.c a5f0ca08ddede803c241266abb46356ec748ded1 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 -F src/resolve.c 3c3cf0dc719cd2a32ab5c1e10c26481dd565492e +F src/resolve.c e918c6434e315fc7f295863dcaa58da10d3a1e9c F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c ea3af83e2d0f245fef81ea4cf04cb730ce67f722 F src/shell.c b80396d2fadce4681397707e30078bf416e1dec2 @@ -848,8 +848,8 @@ F test/index2.test f835d5e13ca163bd78c4459ca15fd2e4ed487407 F test/index3.test 81bc47890b8abfb181bc35f8d10b56c069803386 F test/index4.test ab92e736d5946840236cd61ac3191f91a7856bf6 F test/index5.test 8621491915800ec274609e42e02a97d67e9b13e7 -F test/index6.test 43b4e29258b978fcdab84fc61df4f5212119dd09 -F test/index7.test 9c6765a74fc3fcde7aebc5b3bd40d98df14a527c +F test/index6.test b4fc812290067a578b98bb2667b676db89e202a7 +F test/index7.test 7feababe16f2091b229c22aff2bcc1d4d6b9d2bb F test/index8.test bc2e3db70e8e62459aaa1bd7e4a9b39664f8f9d7 F test/indexedby.test 9c4cd331224e57f79fbf411ae245e6272d415985 F test/indexexpr1.test cb71b6586177b840e28110dd952178bb2bdfedc2 @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d15ae2e530cffea60263f203ac5f89b6790f4bd5 -R 02650575d610a64473014408e653c2e2 +P 109852e51e2cc2674940ba3e5097a92e66f88bb8 +R 570e98b0ce01791f7df81d2307617f83 U drh -Z 400dafa0c844d13dbe01d3e4d393d771 +Z 806f5071a81ad8307711df9ff707b7fc diff --git a/manifest.uuid b/manifest.uuid index b497f8d346..6e617448ac 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -109852e51e2cc2674940ba3e5097a92e66f88bb8 \ No newline at end of file +c6e9b9421805c904b20900b711fa0e51773aef3e \ No newline at end of file diff --git a/src/resolve.c b/src/resolve.c index 2171533ef3..5654a0438b 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -623,7 +623,6 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ /* if( pSrcList==0 ) break; */ notValid(pParse, pNC, "the \".\" operator", NC_IdxExpr); - /*notValid(pParse, pNC, "the \".\" operator", NC_PartIdx|NC_IsCheck, 1);*/ pRight = pExpr->pRight; if( pRight->op==TK_ID ){ zDb = 0; @@ -652,7 +651,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ u8 enc = ENC(pParse->db); /* The database encoding */ assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); - notValid(pParse, pNC, "functions", NC_PartIdx); +// notValid(pParse, pNC, "functions", NC_PartIdx); zId = pExpr->u.zToken; nId = sqlite3Strlen30(zId); pDef = sqlite3FindFunction(pParse->db, zId, n, enc, 0); @@ -712,7 +711,8 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ /* Date/time functions that use 'now', and other functions like ** sqlite_version() that might change over time cannot be used ** in an index. */ - notValid(pParse, pNC, "non-deterministic functions", NC_IdxExpr); + notValid(pParse, pNC, "non-deterministic functions", + NC_IdxExpr|NC_PartIdx); } } if( is_agg && (pNC->ncFlags & NC_AllowAgg)==0 ){ diff --git a/test/index6.test b/test/index6.test index 9501a6c864..f6177b44e9 100644 --- a/test/index6.test +++ b/test/index6.test @@ -65,12 +65,15 @@ do_test index6-1.5 { catchsql { CREATE INDEX bad1 ON t1(a,b) WHERE a!=random(); } -} {1 {functions prohibited in partial index WHERE clauses}} +} {1 {non-deterministic functions prohibited in partial index WHERE clauses}} do_test index6-1.6 { catchsql { CREATE INDEX bad1 ON t1(a,b) WHERE a NOT LIKE 'abc%'; } -} {1 {functions prohibited in partial index WHERE clauses}} +} {0 {}} +do_execsql_test index6-1.7 { + DROP INDEX IF EXISTS bad1; +} do_test index6-1.10 { execsql { diff --git a/test/index7.test b/test/index7.test index 557fe21324..0037a8a44d 100644 --- a/test/index7.test +++ b/test/index7.test @@ -99,12 +99,25 @@ do_test index7-1.5 { catchsql { CREATE INDEX bad1 ON t1(a,b) WHERE a!=random(); } -} {1 {functions prohibited in partial index WHERE clauses}} +} {1 {non-deterministic functions prohibited in partial index WHERE clauses}} do_test index7-1.6 { catchsql { CREATE INDEX bad1 ON t1(a,b) WHERE a NOT LIKE 'abc%'; } -} {1 {functions prohibited in partial index WHERE clauses}} +} {0 {}} +do_execsql_test index7-1.7 { + INSERT INTO t1(a,b,c) + VALUES('abcde',1,101),('abdef',2,102),('xyz',3,103),('abcz',4,104); + SELECT c FROM t1 WHERE a NOT LIKE 'abc%' AND a=7 ORDER BY +b; +} {7} +do_execsql_test index7-1.7eqp { + EXPLAIN QUERY PLAN + SELECT b FROM t1 WHERE a NOT LIKE 'abc%' AND a=7 ORDER BY +b; +} {/SEARCH TABLE t1 USING COVERING INDEX bad1 /} +do_execsql_test index7-1.8 { + DELETE FROM t1 WHERE c>=101; + DROP INDEX IF EXISTS bad1; +} {} do_test index7-1.10 { execsql { From 44728d7e019e33e43f944be4a12fcbe3fd2da62a Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 4 Oct 2016 00:47:26 +0000 Subject: [PATCH 0899/1484] Do not bother to initialize unused fields in the BtreePayload object. FossilOrigin-Name: b10d0f939c82c4de3faa90b86de9ec4a89992856 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/btree.c | 2 -- src/vdbe.c | 3 --- 4 files changed, 8 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index b70497eb6e..51195f39a9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Allow\sdeterministic\sfunctions\sin\sthe\sWHERE\sclause\sof\sa\spartial\sindex. -D 2016-10-03T18:13:23.577 +C Do\snot\sbother\sto\sinitialize\sunused\sfields\sin\sthe\sBtreePayload\sobject. +D 2016-10-04T00:47:26.005 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -329,7 +329,7 @@ F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792 F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b F src/bitvec.c 3ee4c8b2c94ed3a7377256e18199e6ff5cf33f63 F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 -F src/btree.c a0a80fbbb34a35ca02cd829bad693b7854bee313 +F src/btree.c 7a45743fb947c89bd6c972bfb18c8f80c070ad51 F src/btree.h d05b2fcc290991a8a3d9ea1816ddd55a4359dcde F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 F src/build.c 59dcfdc1ee55439d069af301ef7f2e84421b5102 @@ -453,7 +453,7 @@ F src/update.c 8179e699dbd45b92934fd02d3d8e3732e8da8802 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 3e2da6101888d073e79ecc6af5e0a2f70fa1e498 F src/vacuum.c 913970b9d86dd6c2b8063ef1af421880f1464ec3 -F src/vdbe.c 51e754eec26d892abc6279f5e949545af68ec1b3 +F src/vdbe.c f43aa96f2efe9bc8a06d17115661af527a3318fa F src/vdbe.h c044be7050ac6bf596eecc6ab159f5dbc020a3b7 F src/vdbeInt.h 0a18713d0a2fec6807d076bd333d9bf3e57530cd F src/vdbeapi.c 8272f9342c39ab8d7eb4b9decc6caa7bc75b7d83 @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 109852e51e2cc2674940ba3e5097a92e66f88bb8 -R 570e98b0ce01791f7df81d2307617f83 +P c6e9b9421805c904b20900b711fa0e51773aef3e +R 66af79a90ae1c2b03d628f9e680deefb U drh -Z 806f5071a81ad8307711df9ff707b7fc +Z c238f953392eb5f8e38079e9a79ab2f6 diff --git a/manifest.uuid b/manifest.uuid index 6e617448ac..70d83898ea 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c6e9b9421805c904b20900b711fa0e51773aef3e \ No newline at end of file +b10d0f939c82c4de3faa90b86de9ec4a89992856 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 45b4750b7b..3e8e59f3a3 100644 --- a/src/btree.c +++ b/src/btree.c @@ -6100,8 +6100,6 @@ static int fillInCell( nHeader += putVarint32(&pCell[nHeader], nPayload); nHeader += putVarint(&pCell[nHeader], *(u64*)&pX->nKey); }else{ - assert( pX->nData==0 ); - assert( pX->nZero==0 ); assert( pX->nKey<=0x7fffffff && pX->pKey!=0 ); nSrc = nPayload = (int)pX->nKey; pSrc = pX->pKey; diff --git a/src/vdbe.c b/src/vdbe.c index 25b507f37f..54df5c536d 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -5059,9 +5059,6 @@ case OP_IdxInsert: { /* in2 */ }else{ x.nKey = pIn2->n; x.pKey = pIn2->z; - x.nData = 0; - x.nZero = 0; - x.pData = 0; rc = sqlite3BtreeInsert(pC->uc.pCursor, &x, pOp->p3, ((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0) ); From 4eda15e7153b1a361e5b0d7ee26ac88d2e89a8e2 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 4 Oct 2016 12:20:12 +0000 Subject: [PATCH 0900/1484] Fix a problem with the lempar.c parser template. FossilOrigin-Name: 3a9d802fda10585654332b314d317250dc5d894e --- manifest | 12 ++++++------ manifest.uuid | 2 +- tool/lempar.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 51195f39a9..212cabf385 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Do\snot\sbother\sto\sinitialize\sunused\sfields\sin\sthe\sBtreePayload\sobject. -D 2016-10-04T00:47:26.005 +C Fix\sa\sproblem\swith\sthe\slempar.c\sparser\stemplate. +D 2016-10-04T12:20:12.988 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -1453,7 +1453,7 @@ F tool/genfkey.README cf68fddd4643bbe3ff8e31b8b6d8b0a1b85e20f4 F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5 F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce F tool/lemon.c e4fb7d888873ac88f20a41c84a7d1e61f5209a6d -F tool/lempar.c 147e42a5cd83ce38275fde0d07a5df3330cb9b3b +F tool/lempar.c 7cf047778e74433126cb02896e3f898d7b1e20aa F tool/libvers.c caafc3b689638a1d88d44bc5f526c2278760d9b9 F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862 F tool/logest.c 11346aa019e2e77a00902aa7d0cabd27bd2e8cca @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P c6e9b9421805c904b20900b711fa0e51773aef3e -R 66af79a90ae1c2b03d628f9e680deefb +P b10d0f939c82c4de3faa90b86de9ec4a89992856 +R 6c760026d8601df73a97e44e77f2a1fb U drh -Z c238f953392eb5f8e38079e9a79ab2f6 +Z 1b936abb9e0dcff8bac4243206b2a78f diff --git a/manifest.uuid b/manifest.uuid index 70d83898ea..70760d1e99 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b10d0f939c82c4de3faa90b86de9ec4a89992856 \ No newline at end of file +3a9d802fda10585654332b314d317250dc5d894e \ No newline at end of file diff --git a/tool/lempar.c b/tool/lempar.c index 61d19451e9..5195d9c31b 100644 --- a/tool/lempar.c +++ b/tool/lempar.c @@ -872,7 +872,7 @@ void Parse( yy_destructor(yypParser, (YYCODETYPE)yymajor, &yyminorunion); yymajor = YYNOCODE; }else{ - while( yypParser->yytos >= &yypParser->yystack + while( yypParser->yytos >= yypParser->yystack && yymx != YYERRORSYMBOL && (yyact = yy_find_reduce_action( yypParser->yytos->stateno, From e0251d44fa13f5b47ad4aeca01b3c4e154b704a3 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 5 Oct 2016 01:33:57 +0000 Subject: [PATCH 0901/1484] Fix the backup_malloc.test script so that it works on Windows. FossilOrigin-Name: d080012daaaa399663a0f767c792a2fff3e1037a --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/backup_malloc.test | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 212cabf385..2502e5dc66 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\swith\sthe\slempar.c\sparser\stemplate. -D 2016-10-04T12:20:12.988 +C Fix\sthe\sbackup_malloc.test\sscript\sso\sthat\sit\sworks\son\sWindows. +D 2016-10-05T01:33:57.627 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -527,7 +527,7 @@ F test/backup2.test 34986ef926ea522911a51dfdb2f8e99b7b75ebcf F test/backup4.test 8f6fd48e0dfde77b9a3bb26dc471ede3e101df32 F test/backup5.test ee5da6d7fe5082f5b9b0bbfa31d016f52412a2e4 F test/backup_ioerr.test 4c3c7147cee85b024ecf6e150e090c32fdbb5135 -F test/backup_malloc.test 833d1b90561a6dbab00079b9591bd4fc90b7c2e1 +F test/backup_malloc.test 0c9abdf74c51e7bedb66d504cd684f28d4bd4027 F test/badutf.test d5360fc31f643d37a973ab0d8b4fb85799c3169f F test/badutf2.test f5bc7f2d280670ecd79b9cf4f0f1760c607fe51f F test/bc_common.tcl b5e42d80305be95697e6370e015af571e5333a1c @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b10d0f939c82c4de3faa90b86de9ec4a89992856 -R 6c760026d8601df73a97e44e77f2a1fb +P 3a9d802fda10585654332b314d317250dc5d894e +R d615c6e1908364fa884ab39f817d3e59 U drh -Z 1b936abb9e0dcff8bac4243206b2a78f +Z 82328ebb1684c06ada6a91008b6e6bcf diff --git a/manifest.uuid b/manifest.uuid index 70760d1e99..6a1aab38e2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3a9d802fda10585654332b314d317250dc5d894e \ No newline at end of file +d080012daaaa399663a0f767c792a2fff3e1037a \ No newline at end of file diff --git a/test/backup_malloc.test b/test/backup_malloc.test index 45cac44f18..5444a70bdf 100644 --- a/test/backup_malloc.test +++ b/test/backup_malloc.test @@ -95,6 +95,7 @@ do_execsql_test 3.0 { do_faultsim_test 3 -faults oom* -prep { catch { db close } + catch { db2 close } forcedelete test2.db sqlite3 db2 test2.db From da5c62400f4b78056839f7d147a61a920c6d85b9 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 5 Oct 2016 15:02:00 +0000 Subject: [PATCH 0902/1484] Do not set MEM_Blob unless the appropriate fields of the Mem object have been correctly initialized. FossilOrigin-Name: a596b7c6cc780525120604090493f3f7d962b9fa --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbemem.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 2502e5dc66..41cbd6f016 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\sbackup_malloc.test\sscript\sso\sthat\sit\sworks\son\sWindows. -D 2016-10-05T01:33:57.627 +C Do\snot\sset\sMEM_Blob\sunless\sthe\sappropriate\sfields\sof\sthe\sMem\sobject\shave\nbeen\scorrectly\sinitialized. +D 2016-10-05T15:02:00.449 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -459,7 +459,7 @@ F src/vdbeInt.h 0a18713d0a2fec6807d076bd333d9bf3e57530cd F src/vdbeapi.c 8272f9342c39ab8d7eb4b9decc6caa7bc75b7d83 F src/vdbeaux.c 7229203e4e4a3b6eaeeddc807c2287d912c0da74 F src/vdbeblob.c 3e82a797b60c3b9fed7b8de8c539ca7607874937 -F src/vdbemem.c 1c330522e6b6e4ddd2ff63c4c0dfafa20c3965a7 +F src/vdbemem.c fcdd73a2001a673f48a244a77b1038928ae729c9 F src/vdbesort.c 91fda3909326860382b0ca8aa251e609c6a9d62c F src/vdbetrace.c 41963d5376f0349842b5fc4aaaaacd7d9cdc0834 F src/vtab.c e02cacb5c7ae742631edeb9ae9f53d399f093fd8 @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 3a9d802fda10585654332b314d317250dc5d894e -R d615c6e1908364fa884ab39f817d3e59 +P d080012daaaa399663a0f767c792a2fff3e1037a +R aed24a0e8c9a4a3387c1268ec44fc626 U drh -Z 82328ebb1684c06ada6a91008b6e6bcf +Z 826cac4d495f0a95b9177a12f7f9bfad diff --git a/manifest.uuid b/manifest.uuid index 6a1aab38e2..9b4b08bae3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d080012daaaa399663a0f767c792a2fff3e1037a \ No newline at end of file +a596b7c6cc780525120604090493f3f7d962b9fa \ No newline at end of file diff --git a/src/vdbemem.c b/src/vdbemem.c index d009f804df..9b78d5432c 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -593,7 +593,7 @@ void sqlite3VdbeMemCast(Mem *pMem, u8 aff, u8 encoding){ if( (pMem->flags & MEM_Blob)==0 ){ sqlite3ValueApplyAffinity(pMem, SQLITE_AFF_TEXT, encoding); assert( pMem->flags & MEM_Str || pMem->db->mallocFailed ); - MemSetTypeFlag(pMem, MEM_Blob); + if( pMem->flags & MEM_Str ) MemSetTypeFlag(pMem, MEM_Blob); }else{ pMem->flags &= ~(MEM_TypeMask&~MEM_Blob); } From 4e59344a4cbf96862a8d767ca60f277d113f44c5 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 5 Oct 2016 15:04:35 +0000 Subject: [PATCH 0903/1484] Add a test case for the fix in [a596b7c6cc]. FossilOrigin-Name: b2ef39b11f7c46e69e53439680c32adbb18903bd --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/mallocI.test | 11 +++++++++++ 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 41cbd6f016..bed7ed40c5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Do\snot\sset\sMEM_Blob\sunless\sthe\sappropriate\sfields\sof\sthe\sMem\sobject\shave\nbeen\scorrectly\sinitialized. -D 2016-10-05T15:02:00.449 +C Add\sa\stest\scase\sfor\sthe\sfix\sin\s[a596b7c6cc]. +D 2016-10-05T15:04:35.219 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -924,7 +924,7 @@ F test/mallocE.test db1ed69d7eded1b080952e2a7c37f364ad241b08 F test/mallocF.test 2d5c590ebc2fc7f0dcebdf5aa8498b9aed69107e F test/mallocG.test 0ff91b65c50bdaba680fb75d87fe4ad35bb7934f F test/mallocH.test 79b65aed612c9b3ed2dcdaa727c85895fd1bfbdb -F test/mallocI.test a88c2b9627c8506bf4703d8397420043a786cdb6 +F test/mallocI.test 6c23a71df077fa5d387be90e7e669c5b368ca38a F test/mallocJ.test b5d1839da331d96223e5f458856f8ffe1366f62e F test/mallocK.test 27cb5566a6e5f2d76f9d4aa2eca45524401fd61e F test/mallocL.test fb311ff80afddf3b1a75e52289081f4754d901dc @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d080012daaaa399663a0f767c792a2fff3e1037a -R aed24a0e8c9a4a3387c1268ec44fc626 -U drh -Z 826cac4d495f0a95b9177a12f7f9bfad +P a596b7c6cc780525120604090493f3f7d962b9fa +R f1f428b414d0a1cdb093889abe85d0a9 +U dan +Z 5d912db51972f65526081b21248c8b3d diff --git a/manifest.uuid b/manifest.uuid index 9b4b08bae3..28d91e9311 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a596b7c6cc780525120604090493f3f7d962b9fa \ No newline at end of file +b2ef39b11f7c46e69e53439680c32adbb18903bd \ No newline at end of file diff --git a/test/mallocI.test b/test/mallocI.test index 1229455505..ee4a603dee 100644 --- a/test/mallocI.test +++ b/test/mallocI.test @@ -61,4 +61,15 @@ do_malloc_test mallocI-4 -tclprep { } catch { db2 close } +do_faultsim_test mallocI-5 -faults oom* -prep { + catch { db close } + sqlite3 db test.db + sqlite3_db_config_lookaside db 0 0 0 +} -body { + db eval { Select CAST(1 AS blob) } +} -test { + faultsim_test_result {0 1} +} + + finish_test From e3c6b61cee7682a120e044b4009b5840c9282d48 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 5 Oct 2016 20:10:32 +0000 Subject: [PATCH 0904/1484] Fix harmless compiler warnings. FossilOrigin-Name: 2dde3375124198560c8ff15f87aadde2afd722c5 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/resolve.c | 1 - src/wherecode.c | 5 ++--- 4 files changed, 11 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index bed7ed40c5..3ae5e26776 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sa\stest\scase\sfor\sthe\sfix\sin\s[a596b7c6cc]. -D 2016-10-05T15:04:35.219 +C Fix\sharmless\scompiler\swarnings. +D 2016-10-05T20:10:32.759 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -384,7 +384,7 @@ F src/pragma.h 64c78a648751b9f4f297276c4eb7507b14b4628c F src/prepare.c b1140c3d0cf59bc85ace00ce363153041b424b7a F src/printf.c a5f0ca08ddede803c241266abb46356ec748ded1 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 -F src/resolve.c e918c6434e315fc7f295863dcaa58da10d3a1e9c +F src/resolve.c 3fac1b2737ea5a724f20b921ac7e259c9be2100b F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c ea3af83e2d0f245fef81ea4cf04cb730ce67f722 F src/shell.c b80396d2fadce4681397707e30078bf416e1dec2 @@ -469,7 +469,7 @@ F src/wal.h 6dd221ed384afdc204bc61e25c23ef7fd5a511f2 F src/walker.c 91a6df7435827e41cff6bb7df50ea00934ee78b0 F src/where.c c264ec85d94a7292753c03bdf71a015625c01106 F src/whereInt.h 2bcc3d176e6091cb8f50a30b65c006e88a73614d -F src/wherecode.c 81da7e9b1bf1a882f3ee60b96b750322b83f17fd +F src/wherecode.c d07f784cda9d51eb04f086171a67eadda17f963f F src/whereexpr.c 379d0017fb7bc9e5a4d8cd4b056c747de946430e F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a596b7c6cc780525120604090493f3f7d962b9fa -R f1f428b414d0a1cdb093889abe85d0a9 -U dan -Z 5d912db51972f65526081b21248c8b3d +P b2ef39b11f7c46e69e53439680c32adbb18903bd +R f292329ca2bd3e63752265c61e007ecf +U drh +Z e19c7a6707a28d226be185a5400d48cc diff --git a/manifest.uuid b/manifest.uuid index 28d91e9311..98cf0c21a9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b2ef39b11f7c46e69e53439680c32adbb18903bd \ No newline at end of file +2dde3375124198560c8ff15f87aadde2afd722c5 \ No newline at end of file diff --git a/src/resolve.c b/src/resolve.c index 5654a0438b..f464b657fc 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -651,7 +651,6 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ u8 enc = ENC(pParse->db); /* The database encoding */ assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); -// notValid(pParse, pNC, "functions", NC_PartIdx); zId = pExpr->u.zToken; nId = sqlite3Strlen30(zId); pDef = sqlite3FindFunction(pParse->db, zId, n, enc, 0); diff --git a/src/wherecode.c b/src/wherecode.c index ec21e0bf67..a244a303a6 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -361,7 +361,6 @@ static void codeApplyAffinity(Parse *pParse, int base, int n, char *zAff){ ** * the affinity change in zAff is guaranteed not to change the value. */ static void updateRangeAffinityStr( - Parse *pParse, /* Parse context */ Expr *pRight, /* RHS of comparison */ int n, /* Number of vector elements in comparison */ char *zAff /* Affinity string to modify */ @@ -1501,7 +1500,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( VdbeCoverage(v); } if( zStartAff ){ - updateRangeAffinityStr(pParse, pRight, nBtm, &zStartAff[nEq]); + updateRangeAffinityStr(pRight, nBtm, &zStartAff[nEq]); } nConstraint += nBtm; testcase( pRangeStart->wtFlags & TERM_VIRTUAL ); @@ -1551,7 +1550,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( VdbeCoverage(v); } if( zEndAff ){ - updateRangeAffinityStr(pParse, pRight, nTop, zEndAff); + updateRangeAffinityStr(pRight, nTop, zEndAff); codeApplyAffinity(pParse, regBase+nEq, nTop, zEndAff); }else{ assert( pParse->db->mallocFailed ); From 642f0146d7ad5bf1134394c99ee83a69e92a10e7 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 5 Oct 2016 20:14:29 +0000 Subject: [PATCH 0905/1484] Fix some compiler warnings in fts5. FossilOrigin-Name: b066637bb75959267fe6104da323c5112ad78f82 --- ext/fts5/fts5_aux.c | 4 +++- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/ext/fts5/fts5_aux.c b/ext/fts5/fts5_aux.c index e171233050..219ea6fff8 100644 --- a/ext/fts5/fts5_aux.c +++ b/ext/fts5/fts5_aux.c @@ -292,6 +292,9 @@ static int fts5SentenceFinderCb( ){ int rc = SQLITE_OK; + UNUSED_PARAM2(pToken, nToken); + UNUSED_PARAM(iEndOff); + if( (tflags & FTS5_TOKEN_COLOCATED)==0 ){ Fts5SFinder *p = (Fts5SFinder*)pContext; if( p->iPos>0 ){ @@ -447,7 +450,6 @@ static void fts5SnippetFunction( } if( sFinder.aFirst[jj] Date: Sat, 8 Oct 2016 09:21:34 +0000 Subject: [PATCH 0906/1484] Updates to the tool/warnings.sh script to make it easier to use on OpenBSD. FossilOrigin-Name: dbe2997f57f8d8f95e4b767bf73b8df3a5e4f783 --- manifest | 12 ++++++------ manifest.uuid | 2 +- tool/warnings.sh | 21 +++++++++++++++++---- 3 files changed, 24 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index c703e49f4b..b0bf32cff6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\ssome\scompiler\swarnings\sin\sfts5. -D 2016-10-05T20:14:29.499 +C Updates\sto\sthe\stool/warnings.sh\sscript\sto\smake\sit\seasier\sto\suse\son\sOpenBSD. +D 2016-10-08T09:21:34.023 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -1502,7 +1502,7 @@ F tool/varint.c 5d94cb5003db9dbbcbcc5df08d66f16071aee003 F tool/vdbe-compress.tcl 5926c71f9c12d2ab73ef35c29376e756eb68361c F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 -F tool/warnings.sh a98af506df552f3b3c0d904f94e4cdc4e1a6d598 +F tool/warnings.sh d9ded5274b3cb947e98e70d587f71d6263f803b5 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f F vsixtest/App.xaml b76d3b48860e7454775c47ea38ffea9c4abe3e85 F vsixtest/App.xaml.cpp c465147f50871165c60ca16955219f6c5812d6d8 @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 2dde3375124198560c8ff15f87aadde2afd722c5 -R 4b9b0be198a5bbe128b1c0892a941d69 +P b066637bb75959267fe6104da323c5112ad78f82 +R 895493ea71b68bd283f6f57b6ab90541 U dan -Z 15a8a191138ee57877cbdb39242d3ca2 +Z de8241f62395dc0c51d3359eea561a34 diff --git a/manifest.uuid b/manifest.uuid index 6550bdd74e..dd94310763 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b066637bb75959267fe6104da323c5112ad78f82 \ No newline at end of file +dbe2997f57f8d8f95e4b767bf73b8df3a5e4f783 \ No newline at end of file diff --git a/tool/warnings.sh b/tool/warnings.sh index cee639dc45..ae40cfb1ae 100644 --- a/tool/warnings.sh +++ b/tool/warnings.sh @@ -3,15 +3,26 @@ # Run this script in a directory with a working makefile to check for # compiler warnings in SQLite. # + +# Use these for testing on Linux and Mac OSX: +WARNING_OPTS="-Wshadow -Wall -Wextra -pedantic-errors -Wno-long-long" +WARNING_ANDROID_OPTS="-Wshadow -Wall -Wextra" + +# Use these for testing on OpenBSD: +# WARNING_OPTS=-Wall +# WARNING_ANDROID_OPTS=-Wall + rm -f sqlite3.c make sqlite3.c echo '********** No optimizations. Includes FTS4/5, RTREE, JSON1 ***' -gcc -c -Wshadow -Wall -Wextra -pedantic-errors -Wno-long-long -std=c89 \ +echo '********** ' Options: $WARNING_OPTS +gcc -c $WARNING_OPTS -std=c89 \ -ansi -DHAVE_STDINT_H -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_RTREE \ -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_JSON1 \ sqlite3.c if test x`uname` = 'xLinux'; then echo '********** Android configuration ******************************' +echo '********** ' Options: $WARNING_ANDROID_OPTS gcc -c \ -DHAVE_USLEEP=1 \ -DSQLITE_HAVE_ISNAN \ @@ -31,15 +42,17 @@ gcc -c \ -DSQLITE_DEFAULT_FILE_PERMISSIONS=0600 \ -DSQLITE_ENABLE_ICU \ -DUSE_PREAD64 \ - -Wshadow -Wall -Wextra \ + $WARNING_ANDROID_OPTS \ -Os sqlite3.c shell.c fi echo '********** No optimizations. ENABLE_STAT4. THREADSAFE=0 *******' -gcc -c -Wshadow -Wall -Wextra -pedantic-errors -Wno-long-long -std=c89 \ +echo '********** ' Options: $WARNING_OPTS +gcc -c $WARNING_OPTS -std=c89 \ -ansi -DSQLITE_ENABLE_STAT4 -DSQLITE_THREADSAFE=0 \ sqlite3.c echo '********** Optimized -O3. Includes FTS4/5, RTREE, JSON1 ******' -gcc -O3 -c -Wshadow -Wall -Wextra -pedantic-errors -Wno-long-long -std=c89 \ +echo '********** ' Options: $WARNING_OPTS +gcc -O3 -c $WARNING_OPTS -std=c89 \ -ansi -DHAVE_STDINT_H -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_RTREE \ -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_JSON1 \ sqlite3.c From 320d4c304dc73199942a2415c4d1c6aa039b0920 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 8 Oct 2016 11:55:12 +0000 Subject: [PATCH 0907/1484] Add missing "static" to internal function whereRangeVectorLen(). FossilOrigin-Name: cbed3d75cf9a24037263d126727db7dd048a4f97 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/where.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index b0bf32cff6..503cafcfec 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Updates\sto\sthe\stool/warnings.sh\sscript\sto\smake\sit\seasier\sto\suse\son\sOpenBSD. -D 2016-10-08T09:21:34.023 +C Add\smissing\s"static"\sto\sinternal\sfunction\swhereRangeVectorLen(). +D 2016-10-08T11:55:12.559 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -467,7 +467,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 02eeecc265f6ffd0597378f5d8ae9070b62a406a F src/wal.h 6dd221ed384afdc204bc61e25c23ef7fd5a511f2 F src/walker.c 91a6df7435827e41cff6bb7df50ea00934ee78b0 -F src/where.c c264ec85d94a7292753c03bdf71a015625c01106 +F src/where.c a2269d2df19d0e98717e163efaea8d1b532dfce4 F src/whereInt.h 2bcc3d176e6091cb8f50a30b65c006e88a73614d F src/wherecode.c d07f784cda9d51eb04f086171a67eadda17f963f F src/whereexpr.c 379d0017fb7bc9e5a4d8cd4b056c747de946430e @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b066637bb75959267fe6104da323c5112ad78f82 -R 895493ea71b68bd283f6f57b6ab90541 +P dbe2997f57f8d8f95e4b767bf73b8df3a5e4f783 +R 1c63a7fb91dc2dc6972e910863772c96 U dan -Z de8241f62395dc0c51d3359eea561a34 +Z 6786da16e23c94ae7e9e3ff923a5e88f diff --git a/manifest.uuid b/manifest.uuid index dd94310763..9735f0319d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -dbe2997f57f8d8f95e4b767bf73b8df3a5e4f783 \ No newline at end of file +cbed3d75cf9a24037263d126727db7dd048a4f97 \ No newline at end of file diff --git a/src/where.c b/src/where.c index 32ae7323b4..cccf2c47f4 100644 --- a/src/where.c +++ b/src/where.c @@ -2223,7 +2223,7 @@ static void whereLoopOutputAdjust( ** then this function would be invoked with nEq=1. The value returned in ** this case is 3. */ -int whereRangeVectorLen( +static int whereRangeVectorLen( Parse *pParse, /* Parsing context */ int iCur, /* Cursor open on pIdx */ Index *pIdx, /* The index to be used for a inequality constraint */ From dfe4e6bb33bc58a5d72e635c83d0895e412bdde6 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 8 Oct 2016 13:34:08 +0000 Subject: [PATCH 0908/1484] Corrections to Lemon documentation. No SQLite changes. FossilOrigin-Name: c568ae3eef31b49e846fad90e705914e2868a09c --- doc/lemon.html | 4 ++-- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/doc/lemon.html b/doc/lemon.html index 773c68e6ad..114526f372 100644 --- a/doc/lemon.html +++ b/doc/lemon.html @@ -85,7 +85,7 @@ Define C preprocessor macro name. This macro is useable by Do not generate a parser. Instead write the input grammar to standard output with all comments, actions, and other extraneous text removed.
  • -l -Omit "#line" directives int the generated parser C code. +Omit "#line" directives in the generated parser C code.
  • -m Cause the output C source code to be compatible with the "makeheaders" program. @@ -929,7 +929,7 @@ token structure. Like this:

    If the data type of terminals is not specified, the default value -is "int".

    +is "void*".

    Non-terminal symbols can each have their own data types. Typically the data type of a non-terminal is a pointer to the root of a parse-tree diff --git a/manifest b/manifest index 503cafcfec..e34c16e506 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\smissing\s"static"\sto\sinternal\sfunction\swhereRangeVectorLen(). -D 2016-10-08T11:55:12.559 +C Corrections\sto\sLemon\sdocumentation.\s\sNo\sSQLite\schanges. +D 2016-10-08T13:34:08.299 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -33,7 +33,7 @@ F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55 F configure 3f44893bc0e51c30653e02b0fd4dc2ab585e446a x F configure.ac b5d3df43161374f8dffd2e5f4b88fbb51685b975 F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad -F doc/lemon.html e2118945e5f07ed146b45c9cd2b2dd6eabb8ebf2 +F doc/lemon.html b5a3c07d33ecb8e019ce8f7660fe2dbbad9d7977 F doc/pager-invariants.txt 27fed9a70ddad2088750c4a2b493b63853da2710 F doc/vfs-shm.txt e101f27ea02a8387ce46a05be2b1a902a021d37a F ext/README.txt 913a7bd3f4837ab14d7e063304181787658b14e1 @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P dbe2997f57f8d8f95e4b767bf73b8df3a5e4f783 -R 1c63a7fb91dc2dc6972e910863772c96 -U dan -Z 6786da16e23c94ae7e9e3ff923a5e88f +P cbed3d75cf9a24037263d126727db7dd048a4f97 +R 32fe7082776be1c5e19835aad8801e28 +U drh +Z 8f596491c82d3cdf69733967abe08530 diff --git a/manifest.uuid b/manifest.uuid index 9735f0319d..044fdcb277 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cbed3d75cf9a24037263d126727db7dd048a4f97 \ No newline at end of file +c568ae3eef31b49e846fad90e705914e2868a09c \ No newline at end of file From e5ec01c481816280a27056a5770fd4a71395dad4 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 8 Oct 2016 16:10:29 +0000 Subject: [PATCH 0909/1484] Update test/trace3.test to account for the fact that casting a pointer to a 64-bit signed integer might produce a negative value. FossilOrigin-Name: 010ec22541a4c37f2d3b01b6a531b4b4264102b7 --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/trace3.test | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index e34c16e506..a4d49600bc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Corrections\sto\sLemon\sdocumentation.\s\sNo\sSQLite\schanges. -D 2016-10-08T13:34:08.299 +C Update\stest/trace3.test\sto\saccount\sfor\sthe\sfact\sthat\scasting\sa\spointer\sto\sa\s64-bit\ssigned\sinteger\smight\sproduce\sa\snegative\svalue. +D 2016-10-08T16:10:29.189 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -1302,7 +1302,7 @@ F test/tokenize.test ce430a7aed48fc98301611429595883fdfcab5d7 F test/tpch01.test 04adbf8d8300fa60a222f28d901abd76e7be6dd4 F test/trace.test 6f676313e3ebd2a50585036d2f212a3319dd5836 F test/trace2.test f5cb67ad3bc09e0c58e8cca78dfd0b5639259983 -F test/trace3.test 01e4111d582c7b20ab1c63156169157d256bc3d5 +F test/trace3.test 56ab944fddacf628b118cc298503fc45c2e50ab0 F test/trans.test 6e1b4c6a42dba31bd65f8fa5e61a2708e08ddde6 F test/trans2.test 62bd045bfc7a1c14c5ba83ba64d21ade31583f76 F test/trans3.test 91a100e5412b488e22a655fe423a14c26403ab94 @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P cbed3d75cf9a24037263d126727db7dd048a4f97 -R 32fe7082776be1c5e19835aad8801e28 -U drh -Z 8f596491c82d3cdf69733967abe08530 +P c568ae3eef31b49e846fad90e705914e2868a09c +R 9e5920de6f4128afcff04c7e6fedd0d4 +U dan +Z 56894571560057d40d60b3ac68f2d6e1 diff --git a/manifest.uuid b/manifest.uuid index 044fdcb277..d8b46749d7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c568ae3eef31b49e846fad90e705914e2868a09c \ No newline at end of file +010ec22541a4c37f2d3b01b6a531b4b4264102b7 \ No newline at end of file diff --git a/test/trace3.test b/test/trace3.test index 0809759d80..271009a3fc 100644 --- a/test/trace3.test +++ b/test/trace3.test @@ -128,7 +128,7 @@ do_test trace3-5.1 { SELECT a, b FROM t1 ORDER BY a; } set ::stmtlist(record) -} "/^[string trim [string repeat {\d+ } 16]]\$/" +} "/^[string trim [string repeat {-?\d+ } 16]]\$/" do_test trace3-5.2 { set ::stmtlist(record) {} db trace_v2 trace_v2_record 4 @@ -136,7 +136,7 @@ do_test trace3-5.2 { SELECT a, b FROM t1 ORDER BY a; } set ::stmtlist(record) -} "/^[string trim [string repeat {\d+ } 16]]\$/" +} "/^[string trim [string repeat {-?\d+ } 16]]\$/" do_test trace3-6.1 { set ::stmtlist(record) {} From ea5e5f0b8923abf1bf29065001d718f61fa7bc5e Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 10 Oct 2016 10:06:59 +0000 Subject: [PATCH 0910/1484] Fix a case in which the rtree module was ignoring an OOM while generating an error message. FossilOrigin-Name: 788f86bebe413b5a0ab41ba3d75ba8728827a964 --- ext/rtree/rtree.c | 8 +++++--- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/ext/rtree/rtree.c b/ext/rtree/rtree.c index 2301e6816f..c7de6ac123 100644 --- a/ext/rtree/rtree.c +++ b/ext/rtree/rtree.c @@ -3012,10 +3012,12 @@ static int rtreeQueryStat1(sqlite3 *db, Rtree *pRtree){ int rc; i64 nRow = 0; - if( sqlite3_table_column_metadata(db,pRtree->zDb,"sqlite_stat1", - 0,0,0,0,0,0)==SQLITE_ERROR ){ + rc = sqlite3_table_column_metadata( + db, pRtree->zDb, "sqlite_stat1",0,0,0,0,0,0 + ); + if( rc!=SQLITE_OK ){ pRtree->nRowEst = RTREE_DEFAULT_ROWEST; - return SQLITE_OK; + return rc==SQLITE_ERROR ? SQLITE_OK : rc; } zSql = sqlite3_mprintf(zFmt, pRtree->zDb, pRtree->zName); if( zSql==0 ){ diff --git a/manifest b/manifest index a4d49600bc..1c83b5d527 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\stest/trace3.test\sto\saccount\sfor\sthe\sfact\sthat\scasting\sa\spointer\sto\sa\s64-bit\ssigned\sinteger\smight\sproduce\sa\snegative\svalue. -D 2016-10-08T16:10:29.189 +C Fix\sa\scase\sin\swhich\sthe\srtree\smodule\swas\signoring\san\sOOM\swhile\sgenerating\san\serror\smessage. +D 2016-10-10T10:06:59.217 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -259,7 +259,7 @@ F ext/rbu/sqlite3rbu.c e074c38798b90591f7f0cf0032d62f152ce5a95e F ext/rbu/sqlite3rbu.h 6fb6294c34a9ca93b5894a33bca530c6f08decba F ext/rbu/test_rbu.c 5aa22616afac6f71ebd3d9bc9bf1006cfabcca88 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 -F ext/rtree/rtree.c 0b450226001c8ae4622e382b2aff79127581a763 +F ext/rtree/rtree.c 078fc27417b48aaebe988621bf96ef0e1645b201 F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e F ext/rtree/rtree1.test 42dadfc7b44a436cd74a1bebc0b9b689e4eaf7ec F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P c568ae3eef31b49e846fad90e705914e2868a09c -R 9e5920de6f4128afcff04c7e6fedd0d4 +P 010ec22541a4c37f2d3b01b6a531b4b4264102b7 +R 77f705f1e0cdd507ef3a0aa0a78fee02 U dan -Z 56894571560057d40d60b3ac68f2d6e1 +Z e4f9aa06315af4c14cd5c8e66a421664 diff --git a/manifest.uuid b/manifest.uuid index d8b46749d7..8ea56b44f7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -010ec22541a4c37f2d3b01b6a531b4b4264102b7 \ No newline at end of file +788f86bebe413b5a0ab41ba3d75ba8728827a964 \ No newline at end of file From 48590fcb37f6fba73a4eaaf1c234a37e971b91fb Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 10 Oct 2016 13:29:15 +0000 Subject: [PATCH 0911/1484] Make sure indexes on expressions skip over initial NULL values in the index. Fix for ticket [4baa464912129477f3c9] FossilOrigin-Name: 71797ba431085f9ae381ed5ea6471967926f4043 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/wherecode.c | 10 +++++----- test/indexexpr1.test | 16 ++++++++++++++++ 4 files changed, 30 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index 1c83b5d527..4745f802cb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\scase\sin\swhich\sthe\srtree\smodule\swas\signoring\san\sOOM\swhile\sgenerating\san\serror\smessage. -D 2016-10-10T10:06:59.217 +C Make\ssure\sindexes\son\sexpressions\sskip\sover\sinitial\sNULL\svalues\sin\sthe\nindex.\s\sFix\sfor\sticket\s[4baa464912129477f3c9] +D 2016-10-10T13:29:15.581 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -469,7 +469,7 @@ F src/wal.h 6dd221ed384afdc204bc61e25c23ef7fd5a511f2 F src/walker.c 91a6df7435827e41cff6bb7df50ea00934ee78b0 F src/where.c a2269d2df19d0e98717e163efaea8d1b532dfce4 F src/whereInt.h 2bcc3d176e6091cb8f50a30b65c006e88a73614d -F src/wherecode.c d07f784cda9d51eb04f086171a67eadda17f963f +F src/wherecode.c 717a65294df46f30e9b9933d2a63a4bcbca5a9a8 F src/whereexpr.c 379d0017fb7bc9e5a4d8cd4b056c747de946430e F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -852,7 +852,7 @@ F test/index6.test b4fc812290067a578b98bb2667b676db89e202a7 F test/index7.test 7feababe16f2091b229c22aff2bcc1d4d6b9d2bb F test/index8.test bc2e3db70e8e62459aaa1bd7e4a9b39664f8f9d7 F test/indexedby.test 9c4cd331224e57f79fbf411ae245e6272d415985 -F test/indexexpr1.test cb71b6586177b840e28110dd952178bb2bdfedc2 +F test/indexexpr1.test 28a82b3ed15127b18eed7d71f548f84e3c8161c9 F test/indexfault.test 31d4ab9a7d2f6e9616933eb079722362a883eb1d F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7 F test/insert.test 38742b5e9601c8f8d76e9b7555f7270288c2d371 @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 010ec22541a4c37f2d3b01b6a531b4b4264102b7 -R 77f705f1e0cdd507ef3a0aa0a78fee02 -U dan -Z e4f9aa06315af4c14cd5c8e66a421664 +P 788f86bebe413b5a0ab41ba3d75ba8728827a964 +R 4e30116e3ed090b4bf1fd06f3d023297 +U drh +Z 1a6f4c734753d210e419c3f7e49c53f1 diff --git a/manifest.uuid b/manifest.uuid index 8ea56b44f7..79583a19b6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -788f86bebe413b5a0ab41ba3d75ba8728827a964 \ No newline at end of file +71797ba431085f9ae381ed5ea6471967926f4043 \ No newline at end of file diff --git a/src/wherecode.c b/src/wherecode.c index a244a303a6..c095ce7c87 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -1446,11 +1446,11 @@ Bitmask sqlite3WhereCodeOneLoopStart( pLevel->iLikeRepCntr |= bRev ^ (pIdx->aSortOrder[nEq]==SQLITE_SO_DESC); } #endif - if( pRangeStart==0 - && (j = pIdx->aiColumn[nEq])>=0 - && pIdx->pTable->aCol[j].notNull==0 - ){ - bSeekPastNull = 1; + if( pRangeStart==0 ){ + j = pIdx->aiColumn[nEq]; + if( (j>=0 && pIdx->pTable->aCol[j].notNull==0) || j==XN_EXPR ){ + bSeekPastNull = 1; + } } } assert( pRangeEnd==0 || (pRangeEnd->wtFlags & TERM_VNULL)==0 ); diff --git a/test/indexexpr1.test b/test/indexexpr1.test index a8a74f259e..1737e25ea2 100644 --- a/test/indexexpr1.test +++ b/test/indexexpr1.test @@ -323,5 +323,21 @@ do_execsql_test indexexpr1-1010 { SELECT *, '|' FROM t0 ORDER BY +a; } {0 88 2 | 2 99 4 | 5 99 7 |} +# 2016-10-10 +# Make sure indexes on expressions skip over initial NULL values in the +# index as they are suppose to do. +# Ticket https://www.sqlite.org/src/tktview/4baa46491212947 +# +do_execsql_test indexexpr1-1100 { + DROP TABLE IF EXISTS t1; + CREATE TABLE t1(a); + INSERT INTO t1 VALUES(NULL),(1); + SELECT '1:', typeof(a), a FROM t1 WHERE a<10; + SELECT '2:', typeof(a), a FROM t1 WHERE a+0<10; + CREATE INDEX t1x1 ON t1(a); + CREATE INDEX t1x2 ON t1(a+0); + SELECT '3:', typeof(a), a FROM t1 WHERE a<10; + SELECT '4:', typeof(a), a FROM t1 WHERE a+0<10; +} {1: integer 1 2: integer 1 3: integer 1 4: integer 1} finish_test From 90b2fe6b1ea1a7f0d4064290462f0a6106c3b327 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 10 Oct 2016 14:34:00 +0000 Subject: [PATCH 0912/1484] When handling ORDER BY expressions, do not assume all values of an indexed expressions are distinct. Fix for [4766f444]. FossilOrigin-Name: aebe429e52ffef026cb0803fb164339d61bd2e88 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/where.c | 2 +- test/indexexpr1.test | 30 ++++++++++++++++++++++++++++++ 4 files changed, 40 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 4745f802cb..fe7d790eb4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\ssure\sindexes\son\sexpressions\sskip\sover\sinitial\sNULL\svalues\sin\sthe\nindex.\s\sFix\sfor\sticket\s[4baa464912129477f3c9] -D 2016-10-10T13:29:15.581 +C When\shandling\sORDER\sBY\sexpressions,\sdo\snot\sassume\sall\svalues\sof\san\sindexed\sexpressions\sare\sdistinct.\sFix\sfor\s[4766f444]. +D 2016-10-10T14:34:00.108 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -467,7 +467,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 02eeecc265f6ffd0597378f5d8ae9070b62a406a F src/wal.h 6dd221ed384afdc204bc61e25c23ef7fd5a511f2 F src/walker.c 91a6df7435827e41cff6bb7df50ea00934ee78b0 -F src/where.c a2269d2df19d0e98717e163efaea8d1b532dfce4 +F src/where.c 43b53ef361d1b01002376eff5d33de0898f4dd94 F src/whereInt.h 2bcc3d176e6091cb8f50a30b65c006e88a73614d F src/wherecode.c 717a65294df46f30e9b9933d2a63a4bcbca5a9a8 F src/whereexpr.c 379d0017fb7bc9e5a4d8cd4b056c747de946430e @@ -852,7 +852,7 @@ F test/index6.test b4fc812290067a578b98bb2667b676db89e202a7 F test/index7.test 7feababe16f2091b229c22aff2bcc1d4d6b9d2bb F test/index8.test bc2e3db70e8e62459aaa1bd7e4a9b39664f8f9d7 F test/indexedby.test 9c4cd331224e57f79fbf411ae245e6272d415985 -F test/indexexpr1.test 28a82b3ed15127b18eed7d71f548f84e3c8161c9 +F test/indexexpr1.test 7d243fac508b4a99fb900ffe34eb488312cfce84 F test/indexfault.test 31d4ab9a7d2f6e9616933eb079722362a883eb1d F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7 F test/insert.test 38742b5e9601c8f8d76e9b7555f7270288c2d371 @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 788f86bebe413b5a0ab41ba3d75ba8728827a964 -R 4e30116e3ed090b4bf1fd06f3d023297 -U drh -Z 1a6f4c734753d210e419c3f7e49c53f1 +P 71797ba431085f9ae381ed5ea6471967926f4043 +R eb83b0ec6e44fd9a4ddc7d39014a988d +U dan +Z e53885d9c26ab892c301951bca3836f9 diff --git a/manifest.uuid b/manifest.uuid index 79583a19b6..42bdf45b1d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -71797ba431085f9ae381ed5ea6471967926f4043 \ No newline at end of file +aebe429e52ffef026cb0803fb164339d61bd2e88 \ No newline at end of file diff --git a/src/where.c b/src/where.c index cccf2c47f4..ca5d90a46d 100644 --- a/src/where.c +++ b/src/where.c @@ -3669,7 +3669,7 @@ static i8 wherePathSatisfiesOrderBy( } } if( isMatch ){ - if( iColumn<0 ){ + if( iColumn==XN_ROWID ){ testcase( distinctColumns==0 ); distinctColumns = 1; } diff --git a/test/indexexpr1.test b/test/indexexpr1.test index 1737e25ea2..cd72430d91 100644 --- a/test/indexexpr1.test +++ b/test/indexexpr1.test @@ -340,4 +340,34 @@ do_execsql_test indexexpr1-1100 { SELECT '4:', typeof(a), a FROM t1 WHERE a+0<10; } {1: integer 1 2: integer 1 3: integer 1 4: integer 1} +do_execsql_test indexexpr1-1200 { + CREATE TABLE t10(a int, b int, c int, d int); + INSERT INTO t10(a, b, c, d) VALUES(0, 0, 2, 2); + INSERT INTO t10(a, b, c, d) VALUES(0, 0, 0, 0); + INSERT INTO t10(a, b, c, d) VALUES(0, 0, 1, 1); + INSERT INTO t10(a, b, c, d) VALUES(1, 1, 1, 1); + INSERT INTO t10(a, b, c, d) VALUES(1, 1, 0, 0); + INSERT INTO t10(a, b, c, d) VALUES(2, 2, 0, 0); + + SELECT a+b, c+d FROM t10 ORDER BY a+b, c+d; +} { + 0 0 0 2 0 4 2 0 2 2 4 0 +} +do_execsql_test indexexpr1-1200.1 { + CREATE INDEX t10_ab ON t10(a+b); +} +do_execsql_test indexexpr1-1200.2 { + SELECT a+b, c+d FROM t10 ORDER BY a+b, c+d; +} { + 0 0 0 2 0 4 2 0 2 2 4 0 +} +do_execsql_test indexexpr1-1200.3 { + CREATE INDEX t10_abcd ON t10(a+b,c+d); +} +do_execsql_test indexexpr1-1200.4 { + SELECT a+b, c+d FROM t10 ORDER BY a+b, c+d; +} { + 0 0 0 2 0 4 2 0 2 2 4 0 +} + finish_test From ef74652ceb5a96859fe66e1b7d5668ae4f344e3e Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 10 Oct 2016 14:48:36 +0000 Subject: [PATCH 0913/1484] Remove a stray line from session4.test causing a memory leak. No changes to SQLite code. FossilOrigin-Name: 6624c4964b63e259d5ee006eaa7ec79ddadbd6a6 --- ext/session/session4.test | 1 - manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/ext/session/session4.test b/ext/session/session4.test index 8e179baf6d..120a230b57 100644 --- a/ext/session/session4.test +++ b/ext/session/session4.test @@ -30,7 +30,6 @@ do_test 1.0 { INSERT INTO x VALUES(19, 'domains', 'espouse', -94, 'throw'); } - sqlite3session S db main set changeset [changeset_from_sql { DELETE FROM x WHERE e = -66; UPDATE x SET a = 'parameterizable', b = 31.8 WHERE c = 35; diff --git a/manifest b/manifest index fe7d790eb4..a0fdfeea9d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C When\shandling\sORDER\sBY\sexpressions,\sdo\snot\sassume\sall\svalues\sof\san\sindexed\sexpressions\sare\sdistinct.\sFix\sfor\s[4766f444]. -D 2016-10-10T14:34:00.108 +C Remove\sa\sstray\sline\sfrom\ssession4.test\scausing\sa\smemory\sleak.\sNo\schanges\sto\sSQLite\scode. +D 2016-10-10T14:48:36.237 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -286,7 +286,7 @@ F ext/session/changeset.c 4ccbaa4531944c24584bf6a61ba3a39c62b6267a F ext/session/session1.test 98f384736e2bc21ccf5ed81bdadcff4ad863393b F ext/session/session2.test 284de45abae4cc1082bc52012ee81521d5ac58e0 F ext/session/session3.test a7a9ce59b8d1e49e2cc23d81421ac485be0eea01 -F ext/session/session4.test a6ed685da7a5293c5d6f99855bcf41dbc352ca84 +F ext/session/session4.test 457b02bdc349eb01151e54de014df77abd3c08c8 F ext/session/session5.test 716bc6fafd625ce60dfa62ae128971628c1a1169 F ext/session/session6.test 443789bc2fca12e4f7075cf692c60b8a2bea1a26 F ext/session/session8.test 8e194b3f655d861ca36de5d4de53f702751bab3b @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 71797ba431085f9ae381ed5ea6471967926f4043 -R eb83b0ec6e44fd9a4ddc7d39014a988d +P aebe429e52ffef026cb0803fb164339d61bd2e88 +R bc8709bbb1b64b0bd83c97caf5c75201 U dan -Z e53885d9c26ab892c301951bca3836f9 +Z 9c65308e5e48a1f51d309ce5e485020a diff --git a/manifest.uuid b/manifest.uuid index 42bdf45b1d..1b3b44d8a6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -aebe429e52ffef026cb0803fb164339d61bd2e88 \ No newline at end of file +6624c4964b63e259d5ee006eaa7ec79ddadbd6a6 \ No newline at end of file From 83465a662fa4537d67bfce29ef6f08e2d590297e Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 12 Oct 2016 14:48:00 +0000 Subject: [PATCH 0914/1484] Fix a problem affecting queries that match the pattern (... WHERE ipk IN (....) ORDER BY ? LIMIT ?). Fix for [96c1454c]. FossilOrigin-Name: 8e2b25f9b8a7ed087d3cece74239814bee19429e --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/where.c | 5 ++++- test/limit2.test | 30 ++++++++++++++++++++++++++++++ 4 files changed, 42 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index a0fdfeea9d..9ba1c299d4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sa\sstray\sline\sfrom\ssession4.test\scausing\sa\smemory\sleak.\sNo\schanges\sto\sSQLite\scode. -D 2016-10-10T14:48:36.237 +C Fix\sa\sproblem\saffecting\squeries\sthat\smatch\sthe\spattern\s(...\sWHERE\sipk\sIN\s(....)\sORDER\sBY\s?\sLIMIT\s?).\sFix\sfor\s[96c1454c]. +D 2016-10-12T14:48:00.157 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -467,7 +467,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 02eeecc265f6ffd0597378f5d8ae9070b62a406a F src/wal.h 6dd221ed384afdc204bc61e25c23ef7fd5a511f2 F src/walker.c 91a6df7435827e41cff6bb7df50ea00934ee78b0 -F src/where.c 43b53ef361d1b01002376eff5d33de0898f4dd94 +F src/where.c 1398bc4921aeb834dae464735c38dd658e075f74 F src/whereInt.h 2bcc3d176e6091cb8f50a30b65c006e88a73614d F src/wherecode.c 717a65294df46f30e9b9933d2a63a4bcbca5a9a8 F src/whereexpr.c 379d0017fb7bc9e5a4d8cd4b056c747de946430e @@ -893,7 +893,7 @@ F test/like.test 81632c437a947bf1f7130b19537da6a1a844806a F test/like2.test 3b2ee13149ba4a8a60b59756f4e5d345573852da F test/like3.test 3608a2042b6f922f900fbfd5d3ce4e7eca57f7c4 F test/limit.test 0c99a27a87b14c646a9d583c7c89fd06c352663e -F test/limit2.test 7e7744cc548d7e4c92e1dd3edc30dd0f86adafd5 +F test/limit2.test e35f57bd3a62d7c5dcb5ac4306e675c75f974809 F test/loadext.test d077450695ddb5c1ea3ad7d48e5f5850fe732ad9 F test/loadext2.test 0408380b57adca04004247179837a18e866a74f7 F test/lock.test be4fe08118fb988fed741f429b7dd5d65e1c90db @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P aebe429e52ffef026cb0803fb164339d61bd2e88 -R bc8709bbb1b64b0bd83c97caf5c75201 +P 6624c4964b63e259d5ee006eaa7ec79ddadbd6a6 +R 1f3479e07ee809d93ee626f741dcfe99 U dan -Z 9c65308e5e48a1f51d309ce5e485020a +Z 2f5dc1d3c0a42075b0dbac13eca4ba40 diff --git a/manifest.uuid b/manifest.uuid index 1b3b44d8a6..c907c3628b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6624c4964b63e259d5ee006eaa7ec79ddadbd6a6 \ No newline at end of file +8e2b25f9b8a7ed087d3cece74239814bee19429e \ No newline at end of file diff --git a/src/where.c b/src/where.c index ca5d90a46d..5c824b96ab 100644 --- a/src/where.c +++ b/src/where.c @@ -4123,8 +4123,11 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ pWInfo->nOBSat = pFrom->isOrdered; pWInfo->revMask = pFrom->revLoop; if( pWInfo->nOBSat<=0 ){ + u32 wsFlags = pFrom->aLoop[nLoop-1]->wsFlags; pWInfo->nOBSat = 0; - if( nLoop>0 && (pFrom->aLoop[nLoop-1]->wsFlags & WHERE_ONEROW)==0 ){ + if( nLoop>0 && (wsFlags & WHERE_ONEROW)==0 + && (wsFlags & (WHERE_IPK|WHERE_COLUMN_IN))!=(WHERE_IPK|WHERE_COLUMN_IN) + ){ Bitmask m = 0; int rc = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pOrderBy, pFrom, WHERE_ORDERBY_LIMIT, nLoop-1, pFrom->aLoop[nLoop-1], &m); diff --git a/test/limit2.test b/test/limit2.test index 4d03180729..f6eaefb8aa 100644 --- a/test/limit2.test +++ b/test/limit2.test @@ -17,6 +17,7 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl +set testprefix limit2 do_execsql_test limit2-100 { CREATE TABLE t1(a,b); @@ -120,4 +121,33 @@ do_execsql_test limit2-400 { SELECT *,'y' FROM t400 WHERE a IN (1,2,3) ORDER BY +b DESC LIMIT 3; } {1 90 x 2 80 x 3 70 x 1 90 y 2 80 y 3 70 y} + +do_execsql_test 500 { + CREATE TABLE t500(i INTEGER PRIMARY KEY, j); + INSERT INTO t500 VALUES(1, 1); + INSERT INTO t500 VALUES(2, 2); + INSERT INTO t500 VALUES(3, 3); + INSERT INTO t500 VALUES(4, 0); + INSERT INTO t500 VALUES(5, 5); + SELECT j FROM t500 WHERE i IN (1,2,3,4,5) ORDER BY j DESC LIMIT 3; +} {5 3 2} +do_execsql_test 501 { + CREATE TABLE t501(i INTEGER PRIMARY KEY, j); + INSERT INTO t501 VALUES(1, 5); + INSERT INTO t501 VALUES(2, 4); + INSERT INTO t501 VALUES(3, 3); + INSERT INTO t501 VALUES(4, 6); + INSERT INTO t501 VALUES(5, 1); + SELECT j FROM t501 WHERE i IN (1,2,3,4,5) ORDER BY j LIMIT 3; +} {1 3 4} +do_execsql_test 502 { + CREATE TABLE t502(i INT PRIMARY KEY, j); + INSERT INTO t502 VALUES(1, 5); + INSERT INTO t502 VALUES(2, 4); + INSERT INTO t502 VALUES(3, 3); + INSERT INTO t502 VALUES(4, 6); + INSERT INTO t502 VALUES(5, 1); + SELECT j FROM t502 WHERE i IN (1,2,3,4,5) ORDER BY j LIMIT 3; +} {1 3 4} + finish_test From 013ae68b25d785b4ed0d09b4e163c4713567c345 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 12 Oct 2016 15:15:30 +0000 Subject: [PATCH 0915/1484] New testcase() macros to ensure coverage of the ORDER BY LIMIT optimization code in where.c. FossilOrigin-Name: 61f0526978af667781c57bcc87510e4524efd0d8 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/where.c | 2 ++ 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 9ba1c299d4..e13f42949f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\saffecting\squeries\sthat\smatch\sthe\spattern\s(...\sWHERE\sipk\sIN\s(....)\sORDER\sBY\s?\sLIMIT\s?).\sFix\sfor\s[96c1454c]. -D 2016-10-12T14:48:00.157 +C New\stestcase()\smacros\sto\sensure\scoverage\sof\sthe\sORDER\sBY\sLIMIT\soptimization\ncode\sin\swhere.c. +D 2016-10-12T15:15:30.391 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -467,7 +467,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 02eeecc265f6ffd0597378f5d8ae9070b62a406a F src/wal.h 6dd221ed384afdc204bc61e25c23ef7fd5a511f2 F src/walker.c 91a6df7435827e41cff6bb7df50ea00934ee78b0 -F src/where.c 1398bc4921aeb834dae464735c38dd658e075f74 +F src/where.c 7e454887a70a8263f663eab8c9d0f6ecc8ec7ac7 F src/whereInt.h 2bcc3d176e6091cb8f50a30b65c006e88a73614d F src/wherecode.c 717a65294df46f30e9b9933d2a63a4bcbca5a9a8 F src/whereexpr.c 379d0017fb7bc9e5a4d8cd4b056c747de946430e @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 6624c4964b63e259d5ee006eaa7ec79ddadbd6a6 -R 1f3479e07ee809d93ee626f741dcfe99 -U dan -Z 2f5dc1d3c0a42075b0dbac13eca4ba40 +P 8e2b25f9b8a7ed087d3cece74239814bee19429e +R 85b771c181ab2a587da3b9154662733d +U drh +Z ed0e3333d86697e18712f68be162b390 diff --git a/manifest.uuid b/manifest.uuid index c907c3628b..704a1a0c21 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8e2b25f9b8a7ed087d3cece74239814bee19429e \ No newline at end of file +61f0526978af667781c57bcc87510e4524efd0d8 \ No newline at end of file diff --git a/src/where.c b/src/where.c index 5c824b96ab..443e9ea82d 100644 --- a/src/where.c +++ b/src/where.c @@ -4131,6 +4131,8 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ Bitmask m = 0; int rc = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pOrderBy, pFrom, WHERE_ORDERBY_LIMIT, nLoop-1, pFrom->aLoop[nLoop-1], &m); + testcase( wsFlags & WHERE_IPK ); + testcase( wsFlags & WHERE_COLUMN_IN ); if( rc==pWInfo->pOrderBy->nExpr ){ pWInfo->bOrderedInnerLoop = 1; pWInfo->revMask = m; From 432697467f03f10800f4cf8e04752004a1e75182 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 12 Oct 2016 18:26:26 +0000 Subject: [PATCH 0916/1484] Add to sqlite3_analyzer command-line options --version and --tclsh, and also the undocumented --debug option. FossilOrigin-Name: e87d02d289a2016ea3ee074e914b07a8ac22b21f --- manifest | 12 +++++----- manifest.uuid | 2 +- tool/spaceanal.tcl | 57 +++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 61 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index e13f42949f..241e0db8a7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C New\stestcase()\smacros\sto\sensure\scoverage\sof\sthe\sORDER\sBY\sLIMIT\soptimization\ncode\sin\swhere.c. -D 2016-10-12T15:15:30.391 +C Add\sto\ssqlite3_analyzer\scommand-line\soptions\s--version\sand\s--tclsh,\sand\salso\nthe\sundocumented\s--debug\soption. +D 2016-10-12T18:26:26.364 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -1484,7 +1484,7 @@ F tool/showlocks.c 9920bcc64f58378ff1118caead34147201f48c68 F tool/showstat4.c bda40d6e395df7edb6e9ea630784d3d762c35b4b F tool/showwal.c ec79959834f7b21f1e0a2aa52bb7c056d2203977 F tool/soak1.tcl 8d407956e1a45b485a8e072470a3e629a27037fe -F tool/spaceanal.tcl 85d90e6674d8298e3eaf82dbcef3abc2d5317f3e +F tool/spaceanal.tcl ab7d9bf68062907282a64b3e12ccbfad47193c5a F tool/speed-check.sh da6ce45957c509ba6343fe3fef167e7e2b306262 F tool/speedtest.tcl 06c76698485ccf597b9e7dbb1ac70706eb873355 F tool/speedtest16.c ecb6542862151c3e6509bbc00509b234562ae81e @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 8e2b25f9b8a7ed087d3cece74239814bee19429e -R 85b771c181ab2a587da3b9154662733d +P 61f0526978af667781c57bcc87510e4524efd0d8 +R 939be1793993bb5a0733cfe788e02f4d U drh -Z ed0e3333d86697e18712f68be162b390 +Z 3046f41ed5ee9baf8f6c825aaff1459e diff --git a/manifest.uuid b/manifest.uuid index 704a1a0c21..ceae9890fc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -61f0526978af667781c57bcc87510e4524efd0d8 \ No newline at end of file +e87d02d289a2016ea3ee074e914b07a8ac22b21f \ No newline at end of file diff --git a/tool/spaceanal.tcl b/tool/spaceanal.tcl index eef1192a1d..e7ce846f86 100644 --- a/tool/spaceanal.tcl +++ b/tool/spaceanal.tcl @@ -22,6 +22,33 @@ proc is_without_rowid {tname} { return 0 } +# Read and run TCL commands from standard input. Used to implement +# the --tclsh option. +# +proc tclsh {} { + set line {} + while {![eof stdin]} { + if {$line!=""} { + puts -nonewline "> " + } else { + puts -nonewline "% " + } + flush stdout + append line [gets stdin] + if {[info complete $line]} { + if {[catch {uplevel #0 $line} result]} { + puts stderr "Error: $result" + } elseif {$result!=""} { + puts $result + } + set line {} + } else { + append line \n + } + } +} + + # Get the name of the database to analyze # proc usage {} { @@ -34,22 +61,37 @@ information for the database and its constituent tables and indexes. Options: - --stats Output SQL text that creates a new database containing - statistics about the database that was analyzed + --pageinfo Show how each page of the database-file is used - --pageinfo Show how each page of the database-file is used + --stats Output SQL text that creates a new database containing + statistics about the database that was analyzed + + --tclsh Run the built-in TCL interpreter interactively (for debugging) + + --version Show the version number of SQLite } exit 1 } set file_to_analyze {} set flags(-pageinfo) 0 set flags(-stats) 0 +set flags(-debug) 0 append argv {} foreach arg $argv { if {[regexp {^-+pageinfo$} $arg]} { set flags(-pageinfo) 1 } elseif {[regexp {^-+stats$} $arg]} { set flags(-stats) 1 + } elseif {[regexp {^-+debug$} $arg]} { + set flags(-debug) 1 + } elseif {[regexp {^-+tclsh$} $arg]} { + tclsh + exit 0 + } elseif {[regexp {^-+version$} $arg]} { + sqlite3 mem :memory: + puts [mem one {SELECT sqlite_version()||' '||sqlite_source_id()}] + mem close + exit 0 } elseif {[regexp {^-} $arg]} { puts stderr "Unknown option: $arg" usage @@ -100,6 +142,10 @@ if {[catch {sqlite3 db $file_to_analyze -uri 1} msg]} { puts stderr "error trying to open $file_to_analyze: $msg" exit 1 } +if {$flags(-debug)} { + proc dbtrace {txt} {puts $txt; flush stdout;} + db trace ::dbtrace +} db eval {SELECT count(*) FROM sqlite_master} set pageSize [expr {wide([db one {PRAGMA page_size}])}] @@ -142,12 +188,17 @@ if {$flags(-stats)} { exit 0 } + # In-memory database for collecting statistics. This script loops through # the tables and indices in the database being analyzed, adding a row for each # to an in-memory database (for which the schema is shown below). It then # queries the in-memory db to produce the space-analysis report. # sqlite3 mem :memory: +if {$flags(-debug)} { + proc dbtrace {txt} {puts $txt; flush stdout;} + mem trace ::dbtrace +} set tabledef {CREATE TABLE space_used( name clob, -- Name of a table or index in the database file tblname clob, -- Name of associated table From c436a03d027f27d33f6ba5a95724b0a9c4e814e9 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 12 Oct 2016 18:55:53 +0000 Subject: [PATCH 0917/1484] Avoid reading the -1-th element of an array in the query planner. Fix to a bug introduced by check-in [8e2b25f9b8a7] from earlier today. Curiously, the problem only appeared on 32-bit systems. FossilOrigin-Name: 443913d582bcd953d85159047541592e2f68ade3 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/where.c | 24 +++++++++++++----------- 3 files changed, 20 insertions(+), 18 deletions(-) diff --git a/manifest b/manifest index 241e0db8a7..9719134aaa 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sto\ssqlite3_analyzer\scommand-line\soptions\s--version\sand\s--tclsh,\sand\salso\nthe\sundocumented\s--debug\soption. -D 2016-10-12T18:26:26.364 +C Avoid\sreading\sthe\s-1-th\selement\sof\san\sarray\sin\sthe\squery\splanner.\s\sFix\sto\sa\nbug\sintroduced\sby\scheck-in\s[8e2b25f9b8a7]\sfrom\searlier\stoday.\s\sCuriously,\nthe\sproblem\sonly\sappeared\son\s32-bit\ssystems. +D 2016-10-12T18:55:53.185 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -467,7 +467,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 02eeecc265f6ffd0597378f5d8ae9070b62a406a F src/wal.h 6dd221ed384afdc204bc61e25c23ef7fd5a511f2 F src/walker.c 91a6df7435827e41cff6bb7df50ea00934ee78b0 -F src/where.c 7e454887a70a8263f663eab8c9d0f6ecc8ec7ac7 +F src/where.c 5f846d94bb3d35b3146d9915eb301ee362957b0a F src/whereInt.h 2bcc3d176e6091cb8f50a30b65c006e88a73614d F src/wherecode.c 717a65294df46f30e9b9933d2a63a4bcbca5a9a8 F src/whereexpr.c 379d0017fb7bc9e5a4d8cd4b056c747de946430e @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 61f0526978af667781c57bcc87510e4524efd0d8 -R 939be1793993bb5a0733cfe788e02f4d +P e87d02d289a2016ea3ee074e914b07a8ac22b21f +R 347ceac05d5e830be9b0b453b9055752 U drh -Z 3046f41ed5ee9baf8f6c825aaff1459e +Z f6a48b076f4d91846fe2072e2532d39d diff --git a/manifest.uuid b/manifest.uuid index ceae9890fc..f1cc7550cb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e87d02d289a2016ea3ee074e914b07a8ac22b21f \ No newline at end of file +443913d582bcd953d85159047541592e2f68ade3 \ No newline at end of file diff --git a/src/where.c b/src/where.c index 443e9ea82d..c75eb943f3 100644 --- a/src/where.c +++ b/src/where.c @@ -4123,19 +4123,21 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ pWInfo->nOBSat = pFrom->isOrdered; pWInfo->revMask = pFrom->revLoop; if( pWInfo->nOBSat<=0 ){ - u32 wsFlags = pFrom->aLoop[nLoop-1]->wsFlags; pWInfo->nOBSat = 0; - if( nLoop>0 && (wsFlags & WHERE_ONEROW)==0 - && (wsFlags & (WHERE_IPK|WHERE_COLUMN_IN))!=(WHERE_IPK|WHERE_COLUMN_IN) - ){ - Bitmask m = 0; - int rc = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pOrderBy, pFrom, + if( nLoop>0 ){ + u32 wsFlags = pFrom->aLoop[nLoop-1]->wsFlags; + if( (wsFlags & WHERE_ONEROW)==0 + && (wsFlags&(WHERE_IPK|WHERE_COLUMN_IN))!=(WHERE_IPK|WHERE_COLUMN_IN) + ){ + Bitmask m = 0; + int rc = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pOrderBy, pFrom, WHERE_ORDERBY_LIMIT, nLoop-1, pFrom->aLoop[nLoop-1], &m); - testcase( wsFlags & WHERE_IPK ); - testcase( wsFlags & WHERE_COLUMN_IN ); - if( rc==pWInfo->pOrderBy->nExpr ){ - pWInfo->bOrderedInnerLoop = 1; - pWInfo->revMask = m; + testcase( wsFlags & WHERE_IPK ); + testcase( wsFlags & WHERE_COLUMN_IN ); + if( rc==pWInfo->pOrderBy->nExpr ){ + pWInfo->bOrderedInnerLoop = 1; + pWInfo->revMask = m; + } } } } From 989412a1cf2983e446cc8ae2e5f86895930c0362 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 13 Oct 2016 12:56:18 +0000 Subject: [PATCH 0918/1484] Take care to avoid integer overflow when doing the initial page cache allocation with an excessively large cache_size setting. FossilOrigin-Name: 4d66ac98deaa85218be7ff0eb254f78b96d8e8d4 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/pcache1.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 9719134aaa..6982d57f42 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sreading\sthe\s-1-th\selement\sof\san\sarray\sin\sthe\squery\splanner.\s\sFix\sto\sa\nbug\sintroduced\sby\scheck-in\s[8e2b25f9b8a7]\sfrom\searlier\stoday.\s\sCuriously,\nthe\sproblem\sonly\sappeared\son\s32-bit\ssystems. -D 2016-10-12T18:55:53.185 +C Take\scare\sto\savoid\sinteger\soverflow\swhen\sdoing\sthe\sinitial\spage\scache\nallocation\swith\san\sexcessively\slarge\scache_size\ssetting. +D 2016-10-13T12:56:18.996 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -378,7 +378,7 @@ F src/pager.h 966d2769e76ae347c8a32c4165faf6e6cb64546d F src/parse.y 0338f906b61e311c2b7e11a3f89b0092c780b664 F src/pcache.c 5ff2a08f76a9c1b22f43eb063b7068fb085465ac F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 -F src/pcache1.c 4bb7a6a5300c67d0b033d25adb509c120c03e812 +F src/pcache1.c e3967219b2a92b9edcb9324a4ba75009090d3953 F src/pragma.c d932ba278654617cdd281f88a790a3185fca7c44 F src/pragma.h 64c78a648751b9f4f297276c4eb7507b14b4628c F src/prepare.c b1140c3d0cf59bc85ace00ce363153041b424b7a @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e87d02d289a2016ea3ee074e914b07a8ac22b21f -R 347ceac05d5e830be9b0b453b9055752 +P 443913d582bcd953d85159047541592e2f68ade3 +R a065c821855a0dd84a6e1c87c8d5ef05 U drh -Z f6a48b076f4d91846fe2072e2532d39d +Z fa9255d8df284358f598506788fc36f9 diff --git a/manifest.uuid b/manifest.uuid index f1cc7550cb..b4c3b869ac 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -443913d582bcd953d85159047541592e2f68ade3 \ No newline at end of file +4d66ac98deaa85218be7ff0eb254f78b96d8e8d4 \ No newline at end of file diff --git a/src/pcache1.c b/src/pcache1.c index 1b1971a399..110d7ec656 100644 --- a/src/pcache1.c +++ b/src/pcache1.c @@ -279,7 +279,7 @@ static int pcache1InitBulk(PCache1 *pCache){ szBulk = -1024 * (i64)pcache1.nInitPage; } if( szBulk > pCache->szAlloc*(i64)pCache->nMax ){ - szBulk = pCache->szAlloc*pCache->nMax; + szBulk = pCache->szAlloc*(i64)pCache->nMax; } zBulk = pCache->pBulk = sqlite3Malloc( szBulk ); sqlite3EndBenignMalloc(); From 813646c182aea9ca08d9b57a08b9c1416ce91d73 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 14 Oct 2016 10:20:30 +0000 Subject: [PATCH 0919/1484] Version 3.15.0 FossilOrigin-Name: 707875582fcba352b4906a595ad89198d84711d8 --- manifest | 11 +++++++---- manifest.uuid | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/manifest b/manifest index 6982d57f42..0dd2d2a727 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Take\scare\sto\savoid\sinteger\soverflow\swhen\sdoing\sthe\sinitial\spage\scache\nallocation\swith\san\sexcessively\slarge\scache_size\ssetting. -D 2016-10-13T12:56:18.996 +C Version\s3.15.0 +D 2016-10-14T10:20:30.806 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -1525,7 +1525,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 443913d582bcd953d85159047541592e2f68ade3 +P 4d66ac98deaa85218be7ff0eb254f78b96d8e8d4 R a065c821855a0dd84a6e1c87c8d5ef05 +T +bgcolor * #d0c0ff +T +sym-release * +T +sym-version-3.15.0 * U drh -Z fa9255d8df284358f598506788fc36f9 +Z 64923968438b03dca07652ab710e8b24 diff --git a/manifest.uuid b/manifest.uuid index b4c3b869ac..a715a6572c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4d66ac98deaa85218be7ff0eb254f78b96d8e8d4 \ No newline at end of file +707875582fcba352b4906a595ad89198d84711d8 \ No newline at end of file From 9e31fe02ba775d300fae64b5525271445ea1e719 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 14 Oct 2016 21:16:27 +0000 Subject: [PATCH 0920/1484] Bump the version number in anticipation of the next development cycle. FossilOrigin-Name: aa6de9c40ba2d906772b9032fd5d798661f6d4cc --- VERSION | 2 +- configure | 18 +++++++++--------- manifest | 17 +++++++---------- manifest.uuid | 2 +- 4 files changed, 18 insertions(+), 21 deletions(-) diff --git a/VERSION b/VERSION index f02113fe87..1eeac129c5 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.15.0 +3.16.0 diff --git a/configure b/configure index 75c7a3720d..246b1bc63e 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.15.0. +# Generated by GNU Autoconf 2.69 for sqlite 3.16.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.15.0' -PACKAGE_STRING='sqlite 3.15.0' +PACKAGE_VERSION='3.16.0' +PACKAGE_STRING='sqlite 3.16.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.15.0 to adapt to many kinds of systems. +\`configure' configures sqlite 3.16.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.15.0:";; + short | recursive ) echo "Configuration of sqlite 3.16.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.15.0 +sqlite configure 3.16.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.15.0, which was +It was created by sqlite $as_me 3.16.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.15.0, which was +This file was extended by sqlite $as_me 3.16.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.15.0 +sqlite config.status 3.16.0 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/manifest b/manifest index 0dd2d2a727..23fa28269b 100644 --- a/manifest +++ b/manifest @@ -1,10 +1,10 @@ -C Version\s3.15.0 -D 2016-10-14T10:20:30.806 +C Bump\sthe\sversion\snumber\sin\santicipation\sof\sthe\snext\sdevelopment\scycle. +D 2016-10-14T21:16:27.395 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7 -F VERSION 25e2e333adeff5965520bc8db999c658898c972d +F VERSION 661b3e6a778cfbfd7bdce8bbb1545b22f4b6f09e F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 @@ -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 3f44893bc0e51c30653e02b0fd4dc2ab585e446a x +F configure 1c4248006e233187bed6e6b890befec14f625637 x F configure.ac b5d3df43161374f8dffd2e5f4b88fbb51685b975 F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad F doc/lemon.html b5a3c07d33ecb8e019ce8f7660fe2dbbad9d7977 @@ -1525,10 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 4d66ac98deaa85218be7ff0eb254f78b96d8e8d4 -R a065c821855a0dd84a6e1c87c8d5ef05 -T +bgcolor * #d0c0ff -T +sym-release * -T +sym-version-3.15.0 * +P 707875582fcba352b4906a595ad89198d84711d8 +R 87fa5c02031b01e516917f863b526e7b U drh -Z 64923968438b03dca07652ab710e8b24 +Z b28813ae6ede81ad47c41c9f8f93c9ca diff --git a/manifest.uuid b/manifest.uuid index a715a6572c..0c0e23b425 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -707875582fcba352b4906a595ad89198d84711d8 \ No newline at end of file +aa6de9c40ba2d906772b9032fd5d798661f6d4cc \ No newline at end of file From 1cb3c7c4156f86e27c60ecc1a5c4a71c6a4c4fba Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 15 Oct 2016 08:56:18 +0000 Subject: [PATCH 0921/1484] Add test case to hook.test. No changes to non-test code. FossilOrigin-Name: 2674d779f5453ea6b709a39618d4b8017ab2e3fb --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/hook.test | 6 ++++++ 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index d209a80532..b4e33fd389 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sSQLITE_FCNTL_WIN32_GET_HANDLE\sfile\scontrol. -D 2016-10-14T21:27:50.450 +C Add\stest\scase\sto\shook.test.\sNo\schanges\sto\snon-test\scode. +D 2016-10-15T08:56:18.631 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -823,7 +823,7 @@ F test/fuzzerfault.test 8792cd77fd5bce765b05d0c8e01b9edcf8af8536 F test/genesis.tcl 1e2e2e8e5cc4058549a154ff1892fe5c9de19f98 F test/hexlit.test d7b0a5f41123df1e43985b91b8b2e70f95282d21 F test/hidden.test 23c1393a79e846d68fd902d72c85d5e5dcf98711 -F test/hook.test 3b7b99d0eece6d279812c2aef6fa08bdfabc633e +F test/hook.test 3a01b876691f9151d3e44562354f7d663ff90fce F test/icu.test 73956798bace8982909c00476b216714a6d0559a F test/ieee754.test 806fc0ce7f305f57e3331eaceeddcfec9339e607 F test/imposter1.test c3f1db2d3db2c24611a6596a3fc0ffc14f1466c8 @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P aa6de9c40ba2d906772b9032fd5d798661f6d4cc b6ddabe1818c36007c476a31e2e35755630a5f14 -R 60e5658793423fe7463e5f09d2e53763 -U mistachkin -Z 76feeade398c4222d6ce153559d25186 +P 16039be3739b8d3b34a1e6093eaebb09e07f984b +R 166049b4e9b829af91339e72272b5c27 +U dan +Z 7906df778321c686ecad94fabe527fa9 diff --git a/manifest.uuid b/manifest.uuid index c6ae521fea..eeaece7312 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -16039be3739b8d3b34a1e6093eaebb09e07f984b \ No newline at end of file +2674d779f5453ea6b709a39618d4b8017ab2e3fb \ No newline at end of file diff --git a/test/hook.test b/test/hook.test index 12e5bc0656..8f095c9e8d 100644 --- a/test/hook.test +++ b/test/hook.test @@ -848,4 +848,10 @@ do_preupdate_test 7.6.4 { DELETE main t1 1 1 0 abc } +# No preupdate callbacks for modifying sqlite_master. +do_preupdate_test 8.1 { + CREATE TABLE x1(x, y); +} { +} + finish_test From f013e20c668d4311cbf0218d26ac9c93591a052c Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 15 Oct 2016 18:37:05 +0000 Subject: [PATCH 0922/1484] Add documentation for the OP_SorterInsert opcode, formerly omitted by mistake. No changes to code. FossilOrigin-Name: 16d88a907730e3773a1320dbaf1f82c2bc71d71f --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/vdbe.c | 7 +++++++ 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index b4e33fd389..7ab5ed406d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\stest\scase\sto\shook.test.\sNo\schanges\sto\snon-test\scode. -D 2016-10-15T08:56:18.631 +C Add\sdocumentation\sfor\sthe\sOP_SorterInsert\sopcode,\sformerly\somitted\sby\smistake.\nNo\schanges\sto\scode. +D 2016-10-15T18:37:05.801 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -453,7 +453,7 @@ F src/update.c 8179e699dbd45b92934fd02d3d8e3732e8da8802 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 3e2da6101888d073e79ecc6af5e0a2f70fa1e498 F src/vacuum.c 913970b9d86dd6c2b8063ef1af421880f1464ec3 -F src/vdbe.c f43aa96f2efe9bc8a06d17115661af527a3318fa +F src/vdbe.c ad4b4df4885067cd82ec025e5ff0d3eb02e84d4d F src/vdbe.h c044be7050ac6bf596eecc6ab159f5dbc020a3b7 F src/vdbeInt.h 0a18713d0a2fec6807d076bd333d9bf3e57530cd F src/vdbeapi.c 8272f9342c39ab8d7eb4b9decc6caa7bc75b7d83 @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 16039be3739b8d3b34a1e6093eaebb09e07f984b -R 166049b4e9b829af91339e72272b5c27 -U dan -Z 7906df778321c686ecad94fabe527fa9 +P 2674d779f5453ea6b709a39618d4b8017ab2e3fb +R 62ebfcb1750081baeac9df5e0126f18d +U drh +Z 3a945c0067277a9ffe4be7b7ce64faea diff --git a/manifest.uuid b/manifest.uuid index eeaece7312..b3a3e5d126 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2674d779f5453ea6b709a39618d4b8017ab2e3fb \ No newline at end of file +16d88a907730e3773a1320dbaf1f82c2bc71d71f \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 54df5c536d..5eac81734f 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -5038,6 +5038,13 @@ next_tail: ** This instruction only works for indices. The equivalent instruction ** for tables is OP_Insert. */ +/* Opcode: SorterInsert P1 P2 * * * +** Synopsis: key=r[P2] +** +** Register P2 holds an SQL index key made using the +** MakeRecord instructions. This opcode writes that key +** into the sorter P1. Data for the entry is nil. +*/ case OP_SorterInsert: /* in2 */ case OP_IdxInsert: { /* in2 */ VdbeCursor *pC; From cee11adaaa3f7d507adc1eabb9db4e3d8ed1a4d4 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 17 Oct 2016 00:48:06 +0000 Subject: [PATCH 0923/1484] Small size reduction and performance increase in the string duplicator. FossilOrigin-Name: cda998f080cb00779d8c0d1c83d8fe2b74462cd4 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/malloc.c | 5 ++--- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 7ab5ed406d..9ca575bc89 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sdocumentation\sfor\sthe\sOP_SorterInsert\sopcode,\sformerly\somitted\sby\smistake.\nNo\schanges\sto\scode. -D 2016-10-15T18:37:05.801 +C Small\ssize\sreduction\sand\sperformance\sincrease\sin\sthe\sstring\sduplicator. +D 2016-10-17T00:48:06.879 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -352,7 +352,7 @@ F src/insert.c 2d5e197f2f60351937b201196965fd14cd88489c F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e F src/loadext.c 5d6642d141c07d366e43d359e94ec9de47add41d F src/main.c c9e49e376820bccca55fa9bf2ca321a51725db91 -F src/malloc.c 1443d1ad95d67c21d77af7ae3f44678252f0efec +F src/malloc.c 5ee7c2d3dcb1b0a902c9c6d0115deef54736bdfa F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3 @@ -1525,7 +1525,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 2674d779f5453ea6b709a39618d4b8017ab2e3fb -R 62ebfcb1750081baeac9df5e0126f18d +P 16d88a907730e3773a1320dbaf1f82c2bc71d71f +R 2f0998819cd5004bd7aa9d1c4c13ab4c U drh -Z 3a945c0067277a9ffe4be7b7ce64faea +Z 1e4256190583968ad55966afe2350526 diff --git a/manifest.uuid b/manifest.uuid index b3a3e5d126..bf23f2a097 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -16d88a907730e3773a1320dbaf1f82c2bc71d71f \ No newline at end of file +cda998f080cb00779d8c0d1c83d8fe2b74462cd4 \ No newline at end of file diff --git a/src/malloc.c b/src/malloc.c index 462d78e68c..4ec1bca57c 100644 --- a/src/malloc.c +++ b/src/malloc.c @@ -726,9 +726,8 @@ char *sqlite3DbStrDup(sqlite3 *db, const char *z){ if( z==0 ){ return 0; } - n = sqlite3Strlen30(z) + 1; - assert( (n&0x7fffffff)==n ); - zNew = sqlite3DbMallocRaw(db, (int)n); + n = strlen(z) + 1; + zNew = sqlite3DbMallocRaw(db, n); if( zNew ){ memcpy(zNew, z, n); } From 5f0b8a0e304221b391084b87b938d21d779a34da Mon Sep 17 00:00:00 2001 From: mistachkin Date: Mon, 17 Oct 2016 18:33:36 +0000 Subject: [PATCH 0924/1484] Corrections to a couple recently added 'filectrl.test' results. FossilOrigin-Name: 3d89dc4544bc51f8c9fa63a6ecf0458f6d10fc9f --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/filectrl.test | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 846685db9b..bcbb36e237 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Changes\sto\ssupport\sinterrupting\sa\scheckpoint\susing\ssqlite3_interrupt(). -D 2016-10-17T15:28:39.424 +C Corrections\sto\sa\scouple\srecently\sadded\s'filectrl.test'\sresults. +D 2016-10-17T18:33:36.378 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -679,7 +679,7 @@ F test/expr.test 66a2c9ac34f74f036faa4092f5402c7d3162fc93 F test/extension01.test 00d13cec817f331a687a243e0e5a2d87b0e358c9 F test/extraquick.test cb254400bd42bfb777ff675356aabf3287978f79 F test/fallocate.test 3e979af17dfa7e5e9dda5eba1a696c04fa9d47f7 -F test/filectrl.test c6547e6c3c4c3ef9707a0b3dc147de718135cacc +F test/filectrl.test 6e871c2d35dead1d9a88e176e8d2ca094fec6bb3 F test/filefmt.test e4edbdc637ca9576ccf4337a3cce627d9df7a56c F test/fkey1.test 13e3d48236a2b9f5c5ebd232eef9b3ab682a8a2c F test/fkey2.test f3d27ecba480a348c328965d154214719bb158a9 @@ -1526,7 +1526,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P cda998f080cb00779d8c0d1c83d8fe2b74462cd4 c7a9f26d118c7a453d45fa73efa4d1ab79301659 -R 00d803db9be93d1b8c7f2861fe9a2270 -U dan -Z b37d65eeae68b321dec11a25d79485cc +P c88d36e251abec24aa7e37cf550e148904b9fd2d +R a9d0099c5bec3f8fb6b8d6dee554f910 +U mistachkin +Z 550d80ee0f4b6472f738eb0d0f21304b diff --git a/manifest.uuid b/manifest.uuid index ff8b6bf968..a75f31c4b8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c88d36e251abec24aa7e37cf550e148904b9fd2d \ No newline at end of file +3d89dc4544bc51f8c9fa63a6ecf0458f6d10fc9f \ No newline at end of file diff --git a/test/filectrl.test b/test/filectrl.test index cb46994145..460b71e257 100644 --- a/test/filectrl.test +++ b/test/filectrl.test @@ -53,7 +53,7 @@ if {$tcl_platform(platform)=="windows"} { db close forcedelete test2.db list $size $handle [expr {$handle != 0}] - } {/^0 \{0 \d+\} 1$/} + } {/^0 \{0 [0-9A-Fa-f]+\} 1$/} do_test filectrl-2.2 { sqlite3 db test2.db @@ -66,7 +66,7 @@ if {$tcl_platform(platform)=="windows"} { db close forcedelete test2.db list $size $handle [expr {$handle != 0}] - } {/^1\d+ \{0 \d+\} 1$/} + } {/^1\d+ \{0 [0-9A-Fa-f]+\} 1$/} } finish_test From 47d00872fc6a5fe8c6955858c4a1c0c5a53f8978 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Mon, 17 Oct 2016 18:44:11 +0000 Subject: [PATCH 0925/1484] Escape non-ASCII character from an ICU extension comment. FossilOrigin-Name: 5ec02ecf3d20ce7e3f5249e9a3684f9b67a7d703 --- ext/icu/icu.c | 2 +- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/ext/icu/icu.c b/ext/icu/icu.c index 4d19dfbd62..0e33387486 100644 --- a/ext/icu/icu.c +++ b/ext/icu/icu.c @@ -349,7 +349,7 @@ static void icuRegexpFunc(sqlite3_context *p, int nArg, sqlite3_value **apArg){ ** of upper() or lower(). ** ** lower('I', 'en_us') -> 'i' -** lower('I', 'tr_tr') -> 'ı' (small dotless i) +** lower('I', 'tr_tr') -> '\u131' (small dotless i) ** ** http://www.icu-project.org/userguide/posix.html#case_mappings */ diff --git a/manifest b/manifest index bcbb36e237..a61a128157 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Corrections\sto\sa\scouple\srecently\sadded\s'filectrl.test'\sresults. -D 2016-10-17T18:33:36.378 +C Escape\snon-ASCII\scharacter\sfrom\san\sICU\sextension\scomment. +D 2016-10-17T18:44:11.779 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -202,7 +202,7 @@ F ext/fts5/tool/loadfts5.tcl 95b03429ee6b138645703c6ca192c3ac96eaf093 F ext/fts5/tool/mkfts5c.tcl d1c2a9ab8e0ec690a52316f33dd9b1d379942f45 F ext/fts5/tool/showfts5.tcl d54da0e067306663e2d5d523965ca487698e722c F ext/icu/README.txt d9fbbad0c2f647c3fdf715fc9fd64af53aedfc43 -F ext/icu/icu.c 43df9d8ef2fae7a325100ebd713ab089dc829dd7 +F ext/icu/icu.c 7d371146fff9c21d4f7a806866c578f61b566511 F ext/icu/sqliteicu.h 728867a802baa5a96de7495e9689a8e01715ef37 F ext/misc/amatch.c 211108e201105e4bb0c076527b8cfd34330fc234 F ext/misc/carray.c 40c27641010a4dc67e3690bdb7c9d36ca58b3c2d @@ -1526,7 +1526,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P c88d36e251abec24aa7e37cf550e148904b9fd2d -R a9d0099c5bec3f8fb6b8d6dee554f910 +P 3d89dc4544bc51f8c9fa63a6ecf0458f6d10fc9f +R fa25023b830313001a08fb629addaf5e U mistachkin -Z 550d80ee0f4b6472f738eb0d0f21304b +Z 1fb4dc60b08e482dba797565ab552769 diff --git a/manifest.uuid b/manifest.uuid index a75f31c4b8..5b2ad9748c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3d89dc4544bc51f8c9fa63a6ecf0458f6d10fc9f \ No newline at end of file +5ec02ecf3d20ce7e3f5249e9a3684f9b67a7d703 \ No newline at end of file From f8a89ca5dd940344455120ef8b3ed55823ef5efb Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 18 Oct 2016 14:35:55 +0000 Subject: [PATCH 0926/1484] Add the --repeat option to speedtest1.c and speed-check.sh. FossilOrigin-Name: 6ca0e06b21b0d5f7ae5bcb7839a11a45da0d2cea --- manifest | 16 +++++------ manifest.uuid | 2 +- test/speedtest1.c | 67 +++++++++++++++++++++++++++++---------------- tool/speed-check.sh | 5 ++++ 4 files changed, 58 insertions(+), 32 deletions(-) diff --git a/manifest b/manifest index a61a128157..6ba78c216a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Escape\snon-ASCII\scharacter\sfrom\san\sICU\sextension\scomment. -D 2016-10-17T18:44:11.779 +C Add\sthe\s--repeat\soption\sto\sspeedtest1.c\sand\sspeed-check.sh. +D 2016-10-18T14:35:55.358 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -1113,7 +1113,7 @@ F test/speed3.test 694affeb9100526007436334cf7d08f3d74b85ef F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715 F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b -F test/speedtest1.c 43b25ae8e303bcada98e00be036e710de17d346a +F test/speedtest1.c 0258bb629989fcf06534c923c99d0a67d8bfe9d9 F test/spellfix.test f9c1f431e2c096c8775fec032952320c0e4700db F test/spellfix2.test dfc8f519a3fc204cb2dfa8b4f29821ae90f6f8c3 F test/spellfix3.test 0f9efaaa502a0e0a09848028518a6fb096c8ad33 @@ -1486,7 +1486,7 @@ F tool/showstat4.c bda40d6e395df7edb6e9ea630784d3d762c35b4b F tool/showwal.c ec79959834f7b21f1e0a2aa52bb7c056d2203977 F tool/soak1.tcl 8d407956e1a45b485a8e072470a3e629a27037fe F tool/spaceanal.tcl ab7d9bf68062907282a64b3e12ccbfad47193c5a -F tool/speed-check.sh da6ce45957c509ba6343fe3fef167e7e2b306262 +F tool/speed-check.sh b7922d000d66339d5242e7ba47ba6e3f1bc9a538 F tool/speedtest.tcl 06c76698485ccf597b9e7dbb1ac70706eb873355 F tool/speedtest16.c ecb6542862151c3e6509bbc00509b234562ae81e F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff @@ -1526,7 +1526,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 3d89dc4544bc51f8c9fa63a6ecf0458f6d10fc9f -R fa25023b830313001a08fb629addaf5e -U mistachkin -Z 1fb4dc60b08e482dba797565ab552769 +P 5ec02ecf3d20ce7e3f5249e9a3684f9b67a7d703 +R fc69fe36bbf8dbc4c509c14f32494c61 +U drh +Z f0cdcbe9fbac1dc86a3b7a6c4617ee29 diff --git a/manifest.uuid b/manifest.uuid index 5b2ad9748c..88c068dcb6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5ec02ecf3d20ce7e3f5249e9a3684f9b67a7d703 \ No newline at end of file +6ca0e06b21b0d5f7ae5bcb7839a11a45da0d2cea \ No newline at end of file diff --git a/test/speedtest1.c b/test/speedtest1.c index 7ae6739fff..c34b0eb629 100644 --- a/test/speedtest1.c +++ b/test/speedtest1.c @@ -22,6 +22,7 @@ static const char zHelp[] = " --pagesize N Set the page size to N\n" " --pcache N SZ Configure N pages of pagecache each of size SZ bytes\n" " --primarykey Use PRIMARY KEY instead of UNIQUE where appropriate\n" + " --repeat N Repeat each SELECT N times (default: 1)\n" " --reprepare Reprepare each statement upon every invocation\n" " --scratch N SZ Configure scratch memory for N slots of SZ bytes each\n" " --serialized Set serialized threading mode\n" @@ -72,6 +73,7 @@ static struct Global { int bMemShrink; /* Call sqlite3_db_release_memory() often */ int eTemp; /* 0: no TEMP. 9: always TEMP. */ int szTest; /* Scale factor for test iterations */ + int nRepeat; /* Repeat selects this many times */ const char *zWR; /* Might be WITHOUT ROWID */ const char *zNN; /* Might be NOT NULL */ const char *zPK; /* Might be UNIQUE or PRIMARY KEY */ @@ -530,8 +532,10 @@ void testset_main(void){ " WHERE b BETWEEN ?1 AND ?2; -- %d times", n ); for(i=1; i<=n; i++){ - x1 = speedtest1_random()%maxb; - x2 = speedtest1_random()%10 + sz/5000 + x1; + if( (i-1)%g.nRepeat==0 ){ + x1 = speedtest1_random()%maxb; + x2 = speedtest1_random()%10 + sz/5000 + x1; + } sqlite3_bind_int(g.pStmt, 1, x1); sqlite3_bind_int(g.pStmt, 2, x2); speedtest1_run(); @@ -548,11 +552,13 @@ void testset_main(void){ " WHERE c LIKE ?1; -- %d times", n ); for(i=1; i<=n; i++){ - x1 = speedtest1_random()%maxb; - zNum[0] = '%'; - len = speedtest1_numbername(i, zNum+1, sizeof(zNum)-2); - zNum[len] = '%'; - zNum[len+1] = 0; + if( (i-1)%g.nRepeat==0 ){ + x1 = speedtest1_random()%maxb; + zNum[0] = '%'; + len = speedtest1_numbername(i, zNum+1, sizeof(zNum)-2); + zNum[len] = '%'; + zNum[len+1] = 0; + } sqlite3_bind_text(g.pStmt, 1, zNum, len, SQLITE_STATIC); speedtest1_run(); } @@ -568,11 +574,13 @@ void testset_main(void){ " ORDER BY a; -- %d times", n ); for(i=1; i<=n; i++){ - x1 = speedtest1_random()%maxb; - zNum[0] = '%'; - len = speedtest1_numbername(i, zNum+1, sizeof(zNum)-2); - zNum[len] = '%'; - zNum[len+1] = 0; + if( (i-1)%g.nRepeat==0 ){ + x1 = speedtest1_random()%maxb; + zNum[0] = '%'; + len = speedtest1_numbername(i, zNum+1, sizeof(zNum)-2); + zNum[len] = '%'; + zNum[len+1] = 0; + } sqlite3_bind_text(g.pStmt, 1, zNum, len, SQLITE_STATIC); speedtest1_run(); } @@ -587,11 +595,13 @@ void testset_main(void){ " ORDER BY a LIMIT 10; -- %d times", n ); for(i=1; i<=n; i++){ - x1 = speedtest1_random()%maxb; - zNum[0] = '%'; - len = speedtest1_numbername(i, zNum+1, sizeof(zNum)-2); - zNum[len] = '%'; - zNum[len+1] = 0; + if( (i-1)%g.nRepeat==0 ){ + x1 = speedtest1_random()%maxb; + zNum[0] = '%'; + len = speedtest1_numbername(i, zNum+1, sizeof(zNum)-2); + zNum[len] = '%'; + zNum[len+1] = 0; + } sqlite3_bind_text(g.pStmt, 1, zNum, len, SQLITE_STATIC); speedtest1_run(); } @@ -618,8 +628,10 @@ void testset_main(void){ " WHERE b BETWEEN ?1 AND ?2; -- %d times", n ); for(i=1; i<=n; i++){ - x1 = speedtest1_random()%maxb; - x2 = speedtest1_random()%10 + sz/5000 + x1; + if( (i-1)%g.nRepeat==0 ){ + x1 = speedtest1_random()%maxb; + x2 = speedtest1_random()%10 + sz/5000 + x1; + } sqlite3_bind_int(g.pStmt, 1, x1); sqlite3_bind_int(g.pStmt, 2, x2); speedtest1_run(); @@ -636,8 +648,10 @@ void testset_main(void){ " WHERE a BETWEEN ?1 AND ?2; -- %d times", n ); for(i=1; i<=n; i++){ - x1 = speedtest1_random()%maxb; - x2 = speedtest1_random()%10 + sz/5000 + x1; + if( (i-1)%g.nRepeat==0 ){ + x1 = speedtest1_random()%maxb; + x2 = speedtest1_random()%10 + sz/5000 + x1; + } sqlite3_bind_int(g.pStmt, 1, x1); sqlite3_bind_int(g.pStmt, 2, x2); speedtest1_run(); @@ -654,8 +668,10 @@ void testset_main(void){ " WHERE c BETWEEN ?1 AND (?1||'~'); -- %d times", n ); for(i=1; i<=n; i++){ - x1 = swizzle(i, maxb); - len = speedtest1_numbername(x1, zNum, sizeof(zNum)-1); + if( (i-1)%g.nRepeat==0 ){ + x1 = swizzle(i, maxb); + len = speedtest1_numbername(x1, zNum, sizeof(zNum)-1); + } sqlite3_bind_text(g.pStmt, 1, zNum, len, SQLITE_STATIC); speedtest1_run(); } @@ -1260,6 +1276,7 @@ int main(int argc, char **argv){ g.zNN = ""; g.zPK = "UNIQUE"; g.szTest = 100; + g.nRepeat = 1; for(i=1; i=argc-1 ) fatal_error("missing arguments on %s\n", argv[i]); + g.nRepeat = integerValue(argv[i+1]); + i += 1; }else if( strcmp(z,"reprepare")==0 ){ g.bReprepare = 1; }else if( strcmp(z,"scratch")==0 ){ diff --git a/tool/speed-check.sh b/tool/speed-check.sh index 57f2ca0703..536903abf6 100644 --- a/tool/speed-check.sh +++ b/tool/speed-check.sh @@ -85,6 +85,11 @@ while test "$1" != ""; do shift; SPEEDTEST_OPTS="$SPEEDTEST_OPTS --heap $1 64" ;; + --repeat) + CC_OPTS="$CC_OPTS -DSQLITE_ENABLE_RCACHE" + shift; + SPEEDTEST_OPTS="$SPEEDTEST_OPTS --repeat $1" + ;; *) CC_OPTS="$CC_OPTS $1" ;; From ba69061ebcb4631b859b6907feb66a28d24f987f Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 18 Oct 2016 15:29:57 +0000 Subject: [PATCH 0927/1484] Fix harmless uninitialized variable warnings in speedtest1.c. FossilOrigin-Name: 2aa7a03b8632dbfd9741018b5b19c372dcfd3647 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/speedtest1.c | 5 +++-- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 6ba78c216a..80c25b5906 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\s--repeat\soption\sto\sspeedtest1.c\sand\sspeed-check.sh. -D 2016-10-18T14:35:55.358 +C Fix\sharmless\suninitialized\svariable\swarnings\sin\sspeedtest1.c. +D 2016-10-18T15:29:57.091 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -1113,7 +1113,7 @@ F test/speed3.test 694affeb9100526007436334cf7d08f3d74b85ef F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715 F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b -F test/speedtest1.c 0258bb629989fcf06534c923c99d0a67d8bfe9d9 +F test/speedtest1.c ffb96750d02e21d1acdbf63464153580825206d7 F test/spellfix.test f9c1f431e2c096c8775fec032952320c0e4700db F test/spellfix2.test dfc8f519a3fc204cb2dfa8b4f29821ae90f6f8c3 F test/spellfix3.test 0f9efaaa502a0e0a09848028518a6fb096c8ad33 @@ -1526,7 +1526,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 5ec02ecf3d20ce7e3f5249e9a3684f9b67a7d703 -R fc69fe36bbf8dbc4c509c14f32494c61 +P 6ca0e06b21b0d5f7ae5bcb7839a11a45da0d2cea +R 8be4077c354adf7e25cd7dc6c043686c U drh -Z f0cdcbe9fbac1dc86a3b7a6c4617ee29 +Z dabbc883a61a919bd51f75d4eedc92e4 diff --git a/manifest.uuid b/manifest.uuid index 88c068dcb6..c29d224a0f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6ca0e06b21b0d5f7ae5bcb7839a11a45da0d2cea \ No newline at end of file +2aa7a03b8632dbfd9741018b5b19c372dcfd3647 \ No newline at end of file diff --git a/test/speedtest1.c b/test/speedtest1.c index c34b0eb629..a77896fc1f 100644 --- a/test/speedtest1.c +++ b/test/speedtest1.c @@ -463,11 +463,12 @@ void testset_main(void){ int n; /* iteration count */ int sz; /* Size of the tables */ int maxb; /* Maximum swizzled value */ - unsigned x1, x2; /* Parameters */ - int len; /* Length of the zNum[] string */ + unsigned x1 = 0, x2 = 0; /* Parameters */ + int len = 0; /* Length of the zNum[] string */ char zNum[2000]; /* A number name */ sz = n = g.szTest*500; + zNum[0] = 0; maxb = roundup_allones(sz); speedtest1_begin_test(100, "%d INSERTs into table with no index", n); speedtest1_exec("BEGIN"); From c3191d236a9f8eb85343345ee925d2249bbda316 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 18 Oct 2016 16:36:15 +0000 Subject: [PATCH 0928/1484] Minor simplification of the comparison opcodes. FossilOrigin-Name: 56474ebca3fdddb8f3c5156f06dc42dc0a65256c --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 3 +-- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 80c25b5906..48536b0043 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\suninitialized\svariable\swarnings\sin\sspeedtest1.c. -D 2016-10-18T15:29:57.091 +C Minor\ssimplification\sof\sthe\scomparison\sopcodes. +D 2016-10-18T16:36:15.935 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -453,7 +453,7 @@ F src/update.c 8179e699dbd45b92934fd02d3d8e3732e8da8802 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 3e2da6101888d073e79ecc6af5e0a2f70fa1e498 F src/vacuum.c 913970b9d86dd6c2b8063ef1af421880f1464ec3 -F src/vdbe.c 6aa65e22bd1a44eb0cb1fa040cb9955b6670e5dd +F src/vdbe.c c93ae647b3b302234f3593fd686577216aa22543 F src/vdbe.h c044be7050ac6bf596eecc6ab159f5dbc020a3b7 F src/vdbeInt.h 0a18713d0a2fec6807d076bd333d9bf3e57530cd F src/vdbeapi.c 8272f9342c39ab8d7eb4b9decc6caa7bc75b7d83 @@ -1526,7 +1526,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 6ca0e06b21b0d5f7ae5bcb7839a11a45da0d2cea -R 8be4077c354adf7e25cd7dc6c043686c +P 2aa7a03b8632dbfd9741018b5b19c372dcfd3647 +R 4e106c87e784e92bad6650fe8613fe88 U drh -Z dabbc883a61a919bd51f75d4eedc92e4 +Z 84c64fba90e2b1da59a52306d789b152 diff --git a/manifest.uuid b/manifest.uuid index c29d224a0f..091e1f1005 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2aa7a03b8632dbfd9741018b5b19c372dcfd3647 \ No newline at end of file +56474ebca3fdddb8f3c5156f06dc42dc0a65256c \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 4d7e7b99d6..09019f3728 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2003,8 +2003,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ assert( pOp->opcode==OP_Eq || pOp->opcode==OP_Ne ); assert( (flags1 & MEM_Cleared)==0 ); assert( (pOp->p5 & SQLITE_JUMPIFNULL)==0 ); - if( (flags1&MEM_Null)!=0 - && (flags3&MEM_Null)!=0 + if( (flags1&flags3&MEM_Null)!=0 && (flags3&MEM_Cleared)==0 ){ res = 0; /* Operands are equal */ From 86873baa5887761901e78546f7bdaa684d68cfff Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 20 Oct 2016 11:48:48 +0000 Subject: [PATCH 0929/1484] Add test case to incrblob4.test. No changes to code. FossilOrigin-Name: fd9c6ff05f2052810549a1a6a384f4b40f4ba4ac --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/incrblob4.test | 21 +++++++++++++++++++++ 3 files changed, 29 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 48536b0043..a415c87dce 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Minor\ssimplification\sof\sthe\scomparison\sopcodes. -D 2016-10-18T16:36:15.935 +C Add\stest\scase\sto\sincrblob4.test.\sNo\schanges\sto\scode. +D 2016-10-20T11:48:48.196 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -835,7 +835,7 @@ F test/in5.test 6c006e0bcd7351b69350ef566e65f244023489e9 F test/incrblob.test c9b96afc292aeff43d6687bcb09b0280aa599822 F test/incrblob2.test a5ce5ed1d0b01e2ed347245a21170372528af0a5 F test/incrblob3.test d8d036fde015d4a159cd3cbae9d29003b37227a4 -F test/incrblob4.test f26502a5697893e5acea268c910f16478c2f0fab +F test/incrblob4.test fab83541571c7281aa561e5ea6088eb8612a4bec F test/incrblob_err.test 69f9247fed50278d48ea710d1a8f9cdb09e4c0b8 F test/incrblobfault.test 280474078f6da9e732cd2a215d3d854969014b6e F test/incrcorrupt.test 6c567fbf870aa9e91866fe52ce6f200cd548939a @@ -1526,7 +1526,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 2aa7a03b8632dbfd9741018b5b19c372dcfd3647 -R 4e106c87e784e92bad6650fe8613fe88 -U drh -Z 84c64fba90e2b1da59a52306d789b152 +P 56474ebca3fdddb8f3c5156f06dc42dc0a65256c +R 6a7bc6f89b0af2fdd2ebad96f33dfe0d +U dan +Z c3391a8802a4551fd3ff33c7d0504831 diff --git a/manifest.uuid b/manifest.uuid index 091e1f1005..fbad17e2f8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -56474ebca3fdddb8f3c5156f06dc42dc0a65256c \ No newline at end of file +fd9c6ff05f2052810549a1a6a384f4b40f4ba4ac \ No newline at end of file diff --git a/test/incrblob4.test b/test/incrblob4.test index a92e373536..01ee37a087 100644 --- a/test/incrblob4.test +++ b/test/incrblob4.test @@ -86,4 +86,25 @@ do_test 3.3 { execsql { INSERT INTO t1(v) VALUES($new) } } {} +#------------------------------------------------------------------------- +# Test that it is not possible to DROP a table with an incremental blob +# cursor open on it. +# +do_execsql_test 4.1 { + CREATE TABLE t2(a INTEGER PRIMARY KEY, b); + INSERT INTO t2 VALUES(456, '0123456789'); +} +do_test 4.2 { + set blob [db incrblob -readonly t2 b 456] + read $blob 5 +} {01234} +do_catchsql_test 4.3 { + DROP TABLE t2 +} {1 {database table is locked}} +do_test 4.4 { + sqlite3_extended_errcode db +} {SQLITE_LOCKED} +close $blob + finish_test + From ceb97c110715008c71e79d6f84936c42e10501b8 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 21 Oct 2016 10:09:22 +0000 Subject: [PATCH 0930/1484] If SQLITE_DIRECT_OVERFLOW_READ is defined at compile time, add "DIRECT_OVERFLOW_READ" to the list of symbols returned by "PRAGMA compile_options". FossilOrigin-Name: b7d9727bff2e840af4b090872c991693e78e6076 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/ctime.c | 3 +++ test/ctime.test | 12 ++++++++++++ 4 files changed, 23 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index a415c87dce..d7a058afaa 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\stest\scase\sto\sincrblob4.test.\sNo\schanges\sto\scode. -D 2016-10-20T11:48:48.196 +C If\sSQLITE_DIRECT_OVERFLOW_READ\sis\sdefined\sat\scompile\stime,\sadd\s"DIRECT_OVERFLOW_READ"\sto\sthe\slist\sof\ssymbols\sreturned\sby\s"PRAGMA\scompile_options". +D 2016-10-21T10:09:22.112 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -335,7 +335,7 @@ F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 F src/build.c 59dcfdc1ee55439d069af301ef7f2e84421b5102 F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e -F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7 +F src/ctime.c 72c9d01cf446069234e9b54db6fec3e1fc063f58 F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c cb3f6300df24c26c609778b2731f82644b5532ec @@ -621,7 +621,7 @@ F test/crashtest1.c 09c1c7d728ccf4feb9e481671e29dda5669bbcc2 F test/createtab.test b5de160630b209c4b8925bdcbbaf48cc90b67fe8 F test/cse.test 277350a26264495e86b1785f34d2d0c8600e021c F test/csv01.test e0ba3caaa57e4c667a0b45977689fb8082f14348 -F test/ctime.test 0b995accd44a52914bd4744d5c1b6e1a56c7897c +F test/ctime.test ff6c38e822459d6ca743c34901caf57740b08b54 F test/cursorhint.test 7bc346788390475e77a345da2b92270d04d35856 F test/cursorhint2.test 2b45341d32d1aae9991a00ef31ebca339b274255 F test/date.test 984ac1e3e5e031386866f034006148d3972b4a65 @@ -1526,7 +1526,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 56474ebca3fdddb8f3c5156f06dc42dc0a65256c -R 6a7bc6f89b0af2fdd2ebad96f33dfe0d +P fd9c6ff05f2052810549a1a6a384f4b40f4ba4ac +R 4fbfeb317fb8029064d3b09d0cf024a2 U dan -Z c3391a8802a4551fd3ff33c7d0504831 +Z 8fb3e008f86324b83c8c0293ad05a979 diff --git a/manifest.uuid b/manifest.uuid index fbad17e2f8..dafccbb10c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fd9c6ff05f2052810549a1a6a384f4b40f4ba4ac \ No newline at end of file +b7d9727bff2e840af4b090872c991693e78e6076 \ No newline at end of file diff --git a/src/ctime.c b/src/ctime.c index 09587ea88e..55ae13af77 100644 --- a/src/ctime.c +++ b/src/ctime.c @@ -66,6 +66,9 @@ static const char * const azCompileOpt[] = { #if defined(SQLITE_DEFAULT_MMAP_SIZE) && !defined(SQLITE_DEFAULT_MMAP_SIZE_xc) "DEFAULT_MMAP_SIZE=" CTIMEOPT_VAL(SQLITE_DEFAULT_MMAP_SIZE), #endif +#if SQLITE_DIRECT_OVERFLOW_READ + "DIRECT_OVERFLOW_READ", +#endif #if SQLITE_DISABLE_DIRSYNC "DISABLE_DIRSYNC", #endif diff --git a/test/ctime.test b/test/ctime.test index efdf170851..8ed556358f 100644 --- a/test/ctime.test +++ b/test/ctime.test @@ -224,5 +224,17 @@ do_test ctime-2.5.$tc { } ] } {0 {{}}} +#-------------------------------------------------------------------------- +# Test that SQLITE_DIRECT_OVERFLOW_READ is reflected in the output of +# "PRAGMA compile_options". +# +ifcapable direct_read { + set res 1 +} else { + set res 0 +} +do_test ctime-3.0.1 { + expr [lsearch [db eval {PRAGMA compile_options}] DIRECT_OVERFLOW_READ]>=0 +} $res finish_test From e24452edefe76efba5fe76ad786bfc0e8a1daa12 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 21 Oct 2016 10:49:39 +0000 Subject: [PATCH 0931/1484] Avoid using the "direct overflow read" optimization to read large blobs if the pager layer has a wal file open - even if the database header indicates that the db is not a wal database. FossilOrigin-Name: b54c15f11796a75683eec4b502a22ccb87d621c6 --- ext/rbu/rbudor.test | 59 +++++++++++++++++++++++++++++++++++++++++++++ manifest | 17 +++++++------ manifest.uuid | 2 +- src/btree.c | 2 +- src/pager.c | 3 ++- src/pager.h | 3 +++ 6 files changed, 75 insertions(+), 11 deletions(-) create mode 100644 ext/rbu/rbudor.test diff --git a/ext/rbu/rbudor.test b/ext/rbu/rbudor.test new file mode 100644 index 0000000000..dcee7ac381 --- /dev/null +++ b/ext/rbu/rbudor.test @@ -0,0 +1,59 @@ +# 2016 October 21 +# +# 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 test file focuses on interactions between RBU and the feature +# enabled by SQLITE_DIRECT_OVERFLOW_READ - Direct Overflow Read. +# + +if {![info exists testdir]} { + set testdir [file join [file dirname [info script]] .. .. test] +} +source $testdir/tester.tcl +set ::testprefix rbudor + +set bigA [string repeat a 5000] +set bigB [string repeat b 5000] +do_execsql_test 1.0 { + PRAGMA page_size = 1024; + CREATE TABLE t1(a INTEGER PRIMARY KEY, b BLOB); + INSERT INTO t1 VALUES(1, $bigA); +} {} + +do_test 1.1 { + forcedelete rbu.db + sqlite3 rbu rbu.db + rbu eval { + CREATE TABLE data_t1(a, b, rbu_control); + INSERT INTO data_t1 VALUES(2, $bigB, 0); + } + rbu close +} {} + +do_test 1.2 { + sqlite3rbu rbu test.db rbu.db + while {[rbu state]!="checkpoint"} { + rbu step + } + rbu step + db eval { SELECT * FROM t1 } +} [list 1 $bigA 2 $bigB] + +do_test 1.3 { + while {[rbu step]=="SQLITE_OK"} {} + rbu close +} {SQLITE_DONE} + +do_execsql_test 1.4 { + SELECT * FROM t1 +} [list 1 $bigA 2 $bigB] + +finish_test + diff --git a/manifest b/manifest index d7a058afaa..6e989ee6c7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C If\sSQLITE_DIRECT_OVERFLOW_READ\sis\sdefined\sat\scompile\stime,\sadd\s"DIRECT_OVERFLOW_READ"\sto\sthe\slist\sof\ssymbols\sreturned\sby\s"PRAGMA\scompile_options". -D 2016-10-21T10:09:22.112 +C Avoid\susing\sthe\s"direct\soverflow\sread"\soptimization\sto\sread\slarge\sblobs\sif\sthe\npager\slayer\shas\sa\swal\sfile\sopen\s-\seven\sif\sthe\sdatabase\sheader\sindicates\sthat\nthe\sdb\sis\snot\sa\swal\sdatabase. +D 2016-10-21T10:49:39.630 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -247,6 +247,7 @@ F ext/rbu/rbuC.test efe47db508a0269b683cb2a1913a425ffd39a831 F ext/rbu/rbu_common.tcl a38e8e2d4a50fd6aaf151633714c1b1d2fae3ead F ext/rbu/rbucrash.test 8d2ed5d4b05fef6c00c2a6b5f7ead71fa172a695 F ext/rbu/rbudiff.test 3e605cf624d00d04d0fb1316a3acec4fbe3b3ac5 +F ext/rbu/rbudor.test 99b05cc0df613e962c2c8085cfb05686a09cf315 F ext/rbu/rbufault.test cc0be8d5d392d98b0c2d6a51be377ea989250a89 F ext/rbu/rbufault2.test 9a7f19edd6ea35c4c9f807d8a3db0a03a5670c06 F ext/rbu/rbufault3.test 54a399888ac4af44c68f9f58afbed23149428bca @@ -329,7 +330,7 @@ F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792 F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b F src/bitvec.c 3ee4c8b2c94ed3a7377256e18199e6ff5cf33f63 F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 -F src/btree.c 4d035fb52b0ef9658d43dfe604413185dff7a5d1 +F src/btree.c 0fde2593dcf004ac2e5d5af93867a9099ed3cc9d F src/btree.h d05b2fcc290991a8a3d9ea1816ddd55a4359dcde F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 F src/build.c 59dcfdc1ee55439d069af301ef7f2e84421b5102 @@ -373,8 +374,8 @@ F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586 F src/os_unix.c be9ca0f901a2b6c1bc93dc338f4863675180c189 F src/os_win.c cf90abd4e50d9f56d2c20ce8e005aff55d7bd8e9 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a -F src/pager.c 49b6c163832498838c92d0c4c90721576ae707b7 -F src/pager.h 0a19b1e212d0f5d0507f186ae1cca4e523d09d1a +F src/pager.c 549ed86833b484fa3cd4799e3289c83b3ace8859 +F src/pager.h 07d6938df0b74e4abe8f57807a8b0e1084321d8b F src/parse.y 0338f906b61e311c2b7e11a3f89b0092c780b664 F src/pcache.c 5ff2a08f76a9c1b22f43eb063b7068fb085465ac F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 @@ -1526,7 +1527,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P fd9c6ff05f2052810549a1a6a384f4b40f4ba4ac -R 4fbfeb317fb8029064d3b09d0cf024a2 +P b7d9727bff2e840af4b090872c991693e78e6076 +R 775b940b506452362a073212102869ea U dan -Z 8fb3e008f86324b83c8c0293ad05a979 +Z 738379ab10ae31c6f3af66e5c08bf61c diff --git a/manifest.uuid b/manifest.uuid index dafccbb10c..24383aeede 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b7d9727bff2e840af4b090872c991693e78e6076 \ No newline at end of file +b54c15f11796a75683eec4b502a22ccb87d621c6 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 1f7225cd8b..ddf68ebf25 100644 --- a/src/btree.c +++ b/src/btree.c @@ -4608,7 +4608,7 @@ static int accessPayload( && (bEnd || a==ovflSize) /* (6) */ && pBt->inTransaction==TRANS_READ /* (4) */ && (fd = sqlite3PagerFile(pBt->pPager))->pMethods /* (3) */ - && pBt->pPage1->aData[19]==0x01 /* (5) */ + && 0==sqlite3PagerUseWal(pBt->pPager) /* (5) */ && &pBuf[-4]>=pBufStart /* (7) */ ){ u8 aSave[4]; diff --git a/src/pager.c b/src/pager.c index f12594031c..71c4acdb9b 100644 --- a/src/pager.c +++ b/src/pager.c @@ -817,9 +817,10 @@ static const unsigned char aJournalMagic[] = { ** rollback journal. Otherwise false. */ #ifndef SQLITE_OMIT_WAL -static int pagerUseWal(Pager *pPager){ +int sqlite3PagerUseWal(Pager *pPager){ return (pPager->pWal!=0); } +# define pagerUseWal(x) sqlite3PagerUseWal(x) #else # define pagerUseWal(x) 0 # define pagerRollbackWal(x) 0 diff --git a/src/pager.h b/src/pager.h index 68f2c06cae..3003c21ecc 100644 --- a/src/pager.h +++ b/src/pager.h @@ -178,10 +178,13 @@ int sqlite3PagerSharedLock(Pager *pPager); int sqlite3PagerWalCallback(Pager *pPager); int sqlite3PagerOpenWal(Pager *pPager, int *pisOpen); int sqlite3PagerCloseWal(Pager *pPager, sqlite3*); + int sqlite3PagerUseWal(Pager *pPager); # ifdef SQLITE_ENABLE_SNAPSHOT int sqlite3PagerSnapshotGet(Pager *pPager, sqlite3_snapshot **ppSnapshot); int sqlite3PagerSnapshotOpen(Pager *pPager, sqlite3_snapshot *pSnapshot); # endif +#else +# define sqlite3PagerUseWal(x) 0 #endif #ifdef SQLITE_ENABLE_ZIPVFS From 41f5f6ec2c4aac3fd03e3adf837530a01952fc50 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 21 Oct 2016 17:39:30 +0000 Subject: [PATCH 0932/1484] Add ".mode quote" to the command-line shell. FossilOrigin-Name: c4f5fa78cd8207ce1e46e32e632b8f6ee86047e1 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/shell.c | 36 ++++++++++++++++++++++-------------- 3 files changed, 30 insertions(+), 22 deletions(-) diff --git a/manifest b/manifest index 6e989ee6c7..28f26abfa4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\susing\sthe\s"direct\soverflow\sread"\soptimization\sto\sread\slarge\sblobs\sif\sthe\npager\slayer\shas\sa\swal\sfile\sopen\s-\seven\sif\sthe\sdatabase\sheader\sindicates\sthat\nthe\sdb\sis\snot\sa\swal\sdatabase. -D 2016-10-21T10:49:39.630 +C Add\s".mode\squote"\sto\sthe\scommand-line\sshell. +D 2016-10-21T17:39:30.026 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -388,7 +388,7 @@ F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c 3fac1b2737ea5a724f20b921ac7e259c9be2100b F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c ea3af83e2d0f245fef81ea4cf04cb730ce67f722 -F src/shell.c b80396d2fadce4681397707e30078bf416e1dec2 +F src/shell.c f0e8b54c58a8a13cc046f5af6d72de7e0a118a2b F src/sqlite.h.in 7ef021d74ac7d4004c784a16ad015508f171c4bf F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae @@ -1527,7 +1527,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b7d9727bff2e840af4b090872c991693e78e6076 -R 775b940b506452362a073212102869ea -U dan -Z 738379ab10ae31c6f3af66e5c08bf61c +P b54c15f11796a75683eec4b502a22ccb87d621c6 +R cdb213453699e4a8a0bded009eb336d4 +U drh +Z 3ba463b9129586b08f555ed8d54aa9f2 diff --git a/manifest.uuid b/manifest.uuid index 24383aeede..7f3cd83980 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b54c15f11796a75683eec4b502a22ccb87d621c6 \ No newline at end of file +c4f5fa78cd8207ce1e46e32e632b8f6ee86047e1 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 732ef62832..d9aef17d02 100644 --- a/src/shell.c +++ b/src/shell.c @@ -668,11 +668,12 @@ struct ShellState { #define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */ #define MODE_Html 4 /* Generate an XHTML table */ #define MODE_Insert 5 /* Generate SQL "insert" statements */ -#define MODE_Tcl 6 /* Generate ANSI-C or TCL quoted elements */ -#define MODE_Csv 7 /* Quote strings, numbers are plain */ -#define MODE_Explain 8 /* Like MODE_Column, but do not truncate data */ -#define MODE_Ascii 9 /* Use ASCII unit and record separators (0x1F/0x1E) */ -#define MODE_Pretty 10 /* Pretty-print schemas */ +#define MODE_Quote 6 /* Quote values as for SQL */ +#define MODE_Tcl 7 /* Generate ANSI-C or TCL quoted elements */ +#define MODE_Csv 8 /* Quote strings, numbers are plain */ +#define MODE_Explain 9 /* Like MODE_Column, but do not truncate data */ +#define MODE_Ascii 10 /* Use ASCII unit and record separators (0x1F/0x1E) */ +#define MODE_Pretty 11 /* Pretty-print schemas */ static const char *modeDescr[] = { "line", @@ -681,6 +682,7 @@ static const char *modeDescr[] = { "semi", "html", "insert", + "quote", "tcl", "csv", "explain", @@ -1198,19 +1200,22 @@ static int shell_callback( setTextMode(p->out, 1); break; } + case MODE_Quote: case MODE_Insert: { p->cnt++; if( azArg==0 ) break; - utf8_printf(p->out,"INSERT INTO %s",p->zDestTable); - if( p->showHeader ){ - raw_printf(p->out,"("); - for(i=0; i0 ? ",": ""; - utf8_printf(p->out, "%s%s", zSep, azCol[i]); + if( p->cMode==MODE_Insert ){ + utf8_printf(p->out,"INSERT INTO %s",p->zDestTable); + if( p->showHeader ){ + raw_printf(p->out,"("); + for(i=0; i0 ? ",": ""; + utf8_printf(p->out, "%s%s", zSep, azCol[i]); + } + raw_printf(p->out,")"); } - raw_printf(p->out,")"); + raw_printf(p->out," VALUES("); } - raw_printf(p->out," VALUES("); for(i=0; i0 ? ",": ""; if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){ @@ -1233,7 +1238,7 @@ static int shell_callback( output_quoted_string(p->out, azArg[i]); } } - raw_printf(p->out,");\n"); + raw_printf(p->out,p->cMode==MODE_Quote?"\n":");\n"); break; } case MODE_Ascii: { @@ -2177,6 +2182,7 @@ static char zHelp[] = " insert SQL insert statements for TABLE\n" " line One value per line\n" " list Values delimited by .separator strings\n" + " quote Escape answers as for SQL\n" " tabs Tab-separated values\n" " tcl TCL list elements\n" ".nullvalue STRING Use STRING in place of NULL values\n" @@ -3977,6 +3983,8 @@ static int do_meta_command(char *zLine, ShellState *p){ }else if( c2=='i' && strncmp(azArg[1],"insert",n2)==0 ){ p->mode = MODE_Insert; set_table_name(p, nArg>=3 ? azArg[2] : "table"); + }else if( c2=='q' && strncmp(azArg[1],"quote",n2)==0 ){ + p->mode = MODE_Quote; }else if( c2=='a' && strncmp(azArg[1],"ascii",n2)==0 ){ p->mode = MODE_Ascii; sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Unit); From e43635aaa71af696fe36ba334c4386a8a3a9da35 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 21 Oct 2016 21:21:45 +0000 Subject: [PATCH 0933/1484] In the sessions module, avoid recording a change if an UPDATE statement overwrites a column with REAL affinity containing an integer value with the same value. FossilOrigin-Name: b861328ab9ceec6926d97658c3606e6ae9ad39bf --- ext/session/session1.test | 12 ++++++++++++ manifest | 23 +++++++++++++---------- manifest.uuid | 2 +- src/vdbeInt.h | 2 +- src/vdbeapi.c | 13 +++++++++---- src/vdbeaux.c | 2 +- 6 files changed, 37 insertions(+), 17 deletions(-) diff --git a/ext/session/session1.test b/ext/session/session1.test index e97aa3c20d..09d35af7fc 100644 --- a/ext/session/session1.test +++ b/ext/session/session1.test @@ -569,5 +569,17 @@ do_changeset_test 10.1.2 S " " do_test 10.1.4 { S delete } {} +#------------------------------------------------------------------------- +# Test the effect of updating a column from 0.0 to 0.0. +# +reset_db +do_execsql_test 11.1 { + CREATE TABLE t1(a INTEGER PRIMARY KEY, b REAL); + INSERT INTO t1 VALUES(1, 0.0); +} +do_iterator_test 11.2 * { + UPDATE t1 SET b = 0.0; +} { +} finish_test diff --git a/manifest b/manifest index 28f26abfa4..95b8a540f4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\s".mode\squote"\sto\sthe\scommand-line\sshell. -D 2016-10-21T17:39:30.026 +C In\sthe\ssessions\smodule,\savoid\srecording\sa\schange\sif\san\sUPDATE\sstatement\noverwrites\sa\scolumn\swith\sREAL\saffinity\scontaining\san\sinteger\svalue\swith\sthe\ssame\svalue. +D 2016-10-21T21:21:45.978 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -284,7 +284,7 @@ F ext/rtree/sqlite3rtree.h 9c5777af3d2921c7b4ae4954e8e5697502289d28 F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 F ext/session/changeset.c 4ccbaa4531944c24584bf6a61ba3a39c62b6267a -F ext/session/session1.test 98f384736e2bc21ccf5ed81bdadcff4ad863393b +F ext/session/session1.test e5125b216d1e8c91e0984b361b0b68529e7c5dfb F ext/session/session2.test 284de45abae4cc1082bc52012ee81521d5ac58e0 F ext/session/session3.test a7a9ce59b8d1e49e2cc23d81421ac485be0eea01 F ext/session/session4.test 457b02bdc349eb01151e54de014df77abd3c08c8 @@ -456,9 +456,9 @@ F src/util.c 3e2da6101888d073e79ecc6af5e0a2f70fa1e498 F src/vacuum.c 913970b9d86dd6c2b8063ef1af421880f1464ec3 F src/vdbe.c c93ae647b3b302234f3593fd686577216aa22543 F src/vdbe.h c044be7050ac6bf596eecc6ab159f5dbc020a3b7 -F src/vdbeInt.h 0a18713d0a2fec6807d076bd333d9bf3e57530cd -F src/vdbeapi.c 8272f9342c39ab8d7eb4b9decc6caa7bc75b7d83 -F src/vdbeaux.c 7229203e4e4a3b6eaeeddc807c2287d912c0da74 +F src/vdbeInt.h d8a56a491b752dbb5f671963b8c861ec72ea875e +F src/vdbeapi.c 97129bec6b1553da50d8e73f523c278bda66d9f6 +F src/vdbeaux.c 52d9b840859f260ce8418be9333dd77c902e1c74 F src/vdbeblob.c 3e82a797b60c3b9fed7b8de8c539ca7607874937 F src/vdbemem.c fcdd73a2001a673f48a244a77b1038928ae729c9 F src/vdbesort.c 91fda3909326860382b0ca8aa251e609c6a9d62c @@ -1527,7 +1527,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b54c15f11796a75683eec4b502a22ccb87d621c6 -R cdb213453699e4a8a0bded009eb336d4 -U drh -Z 3ba463b9129586b08f555ed8d54aa9f2 +P c4f5fa78cd8207ce1e46e32e632b8f6ee86047e1 +R c528e2d870af682535c32fe7ab38cc9b +T *branch * sessions-fix +T *sym-sessions-fix * +T -sym-trunk * +U dan +Z 40897c5531031ce2803a5defa0bd4f02 diff --git a/manifest.uuid b/manifest.uuid index 7f3cd83980..2b5d9b1434 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c4f5fa78cd8207ce1e46e32e632b8f6ee86047e1 \ No newline at end of file +b861328ab9ceec6926d97658c3606e6ae9ad39bf \ No newline at end of file diff --git a/src/vdbeInt.h b/src/vdbeInt.h index 1c6ee3f63b..86445cef66 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -430,8 +430,8 @@ struct PreUpdate { int iNewReg; /* Register for new.* values */ i64 iKey1; /* First key value passed to hook */ i64 iKey2; /* Second key value passed to hook */ - int iPKey; /* If not negative index of IPK column */ Mem *aNew; /* Array of new.* values */ + Table *pTab; /* Schema object being upated */ }; /* diff --git a/src/vdbeapi.c b/src/vdbeapi.c index 5956943af0..645ef1c864 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -1710,9 +1710,14 @@ int sqlite3_preupdate_old(sqlite3 *db, int iIdx, sqlite3_value **ppValue){ if( iIdx>=p->pUnpacked->nField ){ *ppValue = (sqlite3_value *)columnNullValue(); }else{ + Mem *pMem = *ppValue = &p->pUnpacked->aMem[iIdx]; *ppValue = &p->pUnpacked->aMem[iIdx]; - if( iIdx==p->iPKey ){ - sqlite3VdbeMemSetInt64(*ppValue, p->iKey1); + if( iIdx==p->pTab->iPKey ){ + sqlite3VdbeMemSetInt64(pMem, p->iKey1); + }else if( p->pTab->aCol[iIdx].affinity==SQLITE_AFF_REAL ){ + if( pMem->flags & MEM_Int ){ + sqlite3VdbeMemRealify(pMem); + } } } @@ -1789,7 +1794,7 @@ int sqlite3_preupdate_new(sqlite3 *db, int iIdx, sqlite3_value **ppValue){ pMem = (sqlite3_value *)columnNullValue(); }else{ pMem = &pUnpack->aMem[iIdx]; - if( iIdx==p->iPKey ){ + if( iIdx==p->pTab->iPKey ){ sqlite3VdbeMemSetInt64(pMem, p->iKey2); } } @@ -1810,7 +1815,7 @@ int sqlite3_preupdate_new(sqlite3 *db, int iIdx, sqlite3_value **ppValue){ assert( iIdx>=0 && iIdxpCsr->nField ); pMem = &p->aNew[iIdx]; if( pMem->flags==0 ){ - if( iIdx==p->iPKey ){ + if( iIdx==p->pTab->iPKey ){ sqlite3VdbeMemSetInt64(pMem, p->iKey2); }else{ rc = sqlite3VdbeMemCopy(pMem, &p->v->aMem[p->iNewReg+1+iIdx]); diff --git a/src/vdbeaux.c b/src/vdbeaux.c index df4fb2cdd0..596ab30c7b 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -4617,7 +4617,7 @@ void sqlite3VdbePreUpdateHook( preupdate.keyinfo.aSortOrder = (u8*)&fakeSortOrder; preupdate.iKey1 = iKey1; preupdate.iKey2 = iKey2; - preupdate.iPKey = pTab->iPKey; + preupdate.pTab = pTab; db->pPreUpdate = &preupdate; db->xPreUpdateCallback(db->pPreUpdateArg, db, op, zDb, zTbl, iKey1, iKey2); From 7ad3eb63cf31b432006628f9fe7b0432613bd050 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 24 Oct 2016 01:01:09 +0000 Subject: [PATCH 0934/1484] Performance optimization in moveToRoot(). Avoid repeated validity checking of the root page on each call. Once is enough. FossilOrigin-Name: 98795c2dd9a6d8fa8d49a9f5c36cdf824cae7246 --- manifest | 13 ++++++------- manifest.uuid | 2 +- src/btree.c | 13 +++++++++---- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index e1f6ab8b2b..730515d503 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\sthe\ssessions\smodule,\savoid\srecording\sa\schange\sif\san\sUPDATE\sstatement\noverwrites\sa\scolumn\swith\sREAL\saffinity\scontaining\san\sinteger\svalue\swith\s\nthe\ssame\svalue. -D 2016-10-22T01:22:30.252 +C Performance\soptimization\sin\smoveToRoot().\sAvoid\srepeated\svalidity\schecking\sof\nthe\sroot\spage\son\seach\scall.\sOnce\sis\senough. +D 2016-10-24T01:01:09.853 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -330,7 +330,7 @@ F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792 F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b F src/bitvec.c 3ee4c8b2c94ed3a7377256e18199e6ff5cf33f63 F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 -F src/btree.c 0fde2593dcf004ac2e5d5af93867a9099ed3cc9d +F src/btree.c 6ae1c17347fb2888b2b28a260b947b7717a9fca9 F src/btree.h d05b2fcc290991a8a3d9ea1816ddd55a4359dcde F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 F src/build.c 59dcfdc1ee55439d069af301ef7f2e84421b5102 @@ -1527,8 +1527,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P c4f5fa78cd8207ce1e46e32e632b8f6ee86047e1 b861328ab9ceec6926d97658c3606e6ae9ad39bf -R c528e2d870af682535c32fe7ab38cc9b -T +closed b861328ab9ceec6926d97658c3606e6ae9ad39bf +P 5f3e602831ba2ecaf8ba5411efb387afcde05a33 +R 29a58bbb2dfbc1d411acf8e8bb02ca42 U drh -Z 540f4abc4993beff1c2e838919ebaf63 +Z 723cdd59e0d6445a1b308cfb6d241f2f diff --git a/manifest.uuid b/manifest.uuid index fbe5063cb3..a7497d5dc5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5f3e602831ba2ecaf8ba5411efb387afcde05a33 \ No newline at end of file +98795c2dd9a6d8fa8d49a9f5c36cdf824cae7246 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index ddf68ebf25..4564bda7bb 100644 --- a/src/btree.c +++ b/src/btree.c @@ -4864,9 +4864,12 @@ static int moveToRoot(BtCursor *pCur){ } if( pCur->iPage>=0 ){ - while( pCur->iPage ){ - assert( pCur->apPage[pCur->iPage]!=0 ); - releasePageNotNull(pCur->apPage[pCur->iPage--]); + if( pCur->iPage ){ + do{ + assert( pCur->apPage[pCur->iPage]!=0 ); + releasePageNotNull(pCur->apPage[pCur->iPage--]); + }while( pCur->iPage); + goto skip_init; } }else if( pCur->pgnoRoot==0 ){ pCur->eState = CURSOR_INVALID; @@ -4877,7 +4880,7 @@ static int moveToRoot(BtCursor *pCur){ 0, pCur->curPagerFlags); if( rc!=SQLITE_OK ){ pCur->eState = CURSOR_INVALID; - return rc; + return rc; } pCur->iPage = 0; pCur->curIntKey = pCur->apPage[0]->intKey; @@ -4900,10 +4903,12 @@ static int moveToRoot(BtCursor *pCur){ return SQLITE_CORRUPT_BKPT; } +skip_init: pCur->aiIdx[0] = 0; pCur->info.nSize = 0; pCur->curFlags &= ~(BTCF_AtLast|BTCF_ValidNKey|BTCF_ValidOvfl); + pRoot = pCur->apPage[0]; if( pRoot->nCell>0 ){ pCur->eState = CURSOR_VALID; }else if( !pRoot->leaf ){ From 01e697b4ecefc001695caafefe3e1eb02527fa99 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 25 Oct 2016 15:06:11 +0000 Subject: [PATCH 0935/1484] Add test case to demonstrate a "BEGIN EXCLUSIVE" command returning SQLITE_BUSY_SNAPSHOT. FossilOrigin-Name: b115856408b6aa5538be67beb619d7aff0630bea --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/wal6.test | 29 +++++++++++++++++++++++++++++ 3 files changed, 37 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 730515d503..d4950ff1c5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Performance\soptimization\sin\smoveToRoot().\sAvoid\srepeated\svalidity\schecking\sof\nthe\sroot\spage\son\seach\scall.\sOnce\sis\senough. -D 2016-10-24T01:01:09.853 +C Add\stest\scase\sto\sdemonstrate\sa\s"BEGIN\sEXCLUSIVE"\scommand\sreturning\nSQLITE_BUSY_SNAPSHOT. +D 2016-10-25T15:06:11.142 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -1373,7 +1373,7 @@ F test/wal2.test 56b0bc95b8693a0be294f8d210c49025dd094bd7 F test/wal3.test 2a93004bc0fb2b5c29888964024695bade278ab2 F test/wal4.test 4744e155cd6299c6bd99d3eab1c82f77db9cdb3c F test/wal5.test 9c11da7aeccd83a46d79a556ad11a18d3cb15aa9 -F test/wal6.test a9d6aa635b9d63607dabdc11406f5f96ca986635 +F test/wal6.test 504b24ddb3a75d4b7a6e7c09dc7563622e652fd2 F test/wal64k.test 163655ecd2cb8afef4737cac2a40fdd2eeaf20b8 F test/wal7.test 2ae8f427d240099cc4b2dfef63cff44e2a68a1bd F test/wal8.test d9df3fba4caad5854ed69ed673c68482514203c8 @@ -1527,7 +1527,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 5f3e602831ba2ecaf8ba5411efb387afcde05a33 -R 29a58bbb2dfbc1d411acf8e8bb02ca42 -U drh -Z 723cdd59e0d6445a1b308cfb6d241f2f +P 98795c2dd9a6d8fa8d49a9f5c36cdf824cae7246 +R e30d5f9c1b1789e2c9a0ef25079fdb1b +U dan +Z 8c4ba873f6fa2463459d3dd02e3529e2 diff --git a/manifest.uuid b/manifest.uuid index a7497d5dc5..9cf0539683 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -98795c2dd9a6d8fa8d49a9f5c36cdf824cae7246 \ No newline at end of file +b115856408b6aa5538be67beb619d7aff0630bea \ No newline at end of file diff --git a/test/wal6.test b/test/wal6.test index 2574a64a84..92831f1fb0 100644 --- a/test/wal6.test +++ b/test/wal6.test @@ -234,5 +234,34 @@ do_test 4.4.2 { catchsql { SELECT * FROM t2 } db2 } {1 {database disk image is malformed}} +#------------------------------------------------------------------------- +# Confirm that it is possible to get an SQLITE_BUSY_SNAPSHOT error from +# "BEGIN EXCLUSIVE" if the connection already has an open read-transaction. +# +reset_db +sqlite3 db2 test.db +do_execsql_test 5.1 { + PRAGMA journal_mode = wal; + CREATE TABLE t1(x, y); + INSERT INTO t1 VALUES(1, 2); + INSERT INTO t1 VALUES(3, 4); +} {wal} +do_test 5.2 { + set res [list] + db eval { + SELECT * FROM t1 + } { + if {$x==1} { + db2 eval { INSERT INTO t1 VALUES(5, 6) } + } + if {$x==3} { + set res [catchsql {BEGIN EXCLUSIVE}] + lappend res [sqlite3_extended_errcode db] + } + } + set res +} {1 {database is locked} SQLITE_BUSY_SNAPSHOT} + + finish_test From 5c35e90377b6157f85eceffb67cd438110aa100b Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 26 Oct 2016 12:15:41 +0000 Subject: [PATCH 0936/1484] Add compile time option SQLITE_ENABLE_URI_00_ERROR. If defined, any "%00" escape found in a URI is treated as an error. FossilOrigin-Name: e8a9bfece27e2af178a206ad6bce3f24d64e7ee4 --- manifest | 22 ++++++++++++-------- manifest.uuid | 2 +- src/ctime.c | 3 +++ src/main.c | 7 +++++++ src/test_config.c | 6 ++++++ test/uri.test | 8 ++++++++ test/uri2.test | 52 +++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 90 insertions(+), 10 deletions(-) create mode 100644 test/uri2.test diff --git a/manifest b/manifest index d4950ff1c5..2c2cc3aec7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\stest\scase\sto\sdemonstrate\sa\s"BEGIN\sEXCLUSIVE"\scommand\sreturning\nSQLITE_BUSY_SNAPSHOT. -D 2016-10-25T15:06:11.142 +C Add\scompile\stime\soption\sSQLITE_ENABLE_URI_00_ERROR.\sIf\sdefined,\sany\s"%00"\nescape\sfound\sin\sa\sURI\sis\streated\sas\san\serror. +D 2016-10-26T12:15:41.516 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -336,7 +336,7 @@ F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 F src/build.c 59dcfdc1ee55439d069af301ef7f2e84421b5102 F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e -F src/ctime.c 72c9d01cf446069234e9b54db6fec3e1fc063f58 +F src/ctime.c a2a52d6e353f459d8ab0f07321f60fafa47d5421 F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c cb3f6300df24c26c609778b2731f82644b5532ec @@ -352,7 +352,7 @@ F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 F src/insert.c 2d5e197f2f60351937b201196965fd14cd88489c F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e F src/loadext.c 5d6642d141c07d366e43d359e94ec9de47add41d -F src/main.c 395bfa7a200943395f7742a40b6671ec400559ea +F src/main.c 6890ce0118968d17b18ba52ce2c99166484502ab F src/malloc.c 5ee7c2d3dcb1b0a902c9c6d0115deef54736bdfa F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b @@ -412,7 +412,7 @@ F src/test_backup.c bf5da90c9926df0a4b941f2d92825a01bbe090a0 F src/test_bestindex.c d23f80d334c59662af69191854c76b8d3d0c8c96 F src/test_blob.c a0f7ad49a0c9d4b72f693fe2a71c58d7e507174d F src/test_btree.c 8b2dc8b8848cf3a4db93f11578f075e82252a274 -F src/test_config.c 4d3d4a886416f369771d69a6dba926866deda788 +F src/test_config.c 371853b4691b482ec0bcdf77ec9e3f96dca75b04 F src/test_delete.c 32690ea215abf29dda589a580cd1b790389759b6 F src/test_demovfs.c a0c3bdd45ed044115c2c9f7779e56eafff18741e F src/test_devsym.c 4e58dec2602d8e139ca08659f62a62450587cb58 @@ -1336,7 +1336,8 @@ F test/unique2.test 3674e9f2a3f1fbbfd4772ac74b7a97090d0f77d2 F test/unixexcl.test d936ba2b06794018e136418addd59a2354eeae97 F test/unordered.test ca7adce0419e4ca0c50f039885e76ed2c531eda8 F test/update.test 6c68446b8a0a33d522a7c72b320934596a2d7d32 -F test/uri.test 6630ecbdea2aac10df3c89dbae2243f4c2c353e4 +F test/uri.test 3481026f00ade6dfe8adb7acb6e1e47b04369568 +F test/uri2.test 9d493160caf4f9906cc72d6fa3b19dba91265a70 F test/userauth01.test e740a2697a7b40d7c5003a7d7edaee16acd349a9 F test/utf16align.test 54cd35a27c005a9b6e7815d887718780b6a462ae F test/vacuum.test ce91c39f7f91a4273bf620efad21086b5aa6ef1d @@ -1527,7 +1528,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 98795c2dd9a6d8fa8d49a9f5c36cdf824cae7246 -R e30d5f9c1b1789e2c9a0ef25079fdb1b +P b115856408b6aa5538be67beb619d7aff0630bea +R e2d2bf4e59ce1ff8b210e1974b182dc4 +T *branch * uri-00-error +T *sym-uri-00-error * +T -sym-trunk * U dan -Z 8c4ba873f6fa2463459d3dd02e3529e2 +Z 46faa36cce6bb438993a61c047f9eda6 diff --git a/manifest.uuid b/manifest.uuid index 9cf0539683..2facc36c58 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b115856408b6aa5538be67beb619d7aff0630bea \ No newline at end of file +e8a9bfece27e2af178a206ad6bce3f24d64e7ee4 \ No newline at end of file diff --git a/src/ctime.c b/src/ctime.c index 55ae13af77..0233455e02 100644 --- a/src/ctime.c +++ b/src/ctime.c @@ -155,6 +155,9 @@ static const char * const azCompileOpt[] = { #if SQLITE_ENABLE_UPDATE_DELETE_LIMIT "ENABLE_UPDATE_DELETE_LIMIT", #endif +#if defined(SQLITE_ENABLE_URI_00_ERROR) + "ENABLE_URI_00_ERROR", +#endif #if SQLITE_HAS_CODEC "HAS_CODEC", #endif diff --git a/src/main.c b/src/main.c index 150ef3b1ab..ae25485301 100644 --- a/src/main.c +++ b/src/main.c @@ -2615,6 +2615,7 @@ int sqlite3ParseUri( assert( octet>=0 && octet<256 ); if( octet==0 ){ +#ifndef SQLITE_ENABLE_URI_00_ERROR /* This branch is taken when "%00" appears within the URI. In this ** case we ignore all text in the remainder of the path, name or ** value currently being parsed. So ignore the current character @@ -2627,6 +2628,12 @@ int sqlite3ParseUri( iIn++; } continue; +#else + /* If ENABLE_URI_00_ERROR is defined, "%00" in a URI is an error. */ + *pzErrMsg = sqlite3_mprintf("unexpected %%00 in uri"); + rc = SQLITE_ERROR; + goto parse_uri_out; +#endif } c = octet; }else if( eState==1 && (c=='&' || c=='=') ){ diff --git a/src/test_config.c b/src/test_config.c index 1e68e58d8d..d8e6b3c0fa 100644 --- a/src/test_config.c +++ b/src/test_config.c @@ -714,6 +714,12 @@ Tcl_SetVar2(interp, "sqlite_options", "mergesort", "1", TCL_GLOBAL_ONLY); Tcl_SetVar2(interp, "sqlite_options", "sqllog", "0", TCL_GLOBAL_ONLY); #endif +#ifdef SQLITE_ENABLE_URI_00_ERROR + Tcl_SetVar2(interp, "sqlite_options", "uri_00_error", "1", TCL_GLOBAL_ONLY); +#else + Tcl_SetVar2(interp, "sqlite_options", "uri_00_error", "0", TCL_GLOBAL_ONLY); +#endif + #define LINKVAR(x) { \ static const int cv_ ## x = SQLITE_ ## x; \ Tcl_LinkVar(interp, "SQLITE_" #x, (char *)&(cv_ ## x), \ diff --git a/test/uri.test b/test/uri.test index a0a88d2263..0931a25e51 100644 --- a/test/uri.test +++ b/test/uri.test @@ -55,6 +55,10 @@ foreach {tn uri file} { ifcapable !curdir { if {$tn==3} break } + ifcapable uri_00_error { + if {[string first %00 $uri]>=0} continue + } + if {$tcl_platform(platform)=="windows"} { # # NOTE: Due to limits on legal characters for file names imposed by @@ -124,6 +128,10 @@ foreach {tn uri kvlist} { 14 http:test.db?hello&world {} } { + ifcapable uri_00_error { + if {[string first %00 $uri]>=0} continue + } + if {$tcl_platform(platform) == "windows" && $tn>12} { continue } diff --git a/test/uri2.test b/test/uri2.test new file mode 100644 index 0000000000..91b0578d10 --- /dev/null +++ b/test/uri2.test @@ -0,0 +1,52 @@ +# 2016 October 26 +# +# 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. +# +#*********************************************************************** +# +# Tests for SQLITE_ENABLE_URI_00_ERROR builds. + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +ifcapable !uri_00_error { + finish_test + return +} + +set testprefix uri2 +db close +sqlite3_shutdown +sqlite3_config_uri 1 + +foreach {tn uri} { + 1 file:test.db%00trailing + 2 file:test.db?%00trailing=1 + 3 file:test.db?trailing=1%00 + 4 file:test.db?trailing=1&abc%00def + 5 file:test.db?trailing=1&abc%00def +} { + do_test 1.$tn.1 { + set rc [catch { sqlite3 db $uri } msg] + list $rc $msg + } {1 {unexpected %00 in uri}} + + do_test 1.$tn.2 { + sqlite3 db "" + catchsql { ATTACH $uri AS aux } + } {1 {unexpected %00 in uri}} + + catch { db close } +} + +reset_db +do_test 2.0 { + expr {[lsearch [execsql {PRAGMA compile_options}] ENABLE_URI_00_ERROR] >= 0} +} 1 + +finish_test From 635f83c062fef9154b3916a2c91d6d64d7801bfb Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 26 Oct 2016 13:44:07 +0000 Subject: [PATCH 0937/1484] Add extra tests to check the result of including a %00 escape in a URI when ENABLE_URI_00_ERROR is defined. FossilOrigin-Name: 1aaa06e37f44309c62335d8eda59ca6890d4be9d --- manifest | 15 ++++++--------- manifest.uuid | 2 +- test/uri2.test | 11 +++++++++++ 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 2c2cc3aec7..0b9bb3f9ca 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\scompile\stime\soption\sSQLITE_ENABLE_URI_00_ERROR.\sIf\sdefined,\sany\s"%00"\nescape\sfound\sin\sa\sURI\sis\streated\sas\san\serror. -D 2016-10-26T12:15:41.516 +C Add\sextra\stests\sto\scheck\sthe\sresult\sof\sincluding\sa\s%00\sescape\sin\sa\sURI\nwhen\sENABLE_URI_00_ERROR\sis\sdefined. +D 2016-10-26T13:44:07.443 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -1337,7 +1337,7 @@ F test/unixexcl.test d936ba2b06794018e136418addd59a2354eeae97 F test/unordered.test ca7adce0419e4ca0c50f039885e76ed2c531eda8 F test/update.test 6c68446b8a0a33d522a7c72b320934596a2d7d32 F test/uri.test 3481026f00ade6dfe8adb7acb6e1e47b04369568 -F test/uri2.test 9d493160caf4f9906cc72d6fa3b19dba91265a70 +F test/uri2.test 9d3ba7a53ee167572d53a298ee4a5d38ec4a8fb7 F test/userauth01.test e740a2697a7b40d7c5003a7d7edaee16acd349a9 F test/utf16align.test 54cd35a27c005a9b6e7815d887718780b6a462ae F test/vacuum.test ce91c39f7f91a4273bf620efad21086b5aa6ef1d @@ -1528,10 +1528,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b115856408b6aa5538be67beb619d7aff0630bea -R e2d2bf4e59ce1ff8b210e1974b182dc4 -T *branch * uri-00-error -T *sym-uri-00-error * -T -sym-trunk * +P e8a9bfece27e2af178a206ad6bce3f24d64e7ee4 +R 2575c94e1207131d6b2a9b2da34d054b U dan -Z 46faa36cce6bb438993a61c047f9eda6 +Z 48feeea4819ce0b9454532b781e85fc2 diff --git a/manifest.uuid b/manifest.uuid index 2facc36c58..8de5365eb0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e8a9bfece27e2af178a206ad6bce3f24d64e7ee4 \ No newline at end of file +1aaa06e37f44309c62335d8eda59ca6890d4be9d \ No newline at end of file diff --git a/test/uri2.test b/test/uri2.test index 91b0578d10..52feb7b50f 100644 --- a/test/uri2.test +++ b/test/uri2.test @@ -36,11 +36,22 @@ foreach {tn uri} { list $rc $msg } {1 {unexpected %00 in uri}} + do_test 1.$tn.2 { + set DB2 [sqlite3_open $uri] + sqlite3_errcode $DB2 + } {SQLITE_ERROR} + + catch { sqlite3_close $DB2 } + do_test 1.$tn.2 { sqlite3 db "" catchsql { ATTACH $uri AS aux } } {1 {unexpected %00 in uri}} + do_test 1.$tn.3 { + sqlite3_errcode db + } {SQLITE_ERROR} + catch { db close } } From b40897ab5eae337f3abfb7518c6921d0054e78aa Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 26 Oct 2016 15:46:09 +0000 Subject: [PATCH 0938/1484] If all branches of an OR optimize scan that is the rhs of a LEFT JOIN use the same index, set the index cursor to return NULL values if there are no matches for a row on the lhs. FossilOrigin-Name: e7b9bc678ecb75c594d9d3ade12a99a8d551cdc9 --- manifest | 20 +++++++------ manifest.uuid | 2 +- src/where.c | 10 ++++--- test/whereD.test | 77 ++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 95 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index 08e0334a9c..64c4d72a0f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sthe\sSQLITE_ENABLE_URI_00_ERROR\scompile-time\soption. -D 2016-10-26T13:58:47.701 +C If\sall\sbranches\sof\san\sOR\soptimize\sscan\sthat\sis\sthe\srhs\sof\sa\sLEFT\sJOIN\suse\sthe\nsame\sindex,\sset\sthe\sindex\scursor\sto\sreturn\sNULL\svalues\sif\sthere\sare\sno\smatches\nfor\sa\srow\son\sthe\slhs. +D 2016-10-26T15:46:09.768 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -468,7 +468,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 0b44e89742024d3b6992bf404d2ab692113e1e60 F src/wal.h bf03a23da3100ab25e5c0363450233cfee09cfc2 F src/walker.c 91a6df7435827e41cff6bb7df50ea00934ee78b0 -F src/where.c 5f846d94bb3d35b3146d9915eb301ee362957b0a +F src/where.c 125af074723cf390d0e71ed1ca385240e6d4ea7c F src/whereInt.h 2bcc3d176e6091cb8f50a30b65c006e88a73614d F src/wherecode.c 717a65294df46f30e9b9933d2a63a4bcbca5a9a8 F src/whereexpr.c 379d0017fb7bc9e5a4d8cd4b056c747de946430e @@ -1411,7 +1411,7 @@ F test/where9.test 729c3ba9b47e8f9f1aab96bae7dad2a524f1d1a2 F test/whereA.test 4d253178d135ec46d1671e440cd8f2b916aa6e6b F test/whereB.test 0def95db3bdec220a731c7e4bec5930327c1d8c5 F test/whereC.test cae295158703cb3fc23bf1a108a9ab730efff0f6 -F test/whereD.test 51366b07cb6f546cd30cc803f7e754f063b940de +F test/whereD.test 711d4df58d6d4fb9b3f5ce040b818564198be002 F test/whereE.test b3a055eef928c992b0a33198a7b8dc10eea5ad2f F test/whereF.test 5b2ba0dbe8074aa13e416b37c753991f0a2492d7 F test/whereG.test dde4c52a97385a55be6a7cd46be8373f0cf35501 @@ -1528,8 +1528,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b115856408b6aa5538be67beb619d7aff0630bea 1aaa06e37f44309c62335d8eda59ca6890d4be9d -R 2575c94e1207131d6b2a9b2da34d054b -T +closed 1aaa06e37f44309c62335d8eda59ca6890d4be9d -U drh -Z e54eab78f5c7dec3e7cf474d4365bacf +P 86675ae0abc78960a2faec55d115804acfc3be6d +R c240eb27502d404e84b4aff903524b82 +T *branch * leftjoin-or-fix +T *sym-leftjoin-or-fix * +T -sym-trunk * +U dan +Z e658c0fae6fabdecf9bbfe3c9f4a5ad1 diff --git a/manifest.uuid b/manifest.uuid index 7a8e3f00f4..e0be9f7b69 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -86675ae0abc78960a2faec55d115804acfc3be6d \ No newline at end of file +e7b9bc678ecb75c594d9d3ade12a99a8d551cdc9 \ No newline at end of file diff --git a/src/where.c b/src/where.c index c75eb943f3..d77c333c34 100644 --- a/src/where.c +++ b/src/where.c @@ -4860,13 +4860,15 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ } #endif if( pLevel->iLeftJoin ){ + int ws = pLoop->wsFlags; addr = sqlite3VdbeAddOp1(v, OP_IfPos, pLevel->iLeftJoin); VdbeCoverage(v); - assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 - || (pLoop->wsFlags & WHERE_INDEXED)!=0 ); - if( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 ){ + assert( (ws & WHERE_IDX_ONLY)==0 || (ws & WHERE_INDEXED)!=0 ); + if( (ws & WHERE_IDX_ONLY)==0 ){ sqlite3VdbeAddOp1(v, OP_NullRow, pTabList->a[i].iCursor); } - if( pLoop->wsFlags & WHERE_INDEXED ){ + if( (ws & WHERE_INDEXED) + || ((ws & WHERE_MULTI_OR) && pLevel->u.pCovidx) + ){ sqlite3VdbeAddOp1(v, OP_NullRow, pLevel->iIdxCur); } if( pLevel->op==OP_Return ){ diff --git a/test/whereD.test b/test/whereD.test index de0f9618d2..8ced0ffc72 100644 --- a/test/whereD.test +++ b/test/whereD.test @@ -337,4 +337,81 @@ do_searchcount_test 6.6.4 { SELECT c FROM x1 WHERE b=6 OR c=11 OR a=1 } {7 11 3 search 7} +#------------------------------------------------------------------------- +# +do_execsql_test 7.0 { + CREATE TABLE y1(a, b); + CREATE TABLE y2(x, y); + CREATE INDEX y2xy ON y2(x, y); + INSERT INTO y1 VALUES(1, 1); + INSERT INTO y2 VALUES(3, 3); +} + +do_execsql_test 7.1 { + SELECT * FROM y1 LEFT JOIN y2 ON ((x=1 AND y=b) OR (x=2 AND y=b)) +} {1 1 {} {}} + +do_execsql_test 7.3 { + CREATE TABLE foo (Id INTEGER PRIMARY KEY, fa INTEGER, fb INTEGER); + CREATE TABLE bar (Id INTEGER PRIMARY KEY, ba INTEGER, bb INTEGER); + + INSERT INTO foo VALUES(1, 1, 1); + INSERT INTO foo VALUES(2, 1, 2); + INSERT INTO foo VALUES(3, 1, 3); + INSERT INTO foo VALUES(4, 1, 4); + INSERT INTO foo VALUES(5, 1, 5); + INSERT INTO foo VALUES(6, 1, 6); + INSERT INTO foo VALUES(7, 1, 7); + INSERT INTO foo VALUES(8, 1, 8); + INSERT INTO foo VALUES(9, 1, 9); + + INSERT INTO bar VALUES(NULL, 1, 1); + INSERT INTO bar VALUES(NULL, 2, 2); + INSERT INTO bar VALUES(NULL, 3, 3); + INSERT INTO bar VALUES(NULL, 1, 4); + INSERT INTO bar VALUES(NULL, 2, 5); + INSERT INTO bar VALUES(NULL, 3, 6); + INSERT INTO bar VALUES(NULL, 1, 7); + INSERT INTO bar VALUES(NULL, 2, 8); + INSERT INTO bar VALUES(NULL, 3, 9); +} + +do_execsql_test 7.4 { + SELECT + bar.Id, bar.ba, bar.bb, foo.fb + FROM foo LEFT JOIN bar + ON (bar.ba = 1 AND bar.bb = foo.fb) + OR (bar.ba = 5 AND bar.bb = foo.fb); +} { + 1 1 1 1 + {} {} {} 2 + {} {} {} 3 + 4 1 4 4 + {} {} {} 5 + {} {} {} 6 + 7 1 7 7 + {} {} {} 8 + {} {} {} 9 +} + +do_execsql_test 7.5 { + CREATE INDEX idx_bar ON bar(ba, bb); + SELECT + bar.Id, bar.ba, bar.bb, foo.fb + FROM foo LEFT JOIN bar + ON (bar.ba = 1 AND bar.bb = foo.fb) + OR (bar.ba = 5 AND bar.bb = foo.fb); +} { + 1 1 1 1 + {} {} {} 2 + {} {} {} 3 + 4 1 4 4 + {} {} {} 5 + {} {} {} 6 + 7 1 7 7 + {} {} {} 8 + {} {} {} 9 +} + + finish_test From 392ddeb12d2bbf18e117ec9f5ef42d25047afd9a Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 26 Oct 2016 17:57:40 +0000 Subject: [PATCH 0939/1484] Small size reduction and performance improvement in whereScanNext(). FossilOrigin-Name: d861ee17eb900a607de6ec3f4a5d5c24cfb834a0 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/where.c | 17 +++++++++++------ 3 files changed, 19 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index 1d41c53d85..82d6964d00 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C If\sall\sbranches\sof\san\sOR\soptimize\sscan\sthat\sis\sthe\srhs\sof\sa\sLEFT\sJOIN\suse\sthe\nsame\sindex,\sset\sthe\sindex\scursor\sto\sreturn\sNULL\svalues\sif\sthere\sare\sno\smatches\nfor\sa\srow\son\sthe\slhs. -D 2016-10-26T16:05:10.157 +C Small\ssize\sreduction\sand\sperformance\simprovement\sin\swhereScanNext(). +D 2016-10-26T17:57:40.045 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -468,7 +468,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 0b44e89742024d3b6992bf404d2ab692113e1e60 F src/wal.h bf03a23da3100ab25e5c0363450233cfee09cfc2 F src/walker.c 91a6df7435827e41cff6bb7df50ea00934ee78b0 -F src/where.c 125af074723cf390d0e71ed1ca385240e6d4ea7c +F src/where.c 694dd84a7017f2b284e1da55b5bf00bfd3e1f4e4 F src/whereInt.h 2bcc3d176e6091cb8f50a30b65c006e88a73614d F src/wherecode.c 717a65294df46f30e9b9933d2a63a4bcbca5a9a8 F src/whereexpr.c 379d0017fb7bc9e5a4d8cd4b056c747de946430e @@ -1528,7 +1528,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 86675ae0abc78960a2faec55d115804acfc3be6d e7b9bc678ecb75c594d9d3ade12a99a8d551cdc9 -R c240eb27502d404e84b4aff903524b82 -U dan -Z 498360080b36f95cb7f4a5ed51292736 +P ec9dab8054c71d112c68f58a45821b38c2a45677 +R 48fa39390c766bcfb2f028645ad7c897 +U drh +Z 1bf2b72e2a8cf9aca52b2af50acc10fd diff --git a/manifest.uuid b/manifest.uuid index 58c86f842e..7dd85778b9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ec9dab8054c71d112c68f58a45821b38c2a45677 \ No newline at end of file +d861ee17eb900a607de6ec3f4a5d5c24cfb834a0 \ No newline at end of file diff --git a/src/where.c b/src/where.c index d77c333c34..6395d86659 100644 --- a/src/where.c +++ b/src/where.c @@ -198,11 +198,14 @@ static WhereTerm *whereScanNext(WhereScan *pScan){ WhereTerm *pTerm; /* The term being tested */ int k = pScan->k; /* Where to start scanning */ - while( pScan->iEquiv<=pScan->nEquiv ){ - iCur = pScan->aiCur[pScan->iEquiv-1]; + assert( pScan->iEquiv<=pScan->nEquiv ); + pWC = pScan->pWC; + while(1){ iColumn = pScan->aiColumn[pScan->iEquiv-1]; if( iColumn==XN_EXPR && pScan->pIdxExpr==0 ) return 0; - while( (pWC = pScan->pWC)!=0 ){ + iCur = pScan->aiCur[pScan->iEquiv-1]; + assert( pWC!=0 ); + do{ for(pTerm=pWC->a+k; knTerm; k++, pTerm++){ if( pTerm->leftCursor==iCur && pTerm->u.leftColumn==iColumn @@ -252,15 +255,17 @@ static WhereTerm *whereScanNext(WhereScan *pScan){ testcase( pTerm->eOperator & WO_IS ); continue; } + pScan->pWC = pWC; pScan->k = k+1; return pTerm; } } } - pScan->pWC = pScan->pWC->pOuter; + pWC = pWC->pOuter; k = 0; - } - pScan->pWC = pScan->pOrigWC; + }while( pWC!=0 ); + if( pScan->iEquiv>=pScan->nEquiv ) break; + pWC = pScan->pOrigWC; k = 0; pScan->iEquiv++; } From 9904298bb35292112d0cc7ff37d3fbff202502ed Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 26 Oct 2016 18:41:43 +0000 Subject: [PATCH 0940/1484] Small size reduction and performance enhancement in whereScanInit(). FossilOrigin-Name: c23f5ef337533c1ec6e3ba78a2910352181cc9ee --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/where.c | 27 +++++++++++++-------------- 3 files changed, 20 insertions(+), 21 deletions(-) diff --git a/manifest b/manifest index 82d6964d00..cc4cce49cf 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Small\ssize\sreduction\sand\sperformance\simprovement\sin\swhereScanNext(). -D 2016-10-26T17:57:40.045 +C Small\ssize\sreduction\sand\sperformance\senhancement\sin\swhereScanInit(). +D 2016-10-26T18:41:43.441 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -468,7 +468,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 0b44e89742024d3b6992bf404d2ab692113e1e60 F src/wal.h bf03a23da3100ab25e5c0363450233cfee09cfc2 F src/walker.c 91a6df7435827e41cff6bb7df50ea00934ee78b0 -F src/where.c 694dd84a7017f2b284e1da55b5bf00bfd3e1f4e4 +F src/where.c 952f76e7a03727480b274b66ca6641b1657cd591 F src/whereInt.h 2bcc3d176e6091cb8f50a30b65c006e88a73614d F src/wherecode.c 717a65294df46f30e9b9933d2a63a4bcbca5a9a8 F src/whereexpr.c 379d0017fb7bc9e5a4d8cd4b056c747de946430e @@ -1528,7 +1528,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ec9dab8054c71d112c68f58a45821b38c2a45677 -R 48fa39390c766bcfb2f028645ad7c897 +P d861ee17eb900a607de6ec3f4a5d5c24cfb834a0 +R bd2e0f7c23b42c2ba66bc7a6e23d9160 U drh -Z 1bf2b72e2a8cf9aca52b2af50acc10fd +Z f746697b9b9d8bf9f72c796f60e10bfb diff --git a/manifest.uuid b/manifest.uuid index 7dd85778b9..1910fbafb6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d861ee17eb900a607de6ec3f4a5d5c24cfb834a0 \ No newline at end of file +c23f5ef337533c1ec6e3ba78a2910352181cc9ee \ No newline at end of file diff --git a/src/where.c b/src/where.c index 6395d86659..ddcb2fc881 100644 --- a/src/where.c +++ b/src/where.c @@ -202,7 +202,6 @@ static WhereTerm *whereScanNext(WhereScan *pScan){ pWC = pScan->pWC; while(1){ iColumn = pScan->aiColumn[pScan->iEquiv-1]; - if( iColumn==XN_EXPR && pScan->pIdxExpr==0 ) return 0; iCur = pScan->aiCur[pScan->iEquiv-1]; assert( pWC!=0 ); do{ @@ -299,24 +298,24 @@ static WhereTerm *whereScanInit( u32 opMask, /* Operator(s) to scan for */ Index *pIdx /* Must be compatible with this index */ ){ - int j = 0; - - /* memset(pScan, 0, sizeof(*pScan)); */ pScan->pOrigWC = pWC; pScan->pWC = pWC; pScan->pIdxExpr = 0; + pScan->idxaff = 0; + pScan->zCollName = 0; if( pIdx ){ - j = iColumn; + int j = iColumn; iColumn = pIdx->aiColumn[j]; - if( iColumn==XN_EXPR ) pScan->pIdxExpr = pIdx->aColExpr->a[j].pExpr; - if( iColumn==pIdx->pTable->iPKey ) iColumn = XN_ROWID; - } - if( pIdx && iColumn>=0 ){ - pScan->idxaff = pIdx->pTable->aCol[iColumn].affinity; - pScan->zCollName = pIdx->azColl[j]; - }else{ - pScan->idxaff = 0; - pScan->zCollName = 0; + if( iColumn==XN_EXPR ){ + pScan->pIdxExpr = pIdx->aColExpr->a[j].pExpr; + }else if( iColumn==pIdx->pTable->iPKey ){ + iColumn = XN_ROWID; + }else if( iColumn>=0 ){ + pScan->idxaff = pIdx->pTable->aCol[iColumn].affinity; + pScan->zCollName = pIdx->azColl[j]; + } + }else if( iColumn==XN_EXPR ){ + return 0; } pScan->opMask = opMask; pScan->k = 0; From c52496f57f5fc3026818ceb443ed06200b24228f Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 27 Oct 2016 01:02:20 +0000 Subject: [PATCH 0941/1484] Make sure left-join markings are transferred to the virtual scalar subexpressions when decomposing a vector comparison in the ON clause of a LEFT JOIN. Fix for ticket [fef4bb4bd9185ec8f]. FossilOrigin-Name: 619f5cc71774a37648e185c8502d7af14eb09b7f --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/whereexpr.c | 1 + test/rowvalue.test | 10 ++++++++++ 4 files changed, 19 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index cc4cce49cf..c2b23b0693 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Small\ssize\sreduction\sand\sperformance\senhancement\sin\swhereScanInit(). -D 2016-10-26T18:41:43.441 +C Make\ssure\sleft-join\smarkings\sare\stransferred\sto\sthe\svirtual\sscalar\nsubexpressions\swhen\sdecomposing\sa\svector\scomparison\sin\sthe\sON\sclause\sof\na\sLEFT\sJOIN.\nFix\sfor\sticket\s[fef4bb4bd9185ec8f]. +D 2016-10-27T01:02:20.511 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -471,7 +471,7 @@ F src/walker.c 91a6df7435827e41cff6bb7df50ea00934ee78b0 F src/where.c 952f76e7a03727480b274b66ca6641b1657cd591 F src/whereInt.h 2bcc3d176e6091cb8f50a30b65c006e88a73614d F src/wherecode.c 717a65294df46f30e9b9933d2a63a4bcbca5a9a8 -F src/whereexpr.c 379d0017fb7bc9e5a4d8cd4b056c747de946430e +F src/whereexpr.c a83d70154f3bbce5051a7e9710021f647c0fe4f2 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1025,7 +1025,7 @@ F test/rollbackfault.test 0e646aeab8840c399cfbfa43daab46fd609cf04a F test/rowallock.test 3f88ec6819489d0b2341c7a7528ae17c053ab7cc F test/rowhash.test 0bc1d31415e4575d10cacf31e1a66b5cc0f8be81 F test/rowid.test 5b7509f384f4f6fae1af3c8c104c8ca299fea18d -F test/rowvalue.test 753eb744b7efeb5ac643d35d6e1e5066452ccf79 +F test/rowvalue.test bcd78c91fe2aadade6fd00d2616546650b9ebc9e F test/rowvalue2.test 060d238b7e5639a7c5630cb5e63e311b44efef2b F test/rowvalue3.test 01399b7bf150b0d41abce76c18072da777c2500c F test/rowvalue4.test 4b556d7de161a0dd8cff095c336e913986398bea @@ -1528,7 +1528,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d861ee17eb900a607de6ec3f4a5d5c24cfb834a0 -R bd2e0f7c23b42c2ba66bc7a6e23d9160 +P c23f5ef337533c1ec6e3ba78a2910352181cc9ee +R 724eaf97bc578ade21f74a2fb4242a1f U drh -Z f746697b9b9d8bf9f72c796f60e10bfb +Z c2d38a18abbe8465fdc3725d309eaa8d diff --git a/manifest.uuid b/manifest.uuid index 1910fbafb6..9ce2df9527 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c23f5ef337533c1ec6e3ba78a2910352181cc9ee \ No newline at end of file +619f5cc71774a37648e185c8502d7af14eb09b7f \ No newline at end of file diff --git a/src/whereexpr.c b/src/whereexpr.c index 7406a3bf9a..40075bedee 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -1198,6 +1198,7 @@ static void exprAnalyze( Expr *pRight = sqlite3ExprForVectorField(pParse, pExpr->pRight, i); pNew = sqlite3PExpr(pParse, pExpr->op, pLeft, pRight, 0); + transferJoinMarkings(pNew, pExpr); idxNew = whereClauseInsert(pWC, pNew, TERM_DYNAMIC); exprAnalyze(pSrc, pWC, idxNew); } diff --git a/test/rowvalue.test b/test/rowvalue.test index f53d5328ca..6ab1154b50 100644 --- a/test/rowvalue.test +++ b/test/rowvalue.test @@ -255,5 +255,15 @@ do_catchsql_test 11.8 { SELECT * FROM t11 WHERE (a,a) IS NOT 1; } {1 {row value misused}} +# 2016-10-27: https://www.sqlite.org/src/tktview/fef4bb4bd9185ec8f +# Incorrect result from a LEFT JOIN with a row-value constraint +# +do_execsql_test 12.1 { + DROP TABLE IF EXISTS t1; + CREATE TABLE t1(a,b); INSERT INTO t1 VALUES(1,2); + DROP TABLE IF EXISTS t2; + CREATE TABLE t2(x,y); INSERT INTO t2 VALUES(3,4); + SELECT *,'x' FROM t1 LEFT JOIN t2 ON (a,b)=(x,y); +} {1 2 {} {} x} finish_test From dadafa881f60459abb1c45d1bfca40256de82d1e Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 27 Oct 2016 14:51:02 +0000 Subject: [PATCH 0942/1484] Remove the mutex from test_multiplex.c. FossilOrigin-Name: 6374978e8f1ac091394a9f5a1896be92af658bcd --- manifest | 16 +++--- manifest.uuid | 2 +- src/test_multiplex.c | 122 ------------------------------------------- test/multiplex.test | 21 ++++---- 4 files changed, 18 insertions(+), 143 deletions(-) diff --git a/manifest b/manifest index c2b23b0693..9b6c0b8340 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\ssure\sleft-join\smarkings\sare\stransferred\sto\sthe\svirtual\sscalar\nsubexpressions\swhen\sdecomposing\sa\svector\scomparison\sin\sthe\sON\sclause\sof\na\sLEFT\sJOIN.\nFix\sfor\sticket\s[fef4bb4bd9185ec8f]. -D 2016-10-27T01:02:20.511 +C Remove\sthe\smutex\sfrom\stest_multiplex.c. +D 2016-10-27T14:51:02.086 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -425,7 +425,7 @@ F src/test_intarray.h f3b7672f5d1056eac563c0d6ea8480a660b1475c F src/test_journal.c d3b83f2bcb7792c709e57abddc456a2b1818643a F src/test_loadext.c 337056bae59f80b9eb00ba82088b39d0f4fe6dfd F src/test_malloc.c c05f6c40bd6c8bfe5f1718212f81fd5687f91766 -F src/test_multiplex.c 7c5b218d855cd0505a43185d55283b3fc257c8da +F src/test_multiplex.c e054459f7633f3ff8ce1245da724f9a8be189e4e F src/test_multiplex.h 5436d03f2d0501d04f3ed50a75819e190495b635 F src/test_mutex.c 7f4337ba23ee6b1d2ec81c189653608cb069926a F src/test_onefile.c 416f87a28d6d673352d33fc4b1c7d39db878e50f @@ -955,7 +955,7 @@ F test/mmap2.test 9d6dd9ddb4ad2379f29cc78f38ce1e63ed418022 F test/mmap3.test b3c297e78e6a8520aafcc1a8f140535594c9086e F test/mmap4.test 2e2b4e32555b58da15176e6fe750f17c9dcf7f93 F test/mmapfault.test d4c9eff9cd8c2dc14bc43e71e042f175b0a26fe3 -F test/multiplex.test efd015ca0b5b4a57dc9535b8feb1273eebeadb60 +F test/multiplex.test dc0d67b66f84b484a83cb8bbdf3f0a7f49562ccd F test/multiplex2.test 580ca5817c7edbe4cc68fa150609c9473393003a F test/multiplex3.test d228f59eac91839a977eac19f21d053f03e4d101 F test/multiplex4.test e8ae4c4bd70606a5727743241f13b5701990abe4 @@ -1528,7 +1528,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P c23f5ef337533c1ec6e3ba78a2910352181cc9ee -R 724eaf97bc578ade21f74a2fb4242a1f -U drh -Z c2d38a18abbe8465fdc3725d309eaa8d +P 619f5cc71774a37648e185c8502d7af14eb09b7f +R 93e0c879ea55a634df6077f40936fbef +U dan +Z 9550a31672ece71cb80aa7996bb9624a diff --git a/manifest.uuid b/manifest.uuid index 9ce2df9527..ebc8ce5350 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -619f5cc71774a37648e185c8502d7af14eb09b7f \ No newline at end of file +6374978e8f1ac091394a9f5a1896be92af658bcd \ No newline at end of file diff --git a/src/test_multiplex.c b/src/test_multiplex.c index 1027aa1326..ed8c9f7fa7 100644 --- a/src/test_multiplex.c +++ b/src/test_multiplex.c @@ -68,19 +68,6 @@ #define MAX_PAGE_SIZE 0x10000 #define DEFAULT_SECTOR_SIZE 0x1000 -/* -** For a build without mutexes, no-op the mutex calls. -*/ -#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE==0 -#define sqlite3_mutex_alloc(X) ((sqlite3_mutex*)8) -#define sqlite3_mutex_free(X) -#define sqlite3_mutex_enter(X) -#define sqlite3_mutex_try(X) SQLITE_OK -#define sqlite3_mutex_leave(X) -#define sqlite3_mutex_held(X) ((void)(X),1) -#define sqlite3_mutex_notheld(X) ((void)(X),1) -#endif /* SQLITE_THREADSAFE==0 */ - /* Maximum chunk number */ #define MX_CHUNK_NUMBER 299 @@ -139,7 +126,6 @@ struct multiplexGroup { unsigned int szChunk; /* Chunk size used for this group */ unsigned char bEnabled; /* TRUE to use Multiplex VFS for this file */ unsigned char bTruncate; /* TRUE to enable truncation of databases */ - multiplexGroup *pNext, *pPrev; /* Doubly linked list of all group objects */ }; /* @@ -187,28 +173,9 @@ static struct { /* True when this shim has been initialized. */ int isInitialized; - - /* For run-time access any of the other global data structures in this - ** shim, the following mutex must be held. In practice, all this mutex - ** protects is add/remove operations to/from the linked list of group objects - ** starting at pGroups below. More specifically, it protects the value of - ** pGroups itself, and the pNext/pPrev fields of each multiplexGroup - ** structure. */ - sqlite3_mutex *pMutex; - - /* List of multiplexGroup objects. - */ - multiplexGroup *pGroups; } gMultiplex; /************************* Utility Routines *********************************/ -/* -** Acquire and release the mutex used to serialize access to the -** list of multiplexGroups. -*/ -static void multiplexEnter(void){ sqlite3_mutex_enter(gMultiplex.pMutex); } -static void multiplexLeave(void){ sqlite3_mutex_leave(gMultiplex.pMutex); } - /* ** Compute a string length that is limited to what can be stored in ** lower 30 bits of a 32-bit signed integer. @@ -519,7 +486,6 @@ static int multiplexOpen( /* We need to create a group structure and manage ** access to this group of files. */ - multiplexEnter(); pMultiplexOpen = (multiplexConn*)pConn; if( rc==SQLITE_OK ){ @@ -626,16 +592,11 @@ static int multiplexOpen( }else{ pMultiplexOpen->base.pMethods = &gMultiplex.sIoMethodsV2; } - /* place this group at the head of our list */ - pGroup->pNext = gMultiplex.pGroups; - if( gMultiplex.pGroups ) gMultiplex.pGroups->pPrev = pGroup; - gMultiplex.pGroups = pGroup; }else{ multiplexFreeComponents(pGroup); sqlite3_free(pGroup); } } - multiplexLeave(); sqlite3_free(zToFree); return rc; } @@ -738,17 +699,8 @@ static int multiplexClose(sqlite3_file *pConn){ multiplexConn *p = (multiplexConn*)pConn; multiplexGroup *pGroup = p->pGroup; int rc = SQLITE_OK; - multiplexEnter(); multiplexFreeComponents(pGroup); - /* remove from linked list */ - if( pGroup->pNext ) pGroup->pNext->pPrev = pGroup->pPrev; - if( pGroup->pPrev ){ - pGroup->pPrev->pNext = pGroup->pNext; - }else{ - gMultiplex.pGroups = pGroup->pNext; - } sqlite3_free(pGroup); - multiplexLeave(); return rc; } @@ -845,7 +797,6 @@ static int multiplexTruncate(sqlite3_file *pConn, sqlite3_int64 size){ multiplexConn *p = (multiplexConn*)pConn; multiplexGroup *pGroup = p->pGroup; int rc = SQLITE_OK; - multiplexEnter(); if( !pGroup->bEnabled ){ sqlite3_file *pSubOpen = multiplexSubOpen(pGroup, 0, &rc, NULL, 0); if( pSubOpen==0 ){ @@ -877,7 +828,6 @@ static int multiplexTruncate(sqlite3_file *pConn, sqlite3_int64 size){ } if( rc ) rc = SQLITE_IOERR_TRUNCATE; } - multiplexLeave(); return rc; } @@ -888,7 +838,6 @@ static int multiplexSync(sqlite3_file *pConn, int flags){ multiplexGroup *pGroup = p->pGroup; int rc = SQLITE_OK; int i; - multiplexEnter(); for(i=0; inReal; i++){ sqlite3_file *pSubOpen = pGroup->aReal[i].p; if( pSubOpen ){ @@ -896,7 +845,6 @@ static int multiplexSync(sqlite3_file *pConn, int flags){ if( rc2!=SQLITE_OK ) rc = rc2; } } - multiplexLeave(); return rc; } @@ -908,7 +856,6 @@ static int multiplexFileSize(sqlite3_file *pConn, sqlite3_int64 *pSize){ multiplexGroup *pGroup = p->pGroup; int rc = SQLITE_OK; int i; - multiplexEnter(); if( !pGroup->bEnabled ){ sqlite3_file *pSubOpen = multiplexSubOpen(pGroup, 0, &rc, NULL, 0); if( pSubOpen==0 ){ @@ -924,7 +871,6 @@ static int multiplexFileSize(sqlite3_file *pConn, sqlite3_int64 *pSize){ *pSize = i*(sqlite3_int64)pGroup->szChunk + sz; } } - multiplexLeave(); return rc; } @@ -1151,11 +1097,6 @@ int sqlite3_multiplex_initialize(const char *zOrigVfsName, int makeDefault){ pOrigVfs = sqlite3_vfs_find(zOrigVfsName); if( pOrigVfs==0 ) return SQLITE_ERROR; assert( pOrigVfs!=&gMultiplex.sThisVfs ); - gMultiplex.pMutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); - if( !gMultiplex.pMutex ){ - return SQLITE_NOMEM; - } - gMultiplex.pGroups = NULL; gMultiplex.isInitialized = 1; gMultiplex.pOrigVfs = pOrigVfs; gMultiplex.sThisVfs = *pOrigVfs; @@ -1214,14 +1155,7 @@ int sqlite3_multiplex_initialize(const char *zOrigVfsName, int makeDefault){ int sqlite3_multiplex_shutdown(int eForce){ int rc = SQLITE_OK; if( gMultiplex.isInitialized==0 ) return SQLITE_MISUSE; - if( gMultiplex.pGroups ){ - sqlite3_log(SQLITE_MISUSE, "sqlite3_multiplex_shutdown() called " - "while database connections are still open"); - if( !eForce ) return SQLITE_MISUSE; - rc = SQLITE_MISUSE; - } gMultiplex.isInitialized = 0; - sqlite3_mutex_free(gMultiplex.pMutex); sqlite3_vfs_unregister(&gMultiplex.sThisVfs); memset(&gMultiplex, 0, sizeof(gMultiplex)); return rc; @@ -1299,61 +1233,6 @@ static int SQLITE_TCLAPI test_multiplex_shutdown( return TCL_OK; } -/* -** tclcmd: sqlite3_multiplex_dump -*/ -static int SQLITE_TCLAPI test_multiplex_dump( - void * clientData, - Tcl_Interp *interp, - int objc, - Tcl_Obj *CONST objv[] -){ - Tcl_Obj *pResult; - Tcl_Obj *pGroupTerm; - multiplexGroup *pGroup; - int i; - int nChunks = 0; - - UNUSED_PARAMETER(clientData); - UNUSED_PARAMETER(objc); - UNUSED_PARAMETER(objv); - - pResult = Tcl_NewObj(); - multiplexEnter(); - for(pGroup=gMultiplex.pGroups; pGroup; pGroup=pGroup->pNext){ - pGroupTerm = Tcl_NewObj(); - - if( pGroup->zName ){ - pGroup->zName[pGroup->nName] = '\0'; - Tcl_ListObjAppendElement(interp, pGroupTerm, - Tcl_NewStringObj(pGroup->zName, -1)); - }else{ - Tcl_ListObjAppendElement(interp, pGroupTerm, Tcl_NewObj()); - } - Tcl_ListObjAppendElement(interp, pGroupTerm, - Tcl_NewIntObj(pGroup->nName)); - Tcl_ListObjAppendElement(interp, pGroupTerm, - Tcl_NewIntObj(pGroup->flags)); - - /* count number of chunks with open handles */ - for(i=0; inReal; i++){ - if( pGroup->aReal[i].p!=0 ) nChunks++; - } - Tcl_ListObjAppendElement(interp, pGroupTerm, - Tcl_NewIntObj(nChunks)); - - Tcl_ListObjAppendElement(interp, pGroupTerm, - Tcl_NewIntObj(pGroup->szChunk)); - Tcl_ListObjAppendElement(interp, pGroupTerm, - Tcl_NewIntObj(pGroup->nReal)); - - Tcl_ListObjAppendElement(interp, pResult, pGroupTerm); - } - multiplexLeave(); - Tcl_SetObjResult(interp, pResult); - return TCL_OK; -} - /* ** Tclcmd: test_multiplex_control HANDLE DBNAME SUB-COMMAND ?INT-VALUE? */ @@ -1428,7 +1307,6 @@ int Sqlitemultiplex_Init(Tcl_Interp *interp){ } aCmd[] = { { "sqlite3_multiplex_initialize", test_multiplex_initialize }, { "sqlite3_multiplex_shutdown", test_multiplex_shutdown }, - { "sqlite3_multiplex_dump", test_multiplex_dump }, { "sqlite3_multiplex_control", test_multiplex_control }, }; int i; diff --git a/test/multiplex.test b/test/multiplex.test index 5db56f264a..6ea328906e 100644 --- a/test/multiplex.test +++ b/test/multiplex.test @@ -195,15 +195,16 @@ do_test multiplex-2.3.1 { unset -nocomplain ::log -do_test multiplex-2.4.1 { - sqlite3_multiplex_shutdown -} {SQLITE_MISUSE} +#do_test multiplex-2.4.1 { +# sqlite3_multiplex_shutdown +#} {SQLITE_MISUSE} do_test multiplex-2.4.2 { execsql { INSERT INTO t1 VALUES(3, randomblob(1100)) } } {} -do_test multiplex-2.4.3 { - set ::log -} {SQLITE_MISUSE {sqlite3_multiplex_shutdown() called while database connections are still open}} +#do_test multiplex-2.4.3 { +# set ::log +#} {SQLITE_MISUSE {sqlite3_multiplex_shutdown() called while database connections are still open}} + do_test multiplex-2.4.4 { file size [multiplex_name test.x 0] } {7168} do_test multiplex-2.4.5 { db close @@ -445,11 +446,7 @@ multiplex_set db main 32768 16 # Return a list of all currently defined multiplexs. proc multiplex_list {} { - set allq {} - foreach q [sqlite3_multiplex_dump] { - lappend allq [lindex $q 0] - } - return [lsort $allq] + glob -nocomplain test2.db* } do_test multiplex-4.1.6 { @@ -494,7 +491,7 @@ do_test multiplex-4.1.11 { do_test multiplex-4.1.12 { db close multiplex_list -} {} +} {test2.db} #------------------------------------------------------------------------- From 298af02308f870c2af7eda53cd0c8ce7ca3ab29c Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 31 Oct 2016 16:16:49 +0000 Subject: [PATCH 0943/1484] Add the SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE sqlite3_dbconfig() option - for disabling SQLite's default checkpoint-on-close behaviour. FossilOrigin-Name: 093d2fc2288b75c15ccf877bfa0e622d3918a562 --- manifest | 24 ++++++++++++--------- manifest.uuid | 2 +- src/main.c | 1 + src/sqlite.h.in | 13 ++++++++++++ src/sqliteInt.h | 1 + src/test1.c | 1 + src/wal.c | 5 +++-- test/nockpt.test | 55 ++++++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 89 insertions(+), 13 deletions(-) create mode 100644 test/nockpt.test diff --git a/manifest b/manifest index 9b6c0b8340..2ce40ccb6d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sthe\smutex\sfrom\stest_multiplex.c. -D 2016-10-27T14:51:02.086 +C Add\sthe\sSQLITE_DBCONFIG_NO_CKPT_ON_CLOSE\ssqlite3_dbconfig()\soption\s-\sfor\ndisabling\sSQLite's\sdefault\scheckpoint-on-close\sbehaviour. +D 2016-10-31T16:16:49.195 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -352,7 +352,7 @@ F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 F src/insert.c 2d5e197f2f60351937b201196965fd14cd88489c F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e F src/loadext.c 5d6642d141c07d366e43d359e94ec9de47add41d -F src/main.c 6890ce0118968d17b18ba52ce2c99166484502ab +F src/main.c 694ac90557abdaa62151a6090670e107b0f2c2ab F src/malloc.c 5ee7c2d3dcb1b0a902c9c6d0115deef54736bdfa F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b @@ -389,15 +389,15 @@ F src/resolve.c 3fac1b2737ea5a724f20b921ac7e259c9be2100b F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c ea3af83e2d0f245fef81ea4cf04cb730ce67f722 F src/shell.c f0e8b54c58a8a13cc046f5af6d72de7e0a118a2b -F src/sqlite.h.in 7ef021d74ac7d4004c784a16ad015508f171c4bf +F src/sqlite.h.in 97e9b0f952306677db82b055147ed1d99cb7ba66 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae -F src/sqliteInt.h 8d241c2c0a1a7b6611d3e9398f41d69426da850d +F src/sqliteInt.h 37628fe30c464dc790bcee3bfd3d0caa8f222ed1 F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 F src/tclsqlite.c aef87dcd8cb66564d560ab48d43d19ac812a1eab -F src/test1.c 1f1a399956c8730d5f7b09c729e98764f2082162 +F src/test1.c f52bed152c97be23be794efa234374d0de593eeb F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5 F src/test3.c d03f5b5da9a2410b7a91c64b0d3306ed28ab6fee F src/test4.c 18ec393bb4d0ad1de729f0b94da7267270f3d8e6 @@ -465,7 +465,7 @@ F src/vdbesort.c 91fda3909326860382b0ca8aa251e609c6a9d62c F src/vdbetrace.c 41963d5376f0349842b5fc4aaaaacd7d9cdc0834 F src/vtab.c e02cacb5c7ae742631edeb9ae9f53d399f093fd8 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 -F src/wal.c 0b44e89742024d3b6992bf404d2ab692113e1e60 +F src/wal.c 358ab4d296a12bc9dcb6f8974dd155ba8a9b10c4 F src/wal.h bf03a23da3100ab25e5c0363450233cfee09cfc2 F src/walker.c 91a6df7435827e41cff6bb7df50ea00934ee78b0 F src/where.c 952f76e7a03727480b274b66ca6641b1657cd591 @@ -962,6 +962,7 @@ F test/multiplex4.test e8ae4c4bd70606a5727743241f13b5701990abe4 F test/mutex1.test ea2cc74d97f077b9e74c84cbd024f14d79a8126f F test/mutex2.test bfeaeac2e73095b2ac32285d2756e3a65e681660 F test/nan.test dacc57f80859c06a433d30839336fe227d2038b3 +F test/nockpt.test faeeb1daa357d634103fd0a1d54f449e4a5b3ef1 F test/nolock.test f196cf8b8fbea4e2ca345140a2b3f3b0da45c76e F test/notify1.test 669b2b743618efdc18ca4b02f45423d5d2304abf F test/notify2.test 2ecabaa1305083856b7c39cf32816b612740c161 @@ -1528,7 +1529,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 619f5cc71774a37648e185c8502d7af14eb09b7f -R 93e0c879ea55a634df6077f40936fbef +P 6374978e8f1ac091394a9f5a1896be92af658bcd +R f901fbda939dcfa6ff6d756b39418ee6 +T *branch * no-ckpt-on-close +T *sym-no-ckpt-on-close * +T -sym-trunk * U dan -Z 9550a31672ece71cb80aa7996bb9624a +Z 07a9a1e05af7ee54e911d0aed174054e diff --git a/manifest.uuid b/manifest.uuid index ebc8ce5350..57297ff11b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6374978e8f1ac091394a9f5a1896be92af658bcd \ No newline at end of file +093d2fc2288b75c15ccf877bfa0e622d3918a562 \ No newline at end of file diff --git a/src/main.c b/src/main.c index ae25485301..666a72547b 100644 --- a/src/main.c +++ b/src/main.c @@ -810,6 +810,7 @@ int sqlite3_db_config(sqlite3 *db, int op, ...){ { SQLITE_DBCONFIG_ENABLE_TRIGGER, SQLITE_EnableTrigger }, { SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER, SQLITE_Fts3Tokenizer }, { SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, SQLITE_LoadExtension }, + { SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE, SQLITE_NoCkptOnClose }, }; unsigned int i; rc = SQLITE_ERROR; /* IMP: R-42790-23372 */ diff --git a/src/sqlite.h.in b/src/sqlite.h.in index b24a199055..f7bcdd6746 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -1988,6 +1988,18 @@ struct sqlite3_mem_methods { ** until after the database connection closes. ** ** +**

    SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE
    +**
    Usually, when a database in wal mode is closed or detached from a +** database handle, SQLite checks if this will mean that there are now no +** connections at all to the database. If so, it performs a checkpoint +** operation before closing the connection. This option may be used to +** override this behaviour. The first parameter passed to this operation +** is an integer - non-zero to disable checkpoints-on-close, or zero (the +** default) to enable them. The second parameter is a pointer to an integer +** into which is written 0 or 1 to indicate whether checkpoints-on-close +** have been disabled - 0 if they are not disabled, 1 if they are. +**
    +** ** */ #define SQLITE_DBCONFIG_MAINDBNAME 1000 /* const char* */ @@ -1996,6 +2008,7 @@ struct sqlite3_mem_methods { #define SQLITE_DBCONFIG_ENABLE_TRIGGER 1003 /* int int* */ #define SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER 1004 /* int int* */ #define SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 1005 /* int int* */ +#define SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE 1006 /* int int* */ /* diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 2d13f2635d..c0e5aa01bb 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1435,6 +1435,7 @@ struct sqlite3 { #define SQLITE_Vacuum 0x10000000 /* Currently in a VACUUM */ #define SQLITE_CellSizeCk 0x20000000 /* Check btree cell sizes on load */ #define SQLITE_Fts3Tokenizer 0x40000000 /* Enable fts3_tokenizer(2) */ +#define SQLITE_NoCkptOnClose 0x80000000 /* No checkpoint on close()/DETACH */ /* diff --git a/src/test1.c b/src/test1.c index 6c9a0ea1e6..18b6b295c2 100644 --- a/src/test1.c +++ b/src/test1.c @@ -7221,6 +7221,7 @@ static int SQLITE_TCLAPI test_sqlite3_db_config( { "TRIGGER", SQLITE_DBCONFIG_ENABLE_TRIGGER }, { "FTS3_TOKENIZER", SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER }, { "LOAD_EXTENSION", SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION }, + { "NO_CKPT_ON_CLOSE",SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE }, }; int i; int v; diff --git a/src/wal.c b/src/wal.c index 8da7639535..50b95e4169 100644 --- a/src/wal.c +++ b/src/wal.c @@ -1943,8 +1943,9 @@ int sqlite3WalClose( ** ** The EXCLUSIVE lock is not released before returning. */ - rc = sqlite3OsLock(pWal->pDbFd, SQLITE_LOCK_EXCLUSIVE); - if( rc==SQLITE_OK ){ + if( (db->flags & SQLITE_NoCkptOnClose)==0 + && SQLITE_OK==(rc = sqlite3OsLock(pWal->pDbFd, SQLITE_LOCK_EXCLUSIVE)) + ){ if( pWal->exclusiveMode==WAL_NORMAL_MODE ){ pWal->exclusiveMode = WAL_EXCLUSIVE_MODE; } diff --git a/test/nockpt.test b/test/nockpt.test new file mode 100644 index 0000000000..f24fcaa988 --- /dev/null +++ b/test/nockpt.test @@ -0,0 +1,55 @@ +# 2016 October 31 +# +# 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 regression tests for SQLite library. The +# focus of this file is testing the SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE +# option. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +source $testdir/lock_common.tcl +source $testdir/malloc_common.tcl +source $testdir/wal_common.tcl +ifcapable !wal {finish_test ; return } + +set testprefix nockpt + +do_execsql_test 1.0 { + PRAGMA page_size = 1024; + PRAGMA journal_mode = wal; + CREATE TABLE c1(x, y, z); + INSERT INTO c1 VALUES(1, 2, 3); +} {wal} + +do_test 1.1 { file exists test.db-wal } 1 +do_test 1.2 { file size test.db-wal } [wal_file_size 3 1024] +do_test 1.3 { db close } {} +do_test 1.4 { file exists test.db-wal } 0 + +sqlite3 db test.db +do_execsql_test 1.5 { + INSERT INTO c1 VALUES(4, 5, 6); + INSERT INTO c1 VALUES(7, 8, 9); +} +do_test 1.6 { file exists test.db-wal } 1 +do_test 1.7 { sqlite3_db_config db NO_CKPT_ON_CLOSE 1 } {1} +do_test 1.8 { file size test.db-wal } [wal_file_size 2 1024] +do_test 1.9 { db close } {} +do_test 1.10 { file exists test.db-wal } 1 +do_test 1.11 { file size test.db-wal } [wal_file_size 2 1024] + +sqlite3 db test.db +do_execsql_test 1.12 { + SELECT * FROM c1 +} {1 2 3 4 5 6 7 8 9} + + +finish_test From 1ad93a003d9666f9efdbf20f4f4f810d46f43830 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 2 Nov 2016 02:17:52 +0000 Subject: [PATCH 0944/1484] Use NOT NULL partial indexes when the query is constrained by a single LIKE or GLOB. FossilOrigin-Name: 9b3a3b41b59a7ce7d3dd82c7402d6fdc6a5ca43c --- manifest | 15 +++++++-------- manifest.uuid | 2 +- src/expr.c | 9 ++++----- 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index 66d4767d33..d5880b1fb9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sSQLITE_DBCONFIG_NO_CKPT_ON_CLOSE\ssqlite3_dbconfig()\soption\s-\sfor\ndisabling\sSQLite's\sdefault\scheckpoint-on-close\sbehaviour. -D 2016-10-31T16:49:18.127 +C Use\sNOT\sNULL\spartial\sindexes\swhen\sthe\squery\sis\sconstrained\sby\sa\ssingle\nLIKE\sor\sGLOB. +D 2016-11-02T02:17:52.919 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -340,7 +340,7 @@ F src/ctime.c a2a52d6e353f459d8ab0f07321f60fafa47d5421 F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c cb3f6300df24c26c609778b2731f82644b5532ec -F src/expr.c aac0b8d39373ce8f1d47829ce12c3d7af90c46a6 +F src/expr.c ce7110980fac6dfdfbe1e393443bdb79bad29339 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c b9ca262f6ad4d030a3cab737ebf9b0b3c8b4ac80 F src/func.c 29cc9acb170ec1387b9f63eb52cd85f8de96c771 @@ -1529,8 +1529,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 6374978e8f1ac091394a9f5a1896be92af658bcd 093d2fc2288b75c15ccf877bfa0e622d3918a562 -R f901fbda939dcfa6ff6d756b39418ee6 -T +closed 093d2fc2288b75c15ccf877bfa0e622d3918a562 -U dan -Z 5d42ae70ac4da1275b3f1c98c68ab01c +P 6d142025c74f66f2d48155354b556cd5b2682cb2 +R 6a21c44879153ad3b8a90965de65b693 +U drh +Z 3251c60dbcdf547bbc5e5373f62e3557 diff --git a/manifest.uuid b/manifest.uuid index 7b3b4972d7..eabbb7dbc2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6d142025c74f66f2d48155354b556cd5b2682cb2 \ No newline at end of file +9b3a3b41b59a7ce7d3dd82c7402d6fdc6a5ca43c \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 6d2ec437ff..c2b9c8fe46 100644 --- a/src/expr.c +++ b/src/expr.c @@ -4600,11 +4600,10 @@ int sqlite3ExprImpliesExpr(Expr *pE1, Expr *pE2, int iTab){ ){ return 1; } - if( pE2->op==TK_NOTNULL - && sqlite3ExprCompare(pE1->pLeft, pE2->pLeft, iTab)==0 - && (pE1->op!=TK_ISNULL && pE1->op!=TK_IS) - ){ - return 1; + if( pE2->op==TK_NOTNULL && pE1->op!=TK_ISNULL && pE1->op!=TK_IS ){ + Expr *pX = sqlite3ExprSkipCollate(pE1->pLeft); + testcase( pX!=pE1->pLeft ); + if( sqlite3ExprCompare(pX, pE2->pLeft, iTab)==0 ) return 1; } return 0; } From e77caa191b259db165b00c28849d44905886ddbe Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 2 Nov 2016 13:18:46 +0000 Subject: [PATCH 0945/1484] Fix a requirement mark. No changes to code. FossilOrigin-Name: d18f61b78c8fafef742efbc890382537e8584180 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index d5880b1fb9..5b6bd6df8f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Use\sNOT\sNULL\spartial\sindexes\swhen\sthe\squery\sis\sconstrained\sby\sa\ssingle\nLIKE\sor\sGLOB. -D 2016-11-02T02:17:52.919 +C Fix\sa\srequirement\smark.\s\sNo\schanges\sto\scode. +D 2016-11-02T13:18:46.797 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -454,7 +454,7 @@ F src/update.c 8179e699dbd45b92934fd02d3d8e3732e8da8802 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 3e2da6101888d073e79ecc6af5e0a2f70fa1e498 F src/vacuum.c 913970b9d86dd6c2b8063ef1af421880f1464ec3 -F src/vdbe.c c93ae647b3b302234f3593fd686577216aa22543 +F src/vdbe.c 2edc4fa8a825c79a929766f50bc800ea158646d2 F src/vdbe.h c044be7050ac6bf596eecc6ab159f5dbc020a3b7 F src/vdbeInt.h d8a56a491b752dbb5f671963b8c861ec72ea875e F src/vdbeapi.c 97129bec6b1553da50d8e73f523c278bda66d9f6 @@ -1529,7 +1529,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 6d142025c74f66f2d48155354b556cd5b2682cb2 -R 6a21c44879153ad3b8a90965de65b693 +P 9b3a3b41b59a7ce7d3dd82c7402d6fdc6a5ca43c +R a9c96cf30359222a62867f4daad253b3 U drh -Z 3251c60dbcdf547bbc5e5373f62e3557 +Z ccd9456cce5e8a5cfc9ec8a1242d7e32 diff --git a/manifest.uuid b/manifest.uuid index eabbb7dbc2..220d973bcf 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9b3a3b41b59a7ce7d3dd82c7402d6fdc6a5ca43c \ No newline at end of file +d18f61b78c8fafef742efbc890382537e8584180 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 09019f3728..8b47a37833 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -4270,7 +4270,7 @@ case OP_NewRowid: { /* out2 */ sqlite3VdbeMemIntegerify(pMem); assert( (pMem->flags & MEM_Int)!=0 ); /* mem(P3) holds an integer */ if( pMem->u.i==MAX_ROWID || pC->useRandomRowid ){ - rc = SQLITE_FULL; /* IMP: R-12275-61338 */ + rc = SQLITE_FULL; /* IMP: R-17817-00630 */ goto abort_due_to_error; } if( vu.i+1 ){ From 75ba676790ea108672c732f9d3285859c2b69b28 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 2 Nov 2016 14:50:19 +0000 Subject: [PATCH 0946/1484] Fix an issue that was causing the new database image to be assembled entirely in heap memory when VACUUMing a database, even if it should use a temp file. This could cause SQLITE_NOMEM errors when vacuuming very large databases on 32-bit systems. FossilOrigin-Name: 3028845329c9b7acdec2ec8b01d00d782347454c --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/vacuum.c | 2 +- test/vacuum5.test | 38 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 48 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 5b6bd6df8f..3c2785451b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\srequirement\smark.\s\sNo\schanges\sto\scode. -D 2016-11-02T13:18:46.797 +C Fix\san\sissue\sthat\swas\scausing\sthe\snew\sdatabase\simage\sto\sbe\sassembled\sentirely\nin\sheap\smemory\swhen\sVACUUMing\sa\sdatabase,\seven\sif\sit\sshould\suse\sa\stemp\sfile.\nThis\scould\scause\sSQLITE_NOMEM\serrors\swhen\svacuuming\svery\slarge\sdatabases\son\n32-bit\ssystems. +D 2016-11-02T14:50:19.363 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f @@ -453,7 +453,7 @@ F src/trigger.c 3419bb9862983d84d70735fb4c94b21b934cd0c5 F src/update.c 8179e699dbd45b92934fd02d3d8e3732e8da8802 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 3e2da6101888d073e79ecc6af5e0a2f70fa1e498 -F src/vacuum.c 913970b9d86dd6c2b8063ef1af421880f1464ec3 +F src/vacuum.c 33c174b28886b2faf26e503b5a49a1c01a9b1c16 F src/vdbe.c 2edc4fa8a825c79a929766f50bc800ea158646d2 F src/vdbe.h c044be7050ac6bf596eecc6ab159f5dbc020a3b7 F src/vdbeInt.h d8a56a491b752dbb5f671963b8c861ec72ea875e @@ -1345,7 +1345,7 @@ F test/vacuum.test ce91c39f7f91a4273bf620efad21086b5aa6ef1d F test/vacuum2.test aa048abee196c16c9ba308465494009057b79f9b F test/vacuum3.test 77ecdd54592b45a0bcb133339f99f1ae0ae94d0d F test/vacuum4.test d3f8ecff345f166911568f397d2432c16d2867d9 -F test/vacuum5.test 0b7ac80c64eed657b4ce2dd6535092c0d6afec6c +F test/vacuum5.test 800b5e881fa3dfdc1be252f2a45f107c75176628 F test/vacuummem.test 7b42abb3208bd82dd23a7536588396f295a314f2 F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102 F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661 @@ -1529,7 +1529,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 9b3a3b41b59a7ce7d3dd82c7402d6fdc6a5ca43c -R a9c96cf30359222a62867f4daad253b3 -U drh -Z ccd9456cce5e8a5cfc9ec8a1242d7e32 +P d18f61b78c8fafef742efbc890382537e8584180 +R 341f21774d345780c95f7c12f21ba1af +U dan +Z c3255af0dbcff292701e9438f3a3c514 diff --git a/manifest.uuid b/manifest.uuid index 220d973bcf..c9f54e8b8c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d18f61b78c8fafef742efbc890382537e8584180 \ No newline at end of file +3028845329c9b7acdec2ec8b01d00d782347454c \ No newline at end of file diff --git a/src/vacuum.c b/src/vacuum.c index 295beb6752..25b1258510 100644 --- a/src/vacuum.c +++ b/src/vacuum.c @@ -191,7 +191,7 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db, int iDb){ sqlite3BtreeSetCacheSize(pTemp, db->aDb[iDb].pSchema->cache_size); sqlite3BtreeSetSpillSize(pTemp, sqlite3BtreeSetSpillSize(pMain,0)); - sqlite3BtreeSetPagerFlags(pTemp, PAGER_SYNCHRONOUS_OFF); + sqlite3BtreeSetPagerFlags(pTemp, PAGER_SYNCHRONOUS_OFF|PAGER_CACHESPILL); /* Begin a transaction and take an exclusive lock on the main database ** file. This is done before the sqlite3BtreeGetPageSize(pMain) call below, diff --git a/test/vacuum5.test b/test/vacuum5.test index 16b15b64a1..c44b200964 100644 --- a/test/vacuum5.test +++ b/test/vacuum5.test @@ -14,6 +14,7 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl +set testprefix vacuum5 # If the VACUUM statement is disabled in the current build, skip all # the tests in this file. @@ -111,4 +112,41 @@ do_catchsql_test vacuum5-2.0 { VACUUM olaf; } {1 {unknown database olaf}} +#------------------------------------------------------------------------- +# Test that a temp file is opened as part of VACUUM. +# +if {$::TEMP_STORE<3} { + db close + testvfs tvfs + tvfs filter xOpen + tvfs script open_cb + forcedelete test.db + + set ::openfiles [list] + proc open_cb {method args} { + lappend ::openfiles [file tail [lindex $args 0]] + } + sqlite3 db test.db -vfs tvfs + + do_execsql_test 3.0 { + PRAGMA page_size = 1024; + PRAGMA cache_size = 50; + CREATE TABLE t1(i INTEGER PRIMARY KEY, j UNIQUE); + WITH s(i) AS ( + VALUES(1) UNION ALL SELECT i+1 FROM s WHERE i<1000 + ) + INSERT INTO t1 SELECT NULL, randomblob(100) FROM s; + } + + do_execsql_test 3.1 { VACUUM } + + db close + tvfs delete + do_test 3.2 { + set ::openfiles + } {test.db test.db-journal test.db-journal {} test.db-journal} +} + + + finish_test From 506a1400a30f7ec3da86bec00057225a695eb989 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 2 Nov 2016 19:49:22 +0000 Subject: [PATCH 0947/1484] Adjust the MSVC makefile to use Tcl8.6 by default. FossilOrigin-Name: def8f598b8e33b5bab3a024cc57f4c5e300cd8cd --- Makefile.msc | 6 +++--- manifest | 16 ++++++++-------- manifest.uuid | 2 +- test/wal6.test | 2 ++ 4 files changed, 14 insertions(+), 12 deletions(-) diff --git a/Makefile.msc b/Makefile.msc index 1a78452970..0d42d41aa8 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -794,11 +794,11 @@ TCLLIBDIR = c:\tcl\lib !ENDIF !IFNDEF LIBTCL -LIBTCL = tcl85.lib +LIBTCL = tcl86.lib !ENDIF !IFNDEF LIBTCLSTUB -LIBTCLSTUB = tclstub85.lib +LIBTCLSTUB = tclstub86.lib !ENDIF !IFNDEF LIBTCLPATH @@ -828,7 +828,7 @@ LIBICU = icuuc.lib icuin.lib # specific Tcl shell to use. # !IFNDEF TCLSH_CMD -TCLSH_CMD = tclsh85 +TCLSH_CMD = tclsh !ENDIF # <> diff --git a/manifest b/manifest index 3c2785451b..6a910305aa 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -C Fix\san\sissue\sthat\swas\scausing\sthe\snew\sdatabase\simage\sto\sbe\sassembled\sentirely\nin\sheap\smemory\swhen\sVACUUMing\sa\sdatabase,\seven\sif\sit\sshould\suse\sa\stemp\sfile.\nThis\scould\scause\sSQLITE_NOMEM\serrors\swhen\svacuuming\svery\slarge\sdatabases\son\n32-bit\ssystems. -D 2016-11-02T14:50:19.363 +C Adjust\sthe\sMSVC\smakefile\sto\suse\sTcl8.6\sby\sdefault. +D 2016-11-02T19:49:22.697 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 -F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f +F Makefile.msc e0217f2d35a0448abbe4b066132ae20136e8b408 F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7 F VERSION 661b3e6a778cfbfd7bdce8bbb1545b22f4b6f09e F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 @@ -1375,7 +1375,7 @@ F test/wal2.test 56b0bc95b8693a0be294f8d210c49025dd094bd7 F test/wal3.test 2a93004bc0fb2b5c29888964024695bade278ab2 F test/wal4.test 4744e155cd6299c6bd99d3eab1c82f77db9cdb3c F test/wal5.test 9c11da7aeccd83a46d79a556ad11a18d3cb15aa9 -F test/wal6.test 504b24ddb3a75d4b7a6e7c09dc7563622e652fd2 +F test/wal6.test b602704e4b066199bc89d91ca9000f335dcf4572 F test/wal64k.test 163655ecd2cb8afef4737cac2a40fdd2eeaf20b8 F test/wal7.test 2ae8f427d240099cc4b2dfef63cff44e2a68a1bd F test/wal8.test d9df3fba4caad5854ed69ed673c68482514203c8 @@ -1529,7 +1529,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d18f61b78c8fafef742efbc890382537e8584180 -R 341f21774d345780c95f7c12f21ba1af -U dan -Z c3255af0dbcff292701e9438f3a3c514 +P 3028845329c9b7acdec2ec8b01d00d782347454c +R dfd07fa2751ad1cca77c9ad8863824f5 +U drh +Z e699b75769ea46dd9ab5a62241677b6a diff --git a/manifest.uuid b/manifest.uuid index c9f54e8b8c..49cc0c8e9c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3028845329c9b7acdec2ec8b01d00d782347454c \ No newline at end of file +def8f598b8e33b5bab3a024cc57f4c5e300cd8cd \ No newline at end of file diff --git a/test/wal6.test b/test/wal6.test index 92831f1fb0..9bbc58409d 100644 --- a/test/wal6.test +++ b/test/wal6.test @@ -238,6 +238,8 @@ do_test 4.4.2 { # Confirm that it is possible to get an SQLITE_BUSY_SNAPSHOT error from # "BEGIN EXCLUSIVE" if the connection already has an open read-transaction. # +db close +db2 close reset_db sqlite3 db2 test.db do_execsql_test 5.1 { From 6027561178f8f3b68592816d2a91c38032d6a78e Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 3 Nov 2016 02:25:30 +0000 Subject: [PATCH 0948/1484] Fix an possible NULL pointer deference in the command-line shell that can occur when using imposter mode. FossilOrigin-Name: ad08753a8bbf073ec4af9c3a5783ed664244d954 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/shell.c | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 6a910305aa..33edebd61f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Adjust\sthe\sMSVC\smakefile\sto\suse\sTcl8.6\sby\sdefault. -D 2016-11-02T19:49:22.697 +C Fix\san\spossible\sNULL\spointer\sdeference\sin\sthe\scommand-line\sshell\sthat\scan\noccur\swhen\susing\simposter\smode. +D 2016-11-03T02:25:30.134 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e0217f2d35a0448abbe4b066132ae20136e8b408 @@ -388,7 +388,7 @@ F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c 3fac1b2737ea5a724f20b921ac7e259c9be2100b F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c ea3af83e2d0f245fef81ea4cf04cb730ce67f722 -F src/shell.c f0e8b54c58a8a13cc046f5af6d72de7e0a118a2b +F src/shell.c 0abcad599065d9e00b91ca4ad7d14b98ea381d91 F src/sqlite.h.in 97e9b0f952306677db82b055147ed1d99cb7ba66 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae @@ -1529,7 +1529,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 3028845329c9b7acdec2ec8b01d00d782347454c -R dfd07fa2751ad1cca77c9ad8863824f5 +P def8f598b8e33b5bab3a024cc57f4c5e300cd8cd +R ae537ccc69c194277761110153c77ab0 U drh -Z e699b75769ea46dd9ab5a62241677b6a +Z c8a9d3d6f5e70005dce9f87ade1f94d9 diff --git a/manifest.uuid b/manifest.uuid index 49cc0c8e9c..2068690c00 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -def8f598b8e33b5bab3a024cc57f4c5e300cd8cd \ No newline at end of file +ad08753a8bbf073ec4af9c3a5783ed664244d954 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index d9aef17d02..15bb6f2730 100644 --- a/src/shell.c +++ b/src/shell.c @@ -1901,6 +1901,7 @@ static int shell_exec( continue; } zStmtSql = sqlite3_sql(pStmt); + if( zStmtSql==0 ) zStmtSql = ""; while( IsSpace(zStmtSql[0]) ) zStmtSql++; /* save off the prepared statment handle and reset row count */ From 16eb59484fa7d776ada2867a21786f7d0c810704 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 3 Nov 2016 13:01:38 +0000 Subject: [PATCH 0949/1484] Add the ".imposter" command to the command-line shell. FossilOrigin-Name: be3ec8fdcf1541017ca9375df07645db2a9a3f5a --- manifest | 12 ++++----- manifest.uuid | 2 +- src/shell.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 75 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 33edebd61f..e87531c361 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\spossible\sNULL\spointer\sdeference\sin\sthe\scommand-line\sshell\sthat\scan\noccur\swhen\susing\simposter\smode. -D 2016-11-03T02:25:30.134 +C Add\sthe\s".imposter"\scommand\sto\sthe\scommand-line\sshell. +D 2016-11-03T13:01:38.992 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e0217f2d35a0448abbe4b066132ae20136e8b408 @@ -388,7 +388,7 @@ F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c 3fac1b2737ea5a724f20b921ac7e259c9be2100b F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c ea3af83e2d0f245fef81ea4cf04cb730ce67f722 -F src/shell.c 0abcad599065d9e00b91ca4ad7d14b98ea381d91 +F src/shell.c 859c497e9f83a5326f43c1a0e078acc52952b275 F src/sqlite.h.in 97e9b0f952306677db82b055147ed1d99cb7ba66 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae @@ -1529,7 +1529,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P def8f598b8e33b5bab3a024cc57f4c5e300cd8cd -R ae537ccc69c194277761110153c77ab0 +P ad08753a8bbf073ec4af9c3a5783ed664244d954 +R 4bccfcf3c4fd102e5db9ad5f3fdf53dc U drh -Z c8a9d3d6f5e70005dce9f87ade1f94d9 +Z 3d1bd5abf50601149224220b1d9418d0 diff --git a/manifest.uuid b/manifest.uuid index 2068690c00..c6fc1185b0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ad08753a8bbf073ec4af9c3a5783ed664244d954 \ No newline at end of file +be3ec8fdcf1541017ca9375df07645db2a9a3f5a \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 15bb6f2730..374755fcc5 100644 --- a/src/shell.c +++ b/src/shell.c @@ -2164,6 +2164,9 @@ static char zHelp[] = ".headers on|off Turn display of headers on or off\n" ".help Show this message\n" ".import FILE TABLE Import data from FILE into TABLE\n" +#ifndef SQLITE_OMIT_TEST_CONTROL + ".imposter INDEX TABLE Create imposter table TABLE on index INDEX\n" +#endif ".indexes ?TABLE? Show names of all indexes\n" " If TABLE specified, only show indexes for tables\n" " matching LIKE pattern TABLE.\n" @@ -3846,6 +3849,68 @@ static int do_meta_command(char *zLine, ShellState *p){ } }else +#ifndef SQLITE_OMIT_BUILTIN_TEST + if( c=='i' && strncmp(azArg[0], "imposter", n)==0 ){ + char *zSql; + char *zCollist = 0; + sqlite3_stmt *pStmt; + int tnum = 0; + if( nArg!=3 ){ + utf8_printf(stderr, "Usage: .imposter INDEX IMPOSTER\n"); + rc = 1; + goto meta_command_exit; + } + open_db(p, 0); + zSql = sqlite3_mprintf("SELECT rootpage FROM sqlite_master" + " WHERE name='%q' AND type='index'", azArg[1]); + sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); + sqlite3_free(zSql); + if( sqlite3_step(pStmt)==SQLITE_ROW ){ + tnum = sqlite3_column_int(pStmt, 0); + } + sqlite3_finalize(pStmt); + if( tnum==0 ){ + utf8_printf(stderr, "no such index: \"%s\"\n", azArg[1]); + rc = 1; + goto meta_command_exit; + } + zSql = sqlite3_mprintf("PRAGMA index_xinfo='%q'", azArg[1]); + rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); + sqlite3_free(zSql); + while( sqlite3_step(pStmt)==SQLITE_ROW ){ + const char *zCol = (const char*)sqlite3_column_text(pStmt,2); + if( zCol==0 ) zCol = "_ROWID_"; + if( zCollist==0 ){ + zCollist = sqlite3_mprintf("\"%w\"", zCol); + }else{ + zCollist = sqlite3_mprintf("%z,\"%w\"", zCollist, zCol); + } + } + sqlite3_finalize(pStmt); + zSql = sqlite3_mprintf( + "CREATE TABLE \"%w\"(%s,PRIMARY KEY(%s))WITHOUT ROWID", + azArg[2], zCollist, zCollist); + sqlite3_free(zCollist); + rc = sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 1, tnum); + if( rc==SQLITE_OK ){ + rc = sqlite3_exec(p->db, zSql, 0, 0, 0); + sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 0, 0); + if( rc ){ + utf8_printf(stderr, "Error in [%s]: %s\n", zSql, sqlite3_errmsg(p->db)); + }else{ + utf8_printf(stdout, "%s;\n", zSql); + utf8_printf(stdout, + "WARNING: writing to an imposter table will corrupt the index!\n" + ); + } + }else{ + utf8_printf(stderr, "SQLITE_TESTCTRL_IMPOSTER returns %d\n", rc); + rc = 1; + } + sqlite3_free(zSql); + }else +#endif /* !defined(SQLITE_OMIT_TEST_CONTROL) */ + #ifdef SQLITE_ENABLE_IOTRACE if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){ SQLITE_API extern void (SQLITE_CDECL *sqlite3IoTrace)(const char*, ...); @@ -3868,6 +3933,7 @@ static int do_meta_command(char *zLine, ShellState *p){ } }else #endif + if( c=='l' && n>=5 && strncmp(azArg[0], "limits", n)==0 ){ static const struct { const char *zLimitName; /* Name of a limit */ @@ -4708,6 +4774,7 @@ static int do_meta_command(char *zLine, ShellState *p){ } }else +#ifndef SQLITE_OMIT_BUILTIN_TEST if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){ static const struct { const char *zCtrlName; /* Name of a test-control option */ @@ -4883,6 +4950,7 @@ static int do_meta_command(char *zLine, ShellState *p){ } #endif }else +#endif /* !defined(SQLITE_OMIT_BUILTIN_TEST) */ #if SQLITE_USER_AUTHENTICATION if( c=='u' && strncmp(azArg[0], "user", n)==0 ){ From 59ce2c434c0894b23deca2c60f7d843f11ad5a0d Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 3 Nov 2016 13:12:28 +0000 Subject: [PATCH 0950/1484] In the command-line shell, fix the .imposter command so that it works with indexes on expressions. Fix the ".mode quote" mode so that it works with ".headers ON". FossilOrigin-Name: ba9873da94d21873ff76f16a5332fc0092d83f70 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/shell.c | 21 +++++++++++++++++++-- 3 files changed, 26 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index e87531c361..3767dfc065 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\s".imposter"\scommand\sto\sthe\scommand-line\sshell. -D 2016-11-03T13:01:38.992 +C In\sthe\scommand-line\sshell,\sfix\sthe\s.imposter\scommand\sso\sthat\sit\sworks\nwith\sindexes\son\sexpressions.\s\sFix\sthe\s".mode\squote"\smode\sso\sthat\sit\sworks\nwith\s".headers\sON". +D 2016-11-03T13:12:28.436 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e0217f2d35a0448abbe4b066132ae20136e8b408 @@ -388,7 +388,7 @@ F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c 3fac1b2737ea5a724f20b921ac7e259c9be2100b F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c ea3af83e2d0f245fef81ea4cf04cb730ce67f722 -F src/shell.c 859c497e9f83a5326f43c1a0e078acc52952b275 +F src/shell.c 63e54cfa1c7ec5b70a4c9a86502bc10280c3d5a3 F src/sqlite.h.in 97e9b0f952306677db82b055147ed1d99cb7ba66 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae @@ -1529,7 +1529,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ad08753a8bbf073ec4af9c3a5783ed664244d954 -R 4bccfcf3c4fd102e5db9ad5f3fdf53dc +P be3ec8fdcf1541017ca9375df07645db2a9a3f5a +R 492f3194b55f82acdeed3f831384acda U drh -Z 3d1bd5abf50601149224220b1d9418d0 +Z cf1e2d863175ee56efe47dbfd06f83ec diff --git a/manifest.uuid b/manifest.uuid index c6fc1185b0..9e5798c100 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -be3ec8fdcf1541017ca9375df07645db2a9a3f5a \ No newline at end of file +ba9873da94d21873ff76f16a5332fc0092d83f70 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 374755fcc5..6a7bee142d 100644 --- a/src/shell.c +++ b/src/shell.c @@ -1202,7 +1202,6 @@ static int shell_callback( } case MODE_Quote: case MODE_Insert: { - p->cnt++; if( azArg==0 ) break; if( p->cMode==MODE_Insert ){ utf8_printf(p->out,"INSERT INTO %s",p->zDestTable); @@ -1215,7 +1214,14 @@ static int shell_callback( raw_printf(p->out,")"); } raw_printf(p->out," VALUES("); + }else if( p->cnt==0 && p->showHeader ){ + for(i=0; i0 ) utf8_printf(p->out, ","); + output_quoted_string(p->out, azCol[i]); + } + utf8_printf(p->out,"\n"); } + p->cnt++; for(i=0; i0 ? ",": ""; if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){ @@ -3855,6 +3861,7 @@ static int do_meta_command(char *zLine, ShellState *p){ char *zCollist = 0; sqlite3_stmt *pStmt; int tnum = 0; + int i; if( nArg!=3 ){ utf8_printf(stderr, "Usage: .imposter INDEX IMPOSTER\n"); rc = 1; @@ -3877,9 +3884,19 @@ static int do_meta_command(char *zLine, ShellState *p){ zSql = sqlite3_mprintf("PRAGMA index_xinfo='%q'", azArg[1]); rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); sqlite3_free(zSql); + i = 0; while( sqlite3_step(pStmt)==SQLITE_ROW ){ + char zLabel[20]; const char *zCol = (const char*)sqlite3_column_text(pStmt,2); - if( zCol==0 ) zCol = "_ROWID_"; + i++; + if( zCol==0 ){ + if( sqlite3_column_int(pStmt,1)==-1 ){ + zCol = "_ROWID_"; + }else{ + sqlite3_snprintf(sizeof(zLabel),zLabel,"expr%d",i); + zCol = zLabel; + } + } if( zCollist==0 ){ zCollist = sqlite3_mprintf("\"%w\"", zCol); }else{ From 7df9b8e6e4ce11ae0dff40e742725a171061393b Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 3 Nov 2016 19:01:20 +0000 Subject: [PATCH 0951/1484] Fix a test case in vacuum5.test so that it works with -DSQLITE_TEMP_STORE=2. FossilOrigin-Name: f5dd95e25c703a825ad7af9a4b3886bd3ef8c2e8 --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/vacuum5.test | 1 + 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 3767dfc065..1cd381ff12 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\sthe\scommand-line\sshell,\sfix\sthe\s.imposter\scommand\sso\sthat\sit\sworks\nwith\sindexes\son\sexpressions.\s\sFix\sthe\s".mode\squote"\smode\sso\sthat\sit\sworks\nwith\s".headers\sON". -D 2016-11-03T13:12:28.436 +C Fix\sa\stest\scase\sin\svacuum5.test\sso\sthat\sit\sworks\swith\s-DSQLITE_TEMP_STORE=2. +D 2016-11-03T19:01:20.023 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e0217f2d35a0448abbe4b066132ae20136e8b408 @@ -1345,7 +1345,7 @@ F test/vacuum.test ce91c39f7f91a4273bf620efad21086b5aa6ef1d F test/vacuum2.test aa048abee196c16c9ba308465494009057b79f9b F test/vacuum3.test 77ecdd54592b45a0bcb133339f99f1ae0ae94d0d F test/vacuum4.test d3f8ecff345f166911568f397d2432c16d2867d9 -F test/vacuum5.test 800b5e881fa3dfdc1be252f2a45f107c75176628 +F test/vacuum5.test 93a94eb91b850c5cb4aafc4d8090317ff1a40def F test/vacuummem.test 7b42abb3208bd82dd23a7536588396f295a314f2 F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102 F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661 @@ -1529,7 +1529,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P be3ec8fdcf1541017ca9375df07645db2a9a3f5a -R 492f3194b55f82acdeed3f831384acda -U drh -Z cf1e2d863175ee56efe47dbfd06f83ec +P ba9873da94d21873ff76f16a5332fc0092d83f70 +R 6f4b8c4fa3be6db58f3d71607061b052 +U dan +Z 4bd4a6f70afd6ec41fa3cd32e82508a8 diff --git a/manifest.uuid b/manifest.uuid index 9e5798c100..03d33b5c76 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ba9873da94d21873ff76f16a5332fc0092d83f70 \ No newline at end of file +f5dd95e25c703a825ad7af9a4b3886bd3ef8c2e8 \ No newline at end of file diff --git a/test/vacuum5.test b/test/vacuum5.test index c44b200964..563fedcda0 100644 --- a/test/vacuum5.test +++ b/test/vacuum5.test @@ -129,6 +129,7 @@ if {$::TEMP_STORE<3} { sqlite3 db test.db -vfs tvfs do_execsql_test 3.0 { + PRAGMA temp_store = file; PRAGMA page_size = 1024; PRAGMA cache_size = 50; CREATE TABLE t1(i INTEGER PRIMARY KEY, j UNIQUE); From af580685509eb49ed2e96b44b26c1c3df83707e6 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 3 Nov 2016 19:24:14 +0000 Subject: [PATCH 0952/1484] Fix a test case in vacuum5.test sot aht it works with -DSQLITE_ENABLE_ATOMIC_WRITE. FossilOrigin-Name: 3ca80010397676eca57c8a4c9b3a9c2c40629663 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/vacuum5.test | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 1cd381ff12..4534ee9beb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\stest\scase\sin\svacuum5.test\sso\sthat\sit\sworks\swith\s-DSQLITE_TEMP_STORE=2. -D 2016-11-03T19:01:20.023 +C Fix\sa\stest\scase\sin\svacuum5.test\ssot\saht\sit\sworks\swith\n-DSQLITE_ENABLE_ATOMIC_WRITE. +D 2016-11-03T19:24:14.041 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e0217f2d35a0448abbe4b066132ae20136e8b408 @@ -1345,7 +1345,7 @@ F test/vacuum.test ce91c39f7f91a4273bf620efad21086b5aa6ef1d F test/vacuum2.test aa048abee196c16c9ba308465494009057b79f9b F test/vacuum3.test 77ecdd54592b45a0bcb133339f99f1ae0ae94d0d F test/vacuum4.test d3f8ecff345f166911568f397d2432c16d2867d9 -F test/vacuum5.test 93a94eb91b850c5cb4aafc4d8090317ff1a40def +F test/vacuum5.test 49d9febcb6e13c3ac5b96d8df6736f9b85d9bf70 F test/vacuummem.test 7b42abb3208bd82dd23a7536588396f295a314f2 F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102 F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661 @@ -1529,7 +1529,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ba9873da94d21873ff76f16a5332fc0092d83f70 -R 6f4b8c4fa3be6db58f3d71607061b052 +P f5dd95e25c703a825ad7af9a4b3886bd3ef8c2e8 +R 847169ed1627a5357ca38bad29d184e8 U dan -Z 4bd4a6f70afd6ec41fa3cd32e82508a8 +Z 27879fe940a6bb6d0b25d61dad9f9499 diff --git a/manifest.uuid b/manifest.uuid index 03d33b5c76..ad665ee16b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f5dd95e25c703a825ad7af9a4b3886bd3ef8c2e8 \ No newline at end of file +3ca80010397676eca57c8a4c9b3a9c2c40629663 \ No newline at end of file diff --git a/test/vacuum5.test b/test/vacuum5.test index 563fedcda0..7cc823cb7e 100644 --- a/test/vacuum5.test +++ b/test/vacuum5.test @@ -144,7 +144,7 @@ if {$::TEMP_STORE<3} { db close tvfs delete do_test 3.2 { - set ::openfiles + lrange $::openfiles 0 4 } {test.db test.db-journal test.db-journal {} test.db-journal} } From a622d90040a4fe0a04ca05555fb8775ecc7bb3e7 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Thu, 3 Nov 2016 21:35:10 +0000 Subject: [PATCH 0953/1484] Replace a couple more references to Tcl 8.5 in the Windows build tools. FossilOrigin-Name: 1d0e43c549c36d0919a18d61285e94cad29e7a07 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- tool/build-all-msvc.bat | 2 +- tool/mkvsix.tcl | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 4534ee9beb..726c660aff 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\stest\scase\sin\svacuum5.test\ssot\saht\sit\sworks\swith\n-DSQLITE_ENABLE_ATOMIC_WRITE. -D 2016-11-03T19:24:14.041 +C Replace\sa\scouple\smore\sreferences\sto\sTcl\s8.5\sin\sthe\sWindows\sbuild\stools. +D 2016-11-03T21:35:10.155 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e0217f2d35a0448abbe4b066132ae20136e8b408 @@ -1444,7 +1444,7 @@ F tool/GetFile.cs a15e08acb5dd7539b75ba23501581d7c2b462cb5 F tool/GetTclKit.bat f94784e3bdc2f50c539266f5467cbf1f27612cb3 F tool/Replace.cs 02c67258801c2fb5f63231e0ac0f220b4b36ba91 F tool/addopcodes.tcl 10c889c4a65ec6c5604e4a47306fa77ff57ae189 -F tool/build-all-msvc.bat 3e4e4043b53f1aede4308e0d2567bbd773614630 x +F tool/build-all-msvc.bat 018c1b273458a90c8ba633c6f0c5654cfcb138bf x F tool/build-shell.sh 950f47c6174f1eea171319438b93ba67ff5bf367 F tool/cg_anno.tcl 692ce4b8693d59e3a3de77ca97f4139ecfa641b0 x F tool/checkSpacing.c 810e51703529a204fc4e1eb060e9ab663e3c06d2 @@ -1473,7 +1473,7 @@ F tool/mksqlite3c-noext.tcl fef88397668ae83166735c41af99d79f56afaabb F tool/mksqlite3c.tcl 06b2e6a0f21cc0a5d70fbbd136b3e0a96470645e F tool/mksqlite3h.tcl c006c4e5da57c649b24b689511dcd270dd7b0249 F tool/mksqlite3internalh.tcl eb994013e833359137eb53a55acdad0b5ae1049b -F tool/mkvsix.tcl 4abcaf3267171b2faadaf9b82a0dfbaa6e98f8b7 +F tool/mkvsix.tcl b9e0777a213c23156b6542842c238479e496ebf5 F tool/offsets.c fe4262fdfa378e8f5499a42136d17bf3b98f6091 F tool/omittest.tcl 34d7ac01fe4fd18e3637f64abe12c40eca0f6b97 F tool/opcodesum.tcl 740ed206ba8c5040018988129abbf3089a0ccf4a @@ -1529,7 +1529,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P f5dd95e25c703a825ad7af9a4b3886bd3ef8c2e8 -R 847169ed1627a5357ca38bad29d184e8 -U dan -Z 27879fe940a6bb6d0b25d61dad9f9499 +P 3ca80010397676eca57c8a4c9b3a9c2c40629663 +R d949f61d4b25495f5b01912b96f2a42b +U mistachkin +Z 67303d4014c26477179ef9d2cbf9b1fe diff --git a/manifest.uuid b/manifest.uuid index ad665ee16b..5c7119b539 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3ca80010397676eca57c8a4c9b3a9c2c40629663 \ No newline at end of file +1d0e43c549c36d0919a18d61285e94cad29e7a07 \ No newline at end of file diff --git a/tool/build-all-msvc.bat b/tool/build-all-msvc.bat index ae8b76af5a..497b05e316 100755 --- a/tool/build-all-msvc.bat +++ b/tool/build-all-msvc.bat @@ -268,7 +268,7 @@ REM IF DEFINED TCLSH_CMD ( SET TCLSH_FILE=%TCLSH_CMD% ) ELSE ( - SET TCLSH_FILE=tclsh85.exe + SET TCLSH_FILE=tclsh.exe ) FOR %%T IN (%TCLSH_FILE%) DO ( diff --git a/tool/mkvsix.tcl b/tool/mkvsix.tcl index b7350f9c84..c874d538fb 100644 --- a/tool/mkvsix.tcl +++ b/tool/mkvsix.tcl @@ -77,7 +77,7 @@ # command prompt: # # CD /D C:\dev\sqlite\core -# tclsh85 tool\mkvsix.tcl C:\Temp +# tclsh tool\mkvsix.tcl C:\Temp # # In the example above, "C:\dev\sqlite\core" represents the root of the source # tree for SQLite and "C:\Temp" represents the top-level directory containing From 792557ac67f1c807af1d83267f268d135ee6a200 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 4 Nov 2016 07:25:43 +0000 Subject: [PATCH 0954/1484] Fix a test case in vacuum5.test so that it works with the in-memory journal permutation. FossilOrigin-Name: 81c86401463df6be4ac21987b3b1703e38ab933b --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/vacuum5.test | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 726c660aff..da7b183ab1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Replace\sa\scouple\smore\sreferences\sto\sTcl\s8.5\sin\sthe\sWindows\sbuild\stools. -D 2016-11-03T21:35:10.155 +C Fix\sa\stest\scase\sin\svacuum5.test\sso\sthat\sit\sworks\swith\sthe\sin-memory\sjournal\npermutation. +D 2016-11-04T07:25:43.726 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e0217f2d35a0448abbe4b066132ae20136e8b408 @@ -1345,7 +1345,7 @@ F test/vacuum.test ce91c39f7f91a4273bf620efad21086b5aa6ef1d F test/vacuum2.test aa048abee196c16c9ba308465494009057b79f9b F test/vacuum3.test 77ecdd54592b45a0bcb133339f99f1ae0ae94d0d F test/vacuum4.test d3f8ecff345f166911568f397d2432c16d2867d9 -F test/vacuum5.test 49d9febcb6e13c3ac5b96d8df6736f9b85d9bf70 +F test/vacuum5.test c87234e8ca4107f349da4edbeda3e4ea5adc93f3 F test/vacuummem.test 7b42abb3208bd82dd23a7536588396f295a314f2 F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102 F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661 @@ -1529,7 +1529,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 3ca80010397676eca57c8a4c9b3a9c2c40629663 -R d949f61d4b25495f5b01912b96f2a42b -U mistachkin -Z 67303d4014c26477179ef9d2cbf9b1fe +P 1d0e43c549c36d0919a18d61285e94cad29e7a07 +R e8d6a4378d7e8684c490ab3e02196987 +U dan +Z 85e0796babcc520647a9671cf08776f6 diff --git a/manifest.uuid b/manifest.uuid index 5c7119b539..89753f6d24 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1d0e43c549c36d0919a18d61285e94cad29e7a07 \ No newline at end of file +81c86401463df6be4ac21987b3b1703e38ab933b \ No newline at end of file diff --git a/test/vacuum5.test b/test/vacuum5.test index 7cc823cb7e..8e76a9393c 100644 --- a/test/vacuum5.test +++ b/test/vacuum5.test @@ -115,7 +115,7 @@ do_catchsql_test vacuum5-2.0 { #------------------------------------------------------------------------- # Test that a temp file is opened as part of VACUUM. # -if {$::TEMP_STORE<3} { +if {$::TEMP_STORE<3 && [permutation]!="inmemory_journal"} { db close testvfs tvfs tvfs filter xOpen From 54fc5cc2ae7c2e8ad15d97b7328bf4af3649bc8a Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 4 Nov 2016 11:23:30 +0000 Subject: [PATCH 0955/1484] Add an assert() to silence a coverity false-positive. FossilOrigin-Name: 97354093bceff28714a605068851cfa026c8272a --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/treeview.c | 1 + 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index da7b183ab1..989b6d5ae6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\stest\scase\sin\svacuum5.test\sso\sthat\sit\sworks\swith\sthe\sin-memory\sjournal\npermutation. -D 2016-11-04T07:25:43.726 +C Add\san\sassert()\sto\ssilence\sa\scoverity\sfalse-positive. +D 2016-11-04T11:23:30.899 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e0217f2d35a0448abbe4b066132ae20136e8b408 @@ -448,7 +448,7 @@ F src/test_windirent.h 7edc57e2faa727026dbd5d010dd0e2e665d5aa01 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c 78c8085bc7af1922aa687f0f4bbd716821330de5 -F src/treeview.c f51b75a28b377adde9f79bc3deb6c7770bcf97c0 +F src/treeview.c 4e44ade3bfe59d82005039f72e09333ce2b4162c F src/trigger.c 3419bb9862983d84d70735fb4c94b21b934cd0c5 F src/update.c 8179e699dbd45b92934fd02d3d8e3732e8da8802 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c @@ -1529,7 +1529,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 1d0e43c549c36d0919a18d61285e94cad29e7a07 -R e8d6a4378d7e8684c490ab3e02196987 -U dan -Z 85e0796babcc520647a9671cf08776f6 +P 81c86401463df6be4ac21987b3b1703e38ab933b +R 1ea1eb2b071ef3b9ddfdbffca7d5e856 +U drh +Z 2ff0a32c09088faef645f25d6f42c670 diff --git a/manifest.uuid b/manifest.uuid index 89753f6d24..0e0c819e43 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -81c86401463df6be4ac21987b3b1703e38ab933b \ No newline at end of file +97354093bceff28714a605068851cfa026c8272a \ No newline at end of file diff --git a/src/treeview.c b/src/treeview.c index d3671f2c0c..0ea512b5c6 100644 --- a/src/treeview.c +++ b/src/treeview.c @@ -65,6 +65,7 @@ static void sqlite3TreeViewLine(TreeView *p, const char *zFormat, ...){ va_start(ap, zFormat); sqlite3VXPrintf(&acc, zFormat, ap); va_end(ap); + assert( acc.nChar>0 ); if( zBuf[acc.nChar-1]!='\n' ) sqlite3StrAccumAppend(&acc, "\n", 1); sqlite3StrAccumFinish(&acc); fprintf(stdout,"%s", zBuf); From b1c9633493e484d541bd1a9c90ee2108dbcb15f8 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 4 Nov 2016 12:03:26 +0000 Subject: [PATCH 0956/1484] Mark the ICU extension functions as deterministic. FossilOrigin-Name: afbbb6c66a85ff3f4c8dce677e0892a2a51d2b8e --- ext/icu/icu.c | 22 +++++++++++----------- manifest | 14 +++++++------- manifest.uuid | 2 +- test/cursorhint2.test | 14 ++++++++------ 4 files changed, 27 insertions(+), 25 deletions(-) diff --git a/ext/icu/icu.c b/ext/icu/icu.c index 0e33387486..d2beaa3353 100644 --- a/ext/icu/icu.c +++ b/ext/icu/icu.c @@ -500,20 +500,20 @@ int sqlite3IcuInit(sqlite3 *db){ void *pContext; /* sqlite3_user_data() context */ void (*xFunc)(sqlite3_context*,int,sqlite3_value**); } scalars[] = { - {"regexp", 2, SQLITE_ANY, 0, icuRegexpFunc}, + {"regexp", 2, SQLITE_ANY|SQLITE_DETERMINISTIC, 0, icuRegexpFunc}, - {"lower", 1, SQLITE_UTF16, 0, icuCaseFunc16}, - {"lower", 2, SQLITE_UTF16, 0, icuCaseFunc16}, - {"upper", 1, SQLITE_UTF16, (void*)1, icuCaseFunc16}, - {"upper", 2, SQLITE_UTF16, (void*)1, icuCaseFunc16}, + {"lower", 1, SQLITE_UTF16|SQLITE_DETERMINISTIC, 0, icuCaseFunc16}, + {"lower", 2, SQLITE_UTF16|SQLITE_DETERMINISTIC, 0, icuCaseFunc16}, + {"upper", 1, SQLITE_UTF16|SQLITE_DETERMINISTIC, (void*)1, icuCaseFunc16}, + {"upper", 2, SQLITE_UTF16|SQLITE_DETERMINISTIC, (void*)1, icuCaseFunc16}, - {"lower", 1, SQLITE_UTF8, 0, icuCaseFunc16}, - {"lower", 2, SQLITE_UTF8, 0, icuCaseFunc16}, - {"upper", 1, SQLITE_UTF8, (void*)1, icuCaseFunc16}, - {"upper", 2, SQLITE_UTF8, (void*)1, icuCaseFunc16}, + {"lower", 1, SQLITE_UTF8|SQLITE_DETERMINISTIC, 0, icuCaseFunc16}, + {"lower", 2, SQLITE_UTF8|SQLITE_DETERMINISTIC, 0, icuCaseFunc16}, + {"upper", 1, SQLITE_UTF8|SQLITE_DETERMINISTIC, (void*)1, icuCaseFunc16}, + {"upper", 2, SQLITE_UTF8|SQLITE_DETERMINISTIC, (void*)1, icuCaseFunc16}, - {"like", 2, SQLITE_UTF8, 0, icuLikeFunc}, - {"like", 3, SQLITE_UTF8, 0, icuLikeFunc}, + {"like", 2, SQLITE_UTF8|SQLITE_DETERMINISTIC, 0, icuLikeFunc}, + {"like", 3, SQLITE_UTF8|SQLITE_DETERMINISTIC, 0, icuLikeFunc}, {"icu_load_collation", 2, SQLITE_UTF8, (void*)db, icuLoadCollation}, }; diff --git a/manifest b/manifest index 989b6d5ae6..835eb740f6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\san\sassert()\sto\ssilence\sa\scoverity\sfalse-positive. -D 2016-11-04T11:23:30.899 +C Mark\sthe\sICU\sextension\sfunctions\sas\sdeterministic. +D 2016-11-04T12:03:26.544 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e0217f2d35a0448abbe4b066132ae20136e8b408 @@ -202,7 +202,7 @@ F ext/fts5/tool/loadfts5.tcl 95b03429ee6b138645703c6ca192c3ac96eaf093 F ext/fts5/tool/mkfts5c.tcl d1c2a9ab8e0ec690a52316f33dd9b1d379942f45 F ext/fts5/tool/showfts5.tcl d54da0e067306663e2d5d523965ca487698e722c F ext/icu/README.txt d9fbbad0c2f647c3fdf715fc9fd64af53aedfc43 -F ext/icu/icu.c 7d371146fff9c21d4f7a806866c578f61b566511 +F ext/icu/icu.c 03ff6f90f3004a7e5a86205b581b2b7035ebf6e1 F ext/icu/sqliteicu.h 728867a802baa5a96de7495e9689a8e01715ef37 F ext/misc/amatch.c 211108e201105e4bb0c076527b8cfd34330fc234 F ext/misc/carray.c 40c27641010a4dc67e3690bdb7c9d36ca58b3c2d @@ -624,7 +624,7 @@ F test/cse.test 277350a26264495e86b1785f34d2d0c8600e021c F test/csv01.test e0ba3caaa57e4c667a0b45977689fb8082f14348 F test/ctime.test ff6c38e822459d6ca743c34901caf57740b08b54 F test/cursorhint.test 7bc346788390475e77a345da2b92270d04d35856 -F test/cursorhint2.test 2b45341d32d1aae9991a00ef31ebca339b274255 +F test/cursorhint2.test fa41f0d997e67db921d08c31e73111b32811201a F test/date.test 984ac1e3e5e031386866f034006148d3972b4a65 F test/dbstatus.test 73149851b3aff14fc6db478e58f9083a66422cf5 F test/dbstatus2.test e93ab03bfae6d62d4d935f20de928c19ca0ed0ab @@ -1529,7 +1529,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 81c86401463df6be4ac21987b3b1703e38ab933b -R 1ea1eb2b071ef3b9ddfdbffca7d5e856 +P 97354093bceff28714a605068851cfa026c8272a +R e3306eee283049a63433ee2c85b74690 U drh -Z 2ff0a32c09088faef645f25d6f42c670 +Z 8e57808346e33a5bd8a5f1ed64de48bd diff --git a/manifest.uuid b/manifest.uuid index 0e0c819e43..a8a561ff4e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -97354093bceff28714a605068851cfa026c8272a \ No newline at end of file +afbbb6c66a85ff3f4c8dce677e0892a2a51d2b8e \ No newline at end of file diff --git a/test/cursorhint2.test b/test/cursorhint2.test index 3444fdf441..bc447d0f22 100644 --- a/test/cursorhint2.test +++ b/test/cursorhint2.test @@ -164,17 +164,19 @@ do_extract_hints_test 2.10 { x2 {AND(EQ(c1,ADD(32,32)),EQ(c0,r[2]))} } -do_extract_hints_test 2.11 { - SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE x2.b LIKE 'abc%' -} { - x2 {AND(expr,EQ(c0,r[2]))} +ifcapable !icu { + # This test only works using the built-in LIKE, not the ICU LIKE extension. + do_extract_hints_test 2.11 { + SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE x2.b LIKE 'abc%' + } { + x2 {AND(expr,EQ(c0,r[2]))} + } } -do_extract_hints_test 2.11 { +do_extract_hints_test 2.12 { SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE coalesce(x2.b, 1) } { x2 {EQ(c0,r[2])} } finish_test - From a2bfa046ea93dab08e025809f4fea2629c71fbea Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 4 Nov 2016 12:05:29 +0000 Subject: [PATCH 0957/1484] Avoid a crash that can occur after an obscure OOM in the built-in INSTR() function. FossilOrigin-Name: b86b79c442a58d10aa005ba4f34095375a88d242 --- manifest | 15 +++++----- manifest.uuid | 2 +- src/func.c | 2 ++ test/instrfault.test | 68 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 79 insertions(+), 8 deletions(-) create mode 100644 test/instrfault.test diff --git a/manifest b/manifest index 835eb740f6..daade9e2e4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Mark\sthe\sICU\sextension\sfunctions\sas\sdeterministic. -D 2016-11-04T12:03:26.544 +C Avoid\sa\scrash\sthat\scan\soccur\safter\san\sobscure\sOOM\sin\sthe\sbuilt-in\sINSTR()\nfunction. +D 2016-11-04T12:05:29.977 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e0217f2d35a0448abbe4b066132ae20136e8b408 @@ -343,7 +343,7 @@ F src/delete.c cb3f6300df24c26c609778b2731f82644b5532ec F src/expr.c ce7110980fac6dfdfbe1e393443bdb79bad29339 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c b9ca262f6ad4d030a3cab737ebf9b0b3c8b4ac80 -F src/func.c 29cc9acb170ec1387b9f63eb52cd85f8de96c771 +F src/func.c 7057bc2c105b82faa668d8e2ec85fad4540e5c51 F src/global.c 9da4ca5d74b90715f0ec4957f3d17a4749009f34 F src/hash.c 63d0ee752a3b92d4695b2b1f5259c4621b2cfebd F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4 @@ -862,6 +862,7 @@ F test/insert3.test 1b7db95a03ad9c5013fdf7d6722b6cd66ee55e30 F test/insert4.test a20432f1c0fbbcff8f11d0e6ab4acb8c9db58023 F test/insert5.test 394f96728d1258f406fe5f5aeb0aaf29487c39a6 F test/instr.test 737bbf80685232033f3abedc6ae92f75860b5dd2 +F test/instrfault.test aa90b7c3486a069151b28384ae525644a1f79d51 F test/intarray.test 066b7d7ac38d25bf96f87f1b017bfc687551cdd4 F test/interrupt.test dfe9a67a94b0b2d8f70545ba1a6cca10780d71cc F test/interrupt2.test 829b06f9e20a6c378d8bd121b26c337f4dfa36e5 @@ -1529,7 +1530,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 97354093bceff28714a605068851cfa026c8272a -R e3306eee283049a63433ee2c85b74690 -U drh -Z 8e57808346e33a5bd8a5f1ed64de48bd +P afbbb6c66a85ff3f4c8dce677e0892a2a51d2b8e +R 54226d0f905e5410be62ada12fc4c3f1 +U dan +Z 547f4b4fa61cca40324639e3127db72b diff --git a/manifest.uuid b/manifest.uuid index a8a561ff4e..e7888e6970 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -afbbb6c66a85ff3f4c8dce677e0892a2a51d2b8e \ No newline at end of file +b86b79c442a58d10aa005ba4f34095375a88d242 \ No newline at end of file diff --git a/src/func.c b/src/func.c index 79bb1e3dd2..6ec0962de0 100644 --- a/src/func.c +++ b/src/func.c @@ -208,6 +208,8 @@ static void instrFunc( zHaystack = sqlite3_value_text(argv[0]); zNeedle = sqlite3_value_text(argv[1]); isText = 1; + if( zNeedle==0 ) return; + assert( zHaystack ); } while( nNeedle<=nHaystack && memcmp(zHaystack, zNeedle, nNeedle)!=0 ){ N++; diff --git a/test/instrfault.test b/test/instrfault.test new file mode 100644 index 0000000000..e2d93e742d --- /dev/null +++ b/test/instrfault.test @@ -0,0 +1,68 @@ +# 2016 November 4 +# +# 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 regression tests for SQLite library. The +# focus of this file is testing OOM error handling within the built-in +# INSTR() function. +# + + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix instrfault + +# Use big NEEDLE and HAYSTACK strings. Strings so large they cannot +# use lookaside buffers. +# +set ::NEEDLE [string repeat "abcdefghijklmnopqrstuvwxyz" 10] +set ::HAYSTACK "[string repeat 123 10]$NEEDLE[string repeat 456 10]" + +foreach {enc} { + utf8 + utf16 +} { + reset_db + execsql "PRAGMA encoding = $enc" + do_execsql_test 1.$enc.1 { + CREATE TABLE t1(n, h); + INSERT INTO t1 VALUES($::NEEDLE, $::HAYSTACK); + } {} + + do_faultsim_test 1.$enc.1 -faults oom-t* -prep { + execsql { SELECT instr(h, n) FROM t1 } + } -body { + execsql { SELECT instr(h, n) FROM t1 } + } -test { + faultsim_test_result {0 31} + } + + do_faultsim_test 1.$enc.2 -faults oom-t* -prep { + execsql { SELECT instr($::HAYSTACK, $::NEEDLE) FROM t1 } + } -body { + execsql { SELECT instr($::HAYSTACK, $::NEEDLE) FROM t1 } + } -test { + faultsim_test_result {0 31} + } + + do_faultsim_test 1.$enc.3 -faults oom-t* -prep { + set ::stmt [sqlite3_prepare_v2 db "SELECT instr(?, ?)" -1 dummy] + sqlite3_bind_text $::stmt 1 $::HAYSTACK [string length $::HAYSTACK] + sqlite3_bind_text $::stmt 2 $::NEEDLE [string length $::NEEDLE] + } -body { + set rc [sqlite3_step $::stmt] + if {$rc=="SQLITE_NOMEM"} { error "out of memory" } + sqlite3_column_int $::stmt 0 + } -test { + faultsim_test_result {0 31} + sqlite3_finalize $::stmt + } +} + +finish_test From ad875e741601ea1fa749c18047ce8c1f34e8c510 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 7 Nov 2016 13:37:28 +0000 Subject: [PATCH 0958/1484] Fix the JSON1 extension so that the JSON validator correctly rejects malformed backslash escapes within string literals. FossilOrigin-Name: 7a63539169a384960e30a63e0c8e9b0f07fa431e --- ext/misc/json1.c | 28 ++++- manifest | 16 +-- manifest.uuid | 2 +- test/json101.test | 307 +++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 336 insertions(+), 17 deletions(-) diff --git a/ext/misc/json1.c b/ext/misc/json1.c index 61c52ebe61..839e133bf2 100644 --- a/ext/misc/json1.c +++ b/ext/misc/json1.c @@ -49,13 +49,15 @@ SQLITE_EXTENSION_INIT1 #ifdef sqlite3Isdigit /* Use the SQLite core versions if this routine is part of the ** SQLite amalgamation */ -# define safe_isdigit(x) sqlite3Isdigit(x) -# define safe_isalnum(x) sqlite3Isalnum(x) +# define safe_isdigit(x) sqlite3Isdigit(x) +# define safe_isalnum(x) sqlite3Isalnum(x) +# define safe_isxdigit(x) sqlite3Isxdigit(x) #else /* Use the standard library for separate compilation */ #include /* amalgamator: keep */ -# define safe_isdigit(x) isdigit((unsigned char)(x)) -# define safe_isalnum(x) isalnum((unsigned char)(x)) +# define safe_isdigit(x) isdigit((unsigned char)(x)) +# define safe_isalnum(x) isalnum((unsigned char)(x)) +# define safe_isxdigit(x) isxdigit((unsigned char)(x)) #endif /* @@ -702,6 +704,15 @@ static int jsonParseAddNode( return pParse->nNode++; } +/* +** Return true if z[] begins with 4 (or more) hexadecimal digits +*/ +static int jsonIs4Hex(const char *z){ + int i; + for(i=0; i<4; i++) if( !safe_isxdigit(z[i]) ) return 0; + return 1; +} + /* ** Parse a single JSON value which begins at pParse->zJson[i]. Return the ** index of the first character past the end of the value parsed. @@ -776,8 +787,13 @@ static int jsonParseValue(JsonParse *pParse, u32 i){ if( c==0 ) return -1; if( c=='\\' ){ c = pParse->zJson[++j]; - if( c==0 ) return -1; - jnFlags = JNODE_ESCAPE; + if( c=='"' || c=='\\' || c=='/' || c=='b' || c=='f' + || c=='n' || c=='r' || c=='t' + || (c=='u' && jsonIs4Hex(pParse->zJson+j+1)) ){ + jnFlags = JNODE_ESCAPE; + }else{ + return -1; + } }else if( c=='"' ){ break; } diff --git a/manifest b/manifest index daade9e2e4..8ea3d627b0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sa\scrash\sthat\scan\soccur\safter\san\sobscure\sOOM\sin\sthe\sbuilt-in\sINSTR()\nfunction. -D 2016-11-04T12:05:29.977 +C Fix\sthe\sJSON1\sextension\sso\sthat\sthe\sJSON\svalidator\scorrectly\srejects\smalformed\nbackslash\sescapes\swithin\sstring\sliterals. +D 2016-11-07T13:37:28.861 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e0217f2d35a0448abbe4b066132ae20136e8b408 @@ -213,7 +213,7 @@ F ext/misc/eval.c f971962e92ebb8b0a4e6b62949463ee454d88fa2 F ext/misc/fileio.c d4171c815d6543a9edef8308aab2951413cd8d0f F ext/misc/fuzzer.c 7c64b8197bb77b7d64eff7cac7848870235d4c25 F ext/misc/ieee754.c f190d0cc5182529acb15babd177781be1ac1718c -F ext/misc/json1.c 9799e4252b305edcbe659329eec3ca80ed85f968 +F ext/misc/json1.c 813a2ff17b3e951a4b875ef79b5f4a0543cb0a2d F ext/misc/memvfs.c e5225bc22e79dde6b28380f3a068ddf600683a33 F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342 F ext/misc/percentile.c 92699c8cd7d517ff610e6037e56506f8904dae2e @@ -886,7 +886,7 @@ F test/journal3.test ff8af941f9e06161d3db1b46bb9f965ff0e7f307 F test/jrnlmode.test 7864d59cf7f6e552b9b99ba0f38acd167edc10fa F test/jrnlmode2.test 81610545a4e6ed239ea8fa661891893385e23a1d F test/jrnlmode3.test 556b447a05be0e0963f4311e95ab1632b11c9eaa -F test/json101.test 865776ed8580703e1684fe4b8ee2e473333bb121 +F test/json101.test c0897616f32d95431f37fd291cb78742181980ac F test/json102.test bf3fe7a706d30936a76a0f7a0375e1e8e73aff5a F test/json103.test c5f6b85e69de05f6b3195f9f9d5ce9cd179099a0 F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff @@ -1530,7 +1530,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P afbbb6c66a85ff3f4c8dce677e0892a2a51d2b8e -R 54226d0f905e5410be62ada12fc4c3f1 -U dan -Z 547f4b4fa61cca40324639e3127db72b +P b86b79c442a58d10aa005ba4f34095375a88d242 +R 7a809bd65e85c52e8075f2c4e33138f7 +U drh +Z 3735bc72c61a220065b296aebe8a3b9c diff --git a/manifest.uuid b/manifest.uuid index e7888e6970..5fedc2cefc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b86b79c442a58d10aa005ba4f34095375a88d242 \ No newline at end of file +7a63539169a384960e30a63e0c8e9b0f07fa431e \ No newline at end of file diff --git a/test/json101.test b/test/json101.test index 3ee007c1cb..37123eef1d 100644 --- a/test/json101.test +++ b/test/json101.test @@ -382,8 +382,311 @@ do_catchsql_test json-9.7 { SELECT json_quote() } {1 {wrong number of arguments to function json_quote()}} - - +# Make sure only valid backslash-escapes are accepted. +# +do_execsql_test json-10.1 { + SELECT json_valid('" \ "'); +} {0} +do_execsql_test json-10.2 { + SELECT json_valid('" \! "'); +} {0} +do_execsql_test json-10.3 { + SELECT json_valid('" \" "'); +} {1} +do_execsql_test json-10.4 { + SELECT json_valid('" \# "'); +} {0} +do_execsql_test json-10.5 { + SELECT json_valid('" \$ "'); +} {0} +do_execsql_test json-10.6 { + SELECT json_valid('" \% "'); +} {0} +do_execsql_test json-10.7 { + SELECT json_valid('" \& "'); +} {0} +do_execsql_test json-10.8 { + SELECT json_valid('" \'' "'); +} {0} +do_execsql_test json-10.9 { + SELECT json_valid('" \( "'); +} {0} +do_execsql_test json-10.10 { + SELECT json_valid('" \) "'); +} {0} +do_execsql_test json-10.11 { + SELECT json_valid('" \* "'); +} {0} +do_execsql_test json-10.12 { + SELECT json_valid('" \+ "'); +} {0} +do_execsql_test json-10.13 { + SELECT json_valid('" \, "'); +} {0} +do_execsql_test json-10.14 { + SELECT json_valid('" \- "'); +} {0} +do_execsql_test json-10.15 { + SELECT json_valid('" \. "'); +} {0} +do_execsql_test json-10.16 { + SELECT json_valid('" \/ "'); +} {1} +do_execsql_test json-10.17 { + SELECT json_valid('" \0 "'); +} {0} +do_execsql_test json-10.18 { + SELECT json_valid('" \1 "'); +} {0} +do_execsql_test json-10.19 { + SELECT json_valid('" \2 "'); +} {0} +do_execsql_test json-10.20 { + SELECT json_valid('" \3 "'); +} {0} +do_execsql_test json-10.21 { + SELECT json_valid('" \4 "'); +} {0} +do_execsql_test json-10.22 { + SELECT json_valid('" \5 "'); +} {0} +do_execsql_test json-10.23 { + SELECT json_valid('" \6 "'); +} {0} +do_execsql_test json-10.24 { + SELECT json_valid('" \7 "'); +} {0} +do_execsql_test json-10.25 { + SELECT json_valid('" \8 "'); +} {0} +do_execsql_test json-10.26 { + SELECT json_valid('" \9 "'); +} {0} +do_execsql_test json-10.27 { + SELECT json_valid('" \: "'); +} {0} +do_execsql_test json-10.28 { + SELECT json_valid('" \; "'); +} {0} +do_execsql_test json-10.29 { + SELECT json_valid('" \< "'); +} {0} +do_execsql_test json-10.30 { + SELECT json_valid('" \= "'); +} {0} +do_execsql_test json-10.31 { + SELECT json_valid('" \> "'); +} {0} +do_execsql_test json-10.32 { + SELECT json_valid('" \? "'); +} {0} +do_execsql_test json-10.33 { + SELECT json_valid('" \@ "'); +} {0} +do_execsql_test json-10.34 { + SELECT json_valid('" \A "'); +} {0} +do_execsql_test json-10.35 { + SELECT json_valid('" \B "'); +} {0} +do_execsql_test json-10.36 { + SELECT json_valid('" \C "'); +} {0} +do_execsql_test json-10.37 { + SELECT json_valid('" \D "'); +} {0} +do_execsql_test json-10.38 { + SELECT json_valid('" \E "'); +} {0} +do_execsql_test json-10.39 { + SELECT json_valid('" \F "'); +} {0} +do_execsql_test json-10.40 { + SELECT json_valid('" \G "'); +} {0} +do_execsql_test json-10.41 { + SELECT json_valid('" \H "'); +} {0} +do_execsql_test json-10.42 { + SELECT json_valid('" \I "'); +} {0} +do_execsql_test json-10.43 { + SELECT json_valid('" \J "'); +} {0} +do_execsql_test json-10.44 { + SELECT json_valid('" \K "'); +} {0} +do_execsql_test json-10.45 { + SELECT json_valid('" \L "'); +} {0} +do_execsql_test json-10.46 { + SELECT json_valid('" \M "'); +} {0} +do_execsql_test json-10.47 { + SELECT json_valid('" \N "'); +} {0} +do_execsql_test json-10.48 { + SELECT json_valid('" \O "'); +} {0} +do_execsql_test json-10.49 { + SELECT json_valid('" \P "'); +} {0} +do_execsql_test json-10.50 { + SELECT json_valid('" \Q "'); +} {0} +do_execsql_test json-10.51 { + SELECT json_valid('" \R "'); +} {0} +do_execsql_test json-10.52 { + SELECT json_valid('" \S "'); +} {0} +do_execsql_test json-10.53 { + SELECT json_valid('" \T "'); +} {0} +do_execsql_test json-10.54 { + SELECT json_valid('" \U "'); +} {0} +do_execsql_test json-10.55 { + SELECT json_valid('" \V "'); +} {0} +do_execsql_test json-10.56 { + SELECT json_valid('" \W "'); +} {0} +do_execsql_test json-10.57 { + SELECT json_valid('" \X "'); +} {0} +do_execsql_test json-10.58 { + SELECT json_valid('" \Y "'); +} {0} +do_execsql_test json-10.59 { + SELECT json_valid('" \Z "'); +} {0} +do_execsql_test json-10.60 { + SELECT json_valid('" \[ "'); +} {0} +do_execsql_test json-10.61 { + SELECT json_valid('" \\ "'); +} {1} +do_execsql_test json-10.62 { + SELECT json_valid('" \] "'); +} {0} +do_execsql_test json-10.63 { + SELECT json_valid('" \^ "'); +} {0} +do_execsql_test json-10.64 { + SELECT json_valid('" \_ "'); +} {0} +do_execsql_test json-10.65 { + SELECT json_valid('" \` "'); +} {0} +do_execsql_test json-10.66 { + SELECT json_valid('" \a "'); +} {0} +do_execsql_test json-10.67 { + SELECT json_valid('" \b "'); +} {1} +do_execsql_test json-10.68 { + SELECT json_valid('" \c "'); +} {0} +do_execsql_test json-10.69 { + SELECT json_valid('" \d "'); +} {0} +do_execsql_test json-10.70 { + SELECT json_valid('" \e "'); +} {0} +do_execsql_test json-10.71 { + SELECT json_valid('" \f "'); +} {1} +do_execsql_test json-10.72 { + SELECT json_valid('" \g "'); +} {0} +do_execsql_test json-10.73 { + SELECT json_valid('" \h "'); +} {0} +do_execsql_test json-10.74 { + SELECT json_valid('" \i "'); +} {0} +do_execsql_test json-10.75 { + SELECT json_valid('" \j "'); +} {0} +do_execsql_test json-10.76 { + SELECT json_valid('" \k "'); +} {0} +do_execsql_test json-10.77 { + SELECT json_valid('" \l "'); +} {0} +do_execsql_test json-10.78 { + SELECT json_valid('" \m "'); +} {0} +do_execsql_test json-10.79 { + SELECT json_valid('" \n "'); +} {1} +do_execsql_test json-10.80 { + SELECT json_valid('" \o "'); +} {0} +do_execsql_test json-10.81 { + SELECT json_valid('" \p "'); +} {0} +do_execsql_test json-10.82 { + SELECT json_valid('" \q "'); +} {0} +do_execsql_test json-10.83 { + SELECT json_valid('" \r "'); +} {1} +do_execsql_test json-10.84 { + SELECT json_valid('" \s "'); +} {0} +do_execsql_test json-10.85 { + SELECT json_valid('" \t "'); +} {1} +do_execsql_test json-10.86.0 { + SELECT json_valid('" \u "'); +} {0} +do_execsql_test json-10.86.1 { + SELECT json_valid('" \ua "'); +} {0} +do_execsql_test json-10.86.2 { + SELECT json_valid('" \uab "'); +} {0} +do_execsql_test json-10.86.3 { + SELECT json_valid('" \uabc "'); +} {0} +do_execsql_test json-10.86.4 { + SELECT json_valid('" \uabcd "'); +} {1} +do_execsql_test json-10.86.5 { + SELECT json_valid('" \uFEDC "'); +} {1} +do_execsql_test json-10.86.6 { + SELECT json_valid('" \u1234 "'); +} {1} +do_execsql_test json-10.87 { + SELECT json_valid('" \v "'); +} {0} +do_execsql_test json-10.88 { + SELECT json_valid('" \w "'); +} {0} +do_execsql_test json-10.89 { + SELECT json_valid('" \x "'); +} {0} +do_execsql_test json-10.90 { + SELECT json_valid('" \y "'); +} {0} +do_execsql_test json-10.91 { + SELECT json_valid('" \z "'); +} {0} +do_execsql_test json-10.92 { + SELECT json_valid('" \{ "'); +} {0} +do_execsql_test json-10.93 { + SELECT json_valid('" \| "'); +} {0} +do_execsql_test json-10.94 { + SELECT json_valid('" \} "'); +} {0} +do_execsql_test json-10.95 { + SELECT json_valid('" \~ "'); +} {0} finish_test From 27b2d1b88b432d7145bb7ba540e8d6552a91d89f Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 7 Nov 2016 15:15:42 +0000 Subject: [PATCH 0959/1484] Replace some unreachable branches from the JSON1 extension with assert(). FossilOrigin-Name: 145cd13e3c5a42a717807bcc13c0f7212f38bff8 --- ext/misc/json1.c | 11 ++++++----- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/ext/misc/json1.c b/ext/misc/json1.c index 839e133bf2..df6aa73247 100644 --- a/ext/misc/json1.c +++ b/ext/misc/json1.c @@ -595,12 +595,13 @@ static void jsonReturn( c = z[++i]; if( c=='u' ){ u32 v = 0, k; - for(k=0; k<4 && i='0' && c<='9' ) v = v*16 + c - '0'; - else if( c>='A' && c<='F' ) v = v*16 + c - 'A' + 10; - else if( c>='a' && c<='f' ) v = v*16 + c - 'a' + 10; - else break; + assert( safe_isxdigit(c) ); + if( c<='9' ) v = v*16 + c - '0'; + else if( c<='F' ) v = v*16 + c - 'A' + 10; + else v = v*16 + c - 'a' + 10; } if( v==0 ) break; if( v<=0x7f ){ diff --git a/manifest b/manifest index 8ea3d627b0..754789c49f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\sJSON1\sextension\sso\sthat\sthe\sJSON\svalidator\scorrectly\srejects\smalformed\nbackslash\sescapes\swithin\sstring\sliterals. -D 2016-11-07T13:37:28.861 +C Replace\ssome\sunreachable\sbranches\sfrom\sthe\sJSON1\sextension\swith\sassert(). +D 2016-11-07T15:15:42.501 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e0217f2d35a0448abbe4b066132ae20136e8b408 @@ -213,7 +213,7 @@ F ext/misc/eval.c f971962e92ebb8b0a4e6b62949463ee454d88fa2 F ext/misc/fileio.c d4171c815d6543a9edef8308aab2951413cd8d0f F ext/misc/fuzzer.c 7c64b8197bb77b7d64eff7cac7848870235d4c25 F ext/misc/ieee754.c f190d0cc5182529acb15babd177781be1ac1718c -F ext/misc/json1.c 813a2ff17b3e951a4b875ef79b5f4a0543cb0a2d +F ext/misc/json1.c b8aa1219d25df9c135e067844f515cbaa452395d F ext/misc/memvfs.c e5225bc22e79dde6b28380f3a068ddf600683a33 F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342 F ext/misc/percentile.c 92699c8cd7d517ff610e6037e56506f8904dae2e @@ -1530,7 +1530,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b86b79c442a58d10aa005ba4f34095375a88d242 -R 7a809bd65e85c52e8075f2c4e33138f7 +P 7a63539169a384960e30a63e0c8e9b0f07fa431e +R 301a8516f843000230cab1da4034b3ce U drh -Z 3735bc72c61a220065b296aebe8a3b9c +Z 60f1523be64826a7825849d4d0d5f745 diff --git a/manifest.uuid b/manifest.uuid index 5fedc2cefc..e396626575 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7a63539169a384960e30a63e0c8e9b0f07fa431e \ No newline at end of file +145cd13e3c5a42a717807bcc13c0f7212f38bff8 \ No newline at end of file From 6850a633938816b123b52af6a7f2fa45e7f6c252 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 7 Nov 2016 18:18:08 +0000 Subject: [PATCH 0960/1484] Fix OOM error reporting in the json1_group_object() SQL function. Remove an unreachable branch from the JSON1 logic. FossilOrigin-Name: b54098491531cd26ed461275ef4aae3d3ec9065e --- ext/misc/json1.c | 6 +++--- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/ext/misc/json1.c b/ext/misc/json1.c index df6aa73247..327ad57500 100644 --- a/ext/misc/json1.c +++ b/ext/misc/json1.c @@ -1662,7 +1662,7 @@ static void jsonObjectFinal(sqlite3_context *ctx){ if( pStr ){ jsonAppendChar(pStr, '}'); if( pStr->bErr ){ - if( pStr->bErr==0 ) sqlite3_result_error_nomem(ctx); + if( pStr->bErr==1 ) sqlite3_result_error_nomem(ctx); assert( pStr->bStatic ); }else{ sqlite3_result_text(ctx, pStr->zBuf, pStr->nUsed, @@ -1940,9 +1940,9 @@ static int jsonEachColumn( /* For json_each() path and root are the same so fall through ** into the root case */ } - case JEACH_ROOT: { + default: { const char *zRoot = p->zRoot; - if( zRoot==0 ) zRoot = "$"; + if( zRoot==0 ) zRoot = "$"; sqlite3_result_text(ctx, zRoot, -1, SQLITE_STATIC); break; } diff --git a/manifest b/manifest index 754789c49f..63b59e28d9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Replace\ssome\sunreachable\sbranches\sfrom\sthe\sJSON1\sextension\swith\sassert(). -D 2016-11-07T15:15:42.501 +C Fix\sOOM\serror\sreporting\sin\sthe\sjson1_group_object()\sSQL\sfunction.\s\sRemove\nan\sunreachable\sbranch\sfrom\sthe\sJSON1\slogic. +D 2016-11-07T18:18:08.418 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e0217f2d35a0448abbe4b066132ae20136e8b408 @@ -213,7 +213,7 @@ F ext/misc/eval.c f971962e92ebb8b0a4e6b62949463ee454d88fa2 F ext/misc/fileio.c d4171c815d6543a9edef8308aab2951413cd8d0f F ext/misc/fuzzer.c 7c64b8197bb77b7d64eff7cac7848870235d4c25 F ext/misc/ieee754.c f190d0cc5182529acb15babd177781be1ac1718c -F ext/misc/json1.c b8aa1219d25df9c135e067844f515cbaa452395d +F ext/misc/json1.c e0797ef1bfa637429ceab9140ecba620809ee02a F ext/misc/memvfs.c e5225bc22e79dde6b28380f3a068ddf600683a33 F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342 F ext/misc/percentile.c 92699c8cd7d517ff610e6037e56506f8904dae2e @@ -1530,7 +1530,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 7a63539169a384960e30a63e0c8e9b0f07fa431e -R 301a8516f843000230cab1da4034b3ce +P 145cd13e3c5a42a717807bcc13c0f7212f38bff8 +R 5bf098c60c4b2458fcef57830990e98c U drh -Z 60f1523be64826a7825849d4d0d5f745 +Z beca6c8fe13d65bdcd7b60c2b18aa7d8 diff --git a/manifest.uuid b/manifest.uuid index e396626575..3bdfc11d47 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -145cd13e3c5a42a717807bcc13c0f7212f38bff8 \ No newline at end of file +b54098491531cd26ed461275ef4aae3d3ec9065e \ No newline at end of file From 662389b2653b28e74182034c5febf4cadfe9b272 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 8 Nov 2016 00:30:11 +0000 Subject: [PATCH 0961/1484] Tweaks to speedtest1.c to better reflect mobile usage based on findings in the "Pocket Data" paper by Kennedy, Ajay, Challen, and Ziarek. FossilOrigin-Name: b5733cae3c519482cf6bc642bd63814afb113d35 --- manifest | 12 ++++----- manifest.uuid | 2 +- test/speedtest1.c | 65 +++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 67 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 63b59e28d9..ec85f85a9a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sOOM\serror\sreporting\sin\sthe\sjson1_group_object()\sSQL\sfunction.\s\sRemove\nan\sunreachable\sbranch\sfrom\sthe\sJSON1\slogic. -D 2016-11-07T18:18:08.418 +C Tweaks\sto\sspeedtest1.c\sto\sbetter\sreflect\smobile\susage\sbased\son\sfindings\sin\nthe\s"Pocket\sData"\spaper\sby\sKennedy,\sAjay,\sChallen,\sand\sZiarek. +D 2016-11-08T00:30:11.643 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e0217f2d35a0448abbe4b066132ae20136e8b408 @@ -1116,7 +1116,7 @@ F test/speed3.test 694affeb9100526007436334cf7d08f3d74b85ef F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715 F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b -F test/speedtest1.c ffb96750d02e21d1acdbf63464153580825206d7 +F test/speedtest1.c 4b2538e937332a1fb280c1db42b07e1690a39789 F test/spellfix.test f9c1f431e2c096c8775fec032952320c0e4700db F test/spellfix2.test dfc8f519a3fc204cb2dfa8b4f29821ae90f6f8c3 F test/spellfix3.test 0f9efaaa502a0e0a09848028518a6fb096c8ad33 @@ -1530,7 +1530,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 145cd13e3c5a42a717807bcc13c0f7212f38bff8 -R 5bf098c60c4b2458fcef57830990e98c +P b54098491531cd26ed461275ef4aae3d3ec9065e +R 29c0fc43bc0904b3fe84b3580650f63d U drh -Z beca6c8fe13d65bdcd7b60c2b18aa7d8 +Z 7fea0b281bf173d5dc107b8135144da1 diff --git a/manifest.uuid b/manifest.uuid index 3bdfc11d47..c718df4861 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b54098491531cd26ed461275ef4aae3d3ec9065e \ No newline at end of file +b5733cae3c519482cf6bc642bd63814afb113d35 \ No newline at end of file diff --git a/test/speedtest1.c b/test/speedtest1.c index a77896fc1f..8bb8d6c710 100644 --- a/test/speedtest1.c +++ b/test/speedtest1.c @@ -529,7 +529,7 @@ void testset_main(void){ speedtest1_begin_test(130, "%d SELECTS, numeric BETWEEN, unindexed", n); speedtest1_exec("BEGIN"); speedtest1_prepare( - "SELECT count(*), avg(b), sum(length(c)) FROM t1\n" + "SELECT count(*), avg(b), sum(length(c)), group_concat(c) FROM t1\n" " WHERE b BETWEEN ?1 AND ?2; -- %d times", n ); for(i=1; i<=n; i++){ @@ -549,7 +549,7 @@ void testset_main(void){ speedtest1_begin_test(140, "%d SELECTS, LIKE, unindexed", n); speedtest1_exec("BEGIN"); speedtest1_prepare( - "SELECT count(*), avg(b), sum(length(c)) FROM t1\n" + "SELECT count(*), avg(b), sum(length(c)), group_concat(c) FROM t1\n" " WHERE c LIKE ?1; -- %d times", n ); for(i=1; i<=n; i++){ @@ -625,7 +625,7 @@ void testset_main(void){ speedtest1_begin_test(160, "%d SELECTS, numeric BETWEEN, indexed", n); speedtest1_exec("BEGIN"); speedtest1_prepare( - "SELECT count(*), avg(b), sum(length(c)) FROM t1\n" + "SELECT count(*), avg(b), sum(length(c)), group_concat(a) FROM t1\n" " WHERE b BETWEEN ?1 AND ?2; -- %d times", n ); for(i=1; i<=n; i++){ @@ -645,7 +645,7 @@ void testset_main(void){ speedtest1_begin_test(161, "%d SELECTS, numeric BETWEEN, PK", n); speedtest1_exec("BEGIN"); speedtest1_prepare( - "SELECT count(*), avg(b), sum(length(c)) FROM t2\n" + "SELECT count(*), avg(b), sum(length(c)), group_concat(a) FROM t2\n" " WHERE a BETWEEN ?1 AND ?2; -- %d times", n ); for(i=1; i<=n; i++){ @@ -665,7 +665,7 @@ void testset_main(void){ speedtest1_begin_test(170, "%d SELECTS, text BETWEEN, indexed", n); speedtest1_exec("BEGIN"); speedtest1_prepare( - "SELECT count(*), avg(b), sum(length(c)) FROM t1\n" + "SELECT count(*), avg(b), sum(length(c)), group_concat(a) FROM t1\n" " WHERE c BETWEEN ?1 AND (?1||'~'); -- %d times", n ); for(i=1; i<=n; i++){ @@ -831,6 +831,61 @@ void testset_main(void){ speedtest1_run(); speedtest1_end_test(); + sz = n = g.szTest*700; + zNum[0] = 0; + maxb = roundup_allones(sz/3); + speedtest1_begin_test(400, "%d INSERT OR REPLACE ops on an IPK", n); + speedtest1_exec("BEGIN"); + speedtest1_exec("CREATE%s TABLE t5(a INTEGER PRIMARY KEY, b %s);", + isTemp(9), g.zNN); + speedtest1_prepare("INSERT OR REPLACE INTO t5 VALUES(?1,?2); -- %d times",n); + for(i=1; i<=n; i++){ + x1 = swizzle(i,maxb); + speedtest1_numbername(i, zNum, sizeof(zNum)); + sqlite3_bind_int(g.pStmt, 1, (sqlite3_int64)x1); + sqlite3_bind_text(g.pStmt, 2, zNum, -1, SQLITE_STATIC); + speedtest1_run(); + } + speedtest1_exec("COMMIT"); + speedtest1_end_test(); + speedtest1_begin_test(410, "%d SELECTS on an IPK", n); + speedtest1_prepare("SELECT b FROM t5 WHERE a=?1; -- %d times",n); + for(i=1; i<=n; i++){ + x1 = swizzle(i,maxb); + sqlite3_bind_int(g.pStmt, 1, (sqlite3_int64)x1); + speedtest1_run(); + } + speedtest1_end_test(); + + sz = n = g.szTest*700; + zNum[0] = 0; + maxb = roundup_allones(sz/3); + speedtest1_begin_test(500, "%d INSERT OR REPLACE ops on TEXT PK", n); + speedtest1_exec("BEGIN"); + speedtest1_exec("CREATE%s TABLE t6(a TEXT PRIMARY KEY, b %s)%s;", + isTemp(9), g.zNN, + sqlite3_libversion_number()>=3008002 ? "WITHOUT ROWID" : ""); + speedtest1_prepare("INSERT OR REPLACE INTO t6 VALUES(?1,?2); -- %d times",n); + for(i=1; i<=n; i++){ + x1 = swizzle(i,maxb); + speedtest1_numbername(x1, zNum, sizeof(zNum)); + sqlite3_bind_int(g.pStmt, 2, i); + sqlite3_bind_text(g.pStmt, 1, zNum, -1, SQLITE_STATIC); + speedtest1_run(); + } + speedtest1_exec("COMMIT"); + speedtest1_end_test(); + speedtest1_begin_test(510, "%d SELECTS on an IPK", n); + speedtest1_prepare("SELECT b FROM t6 WHERE a=?1; -- %d times",n); + for(i=1; i<=n; i++){ + x1 = swizzle(i,maxb); + speedtest1_numbername(x1, zNum, sizeof(zNum)); + sqlite3_bind_text(g.pStmt, 1, zNum, -1, SQLITE_STATIC); + speedtest1_run(); + } + speedtest1_end_test(); + + speedtest1_begin_test(980, "PRAGMA integrity_check"); speedtest1_exec("PRAGMA integrity_check"); speedtest1_end_test(); From 0a22c865e475d96cf786574d32a5816d94b031f3 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 8 Nov 2016 16:27:59 +0000 Subject: [PATCH 0962/1484] Fix the speedtest1.c test program so that it gives closing "%" wildcards on LIKE searches. FossilOrigin-Name: c2f84f637f994c3b4522b48161185a4a2c5bca23 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/speedtest1.c | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index ec85f85a9a..2bead90866 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Tweaks\sto\sspeedtest1.c\sto\sbetter\sreflect\smobile\susage\sbased\son\sfindings\sin\nthe\s"Pocket\sData"\spaper\sby\sKennedy,\sAjay,\sChallen,\sand\sZiarek. -D 2016-11-08T00:30:11.643 +C Fix\sthe\sspeedtest1.c\stest\sprogram\sso\sthat\sit\sgives\sclosing\s"%"\swildcards\non\sLIKE\ssearches. +D 2016-11-08T16:27:59.909 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e0217f2d35a0448abbe4b066132ae20136e8b408 @@ -1116,7 +1116,7 @@ F test/speed3.test 694affeb9100526007436334cf7d08f3d74b85ef F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715 F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b -F test/speedtest1.c 4b2538e937332a1fb280c1db42b07e1690a39789 +F test/speedtest1.c cb433ff792a1b317d0787416bb8a57bbc3266871 F test/spellfix.test f9c1f431e2c096c8775fec032952320c0e4700db F test/spellfix2.test dfc8f519a3fc204cb2dfa8b4f29821ae90f6f8c3 F test/spellfix3.test 0f9efaaa502a0e0a09848028518a6fb096c8ad33 @@ -1530,7 +1530,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b54098491531cd26ed461275ef4aae3d3ec9065e -R 29c0fc43bc0904b3fe84b3580650f63d +P b5733cae3c519482cf6bc642bd63814afb113d35 +R 8410446de3d24d7eb0c98f660669793b U drh -Z 7fea0b281bf173d5dc107b8135144da1 +Z cf40cde00d3fe62227035d3b07dec2b1 diff --git a/manifest.uuid b/manifest.uuid index c718df4861..5e694defb6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b5733cae3c519482cf6bc642bd63814afb113d35 \ No newline at end of file +c2f84f637f994c3b4522b48161185a4a2c5bca23 \ No newline at end of file diff --git a/test/speedtest1.c b/test/speedtest1.c index 8bb8d6c710..244a1666ae 100644 --- a/test/speedtest1.c +++ b/test/speedtest1.c @@ -560,7 +560,7 @@ void testset_main(void){ zNum[len] = '%'; zNum[len+1] = 0; } - sqlite3_bind_text(g.pStmt, 1, zNum, len, SQLITE_STATIC); + sqlite3_bind_text(g.pStmt, 1, zNum, len+1, SQLITE_STATIC); speedtest1_run(); } speedtest1_exec("COMMIT"); @@ -582,7 +582,7 @@ void testset_main(void){ zNum[len] = '%'; zNum[len+1] = 0; } - sqlite3_bind_text(g.pStmt, 1, zNum, len, SQLITE_STATIC); + sqlite3_bind_text(g.pStmt, 1, zNum, len+1, SQLITE_STATIC); speedtest1_run(); } speedtest1_exec("COMMIT"); @@ -603,7 +603,7 @@ void testset_main(void){ zNum[len] = '%'; zNum[len+1] = 0; } - sqlite3_bind_text(g.pStmt, 1, zNum, len, SQLITE_STATIC); + sqlite3_bind_text(g.pStmt, 1, zNum, len+1, SQLITE_STATIC); speedtest1_run(); } speedtest1_exec("COMMIT"); From 9d06ff2cb7f4ae51be6f394532fc8a8a2b25758b Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 8 Nov 2016 17:19:22 +0000 Subject: [PATCH 0963/1484] Avoid generating OP_TableLock unnecessary instructions on btrees that are not sharable. FossilOrigin-Name: 8cb8516d2009d52d35a22263e4c892f162b34b81 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/build.c | 2 ++ 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 2bead90866..27b1efadaa 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\sspeedtest1.c\stest\sprogram\sso\sthat\sit\sgives\sclosing\s"%"\swildcards\non\sLIKE\ssearches. -D 2016-11-08T16:27:59.909 +C Avoid\sgenerating\sOP_TableLock\sunnecessary\sinstructions\son\sbtrees\sthat\s\nare\snot\ssharable. +D 2016-11-08T17:19:22.006 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e0217f2d35a0448abbe4b066132ae20136e8b408 @@ -333,7 +333,7 @@ F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 F src/btree.c 6ae1c17347fb2888b2b28a260b947b7717a9fca9 F src/btree.h d05b2fcc290991a8a3d9ea1816ddd55a4359dcde F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 -F src/build.c 59dcfdc1ee55439d069af301ef7f2e84421b5102 +F src/build.c fcd220ccf7cae1b50b700b37eca950cd72c64ff0 F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c a2a52d6e353f459d8ab0f07321f60fafa47d5421 @@ -1530,7 +1530,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b5733cae3c519482cf6bc642bd63814afb113d35 -R 8410446de3d24d7eb0c98f660669793b +P c2f84f637f994c3b4522b48161185a4a2c5bca23 +R 10ce1648dec21a665da138671841929b U drh -Z cf40cde00d3fe62227035d3b07dec2b1 +Z 8856bb137559d0d48b8e63db91d4ed8e diff --git a/manifest.uuid b/manifest.uuid index 5e694defb6..dcfe87a3ac 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c2f84f637f994c3b4522b48161185a4a2c5bca23 \ No newline at end of file +8cb8516d2009d52d35a22263e4c892f162b34b81 \ No newline at end of file diff --git a/src/build.c b/src/build.c index 508e747ea6..350cf9f713 100644 --- a/src/build.c +++ b/src/build.c @@ -59,6 +59,8 @@ void sqlite3TableLock( TableLock *p; assert( iDb>=0 ); + if( iDb==1 ) return; + if( !sqlite3BtreeSharable(pParse->db->aDb[iDb].pBt) ) return; for(i=0; inTableLock; i++){ p = &pToplevel->aTableLock[i]; if( p->iDb==iDb && p->iTab==iTab ){ From 3b908d41a0d3800a6ebe5dff42f4117fc342105c Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 8 Nov 2016 19:22:32 +0000 Subject: [PATCH 0964/1484] Avoid superfluous cursor seeks in "INSERT OR REPLACE" statements. FossilOrigin-Name: bec5b6d4d083556d111a89186b4f7b35b5e7cebf --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/insert.c | 16 +++++++++++++++- src/vdbe.c | 2 ++ 4 files changed, 26 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 27b1efadaa..9c94df9efd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sgenerating\sOP_TableLock\sunnecessary\sinstructions\son\sbtrees\sthat\s\nare\snot\ssharable. -D 2016-11-08T17:19:22.006 +C Avoid\ssuperfluous\scursor\sseeks\sin\s"INSERT\sOR\sREPLACE"\sstatements. +D 2016-11-08T19:22:32.125 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e0217f2d35a0448abbe4b066132ae20136e8b408 @@ -349,7 +349,7 @@ F src/hash.c 63d0ee752a3b92d4695b2b1f5259c4621b2cfebd F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4 F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 -F src/insert.c 2d5e197f2f60351937b201196965fd14cd88489c +F src/insert.c 8c1346304a9a386b036652475296103bae27e0a1 F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e F src/loadext.c 5d6642d141c07d366e43d359e94ec9de47add41d F src/main.c 694ac90557abdaa62151a6090670e107b0f2c2ab @@ -454,7 +454,7 @@ F src/update.c 8179e699dbd45b92934fd02d3d8e3732e8da8802 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 3e2da6101888d073e79ecc6af5e0a2f70fa1e498 F src/vacuum.c 33c174b28886b2faf26e503b5a49a1c01a9b1c16 -F src/vdbe.c 2edc4fa8a825c79a929766f50bc800ea158646d2 +F src/vdbe.c 20307c93ad55af6ab8f50b17147a4704d4f17dab F src/vdbe.h c044be7050ac6bf596eecc6ab159f5dbc020a3b7 F src/vdbeInt.h d8a56a491b752dbb5f671963b8c861ec72ea875e F src/vdbeapi.c 97129bec6b1553da50d8e73f523c278bda66d9f6 @@ -1530,7 +1530,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P c2f84f637f994c3b4522b48161185a4a2c5bca23 -R 10ce1648dec21a665da138671841929b -U drh -Z 8856bb137559d0d48b8e63db91d4ed8e +P 8cb8516d2009d52d35a22263e4c892f162b34b81 +R 36e33fba7941647bfb228c5ae67f2b63 +U dan +Z a11930824d648f16d0f222498c7f4b67 diff --git a/manifest.uuid b/manifest.uuid index dcfe87a3ac..0835b36ebc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8cb8516d2009d52d35a22263e4c892f162b34b81 \ No newline at end of file +bec5b6d4d083556d111a89186b4f7b35b5e7cebf \ No newline at end of file diff --git a/src/insert.c b/src/insert.c index 8167ff78c5..6ea3810a2a 100644 --- a/src/insert.c +++ b/src/insert.c @@ -995,12 +995,26 @@ void sqlite3Insert( #endif { int isReplace; /* Set to true if constraints may cause a replace */ + int bUseSeek; /* True to use OPFLAG_SEEKRESULT */ sqlite3GenerateConstraintChecks(pParse, pTab, aRegIdx, iDataCur, iIdxCur, regIns, 0, ipkColumn>=0, onError, endOfLoop, &isReplace, 0 ); sqlite3FkCheck(pParse, pTab, 0, regIns, 0, 0); + + /* Set the OPFLAG_USESEEKRESULT flag if either (a) there are no REPLACE + ** constraints or (b) there are no triggers and this table is not a + ** parent table in a foreign key constraint. It is safe to set the + ** flag in the second case as if any REPLACE constraint is hit, an + ** OP_Delete or OP_IdxDelete instruction will be executed on each + ** cursor that is disturbed. And these instructions both clear the + ** VdbeCursor.seekResult variable, disabling the OPFLAG_USESEEKRESULT + ** functionality. */ + bUseSeek = (isReplace==0 || (pTrigger==0 && + ((db->flags & SQLITE_ForeignKeys)==0 || sqlite3FkReferences(pTab)==0) + )); sqlite3CompleteInsertion(pParse, pTab, iDataCur, iIdxCur, - regIns, aRegIdx, 0, appendFlag, isReplace==0); + regIns, aRegIdx, 0, appendFlag, bUseSeek + ); } } diff --git a/src/vdbe.c b/src/vdbe.c index 8b47a37833..c2abeced04 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -4554,6 +4554,7 @@ case OP_Delete: { rc = sqlite3BtreeDelete(pC->uc.pCursor, pOp->p5); pC->cacheStatus = CACHE_STALE; + pC->seekResult = 0; if( rc ) goto abort_due_to_error; /* Invoke the update-hook if required. */ @@ -5109,6 +5110,7 @@ case OP_IdxDelete: { } assert( pC->deferredMoveto==0 ); pC->cacheStatus = CACHE_STALE; + pC->seekResult = 0; break; } From 9b4eaebc68ec3a209c698b1220ef2bc49cdb41dc Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 9 Nov 2016 00:10:33 +0000 Subject: [PATCH 0965/1484] Enhance the OP_IdxInsert opcode to optionally accept unpacked key material. FossilOrigin-Name: 89d958abbac45f2ca5954080cd9e74ec9a07ebb2 --- manifest | 35 +++++++++++++++++++---------------- manifest.uuid | 2 +- src/btree.c | 11 ++++++++++- src/btree.h | 2 ++ src/build.c | 2 +- src/delete.c | 2 +- src/expr.c | 2 +- src/insert.c | 4 ++-- src/select.c | 15 ++++++++------- src/update.c | 2 +- src/vdbe.c | 16 ++++++++++++---- src/wherecode.c | 3 ++- 12 files changed, 60 insertions(+), 36 deletions(-) diff --git a/manifest b/manifest index 9c94df9efd..725dfb9138 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\ssuperfluous\scursor\sseeks\sin\s"INSERT\sOR\sREPLACE"\sstatements. -D 2016-11-08T19:22:32.125 +C Enhance\sthe\sOP_IdxInsert\sopcode\sto\soptionally\saccept\sunpacked\skey\smaterial. +D 2016-11-09T00:10:33.633 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e0217f2d35a0448abbe4b066132ae20136e8b408 @@ -330,17 +330,17 @@ F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792 F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b F src/bitvec.c 3ee4c8b2c94ed3a7377256e18199e6ff5cf33f63 F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 -F src/btree.c 6ae1c17347fb2888b2b28a260b947b7717a9fca9 -F src/btree.h d05b2fcc290991a8a3d9ea1816ddd55a4359dcde +F src/btree.c fa0e4f2656562f18a8aeab5faa5747fc2d6bc497 +F src/btree.h 630303068c82a359f6ddf202b205ae927721b090 F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 -F src/build.c fcd220ccf7cae1b50b700b37eca950cd72c64ff0 +F src/build.c 178f16698cbcb43402c343a9413fe22c99ffee21 F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c a2a52d6e353f459d8ab0f07321f60fafa47d5421 F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d -F src/delete.c cb3f6300df24c26c609778b2731f82644b5532ec -F src/expr.c ce7110980fac6dfdfbe1e393443bdb79bad29339 +F src/delete.c 6cac3a6c3f3c5ad4cacc402aee1610fc94ebc3dc +F src/expr.c ddd46bafbbd77b83c8daa733ebbe906093b558dc F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c b9ca262f6ad4d030a3cab737ebf9b0b3c8b4ac80 F src/func.c 7057bc2c105b82faa668d8e2ec85fad4540e5c51 @@ -349,7 +349,7 @@ F src/hash.c 63d0ee752a3b92d4695b2b1f5259c4621b2cfebd F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4 F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 -F src/insert.c 8c1346304a9a386b036652475296103bae27e0a1 +F src/insert.c dff61f28a53a485210b48518f9ec1a5822d7c032 F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e F src/loadext.c 5d6642d141c07d366e43d359e94ec9de47add41d F src/main.c 694ac90557abdaa62151a6090670e107b0f2c2ab @@ -387,7 +387,7 @@ F src/printf.c a5f0ca08ddede803c241266abb46356ec748ded1 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c 3fac1b2737ea5a724f20b921ac7e259c9be2100b F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac -F src/select.c ea3af83e2d0f245fef81ea4cf04cb730ce67f722 +F src/select.c 7788e48a651bef02993531a41aad2ca516d1d4a2 F src/shell.c 63e54cfa1c7ec5b70a4c9a86502bc10280c3d5a3 F src/sqlite.h.in 97e9b0f952306677db82b055147ed1d99cb7ba66 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -450,11 +450,11 @@ F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c 78c8085bc7af1922aa687f0f4bbd716821330de5 F src/treeview.c 4e44ade3bfe59d82005039f72e09333ce2b4162c F src/trigger.c 3419bb9862983d84d70735fb4c94b21b934cd0c5 -F src/update.c 8179e699dbd45b92934fd02d3d8e3732e8da8802 +F src/update.c 771335a33c958a186b66ef7e349f978d6bb2aac4 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 3e2da6101888d073e79ecc6af5e0a2f70fa1e498 F src/vacuum.c 33c174b28886b2faf26e503b5a49a1c01a9b1c16 -F src/vdbe.c 20307c93ad55af6ab8f50b17147a4704d4f17dab +F src/vdbe.c 8044db96efdc586273e2c41aab3cc8f3d8ccb761 F src/vdbe.h c044be7050ac6bf596eecc6ab159f5dbc020a3b7 F src/vdbeInt.h d8a56a491b752dbb5f671963b8c861ec72ea875e F src/vdbeapi.c 97129bec6b1553da50d8e73f523c278bda66d9f6 @@ -470,7 +470,7 @@ F src/wal.h bf03a23da3100ab25e5c0363450233cfee09cfc2 F src/walker.c 91a6df7435827e41cff6bb7df50ea00934ee78b0 F src/where.c 952f76e7a03727480b274b66ca6641b1657cd591 F src/whereInt.h 2bcc3d176e6091cb8f50a30b65c006e88a73614d -F src/wherecode.c 717a65294df46f30e9b9933d2a63a4bcbca5a9a8 +F src/wherecode.c 507738d957dcc3cfa93020bcc1e4b02d11ecab9e F src/whereexpr.c a83d70154f3bbce5051a7e9710021f647c0fe4f2 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -1530,7 +1530,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 8cb8516d2009d52d35a22263e4c892f162b34b81 -R 36e33fba7941647bfb228c5ae67f2b63 -U dan -Z a11930824d648f16d0f222498c7f4b67 +P bec5b6d4d083556d111a89186b4f7b35b5e7cebf +R 91f828c4f65c4334fdcc0da90044f102 +T *branch * unpacked-IdxInsert +T *sym-unpacked-IdxInsert * +T -sym-trunk * +U drh +Z 760e23a13de3588aeee4a9588e9f1a85 diff --git a/manifest.uuid b/manifest.uuid index 0835b36ebc..4c6818ed4d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bec5b6d4d083556d111a89186b4f7b35b5e7cebf \ No newline at end of file +89d958abbac45f2ca5954080cd9e74ec9a07ebb2 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 4564bda7bb..541a581e5d 100644 --- a/src/btree.c +++ b/src/btree.c @@ -8019,7 +8019,16 @@ int sqlite3BtreeInsert( if( rc ) return rc; } }else if( loc==0 ){ - rc = btreeMoveto(pCur, pX->pKey, pX->nKey, appendBias, &loc); + if( pX->nMem ){ + UnpackedRecord r; + memset(&r, 0, sizeof(r)); + r.pKeyInfo = pCur->pKeyInfo; + r.aMem = pX->aMem; + r.nField = pX->nMem; + rc = sqlite3BtreeMovetoUnpacked(pCur, &r, 0, appendBias, &loc); + }else{ + rc = btreeMoveto(pCur, pX->pKey, pX->nKey, appendBias, &loc); + } if( rc ) return rc; } assert( pCur->eState==CURSOR_VALID || (pCur->eState==CURSOR_INVALID && loc) ); diff --git a/src/btree.h b/src/btree.h index 0df98a3a64..8b421e4201 100644 --- a/src/btree.h +++ b/src/btree.h @@ -275,6 +275,8 @@ struct BtreePayload { const void *pKey; /* Key content for indexes. NULL for tables */ sqlite3_int64 nKey; /* Size of pKey for indexes. PRIMARY KEY for tabs */ const void *pData; /* Data for tables. NULL for indexes */ + struct Mem *aMem; /* First of nMem value in the unpacked pKey */ + u16 nMem; /* Number of aMem[] value. Might be zero */ int nData; /* Size of pData. 0 if none. */ int nZero; /* Extra zero data appended after pData,nData */ }; diff --git a/src/build.c b/src/build.c index 350cf9f713..0fe2032689 100644 --- a/src/build.c +++ b/src/build.c @@ -2818,7 +2818,7 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){ } sqlite3VdbeAddOp3(v, OP_SorterData, iSorter, regRecord, iIdx); sqlite3VdbeAddOp3(v, OP_Last, iIdx, 0, -1); - sqlite3VdbeAddOp3(v, OP_IdxInsert, iIdx, regRecord, 0); + sqlite3VdbeAddOp2(v, OP_IdxInsert, iIdx, regRecord); sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); sqlite3ReleaseTempReg(pParse, regRecord); sqlite3VdbeAddOp2(v, OP_SorterNext, iSorter, addr2); VdbeCoverage(v); diff --git a/src/delete.c b/src/delete.c index ec85718246..e16e9485b2 100644 --- a/src/delete.c +++ b/src/delete.c @@ -449,7 +449,7 @@ void sqlite3DeleteFrom( nKey = 0; /* Zero tells OP_Found to use a composite key */ sqlite3VdbeAddOp4(v, OP_MakeRecord, iPk, nPk, iKey, sqlite3IndexAffinityStr(pParse->db, pPk), nPk); - sqlite3VdbeAddOp2(v, OP_IdxInsert, iEphCur, iKey); + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iEphCur, iKey, iPk, nPk); }else{ /* Add the rowid of the row to be deleted to the RowSet */ nKey = 1; /* OP_Seek always uses a single rowid */ diff --git a/src/expr.c b/src/expr.c index c2b9c8fe46..0e9c7e783d 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2538,7 +2538,7 @@ int sqlite3CodeSubselect( }else{ sqlite3VdbeAddOp4(v, OP_MakeRecord, r3, 1, r2, &affinity, 1); sqlite3ExprCacheAffinityChange(pParse, r3, 1); - sqlite3VdbeAddOp2(v, OP_IdxInsert, pExpr->iTable, r2); + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, pExpr->iTable, r2, r3, 1); } } } diff --git a/src/insert.c b/src/insert.c index 6ea3810a2a..14186b2317 100644 --- a/src/insert.c +++ b/src/insert.c @@ -2180,8 +2180,8 @@ static int xferOptimization( if( !HasRowid(pSrc) && pDestIdx->idxType==2 ){ idxInsFlags |= OPFLAG_NCHANGE; } - sqlite3VdbeAddOp3(v, OP_IdxInsert, iDest, regData, 1); - sqlite3VdbeChangeP5(v, idxInsFlags); + sqlite3VdbeAddOp2(v, OP_IdxInsert, iDest, regData); + sqlite3VdbeChangeP5(v, idxInsFlags|OPFLAG_APPEND); sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1+1); VdbeCoverage(v); sqlite3VdbeJumpHere(v, addr1); sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0); diff --git a/src/select.c b/src/select.c index 199e13f113..91ff220d68 100644 --- a/src/select.c +++ b/src/select.c @@ -655,7 +655,7 @@ static void codeDistinct( r1 = sqlite3GetTempReg(pParse); sqlite3VdbeAddOp4Int(v, OP_Found, iTab, addrRepeat, iMem, N); VdbeCoverage(v); sqlite3VdbeAddOp3(v, OP_MakeRecord, iMem, N, r1); - sqlite3VdbeAddOp2(v, OP_IdxInsert, iTab, r1); + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iTab, r1, iMem, N); sqlite3ReleaseTempReg(pParse, r1); } @@ -808,7 +808,7 @@ static void selectInnerLoop( int r1; r1 = sqlite3GetTempReg(pParse); sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nResultCol, r1); - sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, r1); + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, r1, regResult, nResultCol); sqlite3ReleaseTempReg(pParse, r1); break; } @@ -845,7 +845,7 @@ static void selectInnerLoop( int addr = sqlite3VdbeCurrentAddr(v) + 4; sqlite3VdbeAddOp4Int(v, OP_Found, iParm+1, addr, r1, 0); VdbeCoverage(v); - sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm+1, r1); + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm+1, r1,regResult,nResultCol); assert( pSort==0 ); } #endif @@ -881,7 +881,7 @@ static void selectInnerLoop( sqlite3VdbeAddOp4(v, OP_MakeRecord, regResult, nResultCol, r1, pDest->zAffSdst, nResultCol); sqlite3ExprCacheAffinityChange(pParse, regResult, nResultCol); - sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, r1); + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, r1, regResult, nResultCol); sqlite3ReleaseTempReg(pParse, r1); } break; @@ -967,7 +967,7 @@ static void selectInnerLoop( } sqlite3VdbeAddOp2(v, OP_Sequence, iParm, r2+nKey); sqlite3VdbeAddOp3(v, OP_MakeRecord, r2, nKey+2, r1); - sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, r1); + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, r1, r2, nKey+2); if( addrTest ) sqlite3VdbeJumpHere(v, addrTest); sqlite3ReleaseTempReg(pParse, r1); sqlite3ReleaseTempRange(pParse, r2, nKey+2); @@ -1264,7 +1264,7 @@ static void generateSortTail( sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, nColumn, regRowid, pDest->zAffSdst, nColumn); sqlite3ExprCacheAffinityChange(pParse, regRow, nColumn); - sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, regRowid); + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, regRowid, regRow, nColumn); break; } case SRT_Mem: { @@ -2640,7 +2640,8 @@ static int generateOutputSubroutine( sqlite3VdbeAddOp4(v, OP_MakeRecord, pIn->iSdst, pIn->nSdst, r1, pDest->zAffSdst, pIn->nSdst); sqlite3ExprCacheAffinityChange(pParse, pIn->iSdst, pIn->nSdst); - sqlite3VdbeAddOp2(v, OP_IdxInsert, pDest->iSDParm, r1); + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, pDest->iSDParm, r1, + pIn->iSdst, pIn->nSdst); sqlite3ReleaseTempReg(pParse, r1); break; } diff --git a/src/update.c b/src/update.c index 15e58e34c5..1fa53e3d1f 100644 --- a/src/update.c +++ b/src/update.c @@ -398,7 +398,7 @@ void sqlite3Update( }else{ sqlite3VdbeAddOp4(v, OP_MakeRecord, iPk, nPk, regKey, sqlite3IndexAffinityStr(db, pPk), nPk); - sqlite3VdbeAddOp2(v, OP_IdxInsert, iEph, regKey); + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iEph, regKey, iPk, nPk); } sqlite3WhereEnd(pWInfo); } diff --git a/src/vdbe.c b/src/vdbe.c index c2abeced04..e7e936da84 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -5017,15 +5017,20 @@ next_tail: goto check_for_interrupt; } -/* Opcode: IdxInsert P1 P2 P3 * P5 +/* Opcode: IdxInsert P1 P2 P3 P4 P5 ** Synopsis: key=r[P2] ** ** Register P2 holds an SQL index key made using the ** MakeRecord instructions. This opcode writes that key ** into the index P1. Data for the entry is nil. ** -** P3 is a flag that provides a hint to the b-tree layer that this -** insert is likely to be an append. +** If P4 is not zero, the it is the number of values in the unpacked +** key of reg(P2). In that case, P3 is the index of the first register +** for the unpacked key. The availability of the unpacked key can sometimes +** be an optimization. +** +** If P5 has the OPFLAG_APPEND bit set, that is a hint to the b-tree layer +** that this insert is likely to be an append. ** ** If P5 has the OPFLAG_NCHANGE bit set, then the change counter is ** incremented by this instruction. If the OPFLAG_NCHANGE bit is clear, @@ -5066,7 +5071,10 @@ case OP_IdxInsert: { /* in2 */ }else{ x.nKey = pIn2->n; x.pKey = pIn2->z; - rc = sqlite3BtreeInsert(pC->uc.pCursor, &x, pOp->p3, + x.aMem = aMem + pOp->p3; + x.nMem = (u16)pOp->p4.i; + rc = sqlite3BtreeInsert(pC->uc.pCursor, &x, + (pOp->p5 & OPFLAG_APPEND)!=0, ((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0) ); assert( pC->deferredMoveto==0 ); diff --git a/src/wherecode.c b/src/wherecode.c index c095ce7c87..d547a71179 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -1844,7 +1844,8 @@ Bitmask sqlite3WhereCodeOneLoopStart( } if( iSet>=0 ){ sqlite3VdbeAddOp3(v, OP_MakeRecord, r, nPk, regRowid); - sqlite3VdbeAddOp3(v, OP_IdxInsert, regRowset, regRowid, 0); + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, regRowset, regRowid, + r, nPk); if( iSet ) sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); } From 7723371eb71285deeea5cb244abf66cd25dc0884 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 9 Nov 2016 00:57:27 +0000 Subject: [PATCH 0966/1484] Remove the "experimental" marking from the sqlite3_preupdate interfaces. But be sure all the interface definitions are within documentation. FossilOrigin-Name: d6dd2ad35ed17e980ed564688499c802e5850386 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/sqlite.h.in | 14 ++++++++------ 3 files changed, 16 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index 9c94df9efd..7c318efe4e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\ssuperfluous\scursor\sseeks\sin\s"INSERT\sOR\sREPLACE"\sstatements. -D 2016-11-08T19:22:32.125 +C Remove\sthe\s"experimental"\smarking\sfrom\sthe\ssqlite3_preupdate\sinterfaces.\nBut\sbe\ssure\sall\sthe\sinterface\sdefinitions\sare\swithin\s\ndocumentation. +D 2016-11-09T00:57:27.790 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e0217f2d35a0448abbe4b066132ae20136e8b408 @@ -389,7 +389,7 @@ F src/resolve.c 3fac1b2737ea5a724f20b921ac7e259c9be2100b F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c ea3af83e2d0f245fef81ea4cf04cb730ce67f722 F src/shell.c 63e54cfa1c7ec5b70a4c9a86502bc10280c3d5a3 -F src/sqlite.h.in 97e9b0f952306677db82b055147ed1d99cb7ba66 +F src/sqlite.h.in 803f7050f69b2eea573fac219f3c92582c096027 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae F src/sqliteInt.h 37628fe30c464dc790bcee3bfd3d0caa8f222ed1 @@ -1530,7 +1530,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 8cb8516d2009d52d35a22263e4c892f162b34b81 -R 36e33fba7941647bfb228c5ae67f2b63 -U dan -Z a11930824d648f16d0f222498c7f4b67 +P bec5b6d4d083556d111a89186b4f7b35b5e7cebf +R ff2060e290f81fca7217b945d86dd7cc +U drh +Z a7ff54b297c4e1fff86ebb13237d1a94 diff --git a/manifest.uuid b/manifest.uuid index 0835b36ebc..e61f550e0b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bec5b6d4d083556d111a89186b4f7b35b5e7cebf \ No newline at end of file +d6dd2ad35ed17e980ed564688499c802e5850386 \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index f7bcdd6746..dd70407c1b 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -127,7 +127,7 @@ extern "C" { /* ** CAPI3REF: Run-Time Library Version Numbers -** KEYWORDS: sqlite3_version, sqlite3_sourceid +** KEYWORDS: sqlite3_version sqlite3_sourceid ** ** These interfaces provide the same information as the [SQLITE_VERSION], ** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros @@ -8225,7 +8225,8 @@ int sqlite3_db_cacheflush(sqlite3*); ** ** See also: [sqlite3_update_hook()] */ -SQLITE_EXPERIMENTAL void *sqlite3_preupdate_hook( +#if defined(SQLITE_ENABLE_PREUPDATE_HOOK) +void *sqlite3_preupdate_hook( sqlite3 *db, void(*xPreUpdate)( void *pCtx, /* Copy of third arg to preupdate_hook() */ @@ -8238,10 +8239,11 @@ SQLITE_EXPERIMENTAL void *sqlite3_preupdate_hook( ), void* ); -SQLITE_EXPERIMENTAL int sqlite3_preupdate_old(sqlite3 *, int, sqlite3_value **); -SQLITE_EXPERIMENTAL int sqlite3_preupdate_count(sqlite3 *); -SQLITE_EXPERIMENTAL int sqlite3_preupdate_depth(sqlite3 *); -SQLITE_EXPERIMENTAL int sqlite3_preupdate_new(sqlite3 *, int, sqlite3_value **); +int sqlite3_preupdate_old(sqlite3 *, int, sqlite3_value **); +int sqlite3_preupdate_count(sqlite3 *); +int sqlite3_preupdate_depth(sqlite3 *); +int sqlite3_preupdate_new(sqlite3 *, int, sqlite3_value **); +#endif /* ** CAPI3REF: Low-level system error code From 088c086b1459d820f2c7a2a498b3435cb4b4f41b Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 9 Nov 2016 01:07:10 +0000 Subject: [PATCH 0967/1484] Add a DISTINCT query to speedtest1.c. Also change INSERT OR REPLACE into just REPLACE. FossilOrigin-Name: 754ee844958bdc3b96acfd1f5395da5796e54a82 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/speedtest1.c | 14 +++++++++----- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 7c318efe4e..5fb18f4d9a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sthe\s"experimental"\smarking\sfrom\sthe\ssqlite3_preupdate\sinterfaces.\nBut\sbe\ssure\sall\sthe\sinterface\sdefinitions\sare\swithin\s\ndocumentation. -D 2016-11-09T00:57:27.790 +C Add\sa\sDISTINCT\squery\sto\sspeedtest1.c.\s\sAlso\schange\sINSERT\sOR\sREPLACE\sinto\njust\sREPLACE. +D 2016-11-09T01:07:10.116 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e0217f2d35a0448abbe4b066132ae20136e8b408 @@ -1116,7 +1116,7 @@ F test/speed3.test 694affeb9100526007436334cf7d08f3d74b85ef F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715 F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b -F test/speedtest1.c cb433ff792a1b317d0787416bb8a57bbc3266871 +F test/speedtest1.c 48d82e01bd475d288460368497ad55a37f1bf659 F test/spellfix.test f9c1f431e2c096c8775fec032952320c0e4700db F test/spellfix2.test dfc8f519a3fc204cb2dfa8b4f29821ae90f6f8c3 F test/spellfix3.test 0f9efaaa502a0e0a09848028518a6fb096c8ad33 @@ -1530,7 +1530,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P bec5b6d4d083556d111a89186b4f7b35b5e7cebf -R ff2060e290f81fca7217b945d86dd7cc +P d6dd2ad35ed17e980ed564688499c802e5850386 +R d08cd4afd007fbdaa2d25ecaf2cc91e7 U drh -Z a7ff54b297c4e1fff86ebb13237d1a94 +Z 0b6edaf7c64c65fbed1b9876eb6764f5 diff --git a/manifest.uuid b/manifest.uuid index e61f550e0b..4b0a0b7366 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d6dd2ad35ed17e980ed564688499c802e5850386 \ No newline at end of file +754ee844958bdc3b96acfd1f5395da5796e54a82 \ No newline at end of file diff --git a/test/speedtest1.c b/test/speedtest1.c index 244a1666ae..48d13b66c7 100644 --- a/test/speedtest1.c +++ b/test/speedtest1.c @@ -834,11 +834,11 @@ void testset_main(void){ sz = n = g.szTest*700; zNum[0] = 0; maxb = roundup_allones(sz/3); - speedtest1_begin_test(400, "%d INSERT OR REPLACE ops on an IPK", n); + speedtest1_begin_test(400, "%d REPLACE ops on an IPK", n); speedtest1_exec("BEGIN"); speedtest1_exec("CREATE%s TABLE t5(a INTEGER PRIMARY KEY, b %s);", isTemp(9), g.zNN); - speedtest1_prepare("INSERT OR REPLACE INTO t5 VALUES(?1,?2); -- %d times",n); + speedtest1_prepare("REPLACE INTO t5 VALUES(?1,?2); -- %d times",n); for(i=1; i<=n; i++){ x1 = swizzle(i,maxb); speedtest1_numbername(i, zNum, sizeof(zNum)); @@ -860,12 +860,12 @@ void testset_main(void){ sz = n = g.szTest*700; zNum[0] = 0; maxb = roundup_allones(sz/3); - speedtest1_begin_test(500, "%d INSERT OR REPLACE ops on TEXT PK", n); + speedtest1_begin_test(500, "%d REPLACE on TEXT PK", n); speedtest1_exec("BEGIN"); speedtest1_exec("CREATE%s TABLE t6(a TEXT PRIMARY KEY, b %s)%s;", isTemp(9), g.zNN, sqlite3_libversion_number()>=3008002 ? "WITHOUT ROWID" : ""); - speedtest1_prepare("INSERT OR REPLACE INTO t6 VALUES(?1,?2); -- %d times",n); + speedtest1_prepare("REPLACE INTO t6 VALUES(?1,?2); -- %d times",n); for(i=1; i<=n; i++){ x1 = swizzle(i,maxb); speedtest1_numbername(x1, zNum, sizeof(zNum)); @@ -875,7 +875,7 @@ void testset_main(void){ } speedtest1_exec("COMMIT"); speedtest1_end_test(); - speedtest1_begin_test(510, "%d SELECTS on an IPK", n); + speedtest1_begin_test(510, "%d SELECTS on a TEXT PK", n); speedtest1_prepare("SELECT b FROM t6 WHERE a=?1; -- %d times",n); for(i=1; i<=n; i++){ x1 = swizzle(i,maxb); @@ -884,6 +884,10 @@ void testset_main(void){ speedtest1_run(); } speedtest1_end_test(); + speedtest1_begin_test(520, "%d SELECT DISTINCT", n); + speedtest1_exec("SELECT DISTINCT b FROM t5;"); + speedtest1_exec("SELECT DISTINCT b FROM t6;"); + speedtest1_end_test(); speedtest1_begin_test(980, "PRAGMA integrity_check"); From fb8c56f21b40347bfd8a1f1127d6ab81b7a0d696 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 9 Nov 2016 01:19:25 +0000 Subject: [PATCH 0968/1484] Fix a typo on the OP_IdxInsert documentation. No code changes. FossilOrigin-Name: e4acd98207bf12b28f6c0f77896ba8f0b0a155d5 --- manifest | 15 ++++++--------- manifest.uuid | 2 +- src/vdbe.c | 2 +- 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 725dfb9138..e57915f70e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\sthe\sOP_IdxInsert\sopcode\sto\soptionally\saccept\sunpacked\skey\smaterial. -D 2016-11-09T00:10:33.633 +C Fix\sa\stypo\son\sthe\sOP_IdxInsert\sdocumentation.\s\sNo\scode\schanges. +D 2016-11-09T01:19:25.538 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e0217f2d35a0448abbe4b066132ae20136e8b408 @@ -454,7 +454,7 @@ F src/update.c 771335a33c958a186b66ef7e349f978d6bb2aac4 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 3e2da6101888d073e79ecc6af5e0a2f70fa1e498 F src/vacuum.c 33c174b28886b2faf26e503b5a49a1c01a9b1c16 -F src/vdbe.c 8044db96efdc586273e2c41aab3cc8f3d8ccb761 +F src/vdbe.c e6bf36b1df5ff32d222e8c96cacb2fb951be42a2 F src/vdbe.h c044be7050ac6bf596eecc6ab159f5dbc020a3b7 F src/vdbeInt.h d8a56a491b752dbb5f671963b8c861ec72ea875e F src/vdbeapi.c 97129bec6b1553da50d8e73f523c278bda66d9f6 @@ -1530,10 +1530,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P bec5b6d4d083556d111a89186b4f7b35b5e7cebf -R 91f828c4f65c4334fdcc0da90044f102 -T *branch * unpacked-IdxInsert -T *sym-unpacked-IdxInsert * -T -sym-trunk * +P 89d958abbac45f2ca5954080cd9e74ec9a07ebb2 +R 2f63be5b53b1764858d941957facd0a5 U drh -Z 760e23a13de3588aeee4a9588e9f1a85 +Z 100f9d5faafe3036eeb3f1b9e19b8a02 diff --git a/manifest.uuid b/manifest.uuid index 4c6818ed4d..eb365dc381 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -89d958abbac45f2ca5954080cd9e74ec9a07ebb2 \ No newline at end of file +e4acd98207bf12b28f6c0f77896ba8f0b0a155d5 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index e7e936da84..e37bf0da14 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -5024,7 +5024,7 @@ next_tail: ** MakeRecord instructions. This opcode writes that key ** into the index P1. Data for the entry is nil. ** -** If P4 is not zero, the it is the number of values in the unpacked +** If P4 is not zero, then it is the number of values in the unpacked ** key of reg(P2). In that case, P3 is the index of the first register ** for the unpacked key. The availability of the unpacked key can sometimes ** be an optimization. From 4a8b013ef67b5444d37c55bfaee3173d6fa617c2 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 9 Nov 2016 01:38:56 +0000 Subject: [PATCH 0969/1484] Make use of the unpacked key on the OP_IdxInsert on sorters with a LIMIT. FossilOrigin-Name: 42db7cd2c0b367f7dfe733bdaf006538937b812a --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/select.c | 3 ++- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index e57915f70e..1d869017fc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\stypo\son\sthe\sOP_IdxInsert\sdocumentation.\s\sNo\scode\schanges. -D 2016-11-09T01:19:25.538 +C Make\suse\sof\sthe\sunpacked\skey\son\sthe\sOP_IdxInsert\son\ssorters\swith\sa\sLIMIT. +D 2016-11-09T01:38:56.790 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e0217f2d35a0448abbe4b066132ae20136e8b408 @@ -387,7 +387,7 @@ F src/printf.c a5f0ca08ddede803c241266abb46356ec748ded1 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c 3fac1b2737ea5a724f20b921ac7e259c9be2100b F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac -F src/select.c 7788e48a651bef02993531a41aad2ca516d1d4a2 +F src/select.c 0a7c523d755bcd39ae54f6a44bb66a7f0e1d89b3 F src/shell.c 63e54cfa1c7ec5b70a4c9a86502bc10280c3d5a3 F src/sqlite.h.in 97e9b0f952306677db82b055147ed1d99cb7ba66 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1530,7 +1530,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 89d958abbac45f2ca5954080cd9e74ec9a07ebb2 -R 2f63be5b53b1764858d941957facd0a5 +P e4acd98207bf12b28f6c0f77896ba8f0b0a155d5 +R 7361f61ac78ae245768da69ccbec613a U drh -Z 100f9d5faafe3036eeb3f1b9e19b8a02 +Z 555ef190d20751c33a6a59c14a70c249 diff --git a/manifest.uuid b/manifest.uuid index eb365dc381..0428c98284 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e4acd98207bf12b28f6c0f77896ba8f0b0a155d5 \ No newline at end of file +42db7cd2c0b367f7dfe733bdaf006538937b812a \ No newline at end of file diff --git a/src/select.c b/src/select.c index 91ff220d68..b82e7905cc 100644 --- a/src/select.c +++ b/src/select.c @@ -587,7 +587,8 @@ static void pushOntoSorter( }else{ op = OP_IdxInsert; } - sqlite3VdbeAddOp2(v, op, pSort->iECursor, regRecord); + sqlite3VdbeAddOp4Int(v, op, pSort->iECursor, regRecord, + regBase+nOBSat, nBase-nOBSat); if( iLimit ){ int addr; int r1 = 0; From 58282f68d88e6c9ff907988a99ff67d8c473f137 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Wed, 9 Nov 2016 01:46:13 +0000 Subject: [PATCH 0970/1484] Fix typo in the CSV extension. FossilOrigin-Name: b4889588246c33374ff3758e21ccc4ce246380b6 --- ext/misc/csv.c | 2 +- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/ext/misc/csv.c b/ext/misc/csv.c index 2a9463bd6e..f887784ab8 100644 --- a/ext/misc/csv.c +++ b/ext/misc/csv.c @@ -402,7 +402,7 @@ static int csv_boolean(const char *z){ if( sqlite3_stricmp("yes",z)==0 || sqlite3_stricmp("on",z)==0 || sqlite3_stricmp("true",z)==0 - || (z[0]=='1' && z[0]==0) + || (z[0]=='1' && z[1]==0) ){ return 1; } diff --git a/manifest b/manifest index 5fb18f4d9a..a18f153b6d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sa\sDISTINCT\squery\sto\sspeedtest1.c.\s\sAlso\schange\sINSERT\sOR\sREPLACE\sinto\njust\sREPLACE. -D 2016-11-09T01:07:10.116 +C Fix\stypo\sin\sthe\sCSV\sextension. +D 2016-11-09T01:46:13.326 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e0217f2d35a0448abbe4b066132ae20136e8b408 @@ -208,7 +208,7 @@ F ext/misc/amatch.c 211108e201105e4bb0c076527b8cfd34330fc234 F ext/misc/carray.c 40c27641010a4dc67e3690bdb7c9d36ca58b3c2d F ext/misc/closure.c 0d2a038df8fbae7f19de42e7c7d71f2e4dc88704 F ext/misc/compress.c 122faa92d25033d6c3f07c39231de074ab3d2e83 -F ext/misc/csv.c 816a3715356e4210dae2d242057745e937050896 +F ext/misc/csv.c 531a46cbad789fca0aa9db69a0e6c8ac9e68767d F ext/misc/eval.c f971962e92ebb8b0a4e6b62949463ee454d88fa2 F ext/misc/fileio.c d4171c815d6543a9edef8308aab2951413cd8d0f F ext/misc/fuzzer.c 7c64b8197bb77b7d64eff7cac7848870235d4c25 @@ -1530,7 +1530,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d6dd2ad35ed17e980ed564688499c802e5850386 -R d08cd4afd007fbdaa2d25ecaf2cc91e7 -U drh -Z 0b6edaf7c64c65fbed1b9876eb6764f5 +P 754ee844958bdc3b96acfd1f5395da5796e54a82 +R eb905f0421ecb200099f22c1d4910f11 +U mistachkin +Z a09941219c710c6bfaf84cdaf6c10994 diff --git a/manifest.uuid b/manifest.uuid index 4b0a0b7366..952d3c0676 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -754ee844958bdc3b96acfd1f5395da5796e54a82 \ No newline at end of file +b4889588246c33374ff3758e21ccc4ce246380b6 \ No newline at end of file From 7405fa745ed34fed26fffe3fb62758da65409ae9 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 9 Nov 2016 16:03:36 +0000 Subject: [PATCH 0971/1484] Fix a simple comment typo. No changes to code. FossilOrigin-Name: 51d0aed8d63d0710e4aa8925ff18cf3c45dc9e42 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/insert.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 1d869017fc..47015a4f64 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\suse\sof\sthe\sunpacked\skey\son\sthe\sOP_IdxInsert\son\ssorters\swith\sa\sLIMIT. -D 2016-11-09T01:38:56.790 +C Fix\sa\ssimple\scomment\stypo.\s\sNo\schanges\sto\scode. +D 2016-11-09T16:03:36.041 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e0217f2d35a0448abbe4b066132ae20136e8b408 @@ -349,7 +349,7 @@ F src/hash.c 63d0ee752a3b92d4695b2b1f5259c4621b2cfebd F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4 F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 -F src/insert.c dff61f28a53a485210b48518f9ec1a5822d7c032 +F src/insert.c 515af5f585e68aeaf2afaca60cccf982fffa7c37 F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e F src/loadext.c 5d6642d141c07d366e43d359e94ec9de47add41d F src/main.c 694ac90557abdaa62151a6090670e107b0f2c2ab @@ -1530,7 +1530,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e4acd98207bf12b28f6c0f77896ba8f0b0a155d5 -R 7361f61ac78ae245768da69ccbec613a +P 42db7cd2c0b367f7dfe733bdaf006538937b812a +R 725472132a567caa1a975d92e1d85b3c U drh -Z 555ef190d20751c33a6a59c14a70c249 +Z 171f352f5da597b47d092f93a00f48a7 diff --git a/manifest.uuid b/manifest.uuid index 0428c98284..6bee48823a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -42db7cd2c0b367f7dfe733bdaf006538937b812a \ No newline at end of file +51d0aed8d63d0710e4aa8925ff18cf3c45dc9e42 \ No newline at end of file diff --git a/src/insert.c b/src/insert.c index 14186b2317..4ae4623ff2 100644 --- a/src/insert.c +++ b/src/insert.c @@ -1377,7 +1377,7 @@ void sqlite3GenerateConstraintChecks( } if( isUpdate ){ - /* pkChng!=0 does not mean that the rowid has change, only that + /* pkChng!=0 does not mean that the rowid has changed, only that ** it might have changed. Skip the conflict logic below if the rowid ** is unchanged. */ sqlite3VdbeAddOp3(v, OP_Eq, regNewData, addrRowidOk, regOldData); From eaf6ae29928eee11076fc6a0577e2630a6e56b4f Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 9 Nov 2016 20:14:34 +0000 Subject: [PATCH 0972/1484] Comment changes that attempt to better explain the behavior of the "seekResult" field on VdbeCursor objects and the seekResult parameter to sqlite3BtreeInsert() and the OPFLAG_USESEEKRESULT flag on insert opcodes. No changes to code. FossilOrigin-Name: 345b46be75bdf6f9fb7367a6164d89bae11995a6 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/btree.c | 22 ++++++++++++---------- src/vdbe.c | 21 +++++++++------------ src/vdbeInt.h | 5 ++++- 5 files changed, 34 insertions(+), 32 deletions(-) diff --git a/manifest b/manifest index 47015a4f64..e5e5f23851 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\ssimple\scomment\stypo.\s\sNo\schanges\sto\scode. -D 2016-11-09T16:03:36.041 +C Comment\schanges\sthat\sattempt\sto\sbetter\sexplain\sthe\sbehavior\sof\sthe\s"seekResult"\nfield\son\sVdbeCursor\sobjects\sand\sthe\sseekResult\sparameter\sto\nsqlite3BtreeInsert()\sand\sthe\sOPFLAG_USESEEKRESULT\sflag\son\sinsert\sopcodes.\nNo\schanges\sto\scode. +D 2016-11-09T20:14:34.342 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e0217f2d35a0448abbe4b066132ae20136e8b408 @@ -330,7 +330,7 @@ F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792 F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b F src/bitvec.c 3ee4c8b2c94ed3a7377256e18199e6ff5cf33f63 F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 -F src/btree.c fa0e4f2656562f18a8aeab5faa5747fc2d6bc497 +F src/btree.c d1a3d691917cb7d67d50318aef990d8f30d172c7 F src/btree.h 630303068c82a359f6ddf202b205ae927721b090 F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 F src/build.c 178f16698cbcb43402c343a9413fe22c99ffee21 @@ -454,9 +454,9 @@ F src/update.c 771335a33c958a186b66ef7e349f978d6bb2aac4 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 3e2da6101888d073e79ecc6af5e0a2f70fa1e498 F src/vacuum.c 33c174b28886b2faf26e503b5a49a1c01a9b1c16 -F src/vdbe.c e6bf36b1df5ff32d222e8c96cacb2fb951be42a2 +F src/vdbe.c f1a8e5bf7747f2e731812804cb65d4d07d86862e F src/vdbe.h c044be7050ac6bf596eecc6ab159f5dbc020a3b7 -F src/vdbeInt.h d8a56a491b752dbb5f671963b8c861ec72ea875e +F src/vdbeInt.h 29b25318a0286c4b2599c0fbef6acf524398489a F src/vdbeapi.c 97129bec6b1553da50d8e73f523c278bda66d9f6 F src/vdbeaux.c 52d9b840859f260ce8418be9333dd77c902e1c74 F src/vdbeblob.c 3e82a797b60c3b9fed7b8de8c539ca7607874937 @@ -1530,7 +1530,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 42db7cd2c0b367f7dfe733bdaf006538937b812a -R 725472132a567caa1a975d92e1d85b3c +P 51d0aed8d63d0710e4aa8925ff18cf3c45dc9e42 +R eacb8afe762fb37c4ccfd0b85c6e6ad7 U drh -Z 171f352f5da597b47d092f93a00f48a7 +Z e647112eb568bcacd99f7ceac7bd6ee3 diff --git a/manifest.uuid b/manifest.uuid index 6bee48823a..f7958c7d13 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -51d0aed8d63d0710e4aa8925ff18cf3c45dc9e42 \ No newline at end of file +345b46be75bdf6f9fb7367a6164d89bae11995a6 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 541a581e5d..b92b6018b4 100644 --- a/src/btree.c +++ b/src/btree.c @@ -7940,17 +7940,19 @@ static int balance(BtCursor *pCur){ ** pX.pData,nData,nZero fields must be zero. ** ** If the seekResult parameter is non-zero, then a successful call to -** MovetoUnpacked() to seek cursor pCur to (pKey, nKey) has already -** been performed. seekResult is the search result returned (a negative -** number if pCur points at an entry that is smaller than (pKey, nKey), or -** a positive value if pCur points at an entry that is larger than -** (pKey, nKey)). +** MovetoUnpacked() to seek cursor pCur to (pKey,nKey) has already +** been performed. In other words, if seekResult!=0 then the cursor +** is currently pointing to a cell that will be adjacent to the cell +** to be inserted. If seekResult<0 then pCur points to a cell that is +** smaller then (pKey,nKey). If seekResult>0 then pCur points to a cell +** that is larger than (pKey,nKey). ** -** If the seekResult parameter is non-zero, then the caller guarantees that -** cursor pCur is pointing at the existing copy of a row that is to be -** overwritten. If the seekResult parameter is 0, then cursor pCur may -** point to any entry or to no entry at all and so this function has to seek -** the cursor before the new key can be inserted. +** If seekResult==0, that means pCur is pointing at some unknown location. +** In that case, this routine must seek the cursor to the correct insertion +** point for (pKey,nKey) before doing the insertion. For index btrees, +** if pX->nMem is non-zero, then pX->aMem contains pointers to the unpacked +** key values and pX->aMem can be used instead of pX->pKey to avoid having +** to decode the key. */ int sqlite3BtreeInsert( BtCursor *pCur, /* Insert data into the table of this cursor */ diff --git a/src/vdbe.c b/src/vdbe.c index e37bf0da14..740e52fc90 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -4322,15 +4322,10 @@ case OP_NewRowid: { /* out2 */ ** then rowid is stored for subsequent return by the ** sqlite3_last_insert_rowid() function (otherwise it is unmodified). ** -** If the OPFLAG_USESEEKRESULT flag of P5 is set and if the result of -** the last seek operation (OP_NotExists or OP_SeekRowid) was a success, -** then this -** operation will not attempt to find the appropriate row before doing -** the insert but will instead overwrite the row that the cursor is -** currently pointing to. Presumably, the prior OP_NotExists or -** OP_SeekRowid opcode -** has already positioned the cursor correctly. This is an optimization -** that boosts performance by avoiding redundant seeks. +** If the OPFLAG_USESEEKRESULT flag of P5 is set, the implementation might +** run faster by avoiding an unnecessary seek on cursor P1. However, +** the OPFLAG_USESEEKRESULT flag must only be set if there have been no prior +** seeks on the cursor or if the most recent seek used a key equal to P3. ** ** If the OPFLAG_ISUPDATE flag is set, then this opcode is part of an ** UPDATE operation. Otherwise (if the flag is clear) then this opcode @@ -5036,9 +5031,11 @@ next_tail: ** incremented by this instruction. If the OPFLAG_NCHANGE bit is clear, ** then the change counter is unchanged. ** -** If P5 has the OPFLAG_USESEEKRESULT bit set, then the cursor must have -** just done a seek to the spot where the new entry is to be inserted. -** This flag avoids doing an extra seek. +** If the OPFLAG_USESEEKRESULT flag of P5 is set, the implementation might +** run faster by avoiding an unnecessary seek on cursor P1. However, +** the OPFLAG_USESEEKRESULT flag must only be set if there have been no prior +** seeks on the cursor or if the most recent seek used a key equivalent +** to P2. ** ** This instruction only works for indices. The equivalent instruction ** for tables is OP_Insert. diff --git a/src/vdbeInt.h b/src/vdbeInt.h index 86445cef66..6e6ace207c 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -96,7 +96,10 @@ struct VdbeCursor { } uc; Btree *pBt; /* Separate file holding temporary table */ KeyInfo *pKeyInfo; /* Info about index keys needed by index cursors */ - int seekResult; /* Result of previous sqlite3BtreeMoveto() */ + int seekResult; /* Result of previous sqlite3BtreeMoveto() or 0 + ** if there have been no prior seeks on the cursor. */ + /* NB: seekResult does not distinguish between "no seeks have ever occurred + ** on this cursor" and "the most recent seek was an exact match". */ i64 seqCount; /* Sequence counter */ i64 movetoTarget; /* Argument to the deferred sqlite3BtreeMoveto() */ VdbeCursor *pAltCursor; /* Associated index cursor from which to read */ From 2c4dfc30956fe36919426970d72e6be828289c5b Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 10 Nov 2016 14:24:04 +0000 Subject: [PATCH 0973/1484] Add the unpacked key fields to OP_IdxInsert for INSERT and UPDATE statements. FossilOrigin-Name: 67602e40f122cbb6354048a64c5d3a72b2855ec7 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/insert.c | 14 +++++++++----- src/update.c | 2 ++ 4 files changed, 19 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index e5e5f23851..927eabb417 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Comment\schanges\sthat\sattempt\sto\sbetter\sexplain\sthe\sbehavior\sof\sthe\s"seekResult"\nfield\son\sVdbeCursor\sobjects\sand\sthe\sseekResult\sparameter\sto\nsqlite3BtreeInsert()\sand\sthe\sOPFLAG_USESEEKRESULT\sflag\son\sinsert\sopcodes.\nNo\schanges\sto\scode. -D 2016-11-09T20:14:34.342 +C Add\sthe\sunpacked\skey\sfields\sto\sOP_IdxInsert\sfor\sINSERT\sand\sUPDATE\sstatements. +D 2016-11-10T14:24:04.595 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e0217f2d35a0448abbe4b066132ae20136e8b408 @@ -349,7 +349,7 @@ F src/hash.c 63d0ee752a3b92d4695b2b1f5259c4621b2cfebd F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4 F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 -F src/insert.c 515af5f585e68aeaf2afaca60cccf982fffa7c37 +F src/insert.c ba2f101575111114da6a4e7a231949b5d0bf2bc0 F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e F src/loadext.c 5d6642d141c07d366e43d359e94ec9de47add41d F src/main.c 694ac90557abdaa62151a6090670e107b0f2c2ab @@ -450,7 +450,7 @@ F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c 78c8085bc7af1922aa687f0f4bbd716821330de5 F src/treeview.c 4e44ade3bfe59d82005039f72e09333ce2b4162c F src/trigger.c 3419bb9862983d84d70735fb4c94b21b934cd0c5 -F src/update.c 771335a33c958a186b66ef7e349f978d6bb2aac4 +F src/update.c bb9854778bdbbbca55d7533e55058733bd3fefe3 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 3e2da6101888d073e79ecc6af5e0a2f70fa1e498 F src/vacuum.c 33c174b28886b2faf26e503b5a49a1c01a9b1c16 @@ -1530,7 +1530,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 51d0aed8d63d0710e4aa8925ff18cf3c45dc9e42 -R eacb8afe762fb37c4ccfd0b85c6e6ad7 +P 345b46be75bdf6f9fb7367a6164d89bae11995a6 +R e1b2caf55e9d3843f543e00160355508 U drh -Z e647112eb568bcacd99f7ceac7bd6ee3 +Z 41e31850fcf9fee16d82b22da63518af diff --git a/manifest.uuid b/manifest.uuid index f7958c7d13..d20d303140 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -345b46be75bdf6f9fb7367a6164d89bae11995a6 \ No newline at end of file +67602e40f122cbb6354048a64c5d3a72b2855ec7 \ No newline at end of file diff --git a/src/insert.c b/src/insert.c index 4ae4623ff2..361c3a3a6d 100644 --- a/src/insert.c +++ b/src/insert.c @@ -786,14 +786,17 @@ void sqlite3Insert( /* If this is not a view, open the table and and all indices */ if( !isView ){ int nIdx; + Index *pIdx; nIdx = sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, 0, -1, 0, &iDataCur, &iIdxCur); aRegIdx = sqlite3DbMallocRawNN(db, sizeof(int)*(nIdx+1)); if( aRegIdx==0 ){ goto insert_cleanup; } - for(i=0; ipIndex; ipNext, i++){ + assert( pIdx ); aRegIdx[i] = ++pParse->nMem; + pParse->nMem += pIdx->nColumn; } } @@ -1512,7 +1515,7 @@ void sqlite3GenerateConstraintChecks( /* Create a record for this index entry as it should appear after ** the insert or update. Store that record in the aRegIdx[ix] register */ - regIdx = sqlite3GetTempRange(pParse, pIdx->nColumn); + regIdx = aRegIdx[ix]+1; // sqlite3GetTempRange(pParse, pIdx->nColumn); for(i=0; inColumn; i++){ int iField = pIdx->aiColumn[i]; int x; @@ -1549,7 +1552,7 @@ void sqlite3GenerateConstraintChecks( /* Find out what action to take in case there is a uniqueness conflict */ onError = pIdx->onError; if( onError==OE_None ){ - sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nColumn); +// sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nColumn); sqlite3VdbeResolveLabel(v, addrUniqueOk); continue; /* pIdx is not a UNIQUE index */ } @@ -1648,7 +1651,7 @@ void sqlite3GenerateConstraintChecks( } } sqlite3VdbeResolveLabel(v, addrUniqueOk); - sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nColumn); + // sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nColumn); if( regR!=regIdx ) sqlite3ReleaseTempRange(pParse, regR, nPkField); } if( ipkTop ){ @@ -1698,7 +1701,8 @@ void sqlite3CompleteInsertion( sqlite3VdbeAddOp2(v, OP_IsNull, aRegIdx[i], sqlite3VdbeCurrentAddr(v)+2); VdbeCoverage(v); } - sqlite3VdbeAddOp2(v, OP_IdxInsert, iIdxCur+i, aRegIdx[i]); + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iIdxCur+i, aRegIdx[i], + aRegIdx[i]+1, pIdx->nColumn); pik_flags = 0; if( useSeekResult ) pik_flags = OPFLAG_USESEEKRESULT; if( IsPrimaryKeyIndex(pIdx) && !HasRowid(pTab) ){ diff --git a/src/update.c b/src/update.c index 1fa53e3d1f..6838c74398 100644 --- a/src/update.c +++ b/src/update.c @@ -282,12 +282,14 @@ void sqlite3Update( int reg; if( chngKey || hasFK || pIdx->pPartIdxWhere || pIdx==pPk ){ reg = ++pParse->nMem; + pParse->nMem += pIdx->nColumn; }else{ reg = 0; for(i=0; inKeyCol; i++){ i16 iIdxCol = pIdx->aiColumn[i]; if( iIdxCol<0 || aXRef[iIdxCol]>=0 ){ reg = ++pParse->nMem; + pParse->nMem += pIdx->nColumn; break; } } From bf2f5739c956bdd508d427c269e0b46c05025544 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 10 Nov 2016 16:07:43 +0000 Subject: [PATCH 0974/1484] Remove C++ style comments. No code changes. FossilOrigin-Name: 42f8aa6231bf4ed74bebdc85aa79d23dc20b3c14 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/insert.c | 4 +--- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 927eabb417..61e973e4b9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sunpacked\skey\sfields\sto\sOP_IdxInsert\sfor\sINSERT\sand\sUPDATE\sstatements. -D 2016-11-10T14:24:04.595 +C Remove\sC++\sstyle\scomments.\s\sNo\scode\schanges. +D 2016-11-10T16:07:43.214 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e0217f2d35a0448abbe4b066132ae20136e8b408 @@ -349,7 +349,7 @@ F src/hash.c 63d0ee752a3b92d4695b2b1f5259c4621b2cfebd F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4 F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 -F src/insert.c ba2f101575111114da6a4e7a231949b5d0bf2bc0 +F src/insert.c 63bec2cbffc09d2ea45e0980ded1ebc0e8ef6823 F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e F src/loadext.c 5d6642d141c07d366e43d359e94ec9de47add41d F src/main.c 694ac90557abdaa62151a6090670e107b0f2c2ab @@ -1530,7 +1530,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 345b46be75bdf6f9fb7367a6164d89bae11995a6 -R e1b2caf55e9d3843f543e00160355508 +P 67602e40f122cbb6354048a64c5d3a72b2855ec7 +R babf57682996bf94e8ad4ede9c8310bb U drh -Z 41e31850fcf9fee16d82b22da63518af +Z a2fd3a9e97e33aae9cbdedab39a4dc89 diff --git a/manifest.uuid b/manifest.uuid index d20d303140..7bc55dc8ed 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -67602e40f122cbb6354048a64c5d3a72b2855ec7 \ No newline at end of file +42f8aa6231bf4ed74bebdc85aa79d23dc20b3c14 \ No newline at end of file diff --git a/src/insert.c b/src/insert.c index 361c3a3a6d..85f34f0683 100644 --- a/src/insert.c +++ b/src/insert.c @@ -1515,7 +1515,7 @@ void sqlite3GenerateConstraintChecks( /* Create a record for this index entry as it should appear after ** the insert or update. Store that record in the aRegIdx[ix] register */ - regIdx = aRegIdx[ix]+1; // sqlite3GetTempRange(pParse, pIdx->nColumn); + regIdx = aRegIdx[ix]+1; for(i=0; inColumn; i++){ int iField = pIdx->aiColumn[i]; int x; @@ -1552,7 +1552,6 @@ void sqlite3GenerateConstraintChecks( /* Find out what action to take in case there is a uniqueness conflict */ onError = pIdx->onError; if( onError==OE_None ){ -// sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nColumn); sqlite3VdbeResolveLabel(v, addrUniqueOk); continue; /* pIdx is not a UNIQUE index */ } @@ -1651,7 +1650,6 @@ void sqlite3GenerateConstraintChecks( } } sqlite3VdbeResolveLabel(v, addrUniqueOk); - // sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nColumn); if( regR!=regIdx ) sqlite3ReleaseTempRange(pParse, regR, nPkField); } if( ipkTop ){ From c6c9e158c5c492d109cf95cefcfa9e4ee66a61ca Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 10 Nov 2016 17:01:36 +0000 Subject: [PATCH 0975/1484] When doing a REPLACE on a WITHOUT ROWID table with no secondary indexes, bypass the OP_NoConflict/OP_Delete sequence and directly overwrite any preexisting row, for a performance increase. FossilOrigin-Name: f7041cbb63b912f9ecad538804b6f2383efbec4e --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/insert.c | 9 ++++++++- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 61e973e4b9..0d7e6089a8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sC++\sstyle\scomments.\s\sNo\scode\schanges. -D 2016-11-10T16:07:43.214 +C When\sdoing\sa\sREPLACE\son\sa\sWITHOUT\sROWID\stable\swith\sno\ssecondary\sindexes,\nbypass\sthe\sOP_NoConflict/OP_Delete\ssequence\sand\sdirectly\soverwrite\sany\npreexisting\srow,\sfor\sa\sperformance\sincrease. +D 2016-11-10T17:01:36.523 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e0217f2d35a0448abbe4b066132ae20136e8b408 @@ -349,7 +349,7 @@ F src/hash.c 63d0ee752a3b92d4695b2b1f5259c4621b2cfebd F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4 F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 -F src/insert.c 63bec2cbffc09d2ea45e0980ded1ebc0e8ef6823 +F src/insert.c 40c64f0ad405d491127ac13ef450a1b44b076e2f F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e F src/loadext.c 5d6642d141c07d366e43d359e94ec9de47add41d F src/main.c 694ac90557abdaa62151a6090670e107b0f2c2ab @@ -1530,7 +1530,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 67602e40f122cbb6354048a64c5d3a72b2855ec7 -R babf57682996bf94e8ad4ede9c8310bb +P 42f8aa6231bf4ed74bebdc85aa79d23dc20b3c14 +R 67c1c35ade05c28c79c38b3258d2929f U drh -Z a2fd3a9e97e33aae9cbdedab39a4dc89 +Z 9380b641677b007c43aa332b4ac80a39 diff --git a/manifest.uuid b/manifest.uuid index 7bc55dc8ed..cc923dbb74 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -42f8aa6231bf4ed74bebdc85aa79d23dc20b3c14 \ No newline at end of file +f7041cbb63b912f9ecad538804b6f2383efbec4e \ No newline at end of file diff --git a/src/insert.c b/src/insert.c index 85f34f0683..a5852fd327 100644 --- a/src/insert.c +++ b/src/insert.c @@ -1560,6 +1560,12 @@ void sqlite3GenerateConstraintChecks( }else if( onError==OE_Default ){ onError = OE_Abort; } + + if( ix==0 && pPk==pIdx && onError==OE_Replace && pPk->pNext==0 ){ + sqlite3VdbeResolveLabel(v, addrUniqueOk); + continue; + } + /* Check to see if the new index entry will be unique */ sqlite3VdbeAddOp4Int(v, OP_NoConflict, iThisCur, addrUniqueOk, @@ -1700,7 +1706,8 @@ void sqlite3CompleteInsertion( VdbeCoverage(v); } sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iIdxCur+i, aRegIdx[i], - aRegIdx[i]+1, pIdx->nColumn); + aRegIdx[i]+1, + pIdx->uniqNotNull ? pIdx->nKeyCol: pIdx->nColumn); pik_flags = 0; if( useSeekResult ) pik_flags = OPFLAG_USESEEKRESULT; if( IsPrimaryKeyIndex(pIdx) && !HasRowid(pTab) ){ From 257c13fa008b2033960e60927d180f2ebbe1fdca Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 10 Nov 2016 20:14:06 +0000 Subject: [PATCH 0976/1484] Avoid storing redundant fields in sorter records when the sort-key and data have fields in common (as in "SELECT a FROM t1 ORDER BY 1"). FossilOrigin-Name: 0af62fdbd8e2aab14718ff8bcb5934f05463c176 --- manifest | 21 ++++++++++++--------- manifest.uuid | 2 +- src/expr.c | 9 +++++++-- src/select.c | 42 +++++++++++++++++++++++++++++++++--------- src/sqliteInt.h | 1 + 5 files changed, 54 insertions(+), 21 deletions(-) diff --git a/manifest b/manifest index a18f153b6d..089494dd59 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\stypo\sin\sthe\sCSV\sextension. -D 2016-11-09T01:46:13.326 +C Avoid\sstoring\sredundant\sfields\sin\ssorter\srecords\swhen\sthe\ssort-key\sand\sdata\shave\nfields\sin\scommon\s(as\sin\s"SELECT\sa\sFROM\st1\sORDER\sBY\s1"). +D 2016-11-10T20:14:06.787 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e0217f2d35a0448abbe4b066132ae20136e8b408 @@ -340,7 +340,7 @@ F src/ctime.c a2a52d6e353f459d8ab0f07321f60fafa47d5421 F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c cb3f6300df24c26c609778b2731f82644b5532ec -F src/expr.c ce7110980fac6dfdfbe1e393443bdb79bad29339 +F src/expr.c 1fd53148e575de810ad10a9eb15f16f2e44ff1dc F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c b9ca262f6ad4d030a3cab737ebf9b0b3c8b4ac80 F src/func.c 7057bc2c105b82faa668d8e2ec85fad4540e5c51 @@ -387,12 +387,12 @@ F src/printf.c a5f0ca08ddede803c241266abb46356ec748ded1 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c 3fac1b2737ea5a724f20b921ac7e259c9be2100b F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac -F src/select.c ea3af83e2d0f245fef81ea4cf04cb730ce67f722 +F src/select.c 64b2273747c6485638bfeb6790e3e774e0605d02 F src/shell.c 63e54cfa1c7ec5b70a4c9a86502bc10280c3d5a3 F src/sqlite.h.in 803f7050f69b2eea573fac219f3c92582c096027 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae -F src/sqliteInt.h 37628fe30c464dc790bcee3bfd3d0caa8f222ed1 +F src/sqliteInt.h 603953faca895386d4f3a8b7046f3e4e6c071c53 F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 @@ -1530,7 +1530,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 754ee844958bdc3b96acfd1f5395da5796e54a82 -R eb905f0421ecb200099f22c1d4910f11 -U mistachkin -Z a09941219c710c6bfaf84cdaf6c10994 +P b4889588246c33374ff3758e21ccc4ce246380b6 +R e8a5368c67459f65dc206ad3df15a284 +T *branch * sorter-opt +T *sym-sorter-opt * +T -sym-trunk * +U dan +Z 220ba0a8da96dcdf18555b62136e6fa1 diff --git a/manifest.uuid b/manifest.uuid index 952d3c0676..2523f32ffc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b4889588246c33374ff3758e21ccc4ce246380b6 \ No newline at end of file +0af62fdbd8e2aab14718ff8bcb5934f05463c176 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index c2b9c8fe46..165bb30f73 100644 --- a/src/expr.c +++ b/src/expr.c @@ -4086,8 +4086,13 @@ int sqlite3ExprCodeExprList( if( !ConstFactorOk(pParse) ) flags &= ~SQLITE_ECEL_FACTOR; for(pItem=pList->a, i=0; ipExpr; - if( (flags & SQLITE_ECEL_REF)!=0 && (j = pList->a[i].u.x.iOrderByCol)>0 ){ - sqlite3VdbeAddOp2(v, copyOp, j+srcReg-1, target+i); + if( (flags & SQLITE_ECEL_REF)!=0 && (j = pItem->u.x.iOrderByCol)>0 ){ + if( flags & SQLITE_ECEL_OMITREF ){ + i--; + n--; + }else{ + sqlite3VdbeAddOp2(v, copyOp, j+srcReg-1, target+i); + } }else if( (flags & SQLITE_ECEL_FACTOR)!=0 && sqlite3ExprIsConstant(pExpr) ){ sqlite3ExprCodeAtInit(pParse, pExpr, target+i, 0); }else{ diff --git a/src/select.c b/src/select.c index 199e13f113..003d42e728 100644 --- a/src/select.c +++ b/src/select.c @@ -533,11 +533,11 @@ static void pushOntoSorter( iLimit = pSelect->iOffset ? pSelect->iOffset+1 : pSelect->iLimit; pSort->labelDone = sqlite3VdbeMakeLabel(v); sqlite3ExprCodeExprList(pParse, pSort->pOrderBy, regBase, regOrigData, - SQLITE_ECEL_DUP|SQLITE_ECEL_REF); + SQLITE_ECEL_DUP); if( bSeq ){ sqlite3VdbeAddOp2(v, OP_Sequence, pSort->iECursor, regBase+nExpr); } - if( nPrefixReg==0 ){ + if( nPrefixReg==0 && nData>0 ){ sqlite3ExprCodeMove(pParse, regData, regBase+nExpr+bSeq, nData); } sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase+nOBSat, nBase-nOBSat, regRecord); @@ -666,7 +666,7 @@ static void codeDistinct( ** If srcTab is negative, then the pEList expressions ** are evaluated in order to get the data for this row. If srcTab is ** zero or more, then data is pulled from srcTab and pEList is used only -** to get number columns and the datatype for each column. +** to get the number of columns and the collation sequence for each column. */ static void selectInnerLoop( Parse *pParse, /* The parser context */ @@ -734,7 +734,25 @@ static void selectInnerLoop( }else{ ecelFlags = 0; } - sqlite3ExprCodeExprList(pParse, pEList, regResult, 0, ecelFlags); + if( pSort && hasDistinct==0 && eDest!=SRT_EphemTab && eDest!=SRT_Table ){ + /* For each expression in pEList that is a copy of an expression in + ** the ORDER BY clause (pSort->pOrderBy), set the associated + ** iOrderByCol value to one more than the index of the ORDER BY + ** expression within the sort-key that pushOntoSorter() will generate. + ** This allows the pEList field to be omitted from the sorted record, + ** saving space and CPU cycles. */ + ecelFlags |= (SQLITE_ECEL_OMITREF|SQLITE_ECEL_REF); + for(i=pSort->nOBSat; ipOrderBy->nExpr; i++){ + int j; + if( (j = pSort->pOrderBy->a[i].u.x.iOrderByCol)>0 ){ + pEList->a[j-1].u.x.iOrderByCol = i+1-pSort->nOBSat; + } + } + + assert( eDest==SRT_Set || eDest==SRT_Mem + || eDest==SRT_Coroutine || eDest==SRT_Output ); + } + nResultCol = sqlite3ExprCodeExprList(pParse,pEList,regResult,0,ecelFlags); } /* If the DISTINCT keyword was present on the SELECT statement @@ -900,11 +918,12 @@ static void selectInnerLoop( ** memory cells and break out of the scan loop. */ case SRT_Mem: { - assert( nResultCol==pDest->nSdst ); if( pSort ){ + assert( nResultCol<=pDest->nSdst ); pushOntoSorter( pParse, pSort, p, regResult, regResult, nResultCol, nPrefixReg); }else{ + assert( nResultCol==pDest->nSdst ); assert( regResult==iParm ); /* The LIMIT clause will jump out of the loop for us */ } @@ -1202,14 +1221,13 @@ static void generateSortTail( int iParm = pDest->iSDParm; int regRow; int regRowid; + int iCol; int nKey; int iSortTab; /* Sorter cursor to read from */ int nSortData; /* Trailing values to read from sorter */ int i; int bSeq; /* True if sorter record includes seq. no. */ -#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS struct ExprList_item *aOutEx = p->pEList->a; -#endif assert( addrBreak<0 ); if( pSort->labelBkOut ){ @@ -1247,8 +1265,14 @@ static void generateSortTail( iSortTab = iTab; bSeq = 1; } - for(i=0; i Date: Thu, 10 Nov 2016 20:42:08 +0000 Subject: [PATCH 0977/1484] Avoid a few unnecessary calls to sqlite3BtreeMovetoUnpacked(). FossilOrigin-Name: eac0e827a61cfec4dd9b6d407ff398e9fda3510b --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btree.c | 8 +++++--- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 0d7e6089a8..815694d6be 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C When\sdoing\sa\sREPLACE\son\sa\sWITHOUT\sROWID\stable\swith\sno\ssecondary\sindexes,\nbypass\sthe\sOP_NoConflict/OP_Delete\ssequence\sand\sdirectly\soverwrite\sany\npreexisting\srow,\sfor\sa\sperformance\sincrease. -D 2016-11-10T17:01:36.523 +C Avoid\sa\sfew\sunnecessary\scalls\sto\ssqlite3BtreeMovetoUnpacked(). +D 2016-11-10T20:42:08.396 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e0217f2d35a0448abbe4b066132ae20136e8b408 @@ -330,7 +330,7 @@ F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792 F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b F src/bitvec.c 3ee4c8b2c94ed3a7377256e18199e6ff5cf33f63 F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 -F src/btree.c d1a3d691917cb7d67d50318aef990d8f30d172c7 +F src/btree.c 592a72c259752b3cae6928e3f2448a2cb540b032 F src/btree.h 630303068c82a359f6ddf202b205ae927721b090 F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 F src/build.c 178f16698cbcb43402c343a9413fe22c99ffee21 @@ -1530,7 +1530,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 42f8aa6231bf4ed74bebdc85aa79d23dc20b3c14 -R 67c1c35ade05c28c79c38b3258d2929f +P f7041cbb63b912f9ecad538804b6f2383efbec4e +R d3d5f8b510b4445e2e54b3c5a8a5e3a5 U drh -Z 9380b641677b007c43aa332b4ac80a39 +Z 4683912e0f389e0006dbaa0668a519e9 diff --git a/manifest.uuid b/manifest.uuid index cc923dbb74..49b87ea866 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f7041cbb63b912f9ecad538804b6f2383efbec4e \ No newline at end of file +eac0e827a61cfec4dd9b6d407ff398e9fda3510b \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index b92b6018b4..78c4677d25 100644 --- a/src/btree.c +++ b/src/btree.c @@ -8013,9 +8013,11 @@ int sqlite3BtreeInsert( /* If the cursor is currently on the last row and we are appending a ** new row onto the end, set the "loc" to avoid an unnecessary ** btreeMoveto() call */ - if( (pCur->curFlags&BTCF_ValidNKey)!=0 && pX->nKey>0 - && pCur->info.nKey==pX->nKey-1 ){ - loc = -1; + if( (pCur->curFlags&BTCF_ValidNKey)!=0 && pX->nKey==pCur->info.nKey ){ + loc = 0; + }else if( (pCur->curFlags&BTCF_ValidNKey)!=0 && pX->nKey>0 + && pCur->info.nKey==pX->nKey-1 ){ + loc = -1; }else if( loc==0 ){ rc = sqlite3BtreeMovetoUnpacked(pCur, 0, pX->nKey, appendBias, &loc); if( rc ) return rc; From 4360fcea6deb15aabcf1f2d040be14ae9de3d32b Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 11 Nov 2016 03:37:24 +0000 Subject: [PATCH 0978/1484] Take care not to try to generate code for the ATTACH and DETACH commands if there were syntax errors during parsing. Fix for ticket [2f1b168ab4d4844] FossilOrigin-Name: b0ff183b8ffdbebece06cfea1c6781fc0e8e8547 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/attach.c | 1 + test/fuzz-oss1.test | 4 ++++ 4 files changed, 14 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index a18f153b6d..cfad1a2249 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\stypo\sin\sthe\sCSV\sextension. -D 2016-11-09T01:46:13.326 +C Take\scare\snot\sto\stry\sto\sgenerate\scode\sfor\sthe\sATTACH\sand\sDETACH\scommands\nif\sthere\swere\ssyntax\serrors\sduring\sparsing.\nFix\sfor\sticket\s[2f1b168ab4d4844] +D 2016-11-11T03:37:24.086 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e0217f2d35a0448abbe4b066132ae20136e8b408 @@ -325,7 +325,7 @@ F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F src/alter.c 299117695b1f21ac62dfc5b608588810ba22ed0d F src/analyze.c 8b62b2cf4da85451534ac0af82cafc418d837f68 -F src/attach.c 8c19066b4b5357b5d66154e856c61df01e71203a +F src/attach.c f6725410c184a80d8141b294fdf98a854c8a52b5 F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792 F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b F src/bitvec.c 3ee4c8b2c94ed3a7377256e18199e6ff5cf33f63 @@ -807,7 +807,7 @@ F test/func2.test 772d66227e4e6684b86053302e2d74a2500e1e0f F test/func3.test d202a7606d23f90988a664e88e268aed1087c11c F test/func4.test 6beacdfcb0e18c358e6c2dcacf1b65d1fa80955f F test/func5.test cdd224400bc3e48d891827cc913a57051a426fa4 -F test/fuzz-oss1.test 4912e528ec9cf2f42134456933659d371c9e0d74 +F test/fuzz-oss1.test e58330d01cbbd8215ee636b17a03fe220b37dbfa F test/fuzz.test 96083052bf5765e4518c1ba686ce2bab785670d1 F test/fuzz2.test 76dc35b32b6d6f965259508508abce75a6c4d7e1 F test/fuzz3.test b47377143f0c80f91ed29d722861077ff34415d5 @@ -1530,7 +1530,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 754ee844958bdc3b96acfd1f5395da5796e54a82 -R eb905f0421ecb200099f22c1d4910f11 -U mistachkin -Z a09941219c710c6bfaf84cdaf6c10994 +P b4889588246c33374ff3758e21ccc4ce246380b6 +R 26247ef800afdc7745db1d52a3a74bf0 +U drh +Z bdc6c3a824c3e2f132fc99deec6951e5 diff --git a/manifest.uuid b/manifest.uuid index 952d3c0676..be53f11adc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b4889588246c33374ff3758e21ccc4ce246380b6 \ No newline at end of file +b0ff183b8ffdbebece06cfea1c6781fc0e8e8547 \ No newline at end of file diff --git a/src/attach.c b/src/attach.c index 507b9c1238..4fe97bacea 100644 --- a/src/attach.c +++ b/src/attach.c @@ -325,6 +325,7 @@ static void codeAttach( sqlite3* db = pParse->db; int regArgs; + if( pParse->nErr ) goto attach_end; memset(&sName, 0, sizeof(NameContext)); sName.pParse = pParse; diff --git a/test/fuzz-oss1.test b/test/fuzz-oss1.test index 08bc670845..e77b7ed0f8 100644 --- a/test/fuzz-oss1.test +++ b/test/fuzz-oss1.test @@ -1997,5 +1997,9 @@ NULL AND ("9_u" COLLATE NOCASE = ? COLLATE NOCASE))) FROM (SELECT } } {/.* Goto .*/} +# Crash reported by OSS-FUZZ on 2016-11-10 +do_catchsql_test fuzz-oss1-detach { + DETACH x IS #1; +} {1 {near "#1": syntax error}} finish_test From c5b86be7db42b78909dfabe5f8fc0733773a0b90 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 11 Nov 2016 04:37:00 +0000 Subject: [PATCH 0979/1484] Add the --raw option to the ".read" dot-command of the command-line shell, to cause the named file to be read and sent directly into sqlite3_exec() without any interpretation. FossilOrigin-Name: 09233770b24d69a305556241a6beeb5e4d77c0d7 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/shell.c | 48 ++++++++++++++++++++++++++++++++++++++++-------- 3 files changed, 47 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index cfad1a2249..51a0a7d02f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Take\scare\snot\sto\stry\sto\sgenerate\scode\sfor\sthe\sATTACH\sand\sDETACH\scommands\nif\sthere\swere\ssyntax\serrors\sduring\sparsing.\nFix\sfor\sticket\s[2f1b168ab4d4844] -D 2016-11-11T03:37:24.086 +C Add\sthe\s--raw\soption\sto\sthe\s".read"\sdot-command\sof\sthe\scommand-line\sshell,\nto\scause\sthe\snamed\sfile\sto\sbe\sread\sand\ssent\sdirectly\sinto\ssqlite3_exec()\nwithout\sany\sinterpretation. +D 2016-11-11T04:37:00.671 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e0217f2d35a0448abbe4b066132ae20136e8b408 @@ -388,7 +388,7 @@ F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c 3fac1b2737ea5a724f20b921ac7e259c9be2100b F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c ea3af83e2d0f245fef81ea4cf04cb730ce67f722 -F src/shell.c 63e54cfa1c7ec5b70a4c9a86502bc10280c3d5a3 +F src/shell.c e77c47b035e7ac79c89ca25fdb4fbc7158a86a20 F src/sqlite.h.in 803f7050f69b2eea573fac219f3c92582c096027 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae @@ -1530,7 +1530,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b4889588246c33374ff3758e21ccc4ce246380b6 -R 26247ef800afdc7745db1d52a3a74bf0 +P b0ff183b8ffdbebece06cfea1c6781fc0e8e8547 +R 1bc28093103f82773b6175c0eaf36791 U drh -Z bdc6c3a824c3e2f132fc99deec6951e5 +Z 12078e4f7b8e85a9a59383108eda95de diff --git a/manifest.uuid b/manifest.uuid index be53f11adc..271b3c84d2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b0ff183b8ffdbebece06cfea1c6781fc0e8e8547 \ No newline at end of file +09233770b24d69a305556241a6beeb5e4d77c0d7 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 6a7bee142d..8c352e87c8 100644 --- a/src/shell.c +++ b/src/shell.c @@ -4205,18 +4205,50 @@ static int do_meta_command(char *zLine, ShellState *p){ if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 ){ FILE *alt; - if( nArg!=2 ){ - raw_printf(stderr, "Usage: .read FILE\n"); + char *zFile; + int rawMode = 0; + if( nArg!=2 && nArg!=3 ){ + raw_printf(stderr, "Usage: .read [--raw] FILE\n"); rc = 1; goto meta_command_exit; } - alt = fopen(azArg[1], "rb"); - if( alt==0 ){ - utf8_printf(stderr,"Error: cannot open \"%s\"\n", azArg[1]); - rc = 1; + if( nArg==3 ){ + const char *z = azArg[1]; + while( z[0]=='-' ) z++; + if( strcmp(z,"raw")==0 ){ + rawMode = 1; + } + else{ + raw_printf(stderr, "unknown option: \"%s\"\n", azArg[1]); + rc = 1; + goto meta_command_exit; + } + } + zFile = azArg[nArg-1]; + if( rawMode ){ + char *z = readFile(zFile); + if( z==0 ){ + utf8_printf(stderr, "Error: cannot open \"%s\"\n", zFile); + rc = 1; + }else{ + char *zErr = 0; + open_db(p, 1); + rc = sqlite3_exec(p->db, z, callback, p, &zErr); + sqlite3_free(z); + if( zErr ){ + utf8_printf(stdout, "%s", zErr); + sqlite3_free(zErr); + } + } }else{ - rc = process_input(p, alt); - fclose(alt); + alt = fopen(zFile, "rb"); + if( alt==0 ){ + utf8_printf(stderr,"Error: cannot open \"%s\"\n", azArg[1]); + rc = 1; + }else{ + rc = process_input(p, alt); + fclose(alt); + } } }else From 2f9a613ced580d17a7859316b9e761e259476f7b Mon Sep 17 00:00:00 2001 From: mistachkin Date: Fri, 11 Nov 2016 05:19:45 +0000 Subject: [PATCH 0980/1484] In the command line shell, avoid using utf8_printf() in a couple places where it is superfluous. FossilOrigin-Name: 6311a8bdb1f2e1813516a32d171aae030bd73fd3 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/shell.c | 10 +++++----- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 51a0a7d02f..3c2354957f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\s--raw\soption\sto\sthe\s".read"\sdot-command\sof\sthe\scommand-line\sshell,\nto\scause\sthe\snamed\sfile\sto\sbe\sread\sand\ssent\sdirectly\sinto\ssqlite3_exec()\nwithout\sany\sinterpretation. -D 2016-11-11T04:37:00.671 +C In\sthe\scommand\sline\sshell,\savoid\susing\sutf8_printf()\sin\sa\scouple\splaces\swhere\sit\sis\ssuperfluous. +D 2016-11-11T05:19:45.427 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e0217f2d35a0448abbe4b066132ae20136e8b408 @@ -388,7 +388,7 @@ F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c 3fac1b2737ea5a724f20b921ac7e259c9be2100b F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c ea3af83e2d0f245fef81ea4cf04cb730ce67f722 -F src/shell.c e77c47b035e7ac79c89ca25fdb4fbc7158a86a20 +F src/shell.c dd8dbdcfbbac328c9011ce70d516c6872f9bae6e F src/sqlite.h.in 803f7050f69b2eea573fac219f3c92582c096027 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae @@ -1530,7 +1530,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b0ff183b8ffdbebece06cfea1c6781fc0e8e8547 -R 1bc28093103f82773b6175c0eaf36791 -U drh -Z 12078e4f7b8e85a9a59383108eda95de +P 09233770b24d69a305556241a6beeb5e4d77c0d7 +R 5cf5e2ce8ca8e99cb9bee7725cd4410a +U mistachkin +Z 9c763fa2ad7418630629cdc53f5357cd diff --git a/manifest.uuid b/manifest.uuid index 271b3c84d2..1320f1ef5b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -09233770b24d69a305556241a6beeb5e4d77c0d7 \ No newline at end of file +6311a8bdb1f2e1813516a32d171aae030bd73fd3 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 8c352e87c8..103af22e43 100644 --- a/src/shell.c +++ b/src/shell.c @@ -1216,10 +1216,10 @@ static int shell_callback( raw_printf(p->out," VALUES("); }else if( p->cnt==0 && p->showHeader ){ for(i=0; i0 ) utf8_printf(p->out, ","); + if( i>0 ) raw_printf(p->out, ","); output_quoted_string(p->out, azCol[i]); } - utf8_printf(p->out,"\n"); + raw_printf(p->out,"\n"); } p->cnt++; for(i=0; idb)); }else{ utf8_printf(stdout, "%s;\n", zSql); - utf8_printf(stdout, + raw_printf(stdout, "WARNING: writing to an imposter table will corrupt the index!\n" ); } }else{ - utf8_printf(stderr, "SQLITE_TESTCTRL_IMPOSTER returns %d\n", rc); + raw_printf(stderr, "SQLITE_TESTCTRL_IMPOSTER returns %d\n", rc); rc = 1; } sqlite3_free(zSql); @@ -4814,7 +4814,7 @@ static int do_meta_command(char *zLine, ShellState *p){ output_reset(p); p->out = output_file_open("testcase-out.txt"); if( p->out==0 ){ - utf8_printf(stderr, "Error: cannot open 'testcase-out.txt'\n"); + raw_printf(stderr, "Error: cannot open 'testcase-out.txt'\n"); } if( nArg>=2 ){ sqlite3_snprintf(sizeof(p->zTestcase), p->zTestcase, "%s", azArg[1]); From b47ebe6128b37a80011913cbdef13eb1132612ee Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 11 Nov 2016 09:51:46 +0000 Subject: [PATCH 0981/1484] Add extra tests for the xBestIndex() virtual table method. FossilOrigin-Name: 642a8fba91d2bf61b494b845cb499714363209b1 --- manifest | 13 ++--- manifest.uuid | 2 +- test/bestindex4.test | 121 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 129 insertions(+), 7 deletions(-) create mode 100644 test/bestindex4.test diff --git a/manifest b/manifest index 3c2354957f..0170bf1eb8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\sthe\scommand\sline\sshell,\savoid\susing\sutf8_printf()\sin\sa\scouple\splaces\swhere\sit\sis\ssuperfluous. -D 2016-11-11T05:19:45.427 +C Add\sextra\stests\sfor\sthe\sxBestIndex()\svirtual\stable\smethod. +D 2016-11-11T09:51:46.009 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e0217f2d35a0448abbe4b066132ae20136e8b408 @@ -535,6 +535,7 @@ F test/bc_common.tcl b5e42d80305be95697e6370e015af571e5333a1c F test/bestindex1.test 0cf1bd2d7b97d3a3a8c10736125274f64765c4ee F test/bestindex2.test 4a06b8922ab2fd09434870da8d1cdf525aaf7060 F test/bestindex3.test dd5fa4f483cd0356549203c4522f8c9e21cb1fc0 +F test/bestindex4.test e6ef2ffe5787e6dbacb5f934ee3f32cf106474a1 F test/between.test 34d375fb5ce1ae283ffe82b6b233e9f38e84fc6c F test/bigfile.test aa74f4e5db51c8e54a1d9de9fa65d01d1eb20b59 F test/bigfile2.test 1b489a3a39ae90c7f027b79110d6b4e1dbc71bfc @@ -1530,7 +1531,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 09233770b24d69a305556241a6beeb5e4d77c0d7 -R 5cf5e2ce8ca8e99cb9bee7725cd4410a -U mistachkin -Z 9c763fa2ad7418630629cdc53f5357cd +P 6311a8bdb1f2e1813516a32d171aae030bd73fd3 +R 3e019704b19690d86a1b7d773d983727 +U dan +Z f0d6f5c148a8f8096f5f4aa2078863db diff --git a/manifest.uuid b/manifest.uuid index 1320f1ef5b..7bffeb6ac5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6311a8bdb1f2e1813516a32d171aae030bd73fd3 \ No newline at end of file +642a8fba91d2bf61b494b845cb499714363209b1 \ No newline at end of file diff --git a/test/bestindex4.test b/test/bestindex4.test new file mode 100644 index 0000000000..836701f6b9 --- /dev/null +++ b/test/bestindex4.test @@ -0,0 +1,121 @@ +# 2016 November 11 +# +# 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. +# +#*********************************************************************** +# Test the virtual table interface. In particular the xBestIndex +# method. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix bestindex4 + +ifcapable !vtab { + finish_test + return +} + +#------------------------------------------------------------------------- +# Virtual table callback for a virtual table named $tbl. +# +# The table created is: +# +# "CREATE TABLE t1 (id, host, class)" +# +# The virtual table supports == operators on a subset of its columns. The +# exact subset depends on the value of bitmask paramater $param. +# +# 0x01 - == on "id" supported +# 0x02 - == on "host" supported +# 0x04 - == on "class" supported +# +# $param also supports the following bits: +# +# 0x08 - ignore the "usable" flag (malfunction) +# +# +# +proc vtab_cmd {param method args} { + switch -- $method { + xConnect { + return "CREATE TABLE t1(id TEXT, host TEXT, class TEXT)" + } + + xBestIndex { + foreach {clist orderby mask} $args {} + + set ret [list] + + set use use + + + for {set i 0} {$i < [llength $clist]} {incr i} { + array unset C + array set C [lindex $clist $i] + if { ($C(usable) || ($param & 0x08)) + && $C(op)=="eq" && ($param & 1<<$C(column)) + } { + lappend ret $use $i + break + } + } + + set score 1000000 + if {$ret!=""} { + set score [expr $score / [llength $ret]] + } + lappend ret cost $score rows $score + + return $ret + } + + xFilter { + } + } + return "" +} + +register_tcl_module db + +for {set param1 0} {$param1<16} {incr param1} { + for {set param2 0} {$param2<16} {incr param2} { + reset_db + register_tcl_module db + do_execsql_test 1.$param1.$param2.1 " + CREATE VIRTUAL TABLE t1 USING tcl('vtab_cmd $param1'); + CREATE VIRTUAL TABLE t2 USING tcl('vtab_cmd $param2'); + " + + foreach {tn sql} { + 2 "select t1.id as ID from t1, t2 where t1.id=t2.host and t2.class='xx'" + 3 { + select t1.id as ID from t1, t2 where t2.class ='xx' and t2.id = t1.host + } + 4 { + select t1.id as ID from t1, t2 where t1.host = t2.id and t2. class ='xx' + } + } { + + if {($param1 & 0x08)==0 && ($param2 & 0x08)==0} { + + do_execsql_test 1.$param1.$param2.$tn.a $sql {} + + } else { + do_test 1.$param1.$param2.$tn.b { + catchsql $sql + set {} {} + } {} + } + } + + } +} + +finish_test + From 4e8142c726fe3a1dcd4b79f098a012ed0ea365ee Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 11 Nov 2016 14:54:22 +0000 Subject: [PATCH 0982/1484] Back out the "--raw" option on ".read" in the command-line shell. Instead, fix the command-line shell so that if EOF is reached without seeing a final semicolon, it goes ahead and passes the accumulated SQL text to SQLite. FossilOrigin-Name: f98c8ac8c485098f163400d3a92d6afb4008adbe --- manifest | 16 +++---- manifest.uuid | 2 +- src/shell.c | 119 +++++++++++++++++++---------------------------- test/shell3.test | 2 +- 4 files changed, 57 insertions(+), 82 deletions(-) diff --git a/manifest b/manifest index 0170bf1eb8..c6509cbcb1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sextra\stests\sfor\sthe\sxBestIndex()\svirtual\stable\smethod. -D 2016-11-11T09:51:46.009 +C Back\sout\sthe\s"--raw"\soption\son\s".read"\sin\sthe\scommand-line\sshell.\s\sInstead,\nfix\sthe\scommand-line\sshell\sso\sthat\sif\sEOF\sis\sreached\swithout\sseeing\sa\nfinal\ssemicolon,\sit\sgoes\sahead\sand\spasses\sthe\saccumulated\sSQL\stext\sto\nSQLite. +D 2016-11-11T14:54:22.386 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e0217f2d35a0448abbe4b066132ae20136e8b408 @@ -388,7 +388,7 @@ F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c 3fac1b2737ea5a724f20b921ac7e259c9be2100b F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c ea3af83e2d0f245fef81ea4cf04cb730ce67f722 -F src/shell.c dd8dbdcfbbac328c9011ce70d516c6872f9bae6e +F src/shell.c f04e4af75c5517735397d060ed0b4a874104bb41 F src/sqlite.h.in 803f7050f69b2eea573fac219f3c92582c096027 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae @@ -1087,7 +1087,7 @@ F test/shared_err.test 2f2aee20db294b9924e81f6ccbe60f19e21e8506 F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304 F test/shell1.test 65b10cd8a90cda9b5af9100a45689a57dcc01a31 F test/shell2.test e242a9912f44f4c23c3d1d802a83e934e84c853b -F test/shell3.test da513d522ef6f01cee8475dcf8332bff8982b3dd +F test/shell3.test 9b95ba643eaa228376f06a898fb410ee9b6e57c1 F test/shell4.test 89ad573879a745974ff2df20ff97c5d6ffffbd5d F test/shell5.test 50a732c1c2158b1cd62cf53975ce1ea7ce6b9dc9 F test/shortread1.test bb591ef20f0fd9ed26d0d12e80eee6d7ac8897a3 @@ -1531,7 +1531,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 6311a8bdb1f2e1813516a32d171aae030bd73fd3 -R 3e019704b19690d86a1b7d773d983727 -U dan -Z f0d6f5c148a8f8096f5f4aa2078863db +P 642a8fba91d2bf61b494b845cb499714363209b1 +R 8f6e4afb0238a1c423a3400150605c04 +U drh +Z 821b86c08ecda9d420b23c0425e87f9f diff --git a/manifest.uuid b/manifest.uuid index 7bffeb6ac5..d076ff3f20 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -642a8fba91d2bf61b494b845cb499714363209b1 \ No newline at end of file +f98c8ac8c485098f163400d3a92d6afb4008adbe \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 103af22e43..aaba1080e4 100644 --- a/src/shell.c +++ b/src/shell.c @@ -4205,50 +4205,18 @@ static int do_meta_command(char *zLine, ShellState *p){ if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 ){ FILE *alt; - char *zFile; - int rawMode = 0; - if( nArg!=2 && nArg!=3 ){ - raw_printf(stderr, "Usage: .read [--raw] FILE\n"); + if( nArg!=2 ){ + raw_printf(stderr, "Usage: .read FILE\n"); rc = 1; goto meta_command_exit; } - if( nArg==3 ){ - const char *z = azArg[1]; - while( z[0]=='-' ) z++; - if( strcmp(z,"raw")==0 ){ - rawMode = 1; - } - else{ - raw_printf(stderr, "unknown option: \"%s\"\n", azArg[1]); - rc = 1; - goto meta_command_exit; - } - } - zFile = azArg[nArg-1]; - if( rawMode ){ - char *z = readFile(zFile); - if( z==0 ){ - utf8_printf(stderr, "Error: cannot open \"%s\"\n", zFile); - rc = 1; - }else{ - char *zErr = 0; - open_db(p, 1); - rc = sqlite3_exec(p->db, z, callback, p, &zErr); - sqlite3_free(z); - if( zErr ){ - utf8_printf(stdout, "%s", zErr); - sqlite3_free(zErr); - } - } + alt = fopen(azArg[1], "rb"); + if( alt==0 ){ + utf8_printf(stderr,"Error: cannot open \"%s\"\n", azArg[1]); + rc = 1; }else{ - alt = fopen(zFile, "rb"); - if( alt==0 ){ - utf8_printf(stderr,"Error: cannot open \"%s\"\n", azArg[1]); - rc = 1; - }else{ - rc = process_input(p, alt); - fclose(alt); - } + rc = process_input(p, alt); + fclose(alt); } }else @@ -5208,6 +5176,42 @@ static int line_is_complete(char *zSql, int nSql){ return rc; } +/* +** Run a single line of SQL +*/ +static int runOneSqlLine(ShellState *p, char *zSql, FILE *in, int startline){ + int rc; + char *zErrMsg = 0; + + open_db(p, 0); + if( p->backslashOn ) resolve_backslashes(zSql); + BEGIN_TIMER; + rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg); + END_TIMER; + if( rc || zErrMsg ){ + char zPrefix[100]; + if( in!=0 || !stdin_is_interactive ){ + sqlite3_snprintf(sizeof(zPrefix), zPrefix, + "Error: near line %d:", startline); + }else{ + sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:"); + } + if( zErrMsg!=0 ){ + utf8_printf(stderr, "%s %s\n", zPrefix, zErrMsg); + sqlite3_free(zErrMsg); + zErrMsg = 0; + }else{ + utf8_printf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db)); + } + return 1; + }else if( p->countChanges ){ + raw_printf(p->out, "changes: %3d total_changes: %d\n", + sqlite3_changes(p->db), sqlite3_total_changes(p->db)); + } + return 0; +} + + /* ** Read input from *in and process it. If *in==0 then input ** is interactive - the user is typing it it. Otherwise, input @@ -5224,7 +5228,6 @@ static int process_input(ShellState *p, FILE *in){ int nSql = 0; /* Bytes of zSql[] used */ int nAlloc = 0; /* Allocated zSql[] space */ int nSqlPrior = 0; /* Bytes of zSql[] used by prior line */ - char *zErrMsg; /* Error message returned */ int rc; /* Error code */ int errCnt = 0; /* Number of errors seen */ int lineno = 0; /* Current line number */ @@ -5284,32 +5287,7 @@ static int process_input(ShellState *p, FILE *in){ } if( nSql && line_contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior) && sqlite3_complete(zSql) ){ - p->cnt = 0; - open_db(p, 0); - if( p->backslashOn ) resolve_backslashes(zSql); - BEGIN_TIMER; - rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg); - END_TIMER; - if( rc || zErrMsg ){ - char zPrefix[100]; - if( in!=0 || !stdin_is_interactive ){ - sqlite3_snprintf(sizeof(zPrefix), zPrefix, - "Error: near line %d:", startline); - }else{ - sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:"); - } - if( zErrMsg!=0 ){ - utf8_printf(stderr, "%s %s\n", zPrefix, zErrMsg); - sqlite3_free(zErrMsg); - zErrMsg = 0; - }else{ - utf8_printf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db)); - } - errCnt++; - }else if( p->countChanges ){ - raw_printf(p->out, "changes: %3d total_changes: %d\n", - sqlite3_changes(p->db), sqlite3_total_changes(p->db)); - } + errCnt += runOneSqlLine(p, zSql, in, startline); nSql = 0; if( p->outCount ){ output_reset(p); @@ -5320,11 +5298,8 @@ static int process_input(ShellState *p, FILE *in){ nSql = 0; } } - if( nSql ){ - if( !_all_whitespace(zSql) ){ - utf8_printf(stderr, "Error: incomplete SQL: %s\n", zSql); - errCnt++; - } + if( nSql && !_all_whitespace(zSql) ){ + runOneSqlLine(p, zSql, in, startline); } free(zSql); free(zLine); diff --git a/test/shell3.test b/test/shell3.test index 6e38021d0c..bb2524c1cc 100644 --- a/test/shell3.test +++ b/test/shell3.test @@ -96,6 +96,6 @@ do_test shell3-2.6 { } {0 {}} do_test shell3-2.7 { catchcmd "foo.db" "CREATE TABLE" -} {1 {Error: incomplete SQL: CREATE TABLE}} +} {1 {Error: near line 1: near "TABLE": syntax error}} finish_test From 3bafdede8a652d48b1041821dd110fcdc0b26783 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 11 Nov 2016 15:49:01 +0000 Subject: [PATCH 0983/1484] Handle some obscure "row value misused" cases that could cause segfaults or assertion failures. FossilOrigin-Name: fba5fddb1c40af75634b01c1f06d2610df697e01 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/resolve.c | 17 +++++++++++++++-- test/rowvalue.test | 13 +++++++++++++ 4 files changed, 37 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index c6509cbcb1..c3e4c15178 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Back\sout\sthe\s"--raw"\soption\son\s".read"\sin\sthe\scommand-line\sshell.\s\sInstead,\nfix\sthe\scommand-line\sshell\sso\sthat\sif\sEOF\sis\sreached\swithout\sseeing\sa\nfinal\ssemicolon,\sit\sgoes\sahead\sand\spasses\sthe\saccumulated\sSQL\stext\sto\nSQLite. -D 2016-11-11T14:54:22.386 +C Handle\ssome\sobscure\s"row\svalue\smisused"\scases\sthat\scould\scause\ssegfaults\sor\nassertion\sfailures. +D 2016-11-11T15:49:01.962 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e0217f2d35a0448abbe4b066132ae20136e8b408 @@ -385,7 +385,7 @@ F src/pragma.h 64c78a648751b9f4f297276c4eb7507b14b4628c F src/prepare.c b1140c3d0cf59bc85ace00ce363153041b424b7a F src/printf.c a5f0ca08ddede803c241266abb46356ec748ded1 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 -F src/resolve.c 3fac1b2737ea5a724f20b921ac7e259c9be2100b +F src/resolve.c bb070cf5f23611c44ab7e4788803684e385fc3fb F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c ea3af83e2d0f245fef81ea4cf04cb730ce67f722 F src/shell.c f04e4af75c5517735397d060ed0b4a874104bb41 @@ -1028,7 +1028,7 @@ F test/rollbackfault.test 0e646aeab8840c399cfbfa43daab46fd609cf04a F test/rowallock.test 3f88ec6819489d0b2341c7a7528ae17c053ab7cc F test/rowhash.test 0bc1d31415e4575d10cacf31e1a66b5cc0f8be81 F test/rowid.test 5b7509f384f4f6fae1af3c8c104c8ca299fea18d -F test/rowvalue.test bcd78c91fe2aadade6fd00d2616546650b9ebc9e +F test/rowvalue.test b5a9c0fa347a763c558da2397499df51da3cdf6b F test/rowvalue2.test 060d238b7e5639a7c5630cb5e63e311b44efef2b F test/rowvalue3.test 01399b7bf150b0d41abce76c18072da777c2500c F test/rowvalue4.test 4b556d7de161a0dd8cff095c336e913986398bea @@ -1531,7 +1531,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 642a8fba91d2bf61b494b845cb499714363209b1 -R 8f6e4afb0238a1c423a3400150605c04 -U drh -Z 821b86c08ecda9d420b23c0425e87f9f +P f98c8ac8c485098f163400d3a92d6afb4008adbe +R a89e5be61b771e1fa50ceffc5542b881 +U dan +Z 011fdd87018b196e46b8f2521e403dd0 diff --git a/manifest.uuid b/manifest.uuid index d076ff3f20..1bc728291a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f98c8ac8c485098f163400d3a92d6afb4008adbe \ No newline at end of file +fba5fddb1c40af75634b01c1f06d2610df697e01 \ No newline at end of file diff --git a/src/resolve.c b/src/resolve.c index f464b657fc..dac73e5fa9 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -400,6 +400,10 @@ static int lookupName( sqlite3ErrorMsg(pParse, "misuse of aliased aggregate %s", zAs); return WRC_Abort; } + if( sqlite3ExprVectorSize(pOrig)!=1 ){ + sqlite3ErrorMsg(pParse, "row value misused"); + return WRC_Abort; + } resolveAlias(pParse, pEList, j, pExpr, "", nSubquery); cnt = 1; pMatch = 0; @@ -776,6 +780,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ notValid(pParse, pNC, "parameters", NC_IsCheck|NC_PartIdx|NC_IdxExpr); break; } + case TK_BETWEEN: case TK_EQ: case TK_NE: case TK_LT: @@ -786,10 +791,17 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ case TK_ISNOT: { int nLeft, nRight; if( pParse->db->mallocFailed ) break; - assert( pExpr->pRight!=0 ); assert( pExpr->pLeft!=0 ); nLeft = sqlite3ExprVectorSize(pExpr->pLeft); - nRight = sqlite3ExprVectorSize(pExpr->pRight); + if( pExpr->op==TK_BETWEEN ){ + nRight = sqlite3ExprVectorSize(pExpr->x.pList->a[0].pExpr); + if( nRight==nLeft ){ + nRight = sqlite3ExprVectorSize(pExpr->x.pList->a[1].pExpr); + } + }else{ + assert( pExpr->pRight!=0 ); + nRight = sqlite3ExprVectorSize(pExpr->pRight); + } if( nLeft!=nRight ){ testcase( pExpr->op==TK_EQ ); testcase( pExpr->op==TK_NE ); @@ -799,6 +811,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ testcase( pExpr->op==TK_GE ); testcase( pExpr->op==TK_IS ); testcase( pExpr->op==TK_ISNOT ); + testcase( pExpr->op==TK_BETWEEN ); sqlite3ErrorMsg(pParse, "row value misused"); } break; diff --git a/test/rowvalue.test b/test/rowvalue.test index 6ab1154b50..231565a4be 100644 --- a/test/rowvalue.test +++ b/test/rowvalue.test @@ -266,4 +266,17 @@ do_execsql_test 12.1 { SELECT *,'x' FROM t1 LEFT JOIN t2 ON (a,b)=(x,y); } {1 2 {} {} x} + +foreach {tn sql} { + 0 "SELECT (1,2) AS x WHERE x=3" + 1 "SELECT (1,2) BETWEEN 1 AND 2" + 2 "SELECT 1 BETWEEN (1,2) AND 2" + 3 "SELECT 2 BETWEEN 1 AND (1,2)" + 4 "SELECT (1,2) FROM (SELECT 1) ORDER BY 1" + 5 "SELECT (1,2) FROM (SELECT 1) GROUP BY 1" +} { + do_catchsql_test 13.$tn $sql {1 {row value misused}} +} + + finish_test From ea432ba2df01ece565f72816d7f9cc55b57c4953 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 11 Nov 2016 16:33:47 +0000 Subject: [PATCH 0984/1484] Add the test/ossfuzz.c interface adaptor for OSS-FUZZ. Make previsions for testing the adaptor using fuzzcheck.c. FossilOrigin-Name: 119d6ef8478ea6ab07dfd0e974d2f5a8dcfce87e --- main.mk | 6 ++-- manifest | 17 +++++----- manifest.uuid | 2 +- test/fuzzcheck.c | 55 ++++++++++++++++++++++----------- test/ossfuzz.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 130 insertions(+), 30 deletions(-) create mode 100644 test/ossfuzz.c diff --git a/main.mk b/main.mk index a5a50d205d..51f9b5a6d7 100644 --- a/main.mk +++ b/main.mk @@ -511,10 +511,10 @@ fuzzershell$(EXE): $(TOP)/tool/fuzzershell.c sqlite3.c sqlite3.h $(FUZZERSHELL_OPT) $(TOP)/tool/fuzzershell.c sqlite3.c \ $(TLIBS) $(THREADLIB) -fuzzcheck$(EXE): $(TOP)/test/fuzzcheck.c sqlite3.c sqlite3.h +fuzzcheck$(EXE): $(TOP)/test/fuzzcheck.c sqlite3.c sqlite3.h $(TOP)/test/ossfuzz.c $(TCCX) -o fuzzcheck$(EXE) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \ - -DSQLITE_ENABLE_MEMSYS5 $(FUZZCHECK_OPT) \ - $(TOP)/test/fuzzcheck.c sqlite3.c $(TLIBS) $(THREADLIB) + -DSQLITE_ENABLE_MEMSYS5 $(FUZZCHECK_OPT) -DSQLITE_OSS_FUZZ \ + $(TOP)/test/fuzzcheck.c $(TOP)/test/ossfuzz.c sqlite3.c $(TLIBS) $(THREADLIB) mptester$(EXE): sqlite3.c $(TOP)/mptest/mptest.c $(TCCX) -o $@ -I. $(TOP)/mptest/mptest.c sqlite3.c \ diff --git a/manifest b/manifest index c3e4c15178..1f77db4553 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Handle\ssome\sobscure\s"row\svalue\smisused"\scases\sthat\scould\scause\ssegfaults\sor\nassertion\sfailures. -D 2016-11-11T15:49:01.962 +C Add\sthe\stest/ossfuzz.c\sinterface\sadaptor\sfor\sOSS-FUZZ.\s\sMake\sprevisions\sfor\ntesting\sthe\sadaptor\susing\sfuzzcheck.c. +D 2016-11-11T16:33:47.638 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e0217f2d35a0448abbe4b066132ae20136e8b408 @@ -311,7 +311,7 @@ F ext/userauth/userauth.c 5fa3bdb492f481bbc1709fc83c91ebd13460c69e F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60 -F main.mk 06dc0b1a9c9e2d05c9275937dd5b894bfe7d17d8 +F main.mk 4b5c097e286a7b57023547b674c508f14e51dd9d F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 @@ -814,7 +814,7 @@ F test/fuzz2.test 76dc35b32b6d6f965259508508abce75a6c4d7e1 F test/fuzz3.test b47377143f0c80f91ed29d722861077ff34415d5 F test/fuzz_common.tcl a87dfbb88c2a6b08a38e9a070dabd129e617b45b F test/fuzz_malloc.test 328f70aaca63adf29b4c6f06505ed0cf57ca7c26 -F test/fuzzcheck.c f2e8102f7829f7b946ebdb6f1a16c6f942d9de66 +F test/fuzzcheck.c 984470cee0a35b893ad0377a7de75f0c9a758392 F test/fuzzdata1.db 7ee3227bad0e7ccdeb08a9e6822916777073c664 F test/fuzzdata2.db f03a420d3b822cc82e4f894ca957618fbe9c4973 F test/fuzzdata3.db c6586d3e3cef0fbc18108f9bb649aa77bfc38aba @@ -985,6 +985,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 2d64a0e38ec35fb29c09f8474b64c43605e00ce4 w test/oss-fuzz-adaptor.c F test/ovfl.test 199c482696defceacee8c8e0e0ef36da62726b2f F test/pager1.test 841868017e9dd3cb459b8d78862091a7d9cff21d F test/pager2.test 67b8f40ae98112bcdba1f2b2d03ea83266418c71 @@ -1531,7 +1532,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P f98c8ac8c485098f163400d3a92d6afb4008adbe -R a89e5be61b771e1fa50ceffc5542b881 -U dan -Z 011fdd87018b196e46b8f2521e403dd0 +P fba5fddb1c40af75634b01c1f06d2610df697e01 +R 7bae7291b6277b17f47b074bc7079f96 +U drh +Z 392e6662701d2d132b972967184d58cf diff --git a/manifest.uuid b/manifest.uuid index 1bc728291a..e26aed998f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fba5fddb1c40af75634b01c1f06d2610df697e01 \ No newline at end of file +119d6ef8478ea6ab07dfd0e974d2f5a8dcfce87e \ No newline at end of file diff --git a/test/fuzzcheck.c b/test/fuzzcheck.c index fec65881ce..442bcc6e4d 100644 --- a/test/fuzzcheck.c +++ b/test/fuzzcheck.c @@ -80,6 +80,11 @@ # include #endif +#ifdef SQLITE_OSS_FUZZ +# include +# include +#endif + /* ** Files in the virtual file system. */ @@ -794,6 +799,7 @@ static void showHelp(void){ " --load-db ARGS... Load template databases from files into SOURCE_DB\n" " -m TEXT Add a description to the database\n" " --native-vfs Use the native VFS for initially empty database files\n" +" --oss-fuzz Enable OSS-FUZZ testing\n" " --rebuild Rebuild and vacuum the database file\n" " --result-trace Show the results of each SQL command\n" " --sqlid N Use only SQL where sqlid=N\n" @@ -835,6 +841,7 @@ int main(int argc, char **argv){ char *zExpDb = 0; /* Write Databases to files in this directory */ char *zExpSql = 0; /* Write SQL to files in this directory */ void *pHeap = 0; /* Heap for use by SQLite */ + int ossFuzz = 0; /* enable OSS-FUZZ testing */ iBegin = timeOfDay(); #ifdef __unix__ @@ -895,6 +902,9 @@ int main(int argc, char **argv){ if( strcmp(z,"native-vfs")==0 ){ nativeFlag = 1; }else + if( strcmp(z,"oss-fuzz")==0 ){ + ossFuzz = 1; + }else if( strcmp(z,"quiet")==0 || strcmp(z,"q")==0 ){ quietFlag = 1; verboseFlag = 0; @@ -1123,25 +1133,34 @@ int main(int argc, char **argv){ } } createVFile("main.db", pDb->sz, pDb->a); - openFlags = SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE; - if( nativeFlag && pDb->sz==0 ){ - openFlags |= SQLITE_OPEN_MEMORY; - zVfs = 0; - } - rc = sqlite3_open_v2("main.db", &db, openFlags, zVfs); - if( rc ) fatalError("cannot open inmem database"); - if( cellSzCkFlag ) runSql(db, "PRAGMA cell_size_check=ON", runFlags); - setAlarm(iTimeout); -#ifndef SQLITE_OMIT_PROGRESS_CALLBACK - if( sqlFuzz || vdbeLimitFlag ){ - sqlite3_progress_handler(db, 100000, progressHandler, &vdbeLimitFlag); - } + if( ossFuzz ){ +#ifndef SQLITE_OSS_FUZZ + fatalError("--oss-fuzz not supported: recompile with -DSQLITE_OSS_FUZZ"); +#else + extern int LLVMFuzzerTestOneInput(const uint8_t*, size_t); + LLVMFuzzerTestOneInput((const uint8_t*)pSql->a, (size_t)pSql->sz); #endif - do{ - runSql(db, (char*)pSql->a, runFlags); - }while( timeoutTest ); - setAlarm(0); - sqlite3_close(db); + }else{ + openFlags = SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE; + if( nativeFlag && pDb->sz==0 ){ + openFlags |= SQLITE_OPEN_MEMORY; + zVfs = 0; + } + rc = sqlite3_open_v2("main.db", &db, openFlags, zVfs); + if( rc ) fatalError("cannot open inmem database"); + if( cellSzCkFlag ) runSql(db, "PRAGMA cell_size_check=ON", runFlags); + setAlarm(iTimeout); +#ifndef SQLITE_OMIT_PROGRESS_CALLBACK + if( sqlFuzz || vdbeLimitFlag ){ + sqlite3_progress_handler(db, 100000, progressHandler, &vdbeLimitFlag); + } +#endif + do{ + runSql(db, (char*)pSql->a, runFlags); + }while( timeoutTest ); + setAlarm(0); + sqlite3_close(db); + } if( sqlite3_memory_used()>0 ) fatalError("memory leak"); reformatVfs(); nTest++; diff --git a/test/ossfuzz.c b/test/ossfuzz.c new file mode 100644 index 0000000000..ae07bebc30 --- /dev/null +++ b/test/ossfuzz.c @@ -0,0 +1,80 @@ +/* +** This module interfaces SQLite to the Google OSS-Fuzz, fuzzer as a service. +** (https://github.com/google/oss-fuzz) +*/ +#include +#include +#include "sqlite3.h" + +/* +** Progress handler callback +*/ +static int progress_handler(void *pReturn) { + return *(int*)pReturn; +} + +/* +** Callback for sqlite3_exec(). +*/ +static int exec_handler(void *pCnt, int argc, char **argv, char **namev){ + int i; + for(i=0; i>= 1; + progressArg = uSelector & 1; uSelector >>= 1; + + /* Bit 2 of the selector enables foreign key constraints */ + sqlite3_db_config(db, SQLITE_DBCONFIG_ENABLE_FKEY, uSelector&1, &rc); + uSelector >>= 1; + + /* Remaining bits of the selector determine a limit on the number of + ** output rows */ + execCnt = uSelector + 1; + + /* Run the SQL. The sqlite_exec() interface expects a zero-terminated + ** string, so make a copy. */ + zSql = sqlite3_mprintf("%.*s", (int)size, data); + sqlite3_exec(db, zSql, exec_handler, (void*)&execCnt, &zErrMsg); + + /* Cleanup and return */ + sqlite3_free(zErrMsg); + sqlite3_free(zSql); + sqlite3_close(db); + return 0; +} From 4a5bad572ae669f2c6da3299303840bf3852d5b3 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 11 Nov 2016 17:08:51 +0000 Subject: [PATCH 0985/1484] Fix a problem with switching from wal to rollback mode when SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE is configured. FossilOrigin-Name: 46e0016207b8e7df2ae6c7491fd0f3c2926eed21 --- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- src/pager.c | 5 ++++- src/wal.c | 2 +- test/nockpt.test | 6 ++++++ 5 files changed, 22 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 1f77db4553..fb719999e7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\stest/ossfuzz.c\sinterface\sadaptor\sfor\sOSS-FUZZ.\s\sMake\sprevisions\sfor\ntesting\sthe\sadaptor\susing\sfuzzcheck.c. -D 2016-11-11T16:33:47.638 +C Fix\sa\sproblem\swith\sswitching\sfrom\swal\sto\srollback\smode\swhen\nSQLITE_DBCONFIG_NO_CKPT_ON_CLOSE\sis\sconfigured. +D 2016-11-11T17:08:51.459 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e0217f2d35a0448abbe4b066132ae20136e8b408 @@ -374,7 +374,7 @@ F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586 F src/os_unix.c be9ca0f901a2b6c1bc93dc338f4863675180c189 F src/os_win.c cf90abd4e50d9f56d2c20ce8e005aff55d7bd8e9 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a -F src/pager.c 549ed86833b484fa3cd4799e3289c83b3ace8859 +F src/pager.c a31e2c25563065ebfc9308f2ba3a061901fd60a8 F src/pager.h 07d6938df0b74e4abe8f57807a8b0e1084321d8b F src/parse.y 0338f906b61e311c2b7e11a3f89b0092c780b664 F src/pcache.c 5ff2a08f76a9c1b22f43eb063b7068fb085465ac @@ -465,7 +465,7 @@ F src/vdbesort.c 91fda3909326860382b0ca8aa251e609c6a9d62c F src/vdbetrace.c 41963d5376f0349842b5fc4aaaaacd7d9cdc0834 F src/vtab.c e02cacb5c7ae742631edeb9ae9f53d399f093fd8 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 -F src/wal.c 358ab4d296a12bc9dcb6f8974dd155ba8a9b10c4 +F src/wal.c 7e8557314bcf867ffe3fff1d8ef2d207ace8e065 F src/wal.h bf03a23da3100ab25e5c0363450233cfee09cfc2 F src/walker.c 91a6df7435827e41cff6bb7df50ea00934ee78b0 F src/where.c 952f76e7a03727480b274b66ca6641b1657cd591 @@ -964,7 +964,7 @@ F test/multiplex4.test e8ae4c4bd70606a5727743241f13b5701990abe4 F test/mutex1.test ea2cc74d97f077b9e74c84cbd024f14d79a8126f F test/mutex2.test bfeaeac2e73095b2ac32285d2756e3a65e681660 F test/nan.test dacc57f80859c06a433d30839336fe227d2038b3 -F test/nockpt.test faeeb1daa357d634103fd0a1d54f449e4a5b3ef1 +F test/nockpt.test c65fc1c921d48805dcfca2dca5d1302839a5a1de F test/nolock.test f196cf8b8fbea4e2ca345140a2b3f3b0da45c76e F test/notify1.test 669b2b743618efdc18ca4b02f45423d5d2304abf F test/notify2.test 2ecabaa1305083856b7c39cf32816b612740c161 @@ -985,7 +985,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 2d64a0e38ec35fb29c09f8474b64c43605e00ce4 w test/oss-fuzz-adaptor.c +F test/ossfuzz.c 2d64a0e38ec35fb29c09f8474b64c43605e00ce4 F test/ovfl.test 199c482696defceacee8c8e0e0ef36da62726b2f F test/pager1.test 841868017e9dd3cb459b8d78862091a7d9cff21d F test/pager2.test 67b8f40ae98112bcdba1f2b2d03ea83266418c71 @@ -1532,7 +1532,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P fba5fddb1c40af75634b01c1f06d2610df697e01 -R 7bae7291b6277b17f47b074bc7079f96 -U drh -Z 392e6662701d2d132b972967184d58cf +P 119d6ef8478ea6ab07dfd0e974d2f5a8dcfce87e +R 713cac12bbad56d229ae83741d89e9ae +U dan +Z eb4e3f5ce4749269e2c70de28f3602c7 diff --git a/manifest.uuid b/manifest.uuid index e26aed998f..cdd0440791 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -119d6ef8478ea6ab07dfd0e974d2f5a8dcfce87e \ No newline at end of file +46e0016207b8e7df2ae6c7491fd0f3c2926eed21 \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index 71c4acdb9b..04ce19547b 100644 --- a/src/pager.c +++ b/src/pager.c @@ -4033,7 +4033,10 @@ int sqlite3PagerClose(Pager *pPager, sqlite3 *db){ /* pPager->errCode = 0; */ pPager->exclusiveMode = 0; #ifndef SQLITE_OMIT_WAL - sqlite3WalClose(pPager->pWal,db,pPager->ckptSyncFlags,pPager->pageSize,pTmp); + assert( db || pPager->pWal==0 ); + sqlite3WalClose(pPager->pWal, db, pPager->ckptSyncFlags, pPager->pageSize, + (db && (db->flags & SQLITE_NoCkptOnClose) ? 0 : pTmp) + ); pPager->pWal = 0; #endif pager_reset(pPager); diff --git a/src/wal.c b/src/wal.c index 50b95e4169..d71ee81a51 100644 --- a/src/wal.c +++ b/src/wal.c @@ -1943,7 +1943,7 @@ int sqlite3WalClose( ** ** The EXCLUSIVE lock is not released before returning. */ - if( (db->flags & SQLITE_NoCkptOnClose)==0 + if( zBuf!=0 && SQLITE_OK==(rc = sqlite3OsLock(pWal->pDbFd, SQLITE_LOCK_EXCLUSIVE)) ){ if( pWal->exclusiveMode==WAL_NORMAL_MODE ){ diff --git a/test/nockpt.test b/test/nockpt.test index f24fcaa988..cf350c3e1b 100644 --- a/test/nockpt.test +++ b/test/nockpt.test @@ -51,5 +51,11 @@ do_execsql_test 1.12 { SELECT * FROM c1 } {1 2 3 4 5 6 7 8 9} +do_execsql_test 1.13 { PRAGMA main.journal_mode } {wal} +do_test 1.14 { sqlite3_db_config db NO_CKPT_ON_CLOSE 1 } {1} +do_execsql_test 1.14 { PRAGMA main.journal_mode = delete } {delete} +do_test 1.15 { file exists test.db-wal } {0} + + finish_test From 9af90b7231660b5c5670e41ad58c755d95d0fbaa Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 11 Nov 2016 18:08:59 +0000 Subject: [PATCH 0986/1484] Reenable the SQLITE_EXPR_REF optimization for "SELECT DISTINCT ... ORDER BY" queries. FossilOrigin-Name: 6e2e9d383f5fc4a0cbf05fe83ec7425812c0f556 --- manifest | 15 ++++++--------- manifest.uuid | 2 +- src/select.c | 28 ++++++++++++++++++---------- 3 files changed, 25 insertions(+), 20 deletions(-) diff --git a/manifest b/manifest index 089494dd59..fb20daadba 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sstoring\sredundant\sfields\sin\ssorter\srecords\swhen\sthe\ssort-key\sand\sdata\shave\nfields\sin\scommon\s(as\sin\s"SELECT\sa\sFROM\st1\sORDER\sBY\s1"). -D 2016-11-10T20:14:06.787 +C Reenable\sthe\sSQLITE_EXPR_REF\soptimization\sfor\s"SELECT\sDISTINCT\s...\sORDER\sBY"\nqueries. +D 2016-11-11T18:08:59.063 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e0217f2d35a0448abbe4b066132ae20136e8b408 @@ -387,7 +387,7 @@ F src/printf.c a5f0ca08ddede803c241266abb46356ec748ded1 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c 3fac1b2737ea5a724f20b921ac7e259c9be2100b F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac -F src/select.c 64b2273747c6485638bfeb6790e3e774e0605d02 +F src/select.c 04fd717fb99aea2110b752e2b6186b966fa13cb4 F src/shell.c 63e54cfa1c7ec5b70a4c9a86502bc10280c3d5a3 F src/sqlite.h.in 803f7050f69b2eea573fac219f3c92582c096027 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1530,10 +1530,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b4889588246c33374ff3758e21ccc4ce246380b6 -R e8a5368c67459f65dc206ad3df15a284 -T *branch * sorter-opt -T *sym-sorter-opt * -T -sym-trunk * +P 0af62fdbd8e2aab14718ff8bcb5934f05463c176 +R dccdf5cb21f8816d64d778a9f6efd1e8 U dan -Z 220ba0a8da96dcdf18555b62136e6fa1 +Z 74767a1cb4eda88af63e605e54888e92 diff --git a/manifest.uuid b/manifest.uuid index 2523f32ffc..ee5ae85add 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0af62fdbd8e2aab14718ff8bcb5934f05463c176 \ No newline at end of file +6e2e9d383f5fc4a0cbf05fe83ec7425812c0f556 \ No newline at end of file diff --git a/src/select.c b/src/select.c index 003d42e728..b8ed890b3f 100644 --- a/src/select.c +++ b/src/select.c @@ -521,7 +521,7 @@ static void pushOntoSorter( int iLimit; /* LIMIT counter */ assert( bSeq==0 || bSeq==1 ); - assert( nData==1 || regData==regOrigData ); + assert( nData==1 || regData==regOrigData || regOrigData==0 ); if( nPrefixReg ){ assert( nPrefixReg==nExpr+bSeq ); regBase = regData - nExpr - bSeq; @@ -533,7 +533,7 @@ static void pushOntoSorter( iLimit = pSelect->iOffset ? pSelect->iOffset+1 : pSelect->iLimit; pSort->labelDone = sqlite3VdbeMakeLabel(v); sqlite3ExprCodeExprList(pParse, pSort->pOrderBy, regBase, regOrigData, - SQLITE_ECEL_DUP); + SQLITE_ECEL_DUP | (regOrigData? SQLITE_ECEL_REF : 0)); if( bSeq ){ sqlite3VdbeAddOp2(v, OP_Sequence, pSort->iECursor, regBase+nExpr); } @@ -681,13 +681,20 @@ static void selectInnerLoop( ){ Vdbe *v = pParse->pVdbe; int i; - int hasDistinct; /* True if the DISTINCT keyword is present */ - int regResult; /* Start of memory holding result set */ + int hasDistinct; /* True if the DISTINCT keyword is present */ int eDest = pDest->eDest; /* How to dispose of results */ int iParm = pDest->iSDParm; /* First argument to disposal method */ int nResultCol; /* Number of result columns */ int nPrefixReg = 0; /* Number of extra registers before regResult */ + /* Usually, regResult is the first cell in an array of memory cells + ** containing the current result row. In this case regOrig is set to the + ** same value. However, if the results are being sent to the sorter, the + ** values for any expressions that are also part of the sort-key are omitted + ** from this array. In this case regOrig is set to zero. */ + int regResult; /* Start of memory holding current results */ + int regOrig; /* Start of memory holding full result (or 0) */ + assert( v ); assert( pEList!=0 ); hasDistinct = pDistinct ? pDistinct->eTnctType : WHERE_DISTINCT_NOOP; @@ -718,7 +725,7 @@ static void selectInnerLoop( pParse->nMem += nResultCol; } pDest->nSdst = nResultCol; - regResult = pDest->iSdst; + regOrig = regResult = pDest->iSdst; if( srcTab>=0 ){ for(i=0; ipOrderBy), set the associated ** iOrderByCol value to one more than the index of the ORDER BY @@ -748,7 +756,7 @@ static void selectInnerLoop( pEList->a[j-1].u.x.iOrderByCol = i+1-pSort->nOBSat; } } - + regOrig = 0; assert( eDest==SRT_Set || eDest==SRT_Mem || eDest==SRT_Coroutine || eDest==SRT_Output ); } @@ -892,7 +900,7 @@ static void selectInnerLoop( ** does not matter. But there might be a LIMIT clause, in which ** case the order does matter */ pushOntoSorter( - pParse, pSort, p, regResult, regResult, nResultCol, nPrefixReg); + pParse, pSort, p, regResult, regOrig, nResultCol, nPrefixReg); }else{ int r1 = sqlite3GetTempReg(pParse); assert( sqlite3Strlen30(pDest->zAffSdst)==nResultCol ); @@ -921,7 +929,7 @@ static void selectInnerLoop( if( pSort ){ assert( nResultCol<=pDest->nSdst ); pushOntoSorter( - pParse, pSort, p, regResult, regResult, nResultCol, nPrefixReg); + pParse, pSort, p, regResult, regOrig, nResultCol, nPrefixReg); }else{ assert( nResultCol==pDest->nSdst ); assert( regResult==iParm ); @@ -936,7 +944,7 @@ static void selectInnerLoop( testcase( eDest==SRT_Coroutine ); testcase( eDest==SRT_Output ); if( pSort ){ - pushOntoSorter(pParse, pSort, p, regResult, regResult, nResultCol, + pushOntoSorter(pParse, pSort, p, regResult, regOrig, nResultCol, nPrefixReg); }else if( eDest==SRT_Coroutine ){ sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm); From d95ef5cb5a6ef94211463d18e22259bcc48d7266 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 11 Nov 2016 18:19:05 +0000 Subject: [PATCH 0987/1484] Remove obselete and unused logic in the update code generator. Fix the sqlite3BtreeMovetoUnpacked() routine so that it remembers the rowid of the row that it landed on. FossilOrigin-Name: 1a587d72f981cb7064cfd8916a52a83ad9ba6074 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/btree.c | 12 ++++++------ src/insert.c | 3 --- 4 files changed, 14 insertions(+), 17 deletions(-) diff --git a/manifest b/manifest index fc888c5656..cca6f193f0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\senhancements\sand\sbug-fixes\sfrom\strunk. -D 2016-11-11T17:52:57.982 +C Remove\sobselete\sand\sunused\slogic\sin\sthe\supdate\scode\sgenerator.\nFix\sthe\ssqlite3BtreeMovetoUnpacked()\sroutine\sso\sthat\sit\sremembers\sthe\nrowid\sof\sthe\srow\sthat\sit\slanded\son. +D 2016-11-11T18:19:05.491 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e0217f2d35a0448abbe4b066132ae20136e8b408 @@ -330,7 +330,7 @@ F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792 F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b F src/bitvec.c 3ee4c8b2c94ed3a7377256e18199e6ff5cf33f63 F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 -F src/btree.c 592a72c259752b3cae6928e3f2448a2cb540b032 +F src/btree.c cfe038d1844420caddfa0238d52b7b2102dda98b F src/btree.h 630303068c82a359f6ddf202b205ae927721b090 F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 F src/build.c 178f16698cbcb43402c343a9413fe22c99ffee21 @@ -349,7 +349,7 @@ F src/hash.c 63d0ee752a3b92d4695b2b1f5259c4621b2cfebd F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4 F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 -F src/insert.c 40c64f0ad405d491127ac13ef450a1b44b076e2f +F src/insert.c 0db6364a6a64e521281d6f443b1669a5a16bdbd6 F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e F src/loadext.c 5d6642d141c07d366e43d359e94ec9de47add41d F src/main.c 694ac90557abdaa62151a6090670e107b0f2c2ab @@ -1532,7 +1532,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P eac0e827a61cfec4dd9b6d407ff398e9fda3510b 46e0016207b8e7df2ae6c7491fd0f3c2926eed21 -R 702d892ba95768248d8c7e81d0fa0aa8 +P 5515b827dc1805a3010018cd6abf222b03525d24 +R d4149095f37aacb5dfcbf6f677226eee U drh -Z 50432314c566096bfb1a843cbbc042aa +Z dccbc7ad9f33eb000a7232f3de148136 diff --git a/manifest.uuid b/manifest.uuid index 94b93d5a27..273415e51b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5515b827dc1805a3010018cd6abf222b03525d24 \ No newline at end of file +1a587d72f981cb7064cfd8916a52a83ad9ba6074 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 78c4677d25..283f37b797 100644 --- a/src/btree.c +++ b/src/btree.c @@ -5165,16 +5165,16 @@ int sqlite3BtreeMovetoUnpacked( if( lwr>upr ){ c = +1; break; } }else{ assert( nCellKey==intKey ); - pCur->curFlags |= BTCF_ValidNKey; - pCur->info.nKey = nCellKey; pCur->aiIdx[pCur->iPage] = (u16)idx; if( !pPage->leaf ){ lwr = idx; goto moveto_next_layer; }else{ + pCur->curFlags |= BTCF_ValidNKey; + pCur->info.nKey = nCellKey; + pCur->info.nSize = 0; *pRes = 0; - rc = SQLITE_OK; - goto moveto_finish; + return SQLITE_OK; } } assert( lwr+upr>=0 ); @@ -5285,7 +5285,7 @@ moveto_next_layer: } moveto_finish: pCur->info.nSize = 0; - pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl); + assert( (pCur->curFlags & BTCF_ValidOvfl)==0 ); return rc; } @@ -5483,7 +5483,7 @@ static SQLITE_NOINLINE int btreePrevious(BtCursor *pCur, int *pRes){ moveToParent(pCur); } assert( pCur->info.nSize==0 ); - assert( (pCur->curFlags & (BTCF_ValidNKey|BTCF_ValidOvfl))==0 ); + assert( (pCur->curFlags & (BTCF_ValidOvfl))==0 ); pCur->aiIdx[pCur->iPage]--; pPage = pCur->apPage[pCur->iPage]; diff --git a/src/insert.c b/src/insert.c index a5852fd327..59bc99b523 100644 --- a/src/insert.c +++ b/src/insert.c @@ -1260,7 +1260,6 @@ void sqlite3GenerateConstraintChecks( int ipkBottom = 0; /* Bottom of the rowid change constraint check */ u8 isUpdate; /* True if this is an UPDATE operation */ u8 bAffinityDone = 0; /* True if the OP_Affinity operation has been run */ - int regRowid = -1; /* Register holding ROWID value */ isUpdate = regOldData!=0; db = pParse->db; @@ -1526,9 +1525,7 @@ void sqlite3GenerateConstraintChecks( VdbeComment((v, "%s column %d", pIdx->zName, i)); }else{ if( iField==XN_ROWID || iField==pTab->iPKey ){ - if( regRowid==regIdx+i ) continue; /* ROWID already in regIdx+i */ x = regNewData; - regRowid = pIdx->pPartIdxWhere ? -1 : regIdx+i; }else{ x = iField + regNewData + 1; } From b3e845ba331c963a5eb9d0e8970284ba7d0f85ec Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 14 Nov 2016 08:19:37 +0000 Subject: [PATCH 0988/1484] Fix an fts5 problem causing a crash in phrase queries where the first token of the phrase matches one or more rows but some other token within the phrase matches zero. FossilOrigin-Name: e78f6f3bbf4781850960fe6741f7cba480f2c27d --- ext/fts5/fts5_expr.c | 2 +- ext/fts5/fts5_index.c | 1 + ext/fts5/test/fts5simple3.test | 34 ++++++++++++++++++++++++++++++++++ manifest | 18 +++++++++--------- manifest.uuid | 2 +- 5 files changed, 46 insertions(+), 11 deletions(-) diff --git a/ext/fts5/fts5_expr.c b/ext/fts5/fts5_expr.c index ac3913d4e3..bde9eaed8b 100644 --- a/ext/fts5/fts5_expr.c +++ b/ext/fts5/fts5_expr.c @@ -920,7 +920,7 @@ static int fts5ExprNodeTest_STRING( } }else{ Fts5IndexIter *pIter = pPhrase->aTerm[j].pIter; - if( pIter->iRowid==iLast ) continue; + if( pIter->iRowid==iLast || pIter->bEof ) continue; bMatch = 0; if( fts5ExprAdvanceto(pIter, bDesc, &iLast, &rc, &pNode->bEof) ){ return rc; diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index ef36e007df..46517e1aeb 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -2840,6 +2840,7 @@ static void fts5MultiIterNext( i64 iFrom /* Advance at least as far as this */ ){ int bUseFrom = bFrom; + assert( pIter->base.bEof==0 ); while( p->rc==SQLITE_OK ){ int iFirst = pIter->aFirst[1].iFirst; int bNewTerm = 0; diff --git a/ext/fts5/test/fts5simple3.test b/ext/fts5/test/fts5simple3.test index b6922f84dd..c755ea0567 100644 --- a/ext/fts5/test/fts5simple3.test +++ b/ext/fts5/test/fts5simple3.test @@ -80,6 +80,40 @@ do_execsql_test 3.0 { SELECT * FROM x3('x OR y OR z'); } +#------------------------------------------------------------------------- +# Test that a crash occuring when the second or subsequent tokens in a +# phrase matched zero rows has been fixed. +# +do_execsql_test 4.0 { + CREATE VIRTUAL TABLE t1 USING fts5(x); + INSERT INTO t1 VALUES('ab'); + INSERT INTO t1 VALUES('cd'); + INSERT INTO t1 VALUES('ab cd'); + INSERT INTO t1 VALUES('ab cdXXX'); + INSERT INTO t1 VALUES('abXXX cd'); +} +do_execsql_test 4.1 { + SELECT * FROM t1('"ab cd" OR "ab cd" *'); +} {{ab cd} {ab cdXXX}} +do_execsql_test 4.2 { + SELECT * FROM t1('"xy zz" OR "ab cd" *'); +} {{ab cd} {ab cdXXX}} +do_execsql_test 4.3 { + SELECT * FROM t1('"xy zz" OR "xy zz" *'); +} +do_execsql_test 4.4 { + SELECT * FROM t1('"ab cd" OR "xy zz" *'); +} {{ab cd}} +do_execsql_test 4.5 { + CREATE VIRTUAL TABLE t2 USING fts5(x); + INSERT INTO t2 VALUES('ab'); + INSERT INTO t2 VALUES('cd'); + INSERT INTO t2 VALUES('ef'); +} +do_execsql_test 4.6 { + SELECT * FROM t2('ab + xyz'); +} + finish_test diff --git a/manifest b/manifest index a05d8400b0..1197cac4d9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\scompiler\swarnings\sin\stest\scode\sfor\sMSVC. -D 2016-11-11T20:37:27.949 +C Fix\san\sfts5\sproblem\scausing\sa\scrash\sin\sphrase\squeries\swhere\sthe\sfirst\stoken\sof\nthe\sphrase\smatches\sone\sor\smore\srows\sbut\ssome\sother\stoken\swithin\sthe\sphrase\nmatches\szero. +D 2016-11-14T08:19:37.487 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e0217f2d35a0448abbe4b066132ae20136e8b408 @@ -102,9 +102,9 @@ F ext/fts5/fts5Int.h b2eda36e0f224365c8e23dc8f559311834f1c13f F ext/fts5/fts5_aux.c 67acf8d51723cf28ffc3828210ba662df4b8d267 F ext/fts5/fts5_buffer.c 4c1502d4c956cd092c89ce4480867f9d8bf325cd F ext/fts5/fts5_config.c 5af9c360e99669d29f06492c370892394aba0857 -F ext/fts5/fts5_expr.c c65c5629f4b3a49850fd84ea0731dee2360e144f +F ext/fts5/fts5_expr.c e12421946774482f4d49e334c974571177adbc70 F ext/fts5/fts5_hash.c 880998e596b60f078348d48732ca4ad9a90caad2 -F ext/fts5/fts5_index.c 2d146d5c547f60d22d6fc4014d5e2b64248cd7c4 +F ext/fts5/fts5_index.c fdbe46da11e81c1817cd4cb2de25ffdb4dd83711 F ext/fts5/fts5_main.c f85281445dcf8be32d18841c93a6f90fe27dbfe2 F ext/fts5/fts5_storage.c de0ed8a06738bde433afe11e92295ceaffbc4e58 F ext/fts5/fts5_tcl.c 4a901f00c8553740dba63511603f5527d741c26a @@ -183,7 +183,7 @@ F ext/fts5/test/fts5restart.test c17728fdea26e7d0f617d22ad5b4b2862b994c17 F ext/fts5/test/fts5rowid.test 16908a99d6efc9ba21081b4f2b86b3fc699839a6 F ext/fts5/test/fts5simple.test 5da9b15ed534eb0be9f279d8a2bb2e24d30e4e38 F ext/fts5/test/fts5simple2.test 98377ae1ff7749a42c21fe1a139c1ed312522c46 -F ext/fts5/test/fts5simple3.test 8e71733b3d1b0e695011d02c68ebc5ca40b6124e +F ext/fts5/test/fts5simple3.test 25faa8cb8ad470c6f01f670bcc1317c19a89f091 F ext/fts5/test/fts5synonym.test 6475d189c2e20d60795808f83e36bf9318708d48 F ext/fts5/test/fts5synonym2.test aa4c43bd3b691ff80f658cb064f5ab40690e834e F ext/fts5/test/fts5tok1.test beb894c6f3468f10a574302f69ebe4436b0287c7 @@ -1532,7 +1532,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b835cf3e507b910b6a3e0f802ce2c40a72d0c227 1a587d72f981cb7064cfd8916a52a83ad9ba6074 -R 306c4a48ed6a27b97773f1003470ed23 -U drh -Z d9323491e79664d0c5f2710508245de6 +P 7b76be4117f4e57091b03fafcf42d17bce81160d +R d4b78ee7bcfd8ac12430ee90cda2abbd +U dan +Z 698063c6adfdd3558a22de16ea6a2897 diff --git a/manifest.uuid b/manifest.uuid index c724c9d945..0e13fa6520 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7b76be4117f4e57091b03fafcf42d17bce81160d \ No newline at end of file +e78f6f3bbf4781850960fe6741f7cba480f2c27d \ No newline at end of file From 2adb878b1fb7d02c4c247889dbd98c8bfbb96c49 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 14 Nov 2016 15:28:56 +0000 Subject: [PATCH 0989/1484] Avoid unnecessary calls to sqlite3ExprCacheAffinityChange() when generating OP_MakeRecord opcodes that do not change any register affinities. FossilOrigin-Name: e211c579b2f092e3283edd5fb9add7c5183bac35 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/insert.c | 7 ++++--- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 1197cac4d9..74f95efa42 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\sfts5\sproblem\scausing\sa\scrash\sin\sphrase\squeries\swhere\sthe\sfirst\stoken\sof\nthe\sphrase\smatches\sone\sor\smore\srows\sbut\ssome\sother\stoken\swithin\sthe\sphrase\nmatches\szero. -D 2016-11-14T08:19:37.487 +C Avoid\sunnecessary\scalls\sto\ssqlite3ExprCacheAffinityChange()\swhen\sgenerating\nOP_MakeRecord\sopcodes\sthat\sdo\snot\schange\sany\sregister\saffinities. +D 2016-11-14T15:28:56.925 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e0217f2d35a0448abbe4b066132ae20136e8b408 @@ -349,7 +349,7 @@ F src/hash.c 63d0ee752a3b92d4695b2b1f5259c4621b2cfebd F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4 F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 -F src/insert.c 0db6364a6a64e521281d6f443b1669a5a16bdbd6 +F src/insert.c d47f9b4f6b7137b886525f735628fed4ff181ea2 F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e F src/loadext.c 5d6642d141c07d366e43d359e94ec9de47add41d F src/main.c 694ac90557abdaa62151a6090670e107b0f2c2ab @@ -1532,7 +1532,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 7b76be4117f4e57091b03fafcf42d17bce81160d -R d4b78ee7bcfd8ac12430ee90cda2abbd -U dan -Z 698063c6adfdd3558a22de16ea6a2897 +P e78f6f3bbf4781850960fe6741f7cba480f2c27d +R 3fa0a5681db4ad4cdeeecb208061d048 +U drh +Z 63d0e6fa2d7d17a48902a7d1e28254c8 diff --git a/manifest.uuid b/manifest.uuid index 0e13fa6520..3c3f4d160e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e78f6f3bbf4781850960fe6741f7cba480f2c27d \ No newline at end of file +e211c579b2f092e3283edd5fb9add7c5183bac35 \ No newline at end of file diff --git a/src/insert.c b/src/insert.c index 59bc99b523..151c7d746b 100644 --- a/src/insert.c +++ b/src/insert.c @@ -1535,7 +1535,6 @@ void sqlite3GenerateConstraintChecks( } sqlite3VdbeAddOp3(v, OP_MakeRecord, regIdx, pIdx->nColumn, aRegIdx[ix]); VdbeComment((v, "for %s", pIdx->zName)); - sqlite3ExprCacheAffinityChange(pParse, regIdx, pIdx->nColumn); /* In an UPDATE operation, if this index is the PRIMARY KEY index ** of a WITHOUT ROWID table and there has been no change the @@ -1717,8 +1716,10 @@ void sqlite3CompleteInsertion( regData = regNewData + 1; regRec = sqlite3GetTempReg(pParse); sqlite3VdbeAddOp3(v, OP_MakeRecord, regData, pTab->nCol, regRec); - if( !bAffinityDone ) sqlite3TableAffinity(v, pTab, 0); - sqlite3ExprCacheAffinityChange(pParse, regData, pTab->nCol); + if( !bAffinityDone ){ + sqlite3TableAffinity(v, pTab, 0); + sqlite3ExprCacheAffinityChange(pParse, regData, pTab->nCol); + } if( pParse->nested ){ pik_flags = 0; }else{ From 55377b47174f456fc6bb93e1096435a0071d4ea1 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 14 Nov 2016 17:25:57 +0000 Subject: [PATCH 0990/1484] Fix the ossfuzz.c test module so that it does not segfault after a "PRAGMA empty_result_callbacks=1;". Add the ossshell.c program for simple command-line testing of ossfuzz.c. FossilOrigin-Name: 6f2d43eca68175ed28abae3afa792095af906af2 --- main.mk | 5 ++++ manifest | 17 +++++++------ manifest.uuid | 2 +- test/ossfuzz.c | 4 ++- test/ossshell.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++ tool/fuzzershell.c | 14 ++++++----- 6 files changed, 87 insertions(+), 16 deletions(-) create mode 100644 test/ossshell.c diff --git a/main.mk b/main.mk index 51f9b5a6d7..221a568d69 100644 --- a/main.mk +++ b/main.mk @@ -516,6 +516,11 @@ fuzzcheck$(EXE): $(TOP)/test/fuzzcheck.c sqlite3.c sqlite3.h $(TOP)/test/ossfuzz -DSQLITE_ENABLE_MEMSYS5 $(FUZZCHECK_OPT) -DSQLITE_OSS_FUZZ \ $(TOP)/test/fuzzcheck.c $(TOP)/test/ossfuzz.c sqlite3.c $(TLIBS) $(THREADLIB) +ossshell$(EXE): $(TOP)/test/ossfuzz.c $(TOP)/test/ossshell.c sqlite3.c sqlite3.h + $(TCCX) -o ossshell$(EXE) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \ + -DSQLITE_ENABLE_MEMSYS5 $(FUZZCHECK_OPT) \ + $(TOP)/test/ossfuzz.c $(TOP)/test/ossshell.c sqlite3.c $(TLIBS) $(THREADLIB) + mptester$(EXE): sqlite3.c $(TOP)/mptest/mptest.c $(TCCX) -o $@ -I. $(TOP)/mptest/mptest.c sqlite3.c \ $(TLIBS) $(THREADLIB) diff --git a/manifest b/manifest index 74f95efa42..864dc77eed 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sunnecessary\scalls\sto\ssqlite3ExprCacheAffinityChange()\swhen\sgenerating\nOP_MakeRecord\sopcodes\sthat\sdo\snot\schange\sany\sregister\saffinities. -D 2016-11-14T15:28:56.925 +C Fix\sthe\sossfuzz.c\stest\smodule\sso\sthat\sit\sdoes\snot\ssegfault\safter\sa\n"PRAGMA\sempty_result_callbacks=1;".\s\sAdd\sthe\sossshell.c\sprogram\sfor\nsimple\scommand-line\stesting\sof\sossfuzz.c. +D 2016-11-14T17:25:57.150 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e0217f2d35a0448abbe4b066132ae20136e8b408 @@ -311,7 +311,7 @@ F ext/userauth/userauth.c 5fa3bdb492f481bbc1709fc83c91ebd13460c69e F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60 -F main.mk 4b5c097e286a7b57023547b674c508f14e51dd9d +F main.mk ec15a47504f15b84390d84a376a91397b77d5e15 F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 @@ -985,7 +985,8 @@ F test/orderby7.test 3d1383d52ade5b9eb3a173b3147fdd296f0202da F test/orderby8.test 23ef1a5d72bd3adcc2f65561c654295d1b8047bd F test/orderby9.test 87fb9548debcc2cd141c5299002dd94672fa76a3 F test/oserror.test b32dc34f2363ef18532e3a0a7358e3e7e321974f -F test/ossfuzz.c 2d64a0e38ec35fb29c09f8474b64c43605e00ce4 +F test/ossfuzz.c ad79e867fb504338d324b08e0696db65a0c44d68 +F test/ossshell.c d9f1a6f43e7bab45d6be857a5800f5d4a1861db3 F test/ovfl.test 199c482696defceacee8c8e0e0ef36da62726b2f F test/pager1.test 841868017e9dd3cb459b8d78862091a7d9cff21d F test/pager2.test 67b8f40ae98112bcdba1f2b2d03ea83266418c71 @@ -1455,7 +1456,7 @@ F tool/dbhash.c a06228aa21ebc4e6ea8daa486601d938499238a5 F tool/extract.c 054069d81b095fbdc189a6f5d4466e40380505e2 F tool/fast_vacuum.c 5ba0d6f5963a0a63bdc42840f678bad75b2ebce1 F tool/fragck.tcl 5265a95126abcf6ab357f7efa544787e5963f439 -F tool/fuzzershell.c f294ca67a10e87db76af130d75b2c94be36359c6 +F tool/fuzzershell.c d5c870a07452caa5c70a8e49d6c64e403558686d F tool/genfkey.README cf68fddd4643bbe3ff8e31b8b6d8b0a1b85e20f4 F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5 F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce @@ -1532,7 +1533,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e78f6f3bbf4781850960fe6741f7cba480f2c27d -R 3fa0a5681db4ad4cdeeecb208061d048 +P e211c579b2f092e3283edd5fb9add7c5183bac35 +R f5446ee1d5f38bf5dd192848e11b9c1d U drh -Z 63d0e6fa2d7d17a48902a7d1e28254c8 +Z e378b2bf2d2ef2294a0668dccb47568a diff --git a/manifest.uuid b/manifest.uuid index 3c3f4d160e..08d6ed2463 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e211c579b2f092e3283edd5fb9add7c5183bac35 \ No newline at end of file +6f2d43eca68175ed28abae3afa792095af906af2 \ No newline at end of file diff --git a/test/ossfuzz.c b/test/ossfuzz.c index ae07bebc30..4bf0eb5e41 100644 --- a/test/ossfuzz.c +++ b/test/ossfuzz.c @@ -18,7 +18,9 @@ static int progress_handler(void *pReturn) { */ static int exec_handler(void *pCnt, int argc, char **argv, char **namev){ int i; - for(i=0; i +#include +#include +#include +#include "sqlite3.h" + +/* +** The entry point in ossfuzz.c that this routine will be calling +*/ +int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size); + + +/* +** Read files named on the command-line and invoke the fuzzer for +** each one. +*/ +int main(int argc, char **argv){ + FILE *in; + int i; + int nErr = 0; + uint8_t *zBuf = 0; + size_t sz; + + for(i=1; i Date: Mon, 14 Nov 2016 18:27:41 +0000 Subject: [PATCH 0991/1484] Enhance fuzzcheck.c to accept database-specific configuration parameters in the option CONFIG table. Add the fuzzdata5.db fuzz database containing test cases from OSS-FUZZ. FossilOrigin-Name: a71fad4538311ede111815d221d9eb8d9018092b --- Makefile.in | 14 ++++++++++---- Makefile.msc | 14 ++++++++++---- main.mk | 3 ++- manifest | 19 ++++++++++--------- manifest.uuid | 2 +- test/fuzzcheck.c | 38 ++++++++++++++++++++++++++++++++++---- test/fuzzdata5.db | Bin 0 -> 8192 bytes 7 files changed, 67 insertions(+), 23 deletions(-) create mode 100644 test/fuzzdata5.db diff --git a/Makefile.in b/Makefile.in index bb1f14b6ab..8f2c910a24 100644 --- a/Makefile.in +++ b/Makefile.in @@ -550,7 +550,8 @@ FUZZDATA = \ $(TOP)/test/fuzzdata1.db \ $(TOP)/test/fuzzdata2.db \ $(TOP)/test/fuzzdata3.db \ - $(TOP)/test/fuzzdata4.db + $(TOP)/test/fuzzdata4.db \ + $(TOP)/test/fuzzdata5.db # Standard options to testfixture # @@ -563,7 +564,8 @@ SHELL_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS4 SHELL_OPT += -DSQLITE_ENABLE_EXPLAIN_COMMENTS SHELL_OPT += -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1 -FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 +FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_OSS_FUZZ +FUZZCHECK_SRC = $(TOP)/test/fuzzcheck.c $(TOP)/test/ossfuzz.c # This is the default Makefile target. The objects listed here # are what get build when you type just "make" with no arguments. @@ -612,8 +614,11 @@ fuzzershell$(TEXE): $(TOP)/tool/fuzzershell.c sqlite3.c sqlite3.h $(LTLINK) -o $@ $(FUZZERSHELL_OPT) \ $(TOP)/tool/fuzzershell.c sqlite3.c $(TLIBS) -fuzzcheck$(TEXE): $(TOP)/test/fuzzcheck.c sqlite3.c sqlite3.h - $(LTLINK) -o $@ $(FUZZCHECK_OPT) $(TOP)/test/fuzzcheck.c sqlite3.c $(TLIBS) +fuzzcheck$(TEXE): $(FUZZCHECK_SRC) sqlite3.c sqlite3.h + $(LTLINK) -o $@ $(FUZZCHECK_OPT) $(FUZZCHECK_SRC) sqlite3.c $(TLIBS) + +ossshell$(TEXE): $(TOP)/test/ossfuzz.c $(TOP)/test/ossshell.c sqlite3.c sqlite3.h + $(LTLINK) -o $@ $(FUZZCHECK_OPT) $(TOP)/test/ossshell.c sqlite3.c sqlite3.h $(TLIBS) mptester$(TEXE): sqlite3.lo $(TOP)/mptest/mptest.c $(LTLINK) -o $@ -I. $(TOP)/mptest/mptest.c sqlite3.lo \ @@ -1103,6 +1108,7 @@ fastfuzztest: fuzzcheck$(TEXE) $(FUZZDATA) valgrindfuzz: fuzzcheck$(TEXT) $(FUZZDATA) valgrind ./fuzzcheck$(TEXE) --cell-size-check --limit-mem 10M --timeout 600 $(FUZZDATA) + # Minimal testing that runs in less than 3 minutes # quicktest: ./testfixture$(TEXE) diff --git a/Makefile.msc b/Makefile.msc index 0d42d41aa8..097b49f5ec 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -1479,7 +1479,8 @@ FUZZDATA = \ $(TOP)\test\fuzzdata1.db \ $(TOP)\test\fuzzdata2.db \ $(TOP)\test\fuzzdata3.db \ - $(TOP)\test\fuzzdata4.db + $(TOP)\test\fuzzdata4.db \ + $(TOP)\test\fuzzdata5.db # <> # Additional compiler options for the shell. These are only effective @@ -1494,7 +1495,9 @@ SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_SHELL_JSON1 -DSQLITE_ENABLE_ # MPTESTER_COMPILE_OPTS = -DSQLITE_SHELL_JSON1 -DSQLITE_ENABLE_FTS5 FUZZERSHELL_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1 -FUZZCHECK_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 +FUZZCHECK_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_OSS_FUZZ +FUZZCHECK_SRC = $(TOP)\test\fuzzcheck.c $(TOP)\test\ossfuzz.c +OSSSHELL_SRC = $(TOP)\test\ossshell.c $(TOP)\test\ossfuzz.c # Standard options to testfixture. # @@ -1564,8 +1567,11 @@ sourcetest: srcck1.exe sqlite3.c fuzzershell.exe: $(TOP)\tool\fuzzershell.c $(SQLITE3C) $(SQLITE3H) $(LTLINK) $(NO_WARN) $(FUZZERSHELL_COMPILE_OPTS) $(TOP)\tool\fuzzershell.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) -fuzzcheck.exe: $(TOP)\test\fuzzcheck.c $(SQLITE3C) $(SQLITE3H) - $(LTLINK) $(NO_WARN) $(FUZZCHECK_COMPILE_OPTS) $(TOP)\test\fuzzcheck.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) +fuzzcheck.exe: $(FUZZCHECK_SRC) $(SQLITE3C) $(SQLITE3H) + $(LTLINK) $(NO_WARN) $(FUZZCHECK_COMPILE_OPTS) $(FUZZCHECK_SRC) $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) + +ossshell.exe: $(OSSSHELL_SRC) $(SQLITE3C) $(SQLITE3H) + $(LTLINK) $(NO_WARN) $(FUZZCHECK_COMPILE_OPTS) $(OSSSHELL_SRC) $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) mptester.exe: $(TOP)\mptest\mptest.c $(SQLITE3C) $(SQLITE3H) $(LTLINK) $(NO_WARN) $(MPTESTER_COMPILE_OPTS) $(TOP)\mptest\mptest.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) diff --git a/main.mk b/main.mk index 221a568d69..38eb1753af 100644 --- a/main.mk +++ b/main.mk @@ -462,7 +462,8 @@ FUZZDATA = \ $(TOP)/test/fuzzdata1.db \ $(TOP)/test/fuzzdata2.db \ $(TOP)/test/fuzzdata3.db \ - $(TOP)/test/fuzzdata4.db + $(TOP)/test/fuzzdata4.db \ + $(TOP)/test/fuzzdata5.db # Standard options to testfixture # diff --git a/manifest b/manifest index 864dc77eed..eeb7bbca0b 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -C Fix\sthe\sossfuzz.c\stest\smodule\sso\sthat\sit\sdoes\snot\ssegfault\safter\sa\n"PRAGMA\sempty_result_callbacks=1;".\s\sAdd\sthe\sossshell.c\sprogram\sfor\nsimple\scommand-line\stesting\sof\sossfuzz.c. -D 2016-11-14T17:25:57.150 -F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678 +C Enhance\sfuzzcheck.c\sto\saccept\sdatabase-specific\sconfiguration\sparameters\sin\nthe\soption\sCONFIG\stable.\s\sAdd\sthe\sfuzzdata5.db\sfuzz\sdatabase\scontaining\ntest\scases\sfrom\sOSS-FUZZ. +D 2016-11-14T18:27:41.319 +F Makefile.in 6b572807415d3f0a379cebc9461416d8df4a12c8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 -F Makefile.msc e0217f2d35a0448abbe4b066132ae20136e8b408 +F Makefile.msc bb4d970894abbbe0e88d00aac29bd52af8bc95f4 F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7 F VERSION 661b3e6a778cfbfd7bdce8bbb1545b22f4b6f09e F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 @@ -311,7 +311,7 @@ F ext/userauth/userauth.c 5fa3bdb492f481bbc1709fc83c91ebd13460c69e F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60 -F main.mk ec15a47504f15b84390d84a376a91397b77d5e15 +F main.mk 488af8651f927e27f9256e2f20daf63163b2d2eb F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 @@ -814,11 +814,12 @@ F test/fuzz2.test 76dc35b32b6d6f965259508508abce75a6c4d7e1 F test/fuzz3.test b47377143f0c80f91ed29d722861077ff34415d5 F test/fuzz_common.tcl a87dfbb88c2a6b08a38e9a070dabd129e617b45b F test/fuzz_malloc.test 328f70aaca63adf29b4c6f06505ed0cf57ca7c26 -F test/fuzzcheck.c 984470cee0a35b893ad0377a7de75f0c9a758392 +F test/fuzzcheck.c 5592b19e07b9061833a35eaf78869ad0c8b6cf33 F test/fuzzdata1.db 7ee3227bad0e7ccdeb08a9e6822916777073c664 F test/fuzzdata2.db f03a420d3b822cc82e4f894ca957618fbe9c4973 F test/fuzzdata3.db c6586d3e3cef0fbc18108f9bb649aa77bfc38aba F test/fuzzdata4.db 1882f0055fb63214d8407ddc7aca9b0b1c59af21 +F test/fuzzdata5.db b39d6f1b2e6b37789d95e73a291febd5cb5ff779 F test/fuzzer1.test 3d4c4b7e547aba5e5511a2991e3e3d07166cfbb8 F test/fuzzer2.test a85ef814ce071293bce1ad8dffa217cbbaad4c14 F test/fuzzerfault.test 8792cd77fd5bce765b05d0c8e01b9edcf8af8536 @@ -1533,7 +1534,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e211c579b2f092e3283edd5fb9add7c5183bac35 -R f5446ee1d5f38bf5dd192848e11b9c1d +P 6f2d43eca68175ed28abae3afa792095af906af2 +R d3c47178caac86bf7a157d9adc36d0a2 U drh -Z e378b2bf2d2ef2294a0668dccb47568a +Z 2f0e4ab34b209b49e42001823006ce97 diff --git a/manifest.uuid b/manifest.uuid index 08d6ed2463..a64fde53b0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6f2d43eca68175ed28abae3afa792095af906af2 \ No newline at end of file +a71fad4538311ede111815d221d9eb8d9018092b \ No newline at end of file diff --git a/test/fuzzcheck.c b/test/fuzzcheck.c index 442bcc6e4d..ccc4df8d37 100644 --- a/test/fuzzcheck.c +++ b/test/fuzzcheck.c @@ -838,10 +838,12 @@ int main(int argc, char **argv){ int sqlFuzz = 0; /* True for SQL fuzz testing. False for DB fuzz */ int iTimeout = 120; /* Default 120-second timeout */ int nMem = 0; /* Memory limit */ + int nMemThisDb = 0; /* Memory limit set by the CONFIG table */ char *zExpDb = 0; /* Write Databases to files in this directory */ char *zExpSql = 0; /* Write SQL to files in this directory */ void *pHeap = 0; /* Heap for use by SQLite */ int ossFuzz = 0; /* enable OSS-FUZZ testing */ + int ossFuzzThisDb = 0; /* ossFuzz value for this particular database */ iBegin = timeOfDay(); #ifdef __unix__ @@ -981,6 +983,34 @@ int main(int argc, char **argv){ sqlite3_free(zSql); if( rc ) fatalError("cannot change description: %s", sqlite3_errmsg(db)); } + ossFuzzThisDb = ossFuzz; + + /* If the CONFIG(name,value) table exists, read db-specific settings + ** from that table */ + if( sqlite3_table_column_metadata(db,0,"config",0,0,0,0,0,0)==SQLITE_OK ){ + rc = sqlite3_prepare_v2(db, "SELECT name, value FROM config", -1, &pStmt, 0); + if( rc ) fatalError("cannot prepare query of CONFIG table: %s", + sqlite3_errmsg(db)); + while( SQLITE_ROW==sqlite3_step(pStmt) ){ + const char *zName = (const char *)sqlite3_column_text(pStmt,0); + if( zName==0 ) continue; + if( strcmp(zName, "oss-fuzz")==0 ){ + ossFuzzThisDb = sqlite3_column_int(pStmt,1); + if( verboseFlag ) printf("Config: oss-fuzz=%d\n", ossFuzzThisDb); + } + if( strcmp(zName, "limit-mem")==0 ){ +#if !defined(SQLITE_ENABLE_MEMSYS3) && !defined(SQLITE_ENABLE_MEMSYS5) + fatalError("the limit-mem option requires -DSQLITE_ENABLE_MEMSYS5" + " or _MEMSYS3"); +#else + nMemThisDb = sqlite3_column_int(pStmt,1); + if( verboseFlag ) printf("Config: limit-mem=%d\n", nMemThisDb); +#endif + } + } + sqlite3_finalize(pStmt); + } + if( zInsSql ){ sqlite3_create_function(db, "readfile", 1, SQLITE_UTF8, 0, readfileFunc, 0, 0); @@ -1096,13 +1126,13 @@ int main(int argc, char **argv){ } /* Limit available memory, if requested */ - if( nMem>0 ){ + if( nMemThisDb>0 ){ sqlite3_shutdown(); - pHeap = malloc(nMem); + pHeap = realloc(pHeap, nMemThisDb); if( pHeap==0 ){ fatalError("failed to allocate %d bytes of heap memory", nMem); } - sqlite3_config(SQLITE_CONFIG_HEAP, pHeap, nMem, 128); + sqlite3_config(SQLITE_CONFIG_HEAP, pHeap, nMemThisDb, 128); } /* Register the in-memory virtual filesystem @@ -1133,7 +1163,7 @@ int main(int argc, char **argv){ } } createVFile("main.db", pDb->sz, pDb->a); - if( ossFuzz ){ + if( ossFuzzThisDb ){ #ifndef SQLITE_OSS_FUZZ fatalError("--oss-fuzz not supported: recompile with -DSQLITE_OSS_FUZZ"); #else diff --git a/test/fuzzdata5.db b/test/fuzzdata5.db new file mode 100644 index 0000000000000000000000000000000000000000..b5c45f11697c6e1935965dbbfb5d59d0bb1c1dd4 GIT binary patch literal 8192 zcmeHKUvJw~6t|PKT}zNUP^l_}IP(-WAx(+#99a5Knt&d!JH43hZQHe`H@?%V{al>;^Gfuzs4vQ zBDo3-6cVG;Gc)`;Ra!b}o4tH4lAWNUhkjufEV<^2G>tl97C3f4=`cyM}V0M6hrrFTZbTW}S zoQaK1PfhV(PPumW?ay`g#0PA!7G?o6O@-=)EZvqGu+^y6%Z(jamv-g=nAPT;8hD04 zQ$0K-`_%IaAp?SVnRTK+t{zn=F-VWvKuxfm9{M)Qk4;~{&L2K>eN$U%D>mSl+G1X* ztzk}~2~|N|#U`FZY72>`XarVko2y}W!cbMS@4NJXW++`GiG7;`U-ea(nNbW80}%rk zVqgSOeEd&_9rLmasYReG%fOR1pWvRZkC!*fwVhqu#ijbzIE_xV^?CN_mOUJPuo zNSkO6hzcFcH1KXjV6)lGeZ0N93w_JHN7|Hy3j!{Po7)#zGeQgKi>^>_dCTuGYm3Fj zLcX}TbnZfoE0`}YwmZCp@}=w@!-8g8%_Xep_;y~EH~Ej#8QQx4O-}s7#q(bDSgM`7jJt!~vwnGyfgMH54Z#RYT5a`h`&=3w)WvL@pT;5f1u%gHSk23%?QHX zHK`#9zy0vj_s^aRf{+q~iLcjV3GT_;+0%iG=L8SPUL=xZM}s1=>yW z?(Os*^Eky|H>@|c6-Gkf4RdoIBh0!2PQOo(ZDiW38_GU%k9CIgiO8ZAQJT$w2RUv( z!&5%Lu)JJ=$B%P@@DWBS2wnX)w88>Y^*KrOGCi(cg30*TZ Nnlp&Oef!N9e*wu^V$%Qs literal 0 HcmV?d00001 From 588429a87dfbf9ca0dbc3eb16a1e51394f52f198 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 14 Nov 2016 20:08:00 +0000 Subject: [PATCH 0992/1484] Fix a potential use-after-free error during parsing of malformed CREATE TABLE statement. FossilOrigin-Name: c5dbc599b910c02a961675b12b273b8df6d29450 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/sqliteInt.h | 8 ++++---- test/fuzzdata5.db | Bin 8192 -> 8192 bytes 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index eeb7bbca0b..6bee34d1ab 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\sfuzzcheck.c\sto\saccept\sdatabase-specific\sconfiguration\sparameters\sin\nthe\soption\sCONFIG\stable.\s\sAdd\sthe\sfuzzdata5.db\sfuzz\sdatabase\scontaining\ntest\scases\sfrom\sOSS-FUZZ. -D 2016-11-14T18:27:41.319 +C Fix\sa\spotential\suse-after-free\serror\sduring\sparsing\sof\smalformed\nCREATE\sTABLE\sstatement. +D 2016-11-14T20:08:00.627 F Makefile.in 6b572807415d3f0a379cebc9461416d8df4a12c8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc bb4d970894abbbe0e88d00aac29bd52af8bc95f4 @@ -392,7 +392,7 @@ F src/shell.c f04e4af75c5517735397d060ed0b4a874104bb41 F src/sqlite.h.in 803f7050f69b2eea573fac219f3c92582c096027 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae -F src/sqliteInt.h 603953faca895386d4f3a8b7046f3e4e6c071c53 +F src/sqliteInt.h c471d791b10c0f2164c8b7a87adc338e703c09cc F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 @@ -819,7 +819,7 @@ F test/fuzzdata1.db 7ee3227bad0e7ccdeb08a9e6822916777073c664 F test/fuzzdata2.db f03a420d3b822cc82e4f894ca957618fbe9c4973 F test/fuzzdata3.db c6586d3e3cef0fbc18108f9bb649aa77bfc38aba F test/fuzzdata4.db 1882f0055fb63214d8407ddc7aca9b0b1c59af21 -F test/fuzzdata5.db b39d6f1b2e6b37789d95e73a291febd5cb5ff779 +F test/fuzzdata5.db 42d0545086da9f30f8ff83962dc28e273a8d50c2 F test/fuzzer1.test 3d4c4b7e547aba5e5511a2991e3e3d07166cfbb8 F test/fuzzer2.test a85ef814ce071293bce1ad8dffa217cbbaad4c14 F test/fuzzerfault.test 8792cd77fd5bce765b05d0c8e01b9edcf8af8536 @@ -1534,7 +1534,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 6f2d43eca68175ed28abae3afa792095af906af2 -R d3c47178caac86bf7a157d9adc36d0a2 +P a71fad4538311ede111815d221d9eb8d9018092b +R 2fe5b30a451a8ce17b7c2166fae94aef U drh -Z 2f0e4ab34b209b49e42001823006ce97 +Z e6fc9b27598a768c0afd9ae99ec00c26 diff --git a/manifest.uuid b/manifest.uuid index a64fde53b0..dce4b3a195 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a71fad4538311ede111815d221d9eb8d9018092b \ No newline at end of file +c5dbc599b910c02a961675b12b273b8df6d29450 \ No newline at end of file diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 88662958dd..5e256942ff 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2947,15 +2947,15 @@ struct Parse { } aColCache[SQLITE_N_COLCACHE]; /* One for each column cache entry */ int aTempReg[8]; /* Holding area for temporary registers */ Token sNameToken; /* Token with unqualified schema object name */ - Token sLastToken; /* The last token parsed */ /************************************************************************ ** Above is constant between recursions. Below is reset before and after ** each recursion. The boundary between these two regions is determined - ** using offsetof(Parse,nVar) so the nVar field must be the first field - ** in the recursive region. + ** using offsetof(Parse,sLastToken) so the sLastToken field must be the + ** first field in the recursive region. ************************************************************************/ + Token sLastToken; /* The last token parsed */ ynVar nVar; /* Number of '?' variables seen in the SQL so far */ int nzVar; /* Number of available slots in azVar[] */ u8 iPkSortOrder; /* ASC or DESC for INTEGER PRIMARY KEY */ @@ -2989,7 +2989,7 @@ struct Parse { ** Sizes and pointers of various parts of the Parse object. */ #define PARSE_HDR_SZ offsetof(Parse,aColCache) /* Recursive part w/o aColCache*/ -#define PARSE_RECURSE_SZ offsetof(Parse,nVar) /* Recursive part */ +#define PARSE_RECURSE_SZ offsetof(Parse,sLastToken) /* Recursive part */ #define PARSE_TAIL_SZ (sizeof(Parse)-PARSE_RECURSE_SZ) /* Non-recursive part */ #define PARSE_TAIL(X) (((char*)(X))+PARSE_RECURSE_SZ) /* Pointer to tail */ diff --git a/test/fuzzdata5.db b/test/fuzzdata5.db index b5c45f11697c6e1935965dbbfb5d59d0bb1c1dd4..fdd4ec3e98d14bd820040777fd0343fb9f2c205d 100644 GIT binary patch delta 141 zcmZp0XmFSyEhx;uz`y~-Fu*ZU$Cy!gW5O3kM%K-tOxswQIhcQM7Gz;z+APHNhLMqd z^M7temPIlwn*{!|OSAC;^)WMuGcX!4@&hRtXe?!!Y%B3qS&^BU!P7a&)iK1Cvm`Mo YCzUf(!=E?Q&oeO86-sS3l03%*0C!6rYybcN delta 98 zcmZp0XmFSyEhxaiz`y~-Fu*=h$Cy!IW5O3kMvl#)OxswQ*_nTD7Gz;z+APHNhLMqN u^M7temQ5o6*?C!cftr{YtQZ)L7_25X>M=K#GEbJ0`MTLi_8ik90TuwdXBDCV From 5413ba4b174207c361347b596da8de0faf82892b Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 14 Nov 2016 20:47:18 +0000 Subject: [PATCH 0993/1484] Add 8794 new test cases received from the OSS-FUZZ project. FossilOrigin-Name: 03f75a67c320f21192d721a8c34d49dea48ffdbb --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/fuzzdata5.db | Bin 8192 -> 6960128 bytes 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 6bee34d1ab..53f9f991eb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\spotential\suse-after-free\serror\sduring\sparsing\sof\smalformed\nCREATE\sTABLE\sstatement. -D 2016-11-14T20:08:00.627 +C Add\s8794\snew\stest\scases\sreceived\sfrom\sthe\sOSS-FUZZ\sproject. +D 2016-11-14T20:47:18.877 F Makefile.in 6b572807415d3f0a379cebc9461416d8df4a12c8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc bb4d970894abbbe0e88d00aac29bd52af8bc95f4 @@ -819,7 +819,7 @@ F test/fuzzdata1.db 7ee3227bad0e7ccdeb08a9e6822916777073c664 F test/fuzzdata2.db f03a420d3b822cc82e4f894ca957618fbe9c4973 F test/fuzzdata3.db c6586d3e3cef0fbc18108f9bb649aa77bfc38aba F test/fuzzdata4.db 1882f0055fb63214d8407ddc7aca9b0b1c59af21 -F test/fuzzdata5.db 42d0545086da9f30f8ff83962dc28e273a8d50c2 +F test/fuzzdata5.db e143587fe774458ea928abaaa85a98019396f573 F test/fuzzer1.test 3d4c4b7e547aba5e5511a2991e3e3d07166cfbb8 F test/fuzzer2.test a85ef814ce071293bce1ad8dffa217cbbaad4c14 F test/fuzzerfault.test 8792cd77fd5bce765b05d0c8e01b9edcf8af8536 @@ -1534,7 +1534,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a71fad4538311ede111815d221d9eb8d9018092b -R 2fe5b30a451a8ce17b7c2166fae94aef +P c5dbc599b910c02a961675b12b273b8df6d29450 +R 16d589cbe0b8a973a94265be5011a399 U drh -Z e6fc9b27598a768c0afd9ae99ec00c26 +Z 2897265fcdd3b169958c85551506b7bd diff --git a/manifest.uuid b/manifest.uuid index dce4b3a195..c9d695165a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c5dbc599b910c02a961675b12b273b8df6d29450 \ No newline at end of file +03f75a67c320f21192d721a8c34d49dea48ffdbb \ No newline at end of file diff --git a/test/fuzzdata5.db b/test/fuzzdata5.db index fdd4ec3e98d14bd820040777fd0343fb9f2c205d..2aad5b0caabfc3022e666dba7c4c850b73f8f4e6 100644 GIT binary patch literal 6960128 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∾TnDvmu znF#>mh(K9w4^X15H?ngc3>=6sZqDBVAs7!iLR%-DEK8Si2aZQ$%8473hu)}SU$Kuv znb>B#iXM?ecs+>K0%>&iYj`+cytE{3cw{wP*!9GMF%$`6tY$DPu+P%rudr@7RKvDy zzWSen%2*cA(FNdXRN~pZh#XDkfrh)$4vxlcgW**8CYDk$ae7yJr*k5FJU}X(;CtRZ zfU#2An;jej)!sZ%HUG)k4gVIo$02--AmSW zf&Pd1B(1Rj4s)KB{ckOCC=~)W}I;bm;1;{|J&&QE70|? z_y2R^Lx-tT;QlMGEJ%+=Tx}?(REnoV)i2(?WJ9m$|48zl-4H*c1^VA6`;SuY+y9p= zfg{RfX#d|}wOk(=7>dq`mh}JWjc~+NqIGa5R$?Tfy=deSvbB^EP^XwtsK@C(jmUB+ zpd;(%99i zf9a0@xu)IrA2TW5lx59^y{~N>snqIaziG?*4V+dauG#5=ZYPf>a|C4_O({5HnfCuh ziV%|J|>^cBS>>j8-KD8wQN{e;B>-{7!3daTuFleO>BG4 zxfbTML|lJ08z3ch@7D?I5E~KVJpA|AUTF))D3iMLhKa*brtYY?vDF>)IxrdFoBt!# zBGpb4%KkY8iT^mpHRt&@^l9IqoDpG|jB>Ewj1YIqa*J?9u)! z^2w6=7!)860e z^#IcEjj2_K1_u)bnSSvlh~Jt$w_gV?^=%wmV@glt)8T2Cp}^~pa>}qrh!=e0L47?@ zPB1xXWS&eihr*9)snnmMa$e#%-ib(387jl;#wx?LIxL7fI8v=uhH5bDW~f%K4Z-`# zhU=B`z)+R^_$>T*&PPbq*+@lys-*v>0{QC>Vrr*{={=$U)uC#A7}pWv%vqrIi<`DX zRp#!^i41#3it$1ezqDOy`mg8z{t$4A|8+VB$}PqJK%>N&W>@zLhZKCKx%pwcwPEPfbgYsX$XK%f z-C%k1(T0aMZ6y0o_MahHroD~p$^IL!c8Tgzc7E@5!cn=7NdmI4oL8qd=HyIywVlRazMXk%Ec zpv=F$D8hV$h@G{R|Mz-tsfF$!)>j+;Kdt}WS`}}>({?Y}l->GY126*E@m@s_6iJwA z@E9$5fTL5;TK_ZU*GE|@qB}%FhebXYeDRusB{ssy4a3K>|U}tL;csM z&i8GI6FG#hNyH*vz>Qq#b29yh7X}Uv*Tf-s3@n8gMwVLnqEz;gCq=gqv2=iUi z5oz|EZ2g6ny?C^xUCT`W(GvNt|IxV&BxzhVx^lgtW)4FUDR-7^)vHL>$T<*DKrnX> zu=~}p1x}&&BS`-(d&J>}hxHGf3)WfINb}wJIjruHqx|EZBO zUpLylX3l3C{^Z$Y7$!*T){a^Xg*mP^Nd&yK6=zpL{ zGnXWLoax^8|B(GpSM73hx7|x_=^_13qrdP9zCV+Td=_VF|DAT(ou09R)2#CUvP|QD za-+9tRb=;)ZKVH^REH%VGt&QB@YFKW|Fk5Y?!!}H_mb_T|FQI6$mntQU(`^F|9L5+ zh`+RyuKy@%I!X#j4uFT4qunaB{x>r=9Jq_7qZyD+|LqkCv*kT8 z|F^f+|0qafu>Lo^|L2e3pxJHDEwil~-MVehEw{DqX}9dzdMi9_9aC_9AFSme{norE z#?nuE_zBdXdT7&3cJqIQr}+;2O7@?a3R9peQFKh zNZNtpc;gJGoh-oW+`-IzaG7)%Y_(de*TZL{w0@Ldbs!+5PTJ~-%e%Lr)jaa^WAK|b zyJ=k44f^jexTOC+fnsj;U!1{Yh-8|;M-bo(6{P=`XV2kA+}NG@8Tp=#=G1?j{Kz$$ zHKGNUu*LI#M#}K+wJ46y!mcM4cCdN4LZ4t7QsR)RT(|(F|7mcRsZJdIKL8&rW?nr4 zbY4S~dcscq#|m_?{>OPoU!-oh764zaLI529tEfxh{ohc~Mid|lxG1n^W)9N7n-MCl zjl)a_fXD1O6Yw4$y<^WUJ6o69-j0p!8T*fKP2HPxs#w%1DM>S$j*JFxrqgx;dL{^n zoCN5ZAV8o0gRcSA-vsJ{zSv*vS+=VnJ-pGvNjyjkD{J-gP_--$yyEW79B_2uTDEwt z$4Ci%Jt3}MPWuqa55->k)(!^?elxicqzny=3{+dP{->i`Cs>wZT3(OSIj-^2)I1|H zA4q@-$|Wg`23$3^9@b`BUoV036@yd?k& z3<(>kmWRXPC*k-Sl*$~q7<~z6y_E+Bh6nwL<=}$H6d8+m!8#v8EXQ+Lx~;L_?FDJ~ z;oLLAp5pMvIDuk7;m>#e~M%jeQ0qyscnC3nnR2s%XM~F z`hhKm{ud<){(EhEZnz7w5$DXG{LcOgP_VdjZgz5RYI?N4vb4Ar>wEg?tJkbQ z{q&1ZKb=*vGBP+gXgBw~lZq#epR_bw|L^Vr{U00{9CCCeg)3jE;V1oP-T|{L>@(Xt zodeQ;(AJjgzal*@DHlVLk8QqsPeFR~R5LEe%xb(U1=X#C>GpeP1OL*7q2ZCb--%EY zX12o}Z!y0X_3^`%k#Z#zwT6w58Qgipe*tl)x zvJLzHgrr;|J&~&NC%D;sRZ~00k|f3r1_1(mr{_u5N(o_0m!yjSs0-Fz09;duYpL1) zgj|bb{}oXEoaz5Qd66WFByCAzknWvf0sSu!*Rs)nJ^8_BKL8!{jTsO8AQ%vvYwk=4 zp36|%u>Xfk$_dipCVzMDuk8mTXpYbyz>0_uO3iH#=+GA0*^=J%h@FE>KZN}kKOuZ% zAACkAGBS&8OsOM*b$PL_E@OY?iaw*?9>oH`Vm)AZJb#0>Z`+eL0~KpfMl0ltQ;!7E zUQ`8~*~LU6e4m=o7(JlKU?cvoO3D|c-;t`}Rgk1Tw`hx^Pf&p6Qe!Qa=$sDm`rS*k zzUT|tHTO6hA{pGlo~a^!C8%TgGG5$}uncDbII0z4VOpUX5zcqEJJQJIHqD@etjYdu zkN=}ut;9hilT&{ojhHn-jbG#HH7gqH@^sMpKR&s7U3ZPfY(R1p!<)%DX#Ztt4S+x@x8Ji&J0SY}pP1H~=KnC*H~0SN zA3BS`A%~&o3$6pr|B1?oj+p9qX2;Vo0}_)+Z4Ui^1AsVAGTH!{awfw`D4(6hCA`=^v#CGGUAH8OlQPso+&F2A z4nR#?TL7H-^ek?2Jg}s)11v6CQ~*Q{g1E!fjVsYwq;*;ZMu($Y{r}!VBSg+1%S#%R zjRvKmJ?(J&t!LiHdmZHeo8A!TnQ9#-#(Y5mx5Jp3T5O92~r2 zKcSU~R%vNa8ur}s#an)0%>RM)zdt0u&>bs)Yqw~J7o_=XFsiXOP7}nWsy?cDWlQrG*QLC_4l5L_Bog9!kBa-@Ro%dKX~614WPJhZj~t9|Qa%(S(Q z)!Ly2>An*!0^mU#cpI~|25b5Ldb`dJsfl@KTPDo$W^v_5pZ_a=Qd0g43fek{0x;h7 zi0I>8Yq-2=dARBrl4^?~*hYTj=WuzXTJsn#A{aYiDfAaX$Zc5ky>Y86!lOg6f4I~* zPyTYYVk>E;nyt3ES}k%f8e1KVMk*Iosd~!f)_FAEDl7tpAVe zf68CV&HA5>x^@(>XgV5;>gDp_a3z`r4_>t&iOs#9fjikjJVtZ=>+>omO}VA+Bd=!L z2g~E17420H9N_DR7LjCWcSSoAW=e0hzQThbMTD1`thu=ABYj*(31&&aGNY-?zYqpc z#G>$7BO_-UQrirL@nsn?D9opM%~~D{-1Z?An#Y;BFuFIb6x5XS3C#x3<;vhlEy{@G$2~T`H-cEiFK!v1n}BuS*^Cp5 zoc6(&;4n@q3JmmcIc%7l(Cv@U;@HQ;#Hu8GA+WNg17q;vUi#T6Xh(yQ(cjg^Y8)Wc zIQJ)DqL?|=CiW|UVj-Z;Q~j+!tin15B(odn|My9!OX{;~UHP1HrTnk*opPV_PWZ~X z-9Mt8RFEFIgFRi}`*OKn9~z4DaxLL)Z1CvE;c+Ln?s1R7QSq}3t;VsfO#Nh zBXEU~=3n&~zATW#490Ckbs5qKUhL?d;E%`&oge;^7rRn1FK|h=z&38-r2KNCJTO=p z4hT3cMr8e}X)Z+bcnxhdMx*{Wt<}*U!3(UwZI?d8lqHY1MskAPMp=sSPEoVT9j?{6 zKnS7aV#=KcE_%EV?8;9A>yZ!Hej^PnG=(`595&V*om%qp1%|C9bBSW{LXso;d{m|Yp&VE-wrkAh%r349o*FvSgtTWbG1LjTGC z?`K)Y%z9#?+5Z;586=+Sko}LJ|0DfJ$ag|E*?*)8X9L^V6B|7f+oSrAIG zdXlmX4rq%`0d2c>3QWGc0p;D=IKda8VW13C6~f1jgss=kLeC4$gS1D4dX6W>*1=@M z+q9FRy%A>^)axU)ibDZ8;&=|r6?z4Qlj|j@Ld3~1j6`g2yp91TS?H^kF1^ZQVunYn zvCYtE7^%6Wbt5(34v%|n>mH}S^SkN%Ul#V?F;-qMB%(f5u-7?!R9{#4|0%q@%%O>a zgpHeaCjVat3s!KzRiCRCrojT&XcJz0> zxD*E2>&sgIOX6L_J%IVmQ9T07+%Y-Cz1JKOp&6My#hP*UoOR@NU{zL@8Z+9dFui}X z^%Wj)1QC_VpW;ni(#&JxUBgwXZ6yD-!2pZC#{557zCnWjw53gf`%chG1?hp67QJK3 zGcPpmX>6Ydjpurx*~vmeVqjokr0zeTkDDE*!-vQ1pwhw}tCd=P$p4Pf{d(c9Oq;*r zQv-MFvA$7GezV>%cfq*r`~~0MRf;gl7BgKaP&0dsNY~sPDbOC)_YP{WYiNR&t_QYU5)jB4w95( zjV?S*f%nCo;0!TdIKu9!%@CM0R#WC!~xYGBMbaH^Q%XIJ+_VD=s6H#B^ zBKzX=o3*8&>X-6&ZiW=;(ys~xtOfWU=18N|BPK?^y+}WcB))9UMK!HDyAG@d81`S4 zi<0tf`F~+Yn}Y({TCEHz?}&?^03r-Efe59G2kRTwcw=??68+h|+Gg!cXjF9F9y$$P ztSBx3WXO=O2BZUYmXCa)iFgq^JFs$)PAF<;0Gf|l;*JNtHAdc@)&%o9yGsY{zbf4z zDPNSIfL*#9tWj4325gJSfPn#ccd0049Jho309}7$^YmW@ZwPt`21W*9{k!Oq1>V~8 z#^B;L*AZ1VYTJ(?o(qrh3yVe|w^gkQWSg?S!UK*H4lg7I*^El~woV{h#Kqnn@ou_Q zGl`}L#u2DiX+PB>E}xVes)54)ma%ZFxA`#xkhIp-8gutGHn%W!sC1_HVoE~@T}hn{ zUwYI{vSu`hXv@>q13-wV4g zMAh$?GRk_@v8M$V^#2*#zz`CkFeE_&5?UZ&(SJxo654ur7$mR>1s3%G_Y6=Zq>UYj zQT{(*P-T|sK0?{FP!{x`^8eO*58w@=X%W@{RX!y{LYp0J$u;05&4U_9dTuh|q#>RQ z3r7C`6-j;tk$|?|pun>`w1I;3^>L62d*fVlG0WIQ7U0d)MZuAiX`X*r#JIp+B=R6i zrZ)rvT(J_!`g`H;4=A0QS~}H55)&TV`^8X%d(b$P#KDE~&o^jlCBuM@H;qN2H zSWmr&!Lgd90Lh(a6(|_Th{eCxNno!n`jeJ*b{xbNu*jVs)^oV*KW1WZ<0{$h!MH(& zmS&GY|3A8l`M+IHUrxN3SjBU<3?=c`C_`jPXbq7f+ByKN`8>TXQt1*E^#5Zdv^<;A zrEho9cH5+7sT~L88bBvp(qP;{(*>TW`fusG2B80D{*SYb-6ga+nF`;FM9oNO4Lu=& zO|~A3?#t@=Kj{||{_nBvebd@dLHg20rkMJkg$4K_o+pqc_;aGpDj2VFVQ~w)E4G>& zCf6F}cT41XWbSDNOthSBKE;gl`o9hbB1=)5M4`De?JWL|M@0`_OW-3;I;y9&T*|5>B}{r;cSyc^-+ahB&xsAx@jB! zb{ERodWsh4{~y`Tft#@PfDv9{P9+H~QXnlr7#<;%-H<}W8_*xxg8~cs{|Oyv7t+ry zn)kIm`5vS%ud`_(0r^{TTm!OTCD1!#z`CK4d3HEev(Id{@61NOfO7{R5|Kb0By*0xPXU%xYQ4X^*Q+alryM8Ri#cKTP1XQbR--x z&LaBa#$kns#!;4+F`Y>}M3Ti`UVuSwwi7pzv#!vG0fN6`O2we3PY^d_M-WR!%q zH3<|#SzgjSr~#l57YRWBKTSwmLdyB~5Hsht3HsVdODGF+mX6Spz@{d!p#PNrZ;koV zrI!3zPk$DWl}}E@wPIelLcVMiqJsLrfam2P9Z3PQ5m3#7hD;hJ&Ry~zAOQ->ExB#H zOn5k0fj|iQ|7WQFf{ROOS;WK6Tkj+;^IeRmjE;f0yhe35%7Xs?d3#^;m=B>nrMqU) zbhprwz^1n9DCqxR%#QEaLN9#fsL+MI;rT$>j$SIaD_sN7|Idzz3n2!^3oe&2%UFSg zmUl!wr~%xFohl>O0IAjqSp(2bed8F9>W3Q_u7?ifD$df`_AZIb*gC}_))0-wK4 zTfUE^y={W2fxh=e@+RK82`XpU3TVc{bNgy%6{MFA&Hibt@ey1*V!I@qfn&Fc=Y)pk zE!kb6o_yu_q0Ak!#y2zo`-k|NH$4a&q~tU3_j%$UCl~&XAxb%JoG?W}SZj4<%jZgq ze|l}&KaGU?Z9BN%7WDrwJNperhM$=ZBAOZ%W={0edJG9D@B)T+U*HA${{=Jm--TIk z656g5T25f8-Zy6~2y+@l4 zMB$!Wjd3~V&U$w>T z@dot&Yq~p2@Bi}8#&T9y5L(u6Wf0IVIr@6BiBJ~Z7eAufWE78hqUyg;LMVlV5M~n$ zI`j1Pz!nl(5?bd_(|9t`5`Wglm3WoQvo9O;a^s{##reN7y!;FP)0Pee;Qe2(qxXM_ zYsxr0Q-1m?js9rY=noM0ufX4nl>evve=&HNnCPu1H9DeWFT|r1FJ*xS{_zs%|JS?6 zQwn<5GYKuE+^~z2H@-=y>|{w)f1xFTO&W_@0Y2#eH@Y!qY8Mia(4wm!Kb7iq3E1aU z(JIeDewzdq^#7X%ttp)vY8xF<>?9LX=RUU3)=C#s_qE}jL?WtAa1z)Q1Qzt4^8fbW zS@LJGU!LB4Vj#NZC8N7-Y+SFUIGm?L2VhbD9}zIs4f6kIQ~saw|DogOvNSdvbTP^^%F|E;JK1Y{Gob(fXw4Vt3XdiT5Tc+W z^@dV!Xz%ofg8qNUMuXl#0&)$=HK5+mg$2-mGylig#$E&juKB(J6S)TD8g!X!py&Uj zUr6}B$F}!PYv&ZCFKuLKr|+5W;|Ev5BvAj`oy`fXTv*RH*KB@<6F*dl#_5LT5m010 zX-*^P`#-?nKSR9*{&%z_qvGPmwMbNC%5&0CgBU{%y4)`W{r{f-*pn=gfFf`}DN4?V z8P)taVO=S(p#R^GvFdV`fY9YgODIe4nG@Vn7AyD%Gr$R`J^cJYl zg|PymY{=+rl!3TWeCN6bp#MKGYHyDYV4<_13b`N6lqmm&nvWZ6Ivxwn??NQ#T%qkX zfdwViHx9c|Kygbduy|jZ6sil9u%wzn-Q@J`B-(P~#l%X$z)%wq*2~a~M9n$M8sq=J zFUj9GAco4Wqre}&K|8k~{p%Z<_UU`3;P@e)l6Q0ph-)_QJ<$Juv)M#KOF~PF{PL*P?XCgn|BnoKAf(L}X$fUP&MdoQQv(o}Tmuni zLKCg&SpL$e07{tqHxsvE5Ta~`e#L+k&v z(255H_%>v@f_sqqe}%vQ5Miy@pPqNoT)n72g8CzBxOHBWHxoKT(Yu(y~5bD-du25zgkA)am9?c#f~JEq*+0YSkz^ z(0`i$!Bybz6TAYbx7!q|kQKq$-`z`5jwB^M4QlyLyB9KPzbd5A{d7Ja~}$ ze}}*SCC{1q+o->-HT`XQ%L0S`zmm_$q?4RHE^uH00}<5`KCw>4$T4)zJ!k7(867=d z67>J4c9cs(OF~QYe|jnD1N#3nBNvq497S%CcCWdyWE$I3QVoU>WjTtJTm!IE0c#vE zClt>LUds^lpXUG2{2$)rb+kWAzARv)M>y(-1epIt?Z?348 zH#kbfSq8@(heb3_a~yh3Mo0EsU;+C7%beLz5?UKZCv}1JDEJgZ&j~FFtUX{oVYCMN z|1013!KIzT`5(?JAfW~Ono0`CKnETWqC_f$vV^iQ=mYfs*Vf2~+(#@Vw7C{qE>g%g z6+^}&E#m?DPx*h!|BG4FS_#FA24Hc16c9w;IEd?tWQZim5?R$;TU8<2?FykYA{M)( z*rjdbB|!gWS1(pHKzQt3Be<X1)k%SFT4G zrTo81h0b%k$Tjc@Zo-g&^8cyk{_$pz{~x9NKjr^BApbA#1OESkl>evk|Fr(MH4C<< zmNfzWUmP#4vr^TR|2G0BD9Qbd;(pp;#iT_!#{qvE{U^#wWt)`({XdA(sUT_|Dy(M& z$Tc9>po?7t(Eo!C3?`(_7HJ7(31tmU^RhMZeDL)8Rxn{@)QWe#Jd9zy3R*#e&t3II zGZb8UvWEv@5p7W(I9Z^f0p`2XGtVJX{vQ!A)eZ9h7gGM8^8cCZuIWu!J0DxiaMfjH z!1q4@{tl!3KLz;|R`WssUu8F4Xm+UoLP5SEy}VqJ(4zLFF*4On zTT5t3V1YOu)Iib)zwXaPRM7t;j4ugkDgU4S`ag@U6*V|>8&_yaU`uJCEM~r3px}iq z-~o3KLp|5S7Tcr(cVUqtzT%Kzsc5W)996#kAz!kp%l-yD6b*BXM|Ckc6prhXQqWgc8ujqh$#gO5u^LmQGu2zEa?BSA~X1Yn(XsI_6n<8>hW$K`s85@ z<1wE`Ip`v~z-v^Sg_Z=iUh+5Eu>=+q*2dyjZuelY8t|0Pa1DGtn^;8ZVgm76of%Yq zMS}E`M5rtGs#ThRX#J?9b-5&$tRT#Qdxlhi#gv_H#0Xh~pGBP!_s zNd_A9yrlYfrZVrS85AIYz&19XdfN<9b#NttO#uZk-({Gp5H^uN0D?;Xz-pcf@nnKh z1v$*W82SGjCHcng$$aOhB_G^Z8-uApl!Nz&&K}RfBb>Ht?hW|Ar+6u~>E{M1?Xojbw)48JEj$GM zKh;Kqyd%MdC@EImo2_@2fv7IZl$lB)Go@2f72B81_2Bk@8 zJ3?qpX7#ktlE9V#s#2NdMfrag2_Z%M$u&SKbg)0$tWW504SEJ;Y5lL%dkbLwuS;nC zFIxXA_fsms_g?~kr&IplKz|$?KWQMpyX?%&6y^VW#*#ZlHk!bK{x8jY)=zI);^a@3 zu6^Rl^{V^XoY0cMVy03ETw_`=OJG6&m)W->!X_oGfmJ;?nG^|^aRS8>+LQ#A^8X79 zp#NtWAWZpx%K!6&@$4Q3W@zGBhb;XqLRkdcG$yQ2{+~&A=H`opHZ7qw3>F{YrtKP- zCeg+~sJgy!($W>fTq*ybMgIR%%KuaTzZ3HRr-A=pvBN2VxNQ5t38zD>md=5g$()Fe z#YnX_I6M%rq$4FEd(W`|{jd5il1U*PjfOE)0!t3N4PRKW8(rZI+l@7jc(B&L>AEBt z=zq;x{yX;`3yoCB#x)3KJh=vLK;ZC@Wd-78Nb^8c(EoZf%Mp`nK(2vpEjd*n*8nNd zF@OO2KY)DXIM`g>vjl|1mCFOt63SW&J$HSqkgmY83^jMx)KC`h9n|lAViT__$Px;4 zo6~hs7)4;yo3_tv>ZezK`sU&?GGRvl-}fZ>dkkf0-(3{=!+W(=@E#DEnGAi;d_4RR zFKEpY+&KfsDj2VFVM@a8imm3>$>xVW_0Z5w@cqm1Hyjar4bFGc3nV(kSt$1R>Oi+FAq8);_sj|3i$p*@OQR>(p@&!se|}H`Bwmrdi#Jw$iFVwodKLj z%pfU4lh7W41^qwAe;#pHAaXtetqu>ejOtq@?}!@aqlfy<>|7B#iJ7h$n;3$^d@j)c zb4kmQ0?k2u7=3$@wwViUG@?@eZ_IZRwq^1$=I?ORWCt!xg+V@I_hRKlXuB(^O0EHl zqNQvuMQgvn>iIwA^%DH2jVRDc3cP1pTV0SoNBLL42p=G@a}f&>2Ux_(zk=`oI`}(3 zV*ZKxOn32NFXu2s^G9=T+S`+V^0$p$LDbymo?nZ zxNrEdJP;;x@+Yi!iDpmRdI>Q?gVj7_z%fI1i?BpgX4xV}u5BCu0Nm?UlDe`{#`pKlkD(@l=n!5=68WSBI& z`-aR;6N_yma6rNLUjcs?QU0&JNr(|D*Z8qm~e` zNCxfyB=g~&dp>N|e{0&wr~F?KZMmR4oBR~$|5z{jUCD&jH=SbelH*!0(w1v}HbNUp z)X@B&5$;p|58nSr`9A{->^QVdLfeH&RYF;Ss{D`t>)H9gms9?a@_%iO_}l3#f$x7I z{H>z=ALajINB!*-ToTyS1QzuFGAs2%PdZv0(8XXF9Z$0ZzW=50x3+5`lDeOO`vJ1SxgwPR zi~0(PEYYC#0t@ejrAIMThK|<^O*@V7q&n*qo+xfpMDE~+Kzh2J&T@L>Ll{DhTaEfTe zixKYitU~l)vQ)EP)06 zzdEH<0tqb%ZD+p>rw2_J=>IjQ;znEGiIBEQq$QLEIkW7JO%1eLahJu_CAR4$M|=mv znu=i01n+)8u=D>dop#Xugf(P|Cu)}q?LfI!Ee{90#ghhhm>xR+Ru3C%nhPA05*73R zigYQA0)Qgf_WteK`hxVe8<=kEd)6xa5HHVADeX14V0z(=^_p zq1w8F^sQ6%_Ol`h9k7KjhxSb6iVmy&UpXsJ`c!ZLyc-uG&!ny(et`B3D#VcY~ zhpJ&H3egPD9-ZL{`fnKQxHfcV*JJM*!EFV?17}csQP#NTGee(_Kf$267m2Ey9dZvm z-Gjv-5KPkGFs}02`U?7gqkSt9T2!n~ojVSV2PeZ}!J zHnBb?e*YZ*VehZ)Pfy|@@W(c)(W>fqRy&)3&FGUQWB$)OBnkfKX?ys3Z9_qN_t|1A{$%pBDC+7Lk)xcIPCB>VH=ROK)T~ui@2(RVDl)^J2y^b}zQ?FE6c> zmiG1c=>gr+tNQv(t3Rd_lNC?n_3Q&y)QJD|AqwnP=DxV|=Gmzo+cr*5OwY{T#hx2= zzo5Tp2hVogc0sRcf9$IE^*!AW6_4h^*dB~=WVP6||H>H>{HKj55JG|Z)!J1BY0rt4 z0O0|rw28bjQ!^qX(|a&od6tyo6yOS z$^-qpMTI*N>B-$OsZB^F`BpDMr6MF>@vNRod?KS$p>R~BX&;5*$qD4rWqZ@3T051^ z82`UnQqGh%BNk+^J^niF+Jf}V8<76imN$UtcJXz!FTVIfx@hZzquMnE>B)mFKH@=F z@p33&29t}3sJWcwV}uY)h*xepA5;T|PQc&IeoH__#id%kTpg~~1_wu~<&oNOeXs`q zYeV(H@=(2285$g}Rx0&@L6NZeAOSDC#eVV<@YNi!Spl@!bA^%+A29snD%XBk9_3QU zov7Lv4{y-k&ur@Vx`?3}FAsK)Wn^)viFzM=S8SvQpkftz$}RWnF%JCxfh(@C`NPD8 z+cV#e`$|9Tucp!|j+z5K%A7wCWl)BFdMV23Ug8r-l+YiWBboO&f)tR=nX7N^bNCPj zlUpbgc*y7~s96_`Y2n+3$3puuM7_|FKuife&`zjh*Em-LB_zM2Yt5teP9}Bz=n9mC z$kr6(iotj)dp-V_H%jWGP|%h(1)h41c6~wm#0n5Nwugb zK2&v&4s|yQg7IzlAE{kekRGYvuhy1L+u?Cj@VA{C=-Va^qE^<1Pi>Y;msq zAY)`5_jq|cYB0y%{4|QeJ?Q^*Km(!rf`#gOXDl>a^g4kN&@*=-&@T{Qqr|_QI7K;~ zlRbhKf)+*rOBQC(;k9NF#)(2g)=Qx{&y_^?LXOby!gG3i<^Ka7S`ZX|ff3_a7nlbu z33yteszD}q z7P=d6pzcO1pM~bNeWul_MtX7|*-StqMr&l?Bf&X6D+`v`OJyuo2~p2>FJ+ zC^Jlw7Q!#U)42=GD_MUdbvJsVIP;6_F1=Vsk>h``|F`oqYrM4HlHcs2`d%0S=)aDs z7lBP>C99c7tJysk6ZHQM3(IY{z-l1FAzBGI$a-27Y%1Mksefxj4}ungmRWSoDAwNu z3qQ7Xk#T=;3HPt}l0#1Ye~#!Nvj1X5r;gV)LI>cvn5eNf%fEnc zLQ_24$yVn;&lw0L9Y=`#P>ng79-g|$*(e==;QQ}_zq={^kE0jlr1Prbfe|R9q4JqV z-xa5!9@WS)Yi?0MRJu-Tl$kLH{eL|J6)&ziO-AebXD#lwR^j|T@qk|}3VM++R7Tp= zQmk}(N|Ngyn9jH7SwRc>yFKULwMpRu0L1?%ivJn7diWG*o!B^2e-cLd#nu7#IBw5^ zLhdX5(C2MpvqkZ4J{9NPZl_swg!8dKQvA<&)?0gs|8JuB-x_&~TI!*Fp&nW1`wJ1{ ze|V9Rd~bO;g(W&eY1$^Eiy}Z?Zl)`|rnc6h*Wi=fs$#AKp2*4u`u|2GF_-U*5^r1g zPsss8Ej6}g;M%H9l&YuKQmimR3qgzdw%Cpo1$2)$tR54WYR{c54~?gqsqwPf&`4!u zWT0Lhsa5<}=SvSSqQs%Db142d4TF~>4`wTe@qY@QLF|CvaY3y3UzMtoe2DZru#2$4 z0;QW-egBJI6Cs(NudApq;O#_1h4COEa-bX%~`Io*EG`y^x0{d z+=f}qFKEunFo%R|X)6YlW2HI&m6uXMLIW%kI{dmsvu;$|Gse4nm|Um$JG(CVTHv{n zZ!A>VOQ{@pZiNlAH9Gzo$G7p`t6NNS@oGUvM<%{qP zPK2mC%Tsv068PB#g2J~AkA?Pmfs7?to{EqVZS@)$fM_5__h3c~{r}H4M>UJHwmZ@x zMw$~FaQIS&0{P7(ipE6HCd^lli(=S78z12ibO-G{A`X^PMA4x16fQ~}={ko=NVvoWTD#V^6f4~$ zveXIC0{Z`!*u#Hv+pt_)nofe2s5vVOf?{7_UfGUi09mCuJKeKLj>&|XkXK-!;P$Ow ziCS+t2IMG)I$@T+b7Zqajr44whd8rG7mK&fPVJbR#EEJpK2z`I5abTk6-(M|vSDL6 zy=4tW(d6655)IjB8LS$l=SDfk@-_1@*7!eJd9?)pX(I{<6nOSxZA(G=`Vj~W)@I2& zd?Tow7o>0}d+2g{5SVMf4@t)nB0p3E-~T@Nd#J6;AhxjI$lG*87h)UXTQQ6UEgfkH z%`VDzb`j|RTfOzdiSHflQn{u$Ve43u)0J3@@dawBv3Yo<%|J^>c1bte5174so?GLa zL~K%Q6gqrZl^(G)mLF!@@>VEZ3_!6@jh#}9eSs;1?a09)Aos0CLAHG3lFbu;|H@)u zO89-n6=H6IsinDR@sQ)|1=q?y`|4483UNp?(Z2hdc=5md1quGs*2xrj>b2Sgto(DS zu2QVvv?V`bX9`Nf!v-8%o}8%5&3I&vJLiXL41rQ?6!`uR!rvnl|L!w&Jwf;A{~hK zo^C~YfSiFnZw6Y>w|0({j@(XafWBF#jq4>X(WBF$44)Oma z#s6U)5uxV4mqHQn{oe+EPxQCR59-LS|5msQnL1?aSDe3UG+zN_5T;7J0$tD@&@ULaL}3!R`tE5b*uWm8y+{+y2rf} z9(Qx=9{1!^{n}Ot{WqW+ZEcoo0pCRTLo!Z!ldB-|qP?yH`2LT>-#budn79a{60Lf~ z)I2ejk~!OFLM9Egw(kdBhx`Uxp#Q(=3Hn&=WC$lr|+A^%bwNLAZ5GqugUT zyc_4_0nOuJ0T#d4MME!|kq>4)BaQj8jcugUt$TB7YStX~=r%^UJZD#68o~Z5z^7)r0;#nB~ z^PULw?Sf1IlN+}Uuw4QlQ3FB?($@7uXpjy)5~K+JxRcRMC{$|7ggn44Tj&G*e{bj{ zA*@D^h=V^$AQ5om_|ay^(x{K4POJd}UZ?V^#}-Vqaih*^aq~tkQ(!6SLU=ALadD6i((A^gP7bb^<#2{au8Ft)mvVvx|7jx%I4SV#sJ0DW0d_EgpS3Y`!7rkR8JuTgCtN5J2$`#x zCDp+9e;WRNudPcGQKp_;D+H2Uf=ZxkH5=UdoZChT?iA?%??WrOP>5rM0PbC%^!AE_ zL%(AZ;z>e*eqMX+3o zsGn6oqyDk_arGnWv+6VI@2F3yPpXfpZ&mMC=hb`FyVN;#M!iLyP;XMNQ?FFls;ktC z)brJ|)nT=!o}rf1CF%+4vFZ`(A?g9@zN)PJQu(R!vhwfBOUn0^?Zsi@y&agmSRbr>OF;n`$P5Eo`U(27D|4jar{Bili^84lY%I}t+ zlpmEJl<$+@DBmUTl&9sb^0<7Ryg^&ZGrMl+GZ&4(QbnBPHiKUw`n&*d5d;El#|-EP;Sw#hH|rZ6_lH_E1?|MHb8l; zwjRp$+7(c)(bhtFiFP@ZquLrM&(l^zxm>#p%0X=vlxJ#}LRr!-f%3K57?j6r7ejfZ zb`g|^Xct1cNE?N+pj`mG{6B3al>e=*fbz%Mc~JgPI~U6DYUe=tE$wV5|4w@yl%La< zL-|Q<1j;|uhM@eAHVEbKYXeZeN2^2mlvacCU0NB+cWTR^{7vn2DBq!#pnOv6hw?YH zQ=oiMI|<4Mv}2%ri*^*0_iIN$xko!3$~S0-KzWaL0F-xYi=ezq+Yib+HI%|TG!@F* zH5tlX_d+pu4-`A^hGG`w^R_#oxD^+uoY@7%^c)m7WB=9U4k#w3q1dt=ip|@g*aSS2 z#;2gT>1HTy*b2q!7#*xF@Xy=1J!R@1%2qb<#P&E$M7vlk_^^kF*>ZBb|jD z895({;q#yvLPiWC?FW$Pb)iCslnSCG_aR-jmhdJPmu91q2-UJb?J$3k%^GT;!T|G`H>aS-xg@vETdLq6<(C=~l048^_& z?xS8P&BzDBap8RR=j#8c|DnDF+W&3!MfGpgFM{rWTK$CjG4%uLGs>HkyOlX*hjO#B zNx5FRQn_5YM7cmYM;TVC%2MSNrKlXMyh=Gp*YtE3cPV%NNV%%de9M<+6O5 zyhMJDe6)O+e4u)sdX`!TJn2_YQeUke323rNEhxWMeg;_bW95g+KPle=B>A%Pm&%_j ze*!r25#h0>SfLUAA8`Z1TD*&;OPq3-4 zYXAe)S_9NgJ*@$JR8MSxx~WGufSu|=4Ny0AaRbg)`x>Bbs@eeNDlauwLiyDOD3`L( zI19?pG=`!4L<5+se5?TqrF@_PJXYS<046I>HGs>?gAHJ_a&O}dD0eo1$I8~mX;9wS z0EJT4Hb9}23mZ$I9Bcril`|VBK-u2_ek-qO0K=76H;#ky*aom%Il2KnR}O0&4IuE# z2C!cKMFTi4|6c=GF8{P~7?l6p0M5%lX@DBa|JgVQ%KvCAhVtJVAOP}@8=#o-j~a`h z{I^CQl>e`>Ka~I4040_Gr2$GRf3E>bD*tmsf$|?4Kr#8-+8d$#hITKMf2+M7%D>S- zQ{^vccR;zI%|ZF+8tAF~Y3)`h|5%%W@((poTKU5oXs!HyZ97O`wQ(1e1?6K6 z(027LjSWz~sj(i)I~wbt+|dBFS0@^4p}eedIh3P~%YYEq&I2V2+vb6ig{gU~ z096Zv4FE#d)5i^z^o{U?vu;jDX{F$*F+Qa<3JSxGN5bj7oKBrD_N zpSD#lyK<7Yd(9ZYln;TR`G_Pxxq$NjUO6SE)1D*@%}!g{EP@uw|63FY6`K_C5}Xan z|3CVKry8ec%e{~z^t;&U{MZ+mt?s`3KaPeArLTDc<^N^*3lOg%642JM6oCByH0A#( z{~s^^{{is-Kibwfi^l)a_`ekWS#)XA%bGB^&?7ufR$!8Xp8=ChVVkr5(XgtzsC;e zV_#r`SN`IE|Na#(l<+5ElwU-QvGH6#V&S0U>+X90C&mAa%^kdl_(!? z7!gH0Pa|j%-ZF^f@W5CgyukU^nJPg*oYnC1I4uF>1SAUs&jiPVS^}xO>X_R`wbE+= z{r^Pl_5UpHM!||ULrd(WSnLZ-8Kf*4Q%2XGrB$3ibj>VUcYN3>F%0PcC%4#qX$D6- z2@N{3rC8}sk*9>Rlv|t31g9AV$!(*+(LiVpOPV?zzSjAjodhkh{f5{Vm@-I?22)1Y zKE%=JTr-^zR{iw|CM`;`^qhqMJ7s%*sWwxPetZMss|<)(Ew(nVLtH`gLF?r|q4B>o{}-~#PT*{vn}?6)AUQwy-EBzZIsf-hp_Lv`+dgry zM4Cif(y2H(wGv9ntex4%JLgK4pne1`JOv#7F8chbiGv$n@+JCZ3x zl~jYSc9ih5UsQP@V4!Nl(BT`ZVKa z28aTP&S&87vrTg|qk2(3V$=4S5F&JFhhhG`!~lH>VF_q|mIDm4Q8qOBVX~I2VYSl5 zYdnAp!O~4GY^2Z0v=&*Q8w)>1jRBY>v3>sh|IS=F5LPzb);U&G^WZ{6d* z_~4kf3w-~htd`*cSK$;}$KP3?S?R?f$Rd*$)jxQQH5^7z2QmVffp#Wp;6@juUU;`kLh2; zIGy}|esHotY4{MT6RmPDI!tf70KzTKX6^rDMn9#E_9;yt!vG<@nk?_1GTV zZy!Y-|F8G|OMd|RFCPQD9Bz$3pwOqFhD@JeP6V=2LpfZwBjJUD=~U z>zKzzbzbVL#c8iFMz=@VK>z>FQ_@jB!>a71KY5hRN(pM!Z3^caCE&v`Xu1F>w3eHf znP$?_oX|7m?n@!;&}-tMdB{g*kjxg~sR=C-I{a{F`_{It!@K*`BW^d=%ddR*t)Vv- zq_k6@r4zI2?Xfg*WGqw^+N5w^$PxNo)MXjk6no1rqW&|23Y5=QP)1T1za>Lk-bni_OUS7Y9A;po4GL%C@PYsTb*|22 zr29JxMIz`0iey}WEiVe^KP=r+W=?oREpfmJ2r9 z2wI|=u)Hc<0D$=alxzRr=>Hp**d~^7=yI-T- zQ;_aoVUY|EGAEnZx=^x31%)Qb=I=vrq_C;%e>z9EB21XW>dg9UeUx8BlW4dfR>^eH z`ocVbSC5s)*29{b>-#R~D~_MB$?o;Hk0ST~gK~WfT4D)>Aefo4u5~$RzHN9cw69zr z85yj^Nke$!gm~9zRAX%Qzz3m@Uf>YeD6b0y(RJxtDvk1r|D%9k>qNmKLKJ1UHNpX@ zPcX*$LVNm2dR=hYZAH-V5Fe+M2T~aH{~tUpA~w_G<{c@U)c-d-ZoT3>P#jVfg*GW% z6wB*6Cs3=MLSHQp`xuRmgBJ8MGK7~@e7Nr(lSmO91 z_wm0hpDw|F+JY%?-&*aB1?j<45r(YIvT^W@pbKGc`0U*5)HJ?Ey0pU_XdcB4FAr4* zhsr+2$5DgINVPf=aIWc4KKw{}qi&%FvD{SelNp?vd&U*V*ZM&C($c>EKHa@rdR1Sa z85WN*?)-GiD*fu5&rqATsVKmXX`9pl?KZoYY9^R`=OrgqHnXZDwYg@Lv3 zszP7i)BW&$wD8>y>v83N9}4qzf@8k+{7<^Xan&{E|4d5qB)fw4=~LjoBO6jddZ1#< zAROfkI=pq!!=*tP2I5Suu8c6HiG5wy|30^OJRmNmf@g&?{f^F~KKhn1!+1ptw z_MQm8t{S^^l%00+OD~;#4W4dq&Z~^;jhlIw=C%4g`65t2e`dhNLJ&Ugl`b8<1|YEr zcap#B=6n=W6q@F$)yvi4YHe_Eq*@-S4c7;2@V_=xA1n{mYp{ybaJ5pY4-A!1p2*j< zaouzuQ94uMgDc;McaEUftxFVu1T>F^8A)$f26k>y0R8``yorNl7+af7afEHrKB6ue zn}4!Xl+Ze!UQed_&UGXuku4zqKCwxlb|JP-pGI-C}Uq>UYWo5|M?Gfuo%b% z!qJf0@2tp40E^CWfMK-I3BRxIb*JFRa>0Ir!^r*r82>BMwUYc86sc~FdP9LBI}um3 z7%o?8gVi*q1YkIkAl?JsCdufW6+5M)a~VBgeUqi9u5HK#>60Vu8-34-y%>BC4Gazs z2d#wbN_C}U_$&3H`fzQqK2n1Er6Bg$O0JPUNv<#-YgwgSt5k;u$^+G^V_b*h0U{Nb z>CRcKY(qL^EJ3vxu7owt%Yh7RmDdG4jluW-j-LOM)=2n2g>BEWhFXvw-iYL$2QXxkX@hgmdP(qmj#aG50wF_EQ!#moK{NM6Pn`1SNzP>n zb$-lPWYCk8VHgraCe!D0NaZ@0&!4rVpA)$LN<%KJYQ#&@#PE1ein1k-g+s8MfE4gdev@tk%4DN8Rb&Y-pk1V_4|6h&o|GgR? zlGgU%rHy^yWl_gj6~F^uR*@qhNN$MUw8;?wcku@gjy4L>-~UT&%{5zrq2EV+xAZcr z+LGnZceKFqhb%vDs04*b+438fw%zt0YeD`$@Z88XaPGF?uCPo*$HsZSxem@JV~w1h zArxp83h4TO9J>DP^#5-}|Nlko*X%$YtW z#AQeIJ6HB|qD>_2Cw^?NtvdZY_i-qqbcYK4jAk~w6LLzP5C(8-K85S}Pb2%!h!VaB{Xc;8f1%g)9|2Yes~qTmx#qtVkuwP5)&wxe9F>-n{)el* zbq47Ffu#SW|2fkCfcPKX2_XqW`fq7+a|fXRi@Q$$W4e%F_~P3CVT}L7BaGS55eh<9 zF;=}fOU;6XCT`a1`2Uem|DW=I&1rITSAqT?l&1bC8BYewKlg1|?HITvLcZ>!W)M*0 zeYuCjL-ma*7Jd+v%R8W6We3z5(*Y(daMfki6si~tObohq9ud6k|MKOi3c+&ZGvUMF zx-dvi1l;3;U19P*vxOy~`p6Qs3nJqh7G6A={T6sI@Yv$>fBagArs6si_+0Unm# zF>lM=HI$^pqlE=~uGPYV&7-}04RZQOzbC&U!ANE|?z8fI{(>N=t1jHe{GW}I^koT( z)VC+c8;3-HO$hXv0bm66SDUtC$F3Q3(M)WsA@MLg?d6A0X&hXTo?6QUU*9uc;Riv# zj4ryN;q<2;`}WFW6&z8SKev1<9*TrbjW?`UhO2>ZL$JCQLzIGRBsMOYQne5SeSNBk zDin=*amubnU-@#09`m&+?bm8%RE7Qc#S@;UtH3Ii|JS(2(?N* z?v8xJ^w*M z2Mb3$^(K_fl4nl8PDi6iK;&5Im;?IY{%gqny+Zciay>wE^o^rmbVCVOCN)1Eyw>j; z$(Cd!nehOkoi$B?0Ws}=G_@0Lb<|H}|C{ng!2TcJcKbgBZ{4g0IfrEbL0Ji91sY^; zJlvij*#DoA{U`hHdYQpuUOU?%nSc*s70m7|8Z7UkjQ0k z|FaS57RLWUzI8T@^NC%qg13Cx+Llq21pw9#lm+|$bJTxTzFbnykUs-E+7eRWGpia$ z6{Nk#>sE;s92Scig#-h)#^8lb%0BS8BU|=3`B(F+8%GqRJtwk;>HBP2m!MmI8D{hc zj5m|zPGf^+#Ml^Q+w{=Bh|u90Bh@OrcDq`x4GzPMoRNBYkRuIXz^@aKy7NsLzO+4< z+92fCP>m)X&>*I_)STI-43BcB99CDHpCcPpL)yW!P)!YOT?-v7CXt~3dmSSfb=tK- zDxWijlcbW(jTN1RpniJf8NcFVsHo*xkvx>Y*~W=@7xj}P`o_zm^uD8UXieSIQxSao zuVDXMqW$eOxTGd*!E+k}qAG@XUXyC#p(47_`6sDBuQ>e^CW%bBJTexJ2#^u#Bxmo) z;uHQqdv5|@M|PD5SGU?gW0@t!aSS0m4`6rCXmBs;R<}CXw4}DwOiP;Sk;WbyBcvI% z86&Cf9*u{wjU8HM31B+}%p}Hf1PMzB@z@ENm@EW{o0!ERaeg2x#w6rV@DGVeAS?RM zxwlT$xvy?5x2kR}@12tR)qAgB*Q+}BobP;RxwqJ*!zHVYP8VMor<@1(;WW}cX!5Z1 z^<;=lODt>+0sEgwh)|zdURISTL>u&>O#mr(HxCDoY+6~-S7ME9MqDA|>5w(DQz1Yw zz@QX<{Q^5`nn{EGPu_TR_xhD7@_OV& zDkk|d{v4(-Myo5v(?9OJcwrjv#~N?9@fh*TgX4>fD+dp)pS*Zc{Z;s2%pKu3bG>sX z`tw(u+1TC)*C`=EZf|U!JGG&4J$}qUk}iNp!VT4D37nRb(CO&-+OV~BD|kx%t=6vs zw&iA5x<9v!D`%%d7iC;f7I=XDA3_1-E=sX}ZhhOcz7FJdE)V>F5P_W`qkYhZel+oe%AV7%Ln!GkJoej!-w-uH(KMl8dn=- zoO8mryOq7DhcN)S-yx(WFN1si9`|llthJD(lF$hY@U?*l9N@tIr_7Z-azXCY#>+Rh zx7SZ>ZA6Q>r61oswmLP!nzE6LcLBBtb#72vfU)_>12LZ z^YAlfakht1?Td>i?k&Giq043k1aY+RzNnAzOE1&TyeGujY&Er2_;0|CvIq5(LQ5 z^<3g%r&djCr4%+>E^H!@GM-HEQdXB5;dx;HpJn)e1bXikE*^o1ndH}9{E(m+wlY*L z<5yiM8c6*gBEm97gSh^$?`Fo4OVcBxs3z=>n)3XkV}{9P{7S4*>i=f?qhS62v)$^H zjNv%q#3+MK@9l+vlZpfYk+LAC?@s) z%ovG4UzeQ~5K#r1P^rGX6TV6PzYq2Q!)E?A7v!Y=@2}NK>i;ezzQwc%fo@nlVXTEn z9kCaDZKMD@RXRb>km+5TSi-s(^UF=c$3?w1^NZe-rx`SURJ77rBONQzQvZ(`;pFEO zzU`Z6o`2dU^vxR=eN7+c62wb{< zaT!pO@hd4Vy5uFQO&>d-?8k|x$yO-!Ta^{;|MO94$wT3D0}pCL8sn%AC^N2(U93^r z0V*VJS~!cJAaTYMNsxzz7e0wcNA zUE+_A+s^crj-yk;*VSigHF4S8GFvmf1Zw^7iBAOZU$zmHz>iPu|Ea0qH=e`sBHfo( zT94SEt<_yxO?IX(+*i*gt2k|*JGZf|V2624LLE2>s!((&{RG?}%zyF=B>%771w3|S z>}=;@SX6HO#56OyINMRXshOjxksZzdKQF?j{*{kK&HFcIaRRw}sT~_cjx_Ls|NoP2 z7Z?v;MhwWcQu6;Ux#Jdl+A_vd^8YSl*s+XbTDt&-MqvNX$32TwB>yi{{o$glfVnPCt|9^qx|0VygD6PRWj?M%3e=aJ_5P~&cso;o8 zNIGk+~e|zVP_P?+j_y0bcG0#JHbJl9H1_f=v+i8A{j|^!Dy8&#f`jF1t|JyXR z{*76jtxv)P`2QE6&5Qr9snfJYUs9`Pj+*~p%mCvS$BbbMx!x52fBezQH?PjjA9=$O z^)t)<@Qqrou<14tNmd zm%QUk_y6=%@Sgh`_`30KxYw=$ADMe#<61QZQOuyS(aLZkEAuNWOIb%Pgt9eK5Kz}I zhM$4xk=7;Aqn_kJvW*Uq*Qf1U$*~QC4CC+WgblF&7lObH+_YYy#W>t9uxWHd2i)Xk zy{>y&+02;5)IISmkN5LGC?LL8dB3)b3hsAdb?MkbUR{U{87eStOo<&s-3;EZJRXEf zNcp3PNxMP5xL8)}aJ6&u4KfAPso@+08(JDt4+zRlYUp{MHA)m7-_cq#2sUKO6tk?c zN)+B^;63@JQJSY=gXk@3GS$FWy1l1_sf)8*qky1-`)+9=EX{e+&zoEc=wz9w2l)S& z?OwlfZMU_1$@f&v=L^@9y2nIn0^ZbAyXKL?9XoWx>oh9^`~UJGnwa`h&&$bUk^IjK zsD7(4ohCf#;F?SNa-9NxgA0o+binDso~@QcFbZ%N18kW&Wxe^JUBw`q{U4g5p=`rDl7pR%g@_(DLRO-e0<(QL@-@gn6xKZ}Tg{l6H`kD--gl2HtdQR8 zwlyk;7o#biwA)^|CR(MTR$gESGmm9^hlFpQ+iZBD2m<)u-|a(Rxc_ISf={g?W=3185G(cg zNwbtzCT0ap&}1?lTIIHIo;HJ^h%>~b2QS86WB!D%TD_JRX}{T~7Q zAIubTC>ciB?VOYWt8Ip93Txe)%L?Uw%4dizWWKt@q%0VP-4^*Oqies61onTgG1R%7 zqYzN=fT_*0pw#~ma0K0l8+-NL!|hS8f@pXsAM$mq=_4(?#|s7f{|elfzu5Bmi(>Ju zeURAsj%dzFxK>TG5j$p$7A{~o;8N_gG}pqMfB)OCh;HcGhN@#wnWO%qhOGY$ytd=$ zlv<;xZfdrAUEk|}za0ede?+&R{HFacnF@aQZAf#XjqwMwUL(ap!$fk!!RjgKXiU1y zLNoA=oKG0-GyhIkma1&IX`S-qx(~X{OZwx>x^OAee%E8%R|w z4bVFPE_PYn%WiOfOX^U95=i~8FZI7guzSf6k9CHaaaOCzH=C2{e?F=|ZQ8*9kGi3| z)c;B?w9wFe&MN)&85B#pJ4Sc@-xBhFf_;2$;DN^!MPC_mp0~`+nH7Riu|}!?r81%6 z{spQ3sl1A{{x?x`T|?@BQvcgLZ-7(3>wlBMO|1XHLo?gYoY{ZjRB-2c$TgxZm4H+# z$U%5>4C;RassH&}rBLdB-K(dC+t-kg>pbbYq35|VVM`hb_K&mX>73C#XUaDn6dS&b$X2vc-MY>hCI>7%m8)uT z`k{N($G+xPu=%H%bFbG#!2XXnYyEBNoS2DTl2*#SV_oiL6N140*9_!B*Ml2l1f5{) z;*NthvK9n6OTW2>E>hCukJo^6FDb-*7{+~2lerf z*K_>Chx1O?Sm%sgyBb}1D9DFK8Rwkv?QRm>^z^~;#l@8aH2`aDo1Wgh0L!*tnBIJH zdit%=$8W>^=m4Sh>sOrF*xm@&rr8VUsdN$GeusdTrk&zmzvt5M-#oy9{l64Nt<^gh z_M@FX^BF3*2j zrA+{7v$0XE(U>s949tCt*vsATUbs)>Qly*djSs~$>bOA!TvX-cpu(9yq7qqnl5VSw2<_cs*p_`bC6g#a8fiJ2NvXl{l?N)okdWuG*%-{nWV|L>uR_XLN| zP5vhAWb2Fs-ZQ`dWmCaVyf%(C;2EJ4zG)y-rBxC}a{@R}+pm85^8S}j1<#yrK#1^l zr$78T`*%$RpMGHjUsuDJ!5O~{e$LczsCtu<{u7eougBJ3Yuii((%jiYR(jl91_}1R z2@+xA@LvOHDz<6(vbq=7Nt?K4G(s(gxDqs6?w1 zxqQMx-~4*4uwsn~n9b{sIkg%8NdfU$%KpC`O?!!S3Z8JalCr<8R?ue9IeFi5*0Mdq zlzl?Jl}uXPpAqXjxa|UF98Sne6!A1qHaL`-au_qFJen*S`2QA;bfW=4_q4J`lZ$<* z%d*4#S6Y}n z2dj^0#bA=Ft`$~l%iVx=aB{h=#3K@qlx)_sY9!P7athgRUjz1kUIUC|W^9=m1&k5( z8%kzr)HDE^sgoxNW#3R$VVPsG92L$#@!%^xGPnw?wf2`%zIzmGHSC z@!Tv=$6~QO4eAB^%Nl~_o0MONIH566C8`My>(5$OpM>!|-wTX=)DlH@AzVx#G+DG^ z%?a(tF*MDeFy9N!l!+LPub}AG*PpsVWBv+?FcD!8uKhSw}1F0`(Hj4{PH8wSK$*sUnl*Msm=w5l_tR@K14&4 zIx4x`vc-tqi~Ca&@!w!qFs=hLf)&Un9~Avgs4i1k(QhUvZ zom@k+fazI2BG%|K!+$*T+F<_=#XSYc7jR>AAcsGgAJ$x%xgB*h^D|ioY(BTGDlQrT zRq}(duu3Mx{xorz(e5ebcks6*E+%}QhHua9;I4^;HZ}Zw< z|F4)|o;zA$;#2-2L*5n`YCpHlu#P~px>7dXY=)5h!YJf1!+U|`cJ2{i!{YG0Iw4s( zo02mt1(vfSD`FCssLBgy@Yc$)hGePxrQ8Ej+w1UcM)VHOP4h0hL0@dG}9@SW)K;m_y z*;oEm7EbZP{OcSu2*xkLG`bfzH;wL<@ReVOm%z+yFcUAL(7m2^ZfbPWh5_f6$HWji zZwS58$UFj^tB|p|WiTzTU0 zr!L)m?E2N+CvJv+1~rtk+oun&4=?;9RhD>Sxk)K^jf4~`BCVa8dQbD|qqQV#I zow^<*{>Rv%xcf%AD`@s^0o*}UzBS1d68}4~o7Uog>i-G;cl-T6(E4z9bFB|w z5A8;?(rzT}Mry{T5$@F!v3I`90=WMp@bj3Fdo%=5s?=4JqgVJT+Bvq`iQ~_51JaeY zMN`A0+CU9C6|n!;4GX%(yh`UWvsYTlvTbBZ2E5nf=SC(MHja5Pu>WtMY>Z`ck94L< zXPN~?00mu=Of119t8sU!!9>mfzb2h&3ISCLny|30d~|#q$xN39jReoNvY9r6)!t^M z!T(>E$)@Een_8TsL9t6Ir4$R<9A26KKOA7y*km85T@loSX1e?y|CB`w<@qC6n%P2(*9X2rWN6))4Bmtu`2 ztx+;CA-gX%HxTT9kMnoggclRM?TP>i?fy3nqUI9%K^< z6qf)@*ErJLbd8%oc6|Syso-B|P(Z$b8>JNSxxpV~by!0j)+{S<{~Pf0L^shNhZHK4 zev*@tRHhIw3?3O>Q-X(wRNKns=6=RZR;4+qn^9}-|9_)7*1k+G9zHXnX1o%uth4yW zjGBx&-z)HJP@yq12GD#_XQxWpE)_|vW+hg^|368oJ?a0~>#ua*0h(4;^p#lSUfPl< zmW6jP6V3p%x>AHywJdAQutat$RxB^sXbSfKjneMpyJB3^){P&g5{n;^3NR{l&U`SSVJn$VJb%N zGDuyWJPy5A*~p4jkWBt$1ev9X2`{BqU|zk2Ml~j0Q$Ag(6CE+NVIbTlmchFsNX*>Q7VhkQ^E4qz$~WmO8kj$>TG0R3(ar zuP%>HGp~dm35e#bu0H#;>aI0pR~{F`c(kdud@cFeSI*6~iy2 zcXmRD%yyJkz`cH(ueUl%4dn;}qmQ7Ttg(4Z1pEJ{aa{K(GRUMg=HYp%fTn|;i<}e1 z_{IFIg!FR%FM@Kz9hw#(nO49MFQCDX+H6QKS=OO`!a@v?DS?WHOe$nHD4GY{O{-Sy z0iPsD_K{`n*!tgJ(Og66+hG0gdu9Falr#%dWvdIwO+-kRrSn-9;QnudpFd|{Plltn zL?@azcK%8eL8)kG|Hdp%ZIVN@^DY={s`WQ^-$u^VdWDx@|KDuV6kiS@9=?p^iD;$t z|5}47Wz>?DHoUVLLZo`bvxTv!}@m{^Mr6*s~8jgNDzWokru+GFPAEW>4^>T3P(TRm$w10<5n^yp`%VVDmp+?Q3d(jdNk z&;bAc_FgrcNoLxWX(8}4ML?>CTS4l!Yh;Ju@1oe+b7mS@shV3s^t9+ii{hV?DH+o! zEb0G6wH~-m4x1iiMpmS@mVO^*jbw$!*O%gQ9PFDd7E1pwxZ1U~wOROqO;NM^E?$`4 zd=hbXdio($g^Op`_GV6Q<4Rk&-ByODpTpz9@x{fJ1GU(eK8SuS&hp~m0+XZm1*zZ{ zuqFC`zjgP@Ol6IuDza3eDB>Lq>pB5BB7B?e_e#67( zGTE4mcPP=HlH>>b|MR6ZzZ!-W$|?aYNus}a2&j1%I)U^M(7y}+@jv{-PnQM_^hEg# z)G1gU+F5?=V*tOlRg}omH|pN5d;PDW%r)gM%@f z6%-jDMb3&|_(}W}ibDOvA=y?}ITWTLdlA+AYWB86CKd0a1Ux*^??y8z;H3mSrD$LM z#!9yjt^E!ZW4R7U5fZ44LDvCr{?DPwQ^BD(P5vF&$tDtTmcR!#_vc~W*7J#0t37k^ zW+AB3%KSiA|KbNkurCPzDQX~uZ|E}eQ*)!)Y z*rCSKk6({Lrh7iZB8fZ{ErFmJ;41TUTw5{Okb%;wjT|7pForLe>{YWyb}DoV#@BZ& zPYm||7qq}!q$cIN`a3u^B;e?zZdL` z&e@~M#VNmx)R$;wom!cfi^^5XLSvROoRZ1xdL|R>|J_mMM-zGJk_(9o1I40&hWbli zq(!Wez>#`Ae7cKj6I?9Bp_6q5u>bF?Wnx6A`PHP>%_P%=b4Q%*4`i{K(yaky5=^rG z7f3CS03KTc`+r*2|2kYc$&@GIrTO`zbH_6JE3{WI9a-u z4de+!EA&P;t&yZ`NZ6|-g8hHLYX8d}$BtQJUf^9yYVLveVoqq!PBXNmqExG!xzK6> zH~n>Y1Mh~yZbZ>?)1->qsgL{|wd*SnMRr`%sp4_&sz4Gzl=Vg zaZdU(wVo6IT4W=0(Hj|0w21GWhyCD9SNC=`u7?sHyyY!}=x+y3*PJE1=#cc~(Hq5{ z)GyXTq8dIqI{PL>XHgV%4cc~2UhtK%LZhU*DP8{FVSWGKg&_EW03M2LPhZ|&oC=;f zP3}zX354*4L0+n^_V8DJ`1Jn5RPZa$ZQ$#q4>Hxc;IPhw8K%UCXlPQEAeURV7$b~v zmIb)~UxJ_aiQXqvnyIqr{V=AtZqD7yF7m_|>5kzCyPEF?`~RyjzI4tC=LL-~-*|La z7vgfqEpE!|o>t~Xi4GT6D5;kC&?sfuv{h7~3k$1D#}^BK4lySP|C63;3CW9#NrK-n9PeYq-=5*Y@P z>$;_XqI(*-uySlQYpt!=(BhVS8ht<$4k6hpYp6;lmID9(!T8AC6ImWMiJJFs%wjdq z)?%*m3EF_}6*p!djt<@$=8hZig8lzBQ*ODQB_6&635eeit)#hXrgU59I`I&>Jj)9m z_^}EYwS*3aht5@skbT-h2L+52z~kO6hzI-s>mFdV#>`Uzb!wQL*LZQeXG73j8Tj7sTHgPp44TE*#>G_QGHEsn+m_qTBn<2Neb zOI{PaJ@7V&z4m*_XMj}~&`Fye(_hkU!|#?dH69_5(CO&-+W3Za&+eT9KTE$Jgkg&o8NvdqMXXlPPLB^^c7pO&4@ z1>FBO{QL->5Q9ojr^CO3uGGNF+{A0nAbHnr}Ft8?jWu>T+J+-+I=H*RrG zw0r3a0bZ$YYtCWO1hD_VfeycW>?98=W0T8>MKgZYg)nt=yJ2!EtG|>ssxuKxrP>3R zY@xL($k;I**^Ro!%Gxpi0QUc5CjGB^ff**3@hh=L7bQjGVLFLgjvEafJ~#B!vo*3) zp;IuvzEqyAbV^&&*-m+^$-jvmzy}`z6j)nZn}r|Prl&VAoVoAfh3U;FQJH9ibb(}= zZ6#JO7QpEmjR4sfzBX(u-NZYRX+{dlTg$zROzuZzP6;s7g&-LXI`!V4nxmP~cq_2{ zM~`krGjdEtmqMe||H5KB0!+gY(|=S}^}paJ0{q{X?L$ZQm!^VGy@sT(_Nk6hN?Hc+ zOO-`#Zjan?@8AGp{~v~*_fx0pV5YNa3Pkoi!YG>EL(P`@p-W6uzlwwXKcm24$im3C zrn*&=hMSQF;>(QhL~2Gd(TrF)aCHB&I+hfc<~a0P`;Ub+Ja(Vq2ZWNd2&I^+XAK zbf&}5x>l0^H_K-vk5n#X)n^g99e3vForGp86(F**9WaBoa{(d zR_Fi!TM)qiaoPUX>-U$Zf`5IL{HWS95@#ZV)DH}PSbqvi(ogYnlZ~=(;QoILetx2s zPFu;jQ5nUAk8&f*oeUw9m|@>@ZXGOkfc^g@vMiI{*2;9k2+B`AK;{Gr@CxvjFTa8P zf5>!Lxdg9J;#{<{POX$;2Y4izELCt#5A@!=t01e`0rvk>=%9&Y;&X#&mgBEADs0UK zk8WLDMnxmzS5kWHap^J7G)g5UOLygC&TrHvOx?Ky7d7H(dBkbjZsQ=*i|J`u|0@h% zbCW2gOpPCvgkHjXb}9ca>wlpIjphdHe;t$czkIc$_B#Cp-2d;u&rgR7J%*@h;U@rd zlp%y^1GupdRlq>?rzu0jzk=Y^;O@D3ie8V+h}L8}m;sMM9QQ|M$p(VNaHZ zZyDCsdKw@j9PZz^#VOS8WjAU9-UAB2aIc+4(VP@2Uw0L;dn3l2F^SEv-7HTD_W$?M z*4fm*3`@)SmE@!(CuIV0>6}#m^HBp+5;jOxMyIRpjd5xVP=NjagTi1@94PqpKhQ|L zV7a!k*EL!QUwqI6-A8kJMNa+iAA*Jm-|E~V$YPD7X^nY~s#H;;G}pqUcmMeo(G4AQ zszg48pY><;J25Q>F`KsAc#ZTz>VG=ffRA2GjUSbSPGL8`HdtqR+N?|Uzu>n6{6C`G zPkz(>%2e>XZ==Cd`_vJW={|-6XXTDi*~9611i+!~Sqx8oxczw7?c(A*Z3Y`lzjo5N zRAozt2lb~Zr7??iOI;Sk{vU>)pOyMwtOd2y|9*~O3icgE zs=ldt@#=l|a*dqdk~+A#7p0X_|7$a?UwFX4|NlJLz106UwrIi*kpZ8)4v8>Be?nlg zH+*djVJ=Y&nKb|<{ND*_INMP=1o!%F7e~}=POAU;s9x3o{;{EHxdC5pO!QO0NV)Au z{m-Q{z|S=4+(G-$hfbc~x_I_nN;Dze9m8X|IC~~@t*8#6drtlDBj|0)dmi5k+dYQN zhL*%uGlZsCA-yfuIBbmzHCp4`vBlNJ`J4m7qD3RYwJ_)3f4)U@L$h2}#~{L6e^FyJ z>wkarhp_$VPyO`vM%W69`i>2X_!>VK2L7h(Mm9*pgSGyBJ)h;@T_cHXdfQLi+f%FeQ-J+{lqnSn1t6iXn0ox^v6bbl zcu*1+7lv4BuGSawgO*T$-s(a~Aj^l@5*A?pzo;;pLzf0^ULeX!AtHTXxKT6!Qmn&2 z$VmE-j4;|aXpKs%s1<;#l~|+A8VgvW#aSB+#xbV>_Ww(ITuM(N7>V@Z>kub22C5_o z!J&Gwe&YQ01tT|7;YIcI;q%twZF+k10u-VyOm99pJ^faNsrYak)<1)D)URK0X2UJ3 z_t6L{;wKG)2H}MU52c;l7u9S5TKjoqKvFE>)H;&Y!)q!gGO+(&zJBG}?v)uw;7E#X z{oMN2!>`&HT-Z2!|MXybP5pmp{p7`qXV(VsYWn`|_0wn94-apHD^EQB)TNt`UB9~f z#7%5O!p~YiZ24fV$3J|y$l>Dihts4^4=+kN-jJ*m7%||p5z0n>MaOmuEht#l`KHqw zSo+xs4V>-BC*oeeT?}Jt!k2M^<(fn`){xBT-0mLuCG<#y@2K`QZ~46LAv7FthI=z7 zx6#Gnb{o$^KgGvJ)^63dyR~^X2yTG?|5)*E^_UJOo=Kvb`iJXCfN(lWG}H+5RLU+Z z%V|$kd&?tR_z$SF|MX5m592qwr;#0;{RH;^PjQ@dC82vF%flv7^Zt!lTuta+a<&-o zW_1VlOC!Plf7NtY^%R3dE9;~K7Vny516fKLn_TQ4U7mFz`zIxXk|l$z;vLxkKf}O- zNG3ivRIA+!smeMOa*rZ6TdaF7yKeTNo*hdto@h5 zG=S&PwW@vU1-CN|09eewf%E*z9-QZ|J$-rq&rSu;oNhp#AeN8A{eRZv{y)AFk^Ktx zO=f=-)Z`6b@?VOJ)C7>qK4jcf8o?M8Nzk+(68`j_8JTjOw^~x}ptXb~ zVE_LQSQ?!(JoROAg;G#GP8+HYLd`pE+Mpy`eZGc;(zZQj_E12*+l5e|V4`AaZgF95 zC1cjVo;FfJK^In+jx8L`_y*JtHoh>fYGbx(I`G`oT&QkYi3+6q*p{F+t-UI^UgA?F%fh(_{QX~ zOZC4Z&icl(*enyzD)^&Z_u>1p3Sf+~nNPf9brmtBR^Mp7IQ|vncHLsHmS{XEFr6Q+2KQFlpBAoY)2J2&XZ2-SSxAk_ znrn$*|Nn~kzgVMI1JkZ^MM(F+kw|z~Ph0YAjd|u#3cpG>(Db}{2JHV|L%=|cLmPm~ zJ`g0oN+;=K!b~{r&BG_#Nr9<@Qh|iW=+_S{{ZzORHIJAGG1n-O<91NCB?22-^7hV z3Vd#8m1!osMxzCOHk@{a%z@F22a>b&jH4R58V^8d#v`DVv3^xiNSXhevZR1klxY6% zza=#+;t!&=0L&+H7z3U18a>cDjV6?ABWz2sJy1k@XJ#9;rwsrdj?jdJ5A`F}HUXuOjAzf0{6 z)AdXr6;4%xsy6fgS*x`8p~ViC2=@O8;{THWm;C>xg-mwL8W}KH9hH$DNxPmXZ53us z#yJ1~TP%en`G3P}8!x)x!i!P0QWn68d+cx}|F2|0E;5~&Oa9*_Yuz*~SIYh4AEOp% zC1CC+Hj_eWQOW;PV!!y3&lL(%lK(H3|Nm_xEo7xslC#l#(clB-i*(Q6h!Pe8-g=ZM ziTFYQ-@?$DN@%<)q>&K+|ND-vR9Cb-B#C${K5#xSppGC+Qh=wt;A0q#`J#{s_1b*E z{{I7rLsEZ|`b&$+$_G3ae<+D~8!jtE3PqDh@gQ{J#^9@tLaiQFu>apNx^>)YwQ;4v z1kR$bx{y=r&y@6|vz;o7F<>CwG_j3>5}KjA()BU=T_0fopGsH4#(ugbX9o8F|Dh#Y0|dhhRlPvd%8I@cYjm+jDG<8S?`m_Kc8!pqyUPkIx}^1C z#8Z}PouxDRd+7;3S*Z(=vD8BM3BF{-&*F*0+{BO+3!_@$7#0hq{&!_2BO#FvaRq;) zIZ_9`1prifX0hc8c3GvYrywo$zXJ6?;Q#-{ATdV#Qloq7R%%<;m`Mi>ggV@au;6n; zD>86aeRifRv9gpSa)%D=|G&bA*jTrk2^a^h?B8SyDMz>@VSJ-sM(WJne8B!cedE!h z3%C2ew3d>f&3LVham)CXBtTtkuUdd+N&D+&?Y)vM%Eq$JtXO~whZ}RdEm176|3BcT z!6!zFH74v*tkK09r5xcJIaR~266FZ6|NllPWCVGRp?|Fki%?5dg3x`&hAyQi3~IYuh?n_FpE6x^)C&`_fphCyC|173MF{i8$NDp+24Ew~ zozWSj4~A>T7fp@QtvOSL=wqDmX;&@$x;(b@Z=|5Ai4W=%Ry7djSLW<8%CJ!it(cjw1E{3DkXQ{$j|}*|D&1Q zM(?;yF%c2RZ;XRhO77l@>A8VLu7(Myw_`qF|Nq1E+=jcz9k&=6iUNE8Oh~2@gfT=G zXIJzA9?CP1YPl~{i4~O@_1ry|b=kZ<*#G~;)I|C4&?0!Nk6_vn=_70Q>)6mfSt*uRUc@ z=3U9%qmF2r>j)ZJS-n_*9rxRtN?;NQN_V5Y+;Fxbk-28u6N$>!bChVx74EU%q?Cg< zJaKjJsY|;zu053xO!Xpk8N@RF#uLQHB!Y!ca{q6#6Wo_xkWTvli}nBiAL;*3br%t_ z8@VOY+etT>!D89?k71?70mWk`H3XCezrA;&`~&>||H6kTB3H6&F?=5ft?XX{6yTBB z8R&@Gn9k%V8GM|5IAwwf{|frFp}V=cXsIE%n-AFkA4~r~C}@gSGQBUSlyQN?C07}L zw&tv5sRV>%ElVaKdeQ%X#{}nCVT;nN{y8)l&e+0Sp4DuParnQZLlFK*Iau85_jRL| zSYt_R%)|0=tRY~M%j(!1g`t&IrOdeA;&UU9R_R5}HH6j0Xi?u?BL|}BKx~@~2PHK( zj;XohD&DEAL~Gxf!)WW0oABJO5a1rRdDF}IA~AdGuV4uR(UdlisX|nfQL?Cda(q1f^b}C%GIFi4u?QZWg#%tQPRP^ z|MT)H%zJWDe;kGGOvZ~U5pGW$RY~g)6BFteZcN9_G>e(gurv#4wy_tsc4!znaB3FH z9|SEEb*&^GhYK(G(Z(H+>3lMKW0F26dZ*LQ2fZ(D58<#~JiE3xb8;KkB*g7Dj*EVZ zkJw|hdZ4B}uCZ-8-;q1WQLCr!F;e;e;3Wb6FR(qcw7)SG{JY)wjNw_T*;L9-re`He zFTOQPxikc+9l(Ftx+8)2Ufh5ARPf=K z5a(5UVsHuKD|r@^)aDV|E=O5^d-~$Jpo(nf=pK z!MmO($_Ww}3?=>Z+;DCRARfO00Z&|a*wHM2KeoUZcm{;jBNeuC<8_Z67EHFamT6+^ zt>^L+`c>=M9vlD$e4ZKd8)#FCG}fyGzT2gkCRl72Eqta^R@T1+Ss8Z=L6AnYA8B;s z@EJ0HjiUM&d}^FUS-NIA1@IH>|MQL0&H`n2@7IWOj-A9RNh@>iX9DZJtJuKb=HULo z!aSH)f=5*V&gGS*V@pdJQ+Ipoq`?0Fgc81YU2{-~m_#w|ShZ`%WH~k{>zHv?7g#B+ zT$o#(U!2R(^@L%e{=7e9%rvg;C^a)4ss$)no+_ekOs#X}dFfX|0K zN%l-84}$$aH+g?yjA?5huMWf#1qjh7x%XU+&o!Y^8t;Z69YbAzjEGwP();D&;b@E! zf&G6$={oM{(jo0T54Q^3_{mR85l@Y@80~a^8AKtxw<=XC*nb<&5w4`~A-Z-gy z%*!opnwQ4am(2_tL7^O^q)5z`aUI2Ln!azX5b`F)G!!(Uvp%tb{^fL0r&r~3vi@fk z>B--U1ZtMRFI?I`^Q_>T-?ff>CfZUtUDSs|WEB5|eVQT{8yN-e|GDtkmc=1o)Ua1{!y4nC;Uz@icHF-NEOE{^X)rsraa~x$zF=#a+Cb#mf1Rnvo>f|DTSm z)<>?44sO9FRIhIJ*5k>t6Ga2St-L{unS0mbsv@uk5JV_Zw5IhuuK)4H$5xgXu;0@U zhfeT`bat4lK8?{LZt^Bz5}t9KVE7<_R-7_0N>n9`6-pH9WEuAj_Wx%pPISs;g|1Gp zc)Nf%S`=A%Ql`%Vl&WUsba2Kr1VNYt1VNZEN-oD(G^hgm{}PDa*(BJc#-m%Vrt!(l zo?Be$4?()na0D6Ti5&ukcrWP_&^yBtny4L<)W@XZ2<#tB(L?}?Uoy-!nP5;g%fd}Z zgGVplyn6Go>sM#ykHEiKKFB8acbf^+fs0Kv63qg8^!2B6yhNVAV$NZouQ@?Ee!nCOBjSKC53z>R4`eLY5>pE#%bAbAw~ zak_di+9(e7;2C*2-0NTPpgfO~muk!a?*9V#`O>fk=TrI?I2&@6 zrp;%OB3s(HZBg=S0HIncpk-Yg{IO28uo16xK%2Cr0>&y}<6Zp%`~R{lGr2gIDB_{P zF%@OH?ln_b3g`HVRPECRuV0hwn?TL+**U8Q-M=ZTPpUCIun?_*hFg($e2l( zQn#N@HKTA;_#dTZDZpB!GbkZk21yRGOwt?pV{+1!Ko4vF<^&3LWa<#Bt;wgh33AOCS!QbiesOx|>X^mg8tAL{U zQI-VyRq3teFU_dXgDtt5#wY?I=R^mAwOB{m%z#zSV{j+S~E>`#jP_FtjLGXu%Q!^{vXTmq~41R?0+F@x-nc$sc=gr7>rw} zOaD(L@X~G$VOq~&R zkeJ$-f=K_*ojZxul~8ioVynTfr2hwXkyLRg7y_S6_ZZXb|GX;*;C~0UgU$W>unQ=> zC%HDL=rZu7k&}`xAVVC<@=mM*C_4MB4rYs_FY3eE2b5(mbW>S6q;aC|^~g`BGJ8}C z+~|w&x$$MWNvQHncOI9`Pw6e{eismM|9jwP$rk_nkx7ER4fz5#h8@dwiT+_9m2^@~ z54qC5-;xgOe>sK!GhjnZ#f{l#ag4P|EEP3lr{gb=lceqq6j}?2&X0K|Ft-Af)!Ta} zMOL&aH?C4=4gn1l?EhHU{wHMG7z*h-VH%gtxYHq*g&miJ)uMdfd^p!tF0_P%+a^H zeb!BjMxGLtDv`JW8tIr17oN#s|BinZd_J3Rt)I}OE7WXrUIbO7g5UCu` z5=z9#q+ytXAgMGjqL_{Loq_$Yp|XpmGYL3GRHb~WV+l+p-!Vb>5rAnZ-_BwUcMXPa z^8%EhE=+GenLdcsGN}_xFysWH6r#O#tX+ORq|T0m>B3THUDbIDBGmt zJFE>R?0S#tfg4k6Y15H5op2HSA+#Xat-UmJlx{ncjATGJHO?|3t~A!$`ag$0Gl2iH zi3G+~0zdn}{ucC|-THEEXyGGs5hgB-MyU+A|55mPsk+((wF|QXF+P!KQl*khh3e#1 zwiuf-7;4X;Th{-vNh>uH_07!eyi9s9&XI-TKGn+V?ZE*1f0^`QpumkhRqIgJG2=u5 z;g+hExdMyQTP~G6Nf)N-K`D7A8^po>zseZalqPW>MI3V1EY4y2MTDeWk4H>f=#Yke zJ7(X)Gi4{L&B2hIAPCMFOPhdOU0|g&-VH%gt!-o}5!nAaSqKi1VI?uB*Pj2tuS!lw zsh~df(juWm8Oo5vRyCTwqq~k7CkhC+0@jlvum%8)Tx_cQ2KzrT3s+IHl`?r{DFBlE zAbzR3^SFyw9oaq%Jy6nvG3}xav42XcR}V5CU;%1t6G6cKPuk}HB}%xcps6S_3)eAn z2-0XD1}Xy6gN)$kXJ8;Cw>c~>zg70OYuuSV7@_NkArN&5H>OWn>;IgxH*u6=C&>f@ zG^w1}IK6pJwW}l_w$E>EomfAqPSy$gYhePXF92>0n5#&hzad6T$l?zdW&Iz^#MFde zYBXdVvMN(|ve*dxp*z{lJzx!>hXr4Yn03BG*8kxP1CmS}GF;MFB#lM(#-dL3|KQ?3 zomv0qtgQb7zM>}fRfN5;h?_CSj0glNPty@d1vj7TM*YaT7wi9gCB*-yk=3Y;4ZkC` z@gu?n*+b0}b)AL5QrQ-JBMptBTVT_DbyX@#u;ddDd>1lMi=(Y+AjL0cCIt3>MhO-k zNOADBp**<=>RVzREB#2TS{touQj_&ym|*{#4%W_6WuwspZL58hA~SA{CItWERZ($i z{p(I9md1*CP39?yknHvIMwej!UoGz4jfb7J@5Of{#_l|;~tg@fwf>_K8`ZIB3hb%AN z(+NoZzx(z7LlaNID&UiQu#>GR3BZaI_mAU>6Bj@H!u|78!KdS@Ge##YST$2E9n3NV zWj^=eFW)~07jYiXJ=*$o5m>;13wb&G==MLliqwn9rNpI@Ugct%Uc?-qPWA9zm9_K$ zgw9$M9HwQJM$A?;isH&_Duzn?A+_vOuh%yMed10X#BV7d$=$aIXHonzb< z!U8)g87CbbUmM?$>z6YP6YT#1{S}1|YJ;f{!aEu^e|J&Dgugp|K5&boSAbh$|DUEkSkW_1ntGE7Aj7e7| zl&F7{2<-pCkpndWw4`y8C$M^fLIP_5(8$gDaN)^Tkiz~7Wapj{sAYmW<|B;LteX;n z{liz3UA%+FOAv(23-+ZfOoA#VIYZ;!C=qGocp*sn9sn$NC6N&kA-Osq%C-f$c0Gln zP2bSj+-RzXl^ZfvZD?Y-n!+*f^()9O*dU@BF^8eWR}warqS_K%8&M|T+RDPdpTTv< zugS;#KfwP#Wb6MeMfS>(lZs=}Oio3LdAdl2##{5t@NFY% zS}5UTi^V*GQrs83II#a$q<9i$mvrEQ2Q?39lbB?#WcErVff05ahzWJs5g4I+79tPI z!2Vx3@;AFKMP?-KOaTmIEmU;0tZ1GR8ng&*wy)q0@h-V;vikLLwe5>$oFP=;Z;QKIog zkn+X6Bq|~zWES$k{=Wvj3G*c56#(JItBpy(F*xXdF)vERu`(Uq6(aNA6Z9cdf7<2O zIGW`L)0G)y`2jc)vcA34$zXJ<22NVWfnO7uX!Qm9vHpL5rLBo#bC!PErz+@XGmJ5E~+G0+p3Dh z7uB8(-JN>J4g@g@(&|`FLuL=OF?#^){}QdESgt}NRTKh7*b|wcsveX|;3h2`?EmWwwWWY%s3hVeiA(NU5QNMN_N6RL5QIt2z+E>4 zNwv0-t-*r*UoN0>K&Cx#=yvl&ctIBEG1Mmsn1+R>fTiWA$_K_;w4#%yDqy{TBSO$H$=2I#NFc1Xn z{}J2#pM+~h1x-bfkwlP2>#%@^ocdFK(F-aUE-v*W6RaG`7}sD!*AW;0QI~LIygsaO zg-t08SHS)swHI+qVM~%PudS_}*f_m;4)(Tf`~23{iS?7}WSy{o)S1Ba#o059s~@F^ z^x5Wka(u9tIce}?@;JD5^|hBDdFs;6W7n=;+S%Q^e);B*me5g$az8Ab!9T!_j*idc zZ!p%8f_UcbN;T^$nc-I@ds!-+t9$D%UT%R)k4=$%*q!V$Gqsy&4WNhhf3u%oiCIUg z)!Pdybr#%TwzZ%Jxn#)1!7EB*fixD_8w*O6%I{k%2|p~Rzy;OO5ueyV|8n{{VE+@r zy8`^*f$d;({{dJP{~gamq>VO)qNca$;Og+jinzJZUK9H=^u^*m(Lpo!&ICLMI&lBjz|U)yozZyv6tru$FKgt6AWe~F9SMbxl23Ho1b zVI-JXg?g2HCLMvV8}z0w(8HR)Ma)#Jsn)+!^{=)6Awww+yVCzNJ?((Iqj;~3QM@J} z_y6c#|IfDc{{Ww@iG3OFidb^G%VfTdw*i!4FXx7$N+XHoJ_8~BoY5!a#?HNoC_2e> zjZ+xR^rHV~2jc(NZxL8J%FTDWhO^}ZVgadixn_mKFVBvtIwq~uY>fNRIR!H@_P{#SAVzM-sR##voprT9tBwX0dU zjMCYaOm~shc#2;-I`h`S{`VsPU(L!Dw!(u2UL%=#8ZUP~DG0JWcQm8oNeQ4d-vA@3 zHu66B!f>LwCe#3ebPRPHXy+*~9A>&1?Emr5a4mLgjA*Wr5vPcBrb5u>o|_%AXp)3+ z3597t?LHbmS=@Eb11O?o3p6R7$5GSwwqhEuscg9 zA`@a)4DYFpj2B-R20ZGs{z>>uCQKFrIi@ybsn?i74k(aCcMKac5CrW1iJ?p_+FWv- z1=LI*9dF52FymyihFG1bYvf)WL8SjDjRher+{j-wxii{~)&WJc+;=ZKwY_rvM(Cv zA_9ike;0n9a{j}pU}%!(+>vpO)w2$0%kNP3OzkOJ!@d4Rqx~<0cBx>Ob#alwGGnfE zK%2CrIu=d2iO0f^va}nup!PFGB8^nO2JHV$#DH@#FmV|vM~>9jQ(3_WRqq&-b<8*` zfsay$QeN3eRZE)MI!)EZt0gTQ?ElS1BDcZRzxK*jZ1RmDtE=-1^NX$azxXCYf*{vm zSwc4i>6pwKXcz+fe+v-;1bHI>9bZ}`lqf?Pk|o;+t{Kh51K?IbyOIa&LA;``uH^N> zAD5it5>dpeYj&P6HrIVO0>^4_|Opf{5JKPYG&(X>qG zr2j|yfBMk>)1~`=U6A#E%0_nO*h?>R4HevcoW-s)iq4gF_Zx;F_Wwrs*+*6rHHi5X zbe#mqmLaC>nc7pdhI{>so+WpDOKbd!T?MGSA7x48k1JT2d(<)%7m*aG|L2wzyA%Kp z7^LL-j4?A#MZgDHU>5^T&>^EH7jG ztnuxNF}g6Z+%!WX-l~97?wRx?CjCFs|0DfB4(kdX zZ0=u_{-3guUAa643*i}KBrf13FXWE3PO$6fmrE5Ea%J6%{-1A#{Qq|%tD)icDd#%* zk1atQXD#6wB`tBUe^DzBEkOnxwbHk=#;?}J&@F8&{3uJiK?`cX1><#90qp;~cCTN- zr4n)xEpZtsM`m!+5$`c{q6m1n6;OyctHM64!IH^TAFkv96HvDP;72=VoRzK*{ORHOVE=ysgZ~bAc(1gmd+|yy0F5GIAH9xAm^K<+(|wkb zoO=#NC=m#5m=b~ge>V;C_+&jsBjX_mlIUFP3WD@z?KrH>qy3L@aSTy0yx%Fti~g1j zB77aC_2Uv2sH9mc)Y2(L1!~pJcq44Pp^;6mYqNloir~3v107W}&Wt8hYr4xyhVNUe zr^K`d+ldXlzvSuXfc;Md?+oyN``f`+?>~g?KhG!EruJ-v%%rnS4Koa7gmdue=1ZEA zswBB_L=SpB12D08gd8l;mvpuq_kN3~OR|JYy3zq-|32>MH; zDaW_IjD&Lzj;N z#f`*(&ka#z*%5wLF>NMKJOFN`4wx{^GR_0+|LNg{){RRN2SVePsGX44sTOb4t}{~S z0*e~1bJa6e9WaKPBWbYzzeF=&yXxK*M3zNK)PrPK=no|V`~S;J^UHHb zGg6uUL&TavO#qDur9tHyi>aj>8eLXO>9ItPB3GWoZdhnR8lX-@Td=LH3HJXU`0HvE zcJyeGAPDJ?Ac&eATRf=hP3sSW#tp3b`|EfKaf!ha0wZpuUijQlvD(Ao+yjow(sAo2 z&Tn5pw^V}9rLG@mFDhikTR{+yzA^IB|Fac$Em;|{xBj0$9|Z8f)$QQ?{wuKc=Y@y} z(UuAmlB=-TPDTvZ-?ba0^+%I)?Mv(IWC8B~J@E5az}iYVg%%xmqV_T7Wn3xYrq_VU znWXxXm?8RU7)xMp1xTyAgbVinK3V>!%@`yBWo62^Qo;>G&4U9U`L)rVstES~R~az& zB4-IhE%{3DYBX*M1d++k;RH{&ipMyXaKZj>M`?#NLO*`As7sXSy?}QtgGyF!#Q#!( z!QxiG64_ZvQjA%w1MP-rM2gZm5!n9^z<2p+mx=?cB!R*&b#8|&UWIYdg>u~*=`t-Z zPZ}?axkvKyG**HjV~HSO|37$Mb&nI=C`C)8EKoCjXnYbF48PVQg7mA7+b`E=t!~90 z4^%LXiYE1i>8oE0rkHc2mTv(2|7*j^BPG#N>?G+))k*`WH_zdc1D0+3{MOcq^^PIvg}n44 z)lk97$Aly$bf}5w4#~O)%m3i|KktQ~A4W?n<=#wl%$0PV{Kr=FqU@R46KlY|{za`k zln7E<(wWdJ6}(!P7KIjgrtB<95&Xu|;ZQN~N$=mO{2Pa{@S`m41}!LSCTJRK?K{B! zf22?Am5;+(<HnE`ojjK=)AI79@nVKa;Tj$^oVkmk`3`+F z-U}rH8Iibz5;0*IKFvfBu>ZelssA+=1SFk_ak8~%$%=OnO8-wka+?YmwZ8hzSrWdE zTK~_FOaBio_hU(rL>`6d*-$yk2NRI~AN$H83CA=v7K}N;fT@ir0lqMti}e4T+r*l` z#s5=ztJU_O`~CO-+y&c%iMu)3RgYxi;1=ua|M~pHIT@;)1TJW{Jh4%%@iJa@CShF| zT`-ekrc^i>Nl16-nA%8V=AJOqQXH_W*Yx{Z9Hp*l+S~d+9lHP5!*c&G2=q(khLRv) zSd}yYB`_2jfhSq_paBSC{~v;%XB6U=SryKtQ{^ztP|@NCwB>i=R2V#?Xbt!J7cQ03 z+&=UYWT5!PDYYE4e0qAVs`778zj0&iC2cJHC`*D?H5#-G@hy^q=8s_iACUeZP!5Am zw+m&`|0DfB#}*gn=Q2uCbrD3c{||CtOd*LrQe5P&E5?`N-luJ3NXq5dDry$HEQv0| zHFr#Am5ERK0TdrXN(A=*xAR**#*P*VCF&L>k`>K7Q6jMazk@@KrPCeq$nhSdXWI0; zE>U#tG`e{8-sLpQ<;{c=fkH6u7P*vscam)SKoxXe4Ju2$gc5;B%~0QpAYlJLkw=RN z4t!{QQWg9L;>8g}`hOe>oh_zM6m)1Bk4~)UawrfSI3{@`Kll+a2q>@4>h)}}(O^_k8qdKJ!({JAb_WzU8|0DfBpjqUCrw2~Dm1g>2F0%el z!f~k@{^Q)lqCVd6|BsC{sJl|(@fAvu>TLM zUTGukmZX!0`ld7qm`9E~uu**rkSa0GWFcQ#fvj0;$yi5Ac2w+N2K)c%RQOMT72=1F zDgYiAH$f023gK3YFR+A$ERSmVG-(C0wF80u|GmM$LFLAS76~OX2%p3&H5EmEF(tw) zm4k3YH0@!B{WsYE-*1GeXEkd8{J3|26tCpFMEm6;AK^qMd2{e5DF!iSDUa#`D~TXr z|NmfhelcsRL1R%sQWXpW*CK*+p%(}$wG%r8;_)7nnzZS6UEt0~(X&Oepd5+T*FEV4 zB2a;S7)x#@5+`8)|FB{TAx#iy)>L$}mT6)kY61e6ckIo-k zSzfR&*kP;560uWz%HQB#|H371t(3z7`~NvI{UI^8n8&e6ER+7#G0VzL#cajYn%<-F zU@D(B7Jd{afw>hdt&S!&sm2=km!=F3;ZX#rVE;d__08aqS>A zq8l`GJ61QLL@6#U!Rj#70Q>()FVa4Evg||&*sP!?fQHh7tyX~vCGu3Xb_w=#lZ{p@ zPw!6y`#%6%DoI_mmKl1+43hFRJ)}i~AmPvof{>1LFeN27xLZs?QXH^rPO*4URlYwB zYkn!G>xd-fQ6%~OhFtvyK#f~E%4tT+7J;$a%1}J0BeC5|HI~6>08jK*` zm}QtL=Ss~Mz&QWuhhMn=nyKK^O?;gyZqt?2=2ze%{s~;f*Yy1&{t;ZrN2UI6hRQW* z3;E&BFzMXbQR@FEFDUqPFM#y8{{M?H;-?e|8t2G8C=k?C>$e?-#)EJOUmKn)X2eME z)mCd9k)X^KpiJuj%X3HVeL*;^ZQphe{Qoa$eM`}>WN_XCvR>{iaoGwc5!gX<7l zqz2Of)Y>&7>wpqe!2pmg8N*PN5~*5eln+VQ_=L8fTGd{mqIah}8dU zTA!^Z?9WvNKlOi;;Y9}F<$hI^xyp@s+o_dH{U03~0qT%;#OKC0 zC;`vsB>SBY=rF6;eL@J>|34dA70kFKcLgmaGJWEn{liCM zs<_whx@cwA5GxV5>P+#t%jGnW&M&VlWI2ZfP@yPVkY_HU`nU37kF;#ME8QENjphG#C6>rJmHB2xu{b(#@|NJ-U4C=+U`ji^t|xmzL(2 z=Z}H*ddo+MWb`sSrCdcWv?VauCzr`_&33n3bGQZk|6eF|-Rs}l1ybhIWXU~7O$jLx zw(45oC~ZIZXepnfXPh zuoD6@+fgWsd;PY{iMj*MsI%-Y$r{H~*C2rV|8w~H^=PzZsE3ldXr#od|ILflUe`PB8 zyAP9C6JYOFE~()Fg%tV@r#W@J8{HL5(D()6*%PGM&>Pw1|dM|4R>S z5B+-~jCKSR!ib45hZ%}Z3QWjioSbAqLjCVissEK+w`|<&f4>d<|Nk|-pOFJ(2zSvsx66OY zL|Tl^7UT55uDa6^S(~zM#;e!k)638Q`%hB;tF3KNENJX3s4Lc!k`Bz#NMyH?(lH~c z_FKAjKN3EcXz3n-bdIe5?;LfO{)0omd*jgp%@V*aCB~XXDfndI*0fKn1hFgbP3nCq z4nEP}HWan69HeD=N{IhI6?>Zza2;YnCYf1)g68t#{L=hf#u_O(BvA;WDbo=mh)5gC zEW6Wz%wV0CuGo#t`HNi)2t;kndq~aCQ_b%WZvVNzenCk)Wv!aJ>wf4Hj;<^&t<0TP z>;F&u?EwDE)(Z)|_xSz})cc+a4K!h-$$d)jB))yx{$|9`#Qj+HA~Au)Fh4}`-ECORK;JKd&xgz{#ik~71QSL+?q zIx~dKnh_&5%*hlPFzlH$J8#3Ic(2S+ye41ke;o=wH<-9P_Hce{f?tw*m(GH~<=&-H(#&T&NU6GP z;mieS_3y#Yf0O=yoy%ksxS0FySn9LC>K0kd5M}DFtcOmN91S~R(;wzCIBdfYpc5b(-_UkP2o`rk_CJ&UD6-|q_j zC|1Ho@tS;8_t3iYwnP65Nmd1v6HexM(@T*xxNg{VI8&?lMi1y$nM?TCRR7umJ_h{% zf9DBp;BSM`Qd^Z`M@{{L?XBW#qLNV*DwLl{$K>Jx^1pEKvDC3xy`<`GBL2YqP!K_(hoIAF-x;XED;-*^d{B)t) zMoW#6+`l3KzUD43W(<0bq!&U)sSqS=mUVey|BuZ7VLZ)8!OsM}rn03Dpx4oCdYHJL z$d#DQlXvu*ii8b{OxUi;PlaF#=l@Cm9~08BY4_*Cx!obdi83`2ij@l+m>)^_7)cNm zv2^Bm+L}ri1XB}vjLTp8e-Ne~q6h?E8&OCM{(g*8^8Yd6KTrr5J~RP@_#F&I9F#%w z|0FEjGx$xjo)m#W{(ow677ii#|Dtn%MtuoWu-|DOkX5jw(168m);amoLCS~ovy&3wuKBk&OJ3`HW~5c&PT4^4h$aOlG1kHbzj zkw9??z@5&oHFl@-sly-qto?6*#p#}>Tq-?~isNeo%G=4P1E2m3SVZr2Jy}HW4xI02 zmhx(*u$!XtF{I&eC#l#F|6!K8&eKP0oR#2 zU{}@#VuAgCRuNt+H9!>zYR$>e9ru7P1+olZmdt4wr_g609J>5m0q1&}5i-sqhFMWy zVE_0nrIt;R4*vWOewR+7a#rr6dmoJwHw=;we_sP{+}ILz4syNd@5XQ*ic=m|4IFCCO6{hW#fZ@-qwlr zlLq4>7nYuzBww!lozAo6=2Ndw{k~P85_uZ43qLuxbN?iyx4oNrl1z*#GC0 zzW>K_!emKJ(+45A(d@I<04kw=>F%xi01H}yqw^_Xt6yx@f=XLYZf=g$5%%RFCr2Z( z*&{l-;rk`KKdRaNWVf|3@Est1by_)C4+SWAgtje$y9&9v;w@M8e{$;c zyn%~dthwY|2bLt(Fd@|s!e}yE0`T$zuG0|eA&gydcS07EFwUT^sPzE<|NL3}JH*DF z(AL{>#=&3B332{p(Y~-+h=o zzuGe_Gc(E+QpH_i{wch-6mQ9mMHAU$B*DFiMe{i#aR1MRpD(ykWUVq#tCDTPBP`<~ zWgrtwwZ3v?UxS*M=A3oFA<*~L%X74`wR}Cqp9%BMx0>>U+eL%|`+uI6t9~R-D)Bzd zE*}L8S^$VxUYuW=pUbe*Qkp3-e@|n69`7UNmCPPGZi)FhueDGaiTOSCG5*2rKlj(O z)-tJm-EZ^>M^_e?R_4O^|NX(l`+FJuj@e1S_oe$crh*SokaenkDj}6v-^hcGY8)C; zb@#{xxc_s}fKZDhwx2~QxC^m(@}$mMz8W!IP1u9NZHH^O@$51<=ihL*VbIdWsTbZ9oqs6N(0Ig0a@x{fJgNN2nUc87& zdfJTneQ#xdd7uk$@?I?|jAn z?o{yfVx(~RB-Q$aZWyrPg>Go`tqBvs|34pozL4YMP7DzAEITErKE+Om)T3vzK+Wzc z2fCjIipTHPVQ}qvLa9pbL56+7GC^*Axjd0nFR0NaXY++ep|Iljsbw z)if|AxE4z2WM=ZA>S!kx@UEF}G1)Hq6mC^Hu=7N-!HrHApBwt1%;@IjE7z_rWMu7y z|J%e?Ok%?S8ULU7z5xEq))@(W@2mD-KNb9qRRo4;OGOJI-UfJfpLpYtc7SXG_kRKW ze6hv%WPxa@VzHM&DUXNyv^8t?|$aR-DJPvUL4k zlm)wVv|QXsYw)?DIk^GQ+${b{XOgyH|9?geS>hr~1QU@4p;9CcSVd~FmiZ%Y?1X7} zjiIe6NXrt#!m%8>&(0ClNNsek_`*2fTvd#PS_Vkjsn97HU*CYZjviZC9&78ZZn;Q# zL2+mVQHN&4dLt*slpO5~HzukfdlTzTh-(a-$o!&q=~Ox<&SRU^)y?|fWbpD}^5yVQ zdi$Q&@9#|oKXO%DNcfm)C=#z4j?znLq!BD(k6G}Q=S@@MK46f8?|;$$8>WH}Js{%` z5~zN|N@J9$rcd}1`X)BC%+R7zUXk&Kk^9r|^TNckZT{7>4B=FlWVvkrXIn&=LtLPw zG4*69@uA`)leb>bPaR1HC%`=;u z&w3X4|1Y&Bcl~?SGKwo4z)Q4HW+)o+Xa*N{Bw2#GxhY}v|AvSq{l|z3({T!IS+FJA z2V1hS2z1it6m{^O9neGNgJ+Na{2WN-ab<7N_0!2R!n zpBI_an!^+n8~<_{Na2*~#y1XC_?&rY^)mmXvtZ`3>g%q)J(0sGF?#6U$=*4uLVq`O zf2KqZ8Wlw~1?00mBb4Y4Kdv-p#x)HKA~WN2;iA4FqjISDa2v%Py_!BazPh@U#rD(` z0Jx=Ng(;uY561I@z^!a;;@2B$h*5Gpvi1uS0cw|AT7dc%odxRuIT}$-8R#N#ANT)H z20su?d>%Y>ar^eQ{U@e^zwl;M+h}9@Yl2KAatd5%=G|Yne{(AMn;X$r;S)b!C%0YG z>d2BTOwfZFVJOab3{3PMWHJ=c_b*42A45eneO?HQX^N;nj4j(c;U^P2zMh2TFh;~U zip6m~WdKFQm_p5hurrgPdtXPmeH%49dX-PLLdS}K)#9d4_%y2YGjgwRc_u6JX>SqWFOzUX?%L^E#Pea9_lRW zRo!udInO-_nUPLwtQm$E^{zk<>u+w^LxBIk7i}K>f9zy;!hucf#Qz)4&`)|-{6CLy zNiWm=D2BnfMc4z+do@fglkbu9|KBM7zho?&3q9ihYfkc&^8c%=N9R`NGiqvuBSi53 zFG2qgo}LB1gro+F=IVy#4;rT>me)+^k97w3o>YMdUAE*!D!|-pWH!qwypMM7+)d4(s?8YN|SFc~a zar5%EOK-gV$P-UokN=prgTwdGK%karm7>TmzfVZ}|8EEa`0sgp*Yy5VQ^EV5AD?cP z@>J^N9lef5A6SyomePa~g?Pd+inM~<556{BP=R<0)qW>}s-Y)7!&m)PwO$R9ty&M5 z99HoE^YC-@@L>+?GysP1bJb5DouO`K=doElO|%Q*(APBKD2phSqF=d^aB}J`W`0p; zrR);U|Eq6QdzSkI`(H}&16nsF_0luPfk<4l0|MS5=%puaJhFTJ`eQe5UVYU1=ZER<<0Im; z8#lqE4xe65Z1aZ)Z+Q!xYWR!!jqT`-Q_EZDPpJ3t1A}`{9bO(R&#&TkBz%ZoMNibP z=>a~be-XZMWd6wf?An7Hn|im>Ys0|j=I2jsT)2Gl%;51SZe53ve{j#MFTZAH z?%tQpN6%;Pjeqg0|NJBBW3vMUko9x-=$C_g)?dAa@&BQT`-91iiJyU;Y!xN&^yU4x zOa;%Jra@Hu)RC-||fty(pS;g8NK@5uiAdngq$!_VUs@Q#)lnoW1z;UmE=KQ0p&_p{-2T6TaLbMOh$56z1hD_L)R{MVwlB({ z?wsPLshEA89sYCXtDX`tfvD8oTvGGDpl=u&yNd7-e^Q*D|CI4aHrTjnm z|F2BR>^7Hg8ljx3qy_6_HicPz2N*&>(}H0CFRhklAiiR7m0ZqRcw{LrFWI0@4^syW z(4G9&LB0&NFL1z)oh5R{b7A8FS+XLJI!tw>=u1oU%bB%IeN>~LY68xnTm4kq8|T)~ zZrpg(<=zlEkzq*7Z=<-w=WS5*%&{3|NG{h)HLHe-nT2COo|iwPBM(q5+S;bRDpM;= ziw#4&9BofxqEwV=td-dh3ALZpvD17+Xk)RvPXYg5FAP(BxxxAvzEDTJ0aO2|V|}zS zSC>q@9KkkxMKtsSa}@OMZR7^@qTb9d9=ZB7iTbJIvs&At#>whp(P~>dAy$sGCbcL@ z$Gjw5Lv9%DB>&%o{6F^pPX>P?nD}LQP}}#vX#cIy%q?r^&4MM>UZZqI%7V?@z~fH7 zcd-9WuoAG`yR26u2mYodPXjvhGWa>w-Wf>dq2;y~$vlkt0svtD8!Vg0f)8rBqGWy9 z)SnlwnF$<)eXL|2B=g{2utJvHt%4QkF;C4ENF_!6e0VWBV$_ce0O;-8=4Tr3E33!W zdzcWG_&>_UMDzEJ39R^Qng1Wn`7bm7U)whMdMx+vLsT)YV*i)J&t}H4hGZb=qA^bwG4*F| zHL*m72clHoR%%&WXH-)~n*Xz5CE~<}*Ezf3VfYb=CSK+?st8X`TmG+W zJbBcX|C@tF1J_?YtJeRU2%ZS=e`DMCz4=x!75uF?6V|AGD&SOFBv0lxCcronv<^j! zuNNmYy>u&=WhvM8t5m@KVL9Wett^6MIy6}@o+bt5wyYK&Ub4b|PjDR4lLY7x)JNch z?8~WWB>{j3p)R1$pRJu*`#973&k|M8ae`y6*_(DC0l*CnZ|>`VO8}4xm9?z@tpk9N z|GzN^;D2-5_r2-X1Oxz2fd$4}>h($hV0g-0405I(lBe(VTt;8HN8tYV!OwZ&{~m~d zvk?maA4?;2Fg_ow8h!q(@P92@V+mEFBW}L89RGi|WjWP=O*j;C-`|U{&2ZAU8xGc2q(*Iy$~KKs~o# zeneA`!2Qp`&$a^vkp`fVY5@8e`D$h^WG04*wmYM|34)BU-*AdyyWQe{|9u&N#_5_0(=g0VT9I<46PZp`G2>jWd5J< z3gH!l^ksV}u$_k7-v#)2Mf&pp(Lp5dH&S`OFx%0K6xE25Z-=D29xawltX|Q;bgeod z@_#)!p^k(4Jk$El66-%B+xMGwr-f+L(`6ZIL3?$7>K6|81J?yI?0v(i=C}>a!{4~M zwzhWo^m1aGkIMb(SMwX&(Hp0hx6YqX@4f|&Hn{iH;pM^dyh`t>8~sIh_v24k_ODy_ z|I_^cMi9V%|J&1(x1Kc>yq};(?;}2fcFCuNNZ+p^j@%lYv>Y0QhO{hIzs9xhPt*gr z|3mQeDtaw(K*Woy*KWla#TchA4&Nii4bc5JRY?7RRO|oa9tW62KUzQ3d|UXx=Kn3s z|N9K7|92)&FH?`ka_SLq|A*n{HM1Ca`%Q?2#JbiTX3L3T?Mc|YmDshUB(16k6`By% zxeAScirMlofojjRe3O+fXT>q+cR^)Ja1qBYpJ{xS{^6>{1{dM&F^Ptn!=ugH z7a%ctbY*e*=n^c__v*{9nfcX!{*hbPXXa;T2T-n9TR(S?eyM*sH@xhB@jqXGbvXa; zD}n(2=WkD+xb>M+!7~akqKDM{s^st8(mj$gl$2r3DZ|XZ9pL_713zCU>wniD{)jD$ zE!S+zUdTE6d|Cb@Oi$Dmpi|qVgb}6tzy8?G zn^zyTW@MrRn8)p79C2#n%KZG?%!SJ*&kP=aLd69sfdJhYEH!+H_{+HnAk-plIYC{cFr z{KB%~X?|Ck&I;<`ZwJ5LBrM2<&9%eP4ZRdMfw_FNnVjp85GYxmj4k6GVa* z-gD*JZh=)|dc=Fcx~{;_Ye!G*SC&_g9joOY$;czMPsawy9c>@{@ebSc`!~GCQ|ZAc z0c2#d@P->3ETy|g=T{b%v$~cF=Oa5OYaGvd>Go`WBzEue4Z0a!1s@Cc|Mf%j{tTVT zopfpv-q1422@NdCg9RnjPb^47mIqnas0_&rHo}?0;&R%RJYYQ*)D`PVUY`<*`hEP#Y0GGOZ*JY{;{m zpKL*%O+tQ#wlH~uBCCz$iZ2Y==Bj|!RitqK$QcpAgO7kVK%ed`HtVjfO;2xLICK8u zg=uxOcXkPkSQd)Ay?jW||2r83@W15tZL7DQJr%t3Nj*m4BfCy>s48%kejx2Topem0 zLKfB-DEr4Q8$lB@BsMBc`??U;3?V4#5<6j2jdCp>9S*zl>IaM`5xGH#6$a>Zrf;Ls zMX#n0j<2pR9Xzyt^5R9rjx*~IZJs+lgduN@K7Kp6bI15|s$&t*ZEtLzJGDWIVD9zp znegi|ud#S+X=QF9!`oM;b_>TAk1b?rdQ1`A1ib99axD{qizg82)Q`P56fy=;dWoV^ zG)UMcl%@g%IKhXz{VV@J`Ah)+WfKW>T>{^+aqI9@@b1rzTp&J4B?+D4n$6&y%eO%8 z?{)R?|L6GT|G&tn91XV-0d^p04YL9@^M8YPxzPVVRvrW%ETRLW5&rKOP>d%3NBf@) z{#7vX8}Kkv+s{69>vNwKeDkfBIQxnd8>ctVWn`v&cMXMx%j}jefuIjx8}Mg@!+`5I z-u`8`K4&WU_OtYtYM=V&g&gH`x_;e5F$&74TpMD!RBh?;vYmJB>5G);8gymX_Wf~+ z+aVaQEH|d09rI5Vo>jHY=43rLiw2N>-rbco%DA(}WGfnmN}+dD2Ee_3$0f_rG>--Q zf4yD}KA{hF4S`K!=h?v%U);Q(8Ti|jUcQkS-<9a^%oQ z|3j!^T*nwXcZ_)A$uehIH-dou@6j=f_^4!9+ynPc7sy6A%?Bs15B|7h80m%}sn(Vf zxp`h&-X9|x6dsN{cg|lt&?LH64lR_3An*X}|M7!^e#I;juN1bRR8T3^5a$MHq+>o@ zcoL@5)1h_HXor?i@A4odk_$3!nNv=YtbF1lnns|h9;asp8bF%g7-Dp3s{TSeM-T}^Li_CIt?Ei~gqYOt)0 zlXP2$L`**P{cN}hh0vyU@MGpis(9y4^=pccRdX%x=&|fu4q0L7KA23zE1s^Ba^M1_$emonnewoOB%ym5`HH;t6cS7SY2A0#|aYo z1TM$ns`Dwu8Itf}=z|FiB6~KxWHm;Xz)75_FKV+Km1!7$q_8UIDqXG@s;ov}|KB)# zlTxOj+F(SLEQ8)HRkA8L^X7Jz^TYWAwcF@e`e&Mb%Fi z11W_vkkQh4x-`S~MqJ;~;B0uM`~QD0nEaXG_Yez4d;89fTc1A_Jnb}n?AXdjQz?IJ z7YxiSj>C_pksgDI77qoLJy)iUU7(CWUElPcdvAT-RPYm*Pz2GIDi_`1HqHYIGNLGP zZx;jzH~tQSM4H4mSxmL3nv!Zml%oW#LPA%K%hl#jQnfkCNLTH%}3 zO)K0r&)w2|85=N7$T`Jif*=9-LFFOk>$uF&{;goH&pVwT=4z9ur&dCGjJ1>AX-p+a z;c?6irI#@}IQYjj9I%haC?{+ti5k)@1o_?$oE6NGu_m!e&;S2e5WxTbZ|{83tv@jp zy!V0ldf^$36~1YV*XYtg;ZboykaQtc4I&WiGA-2{7NM#>i~|1uX83t)ypV7q1SqsCRIL%q=z!dS6IZC<%L<2KN89Ec-V^Um}oh zFIMXq(E{#)vS4{a`+$t*U{vxMh4K>2&T~C}p##=1UIzCZ?m;1_vUPOcN6Q7%rGzB* zo_hw@FMs3A!aZ>Jo;N;v?04j9 z*k?*`!y1@1JAta{gE7wk1AQ2|{Qnn7{=ejMC9Su^lTjN*8pjZ=3J6xs{~tC^yk2qY zpa!pw2aWn_c~Xgib*?zU|9><3|Bd-wIMCmJ@HfBfd+%&LxN$`17>*o&^z!^H{O*T; z{bT>~W50Ii&c@5*->F~l55pV$rR(3$$LFxR8eU`K`}A2J`HmyM`Q1m}z5B%8jmy_A zUEh85>YJkNOEc?t#3X2 zstx)O>`!f6xP0==z4(s0`_I|(L4Id@fpIyTq=bb;{U6KynFz`|9^|- z|L21M{@1X5+r77*5BCCdn2)u%n&GW<)+0YYGn|b7j1e{t_wl?_8Br!7viN;N-dT&m zEG*5hE-cS2A6s2nJ+?Zxu)4f*Y<20_^3p6)gHM|cQS6J5IpCJcBx<`9{1)?aiY(2O zC}FU3r*k%rTKNvLbW}WDNJZdo$S#N_hWlVb+p~Td-&a^?7IY@z;6T~`#61E0mn~ZY z-}1n%KQ$G6=Zit~@y3S5RHIysu#RD#8a04zbBl|MFMVm&t)NR4zSWuM-~Krr5}2eT z12B?xG$`zY=8!1N$iB4nLD^N!ICN~owvPh99bL?DWBRCWmu5oaux*E$s^50_XaWYr z{_Vy?W?!G5N`G9 z(2tiHyI5V|55;*`s|y70zPLO$l-{FHGK)?3fquQWdCLgHd%F>np9nW{$T<3$BHy=wyG!?vKGd_2C##GAWc0{*FZ>=7yJzCT*snk`>kqJ8TwxBXQN*yf^WqVL;y{G&O zSz*TeHIt^XYd4jwwxmN7V}+8-p3m|Bv-d85aUJEM@SNRM$p(i2;g#?@5lO6-WP9Ha zD^4QY>sW~-JCbbYK_X;Zb`;B!Bgsh|oTSz{t2_yWM+*d~OIt1_T%f=Wg;Gi>b)nGE z+t4I!X`#K`mQpV5E!6byrPcq<%$YeeXU}WjyYd;!vvcOmeDlpW-}lWo&ohG19F}?E zcHl%JkxRNv=%};vcTX?CxrXC&?>4zWXc1S=su*}f_?-)&2C@b~ zRnQu+*70^I?)A+p?(w%>ti3LR-k%dB(FNUnEwz))+uHPl)EiW)cq?T>U;3dVdYcZ^ z)F2a&VSx|0$9Y`QBwM8exku6yYe$Yf4X(yojrHl(E9=Gs`LCb+r(qL&-m(_t((5w| zJdl58B?%)nn^EAJA2qf@{($IeHX#}mz_>=2GA(M}DD{WrdGzAcJky;WGDc z?3{F7hPH*8Yg+M)$P5kqELAX`OBGTs3p8wNsD7EI!lr-`29W$ZLM>#0xcP)Q_Js_N z$)SZ|#@=(o+k(0J{T!^bm@65MfMJ&`e3dep%NEW-R785)$caosIdMJ)&E>TpSdi{B zXIS$R`Bx$+^c;BSsMAKZH$~8cmjX>pC-G=cJoe4AXFq!O?9)$4_BTy#CROj9UYI8z z(#1@iiw%y_bKW$?didJy`r?hFgXMrs5Libxu{4#nIh>)-r_=dVBAbUD`}s^EpUY&D znQR=?4ZI>8*1r!;ncGZET0!VEhGWFs3U#2t)8v%9RQocL3;;R z9w;RmMM#N@Z_2V_YKjTSRe+Ewx_pJ!9YMOwJ@9^M3{{!B>o84iTRv`0U%cTB$z18B z)RUOPKNc3%39uXi!Bv9LY)UAJ;4g3i1$4nH1#D7+j#8NMrgEPO}!VEDH1jp4EIaCk@P7en`k zmO^u(+e7<9Zw~DZ?G9ZR+8(+pln*6C{h=#DYUq;CD?%>`ofirzKUdBw|Dya*`M&Zu z$_vV$Dc@AiC|_2-pnO*Ogz{14!^#JgUsB$oJfi5z{mMPcf-VBmo5Shw#&A!#JN&xvtHLi0pC68d{wwtFp??kiDD?NC z?}h&({L}D{!#@cBUHCiU=fZy){^Rgh!(R&jcKFlbkB2`3L?Etfopv`+;>Fq$_~&a2 z;Gd`634WIbUrXx>Yp`Fc3u#ATY8Qe(t3ihpIidkWMrO1ZgFmgE5B`*P9{9Iu zF9QD-?H9nmQR@PKj|Nt2WLyh_zgr7|Kcd08x5#z)VvESN%MU<%U8cVZ{5R<@1ON5< zOTmAg4tk*L5*^Cwx>$#@x?ZD0DP6DDp_Hyy>Hxp%6*@rfx=06@T`$)GTGz|8`@w&y z2D@asF4Rtf{}Sz9@GsC#Kw0n7-UR+TwM)T&LVF|lZ`0lY{-fG!!GA=%1pJ4!i@|?L zdky#xYOe-=MFZR-y7o%&m$g@b|BKp1;Gfi94*m%Za7H)l(1KkBeJA*N9onudrEdp6 zsY82pC3I-7uDA~E)wN0A0{%ul5B>%n=-<_+1BJU{dN=qzI$+hcUVk0N_Xci0jxn;jW|VUe6tH13@^oi8 zZW~wJ?DC}tgH!9!|G#kdndi=)J^LIP*+3cRTK|vbKcw7>pbx%v4ak3cRpF1OwDn!+ z)Z2^H5;J_kHU);Olh%OV;=OuYy8`C?IA$bbX+2YNKt{s+E!pG@@X z`y2OutZuB{(df2>rHk~UOc-O52}s*{EbBa4GX|f~lBN?CO28|WF4fY(za)bEzu%aX z_B)H|20UPIut3<{ipkp$3fSAa7TjSS&DvybkpCy;wHM642Ism@9R}>Jx~al|y{&WY z2C4_T zH5n!#{~v@=A?eEl_8vMHRAK8no2sZ=6MF}&?XhDG^b+f}FvabpJT9k4gC0jVcW+*P{(?a_61*ch#4=o+fF zfj?ybukuaU|JT4m0?8$;K6?Rtj>8M0y4+|6K7GtB4&MCu&?*E4)CGb}# z_h3wm!8gG630;b4pj59++p$yem|hJSoXl+*lSy4m?>9s^m(@G-14~&=JHeh4tSDrdyeKBtK0RE(sG4j!J^V!Me3og@DdJ{W}#q`4k?ljX*)+#s=T4 z-^BK(_!6#5*>ira%q()g*Nr96@>p2bZ2cuOp^QmHN(m{&bfmeOO`{5h$YO*F=*xg? zw{R4Z6_wGQq0>+t`-xu?P{EUOW=jZ5SXq9MK2X@!6~&N^_Hp$cp7 zSFL-tN5_#-w2f<(fxyUe*vCV}7kBx_83dmqOf|k+;#ym*ef1GYWWbu{u(j5PZh~kw ztut+9H|e*du(AKK{5M{r>uwmh)Y#wLPu;rWP9UB?l6codF!*YtU#*J6fu9-#wrrFP(B0f&Y& zfMaj%=uwm{RL9JQu0Zbot&5D&)wABF!<8K>SDMw_1(oY~q9QmzdG%PIp6UpEnI z^X9DIYFY)v3&c-2yhF5%8<$v^y){}%Di!znZu0~6o*SruwTu~gAAO`hCajwtkO34(BpEK{J00OMIJlVL|_I-Mk|(wU^)r z{eKO1c_WGEzl&{3|Bulr-z6t7ns;|38z(+HE^n{`4qnV2Xo^5n07FSzY8%9r4FX#c zv)9}HS3)HOe}M}q&>9LnGOxuW=sgE$r(pPkNCXzV{~oS_aVyyWpP=i1-$w}k)~Z{1 zjh29q0%ZdBYUEy3L0$uU4OmT}2W32;ma#YS>e>HenKx&+1f0Fm@L3=4%FDF!50<1{ zI}7fO7%SQdET};B0X%N5(AB zK|okF%d^@Y)bmx3h`*D3q^B0{De#vo>M;MWgpMQl3tT{f=1|~~2ec$C0EKDSVEBSm zp4;}m?|z`x{txW`-y-(El0)zpIR6wV6}40ZJ$hk#b1>_m%>JudQ_I7Qs1?xG5<9|HvWQ4n4K{|r)o zh(6<={ac!HIi+PHNIxQ0L~2mdLJr#pgced4rsfXLAKgDYzaKUmoH=vmtlKQQkT{ji zMya#~3@QMIXiMPO?e>Iz0?oGM1+5eBQ9{41faBlrtkK!MJs0Q3skmi7v{ zR3?*6rqi9(D^UCY0;J%;x$a8yS`Mswk9DYIBArX;Q`vOR-fE>fx~$X6rqjuECSCvz zaoBK$GnQrZGv8*D&D;E;Xc}GQKDa>2)%@|dtmIVcM07a1En0-{pnFcL!OeY;YGIzw zM`1i2Z@;pcRAbf@W9BNS$%KY5aK6+IDbM<_uDj~`l-Hv^lZ2Sg(I~P1mFH3DAHWOT zTA{%5I;{Y`;p<5oGf!e^7Aa~RRlXliN>BLs+h?CY`%LWY&!e#@nR$Qy?6;$5pLq_2 z&psQC_U;?PWZ$A>C#IpU{{WFX=8rns_k)3zusY1LZrGle9@kBD8O2(W%VW_IJ^LI}#z(Dc%+(C0(CtWYVfD3ess^TcKk}?2uR?Jt8 zfYdr<0NJZfZQQ@Q`eMYC9{c?)3)ucLM1e3^{=?`V6nZ220sJ)09o4Rkpi`3^6C4oe zW-tOYH$CbA0n$^&V-VtD90Ye7V@-q9XM<}V2MmzX2Hea;f%PRcI0zh&-dF` z+vGyD1i>~jL|UaF7IlX0kbHE{@NkW?2{awuqur`)j-Usxc1D%I>7c3+oF#na#snU# zMeWpq_zlJo3k+3^IG`4{^>Zr;*w4CDE57Un%*1D$xZf=UN#Gm0#hxoG$pG|2tPfg- z_0`RCF@xCB_gTxy-xfq+xDrW%=IITZQe=}d^57BIu022~(^!Jm7Tjs;aX#p+-2@Hn zqB4j>0zBv^Z6Ff+A3cebZQ!++J9U|MRRk@MNOdUJ+LDgIYo`grMi{*7Fv-eo3AS6r zupfkUkOz;+WziC0(XcRXC#1qhLlJsgLfaBS@27<^WIgcop*2Yo8)fTTmjWshZG4ou zt-scuz^2R^5r#^TF3GEx3FzgkfrZWj*8e{b|G$_77qfDUmHXp3RaI_7Rk`dkc_SIO zxI`+EC?sL6E?GzvvYA{WlgfBQu`9a?am_|7>s_a2qh!Iz(wg`&nT#h>g;X}5P3H22 zd_J4cwFt=;6>A}p>!UY{ApgH>rLrhAE@IzsdFpkoTV*f3DPa%KN}DR56WLTDmxyQb z=~S|iOXWZ(rK&~A9?=S7o2ihU(JG^)$aW3qEoZzcf79%Stf$@v`TtVoHExR>%_h5j zrBh;bd!Qs@R71E-K!eWLm6|PU{Oa|2DhcxcdvdM3t6^n~Kyk|ytmVm@`n5p!%xi60 zcy5@%-Lk5l6P2_ywOQvxI+KB&CqU`mWOg$j1a)TXH?f|LTB8E9#LZHOBQ zyVH2b0S!i@Zdto6FCmX5hCQkaOA9kc;ZR~C#-bYhyR&hwj+n;?nJ;Jr$?Jh7MGtcX z`FuA)*6=JFUqzO|DJ-vHV{{1b|54D*2>;dBow;ATx(l6p+XEtkHd|=jwU69a6cX_q z9K4CAX~t%{0g3fXuz0n;^wd@`TOWgA)5dhjKM5rgJ-Z_@geM@Tg=e7cXQo`Fyf^y#0{OB~23>(~g{-#b5av_{*^kDsBOg|1*xz z3?e(ecYooHi?tDL27--M5a*7Xb8jm1t+h$;b7#p_EqdFeLxVy#q~r04%w1$JidQ%367uly*?60v@TeYrpy{ z$afc}k#KYkc%~~!7Me9>Mq2^# z^c56Rc^)X0XA%)B6zs?+#I+kGt>h!m&1gcqf@4f8RrtH%e&UX+2d9>%mu8Oc*)uYr zMpgK~cW@g#5O2VI#xFMwjt&mrbaPQ9FPA2x*Ez(zi!>SWWRb%JlCI0_NO=YCkD0@QUEuZr00K6q0lwxl#Bc~?v*y6ZI7Up zw~9)me3ih5W`PraFt3=8Q$C9W>EMJ|A)A5;^kg!fC?xV+xa_1DvyPKyuw$#btE6-x zL&}jQzr5&}!I<|OjER|v^HQ_;C(rmtyHeW*&39kWe5Cneg+gbw9~SHa^tTe9_2X-W zaEu&nq>;slKM4@TINFgDKxVWVqPZG|04dkN%oP(cA=JAX0`N-7uvn*VA8S(0N&|b! z@bs>=VX3SztEv|R2EVpdY%L~$RcjFt+qDfa5u1pklNQ>LHXW66YHuQC(CA2Pz5)E`YwUk2Mg$spNhM zTROzarkdfJ}`Gx6881)=DGI?Nr4raEdX6BX_ZRy900+_fc;h7X? z-$Vi?W)6ZneUs-2I6U%Je5$x&9Htx)VG8)m(Lxsb0({Bw`!zpRpGG9x$IyBx?9%W?b820 z12(|_WQ<_iZAMI`oF#ISyH()HQxy`3SAk(Jsek`?F*v;D7DPEDR!)U@^88|e6-s{D z3;2~Bi)WD>Ll#l?%X3&kk(BaV@yWgASTVf(a_E7n&xi!SoK8ZV929A9r#r0#X6dc* z6&Hok5bS?~6$4&zXJEyK0)$-;@QN9QS6Z@(GYxTgq>AEGZSun*Rf#9hF9sy! z*$eoU9E)d>?MfkrAN}Q6lj?|1)^=zM`yVF%+HU?Ygx-ikKLxMcm2S|6;EQR+GwQ z3gC&8+Rh02wR-PalITkxEbEXhskej{rL=(u*#3XY`+wdBB9ej%vzF6VbrlF`;%$a#P3uwvMl=pw44BKEjDSoR()~YQ zLCROkJO3c26DaUlQoAmK-aFHD6HQ*y6WLARdd8NF@38nvj^{ICEy6%I{D5DtJwI~! z=d`kb{{LCJ{{J5c!QZ*%RzlkK5%icOHg!07ATc+6uvmeC+{iM>x^(+klb#mMV7?I4 zjj2t{5KU;!U6tgUWtwJ)h;|!b!s{&ty!!uNL&~q6ThiY_wbgIZh9l_VoTRDBPS93- zLQ3Fe7IalqERiWlBImQW;;+boOvvHA94%yEFRXA`JWFa~z+$YwJckt&NhrS+pNRan zY&OP}QmA2*HYL*j|7nEauXEhW4s9fY-uAM#6A8+QRrM_*A4>d8Uw|(;p4^DF2t{Bw zvlU=_`c!wsOK1U3f3aaYwg2COlr5bj{cVG3>1u5hR!73;kQy>2z@l)>7d#}3i1;MP z2~W)o15uvvOP1B92q9W1ji#u&EDlL5iPZpJiqWQJ!CtWW zKP*dTQV!D+5MjxX8(uXFChW0=7ztGtun>acF(!sD{L&QQOOEF=VjbDrzF3?K-q=I6 zk2Q;TEQ=@M*bz|tiNCi5cmg@O94+LbFG%9DSTmw(G_6>OcnIV)OIk~9Bv#g0{;B={ z1BBpjExX6pX}com1Fvt_u9{h^R#_mtDK;h3Bk)3wF5_Y|!bX6sQI4=0g@B1&4JBBq z#cN?ex7N~9C_M5U1eEY31lOuQhxz}%pzD8u{a=;t1N(n>JKO)wRw@?p5=BUsw1#xP zymZHM#TN}hK>*tDvb?Kn>Mf7{UwHw+U*Ogd1@z0b8zShTkv6q=IP>y=C@*3p590t& zWW-k5ze~VGcmP;{&WiC`34l$iB%>9q@XSDA)OiW&f%&6w+u!u${4so4-(p#MQ(mEj zI;{i_-@2{N%@Zl0ga;9*GGG+r=^KHfbc>12r6j=E-}QG{5@}BX zXKPTdv-?{ytza_=nRp5#u2OF2`Ne<$pS2OZmK;wG2{2~DGf7t|9uja79x0eZ7Xwlj z{=$f@w0xdl4A_(auO-Km8?oNy;)FaG0Vh5Mtz1SPgR&Ccj5u#Z>U1iA|zMSs)@^RBwFEXzB zaaTWP&{elcKMLcL3t3V{b10r9Ci z-DidGRsu;Y7AYroZ}PQF7;DYjNGmXbh$#7179{`;P2t{o2>OI(YM`jPVQCZ&KP{jGDcrkU zoJ^#;{M54ALI3}EbpKBuUjGZ6I|X3(KRYugW56o;c?>O04+f( zl*gJ08&s|&|M==ZyW9T|dhk~5M)>aU)q$x^TBJdZA#+~yn1GgK@>(5AmVk-y2%mGI z5(82e{=$f@C&d}h+bqg;>IZx=O zh$Y!rxWc|u0t^ovwuDQCKt&*e;VP8HQjk(?;#pLsLdx>7Usev)gW?mx%WE5M!$$s= zmHU<}3H%wc_1IGvrjN}|9hk-&`e1)>-{!qI7CXaU#TQxa7Hn6?Ah!QQ%9m023Gf2f zaTL%-w3{R7!8bO;Kx5)+svjdJkpKF9CGerEwVNX7iDuj>0rP+VK*#@2BIU`BWBs*` zus)^T0{4Dh+j!A71=`xvgMibU*tzVRfqu4o((8-&I7_dYkA-lzPVEl%8h2*wZP{-& zmCI$5>0~@%qH81~ouJt}uX49}HnDoY52qfSTAE&(Im$ZJ4K&a4cb|L@iQltlWI&Co z@PF^%HvAA3f<~0^7Lsln9333K>E@zJ(l1R$$J52(cs`jgoII)W%b7Nk5Q&ZBm%STu ziF_iSxI7!rC6gJbaH=<#NM`<(gwpAFJR!vAlc_kQ1UG+t4mSG7U`rvj0;tc)upV9{ z`_*gWx&CCbKfSR(k>65)Z$BrKNh1H~0fhfr;8yO_-V7IcJrMA?$?utTA(wXLaY8M% zClQNA>v8R$Symg1KcSB|Y2XvSob6XP&w^}pmI46zr&2A*d86e&q+AE*f58h}4HS4d zq}>)l@02uIW9}37l2@?negx-#Z*9)`UoUJ-#U_TDY&`hX9?ev&0yVtVS~+4y_FC;K z%ut2v?(B>{de3YFb#-B*t~W#9YLl=WX~Pl`OHJv<^#Dokzx?|2Ibf+z|4z z|CRS6_zPTHQ9$3XO~UYhNK^x@u_uTIEA!g3e+cA1kpH$4<^&*MWy}GVO#n7{{Qq&=`9J0N5&Q+N z6Dgn%Xj3rIf9sks6WU!(h)W4-omGapqTslEQ2YG9z5ItZBKQkjKmiX5XrtPG*lloW zplrCNaPpd=SB3;M$D>`lNOcG{CkNcek*=mP@S^;2U`49YAd1!QmIS zog{K`5aBG(Z$K@d0m!?o;yABa*dv@0_D#zOOO+xIF=GeN{cLAY({=#aD}aXX{|PCV zpwJEA1x}#Aa!NZCLHdz82_I&wa{jh*o_7aF&}rD-A3KSR89VE2N-mVkk=Cb8N6^YG z=Lp#jv>rs1f;$m7|J7u z_?nkTGKo(VD1`;p{5P#jI}BRl!g^FQ8z<*<+F!Yfr1IFGLXIkyD_0o;ezIX(b3+z; z?LrzX@OY<)1liYxU**gr!Vnu@&{J}>kb%CS3}Qy}X9JPAoSdnnW16>7dzkFb|8$uAyAeE)e=0zM?68%#;QSAzgxCJx@C69| z0vAx=+@=7`H{Ee=%{ToFH@Ix@)iQ&HJ0O?tM=nTwvN84X%FEQ`;?n%W^yI;rh3Nwj zIuY3a!^LeAq@NG$f02RANiT7_z(`S_F^mn5x|yRAcEW?Vd^OYlr|18_gAn|!HTU>y zv?CGpfebZ^4c|~t_^A>JBGV>9D_VmMWe!r9H{XyNR#K^U95Jl-Y`^Sq~Os z{y!}9g+#yz#ch z0Ez@TJW`PO#EmI2(m%<}f*M5}g0Wdl6)aa)GZR|bE8a{zU>QyN%3&5z4|EwSApfhv zu0o*@vlK!t5l5C;OwF2?BoRkYu18Sf|MdY31TN#VUriX zA^=4|K_d`~Inaegn^YBP=d%$wiAe)^S~(S!KoBI@Ir2bril-FfxElm(l-e>kx-qO&*w^J1_+o<-(gG=Nr3!3@a?oIq;SHICnB0d+I6kuALr`BZZ6~VF=d` zbIY(!1Gnz3+x#ckH=Md5PD5(Jg0 z2R;A$6QulvARl;Zp8`*w(2hpX=k8{64dl0)35Rq%na^fY`9#LyfM8X-t_=+#{BY%A zDmBNqV%nByKD_z0(cdxjFxahR;xw@+U$FiE6QQn98+2EIS*K7UgBR&Z%Tt+rCqR!k42pF!##ZxReJq)DkTw8!j zOK61cj}J)7BZf6;|38G3ht|H~+s-w7_wCwT1pVfoz$hnLqER}+RE^EmO>JpMfbCDF zEHEhuVYsH|0s2PhM)(^sKxt|C`~`ci@5C0z2+EOM9m+M~abTnr@kypdg*nXRjkaJ3 z-lRAI;Z_t+%j6U^P-v8VH^K&3`~5$H%|9*M|MU2QHXlJBoH<8&K0yYV;cCiibA_cX zJ0(UGAO%+%ts+pX%B`khB))PZ9!W?@3;llt{=dkn^KVu4U6r`+{q322Dj6?i6S*v& zkP&)8Qg=)RF+ixoJocjA1Yq#lFDvI(}HrF z#~~dxFbR5hv-iSgMR9ny8Q~P7`~O~m?|(a`2;w`D0`UFsg}QwIyJ923RR0yKYv1bB z7hFihdj}p6l(pGS_%2t{FKzP0GU?b8R2;9hBQX<=$+ZfUVU+7l%y_$^5o zrZ}VNGe2xF@7)K$acMA}w7QCrQ4|IkjVcJ_fAO4_{|=LHChWGqqQsl^vM5?1Cr$5L z{=;Yo3hByu@KdEbb(MBE2$Vv(&+x@9vNy+8g(miL^i7QM7mF-&)8( zILEoc8&fFh|CL`xp}zz#aP2~Y<*T(5AQE9oo0z;Yc-LVt8(o?=uZhKVPcBUzs5;9Z%(R`D`MQ;&!c3A{NE6!fhh#^0Ds<7?)@LKXQh) z<_o~jjqm@V|ACb6g4Zc-`3mhMsP-G|cpiE_mBcSh%^jRSx_@?lKXikZF^8aBA-Ru~ zo-hrFFzmQ{8afrZK_>j%a|2Qg3}T8r28SUx zJvm++pe39+qrYBzD@+4i-L{m9#|&b~gTlr)kYgJZg&UTke=Sc}*9IbEQHckdTR!do ze~gqLcZ%=_cvepV{UzFcpbjpzR|m#$;q2M6`zI`uHiC3g6NK2Nd`?GtorytVcob4I zSdKJ@-{uH&JfTm5sVBf6O!(ut^>|glCTGtV7?IdWmz=VDY-nU~?552)w%#zQ{0|{z z2;&jBswq%PY4=CaBMzSnwlQL96gOpw2`)YfD?UPQnnIY`#k_@A4R(y}8i5g^=nP(A zcDLs!pwjO^5|jnptU<9h{->=;N(mH)W5hOiKMB6SLvpp2&-04`n-YXp#d8wIXP2F? zA}Umx!RG8Tng2s@|IZ8Hog41dl#XDr;#yHuxLzeBs^1I`2q&4PV~QVBm@NXryiHV| zw*i4IdrdEuB3%ZP?$ZQ{fPQ(Gf!F^Ya9sa`N^VGG(ur&iZn5%R*$s(gA)hFuQ|W9j zm&~Q(`E)9mE5!3jIAj6GEYj(0A>(H@i&Mm5N}JZq-xQii;PwWG8x6Y#H~)Z}qdfvl zeID&mug;`m>H#YMPb1}T(bE*aPVkr4>mir`u%967N#x>*bRv-lMvVhcCR2%ADv{0S zQt?zSk;&)NiFgJWxIdAC>#O3~bUvF*K!Rj8m+_Pa5S^rtL_RU_28CsTN-K4%d(Ny0$8ss|u} z7`c9GJw(n+*~IrmETy+n_Ny7p0Vf!H2e<9nGXfBd0G~}7;6g8;P38Z0Q0O1g?=Tv7 z$gke3M}V_$V!Td%DJi4t;K3N0_8am8OISR{*oM=O*IyFS+7?|4qw(K7`yJ+_MKojB z85Nh_aCt13XJR8IEsJM_N9l!#ocPL`$gCEBvoCT#ae0XSNXo4;IxxIrNupD@i z9)>QXk7Xynm2r#M2s~_AU~MXI&}kJiIm2WYSIcH?meyJ(8N|``zYw|?p?}0)Gu?v^ z=)Vv_?~v9bnHgSZ@r8p9uUffChttlF)zbc=K$eFCZDF(90C>z$N@PAADoa;^2^ zfpH>PWF4YcLEYGEDm-X2oPXJb3~b`3v3)YJ|CKHjdLF!U)oG*pc@gxW?Xp;%O_6rd zwb@K2MRp2Goi124YeU~IU#`Chto>a~^2l#x)_%E#M>}~M-#J>zQU4GfL*@TU6k1fS zJXgiP+Ilai^z(tqY?u5bwZS%O3O21}gpOD5h$P0L7b#nQuQVcx&sL~Yfyv) zu_?;C0s_$bxIhDREz4)X>^=JgGyxLPX*?I?G^|la|9F~HLaTR7E zDooIr?~MAEj|$3T8U>eB*g)3*aEMTWQZ{y}{lfDkP`vA>q_;xC^ExEgaoGtK_T*_)`lm24Z1JI!)lN16L*#8oxw!&~F3c&#F zPY3zaXExaS11~B?48(~B^{Sr@q7G5@DiI`E(9^j8SI{AZ{~G5We3gDd1U-&bm+9I; zmpIVcJ{nN3s8h9vQXcCDw>))oW9ln4{&26ZOb6I*#FZ9*9P&FwyTNtJV;BFk)zx}| zvI8%~*^(8@ypX2;L7$a#(zAXMax11Cn%ScsHt2igSY2%)=WyI?c?wsC8WVIF6+vO%dQt&(5oJ=5mRe*pi?ZLs&;FZL)!o~94%0Lh2$0s%i^!4`+q)) zlvksVw!HCO5P17R{iPA~E6v~wAj=y{)B1%G^r-jzakD2s+}gA3og2GQqo^#4HKMvs zxE5=!G2>hyMb$G0R+^A!H`>}}aENT76^Cbqf!W{afLT4F%c)cm)bi{QQwQVH4Q@pU zx+k_N#**PbEzhm8>dVlOBLpq*f1m&EdlPr@*TS1R2pHRLS@Ew8r8%Q;Tx$=Awe^4| zByCTUQ5xeeSEROFE1?o@t&20+=~o$8O-~{w9)N_T?v#&vuZwvUCA=0&^&%C{RRzO} z%|ydO@ff7PRX9!bWJsuN442&I$z*o_cs1j*QE>@|GzfeYsnmR zY!X4rW!Gnn4W)yQ%_r@6GN~y7Jt>j{?Eh}@xjZar=%8a0y4Z3`NihQ1THUc38-OJA zR#yWJEfIt(i%J8Xt)a1f;k7wTqLbyJQfj%Rmmv%C3NF<|sJ zXe^l?E>9JZ3PY))v0MrlU(ull+5e*qAovShWfb^eLVsBVec>=Pk?GdJQkBRgo?)oD zC>4)B0!6Vh$9}@sr0MH9pmISL`s} zW_=ba6z#7vBjQL}PF6y^f(rU8!{~&W1VY|*iN+w=&wEb2Qh!AREpMtOH?9q?+7q~H zc)R+~qS0r|slWxWq9fs(^^3yjtv=8qSK3)xM(fvK4x9ULbAKNTL@g6(_aI}``|o` z>DXsN)Ls>zz3E}kaPgYjpYBg4`coT|{mC>uC;QcF5)hT_PjAGp$ZsMxG>UJ}k?v`O z+Z~VL6eL|7r}$BSnqA+b9>%Yy;B!C+rk2RXI}Q-ockEc>K_T(jQ&06#ckS@5twxaj zTsF?%vZxufzMFnuW2`tjI8wZgy-;VD7G{o;;%8@$O!IoPO9B&#Trz>LLrTDPNV!a$ z=BqSUJf299oDvoL`gptnwtK1@2-w#LWGw9K+sTk*zZ3?0GV=6YJ2JQqJHk;ag5OvI zKdT$!EPDA0{nc=Gi(Rf}L{~Mi)@ZlKvSPZ$McRhUgWPS0* z(LuJ!&+dkQI88~kr0@IR04PD49%WK@j}2bCZ}26c(zTg)7Ojsd&<0 z;|k@FOHPX^B=WDk6NSDGUf|k*0&uGMb=FhG zJ|rzyNWvF2@>}5J8i_)#p4JLBSQ7o+*bR-7AMD{<@>Td%u^GW)@p~{kX2y!$-9*p% zwpIoPCng5B?Nn!b1iNLJ7%u!X4)I))*+d%>tNZ(s*!=2G;JD{UfNZa=f^4#pH@0iv zIo2m(`46MdL;tV*2!1-p!SUobT8}5YiOILW{_LMT^XxaD#YR23S~-zSst2bJO)pFy zf{%5=Cp#yPOrKZ;Q@cIP_FconTL-sYPpyT%N)2#ZBcq_d!7^LnO)wxAAsF=kudk^8 z&)Scn+L`3%;z)_g|D)Lc{}1$NOU3`8y?S>9Js}aekmvr>H1JN5TXKUbKTJZMh5v;E0KSRTEZMkApi3GN~`UEEb+DzTxk_g z&UEkZ#{FTsO{TGo-mtGe{h{aN*JkV#ME>{k$-ut8^Uptj0RC6!)B!bWT+OV)S32nj zpwy@kD+FQU#!PF*v$-s0cjMmy&Pqn-U*Y7M2QnC_O6T520FiRMj2XE-d*bmAVTbIe z=IBgnp3J0{PqM;<5VkkW;R~4|f|(PDhFRF`mTWewo;;boDjtVWnZvK(&i8&gZA%M@ z4aBqYxH0*sLM<+Z8{GM%EUwk1NBZLM6-}49w4eK$OS_R>wJlDt-H4ESYyrOhj(YGw z1tEH?5!|{F7vK2GiZdA#FeLAK0v2K@Wc>QT@df;K>!P}D9iBTJ8C2E9=~OlkU1d+9 zpw3Rs%h!C-{(mD&|bWk!9gQE1*u36^-eoPyU*U=d|$YX9u?p3o=L;vTs~gdv>~_Q z{`-^Mr8be^hWiUi+q8*1e5EIsPRDbpT)dD;7gCTuO(#99#G;Ec<$W{|OFeM=)ZF3e z#hw^h5KSiI$>gRaurMfBquW`UK6-3&acPUXAu%9F!EDQxQP@$~xAQxg5BQkt=*(PC zA`zp0x_|uvU_;9?CZ!4Zj*8h>$E@=*CM}m(#CW-q3#}!--piQl)(uc0#HJjswDECS zT&#NM@%g3cp6ED6h%89<7_y|MHexE|lX?8Drg$oqf$!TS3i;l2I(?- z0s;I(f@J{~0XtZ>>itj#$woZaG9<79kO{pHfS4;&-asgJc1Q|fx9YwAaU+{>#H}zG z5L9rd9s?k+EJewEhykmG%Zj00?k|AOi`Y3VKRhbuj2)VkI>% z%@<9_09LFgu~Sdlpb=f?r1U68v9g+x8YQX#RZb)Tb%P!UQ0oCj>WnI_gD1yo(JJBU zK`KTa_DiU=$%aZkKmwHt`bO`(Ku;*wxMj@fo1t7R|6R(ZDEztbT=??PjSvi+NC8+^ z-U6zHT=LC7qGt-Tx_Ia8%+mDa;{5RiY_J~eiAi6+GgAU{s0&kkF&itl`oi0}Yfs$) znp#q*2-(wi2D`7YX{)WpYllV$*b@X!4e3|HKJQlpw}Ue>t8^QhK!t?OEXPEY8@i;B zGYl*)giL`jco?*ajFe77hRlc!VDvuwk>B_n36PC&BElpMOq>lsDP)ppwKzbFKXYb> zJ^%vm*3${y8}6LokM&VTkoI&t^vxcCqDH5OvsrWn2MS`lLoZYg$N(T=gymm>&A;#$ zxPSs{gaWYt_bO1@H(&+PY@JvKHRP(HsB)^!H&q*vf0Re~uM+p*cKzxIdV86njVVsg z<2cyQyfg4lNqY^v$*h}vA7k-}{zv-1`$YeHps$^qnw>lfGmH0f_w4h}Kl2yQJh!@9 z+%aD4SC3BJ(*qmCV#UP#>aZLEQ7dQ8d~y7{j};1M&Jao(dHQ>%lJ}52^Pu}#q`EY7 zl#7!O|W{8tAjb#_YI5{ zheo#-ZyXpO+*{neYiJavTyJ0a<;7`O@R|PZ!D-r6;Y9EL!P8HD{QLC9Bzr+$WB-YF zf7IqZOehVFjuyx8%+hA;XAAwg#Iw&1J^Sp}M<KAO`rQyL($* z-6w3I%^mDnrPE*obnQZ%ujZ4~G@#yL@W$fIz0;GkGe>8Z%oI3#hPum*U-CmAsGoqC zUYO0^zqqu3M|S3XX+D|3pE=LLI6a#x#B+swK37P^vl*CbE##8Pd>kg?U|!A`YWBgb zjsYf}ETjwYt##OzSw1bB7vc;7REp|Eab!2Fv6?Hs@~W}4C~PK*Qf^U?A3HX^(8IF} z2?oCRr+@ypy_?WAL#o=Jxc~n9vHXY7r(ypucpc&Ni}XQQwZb3rr1Q#V1Je*&Fo$Y8 zq*$l!KfZWk5{vcx@g6XOa~|@K+Sg=9IV^%xz%FwX1)Tj%XS)mA>rj9^oRGzHAY(xC8J(EP=d$z&24^qBd5cCoB)I|`BN~vVmldvXCN8^SUfpMXE~rKI6{i|5MfurRI_0=l^r8| z;p{Uo`PhuoYN}9k+!8Xj+B~J z(^lVy!Z5 z!{{3)qTnoSOcb!dRH|hScCK03RwP&z_5=jS_E%aBYyU>lw&sTSQd%JYIU@Gp35+VQ zReAQbEl^xCzSRjAP86 zw)HZ-J5M19)o0CAneFPOX>Exr?g;1vEo-*xA;UB&`w?w!@-on}ZLDSK{Qswr@^SPj ztP9%Row`Tg0sBghN7?3CycK<+C!fvs!=C1Bp-{LYnNO#3sdy^0DchfbV`4a(yiMgc z#8Y^U23Be2j?d1{9O{X~3Sl4dX#8fFQI=2SkV_`iPvWU&`2{Qvsj*LzHJ`rhKVf(2 zKm8L-M-hBT8QY8aN{b$L>}YUzv77HWF|NB+EJIQP@%uVwZb$p%|R+qNn z8F%%3Ycwowu~~Y%cY8+ua1R{2#547B&T?Q)DTFVR!Q{KRN+2WWR@*%z7 zw*XvPwf4*8x|(R#@dShDvZ6@c7(PPwWI; zSuTrph$a$TTjFi7Z;bXab;Y4Zu#Ky)J7g#N+g3-5=|gY@@V+)^&dnzOv}JoTx;BE< z2Fuvjjs#@=A5EdqZz^N(Q-62rs6GM)`(%T;0XUKOc+qjA8p~LDB#8FF8wd@8+;M!@ zI8LF$2J8OWTh*!KOY@U=4NM(4e*7rzzwy86K?cwz%^XPz*Qcp->bhOy-xxD@6p7QTvv@Q9i^ z{sJDY@3Q=*^$mYvlZ(HTGO<{nC1d1R76UIFWya+#PAZHf6;m6aED-(SVxNh}(z5uY zjEDRrppTIwd2DcyUU0y!<uE&ZLw|;jopY*dyx&JCLRA@j+8f`%N^PO)N%a=u;J$$!2bUW z>nb+Jm*5-N)L_H2`fT%S!y6eCZp)W$(|3d14@!txS-tkwZQgtZyP*ljM76V&8_U-L zd>!b@`bCk+8U)sj7_}E!dt*7^faSjnB~bXn&>x3N$}JFdcW|_FFU*|Z;3N`>D>f&3 z67d-PkP+z>m(kHFi@_sR7Vh^-3>U}3T}vCtUp?R^I9ejyxP*~!d>tx+m+*)KO6>_K z#n}KB6O45TMj-yXRiA*<>~K_9n8FdXEawuTX+$=n;jQ|(8<05T9}x&aZi)J&IbpVH zth(7MHeW>L%#fiPIxju}RWE?{vsHBbKY|ea)$AVJr0;{#{{fqZyyN)n3|xLOb;9`W z65K>O4#!;Q7N-|fd_Y7ztionP{p1;7r(Nowi7x<{cx*^!6Y&geE5I{tO|5|qGGrA= zKqDZfKW6Yj%368S!q_mMOr;Ngrk5rc=I@^AiQRcnUBpUmuBnB693MkpU4@&y!ekB{ z%m0heAER(@=z-8?<=>R+l?&mq1Kn2rHV6GbJ2koS$lUniWiy9+=iv6q$pg1P`GI$< zGl%ddAkat27-^Dx?9OOGzZGAlRNfI$VOKZdyG~iS7p-4i{Vv`aMBJ$>^f$u?J?$(b zo%fWR)JO}(*RNM$%lLyC+97eG!goS2-Sn>_(Mr7oQ~Ha!oQk;Mp4 z@n#+zhQcO_W30CEel-!>s^8*BD#O~MHW&7jBqrIPi5*4LXg#K(nv4&OZ`E&h2V#J* z$!`LA_>KBaaF4RwdD5=m)VlCpqg*@#_nxK;WH%PmdD5`SJGn$j=Wc^Qw=e+M$Xid1 z={JID5VK(pq3jlP4HYRH&KQRLV^#!~Hfz9$D^bfuu{Jt=q93|jUWkNMWo=mZTH06~ zEoaoaR}!`w8oQp#tIJzOv^-qWw{KH6u9lQEVBI!~j1ui_>oE7wetkcDFl?xSjlg&l48UUP27L+^1J*a8IP!^WI_Fy{TRBOY z4LkX%2qQoZ7_nW`?T1Q~rE1oJu~{lD@6 zQvMyhz%`o!cj*UV675buJ+V!L)?mQu5&Zz%qIf}-CHu)%2bu8FUQ!Vjk+h+g2i7(@ zoG9!RZw?*W3md$MsP>;%K9Io-&qr!?RzXthRM&xcF@Q~zc{FmpI@X$KwGR4vJAz;v zz%E{3CWjhJ=#a5D&Eu~P0O%qN+^6RjXO?E}!WZWrnGU!@qMgtLIOwMtge(rpW%h0c zS6F9caR0A_-iqKaZ~+CHNr6XB=+hDOp1b`hY$881i^o7URXw%ns93Ale(ivfq@^mV zBTQ;tOXMFW|KKlh?i7Ieze5$x|8+KZ1pU7xSwd&t?EYUUnxkaK@hF=KByY1Lkbiff z7v6&W9}eW-WIS)?s&P`&V;~|ienlN$4XTY*U#xu0TRT z8ONilmw)s&g#TLZR_68FBj|17{$ckC`JjjOUN#_8KdyY)N-EOJmR!-Rd`E#VX=})G zOHCDNh5Tcg_ci4sshPTH+xkP~O0h}?7{K>kO^nfQ%dw8Mlq!p;GMg){hIze7z@doR zSyL{?U!PVkWdV^*bHQf*&q8E_$}E=i0gG6-jz?AB|A$|N;4g3i1p*2X3Osz9J`+Lj z63>0FK|>Vg|Az7SKZIrwdI5V4bPrDHN8p2@*EV6c7wWZZG)$?H!}>X+%Wu)nW!?H?~Yf~bI2&RjAbz?FjQ<}IgQ!%>%c)!$#S6iF9# ziRC|no`n1VmETj|34!);rxx`);f&Q0(S#R{WwG<9-Q1~;4il@&td20NdO>mBx3f4_ z?C##kF^9mYbNVVNttjyw3(4fu`FKh$#2qIatXwlBa!HqOlNpsrKqcOd zZ(*iR_@IiPN)SpF+$v#wEC!1^2IxqR=FmJ_$mKI`=t|59ICV13=a23umvmQJ2Vcye zs)_kYYv&r*5O8@?A}^^GiS<-Lf~#l#Ogdf2#Ve>pDxI>(iXaXQCoGWeAL$vIfRBVv zL_wMF8taC0_iE3jgE%-iq2g;}uFj-li%ScK;1aWbxFaRDx(bFxf6r1P*0U6k zty>`X5R`d$Nj$&`cDLZfeR>bZc*UW1Ns77ZVy1+#>@`P{xijI>TIL1&`)%`cI+50PMm)}Tql>qw~DdB)faOG{L#>4)cjBb{ptdIOCgnsT@}wJP$E%a zW|{l1@QDtZuqTmFui66F&kn+;?_y`Z2Bl7@ONVFE;I6z9`^5EPA0E4pq)%P0ABUR+ zcePGK`RqNktMnz94^Uc%Xd9{-##a?+1V>S=Ma?(@H9qV_`hS?!*+)mCG4Wf5@MXgc z{@S6MG{16ae5<-A)+c?n8XlMCm!@W6MrvyA@bn_QXO4oPA4)U;(vOJyh9N?rpIWq( zEqs3wN^K0zDyvUrB@omqC0bJ}Y@ww?J2n+1LTa(ZbCYl2vN9*J5{Xm0NPzs`c#us< zIhM&JOA_TO#ll`$)VEeu)+kU;WM0yd4Vv0WfpRjs9ZL0jcf^MDVuN4MxxPwi|Bg+l zk)*O3CE#t{%Qu@Clx^$4wE(DQC{0yaRZyBuG1@Jt4yb%BSNt}Lw31EoFOlVKYJxL> z;w@kJK#R2a%SxL&jOYKt=({L%oAS@_v)0`5I{gGpCcNHrfJ*P5m5Ibi=uUh>d!G$O z(pJ<$BLhB4HxOlvfg6$ScpwWug~AW1Q{R5OeoqAb%AVTkVN7#jmKS^KI3GrWWqI?H zFVXLgprv=j@tjHQRt`2x6$bqAmCBt za$G+N2K;nQ7Nj}=tAN;x8egE4Zb5X2d}B3} zjoILOf*S`Q&44smVP)WUyCP`6L7~Hd5X(RQ{%`0vl|O<#K)>Pn{ogxF3fx$I*o$_ITSwTSl$=*E z8q|(EEMr)f91gQAOs2P(Brk4rH^lMK!u0g)%;FLTacZ~z0Gunhyc%%4 zTJm`U#;E+YSZf|B1b9$PXxU|!$6GdxMcgacqB7gOF+5)ESC2-2ICW1C9@?L}O}`)N zBpq1iWrzVA^<=*G!P7R)Waby8-6o+!{Scbp-;?mF;qthCUj&t;4-wgwY{vxr<69E7 zS)gk@a~WEELAo$wh>vb~c~d4JEU`WDzNF*Rh&l=Ss6^79BOK;FJ(Xpp9wI<-&= zgK*C91|+?MixM=^Vz*Av9`7JMy2ErDRp~s536KdnyF#G6x&mXe#Q1Dbr3KtMixfCd zWc=Xz0W?F+YTcz!1g#8JQtMi9ajR^j;4;EWDx^{(x*=Yd0^C{&%fF)J5&Q+N0t%G2 zm%89GQ0e;_1FFGi$EFU$rFAp+PH!1q9o;oS<<$P&3D7G<9aQ~#b@e*D&rlXKduRb7 zYAc#%wfoxPU0b_**|yXdlM{SD`)M>fG%g(GlY(&G4Nm_Ygzb%qnDnC7ECyf<6Fvpq zhvh$_Y(b%KD8H)ALm+VeDX^&&4I|6c1YH;FOR6ws_U-d`4(=Tqy%uIPRs4x%b!JoP zJck@A`J~Lu?ep`r(OHh=D@red!K(OGaWEzAWc+{ef8v9VL{ z>Ur0@NLtf7^=;-#IIw}FBi^mxD>!8G;pm>>Ve<(>5?7kMnw^I*taJ&8-dyxylNV?zV}-eKfBqtqY?~(7oe-({u25V1DlKx}BvL!<-17!y;1= z2Aj{!9h|-gJ_vtk9%#p^#jI1?mw=UaPw9Nv#ebZ@VwnIjAvj<)M4ezUW7Z8H4jAa* zE1gF&pn!m?5NvC#Ii8-A)BaPk*@zuuyGH0$M(0z~0EMv1n;8qTmBTzFYaF8_CFxGfc_pmfT05OQU z2RjpJo1}7- z0PU6L8wSDl_cJ`UI6g5pv~6M*?m#fMsdZ0vOSQufz1UMXB=C=i!%2IO&P^SihFR9F z#T~oGieu|ka^u3%%u#&q8~$x%ADEYc;jteSlUY|>T(=I}+wyDtB+}XrXRfw|_Fe@-}AK~B|EI;Name_|S&V>M_?QXb^5QDr7vr~JKjW{jJb8{)_!*h70w?(pVM ztYp{uV&HY03#Z`XsL4gLp0I7tx;^#H(zmHz`o{)74diuoSq|6fMt|GBkYpUDaiPUz}|V10~P)f6NFwh*jW zF}9N@LOG_qLWx)emY{tJUFVbg*K~nWdkcKJ~jW-nUp6Y&2mS0JQ&CzKP&3 za2-woJzjb_Ovy}}(rxG@LAdOtNJ_v*8#VB(|KYMwv=FpMlVj$YQcA$HHKjsqrp3Mr z0%E4r3X?Yu5?dBsukn8u@cg`T2>h-W!v7KeY52$CAB6ud{GIS~;Xe)karmp@FNJ?Q z{ORz=!ygI1Km6|SCmS_9}E3@=tH6RhTa)^EVL5(#n8Q>rO;gH_R#*&n?rj;yF=H7wui0?Mb&y};vzbHRczOVcZ+)Dmu$~ToW%9oWdD4$h6p?p;Nu<`-rmy~xX zk0`owzjBYVpv)?V!qy<0O|IW%~;Q!T1H~4?C@&@oGIJ@}88c7p#{sR;frF1p;dI?s7yOv9s4yQ_(4!>A}`Qfey zO0Z9)>;4j4BH49cDFgn=QX2f@B}|{CQXKrnQa|_$B}|!PrAxt|FJU^&m0kz_(bC1> z&y?VMQ(d>0UIG50(#yf0F1-x=gQb^(zrS=L_){e?PP^Vxih@5`0!Hn+trP+O){+AL zoAs06-=v=ae~*soIiW9tKdvu;e}j&xx?9Ke{PUI9fdA~utHJ-X6vh~x*Xg*WhIA0FuATZc_&fB2;BVLWgTGD3tv0CRR=Y;W?RB-j z7yPUA8^GV9?*jiy9k<$ZE0|&fI&Qno`gPzJbli4%eFyj{9k*Rl$8DF;aoff9tH9r+ z;}+bgD36$N3%PbtWrsK^kZSjC?RliyNBC|Cf>SH2QKUivRoemtGY? zpBZvuR0~f4-@1#pz}P~NYY9_G{G7}8Q#dSMGegiHNYLAN=sQZUjG%{K=CjrglJH`V zpF2%_aB(?Z$wvli74W(M!Ro#;M109)gTRu0q)MHxl8-_hn}@GNOddKuJ9}vH#M}XQ zMGxF`gpMURkBbt5_Y4Tk5j+Oe;Frk+%&-QS0px#n4OAnjLLip(imN~?RU`}8=C3G2 zkT{UEK+<4FWo;-LJpK=(WqkgB41QYRP7RkXhSRaHcNoixqi{Y@#>=Vvfegg>lkfsk znS&Z3UY!3k!9Z#@9+o04EAr8CdJ_dsOTM_dXM}EGBirzM_6{zOmtI2-s`HGsO*jh3 z2ti)4N~aI3gFRMfQLnRa1PY^Op=cpk6Ba&h8{q91jRIL;-9cm(2F(UFE1u}Fwp2Mt zfsuijuMt{<2YGU&0r{42vK{4m@AI@|*BUqeMMzohg!IKXsiO`43!BX2JV z*zbq&ol*kD8N#YU{e#08NieylawM>yBD1MnDf>;7~tDCtN zvu#OCs&sL9sdNdP=Q`RjN(q;*yyN}Pe+wM$mcB*i|CJaDeGa_9Ia5G8zw`z;zH+gj z24WjXv&6;YaQdLXdq2IQrEjb_Iyh3~_l2mlOA9kc$vJO)0=P%cn~h@-af_pHIS4pi zY?J^|_BjXuw`?XblFEFnD{KL*92D<-q;CjaR#)-IEc^Q4bVXrb-_FF+LP3RZG_Ce6 z7fY`PYv4jZtx>zi;}E!h!vbHX^~}T64j~vaNDw$&QJ)IhLrz^*9tP*AdA#x(YKPkY zTaof5^l7x!nf;yL94%c6ic2^L2q>ATGPNULO2lp}vcwv96_GE5z!y-2w?OV_bden9 zSw63%LZ9+Vvk=L?76^R)_~72+?p;Hp@X0T@|1WChfJByetoO5NR`V5aFGdYK6foPX z&x_^)ZtC9X-~hJpdLgo$m25Z#pWh^BI5!@gnp1!9gK^m1qhD2eBdh}|X3d;v0S9M{ zqfk@}w1ZM|(?^x7F{)!hc~qWte|PoSOg+|KiZh!@7YgZQM%16lL^_wwr?TlBSEQJe z_b>KrNGIc&TsoJ_XS47>naUU9@icrUF9vsEZQC;jofhVEkRgMM)G2?tgbUIt&pa`? zeQ;uxDmj~y}sAA&AV~b{;$tMmaD<|NkO%D+)gWGl0LU zT!Q`_y$>Gi;|isoFgjs&PM|@UR8AB}c7u!=kG=R5=+q0q^_%0{ixVH7+P1S$TJJBf zTAp`n=?XAOOe&G8R&eaVy;)0lAo z&&<@^!Ko8)_rj(4sup#2YJ3Uq>R6m!02LR-pNQvzPlOj_a&>h%Qo0PxoeOx;A{rHF zsl2Hf0W<%)T+T<-ae0k46w;Yorv4>B{XmHkI-ELKdJ{|&kJL&Bqeo*mWt26ckDk!E zWj7SEK!+^!L>c(TY#uC;L@tNVhFcq3>_xGnH|zP(ZKduAdSbAmdREsH!rK3xSpFmE z_fU8QcHO@h0-fbf?J4yGS8S4~#SC^}au$?LY{6!?jL4XLW5Hs1*{={KgR@P*v%}bq z&fF5?-2@wrPOMjF)dSSOeQE)Ed~(|{nGU+8)CVeTz`I^%Ic8|Qh;_^Qx5CVl2|Xb| zhspF_c`_X;XI#@I4`M{1!&pTfKXz<-0S0FSYNhGdKB!ZhN-^j%4oIz5M>4rk(BT!g z__NSpph$b534!YjK8qKJsr>&g3MWH1DUYJx?I`g-bzLbA(l5-(2{I}KD->5QqoNjY z0{2oT{n2fM1AF(-Av%Wu-HVv9OyotOgxYLsb!|8s)jY8Tnt5a8nwb$(B$_=j{j`l) z8xaPNbp&CifY!sB+0slK+NYW9E9Rf+$oyaEDimHHT7;j#1r(@&0?AS;jE)H1-PYo@ zL!&U5VRjT5T#-3RkZ2Maz4=tUl!RVVIHoK}yAZ5MYcs{+kO{yFGT|ur3~e)kF-;EI zEYV19hKC`%3Pvx%6p!T*zJ~!8qM2H#SH)0@u;Sl!w*X5Bik7iWdopaz2D2uTD9$Kr zGDJB5xs810@QX1|XCf?-OCY1QB0>%!D7F}6HsAQlZcP*r3r`3+tX>4fqGvR%bTE0& zh5g()3*`SEd(kj~`zqEdOfK2&%j2=`2=ioS0TmQ&YFRV8wR+W*?+nd+BeYQk82hL% zOJc1^twjgKs-T@Zlvp7DC-B6Sz$=!HE#NL@voJ~o#G+G~BG;7Zo`6^tD38_=3*`S^ zLH5m{wLybkF)&cskj>IVI5Um;M$nl7XEn^4x7Q6eQN6?RMwGz)s$GPb@li*fp=9}u8f;F*AZkD9p zMR(|2R4@-kH7Mz{9x0D>DnMf9Kp1=v=FW~(YJe55d+W&tV z!Rg-)aVyuA@)7hlbJMTU&>KzCLRF3HY{<>nDoJ78^e?6`uF$SHHMt7NQkn#7|MA5W zllaqi^T(G|vTGi`|4feqi0R3@ZC2NJv z*2Yx#&-!Uafa0?;SV`7`IL3B>kV3~1(E)b$04sr>1l&sSc_!pA*24F}t3>{lzeVsD zxV1&f4vr&{~WKA{>IW~ko|2oR%{^qAP8Yd?$jdcs^iH;0hs0U2=+3*%FEYC}w5KLoW)2?ZE- zN17M`+zzP0Mqsvr`D;|D%$mR{*gG>dkFt4Xq+)N_uTeGfmc#BDF`82paSYc*k;X>gdH1N%lpoLPAqVs|MRci^p3l&N0{&Nn${v8N5W zLxSL7T+J#FuAH3S6y7sDQ4tDbaR2b&coABOV}d#F*d)P;ag2Idf(5OVW1M6DHh^;t zM&c;iHOWmk7Y7E!vIR^lZCO@js_!(5D_mB}T#I=y6H7QCfV^lke@LE(R(l)Yd z$5QJD@GXjf-5E0fkG_tSZ-Cdy?$rIIEinIEHiL}kpv;*;X{yxh&V-5Bdh}riC&<&a zW@%#IXvX5y0v=MLa-D8b>G%fO$6}=`Bj~;Rf?nL(ks7Cx1*L+6l`0nZzRm)?ZqOUp zE5Z7|hDF|{dnk`8kFio&d=^uSVS`HLQ9_ImWJE2GDvuG1C;5aVLeK%EkU|JLB!*}o ziOQ3d$It?-@xrqZbU;Q(Ap{)~SB$v`QVbjL%cF!CAt(_{il>0eqsn8-XkMPg8e@58 zkAj*N)IF$TkKv0AQ5i_~3V!7%vF|Y~9KjklM^9ol83F-a9<_H6j_uK|P3#QpYeDV| zAd4~rqEKX!_W#!-|6`yp6J8jonBAb%?|BiALoo9Tjc88_ zA*m3wZ+a;KFU+x<7SQdrYiqkgj0+|nn=M@xLGLTu(+C*wa;wM2p07n#a0w4iObl+@ zsjfeH68nSWusR6thU4I@xs3HDGrF8@;hjxnd6W<%1R3P=sPdSya)cy8&;g{7LI^q} z_E#wZju0$EQwAocG)lKd3C}{%0aYOd^#Ax1>nNn`N8vPhfolK-w9(QaOs-wp5Vhz_ zJFrzU@}U70b|dttQyceh+&?uN?@z|A`lO1385-O%wrhlcgCLbk#ik^!!?YSi+Upd9 zy}tK(UDox3q^J5V^V&_4kgih;DRGx(fDmG#Fm-U&xDI}BbUQ3hCQ?cG+X5K&@+%29 z#IM}KUUE^`48=XCc9yPz%Ye)q=#3pHfV(~N zJl0Ro;YwGTDAl(Hzm^-ze;5@}s1zE9pX%IWq0)93c}h3v8k_Fr_O#vl0xJ?ecSAr* z)7j+_Sf?IERR_*MvAWF88$ArL?NM#B8RWKuF6H4(rEOtk-tJ`zhsX=i=4|}E?&$K} zrLAxssonYm`}{O5P+hzoZW%u^d35^d{K5$n2}h$*;)2HHUZ<*e9-ldIWRfWj@)7Q6 zWzn28Jp*cC-8$Y^L-ufxTwv;OCWK$Cx z9T3pX-#$zKeT_c`7!+8G25lP056jqPvuS#xIJ?wU@fRrUN7*LBHOxcKlx$j~RnZpNXXX+>*SQzq{Jac^l;4Sx#IZZkWkwjGV_N)cPeE>AU;a;Ok4 zsyc86k}b$=+cImPX7%hb>(9s4@qu$w+VQ=!tkBdyIeqHw^1+g-u)^bi1rPkI9s6Si z^2>dtVg!BS7CvmTAM@32l%E5P@7(UR@^-vZRmBfPSNFC}nzU}yyyoMyFSkkidehz{RodRRyk};1c4v2I7rToE z2vR$ub_cUFXU?2CpZU+~!3cVvXjzN1!C~ zDq`%*-VSKGlJ|+o=dr>>RL5C)1E(PAEpgCpvZ@TBr4~hQd3gc*|9*{=13qRWZ<}F2 z+DEBxc|P`5R`2R@votF~{$Cz|?alOzJhC&%?@^6Fy$DW~^Tw~17TFs(@9gh$e<@He z1{P_WdeM*nF;Vrc9T4&(N@g7&$Gf>}kxCPpnp;#qASvpWFZDg#fI=-l#R`yWC# zqR?)5Xzu)VtAk)JcQru^c`yK+t_H7Q>jEaGu(~`^)5n#v7+o{IP8kcA%5@296HCip zU^#WR5Y93fusF-0b~aXZA|MEk>b|6{)wHQooi#~iV)>Usrx5%FE}%doDRA!E)u9L~ z?+9!P*+%Z0+7s9m=Ng^b|35|2-RMsnS@}(a4c)aPUb<^C9C}7&Z8Y6IKki01uw43FrMLR4-h61)S=9|IxJKO8<>Y(egcq#o^$XNl3H^hzj$W42>Nk)`c#oJssnM+A@}}Q9j6mjixmN!#&y;zZ}I&xkq{ zgcT6p64xjHgSs}bW())Q-^B7y`7IDB}IYhgmlEc$6<)( zY!k4D?0)LP^{Zn*tga?xr?uxq22wyQ!0#h~-)IZt_mh~}wSu*Z{a=4p7SF;kN(m~P zePV9`k0_tKB^HiRvCQyWkfEPF0Gx$4%yCL^ZWCWdtsYDsQS~*!{_EvmgoN9AvpG}W z3mZ^yI3+j^m-o7v39}|7g}Z^u?WWiqx!fe9)CvXwDQ_sxCa{QD35Y7u(Xc)iZAVUM z>*QmTrOBiC4vd-U#ga-25jN^a>Jd;%iD8*Iu=h*)^`3AI3~%rc7)VTh3h3MbgAW(Q zi$)(*galaBs%U5*rm z+(beg z*ot11+LrV()Xqk!NgY`lK~9cin@JN-wRL!)ZjK`MLSb(rx!`B4AzCs97a8`owT*7W z<9}PwEhuy?`a1e)^eA}sF1Pwf7>P!66bV!ZUbq!8ENuVk!x6MBycUq%PMTNlFjRkQ z0f67+lO5x^)rZ6ga2YCB)E;_T?t6L%cSY^N zdPm2Gdk1h`>FdN7BUjhZ9a*#qtnhR1np%Azfe0i2QKa~|H zq*x$16XVsoy3s#S-9Lkcoo{I>Dulk8Ze%fA8AL;e5d08W^#-(h$Ha|M6&V2*$~R0i z!&+T@Q?}+xniqU)+rsh38rlCNWl(4V9)WX6f#>6^Z-;h;=#pFaIH(9TqGhRT3U zb?1=m?;ko)cz~>JcCb@NRpJJyu*IehsGtDA;4F0X4a=C}n?N6}d7o$3KA(o0oJ+^$ zj=hPP%ze(Y2)EAbLXC#MX>`@F&|_|0i~2I*vt_VTQX7h81ziur4giJ=`U7MK+K;ZG z>xs5c-!4rVUBj0Zh(!!4QlX8WOUqmjRqLkyjMzrWlS`%fi8GT^OG~qI2e$9F+CP&Z^*MK~vwYNi;Le@TMdI26;+WJ} zDQWf{-iD^I5S$!nOrVtA>4u8Nr1t*{NcuARLhFf_Ym8R5tWJRexW*TG6mk}0#Ktgc zcMZ#KVXV!1{rqjKN8tdsL0<^b<+_zqf>w&_M1-_;sTOZpvMPo5y6F}?LoMVtqb8G& zFBFS-NzTO7{L)-$*f^dL$1agcX5y)2HXF}%cSFk$?!d|#+I~nPZ9gpk5wrt^ejt5E zii1b&K(0>sCRfQ=UO)Y%R)B&05Yc*I%)I~#&m}QrX&hK7sKYgMykvRr>hTC#v6&DR zY}K(UpAaF4%$6&d#+K{=A*r_y&m-v1y6s57V9&2ZFd6NEYApIzjaJwbB%573eGUfG zxM43K#4+CpA(UHIRqhEP1ZQAVh-2FWtZgS0j-c&-8A-BO@Gtk!)kjuO!Vw_*JlfHz zNm$l3v3PoVW~L2HA{7}c2$mY6gcSdL?+P_b9}6r5g1XW>yUHYJIcE9 zL*WzM8SlVcl;1PTo)f}qIlit*S-ZWKH5HR*;CQB)vrP3w`IA)WP%$L+^4*TG!em)7_nh>8q$FRJN_ZI&`vc zD5sJ=nH)j+60S08|6f7UD>bS<_`Fdla6Y#B7YqnYx^%~r?+^Yq>EE6*c;gY4JUOj5eEA|b6MN} zjV+|>VE>`V|6%m2DEvn0Z{f8u+)CH#<1l+W;fqco z)2*Hca7juh2I(-Q234Cxb!o0IRKsa-?Mre2sY&( z!5oh9dma(1C!yu+R}_!VQ&O`Ho*LoRPs&1%snz)iIw#r(t)+1~)d8h(f|P0P2Dzgc zRwcn5#l`6pa}%eEXBRu$jJQW-vbIOzuEob^rb~+kj$p+mN4Y5YtMh*m^eZUzpVGfe zw}NK_IJhEt$>NG+_f?Zf(oF;6IV;$(_N&Wdt0mxsJ^l%gTP#1oJI_3Dpm0xt?f4~i zzx?d#B4`C^{R*b6c~j`YO``#>>N+OA@Wk&c1s0l50b6t6*r@2u0iTSgqd^atECVq3 zr||7gdW+<7Ml*pI8YU8OdQT>vhRr9i$t0D?WP4Ka6fEAzX48pycTdvuB9?k=0!I@U zQ?yC%D^5Hkn@c8P#bz>|%4ECKJw4soc-HGo(0ZWn(9{`in8`5tqLl2FyOHlbSJ?*U zdyxNMQ}mHR3#LupbvT7_o^2I zcil(N3&A&V_c7=?>N&=<;#`lG7xeu25SnOf8FX6uq-I%&)|Y? zzZzbf0K>Z444UIEj(&B48IE%^S|=no7Q4=@xDBDOe<%eS_fd71IF?nLjMhgcEV%hx|NC5ry^*zuQlbz2liio zOL1;^^(^fDX-@m0VS1rOHd7>21cyBWxyYrUx__A7RXJ2sbj*%$Vv;p`WC zE2lP*k1UKqU?=dVO0{G@aufh)^00KZEQPd4g+i9y56;G?@Vc7dbT6cxocMV$7Jy)Jg*h_WA-S z5wjZwWQfJpVzYHs6hYel{}PhERJZg809u9u=eMsu1B&>*brCQD=X07-b~yRzR;+8} z>bybWHe(|4b>{x4ozu>bqNwqD$GPYuq#X?xCz^-gOxpi&@SpTycm%E{1*+q#&qdIS zi6%%E4A1`d`A1iug>iwqnvk7xY`tc|L?(tZIinaTIVO5=uB+io9JlA3?I}yZY3%0F^_NE`$FZQ-+3aj^m zv}Pk7mnW6VDNcU+X<3oYcs!ddWOHf5$LvmH2#cRh^0Bp01&9io!~?kLcnUhncg8cS z>ccfNtk#oF1Du}ON);KeO6q8_$Dx&v`wQaG0^ClxRmw4$ruPcMg>6tO+-AdtV-=v=Jd72Ay8kzX9zmhc!oz2G{_W*0(0T3k zQkC-TtfB3tT{fjZ1-*RCz0OsZOnrvC*_ER<|2Q{8LHN|3?D| z{U(0Y=c=Ldl@av5sPigV9_k%<@S(y088&10rnXPEceWpGU;C=a4IUwO9md8lmV3)r zM9_P#aGsq^I*rf+QX5Xz?E=uuE@HE7jaK$vKDxAccA~^?TBhfK2_wsEYffU?ToF_= zubL5vVIszL3Wth(%2d~h@xzRE=My)tj6#^ zv>6I;-My@9E5QA3Ym<*+^uU7!jf=v0m6nBFY$eK09^m(UbGPUq>G7mFvx@tw9g?kE zBwhJLKRC0+M&?VCM`w!knl$}P!}rw2n(mlGSO{C3I(2$}dag8ad}(Ip_~KcG8v?o* z=rT72qkZ_~ueBX8feQyiu8~%mI{qi2+YtVxiWuY1eEk#cRCwjvn; zO0A$dxk7VZ3vI2o#9EM^9QM@fv<&N53qZyeLK`~K|Ba0Q!R6oZ7r0GCf%CVOx4GMj zvF5yVG5tJ<&?< zwkhxHkaKH^tnW>ATt~PjeN>g2x(k}?+*mZ{ZLt{$UDI6j!@jv54A*n3_BSP`JN?20aU2@g zu#8(-HtTr}H2@VZpH`=&VCPrw&^l)QoB#KNO78BieOg{BzXt9!a(v!c%h4Rxjd?2g zi`SN~j-a33(X_cNH_d8jjDO*MuPL`h&_`}*0)mj;=ivVrb*;r#p7MdVn7ct@KU#v% zv(B5^nlUwkNq|KQs+H+!Du`Vf>N5;MYu?Q&SG75=%t}z|HG=nXtt!n?OKvbujfh69 zH|R*Us3?rlH)xSW4R~D`wVU{(bF&^rJEL zVA*@%E1_?AZLK#kAa|Xm?SHuc^ZTKk^!<%-|L4jbgbJX`%?@^*PMpw||6DE3@SKGfJ+V~0hh&nBOqioOT z{_^W0XxZsD4H;J06;CWom(EU*C3m#AZOc97Ya?i7(P1UDiFy!xod_d9NgTwX7%3Zz zHQHzt)56G_x0Nf)uLb_Op=D6_t&mFHv^l2*mj5t%6AJyd^f`EO?%eM3>!IuJ^o$B; zf?~DxW>cqLTSJJ}j0{_|Rq|U^$CNS{z^6Byo(5Wvv9ZaVTu{k77g>dtlobw6Gbt!WCUzALZ&xT@T&sN$UgF-0@qsY~zKcNYR{T zfKRodoXYiV0D=!?gwy!oK)O^0?sSjC`E=b?_vb|Z(aQ+`wTdgBEWZ&B_88kF?ZQB;*qMV(lcK=>*J_h7`;TQF7?irEb$!g8 zE8m-}zSx6iGOiCcuq)M*$fgp>WEM^x_0qQW0f!AocVKPh(tv;69ju@U6&?b`9 z{r@3!9EF~NN5kCt>&iF5Zq!|YMfamO-Y{m(*PJM2cA~xk0cL!jf1>=R2>Rim|K!Uc zjcd&d?f<`|^M5Ci^mo!D=w!nb0D`%xxB5Fb#aIy^+d6%!ICGYbaB3RP`RJ&AdPy5n zCF^^=t~I?NmERIUFF8G+uyL(psOY}}75wHv1rw(6p_S7x6{yTB^(kJ{UXJbkpx1-j7rxhg(ChIqSqZ{UdOg_wM^HBkeJS)oX%#$9+{!??9gbap zi+yumotNbL90rRl*R-(q-*&Q!UGfG8gi#YSnMBc~xqlFKdPRXk?vXdU+Y)K6;M_PH`NLADA|`Q3vzAV|`o~8NYj#ZsS4YD)Io( z3O37K!_+#i3PX#`c)_6X_?WV)uH?m~qlzK{>BECVCP0I|qkV_q%nMAUvGK9N-rv3S zu8%}VvW0^mMUHRw5$Mi`HNlZHd%grX?p6^ z1YPvMwno<4!>z5tU{y{#@-kfVq?RL^zlDf8wmC{1RrL8LijiemB)$x)pLoF3z@l3j z)cEaz8s|7e^Qv`%)jkX60xeZOBfeStDvDQ)pn3qTrpD`*e@XfZg1^9RE()B#rMv@1 z{0^$xL3m{*<5aLujns06wnanpqB>dCU&eM#jl7$WsfCia2v${!weH7!ERj7DJP}ks z@hA!%+kZ*=7X*KSyNoDsK2q)g<#6?7svIn2%Oco;$Z^drs(vg$Sp>Vwf$bbqQ{}k^ zox;Q}A!SYU+ ztnBesIMkY_EqfISlNzTDMW_jmr)+DSR6Z*mS72>qgV*@yx0Pcc`ET^KaD1+6$-tvF zD(K3SMz%0~5<7WksT3t>Y2Z_W*syPzvvPd-=shdd5+?jCvff7td-o z{$xCz%cNkpT|AvgCVG;v^^WAM)M37jH=_9VRBf+4iDxSbwq-CB$-z&h80&|!FJuQ= zCy7h#A+N4ybIBxZZ%oEhnQV8ur>8p`hmd4a_+d|1PuH{0l7!?T1ahD-+S_+XzUr=* zx(ru~r*lf?@nn)@pV+AZGX*4t&=nLhCT7gDv`_>$@M=XOA3*-Uso=h6m*VjUlLnTv zfuKE*aGl8KrMA}zRqq@f)O0dwqY$XVr_W?OjvH$5*QS~Z{yX@wCFFu|BM3M6`$kFN zTi7QDir+FyTU*B-yfh>R6U*}S@wug$L}$D+F+*0X;17Fav5BV=)18YkxTND3pJHeH zjud(aVry&o%FgB@LrOxjRH?=rSVj|aj!j#eHzGH?Okx7pOWQGhrE4|4W~l1%UBvB$ z_t4={?FaVZK;pQsJ@L+-#4h@Dl0r5?0Jw6LG-FHi-}v?Ag|o3z2^A4JbBx}sFmY^p zp*Y2#LQ4Hg%Q?>~UmrsYCGqer?@9vwOBM$!k?gHauJy8l4#JA1rYB*r%=i zwX;T#p7#I0fx?pX7w8)`B5%OY%a4~6(5E}$c(jYvnXa>}@Bs{Gah*2KtB!NYi^Zv> zh2q4q;!Lqrl;w_O%sPo(Ry$-eTlZFxLzW<6%n($3bfu#lhxH9LHc)HXYkgC04%#vk zg%~!5HkX;(K{-D*ri0DQZBMxy%x#TrthLOoU&Ys97#)A6F2{z3!N$bK z&FuFpAN{%C@y>obp{4RnIlVEJACQ?hybY>7h5kP3UpAAh@Gh4B2zm<&eMkD16ao+L zmM6=5L9U&zAk%nU<3gsUXoFVQYSbbDF_mRmez%~lGgK%5h0JZ7LhdywF08j|7IGzA z&Vq`nv07iNK3mJ~wI&lWe5upK)cn$1Ntc1f2R0?qrC>jtG8fa-uPOHc8S0#~Rb<^e z8ThUh>nJ9ibQCp0VS&-AOABWNQM7VR#=!C~g+7hoFK__`HVg$;4wUoIaB#kU(N0*r zO0sTnN0UK6jG0i+a}5rY{0kFA$9Pqv!;rK861o}TKY^<}TD~KKUbu^?m70{Qi_FSU zDBhO}PGZ|w!B4lZf`^=*PbL!}Xlj0LYBC`|0lPDG%1|xnj=TrNF(_E0*S-@Yp>3w+ zv1o6{gXwtRtQj9sqKm2XqMPhey zdt63QI{r6=!pEf{f&2$St|)N+`tqHywzkG~r<#t`X)X4{gUaIftO$}@w*pz7U`|w} z=|yMOK!BB4%R_I!>Oi9bAPr4xEe8Q}o*t zq|w6bODw_+j-DXne^MNUJ|le?UV*DYfoizi8$s`DMn@W!X8qF#qvg9J=vQv6ukM|8 zSeck&Wl$I2)gjLgg%61HKUeN9-vxbu8uy22g=#!jjudSZ(cmgkB>%AgAL#fUM_4z4 zBRD4WRq1iXcF+2LRgcr5EGuN|B)ApWW>&Tbt>qW>>!w~^^b?k%CAl5s{~v|eda1iQ zd8_U^V+HYmd!2c+oY%P>-H1}OB-{E$?{!zw{;L^x%#WM9WN#*B9i^${4uYDR)rl}U z93iDYeu67Fcuk!qbsqzpujJypx9N4tMV-kRVRXtN5G$a7Ri#>gsnf(bN-nG~Ay-r8 z)JkD&#kQtMu}w{hZruJy$YGbO>9k|@;F0uoBxgwji8XUHqm8~+0*Q4nXyVoglKwfC z(8f7B{=Wx>BGR75<+5oYFW*=0gT+EMPU>y7At%=SXdxj4WcCb(~BmdW(Ux{~q z;Z^ysJBe=;JbwlM$|@Y<|yIb6OMYQX)nojhx}%}&pC$nBHuo$W{4JK_AfWM_K!p7d^bCX=0+-FFf% z`<0CG?OP%_1klR$<+nj2)&2TFjmN;eGfCvvb~7%~Hv~j6b)eK_I`hOu;k@FE)!RfU zckwvYNQ>9TWxBglARsGe%KfmC$Nf>SHL~D7b6$&r@Kxp$UAFBn9PA(3rnvsW!NP%l zxSEOn&a=CI7>_NK7N%!A;=2>E{0K{9d@IGk!E`k-h(AyB97M<|r;+q-gC7EJ;RwHt zwEv}D2>t?RPl46@$^#MfE~jIEO!oBCp3b#38$_(hxGJyKjH!#Dz*n=;|7O@54z@8K zI1@xO5U6fIl%5S7Q$e4Mv8_Q7c!hSDUP|W^H06pr zYiM--FAwrB<$V_a%?|FT9xfk=px?9KE~9iG;2dpwHe+^Q4o229~{zNg9e2%apx+$ee)?f)oa7C1h#g&0?}Q z1gX6%!z#I`8ktM4LBN4L!|1=zBwQ}K&$@67XOtWszT@eq;Rx{^y(2J*2=2Zm_{2x` zlpVhzQhxg;Ng~|E-x&w#JA#KL{t;wOp`ilU>ums@i0Ol_=Kg(%?WeTVR_u|y4^&z;a z5T<}SN~OR8`TzIcgM+=Kgd%pNAIv!m<2H{`o0pS98F;lE5$sSiA!`Z{mB%4jH?>G? zL~-!U3AmF^6Px+Nsi|jW-I3}z4QCs|iBzQyxbY&^ zKZGmC$Q-rFs_<$@9HQ<}I1*>2xk9`rjgRVpo8R}QVLV%NN=HFs6YOIL4AG{#(h|*N zGSEO?p2703rstc?N+1hjZ#Ay!VPDu={eV4!Ko-Q_y7=S=`@-I=@oWK5mliHDVoz4@=AFk@X{)H$s1PYlAC^akvdK;pmQ1}+tu3L(MJ zT^|7JEz{fm7&1iM=_LpG`~VGQIk0#BBAx%+3+sQ-UaSk8yO-}M4@c0)?62G0Jj36N ztQLgSe}-R-#O%#S5QV7;_=p@FL$D}11IymVB=$)81JS*%h92nJ^K<3Sv`sMz7C}GKXHH;LZb5?%R1nAMM*8SXv)^_L#{NP?{^9D+(3hl7 zNEg5pIM)=|Uw$NlmZK(aKTsH*gcX}nRqwEXKUll;3!m*wceWr}qq&g?EWOj&73kiCuO!IP_CsHfiXU@xMBF?Kt@X;OsP@!#5 z^VM?I#RN({7*Gm#f&`R;>!5}n>>cPO-3u)L_V<51YQFzV2o@?p%}i&2nUS#D*Jn)3 z<)8xP!}zS!2)bOg*k*B2Q)rQ_5%7>)g|EZN5gn{Bssp5yCg>BXWi3yc(%g0%`>jz|rFCnXC?wwX0N*k%j`UXu1%HzOnpA(J2)E)$r-?uFyY* zelc`Z`YGu#2=d!qSS%lpp!c7Of=%nib}<^g8vbJk<0|A$AH72d;PyB0tDobh&s=oy z;>gqujSUPizxI~9lGr>0SiLi*Gv{nZ3?Qg@3BPh#F!<2Yx*}aJhS7YqZ@2&_Kt!XY zg5WjWfAC;oI69Qa$zXu#7I=03;4d%z$(Jt4c=6cszVb0Rx#T%xLWo8u#Bn;DFb1#A zXh&4>fR5O&^AqH`%nqx~!`d4I$d(4qSt zjY_Cco`TlVHB46Wgl z!IWE3em;K%O3UU&kpPvF^wtNaeOn3s}1?5BK$B3y= z+FSs_OcDqY6dOYEKke^OdD=B7HMK5-_T`20NjOG*nvp>!3+iJsz5=&{Ewa~LlS{tH zcO_yMvBP@eBECI$-4i4L3ycwcD?f0+XGUIq_sh_}`hTE_bx&b<{J;Tu`L*Q}z}~kz zFEu$OxIatQD!Fjs3g_Q*La89-q?NZYqnquG-oAu zeU{2MhLuD39sXlVNux*3?_4_UC}GNMLaV2hH zUs6r4*%Jt(N{ks85{*QB<(2;>_$Z8x2$23)Ug;kiEhwNHoD%P2z4N5Zh!Y&@{2d=kN5-~tK+6lf3yF0_>w zBIu>Jv{GXkp{-Zp;&P_QWna=xSANa9HQWGu8Z;4JaM=G3nh4xzjENd`vOAnw+URit6YMugcH%i14jmW`-jNpkBPbNLdoXuZ9^);23yq4Hx4R|J)xX3w!W4>@-yL2SyPr zfOT+W9(9t4K9uzz}{%p;p`1lxgF-(*#OcQ0bmZ7Uo;MN)J zgot2hbaxpnqoHThXlOC{P~VP_Q^2uhIb7M;BAC3Su&)-!5oBk@juHxU1!IeUY>8z~ zrK}aw$l)-1j?m5-N2?r}Lm!_TH}D`is_db{6q)}+??<6Qc(jH)mnol#pz`B7LD0(5 zd*%czcT2{A`*h3Q@G`gV7%Wx;afLWA=<&Hrmp*2WlT_m1_;D_N+#-IOi%(%*y7Z}! z!!kO|!I)w=$4i%f1qU$#;vjJJ=jdUC@c+g+$Z7W?i+hYQQ+xsx}sP)4ZX~3a2PlhUGtu#!%=Nq#uQsKW^o&@>#gf zEzCCEGaYTc%A2jBbh!?lY6Tfj>2hww;M%RADh2}9ODg4-RCTUxFi_W3>XubPQb82F z;FMWU@Ty7kivBiYN--;uZK#W9=cZ0B%ojTPM(1|SuUuVz5@xM$UMCVdAem!Q`9zSB z@)N*QyJ``Ht|FH4!2!jI>ABEcgl%GHd&zZzZ>K~v3oy}iKj|ZqlQXCM{?tPA^9p2G9n*A!+ImtVa;OIjIi;_4F~dAsusRR zH(}A8i0zQBacpI_L2S+TUoZcT0TKHTs`Z9VPW{W7@oF2v%_wd`sa5l!YikSY8sz`= z`X;TK6#B33S_13VDhldbt+ZP89n`gcgywSRaNPbM#y1|p%}=e^*|zA5Zt^BeP-?A$ z1C3VOys7Hnwav!ke-ZQu9{(Rk-vEz~ZW&bo_R1DEScHeUMULMUMfOLikw7U;Efi;q zb0s)i^vvYc($Xyb#wS^1(dk7;izPS|_3+5>$l`P&7Mm|W2b)%>YN5bD;49C(pQCCbX%2kt$Ms{pc=^f%zBYkMN;#KrWv%aN~^;C(AY6s z8*DND?}e;!b^LGZ8&&3S6WjqP3Uhc%qyU;A$TKh#EK@)oxZBahoR8C+5(Oy*L7pih zyrR@QG(S-@!7>H7uB_H5*aoLL^#9)kYrhQlQadE=1`raAqC8#wkc(CXE0vi;H+Wrp zu4h*lyb8$Xke$paO(CWL*II+suBa}}&}nQ@xFF1PF&kS5Gp1Y!ZtgRZSmD3;IJu4h z-!;G*xn#(IrE6*AJgsBD3;f<0Cpby=R81j(CNoPMeZ_po#&6X~9GHkCPf~^nQS*) zZ{3}Z=fty1dWI6C83TtqsG~dNnaPnI{X-+84x<%%53p1*>UnraX=1sn5{3#> zmx3{1>`h9l{-{}G9Me%G9I-~Z#0c-NgkU5{y9f#c;+;IXRGL=?nJgLX$M#jE2>Rr6 zR@^`UD${J54rAGv<<%VGT}!wX{a$GMzX8jCNXnzoZg>RF4F#6xD_6iFc9vs{vi$hc z^wcTZVBocZ74ujo$TRi97)gCwBq;1*5Yr8>vk@$| zT-gZW+)!mJIUS7-f2n9N51=!>)R-bGLuzckj!jJ~zuC;TAy}Qk4x+{AD4~Hsy+r=; z`2TKy$NsS(0k=eJa7&{EB;Xc$$h%j$u;3P`(JO-*WisTIxXSta42)m8X)lp*m(ZXM zaI?|61j19F@HD7?DOi{FOE=CM?V#~@i*a&LQeKoBT3OgmvmMjMjEuiGESLN%?0sq> zxfy_7pOLo4-|Ix{%SK(W9t(^>LNAS@wz>CGUuUWhc+b?Gf-t2|HjV{w9UX1|e+GqL zM4wqlG(2U!dSB(L2zu8J*ZpbN2}~XEpotVTk;ENpZyNNIYMb$ecT~1T(1#1IdDL|R z81LKqRyzLoXDHk+{h22r3=*{%1y&X-SHnWNQ?B{JbpnG{lowAfOwXN~m@UrEFPzm~ zYs)~xHg)%jz*K9ar(TS4-2h;WR9%m3vgL{)UrtrpU_NC1$u8dEVTCr9e@Xf%g1^AE zECtSwS6&lA7ZOa4)Yhxwv6u!>*Pj~W(^jv!sp~~NjWUgwM`-fu2Sk|gtF2n<7IGH= zS`H!I-eFfWI$MC}=cVKD-1?sIzlFaa{!aMY;lBxgHTv9g`NtPLUW;$p`)QkLgS$$p|^z&gzgMwL&;EQXnRNwy(x5k z=ry4$Lm}zkrAyL3Nq;YWQ~J8}W$DkP&q)`h-o8IEqzG(5$S!>^U`_g zS?Nh>L7I_{hwl#W4X4Aq!yV!F@SDT055G3NEgT8`XXsx--wpjk=x;;c2!BL+hxCv% zDh)}8r2WzzQbvkPJEhyCw@Po2UMICt(ck*v3vf`^)}OdA1kVp$xEG#3exVFpr>YTn9<4kB&&kSJc)p{u1kblu=HU5gWg4CjSB}B+p~_KsK3I7N zJRhjM9iHQrhv7L=c>tcnmHXg%Uj^fKq=IofT)79HLzMzN-&WZV&;H7t@H|x63(td< z96ax-WZ+q-q~Up>l7wepB>~SnD{**cE4UOr6@gc*$&Ti<#u?cD!0KiS%KSQ zwk9e!!!usNrQ1`v37)$vZ-Qr6<&E&{th^qcJ1aN9v!il7Ja<&CgXi|jweY;X0=G?V zy{&Q$JliX;f#)q1FhyJC%2n`uO9hTj+xq6p74W>N0xY`q#tP=p*Oi}!=e1=_vDcQ* z!1J1N37)ShFTxW}*oNn}^5gJ~mQTa;$}*TD*m>NG+#nd=c#nhOucEWS6itF@L^;USEtjh2_QN`swUVR-rx0XSO zwr(k7$dNMaquClR<2sVcqp-r}Kg+}L{Fm|(c>bU~1kX$50eJp%`CfQ_zYI0F<$GnQ zyDi@>13p{+SGfY}(+U{GvU4}Z{@~tw|=9a%L zr{MWN%7FQnzb*sLTfR|-8r3 z7{OoQT8{$fAFW&ihX1a>@LTpNT-a@$nf#j{`X$v;x`5%u_J8jq%P+WJkl_L;UBT2+ zfv0A-g|z?i(Vy_wBCb4Ld2Ix}=l+1_t$E&Adl)!K=PbJk?mOkJ(&~3c2r3e)VBkRn zd_b!6B~tnYR9?(>Qo)vrOYO!)XEG;-(ixa8Wz`4*LICp!GX9-4>j%o(25@ z6^orB4Q9AN9^4SvK&_UnQA-YMU1@YHNq!a4jr`N`zduC?{x*es@2!;^BIrZ+S}7h& zB3mVJBS@COg-qJwV&|bS?vl8R-I7|#P=%HyS|{eR#E0-B%q_;S%m?=0P>pSE4HkO) zda1KMj6?IRaPBe<#LcP?Wv$EIQCJ+?!J;f$q2lCj+y9%<{=Yu3{|-m$n$!(9Eds2? z!Nwh_Oog@Fz=n!gjS{u0{ojSZr zZO(}ka6?r1sSX9&@Bg_5Nw5+-aKM0-n_%A0`cym1P9eEZnLV`I%2`M>+B+~1jo#ls z3fF{>M*FpJ@Qn@iA0A>MBp&{u0%3P~(-^|YYFq{d-VM!=!%mnH!8aw(*^Yz~@9+pda!~;UbqZ%UKAhcw zKbEq%s(~5g#nNPH5&!5NxSu5Jk9FXm(TOaa(@1>ev9<;^KtLhsXa{-sjpzL8Hw%w{mR9aUJGd{->(g)#z}^BzE|Y2*s&9WuMR_ z7532;;A%c#WK5FyROKyj*5=v95=zl0reh9QVwE>THMw6uE~+MA2g#luCi1C+D!7j7 zQz`_MqEv`VQPhI&($jzRP8xir9KEQ)x9Gqd{ax)Zd!@*>(!;u8GhwQ-S$7!xbuH+^K@D)JFHJ_Nhu!X#hRNz zG#i49VgYtXx86fUQffiv`fpt*8VbH0L_ZLz2miXuLHTRMPB)_`K5(9xJnn_q60VW&Q6!8 z{0IGi2ci%C|LxxT|Mt4QK3!g`&N*H00|y1r3_Je>B8Ar|Y?wO5@*hIGvHgcrgKD{R z+bbQg!o|Y~_~jx3R{GsSaQu~CE)%f-I|BPpG@idSUTJpElEY2^@!8ParR2hP*Zw^H;FTSH?zBumRy!5v10rTC+m_TpngavqmlZek^Bbo zpT`X3}P**qC198%PGDU`{0a$Mt65B8)if zToS+)G*IrFv1ItlAOE}an~6(mmPN!yH4>>wlm&pEhE}lV5v*BOVROp220G2+?RrYv zkdn6I5EHL~o33(dFpA1sEmxB+Rez0g`aLG9(v6eJy6qO3{|~($g+2(6zy%Z_6!^$Y zB_2V)^Qa;ax_t%sN23R8VN~j_m&Pl5BIxI=?>zKx`lhJ^;LUCTT5BnwGTbJ%^=^k& z(TT1J><;a3SQDM~N1DwBPHIn#wJW>RtX80(HqdIak82KW+8z$bf3Nj)Cr5#X&Dx5Y zP7PJL@A7Fawp>Yr9*#joRPLms^-QO$yt;A5(m?+AH(>0>Z)*eUUL~$r_3LV)MqEp^ z7BpXi=F4Vmm{~VpaCgtBzI39*sXCEVai1-`8;7121z^P%tDqW*SYk_+QzQKbtc#%e zqFE@*YWL03sQhD@l^R3GOA2G+@jnS){paxZKZGi8t0W@mg*PhsHGOO-7_D$I18r9A zszTD36ebARYD*nka-kbXi8G|R7N|AyAQ9Fdt&OIcs$vSd!lh<*4S`1FKLq=Kw7oxM z1UPtH))Y8btR&%}59|96H_qU@STwoN8geDFnhr(`>lrWOkmI~H@bqr~L+BhzZu$3ZfMEH)yNvKmZN5hv1!23QftN4Bma9* z=z6qQFaEWDog1%Yz(j0@`B{#hs+SGnY6Nb2OHpTeRK#?lnkaGKHI%*a#JQ7|Zm8L@ z%R)MvUaR%ij!$h5g>&fs-+N&Hf9MV9o?0?*^&QTI%h{d_$2S-EX{?Gjk8$Tr0%^2w zo(BBuOm44@?T0!xY_WuUa+kX**$7&(z6gP@QH`awd&gu(Et|DM%19w)#naO>Gd%r) zH@NSkJKzZGksbX*Bcp}h18^oj`H2t5$46VkIrp&tzsGj}zcs>s?hocjQG=J;`KZL& z>{a%HKMtF|>7@cBxFP3%=gHjw?ELR9BI%1(vK@qPBnq7Gtn7tzf1It{+gvJ3Ffh!S z1F_ea_7ktQIKRurml#1V)G4luj!szM?0*FHBk511htcnX$E!P2xf71Rc-%>wu}$vi zO84}1XX81z-v~ST`20d~`o!GCsp8qiP7(xxi^GMX-oe5`N8j+_k&(sebSfLu{JGfS z;RA)?*zygPePF5fILlu)RH`Q#Pi3;*ju3l%X1cUks)5+) z${j$FqGP=5X<^K=CnKQ6`Q4Q~NdKghJfng13nXe7U%o8wl;y=qcFm=*eWWQHPU2gj zFF`POGWMvG{~;89Ns`d}(U4d1r|I@r_S>G|z6dA3%uY_6DK0Ed&(C$Gg`#+>(hESW z4{+xia-d26K$YS|O#yn5li7r#K0fqJrYZ?YKsLyiNCPUiaNu;;uiz9ESF$$2dzL$HHL<|yV6 znt?H#`^|YRkl|u*UW>@CG3P<@eg(cchzsGoI)drKDIjx@ImASBa};xk7(5q`^D1RB z=EKF{ycUrm*ij^5JT4{Ytt%%E4(GK1$;IHj7LkP|FcqGI!+A~7^uYL-O76xW@*CuT zaF9eWe%8aoQMeeKmn7DIRe~Hu;-YX~J|_`)KB{G2TqMpb0!PCfMB<`wUJH<149;s2 z8G;=|GDk6ohzrBTYUS!F1sikU7X4VxqY@iaA6K zo{PtMl``RcYV$$Q)!2F%Wx@|6MaS&Bz>$3*o#vv|z}`oou+ojLVnv>QK<AB@ADhFV!_&STh9z7J+p*FynS}4vI z=Sncher9rNX=#>z){S7Z6!IdYrD60o5sNK{D}8{~N#!{YKD$UPMmZqmBrpb~0!qG7XR^O&EYCpZ&^n1qYAwHosg-jvNl0SAfo58fG7f#NncFUI9oP z#Kqve7LoPwtsm_uktJl^IGJ?#o)Xaks;VYq}uX-uwMDc_&LBt7s+jWD;jWc zIIl%)E(Yhdi0rIT930MDgB&>KV1A5cjNg1>?sp*nlt>(TI4}KXA|4lm^IAlPUvmtduB${8RdH z6yv-K?TpmsVsKuI$Pnxxk~xYw#Dpmc;No#!3uL$$oYx{U1Ura?tnSwIZEA;qj!u;r1w__ zg?(X}?}ftsu8Spx5WMA%xUN$S3uXr_7R<_vC+8PR6I1guOS5wmbCa{hMcu*&j;~Cl z!|S#-bL#z-dxf-jRqp+jw|NA@gdN`dEB#hL%-5rJbR`q%o^&>qNoUn11F-H5%l{Rq z4~70R^ipV0`nh{Y05%fO(l2cuI*s3vZt-Bs^tw8$qP9VnWns%B3 zW?x4SRmPzjdA%SP=ceY5fePHGtblKeBBZVs?-(g04irjwhGo2WW_t2O5d?LK+!Xdq zWeh+WmNLm8#xpQRGe2k02)yC}{qUML(FB8FRi>)iHf;7nImln ziI^r~Z^G6i9)WPOv2uH57?hiF|1#z#wGOCm1Z}l2J$Gtiwm3V#aJH>Yr89Ww{sT^j ze*b&ez53P1m!_vq(QC~3<$vx$*TM%hwiqET+rmJhZ&a2icOP9OQ9p}0gWwKNb@{L& z8#LbIYvkt5HMndJ3%aEs^4P(ONKI(9+&OycV(?;JOA6fQ?+m&DeNTzBGCNDoQ;AQZ zgd0$@g3cL#cA5@HeIBm=v<>Q(U!&@TzuncX5xP?gXKAn8*lJ;1D?4n-tecocyvpw; zCW$2*G(ZoL)%Vsqt(mAeR=Ddgz(T2Z7Kq#bVd>{l_{GrY;1#&mq`=B8m4~4{%im?J z>yxZ!gTb8|P}|6|wV0a>k}#^N<8~oec_@NjdV*`Wwh7eJO(QX4wkrCtXJtxsy%hjI(OHr|^hQ*A$4 zKB$Ts?I*MF68n#KqtLA|>c6{|@q?khxBD~H=UKrhw!t(OXbRv42Q9l!U{)X99A?#G zDAj9&xxkHwo_nzJ2psOx)9Pl`1xsm-5VJ(k9l$Pt=|^b1Qd|$k&;nviPa?4&ZidG# zB>>BR2z?8MO7Pgc?p(C;jtDB>=#_`}!62}!W*8(mGHh|4jh^ScfOb5uAs?NYKdPC< zo&12KNn@GW?1_6!l3f!zjo;pWU$%G1Peig9M!XT;@p*$38)Ny%EK*fJyeF$ zdR=D{v|3#d`Il~j^S|H`IGzIMc2rub@N^`ul)Q}E; z@^l5oo??8HT$5#8|C3HdiSiUKqjH$m(8uhx8IV_KD#E}W6eBMwzuoazT@`Za5^ zY`r9kTfhYTtsS;X>wbUbq<*=V7f`v%3Efg+6O6pl3N~N~!TDU}xU;mgvtXSUr=KeB z>ji3J8t31WsT3pVgZ!z7xY23B0Fd#;Hyc!8XZ}Z+Zpi=?e1} zkX%>z(i8IpcCHR6F#q=mmH)d@_+ofDd`CEh?sg#lTojOiIh_Q^Z0#{yz7J~)@qy>K6p!r7i@}hy#)^e)y|f!_l(Emsh+NQsynkM(HYNV;_*x_ z)0xS1!iP*Qm)oAqrc*sBh(NzMkH06=nNR_eWEhGr8!Zn&A{EzV$0sKUB)aziS_Y7< zg!!I5utc?;b5OCeVzFo~Gg6AnmdPYy2xW{88#QB?{&!dAZY5xQW{x=x8c4uIPh~cY zxSpE9cF;BD9m?rFvCdp4cwt%XLWjJ+GUL#6F^PZn7#K`PPqnRGPXUH$Lz|W zt^&qQ@VrcmB$pQC=rk5(y_B(~B+!3U?m1J}4s+*|!_wjTqp%d6EWRnMJxSH=*`;{n$s`F*?0i=Hh<$uOGDVYiJu5gz zc~4hQS0bBEXL{1(Xf>FS=k|^NQP+Y!!|VW*`Q#d0!BMg*=MnqQco!i@hR2&v zhT7#V8CXFe27ZzuUpXB{&ls7ST3w!%*+yQzkB|5N&GRh>d9tVpoQ_e98Q@ck7%i~; zN6^bC{H4$zNPi5T7H}|?bC#dV(FqArGE6hnCQ?4nh^C}rKe+)B7R27-n6_UHAEBSN zGY$Ypmz+u;t{zDTDNS!iHnlQDU88#rj5^^J`}N3Ja%&t}u`m(0ov z5*SV1&!J7d+Q;QHl_x<-s)G>?BAdQfrj6%}76y+*p`pYaCCQN*^fwTW{mkco2jH+@ zj21vu%(pt`1~Rv;TwQqr80Kanqx-@zc`~wQ$XXrB@>2AV2%V|Sj0ElovZHb)jK*q{ zBR@{%KacPKdRDp-xFCH? zMByj-$S_ufFJ?CzF)J%kBRN=kGVX7%^2-lbw}NP}OP=%{W1T(a(=#eE9<@*k3S;YE>Um81 zVC9$k6|$gy+Kf?tLM+lRqzC{jj13xb09;s5@6h?%s$1YDut9f3b67l<4J*AaXF3h7 zl*$m3{S2bZ1iOZ6m$og>*WfZ(CZJi$*79n3BnL=5h)A z#vabW@G10d)P~YfX$#@J7fmxd4stdf)o$+{#jQ>T@*HQR*=)KaXz_Y2`@@TaUguKh06fn)B z(*iz#;1o%XE()*GaNAk0onSn4w0c#8%cU9)q5jm7#(BATpcduYw%+C9aa0XQjr!u# zi26Fqudhboup8KLFtn82>fWW z18#m@UA3N8spEja3u>kEBuc3uL^L!Bprc4o>(|y*>sq}j`T14r@2I{OT2uuG)DpCv zM6wU-Dh%zbN2}LB7V5$Ay00P#?jq#JXR5CO`072!?vmF;z*OPDqgU6(qgq}1M|EAH zO(;9!Q7r#gqB55Mp-@wP7Av zi*dw*CMR2b98i{l#@*<>3Fs$-{9jj>{A+l-$X-8%Zfm2wluYUWZ$)>Z@LNMa7kVgk zo%G+~hjaJ*GgUc)epo$nlIIP>1=Cu6D!o7DB{Lq-GQZfvo)?J$=`43g! zVuz6?54ABmQ++dlvYgm7g3>odbcH)I{QIB&Q6qeD)0No3d0YApyjvq4nd=u z3}0-cQ{>~zZ?E12Qr~MOvMzFV0D>tU8>yER(ZmZ``HFEX{YRNz!|+IAgB%&TbKRNT z36d&T>Y3757Dv%k{@|yZm*%G7WZoj4aLRwocEyaodUzOkP0e`!@aS0YfXyN#3l(f$ zeWG4(*Ss3K4{W_78a6MQtUq(S#!@7_QN~Cv<8Mz)Q>(z^y>uYK32-LrKx{2K#}@FN zE~(gTQ6EUJ7l6NuX)dej?R#d`X9%*!5#N1%G;;f3R&H9z}&tlAE% zGS!Po_@-Vnx>Yr;qdn~$62Tsbs|o<3%>dDEX<4EjwllIsA+HP39>W4}hnf*9SG8gX z*o_e~W@`LxL{eca2hjri&zb?=Y1r(ZnVnMIP!^qU*t7O_4Y5!RG=BMG|1l(zr$d=> zAXAO!hh`$N`P%=K)tX5|JBjtTFWzeMZ$V`@;{aepHQkKGRdN2vKVAQu!u$VL!gq(h z68dTBd4y-ltli2;btkNi-=+2rPAhj%&Ef0jbVFTq<1t`LoWgj@c4B&pq;maMpLR_b zcf_RWqcu|a3)`pMz6?%@im!BEULM6E#K9%;!-tob?_XM6URHE1MG|k#F>Xp{lA`UO zCKoC}ji@nUUn%^!_?eMc-~BS)IIy;cPybLhF>l|CH~PTpE7&ZZ-kHXmiq*ZEyhmOf z>>XXXz8ZrC?4q?w{}Z?Q)hR^LJe*+?RGVwj)R!Jajj?8C4J-g@4;gN z(RZq2*D}}JR1CI`= zom~AV%mw-JyQZ5B%@ZyAtG7Yc>fsr+`-md^vHXXm zzXSP)N8mOu18^aYK z)LO#8$>SHPW6g|wez-u6PR-*b&qogT58)l{3m>58qrG~pNTUxIKK_Yss+S}wFv!am zkcT7}iCx8}^#MIfU;My}FMsS)JQ~K|j?wZ|zTv|I1N(dX?$u+(2nDBIk?b81${8S~ zFt+6NR1T*VF5n7X6>wa#-i7D+f@4`h33NP!xA|Ie|HX?ADbLE@)cX47qQ>jCc4822o=3Ysbx#6KnU@9e6JpBfDlr^_9n<+C73>TVYr;>#25GuVu zxtp6m8%enbik%#Z>r9#zVqIp69pt~n6eFd8Qv$4$at9<;44qZ%hE~(;tZRik$xAK2 zsHqyX(}H#yV-{ORp^a38wl1w_TMbZEvAhh#8Mlhn#;c$++O!teA5tDsX)jVGTsOu^ zvpc9t-FR86R;9{*WZVo7c;m{gw^>_@muU`csE*?-jE=?lo;*AGN|Q%tiU$fd_X!zqzT#$MW!<;YLxrJfZn74ktxtSvOSLP4{y{x7 zxPjTh-8s(h?{Zz@yeu4@(G6VJXjkC4=X5hAidIoy%~hrLI;>t}#LSE{s65u>@t{&#=2TSbe9oNy#g)WN>D#_1;)&a2n7vbZ*I-ZpD09edq5; zo)>6j{adwXvSX+}bv+ z*>^(we?{D73;F}iTL+-DG@LdvE-yRFHN%_|NbN*lj^hcg3Xj#jXr#e(*pDERd7kJZ zqqm`>VzIP9FJLXcqsMkE(3!GyDdw&!QcyqUgD(V;bd|VC2e~)*0Jn8}g-N5j4?=6e zP*$Y-e0kQ{acks)-2t_?`x|#G2Qb4fYNV(SZTcY>mN6flN4a^z3v=wyq06W;2wbDFnsxe-+B0&~JtA4P6iSfB%~FJ}HHM zfPND_2f-HZp6Wh0dh}YwGU_jrlx4UcZ)SS2G%+>5G*<%k!dn0Ow>%e<+j7-A!sx6D zC$F?+;2iO`Hay_W+BQGReB=xHTF6!NTw48E0cx~1xuYwYNcW_(sZ2T>LueWgvUKFC zdtIjOiODlG?L*ZZ6h6n0o}N2ad=hwa5sHe?#2Ktf;7_?$ft^V{GdWV4_|Ej)qC9f zu6BnJyZlL(ADdrVn1dLL(@zx@+55f8wQWjm7UxcsW;*hTSjT)d4Ro1Op&lz9FD^_R zhr&XUCr%a5E=Cn6cTB{<+X?^g?;kyMcx*J<4}PQTFa#($B5C?bU@jT&w& zx!$JDc-6QSym6Yb8;>=rqmN{~5yl^JYk#I#D#AIxzx5G(O1WV`l8r`^;YKX~S4wFV zek$A@`lrydp{t}Hla?SLaF!IfvswT~m!fP}K6gsH992W%%>Sbu{n%|k+Of7a-n+I& ze)ac_-BLXeM(kjEqm?C0KT?>l_VLnWU@BfR{F0{A)%}oTk;$)Zj-W$Qsh(s!mC1Ie zdwROF@tzou6ZO{=;Q4B=<3c8I26d~9{nfi6M|NnwkoHPB3IR?^|N+%L& z0i@+n_09-d(NJLnOjvehz2?`oPV<@_z?KI8E6(NH=^J}hJF9T8odL%3zYX=E&|ie! z2Q7eWrN5MZ0;K=fQ3(RA-QMcqFnXtA+@jGAe6_`;OP~5U=f2nVloyv~!K$9= zsrK_J<;gQAAXs0sG)tBzOS!*#NLQ^m7D*nDeeTkwj~Us+3dlhUMBR`8W^8P%56sv$ z^?0pq;54NhmD&9`SWIxFl^xZ4;3}07@`D~=&rZ&_fbs{gUV8Pj|MjyU#}@-fp@%92Sy)kgr-H7p_@4M3^-#0pd@h2ebS z<460d4+EU5yuwkiIaGbfs$f0YTrR~UBrIBrw8~;X`1sL-)dvC8bs~g%GTpiEBoB+l z0-@pPq#)H(eSninK0+eK^sSXZ-48gZwV+R0leS5!)%RD&T>^>9PZbyD2|FZW<3#rR zs$&2|SUtj8=27iQ$1{{!_E$%(P!U2Ak~3Q!38N<%#pRjO!Zav9uwnATJVz5+y>dIa zdxj4W%8M_iqWi1Ey8NxuGT@LuABB=)fAv0>Km_#MUp>MD0qb^0EhB6;qgej0MiVIf z>G0|B?Qs9si=l(kf50ffGtwRCyXa%^sUCMv^)bNlT1Je$JSpa*oR&}}i7RM4p6c$2 zAqlrD4pyfDkSaN=ylj*Jr4Djm4pbFIq0A*q8^w!P_ zDKH5b&fA^BVLYJMgv4ro{3wI@JzTp^ySd|L;cd4^c&J?X*>EVdI=qJCjJMj zPw>Px2s&q?)KYQsnaL%45+GGXb`Dn0c!vbMjdcctv{VPAM0XY%77S9U4oLBICXrPk zEqaHP#E$8){nZ74q#Aa26lXU1VD)kD=)`;CiCjieh6k&s>wv@)dw+G_reFfCbXPpB z$g;v*K#PObIU95YKzMu69nYq7ni`q)4k?~VrIH$?nK~d*5;4_wsvbz3U8VAW7|TB% z0sKzrXG0H#UMpRc-YLb=|3Du^hn>m466?@~2q30vO3IY!q>XXq)Ic(qNM=90#K+9Q0Z>WTB`6p2cQhCqeP;k z(@CSII~7mmdSZPjCgXP2v)&=Wm`P8LwT=!}pYaX}2Fx9JUbfEf9fOIvp zh!#3iWTMhwR~Qo<+FyMNz_?JoA`O+Rp2bs8n#vOQL0E(+z`#NVLu(_2gViU^6cKb_ z)Wp1Y%k{)zR7;^PmH!M1|7!TL@Xet=4_ye|DSc1+nDln(dh|!=hs1M$2QOS}&fjSp zI-ZDkcdK=K;kBM2b;B5RF0Dbj#xo>5Mw`{7>B4I~LrQ|_NM{&z4_>(1Go%CzI;P`{ za}Ql;14stN>X70I7^7Eo#Q=0$4qdpa4p0dW)X<>|+k65ASVhgCh~-%1yW|{4bC#n! zmq{g)(C$;z{gw5Af<8ooG1Z|9S6G134HSs6N_Qtx$rQBw6s)#-2bIhvp$DOv#x3=N zVg;n~pT+k7RQQ(AmqPCf-7WpI^o!C2$p0Ur6_ouy?7azq9L0GkT-`Hh0drpla}5iK zUF`}@&piSJl6HjzNWe;9Yz$&S3ld0L(5?X49MMW3re}9;FxZam_>=_ zD9+`VmpHcLBX$zU@pJP0oa5zp62IvGs`{#`uI}mX>7MDCt=6h%x~J-^ufDs!s;(CM z|LYqU0ScVQsr{Lcqj!em#ada*=dI3+H7*25oK3EkJRmtxAU~fk73+?VzralsPcS%F z=76f_A>ymrHgRL){K%jxwL-B^49Zz+9FswY|P^7J%Xf-Ag=KxzeiTdWjONGb1CVRr55c z>l&~-W(tnETN*>K#N%?)!shUUQ!DcI zVg(ZD;ED?6LcLxn=kwJSr4oMBiX40a4N4Sofvdqc!$+wE&t<`rSVgM>`3wTdZps&u z5DB}ggKrx^_^QP+#Vo#k_-TOrykUG|Y%I5~aRo?^6~4A0DNjqI8}-7v27d8<03dm9 zz7#HRT%JMJL~1UV+yC&xQ;_Q$9vpo2#_@^q!NKK&gEvnM4%Qo&IkB=wIh>`(W%>Wb z#-$mw$CjVm?&-&%jnz&gLuM;C4-QUD46ZOB6dHpW^pH<2aivRIR?0oR57t=SPl9!V ztJcV6&@R3u2R%_k*EcTa_5bZJ1dad8)k3XiWs$J{t7s=uJ_4r%kGX3bE67qUW4x2g z70ac31y<%=U8-xP6%aHt2Ub=%MvaeBX^m!-z@HUdyh8Mu6aiJh#~KZvBUQ9uTGh>F zoyH8XH5(th6}xR4g#8o7hTv`BE5ywEC!Fmj&B0sGCy3fUc=*=Fa27SLutlW^4KTCC z^vp4=M6yUddGE~7>iqD`BgfX?HZd{2W!v_#wcC#6uCfX|xPSL9n7y4mFq9`*_T27C z8WQ~-)|$XnvQ;q`CuAR}WI<&@&32_j+wprzNv{~%XFY z4#A&1Bn5hi0(0vcBj8aSo#~=SS-oSDn0v6;ZjWGEe#5DhQ|45#{%6nxLSI2T{%HRw zH?GW}M{E~?>5>OSv!bfO&^Uj21$IRsAD34u=3F>fAY7`k60bV9oR(3oS}2sORdDuJ z?TUsStcfMA_Uu)S(JY#`)*^N_uxM8d+6!yiZ5@bd1wcYMjwP~5yb%^lapbu4C^}pXxuY>1*zNI{^toB{`YpCAAryFHhVVSYj6-R=BLQHKGf=qapW>Or1 z+CM{t0#D0K?aN(d$Ei6dQ00q-D@}kZ=q6a7n8PtFkNmN<+qPdd20c|s5xQ9*VeSOH zwEwDg4g9!^<9;xZmDaj=yblZ*E|@Z^`NrM1H{b!5gBn9d8;G;G-X92gw#XuuiCw)> zphwIYxsxsASh$ugbp{2)4K0ISW8;KX)-u0fzsDJ?eejG1?D#V`%#}>F_;Bg8t#Y(-lMe3K7r_iGeJrlf`%QkAjA1moklrX6IC>rKt>+E~q^8EbU7ry^nj(sro z7#2QTQ3S8qj*z=FI}luJ8M!6y58i8zomU)y^h-|DhDUejCQk@hZ0p=LjVjRLX$u?~ zPzN-lf$(jI4y}>}+Nc->KfVMc%<6#UFaaxlKtNlBX;))Yw*@1N;LiSZ;^VBdV_j`@^{L6lslD+;YR-)^~QCyE4**#v~vsd!C-nf>oYdj2- zBaimc-z_y;z2lQ#eE<55M}&v(%Q0(p|gsBBd*f#mMRi+{ne;cZ#0&!b1j zZ~D%<27c0-iZUD^=A$_*KpO)S7{I&fJC`)zDeFy)k(u2+dG8cRfxQxLP2(zP$Xd*7 zSY)G+Q$_&6`SHvKJW{=qDFW~hUC@B1rJucqxo=vy013%L*P=!LL|XUog220u_Z`@GQ5$^(hXOz*%gD2nhzJB9NDe{CLc$b zW5_bqkTehh2w5ELF=j1`JTncAA3Dvg0UWMi@Q8YWhqw&tBe|JJcJG><+Wsik93%e! zGE#n_+>O56QRR=NvBnttWP@jSQYU zjul3?32@&LDS|24_yN!sDideP9WA&3*o5~DVPJlr_@4kh_A%3La)KLj-z3qY7`KAR z7y7h#%yMy936r2v*ZJa#Awtp9$4|5)-6M%vnVGG_o78_=_(M?s2QLJSD||FBVTGc5=7U8F^*JRV*|FgddK;_JXoe( zl)v+pc6bTcVT6|bGSPqa*AV>4LsB5^6qwuG*aXS{i~Ge2`wSF94OfIAybo|Y|A+No zMXM1!>kp?e$H9{tH^SWAg{@e@^&@w!G0T1Qs69S##k=+|eudxpuIAgn`L#c98imJl z&lVatz(U|%t?==8e8fdUOl2TxCR@W#mvMPMcbo1z9G$e$*s-t%UlC`z%+VW5U(wW6 zw23q!_#Q-AM3J~A^8!r*THF8H;{(s>zqQu<-@l;D!|Ly$e+i@iJzMtBmImxUeB=^N zkaJJu@G4Pq01siSPki8aHJTqQH7EkBhwuZc@B&BtYDae=llyi_0?uCVim&o@s2#8( zscoI0A`8~~fqVu8YhsSKD21KlYXt*FET92YjXhx3GlNieb3im8Xt7YO)a<^rPt1c? zG+;C6xveZmeN3#-`4}@selCZd;00IVR~Y-JwcEC>UB8j`Qs6aV^XOQ;ChG{PF`m%> zzi5~Tdj5~dtj!K05h;>bLqh2@5p}G8v{)Gr^y6p1yt-4Y)!|pz(lLGoB=2*@?Xpy) zk;Z!O|7&Ec;MTFO5(D=-md>_s7_bFrY`7sD>0=Y@b+)EbLYh{uk;fcNFX3^!y>1nO zuGj)&HOL$Jze%J__N+foH{uItHg3+Mw~w&C2}_`D9Y82s#{->G24eXWG?nSK4#cgr zW&~kdUr-71fA50-?~TDIw(r?GCEvEz#U_XhL~;>tfRZ;|SPI!>kBx-5MGhiEX_q_p zYAH&5oE8J3)Huf-!h8)YH*V8=Czkvd01af4^{8EWM8JcwBlNOZH-sXz6iE z9>GDvdI%uXXSF zX&yJhh<3Y^=Ai%o4ex{-A#t9tWpdaYo>kH+0rjL+a)v*QKD4wPK?IJ0NG?1yEZy1# z`v1XT^I@#trzgfu|7J~&3n}AojQxKN!j6{Mu}yS4Wf2oLp$6xsQ|mH&aH6a?0-_}$ z&!GP=GZGQqI4)h8CiAg@GQbw8iLao>TB%7{i4#seW?iXNwncE~vnSnjVlEm_o?EnO zsrsyjTh+)XFVG%yRy`(2Y=YIQg-9c=RbuHK z?1m1g-0Oc-*#E1;JAb8n(T>EfGZgsk*EViB4jp`^+Lx=N+ykAK?vIaL5_LHc`@aYN ze;9^iwgF}_lzB98B_xj)D7u#!H<@t@y+|O)h$}fg1pWU=@KkZyEn06RmTY57;?&3{ zo(Xwdj@^PJQ5lHjf<)g-Acz({B(PNSe;;Mo9$k=P66+;7SeE%eMhGq2!-^DBMCJt| zIAga-!{a=Qt}Ru+eRisX(3iOvVoH(g`=e9#K>n$PbNo0AdfKi{}BBDHHUNogDS@U)RRk2 z^jcyq7fabd?cArd0c|6dQZ)`Q271L9ahExn{kkYa6HF&=)V)9ZTlY|y!oX?h8<|&E1&v9VFH$wWQFz*5S|H(cyYk`!F z=QwMd_+LE*iLEA0nhaffV;Y)-E;#208(K2LPA*y+R#xm80KDS@Z4_lGTLxEb6OlEG z$BhNc|0?x-={)`F_iSDs#M5~~qp#QhqQeOPb?f-}J&lPh`rf#lB#@H?fdaQ~dxAb0 zIza6Iaby3_Pax$J-O_&9ZWsz2zNxV_iyGWp7jVdJ$1z|;9KYqY2T6~`UX;f5F6K6e z>@O|S48q(GKR92}?0to=Hh0I?@CMPPf|jok{YRH0{O5Tbd39r37QM09 zD-PPGFaFYUAVY_FUg`pH*sbkr?!E1eRy)?5v6VhQ)J#-6ctI09%I~z_MrJ%9M+|~v z){wUfbd(gvdmwBK>@RV#-v(%WX=x~EJ$H70532v$5Q4wBjw3^j+p=i!Hfb&#o3Rwl zMaOhR>ObS>!|Hzqy&I_?QvMD;(ss(;8fP$2c~9*hT;3{ zu02yj`BD5@6d{1z%p<#Z%}#B9bZXzsuIatFj&+nuT1_)91f_Dj_Rh>g7L@`lZX8P3 zWrWxbkBAX0h`QogxR9?yH}U&##wI2<9LqglYP>p&-nS5(sIlG^OR% zE%TH5#Yhcd|F0_l52;^=lRTCd1sXRtUYA90KA&^w`4x8lj3ln$?GSmvy|T744}UeQ zFwTj!D2lUj@YF`BxC*~q}l`13662h*;EVUYAJ zep$CwgGB-t@%|-1WxL37ZTP5pd|~VN=biU|k4=nC`NN|75Us~_p2NUd~sb$U~Zm2J4=HLSFcw~eRUC5(uicv|gExu>vgVGG75HjItsu)@RGz?}J>nclze zzNziIb~tn2o@3iGRLkv~-oJMTOneuHN33~q0Ss;sVwDumvvXzraf1kHBm^E-KxKrP zxix%Sy-Nk7XJF9mFLi&G^e-u-Krp;@1cJ!B<0_o-e+He6GIy&7;KMi$-_y7k7Mb%8 zFgw6_$B!N z+y0({Beitim>{uI!8XzMm!5FmjM3+$#J*$-`3o9jJ?i}wou$bvaXi2dpNsfy-Wgw{ zsM`dIl@uu!iVg{cq^nH<{3TZDvR#S&#jvP+{15*Bcb%yM+XTZnl4K2Geq#A*`!4xX zbBa6P>>{!vPPSsQg(Z#;oh5Y*3P{n5UA?gX2jWV~#!gvDRZM}D`jLX|-3-gp7OIw| zFBR&gdZk*ZSC>~xwlHQ2>#^JB?`Q_ zyK!F@edsP%mMEplW68VbtfWb+o=a4H!b*t!e+T~me$BK2#1%93N0I_$p~q zA`Z{`RM@f0v&Bk|1JWC@hBYI7Dz7oiYNy5l0b_V!h#s(RJMsTKQs%o9{K{r+3cR?Z zu>-~do8>rw(sJpO67xwA`yVCG|DflQ@@+V!;g}n5+zpZ#_rf zvhKoz7WD0$El$*30%ip)J$~W|tC~^FfbQI*>ez2KV&DrQ1+5jdoVBMDz0X^z42yt` zEv#L)OQpkujVW0EyGat#5SVjl4Iw?kB#Dhi4q32u6;hkx25$*%d@K!XZKN5@d3ct} z0^F3_XtB76@1{_QK>z>P<~A{nlyCKxiL@|9nhZ98kt#}iF_Ri%Wfb3ySw(4VOq1Ad zyFM&ttfo=UP!Mmc4Ep~kmJ+p#SwL^>ZB=Y)h3jJ40%8ovq*e5X2#L#)J4loqd|#@F#g7TG6?BQ zq4d$32w1D$QNQz}0n#IjBsfSl$zX~EUDKB`fCp990ti){S^;Ss020*_-=Fvuq*!(a z{jht6a{*7fb6KLSrq#i%klUpaS^tA}BK()+@iJ;WkVRiRuAOWY!#!V`lAu_6Ls|qK z5vT9QY*eM96AIuHMP<{_PiFSODgpvmO|7V7J zxwvhbEPhO9~M}Qe3e7ClJ-4D=uV0qQ2V1rK+bb%9NVdO7rOKTc}iA zlIb^3*v9^!r=ZO9=!fW(gAaTpMc?&=WMvR-2F2&qeA<`3h-Gv~nATYqGsA17`)2LU!GvaR2AQi9Veh4MV+wJbD6^qD+%F#sud)1(t$kxr#^zz zAHzu=k^)In;BEIcc4yJA-`K%q48*wKnmeoU5WF{LWe1zJJq%^}Y`;*m?4ht!D634n zXg)V~u6z9-n;Qe#{H2XTAGt!BC_qhzpxx}F>6*{(l=H8$Of`C}lpmuE(S=bbqQf`*~8}czCA!^c!BeW+O%y6W>jRWLd0BE4nz`!`$=GWXeh# zJqS`V!f4zRteCapyQyF}(Fa1SxOt9JaBXUfnEc|qeiGXSs{p&Q;f>i0HBGq)$oSt1+i5EuT%devxuUe#C4%UW zqcWbpu&YSg89R(^IMv=S-Qf_pk3pp$WC~CF_QIIJDns+^Q(9%EO+94Iy%``is5fT!O6(=ci+y*y$?*y3=P98*JpR_nHtKEYNHxljktc% zM&UR7i+Q-~LQT6w2>?ON}Cpc~yZM$rH7AoWZHa{+yI%#|AZ!7A)Y z*eZn9MA}BURhu&+T!9vf9vT<047^py9op5H&7vc(PMmI=r-p0`28gui8#ZDoBVF%d z>|(Yt|9=Bg-idB#Py6S#G#-PD%q5A74R~x@Y#a{2Ee{uNdU?AJ79?_{OqyK0Iebs! z(JX3=ONs)!LYOu;UxP+?UXAp=aG4_Sk}*U7$B_C}G!|9==O1qzfTb+^edN@NhD4tw ztyC;%mAZN4AVvgL9ugH5-V@g!$?ce&of=wMEEfw^%>-)Q6ueTkT&dKn)pEH8%g(A5 zyCDeQDy3r4zBayeqDhV(7U~iEQ>*7oB}@hAz;K(eIAV}XF-1DVL|DV}BM9~$4;<{7 z%3ytzgfW+GGpu6NXQ`ysG~+rq^T_U9vs2q2o!U3EYkDspRa%D_?y&cWu?xW-*7;H; zU#ip#MXf58z_c2n4MYTOjZmdl^yF0%3T_&|BoQ@DQK?X`l(mvptq>cPgOzyXh>k&$ zNXP10l0?*ty5I(C_0sT2zCz~z(8~z_rTBREw#MtTXknEMG2)DBk`%pe>qtNMEwCF1 zrvDjKK+3-cn{s5n|rlJ~7i+IVH-i7a}d7?D6p zN74{2|F6T#8gGEi|LG}3F^&;ik}}Y3+vcMQY#7*DSh2!Oa{H$V;uj^EVt`m*^AY3r z4SM`ci#vUi3TI{H|6WF!i&H%UnBU!a8d8jRg?Cs2DuZxA7LAD#$gNVo0+s$sMuX3EaW{tgY^k2TYc&^!a|_* z4+rmRJOvx#cPH45lDGEq|HVSNny=N&?20q~$NrxVn>l88P>h|H`%EXa5m8QqWNrE$)&o z+EFy?8>Mj8E%Q?vSTj&>J0_C)Z=@wC0c%APQ~$GQ4a%%jFG4?uFQJZu6+N3pbB_en z`C_$Dt`v(}v1oGJ4zP_-SbUf25T!>THYCIrM(NeO^>!ekuZ4ck4eA-lVv1k0LbXVL zC6lDo4Hg>`)#EiteUu%V%jqgm$!`S`MGxz1y-+9utMkQ5tz3dN6}5cra#PE#4-)e@ zrxj+^=rygjg`W|?8n}((4{f76 z8K$gq()%Ly_r_qQJ>U;puaK`4$pRuk#a3@Ia$2oas#Hs*e6?83*UM#im2TCpf_vhF zpH`^yv=KJqPXIzLpH_-p@6GTU4IV++G&a6%?fQ-UNQj`1Pd*mh{FOkNyGB0_4Aj#B zmCu_nKIu4Y6TDc$21J7mt zBlEABpJslX`J2plGvCPkY32_zznl4D=ChekWetk-s=uv%LH)G)3H8J32h?||Z&P1T=hbJ`Us7MM&Z>LW zo$9^n>(txTThtrWF?EevQw!>-x?IhvuTsxaPf?FoRpl2j7x^>gC&~|%zf!)X{F(B{ z%2DOZ%IB0%DIZsURe7KCPUS7in-pC+tURSWuIy8GEB9xv%dF0nGFN7XGJ}~5GUsGY z%bb|Ws{f__T>WSDAJreJKghgCxkq`evQ62dY*f}MS1T1IudGlmQ!Y}@RnAaOGHl<# zTbpMCCEn6J6V5L+&w%rb%~Rq0LK8|1Jl{MK&Tnd-0OvP0fpi0l%?z9unkt;nSMN+f2uEo^Z(YfaQ;UfsJHAV4WQn#A2)z*%l^LcdN}`G z;{cq0*mw-if7{p(=f7#p!1=Em@YafDKWID*=kGVB;r!jkUO0cVu^Y~R-gpo&c~%Dq z0|#}0Fz~bv5C#tDkHYzJeHPA->igh4qXUG2hjpksFs<)_^Bx@_3_Pem1m}Bn3}?H( z6V7+*pezG-=~HmNP2U0MZTcj%^|i(WaQ=e^{JQL`4Ytv-2h2g_8Se5gk_&vfPX~CF9!V8 z#w~DucLOA3*{?LV!1+Z!Mo%ihue*;w{c16J}bd$DmHoZs94?k{_x z0o-5qeB(+uzo{_-=QlQ1zS4*_zK7SsFw0I?wV0-*p{yHDE5qStzPii?vFn0`W|7Rk_tT z80){H{0zaLJeB|j4xgl-04skkY%QLqjPbH37QMK1iiYDEj}vjHOL|S^8n^?-R@xzq zkrJ0>Oeu{+oY*oG&!j~$GGXpIh#O;B(_9()UqcGS3GxU|foI0_6JawT@%~ec&IC~y zrUK&>fNkNp44~@yay}0p0H%Dw7gXzI+C!O6n{AO?8Hn0HI8dvSx>X*$0PPmjMuIL#jo4}dWaJ~P8Z;tI24u29V|9sNQtTG z-jD$91{vZ?gLX?LcU07V8jfmdK`9V`wvXY(*GWY*cEHp&l9f_UA%D|No!GG_mMgzY<3laJHR;L`hXF)Amv} zIwBhu=Q(bgw>=GvxVQz(svS8o;tuo@3W`!EWl10e`u|_RlIV8Y&5rou?)2hiNi)zb znn|<(q?GbpuWW2R(!sfre2(M3#f%SS=IF@Ob}e`YBm-^m3U?cd3zh5Z4922hWp#T6v)V8zlf_;NOyip=vF>?t{KQ-Qi-bY%W7RF%* zlMMxoezzOb^3;Rt7}bG?9wX>b`F}-uKY~Abq>}>kx9X?DyU(tWDfwU~&qMZ?O6o7T z<%6+5?72KJ5GE`&LJF%!f3D_}p*P4-dP48WPMiyVgTvt+v*GpoGM5Vaf4tq@7y}R+ zruijC&~n45V6zo{KSb(Fg|rnXMvbvyx|I?1{{+fTcHip9*zFhxf_<+`sf&41hmaNX zIx5l+`47xMWk2=9Y8JPYYG4!Ww*nGFXFrU&S21`dUM1zay4lW6k2>Snu zwvbwiqVKR2nAz5%iFU*xNy>A*qB`t+_5K!J#NB-oPh|B~GS4PtoOBBqoH+A;CKlo# zK*~cu7<*uG7eve!Z~R3pUg^b)L7sFVz6Y0i*m3ekY&Nk`VCVnI`#;c42>-QveC90u zv@H6me0Idci-}E$F{5JsCWlAilX`KgO+c^7Xs+0#rQKt~>#!mAhc~Yxl>9m>4`Rg0 zxpL89ikKS=!{YTeVoTds0jhXuQH<%;csUZE5_4jMFJqKh9(s(RJ=Q>Y_ZfPX+i#Ssb;RM0_^u3sx{yW!|Bu6e1g`>&a71~_MSPaoBccHN%v)8_b@G;0 z`hR<#jA4Kmd*b9sd{V}sZd{bKQn8>_41;AauD3hu5h{@&kvDxj^f+lCj!M1!|4yVN zy8A~QjSw}>zt8XE_})usf=7Ig0LJJpJ8R9_CxWf1UWm6W;AHEA zEys3^qAK1^5W{c1|Kku+4s}d}WJ4?k4j<6Z%A&?&(xN<(1H-|ItQj;r7NrA<8RNTz z9lYbr9L8W#DE(K_5K?{gCJ$GK*Xw74)p$iG ztOk?y2I7UJBgFx+atFHWc5X?jDQ|*0*K#f5W)YTvbA%KkPOFpQ|1)SGQoo^m6h1m| z%vJRBvgq(5Q3cn__IXQ#Z4|t|h+Rrd4S4}CVQj#{)xg#jOZj54JiNwV<>!{`=K|$! zjY>IAI{0){=>B?09S_%w>TtgVwq7fhs?`!-$v{SYx3yRUrC!+$N`c!U325H6v_~l| zK}unTXT6}qF0WjzQ=$Vg4KQ0Q1!3+ACC2Cm&#Lh2Phus9Rw-9ug;~|WxLym>OL5uW z={skiT!_OBaTmkfbwN#Nwm@w5xh}?lI0sSKJ=^7r^ZzRPca+%%r=@hfc%y!P7JaC7 z9=|Be!2jtXW*~say%Ayy>TgGW!7A?T_Z1{h!@i;j*7uWm9E$ILGj^%L;`DA?UJtb{(vd?2Dpa2%`B_;|CcX8O3nnZD|E)n$qf)?SwxILGt zNNpZ9Ny9JQB4`GqDu!Ixbm>vIxMW-+=>LV@DPU9elhh!PAAyY6B83faI_D>)TZEYd zu@~q8?wMi-_>0|Jn7d*kKnp1f8oV+rp#K*+L@;_{)5KOx$x)Gx@QA77jH5s?f%hN@guki5s9O?kc#$VfYR_tzJm3~h<@M+lxnS5s=$Ys zCt>cgEt?IHkK|f`IVvl@N&2}2NeU}%7S)^5BEf(6c?>v+fE(a~Cu;cSy{?m!T)M^N zTA}m==$2Dx@V`X zZT5F5=5P^|x{)^8Li~RT{J#v#JUIj@kbE(c3egWTr`JG$iHOuYil>YX5?Vm~NGRTE z04mYK8QS_-aBLtLi)i?Zxns;I*nMMqW;Gt96DEYn_5Dn+g-2pUumOYp5VEL8dS|nd zNT0K<055|${&)Mv5S`>~2h{8r5=t!r-inFPFDwqKC2eVl(2R7*$a!~gO{s*pk-_;t z6@3gT7r-g)$8($YOS0(si(7@=kzJ2t_aH7>{?ax*mqj0G`96~vnsW@a<>5RHsm)TO zSxOZh?4yH=%beqZ8X)Kjd*XsGhTct86I;qO2UQ^BmtvLgzO?iTHz{T7)9BFLg2*;9 zuJDoFqlgLiK)1c>S=PWNATAi^;Kc^qw{d$&&R849jp8rZ(|bF2*nlef5y7B$DE1K> z0JXX5Q^vIV^JnRUS@gDak6|Jhh#t{Du@7o7C}5KD(9xt^ z7R3KoV9gHxggK1~FwK&~&TjQ$wQ7B`x{oKOjbGgNVHGe#Oz46;vx6>&tysg4Z*MY%gnjey_krK0(kQF6~Nhf8C#K$j%LE}*&zihK|* zaqzI8Hq#%zz;k)7qSYFF8qJe69R&GdSEE*8(g}q*YwQI06<1B0Jy-NRvK5e%OXU@N)^udjcoF z8F<%Q7sTyRTQOr7N4iYfrhll3w`Ff!re6ko|84f6CYMr)RnbFvCh-5mhW@`7ssE(> z7`-=z>OZ$$9|rOC+vgrLD7R)Lh9fug$nIUUQ`;Y%+BdUndhZZ;CF>|zUyM(`l3Y=? zqIu<8U#n@+U=*yjN+o~+8ku`w_t?b5hGV(8 zU(EYu`o7uXbW}0AcSu`~H@hZ>FFKmhY-#?*FKj)A56h&%XBjT;9m+4)hL7R{&R^L2 z{ds)x4Y-(lg?-Z+%`-OZo`N=bkilj1jBZU3;dmmj~&wJ0|$z+gDCfTY>b2#nY{*uK>C|)Q5DV zsq8}%r*CM>Qaav`B*bR>i2@xz5;B^wTtv-B2`sM#gKt>`Q9wioed4bS>%#VEt_q z6XRR9ZQr(O^Z3?nYd7Cwi>}~{I9?IPB1Ubu_}frPTp6I0C_F1r;Taf9cl<_&P0Exxz>FfqA~LL?pwbt zM41LXn~{pw%L6=7{GUOqkoqBI0zO(Da~JDnh)vhGh*e5OBRaMMb8~sZ3M@O$fwM@# zNXM#dBn;(G2=GQt4Z>X?O`Ar`}HU|33? z|I5I{zxo5^=jojP->TOF@ZB>9Kx_=Jv{Y%#47`E{pYh@kT;4d?OoO-#C89uOVj)0P z+k{B?#H21lf)uY)AqZLsAKal=VgA%_ok~cHNSi{u-pn`vNU~ zrdJHEV`(Ci!sv!Tc0x#VD^P|B#u8&I1t=IS|A7ToWlgiTvI1&RkN?u`cUCbh3UyHZ zu$@?rwGeG?C+%_nC98Glu{7{;Yz*F z6agF@6F#z6F#bv?5{!Y2*x*7I42LX4RLhn-Hy_D!`+3o1v#~3{KrQ9=mvYmr?P9n` z#W|QHPT)m?=7d-&(h>??4|~E4S=>_AkL-v+=4DhtjZ%qZ#X%8>|Lax|99+A^>~z<+ zAWKCc78~!t>=-7RTr#}I!vjeX5|dCKgr*1=u22q-PJy}oiEk*|)V*c~b!|JzwGcY9uzz=P171W84}1Oap2aWZ=F zX9IUshZo(RxUV;r^hgbags||g``nQa$Y)&V6jG}9sS4i{|fpp z!hijCJe$+6$)fr3FtfnKVH2Mnd#EMDtYKJVKEZ8k5o_q zRCfHy^t5@dM=xbncsLy-YsDRsrYzqsY4oXo= zRhe<5Wh+SsqsRZ)|Ep*RQZIy4LdT)9zBY@VosP>7n{lWoKZD5=B^mYrAd*;mXZ5jC z3Ylh3+qRfK>~KHalg5X(>(^z`5uc|$C?a~Y!`5J`uubt+;vFNU5}E^MMn#z8$@83$ z+U!m&`hO6f|3L>6Qh$H2hcDCDXVG)wh3LkbOhdBBv-G*$yB;FDPz_>z;K{YSv+G zf;W9{Zr}9&y*q|9@-76Uj#WtT>D`W?u<%y=E%P0PXZ?)bfrOod(oldty!+HHWV)3g z-)+Q$6gE2v&;P9RdkzE(Np8(G=AH|9qV-DHuaw!O6F*X6NE9|dbOqZS5eUw2&Ns4^ zLkXMuk}Y|~3hbr3<{DC&DrtOm;2YP&7&KLih_eZRwQlSeUt7qA!5iQ)Wx zv(x(yjE&`p|5skX`~SV*uc-3Z&QM^ksE$E)LTk?VL!bN<;(SPNW2>#^J6BIan zgMK~i0xI6GKUNK-9k>xdhy^LwT|4NPL$P24qe|JdqwaZs<>N5HHTvAgHjGc0@xP*s zAo!DqKLwt-Ro|FJ%`1|3eM?sHuow20Yt8a`ntKf5Q;Yt|R-__`rbK zg0Yap+s3kud0$0E!@Ff(wnABVZ?N87V1G$jhgjr%uTqA2+F9XCOXf$Lu*_Yri$MDS z2_yaok8-^s?_SXO`@yM7Y%*Wn|CBQPBQb^PS+X5snldhuZICzx-zK0$+hWah%eOVABzxh_JHz@o=TH$M z+en}*y9a?v2lD@P{!hIJ!Jj-N1!AYbp$qhzVC|=P|4moeVXURYi+1qg)~eNb!HoC^ zxXUf~5toBaZ|ns;q!stc-7X|#^Lak6W+H>@8w+^ww_r#FE!Tc;fuhhDeh;jZN1(_5 z#`8bx5Q4vG$C1_g<}6w~5G*O?aMKg9!C!30kt_5qU=p@Ulfbc! zF$45PhfD(9q`5$OG3f`cM47vI4=MJbWpzaD#qx7QG|jx;yuXMvimX zr?0@c#xquvR@$%w3?1AT?obKl{%*wjpFtl&>R&6r2OsG@=FZh8;Q5Yn)G>vdAjTax zSxB%YjJU2g>H-I^aIgn)K$}~8 zo;J}b;ZK|M^;>{8;`iA2Bp|Kyl*KCk)6Mn-<%XwCZlxAnP+a6$S#U%L>%Xd;gVZm; zNggHz4h`ztAZsmtQF+`#LrWG&RXa!0k!8~G!5*^aP;~8>z3cR?@JR4+9dQXg#HBDa z!~$=2Ewz&v5Gcab4tdau+6uteDbw5%kKB8CJ_mY7xhJj~Lv zqV<%h2Cp72X;rP50+g4Gg-)LP9V8`;|8F+*e;gtBi+miZ>bJvu-%KAWV+Yw`TAD6} zVSOdp-6bWo-ZDH(lmAzhe?gfG;3SWwK!Lf-^*bOVcC*l0Kk>w6@D6kh23*F*7Oyu( zT%1@OKDSMS7 z`cL#baM___oxVMb4xZqWL@ZlZ5|O|XRjV7)Lqw76;b!tFkMj9?t*qajL65j#XdoPT zpL8>mPuDBJBagV=U7~tT3iq;`c>*Xgenk}7XCyHX?c86FwQ?Uy==gPH0U81gy1Ml<-Pkf^s%&?;J` zTrVCT)b9aZch6xkwS`oJ2!K9>WrFw_3rGkub%nD1)R$t}qB`^GB_&w@GshNy0Bz_~JiZL5AGiDgjs!z%CmQPW_7?nTQTA zP^0`LbgLQY&+O6f%cB3Y-DS3G6(=$^qbxgW!A4bd6sv`DrC8L8MbjkOHHzh831ZmW z!AsnmLN5^@9A^~OzG&O(+K})UFZ~C~y&AhQ5-QU)h2aRr2N2}SDu1rII7C%9zPd`# z?ZK>iB3MLe19#MgJ-N|ST`)q3RvH$+HYUJHDUBj|j6oVf|L%|Fn#c!odQ4&FfjUrPftzjs9*qLNC0Kiul6E_etN*R!^{jnkr0 zs2pbKCqs3PYveMm(g^y0r)#9&LHpAQi8LkyIIeV=A?d;I!45#_i9pU=byn4?^H--dZHKX>5Gk+VvZ^Ft5@q84p3?zEdTkj9~h-Gq>zDw>Cd~ zq`sBJ=ZroNtzWx!d~kH|UK3{9vtUuUl`Q$l`hWFP2>#?DDbN!XnA@mN!E?W7^9u`{ z^%ymC#TQ;RC0?e0cVmF9Kzn=92K!u}xTC`LBkc443VICTzYZQpj??dlCx%Y-VIlwI zX|N?VtryP-w$cc8tDU_%?B_uuuh9vHqo7n6v}>AZ*OD-L!YEYdl}yn8V7J0hiIXv{ zN0`f_O^krC{`Y01{0zO^LH!Tg)ZDnf6HI>m_CmCy1&;Qdm3v~d+Ii7#M?xKYfA}Q* z0az96dVeqFJEIxixCxm)LlTeyjPQsa1jNZZ2q5~ed=9C@aFRz4QQ$pW^#`-) zD=N-I2qdM(n)9YdJ zfOr31vNJnY9+v?S?_(XjDACBEP+hT^<7;4PcIPF>CP(L+c6#0$UN&419$3<(_>g^T zB8>wX=_Ok_SxY#~-RX^F*TDUFTa~4!UfmvfrPn7&e_#Z}E_cLeREroZ{$YXXo#XWf z5dS|wzZ=xOZ$)SO*W1k<$Yn8DZ?AqYY$Q=#0hvB$5Du!>&Yome8=$E70wL!|h_zkwZo7 z^u=q228 z0F3y51yWWl_3*z{|6kgm@6Mu+oGyn4@WKQ4GeY5nl@4?}K0J^n^Inp7g4q8d>Hmd3 zM?C!;(c3frntM!5`hOT(`V%3RvF_4bKyQ%}b@=c2{uYO<1*xKg3BGLD(pIa5)t@ zK{I_X8vlb0*vD=o<^-tZi5sR8Nn*u1_zP*WLUNwqD;ll3mpS)zKa-t<5Qusl`xJCh zH9FLEm)HVQ&u&TPGXTX7xyAS^u>FfeC=87a>Rtjp97X4vk~KH%a7&y+u*<}}!b*y? zO#zUhzTUycw|l~DiScwFFnjqitKSI{SKfbh!Ib0PW2cpFeR2Z+8eEV9xh9^gYjy-%* z5g`m}m;0O&n&aUr4oHoGEB;295$7rc-=Mj(HlfS1?+_Ulf|B@Oc^%4J2Pb*NN`XW7 z==)&H-0|LxtCy5sFz&{k`?jqTqd$$3{zw+Ru%{P!4DtVdEbz2F>X@6gOn#~iJswXa zPXT|YYbIvs#mC;OitV^qxV|G*wCy%sh3yM(+C+t@#5a-X8@!no#Gl!1wO=q6HHF2J zv0sM&pFrx%%0#TrZ^;6iyH%fsSCw4Riyk2*BSCW{X1NFmQ}xaI3?zRqmP8G{2GurW zhHr2iBJlr@8TtQjBlRQb+x?}o@3=;PG>bm{bn+qt=@oof4|)2y40lus#@kFda8KpM z_eKa|5YJ>S**hfD((XB6WRo09vrCH)|zou^~T+DXM))!hNDjFnRa-}q*3`_>YZIp3BZ0_?ck zCisg4=>HS+P*Y?s0=;*reX+oZ#x}PtB_XUNq(lm+xhiQK*eA}t!nAgb1CIG^#cOF` z1eQQ>OL})&m%O;fj2J}ki8RDtn#5`2X;trCYJ$nXKu`s@+_GEK3MD~7!7XuJ(VJ>u zsL1aB0#*4Nu6iQZY&40GO(XHFw6H39DJ=N^r_8t&s@mhNE`+i~+@=4IN7y4og0#&N z$x9%CZ$Ao@{@;=SyunPM@pdr#Cl(3m|99KA6U<+YU1=yyB3NbiSrV6@a@`2wxTxK3 z3einRF!>kQFTpL52=uf6$N7H+{RhH-OY3;)QT;L4&*u?2KOo972XZ_uhcHQNW*6gC zx1oq`z`8_7i2a|$I&TLYZ4E+t#g@C=lRpFQ1|x$f8en;Gw=K69Ql$=N7i=k7v<4Mr4>E!vrQMV&9kH zG24>r94?6WFTwvq9kyXEDl#`Br_1{|)-bl~Bbozc6tT zO#TIiPjJg^3)`4fmEtN*bre%AkW0a>SVdJl86Ri9sqOJU(f^(beWdKLIwkReu5=*-9dL9{D*)Uew|o=m-Kz!7Xu&>6(`mEyB~tqRqqC z>u<=S#+eD&)^^FtC~GPVn}7j=TkY^9k<^I*N5QRj&?cfp{J%Pg;7=Zs0s;ygdaeE> z>|#`p&)7Kc;$e2A_44@a)74PQ=K*VBD$7ZXa}VPhp@tyHNUlj|cl|(nSNc9$?4ENB z|NJk}erszqj9#CYAx^VXt?A}Nq63e2t1pN8?J62=;r=v^+{ninhzacQ0rO4w(2 zOd*~NFfFD_)m=B-qrA;D{uUd1g&Pd!-9}wF>=!(kB=EmZ zpz9~sF4=P3;MPL7*cdaY#`tOglQ+OgKITU2z@nWFr<4hNDy9v=5LR`@|H`)z{K=z_ zC~)|)rjkX^ZT9tyhP!h6s*qthWp)6f&*&TqI@_e#MdA5+mv;k&7Z(;5^%(UV-4kvq z6K-4}!di$(`#4j($d$!ga5>1tF_+Gv&w2~lV}hXn6KJvVXq&=IcD=RUT9q=XLbYG#3hujVbd8w!rQog+yO`gG3Y zCtqwm>R7jZ>n1F#77lHE3Yg1o?nE&g>wgyAkJKNlA5wn_z9e!SKBsvCj7Bw9q_ma! zd|ks&mRY01RV(vwlWe4o6FT`~VMQKZ3T6Jjirlk{l;Nd!Fxs^07;uV3A<)r$tqhR0 zl^Q_1ItiEn*Emf42s$vwyNV!RDpfVoKGih*mfJl&xnuj(^ z+Zg{}j1c?@jw5$9Pt2k>UdxiLrQ*gc>UmD*MP?(4hSzCgaDb9YVe+n$UveCSM4ckz{smWAha->wk9I#3n?)Q$tIv+$1JuInj--cnAB^ z|F6tHm9!MW!-Q{y&2rN9Z5XC-Fz8j%xGN4BF3GaFTa9;i}vT zx367)+ijceX9ssrZhdI`ioG+rT@S3tRhy@TuDNaPx|_yxi^n%l&Z2jA#Bbmn2JI!K z36mxahm~zbOEE_c@ciGKar~b_=c3HXN)0~jWA1|H8IUizMx>!6nK+~^w-PUqefa{( zEZnqpd^ERb^6{YpPBv)c+O*eC(;xii*Z%Tr-@y49w$Ai1PayUB(W7Q=hpR(3vysNY zY{t8$cWW>5KUuJFUTG|M=+@@xkR<0815!(A`hz}NFEWbfTx&V38%#Yo-8?Oe4&9fm z(0fZGEys)|S+eJ;0g=0G#?DDbOwj4y|mSlSR*N4-&`yZRla6F|~i}m^CU9 zgfXiPeX@*$Wr~d3hV$l%xHXs`WpWi*m>Ovc+oBi2g3>mLiQuEc6dPGGcy8T$zW|K( z|7agV$MC5W$9wiS&&{H*1Pb+oi3snBe8t3J1f)OS{>+ojSHd%W{JIjMQ%w{Zp=f$a zS`?`W+=5VQ9I^$5Lv$hvrW&m|0hyURR)JgSKK(2+B*erD3ye?+l;9nKdls3afm;w_ z97^^~c>x!3``Vjs8{bN&OhN&o40{wI4$);=+_g^PX!|Q6*)2h7lMqsyod_X{An{DH z(pPQ7093Lb^#7f9!agS1b5zicV@yq$a|>?xwA#_%Z7Pacv+3t9!Xn78Rxi(5y)!t{IyI%$8C`@ zThmD!)VmHNvJ&DEKQ(3FL08iO_I98Nd-;M-hRM<(E{_yn;wdFzrJa_OUOHwk-JXZG zf>r3;w^CPLT_TKwMUewIkAx2lnGK&Vr0a zEFq>)Of5f0w;&YVPUaN&U^r!Q7U=)`?9qj3^2F;aVka86d@L0FP8sL%P*}BT3R5A} zoucf~qyA~;R1l-BglSK>NzniIw>Ll8yNpViDejUPhNa+M0ib}jJ)ySJh8dhQERgZ| zlZUkh{r>EjG6jtW}t6!JJN=wF^(|PF`@xUY+3bqI1l>&-we~xX7Jj@WnOY1 zkw$YSop4|$+(icr`u{3`v9Tv2?b4#5#yPMZ8sDT@%)c5|NjAm;4iJm7i-N| zWzjE$yM^(45iPBU^vDymmU*S8y*x*mazcYPZGN6HZm%dbqaxl3O=}XELhSz@qW|h2 zAo!Dqq(JXdV6NCaANKs<_L45tO8IJ`SSyi@wBa>i)DCUAebf8*?ihlX9on0l!WW;n zn5<~|PL5h(w4jx$rCPC4sxdEGqg!bS1{bIYDy0efQ>elAAN&hH_-pHJFNXiW9U=IO z?>Mr&c>%lx>{fOg2-pwZI&x1uk*mVnEy|^QMXT40+vL3;!y_X(;~fZAS)Wg+QGr*0 z)Xf7!h0?{c;Fi&lMt}uthyu=`FiJLdw{BA9FdiOA#L!!_!H%^TtRcY4Vq*_ew=eq& zuh1D@0}6&TZPOOKJF)#9L}Kx<-6Q(1{2GEkd8D5Lhc`Db%%aA{o`%&jN_eN)0H!ep zt3(>Io3*}lwt0cQ7u<@|1z0fyd{QQ#csQ+EtW}bBL9N=aREj11x~xF@kA4&3zn(gt zUEjP2b_{(*+B88RcY<4SiXt10xWk{ebv&3ZCld#B%8qrjk7oEwg34HJc0m2lppPJ> zp}Yz{(tJF3TJw@Ddeh|{(0IsOWR^@{&WA9Kx%-?vy(;^104`=HCAnMyHh7}S#gfVi;DA%$ zahHt#*K1NiIQcg(DZ%FobWA})Bz`Guebf{>(o2cS?$`>P|5H&F;(s^=KjyYHFNIey zUebZ!IOWy}q|6XUMiQMwP|!pS#Q%db{&&ogWrl+3dfPb;i;EqfOKMAgAY0I;*ctPG zcOe9Su^&e+Ze9k{fb09xO1LE@xujl)lpt6$AhA*Ws-@88C)F1BOR^CM*O+xlp~GlY zM{~EqkO*$;0)`YG9yS;@K)@){KmoT{V17#WV*!N2Tu8u?$GW5lNEPnSr4N1C*MQ0y zyHjQXV*j5}PDYvMmAm0%X&+mfS7gyaeozCeB=Fh^>(EBEQq5XmHM?)uo*}qnuD7x; z%{OQrUe#QlMbB|Blmtkl7Bu{6LWiYXG#L27eaEP#G1cMTsH$W>p;v5vs}M!jQ@Xvl-Ho2^tbXqH`W}^qUTTM2utzS_{ww4F5u#&{R@0qK}m)N zg#FYrmo|s8NWZZI&3R&s6_b-c3TOG7u_%@p?Y^Rmi?eWpw>qY|!8$Kx@^>;G?&WxvkAnn1vW=!^cu~-}2yYkLkW+ zRI|cfWdv=IYHA@Z`^9$)oE-Zr{!reR6fFWgVwIDC%5@0C_Y4MR~{14mTiF z{S4#$h|rKhodMEm*_WrjKL$bFX$QUqR4hTG(a=vlf`Pctkx)P#C}AAF9S$~%w?GAx zOejsa=~TAwyU}&uDMe#1)3gApg$<3NPq852IxWF|$r_u)&`;iWV23|s^&fxIG!Wc( zlf`|<W{RJIBrIVjT|@hM0bb1K_(aMyI-iHJVkvH+-s3|-8+hd<5x?wam9 z5fQYSfW~;S@e~Y`Vc6mwmKK^-8$r>36M;;Lq@pfl=E{YWJO<(hGs6_Z0rIk>6WW zu)$AAs8X%=VUhEuU`MGJpG2pmL;R8l%8o_AP@ph2Kwoev76+>XzWAGkT>cHewApvL z0g3<7PK5uGJl=YI^U5sx_}MaCgD8Z}$79|Zc`bvB?w{Rvq#F~^#8d(+{(;Mmhjl@e z6z~dI%)eaQHVa~Z81)bQ7DqQ9$_i!Isvfvobnl(Yc6E3A?mJRpe8}a{l%}+Rh*m+m zm~{_-n)lr`-FKoIB)VwBUmq^3-NpI7G^@)5D|d{REain@*hbMp8Lc~0yO&0zz6hG z0SF0<4E?N!5&wT1DVxx@W6=K;f%yH&X7M<5@Qvfi+ad_0e&?BDvjETg^85EX;%a^q ztVc6`k(SS)Re<0xpxV&I9QbyE!);*PccMn8bkhQ;7B&HkC8Yl#y1(l(z!6QoPbY1H zL$6&%%Ay4Rq^Tje?{30<$K;n$+x@fqPE-a9AUP=09q}pX6oabKO@Q6515ZHa=rOin zs3quBD&$7e(fuep(8NP9K>vRa?_pyL5K~mrG7K#x9eE0fh8C2hdB`LW#VID`F>ZMT z{Xc4Q#3ZxZuDkCzJal*?{f(rfBNtx&M(Q?Cf$rK!(Er~TZ-e9+G8i3@u_W`@l(dnq z{gWsY0Cqu+ZQP3Q>pUG>>J*Egj-dZvb;+*OZK>N>V_kyL8JTo7E9EgUc?A9c13_{} z$Y>W|L=|NYh}llbCM0FVB^@aeN!?CNw?*p7%OmLjAL4sbCZ$XovJprUcrn5fIf7$fCyOd#*n zj}AWtopQ=K#Yp#^A8gHPWucg)iiW+fT8O#s-1RbPTA@^|Rk(NiL|t?g0mFKsP%Ksp`C_G3 zF4>>eaxGuyk+M7E+e~yjD=;>8lZaCu~rF78sNGMT2TyuU=$1^cUamKe=!Ke z43{9m4gZIVjpu*<4I%hjI>$?|ZLJy*so}j zq$oIXFbEh((8Zj}QP4MPv%Q1d-yg&OKZW1eAE-o@s9u`K3%D=AT#09wMb!;52Bn12E(ci0+%s($cna6v>wj2kZ=2@OeYakOb6hogyk2GIXMv*~QLg4y5s!GFsk zsh@bqu1gM4qPS(Fwi{vh9ao|Us+zhgDC}V6`=hPwk@)D@yr50qCIrJi41UpCkn-S& ziY-uZi`Q$=|37DD*c{f7(gG-MDRAHMk!lN~ppx~IAHtnQ))z^PZV+$E1YEXvizwF) ze|T1UP(~Y-!4~0^&*B8j;u41X@H`;#9dJR!12^i%jTeuEf-Ri$vqcht3MlRYi}`~SWnBb4u_+L+QM#C2 z*Xf$O1@|2R^{lQ43OkL^P5TrKSj=h?;CqXU>le5YApfs^3&Ec}BnA400v|r9S!;aff;(nm6=zfZORdAM zFkoWC_{7*)j?DinXCnBMhe3gb$z}z1AHTkp>i`M#)CGE79T-zfSj|t*YB6XlZ^XE! z$tBece;u1TQEfzp$)Vm!s$mP$zt+GcEcpMwFxLO9ekhe^%y?*mrjveH(U7h6P zyi%!SZ9zj=%{}$Mz^4JJ_&=+>4rNYLS1W%6U*r)R1>Ur=c}*6*mwV@Ntx&6!ilw}H zaHNY68FVrr1I`$8c@W~)(C32 zpctCq zMcYvl(EsoDB{2evf>ad4^3qb^7~O7BhqCp6m~&VP?17iXb*Mnwt-$rIc#2h*RCq=@K2z7kt9$`jDQ_oWRtvuHg)h@>T5j{iL}tUVwb zCW@f~9mD@SgQdPnhDb&6%crKEIx^4+oCt3#kTBN&tV9U@S{_GkZm!9qH(tt4ju^5O zZbBp@zd+fpPbb`2`g`rc8wCEfF3T zJ~rMkk?E7e_m9~{Jqm*$AVJfO#f`p-g`qZ2cy`8+8^S$lH6Ie5mO;(Jz~7iN&wS4S zEo)3-kdqZuj5Q^Lyp{tpH_)Ko_Lr8_0=F~n;5^wV@{S`5(t|J9fIKVvBGZ;XGt)Ql4>F9yJ8)QRFqjW~r$z*DkGrHq zg#H?fxWpyWJ>r5)`o%&zR?||y=tHyy(uz-g#v`!_NTCk#|35~aJftPx{vHb-<}ff3F->UQ+H>u0a2QJ_GLtQigpnnBJRy>?ISePDK{7XlN5Yq$Miez4xWg+W?W2b#^@Ie8b| zHmO@`-kd?x4$hM^v)gy=otfGvIKHs;`|~dzBgZ(rOLk&>EVrS#3E-U0!!hMz zA14u&=zw`|+KZPVuQ z;WhBG8>HpeH8->XvJzCi1(1!+aR9=-=!vRR&o5_zkl%(x_&j%Zb1aMAw94*0>6Kw^ zVqVY%bASJg_5T#K6=gn?*_XL4bDa7o>htOy>Z!`_DhHG+;hli*f*->j8=I31F=lt| znHm}#t!TS)dmmr?(IBHLwk(fr+PZDimi60m$Iq1Bx-B>IHaNgm+`}-(1Xb9-kA>o> z1Xc~K78r&BXmDe5y9gg`4N;@PiJR9hE-te0hyr5`2Ebs-;LrHJv3a)$RBq2CXeg-0 z#Ne7i4R=Wl6T>q!<``ggS396gmW%;70QEXIC>tkCkiZ?>(7Y2sIT}2(e-D_RYc%K- zSoRPaTxq^GgPd29%{;Pu*X-2xnd$xe?wi`q*vl1zS6~7IrQvT7tn_PWEA3m+sb>Hv zH}A-xM{LarSa)!+)_ipaJ!aQ?c;BwQv-cB*S`KYBG_?&QNL$|gRilHenzv_=^K9_$ z*?qf!Vjv3GaGFd~$PLR#u4~=~BzF0~O1WIDGOEECMb3$CXl`TpWP0EN0|1kg0V1%t zhW_7%GM~>po>`;*Lj861esxIsXXR7Mqsj>S0eT0zEu8v8>GjQN!0r_`K@GJn@M?P* zMNo_=r?=~xdl^D`K=B8%vAG9;IF{J}qE(KqG!;>(8=Tr3(zUUNI|gj0Yw|}YI8>h?T-Lp@Ve%G z(Drens-qJ|>t7OCZEzqfups>W7&ym!0fb{nOy`J+>I;H&zygBx|5P0Re?GH6bEWz- z_0#Gb)V%U{%FD`K$}7>g(97r{KKe(f(0nR`9%7NVMHkyjS}DmDn96$dN!qd#bp0!t zfS~S`%_r!Hn5|1SW=F(VH{Xy!PkUf!!llglRtTiAIXA4($l&_s>w&hM1+$TL)i-Xe z<)K{PJOEJ642p#b7URG}x~loOOZ^yhXo?de4i8sb}FOd!SCisc*WMjdk8j_-Yi5=+XJRnxn~wk(PPzt5B`&OO=^q~kD7^l= zpindvIN9T%yVJ`3a6W!E^BMyCUS7+6|>Q41u^>ym)>MiOG>X^Dlt*HfdR9&v-)K{rzsi&yNtE%z~ z<=>Q_DL+wusQi`kE#=RYKZabymzB>!MDlUvSC#iE?^NERyh+iO!^%_2 zTvlgFnJY6xnZe8jnR7CyWlqdw)&Ej|uKu(7kLr)qA7tL6+@ri!*`{n!HY)3stCfn9 zS5_#ODHkc{DrYDsVYUMe78f6a^Zeq2aDH}iC!C*I1mYZjXz@Nc&n?~y=cg7Y;r!&{ zYvBCE;;nFg!{RM)ethv}I6t;{Bb*;y+yv+SiyPoPySN_C_bi?c=k1Ho((!jM9uMcc z77oDqbqkNe`85l(aK2+`tO+O&YN+OV(-&f^Ohx9b)j zfOBbK3eNcjjNugv7{lcYcf$Gd1sJ&q`-A2hIR9l6@EQ146F;@`%_d+n@Qo&5 zGVt{#hWxcAehu<(H}RepUukM^{!%j!SnXTHy?A7CHJl$_#J!katigHjBJRbWMW}WB z?nNkn{6mYY;QZj?D4cgKUIFKwi_78sz~bd_zJKvjI8QBJ0_Poz7sL79#S7s)xd;>( z_+Qc+@xrw2@yLld*f4O-sz@J$JUJSggc@CW4+B_T1Z)u(h=a-si!1=}Isc?Rw zi7EMf^F%nmsd)mN-`E7z9$0K<;JnaO;XL0|;M{D2oDb;w({OI+PhtOm3cAJc|Ets= zs=ut>rk<#LO?d&dWe|N6&BKo&j{5vbE+?;z!VJ5ox5|~at(^hmJ~Fs*{uOTDqOBOL zSdp*LO^IXm`4h#UAg0pcKRH~kh6)I9_F(Ni#;QDj0zIfCZp!Hm33lAh7ea~h{P8~Z zu&?KXrl5-8g@on`HUX!I{~~eY3gg`*SYpuP}mp z=m`!LF2{}rzQB3yd=@|rux>I0C=6rcd?qA1##m#8i4H+z`OmJHyaGU}kwD?z;GP+v z$a(#|0-!k04Lz&Cs)z%QJY5Ra3fSAy9@oi8t)GWI_gX{2joSf)75+F-)-|67D4hSd zh2#Np7$8`=CK+QZG{pLUD#|19^v`8BXUip@h5d!!juBxbJZT_?XjZ!u1ST#wb zwfR#;RjVw%!m9Q8Qv?*|{pM9vUEFF7(`v9je{z7jV(wu5KN;PFGQW}8o4FLC_!rcT zs-k>e*{^6Y_xC~gsjXxE{E$$Ru|jaNXPY{=B(Iyl0-$iF4ul9p@t#t^6r$z<*3U2Z zM8z9OfrGMk{&IlA`8FFBULh#U#b9!oCnhkE^r8!g$@=+A{h;^`M=ekzgJbi90EHXU zn*9krs2#k1{t^J=wl$bTTRkimb`EY{kI&}-k~0};1Y8EMPv%HtSUxeF4f7WR9A_%S zfwS$v)Fd~7!-)GSrG|cnK7=OQQh$WT z=gWYrh@IiMFg9QEAl-qf6KyPwZO_QQVk->d4XuBxu?=^2eI$)2*@Q{7$f)vH(Us_N?Mrl^J|5KHG| z+>e?ec;dd>CFci-XO%FKpuaDZ49fb+S|8?&Xm}KIYPlJ31dQzX*}LAxg4;V>*+5mZYa}N%cOoe9Pz75u z8&F9T6RjapZJ2~FD4L{*dJ*TK%91&7+cbHlnI^yiUWp|Yk=HA+8IF$0)qu*NAKbYi zG8L6aqL#-tOt$&8jJZe?79dFukwE1TQL7nIXKP+BSxLoPxXFZ>ML-X*s4&Of0;mj* zJ3mP>Me8S&xB&@qTtWG4wYigzG#4U)$!9iCTLLSfK zld$w|Uua02TZ4fVth;lUH98TaS{t9^Lb1iF@E0?QNmzpCg_Wk>u%Jt;4BI|=wTV-; z60n(9(lfsHNnFF{;dZT<5He$6&paJ&CnmcLZCJ4~j(vv7S>1`*_MY|l6N~+pEUj%^ zQM+k!lTjx1>BClcg(#ItE?coJov<9PZ(C;gn&?(%0G1AD%&|{}+(!NaXX82P3WaZ(;q<9d?`b8+hLKptYX-fqaAH;C7*@ zd2**gZyO|m)>a8%1nErN+*BB31Ba}g+z}yrb&Z$nL=^yi#k!bz>6pZoa~{v9!w3W8 z0Bc4nF}dBKHu;cn0|)EmJO-}5CSKE6!;Y@KR9FU+W3W)pU9{#HD}WIiuaw^sbLXi# zCa*U&TZRo~EnwB0$KvHf!kZ1t<~+@=^Cw=&M{-hKKIgRC1M1gjfM_{9pupvG9%CsZ z31R@n(J|R)Vq#bv!sKo-FcB9J3TwLutt_|;^fW>M(ek%XUTbQF0t^yw2BvDTJjV3D zheVFUbN!8x^XwD$5qK^ivA$p(v92U9lCO|Q2|POvmzpOJ8oD(hwMLT3>$>_kiEeF~ zJYbM!A4p__E6wrA{RU6p;>QN3^KLbDUW-JjEC77SpecUGLnUDhWjaWS4}URH*c*|<#SfTN7K z49}yCen^ZsIwp6UI1v_yh&BfeJrU3glKAd2@Gt<<Q-ztJ@SMjh5f=w<`q zvImmHN6|Z`|E(nQlgL!$>d4vl_hG$G(s~i}f5O^e+2m{FK>{l$ys2aIJ_E~F(K&g) zIEDvA?)*b?@?OBAOVCQakEk{dT8L_?%@NKRg?=dn#(7LBcxZ; zi5d?vO#fm1|ED8&!z#K8`|Ebr?zdlKyF?B99K@*8O&ngLY z4ep@Ju?^^IooCqiq$6cm5>&S|R+CQukj^J9g{ei)WQPzCL8OMc)7zpQd9Yt7BlTn^UkJ$O~DM@Pl+ML<&{}=@w#jV@-R8i-p<9L;cx43o;mW`!eX5?*i^cHxr(0xL292qQl6Ww)qOw%Gz4Zf4(~%$!a~HR#E&vSP-Z5eD$8o+9M^n`MSll1SdEsyXFP3`S z@>XOi`u_{b4qX3>^MC(g|Hyv7z1LoD{fG5Q>kg}pOv4O7777%TYE#w9j2wG6GI}|k zPZsmQTYBBTiq)p7LV)nb(BDL=QZXFnS_BB4gy%ArNGp4E8buY)#1a#`41Yw|9vNwpQk| zA8b4oRRVhKU;WVtv<;+a%NB0oUzxfzLgKE2M3^dglX+9hu$HHlzrGDvj5Ft83B3NZ zBZX^uGGvboN5dS2_5ZpHV@7l6ivMAwxMBo*Im>I64T^o^%AN2e6Xm*9;<^iEKk)%$PQH_ zTkC3-irK1PEWI=pkC49L(zKc@Qne9sty)mSO3Nius}$1FAn4`%NROvhdJK@RWI(iH zfL5edM96?jmjOnwDv_%3(5IL8qc4$K9t0bG)8YO5V47e6cIXjK#1RYX|1AQqSixU$ z>57M;>~q+jm^zX_0{x@|B9>4@s>JzyEz`c_x>ooZ!A<_dqq>N z1SU$u#bERTlF@N0Yt&oj@PoIwr4DFoZK|ceP0&DxRn2jiXOw}3001_<+Sy{LUJo=6 zJ}c75>z`Tk9LX`%fl^SKI(&G3nz0bNzuA#7&^AXMRGmScuSU%f%2MWgA({ys&cnR2 zVo(==dsq4S0>(jZ4;Qrl2Q~AQOG*g+$ML^yKSAu@z@ePV9GJfx*qFlQyke?37Cm@) z|Neb!pRO@IwY0=GcK0S@)nnD$Z(6ozTXh>Pu`Px_k3Eor<-Cu(bAV@N$O?N4oK5wg z946!`Je;DGOyN>-F>`_AnpkvnVAp=w8t&kpVL0pRi~aP&Pd@drr(Sp-&R_uC(c9hK z-VZxS!X5hmx`&e~SSOy6vB0}#&Quu;XBigy3x{r46?rrKMscS!x*r=LqMKUAqjwDK z#}|g+u3Qm9Vr5Q31X0MV2|UJa{AY7n9*2*c3eOmR@E;b3kPP`ls=o>%N0 zyk({x1n`5m-WH2(<~@Z10u$!@wp7Jqo7?+4HpQYfuuGVeoMKU?7+4GxMNOOAJV5Ou z`{Gqp|E<-;-UWwpDu@FUu@t<6bF_=k@;Dr~97~0#La|k|A?w!=TAgC-K`>BvH{3VW zT4Rj{$xz@;$MT|pRgPBG#WugsBUIQFOkLN3z)}f4^4b)*FU-0L zr#vBfN{b7k=;;Rrq25c^rSL6AvE`&_t;Wt+>7rOz{xx@>Gw>Bkd zd1%{KuFc$c<$m+<<&0$s=>LTtZiowKEL#KzJekvgCFP+!?ZmPl0pTvk{~iq&7fu6J z7j4lq<+kY@Szu8xcAymV%lSg$fA;+Um&ASop8u88>CA!08d9)N>(l}7!#fZql$mN+ zJhg}Jr&Sg3aFy!~3ZR;15eI~+FNcT1usLk`p)l_N=~whaK`{+5^?VfgfJfrI4pD)~ z_;ofG@Vm#cd4C03k(nDDoH9X%$P`Ww$EE&;T7Xc3S_KM`@oNDV@VlqdE}sdsA~QEQ zI8A~Kktv)Wj!XR&2t_6cvnb?bg33x$%sLo7m+1HdY#g4tF>%C{N)}hD1;M6!R4#k zUqYzD3BB7}E<&DD5qkx}S5gF0#3W8U8D5Y3tJWx*Qnod~yEBiMwYA}7*x`&TMm(pA zlPkbN66c1eCO03}|Ks@IBJU^oH&4@BH>Y5`^N(G6ipH(NN`w~{E+6c7o=S-z(vLnY z;CD|*xF;jfij0b*?2ilb$AXJ2W8fuNv5*0%+gBP^I7P$|`@?sH7hUX@V>xqaca%_| zhPdeSA$Bb)mP8Ws3nUhDYtVCeS4}<~Er$faI^>kjLHAtcBc9DeUgjgxD`Ku(yZ78i z>$!aR7n->P{eSgLI^E@&S0LPbIv3sZQ2Z>N$uo5}CtMR}1NB(aC0);Xo5C@hYSp3L zb1xnrJqs70gh%YQm=j)lmiRQKY<{7ekn3)5>ABEiQ4lXN=9e(5-QyLA*^%VX(`gQq zB!VI9M>FtKy(Qw7f;c2qrlLC~+zA=#NklqXKU#%YVL5T)$>c-05P4Z1|9j{E>Gm3PbT!=+&$A#mJ9zQwuvfhkGI$pZ?HvRc~J(?#^=b zrWAa4^0D^P*`DHCTsYr3k4|yd6i%qxdEyM{pBcMmgn)C8{|d5brc@Hf*8jbd*uS%0 z>8t){+KnRvDfpP}BO6Pkc3RIBB~>#LB_v?R2pA47jfP*XnV!Wangvvf8_-FYl%j@Z zFdAkdt`vp4S_VGNDcRNuI|ZK^J}U1Y=TDvPdQe3raGmI_&>GRM3 zoZisNdZGaMCaydVQi_`}J9HO>M?or1OxWFPCzV&^VK$83a)XCcLAOhdDJL32GhPad zih|hspUVh=KcDor&8e;m^6^rwztNg;n(2Y)IJKGJDvD5d2?yYv83Mp1XftM{%6zlM zQBfR}M8u2{lw%ANHzD@F1pY@+92Q9EU#JkzP-$i^c!d%y^^?dJM@4Z^qEbru3{6gP zBoqf#Qo>8oYZ5`2Ev{9?K}l8TLx4Wt^lU&vF@K5APk1RhG9L@gR1^m#v3)8 zRgBOp4m7XZ=a<*WT1seBtDN^kkxckjZVR5nCmySp48P@~)YTQ_tt&W`QwRGA69uZ; zr=9^8t$)K{EDlPldBz9;7h{0mQL4;0TO1WK6a?e3>`PKtRgm|VYPpF@ty~#h|9>gU z6l-*to|3Sss1QYg2-2vo< zps=W*g3bRuO$hug!1VBysh$cl`GBuC3ma0P@d{g3?IsaUf-U* zL_D5ofkR7UbK|Nw{r-1^Tm#<#vI+dmI31};T?=1(5+8b(TS+5?uu4`~pUKq-sraWn zIP%=q`ip5~D}Dwrx*P5-oQB{42)@3175sM+zCqehzpA!AHhypFnhJ8{z6D@Fjs3y8 z!)YOJ9(!MmHn6_2p%&$yiamUazF{@|=f{QyY=7?pX@4=|nvXqH|7`-_|E-6^{7y$I zQhi`r&MQV#r;X`}Sxu%Y6&Wt9LlKlGVdCbTU)RDqB=jdnWu0V^`IuN}VOR#In)Ehlt3ubrO zF?mBQ2LC00%rNbO+XI6`&=SZrr*4Rl!$y&1SiY;#L9a%~$Y5LQ`Uo-mM+Pa^&zi9d zZaDQOQ`ZF&k0`zi|5Ya7Rfi!0s3V zbF2$VKdDx@fuEk%k+E~| zB9()w0Wecn2eZy?1cugs-(Hf$>1diB5@-&n6g`p!jh`#|6-IzZ!TgK;e-l|W9@e#Ee_(oT^ zapvK#uVI^+07DPUwQzB#*Q8!n0xd}@w5&j-%a&G7oC*NU=sG8g z3joaMKzL0qtmg5qNM}rcU^t`lA)GN#VFceWQ)as#7iMO8W?&53oDswQAyV9vme;{^ zq`OAw^)^iEgPfBXW2*8Xoe9y<#X>5hWCg(K&P6te3(+I@dwK*eIGr+l_~0n*lMr3Z z=5wLKc>Lom)xmViq8iTryqxC+y}t@*c;iXIAi6lUW7YW(E|$kTc|uDrQRVTD5La)e zP?x}&N+)vYcn9=N-)`s(SQO;@upf_K2tzFl2T^*7MVdhYh^~tc^Rgtz#H^`rGup0C&&mNF33#Rte)Oih(#?f zpW$7Rd@2jFJY|3Ab%Wwc5aT%0%kzJ-ID-DKf^*Is`dfrla(J1!x?YHCS>ZX03d;VF zc7W&(Plk7<$Dw#iIu`^0X7p~yYsIo0VQJEl7EOsC;F+od<@rBfiQuy5k!U{%0e~4@ zV)0tBYB1yAIKs+ zqh|!iu9t4e1+AY^bG_VCuFMGc%+~QN5ZyJzpurNr`0HUT=zo1jKL;)Aw<3n>iHCRa zrUGXi|CQ%I_%-)oOZh>I;7J~b6UbP7XeD%kVK1GP6NqWXr5$oQ4R~{A!@B}2Q;W-I z3Y{KLpxFToc>%z)qTE3u%d_5OQ70?AK-pfXR!dx1_~XGdP|eQh{>BwR>iQoX|Jx)^ ztlQxbCOvgYYN&$zr};H9umt`g1eyueqv~gE%7xilq^?xLPEOGxbqKZ^-*r!FcLn+E zJqv$a@AB~!v5!?)r~)(Z1V?<;s5~|RM(~&b#1V9UQB#?(LPpGiorrWi841wkD_$(m zrwG=_F{HTY|0ba@D|4vm(9eQW%y5m-@}&!Tq0uvHu3(xu87%I$Lp2`DH!cO*7Z;1#9j>|65$CD~m+wM1orXZ^V@r#VN>V}diosnKjG>>=1xY9=b-2{6p~ zR922|Q3__jg%Yn+DDVFv-j?voc;2Gm8+OnebjOZ)vHlsp0c}h zHf&T$mCu67MzxxeV(~dWhA0d+AWqPvTS}R5IWGV(qXXeJx3ENrH#=KT66BgXukYyI z+Sj$MQ@#lKLai4zi>CQK*C}@=lI!tctP%58GeG~>FcQ6_vmPw8<8=814oRYr2b;`J z10q+>rJO@P`_X~$s#I3XDxjXOn}haKf=c`pmTm%zh|%>Jw~achquT@L#EA^1h1W0CCk&jj+Nz8*yX6KpMe%krvki#tf;l*f{*;rV}VUFg! zfn1&Q{jYn8-9zpTv;4o5WsW6Ndn?F?78kx0Uh0;7*;CQ~|uR7l<2)rWf=0ui_04^w?_npQIRMUp#MTD;T9RsVvW! zS16-=y*;aDK5&7mma%n=#(5S^y3w64Z?$;P=~4Eh1L0MzymYF7&R!(RYGjqoj!68O zl-%|OH?LIm(D>i2RLUv!pP@Y?4V;l3dALwkR!MxctRhV_Rn|ZIv%)%NHff15uOo?u z{;<_~6zJJSZN5DJTQB?5*|Bi*xw~lmDkOx->3rZq*_wz>@nlMBO}rX>>O?~F{9w~~ z3T|FWMbzm3mHH*i#)o<{4a&rRLkoH3v=W-0hRXWti&$RoXJsSj1~R7L@;|`+wS11pdmY%mIH69NU<>1tx1>F}G8DC3u$ZOthWZ zleN?Y!rWg6)qip+!9PQKWJhXW1<9-}_qt=}h3_covNW%c;#Wj{dKktF=)VF0Gdd7n z(*fLbyem@a{UVR59R0 z1;k}N5Znb;0MjHP%cE6LSitHc?ZJXR|GFAC3FUXwadLEhS2lmYy! zSx8*_^Zf=cFm@D1=m2IGXlxDMqWefsYJUZJWJ$S`pdSODQ+gi@(vAmtkmM=P0FX*e z@S7Q-b~M-RvP=Z(DjRgj0}rS<2uNC93?)_?)%MM4OohtfWT}Agb&24KY+cc+O0fbH?*u z3AYE{_d%D@l+GVK)_yf&O135CjLQ zaxWH9Q@NHx`=-pXGRHs$W>qUe|F12}Sy|3zTh7WdHa}$y^q;*hfgLofmZmHL^HT!K z{cv2`KmencVxJ|L)tkW&iKajrix}d5|*4{Q2bGDRT^r?EJJcp#NLT z9$#OSSgcqD*u`2rhpY>w`f8}%bjhb0JvT^uH8>F&Jr`hvddnvh_ z3Jzy#I{yZ{kX=6;{Yh zKP%~ZXLVvz>Tm^l=#{fR6jZv4GS3*QFJxY#{zu5mh;#(8Rr3q;k0kSk8o- zzgYiJP3n#c^5z|ZEC?FU70VO>7oIx;L}bFl$|Zp-0)v~8OZccw81o}cM3`QHMRqO$ zKDiJ@ypVI$nEnngDaw`bbg`0}Ev=>V{}+%p68T)@fk;Q>9Qzw~#_qGvxBkXDYHhGy zLcT^GgxjW+OfRY+Aupb9|A2rBQKE zGlPf#i9?aakeporl2~jP;?OBcq|fp*d>%p&+_^{zX-ii`$bCkg_nOOH2pv;+5D6lm z*F?dX!R1X*kl2MGLAy;+DoCsXkRbFGUL=V$coee-L1vgd$S%B$EJ>suC=?ci3c(Tf z{vu#^I>%F%iSefyO)IEj50=>{+;8ikpcVK5hIZ1sG%+Oir|10dzkjR%K z4@c@CQ%+?L%zF;pl|C0l{|=ME?Sj|YoB$0)zN@ciYj-#1hM`q#75=7Jl#MrPt703r z^loO&MdyTR)V(Z3-J9CCb@gmySc7pU z(l7Bb16p$o4QNX*_VYc$3uBPZ=+M0$>i=2fN@BH>KaekjufNi1Y?z;Q>6Za3&N8sV z<1rm8?eV&6(-#5?(}=-@g0?}6AQI^d%)H|Wq7;g;U>70ln_M2OOP}xGfN*~Ip|iME2~Qc(XFgVIO7it)ew z2kT?jE!Jh^r=je?`0LZJtsoQH*TFh^ySv-_JDI&vPAVN6l=mleK?jq^X7@5%olL(5 z^jjOEC?qK-h)rA&nPmFaMI&)A;yCBxJV@Hnaj{2IaQyK!fbz3=O+)R{)_B##=Jcyz z;_Fh?)(AqeGMe~wUv&SzTZhn%Re>8B96mTW5U-&H(5pBpsBGnERh+)J1|G8}UI=6% zWev3;_-2X&4vq`lwUw`uEDKW7V|spMLnsr#|-7 z3(o@-TtIF!#FX#QXNmMh9tXtxgyM*COkNzx^eg-cxX>Yh#WU26`4I4O4*@{pPmp3r zo+toZA&Upb$RO%}#QIAZ|JxshpK_Y-9C&Ov{rU=WY%stE_-c2pYzd-w4D8=IGh4O4AF921L%n_MT%|W@Gea*GFYcFIPuc-B{04G zy3#b=#VxrjiBNB2z3j_}!kJ2Cz-$g;5ICd?L-#N9|5L>N z8*6HT>*i@f{zQHH3Yg`(wWJzHHK_ZW^qp@__E#M=UG+RH2*ejsYi#O@V#TL_t*7cHYnM>o?(n`hOOAC$Xli&DJ9FO~}rZv?^T_ zAw#NiZ|v?(#;RMEwTx{a8yj1;XImTmK#I|0BE8(R4nnB2$i%e89CWEtS2A6l|6!_k zB?tqC7?#Gd$#hkIB;M5=Dw3mbN>^5p$8Jzt?vf9ksTrKoo3*n3qv{0l+-DA3_ufA+i6#PQXt&oemrrNUs7rv{A7jRk3{sE921>V%DfS79F|e(7uDW?mRGbV0aqV znne#lk-D1rJ`{dDACvA+KT8wbKn}%Xts$`l3oGR z0^0l~Tiz@$p5^ZhETwIa#oBw;vz!w#!=lo&Qq+jucQ4MI{Jadld+#Z z{~Q($Rq%O8|AM6<$*hTv+;wp9mP5k_hY#~-rkvo*cMpuh+-ys{rnbs?i6jmycVR70 z3qOZbxIKLMATPy#@s*R-xLgs-e;IyYfivQ1ao$V;C7u4z(e`vL1Pbc-CqJ{GF~KYv zrwxWfFq4p#0o_unYG%LFMk|M+1DEfvZ)ynJX+;V~p+Zy_mL3qTVuc9xKSDl4?B}eH z!q0q76IQwb41+4`Cm~Hg`6P<#4gTrm6*pkHX)Jvb%bJoR>I{OG7l$Z3#2wmuXy52v zJ8_73>pyU8fKt3v9gEp9GCl3X#A@nxw`WPLZVR4mdaAP=$j01(V}ml)w4Iy ztX+rqKG{_@u{2!|Ot_XC8wy}j_z6WXp;$>2ekPij$Cfy#ef3H;pIbURwr=U`+SW<+ zLzVnrQHBDi>PpS2D}aw7P2&RM6!ZTZiM^6+lw`5c?2*BA6FeqXqd`=WX;4s1zohAV z-}~M&_#Z00ohJ&(ut=yFLj4{q#fB^zWCxzh)b%4WmyI6 zxa{Y%l6brIU%6_?I|O^$X70KQcKN@YSBhKHQFA4)evH}6xT3!`ph4?;XNcxdRr(7{o7i)d_M@bKXScv(&5ZWbJ1 z8E)IwclNh;Y>M9RoHN<<2B(q|N?DI7uUyWg{(5gd4Eb-ESwTHX80*K5vDlU4AU>$Ni&$oms$HNq&oR;FnE-`dl4?N+vu#WU_H zkLa8^C0UANF??i>I~u`NHm9UUeQf^k5@J7T9VC~?poC2Hq_2eSCi0E;m>d?}r=Tn@ z1|A@Z-(tsjPDn+6C^EMWCnu^fWE^OZjH&$5&XlpWJZ%0MPgN70>D9o|3-Uw(60H(( z(p8p~?y>AbWfq+ZmAOe7uTDhJM;>A#0vOp=G$TEH^ISM{7|Ha1ADjQ*C-*^#^Al^+ z>!8QfoxV`dVCo3PS?U8W=tqwpC%m9Da^bdP3{qsSphZdtt$aFP~M*~l5e ze$DJayiTG>-8!6{rz+`!1E|&mXEJx>JaB5wLgrL^vUf{AG`i%RV%;Y_qGJ00He&ys z^;z;ZnTKhBx;bQ>eRJ)b0@rPHL!c<;e&(2 z2M+8T9Ua;&SqmVM0Ks4cTs&%I0IcbpJ=V;AQw8%` zMy^oLqvAqxIpN8v@-uN+dOfhl_(U3OlkjsY)ELh#Ajg}`fy}xGp_0W~498h?BTWAX zhOWPp)mHj;`A92Yyu%yR|KKhsA1C6z{EmW zSeTGAG3Azwi|f{tC$-?o90VBPjB)SDlb%?h)oTrSwDfzFT~s3Yp+l*Oi_#l`Q^w~n z$QoDM1*bU2-(ouGqfBw9UL2iQ}apDv^R+vEXa zeFhGvKEYetS3|d`FS}zK6ag;AI&fxjqb{>D&j?`tTZf|?(pSOK-m*<^I|(7pqejnmUL&pzv3W>;(BYP`yMb4P%L zh2T}5dIDQp|ERa^@J1nuiDBT0^6)BF|dBdi6ODvY>fAsF5L&Ll1$2+QwWs5`= zi)~MDhIgvk2AP&y8%0@F|CNjGOAYd??CBS@q8rx|L9XcD$aZNw|De+ z_4c@5HE~vS!oJFPE3)!^>}^GkDi2Ig?`zB>T?oY!m6cgRsuJca_W6~8lZwATGBm9~ z44O_l%3-{UDycCT+94|{kYrLBj|zs-{8IJiX~6hUU8*zww3lME4w5qXnEA3KD}o>~ zjAe^7A&QwTTeG}zOxc=2z~?v@vl~%8i6dX|AsIaig!lk8KNiFI-@*rf^XJ(g686>` z($`dwk14Z;vl`heQgCvSIJ|XvPy>>yh~znipMKONfx>xkKriWQV&Z?uF^&M|3zd8v3_g)rFEax zLjIe)gY19{JSEaMXq#%`CsU&%ch*!6)Zza-tE%V^9HeaBo$;!wMEd$b*qXFI?9J)x zU`9mQJCashIg+cY$-TLz=7m2RK78mPynS|Hc=yoVA|a1)0R3#&v(NrbPk*PYIa{xe z!N42-LxR@DVu|!NjXb{NQ@$^+#o&8>TY)^~%Yu1;4PTCnr~4yBdEw531E={UNUXR| zueci9)S)qEB+@%HpP;ly#Zg0jPt7eT z41gn%zR?IvT_x)n?kTaKHJbWp9TK# zf&DvYkv>Ux3)N)_RH*%yE$cg@i`$}$x3xdLb?fHQo$$hUl~i!n>PR$1+nb@Hno6)f zSYc;XeE6Nmk8>L&D8$%NT>O0B3zLsCi#2d3ZbDeq*$Sc=*UYS{e~u2zc!Yfu7j+(# zmcHTXZfa&R{*?1H9)0%iAN}atKl%1^V0Jru)~l_H^U}Pzaj@GDA3u(aNFhZAbsF zM~T8h`#-LfjAqgyCd_N<~Y1N{NW>>dGgDi|6NK5{29_CJJN#{B(pZ;d=?E0PTgVl zxr$-VjM_8%B+e5-665>%M$fYOM$qig<4pS&iX3$wW?r0G3_2Ilx_f|P`5>RW2r+R1 zLm<<{g_zr*Gt!^$^UkExc@j2RqCdEU8C3_ZL>_+kp%bS{ytnFV3Z;DEwVKW~0ar`P z28o^e%u~4oQLyKk*cQ-VOtm-R+^;j;r#X4_{}I^wHE2ONZDKjSRu)HCOV}llnyZsPrKsiE7C*o z41PYc^?m*=_2-UkkvGjIU*(GM2`BBqyrzHNv(3Eh_Kt&9L9m)2S$5b#v~y=MH=!21hr+r|W8KTEF#w z;#KZ7$QduMsHJ82z+M&rv2;dTMPq7;A~^yOXUp}{l6;o14T1FMC8G%I`<>^W`gUMD z%L2q~D5~GW5FpV1$EZ>ol_0MWImC*LDeA}>Nkf!{ zAp|oJfY4T?Y&oa^&o|ct`u}F8Sw6nf=Q6ZI*BM3d^IDG3g5w5gW%uLs)O-`7IT4_; z>+!fJMFYdR9?<`{u#yUJUiB>*_sdqK>Nq^j7>;)aM%J@4flg0!Y?hSN5rRIe+wWt-;_R^|NkR+{zv{OU)fW3|Dik6Z-NI0 zhYe30y$=b(&G(nb4vy@W#}1_oK9H%w_SRuL{OCr`Y+pWHpWatNzN_qrJHtl_ezFg- z|0Af=#XRZKXSj=aJ_Q2~_J*pA%X$4qzJ$~4r9#i9?1P^|c!@%&*`jD3G?>07thY}Z zaF_%<3?qxdYZ?SqwQuee&!~!e?4>uZRN^#`JCD!liheXdxuolVt)CP4E2q=D2ztk8}!Sl*3ojnC8Sy>suB=Y$({_DFWMQEVe?aZAe1^=Id|5@ES>JRgwgQU z=v_Cbt40;GiOKYEJ|vX`HFwtWC`~m)4w6mjgMj3fei1P$sf2``bjAVLl|?+mCCQu8 z2MR{z)3nELPVcWEAMx&ch|`?qKpmY2Fr2TlGijw0nX7%S!3mS9lq$}&$n+G2cg`Fl z#QqsN{VB(VW?XUyDl|g1+iY|1k9LjERS1UqilSYdGrnKWyFTrRX z6|=_4@~qN8>q+&Wz+(XVBw)_E|KY>wLlq=7e7bg%8h?5_$hXt5^JXY9p=5Z5b>Is( z1vul`Y;Gw@@qdpfm|ydO2L585(H1xXRA(Q=0DnXcLvVxgBBMg)_tw!|8pwsHc~ynJ z3t3h@@jmICsouiWBGCW0%F`=6Sa1x)d@<_9`mnMl!GPKK$yBh-pEFG=$ojdH0p`JX za2xabwGd2LVC0H{2&i~fC+Pp%yy2*rWSM>LspJHZQnVPO?I=5`^$U9AYtA=@$7s@i9(Gv&d*%Ze>!|Vn+ zqfio~t0}~{?|5HDdZdDU^}O=rvKk=)ZyraLFV)I8^NJztJl{D;y}Ra+lw$4d4E)-x zxgRg$a;)RCE+9}mPj8uU{r@-b5g9o(cO#<_;2r9}c%&wIYlPCVt zqpdUvHN>hpdTsh}1$k`QY`U=kd+b;c#~J&#EdT{>_XzN!^~2)ZLCPceuxorg>nOtl z&Wg@s%h*oY&h~F5ZmmwVv$##aOhYBVHAy;2$B*Olf7^ODvCo4;In6T;JaQm?CwzWk zXX#bGUQ9gX?{n)3Op#nr@$3i#?~62XD|2U?>$YB0di4 z8e8Mer6}-o-4~zWvdG`#@%c5Gw$gW%>18Jv*|<{?zJnRvCraWR5T;0_O5YgHSzsNI zJ--;O(k88{4q%pB%8_f_OlSr=;o_5@8t5JAmMTrHzM6RI-4FWz2pJ{zfOQA_oRX9q zN#6q>$u@6sfFb|%biP$PzA^Spw+e`k?cO!CbM%ng<$2;+V+iXr)?`$Jr+xoNdeV1S zkY|_pdfL;11<=xWA9-E+t_t#Sn{P`4y4tjRSHNUaKD8~;2*%jsn$3c-fZ~ozV(SWN zy6{(d{r{r(Fz4V(e2^(DPQSWcc9cfJ{MpU%4-5_kNLE-;0Pbz&8~Wc_S5rCUomrD& zSa=_3IJ`e9gq1w{D8?9_8eRpu;rJOO0E%mp?7-X#rZL6`l?N03UgxR6@a|rn_S3=( zmCc)EqEwq$HgD{il{#@~^4zDZc?13blY)JmZYDUx=BJ7CH*d2@_bj4zzAqFe9PzXI z%8)s5u!6yZW<`-a*;m`=SYNRou{Kz*C;v(Q znmi0eLZ?-kiz8%6>c{G_u|4sXEp;bOJn|h?38q(2VQkL4DnjJX{U{L4zWCZGRLORStfiS(1Qpy<%?qx{ zyc|T=(ooid=00-*lhW*;RRcj>8!e`diOkD1!!tH^lLKFs2fjUXAyj^jQu*?_=4aTS(+Yvz_tt=p`XaI*wy zUFHhCt!NYqY3tg|<$xlh$ax?N1Gg^IxfMu+i@;ISwV7BUB)Hxhl!bLzGP49QEH*U4 zb@D&`Ay_X*Xue#%9ebSxDPtWRNi;8#SS$~c*36|5B70kEbA5u1u{~qU92%$%ZOgnN zLhcJ}g{#KY-pSDGGOq{v6~TA3(j|l@s5sS6l z=@J0o+<`zA#hx}|UFLN`WC(Z%qX|WO=Cvj=R<@*0G`E-?-m*P)wYBjT^pBF!o_UQg z4u~9?@AStIrq&L6g+uu9!truFr9hym^9h1z|13xqs2~u>Srl_Te7&>@e zrVfy3A~uHhh9xQmkQJS560x|UUjT!P1#!6;s&NFviQ$@B>ut-PI)5^@kA0s@dP|EV z>+3SByln|aqN__yW@UuPuMweG)p3b-6?7}pjAUkofov8q(4J!-#l$QyfW>Chx_e7x zYBYa}qD;XZ9R9HJ%yL6m7hGRFQ=Jb6JDHjh9ty@YRYsVqfOfTKDh+Z0LNQ^A_CO@I zO)uNC0vrHqx})>Uf^e+w>~HVbBuSPDM>4b2)Jfkz(bdyYyQOn;XHP$PlKx)TmptqG zk~P$qT>c}}{|m`V68TEx0f_(4v!Agi?QQmJt)E)&v-Vi^Fd+RR8G!;cB{S>wDp{kR z{^|42|Jcb+)2LHYj9*m$qI&y|v1QhDY^;B5Y*VHKkjNYFSDTP95X9Bu4gfS%$xJec zo~IG-(`I^>?U;6)`ie|@gbc{G6TzAU_c31QCi}K{f2=mME<*O|$RsW~o8NeLxsV9#=JI zTJ&M)SNCv(546(c8hm=n?0jRUS(|VgoBRgzG0jaFaJW!o;3eQfk^;78nt*IIjG3e% z3OkOq05}$RlIm}mv2M*Y>VcdDOaV18yvFLM@&5&+fkZwJ{=dooo&8xD{kPj^Szom# zVDxX1&yzdgwvyIm`haNJx3=zqu__JOS_a1UHuP=~&1IvcmKGQ)j_s)(t8zlGWM+%j zUH&Mb`8524MxfV{kz88@5)UQUc#t@wXVE61+LV$N(QR!lElP6|nO;?LS%7yN6Yf8N zpeW{KMQxo^0CZ(-rUwX6hBZvkrqOWmtRuF{+(DaTz}93o0|sUGfrFWpPJ}4a+yW*t z-75KxK?VXiB2hn3ppc))T?-TG))%Y?txk9n@O|>uVnzUo z%%I9&uw&h0(T$sWPdtD5*!CSe`dzgGU%vw`f8#O8;N?VSR{*S2h))T6U|-kmdwrwxkGYy8dxU;b9!?f(ALaNs_{n9&J7xGpwqoUWMZr-vqK$X z0kFzcBVfx|ZRSQbgwX)Km4Ui!*V(#_cjpgzze!yJVoDQ=dvoTEs$U(8eg`KHn`>oi znT$tQFyq7Yq&{l_oP=HT8GgpX3Ey)^PXd@m&1{A~AR_HvYewM7|n%IFhvgU_WJ#*>Rg#pR>lS zD=nKmLw1m>75DFVazW-$gk0frePz!r8Tj_f_*VB)H8e_nz*LD>M56b_nJF`JJ4`$8 z#ZRZh6R7DAO;`2y^^NSSt7^{Nri$3VRgYx=fg+KL68#=VBM`ETwPc1>792cRM9OpGNn_`xvQ`~xXHV^r_KLhaZQK=(AIy9bfLm%>ye)em0R)xW8CYd;|Q z)Az|pstlH3VytOwW#-lhkvIGptG?f-35;FI%$q#5;<&!R;V*pSUh!PiV)FK@r2A0b zp1CCm#|{Of%26;(*qFpvduDGSj{Nv}K0W=~S2aJkZ#RL}s^c znuVv$XPTM+-%cW5io7LqL!>4WvA=D<7b1YyS>LlBwpLq&e3d*-w)-i4!1boAt!T&Q z_I{kx*tn(lICBlAW4xZUt;oWxgESy_0O`|L@if+bgSRb_h3DSVQ+s21_Vo5U_*j)M z?1104MCJhn79V&kPr#KE)mm-L;FIrHxaO_BXMOBTT|NCS1`chyMjx(2eM@53ZOY)I zZ)r*dF?IFzEcIgIP_Zw5w1yQylAZs6YGVc-W9vk<8;Rmj4yvW%oDsD#1G_X7h)JS_ zV*{F6GIuK`7F)+}gR$XE5|_FfL97tfb=NJ=+!Y}^R2Ij;O?Y9jcwOdBpooN^;I;QGp z)zvRfuZ5YNmJprJ2K>7m06JQl^nOx`Ot4 zC09Fq_>gy7e|KF!+o{1lr@2H{eKah+;iZ+NrwWcu*~O}EU$?1q3oNf$8jCIGM-Wjs zm9Mb8d>!&vWEVw-|v{tE~unzCoXW{%RzE5v~MI;X!NnsZuzi1sJ4uwu>Y!yH$p{>YAy`mn6JYR$hi z^aWkS^qmoB0dpJk|Lyqve=>4y0DSDrOJXu3g)*cI_qO);NS*j)_>iwh1Q!;ZUD_y=?SM-~i3R zIaEvb64{}6p{mERKBqS2$@RLd`q0+^+uqZTt3`ZKB(wO?*EJ~y6hLwko4wYI1lp0z z;#1#zNGR|8ku+rCv9G&4k`kgcomLOwx%%`znY~!4n=@*>vexM|FA|5BfRIn&W?!Ws zf#reE!XnOCX9qnvC+4fXNUSak%eUNhGcfdbW*nXBepW3EJ9i@8y(_b@e#;%RFrXlS z`Yf#Davw)j|E&5qC!VHN1w*|&Kh!Gb=LB&(Te7f{%bg3N9*$Ned#mafC2#ec6W>JV z_}<=@?1g4fL8SsWJYSS zL8p081|Ts>0?Pouj*y8gJgb#z9UuSa_klfQBmD94|9%ibd94T_)jDxO79QFjy-Wm> zShj1!c>g#xmQUa*q#rQ$z%hDwWa!WfV?&2V_@#Zr2YD8Mug;&K)K$|kU%>;TXE1%O zy84Gd{NeVSp4t7(Gt)1?O({iJ)Z!UDE53?eeep#`mNni+Gg8seS&Kp{Y+)VIo>d<~ zLpj=uu@6FWxGFNxC&GqET@uYMjgXBpQ#;Y$J6%HidtFvt_=VL}N`6$Dq{Bpw*FA4|a81+axg7MCl>}9fIjgPnWwD)h_(%vm-rS=Xvg(S#Jl`hN1 zB4o4MLgwCdN0!X0tGc`%0bPOW0Ua(eS9q)mU13zVH%1(;Cj|iNKv!pB8CQY+7l`5D z%>Q?i$TN|tNDsUP@QnS4owQ$S{lNNTm;r1he;{9m)xYqauz<8C+op8TlMwQOfVNIg z=QXvJVEMXx6ItcSFN6O*lX2N@zF0k7y%tP&O9CwzhfT<4!50=t;o!|KEIjaaO-e8< zjB7XwMl(F}^?`jv=sbmhhdR}3WtuO~Hpvszyj}^6vZWylPj+4RZYYLL@?dYs!pf_> zV9-O32>z@xb^$ye$+gnZ=b>ZXm;`+;&yR)~%bXe}kIi@wHD+S5Ked zNN7vfWO1#PtKtrlc80`*fHqn~fD5ex5ZtWE5pYdGkj&yDD^D|`V*`fA0hSG6|xziDDL4sRb5^EZ%;GQ{~i-ngTBraFyw>9 zR_?fqLe)*@hhzG`nnb=Gc~@k2ByRtg{WW{S-e6nS=dHV~7V=y2DOmrr+NAvrS$OoT z%NZ)IS?f_yu^nr&R~fp>53btV*K4!*=+}K>&V)rl(B=wv^>g3(4~J!fTWhnM3c*la zZNPv}fP-mRA{5M}p(TNa3wvyB79Rl{F}$0_r;<4^>UlDY&wq811wK42bpSVY5Slx- z2>Pe`#Ls@?n9pQZUDCyw3G+rsn1vNw znr=>q(9Km@SiLo*H;Y#VreOL6)WxkB%G9bXtl0{J@X&_(e*x(rkuOH>i?rCkwm%GW z|Chn)-;Y{*t>xr@laG@J;C4_-WZ~(qmLE=kzgKE3)u>cff6;1Bk1>+}`^E z1*S@~CVM>yi(=-tb#-1BKGJB(!ZTlYc*gr3ZPs-4(@_116C$!;Dg&38-AZJ)DeYuI z4uEjbuj!!M1#B{_KJb<6{W%KuyS3q(qwu_Qso`wN_WRL};TD)zod8jPBHQOjyALQ_ zcG|r*i)*!vh6>izJUtEklB}&MAX%5ig<4(}r=G%y0YqDkm^Ni`nU?#6L}s8E&HI_D z6DOGMV*z6_+Y6`+W>fZC{-`(-T(wms5^grvWYvXR#zqM}V4PJXVr{k?sPO3;!yE_7 zh{{*g|Cd-_A(8J!-X6Ira+&>e`w4p#=KuZx7t3iOaG)g%kAGd029{vj6(rfsd`q+b z)v-iYS)-+ZR!wsQ2aEkBOO9CjI;&&N*x=JKfj zi^wu!cf%XMU$*Xpi2v8*Nw}b<@pH4V*kt1M+*4n^dtel&_}NmN_|n#Ryd_>!E1hen zaab{{+|OHHEnao}_%m@lz;=}V(Zz`@EL(B=Q{@bt1--wK%&IF`bYPf%lXztaTv|bf zlUZEB;@W=+2|84q!{bPt0bB2e4bgoEM^QHLe_#7`fCQJYghKMO>OXKw08w9OKO4)m z_W=@I!{SB4ZGc3Hge0L3ACp;J#1ayTUody1Hai4c{k!oeV@fQxW5@g7N7FlYNPG&+ z?$|LteysA?^s#ANJsq5`61V>#C%7t~(mYP_jgR+N<2q2DI5eDxs8h5gRA~oy;S{zw zkIumeI{^TlJ+2O-++5jxQUvfWfJWh|&IeD0#Jwez1N8k}(WRdk7_*o!nqAfcN z)A{1{EJhO~0Zi_D70vkH6@4P+=S(ta)KCt7Np+jIf`#QmP zF75;C2~R@~%1=W)G>2ecyi}y?94i&x!dNmsnuR5qN5n%y!4lWQ1v;=66a*}xx-Heq zi9(W})JxRV%3f65<@1m@7dbO%@Y<3iMgMP;4-oq~ILy;@bY&LS5kD%T8mDgp`-63c z%qb=M&|&ArO}XReC4r}kod;lfH`k}a>U1C{mS%4Q19z9%DTpy6-|xRE%Dk!T}w0m)K;&kuWbhN z3|FdP5h-2McL100!D6q5EUe@d16zGL6+%Btv^k=r|AkFJltTTfD8ZZiSVU57{R+Bv%KfPyYc_YjNM;KjZdCLf;${zQlO?nkv} z#7s{!00KXYut(S_9w)l8hbqWJ7jtH~?jR4FD$$$fDHGhvLRlHUQFB!<>c3_EBZ0qi zIxRVH^tIVBh@KK$U6$udQHU`Q?j0JbtXjT23Ytqd`vbj!v)c~A48|TbXmCbTbmaE^ z`$mU$;z}u4A%!qJH8jLq>ez{)6wHN;jKX7e7uE8H2B<=+ykqN@EwG8j&i<~=oqhf7 zo3B}}6=2i>3JHl*yHhczMfuh1S-6d?14jgHk2)?!Y31_eb^P{TF4+6mZ`rb8Ix4Nv zW%|F4SnGJ1@^2v=cxZJNKAHVy5h`e1P{3&^q|&QYL7G?JP+QkhSKri>070p5X=tj4 zzxw8errPF)`gn6wOI4H=63@>L1QHm9E}8 z+3W%wonl!q1=`A_4PGPjg9q<1}o@e0d72WWtb zeUbGO>+NtlJ85EB7T%aU+Q(f{Lql}~O*IWTZ^af#weh(Gz7Z%EI>cdD zOc-MvV($$(BM1KCjq$f7d$07=ih(4!ibIzm@I)5g^b^lzR){XFU6H7P z|6&l->Wq{eTx)CFYGTW>@T%Wd-uo+}qlfk#sBDFuQUnwNA;iSS?42+Icm*%3C`Lgi zr7*g@!nuuixTY5v3ZVYm5rBGxG0|laYUn{C(s( zSP}Sj*cIT5k-v(3BJ$D52P5x{JRV6$9*s=EmjcEjw?*Cr?+e@%xjwQb(jD1g|E>K4 z*g51G`^)y{?a$bMVgDJtNBD00?e-MxC;G7cpnW&2Dm-Z4V(+qVg#AUYv9Ge%+iUC= zyUwn$m)cSLwf05!`Sv2)w*DLT9{bnZC~)}LD+hFwYD zWxdtPT5qTQ9fHWwvkeO^>$#Cw4sE496QEZ-V3Y z$6*hI#Wy?-dmt{p{_%P^UiWw%9Jf6lhvU}AtKr!H`0L@=_xJ^H+;Z%GI9_|~b~s*h zY&RTxk8OqHv!)Kiv0`czj*+PmINDQ(U}e^S zPXV4qzndC{PFznB_?|&>fX+qV$-&!oi@u!$+7^8)cN-kPnL`@Bkwg4n&mqpg$-#SKi=N2=_ZFSV zt%Bq6TooL@mU|r>znTLsFZxRE95{X{2ZFcguXBk13pvtZ{>4K=b0nF`#*I%P|{{&Bst<;!_X6@rtSYpstT);rgPFX0X?u$Y5Xm zSq6FXkqq+o!x@mDMIXvQ?TbE`xfqUrnmHSef1C!XSoA;A$l-UUvAu6kgA6P>mPR~N zX=wH0o?{yzpGzap(`n@SWcp2Td^nB0|4FW~L*b%^N^Jc9BC&hOi)ahZkTlVki@*%h^5Uigg01CBh&#g>)LTl0h{{KS zgZog%(kPUjQUg_?e9O`td<5;SV%<$)BeP)f4>4C#wyy=*SBLaY8-g-n zWd`X(gnW+?z$CRaG&D6gG}JcNH`gW_8{!+A!xq9L`vtttH`F%4a=66)od;lZQ|UsBcQavWe{ud@=plETV8dPh#d*CH1)827 zs55=~y6>9q_MRFb#*6ybg(pT84n~e2KXOZM5v-LEOK~L8FPnY-xPBh5Gb_Z*q5fY$ zmg4t6vytA&`S!={19qMDE7tk?n!SHe|lE8I+cC4ZB~u?!}4U6aF&bH&OyKoYHv*T7qi0+zmD zBdt@5jt-9w?1vKcgUqotxmSA-&~@lx5hQXKON-pr#nI5nuqLYcwL}iSbS@Uit&7*l zi`-YE#Sw%fNKC$z%)Jr_7cc1pFfKg{YB^x&^|byXwe^9lGazWm!DhN*I}9KKHw|`P zfKvMZJy7#9!T46#9(--?jk%WrhAYudF}cczAqc4#{hHi` zI&-AP>2hUY&YIi>VG+=Gp!VMd-8U+6urdc*>x)%t>*A(5aR+yBp2^&KP?swX;XLnO zJpaWfE**LP`501P6GQz!A3pFCIS%`OwMWjf|JuIaPQbJG_gI70GV)XMMcat4UFM)~~?Q$)DOt%hi| zX1Dwh@au>uk%NtHCACF@!s1Eft_Tea-~8Cx4cpT4x|2EF`qu4ZYIyaEC7S_&UlhO` z$(9^`_Pk1EXD||%0**xgP3G`Z=mk;cMY=YJ`{qgp!Nga!c?=0{3zC$~DW5`To+)qJ zdQtjgTX>riIoLzj+q<#2B)7b*{+r0b{`Wd;{7OYsO)Wq?8*=y^bX`1G6fWn@IoJSsBjSD(Hv}PJJDHkzDTq?#O39}zxuQ) znOosCMR~i<^}m!+$y`lANTSdHupsy%Gj-w=$xv=NAnDD|th{aYvPX0^uxn$k8tTdC zYGnw&JnH`hkG<|_0B$ZWKFb?{b$z+7I#d-l!e8LQ|pc(1#$h`>EbOc(sQjK&~9~3IWO7IujBxDI)PyX@!C`nOhr-B+P`$jkz^|L>g1mS((*_ z2a)hWYu|10c&w%>2> zvsYRFZhgesZB>$gBJU>G3+*o;(~;`~;>7Bfb@Bg)j|F5)K|fR&MGm<+@G0U1?zAU! zxb?KuW1+Bkkl^mq;gCq6O7FENa@Q#Kf)XMNG5hEmHi!0l8|!^|nt~HG%7)VpFJxf$ z(MAuj`iMl?aC%*Q>Mf}sJ@=(=e>;!JC^EPvw;5O=&z+7QipL>}%Y#IGS+F_Rtq(K} zQ>XB0Nd^G|josKEt%)_~;A0W$5H$~EJAfkOnw;{z2pXaoKt+EEVtLhTa`?Rnwbelg zkml%~!~6H|8M*7=ASg*s4nG&MMDtv-Fq=)7!h1j}&XYO(dW0mB)Z`Y3Fqy*-NECr& zvqTB{|HUMV`k#U~d0uV*J$(K5K5GOn(KOMUyAc-3UdG$r4I56ub|Y2GGymgnKlnoC z1u5%yofg?YAQxqqyb&*6nH{X=y5MTYMA^U~>4e$B8sk5)6{Tk;ASjbo< z%(ugzlUP6b9(l*PyJU%N2Jz)tSgO$??HmUiWDOraD0ZD3j_!g_t?RhItY64;P6>q% zx6_4?&ez-P@$2o;9DF%Kd_K&?hsB8;d>}$hugMQfxXIeW{H^niO{Vj(p;~Aw4<1TWXk4ASn~KH*?C0_Vb`HKWAmoGwqLsCEH7n}tmdBgn&wV@#h7JJXC^D%3 zXOSFY>8z05iZ*||;dX3lN$n>ow~IE_s}Ld{!z4Xz1lf9expI-~Sc1htszTbdhN zV8fW&y2j>~#>Tql`i3{MrD*>^-{{VN2kN5x_8uH&OVC=MeRlBg;B#-cqLM>MH!wI{6CaLN z!5f--lD4`$Ztb$xre=$KL=yxhV%9;|PQ5j~PNgRFy*=sQ(do#BYDi`jgO4`dzV;a}!%~ zuzl@ARVt%|nF2kH?g2&F_m143JL$cT58XB5r>{&WqqQy74fXYKBI$j8LA#DBYmnYX z_a1`%Du+gJwRG#VTm@DAW%TYnxbs$^Q{J8SxR5$zu%@thsg5eF(O@VQdsW(_xX~Q! zc6(GjfKwEgswwB{{NZLPxQJGdaWMpsnscy0e6Vr*=x;y%F~|1LBjeWJp6u>aeMJe3 zTijL4e13uH{}N*Vy>%&B;=+mC_}w|!KK6(RFI4$^$UmWDj_!GT>YZ_)(;I&jN@}0;UCA9Fi+(KKHMNFl$Y450{Y|GMxtmXUGN}v-NXQtfP}e5& z*(>0v|27!|{fEOTOGkI*U<1d;y0lP%j<9fSf}=O>*KkQI(praWv-$K4VqjyP{E)^9 zHS8XO^5381>dk!2L$;Uk93YU5y;^T^pgh0D)~3UmJ7*%AgT0weq0>{i_)P?)1)IrJ zmFMf6p!Rm8Kv5u0#u+dOMUE{6NEg;B3^o>n8FQwH zi76QAXmJdq*{5Ea=G+5eV1ZptY+h5QId{Jw?BRoA{g~TcI@9RTT${U3`r5S2XV}Bt z01G;w$ic?H=4Ki}l&;Ca&c8ZrEp%(+QXq)7$)!^UgnC)dmH7^uT@(_Am=|Ak}= z&i|+3`QNKxAHNU4E`4>d2j5e$zh2Thn|z(5p+M-An1c61bQwa^P`5O;j43iW3q=4V z)9`XLY;^Rl+lGeW%M&ZWswl9MdcUktSgGC%3xai+VWHPcOkEHT7J!;y1iF+Esa|;7 z!^A7m-YRS`k7>{-NU-PSfkg}K2YYUzu*7mqQvK9RBSd^BPc}(TAHlPqWp2IDZ;VUw z%b9thurATF^;3%rsnMY`F}292jkg~j#*YkEEstG@WmRcx!rn z31DLCGDGdFz-O$iZCoXNYD6Z!y`#UYw+HwfD;(BQf##_t(i2)PQKH^Mbo+SRE=Q`D zDNkZ58dR$vB#k2y|DU}#0gUS^4~5UYqmYc_Y=l6)k$jKkJ2Us5^PTT}`&sXTxK+edYeTe2X+RTYPwwP`xK+ft ztZ~a3$N4RGI7c_(s~@y_uia!{7IueNtjx8hvJDPp-(*u3BLd*ARBszmV)I2@5S_g8~T5<{(nZAmYT`GldqCfWSfKg z-?o5j(6vngtj+jJB9W=IB8*39OoFwlKRT2;FadE3^3nRM(Q?HF)!jm=#B_mOsq2l| zl#N8T&|ZkOxY2z^ZOS?nG}YU(aIMw!BvjL*DTSy|-$b?pl;pxDORbw+OR5E-cw(U; zL`)NSp2{W{>TN1*NW`1Bz<-GC*&7WZFmG%&Fb+I$a-q&zwplGJ6t|S6?5TAq3w1{0 z{7s71dTH4jYuPyJAw1Lsz<{lGH@Q&lP*xKFb3wM`iq^Z)Z&?5e1!-Avlc=iy6lci7 z%nsx-R}DR@+Aji~ud&t}+oE--^-@d|w3g6%ueK?xdBS5;;l65c#CjVO=8*>=5wEwywO;1Dby6E~-tJhIi88puB%Io1RwBxv zZH{Ht_e&e&6e>;}=dJc-^*80Y)Vsx|Y<)vpysoVU|3n69RDv%Q=glr z&Tn2wgvd7IxJMKRvS&$0Z?E#Eh2{{^_Gak*l|9|I09)AnxL;gqh>KUz1H<<^>i@&! z>n8s%-37N+Lps&604v((O8qQEO|Qt(#R~Ro~P>plQ7I)mL9tfwB)4@2I!bmA#y*ubz76 zLN83Lb{JW|EYwA;U7F$YsHiPWF2It1Q@3vgTYQNq@2rcaK{ zVh!yc#N~FF&n_t=$L6Mm8ilVcyA5WlJ{1Dq5vKZpu1`{@gYZ@bwAMRj>>ZTF;e%SM zC>9lih+p{>=t2#=$)4L8a&Ft#tpk&;CROa%hpT0O_0S&L z!qvaw4cHV?uTB>Z%`QbV82^Vzl!UI6{tZ6zrgZDV?ke&LZD$0FNb-6uv%mFc7TRpY zarsgZn`lTh$Kx$6&B>-jqPZ#2+?a$H+%~r)qv*{2$c4Te0K@}2Xa(4&(zMYKx$qXj zi4Q+~Xx9R4O3Z3UNCbRD#V(kSK++$)w`KvhXf9}nca@N&umpa28buWfkbV&rUU#}> z6v6{S-0Wm-3uZ^DTXfc%j#bSyTVu#uL_2Vv1kq^TFJQjOa@8YS>P*zmVgUgK3pm)- zE$rZ~8(h3Y_`&@@xHe4G|AP(qD^3D8L<3c{aG2iE*-X1kfdRGaGbz6Mlh$}WFt-?w zI+&2%|2hFm8Eg^YsO@D z4fGEU4|eqQ5Bt$Xn*m=Id3hO%wuTO_@=;2i7Xw3Q=dA_z&XK*A1->}v;?X}L{^EZ& z{`WZ&3QG@>&*@Mq^V{RS3vjI1Z@k6loZ0fmO3I+-&{=Xtjek+I9jQi2%Cw)2v-$6q#m$6=ScHpf`V=-M_ z`KsaCQEj0~o_WYp1}AY0sVLLX&zE|%d~GmJUm+A2N$;|`(vzW;p>B?YcUo}o9NBAG zN)rEr|Nlu5BDAw;_B@y^VXGXMH}1SrqnE2DP7vLVs{_?-F<;Z_$L0q9ACDw+U-D<| zKm?tnU|K`%_O0^ye>VR22$BCpzJWZlvZH>dyBGGtduL5YB>G)jNaH1T8b7{0@_Q3% z0EKJvSfZXwT>kH|2)D0n0fv}D^i#O0sj$X9xT$@2G({j!)fA)wfLDv+1eQTGMCo=IIu&1?GLfHE zj4TF9GsW@GDr(8gS|dXqB&uk_fgazymYCL(Uu;*U(I_jsY+OBfSH{FutC&n;mdX6> znk0kr`3RpJtyKwZD0MD71_yRq%%%b1MGw`W7|Vifi!#bK(UD?kxUqB%zq} zcGBnx%>1PbH$tpc=Q*^~UyVVzE(~=tCFo2I?@OinaYwH3?hGa&o-)&{zy}2eO%BZ& ze~nM7FYDoZg6)E?rBC*C(4!OK!s93!L0!YJz^hP>XEiY4^ytD3(0jSgGg(aAO)OF- zMw1oSk8w~$-LJB}G|My-YLAWiB0F^u!Yg1=exKzSy4wL)bq#tELdWLRbqo7o+xDAE z!e*U(VpF_z8o1p0i~pJa|BA?eBYl_r%9H-Dp-iWCFTmT)PG94hnT41#YC<&Yv^;x6 zVX=!~j|>6|<{4ivR$=D35W>N`lxSM651<1QK$e?UA6bk}LG*8i#emL!loC)AKEtn} zrHxB9O#c-kzen1~-}xsh_h|75blV1IVS|vLTVZ2;8Ll5!w|Z38iE%%&$eL!-tBZ|f62+lkSUyAw7j3< zYLI1b#vC5r%}Hj6qKsB+Zs8qp0I=y?QI`Qco#j58;4`~fz$&Qtl478DW4tAitjBAM z8tZzXJLqYVad&d+qgMeh$CjO127FkUtEhhyy`!^M}CQ;Rjx9eU4wLNkmvSTs7c9DbS=Tbn`$pwvUXc03}>MK zmtpE({%5!ZDWE`+DDd8k7vLqr3x&iAZeze`5}a+atHv_N4D;RpcmBKucro!A@9RvK z?Nut*|0BEgQFkP-ePf65&DJzc58^jHS4r7b2x=;x5yhjR3=HltPRj9d0C7G7f$DA6 zso}}HancEy5uQi`7u70gdG~_l0fHP+mYEc{zn{E*bdp-pwbX0 z)eEnG)%r7zq$vqQO4A}gB79b{+7Dq$ZfcSD1yoYf_@9pdksc!LfXi~yNrK|)9|$mRUoj9=7wY2Hm8WaRalqT)Vpv}Rm6X^oqh^*qvHd^Sk`Krlx0cYq4N)OKPm)+nSy^j}XKsMgNIWvN? zueHERN~($P?^rloMLv3N8Af*@82^{Y?pQcfMLy#Fjn+CP{b~_Z_fPQum#ZTFcNQ95 zqgKt*#4-hUegivi{SCijR&wz|(ZE!ZeK>|1yE>c1BH2$-6@-di2!kHqQ2ANb%_=@i z1iF{rVftryz-+r1%|MlW%8Ji*uS;|LwY01X9#NGvesPcKS^WPBk^i6ckK`5iysPl( z`~?fQ!&Z;Cc?;h3U4R06dxnr%z+gCENE_76_gpQ3Vr3}5OIKJ1(VU@+pDkoKwTM-x z)HT=D)fx7DYkNJ#99_!X%=jdn3#}g~vk{Mg7)s@;;gut4S%tLv?i>eY>0E_1h6jb=NSXQr8|BK+w)()S3_SFkT9I@Z9{8^1A?n zp#Dqpa|Hf^6i{IGQUDIBnE=i9cu-C8EIqSbbTz4F>HXV$FpL(V zY9CfYaCH2wF`Ce#$_uj0k(`dKTa!v{073tkXu!^+aUHEyD&VUWZCwZi4tVI|>*cKa zP)gxhc5g{_w?Vhd+$Dga2wenp_UiY%m}|4O(cu`y1Or~2*%qKzp6T?`V7-AtQ;M%Y zYcfa-=&KwS-om-OQLNSCe^~#Ykg#NQ{b#X3HXBXdlIYgOXg<+&meR{wFw#+4Eple+ zf2>lpbpa4KP<;2|!0*!OWZ?f@Cemy)JMjNvs91ajSd;Xnub{N2m096!M9!QANQ6Ch z%lqGahAsN|za-TV_zRL71+u#qW~#_%E-mi}{7Q_l1uA%!%zs1dPuTjuCL%St34icR zq`>{%3$w8H&*S?e3YlBbqs`@XH`tqx>FBOUB#PlzO!2;@DaOGjd#`B0BkzhMAu9JZ zer2f%-;Lwbla{2#20RQuRFVlTwkM*2&>|a{M2PI+Pb&$Sde8mkPkiaPYvKUyuR{ zl$`?e_beQP_x|3y_6(o7+wRQTZiOtw7vMk7u6`oo8nA=y$u#T${GIuz-#=kxm$6`q$WGd<$)pOH~c7S{0{0nyvioXL<$tAI5g714PVf`OvN9(MU7_y1}&g3|z@2#MG#1JH0pK70_X2Tv3ta-rk5;Zp;Asf4*~1a#bo| zL2Bo}R}sVvJm%0NHwQ^t(Xh(5CpxQQ1|0IkLkuv1;l;FK0kCgQ1-_E`%76}QFlL~- zn73V!i{nRv3%muU{yk)#;gzC2=9I$Ez<4N9{9B9&*QMAAl^R;ZQSc7Xn0;*IH*EX+Y98_YHaQ7n(T{6w*! z|F88v^|?~3l+Z%u9SSXpf#Nhp4D@-fV1<(5ZAf0Yqvhd&mno)Nkqye0QzCljkud^2+zt-*pl-T zV*mB<|MftQ<@RC(+XB#>Wpt%`d7>)WdZ1OYn1wowRX1^wm-fr_{&{3j^nXl7;VRex zKci-XUC8sb{AR8sh0!Q4t5=1ZR`f_Bk%PmI%^{mH& z31PhVFj#LZ%r*y6u=oOmwc;l`K>x3BA+z?#k=}vnR>xgAtBnM~_z9Aw*LikEo5c@6 zR@iK>`c4Jt{~JXbs(y$IvuTo+33CA+TJ_t;upgo6<1k(|Ld16UcHuR{>gkK4_4VxS zR<)DzLL)~K8SSwLCocpBUMkk}IHFL&Tngs@zz7BNe_oGLqYfZ{FjHeX65D3?g01OZ zW*^J3Z=qLagUN~qXQea`lwo{C-f{l#>x97HDokIxa^XZ3`MX`ggduGE^}A4sdM-z& z<=b!Cc8=9WnZ<}BjlrWs=X#a3X+`@F5c^*S|KC!y({aVnyhI%dqY$8V^WTHeBQ`JJ zR*!-dOPEA9>YmfDby*`*6Qy*{6+j};|F?S40yR(Zl;N!EWd$cJ@eowECq<3K^O~$> z_AK(mHpQ~MJ~R=s7DE|9|KH}o35N)4rHxizRvSZv3T;J^IK9TblMgBtLm8MNoK>DF z82^JVL@@qW7|45zp-k!krt=%Kj~)#{(`hdDe&>Cg}bWAH!lbV zNrORB+Ebxn)$AO^{%?l=Y>I$S>d;>f_M7E2jqDl6i49rI_Sm5ls73T!ur#lmk4p02 zdA9dM!)#rOV{c&jcvD&$x)Aqrer*9$L_-FA^WB8sOET ze>OeSvDZqMmvQJGw2>O2&P%n_jn*~Lx99!b7c!37! z=H5Yjka&SL)(1xHJSm2}4rjS&MpfvbRj@aWI!J*ZZz|XTci}m@w4@xKm_7icaeNyb zwW(#rN{gMi>vkfE8Y_W|7Y4hy>l=3|#dOYNY~q=k0^a2(+L~r1vbQ?6StYR6{|Dh7 z5Z?byeoF9fZKfyIE!`0+uTd;({D zUPkfrK%XeEtyJpC>7xY;C?ff|OL69z+~$NR7n)_$>+i>23ID~ z|7!l-{j;(Z&U9vJo(^weH1f#^@Bv)rDoLE&xoUpu$mRSBr$;OCnr9iQ-7pR7BkHtsAjMzUVD!?xKJkl z7>Hbji(DDR%{tPDQd`itTG>Wnxgqe`>nyBcnmqyiuh)LKeQ~rnM!d_Upb@&XO0Ho50T_m#M zWf44&3prcdyoU9eqaVp1x$5c^SeRn58uWit-j!@C(@|N??6%6i+Z{)p;3~#Kk+VIv zYQw4gV)RCr=}0x_xdt33=>N4$y&Zjjg$A}kcrNUC3Y@2~*m#8mc9~YiR{u(FVL<<* zZmvmx7C5QZX(x3Kdimza<-o$MyoD)2Pb`@KZIuV5D+Mojr3RFsXt~t{DoE398 za@mjNTXpmQbp5~FO5{(%B}f4UJW}AX0}J<6k&pCvUXCxSny>G(5TeGPi7lLjH^ZJ8 zD?@#A<=*!}$>C^zO6O#Nur=_%@vLd^3N3Wv9P}mjUQc(VBlC3VAHVsZ;w}DKk?!rIk3LOwe@qs+nVxq~oz7zJ9P zF|QKzNU7SHwpPfCtGL*Ud$J55TBg2U4rW|<|<9La5ErymRP%0VCi&W zb^GQh$UN34`ivpPru@~G)b}sdq{?K#jBL>@0)AW3m<{6pM4@x4%x*Y)o|5v;!Bqy9 z3{P{?0|ti;;wvh5LCls6;NJ?QCnnRRihOl{Fs$3vO-;UL^tnQ< zy5lQ!yXoay9@|>1H8oyP(epSWRj5DnGE7kZXc=PvCOZEo{fLCFg-eju6b0r7(lQ*G zb(II>x>0lFdAkmV?uF)S#nqT<+^ShHhdu}b5^BROT~_O7DQi5Y3XAyfKieRyBjV5` zc3jq}zO+qfv$BhYC~)3qB+}QhG*KNB^P&ES$Yn%|kbi^^mQL+Up98II%-_o1 zp1vM_6ni8xl~f#FF?}J7KeTu)uF_TG>t$+okk##u3R(kUzfh1iag}ueIx}%{lybe6V-|bxDr&} zhtW0Yty4KBf+mug;sJ{dQ03NG%94wl45zA{{J$qZ!Sw&jM81#wihQ|v`d@NLo$1$B zkyGJ3CSt2fVvB``K@>>y_ogp_(DS}LP&P#Vk3koA^b8I6^mh&O*;TEQecfOE?9(rO z_36+27L545Sf)6E)qbTqs(cmuxlEZ-VbTu-wJ#MJ?o6>^Y}zMf8LVUPKEqF7z{O`b z1C~8Mp!1!_e|F>iZvB6mypPCVg3F30h+1ElKWg1MFqrDuMf+a{wG{ooDxd7bs0?LQ zOMg}S%gx(pEalsOtU?;i?@V6`X5$ifyUi(K9x!*A-zdjKfn}aX+?IySu;^;uRm#SZ zeYVOyUsHtffAS6@-42&xr-$V9>#Im6kCQ$d)ESmqbliVQ`Z5UoH@XY$*+319BP!Sm zqYkR$?@Rc7nfBEtJ})(V>pZ{3rl{jYsPX|jO3d!RvnG@)OQ(e0gsV~F%)hx`;~hg@ z%vj2ji)VN0M=~%*Ao;5HmwN>f#j01gPFrQj`Hmm`4|lCnBWKfmCSYEdAsL0&qA#kn z=E+rht@5^}Di4~K(wKY(Ma9!(0WG{K1=X?YHD@9iJ)Jdz`hQ`SVg>WZDB%^1=$aHH z8*9sM8GMbAM;5hZ(ikXr-Wd>^K7%6zY#tbRLW%Aa|Ks?-EOijM8!kcePl5SR`tmAr z=6v^F{oan=J*gp_b=-pN&_|@S`^MX@V?^c^_`Wi$b!*FyIo^>|kYMUnz)gh1xbZ1iDh#V_`C>I@7=pnKb+n%9WL_6m z;wT3Or8-gI_3h$uk3*wOGB%rK$spM@Pw#0}?61`1{z?V5w1GbGC&B|`SmmL#&OqEP7%)e)vn62;9@Nx(8imblE>*EM3V$JjV%U@)tG6hot#p|Rd9d5e z|DQ*sJEZgcJHNG4;yruPZ>%DZU(3mA@4q~lEgP9ISyeE*yB@hWeMJ@dV4j5sMX8QT zsaZ^yZzs5|77do(P%q|FwC?WEieMs{#unQd=?yL=itfZIoYWwQDb(N+O9%~n^Q%RP zu<#aa=;-++rz?D;8xRE^igC7T^x=VvItV4iEf41pT=IknKcF7V)CY0(jitn9e3Eio z?*_4$rJ&%&lXER?V=x%-Lt0okhTSMrZwsm6H8=+H71~oX`fT+7=aT^<|4jafJS<-- z{e|=;=`LxjbPjnAZu?E|zb$=D75V6mW;dE>ZfehF@2uZOR! z1Dc4*GQ7kJfFbKirmqf>6P9{6ZBcF=yA$?2L*;74ATaP(M_2N)Ya)GBh|GE{D;7+q zBes<`*i|YPtc^sH=_~EZ*0Qp3Bf_S#m#38wu~{BHOO$Qtx52u|khw9~4;Kj!2q0}$ z4II<=#nwf(rr!z>Z1--65S#$iN4nE*0RWddqOcx#uUuP;Jg&VK5K-1cqAR(S&o(B; zT3cJ!*W)dvVYV~<=KQNXCr9q2LNYL@jNUpjQyr}_M$7Y;r{4raG|hGhVL{faN(;8Q zUF)DW!Pp`|nm5MIlCX1R!Mf)kw*l38yS=_Kst6lrH04B^={k$Qs4T&Ueul~PAhK7_ zr4{z4*`-4bvBso0x6^>?z~GLQYK)vqAV9s%IyD3{=3H2)&NM}@5zh!8e+87+wq_QE z@|33P#S^P|0q4w^Ll+8~UzG=4K&C}MS5A>c2ahN@qc4ahN?RGVfRakRc*Kw8cFv5? zeel8=kbx>bYGqmT6(|(Csayrf7q-+F6@3?QhK`_Cl-VYB6xcLn77KDiUoa3{4@?2U zMlL#FJcQdt+5Vpa68dAZP(ZwI?jLMVS3|sZ4i8TFC|a9)__;0G$m5&3$on>=H&&4k zUvGwyjK>=rTjJ5iL~C=pE%8x=_9Q4Y zQ=z#z1($A{D=Iz`Wvd7S6Q>3N64T$Cc=@H5ehLjXQ38&rf}8mp4#2A!xkLZ}mfb86 zEGx_mg%kGd5G`{x%yt#PK{qNnlh8jB5Wn{((;Mu1l3Q)NzNVfe_5W_wx;13Ed_h9! z?4~@DQoz*H@W8spWm&9Rz>M18cexkhP#6CHKdB+|`J1zk$P=ujfv+15sNp~H*ac4w8o+h%8{AzskuYdHMP-XG}_n@ZHd9{ByOA5(5{I9 zpj0{zfJ_Jd#2f3IYh%%9U9uro8%1!l#}2@des#1y+RzOD<2AJ+EP%5u9RoO~p}Bah zKCVYc*bM}EfXvuM)W4~}I@3{rVA@X=SGI16*9#$59w0l@*IMZki$imiiMg5a$!Y+F zZAv=Oq#90YAOukCPHzH0=5am&P;7Hstk)Hm4yqv!C~Tl7tahdA0o0|Y@KMAnA1IDg zN4gFmooj+*q%>7tm0iFj46O~(Y)85_4-A#dE--FP*8mL5aIe5|Cm2rm^=KRQ|6;NW z;{VWlLj$49rN^WpDNMdjPD2LwluYlmgdp+e`i5w-r77Cd(i)G) zn_8l+t+7OFLewuj?jxB_*_Vy-)D&w@MiYsqmZYI9kZf0ahn3m1VqO+MW3gy+v?<=y z+}PX{Yl5$>(Wn(tmp!CSA|&y9OH)&0YdmVO7pS?(bf;~5uDlV+nC-SB9lf@MLH{9>$Sv3U19; z5Q>=#QsQi}C5}*|BXQ#C%^`BTYa30NLWQw(dx(ttDHMscq}xK|n5E3siRKN_cxwxK ziD*kB_zRJqS0e9Q(n-6L!U8R%ib$7lt2)}6ZVeIB8EC-3d?nEiC(|u9H1*(F3fHr8}j~l0=>*AM}4R;P&)EpowW15XqZJ#-p_jXg_Nk8tKI@>P9WEO^=4i&DI7b zsNppQ>aFPmcE%G-LX_r&z{AdDV?C|uk%Ee@Lw>!>mS0+}4xR$5ZAbgMYl1f*?-XeR*yk3p*e>E`r1Yy}07c64o6=l1k14lHf1Wi$qiQ^^?c z)rqCs(>Lb_fudo@V%8VxNZ$k?Od&a=n~nvOE(;cus)gL1zR?>R&MoOk-{6jhF60(8 zS~WEGxuf9%Lj$olKM3cJ9I_Sl{{k{dLVpmN2{p+7NB*dMi+qXnoODuZB(IWRhetkB zclszGWi_qM4T;)lQ%ge(O@M;`501>?!V?UKu=6eUmKnFZ(?^N}N{M%;ryW2kw9ku3 z)T*m?Y9Xvo#%#v}kYwHIDOXV7m%W3UbObd$H!`sw*0W3<9-FOJyS}_fZWvi$v`VEX z0F>3oHa93;dj52UyJ+Fk`3uZ>o0%iEo&P;PaH67vG3Gkw^hLF&i}6=j#96Kv4V^dSIZ9+nas zlotppBmnA6k2ztZ%$+zgHhl>Cnfb`e^uL9Kz8JbK^fvhg`MvU182|e%=^fH#va!*jQyqBwY^Av z88?9edQm#52hyTa@DwPMt(gmLqHx!e5CeS|i?(Dg@LQ=GKDA`l+n2=Q2O$_X1<_Dv zP3HU%F)ebALx4jkK7{E5#IHWHE<{W(IMni*CP`>>!uCkfa7hpijfCG)o0G_#XES5~ zNI90&3Z9#{ARuZTq-f2&#)fP4>O@EzSnLK%p^o9<4tQr(JadlSSe|Q9CZXLl54+WgVZ?sxsGv zWxCV%+3WwcK4Lup zAOt%BZ4rW51llN=_A^ZPHCd+nHc~caV2__ANWzxs@o$~x9aVRUH$)0CHYGEcTYLP8 z`sN0q^X=4g?##f>d}|nrdQ9gv1*6%$WDY!0A~Hz(>fAfB27=TEz0 zLV>umCz-j}DjXD%{Pbk;e-i!wWat|CNAlzHPU%0T&r4&{8_A!OGbCxR{iHjC6PxB9 zfLU$DiSZ1)j}>RRre7x-+m0u?V2hUS~G=1Qn~N zqXMx~eFkD6JyCL0$F39~v9Tu-ciq5XdBMG&viGezMl}P&*JiGq^0tUeW9$rZ~u>(J0Y~ zX=lb}X;Pdy6?;HdjirE68C;rVuW9y6wyc1dKe1Vtq#`5)xp6%nj9p{4+-Pg5(&D~uVp-{20HPO}&Ra8p)DMAAmY`Uq? z8XzQcMqp3zS!Fp>knjJI$nymM)<}AwCIbt9AK91RKIGp(WU(DcvtMYDWwvmjou*!bNqx0TjN9)H8iLL(Q_@5-*0q1}Ea~nbKWl`Xfdo#_} z^FITxi>EU<3Nkz^NnmUqA2Rjv9L&5qX3v9m1x6omcEC+k|H&5!{;i7iz;&4fjQ+i; z7`^)fg3khq_zwk`pjV*86gyG`-|9`-+#}M}r+OAbMu@b6<9~5N;Llrn@a>tFD)N}= z{q=$CT1Boai2v1~zCg3G*5dzFH~-h_Vg9cb)`A7|e^k)5fh72)eJ@gY;jTgsv9oS~ zf(SqifCTmwpH;T~fAsm5U}Tv*4F;7ec2J3$1GT>!jQ{27_&ath)|mf)4Y>;6{}UsB zM?Oi$;D<47%WQ?!My6w{TK$|jwJo#77J`q1uQHnff@v#htFm>gA2d2M?e;*T#xtF0 zhaHw#*&e~wm1zSYrv0dZN$Xb6P_B(cVEiwcZ~U)$)f{r_c6?%y!VEobDZXROV+I^z z81u-5qqV5m(Ht26+mGXaVe;3o{~vb#9FpHG{Y3hhbXcl`TWctFW_DRMANHpSN2m?5 zrDdwx+a2YW%vjGjbAr(`M9qhG99(M#&Nwrj?qn=Wtqocn^*$B(Y0q!U$~urYgdG?VWp$LqxZ&}Qi_;CE#o1l0hCrOEL0)F zHRQIdxE*qMDl5iqD5$;tJsq8yZC0UfjmLZ)1_|0f$|)tH&dyC&*a6 z1PP0Y(U{#)lo>c0aC-8<#Poq`IDRBv)7_YSZeUM%Pk+xqKjsl~E7kEDxTDNWADcS( ztd?vt8^E?S#}d(|n(jPM|H%<5qJc?3C2Xi6*3{CP0Ms38Xsm(ae(}cR$r3Ras4)uF z8E*k!1-ANg6b@;W)4r&$UZWrE<|-pF3WgvD&{UcP3K%&C`hU=kYk^b({W$duvR+)N z)D?O;Qt5!IPsQg-@a#801=`!&Yv4bmaJXj}G|m;=e@9Afw&?@jUPm!0 zk1BBKUWE!;Ha&_KD_-!XM=PX5th3XuFfA$|I>k=@s)+2D(Z*HLzO~=^a_*ix_LF(f z2c;BKFT9ZjRW7ZJgMa8VjT(gab`7RFhGBrg)UihdxVl;! ze8@B;p^XgSU`D$r9EP&I2Wab?V6a0SH&DG5^-@#ae0~lG5!m|QpAzY(h+mM_9tA%B znoM^U`KD=iep{?18f%KhS{s{SOaP8$Zj7}w!rK|(_?*U;SaWM@6TCB_1$Mf-jH?yw zbOM76cB}wrU1Yj}K|Fx+J_B!j2?qGeCe1-4V;P|@8|_6$T6m=eL^8IXzr3*m4+d=f zKkNZodydajiyocJ!0Q`6WO{Q>;2kmQEWB4)WJeXuJe4F|0RMkD@c-O07w!&xif5o# zw*G&(Yvm(ikDOd<{-69O!N0RCJ$fPoFM;}yWmQhlF%Dcma|*@jEqF94HreQeR_UTJ z@c-lRe*)hZtFC(sKG_1ifDQp2a6#jmmjm?qf$q~KuWO#y0iVxqKEt|URRqAasV|9V z=YKp);60zKIOS?H@MhSjOmF0AbJ-lkDdF^aRv7;^W)KYWt;xC*hb!U!$|4D||LyR9 z`fP}E)|jYQg75|=at-tkg7|-BZE#?F1NxWCHyPq1A^w-)4WLp#TrkZiGkvhZ(mX1@ zwnOP+xw32|(_2M8-J|Ym;1gPFn|KwYzy|rQ7_8hvwUtE@V*e?&|Np;9=xd=9p(gon z;O)O#rGJ-xkNh{a25b9rsxh;-ip*KbM1?9tQ{ z#>Ae}$KzAV!7=u9(-TkhKJkS8Gt6QC#H|!Qn|f7Nd3z^!CD{^hg8`Cg}MTyw;>MGrT+?0BGMIUYHp=hn#x% z+ql6KaM?REtrHLy?muOup@AT^jLdp2pcQU%+J75`fsa90XOfvg%Zo1i_w@GGC+cD? z@Tb3*3|uO+2HKbI%=OS-(>t@+2vN@v0^zTEQ5~b|l)*EwLmcAuICw};Wa!N77D=b> zk#{lj8jwa2$bdf}2J5CGxh>NVKukyTxD9(5fFOy0tg|5CZj=`vtNNg47nrKcH}Xq( z;O*Qz|m??3%nZ>@V`RW>hZ+gj%v=>MFvw*KPDQy+4cfk31!v z643u+7W}ju6@;jUljTc*WIz%N1uQoLDX}F9=>PGvC0Mr*!2U)cDHgf}Bw4E@0sX(j z(l)%Y5-cyxNW)6B#FnIPHv=Rs)CovZ29kjO-)X5vxZ#rt-+4bT>$6}`j8nk!8Bj7H ziG>1|8wE-U=>LfViw4Dt#e{&80VORIu-qt#l;8xvr6zu(BsFs2md~KJfFu?QSZ)MT zVn-5G^BxtvT`N;Z4+ z>$VG+pc>{~D3)67BF;K_=r};`^6D*;-ux|+{*Xp+aF!pyh+y5UY1pd6G2j8B#sfs*y#afr(!2fI8 z9|A=-I#Qzzqt7ZZkn`;SFCqOT^jzqDp<6?>p^N0F<&*N;4{^LQ_2hqC6=h!KQ%HrHe0J)p4lHFEga^NnenN)L-g&YL}|~w zGeqv?kEQ_T_#s+WQ8WfZ6Jg(waqCc&?iso&^NtYd^yi=zL(m>eXbABH{> zIvA>v|3Us;`A&I@EK7ePJtAE%T}FOLJ^~q*kyI z)Gb?Tv$jRs>m#k1yZjdg38F<$I25gKgR1pvzpz2z7_Bv#xl<5J5n)qNTa52;sl%cC3JmsUPsn$uaMVajZ<-xi^{;$eR z2o^{5#T>cW@mLM&|Ak~93H@>C;n42T1@gD#_sTnEN&19zi}YIZ0(lG``cKW-aEKh` z*67&O_~`V(F|cHs{nDKQI;sQAnAJx*v*&?P=Whj6>af6wimpuIxF5L*htLoNmZg0ij|k{^-y-rXw96oDr__OI$ib!Ghxv6 zMCRTQndLlIy-p0>q$adtQFUK3XnHbpkAu4c|GLe#FhmsKBsbJYQ2#F?LnQP+VgG+4 zME}pr@0W+=i={u4-YfMxIKHRAbT{oxiH>L4Rv+wPDQ$wmY%|rtZX~f4$nHWuLTgiBjp*y zJgr}YafxpjS{o3?tC2`DdvP8zm|G%};Ud3eP$s5FZy%pJynhmW3_wn1FZ5SEl3#89 zmDvkIL_5Caq;l8T%rt!^d#q*xhRjhDl&{~nZre6O1XJ3g7B(qnG@`E+G7o&}1Wt*~B`Kyv)vnv}B zgaKO#gj{&|(HFn}N8kC57&D>bh$MyRATprdq7QauuPh7_hl>456_QdoB#x#E>23ZY zslwJpA#G4`YRSGeM2=~mWwS^OW&2NDy2pv^TdX#n%dA_$mh79wDtV3WwE+>)|Gder zO4pLu>VbInjru4Wv|r`8yKXgQuMj0KZy~4$SVjX*i2YULuqJycvRR8eH-)kQpIDR~`t9PI? zQv1yFH#clNw72~@q^-xhh9mf;Gn?=Sq}B#VBHJv|cOQGN867#J6jRAYDM3fWw$eNG zk(O+e$Wm)Tb^Of;4^#F$ZWeP^o2IAaIF(u94GKxjo25Td+Y@N~D zwf!~tm#=^4k%yfI^4bSlvbCasf$#bBr$0?$I(RK2MY!jw5%r(>M~c3yvqSw4N%!IT zU-!UAkjhJe(+hG1z-`%9X9%hA2J-T|}NI8MwKOl+5lBf@m0VgaAQNCrxn9OA8R5sjWSJ^YOi(ZaBX25CjM{5Fl*M zc7@1&+^M*ft$oH)7J`dpw$o7caH?-Nt-q_;8lY^fedgwdS}j0{Wjh3$y#zr`{xZ?* z_7FMD(H+4A0lb6NW$}J8yG=lm7XeXp?Vj+mTm6>he2jHww}8B8!5e#1J)=#Oj|vYD z7=-RP^5z}K;gAR#y#4a{@lDyyAu`I_o0mXWZasZ@w!Mlxz=tmj)ER1I0wZUjUVh`8 z$A%5E_`e0m|KAhp4P6Z5|L>8zq+dy2mgZpY|8L3X$Si5$0;GK=vqORqa?u&+;ol6M z0F#cjX5kb^&ExSB*n!Y=?GLmL#Kxs1K|hn(>uswQit2q2Q?;F0@zh2-OM-P9>NONL z7~HMA<078gXaHj0`>DN|DiAYnTJHx>ZPc_-q<{;McGW^^K;W2We?aW|VQ^frEfBEP znKZ{ta3N+}O*?b&?iD8>be7y;@a>KE_AI=MQJX_K#9;Z4p)Jla$SyO5O{ zw~d-{OJ=)`5(YSMGQ{fDZ|3$;HxvQKv&*Hd;PU`~?zy}2CWP|r z9$$iQ-@>P#JiOFblg#eXMbM7oyL&tODb-bqBmGq#%%8}@QN;IikKkGwDYdG2_8E3~Va48LkJ*4L7S&aS?NFLjuB56T}InptO zEmW^qn4rc4@G<||>?jbZrj!KAui7R|u~mYv5)h|PEYG;F=2TGwu?;#5?gY63GNELq zN?R5dNAo#)y53iTwE{i;!>Pd`7^mfZ!Ekt6v`Jk;pssLlo0zM~!YXOq4Vz4$v1tw2 zcj>FPt6kh5$T&J*)PGs}Dv@7-OORF<1?JzHg)IeVI!dW)slk+kjN5dDjB59Frd+nF zQ6{|ub3L|}&GoVk6Y9T2K1lGdqS6DS*~3-j(d$Yr+icZIDqMC0Qzp3+ zq8>e5L;Zh^)I;QI=|7}zOHWES!;c{Or@%#7*r{=iW~~}xwVl}saYP_y4#vQM^bZV+ zubxsSNABEzWaRMJ{?X}UQ**%gzS=D8sN{#yR9j%6Xn^K1(2)5y51Fr`0c2lYc05Gh zAs}q*S*wuo1C|N&ogU8K3gZI}TK*FC!~@e%bkhJ4935r0)qfQ9>S#?}+g>(I#IDWw zp~SYt;G=CXSB4n84(K8Jy&MJ=n3UuVX!= zp8g%F8;*=mOoZE&@ZOHDJ$w4vmG<@PSq=sEx{My18QXtwY+`I~Ous)1L-ms*`;U*! z;3iNnC5(`us;@qYRfXv`(ddBX#t@&m>e@4P0)|J2HqPy*3S84Qyb*riys>S6*YHH` z}yo-;CWOdb91l)m;6*iHxT23loZ*1hlj7v&8HYHZy2-RZS=02Kx{E=UK z^p&sD`_QRYl#v6oAltLR7TTF+J!(bS6yHE4B3j!TjYYRaH{k}VXk%*(HcrKxEVta? za(1g`QMv8Fv5E1Kse>c6uy40siGiq0C?jFW)~F@A^a|~&9>&qvGD2)LzH@M(PnmuE zp~vg%>tD&j7Wk==3A(T0E-gL(;`5Mx{`~Vj&p-bh3?SeyEdk8y_Q0S5sw{Yh&p@iC zDK*GtLH)#S3E{e0I{rs4BT|SwM;;~D!&gF*S=gL;g0^XNSW&lxxeYsL!CyyzG7Gyi zS=p{(rmhX};WiY3Zy}_E5y>oU&oq`r2%gHeWMO|MpMPNW<}0h#`smT@R2BIUU%^w& z#iZ>ZlM=kP##@t3ja=xHR1f&m)_BVBuoaa=0VQ$DZpf{HYK_&SPJuM{^jCA(>L=(<30m0Hv>E0dB55TaEHJ4=Qg^8-8<$3y zTwS@e^mY8^2A1ZmrdQ#jjBGlf|HLDAh86uce%n|d1%=EfG?t12_<=>)OnVkWSmHhVx5jg2i$iD*kxW2`078jr=Anw!ywG8Zpk z2{V6>qW)h@s!8Y%LMLJW?DG%T3ZRq|Zx}QiA*o`2y_!sqW0-4o@~tIXYae zK;+u63AjPc7#|FcY=obJEl{U2^*cG-<`3aM%s9^iAGu08xoNJFC&or*G(7Y#sQ(v{8r1(;IQ`?F<)`FP z*!}mCv>^3M7m)9fPmtT-F(F%XxG_}I8I!_X72zytizr(oku8Y0Mm1$C{7&YyU7;W~ zj^&{!10j~L&t0VR&|KC`h?ds(Et~Wf z0O=Hd5f-mvhYxw>;0Mnq@I5IIi z3w3to^urvWl)j_aV#b8BOG{?Tz{6Ay4|C9(;SG`voX(tnasy)I?vh>fe;tXC&{yR9 zVbAZPv|GA_e3#_NDBPrJYwk^euB7#Ju;0K)g5Sd70qk$Eui$#k z%G(q?70bP@ip*=?xh>jUQ{T{3tUsZzu|+tIN^Qu%pf&WTnJpk2AGOoMi;Q`epw}WV@G6N2ox)JpM zRpbs5Iv%<}nt(6mNvDqHU{Cnz!@5;bV`pj;G?Sp3m6os;Qft|?FObKOe_hEE)YPbA zf;~`75ag?<)!amA)DIokj-k|WH<-n655*t4SuCA?OYW_(4`!Qvqt#6KA+$%S*6!Qi zHRb>DE76+nj=eqoyWqhKzkKnR->LcKe}(JAVI7WZiC9fI{NgWP2>UFbcQ2;`0j96 z;||;lhb6|ML%Fwr@xET?PdLmLFDewsH{$W(aF88;XXLNQUy?sBe_H;y{Dk}gc|m?een5V=e3v{YPsz8+ z2jpAiz4C52VR(nURc@8za=pAkR^&Izuahs7&y!{8zu@$df0X`K`Wc)+{Fl;qVPC?t z(jQ7sOTP!_5&xF-G3monPI|xekaR{mDcvc}NE6bb(DqPUs4285R2_3e2QG!{8$R$_xW4`a7sBM|qT+dyE-P7yNS-c*up~XJ%F@LuBR=9p^5%yJt|8(&RxPEgHY6<_z;>B=%cJVy8 zeq*r;uK#lp-p>$zCI_c6g#Rda60U!kgL=bX&%w}l_-nZnaQ$iyBDL^Wa)3kl4{~tO zZTRWjEL^{wI||qTk(-9=@8@oZ>z8uC-0&B3?}F>^<=zR`-^~GT;or#(!1W6`#O?FB zZn*w-E(O=m<#xdJv$;;VK9$=J*U#j(!S&O*t#JLV+!nZgBDWc?znN=;>&J6RxPCMT zdql%e=9=L8ksNrE@Dn*WH75L_9IPh~|5|PnTtAqrhwBG&wQya`!O_p*Z0;(!rgK-q zbs_gQxIUhH6I|b)y9BO}m0u79z3HC+FE5i$SHBJ`2N-(E!g=d;ytJ(ay2 zuJ6ubRB>Mhxpp#xT(~!L6I}1f+z8jZGD!cU8N~TW2I)VUxel(kWf0F>Gd*xUltGS+ zWOf1m@*+NcR|e_-&P*#@-;qIT-;znd_2x`7TyM-EAyFF^xu=gwhU)b z>V`5G!F4c=5_NqVfSd_8oH23w3AOiq?gHhqIR zdKU-fjR?ier6DiGA7ws?IF8JKr0mpy4G0!u*LZcQoQo&Hx_ozs&F+W;q1{S~Stw5eUI~p0W0%^FfAbr18-OC(fRR|puIEen z?`lCgMI18uBdY@tuR{@ttz#<$r|OYX*OZk~#crg@M`}9YCc9?Bh{H6FGWFoQa#zFa zwNhFQ0u(bhcB@gM&k++o!~&i_hx#8Pzd__5OFx8r0+oZHu71YQ2l#C3=o@oz{&z8>#4ob2NpRx%?SKa^ zpJA1qnWVJq=)-qWo_kvj_Zf#yK?aEf%}U`P6rx!HMXdk&H=q^pUajx z5MtTh2Yd=&Num|i=KoQ*>?CaM3Qy2l|`;7+I4?T7{X|5k2eqlVXtu#}v z-gwKM4Y7mQ9K3pW$8h)68}NAfYYtvBb#?rf=+*DS$#4M?)PIY6QDDyd2|d(sFhl~B zAcv8v0X@!QdaQ{4>#?D;{>N+5Tb4rix&cS=9KH_QJ3h$~o*)L=C66ncU ztS3$)68IHE>;b;`y`sl1p3Xow>es3MOGgR(1*seqxc~edyb16jpX1;5QTo|zOl`+S z0@GnI9UjaE8~=ZR$Zh0-a)`fu9jBwYCYTf&)A}5q=G43>g*cX~$4FdpiaB5dFhzPh zSL}Z*$TMi5A3%3gBE|@8!wM`p2I^CITgcAXMt}j@nJaZ)plH9=V9~U8M{dvwc zVyms~9>MM%KEt5Sjnwa=AJ9PgaD!gIc zv`2yS*o3kxf=9eGcV@BOx`II-gN_v!G#EIn+nx9Mb6Do6?Tv`5+YM?lFrE4O@=(mU z(OZ*BEyya1KQ69dpY=M!r`8N1p;^N6>s!|`FIZA6MtshdzUExzTxm*W;~2LN>=M0K)a6Z{8hPDpxSliq8dH+305i= zOwqD4tsM?ZZ)fBGPZR0sN)-J7Cua(r>CClNk@x!O?w3Kr%20)Qu+0!zp(QYCpb%X+ zEP00T7c#9XduWF&Z>Ya5$ZY(-hDg)&lwW6YoA1nRhV_=d#LefvMC=Z`MSym#E)MGo zsJJk4-+w`_9cKUD=Eo})mx^cGp;xww&6$Vh!oSR|r7#H<-mlJa>e*Quo1@!S%(nXH zEN@vk#IK!H3IINhJy25bI& z90AGCnll|L$WBdQMRRoB#VGBK=Vw)(4L(lLBYjbKBwg zBOk|+tpb(wrxukJAXH+<%iK9M#{V+;AnyP9U_}Wyyez9zd|8%w2$cN@R3O)EiMsD` z3+@1&e1tfypi2&{|L^d({y$()$rxn&<_gey!};DhCBl z&E?pZORxg?F-Hqft_SlQbKS6Ndq^`c`7O=L zi!hZ69JF<2H9p;vfC&KHVEFqe)uqbld;Vh6H1W1 z!H4!axjm}p9yUdlghV?_Kq6O8uQC#$|362%n8@FkAC^8Z?SQXmb&BQsLPXeVv$vyn zPihF>o{cZY4%b&dkDs8+U3&%x;b*Mj&r<#4xn6i}^gcU9RM=~=70{~5YGrPEZe$`_ zAFtW^+se+tfxc?~IDx5#UiHhmYvKD)LS5f}9N!_VtUI+YcO7&d@`YmjtO#oq=)Aw% ztDdT-gHZE8qrf~bQwo96pt>zsI6GI=oqIcw@iIFy8f}hhO9Ytub2iciFJ|fi#rN@I zCjPcR;X4BH*_`d#t}bTW7sy8oZ{|H%i4^bA}oC;$^{O13MivPBv=>H#=?~}%*2J&zs z3y~APi&tau&fH#b5Mh6XRb&#$c$1329(M$+E#iczOXh}c%PK?YRomAyQmluhj7^PB z9~_@LyoKGIR_0%u8v=t?1Hyw5MRlw`R-*<75l9#gD6@|@HaA5R@mMU`IyEw}e{%ZZ znBBel>XG=J^b)H{#ipm9eU^Vdo7y>)s#hlKp`^jYHzpapa* z1+{KZ-2n2~({H$EELResT<9c~0Mx$O-fZv4y#vJbT#5!>)cC6%l^;_(ztP^Vh8XSq z*-(n!=}nzFCwEH~nZKwIAj*yuMn6h5w;>~u^|kAj$&ou>aZEq?#<#)f^bZg1-_bE# zLl_#Qm!yv6ZidE8Yk1%nm0{XF;2S3U+dEQofJ{S^A;mO5kZ5gcPV#49_z;WQr4#R& zAIjYXdrIpVXkS;AsOS)d_*VEzLtWnE(C-^^Yl1kO>e~$k+997|6ho~=p%08ev|o4K z_56#^L;Csi&-Xn4{B!-osk_vq-=BTF{-OF;9LMK{J<60Ou7()eE*B=V== z5~Lzf0EGHof>5h^;~?A`=SL3AR!3`Qk1j`?bz^ET#oUq^d*foyQImHOlvXS(6g23O zn7gCD4}&3NJ5aAQg%RFrY8n`@qB6HXJk*rxC5??h*8OKSS@muPa7mdPn>@0Ac5ZrR zZ2!UWnXys$c0#AHKx|u!rjwQVe|Z1b?@K?DZX!Q}*uO;Y0o#^41WqQz6yXA^hu6dm z9KB$>U2g{;M~>ruH)$PT17Jsbsjx7K6?9psCV@C z;$Z+|g$Hn~P;GdLEs?G5u;Y!5Gqsj|o1F>M#dbcG8v$#;L#Glq&0euoq`BO}u&`Zg z`Qv;lX)=XcvHXUUXVrz0!s>!$TQu;uK?@1lO3f9QbfB5NbfzB%H0YUjj4UX zpiRwp#|3%fo&#}q21#3FZOA#f!&=v`JPol&1ogj)v=jL+~nd+v0j4#rpprgZF<+AM>vILC*3~01mP|3X*)CL6VIk;)C;oUa3a%q+1-5acltvImXOtW9~@cjofY4Hf~1SHE+c9e>0IcNSn(i(`%!q zQ-^Z15RDo=ISRR5=%DG3L96U?8Zv0bM3>-A?f5boA8Kb+E*7(#-kY0&y*@FE4YI@E zzWp|#lh9D%Ye56|nqV6pC#Rl)VA?1SAN9{u*xBNFg`~I6fQVjiG284?*)HpV0P4Ra z)e-m$k~;M+JJlkY+}v4o*)Vn3z6L z9joac*c0B<-!srpAL)7Fr=obsnHMIT2BXjwm<-|17nPe?5ejNhSm4LP&3p2XK?*rkX9uHVEx}QT>rOr%@TMt z-Kp6-_~rX(ZWOU97u#7(pIuB?Jn(l76CM1&Oj?L^KU};g7kC(= zR-Jc(XnG0bP`dVZ7$$SO&fJkZ4oCUVt_~IEqSjt6J>eBv;uRphKz-q>7e@HS-cXg_ z!ppZ$dg}~`pd5;7U6B66;s5gI;1Z-#Q((S5cLGMK?k>Nk>jul-NOS*Z^sn3#T4au| ztka5_1y7e(BSiZG!d+{X!rV!J?oMz!R|e!W8WbDy*+{a^M4h56{@+NXjWz{>Tbu&- z@5$W-egA9EGQn$C7pBhq-y;(vqaXU(XFl__ul)Wi)e3B7JaL3=Y=ZB64KmytJM@F; zSoMD`(WS{WTgUK;Ztta`$kGxA(gn+#84RpXuMU1JA0*v8rozX1^lC-i*&1t#1hlQj zOM3D9-+x)nM+xGkOpQ=T%P%N3{|e8lU)Qf3KX_nl|H#3E(?{m=*a1Wtwl<2(F_-3Q zYUuEP4KDa#`u`k}p5vk(e6C6goN3J64Z{G&)fnJ}OWz|acVxl4144vh-%5wOp3565 z;3{ZTI3bJhRjjxoYcu-)5V->1|Mx@q(9@|cxs$L$>Ap(wcpmAfw+wb5-K*_D$|s{m z9iqrr*?POS*xj?yUA=wq{=a+h{eP9hAfeSB+fwS4GZ^m*S}A<>GCm-*$A%9AFyX7H z_xa+IOUy;>o6Dq9vYe(boS;@~2?`kFNT`w}1i_ zM*-OXb02j5>&kEL{Aie<>cZDbFbjq)S-Ka&_+KV35UC3;Ya~5*Vo`$Q3hyXfR1|eX z`hhxS?<-qvHq`RtV&L$EKfXV?2ur9RT1Iu6PcX=gcGontrXL!_r=amO7H@88P9_?g zl8v!ged>muq2VFp`9kz$AzCC>gHy+lCg{0D`LeTW42ASlir7O7Sh!&*FbQ+i?nv3x z;#w#X)d*yri2y<>I%XOs*yaSzn^XK78|&&e*416xcF5`~g*EA%*Uq18rPcDn4WBa# z;}hR`0b8RbY_Tprrl3Haa-tN#;H0jrtF9SUUTfGZwH8r#QUFUvyfKs-e&s*dlRu{) zHt_1|covqCT@BS#i%;CXd#|fnNUClNckrtt!VVU|5ibu&X+u2rUl{0O7-L;S^k_6+ z?2CKGiqsvlZvtI}X0NhVJ*3!JbOVLmn%6JhB6_cUozG}ED3JvRouYaPKuaUJrjEb+ zX+xC$;y*q0;)j>|j*=QeJ3yjt($ZZ^JtAhM{f_=WMBYr~FG{z;hat_seX+{VBtQ6D zvH8nqkYAP*M=ZS5nkSFlB>()b#Sl>Q(!!$>-mSJ1GJ}XwxzcmnF+vklgYeqrG-S|< zY0~YtVl*v<_g>X4RJ#`CvXRo>(rAP*kf(I?vxQs)QlkD>kx!7&7ehy+ZunA>>C{^n z&x658dVuaaeGOwfO)6>F54dW-RSm!g{44)tnR!m(F8|6u#lmJd@LPq@*M8>e#dBf! z-MHTj_``#Bm|yyBjI)gAe*UEXuVVFo{)+OG`XA!4IK%iw`@Xy8Sx_!a9LU^H^kYO} zg=$kYiYLA#lQp%*Lq+*Lu;5DWIk7VLaleivqEyl!IeW(6s4^Cwhk!Jft<% zKfHgqr!S=(o|!&&WPe;tO6yodyd}BygeCWzC>tqB9RS|$WMSx z-``!so}cVHdGcgC{3j&QSla}AXpOhDz}J?Ta?eQx@72-X2Xr%lQqicoL^n}g-MRQ0 z%LZ!{6LofT<30Cubt@Y?hCp7}`4pRBI&xT{=L1zok;bw5X!qhd0OT?+o~k!{c@9 zwk}=-l#<+YIuxb=Mi(yx0I>Ov>mcj-0%)%Lf`Yd7?Pdyz*Ug*hclyz;|4ss+-QS~+ z@PdyM$?C-mLS&z@66M-j1x^iVZ%^r+ZTNQThQ;+TtW zQ;tp_o0=n}9S$47PS!}*D_Y-o3HQe<)q^Rj?$wbUJzWhaPrY+748&Ibj!GNuHK=LU zU5n-nG-m@D)FRp^mf`n=uNp|3XTmKg!E=gt`FH;5Pzis`K>#9s?JWL}68Wd{Ea7gz zMfcBaTf7uzokH4ycUT!D+?>(RzJkQ|?{L29Bdd3ydQM(qBP50W9=P0JY|6?Mx`!~@VtI@U_a1%Wa{wPY_&ZM zn~XJdc%WS$fMx+O`<>u~fuAjn$#}Fm5rv`qSZi}*V>}4~$e?jOE3@g}fH5HtJ)!HP0vV*87J^hM^H0f1ln8v^c zKt+khVfvzh{vkUO3HZHUJ>FTFojx?T|JE^(or&?u@i{mo*5;@%+* zaEi7vJ2rZ3hHb5^Q)Z7&jL(g6MX834o04d1Yy`%sjUoiUFvOwnb7nDE=m1L}q@mc3?bxwndqo`tKvKejAPErGK~a#%n1@VK z@)et+C`h8kLn0~JvSmAz?bu1&+zk%7snfJgQoGI3GqW@mQx0(L=wmv#v5&d$7f^XAQaZ)Rs^XQ&NOueklc5RD`MM}5cO8{qGu zKZ1v9xJ2gVcrzDbX`q8A_UYLBZDUk!Y;F8TU3cfcp8nl3eo4LO#DqLPo5);))AEiB zRg7Xriy9|<-JQ7_dV^QENlekJ_KoI(A9iG32AFEg#zZ;{XLe?;f}yK5c<{&w**cbv4uyy188SN5 zy6I5n6=2D4;f)c7tn2CPOYQ7Y(-j{uA|pd2k;R2><()_*Vbowp<~q`35bMEVQ@3^X z?j7pcM<_Js%;8ke9hqwZNkUJp2(&W=dw&n6c8Xz6{aF8f=*tNIR=9hOlDVMov>1-ryq7-X94VfYxk%A^yB~dsgFPNo>Z#;`FfJx zIb^DSM{4+1NQp;}iPMIa=`$T%wuNHgFraRa$`O#7|KjDhR?U&ztk_tjL=_~qf~cJF znU&kf>EW*Kdgyldbz%>Gsr=>yOsNP=nmrCPLx=G$E0HFp@a{rrU}&hmzOS<|5sWIa z_E@~7E!J+IBubL}^Ze61l^Ofbo}T|>HHV0r1HRGmzt)yejL^ns4cdK-^Blj)v$09jp^(zPK;Tkm znldu5?XEh`ww~Sn1A{4!<@x8Wxb`u7=Ge#B5M*G#d*;~ZXsW>wFIRcQq|O8~Hv+$| z=lq&XPflYFIgtpKxjSf<3g4}nV^>3BN=tuJkOyDIeXPRO0CNP-ZZI`V+JE1-5d1v1 ziZ}r45$ef$1a22J`A~ga3`CEeh~hNX!ix=z6Xmf>ZI9PJW}!Knc%cSB&pfqfm_At3 zEAoo_flxb)f6pQusVZX7{9bvAIBG%>)&CD8-!h-^Uqz}}fucORE3*z}VK3*c7_U_B z;le3;>@~_h##+~SKExyD!Tt6q?PIJnGpeHTStG`MjPo2z_ROl-5vm}S`u-ypMqTgO zo`V{f?dz{tjF#ScX|yzUK6`rYV>qs*CB#wgL1=b$6~u|R^_1CWfZ{%imDfpQuH|jV zWoLNoQfv6J&mPJy#!>FBSX&lTNimiQEg!@0e0sjZ6CMBi4}{>i`rR8Y%&f0LPw{pW zi@PWDCZW&=lqLC?vkPafQN4}NdP3QgJ(OKcPx1X~=AZ znZP0TdhBVc-aJ@7RZysm_?PL}7bVj?KCY5~73hP{SQPTCGaHr=EO5!0sw)E41JS|w zKlA~#aScW_zKd|GpR_9?jOw=pC2?KlIu$dtR;up{>K)%~^3#9?SR3GS>FQEZYk5_e zFoAR}4*Ty_OPRV;J5sw~kqDdr_uqiv=Q)o91`fP+Fw;4AktW?^+;t*BJ$le$Re0+i(8nH0)uGvA=^4}1RAeoHkI0Os+^j#o6?aOL(@ z^OV=*{X;p7SBcT;bv3?}6q7w&4DHB%jgs_B=W@47N+QN8l_HIll_|xHv06D; zh~=GgTJtO-&x=&cGOG^I|8El(5$=4=%u9`b+-C%`t`ZKedED24kkw-3qRYd&5|>&1 z5#}y{ueuTo+%|Z%Is~6JW5m$&f=N1_(1!(7gsY_1wPs0>z9LNtLI1x)Kr9oR!0kav zj3@)H{3?}Nek-$)(&$$URDxfoVwX(jHV0R=AOf36TbVV&7;4Qo7R&ETs|6ze4gP9X z2k8Gll0tJ95RWyxD#9I}(PHGW1Xk5haq45W>Tg-q9j{vEsffT>Gt@!odBJneVq97m zDy1?9Pxuh8i=-|<)m+q@i-ayf^?AUP1JSSsF_F14+q^P)=OUR4P{LDdb~^}VH4?1S zIxrQ#aO3)Y(I6{rbJjlw!v(h~7 zGj+gSYY>$pjn<0DgIW|oZk?-x&}tJVRE1V}A+R!f$`M-U!K0Z+lL784PZ$<|9SG?E z_gFE=otHrK=;Gbja%=W!h`CRngDc*d^YGS!aK7@T)GC9`%)$`@IPAQskl|&yAp{#A-a^K9>vbo!2GzhlF6k{(xf*CEtDyhiw~OQ9t3-C0ks^M3C4#dJ5L`|>dy)uPGqhDl=R`J+J_WzSMA^3UD z%q^Cq}2n zN9O2t77iWP)#pAnWM=wa?4#C?1?rzv5JPhHv1z0cme+WIgCDRNCRz1A9s;gIA{Im%6!klUEUTSvOy=lbS;1CN2QRA$y#;nys zO_-UamBEMcgF*O(>VR=)qM0T**>BtvAkxg05Fo}iumS& z`u`tf)L*o)r6ku@^u6X^;AJT;diqZ|;P$1@ld($580i0h3iyo8zsnbLuWkfhdit;R zH;Q#JJsH#ZWN29pkJMg@yj-x1f&TwQkXcXv$>1qwv1iK!xmd8A3Aj8NTShX5=ls38 z@rId&WiD24f}Z|sZM4|_u6SF9=l>=2x5#$|`XSs_y1Ob9k&seXz-~Czw`X9mbMSWX zhccTbbbH+diTDj%-$i_d!mK&yQ$3kYHRv~2dlSh;CX%b)Gxb`fYPU+z_y2dS|8;0B z^1s&~_x;Rw#@FLpgT9R3h;D;G>|&V?2~7tyH~C0^G8X`czSWm+XPYn?ex8wm6a$+O2N#^=%_ zv(qPL#?m8r4Mrd^m5Bk_qs3D~tcnA}X4ZR3_3N+jn2sHEzK?EbZezd-+{y;s@&jKOCsZ6v8)g~l3pM_C3xK^5~`mv&RcvwVkzl3-aL!SwL7T8_+e7Y~)K=jg^I%YEipJy7 z5YS12B9V9`5{*X4`aj<%k@Qb+@!X2yz@s;0Zh|F~qMU1*EYHo1PX?n+N+_U;VlrS< z3lMihpgANUk5A2|56^Us&z+)*LsW{VlV^|2j87dMnM_Yk&xn>gP#VNYZ7ZfWupufR z>^!9)Y`}CB+Y_g!joSU6Qq|{F1mr{0GwJceQzJ*yr&L3&5f8vdYCz#!Qu7m)R|_YH z^HLPZKtSMtlDLxDHodJAU;;O0k`hWWIDHwTYqvo2K>PncL%spuHRxwzZmZT`pV=m% zo6StobtYn&tv3A^XvuF2z=gQRXcF37t+9QqIkTk(y>7&e9YU6)N**PYawX9ef=i%U z6f?*Ik{WG=QT0k2f`wq{)hUu%K4#|@uDgN2>1Ae1OsY%_H8C4l|1U(}MgITtf7<_u z|4Ls19#)atmq|fC759TR8KX76vu9|yrysw`DA2P~&|n}$dw|dx4DdFSJmCHzacHP( zIF;%RK!-cGJF~L}{rMGYOhD-TftU9{<$Iv7KQ%frGC6%PO<{{dmPiX2iY9lG5m2NK zeiUY=jQPPk;s1PQeWvRIH2-RDBNv<{<$^IU;0t8;Ux~~PtG6!e_q-1yvB-Grqk>Ii@cSK6O$*IHi2^e{(7vP*vZXg z1W|5oYf}R9>C&X*i+o$m7WZ#!N#^OtUl?&F28x9U-`130+;%$AFP#C3L!@)7aNM znzoB66mT5OqL=}OI`^ga4D|F5Hze_WI0;_-#E{!2qySbZam$r`=!IjbYOz&*X?YkVoJLfOIa;=s6{bd)S);{7fnc`FvywWsy40St4fOvvM*A%Y z37K{bX}wO`X~aE2t@~J6pV%>lZmO13A{uRJX^%!)A`vAXi$Q-GW?R&W(S=Z`v;*cu zEY_BYv;+QlOQfClh^@+aif_%g(4< z`8;sO0gzMd1PP`Aj;{`-V`2G#{{Pl7MU@70EOo1i<5o;uOdDjCzZkZdw5)tvu+r@z z=>Lmi?Hl|~HPmqnXuxlJte*6-fL z1Q&t9VDRs{mo=G&K^ovyG#+hfYfD5UiI#Y*tp$E9?Xk837(shH7LO+qP0g`Hq$#Sz+G8+=k14ls=|(8dM);2{VAOv02^p>Vtpp&mh4AqUYp%0Z-0q(}^35ZyZZY;!0{_ma_5hBj5s&fv@q z4F*hXsHW$%42B6iY`)c-D#HLYc4TxWr~oJof=8eUAx(K z=7Qz1x#Q;F%=dP7-PYWpPUI$4C(E>e-kSvS=mat~;MzH%>y@&3xIqv@mBS zu#2UzX9tGB_}Hs6=QK%LbROM0%Y_rYa11Vrjo1HQ;O|G$djF68AM%fb*K-~R%H+T` znO91vJ&;sa5|WWtuwP)o=DRaJ@FB)kY@t20z*tI^z~QD7GW-Yd1^-WRpV_0vwPm`= zr`9wVj>!UkE=WE~Uxz>B3j{i1ncd`Tfz)k#dOLgi1zL)J)HQ!wW*40L)e0zhmKYy6 z_7RD&=22ZjP2=Gz&y52&eK4kpzu?7`l=#fVE)R~8dH}C;oPhvR(c*8#1wYn*A3pj6 zeoN|JGn=`&2K~-aqwv6BT1&LOtsTpdDX!`fPDim9kHpAQu%VnfXvRE=ElsuA(%Y;+ z&r)e$N|CaqZAl`q{`=9Zkbe_gD(oKV&-B%x$JZ{t+B#t6vLtH377m)2XcbK*)M)QA ztI^0J=yH|03e(Y|!2Z>|Ly|7*}oku-}s(FX9K%QCk}sDU+)jg1%0qnBs)NGQRA zsHy0nZ!`07S&vSLWr~Gpz>Gx|p4+3L1;^7gY>C14*>CM-#1!@J^w$N0gYN#9>)v1in3q!kWky zr7hmx0?R{{)_6RoL|Wl%lxkCg+y9GvwMhED^d;%T(pl+o|M%eW{BzITl)0@2{r!Uu zHpx>5V#$E2X_q-RN-J)|24Qk~YHa%8_|#z*uip8#TI3nJwv|PQvD#9Cr@+Phozb|0 ziUAE=?Q5^i+zPF2BESdzmwu}s{q{mY<;9n0_DLwjdIXL4hoRSfO=hn!nbO#JKOMmb z&-~??VG*3bUy~Wqfd@74Ychj2Q6a48!lp;~-AbE16n*WYgNgE3q7^>HgLT>M?IIZ8 zSSaL|gVv7(6 zEN+X$DIpwHn?f3>dyr{S9(y~Ds~ofvk0{Mw|N7UP;Rc@>G&l&?tJQG4;Z|n%p0Pl?rn*p^nDTQ|r z!>-u}W`oT!AVJ+%yzm_>2g}^4R;dYKLo;i5wjiF|bxA6h2PF`4;2xHdo~8!)9-z=C zQpDEg3t`3};aTt|_p$Fz$X7dfv@L{s$hP0sxWu$7ggM9@0{VXm|AK&F7Qh6rMJx^y zAOx=supS-*ea0LlqQoHJEHEcO|9Nw`04I1U4imHhp?cX8f4&(!K0^eyYS%APSAk{N zNKbJ4nBR<+#0bG=NXXa}NWSH0#aCI`LcjK+PwGb=_(lVwB)VfC2AzSei>4=oA?BkS zalvDW=(*`RSeFkUuS^|I&q8wQ#Ow(IBU&1$LN~TD+rvy%eZ9Phj^;|feygwFq|pGr zzRuyU?s^$YSzk{9m}bOdBkeLStSu1jw-AY zxlxhWnVReD>TZS)i&#bRJLrEveHfimJ=XHWlQcHYB@&AG0Tl6@FHHc}8f}TIpGm0z zP3*HNLjnwqgTT=B^arDAEVF_gqw?vFLxv>ek)=y;j}=th6sv_m6n4U#ms^)9U8p(Tb(bAPcPq0pY+KVvb}9^nZ<( zMrmp{<0m1MI-?}wC^0opj03UsT9a%{<^nBzjX)gF)jkK7i_+Y&sC1M=A#lp9{!jpB z{$Q_wEiElA__YMzTI9`PIlLLZLY|y#LZLaN6thGhe&*SKWnYV?pEI~OzwJG?@kusJ zkW_aGPV)Wv@Ie6?iu8qpD$>D}T}BQOjWA4kIq!jEPeVEUnAz z%>74mh^e0}fM74(vnrN=?{2VzFKTcXXEXLI;fLUeBJ51%6eLEg5&*=>h+_!YGwjqw zf}+h2@f}{;;;k@N*cy){Hj`W^WzFr)h7GlVxI`-vw`3~0hmO^n#>92|Q`0d3)}6!m zMmgHr)DB%{nRbxD6KQGM-a>Cmd!sD3MhO75#1M<2`9srog?>s+l7Szfg-DLalmmd` zj1;=@HA&a5Fw77|N{%nAUf7*S=sYZz-GxZ{0=iux9dxyP#@wRIF;)+7pEmnvefhYJ8UecOaXK=z(VK7ut@!TOzxh2du-ki5(0{ArX0Hw=Q{>u-ovH9T{F?yZkb1WY zQTLPpy$C;~DFy(CcO6wMiz}l6xi!{Qybo_9ZsObyXJKb48bsC6Pf=*wctd{V!OZQjp!Z=1vz{dl2?p$Lz z!@jh2uxUrsNPDu`2?kClaF-_!M(hX5>H5DIl0M--r|3wA!1@0W|@K)#xg@%sJ=Ur@|m5P18@%I z8V)a%0Y(H3$38A<;i0TlUfDUL72pNunP{p?GS!k2l8W$$@NsKq6!_?Kz{jGMxx^Np zRIorG=NI>|Dj`jXdH^h~7+&<++D2$2c0H>G$R`gTfQ^092TmL&@Rr=HP439-$LF|m zELad#0RVGF&YjYQSRPJ@_5T9Yfuxs8e*Z80UjnZ~_gElv1dh79UY0wDhhccJ16m>O zHvVPm+__EXw(@{;=PZJ(!i->p1HHRagK8Vd&>4Xs+#<*-OaSA=S!Qvr^W#A%0h^RP zM}XA)1tdi%Dv>=&X_<9J(3ep<;IdX@mXujCW$@3SgVMO++_}zO!>K`975@UGUz5ki zC(H<+&LH`J(mn-4om1(8Ae8Gei+)_-&1(k;9=-AgHOFdKoI{A zrs^_>By^oD2O{@1DQhxm39Xguz%orh_a!ucPv#)BZnx|7ifePF4ZMa=up~f+X31kA zb>GI3@%!E}`ws3l(~ZR1U>`+s3o&hvN7z;@VvgOUIlzFh{`=642>&eH<9B7oYtS3F zc}kAe)j~0?!pvai5UX^$Fb7F2Rn$Q`o1zFQ%P<}oDL4TM4X_My2IdBrnwgs9x|UrNh#l(#w25^1UA-R=S(N zIdcNc`E_)}oX*&*OF`Ly1Ps21$=0J}|DU!t{E#%j2s@;TUPwXV)qPvxK}p~_iWb-> zzoorB5uupLaJ^;bA~x=)8xd*Ou#!yCib!PU;IPahg@NHzG8Sf_ACI!0*_fGyA(>l> zr#7B$&>oJ2;ry?*wpMY_3jDBAz6Bo~2M%v13`H;Uoly%+8^Uli-t)ILjAs|)6sfS? zt%|3$rF|>OPvu4ob_z};;6DmOsqt1A&1!Am$~grd;P6%@tO#M8B8c6p)&PW=91u?t zsWI?CeLFHUq-$+oZ4vt@in6V(HgjA;FQ?3YS>~98$gB-{4#S}P`k?P03WW5{L?OiDNkA=ZH-2IvHnZw=ST|rWw@Oe?o2RqALzl} zB6`5;P%;0lC@pVSYGs5}J|b zB76{<5!ktVg_Mix|2vU%f$yE@oy$=D=TB!I0LDL9gz;uofDo-d)z%5Zn7ZH=gCrss zfW(p?6@-!`j%=bg0wlmgqsP)wfCz)sYue}(0##!m>fI<|$rMCHlP&SJaPUx~E!L{Q z`9m?-^FE@`$~dz>b3crerIvm97lEmShlGQwpq6HF64I39@%+7+Qy^orrFg8#4D|tS zo!Qkr5Ms4U70m_-X}=2d z$1@LsJRBw&lQ1=^yc=GsgArHtwm{^Y3-d3@JP7r)wnBwoaB(*m!1SG7RMV#(xB)8U z&h%R}r3tI98RHAS7k54 z@AJ@1LM!lY^)fy?*O0vsBd6g!jy;~nknq*Q>C>mf$?OHV5G+c?Vth0Q-+tRSzrHzq zZMFvU2f%Ub&F(PxfX5%O{@0*QNJ^mHr~^DjU2XQIc;JEPVO{oe+=ha`Bbof2L)pt} z(Airo>k|ZE7}gfr#(_jwRV_|-im>yQc@+VWEmF7x0)8nlaD32^)RiW2L||hdV^8bqH!u7E`th63nj22d6Kw#d~IrHs}1K) z9ZOFif{7|v#3%S2M9b|FM`$7(v%E8fXKI7NZAvuUp}co1d5VTDbEoLHMZ?=LZP+pT zj`RuC);>L4+XHJRNKt(VhCb`saTkjwfh%db-~cOfhSgvScHZqu(YaP3YTQ*=0#v{L#z=uh^VdK#cxk!K zU}f3@W@+eM-!|%+@f-p&CsEenx zL=&;1b=GQ2l8Xx_yc=P0ZraGMA4(_io)*v;qZup z+kc<$TL^xhTSXjrbba=U8uUaT?WgJRQ*p+*Z- z(9ul?1_m2C2X80+LD2szJ^eQr3$QTfjsDZOf5NpA^iA~?DY~_C+|q@?tw|XWOK4P`w9t-s%!n%v9+CS zEh7YkS=dJWki0Z|9iCO|>>tJECAmeZyEJ>P7_xRt-HzIw;4e}o1K?QX z+UzxWOmgd%j`xP%urYfz-i+Ln&($KIUc*$q))|H|ufzIZ3rl~b|B${RJtf@>^MBX) zf8hTR1bJ>baNx|P*^RIOZ=E`Jk7qmCSF7fG7(V(zhB!s$0w+8TNsG29yz)4~V*=aQSV8zhuw3=zi| zqQXb~WNTXlt=T=OXLELai4-A(ladODg!l9`XV>B8j!u~9-u7u8M);;|y@W;#@WGHg z!44LsvV^-E0DfSeW#}pctq%D@*7&2bvtcFL(lGR^-!~Zw|Ic?CSoz zPkr)(AO2t=`JVUxIvoD>omXdXlu)ZKozkp?UMzH9n!N!x!L(EX<@9NF{4arg37o6v z9CP5Yu53dMdi^Dg&C5qG%TefZ(uhVN5GV&jIcZ3)X8jaWpzoqLboVG~wqbLT^V zlo&jb4DJ``Ij5OWOb9p&6DwL$4K;56YtS*|`=M{YuN6F1cJrOtMwm9eh^dYEr3YR8 z6qa!qTL~3qYa_RcOLhSu+;$UeqY{NV6Bt#7IKz_2n-~tb<7mEQHyo!+=dCg$uqYBIq3 zJB!}Ugzlxj16kRQEa{{c>B{2nD(>eN>E+U{EOZXnb#$`HLhJicd_J)fI&B4qXjJg! z$!)P}j1-G;o=I|Kke6pAuK<-|vPK&+gCthR&}dmwpOt-KFwAn576RPiW2rQ}SbbbH z%-VC{lCRaLK><9$7Fegq!>_xYL;{5)5R1HZQ|+gyV_A+fhg!yAE4M5`eaJOfuI zfKlRDqN-zGZH=Y&GFa52*`{aZ6C0t07U8_$H1z%J;lBYF){#VcRbb|TW36H$<%rWF zu%UO!qIi{+?&R?##KQJHuuoEl>ZOKC6Dc*ndig;2*JhF!2H4l-JyLocBJL7|{3 zBP>|3Ogl7Yg{)!`xR@{%D%xN%XvRzjLPV1+g0wQ)=)J7sn59N*MLd(FV=$8dk!8!I zl0pANI$8^b6`)cY#TKk}tY-|1EAbZ-8QU!}ZY7UEvU0Gy1(O%t95CFx8*@I{(&eLK zp#S!p^09h%tWnFvsBziSdsuNqGt3~E4e(kn#u0M2V%Z{8@(S%tn+0o$_@}GGq81kP zA5KVA-SRO@j3U#WG1N0j*6T5VVa$|y@AuaIGbTcUwmOz3CXbBAMLR7kK%L-wq`D?n zC?Yuqo>hl4JV(`IQ6(INv3jMp%(Ng@C9F-0xsn!)sI06lGS(5b@@Gn{N?4tjJ6nl! zUpHF&??*|5#_`3KYs^L@bQd?s)Ay#~aHB|Q>sA?#IXXm6FT~mdiwr}-{e5q|B)ho= zz2iC#kE`8AyR2ds%1@KX+2qaPh=)<)SW^~CrsIqlotVNRtfXKbr_CIw4yVOxF$|@# zC~if|Yj-R6(gW@PCcOUlLUaR?z9waS-|)rJUU=XxmTi;JG*?-w;&6DGJi)yk3RZgv z+bS!Fm;fa-Kay>QO+LDuCG1F$^a4)7TRf8GZHD4xbtHhit-_-*Ga-r=q+>=chM0;) zk<=YZ-~2V%7;Fs8cUjUHA`)*;pEIcPXnSN^wxtF=t}RpMmE|l~_fWPq7!rAC;yht= zbKF{R9nQ6jeBtzRg)h*yl`@N!%oNh<*k6x(53C zNVAOfUqXkF^hGHPw<S)o)yBoV{7X1<@}WcXqTg#vT+HGnHx|h z7xIZI{PoGiDcI?;BO2Nd7Ngy<#Sq$Wtni+^dHTlW%DbOmb_cirSD+pwJt}RJB>xNk z5BPuAf5JcD5BdJb_nhxZ-%+1}{u@1uUW4`nn7z9)+bbcqzZ{$}7Yc6+g^u*C%ib)Z zKGlu|<^7||&eYDJ99ES5oA!@}=>?!(X@F|tNmS6b{e9ip9&%iCZU8H4?89XWfr@?uQ9t-7hq7)7(&2|8id-W7Vqa2B4N}RC7h@HM&58=}u!~8suP?U5Vu>QXUZA8)! zq_0RHl%ACClUn^>^H2LP^L^F#I^Q9*6C%-d**he(MI|t(03*7|wSZaDcjkud?XcMr zuTUHhr%d8oAxQ7t!3cgT1Z8>xr7ehyR1~u%KAaJ$lAT2+GH|JD9jK#dr9Em zBMEI|S%?b7QvNZmGvwhMm3?+p~i%`D|j+<=I;#6k?Sff$g~u zKr6UMFrLOkTIorwNBXYL4rsf3*Xc-u?Ufe};W@J^k`UYQ-OLGN#7S_cOoSL+Aawe866 z2P;wQGPedjQI}>%v>p3{%4sEZdG>C>aws<`p{Jj{JbRZI)&y-;-{sj?>B2DFrP(`0 zY)wH02yNHrXvdNkXJB^8z3`G8P@-)fk39}7DhELS<5jbQi&c`=5S(W3{d+v{WWcQq z;BLO#G#@cq2_%a;0b=Dm&u3pF zrJ_r}`5G`-CJJ#hhWLFu(6`{EMDjg=*|cD74?=E3`rLr-w3=%O-#5jhdMD2wpBSG@kIYV=m>Elt zj2{e!^Z-yM?AV+aF4ton*|8e*IyQj>%yBss8DBipYE^IQ09m!DpbXQlOIKLY#)*E7 zwvxWe@K4Cbh7MQx6ayw%*N1-iz4Z((jQ7Eq+V$qtOEFk|AYRw_&x){o-=Xa z>66*xHR!L{xvaQ*M%L@$`N8;23BuLQLKQpr-gFa~r(%^wQ4uigg|VBP=KHh9V5#+5 z&CrR|a09wD9_K};khq=byFNQDEDoUDCB5G;X-E2Q%uY!tr7tgrf=)6(JO~(?vXk0b zylVZBLs9T*IXnx`SI!;jgDJ4+h z+>P0LiUZPKJSK45NZ|cKJBb0QE_lO=Ztmy5CcPPW19pRu7?NZ+k z_V-1yhb44aV-1`9;4-x-4l9qf#;aq05M;>GBI63#V5&bZdMw5a!eYw0oAB$fl!}e8 z#$A_+K9ow!I|g3bxW_9|2v#>YK>xRjrS-IBRdZu?3$wZEJX@yYiMjeg|F?-CW{C4L z)?>qYS?y5h^Q`9a>uq^uKF=6c9+Olp@_2Qgn3EM((a`>PCKRPLDxW?riw3IX#K4#XQXp6+#+FKJ!9OfVv z$}KgM(+}B|#aOnY&+@>agK8@Z0`*$7>JuVUiV;&3PtnKr3$3V4fmI-s?*+Ch6{? z;VicoC*aWG79UFJ%c7XR1u7-z|4yw)MMTY0OpQ&duL!r!Q^n*gDxnz*6k485u@3OE zs{+BISagJ{+?})QA%XsLqc$l#*)>NIa#WMTsc4ox&LvttS$>M7>!( zJLpphrc|cUSF7mY%{{GMBdkDeLbBoS_uk6dtT!7|t zeBWfNj|q*!;q1An9s>$1q0umV13(%tbUuM?Bz&>w>p3xQ>er?R4t@Xa@P9MMi9Jw2 z>bRw8CeIu2m51R6I|>AN35@1v@B&y?evZJK za_h-KrUW&sL%5qI4M(1TEONj)qC&tNk%g5JOWfpPw%hPs%n(DZj5@O^j13p7DDpNr z0wXJ(>5>W&mJA!7uS@|FsjiHk6=hLO=eUl+1`pJc#D)uBLVz205{E^gH5QE}BCT({5d;6yBYz=yLRNMAI+yR5`$6?@|{i9no(!m2-=dBl^ zq3W__V}Q!FK30s=vA{w3b?~d7WxC=zV2{e;s!Ill0QCJ|N#6g_s}TNG+C463=W5U! z412Yd`LU2&KI-5-F(YCn2-PBrnVJ>7@y1P8Kd$tmT;o-KjzD@9GbN}6CUF)mM*EL- z-tb-zq`;ScvOp2{3Ie3#CI`?wx_AfmtAhtLZb{%-I7d`Q5?nsBC~!nt@tyPpoKtF@ zt&kh@>QGvdg#nAy;!5Ybp?I{UlsRRn6&*KIVy(DajgPOwu0;15XSOyTq7II}TW5+7xBq_hIFjBBm!)&RcQSjj27RLFrg|DnOZaq3z+fvV^bDnN*JXJg z>fIs~S>QJFt~RbihkVZyYqBS5(3@_o{Oc^^8rKBKt{?ty!4W*r&>3)0vDQYG<>t0U zVd;eXYO7{kG&lTqPzO2|0s8Zs>snLKq^MH-aEr&T>KI+Na=-yJkFJjG5ZlQWps}PK z^nVcI?2_?pbeY>BBZ$gK0_nV7HD-e9%3xs`NpNP)-eoYPAR*L?1BD48`UqD`F@tac zfl-)vTGgYA=Or^h6~X701fGR1W5~}QQ5i`v{m%H!kyo$C3^VTXGe6vQ3|Is*cow>h zfsiHQJZ6O;Sk{uxUXw7e(b>Q4(YMDXd4F_1kfeJ*ts=!9kC)M?0+nH|iUyGus>->N zVjM+mopVH-D(6W`E4((%8|2n`^(lyui;?=zj1fcO5RM-?3Dd*g=ey*20^1B)rs% z3wNE0aK#Y-u(yKdfoGx181h&m-Q@ICugC_>_)%B*MIeD^q01NuSt71u9tc83y*RMC z?^p2dKZN!F0^dbQIwsZmU+>=v-t*C&X~{lVgC0F9+O0-7QKnH|uQbXN>8ZnWM}ly4 zN;DpAX=_VF;S7~TysahH*3!}*Ym2nUT9o#-cvOL2U3;jpv9UveOCzz0MbRW$;(#L- ziA9ulCEnf^X>Cyw6-3qE9&d@nG>TkNRkUy&v6g82E3>EJl(m-^<(eYoE{{*m&dmhb zAvc1g!SOk#vkw5W2d$BfO^;5bXUEbcZO@R(;KoLIW_0S{^kguUq|APi)fq{EiwiJQ zCnhGwAqlO{Lj=bUv3v1FcC_aHzOn56kp0aLvZq+tm0~{>j5aADp+M-x7k~UBa~&=0 z=%4vO_EZfzbG?{N2%q!W9ZU^(GMtsZ1NOfSe-w^Bf{gH?+*+xz{$Gs#2l>C~f5!K1 z-{*WyzH5DT5O7|&+S~;adbynH-fay1fS=V)zHqL=0*32jj8sY5w^TA9Bx=ZCs$ zW_9<35-t?F$t8%d?<^GHJSOl!O#;W|vFQ_2b0cF%MyC#^XE87Y;+v~9g>DVE=vPuh zU7dSUfUWP!oKHgh6QU=SjRp7>y61ayaJ1tiT+|*a>7uReO(lVr1_12Cb=ij{w1qLh zt8*w--&B8~em_~c+6NZ=p(V87MQtTfXUB~}aa7i592nVHq`jp*l4xyJ+LTseld%Pd zKEQ1Ovy<?6V&8HQ}m& z;QjNf-{*<0#?b(7=7q;VVD+f(d8#~OZ7%c5^ptVQ+fX|GH-~)BqPfND^5@s*E~-Hv z>hro0&Z{5#X?MJBXYRrp^xieAn{T51GBii$sYQ3)4|kXVWa?JgX{U8qn9=-&S;FuYP# z!&Q=pD<*eOeO7_`XuXLQtT@pA-|da^d-~|<2^$<@}N*Eg*0rSJ<>qF@C-;`Cb3$(^a;(XMWJ_QYgR3CWFjj@}jg z`rm#25$!3`ysf!Ih>bLNC^!w4_jg!*K>G*Je+fWBU^x$W9u5RP)0?{(PJ^7kZjq!K z`u=xe{rCAA5&S$?oC9EU>Q=MO`5bA%J)5(fK76mb%^~`aP9pqUJoos8xl7<=pvxD@ z&^ce=$hN#(l>2h(Ff~%jt53K&AT}HH*ANp#p>Tg8oOV(&xbXe-WBR((5F@ z|9;;Oe0QS{!(%nw_S{QhqooTBx-ZYpjn2&mcJ~hKs1MK2|Mu1M;2xhpdGgT7hU7`? z=I4`gYB+F5s!^U_pSv7(;xT7|<<-zoQgz>Tr zD#6}kC#Mgl#hQ49_CS>Nu(s=t7DIi;cy&Bi&p%=(ktEX5Y_$_Ot&-DL?!4Ti^Z`%6Z@0(d&P%!CIJ` zO(a${H{H2wAbWw603nZ!&VoryPtA_cji1E!ODj~ev)*LJ>n+ODY)l|tl za#sNUL}~nL0!#FG%S9{XSpP3UK_s2tqY(f>kkKnEb0yY}1$37udx z$aCq*W1DI_`#XDYzau5rCgs|Fon3qP_9bP_J1f@$D`!Hv^%AEsDZukSwU^ z%*lY_BHL0cYN?Bnu_JdQ;LwyrK5%086qb(k^ocpAb`g~12ECGSo?30~28^su>vke{ zJrrh|Gej>3Lj8%};-p%bM4DJs&iTu8uYmFk1H~LEt$#5;EKTH@!&veNGTvFD>sJ&( za{i*+bwJb=0yo4a&#t)>NG14%=FVMdx6zv* z(4E_n+bqcI8d(M#F?VWYCOvy%0=B^%otQW@?(UXV6B&4=>FxAuF zo!bORSQAE&m=l?heEQQCL1$i`Yla;m+f^=OTuIt6tH#+0d7s830cPxu$_Dl}shY?n zbHcNZ76WXtID*QIXKp5vWZ5+^C!6SRz*Apqz(Iy6Rgi!1?^G87g8Dm$_YQXU z&Pq65fg!kW3S&M*#ywdK9r-NJ89N88F~7Y1wOOCxVGwP(r6H zc#5enk!2#+U`)G-)CW#mg6Q_#M(3?_-|XJby~!@xI%EBpe6>ir)87KO^Vgl(n2Un7 zxJ9rQj_d=o4Ql^~cZ2lLtf!RJ2g`=%^1;4I`d)hMMX_PKM!RgqzzPN2sl#Y%<-L0b z`>=sIvp%N)r`X_&Q$x>fw4TVyv4D0z_1KG*jg<@vSV1t2PxEVY5iqg4%atgtjr?>4 z9kjP#iJ%3h?Jd@SzwdRh|2JGbw}c!xlg!0HtsZbIE?AM75z<7)Q3u7`JD{Bded4NT zVCWhKY3FB+fjZWMQWZRj$tn~8in=o`xfWm_8$WYwl`xX3vah_-8B3dN!6B-hGDLzh z8$#G4YhKi6oE)q^=>V#1y8tA9+II-9bw8GVE&W{j59$9%|15n+`g`f?(wC&qNq;GQ zRQjOwtn|lHUV5AK2I&dujC5K$3Fn2}BOR3PmTr>5{~WwIe9iwi{?Gb9>Ho0* z{r*4k|DpdK{;dBk{wMvf@xR)Czkkj@TmLI^vnKh z{a5;5;=kDM_x;xQU%sFC{@wSlzJKz4%lCJ_ulSzxea823--mpE=6jFt4}4Gg-tK#o z?{&UMeGmEW^Ue4se21j%Qil|iHc3ILUV4S}GU+m@PO9<$kN=ncpZb5~|AGIz($l{E zzB_!wzJ6b~Z-?(DUz;!D3;WjlZtz{>d#R7?g9IZXS3I>2u4|rp1zazB>RPy7_|z3} zz2K?K;ac<5rEry=dI?;8Pl4&Y1U+>LaIWxF9bA9=6!f3!e*M(NaQ)R&7sB**_XogYiBQm>sQYLwz@B#1#ER+I1AY7K7SVIsQc_$jPo;RF}6>i z#n}GxEXMPxvwpaKGXF4KKaqbBt{>0e57&?7?}h6}^W$*+i+mccAIy)z_5Jw+aD88X z6s~`k-w)S6%@4x$>HGj(e?R|9xMuU);F`&Af$Q7zo8bDp`7m7Hmfr~1x8{Kxb#KY9 zh3lL1H^B9^`K#gjNFJBsp**JibRN_EKpvO({@f|Jp31>avUT_6j>7ds4%0K2y92H> zxgoe7&*6NJ<#3MExi+{?=3;Q2$VK6LGzX_p)!mcZ0N3#x@W1Xz4(D|^hk0@+hxwe& zVb0v1gOh6N_T?~V_GU3RhO_s!zcOha!LX0q!3{V5+@|LrX1+y6O>VSacP z$A14Tj{TRjGjRRx+2e41;Vh>4pU&P1*MB^Vsr}B`6kNZ3wiT}D&NjjIAI@U_eCsSo zNZs>iuYv0~&SIYQWHFv(7USv2fjjxxNc)eziTnY$tQH4t zLEF-{1)D+BIaD^8+Pp-98C2Oj|}(prPN^Dya`SN#(}({rNNIJ%eB^^$J5K8 z2cpr*eT;>MHZ5s*Ht>|E((qsi{)9aXWSfYKXXmQoc`A;IwDkN5d)yKU)eA%O2If#^ z72u7BIE2Xf-$m$Z3E}34h&D|s+Ha`Rt z+#S%ZxP?U~a!GA0qeNE>kNWLQfjJ`1w`NDKLl^=okyxdW&ij+|cIa!(nU~}eU;)r5%hsq*-EMCGneM#z>#<c%H!Ab!_Y-6ANcL)kxra_ztp zHc;qH)Qqns3*sl^i7O#efs6L~u^cm}NiPmD*nHgnuR)I?=@Zh!{(1kTe~15S-(NsK zxe@&w{T+HgL{;AfbFY-pttuzs*sRH8iel8tCim8QxMSUvlhNdggawoV-x@b@xCD- z15br5w7y7`a9J<2hXaLI4)pYgP@!iew-YkxvdVufE}=$XZ2ZtDoy1|>)J~8K z=5`bZ4My4FcbDfnB@|N0UPIfF`TKL*VfhCeG+!ehg2Va_&7PVXD>`lTY0NFNrFLP| zzVtcJKE2{Cf@w0SUm~|nY$);IT(q?fhUXZQ@cbB=F=GkYbFI81w^i3rYKgUBAP6%| zw&|ze`mz4kqJAVzNS)G4{a^9F$-mb39p9TFs0?>zTW+WZJti^9ycg!Tv3`Nnj2%5T zJw7!Dg4qYd720|MmFK!O1j1qh$AC1=Pzv6&s_#-=!*XLQKGscEw&0^aJNA(?-tZ+P zJjjZ&1%l+6^s$LidUz$Q!+?`0VF6<2Ff2R*Qhm>0_uFUQ{7fPNp6=Wr)GC_*l`T2g zMU$&5F3cRfj&f~B?iN8ntWnVx2-t>;v~HR_>Yko>S#D1adXrMLN-eOI0S|Aavx(e* zrVth+2LhkOE5h(xZb4FU#Ew69O9;?#a>n zM#zFy(s6~(`1tG`GxnxCI{>u_=3Eo|I`8TYYVL^U6@7S(XfPZSgTPOl8Mq$rL#PMq z3LX%&U^S>}W$M+#&rF}kPu8$`@`jtjvgDzn%^Pn2FG9^oTI>J5|7rg=-~WZRf6X>o z%*(kuz<{xF0qZ)X_Jx*Ayy{vN93iVA(Y7`USE~ldqX%YTj&k;Rfem`>>>Mu0Nfr;i z^oh}-IanV&o7^I&XJo)tdw62>!1RIS?3tJ4Zikn;;_a1=MrMvJn_3;DP@ILAMnkr6 zT#h(%OYSyk9@$Db>&hd|&Uaqm{bIF$%(@u*aOlb1ox2rq@>d;876MKtPwroJcI5Vz z?888ZlJ<_R%hZ=lZd;+~|b z+ekZ^Ho-W7`|c*z|4Y#45zO=*kOriL|F`}vzF+%3;ydPxLGa3OPh6f$Lm#z49_rke z+5<1i!*cqqmM$r)!;MJ|6#8tLH^1#YAAaW9f1OQ_oxls=($76N_+09_p68y!Lz5yV z=%b!Y1XB)dUZiX2{p;s6V-g7)aI}p+nE~!d0yi>G3tY3#lHjy zHg|QvApiE<0YGzsGc+O8Co^%wG;Ahjb$f2q5egZ;GMd4?W;2TUWNtsS2M?IYP-R=o zOr4Y%8t&}d^DK4s*ck_V;5={cHZZiC!_UgIN2X_B5$W{A30Mk8jWWJIiwO9$_4Uuf zzscQBLgqHt*N4HUzDrZ6xy|8@+=zrU;yZ`&vF-A<(+ypx<%Z578SoP$%?1h7JKR#Y z?Y$y*w}hHC66Nq_KzUj2E(tZT&`lo#H9Auiv z-C4rCF@~An7_owj@~!!AbE6_9VV}cJL%v`=)KH1Ok~9}rZV{E{FNsvN6)S}i3!zzK z4fYvJ{8o=&24OGGFH_5-PyO6;J5#$l_x27CKyy@`=GdayVqqMYy9NjPD0;XC=irNsy+b|yyNN#_2b$D(B!&7z zftf%ocLY!R(RXc@R1P#h)clb8gdbWW@%GlXmRKqlgA&0TVIp@J_pM4K100DqQ`+CT zCU>X?mn*l~>Pu)$y}COetn8)h zN_~4Ro&eru@5TCGi@t=UFGy3;X8()+ulrx`-{to~&0&}bm7E!~dXOerLQG!lu&WAKZ{4aSn1+8w#$IwbWvO4LD8c~f-bCZ(>v05r{?~1R03--P0s!8eo0d@84w!PG zm8QU1K#H4kQxbZ(cnXbss!yd5lJCn+LJ<{~9_nE(jfVnYFhFirw1jMIJYWy;U35l( zZ_7M~FpZfa$7}niyL9cQB)vsnH;<-~2x>uzE)UPor z%Gm_SB8X(89BmjC#BaifV6EePOYS}xNV3&kSl>4@o1Ph&n}Jz$RsPQy^q|-9T%kv< zNBYvhoCA=Z%-u`IznE|qH#u!qu0mwmp(#rK#@tCD{}!#v?652(yxC#mVw9fQmpcLL zN|@rD@3#Fhvn$4A&e@nwA&CfM{a=IbLel4@+ohNJ|JDEde%beJ_`>EM-&XW9^d5*R z-*x9N1arr_@3I`0albvtT4E#Yj=T>@WG`JH z?xPJoLwF#5>Tr5C7y^GoCk~vm`)m9R>!$!tTgDq%XsMQ?Y+$3el5z z&(P-FgIY5W%uEe+b?!-Vt%$-vKkp9Fy4s#Q4cT6xmAc)+;mU4EcMj1iJZ7lw@!SJ| z;#LPJ45;nV+U6C{-Cv^Rg@(7mvgM`k|FHk}U%>Z#H~PQf^RI|~z`OH!vou@F!jx5M zYS{#aB?iyYCV9I8HUO;4CTwoNK+s*BAL-A-UZjt&t_*HjNu}8@)Qa6 z^asIcC7D$?JTrab*yz~w)Y#}8nfHNsKni_6JqXNh5fC<610a#mGtc0eU~qV2MC#+$ z^+PCaNwfhRV>cGCC~VRou9fN$(fPtT&l^AQ$ol z68?fH$>zEBGv;)v`~^H!j@@8NKYdO^@l{2{mZ-pNXBam1RIrrC1 zHs4iG_WJDGqisGZ_`-<QKN4?!!+;^RRzycD(HDK!jLd=&oR-d0nAEcACcLTWC*r z1!MSZ3oXDHy{~6*cyDJffx@eW8pV?_>goV%p)fNS9DzeJU`>?Vs4x#j#LmsoQk6Pu zgVMqdiKnTX@N&ij^|yAX22+i&Gec)zN=r=p z67Vt-B54@uEz$P2b`Av?RXil9Q;6VR($^>yqVTrZ*a-L%w>EZT+Xi;Fw2cM*pD%u< zQBgZ<${-qvD9z+Y8j-S%_&7UhX)pyMn(FUL4H1OqGnb0CS5Azt11>FqL&c7Zazc7J z>AkiXkCQHCTkNtWUb;7M+~Hliw{YG2w$*zw3`%%!;qVc)a7Kvt7GB<4IBhR=qYCt) zzFvF9R<{BbN0N*~8P#|Tuf%I-`8bx&`goQ{X8{eij*TLE<9{}zY(%Bm)(hVFA0PE| zIsR7z3x9p@@|}P${{F3eE3(W}cIWY_V?}2SC-6j#)r=t?l%u0$atOv(w&vmRv3VbR zV>2#mfCfTtn$x3V(}Z-$rZIn+gzhSu9+RR@P(FD}9uDuy!Pkv+mk!JPijgi%c8WuK z#m2w9w+`)CUyH#@hvRjNJp$?L-C9K) zpmX9vMqPyN0Z;q^qE=m?_)t-rIAS&12oEUYVP%E8e1Cdo`T$;Wsvc;ePga~E99GR- zSm?>4OdgiGDWZ75%3^ErvXqcBlDJak?d^fB+yGj zD$1?~gBH1|m1SdP92sQmf*PBUpZ|=(RaD>@QgTEs*a=4zGyX2yCIs~Vab7abQz^3w z7#RyRIHKRjxuBhkHy_3Bv1!1KVyu%TX3?(?9$)vjMM^0p@c z`#}dBjJ;J<-{|+h1IYhJz8>END31nM<(75t&f{a_wNdttg8q}g?=|5CW%%;FbL2{& zhav2H@IMTX6eRTAkvu*lelKH)Y(zzNtOhK0*hoghB>`al)pMPBI7l8&>t+M&iu^vj zYE4f%{%ph|7?1Xc-WS^S@pvANf&cjlj$~O4ZI=K3>82Y9^6T0f6dMf19dziRzV1)9 z<*%qg-;_MwR&$)k zH=ro>xU$$wL%e3B0+=znyzrm_t zhA^>sbPZnJSeY@fmJB)63_o%g!ljb3)ugEz5mPp z*Z4OsXwP3J8~FZ6Dt`lPt$8V*w>8e;Tg=X@6Z&{xHoCVG-pV1`WIxX@;{(P=PU3|G zC4olAPMnye3j^+jg#+^b(f#U*1ocK2BB&@0(8I=OvS@)|6H~*|260hCN%EdFIJ^?V zh5+jf?Vz2JYnNKhYZ&+xdhV|L^{_xJ`y3TuY{LaBV`X=ZM$q^S7}R9u)c>h&yJF6aTE&sP3~Ja_ zT$>@WU|h5+!j0CPJvA(c8!MJWPhVeZXHVyFiWQVtcC!B`dIR$BhRc$>M_TjiKpEIE zU7j-78S&-TL4b;@_bRTuj%c{5My!MlBkeyrjr{Gf`^V|UH30Lm{6;u`X0kj3iVZ98 z$Y_0L9Hd!U5r}L=>A0cOy(q9ohFazMhw~fYq%mzds$Eah((sEU3DnrrEdbfK7gnq= zLK~lpwS6VT2Hxz}m-%LgnPO@Z%hMbvfcFZgiM~bs;x}W9U@R?Ema+cVpf4loN&k=h zkAi3AI%tE!?%N;}du-UHDGMpGvTow4XVRGSVPrcxP9=R?rT9jHt* z0Ol3SX?QbG?e;73L1=HbR3;+}F5;XuIdNi=RcK1z@q7dD;qW4nNAslmUyuA>^t~0v z{p!u?AJ1u>N0){sf=@_d01ny3+qs|EK(~_TTLf`7iQ)-}l$Pclr)O z^fGYsZTT%=y^nMANY2$78Dqz09n-vcQ}yvFI0Kv09>CIK@0ygf5^9d1o*VN?38gF&H*JGbQiu*4h&B$9uz`qih`0?z ziwY6Vw@XMnpp_RQVpRrZ6CO`tL{UkZ&9=*6wv3 z`E51mZKt>l9>&c*KGe=y<8Ul@FA|?E=v+`#GoDKGz>zT`1lDLRlKX7&a|q^9&)5@j zvMAy193Px%^IPUH0!y~QBCFhESLCo18*sSEM3PMv^sm3QO zF_AX2LkrP0grsf4Do@%;4G4Valh!irg*)dVHZ!hFjgEWdL8uYe*v=an^mtEn&y}cI z3CBY8zwRvWE9<1#vjJ7H0S>wgo;_CWf@hC)8i^lV^-MYcOlWujbWNWs6vTePvbD*) zG|RO;6*$Medh7~$ll%(JpsNJ0O94{p^IQ~b*AwR+ZX zz1&U+o@&`+;2igsPqayn#LBEjpOw?R0DZ&bf7Kwod^S2Z zT_&8-{*%~w9rCR(ap_Z1y7s)%rkB{s7|3t18Gni{#-*EP_;tGA~M*7jHrl~HI{ z;#a#5;)7%1=TI6okelk?k?(<}Pud4yYD#%-dTw+AW?!45YFdm6yiEk5 z9$(w_`ECjEGvH;4BLq1sO(et3`P~vq^9eW{FVBol9h{ydCwoOhK%Ph&YS@_HC7~gG z3Y;w3^np<08wAwX*U7M4wp-WUA6P^76)=mrk@cI0>JO9#;~{|%qs!PGMM$P?3} z2S?KP&84Si$ET-=o`g`J364E}w!&yW&b|@h=kL&U~j1)vR^4R8lr-Vke zf&`UFsA()cGQLxW;wV_I@io@efCEv(Gky8(HR$;pc?xgNS1<`nHN1dHaAjq9(}q); zrlz6qpU3)tfj^6+zmeV~y;8aeyq@zou;d*0XfQuegMOlI|E{(Ov>}kywO{Z~GCD^L zCA0_Y%XFXy@7$j62Mc`xH+O1o&>%!%4Uy7J{^6$iu$TR!(4={U(eEvowi8@@qidOqV71`FV`O*Xn<(#-2~ zh0<0d*T&Y8rGv#%RmjS5vSg^73?V6Kg-tA~}KR@z#ci&aqtv}9)0)!s7K5`k4wKf62^P4z(k z|IkxEyJ{#Nz7X}p6}&UGt8;JfaQQt~8}eML>_HneYVZ$=N3&Q@XUo^w;uTia9w6xd zAF(QQaxYG*6AbQQsxDfK*ZXi^cw>sy*$jD2kg=YfJujpQA~}Hm|FMItR;AiID7Oh@ zwW^<~pv3|_X;8Vd@}&Xv|J~MAy?BkH_exG{znFg{*3U2{`2+sx1sk8#J^}BXC zn#HYqFQjomc*W{bSIUxO)!43+VbfQH8>_YW?a|VTt}C%!L8RK~l6CMxH4OCs*$S+ov?k6~=%Ut; zE6OOaUNOr+P$bFXtM2;s74J$GDPM)77FAUA_3p+X<5DkoQWrA*w@};T*`4!OFI<(} zwV;*8zNmUBlHnyDQJk?#}K?z9e~N3v}4h$_K{CI@Y#~4qIB;7;K1dL(B~U zG`)ZmoDc#y93hZ{yaY({0EciVOa1{TyuiypFX1J5JdzOnzN+e~uBxu;uI}lcYpb>D zuCA{7>Z{*()K}HV7`^~HePTxm1z-P^Uc|sly;1M=-FxbZtKg%(!Fyy>;%3qw^=OETiuRzd4eKAyJTN)1gj< zpW04K+E`EXm`L65pzySjh}8v)-gRv0J@pE<-1EK(oFMl95Vrr*(DkVFNNFRy{rBbK zJ;kZQe--|!@Xo^a!gBPN=pAq|-8OOJ#_%giYd}HjRoIbZ_;n7k+3wfZ?1!8f&6eh#_SrM^Qxed21vI3@Xb z-H^3v`ou0n-6@b0dFPznVH2DE4wd<=0SZtVzcT4Ubq!`;&SUSJA3w1Zhy*`;r?Sjy zGO0*}8Ihp^yywp2f#`%^2it$4@b?J*+}5`UJn*~|d&=mM;J0y!dQE^5!E2CMwR|mS z$C2Smja*56`67I4TTj@(L==#>JaTTOhA*50l_rLud5cn*OMNlvf>kj+ovfMq1BwcC z-HIs)S$_hKQtAzwlQHuhfyAjTaTu_u{ojQOclE9EcW1{QES=a3zXzbaFW$OIG71o- zrZj3sL2tdSxdl?YA^9CV9x_(3;>Irx>^PF5hRFxUd4!oQGvJM|aV%j(v5d`z!Ze@-Thi!u22`U>fHe@&GqawND@)Nr znGND&*BiM(Yb~M}B{rbr|MOAd`Q158c8IGt-Ed-G88wB^ZQ(_T)(wkM=r)fM;}5!( zZN^u6PZ!hiw2qKQF)qsuUcJqH6{}&6tkBWZ-JGb=|0&joz ziMcZR;E;U(Oz*wuJuJIrD@LKWqY#K}KMe@&cL%{>1FXJA4DmO)+wrVyF)X@CPcCRe$^p0loi+ zx0VT#32NLfwclIfjDya=T3oFclFDz_yzS-hcGOO=a}(f&PU! zh&m)q4zf9bEQ=jgT^$*o1`mcqIgV{(Vq$Dc_vli+Ha`fL2uuwZ~QHilM@*Qdv)8NZ)|eBQJowgt4%hh>b2VV zIO+2^{^=cR{Fvd%)!6<|LvKN)ZT zGm(P9^?BX(u{y7ROnW`3e^ht9J^>m}+rM3Ry;g_!MCkR~wAUH^b59&8!EZ77PhXSY zmV)0)I@B1c&@`p8;>6(+dYM{E`E8|_oH!J2YG|}^A@AzJ(DmvZ{D>95{wno)b!={Q znq6Og;?@$nUSeVmUKGTS9-k^dIZdDcE1?%6cvAywK#KQZ{hxLuv=(rG!ErRb=#}-;t z7>9(i^XTKUpT;&%$Ek?XD(8WwZ-f*z;-`)e<}6?T4{Nbh7zN8-{?MQLcWHGB(x-=?d{G zS%R@EDiB>-!A79OwUraAX;_2z7xA5+$8^1>gm*zcF6b|Gnac=GaPw)5O^&5#52iMB z>Fw?cv|PEH9MW+vaFvb`3X;%m6$o(!Fn|oY5L?qPKn^QMTb7cpNex4^Io_zQmdd(+ z-iJL^MPP%5TBlRSg{Na=N=8>`#dTV`{`Xac;I9w1H?M3Cl##bx8$J2X0UHpPURcMS zKLJdL2c+uDU34UBzN!bfX6jGEQldGcBn6qaqwNWyJ=F{PU~nEgWA`wu2jbAN2=V_H zu+3vWdC@*}-D=;hyQnYNqBOZoIOJmd#jjH3;VQ)Qg<7fml_*3@5e#9jRpv-f1YaVe z$g_Jp3QW}JcETDv{=Wmk?|gL2_U1j!Q_E=KayNzxZaJAjrBE)NgK^_1_F5}Pd)qAu zahp7N!1(_sZ2Twg*{Ka3rHIr?l1#QCwFE~qquLO3n7h!2NbG75RwjecDI(E6s)BTn zSAAehrHFCkfANnI{JG5`(1QrPvEDqbjNU1Kw}d@}=9YZ8D^{J!>IoSC{|x?rnOyNF zp|zd&EqL zh`c(tD#+AwNDyimw7@hUYejrisYKc3<0onFOg)g>kDjtX?EfWV|HV3jKessqED*T= zrOngf%YQG7x;^V_AwMuDF5FX~_y237!c&{PxT3_GTI6+We{oN&#*C0W;{_MwXT2iW zh$bkLfhR?yi~H^7*glZ1;SE0qO`4IH_(>)YAIVYz8P;G@0wF)$)AzK=`#wKGgkLb4Y=bBOW|K~+eJY+2Vf zRN{o`b$V)7b|t}FAwV9RrY6QG zCnu(=Qx+x^bd0gg`Lw9b>X6RaSb|?6bsMxkuTG#8LvGFxBzUQIcnYbt0MyQCOQfcl zAZj<$HsXorm6Z^w3ByLm4L4F0D@SdO76-htMhD`Gfq-3>G*rrTh6~UVK?R^X!{sUh z;7FmEXllF=&J>0to(~DJd;l;jAzl>>mtB@>OPMxW8zaRAy)KZgPtuKZr5~(u4PHb> zM<7N@g&hDbAypsRk7|eHExi5*zZQfF*P<`MAqsPuRO(bpKst{oCNG6jG-?w=tC}w^p8($6>z-3m7+@h!?ZwCest%@@H# zX1nFG!34GAn%xF1^|f|s=;3|y%@>x@gNM3S;C!XB2VGf={hx-uj7nc9JyN>8w5_zP z_`Tw<7WWs=E_}c6Sm70gGvQ)yY%|T(@Mz()xCR~Fb9n!eLxV%Z^G6RH8mzF>%4luq zf<~h;%yWhtjj?)gx~Vw?bk0alXSG6TLvs)aEi)1F`4AbQoZ<_^!xO{s^Nl0b3!AG- z==BL`K-UD47dFpNTKxi{`iADpm@fF}^3M2OsN*gSvo4$`@<7LkNf;FB@V(Ztp^>#u zR<3*b%({Uq=jY}R9GV-f9-Z5>|JcC5RU3DWjg4J6-8{F1?&1j0>Xvm^HCKou4y~&l zn>IAhk$TFCu7P39hSgcjYNc5zq2R++3Jo#_KBswh30 za{RX2=8l32MdM4K|6PTOZ$_&k%>03U&5<&CL+~`!(IdwX?;phDH5T)5HR0B%&e0n9 zlf5;P#CnSp+6$3QBqc^$#(Uf*Sc{f=-7h9l*K-#T)TD3=IJ@uqrSB0%KmsjBzPLtX ze4@6l`tth@H-{k#*u%}kshMIO6kg3fCF0orm!Wm2^v9+5m+mbdDx86Sgg%IFgsix2 zMRTHr0*~-SWz&xBTL+owz%^8!7}~VHISy|1WR_b|N~!0yk=urTL)r+9v1BxA5{2LR z4WMy;vtB~MPuIU@?&y)d2aoI>1g}juaLz+p5!!s;wapr+-~{KG7p)EL+PZGt)$2Fz z!biHT-?n}W9=n9xAQ^Fy7OGsZy0ZF$3L!Of?Uh^BZ{Eh5#a^RvG1&(@BKFl}KhB&N zEwj3DArvEfa=8&YUk%r*v@VpWvlP(5Uhrbt7VT8f1Kuyzm354%aD%uOP@>pC0%9s& z9U8}%?>oI&g=cbCvQAbav1M4d8>Ki%s$c&q-7-P(#mx&!=pr2=SQ{(NHDW-)@fsbg zPc|lr!mewMme4(%!2FTGHoUWrP7 zRr=M^Eu~uVC&fQ1zN>g^@%+M{79J?Pv~U{wCOQEHQf<@C88I?>0<$2yiQ7lOQQ&|6 z0g^xZ_Lbk+G_+~5d07b^=l#;u-Ld)dD`x$gj6!ATiJ{5n#$+|YRY5gqbGo@9hTpo( zZ++zZwQpZJLit@E)2iP^av(du)k~X~f`1EMW72e$7S~;%tiPgp36KcXNLLbbUeRAL zWdkbkw-&tk#j*zu3)0M?kM3aeq7u3$N}fIm5JdCB61pzFC>C11xvqqQmlZVqt1^)h zxXEs+xweFY1=}Z{UK3Kx>WHeUn@H91=5z@K@2%^rlAe%$Q*|HOG}WAnZ;@A9i8tsR zX>qJMSwg|Wh~J`)V_qMsp4V)Y(DndB+3Yyf*#1vL`{?|CBh3CkSG=n@UifL@lZ87A zb@ac`hu~ss+lJ;&P@Z5K{PfcrAw4zn-Rj8qzFK=~q_PO|nyoxl8+mGEk*2R4`jZXK z9hOAC`n}3iP!-4lk C4}V|%-nR*nt89oYLNyG~Y=v?%5@Zk}SH=_BGP4o44oqm+ z0V31Q?V_X6Lb7`3yVdnO!@b$i+!oIOuB>aDK{4IjYQ=y`<7|L)LvxFUfj^Wr3@{^N zB;aAMIUA%Zvsj=n3lsTAWpn@pef;zSy`uS2Ao5(UuUs@RGwmnQJbvR#^HX!*m$El-k7eB)h5Skjj748>eys$ zVrr_|n4D^i3D)e=)T^}zhYih_E80!Gci1g)feNBx-eyDdIvo*N$(fx5e!@>(IXhAT z6WP$bwgn>C0TCkCSP&TjO^qCkuC^pXl-wUoz})%30z<&X&0RpGpjwK83Fbs0f-~r7 zHfztt;s^|=br{nAM&^RX|C4n5-%>ig_|4*p;x)w=6uwnx7WNcYK?LwgbQhXb+`%Qy zS3%ps4}ar$FxYhC`(uwiw&t-l&>IL?aojf9yjAwML3M3>u;#mU_!}WL4ioh73nAB8ndam_xK!dJg1Rll^kHyHq4Vqbgp+ZStTb*eFTR;wid{-23L;orVdT}Dbhu)_ByI-o z#3D3pC}>uurKaI{pu>;JblN)Ov^-zOq48yA6|wU-PV>Un=;x&K0XfJB_@Ob6$SMdf zxf4j_Tm9A&YlyFSi;Ig}HqGqV0r#yhg#T;C#%3=2A!IHt{uKVtZW&xpPDmN`$`?Mh za^>O}xsF#Q7T4kUzkqfk{Fl-8?w2%=meI#9VJPBAbI*VrZ~71zj7$`Vp-5WrMAEu+ zI^A^RQ}(f7I!ScGOZ4j41hM~9*ycq$;HcBg+^w&>>^KkYX*Z&xG}}2W$?b;EI1W~^ zX0p<_wGL}iGD``=gJ<2*le5Lezrjzc(#;?7{ZK$1=3@c?b^I^>0KuQz90Glbz#C6* z9)n*9BB_}Zc6RQ`5)rN`jV7GL{Ob&Gm!l zgcCWnofFx>oWecfIXShR6WLzv5{&Z~WEn#z zfR?TIRgN7$1n(UV4CwClg~}0`i@9r))TXV7ZQXZO^G%ac;+rIO?|HG@PT<9vbQz#pn$IHTV_30EH+yBYvR#e(ne5$yr@VA9K z(U0LYhwa{C^Y!3L_3z z#JDuj!Ekw3n}^FJ!-&Qnu>BW{yHM#Y*tyLikOczwZuAOebbqvy4H+D<#89s2yqT@S z(NIn<9V%qg1SNre{k=DO5F6h=6Y2C)wZS_Qs?A%+4ES595Xlea(yFWyKN`yUrRn_t zuMmR2zSI>!&QYuytd96ECX&&%=W%WClP8jGhO6+#JW_W+AZ=g4dr zV^fu}NziGPqH@kC<Ftom>?mQ~`k&r-p;v-?`uw{${o2>SFDWVJ zI$IdG0LOoX|NpE|4o)*@!^IZq5C9=0Kp%?YiHzA~0+}kQ1dS*)@oAdcY3c+`C#VfY zdj=H0gRFP$3%KxrM;m8tr*kNN2ZBRud<~VaT>@tA*OEYK!`BW;CY;7+D2JGau3wR=X}Qyh&yJ z6DaDOrUDFuFE^zj?XgxA5gW1<7EPz=YlHp&3lHOR>p9~uw+5o1HG!t&GaePeD5Y3K z&U$pf*yTB-TN-g0d@ULiB?I>VuWh)Er7A{7eNf2;=eajPnqsXeKEse5a2J_sp*E}9 zqH094r@P47RdCQ1Rr6TY+*r=N0n#JZih_V4TLr;z-a>6wH4av=|9>;I9-nR7NIWH} z1S6|pDU~swu-YyPHe(cVg~1o6I1wZ)F0ob=5gW2C2;w3w)Miz4>vir85R6zW3ak08uhMRJ3XvdWrKx|dx)7$s=PIaCHl@?!!yIiwl9VE_M@rGp5nMT<%x ziJ)zsYN0l(+9Lm)l~5x021tvn6~*HivO`SjGg_$4s`e+WdbmQl3mJ`MSI1O z2lxLovwj^SiSzmsZ3YADU5^@6)Gcz>#qd$AwYlX7>%;UzIbwtAll-B=JR_=B|K0y5 z@Bb8jhTzX_OALX}zrs7|By{h?>!Mz8^T#sv3#Z&%%n9b?ECx&skp#7U7JK69N57}6 zcO4x7Aol+;wf|vM7+zw^pS-&dUgbTbjD9KdBN$k&NB3m#L3LkG;Nf9rocuQzG#@Dq z+Yf%~SX0n971f$`&BQ(wmRVoTOzFB1?kidNw@1Bu_{NijbfVDKvqVd3mAwB0KloQ% zgq_ZUBh=1=R6#&BTe-sWQ_;XwC2)yYT-m)?}aR!U&$(UsRDL%nu zum=r0U|sYWE+vw|X=`)VH)>C=Z4D_bnca|5uzSJK&kVw{ZAAlM{{Nrw|L0*)LOELP zQ%jk}ZN8$R5$>d>kRi@cN}3cQyAiJy{1s-kr+o&zu8(a~j${qB!vb}1sCoHn03Py$ z7F%pgpoEhq^HYkE(`3SF!GPP=kkU&N7%gt=1Uia`=w?s5G{##&ARQlTA@=_-YX6rZ z1b=C_ho`*dW%TCbZdNNu7biO|VTB*vX^T8|TQs$_A`OUgGFbmBqKgpvpLmyWdqc%L zwT#{_e;~O{gS%F54YP5CmKPs7(;I;A0S|Y=NhRS`{G4#wdfd)a6G&Z=HJz3~+Ip;A zz0Wo11;e^>^T8u~;akqNA+lu8X+a{YCj3GO-u^=@FQm)ye*aVV z`zi1v;c@Xlws-~uCf^C?%QQQ zOlkl0`M(=c;l_kxzbkHqz=LObr4WjyMa1=NIHCSO9d_7AP!Rx}3Pc2G zgIp$mo^#;vH@^CfFA_f)BLJx%$@^W;u-~!qKeqoOdKD^N3cGwacz*tj(DU;aL!l&| z5nmn}@!;oUqV3dV6{5Xk`fX^@XrUr6UBoZoZVkC&Y`yC3#9tzv*&%kSFfhP8$h{YO zr^DmX^6wB>D7BE58%P}gw!s8PWVGAgBF4w)2Sj~?Cp3E1 zh=e}kq4TBNH*XurclgXJY!Hl|bZX$hWtNX*b|`Kb9I{yd!}fnNdK4A!DXuS`RQPh? zR`j26+L7(ud%PEw(G!<*zq4WwMcS~Rxpw2sl{}i{wf5krYS}ig-{6kGvPWjT7naf6 zp2aKX+T1f=>Ae7)>iVFy$`jbeE1Py~-x|E+haIWmf+>6Gi6Qt~yJ^yUehCFPVJn+= z-ni$+Ju50JhcOtHQTkiT1ekT`p8Ig(MtU~wJ+FlB;+ze@+dUZh&D&;YcI=$lILogH z(6Wou-gB+$R*v0%@WA}s?qf%eAKf>%8~?ob#`|9HJqLbPyu|54qkELWQ*z6MU9!_= z8zPh?u(pwU{SO z(^ico%wVu7C^8|X84=;w5X{y#3uQ%$AsSCuijDLC*>&RE&?A0=bKY#Mc zZ(vGNIsR2iDVLqRdfBT%R0aGW6%hQ1oRIWzD5qX${Ia851adE%nT5}NR-lzrSxZTd z;s@M_9k9ylw_S#lm7{aF9o(~z-SuKu*>RL5{G-es6J%|CYN9b+ZPcn`Q;muGWUV&s z_Xm4lz95PhTzw%d(j$Ad@%+zmH+}h*?Hl~Jr|LM9f2H&?{BQ)u6+Qhl6D2-kmM*N< zA%V#Kzrr=B@EzE>Eh_{*wBI|cjJ~#&3o^fZ3u4ShR&QWRciN*b@m^d;@42KC?Q^}1 zUxDC7;gK19i()O-?!V)?`h=kF`T|0(Pq&62$$8D((Ias08y@tRAF!dtD?%+(GG)sq za(;gJTYlOKe&e->UwIFvpI5KnvTJ518MeUSB0Rf!Hl}EVk z!^+B9r#WK<$HPqXJ6S($WZXG~Z_f4PNlt37=Z;gAjoK?pg;|k(klgcyZ%+AYNbu$?o8dw`p~!j@eCr&cS$v0r=qX~Cb4Dn*3Gl<==l_E@I3jzrrOBBz|^$2B2``J?bHq4Iq(>L zu&`~@Ftj-^uzefh0&_C8dWv<8oZ=lW0{Xq~Qm+E^PvVLZNxyQ-9KM6Kebc6$Gqa<$ zyYH@GQq$hq*4^_d;J5yu{n6UA_X|?pC`f%+S?iMzRK1s!(Ia!5_cq>i!0gk_+DX|I z)cP)*$yyVREzuJj5@^~#!ee!_Lu|#EmYRGw)^ltzj_F21Gs z(!#$KP82qve?T9D3t4R&ybHjtmT}$Ocn!Trv1{vx-bWs{ptpUf!vMxAYr$McaEE;N zK`m>IWF4~8VIMN5G^T1(qhQvU#5mq|d85F<1p)(-$C4|Lj!jNZHfZI_f${PEhv#0s z`{03NM+#GiFe9)L*1%!x@Sl(Ig;0jY~DZ2u{tJBi095}q6;xHek zyTKa*x}t!i@Rj%lx*!&e?<>7QAQHSJ73qCHI@XxOg225NwIs^DPkXB(Gzb&I8y~h9 zeQ>pNQBH!R37jp5a`SXZ)Fr#AxgNH%*{_#{9$H;cV22DYZwuj|344t zu@*6ooXAEtv^AXrntE@^RZ8vlm?EeMOsgPI6uFIl4a*<9NUoUppxj3%X z$zwlJx;X7ixZ8(4)?+qQE?IrR)B8q4g=1-jLag^GM)*7(S|1I2qL;`MGA2oU3`Q`& zb$-!>xd9a9`F{k@|6dEc?6x-?_iAPIj^J0LZ&Y8Y;>O13JleGdQFCxQoAJf(f1n~9 z5S|EM6Jn(3kO5+<7d?KuS1qG2t>lYEtpSkh98m3Z_Ya1Q<47S@$z%TUUX&3NJO<0+ zN*cGUqN-_do{hrBbd;?h#IecxMY{@mO1}ArbL|_52Q)BK3>pL7*A`n$iDVP0d`so73_=|Dk~TESw8x3NC6oR z`JuHO;>*5woo0z>uCT2BjwllbLV@P`sT2xqt-LuKlFUbZV@x3gduCZFbi^JwhPi)N z1ke8qXcNMJ>9=>U_UiB}zt?3n+hsg*kJjRHvJY(7=`zH{NRZ`OPxobe}d} zGeW%&GFpAGg0hG{ubG#V_V5>sJwz@>tjS#3yK0>xfMtR9d|NJuHJG}?|ff{q0#_Ar^> zt)5^q{OlXBt>78-Q0WprRmye>`+ze#{_jBu{&LwKez7+WKLD~WDl}MPRwFovKoBgY zXh?5q6YGSk=Rq%ml(YZAT6frg5v@hV7s4*l_W4P#aT2=sq1zK$HrElJ@J9f_xx&a7 z3Q~EHEyZkbB9D@sDo^0oax_mZHyRT9yf{zDZ1GlcqB5GA8;$X6db?7k51o|x!EA;r zQs%HfW#&c7;cT{9@D73DIrs1LCd%mHmnD>Lm`RSO*(n4?cnZ@IA|pvuIkgeErXa;o z%&Eyvb&JE?08y_nn1>j9vI=31tF*4FKvdTjYZI<5Aq%!JPm{dDN@^#ra6JY+yTXnv zAC7Bqn&q>jdR;8zU(*z&SK@S_C68u;jQ1em+zvClis^@mFiduQh3m1Nu`BFI^TGbl zC8@0BNs-2bjpdNleuZa<*df|4lI{yB6SY!fBYI9XP9rTQ?!a9IId&=_n@mtUpr|R) z8wLgTf1cQ(pi4on6-cbORbjhew*8)g-^5|P364y{>=<0hY$%jnXG1=fhCkf62I#gA zHw**~FKNTVr7iUKN!j1 zlHqPx*$E?JRoHn_43~;@54g@2h8hdgw4N}7{h!Yijvi$!eV4!-L+a2gBqHqqrtubb z727`YwIDtQFgptH6EBC)m21jrP{U1{11v(Q!6iE%YJ``|K~thXMkKKRRaPJ|oUIDG zQ3=DPDov+GB@)Y}_S|YOoKZ1T@Q*10VpKY7P+FiJ_86_K0RaNIiR>-0wb<>U`{S!-Ivt-M1Y02=P4aVp%ud*O2Vs&WOI7dTY5yl|M_>Q z_&EAI>q!T@jJg2<>IEOZ#G5RmZtj8AwS(A%-Huik>s<2!!FgE+Uip zvPWAI{4_v21plkLr=+4*^5}#xW;94Ae!^oi7!sslhn{d zjnu0;c{5Jn0Zw^i7lPbmKsOpT>owdu!T!bHdVj(NV4`r%~-iTuVzOTrW!a;SMi3HwE@z=O4#N=&C?|6Vtvs9+@__@OD;@FFdncJBzT>2|oEnnIea za6LEtrtqk2W#7Ew(JIgh7soZCHfOcWTSpeg!Tu+WpW1a(XS2A&SHcPqE~Co{*K^(@ z7w-Y!XE}9F6uj#MADx#>Ez%CU_<5g1cQ9Sp%O2>UEA>n6j*+`tgcSg9!AAwsT3_2O zFLbvK#(!lci+H85^NDs=5mzlqSr&_Eh+m2#6?Kgh&?Lh3q6TTIA5=#y-W*IuJiK_G z`yH3adpUI$w`*WyOCq{U@p)lff;v&xa%+{(OaeZHR1^+EF?}+sKT+3O>?_#++6caL zYiYuW@!7m5dXd%|DbYYREsF&e%qdG!mc`8N1XrR+MO_Ohgj3;qeK7#w_&?lP zeNGsHpqv{7d@Lf|T7Z@*6@_rrwH60~2%cT59hGYo{887e6@t9~Q@9lszX&_G<%j^h z#IiP%msm{B1LuczB5IWCwwXkjdu?B(Vi3Sycw&_|T}GeU+4B2A+UERBsa2BK>(Byp zQ}AE>CFUpq4A;WAXbV~v)7Dioqew+vQ^-iC;d)Whb@O`$UPS1?ikOdK(1Ws3*Q`gk zfSizuq8xRtFIxrszu55Ii@xly>nr|#xA9wEf|(eSQ5Ldj7~(M7w!K~A(*?=bIPK8ow&0a)fMQ1{m+C1ytGx**>vjzfb+K@ zqk@dMF{T3^0f)RgR+YTmJpvs{lvX27b7!b^4UUs$xOco$^pPw$r8LMZM2ROSTFGYK zL^8G%R1-mzs4xLH^Uk(GWbMO~bcR0v`!FhASa>*D)2?)e2>iwiy^G4|>yze%1Ts4T zh4yD>cZXH6fel31lwem^L%r`KdmPr5E=-2F@$zQXyReKtJ=Zf#Q_S2{&et7~;YRp> zg@Z+7Og<>w;B-b12^{_XEZ-inDcNs)+@e+Nt&)~ED7e5-lx0&IaiOYP4hf617nei8 z{x@SCjn{~FXcglmjIFQPnee#;=Nc^t*e!?j^KuB-|4Rpab4xnTz+>cOc#HQPZZx5u z4Vxhu+zD>cey9bLwQeKqXIlt8l=((00aNQ5;GYJ$nqwZiv7m$tUEkSpuzaRm0Sa?NKmRoad$&59kECvOa^0IdClC>BYO`X z**h5iEkXbHM!^GUK7_{v6p*dfr)%(YixXqhW3hy#hKDGp0VOe|FsYXHqj7q$WHcZj zLp&%5DXX$7dr2tRcLkSZPA-tL2}Ol*i6wmE#4JLhprse6KG!D`L&09moGm>?u>Wnm z2u(!tr7x0#9idS@XF>rX87eDW!WTqaeew372#9r$-D?-A`DE#uFvH~4HDF#>>FdAx6=N{E|!dx}fB3*@9uOerc<+s?PA1a3Y3+y?)`6$^4+;10|LyTeM}%nSq-O+nf!Yuw#W1vgxN#QsdpEtNw{qH(mVi;(tX^ zLb~K43lS0pExq^C=h_)&3OCX^Pn0#4?G&sCP+4(h!bG6MlPwX{ht=f$AM{74@Kf0J z;`YX2@6s}Q=k-Zu7}99S(G3kN!WEkA6Gs3s-|RbH?OjqvzkWOkY$&L8ui9DF)rvd14OU;+c{*_e}ubs+)d!%d*)1 zgBJR#YeBa{BfHwq6e=fBw}hJ1uqvyvC$!Z=U9m7Fzhg0=IO*8oltfKfS-So|h!Ffm zZExA)tuLeZza&Y#*rqU>btPmP!394Rqi4LlQjX`dM8bIhtCk&un4-d@>NA|t_^`*| z6bL6C(?)-}G>HFqQTsm|A^6j558vQzD5JMrvLwtNtAa*b4B6~m7kpXTG$f?5{iQ@f z*HsS`T!B;!C^6oOk!p>K{~){Nu+&O-D8H>xhyf(Cu3-Bwq5Dwr+l7z7p#$4}=X*0{ z^uSdH7ejxmiosC{p3|ugjaG4X=t~sBy(czMv+Crol#ya>v^J!ri0@_jznMiE%#JKm zZ0T5+&d3S*o;M(MS$7~+%?GI{vSCahCjzOBtsq6UfC-&xkDz=^Rjdn!w6sffimd+^ z?!xweR|kxL={9-ab>8J=^q}sGUx8}qG;fH#NTqy_IKA65Q4IL-jgPUTbE5{XLNv5? zOfpTzY^-6f0G@JF8vCy;xiN*2w{bo7D9{% zukx-aqhDHOpaRChpYdAZZ|io>Y?;|OTVdzyc+C|vJ7!j_IG>%9O1FVs4+{TI(mMBO()0+NXrH`|v($a}kwOu`2 z9V=&819$};IUvBL(=>H{biVI^SvX|$$K(S0eh7_>G9|4xOot=k(P`RFYHVuAKIX{1R%j0z%Ab7J9)=QP)-$4MZv) z*#9eqhSLp}0s$qN1^=A|Na#@3;0UC{Nf9~us(6LOWN_JqJs6`bkjaKhq|VCX^v|;3 zJ+f7O19-}>@)ND+xdNnTG8uy=6x>LVtLUhZG6mU%Agbnv&s($@y8id?sB|j&_r6{J z({=2D)4i9K(IYFB)w~hFGgz~x;6hILwj;h2SupN8yMGx=sO#@Fbv=Ws)tGJ^Ja)bJ z(lYw|Iz=Z=#UjGe<`SnFYHk+GXDX|-C8233kX5h;vH$hhG_Kt^bLA}S67Tz-6)cM% zSK|~`db&yVHgB7q*|8HZcC$6_cmh5h{o(R0+c!XCWC31ZBFJTokz$G>KTEVvL* z5mQ|To}?jt-&^|pPZbrPM(;;e-9RblJ#wzMt&HCKvMAjJ;bx)e;GXt9I_qsMqxX)+ zG)L7*@EBJ1@^8M^v$7|nCWxx+r;{>5ov#%eYHLZG>cu|i1U=~2-Zvcgwv^F3j#%lJ zIQFS>kj`84us*54Z5mTjqx{6$p8^0kV(TUYJyQ%IV^l<&GMtSN6+D)QGX1fSQ8r!Y zRB;0If!-00*e8`04l}HrMgm*SNpDT!Vi>i#*-*g8WC{Gli!)ThX$g~~=9t#on?-@` z-$qUvW`eBN{GCx>jeak<5bz+TtUaJ)@lj)d!lP6#q{0^QyvS`tI_M}%=?iyZhxLr& z+}574bQ-}-)7s}Swep#gnkP9*)4R8Nwe(+Q?JR!G1c z;3izbSqOv8A>oi<2(V-S>IB&T&3-Sf`~@!Czi2ollywuQ6TV6e^eGZx|F^I%lA|%e zcTpC*_34msNT}1_UeyV_Y9QKw*!;;=+bO*dL$9LYkN^ZMRyv$cuqB9IM}ofp|C^}z zc;PqGt{}R4Z9(9_Z}YA^3ElgSv!iZQ^xfnP0@PbSe2KTcjJ{P`QXR*hCEsxrpxqDu zUzLAL#7pv>6iir*HWCViibR3ab+HSB!Xe?1h`-~7F#`KP2xA7M>}0NH`=656!f}YsQSvVE>2tIM;WRN8GbE zV9WuOoTGg}#p?sNBXD9-lT@)S>^zY3Kn4#4_J71#2y+q+35P_#+}RTbm4WaCmW>}^ z|F>BUIBpDaV~Al4abB}`y(ZZI?JnNL-q1FfW}ee|O@{;<5?V$=);^2*pX75BH7^$i z`#(x@*e)C@xRIZU*&*SO=(89IKe@t8A0NZ!Pp;Yyj?O}yh4h()^tW}u_&?8nx<&XR zRLot202B8v5W~VD(G5t{2JD`DkpphVxn}t5^AQc~|2XvCjqgkaa!10p0m6`N;Xc<= zr=d(evql2P|M&;0+*dOqK3fXzF@99>P0%E$Hm>OiEa)b5OUG9bAS4&+q`(mHkM#TB zTTtO?v<3TuR<_SC_jbSwDi6JIDZQsr$4VyIey_}(AoRPldC0q}jDBbLQj!>%=Juq- z=r_5zdvA5E4iw-R{C{=EWZiOt{ADz!YRo@6B)Sd>u>ZTvs~+6d*sloh!1bWpv@cn)!Kzt0FKe;LmS-gC>un$A8qQQIS zkPx5I>9jNVI;8qxBTOF1P4cjse^p%dt6v|`@W;efAz6z3Vn>(x^2QLygfT)1zOeW$$g zFP{5n%mK+qvNp{k%h3t>B0Yog{{d&=y0;%OK7FS=u170$R?Z$u52RB&ije_Q0 zzGeFc`TmxN0xZRZ&ur zVYh=AaJ!s=nOcDu0sklpil>z_{;4dns=g59rezJ58+WhLjB*P>FEoVHP3 zUC5FS5$dC~S6HU4FwzI?8Urj{k83_YbDP{i1&(OF@9}VO*$Apg8jb{*zFx; z?X`@8L)N5nv{x}x-xvjj@W6no2AcCw9g?Bb z4Au%c>Z|#=CO+}+f6LGR2diJY7IlrZQC?lhk`56U$pb28m6IT|kJely55Ofhwz$+k z0Al}#;QyO6L5P$k^@*QkIvBH1hErz=i4pw?D=HredpIjrX_7%6hLN<}!6_WH-wU!} zau_ur2;I250zaxaF+M%jsE$q7AcPnv*z#Rvl*Sd6yU90eNWL$<&KodO;rM8r_ebo2 zoEbjLNx{JW-yAZlaO*fHQzau!Fv#@n$+<~jgh

    W&4P;sEx+uz?m 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 )~ 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≷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

    k5Ed!!EC=&EvrJRC^%*sXg8#ot z473@-YwUzZUYsd0F-@&-k*TWoBx)v6libYEaTWak)%d*!d_sFzv2OZX2V~StGi%k7T6)5rFawXnLk7g?vbhO{v}j*{Wd`cwa)H< z|6hWNCoZeokXIAg;q4Jdc)=N9HIvIs7}{KDR^3l+k*eU zM$uV@Gn5p~;gw2gI4`9Cip)~Yk(ARCKbJw(vX%?k;zK5j&-=0qQU^6~g1Z*^2o?rRO%ATmM${5!4u-8pJnS`1LzdR94UEL{7T5Xv-%FV{$}S}j ze@&G`tysTWxp;Xpn9y?%I9TFnijnD}k6*eUQ>z{Gw6_Zc{$UwdQe zl`ZVAH#AXGg%QsxDdqsf(U|Gm8o{*u%T4LsLc zdUXr?@vcVRALK(@)i!-66gk@!BObGcuZEpg6{uXWYypZP6;&B2w`$T{)nxKGa3MXn zs;er(VGS_j+%O6q384su3YLxYsLU?rXzCSwk@S#r3V zq1>7SZxhLb|6i%(4RIK&+TlO7$!F0EEmma|$~Kgw(NLAX(u+FVrfpD*C{$$>+7Zs# zX1kosN2w;F_oS(+A{04ww!2PfMP?n0BuSg%xvorH@~|ou@buxmrAy#B!Oam@ye^N{qF$dH?(ZKQ>hI4E^$leU0|SG( zT));U&nQ2H)yp+c&y-fRu=h+Y4!f&?UF+hpyXvExOBc7W7p{otomN~_hH9L{(F&DG%87sq~Ov3Y3*(-ADY_kg|ZMIZp6zHeo$j>(0 zx|T8EJ#R#J@39>&H<%mJKg1`S^P~tt(Ny2eUP&Phb5c*(GbXLv5IjfB<%awE2ebWy zg?wLbs4tfv9_q{X4dn)ghx>Ecfua0x54?e2BsWLi78Fn7@RO}MPAI~=YKTV7(xcfc z@$i~<3G$*>xqLxSAyxZD9`s0JPQ^tH7mD_XI>4~Wc zcT5~CaWEO5{mU=w=5#|Q&N?pI8-}u~V}E;c`;8BCFz(6GhufYTz+Sh zDVjgtYDff$^|;KTa10~0-|UC`{PdYnGEXM+yGpNVVLvxkYmbTTiA0^uOEs# z+}af7&`YCsUhyQ)uZVwW?@z9Hz`LX3!O}i(&_h<&fT7O|3Os}@W;cyD2PEzczrnH% zsR37p3$u2F!)Q-Vrk&rkC$EtzX?t!?iIPaJBf$Q z-A@VY|8Dqyo!V0iktA6y!>xW9QT2LCUr4E|yr{)WvRYp7Y8myfm7lDMnz{)dr#xZr z$@)Lk?_~o&Iqw=pP2{!#C;JDFz^~zx`!C#@LS~f3n}TrtpJwfh{Th18Qg#7hV9SaWOd0~@F0TdV*gy}-1xad{M%}< z_U}diU&%UH`t#{$(i_s}r+z2(j?}34@7|}_k3mG}(DC59QhS&`7TXW7l}^`&bdwyscG7|4$79^J5O z*B19FqpJJ+H$O7Ja?6M~uP8r(@!w+bSK(p718R0-0blQi-`su!qz z`O82M>X7nnnI|9Ho6DVt^wD;%6D0+WS%>d1AhD_sXt zcocVy5u)wcM#O3f0>Qbb)SG5|DSqCcsCt9ggQcD{n>FD3aAu$r38zkG2tEr8mbz_3 z4o49I(8aMU7Gmbn$(iZ94^H2WaSG?1j#6iu-EN2~IQDi2U{{wq(ri}{HYg7Ie~SGI z^S%j(WuIUlOF!MmVmh4auUY%Yus%3|hdtl}ZV=&Qxv<7+h>=v$@!~u2zKM(>J&uT2 z;eqWhY>ICNG)up}`_RJP{pWLB(FY~su)OS;-Q*ZOW>3t9iNvc}|>q~3sV(_L-J0~`61$QwoQ^;k6hRDnw zIRvpDSNJ!U3P9vMHRc*5NMyz6*3r$k-!Yb%7~8UaMFuX4R*Ym;z=hHARB5<{ozPbZ zZg*82oUM_K#9$+`J4!>)5q+`dWK%VI+Vne1gK74bn9`lNyfgqa##%SHyEgWW5i0s3 z&KMD)*j8LVFJ}wVfQBwFr6bHNf$(oJxO_M0n2E*`jb)a$8=ssit!rV=-qtkJ zCZ^Sh(M)LYi%a!jW$~=C0V}62i1=%hh#!5?DIUi1>wh-R(wovPsozX})SH1q9SJmk z6V>?a+{`_5Q->zoJ2L8t!#rN2ih_I+q+1*r6(FG**!22Qq?#^8Z~{tlUrtFYe!9>#;M z_~A7wNZ%crl;sRu*FecqM>TxGttm8*AV#sTGvD~KfkQzy~K`|xg8}oByZH{wdhpJbR4Y%K9+NE-P(LGreUB z@5xTz19uWfR^#^%J1;BU5^U|r$=1%&o5=1gi3@w%?gstfZ+qaUHyzI^;HyiU(rlZu zF$KJD`p9AUEl-E0`BOKS##`8Lv?@Sf)iqu9CRZe2i|6_sl*ESg{03|P5q|&A`wN!Z z4u>S2eHwV?t);Ck?0q_#A2~d=Z+ib^du9#X`-DX9Yi8jw86>`=c>ZafMwH8hqDn-t zryHN>E^TRHPu*D+XMTR6>}r#9ak&YthVfLJwo%1g(Y!+7z_E6;+Av_dxaN!ozx)*$ zu9K>E7N(j=L^o1wM@STE2N<_PpN^|hFxR-Cb%d{Q>#D<1xfh3Zw+?#P^>DP>7}<^w zzAv8tU(USC&%UW|p*?!?uF|#^_AdP{=+OBu+<+pZ44O*V07fF#g;X~;ZqfCMS~u6F z=wleqaR1}FaiN7aMEi4{Xf6rD8QEdr_B&#)_QDuNnrp2#z?A@pMPa7bz>CZ6-05SO zUYCPY>A@Gnv7AM1(lS8Y|0}T6$Gx9s^X%QM5OdbtUYdYSlh;&r{BSo87{Gh?m3FqU zpSfiLG+n4+t_GK@Hyyvcv;%f+HudVb1`PyMa^n2bt*|pn-}ziNOOSdUrZyL&Gu1oa zRNCIcKKMG<5Xbc6s;FVoMIzRPg!-!+aY4vFS8#y!@P7sQE%{Qe)ijp1Jd)6>_KcD1nQ^`m_iTR?Ku zCVA@g(gKs#uaQv;wlx-G0i;@wY!%PKP@lR^J|B~kh9h8$LIO5e6lR0D@T5>;3&u%> zD9O!6v1nfBQJkgX&H0ipV)>j=ysPsw=uesJIy*c6m^XXUkHxB99C-sAL}?Ar@dAJT z&n{!$-@w64Pi!vT*212?Lh0JFSmMKyday>ZrDsL%hFk_H#=?n0iE86)EdVq6P{A;7 z0o%>4auiBb8>eLfpm2~zj1w=wJHAFn)PtarcF4nbn~&dkBc7h<6zAi)<0=Q|-0^mr z#&(>1b!j*J0&unB89tsN(Z;NH>B3iF^J0&ow{tDF(73P5oNx z(bNs87VnGRbKb4qW$e4`zp#6uQKmv^(tpqJRo|L}-x!PcudXX}_ZE5zz1{HFTTn-J z?!~vS6iWLea1k^LcVBhf%;SK-j`?X%7+Bmy&B0U_RDeK+unM_YR`OSzZrsh35Kwo55BMO#pQbpcZcZE3QE$(QJoHZ><6K8Y=N{=`A&(N@2vH-Vud5Z0SjKMCs}F5IxD^Q7U%m z>G<~2o8cwUfqUM;MJx8Jwm|w{~|Uf-v7Tj zeR1mRsgI`ir#ijA_kPv8*?T$r3VSCsN2m3rIr0L9tG@NE8S$QaWrXNeosVVUq!Xwa zoQ-?Tr+yuFPiGFSFU{6O1k4yM87LB3h0+We-fDsXBL3?Wf)q**#>V9Vi}1a#^Z*F2 z-p(AU0UH%RV^9;q*idOY&5r266rpXKSD|z`UKg(sVI0(}hiRyEC>B?t6*?#brGshq zU{!fxDEXKYj`zpm2uNTD&{bd7Lg~K9eu}_}rXwOL&OJl;eti&fs5Ir|3LDb#&ESB9 zww%poGd=KrZ#E!KoB- zn#TIlJK_o8$7B-9WH>IAj#&cCwQ~m$bGZ6~26sHPD`CuPl6|{{i(hByZqFJngnd^D z_{%6fRC?6ueqtE~s}VVs2#K-xO8te>Q3qGG)RRt#laTa1>VDbMBWb3- z@v$9aZEf3jwDq-hw(Z!_whaopjP-59<%|3!U|dRo38>@cSJoi~=Zc)ARJ=T1e#HVv zy^)d{F0ZVmLl<+^s1Ci{kfMjXS+2Y7+UH4X^A&q7ya%i8s!rY)?8hkldaWN0U7(u_ z>mUWxxH>FSE9xYbIlw=A0UocVy1*bMFR6rQbq_#M+YEFKJ7eX_I)XqQq z!>=6I7AOIMuDa*mSA+q;zgAv?|nUG6_#zJhi=>*zXsMoV{{cheVFbO7GQhAJ2@UtWzA)gqGW z^hxeYcyUNYN!bITmB>lK2L@{=Ws}6Q9WTSTz9UI>Twln=($&WDYk`zD z6Ht5R*s%;4TCHX>UcS_li4*GW>#T#+Yh0u{3w^!uqymSKc0FFc#3t35hYrRjD5lPRMG61UvGlK{?@PZi^|jQqsde5zdcWk|>0Qizj~!z<%m2sAou)d}nhx}u z>n@BL0n3kcRI^ud_PyZx9dSvuUE8_R7598n?NOu#Vn`))f>Nz^lFE;P>GTZ9?#hxq z`IsFZFT*Dc1FoMJaS4{PuqG^Y5AbO$oDfDloVW0Ue}UL0Z+bp7IWs#oeHgCrZs;Zp zsJ2cpZomiSOXc6#TfJtrNVCk2Bf<0$iXRiQTg7Z^0(uT z4jNKj&q?7I0T)b4NR@Gsk}K9V5PCbVA0E)L1a#f6%oOq}ixNTy@iTz|sUk=TbU9D* zUdsG<`3(`I@_96@kO;@ENtrs#PQw4+Cj9@()HhSlrPh1@;eF0~!W(A)hy5aZo8|vC z6*rdg`!6KmsbEnkfZ68;AZBz2UGrMCdh6@kzGL*}Eu+0{W9300bdg#h$pr^rVnq-N z(%D#sufaqKl+DHyXuJ#`A`6Tr7YI6q9m9#nTAG^CL9G9J;ZmlLuKY!G@F|gjM3XWG z@cME-%^r7Y#bz#1@zTl<{_D&5(Z3b7;Pc^EMDoH#vXPn~@>ic~@$-MSi%3<3M@Sg} z49#pT_W~)0VJ!;hEYz2B}e!<80B zYxpmYL|=SjGIS*@30{m{g%lwYw5IQr{_ykIF`P}-N06#%(KcSjS4=yMl6P>R8=j|u z!UyR^sB$)HQy>;dg)f?pB1N3VMFf`uJhhFM;ce5$&kwq;l*%vxH>tLbW%we4%SYlZ z+@&a7+wiu1XTRu+U)I1IUFb}yqBFSNyLJBNGJL9qu58teu{I_tO=-LgpE7X?h3l<& zt1i*QUQiT%)Xfo0_%sIO#2jSI9oIs)Al^fCk=pNrX>4N|KkQZ;ArYTeUfXFB8m@;B zpMVUBwEwI1|NB$pF#lJ)DK8V#|KSHJ4mFQqEb8x$GX+XR0{4I)csNMGMFp6P<8 zeE$RI|Ep7f4&VMB^Zv~%di%ZCv9Ge{<9-cfL-}nW(#!RH1eyld*FzUv4THboE(r{3 z{zP&^`A(pcu8E3CVPpBNK*5i&!`yf>W(zdiE>>g}DuaA_n0Tm{1F5^#K$=x<3 z72Y(hE}2gbrX~1+tDz`-0H(d9+O>)AC>zW0v(*40xG7bQgnb2x^ZzT^wfOx1!E}4- z#ncB=n^S4N{_kgh!+w_Sfkrl1h8-NU$}RH{!|msGon&E-Q>k3s-&npMZ4Y90 zbQZD&Wvm;<$2Qz@i^7#8HkR+BUCnok51RDJ@0tW3A$I!K&j~7e8_QEJLhAb{@d*u< zVV{Su4gORdzx8f>hP}@!<0st5%LhOLfBkUv90RxA_XZreo6C2_>6=BU15qtX>&tt9l7IKcp(R4)Rv_RY zBK-d@mi~?O(e!ZYUsJ`@fmGJ}JMXmjfHw#`08X*Hs@wsHY#uK^3PNg=haesd9b&h8 zKJSMR?zb3SmD!Jg^ke0tKuX^O3?~&q2Q_eG`4ON)Vv<87UvbWuG*pJYA4mLnSe=3j zLN}Ii=SMViOMW{b4wa8oV{TFKnd3gqnwZl;K;`w9XVYvtwC6)1oX5&Dkz)tXqzf<+ z@Pwyq2lLwGE|81KR)?|jgYoEa0&Pe|?t=t!KFqd8I=Ioev4R^l^y+&}-4Cd5uHZHeJp-(Pi@0|4`U>vS&;d8!Js5~(@U<&taJIU|wNBgmN=r2&_5y|k z08NB$y99F$NOECyA{#5X?NSdGxB0`yZmfJ~K0h24m&dp@uBmuw_I4vC>@?_ffJ29Q z;!PFYa`_4aJFq8AMTBsN9xgvl9->(O9JaFzq=%3;T!yWd4@V22N40Gm4I^vH@34Cw zkUca84V7VsW#l9h7EQ;?ZwH+%cv8g>g8qL2{P>qY|GzTz9r)GHS7Ft^&|d?OSIAC3 z*m@)`arh%|{zO3Bp%}&+9=>YnrK(u!_VxF+byZ-epM0OJ-o%8@gfhmSVz~=+yh1kj z&9$$Pk5}7ZgW;d9hxj?RfgfZ+*5oHa zcE_fG@FZQMI7_MOlSdJ3oH+2yjyQ^tj9;^G#!`_x_f4PjZmg^XN6`~xJUK-iHb!yGJ+d+O-9KkE=F* zw(V`>AD*R$PAp{TCn6xszzqQkqw*LtR%Utzpo}+2RkeQ}d-H~|?Gvh8oo!E!!#0qV z;%%NKAG0!0BHatL@e10#3wMuh-Zi$f{RK?YdsT>9vm0`mgZ#ll9)hu|&kSX|hjIg5 z@Mf#qvXx75TfZD5rK-%KDcCC2^?XOZvnSU*$0iv-tlqHemn-lC>*304a5dmU;duG( zvI7+?V07!nl}pmBOQT-DZtd#%Z(UYdgmF zhDtjz)6w0|%eol=RGk8JoC&zhhF}E&p$6DGXqr`0F08yHJ_@+9PEu98EY&O9Xp5*K zH6*J@1*?KJY9tj7Er&y^K3}3T-}uH0FN6(dM$snpNY>FRt6~5V5R#>xh((^_B7*$L z`RZfG;G5>FM|X(>PN`t1fRAmN3k;$Z^OO#;4`xD|wnmNx<32e)b?2&Kx;RI{x(o(9kCf=Zxfm|Us z*gH6o9~=mYY0E~fH4H%nDD6%J7+L}a)dmHg%V+{Y6Rr-Z(6?iewA6;cDu?ctGm5Rif28tzJyVS7ouK{#PyHwLXNOM?piH=Xx z`VE2n>|fHr+W!vm{O`9|`cH@3mn}GEV!&XuNJABU zpn%H8)R_w{4r&onYah_Szk4Ml@4t4Ho(aCv*7Q$r->HmPuYP53a%a-}AZ{{3R(` z15e&sftSI(Yc&}we>{!K8m^7$$Qv|}bl4@KVK4qyfrK=^C5f`Z!6?{}VeII|C(m0~ zpo9*|I=M&kx4IS9oq(DMQ<4pURU=Pvk+(w~4Ilxtp5vO{P%&;;)QL((^8z4PV|M$d zv58UGHu>0Nk7f2jG= zz6>i&?YkddJ2JWNe&e?=D_4q_%IX`6kjZ2oJQ5$8V}_u}AAj!cy?ge-`3);ZSL~Vx z2iCvM5t6u69W>ZAi?I$spP%4s1nUPDjz!8jyX+IeIn2x)_1f@P1Z^$Mdbm;Wu$&3Q zs>Mh{>~kbD;&Om6p-`SP&7@(p)J*o+3%(DL*rKyHjm^RGcujF`6yEBlUNEX|IN*Rt zNcg3k{FSG2U2M^`$xrH3R{iii1CfB^Xr6?ErmyQDlNoWa5H#`z@~n-Wyn+-zJgx1R$-r034)2G1{s-VO1$=ZM>@fwEd|C7!M848%?A7v;Kz zXX0GfBVZi30IRyM{~-q4%iqgvg!WB4Nl}JzfEvnmkopxX3^3lZb=T(2;UKk8QdE4L zDCR!YV#v6d+slKyA~#m(2?p0IY)KG2lJt7F-(bXDpp*o z*66Q^iK8y-8wHLfhQb_)TC7hFB|iZbw~6aFWXa13Yo>1)zZFb8a)aBC{$;OyIn#(M zXY^S}J`;6GB$@Hn8>KX6+dT8`eFQcEjO_L<@J2VVUE=xQU2I`*`Q{v*ho>*Ez&9|T z*DpX*;>fWeeF$FOhTitFm5Rh-D>mf%8>{QN1`id|LChhyT}8?ytF&fSks`^407G>Q zpdd)FMli7JNtt9rgdq?ccJJCXs_p^Yz~M=Ga4I^zHVWUH1GNj5}CjvgR^z|Fe% zzy(o)1q^l9*pAyd#K;JbH1JH~V&!yKw$JYvYu^eF@iOz7%)TAFR=4jsHYTCNPrHTx zZ(|Jp8jzmusleBBpWkEaT}YsMhNXqMJEat)EouTX5G0b7z(Fd@PC`p)QY2Z`onTe4 zCa#8JU>a^>!$-#Es_*VoJ;F1kd}faiY&w{|cV_DF{d*2g9-5vx%AdfBgX7Vy(Q~Q< zR7(BoJ#qxD{|`~E+O#d5BRfMDQ4y>nbV!zR3d1yLQCx`-tP0iy_z)114H1DrkZcGr zRL1}cf&^;>1G}D-Nj5|n0ztAN!0{vxLJ`U&yC5cn4#`$gEQOTZ?J80x*$`0)1j&W~ zLv;Yit{`QS4dOXSQ6P#NS}(*jKzUWLhLRW=!8za67ZXZQcM>EFNLC?ORisF=A;3@_ z3&;saFiCbnoCqC~4IxP&NHzr6*@Hmm2_2FRfSJT7q~vZ_kuu4Kh)N(xHU!udB@Bqr zA=xVZs@5!+5qcyWCP*xMBXmeskle9t^XB!V8*WhysE`3*7q=KdL6Bfgp!2+f!0GI7 z;`%?uHnDUc92SzEdt0TWh5f`R?X%W{QF&&s+qCL*=YlmxcM*<&kSwiM)M&G)BQ+$; z+tk8u4K5+g_hYMDQTpuI&l$MD^ebGV8Qq9|{ic5Ud3Jmj0hY_t?^|1GZ(%?Cc;j?r zT1YHY2m>M}Lb7gX=*&TMd2;E&v*K$Nk)LxAjYu}gC0G*xA|NE|mXab9VEG$STXws= zXrG&?_J;X0?js8P_xmA3;v9E6P#lkpmZTG`5e;@dDf?OZeS;dl>L9rWjMS%zGOO<< zP{OJ%@>>e>8w7DizRHXEfrPRTetrSB>1ydQLqwMKvc}&E90U4e*U4?4uOWKSl4HLzjBWsExkB3V9qXTs!CCI}(a1G2fu2wa;ODU)mn9|A$LA;3^Affnfh=<|w)B8lZ% zM9}ySJVJ+LYbH-|k)1MrW6`VSAkZYso1KXC7uk`wqs0Q*CB3P!8ls$om@P91ZdZ{q z$tnd{RisF=A;1o1j;bJ?V2xm4*OM~Ih6qC-NHzr6A*Q3sK_{TypuVFCIcQo{yBSk6 zy48Z6304Jb0zd?WWCLJT$cyX$qbxnbj@Cc_*Ma%mV5Pf-{dlrua2Ws@P?D{6YyW;$c7zI#ec!=76%RNSS0q*b)em4FQJg7(fJsWaD5OMG0jzIv^^7RfG=7hCmYtk_`b4@ZT}EY3og6 zZywn>x_fNkSEUD@ zYF-x@39d~t2ELI5T7=>WEXkUKqDpv<0YpGZRuQqPNRebifEUESR`ND{y;1YXIUF_l zINFLNWs>zR3)cU0V*amTN`cMK?l5RXArh$_(J&Z$NyNgeK?`FuNxrAKAmUXR6FZbK$e~q7PiyV!>g8$@~vWQS(1L$?$Kf((?~gdRy2}P8yD-9j;Dq zqiB*=uqs#+kb!`Ztdh>EB1Mu70fy=rKm>$j<6s)(DK5&BOtR#sXL5jS9T^IgFagCA zB$5q)0Xl6K)JP4<^0xZNC;sdO^Z!F){txS%Luy-4SHA+i;}ryxWJ6dJ2$Br}hUyqV z4iE>L1In%BTFn1&8<5`#RM5>mzlT+_E$pYxb6AmOlwneHvoc|AqcdA2LJS}R zLb48qSVbU6HU!v&4+A1}NS1O6!;BOs(g%};h14n4xTqpEB+J_tuF@r5Sit=MD0;dw zD8qnMrQK`0>_p@g(9rBS!9L@ zJEtuMh9*$a+(&O`Fgx^bOe(mD$mfS0@%z7zFmDa}h=5!k$7f$t>4P6vS??{7aod=e z!g}U_^}DSa4NA6dLV@7doU4w1aIlhZVINO^z=&$HHA~7Q8vt`)8nh@bvT@JB^3_JM z7O6dXtE?DtnJT~Ze2#`h;0h3il ziXy+*TTWL38%+oHjS$Ci{Q&514}6jcs#vIS+LW zZqo#bWaI6Ymp&wEs^9;h|Em@}6S7v(YOz|e2q^{-0U_Bqm@Se>;3)@Vyib&#u<4D6BsOF5hNP`19aN#;8=4rK_J;MIjizVL_&vT zLr4+`k_`biiH8CaLL?hRCXFN;N|tsk42aMn**KUr>MhtC6p8Y*%65|vEnC6?kP=S> zgk%F;0T#YWwn2TCjDkke5seOVK?(sN0z$Hqq76+TNHzo*szZVJ{$Fn$gTExztO0n5 z;b8I-!w{<{Hb=7Irl_nJ&jf*FIYiBCjXPo_%Fvg?Vr>-#9IdQjfkM$F!(dggCLkvP zAz9T0tBMpc3+w+U#s2>fFb03iB|UX-WvGQcw=2+D-YwFJTJ8u@w53w`QZKZK4oH@3 zqh_x%SMt?w%3X*lvqJLCtjI`b$*dUhYvJWGD>8l=n?^D|3c)skd=M8^jpieT@%Kep z;b%cXwz@_}Y&n$(VLV)dISB_@1-KIsl9g6%LlX!;3!TgGKA_Lrdy{-HL6Ve7*5-q- zv^f$N8=G!&PJyCj6ha3(LOMpWA_6`%p&Ai9I1&B2YtIoKRYnPflBVciD;CINyqqQR~w zWk1XJ|D+ydsd+dgDbYZ)HSn>ADuovI+sk0v6fA$=`RtL(a0`3?w8MqLiF`My>ER$jB}GFxQ`YLh0v;6b4E%qWiOuN~5+uu;g3ttlWJ7?1=m==zkuu2!z#Nzc zEsBe5lKHOMTF+1)stl8@M!Ot@5O~3Qf=RL=&;){HLx3G(I;tFWf=~pAWEI~URx=Ll zU{$atO5fF?2?WV1>Fp};|91z6DX0@F6Qx1(l1H$L)Q~I(cYCD%YGqi)_?qSXym>L| zC{gj1D$H)zFsu$@cDLdy(5*B=k7SkP!Kz?QK*%6SutqSj>q(hpLxdp^BpU(@)iHn^ zAVEX|M6#iLW56g7bw*mgmB?DZLb3ACfi}M)2DYynA1#Kqh_ocDgbGxF|34RlsskiI zO7gJlNtt9r1R@Y58v+c~F@PK(K|}&XvWhPmfFP<_D91#1EwAs{5H1hT3~kz_-F zO?ktB2py6Qi0LFo5J;ADa))~(nv>`q7T8^4n6^;Eh&hPaQagG{KuFdHGzH*&*9W^z z5wPn8f?q4){0dD`XCm6%T<~&FVH0EpteW6#RgogeD)?Yku*RksCH$bXoMaWa zRYi&<8v+c~F@PK(K|}&XvWhQJeh}5HabO3lf;EAT5D=180$Ek0NU|Zoro3T5gbv9D z#B>sS4LrZ1NG6cgf&wJ^RZpJ`<%r+^-N3vqc0(PvevaQ;8EIipoMDgZZgk(c{NFYcy1emBpZU@9U-Nv)a9D@75mtyHv za5yK^$yZj^wyNSnwIIx*Sy~unM@LD(vN=M(=v50l#UaV9lQh3JL~ z-KaGO86Dsha{rSruiOAmds(zLqzZI@bw=sNMmGV> zlA-yCCYxzU*;tVha_%fALYiD1Ak8Ejf@woI!3Yq^IzbKXgg_8Gw#gxeth1Z!vQ*s2 z$RxbHT1+Y3ts1jvmIxgq%W2u5aUfiVZQ$8N?J{yE zb?$6T@s?K%e*-2ixjc}*$r`RbBXWxQe=YOA&(_v#{!e5p>s#1Ut`BzwdFvXTacY^g zlB^Td7|0Na2H1-&hLaNkB3UPB{bF-+c#tfra|#YPtei#{x^jx(Yd0xTwdh)SRbyh9 zB?CC3Nz$qgk(k5g+XMdZrB*WdOVT;6fhQiQY-nLmFPm^~y0ckY>d4R#X?Bin9@{XH zndyZ4&;NSU*cVToI@JaLPm%ntt($J$HHMXT+H53fy%r%2vZ;j~U!imi+UBoL9D6e=o=z+w)j)6E?I+qQ<8Xg^6QSbR2}hq7 zkr9`SCMHHVjAvFKJBCNGXMt~5&{)CY7MSj%gFmc7`A$3=!RVRaXj52Ilqn!P;OIJ) zQD@+}YYg6N1Ja*(pmK8ydopnSp*p6{D1y$bj5-^QKAd9bBl>L=)t8jks=PWcm zY_1~`DCd#qn<}>ekymKt#0w`9nRzPsoE)pXsf9gzQH^x;P-x4G$6w(|+fhX{r#dNx z@C`8VSt&)vVHzOQbUCXtaLJ^G&+lb5b;hF-Usve=uVA;c)b~?AmAWU@>;0|waqnU8 zM%WGXKiDbu2sG7~F0b5?W;ZxGI8w;44ISCa?P+!((7Zz461g!qJ2#WLKDRd4);79p z*T|O9+cpnW-kfIo5wB8NMq*?RO&xB}%zDT4yI{SGDT4V4}7D7Z**83ro1k|9tWGUp@c71s2v6ECl9g{9bK3PPXJAj~9bSP*ut z>@-JJZJLfW&i-t!hyM+)9WL|@=d)Rhs74?eMNFMZlM7pcsWSx^dDWuMSS#lLVV3@U z`f>Im8;dM_|rhjr^@lkyFe05!A zZ<^`rNgEPm3|v${ae3t~*wWD4fZ=k!g~Z9a=+Tj^H(#S0$>HQDwQS=~Nc_Z#@wUU9 z*j(8I_Xw_tY3=pRJLix-(f`k5KgrTRntr4AlGhK}<&%!LR;FN)(d8U$5@O_nCg|TP z80fPbQXx89twspm$8(i?L9F1_i?nZrq0TmU1fy#(v%ra{W_9*4G*J$x!mM8Kj&6Om z{7A-@?IYU&X2;gi9k;`sy%YJ$0a*7=DQ0duV_H^8UYDJ^QS9MXlK(Pul9fbMjXEpZ z{#i*QAyiQTs4^j7WJgByC#=F*#-puRaXMQcsN4hdbLb4BfmO!jk-7WG?9n}QQ->y} z@e4FsWHAM*&RNy>S0;hwTNJdSte~wjAj9C+mZXCZ;#?}`|I1l=cdC-Qz}wG$i(Re) z!0}9F8thyTuEjdiG!(3<5Y-8d3X!%7gw~GI-<6`XavcFO9VR}?(QcJ2RnW$p0Rn!Q#ff2vI`PvMZ zg$rvn`~8(NUR$|uskMp5yJ2F}Hu=#csZ?81^#7DM&QhO+Lz3#&06e>TkUqOo1|m({ z*S>1-Yn03Bvp+^0TR|#J3a8rCS+G-(v{vQSxfx6pZFN?1)FrVZqRxiEFl`*3KXGH_ z0nqt*io9kgv=AA+CDmF`fT{u~GLfv^te~Yhy7`u|+bNdF8{rr+6gB}RS-V+5+q@`> zgAt$qQ*4lVABRKi1lB$q!`g$)K|EEd&L}a-tE}#jsvuyb3ThQ3tyOt-ZUz%YTb-30 zuHGmZl*1{p0#IiJ(|K;~CwEk4;E`X4s@Cif)Cbl`q)wseGesb9nj|5jvg(Ye&K_vu z6q4jsc0o)O5qVY*e+K=;pWpJsu*iz0u0YCMowMsQ2dD0zY|nM)I&K>u+cDO)V{Gf_ zmN5;LIXE{nb%?ifzzFUOWZKcymD6^u6$^S-{qN4H93Ku1OKMeCoe^+%;kGVyp@v2^ z&Y%CE$4;>H7t-%cy~q0z$S!g^{%GY9*g4?3f2mDHbP~)iaK8>0+OTQGr2vH#aSo*i z6fxa2HV2z-diwiemw=H7P2*XsUoS`pF_BE>7`%2wY~+E*Q4iC{QKZWxE69dQ+oaz6 zol)BkNDa^05-oTO(D8>W4}mevDnlnaAX!@szibPHZ+6kUny4oT@%0Bq)gbO1-94s1 z+WXY)RawO!AxR#q=TyV+FDmGM^OS2;mrTLLMWWxon|2^-U z4E~aI7HQz*)s>^L#h2U{)ZfkxI8vz7G$XEP%k`Z$kW=1hHc(8n541(#kQ$Oz^nz8v z8s$t1hnBZ&z^6~UbQ5GO0;EW?3L#h(tg$K5GKHpjNk3RcYDgBrx&O0wGW=WG^wdn{ zQTXbQ>jt$s+8}jevD6&oum`HhP?Ky3G=U)55MZc|0YpGZHV&pip5mfBp@UD}99k{w z62f4rL!Zz9mBHXInhkOkHi+#&z$$`7vJ#lKLKW=(rVFj#_yzgA5)l=KmY@I1&!?|k zNt~tsd;iGbFG=Ty22QT1yd9PXmny4LCIO~HvcixITW|KS4jhKB%~@q?SsEx{56E$fdnE%~B>5N0#J!RHkXZkB;rl<66s-Yx|K~CK{!ij8BzxBSO+6RGrdfki zEs{%3WM&uOQof6gZV3H2-oW4h`9dIOl}i;ML2Olb2ag<{+Bdx)ZYy>iysopoQyh*$ z26i2S-SCYI(ta`{ot@m)DW_#|;_Q1bf=4(Bi1V7vfNALLYp}`&5Ec$;M_y7OCSFU@nzsqkP~{w)wW@gKkt3*2`Qx|1G~|1CNcaUu-#)vh4`B&+lvtP0lH6ls}4)4Ze~tRgiei{K~vD(?Wj+^@*{ zgXZg0i5;{LIs6*bBCZfa&Y|@1HgbTJFIm_aFXCNC;s1Y!{{MCMcP>Xhi|UR~o=(Bt zKGAm?e#qJg|8K;6bH+?3=>He6JuH2x_p9F9z4hM9*f-cuKt*Fx z;q-;hhZ-vK8TQ~`mW_cU+3I?`hqmu6EuG}-wO+;&yUXvHM42!O>l9> zSq+|kS(>>XSjipkU0vV_U8~_=S660u7>;;=@9+(tKCebZL(dRojyxvino$wUq=4^ z@5fpCWnPy3Pxj-Dar;J489)6>*axlOm!ph=1_@$OR`rGW7M(xi-<*fT_~}}Wj;|?wQP7}9SF4k5_s)47mH*eUyYv-ojV+Ku2Cm|YKT$y|Uoi>8a z8S(4U%-p>*lY95i!s{0vIsjMCubBUr(XDLnotaU5lG!Lao6+khjz4tz<>2mtAD5ra z8WcUp`M-r-$5LNspJTI-iB6-ZF9uIKKQOV@V*KN$U+wfp7Y!-R$jIl7R%Np%SDk(p z+{$)b3>)AfmanQ^vyf_wX8~290}QIbhcFG036Fn^#=s?0z&iYizlNR#sl*@C6W5-; z2rdR3zh;O}LoWw>U7j)ej^9i4{|nhKv-B6!Po!^7r@TJ)_w3v3OYGB7xt!9<)0d~& z8%N$UvS!<(w@rNYqSKe9*)=1(_wxIv>oUD-FFO5tQj_gn2Q{xFH5sT`fBLl$dR8dY z5-aqccJrLUw>4~-knd|KbaWKDGqZDh=Vp0B_RtfzoW2y60GF9mGS_v&4c*mpcO`d= z)1Uw4&wcjeAOASKm7?>y4A5HxmxVtZo4|`hOh4fJN%PrUuJcR3E2`kQZR5tB0_KOZ z?gzRpk8hFSRD4vcjIAQsgrLQzR0c}hcWl}MKMr(@mCg1Ib@C=RHA0NP+rsLb5+cso z@8|!|-kSi{anuLnvu|IHm&h?BmPrC38|ScO$?ul5;>%WLvgH zWXq9cCr+Hhj^iX8AwW3F)j)xArqu7f*rkQGl%^@=Dg{2EX`w({zJ8Rig?{P9zxw}X zW@mP0clLby4oSOunw_2F_xsK7n%UXeS>v8V6VrIAoK<_CMaUVkl2Yo-Ocqw`8e?=5 z5TqTrSl9@J57dlxD~M3uwPoEp14OlU=`!f-md^ZOLt(L~6U^F8$HwRH%xjnA)rCgI z4Wvt9D_O&j7d8|YsR&?%Ff|jM4~M|XTUoeB*kOg$WoJD2#Kw%zI1L6+@DLQIVEbRJ z-H!AreM}$LhxD8E4f<+5t1s1Gqo0-f&(zOTf1P?ERZM*(_4d^9)Xk|zD4ZPr95}YB z&<3x79bzJAkPqr|=CMEF1i}+rnyP;v*!1kV=jzSi;Lh`HC(q`-)IWh&4 zlxDSt!nNSo&1%iv7Zg_L=t}d_c-_dI3k%D^i(3h|LrSZVvUFtWzh78r(NPO411Sdl zUr<;kK!Swx3e7rtwOJ}tXwuOoJ$-}ufd>{9mg?wQ5;w;795^&SP8Ru}TewC?uj=XB zaQnd7g{yURQO~CSvkO;2WZk-^vkO<^$g-KU3rirfc4p?B!WBAdybczOpHnb!Y+Y01 zIfct{Y%NZEEskBcuJKr=a2aUEtGe%7O7{Q0(tJX=j`_Xzt^LdCK_@r*w+@m^e$_wJ z*Jssg!>@PG%_0#+|$Do{n!Ww8Q*oV|}#9~kqL+f5A(f*Vy82;~eJO_uqi=)M%8MbGgU9K{I6!mo{86Ne5=!}z2@ z)=T+{5vCfJnh>(^W+NPx0xr_biI*abMyo}%l}*{^=#@DJ2A#lcTB!huOYq_r5i%p? zD-KklgmuDJMxxaqtC6I&tbhw+e6j%qE;0A`Mw*42W@lX0)Dd@ibCb1P?-I4)9N;`r z=^QVGGs%Hd=8+e3wZ;&fAw?fj92^FX2nNr%jn4+o2f`JOWp)C!f3Qwl(;p* zlK^hb&P(gsjjOx_E0B0G&Jq$~dOCSAJ#*M99uUG+hVZ}Eby5|nI)Dn9K#?uTnmm&u6)I?&c=ai z)jH<+#a6CCTsLrv(le5xv&{Ze@D`xf1p&M^-Hl(Hj$ja`m0<>PZdKLZ%2~reC=NyX zWBI}w*b8)F6i%5OqD!hB_b>724%`)5a^TG~)z@$Et0uv$EX^!8G&MK0$e+=%<85gv z6P$%t#W4qPYgv^z1zvkXxmCC^L@2;KMzPJcq%17Ty2 z{$KjP>A%o_rvF%fN&l|?P5mqSm-R2|XY^D0XY`Nj@6(^rpVFVukLySE!}>w}jrwl= z4f<{RfZnIykorOD+o`XoUQB%{^#`fvQ=dzHD)rIShf?oNy(9IO)XCH%srysYsROBf zshz3Ur*@>arEW@XO07$+O0}h0Q`e-7)TOCKsS8r)rc&CkwU@Pj(f&#MsrI+p_q1`(Tb_6hAH+6T0EYfo!$(oSd(Y4>T9+PJnyzg}OXcjznhCVdIKx4c+? zg?^r%PW?~nKT^MhH<@Qsm;g%9CqinpPl!0(l zNrP}>@hF5FiuXa-Q@j_#rs6UPmlok0E{#_guY&NZ;*}6yS-b+mR}?X>g+=)GYU6_9 zVh9_G3n4ten1=AYq7GrEh^2IH;b92RDLe?_*#!*$tinME(}n#IYK1YltD7l|Liq26 zT@e1i!U%-_R(J!1zbf1b;V%oXhwxttuY>Ua7Vd!X7X^5yd(l4^ZiDdu6mEs^XN4gM z|FJL#;Xf3%L-_ZF0SJFuxCO$$DQtuAe--*6{Hwwi2)|jl8N#m>Zi4Wugpfcw574D*aKll5h!fT6@j+K zYl~|jTu}t78kZNlAZ#rHRgEo0pr>(JF$-aHaXH|6_S6vwfAiFR5Ps+s>{_(wgQxC+ z@B^nNAbkHRESLA4+701voWinr?apu;|`XDB9-^uf*!P^ZP2hVKg%za=U@Cy}8Y+I7X--mj zt$Lx}Ne8@7>(M0FmIY7<(s(G>ipvI3c^5iDK(LHPft)SJ$K;U1ITdZ>)~;r`=D8K0 z!%~mk9d1orq?@#0N&-l$9HCX#*LkXL#V8_ZB}@hPNnuWe$tT-MB8@Pf*Mf)= zld}q`r;?RTLkValOfTx4bOh3i5M<6ip4ccBFP-g#L4pu>(b~gY#TWLl}5APd&O-ICXX@GgAMVV3SD>Zjqylv zo(0r9opa#+AAGGHE2mVuu~ux%)-m@!Cu7$xm3}eMqbQ=p}Y)@c$KshXRE5Zv{$L8_Sk7t(Qiw$S8-`hqDq)= z9;#&LBa{aF|6?1s9hdfMRb#(N3AVH=gF6peE2J{WjkdQ~&Q)I7tIS0vsd*|nUz0aj zWGXg=Q%)5GF|B4iw<8vba*5lkxafyey9!+l9`RG0b^;|z)ED+Db3#3$g z6_@6ytsoh(a9-N^$TQp{_9|6ly-5!lS&fBUcuZ6YW*1MlX#0{}BGa%w{-@N!aCgH~I7dh}AIGLWmC-w5gvp z=GJCu30llp+aX-yXe$ozn6H7&_}~N~nOu?p(77S8YBMN(*6IlQu{aA3+00Bzy#0;_ z*mGG*g5u6{CX8R=bBOY!ni86^^U&0hVZ4F<#Gz>=(5jHp0AG3w(ENGNCL%~0%pY-r z{r@Rz_?*-H!~mIS*}1M2n-K};x~6k3`BOaL-_j#+9-{I2fd=}~Dtq56qbq-)(TV{E z8)lT(IR3e{8|^$JE3^pXVj4UotfN|@^aMByGT=*gR(3E zzz4PzHm1?AtpQG*E&+VcvYUozqXC(pjyUn;yiBw zTXErFp1J&PK)kVJcZ!5qiwbf{f>8IHd-qN-fO|hoV_)J4W`u&aP}%drRau#|Fb>Il z3}>e5R##ok8!}r76fe4MYPT{wLK6O8yq{2rnXfcTf>X?%Q=gvvnlVb=2%Oh+pYjAi((#`{SeU&DdFrifdA)7IX84ic`lo!#_1 zv^n;@Mf`xIHD^5i^zM=Ak)0z`qr>B4Q`4K@bxmPY8hy%l^AyXeyZEyZ10Ys3-l0So zZyQS+;u-^0o$y&Vf-x0_>I;nh|BS5vPkjUFiy=skgafmi1Dgt)p9b=G{OK&iJdSJ68kLwIqj!K->Cy zV80D=c#4YM^gDIbwVF$Y{Q=Z3O_QKR7-RRhwl#~xe~Vt62X5f8cR%*N!Odj;AN?o7 zzj<}M^?^cf8omDk-c>l24>&J9VX6<8;iMC8UZ##5*tKtR;=shADW__MF%pOStePuS zwJSE`cQGQeC7Al)5}$H2SAF* zRYoM6=5EUO}^flh<&pWNy?xV|0a>pAczuAOB#<&(xWai?Zh!$}|F6UUx8!kU zO&jaoMW|$BD!ZNMP9d5F$;maha?A#`3T3_a2ASl$QZBSB83$lRsS>v>wGu>A<53Z% zNub9fvY|m7W#IdN{QU2ij$2%_h6@b8+{BC-#}hM_^^LgjIvkcTc}ZQ&>@j07VWMfQ z8KIv4rO$R@*hswb7U}xc^rSa!jVpCAN?zx$+_u(`Es~=1oI`%v`xK!!11sOw&Th zsXo{Lk~O}ROvl`Sy#81F9D-kR%mNNPbA6#7<^|45<^}A_9D*BjmAYurL#QSa%zTfY zoRkRMF4ux?U|{V39r*vgOsHFFTB>%`Qv4A{B($QvgKwxmEpSjoDW{>UbmuZhHkuum zIKXC1ab<{I(yj#wB-dO|zB+4FW|+?!TQMB~`~Lw3E^^qRhc#_m;&GS~*cIDMcj_Xm zfX}YEn6C~=2de358D1zI4RGL3G|l5Jt{CUCxK@Du|F!)IEl~nq!k#;qrSH(kTH8Z1 zD>qkPYpfGh1N(o;S}&fsUpM#bbcZ$N)m(PMu?+e}$BpAo`I#l=`S21?c?rC7jL>MF zEB8pYYi=^cv=5$`wy`tjpLpv<*&XTS4@ZZhc2FX=fK{-3-=cbIXV;cjQ}W%7jpTc( zi_`cQm_UgQ8zVcXV7EYFCkC8rr^BovAQB$dF>pdIOQPr6$;Oo={|3rUAXfyMBHgk7 zM@sugl-dD7a?Di@JiV!~EsZ{GZH#3%=lI?&f)VB4e)@vK)-?LA`#u5jp>x`d+V45b znWholw(LB_0B6&{3?%hE`2V4kH3T0|-u;Tl5Y!XB-@q5S!e*Y z6Fp{S!Z50D5p9K5c2&pV%6-FD*oOMX{(9WxFVG?%&r$87zhg{>bKUe2LA;|tw;6Sn zb!?U-AQJlmn(T@`xT*;vxm2-rH3`( zMcEV4lf*VYi-0c z4~+ePME3vJzK7tK9CL^RC$1_Cq|p;w%JOo-9wDh8AGxYJv4;;jK$~XbH-O^S6d8gm zVGfIS&=|t?xne1=`2;Km;SJw4*TLSz{^yX<3rzw0-#(}8U#Zf{#PVH4`4C(Qt2ZY@ z?f+$@y(}nC5}o55IB|Ai5WK@H-A4zGzR$D??}4gK?Tyg`yC!yz9oWkaibmw=(>{;& zK#>4qB>ok}mQb>YZPF+_31?r)qY2?k%aAaHdZLH5%=-S{KO+RcIe(m7SQtv9w_G_7 z)!u+r^P<@WGtIiQ-e}F3gC3?Fedimm`~Q@74oY1H z!TdembY9`sGMBn;Ex7)&r2er+oCzHU8K>J4fO0%wUwF&&|I#qy{oIEb5(O0 zlvzN;23bDa6|^g1t~JaI*NTyzjne+V1!*llqEE6PyQT2DGP7e*1YeRZ4%exW=_ZdUqGoZBprOhfmz0ZH+21D!}$NsT8#ha>%v{$N7>h>${n9a=Vq@M=?=M8Hwpev z9K;#^sHKVhqo)!6)x&XeyzquJdh4AbTzZJNGO^~6F_Ev*$U0_?m)th=$K{UeXiFp@^^ z&V;hnypwI1NuvL9mT)rG*flXeJ~BNvabS3SY--wB1z?6)yac6#K*VI$V{2g~_ww=0 zg}c(|vBt{NXN(=#J$m2p*nvG0SajAQNx@s9!C(;3u0_3b>Af!vO%jdC>B+JEO*!Z| zaf+NLJ{3QOqYMt9v!a7$eSq(G1LACIHL&NO<; z<6HKQr^yO*1bi}n5Vpj2GO0$^TsMTsZe^Ro-%%}U_@%>`gf)PUJhKvan{ zh^w)9Xdq?Liq{6?_y55T|5JIF>XcnD!&U-QaUzhLP(q87GzTn4LK(DMqKy-(6IK}{ zDuBfcO@Sb?F-H74+i}*#Ccdsj0H{kp)Ef|8xff}2L?w%8RT>F z6fm54%5b%@0#guMC!{%==}0Jp_IczA@cqAiY)*95$UH=PZ|7;6<8S!R?wkHs!w6nyO+0pGBh?O z+GgZn{Qv)nkEW~17R#eE%TZ{LA}KO2REAk6X6R_9BcTjCt)@_=k77F-;YcW>Re@j; z&2pA3M-x;etJ0#Yse<0fz#OpT1hD`A!90>v3D*Lmtfq1$9>W@+IV9#tm?c7;2OdLt zLlbetN^DbUuuwK3#mR@Luq?+qt8T6( zQ3SlPALvPD8|cbmw*Pku-GlT;AgIRilwKH3qYs?#wzfmz1e{78-3uwemjNtZXmPgF z0n3q42JQ9kZ7X%}Y<4y(&Z*M;2G9sKqG$INcBj!F57ojPVC?_jN&ioT>L)7KA(F$a z90^1-lKvk!XwCS?HMySj|E$Y4$Cb=O1%BFq*Z-x_5~ROA^;5JLB93E2VJwY~1zhAW zJ}(kh|24ejp2EH~`i;Fo-JG@P72ere)zQ(})zOjdYVXRfUb!;YnOhlXKNxFJi`f## z%i~Vt2Ed9$_L?>mhk2F>!il!JVzWEiR(GuK>}p%xzN(|M9e(YwS53C7qdnKvxvDLf z>sZ+?ae?Bn0mO;164NQ+wCJVSStvKO0-U!H`@HiCeQfGbVJ~R#L{Qy>oAs%QJ=4Sc zMn?|9%O(5ArdhMBrQlwx0^8Wyx?@IRPZ}N1hd>Pd(5}hR{i6q_N5+Q_kL)^hXurcC z-4iICu-I{99@Z*S8l7z+YZV!d7?{`hnQZ!G@!jGHj>!VYDXtY~)k~PTC6#X+M&iLQ z?g{G7_%PwtG5eGt#2XATXuicM9IFp*Vf%L|A0t%IN#o$i-qGP*6Ne5c-nA3Tv8wb; zR!sXfGzw?|W0dM{?_x%QRUuOB4nbzDd#-J%ySZ$|sx6RfCE{2hS;T!BJHeZFAL`hPP1*BX$%EcN%PPeNoKACF#A*q=rxyHw*f zLBe(9BwR>2+e??rY)RRUBBFh-E{yBwh@WVj!)MHj4TZbiZebM@KgAa|EPkRpQHWVfT z0g;AyHt=_VTRku*+-fb%*Uei{THJHJ$1B!A2iyO-=vt(GPkX1>7c6l!m7cj*Sbg>*Pn)JZM6T<1ntu+0%$1$Ub9x%T9W^7Se3F zVkuI^qYN%fpaCN-d3R&ggPUNgd&iuIMv@*scKGm~!%MpllVizYc#t{R+-o#|i0p^4 zye$K_*qhAs-14@SD*>;u5+6Bi|GKsw>A#!_iEONnjyAxZ$nX2%oF*lp6LgSrq#_bd?Ee6RzUDej@iM16TQWB8a?Sgf#NbI zvwV*HNZMCps7o^EEydE*gGGQgmtCK8HYJ=xCsRvRbHUjD&qr&){xF4dttFbM^`gA`Tk7}ON;00h`*L$;WW#% zu#}eW#^QN8%CWjEy&KXqiu9K5*A~y!(MEfD1D;LLe!aV)c#e+vlwS9O;@LXlpWIx7 z!2Zvwy8R~>3wBAyM00BhhVB0xF!a^iRHa&%DC1=Hge3a2sVk7v9p0a55 zL~wR-k&a;EdQ)fdA|3IMQibqB8;TdY`a~ax%H2u#lNT0WnMUtuW+@haf42-OE*@;M z#MrfO1a3N-Us4=md5GJpbY*iLx!fvveIeV?3F}QRc(kGT3RnzqS^ZJBx((i}XwP-7 z>Vo-zuH4F1t2%PomGJ(Bve_@a)NM`%O^@zBI6P%zgPji)idD$QCMAmQKu^Yn*#dbY zL70;=EW~VP0hjIR@9xH?T!$^U2!@!AS&~jwfp&+|OT^j9%ZjqRL8vS1%QWn($7}%L z@hFeTNMshY|EWJb$_);25hxLZiEey z4O6ZRLD?Y7%@4?88w@*j66;tCZFM5yEl;#z$g=ebOn1CIes?zv%&9-mHaEP~jr;$z zwbe);)Hmo?>*u9@7cP>+p99CIi?4xY4EuWq2YWVdHkKYeio>4m#>~ti;b7BfvSP92 z2{@HWjg}B|x*f2Wjx5E$ol9k~ayg3>I@eACZ^+-+3;y0Zm~Jl_S<<>>=aLy_0`gfl zc&yrMkC}H<07{~Lom|tr3IhP{yDWDKbg4+&QG7Lwk#cgAf$e)ICk`Ei7gP@H8kr{d zQPAlzDFUTUtl={(GBhwSV;;aUW9H)Gr8??jaM$b~-9IsTWDS<+-b;&@=t!ko7|1iW#|pRbNQwZ6y&#B|D3`sx-TLoaFRyW_t%bFz%zN3*-qFkWc8{8u%pC& zdl9yFhXDrE3^rd!LLE7|#5axy_Kr?9HNX7)r#EjM$_(}QZtdqKGqh-vm0+eQD_g{y zjkXh49{m>h$PDf6-#(b{+2kgSO2NfS0m{GxK^oHBvn5{%?Ew2<6jehk4%dMIIk(tN zT?I{}t{Sd%1<^FuY8O`Rn9OfOTL|sIj=~r@ytk>n`KvF#{E3&HZbtA%v}BvQq*#u+ z9}HG3Z1bL`E0lbi0E8}cd;xIgZ^+pokvhb4VrNJlBCBc`lOqRqPwd}0KC!c@3pTIH zb~H<#lNH1*2m0{om$1#oZtwx-A(2GdBD&R#gaKxTS9P{|U}z^8V6uc_0Q+yGXap>b zBnfgyZdF@n&I2-D>gz>2gNjQvb#OBFux46kX2SSPQ(f4>KuUzx0h6&91%5({$-&6Q z7ZS<7QlomorAC=@i`D%y$P!d1BUmwvAD-vole?}-g)IX1SaM>q3drkycttDFhY78` zQB+V~J~FDcRe}94W@3CnP+2B?ABD<@o@ka!O7OUI*|PGLvMhr>5GM=2;1Scv6uh%A zdSGg7dhGBhyaRCeD9wRzEj)sHIP7ycAX18&`#>Frx4(>u8N=E0#%@4dt`nZdJo%GgSHVa@8* zD_5-k|Ujqma@jB0)`l&x zr{l=3(WV@GH7M8KxthG0vpSo_@8ukY7YN`Lf};jp(Bo=al+|F#))~Jt!mn(lvo`p= z9FBBaSKigI4wJ)FXs(=;Os? z6Ev3%kA%`D6B^cB+Yt(kSXX93{0yMDDvc#xHZv6v`9$NuW(D&hPt-#nk0PmX=gMry z%C;`fA6r9|WpOXd4no#19E4J@*1v4#$P;8-z?S0EK|*ym`;4&7t?(W#rdYkPi}gY= zZ50k(EBX@w_J0WlR7+;@rV!UpHjrdV(gokTnC3<;4eywmi#I1ncO9CX!UNRl$+5kA zM<=J?<=)9X(_{Og_slh;mgUR)XO589XS48P>b_A}qYp32%7;1dHJqEDul*rDnAZOA zhcCg^%vw4!B3VLkmBB7{&fEmAQ8c5OUL`s}?oNwL8Nb3F4l0R+03;%dHj; z7(kILyjBo8p`Ax_ZoBZY4keazJDOm5BK50*9)1V58s_6YlZMc30XmwtQ8X0BC+RZ+^{(Fvn0Uzxz8nE%#6?M$2WKSx*QMt9C$6SKLR_m}c zDFXqu|4UHnyV@o5)BIgp{pjlAm9SCuy$V%_=OMS?Ej~?Nn(N*SwuZ_~wqN@dW7Wgf zic_7l!<()wI^eAkdpzXu2 zyjl{@!Mmt!uv42LE*0 z{%Ud}n~br?0q_YN_OXL2C%U`gu5S72&C6HQApy%VnsZRT1^53t+JWHi|Fdw4=@=|7 zg-zO*d-!5;7>46R`GMO_0>QS;P1@~Sv~Mq717KSMfTgch1%vw5dx}@5(fjxMfMv$R zzph~1OFpK+xK0;|;VVm98knWgLf%Eh?Q?K>+fyB7N&|i|ZFKMC*z^(DCrH(|3RgrK>h;cECqa?g<*y86n7W{Ey0acWW;2qyC-ZcZ23 zccTgKP(rjD2-r8ee*{{A&w z^MP78;UYZyzlPfX&yb!;U5I`bllj*n7`P)`=5j~KhKF{S*J2_*i^AOjUM$HNV{;xmMpc*;aq`*VtJp!(LXI>+)MTlW3TR#5vuCDBGBxn z>NFdFWSJcGa{sTRF{EFn{WY8_cN{-ZTn^vM8F45A?(XS)ny3$vl#@IM?A!GR!O)~@erhf7*8pGH%FtoI3;3(`J?sKU60aB&u z__|^%a9pb}$E~&jS_dxTDJ@|JC~UU39*pDIaIpn^!bV4{;?P;!h*#2u=!zhW27r5*g|^+FcE?P&t2jpZAw*hygfPoWbi)dxY1jz>2Y+u*740*6HqUAyIw zzsiLv;ijG{u?jLV4I7^F}!1DjB!1?sZ4lOA^Lz2MS<|JR>GVg z?f-8^sa2`V(9KLWBAsDz$Vy>xNXtf;z8mZzrzT^3~-L(g5Chm z2cJ#)f9)Oc{2zkkr~?ihZ!dNU53*g|XsnjbT(gfC72NHXp23ZqiOaD$aoL@_*5JLt zdF4W)2!U;#vy*L+JG}A)K-q@vU(>#a;Flb8hyy3CDy~YSC&0GI=gF(=MdC4O%af>L z(jf7?n7oJzk(lNj&B|_A8qVU1C!cuYiF@w_TK~k=6N>O7#r=q4Ko8M~#5j8Y|0ATe zpdZa4_2*65TwDW71{#B!fd?zcAG@WvI*s1EG$<_EIWp$MSz>&3G`0pP@4eT9iROSo zU8Q^dp}6C4lTz(!G*Ci_FT8}QB)1+Mn2Q;CG7ur!|9=c=i_ph-r&({2r?(WZ zOQR28F890}HychtmD{btny9w7-c{^|1%df0pp%6b$WdSg^%N>D;D0z-XN_b7(UCYT zC6mL8CVUMCVlQF3J1o%kEd002O2~nSr>hz@?zQe`tAVaQaU@K@TAFA=`AooFeaO46 z#3X?22@?_~00(9n6PyEkJpR|wQlu?KzYQn1+`iYKVX3 zV?)KYF!y(DE!t1CtX>@sCC&xL%({qujT)K z<};gGHUeSYcRl;7M`nHx(?=O-mB(vzY}7cojT5R-!-3c-X6wF{GRRhCw$9Din&EQk zWQSdJTx%SWxuf-%ISD7glm$OyS?9d5|3LFrSXV6G)RV6ZPZe&9bU2M5@s6HsbvQ+y zFk8JN8)sO}_OgFE|Nk6H{Qx~@j#cXTbfT%)1FKqwYBvm*tPNi{Esl4UZtId zeue%HeFJ>~eHyZ2I5rgfVHHls6vcYjodfSFWVC!{=M-$*({e4{Vd#o3K-H4R7Y9f7 zjt)pM+~wBh3}f&3#Lg@6#uFylO|Lg*p6DuWOrxi# zs-T!Kb+Y=zrNs^4Gui8s#Ez_cP(e4a=2c_ip2LzAAK^{#a}vjnf9zyCu~Vl}c9D6M^DOYRnai zf>&#{vRPs^F>bRV(LlvwV%(z&d2Pcn@(I&nq<)h6Q0jK=8_@rs z3H>(U8;iF=Cx1KZppP!yc+^-5Tb@GK&0bxFGks;1C)zG?LGL8;{%mLSs^YCWVy|qk zmvHeNpz&wN&5@HanBTGuUjzJOw-tB5``#;^g!cE~9pl(076R1%o*9q4zS}?k`7h(+ zOZ=62sV)JETecxj8A4!1tHn12aZ-O{&-Nw9&Mpq6(eYP0b7QC9hmsA&L2<}uNysF` zmsQXlV?%Mf4-mFz(!kcfz70JaZ{~0JSrXV>8~`9}3AmMxMaqa_FH-aBObxNvOdW!x z&Ba@yg1S0)_0=ueWy?ESJ65!=YRz^Rx9R9Xhn(`Dq6)2*lDfN3-%#8Ngm5vF0W}#o z(~-1smEXV`52%g1MrN@6XS5!qe?s4-zc%&#)HA8Asq?fyg{0&N!hvI`I06=TmMKZ| z)HF0eB~hsmc8D>?$*z=eN3o%Jm)cA~$mAft=f>XtZikszdcL7J><)zNcYf$lxB1;p z+ooD;e+Wl+Pe-a#Qma!-wO?yr*M18wk|P!lY%1;rnJq9~!p4Dh>%ixZ9l*0-Z0E~myGQRE z9y_qdC3)iLL&hIA75C`qRsqV;I(FoHHuh}(_0T`(Hw}}0!&-`?I=WLVdfhsVcZdXL z{JM45t;=_9?3rmQ?zREGjsu2#5%9v|E^Dr1W6$>d`bRewcftk$=QCuvYzKV9$>Vq% z!&9TjG1i!r{oD6T$#zOS;rPPCp=f%%hiBKKp$}bpF)ceI*kK*9J{=DHwi8a0NE$=#W$wWTNl<^jjgWR&H>2+YicFWir$EO4?GB| zJ3nWV+7yS+oPEvq7#MnLmub)9K+-Dz4l=-$w9#(=8hRPw-~2gFo?RSIqqng66Un={ zxFDC_!mHyC?BQJSk4)D9sdPV53H-Y$gB1g%dCo7%e$`r7p0*K}FAn(3{{K8QiBdmJ z^`tJ;{zdz;_B8rA`X+h?5-W0CUOcQL_HOOK#{Y&Jk!4rrmzk$4^WT|ST|A_tBWBk= zKr(S~Wqy2o6Fw~?6|75=XJ%hgoYoP0*4;mx9~vCk)HBrdxA4`UnPWzA3dS`I_hxHO z8j!Os$k|j0-G3Us*D|ziQ_o=D{HzN-4H|UAP3tQo=0_-S_Fqdy;bIWxTbgH<9`*UY ziE(rWXv`HSVLNse*wT zq#j0e7}%3+-@ftacW@DxY{B8ss@vy#O2RYV4Mo(2A3yS3C?zsGJX8O|)@FUCg4pdp zIq^|Y|C9LsUrSw&;FlZ;2SRh;(d&x$!JgmjL3ZMC^9o}NW%3?ITOs>TBlrl-$I%hg zfg_g}k6I%{d-sUDOnBV)$nT=)iPK^T^EgCFBAk z8w7-bK@=Z$1JMzH3Jd~1@cEGNflu5Lp)px_7lAg0((fJi_V*6<_Vo4LJ~P9(Apij0 z2v;gdf8<|N zd{9U0&5jekV>OUpabU%`v0}xFCIs_M*x3Da*2XWfEm3%31BWjwD|l}r;}X0Ij-#m} z??AhxI(;+#?!y5PCsfp(&2g)l3!0}?iW!@#;eOlZ5V2k0`~P#%JxKq8{%(Cj->hGx zZH1k{?_q<0*w631u9Qim&zU!ju!wc-_}Vu3%Vo1|%d@%GY%2}TYkYazPDq6;7QHiw7~2$ zYe>Q%a$yot%8BENogOaE3O5)NPV}m+bheJn&mT7#ZQ1N7Xe9jTNxI185bi{?xtXg< zXX$7w(=vM{Uj3?4+N+oaO;;8(^MM!=yS|ii85?(Ux6KCaiV-><8-tB(c4O=}zXlv( z?2llGmDeOro=M%xC~ji*Hs8lDHc6gTaEz)JcX}RKa+Gh|YLd9=K?FN_2<_7b@ z{(G^SDEn4VmFT28;THmA+^Mt9gClZ5>Cv65w03r=ioN+tHwD{QaP1da=3}?Bg9BAD z7R)|D*Am9r{Hn^F@%Y|KudJIFO`iE1F)i4rewMfabx$WYch0lGW{ueO2l9mT&ke?Y zmmLCN!*?-jVyvnG9SkOeb}&A zXM{z;=hkF0>{osxf0Jyh+TGKf6ivk-1$D`E@e>x8}Z8eL829 z5J|@W!gB}wprL~E-hte}{2Tm|z9-vS!_f+v`4{><7=Xk>O&xe7pF08k{Ew{v`+L-h zuEOj87M2$9tsd6*Y;Snz+Y3t#Qp)=7V=blg;iV6A`JVq{F4?NsBL(G{0}uY>SsXq# zaT%p})G$XgCtp=M4_*ssXOCwp_{>q|cjv@-)+UtbGE^8_SlF}v;Xv31`x^u|5@`VM zZyMPC&(}MU{tNvj{VVzz{p0#G`f>fR{zm- zL$4^kN=LmL2jJDxdxS>M~= z@NMYHFR)UeZ~ykUvHff49SHyG<2d=o(j~Cg|MpFJvbV1NZQ8Q0#a$LKFvEg)W8c;d z)>T}ws0gFhi%fU*5LOS9$&3mjtRQH$B*P#ymbVcg=1H{hT(bt25A%Pw#H#d+x|OiI z4@O8e6yef5%zk;?G4$X z2rP0&V}XrF1WwS36o#!TBEt9?!q~;c0LRf11}kLFy9Y9&^3|F6v;_$9~u%6m}S*obTO^KY2ppX4ILI$?!BD@ks-K-Ii#7pgz9hOvZHt z9MOST$Z^bA4$U<;aX{L>`{0wv_|eRXkuQyszeyM7hdF*N^Hc8NL5c z!5*Mx8~-c?@YwyO*QU{%kCba>lOqRqPwd|bAN+30HfOGLw+AC|Np~0#a#+t)`99Dj zu0jYa1U48)D~~+5b_6eJwar049sger+kPs|_whSRm#5L&)+fec@i3N{Ll73!AkSj0 z(sHaqU}Yq3SCvN|T;+q8v|2OU>9<#kp1oAXE{pJa=qJ?Fh-v5ccQ6!ssHVzJgIf(Zl|T@!sh(@XoWny)ib;4q8Ai zU=dQqXmABG+5)aO^G1qg92lt=DAk(=V#|WY?d%h9Mpe51dD#oO9brvW9~6HMs(uWz z^OBq`&o0P{WA{S{rZu%db%=yByRphWX+>#F^23?)acwb)rVyBaW3DBaxBH<>%kj!` zQf+l}lZNOLa}DA3KPd#C6Z<$00vu;58+^vA6848rHx* zQIuu*aX*zRAA=1-g%DNG{Aq6jKBAS~F zvvaZXt+Zhbfe`F}udTM{WeCuoaNIM4D^c*0?$~Hfa7ckm3bRix*aL$K{#4!@X<&q2 zVAy<>IK|}BK+ojLE0PVp9brx8dF$>G2iX5U8>50<+Sw`8@=_mKEU+eKVtULG7@-&K ziRueN4iUAhiooNjk954TR}f(ZL3_7}iL^_=#U&q+awVsxJsSMAWV>0*{lwk1K zhV&;=AB9upjuTy_tJCO-sWMjZ7{=tpp#!^{*n@W7-rnsz3f+LQ#w^uEKjOvnXfanP zcyCW$HaHx%N~6r$3^UMRA4-{9gSvmA!Mm1*?$JFD47!23q5420r9l;V=Y z099(LbrBd;2$5LO%~(~C*sxXrXHB^2k2H+6*qG$FtN_=7D~?xF?Y>Uc`AyM8?0dUu z)b5^~*W8!k&uij?C)gs+s-7t^EDW}m0-KvmE(Q2)r^^sd_L7Qj1!=p^vWSMtIsNQ8;+g3L-b?AkN zIcW6K4B69E96<&thm6;=WVXrtxzs^P&15YjXRkI{1+7xmu*m9Svsy`G7Ix*$g<0Gx zRSk|X8ZC=W>>u+aniNPa%2LTNj5%rlr2p5iMes|GgaZi&ygBe>zO)pkA{NexQ7+v7 zAAtXR@Qj*!KNZc3nthV&LHYch8#W79(!0``PB%`O{1r~s=AD3=MXODMh0mW&$>7L7 zK}~LFu)Fg#ed^499z}C^eT`W zCbibEWHigH#Oo~kZ?mL_->4^Ts~1gU{0+x8R*RikYZM%2Mf}cTg&EF71B^ECoS&V@ zutX`^Uo(HkWD<^1_0n5LWLv~)cDY;EVKpEew*#o9MT!{|IZ=> zzq&u3>nbfvqnDz;L!68-EERT-g|IaOB=P@*4Kc9IE)&+9DL8B|>UQlx6^#84!T(WK z)uX8L5rKlLS=JNPOTW(~z|NJGyHc1H@4^%9%9OpTCjR~l?Ek?;+v;mhhRGwGNhZFG zKgkKlxCpl+bH|tAF+b~d>}RHjte>wJ4Vz_yj0pM_@|n*(U`PmytK4m@Wgv0msOkNG zO1l81J_y0QKi;gDTGQy==LcGkXiQH`kBkrR+Bb4w@90!h^Z3}^qe?Zk)W(X1s2m+l zTu9=AV>Mq9vmt?j>BH~aT53t7(v^Y4p#YhQf4pq(6C*fxrH*(!iKy6U23Y(6HhC}2 zjjntk4?(0i2DFgq_ylBr=BPkoX^$dPDKV=Ciuxo}Mx}Y_PCQ?Fk2lOA zrIobHY$CL?;+$n7Y6n8v0UK?h4onkNXusCvwN*K@J>Qq#I0z`)+N?JyW@a*(8Ms%< zykAZ^2ZHUDzk{n(n)iZpuDk@(z)psYcCjH-&_cK13*TDPTc zIOgb)`2D+d3oP>NT=AmpxJ-_86|{|FCHM9Sr7AmJP&P|k0SHaVtnoWs8kyL?D|-WG zfc;-vpZ3qE(zv1|_Rswp=LrlBmgAW)$JY1`Unx|MH}PRKQ{)J$~lDhCCy7 zHj>ys+KKS5GRNbWma_0+fYtTaKdS75&X^i4D_e}ILp!IYCt()1ZAGrRg&b>k(6i&p zv#?OhvmAy>${HLCz4W6*K)`CQ;d9ZZmc-xD6JC_3Gol9D;JnW=(6gCQAzGm3o;tNYd0K0#!2X}a z4Cg#c%tB&^X#Jc=Vj?aLN7-`Zz!L#resXp=c+GRF%_vM3J_3lE(ErVH1 zPZNJ1Mh|kUeFC@AR%^_=k-XAnRjd>*=vsc%+lGlx! zzLIyn$31 z=TyWjW?Ks=Bg9bM0$w8N|GlOR>HHvB|F3r-_$5cefrJAAIPmuCN-NXoBM$~x)N9^S zRC+0Tvl0JcV7kp&MQ=}eOo$A+#t81xK z{a~40n5wcW&FvPW3^c40EgJ-I6b~14_-2c;aLnIIK5#wP3`~J2*Gc@ z9Vbz#D~;ZARt@}k*=AKMePLEr7gPP57#`s^AXzuhc4|0exy=X$d|1zc^N0@-<)ic( z)(6fL#{a1Y5d4xO;XpMx@TgW=1urw6qj0~*_{6=V@alClw<(A$%dF?2n9kxfpIwo2 zgetUt(27CJNmStrf!Lrhf|hf^C18XS_W^V93yQe^Pob?yI|)Jg$MN>knlw70dLOnL zGL_pXGQu?{C|84)6Ood*fLR5D==6!hrPXQlcSrfYj1QS7!DuavSM>W=BzP3ZJtH?1or=4 zqCo+h#){1eamuD+HO#-d8x{~XO7CVzfd-@T%Qj1{{bandm^XN*H7@0;akIyG7yz;G7JYjGfY(( zI51>B&0@vuW3|9WU;*&+ZZZ>m=$f_TH2m=)&Xe$3S+0%A8s~Dw>8q}N;YWTx9I+@% zZfz~$SzJkM409zoKX^$Wy|Z}jh%pdOhsBCIh6}7pU5w*6F^;iC2F+Y(9?hp%?7|Bd z_#aEy!HX{DF&44y|9>uh{;zA7BE2E?8aO2f=fK-1OKa2Ux5jMGf|j%4C71qWMTRbb4hkb^IY&zr z6-g5A?yAI0N`j3tmZ+dlD#^-8iTFau2nr);ITu_4#)_a9&_AvA=@}~p4@qed=jimOolkiQJA7sl9iJZ@r95P6h_c; zF1Q4YHAm0a|HJtIBMy3n1Y>;LzZMRJ^h=25My%W!0w6tJI5z>%DoiM<{x5g=TCl? zbK<3l3m6GVYeXQvq)L>)MeJ+^`~NKqiPLDTJRI{xpBOP=R$|1m&cIa!miStRWPkN- z#NkM#+!MV{TeHAX3`{;ei!wi#b#YN({~xu$iJ+uWGR5kd%`oNWlrZq4}DcpsMs_?RU}9*I%o0I1qd^KtDxMQGggxPIis2q>xdDNZ#Gv}U-0~&$1q9eyC7#O zqTn`9MJdW#A;iG)W_aDangvM2=pa9~*12GjBwDU9xZnsah{U5=+9AbU7#yn*MT8MZYero7rr zOwu{DY(2H6$)R%9cB(M+{M56DOFe1y$MVJpH4y?(^YIVAu5^7G{YiI4RlDkPb|D(lB{IlCcUSeAv4;?D|gl1koovDy_6=%9c6#jl$tVt~x zW_U$Y7UG@*B)^GatZ9{gE=3kdfl+04X2|~ksb3-ZB}c-6`M`nWnbJnsqxx0CEI&6& z<_LQGo7%FxA8KmDFXhwq*T%t-$*IxF;pxedU8CISvyQ_MQ}VZM>>JwNyCW|qX0y4@ z_SIdv?8;Rfju^p9^u=q%_e?{GE5qOYgo@c zx67UuA(PNv9HNUptI6dxjw|*{&h5lwC|zk;8eL|L+Qpe zI+h7wn`8*D)~Dmwlx_gmeM>;d$d+MJ9n~;#for!w~LX}D(>R_^P z@#`n9D&^DYi7mC@l+gAnu-+~g7t@zyFHjhldH_iCnU+bTTz-{Ewj3HbACW=gvVvwBVSpx zXeTkdxOhv%a?Z^`WWd3%s1!I7_lV)h5(zTn^}u~)+mAO%$#uYZi5|ZTsy8?E^b$Tt z>pLZJ*|ki{WEWun1V*`rM(?<}~`d3G0z;jpYqQJqQ2KJ9+EL zNn3Hd$CI*a+`{C^CXt4ZI6bqu-LM(g8a$-3RLYZ7s~Byy?b`R!6FBF?+@_%wm>I{KN<&JkjlGm_=As~XYQ2BpIG#!8v&0_^|uo_%eNCidBb z9FtD($1|)k?CirO&ul)#tifo;OJWW=kj5s@|CpjgJqJ>-=vK{ClAS$uuLc8c>;Z!g zwnM3Bb(RSv&;OF=f8=G>N-UdnSp8gCVI(~NgZ}>y6rV?l%@Yy7=i>Anoq97VUH;I= z1s_}c>zS?W|KS}oLK+R|SSu`)8~e6y5P(Qg7g#b%9y~Hgx1xvxxv#Huz9m zpA8dsq;YK+Q0~&UI*>2e{}+TtEXOaB3#<;I>Oo{2nH2&_I4bh9=KEN~en8EHzHpAq zNB9Jy6^JdCc95nLvI@$~i7HG{BDR3UUBo${M?>Op)|87|P1(-ucWQUzO{S6mi(ps;+4 zS@ono5#%ehtuEyY_Wy^R*_c8feuuFncUV5G-~`c#s4La!?FFlp9Z0S{>FtB7w1*r8 zAkn)-8+_qXR2czPbiEURFnR@a(tuP^)P)?oZV4N4M(*N5`Y5pfKeBxw)rUzc%3^1Q zHKbOd3&hSKeLc|a0?UU9VuRg*$eQByIa(Q>3r!51XEt-tf*w@sz9bgKmpLI`xis4@ zDbsg{YcykR0DP>d3pq4fDTTz`lwI5Z1B+!Mz#yVo~FX; z^0NyNSx@TR>y!O|wVxpPCCA+4K;gmCP4J%4!!f>hQk}an$9TeW6=Cke1Y#>--_#rU zxB|~?t5w4IpF0^b;sPdWt6=Q^`&i|h1so!*HIeUjWfy3I_gX$6P~aK$g5g*p6J-ek zEQYX-NNWNePmOVc`x3lno6|9D*LZn`$@Su7hyktsSMC)98Ks=TheyLpQW0 z2SAodcbX0-=F*$7zQZ${^_kV^qC5$Sa&zP01Ws_lBKOC@RBL7|3>YO-q5uC9*70Tm zl8mngYhVRh6w##rCrnBDf44ra%=D!H57Ox+WjF_*|L;rsf8vznt|RIHMSch~_~9N* zh(O4oD&GG8%UF?{g^m{Ea~+J(QA9PzUIJw_I`;+u+?CLXVY^Q5|7Ymus>H5-^GMSCHaXhi8 zw5ZD(9sn<2z$Wk6g5cuu1XF27g!eCzbl$U#bCy+1)x~p6oDf0U;xS?H1XF)%X=4Jp z^lUU@0RDQVsaYew8< zRObmMv41dn4SfgU-<&y4E-h_?4*_qFHbC@I7|F+k_As8n=d4nPaqyhK^OIG)`9h?E zoPc|PuWrgP#hXQUJHqY!a)DJs)RSwmIeyR0lLTs9q9T#(CNx}o#9P3+VG3@o*finB zI97T^u8Q~=D@lHcIqg{H>FY`gk{Fz90sH@&$VBhriJuU7B`LD+SUN^O(cbJrg~NT% z5l`Z+lmatoRCEN@c02+;HYMdkjy%s;E5`%&|8>T|SpB3^6i(;E5Rr?P$m?Ef3lS{4(zltCgere!3D`lP^I zO#FnvDoK&6IY4np&{ZtqR8MM9xt1xaoM8Q7&25(JFWCP#qb(__m@r(m$A63z;~?9W z3dbN@usEkOI5f-kzBsJnx#(}KViB9>f{%4{p4rU){UzuECe~KD;0P-K!W;f zDS-X|r3l}OSEFSvI3h{HZ+K<3%q1og6WsdeVGjoU6L}@LxLKq2Y89wPt6XqYT;)Z) zf_8)be@n(apZYhEDS{fy4Ds)@DlqJrBW}fo!Bz1Sf|gT(y1K2f@~%d!TyTUXl{z{R zn9LUZ%-?f67r8hTWn;O-PXKQvMNV$9dAExB5}UdC>2RXIZsRfF95!(C-3Ryg|8GRv zjksWPMC8DqzOr=7S?JiCTtDWW^yl0+xGO958dgCc58{)}Ix7G1o7g=H!$8To&%x7|9uQ0_|@(4 zp&LsBY4nAQobU7aZCozvo12FrzK8~re!7)UMo3&g6Bf;0rwwEOZ=VH5KcVe`aPcGh zf9e0G|3d$n{$u?m{k!@%^{?n(*1xEq(NF20(Lb)gPk%;#N`FE>t{>G8>j(8W>bvzf z=(p(udY^tn>IbQBr@o$gG4-X?AEcg7eJ=H>)JIbvO1(Grj?`OHCsU84?oUmp4y5*_ zcBWpR+L79px+%3OwJx5=Ue^9a`zP(E+TUv5)4rvB zReM4EBkl8AQF~7Ng!U2b1KPW_r?od}C$xvO`?N`IT-&2xudmTN^c8xOzC?eGzF2>S zex9CA{ZHyYQol_7JoOK$AL-9(cWHNMgId3~S=*ppr*&#sZJBnJ_FC;??Lw`A`o6`# zd*&c;;v;AFL->I+V-UXY%svQzIj1BA!Vtby>@nKlR?Idc_+J5FzgaOm_#2)CbJ2jRf!ZV3BMuZA#xx)Z`pr*Zj> zr*jZqe>w}{s?#eV>^glVgq^1sLwN1!3n5%_`jrs2oW20UWv5}1cX8A6hatTDd3cX| z@ukmCLU_sZ_ds~@^SDK?dLFlB@$)+&YR;BzZt>{pWg)GE1$=-o%{R- z2+w&QQ+W3C%OE`Kd5kgr{MituN^gWvD}ll^{^FItYJO0**EQLkT$6`1hq95dN?<1mWM71|j@kr2z>4ssuc2{7PvXgnwSz z3gMrXfS-+jTIz%FPf9>%;~$r9g0NWXh48Z_n6YmBObIA&{B#K@Z~RyZC~thWv>w6_ zmexY}t`e5QLuXzC;e%%uL3s2G>~gdCfiuwUEk1JkD1`T(J_6z4)AvDm=roq{^l50z z;>pv{ip2*{-wEN~)6j~=dro7y?>>DSgu6~-S>JUU=vjQ*X-v;ErBx8Vv(yFQJ4&4p zzP+>(!jq*A2p=nfG#gKpu7&W?63DdicxgF=50zRWyuSo|Zk#SPLpWJ#f^ed=6vF+b zYXJVkXI=~OyGvI?xU;kb!rMy*gtwJ0hw#=C&fQVE48oz(t0CN8x)j2#rAr{}FI^1b zmJ+nL@rF_c!c8UE7Q1m{5!&9kp$M&R{DIK@(E(Z}6RL*`GOEKkq`tM%0~>K(FjQ-z zQrRr9(J?0(r11%hfCGGBq12CfS@g@7Uw)YiO_KS%8q$FM|Fy(+$`FMDL&p4NQ^F!L z{jX39tP{@uf+UJAm?n@g(IQ|&Q?5Q(1or=uB^$Lco2>#WkxKHE+_t^nt&b*Kt%c$O|!sq!Nc3F*QFS(jOmC%sVC4NW`xm4 zMULyvtw$5IMM9Xc#$-maszs^kc;3rjM=%flOW_j9P>?Vo87&JPiOCUiO0>vRKX7JM zSp*YP6pqN$vLw6GjqZMG1FyQQS{{{7`2{#+Pu=5O29 z*VEfi^908eY6RQlHSY&|WPWl@X?q%d>&Ve#4!E&f*aspiU7lpa3hnSZFcy9KvrJI9xpO46m5!K&n1~wRm;Kte_WQTxU$El z>Gsi?qMl{<5pmRp?;>-Mz&)$k^oB!}rKrj>uxLf(eSVWhiZ~$}Q z-VMh7Kce>Eg0z-c)O;=jdF+3S#PKDy?^4E1<6Bms;|a8@%47qFOx4OSRCDY!)8M4=*)JP}4UB_BlOgeWrz zRK6Nxf!X6o+9N(23>o|!0cw%|!_B48WxC(tHjAs7# zQ`eMkOQR3mQU!FD6(gZQ{Kd&#>1c{!+p$jU2$Q|DO|AmF|F78n%RQ z#PYUP9c?RDc67F_>T2(7>&mq`J^{fAqY*oKw(LywX4xU}>+SjfpS?E$l9+ z2rt45HU=9%FS6c~-bk~(nK#dtY)KZDuqV;ceileC2V zAqymdrhl5G(afkxN*YSjCM`(`CF$Q#(sXb3(ELr(HtP4C^*i^RbMKvf-h21zY3AH> zzI{9AuCs6Vu6y(@Z|vA-SwT%IQR!UcS!Dc_!CCk2y=TvzZ@p*TUJLxK`}f`{Zxa&z zetfTFfRJ+Or;fpq#n3{B#~Nn5veY!l!{4TM9_lH#WcN*@ZId0Q^b_BGq{vW8#gw={ z*<5`XNLV&_kUjC#b6y-ciBRX~{~5fX4*o*h3vWODUGMSUc>brlh zD+5IFpn~I5dlmQF;N675_vgPE0PWhUma*Jc;z4-lI}o zcrXAw#Xrk`nHgfXn?&$v7mcb8L;nA%)Y3f&BO0%U3NYl;H!<~6Sab|CmyC~5MMoAH z+5+pwyQ-9YN50O6{QooeL~7z;kv7YCt&-+wOo`@|OxII{%BDPJD_-bfXNpSNC>Om_ z?HFy>%yb9&|K}^~T1qzMVfYTbB+U+oqL&ZX&AP%E{#OO>FfOG81%ZNKi5Jjh;HPvI$ra)hD{_okrzEE5_kq7y6+GW0G`8cG0>lW zS?GfG#(t?8cxH~5xBiW{p4hp<_w4KciT5ee>;K~UpZi&UBZFT$9P;+;8&AKh$X>W; zCEYkQ+<7&=_zG9bPm@l))=fnwN0y$h=ym#-7zzV{AarTcJLu|iL z${M_|i~E1!hlJtJv%PTt>Fe)a&BV4d<`f9}V zSTvgVq_hernZkiNudXH;2a47}Udf)}QRa;CMnVv)N^RVQG`Tkg@kD@-460v!Pl>CC zGqIymQ=$-x67(Jp;uZ}M(Q7{Y&?T9uB+rlk^Ghs$7Cy2qvp{MKz+=)6_V<`{=#WE2 z{7CWviQAb7hrfUQ(i5i-6xpYbt;zK*7~n6_-K%jziN=t%1d0x-!1I6iQGOHV_2At* zq0E@%JfA$3^kE=jX*(Zf7>YGO)D^?!fz&5y)9Hy1oc{~#NAdli{~5lfZ`*l#xyVkg z(*=5V36f;f@uwbLKK5>S?ozd?G<8&`ejmrq(+|5ubciW%N@AVnp?l%|pAT8@|Ky@* zDl>`<3aB^Lsr&q3{$5Q58-9=>&>xtDmaH!&2Vk!mTPFAS4!}maVPFzkvT++KtO2Y6 z{*N5pSq9&+1LkG^8Rt!j#vobCBi)GRKL~;kzDU zp00FhMVUkX|Bc1ZL)Fujj*%gp#h|f;Y8f|p4a~tJBjbxfRrQsy^4rL452$sculyrq z2+vT7Xle#5>@XA`;aEC9&k7QL5JpOQV8-N&EyqN z^B)cC1hzr9X|Y7Zz=f5FjAUsfmwHo><;HyxzeaWqT*R3KE;5q2*|(zS_TrYp7GsyO zby>w+@kb*jJxD%yng%YCECe<(lBLn~R7>Nf)Q;pR!3@WRn;|M%5&v7mhOO+L>jQ^S z^ztIhqV*G67lDXg(X{B=tKIC$glevqK9oM94U3Bd<}@rjWS*?_V(n zf2(5q=}S((yU2cbv$|mL>%ac%GLYm~(3BoKdb-k``4|fmqt`@=(WnkdLm{2yKVuHw zGA{6Xk;6nr#<$Xm$m$aY`y%oQtTby?qrAY;pOhjT`~Ppu|03JK^50}%U<=UjZ5Nz= zPk~({GwQsXUw-kGrw_re`n)DN$5O~jCDLL_yuJJ3_@waMmeY^GyX+5)ft|d>F`(F> zhH-#bKd$J|vo?j;+QQM`iio+g4Qb~occhU!JYZ^Sw<6f%@%8{pFd{CkpH~4YNFZT*AEZ&bRE|yKipOZ7;7s{hu%4;oO2xTW&Nr=K>eLeJ*Prqbdir=KdYlElZ( z^0rE8@#51TutCe4mZ0;=XlH40{pt5pHZ%M0yy)~31vV!sN?|TKeVq1fMggxq{dj@h zF5zZQ%vP{hd?{0wTCY3(Sb^Q>1uC^Roqk_|z0(<-v5A#9VW9M=MX4;<@vqj-)5plo zUx1HD&2pt)sVvs&jdH!ws@5vaTBQL$cvP-6D+`N@^-6i6S#6=rg2>gUj~3W&CC=l= zAA9%lLr2ij{NEgSxN`bPfgMs1hnJ5YJpKs3!BOA!vjlgnnLCx{pn`5ceHcW`#UfRF zcYYxZ$ZC-Zkg&c7n}&D@uBU(9`q zeG~@LY&+W*6ANRQE>-4dW@Mu>H*cCHZzqP#sY3fAShJlcje&3tzAf~ymBm(Ds5Yw$ zwQ6H=UeK^VB~(cgxcJ~}Fe5LjU1*VRd(2_F`9ed*F@mc&|e*3Mv-?-zg`|c@!KmbEwxS@T1 zf!$4*TJQw$s`hyWw!;Oi%n4c>+OH}wwd^L0%O9w;fRAQ)D&JlQ&Q`Z|5=hB;MSp=c z;<8Hk>^M8X_5s4H+nWk( zql|+xV?dr+sr4H zTiVxy$Txt$?Q09{DThRDvC*tm%M0~pb72w1vO1(dt@brR+$|y8Mwu(qYR`Cah1P;^ zNbl|Kt3huy*%;Glg;8igF4d|{%W!I)Q*FPYz}{;qz1Y~IYNP(Hz+}2mYc2|jH?*%Z z6+tkqY^ls`uFfz<7g6)=D+^5hPPBxB6cL*Zz8ltDOYPSe*at0Ha3xr!TP=kA+V<-T ztf`O>9DVrMkp~YSdvJECI(K>d3bQ(V%na3F)5Q`tqm+~9N5v0++w7?#hGCCjvT4T)52*QZCxqV52-5-x=pfUe1W$$H$KPz+! zKVJAdg_jCX77i8OS=d`>7B&6|OU!fE!%skgMZ71{H+097tS(}7kZ43lPp1hLY4l(U2{qq=sF2LQJh($1n=DmcZnbX`MMc>3 zL0H|+)~l_0s{u>k=3=E`TJvQnsDQlu@RJ7)Kk(2a%e&e)f>UwP=0%>b0J=e%E&mDd zo|}=#554!%V~36&pL@B{UJ}7hh*ajw$%t=gw+d{Rik zas>g_x0~V^2U%Zx;M#4C_3ei4xu906m7r%q9|zqG+1i|2->#dUeTQz}ee?Qu&GfWz ziaoDgEwHOZA}&33Ub~|AN>8nCmo;<=pLja|y!KWz-a4Ww@U_k7DaEi=L_r! zL7N_2mB{fCY4W2aaj0~Ddvk$ZEigB3d=T@$n0u5JK9&DU?%UAFwvk%kmoIGZgcoW3 zE%bm0c2fp_^Xp%I_Q-6tQg7B5Ymju1D4VgTEK8gi$Jx1Q56N;WMzC~o;&AC?-O2B6 z?JfR0zh=%~s$nNf6kL<_ zFzpGY>61Q_oKE%k&-QqRFmvb%$=XF=SJur7r{Mk$Q9#u#YH*{3?`{ctD~d(IAy6(|clIpI*!ms_`!2b9F4wacKQ4~nmDwON6x$BO>WhmIYd zJ8~4BT6h_rv49&R`5jFMjvico9B&~l&x!khdWeIR6h%U51}eYw%~KB?<#*W1yQ>cD z!h4N)`98XIWV!PA%Od}8VhsLz-Cnq*eJlJp7~YI;CF>NVd$nAyl=vUNTx*HfOD#F1 zZisu!?lo&k06AAOc2skxJn%NTByXb}1`Vvk^5KCe zBBJOSS)^?AUd;Y6;ht2m$D5|u9&%0~x2ulSFL00Uh3&mXcIuj;#>YS&+S%R%_u1kD zi2VgD+%r5kcU${5AaY5+L@@Av^Q)XvtNlj$3+say-)7IScLIpL zUETgJ@jx_~Z{rgD-?s6_U3+$m7VO=)>kaL9>PIg;5I63+y!{UG+>{})^bnvf!N`5i z2(nn(b#?pgQMSmEu-)3ex4@Q#OExZTyko~bVjNyqx8v^Jdp3d^xosQwYyuI*=dRn@ zZ!=z`C>ytRLK{#}ObMlH+HVza0zi%Q198}Bv}%pzjisd>`%3M5#Iv~sX6E?vkw+hR z{P?lQmLGWd&|}LFLF=i-Jskex_TAz!NQ5upe;{&A`z?mi%*~aheLRj!OZ#@*bKpS% zbF$gK3vv#hAw$$x^|ZnIX<=b;ORd%@HyaNIHq@!ISZ$SSOX~T{#YIq-pn5?J@ZzGB z{B2zHIjLTw{bv0<&~=s_CG}dZ+-Ni#wHEUKRpc*puD0(Kk0^r1Gbi)|LFO6wnI|57 zbonu!a;4IV9ZUEK(3bZ80#gUA5u{lk!pVI54zR2#9_pP233HoTOh%TF_WY-p?wdmo zN604ycDDBoRKcD-^2N#==Kndl`&r=+3TF!M&wmk`*)}W-oVu+Izb^N@oF90-(B;S! zCQl2}zyS7(rzs4V+D2YBckSMP>mFWpw{1LomWmr0?h#y2ljWRO)=hjefrotHhp5#< zKK+`cUp#HfA!&0<8-6FAKgEuf8MQSWRErqcH`Q!yzl%(B7KLs8$?4+u{bnNJ7KVvL z9RI(IG58z)_QD(5@Eehzz!ye@74<1^=@T$eBA&A3o_?t*4j%8Qp`~3B;#=hwixb4Q zh-vvfwETcpZx3cu@^~1jp`fCmuf=wJQX96@AcK(xT9G0cs*%4eN+<^htcZ<`B~y}< z6*-nWtkcEXSJYL^|8vQ@XpVZ9}=ltn&HCnW9xek zl;k1_9yu&6VW#6^j$L#6u01;#yM5PQT(LsWuD9&i3oG!F0*{9__&{#QzE=AYeUL-A z`{Z!A?`*@{Al0#6Y3BM0yme>$cKqX;)m)IhW>EI5Z@*hSgpK+EjhX9T+g=v0k&v~m z2DX(4Fz;*Q4-Ot2tnS75-!~&XS82oV6TUbg(;ljZ74ceFtG5Sgs?e;|8f596GGV7B z|EqZX|Ng>lg)8&FmHT~G_2s|ndv?D4XpwzHKB25~dFcr}&E}K>$P{tF5H>gwiHn!)PaFh#?{%M0hpBW-y9-Lv>=9bUPFKl=99l=%YZmB>u-#`aOD zy%%})RpGc)(Jc|UdY4a1Vj7!m!yEnXO`sz{=i7(H+lz>at?4bNCPVI%oo#$=pFDq{ zSlcOrdq4lVU&NCY<+*Jnv%~;Qr90d2@e=W7oFqqi{ru;Eh*e*{8p*{>a&;m&whJW%-|~o`gz7s73CEF2NmFa@po_R+7Prz8+_WOM+gFB^ zgRg>zX+S+Yi2T2rG5GUrFWldL3@-8C>@9-P!0stkMjE&iPcK=9%oH%Llogu$kISO| z!ho89rSKiNxbB-0aqRWyT5%j>VkrRk|6e&3&Y&w3=P&{zm1NM$nPyi)I7O|UdBPiC zgT>&qR%FQktGH&XrYg(XCE~7ZxiP}Dp4Q-AU4cE4ss#D}2EH0o;V~_XGbPUmv>w8# z%6`j9wjO|W9H!+2jyu-oLf>fZjafYA_Z^7cvuf4@BPbwKJ>MCJqvjJXI1?27lw- ze&T5R@gn<|;$7AH)Zx^h6VE2Dsa!7dw96(fZ;=a~6Na__>*4=3qGo01*Z8GYEaB?d zBk@>hsuu#;3NGqMbKo(hj#Gg*f;DSkB?kF_Z7*EC2N6CyN6N{B*P*HW9ZmdR?Bey9 z&o0xsevk{sh|{75iJ4sj;nj-?S954h>YPX7902)$-6YrCE1@oo-+8^H%?htP_O0Xk zIMAyV&foo)sB8}4a}Qe9WF6%H^=|R+w-omNNt^#3J|R*YiMS4%d&S;Tsa3BL!RnYq^ppSAsY!~8tl^?=rHlb z9A1sA=tBPAfX^8CjhDU(C<1FX8Ykhr!5pXZ##>c9SrjeBF&bxQ1MFHC$%?2YC+G>t z|BbvXDj5bX1XHyF8(G;LEc3F1jO-vIIOlrHaio9@@321diSsSyV9a7qX9M*jsgZv3dT&`p&Q`X7?O*KtqqAp!{ulf5L9E8$ zRC6oJ7@p-rh4Gje7d4jY`-!eTHB-0d1mA*j{y0Um?*A#|?qP)!`H#U@whh4or)ur@ z!^=P4J3S9gn)AKtqypA_?@SX}_@_StOj`KSGUrwxkn5#`?I()t(|1pg*%C!YWA%GM z7gpYLzxxI6d%4A1E%DEg&2QXdRW^Hfs$rk?b-d`8}M5t_?V z5?pZtk9*B9s#|k|^Z!_vCf59a3B24lza{_b+}Ye$azC5<;oK*3&*a{lyDxWJZXtJF z?jm-U{So_FcGP+YaJ92eziG8pt2H+?c9$BB8^jy6`1giJt!8?8>z2+d;gu!w2Lk{r zI^F;hf`|uM47NJwn)iU!s`v`8CcMfEU*-kK{Ec38#~NGTd4+j}S8Xf&K*0LWIi#ml zD>c@4idN4C=qZq%O{E(2>ZHr7tzq0GjeYjZI_w4@mlSTG|e2uq0&Pq7lSE(;7l$(ou z($_fVSc6>AU)__0y9yiY^ypph;rl<%VGZ&A|97ze2F(=POB*{E7TL>csV0(MzD-Z; z@K456J0k6&MzakJ1XibvV#Y)2o6_#nfcy zbt>Z;5nQV5@l<$Z6@)1&r(!Qt$IZvSZG!9n0{p~J;f{O>zNTb*_L9y;@Q&flfyFx4 zR;X;Ep42Xg6tn5JiXUS=2_ztbaC#sexZ!NU!%mN4MG0v+dZgo5Pp%&c6H1>f;?e#YOh9V`D8i$~)RQszb*|kC83F6_w_Qf=WrJ z`1D%W1Rli}p{aX3T3f-Z1fc3_WNl17s`vD`MO<4b2&Z^ye2s!5wAYAe`p4}8Esv!o z3L46PI8%YYh7sK~p#*g`91_q>tX@J|_xC~-33D10dkhhy_-eLV5#7_D8VY@A<`RM_ zvOUHeTp+!7d)zk4 zKnmQRI{dwHv$gh$=Hzk^RCT{b!G791geBOpr$Z&6E2i#|Hq-ms5L`XoZGq`t3)s|d zWf%=7v6VPDPRDdx)6+dRU)3FiQ;ZZ~5+4Dtpr8Y3~|NW^F@l4{0K?uX_{V07*k20obuO+}C{;sOb-6iXdcB zbSdc`$yV%ZB+W4jr=-;V8U;sa?-W*IzgGTUrD#Me)9vc2dnAz9*S$eLE(8*=49hz> zSwFB9O&mnSaV&!mEsHW<|G#WO0wsv35rc4wndYuhq7tl_@IZrcwWv;U6%Y|3=UO;E zex#+L&88`7OifEPbiYRN^Rb}=r6a^`*h``ipCMYB>nn^yO+>;@3jv@UM8gSNsczg$ zFm4o6>}w>=DGH|;>3)sEnd)I0P9}(kCl;3G3({NmHC9ml9Cd+t2YG{_X z^aCBmzU~e3aUrCEq&|A@2QN!5q|Ar=aM4(!wdWj1xJl8*%CpdO~rtQ3;IMrXrv&VVnivb zKAXGonCYL^Y%&tssX?{$P6d<6Lohg(OpB*IpnJ3@aftTDs-XZ^g8O0ZU&j2ufX%VO zrwZ5RzmQHAEV+l8}R%T;$9VlD*=fBsz=~n zY2$J@AsT#&2I(_R_Q{={*V{%DTE^fYXAvyg1-?qkQLl%g>P&K(jv%>VP)FR{We6+Te7slf7ood4bYhx1FhzsUUzbWiv8 zqwnl&DYCEJC<9|@A7&#@NUYJ~*~60TaJm6PK*@&M-3`W7s6iN;4+Yx*JCblj8riQ$ zDIboNgbMY#wX;(qA>E_KLahx@5a%OA%DC-b;9tofwOXUr+}YXeB@%;PFIOsyt;KS+ zS+BP0<%P=PJ35NFN%C8n7YPT%y*tfnjXC9SY zf=BiDtnbX49-dOI&PGxqc})S|ns0C#-GKvFv)k(2KyZ;92APK7bog|L-8iycH^2oO zi1iQ)$GJ!Xlr(Wdm7Vfi_T19B9*C&NX#+&;`H)mMUMnG{mVl_t7aEeQC~<5B;W^ew zW{O?zoEyZasU8~FG_10bDswfiRb2W&C9=~Jr|HXv*P(r|?^Vs zuRc)IS;#Bzl*&2;Zw^~s6bb8jW^Aio>lo&xK_&=~VGTz1{AEqkpz~!Pd4T1$=_yg; zh$di*5<~vq#2Z${jGDz#I9))ELx=P-i=*n5oe|lD4`JCyBo4c<%FIz&leWSRAt8n_ z;e!QfrNRUJY{FNCB>j9j1aA&IE>WcP3JjZjBr8(J)QX);`crq36TXUZkR1M09fkRS zyI%NULk;*>KD2bCbg?>y>;pAjbPN{B#1>k2XmDxAG2^Dwaj~`ubh01As1W zRi`wO+VxZD!_xx$?N8C`KT?7p*DF!2O0Zu@0JTq=VOs8lhY7i=2HCe_xbEF=A? zgBap!-Jo14>>)o*T~DPt0`;jrUbS>w0b-keG3Q~T+M9N62k_Ck{1!ZU9rQl94r=@T zJB-EDZ{&4)h(Rkx>#j0%AY7I4gCdOkHT~WOV%Bq zUFd8rvY%J)Ygu_pXmhBVtu>To*S3-#RnsvR?&KpLSNeRujZQsvCv-gpES*^osF}>N5I)$g?K)^m~&EQ#|;!K3SB+izBq?lRN+g}6R$^!>dJ4OC) zX1UD+1^-$=e*Ugb72XlLF-vfWHc`j;63e%4mwhXvlAx3eT-4MDBC6i`bO&m(Qdvh< zs#A`tT|b2ZL^3vaGhQ&&tl^ju^S{V;vE29Pu3gSc#=GiS3rC_Y&b3!WUd${r;mN^z__$919w@L8T=l^*)*%x>A zq&@$S`pR&0a}WojiK#<6Zp=cW7>I;aakGFTdj!mChQTaqibu*?W27-Hg=*17sS!kO z!7*!qVgRDv6+n(goOTpQaU|FdqQ*fcVn=@Ij@6))(m^ZfXh&=uH|BK`p$@oevp{vH zZWzn!)?#E!pdd(T>?pJz0Jz|oH9#>CiO3o$ahL5OW6(4fu&}HVO%8f3wzv=f`DP8M zUPE2=Agl!{upL5zrW%ZxcQJv2K+`Ov(0Tyif@9VI#Xuw_mjx82H6%U`11?5H81a5* z95Dk9q8_s0cy~&lDH7I-jSGaVBb10Nkr73P3lbW$$SI7Ja(Xo6QYtcywG>;hqTb83 z7a!UN!oaTEJjUxezAWbf!3b07M%CN9SA+DC7bk0IYUWwgf_02tl=Zp4BR11xmN9iN zqJ*64*q>rqI1deEPxvcj(l?Gm&83KnAr&wp`DE2vN-)b5R5fgK7>!|c z%!)Kv$Jm8hJZdvNW)0|G?xKJr9s5%(iyZY^bU?j^EpnhA+?5h>ULF-K@=72N9Eud7 z!6_>gIcoQt1 zUM?@zE9I7D9`vyAStPu5uNalP7Oo#8LPrzVZ}-!Q8ibTMf|()^5){WZ$!G(w{}pn- z%nJAA|2uqT+X}P5sT(>i_(|TodcHnMW77&+3>P&x$gHnuaC&^lRG6VKAaZ(nU?(X? zKlxB+vB-Yo_Ayur4yx~X>Gho^JZ53Pn-WEmn>J6>_<8^UqhrIh8;E&3{NJxd3VF$q zBThy=W(lu)O$?|WK1Vq%?LES`T<+(PI{p?v15vp&)Gm%|C-< z)&Rwz1O!le!wHs({bbh-mV#6%Y;%Q8lxUL;Qi>9IXd7G1Rj-jn^`I3kQ0%}>1Bg+( zZ#p9u^8e1LHc{QQTBsu5@z}%~pco#zSg_nm9w60EtQzKy_&rJH(ZEB4%b=AJ9PGY6 zysGF;Py{Db)5)SFw{5L^xn+pE_<*7ubdSgEnxciId%b*YnFNTVrs}2x4kG1a34oF+ z3f6$?Rk{*5#NoqcjFV6(a@6kYBd7?=C_l~0BMbii=bJfm&tShaz4WLQ$jb}l*b2bX z9+nA$LV4cSER;D@O(7b~GNbO5TvAJ~0DYQCTAa2Fk9a-~5l%tl5ZxmK4x+{ZKub~F z=g83k)obEd^&ohZ1}7l_qGPdmYA}_r0-~ZkTmbPAY`d zJ09Jw0g4f(Y@rCS;Z66GFeln;C`}tTVr68F(QhEk`2pj%3Ze(+VUqbRPH7a*F z32VUQj7vJgX>7ZA{y)$Dkma6(k5#^%ytH#;k)0}$Gr;g@%`W(182CXD_G9N94lYXu~95y1a z#7C)AGb(zx-tg;xtjzM?VxNbv#O=j{o$c`S9ep%y@Ei)~8yue8^IW5|t;k+{A4!i< zvgBnz)BxIqLSWT`efVor*n|H~E3riQ0K)oH2@q4t<^xH!6N$|7f)OoR!aHpsGwR~e|2c&HJNuY8=Ik}_4oOi#*8k0d)H6H+mZ*g!%+8k&iDlA_FuX}hMw)mcW zOXubydv?ym90rLg*oiXu07CNmVBMve+ry`FHA{KdR+=)+|9`^@H|1~29c2H9{hJk# z{%J(Krn9HO_8MooxxcM(uyY%{+k*t13na=3&9O8vA`gj}C-3UK5rT)jJ19tI@T#TK z#;yZHDlSqfOxcsqbasPM>gT6ify)QWK)U^#}X&xcKpzh<=K+hDbI6x*uI&^jz4zjNEwml zD|2%6L}}^vH#4?x$F8@RmS!t3u=`dZgs;(upVcn19sA&iwGB(&>Vxl7!`L`;2*)*T z1T^FzUc~i(j{PLVzbW26aYtuwk^Rus!%tF`o%}mRit6B3h$(RTNbBJ%Dg_^%*jdHq z6Q_T+9RCEGJg33Q^?Tv}J7Bi=3(Z4jN&{w+Ym;QtDx=Bo6g6TDb!AN^s5~H9Ig7gS zdI|FXohxkdJB_7u^7)>2jgeW;9NfjsdTZqX6!QPOA|a7QQqt*N3{7lCpBU>BA90hPMi&GZUaDWGEBgp^z@gl?;Ss%&lj4AwTCQp$~X;Xd5yxybO z<6VzV$y#*H95q1xze}9c?=dV^TAd%le7g!Qlvbt8daLxP0rLNWv0mQGBFPs?Sso5@ z%teo@!XtL@+o zr#v-{$nO-h$rxs!HCf90C?DDtpXp;AzN**%7|z-HKjAKJy#Kez{)*+koO?RA0FAY> zwL1IhqhR9t=l(nIktqmIvde3trf)_z_wVf70nZJsiyR3Uz&K=B*N7YRcXsx9h$!~D zCW~quD$UD*pqUo<~YJhbb$S^#WJ$CQvAlnnRQ0$BSW!2EwzZjt5xYyOAw@6K<{ z{blYy=f08q-rSp@Guwg|Sl@Yjfo)I~;A`7UH}CA+OY<4J5z=cz#UP%G39kY%?|w=_3+dS#se@`@`RGH(9zJyRpxRIP?umi{J`QBzX)XRl7Uduy@bRp( zXK&;K_+VFbA0PDcJj?};a_z$aw}KL*aQo7}9m@~j4uNZ0ydOVsi-ff3^h2viB`5-% zbf`?>q&088r%CIEPM;98;wWDR6_i#})D0n0bJCJ6jKk{nL_3065-l+fNwq(@p9Dwa zvZUD2*y5d7DRe^GM)BS`8C=;S9ZAw!tP?#nxNeL;|Cj$>27lR>Szyu@_~>%yz9Ren zJJpo`wSAj;%G}V{BomP&ljtEGG`naH3y`d?8&h%9!TNt0^FPmavD{|(=x;l7Yv-Ls z_MHn>v(La(k34@@=N(1%G5rpY)f=07UcoRKXf?v)%!J(#6H$=Tk|xaV`tXShWT~V{ z^r38T>*JxZ^{u*;8c}1LrHpsQ2Z4PE7y3{x>2kvom6lR&zbLfV42oWl0!eU#mBi6! z3=}X4561;ivZM+^(Cmq$Wl4*UHKJtELSch?B(pIZzYniwhk=&a(2Ar3^8Y>F!XPbe z3@#AEQQ1>g^cl^*j7XBpsH?FPCW~~Mq_>PKfx(TMd1d=T%p@edh@y0H?z3=O?`VJP zhG3E{?~SpIY5Z0<_J{m`uZd4+86rcNeY8)xK!R(MY(^T5J(PUad_5-^6(^#+04E)O zOB!jR)dRHRm^3>XPg$IhS&SY@RFM{LL}0$3VJ|6%U>9#)%KbgkYP z5wQUJrLO)-(cr67c9LObH96P21O`{ObjRw;S7Dvuc?a_Uh_<+H2m@xbfes|o2;@b& zDAxv#nY#%q>1>VV;T<<-uf}!EWUDD@Vr^+KqR)S6Ev9{-8-nsm$REi6qe&}UWe069 zCxTXXoi%PtYl&>mQ!ycI7neOcY5-KXL+Cz2Y4A`CL0nNLtZ+~bV`GZSsF9M(7?93i z$PKP+>5d-K5ij}0aGjJtY>iRC-tCi=q?)2`2qr6`Y^N<$#B4%K-O)pg0H!Zz&_|Ps z596}5mPm?*Nog{UNDu4AulP%2>d*)|8{q_yhHzE_dIW)2_!X{zK~OW?$S~i}>V~lh zHwfCuGuN)Ix)CvfHjHivqfIJ!#Qi^)vfOrdsk;5=)D4~c;a=&x`n#bA6*EQIgv4m{ zGy$etJ=7$PgF^RFtv=r9d{>cuR{u0aiT~f%b#`886*2MkM zk@r*9l{ds%1NZ{KuShJX5T9XKFqZLlmFv3Lo$oHPm-G+vs>5kz|D=gx7}FQ$ z<*$gtAn&KF=l66$H=I~A*`Vy(PXY`_mISl-YQSJ||I#y^2a4>|`nQYMVyMCV|2VGy zi|nneP|N>u?n-D3V>`L4^Dz7{@_A+jnlf;!*fjOa5k_6Wjz)Tl0UN?t{3^>THwT5B{~ z)pD!0SZ~zeuhy(L%FTMM(rheNE0y{J=clBTf|A{c=m9Y_5eIV`h1l77(0aX!e7e|M zePmdOFX0l=KDoDZ0HXVH6Bd0<4F2ZeJbxhn=KRh1E%~eR=jHw?_g`}VI`@^_&jMh!^=*Njoe!AkTe@}kZg|Vi=XdYI zm+fG4_dVk8z~`~&>_a#Jf2Vhgcc^lZU3=Ddp46}M*#cLMw!_PP-fw!K+?;@(C#;_B z+t+uFTRjbcdEDx$LeFDX&z8o8o%a>kbt2BUG`3^MqgF@x!pHKg zsMgA`t?wK*J>?Cx4FL0A-BUVIU#?cxciv-qZr<7~0n8!NQ>vBVT}h7^bC#CAwl8UU zsLvyiTD7xtFo}q+;Ibm{iOQKnQq?<@n6_nN9AXxOj>-cKdc zn+Pw?|9y@z_?y1%Bk$@wRb(IEA&deka_jC#=%PGk5D(lcyYkNL}btk-paHhbQ2cF&p2`Wv2EtGJ|f*4Tq3lh0VxxGo&5Ht zL_*N|>FTWW$}*lnS1X`Y)xj%gL^rFj^b^f#m{jIS4G0yv@fZ+ZnVXc;y#_~CDb$QK zs`8#P>SdUb{Kxsfz^-7qUxQ=+E93xvwK~t}_v4U9v9(e!3*;-|8eg+$h zy0uiR^1gjL_V1Zv>^&bn)cGL1#p&K`+Fm~V)NC}jM=-m=nVhG;XH)0tBKypJnbF5& z^tibox(=Mm3J6j20ZjE3uLv$+RD}&qo{?ESnv~v2I-79EQM`Hyzf`NFMs&R!zb;)< zk--g!Ne>&Y|8f4mi0x&CUoZS{;XQ?g!X^1X%l}6H2lEH>JM*v3{kz;pbB!EhUjUH! z?d{zQ;Pl0Un0@4e;n0!g+42Vt&~1+H+MiKQLlbN_wa^MQ2J zPkP&}yEPj?-;E0u(_s$+ZBA2tFYVZ0>z-F&M^cd{Sa)?_1ro_O0c!cBvJr`>LjUTU zUqAWPfAq7z;?wf3?z(uI37Sc(S(e+{ePw|y2ek9rdTaOG0LI?C_rG=DKI#|V-hXZP z6$N&?hsUk+CFRKdmF_tOCVx7O+H2n0SwO$@4{$!<6#Y1@Y89?#RLix-;zGUITv#lZ zWx(vex?3nPIPYV{6?(UCkjk1>Aalg3~aUYp&$bY!UI$yEfwbfE8yn8!mk#-xA6AD8}rXi z?oPmGk9RMD>uo9P@M^Jw|H^ul5K=r$P3Wxg^0cb!b~QRRMM|KxJJQL*;>4%OaOJ}Me`W6Pvi$Gm zzmR_1U*?5&Xg)5=1*POeGNRz3ddypkO1p396dy_F=GfefRHsMNAayN639f- z(Au4<{Liy5vi$w?87r?oJ#$d~9F*_VfRMZ(oXs>S^>rIF5u9VmtQV zI$Oq1n9U>mGa%Q4vvAbA>8wS0nq(1zJqWA9Bwf-&YOU3EDDnO5)!nPWX}e_dO~h%I zA7Xdzh8wWgXIXBO5N2ohx}J$V{q4_u^0zb zU`rv&)8EEy<~d!;+M~3?Xa1e=)^~p7+x9d1E@g<7Q^rP1n^y|`uf)bS$V zwkZFd-K~D%h1?)9+&|xh*M-b%sx%fVjY=cR9faT0-2z19FIS#0($75pzQc!(FF)}3 zu_qpTX!(Id56{lcSMc1l)>{?d6R`1it6TEv;-zF+5U}@j=lx=6kK8=JSQqBs#!rAZ z?0qd3XtX(jR0I`H{#&FCsrl}v0((FvoH&y;FV4P`Gw8Ah&WYXEodeG5@{hWt5F3%0X6yBm5Cz($5i`S3B+g&+U3Q#}9k&%qu47v|ob+XNkB z+fH8JT`ICucSt9gT&XP9>y2i;UT)Ula1{>F8kPBGB{o+;X!KLHT&|SLwI>H4ltz&&+I&SGU3rww`jE><{-q~%C7$g|ryhfAz49lZcU@@|C#6IVqe6qU$ zQ?NRHZBvPcfS(+c+~I91^f8oZn}*eH5jhw{R#;*8j2LsG>ae_mTc$x(_XSnS6Z?(% z8T~uHJV17KYeCyvR*RdcF#peIf5YI~-z9}ST>Jm``LE_bl7AD_fq$Osz`&~BPA+uc z2ze=g2OIs(rz26PaVEgUq+EHKX&?p;%afii5Dqp%5{G>xQ-I*)!`K4b_4X1xAh5m* zPit*ZCG*6IrQ3IQZ>7<2VxhXVRyyIXcLLoNJTX{lb$5|)JW;RLH_PiB@+6r3bp!5h zl6|f2&Im3!$z|i=o`ri;cZWF;IDvdUxB^4SV+~iX=-yIbEo}|7RBqo6ypMUuz6-iH z7npp66YX?ice^=jikvR&ZX+FlyR&-}wWMCXo*=V{TD^MKewZ-1bD`qj7+>+}tTwrd zFXsQvEdLj|kLM2Nu4Vs~{XKS&`K|`Gy8EevPn@XCJo8Mog4eX{hSOWE?Cjn_Z3zxRN%O%$zXn?9ZgAFXPyv&**>~@Bo4h!DC@Fz&Z+~Xruf!pIha`Ls^H^VfpZfnJQ zVCcoND!HQhF{@QR&u}47Lm`f>nHOef_s+<~BpHBQbXtzg&YT;EK!bvkFA)C1#C=G_ z=S{8yy34qXN>1%X`+Zt_JwgR_&8x@@_7fGsAFPq!O9jM(K21oZ_8FJLgd!L^B3Fc^ z2ux*MAFT0xIBMhYqw0lyAIBZWqJ+HQB#2^BIPwa$lkl1C4XzJ$1Mh(Rf3XK8{aGa< z$dI92XrilrE*@u}I%=gx5vM4EQCgvXZ>90;q(~&nnl9=@LFU91rxfb)is-j#34RR(>V$c`TtP~X69mz*{473N@nOL9Px}2QP96KiKZHLuP^kunS9oX791bU&@JfKN$D_MvPLbf5-Jj9VLOV57I6xn zN=xkKLr%wV60V0e5uWTp`7Fi*3aZt!h;oHfTMlJ{4Uz0>l4NWGEo>ab=L{@Wqr9kD zsH-Sks2`a}Wd)8DoLj`Qkvkj@-?vSPzbOZwV%$vQV3dYOwkAS%kQfJ}MWf7TM~GxU z9?bvWgCr4&Bhql-9aez)Xs6__g{B;+E}?#ZCiN-XkhQ_tEPh5yV==HjRo+$29ZrCk z&J0Ehy4+?;Js~2&n2ItJaApk1gjJ-70t(scNZ_cwh0l~4JZyqNtc=Er$B!CMIwPff zfHuzmSih9 z4m)MVf=^>+AB<5xtN`VlRLJ^vrFIOLa#*?nRomITcHs5@9Q)r4|JK^}{l~j+DYBnZ z?;Gji;;tPa+)Xqxdhwfsr@b$e35Z3jJf|P=ritGEQa8#2xI3a*q390B!~2AeGWEe2 z#cYXaI8)BFf2d1G?HDelWecC&MmOQeI2nhpqw5_@U_K0M|Bqq*pTkbG{2%1E=Kg8! zdT37n_Q^ZC_ZHcYUQKQoft&tu6OIrDua^0Djc&ZBUe{m%;`mN=RgnPL=;a@{u=}Q_^%e>=4*-67UfaN~pqtgmO^PLBj8SclWJuD~Ni8ALR?&2(~2d_Tw6) z1Ty!~!R=xv7rXbs{V?=K%Dy;>yQ=9eYJ*B9Z`8KQShAnGsCzfu^{3w2*0+`7WuGO( zr0EqemFbiY{kY4^RT1Pjl0)=-QU#p|J155QZEI@lA#*rYg~z{nPpaf2Xc9@tsPat& zKNSox1|hEq3zD>q49E(F8khuGw^1K?jmn)BuRy?wNG`n%N2wT>!nImJZVrtf%84#! zPnvPFiVsd2UR1`nk&#z~ClP#*|DO`-fz^Z{PPADosu2dDkOMwZ4%Z7px=9*q?1n-k zaHgrMCPEGv`%~p=)Q9Uov51@=`=c#9&KaM9wPvc0}16fH_ zc_A#}DHOh}>9MLhR6~wHVQ@_61nj#7c@S4C4pIW#rP+(SXo-M;L=k|(H*D{N`Tx_1 zMNxcnPHiip=>w2D6BcSc;j;l62{)_q)V7u#bi%b-U05hrh;7YSl~V&^75K*qix2GX zjfFrcTSQ_kifq)vNt#seTPNs1Gq5&58=I zrJ%tY^PTh>=$-iuY{6g0=_#+uOk=2C>eM-~90NCNW)t&bLIx=L>~D4DSs4nx)x`?Y zU(){gDT-AMh zk^Mh6uMm;ZA8PZMvnQu#)d(%wW3C}eI>RF*ZvMndM3zg4t-WJC8IMfN>+_A&o!LmRv5E^IhPHgL|+=%%4Krk?6x!28$5L)Idu zcN{Yq?#|F!unF}>qRWVky+ zL^5|QP;oqfQ*9wG@08|09{<0JRayRp{Lb9}$#rv&!7l;+Df>nCBy@VWo!y5cuN@P2 zlfs2J@smrHMit-v9C*>e;Le5W|@THc2qIdJsg^5e7S4ZarYt=;binJ=)H6yz4poAGv5_(5C# z!eDbBs@%sx{_@^k-3Nfoc|kJisO;>%%QYYoCXR|0WoP$(mq_yOaVh&NSALgEB<2mi zvP{@-@crnK?mLU@`_+#ENXLXL%BX5wT%`(BBQ2y)CLEmFas|i#pTYbuvLmc;pm1gW zSD-P^znbO{vo`?IiTejrf{r6Me; z@Gr^4!^_hp5y=Q?;$ScAH-QNOC6NNs74Pcq9RqQROu9XCrpQ=t5SnMHeRmn2n7A=k zKJ}}NVs0Y>MSiIHaAIMo zFd`Wt&0g8}o-Ms&STYe=Nz($+j`9Pz)8Ck!aS}Cm)4>x{o-V|Njf{{cj-(=t zfNGQY9x_&!wUd%fA`Z%s2owh3D#&3El&4E7O-4u)2YWGJ?=`h|3`-^=D`{FF+Ma#@ zS3Sfwu%?Cm9&2E4B2X9r(G|W2Y7_jn(Pcjf|3Ak8lYljlrm1>dJ-yr%IRAEWu-k(t zvE)b?fWw8M!iZ#qG?APuV;sPWn;>2FP-&y0X<@&|8rYi%6b3+ah3|o~x~v_aEFJ() z7iX!N68>_)qhy#0$C1MxC{I@(>=DIs)Ud-0^8bgG7m%6yH7CNBXhNEfWY|F|5dcdA z4rjwAlC{A(1(#-+3P+H`9w@6z@8|}{w!J_JieX`|L>vT81PTLCz8)yur5i#x*H&Ya zV?^wGpW1uJK+(0`h&@Tu0?~f;187nj4zc~PWF!t?D5U`M|3{3TmP8{d1>@9hEP9RH zLu1iGhUc_K={RjLoe`=^#jwK-^8ZKE6e4aF{NS686Cw_2B8&#nHN_9$!XdUFmW;#! z45cu76yWUfgKt`JA_{3Dj0VvP4Fs@q^omn+b?U#{x``4e*>F7njPs zN_6W%F9aoi=9qM!v`JIi$zv{0mz0K#kYz(VqvH-A{imgUfK7)obDaNl8MMl znih!8I6r{vHpKSBl94!o>B(XgSZq?>II%gP0ua~#A7+J3xxdMMFMD_t*8u+Ex!og0 z_CLtat;(zZE8v7a7)zPTZlV?4m?E$afG=DS2sfkzOR>NE;^p1LMfOSeYWDC=1?;}` zbLV&8TV((7s_aq=_d?L4V5`r6X{q}j_?6P9R*$Vfs~>{@Uy!=XFpLXf4VefO2H-U0 zum{T1CApFj(!{~R^U$S$bcb@g43U*Idl5SzoW97JNS5oO!EvuAlW_#e#KX(#vUXCk zNyI?`5`n@1y~ytqITd>ZvK-|r_Z9#bi__+<$*hnd|9>3WOUVKP>evYznT(JoA&pHr z5(Yq^7$^%-@8|}{R;u(sNvltAB2CK8pJ>Npt}$WIJ`doS6&V;~mD!|={XE+AVHD&0sih*QV`4-nIEdYn)tO@z}R36bN% zA$Fg{1nMxN4D$brJ|#E@{NS4wp2$m@2%|x?QUd`DLpPsLDC$V!5((o*?BMK^G18QF z@|erh#c662<6a_A7=RO#!yYJ4*HGE_Ud?;QK!LTbi9)1lfoOaB0W>KMhuD5tG7<+c z*+{pq{~1$hrQ$?K4P%v`tZrO9@!|R{qE}?sf?qjWNU<&HwH4x24mxxALFjIA06WWkm;W1e@Ol#R-CCg75qp93IlK&a@Yf9by+)>f+-33aKN z|MiZ67SaJkd_bBOh>iz8fF`Bk26RF18ugB0DM<7pO$$Wp76ypG9C zx5L>k`zgte$WEF#==#tD;OXjvFrW}Zq?tyJ2)JbL5g$haz%VkrLTIyza7<-YloU39 z2#YcNv}pO}Y6WTms?Mk_Tp*9=o-Rp`jF2V{x`d&Vz>uaN+y=1s5QA@CE|iS|B=8YZ zsYrN%2qDr$PA+&Hz%ZRiSWA|gGaUc_Jz)k*ykT;WvNY_p6sAkGsI$@lSum)G)!{Qe z@(Ba=gTW=IM&unaO#C@bDd@|taa05w{4}Uiv#^4G-inkVL>b3XO9tWV-g8ct~VV^*eriK=cRqsftFAY4=6|o5g z=;iG@CZCZkr6M_7y^?9KycH=*-Y|}%#xXqro-WCRjF2V{dbwLL2w`;ukWv8=Lb|CN zLfDb>Gi*dl3GR_Y0}QhaNut#9qAN}S$p4@A2|=l(iXO=wz6h$-MhHC?Cle>-0q}Hj zP%Dno01+6{wB*w?;{beylM)$CH6F+kR}eglG%h3!Q%kp6!9`nR>8y0(=~3jBO*xle&a@URKV~(QYS+G z|BT_~nm?k01u#rU601m-oIf5@EyglOD0;(7g&iGMb8n7l;rd zO~pp?l_PNgaq$&VF%Hx#V>I7fAdh68E?XPiO9Mn;NE5M>{3gx?xCox+DWKLYg?}Wldm6(+?g8Fi3cyU~#lj8os3gA~2+h=&t^80C5Uw zX*~oyT|#(`1iNW~2n=ZsR}t4FNWUL;i8!eU+sqSb+5q+*^5a`79ThNq2cwY?qOoL9 zA<;e8|MB_X0(%Q9Jj?zud<|iH@$KD5i|kVi{XZuu)l{Nu%_1he0iT%tx#zccj}_U+ za${hp1X3aB$P)$N`%?T0Zdw%_Y1HYiZYNSr1dw7#iaml;nfpsN$)56+qD;&Nwo+0+ z_(~J*5?cGGH*CTI*lmOq%<(Sr0`sT4N8vT&!+WmS2q;>>PjN-oXXOU-KD<30do+S{ z8TA~D5zXny#C(e4u8Q0dcGu>m#`Tr7k%pkE~GbaGmOWr8dv@~W|#R>XF>h>e~r z6#kfp*lyi%&yJlt?%u6)pHv(PqP_$#B8c=s#1*!HbWoy>zr3U5St+nGX-fPeLxM^Z zjvq^btQ25WlWfFY+*G>8eG5pAovsv!_y7MqWAL|9wolyBeINWlz&Vp&@~@C10gQ^Q zOj=1r3)2LruZfmPIDGyG;{9KrWchFA{$cKR_Q^@tfS0y*pD41IAM)n5tZvTDYkc7$ zKZs*V6ER6iH6yyE8-htZuybGxrtG|!?;eMDcdZ+P=)kUh>b2d+i|n~x&$FnKC2eV2 zCFZmuu@7k`+tq9MI0`W`ps%m&Pq;Y}DP{OK$ZegT zON34Y;AE#pvVd0|EvWSf4r!uZ%FEC+Bc??I$4C~0GNnZWcl4$p04Vc_tQ;{b&)z-O-WCNN`A#qH`-@ z2W|w0G;u_7L)vmAn+KA^3oVE1|9tK|mS2F6wY|Zj@yXz#5p4xq7S3peXK(AizsO$j zzt9;0U|SWIs??kH#ag4@iqspSBCk7+o@$JLt1>vXl}Y6P7g_FWxi7Bm^q+3+uj@Wl zV0XC3vnNVRx3k>79lQ3F;A-x3Te=@8vKJ4ya3(69fF0$GygJH&we&ESTn+gTXOezl zq3_L<#oAW1i&}jN8@XKqs#=ndG*tR#JX}PhMl~X{Qb>KHVi6F3*OY3S%5KISnOE(Q zo>H&II}8F8?|lj9gO z&hTZTJKYPY;jChYsGm_|`htEiH6j1MoSMSwHAB<{MpIwhLY*1)3=%D6ZmL8hQ3!>2 z;uv5kM*>m146tuZ8kJm4#p)Y%=w07Irb*;Txes;X=*wm((I6V7WeWNK%jsa(tpBp3 z;dB9FL78ar6;L<3vx(m_-`IBWs#kB!GS7;LT2ESHCm>DYewK=*@1_T}5$i`e|KVbG(& z0bvo>`?amG`uUY#dPn!^BKu#hF|gx;WUKRDG8|#iY}C0!U7fGt)g46tKZO5Z$-=VN zh~)5DSWfRL2HzyQ7B`Q%(J7L3y0|9c!xpSfgi0o zeQKBDyhKdlT?SEuDQl{4l-n(N(JsjUuL^G<{NM#0sZa^Bwb~GqsxMOUndnA{IZ#Aj zuG+u{)uvR_R9+sIS9?GImrA@|fQ%~9;-m_R`o?&41J=_urJgmK3IVBJsN2e!6dnH> z)uQfDN~&+vbG17WbqsDMIIS~rlR5b&&j0;2%l`}Z*OQT8Qe2KydQVp z)+P87fm>-*>y73@b!)A3q6L{+YgWs(#^OS~*<4sGx3-olrOIL*K}z4)7Q-=_*13KPkraEF;1-7(_N| zSXBq}KbJp;!C$tmRSP`(WcLJ=!p8%NBjP?Qg{!B~*P7+lLcLXME%5wj_cHt&;`YLZ z?uU!)6L)42rPm50m|S^c;)j~e$2i$8WXqwIwAia!3q3pk^ZD;%`QL|+Y|AV#1s1sd zOb%X%|9a2das1Gc<=M)7dA>4Nf*)SRt>o*2cOo!&C&HJ$4(~)b^|~|gQtanK_jjz3 z#f>#HG)?})`Tt)>lfpl3(wT=39AB1Zt!~nj3>-sHC}IBiPfCg6(*Bvp-*@=X@#P2J zzx>$ahmIYcozrqC+6KBjU#pj^i`81A(W;hPwZ(d)27k3?y-{w~Yn5hW5nkh0UuXoh zp)x4yvEPO@pr#;7;it`XY2=SJh8mpy#$y`&mEB^$sgcqUrSN?l^~4Ft z|9=5;QEDOXy(Mah3hj?Ih#CxurpEbq2#EGinfz2VY82W(fMZjeWiTF8TB=35kQxnd zDpPMxUwg9)3|Au9Y$j(X( zp0&4%%T{naY_k>zT0aDDTlM z4<^Z*YS)|7SJ&)zqtQrH)HVE_x9z>&*Y2jZ)%<^wkOneTFyG@ zBaH_#-%Bf|G1i((2rI(USZIYLG*x9VrSq&x~$+DWdC&Zz* zL=91){Z>SUc0!_A@F5`DKV|Y$(Wp^qf8UuRjYDY-!~^pGUt0#JJ0UJ+36b48NbO~{ zL&i(fKUjFA;jor+CYxQLL(bjXGu9+1=1gbLaSJ4^!ohEcCQ3@X@|FAOr?a#mI zOrgkr^@_}CE5vEBL1G4l`@zFshyTB0`eR!(W+omnCO|3CGt@08`sWDPT=MzP{5jfK{nQ`6Pf(PdPBfitNU z4Ic8x+&vzeTBpr?AvtNkl{%rFG$}=iQusAz6w8Rz5+Mt%xneX)qx5k8@9ix2o9ykw zJpK3bBWGSwWIz5^-nMBu@vfG(`z7YMp!HRvy9H-l$Iq%Qon7JEv07d_#RuB4(~)8h}_p4J2VOW_YvUvzao1t z%bm@AGj|Xgquajp-Dl1#vftY6KUroMo|~5T?Vj6v_x`u;+ZSEcl6?d?gPbQ zX?9#nW(<~Cf7rS2%&Us*Pnu)U9oYS+8_ujNu)F=tctG8_W7nP%{5aO<51n}>Jm7b) zACze29`*(*xYnB>r=Qa_b|1wOaZ@oR6_(>@rm3)_GoQxpoqJyefr}h4K2g9uj3a~M zJ_LxA--G}EIc2U9{Im&1Y(twaB{CYD?=EI9C4z9Fks`IBqfR?DV;9h&MLTBbj%>Rm z5|vDYVq#{EDC{vU>2gg*27{i^Flo>=uvHq;CXdS@F$@Sp+KizD`Tt)iC~e1}QLq$k zml8qB65cgWqNmfKWC>5A%$I`JFyC>_s$pV=Gz@9D;6w2#;SkewnG;|u-yr}0D;eWW z7duh(C<(dmQVIZyZWlbj*aaL8T|>p?5D>+n1X?a70%-Yy^z){R*_#Yb{wJaj$}y^e z-ggP>A>D|9i5b%9q~U`1sQKUO@z|5_j$c@g)Za!5*8pbBZbAP4H{Ro-1Z?I4+7u&u zE_i^h!RrIXAoG?>Ap!uqF)%ShE*&4GK2&rG$4C(~Uhs6kPJRONro& z)EC+EceXMO=bFalZ^I`x<_wr>x!`t=C^*k#tcQG!)N~DUA1DTyw_FMl0N5okc)2fn zI+zSchg@0~wJhAkwG^M3bf0V96&!9#D_1Es0^cJo^M+5X3_Aw!fP{+Mbio634Qd}K2H9%4l*sT%eUTl4 z^m_=BopJQv`W73@B&=oA1&`z%v228bF@PP6zpdyjtI}LISOw5pvxeFf9$sqTEVvwztONk6ma|}TK z|0#buHvZ5(RzISuY`WlU!WY?e-|uwa>&@OY(Xhnndc;Laea@iUy??`XiR5xf zL?H}m)1^d4N9u3GCsqanrdlp|KzSEXk??-I-~qY@yAKqD%v(_kxc>KDFN?wvn3$mm zGcU*B%xREa4vCgA$X3gxM253)%NFY-93o9ObP|IwJxUakhhmDwI;QJTH+=p-&%U1( zJ_R4svVHu~GZz%u4=($kN(Vnh&6lF4Bzji^xWx64ui=8n#fb~8X~qm`7}9XTr9?-awhKN+dx11AecEwIKKp!YBU)AFhQzP)*o7q-{$)fhKO%NST zQU8fKvFTFK05L-vhBRF8(M68SOA8V+q+v+I1&^27h1bMlhBORmxZokqbp7vfSO|^q z!luhl1H=qz7}9XT6Gi9)g)pQ|ml7GZvx5v^)5S~_J3>M2x|Gz2_uBA z(L=sQdeJp@A1E5vZWu~c_r(jVBczRrsozav+eq&jN~_jbpsUd`$zD;&botNM|G6y; z{<1C60?+S1b5W6f?3%T+@YU(&YeYjX#VNu*P<))N%*gT|O%%0k5BZ^e9ot^!Z<4f5Hl%FT5VUR{QpSSDv}N z$iBEOShG&>-w!R%m&tFKs-NMkE;d@`r#L-;;9^g2YIF@)sV%^y(yUY$7HW&tN_nwS zURRGTfWr@(K*Tvn+p*6NLNz0s=HD$Q!O-l(-|l}58w zuC{8`R;vm|DA($hh1PtnUal@yYYhM`w`z+334gUFU^nZ4+W_e+^@W8wRUw6xt!fp3 zs^wZ^aiQL9E-aQ?^YB$&EW=dVtX3M0I!vt#^Q9#6wMu1Sq1qJW1?}p5HKqBgi(nU5 z6i$t?%X24-XD%zUQx}9|rK-0ZbgR1Qgly}E*zYm5HgWhW{6^zD&b+3`PPTd#!$=h3 zjKo3FJg@n}dgbJ(i!)nB2`wNpDYMg&<=HHrVv5W(WDC{?Qio+J1ToKk%Oyb;tW}Vo&HNooJ4m-ji_US;XO1iU|f@#2s1wPe=aa@qdABVTGI655ZT$_Tt57t}L=o z&W+)y5)MpW`TXn8yuQdjdgB<_ImgnTGdY1nt1OepewlJQa_6PRGp~cE&7N4P;Rz}B z3QYJc_T|!tAMS`VvysyZS?Y`1Nu;4haD*Ja^uJ<`_WHgHBF)j7Z@Hc@NB25>`K!is zZ^>ke_B5|MM;$uqDz3Mr^>zT~%n`|_h9Gu_C_vLXip^ZcF;U-0vmE%6wO3t8+Fe|N$BvLBi#7f zZ?C5TmfO|t)yldj9|M5>$Qi?>w;6Jj;V{w=$lO0Wgay(l-Jk9ZcVDMe@n|7**OGf} z2TzJQ_bg3jU7t;)ad+6KIkwc5Z_;IRdQxYAiPTp`wS}iDZLI5mc>ez!_8wMvUH+%? zmE1d^Iil_4;WO71*|Xs{TPX`x>*S)eHleSxJYTEAqnL6P%$E>eWDgwPTG@b$Yvi^_ zd2TBP7`ZJvYi@JF)Uxc!yU)ykzMB)y4%>?iUe)A>mdCBbhGi-sK~R~pXJkvQC(m3B zPosoi{inQWxR{dwrZ1(~7Uvh=cIFL5_NhvOK?7^Uq(vmyhzrHhVO4zLkM2KnRgrxq z{H_-Q@5Dsn)gy~t@94^xiF`Dmr^thr>oD2Vvgh_0e71MPIr&^tL=93PhGj^PeG<-# z!XtW9A&1E?Pc+!&MVoN~6H=P{A(ebn5D+6=bB}7ho$_3WHNW%c|8s9+@Rw~vv%vE= zoVgZmT(~PdRap;%&zq}_;eIiRCw!8J!22g^h(LiOCC>CiFX>N^NeqXOL;VRvLujG? z1ad=^(MT|1>*3-l2haKJDZz6-{I0(oSJUc;HNZs^a%RX-##IKw4!BUi!Hj8zkVE}m zQU-V!PBzqRJ-w`>ogw5>fMmx=)%hRr1lL$qSnr9H8CfCAA`t3#2-qF*Xra+izfC)^7eWs8d&wAJ+bagxK-ifa>Nl7% zEibY>f(ADF@XZSsL)RWM*ppWdBs1dJmb8VIdj{B+-Snp*qAB-><%nXl?2~9bT4*%X zuT|6y$p1_9j%kDlg!&C8X&GSKD+a_s48>T2@KA^vBDUR0XMb1{J%k+U*IfOL z5L&3;PbJbDLJsvu(8aC+9)`^&3qy1a6$?*!c~!GJiA??12SdcR7O*lyDT34h+jLBS z3L;v+{;(u^2szZRx%wL+v{1jFN~AZ09O{pti(Lae44X?9hUgd~-K&<}N#q%Rl!u7h zA_VqA$f15DW1Z&0ge$Cb2h(`;Jl73kG zzgj&1`vq2bQ+|nkVY(`SlI92VXKsL>n_L%H2~JeDRx9;peX-W4H@B*HpO&jt-mb`Z zvBnG`3W2RO;I+5#O4_Zp(h2vLht}3orBqq014td-fLn$8wSDO2dU|v}x7uRl=D0C( z#`pc==CKMy&gG}hKeM68p1W#ruSA&$Q#29`PaV`dhWiF$%cad)6W*Fvhu0lDZz}e~ zwH8iR&s-0$3qCX|dn5%SwMTlX!IQ5|AEcgO7)Fdkq}9=^aVbZG#I1*EvR@U4sY>1P z6p@%z9-i~jL)B_la#K|7P_ZA2pUCTeTkxx2mtWx~M2vh{qKu8k&eJ*8Yv76_qEIbfUAXWWG?jw_CjLv&dB zz5dw`o!JP#=lS7S%U0`T6Uv~Buq7G64~&HB)Y4j@&?Nz{?XZ$gI<4){+1z^8~s zza?z^WNRW(5jsPVs)W=a2(BC;R=1X#CHM5$qS6@{K-2uplQpmz`NP(W+Tq0LH&2BO zarwA)grrxF`7%#Kq^PV@-#mEYVg~`nQOmVt$k47T*b^2J^8YG4EXdNhZxjAs_TB_Q zj-xsluIV1*2yBG0EngVMD@)qj(=)TXGm<4+$J!E>SGEox7$dKxwY6A>Ev;+|%Ld7} z&0&rJAp{(9eIXfWi<5kTKYtFA{a;meRln-4>gk?) zXS=oPuH)6KSMRD<)yFI<_Vt*gIZ=BFvzRQ*cU^AO5l2erWg7DHpI}VpX7v{- z7m=kbB2v+hV#c)HBntE559)zpvJYnXAO}le{};V3OOHWzhSQic?yxi~$!u8f)_Eyf zOQFVGh|PO;?wp+3y?6Jv8z*<|-gx6pqKS&NUIdu3dU3D;MI}1RdZA64*L7r$={wg- zgi@Huf$L!o_!dPEBXdkIhgkX-3s~qHR=Fq^)*zj9{?{68gN)KDY{Lwx7XfB!y*Q|~ zHOQ34x^A#@twdrBsTn+M1`Z~MsD3Ywb#$W(Y0N7O!q!?YPfeT#47saD=VrWb9Kma& z?(cuvWGAuDCSQb06OL!DDG$MCn(WXmW!QnwW}T62b_BlrP7kITaqR_EZ(Mo>g041$Y!}X?EjNRA&z1+$J? z0P}e*HF%+x97mJJRIhDFA|el?Ipjy4U9s_o(ukH1k&(xlufhzqUhd<;)r+H35|p&J zo!c;C*?GhT85cBbRd3Upb9`5lTreCiha)M|AJ|e^1?A9sz6LR>RssThS{`SFhbZIk0Wl)Sm6z z*$-CvblH>*VlY9n@*sH44(n)QAR&m!0LY7j;7z2}k9;JNMVK)B?24eM(VO@o`46_y zZvZ~_*v|r0^mSk+dgZ;~vtZIclDY@Z7u)uK*gvrU(f*$OUHhB%*X^&_zia=d{dxP0 z{b~CX_RrcMvfpRF(|*Q2ZJ)FswC}gyZ11<x0&NthZZFS#Pu6V$E5HtpnEG)*G!`tedRYTU)FRR?*5?!`5mmV_j-p zV7=1%5z9*bF!isge@^{<>aSAYPJJWwhpDfmzLfg)R3-J9)Gwv}N9tp#52xOrdLi{( z>WS22sfSZXQwLM`*w@-??SegO_uGB;YwQ*FtL&HCY3skOf3yC@`UmT8tiP~dOx=}w zLuz+wDz!DWDRp&fJe5rirmjrAHg$38)v0rM>~nFcavV5OtlSUhiOOL(k5}%4bG8EC zMZb8U0*t!2ud*M`S5)@G`LfEJ;CylAjc~r8atEBxsk{Ns%PP0SIbFFG&UR%FthD}D zHYG1q64|vlSc8&r~cpKV3<|`KbyFR@jTn*=MR4C@#Qlh zqZPk>24uA2OJ_hvE53LJq_d)Y<^-J2oOuY&zj}shqgB}r>Cc>b0M4H}1JYUXu``F@ z{NXdRaQ@Jl191MaGoX_zK5*s@aQ@LVpnEIcdFEC)zvB#ydc~7xK#nV(I0JHA@%R~# z+KSU>U|cIsoyh_HtBaFG|1pRQWc3IxrRmJclNniN0&6BN*_poQiHULCn;uBwz@Q!v z>Kmj)s!RAd=DEWA7MT>~$NAhE@_c$#@Y%^ya}$U^dIrYjCt$%mRG1#@EKuU> z&X+~t3StQs);k8`h%liI8Akkt9B+{<=de()IE>=eN)GIQ*wqc6J;&YT(Dz%9Pjcyz z1FVlQ%#(&x)Fp>qx^0k{wm{m)KwlPt>qi9un1>1wYHUjSy7OgGD+RFx3+o*NaYUHV zr6BBpNg#fz$r`)@`yY`Y0jzq_1i;)L_0XO30EiJLk`YLECVjH;Wf9GK<^upW4I>ao zgh6}OiWb)(TWvk`xtF3*){Bc*J$##n`>$TLe(HS!9$N3K0${}=Xz+r2P;GAFK_98( zo{^vRB>7CVn+L;R{}aCnzjkorcKZBpnoN__Z>FA4?Sw?Lk5h-rPMSQvxAtSa?8!;* zDaMiFL;=1FUL1#SnijI9iLr@^tTPT@p)F>IM_>r@XD{JFN3WFwbz`ORT(*>llo`ff zsbcWgf*uIgIeDj8oN!8G=!ZAqiOT;x1;4a>8~vr_@p9HC$D$2ac@%TJd{xwjnSBSQ z58pd;tbc&^_?1_cN6#XsKDe@Wr}Zwk_3e^Hxb(dkX1GFsO0zZTSKmV*gdt z{%tZx?2**}flFJC)5pq%GNJge|!ChRBWos%I?UXA9j?y{fqWim943VF$ zr*@QcFqcK}v#dGpzbS)=g2WvJ5a6ety$Rqir}l4=KOm`V;nWMqGuM~L;qwFMH&M%T zgY@eO?veL|0RGc?^6K(fnmqSt8@gjURr3@@=`zP2I5;~uv-iQ7qsL~C9PS?o_)ZT? zr#u@9xlH`8$qNSH4Fx1;a6yZKA?|1+Sao#BjoYcoFD*VULd8NPF9uCTw39+9>>^Mp%K@!q(13#TPQ=QkuLt zSx0v!UvHW?p}XsrUAv9yn1Mf2oj@TVVThIEqYP&Ic$;> zE{{ZC6w)wK3~$o%NF6JIrm2T`YG=ZN%OlZ-2Wf0<0>b6(qaXK*Nyg>zsOcdi4i`FR zk(PCIy6bm_D6M8Z}!aOrexV3gDX%uZD(| z*yQ3ypdMn3#qT9>UF{x#FM$T=hEr_>f!3~)Xf828b!531F_z|!T|>54guBL^F_n8Q zaVj1(w2a*V_ok#xm`vqLW0{Eu4b9>;FhS#TEO=(uk3F_+YS-k>-9$dh+5}6k4~68D zo4|CNv<8odHZ!&HZ`4G9Q*O1XTx~6K@t~nq>;~p07!^_+T--iA6AaN_ zqmYD2)gp<{I#aiL^sLm>1eYUT^I#(AblCmB)PE89OOB<+f#)A8uS=5;M0{Bxrdne~ ztYI=SKtcCS(6}6HJ~bCySA!U4UBL$3F+If`OZc#1@2|w4|9vA#{VxLFux{>g`o8jd zc;NhwI(CC=%P4$kT!_j!UIP;}F2_pd#&o<#i0S0(2wnp(1=Sva@XTRNwGCwa==Sx5 zQ@%P)p1HTv?8f7)Uyc|H<`!iWuB+Wc>;@+ErgAPh|2ZCXONhjL3t4oylp}(r_WB2f zSsw&y1Vg`5Cq9qF(C$Mk1r7sH-L!f5a=9A!?gR<`tA|3vAORc+NC3N6eVe5-R5X5r zJNEY9e(-}(rujIlW`BSVwMOO;DM2F;P?3NHuzOY7AUeDxpZ}+bwLsw40UAAiYgzdk zcoX%x3**m0bq-t^q3Q0p0jO?W_i@>mHT0%Jg#v|E3Ooj&CJf4enRgso*(%z+PMhdQ zA^hF&?D6u3GpmLlYESH&7Evrg9w)Ls=vgp+KRP zqE`b@6ZmDo%sURPY!z)@r%iMSg4n26kBG%<2Vno#2FAPS2NpVj&`LiqA_03qi8dkz zdTa@?4+O7CMnVw^6j~{IGyp9D*9rE&QEQ z|IGq4>>8=BFa#zOQ`>}g6IvD05)u;eKa85R2I0 z1~V-tjderYc~qa@a=e*|F3t)h6wipciR%d(67B32BpG=0)D+O)h8VT3~YJ$5(9$pYZufpHpGMe`K)-()M zg8gsxV+g@gk0=6t^8V^UrK8kWX6Q|Y3Iz(S6nG3kO&F8`Gw(RGvQ@NsowiP!1?|SG zM}$VLMXOMt(8?MZnjlxv1HLvw635dB20ADj|NA{jB%IzbLcv2TJsfonrghrr=ZGLQ zbTpxrH83Eunw$j(4psZ-j6BpGcf}S2%OmTg6n(Q1H;opm$Vkq3dl}(67BVGIEZv z5e#+nPCFJ^7$6De|JPHSpQ8#qVSYi~Yd98+MkM-R!fV$|>rD|FKQDC-cAjY>=Ww>h?hw%>OnyM##UD&(cd9j%&-;rOBzYB05Ro z!Pu3aM&PNXYs-^yP-Nzg%uOHMyYImC;d^I}^$$=K?|7uVB~5<(k%(k?_8sD@RWYl% zNC-TjMm$nob7btU-QjudLKx!#b^o{!t={^Q4;EFm&B@2^6E*PY*Qx}}|5G&nx5;{9 zk6UktOT6Q!C(7H>&tfQlB5)tkgq*({K;fPyGf$E8r*F7sOq!~!IHRwYwBFzBqGd;3%bSns3THdLfi!|<*7k)OB@#l$*zxO zu0RiAWZCb}z)l8x{@>n4;4e864kR3?mjkEr<=4aJWzBHm1<=sGc_tFDX4*JnEOeZcE{0>S4x9BcT#~Ya#q4tUgiP>T*r%2e={&x4y1kI(m zMMo-U^FJvN`WN+h*R|yv(&VF2@8J6eY8nbI_uD6~!))=PmRS=#F7E~%k_5X6OdlR6 zF7F1qyO*ALw%BPegJta31(C#)SYA^+zoaMZW4TgZpXH^MFCy>V_K2PhN;9yKGyi9#t` zD30fx@j|vVF$TAvoblpBshAxOAH!H_JeMuy0ZP7A5gezv(#bo;;)GKgLzBER;KyHG z-kv5;4Kz65P7T%T*P)E$jPMHE%XhC|L<~~~pU7%Th1oy+_^w35($KvI{i~Gwr zr^y#@Y|y}jPr+AD-*UtGLN-^-<;TZM)Lj${<1mff`N4b2H>Js^Vm-QpJ20ocuECWe z-$Kiw=Qo^QSKa}yDnxyb)7(*@Cah=vgtOE5vYhrBsiSelEk|sGHw{ed|BLQu^I!_a zVgF$KypO~YJh;egM2%#psJC_rw3~Q~{3@=ln zn38G*vOm<@5>#dy?l$a(5DOzY5`F{2l>ln&3@1|U4jn{7i6K$Ly&!~4868sqrP3c4 zqRMDw=!0BE!QBO3%DB^MF2n1@1A;(h_l|8L3{#`F1!!gzL~kas4=i#f+B zjE$qUma?gkncI{m}rfF7>N#_aM6NQt;({57( z``??`I`dWSX8jUmdoou@L-(dfH`SS0672u3juMb`E~DloIzo39lDIH(T-Zp=&es0{ zU&ISKL8Wy>Q~xx#eB(`0eXj@Ccd|Tjt>GeKQA7^g9DA1)-udfbZqd;nCY0>?zy# zpI6?QCZAZ-0)i4tnMuNQ{2b(>+p&Pyf129=W#k27|C#+c`=ot~Jz)Kp_50Sxt>>&a zTU)Hxrv7*8y{U&%_oViuHm97_>r&^E|0I7${*?R{`4wo^^dnQg-zL{{uhO6C{{j1O z=Yf6v!<`Gxz`($X<>ezbS;axttQlRi=AV|A52KPnR&q#|tlV__$jX`J<%6=MZ>Dd3 zU*GcbeO}3AAA@GQ?r-RZ9B$URl1!CM!9GeH7%Cf{6hY0h1$g)t zZq?@Lll}Q@e!>|m77I>x3_d6TSVk$9P35}*%d(nSGAB=F#!EgdV=k7Jj-PmC3EMTv5te1}bL4~G`r50>9xlRNyd z?DsRN5e#RCCp3r!yfe*N+PkUre zZr-zV=j7Dxy}P&FIC(MyKx^RtjT?7w-rBdWuWwLkHKgQNhH6%@6qS7QTl_#pIJsjd z&IQunkge|u)X@UyUR%CrYTJ$}w`TK>?b|o*o(#gR?#t|&+&;N^cgD#Fk8yO&xYdph zFwZc%jG)}3jEi){;r?JT>txqwozg@pSIE-dM(M-({BSE-i3>r2Aj_p+-^G+g3JFU*l2l~_st{DrSl61a zjZ`Zm=pR>clZdjTU??C)|M>i^Vvj^xi&p<7r<^RcRH{cCI&P`{F{^gnGETMJ1H~Pe z$a%CjcZ#9OQ=MtBlvV_g1unI%1)*-AU;gC>+0uMCBD2e~YHh}i-O%nfuRcj2J76ld_HTR7D zn7TgxKa|A(QSJrQl539yKk@XtNy~5M44VcbRH;!NZ>s%$iA)?dkNC84HCp>CmE%|LOg|RBD01Uvexx4#4fkW6AAC!+jZA z9O2%Kwsl*dG7Btt^TE4q8W>pn-v|Hi*Hjscf(vpZsIMZ}GFks~)rp{EV*TEd+xW@) ze@U znZ5gGkIw9a)CsPOOZQc1Im2R3=~&yOX%owoE@Wl@=*jK~at((L8e6+HUY&W&ZXs6W z0=yHhQ`q@pn!|?h!M~qIzZSzveOY4}{w&O{-5YPb$;FwOfP@c;FIxxBEPPpK%|v#1 z&{>o59Zvrh@H4#dDY`*;Q+jI8_U#+i!1!6v4C25zCOFq0M*^s>dqu*Ir%J2WY#k*zA zRt7ATFz*7z3zy?T2ZQTm(a`BH`Gqd?nzSMf**~P)RmuDR$_5g(sb=kW(wJXzzfogd zOe|JEP2I_*>;JRh3*e~*`2OF&ljk5Qj%Qw8 zeoLCXa7h~$`LGIk+cUZH3FxjJdkWCqTc3SJ`QbEq&t+{Gowp#tDYQ6oqjDhYu@^2X zKa?gf=G#CPbaxV-|9LQZ{s)W2myYmmhOY(BE|TYe9tI_NR679r{cN##)~*`$+iLX3 zIr`zF>;rCd4|nFx#}Cdq+(`*JZeEh46 z-N@F=!6VcA_s%>#H*@&d?2*Il+x(O>K~^JXkg)lNb)QEy4Imt>KGt9upr?u&`1gA z78X`53?d2|PDc4H5A(dPvZ@ap7C-#uZoY<`zro#I4H36->Y{@Q3?*Q`Q9Mon3oi)g zSLT7^v-|GbyYIlvzWWRaykf5Z33DVznyy9?GfU|B?Vpe6;}ub~1Cff7f&OHHQEdXc zDVyjL)OqO2mGGh|@xQ+p;{Z5dO+O*L%w2xOEYH2awu%;pvDlld7%N-wdGIy`s{ZMa zPSR_l`7qE5*@J2u27r0VgZ$PB8QYeuKhd1BNHX3SSrEa_;|hm zKf9JMjuppSxGUhUsO#OXaR=SwZh<~n#t%N;8pDlmga{!@3XS4d*DI-oBG*o@;-9I_ zD@QaIloT}cE2=OX zbUZr2{!b?MPi>%vv8X{#m)ieobsRN@1S=7r@k2Ju{>ctP|C(?-JyL!&P2SnbpRenM zX$NLNp9Gsa%QbO7s&lO%$+PFR;VB`hPfEfK&tv`|JiCe1MbW)^ZywFCD5>w@PDQSuq|?9uFyhf|eVQFUxBo39wWUp}+k@RaSuDRbO`bcRSYs@u^vBv=WsPEC zUe{wxQRZa7J$rd$YYtM&*VJSGLnJlSgNE7MAw79>g`~;zYZ5b0%$%8`(NIy4?U}Vd zWo#WZ^On#5$^L(HT}9`yJ#l3vmF)jfQ|dZrwXooK1uB&_2tN1RvuHSvR$v01TO_jR z3J%2JZg~8k%>NNA7Uq8|ng6L))zHxJE%jD}`3;-Y;tTU*$w0UMhjjvolH0#SQceU5 zNI(dA@`j2HUZ9)a8;tz?c2l?Bz85^Y&oQ7m&`ToIK}oNkrk2Y3AKw3ao{b!W2bBYA zt~HFJeHa20H^K?rz);EZ<&3yET&=B>8iSnNSpVud(EyWoTzBrd^@g@8 zxroOoslqfg0m1auPREKBPZw&cBkOW?>jqV$^FY0-hBOK#RS|f~MMHY1Yr~9_*fW(X z9QClfz4ol!d{#Aw=OQQ;A8XJXwEAUYKe;d;s4ve#u0K%X7OaCeYXyQWle;0_Q;wFt zOiW)ShNI2z5!3a*W$hx?Z@?)z5)L%ZfzMr6IV(;6sT~g|LG=304-Hn*Y4Vxdd;GSn z<}GyYn`%U~A#cP1_nw3Q?^1l6%%G4U{`-HCU*KrLu-FKIdN~qJBEkd)tq=6a7qeHycyqrCeGO)7)Xk|b-zn&YjVZAIcdJ&7%pE0F zn08ve+OsZa^bH(X@u|A@yeuS8VgT5|tuv!hYEYXbhLW6dxgzs{gi)Yf=+_o`3tN|WkH)&4y$82E# z@7=h2GRSsrII2-5aa)j2wW5m<&s5)vEl5H;!sK|XH64v=S-3sdT$8)Vl9)~9DqDv8 zi*P=mjbQ)p69Da=D@DKBYl8|B7^vt(__akIw25aVME5gFapID9=TWoa+$n5g_feg-8~n8y5SduQIBj->f5!r*tj zJ9F#3@jIs7amV(q6X!6!fli1j;GcWrg2CVrkt=C0; zX`nGKXtj1?wzhNTjX3LKR+!V_Ou|F-Mc-imKc+>CtQsX%(8eNMzy)M?|1FZ__J}HV zH5aaVH8=7@bSt?%Qt!jDLP8N@Hn9H>vEPNEZIZ`YfC(WQ>AurKT_~H#7Vl33)fi+F zvr%(s>!ZQELnIfJn;6=Bi^R8MB5mJ4U@vbR zx}J@)G}$fD`ql5AdXfJYwZ~y4CGL=X|HZd`s@6l&BY9_{RLqVS^QBTQJ5h9;Y_2$7 zD(1$DxxAArj1`*lo_R>bt&lD<+}L3Nzrr5HX{qfi5jT7Pk4zHs8G5So`0eS+*=Lbc z@0x7=J6I5}eE74&m6xT-Kit{+-h_C3S7xw$@=qS?mArAeBJ+VnOt%0#+I|lku~=UI46bnri(NCBsuiHT4YCmnseY8Ka0e zV8hM>v$YGi6mg6M_Wu#d9z84drLvJO(K-e%rcEKtnFe)A>^#5~u&T)97b|3cf$&lM zgiOOrN7;o-0-`ISOftui=tiD_{eP5`+l|yEl*Qa)l$w`FQ?PsY@u^uDpGa>_hfWd5f*Vf(5r?aT~iLv1A?I2a?_BKkYa1HO&8wbriW#BO$eW^;5FK6t5!>LP5Ut7r5 z7`n>VE`JI|j!w@;eW`4uOSF!;z4Zi&nEyEsYv_~+df^K2s)BZM4@9Q`tgPMR5e$mJ z9ZFxzrgJuU-KmQi5+E(e9l_pn&!xZDdE2>j?zSN;r82Y&y@PF+Ti z4hBn>w?!F}Z(d7&2NOnJM`Fz_0&C(kYvz3~eB}LmXC9uLIecvP$l-ox*cs3VFvvfl zq{^RmYbRoP=XExGzmhI@!x^ly67d)%RTz;&04OPH`LzMjFfOau)LaykXl#N}`(wEp zBNZ|EqMkI|Vb`JNl3@+Vo#Tii+|C;x^=3lk+_UMunB)sfARR(U6{blHr1q~O7CG0v zx^7wE&S4Q&Lt-SlYpeOH`E*+y=3-QGJ|y%0z>qvRWR2mrR7G{{kNug1b~3LHmieRq zY(w!1k`_v;e5~L8smaTOe*Y&$UPtJk=6L$f$}7_3UDx!?Hn7UX5H;k0W(#BWo)co( z8qnrj_DISosnS}%z+F5>XM$`Cg+sD;V>=GfQ-c<)_?8^Kny7oQRC+2ZH>b#Z-+}3) z{V`?GSU>^m|4(Y^@@@w;X9cK#4Hbj)Rw!23fD1UTdb_paVZ)-N@6y& zX`3IZy0APjfKIcA>wp>)`6qbC88&Q4sBA?1MM)K=ah6<H^@#zmp$1+_k{@@BDS6xf8n%uEneSwrJ2R)=Mg8hGnGOi5^Db}&+ z)KH8QvV1|_2qjf2Bs1E?h~8dNQr?EJTC!d>Raq<&$!gN?%>-w>tC7v90wukMG{v)fqQeL#L7{S<5wE7=d>H*alnVtRVJX3vdBlwABTT9wk*qCCi37UxZWHi1>?=Dh&OFKli9%7s;|A-m-yi_zTvuE0O_9Dj?qO zL9%S1zBX_RHd!{P`r_ugMxV6QiNaPzAZYX`DSGAC=1wWz2TwL{%^aGgZ&5+fz=Gpd zEV%ZccvZtK8BabnSY!^EkhD?KLrhc66+FhR-*VBH;&y>_tL#Eu?Qn))wcgvC-zU}-BJZt70S&S z6%JLPq>7^*N{L_8?IQNHd-IPnzJ?q+;EWV?K;)q$1!4A|`UZi&F<`DSTXrpc)Bh^GniIF9QUxSRgpRIzSoPr9!DBPHzKxk1C^$W=u#3CFh zsYh4W)4GPhma4qcOXh*&v-|GbyYIlvzWbC4T}H=3`b6NQ8T7G7XrlM7vwIpL$J<5O@dnL2(qKPFWBH06XypgyXBgB;ms80gor z+~y|ijoyy^23M1&%L5@qNp%#$>=irpX)eIXMn;`uJi>}Co1i=R(UY<@O3?W~O-4!T zgQ;EQpCA!>oLXPGC{0ewH&?H8=HMByk<69O)aETT$bsaaLfJuI85G@si~Mc;^)8wK z*wo|}RK-?>RF|O4fvU|eEk2qyZg$6%+I;nNWks5tx?aqRCi(*%`%oex#L&GyHdQW! zK9-3-fZ5-s!vEH{zApI=f|Y5MK*eu=W95Q0`LXo~3j*{d12;qey5YmugKMp9`i%T- z`TD;rpEwAY{{aus%&86b|Gz-(-%edm>|eERf=hDL$AQylRW41FCzcCy^&HDf(skU> zArI*cQ);mPr4Ez2>42M?n%s}7++DY|aUAUF>B=Q(@}$PYN=8U8jY$$ShlZqp%Qp;Y zDwM%Fl?7V^9r@}JAB2nNGgxp6GSEXAyk&A%prgi_ytQ&M%rF-Qm2Jx3nO4d|@N|e& z-R1cFt$k|a$w=H6s%=H$dr$U|LK{^hI>HL2-d6-zoQeP+EAiqRDOrC>m%a7%iD{QjL^%~A=E&iLC$^4EEi63n z?!%SK)8wb71uUMBh4+H1^U@s3)lAA+GsL>JE;roAiGG_x4McUn_3U|-*T8cxYr1aq zK-_OWpQ>DzChtF6N1Sl(p;NhkS_;f4VNcTD?=*9QpW zH>jag{zZ-Tm-?aeg^!&2U3rQmXuYcps((8V08$%AGvAW;#a>2eyS28aB5 zH>-%^A-CfBAAG=<*g%+JH+f;0IEz|K=eBbwaTegogb63}$yz%9>y*?m18;4+!eZBz z$V;~umzZ>7(s4p~|NQ@D-@Tr|-6UUqgZF~^;Qo>NVMg8O`uV*hU(YCOyk{z4Tq;F2 zc&&k<#v=?7nB;Z2-b;#Kh0AaqN79*j1yAef-jnD69f^! z>a$kA<+(8eo()``7Rc1ZCh_PRtJCv}15qcu#S*4f&F?*CiXSLpk{UukVm3HF2o zt>wV8rOHaU>+z6#V}Tj#U0RdHlcE+tEvy;B)ID+Y2gCaMIGL~+_q*?Uw9=O*9~F<- zwQ>;9-EUKgsDp)vH1X4Ey&t>!hc6#CrWNg2taK`*&_1Uc;07*W&#d0tj3azGf%{}> zY_Pp1lBSO>z&)=Z&=;NmQ>h^Wf5{QffhTXST$v`%i<|0yO_RHCot&KFg`k8Rr`Tr#`}zps-wDXf9hv)+gZSe? zeSOCsSXjug_c@$lXW{1-26pV)zU{_sy9Me#uTOZH+Ix|@FW7DuZQh^B<_7z7!#QU- z|K{TdXP+rm2GZn(2)71gkC7AJ1j(AfuKL%WeQl*5?nG?t?l=`F{VG-W$RpJNdV}}8 zn*>WLffb963DwX4LZ#1>W)ccAUUWjKu@GXV<4s~n!g7={;i<1Isy87}A(IG0C7x>y zgOPOtx5p+~r6xQ;T&`alV+d1PkIxTX$5>Ppbs(5TMyw)}xoE^o@UVo3$`e5#bz`8U zcENWjNONM}(9SwcTNrO^*458^e*bR+No|PdGZJXZfp?5ohSKCi4>Tvv^Q0Ii@OFBF zE_92X@oH_Jvcx7Z*8{y?G%g#6|Nns5KY5itE zl%!ZxB7Bt;fF5<>;!S<$xcqHq&k8B(xMh{c{9~{mx5Sw*xe}gOoC**2@9w5{oziRA zy*PQy2hw%?O`J*xJ$kn&Hw^`XwA7^6(bBKG}K$@ls+)P||#) z^s{%gtB=8dX?XAzyqTjX_R_E5L9y&~7Q;Xq9VNQ{e+BtAu|8-$WzAW4TQ^x7tYPai zYguX~6fg2)Q)L2uiaRTh{CIAxkSmPm$JQ6bkzZA~TBHjFuYBy(-Ieh)d3>9@FCmdE zl0>eM%Z_Cyiuqi=I9@D_Pvo+$RNVm#ObsracxHKJ41H{ICOg*m%1Xf|E5&Zi%m{ps zF^@rp#-JpJN^+%1C~;89Xo-HsF^ft@MoUm~6)Ne2C-9b6MsdkVU*CszS4Pt0S4Twm zRA<#4FR9+NN}2%8gdRxAoXN2!BvXAWu9d|@R zxfYy>{P;xP$(87PMbdayaUj+Pr;aTR|6j~IXLZW4Bh>2c>ceLp8ppRt?16ATJZ&j$Ar^@ z`WnpX?GEWw&^%UC7vS0ya8;^>NQ5gOlY;<7!ZEgrFPVnuW2Ci1f!fv)WrtQ?`SFrd zgrlU7|FYTfvE4hjU4Q-L&TL^UH!&{27{Y&q^93vgrIMQ?*9`(`DPLVZjO|Y(pL`Cx=~0sG=)^O8{r@w> zz9{uW@-smT>WY%*Zm3+7CO>+aYsPHupr;}A$PNu<4$M5<@8sd2I}-GopJC^G-eJXV zhFzQiwLQy8Bwl6a_~F@oNA}OaD=VT0uTp~o6){Pod?2am&Vvc9^uW9nSDc}YS0Yoi zN@j-OYcCgl`?=+n4QcW|vBj5Ttp_;{IP-k5RG4rkO5>&CSgw$F#>d8rn$4bIlq2Wk zY!)QtHpw}qF&ZkwLfY>BfHmJbHB(s+d%in5K5^i{QLfQ(L-bX&$d_;w7pe>5#XGIY}MS7wg7Km4PeODQ&X z_+})J40j6GLJje`IxubHDIBLG%=j2QpO@qIckdr105%W<$ZlvNh&o$0G0ss6Lc#0T&A7uZ%x9+D+m?*kXipJn^m@h_}-ag{R7u;-?0gICewaX04n|x_JFQU_JAad%!%mE57_!0 z`2XFoO)ZV4B$1?|)h!KRn3y{mNe-bngX^3!c(*9NNk`T>6ucT&L&z9(+V6KKk^6Q> z*Mr-?l4D^1{}0P(3|#^R=8Ht<>zT$P>s=Fc9IRw2Zk~ z-(4fl5?ZBY4lNwRfsG$3RQ`Ton%7c+lvYjFtHQJ=6%)$Ui!`#Pfc^gsrND4R#slp` z`5RiP>zpxPS0TzmF@{zO41w#C8Ld{cIXh@ofH9&Vu`ibsJ)l_Yr3{eTSARC zv{FYoqgq!X%0e-QRtgOGs_BjvVGw;f*i+9amw&)Xc<1MclJA7v!T!I;iO?vpLR~B7 z_awxl`*GAsc>8fG)6Ka~XbY#NM>Qqrh!OKcD-oPbc7jQ=bC#eKs3n>l*#F;YEPH7y z7g~U+$$D*7WqhbEg;uI~c&-zQ)&{>F%7@U(Zefy2M|zr zZGUEIdtuIvP`gR?BV3iKTT|%$zku4s4M$t-B?9#E{vy2PrnZc$EuphaXr=_;TM;{TUeRVdcbN*!iRm!YO4aRhtnS>;L=KT_(tM9<3I zKUl5f=Rl!06W6Ku`(=3=8^{VRC1`$7ll9IPv^y0O%GHZB(UvApK~gES38pF98n-a$ z#}RaBC4!SlO?RQD;WZ2_WtX<1AWP#(`u<-kwLsu6IhGy=e*92nbDDf^Z$0n!aU+Xi z%K_yR1+LQ%MHN~p?VTkA+Q2oLTogt@?Ein@|38aofg8HI4^}H31TsM(n%ps^CHAx0 zbqyePFS_TGg9Afj53NLSH0gb>%rF>A?qj+GzGo8bC}FS4-$vLA0x^F}&LFMm#X&WU z+BVp-#wT+mOCW}#QyyHrZKt3Pb?>)tqH-t%E;jR;Wc`e!VCNx}DpkRjF=U>|8+aMj zl$#`PX>-8@UCDsenGcOgdccNCq%9sSN{MYzj-j*qCAlztt-AwfWbPh$v&b-1_3zKsN^R zD4Z?~e2l?I@@^3O{}cTGzM+SB#V*|;Y5-NyHGy^>U`0#RB6cq=oe{i=$-w?5$lZXs zMsbi&H5$n3V9O*}k<1B8#AaN4)ueNN*leY<=O_V7gRUuzE0OC0>@&2aa2=sHKwu5K z@aPY=tkG1;kqIwZ?qnJBBLP+awT^vpv;SaK4)VSmvriX2gMP zsdAl7PWU7E!XVm%#pwb?Ar6TDCzJR;^alo#_}}w=O-?Q8`2SxZ{{L5Dho-A*>bP3* z0JuU)`=As&iZ`IGe837KFXMw!P!0IV%gIE*2{{{O!^q=r$5 zw2w+r?7RA)jD*Q%8VDZ_392T1P#QccyiT13gon$AhE^C3uMM^e71#%(R?3_Y%143( z^AZ{e9}W*zN%^2Ococ9=CZvfExu!8KLQpygR85nH!v_^Yl#4(E;lt6wo&;*IM;|$@ z8!6cTzp?JUzL^9BNxrKON+Gj%9k-&Chy_08;H<(KUV$3Yq~Y*EDR_F9!^$u@XMBvP zgI(Gtnw|ul*P{=pPH_pm%GHOO)_MK5-}J!#|6NRchz^BhHKQ4T06+-3o@IjO@M|*% ztLtgeb1V{rd_Y~V8{O+?eVh!al%_sh#lZgmLtybiD!96rC4zeQ8a4rDIeMNgs)7rOf%DLh!jwG!Q-<61ST0L22-)@WEV26Cd(mTULUgbP%YT zCJl!VDugH(fd;~dqlG;Q)LxH1a=Lz`Ej1^>9=Q7Wf@(~r6w-pVhBtNC?KzCfmo|fF zYxwVfTjXzuy$Vh}dwh7PvMo){1b#7#aj$z7!Y5qM=CB6&fN)l$P(Bj^z2wf{E^Fe9w7#hmrkS0FlvWc2NP-+Fwp=z2m96qQJqFe+T2p^6X_9RfF9yLXp zS^W zb_IZGfx=J~!o%eQs#9Dlb~ookO-sFgSyJ090Hxqb6eGYiA5#&#XviM`Hx!^|eh6O& z{%SXmpmY$ZnkEg04=RKx7l8)Chogl(3DjPXK61K#q)jy^ckp!%x~ZfH$!M-V5n%{V zj`g}Hj7?34bjtv>OL!H98AMyd*Z(ggzelVy)-h{1^^35>@Oz7P8z5WRVUv5ct2D$W zSNX1DMW+TTQ)zPg*6>Cl`pU2{#pDk}qmB&88pv`1EiZ6V3x$)F8`I>}qh?wKptfgR zsY|v70`?phnPpq$5cfut(dX@wCS9XHg%^1v1sI+@U2IH&ovIbp)pAv>2 z6J{Tuy}xpEU0v4Q`-x{x4_9tVlPC1=t$4Jv6n0Twm2l&lT3n<{yJaC&UN<_RU@e9U z(2OfZ+PxaG6op#F-v77GCh(UWOP2$WAFu36lc$eF^A4V#qLk1pR0PRxwx-2Lv1h%M z%b0$VcCUskZpA^E{ii-f;4e8A0|%bCp|U$op1o|bS}IjRPj!9js;Oe&>?Cv=1Bu$O zx8E+hYNIRw@g&|vJ{P4#qIxXB=xq%p!~f@ z;}a(JEP>X*G)ndkH5a@qttn|zW8X&DDmmvf{DHN2Yeo>02rV~M7B0SV zh**pA-5K_z8%Uug8nu5bwSriqa7qrB1J9jPxiwARcX`MpYf@uWF8Qu17S=rktpJ(I z0VS>)kzJq!20+EA;h55w52wCKVHF`4pY`}u;XTMnFLt?31Es#Rw=~_oz)_U79b@v#U?d znm3||y|`egU(~Rr#Gx*0Gg_<6E~QBQ5bd>b_L%TU3NvYdKh%I2g7}R}3x$Euxm`hH zLh5bNf>%Equy;-*VrWSGq6o8xmLY~9Xhr8u<3q)(mqg^SW{W|E$kTV|3|_*cNq{M$}NWruIf$8l4CVX!UaKMl#LXZ zOiK|E<{fIF@D!Ir+TWyk*j(ZH2HE-!)dBj)Cu+U&F89NN;Kkr)Q2fuu?h}6Vl#6nu zdDs#^Bee`A65%msc%H&%f`~tPX97QIWolw7hklGzs255OQhG+6DCvs$pYQ*jPg18- z=ewIKgvY^-s)dg#g)mMqnxQ=^+ZKZSlST|g6jh#X2F5rx6oC_uHC(nN+7s2jyc4HI`k!=V^Z%LZz4?noY;bw4gkBk;&$ zd^oTW51J{yY+tfvdZ!zkuWv8gRw}rxYN(J$ zTW77qRjhDorS?S{nuoHxtwX2C@kZ(i(U)q6zFj3~_4Vy#!>Itc8neCVfL^)Z0sB9X z<8Q8C(TTzvhnm7G2(*2OaK5h)DkuNXONEz(^)xMCTiDQdHN$aTKMiSXHlIdF&Te#0d z9w=5M8)t%Oi!W9Otud8ODrn1`KiL2IbmURSn@j*bI03Xyt5t(SxhT5UU?hjU5=$-; z=imOF4SEyH6%Aul*U82w$;g64`bLxO7*{9OZ+w{Q6fId6&MXPW6XC!|)?A z9VZYTagCS*Xt74_)UDnIq>Cg3gH~c%_&9+4L>s&RPv!~zTWrVYGnG5iP*qa?tHp*G5L_lH0uy!e}|6fZ8`~{DXPF3ERCSTBf z?@i$%GS7x5IaP;nt_@xZcNcBd8C9JqiyGuj!wA&Tsktc3O+vq(3jHAVzYzXk>MBAM z4QNo?$WksAk)koawim-Uhu{x1l+HA;gQOnK*1xmC_v^O8VPW? z$o@dk2c%pA|1TGLah(|ggyvU&1sJ`A0$e3xNmGpTjGoku-l)WBwagtXX+Bthi zRfTPUmaZWLM$`Z;lw%EWL9kORa-rM;$i0U4hhf!WsW}WM@S07)Ddq}=38hUa6*XR` ztdA7Q4kg0$h>DDrx_jhiXcBP4(a4yfd1L~DohP>C{^-VLZ6Hx8|7)I+PVHT4>TzPB_! ziT^`H-CZ#?Xy~G$)!-g#%zF)Zh2}0Afz=JrLIu_EK8U7&O_37eBNxUZ{3!81fB)w) zLg3GLeDvnZUU>LtO|4x@-fe>;){PB~XYs4Pm_=K-?rg3NM3acmPNFr^Z`t+bN|8VeKY-hQ{`kvVq29324DHiKxJQ=yl`tscZEXcq|%OcX72JN zbfKdQx?7p8+-;M4WoMk2(%9IPTfeO&<3cB1eE8Rq;Qx zGBLhtG&?T1g0BT9%N!9nx(xcLdz}azL9OBH(OOWxN=w1V_|N7F5VY%c`el{7(&UNr ze0-viembG3zI>Waq2I^I=V9e*|J8Fp&;SlG=7Yg~xY{>0+2bWM^p|P+~}zXSHMs zG2`k&T`j3BWbiBXP>M>URg7IBCh60Lph-yNZP$bDbMRfmGDWk`)I9CruDV* z2f#>^-DFd=9dIEDNTYNOk6+YD5$u1Bp_QajW6Hwmg;=xfJq%Awm(YDmgxH-ZJl+}c zCLShZsRT076osdu0TMw(oohJSl7rBgMiiAEYyIJ1N5$#Yaa=AkC`b?>UJx42mT>f} z`?&E$I7)Ny9#K!ID9uQyy|-SDV-W=@dEZGPnwix!jw|e_!^zaA(XcHh*W}V<)H$Ufy9jy!iM(+i zA5#bLETkD(C*w%Llpwq6^AQl^yC|_+>i86e6hjj})BArG*-pq;>8Y^;UaY!Dd9e!J zM{_xYN-&eCQkmzD2+jl0!%AlGovSM|Y4YKl<$WF0U+XDwdtet;sk|DsybFyfR1(r# zX$X(9T^UW19=CMv3e`5sOwB07O)2Olu9xnlFQX$7{R8PVTboZ{G5zp=2toS1l~>a! zt0g9llN5x9xB#hmMm&@O#(VR!Ic1E;Db_;rEu?*-x9p42;Ty~@Z;e8Tz(k5dN?2$7 zKH1f~x?$Gyq8DaIH9NdyifO`yr33qkSP!4cExK9; zj5IpPe8x5*O-1=*$w^=ch>{Yw))S%enZ2k8!bcG3-eXdO9k}YnFLf$e(*)Hs!^~#c zb86o0Yx8{7<%*Qgob*v>&{UHmLHs`&%jANAAX9M-2Mv_C7SR-C^4KzY6FX z1X}}*MPPw}_#^-wc*}`iRl`ID>Hb!W6$w4VupnOkqWAyO#39yaQeP%7LZa63%-NMU z!~1OKn{Kh8J8nJ$WqPgLRtcNgv%^5k#f9fyQ<+VZ_pPt9yLx73Z`;7&WcY;Xp5x4$ zO2ZnAia|N>DgW*_Rt}`ePZ{|HT{o{oKo(F|FNkHep37>`ZTdVqjMe#Ap>l7U{N^E( zPV~xHHSd@<$V}jjcVvKV7)Bzlh?VSaWSuUbji}myVQ@zzd8NM}1K>5t{kt zTxRV)7pf={o$iz1OEaIrLln)G0uzNe#fciQCM5B{%R!x<3+A$G>p2YF=%@&@wlGTz zhE#?Q>K>*p{-^d22zfZCM7~NlkZD2qsPw1fr9wj-i7E|SO*!wZ)x9*AKQ1=v<9tWL zW@^D=Y3gGRWMlCs6pe=Y48ON_itX-^iMy5^`uTtp?8^b_(-O>oh0<-jUl4icDqC0u z(<|pQ|H!7^deDbR3`~iNiI2+sY#OVF6Iv|r`QI6aorpGaD8{;IfOB8YzyA60Wv?^og0s#tU<4}1S()c)<%E@JcLU>IM|^BoHdo5|3~ z$OBwlAcLue6Q?e$97>bZR|&ap&fI(O$ld)^PV~Q*<0**aN2caBZXMYS|EF+$ZD_~E z=HUpIP^`|t=8+Tq*~&rhMw$WRFl{>ewnpPyJ+nM;#r zZZN?@Bjy<0W**qw^xX$%RJ=ymm|z{~QgTQ?*q8&T6I-3lm^?kfw1n2vt1HJ~RuSK3 z5L}Wf)hy9>F$+8^5~HUU6yW<{<)}^W2o&pEUtM{?CU2F%xHWN9@10zhHmdp0kcwcU#-632TjYp=G81G44)_PHjL-0FSm(1yQ4xf$q{*qvI3q=)wfm-Bk~AgzrVkwLAAs+u4*(vS z9B`cB4KJ;%o^6vG1IQ#4?{j(eWj0yGp+-w1eYw8n)w7h6Q7B1!CE1a_&3&(_+LB`< zpWM6!))rgob#i0@{sv!FwQM4Oy@eJp44zj_*<`@g5e^Ap1cOlo%PVh{U5$Kl!%JI7 z&aFIVlPg5S4KFRPJc=MjUmAUBMdhST@-D=~Yt~F{ywaJ?Jh=bXS5_Xe$x5#x^X&1; zThipcN8F-YfoSm`K7GXoA$~1El+$Z()WMp2UA}U{CgSNuF+@2$mmTygU~JUx zm4|IIq)omV(uHy&=*%8w8;c+DyML2%Dv9>WPH7APl;?BlP#V9 z&m(sd`{(R;*hlQW_Sx3wt#@1dt*cW1k@{5XWXd5wB!5ai1R(K`wbj?y#JxkX_LJ1J z^T|8|Q^S2TkQsqVdcT{737eN6-@Csb=I*uC%W5}PFkR`~H{&+$t6pjocSREHnN#sn zu6hXyDS*5U83qfKl}0eB6N1(&otL&&FNW~oLhei%_y$Ge>?v9?1M%lhNw5Ub?7yu1&^-YO%1^Rn=Rn=Ky_UeCU3iG z`^IfknO&3HCpYiTWR6ZB-hbp!|G_e$Xor75N+?fAO_Fe<|~jU`2oOmxEW4YqyG5*%=w{qXUF2WRgAva;}?P%)d$gI3Uk136Bqm@UFv7KMDC zHlT;U5dhbKs244wfziaffh4^X4kYHs1~z2J9RgGeB1-0Av(|9S4>;8qi&GJqV5Bx4 zFY6M3vG0aB_44W!Ho45zs8>`oHo1IqYRgDz>qzPB>g#NB;g+2{Zn~!WTF`r2nD^Yq z$=f!ATX9CRGb4^nWF1geb{w3A8RgiK<45<+?44z^?UF063f(b31PTn~D7a zd#8PY^?qwK^(W+y$TP4L81>jx9R=c-8I2ZOTi&%*S|;r^52ahHBY@;WBNAtPd_+M6 znNf|2kLJj!$Ew4io2f8dLw;O7A5viXb;1ztJ$mH${d@NvIlOOrj(VT`D5gH2AJ{fU zcO0niH#KoVa_*HqEyY{$qDE0LX|Yiea!YjxnCUda0FOV|LC#bM0r8Glh&56g9dwa; zy{L}(k?H{S^GK|I201dRRa~O=^uDgzZxiz*1gaQNAKp2e&o))p0PSXTz|8{_ARPmc zoWG~K8jy&INHdEf8Yq%TNGWPD(~6F${hv?9i2Zr{efDbWht{uKk67cW|C{<=>YJ&r zr2c2>>D0DVntYM`1bGy|_%T`C2-GdVY3Ii4Z`_#4?3>J`)3ax%|16sglJ0l)6K`rtJm6Oqd+r#|NRGN!N6vZ90sRGE?qcrMfDn+Y!mev6=40; z!qkr4C$6n-09wup1zHzcdty^{J(XA}kO{@Qn_N29Rj&r6G2p1#x>Q{UK@)F%PGyNxPVYN@{Lr%XnPqvmxvzpgMS6VCp=B?tuC>YeJFdI-+-eDe&23Y=CU@?p!RE4R z(I%Jh{L88n0JL@UflbwMI#^*^w`|cpIznz6}ZBY>n-%?G1RM96AntA0Y(RC92P zOK`#+#9Hn~Jb&~_2n_G5IzZ|jKG5;vdH{y`b#UY{hk5`nIr5l5W4ac6ZBUCf)ohS1 ziAVTjO4l{jtAH-sN0%3D%SK8JBa;T_8VaB|I5}x)-LNR>vHQAslQA8 zHthUAM7~eHKt4(i08qT+<<(sf`RttBHnnB)wnBBMO^&$c@zC_az2GwT-FN?y*~4?0 z48waDA+CYD!{Hv{X3s;+9Xoo@-0UIvsa#nmiIUR*{@~UG)YJV)pR< znTPitoIQpimRDa7d-^Vp$=zVb%d6YGlD_G_^%GZAw<3=W!kfAG=lg}+=_cyVEYvTFg@^(5uV;bL`@ zO&$_GX{TVWt?CR)je*+#D^ov7>^0W+t*5Qy*1gsqYlAgxU6T5z)E}gNE%l2~nH-(t zz_RKzOyYcUI=6ZkOz^ul-ZFX9j%`!B*PU103%B!Re$Be6-D@tZz6o}iP#J~Yy$-

    DWs-3XMvvJpCX3g}PHFvL>JpY2_)!P{$^Ze^zxl3MAy$u$=?py$VeRaU8?twW&bhUHRagTduGR}-1 zbm#xnEliET-p`GxO%XJ}~X@bsaX;oNZMTBk6aUAAodIy(QStknemk|W`O zfdkJ^Rqsxd4_qNMpV|kk50)*vZs(30m-Ryy4yCg0B0jSu^8>wY23&U6@@!US^JgsA z7(N%mvq+n${afVqBy|c-4IQWR)%~#TexITSp*j*p)N9#&L+sxL{<>KMAxO=sir%cO zljkv~qbDAz?n{$r9}&X>!>M6fX0~yoQ!G){pq9pUHJQp{w5H9YGT@8J@Y=!cQk(xR z@_u5C!l`SH$1kYDF9|+1(hQ>zI9lp2mWXOUK2?R^SA04~9AI`<^~t5-357q165F>& znKU9PK^{KQGr=aH@4xuAPlv6p`{T^__0q@U|I`}^{3S<|Iq+nr3g4-HZc=D^BU8J; zQMVVPv*ee)bRGOhGq65jfL)p)n(>6?4Im$&42MtGN4?!t>NGUKiaopgx=H*W$!&TYf9^IQ z+Qp+LpV)u68Fs7|>>qxLpeO7<+5Zo_xwYih|EXofx)x4L`GD<9_?}s_w=dD$8@`%r z#r@EF*M!kFp7{pp<5ySV=U|?CREZ)wwMeJIO6@g{2!f1Guo?EhY!dFSErUlfDKlB5 zD0V`+Z~nJZOpW8 zD?8&X+G6*nM`ixyh_riG$5P@k0AI-8{`lWYy@y!81E=KZ0uF$0fe(o_*|*RquVU@# z(TQ}=vi*z4w*cGVtBXx$n|t>?+73uW{zhSG`))t;{r}Y@l|26wV*5|tQiU%fKJP@E zxcFvpzUET~$u?WtAF~U6sI?h!e}ws8JMVkX|4}uRTmLN4>ivH!bphP}hf{Je4xC<5 zJqlBau=b4n=78~OH?g*h^H6hyr;wuEP@WhoX2Z6#Byr*iX+F2hThA=GhZAycrl*GB z{{I7k`~MO@#cQ}*0FQC)&cGW)=ZFK|GML;+SI6SrR$d8j&=uF0@)HjIe^qwE$*n4u z@AIjM4?*)l?vQ&#(f_QUOmrT z1GVsg7)`))yu5fvhm!~^}manJ4@^zDs> zgVNt_+5%uPdUR_4X)+A+zxA5be?ubV0DF7bv$qT!*|AklF8LpY2k^BZmsg{m z1S8jOa`AbSzd+DMy}$u=ajB?u695Jj(ZxgtYh}c z_B~tVaSH?BwS8~@wAcRQZ2od4&@*~UBgV8t?f)EZ|F2H{Yw9;rkEQNTU6*<}`5Jr! z>~_^349>$BXzvi(lF6>hLX<(z&MF7~*oj?fQEnbSPV2r5Ks`kmu&8#fnYZ9IP&>Q} z-jC>$cMrX@4xEX3_`>aREdoI;CPkEGGEQk8zJq(Bj+WU~&Lvg&V6OaZ7KCSvM*2zM zVW@*o=LYHk0O~eYABFLrEj!K74~_9p9Iy`r(UWAHfo`V?AKsnyP`HdK<#PG_L@t{j zFOC%^=o+E8s^CCWJqA(cB~|z)uSZixGLzB!7JVHE73}|nXaC6z&^b>oJb0s5YX7ey z>*)7?K5XA^UubQHxBfq!dMGuO8YTZtzDp|Pd9n`xg2$?P_!i{NQt{j`{J|VDyYI+; z_((?yK8Q6iFyO43htEHTzyVBY6clfG9=`mz*TdJ(z8EO*Nwf@nCD_IMc?wz;9M)nk z+DqnNh4uOVqwv)V`mH`^0DhNc9zM_LMw_6`2WJl7J9hw@9^Jq0_~9c14qYP^;s5aW z2G&y&FQ13cH*S<9-Z6b=e|9iSzrUDbLs&fzA8_0y>*?#{%oFevayG^JbKr{&9w0Yz zv6N*W+#U;9Fdi% z47had{Mmrxte_kKEDs@|s}}{hiZo*^WZ)m|$a&p7d==h(dK|OG!*I>~S;KdaVoky+IU41_siX7odEUpp>6q>DJEhUV;r;CF?Y%54Y@?N?nmU>sKWu0O z9?V=recWUNO?PLU$0z15g!}r(q_X$Gs0(_*P;MaAI!%rz8&P_+b^m?Cat=fplW({#&)kO&}|RDc7W&@-_A zTZZ?$w$CF{^IT-Ep$L+ho$^Ns@H-*VM4IC6c85%AQ3(L-|JG#63ogxFkC^zh#HVST zdhbkkbi*r|rMR^x#-14aqBVBy6jmc(hy6dc|4&{?;Ok#-I+dP>U$;AbZuE^@9y@3v zh^fuyO;U5Cos&1xUCCdXn!hMbzUAFgs(VAZfsJjqsT&C-YopFAP#0A+t+9hHo?IdJ z-$m^|4Zi?l{~~#s+yDtOJ`X?IDR1S#W7&OucMrRl%=Clz!tL?FW5?k~_y$OS=7Hlg zM^EfMau^;N8z{}g4|aMF(73;3NpI}Kt#6!v?&6IcyA)`R z1Y?ND+tBu*mAZc7AUC#W)8b9@m%#0Q_lZn+B0!R&yLAv+Nfm&hr1pOv*-Gr+w4br3 z?bq8m`w}~4{hjq`>yXu-`ef=SQn!;|BPReP^cbBVv59=@WE9@l2sy?}xx&VI_>n&E z8H*Y%Ff#b%)uL0PI8I$W4?lEwdQ5nY7)UU}CZ;{wHqO(Z%9GEKaMFgNbmie#K0hEI zz|CYv;W?ZK=lcQc17g4<&d{2n(Oh;7eA-)4Nkb+0RQ zHqFytwR2xI%49J0et0v{g?adW*&~9G!D0F@b1(hX3gFMcLWaJi)i2%w%4P;={U-;m zyKw$Wo4BuZWitIGcq#^du5sA8aDF8&ho7Vd&kE%$=KE}t7v0dGs&*?boQEIu^bo<* zI{Z1$3+CasJ+G1t1fDDB;YU7qh+=g*J(k(BYx4MJ(oZMP*P_W&1%n@jrqiuA>#pOo zE)=^HFZ}kWoOsP`;X$?jjIS-V|Ff(Nv46+@n023ZJ0z1M;eh18_&oeZo{R=Zoz+=* z;BkRv9hCvc#yP zkE7Gw%8PELtIJh8Ay3PJC815liBgu(_&-Hp1w&tA2|GS;{d_)6K6$=a$%KT0T9zh- z9pS)|(Bwrtfpty`PeIkH$1+T^YOtxE{}B}c*mj{`rxYrc>spBqZ{dwSLxKU=c-!nB9=dauXZ<=yautwqo&!!$Lqbpp+;^_?cXLliFJ}3hf5QV z%zViv=1G^XI-aoSi)r%AE5c{yW(y!PPdYED&Qnkyv*OJ?kCXWc_-vT`MxNfGCTdWh zETXkK%YKm@PTd1`f5|KD|FC~x|D*jq`@8lx?XTNkvws)f3i!Nz#{RVZ3HxX5583at z-wAICoVHKe58C(JZ?^Z_Z?bQ*ciP+S>#RSs{@D7e^=0cftawVGZ?WdA!`1=oZtIQKE!Iue>#Z%;2CHc0tYK@lm9Z|hF8Kf1dlLXTj`C2r zdU|YQTRs3|Bwvizvi6wW)%4u6I;>r3EyE1ZxgCP6){(bt7Cx+->Q>=m(?_Fu3M@jq*Sr+r`hYwg?GpK4#%zN($kUeJDB`(^DHv`=dv z(>|!ZM|-<=3ic{~L_4A#)b7*Q=_7hpAJ+Ty9{n2qO8s*EB0V1aY3wJlAI1J5_Ji1W zwN2WXwpz<;Db^lsKwGX|r+-dcs=Z48q_%`9zGa(gSs=({Ee-V8P+O^gj%=#I$wz zr1ejgn;`zj3hd&!^nX=~5dT93S6}|Hl7aZU72JvK+m#f=e^G&5*q45*(g*Q3E6XAN z^GX8ZKdV5!OTS)$?=+YGw+blkrC+N6-b;V4av{XOTY=h_zF5&Au2o_XS1KCBrz_C3 zr7x7<0`V8iCm{a$@?#KxuKXy(KUaPP;!l@nA^uSL2*mF%KM3*r$}mZ&kmmuC(hVv(v?kyut_LQ>_-&;n?yuJ*5vGnfp5X5(t zuYvf^@=}Pmm#>8Q_VN`F-&T%8yzMl$1L2_~z65As#=C)Z1`+AH?fV?}2#q z^c2MFPVa#Drqf81wWo(6UUT|Jh*zJ6_LB2!NQaTrz-dcMF95bni!Wdw6<)yJ$-jVg zrCxXd;{F#9e$NXC|N0kpLwxlM_d>k%1#H(9FJMnCc>#Os!WXcO@fYs61S+^dTTb*L z_}b?u+HYu|(cTERQIIH5DzB5iuNXF*)|u;C{tG$izF18!!%gSrz zmGtmA<+}136{u9N6M~BY9Y_t8S4%q|4;%gv22v-r@+w%oZ+*{XtT+)i7&&>hf7sGI zf2v~@^IoJRMZa}!TX_U_cfCRKTTkFHkfYXu-^999PN}yAFij8+(AXrDe@*)_fxjr6 zBNRCGit;E7zg}apu~TW((+AEH3oNB8&_&@3Na;S7uRhv=AyR-${=Y-C@0=sde-1VC zRH8fvaxQj|_w!up^Ho4TZ7iEt^^HLbQp&5wj;42q{9jB~aub`4+`DHVY)4$mgGc zfB0tx2Fdv#GhE&*?`5Dskjis7aNJ{glM9XvvX#ray0yF!aJ*Wf95l+SfQoRay{0yqY%$0 z)zId~Il4-!+Ib16J8;J4ge6@wy^E*+4)*Nnabl;W)I+t&hBVUx1yAQqJ$89%R#rbz}ZPsN~GS*?gg3zlDuYmw?*nLD5_RBLmPc{ zyPJ}*3KZ!0pIk@q&l!GZdwBvr`t4VoOX@6G2v}DXl~&tA3%qsJqKXo19D=@&TWC=& zY6o?!BB<63i&MKn<19AjO@&|HS~tGOY>q;$W>^asjtca-zy4`P@whRRl;+lA#1L@< z-yhx`5`uodgDgA~{zkN<6a_-~lF7B7Dg7|&c5Xl%U0Wb=lk;)`I~k6~G$V!!+WyB3 z0)J76C{UjQ?^s{n7AHSrt=+`g$wlK5f({I?;$=nBj1H0ExLh}ln;j>08E}(~OG^4(|%LR0F6DB}UJA@W{{~YUlJdwhMK8vUGr7m?--WCtg`9Gap zM#vd*JN(>K-VSexb=!O&vIqpO-r1cQugFvXkEiv2=(_Ulaq`7c2MDWDo)>>zV44}- z@~dg!yBz&ss(f3Vd|}#FolEZu{^wOndHg*fDI>cCyd_K=k0F8PXmv$MFBSsJYcnkE z)-EXxFp-GBF>6Mb)Pv~8ELg7tjfn7p{1A{I{ElGO>N|^=cAA>^_GDM`Gk66PEbk2S z)?Ok|wm_Mr3i5egLP}I|58ogOa|x7mDb?lOXt(@sX(ll9kv)e;vV@|9487z8@y0B8 zwt%oC6nF_KNo`W-28Av_tM(}6k&H#mM-t-nk~e6flN03sn9?>UDcmXG-Eg=3ZfRz< z&I;)Rk7Ru20c^2!iAfjs<3R?G9olsc2))>qW<>8A4h^(-7t#!?=WEP@N zQ)UW4;CUUTGFBe?$pmI}Wa6dqSKwnMI`dmVc`kb%`+XrRqwj)({FoMAkgcPgY0|_b zft?chxrfR-;OpM~F3iBGx%hrj{^MjhiG3@!U;9V6a0%}lDc>0kf93Fs&1A;><*VU&|Y#x&FK;W&fe{zSfmBS6o}+0 zFt}|C1yEL+qgdOtFH)c_Z3dtS8-u-uu!q`DH=HPI>$_WyCbtCP(t&>T$!96K5O8ez}dip~*;1h7bE{r3Je zNfv1+K}$zR@i+EBDxS%ahtuzzL7s=nEE?A`D`BM4rIQjI$jtL=IUr5*Ur;vSQ z2Yj_RpW0HsD^8xhc0o6Uv2UAaw(1O{G9skwAtLbw#oSNe?0M_?ssf9QCmL)^9kH*0vU=ZT$K#Y&)Zn3(Xml{S~dgkPtvu~%%r7l=qunwo=~U;iI`%D3_*Af|n#4O{D) z$U4PNlD15YN$!xkctD}MbhFs3RHVaz&mxzPEkd*S+%9|pbeN-vq;f$1=LB%Sj8P^* z0mldo+0=S!UPZ)==tPIDDra;Vt1$l`Pz;M#*!+SDkz7P_(fx8k+4UUYak~Gfc9y_j z6wW;geDqNH^>Om$-O=j=Zl6r^Lc6G_7D7=)s7PtstbZBa1`&xR#J4oF`eoP3sQ^%3g<;DFXR_8bX&bHTe;UWv$suz8W&BAg)cE}TdfWNI1D;cWqLLdh|rn`wlUi8s}ed7*N%xkm* zg!?X*@%lp?dwaYTCbr+6x24L`)#x#*JL=_~fxlhER1rf#f7m;#8ySkN|JBIH3I26m z_}s1KH^j*wst08vugkQRt|J8$X>yf0kXgD*@FaFc@%o_#fpOqFSA@Tj+ z1tdpeXSE+_pVHo-t=6uATmLY(x4aj2O1f2gYm|a8m>MXi#1Ya)sZdI12do6llEN&5 z{FG^yMaq#WrZPpBRHM`$;DwTRjfK*+8Z}pN^IM;&eLrhG5#hqF@ZFg&zJ(O{^F z-O?Zzf1P70Yk{m%UP%Q%LXsTz;}B|L1EeOeK2&e70cKB$wsBvZgT z1Y86oRZ6AurF4qY4KA|%Rn@sos_F>^yUZ0ER9kpbE&t#(#>-$WtNN_C%soiIPotnyJF-HTH&M zVNO#EkcGRAo+fkf5*)O^%_?ZiX~G6${LYc`{W^Kv!GN+?ZDFGH8~ECp@_wBhau%iv z&`a@VQPllf&fDQh@335#ad-YHXUh$hD>geWm0|r2G_c6vO;;?{HQdWo$Ld0Tevli^ zd0CXAoz7DgIwx}fB7l|=iD($H4Tx8F zNecS^n)U_)e^F>L1)f`4J`^V($tgY=>QK-GcC}#hY+9sKnWvC~VFhrV-8EHgc#A5e zql!gu6)b~^gQx}DTo`gZ2mjxLM!&nX5~FD;UGVoG7D+!?&G2t-HuAp~u(Wk&FQduh zZkal&n+INudY8U4b@K(HK^Y&Tg2|2aV9O+h`TvKAcBsY9Zv@Usfe+~A!*TLU>N}rk zKv1gV=5@ckTef{64G6&Ze>XCzL!H93p#f8drp9ggAd-(Y-0PKRA6>7V>_G8#%?qPm zNSB6a*4*U6Zx+%I2iy@ISvNB}geJ$i$vEZ^o7w*i(K1eR6{WaR;JMNAOq_i5f>6_X zK4Yvlt0ce4#`(i4(p%n-|1vKcyp{eLf&e?0cn_2f^+|4-jpelSkn9c~_b z{#Yww_{iZAQq`1au$bv++JDdiA9N*F-3E zZV7* zQ=7$KZrEi@5|cJN;!QU}A*6k2m`zbF(q=_d9-OOX+Z0}K^L*_idicngxKvPG@o8fy zZUsxQgq1NDE!D^(5-#y3NC{dX99U~3c{a=rXyNjnmh_Cm9|3wa(u=K_3J6PeQ|fU1 zAB$Z{VoyO7g@^)_0`Iw_d?Zdjl?gS)*_b*42lT@q*Y4K190WanFB5yRP6jpEn6ePxNg3oH5XahiVrN6R#_MjT{A z5)ZpbG)m@7H*j?ms{`6Z6QPFOTy9sKx6t^H~&WoxHb_58HvC z(pQW;-r_Hj4JLuUq~JBn7o9JOQ8gDt!n;FuM59{|Nn7w(Yb5}lwO)Iu~Cq)`g-xR zicfz9>#IgpUU09+#S|n1+kz$;y_I~?IHkmw@-9*pqL(BU<3$#l-X>=U3K+``Al_F`DmQ{pVxGtIu}nLU1{n^G}ZtYh>pcV z4X=!d9APmDXSvKTGl-;9tTRo->KG;^xa97!)))1vb)A{E- z#ckG~5VZes@)tz=thQ4-4=xr*NR}Vb$vv_IQN$gMFrc4~BOdsn|G{o-Ek6urY`xAm zJLF~M1pqjXz=D>_tOj`apTaxdJUqnDgm>zW^07F1wiCkan9CLlxuU$Zoiabny2v@q%-MV) zpDUC~Ylhe-iq=HB1>Emh(2DC;5)=??V&lPC$-CA|j&<|064`%T z4bXs}770k?>8axa;3Lohzj%&0zqpo$YesLA9I2VERWo%4nG17BHcwm$^8ZVbT2$2H zq8k8PI}>o1*j4?VD?{RWlCFn%X5-?SdO{ZWq)B`?KbB#Wr*S zv}Hpx%We0}BCUw?RUrRg5EJ~7W~5W$b>3GfuS*u1-i&-_@3&Lo1`djXTClzo$p8OS zZ{FJVH6V8-7x~Mh$Vw>O5m|^J7NQ}CXMUs%VDncjDIO7NY3fHi*6 zyW`eQ-$vpWy@Hij-OkH263*tb_5YtC`t90AElWPr@-;xs1N^N+Gp*3jC#Cy}bNpo%CAh48GYo zb$Bb7m zph0@0;%W`r-*dprzX1Qggx|3wo_Hc5u{kDT5F#YLbzyR2$(DFvlR&w!4KUV40o#h; z*AKK9)(k;Zj$iBGO)5yWbr1>-mEmHG0UHC(AbDZ|2R|M`|TfD`>DHZv{orW>dgV7WNxS95{l-Fp8OMJ_YZ{(ix+WG4jPiCY31|xnePEq;iFHF+@EA zx({-Ip$FokG~gz#Jt6TNtjTt$p2ad52X#0ksMZ5BT8GCoQMv_KGgw%g3DpfDxk3+| zTpDTdh+JM=`!qcyy^yoI5G~q;oUEZx3_>G-?$Ktmv>QnT;2`Lr{TBr~)|rfIbz29B zg%R0sx!rLH!(@VPK80G{Mt7_kCiu+6scF6tZR;3ML;@~oZgpgCh08~Y1&4hWB?E|j zCYwqZ)4(V&lTymi{lD}Kfxjq36o@ELp90UXDZeF7KK&MJttVB=4u7U&nv+(KQAl3_ zeE;8K`~UqBA@H{d!rO)_u$}okrM1Efv~Mhp4p%<@Mb~p3MPIbWvn4!7qrA+^(_hb8 zIx~P-;!}TJDTM}5pVtLd(Z=+Ov$o(N`IMS|&(bLK6fPsYgPo*0UEp*dYhp7@oEM-E z%sK&L7g|d#g9e5f7X^g60O{3z{Fl#rQQIpWxz(j_J>`D{8*LN+vmX3H>-2k;ruJX^ zD1pBybQcBQc~?b?lMfdbyq{_6WA@`?8y&`{+dOD!!D7<8;QyDA<=x5bsWy0bhUrOO z2Iyyp>r8>nOj({A4BitP6;n~7)|N1NG>`f7m*GVE>+jt8*wxTwSuxA zjvg;{8R-6>G4fA1{{N?z4}ZH4;M4mm=f%mpw^{@8H7TbVcBPl-ceXDLC#R=}0iM-Y zKYnQ?9w#qc-+}7*5rzux{x*s?0iDWdWQJ5=L8eQ?V?+CpOYz*fwQ6=a&~X1!W(E%Z zZ4}Xnbz~LL<%9aj01HLDC=BpC+eo_qxAt`s`&R5DvBPi?g#}B2x$7zy#>vT1?roUn zY`%Unxgz)#xl}e?EapquyiqFlS6-o$y99o2Hj+(c!Gu+*a)C}B6?q3>Bx?TIf5iiF zadJiF{5UyvJ1;$)ZotjsnwF}WaIS&BUGAnaHOjwEUPZKTlR5Z-@Jy+)Bu?J*FsB`D zIorb_v2q|WurjdkubB-HwtUndj%2GqR?9qvhZKYGmy`(1qb90-hON4 z;yC%h)g7o#;FUKKN&^xQ5I-{vvtOD_TeAd0V#vTB2zRa@zipCTE?Kg9Vsd=@j`8)A zoCZBpJ^Y#Y9l$FKfJpbh_@q7LJoAq$I8ju9tiOM1dF3KFkU$J{XuI0eiyXt*7qK-KQIr;REmfhPeLA>gZP#xe7*O!+GU>s_E!)O`5-BOk^OCa?{q@X+4=mF9 zX4?o)QR4ku#(Cc#)O@#tV&@_Y3%+fPuz@;(Gl-+7?ApZT-cg1otiqV9x1mr770Q2D1&;YCV|1fkTs1bnaq|RqQOt;Y7NETcd-n94{f=u`b=&sQjax?(v(twj z+xS=q2ftFAx(C~eSG{oT z%ULc}_FvNw2GMgr`KHQz7AP0JW>2y*%U7+}b6jcWi)&!L%}~l17&>7LWHO#Q8qlHH zR)TO1f)kZ5nLnk{igYoXf$g&}A*}?d4LvW8^`}q zSVRz9Z(W7 z;?D6Xon9#(+AiE5xIjp!9f=`pw6ZHWGz(S%CT>DOwJ>uO^CF!~#;&Fi#g{r5B7*&1 zOR)Ahmo5fm0*g#0ncGE#W{?#M!Dh!BRzpFCI^4nVS6L0uPyp^A|9=#6N?TCEanYPR zWFxEv-JyY<307wLsud2B3~!0uiED4?TU9$6?6g5VbHmKQ0l5Co`#d$pYB9ELp67Q# z{{I+g%cm>aF~{pJBq*4mu7*mLP!)k{Q5#`Q!9MybjJv1r0WINB&j^Mvw^xy(!6YOVguBA`DK%% zB`ChQxaMoH1#Xmr*^=|!(plR7!5^s2B?pqjCHX%vEsR9A68b4PV^^p1Itam?uQNptde4EZC<1qdWd2&aroH5g9q;GLsBMb zM3c=HuWj!^R3+ z3CNcL!gq2o;ot+-UjGtD{de81AZQ}viHQRsE8v-*K4wohz{^lrHioa7ttR6YeOW^R zyP*=MbqwxZcbl(&k}mR`$fXC@!Sh@ar@WJXSx{7yIp6~?Fu+v+jl~7yY~uL7J=44Q zP479jpUdJcaM5@6?0=ww-*@)xGat?-j?5f8ypQULVhP?{;_$L(;AK%-t7@jo1K}RI=Fl9{ZohcPao}Lrhq;hIXHXdz#&OVr&5U30zwy;liJiG z8&2}JgT@Qfd?&mn!P$^o#qRAuEo`0rf|{SD@(cMlanQW8M$w|mWJY>6xqegc2>jnV zO0Tk3$S0Hd{x3%EAh8t?wJtn)YvuAddD?ANFFG!cL*YQ555Z^1#dM*V%i!l|=^UIJ zmdfXHuzWfwdYRIgK^5)oa2PZVs@T*vg;5b;p!5APo_e zd@{!y1?!!Ie#=; zz7YFx?CIF?n4$fH_Ve0q?FRDK{#WxIGMYUmnlvU zfo@ov88B8BQqu*4lA$FHvDHUoZ@h8XF>Smi2@hPc3CK#(*@l<5MEDUfB2 z0Fg*afh<*kIJ?EQo2+gzfTWjJUaONEI8{KmURJqMCpTINgU02R*XX2IN*OT5Dp$x= z7tD_}7zg>saP}lSmNeU2d9_Z&(kSCb1OBoQv#T488)4)EG5lLsc@KlZ2E z8Mruy!rZ#b@;G@?^e}V5VfYQRNOW4sz=fDR7)B1Pi;*h~rt_Ins!&2#0~TfG;M0#% zAr0OO^{*2N6O19iWYZ;ZMhcK?(D|82(Iu^bkP=gSj>3q5I&!&829C|mC zd-BrC4e+I#*kQo84X_NgP9su*8ex*891SC9%vk)8!g5g#6D zh9b)<*XyLj_1Nf^EmY~DiW@YT{J)jN{!7b|zaww$wD|9@^nsGy!I5)eUt=(7^p8$# zNLo@Ul0ZthxLM+oI5hPL8`<(SI=Q#0(hD`c#;+!vdUL78k@V#H$_g0WTVcH)}#{+S2*yVQ~Aw*qZGH2G+`;+@B$vAn+zaCTWxsVGpn(wDm z8B)cd$Z+;sHkyeMRSonrgL;nq05K@tfzAUFo$GY{2u_VsTM_z)(|Ime=?6!D#>XN! zj8<3hGn4;+A^L}7f3Llf{7a|pf5+>4&txSPC!ZSf?I~Hq!L_B~a`|jNlY?1Br^2D{ z5ShacqK6kSzw+|i-%?o_Cm+;1P@RRPVH5|8K|+5L6?|H5VR|r?E2N8ZQV4Kd1E))D z;8IBO6n+n57JShP=D@-?ZDb4CVkVz0)k8alt%AXT3)-dyFg-%0O~xQ}#b3@1RE9xD z#r7k0ZJW~bE+$6wxYZJo%W_OdT%K~r6bE-yPn#scdoyKUWvD4b%I=nRud&d-k8SPwTzjxy*!>G$ntmUq)Q`xBzR`3%-QDsUD zID|^ESjXZVptaq>F}ct8#RQ+g?^bc9^lw0%hYXx@c5nsNx)#w~cq@3pF6JG^wRK`A zb&@Hrd4X^csNw;|`2YG+%)J`HzgF4BX*k@QFQ>Yb!c@OvdIIPa=|-XJTqM&XsUT>i z8yj(Tf~z5RVQ5*lbx-~eXartzXjqzrXc5;c zQ*48l=Os;y`TEInw^@q6Maap(>2;$sZw^3?1XqTOCYRLlV!J#wkpI8IFQ_7W<={(^ z5DAz2^y(sU1kLwwnS7yLLe|9sh64fl4TLmW4*XJv3QC|Mkq{~8MI>a4TFA^-q85Ak zx;DZkSjba=A!k}F2QXworz~NLB~N%oNB3^?|M>o2gO7jUFA5O_JSgy)v5FBVzbC%N z2>0qd)S`)i8bW4zp)IVk(aR|Dt_4WpG3yP!|99a3_k6x=6EBcudW&mI$3&w}i}!pj zTd^3;kS?Yf(uF>W1M>er%&%SS3s7uJsD#veUbyRF59JfRbYPztMXQ8@y-AM7mx?@k zTlH{)1@ixWKNeg__UfFT$cZL#)OS>hv>5f)6@yJXH?0@Q|NloP2;`M&;`3LpMW>3_ zDf4g`@$`T0q zDzaCL$6m?(+9F$ZP7fRLg-=MkrFH?oi-ar^GQMk4 zoZFr2VAAV-bhw#o|K5n+vetjg3X=5S;s4)7EKXGUz4is<|L^(!cI}?XWE+n!B(4qiL1eHO*wMtQB|OSi`z481=Qco{ z2mRh<>K#3PS0~LJ!?|rn)3Ol@7 zJx*f(3Q-gy3UrPF$0|A4;m&`{Og1IJ*QU_ZCXy)=MNKSm_cBPZt6rjKs)u@UDWkv8 zmplsU`s9U`ENuJx+HjLcd@FY6hfMtacYRaIHdlAw@sB&_$*_Q8BZ|>7RfE(ERofneWe{g0GJ;A``Y!H|8Lb8QI zt{CcwjGdJc*cE)`A|uHB6LxO6Qi3gpr~C*zIHEc=!W_X-^g>wkc3>f6C+H>hPH^{WwgLVL+4%89NTa+0=OwMF zb6%1(qtkXhYMle(=n|jvl9p6fgDvo;DX?A#Z9zR#AbL39(NUpI0m{EdK0xrVYr@<1 zSJuVJbIPeews{!nCgfzU0=xy=VrVvkbB^DFzwvQ-t?!11vVOy^D=aU}lF+t(G3>ib zkEOZhZ4y}N*mkcpx7zFGA-ABftP19VpjPFst@GOdBL<5e0`zPed6P2+zc}A1% zsKRx^-Keil7>T`o5pP8#caGmR9E&Gxv`}7t1;jIFF&7WRp~JeW@z54$D?|hRF6_m) zVy2$U$tx?PVD*iK!2zu!0&TpnkBRo5&i|i@=Ks6K|2a1h8LMot&*0j%a#nWoY)8$d z`^nm5^5p8udXVflw?wi_#Z=B^5E|4f_^BuH%&w;j^usFg*z3Y7ri^yIM!MEZ$vR_9 zD*xoOM7si_ZVm6gw{mlw{OqXG$(d|EmCfgcDbAL%IU}9P7V_zADwiph3YozneD_*_ z5gi6Ftn~w|hx+kT_gBVYa$g)0O-*Kds;iGsm>d?9;8ikdaR;1OT*$y}#>i%h#TnRh%Km~|~;4on+Qu=53F4mPI){Qhr^19mGZDg#+;hlIM-*?3xn zZR517S2Ch)Jqk7cyj8SClixTNVM+>&%|WfdajIjxy7+Ndn^jnkmM*4>nL-gfqiiWx z%H`l1KV~1wWK-#4I+M?r(y3CW2+!k87}nq z^w8CIJw1f<4D|G@=)w50$`+X9aW9A-#BmH{wa7e{^C4=;Ty_t>W7{I=Oz6Efe)wEFGR0IW+YMU7^D| z6&|xU~CfMsRV=htI49gJ4yQ@(ujt^BfK~L|mhoX%{?vw?{zztGov%bcaHawAb_OqqR z#yENJ!*ZqKeZ7O`$#-x*W3`H$`TpPxXB1!!hqs1N^^JMwt#)AS|L;`(V;hM6JNi5H zZThQY--ta6w^4{F5SRjEl}ULb-_1az>31`r;L`&`aCA4jNQ3Sj7)lT3`e(`XSY<~T zAWB)%JDD&B6Km3AmF;zb4C2}0E(i!9rONGf%^ku>tX%`GQ4uLsZmU~XGL>K>EmN7V zY?BtFyHQa!v%;b|x4v?m%C z>y~3yM+G6tTO_km?=?l1}V|@K&!c@5MSss5Teh2U>F=U7Y zpNoxKwv9pF6lC$GOmiaKZsp%{E(zUtDF2qFYlPj8&7Q-&=g#ElJ%n}yTFwj2dL|7c zwD_e4B*yLqKGZ>t=gxH@RVxF+{Qs*->=((^s0*a}($HGct-sNE zZ&*acAR~;LXxuk!opaDeV+%C#7;?cF>Hoa_*2*1m@`0=8eZbc8KA$&k1hW4BDDMtk z*0|f(7NM9o0yXOxfrdCohPQ0S#6_9aoj5s12o!WqsBs6-F>`SYwGy#XHveWX9{=Y_UBly>f@b2Z6yW->%TO&6O zC(su(LoM(@gM;{s-K+iX2fy%L%VQ1j(hB_lpAxc6Ysic=ZMi(gdfnb_F7824->x~5 zMYC!!*Wb?f2rZmdGhbXduwAl*zT?2h@SelDJbIvrHn@{7VL|?5Q_V4^_q@%5lx3$E zw4~qcPxkXB?7e)N;lqC?49|%hAD}o4;?%(JH7k(^pT?nW)8#Z*(6X652WMY z?_;iP7Lxbg&lhsKWr4%_L~wzSl%FRPuzt@C2tx3B#sCzIvk=%u_F25-A$|0rvu6`q zS0ye?T)1m={mz|RR~?+%F}wR8;a$-FBha+zqq||gc;v*1#J;K7>DdE^rp@iXhE708 zm}ORpN&NM9Y@Xb-e%qFvTPN^U=}%1-q+6gShJF=w$C5!vq__+eSFIWw-?({V6>u-V zT(xS|`fXdcCK98QSB$RTH1hJxn;h(g$48oV+z3{?V1cf{goTIt#1VBW%nKj#S9vGM?7 zNX>Cyp=_>;PM0w7Hz=^!tEcCO5YC?cG7W!kg^|&-*Td5-n{OTG*>3#d4{y8+vs=Ml zijT73ZF*17oT@nh>rUtj;1&9W4x9ASrhhM$;RO>P~(i;#pZ9|c3%9Uf?O zuR_?i=j_j)?ccUz$I$~u|Jk!K6Ts&+xIk`NGC1;w^moaP^e1s->hQjqLw%}dUE=lB zzmO1`BhwEaoZ8C;3%C9q?Ag=v^2_P7XQBQyLx9F^0K=j<%r_d%V@UE|ro7h2o+Vb9 zay>dRy5+9B$5H%fQ0}1@A#vCCaVpEJr5G>SJ^d+_21_M_@)TUCcSb3lWgT^)2;)Cm zvc%}${nQ7SB#zGP+_Gh@k)a{+$nJv&j?Vt&R^Jt!G-(ZQGl1@|$=M469jw=CR7_T8X z`ZuYv1eRMCtK_J_%p z0p`yZ!;B2b|M`piy-0Yy7|n+&t9<;`wEt5DP-o1GZ@Q0sWYR`mL zmS<8d7SUr4r+*l)&$v>$3; z(DrLRPkYV5TUj$$Gr_+P*VLyK5kAL(o&A#y;Pwrg5 zeeK$TWOA&s&liXU&jAvkGkBXSdjZI6_^_5^!YXC>2n_1tv&RJ=`0i6_hI;4Hs3|WX zNiSOLWOGLF%}mdi;WJU#&ad)D={rwsQ?iI3pawx?tg_pV0G}TlG`nb}g~(b3q-f3D zd6j!%CjfEk5%ZNh_{Ah28=btlau1wC@k-vm4bGC_@V=g(?<=8oOREzIVLvLZgBu^J zxap2ym>GGL|I5h$e*ga#{p#4aV$a96#4gvqrF~4>qm65Qf^K_LY@con&~oSul*T%25aOzDzDvf-Mh> zY{AIDUR0&QG|VmgggYxo07y;&?*xJq)V=`~-}zP!x`*ghm4|d9=K3k(^c59QVbHj$ z@}Tn}yc;VG!%1I-%8X8qahynv3c+H_1tt<)@viril7SmjM}A9AHj6;xmyGgf&Z2$11)7E$m}RAZF`^?)z}`Wd9D z%KZRjqug`CnhC3>bS2lC0NWife;_C~R@v`~s7iP1P88-AvsAgy)@K4wUdoP{fPwP= zTC$($U)O(4|DgV;zDHlL->6>{`$_Ceu}{Swj_r?4#IDf(QTvYeb?sSgE%{gSCCDB& zY^pASc5-_>khppKwyk~qUFX1HVs>VB>L9#NKC3>#z3HuYb4H^7SNd;WTfG=S@y+~0 zfnoqQRWE7`7uaJ$pu<637ywktqgf_625MdP6#(iyliQrlN<21wWM&UN7_48R9z8OH zQs$EC1vx{A8~|6X@BvJ~(>p5YPo*j9ykbVbP{%NzaPZ(#o54 zQZT^^hNO&sb>#`2tl^Iskcn-R6Yxq6KwVRLTqid?~z|3M<9zWV0V^�bh2t5@lSZ_-o;&(t6o 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 I*qvqq0HZxJc>n+a From c9b9deaee2bfdd535bc8779106e02ab12114b0d7 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 15 Nov 2016 02:46:39 +0000 Subject: [PATCH 0994/1484] Make the VACUUM command about 9% faster by avoiding unnecessary calls to sqlite3BtreeMovetoUnpacked() while copying rowid tables. FossilOrigin-Name: 5ed0bd387699a0f3b477d4f3cfcb460a6a44cb84 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/insert.c | 10 +++++++++- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 53f9f991eb..59906c5d78 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\s8794\snew\stest\scases\sreceived\sfrom\sthe\sOSS-FUZZ\sproject. -D 2016-11-14T20:47:18.877 +C Make\sthe\sVACUUM\scommand\sabout\s9%\sfaster\sby\savoiding\sunnecessary\scalls\nto\ssqlite3BtreeMovetoUnpacked()\swhile\scopying\srowid\stables. +D 2016-11-15T02:46:39.239 F Makefile.in 6b572807415d3f0a379cebc9461416d8df4a12c8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc bb4d970894abbbe0e88d00aac29bd52af8bc95f4 @@ -349,7 +349,7 @@ F src/hash.c 63d0ee752a3b92d4695b2b1f5259c4621b2cfebd F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4 F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 -F src/insert.c d47f9b4f6b7137b886525f735628fed4ff181ea2 +F src/insert.c 0d6e59f9eea62db772eabc0f07901ec26fe01968 F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e F src/loadext.c 5d6642d141c07d366e43d359e94ec9de47add41d F src/main.c 694ac90557abdaa62151a6090670e107b0f2c2ab @@ -1534,7 +1534,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P c5dbc599b910c02a961675b12b273b8df6d29450 -R 16d589cbe0b8a973a94265be5011a399 +P 03f75a67c320f21192d721a8c34d49dea48ffdbb +R 8e81a23a0b0c79dacc7554a88cc14173 U drh -Z 2897265fcdd3b169958c85551506b7bd +Z deb6f2821ede2b99520e7ac64aa770e4 diff --git a/manifest.uuid b/manifest.uuid index c9d695165a..8dcb1cf916 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -03f75a67c320f21192d721a8c34d49dea48ffdbb \ No newline at end of file +5ed0bd387699a0f3b477d4f3cfcb460a6a44cb84 \ No newline at end of file diff --git a/src/insert.c b/src/insert.c index 151c7d746b..f7c7bed540 100644 --- a/src/insert.c +++ b/src/insert.c @@ -2117,6 +2117,7 @@ static int xferOptimization( sqlite3VdbeJumpHere(v, addr1); } if( HasRowid(pSrc) ){ + u8 insFlags; sqlite3OpenTable(pParse, iSrc, iDbSrc, pSrc, OP_OpenRead); emptySrcTest = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0); VdbeCoverage(v); if( pDest->iPKey>=0 ){ @@ -2133,9 +2134,16 @@ static int xferOptimization( assert( (pDest->tabFlags & TF_Autoincrement)==0 ); } sqlite3VdbeAddOp2(v, OP_RowData, iSrc, regData); + if( db->flags & SQLITE_Vacuum ){ + sqlite3VdbeAddOp3(v, OP_Last, iDest, 0, -1); + insFlags = OPFLAG_NCHANGE|OPFLAG_LASTROWID| + OPFLAG_APPEND|OPFLAG_USESEEKRESULT; + }else{ + insFlags = OPFLAG_NCHANGE|OPFLAG_LASTROWID|OPFLAG_APPEND; + } sqlite3VdbeAddOp4(v, OP_Insert, iDest, regData, regRowid, (char*)pDest, P4_TABLE); - sqlite3VdbeChangeP5(v, OPFLAG_NCHANGE|OPFLAG_LASTROWID|OPFLAG_APPEND); + sqlite3VdbeChangeP5(v, insFlags); sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1); VdbeCoverage(v); sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0); sqlite3VdbeAddOp2(v, OP_Close, iDest, 0); From d6ef5afe3f905596571041926a4dae18322e58f9 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 15 Nov 2016 04:00:24 +0000 Subject: [PATCH 0995/1484] Change the OP_Last opcode so that it is a no-op if the cursor is already pointing at the end of the b-tree. FossilOrigin-Name: 663473850c4274270445b3771911fa773a8c405f --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/btree.c | 4 ++++ src/btree.h | 1 + src/vdbe.c | 27 +++++++++++++++++++-------- 5 files changed, 33 insertions(+), 17 deletions(-) diff --git a/manifest b/manifest index 59906c5d78..ebd7485bf2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\sthe\sVACUUM\scommand\sabout\s9%\sfaster\sby\savoiding\sunnecessary\scalls\nto\ssqlite3BtreeMovetoUnpacked()\swhile\scopying\srowid\stables. -D 2016-11-15T02:46:39.239 +C Change\sthe\sOP_Last\sopcode\sso\sthat\sit\sis\sa\sno-op\sif\sthe\scursor\sis\salready\npointing\sat\sthe\send\sof\sthe\sb-tree. +D 2016-11-15T04:00:24.244 F Makefile.in 6b572807415d3f0a379cebc9461416d8df4a12c8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc bb4d970894abbbe0e88d00aac29bd52af8bc95f4 @@ -330,8 +330,8 @@ F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792 F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b F src/bitvec.c 3ee4c8b2c94ed3a7377256e18199e6ff5cf33f63 F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 -F src/btree.c cfe038d1844420caddfa0238d52b7b2102dda98b -F src/btree.h 630303068c82a359f6ddf202b205ae927721b090 +F src/btree.c a7ed407f879be72c94b81f965d552e51b54a971f +F src/btree.h 01ec45846fa177e929f01ee36a8e34337d653544 F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 F src/build.c 178f16698cbcb43402c343a9413fe22c99ffee21 F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 @@ -454,7 +454,7 @@ F src/update.c bb9854778bdbbbca55d7533e55058733bd3fefe3 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 3e2da6101888d073e79ecc6af5e0a2f70fa1e498 F src/vacuum.c 33c174b28886b2faf26e503b5a49a1c01a9b1c16 -F src/vdbe.c f1a8e5bf7747f2e731812804cb65d4d07d86862e +F src/vdbe.c e76ee960a2e6d099838173599ae2d0999dc3aa63 F src/vdbe.h c044be7050ac6bf596eecc6ab159f5dbc020a3b7 F src/vdbeInt.h 29b25318a0286c4b2599c0fbef6acf524398489a F src/vdbeapi.c 97129bec6b1553da50d8e73f523c278bda66d9f6 @@ -1534,7 +1534,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 03f75a67c320f21192d721a8c34d49dea48ffdbb -R 8e81a23a0b0c79dacc7554a88cc14173 +P 5ed0bd387699a0f3b477d4f3cfcb460a6a44cb84 +R 666875522a5a69f5f9bb179805474981 U drh -Z deb6f2821ede2b99520e7ac64aa770e4 +Z 3c6d6cf804e5301c81a1f9af34f5b4ed diff --git a/manifest.uuid b/manifest.uuid index 8dcb1cf916..53cf085748 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5ed0bd387699a0f3b477d4f3cfcb460a6a44cb84 \ No newline at end of file +663473850c4274270445b3771911fa773a8c405f \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 283f37b797..895e8009ed 100644 --- a/src/btree.c +++ b/src/btree.c @@ -4278,6 +4278,10 @@ int sqlite3BtreeCursorIsValid(BtCursor *pCur){ return pCur && pCur->eState==CURSOR_VALID; } #endif /* NDEBUG */ +int sqlite3BtreeCursorIsValidNN(BtCursor *pCur){ + assert( pCur!=0 ); + return pCur->eState==CURSOR_VALID; +} /* ** Return the value of the integer key or "rowid" for a table btree. diff --git a/src/btree.h b/src/btree.h index 8b421e4201..92cf443b21 100644 --- a/src/btree.h +++ b/src/btree.h @@ -310,6 +310,7 @@ int sqlite3HeaderSizeBtree(void); #ifndef NDEBUG int sqlite3BtreeCursorIsValid(BtCursor*); #endif +int sqlite3BtreeCursorIsValidNN(BtCursor*); #ifndef SQLITE_OMIT_BTREECOUNT int sqlite3BtreeCount(BtCursor *, i64 *); diff --git a/src/vdbe.c b/src/vdbe.c index 740e52fc90..9cf62f33bf 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -4799,6 +4799,13 @@ case OP_NullRow: { ** This opcode leaves the cursor configured to move in reverse order, ** from the end toward the beginning. In other words, the cursor is ** configured to use Prev, not Next. +** +** If P3 is -1, then the cursor is positioned at the end of the btree +** for the purpose of appending a new entry onto the btree. In that +** case P2 must be 0. It is assumed that the cursor is used only for +** appending and so if the cursor is valid, then the cursor must already +** be pointing at the end of the btree and so no changes are made to +** the cursor. */ case OP_Last: { /* jump */ VdbeCursor *pC; @@ -4812,18 +4819,22 @@ case OP_Last: { /* jump */ pCrsr = pC->uc.pCursor; res = 0; assert( pCrsr!=0 ); - rc = sqlite3BtreeLast(pCrsr, &res); - pC->nullRow = (u8)res; - pC->deferredMoveto = 0; - pC->cacheStatus = CACHE_STALE; pC->seekResult = pOp->p3; #ifdef SQLITE_DEBUG pC->seekOp = OP_Last; #endif - if( rc ) goto abort_due_to_error; - if( pOp->p2>0 ){ - VdbeBranchTaken(res!=0,2); - if( res ) goto jump_to_p2; + if( pOp->p3==0 || !sqlite3BtreeCursorIsValidNN(pCrsr) ){ + rc = sqlite3BtreeLast(pCrsr, &res); + pC->nullRow = (u8)res; + pC->deferredMoveto = 0; + pC->cacheStatus = CACHE_STALE; + if( rc ) goto abort_due_to_error; + if( pOp->p2>0 ){ + VdbeBranchTaken(res!=0,2); + if( res ) goto jump_to_p2; + } + }else{ + assert( pOp->p2==0 ); } break; } From ba6eb8769f4f22cbf0f0244e2d39ac887c85d935 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 15 Nov 2016 17:37:56 +0000 Subject: [PATCH 0996/1484] Experimental changes toward making snapshots serializable. FossilOrigin-Name: b6a81fa1fc1fb78a65894129851a4ec3986640de --- manifest | 17 ++++++++++------- manifest.uuid | 2 +- src/sqlite.h.in | 4 +++- src/wal.c | 5 +++++ 4 files changed, 19 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index ebd7485bf2..9c806b3a89 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sthe\sOP_Last\sopcode\sso\sthat\sit\sis\sa\sno-op\sif\sthe\scursor\sis\salready\npointing\sat\sthe\send\sof\sthe\sb-tree. -D 2016-11-15T04:00:24.244 +C Experimental\schanges\stoward\smaking\ssnapshots\sserializable. +D 2016-11-15T17:37:56.374 F Makefile.in 6b572807415d3f0a379cebc9461416d8df4a12c8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc bb4d970894abbbe0e88d00aac29bd52af8bc95f4 @@ -389,7 +389,7 @@ F src/resolve.c bb070cf5f23611c44ab7e4788803684e385fc3fb F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c 672b1af237ad257149fc5189f3277dcbca036eeb F src/shell.c f04e4af75c5517735397d060ed0b4a874104bb41 -F src/sqlite.h.in 803f7050f69b2eea573fac219f3c92582c096027 +F src/sqlite.h.in dfe8c1b4ac66635495ec9a6a7205fcb0f27f4451 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae F src/sqliteInt.h c471d791b10c0f2164c8b7a87adc338e703c09cc @@ -465,7 +465,7 @@ F src/vdbesort.c 91fda3909326860382b0ca8aa251e609c6a9d62c F src/vdbetrace.c 41963d5376f0349842b5fc4aaaaacd7d9cdc0834 F src/vtab.c e02cacb5c7ae742631edeb9ae9f53d399f093fd8 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 -F src/wal.c 7e8557314bcf867ffe3fff1d8ef2d207ace8e065 +F src/wal.c 88f8d8adcaecf6a225ae5098062fd151634fb672 F src/wal.h bf03a23da3100ab25e5c0363450233cfee09cfc2 F src/walker.c 91a6df7435827e41cff6bb7df50ea00934ee78b0 F src/where.c 952f76e7a03727480b274b66ca6641b1657cd591 @@ -1534,7 +1534,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 5ed0bd387699a0f3b477d4f3cfcb460a6a44cb84 -R 666875522a5a69f5f9bb179805474981 +P 663473850c4274270445b3771911fa773a8c405f +R 1784ed6bcadef61e22ad39533122ebea +T *branch * serializable-snapshot +T *sym-serializable-snapshot * +T -sym-trunk * U drh -Z 3c6d6cf804e5301c81a1f9af34f5b4ed +Z 8a16f1f47c269929c7f968ee35b8cb55 diff --git a/manifest.uuid b/manifest.uuid index 53cf085748..5e74943d27 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -663473850c4274270445b3771911fa773a8c405f \ No newline at end of file +b6a81fa1fc1fb78a65894129851a4ec3986640de \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index dd70407c1b..7987cfae5e 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -8283,7 +8283,9 @@ int sqlite3_system_errno(sqlite3*); ** to an historical snapshot (if possible). The destructor for ** sqlite3_snapshot objects is [sqlite3_snapshot_free()]. */ -typedef struct sqlite3_snapshot sqlite3_snapshot; +typedef struct sqlite3_snapshot { + unsigned char hidden[48]; +} sqlite3_snapshot; /* ** CAPI3REF: Record A Database Snapshot diff --git a/src/wal.c b/src/wal.c index d71ee81a51..669c428efa 100644 --- a/src/wal.c +++ b/src/wal.c @@ -3393,9 +3393,14 @@ int sqlite3WalHeapMemory(Wal *pWal){ int sqlite3WalSnapshotGet(Wal *pWal, sqlite3_snapshot **ppSnapshot){ int rc = SQLITE_OK; WalIndexHdr *pRet; + static const u32 aZero[4] = { 0, 0, 0, 0 }; assert( pWal->readLock>=0 && pWal->writeLock==0 ); + if( memcmp(&pWal->hdr.aFrameCksum[0],aZero,16)==0 ){ + *ppSnapshot = 0; + return SQLITE_ERROR; + } pRet = (WalIndexHdr*)sqlite3_malloc(sizeof(WalIndexHdr)); if( pRet==0 ){ rc = SQLITE_NOMEM_BKPT; From d2d69cc1fa930905ac2c15a20f7c34f909a61924 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 15 Nov 2016 21:17:13 +0000 Subject: [PATCH 0997/1484] Add a needed #include to speedtest1.c. FossilOrigin-Name: 77aeb705c37b1bf61a05b5e4a09f5b5cd67d07bc --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/speedtest1.c | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index ebd7485bf2..89b610db7e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sthe\sOP_Last\sopcode\sso\sthat\sit\sis\sa\sno-op\sif\sthe\scursor\sis\salready\npointing\sat\sthe\send\sof\sthe\sb-tree. -D 2016-11-15T04:00:24.244 +C Add\sa\sneeded\s#include\sto\sspeedtest1.c. +D 2016-11-15T21:17:13.322 F Makefile.in 6b572807415d3f0a379cebc9461416d8df4a12c8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc bb4d970894abbbe0e88d00aac29bd52af8bc95f4 @@ -1120,7 +1120,7 @@ F test/speed3.test 694affeb9100526007436334cf7d08f3d74b85ef F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715 F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b -F test/speedtest1.c 48d82e01bd475d288460368497ad55a37f1bf659 +F test/speedtest1.c 2699cdb3c04cdaa44f47bf3cb0b720d8c52883e6 F test/spellfix.test f9c1f431e2c096c8775fec032952320c0e4700db F test/spellfix2.test dfc8f519a3fc204cb2dfa8b4f29821ae90f6f8c3 F test/spellfix3.test 0f9efaaa502a0e0a09848028518a6fb096c8ad33 @@ -1534,7 +1534,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 5ed0bd387699a0f3b477d4f3cfcb460a6a44cb84 -R 666875522a5a69f5f9bb179805474981 +P 663473850c4274270445b3771911fa773a8c405f +R f5b4a03f1eb13dfd7b1d8f8050241f6c U drh -Z 3c6d6cf804e5301c81a1f9af34f5b4ed +Z 74cbdb3d405329420299a0b66fca7782 diff --git a/manifest.uuid b/manifest.uuid index 53cf085748..fd2e5151f8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -663473850c4274270445b3771911fa773a8c405f \ No newline at end of file +77aeb705c37b1bf61a05b5e4a09f5b5cd67d07bc \ No newline at end of file diff --git a/test/speedtest1.c b/test/speedtest1.c index 48d13b66c7..2a744380dd 100644 --- a/test/speedtest1.c +++ b/test/speedtest1.c @@ -49,6 +49,7 @@ static const char zHelp[] = #include #include #include +#include #define ISSPACE(X) isspace((unsigned char)(X)) #define ISDIGIT(X) isdigit((unsigned char)(X)) From 54cda4edbee1febc11e4c7ae0eb56ad5b2253a68 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 17 Nov 2016 13:13:25 +0000 Subject: [PATCH 0998/1484] Disable the query flattener optimization for SELECT statements that are on the RHS of vector IN operators. This is a hack that fixes the bug described in ticket [da7841375186386c]. A better solution that does not disable the query flattener is needed, but this will server for the time being. FossilOrigin-Name: 005d5b870625d175fdf3c0e87d974006c569d9e1 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/wherecode.c | 3 +++ test/rowvalue3.test | 14 ++++++++++++++ 4 files changed, 25 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 89b610db7e..110e1a1a71 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sa\sneeded\s#include\sto\sspeedtest1.c. -D 2016-11-15T21:17:13.322 +C Disable\sthe\squery\sflattener\soptimization\sfor\sSELECT\sstatements\sthat\sare\son\nthe\sRHS\sof\svector\sIN\soperators.\s\sThis\sis\sa\shack\sthat\sfixes\sthe\sbug\ndescribed\sin\sticket\s[da7841375186386c].\sA\sbetter\ssolution\sthat\sdoes\snot\ndisable\sthe\squery\sflattener\sis\sneeded,\sbut\sthis\swill\sserver\sfor\sthe\stime\nbeing. +D 2016-11-17T13:13:25.555 F Makefile.in 6b572807415d3f0a379cebc9461416d8df4a12c8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc bb4d970894abbbe0e88d00aac29bd52af8bc95f4 @@ -470,7 +470,7 @@ F src/wal.h bf03a23da3100ab25e5c0363450233cfee09cfc2 F src/walker.c 91a6df7435827e41cff6bb7df50ea00934ee78b0 F src/where.c 952f76e7a03727480b274b66ca6641b1657cd591 F src/whereInt.h 2bcc3d176e6091cb8f50a30b65c006e88a73614d -F src/wherecode.c 507738d957dcc3cfa93020bcc1e4b02d11ecab9e +F src/wherecode.c 4ea298998499db5a407ffd70e87e119a86ed7834 F src/whereexpr.c a83d70154f3bbce5051a7e9710021f647c0fe4f2 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -1033,7 +1033,7 @@ F test/rowhash.test 0bc1d31415e4575d10cacf31e1a66b5cc0f8be81 F test/rowid.test 5b7509f384f4f6fae1af3c8c104c8ca299fea18d F test/rowvalue.test b5a9c0fa347a763c558da2397499df51da3cdf6b F test/rowvalue2.test 060d238b7e5639a7c5630cb5e63e311b44efef2b -F test/rowvalue3.test 01399b7bf150b0d41abce76c18072da777c2500c +F test/rowvalue3.test 3068f508753af69884b12125995f023da0dbb256 F test/rowvalue4.test 4b556d7de161a0dd8cff095c336e913986398bea F test/rowvalue5.test c81c7d8cf36711ab37675ad7376084ae2a359cb6 F test/rowvalue6.test d19b54feb604d5601f8614b15e214e0774c01087 @@ -1534,7 +1534,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 663473850c4274270445b3771911fa773a8c405f -R f5b4a03f1eb13dfd7b1d8f8050241f6c +P 77aeb705c37b1bf61a05b5e4a09f5b5cd67d07bc +R fd152d0bb86ce30d6ad75d12d28ac69c U drh -Z 74cbdb3d405329420299a0b66fca7782 +Z 0a052b186d2930619fca6146d580a03f diff --git a/manifest.uuid b/manifest.uuid index fd2e5151f8..fd192eeffd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -77aeb705c37b1bf61a05b5e4a09f5b5cd67d07bc \ No newline at end of file +005d5b870625d175fdf3c0e87d974006c569d9e1 \ No newline at end of file diff --git a/src/wherecode.c b/src/wherecode.c index d547a71179..9a4961d293 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -446,6 +446,7 @@ static int codeEqualityTerm( }else{ Select *pSelect = pX->x.pSelect; sqlite3 *db = pParse->db; + u16 savedDbOptFlags = db->dbOptFlags; ExprList *pOrigRhs = pSelect->pEList; ExprList *pOrigLhs = pX->pLeft->x.pList; ExprList *pRhs = 0; /* New Select.pEList for RHS */ @@ -489,7 +490,9 @@ static int codeEqualityTerm( testcase( aiMap==0 ); } pSelect->pEList = pRhs; + db->dbOptFlags |= SQLITE_QueryFlattener; eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap); + db->dbOptFlags = savedDbOptFlags; testcase( aiMap!=0 && aiMap[0]!=0 ); pSelect->pEList = pOrigRhs; pLeft->x.pList = pOrigLhs; diff --git a/test/rowvalue3.test b/test/rowvalue3.test index b050e70dde..988eea9008 100644 --- a/test/rowvalue3.test +++ b/test/rowvalue3.test @@ -202,5 +202,19 @@ foreach {tn idx} { #------------------------------------------------------------------------- +# 2016-11-17. Query flattening in a vector SELECT on the RHS of an IN +# operator. Ticket https://www.sqlite.org/src/info/da7841375186386c +# +do_execsql_test 5.0 { + DROP TABLE IF EXISTS t1; + DROP TABLE IF EXISTS t2; + CREATE TABLE T1(a TEXT); + INSERT INTO T1(a) VALUES ('aaa'); + CREATE TABLE T2(a TEXT PRIMARY KEY,n INT); + INSERT INTO T2(a, n) VALUES('aaa',0); + SELECT * FROM T2 + WHERE (a,n) IN (SELECT T1.a, V.n FROM T1, (SELECT * FROM (SELECT 0 n)) V); +} {aaa 0} + finish_test From 223b4bb3f7cd9bfc78549f9c5b924ce0c2919fba Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 17 Nov 2016 13:54:21 +0000 Subject: [PATCH 0999/1484] Change the --enable-debug option on configure so that it enables the ".selecttrace" and ".wheretrace" commands in the command-line shell. FossilOrigin-Name: 2331192b4ca6a169b6ac0daafb21ceb7c390de65 --- configure | 3 +-- configure.ac | 2 +- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 10 insertions(+), 11 deletions(-) diff --git a/configure b/configure index 246b1bc63e..598b0dd7d9 100755 --- a/configure +++ b/configure @@ -11252,7 +11252,7 @@ else fi if test "${use_debug}" = "yes" ; then - TARGET_DEBUG="-DSQLITE_DEBUG=1" + TARGET_DEBUG="-DSQLITE_DEBUG=1 -DSQLITE_ENABLE_SELECTTRACE -DSQLITE_ENABLE_WHERETRACE" else TARGET_DEBUG="-DNDEBUG" fi @@ -13829,4 +13829,3 @@ if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi - diff --git a/configure.ac b/configure.ac index c9e3af9220..095db6bf81 100644 --- a/configure.ac +++ b/configure.ac @@ -560,7 +560,7 @@ AC_SEARCH_LIBS(fdatasync, [rt]) AC_ARG_ENABLE(debug, AC_HELP_STRING([--enable-debug],[enable debugging & verbose explain]), [use_debug=$enableval],[use_debug=no]) if test "${use_debug}" = "yes" ; then - TARGET_DEBUG="-DSQLITE_DEBUG=1" + TARGET_DEBUG="-DSQLITE_DEBUG=1 -DSQLITE_ENABLE_SELECTTRACE -DSQLITE_ENABLE_WHERETRACE" else TARGET_DEBUG="-DNDEBUG" fi diff --git a/manifest b/manifest index 110e1a1a71..38b8a4529b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Disable\sthe\squery\sflattener\soptimization\sfor\sSELECT\sstatements\sthat\sare\son\nthe\sRHS\sof\svector\sIN\soperators.\s\sThis\sis\sa\shack\sthat\sfixes\sthe\sbug\ndescribed\sin\sticket\s[da7841375186386c].\sA\sbetter\ssolution\sthat\sdoes\snot\ndisable\sthe\squery\sflattener\sis\sneeded,\sbut\sthis\swill\sserver\sfor\sthe\stime\nbeing. -D 2016-11-17T13:13:25.555 +C Change\sthe\s--enable-debug\soption\son\sconfigure\sso\sthat\sit\senables\sthe\n".selecttrace"\sand\s".wheretrace"\scommands\sin\sthe\scommand-line\sshell. +D 2016-11-17T13:54:21.139 F Makefile.in 6b572807415d3f0a379cebc9461416d8df4a12c8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc bb4d970894abbbe0e88d00aac29bd52af8bc95f4 @@ -30,8 +30,8 @@ F autoconf/tea/win/rules.vc c511f222b80064096b705dbeb97060ee1d6b6d63 F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977 F config.h.in 6376abec766e9a0785178b1823b5a587e9f1ccbc F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55 -F configure 1c4248006e233187bed6e6b890befec14f625637 x -F configure.ac b5d3df43161374f8dffd2e5f4b88fbb51685b975 +F configure adbf03e758431e886bba5ab04b5adfbd496d7b24 x +F configure.ac 605173e829ab64514ed89f9b53d0da1739d7b0a0 F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad F doc/lemon.html b5a3c07d33ecb8e019ce8f7660fe2dbbad9d7977 F doc/pager-invariants.txt 27fed9a70ddad2088750c4a2b493b63853da2710 @@ -1534,7 +1534,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 77aeb705c37b1bf61a05b5e4a09f5b5cd67d07bc -R fd152d0bb86ce30d6ad75d12d28ac69c +P 005d5b870625d175fdf3c0e87d974006c569d9e1 +R c068ae8a47d20415894fb1f98ce1114d U drh -Z 0a052b186d2930619fca6146d580a03f +Z 18e3715bfdc10f86213a4f9bab0304db diff --git a/manifest.uuid b/manifest.uuid index fd192eeffd..33b576ead7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -005d5b870625d175fdf3c0e87d974006c569d9e1 \ No newline at end of file +2331192b4ca6a169b6ac0daafb21ceb7c390de65 \ No newline at end of file From 9c8753c0a8cf5255e479d45c2ac66db5f61a2acb Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 17 Nov 2016 20:05:00 +0000 Subject: [PATCH 1000/1484] Fix a problem in rtreeD.test causing it to fail in OMIT_BUILTIN_TEST builds. FossilOrigin-Name: d6b3779e6dad038d8bc35139cf314bf1e6e91977 --- ext/rtree/rtreeD.test | 2 +- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/ext/rtree/rtreeD.test b/ext/rtree/rtreeD.test index c4a7d22e2e..d846fc61ff 100644 --- a/ext/rtree/rtreeD.test +++ b/ext/rtree/rtreeD.test @@ -19,7 +19,7 @@ if {![info exists testdir]} { source [file join [file dirname [info script]] rtree_util.tcl] source $testdir/tester.tcl source $testdir/lock_common.tcl -ifcapable !rtree { +ifcapable !rtree||!builtin_test { finish_test return } diff --git a/manifest b/manifest index 38b8a4529b..f1ad21a433 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sthe\s--enable-debug\soption\son\sconfigure\sso\sthat\sit\senables\sthe\n".selecttrace"\sand\s".wheretrace"\scommands\sin\sthe\scommand-line\sshell. -D 2016-11-17T13:54:21.139 +C Fix\sa\sproblem\sin\srtreeD.test\scausing\sit\sto\sfail\sin\sOMIT_BUILTIN_TEST\sbuilds. +D 2016-11-17T20:05:00.694 F Makefile.in 6b572807415d3f0a379cebc9461416d8df4a12c8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc bb4d970894abbbe0e88d00aac29bd52af8bc95f4 @@ -274,7 +274,7 @@ F ext/rtree/rtree9.test b5eb13849545dfd271a54ff16784cb00d8792aea F ext/rtree/rtreeA.test ace05e729a36e342d40cf94e9efc7b4723d9dcdf F ext/rtree/rtreeB.test c85f9ce78766c4e68b8b89fbf2979ee9cfa82b4e F ext/rtree/rtreeC.test c0a9c67f2efa98b6fae12acb8a28348d231a481d -F ext/rtree/rtreeD.test 636630357638f5983701550b37f0f5867130d2ca +F ext/rtree/rtreeD.test bdfaaf26df8b4eea7364039aca9150bc1e1f8825 F ext/rtree/rtreeE.test 45a147a64a76306172819562309681d8e90f94bb F ext/rtree/rtreeF.test 66deb9fd1611c7ca2e374adba63debdc2dbb12b4 F ext/rtree/rtreeG.test 3b185719630795f38594f64cd7d1de86a33f91f1 @@ -1534,7 +1534,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 005d5b870625d175fdf3c0e87d974006c569d9e1 -R c068ae8a47d20415894fb1f98ce1114d -U drh -Z 18e3715bfdc10f86213a4f9bab0304db +P 2331192b4ca6a169b6ac0daafb21ceb7c390de65 +R 252cde6585f71191b31af3499dd16889 +U dan +Z 3bd9299c3f417af0dbc0173ca4fc27e5 diff --git a/manifest.uuid b/manifest.uuid index 33b576ead7..19168176ad 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2331192b4ca6a169b6ac0daafb21ceb7c390de65 \ No newline at end of file +d6b3779e6dad038d8bc35139cf314bf1e6e91977 \ No newline at end of file From 65e1ba3fe751f92efcd921dd85aadce658907fbf Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 17 Nov 2016 21:52:08 +0000 Subject: [PATCH 1001/1484] Experimental changes for faster in-memory DB operation for large databases. FossilOrigin-Name: 4fe94b0f1841180dfd8cac33838e335dc6a428bf --- manifest | 15 +++++++++------ manifest.uuid | 2 +- src/pager.c | 2 +- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 38b8a4529b..4a83e54278 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sthe\s--enable-debug\soption\son\sconfigure\sso\sthat\sit\senables\sthe\n".selecttrace"\sand\s".wheretrace"\scommands\sin\sthe\scommand-line\sshell. -D 2016-11-17T13:54:21.139 +C Experimental\schanges\sfor\sfaster\sin-memory\sDB\soperation\sfor\slarge\sdatabases. +D 2016-11-17T21:52:08.779 F Makefile.in 6b572807415d3f0a379cebc9461416d8df4a12c8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc bb4d970894abbbe0e88d00aac29bd52af8bc95f4 @@ -374,7 +374,7 @@ F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586 F src/os_unix.c be9ca0f901a2b6c1bc93dc338f4863675180c189 F src/os_win.c cf90abd4e50d9f56d2c20ce8e005aff55d7bd8e9 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a -F src/pager.c a31e2c25563065ebfc9308f2ba3a061901fd60a8 +F src/pager.c eca40c57a4f35ed9609fa094573077adc99278c1 F src/pager.h 07d6938df0b74e4abe8f57807a8b0e1084321d8b F src/parse.y 0338f906b61e311c2b7e11a3f89b0092c780b664 F src/pcache.c 5ff2a08f76a9c1b22f43eb063b7068fb085465ac @@ -1534,7 +1534,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 005d5b870625d175fdf3c0e87d974006c569d9e1 -R c068ae8a47d20415894fb1f98ce1114d +P 2331192b4ca6a169b6ac0daafb21ceb7c390de65 +R 0286645640a2da4eb8b13e6d6f145f5c +T *branch * memdb-opt +T *sym-memdb-opt * +T -sym-trunk * U drh -Z 18e3715bfdc10f86213a4f9bab0304db +Z d8145835471c7af9153066b699da469e diff --git a/manifest.uuid b/manifest.uuid index 33b576ead7..831b681562 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2331192b4ca6a169b6ac0daafb21ceb7c390de65 \ No newline at end of file +4fe94b0f1841180dfd8cac33838e335dc6a428bf \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index 04ce19547b..91cba7d767 100644 --- a/src/pager.c +++ b/src/pager.c @@ -2038,7 +2038,7 @@ static int pager_end_transaction(Pager *pPager, int hasMaster, int bCommit){ pPager->pInJournal = 0; pPager->nRec = 0; if( rc==SQLITE_OK ){ - if( pagerFlushOnCommit(pPager, bCommit) ){ + if( MEMDB || pagerFlushOnCommit(pPager, bCommit) ){ sqlite3PcacheCleanAll(pPager->pPCache); }else{ sqlite3PcacheClearWritable(pPager->pPCache); From 25accbca7234545ce9d665a1f5672ab0bf04d38a Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 18 Nov 2016 14:38:41 +0000 Subject: [PATCH 1002/1484] Enhance existing snapshot tests to serialize/deserialize snapshots. No new tests. FossilOrigin-Name: 16b9bf92741e4c62874cffd7c6a61763c5054c7a --- manifest | 19 +- manifest.uuid | 2 +- src/test1.c | 110 +++++++ test/snapshot.test | 779 +++++++++++++++++++++++---------------------- 4 files changed, 526 insertions(+), 384 deletions(-) diff --git a/manifest b/manifest index 9c806b3a89..c5597fb646 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Experimental\schanges\stoward\smaking\ssnapshots\sserializable. -D 2016-11-15T17:37:56.374 +C Enhance\sexisting\ssnapshot\stests\sto\sserialize/deserialize\ssnapshots.\sNo\snew\ntests. +D 2016-11-18T14:38:41.852 F Makefile.in 6b572807415d3f0a379cebc9461416d8df4a12c8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc bb4d970894abbbe0e88d00aac29bd52af8bc95f4 @@ -397,7 +397,7 @@ F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 F src/tclsqlite.c aef87dcd8cb66564d560ab48d43d19ac812a1eab -F src/test1.c f52bed152c97be23be794efa234374d0de593eeb +F src/test1.c 58de30ed902f78531cf5cf52b883a26d107208c4 F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5 F src/test3.c d03f5b5da9a2410b7a91c64b0d3306ed28ab6fee F src/test4.c 18ec393bb4d0ad1de729f0b94da7267270f3d8e6 @@ -1102,7 +1102,7 @@ F test/skipscan2.test d1d1450952b7275f0b0a3a981f0230532743951a F test/skipscan3.test ec5bab3f81c7038b43450e7b3062e04a198bdbb5 F test/skipscan5.test 67817a4b6857c47e0e33ba3e506da6f23ef68de2 F test/skipscan6.test 5866039d03a56f5bd0b3d172a012074a1d90a15b -F test/snapshot.test a19465046168b4420b5afeed37c3214e42a49f4a +F test/snapshot.test bb34cc38828bf2e86a49207995fa7dfacd303832 F test/snapshot_fault.test 062ff0438a074978d45e9f9a92e7ad459b74ee73 F test/soak.test 0b5b6375c9f4110c828070b826b3b4b0bb65cd5f F test/softheap1.test 843cd84db9891b2d01b9ab64cef3e9020f98d087 @@ -1534,10 +1534,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 663473850c4274270445b3771911fa773a8c405f -R 1784ed6bcadef61e22ad39533122ebea -T *branch * serializable-snapshot -T *sym-serializable-snapshot * -T -sym-trunk * -U drh -Z 8a16f1f47c269929c7f968ee35b8cb55 +P b6a81fa1fc1fb78a65894129851a4ec3986640de +R 17ac6d49deba8d40db4fa5f6ce7fc2ca +U dan +Z cee5f11eb9093786088be3369dcd2153 diff --git a/manifest.uuid b/manifest.uuid index 5e74943d27..6af23f5732 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b6a81fa1fc1fb78a65894129851a4ec3986640de \ No newline at end of file +16b9bf92741e4c62874cffd7c6a61763c5054c7a \ No newline at end of file diff --git a/src/test1.c b/src/test1.c index 18b6b295c2..e31ad95f40 100644 --- a/src/test1.c +++ b/src/test1.c @@ -2388,6 +2388,113 @@ static int SQLITE_TCLAPI test_snapshot_cmp( } #endif /* SQLITE_ENABLE_SNAPSHOT */ +#ifdef SQLITE_ENABLE_SNAPSHOT +/* +** Usage: sqlite3_snapshot_get_blob DB DBNAME +*/ +static int SQLITE_TCLAPI test_snapshot_get_blob( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + int rc; + sqlite3 *db; + char *zName; + sqlite3_snapshot *pSnapshot = 0; + + if( objc!=3 ){ + Tcl_WrongNumArgs(interp, 1, objv, "DB DBNAME"); + return TCL_ERROR; + } + if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; + zName = Tcl_GetString(objv[2]); + + rc = sqlite3_snapshot_get(db, zName, &pSnapshot); + if( rc!=SQLITE_OK ){ + Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1)); + return TCL_ERROR; + }else{ + Tcl_SetObjResult(interp, + Tcl_NewByteArrayObj((unsigned char*)pSnapshot, sizeof(sqlite3_snapshot)) + ); + sqlite3_snapshot_free(pSnapshot); + } + return TCL_OK; +} +#endif /* SQLITE_ENABLE_SNAPSHOT */ + +#ifdef SQLITE_ENABLE_SNAPSHOT + /* + ** Usage: sqlite3_snapshot_open_blob DB DBNAME SNAPSHOT +*/ +static int SQLITE_TCLAPI test_snapshot_open_blob( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + int rc; + sqlite3 *db; + char *zName; + unsigned char *pBlob; + int nBlob; + + if( objc!=4 ){ + Tcl_WrongNumArgs(interp, 1, objv, "DB DBNAME SNAPSHOT"); + return TCL_ERROR; + } + if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; + zName = Tcl_GetString(objv[2]); + pBlob = Tcl_GetByteArrayFromObj(objv[3], &nBlob); + if( nBlob!=sizeof(sqlite3_snapshot) ){ + Tcl_AppendResult(interp, "bad SNAPSHOT", 0); + return TCL_ERROR; + } + rc = sqlite3_snapshot_open(db, zName, (sqlite3_snapshot*)pBlob); + if( rc!=SQLITE_OK ){ + Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1)); + return TCL_ERROR; + } + return TCL_OK; +} +#endif /* SQLITE_ENABLE_SNAPSHOT */ + +#ifdef SQLITE_ENABLE_SNAPSHOT +/* +** Usage: sqlite3_snapshot_cmp_blob SNAPSHOT1 SNAPSHOT2 +*/ +static int SQLITE_TCLAPI test_snapshot_cmp_blob( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + int res; + unsigned char *p1; + unsigned char *p2; + int n1; + int n2; + + if( objc!=3 ){ + Tcl_WrongNumArgs(interp, 1, objv, "SNAPSHOT1 SNAPSHOT2"); + return TCL_ERROR; + } + + p1 = Tcl_GetByteArrayFromObj(objv[1], &n1); + p2 = Tcl_GetByteArrayFromObj(objv[2], &n2); + + if( n1!=sizeof(sqlite3_snapshot) || n1!=n2 ){ + Tcl_AppendResult(interp, "bad SNAPSHOT", 0); + return TCL_ERROR; + } + + res = sqlite3_snapshot_cmp((sqlite3_snapshot*)p1, (sqlite3_snapshot*)p2); + Tcl_SetObjResult(interp, Tcl_NewIntObj(res)); + return TCL_OK; +} +#endif /* SQLITE_ENABLE_SNAPSHOT */ + /* ** Usage: sqlite3_delete_database FILENAME */ @@ -7539,6 +7646,9 @@ int Sqlitetest1_Init(Tcl_Interp *interp){ { "sqlite3_snapshot_open", test_snapshot_open, 0 }, { "sqlite3_snapshot_free", test_snapshot_free, 0 }, { "sqlite3_snapshot_cmp", test_snapshot_cmp, 0 }, + { "sqlite3_snapshot_get_blob", test_snapshot_get_blob, 0 }, + { "sqlite3_snapshot_open_blob", test_snapshot_open_blob, 0 }, + { "sqlite3_snapshot_cmp_blob", test_snapshot_cmp_blob, 0 }, #endif { "sqlite3_delete_database", test_delete_database, 0 }, }; diff --git a/test/snapshot.test b/test/snapshot.test index b2d61941a7..1143c14962 100644 --- a/test/snapshot.test +++ b/test/snapshot.test @@ -26,413 +26,448 @@ if {[permutation]=="inmemory_journal"} { return } -#------------------------------------------------------------------------- -# Check some error conditions in snapshot_get(). It is an error if: -# -# 1) snapshot_get() is called on a non-WAL database, or -# 2) there is an open write transaction on the database. -# -do_execsql_test 1.0 { - CREATE TABLE t1(a, b); - INSERT INTO t1 VALUES(1, 2); - INSERT INTO t1 VALUES(3, 4); -} - -do_test 1.1.1 { - execsql { BEGIN; SELECT * FROM t1; } - list [catch { sqlite3_snapshot_get db main } msg] $msg -} {1 SQLITE_ERROR} -do_execsql_test 1.1.2 COMMIT - -do_test 1.2.1 { - execsql { - PRAGMA journal_mode = WAL; - BEGIN; - INSERT INTO t1 VALUES(5, 6); - INSERT INTO t1 VALUES(7, 8); +foreach {tn tcl} { + 1 { + proc snapshot_get {DB DBNAME} { + uplevel [list sqlite3_snapshot_get $DB $DBNAME] + } + proc snapshot_open {DB DBNAME SNAPSHOT} { + uplevel [list sqlite3_snapshot_open $DB $DBNAME $SNAPSHOT] + } + proc snapshot_free {SNAPSHOT} { + uplevel [list sqlite3_snapshot_free $SNAPSHOT] + } + proc snapshot_cmp {SNAPSHOT1 SNAPSHOT2} { + uplevel [list sqlite3_snapshot_cmp $SNAPSHOT1 $SNAPSHOT2] + } } - list [catch { sqlite3_snapshot_get db main } msg] $msg -} {1 SQLITE_ERROR} -do_execsql_test 1.3.2 COMMIT -#------------------------------------------------------------------------- -# Check that a simple case works. Reuse the database created by the -# block of tests above. -# -do_execsql_test 2.1.0 { - BEGIN; - SELECT * FROM t1; -} {1 2 3 4 5 6 7 8} - -do_test 2.1.1 { - set snapshot [sqlite3_snapshot_get db main] - execsql { - COMMIT; - INSERT INTO t1 VALUES(9, 10); - SELECT * FROM t1; + 2 { + proc snapshot_get {DB DBNAME} { + uplevel [list sqlite3_snapshot_get_blob $DB $DBNAME] + } + proc snapshot_open {DB DBNAME SNAPSHOT} { + uplevel [list sqlite3_snapshot_open_blob $DB $DBNAME $SNAPSHOT] + } + proc snapshot_free {SNAPSHOT} { + } + proc snapshot_cmp {SNAPSHOT1 SNAPSHOT2} { + uplevel [list sqlite3_snapshot_cmp_blob $SNAPSHOT1 $SNAPSHOT2] + } } -} {1 2 3 4 5 6 7 8 9 10} +} { -do_test 2.1.2 { - execsql BEGIN - sqlite3_snapshot_open db main $snapshot - execsql { - SELECT * FROM t1; + reset_db + eval $tcl + + #------------------------------------------------------------------------- + # Check some error conditions in snapshot_get(). It is an error if: + # + # 1) snapshot_get() is called on a non-WAL database, or + # 2) there is an open write transaction on the database. + # + do_execsql_test $tn.1.0 { + CREATE TABLE t1(a, b); + INSERT INTO t1 VALUES(1, 2); + INSERT INTO t1 VALUES(3, 4); } -} {1 2 3 4 5 6 7 8} -do_test 2.1.3 { - sqlite3_snapshot_free $snapshot - execsql COMMIT -} {} + do_test $tn.1.1.1 { + execsql { BEGIN; SELECT * FROM t1; } + list [catch { snapshot_get db main } msg] $msg + } {1 SQLITE_ERROR} + do_execsql_test 1.1.2 COMMIT -do_test 2.2.0 { - sqlite3 db2 test.db - execsql { + do_test $tn.1.2.1 { + execsql { + PRAGMA journal_mode = WAL; + BEGIN; + INSERT INTO t1 VALUES(5, 6); + INSERT INTO t1 VALUES(7, 8); + } + list [catch { snapshot_get db main } msg] $msg + } {1 SQLITE_ERROR} + do_execsql_test $tn.1.3.2 COMMIT + + #------------------------------------------------------------------------- + # Check that a simple case works. Reuse the database created by the + # block of tests above. + # + do_execsql_test $tn.2.1.0 { BEGIN; SELECT * FROM t1; - } db2 -} {1 2 3 4 5 6 7 8 9 10} + } {1 2 3 4 5 6 7 8} -do_test 2.2.1 { - set snapshot [sqlite3_snapshot_get db2 main] - execsql { - INSERT INTO t1 VALUES(11, 12); - SELECT * FROM t1; - } -} {1 2 3 4 5 6 7 8 9 10 11 12} + do_test $tn.2.1.1 { + set snapshot [snapshot_get db main] + execsql { + COMMIT; + INSERT INTO t1 VALUES(9, 10); + SELECT * FROM t1; + } + } {1 2 3 4 5 6 7 8 9 10} -do_test 2.2.2 { - execsql BEGIN - sqlite3_snapshot_open db main $snapshot - execsql { - SELECT * FROM t1; - } -} {1 2 3 4 5 6 7 8 9 10} + do_test $tn.2.1.2 { + execsql BEGIN + snapshot_open db main $snapshot + execsql { + SELECT * FROM t1; + } + } {1 2 3 4 5 6 7 8} -do_test 2.2.3 { - sqlite3_snapshot_free $snapshot - execsql COMMIT - execsql COMMIT db2 - db2 close -} {} + do_test $tn.2.1.3 { + snapshot_free $snapshot + execsql COMMIT + } {} -do_test 2.3.1 { - execsql { DELETE FROM t1 WHERE a>6 } - set snapshot [sqlite3_snapshot_get db main] - execsql { - INSERT INTO t1 VALUES('a', 'b'); - INSERT INTO t1 VALUES('c', 'd'); - SELECT * FROM t1; - } -} {1 2 3 4 5 6 a b c d} -do_test 2.3.2 { - execsql BEGIN - sqlite3_snapshot_open db main $snapshot - execsql { SELECT * FROM t1 } -} {1 2 3 4 5 6} + do_test $tn.2.2.0 { + sqlite3 db2 test.db + execsql { + BEGIN; + SELECT * FROM t1; + } db2 + } {1 2 3 4 5 6 7 8 9 10} -do_test 2.3.3 { - catchsql { - INSERT INTO t1 VALUES('x','y') - } -} {1 {database is locked}} -do_test 2.3.4 { - execsql COMMIT - sqlite3_snapshot_free $snapshot -} {} + do_test $tn.2.2.1 { + set snapshot [snapshot_get db2 main] + execsql { + INSERT INTO t1 VALUES(11, 12); + SELECT * FROM t1; + } + } {1 2 3 4 5 6 7 8 9 10 11 12} -#------------------------------------------------------------------------- -# Check some errors in sqlite3_snapshot_open(). It is an error if: -# -# 1) the db is in auto-commit mode, -# 2) the db has an open (read or write) transaction, -# 3) the db is not a wal database, -# -# Reuse the database created by earlier tests. -# -do_execsql_test 3.0.0 { - CREATE TABLE t2(x, y); - INSERT INTO t2 VALUES('a', 'b'); - INSERT INTO t2 VALUES('c', 'd'); - BEGIN; - SELECT * FROM t2; -} {a b c d} -do_test 3.0.1 { - set snapshot [sqlite3_snapshot_get db main] - execsql { COMMIT } - execsql { INSERT INTO t2 VALUES('e', 'f'); } -} {} + do_test $tn.2.2.2 { + execsql BEGIN + snapshot_open db main $snapshot + execsql { + SELECT * FROM t1; + } + } {1 2 3 4 5 6 7 8 9 10} -do_test 3.1 { - list [catch {sqlite3_snapshot_open db main $snapshot } msg] $msg -} {1 SQLITE_ERROR} + do_test $tn.2.2.3 { + snapshot_free $snapshot + execsql COMMIT + execsql COMMIT db2 + db2 close + } {} -do_test 3.2.1 { - execsql { + do_test $tn.2.3.1 { + execsql { DELETE FROM t1 WHERE a>6 } + set snapshot [snapshot_get db main] + execsql { + INSERT INTO t1 VALUES('a', 'b'); + INSERT INTO t1 VALUES('c', 'd'); + SELECT * FROM t1; + } + } {1 2 3 4 5 6 a b c d} + do_test $tn.2.3.2 { + execsql BEGIN + snapshot_open db main $snapshot + execsql { SELECT * FROM t1 } + } {1 2 3 4 5 6} + + do_test $tn.2.3.3 { + catchsql { + INSERT INTO t1 VALUES('x','y') + } + } {1 {database is locked}} + do_test $tn.2.3.4 { + execsql COMMIT + snapshot_free $snapshot + } {} + + #------------------------------------------------------------------------- + # Check some errors in snapshot_open(). It is an error if: + # + # 1) the db is in auto-commit mode, + # 2) the db has an open (read or write) transaction, + # 3) the db is not a wal database, + # + # Reuse the database created by earlier tests. + # + do_execsql_test $tn.3.0.0 { + CREATE TABLE t2(x, y); + INSERT INTO t2 VALUES('a', 'b'); + INSERT INTO t2 VALUES('c', 'd'); BEGIN; SELECT * FROM t2; - } -} {a b c d e f} -do_test 3.2.2 { - list [catch {sqlite3_snapshot_open db main $snapshot } msg] $msg -} {1 SQLITE_ERROR} + } {a b c d} + do_test $tn.3.0.1 { + set snapshot [snapshot_get db main] + execsql { COMMIT } + execsql { INSERT INTO t2 VALUES('e', 'f'); } + } {} -do_test 3.2.3 { - execsql { - COMMIT; - BEGIN; - INSERT INTO t2 VALUES('g', 'h'); - } - list [catch {sqlite3_snapshot_open db main $snapshot } msg] $msg -} {1 SQLITE_ERROR} -do_execsql_test 3.2.4 COMMIT + do_test $tn.3.1 { + list [catch {snapshot_open db main $snapshot } msg] $msg + } {1 SQLITE_ERROR} -do_test 3.3.1 { - execsql { PRAGMA journal_mode = DELETE } - execsql { BEGIN } - list [catch {sqlite3_snapshot_open db main $snapshot } msg] $msg -} {1 SQLITE_ERROR} + do_test $tn.3.2.1 { + execsql { + BEGIN; + SELECT * FROM t2; + } + } {a b c d e f} + do_test $tn.3.2.2 { + list [catch {snapshot_open db main $snapshot } msg] $msg + } {1 SQLITE_ERROR} -do_test 3.3.2 { - sqlite3_snapshot_free $snapshot - execsql COMMIT -} {} + do_test $tn.3.2.3 { + execsql { + COMMIT; + BEGIN; + INSERT INTO t2 VALUES('g', 'h'); + } + list [catch {snapshot_open db main $snapshot } msg] $msg + } {1 SQLITE_ERROR} + do_execsql_test 3.2.4 COMMIT -#------------------------------------------------------------------------- -# Check that SQLITE_BUSY_SNAPSHOT is returned if the specified snapshot -# no longer exists because the wal file has been checkpointed. -# -# 1. Reading a snapshot from the middle of a wal file is not possible -# after the wal file has been checkpointed. -# -# 2. That a snapshot from the end of a wal file can not be read once -# the wal file has been wrapped. -# -do_execsql_test 4.1.0 { - PRAGMA journal_mode = wal; - CREATE TABLE t3(i, j); - INSERT INTO t3 VALUES('o', 't'); - INSERT INTO t3 VALUES('t', 'f'); - BEGIN; - SELECT * FROM t3; -} {wal o t t f} + do_test $tn.3.3.1 { + execsql { PRAGMA journal_mode = DELETE } + execsql { BEGIN } + list [catch {snapshot_open db main $snapshot } msg] $msg + } {1 SQLITE_ERROR} -do_test 4.1.1 { - set snapshot [sqlite3_snapshot_get db main] - execsql COMMIT -} {} -do_test 4.1.2 { - execsql { - INSERT INTO t3 VALUES('f', 's'); - BEGIN; - } - sqlite3_snapshot_open db main $snapshot - execsql { SELECT * FROM t3 } -} {o t t f} + do_test $tn.$tn.3.3.2 { + snapshot_free $snapshot + execsql COMMIT + } {} -do_test 4.1.3 { - execsql { - COMMIT; - PRAGMA wal_checkpoint; - BEGIN; - } - list [catch {sqlite3_snapshot_open db main $snapshot} msg] $msg -} {1 SQLITE_BUSY_SNAPSHOT} -do_test 4.1.4 { - sqlite3_snapshot_free $snapshot - execsql COMMIT -} {} - -do_test 4.2.1 { - execsql { - INSERT INTO t3 VALUES('s', 'e'); - INSERT INTO t3 VALUES('n', 't'); + #------------------------------------------------------------------------- + # Check that SQLITE_BUSY_SNAPSHOT is returned if the specified snapshot + # no longer exists because the wal file has been checkpointed. + # + # 1. Reading a snapshot from the middle of a wal file is not possible + # after the wal file has been checkpointed. + # + # 2. That a snapshot from the end of a wal file can not be read once + # the wal file has been wrapped. + # + do_execsql_test $tn.4.1.0 { + PRAGMA journal_mode = wal; + CREATE TABLE t3(i, j); + INSERT INTO t3 VALUES('o', 't'); + INSERT INTO t3 VALUES('t', 'f'); BEGIN; SELECT * FROM t3; - } -} {o t t f f s s e n t} -do_test 4.2.2 { - set snapshot [sqlite3_snapshot_get db main] - execsql { - COMMIT; - PRAGMA wal_checkpoint; + } {wal o t t f} + + do_test $tn.4.1.1 { + set snapshot [snapshot_get db main] + execsql COMMIT + } {} + do_test $tn.4.1.2 { + execsql { + INSERT INTO t3 VALUES('f', 's'); + BEGIN; + } + snapshot_open db main $snapshot + execsql { SELECT * FROM t3 } + } {o t t f} + + do_test $tn.4.1.3 { + execsql { + COMMIT; + PRAGMA wal_checkpoint; + BEGIN; + } + list [catch {snapshot_open db main $snapshot} msg] $msg + } {1 SQLITE_BUSY_SNAPSHOT} + do_test $tn.4.1.4 { + snapshot_free $snapshot + execsql COMMIT + } {} + + do_test $tn.4.2.1 { + execsql { + INSERT INTO t3 VALUES('s', 'e'); + INSERT INTO t3 VALUES('n', 't'); + BEGIN; + SELECT * FROM t3; + } + } {o t t f f s s e n t} + do_test $tn.4.2.2 { + set snapshot [snapshot_get db main] + execsql { + COMMIT; + PRAGMA wal_checkpoint; + BEGIN; + } + snapshot_open db main $snapshot + execsql { SELECT * FROM t3 } + } {o t t f f s s e n t} + do_test $tn.4.2.3 { + execsql { + COMMIT; + INSERT INTO t3 VALUES('e', 't'); + BEGIN; + } + list [catch {snapshot_open db main $snapshot} msg] $msg + } {1 SQLITE_BUSY_SNAPSHOT} + do_test $tn.4.2.4 { + snapshot_free $snapshot + } {} + + #------------------------------------------------------------------------- + # Check that SQLITE_BUSY is returned if a checkpoint is running when + # sqlite3_snapshot_open() is called. + # + reset_db + db close + testvfs tvfs + sqlite3 db test.db -vfs tvfs + + do_execsql_test $tn.5.1 { + PRAGMA journal_mode = wal; + CREATE TABLE x1(x, xx, xxx); + INSERT INTO x1 VALUES('z', 'zz', 'zzz'); BEGIN; + SELECT * FROM x1; + } {wal z zz zzz} + + do_test $tn.5.2 { + set ::snapshot [snapshot_get db main] + sqlite3 db2 test.db -vfs tvfs + execsql { + INSERT INTO x1 VALUES('a', 'aa', 'aaa'); + COMMIT; + } + } {} + + set t53 0 + proc write_callback {args} { + do_test $tn.5.3.[incr ::t53] { + execsql BEGIN + list [catch { snapshot_open db main $::snapshot } msg] $msg + } {1 SQLITE_BUSY} + catchsql COMMIT } - sqlite3_snapshot_open db main $snapshot - execsql { SELECT * FROM t3 } -} {o t t f f s s e n t} -do_test 4.2.3 { - execsql { - COMMIT; - INSERT INTO t3 VALUES('e', 't'); - BEGIN; - } - list [catch {sqlite3_snapshot_open db main $snapshot} msg] $msg -} {1 SQLITE_BUSY_SNAPSHOT} -do_test 4.2.4 { - sqlite3_snapshot_free $snapshot -} {} -#------------------------------------------------------------------------- -# Check that SQLITE_BUSY is returned if a checkpoint is running when -# sqlite3_snapshot_open() is called. -# -reset_db -db close -testvfs tvfs -sqlite3 db test.db -vfs tvfs - -do_execsql_test 5.1 { - PRAGMA journal_mode = wal; - CREATE TABLE x1(x, xx, xxx); - INSERT INTO x1 VALUES('z', 'zz', 'zzz'); - BEGIN; - SELECT * FROM x1; -} {wal z zz zzz} - -do_test 5.2 { - set ::snapshot [sqlite3_snapshot_get db main] - sqlite3 db2 test.db -vfs tvfs - execsql { - INSERT INTO x1 VALUES('a', 'aa', 'aaa'); - COMMIT; - } -} {} - -set t53 0 -proc write_callback {args} { - do_test 5.3.[incr ::t53] { - execsql BEGIN - list [catch { sqlite3_snapshot_open db main $::snapshot } msg] $msg - } {1 SQLITE_BUSY} - catchsql COMMIT -} - -tvfs filter xWrite -tvfs script write_callback -db2 eval { PRAGMA wal_checkpoint } -db close -db2 close -tvfs delete -sqlite3_snapshot_free $snapshot - -#------------------------------------------------------------------------- -# Test that sqlite3_snapshot_get() may be called immediately after -# "BEGIN; PRAGMA user_version;". And that sqlite3_snapshot_open() may -# be called after opening the db handle and running the script -# "PRAGMA user_version; BEGIN". -reset_db -do_execsql_test 6.1 { - PRAGMA journal_mode = wal; - CREATE TABLE x1(x, xx, xxx); - INSERT INTO x1 VALUES('z', 'zz', 'zzz'); - BEGIN; - PRAGMA user_version; -} {wal 0} -do_test 6.2 { - set ::snapshot [sqlite3_snapshot_get db main] - execsql { - INSERT INTO x1 VALUES('a', 'aa', 'aaa'); - COMMIT; - } -} {} -do_test 6.3 { - sqlite3 db2 test.db - db2 eval "PRAGMA user_version ; BEGIN" - sqlite3_snapshot_open db2 main $::snapshot - db2 eval { SELECT * FROM x1 } -} {z zz zzz} -do_test 6.4 { + tvfs filter xWrite + tvfs script write_callback + db2 eval { PRAGMA wal_checkpoint } + db close db2 close - sqlite3 db2 test.db - db2 eval "PRAGMA application_id" - db2 eval "BEGIN" - sqlite3_snapshot_open db2 main $::snapshot - db2 eval { SELECT * FROM x1 } -} {z zz zzz} + tvfs delete + snapshot_free $snapshot -do_test 6.5 { - db2 close - sqlite3 db2 test.db - db2 eval "BEGIN" - list [catch {sqlite3_snapshot_open db2 main $::snapshot} msg] $msg -} {1 SQLITE_ERROR} + #------------------------------------------------------------------------- + # Test that sqlite3_snapshot_get() may be called immediately after + # "BEGIN; PRAGMA user_version;". And that sqlite3_snapshot_open() may + # be called after opening the db handle and running the script + # "PRAGMA user_version; BEGIN". + reset_db + do_execsql_test $tn.6.1 { + PRAGMA journal_mode = wal; + CREATE TABLE x1(x, xx, xxx); + INSERT INTO x1 VALUES('z', 'zz', 'zzz'); + BEGIN; + PRAGMA user_version; + } {wal 0} + do_test $tn.6.2 { + set ::snapshot [snapshot_get db main] + execsql { + INSERT INTO x1 VALUES('a', 'aa', 'aaa'); + COMMIT; + } + } {} + do_test $tn.6.3 { + sqlite3 db2 test.db + db2 eval "PRAGMA user_version ; BEGIN" + snapshot_open db2 main $::snapshot + db2 eval { SELECT * FROM x1 } + } {z zz zzz} + do_test $tn.6.4 { + db2 close + sqlite3 db2 test.db + db2 eval "PRAGMA application_id" + db2 eval "BEGIN" + snapshot_open db2 main $::snapshot + db2 eval { SELECT * FROM x1 } + } {z zz zzz} -sqlite3_snapshot_free $snapshot + do_test $tn.6.5 { + db2 close + sqlite3 db2 test.db + db2 eval "BEGIN" + list [catch {snapshot_open db2 main $::snapshot} msg] $msg + } {1 SQLITE_ERROR} -#------------------------------------------------------------------------- -# The following tests investigate the sqlite3_snapshot_cmp() API. -# + snapshot_free $snapshot -# Compare snapshots $p1 and $p2, checking that the result is $r. -# -proc do_snapshot_cmp_test {tn p1 p2 r} { - uplevel [list do_test $tn.1 [list sqlite3_snapshot_cmp $p1 $p2] $r] - uplevel [list do_test $tn.2 [list sqlite3_snapshot_cmp $p2 $p1] [expr $r*-1]] - uplevel [list do_test $tn.3 [list sqlite3_snapshot_cmp $p1 $p1] 0] - uplevel [list do_test $tn.4 [list sqlite3_snapshot_cmp $p2 $p2] 0] + #------------------------------------------------------------------------- + # The following tests investigate the sqlite3_snapshot_cmp() API. + # + + # Compare snapshots $p1 and $p2, checking that the result is $r. + # + proc do_snapshot_cmp_test {tn p1 p2 r} { + uplevel [list do_test $tn.1 [list snapshot_cmp $p1 $p2] $r] + uplevel [list do_test $tn.2 [list snapshot_cmp $p2 $p1] [expr $r*-1]] + uplevel [list do_test $tn.3 [list snapshot_cmp $p1 $p1] 0] + uplevel [list do_test $tn.4 [list snapshot_cmp $p2 $p2] 0] + } + + catch { db2 close } + reset_db + + do_execsql_test $tn.7.1 { + PRAGMA journal_mode = wal; + CREATE TABLE t1(x); + } wal + + do_test $tn.7.1.2 { + execsql { BEGIN ; PRAGMA application_id } + set p1 [snapshot_get db main] + execsql { + INSERT INTO t1 VALUES(10); + COMMIT; + } + execsql { BEGIN ; PRAGMA application_id } + set p2 [snapshot_get db main] + execsql COMMIT + } {} + + do_snapshot_cmp_test $tn.7.1.3 $p1 $p2 -1 + snapshot_free $p1 + snapshot_free $p2 + + do_execsql_test $tn.7.2.1 { + INSERT INTO t1 VALUES(11); + INSERT INTO t1 VALUES(12); + INSERT INTO t1 VALUES(13); + BEGIN; + PRAGMA application_id; + } {0} + do_test $tn.7.2.2 { + set p1 [snapshot_get db main] + execsql { + COMMIT; + INSERT INTO t1 VALUES(14); + PRAGMA wal_checkpoint; + BEGIN; + PRAGMA application_id; + } + set p2 [snapshot_get db main] + execsql COMMIT + } {} + + do_snapshot_cmp_test $tn.7.2.3 $p1 $p2 -1 + snapshot_free $p2 + + do_test $tn.7.3.1 { + execsql { + INSERT INTO t1 VALUES(14); + BEGIN; + PRAGMA application_id; + } + set p2 [snapshot_get db main] + execsql COMMIT + } {} + + do_snapshot_cmp_test $tn.7.3.2 $p1 $p2 -1 + snapshot_free $p1 + snapshot_free $p2 } -catch { db2 close } -reset_db - -do_execsql_test 7.1 { - PRAGMA journal_mode = wal; - CREATE TABLE t1(x); -} wal - -do_test 7.1.2 { - execsql { BEGIN ; PRAGMA application_id } - set p1 [sqlite3_snapshot_get db main] - execsql { - INSERT INTO t1 VALUES(10); - COMMIT; - } - execsql { BEGIN ; PRAGMA application_id } - set p2 [sqlite3_snapshot_get db main] - execsql COMMIT -} {} - -do_snapshot_cmp_test 7.1.3 $p1 $p2 -1 -sqlite3_snapshot_free $p1 -sqlite3_snapshot_free $p2 - -do_execsql_test 7.2.1 { - INSERT INTO t1 VALUES(11); - INSERT INTO t1 VALUES(12); - INSERT INTO t1 VALUES(13); - BEGIN; - PRAGMA application_id; -} {0} -do_test 7.2.2 { - set p1 [sqlite3_snapshot_get db main] - execsql { - COMMIT; - INSERT INTO t1 VALUES(14); - PRAGMA wal_checkpoint; - BEGIN; - PRAGMA application_id; - } - set p2 [sqlite3_snapshot_get db main] - execsql COMMIT -} {} - -do_snapshot_cmp_test 7.2.3 $p1 $p2 -1 -sqlite3_snapshot_free $p2 - -do_test 7.3.1 { - execsql { - INSERT INTO t1 VALUES(14); - BEGIN; - PRAGMA application_id; - } - set p2 [sqlite3_snapshot_get db main] - execsql COMMIT -} {} - -do_snapshot_cmp_test 7.3.2 $p1 $p2 -1 -sqlite3_snapshot_free $p1 -sqlite3_snapshot_free $p2 - finish_test From 93006cdd853eb84752c0803928afdd25ce4cdb53 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 18 Nov 2016 18:22:05 +0000 Subject: [PATCH 1003/1484] Add tests for snapshot interfaces. FossilOrigin-Name: 1f7ee7af7b620262ae663d65889b6a87415d4a34 --- manifest | 11 +++--- manifest.uuid | 2 +- test/snapshot2.test | 82 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 89 insertions(+), 6 deletions(-) create mode 100644 test/snapshot2.test diff --git a/manifest b/manifest index c5597fb646..066a12a0ba 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\sexisting\ssnapshot\stests\sto\sserialize/deserialize\ssnapshots.\sNo\snew\ntests. -D 2016-11-18T14:38:41.852 +C Add\stests\sfor\ssnapshot\sinterfaces. +D 2016-11-18T18:22:05.618 F Makefile.in 6b572807415d3f0a379cebc9461416d8df4a12c8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc bb4d970894abbbe0e88d00aac29bd52af8bc95f4 @@ -1103,6 +1103,7 @@ F test/skipscan3.test ec5bab3f81c7038b43450e7b3062e04a198bdbb5 F test/skipscan5.test 67817a4b6857c47e0e33ba3e506da6f23ef68de2 F test/skipscan6.test 5866039d03a56f5bd0b3d172a012074a1d90a15b F test/snapshot.test bb34cc38828bf2e86a49207995fa7dfacd303832 +F test/snapshot2.test 30bd95f6fefa8be7f29421e27745cac90b66c74d F test/snapshot_fault.test 062ff0438a074978d45e9f9a92e7ad459b74ee73 F test/soak.test 0b5b6375c9f4110c828070b826b3b4b0bb65cd5f F test/softheap1.test 843cd84db9891b2d01b9ab64cef3e9020f98d087 @@ -1534,7 +1535,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b6a81fa1fc1fb78a65894129851a4ec3986640de -R 17ac6d49deba8d40db4fa5f6ce7fc2ca +P 16b9bf92741e4c62874cffd7c6a61763c5054c7a +R aa1ba4f87ce4a1d41c6deb879752303b U dan -Z cee5f11eb9093786088be3369dcd2153 +Z ee11b90501c467e7c32bf0deb14250e6 diff --git a/manifest.uuid b/manifest.uuid index 6af23f5732..891d62480c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -16b9bf92741e4c62874cffd7c6a61763c5054c7a \ No newline at end of file +1f7ee7af7b620262ae663d65889b6a87415d4a34 \ No newline at end of file diff --git a/test/snapshot2.test b/test/snapshot2.test new file mode 100644 index 0000000000..aa5d385893 --- /dev/null +++ b/test/snapshot2.test @@ -0,0 +1,82 @@ +# 2016 November 18 +# +# 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 regression tests for SQLite library. The focus +# of this file is the sqlite3_snapshot_xxx() APIs. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +ifcapable !snapshot {finish_test; return} +set testprefix snapshot2 + +# This test does not work with the inmemory_journal permutation. The reason +# is that each connection opened as part of this permutation executes +# "PRAGMA journal_mode=memory", which fails if the database is in wal mode +# and there are one or more existing connections. +if {[permutation]=="inmemory_journal"} { + finish_test + return +} + +#------------------------------------------------------------------------- +# Check that it is not possible to obtain a snapshot immediately after +# a wal mode database with an empty wal file is opened. But it is after +# the file has been written, even by some other connection. +# +do_execsql_test 1.0 { + PRAGMA journal_mode = wal; + CREATE TABLE t1(a, b, c); + INSERT INTO t1 VALUES(1, 2, 3); + INSERT INTO t1 VALUES(4, 5, 6); +} {wal} + +db close +do_test 1.1.1 { list [file exists test.db] [file exists test.db-wal] } {1 0} + +sqlite3 db test.db +do_execsql_test 1.1.2 { SELECT * FROM t1 } {1 2 3 4 5 6} + +do_test 1.1.3 { + execsql BEGIN + list [catch { sqlite3_snapshot_get_blob db main } msg] $msg +} {1 SQLITE_ERROR} +execsql COMMIT + +do_test 1.1.4 { + execsql { INSERT INTO t1 VALUES(7, 8, 9) } + execsql BEGIN + string length [sqlite3_snapshot_get_blob db main] +} 48 +execsql COMMIT + +db close +do_test 1.2.1 { list [file exists test.db] [file exists test.db-wal] } {1 0} + +sqlite3 db test.db +do_execsql_test 1.2.2 { SELECT * FROM t1 } {1 2 3 4 5 6 7 8 9} + +do_test 1.2.3 { + execsql BEGIN + list [catch { sqlite3_snapshot_get_blob db main } msg] $msg +} {1 SQLITE_ERROR} +execsql COMMIT + +do_test 1.2.4 { + sqlite3 db2 test.db + execsql { INSERT INTO t1 VALUES(10, 11, 12) } db2 + execsql BEGIN + string length [sqlite3_snapshot_get_blob db main] +} 48 +execsql COMMIT +db2 close + + +finish_test From edace5d4f16897f813564259afe5200acd03ce0d Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 18 Nov 2016 18:43:39 +0000 Subject: [PATCH 1004/1484] Require that the database handle be in autocommit mode for sqlite3_snapshot_get() to succeed. This is because it may open a read transaction on the database file. FossilOrigin-Name: 83b658dad091211ade3594d1e8d00ce525882506 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/main.c | 17 +++++++++-------- src/sqlite.h.in | 29 ++++++++++++++++++++++++++--- test/snapshot.test | 17 +++++++++++++---- 5 files changed, 57 insertions(+), 24 deletions(-) diff --git a/manifest b/manifest index 066a12a0ba..955a7b77e9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\stests\sfor\ssnapshot\sinterfaces. -D 2016-11-18T18:22:05.618 +C Require\sthat\sthe\sdatabase\shandle\sbe\sin\sautocommit\smode\sfor\nsqlite3_snapshot_get()\sto\ssucceed.\sThis\sis\sbecause\sit\smay\sopen\sa\sread\ntransaction\son\sthe\sdatabase\sfile. +D 2016-11-18T18:43:39.100 F Makefile.in 6b572807415d3f0a379cebc9461416d8df4a12c8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc bb4d970894abbbe0e88d00aac29bd52af8bc95f4 @@ -352,7 +352,7 @@ F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 F src/insert.c 0d6e59f9eea62db772eabc0f07901ec26fe01968 F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e F src/loadext.c 5d6642d141c07d366e43d359e94ec9de47add41d -F src/main.c 694ac90557abdaa62151a6090670e107b0f2c2ab +F src/main.c 602d7179fda1879d688174dcd74c69c8579045b5 F src/malloc.c 5ee7c2d3dcb1b0a902c9c6d0115deef54736bdfa F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b @@ -389,7 +389,7 @@ F src/resolve.c bb070cf5f23611c44ab7e4788803684e385fc3fb F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c 672b1af237ad257149fc5189f3277dcbca036eeb F src/shell.c f04e4af75c5517735397d060ed0b4a874104bb41 -F src/sqlite.h.in dfe8c1b4ac66635495ec9a6a7205fcb0f27f4451 +F src/sqlite.h.in cc6e3f38d4c1e4df4f569af49c5deb7c32f1ea10 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae F src/sqliteInt.h c471d791b10c0f2164c8b7a87adc338e703c09cc @@ -1102,7 +1102,7 @@ F test/skipscan2.test d1d1450952b7275f0b0a3a981f0230532743951a F test/skipscan3.test ec5bab3f81c7038b43450e7b3062e04a198bdbb5 F test/skipscan5.test 67817a4b6857c47e0e33ba3e506da6f23ef68de2 F test/skipscan6.test 5866039d03a56f5bd0b3d172a012074a1d90a15b -F test/snapshot.test bb34cc38828bf2e86a49207995fa7dfacd303832 +F test/snapshot.test 85735bd997a4f6d710140c28fd860519a299649f F test/snapshot2.test 30bd95f6fefa8be7f29421e27745cac90b66c74d F test/snapshot_fault.test 062ff0438a074978d45e9f9a92e7ad459b74ee73 F test/soak.test 0b5b6375c9f4110c828070b826b3b4b0bb65cd5f @@ -1535,7 +1535,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 16b9bf92741e4c62874cffd7c6a61763c5054c7a -R aa1ba4f87ce4a1d41c6deb879752303b +P 1f7ee7af7b620262ae663d65889b6a87415d4a34 +R 94e3e6505e79390151b9cd467eca8236 U dan -Z ee11b90501c467e7c32bf0deb14250e6 +Z 084fdf6a46a9563f3a18164c0feb0d49 diff --git a/manifest.uuid b/manifest.uuid index 891d62480c..0a12e01e25 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1f7ee7af7b620262ae663d65889b6a87415d4a34 \ No newline at end of file +83b658dad091211ade3594d1e8d00ce525882506 \ No newline at end of file diff --git a/src/main.c b/src/main.c index 666a72547b..29e166447e 100644 --- a/src/main.c +++ b/src/main.c @@ -3981,7 +3981,6 @@ int sqlite3_snapshot_get( ){ int rc = SQLITE_ERROR; #ifndef SQLITE_OMIT_WAL - int iDb; #ifdef SQLITE_ENABLE_API_ARMOR if( !sqlite3SafetyCheckOk(db) ){ @@ -3990,13 +3989,15 @@ int sqlite3_snapshot_get( #endif sqlite3_mutex_enter(db->mutex); - iDb = sqlite3FindDbName(db, zDb); - if( iDb==0 || iDb>1 ){ - Btree *pBt = db->aDb[iDb].pBt; - if( 0==sqlite3BtreeIsInTrans(pBt) ){ - rc = sqlite3BtreeBeginTrans(pBt, 0); - if( rc==SQLITE_OK ){ - rc = sqlite3PagerSnapshotGet(sqlite3BtreePager(pBt), ppSnapshot); + if( db->autoCommit==0 ){ + int iDb = sqlite3FindDbName(db, zDb); + if( iDb==0 || iDb>1 ){ + Btree *pBt = db->aDb[iDb].pBt; + if( 0==sqlite3BtreeIsInTrans(pBt) ){ + rc = sqlite3BtreeBeginTrans(pBt, 0); + if( rc==SQLITE_OK ){ + rc = sqlite3PagerSnapshotGet(sqlite3BtreePager(pBt), ppSnapshot); + } } } } diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 7987cfae5e..8f3b40292d 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -8296,9 +8296,32 @@ typedef struct sqlite3_snapshot { ** schema S in database connection D. ^On success, the ** [sqlite3_snapshot_get(D,S,P)] interface writes a pointer to the newly ** created [sqlite3_snapshot] object into *P and returns SQLITE_OK. -** ^If schema S of [database connection] D is not a [WAL mode] database -** that is in a read transaction, then [sqlite3_snapshot_get(D,S,P)] -** leaves the *P value unchanged and returns an appropriate [error code]. +** If there is not already a read-transaction open on schema S when +** this function is called, one is opened automatically. +** +** The following must be true for this function to succeed. If any of +** the following statements are false when sqlite3_snapshot_get() is +** called, SQLITE_ERROR is returned. The final value of *P is undefined +** in this case. +** +**

    +** +** This function may also return SQLITE_NOMEM. If it is called with the +** database handle in autocommit mode but fails for some other reason, +** whether or not a read transaction is opened on schema S is undefined. ** ** The [sqlite3_snapshot] object returned from a successful call to ** [sqlite3_snapshot_get()] must be freed using [sqlite3_snapshot_free()] diff --git a/test/snapshot.test b/test/snapshot.test index 1143c14962..99d3ed47c3 100644 --- a/test/snapshot.test +++ b/test/snapshot.test @@ -65,6 +65,7 @@ foreach {tn tcl} { # # 1) snapshot_get() is called on a non-WAL database, or # 2) there is an open write transaction on the database. + # 3) the database handle is in auto-commit mode # do_execsql_test $tn.1.0 { CREATE TABLE t1(a, b); @@ -76,7 +77,7 @@ foreach {tn tcl} { execsql { BEGIN; SELECT * FROM t1; } list [catch { snapshot_get db main } msg] $msg } {1 SQLITE_ERROR} - do_execsql_test 1.1.2 COMMIT + do_execsql_test $tn.1.1.2 COMMIT do_test $tn.1.2.1 { execsql { @@ -87,7 +88,15 @@ foreach {tn tcl} { } list [catch { snapshot_get db main } msg] $msg } {1 SQLITE_ERROR} - do_execsql_test $tn.1.3.2 COMMIT + do_execsql_test $tn.1.2.2 COMMIT + + do_test $tn.1.3.1 { + list [catch { snapshot_get db main } msg] $msg + } {1 SQLITE_ERROR} + do_test $tn.1.3.2 { + db trans { set snap [snapshot_get db main] } + snapshot_free $snap + } {} #------------------------------------------------------------------------- # Check that a simple case works. Reuse the database created by the @@ -153,7 +162,7 @@ foreach {tn tcl} { do_test $tn.2.3.1 { execsql { DELETE FROM t1 WHERE a>6 } - set snapshot [snapshot_get db main] + db trans { set snapshot [snapshot_get db main] } execsql { INSERT INTO t1 VALUES('a', 'b'); INSERT INTO t1 VALUES('c', 'd'); @@ -220,7 +229,7 @@ foreach {tn tcl} { } list [catch {snapshot_open db main $snapshot } msg] $msg } {1 SQLITE_ERROR} - do_execsql_test 3.2.4 COMMIT + do_execsql_test $tn.3.2.4 COMMIT do_test $tn.3.3.1 { execsql { PRAGMA journal_mode = DELETE } From 1158498dce3f73e3666c06f7067f69f06fe14fb4 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 18 Nov 2016 20:49:43 +0000 Subject: [PATCH 1005/1484] Add experimental sqlite3_snapshot_recover() API. FossilOrigin-Name: 174a6076a8d7bebe5efebf55f3fdc5d87c589cc7 --- manifest | 26 +++++++++--------- manifest.uuid | 2 +- src/main.c | 28 +++++++++++++++++++ src/pager.c | 14 ++++++++++ src/pager.h | 1 + src/sqlite.h.in | 6 +++++ src/test1.c | 33 +++++++++++++++++++++++ src/wal.c | 65 ++++++++++++++++++++++++++++++++++++++++++++- src/wal.h | 1 + test/snapshot2.test | 60 +++++++++++++++++++++++++++++++++++++++++ 10 files changed, 221 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index 955a7b77e9..8ffa3b7ee3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Require\sthat\sthe\sdatabase\shandle\sbe\sin\sautocommit\smode\sfor\nsqlite3_snapshot_get()\sto\ssucceed.\sThis\sis\sbecause\sit\smay\sopen\sa\sread\ntransaction\son\sthe\sdatabase\sfile. -D 2016-11-18T18:43:39.100 +C Add\sexperimental\ssqlite3_snapshot_recover()\sAPI. +D 2016-11-18T20:49:43.736 F Makefile.in 6b572807415d3f0a379cebc9461416d8df4a12c8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc bb4d970894abbbe0e88d00aac29bd52af8bc95f4 @@ -352,7 +352,7 @@ F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 F src/insert.c 0d6e59f9eea62db772eabc0f07901ec26fe01968 F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e F src/loadext.c 5d6642d141c07d366e43d359e94ec9de47add41d -F src/main.c 602d7179fda1879d688174dcd74c69c8579045b5 +F src/main.c de55e68145758d5512e9397728c9a8f4ff0ffa78 F src/malloc.c 5ee7c2d3dcb1b0a902c9c6d0115deef54736bdfa F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b @@ -374,8 +374,8 @@ F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586 F src/os_unix.c be9ca0f901a2b6c1bc93dc338f4863675180c189 F src/os_win.c cf90abd4e50d9f56d2c20ce8e005aff55d7bd8e9 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a -F src/pager.c a31e2c25563065ebfc9308f2ba3a061901fd60a8 -F src/pager.h 07d6938df0b74e4abe8f57807a8b0e1084321d8b +F src/pager.c 4e4aea7ced5734753ccbff4cf4bb4d032cf2173e +F src/pager.h d1e944291030351f362a0a7da9b5c3e34e603e39 F src/parse.y 0338f906b61e311c2b7e11a3f89b0092c780b664 F src/pcache.c 5ff2a08f76a9c1b22f43eb063b7068fb085465ac F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 @@ -389,7 +389,7 @@ F src/resolve.c bb070cf5f23611c44ab7e4788803684e385fc3fb F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c 672b1af237ad257149fc5189f3277dcbca036eeb F src/shell.c f04e4af75c5517735397d060ed0b4a874104bb41 -F src/sqlite.h.in cc6e3f38d4c1e4df4f569af49c5deb7c32f1ea10 +F src/sqlite.h.in d9b7b5942a18bb83b560c7699aff3925b4f9af90 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae F src/sqliteInt.h c471d791b10c0f2164c8b7a87adc338e703c09cc @@ -397,7 +397,7 @@ F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 F src/tclsqlite.c aef87dcd8cb66564d560ab48d43d19ac812a1eab -F src/test1.c 58de30ed902f78531cf5cf52b883a26d107208c4 +F src/test1.c d6a047ea534fb68fedcb5a47f4db3baef6748294 F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5 F src/test3.c d03f5b5da9a2410b7a91c64b0d3306ed28ab6fee F src/test4.c 18ec393bb4d0ad1de729f0b94da7267270f3d8e6 @@ -465,8 +465,8 @@ F src/vdbesort.c 91fda3909326860382b0ca8aa251e609c6a9d62c F src/vdbetrace.c 41963d5376f0349842b5fc4aaaaacd7d9cdc0834 F src/vtab.c e02cacb5c7ae742631edeb9ae9f53d399f093fd8 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 -F src/wal.c 88f8d8adcaecf6a225ae5098062fd151634fb672 -F src/wal.h bf03a23da3100ab25e5c0363450233cfee09cfc2 +F src/wal.c 5ef877f34c1becb8aaff337bb24544462117a79b +F src/wal.h 06b2a0b599cc0f53ea97f497cf8c6b758c999f71 F src/walker.c 91a6df7435827e41cff6bb7df50ea00934ee78b0 F src/where.c 952f76e7a03727480b274b66ca6641b1657cd591 F src/whereInt.h 2bcc3d176e6091cb8f50a30b65c006e88a73614d @@ -1103,7 +1103,7 @@ F test/skipscan3.test ec5bab3f81c7038b43450e7b3062e04a198bdbb5 F test/skipscan5.test 67817a4b6857c47e0e33ba3e506da6f23ef68de2 F test/skipscan6.test 5866039d03a56f5bd0b3d172a012074a1d90a15b F test/snapshot.test 85735bd997a4f6d710140c28fd860519a299649f -F test/snapshot2.test 30bd95f6fefa8be7f29421e27745cac90b66c74d +F test/snapshot2.test 26949814860534949672dc007877062719b57c39 F test/snapshot_fault.test 062ff0438a074978d45e9f9a92e7ad459b74ee73 F test/soak.test 0b5b6375c9f4110c828070b826b3b4b0bb65cd5f F test/softheap1.test 843cd84db9891b2d01b9ab64cef3e9020f98d087 @@ -1535,7 +1535,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 1f7ee7af7b620262ae663d65889b6a87415d4a34 -R 94e3e6505e79390151b9cd467eca8236 +P 83b658dad091211ade3594d1e8d00ce525882506 +R 3db63b187961b7fe3d252e007ca73669 U dan -Z 084fdf6a46a9563f3a18164c0feb0d49 +Z 5c1ddc1fb889cebc1f3b9de248414272 diff --git a/manifest.uuid b/manifest.uuid index 0a12e01e25..3e4851d960 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -83b658dad091211ade3594d1e8d00ce525882506 \ No newline at end of file +174a6076a8d7bebe5efebf55f3fdc5d87c589cc7 \ No newline at end of file diff --git a/src/main.c b/src/main.c index 29e166447e..c0494135ca 100644 --- a/src/main.c +++ b/src/main.c @@ -4044,6 +4044,34 @@ int sqlite3_snapshot_open( return rc; } +/* +** Recover as many snapshots as possible from the wal file associated with +** schema zDb of database db. +*/ +int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb){ + int rc = SQLITE_ERROR; + int iDb; +#ifndef SQLITE_OMIT_WAL + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + return SQLITE_MISUSE_BKPT; + } +#endif + + sqlite3_mutex_enter(db->mutex); + iDb = sqlite3FindDbName(db, zDb); + if( iDb==0 || iDb>1 ){ + Btree *pBt = db->aDb[iDb].pBt; + if( 0==sqlite3BtreeIsInReadTrans(pBt) ){ + rc = sqlite3PagerSnapshotRecover(sqlite3BtreePager(pBt)); + } + } + sqlite3_mutex_leave(db->mutex); +#endif /* SQLITE_OMIT_WAL */ + return rc; +} + /* ** Free a snapshot handle obtained from sqlite3_snapshot_get(). */ diff --git a/src/pager.c b/src/pager.c index 04ce19547b..9975f3fcbb 100644 --- a/src/pager.c +++ b/src/pager.c @@ -7405,6 +7405,20 @@ int sqlite3PagerSnapshotOpen(Pager *pPager, sqlite3_snapshot *pSnapshot){ } return rc; } + +/* +** If this is a WAL database, call sqlite3WalSnapshotRecover(). If this +** is not a WAL database, return an error. +*/ +int sqlite3PagerSnapshotRecover(Pager *pPager){ + int rc; + if( pPager->pWal ){ + rc = sqlite3WalSnapshotRecover(pPager->pWal); + }else{ + rc = SQLITE_ERROR; + } + return rc; +} #endif /* SQLITE_ENABLE_SNAPSHOT */ #endif /* !SQLITE_OMIT_WAL */ diff --git a/src/pager.h b/src/pager.h index 3003c21ecc..dd57f598bd 100644 --- a/src/pager.h +++ b/src/pager.h @@ -182,6 +182,7 @@ int sqlite3PagerSharedLock(Pager *pPager); # ifdef SQLITE_ENABLE_SNAPSHOT int sqlite3PagerSnapshotGet(Pager *pPager, sqlite3_snapshot **ppSnapshot); int sqlite3PagerSnapshotOpen(Pager *pPager, sqlite3_snapshot *pSnapshot); + int sqlite3PagerSnapshotRecover(Pager *pPager); # endif #else # define sqlite3PagerUseWal(x) 0 diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 8f3b40292d..9c921b8c99 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -8414,6 +8414,12 @@ SQLITE_EXPERIMENTAL int sqlite3_snapshot_cmp( sqlite3_snapshot *p2 ); +/* +** CAPI3REF: Recover snapshots from a wal file +** EXPERIMENTAL +*/ +SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb); + /* ** Undo the hack that converts floating point types to integer for ** builds on processors without floating point support. diff --git a/src/test1.c b/src/test1.c index e31ad95f40..de16246b56 100644 --- a/src/test1.c +++ b/src/test1.c @@ -2310,6 +2310,38 @@ static int SQLITE_TCLAPI test_snapshot_get( } #endif /* SQLITE_ENABLE_SNAPSHOT */ +#ifdef SQLITE_ENABLE_SNAPSHOT +/* +** Usage: sqlite3_snapshot_recover DB DBNAME +*/ +static int SQLITE_TCLAPI test_snapshot_recover( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + int rc; + sqlite3 *db; + char *zName; + + if( objc!=3 ){ + Tcl_WrongNumArgs(interp, 1, objv, "DB DBNAME"); + return TCL_ERROR; + } + if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; + zName = Tcl_GetString(objv[2]); + + rc = sqlite3_snapshot_recover(db, zName); + if( rc!=SQLITE_OK ){ + Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1)); + return TCL_ERROR; + }else{ + Tcl_ResetResult(interp); + } + return TCL_OK; +} +#endif /* SQLITE_ENABLE_SNAPSHOT */ + #ifdef SQLITE_ENABLE_SNAPSHOT /* ** Usage: sqlite3_snapshot_open DB DBNAME SNAPSHOT @@ -7646,6 +7678,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){ { "sqlite3_snapshot_open", test_snapshot_open, 0 }, { "sqlite3_snapshot_free", test_snapshot_free, 0 }, { "sqlite3_snapshot_cmp", test_snapshot_cmp, 0 }, + { "sqlite3_snapshot_recover", test_snapshot_recover, 0 }, { "sqlite3_snapshot_get_blob", test_snapshot_get_blob, 0 }, { "sqlite3_snapshot_open_blob", test_snapshot_open_blob, 0 }, { "sqlite3_snapshot_cmp_blob", test_snapshot_cmp_blob, 0 }, diff --git a/src/wal.c b/src/wal.c index 669c428efa..178278816a 100644 --- a/src/wal.c +++ b/src/wal.c @@ -2379,6 +2379,65 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){ return rc; } +/* +** Recover as many snapshots as possible from the wal file. +*/ +int sqlite3WalSnapshotRecover(Wal *pWal){ + int dummy; + int rc; + + rc = sqlite3WalBeginReadTransaction(pWal, &dummy); + if( rc==SQLITE_OK ){ + rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1); + if( rc==SQLITE_OK ){ + volatile WalCkptInfo *pInfo = walCkptInfo(pWal); + int szPage = (int)pWal->szPage; + void *pBuf1 = sqlite3_malloc(szPage); + void *pBuf2 = sqlite3_malloc(szPage); + + if( pBuf1==0 || pBuf2==0 ){ + rc = SQLITE_NOMEM; + }else{ + u32 i = pInfo->nBackfillAttempted; + for(i=pInfo->nBackfillAttempted; i>pInfo->nBackfill; i--){ + volatile ht_slot *dummy; + volatile u32 *aPgno; /* Array of page numbers */ + u32 iZero; /* Frame corresponding to aPgno[0] */ + u32 pgno; /* Page number in db file */ + i64 iDbOff; /* Offset of db file entry */ + i64 iWalOff; /* Offset of wal file entry */ + rc = walHashGet(pWal, walFramePage(i), &dummy, &aPgno, &iZero); + + if( rc==SQLITE_OK ){ + pgno = aPgno[i-iZero]; + iDbOff = (i64)(pgno-1) * szPage; + iWalOff = walFrameOffset(i, szPage) + WAL_FRAME_HDRSIZE; + rc = sqlite3OsRead(pWal->pWalFd, pBuf1, szPage, iWalOff); + } + + if( rc==SQLITE_OK ){ + rc = sqlite3OsRead(pWal->pDbFd, pBuf2, szPage, iDbOff); + } + + if( rc!=SQLITE_OK || 0==memcmp(pBuf1, pBuf2, szPage) ){ + break; + } + + pInfo->nBackfillAttempted = i-1; + } + } + + sqlite3_free(pBuf1); + sqlite3_free(pBuf2); + walUnlockExclusive(pWal, WAL_CKPT_LOCK, 1); + } + + sqlite3WalEndReadTransaction(pWal); + } + + return rc; +} + /* ** Begin a read transaction on the database. ** @@ -2441,7 +2500,11 @@ int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){ ** has not yet set the pInfo->nBackfillAttempted variable to indicate ** its intent. To avoid the race condition this leads to, ensure that ** there is no checkpointer process by taking a shared CKPT lock - ** before checking pInfo->nBackfillAttempted. */ + ** before checking pInfo->nBackfillAttempted. + ** + ** TODO: Does the aReadMark[] lock prevent a checkpointer from doing + ** this already? + */ rc = walLockShared(pWal, WAL_CKPT_LOCK); if( rc==SQLITE_OK ){ diff --git a/src/wal.h b/src/wal.h index 16d9d6e0d4..4f6d01dad6 100644 --- a/src/wal.h +++ b/src/wal.h @@ -131,6 +131,7 @@ int sqlite3WalHeapMemory(Wal *pWal); #ifdef SQLITE_ENABLE_SNAPSHOT int sqlite3WalSnapshotGet(Wal *pWal, sqlite3_snapshot **ppSnapshot); void sqlite3WalSnapshotOpen(Wal *pWal, sqlite3_snapshot *pSnapshot); +int sqlite3WalSnapshotRecover(Wal *pWal); #endif #ifdef SQLITE_ENABLE_ZIPVFS diff --git a/test/snapshot2.test b/test/snapshot2.test index aa5d385893..8d37a1499f 100644 --- a/test/snapshot2.test +++ b/test/snapshot2.test @@ -78,5 +78,65 @@ do_test 1.2.4 { execsql COMMIT db2 close +#------------------------------------------------------------------------- +# +reset_db +do_execsql_test 2.0 { + CREATE TABLE t1(x); + PRAGMA journal_mode = wal; + INSERT INTO t1 VALUES(1); + INSERT INTO t1 VALUES(2); +} {wal} + +do_test 2.1 { + db trans { set snap [sqlite3_snapshot_get_blob db main] } + sqlite3_db_config db NO_CKPT_ON_CLOSE 1 + db close + sqlite3 db test.db + + execsql {SELECT * FROM sqlite_master} + execsql BEGIN + sqlite3_snapshot_open_blob db main $snap + execsql COMMIT; + execsql { INSERT INTO t1 VALUES(3); } +} {} + +do_test 2.2 { + sqlite3_db_config db NO_CKPT_ON_CLOSE 1 + db close + sqlite3 db test.db + + execsql {SELECT * FROM sqlite_master} + execsql BEGIN + list [catch { sqlite3_snapshot_open_blob db main $snap } msg] $msg +} {1 SQLITE_BUSY_SNAPSHOT} + +do_test 2.3 { + execsql COMMIT + sqlite3_snapshot_recover db main + execsql BEGIN + sqlite3_snapshot_open_blob db main $snap + execsql { SELECT * FROM t1 } +} {1 2} + +do_test 2.4 { + execsql COMMIT + execsql { SELECT * FROM t1 } +} {1 2 3} + +do_test 2.5 { + execsql { PRAGMA wal_checkpoint } + sqlite3_db_config db NO_CKPT_ON_CLOSE 1 + db close + sqlite3 db test.db + + execsql {SELECT * FROM sqlite_master} + sqlite3_snapshot_recover db main + execsql BEGIN + list [catch { sqlite3_snapshot_open_blob db main $snap } msg] $msg +} {1 SQLITE_BUSY_SNAPSHOT} + finish_test + + From 5b4009f6376fb7b7433e859ce647a4262d2bcf07 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 19 Nov 2016 14:53:22 +0000 Subject: [PATCH 1006/1484] Fix a bug in sqlite3_snapshot_recover() that could cause subsequent read transactions to use out-of-data cache entries. FossilOrigin-Name: 9abeb7980a34cec11a3420e14ad98a4ec0d9c599 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/wal.c | 5 +++++ test/snapshot2.test | 21 +++++++++++++++++++++ 4 files changed, 34 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 8ffa3b7ee3..e549e4dfd0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sexperimental\ssqlite3_snapshot_recover()\sAPI. -D 2016-11-18T20:49:43.736 +C Fix\sa\sbug\sin\ssqlite3_snapshot_recover()\sthat\scould\scause\ssubsequent\sread\ntransactions\sto\suse\sout-of-data\scache\sentries. +D 2016-11-19T14:53:22.181 F Makefile.in 6b572807415d3f0a379cebc9461416d8df4a12c8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc bb4d970894abbbe0e88d00aac29bd52af8bc95f4 @@ -465,7 +465,7 @@ F src/vdbesort.c 91fda3909326860382b0ca8aa251e609c6a9d62c F src/vdbetrace.c 41963d5376f0349842b5fc4aaaaacd7d9cdc0834 F src/vtab.c e02cacb5c7ae742631edeb9ae9f53d399f093fd8 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 -F src/wal.c 5ef877f34c1becb8aaff337bb24544462117a79b +F src/wal.c df90cfbeb84788a05947da40bc821c834a29b085 F src/wal.h 06b2a0b599cc0f53ea97f497cf8c6b758c999f71 F src/walker.c 91a6df7435827e41cff6bb7df50ea00934ee78b0 F src/where.c 952f76e7a03727480b274b66ca6641b1657cd591 @@ -1103,7 +1103,7 @@ F test/skipscan3.test ec5bab3f81c7038b43450e7b3062e04a198bdbb5 F test/skipscan5.test 67817a4b6857c47e0e33ba3e506da6f23ef68de2 F test/skipscan6.test 5866039d03a56f5bd0b3d172a012074a1d90a15b F test/snapshot.test 85735bd997a4f6d710140c28fd860519a299649f -F test/snapshot2.test 26949814860534949672dc007877062719b57c39 +F test/snapshot2.test aeacd61be9ad4aafdab183e9137eeca87623edad F test/snapshot_fault.test 062ff0438a074978d45e9f9a92e7ad459b74ee73 F test/soak.test 0b5b6375c9f4110c828070b826b3b4b0bb65cd5f F test/softheap1.test 843cd84db9891b2d01b9ab64cef3e9020f98d087 @@ -1535,7 +1535,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 83b658dad091211ade3594d1e8d00ce525882506 -R 3db63b187961b7fe3d252e007ca73669 +P 174a6076a8d7bebe5efebf55f3fdc5d87c589cc7 +R d8309c01b710e62ecca9fb17e1bbb17f U dan -Z 5c1ddc1fb889cebc1f3b9de248414272 +Z 62bf95225417162d453d1041ff22e883 diff --git a/manifest.uuid b/manifest.uuid index 3e4851d960..a6da6c0bc7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -174a6076a8d7bebe5efebf55f3fdc5d87c589cc7 \ No newline at end of file +9abeb7980a34cec11a3420e14ad98a4ec0d9c599 \ No newline at end of file diff --git a/src/wal.c b/src/wal.c index 178278816a..279d751d7f 100644 --- a/src/wal.c +++ b/src/wal.c @@ -2432,7 +2432,12 @@ int sqlite3WalSnapshotRecover(Wal *pWal){ walUnlockExclusive(pWal, WAL_CKPT_LOCK, 1); } + /* End the read transaction opened above. Also zero the cache of the + ** wal-index header to force the pager-cache to be flushed when the next + ** read transaction is open, as it may not match the current contents of + ** pWal->hdr. */ sqlite3WalEndReadTransaction(pWal); + memset(&pWal->hdr, 0, sizeof(WalIndexHdr)); } return rc; diff --git a/test/snapshot2.test b/test/snapshot2.test index 8d37a1499f..5c21b31005 100644 --- a/test/snapshot2.test +++ b/test/snapshot2.test @@ -79,6 +79,7 @@ execsql COMMIT db2 close #------------------------------------------------------------------------- +# Simple tests for sqlite3_snapshot_recover(). # reset_db do_execsql_test 2.0 { @@ -136,6 +137,26 @@ do_test 2.5 { list [catch { sqlite3_snapshot_open_blob db main $snap } msg] $msg } {1 SQLITE_BUSY_SNAPSHOT} +#------------------------------------------------------------------------- +# Check that calling sqlite3_snapshot_recover() does not confuse the +# pager cache. +reset_db +do_execsql_test 3.0 { + PRAGMA journal_mode = wal; + CREATE TABLE t1(x, y); + INSERT INTO t1 VALUES('a', 'b'); + INSERT INTO t1 VALUES('c', 'd'); +} {wal} +do_test 3.1 { + sqlite3 db2 test.db + execsql { INSERT INTO t1 VALUES('e', 'f') } db2 + db2 close + sqlite3_snapshot_recover db main +} {} +breakpoint +do_execsql_test 3.2 { + SELECT * FROM t1; +} {a b c d e f} finish_test From 6a9e7f16ebab46e2f8ec2be8b6f834535787a164 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 19 Nov 2016 16:35:53 +0000 Subject: [PATCH 1007/1484] Fix a problem causing sqlite3_snapshot_recover() to return SQLITE_IOERR_SHORT_READ. FossilOrigin-Name: 525f75fa9fd4a95acc3fb3b0a01dabe2be39b383 --- manifest | 14 ++++----- manifest.uuid | 2 +- src/wal.c | 62 ++++++++++++++++++++++------------------ test/snapshot_fault.test | 31 ++++++++++++++++++++ 4 files changed, 73 insertions(+), 36 deletions(-) diff --git a/manifest b/manifest index e549e4dfd0..8f0fbcafe4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sbug\sin\ssqlite3_snapshot_recover()\sthat\scould\scause\ssubsequent\sread\ntransactions\sto\suse\sout-of-data\scache\sentries. -D 2016-11-19T14:53:22.181 +C Fix\sa\sproblem\scausing\ssqlite3_snapshot_recover()\sto\sreturn\nSQLITE_IOERR_SHORT_READ. +D 2016-11-19T16:35:53.322 F Makefile.in 6b572807415d3f0a379cebc9461416d8df4a12c8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc bb4d970894abbbe0e88d00aac29bd52af8bc95f4 @@ -465,7 +465,7 @@ F src/vdbesort.c 91fda3909326860382b0ca8aa251e609c6a9d62c F src/vdbetrace.c 41963d5376f0349842b5fc4aaaaacd7d9cdc0834 F src/vtab.c e02cacb5c7ae742631edeb9ae9f53d399f093fd8 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 -F src/wal.c df90cfbeb84788a05947da40bc821c834a29b085 +F src/wal.c 006eec60874fc502afc9e95639bbd446125cfab5 F src/wal.h 06b2a0b599cc0f53ea97f497cf8c6b758c999f71 F src/walker.c 91a6df7435827e41cff6bb7df50ea00934ee78b0 F src/where.c 952f76e7a03727480b274b66ca6641b1657cd591 @@ -1104,7 +1104,7 @@ F test/skipscan5.test 67817a4b6857c47e0e33ba3e506da6f23ef68de2 F test/skipscan6.test 5866039d03a56f5bd0b3d172a012074a1d90a15b F test/snapshot.test 85735bd997a4f6d710140c28fd860519a299649f F test/snapshot2.test aeacd61be9ad4aafdab183e9137eeca87623edad -F test/snapshot_fault.test 062ff0438a074978d45e9f9a92e7ad459b74ee73 +F test/snapshot_fault.test 566e8a45a2ba71c67bad2077072c85ac54e9dded F test/soak.test 0b5b6375c9f4110c828070b826b3b4b0bb65cd5f F test/softheap1.test 843cd84db9891b2d01b9ab64cef3e9020f98d087 F test/sort.test c2adc635c2564241fefec0b3a68391ef6868fd3b @@ -1535,7 +1535,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 174a6076a8d7bebe5efebf55f3fdc5d87c589cc7 -R d8309c01b710e62ecca9fb17e1bbb17f +P 9abeb7980a34cec11a3420e14ad98a4ec0d9c599 +R 7b6eb1e1f049ba4c986979f464295360 U dan -Z 62bf95225417162d453d1041ff22e883 +Z 9f95743e0b02ecca5491496b02c4041a diff --git a/manifest.uuid b/manifest.uuid index a6da6c0bc7..51ffaef2ce 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9abeb7980a34cec11a3420e14ad98a4ec0d9c599 \ No newline at end of file +525f75fa9fd4a95acc3fb3b0a01dabe2be39b383 \ No newline at end of file diff --git a/src/wal.c b/src/wal.c index 279d751d7f..4819d65c27 100644 --- a/src/wal.c +++ b/src/wal.c @@ -2392,43 +2392,49 @@ int sqlite3WalSnapshotRecover(Wal *pWal){ if( rc==SQLITE_OK ){ volatile WalCkptInfo *pInfo = walCkptInfo(pWal); int szPage = (int)pWal->szPage; - void *pBuf1 = sqlite3_malloc(szPage); - void *pBuf2 = sqlite3_malloc(szPage); + i64 szDb; /* Size of db file in bytes */ - if( pBuf1==0 || pBuf2==0 ){ - rc = SQLITE_NOMEM; - }else{ - u32 i = pInfo->nBackfillAttempted; - for(i=pInfo->nBackfillAttempted; i>pInfo->nBackfill; i--){ - volatile ht_slot *dummy; - volatile u32 *aPgno; /* Array of page numbers */ - u32 iZero; /* Frame corresponding to aPgno[0] */ - u32 pgno; /* Page number in db file */ - i64 iDbOff; /* Offset of db file entry */ - i64 iWalOff; /* Offset of wal file entry */ - rc = walHashGet(pWal, walFramePage(i), &dummy, &aPgno, &iZero); + rc = sqlite3OsFileSize(pWal->pDbFd, &szDb); + if( rc==SQLITE_OK ){ + void *pBuf1 = sqlite3_malloc(szPage); + void *pBuf2 = sqlite3_malloc(szPage); + if( pBuf1==0 || pBuf2==0 ){ + rc = SQLITE_NOMEM; + }else{ + u32 i = pInfo->nBackfillAttempted; + for(i=pInfo->nBackfillAttempted; i>pInfo->nBackfill; i--){ + volatile ht_slot *dummy; + volatile u32 *aPgno; /* Array of page numbers */ + u32 iZero; /* Frame corresponding to aPgno[0] */ + u32 pgno; /* Page number in db file */ + i64 iDbOff; /* Offset of db file entry */ + i64 iWalOff; /* Offset of wal file entry */ - if( rc==SQLITE_OK ){ + rc = walHashGet(pWal, walFramePage(i), &dummy, &aPgno, &iZero); + if( rc!=SQLITE_OK ) break; pgno = aPgno[i-iZero]; iDbOff = (i64)(pgno-1) * szPage; - iWalOff = walFrameOffset(i, szPage) + WAL_FRAME_HDRSIZE; - rc = sqlite3OsRead(pWal->pWalFd, pBuf1, szPage, iWalOff); - } - if( rc==SQLITE_OK ){ - rc = sqlite3OsRead(pWal->pDbFd, pBuf2, szPage, iDbOff); - } + if( iDbOff+szPage<=szDb ){ + iWalOff = walFrameOffset(i, szPage) + WAL_FRAME_HDRSIZE; + rc = sqlite3OsRead(pWal->pWalFd, pBuf1, szPage, iWalOff); - if( rc!=SQLITE_OK || 0==memcmp(pBuf1, pBuf2, szPage) ){ - break; - } + if( rc==SQLITE_OK ){ + rc = sqlite3OsRead(pWal->pDbFd, pBuf2, szPage, iDbOff); + } - pInfo->nBackfillAttempted = i-1; + if( rc!=SQLITE_OK || 0==memcmp(pBuf1, pBuf2, szPage) ){ + break; + } + } + + pInfo->nBackfillAttempted = i-1; + } } - } - sqlite3_free(pBuf1); - sqlite3_free(pBuf2); + sqlite3_free(pBuf1); + sqlite3_free(pBuf2); + } walUnlockExclusive(pWal, WAL_CKPT_LOCK, 1); } diff --git a/test/snapshot_fault.test b/test/snapshot_fault.test index f90690e3f6..f4f45249a4 100644 --- a/test/snapshot_fault.test +++ b/test/snapshot_fault.test @@ -17,6 +17,8 @@ source $testdir/tester.tcl ifcapable !snapshot {finish_test; return} set testprefix snapshot_fault +if 1 { + #------------------------------------------------------------------------- # Check that an sqlite3_snapshot_open() client cannot be tricked into # reading a corrupt snapshot even if a second client fails while @@ -159,6 +161,35 @@ do_faultsim_test 3.0 -prep { sqlite3_snapshot_free $::snapshot } +} + +#------------------------------------------------------------------------- +# Test the handling of faults that occur within sqlite3_snapshot_recover(). +# +reset_db +do_execsql_test 4.0 { + PRAGMA journal_mode = wal; + CREATE TABLE t1(zzz); + INSERT INTO t1 VALUES('abc'); + INSERT INTO t1 VALUES('def'); +} {wal} +faultsim_save_and_close + +do_test 4.1 { + faultsim_restore_and_reopen + db eval { SELECT * FROM sqlite_master } + sqlite3_snapshot_recover db main +} {} +db close + +do_faultsim_test 4 -faults oom* -prep { + faultsim_restore_and_reopen + db eval { SELECT * FROM sqlite_master } +} -body { + sqlite3_snapshot_recover db main +} -test { + faultsim_test_result {0 {}} {1 SQLITE_NOMEM} {1 SQLITE_IOERR_NOMEM} +} finish_test From 20ba3d7fcb6d8f7e21149b01e181fc1a9532c050 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 19 Nov 2016 17:20:28 +0000 Subject: [PATCH 1008/1484] Add another fault-injection test for sqlite3_snapshot_recover(). FossilOrigin-Name: 7e040406138669bd67dd6ecae016b3e50dbfaaf8 --- manifest | 12 +++++------ manifest.uuid | 2 +- test/snapshot_fault.test | 43 ++++++++++++++++++++++++++++++++++------ 3 files changed, 44 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 8f0fbcafe4..c1d99f809d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\scausing\ssqlite3_snapshot_recover()\sto\sreturn\nSQLITE_IOERR_SHORT_READ. -D 2016-11-19T16:35:53.322 +C Add\sanother\sfault-injection\stest\sfor\ssqlite3_snapshot_recover(). +D 2016-11-19T17:20:28.983 F Makefile.in 6b572807415d3f0a379cebc9461416d8df4a12c8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc bb4d970894abbbe0e88d00aac29bd52af8bc95f4 @@ -1104,7 +1104,7 @@ F test/skipscan5.test 67817a4b6857c47e0e33ba3e506da6f23ef68de2 F test/skipscan6.test 5866039d03a56f5bd0b3d172a012074a1d90a15b F test/snapshot.test 85735bd997a4f6d710140c28fd860519a299649f F test/snapshot2.test aeacd61be9ad4aafdab183e9137eeca87623edad -F test/snapshot_fault.test 566e8a45a2ba71c67bad2077072c85ac54e9dded +F test/snapshot_fault.test 52c5e97ebd218846a8ae2da4d147d3e77d71f963 F test/soak.test 0b5b6375c9f4110c828070b826b3b4b0bb65cd5f F test/softheap1.test 843cd84db9891b2d01b9ab64cef3e9020f98d087 F test/sort.test c2adc635c2564241fefec0b3a68391ef6868fd3b @@ -1535,7 +1535,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 9abeb7980a34cec11a3420e14ad98a4ec0d9c599 -R 7b6eb1e1f049ba4c986979f464295360 +P 525f75fa9fd4a95acc3fb3b0a01dabe2be39b383 +R 540803770026fc0e2bba54ecd3e455de U dan -Z 9f95743e0b02ecca5491496b02c4041a +Z a16f9ea1f945ee0adbd8c25a4885f6d9 diff --git a/manifest.uuid b/manifest.uuid index 51ffaef2ce..cb29e68423 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -525f75fa9fd4a95acc3fb3b0a01dabe2be39b383 \ No newline at end of file +7e040406138669bd67dd6ecae016b3e50dbfaaf8 \ No newline at end of file diff --git a/test/snapshot_fault.test b/test/snapshot_fault.test index f4f45249a4..5c6cf40a6f 100644 --- a/test/snapshot_fault.test +++ b/test/snapshot_fault.test @@ -17,8 +17,6 @@ source $testdir/tester.tcl ifcapable !snapshot {finish_test; return} set testprefix snapshot_fault -if 1 { - #------------------------------------------------------------------------- # Check that an sqlite3_snapshot_open() client cannot be tricked into # reading a corrupt snapshot even if a second client fails while @@ -161,8 +159,6 @@ do_faultsim_test 3.0 -prep { sqlite3_snapshot_free $::snapshot } -} - #------------------------------------------------------------------------- # Test the handling of faults that occur within sqlite3_snapshot_recover(). # @@ -175,14 +171,14 @@ do_execsql_test 4.0 { } {wal} faultsim_save_and_close -do_test 4.1 { +do_test 4.0.1 { faultsim_restore_and_reopen db eval { SELECT * FROM sqlite_master } sqlite3_snapshot_recover db main } {} db close -do_faultsim_test 4 -faults oom* -prep { +do_faultsim_test 4.0 -faults oom* -prep { faultsim_restore_and_reopen db eval { SELECT * FROM sqlite_master } } -body { @@ -191,5 +187,40 @@ do_faultsim_test 4 -faults oom* -prep { faultsim_test_result {0 {}} {1 SQLITE_NOMEM} {1 SQLITE_IOERR_NOMEM} } +# The following test cases contrive to call sqlite3_snapshot_recover() +# before all pages of the *-shm file have been mapped. This tests an +# extra branch of error handling logic in snapshot_recover(). +# +reset_db +do_execsql_test 4.1.0 { + PRAGMA page_size = 512; + PRAGMA journal_mode = wal; + PRAGMA wal_autocheckpoint = 0; + CREATE TABLE t1(zzz); + INSERT INTO t1 VALUES(randomblob( 500 * 9500 )); + PRAGMA user_version = 211; +} {wal 0} + +do_test 4.1.1 { + list [file size test.db-shm] [file size test.db] +} {98304 512} + +faultsim_save_and_close +do_faultsim_test 4.1 -faults shm* -prep { + catch { db2 close } + catch { db close } + faultsim_restore_and_reopen + sqlite3 db2 test.db + db2 eval { SELECT * FROM sqlite_master } + db eval BEGIN + sqlite3_snapshot_get_blob db main + db eval COMMIT +} -body { + sqlite3_snapshot_recover db main +} -test { + faultsim_test_result {0 {}} {1 SQLITE_IOERR} +} + + finish_test From 4d4757fcc86fd7014b58b08aa06b2c0f1b88105e Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 19 Nov 2016 17:30:57 +0000 Subject: [PATCH 1009/1484] Test some extra error conditions in sqlite3_recover_snapshot(). FossilOrigin-Name: db314213c08f27dd0ff5ede3c6a8eda36560809a --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/snapshot2.test | 42 +++++++++++++++++++++++++++++++++++++++++- 3 files changed, 48 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index c1d99f809d..c697bbdef6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sanother\sfault-injection\stest\sfor\ssqlite3_snapshot_recover(). -D 2016-11-19T17:20:28.983 +C Test\ssome\sextra\serror\sconditions\sin\ssqlite3_recover_snapshot(). +D 2016-11-19T17:30:57.131 F Makefile.in 6b572807415d3f0a379cebc9461416d8df4a12c8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc bb4d970894abbbe0e88d00aac29bd52af8bc95f4 @@ -1103,7 +1103,7 @@ F test/skipscan3.test ec5bab3f81c7038b43450e7b3062e04a198bdbb5 F test/skipscan5.test 67817a4b6857c47e0e33ba3e506da6f23ef68de2 F test/skipscan6.test 5866039d03a56f5bd0b3d172a012074a1d90a15b F test/snapshot.test 85735bd997a4f6d710140c28fd860519a299649f -F test/snapshot2.test aeacd61be9ad4aafdab183e9137eeca87623edad +F test/snapshot2.test 706498fdd1f03163473965faedd56b137ff7ec50 F test/snapshot_fault.test 52c5e97ebd218846a8ae2da4d147d3e77d71f963 F test/soak.test 0b5b6375c9f4110c828070b826b3b4b0bb65cd5f F test/softheap1.test 843cd84db9891b2d01b9ab64cef3e9020f98d087 @@ -1535,7 +1535,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 525f75fa9fd4a95acc3fb3b0a01dabe2be39b383 -R 540803770026fc0e2bba54ecd3e455de +P 7e040406138669bd67dd6ecae016b3e50dbfaaf8 +R 8677d727bb420bd9cae1a19aef039ec1 U dan -Z a16f9ea1f945ee0adbd8c25a4885f6d9 +Z 6dc3dd1ccc30316098a970a98f898ad5 diff --git a/manifest.uuid b/manifest.uuid index cb29e68423..a26ea4d37d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7e040406138669bd67dd6ecae016b3e50dbfaaf8 \ No newline at end of file +db314213c08f27dd0ff5ede3c6a8eda36560809a \ No newline at end of file diff --git a/test/snapshot2.test b/test/snapshot2.test index 5c21b31005..b13bbe8862 100644 --- a/test/snapshot2.test +++ b/test/snapshot2.test @@ -153,11 +153,51 @@ do_test 3.1 { db2 close sqlite3_snapshot_recover db main } {} -breakpoint do_execsql_test 3.2 { SELECT * FROM t1; } {a b c d e f} +#------------------------------------------------------------------------- +# Check that sqlite3_snapshot_recover() returns an error if it is called +# with an open read-transaction. Or on a database that does not exist. Or +# on the temp database. Or on a db that is not in wal mode. +# +do_test 4.1 { + sqlite3_snapshot_recover db main +} {} +do_test 4.2 { + execsql { + BEGIN; + SELECT * FROM sqlite_master; + } + list [catch { sqlite3_snapshot_recover db main } msg] $msg +} {1 SQLITE_ERROR} +do_test 4.3 { + execsql COMMIT + sqlite3_snapshot_recover db main +} {} +do_test 4.4 { + list [catch { sqlite3_snapshot_recover db aux } msg] $msg +} {1 SQLITE_ERROR} +do_test 4.5 { + forcedelete test.db2 + execsql { + ATTACH 'test.db2' AS aux; + PRAGMA aux.journal_mode = wal; + CREATE TABLE aux.t2(x, y); + } + list [catch { sqlite3_snapshot_recover db aux } msg] $msg +} {0 {}} +do_test 4.6 { + list [catch { sqlite3_snapshot_recover db temp } msg] $msg +} {1 SQLITE_ERROR} +do_test 4.7 { + execsql { + PRAGMA aux.journal_mode = delete; + } + list [catch { sqlite3_snapshot_recover db aux } msg] $msg +} {1 SQLITE_ERROR} + finish_test From 93f5113290a42f48386e17cee1a737ed1e5fe0d2 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 19 Nov 2016 18:31:37 +0000 Subject: [PATCH 1010/1484] Remove the requirement to open the wal file before sqlite3_snapshot_recover() is called. Also add some comments to new functions. FossilOrigin-Name: 28393c413cc4505b94411730e728583c5d4baaae --- manifest | 18 ++++---- manifest.uuid | 2 +- src/main.c | 6 ++- src/sqlite.h.in | 16 +++++++ src/wal.c | 104 +++++++++++++++++++++++--------------------- test/snapshot2.test | 1 - 6 files changed, 86 insertions(+), 61 deletions(-) diff --git a/manifest b/manifest index c697bbdef6..21ea07385c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Test\ssome\sextra\serror\sconditions\sin\ssqlite3_recover_snapshot(). -D 2016-11-19T17:30:57.131 +C Remove\sthe\srequirement\sto\sopen\sthe\swal\sfile\sbefore\ssqlite3_snapshot_recover()\nis\scalled.\sAlso\sadd\ssome\scomments\sto\snew\sfunctions. +D 2016-11-19T18:31:37.017 F Makefile.in 6b572807415d3f0a379cebc9461416d8df4a12c8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc bb4d970894abbbe0e88d00aac29bd52af8bc95f4 @@ -352,7 +352,7 @@ F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 F src/insert.c 0d6e59f9eea62db772eabc0f07901ec26fe01968 F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e F src/loadext.c 5d6642d141c07d366e43d359e94ec9de47add41d -F src/main.c de55e68145758d5512e9397728c9a8f4ff0ffa78 +F src/main.c 5669ae83c6bd47f090aee26a6b548a882d69e9e1 F src/malloc.c 5ee7c2d3dcb1b0a902c9c6d0115deef54736bdfa F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b @@ -389,7 +389,7 @@ F src/resolve.c bb070cf5f23611c44ab7e4788803684e385fc3fb F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c 672b1af237ad257149fc5189f3277dcbca036eeb F src/shell.c f04e4af75c5517735397d060ed0b4a874104bb41 -F src/sqlite.h.in d9b7b5942a18bb83b560c7699aff3925b4f9af90 +F src/sqlite.h.in 631cc94108c1c03190d5f1edb70e7797c522a37a F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae F src/sqliteInt.h c471d791b10c0f2164c8b7a87adc338e703c09cc @@ -465,7 +465,7 @@ F src/vdbesort.c 91fda3909326860382b0ca8aa251e609c6a9d62c F src/vdbetrace.c 41963d5376f0349842b5fc4aaaaacd7d9cdc0834 F src/vtab.c e02cacb5c7ae742631edeb9ae9f53d399f093fd8 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 -F src/wal.c 006eec60874fc502afc9e95639bbd446125cfab5 +F src/wal.c 56bba6f4101b55054145ce164951bea4a1b09548 F src/wal.h 06b2a0b599cc0f53ea97f497cf8c6b758c999f71 F src/walker.c 91a6df7435827e41cff6bb7df50ea00934ee78b0 F src/where.c 952f76e7a03727480b274b66ca6641b1657cd591 @@ -1103,7 +1103,7 @@ F test/skipscan3.test ec5bab3f81c7038b43450e7b3062e04a198bdbb5 F test/skipscan5.test 67817a4b6857c47e0e33ba3e506da6f23ef68de2 F test/skipscan6.test 5866039d03a56f5bd0b3d172a012074a1d90a15b F test/snapshot.test 85735bd997a4f6d710140c28fd860519a299649f -F test/snapshot2.test 706498fdd1f03163473965faedd56b137ff7ec50 +F test/snapshot2.test eb083df2e617708a4a93d70965f14268d4934120 F test/snapshot_fault.test 52c5e97ebd218846a8ae2da4d147d3e77d71f963 F test/soak.test 0b5b6375c9f4110c828070b826b3b4b0bb65cd5f F test/softheap1.test 843cd84db9891b2d01b9ab64cef3e9020f98d087 @@ -1535,7 +1535,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 7e040406138669bd67dd6ecae016b3e50dbfaaf8 -R 8677d727bb420bd9cae1a19aef039ec1 +P db314213c08f27dd0ff5ede3c6a8eda36560809a +R 0c1e63a3653bf6d9b725483fda2de4a1 U dan -Z 6dc3dd1ccc30316098a970a98f898ad5 +Z 573fa32a4bef0fb7a3cf7415ded5b3fe diff --git a/manifest.uuid b/manifest.uuid index a26ea4d37d..d4754cb8fa 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -db314213c08f27dd0ff5ede3c6a8eda36560809a \ No newline at end of file +28393c413cc4505b94411730e728583c5d4baaae \ No newline at end of file diff --git a/src/main.c b/src/main.c index c0494135ca..5980dbcc37 100644 --- a/src/main.c +++ b/src/main.c @@ -4064,7 +4064,11 @@ int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb){ if( iDb==0 || iDb>1 ){ Btree *pBt = db->aDb[iDb].pBt; if( 0==sqlite3BtreeIsInReadTrans(pBt) ){ - rc = sqlite3PagerSnapshotRecover(sqlite3BtreePager(pBt)); + rc = sqlite3BtreeBeginTrans(pBt, 0); + if( rc==SQLITE_OK ){ + rc = sqlite3PagerSnapshotRecover(sqlite3BtreePager(pBt)); + sqlite3BtreeCommit(pBt); + } } } sqlite3_mutex_leave(db->mutex); diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 9c921b8c99..563b21f24e 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -8417,6 +8417,22 @@ SQLITE_EXPERIMENTAL int sqlite3_snapshot_cmp( /* ** CAPI3REF: Recover snapshots from a wal file ** EXPERIMENTAL +** +** If all connections disconnect from a database file but do not perform +** a checkpoint, the existing wal file is opened along with the database +** file the next time the database is opened. At this point it is only +** possible to successfully call sqlite3_snapshot_open() to open the most +** recent snapshot of the database (the one at the head of the wal file), +** even though the wal file may contain other valid snapshots for which +** clients have sqlite3_snapshot handles. +** +** This function attempts to scan the wal file associated with database zDb +** of database handle db and make all valid snapshots available to +** sqlite3_snapshot_open(). It is an error if there is already a read +** transaction open on the database, or if the database is not a wal mode +** database. +** +** SQLITE_OK is returned if successful, or an SQLite error code otherwise. */ SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb); diff --git a/src/wal.c b/src/wal.c index 4819d65c27..52e44ad550 100644 --- a/src/wal.c +++ b/src/wal.c @@ -2380,70 +2380,76 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){ } /* -** Recover as many snapshots as possible from the wal file. +** Attempt to reduce the value of the WalCkptInfo.nBackfillAttempted +** variable so that older snapshots can be accessed. To do this, loop +** through all wal frames from nBackfillAttempted to (nBackfill+1), +** comparing their content to the corresponding page with the database +** file, if any. Set nBackfillAttempted to the frame number of the +** first frame for which the wal file content matches the db file. +** +** This is only really safe if the file-system is such that any page +** writes made by earlier checkpointers were atomic operations, which +** is not always true. It is also possible that nBackfillAttempted +** may be left set to a value larger than expected, if a wal frame +** contains content that duplicate of an earlier version of the same +** page. +** +** SQLITE_OK is returned if successful, or an SQLite error code if an +** error occurs. It is not an error if nBackfillAttempted cannot be +** decreased at all. */ int sqlite3WalSnapshotRecover(Wal *pWal){ - int dummy; int rc; - rc = sqlite3WalBeginReadTransaction(pWal, &dummy); + assert( pWal->readLock>=0 ); + rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1); if( rc==SQLITE_OK ){ - rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1); + volatile WalCkptInfo *pInfo = walCkptInfo(pWal); + int szPage = (int)pWal->szPage; + i64 szDb; /* Size of db file in bytes */ + + rc = sqlite3OsFileSize(pWal->pDbFd, &szDb); if( rc==SQLITE_OK ){ - volatile WalCkptInfo *pInfo = walCkptInfo(pWal); - int szPage = (int)pWal->szPage; - i64 szDb; /* Size of db file in bytes */ + void *pBuf1 = sqlite3_malloc(szPage); + void *pBuf2 = sqlite3_malloc(szPage); + if( pBuf1==0 || pBuf2==0 ){ + rc = SQLITE_NOMEM; + }else{ + u32 i = pInfo->nBackfillAttempted; + for(i=pInfo->nBackfillAttempted; i>pInfo->nBackfill; i--){ + volatile ht_slot *dummy; + volatile u32 *aPgno; /* Array of page numbers */ + u32 iZero; /* Frame corresponding to aPgno[0] */ + u32 pgno; /* Page number in db file */ + i64 iDbOff; /* Offset of db file entry */ + i64 iWalOff; /* Offset of wal file entry */ - rc = sqlite3OsFileSize(pWal->pDbFd, &szDb); - if( rc==SQLITE_OK ){ - void *pBuf1 = sqlite3_malloc(szPage); - void *pBuf2 = sqlite3_malloc(szPage); - if( pBuf1==0 || pBuf2==0 ){ - rc = SQLITE_NOMEM; - }else{ - u32 i = pInfo->nBackfillAttempted; - for(i=pInfo->nBackfillAttempted; i>pInfo->nBackfill; i--){ - volatile ht_slot *dummy; - volatile u32 *aPgno; /* Array of page numbers */ - u32 iZero; /* Frame corresponding to aPgno[0] */ - u32 pgno; /* Page number in db file */ - i64 iDbOff; /* Offset of db file entry */ - i64 iWalOff; /* Offset of wal file entry */ + rc = walHashGet(pWal, walFramePage(i), &dummy, &aPgno, &iZero); + if( rc!=SQLITE_OK ) break; + pgno = aPgno[i-iZero]; + iDbOff = (i64)(pgno-1) * szPage; - rc = walHashGet(pWal, walFramePage(i), &dummy, &aPgno, &iZero); - if( rc!=SQLITE_OK ) break; - pgno = aPgno[i-iZero]; - iDbOff = (i64)(pgno-1) * szPage; + if( iDbOff+szPage<=szDb ){ + iWalOff = walFrameOffset(i, szPage) + WAL_FRAME_HDRSIZE; + rc = sqlite3OsRead(pWal->pWalFd, pBuf1, szPage, iWalOff); - if( iDbOff+szPage<=szDb ){ - iWalOff = walFrameOffset(i, szPage) + WAL_FRAME_HDRSIZE; - rc = sqlite3OsRead(pWal->pWalFd, pBuf1, szPage, iWalOff); - - if( rc==SQLITE_OK ){ - rc = sqlite3OsRead(pWal->pDbFd, pBuf2, szPage, iDbOff); - } - - if( rc!=SQLITE_OK || 0==memcmp(pBuf1, pBuf2, szPage) ){ - break; - } + if( rc==SQLITE_OK ){ + rc = sqlite3OsRead(pWal->pDbFd, pBuf2, szPage, iDbOff); } - pInfo->nBackfillAttempted = i-1; + if( rc!=SQLITE_OK || 0==memcmp(pBuf1, pBuf2, szPage) ){ + break; + } } + + pInfo->nBackfillAttempted = i-1; } - - sqlite3_free(pBuf1); - sqlite3_free(pBuf2); } - walUnlockExclusive(pWal, WAL_CKPT_LOCK, 1); - } - /* End the read transaction opened above. Also zero the cache of the - ** wal-index header to force the pager-cache to be flushed when the next - ** read transaction is open, as it may not match the current contents of - ** pWal->hdr. */ - sqlite3WalEndReadTransaction(pWal); - memset(&pWal->hdr, 0, sizeof(WalIndexHdr)); + sqlite3_free(pBuf1); + sqlite3_free(pBuf2); + } + walUnlockExclusive(pWal, WAL_CKPT_LOCK, 1); } return rc; diff --git a/test/snapshot2.test b/test/snapshot2.test index b13bbe8862..62d3070ecd 100644 --- a/test/snapshot2.test +++ b/test/snapshot2.test @@ -131,7 +131,6 @@ do_test 2.5 { db close sqlite3 db test.db - execsql {SELECT * FROM sqlite_master} sqlite3_snapshot_recover db main execsql BEGIN list [catch { sqlite3_snapshot_open_blob db main $snap } msg] $msg From 0f85b2ff0970391caf4629236d5bedcf55cc3b8d Mon Sep 17 00:00:00 2001 From: drh Date: Sun, 20 Nov 2016 12:00:27 +0000 Subject: [PATCH 1011/1484] Prevent a possible use-after-free bug in the query optimizer. FossilOrigin-Name: 0a98c8d76ac86412d5eb68de994658c250989349 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/whereexpr.c | 2 ++ 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index f1ad21a433..1a6c1dd879 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\sin\srtreeD.test\scausing\sit\sto\sfail\sin\sOMIT_BUILTIN_TEST\sbuilds. -D 2016-11-17T20:05:00.694 +C Prevent\sa\spossible\suse-after-free\sbug\sin\sthe\squery\soptimizer. +D 2016-11-20T12:00:27.508 F Makefile.in 6b572807415d3f0a379cebc9461416d8df4a12c8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc bb4d970894abbbe0e88d00aac29bd52af8bc95f4 @@ -471,7 +471,7 @@ F src/walker.c 91a6df7435827e41cff6bb7df50ea00934ee78b0 F src/where.c 952f76e7a03727480b274b66ca6641b1657cd591 F src/whereInt.h 2bcc3d176e6091cb8f50a30b65c006e88a73614d F src/wherecode.c 4ea298998499db5a407ffd70e87e119a86ed7834 -F src/whereexpr.c a83d70154f3bbce5051a7e9710021f647c0fe4f2 +F src/whereexpr.c c19a84ac530835d37217db2181e4fe75901b7b97 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1534,7 +1534,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 2331192b4ca6a169b6ac0daafb21ceb7c390de65 -R 252cde6585f71191b31af3499dd16889 -U dan -Z 3bd9299c3f417af0dbc0173ca4fc27e5 +P d6b3779e6dad038d8bc35139cf314bf1e6e91977 +R 830f3978b6b30c614984da775063fd9f +U drh +Z d214ac5b563755a186f4bc035514a8e0 diff --git a/manifest.uuid b/manifest.uuid index 19168176ad..3e43a5563d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d6b3779e6dad038d8bc35139cf314bf1e6e91977 \ No newline at end of file +0a98c8d76ac86412d5eb68de994658c250989349 \ No newline at end of file diff --git a/src/whereexpr.c b/src/whereexpr.c index 40075bedee..13d5611457 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -1270,6 +1270,8 @@ static void exprAnalyze( /* Prevent ON clause terms of a LEFT JOIN from being used to drive ** an index for tables to the left of the join. */ + testcase( pTerm!=&pWC->a[idxTerm] ); + pTerm = &pWC->a[idxTerm]; pTerm->prereqRight |= extraRight; } From c10b9dac840697b72c256252904d85d985da4b4c Mon Sep 17 00:00:00 2001 From: drh Date: Sun, 20 Nov 2016 17:59:59 +0000 Subject: [PATCH 1012/1484] Fix harmless compiler warnings. FossilOrigin-Name: b3b7b42d9a4a0e7e2be8b2933328a7bec2f49a81 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/insert.c | 1 - src/shell.c | 4 ++++ 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 1a6c1dd879..82825d7679 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Prevent\sa\spossible\suse-after-free\sbug\sin\sthe\squery\soptimizer. -D 2016-11-20T12:00:27.508 +C Fix\sharmless\scompiler\swarnings. +D 2016-11-20T17:59:59.686 F Makefile.in 6b572807415d3f0a379cebc9461416d8df4a12c8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc bb4d970894abbbe0e88d00aac29bd52af8bc95f4 @@ -349,7 +349,7 @@ F src/hash.c 63d0ee752a3b92d4695b2b1f5259c4621b2cfebd F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4 F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 -F src/insert.c 0d6e59f9eea62db772eabc0f07901ec26fe01968 +F src/insert.c 24a42864ae46e4448d15f3207af963a6452b611e F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e F src/loadext.c 5d6642d141c07d366e43d359e94ec9de47add41d F src/main.c 694ac90557abdaa62151a6090670e107b0f2c2ab @@ -388,7 +388,7 @@ F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c bb070cf5f23611c44ab7e4788803684e385fc3fb F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c 672b1af237ad257149fc5189f3277dcbca036eeb -F src/shell.c f04e4af75c5517735397d060ed0b4a874104bb41 +F src/shell.c b6ba45f741cc0e56ec7a3504855fe1373def2e16 F src/sqlite.h.in 803f7050f69b2eea573fac219f3c92582c096027 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae @@ -1534,7 +1534,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d6b3779e6dad038d8bc35139cf314bf1e6e91977 -R 830f3978b6b30c614984da775063fd9f +P 0a98c8d76ac86412d5eb68de994658c250989349 +R 38b98996abd27ed143b71be3145a6356 U drh -Z d214ac5b563755a186f4bc035514a8e0 +Z ab3b36c0e8942c1f47487ebf38a820ad diff --git a/manifest.uuid b/manifest.uuid index 3e43a5563d..90143d3d06 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0a98c8d76ac86412d5eb68de994658c250989349 \ No newline at end of file +b3b7b42d9a4a0e7e2be8b2933328a7bec2f49a81 \ No newline at end of file diff --git a/src/insert.c b/src/insert.c index f7c7bed540..11b7221714 100644 --- a/src/insert.c +++ b/src/insert.c @@ -786,7 +786,6 @@ void sqlite3Insert( /* If this is not a view, open the table and and all indices */ if( !isView ){ int nIdx; - Index *pIdx; nIdx = sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, 0, -1, 0, &iDataCur, &iIdxCur); aRegIdx = sqlite3DbMallocRawNN(db, sizeof(int)*(nIdx+1)); diff --git a/src/shell.c b/src/shell.c index aaba1080e4..1cc4cc2230 100644 --- a/src/shell.c +++ b/src/shell.c @@ -2583,6 +2583,8 @@ static FILE *output_file_open(const char *zFile){ return f; } +#if !defined(SQLITE_OMIT_BUILTIN_TEST) +#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT) /* ** A routine for handling output from sqlite3_trace(). */ @@ -2603,6 +2605,8 @@ static int sql_trace_callback( } return 0; } +#endif +#endif /* ** A no-op routine that runs with the ".breakpoint" doc-command. This is From 89500dcd0b1f3d422d22c548c97ccfadef88dd36 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 21 Nov 2016 18:15:35 +0000 Subject: [PATCH 1013/1484] Enhance speedtest1.c so that is works on older versions of SQLite, before the introduction of the group_concat() aggregate function. FossilOrigin-Name: 9979ba80a649ee61d9d174dc9d9fcab7e9fc1332 --- manifest | 12 ++++---- manifest.uuid | 2 +- test/speedtest1.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 77 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 82825d7679..3840f7a7d0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\scompiler\swarnings. -D 2016-11-20T17:59:59.686 +C Enhance\sspeedtest1.c\sso\sthat\sis\sworks\son\solder\sversions\sof\sSQLite,\sbefore\nthe\sintroduction\sof\sthe\sgroup_concat()\saggregate\sfunction. +D 2016-11-21T18:15:35.996 F Makefile.in 6b572807415d3f0a379cebc9461416d8df4a12c8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc bb4d970894abbbe0e88d00aac29bd52af8bc95f4 @@ -1120,7 +1120,7 @@ F test/speed3.test 694affeb9100526007436334cf7d08f3d74b85ef F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715 F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b -F test/speedtest1.c 2699cdb3c04cdaa44f47bf3cb0b720d8c52883e6 +F test/speedtest1.c dae4b22c620743e2767d0ec9fc11f2d1d6383ff1 F test/spellfix.test f9c1f431e2c096c8775fec032952320c0e4700db F test/spellfix2.test dfc8f519a3fc204cb2dfa8b4f29821ae90f6f8c3 F test/spellfix3.test 0f9efaaa502a0e0a09848028518a6fb096c8ad33 @@ -1534,7 +1534,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 0a98c8d76ac86412d5eb68de994658c250989349 -R 38b98996abd27ed143b71be3145a6356 +P b3b7b42d9a4a0e7e2be8b2933328a7bec2f49a81 +R 142d4e960b1bc74fe4e27f638486681b U drh -Z ab3b36c0e8942c1f47487ebf38a820ad +Z 46dbec5fea6f8ea94f3f3ff9f77bd1e2 diff --git a/manifest.uuid b/manifest.uuid index 90143d3d06..9891c7c97a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b3b7b42d9a4a0e7e2be8b2933328a7bec2f49a81 \ No newline at end of file +9979ba80a649ee61d9d174dc9d9fcab7e9fc1332 \ No newline at end of file diff --git a/test/speedtest1.c b/test/speedtest1.c index 2a744380dd..1c3e3c27f8 100644 --- a/test/speedtest1.c +++ b/test/speedtest1.c @@ -456,6 +456,68 @@ static int est_square_root(int x){ return y0; } + +#if SQLITE_VERSION_NUMBER<3005004 +/* +** An implementation of group_concat(). Used only when testing older +** versions of SQLite that lack the built-in group_concat(). +*/ +struct groupConcat { + char *z; + int nAlloc; + int nUsed; +}; +static void groupAppend(struct groupConcat *p, const char *z, int n){ + if( p->nUsed+n >= p->nAlloc ){ + int n2 = (p->nAlloc+n+1)*2; + char *z2 = sqlite3_realloc(p->z, n2); + if( z2==0 ) return; + p->z = z2; + p->nAlloc = n2; + } + memcpy(p->z+p->nUsed, z, n); + p->nUsed += n; +} +static void groupStep( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + const char *zVal; + struct groupConcat *p; + const char *zSep; + int nVal, nSep; + assert( argc==1 || argc==2 ); + if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; + p= (struct groupConcat*)sqlite3_aggregate_context(context, sizeof(*p)); + + if( p ){ + int firstTerm = p->nUsed==0; + if( !firstTerm ){ + if( argc==2 ){ + zSep = (char*)sqlite3_value_text(argv[1]); + nSep = sqlite3_value_bytes(argv[1]); + }else{ + zSep = ","; + nSep = 1; + } + if( nSep ) groupAppend(p, zSep, nSep); + } + zVal = (char*)sqlite3_value_text(argv[0]); + nVal = sqlite3_value_bytes(argv[0]); + if( zVal ) groupAppend(p, zVal, nVal); + } +} +static void groupFinal(sqlite3_context *context){ + struct groupConcat *p; + p = sqlite3_aggregate_context(context, 0); + if( p && p->z ){ + p->z[p->nUsed] = 0; + sqlite3_result_text(context, p->z, p->nUsed, sqlite3_free); + } +} +#endif + /* ** The main and default testset */ @@ -525,6 +587,10 @@ void testset_main(void){ speedtest1_exec("COMMIT"); speedtest1_end_test(); +#if SQLITE_VERSION_NUMBER<3005004 + sqlite3_create_function(g.db, "group_concat", 1, SQLITE_UTF8, 0, + 0, groupStep, groupFinal); +#endif n = 25; speedtest1_begin_test(130, "%d SELECTS, numeric BETWEEN, unindexed", n); @@ -1371,10 +1437,12 @@ int main(int argc, char **argv){ nLook = integerValue(argv[i+1]); szLook = integerValue(argv[i+2]); i += 2; +#if SQLITE_VERSION_NUMBER>=3006000 }else if( strcmp(z,"multithread")==0 ){ sqlite3_config(SQLITE_CONFIG_MULTITHREAD); }else if( strcmp(z,"nomemstat")==0 ){ sqlite3_config(SQLITE_CONFIG_MEMSTATUS, 0); +#endif }else if( strcmp(z,"nosync")==0 ){ noSync = 1; }else if( strcmp(z,"notnull")==0 ){ @@ -1406,10 +1474,12 @@ int main(int argc, char **argv){ nScratch = integerValue(argv[i+1]); szScratch = integerValue(argv[i+2]); i += 2; +#if SQLITE_VERSION_NUMBER>=3006000 }else if( strcmp(z,"serialized")==0 ){ sqlite3_config(SQLITE_CONFIG_SERIALIZED); }else if( strcmp(z,"singlethread")==0 ){ sqlite3_config(SQLITE_CONFIG_SINGLETHREAD); +#endif }else if( strcmp(z,"sqlonly")==0 ){ g.bSqlOnly = 1; }else if( strcmp(z,"shrink-memory")==0 ){ From 60ffc80756f9a48f6ce260437dcf4140364c2ff4 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 21 Nov 2016 21:33:46 +0000 Subject: [PATCH 1014/1484] Remove unnecessary OP_Close opcodes at the end of INSERT operations, resulting in smaller and faster code. FossilOrigin-Name: abeddb6d5a4040e1d0a87a4f32ad79794ba0842b --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/insert.c | 10 +--------- 3 files changed, 8 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index 3840f7a7d0..cf92f6bee8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\sspeedtest1.c\sso\sthat\sis\sworks\son\solder\sversions\sof\sSQLite,\sbefore\nthe\sintroduction\sof\sthe\sgroup_concat()\saggregate\sfunction. -D 2016-11-21T18:15:35.996 +C Remove\sunnecessary\sOP_Close\sopcodes\sat\sthe\send\sof\sINSERT\soperations,\sresulting\nin\ssmaller\sand\sfaster\scode. +D 2016-11-21T21:33:46.646 F Makefile.in 6b572807415d3f0a379cebc9461416d8df4a12c8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc bb4d970894abbbe0e88d00aac29bd52af8bc95f4 @@ -349,7 +349,7 @@ F src/hash.c 63d0ee752a3b92d4695b2b1f5259c4621b2cfebd F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4 F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 -F src/insert.c 24a42864ae46e4448d15f3207af963a6452b611e +F src/insert.c b07f929977f36d2279cc3bce41583e30881cb617 F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e F src/loadext.c 5d6642d141c07d366e43d359e94ec9de47add41d F src/main.c 694ac90557abdaa62151a6090670e107b0f2c2ab @@ -1534,7 +1534,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b3b7b42d9a4a0e7e2be8b2933328a7bec2f49a81 -R 142d4e960b1bc74fe4e27f638486681b +P 9979ba80a649ee61d9d174dc9d9fcab7e9fc1332 +R 92d61cb2d5bdcee0374dbd9c4ae6bd21 U drh -Z 46dbec5fea6f8ea94f3f3ff9f77bd1e2 +Z 31a59b2224bec36ffef21dc37a376954 diff --git a/manifest.uuid b/manifest.uuid index 9891c7c97a..659aa4015d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9979ba80a649ee61d9d174dc9d9fcab7e9fc1332 \ No newline at end of file +abeddb6d5a4040e1d0a87a4f32ad79794ba0842b \ No newline at end of file diff --git a/src/insert.c b/src/insert.c index 11b7221714..bb9936f3f7 100644 --- a/src/insert.c +++ b/src/insert.c @@ -485,7 +485,7 @@ void sqlite3Insert( sqlite3 *db; /* The main database structure */ Table *pTab; /* The table to insert into. aka TABLE */ char *zTab; /* Name of the table into which we are inserting */ - int i, j, idx; /* Loop counters */ + int i, j; /* Loop counters */ Vdbe *v; /* Generate code into this virtual machine */ Index *pIdx; /* For looping over indices of the table */ int nColumn; /* Number of columns in the data */ @@ -1045,14 +1045,6 @@ void sqlite3Insert( sqlite3VdbeJumpHere(v, addrInsTop); } - if( !IsVirtual(pTab) && !isView ){ - /* Close all tables opened */ - if( iDataCurpIndex; pIdx; pIdx=pIdx->pNext, idx++){ - sqlite3VdbeAddOp1(v, OP_Close, idx+iIdxCur); - } - } - insert_end: /* Update the sqlite_sequence table by storing the content of the ** maximum rowid counter values recorded while inserting into From 65f38d960d22370c45e67ca9557f26f3e0e9356c Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 22 Nov 2016 01:26:42 +0000 Subject: [PATCH 1015/1484] Remove unnecessary OP_Close opcodes for a size reduction and performance increase. FossilOrigin-Name: 32be7aae92ee48bf2cd260ea41e79c2bc62738f9 --- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- src/btree.c | 22 +--------------------- src/delete.c | 8 -------- src/update.c | 9 --------- src/vdbeblob.c | 3 +-- src/where.c | 21 --------------------- 7 files changed, 13 insertions(+), 72 deletions(-) diff --git a/manifest b/manifest index cf92f6bee8..12324450ae 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sunnecessary\sOP_Close\sopcodes\sat\sthe\send\sof\sINSERT\soperations,\sresulting\nin\ssmaller\sand\sfaster\scode. -D 2016-11-21T21:33:46.646 +C Remove\sunnecessary\sOP_Close\sopcodes\sfor\sa\ssize\sreduction\sand\sperformance\nincrease. +D 2016-11-22T01:26:42.349 F Makefile.in 6b572807415d3f0a379cebc9461416d8df4a12c8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc bb4d970894abbbe0e88d00aac29bd52af8bc95f4 @@ -330,7 +330,7 @@ F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792 F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b F src/bitvec.c 3ee4c8b2c94ed3a7377256e18199e6ff5cf33f63 F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 -F src/btree.c a7ed407f879be72c94b81f965d552e51b54a971f +F src/btree.c 090a13ac2a11bff2fcd30763a7347af998cf468f F src/btree.h 01ec45846fa177e929f01ee36a8e34337d653544 F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 F src/build.c 178f16698cbcb43402c343a9413fe22c99ffee21 @@ -339,7 +339,7 @@ F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c a2a52d6e353f459d8ab0f07321f60fafa47d5421 F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d -F src/delete.c 6cac3a6c3f3c5ad4cacc402aee1610fc94ebc3dc +F src/delete.c 99949851e8e9ea4e1db739b0d354d360e1f80f2b F src/expr.c d8c8277d77e95d7fcce3b6b6d0f66652e482567f F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c b9ca262f6ad4d030a3cab737ebf9b0b3c8b4ac80 @@ -450,7 +450,7 @@ F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c 78c8085bc7af1922aa687f0f4bbd716821330de5 F src/treeview.c 4e44ade3bfe59d82005039f72e09333ce2b4162c F src/trigger.c 3419bb9862983d84d70735fb4c94b21b934cd0c5 -F src/update.c bb9854778bdbbbca55d7533e55058733bd3fefe3 +F src/update.c 68714ed42a506d782a3d75ff8f09640706d6a3b2 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 3e2da6101888d073e79ecc6af5e0a2f70fa1e498 F src/vacuum.c 33c174b28886b2faf26e503b5a49a1c01a9b1c16 @@ -459,7 +459,7 @@ F src/vdbe.h c044be7050ac6bf596eecc6ab159f5dbc020a3b7 F src/vdbeInt.h 29b25318a0286c4b2599c0fbef6acf524398489a F src/vdbeapi.c 97129bec6b1553da50d8e73f523c278bda66d9f6 F src/vdbeaux.c 52d9b840859f260ce8418be9333dd77c902e1c74 -F src/vdbeblob.c 3e82a797b60c3b9fed7b8de8c539ca7607874937 +F src/vdbeblob.c ba5b57b9fa47b320ad5c46468e77d8660c931190 F src/vdbemem.c fcdd73a2001a673f48a244a77b1038928ae729c9 F src/vdbesort.c 91fda3909326860382b0ca8aa251e609c6a9d62c F src/vdbetrace.c 41963d5376f0349842b5fc4aaaaacd7d9cdc0834 @@ -468,7 +468,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 7e8557314bcf867ffe3fff1d8ef2d207ace8e065 F src/wal.h bf03a23da3100ab25e5c0363450233cfee09cfc2 F src/walker.c 91a6df7435827e41cff6bb7df50ea00934ee78b0 -F src/where.c 952f76e7a03727480b274b66ca6641b1657cd591 +F src/where.c 6bbf9284f4f15a6fa48663d033870cc0d7f5ee66 F src/whereInt.h 2bcc3d176e6091cb8f50a30b65c006e88a73614d F src/wherecode.c 4ea298998499db5a407ffd70e87e119a86ed7834 F src/whereexpr.c c19a84ac530835d37217db2181e4fe75901b7b97 @@ -1534,7 +1534,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 9979ba80a649ee61d9d174dc9d9fcab7e9fc1332 -R 92d61cb2d5bdcee0374dbd9c4ae6bd21 +P abeddb6d5a4040e1d0a87a4f32ad79794ba0842b +R 0b6428f20f271d9267866f8abeb28948 U drh -Z 31a59b2224bec36ffef21dc37a376954 +Z c9fbc8dd9eccb05e2261cb73023007c2 diff --git a/manifest.uuid b/manifest.uuid index 659aa4015d..aae65b2c2f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -abeddb6d5a4040e1d0a87a4f32ad79794ba0842b \ No newline at end of file +32be7aae92ee48bf2cd260ea41e79c2bc62738f9 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 895e8009ed..d4f0e067f0 100644 --- a/src/btree.c +++ b/src/btree.c @@ -8578,27 +8578,7 @@ static int btreeDropTable(Btree *p, Pgno iTable, int *piMoved){ assert( sqlite3BtreeHoldsMutex(p) ); assert( p->inTrans==TRANS_WRITE ); - - /* It is illegal to drop a table if any cursors are open on the - ** database. This is because in auto-vacuum mode the backend may - ** need to move another root-page to fill a gap left by the deleted - ** root page. If an open cursor was using this page a problem would - ** occur. - ** - ** This error is caught long before control reaches this point. - */ - if( NEVER(pBt->pCursor) ){ - sqlite3ConnectionBlocked(p->db, pBt->pCursor->pBtree->db); - return SQLITE_LOCKED_SHAREDCACHE; - } - - /* - ** It is illegal to drop the sqlite_master table on page 1. But again, - ** this error is caught long before reaching this point. - */ - if( NEVER(iTable<2) ){ - return SQLITE_CORRUPT_BKPT; - } + assert( iTable>=2 ); rc = btreeGetPage(pBt, (Pgno)iTable, &pPage, 0); if( rc ) return rc; diff --git a/src/delete.c b/src/delete.c index e16e9485b2..46af65a361 100644 --- a/src/delete.c +++ b/src/delete.c @@ -538,14 +538,6 @@ void sqlite3DeleteFrom( sqlite3VdbeGoto(v, addrLoop); sqlite3VdbeJumpHere(v, addrLoop); } - - /* Close the cursors open on the table and its indexes. */ - if( !isView && !IsVirtual(pTab) ){ - if( !pPk ) sqlite3VdbeAddOp1(v, OP_Close, iDataCur); - for(i=0, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){ - sqlite3VdbeAddOp1(v, OP_Close, iIdxCur + i); - } - } } /* End non-truncate path */ /* Update the sqlite_sequence table by storing the content of the diff --git a/src/update.c b/src/update.c index 6838c74398..b370a4ec1a 100644 --- a/src/update.c +++ b/src/update.c @@ -659,15 +659,6 @@ void sqlite3Update( } sqlite3VdbeResolveLabel(v, labelBreak); - /* Close all tables */ - for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){ - assert( aRegIdx ); - if( aToOpen[i+1] ){ - sqlite3VdbeAddOp2(v, OP_Close, iIdxCur+i, 0); - } - } - if( iDataCurpStmt; int iDb = sqlite3SchemaToIndex(db, pTab->pSchema); diff --git a/src/where.c b/src/where.c index ddcb2fc881..81cc1f131b 100644 --- a/src/where.c +++ b/src/where.c @@ -4911,27 +4911,6 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ continue; } - /* Close all of the cursors that were opened by sqlite3WhereBegin. - ** Except, do not close cursors that will be reused by the OR optimization - ** (WHERE_OR_SUBCLAUSE). And do not close the OP_OpenWrite cursors - ** created for the ONEPASS optimization. - */ - if( (pTab->tabFlags & TF_Ephemeral)==0 - && pTab->pSelect==0 - && (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0 - ){ - int ws = pLoop->wsFlags; - if( pWInfo->eOnePass==ONEPASS_OFF && (ws & WHERE_IDX_ONLY)==0 ){ - sqlite3VdbeAddOp1(v, OP_Close, pTabItem->iCursor); - } - if( (ws & WHERE_INDEXED)!=0 - && (ws & (WHERE_IPK|WHERE_AUTO_INDEX))==0 - && pLevel->iIdxCur!=pWInfo->aiCurOnePass[1] - ){ - sqlite3VdbeAddOp1(v, OP_Close, pLevel->iIdxCur); - } - } - /* If this scan uses an index, make VDBE code substitutions to read data ** from the index instead of from the table where possible. In some cases ** this optimization prevents the table from ever being read, which can From 50da6635163b0f3586601db51121406129bad57e Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 22 Nov 2016 19:15:05 +0000 Subject: [PATCH 1016/1484] Update requirement marks to reflect changes in wording in the documentation. No changes to code. FossilOrigin-Name: f5ac98efb5d5f7751c5c560bed9c7885e60ac4bc --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- test/e_expr.test | 21 +++++++++++---------- test/e_select.test | 4 ++-- test/tkt-80e031a00f.test | 4 ---- 5 files changed, 22 insertions(+), 25 deletions(-) diff --git a/manifest b/manifest index 12324450ae..a28a49ad80 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sunnecessary\sOP_Close\sopcodes\sfor\sa\ssize\sreduction\sand\sperformance\nincrease. -D 2016-11-22T01:26:42.349 +C Update\srequirement\smarks\sto\sreflect\schanges\sin\swording\sin\sthe\sdocumentation.\nNo\schanges\sto\scode. +D 2016-11-22T19:15:05.929 F Makefile.in 6b572807415d3f0a379cebc9461416d8df4a12c8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc bb4d970894abbbe0e88d00aac29bd52af8bc95f4 @@ -650,13 +650,13 @@ F test/e_createtable.test d4c6059d44dcd4b636de9aae322766062b471844 F test/e_delete.test ab39084f26ae1f033c940b70ebdbbd523dc4962e F test/e_droptrigger.test 3cd080807622c13e5bbb61fc9a57bd7754da2412 F test/e_dropview.test 0c9f7f60989164a70a67a9d9c26d1083bc808306 -F test/e_expr.test 1ffa8866d38e7becc76893a8829e9432050e5716 +F test/e_expr.test 3520cd3a1843ceb4facd1760f97bd0a2db4b351a F test/e_fkey.test 54cc0046d2d952d6c42b0dd94414e7a8f75f79f4 F test/e_fts3.test 5c02288842e4f941896fd44afdef564dd5fc1459 F test/e_insert.test 3de217e95094d3d165992a6de1164bbc4bd92dc7 F test/e_reindex.test 2bebf7b393e519198b7c654407221cf171a439b8 F test/e_resolve.test a61751c368b109db73df0f20fc75fb47e166b1d8 -F test/e_select.test 52692ff3849541e828ad4661fe3773a9b8711763 +F test/e_select.test 16651bb681e83a1a2875ff4a595ed2b4b4dee375 F test/e_select2.test aceb80ab927d46fba5ce7586ebabf23e2bb0604f F test/e_totalchanges.test b12ee5809d3e63aeb83238dd501a7bca7fd72c10 F test/e_update.test f46c2554d915c9197548681e8d8c33a267e84528 @@ -1192,7 +1192,7 @@ F test/tkt-78e04e52ea.test 813779f8888f3ca226df656c4eef078f9635f3c9 F test/tkt-7a31705a7e6.test e75a2bba4eec801b92c8040eb22096ac6d35e844 F test/tkt-7bbfb7d442.test 7b2cd79c7a17ae6750e75ec1a7846712a69c9d18 F test/tkt-80ba201079.test 105a721e6aad0ae3c5946d7615d1e4d03f6145b8 -F test/tkt-80e031a00f.test f50046f474ecf67ad5c50cd9200da04ff887d7cd +F test/tkt-80e031a00f.test 9ee36348b761bf7c14261e002b75a4c0d5a04d4c F test/tkt-8454a207b9.test c583a9f814a82a2b5ba95207f55001c9f0cd816c F test/tkt-868145d012.test a5f941107ece6a64410ca4755c6329b7eb57a356 F test/tkt-8c63ff0ec.test 258b7fc8d7e4e1cb5362c7d65c143528b9c4cbed @@ -1534,7 +1534,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P abeddb6d5a4040e1d0a87a4f32ad79794ba0842b -R 0b6428f20f271d9267866f8abeb28948 +P 32be7aae92ee48bf2cd260ea41e79c2bc62738f9 +R 49b4ed62c4b9622a332c802f3bc11e93 U drh -Z c9fbc8dd9eccb05e2261cb73023007c2 +Z d757a5720bbbbd29737d4e0fbf7742d9 diff --git a/manifest.uuid b/manifest.uuid index aae65b2c2f..cffc99a4c7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -32be7aae92ee48bf2cd260ea41e79c2bc62738f9 \ No newline at end of file +f5ac98efb5d5f7751c5c560bed9c7885e60ac4bc \ No newline at end of file diff --git a/test/e_expr.test b/test/e_expr.test index 6165aa3588..5b78faeefb 100644 --- a/test/e_expr.test +++ b/test/e_expr.test @@ -1786,8 +1786,8 @@ do_test e_expr-35.0 { } } {} -# EVIDENCE-OF: R-00980-39256 A SELECT statement enclosed in parentheses -# may appear as a scalar quantity. +# EVIDENCE-OF: R-43573-23448 A SELECT statement enclosed in parentheses +# is a subquery. # # EVIDENCE-OF: R-56294-03966 All types of SELECT statement, including # aggregate and compound SELECT queries (queries with keywords like @@ -1806,8 +1806,9 @@ do_expr_test e_expr-35.1.6 { (SELECT a FROM t2 UNION SELECT COALESCE(b, 55) FROM t2 ORDER BY 1) } integer 4 -# EVIDENCE-OF: R-46899-53765 A SELECT used as a scalar quantity must -# return a result set with a single column. +# EVIDENCE-OF: R-22239-33740 A subquery that returns two or more columns +# is a row value subquery and can only be used as the operand of a +# comparison operator. # # The following block tests that errors are returned in a bunch of cases # where a subquery returns more than one column. @@ -1824,11 +1825,11 @@ foreach {tn sql} { do_catchsql_test e_expr-35.2.$tn $sql $M } -# EVIDENCE-OF: R-35764-28041 The result of the expression is the value -# of the only column in the first row returned by the SELECT statement. +# EVIDENCE-OF: R-18318-14995 The value of a subquery expression is the +# first row of the result from the enclosed SELECT statement. # -# EVIDENCE-OF: R-41898-06686 If the SELECT yields more than one result -# row, all rows after the first are ignored. +# EVIDENCE-OF: R-15900-52156 In other words, an implied "LIMIT 1" is +# added to the subquery, overriding an explicitly coded LIMIT. # do_execsql_test e_expr-36.3.1 { CREATE TABLE t4(x, y); @@ -1852,8 +1853,8 @@ foreach {tn expr restype resval} { do_expr_test e_expr-36.3.$tn $expr $restype $resval } -# EVIDENCE-OF: R-25492-41572 If the SELECT yields no rows, then the -# value of the expression is NULL. +# EVIDENCE-OF: R-52325-25449 The value of a subquery expression is NULL +# if the enclosed SELECT statement returns no rows. # foreach {tn expr} { 1 { ( SELECT x FROM t4 WHERE x>3 ORDER BY x ) } diff --git a/test/e_select.test b/test/e_select.test index 89d61b53bc..9aa2de6038 100644 --- a/test/e_select.test +++ b/test/e_select.test @@ -1252,8 +1252,8 @@ do_select_tests e_select-5.5 { 1 "SELECT DISTINCT d FROM h3" {{} 2 2,3 2,4 3} } -# EVIDENCE-OF: R-58359-52112 The normal rules for selecting a collation -# sequence to compare text values with apply. +# EVIDENCE-OF: R-47709-27231 The usual rules apply for selecting a +# collation sequence to compare text values. # do_select_tests e_select-5.6 { 1 "SELECT DISTINCT b FROM h1" {one I i four IV iv} diff --git a/test/tkt-80e031a00f.test b/test/tkt-80e031a00f.test index af1d636eed..4ad0a772a5 100644 --- a/test/tkt-80e031a00f.test +++ b/test/tkt-80e031a00f.test @@ -20,10 +20,6 @@ source $testdir/tester.tcl source $testdir/lock_common.tcl source $testdir/malloc_common.tcl -# EVIDENCE-OF: R-58875-56087 The IN and NOT IN operators take a single -# scalar operand on the left and a vector operand on the right formed by -# an explicit list of zero or more scalars or by a single subquery. -# # EVIDENCE-OF: R-52275-55503 When the right operand is an empty set, the # result of IN is false and the result of NOT IN is true, regardless of # the left operand and even if the left operand is NULL. From e74cc5c9bc7414158b5f51c620a0052eb9ed4741 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 22 Nov 2016 20:29:05 +0000 Subject: [PATCH 1017/1484] Add a new requirement mark for CAST expressions. FossilOrigin-Name: bee2859b953c935c413de2917588159d03c672d9 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/e_expr.test | 7 +++++++ 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index a28a49ad80..abe18f7860 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\srequirement\smarks\sto\sreflect\schanges\sin\swording\sin\sthe\sdocumentation.\nNo\schanges\sto\scode. -D 2016-11-22T19:15:05.929 +C Add\sa\snew\srequirement\smark\sfor\sCAST\sexpressions. +D 2016-11-22T20:29:05.473 F Makefile.in 6b572807415d3f0a379cebc9461416d8df4a12c8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc bb4d970894abbbe0e88d00aac29bd52af8bc95f4 @@ -650,7 +650,7 @@ F test/e_createtable.test d4c6059d44dcd4b636de9aae322766062b471844 F test/e_delete.test ab39084f26ae1f033c940b70ebdbbd523dc4962e F test/e_droptrigger.test 3cd080807622c13e5bbb61fc9a57bd7754da2412 F test/e_dropview.test 0c9f7f60989164a70a67a9d9c26d1083bc808306 -F test/e_expr.test 3520cd3a1843ceb4facd1760f97bd0a2db4b351a +F test/e_expr.test d0dd488e0527cbc560ae2dea1939cc44cb9b9924 F test/e_fkey.test 54cc0046d2d952d6c42b0dd94414e7a8f75f79f4 F test/e_fts3.test 5c02288842e4f941896fd44afdef564dd5fc1459 F test/e_insert.test 3de217e95094d3d165992a6de1164bbc4bd92dc7 @@ -1534,7 +1534,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 32be7aae92ee48bf2cd260ea41e79c2bc62738f9 -R 49b4ed62c4b9622a332c802f3bc11e93 +P f5ac98efb5d5f7751c5c560bed9c7885e60ac4bc +R 7f4eeea43dc88b31022d41b7c5421073 U drh -Z d757a5720bbbbd29737d4e0fbf7742d9 +Z a9cabf6ebd1d5980aefc6cb67510aa1c diff --git a/manifest.uuid b/manifest.uuid index cffc99a4c7..c87379ecc7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f5ac98efb5d5f7751c5c560bed9c7885e60ac4bc \ No newline at end of file +bee2859b953c935c413de2917588159d03c672d9 \ No newline at end of file diff --git a/test/e_expr.test b/test/e_expr.test index 5b78faeefb..de7b43c92e 100644 --- a/test/e_expr.test +++ b/test/e_expr.test @@ -1437,6 +1437,13 @@ do_expr_test e_expr-27.2.2 { CAST(NULL AS text) } null {} do_expr_test e_expr-27.2.3 { CAST(NULL AS blob) } null {} do_expr_test e_expr-27.2.4 { CAST(NULL AS number) } null {} +# EVIDENCE-OF: R-29283-15561 Otherwise, the storage class of the result +# is determined by applying the rules for determining column affinity to +# the type-name. +# +# The R-29283-15561 requirement above is demonstrated by all of the +# subsequent e_expr-26 tests. +# # EVIDENCE-OF: R-43522-35548 Casting a value to a type-name with no # affinity causes the value to be converted into a BLOB. # From bc88711d08602b00b591bf1f127b1d4a9d8b310d Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 22 Nov 2016 21:11:59 +0000 Subject: [PATCH 1018/1484] Enclose the sqlite3WalSnapshotRecover() routine within FossilOrigin-Name: e7be3183eb25e0f9f04b9e251ff37fa5e50cc1a7 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/wal.c | 2 ++ 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 21ea07385c..8112830311 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sthe\srequirement\sto\sopen\sthe\swal\sfile\sbefore\ssqlite3_snapshot_recover()\nis\scalled.\sAlso\sadd\ssome\scomments\sto\snew\sfunctions. -D 2016-11-19T18:31:37.017 +C Enclose\sthe\ssqlite3WalSnapshotRecover()\sroutine\swithin +D 2016-11-22T21:11:59.294 F Makefile.in 6b572807415d3f0a379cebc9461416d8df4a12c8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc bb4d970894abbbe0e88d00aac29bd52af8bc95f4 @@ -465,7 +465,7 @@ F src/vdbesort.c 91fda3909326860382b0ca8aa251e609c6a9d62c F src/vdbetrace.c 41963d5376f0349842b5fc4aaaaacd7d9cdc0834 F src/vtab.c e02cacb5c7ae742631edeb9ae9f53d399f093fd8 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 -F src/wal.c 56bba6f4101b55054145ce164951bea4a1b09548 +F src/wal.c 40c543f0a2195d1b0dc88ef12142bea690009344 F src/wal.h 06b2a0b599cc0f53ea97f497cf8c6b758c999f71 F src/walker.c 91a6df7435827e41cff6bb7df50ea00934ee78b0 F src/where.c 952f76e7a03727480b274b66ca6641b1657cd591 @@ -1535,7 +1535,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P db314213c08f27dd0ff5ede3c6a8eda36560809a -R 0c1e63a3653bf6d9b725483fda2de4a1 -U dan -Z 573fa32a4bef0fb7a3cf7415ded5b3fe +P 28393c413cc4505b94411730e728583c5d4baaae +R 87af84aaf5faeefdf69427a408fd9884 +U drh +Z eaed2a9cb4277f14d0de83d53d00fc85 diff --git a/manifest.uuid b/manifest.uuid index d4754cb8fa..f2d1cc2d07 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -28393c413cc4505b94411730e728583c5d4baaae \ No newline at end of file +e7be3183eb25e0f9f04b9e251ff37fa5e50cc1a7 \ No newline at end of file diff --git a/src/wal.c b/src/wal.c index 52e44ad550..09f605fe57 100644 --- a/src/wal.c +++ b/src/wal.c @@ -2379,6 +2379,7 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){ return rc; } +#ifdef SQLITE_ENABLE_SNAPSHOT /* ** Attempt to reduce the value of the WalCkptInfo.nBackfillAttempted ** variable so that older snapshots can be accessed. To do this, loop @@ -2454,6 +2455,7 @@ int sqlite3WalSnapshotRecover(Wal *pWal){ return rc; } +#endif /* SQLITE_ENABLE_SNAPSHOT */ /* ** Begin a read transaction on the database. From 30642cf4d2007a9832e6325290ed96f42e396a98 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 23 Nov 2016 14:19:11 +0000 Subject: [PATCH 1019/1484] Correctly display the names of SQL functions in the VDBE_PROFILE output. FossilOrigin-Name: 161192f17273f32f1b3b82d41135aaca047e9a83 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbeaux.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index abe18f7860..aea8bb2bc4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sa\snew\srequirement\smark\sfor\sCAST\sexpressions. -D 2016-11-22T20:29:05.473 +C Correctly\sdisplay\sthe\snames\sof\sSQL\sfunctions\sin\sthe\sVDBE_PROFILE\soutput. +D 2016-11-23T14:19:11.143 F Makefile.in 6b572807415d3f0a379cebc9461416d8df4a12c8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc bb4d970894abbbe0e88d00aac29bd52af8bc95f4 @@ -458,7 +458,7 @@ F src/vdbe.c e76ee960a2e6d099838173599ae2d0999dc3aa63 F src/vdbe.h c044be7050ac6bf596eecc6ab159f5dbc020a3b7 F src/vdbeInt.h 29b25318a0286c4b2599c0fbef6acf524398489a F src/vdbeapi.c 97129bec6b1553da50d8e73f523c278bda66d9f6 -F src/vdbeaux.c 52d9b840859f260ce8418be9333dd77c902e1c74 +F src/vdbeaux.c c0adf6e1ce14e0b511fbeb71aa3ef1d603051b71 F src/vdbeblob.c ba5b57b9fa47b320ad5c46468e77d8660c931190 F src/vdbemem.c fcdd73a2001a673f48a244a77b1038928ae729c9 F src/vdbesort.c 91fda3909326860382b0ca8aa251e609c6a9d62c @@ -1534,7 +1534,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P f5ac98efb5d5f7751c5c560bed9c7885e60ac4bc -R 7f4eeea43dc88b31022d41b7c5421073 +P bee2859b953c935c413de2917588159d03c672d9 +R 2c4c0cbde8a5576e7dee09bc8f314063 U drh -Z a9cabf6ebd1d5980aefc6cb67510aa1c +Z d768832216e311c9257ef81108e44f2d diff --git a/manifest.uuid b/manifest.uuid index c87379ecc7..ef0d8075a9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bee2859b953c935c413de2917588159d03c672d9 \ No newline at end of file +161192f17273f32f1b3b82d41135aaca047e9a83 \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 596ab30c7b..66e076e4c8 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -1271,7 +1271,7 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){ sqlite3XPrintf(&x, "%s(%d)", pDef->zName, pDef->nArg); break; } -#ifdef SQLITE_DEBUG +#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) case P4_FUNCCTX: { FuncDef *pDef = pOp->p4.pCtx->pFunc; sqlite3XPrintf(&x, "%s(%d)", pDef->zName, pDef->nArg); From 4b72524072e6a0ba2ebbaf42c623eb76a69b0270 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 23 Nov 2016 19:31:18 +0000 Subject: [PATCH 1020/1484] Code constant vector components outside of any loops in CASE and BETWEEN expressions. Fix for [1a684656]. FossilOrigin-Name: c08aff13ead3e6a8b92c0f031b08f7e556922e70 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/expr.c | 2 +- test/rowvalue.test | 14 ++++++++++++++ 4 files changed, 24 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index aea8bb2bc4..7013604693 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Correctly\sdisplay\sthe\snames\sof\sSQL\sfunctions\sin\sthe\sVDBE_PROFILE\soutput. -D 2016-11-23T14:19:11.143 +C Code\sconstant\svector\scomponents\soutside\sof\sany\sloops\sin\sCASE\sand\sBETWEEN\nexpressions.\sFix\sfor\s[1a684656]. +D 2016-11-23T19:31:18.510 F Makefile.in 6b572807415d3f0a379cebc9461416d8df4a12c8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc bb4d970894abbbe0e88d00aac29bd52af8bc95f4 @@ -340,7 +340,7 @@ F src/ctime.c a2a52d6e353f459d8ab0f07321f60fafa47d5421 F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c 99949851e8e9ea4e1db739b0d354d360e1f80f2b -F src/expr.c d8c8277d77e95d7fcce3b6b6d0f66652e482567f +F src/expr.c b64811af00daf50c28abf55eb7aaa8fddfc1bd9e F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c b9ca262f6ad4d030a3cab737ebf9b0b3c8b4ac80 F src/func.c 7057bc2c105b82faa668d8e2ec85fad4540e5c51 @@ -1031,7 +1031,7 @@ F test/rollbackfault.test 0e646aeab8840c399cfbfa43daab46fd609cf04a F test/rowallock.test 3f88ec6819489d0b2341c7a7528ae17c053ab7cc F test/rowhash.test 0bc1d31415e4575d10cacf31e1a66b5cc0f8be81 F test/rowid.test 5b7509f384f4f6fae1af3c8c104c8ca299fea18d -F test/rowvalue.test b5a9c0fa347a763c558da2397499df51da3cdf6b +F test/rowvalue.test f4dc97fe52d4e206e25b3395588b9497a8eed3ff F test/rowvalue2.test 060d238b7e5639a7c5630cb5e63e311b44efef2b F test/rowvalue3.test 3068f508753af69884b12125995f023da0dbb256 F test/rowvalue4.test 4b556d7de161a0dd8cff095c336e913986398bea @@ -1534,7 +1534,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P bee2859b953c935c413de2917588159d03c672d9 -R 2c4c0cbde8a5576e7dee09bc8f314063 -U drh -Z d768832216e311c9257ef81108e44f2d +P 161192f17273f32f1b3b82d41135aaca047e9a83 +R 341e1eecb334b8adf0209376efd6d1b8 +U dan +Z 964cce392c039cd22f462b9221e4b3a8 diff --git a/manifest.uuid b/manifest.uuid index ef0d8075a9..cf06120f6a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -161192f17273f32f1b3b82d41135aaca047e9a83 \ No newline at end of file +c08aff13ead3e6a8b92c0f031b08f7e556922e70 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 639bafe0b5..ffbafb0aa6 100644 --- a/src/expr.c +++ b/src/expr.c @@ -3296,7 +3296,7 @@ static int exprCodeVector(Parse *pParse, Expr *p, int *piFreeable){ iResult = pParse->nMem+1; pParse->nMem += nResult; for(i=0; ix.pList->a[i].pExpr, i+iResult); + sqlite3ExprCodeFactorable(pParse, p->x.pList->a[i].pExpr, i+iResult); } } } diff --git a/test/rowvalue.test b/test/rowvalue.test index 231565a4be..0df2e734c6 100644 --- a/test/rowvalue.test +++ b/test/rowvalue.test @@ -278,5 +278,19 @@ foreach {tn sql} { do_catchsql_test 13.$tn $sql {1 {row value misused}} } +do_execsql_test 14.0 { + CREATE TABLE t12(x); + INSERT INTO t12 VALUES(2), (4); +} +do_execsql_test 14.1 "SELECT 1 WHERE (2,2) BETWEEN (1,1) AND (3,3)" 1 +do_execsql_test 14.2 "SELECT CASE (2,2) WHEN (1, 1) THEN 2 ELSE 1 END" 1 +do_execsql_test 14.3 "SELECT CASE (SELECT 2,2) WHEN (1, 1) THEN 2 ELSE 1 END" 1 +do_execsql_test 14.4 "SELECT 1 WHERE (SELECT 2,2) BETWEEN (1,1) AND (3,3)" 1 +do_execsql_test 14.5 "SELECT 1 FROM t12 WHERE (x,1) BETWEEN (1,1) AND (3,3)" 1 +do_execsql_test 14.6 { + SELECT 1 FROM t12 WHERE (1,x) BETWEEN (1,1) AND (3,3) +} {1 1} finish_test + + From 36f49d05650bd928eea77934172b9feae497f659 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 23 Nov 2016 23:18:45 +0000 Subject: [PATCH 1021/1484] Fix the error message for invalid ".mode" arguments in the command-line shell, so that it mentions the new "quote" mode. FossilOrigin-Name: 9a603a18ef626b7d7a24b82eb961d6d8b4926195 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/shell.c | 2 +- test/shell1.test | 14 +++++++------- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/manifest b/manifest index 7013604693..2f5c533a66 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Code\sconstant\svector\scomponents\soutside\sof\sany\sloops\sin\sCASE\sand\sBETWEEN\nexpressions.\sFix\sfor\s[1a684656]. -D 2016-11-23T19:31:18.510 +C Fix\sthe\serror\smessage\sfor\sinvalid\s".mode"\sarguments\sin\sthe\scommand-line\sshell,\nso\sthat\sit\smentions\sthe\snew\s"quote"\smode. +D 2016-11-23T23:18:45.525 F Makefile.in 6b572807415d3f0a379cebc9461416d8df4a12c8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc bb4d970894abbbe0e88d00aac29bd52af8bc95f4 @@ -388,7 +388,7 @@ F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c bb070cf5f23611c44ab7e4788803684e385fc3fb F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c 672b1af237ad257149fc5189f3277dcbca036eeb -F src/shell.c b6ba45f741cc0e56ec7a3504855fe1373def2e16 +F src/shell.c a3fc2c719ed6d381895cbdb66a4a9b6a791cb02e F src/sqlite.h.in 803f7050f69b2eea573fac219f3c92582c096027 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae @@ -1088,7 +1088,7 @@ F test/sharedA.test 0cdf1a76dfa00e6beee66af5b534b1e8df2720f5 F test/sharedB.test 16cc7178e20965d75278f410943109b77b2e645e F test/shared_err.test 2f2aee20db294b9924e81f6ccbe60f19e21e8506 F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304 -F test/shell1.test 65b10cd8a90cda9b5af9100a45689a57dcc01a31 +F test/shell1.test 8ff47a4821570b99cc340c4da0ac4efe2ba06627 F test/shell2.test e242a9912f44f4c23c3d1d802a83e934e84c853b F test/shell3.test 9b95ba643eaa228376f06a898fb410ee9b6e57c1 F test/shell4.test 89ad573879a745974ff2df20ff97c5d6ffffbd5d @@ -1534,7 +1534,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 161192f17273f32f1b3b82d41135aaca047e9a83 -R 341e1eecb334b8adf0209376efd6d1b8 -U dan -Z 964cce392c039cd22f462b9221e4b3a8 +P c08aff13ead3e6a8b92c0f031b08f7e556922e70 +R 199e8bdbbce6038cd06aa9b67980383f +U drh +Z 0dd279d9766d052bb409f9a65270d351 diff --git a/manifest.uuid b/manifest.uuid index cf06120f6a..ce01924e72 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c08aff13ead3e6a8b92c0f031b08f7e556922e70 \ No newline at end of file +9a603a18ef626b7d7a24b82eb961d6d8b4926195 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 1cc4cc2230..148a534b86 100644 --- a/src/shell.c +++ b/src/shell.c @@ -4079,7 +4079,7 @@ static int do_meta_command(char *zLine, ShellState *p){ sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Record); }else { raw_printf(stderr, "Error: mode should be one of: " - "ascii column csv html insert line list tabs tcl\n"); + "ascii column csv html insert line list quote tabs tcl\n"); rc = 1; } p->cMode = p->mode; diff --git a/test/shell1.test b/test/shell1.test index 9a966fd8db..9400d75296 100644 --- a/test/shell1.test +++ b/test/shell1.test @@ -199,10 +199,10 @@ do_test shell1-2.2.4 { } {0 {}} do_test shell1-2.2.5 { catchcmd "test.db" ".mode \"insert FOO" -} {1 {Error: mode should be one of: ascii column csv html insert line list tabs tcl}} +} {1 {Error: mode should be one of: ascii column csv html insert line list quote tabs tcl}} do_test shell1-2.2.6 { catchcmd "test.db" ".mode \'insert FOO" -} {1 {Error: mode should be one of: ascii column csv html insert line list tabs tcl}} +} {1 {Error: mode should be one of: ascii column csv html insert line list quote tabs tcl}} # check multiple tokens, and quoted tokens do_test shell1-2.3.1 { @@ -230,7 +230,7 @@ do_test shell1-2.3.7 { # check quoted args are unquoted do_test shell1-2.4.1 { catchcmd "test.db" ".mode FOO" -} {1 {Error: mode should be one of: ascii column csv html insert line list tabs tcl}} +} {1 {Error: mode should be one of: ascii column csv html insert line list quote tabs tcl}} do_test shell1-2.4.2 { catchcmd "test.db" ".mode csv" } {0 {}} @@ -427,10 +427,10 @@ do_test shell1-3.12.3 { # tcl TCL list elements do_test shell1-3.13.1 { catchcmd "test.db" ".mode" -} {1 {Error: mode should be one of: ascii column csv html insert line list tabs tcl}} +} {1 {Error: mode should be one of: ascii column csv html insert line list quote tabs tcl}} do_test shell1-3.13.2 { catchcmd "test.db" ".mode FOO" -} {1 {Error: mode should be one of: ascii column csv html insert line list tabs tcl}} +} {1 {Error: mode should be one of: ascii column csv html insert line list quote tabs tcl}} do_test shell1-3.13.3 { catchcmd "test.db" ".mode csv" } {0 {}} @@ -463,10 +463,10 @@ do_test shell1-3.13.11 { # don't allow partial mode type matches do_test shell1-3.13.12 { catchcmd "test.db" ".mode l" -} {1 {Error: mode should be one of: ascii column csv html insert line list tabs tcl}} +} {1 {Error: mode should be one of: ascii column csv html insert line list quote tabs tcl}} do_test shell1-3.13.13 { catchcmd "test.db" ".mode li" -} {1 {Error: mode should be one of: ascii column csv html insert line list tabs tcl}} +} {1 {Error: mode should be one of: ascii column csv html insert line list quote tabs tcl}} do_test shell1-3.13.14 { catchcmd "test.db" ".mode lin" } {0 {}} From 36fd41e52b8c8eba02c2fa89e1a39afa7c7e9907 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 25 Nov 2016 14:30:42 +0000 Subject: [PATCH 1022/1484] Add a comment to help clarify the EP_FromJoin hack in exprCodeBetween(). FossilOrigin-Name: 6df7c5747e0247b14bf015ef4320ddcf6fccf694 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/expr.c | 5 +++++ 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 2f5c533a66..4349d03c88 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\serror\smessage\sfor\sinvalid\s".mode"\sarguments\sin\sthe\scommand-line\sshell,\nso\sthat\sit\smentions\sthe\snew\s"quote"\smode. -D 2016-11-23T23:18:45.525 +C Add\sa\scomment\sto\shelp\sclarify\sthe\sEP_FromJoin\shack\sin\sexprCodeBetween(). +D 2016-11-25T14:30:42.666 F Makefile.in 6b572807415d3f0a379cebc9461416d8df4a12c8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc bb4d970894abbbe0e88d00aac29bd52af8bc95f4 @@ -340,7 +340,7 @@ F src/ctime.c a2a52d6e353f459d8ab0f07321f60fafa47d5421 F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c 99949851e8e9ea4e1db739b0d354d360e1f80f2b -F src/expr.c b64811af00daf50c28abf55eb7aaa8fddfc1bd9e +F src/expr.c 8c224aa28278a5c1eed55247b7a571ff388ad5c2 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c b9ca262f6ad4d030a3cab737ebf9b0b3c8b4ac80 F src/func.c 7057bc2c105b82faa668d8e2ec85fad4540e5c51 @@ -1534,7 +1534,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P c08aff13ead3e6a8b92c0f031b08f7e556922e70 -R 199e8bdbbce6038cd06aa9b67980383f +P 9a603a18ef626b7d7a24b82eb961d6d8b4926195 +R ef9f01036377c9e5a69b01dd8a74832e U drh -Z 0dd279d9766d052bb409f9a65270d351 +Z 1cc8fc31dc9cfa12819270a952431b2f diff --git a/manifest.uuid b/manifest.uuid index ce01924e72..1b68bc8bdc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9a603a18ef626b7d7a24b82eb961d6d8b4926195 \ No newline at end of file +6df7c5747e0247b14bf015ef4320ddcf6fccf694 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index ffbafb0aa6..2f7deeea9a 100644 --- a/src/expr.c +++ b/src/expr.c @@ -4167,6 +4167,11 @@ static void exprCodeBetween( if( xJump ){ xJump(pParse, &exprAnd, dest, jumpIfNull); }else{ + /* Mark the expression is being from the ON or USING clause of a join + ** so that the sqlite3ExprCodeTarget() routine will not attempt to move + ** it into the Parse.pConstExpr list. We should use a new bit for this, + ** for clarity, but we are out of bits in the Expr.flags field so we + ** have to reuse the EP_FromJoin bit. Bummer. */ exprX.flags |= EP_FromJoin; sqlite3ExprCodeTarget(pParse, &exprAnd, dest); } From 043e586e29572d447302fd95987d673d5f0438b7 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 25 Nov 2016 15:11:26 +0000 Subject: [PATCH 1023/1484] Performance improvement in sqlite3StrAccumFinish() for the common case where no memory allocation is required. FossilOrigin-Name: b6acf5d4ef016326a079463e70e71c2fc95a352d --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/printf.c | 19 ++++++++++++------- 3 files changed, 19 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index 4349d03c88..242a15cf54 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sa\scomment\sto\shelp\sclarify\sthe\sEP_FromJoin\shack\sin\sexprCodeBetween(). -D 2016-11-25T14:30:42.666 +C Performance\simprovement\sin\ssqlite3StrAccumFinish()\sfor\sthe\scommon\scase\swhere\nno\smemory\sallocation\sis\srequired. +D 2016-11-25T15:11:26.619 F Makefile.in 6b572807415d3f0a379cebc9461416d8df4a12c8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc bb4d970894abbbe0e88d00aac29bd52af8bc95f4 @@ -383,7 +383,7 @@ F src/pcache1.c e3967219b2a92b9edcb9324a4ba75009090d3953 F src/pragma.c d932ba278654617cdd281f88a790a3185fca7c44 F src/pragma.h 64c78a648751b9f4f297276c4eb7507b14b4628c F src/prepare.c b1140c3d0cf59bc85ace00ce363153041b424b7a -F src/printf.c a5f0ca08ddede803c241266abb46356ec748ded1 +F src/printf.c 8a76e8e9b44a282bd78f5a4113e4dec233c3dfff F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c bb070cf5f23611c44ab7e4788803684e385fc3fb F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac @@ -1534,7 +1534,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 9a603a18ef626b7d7a24b82eb961d6d8b4926195 -R ef9f01036377c9e5a69b01dd8a74832e +P 6df7c5747e0247b14bf015ef4320ddcf6fccf694 +R 52321675b69054515968315ac6e47ed5 U drh -Z 1cc8fc31dc9cfa12819270a952431b2f +Z 9d212a5ec3719e9483eacdb11891359b diff --git a/manifest.uuid b/manifest.uuid index 1b68bc8bdc..ffa66fcd74 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6df7c5747e0247b14bf015ef4320ddcf6fccf694 \ No newline at end of file +b6acf5d4ef016326a079463e70e71c2fc95a352d \ No newline at end of file diff --git a/src/printf.c b/src/printf.c index a888d50b94..563f37c6a6 100644 --- a/src/printf.c +++ b/src/printf.c @@ -861,18 +861,23 @@ void sqlite3StrAccumAppendAll(StrAccum *p, const char *z){ ** Return a pointer to the resulting string. Return a NULL ** pointer if any kind of error was encountered. */ +static SQLITE_NOINLINE char *strAccumFinishRealloc(StrAccum *p){ + assert( p->mxAlloc>0 && !isMalloced(p) ); + p->zText = sqlite3DbMallocRaw(p->db, p->nChar+1 ); + if( p->zText ){ + memcpy(p->zText, p->zBase, p->nChar+1); + p->printfFlags |= SQLITE_PRINTF_MALLOCED; + }else{ + setStrAccumError(p, STRACCUM_NOMEM); + } + return p->zText; +} char *sqlite3StrAccumFinish(StrAccum *p){ if( p->zText ){ assert( (p->zText==p->zBase)==!isMalloced(p) ); p->zText[p->nChar] = 0; if( p->mxAlloc>0 && !isMalloced(p) ){ - p->zText = sqlite3DbMallocRaw(p->db, p->nChar+1 ); - if( p->zText ){ - memcpy(p->zText, p->zBase, p->nChar+1); - p->printfFlags |= SQLITE_PRINTF_MALLOCED; - }else{ - setStrAccumError(p, STRACCUM_NOMEM); - } + return strAccumFinishRealloc(p); } } return p->zText; From e9bb566096da8f50f556a15eaa41e8c592409653 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 25 Nov 2016 15:47:53 +0000 Subject: [PATCH 1024/1484] Performance enhancement to sqlite3_snprintf(). FossilOrigin-Name: c53dca7fadd81ea340fef776373cbb122c9ccd46 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/printf.c | 3 ++- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 242a15cf54..42d8f60af9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Performance\simprovement\sin\ssqlite3StrAccumFinish()\sfor\sthe\scommon\scase\swhere\nno\smemory\sallocation\sis\srequired. -D 2016-11-25T15:11:26.619 +C Performance\senhancement\sto\ssqlite3_snprintf(). +D 2016-11-25T15:47:53.375 F Makefile.in 6b572807415d3f0a379cebc9461416d8df4a12c8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc bb4d970894abbbe0e88d00aac29bd52af8bc95f4 @@ -383,7 +383,7 @@ F src/pcache1.c e3967219b2a92b9edcb9324a4ba75009090d3953 F src/pragma.c d932ba278654617cdd281f88a790a3185fca7c44 F src/pragma.h 64c78a648751b9f4f297276c4eb7507b14b4628c F src/prepare.c b1140c3d0cf59bc85ace00ce363153041b424b7a -F src/printf.c 8a76e8e9b44a282bd78f5a4113e4dec233c3dfff +F src/printf.c f94da4935d1dd25420ac50c6745db1deb35e07c1 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c bb070cf5f23611c44ab7e4788803684e385fc3fb F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac @@ -1534,7 +1534,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 6df7c5747e0247b14bf015ef4320ddcf6fccf694 -R 52321675b69054515968315ac6e47ed5 +P b6acf5d4ef016326a079463e70e71c2fc95a352d +R 66214ce5c9237cac8843327752704c96 U drh -Z 9d212a5ec3719e9483eacdb11891359b +Z 00ed6ef21d5c142098e92d37ff95081c diff --git a/manifest.uuid b/manifest.uuid index ffa66fcd74..a717baef40 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b6acf5d4ef016326a079463e70e71c2fc95a352d \ No newline at end of file +c53dca7fadd81ea340fef776373cbb122c9ccd46 \ No newline at end of file diff --git a/src/printf.c b/src/printf.c index 563f37c6a6..8de0a924ae 100644 --- a/src/printf.c +++ b/src/printf.c @@ -1017,7 +1017,8 @@ char *sqlite3_vsnprintf(int n, char *zBuf, const char *zFormat, va_list ap){ #endif sqlite3StrAccumInit(&acc, 0, zBuf, n, 0); sqlite3VXPrintf(&acc, zFormat, ap); - return sqlite3StrAccumFinish(&acc); + zBuf[acc.nChar] = 0; + return zBuf; } char *sqlite3_snprintf(int n, char *zBuf, const char *zFormat, ...){ char *z; From 06a09a828addd181074086389b83a283f523458b Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 25 Nov 2016 17:03:03 +0000 Subject: [PATCH 1025/1484] Small performance increase and size reduction in the OP_Column opcode. FossilOrigin-Name: a9498407e646305e7b60115d63e85c642bbd1c3f --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 9 +++++---- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 42d8f60af9..9e99dd58e1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Performance\senhancement\sto\ssqlite3_snprintf(). -D 2016-11-25T15:47:53.375 +C Small\sperformance\sincrease\sand\ssize\sreduction\sin\sthe\sOP_Column\sopcode. +D 2016-11-25T17:03:03.293 F Makefile.in 6b572807415d3f0a379cebc9461416d8df4a12c8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc bb4d970894abbbe0e88d00aac29bd52af8bc95f4 @@ -454,7 +454,7 @@ F src/update.c 68714ed42a506d782a3d75ff8f09640706d6a3b2 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 3e2da6101888d073e79ecc6af5e0a2f70fa1e498 F src/vacuum.c 33c174b28886b2faf26e503b5a49a1c01a9b1c16 -F src/vdbe.c e76ee960a2e6d099838173599ae2d0999dc3aa63 +F src/vdbe.c 54a1d3e143a87ebcd355c956999b667dcfb64824 F src/vdbe.h c044be7050ac6bf596eecc6ab159f5dbc020a3b7 F src/vdbeInt.h 29b25318a0286c4b2599c0fbef6acf524398489a F src/vdbeapi.c 97129bec6b1553da50d8e73f523c278bda66d9f6 @@ -1534,7 +1534,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b6acf5d4ef016326a079463e70e71c2fc95a352d -R 66214ce5c9237cac8843327752704c96 +P c53dca7fadd81ea340fef776373cbb122c9ccd46 +R 5cc42cc506bbe372234cb9f20b970e00 U drh -Z 00ed6ef21d5c142098e92d37ff95081c +Z dac9238c0e962ec79642eb1c1f1654f2 diff --git a/manifest.uuid b/manifest.uuid index a717baef40..3a997e9a3c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c53dca7fadd81ea340fef776373cbb122c9ccd46 \ No newline at end of file +a9498407e646305e7b60115d63e85c642bbd1c3f \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 9cf62f33bf..9f57b47480 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2470,7 +2470,6 @@ case OP_Column: { assert( pC->eCurType!=CURTYPE_VTAB ); assert( pC->eCurType!=CURTYPE_PSEUDO || pC->nullRow ); assert( pC->eCurType!=CURTYPE_SORTER ); - pCrsr = pC->uc.pCursor; if( pC->cacheStatus!=p->cacheCtr ){ /*OPTIMIZATION-IF-FALSE*/ if( pC->nullRow ){ @@ -2486,6 +2485,7 @@ case OP_Column: { goto op_column_out; } }else{ + pCrsr = pC->uc.pCursor; assert( pC->eCurType==CURTYPE_BTREE ); assert( pCrsr ); assert( sqlite3BtreeCursorIsValid(pCrsr) ); @@ -2549,7 +2549,8 @@ case OP_Column: { /* Make sure zData points to enough of the record to cover the header. */ if( pC->aRow==0 ){ memset(&sMem, 0, sizeof(sMem)); - rc = sqlite3VdbeMemFromBtree(pCrsr, 0, aOffset[0], !pC->isTable, &sMem); + rc = sqlite3VdbeMemFromBtree(pC->uc.pCursor, 0, aOffset[0], + !pC->isTable, &sMem); if( rc!=SQLITE_OK ) goto abort_due_to_error; zData = (u8*)sMem.z; }else{ @@ -2662,8 +2663,8 @@ case OP_Column: { static u8 aZero[8]; /* This is the bogus content */ sqlite3VdbeSerialGet(aZero, t, pDest); }else{ - rc = sqlite3VdbeMemFromBtree(pCrsr, aOffset[p2], len, !pC->isTable, - pDest); + rc = sqlite3VdbeMemFromBtree(pC->uc.pCursor, aOffset[p2], len, + !pC->isTable, pDest); if( rc!=SQLITE_OK ) goto abort_due_to_error; sqlite3VdbeSerialGet((const u8*)pDest->z, t, pDest); pDest->flags &= ~MEM_Ephem; From cb3cabd01b81ff1c4a31466cccef809b665a6999 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 25 Nov 2016 19:18:28 +0000 Subject: [PATCH 1026/1484] Refactor the sqlite3BtreeKey() and sqlite3BtreeData() internal interfaces into sqlite3BtreePayload() and sqlite3BtreePayloadChecked(), respectively. This is a continuation of the optimization started by check-in [2d831074cf]. The result is a slightly smaller and faster binary. FossilOrigin-Name: 49ebc219faea30eaa61def4a3fba2817b9c58a86 --- manifest | 26 +++++++++++++------------- manifest.uuid | 2 +- src/btree.c | 35 ++++++++++++++--------------------- src/btree.h | 4 ++-- src/vdbe.c | 12 +++--------- src/vdbeInt.h | 2 +- src/vdbeapi.c | 2 +- src/vdbeaux.c | 4 ++-- src/vdbeblob.c | 2 +- src/vdbemem.c | 15 ++++----------- 10 files changed, 42 insertions(+), 62 deletions(-) diff --git a/manifest b/manifest index 9e99dd58e1..40222008f7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Small\sperformance\sincrease\sand\ssize\sreduction\sin\sthe\sOP_Column\sopcode. -D 2016-11-25T17:03:03.293 +C Refactor\sthe\ssqlite3BtreeKey()\sand\ssqlite3BtreeData()\sinternal\sinterfaces\ninto\ssqlite3BtreePayload()\sand\ssqlite3BtreePayloadChecked(),\srespectively.\nThis\sis\sa\scontinuation\sof\sthe\soptimization\sstarted\sby\scheck-in\n[2d831074cf].\s\sThe\sresult\sis\sa\sslightly\ssmaller\sand\sfaster\sbinary. +D 2016-11-25T19:18:28.043 F Makefile.in 6b572807415d3f0a379cebc9461416d8df4a12c8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc bb4d970894abbbe0e88d00aac29bd52af8bc95f4 @@ -330,8 +330,8 @@ F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792 F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b F src/bitvec.c 3ee4c8b2c94ed3a7377256e18199e6ff5cf33f63 F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 -F src/btree.c 090a13ac2a11bff2fcd30763a7347af998cf468f -F src/btree.h 01ec45846fa177e929f01ee36a8e34337d653544 +F src/btree.c 9b30dbe2f6306c50dc5af8296e67034400de37cb +F src/btree.h 2349a588abcd7e0c04f984e15c5c777b61637583 F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 F src/build.c 178f16698cbcb43402c343a9413fe22c99ffee21 F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 @@ -454,13 +454,13 @@ F src/update.c 68714ed42a506d782a3d75ff8f09640706d6a3b2 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 3e2da6101888d073e79ecc6af5e0a2f70fa1e498 F src/vacuum.c 33c174b28886b2faf26e503b5a49a1c01a9b1c16 -F src/vdbe.c 54a1d3e143a87ebcd355c956999b667dcfb64824 +F src/vdbe.c e8802d83ebd04db1ff91137f26834a08a560575c F src/vdbe.h c044be7050ac6bf596eecc6ab159f5dbc020a3b7 -F src/vdbeInt.h 29b25318a0286c4b2599c0fbef6acf524398489a -F src/vdbeapi.c 97129bec6b1553da50d8e73f523c278bda66d9f6 -F src/vdbeaux.c c0adf6e1ce14e0b511fbeb71aa3ef1d603051b71 -F src/vdbeblob.c ba5b57b9fa47b320ad5c46468e77d8660c931190 -F src/vdbemem.c fcdd73a2001a673f48a244a77b1038928ae729c9 +F src/vdbeInt.h 9b498d3cb52dc2efb53571fb8ae8e14cf298ce84 +F src/vdbeapi.c ea4e2dc2213cc6bd7bee375a29a9b51c31b93ae0 +F src/vdbeaux.c 50a8caa4c8ce8b4c26bad807a6cae89fcc3bdb7e +F src/vdbeblob.c f4f98ea672b242f807c08c92c7faaa79e5091b65 +F src/vdbemem.c 1af2f14ab0f7004b364933ddcfc767fb880d4742 F src/vdbesort.c 91fda3909326860382b0ca8aa251e609c6a9d62c F src/vdbetrace.c 41963d5376f0349842b5fc4aaaaacd7d9cdc0834 F src/vtab.c e02cacb5c7ae742631edeb9ae9f53d399f093fd8 @@ -1534,7 +1534,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P c53dca7fadd81ea340fef776373cbb122c9ccd46 -R 5cc42cc506bbe372234cb9f20b970e00 +P a9498407e646305e7b60115d63e85c642bbd1c3f +R 7c80cb213cf47d7b67265bccbb049e71 U drh -Z dac9238c0e962ec79642eb1c1f1654f2 +Z ea86d85568a47d84eaa403d5a88154cd diff --git a/manifest.uuid b/manifest.uuid index 3a997e9a3c..c5f928c3a9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a9498407e646305e7b60115d63e85c642bbd1c3f \ No newline at end of file +49ebc219faea30eaa61def4a3fba2817b9c58a86 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index d4f0e067f0..7a68331c3d 100644 --- a/src/btree.c +++ b/src/btree.c @@ -632,7 +632,7 @@ static int saveCursorKey(BtCursor *pCur){ pCur->nKey = sqlite3BtreePayloadSize(pCur); pKey = sqlite3Malloc( pCur->nKey ); if( pKey ){ - rc = sqlite3BtreeKey(pCur, 0, (int)pCur->nKey, pKey); + rc = sqlite3BtreePayload(pCur, 0, (int)pCur->nKey, pKey); if( rc==SQLITE_OK ){ pCur->pKey = pKey; }else{ @@ -4651,43 +4651,35 @@ static int accessPayload( } /* -** Read part of the key associated with cursor pCur. Exactly -** "amt" bytes will be transferred into pBuf[]. The transfer +** Read part of the payload for the row at which that cursor pCur is currently +** pointing. "amt" bytes will be transferred into pBuf[]. The transfer ** begins at "offset". ** -** The caller must ensure that pCur is pointing to a valid row -** in the table. +** pCur can be pointing to either a table or an index b-tree. +** If pointing to a table btree, then the content section is read. If +** pCur is pointing to an index b-tree then the key section is read. +** +** For sqlite3BtreePayload(), the caller must ensure that pCur is pointing +** to a valid row in the table. For sqlite3BtreePayloadChecked(), the +** cursor might be invalid or might need to be restored before being read. ** ** Return SQLITE_OK on success or an error code if anything goes ** wrong. An error is returned if "offset+amt" is larger than ** the available payload. */ -int sqlite3BtreeKey(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){ +int sqlite3BtreePayload(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){ assert( cursorHoldsMutex(pCur) ); assert( pCur->eState==CURSOR_VALID ); assert( pCur->iPage>=0 && pCur->apPage[pCur->iPage] ); assert( pCur->aiIdx[pCur->iPage]apPage[pCur->iPage]->nCell ); return accessPayload(pCur, offset, amt, (unsigned char*)pBuf, 0); } - -/* -** Read part of the data associated with cursor pCur. Exactly -** "amt" bytes will be transfered into pBuf[]. The transfer -** begins at "offset". -** -** Return SQLITE_OK on success or an error code if anything goes -** wrong. An error is returned if "offset+amt" is larger than -** the available payload. -*/ -int sqlite3BtreeData(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){ - int rc; - #ifndef SQLITE_OMIT_INCRBLOB +int sqlite3BtreePayloadChecked(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){ + int rc; if ( pCur->eState==CURSOR_INVALID ){ return SQLITE_ABORT; } -#endif - assert( cursorOwnsBtShared(pCur) ); rc = restoreCursorPosition(pCur); if( rc==SQLITE_OK ){ @@ -4698,6 +4690,7 @@ int sqlite3BtreeData(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){ } return rc; } +#endif /* SQLITE_OMIT_INCRBLOB */ /* ** Return a pointer to payload information from the entry that the diff --git a/src/btree.h b/src/btree.h index 92cf443b21..5e54125d39 100644 --- a/src/btree.h +++ b/src/btree.h @@ -289,15 +289,15 @@ int sqlite3BtreeNext(BtCursor*, int *pRes); int sqlite3BtreeEof(BtCursor*); int sqlite3BtreePrevious(BtCursor*, int *pRes); i64 sqlite3BtreeIntegerKey(BtCursor*); -int sqlite3BtreeKey(BtCursor*, u32 offset, u32 amt, void*); +int sqlite3BtreePayload(BtCursor*, u32 offset, u32 amt, void*); const void *sqlite3BtreePayloadFetch(BtCursor*, u32 *pAmt); u32 sqlite3BtreePayloadSize(BtCursor*); -int sqlite3BtreeData(BtCursor*, u32 offset, u32 amt, void*); char *sqlite3BtreeIntegrityCheck(Btree*, int *aRoot, int nRoot, int, int*); struct Pager *sqlite3BtreePager(Btree*); #ifndef SQLITE_OMIT_INCRBLOB +int sqlite3BtreePayloadChecked(BtCursor*, u32 offset, u32 amt, void*); int sqlite3BtreePutData(BtCursor*, u32 offset, u32 amt, void*); void sqlite3BtreeIncrblobCursor(BtCursor *); #endif diff --git a/src/vdbe.c b/src/vdbe.c index 9f57b47480..6a51b38ff1 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2549,8 +2549,7 @@ case OP_Column: { /* Make sure zData points to enough of the record to cover the header. */ if( pC->aRow==0 ){ memset(&sMem, 0, sizeof(sMem)); - rc = sqlite3VdbeMemFromBtree(pC->uc.pCursor, 0, aOffset[0], - !pC->isTable, &sMem); + rc = sqlite3VdbeMemFromBtree(pC->uc.pCursor, 0, aOffset[0], &sMem); if( rc!=SQLITE_OK ) goto abort_due_to_error; zData = (u8*)sMem.z; }else{ @@ -2663,8 +2662,7 @@ case OP_Column: { static u8 aZero[8]; /* This is the bogus content */ sqlite3VdbeSerialGet(aZero, t, pDest); }else{ - rc = sqlite3VdbeMemFromBtree(pC->uc.pCursor, aOffset[p2], len, - !pC->isTable, pDest); + rc = sqlite3VdbeMemFromBtree(pC->uc.pCursor, aOffset[p2], len, pDest); if( rc!=SQLITE_OK ) goto abort_due_to_error; sqlite3VdbeSerialGet((const u8*)pDest->z, t, pDest); pDest->flags &= ~MEM_Ephem; @@ -4705,11 +4703,7 @@ case OP_RowData: { } pOut->n = n; MemSetTypeFlag(pOut, MEM_Blob); - if( pC->isTable==0 ){ - rc = sqlite3BtreeKey(pCrsr, 0, n, pOut->z); - }else{ - rc = sqlite3BtreeData(pCrsr, 0, n, pOut->z); - } + rc = sqlite3BtreePayload(pCrsr, 0, n, pOut->z); if( rc ) goto abort_due_to_error; pOut->enc = SQLITE_UTF8; /* In case the blob is ever cast to text */ UPDATE_MAX_BLOBSIZE(pOut); diff --git a/src/vdbeInt.h b/src/vdbeInt.h index 6e6ace207c..df65124999 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -487,7 +487,7 @@ void sqlite3VdbeIntegerAffinity(Mem*); int sqlite3VdbeMemRealify(Mem*); int sqlite3VdbeMemNumerify(Mem*); void sqlite3VdbeMemCast(Mem*,u8,u8); -int sqlite3VdbeMemFromBtree(BtCursor*,u32,u32,int,Mem*); +int sqlite3VdbeMemFromBtree(BtCursor*,u32,u32,Mem*); void sqlite3VdbeMemRelease(Mem *p); int sqlite3VdbeMemFinalize(Mem*, FuncDef*); const char *sqlite3OpcodeName(int); diff --git a/src/vdbeapi.c b/src/vdbeapi.c index 645ef1c864..050a4d0e61 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -1695,7 +1695,7 @@ int sqlite3_preupdate_old(sqlite3 *db, int iIdx, sqlite3_value **ppValue){ nRec = sqlite3BtreePayloadSize(p->pCsr->uc.pCursor); aRec = sqlite3DbMallocRaw(db, nRec); if( !aRec ) goto preupdate_old_out; - rc = sqlite3BtreeData(p->pCsr->uc.pCursor, 0, nRec, aRec); + rc = sqlite3BtreePayload(p->pCsr->uc.pCursor, 0, nRec, aRec); if( rc==SQLITE_OK ){ p->pUnpacked = vdbeUnpackRecord(&p->keyinfo, nRec, aRec); if( !p->pUnpacked ) rc = SQLITE_NOMEM; diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 66e076e4c8..308d96917f 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -4365,7 +4365,7 @@ int sqlite3VdbeIdxRowid(sqlite3 *db, BtCursor *pCur, i64 *rowid){ /* Read in the complete content of the index entry */ sqlite3VdbeMemInit(&m, db, 0); - rc = sqlite3VdbeMemFromBtree(pCur, 0, (u32)nCellKey, 1, &m); + rc = sqlite3VdbeMemFromBtree(pCur, 0, (u32)nCellKey, &m); if( rc ){ return rc; } @@ -4445,7 +4445,7 @@ int sqlite3VdbeIdxKeyCompare( return SQLITE_CORRUPT_BKPT; } sqlite3VdbeMemInit(&m, db, 0); - rc = sqlite3VdbeMemFromBtree(pCur, 0, (u32)nCellKey, 1, &m); + rc = sqlite3VdbeMemFromBtree(pCur, 0, (u32)nCellKey, &m); if( rc ){ return rc; } diff --git a/src/vdbeblob.c b/src/vdbeblob.c index e4cf286865..520d16c985 100644 --- a/src/vdbeblob.c +++ b/src/vdbeblob.c @@ -440,7 +440,7 @@ static int blobReadWrite( ** Read data from a blob handle. */ int sqlite3_blob_read(sqlite3_blob *pBlob, void *z, int n, int iOffset){ - return blobReadWrite(pBlob, z, n, iOffset, sqlite3BtreeData); + return blobReadWrite(pBlob, z, n, iOffset, sqlite3BtreePayloadChecked); } /* diff --git a/src/vdbemem.c b/src/vdbemem.c index 9b78d5432c..2ee80045d1 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -934,10 +934,9 @@ int sqlite3VdbeMemSetStr( /* ** Move data out of a btree key or data field and into a Mem structure. -** The data or key is taken from the entry that pCur is currently pointing +** The data is payload from the entry that pCur is currently pointing ** to. offset and amt determine what portion of the data or key to retrieve. -** key is true to get the key or false to get data. The result is written -** into the pMem element. +** The result is written into the pMem element. ** ** The pMem object must have been initialized. This routine will use ** pMem->zMalloc to hold the content from the btree, if possible. New @@ -952,17 +951,12 @@ static SQLITE_NOINLINE int vdbeMemFromBtreeResize( BtCursor *pCur, /* Cursor pointing at record to retrieve. */ u32 offset, /* Offset from the start of data to return bytes from. */ u32 amt, /* Number of bytes to return. */ - int key, /* If true, retrieve from the btree key, not data. */ Mem *pMem /* OUT: Return data in this Mem structure. */ ){ int rc; pMem->flags = MEM_Null; if( SQLITE_OK==(rc = sqlite3VdbeMemClearAndResize(pMem, amt+2)) ){ - if( key ){ - rc = sqlite3BtreeKey(pCur, offset, amt, pMem->z); - }else{ - rc = sqlite3BtreeData(pCur, offset, amt, pMem->z); - } + rc = sqlite3BtreePayload(pCur, offset, amt, pMem->z); if( rc==SQLITE_OK ){ pMem->z[amt] = 0; pMem->z[amt+1] = 0; @@ -978,7 +972,6 @@ int sqlite3VdbeMemFromBtree( BtCursor *pCur, /* Cursor pointing at record to retrieve. */ u32 offset, /* Offset from the start of data to return bytes from. */ u32 amt, /* Number of bytes to return. */ - int key, /* If true, retrieve from the btree key, not data. */ Mem *pMem /* OUT: Return data in this Mem structure. */ ){ char *zData; /* Data from the btree layer */ @@ -999,7 +992,7 @@ int sqlite3VdbeMemFromBtree( pMem->flags = MEM_Blob|MEM_Ephem; pMem->n = (int)amt; }else{ - rc = vdbeMemFromBtreeResize(pCur, offset, amt, key, pMem); + rc = vdbeMemFromBtreeResize(pCur, offset, amt, pMem); } return rc; From 9057fc7c7fc2038d8c5873af35d22415d842c6cf Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 25 Nov 2016 19:32:32 +0000 Subject: [PATCH 1027/1484] Remove the OP_RowKey opcode. Use OP_RowData in its place. FossilOrigin-Name: 6ac7b07a4aff2e1a9031289e3dafdb9ac0071c24 --- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- src/delete.c | 2 +- src/insert.c | 2 +- src/select.c | 2 +- src/update.c | 2 +- src/vdbe.c | 21 +++++---------------- 7 files changed, 20 insertions(+), 31 deletions(-) diff --git a/manifest b/manifest index 40222008f7..f2e0359e9f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Refactor\sthe\ssqlite3BtreeKey()\sand\ssqlite3BtreeData()\sinternal\sinterfaces\ninto\ssqlite3BtreePayload()\sand\ssqlite3BtreePayloadChecked(),\srespectively.\nThis\sis\sa\scontinuation\sof\sthe\soptimization\sstarted\sby\scheck-in\n[2d831074cf].\s\sThe\sresult\sis\sa\sslightly\ssmaller\sand\sfaster\sbinary. -D 2016-11-25T19:18:28.043 +C Remove\sthe\sOP_RowKey\sopcode.\s\sUse\sOP_RowData\sin\sits\splace. +D 2016-11-25T19:32:32.783 F Makefile.in 6b572807415d3f0a379cebc9461416d8df4a12c8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc bb4d970894abbbe0e88d00aac29bd52af8bc95f4 @@ -339,7 +339,7 @@ F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c a2a52d6e353f459d8ab0f07321f60fafa47d5421 F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d -F src/delete.c 99949851e8e9ea4e1db739b0d354d360e1f80f2b +F src/delete.c cac97d1117a3008934da3a6a587b3608e65e1495 F src/expr.c 8c224aa28278a5c1eed55247b7a571ff388ad5c2 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c b9ca262f6ad4d030a3cab737ebf9b0b3c8b4ac80 @@ -349,7 +349,7 @@ F src/hash.c 63d0ee752a3b92d4695b2b1f5259c4621b2cfebd F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4 F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 -F src/insert.c b07f929977f36d2279cc3bce41583e30881cb617 +F src/insert.c 2f8d2c1fa472409625cecacddd39a3b1c6811a26 F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e F src/loadext.c 5d6642d141c07d366e43d359e94ec9de47add41d F src/main.c 694ac90557abdaa62151a6090670e107b0f2c2ab @@ -387,7 +387,7 @@ F src/printf.c f94da4935d1dd25420ac50c6745db1deb35e07c1 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c bb070cf5f23611c44ab7e4788803684e385fc3fb F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac -F src/select.c 672b1af237ad257149fc5189f3277dcbca036eeb +F src/select.c 668c6865b16813dab5f9c18d3672fed11a5c34c5 F src/shell.c a3fc2c719ed6d381895cbdb66a4a9b6a791cb02e F src/sqlite.h.in 803f7050f69b2eea573fac219f3c92582c096027 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -450,11 +450,11 @@ F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c 78c8085bc7af1922aa687f0f4bbd716821330de5 F src/treeview.c 4e44ade3bfe59d82005039f72e09333ce2b4162c F src/trigger.c 3419bb9862983d84d70735fb4c94b21b934cd0c5 -F src/update.c 68714ed42a506d782a3d75ff8f09640706d6a3b2 +F src/update.c 1b8321100cac004f0721ab67b16909dd006e663c F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 3e2da6101888d073e79ecc6af5e0a2f70fa1e498 F src/vacuum.c 33c174b28886b2faf26e503b5a49a1c01a9b1c16 -F src/vdbe.c e8802d83ebd04db1ff91137f26834a08a560575c +F src/vdbe.c 4a3ff567745aac67ffbb55d06fbecf19f88d12be F src/vdbe.h c044be7050ac6bf596eecc6ab159f5dbc020a3b7 F src/vdbeInt.h 9b498d3cb52dc2efb53571fb8ae8e14cf298ce84 F src/vdbeapi.c ea4e2dc2213cc6bd7bee375a29a9b51c31b93ae0 @@ -1534,7 +1534,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a9498407e646305e7b60115d63e85c642bbd1c3f -R 7c80cb213cf47d7b67265bccbb049e71 +P 49ebc219faea30eaa61def4a3fba2817b9c58a86 +R bc9bbb95d3f8cdb1915e65f8ff0e8ded U drh -Z ea86d85568a47d84eaa403d5a88154cd +Z ad1418d236344734ff49bed1db4111ac diff --git a/manifest.uuid b/manifest.uuid index c5f928c3a9..85438c23d4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -49ebc219faea30eaa61def4a3fba2817b9c58a86 \ No newline at end of file +6ac7b07a4aff2e1a9031289e3dafdb9ac0071c24 \ No newline at end of file diff --git a/src/delete.c b/src/delete.c index 46af65a361..9cd1cd0f25 100644 --- a/src/delete.c +++ b/src/delete.c @@ -495,7 +495,7 @@ void sqlite3DeleteFrom( } }else if( pPk ){ addrLoop = sqlite3VdbeAddOp1(v, OP_Rewind, iEphCur); VdbeCoverage(v); - sqlite3VdbeAddOp2(v, OP_RowKey, iEphCur, iKey); + sqlite3VdbeAddOp2(v, OP_RowData, iEphCur, iKey); assert( nKey==0 ); /* OP_Found will use a composite key */ }else{ addrLoop = sqlite3VdbeAddOp3(v, OP_RowSetRead, iRowSet, 0, iKey); diff --git a/src/insert.c b/src/insert.c index bb9936f3f7..007e0bb578 100644 --- a/src/insert.c +++ b/src/insert.c @@ -2156,7 +2156,7 @@ static int xferOptimization( sqlite3VdbeChangeP5(v, OPFLAG_BULKCSR); VdbeComment((v, "%s", pDestIdx->zName)); addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0); VdbeCoverage(v); - sqlite3VdbeAddOp2(v, OP_RowKey, iSrc, regData); + sqlite3VdbeAddOp2(v, OP_RowData, iSrc, regData); if( db->flags & SQLITE_Vacuum ){ /* This INSERT command is part of a VACUUM operation, which guarantees ** that the destination table is empty. If all indexed columns use diff --git a/src/select.c b/src/select.c index ab3371e86b..8e6022c9cd 100644 --- a/src/select.c +++ b/src/select.c @@ -2506,7 +2506,7 @@ static int multiSelect( computeLimitRegisters(pParse, p, iBreak); sqlite3VdbeAddOp2(v, OP_Rewind, tab1, iBreak); VdbeCoverage(v); r1 = sqlite3GetTempReg(pParse); - iStart = sqlite3VdbeAddOp2(v, OP_RowKey, tab1, r1); + iStart = sqlite3VdbeAddOp2(v, OP_RowData, tab1, r1); sqlite3VdbeAddOp4Int(v, OP_NotFound, tab2, iCont, r1, 0); VdbeCoverage(v); sqlite3ReleaseTempReg(pParse, r1); selectInnerLoop(pParse, p, p->pEList, tab1, diff --git a/src/update.c b/src/update.c index b370a4ec1a..c3b3681808 100644 --- a/src/update.c +++ b/src/update.c @@ -452,7 +452,7 @@ void sqlite3Update( }else if( pPk ){ labelContinue = sqlite3VdbeMakeLabel(v); sqlite3VdbeAddOp2(v, OP_Rewind, iEph, labelBreak); VdbeCoverage(v); - addrTop = sqlite3VdbeAddOp2(v, OP_RowKey, iEph, regKey); + addrTop = sqlite3VdbeAddOp2(v, OP_RowData, iEph, regKey); sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelContinue, regKey, 0); VdbeCoverage(v); }else{ diff --git a/src/vdbe.c b/src/vdbe.c index 6a51b38ff1..efd069a72e 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -4638,26 +4638,18 @@ case OP_SorterData: { /* Opcode: RowData P1 P2 * * * ** Synopsis: r[P2]=data ** -** Write into register P2 the complete row data for cursor P1. +** Write into register P2 the complete row content for the row at +** which cursor P1 is currently pointing. ** There is no interpretation of the data. ** It is just copied onto the P2 register exactly as ** it is found in the database file. ** -** If the P1 cursor must be pointing to a valid row (not a NULL row) -** of a real table, not a pseudo-table. -*/ -/* Opcode: RowKey P1 P2 * * * -** Synopsis: r[P2]=key -** -** Write into register P2 the complete row key for cursor P1. -** There is no interpretation of the data. -** The key is copied onto the P2 register exactly as -** it is found in the database file. +** If cursor P1 is an index, then the content is the key of the row. +** If cursor P2 is a table, then the content extracted is the data. ** ** If the P1 cursor must be pointing to a valid row (not a NULL row) ** of a real table, not a pseudo-table. */ -case OP_RowKey: case OP_RowData: { VdbeCursor *pC; BtCursor *pCrsr; @@ -4666,19 +4658,16 @@ case OP_RowData: { pOut = &aMem[pOp->p2]; memAboutToChange(p, pOut); - /* Note that RowKey and RowData are really exactly the same instruction */ assert( pOp->p1>=0 && pOp->p1nCursor ); pC = p->apCsr[pOp->p1]; assert( pC!=0 ); assert( pC->eCurType==CURTYPE_BTREE ); assert( isSorter(pC)==0 ); - assert( pC->isTable || pOp->opcode!=OP_RowData ); - assert( pC->isTable==0 || pOp->opcode==OP_RowData ); assert( pC->nullRow==0 ); assert( pC->uc.pCursor!=0 ); pCrsr = pC->uc.pCursor; - /* The OP_RowKey and OP_RowData opcodes always follow OP_NotExists or + /* The OP_RowData opcodes always follow OP_NotExists or ** OP_SeekRowid or OP_Rewind/Op_Next with no intervening instructions ** that might invalidate the cursor. ** If this where not the case, on of the following assert()s From 6412a4c8a59294a00e5be5e85057ad6473d407eb Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 25 Nov 2016 20:20:40 +0000 Subject: [PATCH 1028/1484] Clarification of the behavior of sqlite3_stmt_readonly() on BEGIN IMMEDIATE statements. The is comment changes only - no changes to code. FossilOrigin-Name: a4205a83e4ed977a89ecae665604993711f7dd3f --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/sqlite.h.in | 4 ++++ 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index f2e0359e9f..d95479008e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sthe\sOP_RowKey\sopcode.\s\sUse\sOP_RowData\sin\sits\splace. -D 2016-11-25T19:32:32.783 +C Clarification\sof\sthe\sbehavior\sof\ssqlite3_stmt_readonly()\son\sBEGIN\sIMMEDIATE\nstatements.\s\sThe\sis\scomment\schanges\sonly\s-\sno\schanges\sto\scode. +D 2016-11-25T20:20:40.663 F Makefile.in 6b572807415d3f0a379cebc9461416d8df4a12c8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc bb4d970894abbbe0e88d00aac29bd52af8bc95f4 @@ -389,7 +389,7 @@ F src/resolve.c bb070cf5f23611c44ab7e4788803684e385fc3fb F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c 668c6865b16813dab5f9c18d3672fed11a5c34c5 F src/shell.c a3fc2c719ed6d381895cbdb66a4a9b6a791cb02e -F src/sqlite.h.in 803f7050f69b2eea573fac219f3c92582c096027 +F src/sqlite.h.in e30a501ccb8c8bd25b6559c65ba240c6370802ae F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae F src/sqliteInt.h c471d791b10c0f2164c8b7a87adc338e703c09cc @@ -1534,7 +1534,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 49ebc219faea30eaa61def4a3fba2817b9c58a86 -R bc9bbb95d3f8cdb1915e65f8ff0e8ded +P 6ac7b07a4aff2e1a9031289e3dafdb9ac0071c24 +R 32f39fc3fb2e8643f8b6bcf49fda406b U drh -Z ad1418d236344734ff49bed1db4111ac +Z be231616b2371336e459be64a91b2f84 diff --git a/manifest.uuid b/manifest.uuid index 85438c23d4..b87bf72629 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6ac7b07a4aff2e1a9031289e3dafdb9ac0071c24 \ No newline at end of file +a4205a83e4ed977a89ecae665604993711f7dd3f \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index dd70407c1b..578a9066e1 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -3610,6 +3610,10 @@ char *sqlite3_expanded_sql(sqlite3_stmt *pStmt); ** sqlite3_stmt_readonly() to return true since, while those statements ** change the configuration of a database connection, they do not make ** changes to the content of the database files on disk. +** ^The sqlite3_stmt_readonly() interface returns true for [BEGIN] since +** [BEGIN] merely sets internal flags, but the [BEGIN|BEGIN IMMEDIATE] and +** [BEGIN|BEGIN EXCLUSIVE] commands do touch the database and so +** sqlite3_stmt_readonly() returns false for those commands. */ int sqlite3_stmt_readonly(sqlite3_stmt *pStmt); From 158e4e56d775fff89eb01b2dada975654b8a6567 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 28 Nov 2016 14:52:23 +0000 Subject: [PATCH 1029/1484] Simplify some code in fts5_expr.c. Add some extra test cases for the same. FossilOrigin-Name: 7cc2d60dce90b8d4dca35708e33002ae6387806e --- ext/fts5/fts5_expr.c | 65 ++++++++++++++++++++-------------- ext/fts5/test/fts5prefix.test | 2 +- ext/fts5/test/fts5simple2.test | 35 ++++++++++++++++++ manifest | 19 +++++----- manifest.uuid | 2 +- 5 files changed, 85 insertions(+), 38 deletions(-) diff --git a/ext/fts5/fts5_expr.c b/ext/fts5/fts5_expr.c index bde9eaed8b..20fd32467c 100644 --- a/ext/fts5/fts5_expr.c +++ b/ext/fts5/fts5_expr.c @@ -746,48 +746,61 @@ static int fts5ExprNearTest( ** Initialize all term iterators in the pNear object. If any term is found ** to match no documents at all, return immediately without initializing any ** further iterators. +** +** If an error occurs, return an SQLite error code. Otherwise, return +** SQLITE_OK. It is not considered an error if some term matches zero +** documents. */ static int fts5ExprNearInitAll( Fts5Expr *pExpr, Fts5ExprNode *pNode ){ Fts5ExprNearset *pNear = pNode->pNear; - int i, j; - int rc = SQLITE_OK; - int bEof = 1; + int i; assert( pNode->bNomatch==0 ); - for(i=0; rc==SQLITE_OK && inPhrase; i++){ + for(i=0; inPhrase; i++){ Fts5ExprPhrase *pPhrase = pNear->apPhrase[i]; - for(j=0; jnTerm; j++){ - Fts5ExprTerm *pTerm = &pPhrase->aTerm[j]; - Fts5ExprTerm *p; + if( pPhrase->nTerm==0 ){ + pNode->bEof = 1; + return SQLITE_OK; + }else{ + int j; + for(j=0; jnTerm; j++){ + Fts5ExprTerm *pTerm = &pPhrase->aTerm[j]; + Fts5ExprTerm *p; + int bHit = 0; - for(p=pTerm; p && rc==SQLITE_OK; p=p->pSynonym){ - if( p->pIter ){ - sqlite3Fts5IterClose(p->pIter); - p->pIter = 0; + for(p=pTerm; p; p=p->pSynonym){ + int rc; + if( p->pIter ){ + sqlite3Fts5IterClose(p->pIter); + p->pIter = 0; + } + rc = sqlite3Fts5IndexQuery( + pExpr->pIndex, p->zTerm, (int)strlen(p->zTerm), + (pTerm->bPrefix ? FTS5INDEX_QUERY_PREFIX : 0) | + (pExpr->bDesc ? FTS5INDEX_QUERY_DESC : 0), + pNear->pColset, + &p->pIter + ); + assert( (rc==SQLITE_OK)==(p->pIter!=0) ); + if( rc!=SQLITE_OK ) return rc; + if( 0==sqlite3Fts5IterEof(p->pIter) ){ + bHit = 1; + } } - rc = sqlite3Fts5IndexQuery( - pExpr->pIndex, p->zTerm, (int)strlen(p->zTerm), - (pTerm->bPrefix ? FTS5INDEX_QUERY_PREFIX : 0) | - (pExpr->bDesc ? FTS5INDEX_QUERY_DESC : 0), - pNear->pColset, - &p->pIter - ); - assert( rc==SQLITE_OK || p->pIter==0 ); - if( p->pIter && 0==sqlite3Fts5IterEof(p->pIter) ){ - bEof = 0; + + if( bHit==0 ){ + pNode->bEof = 1; + return SQLITE_OK; } } - - if( bEof ) break; } - if( bEof ) break; } - pNode->bEof = bEof; - return rc; + pNode->bEof = 0; + return SQLITE_OK; } /* diff --git a/ext/fts5/test/fts5prefix.test b/ext/fts5/test/fts5prefix.test index 8e0d5a2954..01d0fe5d14 100644 --- a/ext/fts5/test/fts5prefix.test +++ b/ext/fts5/test/fts5prefix.test @@ -9,7 +9,7 @@ # #*********************************************************************** # -# This file containst tests focused on prefix indexes. +# This file contains tests focused on prefix indexes. # source [file join [file dirname [info script]] fts5_common.tcl] diff --git a/ext/fts5/test/fts5simple2.test b/ext/fts5/test/fts5simple2.test index 186d771f76..a6c1789473 100644 --- a/ext/fts5/test/fts5simple2.test +++ b/ext/fts5/test/fts5simple2.test @@ -332,6 +332,41 @@ do_execsql_test 16.0 { DELETE FROM t2; } +#------------------------------------------------------------------------- +# +reset_db +do_execsql_test 17.0 { + CREATE VIRTUAL TABLE t2 USING fts5(x, y); + BEGIN; + INSERT INTO t2 VALUES('a aa aaa', 'b bb bbb'); + INSERT INTO t2 VALUES('a aa aaa', 'b bb bbb'); + INSERT INTO t2 VALUES('a aa aaa', 'b bb bbb'); + COMMIT; +} +do_execsql_test 17.1 { SELECT * FROM t2('y:a*') WHERE rowid BETWEEN 10 AND 20 } +do_execsql_test 17.2 { + BEGIN; + INSERT INTO t2 VALUES('a aa aaa', 'b bb bbb'); + SELECT * FROM t2('y:a*') WHERE rowid BETWEEN 10 AND 20 ; +} +do_execsql_test 17.3 { + COMMIT +} + +reset_db +do_execsql_test 17.4 { + CREATE VIRTUAL TABLE t2 USING fts5(x, y); + BEGIN; + INSERT INTO t2 VALUES('a aa aaa', 'b bb bbb'); + INSERT INTO t2 VALUES('a aa aaa', 'b bb bbb'); + SELECT * FROM t2('y:a*') WHERE rowid>66; +} +do_execsql_test 17.5 { SELECT * FROM t2('x:b* OR y:a*') } +do_execsql_test 17.5 { COMMIT ; SELECT * FROM t2('x:b* OR y:a*') } +do_execsql_test 17.6 { + SELECT * FROM t2('x:b* OR y:a*') WHERE rowid>55 +} + #db eval {SELECT rowid, fts5_decode_none(rowid, block) aS r FROM t2_data} {puts $r} finish_test diff --git a/manifest b/manifest index 4870b53952..c3636a76be 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\ssqlite3_snapshot_recover()\sinterface\sand\srelated\sfunctionality. -D 2016-11-26T19:44:40.853 +C Simplify\ssome\scode\sin\sfts5_expr.c.\sAdd\ssome\sextra\stest\scases\sfor\sthe\ssame. +D 2016-11-28T14:52:23.554 F Makefile.in 6b572807415d3f0a379cebc9461416d8df4a12c8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc bb4d970894abbbe0e88d00aac29bd52af8bc95f4 @@ -102,7 +102,7 @@ F ext/fts5/fts5Int.h b2eda36e0f224365c8e23dc8f559311834f1c13f F ext/fts5/fts5_aux.c 67acf8d51723cf28ffc3828210ba662df4b8d267 F ext/fts5/fts5_buffer.c 4c1502d4c956cd092c89ce4480867f9d8bf325cd F ext/fts5/fts5_config.c 5af9c360e99669d29f06492c370892394aba0857 -F ext/fts5/fts5_expr.c e12421946774482f4d49e334c974571177adbc70 +F ext/fts5/fts5_expr.c 34ece379a83efd047e0a0fc170e476ba76b0404a F ext/fts5/fts5_hash.c 880998e596b60f078348d48732ca4ad9a90caad2 F ext/fts5/fts5_index.c fdbe46da11e81c1817cd4cb2de25ffdb4dd83711 F ext/fts5/fts5_main.c f85281445dcf8be32d18841c93a6f90fe27dbfe2 @@ -175,14 +175,14 @@ F ext/fts5/test/fts5phrase.test f6d1d464da5beb25dc56277aa4f1d6102f0d9a2f F ext/fts5/test/fts5plan.test 6a55ecbac9890765b0e16f8c421c7e0888cfe436 F ext/fts5/test/fts5porter.test 7cdc07bef301d70eebbfa75dcaf45c3680e1d0e1 F ext/fts5/test/fts5porter2.test 2e65633d58a1c525d5af0f6c01e5a59155bb3487 -F ext/fts5/test/fts5prefix.test efd42e00bb8e8a36383f25c838185508681c093f +F ext/fts5/test/fts5prefix.test 6ef7e875738412907b17687d25db39a25cbdaba4 F ext/fts5/test/fts5query.test f5ec25f5f2fbb70033424113cdffc101b1985a40 F ext/fts5/test/fts5rank.test 2bdc0c5f22ccc1f9dbe9f4d0b82a491dce6f8a32 F ext/fts5/test/fts5rebuild.test 03935f617ace91ed23a6099c7c74d905227ff29b F ext/fts5/test/fts5restart.test c17728fdea26e7d0f617d22ad5b4b2862b994c17 F ext/fts5/test/fts5rowid.test 16908a99d6efc9ba21081b4f2b86b3fc699839a6 F ext/fts5/test/fts5simple.test 5da9b15ed534eb0be9f279d8a2bb2e24d30e4e38 -F ext/fts5/test/fts5simple2.test 98377ae1ff7749a42c21fe1a139c1ed312522c46 +F ext/fts5/test/fts5simple2.test 00839031878f52391562594fdab0503e424ee071 F ext/fts5/test/fts5simple3.test 25faa8cb8ad470c6f01f670bcc1317c19a89f091 F ext/fts5/test/fts5synonym.test 6475d189c2e20d60795808f83e36bf9318708d48 F ext/fts5/test/fts5synonym2.test aa4c43bd3b691ff80f658cb064f5ab40690e834e @@ -1535,8 +1535,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a4205a83e4ed977a89ecae665604993711f7dd3f e2c4bdf54fc1b9605226c7d6c79ef4f8302d6213 -R e3a0631511335a83b0a91c37cc46bd7e -T +closed e2c4bdf54fc1b9605226c7d6c79ef4f8302d6213 -U drh -Z 12f51558a308f260b27f24c87a70fdb2 +P b70c85ce6d07b08e13f4ea99edb8f4855a6d7580 +R e2d59b569b83323f61b57e394e54a92d +U dan +Z da120d25a7b116db8d62d3eda200a581 diff --git a/manifest.uuid b/manifest.uuid index 8b694c9f20..c671b3421c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b70c85ce6d07b08e13f4ea99edb8f4855a6d7580 \ No newline at end of file +7cc2d60dce90b8d4dca35708e33002ae6387806e \ No newline at end of file From bc60368d6f8521260cc1228da279a3421651b39f Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 28 Nov 2016 21:22:26 +0000 Subject: [PATCH 1030/1484] Fix broken hyperlinks to the sqlite3_snapshot objection definition in the documentation. No changes to code. FossilOrigin-Name: 9021f6875f897d8b609ebcc04162dc6e0b529a4a --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/sqlite.h.in | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index c3636a76be..f7115da4be 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Simplify\ssome\scode\sin\sfts5_expr.c.\sAdd\ssome\sextra\stest\scases\sfor\sthe\ssame. -D 2016-11-28T14:52:23.554 +C Fix\sbroken\shyperlinks\sto\sthe\ssqlite3_snapshot\sobjection\sdefinition\nin\sthe\sdocumentation.\s\sNo\schanges\sto\scode. +D 2016-11-28T21:22:26.486 F Makefile.in 6b572807415d3f0a379cebc9461416d8df4a12c8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc bb4d970894abbbe0e88d00aac29bd52af8bc95f4 @@ -389,7 +389,7 @@ F src/resolve.c bb070cf5f23611c44ab7e4788803684e385fc3fb F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c 668c6865b16813dab5f9c18d3672fed11a5c34c5 F src/shell.c a3fc2c719ed6d381895cbdb66a4a9b6a791cb02e -F src/sqlite.h.in 566e3aa20e40f3eceda8bfb36c72504b4f10b500 +F src/sqlite.h.in e8e2d108d82647f0a812fdb74accf91c1ec08ddc F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae F src/sqliteInt.h c471d791b10c0f2164c8b7a87adc338e703c09cc @@ -1535,7 +1535,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b70c85ce6d07b08e13f4ea99edb8f4855a6d7580 -R e2d59b569b83323f61b57e394e54a92d -U dan -Z da120d25a7b116db8d62d3eda200a581 +P 7cc2d60dce90b8d4dca35708e33002ae6387806e +R de1f3e041fb172133322c08f2e17859a +U drh +Z 0f2a9b7b29f5f440f84b18c2372070c3 diff --git a/manifest.uuid b/manifest.uuid index c671b3421c..aaf0921076 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7cc2d60dce90b8d4dca35708e33002ae6387806e \ No newline at end of file +9021f6875f897d8b609ebcc04162dc6e0b529a4a \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 4a8a52016a..caa89721e1 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -8263,7 +8263,7 @@ int sqlite3_system_errno(sqlite3*); /* ** CAPI3REF: Database Snapshot -** KEYWORDS: {snapshot} +** KEYWORDS: {snapshot} {sqlite3_snapshot} ** EXPERIMENTAL ** ** An instance of the snapshot object records the state of a [WAL mode] From 3edb157e2316476aa88f28ad203382905fee363c Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 29 Nov 2016 20:39:48 +0000 Subject: [PATCH 1031/1484] The documentation says that the built-in date-time functions give undefined results for dates before 0000-01-01 and after 9999-12-31. Change the actually implementation so that the answer given is really NULL. This also avoids unnecessary hand-wringing over an signed integer overflow that might otherwise occur when processing out-of-bound dates. FossilOrigin-Name: d410a839752153c6d8be08f758abfbc16475745a --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/date.c | 15 +++++++++++++++ test/date.test | 14 ++------------ 4 files changed, 25 insertions(+), 20 deletions(-) diff --git a/manifest b/manifest index f7115da4be..733c2d390f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sbroken\shyperlinks\sto\sthe\ssqlite3_snapshot\sobjection\sdefinition\nin\sthe\sdocumentation.\s\sNo\schanges\sto\scode. -D 2016-11-28T21:22:26.486 +C The\sdocumentation\ssays\sthat\sthe\sbuilt-in\sdate-time\sfunctions\sgive\sundefined\nresults\sfor\sdates\sbefore\s0000-01-01\sand\safter\s9999-12-31.\s\sChange\sthe\nactually\simplementation\sso\sthat\sthe\sanswer\sgiven\sis\sreally\sNULL.\s\sThis\salso\navoids\sunnecessary\shand-wringing\sover\san\ssigned\sinteger\soverflow\sthat\smight\notherwise\soccur\swhen\sprocessing\sout-of-bound\sdates. +D 2016-11-29T20:39:48.413 F Makefile.in 6b572807415d3f0a379cebc9461416d8df4a12c8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc bb4d970894abbbe0e88d00aac29bd52af8bc95f4 @@ -337,7 +337,7 @@ F src/build.c 178f16698cbcb43402c343a9413fe22c99ffee21 F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c a2a52d6e353f459d8ab0f07321f60fafa47d5421 -F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b +F src/date.c 53a4019b90ae1c9cb990196eed0ed196d3f341e1 F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c cac97d1117a3008934da3a6a587b3608e65e1495 F src/expr.c 8c224aa28278a5c1eed55247b7a571ff388ad5c2 @@ -626,7 +626,7 @@ F test/csv01.test e0ba3caaa57e4c667a0b45977689fb8082f14348 F test/ctime.test ff6c38e822459d6ca743c34901caf57740b08b54 F test/cursorhint.test 7bc346788390475e77a345da2b92270d04d35856 F test/cursorhint2.test fa41f0d997e67db921d08c31e73111b32811201a -F test/date.test 984ac1e3e5e031386866f034006148d3972b4a65 +F test/date.test 47e7f7057c0efac0e5e26da2d7b6a9a128139de6 F test/dbstatus.test 73149851b3aff14fc6db478e58f9083a66422cf5 F test/dbstatus2.test e93ab03bfae6d62d4d935f20de928c19ca0ed0ab F test/default.test 0cb49b1c315a0d81c81d775e407f66906a2a604d @@ -1535,7 +1535,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 7cc2d60dce90b8d4dca35708e33002ae6387806e -R de1f3e041fb172133322c08f2e17859a +P 9021f6875f897d8b609ebcc04162dc6e0b529a4a +R e95c6d806c4c5b465cfcf2c97462edc9 U drh -Z 0f2a9b7b29f5f440f84b18c2372070c3 +Z f7a67f418429ef937fb437b96080796e diff --git a/manifest.uuid b/manifest.uuid index aaf0921076..95eeb46ae6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9021f6875f897d8b609ebcc04162dc6e0b529a4a \ No newline at end of file +d410a839752153c6d8be08f758abfbc16475745a \ No newline at end of file diff --git a/src/date.c b/src/date.c index 8b2f2fa717..a90b5318b8 100644 --- a/src/date.c +++ b/src/date.c @@ -75,6 +75,7 @@ struct DateTime { char validJD; /* True (1) if iJD is valid */ char validTZ; /* True (1) if tz is valid */ char tzSet; /* Timezone was set explicitly */ + char isError; /* An overflow has occurred */ }; @@ -366,6 +367,15 @@ static int parseDateOrTime( return 1; } +/* +** Return TRUE if the given julian day number is within range. +** +** The input is the JulianDay times 86400000. +*/ +static int validJulianDay(sqlite3_int64 iJD){ + return iJD>=148699540800000 && iJD<=464269060799999; +} + /* ** Compute the Year, Month, and Day from the julian day number. */ @@ -376,6 +386,10 @@ static void computeYMD(DateTime *p){ p->Y = 2000; p->M = 1; p->D = 1; + }else if( !validJulianDay(p->iJD) ){ + memset(p, 0, sizeof(*p)); + p->isError = 1; + return; }else{ Z = (int)((p->iJD + 43200000)/86400000); A = (int)((Z - 1867216.25)/36524.25); @@ -814,6 +828,7 @@ static int isDate( z = sqlite3_value_text(argv[i]); if( z==0 || parseModifier(context, (char*)z, p) ) return 1; } + if( p->isError || (p->validJD && !validJulianDay(p->iJD)) ) return 1; return 0; } diff --git a/test/date.test b/test/date.test index 2f48b111e6..0286bcc3bc 100644 --- a/test/date.test +++ b/test/date.test @@ -61,8 +61,8 @@ datetest 1.19 {julianday('2000-01-01 12:00:00.1')} 2451545.00000116 datetest 1.20 {julianday('2000-01-01 12:00:00.01')} 2451545.00000012 datetest 1.21 {julianday('2000-01-01 12:00:00.001')} 2451545.00000001 datetest 1.22 {julianday('2000-01-01 12:00:00.')} NULL -datetest 1.23 julianday(12345.6) 12345.6 -datetest 1.23b julianday('12345.6') 12345.6 +datetest 1.23 julianday(12345.6) NULL +datetest 1.23b julianday(1721059.5) 1721059.5 datetest 1.24 {julianday('2001-01-01 12:00:00 bogus')} NULL datetest 1.25 {julianday('2001-01-01 bogus')} NULL datetest 1.26 {julianday('2001-01-01 12:60:00')} NULL @@ -418,16 +418,6 @@ datetest 8.19 {datetime('now','11.25 seconds')} {2003-10-22 12:34:11} datetest 8.90 {datetime('now','abcdefghijklmnopqrstuvwyxzABCDEFGHIJLMNOP')} NULL set sqlite_current_time 0 -# Negative years work. Example: '-4713-11-26' is JD 1.5. -# -datetest 9.1 {julianday('-4713-11-24 12:00:00')} {0.0} -datetest 9.2 {julianday(datetime(5))} {5.0} -datetest 9.3 {julianday(datetime(10))} {10.0} -datetest 9.4 {julianday(datetime(100))} {100.0} -datetest 9.5 {julianday(datetime(1000))} {1000.0} -datetest 9.6 {julianday(datetime(10000))} {10000.0} -datetest 9.7 {julianday(datetime(100000))} {100000.0} - # datetime() with just an HH:MM:SS correctly inserts the date 2000-01-01. # datetest 10.1 {datetime('01:02:03')} {2000-01-01 01:02:03} From d76a902c877bcaa79d28008a0d51776fc9333621 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 30 Nov 2016 00:48:28 +0000 Subject: [PATCH 1032/1484] Further changes to the date/time functions to suppress harmless signed integer overflow warnings that could have occurred when doing out-of-range date calculations which, according to the docs, give undefined results. FossilOrigin-Name: dc453b3403450b1d8cc53daf0721fed025b9053c --- manifest | 14 ++++++------- manifest.uuid | 2 +- src/date.c | 53 +++++++++++++++++++++++++++++++------------------- test/date.test | 49 +++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 89 insertions(+), 29 deletions(-) diff --git a/manifest b/manifest index 733c2d390f..aecf668d2a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C The\sdocumentation\ssays\sthat\sthe\sbuilt-in\sdate-time\sfunctions\sgive\sundefined\nresults\sfor\sdates\sbefore\s0000-01-01\sand\safter\s9999-12-31.\s\sChange\sthe\nactually\simplementation\sso\sthat\sthe\sanswer\sgiven\sis\sreally\sNULL.\s\sThis\salso\navoids\sunnecessary\shand-wringing\sover\san\ssigned\sinteger\soverflow\sthat\smight\notherwise\soccur\swhen\sprocessing\sout-of-bound\sdates. -D 2016-11-29T20:39:48.413 +C Further\schanges\sto\sthe\sdate/time\sfunctions\sto\ssuppress\sharmless\ssigned\ninteger\soverflow\swarnings\sthat\scould\shave\soccurred\swhen\sdoing\sout-of-range\ndate\scalculations\swhich,\saccording\sto\sthe\sdocs,\sgive\sundefined\sresults. +D 2016-11-30T00:48:28.495 F Makefile.in 6b572807415d3f0a379cebc9461416d8df4a12c8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc bb4d970894abbbe0e88d00aac29bd52af8bc95f4 @@ -337,7 +337,7 @@ F src/build.c 178f16698cbcb43402c343a9413fe22c99ffee21 F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c a2a52d6e353f459d8ab0f07321f60fafa47d5421 -F src/date.c 53a4019b90ae1c9cb990196eed0ed196d3f341e1 +F src/date.c 736c1f36c58bb137f64d8d1f72467dc027832563 F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c cac97d1117a3008934da3a6a587b3608e65e1495 F src/expr.c 8c224aa28278a5c1eed55247b7a571ff388ad5c2 @@ -626,7 +626,7 @@ F test/csv01.test e0ba3caaa57e4c667a0b45977689fb8082f14348 F test/ctime.test ff6c38e822459d6ca743c34901caf57740b08b54 F test/cursorhint.test 7bc346788390475e77a345da2b92270d04d35856 F test/cursorhint2.test fa41f0d997e67db921d08c31e73111b32811201a -F test/date.test 47e7f7057c0efac0e5e26da2d7b6a9a128139de6 +F test/date.test a6a5a48b90907bca9fbcc79a30be5a715c1ab2fc F test/dbstatus.test 73149851b3aff14fc6db478e58f9083a66422cf5 F test/dbstatus2.test e93ab03bfae6d62d4d935f20de928c19ca0ed0ab F test/default.test 0cb49b1c315a0d81c81d775e407f66906a2a604d @@ -1535,7 +1535,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 9021f6875f897d8b609ebcc04162dc6e0b529a4a -R e95c6d806c4c5b465cfcf2c97462edc9 +P d410a839752153c6d8be08f758abfbc16475745a +R 4de84d6de9c4735ca2171beb11da6949 U drh -Z f7a67f418429ef937fb437b96080796e +Z a5d0c3a9dbd00d301630dafcf90b9504 diff --git a/manifest.uuid b/manifest.uuid index 95eeb46ae6..f5cb5e6a0d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d410a839752153c6d8be08f758abfbc16475745a \ No newline at end of file +dc453b3403450b1d8cc53daf0721fed025b9053c \ No newline at end of file diff --git a/src/date.c b/src/date.c index a90b5318b8..6a6743f86d 100644 --- a/src/date.c +++ b/src/date.c @@ -65,17 +65,17 @@ struct tm *__cdecl localtime(const time_t *); */ typedef struct DateTime DateTime; struct DateTime { - sqlite3_int64 iJD; /* The julian day number times 86400000 */ - int Y, M, D; /* Year, month, and day */ - int h, m; /* Hour and minutes */ - int tz; /* Timezone offset in minutes */ - double s; /* Seconds */ - char validYMD; /* True (1) if Y,M,D are valid */ - char validHMS; /* True (1) if h,m,s are valid */ - char validJD; /* True (1) if iJD is valid */ - char validTZ; /* True (1) if tz is valid */ - char tzSet; /* Timezone was set explicitly */ - char isError; /* An overflow has occurred */ + sqlite3_uint64 iJD; /* The julian day number times 86400000 */ + int Y, M, D; /* Year, month, and day */ + int h, m; /* Hour and minutes */ + int tz; /* Timezone offset in minutes */ + double s; /* Seconds */ + char validYMD; /* True (1) if Y,M,D are valid */ + char validHMS; /* True (1) if h,m,s are valid */ + char validJD; /* True (1) if iJD is valid */ + char validTZ; /* True (1) if tz is valid */ + char tzSet; /* Timezone was set explicitly */ + char isError; /* An overflow has occurred */ }; @@ -232,6 +232,14 @@ static int parseHhMmSs(const char *zDate, DateTime *p){ return 0; } +/* +** Put the DateTime object into its error state. +*/ +static void datetimeError(DateTime *p){ + memset(p, 0, sizeof(*p)); + p->isError = 1; +} + /* ** Convert from YYYY-MM-DD HH:MM:SS to julian day. We always assume ** that the YYYY-MM-DD is according to the Gregorian calendar. @@ -251,6 +259,10 @@ static void computeJD(DateTime *p){ M = 1; D = 1; } + if( Y<-4713 || Y>9999 ){ + datetimeError(p); + return; + } if( M<=2 ){ Y--; M += 12; @@ -373,7 +385,7 @@ static int parseDateOrTime( ** The input is the JulianDay times 86400000. */ static int validJulianDay(sqlite3_int64 iJD){ - return iJD>=148699540800000 && iJD<=464269060799999; + return iJD>=0 && iJD<=464269060799999; } /* @@ -387,8 +399,7 @@ static void computeYMD(DateTime *p){ p->M = 1; p->D = 1; }else if( !validJulianDay(p->iJD) ){ - memset(p, 0, sizeof(*p)); - p->isError = 1; + datetimeError(p); return; }else{ Z = (int)((p->iJD + 43200000)/86400000); @@ -713,6 +724,7 @@ static int parseModifier(sqlite3_context *pCtx, const char *zMod, DateTime *p){ case '8': case '9': { double rRounder; + double rAbs; for(n=1; z[n] && z[n]!=':' && !sqlite3Isspace(z[n]); n++){} if( !sqlite3AtoF(z, &r, n, SQLITE_UTF8) ){ rc = 1; @@ -749,15 +761,16 @@ static int parseModifier(sqlite3_context *pCtx, const char *zMod, DateTime *p){ computeJD(p); rc = 0; rRounder = r<0 ? -0.5 : +0.5; - if( n==3 && strcmp(z,"day")==0 ){ + rAbs = r<0 ? -r : r; + if( n==3 && strcmp(z,"day")==0 && rAbs<5373485.0 ){ p->iJD += (sqlite3_int64)(r*86400000.0 + rRounder); - }else if( n==4 && strcmp(z,"hour")==0 ){ + }else if( n==4 && strcmp(z,"hour")==0 && rAbs<128963628.0 ){ p->iJD += (sqlite3_int64)(r*(86400000.0/24.0) + rRounder); - }else if( n==6 && strcmp(z,"minute")==0 ){ + }else if( n==6 && strcmp(z,"minute")==0 && rAbs<7737817680.0 ){ p->iJD += (sqlite3_int64)(r*(86400000.0/(24.0*60.0)) + rRounder); - }else if( n==6 && strcmp(z,"second")==0 ){ + }else if( n==6 && strcmp(z,"second")==0 && rAbs<464269060800.0 ){ p->iJD += (sqlite3_int64)(r*(86400000.0/(24.0*60.0*60.0)) + rRounder); - }else if( n==5 && strcmp(z,"month")==0 ){ + }else if( n==5 && strcmp(z,"month")==0 && rAbs<176546.0 ){ int x, y; computeYMD_HMS(p); p->M += (int)r; @@ -770,7 +783,7 @@ static int parseModifier(sqlite3_context *pCtx, const char *zMod, DateTime *p){ if( y!=r ){ p->iJD += (sqlite3_int64)((r - y)*30.0*86400000.0 + rRounder); } - }else if( n==4 && strcmp(z,"year")==0 ){ + }else if( n==4 && strcmp(z,"year")==0 && rAbs<14713.0 ){ int y = (int)r; computeYMD_HMS(p); p->Y += y; diff --git a/test/date.test b/test/date.test index 0286bcc3bc..2d336e6c00 100644 --- a/test/date.test +++ b/test/date.test @@ -61,7 +61,7 @@ datetest 1.19 {julianday('2000-01-01 12:00:00.1')} 2451545.00000116 datetest 1.20 {julianday('2000-01-01 12:00:00.01')} 2451545.00000012 datetest 1.21 {julianday('2000-01-01 12:00:00.001')} 2451545.00000001 datetest 1.22 {julianday('2000-01-01 12:00:00.')} NULL -datetest 1.23 julianday(12345.6) NULL +datetest 1.23 julianday(12345.6) 12345.6 datetest 1.23b julianday(1721059.5) 1721059.5 datetest 1.24 {julianday('2001-01-01 12:00:00 bogus')} NULL datetest 1.25 {julianday('2001-01-01 bogus')} NULL @@ -418,6 +418,16 @@ datetest 8.19 {datetime('now','11.25 seconds')} {2003-10-22 12:34:11} datetest 8.90 {datetime('now','abcdefghijklmnopqrstuvwyxzABCDEFGHIJLMNOP')} NULL set sqlite_current_time 0 +# Negative years work. Example: '-4713-11-26' is JD 1.5. +# +datetest 9.1 {julianday('-4713-11-24 12:00:00')} {0.0} +datetest 9.2 {julianday(datetime(5))} {5.0} +datetest 9.3 {julianday(datetime(10))} {10.0} +datetest 9.4 {julianday(datetime(100))} {100.0} +datetest 9.5 {julianday(datetime(1000))} {1000.0} +datetest 9.6 {julianday(datetime(10000))} {10000.0} +datetest 9.7 {julianday(datetime(100000))} {100000.0} + # datetime() with just an HH:MM:SS correctly inserts the date 2000-01-01. # datetest 10.1 {datetime('01:02:03')} {2000-01-01 01:02:03} @@ -550,4 +560,41 @@ do_test date-15.2 { } } {1} +# Tests of extreme values in date/time functions. Run with UBSan or the +# equivalent to verify no signed interger overflow warnings. +# +datetest 16.1 {date(147483649)} NULL +datetest 16.2 {datetime(0)} {-4713-11-24 12:00:00} +datetest 16.3 {datetime(5373484.49999999)} {9999-12-31 23:59:59} +datetest 16.4 {julianday('-4713-11-24 12:00:00')} 0.0 +datetest 16.5 {julianday('9999-12-31 23:59:59.999')} 5373484.49999999 +datetest 16.6 {datetime(0,'+464269060799 seconds')} {9999-12-31 23:59:59} +datetest 16.7 {datetime(0,'+464269060800 seconds')} NULL +datetest 16.8 {datetime(0,'+7737817679 minutes')} {9999-12-31 23:59:00} +datetest 16.9 {datetime(0,'+7737817680 minutes')} NULL +datetest 16.10 {datetime(0,'+128963627 hours')} {9999-12-31 23:00:00} +datetest 16.11 {datetime(0,'+128963628 hours')} NULL +datetest 16.12 {datetime(0,'+5373484 days')} {9999-12-31 12:00:00} +datetest 16.13 {datetime(0,'+5373485 days')} NULL +datetest 16.14 {datetime(0,'+176545 months')} {9999-12-24 12:00:00} +datetest 16.15 {datetime(0,'+176546 months')} NULL +datetest 16.16 {datetime(0,'+14712 years')} {9999-11-24 12:00:00} +datetest 16.17 {datetime(0,'+14713 years')} NULL +datetest 16.20 {datetime(5373484.4999999,'-464269060799 seconds')} \ + {-4713-11-24 12:00:00} +datetest 16.21 {datetime(5373484,'-464269060800 seconds')} NULL +datetest 16.22 {datetime(5373484.4999999,'-7737817679 minutes')} \ + {-4713-11-24 12:00:59} +datetest 16.23 {datetime(5373484,'-7737817680 minutes')} NULL +datetest 16.24 {datetime(5373484.4999999,'-128963627 hours')} \ + {-4713-11-24 12:59:59} +datetest 16.25 {datetime(5373484,'-128963628 hours')} NULL +datetest 16.26 {datetime(5373484,'-5373484 days')} {-4713-11-24 12:00:00} +datetest 16.27 {datetime(5373484,'-5373485 days')} NULL +datetest 16.28 {datetime(5373484,'-176545 months')} {-4713-12-01 12:00:00} +datetest 16.29 {datetime(5373484,'-176546 months')} NULL +datetest 16.30 {datetime(5373484,'-14712 years')} {-4713-12-31 12:00:00} +datetest 16.31 {datetime(5373484,'-14713 years')} NULL + + finish_test From 64777ba8342761bbe2e28e8bebf52d6421965a1a Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 30 Nov 2016 01:05:41 +0000 Subject: [PATCH 1033/1484] Prevent a warning about integer overflow when using a very large negative LIMIT. FossilOrigin-Name: 96106d5620eae51474234f4eec1d2c5bd570d486 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 12 +++++++----- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index aecf668d2a..ce5272dd34 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Further\schanges\sto\sthe\sdate/time\sfunctions\sto\ssuppress\sharmless\ssigned\ninteger\soverflow\swarnings\sthat\scould\shave\soccurred\swhen\sdoing\sout-of-range\ndate\scalculations\swhich,\saccording\sto\sthe\sdocs,\sgive\sundefined\sresults. -D 2016-11-30T00:48:28.495 +C Prevent\sa\swarning\sabout\sinteger\soverflow\swhen\susing\sa\svery\slarge\snegative\nLIMIT. +D 2016-11-30T01:05:41.141 F Makefile.in 6b572807415d3f0a379cebc9461416d8df4a12c8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc bb4d970894abbbe0e88d00aac29bd52af8bc95f4 @@ -454,7 +454,7 @@ F src/update.c 1b8321100cac004f0721ab67b16909dd006e663c F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 3e2da6101888d073e79ecc6af5e0a2f70fa1e498 F src/vacuum.c 33c174b28886b2faf26e503b5a49a1c01a9b1c16 -F src/vdbe.c 4a3ff567745aac67ffbb55d06fbecf19f88d12be +F src/vdbe.c 1802a10926b14de7065950d436e7ce418682faef F src/vdbe.h c044be7050ac6bf596eecc6ab159f5dbc020a3b7 F src/vdbeInt.h 9b498d3cb52dc2efb53571fb8ae8e14cf298ce84 F src/vdbeapi.c ea4e2dc2213cc6bd7bee375a29a9b51c31b93ae0 @@ -1535,7 +1535,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d410a839752153c6d8be08f758abfbc16475745a -R 4de84d6de9c4735ca2171beb11da6949 +P dc453b3403450b1d8cc53daf0721fed025b9053c +R dc777d9d449bf1af0c4185b27e450723 U drh -Z a5d0c3a9dbd00d301630dafcf90b9504 +Z 787a300f5849727b901aee7620134dd8 diff --git a/manifest.uuid b/manifest.uuid index f5cb5e6a0d..85a66cede4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -dc453b3403450b1d8cc53daf0721fed025b9053c \ No newline at end of file +96106d5620eae51474234f4eec1d2c5bd570d486 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index efd069a72e..ec92e8b1c0 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -6022,15 +6022,17 @@ case OP_IfNotZero: { /* jump, in1 */ /* Opcode: DecrJumpZero P1 P2 * * * ** Synopsis: if (--r[P1])==0 goto P2 ** -** Register P1 must hold an integer. Decrement the value in register P1 -** then jump to P2 if the new value is exactly zero. +** Register P1 must hold an integer. If the value in P1 is positive, +** decrement the value and jump to P2 if the new value is exactly zero. */ case OP_DecrJumpZero: { /* jump, in1 */ pIn1 = &aMem[pOp->p1]; assert( pIn1->flags&MEM_Int ); - pIn1->u.i--; - VdbeBranchTaken(pIn1->u.i==0, 2); - if( pIn1->u.i==0 ) goto jump_to_p2; + if( pIn1->u.i>0 ){ + pIn1->u.i--; + VdbeBranchTaken(pIn1->u.i==0, 2); + if( pIn1->u.i==0 ) goto jump_to_p2; + } break; } From b5489b88b01739c5b97f360a6e4a386a3805c2e3 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 30 Nov 2016 04:07:57 +0000 Subject: [PATCH 1034/1484] More improvements to boundary cases in the date/time functions, flowing out of branch coverage testing. FossilOrigin-Name: 1218005ab7b52ef45db1354d17fdd8a1a1af9854 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/date.c | 9 ++++++--- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index ce5272dd34..290e4d72d8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Prevent\sa\swarning\sabout\sinteger\soverflow\swhen\susing\sa\svery\slarge\snegative\nLIMIT. -D 2016-11-30T01:05:41.141 +C More\simprovements\sto\sboundary\scases\sin\sthe\sdate/time\sfunctions,\sflowing\sout\nof\sbranch\scoverage\stesting. +D 2016-11-30T04:07:57.427 F Makefile.in 6b572807415d3f0a379cebc9461416d8df4a12c8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc bb4d970894abbbe0e88d00aac29bd52af8bc95f4 @@ -337,7 +337,7 @@ F src/build.c 178f16698cbcb43402c343a9413fe22c99ffee21 F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c a2a52d6e353f459d8ab0f07321f60fafa47d5421 -F src/date.c 736c1f36c58bb137f64d8d1f72467dc027832563 +F src/date.c 206d0eb85cedec99a9820929579057fb364a72cb F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c cac97d1117a3008934da3a6a587b3608e65e1495 F src/expr.c 8c224aa28278a5c1eed55247b7a571ff388ad5c2 @@ -1535,7 +1535,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P dc453b3403450b1d8cc53daf0721fed025b9053c -R dc777d9d449bf1af0c4185b27e450723 +P 96106d5620eae51474234f4eec1d2c5bd570d486 +R 533c0afd3cc78feab0c7d06b5d67b3a1 U drh -Z 787a300f5849727b901aee7620134dd8 +Z 8875af7104f1fa4c1f8084b812f6f104 diff --git a/manifest.uuid b/manifest.uuid index 85a66cede4..67b5bd51d3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -96106d5620eae51474234f4eec1d2c5bd570d486 \ No newline at end of file +1218005ab7b52ef45db1354d17fdd8a1a1af9854 \ No newline at end of file diff --git a/src/date.c b/src/date.c index 6a6743f86d..c675d17455 100644 --- a/src/date.c +++ b/src/date.c @@ -65,7 +65,7 @@ struct tm *__cdecl localtime(const time_t *); */ typedef struct DateTime DateTime; struct DateTime { - sqlite3_uint64 iJD; /* The julian day number times 86400000 */ + sqlite3_int64 iJD; /* The julian day number times 86400000 */ int Y, M, D; /* Year, month, and day */ int h, m; /* Hour and minutes */ int tz; /* Timezone offset in minutes */ @@ -829,7 +829,9 @@ static int isDate( } if( (eType = sqlite3_value_type(argv[0]))==SQLITE_FLOAT || eType==SQLITE_INTEGER ){ - p->iJD = (sqlite3_int64)(sqlite3_value_double(argv[0])*86400000.0 + 0.5); + double r = sqlite3_value_double(argv[0]); + if( r>106751991167.0 || r<-106751991167.0 ) return 1; + p->iJD = (sqlite3_int64)(r*86400000.0 + 0.5); p->validJD = 1; }else{ z = sqlite3_value_text(argv[0]); @@ -841,7 +843,8 @@ static int isDate( z = sqlite3_value_text(argv[i]); if( z==0 || parseModifier(context, (char*)z, p) ) return 1; } - if( p->isError || (p->validJD && !validJulianDay(p->iJD)) ) return 1; + computeJD(p); + if( p->isError || !validJulianDay(p->iJD) ) return 1; return 0; } From ab5be2e651b6bbc7f979d921aefcafede3439ade Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 30 Nov 2016 05:08:59 +0000 Subject: [PATCH 1035/1484] Change the OP_DecrJumpZero opcode back to its old behavior of always decrementing, except top the decrementing when it reaches the largest negative number. FossilOrigin-Name: 9d0d8c2e7c529562889de02346733dcb532e9388 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 12 +++++------- 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index 290e4d72d8..afe9bd5c8d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C More\simprovements\sto\sboundary\scases\sin\sthe\sdate/time\sfunctions,\sflowing\sout\nof\sbranch\scoverage\stesting. -D 2016-11-30T04:07:57.427 +C Change\sthe\sOP_DecrJumpZero\sopcode\sback\sto\sits\sold\sbehavior\sof\salways\ndecrementing,\sexcept\stop\sthe\sdecrementing\swhen\sit\sreaches\sthe\slargest\snegative\nnumber. +D 2016-11-30T05:08:59.150 F Makefile.in 6b572807415d3f0a379cebc9461416d8df4a12c8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc bb4d970894abbbe0e88d00aac29bd52af8bc95f4 @@ -454,7 +454,7 @@ F src/update.c 1b8321100cac004f0721ab67b16909dd006e663c F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 3e2da6101888d073e79ecc6af5e0a2f70fa1e498 F src/vacuum.c 33c174b28886b2faf26e503b5a49a1c01a9b1c16 -F src/vdbe.c 1802a10926b14de7065950d436e7ce418682faef +F src/vdbe.c 336a3e5696683a585e56bbbc4f05ce33957d28dd F src/vdbe.h c044be7050ac6bf596eecc6ab159f5dbc020a3b7 F src/vdbeInt.h 9b498d3cb52dc2efb53571fb8ae8e14cf298ce84 F src/vdbeapi.c ea4e2dc2213cc6bd7bee375a29a9b51c31b93ae0 @@ -1535,7 +1535,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 96106d5620eae51474234f4eec1d2c5bd570d486 -R 533c0afd3cc78feab0c7d06b5d67b3a1 +P 1218005ab7b52ef45db1354d17fdd8a1a1af9854 +R cd48ebcdd22406f3055d813d70fb9f48 U drh -Z 8875af7104f1fa4c1f8084b812f6f104 +Z 430b79992fd44a23d3200085781e41a0 diff --git a/manifest.uuid b/manifest.uuid index 67b5bd51d3..529fc7f38b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1218005ab7b52ef45db1354d17fdd8a1a1af9854 \ No newline at end of file +9d0d8c2e7c529562889de02346733dcb532e9388 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index ec92e8b1c0..3b2550810f 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -6022,17 +6022,15 @@ case OP_IfNotZero: { /* jump, in1 */ /* Opcode: DecrJumpZero P1 P2 * * * ** Synopsis: if (--r[P1])==0 goto P2 ** -** Register P1 must hold an integer. If the value in P1 is positive, -** decrement the value and jump to P2 if the new value is exactly zero. +** Register P1 must hold an integer. Decrement the value in P1 +** and jump to P2 if the new value is exactly zero. */ case OP_DecrJumpZero: { /* jump, in1 */ pIn1 = &aMem[pOp->p1]; assert( pIn1->flags&MEM_Int ); - if( pIn1->u.i>0 ){ - pIn1->u.i--; - VdbeBranchTaken(pIn1->u.i==0, 2); - if( pIn1->u.i==0 ) goto jump_to_p2; - } + if( pIn1->u.i>SMALLEST_INT64 ) pIn1->u.i--; + VdbeBranchTaken(pIn1->u.i==0, 2); + if( pIn1->u.i==0 ) goto jump_to_p2; break; } From 77320ea48d30d7fb85756ca642f80d4d54307cfe Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 30 Nov 2016 14:47:37 +0000 Subject: [PATCH 1036/1484] Fix then handling of the (oversized) integer literal -0x8000000000000000. FossilOrigin-Name: 3816bb415ecfd4f36430d0fcbc878e382975de60 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/expr.c | 10 +++++----- test/hexlit.test | 3 +++ 4 files changed, 16 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index afe9bd5c8d..ca75b2f116 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sthe\sOP_DecrJumpZero\sopcode\sback\sto\sits\sold\sbehavior\sof\salways\ndecrementing,\sexcept\stop\sthe\sdecrementing\swhen\sit\sreaches\sthe\slargest\snegative\nnumber. -D 2016-11-30T05:08:59.150 +C Fix\sthen\shandling\sof\sthe\s(oversized)\sinteger\sliteral\s-0x8000000000000000. +D 2016-11-30T14:47:37.324 F Makefile.in 6b572807415d3f0a379cebc9461416d8df4a12c8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc bb4d970894abbbe0e88d00aac29bd52af8bc95f4 @@ -340,7 +340,7 @@ F src/ctime.c a2a52d6e353f459d8ab0f07321f60fafa47d5421 F src/date.c 206d0eb85cedec99a9820929579057fb364a72cb F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c cac97d1117a3008934da3a6a587b3608e65e1495 -F src/expr.c 8c224aa28278a5c1eed55247b7a571ff388ad5c2 +F src/expr.c b22e09630f874c52db0770973b7ce55ee50c1dde F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c b9ca262f6ad4d030a3cab737ebf9b0b3c8b4ac80 F src/func.c 7057bc2c105b82faa668d8e2ec85fad4540e5c51 @@ -824,7 +824,7 @@ F test/fuzzer1.test 3d4c4b7e547aba5e5511a2991e3e3d07166cfbb8 F test/fuzzer2.test a85ef814ce071293bce1ad8dffa217cbbaad4c14 F test/fuzzerfault.test 8792cd77fd5bce765b05d0c8e01b9edcf8af8536 F test/genesis.tcl 1e2e2e8e5cc4058549a154ff1892fe5c9de19f98 -F test/hexlit.test d7b0a5f41123df1e43985b91b8b2e70f95282d21 +F test/hexlit.test 4a6a5f46e3c65c4bf1fa06f5dd5a9507a5627751 F test/hidden.test 23c1393a79e846d68fd902d72c85d5e5dcf98711 F test/hook.test 3a01b876691f9151d3e44562354f7d663ff90fce F test/icu.test 73956798bace8982909c00476b216714a6d0559a @@ -1535,7 +1535,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 1218005ab7b52ef45db1354d17fdd8a1a1af9854 -R cd48ebcdd22406f3055d813d70fb9f48 +P 9d0d8c2e7c529562889de02346733dcb532e9388 +R 3cdfa3322e8c1e15bb4a1105ccb3dfa9 U drh -Z 430b79992fd44a23d3200085781e41a0 +Z 1db6a5b72b559f0fea9bc564b812e94c diff --git a/manifest.uuid b/manifest.uuid index 529fc7f38b..a3846b0f11 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9d0d8c2e7c529562889de02346733dcb532e9388 \ No newline at end of file +3816bb415ecfd4f36430d0fcbc878e382975de60 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 2f7deeea9a..1ad166777b 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2942,22 +2942,22 @@ static void codeInteger(Parse *pParse, Expr *pExpr, int negFlag, int iMem){ const char *z = pExpr->u.zToken; assert( z!=0 ); c = sqlite3DecOrHexToI64(z, &value); - if( c==0 || (c==2 && negFlag) ){ - if( negFlag ){ value = c==2 ? SMALLEST_INT64 : -value; } - sqlite3VdbeAddOp4Dup8(v, OP_Int64, 0, iMem, 0, (u8*)&value, P4_INT64); - }else{ + if( c==1 || (c==2 && !negFlag) || (negFlag && value==SMALLEST_INT64)){ #ifdef SQLITE_OMIT_FLOATING_POINT sqlite3ErrorMsg(pParse, "oversized integer: %s%s", negFlag ? "-" : "", z); #else #ifndef SQLITE_OMIT_HEX_INTEGER if( sqlite3_strnicmp(z,"0x",2)==0 ){ - sqlite3ErrorMsg(pParse, "hex literal too big: %s", z); + sqlite3ErrorMsg(pParse, "hex literal too big: %s%s", negFlag?"-":"",z); }else #endif { codeReal(v, z, negFlag, iMem); } #endif + }else{ + if( negFlag ){ value = c==2 ? SMALLEST_INT64 : -value; } + sqlite3VdbeAddOp4Dup8(v, OP_Int64, 0, iMem, 0, (u8*)&value, P4_INT64); } } } diff --git a/test/hexlit.test b/test/hexlit.test index c48930b49b..2161f27a12 100644 --- a/test/hexlit.test +++ b/test/hexlit.test @@ -112,6 +112,9 @@ do_catchsql_test hexlist-400 { do_catchsql_test hexlist-401 { SELECT DISTINCT 0x10000000000000000; } {1 {hex literal too big: 0x10000000000000000}} +do_catchsql_test hexlist-402 { + SELECT DISTINCT -0x08000000000000000; +} {1 {hex literal too big: -0x08000000000000000}} do_catchsql_test hexlist-410 { DROP TABLE IF EXISTS t1; CREATE TABLE t1(x); From 1a4a73764ca8a1a79b2fedda3352d2350d7f2ede Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 1 Dec 2016 17:34:59 +0000 Subject: [PATCH 1037/1484] Modify the patternCompare() function (used for GLOB, LIKE) to better handle patterns containing multiple wildcard characters ("*", "%"). FossilOrigin-Name: c5e5614d98a752738c081fecdd1e349a1a92b0e5 --- manifest | 18 ++++++++++-------- manifest.uuid | 2 +- src/func.c | 32 ++++++++++++++++++++++++-------- 3 files changed, 35 insertions(+), 17 deletions(-) diff --git a/manifest b/manifest index 867860bee6..8c10ea1dbf 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sremember(V,PTR)\sextension\sfunction\swhich\scopies\san\sSQL\svalue\sinto\nan\sapplication\svariable. -D 2016-11-30T16:54:52.848 +C Modify\sthe\spatternCompare()\sfunction\s(used\sfor\sGLOB,\sLIKE)\sto\sbetter\shandle\npatterns\scontaining\smultiple\swildcard\scharacters\s("*",\s"%"). +D 2016-12-01T17:34:59.799 F Makefile.in 7639c6a09da11a9c7c6f2630fc981ee588d1072d F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -344,7 +344,7 @@ F src/delete.c cac97d1117a3008934da3a6a587b3608e65e1495 F src/expr.c b22e09630f874c52db0770973b7ce55ee50c1dde F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c b9ca262f6ad4d030a3cab737ebf9b0b3c8b4ac80 -F src/func.c 7057bc2c105b82faa668d8e2ec85fad4540e5c51 +F src/func.c 528e92597efe1bb80b5dfc18184bd6cbf50d0cf9 F src/global.c 9da4ca5d74b90715f0ec4957f3d17a4749009f34 F src/hash.c 63d0ee752a3b92d4695b2b1f5259c4621b2cfebd F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4 @@ -1536,8 +1536,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 3816bb415ecfd4f36430d0fcbc878e382975de60 f0942c362f45ca1e986e142dbdd3ad957626dfb1 -R cd510c86291ec9069bea94544a3e0b95 -T +closed f0942c362f45ca1e986e142dbdd3ad957626dfb1 -U drh -Z 6b290cfef4656939d1e961e713e76c69 +P d2d30914d81022d7d4e1670caf9326524520deaf +R e10a8ca94d0faea9fbbc7bdc7c3a49de +T *branch * pattern-compare-optimization +T *sym-pattern-compare-optimization * +T -sym-trunk * +U dan +Z 02660061daf6ca9953ba412794b057ac diff --git a/manifest.uuid b/manifest.uuid index 305748dc68..9b8ba94419 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d2d30914d81022d7d4e1670caf9326524520deaf \ No newline at end of file +c5e5614d98a752738c081fecdd1e349a1a92b0e5 \ No newline at end of file diff --git a/src/func.c b/src/func.c index 6ec0962de0..54f5df46aa 100644 --- a/src/func.c +++ b/src/func.c @@ -636,7 +636,8 @@ static int patternCompare( const u8 *zPattern, /* The glob pattern */ const u8 *zString, /* The string to compare against the glob */ const struct compareInfo *pInfo, /* Information about how to do the compare */ - u32 matchOther /* The escape char (LIKE) or '[' (GLOB) */ + u32 matchOther, /* The escape char (LIKE) or '[' (GLOB) */ + int *pbSeenMatchAll /* OUT: True if have seen matchAll */ ){ u32 c, c2; /* Next pattern and input string chars */ u32 matchOne = pInfo->matchOne; /* "?" or "_" */ @@ -649,6 +650,7 @@ static int patternCompare( /* Skip over multiple "*" characters in the pattern. If there ** are also "?" characters, skip those as well, but consume a ** single character of the input string for each "?" skipped */ + *pbSeenMatchAll = 1; while( (c=Utf8Read(zPattern)) == matchAll || c == matchOne ){ if( c==matchOne && sqlite3Utf8Read(&zString)==0 ){ return 0; @@ -661,11 +663,14 @@ static int patternCompare( c = sqlite3Utf8Read(&zPattern); if( c==0 ) return 0; }else{ + int bMA = 0; /* True if patternCompare sees matchAll */ /* "[...]" immediately follows the "*". We have to do a slow ** recursive search in this case, but it is an unusual case. */ assert( matchOther<0x80 ); /* '[' is a single-byte character */ while( *zString - && patternCompare(&zPattern[-1],zString,pInfo,matchOther)==0 ){ + && patternCompare(&zPattern[-1],zString,pInfo,matchOther,&bMA)==0 + ){ + if( bMA ) return 0; SQLITE_SKIP_UTF8(zString); } return *zString!=0; @@ -674,7 +679,7 @@ static int patternCompare( /* At this point variable c contains the first character of the ** pattern string past the "*". Search in the input string for the - ** first matching character and recursively contine the match from + ** first matching character and recursively continue the match from ** that point. ** ** For a case-insensitive search, set variable cx to be the same as @@ -683,6 +688,7 @@ static int patternCompare( */ if( c<=0x80 ){ u32 cx; + int bMatchAll = 0; if( noCase ){ cx = sqlite3Toupper(c); c = sqlite3Tolower(c); @@ -691,12 +697,19 @@ static int patternCompare( } while( (c2 = *(zString++))!=0 ){ if( c2!=c && c2!=cx ) continue; - if( patternCompare(zPattern,zString,pInfo,matchOther) ) return 1; + if( patternCompare(zPattern,zString,pInfo,matchOther, &bMatchAll) ){ + return 1; + } + if( bMatchAll ) break; } }else{ + int bMatchAll = 0; while( (c2 = Utf8Read(zString))!=0 ){ if( c2!=c ) continue; - if( patternCompare(zPattern,zString,pInfo,matchOther) ) return 1; + if( patternCompare(zPattern,zString,pInfo,matchOther, &bMatchAll) ){ + return 1; + } + if( bMatchAll ) break; } } return 0; @@ -755,14 +768,16 @@ static int patternCompare( ** The sqlite3_strglob() interface. */ int sqlite3_strglob(const char *zGlobPattern, const char *zString){ - return patternCompare((u8*)zGlobPattern, (u8*)zString, &globInfo, '[')==0; + int dummy = 0; + return patternCompare((u8*)zGlobPattern, (u8*)zString, &globInfo, '[', &dummy)==0; } /* ** The sqlite3_strlike() interface. */ int sqlite3_strlike(const char *zPattern, const char *zStr, unsigned int esc){ - return patternCompare((u8*)zPattern, (u8*)zStr, &likeInfoNorm, esc)==0; + int dummy = 0; + return patternCompare((u8*)zPattern, (u8*)zStr, &likeInfoNorm, esc, &dummy)==0; } /* @@ -840,10 +855,11 @@ static void likeFunc( escape = pInfo->matchSet; } if( zA && zB ){ + int dummy = 0; #ifdef SQLITE_TEST sqlite3_like_count++; #endif - sqlite3_result_int(context, patternCompare(zB, zA, pInfo, escape)); + sqlite3_result_int(context, patternCompare(zB, zA, pInfo, escape, &dummy)); } } From 698a01ca2fa3cb8dd7a3005474cac3ecc450f252 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 1 Dec 2016 18:49:40 +0000 Subject: [PATCH 1038/1484] Faster version of patternCompare() that uses new return values rather than an extra parameter to communicate wildcard information back up to parent searches. FossilOrigin-Name: a1e2b6ce3af690ae91bda3d056357205c4018da7 --- manifest | 17 +++++------ manifest.uuid | 2 +- src/func.c | 79 ++++++++++++++++++++++++++------------------------- 3 files changed, 48 insertions(+), 50 deletions(-) diff --git a/manifest b/manifest index 8c10ea1dbf..b0f600d002 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Modify\sthe\spatternCompare()\sfunction\s(used\sfor\sGLOB,\sLIKE)\sto\sbetter\shandle\npatterns\scontaining\smultiple\swildcard\scharacters\s("*",\s"%"). -D 2016-12-01T17:34:59.799 +C Faster\sversion\sof\spatternCompare()\sthat\suses\snew\sreturn\svalues\srather\sthan\nan\sextra\sparameter\sto\scommunicate\swildcard\sinformation\sback\sup\sto\sparent\nsearches. +D 2016-12-01T18:49:40.948 F Makefile.in 7639c6a09da11a9c7c6f2630fc981ee588d1072d F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -344,7 +344,7 @@ F src/delete.c cac97d1117a3008934da3a6a587b3608e65e1495 F src/expr.c b22e09630f874c52db0770973b7ce55ee50c1dde F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c b9ca262f6ad4d030a3cab737ebf9b0b3c8b4ac80 -F src/func.c 528e92597efe1bb80b5dfc18184bd6cbf50d0cf9 +F src/func.c 43916c1d8e6da5d107d91d2b212577d4f69a876a F src/global.c 9da4ca5d74b90715f0ec4957f3d17a4749009f34 F src/hash.c 63d0ee752a3b92d4695b2b1f5259c4621b2cfebd F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4 @@ -1536,10 +1536,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d2d30914d81022d7d4e1670caf9326524520deaf -R e10a8ca94d0faea9fbbc7bdc7c3a49de -T *branch * pattern-compare-optimization -T *sym-pattern-compare-optimization * -T -sym-trunk * -U dan -Z 02660061daf6ca9953ba412794b057ac +P c5e5614d98a752738c081fecdd1e349a1a92b0e5 +R 7fd404505e6cb7c0d4a931aa83fe2cab +U drh +Z 7c186ec4fef5aa272b546661aa8fedfc diff --git a/manifest.uuid b/manifest.uuid index 9b8ba94419..b7832d7eab 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c5e5614d98a752738c081fecdd1e349a1a92b0e5 \ No newline at end of file +a1e2b6ce3af690ae91bda3d056357205c4018da7 \ No newline at end of file diff --git a/src/func.c b/src/func.c index 54f5df46aa..5b8ed6dd2b 100644 --- a/src/func.c +++ b/src/func.c @@ -598,9 +598,19 @@ static const struct compareInfo likeInfoNorm = { '%', '_', 0, 1 }; static const struct compareInfo likeInfoAlt = { '%', '_', 0, 0 }; /* -** Compare two UTF-8 strings for equality where the first string can -** potentially be a "glob" or "like" expression. Return true (1) if they -** are the same and false (0) if they are different. +** Possible error returns from patternMatch() +*/ +#define SQLITE_MATCH 0 +#define SQLITE_NOMATCH 1 +#define SQLITE_NOWILDCARDMATCH 2 + +/* +** Compare two UTF-8 strings for equality where the first string is +** a GLOB or LIKE expression. Return values: +** +** SQLITE_MATCH: Match +** SQLITE_NOMATCH: No match +** SQLITE_NOWILDCARDMATCH: No match in spite of having * or % wildcards. ** ** Globbing rules: ** @@ -636,8 +646,7 @@ static int patternCompare( const u8 *zPattern, /* The glob pattern */ const u8 *zString, /* The string to compare against the glob */ const struct compareInfo *pInfo, /* Information about how to do the compare */ - u32 matchOther, /* The escape char (LIKE) or '[' (GLOB) */ - int *pbSeenMatchAll /* OUT: True if have seen matchAll */ + u32 matchOther /* The escape char (LIKE) or '[' (GLOB) */ ){ u32 c, c2; /* Next pattern and input string chars */ u32 matchOne = pInfo->matchOne; /* "?" or "_" */ @@ -650,30 +659,27 @@ static int patternCompare( /* Skip over multiple "*" characters in the pattern. If there ** are also "?" characters, skip those as well, but consume a ** single character of the input string for each "?" skipped */ - *pbSeenMatchAll = 1; while( (c=Utf8Read(zPattern)) == matchAll || c == matchOne ){ if( c==matchOne && sqlite3Utf8Read(&zString)==0 ){ - return 0; + return SQLITE_NOWILDCARDMATCH; } } if( c==0 ){ - return 1; /* "*" at the end of the pattern matches */ + return SQLITE_MATCH; /* "*" at the end of the pattern matches */ }else if( c==matchOther ){ if( pInfo->matchSet==0 ){ c = sqlite3Utf8Read(&zPattern); - if( c==0 ) return 0; + if( c==0 ) return SQLITE_NOWILDCARDMATCH; }else{ - int bMA = 0; /* True if patternCompare sees matchAll */ /* "[...]" immediately follows the "*". We have to do a slow ** recursive search in this case, but it is an unusual case. */ assert( matchOther<0x80 ); /* '[' is a single-byte character */ - while( *zString - && patternCompare(&zPattern[-1],zString,pInfo,matchOther,&bMA)==0 - ){ - if( bMA ) return 0; + while( *zString ){ + int bMatch = patternCompare(&zPattern[-1],zString,pInfo,matchOther); + if( bMatch!=SQLITE_NOMATCH ) return bMatch; SQLITE_SKIP_UTF8(zString); } - return *zString!=0; + return SQLITE_NOWILDCARDMATCH; } } @@ -688,7 +694,7 @@ static int patternCompare( */ if( c<=0x80 ){ u32 cx; - int bMatchAll = 0; + int bMatch; if( noCase ){ cx = sqlite3Toupper(c); c = sqlite3Tolower(c); @@ -697,34 +703,30 @@ static int patternCompare( } while( (c2 = *(zString++))!=0 ){ if( c2!=c && c2!=cx ) continue; - if( patternCompare(zPattern,zString,pInfo,matchOther, &bMatchAll) ){ - return 1; - } - if( bMatchAll ) break; + bMatch = patternCompare(zPattern,zString,pInfo,matchOther); + if( bMatch!=SQLITE_NOMATCH ) return bMatch; } }else{ - int bMatchAll = 0; + int bMatch; while( (c2 = Utf8Read(zString))!=0 ){ if( c2!=c ) continue; - if( patternCompare(zPattern,zString,pInfo,matchOther, &bMatchAll) ){ - return 1; - } - if( bMatchAll ) break; + bMatch = patternCompare(zPattern,zString,pInfo,matchOther); + if( bMatch!=SQLITE_NOMATCH ) return bMatch; } } - return 0; + return SQLITE_NOWILDCARDMATCH; } if( c==matchOther ){ if( pInfo->matchSet==0 ){ c = sqlite3Utf8Read(&zPattern); - if( c==0 ) return 0; + if( c==0 ) return SQLITE_NOMATCH; zEscaped = zPattern; }else{ u32 prior_c = 0; int seen = 0; int invert = 0; c = sqlite3Utf8Read(&zString); - if( c==0 ) return 0; + if( c==0 ) return SQLITE_NOMATCH; c2 = sqlite3Utf8Read(&zPattern); if( c2=='^' ){ invert = 1; @@ -748,7 +750,7 @@ static int patternCompare( c2 = sqlite3Utf8Read(&zPattern); } if( c2==0 || (seen ^ invert)==0 ){ - return 0; + return SQLITE_NOMATCH; } continue; } @@ -759,25 +761,25 @@ static int patternCompare( continue; } if( c==matchOne && zPattern!=zEscaped && c2!=0 ) continue; - return 0; + return SQLITE_NOMATCH; } - return *zString==0; + return *zString==0 ? SQLITE_MATCH : SQLITE_NOMATCH; } /* -** The sqlite3_strglob() interface. +** The sqlite3_strglob() interface. Return 0 on a match (like strcmp()) and +** non-zero if there is no match. */ int sqlite3_strglob(const char *zGlobPattern, const char *zString){ - int dummy = 0; - return patternCompare((u8*)zGlobPattern, (u8*)zString, &globInfo, '[', &dummy)==0; + return patternCompare((u8*)zGlobPattern, (u8*)zString, &globInfo, '['); } /* -** The sqlite3_strlike() interface. +** The sqlite3_strlike() interface. Return 0 on a match and non-zero for +** a miss - like strcmp(). */ int sqlite3_strlike(const char *zPattern, const char *zStr, unsigned int esc){ - int dummy = 0; - return patternCompare((u8*)zPattern, (u8*)zStr, &likeInfoNorm, esc, &dummy)==0; + return patternCompare((u8*)zPattern, (u8*)zStr, &likeInfoNorm, esc); } /* @@ -855,11 +857,10 @@ static void likeFunc( escape = pInfo->matchSet; } if( zA && zB ){ - int dummy = 0; #ifdef SQLITE_TEST sqlite3_like_count++; #endif - sqlite3_result_int(context, patternCompare(zB, zA, pInfo, escape, &dummy)); + sqlite3_result_int(context, patternCompare(zB, zA, pInfo, escape)==SQLITE_MATCH); } } From 92ddb3bd021fe08b9f157224ba08fde7bb0b775b Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 1 Dec 2016 19:38:05 +0000 Subject: [PATCH 1039/1484] Avoid clearing the EP_FromJoin flag from terms in ON clauses when flattening sub-selects. Possible fix for [2df0107b]. FossilOrigin-Name: 8bed4cd549759a93c4a087d8d8c08c0068ba8d59 --- manifest | 20 +++++++++++--------- manifest.uuid | 2 +- src/select.c | 4 ++++ test/join5.test | 30 +++++++++++++++++++++++++++++- 4 files changed, 45 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 867860bee6..c8dd5c396b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sremember(V,PTR)\sextension\sfunction\swhich\scopies\san\sSQL\svalue\sinto\nan\sapplication\svariable. -D 2016-11-30T16:54:52.848 +C Avoid\sclearing\sthe\sEP_FromJoin\sflag\sfrom\sterms\sin\sON\sclauses\swhen\sflattening\nsub-selects.\sPossible\sfix\sfor\s[2df0107b]. +D 2016-12-01T19:38:05.478 F Makefile.in 7639c6a09da11a9c7c6f2630fc981ee588d1072d F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -388,7 +388,7 @@ F src/printf.c f94da4935d1dd25420ac50c6745db1deb35e07c1 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c bb070cf5f23611c44ab7e4788803684e385fc3fb F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac -F src/select.c 668c6865b16813dab5f9c18d3672fed11a5c34c5 +F src/select.c 403775526d5e0e420924fe89f34256dc1dd98d48 F src/shell.c a3fc2c719ed6d381895cbdb66a4a9b6a791cb02e F src/sqlite.h.in e8e2d108d82647f0a812fdb74accf91c1ec08ddc F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -881,7 +881,7 @@ F test/join.test f9d4a28dec81c6e9dc21b73518e024d73b5ebf57 F test/join2.test f2171c265e57ee298a27e57e7051d22962f9f324 F test/join3.test 6f0c774ff1ba0489e6c88a3e77b9d3528fb4fda0 F test/join4.test 1a352e4e267114444c29266ce79e941af5885916 -F test/join5.test 8a5c0be6f0c260a5c7177c3b8f07c7856141038a +F test/join5.test bc98ea4b4e5003f5b1453701ebb8cd7d1c01a550 F test/join6.test cfe6503791ceb0cbb509966740286ec423cbf10b F test/journal1.test 69abc726c51b4a0409189f9a85191205297c0577 F test/journal2.test 9dac6b4ba0ca79c3b21446bbae993a462c2397c4 @@ -1536,8 +1536,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 3816bb415ecfd4f36430d0fcbc878e382975de60 f0942c362f45ca1e986e142dbdd3ad957626dfb1 -R cd510c86291ec9069bea94544a3e0b95 -T +closed f0942c362f45ca1e986e142dbdd3ad957626dfb1 -U drh -Z 6b290cfef4656939d1e961e713e76c69 +P d2d30914d81022d7d4e1670caf9326524520deaf +R 1ad7b1a9bc1f307af71495d29fca4162 +T *branch * left-join-fix +T *sym-left-join-fix * +T -sym-trunk * +U dan +Z 70e2f22a0ab5072019cd24cf4ad22371 diff --git a/manifest.uuid b/manifest.uuid index 305748dc68..9c4dc93c62 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d2d30914d81022d7d4e1670caf9326524520deaf \ No newline at end of file +8bed4cd549759a93c4a087d8d8c08c0068ba8d59 \ No newline at end of file diff --git a/src/select.c b/src/select.c index 8e6022c9cd..e0b8fccc53 100644 --- a/src/select.c +++ b/src/select.c @@ -3164,6 +3164,10 @@ static Expr *substExpr( assert( pEList!=0 && pExpr->iColumnnExpr ); assert( pExpr->pLeft==0 && pExpr->pRight==0 ); pNew = sqlite3ExprDup(db, pEList->a[pExpr->iColumn].pExpr, 0); + if( pNew && (pExpr->flags & EP_FromJoin) ){ + pNew->iRightJoinTable = pExpr->iRightJoinTable; + pNew->flags |= EP_FromJoin; + } sqlite3ExprDelete(db, pExpr); pExpr = pNew; } diff --git a/test/join5.test b/test/join5.test index 543cd4d27f..352ffd40a6 100644 --- a/test/join5.test +++ b/test/join5.test @@ -13,10 +13,10 @@ # This file implements tests for left outer joins containing ON # clauses that restrict the scope of the left term of the join. # -# $Id: join5.test,v 1.2 2007/06/08 00:20:48 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl +set testprefix join5 do_test join5-1.1 { @@ -184,4 +184,32 @@ do_execsql_test join6-4.2 { LEFT JOIN (SELECT 1) ON fruit='banana'; } {apple {} banana 1} +#------------------------------------------------------------------------- +do_execsql_test 5.0 { + CREATE TABLE y1(x, y, z); + INSERT INTO y1 VALUES(0, 0, 1); + CREATE TABLE y2(a); +} + +do_execsql_test 5.1 { + SELECT count(z) FROM y1 LEFT JOIN y2 ON x GROUP BY y; +} 1 + +do_execsql_test 5.2 { + SELECT count(z) FROM ( SELECT * FROM y1 ) LEFT JOIN y2 ON x GROUP BY y; +} 1 + +do_execsql_test 5.3 { + CREATE VIEW v1 AS SELECT x, y, z FROM y1; + SELECT count(z) FROM v1 LEFT JOIN y2 ON x GROUP BY y; +} 1 + +do_execsql_test 5.4 { + SELECT count(z) FROM ( SELECT * FROM y1 ) LEFT JOIN y2 ON x +} 1 + +do_execsql_test 5.5 { + SELECT * FROM ( SELECT * FROM y1 ) LEFT JOIN y2 ON x +} {0 0 1 {}} + finish_test From 7a40707b1ffbec7664cebc945a132869ef8aedbe Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 2 Dec 2016 02:19:24 +0000 Subject: [PATCH 1040/1484] Test cases for the improved LIKE/GLOB matcher. FossilOrigin-Name: 0bdb7ae126d3909344640813489ee68ecad041c4 --- manifest | 15 +++++++-------- manifest.uuid | 2 +- test/like.test | 20 +++++++++++++++++++- 3 files changed, 27 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 6cac216075..7adba24c89 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sclearing\sthe\sEP_FromJoin\sflag\sfrom\sterms\sin\sON\sclauses\swhen\sflattening\nsub-selects.\sPossible\sfix\sfor\s[2df0107b]. -D 2016-12-01T19:58:01.439 +C Test\scases\sfor\sthe\simproved\sLIKE/GLOB\smatcher. +D 2016-12-02T02:19:24.505 F Makefile.in 7639c6a09da11a9c7c6f2630fc981ee588d1072d F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -895,7 +895,7 @@ F test/json103.test c5f6b85e69de05f6b3195f9f9d5ce9cd179099a0 F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63 F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200 -F test/like.test 81632c437a947bf1f7130b19537da6a1a844806a +F test/like.test 0603f4fa0dad50987f70032c05800cbfa8985302 F test/like2.test 3b2ee13149ba4a8a60b59756f4e5d345573852da F test/like3.test 3608a2042b6f922f900fbfd5d3ce4e7eca57f7c4 F test/limit.test 0c99a27a87b14c646a9d583c7c89fd06c352663e @@ -1536,8 +1536,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 2df0ebf95f6a25c77777c33685303e81550fd739 8bed4cd549759a93c4a087d8d8c08c0068ba8d59 -R 72f6d6d0e28ae71211501e4595390bfd -T +closed 8bed4cd549759a93c4a087d8d8c08c0068ba8d59 -U dan -Z a00b285125498e1667085e3791884b85 +P a427c4052820d90c3c8c23abf9097f973e564010 +R f16f032d9f385e340b291882ba284c15 +U drh +Z a0288af86999fbddd2602cee91996f35 diff --git a/manifest.uuid b/manifest.uuid index fa3a6d00fc..9002e90b71 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a427c4052820d90c3c8c23abf9097f973e564010 \ No newline at end of file +0bdb7ae126d3909344640813489ee68ecad041c4 \ No newline at end of file diff --git a/test/like.test b/test/like.test index fba89e9037..8082b35123 100644 --- a/test/like.test +++ b/test/like.test @@ -980,6 +980,24 @@ do_execsql_test like-13.4 { SELECT char(0x4d) LIKE char(0x6d); } {1} - +# Performance testing for patterns with many wildcards. These LIKE and GLOB +# patterns were quite slow with SQLite 3.15.2 and earlier. +# +do_test like-14.1 { + set x [lindex [time { + db one {SELECT 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaz'GLOB'*a*a*a*a*a*a*a*a*y'} + }] 0] + puts -nonewline " ($x ms - want less than 1000) " + expr {$x<1000} +} {1} +ifcapable !icu { + do_test like-14.2 { + set x [lindex [time { + db one {SELECT 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaz'LIKE'%a%a%a%a%a%a%a%a%y'} + }] 0] + puts -nonewline " ($x ms - want less than 1000) " + expr {$x<1000} + } {1} +} finish_test From 861a56821b1ce558b062d6a0f3f2f3ff4b848058 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 2 Dec 2016 17:08:27 +0000 Subject: [PATCH 1041/1484] Extend the valid range of 'unixepoch' dates from JulianDay 0 through 9999-12-31. FossilOrigin-Name: 768c9859b21a3c88be084d6dd87acab4211b3a87 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/date.c | 47 ++++++++++++++++++++++++++++++++++------------- 3 files changed, 41 insertions(+), 20 deletions(-) diff --git a/manifest b/manifest index 7adba24c89..6ee552ce01 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Test\scases\sfor\sthe\simproved\sLIKE/GLOB\smatcher. -D 2016-12-02T02:19:24.505 +C Extend\sthe\svalid\srange\sof\s'unixepoch'\sdates\sfrom\sJulianDay\s0\sthrough\s9999-12-31. +D 2016-12-02T17:08:27.447 F Makefile.in 7639c6a09da11a9c7c6f2630fc981ee588d1072d F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -338,7 +338,7 @@ F src/build.c 178f16698cbcb43402c343a9413fe22c99ffee21 F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c a2a52d6e353f459d8ab0f07321f60fafa47d5421 -F src/date.c 206d0eb85cedec99a9820929579057fb364a72cb +F src/date.c 58d4275a8778c2da80fcb515e2605c791a2b8884 F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c cac97d1117a3008934da3a6a587b3608e65e1495 F src/expr.c b22e09630f874c52db0770973b7ce55ee50c1dde @@ -1536,7 +1536,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a427c4052820d90c3c8c23abf9097f973e564010 -R f16f032d9f385e340b291882ba284c15 +P 0bdb7ae126d3909344640813489ee68ecad041c4 +R de507b0b0d00b8f392dd9c1b935d5409 U drh -Z a0288af86999fbddd2602cee91996f35 +Z 8b7f9d120e42b1682165e88e877e78a0 diff --git a/manifest.uuid b/manifest.uuid index 9002e90b71..b13054cb92 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0bdb7ae126d3909344640813489ee68ecad041c4 \ No newline at end of file +768c9859b21a3c88be084d6dd87acab4211b3a87 \ No newline at end of file diff --git a/src/date.c b/src/date.c index c675d17455..933d79c964 100644 --- a/src/date.c +++ b/src/date.c @@ -70,9 +70,10 @@ struct DateTime { int h, m; /* Hour and minutes */ int tz; /* Timezone offset in minutes */ double s; /* Seconds */ + char validJD; /* True (1) if iJD is valid */ + char rawS; /* Raw numeric value stored in s */ char validYMD; /* True (1) if Y,M,D are valid */ char validHMS; /* True (1) if h,m,s are valid */ - char validJD; /* True (1) if iJD is valid */ char validTZ; /* True (1) if tz is valid */ char tzSet; /* Timezone was set explicitly */ char isError; /* An overflow has occurred */ @@ -223,6 +224,7 @@ static int parseHhMmSs(const char *zDate, DateTime *p){ s = 0; } p->validJD = 0; + p->rawS = 0; p->validHMS = 1; p->h = h; p->m = m; @@ -259,7 +261,7 @@ static void computeJD(DateTime *p){ M = 1; D = 1; } - if( Y<-4713 || Y>9999 ){ + if( Y<-4713 || Y>9999 || p->rawS ){ datetimeError(p); return; } @@ -343,6 +345,21 @@ static int setDateTimeToCurrent(sqlite3_context *context, DateTime *p){ } } +/* +** Input "r" is a numeric quantity which might be a julian day number, +** or the number of seconds since 1970. If the value if r is within +** range of a julian day number, install it as such and set validJD. +** If the value is a valid unix timestamp, put it in p->s and set p->rawS. +*/ +static void setRawDateNumber(DateTime *p, double r){ + p->s = r; + p->rawS = 1; + if( r>=0.0 && r<5373484.5 ){ + p->iJD = (sqlite3_int64)(r*86400000.0 + 0.5); + p->validJD = 1; + } +} + /* ** Attempt to parse the given string into a julian day number. Return ** the number of errors. @@ -372,8 +389,7 @@ static int parseDateOrTime( }else if( sqlite3StrICmp(zDate,"now")==0){ return setDateTimeToCurrent(context, p); }else if( sqlite3AtoF(zDate, &r, sqlite3Strlen30(zDate), SQLITE_UTF8) ){ - p->iJD = (sqlite3_int64)(r*86400000.0 + 0.5); - p->validJD = 1; + setRawDateNumber(p, r); return 0; } return 1; @@ -432,6 +448,7 @@ static void computeHMS(DateTime *p){ s -= p->h*3600; p->m = s/60; p->s += s - p->m*60; + p->rawS = 0; p->validHMS = 1; } @@ -571,7 +588,9 @@ static sqlite3_int64 localtimeOffset( y.validYMD = 1; y.validHMS = 1; y.validJD = 0; + y.rawS = 0; y.validTZ = 0; + y.isError = 0; computeJD(&y); *pRc = SQLITE_OK; return y.iJD - x.iJD; @@ -632,13 +651,18 @@ static int parseModifier(sqlite3_context *pCtx, const char *zMod, DateTime *p){ /* ** unixepoch ** - ** Treat the current value of p->iJD as the number of + ** Treat the current value of p->s as the number of ** seconds since 1970. Convert to a real julian day number. */ - if( strcmp(z, "unixepoch")==0 && p->validJD ){ - p->iJD = (p->iJD + 43200)/86400 + 21086676*(i64)10000000; - clearYMD_HMS_TZ(p); - rc = 0; + if( strcmp(z, "unixepoch")==0 && p->rawS ){ + double r = p->s*1000.0 + 210866760000000.0; + if( r>=0.0 && r<464269060800000.0 ){ + clearYMD_HMS_TZ(p); + p->iJD = (sqlite3_int64)r; + p->validJD = 1; + p->rawS = 0; + rc = 0; + } } #ifndef SQLITE_OMIT_LOCALTIME else if( strcmp(z, "utc")==0 ){ @@ -829,10 +853,7 @@ static int isDate( } if( (eType = sqlite3_value_type(argv[0]))==SQLITE_FLOAT || eType==SQLITE_INTEGER ){ - double r = sqlite3_value_double(argv[0]); - if( r>106751991167.0 || r<-106751991167.0 ) return 1; - p->iJD = (sqlite3_int64)(r*86400000.0 + 0.5); - p->validJD = 1; + setRawDateNumber(p, sqlite3_value_double(argv[0])); }else{ z = sqlite3_value_text(argv[0]); if( !z || parseDateOrTime(context, (char*)z, p) ){ From 6d4e9c3d921aa651d84a04ac23bb4f4833e2688a Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 2 Dec 2016 19:07:03 +0000 Subject: [PATCH 1042/1484] Simplify the date/time function logic for improved rebustness and also to decrease the size of the binary. FossilOrigin-Name: 6e144735ed0cd3d4461ae6a4d8034264563e3165 --- manifest | 12 ++--- manifest.uuid | 2 +- src/date.c | 135 +++++++++++++++++++++++++++++--------------------- 3 files changed, 85 insertions(+), 64 deletions(-) diff --git a/manifest b/manifest index 6ee552ce01..ec3963b09e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Extend\sthe\svalid\srange\sof\s'unixepoch'\sdates\sfrom\sJulianDay\s0\sthrough\s9999-12-31. -D 2016-12-02T17:08:27.447 +C Simplify\sthe\sdate/time\sfunction\slogic\sfor\simproved\srebustness\sand\salso\sto\ndecrease\sthe\ssize\sof\sthe\sbinary. +D 2016-12-02T19:07:03.138 F Makefile.in 7639c6a09da11a9c7c6f2630fc981ee588d1072d F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -338,7 +338,7 @@ F src/build.c 178f16698cbcb43402c343a9413fe22c99ffee21 F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c a2a52d6e353f459d8ab0f07321f60fafa47d5421 -F src/date.c 58d4275a8778c2da80fcb515e2605c791a2b8884 +F src/date.c 116097946bffdfe510b30affa15b36026f632ae6 F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c cac97d1117a3008934da3a6a587b3608e65e1495 F src/expr.c b22e09630f874c52db0770973b7ce55ee50c1dde @@ -1536,7 +1536,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 0bdb7ae126d3909344640813489ee68ecad041c4 -R de507b0b0d00b8f392dd9c1b935d5409 +P 768c9859b21a3c88be084d6dd87acab4211b3a87 +R 65ce4f7c2b4b3fd05ab801cab333052f U drh -Z 8b7f9d120e42b1682165e88e877e78a0 +Z 0e9aea10c8c8bd36917285b40426a93d diff --git a/manifest.uuid b/manifest.uuid index b13054cb92..ac1f572256 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -768c9859b21a3c88be084d6dd87acab4211b3a87 \ No newline at end of file +6e144735ed0cd3d4461ae6a4d8034264563e3165 \ No newline at end of file diff --git a/src/date.c b/src/date.c index 933d79c964..fd95582b06 100644 --- a/src/date.c +++ b/src/date.c @@ -414,10 +414,8 @@ static void computeYMD(DateTime *p){ p->Y = 2000; p->M = 1; p->D = 1; - }else if( !validJulianDay(p->iJD) ){ - datetimeError(p); - return; }else{ + assert( validJulianDay(p->iJD) ); Z = (int)((p->iJD + 43200000)/86400000); A = (int)((Z - 1867216.25)/36524.25); A = Z + 1 + A - (A/4); @@ -597,6 +595,29 @@ static sqlite3_int64 localtimeOffset( } #endif /* SQLITE_OMIT_LOCALTIME */ +/* +** The following table defines various date transformations of the form +** +** 'NNN days' +** +** Where NNN is an arbitrary floating-point number and "days" can be one +** of several units of time. +*/ +static const struct { + u8 eType; /* Transformation type code */ + u8 nName; /* Length of th name */ + char *zName; /* Name of the transformation */ + double rLimit; /* Maximum NNN value for this transform */ + double rXform; /* Constant used for this transform */ +} aXformType[] = { + { 0, 6, "second", 464269060800.0, 86400000.0/(24.0*60.0*60.0) }, + { 0, 6, "minute", 7737817680.0, 86400000.0/(24.0*60.0) }, + { 0, 4, "hour", 128963628.0, 86400000.0/24.0 }, + { 0, 3, "day", 5373485.0, 86400000.0 }, + { 1, 5, "month", 176546.0, 30.0*86400000.0 }, + { 2, 4, "year", 14713.0, 365.0*86400000.0 }, +}; + /* ** Process a modifier to a date-time stamp. The modifiers are ** as follows: @@ -621,17 +642,15 @@ static sqlite3_int64 localtimeOffset( ** to context pCtx. If the error is an unrecognized modifier, no error is ** written to pCtx. */ -static int parseModifier(sqlite3_context *pCtx, const char *zMod, DateTime *p){ +static int parseModifier( + sqlite3_context *pCtx, /* Function context */ + const char *z, /* The text of the modifier */ + int n, /* Length of zMod in bytes */ + DateTime *p /* The date/time value to be modified */ +){ int rc = 1; - int n; double r; - char *z, zBuf[30]; - z = zBuf; - for(n=0; niJD += localtimeOffset(p, pCtx, &rc); clearYMD_HMS_TZ(p); @@ -654,7 +673,7 @@ static int parseModifier(sqlite3_context *pCtx, const char *zMod, DateTime *p){ ** Treat the current value of p->s as the number of ** seconds since 1970. Convert to a real julian day number. */ - if( strcmp(z, "unixepoch")==0 && p->rawS ){ + if( sqlite3_stricmp(z, "unixepoch")==0 && p->rawS ){ double r = p->s*1000.0 + 210866760000000.0; if( r>=0.0 && r<464269060800000.0 ){ clearYMD_HMS_TZ(p); @@ -665,7 +684,7 @@ static int parseModifier(sqlite3_context *pCtx, const char *zMod, DateTime *p){ } } #ifndef SQLITE_OMIT_LOCALTIME - else if( strcmp(z, "utc")==0 ){ + else if( sqlite3_stricmp(z, "utc")==0 ){ if( p->tzSet==0 ){ sqlite3_int64 c1; computeJD(p); @@ -691,7 +710,7 @@ static int parseModifier(sqlite3_context *pCtx, const char *zMod, DateTime *p){ ** weekday N where 0==Sunday, 1==Monday, and so forth. If the ** date is already on the appropriate weekday, this is a no-op. */ - if( strncmp(z, "weekday ", 8)==0 + if( sqlite3_strnicmp(z, "weekday ", 8)==0 && sqlite3AtoF(&z[8], &r, sqlite3Strlen30(&z[8]), SQLITE_UTF8) && (n=(int)r)==r && n>=0 && r<7 ){ sqlite3_int64 Z; @@ -714,7 +733,7 @@ static int parseModifier(sqlite3_context *pCtx, const char *zMod, DateTime *p){ ** Move the date backwards to the beginning of the current day, ** or month or year. */ - if( strncmp(z, "start of ", 9)!=0 ) break; + if( sqlite3_strnicmp(z, "start of ", 9)!=0 ) break; z += 9; computeYMD(p); p->validHMS = 1; @@ -722,15 +741,15 @@ static int parseModifier(sqlite3_context *pCtx, const char *zMod, DateTime *p){ p->s = 0.0; p->validTZ = 0; p->validJD = 0; - if( strcmp(z,"month")==0 ){ + if( sqlite3_stricmp(z,"month")==0 ){ p->D = 1; rc = 0; - }else if( strcmp(z,"year")==0 ){ + }else if( sqlite3_stricmp(z,"year")==0 ){ computeYMD(p); p->M = 1; p->D = 1; rc = 0; - }else if( strcmp(z,"day")==0 ){ + }else if( sqlite3_stricmp(z,"day")==0 ){ rc = 0; } break; @@ -748,7 +767,7 @@ static int parseModifier(sqlite3_context *pCtx, const char *zMod, DateTime *p){ case '8': case '9': { double rRounder; - double rAbs; + int i; for(n=1; z[n] && z[n]!=':' && !sqlite3Isspace(z[n]); n++){} if( !sqlite3AtoF(z, &r, n, SQLITE_UTF8) ){ rc = 1; @@ -777,47 +796,48 @@ static int parseModifier(sqlite3_context *pCtx, const char *zMod, DateTime *p){ rc = 0; break; } + + /* If control reaches this point, it means the transformation is + ** one of the forms like "+NNN days". */ z += n; while( sqlite3Isspace(*z) ) z++; n = sqlite3Strlen30(z); if( n>10 || n<3 ) break; - if( z[n-1]=='s' ){ z[n-1] = 0; n--; } + if( sqlite3UpperToLower[(u8)z[n-1]]=='s' ) n--; computeJD(p); - rc = 0; + rc = 1; rRounder = r<0 ? -0.5 : +0.5; - rAbs = r<0 ? -r : r; - if( n==3 && strcmp(z,"day")==0 && rAbs<5373485.0 ){ - p->iJD += (sqlite3_int64)(r*86400000.0 + rRounder); - }else if( n==4 && strcmp(z,"hour")==0 && rAbs<128963628.0 ){ - p->iJD += (sqlite3_int64)(r*(86400000.0/24.0) + rRounder); - }else if( n==6 && strcmp(z,"minute")==0 && rAbs<7737817680.0 ){ - p->iJD += (sqlite3_int64)(r*(86400000.0/(24.0*60.0)) + rRounder); - }else if( n==6 && strcmp(z,"second")==0 && rAbs<464269060800.0 ){ - p->iJD += (sqlite3_int64)(r*(86400000.0/(24.0*60.0*60.0)) + rRounder); - }else if( n==5 && strcmp(z,"month")==0 && rAbs<176546.0 ){ - int x, y; - computeYMD_HMS(p); - p->M += (int)r; - x = p->M>0 ? (p->M-1)/12 : (p->M-12)/12; - p->Y += x; - p->M -= x*12; - p->validJD = 0; - computeJD(p); - y = (int)r; - if( y!=r ){ - p->iJD += (sqlite3_int64)((r - y)*30.0*86400000.0 + rRounder); + for(i=0; i-aXformType[i].rLimit && rM += (int)r; + x = p->M>0 ? (p->M-1)/12 : (p->M-12)/12; + p->Y += x; + p->M -= x*12; + p->validJD = 0; + r -= (int)r; + break; + } + case 2: { /* Special processing to add years */ + int y = (int)r; + computeYMD_HMS(p); + p->Y += y; + p->validJD = 0; + r -= (int)r; + break; + } + } + computeJD(p); + p->iJD += (sqlite3_int64)(r*aXformType[i].rXform + rRounder); + rc = 0; + break; } - }else if( n==4 && strcmp(z,"year")==0 && rAbs<14713.0 ){ - int y = (int)r; - computeYMD_HMS(p); - p->Y += y; - p->validJD = 0; - computeJD(p); - if( y!=r ){ - p->iJD += (sqlite3_int64)((r - y)*365.0*86400000.0 + rRounder); - } - }else{ - rc = 1; } clearYMD_HMS_TZ(p); break; @@ -844,7 +864,7 @@ static int isDate( sqlite3_value **argv, DateTime *p ){ - int i; + int i, n; const unsigned char *z; int eType; memset(p, 0, sizeof(*p)); @@ -862,7 +882,8 @@ static int isDate( } for(i=1; iisError || !validJulianDay(p->iJD) ) return 1; From 25ef7f55d778708e96694a16fa1f319f0ff4b96f Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 5 Dec 2016 20:06:45 +0000 Subject: [PATCH 1043/1484] Work around a bug in the definition of "ino_t" on some versions of Android. FossilOrigin-Name: 8df492c1711bfea250264fdaa4892e0842705f83 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/os_unix.c | 16 ++++++++++++---- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index ec3963b09e..8c4b021684 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Simplify\sthe\sdate/time\sfunction\slogic\sfor\simproved\srebustness\sand\salso\sto\ndecrease\sthe\ssize\sof\sthe\sbinary. -D 2016-12-02T19:07:03.138 +C Work\saround\sa\sbug\sin\sthe\sdefinition\sof\s"ino_t"\son\ssome\sversions\sof\sAndroid. +D 2016-12-05T20:06:45.078 F Makefile.in 7639c6a09da11a9c7c6f2630fc981ee588d1072d F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -372,7 +372,7 @@ F src/os.c add02933b1dce7a39a005b00a2f5364b763e9a24 F src/os.h 8e976e59eb4ca1c0fca6d35ee803e38951cb0343 F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85 F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586 -F src/os_unix.c be9ca0f901a2b6c1bc93dc338f4863675180c189 +F src/os_unix.c 30e2c43e4955db990e5b5a81e901f8aa74cc8820 F src/os_win.c cf90abd4e50d9f56d2c20ce8e005aff55d7bd8e9 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c 4e4aea7ced5734753ccbff4cf4bb4d032cf2173e @@ -1536,7 +1536,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 768c9859b21a3c88be084d6dd87acab4211b3a87 -R 65ce4f7c2b4b3fd05ab801cab333052f +P 6e144735ed0cd3d4461ae6a4d8034264563e3165 +R 8d68a5c1fa2466ac0f1223eb05620da4 U drh -Z 0e9aea10c8c8bd36917285b40426a93d +Z 14362e44254b879dd6931510df84654e diff --git a/manifest.uuid b/manifest.uuid index ac1f572256..41e870bba2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6e144735ed0cd3d4461ae6a4d8034264563e3165 \ No newline at end of file +8df492c1711bfea250264fdaa4892e0842705f83 \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index 08d4cb5d11..7f0ebdba6f 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -1061,7 +1061,14 @@ struct unixFileId { #if OS_VXWORKS struct vxworksFileId *pId; /* Unique file ID for vxworks. */ #else - ino_t ino; /* Inode number */ + /* We are told that some versions of Android contain a bug that + ** sizes ino_t at only 32-bits instead of 64-bits. (See + ** https://android-review.googlesource.com/#/c/115351/3/dist/sqlite3.c) + ** To work around this, always allocate 64-bits for the inode number. + ** On small machines that only have 32-bit inodes, this wastes 4 bytes, + ** but that should not be a big deal. */ + /* WAS: ino_t ino; */ + u64 ino; /* Inode number */ #endif }; @@ -1306,7 +1313,7 @@ static int findInodeInfo( #if OS_VXWORKS fileId.pId = pFile->pId; #else - fileId.ino = statbuf.st_ino; + fileId.ino = (u64)statbuf.st_ino; #endif pInode = inodeList; while( pInode && memcmp(&fileId, &pInode->fileId, sizeof(fileId)) ){ @@ -1340,7 +1347,8 @@ static int fileHasMoved(unixFile *pFile){ #else struct stat buf; return pFile->pInode!=0 && - (osStat(pFile->zPath, &buf)!=0 || buf.st_ino!=pFile->pInode->fileId.ino); + (osStat(pFile->zPath, &buf)!=0 + || (u64)buf.st_ino!=pFile->pInode->fileId.ino); #endif } @@ -5512,7 +5520,7 @@ static UnixUnusedFd *findReusableFd(const char *zPath, int flags){ unixEnterMutex(); pInode = inodeList; while( pInode && (pInode->fileId.dev!=sStat.st_dev - || pInode->fileId.ino!=sStat.st_ino) ){ + || pInode->fileId.ino!=(u64)sStat.st_ino) ){ pInode = pInode->pNext; } if( pInode ){ From e6ad1717da58d9006c9fe46c32f1535140bf2e60 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 5 Dec 2016 20:16:04 +0000 Subject: [PATCH 1044/1484] Fix a harmless redundant local variable declaration in the date/time function logic. FossilOrigin-Name: b4bc40d1836d8ed0803b81a734ce48be8e9d434a --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/date.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 8c4b021684..6cb1a0e4fa 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Work\saround\sa\sbug\sin\sthe\sdefinition\sof\s"ino_t"\son\ssome\sversions\sof\sAndroid. -D 2016-12-05T20:06:45.078 +C Fix\sa\sharmless\sredundant\slocal\svariable\sdeclaration\sin\sthe\sdate/time\sfunction\nlogic. +D 2016-12-05T20:16:04.626 F Makefile.in 7639c6a09da11a9c7c6f2630fc981ee588d1072d F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -338,7 +338,7 @@ F src/build.c 178f16698cbcb43402c343a9413fe22c99ffee21 F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c a2a52d6e353f459d8ab0f07321f60fafa47d5421 -F src/date.c 116097946bffdfe510b30affa15b36026f632ae6 +F src/date.c 57f23f5835c0b8b2be0e71f3b0a38e5960d053ec F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c cac97d1117a3008934da3a6a587b3608e65e1495 F src/expr.c b22e09630f874c52db0770973b7ce55ee50c1dde @@ -1536,7 +1536,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 6e144735ed0cd3d4461ae6a4d8034264563e3165 -R 8d68a5c1fa2466ac0f1223eb05620da4 +P 8df492c1711bfea250264fdaa4892e0842705f83 +R 8fe53b14c4c2a7f94eb87c2ca6789b39 U drh -Z 14362e44254b879dd6931510df84654e +Z 87a0907e7cda49221885d8ac7a3cd194 diff --git a/manifest.uuid b/manifest.uuid index 41e870bba2..dcb25a027a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8df492c1711bfea250264fdaa4892e0842705f83 \ No newline at end of file +b4bc40d1836d8ed0803b81a734ce48be8e9d434a \ No newline at end of file diff --git a/src/date.c b/src/date.c index fd95582b06..62a03ddb66 100644 --- a/src/date.c +++ b/src/date.c @@ -674,7 +674,7 @@ static int parseModifier( ** seconds since 1970. Convert to a real julian day number. */ if( sqlite3_stricmp(z, "unixepoch")==0 && p->rawS ){ - double r = p->s*1000.0 + 210866760000000.0; + r = p->s*1000.0 + 210866760000000.0; if( r>=0.0 && r<464269060800000.0 ){ clearYMD_HMS_TZ(p); p->iJD = (sqlite3_int64)r; From 634133183cec6e45a2b30668d0659ffedf8eb6d3 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 6 Dec 2016 17:59:05 +0000 Subject: [PATCH 1045/1484] In the LEMON parser-generator, fix the stack overflow processing so that it correct invokes the destructor on the top-level of the parse stack. FossilOrigin-Name: e8247065cf1d929f42d13864f8a1886ed4d329cd --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/fuzzdata5.db | Bin 6960128 -> 6964224 bytes tool/lempar.c | 3 ++- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 6cb1a0e4fa..7150d72336 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sharmless\sredundant\slocal\svariable\sdeclaration\sin\sthe\sdate/time\sfunction\nlogic. -D 2016-12-05T20:16:04.626 +C In\sthe\sLEMON\sparser-generator,\sfix\sthe\sstack\soverflow\sprocessing\sso\sthat\sit\ncorrect\sinvokes\sthe\sdestructor\son\sthe\stop-level\sof\sthe\sparse\sstack. +D 2016-12-06T17:59:05.162 F Makefile.in 7639c6a09da11a9c7c6f2630fc981ee588d1072d F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -820,7 +820,7 @@ F test/fuzzdata1.db 7ee3227bad0e7ccdeb08a9e6822916777073c664 F test/fuzzdata2.db f03a420d3b822cc82e4f894ca957618fbe9c4973 F test/fuzzdata3.db c6586d3e3cef0fbc18108f9bb649aa77bfc38aba F test/fuzzdata4.db 1882f0055fb63214d8407ddc7aca9b0b1c59af21 -F test/fuzzdata5.db e143587fe774458ea928abaaa85a98019396f573 +F test/fuzzdata5.db 9f0cdcc5c6e83b90cf9ae343bd07f684d2da2de7 F test/fuzzer1.test 3d4c4b7e547aba5e5511a2991e3e3d07166cfbb8 F test/fuzzer2.test a85ef814ce071293bce1ad8dffa217cbbaad4c14 F test/fuzzerfault.test 8792cd77fd5bce765b05d0c8e01b9edcf8af8536 @@ -1464,7 +1464,7 @@ F tool/genfkey.README cf68fddd4643bbe3ff8e31b8b6d8b0a1b85e20f4 F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5 F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce F tool/lemon.c e4fb7d888873ac88f20a41c84a7d1e61f5209a6d -F tool/lempar.c 7cf047778e74433126cb02896e3f898d7b1e20aa +F tool/lempar.c 320d630b44da693407684c64d9fa91a163419dac F tool/libvers.c caafc3b689638a1d88d44bc5f526c2278760d9b9 F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862 F tool/logest.c 11346aa019e2e77a00902aa7d0cabd27bd2e8cca @@ -1536,7 +1536,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 8df492c1711bfea250264fdaa4892e0842705f83 -R 8fe53b14c4c2a7f94eb87c2ca6789b39 +P b4bc40d1836d8ed0803b81a734ce48be8e9d434a +R 81d8a2026014eefac917511077da3519 U drh -Z 87a0907e7cda49221885d8ac7a3cd194 +Z 9f71fcfb3a0f47c77589a0b90da6d3b4 diff --git a/manifest.uuid b/manifest.uuid index dcb25a027a..98f131efca 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b4bc40d1836d8ed0803b81a734ce48be8e9d434a \ No newline at end of file +e8247065cf1d929f42d13864f8a1886ed4d329cd \ No newline at end of file diff --git a/test/fuzzdata5.db b/test/fuzzdata5.db index 2aad5b0caabfc3022e666dba7c4c850b73f8f4e6..4645b1921b32d1b4a8255c69904eb968a023ca77 100644 GIT binary patch delta 92799 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 K-9TR<%YOr7sxtHd delta 88688 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

    ;xOnZjh_Pb#Ry<#0UZN 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 Q;T?#ISgOsXuaV_{0Ggf%qW}N^ diff --git a/tool/lempar.c b/tool/lempar.c index 5195d9c31b..dab8343f3a 100644 --- a/tool/lempar.c +++ b/tool/lempar.c @@ -538,7 +538,6 @@ static int yy_find_reduce_action( */ static void yyStackOverflow(yyParser *yypParser){ ParseARG_FETCH; - yypParser->yytos--; #ifndef NDEBUG if( yyTraceFILE ){ fprintf(yyTraceFILE,"%sStack Overflow!\n",yyTracePrompt); @@ -592,12 +591,14 @@ static void yy_shift( #endif #if YYSTACKDEPTH>0 if( yypParser->yytos>=&yypParser->yystack[YYSTACKDEPTH] ){ + yypParser->yytos--; yyStackOverflow(yypParser); return; } #else if( yypParser->yytos>=&yypParser->yystack[yypParser->yystksz] ){ if( yyGrowStack(yypParser) ){ + yypParser->yytos--; yyStackOverflow(yypParser); return; } From 2b519ab0155a0559888a571659b7a68e922db06d Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 6 Dec 2016 19:33:42 +0000 Subject: [PATCH 1046/1484] Add missing nul-terminator to a Tcl_AppendResult() call in tclsqlite.c. FossilOrigin-Name: 0820f8b3dedfc846d187844847dfa8617539fc9a --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/tclsqlite.c | 3 ++- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 7150d72336..d0b42b46fd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\sthe\sLEMON\sparser-generator,\sfix\sthe\sstack\soverflow\sprocessing\sso\sthat\sit\ncorrect\sinvokes\sthe\sdestructor\son\sthe\stop-level\sof\sthe\sparse\sstack. -D 2016-12-06T17:59:05.162 +C Add\smissing\snul-terminator\sto\sa\sTcl_AppendResult()\scall\sin\stclsqlite.c. +D 2016-12-06T19:33:42.745 F Makefile.in 7639c6a09da11a9c7c6f2630fc981ee588d1072d F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -397,7 +397,7 @@ F src/sqliteInt.h c471d791b10c0f2164c8b7a87adc338e703c09cc F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 -F src/tclsqlite.c aef87dcd8cb66564d560ab48d43d19ac812a1eab +F src/tclsqlite.c 205c66b9b81d97978a155caa3ef5be9c4de2b174 F src/test1.c 8a98191a1da8e100f77cdb5cc716df67d405028d F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5 F src/test3.c d03f5b5da9a2410b7a91c64b0d3306ed28ab6fee @@ -1536,7 +1536,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b4bc40d1836d8ed0803b81a734ce48be8e9d434a -R 81d8a2026014eefac917511077da3519 -U drh -Z 9f71fcfb3a0f47c77589a0b90da6d3b4 +P e8247065cf1d929f42d13864f8a1886ed4d329cd +R d584b43abf3b6acb5fcfedbaac517d67 +U dan +Z 4afd164e190ae9a4d35011e09b19c24e diff --git a/manifest.uuid b/manifest.uuid index 98f131efca..9c8cae6e20 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e8247065cf1d929f42d13864f8a1886ed4d329cd \ No newline at end of file +0820f8b3dedfc846d187844847dfa8617539fc9a \ No newline at end of file diff --git a/src/tclsqlite.c b/src/tclsqlite.c index b2f13bd5ed..1d87c9b331 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -3140,7 +3140,8 @@ static int SQLITE_TCLAPI DbObjCmd( */ case DB_PREUPDATE: { #ifndef SQLITE_ENABLE_PREUPDATE_HOOK - Tcl_AppendResult(interp, "preupdate_hook was omitted at compile-time"); + Tcl_AppendResult(interp, "preupdate_hook was omitted at compile-time", + (char*)0); rc = TCL_ERROR; #else static const char *azSub[] = {"count", "depth", "hook", "new", "old", 0}; From abfd35ea03475fab71b71e1320f103dc43cce523 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 6 Dec 2016 22:47:23 +0000 Subject: [PATCH 1047/1484] Performance improvement and size reduction in the Expr node allocator function sqlite3PExpr(). FossilOrigin-Name: 2a81763e68cdf9b8c46389b1e1a87bc2084b53e7 --- manifest | 28 +++++++++++++-------------- manifest.uuid | 2 +- src/delete.c | 6 +++--- src/expr.c | 12 ++++++++---- src/fkey.c | 26 +++++++++++-------------- src/parse.y | 51 +++++++++++++++++++++++++------------------------ src/select.c | 6 +++--- src/sqliteInt.h | 2 +- src/wherecode.c | 4 ++-- src/whereexpr.c | 16 ++++++++-------- 10 files changed, 77 insertions(+), 76 deletions(-) diff --git a/manifest b/manifest index d0b42b46fd..55337320a3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\smissing\snul-terminator\sto\sa\sTcl_AppendResult()\scall\sin\stclsqlite.c. -D 2016-12-06T19:33:42.745 +C Performance\simprovement\sand\ssize\sreduction\sin\sthe\sExpr\snode\sallocator\nfunction\ssqlite3PExpr(). +D 2016-12-06T22:47:23.006 F Makefile.in 7639c6a09da11a9c7c6f2630fc981ee588d1072d F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -340,10 +340,10 @@ F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c a2a52d6e353f459d8ab0f07321f60fafa47d5421 F src/date.c 57f23f5835c0b8b2be0e71f3b0a38e5960d053ec F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d -F src/delete.c cac97d1117a3008934da3a6a587b3608e65e1495 -F src/expr.c b22e09630f874c52db0770973b7ce55ee50c1dde +F src/delete.c a6881ec5a7d1adc6157dfe1596ead3522db04740 +F src/expr.c b4db982acf30aad864a047bf7676fa85761fc55e F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb -F src/fkey.c b9ca262f6ad4d030a3cab737ebf9b0b3c8b4ac80 +F src/fkey.c 4017dc6d8bf894c4818ffbaf392e53c7c68dd761 F src/func.c 43916c1d8e6da5d107d91d2b212577d4f69a876a F src/global.c 9da4ca5d74b90715f0ec4957f3d17a4749009f34 F src/hash.c 63d0ee752a3b92d4695b2b1f5259c4621b2cfebd @@ -377,7 +377,7 @@ F src/os_win.c cf90abd4e50d9f56d2c20ce8e005aff55d7bd8e9 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c 4e4aea7ced5734753ccbff4cf4bb4d032cf2173e F src/pager.h d1e944291030351f362a0a7da9b5c3e34e603e39 -F src/parse.y 0338f906b61e311c2b7e11a3f89b0092c780b664 +F src/parse.y 29153738a7322054359320eb00b5a4cd44389f20 F src/pcache.c 5ff2a08f76a9c1b22f43eb063b7068fb085465ac F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 F src/pcache1.c e3967219b2a92b9edcb9324a4ba75009090d3953 @@ -388,12 +388,12 @@ F src/printf.c f94da4935d1dd25420ac50c6745db1deb35e07c1 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c bb070cf5f23611c44ab7e4788803684e385fc3fb F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac -F src/select.c 403775526d5e0e420924fe89f34256dc1dd98d48 +F src/select.c ee68944dfee9d548032bba3fdd5a6355011212c0 F src/shell.c a3fc2c719ed6d381895cbdb66a4a9b6a791cb02e F src/sqlite.h.in e8e2d108d82647f0a812fdb74accf91c1ec08ddc F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae -F src/sqliteInt.h c471d791b10c0f2164c8b7a87adc338e703c09cc +F src/sqliteInt.h bdfd92824dd50ff037373aaada276f90b168952d F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 @@ -471,8 +471,8 @@ F src/wal.h 06b2a0b599cc0f53ea97f497cf8c6b758c999f71 F src/walker.c 91a6df7435827e41cff6bb7df50ea00934ee78b0 F src/where.c 6bbf9284f4f15a6fa48663d033870cc0d7f5ee66 F src/whereInt.h 2bcc3d176e6091cb8f50a30b65c006e88a73614d -F src/wherecode.c 4ea298998499db5a407ffd70e87e119a86ed7834 -F src/whereexpr.c c19a84ac530835d37217db2181e4fe75901b7b97 +F src/wherecode.c 9a3b1034191c9ea8ac14a5405564402f8b1114b2 +F src/whereexpr.c 87ecdf24beba4498e4380b31c4131febb0a6ceaa F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1536,7 +1536,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e8247065cf1d929f42d13864f8a1886ed4d329cd -R d584b43abf3b6acb5fcfedbaac517d67 -U dan -Z 4afd164e190ae9a4d35011e09b19c24e +P 0820f8b3dedfc846d187844847dfa8617539fc9a +R 66c67520d75b6cc9d6a9f98310fc2b1f +U drh +Z aa79b15c8c6da20e9ca7087094bfadd8 diff --git a/manifest.uuid b/manifest.uuid index 9c8cae6e20..40f364d25f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0820f8b3dedfc846d187844847dfa8617539fc9a \ No newline at end of file +2a81763e68cdf9b8c46389b1e1a87bc2084b53e7 \ No newline at end of file diff --git a/src/delete.c b/src/delete.c index 9cd1cd0f25..aaf1bc7d7f 100644 --- a/src/delete.c +++ b/src/delete.c @@ -164,7 +164,7 @@ Expr *sqlite3LimitWhere( ** ); */ - pSelectRowid = sqlite3PExpr(pParse, TK_ROW, 0, 0, 0); + pSelectRowid = sqlite3PExpr(pParse, TK_ROW, 0, 0); if( pSelectRowid == 0 ) goto limit_where_cleanup; pEList = sqlite3ExprListAppend(pParse, 0, pSelectRowid); if( pEList == 0 ) goto limit_where_cleanup; @@ -183,8 +183,8 @@ Expr *sqlite3LimitWhere( if( pSelect == 0 ) return 0; /* now generate the new WHERE rowid IN clause for the DELETE/UDPATE */ - pWhereRowid = sqlite3PExpr(pParse, TK_ROW, 0, 0, 0); - pInClause = pWhereRowid ? sqlite3PExpr(pParse, TK_IN, pWhereRowid, 0, 0) : 0; + pWhereRowid = sqlite3PExpr(pParse, TK_ROW, 0, 0); + pInClause = pWhereRowid ? sqlite3PExpr(pParse, TK_IN, pWhereRowid, 0) : 0; sqlite3PExprAddSelect(pParse, pInClause, pSelect); return pInClause; diff --git a/src/expr.c b/src/expr.c index 1ad166777b..881123e314 100644 --- a/src/expr.c +++ b/src/expr.c @@ -427,7 +427,7 @@ Expr *sqlite3ExprForVectorField( ** with the same pLeft pointer to the pVector, but only one of them ** will own the pVector. */ - pRet = sqlite3PExpr(pParse, TK_SELECT_COLUMN, 0, 0, 0); + pRet = sqlite3PExpr(pParse, TK_SELECT_COLUMN, 0, 0); if( pRet ){ pRet->iColumn = iField; pRet->pLeft = pVector; @@ -819,15 +819,19 @@ Expr *sqlite3PExpr( Parse *pParse, /* Parsing context */ int op, /* Expression opcode */ Expr *pLeft, /* Left operand */ - Expr *pRight, /* Right operand */ - const Token *pToken /* Argument token */ + Expr *pRight /* Right operand */ ){ Expr *p; if( op==TK_AND && pParse->nErr==0 ){ /* Take advantage of short-circuit false optimization for AND */ p = sqlite3ExprAnd(pParse->db, pLeft, pRight); }else{ - p = sqlite3ExprAlloc(pParse->db, op & TKFLG_MASK, pToken, 1); + p = sqlite3DbMallocRawNN(pParse->db, sizeof(Expr)); + if( p ){ + memset(p, 0, sizeof(Expr)); + p->op = op & TKFLG_MASK; + p->iAgg = -1; + } sqlite3ExprAttachSubtrees(pParse->db, p, pLeft, pRight); } if( p ) { diff --git a/src/fkey.c b/src/fkey.c index 883cc6411e..38b961be65 100644 --- a/src/fkey.c +++ b/src/fkey.c @@ -584,7 +584,7 @@ static void fkScanChildren( assert( iCol>=0 ); zCol = pFKey->pFrom->aCol[iCol].zName; pRight = sqlite3Expr(db, TK_ID, zCol); - pEq = sqlite3PExpr(pParse, TK_EQ, pLeft, pRight, 0); + pEq = sqlite3PExpr(pParse, TK_EQ, pLeft, pRight); pWhere = sqlite3ExprAnd(db, pWhere, pEq); } @@ -606,7 +606,7 @@ static void fkScanChildren( if( HasRowid(pTab) ){ pLeft = exprTableRegister(pParse, pTab, regData, -1); pRight = exprTableColumn(db, pTab, pSrc->a[0].iCursor, -1); - pNe = sqlite3PExpr(pParse, TK_NE, pLeft, pRight, 0); + pNe = sqlite3PExpr(pParse, TK_NE, pLeft, pRight); }else{ Expr *pEq, *pAll = 0; Index *pPk = sqlite3PrimaryKeyIndex(pTab); @@ -616,10 +616,10 @@ static void fkScanChildren( assert( iCol>=0 ); pLeft = exprTableRegister(pParse, pTab, regData, iCol); pRight = exprTableColumn(db, pTab, pSrc->a[0].iCursor, iCol); - pEq = sqlite3PExpr(pParse, TK_EQ, pLeft, pRight, 0); + pEq = sqlite3PExpr(pParse, TK_EQ, pLeft, pRight); pAll = sqlite3ExprAnd(db, pAll, pEq); } - pNe = sqlite3PExpr(pParse, TK_NOT, pAll, 0, 0); + pNe = sqlite3PExpr(pParse, TK_NOT, pAll, 0); } pWhere = sqlite3ExprAnd(db, pWhere, pNe); } @@ -1205,10 +1205,9 @@ static Trigger *fkActionTrigger( pEq = sqlite3PExpr(pParse, TK_EQ, sqlite3PExpr(pParse, TK_DOT, sqlite3ExprAlloc(db, TK_ID, &tOld, 0), - sqlite3ExprAlloc(db, TK_ID, &tToCol, 0) - , 0), + sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)), sqlite3ExprAlloc(db, TK_ID, &tFromCol, 0) - , 0); + ); pWhere = sqlite3ExprAnd(db, pWhere, pEq); /* For ON UPDATE, construct the next term of the WHEN clause. @@ -1220,13 +1219,11 @@ static Trigger *fkActionTrigger( pEq = sqlite3PExpr(pParse, TK_IS, sqlite3PExpr(pParse, TK_DOT, sqlite3ExprAlloc(db, TK_ID, &tOld, 0), - sqlite3ExprAlloc(db, TK_ID, &tToCol, 0), - 0), + sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)), sqlite3PExpr(pParse, TK_DOT, sqlite3ExprAlloc(db, TK_ID, &tNew, 0), - sqlite3ExprAlloc(db, TK_ID, &tToCol, 0), - 0), - 0); + sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)) + ); pWhen = sqlite3ExprAnd(db, pWhen, pEq); } @@ -1235,8 +1232,7 @@ static Trigger *fkActionTrigger( if( action==OE_Cascade ){ pNew = sqlite3PExpr(pParse, TK_DOT, sqlite3ExprAlloc(db, TK_ID, &tNew, 0), - sqlite3ExprAlloc(db, TK_ID, &tToCol, 0) - , 0); + sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)); }else if( action==OE_SetDflt ){ Expr *pDflt = pFKey->pFrom->aCol[iFromCol].pDflt; if( pDflt ){ @@ -1292,7 +1288,7 @@ static Trigger *fkActionTrigger( pStep->pExprList = sqlite3ExprListDup(db, pList, EXPRDUP_REDUCE); pStep->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE); if( pWhen ){ - pWhen = sqlite3PExpr(pParse, TK_NOT, pWhen, 0, 0); + pWhen = sqlite3PExpr(pParse, TK_NOT, pWhen, 0); pTrigger->pWhen = sqlite3ExprDup(db, pWhen, EXPRDUP_REDUCE); } } diff --git a/src/parse.y b/src/parse.y index 1eff123d18..c9dbc767cd 100644 --- a/src/parse.y +++ b/src/parse.y @@ -268,7 +268,7 @@ ccons ::= DEFAULT LP expr(X) RP. {sqlite3AddDefaultValue(pParse,&X);} ccons ::= DEFAULT PLUS term(X). {sqlite3AddDefaultValue(pParse,&X);} ccons ::= DEFAULT MINUS(A) term(X). { ExprSpan v; - v.pExpr = sqlite3PExpr(pParse, TK_UMINUS, X.pExpr, 0, 0); + v.pExpr = sqlite3PExpr(pParse, TK_UMINUS, X.pExpr, 0); v.zStart = A.z; v.zEnd = X.zEnd; sqlite3AddDefaultValue(pParse,&v); @@ -543,9 +543,9 @@ selcollist(A) ::= sclp(A) STAR. { A = sqlite3ExprListAppend(pParse, A, p); } selcollist(A) ::= sclp(A) nm(X) DOT STAR. { - Expr *pRight = sqlite3PExpr(pParse, TK_ASTERISK, 0, 0, 0); - Expr *pLeft = sqlite3PExpr(pParse, TK_ID, 0, 0, &X); - Expr *pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight, 0); + Expr *pRight = sqlite3PExpr(pParse, TK_ASTERISK, 0, 0); + Expr *pLeft = sqlite3ExprAlloc(pParse->db, TK_ID, &X, 1); + Expr *pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight); A = sqlite3ExprListAppend(pParse,A, pDot); } @@ -870,15 +870,15 @@ expr(A) ::= nm(X) DOT nm(Y). { Expr *temp1 = sqlite3ExprAlloc(pParse->db, TK_ID, &X, 1); Expr *temp2 = sqlite3ExprAlloc(pParse->db, TK_ID, &Y, 1); spanSet(&A,&X,&Y); /*A-overwrites-X*/ - A.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp2, 0); + A.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp2); } expr(A) ::= nm(X) DOT nm(Y) DOT nm(Z). { Expr *temp1 = sqlite3ExprAlloc(pParse->db, TK_ID, &X, 1); Expr *temp2 = sqlite3ExprAlloc(pParse->db, TK_ID, &Y, 1); Expr *temp3 = sqlite3ExprAlloc(pParse->db, TK_ID, &Z, 1); - Expr *temp4 = sqlite3PExpr(pParse, TK_DOT, temp2, temp3, 0); + Expr *temp4 = sqlite3PExpr(pParse, TK_DOT, temp2, temp3); spanSet(&A,&X,&Z); /*A-overwrites-X*/ - A.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp4, 0); + A.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp4); } term(A) ::= FLOAT|BLOB(X). {spanExpr(&A,pParse,@X,X);/*A-overwrites-X*/} term(A) ::= STRING(X). {spanExpr(&A,pParse,@X,X);/*A-overwrites-X*/} @@ -904,7 +904,7 @@ expr(A) ::= VARIABLE(X). { sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &t); A.pExpr = 0; }else{ - A.pExpr = sqlite3PExpr(pParse, TK_REGISTER, 0, 0, 0); + A.pExpr = sqlite3PExpr(pParse, TK_REGISTER, 0, 0); if( A.pExpr ) sqlite3GetInt32(&t.z[1], &A.pExpr->iTable); } } @@ -916,7 +916,8 @@ expr(A) ::= expr(A) COLLATE ids(C). { %ifndef SQLITE_OMIT_CAST expr(A) ::= CAST(X) LP expr(E) AS typetoken(T) RP(Y). { spanSet(&A,&X,&Y); /*A-overwrites-X*/ - A.pExpr = sqlite3PExpr(pParse, TK_CAST, E.pExpr, 0, &T); + A.pExpr = sqlite3ExprAlloc(pParse->db, TK_CAST, &T, 1); + sqlite3ExprAttachSubtrees(pParse->db, A.pExpr, E.pExpr, 0); } %endif SQLITE_OMIT_CAST expr(A) ::= id(X) LP distinct(D) exprlist(Y) RP(E). { @@ -948,7 +949,7 @@ term(A) ::= CTIME_KW(OP). { ExprSpan *pLeft, /* The left operand, and output */ ExprSpan *pRight /* The right operand */ ){ - pLeft->pExpr = sqlite3PExpr(pParse, op, pLeft->pExpr, pRight->pExpr, 0); + pLeft->pExpr = sqlite3PExpr(pParse, op, pLeft->pExpr, pRight->pExpr); pLeft->zEnd = pRight->zEnd; } @@ -957,14 +958,14 @@ term(A) ::= CTIME_KW(OP). { */ static void exprNot(Parse *pParse, int doNot, ExprSpan *pSpan){ if( doNot ){ - pSpan->pExpr = sqlite3PExpr(pParse, TK_NOT, pSpan->pExpr, 0, 0); + pSpan->pExpr = sqlite3PExpr(pParse, TK_NOT, pSpan->pExpr, 0); } } } expr(A) ::= LP(L) nexprlist(X) COMMA expr(Y) RP(R). { ExprList *pList = sqlite3ExprListAppend(pParse, X, Y.pExpr); - A.pExpr = sqlite3PExpr(pParse, TK_VECTOR, 0, 0, 0); + A.pExpr = sqlite3PExpr(pParse, TK_VECTOR, 0, 0); if( A.pExpr ){ A.pExpr->x.pList = pList; spanSet(&A, &L, &R); @@ -1021,7 +1022,7 @@ expr(A) ::= expr(A) likeop(OP) expr(Y) ESCAPE expr(E). [LIKE_KW] { ExprSpan *pOperand, /* The operand, and output */ Token *pPostOp /* The operand token for setting the span */ ){ - pOperand->pExpr = sqlite3PExpr(pParse, op, pOperand->pExpr, 0, 0); + pOperand->pExpr = sqlite3PExpr(pParse, op, pOperand->pExpr, 0); pOperand->zEnd = &pPostOp->z[pPostOp->n]; } } @@ -1068,7 +1069,7 @@ expr(A) ::= expr(A) IS NOT expr(Y). { Token *pPreOp /* The operand token for setting the span */ ){ pOut->zStart = pPreOp->z; - pOut->pExpr = sqlite3PExpr(pParse, op, pOperand->pExpr, 0, 0); + pOut->pExpr = sqlite3PExpr(pParse, op, pOperand->pExpr, 0); pOut->zEnd = pOperand->zEnd; } } @@ -1090,7 +1091,7 @@ between_op(A) ::= NOT BETWEEN. {A = 1;} expr(A) ::= expr(A) between_op(N) expr(X) AND expr(Y). [BETWEEN] { ExprList *pList = sqlite3ExprListAppend(pParse,0, X.pExpr); pList = sqlite3ExprListAppend(pParse,pList, Y.pExpr); - A.pExpr = sqlite3PExpr(pParse, TK_BETWEEN, A.pExpr, 0, 0); + A.pExpr = sqlite3PExpr(pParse, TK_BETWEEN, A.pExpr, 0); if( A.pExpr ){ A.pExpr->x.pList = pList; }else{ @@ -1114,7 +1115,7 @@ expr(A) ::= expr(A) between_op(N) expr(X) AND expr(Y). [BETWEEN] { ** regardless of the value of expr1. */ sqlite3ExprDelete(pParse->db, A.pExpr); - A.pExpr = sqlite3PExpr(pParse, TK_INTEGER, 0, 0, &sqlite3IntTokens[N]); + A.pExpr = sqlite3ExprAlloc(pParse->db, TK_INTEGER,&sqlite3IntTokens[N],1); }else if( Y->nExpr==1 ){ /* Expressions of the form: ** @@ -1141,9 +1142,9 @@ expr(A) ::= expr(A) between_op(N) expr(X) AND expr(Y). [BETWEEN] { pRHS->flags &= ~EP_Collate; pRHS->flags |= EP_Generic; } - A.pExpr = sqlite3PExpr(pParse, N ? TK_NE : TK_EQ, A.pExpr, pRHS, 0); + A.pExpr = sqlite3PExpr(pParse, N ? TK_NE : TK_EQ, A.pExpr, pRHS); }else{ - A.pExpr = sqlite3PExpr(pParse, TK_IN, A.pExpr, 0, 0); + A.pExpr = sqlite3PExpr(pParse, TK_IN, A.pExpr, 0); if( A.pExpr ){ A.pExpr->x.pList = Y; sqlite3ExprSetHeightAndFlags(pParse, A.pExpr); @@ -1156,11 +1157,11 @@ expr(A) ::= expr(A) between_op(N) expr(X) AND expr(Y). [BETWEEN] { } expr(A) ::= LP(B) select(X) RP(E). { spanSet(&A,&B,&E); /*A-overwrites-B*/ - A.pExpr = sqlite3PExpr(pParse, TK_SELECT, 0, 0, 0); + A.pExpr = sqlite3PExpr(pParse, TK_SELECT, 0, 0); sqlite3PExprAddSelect(pParse, A.pExpr, X); } expr(A) ::= expr(A) in_op(N) LP select(Y) RP(E). [IN] { - A.pExpr = sqlite3PExpr(pParse, TK_IN, A.pExpr, 0, 0); + A.pExpr = sqlite3PExpr(pParse, TK_IN, A.pExpr, 0); sqlite3PExprAddSelect(pParse, A.pExpr, Y); exprNot(pParse, N, &A); A.zEnd = &E.z[E.n]; @@ -1169,7 +1170,7 @@ expr(A) ::= expr(A) between_op(N) expr(X) AND expr(Y). [BETWEEN] { SrcList *pSrc = sqlite3SrcListAppend(pParse->db, 0,&Y,&Z); Select *pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0); if( E ) sqlite3SrcListFuncArgs(pParse, pSelect ? pSrc : 0, E); - A.pExpr = sqlite3PExpr(pParse, TK_IN, A.pExpr, 0, 0); + A.pExpr = sqlite3PExpr(pParse, TK_IN, A.pExpr, 0); sqlite3PExprAddSelect(pParse, A.pExpr, pSelect); exprNot(pParse, N, &A); A.zEnd = Z.z ? &Z.z[Z.n] : &Y.z[Y.n]; @@ -1177,7 +1178,7 @@ expr(A) ::= expr(A) between_op(N) expr(X) AND expr(Y). [BETWEEN] { expr(A) ::= EXISTS(B) LP select(Y) RP(E). { Expr *p; spanSet(&A,&B,&E); /*A-overwrites-B*/ - p = A.pExpr = sqlite3PExpr(pParse, TK_EXISTS, 0, 0, 0); + p = A.pExpr = sqlite3PExpr(pParse, TK_EXISTS, 0, 0); sqlite3PExprAddSelect(pParse, p, Y); } %endif SQLITE_OMIT_SUBQUERY @@ -1185,7 +1186,7 @@ expr(A) ::= expr(A) between_op(N) expr(X) AND expr(Y). [BETWEEN] { /* CASE expressions */ expr(A) ::= CASE(C) case_operand(X) case_exprlist(Y) case_else(Z) END(E). { spanSet(&A,&C,&E); /*A-overwrites-C*/ - A.pExpr = sqlite3PExpr(pParse, TK_CASE, X, 0, 0); + A.pExpr = sqlite3PExpr(pParse, TK_CASE, X, 0); if( A.pExpr ){ A.pExpr->x.pList = Z ? sqlite3ExprListAppend(pParse,Y,Z) : Y; sqlite3ExprSetHeightAndFlags(pParse, A.pExpr); @@ -1445,14 +1446,14 @@ trigger_cmd(A) ::= select(X). // The special RAISE expression that may occur in trigger programs expr(A) ::= RAISE(X) LP IGNORE RP(Y). { spanSet(&A,&X,&Y); /*A-overwrites-X*/ - A.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0, 0); + A.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0); if( A.pExpr ){ A.pExpr->affinity = OE_Ignore; } } expr(A) ::= RAISE(X) LP raisetype(T) COMMA nm(Z) RP(Y). { spanSet(&A,&X,&Y); /*A-overwrites-X*/ - A.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0, &Z); + A.pExpr = sqlite3ExprAlloc(pParse->db, TK_RAISE, &Z, 1); if( A.pExpr ) { A.pExpr->affinity = (char)T; } diff --git a/src/select.c b/src/select.c index e0b8fccc53..26a4619dfd 100644 --- a/src/select.c +++ b/src/select.c @@ -334,7 +334,7 @@ static void addWhereTerm( pE1 = sqlite3CreateColumnExpr(db, pSrc, iLeft, iColLeft); pE2 = sqlite3CreateColumnExpr(db, pSrc, iRight, iColRight); - pEq = sqlite3PExpr(pParse, TK_EQ, pE1, pE2, 0); + pEq = sqlite3PExpr(pParse, TK_EQ, pE1, pE2); if( pEq && isOuterJoin ){ ExprSetProperty(pEq, EP_FromJoin); assert( !ExprHasProperty(pEq, EP_TokenOnly|EP_Reduced) ); @@ -4475,10 +4475,10 @@ static int selectExpander(Walker *pWalker, Select *p){ if( longNames || pTabList->nSrc>1 ){ Expr *pLeft; pLeft = sqlite3Expr(db, TK_ID, zTabName); - pExpr = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight, 0); + pExpr = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight); if( zSchemaName ){ pLeft = sqlite3Expr(db, TK_ID, zSchemaName); - pExpr = sqlite3PExpr(pParse, TK_DOT, pLeft, pExpr, 0); + pExpr = sqlite3PExpr(pParse, TK_DOT, pLeft, pExpr); } if( longNames ){ zColname = sqlite3MPrintf(db, "%s.%s", zTabName, zName); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 5e256942ff..d6d95b9f19 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3552,7 +3552,7 @@ int sqlite3NoTempsInRange(Parse*,int,int); Expr *sqlite3ExprAlloc(sqlite3*,int,const Token*,int); Expr *sqlite3Expr(sqlite3*,int,const char*); void sqlite3ExprAttachSubtrees(sqlite3*,Expr*,Expr*,Expr*); -Expr *sqlite3PExpr(Parse*, int, Expr*, Expr*, const Token*); +Expr *sqlite3PExpr(Parse*, int, Expr*, Expr*); void sqlite3PExprAddSelect(Parse*, Expr*, Select*); Expr *sqlite3ExprAnd(sqlite3*,Expr*, Expr*); Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*); diff --git a/src/wherecode.c b/src/wherecode.c index 9a4961d293..00c50b1ec7 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -1175,7 +1175,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( /* Generate code that will continue to the next row if ** the IN constraint is not satisfied */ - pCompare = sqlite3PExpr(pParse, TK_EQ, 0, 0, 0); + pCompare = sqlite3PExpr(pParse, TK_EQ, 0, 0); assert( pCompare!=0 || db->mallocFailed ); if( pCompare ){ pCompare->pLeft = pTerm->pExpr->pLeft; @@ -1774,7 +1774,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( pAndExpr = sqlite3ExprAnd(db, pAndExpr, pExpr); } if( pAndExpr ){ - pAndExpr = sqlite3PExpr(pParse, TK_AND|TKFLG_DONTFOLD, 0, pAndExpr, 0); + pAndExpr = sqlite3PExpr(pParse, TK_AND|TKFLG_DONTFOLD, 0, pAndExpr); } } diff --git a/src/whereexpr.c b/src/whereexpr.c index 13d5611457..4bb161044e 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -734,7 +734,7 @@ static void exprAnalyzeOrTerm( } assert( pLeft!=0 ); pDup = sqlite3ExprDup(db, pLeft, 0); - pNew = sqlite3PExpr(pParse, TK_IN, pDup, 0, 0); + pNew = sqlite3PExpr(pParse, TK_IN, pDup, 0); if( pNew ){ int idxNew; transferJoinMarkings(pNew, pExpr); @@ -1032,7 +1032,7 @@ static void exprAnalyze( int idxNew; pNewExpr = sqlite3PExpr(pParse, ops[i], sqlite3ExprDup(db, pExpr->pLeft, 0), - sqlite3ExprDup(db, pList->a[i].pExpr, 0), 0); + sqlite3ExprDup(db, pList->a[i].pExpr, 0)); transferJoinMarkings(pNewExpr, pExpr); idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC); testcase( idxNew==0 ); @@ -1117,7 +1117,7 @@ static void exprAnalyze( pNewExpr1 = sqlite3ExprDup(db, pLeft, 0); pNewExpr1 = sqlite3PExpr(pParse, TK_GE, sqlite3ExprAddCollateString(pParse,pNewExpr1,zCollSeqName), - pStr1, 0); + pStr1); transferJoinMarkings(pNewExpr1, pExpr); idxNew1 = whereClauseInsert(pWC, pNewExpr1, wtFlags); testcase( idxNew1==0 ); @@ -1125,7 +1125,7 @@ static void exprAnalyze( pNewExpr2 = sqlite3ExprDup(db, pLeft, 0); pNewExpr2 = sqlite3PExpr(pParse, TK_LT, sqlite3ExprAddCollateString(pParse,pNewExpr2,zCollSeqName), - pStr2, 0); + pStr2); transferJoinMarkings(pNewExpr2, pExpr); idxNew2 = whereClauseInsert(pWC, pNewExpr2, wtFlags); testcase( idxNew2==0 ); @@ -1158,7 +1158,7 @@ static void exprAnalyze( if( (prereqExpr & prereqColumn)==0 ){ Expr *pNewExpr; pNewExpr = sqlite3PExpr(pParse, TK_MATCH, - 0, sqlite3ExprDup(db, pRight, 0), 0); + 0, sqlite3ExprDup(db, pRight, 0)); idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC); testcase( idxNew==0 ); pNewTerm = &pWC->a[idxNew]; @@ -1197,7 +1197,7 @@ static void exprAnalyze( Expr *pLeft = sqlite3ExprForVectorField(pParse, pExpr->pLeft, i); Expr *pRight = sqlite3ExprForVectorField(pParse, pExpr->pRight, i); - pNew = sqlite3PExpr(pParse, pExpr->op, pLeft, pRight, 0); + pNew = sqlite3PExpr(pParse, pExpr->op, pLeft, pRight); transferJoinMarkings(pNew, pExpr); idxNew = whereClauseInsert(pWC, pNew, TERM_DYNAMIC); exprAnalyze(pSrc, pWC, idxNew); @@ -1249,7 +1249,7 @@ static void exprAnalyze( pNewExpr = sqlite3PExpr(pParse, TK_GT, sqlite3ExprDup(db, pLeft, 0), - sqlite3ExprAlloc(db, TK_NULL, 0, 0), 0); + sqlite3ExprAlloc(db, TK_NULL, 0, 0)); idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC|TERM_VNULL); @@ -1435,7 +1435,7 @@ void sqlite3WhereTabFuncArgs( pColRef->iColumn = k++; pColRef->pTab = pTab; pTerm = sqlite3PExpr(pParse, TK_EQ, pColRef, - sqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0), 0); + sqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0)); whereClauseInsert(pWC, pTerm, TERM_DYNAMIC); } } From 9314bd5fe2916f7034dbc197d9fcac06dc9c41d0 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 7 Dec 2016 13:49:11 +0000 Subject: [PATCH 1048/1484] Always honor the sqlite3.dbOptFlags bitmask, regardless of compile-time options. Continuing fix for ticket [da78413751863]. FossilOrigin-Name: afab166313e0b8ad530df99887437a362398ed02 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/sqliteInt.h | 5 ----- 3 files changed, 7 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 55337320a3..4c14cd36fb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Performance\simprovement\sand\ssize\sreduction\sin\sthe\sExpr\snode\sallocator\nfunction\ssqlite3PExpr(). -D 2016-12-06T22:47:23.006 +C Always\shonor\sthe\ssqlite3.dbOptFlags\sbitmask,\sregardless\sof\scompile-time\noptions.\s\sContinuing\sfix\sfor\sticket\s[da78413751863]. +D 2016-12-07T13:49:11.158 F Makefile.in 7639c6a09da11a9c7c6f2630fc981ee588d1072d F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -393,7 +393,7 @@ F src/shell.c a3fc2c719ed6d381895cbdb66a4a9b6a791cb02e F src/sqlite.h.in e8e2d108d82647f0a812fdb74accf91c1ec08ddc F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae -F src/sqliteInt.h bdfd92824dd50ff037373aaada276f90b168952d +F src/sqliteInt.h 181158754e1bd7837747d2459e54cb0e556f9c82 F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 @@ -1536,7 +1536,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 0820f8b3dedfc846d187844847dfa8617539fc9a -R 66c67520d75b6cc9d6a9f98310fc2b1f +P 2a81763e68cdf9b8c46389b1e1a87bc2084b53e7 +R ad65390018631e2625a804a98b6533cb U drh -Z aa79b15c8c6da20e9ca7087094bfadd8 +Z 680af68799bfcad1d8fa388c257b6fc8 diff --git a/manifest.uuid b/manifest.uuid index 40f364d25f..d540a8d3c1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2a81763e68cdf9b8c46389b1e1a87bc2084b53e7 \ No newline at end of file +afab166313e0b8ad530df99887437a362398ed02 \ No newline at end of file diff --git a/src/sqliteInt.h b/src/sqliteInt.h index d6d95b9f19..38b002a09f 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1461,13 +1461,8 @@ struct sqlite3 { /* ** Macros for testing whether or not optimizations are enabled or disabled. */ -#ifndef SQLITE_OMIT_BUILTIN_TEST #define OptimizationDisabled(db, mask) (((db)->dbOptFlags&(mask))!=0) #define OptimizationEnabled(db, mask) (((db)->dbOptFlags&(mask))==0) -#else -#define OptimizationDisabled(db, mask) 0 -#define OptimizationEnabled(db, mask) 1 -#endif /* ** Return true if it OK to factor constant expressions into the initialization From 44c5604cedbee85135eff5957af4e3843f25afa9 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 7 Dec 2016 15:38:37 +0000 Subject: [PATCH 1049/1484] Prevent the flattening or where-term push-down optimizations from obscuring misuses of SQL row values that can lead to crashes or assert() failures. FossilOrigin-Name: 433d16ff3adfede3be53d5b0e0512f37e225591b --- manifest | 20 +++++++------- manifest.uuid | 2 +- src/expr.c | 28 ++++++++++++++++---- src/select.c | 66 +++++++++++++++++++++++++--------------------- src/sqliteInt.h | 1 + test/rowvalue.test | 25 ++++++++++++++++++ 6 files changed, 96 insertions(+), 46 deletions(-) diff --git a/manifest b/manifest index 4c14cd36fb..509a2a1b7d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Always\shonor\sthe\ssqlite3.dbOptFlags\sbitmask,\sregardless\sof\scompile-time\noptions.\s\sContinuing\sfix\sfor\sticket\s[da78413751863]. -D 2016-12-07T13:49:11.158 +C Prevent\sthe\sflattening\sor\swhere-term\spush-down\soptimizations\sfrom\sobscuring\nmisuses\sof\sSQL\srow\svalues\sthat\scan\slead\sto\scrashes\sor\sassert()\sfailures. +D 2016-12-07T15:38:37.162 F Makefile.in 7639c6a09da11a9c7c6f2630fc981ee588d1072d F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -341,7 +341,7 @@ F src/ctime.c a2a52d6e353f459d8ab0f07321f60fafa47d5421 F src/date.c 57f23f5835c0b8b2be0e71f3b0a38e5960d053ec F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c a6881ec5a7d1adc6157dfe1596ead3522db04740 -F src/expr.c b4db982acf30aad864a047bf7676fa85761fc55e +F src/expr.c 0393a016d990c8c2023b737f5a143cdf308d429f F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 4017dc6d8bf894c4818ffbaf392e53c7c68dd761 F src/func.c 43916c1d8e6da5d107d91d2b212577d4f69a876a @@ -388,12 +388,12 @@ F src/printf.c f94da4935d1dd25420ac50c6745db1deb35e07c1 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c bb070cf5f23611c44ab7e4788803684e385fc3fb F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac -F src/select.c ee68944dfee9d548032bba3fdd5a6355011212c0 +F src/select.c 0e4920c4ab7b5751473a1b457ff7d57f4b54e288 F src/shell.c a3fc2c719ed6d381895cbdb66a4a9b6a791cb02e F src/sqlite.h.in e8e2d108d82647f0a812fdb74accf91c1ec08ddc F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae -F src/sqliteInt.h 181158754e1bd7837747d2459e54cb0e556f9c82 +F src/sqliteInt.h 33b14fb2b549001f2255565068c20fc8d883321e F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 @@ -1032,7 +1032,7 @@ F test/rollbackfault.test 0e646aeab8840c399cfbfa43daab46fd609cf04a F test/rowallock.test 3f88ec6819489d0b2341c7a7528ae17c053ab7cc F test/rowhash.test 0bc1d31415e4575d10cacf31e1a66b5cc0f8be81 F test/rowid.test 5b7509f384f4f6fae1af3c8c104c8ca299fea18d -F test/rowvalue.test f4dc97fe52d4e206e25b3395588b9497a8eed3ff +F test/rowvalue.test 3f468a9e370a3ee8b267e58049679eb0df2b9d01 F test/rowvalue2.test 060d238b7e5639a7c5630cb5e63e311b44efef2b F test/rowvalue3.test 3068f508753af69884b12125995f023da0dbb256 F test/rowvalue4.test 4b556d7de161a0dd8cff095c336e913986398bea @@ -1536,7 +1536,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 2a81763e68cdf9b8c46389b1e1a87bc2084b53e7 -R ad65390018631e2625a804a98b6533cb -U drh -Z 680af68799bfcad1d8fa388c257b6fc8 +P afab166313e0b8ad530df99887437a362398ed02 +R 805d4861d87a142d84fe0d34bae5d292 +U dan +Z fc6459b5407c4f6a11de33c5ce52ff74 diff --git a/manifest.uuid b/manifest.uuid index d540a8d3c1..bf18ea7c5c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -afab166313e0b8ad530df99887437a362398ed02 \ No newline at end of file +433d16ff3adfede3be53d5b0e0512f37e225591b \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 881123e314..a5833a6579 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2355,6 +2355,28 @@ void sqlite3SubselectError(Parse *pParse, int nActual, int nExpect){ } #endif +/* +** Expression pExpr is a vector that has been used in a context where +** it is not permitted. If pExpr is a sub-select vector, this routine +** loads the Parse object with a message of the form: +** +** "sub-select returns N columns - expected 1" +** +** Or, if it is a regular scalar vector: +** +** "row value misused" +*/ +void sqlite3VectorErrorMsg(Parse *pParse, Expr *pExpr){ +#ifndef SQLITE_OMIT_SUBQUERY + if( pExpr->flags & EP_xIsSelect ){ + sqlite3SubselectError(pParse, pExpr->x.pSelect->pEList->nExpr, 1); + }else +#endif + { + sqlite3ErrorMsg(pParse, "row value misused"); + } +} + /* ** Generate code for scalar subqueries used as a subquery expression, EXISTS, ** or IN operators. Examples: @@ -2637,11 +2659,7 @@ int sqlite3ExprCheckIN(Parse *pParse, Expr *pIn){ return 1; } }else if( nVector!=1 ){ - if( (pIn->pLeft->flags & EP_xIsSelect) ){ - sqlite3SubselectError(pParse, nVector, 1); - }else{ - sqlite3ErrorMsg(pParse, "row value misused"); - } + sqlite3VectorErrorMsg(pParse, pIn->pLeft); return 1; } return 0; diff --git a/src/select.c b/src/select.c index 26a4619dfd..71977c5f78 100644 --- a/src/select.c +++ b/src/select.c @@ -3133,8 +3133,8 @@ static int multiSelectOrderBy( #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) /* Forward Declarations */ -static void substExprList(sqlite3*, ExprList*, int, ExprList*); -static void substSelect(sqlite3*, Select *, int, ExprList*, int); +static void substExprList(Parse*, ExprList*, int, ExprList*); +static void substSelect(Parse*, Select *, int, ExprList*, int); /* ** Scan through the expression pExpr. Replace every reference to @@ -3150,40 +3150,46 @@ static void substSelect(sqlite3*, Select *, int, ExprList*, int); ** of the subquery rather the result set of the subquery. */ static Expr *substExpr( - sqlite3 *db, /* Report malloc errors to this connection */ + Parse *pParse, /* Report errors here */ Expr *pExpr, /* Expr in which substitution occurs */ int iTable, /* Table to be substituted */ ExprList *pEList /* Substitute expressions */ ){ + sqlite3 *db = pParse->db; if( pExpr==0 ) return 0; if( pExpr->op==TK_COLUMN && pExpr->iTable==iTable ){ if( pExpr->iColumn<0 ){ pExpr->op = TK_NULL; }else{ Expr *pNew; + Expr *pCopy = pEList->a[pExpr->iColumn].pExpr; assert( pEList!=0 && pExpr->iColumnnExpr ); assert( pExpr->pLeft==0 && pExpr->pRight==0 ); - pNew = sqlite3ExprDup(db, pEList->a[pExpr->iColumn].pExpr, 0); - if( pNew && (pExpr->flags & EP_FromJoin) ){ - pNew->iRightJoinTable = pExpr->iRightJoinTable; - pNew->flags |= EP_FromJoin; + if( sqlite3ExprIsVector(pCopy) ){ + sqlite3VectorErrorMsg(pParse, pCopy); + }else{ + pNew = sqlite3ExprDup(db, pCopy, 0); + if( pNew && (pExpr->flags & EP_FromJoin) ){ + pNew->iRightJoinTable = pExpr->iRightJoinTable; + pNew->flags |= EP_FromJoin; + } + sqlite3ExprDelete(db, pExpr); + pExpr = pNew; } - sqlite3ExprDelete(db, pExpr); - pExpr = pNew; } }else{ - pExpr->pLeft = substExpr(db, pExpr->pLeft, iTable, pEList); - pExpr->pRight = substExpr(db, pExpr->pRight, iTable, pEList); + pExpr->pLeft = substExpr(pParse, pExpr->pLeft, iTable, pEList); + pExpr->pRight = substExpr(pParse, pExpr->pRight, iTable, pEList); if( ExprHasProperty(pExpr, EP_xIsSelect) ){ - substSelect(db, pExpr->x.pSelect, iTable, pEList, 1); + substSelect(pParse, pExpr->x.pSelect, iTable, pEList, 1); }else{ - substExprList(db, pExpr->x.pList, iTable, pEList); + substExprList(pParse, pExpr->x.pList, iTable, pEList); } } return pExpr; } static void substExprList( - sqlite3 *db, /* Report malloc errors here */ + Parse *pParse, /* Report errors here */ ExprList *pList, /* List to scan and in which to make substitutes */ int iTable, /* Table to be substituted */ ExprList *pEList /* Substitute values */ @@ -3191,11 +3197,11 @@ static void substExprList( int i; if( pList==0 ) return; for(i=0; inExpr; i++){ - pList->a[i].pExpr = substExpr(db, pList->a[i].pExpr, iTable, pEList); + pList->a[i].pExpr = substExpr(pParse, pList->a[i].pExpr, iTable, pEList); } } static void substSelect( - sqlite3 *db, /* Report malloc errors here */ + Parse *pParse, /* Report errors here */ Select *p, /* SELECT statement in which to make substitutions */ int iTable, /* Table to be replaced */ ExprList *pEList, /* Substitute values */ @@ -3206,17 +3212,17 @@ static void substSelect( int i; if( !p ) return; do{ - substExprList(db, p->pEList, iTable, pEList); - substExprList(db, p->pGroupBy, iTable, pEList); - substExprList(db, p->pOrderBy, iTable, pEList); - p->pHaving = substExpr(db, p->pHaving, iTable, pEList); - p->pWhere = substExpr(db, p->pWhere, iTable, pEList); + substExprList(pParse, p->pEList, iTable, pEList); + substExprList(pParse, p->pGroupBy, iTable, pEList); + substExprList(pParse, p->pOrderBy, iTable, pEList); + p->pHaving = substExpr(pParse, p->pHaving, iTable, pEList); + p->pWhere = substExpr(pParse, p->pWhere, iTable, pEList); pSrc = p->pSrc; assert( pSrc!=0 ); for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){ - substSelect(db, pItem->pSelect, iTable, pEList, 1); + substSelect(pParse, pItem->pSelect, iTable, pEList, 1); if( pItem->fg.isTabFunc ){ - substExprList(db, pItem->u1.pFuncArg, iTable, pEList); + substExprList(pParse, pItem->u1.pFuncArg, iTable, pEList); } } }while( doPrior && (p = p->pPrior)!=0 ); @@ -3741,7 +3747,7 @@ static int flattenSubquery( }else{ pParent->pWhere = sqlite3ExprAnd(db, pWhere, pParent->pWhere); } - substSelect(db, pParent, iParent, pSub->pEList, 0); + substSelect(pParse, pParent, iParent, pSub->pEList, 0); /* The flattened query is distinct if either the inner or the ** outer query is distinct. @@ -3815,7 +3821,7 @@ static int flattenSubquery( ** terms are duplicated into the subquery. */ static int pushDownWhereTerms( - sqlite3 *db, /* The database connection (for malloc()) */ + Parse *pParse, /* Parse context (for malloc() and error reporting) */ Select *pSubq, /* The subquery whose WHERE clause is to be augmented */ Expr *pWhere, /* The WHERE clause of the outer query */ int iCursor /* Cursor number of the subquery */ @@ -3836,16 +3842,16 @@ static int pushDownWhereTerms( return 0; /* restriction (3) */ } while( pWhere->op==TK_AND ){ - nChng += pushDownWhereTerms(db, pSubq, pWhere->pRight, iCursor); + nChng += pushDownWhereTerms(pParse, pSubq, pWhere->pRight, iCursor); pWhere = pWhere->pLeft; } if( ExprHasProperty(pWhere,EP_FromJoin) ) return 0; /* restriction 5 */ if( sqlite3ExprIsTableConstant(pWhere, iCursor) ){ nChng++; while( pSubq ){ - pNew = sqlite3ExprDup(db, pWhere, 0); - pNew = substExpr(db, pNew, iCursor, pSubq->pEList); - pSubq->pWhere = sqlite3ExprAnd(db, pSubq->pWhere, pNew); + pNew = sqlite3ExprDup(pParse->db, pWhere, 0); + pNew = substExpr(pParse, pNew, iCursor, pSubq->pEList); + pSubq->pWhere = sqlite3ExprAnd(pParse->db, pSubq->pWhere, pNew); pSubq = pSubq->pPrior; } } @@ -5002,7 +5008,7 @@ int sqlite3Select( ** inside the subquery. This can help the subquery to run more efficiently. */ if( (pItem->fg.jointype & JT_OUTER)==0 - && pushDownWhereTerms(db, pSub, p->pWhere, pItem->iCursor) + && pushDownWhereTerms(pParse, pSub, p->pWhere, pItem->iCursor) ){ #if SELECTTRACE_ENABLED if( sqlite3SelectTrace & 0x100 ){ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 38b002a09f..4d0af98005 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -4286,5 +4286,6 @@ int sqlite3ExprVectorSize(Expr *pExpr); int sqlite3ExprIsVector(Expr *pExpr); Expr *sqlite3VectorFieldSubexpr(Expr*, int); Expr *sqlite3ExprForVectorField(Parse*,Expr*,int); +void sqlite3VectorErrorMsg(Parse*, Expr*); #endif /* SQLITEINT_H */ diff --git a/test/rowvalue.test b/test/rowvalue.test index 0df2e734c6..48fa8bc4d7 100644 --- a/test/rowvalue.test +++ b/test/rowvalue.test @@ -291,6 +291,31 @@ do_execsql_test 14.6 { SELECT 1 FROM t12 WHERE (1,x) BETWEEN (1,1) AND (3,3) } {1 1} +#------------------------------------------------------------------------- +# Test that errors are not concealed by the SELECT flattening or +# WHERE-clause push-down optimizations. +do_execsql_test 14.1 { + CREATE TABLE x1(a PRIMARY KEY, b); + CREATE TABLE x2(a INTEGER PRIMARY KEY, b); +} + +foreach {tn n sql} { + 1 0 "SELECT * FROM (SELECT (1, 1) AS c FROM x1) WHERE c=1" + 2 2 "SELECT * FROM (SELECT 1 AS x, (SELECT 8,9) AS y) WHERE y<1" + 3 3 "SELECT * FROM (SELECT 1 AS x, (SELECT 8,9,10) AS y) WHERE y<1" + 4 0 "SELECT * FROM (SELECT (a, b) AS c FROM x1), x2 WHERE c=a" + 5 0 "SELECT * FROM (SELECT a AS c, (1, 2, 3) FROM x1), x2 WHERE c=a" + 6 0 "SELECT * FROM (SELECT 1 AS c, (1, 2, 3) FROM x1) WHERE c=1" +} { + if {$n==0} { + set err "row value misused" + } else { + set err "sub-select returns $n columns - expected 1" + } + do_catchsql_test 14.2.$tn $sql [list 1 $err] +} + + finish_test From d12602a9c54fd9b150a26848d831a7056a5a6221 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 7 Dec 2016 15:49:02 +0000 Subject: [PATCH 1050/1484] Rename the SQLITE_OMIT_BUILTIN_TEST compile-time option to SQLITE_UNTESTABLE. FossilOrigin-Name: f360818737e73ee4f944685a547abc8f14f47819 --- manifest | 38 +++++++++++++++++++------------------- manifest.uuid | 2 +- src/bitvec.c | 4 ++-- src/ctime.c | 4 ++-- src/date.c | 4 ++-- src/fault.c | 4 ++-- src/global.c | 2 +- src/main.c | 4 ++-- src/random.c | 4 ++-- src/shell.c | 8 ++++---- src/sqliteInt.h | 14 +++++++------- src/test_config.c | 2 +- src/test_func.c | 2 +- src/util.c | 2 +- src/vdbe.c | 2 +- 15 files changed, 48 insertions(+), 48 deletions(-) diff --git a/manifest b/manifest index 509a2a1b7d..996956852c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Prevent\sthe\sflattening\sor\swhere-term\spush-down\soptimizations\sfrom\sobscuring\nmisuses\sof\sSQL\srow\svalues\sthat\scan\slead\sto\scrashes\sor\sassert()\sfailures. -D 2016-12-07T15:38:37.162 +C Rename\sthe\sSQLITE_OMIT_BUILTIN_TEST\scompile-time\soption\sto\sSQLITE_UNTESTABLE. +D 2016-12-07T15:49:02.031 F Makefile.in 7639c6a09da11a9c7c6f2630fc981ee588d1072d F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -329,7 +329,7 @@ F src/analyze.c 8b62b2cf4da85451534ac0af82cafc418d837f68 F src/attach.c f6725410c184a80d8141b294fdf98a854c8a52b5 F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792 F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b -F src/bitvec.c 3ee4c8b2c94ed3a7377256e18199e6ff5cf33f63 +F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 F src/btree.c 9b30dbe2f6306c50dc5af8296e67034400de37cb F src/btree.h 2349a588abcd7e0c04f984e15c5c777b61637583 @@ -337,15 +337,15 @@ F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 F src/build.c 178f16698cbcb43402c343a9413fe22c99ffee21 F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e -F src/ctime.c a2a52d6e353f459d8ab0f07321f60fafa47d5421 -F src/date.c 57f23f5835c0b8b2be0e71f3b0a38e5960d053ec +F src/ctime.c bcec3165b4921312a86bc239793246767a66754d +F src/date.c b48378aeac68fa20c811404955a9b62108df47d8 F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c a6881ec5a7d1adc6157dfe1596ead3522db04740 F src/expr.c 0393a016d990c8c2023b737f5a143cdf308d429f -F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb +F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 4017dc6d8bf894c4818ffbaf392e53c7c68dd761 F src/func.c 43916c1d8e6da5d107d91d2b212577d4f69a876a -F src/global.c 9da4ca5d74b90715f0ec4957f3d17a4749009f34 +F src/global.c 235021a21ee2cb52b304589f8f9e85a36bbe24fa F src/hash.c 63d0ee752a3b92d4695b2b1f5259c4621b2cfebd F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4 F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da @@ -353,7 +353,7 @@ F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 F src/insert.c 2f8d2c1fa472409625cecacddd39a3b1c6811a26 F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e F src/loadext.c 5d6642d141c07d366e43d359e94ec9de47add41d -F src/main.c 5669ae83c6bd47f090aee26a6b548a882d69e9e1 +F src/main.c c0daeb1f716de3e93c573aeed6b164faeddee772 F src/malloc.c 5ee7c2d3dcb1b0a902c9c6d0115deef54736bdfa F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b @@ -385,15 +385,15 @@ F src/pragma.c d932ba278654617cdd281f88a790a3185fca7c44 F src/pragma.h 64c78a648751b9f4f297276c4eb7507b14b4628c F src/prepare.c b1140c3d0cf59bc85ace00ce363153041b424b7a F src/printf.c f94da4935d1dd25420ac50c6745db1deb35e07c1 -F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 +F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c bb070cf5f23611c44ab7e4788803684e385fc3fb F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c 0e4920c4ab7b5751473a1b457ff7d57f4b54e288 -F src/shell.c a3fc2c719ed6d381895cbdb66a4a9b6a791cb02e +F src/shell.c 9597efa50a4a27bc6440ad99cbcd7fff6957f514 F src/sqlite.h.in e8e2d108d82647f0a812fdb74accf91c1ec08ddc F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae -F src/sqliteInt.h 33b14fb2b549001f2255565068c20fc8d883321e +F src/sqliteInt.h 9d0834b980e2d156109d73c307b803d29d2686e8 F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 @@ -413,12 +413,12 @@ F src/test_backup.c bf5da90c9926df0a4b941f2d92825a01bbe090a0 F src/test_bestindex.c d23f80d334c59662af69191854c76b8d3d0c8c96 F src/test_blob.c 6a4c7920d1d9c6cc0f7aa50c89c4f80016aeda83 F src/test_btree.c 8b2dc8b8848cf3a4db93f11578f075e82252a274 -F src/test_config.c 371853b4691b482ec0bcdf77ec9e3f96dca75b04 +F src/test_config.c 83179ea845479b5be9a651d014649e3f2722a1fe F src/test_delete.c 8499d4d323f2ec8e28301deb3d6ddd8eef8b8139 F src/test_demovfs.c a0c3bdd45ed044115c2c9f7779e56eafff18741e F src/test_devsym.c 4e58dec2602d8e139ca08659f62a62450587cb58 F src/test_fs.c e16cbe68d3b107e00a907c20a9a02629870eb69b -F src/test_func.c a2b4993da973b0ea60dd5d51a7066238ede8c329 +F src/test_func.c a4fdab3363b436c1b12660e9362ce3f3782b7b5e F src/test_hexio.c 1d4469ca61ab202a1fcec6543f584d2407205e8d F src/test_init.c 4413c211a94b62157ca4c145b3f27c497f03c664 F src/test_intarray.c 988fc61cb0ff539f4172c0d95f15287c92516f64 @@ -453,9 +453,9 @@ F src/treeview.c 4e44ade3bfe59d82005039f72e09333ce2b4162c F src/trigger.c 3419bb9862983d84d70735fb4c94b21b934cd0c5 F src/update.c 1b8321100cac004f0721ab67b16909dd006e663c F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c -F src/util.c 3e2da6101888d073e79ecc6af5e0a2f70fa1e498 +F src/util.c e68e8ced7328f22d2cf7b4c898c394a0de34cdf1 F src/vacuum.c 33c174b28886b2faf26e503b5a49a1c01a9b1c16 -F src/vdbe.c 336a3e5696683a585e56bbbc4f05ce33957d28dd +F src/vdbe.c 3986f226945b14b98eb26bd589de3705223c95ad F src/vdbe.h c044be7050ac6bf596eecc6ab159f5dbc020a3b7 F src/vdbeInt.h 9b498d3cb52dc2efb53571fb8ae8e14cf298ce84 F src/vdbeapi.c ea4e2dc2213cc6bd7bee375a29a9b51c31b93ae0 @@ -1536,7 +1536,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P afab166313e0b8ad530df99887437a362398ed02 -R 805d4861d87a142d84fe0d34bae5d292 -U dan -Z fc6459b5407c4f6a11de33c5ce52ff74 +P 433d16ff3adfede3be53d5b0e0512f37e225591b +R e6d88f40ad98e257f66f33654ad3712f +U drh +Z 7632e2864475c2accdb8129364863b0d diff --git a/manifest.uuid b/manifest.uuid index bf18ea7c5c..47c6369693 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -433d16ff3adfede3be53d5b0e0512f37e225591b \ No newline at end of file +f360818737e73ee4f944685a547abc8f14f47819 \ No newline at end of file diff --git a/src/bitvec.c b/src/bitvec.c index 9d13ba9185..bd4a09429b 100644 --- a/src/bitvec.c +++ b/src/bitvec.c @@ -293,7 +293,7 @@ u32 sqlite3BitvecSize(Bitvec *p){ return p->iSize; } -#ifndef SQLITE_OMIT_BUILTIN_TEST +#ifndef SQLITE_UNTESTABLE /* ** Let V[] be an array of unsigned characters sufficient to hold ** up to N bits. Let I be an integer between 0 and N. 0<=I=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){ static const struct { const char *zCtrlName; /* Name of a test-control option */ @@ -4971,7 +4971,7 @@ static int do_meta_command(char *zLine, ShellState *p){ } #endif }else -#endif /* !defined(SQLITE_OMIT_BUILTIN_TEST) */ +#endif /* !defined(SQLITE_UNTESTABLE) */ #if SQLITE_USER_AUTHENTICATION if( c=='u' && strncmp(azArg[0], "user", n)==0 ){ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 4d0af98005..46d5a169b5 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3232,7 +3232,7 @@ struct Sqlite3Config { void (*xVdbeBranch)(void*,int iSrcLine,u8 eThis,u8 eMx); /* Callback */ void *pVdbeBranchArg; /* 1st argument */ #endif -#ifndef SQLITE_OMIT_BUILTIN_TEST +#ifndef SQLITE_UNTESTABLE int (*xTestCallback)(int); /* Invoked by sqlite3FaultSim() */ #endif int bLocaltimeFault; /* True to fail localtime() calls */ @@ -3436,7 +3436,7 @@ void sqlite3ScratchFree(void*); void *sqlite3PageMalloc(int); void sqlite3PageFree(void*); void sqlite3MemSetDefault(void); -#ifndef SQLITE_OMIT_BUILTIN_TEST +#ifndef SQLITE_UNTESTABLE void sqlite3BenignMallocHooks(void (*)(void), void (*)(void)); #endif int sqlite3HeapNearlyFull(void); @@ -3591,7 +3591,7 @@ int sqlite3ParseUri(const char*,const char*,unsigned int*, sqlite3_vfs**,char**,char **); Btree *sqlite3DbNameToBtree(sqlite3*,const char*); -#ifdef SQLITE_OMIT_BUILTIN_TEST +#ifdef SQLITE_UNTESTABLE # define sqlite3FaultSim(X) SQLITE_OK #else int sqlite3FaultSim(int); @@ -3604,7 +3604,7 @@ int sqlite3BitvecSet(Bitvec*, u32); void sqlite3BitvecClear(Bitvec*, u32, void*); void sqlite3BitvecDestroy(Bitvec*); u32 sqlite3BitvecSize(Bitvec*); -#ifndef SQLITE_OMIT_BUILTIN_TEST +#ifndef SQLITE_UNTESTABLE int sqlite3BitvecBuiltinTest(int,int*); #endif @@ -3724,7 +3724,7 @@ void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*); int sqlite3ExprCoveredByIndex(Expr*, int iCur, Index *pIdx); int sqlite3FunctionUsesThisSrc(Expr*, SrcList*); Vdbe *sqlite3GetVdbe(Parse*); -#ifndef SQLITE_OMIT_BUILTIN_TEST +#ifndef SQLITE_UNTESTABLE void sqlite3PrngSaveState(void); void sqlite3PrngRestoreState(void); #endif @@ -4152,10 +4152,10 @@ const char *sqlite3JournalModename(int); /* ** The interface to the code in fault.c used for identifying "benign" -** malloc failures. This is only present if SQLITE_OMIT_BUILTIN_TEST +** malloc failures. This is only present if SQLITE_UNTESTABLE ** is not defined. */ -#ifndef SQLITE_OMIT_BUILTIN_TEST +#ifndef SQLITE_UNTESTABLE void sqlite3BeginBenignMalloc(void); void sqlite3EndBenignMalloc(void); #else diff --git a/src/test_config.c b/src/test_config.c index d8e6b3c0fa..f409b1ca6f 100644 --- a/src/test_config.c +++ b/src/test_config.c @@ -268,7 +268,7 @@ static void set_options(Tcl_Interp *interp){ Tcl_SetVar2(interp, "sqlite_options", "between_opt", "1", TCL_GLOBAL_ONLY); #endif -#ifdef SQLITE_OMIT_BUILTIN_TEST +#ifdef SQLITE_UNTESTABLE Tcl_SetVar2(interp, "sqlite_options", "builtin_test", "0", TCL_GLOBAL_ONLY); #else Tcl_SetVar2(interp, "sqlite_options", "builtin_test", "1", TCL_GLOBAL_ONLY); diff --git a/src/test_func.c b/src/test_func.c index 26f0d369ef..c7860fe887 100644 --- a/src/test_func.c +++ b/src/test_func.c @@ -155,7 +155,7 @@ static void test_destructor_count( ** arguments. It returns the text value returned by the sqlite3_errmsg16() ** API function. */ -#ifndef SQLITE_OMIT_BUILTIN_TEST +#ifndef SQLITE_UNTESTABLE void sqlite3BeginBenignMalloc(void); void sqlite3EndBenignMalloc(void); #else diff --git a/src/util.c b/src/util.c index e18b847578..a614f14619 100644 --- a/src/util.c +++ b/src/util.c @@ -42,7 +42,7 @@ void sqlite3Coverage(int x){ ** Return whatever integer value the test callback returns, or return ** SQLITE_OK if no test callback is installed. */ -#ifndef SQLITE_OMIT_BUILTIN_TEST +#ifndef SQLITE_UNTESTABLE int sqlite3FaultSim(int iTest){ int (*xCallback)(int) = sqlite3GlobalConfig.xTestCallback; return xCallback ? xCallback(iTest) : SQLITE_OK; diff --git a/src/vdbe.c b/src/vdbe.c index 3b2550810f..86088905f4 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -111,7 +111,7 @@ int sqlite3_found_count = 0; ** Test a register to see if it exceeds the current maximum blob size. ** If it does, record the new maximum blob size. */ -#if defined(SQLITE_TEST) && !defined(SQLITE_OMIT_BUILTIN_TEST) +#if defined(SQLITE_TEST) && !defined(SQLITE_UNTESTABLE) # define UPDATE_MAX_BLOBSIZE(P) updateMaxBlobsize(P) #else # define UPDATE_MAX_BLOBSIZE(P) From 4ed8c83cfd08fec21b672bcc2fd6e81323975c49 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 7 Dec 2016 17:06:12 +0000 Subject: [PATCH 1051/1484] Put the SQLITE_UNTESTABLE compile-time option in the correct order for PRAGMA compile_options. FossilOrigin-Name: 24574a15a336ffcb961334f84b56e9ab98490a79 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/ctime.c | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 996956852c..443be1b2bd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Rename\sthe\sSQLITE_OMIT_BUILTIN_TEST\scompile-time\soption\sto\sSQLITE_UNTESTABLE. -D 2016-12-07T15:49:02.031 +C Put\sthe\sSQLITE_UNTESTABLE\scompile-time\soption\sin\sthe\scorrect\sorder\sfor\nPRAGMA\scompile_options. +D 2016-12-07T17:06:12.360 F Makefile.in 7639c6a09da11a9c7c6f2630fc981ee588d1072d F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -337,7 +337,7 @@ F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 F src/build.c 178f16698cbcb43402c343a9413fe22c99ffee21 F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e -F src/ctime.c bcec3165b4921312a86bc239793246767a66754d +F src/ctime.c 9f2296a4e5d26ebf0e0d95a0af4628f1ea694e7a F src/date.c b48378aeac68fa20c811404955a9b62108df47d8 F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c a6881ec5a7d1adc6157dfe1596ead3522db04740 @@ -1536,7 +1536,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 433d16ff3adfede3be53d5b0e0512f37e225591b -R e6d88f40ad98e257f66f33654ad3712f +P f360818737e73ee4f944685a547abc8f14f47819 +R f5ba64c964c5dccab19f910ff0a2ac41 U drh -Z 7632e2864475c2accdb8129364863b0d +Z 1f3e5852b0694b4e7c0a8b4adaebbb2a diff --git a/manifest.uuid b/manifest.uuid index 47c6369693..01db6f30d3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f360818737e73ee4f944685a547abc8f14f47819 \ No newline at end of file +24574a15a336ffcb961334f84b56e9ab98490a79 \ No newline at end of file diff --git a/src/ctime.c b/src/ctime.c index cb701342ca..969bbc73d2 100644 --- a/src/ctime.c +++ b/src/ctime.c @@ -233,9 +233,6 @@ static const char * const azCompileOpt[] = { #if SQLITE_OMIT_BTREECOUNT "OMIT_BTREECOUNT", #endif -#if SQLITE_UNTESTABLE - "UNTESTABLE" -#endif #if SQLITE_OMIT_CAST "OMIT_CAST", #endif @@ -398,6 +395,9 @@ static const char * const azCompileOpt[] = { #if defined(SQLITE_THREADSAFE) "THREADSAFE=" CTIMEOPT_VAL(SQLITE_THREADSAFE), #endif +#if SQLITE_UNTESTABLE + "UNTESTABLE" +#endif #if SQLITE_USE_ALLOCA "USE_ALLOCA", #endif From bdaa1ee2ee41dddd318b289450cfc7aafa3bf34c Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 7 Dec 2016 20:09:51 +0000 Subject: [PATCH 1052/1484] Performance optimization for sqlite3VdbeAddOp4(). FossilOrigin-Name: 04716c907bf9fc9b827e18fdc7b4e1069e201536 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbeaux.c | 6 +++++- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 443be1b2bd..f9b12284f9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Put\sthe\sSQLITE_UNTESTABLE\scompile-time\soption\sin\sthe\scorrect\sorder\sfor\nPRAGMA\scompile_options. -D 2016-12-07T17:06:12.360 +C Performance\soptimization\sfor\ssqlite3VdbeAddOp4(). +D 2016-12-07T20:09:51.583 F Makefile.in 7639c6a09da11a9c7c6f2630fc981ee588d1072d F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -459,7 +459,7 @@ F src/vdbe.c 3986f226945b14b98eb26bd589de3705223c95ad F src/vdbe.h c044be7050ac6bf596eecc6ab159f5dbc020a3b7 F src/vdbeInt.h 9b498d3cb52dc2efb53571fb8ae8e14cf298ce84 F src/vdbeapi.c ea4e2dc2213cc6bd7bee375a29a9b51c31b93ae0 -F src/vdbeaux.c 50a8caa4c8ce8b4c26bad807a6cae89fcc3bdb7e +F src/vdbeaux.c 3afb187a9239e49d999a0f077f7c138a2799d074 F src/vdbeblob.c f4f98ea672b242f807c08c92c7faaa79e5091b65 F src/vdbemem.c 1af2f14ab0f7004b364933ddcfc767fb880d4742 F src/vdbesort.c 91fda3909326860382b0ca8aa251e609c6a9d62c @@ -1536,7 +1536,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P f360818737e73ee4f944685a547abc8f14f47819 -R f5ba64c964c5dccab19f910ff0a2ac41 +P 24574a15a336ffcb961334f84b56e9ab98490a79 +R fe9a80abf2b1a7e9a5d7d152eff8a8fe U drh -Z 1f3e5852b0694b4e7c0a8b4adaebbb2a +Z 7f586b627685f0d65f8b0e7af7753ff2 diff --git a/manifest.uuid b/manifest.uuid index 01db6f30d3..4c1a459fe2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -24574a15a336ffcb961334f84b56e9ab98490a79 \ No newline at end of file +04716c907bf9fc9b827e18fdc7b4e1069e201536 \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 308d96917f..04dc9599f5 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -313,7 +313,11 @@ int sqlite3VdbeAddOp4Int( int p4 /* The P4 operand as an integer */ ){ int addr = sqlite3VdbeAddOp3(p, op, p1, p2, p3); - sqlite3VdbeChangeP4(p, addr, SQLITE_INT_TO_PTR(p4), P4_INT32); + if( p->db->mallocFailed==0 ){ + VdbeOp *pOp = &p->aOp[addr]; + pOp->p4type = P4_INT32; + pOp->p4.i = p4; + } return addr; } From 861b1307cb43da57aa26db60cf18cd674e15017f Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 7 Dec 2016 20:22:31 +0000 Subject: [PATCH 1053/1484] The use P4_DYNAMIC in place of the P4_MPRINTF operand type. FossilOrigin-Name: 3954f83798ed78527280c9db6360c62a5134b9ec --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/vdbe.h | 29 ++++++++++++++--------------- src/vdbeaux.c | 4 ---- src/wherecode.c | 2 +- 5 files changed, 24 insertions(+), 29 deletions(-) diff --git a/manifest b/manifest index f9b12284f9..5fd4826eed 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Performance\soptimization\sfor\ssqlite3VdbeAddOp4(). -D 2016-12-07T20:09:51.583 +C The\suse\sP4_DYNAMIC\sin\splace\sof\sthe\sP4_MPRINTF\soperand\stype. +D 2016-12-07T20:22:31.737 F Makefile.in 7639c6a09da11a9c7c6f2630fc981ee588d1072d F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -456,10 +456,10 @@ F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c e68e8ced7328f22d2cf7b4c898c394a0de34cdf1 F src/vacuum.c 33c174b28886b2faf26e503b5a49a1c01a9b1c16 F src/vdbe.c 3986f226945b14b98eb26bd589de3705223c95ad -F src/vdbe.h c044be7050ac6bf596eecc6ab159f5dbc020a3b7 +F src/vdbe.h 1987921713ee2b948a79f0af192024065db095fb F src/vdbeInt.h 9b498d3cb52dc2efb53571fb8ae8e14cf298ce84 F src/vdbeapi.c ea4e2dc2213cc6bd7bee375a29a9b51c31b93ae0 -F src/vdbeaux.c 3afb187a9239e49d999a0f077f7c138a2799d074 +F src/vdbeaux.c 8378658e15a82b20fa49718f9204d1286b4fbc26 F src/vdbeblob.c f4f98ea672b242f807c08c92c7faaa79e5091b65 F src/vdbemem.c 1af2f14ab0f7004b364933ddcfc767fb880d4742 F src/vdbesort.c 91fda3909326860382b0ca8aa251e609c6a9d62c @@ -471,7 +471,7 @@ F src/wal.h 06b2a0b599cc0f53ea97f497cf8c6b758c999f71 F src/walker.c 91a6df7435827e41cff6bb7df50ea00934ee78b0 F src/where.c 6bbf9284f4f15a6fa48663d033870cc0d7f5ee66 F src/whereInt.h 2bcc3d176e6091cb8f50a30b65c006e88a73614d -F src/wherecode.c 9a3b1034191c9ea8ac14a5405564402f8b1114b2 +F src/wherecode.c e04ac8f24c3ac8621df6c3be3ac8c7d4fa893745 F src/whereexpr.c 87ecdf24beba4498e4380b31c4131febb0a6ceaa F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -1536,7 +1536,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 24574a15a336ffcb961334f84b56e9ab98490a79 -R fe9a80abf2b1a7e9a5d7d152eff8a8fe +P 04716c907bf9fc9b827e18fdc7b4e1069e201536 +R 5a971bdba4dcd12ecdc94b0ffc7d235f U drh -Z 7f586b627685f0d65f8b0e7af7753ff2 +Z 9cd8827513cba2f6d012918afdfa6fc2 diff --git a/manifest.uuid b/manifest.uuid index 4c1a459fe2..584cf35915 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -04716c907bf9fc9b827e18fdc7b4e1069e201536 \ No newline at end of file +3954f83798ed78527280c9db6360c62a5134b9ec \ No newline at end of file diff --git a/src/vdbe.h b/src/vdbe.h index ecb2b0e3f4..6567a980f9 100644 --- a/src/vdbe.h +++ b/src/vdbe.h @@ -110,22 +110,21 @@ typedef struct VdbeOpList VdbeOpList; #define P4_NOTUSED 0 /* The P4 parameter is not used */ #define P4_DYNAMIC (-1) /* Pointer to a string obtained from sqliteMalloc() */ #define P4_STATIC (-2) /* Pointer to a static string */ -#define P4_COLLSEQ (-4) /* P4 is a pointer to a CollSeq structure */ -#define P4_FUNCDEF (-5) /* P4 is a pointer to a FuncDef structure */ -#define P4_KEYINFO (-6) /* P4 is a pointer to a KeyInfo structure */ -#define P4_EXPR (-7) /* P4 is a pointer to an Expr tree */ -#define P4_MEM (-8) /* P4 is a pointer to a Mem* structure */ +#define P4_COLLSEQ (-3) /* P4 is a pointer to a CollSeq structure */ +#define P4_FUNCDEF (-4) /* P4 is a pointer to a FuncDef structure */ +#define P4_KEYINFO (-5) /* P4 is a pointer to a KeyInfo structure */ +#define P4_EXPR (-6) /* P4 is a pointer to an Expr tree */ +#define P4_MEM (-7) /* P4 is a pointer to a Mem* structure */ #define P4_TRANSIENT 0 /* P4 is a pointer to a transient string */ -#define P4_VTAB (-10) /* P4 is a pointer to an sqlite3_vtab structure */ -#define P4_MPRINTF (-11) /* P4 is a string obtained from sqlite3_mprintf() */ -#define P4_REAL (-12) /* P4 is a 64-bit floating point value */ -#define P4_INT64 (-13) /* P4 is a 64-bit signed integer */ -#define P4_INT32 (-14) /* P4 is a 32-bit signed integer */ -#define P4_INTARRAY (-15) /* P4 is a vector of 32-bit integers */ -#define P4_SUBPROGRAM (-18) /* P4 is a pointer to a SubProgram structure */ -#define P4_ADVANCE (-19) /* P4 is a pointer to BtreeNext() or BtreePrev() */ -#define P4_TABLE (-20) /* P4 is a pointer to a Table structure */ -#define P4_FUNCCTX (-21) /* P4 is a pointer to an sqlite3_context object */ +#define P4_VTAB (-8) /* P4 is a pointer to an sqlite3_vtab structure */ +#define P4_REAL (-9) /* P4 is a 64-bit floating point value */ +#define P4_INT64 (-10) /* P4 is a 64-bit signed integer */ +#define P4_INT32 (-11) /* P4 is a 32-bit signed integer */ +#define P4_INTARRAY (-12) /* P4 is a vector of 32-bit integers */ +#define P4_SUBPROGRAM (-13) /* P4 is a pointer to a SubProgram structure */ +#define P4_ADVANCE (-14) /* P4 is a pointer to BtreeNext() or BtreePrev() */ +#define P4_TABLE (-15) /* P4 is a pointer to a Table structure */ +#define P4_FUNCCTX (-16) /* P4 is a pointer to an sqlite3_context object */ /* Error message codes for OP_Halt */ #define P5_ConstraintNotNull 1 diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 04dc9599f5..01430c6136 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -828,10 +828,6 @@ static void freeP4(sqlite3 *db, int p4type, void *p4){ break; } #endif - case P4_MPRINTF: { - if( db->pnBytesFreed==0 ) sqlite3_free(p4); - break; - } case P4_FUNCDEF: { freeEphemeralFunction(db, (FuncDef*)p4); break; diff --git a/src/wherecode.c b/src/wherecode.c index 00c50b1ec7..032c56fef3 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -1142,7 +1142,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( sqlite3VdbeAddOp2(v, OP_Integer, nConstraint, iReg+1); sqlite3VdbeAddOp4(v, OP_VFilter, iCur, addrNotFound, iReg, pLoop->u.vtab.idxStr, - pLoop->u.vtab.needFree ? P4_MPRINTF : P4_STATIC); + pLoop->u.vtab.needFree ? P4_DYNAMIC : P4_STATIC); VdbeCoverage(v); pLoop->u.vtab.needFree = 0; pLevel->p1 = iCur; From f14b7fb73b1f3886854f0dceacc7fd3ae04ee8d0 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 7 Dec 2016 21:35:55 +0000 Subject: [PATCH 1054/1484] Add the sqlite3VdbeAppendP4() method for adding P4 content to the most recently coded instruction. FossilOrigin-Name: 28883e8f3e92a8015fb5f6c8ae8580833931543d --- manifest | 22 +++++++++++----------- manifest.uuid | 2 +- src/delete.c | 2 +- src/expr.c | 2 +- src/insert.c | 4 ++-- src/update.c | 4 ++-- src/vdbe.h | 1 + src/vdbeaux.c | 30 ++++++++++++++++++++++++++++-- 8 files changed, 47 insertions(+), 20 deletions(-) diff --git a/manifest b/manifest index 5fd4826eed..e81d777796 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C The\suse\sP4_DYNAMIC\sin\splace\sof\sthe\sP4_MPRINTF\soperand\stype. -D 2016-12-07T20:22:31.737 +C Add\sthe\ssqlite3VdbeAppendP4()\smethod\sfor\sadding\sP4\scontent\sto\sthe\smost\srecently\ncoded\sinstruction. +D 2016-12-07T21:35:55.152 F Makefile.in 7639c6a09da11a9c7c6f2630fc981ee588d1072d F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -340,8 +340,8 @@ F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 9f2296a4e5d26ebf0e0d95a0af4628f1ea694e7a F src/date.c b48378aeac68fa20c811404955a9b62108df47d8 F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d -F src/delete.c a6881ec5a7d1adc6157dfe1596ead3522db04740 -F src/expr.c 0393a016d990c8c2023b737f5a143cdf308d429f +F src/delete.c 42768e673861dffec92664b2036da6be51720e49 +F src/expr.c 84a5e590184ad7ccae22e7ad484d6394dec46f16 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 4017dc6d8bf894c4818ffbaf392e53c7c68dd761 F src/func.c 43916c1d8e6da5d107d91d2b212577d4f69a876a @@ -350,7 +350,7 @@ F src/hash.c 63d0ee752a3b92d4695b2b1f5259c4621b2cfebd F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4 F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 -F src/insert.c 2f8d2c1fa472409625cecacddd39a3b1c6811a26 +F src/insert.c 4f92d50c588009c46aef4016a8ae4c3c70133621 F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e F src/loadext.c 5d6642d141c07d366e43d359e94ec9de47add41d F src/main.c c0daeb1f716de3e93c573aeed6b164faeddee772 @@ -451,15 +451,15 @@ F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c 78c8085bc7af1922aa687f0f4bbd716821330de5 F src/treeview.c 4e44ade3bfe59d82005039f72e09333ce2b4162c F src/trigger.c 3419bb9862983d84d70735fb4c94b21b934cd0c5 -F src/update.c 1b8321100cac004f0721ab67b16909dd006e663c +F src/update.c 1da7c462110bffed442a42884cb0d528c1db46d8 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c e68e8ced7328f22d2cf7b4c898c394a0de34cdf1 F src/vacuum.c 33c174b28886b2faf26e503b5a49a1c01a9b1c16 F src/vdbe.c 3986f226945b14b98eb26bd589de3705223c95ad -F src/vdbe.h 1987921713ee2b948a79f0af192024065db095fb +F src/vdbe.h 0c74f6305fb43b9b282dacaff102272370e327d4 F src/vdbeInt.h 9b498d3cb52dc2efb53571fb8ae8e14cf298ce84 F src/vdbeapi.c ea4e2dc2213cc6bd7bee375a29a9b51c31b93ae0 -F src/vdbeaux.c 8378658e15a82b20fa49718f9204d1286b4fbc26 +F src/vdbeaux.c be0797ca0c392eea2201afbf2eef0b1531e2a8b7 F src/vdbeblob.c f4f98ea672b242f807c08c92c7faaa79e5091b65 F src/vdbemem.c 1af2f14ab0f7004b364933ddcfc767fb880d4742 F src/vdbesort.c 91fda3909326860382b0ca8aa251e609c6a9d62c @@ -1536,7 +1536,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 04716c907bf9fc9b827e18fdc7b4e1069e201536 -R 5a971bdba4dcd12ecdc94b0ffc7d235f +P 3954f83798ed78527280c9db6360c62a5134b9ec +R 868d7a6f4c3cd694f9e2b539e54ae53a U drh -Z 9cd8827513cba2f6d012918afdfa6fc2 +Z c03069fde6cdcd0dcb352e80d6595c45 diff --git a/manifest.uuid b/manifest.uuid index 584cf35915..f752cae81f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3954f83798ed78527280c9db6360c62a5134b9ec \ No newline at end of file +28883e8f3e92a8015fb5f6c8ae8580833931543d \ No newline at end of file diff --git a/src/delete.c b/src/delete.c index aaf1bc7d7f..d3bcbaa00d 100644 --- a/src/delete.c +++ b/src/delete.c @@ -712,7 +712,7 @@ void sqlite3GenerateRowDelete( u8 p5 = 0; sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur,0,iIdxNoSeek); sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, (count?OPFLAG_NCHANGE:0)); - sqlite3VdbeChangeP4(v, -1, (char*)pTab, P4_TABLE); + sqlite3VdbeAppendP4(v, (char*)pTab, P4_TABLE); if( eMode!=ONEPASS_OFF ){ sqlite3VdbeChangeP5(v, OPFLAG_AUXDELETE); } diff --git a/src/expr.c b/src/expr.c index a5833a6579..97f7182e1e 100644 --- a/src/expr.c +++ b/src/expr.c @@ -3432,7 +3432,7 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ if( pExpr->u.zToken[1]!=0 ){ assert( pExpr->u.zToken[0]=='?' || strcmp(pExpr->u.zToken, pParse->azVar[pExpr->iColumn-1])==0 ); - sqlite3VdbeChangeP4(v, -1, pParse->azVar[pExpr->iColumn-1], P4_STATIC); + sqlite3VdbeAppendP4(v, pParse->azVar[pExpr->iColumn-1], P4_STATIC); } return target; } diff --git a/src/insert.c b/src/insert.c index 007e0bb578..0885a40f30 100644 --- a/src/insert.c +++ b/src/insert.c @@ -1448,7 +1448,7 @@ void sqlite3GenerateConstraintChecks( ** OP_Insert replace the existing entry than it is to delete the ** existing entry and then insert a new one. */ sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, OPFLAG_ISNOOP); - sqlite3VdbeChangeP4(v, -1, (char *)pTab, P4_TABLE); + sqlite3VdbeAppendP4(v, pTab, P4_TABLE); } #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ if( pTab->pIndex ){ @@ -1725,7 +1725,7 @@ void sqlite3CompleteInsertion( } sqlite3VdbeAddOp3(v, OP_Insert, iDataCur, regRec, regNewData); if( !pParse->nested ){ - sqlite3VdbeChangeP4(v, -1, (char *)pTab, P4_TABLE); + sqlite3VdbeAppendP4(v, pTab, P4_TABLE); } sqlite3VdbeChangeP5(v, pik_flags); } diff --git a/src/update.c b/src/update.c index c3b3681808..5f89e31dac 100644 --- a/src/update.c +++ b/src/update.c @@ -69,7 +69,7 @@ void sqlite3ColumnDefault(Vdbe *v, Table *pTab, int i, int iReg){ sqlite3ValueFromExpr(sqlite3VdbeDb(v), pCol->pDflt, enc, pCol->affinity, &pValue); if( pValue ){ - sqlite3VdbeChangeP4(v, -1, (const char *)pValue, P4_MEM); + sqlite3VdbeAppendP4(v, pValue, P4_MEM); } #ifndef SQLITE_OMIT_FLOATING_POINT if( pTab->aCol[i].affinity==SQLITE_AFF_REAL ){ @@ -610,7 +610,7 @@ void sqlite3Update( regNewRowid ); if( !pParse->nested ){ - sqlite3VdbeChangeP4(v, -1, (char*)pTab, P4_TABLE); + sqlite3VdbeAppendP4(v, pTab, P4_TABLE); } #else if( hasFK || chngKey || pPk!=0 ){ diff --git a/src/vdbe.h b/src/vdbe.h index 6567a980f9..b8bcfdec5f 100644 --- a/src/vdbe.h +++ b/src/vdbe.h @@ -197,6 +197,7 @@ void sqlite3VdbeJumpHere(Vdbe*, int addr); int sqlite3VdbeChangeToNoop(Vdbe*, int addr); int sqlite3VdbeDeletePriorOpcode(Vdbe*, u8 op); void sqlite3VdbeChangeP4(Vdbe*, int addr, const char *zP4, int N); +void sqlite3VdbeAppendP4(Vdbe*, void *pP4, int p4type); void sqlite3VdbeSetP4KeyInfo(Parse*, Index*); void sqlite3VdbeUsesBtree(Vdbe*, int); VdbeOp *sqlite3VdbeGetOp(Vdbe*, int); diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 01430c6136..2fc973c48a 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -972,16 +972,42 @@ void sqlite3VdbeChangeP4(Vdbe *p, int addr, const char *zP4, int n){ } } +/* +** Change the P4 operand of the most recently coded instruction +** to the value defined by the arguments. This is a high-speed +** version of sqlite3VdbeChangeP4(). +** +** The P4 operand must not have been previously defined. And the new +** P4 must not be P4_INT32. Use sqlite3VdbeChangeP4() in either of +** those cases. +*/ +void sqlite3VdbeAppendP4(Vdbe *p, void *pP4, int n){ + VdbeOp *pOp; + assert( n!=P4_INT32 && n!=P4_VTAB ); + assert( n<=0 ); + if( p->db->mallocFailed ){ + freeP4(p->db, n, pP4); + }else{ + assert( pP4!=0 ); + assert( p->nOp>0 ); + pOp = &p->aOp[p->nOp-1]; + assert( pOp->p4type==P4_NOTUSED ); + pOp->p4type = n; + pOp->p4.p = pP4; + } +} + /* ** Set the P4 on the most recently added opcode to the KeyInfo for the ** index given. */ void sqlite3VdbeSetP4KeyInfo(Parse *pParse, Index *pIdx){ Vdbe *v = pParse->pVdbe; + KeyInfo *pKeyInfo; assert( v!=0 ); assert( pIdx!=0 ); - sqlite3VdbeChangeP4(v, -1, (char*)sqlite3KeyInfoOfIndex(pParse, pIdx), - P4_KEYINFO); + pKeyInfo = sqlite3KeyInfoOfIndex(pParse, pIdx); + if( pKeyInfo ) sqlite3VdbeAppendP4(v, pKeyInfo, P4_KEYINFO); } #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS From 2700acaacdedf5450cbcf8ba4c2a9f7d153fe71b Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 8 Dec 2016 01:38:24 +0000 Subject: [PATCH 1055/1484] More changes to take advantage of the sqlite3VdbeAppendP4() method. FossilOrigin-Name: 83bc5e40af9b20afeed008bf3e2669b7ac9e2dc8 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/insert.c | 5 +++-- src/select.c | 8 ++++---- 4 files changed, 15 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index e81d777796..aad62e3fe5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\ssqlite3VdbeAppendP4()\smethod\sfor\sadding\sP4\scontent\sto\sthe\smost\srecently\ncoded\sinstruction. -D 2016-12-07T21:35:55.152 +C More\schanges\sto\stake\sadvantage\sof\sthe\ssqlite3VdbeAppendP4()\smethod. +D 2016-12-08T01:38:24.218 F Makefile.in 7639c6a09da11a9c7c6f2630fc981ee588d1072d F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -350,7 +350,7 @@ F src/hash.c 63d0ee752a3b92d4695b2b1f5259c4621b2cfebd F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4 F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 -F src/insert.c 4f92d50c588009c46aef4016a8ae4c3c70133621 +F src/insert.c 91ba5d0143e66479081536ebbaff1850ec9f57d9 F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e F src/loadext.c 5d6642d141c07d366e43d359e94ec9de47add41d F src/main.c c0daeb1f716de3e93c573aeed6b164faeddee772 @@ -388,7 +388,7 @@ F src/printf.c f94da4935d1dd25420ac50c6745db1deb35e07c1 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c bb070cf5f23611c44ab7e4788803684e385fc3fb F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac -F src/select.c 0e4920c4ab7b5751473a1b457ff7d57f4b54e288 +F src/select.c b4bd43e1233c87e8a7cf66150421997b0396417e F src/shell.c 9597efa50a4a27bc6440ad99cbcd7fff6957f514 F src/sqlite.h.in e8e2d108d82647f0a812fdb74accf91c1ec08ddc F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1536,7 +1536,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 3954f83798ed78527280c9db6360c62a5134b9ec -R 868d7a6f4c3cd694f9e2b539e54ae53a +P 28883e8f3e92a8015fb5f6c8ae8580833931543d +R 1e20aaec5c4813580d21f8e842d1cbfd U drh -Z c03069fde6cdcd0dcb352e80d6595c45 +Z d1f3c66819deb29754aa3e44d8d64780 diff --git a/manifest.uuid b/manifest.uuid index f752cae81f..e18fdf10e9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -28883e8f3e92a8015fb5f6c8ae8580833931543d \ No newline at end of file +83bc5e40af9b20afeed008bf3e2669b7ac9e2dc8 \ No newline at end of file diff --git a/src/insert.c b/src/insert.c index 0885a40f30..27e05d4de6 100644 --- a/src/insert.c +++ b/src/insert.c @@ -1305,8 +1305,9 @@ void sqlite3GenerateConstraintChecks( case OE_Fail: { char *zMsg = sqlite3MPrintf(db, "%s.%s", pTab->zName, pTab->aCol[i].zName); - sqlite3VdbeAddOp4(v, OP_HaltIfNull, SQLITE_CONSTRAINT_NOTNULL, onError, - regNewData+1+i, zMsg, P4_DYNAMIC); + sqlite3VdbeAddOp3(v, OP_HaltIfNull, SQLITE_CONSTRAINT_NOTNULL, onError, + regNewData+1+i); + sqlite3VdbeAppendP4(v, zMsg, P4_DYNAMIC); sqlite3VdbeChangeP5(v, P5_ConstraintNotNull); VdbeCoverage(v); break; diff --git a/src/select.c b/src/select.c index 71977c5f78..e63ef837e9 100644 --- a/src/select.c +++ b/src/select.c @@ -4721,8 +4721,8 @@ static void finalizeAggFunctions(Parse *pParse, AggInfo *pAggInfo){ for(i=0, pF=pAggInfo->aFunc; inFunc; i++, pF++){ ExprList *pList = pF->pExpr->x.pList; assert( !ExprHasProperty(pF->pExpr, EP_xIsSelect) ); - sqlite3VdbeAddOp4(v, OP_AggFinal, pF->iMem, pList ? pList->nExpr : 0, 0, - (void*)pF->pFunc, P4_FUNCDEF); + sqlite3VdbeAddOp2(v, OP_AggFinal, pF->iMem, pList ? pList->nExpr : 0); + sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF); } } @@ -4773,8 +4773,8 @@ static void updateAccumulator(Parse *pParse, AggInfo *pAggInfo){ if( regHit==0 && pAggInfo->nAccumulator ) regHit = ++pParse->nMem; sqlite3VdbeAddOp4(v, OP_CollSeq, regHit, 0, 0, (char *)pColl, P4_COLLSEQ); } - sqlite3VdbeAddOp4(v, OP_AggStep0, 0, regAgg, pF->iMem, - (void*)pF->pFunc, P4_FUNCDEF); + sqlite3VdbeAddOp3(v, OP_AggStep0, 0, regAgg, pF->iMem); + sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF); sqlite3VdbeChangeP5(v, (u8)nArg); sqlite3ExprCacheAffinityChange(pParse, regAgg, nArg); sqlite3ReleaseTempRange(pParse, regAgg, nArg); From 23ee9dc3699a141fb368525b3525359c0a7532e1 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 8 Dec 2016 18:36:19 +0000 Subject: [PATCH 1056/1484] Update the tool/cg_anno.tcl script to give a summary of cycle counts by canonical source file name. FossilOrigin-Name: 254a83bf30c15d6a355db309ccb97a8744675cc3 --- manifest | 12 +++++----- manifest.uuid | 2 +- tool/cg_anno.tcl | 57 ++++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 62 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index aad62e3fe5..85a244513e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C More\schanges\sto\stake\sadvantage\sof\sthe\ssqlite3VdbeAppendP4()\smethod. -D 2016-12-08T01:38:24.218 +C Update\sthe\stool/cg_anno.tcl\sscript\sto\sgive\sa\ssummary\sof\scycle\scounts\sby\ncanonical\ssource\sfile\sname. +D 2016-12-08T18:36:19.891 F Makefile.in 7639c6a09da11a9c7c6f2630fc981ee588d1072d F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -1453,7 +1453,7 @@ F tool/Replace.cs 02c67258801c2fb5f63231e0ac0f220b4b36ba91 F tool/addopcodes.tcl 10c889c4a65ec6c5604e4a47306fa77ff57ae189 F tool/build-all-msvc.bat 018c1b273458a90c8ba633c6f0c5654cfcb138bf x F tool/build-shell.sh 950f47c6174f1eea171319438b93ba67ff5bf367 -F tool/cg_anno.tcl 692ce4b8693d59e3a3de77ca97f4139ecfa641b0 x +F tool/cg_anno.tcl ac9802cc0f6661beb3bf02dc8792151fdb2ce4a5 x F tool/checkSpacing.c 810e51703529a204fc4e1eb060e9ab663e3c06d2 F tool/dbhash.c a06228aa21ebc4e6ea8daa486601d938499238a5 F tool/extract.c 054069d81b095fbdc189a6f5d4466e40380505e2 @@ -1536,7 +1536,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 28883e8f3e92a8015fb5f6c8ae8580833931543d -R 1e20aaec5c4813580d21f8e842d1cbfd +P 83bc5e40af9b20afeed008bf3e2669b7ac9e2dc8 +R 92154a53c8af746c5059d64a2c3e6ba6 U drh -Z d1f3c66819deb29754aa3e44d8d64780 +Z cc8ee367bbd5864c12ba6ee49a8e2fe0 diff --git a/manifest.uuid b/manifest.uuid index e18fdf10e9..b636c3a582 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -83bc5e40af9b20afeed008bf3e2669b7ac9e2dc8 \ No newline at end of file +254a83bf30c15d6a355db309ccb97a8744675cc3 \ No newline at end of file diff --git a/tool/cg_anno.tcl b/tool/cg_anno.tcl index f806c5a5af..0d2bd4dbd5 100755 --- a/tool/cg_anno.tcl +++ b/tool/cg_anno.tcl @@ -2,23 +2,76 @@ # # A wrapper around cg_annotate that sets appropriate command-line options # and rearranges the output so that annotated files occur in a consistent -# sorted order. Used by the run-speed-test.tcl script. +# sorted order. Used by the speed-check.tcl script. # set in [open "|cg_annotate --show=Ir --auto=yes --context=40 $argv" r] set dest ! set out(!) {} +set linenum 0 +set cntlines 0 ;# true to remember cycle counts on each line +set seenSqlite3 0 ;# true if we have seen the sqlite3.c file while {![eof $in]} { set line [string map {\t { }} [gets $in]] if {[regexp {^-- Auto-annotated source: (.*)} $line all name]} { set dest $name - } elseif {[regexp {^-- line \d+ ------} $line]} { + if {[string match */sqlite3.c $dest]} { + set cntlines 1 + set seenSqlite3 1 + } else { + set cntlines 0 + } + } elseif {[regexp {^-- line (\d+) ------} $line all ln]} { set line [lreplace $line 2 2 {#}] + set linenum [expr {$ln-1}] } elseif {[regexp {^The following files chosen for } $line]} { set dest ! } append out($dest) $line\n + if {$cntlines && [regexp { *([0-9,]+) } $line all x]} { + incr linenum + if {[regexp {^ *([0-9,]+) } $line all x]} { + set x [string map {, {}} $x] + set cycles($linenum) $x + } + } } foreach x [lsort [array names out]] { puts $out($x) } + +# If the sqlite3.c file has been seen, then output a summary of the +# cycle counts for each file that went into making up sqlite3.c +# +if {$seenSqlite3} { + close $in + set in [open sqlite3.c] + set linenum 0 + set fn sqlite3.c + set pattern1 {^/\*+ Begin file ([^ ]+) \*} + set pattern2 {^/\*+ Continuing where we left off in ([^ ]+) \*} + while {![eof $in]} { + set line [gets $in] + incr linenum + if {[regexp $pattern1 $line all newfn]} { + set fn $newfn + } elseif {[regexp $pattern2 $line all newfn]} { + set fn $newfn + } elseif {[info exists cycles($linenum)]} { + incr fcycles($fn) $cycles($linenum) + } + } + close $in + puts {**********************************************************************} + set lx {} + set sum 0 + foreach {fn cnt} [array get fcycles] { + lappend lx [list $cnt $fn] + incr sum $cnt + } + puts [format {%20s %14d %8.3f%%} TOTAL $sum 100] + foreach entry [lsort -index 0 -integer -decreasing $lx] { + foreach {cnt fn} $entry break + puts [format {%20s %14d %8.3f%%} $fn $cnt [expr {$cnt*100.0/$sum}]] + } +} From 5f00b9bea717fb3798fe30dd0e3694df76c50310 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 8 Dec 2016 19:04:36 +0000 Subject: [PATCH 1057/1484] Fix a minor error in the cg_anno.tcl script causing the cycles-per-file counts to be miscomputed. FossilOrigin-Name: b26df26e184ec6da4b5537526c10f42a293d09b5 --- manifest | 12 ++++++------ manifest.uuid | 2 +- tool/cg_anno.tcl | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 85a244513e..767b0b5ba8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\sthe\stool/cg_anno.tcl\sscript\sto\sgive\sa\ssummary\sof\scycle\scounts\sby\ncanonical\ssource\sfile\sname. -D 2016-12-08T18:36:19.891 +C Fix\sa\sminor\serror\sin\sthe\scg_anno.tcl\sscript\scausing\sthe\scycles-per-file\scounts\nto\sbe\smiscomputed. +D 2016-12-08T19:04:36.568 F Makefile.in 7639c6a09da11a9c7c6f2630fc981ee588d1072d F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -1453,7 +1453,7 @@ F tool/Replace.cs 02c67258801c2fb5f63231e0ac0f220b4b36ba91 F tool/addopcodes.tcl 10c889c4a65ec6c5604e4a47306fa77ff57ae189 F tool/build-all-msvc.bat 018c1b273458a90c8ba633c6f0c5654cfcb138bf x F tool/build-shell.sh 950f47c6174f1eea171319438b93ba67ff5bf367 -F tool/cg_anno.tcl ac9802cc0f6661beb3bf02dc8792151fdb2ce4a5 x +F tool/cg_anno.tcl f95b0006c52cf7f0496b506343415b6ee3cdcdd3 x F tool/checkSpacing.c 810e51703529a204fc4e1eb060e9ab663e3c06d2 F tool/dbhash.c a06228aa21ebc4e6ea8daa486601d938499238a5 F tool/extract.c 054069d81b095fbdc189a6f5d4466e40380505e2 @@ -1536,7 +1536,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 83bc5e40af9b20afeed008bf3e2669b7ac9e2dc8 -R 92154a53c8af746c5059d64a2c3e6ba6 +P 254a83bf30c15d6a355db309ccb97a8744675cc3 +R c83132c87ae23a23d263e8ee60d3c2ea U drh -Z cc8ee367bbd5864c12ba6ee49a8e2fe0 +Z c2b446af19201dba66c3a9f1ed9bef6f diff --git a/manifest.uuid b/manifest.uuid index b636c3a582..aa4fd7848a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -254a83bf30c15d6a355db309ccb97a8744675cc3 \ No newline at end of file +b26df26e184ec6da4b5537526c10f42a293d09b5 \ No newline at end of file diff --git a/tool/cg_anno.tcl b/tool/cg_anno.tcl index 0d2bd4dbd5..43d2b74fcd 100755 --- a/tool/cg_anno.tcl +++ b/tool/cg_anno.tcl @@ -28,7 +28,7 @@ while {![eof $in]} { set dest ! } append out($dest) $line\n - if {$cntlines && [regexp { *([0-9,]+) } $line all x]} { + if {$cntlines} { incr linenum if {[regexp {^ *([0-9,]+) } $line all x]} { set x [string map {, {}} $x] From 4c177424a2293e2e3580f1931ecf881368fad713 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 8 Dec 2016 23:52:38 +0000 Subject: [PATCH 1058/1484] Fix the showstat4 utility program so that is displays strings using standard SQL notation (single quotes) rather than C-style notation. FossilOrigin-Name: 92998e4afbe4da1723e7e5155071a0e7242bd6ff --- manifest | 12 ++++++------ manifest.uuid | 2 +- tool/showstat4.c | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 767b0b5ba8..546a10b05d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sminor\serror\sin\sthe\scg_anno.tcl\sscript\scausing\sthe\scycles-per-file\scounts\nto\sbe\smiscomputed. -D 2016-12-08T19:04:36.568 +C Fix\sthe\sshowstat4\sutility\sprogram\sso\sthat\sis\sdisplays\sstrings\susing\nstandard\sSQL\snotation\s(single\squotes)\srather\sthan\sC-style\snotation. +D 2016-12-08T23:52:38.728 F Makefile.in 7639c6a09da11a9c7c6f2630fc981ee588d1072d F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -1492,7 +1492,7 @@ F tool/run-speed-test.sh f95d19fd669b68c4c38b6b475242841d47c66076 F tool/showdb.c c695a5d5c8110640e0d9fadf5e254da90c79c36e F tool/showjournal.c 5bad7ae8784a43d2b270d953060423b8bd480818 F tool/showlocks.c 9920bcc64f58378ff1118caead34147201f48c68 -F tool/showstat4.c bda40d6e395df7edb6e9ea630784d3d762c35b4b +F tool/showstat4.c b14159aa062f661b394ba37b6b7b94bfb8012ab9 F tool/showwal.c ec79959834f7b21f1e0a2aa52bb7c056d2203977 F tool/soak1.tcl 8d407956e1a45b485a8e072470a3e629a27037fe F tool/spaceanal.tcl ab7d9bf68062907282a64b3e12ccbfad47193c5a @@ -1536,7 +1536,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 254a83bf30c15d6a355db309ccb97a8744675cc3 -R c83132c87ae23a23d263e8ee60d3c2ea +P b26df26e184ec6da4b5537526c10f42a293d09b5 +R 20c5d0b862118000112ece07f7baa65b U drh -Z c2b446af19201dba66c3a9f1ed9bef6f +Z fcf8e16d4cd3aef2bba348beb58ea104 diff --git a/manifest.uuid b/manifest.uuid index aa4fd7848a..314984d3d1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b26df26e184ec6da4b5537526c10f42a293d09b5 \ No newline at end of file +92998e4afbe4da1723e7e5155071a0e7242bd6ff \ No newline at end of file diff --git a/tool/showstat4.c b/tool/showstat4.c index c7f9b10fbc..e31150f0c0 100644 --- a/tool/showstat4.c +++ b/tool/showstat4.c @@ -130,11 +130,11 @@ int main(int argc, char **argv){ } printf("'"); }else{ - printf("%s\"", zSep); + printf("%s'", zSep); for(j=0; j Date: Fri, 9 Dec 2016 00:15:17 +0000 Subject: [PATCH 1059/1484] Fix an obscure problem in range estimation with STAT4. FossilOrigin-Name: 1f16c9a76bc48331799f33b30d143c632fe0e7db --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/vdbemem.c | 1 + test/analyzeF.test | 26 ++++++++++++++++++++++++++ 4 files changed, 35 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 546a10b05d..d6c3f0afbb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\sshowstat4\sutility\sprogram\sso\sthat\sis\sdisplays\sstrings\susing\nstandard\sSQL\snotation\s(single\squotes)\srather\sthan\sC-style\snotation. -D 2016-12-08T23:52:38.728 +C Fix\san\sobscure\sproblem\sin\srange\sestimation\swith\sSTAT4. +D 2016-12-09T00:15:17.019 F Makefile.in 7639c6a09da11a9c7c6f2630fc981ee588d1072d F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -461,7 +461,7 @@ F src/vdbeInt.h 9b498d3cb52dc2efb53571fb8ae8e14cf298ce84 F src/vdbeapi.c ea4e2dc2213cc6bd7bee375a29a9b51c31b93ae0 F src/vdbeaux.c be0797ca0c392eea2201afbf2eef0b1531e2a8b7 F src/vdbeblob.c f4f98ea672b242f807c08c92c7faaa79e5091b65 -F src/vdbemem.c 1af2f14ab0f7004b364933ddcfc767fb880d4742 +F src/vdbemem.c d3fd85b7b7ef3eb75de29c6d7e1d10d3ca78b4fd F src/vdbesort.c 91fda3909326860382b0ca8aa251e609c6a9d62c F src/vdbetrace.c 41963d5376f0349842b5fc4aaaaacd7d9cdc0834 F src/vtab.c e02cacb5c7ae742631edeb9ae9f53d399f093fd8 @@ -498,7 +498,7 @@ F test/analyzeB.test a4c1c3048f6d9e090eb76e83eecb18bcf6d31a70 F test/analyzeC.test 555a6cc388b9818b6eda6df816f01ce0a75d3a93 F test/analyzeD.test 42af58de25a6436502e43006e9e59e2d71bcb0cf F test/analyzeE.test 8684e8ac5722fb97c251887ad97e5d496a98af1d -F test/analyzeF.test 5d1fe1024ba2dfea3c18bede8c1ccef8aba1ab34 +F test/analyzeF.test f423125b557f11ad71bb29765ef9c34b6dcf4ab7 F test/analyzer1.test 459fa02c445ddbf0101a3bad47b34290a35f2e49 F test/async.test 1d0e056ba1bb9729283a0f22718d3a25e82c277b F test/async2.test c0a9bd20816d7d6a2ceca7b8c03d3d69c28ffb8b @@ -1536,7 +1536,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b26df26e184ec6da4b5537526c10f42a293d09b5 -R 20c5d0b862118000112ece07f7baa65b +P 92998e4afbe4da1723e7e5155071a0e7242bd6ff +R 146bb5a9bbf2bccc768a9ed3b6a15043 U drh -Z fcf8e16d4cd3aef2bba348beb58ea104 +Z eab3e469ec793ab1e1350c15f3974350 diff --git a/manifest.uuid b/manifest.uuid index 314984d3d1..7d54383ae9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -92998e4afbe4da1723e7e5155071a0e7242bd6ff \ No newline at end of file +1f16c9a76bc48331799f33b30d143c632fe0e7db \ No newline at end of file diff --git a/src/vdbemem.c b/src/vdbemem.c index 2ee80045d1..9a73b62777 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -1333,6 +1333,7 @@ static int valueFromExpr( }else if( op==TK_NULL ){ pVal = valueNew(db, pCtx); if( pVal==0 ) goto no_mem; + sqlite3VdbeMemNumerify(pVal); } #ifndef SQLITE_OMIT_BLOB_LITERAL else if( op==TK_BLOB ){ diff --git a/test/analyzeF.test b/test/analyzeF.test index 3cbc5f47be..76891ddfe3 100644 --- a/test/analyzeF.test +++ b/test/analyzeF.test @@ -120,5 +120,31 @@ do_catchsql_test 4.4 { SELECT * FROM t1 WHERE x = test_zeroblob(1100000) AND y = 4; } {1 {string or blob too big}} +# 2016-12-08: Constraints of the form "x=? AND x IS NOT NULL" were being +# mishandled. The sqlite3Stat4ProbeSetValue() routine was assuming that +# valueNew() was returning a Mem object that was preset to NULL, which is +# not the case. The consequence was the the "x IS NOT NULL" constraint +# was used to drive the index (via the "x>NULL" pseudo-constraint) rather +# than the "x=?" constraint. +# +do_execsql_test 5.1 { + DROP TABLE IF EXISTS t1; + CREATE TABLE t1(a INTEGER PRIMARY KEY, b TEXT, c INT); + WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<10000) + INSERT INTO t1(a, c) SELECT x, x FROM c; + UPDATE t1 SET b=printf('x%02x',a/500) WHERE a>4000; + UPDATE t1 SET b='xyz' where a>=9998; + CREATE INDEX t1b ON t1(b); + ANALYZE; + SELECT count(*), b FROM t1 GROUP BY 2 ORDER BY 2; +} {4000 {} 499 x08 500 x09 500 x0a 500 x0b 500 x0c 500 x0d 500 x0e 500 x0f 500 x10 500 x11 500 x12 498 x13 3 xyz} +do_execsql_test 5.2 { + explain query plan + SELECT * FROM t1 WHERE b='xyz' AND b IS NOT NULL ORDER BY +a; + /* v---- Should be "=", not ">" */ +} {/USING INDEX t1b .b=/} +do_execsql_test 5.3 { + SELECT * FROM t1 WHERE b='xyz' AND b IS NOT NULL ORDER BY +a; +} {9998 xyz 9998 9999 xyz 9999 10000 xyz 10000} finish_test From a2ee589c468b0b8b6cf9682dae652c9068c825f6 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 9 Dec 2016 16:02:00 +0000 Subject: [PATCH 1060/1484] Avoid unnecessary zeroing of fields in the MemPage object that are going to be reinitialized before use anyhow. A smaller and faster binary results. FossilOrigin-Name: 01ada3d1068476f90dcae02cb089001ea4bcc23d --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/btree.c | 8 +++++--- src/btreeInt.h | 32 +++++++++++++------------------- src/pager.c | 9 ++++++--- src/pcache.c | 9 ++++++++- 6 files changed, 42 insertions(+), 36 deletions(-) diff --git a/manifest b/manifest index d6c3f0afbb..660cdf184e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\sobscure\sproblem\sin\srange\sestimation\swith\sSTAT4. -D 2016-12-09T00:15:17.019 +C Avoid\sunnecessary\szeroing\sof\sfields\sin\sthe\sMemPage\sobject\sthat\sare\sgoing\nto\sbe\sreinitialized\sbefore\suse\sanyhow.\s\sA\ssmaller\sand\sfaster\sbinary\sresults. +D 2016-12-09T16:02:00.219 F Makefile.in 7639c6a09da11a9c7c6f2630fc981ee588d1072d F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -331,9 +331,9 @@ F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792 F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 -F src/btree.c 9b30dbe2f6306c50dc5af8296e67034400de37cb +F src/btree.c c73d77875c83407a0048f5e29d1251536e9f009d F src/btree.h 2349a588abcd7e0c04f984e15c5c777b61637583 -F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 +F src/btreeInt.h 10c4b77c2fb399580babbcc7cf652ac10dba796e F src/build.c 178f16698cbcb43402c343a9413fe22c99ffee21 F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e @@ -375,10 +375,10 @@ F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586 F src/os_unix.c 30e2c43e4955db990e5b5a81e901f8aa74cc8820 F src/os_win.c cf90abd4e50d9f56d2c20ce8e005aff55d7bd8e9 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a -F src/pager.c 4e4aea7ced5734753ccbff4cf4bb4d032cf2173e +F src/pager.c 865779c0d33a5804aa6acd547600fca64b511b8a F src/pager.h d1e944291030351f362a0a7da9b5c3e34e603e39 F src/parse.y 29153738a7322054359320eb00b5a4cd44389f20 -F src/pcache.c 5ff2a08f76a9c1b22f43eb063b7068fb085465ac +F src/pcache.c 219fc5238d5c80e2990ab01e1459db3a96866447 F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 F src/pcache1.c e3967219b2a92b9edcb9324a4ba75009090d3953 F src/pragma.c d932ba278654617cdd281f88a790a3185fca7c44 @@ -1536,7 +1536,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 92998e4afbe4da1723e7e5155071a0e7242bd6ff -R 146bb5a9bbf2bccc768a9ed3b6a15043 +P 1f16c9a76bc48331799f33b30d143c632fe0e7db +R 7472834dbbfbcc03bad94800a01d7495 U drh -Z eab3e469ec793ab1e1350c15f3974350 +Z 662ad8d58fb59ba8bcf6c7d7e219ef69 diff --git a/manifest.uuid b/manifest.uuid index 7d54383ae9..f9626ae2c1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1f16c9a76bc48331799f33b30d143c632fe0e7db \ No newline at end of file +01ada3d1068476f90dcae02cb089001ea4bcc23d \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 7a68331c3d..999ce159cc 100644 --- a/src/btree.c +++ b/src/btree.c @@ -2282,7 +2282,7 @@ int sqlite3BtreeOpen( goto btree_open_out; } rc = sqlite3PagerOpen(pVfs, &pBt->pPager, zFilename, - EXTRA_SIZE, flags, vfsFlags, pageReinit); + sizeof(MemPage), flags, vfsFlags, pageReinit); if( rc==SQLITE_OK ){ sqlite3PagerSetMmapLimit(pBt->pPager, db->szMmap); rc = sqlite3PagerReadFileheader(pBt->pPager,sizeof(zDbHeader),zDbHeader); @@ -6259,7 +6259,6 @@ static void dropCell(MemPage *pPage, int idx, int sz, int *pRC){ int hdr; /* Beginning of the header. 0 most pages. 100 page 1 */ if( *pRC ) return; - assert( idx>=0 && idxnCell ); assert( CORRUPT_DB || sz==cellSize(pPage, idx) ); assert( sqlite3PagerIswriteable(pPage->pDbPage) ); @@ -6343,7 +6342,10 @@ static void insertCell( put4byte(pCell, iChild); } j = pPage->nOverflow++; - assert( j<(int)(sizeof(pPage->apOvfl)/sizeof(pPage->apOvfl[0])) ); + /* Comparison against ArraySize-1 since we hold back one extra slot + ** as a contingency. In other words, never need more than 3 overflow + ** slots but 4 are allocated, just to be safe. */ + assert( j < ArraySize(pPage->apOvfl)-1 ); pPage->apOvfl[j] = pCell; pPage->aiOvfl[j] = (u16)i; diff --git a/src/btreeInt.h b/src/btreeInt.h index 6cd090257c..fc2182b634 100644 --- a/src/btreeInt.h +++ b/src/btreeInt.h @@ -259,37 +259,39 @@ typedef struct CellInfo CellInfo; #define PTF_LEAF 0x08 /* -** As each page of the file is loaded into memory, an instance of the following -** structure is appended and initialized to zero. This structure stores -** information about the page that is decoded from the raw file page. +** An instance of this object stores information about each a single database +** page that has been loaded into memory. The information in this object +** is derived from the raw on-disk page content. ** -** The pParent field points back to the parent page. This allows us to -** walk up the BTree from any leaf to the root. Care must be taken to -** unref() the parent page pointer when this page is no longer referenced. -** The pageDestructor() routine handles that chore. +** As each database page is loaded into memory, the pager allocats an +** instance of this object and zeros the first 8 bytes. (This is the +** "extra" information associated with each page of the pager.) ** ** Access to all fields of this structure is controlled by the mutex ** stored in MemPage.pBt->mutex. */ struct MemPage { u8 isInit; /* True if previously initialized. MUST BE FIRST! */ - u8 nOverflow; /* Number of overflow cell bodies in aCell[] */ + u8 bBusy; /* Prevent endless loops on corrupt database files */ u8 intKey; /* True if table b-trees. False for index b-trees */ u8 intKeyLeaf; /* True if the leaf of an intKey table */ + Pgno pgno; /* Page number for this page */ + /* Only the first 8 bytes (above) are zeroed by pager.c when a new page + ** is allocated. All fields that follow must be initialized before use */ u8 leaf; /* True if a leaf page */ u8 hdrOffset; /* 100 for page 1. 0 otherwise */ u8 childPtrSize; /* 0 if leaf==1. 4 if leaf==0 */ u8 max1bytePayload; /* min(maxLocal,127) */ - u8 bBusy; /* Prevent endless loops on corrupt database files */ + u8 nOverflow; /* Number of overflow cell bodies in aCell[] */ u16 maxLocal; /* Copy of BtShared.maxLocal or BtShared.maxLeaf */ u16 minLocal; /* Copy of BtShared.minLocal or BtShared.minLeaf */ u16 cellOffset; /* Index in aData of first cell pointer */ u16 nFree; /* Number of free bytes on the page */ u16 nCell; /* Number of cells on this page, local and ovfl */ u16 maskPage; /* Mask for page offset */ - u16 aiOvfl[5]; /* Insert the i-th overflow cell before the aiOvfl-th + u16 aiOvfl[4]; /* Insert the i-th overflow cell before the aiOvfl-th ** non-overflow cell */ - u8 *apOvfl[5]; /* Pointers to the body of overflow cells */ + u8 *apOvfl[4]; /* Pointers to the body of overflow cells */ BtShared *pBt; /* Pointer to BtShared that this page is part of */ u8 *aData; /* Pointer to disk image of the page data */ u8 *aDataEnd; /* One byte past the end of usable data */ @@ -298,16 +300,8 @@ struct MemPage { DbPage *pDbPage; /* Pager page handle */ u16 (*xCellSize)(MemPage*,u8*); /* cellSizePtr method */ void (*xParseCell)(MemPage*,u8*,CellInfo*); /* btreeParseCell method */ - Pgno pgno; /* Page number for this page */ }; -/* -** The in-memory image of a disk page has the auxiliary information appended -** to the end. EXTRA_SIZE is the number of bytes of space needed to hold -** that extra information. -*/ -#define EXTRA_SIZE sizeof(MemPage) - /* ** A linked list of the following structures is stored at BtShared.pLock. ** Locks are added (or upgraded from READ_LOCK to WRITE_LOCK) when a cursor diff --git a/src/pager.c b/src/pager.c index 9975f3fcbb..aa989f4ef2 100644 --- a/src/pager.c +++ b/src/pager.c @@ -3955,7 +3955,8 @@ static int pagerAcquireMapPage( *ppPage = p = pPager->pMmapFreelist; pPager->pMmapFreelist = p->pDirty; p->pDirty = 0; - memset(p->pExtra, 0, pPager->nExtra); + assert( pPager->nExtra>=8 ); + memset(p->pExtra, 0, 8); }else{ *ppPage = p = (PgHdr *)sqlite3MallocZero(sizeof(PgHdr) + pPager->nExtra); if( p==0 ){ @@ -4555,7 +4556,9 @@ int sqlite3PagerFlush(Pager *pPager){ ** ** The nExtra parameter specifies the number of bytes of space allocated ** along with each page reference. This space is available to the user -** via the sqlite3PagerGetExtra() API. +** via the sqlite3PagerGetExtra() API. When a new page is allocated, the +** first 8 bytes of this space are zeroed but the remainder is uninitialized. +** (The extra space is used by btree as the MemPage object.) ** ** The flags argument is used to specify properties that affect the ** operation of the pager. It should be passed some bitwise combination @@ -4785,8 +4788,8 @@ act_like_temp_file: /* Initialize the PCache object. */ if( rc==SQLITE_OK ){ - assert( nExtra<1000 ); nExtra = ROUND8(nExtra); + assert( nExtra>=8 && nExtra<1000 ); rc = sqlite3PcacheOpen(szPageDflt, nExtra, !memDb, !memDb?pagerStress:0, (void *)pPager, pPager->pPCache); } diff --git a/src/pcache.c b/src/pcache.c index 68f4b51dc8..70cf0f5a0d 100644 --- a/src/pcache.c +++ b/src/pcache.c @@ -284,6 +284,12 @@ int sqlite3PcacheSize(void){ return sizeof(PCache); } ** has already been allocated and is passed in as the p pointer. ** The caller discovers how much space needs to be allocated by ** calling sqlite3PcacheSize(). +** +** szExtra is some extra space allocated for each page. The first +** 8 bytes of the extra space will be zeroed as the page is allocated, +** but remaining content will be uninitialized. Though it is opaque +** to this module, the extra space really ends up being the MemPage +** structure in the pager. */ int sqlite3PcacheOpen( int szPage, /* Size of every page */ @@ -296,6 +302,7 @@ int sqlite3PcacheOpen( memset(p, 0, sizeof(PCache)); p->szPage = 1; p->szExtra = szExtra; + assert( szExtra>=8 ); /* First 8 bytes will be zeroed */ p->bPurgeable = bPurgeable; p->eCreate = 2; p->xStress = xStress; @@ -465,7 +472,7 @@ static SQLITE_NOINLINE PgHdr *pcacheFetchFinishWithInit( pPgHdr->pPage = pPage; pPgHdr->pData = pPage->pBuf; pPgHdr->pExtra = (void *)&pPgHdr[1]; - memset(pPgHdr->pExtra, 0, pCache->szExtra); + memset(pPgHdr->pExtra, 0, 8); pPgHdr->pCache = pCache; pPgHdr->pgno = pgno; pPgHdr->flags = PGHDR_CLEAN; From 55092c15042119da5b2970272b96e8244f498387 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 9 Dec 2016 16:12:04 +0000 Subject: [PATCH 1061/1484] Fix an fts5 bug that could cause a crash following an OOM error or sqlite3_interrupt() interrupt. FossilOrigin-Name: 0ea3ece988883874bb88e3daaa220d7fc0cf36ef --- ext/fts5/fts5_expr.c | 5 ++++- ext/fts5/test/fts5faultB.test | 28 ++++++++++++++++++++++++++++ manifest | 16 ++++++++-------- manifest.uuid | 2 +- 4 files changed, 41 insertions(+), 10 deletions(-) diff --git a/ext/fts5/fts5_expr.c b/ext/fts5/fts5_expr.c index 20fd32467c..9dcd88a5bc 100644 --- a/ext/fts5/fts5_expr.c +++ b/ext/fts5/fts5_expr.c @@ -1344,7 +1344,10 @@ int sqlite3Fts5ExprFirst(Fts5Expr *p, Fts5Index *pIdx, i64 iFirst, int bDesc){ /* If not at EOF but the current rowid occurs earlier than iFirst in ** the iteration order, move to document iFirst or later. */ - if( pRoot->bEof==0 && fts5RowidCmp(p, pRoot->iRowid, iFirst)<0 ){ + if( rc==SQLITE_OK + && 0==pRoot->bEof + && fts5RowidCmp(p, pRoot->iRowid, iFirst)<0 + ){ rc = fts5ExprNodeNext(p, pRoot, 1, iFirst); } diff --git a/ext/fts5/test/fts5faultB.test b/ext/fts5/test/fts5faultB.test index 40df8b6043..2ce33f4bc4 100644 --- a/ext/fts5/test/fts5faultB.test +++ b/ext/fts5/test/fts5faultB.test @@ -78,6 +78,34 @@ do_faultsim_test 2.4 -faults oom* -body { faultsim_test_result {0 {{3 2} {2 3}}} } +#------------------------------------------------------------------------- +# +reset_db +do_execsql_test 3.0 { + CREATE VIRTUAL TABLE x1 USING fts5(z); +} + +do_faultsim_test 3.1 -faults oom* -body { + execsql { + SELECT rowid FROM x1('c') WHERE rowid>1; + } +} -test { + faultsim_test_result {0 {}} +} + +do_execsql_test 3.2 { + INSERT INTO x1 VALUES('a b c'); + INSERT INTO x1 VALUES('b c d'); + INSERT INTO x1 VALUES('c d e'); + INSERT INTO x1 VALUES('d e f'); +} +do_faultsim_test 3.3 -faults oom* -body { + execsql { + SELECT rowid FROM x1('c') WHERE rowid>1; + } +} -test { + faultsim_test_result {0 {2 3}} +} finish_test diff --git a/manifest b/manifest index 660cdf184e..faa73d2add 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sunnecessary\szeroing\sof\sfields\sin\sthe\sMemPage\sobject\sthat\sare\sgoing\nto\sbe\sreinitialized\sbefore\suse\sanyhow.\s\sA\ssmaller\sand\sfaster\sbinary\sresults. -D 2016-12-09T16:02:00.219 +C Fix\san\sfts5\sbug\sthat\scould\scause\sa\scrash\sfollowing\san\sOOM\serror\sor\nsqlite3_interrupt()\sinterrupt. +D 2016-12-09T16:12:04.593 F Makefile.in 7639c6a09da11a9c7c6f2630fc981ee588d1072d F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -102,7 +102,7 @@ F ext/fts5/fts5Int.h b2eda36e0f224365c8e23dc8f559311834f1c13f F ext/fts5/fts5_aux.c 67acf8d51723cf28ffc3828210ba662df4b8d267 F ext/fts5/fts5_buffer.c 4c1502d4c956cd092c89ce4480867f9d8bf325cd F ext/fts5/fts5_config.c 5af9c360e99669d29f06492c370892394aba0857 -F ext/fts5/fts5_expr.c 34ece379a83efd047e0a0fc170e476ba76b0404a +F ext/fts5/fts5_expr.c dc2cee9f56b1818b85df59304b8104a5dfb8ab60 F ext/fts5/fts5_hash.c 880998e596b60f078348d48732ca4ad9a90caad2 F ext/fts5/fts5_index.c fdbe46da11e81c1817cd4cb2de25ffdb4dd83711 F ext/fts5/fts5_main.c f85281445dcf8be32d18841c93a6f90fe27dbfe2 @@ -159,7 +159,7 @@ F ext/fts5/test/fts5fault7.test cb14ea3c1f42394f06f2284abc58eecee6ff8080 F ext/fts5/test/fts5fault8.test 6785af34bd1760de74e2824ea9c161965af78f85 F ext/fts5/test/fts5fault9.test e10e395428a9ea0596ebe752ff7123d16ab78e08 F ext/fts5/test/fts5faultA.test fa5d59c0ff62b7125cd14eee38ded1c46e15a7ea -F ext/fts5/test/fts5faultB.test 92ae906284062bf081b6c854afa54dcb1aa9ef88 +F ext/fts5/test/fts5faultB.test 7f3bba790fa172073ac314f9b8ed197390b61eca F ext/fts5/test/fts5full.test 6f6143af0c6700501d9fd597189dfab1555bb741 F ext/fts5/test/fts5fuzz1.test bece4695fc169b61ab236ada7931c6e4942cbef9 F ext/fts5/test/fts5hash.test 06f9309ccb4d5050a131594e9e47d0b21456837d @@ -1536,7 +1536,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 1f16c9a76bc48331799f33b30d143c632fe0e7db -R 7472834dbbfbcc03bad94800a01d7495 -U drh -Z 662ad8d58fb59ba8bcf6c7d7e219ef69 +P 01ada3d1068476f90dcae02cb089001ea4bcc23d +R 6c11217a616aa1a10db37b68e7e9ff3a +U dan +Z 2ed0e00b28721a896fc3a4cd535080e8 diff --git a/manifest.uuid b/manifest.uuid index f9626ae2c1..926c22f6a6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -01ada3d1068476f90dcae02cb089001ea4bcc23d \ No newline at end of file +0ea3ece988883874bb88e3daaa220d7fc0cf36ef \ No newline at end of file From 80159da6c653ecf8e6af90b9ca632809a538a58b Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 9 Dec 2016 17:32:51 +0000 Subject: [PATCH 1062/1484] In sqlite3BtreeInsert() when replacing a re-existing row, try to overwrite the cell directly rather than deallocate and reallocate the cell. FossilOrigin-Name: 0b86fbca6615ccf1f3a62614db577a8acbec6d9e --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/btree.c | 37 ++++++++++++++++++++----------------- 3 files changed, 28 insertions(+), 25 deletions(-) diff --git a/manifest b/manifest index faa73d2add..51cd5a2b1f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\sfts5\sbug\sthat\scould\scause\sa\scrash\sfollowing\san\sOOM\serror\sor\nsqlite3_interrupt()\sinterrupt. -D 2016-12-09T16:12:04.593 +C In\ssqlite3BtreeInsert()\swhen\sreplacing\sa\sre-existing\srow,\stry\sto\soverwrite\nthe\scell\sdirectly\srather\sthan\sdeallocate\sand\sreallocate\sthe\scell. +D 2016-12-09T17:32:51.304 F Makefile.in 7639c6a09da11a9c7c6f2630fc981ee588d1072d F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -331,7 +331,7 @@ F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792 F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 -F src/btree.c c73d77875c83407a0048f5e29d1251536e9f009d +F src/btree.c 71f31086e48b0802990e95dbc30b65486f8c102d F src/btree.h 2349a588abcd7e0c04f984e15c5c777b61637583 F src/btreeInt.h 10c4b77c2fb399580babbcc7cf652ac10dba796e F src/build.c 178f16698cbcb43402c343a9413fe22c99ffee21 @@ -1536,7 +1536,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 01ada3d1068476f90dcae02cb089001ea4bcc23d -R 6c11217a616aa1a10db37b68e7e9ff3a -U dan -Z 2ed0e00b28721a896fc3a4cd535080e8 +P 0ea3ece988883874bb88e3daaa220d7fc0cf36ef +R 6946276392a9f20f9596069270e1a062 +U drh +Z ec93e08c56ba9575d48dea94960936a0 diff --git a/manifest.uuid b/manifest.uuid index 926c22f6a6..3a823c3a65 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0ea3ece988883874bb88e3daaa220d7fc0cf36ef \ No newline at end of file +0b86fbca6615ccf1f3a62614db577a8acbec6d9e \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 999ce159cc..2505e099bb 100644 --- a/src/btree.c +++ b/src/btree.c @@ -5996,30 +5996,28 @@ static void freePage(MemPage *pPage, int *pRC){ static int clearCell( MemPage *pPage, /* The page that contains the Cell */ unsigned char *pCell, /* First byte of the Cell */ - u16 *pnSize /* Write the size of the Cell here */ + CellInfo *pInfo /* Size information about the cell */ ){ BtShared *pBt = pPage->pBt; - CellInfo info; Pgno ovflPgno; int rc; int nOvfl; u32 ovflPageSize; assert( sqlite3_mutex_held(pPage->pBt->mutex) ); - pPage->xParseCell(pPage, pCell, &info); - *pnSize = info.nSize; - if( info.nLocal==info.nPayload ){ + pPage->xParseCell(pPage, pCell, pInfo); + if( pInfo->nLocal==pInfo->nPayload ){ return SQLITE_OK; /* No overflow pages. Return without doing anything */ } - if( pCell+info.nSize-1 > pPage->aData+pPage->maskPage ){ + if( pCell+pInfo->nSize-1 > pPage->aData+pPage->maskPage ){ return SQLITE_CORRUPT_BKPT; /* Cell extends past end of page */ } - ovflPgno = get4byte(pCell + info.nSize - 4); + ovflPgno = get4byte(pCell + pInfo->nSize - 4); assert( pBt->usableSize > 4 ); ovflPageSize = pBt->usableSize - 4; - nOvfl = (info.nPayload - info.nLocal + ovflPageSize - 1)/ovflPageSize; + nOvfl = (pInfo->nPayload - pInfo->nLocal + ovflPageSize - 1)/ovflPageSize; assert( nOvfl>0 || - (CORRUPT_DB && (info.nPayload + ovflPageSize)nPayload + ovflPageSize)aiIdx[pCur->iPage]; if( loc==0 ){ - u16 szOld; + CellInfo info; assert( idxnCell ); rc = sqlite3PagerWrite(pPage->pDbPage); if( rc ){ @@ -8062,8 +8060,13 @@ int sqlite3BtreeInsert( if( !pPage->leaf ){ memcpy(newCell, oldCell, 4); } - rc = clearCell(pPage, oldCell, &szOld); - dropCell(pPage, idx, szOld, &rc); + rc = clearCell(pPage, oldCell, &info); + if( info.nSize==szNew && info.nLocal==info.nPayload ){ + /* Overwrite the old cell with the new */ + memcpy(oldCell, newCell, szNew); + return SQLITE_OK; + } + dropCell(pPage, idx, info.nSize, &rc); if( rc ) goto end_insert; }else if( loc<0 && pPage->nCell>0 ){ assert( pPage->leaf ); @@ -8139,7 +8142,7 @@ int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){ unsigned char *pCell; /* Pointer to cell to delete */ int iCellIdx; /* Index of cell to delete */ int iCellDepth; /* Depth of node containing pCell */ - u16 szCell; /* Size of the cell being deleted */ + CellInfo info; /* Size of the cell being deleted */ int bSkipnext = 0; /* Leaf cursor in SKIPNEXT state */ u8 bPreserve = flags & BTREE_SAVEPOSITION; /* Keep cursor valid */ @@ -8211,8 +8214,8 @@ int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){ ** itself from within the page. */ rc = sqlite3PagerWrite(pPage->pDbPage); if( rc ) return rc; - rc = clearCell(pPage, pCell, &szCell); - dropCell(pPage, iCellIdx, szCell, &rc); + rc = clearCell(pPage, pCell, &info); + dropCell(pPage, iCellIdx, info.nSize, &rc); if( rc ) return rc; /* If the cell deleted was not located on a leaf page, then the cursor @@ -8462,7 +8465,7 @@ static int clearDatabasePage( unsigned char *pCell; int i; int hdr; - u16 szCell; + CellInfo info; assert( sqlite3_mutex_held(pBt->mutex) ); if( pgno>btreePagecount(pBt) ){ @@ -8482,7 +8485,7 @@ static int clearDatabasePage( rc = clearDatabasePage(pBt, get4byte(pCell), 1, pnChange); if( rc ) goto cleardatabasepage_out; } - rc = clearCell(pPage, pCell, &szCell); + rc = clearCell(pPage, pCell, &info); if( rc ) goto cleardatabasepage_out; } if( !pPage->leaf ){ From f9238254246895d748dc1eb17150744b05188906 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 9 Dec 2016 18:09:42 +0000 Subject: [PATCH 1063/1484] Additional comments and an assert on the sqlite3BtreeInsert() overwrite optimization. FossilOrigin-Name: c1f0ae9d2981a19875103750379ad26f2575f878 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btree.c | 7 ++++++- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 51cd5a2b1f..f92e4ec7ff 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\ssqlite3BtreeInsert()\swhen\sreplacing\sa\sre-existing\srow,\stry\sto\soverwrite\nthe\scell\sdirectly\srather\sthan\sdeallocate\sand\sreallocate\sthe\scell. -D 2016-12-09T17:32:51.304 +C Additional\scomments\sand\san\sassert\son\sthe\ssqlite3BtreeInsert()\soverwrite\noptimization. +D 2016-12-09T18:09:42.258 F Makefile.in 7639c6a09da11a9c7c6f2630fc981ee588d1072d F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -331,7 +331,7 @@ F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792 F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 -F src/btree.c 71f31086e48b0802990e95dbc30b65486f8c102d +F src/btree.c 38bc160dfb270b4e005b23672310096c78eed4c8 F src/btree.h 2349a588abcd7e0c04f984e15c5c777b61637583 F src/btreeInt.h 10c4b77c2fb399580babbcc7cf652ac10dba796e F src/build.c 178f16698cbcb43402c343a9413fe22c99ffee21 @@ -1536,7 +1536,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 0ea3ece988883874bb88e3daaa220d7fc0cf36ef -R 6946276392a9f20f9596069270e1a062 +P 0b86fbca6615ccf1f3a62614db577a8acbec6d9e +R 11e5ca14997252e736d13429f6c59d06 U drh -Z ec93e08c56ba9575d48dea94960936a0 +Z db8419761e0f22ff22785868538d89ab diff --git a/manifest.uuid b/manifest.uuid index 3a823c3a65..56e8b4d197 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0b86fbca6615ccf1f3a62614db577a8acbec6d9e \ No newline at end of file +c1f0ae9d2981a19875103750379ad26f2575f878 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 2505e099bb..d18f8d186d 100644 --- a/src/btree.c +++ b/src/btree.c @@ -8062,7 +8062,12 @@ int sqlite3BtreeInsert( } rc = clearCell(pPage, oldCell, &info); if( info.nSize==szNew && info.nLocal==info.nPayload ){ - /* Overwrite the old cell with the new */ + /* Overwrite the old cell with the new if they are the same size. + ** We could also try to do this if the old cell is smaller, then add + ** the leftover space to the free list. But experiments show that + ** doing that is no faster then skipping this optimization and just + ** calling dropCell() and insertCell(). */ + assert( rc==SQLITE_OK ); /* clearCell never fails when nLocal==nPayload */ memcpy(oldCell, newCell, szNew); return SQLITE_OK; } From 2d08343a913619f05e379b7ce55f900ec80d9f77 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 9 Dec 2016 19:42:18 +0000 Subject: [PATCH 1064/1484] When doing the sqlite3BtreeInsert() overwrite optimization, make sure the memcpy() does not extend off the end of the page. FossilOrigin-Name: 684ef4582ed19b2af22dda6fc085c70464f92f1b --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btree.c | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index f92e4ec7ff..45507e32cb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Additional\scomments\sand\san\sassert\son\sthe\ssqlite3BtreeInsert()\soverwrite\noptimization. -D 2016-12-09T18:09:42.258 +C When\sdoing\sthe\ssqlite3BtreeInsert()\soverwrite\soptimization,\smake\ssure\sthe\nmemcpy()\sdoes\snot\sextend\soff\sthe\send\sof\sthe\spage. +D 2016-12-09T19:42:18.129 F Makefile.in 7639c6a09da11a9c7c6f2630fc981ee588d1072d F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -331,7 +331,7 @@ F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792 F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 -F src/btree.c 38bc160dfb270b4e005b23672310096c78eed4c8 +F src/btree.c 217c9900de7cf04997aff25faabc366cfe84e8f1 F src/btree.h 2349a588abcd7e0c04f984e15c5c777b61637583 F src/btreeInt.h 10c4b77c2fb399580babbcc7cf652ac10dba796e F src/build.c 178f16698cbcb43402c343a9413fe22c99ffee21 @@ -1536,7 +1536,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 0b86fbca6615ccf1f3a62614db577a8acbec6d9e -R 11e5ca14997252e736d13429f6c59d06 +P c1f0ae9d2981a19875103750379ad26f2575f878 +R 956ba83a1c02ce8b54106bed68f282ac U drh -Z db8419761e0f22ff22785868538d89ab +Z 1db7deef38744b5038e919d70ebcde44 diff --git a/manifest.uuid b/manifest.uuid index 56e8b4d197..ea8d54ff5b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c1f0ae9d2981a19875103750379ad26f2575f878 \ No newline at end of file +684ef4582ed19b2af22dda6fc085c70464f92f1b \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index d18f8d186d..b7e16a85f2 100644 --- a/src/btree.c +++ b/src/btree.c @@ -8068,6 +8068,7 @@ int sqlite3BtreeInsert( ** doing that is no faster then skipping this optimization and just ** calling dropCell() and insertCell(). */ assert( rc==SQLITE_OK ); /* clearCell never fails when nLocal==nPayload */ + if( oldCell+szNew > pPage->aDataEnd ) return SQLITE_CORRUPT_BKPT; memcpy(oldCell, newCell, szNew); return SQLITE_OK; } From 719da30d53511cbaf2c818b712bdc7db3c5cf140 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 10 Dec 2016 04:06:49 +0000 Subject: [PATCH 1065/1484] Avoid signed integer overflow when dealing with a LIMIT and OFFSET whose sum exceeds the maximum integer value. FossilOrigin-Name: c9bdf7adb4745cfaf23d9afd496e71fa37793108 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 15 ++++++++++++++- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 45507e32cb..a09f854f71 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C When\sdoing\sthe\ssqlite3BtreeInsert()\soverwrite\soptimization,\smake\ssure\sthe\nmemcpy()\sdoes\snot\sextend\soff\sthe\send\sof\sthe\spage. -D 2016-12-09T19:42:18.129 +C Avoid\ssigned\sinteger\soverflow\swhen\sdealing\swith\sa\sLIMIT\sand\sOFFSET\swhose\nsum\sexceeds\sthe\smaximum\sinteger\svalue. +D 2016-12-10T04:06:49.278 F Makefile.in 7639c6a09da11a9c7c6f2630fc981ee588d1072d F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -455,7 +455,7 @@ F src/update.c 1da7c462110bffed442a42884cb0d528c1db46d8 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c e68e8ced7328f22d2cf7b4c898c394a0de34cdf1 F src/vacuum.c 33c174b28886b2faf26e503b5a49a1c01a9b1c16 -F src/vdbe.c 3986f226945b14b98eb26bd589de3705223c95ad +F src/vdbe.c 74a0b006d478fa2473aba99c7ead716853686bfb F src/vdbe.h 0c74f6305fb43b9b282dacaff102272370e327d4 F src/vdbeInt.h 9b498d3cb52dc2efb53571fb8ae8e14cf298ce84 F src/vdbeapi.c ea4e2dc2213cc6bd7bee375a29a9b51c31b93ae0 @@ -1536,7 +1536,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P c1f0ae9d2981a19875103750379ad26f2575f878 -R 956ba83a1c02ce8b54106bed68f282ac +P 684ef4582ed19b2af22dda6fc085c70464f92f1b +R 385b2371f29bb67ef698b575b58999ac U drh -Z 1db7deef38744b5038e919d70ebcde44 +Z 61eef24c866f9763195673d062edf64e diff --git a/manifest.uuid b/manifest.uuid index ea8d54ff5b..81c1cc2c03 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -684ef4582ed19b2af22dda6fc085c70464f92f1b \ No newline at end of file +c9bdf7adb4745cfaf23d9afd496e71fa37793108 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 86088905f4..6b39ac54a1 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -5991,12 +5991,25 @@ case OP_IfPos: { /* jump, in1 */ ** Otherwise, r[P2] is set to the sum of r[P1] and r[P3]. */ case OP_OffsetLimit: { /* in1, out2, in3 */ + i64 x; pIn1 = &aMem[pOp->p1]; pIn3 = &aMem[pOp->p3]; pOut = out2Prerelease(p, pOp); assert( pIn1->flags & MEM_Int ); assert( pIn3->flags & MEM_Int ); - pOut->u.i = pIn1->u.i<=0 ? -1 : pIn1->u.i+(pIn3->u.i>0?pIn3->u.i:0); + x = pIn1->u.i; + if( x<=0 || sqlite3AddInt64(&x, pIn3->u.i>0?pIn3->u.i:0) ){ + /* If the LIMIT is less than or equal to zero, loop forever. This + ** is documented. But also, if the LIMIT+OFFSET exceeds 2^63 then + ** also loop forever. This is undocumented. In fact, one could argue + ** that the loop should terminate. But assuming 1 billion iterations + ** per second (far exceeding the capabilities of any current hardware) + ** it would take nearly 300 years to actually reach the limit. So + ** looping forever is a reasonable approximation. */ + pOut->u.i = -1; + }else{ + pOut->u.i = x; + } break; } From fbd8cbdcf524380dc760666313e22426c508df0f Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 10 Dec 2016 12:58:15 +0000 Subject: [PATCH 1066/1484] Reorder the fields in the VdbeCursor object so that those that need to be bulk zeroed on allocation are grouped at the beginning, and the memset() only runs over those fields that really need it. FossilOrigin-Name: 8165f88bb1d40693d67005a8d5dc499085f64b91 --- manifest | 18 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 15 +++++----- src/vdbeInt.h | 80 +++++++++++++++++++++++++------------------------- src/vdbeaux.c | 6 ++-- src/vdbesort.c | 2 +- 6 files changed, 61 insertions(+), 62 deletions(-) diff --git a/manifest b/manifest index a09f854f71..3d85299a2f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\ssigned\sinteger\soverflow\swhen\sdealing\swith\sa\sLIMIT\sand\sOFFSET\swhose\nsum\sexceeds\sthe\smaximum\sinteger\svalue. -D 2016-12-10T04:06:49.278 +C Reorder\sthe\sfields\sin\sthe\sVdbeCursor\sobject\sso\sthat\sthose\sthat\sneed\sto\sbe\nbulk\szeroed\son\sallocation\sare\sgrouped\sat\sthe\sbeginning,\sand\sthe\smemset()\nonly\sruns\sover\sthose\sfields\sthat\sreally\sneed\sit. +D 2016-12-10T12:58:15.294 F Makefile.in 7639c6a09da11a9c7c6f2630fc981ee588d1072d F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -455,14 +455,14 @@ F src/update.c 1da7c462110bffed442a42884cb0d528c1db46d8 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c e68e8ced7328f22d2cf7b4c898c394a0de34cdf1 F src/vacuum.c 33c174b28886b2faf26e503b5a49a1c01a9b1c16 -F src/vdbe.c 74a0b006d478fa2473aba99c7ead716853686bfb +F src/vdbe.c 2d90c42f2117b36e92c3af6a9c9f380b22e6e3b8 F src/vdbe.h 0c74f6305fb43b9b282dacaff102272370e327d4 -F src/vdbeInt.h 9b498d3cb52dc2efb53571fb8ae8e14cf298ce84 +F src/vdbeInt.h 42e498dbe96475dbb3fda3d85d8fd2a87eff60a2 F src/vdbeapi.c ea4e2dc2213cc6bd7bee375a29a9b51c31b93ae0 -F src/vdbeaux.c be0797ca0c392eea2201afbf2eef0b1531e2a8b7 +F src/vdbeaux.c f5edc89007f8a49e224089a4a4dddbc11bd38213 F src/vdbeblob.c f4f98ea672b242f807c08c92c7faaa79e5091b65 F src/vdbemem.c d3fd85b7b7ef3eb75de29c6d7e1d10d3ca78b4fd -F src/vdbesort.c 91fda3909326860382b0ca8aa251e609c6a9d62c +F src/vdbesort.c bb34eed4fb52e11ac037dccea4ee3190594c7f9e F src/vdbetrace.c 41963d5376f0349842b5fc4aaaaacd7d9cdc0834 F src/vtab.c e02cacb5c7ae742631edeb9ae9f53d399f093fd8 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 @@ -1536,7 +1536,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 684ef4582ed19b2af22dda6fc085c70464f92f1b -R 385b2371f29bb67ef698b575b58999ac +P c9bdf7adb4745cfaf23d9afd496e71fa37793108 +R 15ccb7ac71f3aa4a9f56889c6a3828ff U drh -Z 61eef24c866f9763195673d062edf64e +Z 0b109188ec32185ef59cc63fa028b152 diff --git a/manifest.uuid b/manifest.uuid index 81c1cc2c03..3253d01dd9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c9bdf7adb4745cfaf23d9afd496e71fa37793108 \ No newline at end of file +8165f88bb1d40693d67005a8d5dc499085f64b91 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 6b39ac54a1..8459cc4613 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -221,7 +221,7 @@ static VdbeCursor *allocateCursor( } if( SQLITE_OK==sqlite3VdbeMemClearAndResize(pMem, nByte) ){ p->apCsr[iCur] = pCx = (VdbeCursor*)pMem->z; - memset(pCx, 0, sizeof(VdbeCursor)); + memset(pCx, 0, offsetof(VdbeCursor,pAltCursor)); pCx->eCurType = eCurType; pCx->iDb = iDb; pCx->nField = nField; @@ -3527,10 +3527,10 @@ case OP_OpenEphemeral: { if( pCx==0 ) goto no_mem; pCx->nullRow = 1; pCx->isEphemeral = 1; - rc = sqlite3BtreeOpen(db->pVfs, 0, db, &pCx->pBt, + rc = sqlite3BtreeOpen(db->pVfs, 0, db, &pCx->pBtx, BTREE_OMIT_JOURNAL | BTREE_SINGLE | pOp->p5, vfsFlags); if( rc==SQLITE_OK ){ - rc = sqlite3BtreeBeginTrans(pCx->pBt, 1); + rc = sqlite3BtreeBeginTrans(pCx->pBtx, 1); } if( rc==SQLITE_OK ){ /* If a transient index is required, create it by calling @@ -3538,21 +3538,20 @@ case OP_OpenEphemeral: { ** opening it. If a transient table is required, just use the ** automatically created table with root-page 1 (an BLOB_INTKEY table). */ - if( (pKeyInfo = pOp->p4.pKeyInfo)!=0 ){ + if( (pCx->pKeyInfo = pKeyInfo = pOp->p4.pKeyInfo)!=0 ){ int pgno; assert( pOp->p4type==P4_KEYINFO ); - rc = sqlite3BtreeCreateTable(pCx->pBt, &pgno, BTREE_BLOBKEY | pOp->p5); + rc = sqlite3BtreeCreateTable(pCx->pBtx, &pgno, BTREE_BLOBKEY | pOp->p5); if( rc==SQLITE_OK ){ assert( pgno==MASTER_ROOT+1 ); assert( pKeyInfo->db==db ); assert( pKeyInfo->enc==ENC(db) ); - pCx->pKeyInfo = pKeyInfo; - rc = sqlite3BtreeCursor(pCx->pBt, pgno, BTREE_WRCSR, + rc = sqlite3BtreeCursor(pCx->pBtx, pgno, BTREE_WRCSR, pKeyInfo, pCx->uc.pCursor); } pCx->isTable = 0; }else{ - rc = sqlite3BtreeCursor(pCx->pBt, MASTER_ROOT, BTREE_WRCSR, + rc = sqlite3BtreeCursor(pCx->pBtx, MASTER_ROOT, BTREE_WRCSR, 0, pCx->uc.pCursor); pCx->isTable = 1; } diff --git a/src/vdbeInt.h b/src/vdbeInt.h index df65124999..dbdde00edf 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -73,60 +73,60 @@ typedef struct AuxData AuxData; */ typedef struct VdbeCursor VdbeCursor; struct VdbeCursor { - u8 eCurType; /* One of the CURTYPE_* values above */ - i8 iDb; /* Index of cursor database in db->aDb[] (or -1) */ - u8 nullRow; /* True if pointing to a row with no data */ - u8 deferredMoveto; /* A call to sqlite3BtreeMoveto() is needed */ - u8 isTable; /* True for rowid tables. False for indexes */ + u8 eCurType; /* One of the CURTYPE_* values above */ + i8 iDb; /* Index of cursor database in db->aDb[] (or -1) */ + u8 nullRow; /* True if pointing to a row with no data */ + u8 deferredMoveto; /* A call to sqlite3BtreeMoveto() is needed */ + u8 isTable; /* True for rowid tables. False for indexes */ #ifdef SQLITE_DEBUG - u8 seekOp; /* Most recent seek operation on this cursor */ - u8 wrFlag; /* The wrFlag argument to sqlite3BtreeCursor() */ + u8 seekOp; /* Most recent seek operation on this cursor */ + u8 wrFlag; /* The wrFlag argument to sqlite3BtreeCursor() */ #endif - Bool isEphemeral:1; /* True for an ephemeral table */ - Bool useRandomRowid:1;/* Generate new record numbers semi-randomly */ - Bool isOrdered:1; /* True if the table is not BTREE_UNORDERED */ - Pgno pgnoRoot; /* Root page of the open btree cursor */ - i16 nField; /* Number of fields in the header */ - u16 nHdrParsed; /* Number of header fields parsed so far */ + Bool isEphemeral:1; /* True for an ephemeral table */ + Bool useRandomRowid:1; /* Generate new record numbers semi-randomly */ + Bool isOrdered:1; /* True if the table is not BTREE_UNORDERED */ + Btree *pBtx; /* Separate file holding temporary table */ + i64 seqCount; /* Sequence counter */ + int *aAltMap; /* Mapping from table to index column numbers */ + + /* Cached OP_Column parse information is only valid if cacheStatus matches + ** Vdbe.cacheCtr. Vdbe.cacheCtr will never take on the value of + ** CACHE_STALE (0) and so setting cacheStatus=CACHE_STALE guarantees that + ** the cache is out of date. */ + u32 cacheStatus; /* Cache is valid if this matches Vdbe.cacheCtr */ + int seekResult; /* Result of previous sqlite3BtreeMoveto() or 0 + ** if there have been no prior seeks on the cursor. */ + /* NB: seekResult does not distinguish between "no seeks have ever occurred + ** on this cursor" and "the most recent seek was an exact match". */ + + /* When a new VdbeCursor is allocated, only the fields above are zeroed. + ** The fields that follow are uninitialized, and must be individually + ** initialized prior to first use. */ + VdbeCursor *pAltCursor; /* Associated index cursor from which to read */ union { BtCursor *pCursor; /* CURTYPE_BTREE. Btree cursor */ sqlite3_vtab_cursor *pVCur; /* CURTYPE_VTAB. Vtab cursor */ int pseudoTableReg; /* CURTYPE_PSEUDO. Reg holding content. */ VdbeSorter *pSorter; /* CURTYPE_SORTER. Sorter object */ } uc; - Btree *pBt; /* Separate file holding temporary table */ - KeyInfo *pKeyInfo; /* Info about index keys needed by index cursors */ - int seekResult; /* Result of previous sqlite3BtreeMoveto() or 0 - ** if there have been no prior seeks on the cursor. */ - /* NB: seekResult does not distinguish between "no seeks have ever occurred - ** on this cursor" and "the most recent seek was an exact match". */ - i64 seqCount; /* Sequence counter */ - i64 movetoTarget; /* Argument to the deferred sqlite3BtreeMoveto() */ - VdbeCursor *pAltCursor; /* Associated index cursor from which to read */ - int *aAltMap; /* Mapping from table to index column numbers */ + KeyInfo *pKeyInfo; /* Info about index keys needed by index cursors */ + u32 iHdrOffset; /* Offset to next unparsed byte of the header */ + Pgno pgnoRoot; /* Root page of the open btree cursor */ + i16 nField; /* Number of fields in the header */ + u16 nHdrParsed; /* Number of header fields parsed so far */ + i64 movetoTarget; /* Argument to the deferred sqlite3BtreeMoveto() */ + u32 *aOffset; /* Pointer to aType[nField] */ + const u8 *aRow; /* Data for the current row, if all on one page */ + u32 payloadSize; /* Total number of bytes in the record */ + u32 szRow; /* Byte available in aRow */ #ifdef SQLITE_ENABLE_COLUMN_USED_MASK - u64 maskUsed; /* Mask of columns used by this cursor */ + u64 maskUsed; /* Mask of columns used by this cursor */ #endif - /* Cached information about the header for the data record that the - ** cursor is currently pointing to. Only valid if cacheStatus matches - ** Vdbe.cacheCtr. Vdbe.cacheCtr will never take on the value of - ** CACHE_STALE and so setting cacheStatus=CACHE_STALE guarantees that - ** the cache is out of date. - ** - ** aRow might point to (ephemeral) data for the current row, or it might - ** be NULL. - */ - u32 cacheStatus; /* Cache is valid if this matches Vdbe.cacheCtr */ - u32 payloadSize; /* Total number of bytes in the record */ - u32 szRow; /* Byte available in aRow */ - u32 iHdrOffset; /* Offset to next unparsed byte of the header */ - const u8 *aRow; /* Data for the current row, if all on one page */ - u32 *aOffset; /* Pointer to aType[nField] */ - u32 aType[1]; /* Type values for all entries in the record */ /* 2*nField extra array elements allocated for aType[], beyond the one ** static element declared in the structure. nField total array slots for ** aType[] and nField+1 array slots for aOffset[] */ + u32 aType[1]; /* Type values record decode. MUST BE LAST */ }; diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 2fc973c48a..765f412786 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -2006,15 +2006,15 @@ void sqlite3VdbeFreeCursor(Vdbe *p, VdbeCursor *pCx){ if( pCx==0 ){ return; } - assert( pCx->pBt==0 || pCx->eCurType==CURTYPE_BTREE ); + assert( pCx->pBtx==0 || pCx->eCurType==CURTYPE_BTREE ); switch( pCx->eCurType ){ case CURTYPE_SORTER: { sqlite3VdbeSorterClose(p->db, pCx); break; } case CURTYPE_BTREE: { - if( pCx->pBt ){ - sqlite3BtreeClose(pCx->pBt); + if( pCx->pBtx ){ + sqlite3BtreeClose(pCx->pBtx); /* The pCx->pCursor will be close automatically, if it exists, by ** the call above. */ }else{ diff --git a/src/vdbesort.c b/src/vdbesort.c index 69619802e8..52f08bfb4b 100644 --- a/src/vdbesort.c +++ b/src/vdbesort.c @@ -959,7 +959,7 @@ int sqlite3VdbeSorterInit( } #endif - assert( pCsr->pKeyInfo && pCsr->pBt==0 ); + assert( pCsr->pKeyInfo && pCsr->pBtx==0 ); assert( pCsr->eCurType==CURTYPE_SORTER ); szKeyInfo = sizeof(KeyInfo) + (pCsr->pKeyInfo->nField-1)*sizeof(CollSeq*); sz = sizeof(VdbeSorter) + nWorker * sizeof(SortSubtask); From 8c730bc5c5e3cf74086b8947dcf18e476aee0cc0 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 10 Dec 2016 13:12:55 +0000 Subject: [PATCH 1067/1484] Avoid an unnecessary memset() in the sqlite3BtreeInsert() routine. FossilOrigin-Name: 35ecd4ebc55579175f7c934e4eb1edb969008428 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btree.c | 6 +++++- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 3d85299a2f..ac907f8413 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Reorder\sthe\sfields\sin\sthe\sVdbeCursor\sobject\sso\sthat\sthose\sthat\sneed\sto\sbe\nbulk\szeroed\son\sallocation\sare\sgrouped\sat\sthe\sbeginning,\sand\sthe\smemset()\nonly\sruns\sover\sthose\sfields\sthat\sreally\sneed\sit. -D 2016-12-10T12:58:15.294 +C Avoid\san\sunnecessary\smemset()\sin\sthe\ssqlite3BtreeInsert()\sroutine. +D 2016-12-10T13:12:55.805 F Makefile.in 7639c6a09da11a9c7c6f2630fc981ee588d1072d F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -331,7 +331,7 @@ F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792 F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 -F src/btree.c 217c9900de7cf04997aff25faabc366cfe84e8f1 +F src/btree.c 55b5e0e106854ba79aff6b617e60e387c0315214 F src/btree.h 2349a588abcd7e0c04f984e15c5c777b61637583 F src/btreeInt.h 10c4b77c2fb399580babbcc7cf652ac10dba796e F src/build.c 178f16698cbcb43402c343a9413fe22c99ffee21 @@ -1536,7 +1536,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P c9bdf7adb4745cfaf23d9afd496e71fa37793108 -R 15ccb7ac71f3aa4a9f56889c6a3828ff +P 8165f88bb1d40693d67005a8d5dc499085f64b91 +R 8a2cfd12e003eb0df2bfb3a16ae22c0f U drh -Z 0b109188ec32185ef59cc63fa028b152 +Z ffa21cab9c1b5a6f94b1af69e3c75538 diff --git a/manifest.uuid b/manifest.uuid index 3253d01dd9..d5a90d9b7c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8165f88bb1d40693d67005a8d5dc499085f64b91 \ No newline at end of file +35ecd4ebc55579175f7c934e4eb1edb969008428 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index b7e16a85f2..2439edecd0 100644 --- a/src/btree.c +++ b/src/btree.c @@ -8022,10 +8022,14 @@ int sqlite3BtreeInsert( }else if( loc==0 ){ if( pX->nMem ){ UnpackedRecord r; - memset(&r, 0, sizeof(r)); r.pKeyInfo = pCur->pKeyInfo; r.aMem = pX->aMem; r.nField = pX->nMem; + r.default_rc = 0; + r.errCode = 0; + r.r1 = 0; + r.r2 = 0; + r.eqSeen = 0; rc = sqlite3BtreeMovetoUnpacked(pCur, &r, 0, appendBias, &loc); }else{ rc = btreeMoveto(pCur, pX->pKey, pX->nKey, appendBias, &loc); From f0bc50aa3ab9357b3525e073c71c6d9ce2770447 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 12 Dec 2016 00:58:40 +0000 Subject: [PATCH 1068/1484] Change the order of comparison for divider cell overflow in balance non-root to avoid a (harmless) reference to an uninitialized variable. FossilOrigin-Name: f9f2e23bbd68a8994621623446868d666df52eff --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btree.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index ac907f8413..063b4151ee 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\san\sunnecessary\smemset()\sin\sthe\ssqlite3BtreeInsert()\sroutine. -D 2016-12-10T13:12:55.805 +C Change\sthe\sorder\sof\scomparison\sfor\sdivider\scell\soverflow\sin\sbalance\snon-root\nto\savoid\sa\s(harmless)\sreference\sto\san\suninitialized\svariable. +D 2016-12-12T00:58:40.524 F Makefile.in 7639c6a09da11a9c7c6f2630fc981ee588d1072d F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -331,7 +331,7 @@ F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792 F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 -F src/btree.c 55b5e0e106854ba79aff6b617e60e387c0315214 +F src/btree.c 5299b39ca2ae3a177aa4f10c32adecb6ae3dfb2e F src/btree.h 2349a588abcd7e0c04f984e15c5c777b61637583 F src/btreeInt.h 10c4b77c2fb399580babbcc7cf652ac10dba796e F src/build.c 178f16698cbcb43402c343a9413fe22c99ffee21 @@ -1536,7 +1536,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 8165f88bb1d40693d67005a8d5dc499085f64b91 -R 8a2cfd12e003eb0df2bfb3a16ae22c0f +P 35ecd4ebc55579175f7c934e4eb1edb969008428 +R 4eec70a8d01ab30e743f435be503a7d5 U drh -Z ffa21cab9c1b5a6f94b1af69e3c75538 +Z 5a1985fcb882d74ad54a7fce35ec702f diff --git a/manifest.uuid b/manifest.uuid index d5a90d9b7c..614c1437a0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -35ecd4ebc55579175f7c934e4eb1edb969008428 \ No newline at end of file +f9f2e23bbd68a8994621623446868d666df52eff \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 2439edecd0..4598c624dd 100644 --- a/src/btree.c +++ b/src/btree.c @@ -7083,7 +7083,7 @@ static int balance_nonroot( nMaxCells += 1+apOld[i]->nCell+apOld[i]->nOverflow; if( (i--)==0 ) break; - if( i+nxDiv==pParent->aiOvfl[0] && pParent->nOverflow ){ + if( pParent->nOverflow && ALWAYS(i+nxDiv==pParent->aiOvfl[0]) ){ apDiv[i] = pParent->apOvfl[0]; pgno = get4byte(apDiv[i]); szNew[i] = pParent->xCellSize(pParent, apDiv[i]); From 77dc0ed621b8b6cef0ad6a3c666f007c9750545d Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 12 Dec 2016 01:30:01 +0000 Subject: [PATCH 1069/1484] Size and performance optimization in btreeInitPage() in the freeblock validation step. FossilOrigin-Name: 57deb1b412e0c328528f2b4d697e326bfd028dca --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btree.c | 33 +++++++++++++++++++-------------- 3 files changed, 26 insertions(+), 21 deletions(-) diff --git a/manifest b/manifest index 063b4151ee..3452a6cb53 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sthe\sorder\sof\scomparison\sfor\sdivider\scell\soverflow\sin\sbalance\snon-root\nto\savoid\sa\s(harmless)\sreference\sto\san\suninitialized\svariable. -D 2016-12-12T00:58:40.524 +C Size\sand\sperformance\soptimization\sin\sbtreeInitPage()\sin\sthe\sfreeblock\nvalidation\sstep. +D 2016-12-12T01:30:01.538 F Makefile.in 7639c6a09da11a9c7c6f2630fc981ee588d1072d F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -331,7 +331,7 @@ F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792 F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 -F src/btree.c 5299b39ca2ae3a177aa4f10c32adecb6ae3dfb2e +F src/btree.c 383ce69bd36b0f409bfb8bd028786b2f0a4cbb24 F src/btree.h 2349a588abcd7e0c04f984e15c5c777b61637583 F src/btreeInt.h 10c4b77c2fb399580babbcc7cf652ac10dba796e F src/build.c 178f16698cbcb43402c343a9413fe22c99ffee21 @@ -1536,7 +1536,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 35ecd4ebc55579175f7c934e4eb1edb969008428 -R 4eec70a8d01ab30e743f435be503a7d5 +P f9f2e23bbd68a8994621623446868d666df52eff +R d6e7ff9713db8a1c5bca23b53d1ed305 U drh -Z 5a1985fcb882d74ad54a7fce35ec702f +Z a7e99aa30e3b05522d980cd982791774 diff --git a/manifest.uuid b/manifest.uuid index 614c1437a0..31c04846da 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f9f2e23bbd68a8994621623446868d666df52eff \ No newline at end of file +57deb1b412e0c328528f2b4d697e326bfd028dca \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 4598c624dd..a6a8a4782a 100644 --- a/src/btree.c +++ b/src/btree.c @@ -1743,7 +1743,7 @@ static int btreeInitPage(MemPage *pPage){ assert( pPage->aData == sqlite3PagerGetData(pPage->pDbPage) ); if( !pPage->isInit ){ - u16 pc; /* Address of a freeblock within pPage->aData[] */ + u32 pc; /* Address of a freeblock within pPage->aData[] */ u8 hdr; /* Offset to beginning of page header */ u8 *data; /* Equal to pPage->aData */ BtShared *pBt; /* The main btree structure */ @@ -1823,25 +1823,30 @@ static int btreeInitPage(MemPage *pPage){ ** freeblocks. */ pc = get2byte(&data[hdr+1]); nFree = data[hdr+7] + top; /* Init nFree to non-freeblock free space */ - while( pc>0 ){ - u16 next, size; - if( pciCellLast ){ + if( pc>0 ){ + u32 next, size; + if( pc0 && next<=pc+size+3) || pc+size>usableSize ){ - /* Free blocks must be in ascending order. And the last byte of - ** the free-block must lie on the database page. */ - return SQLITE_CORRUPT_BKPT; + while( 1 ){ + if( pc>iCellLast ){ + return SQLITE_CORRUPT_BKPT; /* Freeblock off the end of the page */ + } + next = get2byte(&data[pc]); + size = get2byte(&data[pc+2]); + nFree = nFree + size; + if( next<=pc+size+3 ) break; + pc = next; + } + if( next>0 ){ + return SQLITE_CORRUPT_BKPT; /* Freeblock not in ascending order */ + } + if( pc+size>usableSize ){ + return SQLITE_CORRUPT_BKPT; /* Last freeblock extends past page end */ } - nFree = nFree + size; - pc = next; } /* At this point, nFree contains the sum of the offset to the start From 585a59795c4ac625c42d70a51f064abda1f7a2f5 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 12 Dec 2016 01:53:36 +0000 Subject: [PATCH 1070/1484] Updates to the tokenizer for EBCDIC. No changes for standard builds. FossilOrigin-Name: 4fc6580ffa7232aaf751f38f90c45edc8863abe5 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/tokenize.c | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 3452a6cb53..d6e30ce3d5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Size\sand\sperformance\soptimization\sin\sbtreeInitPage()\sin\sthe\sfreeblock\nvalidation\sstep. -D 2016-12-12T01:30:01.538 +C Updates\sto\sthe\stokenizer\sfor\sEBCDIC.\s\sNo\schanges\sfor\sstandard\sbuilds. +D 2016-12-12T01:53:36.933 F Makefile.in 7639c6a09da11a9c7c6f2630fc981ee588d1072d F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -448,7 +448,7 @@ F src/test_windirent.c 600398db0198ca1c77ca183831bf456746b6f5c4 F src/test_windirent.h 7edc57e2faa727026dbd5d010dd0e2e665d5aa01 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c -F src/tokenize.c 78c8085bc7af1922aa687f0f4bbd716821330de5 +F src/tokenize.c 6eb0752c4fd191f789190c3708ee5b0060fd2829 F src/treeview.c 4e44ade3bfe59d82005039f72e09333ce2b4162c F src/trigger.c 3419bb9862983d84d70735fb4c94b21b934cd0c5 F src/update.c 1da7c462110bffed442a42884cb0d528c1db46d8 @@ -1536,7 +1536,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P f9f2e23bbd68a8994621623446868d666df52eff -R d6e7ff9713db8a1c5bca23b53d1ed305 +P 57deb1b412e0c328528f2b4d697e326bfd028dca +R e7e10da8262dc9afb4f067773f04c52f U drh -Z a7e99aa30e3b05522d980cd982791774 +Z d3ba2fc1770bebb5c69c968ec213ff98 diff --git a/manifest.uuid b/manifest.uuid index 31c04846da..dea4c9d35d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -57deb1b412e0c328528f2b4d697e326bfd028dca \ No newline at end of file +4fc6580ffa7232aaf751f38f90c45edc8863abe5 \ No newline at end of file diff --git a/src/tokenize.c b/src/tokenize.c index 9230da2a0f..0e60c56d66 100644 --- a/src/tokenize.c +++ b/src/tokenize.c @@ -81,13 +81,13 @@ static const unsigned char aiClass[] = { /* 1x */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, /* 2x */ 27, 27, 27, 27, 27, 7, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, /* 3x */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, -/* 4x */ 7, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 12, 17, 20, 10, +/* 4x */ 7, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 26, 12, 17, 20, 10, /* 5x */ 24, 27, 27, 27, 27, 27, 27, 27, 27, 27, 15, 4, 21, 18, 19, 27, -/* 6x */ 11, 16, 27, 27, 27, 27, 27, 27, 27, 27, 27, 23, 22, 1, 13, 7, +/* 6x */ 11, 16, 27, 27, 27, 27, 27, 27, 27, 27, 27, 23, 22, 1, 13, 6, /* 7x */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 8, 5, 5, 5, 8, 14, 8, /* 8x */ 27, 1, 1, 1, 1, 1, 1, 1, 1, 1, 27, 27, 27, 27, 27, 27, /* 9x */ 27, 1, 1, 1, 1, 1, 1, 1, 1, 1, 27, 27, 27, 27, 27, 27, -/* 9x */ 25, 1, 1, 1, 1, 1, 1, 0, 1, 1, 27, 27, 27, 27, 27, 27, +/* Ax */ 27, 25, 1, 1, 1, 1, 1, 0, 1, 1, 27, 27, 27, 27, 27, 27, /* Bx */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 9, 27, 27, 27, 27, 27, /* Cx */ 27, 1, 1, 1, 1, 1, 1, 1, 1, 1, 27, 27, 27, 27, 27, 27, /* Dx */ 27, 1, 1, 1, 1, 1, 1, 1, 1, 1, 27, 27, 27, 27, 27, 27, From 6606586d818a4547cf77358f4ea1b05aca636b16 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 12 Dec 2016 11:05:15 +0000 Subject: [PATCH 1071/1484] Performance optimization in sqlite3PagerWrite(). FossilOrigin-Name: d4dff10a3d4edf8e1cc77c0a4f185d33f2c2e953 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/pager.c | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index d6e30ce3d5..acfaf94242 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Updates\sto\sthe\stokenizer\sfor\sEBCDIC.\s\sNo\schanges\sfor\sstandard\sbuilds. -D 2016-12-12T01:53:36.933 +C Performance\soptimization\sin\ssqlite3PagerWrite(). +D 2016-12-12T11:05:15.832 F Makefile.in 7639c6a09da11a9c7c6f2630fc981ee588d1072d F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -375,7 +375,7 @@ F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586 F src/os_unix.c 30e2c43e4955db990e5b5a81e901f8aa74cc8820 F src/os_win.c cf90abd4e50d9f56d2c20ce8e005aff55d7bd8e9 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a -F src/pager.c 865779c0d33a5804aa6acd547600fca64b511b8a +F src/pager.c b6f38fc2f0da8eafe6ccfbf0b12e228b2ce5fb76 F src/pager.h d1e944291030351f362a0a7da9b5c3e34e603e39 F src/parse.y 29153738a7322054359320eb00b5a4cd44389f20 F src/pcache.c 219fc5238d5c80e2990ab01e1459db3a96866447 @@ -1536,7 +1536,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 57deb1b412e0c328528f2b4d697e326bfd028dca -R e7e10da8262dc9afb4f067773f04c52f +P 4fc6580ffa7232aaf751f38f90c45edc8863abe5 +R bc14df45b85bb125e9e5bbeaef507f4a U drh -Z d3ba2fc1770bebb5c69c968ec213ff98 +Z 4c6df250e0c9c71056406dc87d5d9884 diff --git a/manifest.uuid b/manifest.uuid index dea4c9d35d..cdd0155282 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4fc6580ffa7232aaf751f38f90c45edc8863abe5 \ No newline at end of file +d4dff10a3d4edf8e1cc77c0a4f185d33f2c2e953 \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index aa989f4ef2..9422b800ca 100644 --- a/src/pager.c +++ b/src/pager.c @@ -5961,11 +5961,11 @@ int sqlite3PagerWrite(PgHdr *pPg){ assert( (pPg->flags & PGHDR_MMAP)==0 ); assert( pPager->eState>=PAGER_WRITER_LOCKED ); assert( assert_pager_state(pPager) ); - if( pPager->errCode ){ - return pPager->errCode; - }else if( (pPg->flags & PGHDR_WRITEABLE)!=0 && pPager->dbSize>=pPg->pgno ){ + if( (pPg->flags & PGHDR_WRITEABLE)!=0 && pPager->dbSize>=pPg->pgno ){ if( pPager->nSavepoint ) return subjournalPageIfRequired(pPg); return SQLITE_OK; + }else if( pPager->errCode ){ + return pPager->errCode; }else if( pPager->sectorSize > (u32)pPager->pageSize ){ assert( pPager->tempFile==0 ); return pagerWriteLargeSector(pPg); From 2a70254f7430455ac89abbfc67fe95f2bf3e8941 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 12 Dec 2016 18:12:03 +0000 Subject: [PATCH 1072/1484] Remove unnecessary MemPage initialization resets in the autovacuum ptrmap processing. FossilOrigin-Name: 1b36fbb9f05f3a5844e198b489bff36ef6cd908c --- manifest | 13 ++++++------- manifest.uuid | 2 +- src/btree.c | 10 +--------- 3 files changed, 8 insertions(+), 17 deletions(-) diff --git a/manifest b/manifest index a14a5ca3c0..bbdb5fc0a1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Faster\soperation\sfor\slarge\sin-memory\sdatabases. -D 2016-12-12T16:08:44.373 +C Remove\sunnecessary\sMemPage\sinitialization\sresets\sin\sthe\sautovacuum\sptrmap\nprocessing. +D 2016-12-12T18:12:03.591 F Makefile.in 7639c6a09da11a9c7c6f2630fc981ee588d1072d F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -331,7 +331,7 @@ F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792 F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 -F src/btree.c 383ce69bd36b0f409bfb8bd028786b2f0a4cbb24 +F src/btree.c 0d377e5769657d3ac2a1b6ba081ba77a128610d5 F src/btree.h 2349a588abcd7e0c04f984e15c5c777b61637583 F src/btreeInt.h 10c4b77c2fb399580babbcc7cf652ac10dba796e F src/build.c 178f16698cbcb43402c343a9413fe22c99ffee21 @@ -1536,8 +1536,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d4dff10a3d4edf8e1cc77c0a4f185d33f2c2e953 4fe94b0f1841180dfd8cac33838e335dc6a428bf -R ea4e252aab274ae80300d82ccbdd9ba6 -T +closed 4fe94b0f1841180dfd8cac33838e335dc6a428bf +P 9675518b33e8d40769daefb860dc748113f750b6 +R 5c1b605906a01e86141edb10d66002b4 U drh -Z 222df42015043d416e25238322e825fe +Z 43d64d3ee0d93b0119909f8d75d1fdb9 diff --git a/manifest.uuid b/manifest.uuid index ce37cd3aa6..c16cee434f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9675518b33e8d40769daefb860dc748113f750b6 \ No newline at end of file +1b36fbb9f05f3a5844e198b489bff36ef6cd908c \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index a6a8a4782a..e91fad3b12 100644 --- a/src/btree.c +++ b/src/btree.c @@ -3296,14 +3296,11 @@ static int setChildPtrmaps(MemPage *pPage){ int nCell; /* Number of cells in page pPage */ int rc; /* Return code */ BtShared *pBt = pPage->pBt; - u8 isInitOrig = pPage->isInit; Pgno pgno = pPage->pgno; assert( sqlite3_mutex_held(pPage->pBt->mutex) ); rc = btreeInitPage(pPage); - if( rc!=SQLITE_OK ){ - goto set_child_ptrmaps_out; - } + if( rc!=SQLITE_OK ) return rc; nCell = pPage->nCell; for(i=0; iisInit = isInitOrig; return rc; } @@ -3351,7 +3346,6 @@ static int modifyPagePointer(MemPage *pPage, Pgno iFrom, Pgno iTo, u8 eType){ } put4byte(pPage->aData, iTo); }else{ - u8 isInitOrig = pPage->isInit; int i; int nCell; int rc; @@ -3387,8 +3381,6 @@ static int modifyPagePointer(MemPage *pPage, Pgno iFrom, Pgno iTo, u8 eType){ } put4byte(&pPage->aData[pPage->hdrOffset+8], iTo); } - - pPage->isInit = isInitOrig; } return SQLITE_OK; } From 26f419800a4e9d91813ab49c053f83db452bf8dc Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 12 Dec 2016 23:24:08 +0000 Subject: [PATCH 1073/1484] Add the --mmap option to the speedtest1 program and to the speed-check.sh script that is frequently used to run speedtest1. FossilOrigin-Name: 1a636d5e0eec0a4d968519d1dfd35a983e512c78 --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/speedtest1.c | 10 ++++++++++ tool/speed-check.sh | 4 ++++ 4 files changed, 22 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index bbdb5fc0a1..4a681af0fe 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sunnecessary\sMemPage\sinitialization\sresets\sin\sthe\sautovacuum\sptrmap\nprocessing. -D 2016-12-12T18:12:03.591 +C Add\sthe\s--mmap\soption\sto\sthe\sspeedtest1\sprogram\sand\sto\sthe\sspeed-check.sh\nscript\sthat\sis\sfrequently\sused\sto\srun\sspeedtest1. +D 2016-12-12T23:24:08.261 F Makefile.in 7639c6a09da11a9c7c6f2630fc981ee588d1072d F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -1122,7 +1122,7 @@ F test/speed3.test 694affeb9100526007436334cf7d08f3d74b85ef F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715 F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b -F test/speedtest1.c dae4b22c620743e2767d0ec9fc11f2d1d6383ff1 +F test/speedtest1.c 0c92fd0db4cb778e3b6968db0ea859e28f077823 F test/spellfix.test f9c1f431e2c096c8775fec032952320c0e4700db F test/spellfix2.test dfc8f519a3fc204cb2dfa8b4f29821ae90f6f8c3 F test/spellfix3.test 0f9efaaa502a0e0a09848028518a6fb096c8ad33 @@ -1496,7 +1496,7 @@ F tool/showstat4.c b14159aa062f661b394ba37b6b7b94bfb8012ab9 F tool/showwal.c ec79959834f7b21f1e0a2aa52bb7c056d2203977 F tool/soak1.tcl 8d407956e1a45b485a8e072470a3e629a27037fe F tool/spaceanal.tcl ab7d9bf68062907282a64b3e12ccbfad47193c5a -F tool/speed-check.sh b7922d000d66339d5242e7ba47ba6e3f1bc9a538 +F tool/speed-check.sh e6ca0695b047af64201ebe0ef452e423f55d78b1 F tool/speedtest.tcl 06c76698485ccf597b9e7dbb1ac70706eb873355 F tool/speedtest16.c ecb6542862151c3e6509bbc00509b234562ae81e F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff @@ -1536,7 +1536,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 9675518b33e8d40769daefb860dc748113f750b6 -R 5c1b605906a01e86141edb10d66002b4 +P 1b36fbb9f05f3a5844e198b489bff36ef6cd908c +R 54a6c1795de20385060d3d26915836b2 U drh -Z 43d64d3ee0d93b0119909f8d75d1fdb9 +Z 47f248a7928b3840fe2e23a9066d59e9 diff --git a/manifest.uuid b/manifest.uuid index c16cee434f..1f2e52b085 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1b36fbb9f05f3a5844e198b489bff36ef6cd908c \ No newline at end of file +1a636d5e0eec0a4d968519d1dfd35a983e512c78 \ No newline at end of file diff --git a/test/speedtest1.c b/test/speedtest1.c index 1c3e3c27f8..d568aada0a 100644 --- a/test/speedtest1.c +++ b/test/speedtest1.c @@ -15,6 +15,7 @@ static const char zHelp[] = " --journal M Set the journal_mode to M\n" " --key KEY Set the encryption key to KEY\n" " --lookaside N SZ Configure lookaside for N slots of SZ bytes each\n" + " --mmap SZ MMAP the first SZ bytes of the database file\n" " --multithread Set multithreaded mode\n" " --nomemstat Disable memory statistics\n" " --nosync Set PRAGMA synchronous=OFF\n" @@ -1381,6 +1382,7 @@ int main(int argc, char **argv){ int nScratch = 0, szScratch=0;/* --scratch configuration */ int showStats = 0; /* True for --stats */ int nThread = 0; /* --threads value */ + int mmapSize = 0; /* How big of a memory map to use */ const char *zTSet = "main"; /* Which --testset torun */ int doTrace = 0; /* True for --trace */ const char *zEncoding = 0; /* --utf16be or --utf16le */ @@ -1443,6 +1445,11 @@ int main(int argc, char **argv){ }else if( strcmp(z,"nomemstat")==0 ){ sqlite3_config(SQLITE_CONFIG_MEMSTATUS, 0); #endif +#if SQLITE_VERSION_NUMBER>=3007017 + }else if( strcmp(z, "mmap")==0 ){ + if( i>=argc-1 ) fatal_error("missing argument on %s\n", argv[i]); + mmapSize = integerValue(argv[++i]); + #endif }else if( strcmp(z,"nosync")==0 ){ noSync = 1; }else if( strcmp(z,"notnull")==0 ){ @@ -1573,6 +1580,9 @@ int main(int argc, char **argv){ #ifndef SQLITE_OMIT_DEPRECATED if( doTrace ) sqlite3_trace(g.db, traceCallback, 0); #endif + if( mmapSize>0 ){ + speedtest1_exec("PRAGMA mmap_size=%d", mmapSize); + } speedtest1_exec("PRAGMA threads=%d", nThread); if( zKey ){ speedtest1_exec("PRAGMA key('%s')", zKey); diff --git a/tool/speed-check.sh b/tool/speed-check.sh index 536903abf6..d6e7eb6d25 100644 --- a/tool/speed-check.sh +++ b/tool/speed-check.sh @@ -90,6 +90,10 @@ while test "$1" != ""; do shift; SPEEDTEST_OPTS="$SPEEDTEST_OPTS --repeat $1" ;; + --mmap) + shift; + SPEEDTEST_OPTS="$SPEEDTEST_OPTS --mmap $1" + ;; *) CC_OPTS="$CC_OPTS $1" ;; From 12e6f682798853ab44a08ee4fd203d11d9899b47 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 13 Dec 2016 14:32:47 +0000 Subject: [PATCH 1074/1484] Make the sqlite3PagerGet() interface into a virtual method, with different implementations based on the current state of the pager. This gives a small performance increase by avoiding unnecessary branches inside the various methods. FossilOrigin-Name: df5bb90d208e0633056389e97696d260e3830e8d --- manifest | 15 ++-- manifest.uuid | 2 +- src/pager.c | 220 ++++++++++++++++++++++++++++++++------------------ 3 files changed, 150 insertions(+), 87 deletions(-) diff --git a/manifest b/manifest index 4a681af0fe..8e294defe8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\s--mmap\soption\sto\sthe\sspeedtest1\sprogram\sand\sto\sthe\sspeed-check.sh\nscript\sthat\sis\sfrequently\sused\sto\srun\sspeedtest1. -D 2016-12-12T23:24:08.261 +C Make\sthe\ssqlite3PagerGet()\sinterface\sinto\sa\svirtual\smethod,\swith\sdifferent\nimplementations\sbased\son\sthe\scurrent\sstate\sof\sthe\spager.\s\sThis\sgives\sa\ssmall\nperformance\sincrease\sby\savoiding\sunnecessary\sbranches\sinside\sthe\svarious\nmethods. +D 2016-12-13T14:32:47.273 F Makefile.in 7639c6a09da11a9c7c6f2630fc981ee588d1072d F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -375,7 +375,7 @@ F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586 F src/os_unix.c 30e2c43e4955db990e5b5a81e901f8aa74cc8820 F src/os_win.c cf90abd4e50d9f56d2c20ce8e005aff55d7bd8e9 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a -F src/pager.c eaf8590131ab651420e86e89c3fd12d729f55ad3 +F src/pager.c e99f7edfab2441f55fc1a4f4dd05f3bf0f1a82cd F src/pager.h d1e944291030351f362a0a7da9b5c3e34e603e39 F src/parse.y 29153738a7322054359320eb00b5a4cd44389f20 F src/pcache.c 219fc5238d5c80e2990ab01e1459db3a96866447 @@ -1536,7 +1536,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 1b36fbb9f05f3a5844e198b489bff36ef6cd908c -R 54a6c1795de20385060d3d26915836b2 +P 1a636d5e0eec0a4d968519d1dfd35a983e512c78 +R d5446ab8495308acac3b07699664fa42 +T *branch * pager-get-method +T *sym-pager-get-method * +T -sym-trunk * U drh -Z 47f248a7928b3840fe2e23a9066d59e9 +Z 3a0d20f1bb36125dcd9d753c0baba230 diff --git a/manifest.uuid b/manifest.uuid index 1f2e52b085..758ca3ddc7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1a636d5e0eec0a4d968519d1dfd35a983e512c78 \ No newline at end of file +df5bb90d208e0633056389e97696d260e3830e8d \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index 02e9aac790..d8a2062282 100644 --- a/src/pager.c +++ b/src/pager.c @@ -693,6 +693,7 @@ struct Pager { int nRead; /* Database pages read */ #endif void (*xReiniter)(DbPage*); /* Call this routine when reloading pages */ + int (*xGet)(Pager*,Pgno,DbPage**,int); /* Routine to fetch a patch */ #ifdef SQLITE_HAS_CODEC void *(*xCodec)(void*,void*,Pgno,int); /* Routine for en/decoding data */ void (*xCodecSizeChng)(void*,int,int); /* Notify of page size changes */ @@ -1019,6 +1020,29 @@ static char *print_pager_state(Pager *p){ } #endif +/* Forward references to the various page getters */ +static int getPageNormal(Pager*,Pgno,DbPage**,int); +static int getPageMMap(Pager*,Pgno,DbPage**,int); +static int getPageError(Pager*,Pgno,DbPage**,int); + +/* +** Set the Pager.xGet method for the appropriate routine used to fetch +** content from the pager. +*/ +static void setGetterMethod(Pager *pPager){ + if( pPager->errCode ){ + pPager->xGet = getPageError; + }else if( USEFETCH(pPager) +#ifdef SQLITE_HAS_CODEC + && pPager->xCodec==0 +#endif + ){ + pPager->xGet = getPageMMap; + }else{ + pPager->xGet = getPageNormal; + } +} + /* ** Return true if it is necessary to write page *pPg into the sub-journal. ** A page needs to be written into the sub-journal if there exists one @@ -1833,6 +1857,7 @@ static void pager_unlock(Pager *pPager){ } if( USEFETCH(pPager) ) sqlite3OsUnfetch(pPager->fd, 0, 0); pPager->errCode = SQLITE_OK; + setGetterMethod(pPager); } pPager->journalOff = 0; @@ -1870,6 +1895,7 @@ static int pager_error(Pager *pPager, int rc){ if( rc2==SQLITE_FULL || rc2==SQLITE_IOERR ){ pPager->errCode = rc; pPager->eState = PAGER_ERROR; + setGetterMethod(pPager); } return rc; } @@ -3437,6 +3463,7 @@ static void pagerFixMaplimit(Pager *pPager){ sqlite3_int64 sz; sz = pPager->szMmap; pPager->bUseFetch = (sz>0); + setGetterMethod(pPager); sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_MMAP_SIZE, &sz); } #endif @@ -4854,6 +4881,7 @@ act_like_temp_file: /* pPager->xBusyHandler = 0; */ /* pPager->pBusyHandlerArg = 0; */ pPager->xReiniter = xReinit; + setGetterMethod(pPager); /* memset(pPager->aHash, 0, sizeof(pPager->aHash)); */ /* pPager->szMmap = SQLITE_DEFAULT_MMAP_SIZE // will be set by btree.c */ @@ -5316,7 +5344,7 @@ static void pagerUnlockIfUnused(Pager *pPager){ ** Since Lookup() never goes to disk, it never has to deal with locks ** or journal files. */ -int sqlite3PagerGet( +static int getPageNormal( Pager *pPager, /* The pager open on the database file */ Pgno pgno, /* Page number to fetch */ DbPage **ppPage, /* Write a pointer to the page here */ @@ -5326,92 +5354,28 @@ int sqlite3PagerGet( PgHdr *pPg = 0; u32 iFrame = 0; /* Frame to read from WAL file */ const int noContent = (flags & PAGER_GET_NOCONTENT); + sqlite3_pcache_page *pBase; - /* It is acceptable to use a read-only (mmap) page for any page except - ** page 1 if there is no write-transaction open or the ACQUIRE_READONLY - ** flag was specified by the caller. And so long as the db is not a - ** temporary or in-memory database. */ - const int bMmapOk = (pgno>1 && USEFETCH(pPager) - && (pPager->eState==PAGER_READER || (flags & PAGER_GET_READONLY)) -#ifdef SQLITE_HAS_CODEC - && pPager->xCodec==0 -#endif - ); - - /* Optimization note: Adding the "pgno<=1" term before "pgno==0" here - ** allows the compiler optimizer to reuse the results of the "pgno>1" - ** test in the previous statement, and avoid testing pgno==0 in the - ** common case where pgno is large. */ - if( pgno<=1 && pgno==0 ){ + if( pgno==0 ){ return SQLITE_CORRUPT_BKPT; } + assert( pPager->errCode==SQLITE_OK ); assert( pPager->eState>=PAGER_READER ); assert( assert_pager_state(pPager) ); - assert( noContent==0 || bMmapOk==0 ); - assert( pPager->hasHeldSharedLock==1 ); - /* If the pager is in the error state, return an error immediately. - ** Otherwise, request the page from the PCache layer. */ - if( pPager->errCode!=SQLITE_OK ){ - rc = pPager->errCode; - }else{ - if( bMmapOk && pagerUseWal(pPager) ){ - rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iFrame); - if( rc!=SQLITE_OK ) goto pager_acquire_err; - } - if( bMmapOk && iFrame==0 ){ - void *pData = 0; - - rc = sqlite3OsFetch(pPager->fd, - (i64)(pgno-1) * pPager->pageSize, pPager->pageSize, &pData - ); - - if( rc==SQLITE_OK && pData ){ - if( pPager->eState>PAGER_READER || pPager->tempFile ){ - pPg = sqlite3PagerLookup(pPager, pgno); - } - if( pPg==0 ){ - rc = pagerAcquireMapPage(pPager, pgno, pData, &pPg); - }else{ - sqlite3OsUnfetch(pPager->fd, (i64)(pgno-1)*pPager->pageSize, pData); - } - if( pPg ){ - assert( rc==SQLITE_OK ); - *ppPage = pPg; - return SQLITE_OK; - } - } - if( rc!=SQLITE_OK ){ - goto pager_acquire_err; - } - } - - { - sqlite3_pcache_page *pBase; - pBase = sqlite3PcacheFetch(pPager->pPCache, pgno, 3); - if( pBase==0 ){ - rc = sqlite3PcacheFetchStress(pPager->pPCache, pgno, &pBase); - if( rc!=SQLITE_OK ) goto pager_acquire_err; - if( pBase==0 ){ - pPg = *ppPage = 0; - rc = SQLITE_NOMEM_BKPT; - goto pager_acquire_err; - } - } - pPg = *ppPage = sqlite3PcacheFetchFinish(pPager->pPCache, pgno, pBase); - assert( pPg!=0 ); + pBase = sqlite3PcacheFetch(pPager->pPCache, pgno, 3); + if( pBase==0 ){ + rc = sqlite3PcacheFetchStress(pPager->pPCache, pgno, &pBase); + if( rc!=SQLITE_OK ) goto pager_acquire_err; + if( pBase==0 ){ + pPg = *ppPage = 0; + rc = SQLITE_NOMEM_BKPT; + goto pager_acquire_err; } } - - if( rc!=SQLITE_OK ){ - /* Either the call to sqlite3PcacheFetch() returned an error or the - ** pager was already in the error-state when this function was called. - ** Set pPg to 0 and jump to the exception handler. */ - pPg = 0; - goto pager_acquire_err; - } + pPg = *ppPage = sqlite3PcacheFetchFinish(pPager->pPCache, pgno, pBase); assert( pPg==(*ppPage) ); assert( pPg->pgno==pgno ); assert( pPg->pPager==pPager || pPg->pPager==0 ); @@ -5461,7 +5425,7 @@ int sqlite3PagerGet( memset(pPg->pData, 0, pPager->pageSize); IOTRACE(("ZERO %p %d\n", pPager, pgno)); }else{ - if( pagerUseWal(pPager) && bMmapOk==0 ){ + if( pagerUseWal(pPager) /*&& bMmapOk==0*/ ){ rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iFrame); if( rc!=SQLITE_OK ) goto pager_acquire_err; } @@ -5474,7 +5438,6 @@ int sqlite3PagerGet( } pager_set_pagehash(pPg); } - return SQLITE_OK; pager_acquire_err: @@ -5483,11 +5446,105 @@ pager_acquire_err: sqlite3PcacheDrop(pPg); } pagerUnlockIfUnused(pPager); - *ppPage = 0; return rc; } +/* The page getter for when memory-mapped I/O is enabled */ +static int getPageMMap( + Pager *pPager, /* The pager open on the database file */ + Pgno pgno, /* Page number to fetch */ + DbPage **ppPage, /* Write a pointer to the page here */ + int flags /* PAGER_GET_XXX flags */ +){ + int rc = SQLITE_OK; + PgHdr *pPg = 0; + u32 iFrame = 0; /* Frame to read from WAL file */ + + assert( USEFETCH(pPager) ); +#ifdef SQLITE_HAS_CODEC + assert( pPager->xCodec==0 ); +#endif + + /* It is acceptable to use a read-only (mmap) page for any page except + ** page 1 if there is no write-transaction open or the ACQUIRE_READONLY + ** flag was specified by the caller. And so long as the db is not a + ** temporary or in-memory database. */ + const int bMmapOk = (pgno>1 + && (pPager->eState==PAGER_READER || (flags & PAGER_GET_READONLY)) + ); + + /* Optimization note: Adding the "pgno<=1" term before "pgno==0" here + ** allows the compiler optimizer to reuse the results of the "pgno>1" + ** test in the previous statement, and avoid testing pgno==0 in the + ** common case where pgno is large. */ + if( pgno<=1 && pgno==0 ){ + return SQLITE_CORRUPT_BKPT; + } + assert( pPager->eState>=PAGER_READER ); + assert( assert_pager_state(pPager) ); + assert( pPager->hasHeldSharedLock==1 ); + assert( pPager->errCode==SQLITE_OK ); + + if( bMmapOk && pagerUseWal(pPager) ){ + rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iFrame); + if( rc!=SQLITE_OK ){ + *ppPage = 0; + return rc; + } + } + if( bMmapOk && iFrame==0 ){ + void *pData = 0; + rc = sqlite3OsFetch(pPager->fd, + (i64)(pgno-1) * pPager->pageSize, pPager->pageSize, &pData + ); + if( rc==SQLITE_OK && pData ){ + if( pPager->eState>PAGER_READER || pPager->tempFile ){ + pPg = sqlite3PagerLookup(pPager, pgno); + } + if( pPg==0 ){ + rc = pagerAcquireMapPage(pPager, pgno, pData, &pPg); + }else{ + sqlite3OsUnfetch(pPager->fd, (i64)(pgno-1)*pPager->pageSize, pData); + } + if( pPg ){ + assert( rc==SQLITE_OK ); + *ppPage = pPg; + return SQLITE_OK; + } + } + if( rc!=SQLITE_OK ){ + *ppPage = 0; + return rc; + } + } + return getPageNormal(pPager, pgno, ppPage, flags); +} + +/* The page getter method for when the pager is an error state */ +static int getPageError( + Pager *pPager, /* The pager open on the database file */ + Pgno pgno, /* Page number to fetch */ + DbPage **ppPage, /* Write a pointer to the page here */ + int flags /* PAGER_GET_XXX flags */ +){ + assert( pPager->errCode!=SQLITE_OK ); + *ppPage = 0; + return pPager->errCode; +} + + +/* Dispatch all page fetch requests to the appropriate getter method. +*/ +int sqlite3PagerGet( + Pager *pPager, /* The pager open on the database file */ + Pgno pgno, /* Page number to fetch */ + DbPage **ppPage, /* Write a pointer to the page here */ + int flags /* PAGER_GET_XXX flags */ +){ + return pPager->xGet(pPager, pgno, ppPage, flags); +} + /* ** Acquire a page if it is already in the in-memory cache. Do ** not read the page from disk. Return a pointer to the page, @@ -6460,6 +6517,7 @@ int sqlite3PagerRollback(Pager *pPager){ */ pPager->errCode = SQLITE_ABORT; pPager->eState = PAGER_ERROR; + setGetterMethod(pPager); return rc; } }else{ @@ -6721,6 +6779,7 @@ int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint){ ){ pPager->errCode = SQLITE_ABORT; pPager->eState = PAGER_ERROR; + setGettterMethod(pPager); } #endif } @@ -6793,6 +6852,7 @@ void sqlite3PagerSetCodec( pPager->xCodecSizeChng = xCodecSizeChng; pPager->xCodecFree = xCodecFree; pPager->pCodec = pCodec; + setGetterMethod(pPager); pagerReportSize(pPager); } void *sqlite3PagerGetCodec(Pager *pPager){ From d5df3ff2cc30331722760059a9236c3a9dc5b3ce Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 13 Dec 2016 15:53:22 +0000 Subject: [PATCH 1075/1484] Further refinements to the virtual method implementation of sqlite3PagerGet(). FossilOrigin-Name: 67df44464847b43f8c0b186157e31cc66c1e5796 --- manifest | 15 ++++++--------- manifest.uuid | 2 +- src/pager.c | 44 +++++++++++++++++++++++++++++--------------- 3 files changed, 36 insertions(+), 25 deletions(-) diff --git a/manifest b/manifest index 8e294defe8..a88cc6c349 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\sthe\ssqlite3PagerGet()\sinterface\sinto\sa\svirtual\smethod,\swith\sdifferent\nimplementations\sbased\son\sthe\scurrent\sstate\sof\sthe\spager.\s\sThis\sgives\sa\ssmall\nperformance\sincrease\sby\savoiding\sunnecessary\sbranches\sinside\sthe\svarious\nmethods. -D 2016-12-13T14:32:47.273 +C Further\srefinements\sto\sthe\svirtual\smethod\simplementation\sof\s\nsqlite3PagerGet(). +D 2016-12-13T15:53:22.192 F Makefile.in 7639c6a09da11a9c7c6f2630fc981ee588d1072d F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -375,7 +375,7 @@ F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586 F src/os_unix.c 30e2c43e4955db990e5b5a81e901f8aa74cc8820 F src/os_win.c cf90abd4e50d9f56d2c20ce8e005aff55d7bd8e9 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a -F src/pager.c e99f7edfab2441f55fc1a4f4dd05f3bf0f1a82cd +F src/pager.c 642b1968fdaa6219aa562ae17b9a3745dfca10f5 F src/pager.h d1e944291030351f362a0a7da9b5c3e34e603e39 F src/parse.y 29153738a7322054359320eb00b5a4cd44389f20 F src/pcache.c 219fc5238d5c80e2990ab01e1459db3a96866447 @@ -1536,10 +1536,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 1a636d5e0eec0a4d968519d1dfd35a983e512c78 -R d5446ab8495308acac3b07699664fa42 -T *branch * pager-get-method -T *sym-pager-get-method * -T -sym-trunk * +P df5bb90d208e0633056389e97696d260e3830e8d +R f50bcbf9b53ee7a4a76924f315bdb191 U drh -Z 3a0d20f1bb36125dcd9d753c0baba230 +Z 01ed48a40bff392ec009867b80e6ecce diff --git a/manifest.uuid b/manifest.uuid index 758ca3ddc7..be9ae7f0eb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -df5bb90d208e0633056389e97696d260e3830e8d \ No newline at end of file +67df44464847b43f8c0b186157e31cc66c1e5796 \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index d8a2062282..4cda7c92ce 100644 --- a/src/pager.c +++ b/src/pager.c @@ -1022,8 +1022,10 @@ static char *print_pager_state(Pager *p){ /* Forward references to the various page getters */ static int getPageNormal(Pager*,Pgno,DbPage**,int); -static int getPageMMap(Pager*,Pgno,DbPage**,int); static int getPageError(Pager*,Pgno,DbPage**,int); +#if SQLITE_MAX_MMAP_SIZE>0 +static int getPageMMap(Pager*,Pgno,DbPage**,int); +#endif /* ** Set the Pager.xGet method for the appropriate routine used to fetch @@ -1032,12 +1034,14 @@ static int getPageError(Pager*,Pgno,DbPage**,int); static void setGetterMethod(Pager *pPager){ if( pPager->errCode ){ pPager->xGet = getPageError; +#if SQLITE_MAX_MMAP_SIZE>0 }else if( USEFETCH(pPager) #ifdef SQLITE_HAS_CODEC && pPager->xCodec==0 #endif ){ pPager->xGet = getPageMMap; +#endif /* SQLITE_MAX_MMAP_SIZE>0 */ }else{ pPager->xGet = getPageNormal; } @@ -5295,10 +5299,17 @@ static void pagerUnlockIfUnused(Pager *pPager){ } /* -** Acquire a reference to page number pgno in pager pPager (a page -** reference has type DbPage*). If the requested reference is +** The page getter methods each try to acquire a reference to a +** page with page number pgno. If the requested reference is ** successfully obtained, it is copied to *ppPage and SQLITE_OK returned. ** +** There are different implementations of the getter method depending +** on the current state of the pager. +** +** getPageNormal() -- The normal getter +** getPageError() -- Used if the pager is in an error state +** getPageMmap() -- Used if memory-mapped I/O is enabled +** ** If the requested page is already in the cache, it is returned. ** Otherwise, a new page object is allocated and populated with data ** read from the database file. In some cases, the pcache module may @@ -5310,14 +5321,14 @@ static void pagerUnlockIfUnused(Pager *pPager){ ** already in the cache when this function is called, then the extra ** data is left as it was when the page object was last used. ** -** If the database image is smaller than the requested page or if a -** non-zero value is passed as the noContent parameter and the +** If the database image is smaller than the requested page or if +** the flags parameter contains the PAGER_GET_NOCONTENT bit and the ** requested page is not already stored in the cache, then no ** actual disk read occurs. In this case the memory image of the ** page is initialized to all zeros. ** -** If noContent is true, it means that we do not care about the contents -** of the page. This occurs in two scenarios: +** If PAGER_GET_NOCONTENT is true, it means that we do not care about +** the contents of the page. This occurs in two scenarios: ** ** a) When reading a free-list leaf page from the database, and ** @@ -5325,8 +5336,8 @@ static void pagerUnlockIfUnused(Pager *pPager){ ** a new page into the cache to be filled with the data read ** from the savepoint journal. ** -** If noContent is true, then the data returned is zeroed instead of -** being read from the database. Additionally, the bits corresponding +** If PAGER_GET_NOCONTENT is true, then the data returned is zeroed instead +** of being read from the database. Additionally, the bits corresponding ** to pgno in Pager.pInJournal (bitvec of pages already written to the ** journal file) and the PagerSavepoint.pInSavepoint bitvecs of any open ** savepoints are set. This means if the page is made writable at any @@ -5351,9 +5362,8 @@ static int getPageNormal( int flags /* PAGER_GET_XXX flags */ ){ int rc = SQLITE_OK; - PgHdr *pPg = 0; - u32 iFrame = 0; /* Frame to read from WAL file */ - const int noContent = (flags & PAGER_GET_NOCONTENT); + PgHdr *pPg; + u8 noContent; /* True if PAGER_GET_NOCONTENT is set */ sqlite3_pcache_page *pBase; if( pgno==0 ){ @@ -5367,10 +5377,10 @@ static int getPageNormal( pBase = sqlite3PcacheFetch(pPager->pPCache, pgno, 3); if( pBase==0 ){ + pPg = 0; rc = sqlite3PcacheFetchStress(pPager->pPCache, pgno, &pBase); if( rc!=SQLITE_OK ) goto pager_acquire_err; if( pBase==0 ){ - pPg = *ppPage = 0; rc = SQLITE_NOMEM_BKPT; goto pager_acquire_err; } @@ -5380,7 +5390,7 @@ static int getPageNormal( assert( pPg->pgno==pgno ); assert( pPg->pPager==pPager || pPg->pPager==0 ); - if( pPg->pPager && !noContent ){ + if( pPg->pPager ){ /* In this case the pcache already contains an initialized copy of ** the page. Return without further ado. */ assert( pgno<=PAGER_MAX_PGNO && pgno!=PAGER_MJ_PGNO(pPager) ); @@ -5401,6 +5411,7 @@ static int getPageNormal( } assert( !isOpen(pPager->fd) || !MEMDB ); + noContent = (flags & PAGER_GET_NOCONTENT)!=0; if( !isOpen(pPager->fd) || pPager->dbSizepPager->mxPgno ){ rc = SQLITE_FULL; @@ -5425,7 +5436,8 @@ static int getPageNormal( memset(pPg->pData, 0, pPager->pageSize); IOTRACE(("ZERO %p %d\n", pPager, pgno)); }else{ - if( pagerUseWal(pPager) /*&& bMmapOk==0*/ ){ + u32 iFrame = 0; /* Frame to read from WAL file */ + if( pagerUseWal(pPager) ){ rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iFrame); if( rc!=SQLITE_OK ) goto pager_acquire_err; } @@ -5450,6 +5462,7 @@ pager_acquire_err: return rc; } +#if SQLITE_MAX_MMAP_SIZE>0 /* The page getter for when memory-mapped I/O is enabled */ static int getPageMMap( Pager *pPager, /* The pager open on the database file */ @@ -5520,6 +5533,7 @@ static int getPageMMap( } return getPageNormal(pPager, pgno, ppPage, flags); } +#endif /* SQLITE_MAX_MMAP_SIZE>0 */ /* The page getter method for when the pager is an error state */ static int getPageError( From 68a494c06f2239e0028656376af482ddc705d100 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 13 Dec 2016 16:57:49 +0000 Subject: [PATCH 1076/1484] Fix a problem causing SQLite to return false "foreign key violation" errors when there is a partial (i.e. WHERE constrained) UNIQUE index on the parent key columns. This bug did not cause SQLite to allow illegal data to be inserted into the database, only to reject legal operations. FossilOrigin-Name: 850877d1ea43104cc215353414b870c340acced2 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/fkey.c | 2 +- test/fkey1.test | 22 ++++++++++++++++++++++ 4 files changed, 32 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 4a681af0fe..acf36f3b93 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\s--mmap\soption\sto\sthe\sspeedtest1\sprogram\sand\sto\sthe\sspeed-check.sh\nscript\sthat\sis\sfrequently\sused\sto\srun\sspeedtest1. -D 2016-12-12T23:24:08.261 +C Fix\sa\sproblem\scausing\sSQLite\sto\sreturn\sfalse\s"foreign\skey\sviolation"\serrors\nwhen\sthere\sis\sa\spartial\s(i.e.\sWHERE\sconstrained)\sUNIQUE\sindex\son\sthe\sparent\nkey\scolumns.\sThis\sbug\sdid\snot\scause\sSQLite\sto\sallow\sillegal\sdata\sto\sbe\ninserted\sinto\sthe\sdatabase,\sonly\sto\sreject\slegal\soperations. +D 2016-12-13T16:57:49.299 F Makefile.in 7639c6a09da11a9c7c6f2630fc981ee588d1072d F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -343,7 +343,7 @@ F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c 42768e673861dffec92664b2036da6be51720e49 F src/expr.c 84a5e590184ad7ccae22e7ad484d6394dec46f16 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 -F src/fkey.c 4017dc6d8bf894c4818ffbaf392e53c7c68dd761 +F src/fkey.c 4f527ddd05250b3f750f17be76ca65ec76b4e6cb F src/func.c 43916c1d8e6da5d107d91d2b212577d4f69a876a F src/global.c 235021a21ee2cb52b304589f8f9e85a36bbe24fa F src/hash.c 63d0ee752a3b92d4695b2b1f5259c4621b2cfebd @@ -684,7 +684,7 @@ F test/extraquick.test cb254400bd42bfb777ff675356aabf3287978f79 F test/fallocate.test 3e979af17dfa7e5e9dda5eba1a696c04fa9d47f7 F test/filectrl.test 6e871c2d35dead1d9a88e176e8d2ca094fec6bb3 F test/filefmt.test e4edbdc637ca9576ccf4337a3cce627d9df7a56c -F test/fkey1.test 13e3d48236a2b9f5c5ebd232eef9b3ab682a8a2c +F test/fkey1.test ba64806ff9a04eecab2679caad377ae99a5e94e4 F test/fkey2.test f3d27ecba480a348c328965d154214719bb158a9 F test/fkey3.test 76d475c80b84ee7a5d062e56ccb6ea68882e2b49 F test/fkey4.test 86446017011273aad8f9a99c1a65019e7bd9ca9d @@ -1536,7 +1536,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 1b36fbb9f05f3a5844e198b489bff36ef6cd908c -R 54a6c1795de20385060d3d26915836b2 -U drh -Z 47f248a7928b3840fe2e23a9066d59e9 +P 1a636d5e0eec0a4d968519d1dfd35a983e512c78 +R 5a6882353526d0c1387fb8d5e18f94f5 +U dan +Z 8572282c856eadf1ae5a34d00073243b diff --git a/manifest.uuid b/manifest.uuid index 1f2e52b085..5e21fc4816 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1a636d5e0eec0a4d968519d1dfd35a983e512c78 \ No newline at end of file +850877d1ea43104cc215353414b870c340acced2 \ No newline at end of file diff --git a/src/fkey.c b/src/fkey.c index 38b961be65..eaf09ac1ad 100644 --- a/src/fkey.c +++ b/src/fkey.c @@ -225,7 +225,7 @@ int sqlite3FkLocateIndex( } for(pIdx=pParent->pIndex; pIdx; pIdx=pIdx->pNext){ - if( pIdx->nKeyCol==nCol && IsUniqueIndex(pIdx) ){ + if( pIdx->nKeyCol==nCol && IsUniqueIndex(pIdx) && pIdx->pPartIdxWhere==0 ){ /* pIdx is a UNIQUE index (or a PRIMARY KEY) and has the right number ** of columns. If each indexed column corresponds to a foreign key ** column of pFKey, then this index is a winner. */ diff --git a/test/fkey1.test b/test/fkey1.test index e10781ac52..d9b038a022 100644 --- a/test/fkey1.test +++ b/test/fkey1.test @@ -15,6 +15,7 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl +set testprefix fkey1 ifcapable {!foreignkey} { finish_test @@ -185,4 +186,25 @@ do_catchsql_test fkey1-5.4 { INSERT OR REPLACE INTO Foo(Id, ParentId, C1) VALUES (2, 3, 'A-2-3'); } {1 {FOREIGN KEY constraint failed}} +#------------------------------------------------------------------------- +# Check that foreign key processing is not fooled by partial indexes +# on the parent table. +# +do_execsql_test 6.0 { + CREATE TABLE p1(x, y); + CREATE UNIQUE INDEX p1x ON p1(x) WHERE y<2; + INSERT INTO p1 VALUES(1, 1); + CREATE TABLE c1(a REFERENCES p1(x)); +} + +do_catchsql_test 6.1 { + INSERT INTO c1 VALUES(1); +} {1 {foreign key mismatch - "c1" referencing "p1"}} + +do_execsql_test 6.2 { + CREATE UNIQUE INDEX p1x2 ON p1(x); + INSERT INTO c1 VALUES(1); +} {} + + finish_test From cbed604f52972491e0b8b32936550c82021d8090 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 13 Dec 2016 18:34:01 +0000 Subject: [PATCH 1077/1484] In the pager, avoid checking for the illegal page number 0 except when creating a new page. FossilOrigin-Name: dee20ba982125ea98c280ad1571789af0f393903 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/pager.c | 20 +++++++++----------- src/pcache.c | 3 +-- 4 files changed, 18 insertions(+), 21 deletions(-) diff --git a/manifest b/manifest index a88cc6c349..a735100eb0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Further\srefinements\sto\sthe\svirtual\smethod\simplementation\sof\s\nsqlite3PagerGet(). -D 2016-12-13T15:53:22.192 +C In\sthe\spager,\savoid\schecking\sfor\sthe\sillegal\spage\snumber\s0\sexcept\swhen\screating\na\snew\spage. +D 2016-12-13T18:34:01.957 F Makefile.in 7639c6a09da11a9c7c6f2630fc981ee588d1072d F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -375,10 +375,10 @@ F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586 F src/os_unix.c 30e2c43e4955db990e5b5a81e901f8aa74cc8820 F src/os_win.c cf90abd4e50d9f56d2c20ce8e005aff55d7bd8e9 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a -F src/pager.c 642b1968fdaa6219aa562ae17b9a3745dfca10f5 +F src/pager.c 38b3a02f5f5e49224a006d17c842c106a93cb5b9 F src/pager.h d1e944291030351f362a0a7da9b5c3e34e603e39 F src/parse.y 29153738a7322054359320eb00b5a4cd44389f20 -F src/pcache.c 219fc5238d5c80e2990ab01e1459db3a96866447 +F src/pcache.c 51070ec9b8251bbf9c6ea3d35fd96a458752929e F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 F src/pcache1.c e3967219b2a92b9edcb9324a4ba75009090d3953 F src/pragma.c d932ba278654617cdd281f88a790a3185fca7c44 @@ -1536,7 +1536,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P df5bb90d208e0633056389e97696d260e3830e8d -R f50bcbf9b53ee7a4a76924f315bdb191 +P 67df44464847b43f8c0b186157e31cc66c1e5796 +R 96cb62ad3fe18d08872a93c1ec7681b1 U drh -Z 01ed48a40bff392ec009867b80e6ecce +Z 5d3a5e7b85c439c40dd9c8767b987c29 diff --git a/manifest.uuid b/manifest.uuid index be9ae7f0eb..e5fa81fb64 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -67df44464847b43f8c0b186157e31cc66c1e5796 \ No newline at end of file +dee20ba982125ea98c280ad1571789af0f393903 \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index 4cda7c92ce..d40c1f4117 100644 --- a/src/pager.c +++ b/src/pager.c @@ -5366,15 +5366,11 @@ static int getPageNormal( u8 noContent; /* True if PAGER_GET_NOCONTENT is set */ sqlite3_pcache_page *pBase; - if( pgno==0 ){ - return SQLITE_CORRUPT_BKPT; - } assert( pPager->errCode==SQLITE_OK ); assert( pPager->eState>=PAGER_READER ); assert( assert_pager_state(pPager) ); assert( pPager->hasHeldSharedLock==1 ); - pBase = sqlite3PcacheFetch(pPager->pPCache, pgno, 3); if( pBase==0 ){ pPg = 0; @@ -5399,17 +5395,19 @@ static int getPageNormal( }else{ /* The pager cache has created a new page. Its content needs to - ** be initialized. */ - - pPg->pPager = pPager; - - /* The maximum page number is 2^31. Return SQLITE_CORRUPT if a page - ** number greater than this, or the unused locking-page, is requested. */ - if( pgno>PAGER_MAX_PGNO || pgno==PAGER_MJ_PGNO(pPager) ){ + ** be initialized. But first some error checks: + ** + ** (1) Minimum page number is 1 + ** (2) The maximum page number is 2^31 + ** (3) Never try to fetch the locking page + */ + if( pgno==0 || pgno>PAGER_MAX_PGNO || pgno==PAGER_MJ_PGNO(pPager) ){ rc = SQLITE_CORRUPT_BKPT; goto pager_acquire_err; } + pPg->pPager = pPager; + assert( !isOpen(pPager->fd) || !MEMDB ); noContent = (flags & PAGER_GET_NOCONTENT)!=0; if( !isOpen(pPager->fd) || pPager->dbSizepgno>0 ); /* Page number is 1 or more */ + assert( pPg->pgno>0 || pPg->pPager==0 ); /* Page number is 1 or more */ pCache = pPg->pCache; assert( pCache!=0 ); /* Every page has an associated PCache */ if( pPg->flags & PGHDR_CLEAN ){ @@ -372,7 +372,6 @@ sqlite3_pcache_page *sqlite3PcacheFetch( assert( pCache!=0 ); assert( pCache->pCache!=0 ); assert( createFlag==3 || createFlag==0 ); - assert( pgno>0 ); assert( pCache->eCreate==((pCache->bPurgeable && pCache->pDirty) ? 1 : 2) ); /* eCreate defines what to do if the page does not exist. From 380c08eaadc26dc5e879266e3d536967297d2251 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 13 Dec 2016 20:30:29 +0000 Subject: [PATCH 1078/1484] Fix harmless compiler warnings. FossilOrigin-Name: ed2c9f3738c96d8e3dbece7ccb721cb1a8ae8fac --- manifest | 15 +++++++-------- manifest.uuid | 2 +- src/btree.c | 4 ++-- src/pager.c | 12 +++++++----- 4 files changed, 17 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index 6c25d39d50..254f17d042 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Convert\ssqlite3PagerGet()\sinto\sa\spointer-dispatched\svirtual\smethod.\s\sThis\nmakes\sit\sabout\s25%\sfaster. -D 2016-12-13T18:47:54.625 +C Fix\sharmless\scompiler\swarnings. +D 2016-12-13T20:30:29.436 F Makefile.in 7639c6a09da11a9c7c6f2630fc981ee588d1072d F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -331,7 +331,7 @@ F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792 F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 -F src/btree.c 0d377e5769657d3ac2a1b6ba081ba77a128610d5 +F src/btree.c b2055dff0b94e03eaad48a760984a2d8e39244e6 F src/btree.h 2349a588abcd7e0c04f984e15c5c777b61637583 F src/btreeInt.h 10c4b77c2fb399580babbcc7cf652ac10dba796e F src/build.c 178f16698cbcb43402c343a9413fe22c99ffee21 @@ -375,7 +375,7 @@ F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586 F src/os_unix.c 30e2c43e4955db990e5b5a81e901f8aa74cc8820 F src/os_win.c cf90abd4e50d9f56d2c20ce8e005aff55d7bd8e9 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a -F src/pager.c dbcac003871bf8a9bfb69d6cb66bbb85b528aaf6 +F src/pager.c c3ba8e69388d974017004aa3fd3511e5bbadbba0 F src/pager.h d1e944291030351f362a0a7da9b5c3e34e603e39 F src/parse.y 29153738a7322054359320eb00b5a4cd44389f20 F src/pcache.c 51070ec9b8251bbf9c6ea3d35fd96a458752929e @@ -1536,8 +1536,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 850877d1ea43104cc215353414b870c340acced2 dee20ba982125ea98c280ad1571789af0f393903 -R 1925a57b32b9d19fb42c95ae0d5863ee -T +closed dee20ba982125ea98c280ad1571789af0f393903 +P 7f88bb44129a0cd36e27e00dc7c37e87cf3c90f7 +R f2e66ee6668f0716a35acfaa4809f04b U drh -Z ca81384c708270e6307c733a622217dc +Z 404271946c196a116af17aa555379b02 diff --git a/manifest.uuid b/manifest.uuid index ad8184c8ed..99dfe7c001 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7f88bb44129a0cd36e27e00dc7c37e87cf3c90f7 \ No newline at end of file +ed2c9f3738c96d8e3dbece7ccb721cb1a8ae8fac \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index e91fad3b12..0cd1a28778 100644 --- a/src/btree.c +++ b/src/btree.c @@ -1743,7 +1743,7 @@ static int btreeInitPage(MemPage *pPage){ assert( pPage->aData == sqlite3PagerGetData(pPage->pDbPage) ); if( !pPage->isInit ){ - u32 pc; /* Address of a freeblock within pPage->aData[] */ + int pc; /* Address of a freeblock within pPage->aData[] */ u8 hdr; /* Offset to beginning of page header */ u8 *data; /* Equal to pPage->aData */ BtShared *pBt; /* The main btree structure */ @@ -1844,7 +1844,7 @@ static int btreeInitPage(MemPage *pPage){ if( next>0 ){ return SQLITE_CORRUPT_BKPT; /* Freeblock not in ascending order */ } - if( pc+size>usableSize ){ + if( pc+size>(unsigned int)usableSize ){ return SQLITE_CORRUPT_BKPT; /* Last freeblock extends past page end */ } } diff --git a/src/pager.c b/src/pager.c index 7bafc1c09b..cd2ded4e3f 100644 --- a/src/pager.c +++ b/src/pager.c @@ -5472,11 +5472,6 @@ static int getPageMMap( PgHdr *pPg = 0; u32 iFrame = 0; /* Frame to read from WAL file */ - assert( USEFETCH(pPager) ); -#ifdef SQLITE_HAS_CODEC - assert( pPager->xCodec==0 ); -#endif - /* It is acceptable to use a read-only (mmap) page for any page except ** page 1 if there is no write-transaction open or the ACQUIRE_READONLY ** flag was specified by the caller. And so long as the db is not a @@ -5485,6 +5480,11 @@ static int getPageMMap( && (pPager->eState==PAGER_READER || (flags & PAGER_GET_READONLY)) ); + assert( USEFETCH(pPager) ); +#ifdef SQLITE_HAS_CODEC + assert( pPager->xCodec==0 ); +#endif + /* Optimization note: Adding the "pgno<=1" term before "pgno==0" here ** allows the compiler optimizer to reuse the results of the "pgno>1" ** test in the previous statement, and avoid testing pgno==0 in the @@ -5540,6 +5540,8 @@ static int getPageError( DbPage **ppPage, /* Write a pointer to the page here */ int flags /* PAGER_GET_XXX flags */ ){ + UNUSED_PARAMETER(pgno); + UNUSED_PARAMETER(flags); assert( pPager->errCode!=SQLITE_OK ); *ppPage = 0; return pPager->errCode; From 79f20e96dc72f054f29155c7212563271da439e0 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 13 Dec 2016 23:22:39 +0000 Subject: [PATCH 1079/1484] In the command-line shell, in the output of the ".dump", ".schema", and ".fullschema" commands, convert CREATE TABLE statements that appear to come from shadow tables into CREATE TABLE IF NOT EXISTS statements. FossilOrigin-Name: c7021960f5c070fb5c9db9e41b4000d3dc065f42 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/shell.c | 29 ++++++++++++++++++++++++----- 3 files changed, 31 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 254f17d042..e64156d9ec 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\scompiler\swarnings. -D 2016-12-13T20:30:29.436 +C In\sthe\scommand-line\sshell,\sin\sthe\soutput\sof\sthe\s".dump",\s".schema",\sand\n".fullschema"\scommands,\sconvert\sCREATE\sTABLE\sstatements\sthat\sappear\sto\scome\nfrom\sshadow\stables\sinto\sCREATE\sTABLE\sIF\sNOT\sEXISTS\sstatements. +D 2016-12-13T23:22:39.714 F Makefile.in 7639c6a09da11a9c7c6f2630fc981ee588d1072d F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -389,7 +389,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c bb070cf5f23611c44ab7e4788803684e385fc3fb F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c b4bd43e1233c87e8a7cf66150421997b0396417e -F src/shell.c 9597efa50a4a27bc6440ad99cbcd7fff6957f514 +F src/shell.c f1c7fde7a83421e6ed620df41d200674a2327e65 F src/sqlite.h.in e8e2d108d82647f0a812fdb74accf91c1ec08ddc F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae @@ -1536,7 +1536,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 7f88bb44129a0cd36e27e00dc7c37e87cf3c90f7 -R f2e66ee6668f0716a35acfaa4809f04b +P ed2c9f3738c96d8e3dbece7ccb721cb1a8ae8fac +R 064921518747d6f1187652c989ffbe09 U drh -Z 404271946c196a116af17aa555379b02 +Z 06643ca029a5c5cdb028f91458ca4784 diff --git a/manifest.uuid b/manifest.uuid index 99dfe7c001..136940b880 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ed2c9f3738c96d8e3dbece7ccb721cb1a8ae8fac \ No newline at end of file +c7021960f5c070fb5c9db9e41b4000d3dc065f42 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 756c389761..d0b743cb5b 100644 --- a/src/shell.c +++ b/src/shell.c @@ -946,6 +946,25 @@ static int shellAuth( } #endif +/* +** Print a schema statement. Part of MODE_Semi and MODE_Pretty output. +** +** This routine converts some CREATE TABLE statements for shadow tables +** in FTS3/4/5 into CREATE TABLE IF NOT EXISTS statements. +*/ +static void printSchemaLine(FILE *out, const char *z, const char *zTail){ + if( sqlite3_strglob("CREATE TABLE ['\"]*", z)==0 ){ + utf8_printf(out, "CREATE TABLE IF NOT EXISTS %s%s", z+13, zTail); + }else{ + utf8_printf(out, "%s%s", z, zTail); + } +} +static void printSchemaLineN(FILE *out, char *z, int n, const char *zTail){ + char c = z[n]; + z[n] = 0; + printSchemaLine(out, z, zTail); + z[n] = c; +} /* ** This is the callback routine that the shell @@ -1064,7 +1083,7 @@ static int shell_callback( break; } case MODE_Semi: { /* .schema and .fullschema output */ - utf8_printf(p->out, "%s;\n", azArg[0]); + printSchemaLine(p->out, azArg[0], ";\n"); break; } case MODE_Pretty: { /* .schema and .fullschema with --indent */ @@ -1108,14 +1127,14 @@ static int shell_callback( }else if( c==')' ){ nParen--; if( nLine>0 && nParen==0 && j>0 ){ - utf8_printf(p->out, "%.*s\n", j, z); + printSchemaLineN(p->out, z, j, "\n"); j = 0; } } z[j++] = c; if( nParen==1 && (c=='(' || c==',' || c=='\n') ){ if( c=='\n' ) j--; - utf8_printf(p->out, "%.*s\n ", j, z); + printSchemaLineN(p->out, z, j, "\n "); j = 0; nLine++; while( IsSpace(z[i+1]) ){ i++; } @@ -1123,7 +1142,7 @@ static int shell_callback( } z[j] = 0; } - utf8_printf(p->out, "%s;\n", z); + printSchemaLine(p->out, z, ";\n"); sqlite3_free(z); break; } @@ -2046,7 +2065,7 @@ static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){ sqlite3_free(zIns); return 0; }else{ - utf8_printf(p->out, "%s;\n", zSql); + printSchemaLine(p->out, zSql, ";\n"); } if( strcmp(zType, "table")==0 ){ From 8a123d60a85992b329db24791c4f1b865279ff3c Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 14 Dec 2016 10:30:12 +0000 Subject: [PATCH 1080/1484] Fix the optimization that prevents writing freelist pages to the journal. FossilOrigin-Name: 6aa9b26544cbd0b41115c5f127dcf9a286d17e2b --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/pager.c | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index e64156d9ec..2934b2c6ef 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\sthe\scommand-line\sshell,\sin\sthe\soutput\sof\sthe\s".dump",\s".schema",\sand\n".fullschema"\scommands,\sconvert\sCREATE\sTABLE\sstatements\sthat\sappear\sto\scome\nfrom\sshadow\stables\sinto\sCREATE\sTABLE\sIF\sNOT\sEXISTS\sstatements. -D 2016-12-13T23:22:39.714 +C Fix\sthe\soptimization\sthat\sprevents\swriting\sfreelist\spages\sto\sthe\sjournal. +D 2016-12-14T10:30:12.405 F Makefile.in 7639c6a09da11a9c7c6f2630fc981ee588d1072d F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -375,7 +375,7 @@ F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586 F src/os_unix.c 30e2c43e4955db990e5b5a81e901f8aa74cc8820 F src/os_win.c cf90abd4e50d9f56d2c20ce8e005aff55d7bd8e9 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a -F src/pager.c c3ba8e69388d974017004aa3fd3511e5bbadbba0 +F src/pager.c 81fe2bb847df537694ec39e28e8b3dc221c64a7d F src/pager.h d1e944291030351f362a0a7da9b5c3e34e603e39 F src/parse.y 29153738a7322054359320eb00b5a4cd44389f20 F src/pcache.c 51070ec9b8251bbf9c6ea3d35fd96a458752929e @@ -1536,7 +1536,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ed2c9f3738c96d8e3dbece7ccb721cb1a8ae8fac -R 064921518747d6f1187652c989ffbe09 +P c7021960f5c070fb5c9db9e41b4000d3dc065f42 +R 29a5ab173feb9dcb847f7e97678fc3f9 U drh -Z 06643ca029a5c5cdb028f91458ca4784 +Z a1e79a7a1334afe1605804fa02a1d4f0 diff --git a/manifest.uuid b/manifest.uuid index 136940b880..e16b607041 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c7021960f5c070fb5c9db9e41b4000d3dc065f42 \ No newline at end of file +6aa9b26544cbd0b41115c5f127dcf9a286d17e2b \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index cd2ded4e3f..5bcb9247e8 100644 --- a/src/pager.c +++ b/src/pager.c @@ -5386,7 +5386,8 @@ static int getPageNormal( assert( pPg->pgno==pgno ); assert( pPg->pPager==pPager || pPg->pPager==0 ); - if( pPg->pPager ){ + noContent = (flags & PAGER_GET_NOCONTENT)!=0; + if( pPg->pPager && !noContent ){ /* In this case the pcache already contains an initialized copy of ** the page. Return without further ado. */ assert( pgno<=PAGER_MAX_PGNO && pgno!=PAGER_MJ_PGNO(pPager) ); @@ -5409,7 +5410,6 @@ static int getPageNormal( pPg->pPager = pPager; assert( !isOpen(pPager->fd) || !MEMDB ); - noContent = (flags & PAGER_GET_NOCONTENT)!=0; if( !isOpen(pPager->fd) || pPager->dbSizepPager->mxPgno ){ rc = SQLITE_FULL; From ac178b3d7f7db2dfdf0bd693cb36497fc6d57dd9 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 14 Dec 2016 11:14:13 +0000 Subject: [PATCH 1081/1484] Three times faster sqlite3SrcListAppend() in the common case by avoiding the call to sqlite3SrcListEnlarge() for the first allocation. FossilOrigin-Name: 0ea2762f1d8f6a93ae2ee3b7b835927a474c6f66 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/build.c | 7 +++++-- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 2934b2c6ef..26d50e31a5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\soptimization\sthat\sprevents\swriting\sfreelist\spages\sto\sthe\sjournal. -D 2016-12-14T10:30:12.405 +C Three\stimes\sfaster\ssqlite3SrcListAppend()\sin\sthe\scommon\scase\sby\savoiding\sthe\ncall\sto\ssqlite3SrcListEnlarge()\sfor\sthe\sfirst\sallocation. +D 2016-12-14T11:14:13.907 F Makefile.in 7639c6a09da11a9c7c6f2630fc981ee588d1072d F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -334,7 +334,7 @@ F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 F src/btree.c b2055dff0b94e03eaad48a760984a2d8e39244e6 F src/btree.h 2349a588abcd7e0c04f984e15c5c777b61637583 F src/btreeInt.h 10c4b77c2fb399580babbcc7cf652ac10dba796e -F src/build.c 178f16698cbcb43402c343a9413fe22c99ffee21 +F src/build.c 66bab5ee3998b1ebbea66ce0de60a82dcf497747 F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 9f2296a4e5d26ebf0e0d95a0af4628f1ea694e7a @@ -1536,7 +1536,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P c7021960f5c070fb5c9db9e41b4000d3dc065f42 -R 29a5ab173feb9dcb847f7e97678fc3f9 +P 6aa9b26544cbd0b41115c5f127dcf9a286d17e2b +R 5c6f1d55f58a01899a13212bdf50e07f U drh -Z a1e79a7a1334afe1605804fa02a1d4f0 +Z b26cd3596202cf83d05f18857a98dc5b diff --git a/manifest.uuid b/manifest.uuid index e16b607041..1d21ba4de4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6aa9b26544cbd0b41115c5f127dcf9a286d17e2b \ No newline at end of file +0ea2762f1d8f6a93ae2ee3b7b835927a474c6f66 \ No newline at end of file diff --git a/src/build.c b/src/build.c index 0fe2032689..d613e3a9e4 100644 --- a/src/build.c +++ b/src/build.c @@ -3736,9 +3736,12 @@ SrcList *sqlite3SrcListAppend( pList = sqlite3DbMallocRawNN(db, sizeof(SrcList) ); if( pList==0 ) return 0; pList->nAlloc = 1; - pList->nSrc = 0; + pList->nSrc = 1; + memset(&pList->a[0], 0, sizeof(pList->a[0])); + pList->a[0].iCursor = -1; + }else{ + pList = sqlite3SrcListEnlarge(db, pList, 1, pList->nSrc); } - pList = sqlite3SrcListEnlarge(db, pList, 1, pList->nSrc); if( db->mallocFailed ){ sqlite3SrcListDelete(db, pList); return 0; From c06e54345c45697f0f3744ac23eb29ede102378c Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 14 Dec 2016 11:23:51 +0000 Subject: [PATCH 1082/1484] Adjust the unix makefiles so that "make test" runs fuzzcheck prior to even attempting to build the other test programs. FossilOrigin-Name: bb48f7a55945da4cee369bae0809037900fcaac7 --- Makefile.in | 7 +++++-- main.mk | 9 ++++++--- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 19 insertions(+), 13 deletions(-) diff --git a/Makefile.in b/Makefile.in index 4218ab9914..4da74d4f07 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1109,6 +1109,10 @@ fastfuzztest: fuzzcheck$(TEXE) $(FUZZDATA) valgrindfuzz: fuzzcheck$(TEXT) $(FUZZDATA) valgrind ./fuzzcheck$(TEXE) --cell-size-check --limit-mem 10M --timeout 600 $(FUZZDATA) +# The veryquick.test TCL tests. +# +tcltest: ./testfixture$(TEXE) + ./testfixture$(TEXE) $(TOP)/test/veryquick.test $(TESTOPTS) # Minimal testing that runs in less than 3 minutes # @@ -1118,8 +1122,7 @@ quicktest: ./testfixture$(TEXE) # This is the common case. Run many tests that do not take too long, # including fuzzcheck, sqlite3_analyzer, and sqldiff tests. # -test: $(TESTPROGS) sourcetest fastfuzztest - ./testfixture$(TEXE) $(TOP)/test/veryquick.test $(TESTOPTS) +test: fastfuzztest $(TESTPROGS) tcltest sourcetest # Run a test using valgrind. This can take a really long time # because valgrind is so much slower than a native machine. diff --git a/main.mk b/main.mk index 5709afc8d1..91487b72b3 100644 --- a/main.mk +++ b/main.mk @@ -798,6 +798,11 @@ fastfuzztest: fuzzcheck$(EXE) $(FUZZDATA) valgrindfuzz: fuzzcheck$(EXE) $(FUZZDATA) valgrind ./fuzzcheck$(EXE) --cell-size-check --limit-mem 10M --timeout 600 $(FUZZDATA) +# The veryquick.test TCL tests. +# +tcltest: ./testfixture$(EXE) + ./testfixture$(EXE) $(TOP)/test/veryquick.test $(TESTOPTS) + # A very quick test using only testfixture and omitting all the slower # tests. Designed to run in under 3 minutes on a workstation. # @@ -806,9 +811,7 @@ quicktest: ./testfixture$(EXE) # The default test case. Runs most of the faster standard TCL tests, # and fuzz tests, and sqlite3_analyzer and sqldiff tests. -# -test: $(TESTPROGS) sourcetest fastfuzztest - ./testfixture$(EXE) $(TOP)/test/veryquick.test $(TESTOPTS) +test: fastfuzztest sourcetest $(TESTPROGS) tcltest # Run a test using valgrind. This can take a really long time # because valgrind is so much slower than a native machine. diff --git a/manifest b/manifest index 26d50e31a5..c5473dbdf2 100644 --- a/manifest +++ b/manifest @@ -1,6 +1,6 @@ -C Three\stimes\sfaster\ssqlite3SrcListAppend()\sin\sthe\scommon\scase\sby\savoiding\sthe\ncall\sto\ssqlite3SrcListEnlarge()\sfor\sthe\sfirst\sallocation. -D 2016-12-14T11:14:13.907 -F Makefile.in 7639c6a09da11a9c7c6f2630fc981ee588d1072d +C Adjust\sthe\sunix\smakefiles\sso\sthat\s"make\stest"\sruns\sfuzzcheck\sprior\sto\seven\nattempting\sto\sbuild\sthe\sother\stest\sprograms. +D 2016-12-14T11:23:51.380 +F Makefile.in 609c5f7a19d5b5d2dff61f8a4740581fee34b8af F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7 @@ -312,7 +312,7 @@ F ext/userauth/userauth.c 5fa3bdb492f481bbc1709fc83c91ebd13460c69e F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60 -F main.mk da18a283b8fc3c6892e9205e6228f3ae60d8cd8d +F main.mk bd1149fdb5543e432a8530a0ea7642613a655bc1 F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 @@ -1536,7 +1536,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 6aa9b26544cbd0b41115c5f127dcf9a286d17e2b -R 5c6f1d55f58a01899a13212bdf50e07f +P 0ea2762f1d8f6a93ae2ee3b7b835927a474c6f66 +R 780cd0abdea39fa1a5d5daabb688bd72 U drh -Z b26cd3596202cf83d05f18857a98dc5b +Z 2e2657a5376509e8032ac3542578485e diff --git a/manifest.uuid b/manifest.uuid index 1d21ba4de4..a695a69c1f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0ea2762f1d8f6a93ae2ee3b7b835927a474c6f66 \ No newline at end of file +bb48f7a55945da4cee369bae0809037900fcaac7 \ No newline at end of file From 5ed7de09b0cb767011a317aa7c0a109b8feba4f7 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 14 Dec 2016 11:39:52 +0000 Subject: [PATCH 1083/1484] Fix the configure makefile to align it with the manual makefile. Unsaved changes from the previous check-in. FossilOrigin-Name: 00a184b65f73f361e1728fea06529f746fab66b5 --- Makefile.in | 2 +- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Makefile.in b/Makefile.in index 4da74d4f07..76233c4a7b 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1122,7 +1122,7 @@ quicktest: ./testfixture$(TEXE) # This is the common case. Run many tests that do not take too long, # including fuzzcheck, sqlite3_analyzer, and sqldiff tests. # -test: fastfuzztest $(TESTPROGS) tcltest sourcetest +test: fastfuzztest sourcetest $(TESTPROGS) tcltest # Run a test using valgrind. This can take a really long time # because valgrind is so much slower than a native machine. diff --git a/manifest b/manifest index c5473dbdf2..d4fde75110 100644 --- a/manifest +++ b/manifest @@ -1,6 +1,6 @@ -C Adjust\sthe\sunix\smakefiles\sso\sthat\s"make\stest"\sruns\sfuzzcheck\sprior\sto\seven\nattempting\sto\sbuild\sthe\sother\stest\sprograms. -D 2016-12-14T11:23:51.380 -F Makefile.in 609c5f7a19d5b5d2dff61f8a4740581fee34b8af +C Fix\sthe\sconfigure\smakefile\sto\salign\sit\swith\sthe\smanual\smakefile.\s\sUnsaved\nchanges\sfrom\sthe\sprevious\scheck-in. +D 2016-12-14T11:39:52.040 +F Makefile.in c194b58fe00c370a48ac6ae6945e92a7781db1c8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7 @@ -1536,7 +1536,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 0ea2762f1d8f6a93ae2ee3b7b835927a474c6f66 -R 780cd0abdea39fa1a5d5daabb688bd72 +P bb48f7a55945da4cee369bae0809037900fcaac7 +R 9545652591400e7cde029c09f3430ecd U drh -Z 2e2657a5376509e8032ac3542578485e +Z b9f69002fb2c61130ee41e4f20258d96 diff --git a/manifest.uuid b/manifest.uuid index a695a69c1f..721a34a85c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bb48f7a55945da4cee369bae0809037900fcaac7 \ No newline at end of file +00a184b65f73f361e1728fea06529f746fab66b5 \ No newline at end of file From d07df8e76a174278418850627f7665745089902a Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 14 Dec 2016 13:54:25 +0000 Subject: [PATCH 1084/1484] Increase the size of the reference count on Table objects to 32 bits. FossilOrigin-Name: d08b72c38ff6fae6ddf7dc84a54f6d7189876289 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/sqliteInt.h | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index d4fde75110..8af8165181 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\sconfigure\smakefile\sto\salign\sit\swith\sthe\smanual\smakefile.\s\sUnsaved\nchanges\sfrom\sthe\sprevious\scheck-in. -D 2016-12-14T11:39:52.040 +C Increase\sthe\ssize\sof\sthe\sreference\scount\son\sTable\sobjects\sto\s32\sbits. +D 2016-12-14T13:54:25.287 F Makefile.in c194b58fe00c370a48ac6ae6945e92a7781db1c8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -393,7 +393,7 @@ F src/shell.c f1c7fde7a83421e6ed620df41d200674a2327e65 F src/sqlite.h.in e8e2d108d82647f0a812fdb74accf91c1ec08ddc F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae -F src/sqliteInt.h 9d0834b980e2d156109d73c307b803d29d2686e8 +F src/sqliteInt.h 69345b355da43b89216e9cea619eb24ddd418896 F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 @@ -1536,7 +1536,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P bb48f7a55945da4cee369bae0809037900fcaac7 -R 9545652591400e7cde029c09f3430ecd +P 00a184b65f73f361e1728fea06529f746fab66b5 +R bb3d64fa96b2e381730c4f4039396de5 U drh -Z b9f69002fb2c61130ee41e4f20258d96 +Z 286d124da8f3f0702924a8d69dad9e38 diff --git a/manifest.uuid b/manifest.uuid index 721a34a85c..647231f77a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -00a184b65f73f361e1728fea06529f746fab66b5 \ No newline at end of file +d08b72c38ff6fae6ddf7dc84a54f6d7189876289 \ No newline at end of file diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 46d5a169b5..8707858fd6 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1801,9 +1801,9 @@ struct Table { ExprList *pCheck; /* All CHECK constraints */ /* ... also used as column name list in a VIEW */ int tnum; /* Root BTree page for this table */ + u32 nRef; /* Number of pointers to this Table */ i16 iPKey; /* If not negative, use aCol[iPKey] as the rowid */ i16 nCol; /* Number of columns in this table */ - u16 nRef; /* Number of pointers to this Table */ LogEst nRowLogEst; /* Estimated rows in table - from sqlite_stat1 table */ LogEst szTabRow; /* Estimated size of each table row in bytes */ #ifdef SQLITE_ENABLE_COSTMULT From 79df77821aa8ed2ff41defe354eaf5a245d1a34f Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 14 Dec 2016 14:07:35 +0000 Subject: [PATCH 1085/1484] Refactor the Table.nRef field as Table.nTabRef for easier grepping. FossilOrigin-Name: 9cae4c2e300e20304ced0dc8c1415c4922185928 --- manifest | 26 +++++++++++++------------- manifest.uuid | 2 +- src/alter.c | 4 ++-- src/build.c | 4 ++-- src/delete.c | 2 +- src/expr.c | 2 +- src/fkey.c | 2 +- src/select.c | 20 ++++++++++---------- src/sqliteInt.h | 2 +- src/vtab.c | 2 +- 10 files changed, 33 insertions(+), 33 deletions(-) diff --git a/manifest b/manifest index 8af8165181..82049f338e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Increase\sthe\ssize\sof\sthe\sreference\scount\son\sTable\sobjects\sto\s32\sbits. -D 2016-12-14T13:54:25.287 +C Refactor\sthe\sTable.nRef\sfield\sas\sTable.nTabRef\sfor\seasier\sgrepping. +D 2016-12-14T14:07:35.372 F Makefile.in c194b58fe00c370a48ac6ae6945e92a7781db1c8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -324,7 +324,7 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a -F src/alter.c 299117695b1f21ac62dfc5b608588810ba22ed0d +F src/alter.c 0f83ee1d5963e85f8f3316cb11a90227807a74c8 F src/analyze.c 8b62b2cf4da85451534ac0af82cafc418d837f68 F src/attach.c f6725410c184a80d8141b294fdf98a854c8a52b5 F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792 @@ -334,16 +334,16 @@ F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 F src/btree.c b2055dff0b94e03eaad48a760984a2d8e39244e6 F src/btree.h 2349a588abcd7e0c04f984e15c5c777b61637583 F src/btreeInt.h 10c4b77c2fb399580babbcc7cf652ac10dba796e -F src/build.c 66bab5ee3998b1ebbea66ce0de60a82dcf497747 +F src/build.c e2b32766847eb16d4314c99067571ae08b888dfe F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 9f2296a4e5d26ebf0e0d95a0af4628f1ea694e7a F src/date.c b48378aeac68fa20c811404955a9b62108df47d8 F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d -F src/delete.c 42768e673861dffec92664b2036da6be51720e49 -F src/expr.c 84a5e590184ad7ccae22e7ad484d6394dec46f16 +F src/delete.c c8bc10d145c9666a34ae906250326fdaa8d58fa5 +F src/expr.c c7c11fbe8bd4d27d04f1370efcce5a05b4fca229 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 -F src/fkey.c 4f527ddd05250b3f750f17be76ca65ec76b4e6cb +F src/fkey.c 2e9aabe1aee76273aff8a84ee92c464e095400ae F src/func.c 43916c1d8e6da5d107d91d2b212577d4f69a876a F src/global.c 235021a21ee2cb52b304589f8f9e85a36bbe24fa F src/hash.c 63d0ee752a3b92d4695b2b1f5259c4621b2cfebd @@ -388,12 +388,12 @@ F src/printf.c f94da4935d1dd25420ac50c6745db1deb35e07c1 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c bb070cf5f23611c44ab7e4788803684e385fc3fb F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac -F src/select.c b4bd43e1233c87e8a7cf66150421997b0396417e +F src/select.c 204491a5e09a66380a067943d8651af8bda1d358 F src/shell.c f1c7fde7a83421e6ed620df41d200674a2327e65 F src/sqlite.h.in e8e2d108d82647f0a812fdb74accf91c1ec08ddc F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae -F src/sqliteInt.h 69345b355da43b89216e9cea619eb24ddd418896 +F src/sqliteInt.h 657a892d885253768c82f1e04e8053468b13cb6a F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 @@ -464,7 +464,7 @@ F src/vdbeblob.c f4f98ea672b242f807c08c92c7faaa79e5091b65 F src/vdbemem.c d3fd85b7b7ef3eb75de29c6d7e1d10d3ca78b4fd F src/vdbesort.c bb34eed4fb52e11ac037dccea4ee3190594c7f9e F src/vdbetrace.c 41963d5376f0349842b5fc4aaaaacd7d9cdc0834 -F src/vtab.c e02cacb5c7ae742631edeb9ae9f53d399f093fd8 +F src/vtab.c 2d5db3fd68c41c5a7476e43e79eb54181fa01713 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 40c543f0a2195d1b0dc88ef12142bea690009344 F src/wal.h 06b2a0b599cc0f53ea97f497cf8c6b758c999f71 @@ -1536,7 +1536,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 00a184b65f73f361e1728fea06529f746fab66b5 -R bb3d64fa96b2e381730c4f4039396de5 +P d08b72c38ff6fae6ddf7dc84a54f6d7189876289 +R ee18812138ebcbd59cf246eeb625fa00 U drh -Z 286d124da8f3f0702924a8d69dad9e38 +Z c1d49b9032916157524a152005703654 diff --git a/manifest.uuid b/manifest.uuid index 647231f77a..1ac27241a3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d08b72c38ff6fae6ddf7dc84a54f6d7189876289 \ No newline at end of file +9cae4c2e300e20304ced0dc8c1415c4922185928 \ No newline at end of file diff --git a/src/alter.c b/src/alter.c index 2c86a8bac2..b16f098e1d 100644 --- a/src/alter.c +++ b/src/alter.c @@ -773,7 +773,7 @@ void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){ pNew = (Table*)sqlite3DbMallocZero(db, sizeof(Table)); if( !pNew ) goto exit_begin_add_column; pParse->pNewTable = pNew; - pNew->nRef = 1; + pNew->nTabRef = 1; pNew->nCol = pTab->nCol; assert( pNew->nCol>0 ); nAlloc = (((pNew->nCol-1)/8)*8)+8; @@ -793,7 +793,7 @@ void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){ } pNew->pSchema = db->aDb[iDb].pSchema; pNew->addColOffset = pTab->addColOffset; - pNew->nRef = 1; + pNew->nTabRef = 1; /* Begin a transaction and increment the schema cookie. */ sqlite3BeginWriteOperation(pParse, 0, iDb); diff --git a/src/build.c b/src/build.c index d613e3a9e4..43e293e7c6 100644 --- a/src/build.c +++ b/src/build.c @@ -634,7 +634,7 @@ static void SQLITE_NOINLINE deleteTable(sqlite3 *db, Table *pTable){ void sqlite3DeleteTable(sqlite3 *db, Table *pTable){ /* Do not delete the table until the reference count reaches zero. */ if( !pTable ) return; - if( ((!db || db->pnBytesFreed==0) && (--pTable->nRef)>0) ) return; + if( ((!db || db->pnBytesFreed==0) && (--pTable->nTabRef)>0) ) return; deleteTable(db, pTable); } @@ -925,7 +925,7 @@ void sqlite3StartTable( pTable->zName = zName; pTable->iPKey = -1; pTable->pSchema = db->aDb[iDb].pSchema; - pTable->nRef = 1; + pTable->nTabRef = 1; pTable->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) ); assert( pParse->pNewTable==0 ); pParse->pNewTable = pTable; diff --git a/src/delete.c b/src/delete.c index d3bcbaa00d..9ec8ed59e3 100644 --- a/src/delete.c +++ b/src/delete.c @@ -36,7 +36,7 @@ Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){ sqlite3DeleteTable(pParse->db, pItem->pTab); pItem->pTab = pTab; if( pTab ){ - pTab->nRef++; + pTab->nTabRef++; } if( sqlite3IndexedByLookup(pParse, pItem) ){ pTab = 0; diff --git a/src/expr.c b/src/expr.c index 97f7182e1e..60843bf52a 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1365,7 +1365,7 @@ SrcList *sqlite3SrcListDup(sqlite3 *db, SrcList *p, int flags){ } pTab = pNewItem->pTab = pOldItem->pTab; if( pTab ){ - pTab->nRef++; + pTab->nTabRef++; } pNewItem->pSelect = sqlite3SelectDup(db, pOldItem->pSelect, flags); pNewItem->pOn = sqlite3ExprDup(db, pOldItem->pOn, flags); diff --git a/src/fkey.c b/src/fkey.c index eaf09ac1ad..cb78764f51 100644 --- a/src/fkey.c +++ b/src/fkey.c @@ -1007,7 +1007,7 @@ void sqlite3FkCheck( struct SrcList_item *pItem = pSrc->a; pItem->pTab = pFKey->pFrom; pItem->zName = pFKey->pFrom->zName; - pItem->pTab->nRef++; + pItem->pTab->nTabRef++; pItem->iCursor = pParse->nTab++; if( regNew!=0 ){ diff --git a/src/select.c b/src/select.c index e63ef837e9..83d9540cf0 100644 --- a/src/select.c +++ b/src/select.c @@ -1806,7 +1806,7 @@ Table *sqlite3ResultSetOfSelect(Parse *pParse, Select *pSelect){ /* The sqlite3ResultSetOfSelect() is only used n contexts where lookaside ** is disabled */ assert( db->lookaside.bDisable ); - pTab->nRef = 1; + pTab->nTabRef = 1; pTab->zName = 0; pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) ); sqlite3ColumnsFromExprList(pParse, pSelect->pEList, &pTab->nCol, &pTab->aCol); @@ -3619,12 +3619,12 @@ static int flattenSubquery( */ if( ALWAYS(pSubitem->pTab!=0) ){ Table *pTabToDel = pSubitem->pTab; - if( pTabToDel->nRef==1 ){ + if( pTabToDel->nTabRef==1 ){ Parse *pToplevel = sqlite3ParseToplevel(pParse); pTabToDel->pNextZombie = pToplevel->pZombieTab; pToplevel->pZombieTab = pTabToDel; }else{ - pTabToDel->nRef--; + pTabToDel->nTabRef--; } pSubitem->pTab = 0; } @@ -4143,7 +4143,7 @@ static int withExpand( assert( pFrom->pTab==0 ); pFrom->pTab = pTab = sqlite3DbMallocZero(db, sizeof(Table)); if( pTab==0 ) return WRC_Abort; - pTab->nRef = 1; + pTab->nTabRef = 1; pTab->zName = sqlite3DbStrDup(db, pCte->zName); pTab->iPKey = -1; pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) ); @@ -4166,20 +4166,20 @@ static int withExpand( ){ pItem->pTab = pTab; pItem->fg.isRecursive = 1; - pTab->nRef++; + pTab->nTabRef++; pSel->selFlags |= SF_Recursive; } } } /* Only one recursive reference is permitted. */ - if( pTab->nRef>2 ){ + if( pTab->nTabRef>2 ){ sqlite3ErrorMsg( pParse, "multiple references to recursive table: %s", pCte->zName ); return SQLITE_ERROR; } - assert( pTab->nRef==1 || ((pSel->selFlags&SF_Recursive) && pTab->nRef==2 )); + assert( pTab->nTabRef==1 || ((pSel->selFlags&SF_Recursive) && pTab->nTabRef==2 )); pCte->zCteErr = "circular reference: %s"; pSavedWith = pParse->pWith; @@ -4312,7 +4312,7 @@ static int selectExpander(Walker *pWalker, Select *p){ if( sqlite3WalkSelect(pWalker, pSel) ) return WRC_Abort; pFrom->pTab = pTab = sqlite3DbMallocZero(db, sizeof(Table)); if( pTab==0 ) return WRC_Abort; - pTab->nRef = 1; + pTab->nTabRef = 1; pTab->zName = sqlite3MPrintf(db, "sqlite_sq_%p", (void*)pTab); while( pSel->pPrior ){ pSel = pSel->pPrior; } sqlite3ColumnsFromExprList(pParse, pSel->pEList,&pTab->nCol,&pTab->aCol); @@ -4325,13 +4325,13 @@ static int selectExpander(Walker *pWalker, Select *p){ assert( pFrom->pTab==0 ); pFrom->pTab = pTab = sqlite3LocateTableItem(pParse, 0, pFrom); if( pTab==0 ) return WRC_Abort; - if( pTab->nRef==0xffff ){ + if( pTab->nTabRef>=0xffff ){ sqlite3ErrorMsg(pParse, "too many references to \"%s\": max 65535", pTab->zName); pFrom->pTab = 0; return WRC_Abort; } - pTab->nRef++; + pTab->nTabRef++; if( !IsVirtual(pTab) && cannotBeFunction(pParse, pFrom) ){ return WRC_Abort; } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 8707858fd6..c30b38b731 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1801,7 +1801,7 @@ struct Table { ExprList *pCheck; /* All CHECK constraints */ /* ... also used as column name list in a VIEW */ int tnum; /* Root BTree page for this table */ - u32 nRef; /* Number of pointers to this Table */ + u32 nTabRef; /* Number of pointers to this Table */ i16 iPKey; /* If not negative, use aCol[iPKey] as the rowid */ i16 nCol; /* Number of columns in this table */ LogEst nRowLogEst; /* Estimated rows in table - from sqlite_stat1 table */ diff --git a/src/vtab.c b/src/vtab.c index c54dc65742..2531155546 100644 --- a/src/vtab.c +++ b/src/vtab.c @@ -1133,7 +1133,7 @@ int sqlite3VtabEponymousTableInit(Parse *pParse, Module *pMod){ return 0; } pMod->pEpoTab = pTab; - pTab->nRef = 1; + pTab->nTabRef = 1; pTab->pSchema = db->aDb[0].pSchema; pTab->tabFlags |= TF_Virtual; pTab->nModuleArg = 0; From 35ac58eabc18c49ebdcdbec7405780d18d7b678d Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 14 Dec 2016 19:28:27 +0000 Subject: [PATCH 1086/1484] Add the experimental ".fkey_missing_indexes" command to the shell tool. To identify indexes that should be created on child keys if FK processing is to be enabled. FossilOrigin-Name: 7df23aca1f7c7b769d614d740b3fda3073f46ba9 --- manifest | 18 +- manifest.uuid | 2 +- src/shell.c | 445 +++++++++++++++++++++++++++++++++++++++++++++++ test/shell6.test | 100 +++++++++++ 4 files changed, 557 insertions(+), 8 deletions(-) create mode 100644 test/shell6.test diff --git a/manifest b/manifest index 82049f338e..07bbf2b3e9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Refactor\sthe\sTable.nRef\sfield\sas\sTable.nTabRef\sfor\seasier\sgrepping. -D 2016-12-14T14:07:35.372 +C Add\sthe\sexperimental\s".fkey_missing_indexes"\scommand\sto\sthe\sshell\stool.\sTo\nidentify\sindexes\sthat\sshould\sbe\screated\son\schild\skeys\sif\sFK\sprocessing\sis\sto\nbe\senabled. +D 2016-12-14T19:28:27.708 F Makefile.in c194b58fe00c370a48ac6ae6945e92a7781db1c8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -389,7 +389,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c bb070cf5f23611c44ab7e4788803684e385fc3fb F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c 204491a5e09a66380a067943d8651af8bda1d358 -F src/shell.c f1c7fde7a83421e6ed620df41d200674a2327e65 +F src/shell.c bf722e55563acd5111fe36bc54ba1669cf9a6b22 F src/sqlite.h.in e8e2d108d82647f0a812fdb74accf91c1ec08ddc F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae @@ -1094,6 +1094,7 @@ F test/shell2.test e242a9912f44f4c23c3d1d802a83e934e84c853b F test/shell3.test 9b95ba643eaa228376f06a898fb410ee9b6e57c1 F test/shell4.test 89ad573879a745974ff2df20ff97c5d6ffffbd5d F test/shell5.test 50a732c1c2158b1cd62cf53975ce1ea7ce6b9dc9 +F test/shell6.test e9ea06630bcd9ea10e14109f0e62c41571bcc1ae F test/shortread1.test bb591ef20f0fd9ed26d0d12e80eee6d7ac8897a3 F test/show_speedtest1_rtree.tcl 32e6c5f073d7426148a6936a0408f4b5b169aba5 F test/shrink.test 1b4330b1fd9e818c04726d45cb28db73087535ce @@ -1536,7 +1537,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d08b72c38ff6fae6ddf7dc84a54f6d7189876289 -R ee18812138ebcbd59cf246eeb625fa00 -U drh -Z c1d49b9032916157524a152005703654 +P 9cae4c2e300e20304ced0dc8c1415c4922185928 +R 9017289f90148307424d56c20b193c71 +T *branch * fkey-missing-indexes +T *sym-fkey-missing-indexes * +T -sym-trunk * +U dan +Z 4ebf85f006949e0e6db45fa67eafcbbb diff --git a/manifest.uuid b/manifest.uuid index 1ac27241a3..354a93a4cc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9cae4c2e300e20304ced0dc8c1415c4922185928 \ No newline at end of file +7df23aca1f7c7b769d614d740b3fda3073f46ba9 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index d0b743cb5b..9fd2eec8a8 100644 --- a/src/shell.c +++ b/src/shell.c @@ -2185,6 +2185,7 @@ static char zHelp[] = ".eqp on|off|full Enable or disable automatic EXPLAIN QUERY PLAN\n" ".exit Exit this program\n" ".explain ?on|off|auto? Turn EXPLAIN output mode on or off or to automatic\n" + ".fkey_missing_indexes Find indexes to make FK processing more efficient\n" ".fullschema ?--indent? Show schema and the content of sqlite_stat tables\n" ".headers on|off Turn display of headers on or off\n" ".help Show this message\n" @@ -3253,6 +3254,446 @@ int shellDeleteFile(const char *zFilename){ return rc; } + +/************************************************************************** +** Beginning of implementation of .fkey_missing_indexes +*/ +typedef struct PragmaVtab PragmaVtab; +typedef struct PragmaCursor PragmaCursor; +typedef struct PragmaConfig PragmaConfig; + +/* +** Table structure for "pragma" eponymous virtual tables. +*/ +struct PragmaVtab { + sqlite3_vtab base; + PragmaConfig *pConfig; + sqlite3 *db; +}; + +/* +** Cursor structure for "pragma" eponymous virtual tables. +*/ +struct PragmaCursor { + sqlite3_vtab_cursor base; + sqlite3_stmt *pSelect; + sqlite3_stmt *pPragma; + sqlite_int64 iRowid; +}; + +struct PragmaConfig { + const char *zModule; + const char *zSchema; + const char *zPragma; +}; + +/* +** Pragma virtual table module xConnect method. +*/ +static int shellPragmaConnect( + sqlite3 *db, + void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVtab, + char **pzErr +){ + PragmaConfig *pConfig = (PragmaConfig*)pAux; + PragmaVtab *pTab = 0; + int rc; + + rc = sqlite3_declare_vtab(db, pConfig->zSchema); + if( rc==SQLITE_OK ){ + pTab = (PragmaVtab*)sqlite3_malloc(sizeof(PragmaVtab)); + if( pTab==0 ){ + rc = SQLITE_NOMEM; + }else{ + memset(pTab, 0, sizeof(PragmaVtab)); + pTab->db = db; + pTab->pConfig = pConfig; + } + }else{ + *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db)); + } + + *ppVtab = (sqlite3_vtab*)pTab; + return rc; +} + +/* +** Pragma virtual table module xDisconnect method. +*/ +static int shellPragmaDisconnect(sqlite3_vtab *pVtab){ + PragmaVtab *pTab = (PragmaVtab*)pVtab; + sqlite3_free(pTab); + return SQLITE_OK; +} + +/* +** Pragma virtual table module xBestIndex method. +*/ +static int shellPragmaBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ + return SQLITE_OK; +} + +/* +** Pragma virtual table module xOpen method. +*/ +static int shellPragmaOpen(sqlite3_vtab *pVtab, sqlite3_vtab_cursor **ppCursor){ + PragmaCursor *pCsr; + + pCsr = (PragmaCursor*)sqlite3_malloc(sizeof(PragmaCursor)); + if( pCsr==0 ) return SQLITE_NOMEM; + memset(pCsr, 0, sizeof(PragmaCursor)); + pCsr->base.pVtab = pVtab; + + *ppCursor = (sqlite3_vtab_cursor*)pCsr; + return SQLITE_OK; +} + +/* +** Pragma virtual table module xClose method. +*/ +static int shellPragmaClose(sqlite3_vtab_cursor *cur){ + return SQLITE_OK; +} + +/* +** Pragma virtual table module xNext method. +*/ +static int shellPragmaNext(sqlite3_vtab_cursor *pVtabCursor){ + PragmaCursor *pCsr = (PragmaCursor*)pVtabCursor; + PragmaVtab *pTab = (PragmaVtab*)(pVtabCursor->pVtab); + sqlite3 *db = pTab->db; + int rc = SQLITE_OK; + + /* Increment the xRowid value */ + pCsr->iRowid++; + + while( 1 ){ + assert( rc==SQLITE_OK ); + + if( pCsr->pPragma ){ + if( SQLITE_ROW!=sqlite3_step(pCsr->pPragma) ){ + rc = sqlite3_finalize(pCsr->pPragma); + pCsr->pPragma = 0; + } + } + + if( rc==SQLITE_OK && pCsr->pPragma==0 ){ + if( SQLITE_ROW!=sqlite3_step(pCsr->pSelect) ){ + rc = sqlite3_finalize(pCsr->pSelect); + pCsr->pSelect = 0; + }else{ + const char *zName = (const char*)sqlite3_column_text(pCsr->pSelect, 0); + char *zSql = sqlite3_mprintf(pTab->pConfig->zPragma, zName); + if( zSql==0 ){ + rc = SQLITE_NOMEM; + }else{ + rc = sqlite3_prepare_v2(db, zSql, -1, &pCsr->pPragma, 0); + if( rc!=SQLITE_OK ){ + pTab->base.zErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(db)); + }else{ + continue; + } + } + } + } + + break; + } + + return rc; +} + +/* +** Pragma virtual table module xFilter method. +*/ +static int shellPragmaFilter( + sqlite3_vtab_cursor *pVtabCursor, + int idxNum, const char *idxStr, + int argc, sqlite3_value **argv +){ + PragmaCursor *pCsr = (PragmaCursor*)pVtabCursor; + PragmaVtab *pTab = (PragmaVtab*)(pVtabCursor->pVtab); + int rc; + + sqlite3_finalize(pCsr->pSelect); + sqlite3_finalize(pCsr->pPragma); + pCsr->pSelect = 0; + pCsr->pPragma = 0; + pCsr->iRowid = 0; + + rc = sqlite3_prepare_v2(pTab->db, + "SELECT name FROM sqlite_master WHERE type = 'table' AND rootpage>0", + -1, &pCsr->pSelect, 0 + ); + if( rc!=SQLITE_OK ){ + pTab->base.zErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(pTab->db)); + return rc; + } + + return shellPragmaNext(pVtabCursor); +} + +/* +** Pragma virtual table module xEof method. +*/ +static int shellPragmaEof(sqlite3_vtab_cursor *pVtabCursor){ + PragmaCursor *pCsr = (PragmaCursor*)pVtabCursor; + return (pCsr->pSelect==0); +} + +/* +** Pragma virtual table module xColumn method. +*/ +static int shellPragmaColumn( + sqlite3_vtab_cursor *pVtabCursor, + sqlite3_context *ctx, + int i +){ + PragmaCursor *pCsr = (PragmaCursor*)pVtabCursor; + switch( i ){ + case 0: /* "database" */ + sqlite3_result_text(ctx, "main", -1, SQLITE_STATIC); + break; + + case 1: /* "child"/"table" */ + sqlite3_result_value(ctx, sqlite3_column_value(pCsr->pSelect, 0)); + break; + + default: + sqlite3_result_value(ctx, sqlite3_column_value(pCsr->pPragma, i-2)); + break; + } + + return SQLITE_OK; +} + +/* +** Pragma virtual table module xRowid method. +*/ +static int shellPragmaRowid(sqlite3_vtab_cursor *pVtabCursor, sqlite_int64 *p){ + PragmaCursor *pCsr = (PragmaCursor*)pVtabCursor; + *p = pCsr->iRowid; + return SQLITE_OK; +} + +/* +** Register the virtual table module with the supplied database handle. +*/ +static int shellPragmaRegister(sqlite3 *db){ + static sqlite3_module shellPragmaModule = { + 0, /* iVersion */ + shellPragmaConnect, /* xCreate - create a table */ + shellPragmaConnect, /* xConnect - connect to an existing table */ + shellPragmaBestIndex, /* xBestIndex - Determine search strategy */ + shellPragmaDisconnect, /* xDisconnect - Disconnect from a table */ + shellPragmaDisconnect, /* xDestroy - Drop a table */ + shellPragmaOpen, /* xOpen - open a cursor */ + shellPragmaClose, /* xClose - close a cursor */ + shellPragmaFilter, /* xFilter - configure scan constraints */ + shellPragmaNext, /* xNext - advance a cursor */ + shellPragmaEof, /* xEof */ + shellPragmaColumn, /* xColumn - read data */ + shellPragmaRowid, /* xRowid - read data */ + 0, /* xUpdate - write data */ + 0, /* xBegin - begin transaction */ + 0, /* xSync - sync transaction */ + 0, /* xCommit - commit transaction */ + 0, /* xRollback - rollback transaction */ + 0, /* xFindFunction - function overloading */ + 0, /* xRename - rename the table */ + 0, /* xSavepoint */ + 0, /* xRelease */ + 0 /* xRollbackTo */ + }; + int rc = SQLITE_OK; + int i; + + static PragmaConfig aConfig[] = { + { "pragma_foreign_key_list", + "CREATE TABLE x(database, child, " + "id, seq, parent, child_col, parent_col, on_update, on_delete, match)", + "PRAGMA foreign_key_list = %Q" + }, + { "pragma_table_info", + "CREATE TABLE x(database, tbl, " + "cid, name, type, not_null, dflt_value, pk)", + "PRAGMA table_info = %Q" + } + }; + + for(i=0; rc==SQLITE_OK && i", where +** is the default collation sequence of the parent column. +*/ +static void shellFkeyCollateClause( + sqlite3_context *pCtx, + int nVal, + sqlite3_value **apVal +){ + sqlite3 *db = sqlite3_context_db_handle(pCtx); + const char *zParent; + const char *zParentCol; + const char *zParentSeq; + const char *zChild; + const char *zChildCol; + const char *zChildSeq; + int rc; + + assert( nVal==4 ); + zParent = (const char*)sqlite3_value_text(apVal[0]); + zParentCol = (const char*)sqlite3_value_text(apVal[1]); + zChild = (const char*)sqlite3_value_text(apVal[2]); + zChildCol = (const char*)sqlite3_value_text(apVal[3]); + + sqlite3_result_text(pCtx, "", -1, SQLITE_STATIC); + rc = sqlite3_table_column_metadata( + db, "main", zParent, zParentCol, 0, &zParentSeq, 0, 0, 0 + ); + if( rc==SQLITE_OK ){ + rc = sqlite3_table_column_metadata( + db, "main", zChild, zChildCol, 0, &zChildSeq, 0, 0, 0 + ); + } + + if( rc==SQLITE_OK && sqlite3_stricmp(zParentSeq, zChildSeq) ){ + char *z = sqlite3_mprintf(" COLLATE %s", zParentSeq); + sqlite3_result_text(pCtx, z, -1, SQLITE_TRANSIENT); + sqlite3_free(z); + } +} + + +/* +** The implementation of dot-command ".fkey_missing_indexes". +*/ +static int shellFkeyMissingIndexes( + ShellState *pState, /* Current shell tool state */ + char **azArg, /* Array of arguments passed to dot command */ + int nArg /* Number of entries in azArg[] */ +){ + sqlite3 *db = pState->db; + FILE *out = pState->out; + int bVerbose = 0; + + int rc; + sqlite3_stmt *pSql = 0; + const char *zSql = + "SELECT " + " 'EXPLAIN QUERY PLAN SELECT rowid FROM ' || quote(child) || ' WHERE ' " + " || group_concat(quote(child) || '.' || quote(child_col) || '=?' || " + " fkey_collate_clause(parent, parent_col, child, child_col),' AND ')" + ", " + " 'SEARCH TABLE ' || child || ' USING COVERING INDEX*('" + " || group_concat('*=?', ' AND ') || ')'" + ", " + " child || '(' || group_concat(child_col, ', ') || ')'" + ", " + " parent || '(' || group_concat(COALESCE(parent_col, " + " (SELECT name FROM pragma_table_info WHERE tbl=parent AND pk=seq+1)" + " )) || ')'" + ", " + " 'CREATE INDEX ' || quote(child ||'_'|| group_concat(child_col, '_'))" + " || ' ON ' || quote(child) || '('" + " || group_concat(quote(child_col) ||" + " fkey_collate_clause(parent, parent_col, child, child_col), ', ')" + " || ');'" + + "FROM pragma_foreign_key_list AS o GROUP BY child, id" + ; + + if( nArg>2 ){ + raw_printf(stderr, "Usage: .fkey_lint ?verbose-flag?\n"); + } + if( nArg==2 ) bVerbose = booleanValue(azArg[1]); + + /* Register the pragma eponymous virtual tables */ + rc = shellPragmaRegister(db); + + /* Register the fkey_collate_clause() SQL function */ + if( rc==SQLITE_OK ){ + rc = sqlite3_create_function(db, "fkey_collate_clause", 4, SQLITE_UTF8, + 0, shellFkeyCollateClause, 0, 0 + ); + } + + + if( rc==SQLITE_OK ){ + rc = sqlite3_prepare_v2(db, zSql, -1, &pSql, 0); + } + + if( rc==SQLITE_OK ){ + int rc2; + while( SQLITE_ROW==sqlite3_step(pSql) ){ + int res = -1; + sqlite3_stmt *pExplain = 0; + const char *zEQP = (const char*)sqlite3_column_text(pSql, 0); + const char *zGlob = (const char*)sqlite3_column_text(pSql, 1); + const char *zFrom = (const char*)sqlite3_column_text(pSql, 2); + const char *zTarget = (const char*)sqlite3_column_text(pSql, 3); + const char *zCI = (const char*)sqlite3_column_text(pSql, 4); + + rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0); + if( rc!=SQLITE_OK ) break; + if( SQLITE_ROW==sqlite3_step(pExplain) ){ + const char *zPlan = (const char*)sqlite3_column_text(pExplain, 3); + res = (0==sqlite3_strglob(zGlob, zPlan)); + } + rc = sqlite3_finalize(pExplain); + if( rc!=SQLITE_OK ) break; + + if( res<0 ){ + raw_printf(stderr, "Error: internal error"); + break; + }else if( res==0 ){ + raw_printf(out, "%s --> %s\n", zCI, zTarget); + }else if( bVerbose ){ + raw_printf(out, "/* no extra indexes required for %s -> %s */\n", + zFrom, zTarget + ); + } + } + + if( rc!=SQLITE_OK ){ + raw_printf(stderr, "%s\n", sqlite3_errmsg(db)); + } + + rc2 = sqlite3_finalize(pSql); + if( rc==SQLITE_OK && rc2!=SQLITE_OK ){ + rc = rc2; + raw_printf(stderr, "%s\n", sqlite3_errmsg(db)); + } + }else{ + raw_printf(stderr, "%s\n", sqlite3_errmsg(db)); + } + + return rc; +} +/* +** End of implementation of .fkey_missing_indexes +**************************************************************************/ + /* ** If an input line begins with "." then invoke this routine to ** process that line. @@ -3566,6 +4007,10 @@ static int do_meta_command(char *zLine, ShellState *p){ } }else + if( c=='f' && strncmp(azArg[0], "fkey_missing_indexes", n)==0 ){ + shellFkeyMissingIndexes(p, azArg, nArg); + }else + if( c=='f' && strncmp(azArg[0], "fullschema", n)==0 ){ ShellState data; char *zErrMsg = 0; diff --git a/test/shell6.test b/test/shell6.test new file mode 100644 index 0000000000..df7e1de58d --- /dev/null +++ b/test/shell6.test @@ -0,0 +1,100 @@ +# 2016 December 15 +# +# 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. +# +#*********************************************************************** +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix shell6 +set CLI [test_find_cli] +db close +forcedelete test.db test.db-journal test.db-wal + +foreach {tn schema output} { + 1 { + CREATE TABLE p1(a PRIMARY KEY, b); + CREATE TABLE c1(x, y REFERENCES p1); + } { + CREATE INDEX 'c1_y' ON 'c1'('y'); --> p1(a) + } + + 2 { + CREATE TABLE p1(a PRIMARY KEY, b); + CREATE TABLE c2(x REFERENCES p1, y REFERENCES p1); + } { + CREATE INDEX 'c2_y' ON 'c2'('y'); --> p1(a) + CREATE INDEX 'c2_x' ON 'c2'('x'); --> p1(a) + } + + 3 { + CREATE TABLE 'p 1'(a, b, c, PRIMARY KEY(c, b)); + CREATE TABLE 'c 1'(x, y, z, FOREIGN KEY (z, y) REFERENCES 'p 1'); + } { + CREATE INDEX 'c 1_z_y' ON 'c 1'('z', 'y'); --> p 1(c,b) + } + + 4 { + CREATE TABLE p1(a, 'b b b' PRIMARY KEY); + CREATE TABLE c1('x y z' REFERENCES p1); + CREATE INDEX i1 ON c1('x y z') WHERE "x y z" IS NOT NULL; + } { + } + + 5 { + CREATE TABLE p1(a, 'b b b' PRIMARY KEY); + CREATE TABLE c1('x y z' REFERENCES p1); + CREATE INDEX i1 ON c1('x y z') WHERE "x y z" IS NOT 12; + } { + CREATE INDEX 'c1_x y z' ON 'c1'('x y z'); --> p1(b b b) + } + + 6 { + CREATE TABLE x1(a, b, c, UNIQUE(a, b)); + CREATE TABLE y1(a, b, c, FOREIGN KEY(b, a) REFERENCES x1(a, b)); + CREATE INDEX y1i ON y1(a, c, b); + } { + CREATE INDEX 'y1_b_a' ON 'y1'('b', 'a'); --> x1(a,b) + } + + 6 { + CREATE TABLE x1(a COLLATE nocase, b, UNIQUE(a)); + CREATE TABLE y1(a COLLATE rtrim REFERENCES x1(a)); + } { + CREATE INDEX 'y1_a' ON 'y1'('a' COLLATE nocase); --> x1(a) + } + +} { + forcedelete test.db + sqlite3 db test.db + execsql $schema + + set expected "" + foreach line [split $output "\n"] { + set line [string trim $line] + if {$line!=""} { + append expected "$line\n" + } + } + + do_test 1.$tn.1 { + set RES [catchcmd test.db .fkey_missing_indexes] + } [list 0 [string trim $expected]] + + do_test 1.$tn.2 { + execsql [lindex $RES 1] + catchcmd test.db .fkey_missing_indexes + } {0 {}} + + db close +} + +finish_test + + From f9647b6625b9241dbf0fa1b81a295ca4eb9e0cb5 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 15 Dec 2016 06:01:40 +0000 Subject: [PATCH 1087/1484] Add the -groupbyparent option to the ".fkey_missing_indexes" command. FossilOrigin-Name: 976c51b4836dfba2ce9b246334a85bda08ac526f --- manifest | 15 ++++++-------- manifest.uuid | 2 +- src/shell.c | 55 ++++++++++++++++++++++++++++++++++++++++----------- 3 files changed, 51 insertions(+), 21 deletions(-) diff --git a/manifest b/manifest index 07bbf2b3e9..36ecb42102 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sexperimental\s".fkey_missing_indexes"\scommand\sto\sthe\sshell\stool.\sTo\nidentify\sindexes\sthat\sshould\sbe\screated\son\schild\skeys\sif\sFK\sprocessing\sis\sto\nbe\senabled. -D 2016-12-14T19:28:27.708 +C Add\sthe\s-groupbyparent\soption\sto\sthe\s".fkey_missing_indexes"\scommand. +D 2016-12-15T06:01:40.711 F Makefile.in c194b58fe00c370a48ac6ae6945e92a7781db1c8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -389,7 +389,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c bb070cf5f23611c44ab7e4788803684e385fc3fb F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c 204491a5e09a66380a067943d8651af8bda1d358 -F src/shell.c bf722e55563acd5111fe36bc54ba1669cf9a6b22 +F src/shell.c 331be7c5d82477baff3ab584f1dc679e9676e0ef F src/sqlite.h.in e8e2d108d82647f0a812fdb74accf91c1ec08ddc F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae @@ -1537,10 +1537,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 9cae4c2e300e20304ced0dc8c1415c4922185928 -R 9017289f90148307424d56c20b193c71 -T *branch * fkey-missing-indexes -T *sym-fkey-missing-indexes * -T -sym-trunk * +P 7df23aca1f7c7b769d614d740b3fda3073f46ba9 +R 109aa4e43fd004b2c710d444b0c58b6c U dan -Z 4ebf85f006949e0e6db45fa67eafcbbb +Z 2faf32103da4e43d54e82bc173d9e560 diff --git a/manifest.uuid b/manifest.uuid index 354a93a4cc..9760c01f9e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7df23aca1f7c7b769d614d740b3fda3073f46ba9 \ No newline at end of file +976c51b4836dfba2ce9b246334a85bda08ac526f \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 9fd2eec8a8..b0bd9c6ece 100644 --- a/src/shell.c +++ b/src/shell.c @@ -3595,7 +3595,10 @@ static int shellFkeyMissingIndexes( ){ sqlite3 *db = pState->db; FILE *out = pState->out; - int bVerbose = 0; + int bVerbose = 0; /* If -verbose is present */ + int bGroupByParent = 0; /* If -groupbyparent is present */ + int i; + const char *zIndent = ""; int rc; sqlite3_stmt *pSql = 0; @@ -3619,14 +3622,27 @@ static int shellFkeyMissingIndexes( " || group_concat(quote(child_col) ||" " fkey_collate_clause(parent, parent_col, child, child_col), ', ')" " || ');'" + ", " + " parent " - "FROM pragma_foreign_key_list AS o GROUP BY child, id" + "FROM pragma_foreign_key_list GROUP BY child, id " + "ORDER BY (CASE WHEN ? THEN parent ELSE CHILD END)" ; - if( nArg>2 ){ - raw_printf(stderr, "Usage: .fkey_lint ?verbose-flag?\n"); + for(i=1; i1 && sqlite3_strnicmp("-verbose", azArg[i], n)==0 ){ + bVerbose = 1; + } + else if( n>1 && sqlite3_strnicmp("-groupbyparent", azArg[i], n)==0 ){ + bGroupByParent = 1; + zIndent = " "; + } + else{ + raw_printf(stderr, "Usage: .fkey_lint ?-verbose? ?-groupbyparent?\n"); + return SQLITE_ERROR; + } } - if( nArg==2 ) bVerbose = booleanValue(azArg[1]); /* Register the pragma eponymous virtual tables */ rc = shellPragmaRegister(db); @@ -3642,9 +3658,13 @@ static int shellFkeyMissingIndexes( if( rc==SQLITE_OK ){ rc = sqlite3_prepare_v2(db, zSql, -1, &pSql, 0); } + if( rc==SQLITE_OK ){ + sqlite3_bind_int(pSql, 1, bGroupByParent); + } if( rc==SQLITE_OK ){ int rc2; + char *zPrev = 0; while( SQLITE_ROW==sqlite3_step(pSql) ){ int res = -1; sqlite3_stmt *pExplain = 0; @@ -3653,6 +3673,7 @@ static int shellFkeyMissingIndexes( const char *zFrom = (const char*)sqlite3_column_text(pSql, 2); const char *zTarget = (const char*)sqlite3_column_text(pSql, 3); const char *zCI = (const char*)sqlite3_column_text(pSql, 4); + const char *zParent = (const char*)sqlite3_column_text(pSql, 5); rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0); if( rc!=SQLITE_OK ) break; @@ -3666,14 +3687,26 @@ static int shellFkeyMissingIndexes( if( res<0 ){ raw_printf(stderr, "Error: internal error"); break; - }else if( res==0 ){ - raw_printf(out, "%s --> %s\n", zCI, zTarget); - }else if( bVerbose ){ - raw_printf(out, "/* no extra indexes required for %s -> %s */\n", - zFrom, zTarget - ); + }else{ + if( bGroupByParent + && (bVerbose || res==0) + && (zPrev==0 || sqlite3_stricmp(zParent, zPrev)) + ){ + raw_printf(out, "-- Parent table %s\n", zParent); + sqlite3_free(zPrev); + zPrev = sqlite3_mprintf("%s", zParent); + } + + if( res==0 ){ + raw_printf(out, "%s%s --> %s\n", zIndent, zCI, zTarget); + }else if( bVerbose ){ + raw_printf(out, "%s/* no extra indexes required for %s -> %s */\n", + zIndent, zFrom, zTarget + ); + } } } + sqlite3_free(zPrev); if( rc!=SQLITE_OK ){ raw_printf(stderr, "%s\n", sqlite3_errmsg(db)); From c232aca184a75f25b2be9778f8227f333fbd0e5d Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 15 Dec 2016 16:01:17 +0000 Subject: [PATCH 1088/1484] Do more pragma processing from tables rather than in-line code. FossilOrigin-Name: a88ca3524b97f296dffc68335466b3767a681747 --- manifest | 19 +- manifest.uuid | 2 +- src/pragma.c | 126 +++----- src/pragma.h | 737 ++++++++++++++++++++++++++----------------- tool/mkpragmatab.tcl | 147 +++++++-- 5 files changed, 615 insertions(+), 416 deletions(-) diff --git a/manifest b/manifest index 82049f338e..a02ef53983 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Refactor\sthe\sTable.nRef\sfield\sas\sTable.nTabRef\sfor\seasier\sgrepping. -D 2016-12-14T14:07:35.372 +C Do\smore\spragma\sprocessing\sfrom\stables\srather\sthan\sin-line\scode. +D 2016-12-15T16:01:17.867 F Makefile.in c194b58fe00c370a48ac6ae6945e92a7781db1c8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -381,8 +381,8 @@ F src/parse.y 29153738a7322054359320eb00b5a4cd44389f20 F src/pcache.c 51070ec9b8251bbf9c6ea3d35fd96a458752929e F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 F src/pcache1.c e3967219b2a92b9edcb9324a4ba75009090d3953 -F src/pragma.c d932ba278654617cdd281f88a790a3185fca7c44 -F src/pragma.h 64c78a648751b9f4f297276c4eb7507b14b4628c +F src/pragma.c 78f85cf6c668b084702bb305bd4980b4813afa70 +F src/pragma.h 7dff1007ade3aabf8b2e467107b4506940c0ad86 F src/prepare.c b1140c3d0cf59bc85ace00ce363153041b424b7a F src/printf.c f94da4935d1dd25420ac50c6745db1deb35e07c1 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 @@ -1474,7 +1474,7 @@ F tool/mkmsvcmin.tcl 2f12f7fa8858bbe61cf81820a2da96c79ed1ca8d F tool/mkopcodec.tcl d1b6362bd3aa80d5520d4d6f3765badf01f6c43c F tool/mkopcodeh.tcl a01d2c1d8a6205b03fc635adf3735b4c523befd3 F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e -F tool/mkpragmatab.tcl f0d5bb266d1d388cf86fce5ba01a891e95d72d41 +F tool/mkpragmatab.tcl 999d7da2b77e83f24de01c3c8f90dc66411ce6d2 F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 F tool/mksqlite3c-noext.tcl fef88397668ae83166735c41af99d79f56afaabb F tool/mksqlite3c.tcl 06b2e6a0f21cc0a5d70fbbd136b3e0a96470645e @@ -1536,7 +1536,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d08b72c38ff6fae6ddf7dc84a54f6d7189876289 -R ee18812138ebcbd59cf246eeb625fa00 +P 9cae4c2e300e20304ced0dc8c1415c4922185928 +R d8e6c9c98262f0aea48f528b484866a4 +T *branch * table-driven-pragma +T *sym-table-driven-pragma * +T -sym-trunk * U drh -Z c1d49b9032916157524a152005703654 +Z 7260d2e6fdce7485555b88e6d856ce9f diff --git a/manifest.uuid b/manifest.uuid index 1ac27241a3..206d8471d0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9cae4c2e300e20304ced0dc8c1415c4922185928 \ No newline at end of file +a88ca3524b97f296dffc68335466b3767a681747 \ No newline at end of file diff --git a/src/pragma.c b/src/pragma.c index e774de3421..7faf937001 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -163,29 +163,29 @@ static int changeTempStorage(Parse *pParse, const char *zStorageType){ #endif /* SQLITE_PAGER_PRAGMAS */ /* -** Set the names of the first N columns to the values in azCol[] +** Set result column names for a pragma. */ -static void setAllColumnNames( - Vdbe *v, /* The query under construction */ - int N, /* Number of columns */ - const char **azCol /* Names of columns */ +static void setPragmaResultColumnNames( + Vdbe *v, /* The query under construction */ + const struct sPragmaNames *pPragma /* The pragma */ ){ - int i; - sqlite3VdbeSetNumCols(v, N); - for(i=0; inPragCName; + sqlite3VdbeSetNumCols(v, n==0 ? 1 : n); + if( n==0 ){ + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, pPragma->zName, SQLITE_STATIC); + }else{ + int i, j; + for(i=0, j=pPragma->iPragCName; ibusyHandler.nBusy = 0; rc = sqlite3_file_control(db, zDb, SQLITE_FCNTL_PRAGMA, (void*)aFcntl); if( rc==SQLITE_OK ){ - returnSingleText(v, "result", aFcntl[0]); + sqlite3VdbeSetNumCols(v, 1); + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, aFcntl[0], SQLITE_TRANSIENT); + returnSingleText(v, aFcntl[0]); sqlite3_free(aFcntl[0]); goto pragma_out; } @@ -396,10 +396,15 @@ void sqlite3Pragma( pPragma = &aPragmaNames[mid]; /* Make sure the database schema is loaded if the pragma requires that */ - if( (pPragma->mPragFlag & PragFlag_NeedSchema)!=0 ){ + if( (pPragma->mPragFlg & PragFlg_NeedSchema)!=0 ){ if( sqlite3ReadSchema(pParse) ) goto pragma_out; } + /* Register the result column names for pragmas that return results */ + if( (pPragma->mPragFlg & PragFlg_NoColumns)==0 ){ + setPragmaResultColumnNames(v, pPragma); + } + /* Jump to the appropriate pragma handler */ switch( pPragma->ePragTyp ){ @@ -436,7 +441,6 @@ void sqlite3Pragma( VdbeOp *aOp; sqlite3VdbeUsesBtree(v, iDb); if( !zRight ){ - setOneColumnName(v, "cache_size"); pParse->nMem += 2; sqlite3VdbeVerifyNoMallocRequired(v, ArraySize(getCacheSize)); aOp = sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize, iLn); @@ -471,7 +475,7 @@ void sqlite3Pragma( assert( pBt!=0 ); if( !zRight ){ int size = ALWAYS(pBt) ? sqlite3BtreeGetPageSize(pBt) : 0; - returnSingleInt(v, "page_size", size); + returnSingleInt(v, size); }else{ /* Malloc may fail when setting the page-size, as there is an internal ** buffer that the pager module resizes using sqlite3_realloc(). @@ -506,7 +510,7 @@ void sqlite3Pragma( } } b = sqlite3BtreeSecureDelete(pBt, b); - returnSingleInt(v, "secure_delete", b); + returnSingleInt(v, b); break; } @@ -538,8 +542,6 @@ void sqlite3Pragma( sqlite3AbsInt32(sqlite3Atoi(zRight))); } sqlite3VdbeAddOp2(v, OP_ResultRow, iReg, 1); - sqlite3VdbeSetNumCols(v, 1); - sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLeft, SQLITE_TRANSIENT); break; } @@ -585,7 +587,7 @@ void sqlite3Pragma( if( eMode==PAGER_LOCKINGMODE_EXCLUSIVE ){ zRet = "exclusive"; } - returnSingleText(v, "locking_mode", zRet); + returnSingleText(v, zRet); break; } @@ -598,7 +600,6 @@ void sqlite3Pragma( int eMode; /* One of the PAGER_JOURNALMODE_XXX symbols */ int ii; /* Loop counter */ - setOneColumnName(v, "journal_mode"); if( zRight==0 ){ /* If there is no "=MODE" part of the pragma, do a query for the ** current mode */ @@ -644,7 +645,7 @@ void sqlite3Pragma( if( iLimit<-1 ) iLimit = -1; } iLimit = sqlite3PagerJournalSizeLimit(pPager, iLimit); - returnSingleInt(v, "journal_size_limit", iLimit); + returnSingleInt(v, iLimit); break; } @@ -662,7 +663,7 @@ void sqlite3Pragma( Btree *pBt = pDb->pBt; assert( pBt!=0 ); if( !zRight ){ - returnSingleInt(v, "auto_vacuum", sqlite3BtreeGetAutoVacuum(pBt)); + returnSingleInt(v, sqlite3BtreeGetAutoVacuum(pBt)); }else{ int eAuto = getAutoVacuum(zRight); assert( eAuto>=0 && eAuto<=2 ); @@ -741,7 +742,7 @@ void sqlite3Pragma( case PragTyp_CACHE_SIZE: { assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); if( !zRight ){ - returnSingleInt(v, "cache_size", pDb->pSchema->cache_size); + returnSingleInt(v, pDb->pSchema->cache_size); }else{ int size = sqlite3Atoi(zRight); pDb->pSchema->cache_size = size; @@ -775,7 +776,7 @@ void sqlite3Pragma( case PragTyp_CACHE_SPILL: { assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); if( !zRight ){ - returnSingleInt(v, "cache_spill", + returnSingleInt(v, (db->flags & SQLITE_CacheSpill)==0 ? 0 : sqlite3BtreeSetSpillSize(pDb->pBt,0)); }else{ @@ -829,7 +830,7 @@ void sqlite3Pragma( rc = SQLITE_OK; #endif if( rc==SQLITE_OK ){ - returnSingleInt(v, "mmap_size", sz); + returnSingleInt(v, sz); }else if( rc!=SQLITE_NOTFOUND ){ pParse->nErr++; pParse->rc = rc; @@ -850,7 +851,7 @@ void sqlite3Pragma( */ case PragTyp_TEMP_STORE: { if( !zRight ){ - returnSingleInt(v, "temp_store", db->temp_store); + returnSingleInt(v, db->temp_store); }else{ changeTempStorage(pParse, zRight); } @@ -869,7 +870,7 @@ void sqlite3Pragma( */ case PragTyp_TEMP_STORE_DIRECTORY: { if( !zRight ){ - returnSingleText(v, "temp_store_directory", sqlite3_temp_directory); + returnSingleText(v, sqlite3_temp_directory); }else{ #ifndef SQLITE_OMIT_WSD if( zRight[0] ){ @@ -913,7 +914,7 @@ void sqlite3Pragma( */ case PragTyp_DATA_STORE_DIRECTORY: { if( !zRight ){ - returnSingleText(v, "data_store_directory", sqlite3_data_directory); + returnSingleText(v, sqlite3_data_directory); }else{ #ifndef SQLITE_OMIT_WSD if( zRight[0] ){ @@ -952,7 +953,7 @@ void sqlite3Pragma( sqlite3_file *pFile = sqlite3PagerFile(pPager); sqlite3OsFileControlHint(pFile, SQLITE_GET_LOCKPROXYFILE, &proxy_file_path); - returnSingleText(v, "lock_proxy_file", proxy_file_path); + returnSingleText(v, proxy_file_path); }else{ Pager *pPager = sqlite3BtreePager(pDb->pBt); sqlite3_file *pFile = sqlite3PagerFile(pPager); @@ -984,7 +985,7 @@ void sqlite3Pragma( */ case PragTyp_SYNCHRONOUS: { if( !zRight ){ - returnSingleInt(v, "synchronous", pDb->safety_level-1); + returnSingleInt(v, pDb->safety_level-1); }else{ if( !db->autoCommit ){ sqlite3ErrorMsg(pParse, @@ -1004,7 +1005,8 @@ void sqlite3Pragma( #ifndef SQLITE_OMIT_FLAG_PRAGMAS case PragTyp_FLAG: { if( zRight==0 ){ - returnSingleInt(v, pPragma->zName, (db->flags & pPragma->iArg)!=0 ); + setPragmaResultColumnNames(v, pPragma); + returnSingleInt(v, (db->flags & pPragma->iArg)!=0 ); }else{ int mask = pPragma->iArg; /* Mask of bits to set or clear. */ if( db->autoCommit==0 ){ @@ -1054,16 +1056,12 @@ void sqlite3Pragma( Table *pTab; pTab = sqlite3LocateTable(pParse, LOCATE_NOERR, zRight, zDb); if( pTab ){ - static const char *azCol[] = { - "cid", "name", "type", "notnull", "dflt_value", "pk" - }; int i, k; int nHidden = 0; Column *pCol; Index *pPk = sqlite3PrimaryKeyIndex(pTab); pParse->nMem = 6; sqlite3CodeVerifySchema(pParse, iDb); - setAllColumnNames(v, 6, azCol); assert( 6==ArraySize(azCol) ); sqlite3ViewGetColumnNames(pParse, pTab); for(i=0, pCol=pTab->aCol; inCol; i++, pCol++){ if( IsHiddenColumn(pCol) ){ @@ -1092,13 +1090,10 @@ void sqlite3Pragma( break; case PragTyp_STATS: { - static const char *azCol[] = { "table", "index", "width", "height" }; Index *pIdx; HashElem *i; - v = sqlite3GetVdbe(pParse); pParse->nMem = 4; sqlite3CodeVerifySchema(pParse, iDb); - setAllColumnNames(v, 4, azCol); assert( 4==ArraySize(azCol) ); for(i=sqliteHashFirst(&pDb->pSchema->tblHash); i; i=sqliteHashNext(i)){ Table *pTab = sqliteHashData(i); sqlite3VdbeMultiLoad(v, 1, "ssii", @@ -1123,9 +1118,6 @@ void sqlite3Pragma( Table *pTab; pIdx = sqlite3FindIndex(db, zRight, zDb); if( pIdx ){ - static const char *azCol[] = { - "seqno", "cid", "name", "desc", "coll", "key" - }; int i; int mx; if( pPragma->iArg ){ @@ -1139,8 +1131,7 @@ void sqlite3Pragma( } pTab = pIdx->pTable; sqlite3CodeVerifySchema(pParse, iDb); - assert( pParse->nMem<=ArraySize(azCol) ); - setAllColumnNames(v, pParse->nMem, azCol); + assert( pParse->nMem<=pPragma->nPragCName ); for(i=0; iaiColumn[i]; sqlite3VdbeMultiLoad(v, 1, "iis", i, cnum, @@ -1163,13 +1154,8 @@ void sqlite3Pragma( int i; pTab = sqlite3FindTable(db, zRight, zDb); if( pTab ){ - static const char *azCol[] = { - "seq", "name", "unique", "origin", "partial" - }; - v = sqlite3GetVdbe(pParse); pParse->nMem = 5; sqlite3CodeVerifySchema(pParse, iDb); - setAllColumnNames(v, 5, azCol); assert( 5==ArraySize(azCol) ); for(pIdx=pTab->pIndex, i=0; pIdx; pIdx=pIdx->pNext, i++){ const char *azOrigin[] = { "c", "u", "pk" }; sqlite3VdbeMultiLoad(v, 1, "isisi", @@ -1185,10 +1171,8 @@ void sqlite3Pragma( break; case PragTyp_DATABASE_LIST: { - static const char *azCol[] = { "seq", "name", "file" }; int i; pParse->nMem = 3; - setAllColumnNames(v, 3, azCol); assert( 3==ArraySize(azCol) ); for(i=0; inDb; i++){ if( db->aDb[i].pBt==0 ) continue; assert( db->aDb[i].zDbSName!=0 ); @@ -1202,11 +1186,9 @@ void sqlite3Pragma( break; case PragTyp_COLLATION_LIST: { - static const char *azCol[] = { "seq", "name" }; int i = 0; HashElem *p; pParse->nMem = 2; - setAllColumnNames(v, 2, azCol); assert( 2==ArraySize(azCol) ); for(p=sqliteHashFirst(&db->aCollSeq); p; p=sqliteHashNext(p)){ CollSeq *pColl = (CollSeq *)sqliteHashData(p); sqlite3VdbeMultiLoad(v, 1, "is", i++, pColl->zName); @@ -1222,17 +1204,11 @@ void sqlite3Pragma( Table *pTab; pTab = sqlite3FindTable(db, zRight, zDb); if( pTab ){ - v = sqlite3GetVdbe(pParse); pFK = pTab->pFKey; if( pFK ){ - static const char *azCol[] = { - "id", "seq", "table", "from", "to", "on_update", "on_delete", - "match" - }; int i = 0; pParse->nMem = 8; sqlite3CodeVerifySchema(pParse, iDb); - setAllColumnNames(v, 8, azCol); assert( 8==ArraySize(azCol) ); while(pFK){ int j; for(j=0; jnCol; j++){ @@ -1273,14 +1249,11 @@ void sqlite3Pragma( int addrTop; /* Top of a loop checking foreign keys */ int addrOk; /* Jump here if the key is OK */ int *aiCols; /* child to parent column mapping */ - static const char *azCol[] = { "table", "rowid", "parent", "fkid" }; regResult = pParse->nMem+1; pParse->nMem += 4; regKey = ++pParse->nMem; regRow = ++pParse->nMem; - v = sqlite3GetVdbe(pParse); - setAllColumnNames(v, 4, azCol); assert( 4==ArraySize(azCol) ); sqlite3CodeVerifySchema(pParse, iDb); k = sqliteHashFirst(&db->aDb[iDb].pSchema->tblHash); while( k ){ @@ -1419,7 +1392,6 @@ void sqlite3Pragma( /* Initialize the VDBE program */ pParse->nMem = 6; - setOneColumnName(v, "integrity_check"); /* Set the maximum error count */ mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX; @@ -1671,7 +1643,7 @@ void sqlite3Pragma( assert( encnames[SQLITE_UTF8].enc==SQLITE_UTF8 ); assert( encnames[SQLITE_UTF16LE].enc==SQLITE_UTF16LE ); assert( encnames[SQLITE_UTF16BE].enc==SQLITE_UTF16BE ); - returnSingleText(v, "encoding", encnames[ENC(pParse->db)].zName); + returnSingleText(v, encnames[ENC(pParse->db)].zName); }else{ /* "PRAGMA encoding = XXX" */ /* Only change the value of sqlite.enc if the database handle is not ** initialized. If the main database exists, the new sqlite.enc value @@ -1734,7 +1706,7 @@ void sqlite3Pragma( case PragTyp_HEADER_VALUE: { int iCookie = pPragma->iArg; /* Which cookie to read or write */ sqlite3VdbeUsesBtree(v, iDb); - if( zRight && (pPragma->mPragFlag & PragFlag_ReadOnly)==0 ){ + if( zRight && (pPragma->mPragFlg & PragFlg_ReadOnly)==0 ){ /* Write the specified cookie value */ static const VdbeOpList setCookie[] = { { OP_Transaction, 0, 1, 0}, /* 0 */ @@ -1762,8 +1734,6 @@ void sqlite3Pragma( aOp[0].p1 = iDb; aOp[1].p1 = iDb; aOp[1].p3 = iCookie; - sqlite3VdbeSetNumCols(v, 1); - sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLeft, SQLITE_TRANSIENT); sqlite3VdbeReusable(v); } } @@ -1781,7 +1751,6 @@ void sqlite3Pragma( int i = 0; const char *zOpt; pParse->nMem = 1; - setOneColumnName(v, "compile_option"); while( (zOpt = sqlite3_compileoption_get(i++))!=0 ){ sqlite3VdbeLoadString(v, 1, zOpt); sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1); @@ -1798,7 +1767,6 @@ void sqlite3Pragma( ** Checkpoint the database. */ case PragTyp_WAL_CHECKPOINT: { - static const char *azCol[] = { "busy", "log", "checkpointed" }; int iBt = (pId2->z?iDb:SQLITE_MAX_ATTACHED); int eMode = SQLITE_CHECKPOINT_PASSIVE; if( zRight ){ @@ -1810,7 +1778,6 @@ void sqlite3Pragma( eMode = SQLITE_CHECKPOINT_TRUNCATE; } } - setAllColumnNames(v, 3, azCol); assert( 3==ArraySize(azCol) ); pParse->nMem = 3; sqlite3VdbeAddOp3(v, OP_Checkpoint, iBt, eMode, 1); sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 3); @@ -1829,7 +1796,7 @@ void sqlite3Pragma( if( zRight ){ sqlite3_wal_autocheckpoint(db, sqlite3Atoi(zRight)); } - returnSingleInt(v, "wal_autocheckpoint", + returnSingleInt(v, db->xWalCallback==sqlite3WalDefaultHook ? SQLITE_PTR_TO_INT(db->pWalArg) : 0); } @@ -1862,7 +1829,7 @@ void sqlite3Pragma( if( zRight ){ sqlite3_busy_timeout(db, sqlite3Atoi(zRight)); } - returnSingleInt(v, "timeout", db->busyTimeout); + returnSingleInt(v, db->busyTimeout); break; } @@ -1882,7 +1849,7 @@ void sqlite3Pragma( if( zRight && sqlite3DecOrHexToI64(zRight, &N)==SQLITE_OK ){ sqlite3_soft_heap_limit64(N); } - returnSingleInt(v, "soft_heap_limit", sqlite3_soft_heap_limit64(-1)); + returnSingleInt(v, sqlite3_soft_heap_limit64(-1)); break; } @@ -1901,8 +1868,7 @@ void sqlite3Pragma( ){ sqlite3_limit(db, SQLITE_LIMIT_WORKER_THREADS, (int)(N&0x7fffffff)); } - returnSingleInt(v, "threads", - sqlite3_limit(db, SQLITE_LIMIT_WORKER_THREADS, -1)); + returnSingleInt(v, sqlite3_limit(db, SQLITE_LIMIT_WORKER_THREADS, -1)); break; } @@ -1914,9 +1880,7 @@ void sqlite3Pragma( static const char *const azLockName[] = { "unlocked", "shared", "reserved", "pending", "exclusive" }; - static const char *azCol[] = { "database", "status" }; int i; - setAllColumnNames(v, 2, azCol); assert( 2==ArraySize(azCol) ); pParse->nMem = 2; for(i=0; inDb; i++){ Btree *pBt; diff --git a/src/pragma.h b/src/pragma.h index 81779e9d4a..1ae9fe7bc5 100644 --- a/src/pragma.h +++ b/src/pragma.h @@ -3,6 +3,8 @@ ** ../tool/mkpragmatab.tcl. To update the set of pragmas, edit ** that script and rerun it. */ + +/* The various pragma types */ #define PragTyp_HEADER_VALUE 0 #define PragTyp_AUTO_VACUUM 1 #define PragTyp_FLAG 2 @@ -46,419 +48,558 @@ #define PragTyp_REKEY 40 #define PragTyp_LOCK_STATUS 41 #define PragTyp_PARSER_TRACE 42 -#define PragFlag_NeedSchema 0x01 -#define PragFlag_ReadOnly 0x02 + +/* Property flags associated with various pragma. */ +#define PragFlg_NeedSchema 0x01 /* Force schema load before running */ +#define PragFlg_NoColumns 0x02 /* OP_ResultRow called with zero columns */ +#define PragFlg_ReadOnly 0x04 /* Read-only HEADER_VALUE */ +#define PragFlg_Result0 0x08 /* Acts as query when no argument */ +#define PragFlg_Result1 0x10 /* Acts as query when has one argument */ +#define PragFlg_SchemaOpt 0x20 /* Schema restricts name search if present */ +#define PragFlg_SchemaReq 0x40 /* Schema required - "main" is default */ + +/* Names of columns for pragmas that return multi-column result +** or that return single-column results where the name of the +** result column is different from the name of the pragma +*/ +static const char *const pragCName[] = { + /* 0 */ "cache_size", /* Used by: default_cache_size */ + /* 1 */ "cid", /* Used by: table_info */ + /* 2 */ "name", + /* 3 */ "type", + /* 4 */ "notnull", + /* 5 */ "dflt_value", + /* 6 */ "pk", + /* 7 */ "table", /* Used by: stats */ + /* 8 */ "index", + /* 9 */ "width", + /* 10 */ "height", + /* 11 */ "seqno", /* Used by: index_info */ + /* 12 */ "cid", + /* 13 */ "name", + /* 14 */ "seqno", /* Used by: index_xinfo */ + /* 15 */ "cid", + /* 16 */ "name", + /* 17 */ "desc", + /* 18 */ "coll", + /* 19 */ "key", + /* 20 */ "seq", /* Used by: index_list */ + /* 21 */ "name", + /* 22 */ "unique", + /* 23 */ "origin", + /* 24 */ "partial", + /* 25 */ "seq", /* Used by: database_list */ + /* 26 */ "name", + /* 27 */ "file", + /* 28 */ "seq", /* Used by: collation_list */ + /* 29 */ "name", + /* 30 */ "id", /* Used by: foreign_key_list */ + /* 31 */ "seq", + /* 32 */ "table", + /* 33 */ "from", + /* 34 */ "to", + /* 35 */ "on_update", + /* 36 */ "on_delete", + /* 37 */ "match", + /* 38 */ "table", /* Used by: foreign_key_check */ + /* 39 */ "rowid", + /* 40 */ "parent", + /* 41 */ "fkid", + /* 42 */ "busy", /* Used by: wal_checkpoint */ + /* 43 */ "log", + /* 44 */ "checkpointed", + /* 45 */ "timeout", /* Used by: busy_timeout */ + /* 46 */ "database", /* Used by: lock_status */ + /* 47 */ "status", +}; + +/* Definitions of all built-in pragmas */ static const struct sPragmaNames { - const char *const zName; /* Name of pragma */ - u8 ePragTyp; /* PragTyp_XXX value */ - u8 mPragFlag; /* Zero or more PragFlag_XXX values */ - u32 iArg; /* Extra argument */ + const char *const zName; /* Name of pragma */ + u8 ePragTyp; /* PragTyp_XXX value */ + u8 mPragFlg; /* Zero or more PragFlg_XXX values */ + u8 iPragCName; /* Start of column names in pragCName[] */ + u8 nPragCName; /* Num of col names. 0 means use pragma name */ + u32 iArg; /* Extra argument */ } aPragmaNames[] = { #if defined(SQLITE_HAS_CODEC) || defined(SQLITE_ENABLE_CEROD) - { /* zName: */ "activate_extensions", - /* ePragTyp: */ PragTyp_ACTIVATE_EXTENSIONS, - /* ePragFlag: */ 0, - /* iArg: */ 0 }, + {/* zName: */ "activate_extensions", + /* ePragTyp: */ PragTyp_ACTIVATE_EXTENSIONS, + /* ePragFlg: */ 0, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) - { /* zName: */ "application_id", - /* ePragTyp: */ PragTyp_HEADER_VALUE, - /* ePragFlag: */ 0, - /* iArg: */ BTREE_APPLICATION_ID }, + {/* zName: */ "application_id", + /* ePragTyp: */ PragTyp_HEADER_VALUE, + /* ePragFlg: */ PragFlg_Result0, + /* ColNames: */ 0, 0, + /* iArg: */ BTREE_APPLICATION_ID }, #endif #if !defined(SQLITE_OMIT_AUTOVACUUM) - { /* zName: */ "auto_vacuum", - /* ePragTyp: */ PragTyp_AUTO_VACUUM, - /* ePragFlag: */ PragFlag_NeedSchema, - /* iArg: */ 0 }, + {/* zName: */ "auto_vacuum", + /* ePragTyp: */ PragTyp_AUTO_VACUUM, + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) #if !defined(SQLITE_OMIT_AUTOMATIC_INDEX) - { /* zName: */ "automatic_index", - /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlag: */ 0, - /* iArg: */ SQLITE_AutoIndex }, + {/* zName: */ "automatic_index", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_AutoIndex }, #endif #endif - { /* zName: */ "busy_timeout", - /* ePragTyp: */ PragTyp_BUSY_TIMEOUT, - /* ePragFlag: */ 0, - /* iArg: */ 0 }, + {/* zName: */ "busy_timeout", + /* ePragTyp: */ PragTyp_BUSY_TIMEOUT, + /* ePragFlg: */ PragFlg_Result0, + /* ColNames: */ 45, 1, + /* iArg: */ 0 }, #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) - { /* zName: */ "cache_size", - /* ePragTyp: */ PragTyp_CACHE_SIZE, - /* ePragFlag: */ PragFlag_NeedSchema, - /* iArg: */ 0 }, + {/* zName: */ "cache_size", + /* ePragTyp: */ PragTyp_CACHE_SIZE, + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) - { /* zName: */ "cache_spill", - /* ePragTyp: */ PragTyp_CACHE_SPILL, - /* ePragFlag: */ 0, - /* iArg: */ 0 }, + {/* zName: */ "cache_spill", + /* ePragTyp: */ PragTyp_CACHE_SPILL, + /* ePragFlg: */ PragFlg_Result0|PragFlg_SchemaReq, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, #endif - { /* zName: */ "case_sensitive_like", - /* ePragTyp: */ PragTyp_CASE_SENSITIVE_LIKE, - /* ePragFlag: */ 0, - /* iArg: */ 0 }, - { /* zName: */ "cell_size_check", - /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlag: */ 0, - /* iArg: */ SQLITE_CellSizeCk }, + {/* zName: */ "case_sensitive_like", + /* ePragTyp: */ PragTyp_CASE_SENSITIVE_LIKE, + /* ePragFlg: */ 0, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, + {/* zName: */ "cell_size_check", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_CellSizeCk }, #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) - { /* zName: */ "checkpoint_fullfsync", - /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlag: */ 0, - /* iArg: */ SQLITE_CkptFullFSync }, + {/* zName: */ "checkpoint_fullfsync", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_CkptFullFSync }, #endif #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) - { /* zName: */ "collation_list", - /* ePragTyp: */ PragTyp_COLLATION_LIST, - /* ePragFlag: */ 0, - /* iArg: */ 0 }, + {/* zName: */ "collation_list", + /* ePragTyp: */ PragTyp_COLLATION_LIST, + /* ePragFlg: */ PragFlg_Result0, + /* ColNames: */ 28, 2, + /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_COMPILEOPTION_DIAGS) - { /* zName: */ "compile_options", - /* ePragTyp: */ PragTyp_COMPILE_OPTIONS, - /* ePragFlag: */ 0, - /* iArg: */ 0 }, + {/* zName: */ "compile_options", + /* ePragTyp: */ PragTyp_COMPILE_OPTIONS, + /* ePragFlg: */ PragFlg_Result0, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) - { /* zName: */ "count_changes", - /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlag: */ 0, - /* iArg: */ SQLITE_CountRows }, + {/* zName: */ "count_changes", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_CountRows }, #endif #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_OS_WIN - { /* zName: */ "data_store_directory", - /* ePragTyp: */ PragTyp_DATA_STORE_DIRECTORY, - /* ePragFlag: */ 0, - /* iArg: */ 0 }, + {/* zName: */ "data_store_directory", + /* ePragTyp: */ PragTyp_DATA_STORE_DIRECTORY, + /* ePragFlg: */ 0, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) - { /* zName: */ "data_version", - /* ePragTyp: */ PragTyp_HEADER_VALUE, - /* ePragFlag: */ PragFlag_ReadOnly, - /* iArg: */ BTREE_DATA_VERSION }, + {/* zName: */ "data_version", + /* ePragTyp: */ PragTyp_HEADER_VALUE, + /* ePragFlg: */ PragFlg_Result0|PragFlg_ReadOnly, + /* ColNames: */ 0, 0, + /* iArg: */ BTREE_DATA_VERSION }, #endif #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) - { /* zName: */ "database_list", - /* ePragTyp: */ PragTyp_DATABASE_LIST, - /* ePragFlag: */ PragFlag_NeedSchema, - /* iArg: */ 0 }, + {/* zName: */ "database_list", + /* ePragTyp: */ PragTyp_DATABASE_LIST, + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0, + /* ColNames: */ 25, 3, + /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED) - { /* zName: */ "default_cache_size", - /* ePragTyp: */ PragTyp_DEFAULT_CACHE_SIZE, - /* ePragFlag: */ PragFlag_NeedSchema, - /* iArg: */ 0 }, + {/* zName: */ "default_cache_size", + /* ePragTyp: */ PragTyp_DEFAULT_CACHE_SIZE, + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq, + /* ColNames: */ 0, 1, + /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) #if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) - { /* zName: */ "defer_foreign_keys", - /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlag: */ 0, - /* iArg: */ SQLITE_DeferFKs }, + {/* zName: */ "defer_foreign_keys", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_DeferFKs }, #endif #endif #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) - { /* zName: */ "empty_result_callbacks", - /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlag: */ 0, - /* iArg: */ SQLITE_NullCallback }, + {/* zName: */ "empty_result_callbacks", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_NullCallback }, #endif #if !defined(SQLITE_OMIT_UTF16) - { /* zName: */ "encoding", - /* ePragTyp: */ PragTyp_ENCODING, - /* ePragFlag: */ 0, - /* iArg: */ 0 }, + {/* zName: */ "encoding", + /* ePragTyp: */ PragTyp_ENCODING, + /* ePragFlg: */ PragFlg_Result0, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) - { /* zName: */ "foreign_key_check", - /* ePragTyp: */ PragTyp_FOREIGN_KEY_CHECK, - /* ePragFlag: */ PragFlag_NeedSchema, - /* iArg: */ 0 }, + {/* zName: */ "foreign_key_check", + /* ePragTyp: */ PragTyp_FOREIGN_KEY_CHECK, + /* ePragFlg: */ PragFlg_NeedSchema, + /* ColNames: */ 38, 4, + /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_FOREIGN_KEY) - { /* zName: */ "foreign_key_list", - /* ePragTyp: */ PragTyp_FOREIGN_KEY_LIST, - /* ePragFlag: */ PragFlag_NeedSchema, - /* iArg: */ 0 }, + {/* zName: */ "foreign_key_list", + /* ePragTyp: */ PragTyp_FOREIGN_KEY_LIST, + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt, + /* ColNames: */ 30, 8, + /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) #if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) - { /* zName: */ "foreign_keys", - /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlag: */ 0, - /* iArg: */ SQLITE_ForeignKeys }, + {/* zName: */ "foreign_keys", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_ForeignKeys }, #endif #endif #if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) - { /* zName: */ "freelist_count", - /* ePragTyp: */ PragTyp_HEADER_VALUE, - /* ePragFlag: */ PragFlag_ReadOnly, - /* iArg: */ BTREE_FREE_PAGE_COUNT }, + {/* zName: */ "freelist_count", + /* ePragTyp: */ PragTyp_HEADER_VALUE, + /* ePragFlg: */ PragFlg_Result0|PragFlg_ReadOnly, + /* ColNames: */ 0, 0, + /* iArg: */ BTREE_FREE_PAGE_COUNT }, #endif #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) - { /* zName: */ "full_column_names", - /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlag: */ 0, - /* iArg: */ SQLITE_FullColNames }, - { /* zName: */ "fullfsync", - /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlag: */ 0, - /* iArg: */ SQLITE_FullFSync }, + {/* zName: */ "full_column_names", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_FullColNames }, + {/* zName: */ "fullfsync", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_FullFSync }, #endif #if defined(SQLITE_HAS_CODEC) - { /* zName: */ "hexkey", - /* ePragTyp: */ PragTyp_HEXKEY, - /* ePragFlag: */ 0, - /* iArg: */ 0 }, - { /* zName: */ "hexrekey", - /* ePragTyp: */ PragTyp_HEXKEY, - /* ePragFlag: */ 0, - /* iArg: */ 0 }, + {/* zName: */ "hexkey", + /* ePragTyp: */ PragTyp_HEXKEY, + /* ePragFlg: */ 0, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, + {/* zName: */ "hexrekey", + /* ePragTyp: */ PragTyp_HEXKEY, + /* ePragFlg: */ 0, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) #if !defined(SQLITE_OMIT_CHECK) - { /* zName: */ "ignore_check_constraints", - /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlag: */ 0, - /* iArg: */ SQLITE_IgnoreChecks }, + {/* zName: */ "ignore_check_constraints", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_IgnoreChecks }, #endif #endif #if !defined(SQLITE_OMIT_AUTOVACUUM) - { /* zName: */ "incremental_vacuum", - /* ePragTyp: */ PragTyp_INCREMENTAL_VACUUM, - /* ePragFlag: */ PragFlag_NeedSchema, - /* iArg: */ 0 }, + {/* zName: */ "incremental_vacuum", + /* ePragTyp: */ PragTyp_INCREMENTAL_VACUUM, + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_NoColumns, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) - { /* zName: */ "index_info", - /* ePragTyp: */ PragTyp_INDEX_INFO, - /* ePragFlag: */ PragFlag_NeedSchema, - /* iArg: */ 0 }, - { /* zName: */ "index_list", - /* ePragTyp: */ PragTyp_INDEX_LIST, - /* ePragFlag: */ PragFlag_NeedSchema, - /* iArg: */ 0 }, - { /* zName: */ "index_xinfo", - /* ePragTyp: */ PragTyp_INDEX_INFO, - /* ePragFlag: */ PragFlag_NeedSchema, - /* iArg: */ 1 }, + {/* zName: */ "index_info", + /* ePragTyp: */ PragTyp_INDEX_INFO, + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt, + /* ColNames: */ 11, 3, + /* iArg: */ 0 }, + {/* zName: */ "index_list", + /* ePragTyp: */ PragTyp_INDEX_LIST, + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt, + /* ColNames: */ 20, 5, + /* iArg: */ 0 }, + {/* zName: */ "index_xinfo", + /* ePragTyp: */ PragTyp_INDEX_INFO, + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt, + /* ColNames: */ 14, 6, + /* iArg: */ 1 }, #endif #if !defined(SQLITE_OMIT_INTEGRITY_CHECK) - { /* zName: */ "integrity_check", - /* ePragTyp: */ PragTyp_INTEGRITY_CHECK, - /* ePragFlag: */ PragFlag_NeedSchema, - /* iArg: */ 0 }, + {/* zName: */ "integrity_check", + /* ePragTyp: */ PragTyp_INTEGRITY_CHECK, + /* ePragFlg: */ PragFlg_NeedSchema, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) - { /* zName: */ "journal_mode", - /* ePragTyp: */ PragTyp_JOURNAL_MODE, - /* ePragFlag: */ PragFlag_NeedSchema, - /* iArg: */ 0 }, - { /* zName: */ "journal_size_limit", - /* ePragTyp: */ PragTyp_JOURNAL_SIZE_LIMIT, - /* ePragFlag: */ 0, - /* iArg: */ 0 }, + {/* zName: */ "journal_mode", + /* ePragTyp: */ PragTyp_JOURNAL_MODE, + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, + {/* zName: */ "journal_size_limit", + /* ePragTyp: */ PragTyp_JOURNAL_SIZE_LIMIT, + /* ePragFlg: */ PragFlg_Result0|PragFlg_SchemaReq, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, #endif #if defined(SQLITE_HAS_CODEC) - { /* zName: */ "key", - /* ePragTyp: */ PragTyp_KEY, - /* ePragFlag: */ 0, - /* iArg: */ 0 }, + {/* zName: */ "key", + /* ePragTyp: */ PragTyp_KEY, + /* ePragFlg: */ 0, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) - { /* zName: */ "legacy_file_format", - /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlag: */ 0, - /* iArg: */ SQLITE_LegacyFileFmt }, + {/* zName: */ "legacy_file_format", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_LegacyFileFmt }, #endif #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_ENABLE_LOCKING_STYLE - { /* zName: */ "lock_proxy_file", - /* ePragTyp: */ PragTyp_LOCK_PROXY_FILE, - /* ePragFlag: */ 0, - /* iArg: */ 0 }, + {/* zName: */ "lock_proxy_file", + /* ePragTyp: */ PragTyp_LOCK_PROXY_FILE, + /* ePragFlg: */ 0, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, #endif #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) - { /* zName: */ "lock_status", - /* ePragTyp: */ PragTyp_LOCK_STATUS, - /* ePragFlag: */ 0, - /* iArg: */ 0 }, + {/* zName: */ "lock_status", + /* ePragTyp: */ PragTyp_LOCK_STATUS, + /* ePragFlg: */ PragFlg_Result0, + /* ColNames: */ 46, 2, + /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) - { /* zName: */ "locking_mode", - /* ePragTyp: */ PragTyp_LOCKING_MODE, - /* ePragFlag: */ 0, - /* iArg: */ 0 }, - { /* zName: */ "max_page_count", - /* ePragTyp: */ PragTyp_PAGE_COUNT, - /* ePragFlag: */ PragFlag_NeedSchema, - /* iArg: */ 0 }, - { /* zName: */ "mmap_size", - /* ePragTyp: */ PragTyp_MMAP_SIZE, - /* ePragFlag: */ 0, - /* iArg: */ 0 }, - { /* zName: */ "page_count", - /* ePragTyp: */ PragTyp_PAGE_COUNT, - /* ePragFlag: */ PragFlag_NeedSchema, - /* iArg: */ 0 }, - { /* zName: */ "page_size", - /* ePragTyp: */ PragTyp_PAGE_SIZE, - /* ePragFlag: */ 0, - /* iArg: */ 0 }, + {/* zName: */ "locking_mode", + /* ePragTyp: */ PragTyp_LOCKING_MODE, + /* ePragFlg: */ PragFlg_Result0|PragFlg_SchemaReq, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, + {/* zName: */ "max_page_count", + /* ePragTyp: */ PragTyp_PAGE_COUNT, + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, + {/* zName: */ "mmap_size", + /* ePragTyp: */ PragTyp_MMAP_SIZE, + /* ePragFlg: */ 0, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, + {/* zName: */ "page_count", + /* ePragTyp: */ PragTyp_PAGE_COUNT, + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, + {/* zName: */ "page_size", + /* ePragTyp: */ PragTyp_PAGE_SIZE, + /* ePragFlg: */ PragFlg_Result0|PragFlg_SchemaReq, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, #endif #if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_PARSER_TRACE) - { /* zName: */ "parser_trace", - /* ePragTyp: */ PragTyp_PARSER_TRACE, - /* ePragFlag: */ 0, - /* iArg: */ 0 }, + {/* zName: */ "parser_trace", + /* ePragTyp: */ PragTyp_PARSER_TRACE, + /* ePragFlg: */ 0, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) - { /* zName: */ "query_only", - /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlag: */ 0, - /* iArg: */ SQLITE_QueryOnly }, + {/* zName: */ "query_only", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_QueryOnly }, #endif #if !defined(SQLITE_OMIT_INTEGRITY_CHECK) - { /* zName: */ "quick_check", - /* ePragTyp: */ PragTyp_INTEGRITY_CHECK, - /* ePragFlag: */ PragFlag_NeedSchema, - /* iArg: */ 0 }, + {/* zName: */ "quick_check", + /* ePragTyp: */ PragTyp_INTEGRITY_CHECK, + /* ePragFlg: */ PragFlg_NeedSchema, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) - { /* zName: */ "read_uncommitted", - /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlag: */ 0, - /* iArg: */ SQLITE_ReadUncommitted }, - { /* zName: */ "recursive_triggers", - /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlag: */ 0, - /* iArg: */ SQLITE_RecTriggers }, + {/* zName: */ "read_uncommitted", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_ReadUncommitted }, + {/* zName: */ "recursive_triggers", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_RecTriggers }, #endif #if defined(SQLITE_HAS_CODEC) - { /* zName: */ "rekey", - /* ePragTyp: */ PragTyp_REKEY, - /* ePragFlag: */ 0, - /* iArg: */ 0 }, + {/* zName: */ "rekey", + /* ePragTyp: */ PragTyp_REKEY, + /* ePragFlg: */ 0, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) - { /* zName: */ "reverse_unordered_selects", - /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlag: */ 0, - /* iArg: */ SQLITE_ReverseOrder }, + {/* zName: */ "reverse_unordered_selects", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_ReverseOrder }, #endif #if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) - { /* zName: */ "schema_version", - /* ePragTyp: */ PragTyp_HEADER_VALUE, - /* ePragFlag: */ 0, - /* iArg: */ BTREE_SCHEMA_VERSION }, + {/* zName: */ "schema_version", + /* ePragTyp: */ PragTyp_HEADER_VALUE, + /* ePragFlg: */ PragFlg_Result0, + /* ColNames: */ 0, 0, + /* iArg: */ BTREE_SCHEMA_VERSION }, #endif #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) - { /* zName: */ "secure_delete", - /* ePragTyp: */ PragTyp_SECURE_DELETE, - /* ePragFlag: */ 0, - /* iArg: */ 0 }, + {/* zName: */ "secure_delete", + /* ePragTyp: */ PragTyp_SECURE_DELETE, + /* ePragFlg: */ PragFlg_Result0, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) - { /* zName: */ "short_column_names", - /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlag: */ 0, - /* iArg: */ SQLITE_ShortColNames }, + {/* zName: */ "short_column_names", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_ShortColNames }, #endif - { /* zName: */ "shrink_memory", - /* ePragTyp: */ PragTyp_SHRINK_MEMORY, - /* ePragFlag: */ 0, - /* iArg: */ 0 }, - { /* zName: */ "soft_heap_limit", - /* ePragTyp: */ PragTyp_SOFT_HEAP_LIMIT, - /* ePragFlag: */ 0, - /* iArg: */ 0 }, + {/* zName: */ "shrink_memory", + /* ePragTyp: */ PragTyp_SHRINK_MEMORY, + /* ePragFlg: */ 0, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, + {/* zName: */ "soft_heap_limit", + /* ePragTyp: */ PragTyp_SOFT_HEAP_LIMIT, + /* ePragFlg: */ PragFlg_Result0, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) #if defined(SQLITE_DEBUG) - { /* zName: */ "sql_trace", - /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlag: */ 0, - /* iArg: */ SQLITE_SqlTrace }, + {/* zName: */ "sql_trace", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_SqlTrace }, #endif #endif #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) - { /* zName: */ "stats", - /* ePragTyp: */ PragTyp_STATS, - /* ePragFlag: */ PragFlag_NeedSchema, - /* iArg: */ 0 }, + {/* zName: */ "stats", + /* ePragTyp: */ PragTyp_STATS, + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq, + /* ColNames: */ 7, 4, + /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) - { /* zName: */ "synchronous", - /* ePragTyp: */ PragTyp_SYNCHRONOUS, - /* ePragFlag: */ PragFlag_NeedSchema, - /* iArg: */ 0 }, + {/* zName: */ "synchronous", + /* ePragTyp: */ PragTyp_SYNCHRONOUS, + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) - { /* zName: */ "table_info", - /* ePragTyp: */ PragTyp_TABLE_INFO, - /* ePragFlag: */ PragFlag_NeedSchema, - /* iArg: */ 0 }, + {/* zName: */ "table_info", + /* ePragTyp: */ PragTyp_TABLE_INFO, + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt, + /* ColNames: */ 1, 6, + /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) - { /* zName: */ "temp_store", - /* ePragTyp: */ PragTyp_TEMP_STORE, - /* ePragFlag: */ 0, - /* iArg: */ 0 }, - { /* zName: */ "temp_store_directory", - /* ePragTyp: */ PragTyp_TEMP_STORE_DIRECTORY, - /* ePragFlag: */ 0, - /* iArg: */ 0 }, + {/* zName: */ "temp_store", + /* ePragTyp: */ PragTyp_TEMP_STORE, + /* ePragFlg: */ PragFlg_Result0, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, + {/* zName: */ "temp_store_directory", + /* ePragTyp: */ PragTyp_TEMP_STORE_DIRECTORY, + /* ePragFlg: */ 0, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, #endif - { /* zName: */ "threads", - /* ePragTyp: */ PragTyp_THREADS, - /* ePragFlag: */ 0, - /* iArg: */ 0 }, + {/* zName: */ "threads", + /* ePragTyp: */ PragTyp_THREADS, + /* ePragFlg: */ PragFlg_Result0, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, #if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) - { /* zName: */ "user_version", - /* ePragTyp: */ PragTyp_HEADER_VALUE, - /* ePragFlag: */ 0, - /* iArg: */ BTREE_USER_VERSION }, + {/* zName: */ "user_version", + /* ePragTyp: */ PragTyp_HEADER_VALUE, + /* ePragFlg: */ PragFlg_Result0, + /* ColNames: */ 0, 0, + /* iArg: */ BTREE_USER_VERSION }, #endif #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) #if defined(SQLITE_DEBUG) - { /* zName: */ "vdbe_addoptrace", - /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlag: */ 0, - /* iArg: */ SQLITE_VdbeAddopTrace }, - { /* zName: */ "vdbe_debug", - /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlag: */ 0, - /* iArg: */ SQLITE_SqlTrace|SQLITE_VdbeListing|SQLITE_VdbeTrace }, - { /* zName: */ "vdbe_eqp", - /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlag: */ 0, - /* iArg: */ SQLITE_VdbeEQP }, - { /* zName: */ "vdbe_listing", - /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlag: */ 0, - /* iArg: */ SQLITE_VdbeListing }, - { /* zName: */ "vdbe_trace", - /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlag: */ 0, - /* iArg: */ SQLITE_VdbeTrace }, + {/* zName: */ "vdbe_addoptrace", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_VdbeAddopTrace }, + {/* zName: */ "vdbe_debug", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_SqlTrace|SQLITE_VdbeListing|SQLITE_VdbeTrace }, + {/* zName: */ "vdbe_eqp", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_VdbeEQP }, + {/* zName: */ "vdbe_listing", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_VdbeListing }, + {/* zName: */ "vdbe_trace", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_VdbeTrace }, #endif #endif #if !defined(SQLITE_OMIT_WAL) - { /* zName: */ "wal_autocheckpoint", - /* ePragTyp: */ PragTyp_WAL_AUTOCHECKPOINT, - /* ePragFlag: */ 0, - /* iArg: */ 0 }, - { /* zName: */ "wal_checkpoint", - /* ePragTyp: */ PragTyp_WAL_CHECKPOINT, - /* ePragFlag: */ PragFlag_NeedSchema, - /* iArg: */ 0 }, + {/* zName: */ "wal_autocheckpoint", + /* ePragTyp: */ PragTyp_WAL_AUTOCHECKPOINT, + /* ePragFlg: */ 0, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, + {/* zName: */ "wal_checkpoint", + /* ePragTyp: */ PragTyp_WAL_CHECKPOINT, + /* ePragFlg: */ PragFlg_NeedSchema, + /* ColNames: */ 42, 3, + /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) - { /* zName: */ "writable_schema", - /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlag: */ 0, - /* iArg: */ SQLITE_WriteSchema|SQLITE_RecoveryMode }, + {/* zName: */ "writable_schema", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_WriteSchema|SQLITE_RecoveryMode }, #endif }; /* Number of pragmas: 60 on by default, 73 total. */ diff --git a/tool/mkpragmatab.tcl b/tool/mkpragmatab.tcl index 145a365c54..858e0332cf 100644 --- a/tool/mkpragmatab.tcl +++ b/tool/mkpragmatab.tcl @@ -10,6 +10,15 @@ # new pragma in ../src/pragma.c. # +# Flag meanings: +set flagMeaning(NeedSchema) {Force schema load before running} +set flagMeaning(ReadOnly) {Read-only HEADER_VALUE} +set flagMeaning(Result0) {Acts as query when no argument} +set flagMeaning(Result1) {Acts as query when has one argument} +set flagMeaning(SchemaReq) {Schema required - "main" is default} +set flagMeaning(SchemaOpt) {Schema restricts name search if present} +set flagMeaning(NoColumns) {OP_ResultRow called with zero columns} + set pragma_def { NAME: full_column_names TYPE: FLAG @@ -47,6 +56,7 @@ set pragma_def { IF: !defined(SQLITE_OMIT_FLAG_PRAGMAS) NAME: cache_spill + FLAG: Result0 SchemaReq IF: !defined(SQLITE_OMIT_FLAG_PRAGMAS) NAME: reverse_unordered_selects @@ -139,50 +149,56 @@ set pragma_def { ARG: SQLITE_CellSizeCk NAME: default_cache_size - FLAG: NeedSchema + FLAG: NeedSchema Result0 SchemaReq + COLS: cache_size IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED) NAME: page_size + FLAG: Result0 SchemaReq IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS) NAME: secure_delete + FLAG: Result0 IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS) NAME: page_count - FLAG: NeedSchema + FLAG: NeedSchema Result0 SchemaReq IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS) NAME: max_page_count TYPE: PAGE_COUNT - FLAG: NeedSchema + FLAG: NeedSchema Result0 SchemaReq IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS) NAME: locking_mode + FLAG: Result0 SchemaReq IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS) NAME: journal_mode - FLAG: NeedSchema + FLAG: NeedSchema Result0 SchemaReq IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS) NAME: journal_size_limit + FLAG: Result0 SchemaReq IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS) NAME: cache_size - FLAG: NeedSchema + FLAG: NeedSchema Result0 SchemaReq IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS) NAME: mmap_size IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS) NAME: auto_vacuum - FLAG: NeedSchema + FLAG: NeedSchema Result0 SchemaReq IF: !defined(SQLITE_OMIT_AUTOVACUUM) NAME: incremental_vacuum - FLAG: NeedSchema + FLAG: NeedSchema NoColumns IF: !defined(SQLITE_OMIT_AUTOVACUUM) NAME: temp_store + FLAG: Result0 IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS) NAME: temp_store_directory @@ -195,46 +211,56 @@ set pragma_def { IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_ENABLE_LOCKING_STYLE NAME: synchronous - FLAG: NeedSchema + FLAG: NeedSchema Result0 SchemaReq IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS) NAME: table_info - FLAG: NeedSchema + FLAG: NeedSchema Result1 SchemaOpt + COLS: cid name type notnull dflt_value pk IF: !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) NAME: stats - FLAG: NeedSchema + FLAG: NeedSchema Result0 SchemaReq + COLS: table index width height IF: !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) NAME: index_info TYPE: INDEX_INFO ARG: 0 - FLAG: NeedSchema + FLAG: NeedSchema Result1 SchemaOpt + COLS: seqno cid name IF: !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) NAME: index_xinfo TYPE: INDEX_INFO ARG: 1 - FLAG: NeedSchema + FLAG: NeedSchema Result1 SchemaOpt + COLS: seqno cid name desc coll key IF: !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) NAME: index_list - FLAG: NeedSchema + FLAG: NeedSchema Result1 SchemaOpt + COLS: seq name unique origin partial IF: !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) NAME: database_list - FLAG: NeedSchema + FLAG: NeedSchema Result0 + COLS: seq name file IF: !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) NAME: collation_list + FLAG: Result0 + COLS: seq name IF: !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) NAME: foreign_key_list - FLAG: NeedSchema + FLAG: NeedSchema Result1 SchemaOpt + COLS: id seq table from to on_update on_delete match IF: !defined(SQLITE_OMIT_FOREIGN_KEY) NAME: foreign_key_check FLAG: NeedSchema + COLS: table rowid parent fkid IF: !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) NAME: parser_trace @@ -252,6 +278,7 @@ set pragma_def { IF: !defined(SQLITE_OMIT_INTEGRITY_CHECK) NAME: encoding + FLAG: Result0 IF: !defined(SQLITE_OMIT_UTF16) NAME: schema_version @@ -282,10 +309,12 @@ set pragma_def { IF: !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) NAME: compile_options + FLAG: Result0 IF: !defined(SQLITE_OMIT_COMPILEOPTION_DIAGS) NAME: wal_checkpoint FLAG: NeedSchema + COLS: busy log checkpointed IF: !defined(SQLITE_OMIT_WAL) NAME: wal_autocheckpoint @@ -294,8 +323,12 @@ set pragma_def { NAME: shrink_memory NAME: busy_timeout + FLAG: Result0 + COLS: timeout NAME: lock_status + FLAG: Result0 + COLS: database status IF: defined(SQLITE_DEBUG) || defined(SQLITE_TEST) NAME: key @@ -315,8 +348,10 @@ set pragma_def { IF: defined(SQLITE_HAS_CODEC) || defined(SQLITE_ENABLE_CEROD) NAME: soft_heap_limit + FLAG: Result0 NAME: threads + FLAG: Result0 } # Open the output file @@ -336,15 +371,29 @@ set name {} set type {} set if {} set flags {} +set cols {} +set cols_list {} set arg 0 proc record_one {} { - global name type if arg allbyname typebyif flags + global name type if arg allbyname typebyif flags cols allcols + global cols_list colUsedBy if {$name==""} return - set allbyname($name) [list $type $arg $if $flags] + if {$cols!=""} { + if {![info exists allcols($cols)]} { + lappend cols_list $cols + set allcols($cols) [llength $cols_list] + } + set cx $allcols($cols) + lappend colUsedBy($cols) $name + } else { + set cx 0 + } + set allbyname($name) [list $type $arg $if $flags $cx] set name {} set type {} set if {} set flags {} + set cols {} set arg 0 } foreach line [split $pragma_def \n] { @@ -358,8 +407,16 @@ foreach line [split $pragma_def \n] { set type [string toupper $val] } elseif {$id=="TYPE"} { set type $val + if {$type=="FLAG"} { + lappend flags Result0 NoColumns + } + if {$type=="HEADER_VALUE"} { + lappend flags Result0 + } } elseif {$id=="ARG"} { set arg $val + } elseif {$id=="COLS"} { + set cols $val } elseif {$id=="IF"} { lappend if $val } elseif {$id=="FLAG"} { @@ -378,6 +435,7 @@ set allnames [lsort [array names allbyname]] # omit in default builds (defined(SQLITE_DEBUG) and defined(SQLITE_HAS_CODEC)) # at the end. # +puts $fd "\n/* The various pragma types */" set pnum 0 foreach name $allnames { set type [lindex $allbyname($name) 0] @@ -407,25 +465,57 @@ foreach name $allnames { # Generate #defines for flags # +puts $fd "\n/* Property flags associated with various pragma. */" set fv 1 foreach f [lsort [array names allflags]] { - puts $fd [format {#define PragFlag_%-20s 0x%02x} $f $fv] + puts $fd [format {#define PragFlg_%-10s 0x%02x /* %s */} \ + $f $fv $flagMeaning($f)] set fv [expr {$fv*2}] } +# Generate the array of column names used by pragmas that act like +# queries. +# +puts $fd "\n/* Names of columns for pragmas that return multi-column result" +puts $fd "** or that return single-column results where the name of the" +puts $fd "** result column is different from the name of the pragma\n*/" +puts $fd "static const char *const pragCName\[\] = {" +set offset 0 +foreach cols $cols_list { + set cols_offset($allcols($cols)) $offset + set ub " /* Used by: $colUsedBy($cols) */" + foreach c $cols { + puts $fd [format " /* %3d */ %-14s%s" $offset \"$c\", $ub] + set ub "" + incr offset + } +} +puts $fd "\175;" + # Generate the lookup table # +puts $fd "\n/* Definitions of all built-in pragmas */" puts $fd "static const struct sPragmaNames \173" -puts $fd " const char *const zName; /* Name of pragma */" -puts $fd " u8 ePragTyp; /* PragTyp_XXX value */" -puts $fd " u8 mPragFlag; /* Zero or more PragFlag_XXX values */" -puts $fd " u32 iArg; /* Extra argument */" +puts $fd " const char *const zName; /* Name of pragma */" +puts $fd " u8 ePragTyp; /* PragTyp_XXX value */" +puts $fd " u8 mPragFlg; /* Zero or more PragFlg_XXX values */" +puts $fd { u8 iPragCName; /* Start of column names in pragCName[] */} +puts $fd " u8 nPragCName; \ +/* Num of col names. 0 means use pragma name */" +puts $fd " u32 iArg; /* Extra argument */" puts $fd "\175 aPragmaNames\[\] = \173" set current_if {} set spacer [format { %26s } {}] foreach name $allnames { - foreach {type arg if flag} $allbyname($name) break + foreach {type arg if flag cx} $allbyname($name) break + if {$cx==0} { + set cy 0 + set nx 0 + } else { + set cy $cols_offset($cx) + set nx [llength [lindex $cols_list [expr {$cx-1}]]] + } if {$if!=$current_if} { if {$current_if!=""} { foreach this_if $current_if { @@ -443,12 +533,13 @@ foreach name $allnames { if {$flag==""} { set flagx "0" } else { - set flagx PragFlag_[join $flag {|PragFlag_}] + set flagx PragFlg_[join $flag {|PragFlg_}] } - puts $fd " \173 /* zName: */ \"$name\"," - puts $fd " /* ePragTyp: */ PragTyp_$type," - puts $fd " /* ePragFlag: */ $flagx," - puts $fd " /* iArg: */ $arg \175," + puts $fd " \173/* zName: */ \"$name\"," + puts $fd " /* ePragTyp: */ PragTyp_$type," + puts $fd " /* ePragFlg: */ $flagx," + puts $fd " /* ColNames: */ $cy, $nx," + puts $fd " /* iArg: */ $arg \175," } if {$current_if!=""} { foreach this_if $current_if { From 35a1895990d8267ed1b99440edcca0fe7e0a71d0 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 15 Dec 2016 18:59:14 +0000 Subject: [PATCH 1089/1484] Do exponential rather than linear expansion of the SrcList.a array when appending new elements, to reduce the number of malloc() calls. FossilOrigin-Name: 4e3749127e7249f46e17bfabc614b0876f60565a --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/build.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 82049f338e..b183400c02 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Refactor\sthe\sTable.nRef\sfield\sas\sTable.nTabRef\sfor\seasier\sgrepping. -D 2016-12-14T14:07:35.372 +C Do\sexponential\srather\sthan\slinear\sexpansion\sof\sthe\sSrcList.a\sarray\swhen\s\nappending\snew\selements,\sto\sreduce\sthe\snumber\sof\smalloc()\scalls. +D 2016-12-15T18:59:14.960 F Makefile.in c194b58fe00c370a48ac6ae6945e92a7781db1c8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -334,7 +334,7 @@ F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 F src/btree.c b2055dff0b94e03eaad48a760984a2d8e39244e6 F src/btree.h 2349a588abcd7e0c04f984e15c5c777b61637583 F src/btreeInt.h 10c4b77c2fb399580babbcc7cf652ac10dba796e -F src/build.c e2b32766847eb16d4314c99067571ae08b888dfe +F src/build.c 4c7952b6d4fd68e3d25d4b05a06d65a496c0f7c8 F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 9f2296a4e5d26ebf0e0d95a0af4628f1ea694e7a @@ -1536,7 +1536,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d08b72c38ff6fae6ddf7dc84a54f6d7189876289 -R ee18812138ebcbd59cf246eeb625fa00 +P 9cae4c2e300e20304ced0dc8c1415c4922185928 +R 9770eba5fe5acae93ed970f661562070 U drh -Z c1d49b9032916157524a152005703654 +Z 9a292fcbff4c94ddef7a536330d555ac diff --git a/manifest.uuid b/manifest.uuid index 1ac27241a3..c55edda4a5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9cae4c2e300e20304ced0dc8c1415c4922185928 \ No newline at end of file +4e3749127e7249f46e17bfabc614b0876f60565a \ No newline at end of file diff --git a/src/build.c b/src/build.c index 43e293e7c6..44c1d67ee0 100644 --- a/src/build.c +++ b/src/build.c @@ -3658,7 +3658,7 @@ SrcList *sqlite3SrcListEnlarge( /* Allocate additional space if needed */ if( (u32)pSrc->nSrc+nExtra>pSrc->nAlloc ){ SrcList *pNew; - int nAlloc = pSrc->nSrc+nExtra; + int nAlloc = pSrc->nSrc*2+nExtra; int nGot; pNew = sqlite3DbRealloc(db, pSrc, sizeof(*pSrc) + (nAlloc-1)*sizeof(pSrc->a[0]) ); From 2fcc1590c4f573e7e5787666a358627ecd2b343b Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 15 Dec 2016 20:59:03 +0000 Subject: [PATCH 1090/1484] Code to automatically create eponymous virtual tables for read-only pragmas. Compiles, but does not yet work. FossilOrigin-Name: 988a61e8b03f302c69d11898d1ea95f002cba1a5 --- manifest | 28 ++-- manifest.uuid | 2 +- src/build.c | 3 + src/pragma.c | 340 ++++++++++++++++++++++++++++++++++++++++--- src/pragma.h | 5 +- src/sqliteInt.h | 10 ++ src/vtab.c | 56 ++++--- tool/mkpragmatab.tcl | 5 +- 8 files changed, 391 insertions(+), 58 deletions(-) diff --git a/manifest b/manifest index a02ef53983..843ef1cfc5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Do\smore\spragma\sprocessing\sfrom\stables\srather\sthan\sin-line\scode. -D 2016-12-15T16:01:17.867 +C Code\sto\sautomatically\screate\seponymous\svirtual\stables\sfor\sread-only\spragmas.\nCompiles,\sbut\sdoes\snot\syet\swork. +D 2016-12-15T20:59:03.895 F Makefile.in c194b58fe00c370a48ac6ae6945e92a7781db1c8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -334,7 +334,7 @@ F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 F src/btree.c b2055dff0b94e03eaad48a760984a2d8e39244e6 F src/btree.h 2349a588abcd7e0c04f984e15c5c777b61637583 F src/btreeInt.h 10c4b77c2fb399580babbcc7cf652ac10dba796e -F src/build.c e2b32766847eb16d4314c99067571ae08b888dfe +F src/build.c 43c9c2bde195267364e92833b36e78f6c5afc66a F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 9f2296a4e5d26ebf0e0d95a0af4628f1ea694e7a @@ -381,8 +381,8 @@ F src/parse.y 29153738a7322054359320eb00b5a4cd44389f20 F src/pcache.c 51070ec9b8251bbf9c6ea3d35fd96a458752929e F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 F src/pcache1.c e3967219b2a92b9edcb9324a4ba75009090d3953 -F src/pragma.c 78f85cf6c668b084702bb305bd4980b4813afa70 -F src/pragma.h 7dff1007ade3aabf8b2e467107b4506940c0ad86 +F src/pragma.c b2421f23af876cb7a2f9aca09e803e207a4750f1 +F src/pragma.h f9b221b2c8949ea941dbee49934299e4ed5af41c F src/prepare.c b1140c3d0cf59bc85ace00ce363153041b424b7a F src/printf.c f94da4935d1dd25420ac50c6745db1deb35e07c1 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 @@ -393,7 +393,7 @@ F src/shell.c f1c7fde7a83421e6ed620df41d200674a2327e65 F src/sqlite.h.in e8e2d108d82647f0a812fdb74accf91c1ec08ddc F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae -F src/sqliteInt.h 657a892d885253768c82f1e04e8053468b13cb6a +F src/sqliteInt.h adbe80409c2926d91e5485789e5bf69313cd54b0 F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 @@ -464,7 +464,7 @@ F src/vdbeblob.c f4f98ea672b242f807c08c92c7faaa79e5091b65 F src/vdbemem.c d3fd85b7b7ef3eb75de29c6d7e1d10d3ca78b4fd F src/vdbesort.c bb34eed4fb52e11ac037dccea4ee3190594c7f9e F src/vdbetrace.c 41963d5376f0349842b5fc4aaaaacd7d9cdc0834 -F src/vtab.c 2d5db3fd68c41c5a7476e43e79eb54181fa01713 +F src/vtab.c 24f3412e26511701cda951a32b7b33b693cdf450 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 40c543f0a2195d1b0dc88ef12142bea690009344 F src/wal.h 06b2a0b599cc0f53ea97f497cf8c6b758c999f71 @@ -1474,7 +1474,7 @@ F tool/mkmsvcmin.tcl 2f12f7fa8858bbe61cf81820a2da96c79ed1ca8d F tool/mkopcodec.tcl d1b6362bd3aa80d5520d4d6f3765badf01f6c43c F tool/mkopcodeh.tcl a01d2c1d8a6205b03fc635adf3735b4c523befd3 F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e -F tool/mkpragmatab.tcl 999d7da2b77e83f24de01c3c8f90dc66411ce6d2 +F tool/mkpragmatab.tcl a30ee93515135466fc49ae881f75da07ebcafd19 F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 F tool/mksqlite3c-noext.tcl fef88397668ae83166735c41af99d79f56afaabb F tool/mksqlite3c.tcl 06b2e6a0f21cc0a5d70fbbd136b3e0a96470645e @@ -1536,10 +1536,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 9cae4c2e300e20304ced0dc8c1415c4922185928 -R d8e6c9c98262f0aea48f528b484866a4 -T *branch * table-driven-pragma -T *sym-table-driven-pragma * -T -sym-trunk * +P a88ca3524b97f296dffc68335466b3767a681747 +R 23c19e6ab9e9f56bda2263bb45958620 +T *branch * pragma-as-vtab +T *sym-pragma-as-vtab * +T -sym-table-driven-pragma * U drh -Z 7260d2e6fdce7485555b88e6d856ce9f +Z 91a2192a11c3bfa409136450c9378cb1 diff --git a/manifest.uuid b/manifest.uuid index 206d8471d0..24ee5e50c2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a88ca3524b97f296dffc68335466b3767a681747 \ No newline at end of file +988a61e8b03f302c69d11898d1ea95f002cba1a5 \ No newline at end of file diff --git a/src/build.c b/src/build.c index 43e293e7c6..8cc62eb9c8 100644 --- a/src/build.c +++ b/src/build.c @@ -352,6 +352,9 @@ Table *sqlite3LocateTable( ** CREATE, then check to see if it is the name of an virtual table that ** can be an eponymous virtual table. */ Module *pMod = (Module*)sqlite3HashFind(&pParse->db->aModule, zName); + if( pMod==0 && sqlite3_strnicmp(zName, "pragma_", 7)==0 ){ + pMod = sqlite3PragmaVtabRegister(pParse->db, zName); + } if( pMod && sqlite3VtabEponymousTableInit(pParse, pMod) ){ return pMod->pEpoTab; } diff --git a/src/pragma.c b/src/pragma.c index 7faf937001..0018714c25 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -166,8 +166,8 @@ static int changeTempStorage(Parse *pParse, const char *zStorageType){ ** Set result column names for a pragma. */ static void setPragmaResultColumnNames( - Vdbe *v, /* The query under construction */ - const struct sPragmaNames *pPragma /* The pragma */ + Vdbe *v, /* The query under construction */ + const PragmaName *pPragma /* The pragma */ ){ u8 n = pPragma->nPragCName; sqlite3VdbeSetNumCols(v, n==0 ? 1 : n); @@ -275,6 +275,26 @@ const char *sqlite3JournalModename(int eMode){ return azModeName[eMode]; } +/* +** Locate a pragma in the aPragmaName[] array. +*/ +static const PragmaName *pragmaLocate(const char *zName){ + int upr, lwr, mid, rc; + lwr = 0; + upr = ArraySize(aPragmaName)-1; + while( lwr<=upr ){ + mid = (lwr+upr)/2; + rc = sqlite3_stricmp(zName, aPragmaName[mid].zName); + if( rc==0 ) break; + if( rc<0 ){ + upr = mid - 1; + }else{ + lwr = mid + 1; + } + } + return lwr>upr ? 0 : &aPragmaName[mid]; +} + /* ** Process a pragma statement. ** @@ -303,12 +323,11 @@ void sqlite3Pragma( Token *pId; /* Pointer to token */ char *aFcntl[4]; /* Argument to SQLITE_FCNTL_PRAGMA */ int iDb; /* Database index for */ - int lwr, upr, mid = 0; /* Binary search bounds */ int rc; /* return value form SQLITE_FCNTL_PRAGMA */ sqlite3 *db = pParse->db; /* The database connection */ Db *pDb; /* The specific database being pragmaed */ Vdbe *v = sqlite3GetVdbe(pParse); /* Prepared statement */ - const struct sPragmaNames *pPragma; + const PragmaName *pPragma; /* The pragma */ if( v==0 ) return; sqlite3VdbeRunOnlyOnce(v); @@ -380,20 +399,8 @@ void sqlite3Pragma( } /* Locate the pragma in the lookup table */ - lwr = 0; - upr = ArraySize(aPragmaNames)-1; - while( lwr<=upr ){ - mid = (lwr+upr)/2; - rc = sqlite3_stricmp(zLeft, aPragmaNames[mid].zName); - if( rc==0 ) break; - if( rc<0 ){ - upr = mid - 1; - }else{ - lwr = mid + 1; - } - } - if( lwr>upr ) goto pragma_out; - pPragma = &aPragmaNames[mid]; + pPragma = pragmaLocate(zLeft); + if( pPragma==0 ) goto pragma_out; /* Make sure the database schema is loaded if the pragma requires that */ if( (pPragma->mPragFlg & PragFlg_NeedSchema)!=0 ){ @@ -1950,5 +1957,302 @@ pragma_out: sqlite3DbFree(db, zLeft); sqlite3DbFree(db, zRight); } +#ifndef SQLITE_OMIT_VIRTUALTABLE +/***************************************************************************** +** Implementation of an eponymous virtual table that runs a pragma. +** +*/ +typedef struct PragmaVtab PragmaVtab; +typedef struct PragmaVtabCursor PragmaVtabCursor; +struct PragmaVtab { + sqlite3_vtab base; /* Base class. Must be first */ + sqlite3 *db; /* The database connection to which it belongs */ + const PragmaName *pName; /* Name of the pragma */ + u8 nHidden; /* Number of hidden columns */ + u8 iHidden; /* Index of the first hidden column */ +}; +struct PragmaVtabCursor { + sqlite3_vtab_cursor base; /* Base class. Must be first */ + sqlite3_stmt *pPragma; /* The pragma statement to run */ + sqlite_int64 iRowid; /* Current rowid */ + char *azArg[2]; /* Value of the argument and schema */ +}; + +/* +** Pragma virtual table module xConnect method. +*/ +static int pragmaVtabConnect( + sqlite3 *db, + void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVtab, + char **pzErr +){ + const PragmaName *pPragma = (const PragmaName*)pAux; + PragmaVtab *pTab = 0; + int rc; + int i, j; + char cSep = '('; + StrAccum acc; + char zBuf[200]; + + sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0); + sqlite3StrAccumAppendAll(&acc, "CREATE TABLE x"); + for(i=0, j=pPragma->iPragCName; inPragCName; i++, j++){ + sqlite3StrAccumAppend(&acc, &cSep, 1); + sqlite3StrAccumAppendAll(&acc, pragCName[j]); + cSep = ','; + } + j = 0; + if( pPragma->mPragFlg & PragFlg_Result1 ){ + sqlite3StrAccumAppendAll(&acc, ",arg HIDDEN"); + j++; + } + if( pPragma->mPragFlg & (PragFlg_SchemaOpt|PragFlg_SchemaReq) ){ + sqlite3StrAccumAppendAll(&acc, ",schema HIDDEN"); + j++; + } + sqlite3StrAccumAppend(&acc, ")", 1); + sqlite3StrAccumFinish(&acc); + assert( strlen(zBuf) < sizeof(zBuf)-1 ); + rc = sqlite3_declare_vtab(db, zBuf); + if( rc==SQLITE_OK ){ + pTab = (PragmaVtab*)sqlite3_malloc(sizeof(PragmaVtab)); + if( pTab==0 ){ + rc = SQLITE_NOMEM; + }else{ + memset(pTab, 0, sizeof(PragmaVtab)); + pTab->pName = pPragma; + pTab->db = db; + pTab->iHidden = i; + pTab->nHidden = j; + } + }else{ + *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db)); + } + + *ppVtab = (sqlite3_vtab*)pTab; + return rc; +} + +/* +** Pragma virtual table module xDisconnect method. +*/ +static int pragmaVtabDisconnect(sqlite3_vtab *pVtab){ + PragmaVtab *pTab = (PragmaVtab*)pVtab; + sqlite3_free(pTab); + return SQLITE_OK; +} + +/* Figure out the best index to use to search a pragma virtual table. +** +** There are not really any index choices. But we want to encourage the +** query planner to give == constraints on as many hidden parameters as +** possible, and especially on the first hidden parameter. So return a +** high cost if hidden parameters are unconstrained. +*/ +static int pragmaVtabBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ + PragmaVtab *pTab = (PragmaVtab*)tab; + const struct sqlite3_index_constraint *pConstraint; + int i, j; + int seen[2]; + + if( pTab->nHidden==0 ){ return SQLITE_OK; } + pConstraint = pIdxInfo->aConstraint; + seen[0] = 0; + seen[1] = 0; + for(i=0; inConstraint; i++, pConstraint++){ + if( pConstraint->usable==0 ) continue; + if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue; + if( pConstraint->iColumn < pTab->iHidden ) continue; + j = pConstraint->iColumn - pTab->iHidden; + assert( j < 2 ); + if( seen[j] ) continue; + seen[j] = i; + } + if( seen[0]==0 ){ + pIdxInfo->estimatedCost = (double)2147483647; + pIdxInfo->estimatedRows = 2147483647; + return SQLITE_OK; + } + j = seen[0]; + pIdxInfo->aConstraintUsage[j].argvIndex = 1; + pIdxInfo->aConstraintUsage[j].omit = 1; + if( seen[1]==0 ) return SQLITE_OK; + pIdxInfo->estimatedCost = (double)20; + pIdxInfo->estimatedRows = 20; + j = seen[1]; + pIdxInfo->aConstraintUsage[j].argvIndex = 2; + pIdxInfo->aConstraintUsage[j].omit = 1; + return SQLITE_OK; +} + +/* Create a new cursor for the pragma virtual table */ +static int pragmaVtabOpen(sqlite3_vtab *pVtab, sqlite3_vtab_cursor **ppCursor){ + PragmaVtabCursor *pCsr; + pCsr = (PragmaVtabCursor*)sqlite3_malloc(sizeof(*pCsr)); + if( pCsr==0 ) return SQLITE_NOMEM; + memset(pCsr, 0, sizeof(PragmaVtabCursor)); + pCsr->base.pVtab = pVtab; + *ppCursor = &pCsr->base; + return SQLITE_OK; +} + +/* Clear all content from pragma virtual table cursor. */ +static void pragmaVtabCursorClear(PragmaVtabCursor *pCsr){ + int i; + sqlite3_finalize(pCsr->pPragma); + pCsr->pPragma = 0; + for(i=0; iazArg); i++){ + sqlite3_free(pCsr->azArg[i]); + pCsr->azArg[i] = 0; + } +} + +/* Close a pragma virtual table cursor */ +static int pragmaVtabClose(sqlite3_vtab_cursor *cur){ + PragmaVtabCursor *pCsr = (PragmaVtabCursor*)cur; + pragmaVtabCursorClear(pCsr); + return SQLITE_OK; +} + +/* Advance the pragma virtual table cursor to the next row */ +static int pragmaVtabNext(sqlite3_vtab_cursor *pVtabCursor){ + PragmaVtabCursor *pCsr = (PragmaVtabCursor*)pVtabCursor; + int rc = SQLITE_OK; + + /* Increment the xRowid value */ + pCsr->iRowid++; + if( pCsr->pPragma ){ + if( SQLITE_ROW!=sqlite3_step(pCsr->pPragma) ){ + rc = sqlite3_finalize(pCsr->pPragma); + pCsr->pPragma = 0; + pragmaVtabCursorClear(pCsr); + } + } + return rc; +} + +/* +** Pragma virtual table module xFilter method. +*/ +static int pragmaVtabFilter( + sqlite3_vtab_cursor *pVtabCursor, + int idxNum, const char *idxStr, + int argc, sqlite3_value **argv +){ + PragmaVtabCursor *pCsr = (PragmaVtabCursor*)pVtabCursor; + PragmaVtab *pTab = (PragmaVtab*)(pVtabCursor->pVtab); + int rc; + int i; + StrAccum acc; + char *zSql; + + pragmaVtabCursorClear(pCsr); + for(i=0; iazArg) ); + pCsr->azArg[i] = sqlite3_mprintf("%s", sqlite3_value_text(argv[i])); + if( pCsr->azArg[i]==0 ){ + return SQLITE_NOMEM; + } + } + sqlite3StrAccumInit(&acc, 0, 0, 0, pTab->db->aLimit[SQLITE_MAX_SQL_LENGTH]); + sqlite3StrAccumAppendAll(&acc, "PRAGMA "); + if( pCsr->azArg[1] ){ + sqlite3XPrintf(&acc, "%Q.", pCsr->azArg[1]); + } + sqlite3StrAccumAppendAll(&acc, pTab->pName->zName); + if( pCsr->azArg[0] ){ + sqlite3XPrintf(&acc, "=%Q", pCsr->azArg[0]); + } + zSql = sqlite3StrAccumFinish(&acc); + if( zSql==0 ) return SQLITE_NOMEM; + rc = sqlite3_prepare_v2(pTab->db, zSql, -1, &pCsr->pPragma, 0); + sqlite3_free(zSql); + if( rc!=SQLITE_OK ){ + pTab->base.zErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(pTab->db)); + return rc; + } + return pragmaVtabNext(pVtabCursor); +} + +/* +** Pragma virtual table module xEof method. +*/ +static int pragmaVtabEof(sqlite3_vtab_cursor *pVtabCursor){ + PragmaVtabCursor *pCsr = (PragmaVtabCursor*)pVtabCursor; + return (pCsr->pPragma==0); +} + +/* The xColumn method simply returns the corresponding column from +** the PRAGMA. +*/ +static int pragmaVtabColumn( + sqlite3_vtab_cursor *pVtabCursor, + sqlite3_context *ctx, + int i +){ + PragmaVtabCursor *pCsr = (PragmaVtabCursor*)pVtabCursor; + PragmaVtab *pTab = (PragmaVtab*)(pVtabCursor->pVtab); + if( iiHidden ){ + sqlite3_result_value(ctx, sqlite3_column_value(pCsr->pPragma, i)); + }else{ + sqlite3_result_text(ctx, pCsr->azArg[i-pTab->iHidden],-1,SQLITE_TRANSIENT); + } + return SQLITE_OK; +} + +/* +** Pragma virtual table module xRowid method. +*/ +static int pragmaVtabRowid(sqlite3_vtab_cursor *pVtabCursor, sqlite_int64 *p){ + PragmaVtabCursor *pCsr = (PragmaVtabCursor*)pVtabCursor; + *p = pCsr->iRowid; + return SQLITE_OK; +} + +/* The pragma virtual table object */ +static const sqlite3_module pragmaVtabModule = { + 0, /* iVersion */ + 0, /* xCreate - create a table */ + pragmaVtabConnect, /* xConnect - connect to an existing table */ + pragmaVtabBestIndex, /* xBestIndex - Determine search strategy */ + pragmaVtabDisconnect, /* xDisconnect - Disconnect from a table */ + 0, /* xDestroy - Drop a table */ + pragmaVtabOpen, /* xOpen - open a cursor */ + pragmaVtabClose, /* xClose - close a cursor */ + pragmaVtabFilter, /* xFilter - configure scan constraints */ + pragmaVtabNext, /* xNext - advance a cursor */ + pragmaVtabEof, /* xEof */ + pragmaVtabColumn, /* xColumn - read data */ + pragmaVtabRowid, /* xRowid - read data */ + 0, /* xUpdate - write data */ + 0, /* xBegin - begin transaction */ + 0, /* xSync - sync transaction */ + 0, /* xCommit - commit transaction */ + 0, /* xRollback - rollback transaction */ + 0, /* xFindFunction - function overloading */ + 0, /* xRename - rename the table */ + 0, /* xSavepoint */ + 0, /* xRelease */ + 0 /* xRollbackTo */ +}; + +/* +** Check to see if zTabName is really the name of a pragma. If it is, +** then register an eponymous virtual table for that pragma and return +** a pointer to the Module object for the new virtual table. +*/ +Module *sqlite3PragmaVtabRegister(sqlite3 *db, const char *zName){ + const PragmaName *pName; + assert( sqlite3_strnicmp(zName, "pragma_", 7)==0 ); + pName = pragmaLocate(zName+7); + if( pName==0 ) return 0; + if( (pName->mPragFlg & (PragFlg_Result0|PragFlg_Result1))==0 ) return 0; + assert( sqlite3HashFind(&db->aModule, zName)==0 ); + return sqlite3VtabCreateModule(db, zName, &pragmaVtabModule, 0, 0); +} + +#endif /* SQLITE_OMIT_VIRTUALTABLE */ #endif /* SQLITE_OMIT_PRAGMA */ diff --git a/src/pragma.h b/src/pragma.h index 1ae9fe7bc5..b854b4f38c 100644 --- a/src/pragma.h +++ b/src/pragma.h @@ -114,14 +114,15 @@ static const char *const pragCName[] = { }; /* Definitions of all built-in pragmas */ -static const struct sPragmaNames { +typedef struct PragmaName { const char *const zName; /* Name of pragma */ u8 ePragTyp; /* PragTyp_XXX value */ u8 mPragFlg; /* Zero or more PragFlg_XXX values */ u8 iPragCName; /* Start of column names in pragCName[] */ u8 nPragCName; /* Num of col names. 0 means use pragma name */ u32 iArg; /* Extra argument */ -} aPragmaNames[] = { +} PragmaName; +static const PragmaName aPragmaName[] = { #if defined(SQLITE_HAS_CODEC) || defined(SQLITE_ENABLE_CEROD) {/* zName: */ "activate_extensions", /* ePragTyp: */ PragTyp_ACTIVATE_EXTENSIONS, diff --git a/src/sqliteInt.h b/src/sqliteInt.h index c30b38b731..07156092c9 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3563,6 +3563,9 @@ u32 sqlite3ExprListFlags(const ExprList*); int sqlite3Init(sqlite3*, char**); int sqlite3InitCallback(void*, int, char**, char**); void sqlite3Pragma(Parse*,Token*,Token*,Token*,int); +#ifndef SQLITE_OMIT_VIRTUALTABLE +Module *sqlite3PragmaVtabRegister(sqlite3*,const char *zName); +#endif void sqlite3ResetAllSchemasOfConnection(sqlite3*); void sqlite3ResetOneSchema(sqlite3*,int); void sqlite3CollapseDatabaseArray(sqlite3*); @@ -4077,6 +4080,13 @@ void sqlite3AutoLoadExtensions(sqlite3*); int sqlite3VtabSavepoint(sqlite3 *, int, int); void sqlite3VtabImportErrmsg(Vdbe*, sqlite3_vtab*); VTable *sqlite3GetVTable(sqlite3*, Table*); + Module *sqlite3VtabCreateModule( + sqlite3*, + const char*, + const sqlite3_module*, + void*, + void(*)(void*) + ); # define sqlite3VtabInSync(db) ((db)->nVTrans>0 && (db)->aVTrans==0) #endif int sqlite3VtabEponymousTableInit(Parse*,Module*); diff --git a/src/vtab.c b/src/vtab.c index 2531155546..ebdd6b5dca 100644 --- a/src/vtab.c +++ b/src/vtab.c @@ -28,6 +28,40 @@ struct VtabCtx { int bDeclared; /* True after sqlite3_declare_vtab() is called */ }; +/* +** Construct and install a Module object for a virtual table. When this +** routine is called, it is guaranteed that all appropriate locks are held +** and the module is not already part of the connection. +*/ +Module *sqlite3VtabCreateModule( + sqlite3 *db, /* Database in which module is registered */ + const char *zName, /* Name assigned to this module */ + const sqlite3_module *pModule, /* The definition of the module */ + void *pAux, /* Context pointer for xCreate/xConnect */ + void (*xDestroy)(void *) /* Module destructor function */ +){ + Module *pMod; + int nName = sqlite3Strlen30(zName); + pMod = (Module *)sqlite3DbMallocRawNN(db, sizeof(Module) + nName + 1); + if( pMod ){ + Module *pDel; + char *zCopy = (char *)(&pMod[1]); + memcpy(zCopy, zName, nName+1); + pMod->zName = zCopy; + pMod->pModule = pModule; + pMod->pAux = pAux; + pMod->xDestroy = xDestroy; + pMod->pEpoTab = 0; + pDel = (Module *)sqlite3HashInsert(&db->aModule,zCopy,(void*)pMod); + assert( pDel==0 || pDel==pMod ); + if( pDel ){ + sqlite3OomFault(db); + sqlite3DbFree(db, pDel); + } + } + return pMod; +} + /* ** The actual function that does the work of creating a new module. ** This function implements the sqlite3_create_module() and @@ -41,35 +75,15 @@ static int createModule( void (*xDestroy)(void *) /* Module destructor function */ ){ int rc = SQLITE_OK; - int nName; sqlite3_mutex_enter(db->mutex); - nName = sqlite3Strlen30(zName); if( sqlite3HashFind(&db->aModule, zName) ){ rc = SQLITE_MISUSE_BKPT; }else{ - Module *pMod; - pMod = (Module *)sqlite3DbMallocRawNN(db, sizeof(Module) + nName + 1); - if( pMod ){ - Module *pDel; - char *zCopy = (char *)(&pMod[1]); - memcpy(zCopy, zName, nName+1); - pMod->zName = zCopy; - pMod->pModule = pModule; - pMod->pAux = pAux; - pMod->xDestroy = xDestroy; - pMod->pEpoTab = 0; - pDel = (Module *)sqlite3HashInsert(&db->aModule,zCopy,(void*)pMod); - assert( pDel==0 || pDel==pMod ); - if( pDel ){ - sqlite3OomFault(db); - sqlite3DbFree(db, pDel); - } - } + (void)sqlite3VtabCreateModule(db, zName, pModule, pAux, xDestroy); } rc = sqlite3ApiExit(db, rc); if( rc!=SQLITE_OK && xDestroy ) xDestroy(pAux); - sqlite3_mutex_leave(db->mutex); return rc; } diff --git a/tool/mkpragmatab.tcl b/tool/mkpragmatab.tcl index 858e0332cf..d9e100366c 100644 --- a/tool/mkpragmatab.tcl +++ b/tool/mkpragmatab.tcl @@ -495,7 +495,7 @@ puts $fd "\175;" # Generate the lookup table # puts $fd "\n/* Definitions of all built-in pragmas */" -puts $fd "static const struct sPragmaNames \173" +puts $fd "typedef struct PragmaName \173" puts $fd " const char *const zName; /* Name of pragma */" puts $fd " u8 ePragTyp; /* PragTyp_XXX value */" puts $fd " u8 mPragFlg; /* Zero or more PragFlg_XXX values */" @@ -503,7 +503,8 @@ puts $fd { u8 iPragCName; /* Start of column names in pragCName[] */} puts $fd " u8 nPragCName; \ /* Num of col names. 0 means use pragma name */" puts $fd " u32 iArg; /* Extra argument */" -puts $fd "\175 aPragmaNames\[\] = \173" +puts $fd "\175 PragmaName;" +puts $fd "static const PragmaName aPragmaName\[\] = \173" set current_if {} set spacer [format { %26s } {}] From d7175ebeaf8b7a5a7247bcfe6472646588b7efb5 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 15 Dec 2016 21:11:15 +0000 Subject: [PATCH 1091/1484] The pragma as eponymous virtual table mechanism now appears to work. FossilOrigin-Name: 2c274a1a7b57ef1208901fbc1d96d39c0d492652 --- manifest | 15 ++++++--------- manifest.uuid | 2 +- src/pragma.c | 13 ++++++------- 3 files changed, 13 insertions(+), 17 deletions(-) diff --git a/manifest b/manifest index 843ef1cfc5..9557ff3947 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Code\sto\sautomatically\screate\seponymous\svirtual\stables\sfor\sread-only\spragmas.\nCompiles,\sbut\sdoes\snot\syet\swork. -D 2016-12-15T20:59:03.895 +C The\spragma\sas\seponymous\svirtual\stable\smechanism\snow\sappears\sto\swork. +D 2016-12-15T21:11:15.541 F Makefile.in c194b58fe00c370a48ac6ae6945e92a7781db1c8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -381,7 +381,7 @@ F src/parse.y 29153738a7322054359320eb00b5a4cd44389f20 F src/pcache.c 51070ec9b8251bbf9c6ea3d35fd96a458752929e F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 F src/pcache1.c e3967219b2a92b9edcb9324a4ba75009090d3953 -F src/pragma.c b2421f23af876cb7a2f9aca09e803e207a4750f1 +F src/pragma.c db1d2ae01ad327b2c1d348924cdb11bbe1a54dcf F src/pragma.h f9b221b2c8949ea941dbee49934299e4ed5af41c F src/prepare.c b1140c3d0cf59bc85ace00ce363153041b424b7a F src/printf.c f94da4935d1dd25420ac50c6745db1deb35e07c1 @@ -1536,10 +1536,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a88ca3524b97f296dffc68335466b3767a681747 -R 23c19e6ab9e9f56bda2263bb45958620 -T *branch * pragma-as-vtab -T *sym-pragma-as-vtab * -T -sym-table-driven-pragma * +P 988a61e8b03f302c69d11898d1ea95f002cba1a5 +R fc9b9c22fa99573809efcbc3a3ada70d U drh -Z 91a2192a11c3bfa409136450c9378cb1 +Z 6fcba4a1d98b45e26069fbc257e90ccd diff --git a/manifest.uuid b/manifest.uuid index 24ee5e50c2..b606d7a8f8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -988a61e8b03f302c69d11898d1ea95f002cba1a5 \ No newline at end of file +2c274a1a7b57ef1208901fbc1d96d39c0d492652 \ No newline at end of file diff --git a/src/pragma.c b/src/pragma.c index 0018714c25..7cf0c61c09 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -1999,8 +1999,7 @@ static int pragmaVtabConnect( sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0); sqlite3StrAccumAppendAll(&acc, "CREATE TABLE x"); for(i=0, j=pPragma->iPragCName; inPragCName; i++, j++){ - sqlite3StrAccumAppend(&acc, &cSep, 1); - sqlite3StrAccumAppendAll(&acc, pragCName[j]); + sqlite3XPrintf(&acc, "%c\"%s\"", cSep, pragCName[j]); cSep = ','; } j = 0; @@ -2068,20 +2067,20 @@ static int pragmaVtabBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ j = pConstraint->iColumn - pTab->iHidden; assert( j < 2 ); if( seen[j] ) continue; - seen[j] = i; + seen[j] = i+1; } if( seen[0]==0 ){ pIdxInfo->estimatedCost = (double)2147483647; pIdxInfo->estimatedRows = 2147483647; return SQLITE_OK; } - j = seen[0]; + j = seen[0]-1; pIdxInfo->aConstraintUsage[j].argvIndex = 1; pIdxInfo->aConstraintUsage[j].omit = 1; if( seen[1]==0 ) return SQLITE_OK; pIdxInfo->estimatedCost = (double)20; pIdxInfo->estimatedRows = 20; - j = seen[1]; + j = seen[1]-1; pIdxInfo->aConstraintUsage[j].argvIndex = 2; pIdxInfo->aConstraintUsage[j].omit = 1; return SQLITE_OK; @@ -2156,7 +2155,7 @@ static int pragmaVtabFilter( return SQLITE_NOMEM; } } - sqlite3StrAccumInit(&acc, 0, 0, 0, pTab->db->aLimit[SQLITE_MAX_SQL_LENGTH]); + sqlite3StrAccumInit(&acc, 0, 0, 0, pTab->db->aLimit[SQLITE_LIMIT_SQL_LENGTH]); sqlite3StrAccumAppendAll(&acc, "PRAGMA "); if( pCsr->azArg[1] ){ sqlite3XPrintf(&acc, "%Q.", pCsr->azArg[1]); @@ -2250,7 +2249,7 @@ Module *sqlite3PragmaVtabRegister(sqlite3 *db, const char *zName){ if( pName==0 ) return 0; if( (pName->mPragFlg & (PragFlg_Result0|PragFlg_Result1))==0 ) return 0; assert( sqlite3HashFind(&db->aModule, zName)==0 ); - return sqlite3VtabCreateModule(db, zName, &pragmaVtabModule, 0, 0); + return sqlite3VtabCreateModule(db, zName, &pragmaVtabModule, (void*)pName, 0); } #endif /* SQLITE_OMIT_VIRTUALTABLE */ From ae7045cd538586d6e6d09ff60390d9211fa13a8c Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 15 Dec 2016 21:33:55 +0000 Subject: [PATCH 1092/1484] Fix the cost estimation in the BestIndex method of the eponymous pragma virtual table implementation. FossilOrigin-Name: 7126807a186746a8663fbaa267d63214d06476e4 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/pragma.c | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 9557ff3947..2b64aeeef2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C The\spragma\sas\seponymous\svirtual\stable\smechanism\snow\sappears\sto\swork. -D 2016-12-15T21:11:15.541 +C Fix\sthe\scost\sestimation\sin\sthe\sBestIndex\smethod\sof\sthe\seponymous\spragma\nvirtual\stable\simplementation. +D 2016-12-15T21:33:55.724 F Makefile.in c194b58fe00c370a48ac6ae6945e92a7781db1c8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -381,7 +381,7 @@ F src/parse.y 29153738a7322054359320eb00b5a4cd44389f20 F src/pcache.c 51070ec9b8251bbf9c6ea3d35fd96a458752929e F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 F src/pcache1.c e3967219b2a92b9edcb9324a4ba75009090d3953 -F src/pragma.c db1d2ae01ad327b2c1d348924cdb11bbe1a54dcf +F src/pragma.c 41f18267db44df49756c3c3cdc695e701e169a63 F src/pragma.h f9b221b2c8949ea941dbee49934299e4ed5af41c F src/prepare.c b1140c3d0cf59bc85ace00ce363153041b424b7a F src/printf.c f94da4935d1dd25420ac50c6745db1deb35e07c1 @@ -1536,7 +1536,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 988a61e8b03f302c69d11898d1ea95f002cba1a5 -R fc9b9c22fa99573809efcbc3a3ada70d +P 2c274a1a7b57ef1208901fbc1d96d39c0d492652 +R 443faf38855e36ce9518a22aacd4e206 U drh -Z 6fcba4a1d98b45e26069fbc257e90ccd +Z cec7546529435a8d9c60da5648254c3a diff --git a/manifest.uuid b/manifest.uuid index b606d7a8f8..0e05c05ce7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2c274a1a7b57ef1208901fbc1d96d39c0d492652 \ No newline at end of file +7126807a186746a8663fbaa267d63214d06476e4 \ No newline at end of file diff --git a/src/pragma.c b/src/pragma.c index 7cf0c61c09..6b3b84b4a4 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -2056,6 +2056,7 @@ static int pragmaVtabBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ int i, j; int seen[2]; + pIdxInfo->estimatedCost = (double)1; if( pTab->nHidden==0 ){ return SQLITE_OK; } pConstraint = pIdxInfo->aConstraint; seen[0] = 0; From e0a04a36a68c31d16cb62e1393d677c6ea0e1e9f Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 16 Dec 2016 01:00:21 +0000 Subject: [PATCH 1093/1484] All temp.sqlite_master to be used as an alias for sqlite_temp_master. FossilOrigin-Name: 8d646905b830d5bb29092e103ac5cb499b3c7e5a --- manifest | 70 ++++++++++++++++++++-------------------- manifest.uuid | 2 +- src/alter.c | 6 ++-- src/build.c | 46 +++++++++++++++----------- src/trigger.c | 4 +-- src/vdbe.c | 2 +- src/vtab.c | 2 +- test/alter.test | 6 ++-- test/alter4.test | 20 ++++++++++++ test/attach.test | 2 +- test/attach3.test | 4 +-- test/auth.test | 40 +++++++++++------------ test/auth3.test | 2 +- test/autoinc.test | 2 +- test/bestindex3.test | 1 - test/bestindex4.test | 1 - test/e_dropview.test | 2 +- test/fkey2.test | 4 +-- test/incrblob4.test | 1 - test/intarray.test | 2 +- test/interrupt.test | 4 +-- test/regexp2.test | 1 - test/rowvalue.test | 2 -- test/rowvalue9.test | 1 - test/rowvaluefault.test | 1 - test/schema4.test | 2 +- test/snapshot2.test | 2 -- test/tempdb2.test | 1 - test/temptrigger.test | 2 +- test/tkt3630.test | 4 +-- test/tkt3810.test | 2 +- test/without_rowid3.test | 4 +-- 32 files changed, 131 insertions(+), 114 deletions(-) diff --git a/manifest b/manifest index b183400c02..ca47317dff 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Do\sexponential\srather\sthan\slinear\sexpansion\sof\sthe\sSrcList.a\sarray\swhen\s\nappending\snew\selements,\sto\sreduce\sthe\snumber\sof\smalloc()\scalls. -D 2016-12-15T18:59:14.960 +C All\stemp.sqlite_master\sto\sbe\sused\sas\san\salias\sfor\ssqlite_temp_master. +D 2016-12-16T01:00:21.326 F Makefile.in c194b58fe00c370a48ac6ae6945e92a7781db1c8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -324,7 +324,7 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a -F src/alter.c 0f83ee1d5963e85f8f3316cb11a90227807a74c8 +F src/alter.c 3b23977620ce9662ac54443f65b87ba996e36121 F src/analyze.c 8b62b2cf4da85451534ac0af82cafc418d837f68 F src/attach.c f6725410c184a80d8141b294fdf98a854c8a52b5 F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792 @@ -334,7 +334,7 @@ F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 F src/btree.c b2055dff0b94e03eaad48a760984a2d8e39244e6 F src/btree.h 2349a588abcd7e0c04f984e15c5c777b61637583 F src/btreeInt.h 10c4b77c2fb399580babbcc7cf652ac10dba796e -F src/build.c 4c7952b6d4fd68e3d25d4b05a06d65a496c0f7c8 +F src/build.c 854ec3a222d2872df5351339f7af4002e64fdd1a F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 9f2296a4e5d26ebf0e0d95a0af4628f1ea694e7a @@ -450,12 +450,12 @@ F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c 6eb0752c4fd191f789190c3708ee5b0060fd2829 F src/treeview.c 4e44ade3bfe59d82005039f72e09333ce2b4162c -F src/trigger.c 3419bb9862983d84d70735fb4c94b21b934cd0c5 +F src/trigger.c c9f0810043b265724fdb1bdd466894f984dfc182 F src/update.c 1da7c462110bffed442a42884cb0d528c1db46d8 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c e68e8ced7328f22d2cf7b4c898c394a0de34cdf1 F src/vacuum.c 33c174b28886b2faf26e503b5a49a1c01a9b1c16 -F src/vdbe.c 2d90c42f2117b36e92c3af6a9c9f380b22e6e3b8 +F src/vdbe.c 64c3426893e1660bde7446c242468926555e3650 F src/vdbe.h 0c74f6305fb43b9b282dacaff102272370e327d4 F src/vdbeInt.h 42e498dbe96475dbb3fda3d85d8fd2a87eff60a2 F src/vdbeapi.c ea4e2dc2213cc6bd7bee375a29a9b51c31b93ae0 @@ -464,7 +464,7 @@ F src/vdbeblob.c f4f98ea672b242f807c08c92c7faaa79e5091b65 F src/vdbemem.c d3fd85b7b7ef3eb75de29c6d7e1d10d3ca78b4fd F src/vdbesort.c bb34eed4fb52e11ac037dccea4ee3190594c7f9e F src/vdbetrace.c 41963d5376f0349842b5fc4aaaaacd7d9cdc0834 -F src/vtab.c 2d5db3fd68c41c5a7476e43e79eb54181fa01713 +F src/vtab.c fd64fd37aad1e47e3e887f0e171099ddddc7e3cb F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 40c543f0a2195d1b0dc88ef12142bea690009344 F src/wal.h 06b2a0b599cc0f53ea97f497cf8c6b758c999f71 @@ -479,10 +479,10 @@ F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/aggnested.test b35b4cd69fc913f90d39a575e171e1116c3a4bb7 F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87 F test/all.test 6ff7b43c2b4b905c74dc4a813d201d0fa64c5783 -F test/alter.test 2facdddf08d0d48e75dc6cc312cd2b030f4835dd +F test/alter.test b820ab9dcf85f8e3a65bc8326accb2f0c7be64ef F test/alter2.test 7ea05c7d92ac99349a802ef7ada17294dd647060 F test/alter3.test 4d79934d812eaeacc6f22781a080f8cfe012fdc3 -F test/alter4.test 0c33c542247ba5aee4f4a0133ac44bcf8f97e5e0 +F test/alter4.test b6d7b86860111864f6cddb54af313f5862dda23b F test/altermalloc.test e81ac9657ed25c6c5bb09bebfa5a047cd8e4acfc F test/amatch1.test b5ae7065f042b7f4c1c922933f4700add50cdb9f F test/analyze.test 3eb35a4af972f98422e5dc0586501b17d103d321 @@ -506,15 +506,15 @@ F test/async3.test d73a062002376d7edc1fe3edff493edbec1fc2f7 F test/async4.test 1787e3952128aa10238bf39945126de7ca23685a F test/async5.test 383ab533fdb9f7ad228cc99ee66e1acb34cc0dc0 F test/atof1.test ff0b0156fd705b67c506e1f2bfe9e26102bea9bd -F test/attach.test 437107943f14d131cf5efc2ae5305a94d7cb1d58 +F test/attach.test 9976867b1a6585018f0966857aa82ed44e0bd6dc F test/attach2.test 0ec5defa340363de6cd50fd595046465e9aaba2d -F test/attach3.test 359eb65d00102cdfcef6fa4e81dc1648f8f80b27 +F test/attach3.test c59d92791070c59272e00183b7353eeb94915976 F test/attach4.test 53bf502f17647c6d6c5add46dda6bac8b6f4665c F test/attachmalloc.test 3a4bfca9545bfe906a8d2e622de10fbac5b711b0 -F test/auth.test 872a122b3977c1d1bb9fd637dc20016e5c01880f +F test/auth.test c6ede04bee65637ff354b43fc1235aa560c0863e F test/auth2.test 9eb7fce9f34bf1f50d3f366fb3e606be5a2000a1 -F test/auth3.test b810826b193831929951c0d50783a200e5ef6b72 -F test/autoinc.test c3a55c3667f429f4f4c7bed05f67b4d93e89e79d +F test/auth3.test 0d48b901cf111c14b4b1b5205c7d28f1a278190f +F test/autoinc.test 6ae8fb69c9f656962464ae4e6667045d0dfc3b46 F test/autoindex1.test 14b63a9f1e405fe6d5bfc8c8d00249c2ebaf13ea F test/autoindex2.test 12ef578928102baaa0dc23ad397601a2f4ecb0df F test/autoindex3.test a3be0d1a53a7d2edff208a5e442312957047e972 @@ -535,8 +535,8 @@ F test/badutf2.test f5bc7f2d280670ecd79b9cf4f0f1760c607fe51f F test/bc_common.tcl b5e42d80305be95697e6370e015af571e5333a1c F test/bestindex1.test 0cf1bd2d7b97d3a3a8c10736125274f64765c4ee F test/bestindex2.test 4a06b8922ab2fd09434870da8d1cdf525aaf7060 -F test/bestindex3.test dd5fa4f483cd0356549203c4522f8c9e21cb1fc0 -F test/bestindex4.test e6ef2ffe5787e6dbacb5f934ee3f32cf106474a1 +F test/bestindex3.test 578b6a52dab819e63f28e3640e04b32c85aed320 +F test/bestindex4.test 4cb5ff7dbaebadb87d366f51969271778423b455 F test/between.test 34d375fb5ce1ae283ffe82b6b233e9f38e84fc6c F test/bigfile.test aa74f4e5db51c8e54a1d9de9fa65d01d1eb20b59 F test/bigfile2.test 1b489a3a39ae90c7f027b79110d6b4e1dbc71bfc @@ -650,7 +650,7 @@ F test/e_changes.test fd66105385153dbf21fdb35eb8ef6c3e1eade579 F test/e_createtable.test d4c6059d44dcd4b636de9aae322766062b471844 F test/e_delete.test ab39084f26ae1f033c940b70ebdbbd523dc4962e F test/e_droptrigger.test 3cd080807622c13e5bbb61fc9a57bd7754da2412 -F test/e_dropview.test 0c9f7f60989164a70a67a9d9c26d1083bc808306 +F test/e_dropview.test 21ce09c361227ddbc9819a5608ee2700c276bdd5 F test/e_expr.test d0dd488e0527cbc560ae2dea1939cc44cb9b9924 F test/e_fkey.test 54cc0046d2d952d6c42b0dd94414e7a8f75f79f4 F test/e_fts3.test 5c02288842e4f941896fd44afdef564dd5fc1459 @@ -685,7 +685,7 @@ F test/fallocate.test 3e979af17dfa7e5e9dda5eba1a696c04fa9d47f7 F test/filectrl.test 6e871c2d35dead1d9a88e176e8d2ca094fec6bb3 F test/filefmt.test e4edbdc637ca9576ccf4337a3cce627d9df7a56c F test/fkey1.test ba64806ff9a04eecab2679caad377ae99a5e94e4 -F test/fkey2.test f3d27ecba480a348c328965d154214719bb158a9 +F test/fkey2.test 155809016fad6b2a1491facf2ac53a551bc57c2c F test/fkey3.test 76d475c80b84ee7a5d062e56ccb6ea68882e2b49 F test/fkey4.test 86446017011273aad8f9a99c1a65019e7bd9ca9d F test/fkey5.test 5a373303f201ac03c22ba1ef17a733d3f56e611a @@ -839,7 +839,7 @@ F test/in5.test 6c006e0bcd7351b69350ef566e65f244023489e9 F test/incrblob.test c9b96afc292aeff43d6687bcb09b0280aa599822 F test/incrblob2.test a5ce5ed1d0b01e2ed347245a21170372528af0a5 F test/incrblob3.test d8d036fde015d4a159cd3cbae9d29003b37227a4 -F test/incrblob4.test fab83541571c7281aa561e5ea6088eb8612a4bec +F test/incrblob4.test 21a52a6843a56cdcce968c6a86b72a7066d0e6ba F test/incrblob_err.test 69f9247fed50278d48ea710d1a8f9cdb09e4c0b8 F test/incrblobfault.test 280474078f6da9e732cd2a215d3d854969014b6e F test/incrcorrupt.test 6c567fbf870aa9e91866fe52ce6f200cd548939a @@ -866,8 +866,8 @@ F test/insert4.test a20432f1c0fbbcff8f11d0e6ab4acb8c9db58023 F test/insert5.test 394f96728d1258f406fe5f5aeb0aaf29487c39a6 F test/instr.test 737bbf80685232033f3abedc6ae92f75860b5dd2 F test/instrfault.test aa90b7c3486a069151b28384ae525644a1f79d51 -F test/intarray.test 066b7d7ac38d25bf96f87f1b017bfc687551cdd4 -F test/interrupt.test dfe9a67a94b0b2d8f70545ba1a6cca10780d71cc +F test/intarray.test 46d95b457916638c5d8b1af21fb174804b3acf8b +F test/interrupt.test 16ea879ec728cb76414c148c5f24afd5d1f91054 F test/interrupt2.test 829b06f9e20a6c378d8bd121b26c337f4dfa36e5 F test/intpkey.test ac71107a49a06492b69b82aafaf225400598d3c8 F test/io.test f95bca1783b01ea7761671560d023360d2dfa4cc @@ -1022,7 +1022,7 @@ F test/randexpr1.test eda062a97e60f9c38ae8d806b03b0ddf23d796df F test/rbu.test 168573d353cd0fd10196b87b0caa322c144ef736 F test/rdonly.test 64e2696c322e3538df0b1ed624e21f9a23ed9ff8 F test/regexp1.test 497ea812f264d12b6198d6e50a76be4a1973a9d8 -F test/regexp2.test aa7ffcc21350007a78361b82bcf3b74d12227144 +F test/regexp2.test 40e894223b3d6672655481493f1be12012f2b33c F test/reindex.test 44edd3966b474468b823d481eafef0c305022254 F test/releasetest.tcl cb06c4df0de4872e65b178316f8a87ccf7624d59 x F test/resolver01.test f4022acafda7f4d40eca94dbf16bc5fc4ac30ceb @@ -1032,7 +1032,7 @@ F test/rollbackfault.test 0e646aeab8840c399cfbfa43daab46fd609cf04a F test/rowallock.test 3f88ec6819489d0b2341c7a7528ae17c053ab7cc F test/rowhash.test 0bc1d31415e4575d10cacf31e1a66b5cc0f8be81 F test/rowid.test 5b7509f384f4f6fae1af3c8c104c8ca299fea18d -F test/rowvalue.test 3f468a9e370a3ee8b267e58049679eb0df2b9d01 +F test/rowvalue.test cacc565ed7e3ac467866af6705dd99020fdf2ee2 F test/rowvalue2.test 060d238b7e5639a7c5630cb5e63e311b44efef2b F test/rowvalue3.test 3068f508753af69884b12125995f023da0dbb256 F test/rowvalue4.test 4b556d7de161a0dd8cff095c336e913986398bea @@ -1040,8 +1040,8 @@ F test/rowvalue5.test c81c7d8cf36711ab37675ad7376084ae2a359cb6 F test/rowvalue6.test d19b54feb604d5601f8614b15e214e0774c01087 F test/rowvalue7.test 5d06ff19d9e6969e574a2e662a531dd0c67801a8 F test/rowvalue8.test 5900eddad9e2c3c2e26f1a95f74aafc1232ee5e0 -F test/rowvalue9.test e24f9eb02baffc6a67b6eed9e40d4c612c98079d -F test/rowvaluefault.test 7b16485e3f2b371f3e3d05455b8ded6d0c090244 +F test/rowvalue9.test d8dd2c6ecac432dadaa79e41dc2434f007be1b6b +F test/rowvaluefault.test 7cd9ccc6c2fbdd881672984087aad0491bb75504 F test/rtree.test 0c8d9dd458d6824e59683c19ab2ffa9ef946f798 F test/run-wordcount.sh 891e89c4c2d16e629cd45951d4ed899ad12afc09 F test/savepoint.test c671fdbd34cd3bfe1518a777526ada595180cf8d @@ -1055,7 +1055,7 @@ F test/scanstatus.test 5253c219e331318a437f436268e0e82345700285 F test/schema.test 8f7999be894260f151adf15c2c7540f1c6d6a481 F test/schema2.test 906408621ea881fdb496d878b1822572a34e32c5 F test/schema3.test 1bc1008e1f8cb5654b248c55f27249366eb7ed38 -F test/schema4.test e6a66e20cc69f0e306667c08be7fda3d11707dc5 +F test/schema4.test 3b26c9fa916abb6dadf894137adcf41b7796f7b9 F test/schema5.test 29699b4421f183c8f0e88bd28ce7d75d13ea653e F test/securedel.test 21749c32ccc30f1ea9e4b9f33295a6521ec20fa0 F test/securedel2.test 2d54c28e46eb1fd6902089958b20b1b056c6f1c5 @@ -1104,7 +1104,7 @@ F test/skipscan3.test ec5bab3f81c7038b43450e7b3062e04a198bdbb5 F test/skipscan5.test 67817a4b6857c47e0e33ba3e506da6f23ef68de2 F test/skipscan6.test 5866039d03a56f5bd0b3d172a012074a1d90a15b F test/snapshot.test 85735bd997a4f6d710140c28fd860519a299649f -F test/snapshot2.test eb083df2e617708a4a93d70965f14268d4934120 +F test/snapshot2.test 867652ed4a13282dce218723535fad1c7b44c3c4 F test/snapshot_fault.test 52c5e97ebd218846a8ae2da4d147d3e77d71f963 F test/soak.test 0b5b6375c9f4110c828070b826b3b4b0bb65cd5f F test/softheap1.test 843cd84db9891b2d01b9ab64cef3e9020f98d087 @@ -1148,12 +1148,12 @@ F test/tableapi.test 2674633fa95d80da917571ebdd759a14d9819126 F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930 F test/tclsqlite.test 1d73b9203b1ca8798d7d7310742b8d3febc0d56e F test/tempdb.test bd92eba8f20e16a9136e434e20b280794de3cdb6 -F test/tempdb2.test 4fc92055f2a3f7626c0f2eabbb637dc021b311d5 +F test/tempdb2.test 27e41ed540b2f9b056c2e77e9bddc1b875358507 F test/tempfault.test 0c0d349c9a99bf5f374655742577f8712c647900 F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30 F test/temptable2.test cd396beb41117a5302fff61767c35fa4270a0d5e F test/temptable3.test d11a0974e52b347e45ee54ef1923c91ed91e4637 -F test/temptrigger.test 8ec228b0db5d7ebc4ee9b458fc28cb9e7873f5e1 +F test/temptrigger.test 38f0ca479b1822d3117069e014daabcaacefffcc F test/tester.tcl 4ce5afd5e192db4cae178e1a983b060e0f08c5d6 F test/thread001.test 9f22fd3525a307ff42a326b6bc7b0465be1745a5 F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58 @@ -1284,7 +1284,7 @@ F test/tkt3541.test 5dc257bde9bc833ab9cc6844bf170b998dbb950a F test/tkt3554.test f599967f279077bace39220cbe76085c7b423725 F test/tkt3581.test 1966b7193f1e3f14951cce8c66907ae69454e9a3 F test/tkt35xx.test f38c1b03713179d414969187c941466e44945b35 -F test/tkt3630.test 929f64852103054125200bc825c316d5f75d42f7 +F test/tkt3630.test 9a934c58c259f89a0ae6bb6bb846c56285a6fd0f F test/tkt3718.test 3b59dcb5c4e7754dacd91e7fd353a61492cc402a F test/tkt3731.test 0c5f4cbffe102d43c3b2188af91a9e36348f974b F test/tkt3757.test 10cd679a88675c880533083fc79ac04324525595 @@ -1293,7 +1293,7 @@ F test/tkt3762.test 4d439ff7abdc8d9323150269d182c37c2d514576 F test/tkt3773.test 7bca904d2a647a6a4a291bd86d7fd7c73855b789 F test/tkt3791.test a6624b9a80b216a26cf473607f42f3e51898c267 F test/tkt3793.test d90ffd75c52413908d15e1c44fc2ea9c80fcc449 -F test/tkt3810.test 90fa0635dfa7da9680c8cd3513350a49b3a8ae12 +F test/tkt3810.test 09608d81c63a6ff3aaf7bc70717909c51f5f4048 F test/tkt3824.test 150aa00bb6220672e5f0eb14dc8eaa36750425f0 F test/tkt3832.test 2300d10d57562b89875b72148338ac3e14f8847d F test/tkt3838.test 292e72489101cd1320d7278dc111c173ebf334d4 @@ -1440,7 +1440,7 @@ F test/with3.test 511bacdbe41c49cf34f9fd1bd3245fe1575bca98 F test/withM.test 693b61765f2b387b5e3e24a4536e2e82de15ff64 F test/without_rowid1.test 1a7b9bd51b899928d327052df9741d2fe8dbe701 F test/without_rowid2.test af260339f79d13cb220288b67cd287fbcf81ad99 -F test/without_rowid3.test aad4f9d383e199349b6c7e508a778f7dff5dff79 +F test/without_rowid3.test 2724c787a51a5dce09d078453a758117b4b728f1 F test/without_rowid4.test 4e08bcbaee0399f35d58b5581881e7a6243d458a F test/without_rowid5.test 89b1c587bd92a0590e440da33e7666bf4891572a F test/without_rowid6.test 1f99644e6508447fb050f73697350c7ceca3392e @@ -1536,7 +1536,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 9cae4c2e300e20304ced0dc8c1415c4922185928 -R 9770eba5fe5acae93ed970f661562070 +P 4e3749127e7249f46e17bfabc614b0876f60565a +R 27200c6ed9ee619c25ffbd7fc5b77433 U drh -Z 9a292fcbff4c94ddef7a536330d555ac +Z dbd7760e0bb1a8efbcd514dce9f9a0ad diff --git a/manifest.uuid b/manifest.uuid index c55edda4a5..da81604870 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4e3749127e7249f46e17bfabc614b0876f60565a \ No newline at end of file +8d646905b830d5bb29092e103ac5cb499b3c7e5a \ No newline at end of file diff --git a/src/alter.c b/src/alter.c index b16f098e1d..067cbb896d 100644 --- a/src/alter.c +++ b/src/alter.c @@ -504,7 +504,7 @@ void sqlite3AlterRenameTable( sqlite3NestedParse(pParse, "UPDATE \"%w\".%s SET " "sql = sqlite_rename_parent(sql, %Q, %Q) " - "WHERE %s;", zDb, SCHEMA_TABLE(iDb), zTabName, zName, zWhere); + "WHERE %s;", zDb, MASTER_NAME, zTabName, zName, zWhere); sqlite3DbFree(db, zWhere); } } @@ -528,7 +528,7 @@ void sqlite3AlterRenameTable( "ELSE name END " "WHERE tbl_name=%Q COLLATE nocase AND " "(type='table' OR type='index' OR type='trigger');", - zDb, SCHEMA_TABLE(iDb), zName, zName, zName, + zDb, MASTER_NAME, zName, zName, zName, #ifndef SQLITE_OMIT_TRIGGER zName, #endif @@ -689,7 +689,7 @@ void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){ "UPDATE \"%w\".%s SET " "sql = substr(sql,1,%d) || ', ' || %Q || substr(sql,%d) " "WHERE type = 'table' AND name = %Q", - zDb, SCHEMA_TABLE(iDb), pNew->addColOffset, zCol, pNew->addColOffset+1, + zDb, MASTER_NAME, pNew->addColOffset, zCol, pNew->addColOffset+1, zTab ); sqlite3DbFree(db, zCol); diff --git a/src/build.c b/src/build.c index 44c1d67ee0..24d41ba0b4 100644 --- a/src/build.c +++ b/src/build.c @@ -30,10 +30,10 @@ ** codeTableLocks() functions. */ struct TableLock { - int iDb; /* The database containing the table to be locked */ - int iTab; /* The root page of the table to be locked */ - u8 isWriteLock; /* True for write lock. False for a read lock */ - const char *zName; /* Name of the table */ + int iDb; /* The database containing the table to be locked */ + int iTab; /* The root page of the table to be locked */ + u8 isWriteLock; /* True for write lock. False for a read lock */ + const char *zLockName; /* Name of the table */ }; /* @@ -77,7 +77,7 @@ void sqlite3TableLock( p->iDb = iDb; p->iTab = iTab; p->isWriteLock = isWriteLock; - p->zName = zName; + p->zLockName = zName; }else{ pToplevel->nTableLock = 0; sqlite3OomFault(pToplevel->db); @@ -99,7 +99,7 @@ static void codeTableLocks(Parse *pParse){ TableLock *p = &pParse->aTableLock[i]; int p1 = p->iDb; sqlite3VdbeAddOp4(pVdbe, OP_TableLock, p1, p->iTab, p->isWriteLock, - p->zName, P4_STATIC); + p->zLockName, P4_STATIC); } } #else @@ -308,15 +308,23 @@ Table *sqlite3FindTable(sqlite3 *db, const char *zName, const char *zDatabase){ return 0; } #endif - for(i=OMIT_TEMPDB; inDb; i++){ - int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */ - if( zDatabase==0 || sqlite3StrICmp(zDatabase, db->aDb[j].zDbSName)==0 ){ - assert( sqlite3SchemaMutexHeld(db, j, 0) ); - p = sqlite3HashFind(&db->aDb[j].pSchema->tblHash, zName); - if( p ) break; + while(1){ + for(i=OMIT_TEMPDB; inDb; i++){ + int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */ + if( zDatabase==0 || sqlite3StrICmp(zDatabase, db->aDb[j].zDbSName)==0 ){ + assert( sqlite3SchemaMutexHeld(db, j, 0) ); + p = sqlite3HashFind(&db->aDb[j].pSchema->tblHash, zName); + if( p ) return p; + } } + /* Not found. If the name we were looking for was temp.sqlite_master + ** then change the name to sqlite_temp_master and try again. */ + if( sqlite3StrICmp(zName, MASTER_NAME)!=0 ) break; + if( zDatabase==0 ) break; + if( sqlite3StrICmp(zDatabase, db->aDb[1].zDbSName)!=0 ) break; + zName = TEMP_MASTER_NAME; } - return p; + return 0; } /* @@ -688,7 +696,7 @@ char *sqlite3NameFromToken(sqlite3 *db, Token *pName){ */ void sqlite3OpenMasterTable(Parse *p, int iDb){ Vdbe *v = sqlite3GetVdbe(p); - sqlite3TableLock(p, iDb, MASTER_ROOT, 1, SCHEMA_TABLE(iDb)); + sqlite3TableLock(p, iDb, MASTER_ROOT, 1, MASTER_NAME); sqlite3VdbeAddOp4Int(v, OP_OpenWrite, 0, MASTER_ROOT, iDb, 5); if( p->nTab==0 ){ p->nTab = 1; @@ -1991,7 +1999,7 @@ void sqlite3EndTable( "UPDATE %Q.%s " "SET type='%s', name=%Q, tbl_name=%Q, rootpage=#%d, sql=%Q " "WHERE rowid=#%d", - db->aDb[iDb].zDbSName, SCHEMA_TABLE(iDb), + db->aDb[iDb].zDbSName, MASTER_NAME, zType, p->zName, p->zName, @@ -2328,7 +2336,7 @@ static void destroyRootPage(Parse *pParse, int iTable, int iDb){ */ sqlite3NestedParse(pParse, "UPDATE %Q.%s SET rootpage=%d WHERE #%d AND rootpage=#%d", - pParse->db->aDb[iDb].zDbSName, SCHEMA_TABLE(iDb), iTable, r1, r1); + pParse->db->aDb[iDb].zDbSName, MASTER_NAME, iTable, r1, r1); #endif sqlite3ReleaseTempReg(pParse, r1); } @@ -2471,7 +2479,7 @@ void sqlite3CodeDropTable(Parse *pParse, Table *pTab, int iDb, int isView){ */ sqlite3NestedParse(pParse, "DELETE FROM %Q.%s WHERE tbl_name=%Q and type!='trigger'", - pDb->zDbSName, SCHEMA_TABLE(iDb), pTab->zName); + pDb->zDbSName, MASTER_NAME, pTab->zName); if( !isView && !IsVirtual(pTab) ){ destroyTable(pParse, pTab); } @@ -3363,7 +3371,7 @@ void sqlite3CreateIndex( */ sqlite3NestedParse(pParse, "INSERT INTO %Q.%s VALUES('index',%Q,%Q,#%d,%Q);", - db->aDb[iDb].zDbSName, SCHEMA_TABLE(iDb), + db->aDb[iDb].zDbSName, MASTER_NAME, pIndex->zName, pTab->zName, iMem, @@ -3515,7 +3523,7 @@ void sqlite3DropIndex(Parse *pParse, SrcList *pName, int ifExists){ sqlite3BeginWriteOperation(pParse, 1, iDb); sqlite3NestedParse(pParse, "DELETE FROM %Q.%s WHERE name=%Q AND type='index'", - db->aDb[iDb].zDbSName, SCHEMA_TABLE(iDb), pIndex->zName + db->aDb[iDb].zDbSName, MASTER_NAME, pIndex->zName ); sqlite3ClearStatTables(pParse, iDb, "idx", pIndex->zName); sqlite3ChangeCookie(pParse, iDb); diff --git a/src/trigger.c b/src/trigger.c index 7eb14bcf8d..bdf964084b 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -308,7 +308,7 @@ void sqlite3FinishTrigger( z = sqlite3DbStrNDup(db, (char*)pAll->z, pAll->n); sqlite3NestedParse(pParse, "INSERT INTO %Q.%s VALUES('trigger',%Q,%Q,0,'CREATE TRIGGER %q')", - db->aDb[iDb].zDbSName, SCHEMA_TABLE(iDb), zName, + db->aDb[iDb].zDbSName, MASTER_NAME, zName, pTrig->table, z); sqlite3DbFree(db, z); sqlite3ChangeCookie(pParse, iDb); @@ -559,7 +559,7 @@ void sqlite3DropTriggerPtr(Parse *pParse, Trigger *pTrigger){ if( (v = sqlite3GetVdbe(pParse))!=0 ){ sqlite3NestedParse(pParse, "DELETE FROM %Q.%s WHERE name=%Q AND type='trigger'", - db->aDb[iDb].zDbSName, SCHEMA_TABLE(iDb), pTrigger->zName + db->aDb[iDb].zDbSName, MASTER_NAME, pTrigger->zName ); sqlite3ChangeCookie(pParse, iDb); sqlite3VdbeAddOp4(v, OP_DropTrigger, iDb, 0, 0, pTrigger->zName, 0); diff --git a/src/vdbe.c b/src/vdbe.c index 8459cc4613..6ccd746ef2 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -5479,7 +5479,7 @@ case OP_ParseSchema: { assert( iDb>=0 && iDbnDb ); assert( DbHasProperty(db, iDb, DB_SchemaLoaded) ); /* Used to be a conditional */ { - zMaster = SCHEMA_TABLE(iDb); + zMaster = MASTER_NAME; initData.db = db; initData.iDb = pOp->p1; initData.pzErrMsg = &p->zErrMsg; diff --git a/src/vtab.c b/src/vtab.c index 2531155546..516f412c8b 100644 --- a/src/vtab.c +++ b/src/vtab.c @@ -408,7 +408,7 @@ void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){ "UPDATE %Q.%s " "SET type='table', name=%Q, tbl_name=%Q, rootpage=0, sql=%Q " "WHERE rowid=#%d", - db->aDb[iDb].zDbSName, SCHEMA_TABLE(iDb), + db->aDb[iDb].zDbSName, MASTER_NAME, pTab->zName, pTab->zName, zStmt, diff --git a/test/alter.test b/test/alter.test index ebfe97a764..76c18cedc9 100644 --- a/test/alter.test +++ b/test/alter.test @@ -77,7 +77,7 @@ do_test alter-1.2 { ifcapable tempdb { execsql { INSERT INTO objlist SELECT type, name, tbl_name - FROM sqlite_temp_master WHERE NAME!='objlist'; + FROM temp.sqlite_master WHERE NAME!='objlist'; } } @@ -153,7 +153,7 @@ ifcapable tempdb { CREATE TEMP TABLE objlist(type, name, tbl_name); INSERT INTO objlist SELECT type, name, tbl_name FROM sqlite_master; INSERT INTO objlist - SELECT type, name, tbl_name FROM sqlite_temp_master + SELECT type, name, tbl_name FROM temp.sqlite_master WHERE NAME!='objlist'; SELECT type, name, tbl_name FROM objlist ORDER BY tbl_name, type desc, name; @@ -524,7 +524,7 @@ do_test alter-3.3.7 { ifcapable tempdb { do_test alter-3.3.8 { execsql { - SELECT * FROM sqlite_temp_master WHERE type = 'trigger'; + SELECT * FROM temp.sqlite_master WHERE type = 'trigger'; } } {} } diff --git a/test/alter4.test b/test/alter4.test index 2cd78777a2..5155110cf5 100644 --- a/test/alter4.test +++ b/test/alter4.test @@ -45,18 +45,33 @@ do_test alter4-1.1 { SELECT sql FROM sqlite_temp_master; } } {{CREATE TABLE abc(a, b, c)}} +do_test alter4-1.1b { + execsql { + SELECT sql FROM temp.sqlite_master; + } +} {{CREATE TABLE abc(a, b, c)}} do_test alter4-1.2 { execsql {ALTER TABLE abc ADD d INTEGER;} execsql { SELECT sql FROM sqlite_temp_master; } } {{CREATE TABLE abc(a, b, c, d INTEGER)}} +do_test alter4-1.2b { + execsql { + SELECT sql FROM temp.sqlite_master; + } +} {{CREATE TABLE abc(a, b, c, d INTEGER)}} do_test alter4-1.3 { execsql {ALTER TABLE abc ADD e} execsql { SELECT sql FROM sqlite_temp_master; } } {{CREATE TABLE abc(a, b, c, d INTEGER, e)}} +do_test alter4-1.3b { + execsql { + SELECT sql FROM temp.sqlite_master; + } +} {{CREATE TABLE abc(a, b, c, d INTEGER, e)}} do_test alter4-1.4 { execsql { CREATE TABLE temp.t1(a, b); @@ -64,6 +79,11 @@ do_test alter4-1.4 { SELECT sql FROM sqlite_temp_master WHERE tbl_name = 't1'; } } {{CREATE TABLE t1(a, b, c)}} +do_test alter4-1.4b { + execsql { + SELECT sql FROM temp.sqlite_master WHERE tbl_name = 't1'; + } +} {{CREATE TABLE t1(a, b, c)}} do_test alter4-1.5 { execsql { ALTER TABLE t1 ADD d CHECK (a>d); diff --git a/test/attach.test b/test/attach.test index 31c24e61d9..54be6a41ac 100644 --- a/test/attach.test +++ b/test/attach.test @@ -193,7 +193,7 @@ do_test attach-1.20.2 { } ;# ifcapable schema_pragmas integrity_check attach-1.20.3 ifcapable tempdb { - execsql {select * from sqlite_temp_master} + execsql {select * from temp.sqlite_master} } do_test attach-1.21 { catchsql { diff --git a/test/attach3.test b/test/attach3.test index 1ac10d97a4..1c8601c7b3 100644 --- a/test/attach3.test +++ b/test/attach3.test @@ -207,7 +207,7 @@ ifcapable tempdb { CREATE TEMP TRIGGER tst_trigger BEFORE INSERT ON aux.t4 BEGIN SELECT 'hello world'; END; - SELECT count(*) FROM sqlite_temp_master; + SELECT count(*) FROM temp.sqlite_master; } } {1} do_test attach3-9.1 { @@ -219,7 +219,7 @@ ifcapable tempdb { do_test attach3-9.2 { execsql { DROP TABLE aux.t4; - SELECT count(*) FROM sqlite_temp_master; + SELECT count(*) FROM temp.sqlite_master; } } {0} } diff --git a/test/auth.test b/test/auth.test index d9e12edc3c..0044fddebe 100644 --- a/test/auth.test +++ b/test/auth.test @@ -91,7 +91,7 @@ ifcapable tempdb { catchsql {CREATE TEMP TABLE t1(a,b,c)} } {1 {not authorized}} do_test auth-1.6 { - execsql {SELECT name FROM sqlite_temp_master} + execsql {SELECT name FROM temp.sqlite_master} } {} do_test auth-1.7.1 { proc auth {code arg1 arg2 arg3 arg4 args} { @@ -148,7 +148,7 @@ ifcapable tempdb { catchsql {CREATE TEMP TABLE t1(a,b,c)} } {0 {}} do_test auth-1.14 { - execsql {SELECT name FROM sqlite_temp_master} + execsql {SELECT name FROM temp.sqlite_master} } {} do_test auth-1.15 { proc auth {code arg1 arg2 arg3 arg4 args} { @@ -561,7 +561,7 @@ ifcapable tempdb { catchsql {DROP TABLE t1} } {0 {}} do_test auth-1.78 { - execsql {SELECT name FROM sqlite_temp_master} + execsql {SELECT name FROM temp.sqlite_master} } {t1} } @@ -632,7 +632,7 @@ ifcapable tempdb { set ::authargs } {v1 {} temp {}} do_test auth-1.90 { - execsql {SELECT name FROM sqlite_temp_master} + execsql {SELECT name FROM temp.sqlite_master} } {t1} } @@ -779,7 +779,7 @@ ifcapable tempdb { } } {1 {not authorized}} do_test auth-1.113 { - execsql {SELECT name FROM sqlite_temp_master} + execsql {SELECT name FROM temp.sqlite_master} } {t1 v1} do_test auth-1.114 { proc auth {code arg1 arg2 arg3 arg4 args} { @@ -823,7 +823,7 @@ ifcapable tempdb { set ::authargs } {v1 {} temp {}} do_test auth-1.121 { - execsql {SELECT name FROM sqlite_temp_master} + execsql {SELECT name FROM temp.sqlite_master} } {t1 v1} do_test auth-1.122 { proc auth {code arg1 arg2 arg3 arg4 args} { @@ -980,7 +980,7 @@ do_test auth-1.139 { set ::authargs } {r1 t1 temp {}} do_test auth-1.140 { - execsql {SELECT name FROM sqlite_temp_master} + execsql {SELECT name FROM temp.sqlite_master} } {t1} do_test auth-1.141 { proc auth {code arg1 arg2 arg3 arg4 args} { @@ -1016,7 +1016,7 @@ do_test auth-1.144 { set ::authargs } {r1 t1 temp {}} do_test auth-1.145 { - execsql {SELECT name FROM sqlite_temp_master} + execsql {SELECT name FROM temp.sqlite_master} } {t1} do_test auth-1.146 { proc auth {code arg1 arg2 arg3 arg4 args} { @@ -1052,7 +1052,7 @@ do_test auth-1.149 { set ::authargs } {r1 t1 temp {}} do_test auth-1.150 { - execsql {SELECT name FROM sqlite_temp_master} + execsql {SELECT name FROM temp.sqlite_master} } {t1 r1} do_test auth-1.151 { @@ -1142,7 +1142,7 @@ do_test auth-1.164 { catchsql {DROP TRIGGER r1} } {1 {not authorized}} do_test auth-1.165 { - execsql {SELECT name FROM sqlite_temp_master} + execsql {SELECT name FROM temp.sqlite_master} } {t1 r1} do_test auth-1.166 { proc auth {code arg1 arg2 arg3 arg4 args} { @@ -1170,7 +1170,7 @@ do_test auth-1.169 { catchsql {DROP TRIGGER r1} } {0 {}} do_test auth-1.170 { - execsql {SELECT name FROM sqlite_temp_master} + execsql {SELECT name FROM temp.sqlite_master} } {t1 r1} do_test auth-1.171 { proc auth {code arg1 arg2 arg3 arg4 args} { @@ -1202,7 +1202,7 @@ do_test auth-1.175 { set ::authargs } {r1 t1 temp {}} do_test auth-1.176 { - execsql {SELECT name FROM sqlite_temp_master} + execsql {SELECT name FROM temp.sqlite_master} } {t1} } ;# ifcapable trigger @@ -1306,7 +1306,7 @@ ifcapable tempdb { catchsql {CREATE INDEX i1 ON t1(b)} } {1 {not authorized}} do_test auth-1.194 { - execsql {SELECT name FROM sqlite_temp_master} + execsql {SELECT name FROM temp.sqlite_master} } {t1} do_test auth-1.195 { proc auth {code arg1 arg2 arg3 arg4 args} { @@ -1350,7 +1350,7 @@ ifcapable tempdb { set ::authargs } {i1 t1 temp {}} do_test auth-1.202 { - execsql {SELECT name FROM sqlite_temp_master} + execsql {SELECT name FROM temp.sqlite_master} } {t1 i1} } @@ -1466,7 +1466,7 @@ ifcapable tempdb { catchsql {DROP INDEX i1} } {0 {}} do_test auth-1.222 { - execsql {SELECT name FROM sqlite_temp_master} + execsql {SELECT name FROM temp.sqlite_master} } {t1 i1} do_test auth-1.223 { proc auth {code arg1 arg2 arg3 arg4 args} { @@ -1482,7 +1482,7 @@ ifcapable tempdb { set ::authargs } {i1 t1 temp {}} do_test auth-1.225 { - execsql {SELECT name FROM sqlite_temp_master} + execsql {SELECT name FROM temp.sqlite_master} } {t1 i1} do_test auth-1.226 { proc auth {code arg1 arg2 arg3 arg4 args} { @@ -1498,7 +1498,7 @@ ifcapable tempdb { set ::authargs } {i1 t1 temp {}} do_test auth-1.228 { - execsql {SELECT name FROM sqlite_temp_master} + execsql {SELECT name FROM temp.sqlite_master} } {t1} } @@ -1765,7 +1765,7 @@ ifcapable attach { } } {0 {}} do_test auth-1.267 { - execsql {SELECT name FROM sqlite_temp_master WHERE type='table'} + execsql {SELECT name FROM temp.sqlite_master WHERE type='table'} } {t1x} do_test auth-1.268 { set authargs @@ -2070,7 +2070,7 @@ ifcapable {altertable} { } } {1 {not authorized}} do_test auth-1.307 { - set x [execsql {SELECT sql FROM sqlite_temp_master WHERE type='t5'}] + set x [execsql {SELECT sql FROM temp.sqlite_master WHERE type='t5'}] regexp new_col_3 $x } {0} @@ -2373,7 +2373,7 @@ ifcapable compound&&subquery { do_test auth-5.2 { execsql { SELECT name FROM ( - SELECT * FROM sqlite_master UNION ALL SELECT * FROM sqlite_temp_master) + SELECT * FROM sqlite_master UNION ALL SELECT * FROM temp.sqlite_master) WHERE type='table' ORDER BY name } diff --git a/test/auth3.test b/test/auth3.test index ca7e16c84c..013486e5a0 100644 --- a/test/auth3.test +++ b/test/auth3.test @@ -122,7 +122,7 @@ do_execsql_test auth3-3.0 { key TEXT NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT REPLACE, value TEXT NOT NULL ON CONFLICT FAIL); ALTER TABLE TempTable RENAME TO DoNotRead; - SELECT name FROM sqlite_temp_master; + SELECT name FROM temp.sqlite_master; } {DoNotRead sqlite_autoindex_DoNotRead_1} finish_test diff --git a/test/autoinc.test b/test/autoinc.test index 4c108eadd4..8ac12b1772 100644 --- a/test/autoinc.test +++ b/test/autoinc.test @@ -344,7 +344,7 @@ ifcapable tempdb { do_test autoinc-4.1 { execsql { SELECT 1, name FROM sqlite_master WHERE type='table'; - SELECT 2, name FROM sqlite_temp_master WHERE type='table'; + SELECT 2, name FROM temp.sqlite_master WHERE type='table'; } } {1 sqlite_sequence} do_test autoinc-4.2 { diff --git a/test/bestindex3.test b/test/bestindex3.test index 8baf854254..70c60d66dd 100644 --- a/test/bestindex3.test +++ b/test/bestindex3.test @@ -172,4 +172,3 @@ do_execsql_test 3.1 { CREATE VIRTUAL TABLE t3 USING tcl('vvv_command') } do_execsql_test 3.2 { CREATE VIRTUAL TABLE t4 USING tcl('yyy_command') } finish_test - diff --git a/test/bestindex4.test b/test/bestindex4.test index 836701f6b9..64727bd0d7 100644 --- a/test/bestindex4.test +++ b/test/bestindex4.test @@ -118,4 +118,3 @@ for {set param1 0} {$param1<16} {incr param1} { } finish_test - diff --git a/test/e_dropview.test b/test/e_dropview.test index 143dce2907..04c4ad8c4b 100644 --- a/test/e_dropview.test +++ b/test/e_dropview.test @@ -45,7 +45,7 @@ proc list_all_views {{db db}} { set res [list] $db eval { PRAGMA database_list } { set tbl "$name.sqlite_master" - if {$name == "temp"} { set tbl sqlite_temp_master } + if {$name == "temp"} { set tbl temp.sqlite_master } set sql "SELECT '$name.' || name FROM $tbl WHERE type = 'view'" lappend res {*}[$db eval $sql] diff --git a/test/fkey2.test b/test/fkey2.test index aec75ed693..c2ae3788f5 100644 --- a/test/fkey2.test +++ b/test/fkey2.test @@ -1062,7 +1062,7 @@ ifcapable altertable { PRAGMA foreign_keys = off; ALTER TABLE t2 ADD COLUMN h DEFAULT 'text' REFERENCES t1; PRAGMA foreign_keys = on; - SELECT sql FROM sqlite_temp_master WHERE name='t2'; + SELECT sql FROM temp.sqlite_master WHERE name='t2'; } } {{CREATE TABLE t2(a, b, c REFERENCES t1, d DEFAULT NULL REFERENCES t1, e REFERENCES t1 DEFAULT NULL, h DEFAULT 'text' REFERENCES t1)}} @@ -1093,7 +1093,7 @@ ifcapable altertable { ] do_test fkey2-14.2tmp.2.2 { execsql { ALTER TABLE t1 RENAME TO t4 } - execsql { SELECT sql FROM sqlite_temp_master WHERE type = 'table'} + execsql { SELECT sql FROM temp.sqlite_master WHERE type = 'table'} } [list \ {CREATE TABLE "t4"(a PRIMARY KEY, b REFERENCES "t4")} \ {CREATE TABLE t2(a PRIMARY KEY, b REFERENCES "t4", c REFERENCES t2)} \ diff --git a/test/incrblob4.test b/test/incrblob4.test index 01ee37a087..dbff8eb7d5 100644 --- a/test/incrblob4.test +++ b/test/incrblob4.test @@ -107,4 +107,3 @@ do_test 4.4 { close $blob finish_test - diff --git a/test/intarray.test b/test/intarray.test index 2aba080bd4..5c70ebaf1a 100644 --- a/test/intarray.test +++ b/test/intarray.test @@ -42,7 +42,7 @@ do_test intarray-1.1 { set ia3 [sqlite3_intarray_create db ia3] set ia4 [sqlite3_intarray_create db ia4] db eval { - SELECT type, name FROM sqlite_temp_master + SELECT type, name FROM temp.sqlite_master ORDER BY name } } {table ia1 table ia2 table ia3 table ia4} diff --git a/test/interrupt.test b/test/interrupt.test index 92ab4c3265..8774aee860 100644 --- a/test/interrupt.test +++ b/test/interrupt.test @@ -128,7 +128,7 @@ ifcapable tempdb { } {1 interrupted} do_test interrupt-3.$i.3 { execsql { - SELECT name FROM sqlite_temp_master; + SELECT name FROM temp.sqlite_master; } } {} do_test interrupt-3.$i.4 { @@ -139,7 +139,7 @@ ifcapable tempdb { do_test interrupt-3.$i.5 { catchsql {SELECT name FROM sqlite_temp_master}; execsql { - SELECT name FROM sqlite_temp_master; + SELECT name FROM temp.sqlite_master; } } {} } diff --git a/test/regexp2.test b/test/regexp2.test index 9928e8ce8e..e3922042cc 100644 --- a/test/regexp2.test +++ b/test/regexp2.test @@ -122,4 +122,3 @@ do_execsql_test 3.0 { finish_test - diff --git a/test/rowvalue.test b/test/rowvalue.test index 48fa8bc4d7..1e59bb5df9 100644 --- a/test/rowvalue.test +++ b/test/rowvalue.test @@ -317,5 +317,3 @@ foreach {tn n sql} { finish_test - - diff --git a/test/rowvalue9.test b/test/rowvalue9.test index ce324f0b42..0fa652f97d 100644 --- a/test/rowvalue9.test +++ b/test/rowvalue9.test @@ -299,4 +299,3 @@ do_execsql_test 7.3 { finish_test - diff --git a/test/rowvaluefault.test b/test/rowvaluefault.test index 0a4da6ba47..ac1b236ba4 100644 --- a/test/rowvaluefault.test +++ b/test/rowvaluefault.test @@ -69,4 +69,3 @@ do_faultsim_test 6 -faults oom* -body { } finish_test - diff --git a/test/schema4.test b/test/schema4.test index 6618d75388..9b794ee555 100644 --- a/test/schema4.test +++ b/test/schema4.test @@ -149,7 +149,7 @@ ifcapable altertable { } {} do_execsql_test schema4-2.8 { - select sql from sqlite_temp_master WHERE type='table'; + select sql from temp.sqlite_master WHERE type='table'; } {{CREATE TABLE x1(x)}} do_execsql_test schema4-2.7 { ALTER TABLE tbl RENAME TO tbl2 } {} diff --git a/test/snapshot2.test b/test/snapshot2.test index 62d3070ecd..41e555258b 100644 --- a/test/snapshot2.test +++ b/test/snapshot2.test @@ -198,5 +198,3 @@ do_test 4.7 { } {1 SQLITE_ERROR} finish_test - - diff --git a/test/tempdb2.test b/test/tempdb2.test index bc2822e71e..5f019bd117 100644 --- a/test/tempdb2.test +++ b/test/tempdb2.test @@ -74,4 +74,3 @@ do_execsql_test 1.4 { } {1 1 1} finish_test - diff --git a/test/temptrigger.test b/test/temptrigger.test index 551c620479..e4277adf65 100644 --- a/test/temptrigger.test +++ b/test/temptrigger.test @@ -236,7 +236,7 @@ do_test 5.1 { do_execsql_test 5.2 { SELECT * FROM sqlite_master; - SELECT * FROM sqlite_temp_master; + SELECT * FROM temp.sqlite_master; } { trigger tr1 t1 0 {CREATE TRIGGER tr1 BEFORE INSERT ON t1 BEGIN SELECT 1,2,3; END} diff --git a/test/tkt3630.test b/test/tkt3630.test index b329c48dcf..1fe7ce70fa 100644 --- a/test/tkt3630.test +++ b/test/tkt3630.test @@ -23,7 +23,7 @@ source $testdir/tester.tcl do_test tkt3630-1 { db eval { CREATE TEMP TABLE temp1(a,b,c); - SELECT * FROM sqlite_temp_master WHERE sql GLOB '*TEMP*'; + SELECT * FROM temp.sqlite_master WHERE sql GLOB '*TEMP*'; } } {} do_test tkt3630-2 { @@ -39,7 +39,7 @@ ifcapable altertable { db eval { ALTER TABLE temp2 ADD COLUMN d; ALTER TABLE temp2 RENAME TO temp2rn; - SELECT name FROM sqlite_temp_master WHERE name LIKE 'temp2%'; + SELECT name FROM temp.sqlite_master WHERE name LIKE 'temp2%'; } } {temp2rn} } diff --git a/test/tkt3810.test b/test/tkt3810.test index 7e1b2ec5c9..f15eb7d63a 100644 --- a/test/tkt3810.test +++ b/test/tkt3810.test @@ -62,7 +62,7 @@ do_test tkt3810-3 { # an orphan. # do_test tkt3810-4 { - execsql {SELECT name FROM sqlite_temp_master ORDER BY name} + execsql {SELECT name FROM temp.sqlite_master ORDER BY name} } {r1} # Because it is an orphan, it cannot be dropped. diff --git a/test/without_rowid3.test b/test/without_rowid3.test index 2af43a9191..387a213b99 100644 --- a/test/without_rowid3.test +++ b/test/without_rowid3.test @@ -1031,7 +1031,7 @@ ifcapable altertable { PRAGMA foreign_keys = off; ALTER TABLE t2 ADD COLUMN h DEFAULT 'text' REFERENCES t1; PRAGMA foreign_keys = on; - SELECT sql FROM sqlite_temp_master WHERE name='t2'; + SELECT sql FROM temp.sqlite_master WHERE name='t2'; } } {{CREATE TABLE t2(a, b, c REFERENCES t1, d DEFAULT NULL REFERENCES t1, e REFERENCES t1 DEFAULT NULL, h DEFAULT 'text' REFERENCES t1)}} @@ -1064,7 +1064,7 @@ ifcapable altertable { ] do_test without_rowid3-14.2tmp.2.2 { execsql { ALTER TABLE t1 RENAME TO t4 } - execsql { SELECT sql FROM sqlite_temp_master WHERE type = 'table'} + execsql { SELECT sql FROM temp.sqlite_master WHERE type = 'table'} } [list \ {CREATE TABLE "t4"(a PRIMARY KEY, b REFERENCES "t4") WITHOUT rowid} \ {CREATE TABLE t2(a PRIMARY KEY, b REFERENCES "t4", c REFERENCES t2) From 9a63f092044f8e7749394b47d15c41b437762b89 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 16 Dec 2016 02:14:15 +0000 Subject: [PATCH 1094/1484] Minor bug fixes and enhancements to the pragma eponymous virtual tables. FossilOrigin-Name: 3f8f461504139a4efea0e033e3a274cc4b2d3072 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/pragma.c | 18 +++++++++++------- src/vtab.c | 1 + 4 files changed, 20 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index a7d760429e..4307d5eedb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\senhancements\sfrom\strunk,\sand\sespecially\sthe\sability\sto\suse\ntemp.sqlite_master\sas\san\salias\sfor\ssqlite_temp_master. -D 2016-12-16T01:09:22.413 +C Minor\sbug\sfixes\sand\senhancements\sto\sthe\spragma\seponymous\svirtual\stables. +D 2016-12-16T02:14:15.843 F Makefile.in c194b58fe00c370a48ac6ae6945e92a7781db1c8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -381,7 +381,7 @@ F src/parse.y 29153738a7322054359320eb00b5a4cd44389f20 F src/pcache.c 51070ec9b8251bbf9c6ea3d35fd96a458752929e F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 F src/pcache1.c e3967219b2a92b9edcb9324a4ba75009090d3953 -F src/pragma.c 41f18267db44df49756c3c3cdc695e701e169a63 +F src/pragma.c 767a41128464e8dfb8a86449bdd0ce8ad57c7420 F src/pragma.h f9b221b2c8949ea941dbee49934299e4ed5af41c F src/prepare.c b1140c3d0cf59bc85ace00ce363153041b424b7a F src/printf.c f94da4935d1dd25420ac50c6745db1deb35e07c1 @@ -464,7 +464,7 @@ F src/vdbeblob.c f4f98ea672b242f807c08c92c7faaa79e5091b65 F src/vdbemem.c d3fd85b7b7ef3eb75de29c6d7e1d10d3ca78b4fd F src/vdbesort.c bb34eed4fb52e11ac037dccea4ee3190594c7f9e F src/vdbetrace.c 41963d5376f0349842b5fc4aaaaacd7d9cdc0834 -F src/vtab.c 104907646940e597f60debb42e7e0981b276dcaa +F src/vtab.c c4bbe0f870f52036553f8098aee0703997f0577a F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 40c543f0a2195d1b0dc88ef12142bea690009344 F src/wal.h 06b2a0b599cc0f53ea97f497cf8c6b758c999f71 @@ -1536,7 +1536,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 7126807a186746a8663fbaa267d63214d06476e4 8d646905b830d5bb29092e103ac5cb499b3c7e5a -R c03b90088a1e080799e09d2f075e1354 +P 994a4401f5c34fed17af420761291b03072a5ea1 +R afd4feda84f0d8c4e20e6eee8d9eee4f U drh -Z 3b955bd6345f72aad83fc556ff64eb52 +Z 47dbd97e4f7c38d810ba53087789cc3e diff --git a/manifest.uuid b/manifest.uuid index 4b11bf1ff2..ea7bf347b0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -994a4401f5c34fed17af420761291b03072a5ea1 \ No newline at end of file +3f8f461504139a4efea0e033e3a274cc4b2d3072 \ No newline at end of file diff --git a/src/pragma.c b/src/pragma.c index 6b3b84b4a4..dca019c088 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -2002,6 +2002,11 @@ static int pragmaVtabConnect( sqlite3XPrintf(&acc, "%c\"%s\"", cSep, pragCName[j]); cSep = ','; } + if( i==0 ){ + sqlite3XPrintf(&acc, "(\"%s\"", pPragma->zName); + cSep = ','; + i++; + } j = 0; if( pPragma->mPragFlg & PragFlg_Result1 ){ sqlite3StrAccumAppendAll(&acc, ",arg HIDDEN"); @@ -2067,7 +2072,6 @@ static int pragmaVtabBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ if( pConstraint->iColumn < pTab->iHidden ) continue; j = pConstraint->iColumn - pTab->iHidden; assert( j < 2 ); - if( seen[j] ) continue; seen[j] = i+1; } if( seen[0]==0 ){ @@ -2113,6 +2117,7 @@ static void pragmaVtabCursorClear(PragmaVtabCursor *pCsr){ static int pragmaVtabClose(sqlite3_vtab_cursor *cur){ PragmaVtabCursor *pCsr = (PragmaVtabCursor*)cur; pragmaVtabCursorClear(pCsr); + sqlite3_free(pCsr); return SQLITE_OK; } @@ -2123,12 +2128,11 @@ static int pragmaVtabNext(sqlite3_vtab_cursor *pVtabCursor){ /* Increment the xRowid value */ pCsr->iRowid++; - if( pCsr->pPragma ){ - if( SQLITE_ROW!=sqlite3_step(pCsr->pPragma) ){ - rc = sqlite3_finalize(pCsr->pPragma); - pCsr->pPragma = 0; - pragmaVtabCursorClear(pCsr); - } + assert( pCsr->pPragma ); + if( SQLITE_ROW!=sqlite3_step(pCsr->pPragma) ){ + rc = sqlite3_finalize(pCsr->pPragma); + pCsr->pPragma = 0; + pragmaVtabCursorClear(pCsr); } return rc; } diff --git a/src/vtab.c b/src/vtab.c index 7fc1bb7519..30079cbb5e 100644 --- a/src/vtab.c +++ b/src/vtab.c @@ -57,6 +57,7 @@ Module *sqlite3VtabCreateModule( if( pDel ){ sqlite3OomFault(db); sqlite3DbFree(db, pDel); + pMod = 0; } } return pMod; From 30776acd74f1b3a8cfc2089574642c9d82b9d174 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 16 Dec 2016 02:31:50 +0000 Subject: [PATCH 1095/1484] Simplifications to facilitate full test coverage. FossilOrigin-Name: 01afc515970a868c6a36d9a598453d0fde9e39ca --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/build.c | 3 +-- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 4307d5eedb..671afaa9b4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Minor\sbug\sfixes\sand\senhancements\sto\sthe\spragma\seponymous\svirtual\stables. -D 2016-12-16T02:14:15.843 +C Simplifications\sto\sfacilitate\sfull\stest\scoverage. +D 2016-12-16T02:31:50.286 F Makefile.in c194b58fe00c370a48ac6ae6945e92a7781db1c8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -334,7 +334,7 @@ F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 F src/btree.c b2055dff0b94e03eaad48a760984a2d8e39244e6 F src/btree.h 2349a588abcd7e0c04f984e15c5c777b61637583 F src/btreeInt.h 10c4b77c2fb399580babbcc7cf652ac10dba796e -F src/build.c ec9e3595d74690af28595cfda996da0fc9dba27f +F src/build.c 52970b6cf3cf3107551a5d6dd668b0b261b0b491 F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 9f2296a4e5d26ebf0e0d95a0af4628f1ea694e7a @@ -1536,7 +1536,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 994a4401f5c34fed17af420761291b03072a5ea1 -R afd4feda84f0d8c4e20e6eee8d9eee4f +P 3f8f461504139a4efea0e033e3a274cc4b2d3072 +R 691580f444d968a1280c44f14b7468b6 U drh -Z 47dbd97e4f7c38d810ba53087789cc3e +Z fe17a4b90cecec95c309ae2fb5e6d93a diff --git a/manifest.uuid b/manifest.uuid index ea7bf347b0..007f3751c5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3f8f461504139a4efea0e033e3a274cc4b2d3072 \ No newline at end of file +01afc515970a868c6a36d9a598453d0fde9e39ca \ No newline at end of file diff --git a/src/build.c b/src/build.c index 30bc645eca..1dfa998d78 100644 --- a/src/build.c +++ b/src/build.c @@ -320,8 +320,7 @@ Table *sqlite3FindTable(sqlite3 *db, const char *zName, const char *zDatabase){ /* Not found. If the name we were looking for was temp.sqlite_master ** then change the name to sqlite_temp_master and try again. */ if( sqlite3StrICmp(zName, MASTER_NAME)!=0 ) break; - if( zDatabase==0 ) break; - if( sqlite3StrICmp(zDatabase, db->aDb[1].zDbSName)!=0 ) break; + if( sqlite3_stricmp(zDatabase, db->aDb[1].zDbSName)!=0 ) break; zName = TEMP_MASTER_NAME; } return 0; From d8b7200b84e379723a695527aaa4fb7818b541bd Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 16 Dec 2016 04:20:27 +0000 Subject: [PATCH 1096/1484] Fix an error in the way the "schema" argument to some pragma virtual tables is handled. FossilOrigin-Name: 546821e29edb0282a4b1d8f49512e36027a6bf6d --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/pragma.c | 11 ++++++----- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 671afaa9b4..4d0b8539bf 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Simplifications\sto\sfacilitate\sfull\stest\scoverage. -D 2016-12-16T02:31:50.286 +C Fix\san\serror\sin\sthe\sway\sthe\s"schema"\sargument\sto\ssome\spragma\svirtual\stables\nis\shandled. +D 2016-12-16T04:20:27.559 F Makefile.in c194b58fe00c370a48ac6ae6945e92a7781db1c8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -381,7 +381,7 @@ F src/parse.y 29153738a7322054359320eb00b5a4cd44389f20 F src/pcache.c 51070ec9b8251bbf9c6ea3d35fd96a458752929e F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 F src/pcache1.c e3967219b2a92b9edcb9324a4ba75009090d3953 -F src/pragma.c 767a41128464e8dfb8a86449bdd0ce8ad57c7420 +F src/pragma.c d5adfe89ad7f3f45d4dbd25b96cbf3f6611aea2a F src/pragma.h f9b221b2c8949ea941dbee49934299e4ed5af41c F src/prepare.c b1140c3d0cf59bc85ace00ce363153041b424b7a F src/printf.c f94da4935d1dd25420ac50c6745db1deb35e07c1 @@ -1536,7 +1536,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 3f8f461504139a4efea0e033e3a274cc4b2d3072 -R 691580f444d968a1280c44f14b7468b6 +P 01afc515970a868c6a36d9a598453d0fde9e39ca +R a742a8093b3e07485d2949a360f59e06 U drh -Z fe17a4b90cecec95c309ae2fb5e6d93a +Z b26c88cbc10f1352d564598308e683f5 diff --git a/manifest.uuid b/manifest.uuid index 007f3751c5..e8e79b2cfb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -01afc515970a868c6a36d9a598453d0fde9e39ca \ No newline at end of file +546821e29edb0282a4b1d8f49512e36027a6bf6d \ No newline at end of file diff --git a/src/pragma.c b/src/pragma.c index dca019c088..d84e1d7929 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -2148,15 +2148,16 @@ static int pragmaVtabFilter( PragmaVtabCursor *pCsr = (PragmaVtabCursor*)pVtabCursor; PragmaVtab *pTab = (PragmaVtab*)(pVtabCursor->pVtab); int rc; - int i; + int i, j; StrAccum acc; char *zSql; pragmaVtabCursorClear(pCsr); - for(i=0; iazArg) ); - pCsr->azArg[i] = sqlite3_mprintf("%s", sqlite3_value_text(argv[i])); - if( pCsr->azArg[i]==0 ){ + j = (pTab->pName->mPragFlg & PragFlg_Result1)!=0 ? 0 : 1; + for(i=0; iazArg) ); + pCsr->azArg[j] = sqlite3_mprintf("%s", sqlite3_value_text(argv[i])); + if( pCsr->azArg[j]==0 ){ return SQLITE_NOMEM; } } From 69b9383edf56a44591e7b47c1c97339e7cebd956 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 16 Dec 2016 15:05:40 +0000 Subject: [PATCH 1097/1484] Fix a problem causing the planner to generate sub-optimal plans for some queries that use recursive WITH sub-queries with LIMIT clauses. FossilOrigin-Name: 053a149cc8244a7f85137129cfcb8622efe90306 --- manifest | 16 +++++++------- manifest.uuid | 2 +- src/select.c | 5 ++++- test/with3.test | 56 +++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 69 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index ca47317dff..b952a95fe5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C All\stemp.sqlite_master\sto\sbe\sused\sas\san\salias\sfor\ssqlite_temp_master. -D 2016-12-16T01:00:21.326 +C Fix\sa\sproblem\scausing\sthe\splanner\sto\sgenerate\ssub-optimal\splans\sfor\ssome\squeries\nthat\suse\srecursive\sWITH\ssub-queries\swith\sLIMIT\sclauses. +D 2016-12-16T15:05:40.539 F Makefile.in c194b58fe00c370a48ac6ae6945e92a7781db1c8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -388,7 +388,7 @@ F src/printf.c f94da4935d1dd25420ac50c6745db1deb35e07c1 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c bb070cf5f23611c44ab7e4788803684e385fc3fb F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac -F src/select.c 204491a5e09a66380a067943d8651af8bda1d358 +F src/select.c e4c687333c5fa33b1ce05c37bfbea6e09d3dbee9 F src/shell.c f1c7fde7a83421e6ed620df41d200674a2327e65 F src/sqlite.h.in e8e2d108d82647f0a812fdb74accf91c1ec08ddc F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1436,7 +1436,7 @@ F test/win32longpath.test 169c75a3b2e43481f4a62122510210c67b08f26d F test/win32nolock.test ac4f08811a562e45a5755e661f45ca85892bdbbc F test/with1.test cef099a491eac9874f2c28bd2dc86394fb3e47b3 F test/with2.test 2b40da883658eb74ad8ad06afabe11a408e7fb87 -F test/with3.test 511bacdbe41c49cf34f9fd1bd3245fe1575bca98 +F test/with3.test e71604a0e53cba82bc04c703987cb1d6751ec0b6 F test/withM.test 693b61765f2b387b5e3e24a4536e2e82de15ff64 F test/without_rowid1.test 1a7b9bd51b899928d327052df9741d2fe8dbe701 F test/without_rowid2.test af260339f79d13cb220288b67cd287fbcf81ad99 @@ -1536,7 +1536,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 4e3749127e7249f46e17bfabc614b0876f60565a -R 27200c6ed9ee619c25ffbd7fc5b77433 -U drh -Z dbd7760e0bb1a8efbcd514dce9f9a0ad +P 8d646905b830d5bb29092e103ac5cb499b3c7e5a +R 147fd014e993bf990284d024622f7825 +U dan +Z ececc9941f2e958f0280d3f055b0e66d diff --git a/manifest.uuid b/manifest.uuid index da81604870..7e8bf801a0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8d646905b830d5bb29092e103ac5cb499b3c7e5a \ No newline at end of file +053a149cc8244a7f85137129cfcb8622efe90306 \ No newline at end of file diff --git a/src/select.c b/src/select.c index 83d9540cf0..18344b7d43 100644 --- a/src/select.c +++ b/src/select.c @@ -2037,6 +2037,7 @@ static void generateWithRecursiveQuery( /* Process the LIMIT and OFFSET clauses, if they exist */ addrBreak = sqlite3VdbeMakeLabel(v); + p->nSelectRow = 320; /* 4 billion rows */ computeLimitRegisters(pParse, p, addrBreak); pLimit = p->pLimit; pOffset = p->pOffset; @@ -5170,7 +5171,9 @@ int sqlite3Select( /* Set the limiter. */ iEnd = sqlite3VdbeMakeLabel(v); - p->nSelectRow = 320; /* 4 billion rows */ + if( (p->selFlags & SF_FixedLimit)==0 ){ + p->nSelectRow = 320; /* 4 billion rows */ + } computeLimitRegisters(pParse, p, iEnd); if( p->iLimit==0 && sSort.addrSortIndex>=0 ){ sqlite3VdbeChangeOpcode(v, sSort.addrSortIndex, OP_SorterOpen); diff --git a/test/with3.test b/test/with3.test index 62e88441ab..5540a7fca6 100644 --- a/test/with3.test +++ b/test/with3.test @@ -61,4 +61,60 @@ do_execsql_test 2.1 { SELECT * FROM t1; } {200} +#------------------------------------------------------------------------- +# Test that the planner notices LIMIT clauses on recursive WITH queries. +# + +ifcapable analyze { + do_execsql_test 3.1.1 { + CREATE TABLE y1(a, b); + CREATE INDEX y1a ON y1(a); + + WITH cnt(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM cnt LIMIT 1000) + INSERT INTO y1 SELECT i%10, i FROM cnt; + ANALYZE; + + } + + do_eqp_test 3.1.2 { + WITH cnt(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM cnt LIMIT 1) + SELECT * FROM cnt, y1 WHERE i=a + } { + 3 0 0 {SCAN TABLE cnt} + 1 0 0 {COMPOUND SUBQUERIES 0 AND 0 (UNION ALL)} + 0 0 0 {SCAN SUBQUERY 1} + 0 1 1 {SEARCH TABLE y1 USING INDEX y1a (a=?)} + } + + do_eqp_test 3.1.3 { + WITH cnt(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM cnt LIMIT 1000000) + SELECT * FROM cnt, y1 WHERE i=a + } { + 3 0 0 {SCAN TABLE cnt} + 1 0 0 {COMPOUND SUBQUERIES 0 AND 0 (UNION ALL)} + 0 0 1 {SCAN TABLE y1} + 0 1 0 {SEARCH SUBQUERY 1 USING AUTOMATIC COVERING INDEX (i=?)} + } +} + +do_execsql_test 3.2.1 { + CREATE TABLE w1(pk INTEGER PRIMARY KEY, x INTEGER); + CREATE TABLE w2(pk INTEGER PRIMARY KEY); +} + +do_eqp_test 3.2.2 { + WITH RECURSIVE c(w,id) AS (SELECT 0, (SELECT pk FROM w2 LIMIT 1) + UNION ALL SELECT c.w + 1, x FROM w1, c LIMIT 1) + SELECT * FROM c, w2, w1 + WHERE c.id=w2.pk AND c.id=w1.pk; +} { + 2 0 0 {EXECUTE SCALAR SUBQUERY 3} + 3 0 0 {SCAN TABLE w2} + 4 0 0 {SCAN TABLE w1} + 4 1 1 {SCAN TABLE c} + 1 0 0 {COMPOUND SUBQUERIES 0 AND 0 (UNION ALL)} 0 0 0 {SCAN SUBQUERY 1} + 0 1 1 {SEARCH TABLE w2 USING INTEGER PRIMARY KEY (rowid=?)} + 0 2 2 {SEARCH TABLE w1 USING INTEGER PRIMARY KEY (rowid=?)} +} + finish_test From dd9e0be46aedab029eeaa487b61e2bd31ac31eb7 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 16 Dec 2016 16:44:27 +0000 Subject: [PATCH 1098/1484] Update .fkey_missing_indexes to use the built-in pragma vtabs. FossilOrigin-Name: 3ab05987b0cc12af64bf32d885d04aff45d7a77c --- manifest | 12 +- manifest.uuid | 2 +- src/shell.c | 370 +++++++++----------------------------------------- 3 files changed, 71 insertions(+), 313 deletions(-) diff --git a/manifest b/manifest index fd8c4d7b2f..9287923a08 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sthe\spragma-as-vtab\schange\sinto\sthis\sbranch. -D 2016-12-16T16:13:45.218 +C Update\s.fkey_missing_indexes\sto\suse\sthe\sbuilt-in\spragma\svtabs. +D 2016-12-16T16:44:27.209 F Makefile.in c194b58fe00c370a48ac6ae6945e92a7781db1c8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -389,7 +389,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c bb070cf5f23611c44ab7e4788803684e385fc3fb F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c 204491a5e09a66380a067943d8651af8bda1d358 -F src/shell.c 331be7c5d82477baff3ab584f1dc679e9676e0ef +F src/shell.c 667382b94e1ba301960cbf34db96d25afe219892 F src/sqlite.h.in e8e2d108d82647f0a812fdb74accf91c1ec08ddc F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae @@ -1537,7 +1537,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 976c51b4836dfba2ce9b246334a85bda08ac526f 546821e29edb0282a4b1d8f49512e36027a6bf6d -R 30e9fb459cb16eb6392de3bdb60521ee +P 4ba45e722371ca4343e3563e7e1c2896b48c9a87 +R 5944ad7aef550b0c7873733cf5d30c76 U dan -Z 8d92568d6acf97185670c4652b437304 +Z 1d6e2ebe082c25e976b4f2822f56282f diff --git a/manifest.uuid b/manifest.uuid index f61f9ac100..eae7fa71fb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4ba45e722371ca4343e3563e7e1c2896b48c9a87 \ No newline at end of file +3ab05987b0cc12af64bf32d885d04aff45d7a77c \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index b0bd9c6ece..164d2b0d67 100644 --- a/src/shell.c +++ b/src/shell.c @@ -3258,285 +3258,12 @@ int shellDeleteFile(const char *zFilename){ /************************************************************************** ** Beginning of implementation of .fkey_missing_indexes */ -typedef struct PragmaVtab PragmaVtab; -typedef struct PragmaCursor PragmaCursor; -typedef struct PragmaConfig PragmaConfig; /* -** Table structure for "pragma" eponymous virtual tables. -*/ -struct PragmaVtab { - sqlite3_vtab base; - PragmaConfig *pConfig; - sqlite3 *db; -}; - -/* -** Cursor structure for "pragma" eponymous virtual tables. -*/ -struct PragmaCursor { - sqlite3_vtab_cursor base; - sqlite3_stmt *pSelect; - sqlite3_stmt *pPragma; - sqlite_int64 iRowid; -}; - -struct PragmaConfig { - const char *zModule; - const char *zSchema; - const char *zPragma; -}; - -/* -** Pragma virtual table module xConnect method. -*/ -static int shellPragmaConnect( - sqlite3 *db, - void *pAux, - int argc, const char *const*argv, - sqlite3_vtab **ppVtab, - char **pzErr -){ - PragmaConfig *pConfig = (PragmaConfig*)pAux; - PragmaVtab *pTab = 0; - int rc; - - rc = sqlite3_declare_vtab(db, pConfig->zSchema); - if( rc==SQLITE_OK ){ - pTab = (PragmaVtab*)sqlite3_malloc(sizeof(PragmaVtab)); - if( pTab==0 ){ - rc = SQLITE_NOMEM; - }else{ - memset(pTab, 0, sizeof(PragmaVtab)); - pTab->db = db; - pTab->pConfig = pConfig; - } - }else{ - *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db)); - } - - *ppVtab = (sqlite3_vtab*)pTab; - return rc; -} - -/* -** Pragma virtual table module xDisconnect method. -*/ -static int shellPragmaDisconnect(sqlite3_vtab *pVtab){ - PragmaVtab *pTab = (PragmaVtab*)pVtab; - sqlite3_free(pTab); - return SQLITE_OK; -} - -/* -** Pragma virtual table module xBestIndex method. -*/ -static int shellPragmaBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ - return SQLITE_OK; -} - -/* -** Pragma virtual table module xOpen method. -*/ -static int shellPragmaOpen(sqlite3_vtab *pVtab, sqlite3_vtab_cursor **ppCursor){ - PragmaCursor *pCsr; - - pCsr = (PragmaCursor*)sqlite3_malloc(sizeof(PragmaCursor)); - if( pCsr==0 ) return SQLITE_NOMEM; - memset(pCsr, 0, sizeof(PragmaCursor)); - pCsr->base.pVtab = pVtab; - - *ppCursor = (sqlite3_vtab_cursor*)pCsr; - return SQLITE_OK; -} - -/* -** Pragma virtual table module xClose method. -*/ -static int shellPragmaClose(sqlite3_vtab_cursor *cur){ - return SQLITE_OK; -} - -/* -** Pragma virtual table module xNext method. -*/ -static int shellPragmaNext(sqlite3_vtab_cursor *pVtabCursor){ - PragmaCursor *pCsr = (PragmaCursor*)pVtabCursor; - PragmaVtab *pTab = (PragmaVtab*)(pVtabCursor->pVtab); - sqlite3 *db = pTab->db; - int rc = SQLITE_OK; - - /* Increment the xRowid value */ - pCsr->iRowid++; - - while( 1 ){ - assert( rc==SQLITE_OK ); - - if( pCsr->pPragma ){ - if( SQLITE_ROW!=sqlite3_step(pCsr->pPragma) ){ - rc = sqlite3_finalize(pCsr->pPragma); - pCsr->pPragma = 0; - } - } - - if( rc==SQLITE_OK && pCsr->pPragma==0 ){ - if( SQLITE_ROW!=sqlite3_step(pCsr->pSelect) ){ - rc = sqlite3_finalize(pCsr->pSelect); - pCsr->pSelect = 0; - }else{ - const char *zName = (const char*)sqlite3_column_text(pCsr->pSelect, 0); - char *zSql = sqlite3_mprintf(pTab->pConfig->zPragma, zName); - if( zSql==0 ){ - rc = SQLITE_NOMEM; - }else{ - rc = sqlite3_prepare_v2(db, zSql, -1, &pCsr->pPragma, 0); - if( rc!=SQLITE_OK ){ - pTab->base.zErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(db)); - }else{ - continue; - } - } - } - } - - break; - } - - return rc; -} - -/* -** Pragma virtual table module xFilter method. -*/ -static int shellPragmaFilter( - sqlite3_vtab_cursor *pVtabCursor, - int idxNum, const char *idxStr, - int argc, sqlite3_value **argv -){ - PragmaCursor *pCsr = (PragmaCursor*)pVtabCursor; - PragmaVtab *pTab = (PragmaVtab*)(pVtabCursor->pVtab); - int rc; - - sqlite3_finalize(pCsr->pSelect); - sqlite3_finalize(pCsr->pPragma); - pCsr->pSelect = 0; - pCsr->pPragma = 0; - pCsr->iRowid = 0; - - rc = sqlite3_prepare_v2(pTab->db, - "SELECT name FROM sqlite_master WHERE type = 'table' AND rootpage>0", - -1, &pCsr->pSelect, 0 - ); - if( rc!=SQLITE_OK ){ - pTab->base.zErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(pTab->db)); - return rc; - } - - return shellPragmaNext(pVtabCursor); -} - -/* -** Pragma virtual table module xEof method. -*/ -static int shellPragmaEof(sqlite3_vtab_cursor *pVtabCursor){ - PragmaCursor *pCsr = (PragmaCursor*)pVtabCursor; - return (pCsr->pSelect==0); -} - -/* -** Pragma virtual table module xColumn method. -*/ -static int shellPragmaColumn( - sqlite3_vtab_cursor *pVtabCursor, - sqlite3_context *ctx, - int i -){ - PragmaCursor *pCsr = (PragmaCursor*)pVtabCursor; - switch( i ){ - case 0: /* "database" */ - sqlite3_result_text(ctx, "main", -1, SQLITE_STATIC); - break; - - case 1: /* "child"/"table" */ - sqlite3_result_value(ctx, sqlite3_column_value(pCsr->pSelect, 0)); - break; - - default: - sqlite3_result_value(ctx, sqlite3_column_value(pCsr->pPragma, i-2)); - break; - } - - return SQLITE_OK; -} - -/* -** Pragma virtual table module xRowid method. -*/ -static int shellPragmaRowid(sqlite3_vtab_cursor *pVtabCursor, sqlite_int64 *p){ - PragmaCursor *pCsr = (PragmaCursor*)pVtabCursor; - *p = pCsr->iRowid; - return SQLITE_OK; -} - -/* -** Register the virtual table module with the supplied database handle. -*/ -static int shellPragmaRegister(sqlite3 *db){ - static sqlite3_module shellPragmaModule = { - 0, /* iVersion */ - shellPragmaConnect, /* xCreate - create a table */ - shellPragmaConnect, /* xConnect - connect to an existing table */ - shellPragmaBestIndex, /* xBestIndex - Determine search strategy */ - shellPragmaDisconnect, /* xDisconnect - Disconnect from a table */ - shellPragmaDisconnect, /* xDestroy - Drop a table */ - shellPragmaOpen, /* xOpen - open a cursor */ - shellPragmaClose, /* xClose - close a cursor */ - shellPragmaFilter, /* xFilter - configure scan constraints */ - shellPragmaNext, /* xNext - advance a cursor */ - shellPragmaEof, /* xEof */ - shellPragmaColumn, /* xColumn - read data */ - shellPragmaRowid, /* xRowid - read data */ - 0, /* xUpdate - write data */ - 0, /* xBegin - begin transaction */ - 0, /* xSync - sync transaction */ - 0, /* xCommit - commit transaction */ - 0, /* xRollback - rollback transaction */ - 0, /* xFindFunction - function overloading */ - 0, /* xRename - rename the table */ - 0, /* xSavepoint */ - 0, /* xRelease */ - 0 /* xRollbackTo */ - }; - int rc = SQLITE_OK; - int i; - - static PragmaConfig aConfig[] = { - { "pragma_foreign_key_list", - "CREATE TABLE x(database, child, " - "id, seq, parent, child_col, parent_col, on_update, on_delete, match)", - "PRAGMA foreign_key_list = %Q" - }, - { "pragma_table_info", - "CREATE TABLE x(database, tbl, " - "cid, name, type, not_null, dflt_value, pk)", - "PRAGMA table_info = %Q" - } - }; - - for(i=0; rc==SQLITE_OK && idb; - FILE *out = pState->out; + sqlite3 *db = pState->db; /* Database handle to query "main" db of */ + FILE *out = pState->out; /* Stream to write non-error output to */ int bVerbose = 0; /* If -verbose is present */ int bGroupByParent = 0; /* If -groupbyparent is present */ - int i; - const char *zIndent = ""; + int i; /* To iterate through azArg[] */ + const char *zIndent = ""; /* How much to indent CREATE INDEX by */ + int rc; /* Return code */ + sqlite3_stmt *pSql = 0; /* Compiled version of SQL statement below */ - int rc; - sqlite3_stmt *pSql = 0; + /* + ** This SELECT statement returns one row for each foreign key constraint + ** in the schema of the main database. The column values are: + ** + ** 0. The text of an SQL statement similar to: + ** + ** "EXPLAIN QUERY PLAN SELECT rowid FROM child_table WHERE child_key=?" + ** + ** This is the same SELECT that the foreign keys implementation needs + ** to run internally on child tables. If there is an index that can + ** be used to optimize this query, then it can also be used by the FK + ** implementation to optimize DELETE or UPDATE statements on the parent + ** table. + ** + ** 1. A GLOB pattern suitable for sqlite3_strglob(). If the plan output by + ** the EXPLAIN QUERY PLAN command matches this pattern, then the schema + ** contains an index that can be used to optimize the query. + ** + ** 2. Human readable text that describes the child table and columns. e.g. + ** + ** "child_table(child_key1, child_key2)" + ** + ** 3. Human readable text that describes the parent table and columns. e.g. + ** + ** "parent_table(parent_key1, parent_key2)" + ** + ** 4. A full CREATE INDEX statement for an index that could be used to + ** optimize DELETE or UPDATE statements on the parent table. e.g. + ** + ** "CREATE INDEX child_table_child_key ON child_table(child_key)" + ** + ** 5. The name of the parent table. + ** + ** These six values are used by the C logic below to generate the report. + */ const char *zSql = - "SELECT " - " 'EXPLAIN QUERY PLAN SELECT rowid FROM ' || quote(child) || ' WHERE ' " - " || group_concat(quote(child) || '.' || quote(child_col) || '=?' || " - " fkey_collate_clause(parent, parent_col, child, child_col),' AND ')" + "SELECT " + " 'EXPLAIN QUERY PLAN SELECT rowid FROM ' || quote(s.name) || ' WHERE '" + " || group_concat(quote(s.name) || '.' || quote(f.[from]) || '=?' " + " || fkey_collate_clause(f.[table], f.[to], s.name, f.[from]),' AND ')" ", " - " 'SEARCH TABLE ' || child || ' USING COVERING INDEX*('" + " 'SEARCH TABLE ' || s.name || ' USING COVERING INDEX*('" " || group_concat('*=?', ' AND ') || ')'" ", " - " child || '(' || group_concat(child_col, ', ') || ')'" + " s.name || '(' || group_concat(f.[from], ', ') || ')'" ", " - " parent || '(' || group_concat(COALESCE(parent_col, " - " (SELECT name FROM pragma_table_info WHERE tbl=parent AND pk=seq+1)" + " f.[table] || '(' || group_concat(COALESCE(f.[to], " + " (SELECT name FROM pragma_table_info(f.[table]) WHERE pk=seq+1)" " )) || ')'" ", " - " 'CREATE INDEX ' || quote(child ||'_'|| group_concat(child_col, '_'))" - " || ' ON ' || quote(child) || '('" - " || group_concat(quote(child_col) ||" - " fkey_collate_clause(parent, parent_col, child, child_col), ', ')" + " 'CREATE INDEX ' || quote(s.name ||'_'|| group_concat(f.[from], '_'))" + " || ' ON ' || quote(s.name) || '('" + " || group_concat(quote(f.[from]) ||" + " fkey_collate_clause(f.[table], f.[to], s.name, f.[from]), ', ')" " || ');'" ", " - " parent " + " f.[table] " - "FROM pragma_foreign_key_list GROUP BY child, id " - "ORDER BY (CASE WHEN ? THEN parent ELSE CHILD END)" + "FROM sqlite_master AS s, pragma_foreign_key_list(s.name) AS f " + "GROUP BY s.name, f.id " + "ORDER BY (CASE WHEN ? THEN f.[table] ELSE s.name END)" ; for(i=1; i Date: Fri, 16 Dec 2016 17:28:56 +0000 Subject: [PATCH 1099/1484] Change ".fkey_missing_indexes" to ".lint fkey-indexes". FossilOrigin-Name: ee621ade38c11806e1df57c459da5f018a6d0670 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/shell.c | 46 +++++++++++++++++++++++++++++++--------------- test/shell6.test | 4 ++-- 4 files changed, 41 insertions(+), 25 deletions(-) diff --git a/manifest b/manifest index 9287923a08..ad23b1fdbe 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\s.fkey_missing_indexes\sto\suse\sthe\sbuilt-in\spragma\svtabs. -D 2016-12-16T16:44:27.209 +C Change\s".fkey_missing_indexes"\sto\s".lint\sfkey-indexes". +D 2016-12-16T17:28:56.295 F Makefile.in c194b58fe00c370a48ac6ae6945e92a7781db1c8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -389,7 +389,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c bb070cf5f23611c44ab7e4788803684e385fc3fb F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c 204491a5e09a66380a067943d8651af8bda1d358 -F src/shell.c 667382b94e1ba301960cbf34db96d25afe219892 +F src/shell.c 0f1f7935f9a18b5458fd8279d7995c2e1743bdc2 F src/sqlite.h.in e8e2d108d82647f0a812fdb74accf91c1ec08ddc F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae @@ -1094,7 +1094,7 @@ F test/shell2.test e242a9912f44f4c23c3d1d802a83e934e84c853b F test/shell3.test 9b95ba643eaa228376f06a898fb410ee9b6e57c1 F test/shell4.test 89ad573879a745974ff2df20ff97c5d6ffffbd5d F test/shell5.test 50a732c1c2158b1cd62cf53975ce1ea7ce6b9dc9 -F test/shell6.test e9ea06630bcd9ea10e14109f0e62c41571bcc1ae +F test/shell6.test 806472f6ffdd31d632e27dbe8515c0c45f68f3ec F test/shortread1.test bb591ef20f0fd9ed26d0d12e80eee6d7ac8897a3 F test/show_speedtest1_rtree.tcl 32e6c5f073d7426148a6936a0408f4b5b169aba5 F test/shrink.test 1b4330b1fd9e818c04726d45cb28db73087535ce @@ -1537,7 +1537,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 4ba45e722371ca4343e3563e7e1c2896b48c9a87 -R 5944ad7aef550b0c7873733cf5d30c76 +P 3ab05987b0cc12af64bf32d885d04aff45d7a77c +R 17b5d854673e0a0adb6375b01c294779 U dan -Z 1d6e2ebe082c25e976b4f2822f56282f +Z 080e8bf78fe63c73094cbd3615b790ed diff --git a/manifest.uuid b/manifest.uuid index eae7fa71fb..b8d8dbe1a3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3ab05987b0cc12af64bf32d885d04aff45d7a77c \ No newline at end of file +ee621ade38c11806e1df57c459da5f018a6d0670 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 164d2b0d67..27267918fd 100644 --- a/src/shell.c +++ b/src/shell.c @@ -3255,13 +3255,9 @@ int shellDeleteFile(const char *zFilename){ } -/************************************************************************** -** Beginning of implementation of .fkey_missing_indexes -*/ - /* ** The implementation of SQL scalar function fkey_collate_clause(), used -** by the ".fkey_missing_indexes" command. This scalar function is always +** by the ".lint fkey-indexes" command. This scalar function is always ** called with four arguments - the parent table name, the parent column name, ** the child table name and the child column name. ** @@ -3313,9 +3309,9 @@ static void shellFkeyCollateClause( /* -** The implementation of dot-command ".fkey_missing_indexes". +** The implementation of dot-command ".lint fkey-indexes". */ -static int shellFkeyMissingIndexes( +static int lintFkeyIndexes( ShellState *pState, /* Current shell tool state */ char **azArg, /* Array of arguments passed to dot command */ int nArg /* Number of entries in azArg[] */ @@ -3392,7 +3388,7 @@ static int shellFkeyMissingIndexes( "ORDER BY (CASE WHEN ? THEN f.[table] ELSE s.name END)" ; - for(i=1; i1 && sqlite3_strnicmp("-verbose", azArg[i], n)==0 ){ bVerbose = 1; @@ -3402,7 +3398,9 @@ static int shellFkeyMissingIndexes( zIndent = " "; } else{ - raw_printf(stderr, "Usage: .fkey_lint ?-verbose? ?-groupbyparent?\n"); + raw_printf(stderr, "Usage: %s %s ?-verbose? ?-groupbyparent?\n", + azArg[0], azArg[1] + ); return SQLITE_ERROR; } } @@ -3481,9 +3479,27 @@ static int shellFkeyMissingIndexes( return rc; } + /* -** End of implementation of .fkey_missing_indexes -**************************************************************************/ +** Implementation of ".lint" dot command. +*/ +static int lintDotCommand( + ShellState *pState, /* Current shell tool state */ + char **azArg, /* Array of arguments passed to dot command */ + int nArg /* Number of entries in azArg[] */ +){ + int n; + n = (nArg>=1 ? strlen(azArg[1]) : 0); + if( n<1 || sqlite3_strnicmp(azArg[1], "fkey-indexes", n) ) goto usage; + return lintFkeyIndexes(pState, azArg, nArg); + + usage: + raw_printf(stderr, "Usage %s sub-command ?switches...?\n", azArg[0]); + raw_printf(stderr, "Where sub-commands are:\n"); + raw_printf(stderr, " fkey-indexes\n"); + return SQLITE_ERROR; +} + /* ** If an input line begins with "." then invoke this routine to @@ -3798,10 +3814,6 @@ static int do_meta_command(char *zLine, ShellState *p){ } }else - if( c=='f' && strncmp(azArg[0], "fkey_missing_indexes", n)==0 ){ - shellFkeyMissingIndexes(p, azArg, nArg); - }else - if( c=='f' && strncmp(azArg[0], "fullschema", n)==0 ){ ShellState data; char *zErrMsg = 0; @@ -4269,6 +4281,10 @@ static int do_meta_command(char *zLine, ShellState *p){ } }else + if( c=='l' && n>2 && strncmp(azArg[0], "lint", n)==0 ){ + lintDotCommand(p, azArg, nArg); + }else + #ifndef SQLITE_OMIT_LOAD_EXTENSION if( c=='l' && strncmp(azArg[0], "load", n)==0 ){ const char *zFile, *zProc; diff --git a/test/shell6.test b/test/shell6.test index df7e1de58d..6d3fdd24a3 100644 --- a/test/shell6.test +++ b/test/shell6.test @@ -84,12 +84,12 @@ foreach {tn schema output} { } do_test 1.$tn.1 { - set RES [catchcmd test.db .fkey_missing_indexes] + set RES [catchcmd test.db [list .lint fkey-indexes]] } [list 0 [string trim $expected]] do_test 1.$tn.2 { execsql [lindex $RES 1] - catchcmd test.db .fkey_missing_indexes + catchcmd test.db [list .lint fkey-indexes] } {0 {}} db close From 3fd9f33bd13fbc777b8590b5b91379c3995c3179 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 16 Dec 2016 18:41:11 +0000 Subject: [PATCH 1100/1484] Fix minor issues with the ".lint" command implemention in the shell and the shell help text related to ".lint". FossilOrigin-Name: 1268dc77712d85de0b62332c88b22f7489f4e87f --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/shell.c | 6 ++++-- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index ad23b1fdbe..e34d3de33b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\s".fkey_missing_indexes"\sto\s".lint\sfkey-indexes". -D 2016-12-16T17:28:56.295 +C Fix\sminor\sissues\swith\sthe\s".lint"\scommand\simplemention\sin\sthe\sshell\sand\nthe\sshell\shelp\stext\srelated\sto\s".lint". +D 2016-12-16T18:41:11.376 F Makefile.in c194b58fe00c370a48ac6ae6945e92a7781db1c8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -389,7 +389,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c bb070cf5f23611c44ab7e4788803684e385fc3fb F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c 204491a5e09a66380a067943d8651af8bda1d358 -F src/shell.c 0f1f7935f9a18b5458fd8279d7995c2e1743bdc2 +F src/shell.c 9be556ad9c7cf429d0acc48e386960d290c4df75 F src/sqlite.h.in e8e2d108d82647f0a812fdb74accf91c1ec08ddc F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae @@ -1537,7 +1537,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 3ab05987b0cc12af64bf32d885d04aff45d7a77c -R 17b5d854673e0a0adb6375b01c294779 -U dan -Z 080e8bf78fe63c73094cbd3615b790ed +P ee621ade38c11806e1df57c459da5f018a6d0670 +R c295b60403c83c54dd0a041668d05312 +U drh +Z 639f0a5a4b0a629c3f185644f89569f0 diff --git a/manifest.uuid b/manifest.uuid index b8d8dbe1a3..fdb102989d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ee621ade38c11806e1df57c459da5f018a6d0670 \ No newline at end of file +1268dc77712d85de0b62332c88b22f7489f4e87f \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 27267918fd..c4c1eed3de 100644 --- a/src/shell.c +++ b/src/shell.c @@ -2185,7 +2185,6 @@ static char zHelp[] = ".eqp on|off|full Enable or disable automatic EXPLAIN QUERY PLAN\n" ".exit Exit this program\n" ".explain ?on|off|auto? Turn EXPLAIN output mode on or off or to automatic\n" - ".fkey_missing_indexes Find indexes to make FK processing more efficient\n" ".fullschema ?--indent? Show schema and the content of sqlite_stat tables\n" ".headers on|off Turn display of headers on or off\n" ".help Show this message\n" @@ -2200,6 +2199,8 @@ static char zHelp[] = ".iotrace FILE Enable I/O diagnostic logging to FILE\n" #endif ".limit ?LIMIT? ?VAL? Display or change the value of an SQLITE_LIMIT\n" + ".lint OPTIONS Report potential schema issues. Options:\n" + " fkey-indexes Find missing foreign key indexes\n" #ifndef SQLITE_OMIT_LOAD_EXTENSION ".load FILE ?ENTRY? Load an extension library\n" #endif @@ -3489,7 +3490,7 @@ static int lintDotCommand( int nArg /* Number of entries in azArg[] */ ){ int n; - n = (nArg>=1 ? strlen(azArg[1]) : 0); + n = (nArg>=2 ? strlen(azArg[1]) : 0); if( n<1 || sqlite3_strnicmp(azArg[1], "fkey-indexes", n) ) goto usage; return lintFkeyIndexes(pState, azArg, nArg); @@ -4282,6 +4283,7 @@ static int do_meta_command(char *zLine, ShellState *p){ }else if( c=='l' && n>2 && strncmp(azArg[0], "lint", n)==0 ){ + open_db(p, 0); lintDotCommand(p, azArg, nArg); }else From 11da002c0209be4cd0e07cefdef0e869e174f2e0 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 17 Dec 2016 08:18:05 +0000 Subject: [PATCH 1101/1484] Fix a problem in the shell tools readfile() command causing blobs to be truncated at the first embedded 0x00 byte in release builds, or an assert() to fail in a debug build. FossilOrigin-Name: 8dedd6ad44bd1d103dced9d1350188cb2327128d --- manifest | 18 ++++++++-------- manifest.uuid | 2 +- src/shell.c | 26 ++++++++++++++++------- test/shell6.test | 2 ++ test/shell7.test | 54 ++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 84 insertions(+), 18 deletions(-) create mode 100644 test/shell7.test diff --git a/manifest b/manifest index 8fda08169a..3f3cdc35e5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\s".lint\sfkey-indexes"\scommand\sto\sthe\scommand-line\sshell. -D 2016-12-16T18:43:49.329 +C Fix\sa\sproblem\sin\sthe\sshell\stools\sreadfile()\scommand\scausing\sblobs\sto\sbe\s\ntruncated\sat\sthe\sfirst\sembedded\s0x00\sbyte\sin\srelease\sbuilds,\sor\san\sassert()\sto\nfail\sin\sa\sdebug\sbuild. +D 2016-12-17T08:18:05.241 F Makefile.in c194b58fe00c370a48ac6ae6945e92a7781db1c8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -389,7 +389,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c bb070cf5f23611c44ab7e4788803684e385fc3fb F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c e4c687333c5fa33b1ce05c37bfbea6e09d3dbee9 -F src/shell.c 9be556ad9c7cf429d0acc48e386960d290c4df75 +F src/shell.c 95fc9f4cbdfda44f3328ea23d69fb1905a974a90 F src/sqlite.h.in e8e2d108d82647f0a812fdb74accf91c1ec08ddc F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae @@ -1094,7 +1094,8 @@ F test/shell2.test e242a9912f44f4c23c3d1d802a83e934e84c853b F test/shell3.test 9b95ba643eaa228376f06a898fb410ee9b6e57c1 F test/shell4.test 89ad573879a745974ff2df20ff97c5d6ffffbd5d F test/shell5.test 50a732c1c2158b1cd62cf53975ce1ea7ce6b9dc9 -F test/shell6.test 806472f6ffdd31d632e27dbe8515c0c45f68f3ec +F test/shell6.test 87b47bf2f5c47a4e44f07dd119ea88ae303a8247 +F test/shell7.test 07751911b294698e0c5df67bcbd29e7d2f0f2907 F test/shortread1.test bb591ef20f0fd9ed26d0d12e80eee6d7ac8897a3 F test/show_speedtest1_rtree.tcl 32e6c5f073d7426148a6936a0408f4b5b169aba5 F test/shrink.test 1b4330b1fd9e818c04726d45cb28db73087535ce @@ -1537,8 +1538,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d66ec5cfb67c6c8134fb642e0c2f72113fe1b7fd 1268dc77712d85de0b62332c88b22f7489f4e87f -R 687c3d19b933c4e396bfa9c657e5c87e -T +closed 1268dc77712d85de0b62332c88b22f7489f4e87f -U drh -Z fa4bf48b88eaf725bf36396e1a6dc597 +P 94689e3bdac2eabbcf1a51d741c2604ed4bd8a40 +R b4ced5d015604f5a5058a9f967dfbb21 +U dan +Z aab7365a5b426408e7c16bc3f1fbf9d3 diff --git a/manifest.uuid b/manifest.uuid index 78caff5224..04a638bfe5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -94689e3bdac2eabbcf1a51d741c2604ed4bd8a40 \ No newline at end of file +8dedd6ad44bd1d103dced9d1350188cb2327128d \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index c4c1eed3de..d7e6084c4b 100644 --- a/src/shell.c +++ b/src/shell.c @@ -2280,14 +2280,22 @@ void session_help(ShellState *p){ /* Forward reference */ static int process_input(ShellState *p, FILE *in); - /* -** Read the content of a file into memory obtained from sqlite3_malloc64(). -** The caller is responsible for freeing the memory. +** Read the content of file zName into memory obtained from sqlite3_malloc64() +** and return a pointer to the buffer. The caller is responsible for freeing +** the memory. ** -** NULL is returned if any error is encountered. +** If parameter pnByte is not NULL, (*pnByte) is set to the number of bytes +** read. +** +** For convenience, a nul-terminator byte is always appended to the data read +** from the file before the buffer is returned. This byte is not included in +** the final value of (*pnByte), if applicable. +** +** NULL is returned if any error is encountered. The final value of *pnByte +** is undefined in this case. */ -static char *readFile(const char *zName){ +static char *readFile(const char *zName, int *pnByte){ FILE *in = fopen(zName, "rb"); long nIn; size_t nRead; @@ -2305,6 +2313,7 @@ static char *readFile(const char *zName){ return 0; } pBuf[nIn] = 0; + if( pnByte ) *pnByte = nIn; return pBuf; } @@ -2320,12 +2329,13 @@ static void readfileFunc( ){ const char *zName; void *pBuf; + int nBuf; UNUSED_PARAMETER(argc); zName = (const char*)sqlite3_value_text(argv[0]); if( zName==0 ) return; - pBuf = readFile(zName); - if( pBuf ) sqlite3_result_blob(context, pBuf, -1, sqlite3_free); + pBuf = readFile(zName, &nBuf); + if( pBuf ) sqlite3_result_blob(context, pBuf, nBuf, sqlite3_free); } /* @@ -3665,7 +3675,7 @@ static int do_meta_command(char *zLine, ShellState *p){ if( nArg!=2 ){ raw_printf(stderr, "Usage: .check GLOB-PATTERN\n"); rc = 2; - }else if( (zRes = readFile("testcase-out.txt"))==0 ){ + }else if( (zRes = readFile("testcase-out.txt", 0))==0 ){ raw_printf(stderr, "Error: cannot read 'testcase-out.txt'\n"); rc = 2; }else if( testcase_glob(azArg[1],zRes)==0 ){ diff --git a/test/shell6.test b/test/shell6.test index 6d3fdd24a3..028ac5efe9 100644 --- a/test/shell6.test +++ b/test/shell6.test @@ -9,6 +9,8 @@ # #*********************************************************************** # +# Test the shell tool ".lint fkey-indexes" command. +# set testdir [file dirname $argv0] source $testdir/tester.tcl diff --git a/test/shell7.test b/test/shell7.test new file mode 100644 index 0000000000..a062885140 --- /dev/null +++ b/test/shell7.test @@ -0,0 +1,54 @@ +# 2016 December 17 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# Test the readfile() function built into the shell tool. Specifically, +# that it does not truncate the blob read at the first embedded 0x00 +# byte. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix shell7 +set CLI [test_find_cli] + + +do_execsql_test 1.0 { + CREATE TABLE f1(tn INTEGER PRIMARY KEY, x BLOB); + CREATE TABLE f2(tn INTEGER PRIMARY KEY, x BLOB); + + INSERT INTO f1 VALUES(1, X'01020304'); + INSERT INTO f1 VALUES(2, X'01000304'); + INSERT INTO f1 VALUES(3, randomblob(200)); +} + +foreach {tn l x} [db eval { SELECT tn, length(x) AS l, x FROM f1 }] { + forcedelete shell7_test.bin + set fd [open shell7_test.bin w] + fconfigure $fd -encoding binary + fconfigure $fd -translation binary + puts -nonewline $fd $x + close $fd + + do_test 1.$tn.1 { file size shell7_test.bin } $l + do_test 1.$tn.2 { + catchcmd test.db "INSERT INTO f2 VALUES($tn, readfile('shell7_test.bin'));" + } {0 {}} + + do_execsql_test 1.$tn.3 { + SELECT (SELECT x FROM f1 WHERE tn=1)==(SELECT x FROM f2 WHERE tn=1) + } {1} +} + + + +finish_test + + From 6918e2f9b22d475fa31d1f29cad418a438f05f42 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 17 Dec 2016 20:27:22 +0000 Subject: [PATCH 1102/1484] Enhance fuzzershell.c to read and execute SQL commands in the autoexec table of the database under test. Add the dbfuzz.c test program combining selected features of fuzzershell.c and fuzzcheck.c. FossilOrigin-Name: ef6e071a62cd79a0edbbef9f41ca9482540e5cb8 --- Makefile.in | 4 + main.mk | 6 + manifest | 19 +- manifest.uuid | 2 +- test/dbfuzz.c | 710 +++++++++++++++++++++++++++++++++++++++++++++ tool/fuzzershell.c | 72 +++++ 6 files changed, 803 insertions(+), 10 deletions(-) create mode 100644 test/dbfuzz.c diff --git a/Makefile.in b/Makefile.in index 76233c4a7b..b961070c23 100644 --- a/Makefile.in +++ b/Makefile.in @@ -567,6 +567,7 @@ SHELL_OPT += -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1 FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_OSS_FUZZ FUZZCHECK_SRC = $(TOP)/test/fuzzcheck.c $(TOP)/test/ossfuzz.c +DBFUZZ_OPT = # This is the default Makefile target. The objects listed here # are what get build when you type just "make" with no arguments. @@ -621,6 +622,9 @@ fuzzcheck$(TEXE): $(FUZZCHECK_SRC) sqlite3.c sqlite3.h ossshell$(TEXE): $(TOP)/test/ossfuzz.c $(TOP)/test/ossshell.c sqlite3.c sqlite3.h $(LTLINK) -o $@ $(FUZZCHECK_OPT) $(TOP)/test/ossshell.c sqlite3.c sqlite3.h $(TLIBS) +dbfuzz$(TEXE): $(TOP)/test/dbfuzz.c sqlite3.c sqlite3.h + $(LTLINK) -o $@ $(DBFUZZ_OPT) $(TOP)/test/dbfuzz.c sqlite3.c $(TLIBS) + mptester$(TEXE): sqlite3.lo $(TOP)/mptest/mptest.c $(LTLINK) -o $@ -I. $(TOP)/mptest/mptest.c sqlite3.lo \ $(TLIBS) -rpath "$(libdir)" diff --git a/main.mk b/main.mk index 91487b72b3..e07b964d67 100644 --- a/main.mk +++ b/main.mk @@ -477,6 +477,7 @@ SHELL_OPT += -DSQLITE_ENABLE_EXPLAIN_COMMENTS SHELL_OPT += -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1 FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 +DBFUZZ_OPT = # This is the default Makefile target. The objects listed here # are what get build when you type just "make" with no arguments. @@ -513,6 +514,11 @@ fuzzershell$(EXE): $(TOP)/tool/fuzzershell.c sqlite3.c sqlite3.h $(FUZZERSHELL_OPT) $(TOP)/tool/fuzzershell.c sqlite3.c \ $(TLIBS) $(THREADLIB) +dbfuzz$(EXE): $(TOP)/test/dbfuzz.c sqlite3.c sqlite3.h + $(TCCX) -o dbfuzz$(EXE) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \ + $(DBFUZZ_OPT) $(TOP)/test/dbfuzz.c sqlite3.c \ + $(TLIBS) $(THREADLIB) + fuzzcheck$(EXE): $(TOP)/test/fuzzcheck.c sqlite3.c sqlite3.h $(TOP)/test/ossfuzz.c $(TCCX) -o fuzzcheck$(EXE) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \ -DSQLITE_ENABLE_MEMSYS5 $(FUZZCHECK_OPT) -DSQLITE_OSS_FUZZ \ diff --git a/manifest b/manifest index 3f3cdc35e5..1dc3a4ab57 100644 --- a/manifest +++ b/manifest @@ -1,6 +1,6 @@ -C Fix\sa\sproblem\sin\sthe\sshell\stools\sreadfile()\scommand\scausing\sblobs\sto\sbe\s\ntruncated\sat\sthe\sfirst\sembedded\s0x00\sbyte\sin\srelease\sbuilds,\sor\san\sassert()\sto\nfail\sin\sa\sdebug\sbuild. -D 2016-12-17T08:18:05.241 -F Makefile.in c194b58fe00c370a48ac6ae6945e92a7781db1c8 +C Enhance\sfuzzershell.c\sto\sread\sand\sexecute\sSQL\scommands\sin\sthe\sautoexec\stable\nof\sthe\sdatabase\sunder\stest.\s\sAdd\sthe\sdbfuzz.c\stest\sprogram\scombining\sselected\nfeatures\sof\sfuzzershell.c\sand\sfuzzcheck.c. +D 2016-12-17T20:27:22.394 +F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7 @@ -312,7 +312,7 @@ F ext/userauth/userauth.c 5fa3bdb492f481bbc1709fc83c91ebd13460c69e F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60 -F main.mk bd1149fdb5543e432a8530a0ea7642613a655bc1 +F main.mk 2cf5f0362c5687fd8e912c3a327b49a2e8ba0f9b F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 @@ -628,6 +628,7 @@ F test/ctime.test ff6c38e822459d6ca743c34901caf57740b08b54 F test/cursorhint.test 7bc346788390475e77a345da2b92270d04d35856 F test/cursorhint2.test fa41f0d997e67db921d08c31e73111b32811201a F test/date.test a6a5a48b90907bca9fbcc79a30be5a715c1ab2fc +F test/dbfuzz.c 2bf7858028c0c437ccffc5795f791c495800cd9b F test/dbstatus.test 73149851b3aff14fc6db478e58f9083a66422cf5 F test/dbstatus2.test e93ab03bfae6d62d4d935f20de928c19ca0ed0ab F test/default.test 0cb49b1c315a0d81c81d775e407f66906a2a604d @@ -1461,7 +1462,7 @@ F tool/dbhash.c a06228aa21ebc4e6ea8daa486601d938499238a5 F tool/extract.c 054069d81b095fbdc189a6f5d4466e40380505e2 F tool/fast_vacuum.c 5ba0d6f5963a0a63bdc42840f678bad75b2ebce1 F tool/fragck.tcl 5265a95126abcf6ab357f7efa544787e5963f439 -F tool/fuzzershell.c d5c870a07452caa5c70a8e49d6c64e403558686d +F tool/fuzzershell.c dbf6c26eef936ec78cb0707570de3a4308b2507e F tool/genfkey.README cf68fddd4643bbe3ff8e31b8b6d8b0a1b85e20f4 F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5 F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce @@ -1538,7 +1539,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 94689e3bdac2eabbcf1a51d741c2604ed4bd8a40 -R b4ced5d015604f5a5058a9f967dfbb21 -U dan -Z aab7365a5b426408e7c16bc3f1fbf9d3 +P 8dedd6ad44bd1d103dced9d1350188cb2327128d +R 467cdb2635ae3db86cb6ad0c3fe29c15 +U drh +Z 6af4ccd37cf6da1faf8a726dcd8a746b diff --git a/manifest.uuid b/manifest.uuid index 04a638bfe5..258fb2afd4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8dedd6ad44bd1d103dced9d1350188cb2327128d \ No newline at end of file +ef6e071a62cd79a0edbbef9f41ca9482540e5cb8 \ No newline at end of file diff --git a/test/dbfuzz.c b/test/dbfuzz.c new file mode 100644 index 0000000000..0484b15eb3 --- /dev/null +++ b/test/dbfuzz.c @@ -0,0 +1,710 @@ +/* +** 2016-12-17 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This program is designed for fuzz-testing SQLite database files. +** +** This program reads fuzzed database files from the disk files named +** on the command-line. Each database is loaded into an in-memory +** filesystem so that the original database file is unmolested. +** +** The fuzzed database is then opened, and series of SQL statements +** are run against the database to ensure that SQLite can safely handle +** the fuzzed database. +*/ +#include +#include +#include +#include +#include +#define ISSPACE(X) isspace((unsigned char)(X)) +#define ISDIGIT(X) isdigit((unsigned char)(X)) +#include "sqlite3.h" +#ifdef __unix__ +# include +# include +#endif + +/* +** Print sketchy documentation for this utility program +*/ +static void showHelp(const char *zArgv0){ + printf("Usage: %s [options] DATABASE ...\n", zArgv0); + printf( +"Read databases into an in-memory filesystem. Run test SQL as specified\n" +"by command-line arguments or from\n" +"\n" +" SELECT group_concat(sql) FROM autoexec;\n" +"\n" +"Options:\n" +" --help Show this help text\n" +" -q|--quiet Reduced output\n" +" --limit-mem N Limit memory used by test SQLite instances to N bytes\n" +" --limit-vdbe Panic if any test runs for more than 100,000 cycles\n" +" --no-lookaside Disable the lookaside memory allocator\n" +" --timeout N Timeout after N seconds.\n" +" --trace Show the results of each SQL command\n" +" -v|--verbose Increased output. Repeat for more output.\n" + ); + exit(0); +} + +/* +** Print an error message and quit. +*/ +static void fatalError(const char *zFormat, ...){ + va_list ap; + va_start(ap, zFormat); + vfprintf(stderr, zFormat, ap); + va_end(ap); + fprintf(stderr, "\n"); + exit(1); +} + +/* +** Files in the virtual file system. +*/ +typedef struct VFile VFile; +typedef struct VHandle VHandle; +struct VFile { + char *zFilename; /* Filename. NULL for delete-on-close. From malloc() */ + int sz; /* Size of the file in bytes */ + int nRef; /* Number of references to this file */ + unsigned char *a; /* Content of the file. From malloc() */ +}; +struct VHandle { + sqlite3_file base; /* Base class. Must be first */ + VFile *pVFile; /* The underlying file */ +}; + +/* +** Maximum number of files in the in-memory virtual filesystem. +*/ +#define MX_FILE 10 + +/* +** Maximum allowed file size +*/ +#define MX_FILE_SZ 1000000 + +/* +** All global variables are gathered into the "g" singleton. +*/ +static struct GlobalVars { + VFile aFile[MX_FILE]; /* The virtual filesystem */ +} g; + + +/* +** Initialize the virtual file system. +*/ +static void formatVfs(void){ + int i; + for(i=0; i0 ){ + fatalError("file %d still open. nRef=%d", i, g.aFile[i].nRef); + } + g.aFile[i].sz = -1; + free(g.aFile[i].a); + g.aFile[i].a = 0; + g.aFile[i].nRef = 0; + } +} + +/* +** Find a VFile by name +*/ +static VFile *findVFile(const char *zName){ + int i; + if( zName==0 ) return 0; + for(i=0; i=0; i++){} + if( i>=MX_FILE ) return 0; + if( zDiskFile ){ + in = fopen(zDiskFile, "rb"); + if( in==0 ) fatalError("no such file: \"%s\"", zDiskFile); + fseek(in, 0, SEEK_END); + sz = ftell(in); + rewind(in); + } + pNew = &g.aFile[i]; + if( zName ){ + int nName = (int)strlen(zName)+1; + pNew->zFilename = malloc(nName); + if( pNew->zFilename==0 ){ + if( in ) fclose(in); + return 0; + } + memcpy(pNew->zFilename, zName, nName); + }else{ + pNew->zFilename = 0; + } + pNew->nRef = 0; + pNew->sz = sz; + pNew->a = malloc(sz); + if( sz>0 ){ + if( pNew->a==0 || fread(pNew->a, sz, 1, in)<1 ){ + free(pNew->zFilename); + free(pNew->a); + pNew->a = 0; + pNew->zFilename = 0; + pNew->sz = -1; + pNew = 0; + } + } + if( in ) fclose(in); + return pNew; +} + +/* Methods for the VHandle object +*/ +static int inmemClose(sqlite3_file *pFile){ + VHandle *p = (VHandle*)pFile; + VFile *pVFile = p->pVFile; + pVFile->nRef--; + if( pVFile->nRef==0 && pVFile->zFilename==0 ){ + pVFile->sz = -1; + free(pVFile->a); + pVFile->a = 0; + } + return SQLITE_OK; +} +static int inmemRead( + sqlite3_file *pFile, /* Read from this open file */ + void *pData, /* Store content in this buffer */ + int iAmt, /* Bytes of content */ + sqlite3_int64 iOfst /* Start reading here */ +){ + VHandle *pHandle = (VHandle*)pFile; + VFile *pVFile = pHandle->pVFile; + if( iOfst<0 || iOfst>=pVFile->sz ){ + memset(pData, 0, iAmt); + return SQLITE_IOERR_SHORT_READ; + } + if( iOfst+iAmt>pVFile->sz ){ + memset(pData, 0, iAmt); + iAmt = (int)(pVFile->sz - iOfst); + memcpy(pData, pVFile->a, iAmt); + return SQLITE_IOERR_SHORT_READ; + } + memcpy(pData, pVFile->a + iOfst, iAmt); + return SQLITE_OK; +} +static int inmemWrite( + sqlite3_file *pFile, /* Write to this file */ + const void *pData, /* Content to write */ + int iAmt, /* bytes to write */ + sqlite3_int64 iOfst /* Start writing here */ +){ + VHandle *pHandle = (VHandle*)pFile; + VFile *pVFile = pHandle->pVFile; + if( iOfst+iAmt > pVFile->sz ){ + unsigned char *aNew; + if( iOfst+iAmt >= MX_FILE_SZ ){ + return SQLITE_FULL; + } + aNew = realloc(pVFile->a, (int)(iOfst+iAmt)); + if( aNew==0 ){ + return SQLITE_FULL; + } + pVFile->a = aNew; + if( iOfst > pVFile->sz ){ + memset(pVFile->a + pVFile->sz, 0, (int)(iOfst - pVFile->sz)); + } + pVFile->sz = (int)(iOfst + iAmt); + } + memcpy(pVFile->a + iOfst, pData, iAmt); + return SQLITE_OK; +} +static int inmemTruncate(sqlite3_file *pFile, sqlite3_int64 iSize){ + VHandle *pHandle = (VHandle*)pFile; + VFile *pVFile = pHandle->pVFile; + if( pVFile->sz>iSize && iSize>=0 ) pVFile->sz = (int)iSize; + return SQLITE_OK; +} +static int inmemSync(sqlite3_file *pFile, int flags){ + return SQLITE_OK; +} +static int inmemFileSize(sqlite3_file *pFile, sqlite3_int64 *pSize){ + *pSize = ((VHandle*)pFile)->pVFile->sz; + return SQLITE_OK; +} +static int inmemLock(sqlite3_file *pFile, int type){ + return SQLITE_OK; +} +static int inmemUnlock(sqlite3_file *pFile, int type){ + return SQLITE_OK; +} +static int inmemCheckReservedLock(sqlite3_file *pFile, int *pOut){ + *pOut = 0; + return SQLITE_OK; +} +static int inmemFileControl(sqlite3_file *pFile, int op, void *pArg){ + return SQLITE_NOTFOUND; +} +static int inmemSectorSize(sqlite3_file *pFile){ + return 512; +} +static int inmemDeviceCharacteristics(sqlite3_file *pFile){ + return + SQLITE_IOCAP_SAFE_APPEND | + SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN | + SQLITE_IOCAP_POWERSAFE_OVERWRITE; +} + + +/* Method table for VHandle +*/ +static sqlite3_io_methods VHandleMethods = { + /* iVersion */ 1, + /* xClose */ inmemClose, + /* xRead */ inmemRead, + /* xWrite */ inmemWrite, + /* xTruncate */ inmemTruncate, + /* xSync */ inmemSync, + /* xFileSize */ inmemFileSize, + /* xLock */ inmemLock, + /* xUnlock */ inmemUnlock, + /* xCheck... */ inmemCheckReservedLock, + /* xFileCtrl */ inmemFileControl, + /* xSectorSz */ inmemSectorSize, + /* xDevchar */ inmemDeviceCharacteristics, + /* xShmMap */ 0, + /* xShmLock */ 0, + /* xShmBarrier */ 0, + /* xShmUnmap */ 0, + /* xFetch */ 0, + /* xUnfetch */ 0 +}; + +/* +** Open a new file in the inmem VFS. All files are anonymous and are +** delete-on-close. +*/ +static int inmemOpen( + sqlite3_vfs *pVfs, + const char *zFilename, + sqlite3_file *pFile, + int openFlags, + int *pOutFlags +){ + VFile *pVFile = createVFile(zFilename, 0); + VHandle *pHandle = (VHandle*)pFile; + if( pVFile==0 ){ + return SQLITE_FULL; + } + pHandle->pVFile = pVFile; + pVFile->nRef++; + pFile->pMethods = &VHandleMethods; + if( pOutFlags ) *pOutFlags = openFlags; + return SQLITE_OK; +} + +/* +** Delete a file by name +*/ +static int inmemDelete( + sqlite3_vfs *pVfs, + const char *zFilename, + int syncdir +){ + VFile *pVFile = findVFile(zFilename); + if( pVFile==0 ) return SQLITE_OK; + if( pVFile->nRef==0 ){ + free(pVFile->zFilename); + pVFile->zFilename = 0; + pVFile->sz = -1; + free(pVFile->a); + pVFile->a = 0; + return SQLITE_OK; + } + return SQLITE_IOERR_DELETE; +} + +/* Check for the existance of a file +*/ +static int inmemAccess( + sqlite3_vfs *pVfs, + const char *zFilename, + int flags, + int *pResOut +){ + VFile *pVFile = findVFile(zFilename); + *pResOut = pVFile!=0; + return SQLITE_OK; +} + +/* Get the canonical pathname for a file +*/ +static int inmemFullPathname( + sqlite3_vfs *pVfs, + const char *zFilename, + int nOut, + char *zOut +){ + sqlite3_snprintf(nOut, zOut, "%s", zFilename); + return SQLITE_OK; +} + +/* +** Register the VFS that reads from the g.aFile[] set of files. +*/ +static void inmemVfsRegister(void){ + static sqlite3_vfs inmemVfs; + sqlite3_vfs *pDefault = sqlite3_vfs_find(0); + inmemVfs.iVersion = 3; + inmemVfs.szOsFile = sizeof(VHandle); + inmemVfs.mxPathname = 200; + inmemVfs.zName = "inmem"; + inmemVfs.xOpen = inmemOpen; + inmemVfs.xDelete = inmemDelete; + inmemVfs.xAccess = inmemAccess; + inmemVfs.xFullPathname = inmemFullPathname; + inmemVfs.xRandomness = pDefault->xRandomness; + inmemVfs.xSleep = pDefault->xSleep; + inmemVfs.xCurrentTimeInt64 = pDefault->xCurrentTimeInt64; + sqlite3_vfs_register(&inmemVfs, 0); +}; + +/* +** Timeout handler +*/ +#ifdef __unix__ +static void timeoutHandler(int NotUsed){ + (void)NotUsed; + fatalError("timeout\n"); +} +#endif + +/* +** Set the an alarm to go off after N seconds. Disable the alarm +** if N==0 +*/ +static void setAlarm(int N){ +#ifdef __unix__ + alarm(N); +#else + (void)N; +#endif +} +/*************************************************************************** +** String accumulator object +*/ +typedef struct Str Str; +struct Str { + char *z; /* The string. Memory from malloc() */ + sqlite3_uint64 n; /* Bytes of input used */ + sqlite3_uint64 nAlloc; /* Bytes allocated to z[] */ + int oomErr; /* OOM error has been seen */ +}; + +/* Initialize a Str object */ +static void StrInit(Str *p){ + memset(p, 0, sizeof(*p)); +} + +/* Append text to the end of a Str object */ +static void StrAppend(Str *p, const char *z){ + sqlite3_uint64 n = strlen(z); + if( p->n + n >= p->nAlloc ){ + char *zNew; + sqlite3_uint64 nNew; + if( p->oomErr ) return; + nNew = p->nAlloc*2 + 100 + n; + zNew = sqlite3_realloc(p->z, nNew); + if( zNew==0 ){ + sqlite3_free(p->z); + memset(p, 0, sizeof(*p)); + p->oomErr = 1; + return; + } + p->z = zNew; + p->nAlloc = nNew; + } + memcpy(p->z + p->n, z, n); + p->n += n; + p->z[p->n] = 0; +} + +/* Return the current string content */ +static char *StrStr(Str *p){ + return p->z; +} + +/* Free the string */ +static void StrFree(Str *p){ + sqlite3_free(p->z); + StrInit(p); +} + +/* +** Return the value of a hexadecimal digit. Return -1 if the input +** is not a hex digit. +*/ +static int hexDigitValue(char c){ + if( c>='0' && c<='9' ) return c - '0'; + if( c>='a' && c<='f' ) return c - 'a' + 10; + if( c>='A' && c<='F' ) return c - 'A' + 10; + return -1; +} + +/* +** Interpret zArg as an integer value, possibly with suffixes. +*/ +static int integerValue(const char *zArg){ + sqlite3_int64 v = 0; + static const struct { char *zSuffix; int iMult; } aMult[] = { + { "KiB", 1024 }, + { "MiB", 1024*1024 }, + { "GiB", 1024*1024*1024 }, + { "KB", 1000 }, + { "MB", 1000000 }, + { "GB", 1000000000 }, + { "K", 1000 }, + { "M", 1000000 }, + { "G", 1000000000 }, + }; + int i; + int isNeg = 0; + if( zArg[0]=='-' ){ + isNeg = 1; + zArg++; + }else if( zArg[0]=='+' ){ + zArg++; + } + if( zArg[0]=='0' && zArg[1]=='x' ){ + int x; + zArg += 2; + while( (x = hexDigitValue(zArg[0]))>=0 ){ + v = (v<<4) + x; + zArg++; + } + }else{ + while( ISDIGIT(zArg[0]) ){ + v = v*10 + zArg[0] - '0'; + zArg++; + } + } + for(i=0; i0x7fffffff ) fatalError("parameter too large - max 2147483648"); + return (int)(isNeg? -v : v); +} + +/* +** This callback is invoked by sqlite3_exec() to return query results. +*/ +static int execCallback(void *NotUsed, int argc, char **argv, char **colv){ + int i; + static unsigned cnt = 0; + printf("ROW #%u:\n", ++cnt); + if( argv ){ + for(i=0; i0 ){ + void *pHeap = malloc( nHeap ); + if( pHeap==0 ) fatalError("cannot allocate %d-byte heap\n", nHeap); + rc = sqlite3_config(SQLITE_CONFIG_HEAP, pHeap, nHeap, 32); + if( rc ) fatalError("heap configuration failed: %d\n", rc); + } + if( noLookaside ){ + sqlite3_config(SQLITE_CONFIG_LOOKASIDE, 0, 0); + } + inmemVfsRegister(); + formatVfs(); + StrInit(&sql); +#ifdef __unix__ + signal(SIGALRM, timeoutHandler); +#endif + for(i=0; i1 ){ + printf("DATABASE-FILE: %s\n", azDb[i]); + fflush(stdout); + } + if( iTimeout ) setAlarm(iTimeout); + createVFile("test.db", azDb[i]); + rc = sqlite3_open_v2("test.db", &db, SQLITE_OPEN_READWRITE, "inmem"); + if( rc ){ + printf("cannot open test.db for \"%s\"\n", azDb[i]); + reformatVfs(); + continue; + } +#ifndef SQLITE_OMIT_PROGRESS_CALLBACK + if( vdbeLimitFlag ){ + sqlite3_progress_handler(db, 100000, progressHandler, &vdbeLimitFlag); + } +#endif + rc = sqlite3_prepare_v2(db, "SELECT sql FROM autoexec", -1, &pStmt, 0); + if( rc==SQLITE_OK ){ + while( SQLITE_ROW==sqlite3_step(pStmt) ){ + StrAppend(&sql, (const char*)sqlite3_column_text(pStmt, 0)); + StrAppend(&sql, "\n"); + } + } + sqlite3_finalize(pStmt); + StrAppend(&sql, "PRAGMA integrity_check;\n"); + if( traceFlag ){ + char *zErrMsg = 0; + rc = sqlite3_exec(db, StrStr(&sql), execCallback, 0, &zErrMsg); + if( zErrMsg ){ + printf("ERRMSG: %s\n", zErrMsg); + sqlite3_free(zErrMsg); + } + }else { + rc = sqlite3_exec(db, StrStr(&sql), execNoop, 0, 0); + } + sqlite3_close(db); + reformatVfs(); + StrFree(&sql); + if( sqlite3_memory_used()>0 ){ + free(azDb); + reformatVfs(); + fatalError("memory leak of %lld bytes", sqlite3_memory_used()); + } + } + StrFree(&sql); + reformatVfs(); + return 0; +} diff --git a/tool/fuzzershell.c b/tool/fuzzershell.c index 710e07024e..c75beb4d88 100644 --- a/tool/fuzzershell.c +++ b/tool/fuzzershell.c @@ -226,6 +226,56 @@ static void traceNoop(void *NotUsed, const char *zMsg){ } #endif +/*************************************************************************** +** String accumulator object +*/ +typedef struct Str Str; +struct Str { + char *z; /* The string. Memory from malloc() */ + sqlite3_uint64 n; /* Bytes of input used */ + sqlite3_uint64 nAlloc; /* Bytes allocated to z[] */ + int oomErr; /* OOM error has been seen */ +}; + +/* Initialize a Str object */ +static void StrInit(Str *p){ + memset(p, 0, sizeof(*p)); +} + +/* Append text to the end of a Str object */ +static void StrAppend(Str *p, const char *z){ + sqlite3_uint64 n = strlen(z); + if( p->n + n >= p->nAlloc ){ + char *zNew; + sqlite3_uint64 nNew; + if( p->oomErr ) return; + nNew = p->nAlloc*2 + 100 + n; + zNew = sqlite3_realloc(p->z, nNew); + if( zNew==0 ){ + sqlite3_free(p->z); + memset(p, 0, sizeof(*p)); + p->oomErr = 1; + return; + } + p->z = zNew; + p->nAlloc = nNew; + } + memcpy(p->z + p->n, z, n); + p->n += n; + p->z[p->n] = 0; +} + +/* Return the current string content */ +static char *StrStr(Str *p){ + return p->z; +} + +/* Free the string */ +static void StrFree(Str *p){ + sqlite3_free(p->z); + StrInit(p); +} + /*************************************************************************** ** eval() implementation copied from ../ext/misc/eval.c */ @@ -1028,6 +1078,8 @@ int main(int argc, char **argv){ oomCnt = 0; } do{ + Str sql; + StrInit(&sql); if( zDbName ){ rc = sqlite3_open_v2(zDbName, &db, SQLITE_OPEN_READWRITE, 0); if( rc!=SQLITE_OK ){ @@ -1057,6 +1109,25 @@ int main(int argc, char **argv){ if( pageSize ) sqlexec(db, "PRAGMA pagesize=%d", pageSize); if( doAutovac ) sqlexec(db, "PRAGMA auto_vacuum=FULL"); iStart = timeOfDay(); + + /* If using an input database file and that database contains a table + ** named "autoexec" with a column "sql", then replace the input SQL + ** with the concatenated text of the autoexec table. In this way, + ** if the database file is the input being fuzzed, the SQL text is + ** fuzzed at the same time. */ + if( sqlite3_table_column_metadata(db,0,"autoexec","sql",0,0,0,0,0)==0 ){ + sqlite3_stmt *pStmt; + rc = sqlite3_prepare_v2(db, "SELECT sql FROM autoexec", -1, &pStmt, 0); + if( rc==SQLITE_OK ){ + while( sqlite3_step(pStmt)==SQLITE_ROW ){ + StrAppend(&sql, (const char*)sqlite3_column_text(pStmt, 0)); + StrAppend(&sql, "\n"); + } + } + sqlite3_finalize(pStmt); + zSql = StrStr(&sql); + } + g.bOomEnable = 1; if( verboseFlag ){ zErrMsg = 0; @@ -1070,6 +1141,7 @@ int main(int argc, char **argv){ } g.bOomEnable = 0; iEnd = timeOfDay(); + StrFree(&sql); rc = sqlite3_close(db); if( rc ){ abendError("sqlite3_close() failed with rc=%d", rc); From 22d709dd911129e2e657d0f6e6bd132ea5f3b0a4 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 17 Dec 2016 21:07:30 +0000 Subject: [PATCH 1103/1484] Refinements to the new dbfuzz test program. FossilOrigin-Name: 50325abe79b6a79b09ec6a1cee7d80ca02337428 --- manifest | 12 ++--- manifest.uuid | 2 +- test/dbfuzz.c | 122 ++++++++++++++++++++++++++++++++++---------------- 3 files changed, 90 insertions(+), 46 deletions(-) diff --git a/manifest b/manifest index 1dc3a4ab57..471db5a55d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\sfuzzershell.c\sto\sread\sand\sexecute\sSQL\scommands\sin\sthe\sautoexec\stable\nof\sthe\sdatabase\sunder\stest.\s\sAdd\sthe\sdbfuzz.c\stest\sprogram\scombining\sselected\nfeatures\sof\sfuzzershell.c\sand\sfuzzcheck.c. -D 2016-12-17T20:27:22.394 +C Refinements\sto\sthe\snew\sdbfuzz\stest\sprogram. +D 2016-12-17T21:07:30.972 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -628,7 +628,7 @@ F test/ctime.test ff6c38e822459d6ca743c34901caf57740b08b54 F test/cursorhint.test 7bc346788390475e77a345da2b92270d04d35856 F test/cursorhint2.test fa41f0d997e67db921d08c31e73111b32811201a F test/date.test a6a5a48b90907bca9fbcc79a30be5a715c1ab2fc -F test/dbfuzz.c 2bf7858028c0c437ccffc5795f791c495800cd9b +F test/dbfuzz.c 8cc2bdb818b4483a052f9f80f96be74cbd9a6e1d F test/dbstatus.test 73149851b3aff14fc6db478e58f9083a66422cf5 F test/dbstatus2.test e93ab03bfae6d62d4d935f20de928c19ca0ed0ab F test/default.test 0cb49b1c315a0d81c81d775e407f66906a2a604d @@ -1539,7 +1539,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 8dedd6ad44bd1d103dced9d1350188cb2327128d -R 467cdb2635ae3db86cb6ad0c3fe29c15 +P ef6e071a62cd79a0edbbef9f41ca9482540e5cb8 +R dc4a1399a03b50b6a494c9549eb51d65 U drh -Z 6af4ccd37cf6da1faf8a726dcd8a746b +Z 264edff2f6705a86fbfac5952dd5c460 diff --git a/manifest.uuid b/manifest.uuid index 258fb2afd4..7df7255bc5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ef6e071a62cd79a0edbbef9f41ca9482540e5cb8 \ No newline at end of file +50325abe79b6a79b09ec6a1cee7d80ca02337428 \ No newline at end of file diff --git a/test/dbfuzz.c b/test/dbfuzz.c index 0484b15eb3..2de97c35cb 100644 --- a/test/dbfuzz.c +++ b/test/dbfuzz.c @@ -20,6 +20,7 @@ ** are run against the database to ensure that SQLite can safely handle ** the fuzzed database. */ +#include #include #include #include @@ -541,30 +542,6 @@ static int integerValue(const char *zArg){ return (int)(isNeg? -v : v); } -/* -** This callback is invoked by sqlite3_exec() to return query results. -*/ -static int execCallback(void *NotUsed, int argc, char **argv, char **colv){ - int i; - static unsigned cnt = 0; - printf("ROW #%u:\n", ++cnt); - if( argv ){ - for(i=0; i0 && ISSPACE(z[n-1]) ) n--; + if( n==0 ) break; + if( pStmt==0 ){ + printf("TRACE: %.*s (error: %s)\n", n, z, sqlite3_errmsg(db)); + }else{ + printf("TRACE: %.*s\n", n, z); + } + } + zSql = zMore; + if( pStmt ){ + if( (runFlags & SQL_OUTPUT)==0 ){ + while( SQLITE_ROW==sqlite3_step(pStmt) ){} + }else{ + int nCol = -1; + int nRow; + for(nRow=0; SQLITE_ROW==sqlite3_step(pStmt); nRow++){ + int i; + if( nCol<0 ){ + nCol = sqlite3_column_count(pStmt); + } + for(i=0; i1 ){ printf("DATABASE-FILE: %s\n", azDb[i]); fflush(stdout); @@ -685,16 +738,7 @@ int main(int argc, char **argv){ } sqlite3_finalize(pStmt); StrAppend(&sql, "PRAGMA integrity_check;\n"); - if( traceFlag ){ - char *zErrMsg = 0; - rc = sqlite3_exec(db, StrStr(&sql), execCallback, 0, &zErrMsg); - if( zErrMsg ){ - printf("ERRMSG: %s\n", zErrMsg); - sqlite3_free(zErrMsg); - } - }else { - rc = sqlite3_exec(db, StrStr(&sql), execNoop, 0, 0); - } + runSql(db, StrStr(&sql), runFlags); sqlite3_close(db); reformatVfs(); StrFree(&sql); From f99dd359d00fd5af78d8ccb4b7c27fc82f578ddb Mon Sep 17 00:00:00 2001 From: drh Date: Sun, 18 Dec 2016 17:42:00 +0000 Subject: [PATCH 1104/1484] Change the OP_IfNotZero opcode so that it decrements register P1 by 1 rather than the value in P3, and so that it only decrements if originally positive. This avoids decrementing the smallest 64-bit signed integer. FossilOrigin-Name: 165c044686212fbf7182dd560ad1e57eb4cc9838 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/select.c | 2 +- src/vdbe.c | 12 ++++++------ 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index 471db5a55d..c032134449 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Refinements\sto\sthe\snew\sdbfuzz\stest\sprogram. -D 2016-12-17T21:07:30.972 +C Change\sthe\sOP_IfNotZero\sopcode\sso\sthat\sit\sdecrements\sregister\sP1\sby\s1\srather\nthan\sthe\svalue\sin\sP3,\sand\sso\sthat\sit\sonly\sdecrements\sif\soriginally\spositive.\nThis\savoids\sdecrementing\sthe\ssmallest\s64-bit\ssigned\sinteger. +D 2016-12-18T17:42:00.870 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -388,7 +388,7 @@ F src/printf.c f94da4935d1dd25420ac50c6745db1deb35e07c1 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c bb070cf5f23611c44ab7e4788803684e385fc3fb F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac -F src/select.c e4c687333c5fa33b1ce05c37bfbea6e09d3dbee9 +F src/select.c dfb6cadc3dcfba1b1bdbfba62ebba2b4b673413e F src/shell.c 95fc9f4cbdfda44f3328ea23d69fb1905a974a90 F src/sqlite.h.in e8e2d108d82647f0a812fdb74accf91c1ec08ddc F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -455,7 +455,7 @@ F src/update.c 1da7c462110bffed442a42884cb0d528c1db46d8 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c e68e8ced7328f22d2cf7b4c898c394a0de34cdf1 F src/vacuum.c 33c174b28886b2faf26e503b5a49a1c01a9b1c16 -F src/vdbe.c 64c3426893e1660bde7446c242468926555e3650 +F src/vdbe.c 4537452b85817772f159751d6b05799f3f4b09f5 F src/vdbe.h 0c74f6305fb43b9b282dacaff102272370e327d4 F src/vdbeInt.h 42e498dbe96475dbb3fda3d85d8fd2a87eff60a2 F src/vdbeapi.c ea4e2dc2213cc6bd7bee375a29a9b51c31b93ae0 @@ -1539,7 +1539,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ef6e071a62cd79a0edbbef9f41ca9482540e5cb8 -R dc4a1399a03b50b6a494c9549eb51d65 +P 50325abe79b6a79b09ec6a1cee7d80ca02337428 +R e3435f7f9ecf849784b4c50691f0f18b U drh -Z 264edff2f6705a86fbfac5952dd5c460 +Z 8b4cd82f585875ac24b32af2b88bc83b diff --git a/manifest.uuid b/manifest.uuid index 7df7255bc5..3da2ae76e4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -50325abe79b6a79b09ec6a1cee7d80ca02337428 \ No newline at end of file +165c044686212fbf7182dd560ad1e57eb4cc9838 \ No newline at end of file diff --git a/src/select.c b/src/select.c index 18344b7d43..e5f4c7fcdf 100644 --- a/src/select.c +++ b/src/select.c @@ -596,7 +596,7 @@ static void pushOntoSorter( ** register is initialized with value of LIMIT+OFFSET.) After the sorter ** fills up, delete the least entry in the sorter after each insert. ** Thus we never hold more than the LIMIT+OFFSET rows in memory at once */ - addr = sqlite3VdbeAddOp3(v, OP_IfNotZero, iLimit, 0, 1); VdbeCoverage(v); + addr = sqlite3VdbeAddOp1(v, OP_IfNotZero, iLimit); VdbeCoverage(v); sqlite3VdbeAddOp1(v, OP_Last, pSort->iECursor); if( pSort->bOrderedInnerLoop ){ r1 = ++pParse->nMem; diff --git a/src/vdbe.c b/src/vdbe.c index 6ccd746ef2..0935e87630 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -6012,20 +6012,20 @@ case OP_OffsetLimit: { /* in1, out2, in3 */ break; } -/* Opcode: IfNotZero P1 P2 P3 * * -** Synopsis: if r[P1]!=0 then r[P1]-=P3, goto P2 +/* Opcode: IfNotZero P1 P2 * * * +** Synopsis: if r[P1]!=0 then r[P1]--, goto P2 ** ** Register P1 must contain an integer. If the content of register P1 is -** initially nonzero, then subtract P3 from the value in register P1 and -** jump to P2. If register P1 is initially zero, leave it unchanged -** and fall through. +** initially greater than zero, then decrement the value in register P1. +** If it is non-zero (negative or positive) and then also jump to P2. +** If register P1 is initially zero, leave it unchanged and fall through. */ case OP_IfNotZero: { /* jump, in1 */ pIn1 = &aMem[pOp->p1]; assert( pIn1->flags&MEM_Int ); VdbeBranchTaken(pIn1->u.i<0, 2); if( pIn1->u.i ){ - pIn1->u.i -= pOp->p3; + if( pIn1->u.i>0 ) pIn1->u.i--; goto jump_to_p2; } break; From a582b016983c5fc14971a8550f59c7e65fa5ae0d Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 21 Dec 2016 19:45:54 +0000 Subject: [PATCH 1105/1484] Simplifications to the way UnpackedRecord objects are allocated. Smaller and faster code that also fixes a subtle (currently unreachable) bug. FossilOrigin-Name: f7ab01f254cd9d7006b8dec29adb234a671b8e6f --- manifest | 22 +++++++++++----------- manifest.uuid | 2 +- src/btree.c | 15 ++++++--------- src/vdbe.c | 11 ++++------- src/vdbe.h | 2 +- src/vdbeapi.c | 3 +-- src/vdbeaux.c | 23 +++-------------------- src/vdbesort.c | 12 +++--------- 8 files changed, 30 insertions(+), 60 deletions(-) diff --git a/manifest b/manifest index c032134449..5b732bb567 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sthe\sOP_IfNotZero\sopcode\sso\sthat\sit\sdecrements\sregister\sP1\sby\s1\srather\nthan\sthe\svalue\sin\sP3,\sand\sso\sthat\sit\sonly\sdecrements\sif\soriginally\spositive.\nThis\savoids\sdecrementing\sthe\ssmallest\s64-bit\ssigned\sinteger. -D 2016-12-18T17:42:00.870 +C Simplifications\sto\sthe\sway\sUnpackedRecord\sobjects\sare\sallocated.\s\sSmaller\nand\sfaster\scode\sthat\salso\sfixes\sa\ssubtle\s(currently\sunreachable)\sbug. +D 2016-12-21T19:45:54.698 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -331,7 +331,7 @@ F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792 F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 -F src/btree.c b2055dff0b94e03eaad48a760984a2d8e39244e6 +F src/btree.c 2e07a5a6d705c1439392460f4044ea4179d9cd40 F src/btree.h 2349a588abcd7e0c04f984e15c5c777b61637583 F src/btreeInt.h 10c4b77c2fb399580babbcc7cf652ac10dba796e F src/build.c 52970b6cf3cf3107551a5d6dd668b0b261b0b491 @@ -455,14 +455,14 @@ F src/update.c 1da7c462110bffed442a42884cb0d528c1db46d8 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c e68e8ced7328f22d2cf7b4c898c394a0de34cdf1 F src/vacuum.c 33c174b28886b2faf26e503b5a49a1c01a9b1c16 -F src/vdbe.c 4537452b85817772f159751d6b05799f3f4b09f5 -F src/vdbe.h 0c74f6305fb43b9b282dacaff102272370e327d4 +F src/vdbe.c 0106e0d4f0d39aced35c150a6919d2878df6b1e0 +F src/vdbe.h 50ee139f9c68fff91be1d717ed3a6abbd496919c F src/vdbeInt.h 42e498dbe96475dbb3fda3d85d8fd2a87eff60a2 -F src/vdbeapi.c ea4e2dc2213cc6bd7bee375a29a9b51c31b93ae0 -F src/vdbeaux.c f5edc89007f8a49e224089a4a4dddbc11bd38213 +F src/vdbeapi.c 129a2a1103e29fe839e137c641ff42b8066667b5 +F src/vdbeaux.c 7f67112cc57b2fa37b777fbf03eb32c96b337cfe F src/vdbeblob.c f4f98ea672b242f807c08c92c7faaa79e5091b65 F src/vdbemem.c d3fd85b7b7ef3eb75de29c6d7e1d10d3ca78b4fd -F src/vdbesort.c bb34eed4fb52e11ac037dccea4ee3190594c7f9e +F src/vdbesort.c eda25cb2d1727efca6f7862fea32b8aa33c0face F src/vdbetrace.c 41963d5376f0349842b5fc4aaaaacd7d9cdc0834 F src/vtab.c c4bbe0f870f52036553f8098aee0703997f0577a F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 @@ -1539,7 +1539,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 50325abe79b6a79b09ec6a1cee7d80ca02337428 -R e3435f7f9ecf849784b4c50691f0f18b +P 165c044686212fbf7182dd560ad1e57eb4cc9838 +R 4dcc327309935c00dd451588970c060d U drh -Z 8b4cd82f585875ac24b32af2b88bc83b +Z 2858688c4db6360d8c3b1c8fd6aab8f2 diff --git a/manifest.uuid b/manifest.uuid index 3da2ae76e4..74b572aeb8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -165c044686212fbf7182dd560ad1e57eb4cc9838 \ No newline at end of file +f7ab01f254cd9d7006b8dec29adb234a671b8e6f \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 0cd1a28778..d2fd448f68 100644 --- a/src/btree.c +++ b/src/btree.c @@ -763,26 +763,23 @@ static int btreeMoveto( ){ int rc; /* Status code */ UnpackedRecord *pIdxKey; /* Unpacked index key */ - char aSpace[384]; /* Temp space for pIdxKey - to avoid a malloc */ - char *pFree = 0; if( pKey ){ assert( nKey==(i64)(int)nKey ); - pIdxKey = sqlite3VdbeAllocUnpackedRecord( - pCur->pKeyInfo, aSpace, sizeof(aSpace), &pFree - ); + pIdxKey = sqlite3VdbeAllocUnpackedRecord(pCur->pKeyInfo); if( pIdxKey==0 ) return SQLITE_NOMEM_BKPT; sqlite3VdbeRecordUnpack(pCur->pKeyInfo, (int)nKey, pKey, pIdxKey); if( pIdxKey->nField==0 ){ - sqlite3DbFree(pCur->pKeyInfo->db, pFree); - return SQLITE_CORRUPT_BKPT; + rc = SQLITE_CORRUPT_BKPT; + goto moveto_done; } }else{ pIdxKey = 0; } rc = sqlite3BtreeMovetoUnpacked(pCur, pIdxKey, nKey, bias, pRes); - if( pFree ){ - sqlite3DbFree(pCur->pKeyInfo->db, pFree); +moveto_done: + if( pIdxKey ){ + sqlite3DbFree(pCur->pKeyInfo->db, pIdxKey); } return rc; } diff --git a/src/vdbe.c b/src/vdbe.c index 0935e87630..1093622735 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -3985,10 +3985,9 @@ case OP_Found: { /* jump, in3 */ int ii; VdbeCursor *pC; int res; - char *pFree; + UnpackedRecord *pFree; UnpackedRecord *pIdxKey; UnpackedRecord r; - char aTempRec[ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*4 + 7]; #ifdef SQLITE_TEST if( pOp->opcode!=OP_NoConflict ) sqlite3_found_count++; @@ -4005,7 +4004,6 @@ case OP_Found: { /* jump, in3 */ assert( pC->eCurType==CURTYPE_BTREE ); assert( pC->uc.pCursor!=0 ); assert( pC->isTable==0 ); - pFree = 0; if( pOp->p4.i>0 ){ r.pKeyInfo = pC->pKeyInfo; r.nField = (u16)pOp->p4.i; @@ -4018,10 +4016,9 @@ case OP_Found: { /* jump, in3 */ } #endif pIdxKey = &r; + pFree = 0; }else{ - pIdxKey = sqlite3VdbeAllocUnpackedRecord( - pC->pKeyInfo, aTempRec, sizeof(aTempRec), &pFree - ); + pFree = pIdxKey = sqlite3VdbeAllocUnpackedRecord(pC->pKeyInfo); if( pIdxKey==0 ) goto no_mem; assert( pIn3->flags & MEM_Blob ); (void)ExpandBlob(pIn3); @@ -4041,7 +4038,7 @@ case OP_Found: { /* jump, in3 */ } } rc = sqlite3BtreeMovetoUnpacked(pC->uc.pCursor, pIdxKey, 0, 0, &res); - sqlite3DbFree(db, pFree); + if( pFree ) sqlite3DbFree(db, pFree); if( rc!=SQLITE_OK ){ goto abort_due_to_error; } diff --git a/src/vdbe.h b/src/vdbe.h index b8bcfdec5f..925ba08e50 100644 --- a/src/vdbe.h +++ b/src/vdbe.h @@ -233,7 +233,7 @@ int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*); void sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,UnpackedRecord*); int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*); int sqlite3VdbeRecordCompareWithSkip(int, const void *, UnpackedRecord *, int); -UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(KeyInfo *, char *, int, char **); +UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(KeyInfo*); typedef int (*RecordCompare)(int,const void*,UnpackedRecord*); RecordCompare sqlite3VdbeFindCompare(UnpackedRecord*); diff --git a/src/vdbeapi.c b/src/vdbeapi.c index 050a4d0e61..213ba830d8 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -1657,10 +1657,9 @@ static UnpackedRecord *vdbeUnpackRecord( int nKey, const void *pKey ){ - char *dummy; /* Dummy argument for AllocUnpackedRecord() */ UnpackedRecord *pRet; /* Return value */ - pRet = sqlite3VdbeAllocUnpackedRecord(pKeyInfo, 0, 0, &dummy); + pRet = sqlite3VdbeAllocUnpackedRecord(pKeyInfo); if( pRet ){ memset(pRet->aMem, 0, sizeof(Mem)*(pKeyInfo->nField+1)); sqlite3VdbeRecordUnpack(pKeyInfo, nKey, pKey, pRet); diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 765f412786..cfc07ba702 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -3494,30 +3494,13 @@ u32 sqlite3VdbeSerialGet( ** If an OOM error occurs, NULL is returned. */ UnpackedRecord *sqlite3VdbeAllocUnpackedRecord( - KeyInfo *pKeyInfo, /* Description of the record */ - char *pSpace, /* Unaligned space available */ - int szSpace, /* Size of pSpace[] in bytes */ - char **ppFree /* OUT: Caller should free this pointer */ + KeyInfo *pKeyInfo /* Description of the record */ ){ UnpackedRecord *p; /* Unpacked record to return */ - int nOff; /* Increment pSpace by nOff to align it */ int nByte; /* Number of bytes required for *p */ - - /* We want to shift the pointer pSpace up such that it is 8-byte aligned. - ** Thus, we need to calculate a value, nOff, between 0 and 7, to shift - ** it by. If pSpace is already 8-byte aligned, nOff should be zero. - */ - nOff = (8 - (SQLITE_PTR_TO_INT(pSpace) & 7)) & 7; nByte = ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*(pKeyInfo->nField+1); - if( nByte>szSpace+nOff ){ - p = (UnpackedRecord *)sqlite3DbMallocRaw(pKeyInfo->db, nByte); - *ppFree = (char *)p; - if( !p ) return 0; - }else{ - p = (UnpackedRecord*)&pSpace[nOff]; - *ppFree = 0; - } - + p = (UnpackedRecord *)sqlite3DbMallocRaw(pKeyInfo->db, nByte); + if( !p ) return 0; p->aMem = (Mem*)&((char*)p)[ROUND8(sizeof(UnpackedRecord))]; assert( pKeyInfo->aSortOrder!=0 ); p->pKeyInfo = pKeyInfo; diff --git a/src/vdbesort.c b/src/vdbesort.c index 52f08bfb4b..631fb19616 100644 --- a/src/vdbesort.c +++ b/src/vdbesort.c @@ -1327,12 +1327,8 @@ static int vdbeSorterOpenTempFile( */ static int vdbeSortAllocUnpacked(SortSubtask *pTask){ if( pTask->pUnpacked==0 ){ - char *pFree; - pTask->pUnpacked = sqlite3VdbeAllocUnpackedRecord( - pTask->pSorter->pKeyInfo, 0, 0, &pFree - ); - assert( pTask->pUnpacked==(UnpackedRecord*)pFree ); - if( pFree==0 ) return SQLITE_NOMEM_BKPT; + pTask->pUnpacked = sqlite3VdbeAllocUnpackedRecord(pTask->pSorter->pKeyInfo); + if( pTask->pUnpacked==0 ) return SQLITE_NOMEM_BKPT; pTask->pUnpacked->nField = pTask->pSorter->pKeyInfo->nField; pTask->pUnpacked->errCode = 0; } @@ -2733,9 +2729,7 @@ int sqlite3VdbeSorterCompare( r2 = pSorter->pUnpacked; pKeyInfo = pCsr->pKeyInfo; if( r2==0 ){ - char *p; - r2 = pSorter->pUnpacked = sqlite3VdbeAllocUnpackedRecord(pKeyInfo,0,0,&p); - assert( pSorter->pUnpacked==(UnpackedRecord*)p ); + r2 = pSorter->pUnpacked = sqlite3VdbeAllocUnpackedRecord(pKeyInfo); if( r2==0 ) return SQLITE_NOMEM_BKPT; r2->nField = nKeyCol; } From cdfffed7902b801004b3298946875f224d3e9cf5 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 21 Dec 2016 21:26:58 +0000 Subject: [PATCH 1106/1484] Change the default lookaside configuration from 500 slots of 128 bytes each to 125 slots of 512 bytes each. This uses the same amount of memory (64,000 bytes) but seems to perform much better in test applications. FossilOrigin-Name: 52a12e47de88744187bd1c71f2820885cde414a8 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/global.c | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 5b732bb567..8581a80890 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Simplifications\sto\sthe\sway\sUnpackedRecord\sobjects\sare\sallocated.\s\sSmaller\nand\sfaster\scode\sthat\salso\sfixes\sa\ssubtle\s(currently\sunreachable)\sbug. -D 2016-12-21T19:45:54.698 +C Change\sthe\sdefault\slookaside\sconfiguration\sfrom\s500\sslots\sof\s128\sbytes\seach\sto\s125\sslots\sof\s512\sbytes\seach.\s\sThis\suses\sthe\ssame\samount\sof\smemory\s(64,000\sbytes)\sbut\sseems\sto\sperform\smuch\sbetter\sin\stest\sapplications. +D 2016-12-21T21:26:58.399 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -345,7 +345,7 @@ F src/expr.c c7c11fbe8bd4d27d04f1370efcce5a05b4fca229 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 2e9aabe1aee76273aff8a84ee92c464e095400ae F src/func.c 43916c1d8e6da5d107d91d2b212577d4f69a876a -F src/global.c 235021a21ee2cb52b304589f8f9e85a36bbe24fa +F src/global.c dcdb89f30b7aa531c5660030af106bc5bc48ef2e F src/hash.c 63d0ee752a3b92d4695b2b1f5259c4621b2cfebd F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4 F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da @@ -1539,7 +1539,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 165c044686212fbf7182dd560ad1e57eb4cc9838 -R 4dcc327309935c00dd451588970c060d +P f7ab01f254cd9d7006b8dec29adb234a671b8e6f +R 410ebc8fd4cf49ee7979c021d6ce32fb U drh -Z 2858688c4db6360d8c3b1c8fd6aab8f2 +Z 1212e279b84c412f5a6bde29137a4a85 diff --git a/manifest.uuid b/manifest.uuid index 74b572aeb8..cd272525c9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f7ab01f254cd9d7006b8dec29adb234a671b8e6f \ No newline at end of file +52a12e47de88744187bd1c71f2820885cde414a8 \ No newline at end of file diff --git a/src/global.c b/src/global.c index 46f04d9fd9..ff6c7dba52 100644 --- a/src/global.c +++ b/src/global.c @@ -181,8 +181,8 @@ SQLITE_WSD struct Sqlite3Config sqlite3Config = { SQLITE_ALLOW_COVERING_INDEX_SCAN, /* bUseCis */ 0x7ffffffe, /* mxStrlen */ 0, /* neverCorrupt */ - 128, /* szLookaside */ - 500, /* nLookaside */ + 512, /* szLookaside */ + 125, /* nLookaside */ SQLITE_STMTJRNL_SPILL, /* nStmtSpill */ {0,0,0,0,0,0,0,0}, /* m */ {0,0,0,0,0,0,0,0,0}, /* mutex */ From 344a1bf133771614774acd3233fc098eae26e5f7 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 22 Dec 2016 14:53:25 +0000 Subject: [PATCH 1107/1484] Fix harmless compiler warnings. FossilOrigin-Name: fa86db2f915c0a189c3be02b1aaa7f24d339d7d6 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/pragma.c | 4 ++++ src/shell.c | 2 +- 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 8581a80890..a70672ab10 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sthe\sdefault\slookaside\sconfiguration\sfrom\s500\sslots\sof\s128\sbytes\seach\sto\s125\sslots\sof\s512\sbytes\seach.\s\sThis\suses\sthe\ssame\samount\sof\smemory\s(64,000\sbytes)\sbut\sseems\sto\sperform\smuch\sbetter\sin\stest\sapplications. -D 2016-12-21T21:26:58.399 +C Fix\sharmless\scompiler\swarnings. +D 2016-12-22T14:53:25.934 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -381,7 +381,7 @@ F src/parse.y 29153738a7322054359320eb00b5a4cd44389f20 F src/pcache.c 51070ec9b8251bbf9c6ea3d35fd96a458752929e F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 F src/pcache1.c e3967219b2a92b9edcb9324a4ba75009090d3953 -F src/pragma.c d5adfe89ad7f3f45d4dbd25b96cbf3f6611aea2a +F src/pragma.c 5a23557e490e7ac5afef097efc4b59dce5b482c2 F src/pragma.h f9b221b2c8949ea941dbee49934299e4ed5af41c F src/prepare.c b1140c3d0cf59bc85ace00ce363153041b424b7a F src/printf.c f94da4935d1dd25420ac50c6745db1deb35e07c1 @@ -389,7 +389,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c bb070cf5f23611c44ab7e4788803684e385fc3fb F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c dfb6cadc3dcfba1b1bdbfba62ebba2b4b673413e -F src/shell.c 95fc9f4cbdfda44f3328ea23d69fb1905a974a90 +F src/shell.c bf79a69d1f9b53de958498752b78e9906c5d0aff F src/sqlite.h.in e8e2d108d82647f0a812fdb74accf91c1ec08ddc F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae @@ -1539,7 +1539,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P f7ab01f254cd9d7006b8dec29adb234a671b8e6f -R 410ebc8fd4cf49ee7979c021d6ce32fb +P 52a12e47de88744187bd1c71f2820885cde414a8 +R d04805544fe17af2729028773b1348a0 U drh -Z 1212e279b84c412f5a6bde29137a4a85 +Z 33ba125ec9059ffd904b774699d11e2c diff --git a/manifest.uuid b/manifest.uuid index cd272525c9..2f4de5bfe2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -52a12e47de88744187bd1c71f2820885cde414a8 \ No newline at end of file +fa86db2f915c0a189c3be02b1aaa7f24d339d7d6 \ No newline at end of file diff --git a/src/pragma.c b/src/pragma.c index d84e1d7929..6f2e0b545d 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -1996,6 +1996,8 @@ static int pragmaVtabConnect( StrAccum acc; char zBuf[200]; + UNUSED_PARAMETER(argc); + UNUSED_PARAMETER(argv); sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0); sqlite3StrAccumAppendAll(&acc, "CREATE TABLE x"); for(i=0, j=pPragma->iPragCName; inPragCName; i++, j++){ @@ -2152,6 +2154,8 @@ static int pragmaVtabFilter( StrAccum acc; char *zSql; + UNUSED_PARAMETER(idxNum); + UNUSED_PARAMETER(idxStr); pragmaVtabCursorClear(pCsr); j = (pTab->pName->mPragFlg & PragFlg_Result1)!=0 ? 0 : 1; for(i=0; i1 && sqlite3_strnicmp("-verbose", azArg[i], n)==0 ){ bVerbose = 1; } From 9bf755cc4467dd1e2d2fb8257f14ef974ec8bc41 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 23 Dec 2016 03:59:31 +0000 Subject: [PATCH 1108/1484] Use the VList object to replace Parse.azVar for tracking the mapping between SQL parameter names and parameter numbers. There is a performance improvement, though there are still a few hiccups in the current code. FossilOrigin-Name: 68ecafa1425a41358c88f41efea3262f1b4490f2 --- manifest | 29 ++++++++-------- manifest.uuid | 2 +- src/expr.c | 35 ++++++------------- src/sqliteInt.h | 14 ++++++-- src/tokenize.c | 6 ++-- src/util.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++++ src/vdbe.c | 2 +- src/vdbeInt.h | 3 +- src/vdbeapi.c | 21 +++--------- src/vdbeaux.c | 9 ++--- 10 files changed, 139 insertions(+), 71 deletions(-) diff --git a/manifest b/manifest index a70672ab10..7c7b701cf1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\scompiler\swarnings. -D 2016-12-22T14:53:25.934 +C Use\sthe\sVList\sobject\sto\sreplace\sParse.azVar\sfor\stracking\sthe\smapping\sbetween\nSQL\sparameter\snames\sand\sparameter\snumbers.\s\sThere\sis\sa\sperformance\nimprovement,\sthough\sthere\sare\sstill\sa\sfew\shiccups\sin\sthe\scurrent\scode. +D 2016-12-23T03:59:31.797 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -341,7 +341,7 @@ F src/ctime.c 9f2296a4e5d26ebf0e0d95a0af4628f1ea694e7a F src/date.c b48378aeac68fa20c811404955a9b62108df47d8 F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c c8bc10d145c9666a34ae906250326fdaa8d58fa5 -F src/expr.c c7c11fbe8bd4d27d04f1370efcce5a05b4fca229 +F src/expr.c e640b1c82b0f22f6c00b75989b0c13503bd5083e F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 2e9aabe1aee76273aff8a84ee92c464e095400ae F src/func.c 43916c1d8e6da5d107d91d2b212577d4f69a876a @@ -393,7 +393,7 @@ F src/shell.c bf79a69d1f9b53de958498752b78e9906c5d0aff F src/sqlite.h.in e8e2d108d82647f0a812fdb74accf91c1ec08ddc F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae -F src/sqliteInt.h adbe80409c2926d91e5485789e5bf69313cd54b0 +F src/sqliteInt.h 2075e22d50833ca2d9956d0b7a6bfb845ad05dd2 F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 @@ -448,18 +448,18 @@ F src/test_windirent.c 600398db0198ca1c77ca183831bf456746b6f5c4 F src/test_windirent.h 7edc57e2faa727026dbd5d010dd0e2e665d5aa01 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c -F src/tokenize.c 6eb0752c4fd191f789190c3708ee5b0060fd2829 +F src/tokenize.c 5c2f516876fc27fbd7753913f032f49eb89e83b5 F src/treeview.c 4e44ade3bfe59d82005039f72e09333ce2b4162c F src/trigger.c c9f0810043b265724fdb1bdd466894f984dfc182 F src/update.c 1da7c462110bffed442a42884cb0d528c1db46d8 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c -F src/util.c e68e8ced7328f22d2cf7b4c898c394a0de34cdf1 +F src/util.c adf5ff9e457b69d3cab2afa45c9c4ce5da83da06 F src/vacuum.c 33c174b28886b2faf26e503b5a49a1c01a9b1c16 -F src/vdbe.c 0106e0d4f0d39aced35c150a6919d2878df6b1e0 +F src/vdbe.c 54b12d95dbf10533ab2584acbf31ae12b8bfe171 F src/vdbe.h 50ee139f9c68fff91be1d717ed3a6abbd496919c -F src/vdbeInt.h 42e498dbe96475dbb3fda3d85d8fd2a87eff60a2 -F src/vdbeapi.c 129a2a1103e29fe839e137c641ff42b8066667b5 -F src/vdbeaux.c 7f67112cc57b2fa37b777fbf03eb32c96b337cfe +F src/vdbeInt.h 281cb70332dc8b593b8c7afe776f3a2ba7d4255e +F src/vdbeapi.c d6ebaa465f070eb1af8ba4e7b34583ece87bdd24 +F src/vdbeaux.c 1e2840804828d32332565485b7faa755a3acabdb F src/vdbeblob.c f4f98ea672b242f807c08c92c7faaa79e5091b65 F src/vdbemem.c d3fd85b7b7ef3eb75de29c6d7e1d10d3ca78b4fd F src/vdbesort.c eda25cb2d1727efca6f7862fea32b8aa33c0face @@ -1539,7 +1539,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 52a12e47de88744187bd1c71f2820885cde414a8 -R d04805544fe17af2729028773b1348a0 +P fa86db2f915c0a189c3be02b1aaa7f24d339d7d6 +R 4ff4f0f6aea9a4ccf6f07bfaa8f513d5 +T *branch * VList +T *sym-VList * +T -sym-trunk * U drh -Z 33ba125ec9059ffd904b774699d11e2c +Z d52e7f32e7ed6699ecd9b8a5a1a7ee92 diff --git a/manifest.uuid b/manifest.uuid index 2f4de5bfe2..f19d36a035 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fa86db2f915c0a189c3be02b1aaa7f24d339d7d6 \ No newline at end of file +68ecafa1425a41358c88f41efea3262f1b4490f2 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 60843bf52a..ae6107449d 100644 --- a/src/expr.c +++ b/src/expr.c @@ -934,7 +934,7 @@ Expr *sqlite3ExprFunction(Parse *pParse, ExprList *pList, Token *pToken){ ** variable number. ** ** Wildcards of the form "?nnn" are assigned the number "nnn". We make -** sure "nnn" is not too be to avoid a denial of service attack when +** sure "nnn" is not too big to avoid a denial of service attack when ** the SQL statement comes from an external source. ** ** Wildcards of the form ":aaa", "@aaa", or "$aaa" are assigned the same number @@ -981,30 +981,13 @@ void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr, u32 n){ ** number as the prior appearance of the same name, or if the name ** has never appeared before, reuse the same variable number */ - ynVar i; - for(i=x=0; inzVar; i++){ - if( pParse->azVar[i] && strcmp(pParse->azVar[i],z)==0 ){ - x = (ynVar)i+1; - break; - } + x = (ynVar)sqlite3VListNameToNum(pParse->pVList, z, n); + if( x==0 ){ + x = (ynVar)(++pParse->nVar); + pParse->pVList = sqlite3VListAdd(db, pParse->pVList, z, n, x); } - if( x==0 ) x = (ynVar)(++pParse->nVar); } pExpr->iColumn = x; - if( x>pParse->nzVar ){ - char **a; - a = sqlite3DbRealloc(db, pParse->azVar, x*sizeof(a[0])); - if( a==0 ){ - assert( db->mallocFailed ); /* Error reported through mallocFailed */ - return; - } - pParse->azVar = a; - memset(&a[pParse->nzVar], 0, (x-pParse->nzVar)*sizeof(a[0])); - pParse->nzVar = x; - } - if( pParse->azVar[x-1]==0 ){ - pParse->azVar[x-1] = sqlite3DbStrNDup(db, z, n); - } } if( pParse->nVar>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){ sqlite3ErrorMsg(pParse, "too many SQL variables"); @@ -3430,9 +3413,11 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ assert( pExpr->u.zToken[0]!=0 ); sqlite3VdbeAddOp2(v, OP_Variable, pExpr->iColumn, target); if( pExpr->u.zToken[1]!=0 ){ - assert( pExpr->u.zToken[0]=='?' - || strcmp(pExpr->u.zToken, pParse->azVar[pExpr->iColumn-1])==0 ); - sqlite3VdbeAppendP4(v, pParse->azVar[pExpr->iColumn-1], P4_STATIC); + const char *z = sqlite3VListNumToName(pParse->pVList, pExpr->iColumn); + if( z ){ + assert( pExpr->u.zToken[0]=='?' || strcmp(pExpr->u.zToken, z)==0 ); + sqlite3VdbeAppendP4(v, (char*)z, P4_STATIC); + } } return target; } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 07156092c9..d78d2072de 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1046,6 +1046,14 @@ typedef struct Walker Walker; typedef struct WhereInfo WhereInfo; typedef struct With With; +/* A VList object records a mapping between parameters/variables/wildcards +** in the SQL statement (such as $abc, @pqr, or :xyz) and the integer +** variable number associated with that parameter. See the format description +** on the sqlite3VListAdd() routine for more information. A VList is really +** just an array of integers. +*/ +typedef int VList; + /* ** Defer sourcing vdbe.h and btree.h until after the "u8" and ** "BusyHandler" typedefs. vdbe.h also requires a few of the opaque @@ -2952,7 +2960,6 @@ struct Parse { Token sLastToken; /* The last token parsed */ ynVar nVar; /* Number of '?' variables seen in the SQL so far */ - int nzVar; /* Number of available slots in azVar[] */ u8 iPkSortOrder; /* ASC or DESC for INTEGER PRIMARY KEY */ u8 explain; /* True if the EXPLAIN flag is found on the query */ #ifndef SQLITE_OMIT_VIRTUALTABLE @@ -2964,7 +2971,7 @@ struct Parse { int iSelectId; /* ID of current select for EXPLAIN output */ int iNextSelectId; /* Next available select ID for EXPLAIN output */ #endif - char **azVar; /* Pointers to names of parameters */ + VList *pVList; /* Mapping between variable names and numbers */ Vdbe *pReprepare; /* VM being reprepared (sqlite3Reprepare()) */ const char *zTail; /* All SQL text past the last semicolon parsed */ Table *pNewTable; /* A table being constructed by CREATE TABLE */ @@ -3864,6 +3871,9 @@ LogEst sqlite3LogEstFromDouble(double); defined(SQLITE_EXPLAIN_ESTIMATED_ROWS) u64 sqlite3LogEstToInt(LogEst); #endif +VList *sqlite3VListAdd(sqlite3*,VList*,const char*,int,int); +const char *sqlite3VListNumToName(VList*,int); +int sqlite3VListNameToNum(VList*,const char*,int); /* ** Routines to read and write variable-length integers. These used to diff --git a/src/tokenize.c b/src/tokenize.c index 0e60c56d66..c400dcd554 100644 --- a/src/tokenize.c +++ b/src/tokenize.c @@ -500,8 +500,7 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){ assert( pParse->pNewTable==0 ); assert( pParse->pNewTrigger==0 ); assert( pParse->nVar==0 ); - assert( pParse->nzVar==0 ); - assert( pParse->azVar==0 ); + assert( pParse->pVList==0 ); while( 1 ){ assert( i>=0 ); if( zSql[i]!=0 ){ @@ -588,8 +587,7 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){ if( pParse->pWithToFree ) sqlite3WithDelete(db, pParse->pWithToFree); sqlite3DeleteTrigger(db, pParse->pNewTrigger); - for(i=pParse->nzVar-1; i>=0; i--) sqlite3DbFree(db, pParse->azVar[i]); - sqlite3DbFree(db, pParse->azVar); + sqlite3DbFree(db, pParse->pVList); while( pParse->pAinc ){ AutoincInfo *p = pParse->pAinc; pParse->pAinc = p->pNext; diff --git a/src/util.c b/src/util.c index a614f14619..5ece9226ff 100644 --- a/src/util.c +++ b/src/util.c @@ -1453,3 +1453,92 @@ u64 sqlite3LogEstToInt(LogEst x){ return x>=3 ? (n+8)<<(x-3) : (n+8)>>(3-x); } #endif /* defined SCANSTAT or STAT4 or ESTIMATED_ROWS */ + +/* +** Add a new name/number pair to a VList. This might require that the +** VList object be reallocated, so return the new VList. If an OOM +** error occurs, the original VList freed, NULL is returned, and the +** db->mallocFailed flag is set. +** +** A VList is really just an array of integers. To destroy a VList, +** simply pass it to sqlite3DbFree(). +** +** The first integer is the number of integers allocated for the whole +** VList. The second integer is the number of integers actually used. +** Each name/number pair is encoded by subsequent groups of 3 or more +** integers. +** +** Each name/number pair starts with two integers which are the number +** value for the pair and the size of the name/number pair, respectively. +** The text name overlays one or more following integers. The text name +** is always zero-terminated. +** +*/ +VList *sqlite3VListAdd( + sqlite3 *db, /* The database connection used for malloc() */ + VList *pIn, /* The input VList. Might be NULL */ + const char *zName, /* Name of symbol to add */ + int nName, /* Bytes of text in zName */ + int iVal /* Value to associate with zName */ +){ + int nInt; /* number of sizeof(int) objects needed for zName */ + char *z; + int i; + + nInt = nName/4 + 3; + if( pIn==0 || pIn[1]+nInt > pIn[0] ){ + /* Enlarge the allocation */ + int nAlloc = (pIn ? pIn[0]*2 : 10) + nInt; + VList *pOut = sqlite3DbRealloc(db, pIn, nAlloc*sizeof(int)); + if( pOut==0 ){ + sqlite3DbFree(db, pIn); + return 0; + } + if( pIn==0 ) pOut[1] = 2; + pIn = pOut; + pIn[0] = nAlloc; + } + i = pIn[1]; + pIn[i] = iVal; + pIn[i+1] = nInt; + z = (char*)&pIn[i+2]; + pIn[1] = i+nInt; + assert( pIn[1]<=pIn[0] ); + memcpy(z, zName, nName); + z[nName] = 0; + return pIn; +} + +/* +** Return a pointer to the name of a variable in the given VList that +** has the value iVal. Or return a NULL if there is no such variable in +** the list +*/ +const char *sqlite3VListNumToName(VList *pIn, int iVal){ + int i, mx; + if( pIn==0 ) return 0; + mx = pIn[1]; + i = 2; + do{ + if( pIn[i]==iVal ) return (char*)&pIn[i+2]; + i += pIn[i+1]; + }while( ip1>0 && pOp->p1<=p->nVar ); - assert( pOp->p4.z==0 || pOp->p4.z==p->azVar[pOp->p1-1] ); + assert( pOp->p4.z==0 || pOp->p4.z==sqlite3VListNumToName(p->pVList,pOp->p1) ); pVar = &p->aVar[pOp->p1 - 1]; if( sqlite3VdbeMemTooBig(pVar) ){ goto too_big; diff --git a/src/vdbeInt.h b/src/vdbeInt.h index dbdde00edf..3e6bb06889 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -346,7 +346,6 @@ struct Vdbe { Vdbe *pPrev,*pNext; /* Linked list of VDBEs with the same Vdbe.db */ Parse *pParse; /* Parsing context used to create this Vdbe */ ynVar nVar; /* Number of entries in aVar[] */ - ynVar nzVar; /* Number of entries in azVar[] */ u32 magic; /* Magic number for sanity checking */ int nMem; /* Number of memory locations currently allocated */ int nCursor; /* Number of slots in apCsr[] */ @@ -371,7 +370,7 @@ struct Vdbe { char *zErrMsg; /* Error message written here */ VdbeCursor **apCsr; /* One element of this array for each open cursor */ Mem *aVar; /* Values for the OP_Variable opcode. */ - char **azVar; /* Name of variables */ + VList *pVList; /* Name of variables */ #ifndef SQLITE_OMIT_TRACE i64 startTime; /* Time when query started - used for profiling */ #endif diff --git a/src/vdbeapi.c b/src/vdbeapi.c index 213ba830d8..32794de9a0 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -1470,10 +1470,8 @@ int sqlite3_bind_parameter_count(sqlite3_stmt *pStmt){ */ const char *sqlite3_bind_parameter_name(sqlite3_stmt *pStmt, int i){ Vdbe *p = (Vdbe*)pStmt; - if( p==0 || i<1 || i>p->nzVar ){ - return 0; - } - return p->azVar[i-1]; + if( p==0 ) return 0; + return sqlite3VListNumToName(p->pVList, i); } /* @@ -1482,19 +1480,8 @@ const char *sqlite3_bind_parameter_name(sqlite3_stmt *pStmt, int i){ ** return 0. */ int sqlite3VdbeParameterIndex(Vdbe *p, const char *zName, int nName){ - int i; - if( p==0 ){ - return 0; - } - if( zName ){ - for(i=0; inzVar; i++){ - const char *z = p->azVar[i]; - if( z && strncmp(z,zName,nName)==0 && z[nName]==0 ){ - return i+1; - } - } - } - return 0; + if( p==0 || zName==0 ) return 0; + return sqlite3VListNameToNum(p->pVList, zName, nName); } int sqlite3_bind_parameter_index(sqlite3_stmt *pStmt, const char *zName){ return sqlite3VdbeParameterIndex((Vdbe*)pStmt, zName, sqlite3Strlen30(zName)); diff --git a/src/vdbeaux.c b/src/vdbeaux.c index cfc07ba702..53aedf4983 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -1975,10 +1975,8 @@ void sqlite3VdbeMakeReady( x.nFree = x.nNeeded; }while( !db->mallocFailed ); - p->nzVar = pParse->nzVar; - p->azVar = pParse->azVar; - pParse->nzVar = 0; - pParse->azVar = 0; + p->pVList = pParse->pVList; + pParse->pVList = 0; p->explain = pParse->explain; if( db->mallocFailed ){ p->nVar = 0; @@ -2982,8 +2980,7 @@ void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){ } if( p->magic!=VDBE_MAGIC_INIT ){ releaseMemArray(p->aVar, p->nVar); - for(i=p->nzVar-1; i>=0; i--) sqlite3DbFree(db, p->azVar[i]); - sqlite3DbFree(db, p->azVar); + sqlite3DbFree(db, p->pVList); sqlite3DbFree(db, p->pFree); } vdbeFreeOpArray(db, p->aOp, p->nOp); From f326d66d618c50bfcb348e3023793524da25c28b Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 23 Dec 2016 13:30:53 +0000 Subject: [PATCH 1109/1484] Fix the VList object so that it actually works. FossilOrigin-Name: 9dcd85698af46fd5ba34004ca690d368c4ae3078 --- manifest | 17 +++++++---------- manifest.uuid | 2 +- src/expr.c | 29 +++++++++++++++++------------ src/vdbeaux.c | 10 ++++++---- 4 files changed, 31 insertions(+), 27 deletions(-) diff --git a/manifest b/manifest index 7c7b701cf1..ed40e8d7f5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Use\sthe\sVList\sobject\sto\sreplace\sParse.azVar\sfor\stracking\sthe\smapping\sbetween\nSQL\sparameter\snames\sand\sparameter\snumbers.\s\sThere\sis\sa\sperformance\nimprovement,\sthough\sthere\sare\sstill\sa\sfew\shiccups\sin\sthe\scurrent\scode. -D 2016-12-23T03:59:31.797 +C Fix\sthe\sVList\sobject\sso\sthat\sit\sactually\sworks. +D 2016-12-23T13:30:53.667 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -341,7 +341,7 @@ F src/ctime.c 9f2296a4e5d26ebf0e0d95a0af4628f1ea694e7a F src/date.c b48378aeac68fa20c811404955a9b62108df47d8 F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c c8bc10d145c9666a34ae906250326fdaa8d58fa5 -F src/expr.c e640b1c82b0f22f6c00b75989b0c13503bd5083e +F src/expr.c fedcfcd8749f95627dfe0aeb5630b68c5979cb0b F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 2e9aabe1aee76273aff8a84ee92c464e095400ae F src/func.c 43916c1d8e6da5d107d91d2b212577d4f69a876a @@ -459,7 +459,7 @@ F src/vdbe.c 54b12d95dbf10533ab2584acbf31ae12b8bfe171 F src/vdbe.h 50ee139f9c68fff91be1d717ed3a6abbd496919c F src/vdbeInt.h 281cb70332dc8b593b8c7afe776f3a2ba7d4255e F src/vdbeapi.c d6ebaa465f070eb1af8ba4e7b34583ece87bdd24 -F src/vdbeaux.c 1e2840804828d32332565485b7faa755a3acabdb +F src/vdbeaux.c 12919c5aa354296d6b9ba808bca3e9dda836858c F src/vdbeblob.c f4f98ea672b242f807c08c92c7faaa79e5091b65 F src/vdbemem.c d3fd85b7b7ef3eb75de29c6d7e1d10d3ca78b4fd F src/vdbesort.c eda25cb2d1727efca6f7862fea32b8aa33c0face @@ -1539,10 +1539,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P fa86db2f915c0a189c3be02b1aaa7f24d339d7d6 -R 4ff4f0f6aea9a4ccf6f07bfaa8f513d5 -T *branch * VList -T *sym-VList * -T -sym-trunk * +P 68ecafa1425a41358c88f41efea3262f1b4490f2 +R e3b464298f4645ba05beea0d35779569 U drh -Z d52e7f32e7ed6699ecd9b8a5a1a7ee92 +Z e1b50397ad009309edd4038594b0291c diff --git a/manifest.uuid b/manifest.uuid index f19d36a035..d87d18b9ad 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -68ecafa1425a41358c88f41efea3262f1b4490f2 \ No newline at end of file +9dcd85698af46fd5ba34004ca690d368c4ae3078 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index ae6107449d..3f8406bc53 100644 --- a/src/expr.c +++ b/src/expr.c @@ -945,6 +945,7 @@ Expr *sqlite3ExprFunction(Parse *pParse, ExprList *pList, Token *pToken){ void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr, u32 n){ sqlite3 *db = pParse->db; const char *z; + ynVar x; if( pExpr==0 ) return; assert( !ExprHasProperty(pExpr, EP_IntValue|EP_Reduced|EP_TokenOnly) ); @@ -955,9 +956,9 @@ void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr, u32 n){ if( z[1]==0 ){ /* Wildcard of the form "?". Assign the next variable number */ assert( z[0]=='?' ); - pExpr->iColumn = (ynVar)(++pParse->nVar); + x = (ynVar)(++pParse->nVar); }else{ - ynVar x; + int doAdd = 0; if( z[0]=='?' ){ /* Wildcard of the form "?nnn". Convert "nnn" to an integer and ** use it as the variable number */ @@ -973,8 +974,11 @@ void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr, u32 n){ db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]); return; } - if( i>pParse->nVar ){ - pParse->nVar = (int)i; + if( x>pParse->nVar ){ + pParse->nVar = (int)x; + doAdd = 1; + }else if( sqlite3VListNumToName(pParse->pVList, x)==0 ){ + doAdd = 1; } }else{ /* Wildcards like ":aaa", "$aaa" or "@aaa". Reuse the same variable @@ -984,12 +988,15 @@ void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr, u32 n){ x = (ynVar)sqlite3VListNameToNum(pParse->pVList, z, n); if( x==0 ){ x = (ynVar)(++pParse->nVar); - pParse->pVList = sqlite3VListAdd(db, pParse->pVList, z, n, x); + doAdd = 1; } } - pExpr->iColumn = x; - } - if( pParse->nVar>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){ + if( doAdd ){ + pParse->pVList = sqlite3VListAdd(db, pParse->pVList, z, n, x); + } + } + pExpr->iColumn = x; + if( x>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){ sqlite3ErrorMsg(pParse, "too many SQL variables"); } } @@ -3414,10 +3421,8 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ sqlite3VdbeAddOp2(v, OP_Variable, pExpr->iColumn, target); if( pExpr->u.zToken[1]!=0 ){ const char *z = sqlite3VListNumToName(pParse->pVList, pExpr->iColumn); - if( z ){ - assert( pExpr->u.zToken[0]=='?' || strcmp(pExpr->u.zToken, z)==0 ); - sqlite3VdbeAppendP4(v, (char*)z, P4_STATIC); - } + assert( pExpr->u.zToken[0]=='?' || strcmp(pExpr->u.zToken, z)==0 ); + sqlite3VdbeAppendP4(v, (char*)z, P4_STATIC); } return target; } diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 53aedf4983..7c9a295c92 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -2970,7 +2970,6 @@ void sqlite3VdbeDeleteAuxData(sqlite3 *db, AuxData **pp, int iOp, int mask){ */ void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){ SubProgram *pSub, *pNext; - int i; assert( p->db==0 || p->db==db ); releaseMemArray(p->aColName, p->nResColumn*COLNAME_N); for(pSub=p->pProgram; pSub; pSub=pNext){ @@ -2987,10 +2986,13 @@ void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){ sqlite3DbFree(db, p->aColName); sqlite3DbFree(db, p->zSql); #ifdef SQLITE_ENABLE_STMT_SCANSTATUS - for(i=0; inScan; i++){ - sqlite3DbFree(db, p->aScan[i].zName); + { + int i; + for(i=0; inScan; i++){ + sqlite3DbFree(db, p->aScan[i].zName); + } + sqlite3DbFree(db, p->aScan); } - sqlite3DbFree(db, p->aScan); #endif } From ce1bbe51b5c57b6487e92fe83c5c168a84c9e051 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 23 Dec 2016 13:52:45 +0000 Subject: [PATCH 1110/1484] Add check to prevent a VList from growing after pointers to labels have been taken. FossilOrigin-Name: aa23d7eaf69f5ecbf9500b2353846094cae41e6c --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/expr.c | 1 + src/util.c | 32 +++++++++++++++++++++++--------- 4 files changed, 32 insertions(+), 17 deletions(-) diff --git a/manifest b/manifest index ed40e8d7f5..6842b9b8b8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\sVList\sobject\sso\sthat\sit\sactually\sworks. -D 2016-12-23T13:30:53.667 +C Add\scheck\sto\sprevent\sa\sVList\sfrom\sgrowing\safter\spointers\sto\slabels\shave\sbeen\ntaken. +D 2016-12-23T13:52:45.010 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -341,7 +341,7 @@ F src/ctime.c 9f2296a4e5d26ebf0e0d95a0af4628f1ea694e7a F src/date.c b48378aeac68fa20c811404955a9b62108df47d8 F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c c8bc10d145c9666a34ae906250326fdaa8d58fa5 -F src/expr.c fedcfcd8749f95627dfe0aeb5630b68c5979cb0b +F src/expr.c a90e37bc542abe33890cafccacbf8a7db9cb5401 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 2e9aabe1aee76273aff8a84ee92c464e095400ae F src/func.c 43916c1d8e6da5d107d91d2b212577d4f69a876a @@ -453,7 +453,7 @@ F src/treeview.c 4e44ade3bfe59d82005039f72e09333ce2b4162c F src/trigger.c c9f0810043b265724fdb1bdd466894f984dfc182 F src/update.c 1da7c462110bffed442a42884cb0d528c1db46d8 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c -F src/util.c adf5ff9e457b69d3cab2afa45c9c4ce5da83da06 +F src/util.c 1534060bc034cdc51381c040c8bd6252dbcb64c9 F src/vacuum.c 33c174b28886b2faf26e503b5a49a1c01a9b1c16 F src/vdbe.c 54b12d95dbf10533ab2584acbf31ae12b8bfe171 F src/vdbe.h 50ee139f9c68fff91be1d717ed3a6abbd496919c @@ -1539,7 +1539,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 68ecafa1425a41358c88f41efea3262f1b4490f2 -R e3b464298f4645ba05beea0d35779569 +P 9dcd85698af46fd5ba34004ca690d368c4ae3078 +R 2f816100f2d74d42d3a1978c26f09af2 U drh -Z e1b50397ad009309edd4038594b0291c +Z 3cd0270ead5747022cdd1e84b75d8956 diff --git a/manifest.uuid b/manifest.uuid index d87d18b9ad..63d4ce335d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9dcd85698af46fd5ba34004ca690d368c4ae3078 \ No newline at end of file +aa23d7eaf69f5ecbf9500b2353846094cae41e6c \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 3f8406bc53..ecc6c7928b 100644 --- a/src/expr.c +++ b/src/expr.c @@ -3422,6 +3422,7 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ if( pExpr->u.zToken[1]!=0 ){ const char *z = sqlite3VListNumToName(pParse->pVList, pExpr->iColumn); assert( pExpr->u.zToken[0]=='?' || strcmp(pExpr->u.zToken, z)==0 ); + pParse->pVList[0] = 0; /* Indicate VList may no longer be enlarged */ sqlite3VdbeAppendP4(v, (char*)z, P4_STATIC); } return target; diff --git a/src/util.c b/src/util.c index 5ece9226ff..b9684c6c01 100644 --- a/src/util.c +++ b/src/util.c @@ -1457,7 +1457,7 @@ u64 sqlite3LogEstToInt(LogEst x){ /* ** Add a new name/number pair to a VList. This might require that the ** VList object be reallocated, so return the new VList. If an OOM -** error occurs, the original VList freed, NULL is returned, and the +** error occurs, the original VList returned and the ** db->mallocFailed flag is set. ** ** A VList is really just an array of integers. To destroy a VList, @@ -1468,11 +1468,27 @@ u64 sqlite3LogEstToInt(LogEst x){ ** Each name/number pair is encoded by subsequent groups of 3 or more ** integers. ** -** Each name/number pair starts with two integers which are the number +** Each name/number pair starts with two integers which are the numeric ** value for the pair and the size of the name/number pair, respectively. ** The text name overlays one or more following integers. The text name ** is always zero-terminated. -** +** +** Conceptually: +** +** struct VList { +** int nAlloc; // Number of allocated slots +** int nUsed; // Number of used slots +** struct VListEntry { +** int iValue; // Value for this entry +** int nSlot; // Slots used by this entry +** // ... variable name goes here +** } a[0]; +** } +** +** During code generation, pointers to the variable names within the +** VList are taken. When that happens, nAlloc is set to zero as an +** indication that the VList may never again be enlarged, since the +** accompanying realloc() would invalidate the pointers. */ VList *sqlite3VListAdd( sqlite3 *db, /* The database connection used for malloc() */ @@ -1482,18 +1498,16 @@ VList *sqlite3VListAdd( int iVal /* Value to associate with zName */ ){ int nInt; /* number of sizeof(int) objects needed for zName */ - char *z; - int i; + char *z; /* Pointer to where zName will be stored */ + int i; /* Index in pIn[] where zName is stored */ nInt = nName/4 + 3; + assert( pIn==0 || pIn[0]>=3 ); /* Verify ok to add new elements */ if( pIn==0 || pIn[1]+nInt > pIn[0] ){ /* Enlarge the allocation */ int nAlloc = (pIn ? pIn[0]*2 : 10) + nInt; VList *pOut = sqlite3DbRealloc(db, pIn, nAlloc*sizeof(int)); - if( pOut==0 ){ - sqlite3DbFree(db, pIn); - return 0; - } + if( pOut==0 ) return pIn; if( pIn==0 ) pOut[1] = 2; pIn = pOut; pIn[0] = nAlloc; From 6bd4dc6dc472b144a79cf646bdfcae8af2ec29b7 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 23 Dec 2016 16:05:22 +0000 Subject: [PATCH 1111/1484] Fill in missing opcode documentation entries for OP_SorterNext and OP_SorterSort. FossilOrigin-Name: 2940661b8c014b94973e05c44f1b1f4f443dbdd3 --- manifest | 13 ++++++------- manifest.uuid | 2 +- src/vdbe.c | 16 ++++++++++++++++ 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 70f6bed2e2..28e652f06d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Use\sthe\sVList\sobject\sto\scapture\sthe\smapping\sbetween\sSQL\sparameter\snames\sand\nvariable\snumbers\sin\sa\ssingle\smemory\sallocation. -D 2016-12-23T13:54:22.985 +C Fill\sin\smissing\sopcode\sdocumentation\sentries\sfor\sOP_SorterNext\sand\nOP_SorterSort. +D 2016-12-23T16:05:22.280 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -455,7 +455,7 @@ F src/update.c 1da7c462110bffed442a42884cb0d528c1db46d8 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 1534060bc034cdc51381c040c8bd6252dbcb64c9 F src/vacuum.c 33c174b28886b2faf26e503b5a49a1c01a9b1c16 -F src/vdbe.c 54b12d95dbf10533ab2584acbf31ae12b8bfe171 +F src/vdbe.c 73ded9a61658c82cf726cb7feb070836cb4f8a87 F src/vdbe.h 50ee139f9c68fff91be1d717ed3a6abbd496919c F src/vdbeInt.h 281cb70332dc8b593b8c7afe776f3a2ba7d4255e F src/vdbeapi.c d6ebaa465f070eb1af8ba4e7b34583ece87bdd24 @@ -1539,8 +1539,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P fa86db2f915c0a189c3be02b1aaa7f24d339d7d6 aa23d7eaf69f5ecbf9500b2353846094cae41e6c -R 2f816100f2d74d42d3a1978c26f09af2 -T +closed aa23d7eaf69f5ecbf9500b2353846094cae41e6c +P 99fddf2ecb7202bfdf5ddc4cc1c4e155c883f7ec +R 56df15bb1ab261ae6795a2b612a0d655 U drh -Z bdddf7c19647dc703ac75fbc8ecd14da +Z 214f09845ac7912624c689c7d0a93d7d diff --git a/manifest.uuid b/manifest.uuid index 51207f7f2f..31b7ace9e9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -99fddf2ecb7202bfdf5ddc4cc1c4e155c883f7ec \ No newline at end of file +2940661b8c014b94973e05c44f1b1f4f443dbdd3 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 6d243263e3..ec722691f1 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -4820,6 +4820,15 @@ case OP_Last: { /* jump */ } +/* Opcode: SorterSort P1 P2 * * * +** +** After all records have been inserted into the Sorter object +** identified by P1, invoke this opcode to actually do the sorting. +** Jump to P2 if there are no records to be sorted. +** +** This opcode is an alias for OP_Sort and OP_Rewind that is used +** for Sorter objects. +*/ /* Opcode: Sort P1 P2 * * * ** ** This opcode does exactly the same thing as OP_Rewind except that @@ -4947,6 +4956,13 @@ case OP_Rewind: { /* jump */ ** This opcode works just like Prev except that if cursor P1 is not ** open it behaves a no-op. */ +/* Opcode: SorterNext P1 P2 * * P5 +** +** This opcode works just like OP_Next except that P1 must be a +** sorter object for which the OP_SorterSort opcode has been +** invoked. This opcode advances the cursor to the next sorted +** record, or jumps to P2 if there are no more sorted records. +*/ case OP_SorterNext: { /* jump */ VdbeCursor *pC; int res; From a4b81d2a44ea288af4293d0e2cd593580dd84f61 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 24 Dec 2016 18:04:28 +0000 Subject: [PATCH 1112/1484] In the command-line shell, improve the formatting to the ".databases" command and on the ".tables" command, only show the schema prefix for databases past the first ("main") database. FossilOrigin-Name: c0d5626e274cbf8c2d2167183c4d6835d72dae57 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/shell.c | 8 ++++---- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 28e652f06d..812a43e8c0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fill\sin\smissing\sopcode\sdocumentation\sentries\sfor\sOP_SorterNext\sand\nOP_SorterSort. -D 2016-12-23T16:05:22.280 +C In\sthe\scommand-line\sshell,\simprove\sthe\sformatting\sto\sthe\s".databases"\ncommand\sand\son\sthe\s".tables"\scommand,\sonly\sshow\sthe\sschema\sprefix\sfor\ndatabases\spast\sthe\sfirst\s("main")\sdatabase. +D 2016-12-24T18:04:28.394 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -389,7 +389,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c bb070cf5f23611c44ab7e4788803684e385fc3fb F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c dfb6cadc3dcfba1b1bdbfba62ebba2b4b673413e -F src/shell.c bf79a69d1f9b53de958498752b78e9906c5d0aff +F src/shell.c e99c2d27b263166a1eb58d7db200f481308a2066 F src/sqlite.h.in e8e2d108d82647f0a812fdb74accf91c1ec08ddc F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae @@ -1539,7 +1539,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 99fddf2ecb7202bfdf5ddc4cc1c4e155c883f7ec -R 56df15bb1ab261ae6795a2b612a0d655 +P 2940661b8c014b94973e05c44f1b1f4f443dbdd3 +R 52df4fe6a27080b6c7afd95948d62b3b U drh -Z 214f09845ac7912624c689c7d0a93d7d +Z 7fc049944b0ca3b30ace09cf9ed6380f diff --git a/manifest.uuid b/manifest.uuid index 31b7ace9e9..ddb2c1308d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2940661b8c014b94973e05c44f1b1f4f443dbdd3 \ No newline at end of file +c0d5626e274cbf8c2d2167183c4d6835d72dae57 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 7e89527d90..3549ae3651 100644 --- a/src/shell.c +++ b/src/shell.c @@ -3707,8 +3707,8 @@ static int do_meta_command(char *zLine, ShellState *p){ data.showHeader = 1; data.cMode = data.mode = MODE_Column; data.colWidth[0] = 3; - data.colWidth[1] = 15; - data.colWidth[2] = 58; + data.colWidth[1] = 0; + data.colWidth[2] = 0; data.cnt = 0; sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg); if( zErrMsg ){ @@ -4978,9 +4978,9 @@ static int do_meta_command(char *zLine, ShellState *p){ " WHERE type IN ('table','view')" " AND name NOT LIKE 'sqlite_%%'" " AND name LIKE ?1"); - while( zSql && sqlite3_step(pStmt)==SQLITE_ROW ){ + for(ii=0; zSql && sqlite3_step(pStmt)==SQLITE_ROW; ii++){ const char *zDbName = (const char*)sqlite3_column_text(pStmt, 1); - if( zDbName==0 || strcmp(zDbName,"main")==0 ) continue; + if( zDbName==0 || ii==0 ) continue; if( strcmp(zDbName,"temp")==0 ){ zSql = sqlite3_mprintf( "%z UNION ALL " From b20a61b704844076d5e73877ca47836a1af495a6 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 24 Dec 2016 18:18:58 +0000 Subject: [PATCH 1113/1484] Change the output format of the ".databases" command in the command-line shell so that it shows the schema name, a colon, and the corresponding filename. FossilOrigin-Name: 8558512e9ca343300a767ef23810f2d7b50fd925 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/shell.c | 11 +++++------ 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 812a43e8c0..34ebd6213d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\sthe\scommand-line\sshell,\simprove\sthe\sformatting\sto\sthe\s".databases"\ncommand\sand\son\sthe\s".tables"\scommand,\sonly\sshow\sthe\sschema\sprefix\sfor\ndatabases\spast\sthe\sfirst\s("main")\sdatabase. -D 2016-12-24T18:04:28.394 +C Change\sthe\soutput\sformat\sof\sthe\s".databases"\scommand\sin\sthe\scommand-line\sshell\nso\sthat\sit\sshows\sthe\sschema\sname,\sa\scolon,\sand\sthe\scorresponding\sfilename. +D 2016-12-24T18:18:58.867 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -389,7 +389,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c bb070cf5f23611c44ab7e4788803684e385fc3fb F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c dfb6cadc3dcfba1b1bdbfba62ebba2b4b673413e -F src/shell.c e99c2d27b263166a1eb58d7db200f481308a2066 +F src/shell.c 1594340a8c7b75751b73950f0006643d116d3ef5 F src/sqlite.h.in e8e2d108d82647f0a812fdb74accf91c1ec08ddc F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae @@ -1539,7 +1539,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 2940661b8c014b94973e05c44f1b1f4f443dbdd3 -R 52df4fe6a27080b6c7afd95948d62b3b +P c0d5626e274cbf8c2d2167183c4d6835d72dae57 +R 70d48e0060cab5ee6418aa941c5a0469 U drh -Z 7fc049944b0ca3b30ace09cf9ed6380f +Z 4cb56a28188b85f79aed3457527e657d diff --git a/manifest.uuid b/manifest.uuid index ddb2c1308d..bf31e58ff9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c0d5626e274cbf8c2d2167183c4d6835d72dae57 \ No newline at end of file +8558512e9ca343300a767ef23810f2d7b50fd925 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 3549ae3651..2ad6c8c195 100644 --- a/src/shell.c +++ b/src/shell.c @@ -3704,13 +3704,12 @@ static int do_meta_command(char *zLine, ShellState *p){ char *zErrMsg = 0; open_db(p, 0); memcpy(&data, p, sizeof(data)); - data.showHeader = 1; - data.cMode = data.mode = MODE_Column; - data.colWidth[0] = 3; - data.colWidth[1] = 0; - data.colWidth[2] = 0; + data.showHeader = 0; + data.cMode = data.mode = MODE_List; + sqlite3_snprintf(sizeof(data.colSeparator),data.colSeparator,": "); data.cnt = 0; - sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg); + sqlite3_exec(p->db, "SELECT name, file FROM pragma_database_list", + callback, &data, &zErrMsg); if( zErrMsg ){ utf8_printf(stderr,"Error: %s\n", zErrMsg); sqlite3_free(zErrMsg); From 2951809ed48c8500712acd0b52f891924ebd1739 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 24 Dec 2016 19:37:16 +0000 Subject: [PATCH 1114/1484] The schema name "main" is always an acceptable alias for the primary database even if the primary database is renamed using SQLITE_DBCONFIG_MAINDBNAME. FossilOrigin-Name: 2f481b854f04bec546eb172d1b6dbc88067d3fda --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/build.c | 5 ++++- src/main.c | 11 ++--------- 4 files changed, 14 insertions(+), 18 deletions(-) diff --git a/manifest b/manifest index 34ebd6213d..7ac383dc3b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sthe\soutput\sformat\sof\sthe\s".databases"\scommand\sin\sthe\scommand-line\sshell\nso\sthat\sit\sshows\sthe\sschema\sname,\sa\scolon,\sand\sthe\scorresponding\sfilename. -D 2016-12-24T18:18:58.867 +C The\sschema\sname\s"main"\sis\salways\san\sacceptable\salias\sfor\sthe\sprimary\sdatabase\neven\sif\sthe\sprimary\sdatabase\sis\srenamed\susing\sSQLITE_DBCONFIG_MAINDBNAME. +D 2016-12-24T19:37:16.675 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -334,7 +334,7 @@ F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 F src/btree.c 2e07a5a6d705c1439392460f4044ea4179d9cd40 F src/btree.h 2349a588abcd7e0c04f984e15c5c777b61637583 F src/btreeInt.h 10c4b77c2fb399580babbcc7cf652ac10dba796e -F src/build.c 52970b6cf3cf3107551a5d6dd668b0b261b0b491 +F src/build.c 9e799f1edd910dfa8a0bc29bd390d35d310596af F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 9f2296a4e5d26ebf0e0d95a0af4628f1ea694e7a @@ -353,7 +353,7 @@ F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 F src/insert.c 91ba5d0143e66479081536ebbaff1850ec9f57d9 F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e F src/loadext.c 5d6642d141c07d366e43d359e94ec9de47add41d -F src/main.c c0daeb1f716de3e93c573aeed6b164faeddee772 +F src/main.c ec789a410860bcdc5d8f7a82090043f482482aec F src/malloc.c 5ee7c2d3dcb1b0a902c9c6d0115deef54736bdfa F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b @@ -1539,7 +1539,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P c0d5626e274cbf8c2d2167183c4d6835d72dae57 -R 70d48e0060cab5ee6418aa941c5a0469 +P 8558512e9ca343300a767ef23810f2d7b50fd925 +R b30977e76e92562c072b2b96c5549420 U drh -Z 4cb56a28188b85f79aed3457527e657d +Z d1e40bfcd22533ee4ef2e0ad49608c3a diff --git a/manifest.uuid b/manifest.uuid index bf31e58ff9..8afde31bf9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8558512e9ca343300a767ef23810f2d7b50fd925 \ No newline at end of file +2f481b854f04bec546eb172d1b6dbc88067d3fda \ No newline at end of file diff --git a/src/build.c b/src/build.c index 1dfa998d78..cd9c81be82 100644 --- a/src/build.c +++ b/src/build.c @@ -716,7 +716,10 @@ int sqlite3FindDbName(sqlite3 *db, const char *zName){ if( zName ){ Db *pDb; for(i=(db->nDb-1), pDb=&db->aDb[i]; i>=0; i--, pDb--){ - if( 0==sqlite3StrICmp(pDb->zDbSName, zName) ) break; + if( 0==sqlite3_stricmp(pDb->zDbSName, zName) ) break; + /* "main" is always an acceptable alias for the primary database + ** even if it has been renamed using SQLITE_DBCONFIG_MAINDBNAME. */ + if( i==0 && 0==sqlite3_stricmp("main", zName) ) break; } } return i; diff --git a/src/main.c b/src/main.c index de971fe785..244ac0f0fc 100644 --- a/src/main.c +++ b/src/main.c @@ -3926,15 +3926,8 @@ sqlite3_int64 sqlite3_uri_int64( ** Return the Btree pointer identified by zDbName. Return NULL if not found. */ Btree *sqlite3DbNameToBtree(sqlite3 *db, const char *zDbName){ - int i; - for(i=0; inDb; i++){ - if( db->aDb[i].pBt - && (zDbName==0 || sqlite3StrICmp(zDbName, db->aDb[i].zDbSName)==0) - ){ - return db->aDb[i].pBt; - } - } - return 0; + int iDb = zDbName ? sqlite3FindDbName(db, zDbName) : 0; + return iDb<0 ? 0 : db->aDb[iDb].pBt; } /* From 6a5a4208fce89a15870af87d4254e0caa99323a8 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 24 Dec 2016 21:32:40 +0000 Subject: [PATCH 1115/1484] Combine the implementations of the ".tables" and ".indexes" commands in the command-line shell. The ".indexes" command now puts the indexes in multiple columns, just like ".tables" and shows all indexes in all attached databases. FossilOrigin-Name: def29333655691c7d54451193be13445a2857d29 --- manifest | 12 +++---- manifest.uuid | 2 +- src/shell.c | 90 +++++++++++++++++---------------------------------- 3 files changed, 37 insertions(+), 67 deletions(-) diff --git a/manifest b/manifest index 7ac383dc3b..f144229d72 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C The\sschema\sname\s"main"\sis\salways\san\sacceptable\salias\sfor\sthe\sprimary\sdatabase\neven\sif\sthe\sprimary\sdatabase\sis\srenamed\susing\sSQLITE_DBCONFIG_MAINDBNAME. -D 2016-12-24T19:37:16.675 +C Combine\sthe\simplementations\sof\sthe\s".tables"\sand\s".indexes"\scommands\sin\sthe\ncommand-line\sshell.\s\sThe\s".indexes"\scommand\snow\sputs\sthe\sindexes\sin\smultiple\ncolumns,\sjust\slike\s".tables"\sand\sshows\sall\sindexes\sin\sall\sattached\sdatabases. +D 2016-12-24T21:32:40.591 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -389,7 +389,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c bb070cf5f23611c44ab7e4788803684e385fc3fb F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c dfb6cadc3dcfba1b1bdbfba62ebba2b4b673413e -F src/shell.c 1594340a8c7b75751b73950f0006643d116d3ef5 +F src/shell.c 48ab675e5526903d2b7bea8c9736cafa345544e1 F src/sqlite.h.in e8e2d108d82647f0a812fdb74accf91c1ec08ddc F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae @@ -1539,7 +1539,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 8558512e9ca343300a767ef23810f2d7b50fd925 -R b30977e76e92562c072b2b96c5549420 +P 2f481b854f04bec546eb172d1b6dbc88067d3fda +R c83fd4223f5b56b5947d45d91cd58312 U drh -Z d1e40bfcd22533ee4ef2e0ad49608c3a +Z f50c0755f44c554bddf33086d9d8e98a diff --git a/manifest.uuid b/manifest.uuid index 8afde31bf9..021315cf1a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2f481b854f04bec546eb172d1b6dbc88067d3fda \ No newline at end of file +def29333655691c7d54451193be13445a2857d29 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 2ad6c8c195..ae833d767a 100644 --- a/src/shell.c +++ b/src/shell.c @@ -4090,52 +4090,6 @@ static int do_meta_command(char *zLine, ShellState *p){ if( needCommit ) sqlite3_exec(p->db, "COMMIT", 0, 0, 0); }else - if( c=='i' && (strncmp(azArg[0], "indices", n)==0 - || strncmp(azArg[0], "indexes", n)==0) ){ - ShellState data; - char *zErrMsg = 0; - open_db(p, 0); - memcpy(&data, p, sizeof(data)); - data.showHeader = 0; - data.cMode = data.mode = MODE_List; - if( nArg==1 ){ - rc = sqlite3_exec(p->db, - "SELECT name FROM sqlite_master " - "WHERE type='index' AND name NOT LIKE 'sqlite_%' " - "UNION ALL " - "SELECT name FROM sqlite_temp_master " - "WHERE type='index' " - "ORDER BY 1", - callback, &data, &zErrMsg - ); - }else if( nArg==2 ){ - zShellStatic = azArg[1]; - rc = sqlite3_exec(p->db, - "SELECT name FROM sqlite_master " - "WHERE type='index' AND tbl_name LIKE shellstatic() " - "UNION ALL " - "SELECT name FROM sqlite_temp_master " - "WHERE type='index' AND tbl_name LIKE shellstatic() " - "ORDER BY 1", - callback, &data, &zErrMsg - ); - zShellStatic = 0; - }else{ - raw_printf(stderr, "Usage: .indexes ?LIKE-PATTERN?\n"); - rc = 1; - goto meta_command_exit; - } - if( zErrMsg ){ - utf8_printf(stderr,"Error: %s\n", zErrMsg); - sqlite3_free(zErrMsg); - rc = 1; - }else if( rc != SQLITE_OK ){ - raw_printf(stderr, - "Error: querying sqlite_master and sqlite_temp_master\n"); - rc = 1; - } - }else - #ifndef SQLITE_UNTESTABLE if( c=='i' && strncmp(azArg[0], "imposter", n)==0 ){ char *zSql; @@ -4959,7 +4913,10 @@ static int do_meta_command(char *zLine, ShellState *p){ } }else - if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 ){ + if( (c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0) + || (c=='i' && (strncmp(azArg[0], "indices", n)==0 + || strncmp(azArg[0], "indexes", n)==0) ) + ){ sqlite3_stmt *pStmt; char **azResult; int nRow, nAlloc; @@ -4972,28 +4929,41 @@ static int do_meta_command(char *zLine, ShellState *p){ /* Create an SQL statement to query for the list of tables in the ** main and all attached databases where the table name matches the ** LIKE pattern bound to variable "?1". */ - zSql = sqlite3_mprintf( - "SELECT name FROM sqlite_master" - " WHERE type IN ('table','view')" - " AND name NOT LIKE 'sqlite_%%'" - " AND name LIKE ?1"); + if( c=='t' ){ + zSql = sqlite3_mprintf( + "SELECT name FROM sqlite_master" + " WHERE type IN ('table','view')" + " AND name NOT LIKE 'sqlite_%%'" + " AND name LIKE ?1"); + }else if( nArg>2 ){ + /* It is an historical accident that the .indexes command shows an error + ** when called with the wrong number of arguments whereas the .tables + ** command does not. */ + raw_printf(stderr, "Usage: .indexes ?LIKE-PATTERN?\n"); + rc = 1; + goto meta_command_exit; + }else{ + zSql = sqlite3_mprintf( + "SELECT name FROM sqlite_master" + " WHERE type='index'" + " AND tbl_name LIKE ?1"); + } for(ii=0; zSql && sqlite3_step(pStmt)==SQLITE_ROW; ii++){ const char *zDbName = (const char*)sqlite3_column_text(pStmt, 1); if( zDbName==0 || ii==0 ) continue; - if( strcmp(zDbName,"temp")==0 ){ - zSql = sqlite3_mprintf( - "%z UNION ALL " - "SELECT 'temp.' || name FROM sqlite_temp_master" - " WHERE type IN ('table','view')" - " AND name NOT LIKE 'sqlite_%%'" - " AND name LIKE ?1", zSql); - }else{ + if( c=='t' ){ zSql = sqlite3_mprintf( "%z UNION ALL " "SELECT '%q.' || name FROM \"%w\".sqlite_master" " WHERE type IN ('table','view')" " AND name NOT LIKE 'sqlite_%%'" " AND name LIKE ?1", zSql, zDbName, zDbName); + }else{ + zSql = sqlite3_mprintf( + "%z UNION ALL " + "SELECT '%q.' || name FROM \"%w\".sqlite_master" + " WHERE type='index'" + " AND tbl_name LIKE ?1", zSql, zDbName, zDbName); } } rc = sqlite3_finalize(pStmt); From beaf514e2300cfdaa2d606fc9f3b9cbe89afaefc Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 26 Dec 2016 00:15:56 +0000 Subject: [PATCH 1116/1484] Enhance the fuzztest utility with the --prng-seed option. Always reseed the PRNG prior to each test. FossilOrigin-Name: 8c5187f69d719b69aa6eaf2dc8f89243e5979222 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/fuzzcheck.c | 31 ++++++++++++++++++++++++------- 3 files changed, 31 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index f144229d72..2e7abd7f9e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Combine\sthe\simplementations\sof\sthe\s".tables"\sand\s".indexes"\scommands\sin\sthe\ncommand-line\sshell.\s\sThe\s".indexes"\scommand\snow\sputs\sthe\sindexes\sin\smultiple\ncolumns,\sjust\slike\s".tables"\sand\sshows\sall\sindexes\sin\sall\sattached\sdatabases. -D 2016-12-24T21:32:40.591 +C Enhance\sthe\sfuzztest\sutility\swith\sthe\s--prng-seed\soption.\s\sAlways\sreseed\sthe\nPRNG\sprior\sto\seach\stest. +D 2016-12-26T00:15:56.766 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -816,7 +816,7 @@ F test/fuzz2.test 76dc35b32b6d6f965259508508abce75a6c4d7e1 F test/fuzz3.test b47377143f0c80f91ed29d722861077ff34415d5 F test/fuzz_common.tcl a87dfbb88c2a6b08a38e9a070dabd129e617b45b F test/fuzz_malloc.test 328f70aaca63adf29b4c6f06505ed0cf57ca7c26 -F test/fuzzcheck.c 5592b19e07b9061833a35eaf78869ad0c8b6cf33 +F test/fuzzcheck.c b5a3e54b100e65b008452a2d29193c7132af0b05 F test/fuzzdata1.db 7ee3227bad0e7ccdeb08a9e6822916777073c664 F test/fuzzdata2.db f03a420d3b822cc82e4f894ca957618fbe9c4973 F test/fuzzdata3.db c6586d3e3cef0fbc18108f9bb649aa77bfc38aba @@ -1539,7 +1539,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 2f481b854f04bec546eb172d1b6dbc88067d3fda -R c83fd4223f5b56b5947d45d91cd58312 +P def29333655691c7d54451193be13445a2857d29 +R e04e5338dd0157c18f4661e2b40e485c U drh -Z f50c0755f44c554bddf33086d9d8e98a +Z 34d4889fdc22385ba735ec50d68d537d diff --git a/manifest.uuid b/manifest.uuid index 021315cf1a..ab702bb52d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -def29333655691c7d54451193be13445a2857d29 \ No newline at end of file +8c5187f69d719b69aa6eaf2dc8f89243e5979222 \ No newline at end of file diff --git a/test/fuzzcheck.c b/test/fuzzcheck.c index ccc4df8d37..90765ffc8d 100644 --- a/test/fuzzcheck.c +++ b/test/fuzzcheck.c @@ -133,6 +133,7 @@ static struct GlobalVars { Blob *pFirstDb; /* Content of first template database */ int nSql; /* Number of SQL scripts */ Blob *pFirstSql; /* First SQL script */ + unsigned int uRandom; /* Seed for the SQLite PRNG */ char zTestName[100]; /* Name of current test */ } g; @@ -595,10 +596,18 @@ static int inmemFullPathname( return SQLITE_OK; } +/* Always use the same random see, for repeatability. +*/ +static int inmemRandomness(sqlite3_vfs *NotUsed, int nBuf, char *zBuf){ + memset(zBuf, 0, nBuf); + memcpy(zBuf, &g.uRandom, nBufxRandomness; + inmemVfs.xRandomness = inmemRandomness; inmemVfs.xSleep = pDefault->xSleep; inmemVfs.xCurrentTimeInt64 = pDefault->xCurrentTimeInt64; - sqlite3_vfs_register(&inmemVfs, 0); + sqlite3_vfs_register(&inmemVfs, makeDefault); }; /* @@ -800,6 +809,7 @@ static void showHelp(void){ " -m TEXT Add a description to the database\n" " --native-vfs Use the native VFS for initially empty database files\n" " --oss-fuzz Enable OSS-FUZZ testing\n" +" --prng-seed N Seed value for the PRGN inside of SQLite\n" " --rebuild Rebuild and vacuum the database file\n" " --result-trace Show the results of each SQL command\n" " --sqlid N Use only SQL where sqlid=N\n" @@ -844,6 +854,7 @@ int main(int argc, char **argv){ void *pHeap = 0; /* Heap for use by SQLite */ int ossFuzz = 0; /* enable OSS-FUZZ testing */ int ossFuzzThisDb = 0; /* ossFuzz value for this particular database */ + sqlite3_vfs *pDfltVfs; /* The default VFS */ iBegin = timeOfDay(); #ifdef __unix__ @@ -851,6 +862,8 @@ int main(int argc, char **argv){ #endif g.zArgv0 = argv[0]; zFailCode = getenv("TEST_FAILURE"); + pDfltVfs = sqlite3_vfs_find(0); + inmemVfsRegister(1); for(i=1; i=argc-1 ) fatalError("missing arguments on %s", argv[i]); + g.uRandom = atoi(argv[++i]); + }else if( strcmp(z,"quiet")==0 || strcmp(z,"q")==0 ){ quietFlag = 1; verboseFlag = 0; @@ -957,7 +974,8 @@ int main(int argc, char **argv){ /* Process each source database separately */ for(iSrcDb=0; iSrcDbzName); if( rc ){ fatalError("cannot open source database %s - %s", azSrcDb[iSrcDb], sqlite3_errmsg(db)); @@ -1135,10 +1153,8 @@ int main(int argc, char **argv){ sqlite3_config(SQLITE_CONFIG_HEAP, pHeap, nMemThisDb, 128); } - /* Register the in-memory virtual filesystem - */ + /* Reset the in-memory virtual filesystem */ formatVfs(); - inmemVfsRegister(); /* Run a test using each SQL script against each database. */ @@ -1163,6 +1179,7 @@ int main(int argc, char **argv){ } } createVFile("main.db", pDb->sz, pDb->a); + sqlite3_randomness(0,0); if( ossFuzzThisDb ){ #ifndef SQLITE_OSS_FUZZ fatalError("--oss-fuzz not supported: recompile with -DSQLITE_OSS_FUZZ"); From a1a523a5bb3628a833065d43d8035cfa8249fc16 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 26 Dec 2016 00:18:36 +0000 Subject: [PATCH 1117/1484] Add the built-in affinity() SQL function. FossilOrigin-Name: 57e40e1cb1bcd3dd8473d2fdeecc9c7ff3d6192b --- manifest | 19 +++++++++++-------- manifest.uuid | 2 +- src/expr.c | 14 ++++++++++++++ src/func.c | 1 + src/sqliteInt.h | 1 + 5 files changed, 28 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 2e7abd7f9e..7d07fb38d6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\sthe\sfuzztest\sutility\swith\sthe\s--prng-seed\soption.\s\sAlways\sreseed\sthe\nPRNG\sprior\sto\seach\stest. -D 2016-12-26T00:15:56.766 +C Add\sthe\sbuilt-in\saffinity()\sSQL\sfunction. +D 2016-12-26T00:18:36.252 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -341,10 +341,10 @@ F src/ctime.c 9f2296a4e5d26ebf0e0d95a0af4628f1ea694e7a F src/date.c b48378aeac68fa20c811404955a9b62108df47d8 F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c c8bc10d145c9666a34ae906250326fdaa8d58fa5 -F src/expr.c a90e37bc542abe33890cafccacbf8a7db9cb5401 +F src/expr.c dfde7bf6d3293c34b975aef24a7b9e4f6dbe89da F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 2e9aabe1aee76273aff8a84ee92c464e095400ae -F src/func.c 43916c1d8e6da5d107d91d2b212577d4f69a876a +F src/func.c 18193418066b4a46df0678167a61e2ecb532449e F src/global.c dcdb89f30b7aa531c5660030af106bc5bc48ef2e F src/hash.c 63d0ee752a3b92d4695b2b1f5259c4621b2cfebd F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4 @@ -393,7 +393,7 @@ F src/shell.c 48ab675e5526903d2b7bea8c9736cafa345544e1 F src/sqlite.h.in e8e2d108d82647f0a812fdb74accf91c1ec08ddc F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae -F src/sqliteInt.h 2075e22d50833ca2d9956d0b7a6bfb845ad05dd2 +F src/sqliteInt.h 5a4ac95a34d9d323b2276ae1ed2b3eaafce6c97e F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 @@ -1539,7 +1539,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P def29333655691c7d54451193be13445a2857d29 -R e04e5338dd0157c18f4661e2b40e485c +P 8c5187f69d719b69aa6eaf2dc8f89243e5979222 +R b3d06bee0b628897cfc6aea60fc78deb +T *branch * affinity-sql-func +T *sym-affinity-sql-func * +T -sym-trunk * U drh -Z 34d4889fdc22385ba735ec50d68d537d +Z 89d8ee615380053a8bde91353136b95e diff --git a/manifest.uuid b/manifest.uuid index ab702bb52d..aa72dce7c8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8c5187f69d719b69aa6eaf2dc8f89243e5979222 \ No newline at end of file +57e40e1cb1bcd3dd8473d2fdeecc9c7ff3d6192b \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index ecc6c7928b..883273b3bc 100644 --- a/src/expr.c +++ b/src/expr.c @@ -3621,6 +3621,20 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ return sqlite3ExprCodeTarget(pParse, pFarg->a[0].pExpr, target); } + /* The AFFINITY() function evaluates to a string that describes + ** the type affinity of the argument. This is used for testing of + ** the SQLite type logic. + */ + if( pDef->funcFlags & SQLITE_FUNC_AFFINITY ){ + const char *azAff[] = { "blob", "text", "numeric", "integer", "real" }; + char aff; + assert( nFarg==1 ); + aff = sqlite3ExprAffinity(pFarg->a[0].pExpr); + sqlite3VdbeLoadString(v, target, + aff ? azAff[aff-SQLITE_AFF_BLOB] : "none"); + return target; + } + for(i=0; ia[i].pExpr) ){ testcase( i==31 ); diff --git a/src/func.c b/src/func.c index 5b8ed6dd2b..ec50d97af0 100644 --- a/src/func.c +++ b/src/func.c @@ -1772,6 +1772,7 @@ void sqlite3RegisterBuiltinFunctions(void){ FUNCTION2(unlikely, 1, 0, 0, noopFunc, SQLITE_FUNC_UNLIKELY), FUNCTION2(likelihood, 2, 0, 0, noopFunc, SQLITE_FUNC_UNLIKELY), FUNCTION2(likely, 1, 0, 0, noopFunc, SQLITE_FUNC_UNLIKELY), + FUNCTION2(affinity, 1, 0, 0, noopFunc, SQLITE_FUNC_AFFINITY), FUNCTION(ltrim, 1, 1, 0, trimFunc ), FUNCTION(ltrim, 2, 1, 0, trimFunc ), FUNCTION(rtrim, 1, 2, 0, trimFunc ), diff --git a/src/sqliteInt.h b/src/sqliteInt.h index d78d2072de..c4aaf39244 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1561,6 +1561,7 @@ struct FuncDestructor { #define SQLITE_FUNC_MINMAX 0x1000 /* True for min() and max() aggregates */ #define SQLITE_FUNC_SLOCHNG 0x2000 /* "Slow Change". Value constant during a ** single query - might change over time */ +#define SQLITE_FUNC_AFFINITY 0x4000 /* Built-in affinity() function */ /* ** The following three macros, FUNCTION(), LIKEFUNC() and AGGREGATE() are From 9cc5b4eeb5deb3c3348e6e51e205d79a50334748 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 26 Dec 2016 01:41:33 +0000 Subject: [PATCH 1118/1484] Remove an incorrect ALWAYS() macro from balance_nonroot(), which could result in corrupt databases if it were optimized out. This ALWAYS was added only two weeks ago (check-in [f9f2e23bbd68a]) and has never appeared in an official release. FossilOrigin-Name: e447b23cfd7bb31817e42adb3a98868d351c6b8a --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btree.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 2e7abd7f9e..c16355bf4f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\sthe\sfuzztest\sutility\swith\sthe\s--prng-seed\soption.\s\sAlways\sreseed\sthe\nPRNG\sprior\sto\seach\stest. -D 2016-12-26T00:15:56.766 +C Remove\san\sincorrect\sALWAYS()\smacro\sfrom\sbalance_nonroot(),\swhich\scould\sresult\nin\scorrupt\sdatabases\sif\sit\swere\soptimized\sout.\s\sThis\sALWAYS\swas\sadded\s\nonly\stwo\sweeks\sago\s(check-in\s[f9f2e23bbd68a])\sand\shas\snever\sappeared\sin\san\nofficial\srelease. +D 2016-12-26T01:41:33.072 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -331,7 +331,7 @@ F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792 F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 -F src/btree.c 2e07a5a6d705c1439392460f4044ea4179d9cd40 +F src/btree.c d2c100618784bd89c089fcef03ff6e789768ecae F src/btree.h 2349a588abcd7e0c04f984e15c5c777b61637583 F src/btreeInt.h 10c4b77c2fb399580babbcc7cf652ac10dba796e F src/build.c 9e799f1edd910dfa8a0bc29bd390d35d310596af @@ -1539,7 +1539,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P def29333655691c7d54451193be13445a2857d29 -R e04e5338dd0157c18f4661e2b40e485c +P 8c5187f69d719b69aa6eaf2dc8f89243e5979222 +R 8f159ac0828ffa15fefdcbf0386259c4 U drh -Z 34d4889fdc22385ba735ec50d68d537d +Z 7c774566c7c911446145658eecf4799d diff --git a/manifest.uuid b/manifest.uuid index ab702bb52d..7a7a6d9726 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8c5187f69d719b69aa6eaf2dc8f89243e5979222 \ No newline at end of file +e447b23cfd7bb31817e42adb3a98868d351c6b8a \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index d2fd448f68..f869761625 100644 --- a/src/btree.c +++ b/src/btree.c @@ -7077,7 +7077,7 @@ static int balance_nonroot( nMaxCells += 1+apOld[i]->nCell+apOld[i]->nOverflow; if( (i--)==0 ) break; - if( pParent->nOverflow && ALWAYS(i+nxDiv==pParent->aiOvfl[0]) ){ + if( pParent->nOverflow && i+nxDiv==pParent->aiOvfl[0] ){ apDiv[i] = pParent->apOvfl[0]; pgno = get4byte(apDiv[i]); szNew[i] = pParent->xCellSize(pParent, apDiv[i]); From e6ce2b670480a72aa869dafaf252297577b732d9 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 26 Dec 2016 12:14:44 +0000 Subject: [PATCH 1119/1484] Enable ossfuzz.c to build even if SQLITE_OMIT_PROGRESS_CALLBACK is defined. FossilOrigin-Name: a37c00dcd192f9d610ecb91810ef57ef41d1f6a6 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/ossfuzz.c | 4 ++++ 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index c16355bf4f..95c91f8c54 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\san\sincorrect\sALWAYS()\smacro\sfrom\sbalance_nonroot(),\swhich\scould\sresult\nin\scorrupt\sdatabases\sif\sit\swere\soptimized\sout.\s\sThis\sALWAYS\swas\sadded\s\nonly\stwo\sweeks\sago\s(check-in\s[f9f2e23bbd68a])\sand\shas\snever\sappeared\sin\san\nofficial\srelease. -D 2016-12-26T01:41:33.072 +C Enable\sossfuzz.c\sto\sbuild\seven\sif\sSQLITE_OMIT_PROGRESS_CALLBACK\sis\sdefined. +D 2016-12-26T12:14:44.677 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -988,7 +988,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 ad79e867fb504338d324b08e0696db65a0c44d68 +F test/ossfuzz.c e469138f4be3e92df6173b79b3b216ab6e17b407 F test/ossshell.c d9f1a6f43e7bab45d6be857a5800f5d4a1861db3 F test/ovfl.test 199c482696defceacee8c8e0e0ef36da62726b2f F test/pager1.test 841868017e9dd3cb459b8d78862091a7d9cff21d @@ -1539,7 +1539,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 8c5187f69d719b69aa6eaf2dc8f89243e5979222 -R 8f159ac0828ffa15fefdcbf0386259c4 +P e447b23cfd7bb31817e42adb3a98868d351c6b8a +R 8841b84029dbf760ce265e8a468ac866 U drh -Z 7c774566c7c911446145658eecf4799d +Z 2b73fc063411ed2f663f21e959442a2c diff --git a/manifest.uuid b/manifest.uuid index 7a7a6d9726..f119d0b647 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e447b23cfd7bb31817e42adb3a98868d351c6b8a \ No newline at end of file +a37c00dcd192f9d610ecb91810ef57ef41d1f6a6 \ No newline at end of file diff --git a/test/ossfuzz.c b/test/ossfuzz.c index 4bf0eb5e41..3a3e852c34 100644 --- a/test/ossfuzz.c +++ b/test/ossfuzz.c @@ -6,12 +6,14 @@ #include #include "sqlite3.h" +#ifndef SQLITE_OMIT_PROGRESS_CALLBACK /* ** Progress handler callback */ static int progress_handler(void *pReturn) { return *(int*)pReturn; } +#endif /* ** Callback for sqlite3_exec(). @@ -53,11 +55,13 @@ int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_MEMORY, 0); if( rc ) return 0; +#ifndef SQLITE_OMIT_PROGRESS_CALLBACK /* Bit 0 of the selector enables progress callbacks. Bit 1 is the ** return code from progress callbacks */ if( uSelector & 1 ){ sqlite3_progress_handler(db, 4, progress_handler, (void*)&progressArg); } +#endif uSelector >>= 1; progressArg = uSelector & 1; uSelector >>= 1; From dfcfff646a7ecd52dcdfebb65743762840b9b6d2 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 26 Dec 2016 12:25:19 +0000 Subject: [PATCH 1120/1484] During fuzz testing with the fuzzcheck utility program, impose a record length limit of 100MB and a limit on the length of LIKE strings of 50 bytes. FossilOrigin-Name: edc9db41f3ee200ba44579a46ed8331bbbbf539e --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/fuzzcheck.c | 2 ++ 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 95c91f8c54..2bd0f4f1da 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enable\sossfuzz.c\sto\sbuild\seven\sif\sSQLITE_OMIT_PROGRESS_CALLBACK\sis\sdefined. -D 2016-12-26T12:14:44.677 +C During\sfuzz\stesting\swith\sthe\sfuzzcheck\sutility\sprogram,\simpose\sa\srecord\nlength\slimit\sof\s100MB\sand\sa\slimit\son\sthe\slength\sof\sLIKE\sstrings\sof\s50\sbytes. +D 2016-12-26T12:25:19.250 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -816,7 +816,7 @@ F test/fuzz2.test 76dc35b32b6d6f965259508508abce75a6c4d7e1 F test/fuzz3.test b47377143f0c80f91ed29d722861077ff34415d5 F test/fuzz_common.tcl a87dfbb88c2a6b08a38e9a070dabd129e617b45b F test/fuzz_malloc.test 328f70aaca63adf29b4c6f06505ed0cf57ca7c26 -F test/fuzzcheck.c b5a3e54b100e65b008452a2d29193c7132af0b05 +F test/fuzzcheck.c 9c29eae3536beaf1a816e81d106208c304e50b0a F test/fuzzdata1.db 7ee3227bad0e7ccdeb08a9e6822916777073c664 F test/fuzzdata2.db f03a420d3b822cc82e4f894ca957618fbe9c4973 F test/fuzzdata3.db c6586d3e3cef0fbc18108f9bb649aa77bfc38aba @@ -1539,7 +1539,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e447b23cfd7bb31817e42adb3a98868d351c6b8a -R 8841b84029dbf760ce265e8a468ac866 +P a37c00dcd192f9d610ecb91810ef57ef41d1f6a6 +R 96ba27febbb334158a799b41f6781b59 U drh -Z 2b73fc063411ed2f663f21e959442a2c +Z 01474197bef46a6f383dfbedbe3b38a0 diff --git a/manifest.uuid b/manifest.uuid index f119d0b647..0d9073032e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a37c00dcd192f9d610ecb91810ef57ef41d1f6a6 \ No newline at end of file +edc9db41f3ee200ba44579a46ed8331bbbbf539e \ No newline at end of file diff --git a/test/fuzzcheck.c b/test/fuzzcheck.c index 90765ffc8d..2182f03d09 100644 --- a/test/fuzzcheck.c +++ b/test/fuzzcheck.c @@ -1195,6 +1195,8 @@ int main(int argc, char **argv){ } rc = sqlite3_open_v2("main.db", &db, openFlags, zVfs); if( rc ) fatalError("cannot open inmem database"); + sqlite3_limit(db, SQLITE_LIMIT_LENGTH, 100000000); + sqlite3_limit(db, SQLITE_LIMIT_LIKE_PATTERN_LENGTH, 50); if( cellSzCkFlag ) runSql(db, "PRAGMA cell_size_check=ON", runFlags); setAlarm(iTimeout); #ifndef SQLITE_OMIT_PROGRESS_CALLBACK From c595419910ece09e9d8af38bbc351531e63a193c Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 27 Dec 2016 02:43:47 +0000 Subject: [PATCH 1121/1484] Minor changes to make some newer test cases work under more compile-time options. FossilOrigin-Name: 382eea36c56f866efee1321f643687a4061e8b9e --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- test/nockpt.test | 1 + test/shell1.test | 2 ++ test/shell6.test | 3 +-- 5 files changed, 13 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 2bd0f4f1da..a1a4c4b69e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C During\sfuzz\stesting\swith\sthe\sfuzzcheck\sutility\sprogram,\simpose\sa\srecord\nlength\slimit\sof\s100MB\sand\sa\slimit\son\sthe\slength\sof\sLIKE\sstrings\sof\s50\sbytes. -D 2016-12-26T12:25:19.250 +C Minor\schanges\sto\smake\ssome\snewer\stest\scases\swork\sunder\smore\scompile-time\noptions. +D 2016-12-27T02:43:47.038 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -967,7 +967,7 @@ F test/multiplex4.test e8ae4c4bd70606a5727743241f13b5701990abe4 F test/mutex1.test ea2cc74d97f077b9e74c84cbd024f14d79a8126f F test/mutex2.test bfeaeac2e73095b2ac32285d2756e3a65e681660 F test/nan.test dacc57f80859c06a433d30839336fe227d2038b3 -F test/nockpt.test c65fc1c921d48805dcfca2dca5d1302839a5a1de +F test/nockpt.test 1e5c87614d200585b4395286946cca5fc0930e3f F test/nolock.test f196cf8b8fbea4e2ca345140a2b3f3b0da45c76e F test/notify1.test 669b2b743618efdc18ca4b02f45423d5d2304abf F test/notify2.test 2ecabaa1305083856b7c39cf32816b612740c161 @@ -1090,12 +1090,12 @@ F test/sharedA.test 0cdf1a76dfa00e6beee66af5b534b1e8df2720f5 F test/sharedB.test 16cc7178e20965d75278f410943109b77b2e645e F test/shared_err.test 2f2aee20db294b9924e81f6ccbe60f19e21e8506 F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304 -F test/shell1.test 8ff47a4821570b99cc340c4da0ac4efe2ba06627 +F test/shell1.test 52ac23a345772ab0d6d3241a21a633fdaa3ed581 F test/shell2.test e242a9912f44f4c23c3d1d802a83e934e84c853b F test/shell3.test 9b95ba643eaa228376f06a898fb410ee9b6e57c1 F test/shell4.test 89ad573879a745974ff2df20ff97c5d6ffffbd5d F test/shell5.test 50a732c1c2158b1cd62cf53975ce1ea7ce6b9dc9 -F test/shell6.test 87b47bf2f5c47a4e44f07dd119ea88ae303a8247 +F test/shell6.test cff624fadf71bdb5e3a9b0f86eaf59a43c0622b1 F test/shell7.test 07751911b294698e0c5df67bcbd29e7d2f0f2907 F test/shortread1.test bb591ef20f0fd9ed26d0d12e80eee6d7ac8897a3 F test/show_speedtest1_rtree.tcl 32e6c5f073d7426148a6936a0408f4b5b169aba5 @@ -1539,7 +1539,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a37c00dcd192f9d610ecb91810ef57ef41d1f6a6 -R 96ba27febbb334158a799b41f6781b59 +P edc9db41f3ee200ba44579a46ed8331bbbbf539e +R 96afac5b20dcc0117476250a7301f42d U drh -Z 01474197bef46a6f383dfbedbe3b38a0 +Z 51bc03a9fcd5bae5965694035444d10d diff --git a/manifest.uuid b/manifest.uuid index 0d9073032e..9b729c87bb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -edc9db41f3ee200ba44579a46ed8331bbbbf539e \ No newline at end of file +382eea36c56f866efee1321f643687a4061e8b9e \ No newline at end of file diff --git a/test/nockpt.test b/test/nockpt.test index cf350c3e1b..6ac434ed56 100644 --- a/test/nockpt.test +++ b/test/nockpt.test @@ -23,6 +23,7 @@ ifcapable !wal {finish_test ; return } set testprefix nockpt do_execsql_test 1.0 { + PRAGMA auto_vacuum=OFF; PRAGMA page_size = 1024; PRAGMA journal_mode = wal; CREATE TABLE c1(x, y, z); diff --git a/test/shell1.test b/test/shell1.test index 9400d75296..95c3130bdd 100644 --- a/test/shell1.test +++ b/test/shell1.test @@ -273,6 +273,7 @@ do_test shell1-3.2.4 { catchcmd "test.db" ".bail OFF BAD" } {1 {Usage: .bail on|off}} +ifcapable vtab { # .databases List names and files of attached databases do_test shell1-3.3.1 { catchcmd "-csv test.db" ".databases" @@ -281,6 +282,7 @@ do_test shell1-3.3.2 { # extra arguments ignored catchcmd "test.db" ".databases BAD" } "/0.+main.+[string map {/ ".{1,2}"} [string range [get_pwd] 0 10]].*/" +} # .dump ?TABLE? ... Dump the database in an SQL text format # If TABLE specified, only dump tables matching diff --git a/test/shell6.test b/test/shell6.test index 028ac5efe9..a70c4b4298 100644 --- a/test/shell6.test +++ b/test/shell6.test @@ -14,6 +14,7 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl +ifcapable !vtab {finish_test; return} set testprefix shell6 set CLI [test_find_cli] db close @@ -98,5 +99,3 @@ foreach {tn schema output} { } finish_test - - From 1aa346950e20a56474db7aac014e6e4e69051b11 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 27 Dec 2016 12:08:36 +0000 Subject: [PATCH 1122/1484] Avoid a potential (harmless) signed integer overflow in memory usage accounting when calling sqlite3_realloc() to reduce the size of an allocation. FossilOrigin-Name: 2d71cbdf6bc24f0269027c70b39ea7f342436bdb --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/malloc.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index a1a4c4b69e..5efd5be104 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Minor\schanges\sto\smake\ssome\snewer\stest\scases\swork\sunder\smore\scompile-time\noptions. -D 2016-12-27T02:43:47.038 +C Avoid\sa\spotential\s(harmless)\ssigned\sinteger\soverflow\sin\smemory\susage\naccounting\swhen\scalling\ssqlite3_realloc()\sto\sreduce\sthe\ssize\sof\san\nallocation. +D 2016-12-27T12:08:36.304 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -354,7 +354,7 @@ F src/insert.c 91ba5d0143e66479081536ebbaff1850ec9f57d9 F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e F src/loadext.c 5d6642d141c07d366e43d359e94ec9de47add41d F src/main.c ec789a410860bcdc5d8f7a82090043f482482aec -F src/malloc.c 5ee7c2d3dcb1b0a902c9c6d0115deef54736bdfa +F src/malloc.c f3fad34cd570022abca558c573f1761fb09a8212 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3 @@ -1539,7 +1539,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P edc9db41f3ee200ba44579a46ed8331bbbbf539e -R 96afac5b20dcc0117476250a7301f42d +P 382eea36c56f866efee1321f643687a4061e8b9e +R 93ac45881220ef048be2df84ae58f915 U drh -Z 51bc03a9fcd5bae5965694035444d10d +Z 198951405d8d4aa948aae7ef07798be3 diff --git a/manifest.uuid b/manifest.uuid index 9b729c87bb..28b15c57b0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -382eea36c56f866efee1321f643687a4061e8b9e \ No newline at end of file +2d71cbdf6bc24f0269027c70b39ea7f342436bdb \ No newline at end of file diff --git a/src/malloc.c b/src/malloc.c index 4ec1bca57c..84191c78a1 100644 --- a/src/malloc.c +++ b/src/malloc.c @@ -519,7 +519,7 @@ void *sqlite3Realloc(void *pOld, u64 nBytes){ sqlite3_mutex_enter(mem0.mutex); sqlite3StatusHighwater(SQLITE_STATUS_MALLOC_SIZE, (int)nBytes); nDiff = nNew - nOld; - if( sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED) >= + if( nDiff>0 && sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED) >= mem0.alarmThreshold-nDiff ){ sqlite3MallocAlarm(nDiff); } From 218c66e0e3e3341d607b3f5abb82d402e59f11a1 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 27 Dec 2016 12:35:36 +0000 Subject: [PATCH 1123/1484] Disable new test modules nockpt.test and interrupt2.test for incompatible permutations. Add a CORRUPT_DB term to an assert() in vdbe.c. FossilOrigin-Name: a54e619e6f0266932c8873f9ac826fd042a0602f --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/vdbe.c | 3 ++- test/interrupt2.test | 5 +++++ test/nockpt.test | 1 + 5 files changed, 17 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 5efd5be104..ad20453554 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sa\spotential\s(harmless)\ssigned\sinteger\soverflow\sin\smemory\susage\naccounting\swhen\scalling\ssqlite3_realloc()\sto\sreduce\sthe\ssize\sof\san\nallocation. -D 2016-12-27T12:08:36.304 +C Disable\snew\stest\smodules\snockpt.test\sand\sinterrupt2.test\sfor\sincompatible\npermutations.\s\sAdd\sa\sCORRUPT_DB\sterm\sto\san\sassert()\sin\svdbe.c. +D 2016-12-27T12:35:36.977 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -455,7 +455,7 @@ F src/update.c 1da7c462110bffed442a42884cb0d528c1db46d8 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 1534060bc034cdc51381c040c8bd6252dbcb64c9 F src/vacuum.c 33c174b28886b2faf26e503b5a49a1c01a9b1c16 -F src/vdbe.c 73ded9a61658c82cf726cb7feb070836cb4f8a87 +F src/vdbe.c a35ad51713d9be42f97e80f24cd4be5d20886a0c F src/vdbe.h 50ee139f9c68fff91be1d717ed3a6abbd496919c F src/vdbeInt.h 281cb70332dc8b593b8c7afe776f3a2ba7d4255e F src/vdbeapi.c d6ebaa465f070eb1af8ba4e7b34583ece87bdd24 @@ -869,7 +869,7 @@ F test/instr.test 737bbf80685232033f3abedc6ae92f75860b5dd2 F test/instrfault.test aa90b7c3486a069151b28384ae525644a1f79d51 F test/intarray.test 46d95b457916638c5d8b1af21fb174804b3acf8b F test/interrupt.test 16ea879ec728cb76414c148c5f24afd5d1f91054 -F test/interrupt2.test 829b06f9e20a6c378d8bd121b26c337f4dfa36e5 +F test/interrupt2.test e4408ca770a6feafbadb0801e54a0dcd1a8d108d F test/intpkey.test ac71107a49a06492b69b82aafaf225400598d3c8 F test/io.test f95bca1783b01ea7761671560d023360d2dfa4cc F test/ioerr.test 2a24bd6ed5a8b062e64bfe1f6cf94fb25e92210d @@ -967,7 +967,7 @@ F test/multiplex4.test e8ae4c4bd70606a5727743241f13b5701990abe4 F test/mutex1.test ea2cc74d97f077b9e74c84cbd024f14d79a8126f F test/mutex2.test bfeaeac2e73095b2ac32285d2756e3a65e681660 F test/nan.test dacc57f80859c06a433d30839336fe227d2038b3 -F test/nockpt.test 1e5c87614d200585b4395286946cca5fc0930e3f +F test/nockpt.test 9f56a64b20fc78d278fa350a2271c1569d59cd7e F test/nolock.test f196cf8b8fbea4e2ca345140a2b3f3b0da45c76e F test/notify1.test 669b2b743618efdc18ca4b02f45423d5d2304abf F test/notify2.test 2ecabaa1305083856b7c39cf32816b612740c161 @@ -1539,7 +1539,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 382eea36c56f866efee1321f643687a4061e8b9e -R 93ac45881220ef048be2df84ae58f915 +P 2d71cbdf6bc24f0269027c70b39ea7f342436bdb +R 489b2a3e1a6fc86f485ef85f303a7517 U drh -Z 198951405d8d4aa948aae7ef07798be3 +Z 1382d3dd489de9084fb45c97add8c7aa diff --git a/manifest.uuid b/manifest.uuid index 28b15c57b0..28eb1d9dff 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2d71cbdf6bc24f0269027c70b39ea7f342436bdb \ No newline at end of file +a54e619e6f0266932c8873f9ac826fd042a0602f \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index ec722691f1..152a37447a 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -3783,7 +3783,8 @@ case OP_SeekGT: { /* jump, in3 */ if( pC->isTable ){ /* The BTREE_SEEK_EQ flag is only set on index cursors */ - assert( sqlite3BtreeCursorHasHint(pC->uc.pCursor, BTREE_SEEK_EQ)==0 ); + assert( sqlite3BtreeCursorHasHint(pC->uc.pCursor, BTREE_SEEK_EQ)==0 + || CORRUPT_DB ); /* The input value in P3 might be of any type: integer, real, string, ** blob, or NULL. But it needs to be an integer before we can do diff --git a/test/interrupt2.test b/test/interrupt2.test index 59ad7b3893..b9c66bd1f4 100644 --- a/test/interrupt2.test +++ b/test/interrupt2.test @@ -18,6 +18,11 @@ source $testdir/tester.tcl source $testdir/wal_common.tcl set testprefix interrupt2 +if {[permutation]=="journaltest" || [permutation]=="inmemory_journal"} { + finish_test + return +} + db close testvfs tvfs -default 1 diff --git a/test/nockpt.test b/test/nockpt.test index 6ac434ed56..60d687d99f 100644 --- a/test/nockpt.test +++ b/test/nockpt.test @@ -19,6 +19,7 @@ source $testdir/lock_common.tcl source $testdir/malloc_common.tcl source $testdir/wal_common.tcl ifcapable !wal {finish_test ; return } +if {[permutation]=="journaltest"} {finish_test; return} set testprefix nockpt From 5ad74a761db60d985ee36b5f926f9aa2a056a0aa Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 27 Dec 2016 12:45:41 +0000 Subject: [PATCH 1124/1484] Adjust a corruption test case to accommodate the sqlite3BtreeInsert() optimization of check-in [0b86fbca66]. FossilOrigin-Name: 4cb0945f13f2040c8b67936b950da48fc951d55d --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/corruptC.test | 11 +++++++++-- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index ad20453554..60d41d8a95 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Disable\snew\stest\smodules\snockpt.test\sand\sinterrupt2.test\sfor\sincompatible\npermutations.\s\sAdd\sa\sCORRUPT_DB\sterm\sto\san\sassert()\sin\svdbe.c. -D 2016-12-27T12:35:36.977 +C Adjust\sa\scorruption\stest\scase\sto\saccommodate\sthe\ssqlite3BtreeInsert()\noptimization\sof\scheck-in\s[0b86fbca66]. +D 2016-12-27T12:45:41.649 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -600,7 +600,7 @@ F test/corrupt8.test 2399dfe40d2c0c63af86706e30f3e6302a8d0516 F test/corrupt9.test 730a3db08d4ab9aa43392ea30d9c2b4879cbff85 F test/corruptA.test 53e56dafd180addcdadb402244b8cb9771d2ba26 F test/corruptB.test 73a8d6c0b9833697ecf16b63e3c5c05c945b5dec -F test/corruptC.test 0c46574f8d4f27ecc799b1b5c4cbf9b1817bce9a +F test/corruptC.test 4ef10844eba5213bd262f4d96784d7fcda114afe F test/corruptD.test b3c205fac7952b1de645ce44bb02335cd9e3e040 F test/corruptE.test 82ccf4f8f543fdbedd4aa42c709cb077f7374c62 F test/corruptF.test be9fde98e4c93648f1ba52b74e5318edc8f59fe4 @@ -1539,7 +1539,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 2d71cbdf6bc24f0269027c70b39ea7f342436bdb -R 489b2a3e1a6fc86f485ef85f303a7517 +P a54e619e6f0266932c8873f9ac826fd042a0602f +R eb35cd952180d5ebb2679925e01b66f1 U drh -Z 1382d3dd489de9084fb45c97add8c7aa +Z a0a0f1b4d334e304a9f18235642eec10 diff --git a/manifest.uuid b/manifest.uuid index 28eb1d9dff..e7e11f6c8e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a54e619e6f0266932c8873f9ac826fd042a0602f \ No newline at end of file +4cb0945f13f2040c8b67936b950da48fc951d55d \ No newline at end of file diff --git a/test/corruptC.test b/test/corruptC.test index 80c3c09f61..e2fb1f33c4 100644 --- a/test/corruptC.test +++ b/test/corruptC.test @@ -100,6 +100,12 @@ do_test corruptC-2.1 { } {1 {database disk image is malformed}} # test that a corrupt content offset size is handled (seed 5649) +# +# Update 2016-12-27: As of check-in [0b86fbca66] "In sqlite3BtreeInsert() when +# replacing a re-existing row, try to overwrite the cell directly rather than +# deallocate and reallocate the cell" on 2016-12-09, this test case no longer +# detects the offset size problem during the UPDATE. We have to run a subsequent +# integrity_check to see it. do_test corruptC-2.2 { db close forcecopy test.bu test.db @@ -117,8 +123,9 @@ do_test corruptC-2.2 { hexio_write test.db 3746 [format %02x 0x9a] sqlite3 db test.db - catchsql {UPDATE t1 SET y=1} -} {1 {database disk image is malformed}} + db eval {UPDATE t1 SET y=1} + db eval {PRAGMA integrity_check} +} {/Offset .* out of range/} # test that a corrupt free cell size is handled (seed 13329) do_test corruptC-2.3 { From 575242f66fb2ae9bb7c55fbd62707e7e09fbf6f8 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 27 Dec 2016 13:33:52 +0000 Subject: [PATCH 1125/1484] Allow sqlite3_interrupt() to be invoked on a database connection that is in the process of being closed even if SQLITE_ENABLE_API_ARMOR is defined. FossilOrigin-Name: 7854bee260996087bdb7f8729ba8cfb4f467f93f --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/main.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 60d41d8a95..bd4c9acd50 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Adjust\sa\scorruption\stest\scase\sto\saccommodate\sthe\ssqlite3BtreeInsert()\noptimization\sof\scheck-in\s[0b86fbca66]. -D 2016-12-27T12:45:41.649 +C Allow\ssqlite3_interrupt()\sto\sbe\sinvoked\son\sa\sdatabase\sconnection\sthat\sis\sin\nthe\sprocess\sof\sbeing\sclosed\seven\sif\sSQLITE_ENABLE_API_ARMOR\sis\sdefined. +D 2016-12-27T13:33:52.277 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -353,7 +353,7 @@ F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 F src/insert.c 91ba5d0143e66479081536ebbaff1850ec9f57d9 F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e F src/loadext.c 5d6642d141c07d366e43d359e94ec9de47add41d -F src/main.c ec789a410860bcdc5d8f7a82090043f482482aec +F src/main.c f2d0e34457ba8c5cce6d78a32cacab388d33e967 F src/malloc.c f3fad34cd570022abca558c573f1761fb09a8212 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b @@ -1539,7 +1539,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a54e619e6f0266932c8873f9ac826fd042a0602f -R eb35cd952180d5ebb2679925e01b66f1 +P 4cb0945f13f2040c8b67936b950da48fc951d55d +R 810fdb7ff72cf3b249dfacd602111888 U drh -Z a0a0f1b4d334e304a9f18235642eec10 +Z 28bf17136c2b551052e6d48a50385817 diff --git a/manifest.uuid b/manifest.uuid index e7e11f6c8e..2c8693c1dd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4cb0945f13f2040c8b67936b950da48fc951d55d \ No newline at end of file +7854bee260996087bdb7f8729ba8cfb4f467f93f \ No newline at end of file diff --git a/src/main.c b/src/main.c index 244ac0f0fc..ffb1bc2a97 100644 --- a/src/main.c +++ b/src/main.c @@ -1568,7 +1568,7 @@ int sqlite3_busy_timeout(sqlite3 *db, int ms){ */ void sqlite3_interrupt(sqlite3 *db){ #ifdef SQLITE_ENABLE_API_ARMOR - if( !sqlite3SafetyCheckOk(db) ){ + if( !sqlite3SafetyCheckOk(db) && (db==0 || db->magic!=SQLITE_MAGIC_ZOMBIE) ){ (void)SQLITE_MISUSE_BKPT; return; } From 402124de5cfbc337bb405c7e03da209ceb5cd780 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 27 Dec 2016 15:59:15 +0000 Subject: [PATCH 1126/1484] Do not allow the nockpt.test module to run under the inmemory_journal permutation. FossilOrigin-Name: a6af06f164b1f65779e2171ec4946119c66f9be8 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/nockpt.test | 5 ++++- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index bd4c9acd50..7dd19b6bf3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Allow\ssqlite3_interrupt()\sto\sbe\sinvoked\son\sa\sdatabase\sconnection\sthat\sis\sin\nthe\sprocess\sof\sbeing\sclosed\seven\sif\sSQLITE_ENABLE_API_ARMOR\sis\sdefined. -D 2016-12-27T13:33:52.277 +C Do\snot\sallow\sthe\snockpt.test\smodule\sto\srun\sunder\sthe\sinmemory_journal\npermutation. +D 2016-12-27T15:59:15.338 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -967,7 +967,7 @@ F test/multiplex4.test e8ae4c4bd70606a5727743241f13b5701990abe4 F test/mutex1.test ea2cc74d97f077b9e74c84cbd024f14d79a8126f F test/mutex2.test bfeaeac2e73095b2ac32285d2756e3a65e681660 F test/nan.test dacc57f80859c06a433d30839336fe227d2038b3 -F test/nockpt.test 9f56a64b20fc78d278fa350a2271c1569d59cd7e +F test/nockpt.test 9a436a7213ba5ef7a32304998d386d3ea3f76c9d F test/nolock.test f196cf8b8fbea4e2ca345140a2b3f3b0da45c76e F test/notify1.test 669b2b743618efdc18ca4b02f45423d5d2304abf F test/notify2.test 2ecabaa1305083856b7c39cf32816b612740c161 @@ -1539,7 +1539,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 4cb0945f13f2040c8b67936b950da48fc951d55d -R 810fdb7ff72cf3b249dfacd602111888 +P 7854bee260996087bdb7f8729ba8cfb4f467f93f +R 0002370ca7e07ee4867da4a22905f821 U drh -Z 28bf17136c2b551052e6d48a50385817 +Z 948aac4cd107424288db7dcd7f723dea diff --git a/manifest.uuid b/manifest.uuid index 2c8693c1dd..5dc63da264 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7854bee260996087bdb7f8729ba8cfb4f467f93f \ No newline at end of file +a6af06f164b1f65779e2171ec4946119c66f9be8 \ No newline at end of file diff --git a/test/nockpt.test b/test/nockpt.test index 60d687d99f..bd3953f1ee 100644 --- a/test/nockpt.test +++ b/test/nockpt.test @@ -19,7 +19,10 @@ source $testdir/lock_common.tcl source $testdir/malloc_common.tcl source $testdir/wal_common.tcl ifcapable !wal {finish_test ; return } -if {[permutation]=="journaltest"} {finish_test; return} +if {[permutation]=="journaltest" || [permutation]=="inmemory_journal"} { + finish_test + return +} set testprefix nockpt From cac028ba19d383c2f49cde751b156cedb69f2aa6 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 29 Dec 2016 03:57:43 +0000 Subject: [PATCH 1127/1484] Add the kvtest.c test program for measuring key/value read performance under various scenarios. FossilOrigin-Name: 489e0787c1ea47963174387e8ade6295ceff568e --- manifest | 14 +- manifest.uuid | 2 +- test/kvtest.c | 473 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 483 insertions(+), 6 deletions(-) create mode 100644 test/kvtest.c diff --git a/manifest b/manifest index 7dd19b6bf3..d07e3a5fa2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Do\snot\sallow\sthe\snockpt.test\smodule\sto\srun\sunder\sthe\sinmemory_journal\npermutation. -D 2016-12-27T15:59:15.338 +C Add\sthe\skvtest.c\stest\sprogram\sfor\smeasuring\skey/value\sread\sperformance\sunder\nvarious\sscenarios. +D 2016-12-29T03:57:43.130 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -894,6 +894,7 @@ F test/json101.test c0897616f32d95431f37fd291cb78742181980ac F test/json102.test bf3fe7a706d30936a76a0f7a0375e1e8e73aff5a F test/json103.test c5f6b85e69de05f6b3195f9f9d5ce9cd179099a0 F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff +F test/kvtest.c 1f8e6f0352ebb0ef4179cd7968af594eee130d57 F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63 F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200 F test/like.test 0603f4fa0dad50987f70032c05800cbfa8985302 @@ -1539,7 +1540,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 7854bee260996087bdb7f8729ba8cfb4f467f93f -R 0002370ca7e07ee4867da4a22905f821 +P a6af06f164b1f65779e2171ec4946119c66f9be8 +R a9bf163ca1249527027c884b8ea94c96 +T *branch * kvtest +T *sym-kvtest * +T -sym-trunk * U drh -Z 948aac4cd107424288db7dcd7f723dea +Z fb835c04c55072b05b31100f6eb7b616 diff --git a/manifest.uuid b/manifest.uuid index 5dc63da264..437dcdf57b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a6af06f164b1f65779e2171ec4946119c66f9be8 \ No newline at end of file +489e0787c1ea47963174387e8ade6295ceff568e \ No newline at end of file diff --git a/test/kvtest.c b/test/kvtest.c new file mode 100644 index 0000000000..9b9a0c3d40 --- /dev/null +++ b/test/kvtest.c @@ -0,0 +1,473 @@ +/* +** 2016-12-28 +** +** 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 "key-value" performance test for SQLite. The +** purpose is to compare the speed of SQLite for accessing large BLOBs +** versus reading those same BLOB values out of individual files in the +** filesystem. +** +** Run "kvtest --help" for further information, or see comments below. +*/ +static const char zHelp[] = +"Usage: kvhelp COMMAND ARGS...\n" +"\n" +" kvhelp init DBFILE --count N --size M --pagesize X\n" +"\n" +" Generate a new test database file named DBFILE containing N\n" +" BLOBs each of size M bytes. The page size of the new database\n" +" file will be X\n" +"\n" +" kvhelp export DBFILE DIRECTORY\n" +"\n" +" Export all the blobs in the kv table of DBFILE into separate\n" +" files in DIRECTORY.\n" +"\n" +" kvhelp run DBFILE [options]\n" +"\n" +" Run a performance test. DBFILE can be either the name of a\n" +" database or a directory containing sample files. Options:\n" +"\n" +" --count N Read N blobs\n" +" --blob-api Use the BLOB API\n" +" --random Read blobs in a random order\n" +" --desc Read blobs in descending order\n" +" --max-id N Maximum blob key to use\n" +" --start N Start reading with this blob key\n" +; + +/* Reference resources used */ +#include +#include +#include +#include +#include +#include +#include +#include "sqlite3.h" + +/* +** Show thqe help text and quit. +*/ +static void showHelp(void){ + fprintf(stdout, "%s", zHelp); + exit(1); +} + +/* +** Show an error message an quit. +*/ +static void fatalError(const char *zFormat, ...){ + va_list ap; + fprintf(stdout, "ERROR: "); + va_start(ap, zFormat); + vfprintf(stdout, zFormat, ap); + va_end(ap); + fprintf(stdout, "\n"); + exit(1); +} + +/* +** Check the filesystem object zPath. Determine what it is: +** +** PATH_DIR A directory +** PATH_DB An SQLite database +** PATH_NEXIST Does not exist +** PATH_OTHER Something else +*/ +#define PATH_DIR 1 +#define PATH_DB 2 +#define PATH_NEXIST 0 +#define PATH_OTHER 99 +static int pathType(const char *zPath){ + struct stat x; + int rc; + if( access(zPath,R_OK) ) return PATH_NEXIST; + memset(&x, 0, sizeof(x)); + rc = stat(zPath, &x); + if( rc<0 ) return PATH_OTHER; + if( S_ISDIR(x.st_mode) ) return PATH_DIR; + if( (x.st_size%512)==0 ) return PATH_DB; + return PATH_OTHER; +} + +/* +** A Pseudo-random number generator with a fixed seed. Use this so +** that the same sequence of "random" numbers are generated on each +** run, for repeatability. +*/ +static unsigned int randInt(void){ + static unsigned int x = 0x333a13cd; + static unsigned int y = 0xecb2adea; + x = (x>>1) ^ ((1+~(x&1)) & 0xd0000001); + y = y*1103515245 + 12345; + return x^y; +} + +/* +** Do database initialization. +*/ +static int initMain(int argc, char **argv){ + char *zDb; + int i, rc; + int nCount = 1000; + int sz = 10000; + int pgsz = 4096; + sqlite3 *db; + char *zSql; + char *zErrMsg = 0; + + assert( strcmp(argv[1],"init")==0 ); + assert( argc>=3 ); + zDb = argv[2]; + for(i=3; i65536 || ((pgsz-1)&pgsz)!=0 ){ + fatalError("the --pagesize must be power of 2 between 512 and 65536"); + } + continue; + } + fatalError("unknown option: \"%s\"", argv[i]); + } + rc = sqlite3_open(zDb, &db); + if( rc ){ + fatalError("cannot open database \"%s\": %s", zDb, sqlite3_errmsg(db)); + } + zSql = sqlite3_mprintf( + "DROP TABLE IF EXISTS kv;\n" + "PRAGMA page_size=%d;\n" + "VACUUM;\n" + "BEGIN;\n" + "CREATE TABLE kv(k INTEGER PRIMARY KEY, v BLOB);\n" + "WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<%d)" + " INSERT INTO kv(k,v) SELECT x, randomblob(%d) FROM c;\n" + "COMMIT;\n", + pgsz, nCount, sz + ); + rc = sqlite3_exec(db, zSql, 0, 0, &zErrMsg); + if( rc ) fatalError("database create failed: %s", zErrMsg); + sqlite3_free(zSql); + sqlite3_close(db); + return 0; +} + +/* +** Implementation of the "writefile(X,Y)" SQL function. The argument Y +** is written into file X. The number of bytes written is returned. Or +** NULL is returned if something goes wrong, such as being unable to open +** file X for writing. +*/ +static void writefileFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + FILE *out; + const char *z; + sqlite3_int64 rc; + const char *zFile; + + zFile = (const char*)sqlite3_value_text(argv[0]); + if( zFile==0 ) return; + out = fopen(zFile, "wb"); + if( out==0 ) return; + z = (const char*)sqlite3_value_blob(argv[1]); + if( z==0 ){ + rc = 0; + }else{ + rc = fwrite(z, 1, sqlite3_value_bytes(argv[1]), out); + } + fclose(out); + sqlite3_result_int64(context, rc); +} + +/* +** Export the kv table to individual files in the filesystem +*/ +static int exportMain(int argc, char **argv){ + char *zDb; + char *zDir; + sqlite3 *db; + char *zSql; + int rc; + char *zErrMsg = 0; + + assert( strcmp(argv[1],"export")==0 ); + assert( argc>=3 ); + zDb = argv[2]; + if( argc!=4 ) fatalError("Usage: kvtest export DATABASE DIRECTORY"); + zDir = argv[3]; + if( pathType(zDir)!=PATH_DIR ){ + fatalError("object \"%s\" is not a directory", zDir); + } + rc = sqlite3_open(zDb, &db); + if( rc ){ + fatalError("cannot open database \"%s\": %s", zDb, sqlite3_errmsg(db)); + } + sqlite3_create_function(db, "writefile", 2, SQLITE_UTF8, 0, + writefileFunc, 0, 0); + zSql = sqlite3_mprintf( + "SELECT writefile(printf('%s/%%06d',k),v) FROM kv;", + zDir + ); + rc = sqlite3_exec(db, zSql, 0, 0, &zErrMsg); + if( rc ) fatalError("database create failed: %s", zErrMsg); + sqlite3_free(zSql); + sqlite3_close(db); + return 0; +} + +/* +** Read the content of file zName into memory obtained from sqlite3_malloc64() +** and return a pointer to the buffer. The caller is responsible for freeing +** the memory. +** +** If parameter pnByte is not NULL, (*pnByte) is set to the number of bytes +** read. +** +** For convenience, a nul-terminator byte is always appended to the data read +** from the file before the buffer is returned. This byte is not included in +** the final value of (*pnByte), if applicable. +** +** NULL is returned if any error is encountered. The final value of *pnByte +** is undefined in this case. +*/ +static unsigned char *readFile(const char *zName, int *pnByte){ + FILE *in = fopen(zName, "rb"); + long nIn; + size_t nRead; + unsigned char *pBuf; + if( in==0 ) return 0; + fseek(in, 0, SEEK_END); + nIn = ftell(in); + rewind(in); + pBuf = sqlite3_malloc64( nIn+1 ); + if( pBuf==0 ) return 0; + nRead = fread(pBuf, nIn, 1, in); + fclose(in); + if( nRead!=1 ){ + sqlite3_free(pBuf); + return 0; + } + pBuf[nIn] = 0; + if( pnByte ) *pnByte = nIn; + return pBuf; +} + +/* +** Return the current time in milliseconds since the beginning of +** the Julian epoch. +*/ +static sqlite3_int64 timeOfDay(void){ + static sqlite3_vfs *clockVfs = 0; + sqlite3_int64 t; + if( clockVfs==0 ) clockVfs = sqlite3_vfs_find(0); + if( clockVfs->iVersion>=2 && clockVfs->xCurrentTimeInt64!=0 ){ + clockVfs->xCurrentTimeInt64(clockVfs, &t); + }else{ + double r; + clockVfs->xCurrentTime(clockVfs, &r); + t = (sqlite3_int64)(r*86400000.0); + } + return t; +} + +/* Blob access order */ +#define ORDER_ASC 1 +#define ORDER_DESC 2 +#define ORDER_RANDOM 3 + +/* +** Run a performance test +*/ +static int runMain(int argc, char **argv){ + int eType; /* Is zDb a database or a directory? */ + char *zDb; /* Database or directory name */ + int i; /* Loop counter */ + int rc; /* Return code from SQLite calls */ + int nCount = 1000; /* Number of blob fetch operations */ + int nExtra = 0; /* Extra cycles */ + int iKey = 1; /* Next blob key */ + int iMax = 1000; /* Largest allowed key */ + int bBlobApi = 0; /* Use the incremental blob I/O API */ + int eOrder = ORDER_ASC; /* Access order */ + sqlite3 *db = 0; /* Database connection */ + sqlite3_stmt *pStmt = 0; /* Prepared statement for SQL access */ + sqlite3_blob *pBlob = 0; /* Handle for incremental Blob I/O */ + sqlite3_int64 tmStart; /* Start time */ + sqlite3_int64 tmElapsed; /* Elapsed time */ + int nData = 0; /* Bytes of data */ + sqlite3_int64 nTotal = 0; /* Total data read */ + unsigned char *pData; /* Content of the blob */ + + + assert( strcmp(argv[1],"run")==0 ); + assert( argc>=3 ); + zDb = argv[2]; + eType = pathType(zDb); + if( eType==PATH_OTHER ) fatalError("unknown object type: \"%s\"", zDb); + if( eType==PATH_NEXIST ) fatalError("object does not exist: \"%s\"", zDb); + for(i=3; iiMax ) iKey = 1; + }else if( eOrder==ORDER_DESC ){ + iKey--; + if( iKey<=0 ) iKey = iMax; + }else{ + iKey = (randInt()%iMax)+1; + } + nTotal += nData; + if( nData==0 ){ nCount++; nExtra++; } + } + if( pStmt ) sqlite3_finalize(pStmt); + if( pBlob ) sqlite3_blob_close(pBlob); + if( db ) sqlite3_close(db); + tmElapsed = timeOfDay() - tmStart; + if( nExtra ){ + printf("%d cycles due to %d misses\n", nCount, nExtra); + } + printf("Total elapsed time: %.3f\n", tmElapsed/1000.0); + printf("Microseconds per BLOB read: %.3f\n", tmElapsed*1000.0/nCount); + printf("Content read rate: %.1f MB/s\n", nTotal/(1000.0*tmElapsed)); + return 0; +} + + +int main(int argc, char **argv){ + if( argc<3 ) showHelp(); + if( strcmp(argv[1],"init")==0 ){ + return initMain(argc, argv); + } + if( strcmp(argv[1],"export")==0 ){ + return exportMain(argc, argv); + } + if( strcmp(argv[1],"run")==0 ){ + return runMain(argc, argv); + } + showHelp(); + return 0; +} From 61c565f63bbf5959160230ee481689b7b4745d9a Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 29 Dec 2016 14:44:43 +0000 Subject: [PATCH 1128/1484] Improvements to the kvtest.c utility. Added the --cache-size option. Additional reporting of version and settings at the end of "./kvtest run". FossilOrigin-Name: f6fcac6ae8b3bffee6bf994eef2064affd301a95 --- manifest | 15 ++++++--------- manifest.uuid | 2 +- test/kvtest.c | 41 +++++++++++++++++++++++++++++++++++++++-- 3 files changed, 46 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index d07e3a5fa2..56f5c02cde 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\skvtest.c\stest\sprogram\sfor\smeasuring\skey/value\sread\sperformance\sunder\nvarious\sscenarios. -D 2016-12-29T03:57:43.130 +C Improvements\sto\sthe\skvtest.c\sutility.\s\sAdded\sthe\s--cache-size\soption.\nAdditional\sreporting\sof\sversion\sand\ssettings\sat\sthe\send\sof\s"./kvtest\srun". +D 2016-12-29T14:44:43.614 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -894,7 +894,7 @@ F test/json101.test c0897616f32d95431f37fd291cb78742181980ac F test/json102.test bf3fe7a706d30936a76a0f7a0375e1e8e73aff5a F test/json103.test c5f6b85e69de05f6b3195f9f9d5ce9cd179099a0 F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff -F test/kvtest.c 1f8e6f0352ebb0ef4179cd7968af594eee130d57 +F test/kvtest.c c3dac524f2eb0f73dbeea6c20f5154cfeaf17cbb F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63 F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200 F test/like.test 0603f4fa0dad50987f70032c05800cbfa8985302 @@ -1540,10 +1540,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a6af06f164b1f65779e2171ec4946119c66f9be8 -R a9bf163ca1249527027c884b8ea94c96 -T *branch * kvtest -T *sym-kvtest * -T -sym-trunk * +P 489e0787c1ea47963174387e8ade6295ceff568e +R a988144fafa83a0cd326685ae38da518 U drh -Z fb835c04c55072b05b31100f6eb7b616 +Z 4424d9424f7545651642c0148887a562 diff --git a/manifest.uuid b/manifest.uuid index 437dcdf57b..a2cbdb5225 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -489e0787c1ea47963174387e8ade6295ceff568e \ No newline at end of file +f6fcac6ae8b3bffee6bf994eef2064affd301a95 \ No newline at end of file diff --git a/test/kvtest.c b/test/kvtest.c index 9b9a0c3d40..94e15e4e16 100644 --- a/test/kvtest.c +++ b/test/kvtest.c @@ -36,11 +36,13 @@ static const char zHelp[] = " Run a performance test. DBFILE can be either the name of a\n" " database or a directory containing sample files. Options:\n" "\n" -" --count N Read N blobs\n" +" --asc Read blobs in ascending order\n" " --blob-api Use the BLOB API\n" -" --random Read blobs in a random order\n" +" --cache-size N Database cache size\n" +" --count N Read N blobs\n" " --desc Read blobs in descending order\n" " --max-id N Maximum blob key to use\n" +" --random Read blobs in a random order\n" " --start N Start reading with this blob key\n" ; @@ -314,6 +316,8 @@ static int runMain(int argc, char **argv){ int nExtra = 0; /* Extra cycles */ int iKey = 1; /* Next blob key */ int iMax = 1000; /* Largest allowed key */ + int iPagesize = 0; /* Database page size */ + int iCache = 1000; /* Database cache size in kibibytes */ int bBlobApi = 0; /* Use the incremental blob I/O API */ int eOrder = ORDER_ASC; /* Access order */ sqlite3 *db = 0; /* Database connection */ @@ -354,6 +358,11 @@ static int runMain(int argc, char **argv){ if( iKey<1 ) fatalError("the --start must be positive"); continue; } + if( strcmp(z, "-cache-size")==0 ){ + if( i==argc-1 ) fatalError("missing argument on \"%s\"", argv[i]); + iCache = atoi(argv[++i]); + continue; + } if( strcmp(z, "-random")==0 ){ eOrder = ORDER_RANDOM; continue; @@ -374,10 +383,28 @@ static int runMain(int argc, char **argv){ } tmStart = timeOfDay(); if( eType==PATH_DB ){ + char *zSql; rc = sqlite3_open(zDb, &db); if( rc ){ fatalError("cannot open database \"%s\": %s", zDb, sqlite3_errmsg(db)); } + zSql = sqlite3_mprintf("PRAGMA cache_size=%d", iCache); + sqlite3_exec(db, zSql, 0, 0, 0); + sqlite3_free(zSql); + pStmt = 0; + sqlite3_prepare_v2(db, "PRAGMA page_size", -1, &pStmt, 0); + if( sqlite3_step(pStmt)==SQLITE_ROW ){ + iPagesize = sqlite3_column_int(pStmt, 0); + } + sqlite3_finalize(pStmt); + sqlite3_prepare_v2(db, "PRAGMA cache_size", -1, &pStmt, 0); + if( sqlite3_step(pStmt)==SQLITE_ROW ){ + iCache = sqlite3_column_int(pStmt, 0); + }else{ + iCache = 0; + } + sqlite3_finalize(pStmt); + pStmt = 0; sqlite3_exec(db, "BEGIN", 0, 0, 0); } for(i=0; i Date: Thu, 29 Dec 2016 15:26:50 +0000 Subject: [PATCH 1129/1484] In kvtest.c: do not show the --cache-size setting on fopen() runs. Show progress for the (potentially slow) "export" command. FossilOrigin-Name: b0f58d2470e08b9c217afd19fcfde3e6d1007d1d --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/kvtest.c | 7 ++++++- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 56f5c02cde..0ee7887b32 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improvements\sto\sthe\skvtest.c\sutility.\s\sAdded\sthe\s--cache-size\soption.\nAdditional\sreporting\sof\sversion\sand\ssettings\sat\sthe\send\sof\s"./kvtest\srun". -D 2016-12-29T14:44:43.614 +C In\skvtest.c:\sdo\snot\sshow\sthe\s--cache-size\ssetting\son\sfopen()\sruns.\nShow\sprogress\sfor\sthe\s(potentially\sslow)\s"export"\scommand. +D 2016-12-29T15:26:50.575 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -894,7 +894,7 @@ F test/json101.test c0897616f32d95431f37fd291cb78742181980ac F test/json102.test bf3fe7a706d30936a76a0f7a0375e1e8e73aff5a F test/json103.test c5f6b85e69de05f6b3195f9f9d5ce9cd179099a0 F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff -F test/kvtest.c c3dac524f2eb0f73dbeea6c20f5154cfeaf17cbb +F test/kvtest.c b25f9fbcb2c1479b8df949ac2ce77362aaf86626 F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63 F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200 F test/like.test 0603f4fa0dad50987f70032c05800cbfa8985302 @@ -1540,7 +1540,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 489e0787c1ea47963174387e8ade6295ceff568e -R a988144fafa83a0cd326685ae38da518 +P f6fcac6ae8b3bffee6bf994eef2064affd301a95 +R b185b854ef51d14c2b7ee5552cbd21ed U drh -Z 4424d9424f7545651642c0148887a562 +Z 874446abf963a27a56a6fa2b35a90f66 diff --git a/manifest.uuid b/manifest.uuid index a2cbdb5225..1919d6c8ca 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f6fcac6ae8b3bffee6bf994eef2064affd301a95 \ No newline at end of file +b0f58d2470e08b9c217afd19fcfde3e6d1007d1d \ No newline at end of file diff --git a/test/kvtest.c b/test/kvtest.c index 94e15e4e16..8c6915f238 100644 --- a/test/kvtest.c +++ b/test/kvtest.c @@ -205,6 +205,7 @@ static void writefileFunc( rc = fwrite(z, 1, sqlite3_value_bytes(argv[1]), out); } fclose(out); + printf("\r%s ", zFile); fflush(stdout); sqlite3_result_int64(context, rc); } @@ -241,6 +242,7 @@ static int exportMain(int argc, char **argv){ if( rc ) fatalError("database create failed: %s", zErrMsg); sqlite3_free(zSql); sqlite3_close(db); + printf("\n"); return 0; } @@ -480,7 +482,10 @@ static int runMain(int argc, char **argv){ if( eType==PATH_DB ){ printf("SQLite version: %s\n", sqlite3_libversion()); } - printf("--count %d --max-id %d --cache-size %d", nCount-nExtra, iMax, iCache); + printf("--count %d --max-id %d", nCount-nExtra, iMax); + if( eType==PATH_DB ){ + printf(" --cache-size %d", iCache); + } switch( eOrder ){ case ORDER_RANDOM: printf(" --random\n"); break; case ORDER_DESC: printf(" --desc\n"); break; From d7b9b97c3bb4bb8f99fc07369832d64c99d9fcfd Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 29 Dec 2016 16:18:35 +0000 Subject: [PATCH 1130/1484] Fix kvtest.c so that it compiles using MSVC. FossilOrigin-Name: e2bbeae7e77cde531885ca492494a02e5322154d --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/kvtest.c | 12 +++++++++++- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 0ee7887b32..600430855b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\skvtest.c:\sdo\snot\sshow\sthe\s--cache-size\ssetting\son\sfopen()\sruns.\nShow\sprogress\sfor\sthe\s(potentially\sslow)\s"export"\scommand. -D 2016-12-29T15:26:50.575 +C Fix\skvtest.c\sso\sthat\sit\scompiles\susing\sMSVC. +D 2016-12-29T16:18:35.078 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -894,7 +894,7 @@ F test/json101.test c0897616f32d95431f37fd291cb78742181980ac F test/json102.test bf3fe7a706d30936a76a0f7a0375e1e8e73aff5a F test/json103.test c5f6b85e69de05f6b3195f9f9d5ce9cd179099a0 F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff -F test/kvtest.c b25f9fbcb2c1479b8df949ac2ce77362aaf86626 +F test/kvtest.c ae8d6b7def067c9a2587c7407c51cc3bc3265994 F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63 F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200 F test/like.test 0603f4fa0dad50987f70032c05800cbfa8985302 @@ -1540,7 +1540,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P f6fcac6ae8b3bffee6bf994eef2064affd301a95 -R b185b854ef51d14c2b7ee5552cbd21ed +P b0f58d2470e08b9c217afd19fcfde3e6d1007d1d +R 407e9e40cdfd5c1d4c79f070fab30b80 U drh -Z 874446abf963a27a56a6fa2b35a90f66 +Z e5c7d745e1b19fb63cf400140139de77 diff --git a/manifest.uuid b/manifest.uuid index 1919d6c8ca..a51064f52d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b0f58d2470e08b9c217afd19fcfde3e6d1007d1d \ No newline at end of file +e2bbeae7e77cde531885ca492494a02e5322154d \ No newline at end of file diff --git a/test/kvtest.c b/test/kvtest.c index 8c6915f238..bb23312a24 100644 --- a/test/kvtest.c +++ b/test/kvtest.c @@ -51,11 +51,21 @@ static const char zHelp[] = #include #include #include -#include #include #include #include "sqlite3.h" +#ifndef _WIN32 +# include +#else + /* Provide Windows equivalent for the needed parts of unistd.h */ +# include +# define R_OK 2 +# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) +# define access _access +#endif + + /* ** Show thqe help text and quit. */ From 2f917e05d764857ba9685582f1375996a5d5e4b8 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 29 Dec 2016 16:49:22 +0000 Subject: [PATCH 1131/1484] Add more detail to the header command to further explain how to compile and use the kvtest.c utility. FossilOrigin-Name: 55d29839c9fafe9e6a694f5790151d1f22396b01 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/kvtest.c | 45 ++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 51 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 600430855b..30efa07022 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\skvtest.c\sso\sthat\sit\scompiles\susing\sMSVC. -D 2016-12-29T16:18:35.078 +C Add\smore\sdetail\sto\sthe\sheader\scommand\sto\sfurther\sexplain\show\sto\scompile\sand\nuse\sthe\skvtest.c\sutility. +D 2016-12-29T16:49:22.977 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -894,7 +894,7 @@ F test/json101.test c0897616f32d95431f37fd291cb78742181980ac F test/json102.test bf3fe7a706d30936a76a0f7a0375e1e8e73aff5a F test/json103.test c5f6b85e69de05f6b3195f9f9d5ce9cd179099a0 F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff -F test/kvtest.c ae8d6b7def067c9a2587c7407c51cc3bc3265994 +F test/kvtest.c 05685d636f6c2985cfe00f88ba95e5c19cbd22bc F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63 F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200 F test/like.test 0603f4fa0dad50987f70032c05800cbfa8985302 @@ -1540,7 +1540,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b0f58d2470e08b9c217afd19fcfde3e6d1007d1d -R 407e9e40cdfd5c1d4c79f070fab30b80 +P e2bbeae7e77cde531885ca492494a02e5322154d +R 7016508fdc58bb08d2b99836c37fbfc4 U drh -Z e5c7d745e1b19fb63cf400140139de77 +Z 4f0078fee62bc1e424f0bd1372e59e1a diff --git a/manifest.uuid b/manifest.uuid index a51064f52d..37f0c85bf8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e2bbeae7e77cde531885ca492494a02e5322154d \ No newline at end of file +55d29839c9fafe9e6a694f5790151d1f22396b01 \ No newline at end of file diff --git a/test/kvtest.c b/test/kvtest.c index bb23312a24..25accc0262 100644 --- a/test/kvtest.c +++ b/test/kvtest.c @@ -15,7 +15,50 @@ ** versus reading those same BLOB values out of individual files in the ** filesystem. ** -** Run "kvtest --help" for further information, or see comments below. +** Run "kvtest" with no arguments for on-line help, or see comments below. +** +** HOW TO COMPILE: +** +** (1) Gather this source file and a recent SQLite3 amalgamation with its +** header into the working directory. You should have: +** +** kvtest.c >--- this file +** sqlite3.c \___ SQLite +** sqlite3.h / amlagamation & header +** +** (2) Run you compiler against the two C source code files. +** +** (a) On linux or mac: +** +** OPTS="-DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION" +** gcc -Os -I. $OPTS kvtest.c sqlite3.c -o kvtest +** +** The $OPTS options can be omitted. The $OPTS merely omit +** the need to link against -ldl and -lpthread, or whatever +** the equivalent libraries are called on your system. +** +** (b) Windows with MSVC: +** +** cl -I. kvtest.c sqlite3.c +** +** USAGE: +** +** (1) Create a test database by running "kvtest init" with appropriate +** options. See the help message for available options. +** +** (2) Construct the corresponding pile-of-files database on disk using +** the "kvtest export" command. +** +** (3) Run tests using "kvtest run" against either the SQLite database or +** the pile-of-files database and with appropriate options. +** +** For example: +** +** ./kvtest init x1.db --count 100000 --size 10000 +** mkdir x1 +** ./kvtest export x1.db x1 +** ./kvtest run x1.db --count 10000 --max-id 1000000 +** ./kvtest run x1 --count 10000 --max-id 1000000 */ static const char zHelp[] = "Usage: kvhelp COMMAND ARGS...\n" From cae20d5cf1d324fc6d43cf4d0c60ca6331da4201 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 29 Dec 2016 17:25:06 +0000 Subject: [PATCH 1132/1484] In kvtest.c, use stat() instead of fseek()/ftell() to determine the size of a BLOB to be read directly from disk. This makes the pile-of-files database more competative against SQLite. FossilOrigin-Name: a7dca29f03e037fe71cc600db97f8058e3bd28a4 --- manifest | 13 ++++++------- manifest.uuid | 2 +- test/kvtest.c | 33 ++++++++++++++++++++++++--------- 3 files changed, 31 insertions(+), 17 deletions(-) diff --git a/manifest b/manifest index 70c7ebc070..ee9eb6e447 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\skvtest.c\stest\sprogram\sused\sto\sshow\sthat\sit\sis\smany\stimes\sfaster\sto\nread\sthumbnail\sand\ssimilar\sBLOBs\sout\sof\san\sSQLite\sdatabase\sthan\sit\sis\sto\sread\nthem\sas\sseparate\sfiles\sfrom\sthe\sfilesystem. -D 2016-12-29T16:58:01.454 +C In\skvtest.c,\suse\sstat()\sinstead\sof\sfseek()/ftell()\sto\sdetermine\sthe\ssize\sof\na\sBLOB\sto\sbe\sread\sdirectly\sfrom\sdisk.\s\sThis\smakes\sthe\spile-of-files\sdatabase\nmore\scompetative\sagainst\sSQLite. +D 2016-12-29T17:25:06.872 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -894,7 +894,7 @@ F test/json101.test c0897616f32d95431f37fd291cb78742181980ac F test/json102.test bf3fe7a706d30936a76a0f7a0375e1e8e73aff5a F test/json103.test c5f6b85e69de05f6b3195f9f9d5ce9cd179099a0 F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff -F test/kvtest.c 05685d636f6c2985cfe00f88ba95e5c19cbd22bc +F test/kvtest.c 2c66ddefcd03c2caa337f6dd79e6c82368af83df F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63 F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200 F test/like.test 0603f4fa0dad50987f70032c05800cbfa8985302 @@ -1540,8 +1540,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a6af06f164b1f65779e2171ec4946119c66f9be8 55d29839c9fafe9e6a694f5790151d1f22396b01 -R 7016508fdc58bb08d2b99836c37fbfc4 -T +closed 55d29839c9fafe9e6a694f5790151d1f22396b01 +P 8074d59cf177cb91ee371e2660f2c59ce540b7e2 +R 753a90b01c338f55ad8c1b7fed642932 U drh -Z 23505d55f5d4f936007bea728155ea61 +Z 3b88de21d40c4e92a72ebab5ce816139 diff --git a/manifest.uuid b/manifest.uuid index 8059e9f0ee..52db41a773 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8074d59cf177cb91ee371e2660f2c59ce540b7e2 \ No newline at end of file +a7dca29f03e037fe71cc600db97f8058e3bd28a4 \ No newline at end of file diff --git a/test/kvtest.c b/test/kvtest.c index 25accc0262..877605aced 100644 --- a/test/kvtest.c +++ b/test/kvtest.c @@ -104,6 +104,7 @@ static const char zHelp[] = /* Provide Windows equivalent for the needed parts of unistd.h */ # include # define R_OK 2 +# define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) # define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) # define access _access #endif @@ -154,6 +155,20 @@ static int pathType(const char *zPath){ return PATH_OTHER; } +/* +** Return the size of a file in bytes. Or return -1 if the +** named object is not a regular file or does not exist. +*/ +static sqlite3_int64 fileSize(const char *zPath){ + struct stat x; + int rc; + memset(&x, 0, sizeof(x)); + rc = stat(zPath, &x); + if( rc<0 ) return -1; + if( !S_ISREG(x.st_mode) ) return -1; + return x.st_size; +} + /* ** A Pseudo-random number generator with a fixed seed. Use this so ** that the same sequence of "random" numbers are generated on each @@ -315,15 +330,16 @@ static int exportMain(int argc, char **argv){ ** is undefined in this case. */ static unsigned char *readFile(const char *zName, int *pnByte){ - FILE *in = fopen(zName, "rb"); - long nIn; - size_t nRead; - unsigned char *pBuf; + FILE *in; /* FILE from which to read content of zName */ + sqlite3_int64 nIn; /* Size of zName in bytes */ + size_t nRead; /* Number of bytes actually read */ + unsigned char *pBuf; /* Content read from disk */ + + nIn = fileSize(zName); + if( nIn<0 ) return 0; + in = fopen(zName, "rb"); if( in==0 ) return 0; - fseek(in, 0, SEEK_END); - nIn = ftell(in); - rewind(in); - pBuf = sqlite3_malloc64( nIn+1 ); + pBuf = sqlite3_malloc64( nIn ); if( pBuf==0 ) return 0; nRead = fread(pBuf, nIn, 1, in); fclose(in); @@ -331,7 +347,6 @@ static unsigned char *readFile(const char *zName, int *pnByte){ sqlite3_free(pBuf); return 0; } - pBuf[nIn] = 0; if( pnByte ) *pnByte = nIn; return pBuf; } From 96ada59cbb25b37a73618016c8af6b39af005295 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 29 Dec 2016 19:48:46 +0000 Subject: [PATCH 1133/1484] Fix harmless compiler warnings in the command-line shell and in Lemon. FossilOrigin-Name: afcdc4a60e357d171156e0de705bf7ad1b37daab --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/shell.c | 4 ++-- tool/lemon.c | 1 - 4 files changed, 10 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index ee9eb6e447..aa299106eb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\skvtest.c,\suse\sstat()\sinstead\sof\sfseek()/ftell()\sto\sdetermine\sthe\ssize\sof\na\sBLOB\sto\sbe\sread\sdirectly\sfrom\sdisk.\s\sThis\smakes\sthe\spile-of-files\sdatabase\nmore\scompetative\sagainst\sSQLite. -D 2016-12-29T17:25:06.872 +C Fix\sharmless\scompiler\swarnings\sin\sthe\scommand-line\sshell\sand\sin\sLemon. +D 2016-12-29T19:48:46.056 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -389,7 +389,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c bb070cf5f23611c44ab7e4788803684e385fc3fb F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c dfb6cadc3dcfba1b1bdbfba62ebba2b4b673413e -F src/shell.c 48ab675e5526903d2b7bea8c9736cafa345544e1 +F src/shell.c 6095531aa900decdaa765e0f3993fba7153c92c1 F src/sqlite.h.in e8e2d108d82647f0a812fdb74accf91c1ec08ddc F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae @@ -1467,7 +1467,7 @@ F tool/fuzzershell.c dbf6c26eef936ec78cb0707570de3a4308b2507e F tool/genfkey.README cf68fddd4643bbe3ff8e31b8b6d8b0a1b85e20f4 F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5 F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce -F tool/lemon.c e4fb7d888873ac88f20a41c84a7d1e61f5209a6d +F tool/lemon.c 5ccba178a8e8a4b21e1c9232944d23973da38ad7 F tool/lempar.c 320d630b44da693407684c64d9fa91a163419dac F tool/libvers.c caafc3b689638a1d88d44bc5f526c2278760d9b9 F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862 @@ -1540,7 +1540,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 8074d59cf177cb91ee371e2660f2c59ce540b7e2 -R 753a90b01c338f55ad8c1b7fed642932 +P a7dca29f03e037fe71cc600db97f8058e3bd28a4 +R a5cb3a1af480c7a18023eb7f338349d2 U drh -Z 3b88de21d40c4e92a72ebab5ce816139 +Z e569fcc83d59a51062b98f5f55226d42 diff --git a/manifest.uuid b/manifest.uuid index 52db41a773..40f4cfbe72 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a7dca29f03e037fe71cc600db97f8058e3bd28a4 \ No newline at end of file +afcdc4a60e357d171156e0de705bf7ad1b37daab \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index ae833d767a..b0928ce792 100644 --- a/src/shell.c +++ b/src/shell.c @@ -3292,7 +3292,7 @@ static void shellFkeyCollateClause( const char *zParentSeq; const char *zChild; const char *zChildCol; - const char *zChildSeq; + const char *zChildSeq = 0; /* Initialize to avoid false-positive warning */ int rc; assert( nVal==4 ); @@ -3500,7 +3500,7 @@ static int lintDotCommand( int nArg /* Number of entries in azArg[] */ ){ int n; - n = (nArg>=2 ? strlen(azArg[1]) : 0); + n = (nArg>=2 ? (int)strlen(azArg[1]) : 0); if( n<1 || sqlite3_strnicmp(azArg[1], "fkey-indexes", n) ) goto usage; return lintFkeyIndexes(pState, azArg, nArg); diff --git a/tool/lemon.c b/tool/lemon.c index 0fa3d63b4e..aa0f4e3e9c 100644 --- a/tool/lemon.c +++ b/tool/lemon.c @@ -4159,7 +4159,6 @@ void ReportTable( */ for(rp=lemp->rule; rp; rp=rp->next) rp->doesReduce = LEMON_FALSE; for(i=0; inxstate; i++){ - struct action *ap; for(ap=lemp->sorted[i]->ap; ap; ap=ap->next){ if( ap->type==REDUCE || ap->type==SHIFTREDUCE ){ ap->x.rp->doesReduce = i; From fb4e3a3bbb0e7879f07da22b304c434b0adf87e4 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 30 Dec 2016 00:09:14 +0000 Subject: [PATCH 1134/1484] Encode a 64-bit integer literal in date.c as a constant expression so that it works on older compilers. Also fix a harmless compiler warning in vdbe.c. FossilOrigin-Name: f57952bac652901e1bd48b68301941efbcf29dc4 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/date.c | 11 ++++++++++- src/vdbe.c | 2 +- 4 files changed, 19 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index aa299106eb..728e7dbd28 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\scompiler\swarnings\sin\sthe\scommand-line\sshell\sand\sin\sLemon. -D 2016-12-29T19:48:46.056 +C Encode\sa\s64-bit\sinteger\sliteral\sin\sdate.c\sas\sa\sconstant\sexpression\sso\sthat\nit\sworks\son\solder\scompilers.\s\sAlso\sfix\sa\sharmless\scompiler\swarning\sin\svdbe.c. +D 2016-12-30T00:09:14.046 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -338,7 +338,7 @@ F src/build.c 9e799f1edd910dfa8a0bc29bd390d35d310596af F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 9f2296a4e5d26ebf0e0d95a0af4628f1ea694e7a -F src/date.c b48378aeac68fa20c811404955a9b62108df47d8 +F src/date.c dc3f1391d9297f8c748132813aaffcb117090d6e F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c c8bc10d145c9666a34ae906250326fdaa8d58fa5 F src/expr.c a90e37bc542abe33890cafccacbf8a7db9cb5401 @@ -455,7 +455,7 @@ F src/update.c 1da7c462110bffed442a42884cb0d528c1db46d8 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 1534060bc034cdc51381c040c8bd6252dbcb64c9 F src/vacuum.c 33c174b28886b2faf26e503b5a49a1c01a9b1c16 -F src/vdbe.c a35ad51713d9be42f97e80f24cd4be5d20886a0c +F src/vdbe.c 88bd6c32b333580d2661ac3afe33369757fb1522 F src/vdbe.h 50ee139f9c68fff91be1d717ed3a6abbd496919c F src/vdbeInt.h 281cb70332dc8b593b8c7afe776f3a2ba7d4255e F src/vdbeapi.c d6ebaa465f070eb1af8ba4e7b34583ece87bdd24 @@ -1540,7 +1540,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a7dca29f03e037fe71cc600db97f8058e3bd28a4 -R a5cb3a1af480c7a18023eb7f338349d2 +P afcdc4a60e357d171156e0de705bf7ad1b37daab +R 813e73c67c9aeca5cd69ce74ed137efb U drh -Z e569fcc83d59a51062b98f5f55226d42 +Z 3112948a79a12b2a077d364cd13de4f8 diff --git a/manifest.uuid b/manifest.uuid index 40f4cfbe72..27009fe9f9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -afcdc4a60e357d171156e0de705bf7ad1b37daab \ No newline at end of file +f57952bac652901e1bd48b68301941efbcf29dc4 \ No newline at end of file diff --git a/src/date.c b/src/date.c index 4326919601..a08248ce2f 100644 --- a/src/date.c +++ b/src/date.c @@ -395,13 +395,22 @@ static int parseDateOrTime( return 1; } +/* The julian day number for 9999-12-31 23:59:59.999 is 5373484.4999999. +** Multiplying this by 86400000 gives 464269060799999 as the maximum value +** for DateTime.iJD. +** +** But some older compilers (ex: gcc 4.2.1 on older Macs) cannot deal with +** such a large integer literal, so we have to encode it. +*/ +#define INT_464269060799999 ((((i64)0x1a640)<<32)|0x1072fdff) + /* ** Return TRUE if the given julian day number is within range. ** ** The input is the JulianDay times 86400000. */ static int validJulianDay(sqlite3_int64 iJD){ - return iJD>=0 && iJD<=464269060799999; + return iJD>=0 && iJD<=INT_464269060799999; } /* diff --git a/src/vdbe.c b/src/vdbe.c index 152a37447a..5e707a6232 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -977,7 +977,7 @@ case OP_Halt: { p->rc = pOp->p1; p->errorAction = (u8)pOp->p2; p->pc = pcx; - assert( pOp->p5>=0 && pOp->p5<=4 ); + assert( pOp->p5<=4 ); if( p->rc ){ if( pOp->p5 ){ static const char * const azType[] = { "NOT NULL", "UNIQUE", "CHECK", From 9c4dc22926a5de0d7b7e6121f8f640b17aaccbbe Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 30 Dec 2016 12:06:22 +0000 Subject: [PATCH 1135/1484] Disable the pagerAcquireMapPage() routine if memory-mapped I/O is disabled. This fixes a harmless compiler warning on OpenBSD. FossilOrigin-Name: 3e25ba6e42fba239795a465b8510386a361ee5be --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/pager.c | 2 ++ 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 728e7dbd28..9133bf9181 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Encode\sa\s64-bit\sinteger\sliteral\sin\sdate.c\sas\sa\sconstant\sexpression\sso\sthat\nit\sworks\son\solder\scompilers.\s\sAlso\sfix\sa\sharmless\scompiler\swarning\sin\svdbe.c. -D 2016-12-30T00:09:14.046 +C Disable\sthe\spagerAcquireMapPage()\sroutine\sif\smemory-mapped\sI/O\sis\sdisabled.\nThis\sfixes\sa\sharmless\scompiler\swarning\son\sOpenBSD. +D 2016-12-30T12:06:22.488 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -375,7 +375,7 @@ F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586 F src/os_unix.c 30e2c43e4955db990e5b5a81e901f8aa74cc8820 F src/os_win.c cf90abd4e50d9f56d2c20ce8e005aff55d7bd8e9 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a -F src/pager.c 81fe2bb847df537694ec39e28e8b3dc221c64a7d +F src/pager.c 1c7a2b82b290b85b90f9275ae003f688935f70f9 F src/pager.h d1e944291030351f362a0a7da9b5c3e34e603e39 F src/parse.y 29153738a7322054359320eb00b5a4cd44389f20 F src/pcache.c 51070ec9b8251bbf9c6ea3d35fd96a458752929e @@ -1540,7 +1540,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P afcdc4a60e357d171156e0de705bf7ad1b37daab -R 813e73c67c9aeca5cd69ce74ed137efb +P f57952bac652901e1bd48b68301941efbcf29dc4 +R 84982edb372ca58cbe65b01953728d25 U drh -Z 3112948a79a12b2a077d364cd13de4f8 +Z cbb966aa1c32407e62c70cc77619dbe0 diff --git a/manifest.uuid b/manifest.uuid index 27009fe9f9..6d837edae3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f57952bac652901e1bd48b68301941efbcf29dc4 \ No newline at end of file +3e25ba6e42fba239795a465b8510386a361ee5be \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index 5bcb9247e8..073bf35edb 100644 --- a/src/pager.c +++ b/src/pager.c @@ -3964,6 +3964,7 @@ static int pagerSyncHotJournal(Pager *pPager){ return rc; } +#if SQLITE_MAX_MMAP_SIZE>0 /* ** Obtain a reference to a memory mapped page object for page number pgno. ** The new object will use the pointer pData, obtained from xFetch(). @@ -4012,6 +4013,7 @@ static int pagerAcquireMapPage( return SQLITE_OK; } +#endif /* ** Release a reference to page pPg. pPg must have been returned by an From d0d7e1351192300b90b3ada5ea10c6fb596c8796 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 30 Dec 2016 12:10:48 +0000 Subject: [PATCH 1136/1484] Fix a harmless compiler warning in fuzzcheck.c FossilOrigin-Name: 2842bc60538369f888c7df8365858c910322277d --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/fuzzcheck.c | 3 --- 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 9133bf9181..a98844efba 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Disable\sthe\spagerAcquireMapPage()\sroutine\sif\smemory-mapped\sI/O\sis\sdisabled.\nThis\sfixes\sa\sharmless\scompiler\swarning\son\sOpenBSD. -D 2016-12-30T12:06:22.488 +C Fix\sa\sharmless\scompiler\swarning\sin\sfuzzcheck.c +D 2016-12-30T12:10:48.960 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -816,7 +816,7 @@ F test/fuzz2.test 76dc35b32b6d6f965259508508abce75a6c4d7e1 F test/fuzz3.test b47377143f0c80f91ed29d722861077ff34415d5 F test/fuzz_common.tcl a87dfbb88c2a6b08a38e9a070dabd129e617b45b F test/fuzz_malloc.test 328f70aaca63adf29b4c6f06505ed0cf57ca7c26 -F test/fuzzcheck.c 9c29eae3536beaf1a816e81d106208c304e50b0a +F test/fuzzcheck.c a87e6067a8d19844bade916841cb76150ecf24a2 F test/fuzzdata1.db 7ee3227bad0e7ccdeb08a9e6822916777073c664 F test/fuzzdata2.db f03a420d3b822cc82e4f894ca957618fbe9c4973 F test/fuzzdata3.db c6586d3e3cef0fbc18108f9bb649aa77bfc38aba @@ -1540,7 +1540,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P f57952bac652901e1bd48b68301941efbcf29dc4 -R 84982edb372ca58cbe65b01953728d25 +P 3e25ba6e42fba239795a465b8510386a361ee5be +R cb43d33d19adf32bebd1dfaa0e0b456a U drh -Z cbb966aa1c32407e62c70cc77619dbe0 +Z 067d360edde333b631fbf0df03bf7c2e diff --git a/manifest.uuid b/manifest.uuid index 6d837edae3..6755f6c671 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3e25ba6e42fba239795a465b8510386a361ee5be \ No newline at end of file +2842bc60538369f888c7df8365858c910322277d \ No newline at end of file diff --git a/test/fuzzcheck.c b/test/fuzzcheck.c index 2182f03d09..75d519566f 100644 --- a/test/fuzzcheck.c +++ b/test/fuzzcheck.c @@ -70,7 +70,6 @@ #include #include #include "sqlite3.h" -#include #define ISSPACE(X) isspace((unsigned char)(X)) #define ISDIGIT(X) isdigit((unsigned char)(X)) @@ -636,14 +635,12 @@ static void inmemVfsRegister(int makeDefault){ */ static void runSql(sqlite3 *db, const char *zSql, unsigned runFlags){ const char *zMore; - const char *zEnd = &zSql[strlen(zSql)]; sqlite3_stmt *pStmt; while( zSql && zSql[0] ){ zMore = 0; pStmt = 0; sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zMore); - assert( zMore<=zEnd ); if( zMore==zSql ) break; if( runFlags & SQL_TRACE ){ const char *z = zSql; From 895decf6b5c21d73f5de02581498c221dfa7c5f8 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 30 Dec 2016 14:15:56 +0000 Subject: [PATCH 1137/1484] Avoid passing NULL pointers to memcmp() or memcpy(), even when the "number-of-bytes" argument is passed 0. FossilOrigin-Name: 56ff72ab44288296efc99a608f7edc4346366a50 --- ext/session/sqlite3session.c | 16 +++++++-------- manifest | 22 ++++++++++----------- manifest.uuid | 2 +- src/analyze.c | 4 +++- src/func.c | 38 +++++++++++++++++++----------------- src/main.c | 4 +++- src/printf.c | 2 +- 7 files changed, 46 insertions(+), 42 deletions(-) diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index 70ca840dae..50793df0a0 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -374,9 +374,7 @@ static int sessionSerializeValue( if( aBuf ){ sessionVarintPut(&aBuf[1], n); - memcpy(&aBuf[nVarint + 1], eType==SQLITE_TEXT ? - sqlite3_value_text(pValue) : sqlite3_value_blob(pValue), n - ); + if( n ) memcpy(&aBuf[nVarint + 1], z, n); } nByte = 1 + nVarint + n; @@ -1792,7 +1790,7 @@ static void sessionAppendBlob( int nBlob, int *pRc ){ - if( 0==sessionBufferGrow(p, nBlob, pRc) ){ + if( nBlob>0 && 0==sessionBufferGrow(p, nBlob, pRc) ){ memcpy(&p->aBuf[p->nBuf], aBlob, nBlob); p->nBuf += nBlob; } @@ -1978,13 +1976,13 @@ static int sessionAppendUpdate( } default: { - int nByte; - int nHdr = 1 + sessionVarintGet(&pCsr[1], &nByte); + int n; + int nHdr = 1 + sessionVarintGet(&pCsr[1], &n); assert( eType==SQLITE_TEXT || eType==SQLITE_BLOB ); - nAdvance = nHdr + nByte; + nAdvance = nHdr + n; if( eType==sqlite3_column_type(pStmt, i) - && nByte==sqlite3_column_bytes(pStmt, i) - && 0==memcmp(&pCsr[nHdr], sqlite3_column_blob(pStmt, i), nByte) + && n==sqlite3_column_bytes(pStmt, i) + && (n==0 || 0==memcmp(&pCsr[nHdr], sqlite3_column_blob(pStmt, i), n)) ){ break; } diff --git a/manifest b/manifest index a98844efba..52cf7abd9c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sharmless\scompiler\swarning\sin\sfuzzcheck.c -D 2016-12-30T12:10:48.960 +C Avoid\spassing\sNULL\spointers\sto\smemcmp()\sor\smemcpy(),\seven\swhen\sthe\n"number-of-bytes"\sargument\sis\spassed\s0. +D 2016-12-30T14:15:56.745 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -303,7 +303,7 @@ F ext/session/sessionG.test 01ef705096a9d3984eebdcca79807a211dee1b60 F ext/session/session_common.tcl 9b696a341cf1d3744823715ed92bb19749b6c3d4 F ext/session/sessionfault.test da273f2712b6411e85e71465a1733b8501dbf6f7 F ext/session/sessionfault2.test 04aa0bc9aa70ea43d8de82c4f648db4de1e990b0 -F ext/session/sqlite3session.c 37485891b4add26cf61495df193c419f36556a32 +F ext/session/sqlite3session.c c61a43396368ec00dc127f7bc647e9bd6a4ee5fb F ext/session/sqlite3session.h 9345166bd8f80562145586cf817f707de5ecada2 F ext/session/test_session.c eb0bd6c1ea791c1d66ee4ef94c16500dad936386 F ext/userauth/sqlite3userauth.h 19cb6f0e31316d0ee4afdfb7a85ef9da3333a220 @@ -325,7 +325,7 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F src/alter.c 3b23977620ce9662ac54443f65b87ba996e36121 -F src/analyze.c 8b62b2cf4da85451534ac0af82cafc418d837f68 +F src/analyze.c 3c4a63ff7a55faefecf6eb1589932fdbc06b2415 F src/attach.c f6725410c184a80d8141b294fdf98a854c8a52b5 F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792 F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b @@ -344,7 +344,7 @@ F src/delete.c c8bc10d145c9666a34ae906250326fdaa8d58fa5 F src/expr.c a90e37bc542abe33890cafccacbf8a7db9cb5401 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 2e9aabe1aee76273aff8a84ee92c464e095400ae -F src/func.c 43916c1d8e6da5d107d91d2b212577d4f69a876a +F src/func.c e0190fd64810a66889bd52c8950f6b5ab3e67356 F src/global.c dcdb89f30b7aa531c5660030af106bc5bc48ef2e F src/hash.c 63d0ee752a3b92d4695b2b1f5259c4621b2cfebd F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4 @@ -353,7 +353,7 @@ F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 F src/insert.c 91ba5d0143e66479081536ebbaff1850ec9f57d9 F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e F src/loadext.c 5d6642d141c07d366e43d359e94ec9de47add41d -F src/main.c f2d0e34457ba8c5cce6d78a32cacab388d33e967 +F src/main.c e207b81542d13b9f13d61e78ca441f9781f055b0 F src/malloc.c f3fad34cd570022abca558c573f1761fb09a8212 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b @@ -384,7 +384,7 @@ F src/pcache1.c e3967219b2a92b9edcb9324a4ba75009090d3953 F src/pragma.c 5a23557e490e7ac5afef097efc4b59dce5b482c2 F src/pragma.h f9b221b2c8949ea941dbee49934299e4ed5af41c F src/prepare.c b1140c3d0cf59bc85ace00ce363153041b424b7a -F src/printf.c f94da4935d1dd25420ac50c6745db1deb35e07c1 +F src/printf.c 0c8579432f47948d9be5077eb590e8c4a01be667 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c bb070cf5f23611c44ab7e4788803684e385fc3fb F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac @@ -1540,7 +1540,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 3e25ba6e42fba239795a465b8510386a361ee5be -R cb43d33d19adf32bebd1dfaa0e0b456a -U drh -Z 067d360edde333b631fbf0df03bf7c2e +P 2842bc60538369f888c7df8365858c910322277d +R 2f360df0a4ed7700031588f42df25e4f +U dan +Z 37bb29b03ead205804ed648a38318574 diff --git a/manifest.uuid b/manifest.uuid index 6755f6c671..3fe3e58c51 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2842bc60538369f888c7df8365858c910322277d \ No newline at end of file +56ff72ab44288296efc99a608f7edc4346366a50 \ No newline at end of file diff --git a/src/analyze.c b/src/analyze.c index e3955f3022..c480a0c507 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -1766,7 +1766,9 @@ static int loadStatTbl( sqlite3_finalize(pStmt); return SQLITE_NOMEM_BKPT; } - memcpy(pSample->p, sqlite3_column_blob(pStmt, 4), pSample->n); + if( pSample->n ){ + memcpy(pSample->p, sqlite3_column_blob(pStmt, 4), pSample->n); + } pIdx->nSample++; } rc = sqlite3_finalize(pStmt); diff --git a/src/func.c b/src/func.c index 5b8ed6dd2b..37f7cd6152 100644 --- a/src/func.c +++ b/src/func.c @@ -200,25 +200,27 @@ static void instrFunc( if( typeHaystack==SQLITE_NULL || typeNeedle==SQLITE_NULL ) return; nHaystack = sqlite3_value_bytes(argv[0]); nNeedle = sqlite3_value_bytes(argv[1]); - if( typeHaystack==SQLITE_BLOB && typeNeedle==SQLITE_BLOB ){ - zHaystack = sqlite3_value_blob(argv[0]); - zNeedle = sqlite3_value_blob(argv[1]); - isText = 0; - }else{ - zHaystack = sqlite3_value_text(argv[0]); - zNeedle = sqlite3_value_text(argv[1]); - isText = 1; - if( zNeedle==0 ) return; - assert( zHaystack ); + if( nNeedle>0 ){ + if( typeHaystack==SQLITE_BLOB && typeNeedle==SQLITE_BLOB ){ + zHaystack = sqlite3_value_blob(argv[0]); + zNeedle = sqlite3_value_blob(argv[1]); + isText = 0; + }else{ + zHaystack = sqlite3_value_text(argv[0]); + zNeedle = sqlite3_value_text(argv[1]); + isText = 1; + if( zNeedle==0 ) return; + assert( zHaystack ); + } + while( nNeedle<=nHaystack && memcmp(zHaystack, zNeedle, nNeedle)!=0 ){ + N++; + do{ + nHaystack--; + zHaystack++; + }while( isText && (zHaystack[0]&0xc0)==0x80 ); + } + if( nNeedle>nHaystack ) N = 0; } - while( nNeedle<=nHaystack && memcmp(zHaystack, zNeedle, nNeedle)!=0 ){ - N++; - do{ - nHaystack--; - zHaystack++; - }while( isText && (zHaystack[0]&0xc0)==0x80 ); - } - if( nNeedle>nHaystack ) N = 0; sqlite3_result_int(context, N); } diff --git a/src/main.c b/src/main.c index ffb1bc2a97..9aad8fdd4c 100644 --- a/src/main.c +++ b/src/main.c @@ -2739,7 +2739,9 @@ int sqlite3ParseUri( }else{ zFile = sqlite3_malloc64(nUri+2); if( !zFile ) return SQLITE_NOMEM_BKPT; - memcpy(zFile, zUri, nUri); + if( nUri ){ + memcpy(zFile, zUri, nUri); + } zFile[nUri] = '\0'; zFile[nUri+1] = '\0'; flags &= ~SQLITE_OPEN_URI; diff --git a/src/printf.c b/src/printf.c index 8de0a924ae..91b753e04f 100644 --- a/src/printf.c +++ b/src/printf.c @@ -841,7 +841,7 @@ void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){ assert( p->accError==0 || p->nAlloc==0 ); if( p->nChar+N >= p->nAlloc ){ enlargeAndAppend(p,z,N); - }else{ + }else if( N ){ assert( p->zText ); p->nChar += N; memcpy(&p->zText[p->nChar-N], z, N); From 5f4ade0473f2d76361a91120a2c4fe9489feaee8 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 30 Dec 2016 14:25:42 +0000 Subject: [PATCH 1138/1484] Add a test to ensure that the app-defined pcache xFetch() method is never passed a key of zero. FossilOrigin-Name: 0bdbe49c6d392c4c86a6c01219c9d91d150dea7d --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/pager.c | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 52cf7abd9c..e1bb7e3206 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\spassing\sNULL\spointers\sto\smemcmp()\sor\smemcpy(),\seven\swhen\sthe\n"number-of-bytes"\sargument\sis\spassed\s0. -D 2016-12-30T14:15:56.745 +C Add\sa\stest\sto\sensure\sthat\sthe\sapp-defined\spcache\sxFetch()\smethod\sis\snever\npassed\sa\skey\sof\szero. +D 2016-12-30T14:25:42.274 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -375,7 +375,7 @@ F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586 F src/os_unix.c 30e2c43e4955db990e5b5a81e901f8aa74cc8820 F src/os_win.c cf90abd4e50d9f56d2c20ce8e005aff55d7bd8e9 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a -F src/pager.c 1c7a2b82b290b85b90f9275ae003f688935f70f9 +F src/pager.c 9dc72d23eebbdf992bd69f2ab954d0d3a27c7340 F src/pager.h d1e944291030351f362a0a7da9b5c3e34e603e39 F src/parse.y 29153738a7322054359320eb00b5a4cd44389f20 F src/pcache.c 51070ec9b8251bbf9c6ea3d35fd96a458752929e @@ -1540,7 +1540,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 2842bc60538369f888c7df8365858c910322277d -R 2f360df0a4ed7700031588f42df25e4f -U dan -Z 37bb29b03ead205804ed648a38318574 +P 56ff72ab44288296efc99a608f7edc4346366a50 +R e9376a0e6f39c186396a7f16973b7c00 +U drh +Z a28c5cf75c694c3d54fc5cc0da0c3d0d diff --git a/manifest.uuid b/manifest.uuid index 3fe3e58c51..23f172d71f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -56ff72ab44288296efc99a608f7edc4346366a50 \ No newline at end of file +0bdbe49c6d392c4c86a6c01219c9d91d150dea7d \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index 073bf35edb..5813b4db47 100644 --- a/src/pager.c +++ b/src/pager.c @@ -5373,6 +5373,7 @@ static int getPageNormal( assert( assert_pager_state(pPager) ); assert( pPager->hasHeldSharedLock==1 ); + if( pgno==0 ) return SQLITE_CORRUPT_BKPT; pBase = sqlite3PcacheFetch(pPager->pPCache, pgno, 3); if( pBase==0 ){ pPg = 0; @@ -5400,11 +5401,10 @@ static int getPageNormal( /* The pager cache has created a new page. Its content needs to ** be initialized. But first some error checks: ** - ** (1) Minimum page number is 1 - ** (2) The maximum page number is 2^31 - ** (3) Never try to fetch the locking page + ** (1) The maximum page number is 2^31 + ** (2) Never try to fetch the locking page */ - if( pgno==0 || pgno>PAGER_MAX_PGNO || pgno==PAGER_MJ_PGNO(pPager) ){ + if( pgno>PAGER_MAX_PGNO || pgno==PAGER_MJ_PGNO(pPager) ){ rc = SQLITE_CORRUPT_BKPT; goto pager_acquire_err; } From 1d081ab39e8296a46e1254278464c11aec582b51 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 30 Dec 2016 15:16:20 +0000 Subject: [PATCH 1139/1484] Strengthen the defense against OOM in the instr() SQL function. FossilOrigin-Name: a0971e713682a73d8c7c20511db256c20d2f6388 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/func.c | 5 +++-- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index e1bb7e3206..cb748fb07e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sa\stest\sto\sensure\sthat\sthe\sapp-defined\spcache\sxFetch()\smethod\sis\snever\npassed\sa\skey\sof\szero. -D 2016-12-30T14:25:42.274 +C Strengthen\sthe\sdefense\sagainst\sOOM\sin\sthe\sinstr()\sSQL\sfunction. +D 2016-12-30T15:16:20.650 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -344,7 +344,7 @@ F src/delete.c c8bc10d145c9666a34ae906250326fdaa8d58fa5 F src/expr.c a90e37bc542abe33890cafccacbf8a7db9cb5401 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 2e9aabe1aee76273aff8a84ee92c464e095400ae -F src/func.c e0190fd64810a66889bd52c8950f6b5ab3e67356 +F src/func.c 00cd42119843ab0730fac5ae35fc09f344b08259 F src/global.c dcdb89f30b7aa531c5660030af106bc5bc48ef2e F src/hash.c 63d0ee752a3b92d4695b2b1f5259c4621b2cfebd F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4 @@ -1540,7 +1540,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 56ff72ab44288296efc99a608f7edc4346366a50 -R e9376a0e6f39c186396a7f16973b7c00 +P 0bdbe49c6d392c4c86a6c01219c9d91d150dea7d +R 08bfc0b07daab66cd8d9a28810d0ff87 U drh -Z a28c5cf75c694c3d54fc5cc0da0c3d0d +Z 6b0be7f43941c0b0506a1dbb2af0a32d diff --git a/manifest.uuid b/manifest.uuid index 23f172d71f..674c29ed2a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0bdbe49c6d392c4c86a6c01219c9d91d150dea7d \ No newline at end of file +a0971e713682a73d8c7c20511db256c20d2f6388 \ No newline at end of file diff --git a/src/func.c b/src/func.c index 37f7cd6152..1f80392ba9 100644 --- a/src/func.c +++ b/src/func.c @@ -204,13 +204,14 @@ static void instrFunc( if( typeHaystack==SQLITE_BLOB && typeNeedle==SQLITE_BLOB ){ zHaystack = sqlite3_value_blob(argv[0]); zNeedle = sqlite3_value_blob(argv[1]); + assert( zNeedle!=0 ); + assert( zHaystack!=0 || nHaystack==0 ); isText = 0; }else{ zHaystack = sqlite3_value_text(argv[0]); zNeedle = sqlite3_value_text(argv[1]); isText = 1; - if( zNeedle==0 ) return; - assert( zHaystack ); + if( zHaystack==0 || zNeedle==0 ) return; } while( nNeedle<=nHaystack && memcmp(zHaystack, zNeedle, nNeedle)!=0 ){ N++; From 3043b53222c647a5d971f6fce5df980aa71b637d Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 30 Dec 2016 17:40:14 +0000 Subject: [PATCH 1140/1484] Fix a crash that could occur following an OOM in the group_concat() function if the second argument is an SQLITE_BLOB value. FossilOrigin-Name: 14d855d2b2b5b3485e0673d11405db7266b34c6d --- manifest | 19 ++++++++------- manifest.uuid | 2 +- src/func.c | 2 +- test/gcfault.test | 56 ++++++++++++++++++++++++++++++++++++++++++++ test/instr.test | 9 +++++++ test/instrfault.test | 24 +++++++++++++++++++ 6 files changed, 101 insertions(+), 11 deletions(-) create mode 100644 test/gcfault.test diff --git a/manifest b/manifest index cb748fb07e..0b232f2882 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Strengthen\sthe\sdefense\sagainst\sOOM\sin\sthe\sinstr()\sSQL\sfunction. -D 2016-12-30T15:16:20.650 +C Fix\sa\scrash\sthat\scould\soccur\sfollowing\san\sOOM\sin\sthe\sgroup_concat()\sfunction\nif\sthe\ssecond\sargument\sis\san\sSQLITE_BLOB\svalue. +D 2016-12-30T17:40:14.373 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -344,7 +344,7 @@ F src/delete.c c8bc10d145c9666a34ae906250326fdaa8d58fa5 F src/expr.c a90e37bc542abe33890cafccacbf8a7db9cb5401 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 2e9aabe1aee76273aff8a84ee92c464e095400ae -F src/func.c 00cd42119843ab0730fac5ae35fc09f344b08259 +F src/func.c d8582ee91975975645f206db332c38f534b783ad F src/global.c dcdb89f30b7aa531c5660030af106bc5bc48ef2e F src/hash.c 63d0ee752a3b92d4695b2b1f5259c4621b2cfebd F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4 @@ -825,6 +825,7 @@ F test/fuzzdata5.db 9f0cdcc5c6e83b90cf9ae343bd07f684d2da2de7 F test/fuzzer1.test 3d4c4b7e547aba5e5511a2991e3e3d07166cfbb8 F test/fuzzer2.test a85ef814ce071293bce1ad8dffa217cbbaad4c14 F test/fuzzerfault.test 8792cd77fd5bce765b05d0c8e01b9edcf8af8536 +F test/gcfault.test dd28c228a38976d6336a3fc42d7e5f1ad060cb8c F test/genesis.tcl 1e2e2e8e5cc4058549a154ff1892fe5c9de19f98 F test/hexlit.test 4a6a5f46e3c65c4bf1fa06f5dd5a9507a5627751 F test/hidden.test 23c1393a79e846d68fd902d72c85d5e5dcf98711 @@ -865,8 +866,8 @@ F test/insert2.test 4d14b8f1b810a41995f6286b64a6943215d52208 F test/insert3.test 1b7db95a03ad9c5013fdf7d6722b6cd66ee55e30 F test/insert4.test a20432f1c0fbbcff8f11d0e6ab4acb8c9db58023 F test/insert5.test 394f96728d1258f406fe5f5aeb0aaf29487c39a6 -F test/instr.test 737bbf80685232033f3abedc6ae92f75860b5dd2 -F test/instrfault.test aa90b7c3486a069151b28384ae525644a1f79d51 +F test/instr.test 9a8802f28437d8ade53fedfc47b2ca599b4e48ba +F test/instrfault.test 0f870b218ea17cd477bb19ed330eecdb460dd53a F test/intarray.test 46d95b457916638c5d8b1af21fb174804b3acf8b F test/interrupt.test 16ea879ec728cb76414c148c5f24afd5d1f91054 F test/interrupt2.test e4408ca770a6feafbadb0801e54a0dcd1a8d108d @@ -1540,7 +1541,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 0bdbe49c6d392c4c86a6c01219c9d91d150dea7d -R 08bfc0b07daab66cd8d9a28810d0ff87 -U drh -Z 6b0be7f43941c0b0506a1dbb2af0a32d +P a0971e713682a73d8c7c20511db256c20d2f6388 +R b2119513a85656f5ab1ba46bed3bca22 +U dan +Z b8d94ab9819b45ed8f5f9b27f33e84f7 diff --git a/manifest.uuid b/manifest.uuid index 674c29ed2a..c1f02179dd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a0971e713682a73d8c7c20511db256c20d2f6388 \ No newline at end of file +14d855d2b2b5b3485e0673d11405db7266b34c6d \ No newline at end of file diff --git a/src/func.c b/src/func.c index 1f80392ba9..4afb25ad6f 100644 --- a/src/func.c +++ b/src/func.c @@ -1634,7 +1634,7 @@ static void groupConcatStep( zSep = ","; nSep = 1; } - if( nSep ) sqlite3StrAccumAppend(pAccum, zSep, nSep); + if( zSep ) sqlite3StrAccumAppend(pAccum, zSep, nSep); } zVal = (char*)sqlite3_value_text(argv[0]); nVal = sqlite3_value_bytes(argv[0]); diff --git a/test/gcfault.test b/test/gcfault.test new file mode 100644 index 0000000000..d54b78fafc --- /dev/null +++ b/test/gcfault.test @@ -0,0 +1,56 @@ +# 2016 December 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 regression tests for SQLite library. The +# focus of this file is testing OOM error handling within the built-in +# group_concat() function. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix gcfault + + +foreach {enc} { + utf16 + utf8 +} { + reset_db + sqlite3_db_config_lookaside db 0 0 0 + execsql "PRAGMA encoding = $enc" + + do_execsql_test 1.$enc.1 { + CREATE TABLE s(i, s); + INSERT INTO s VALUES(1, ',0123456789,'); + INSERT INTO s VALUES(2, X'2c303132333435363738392c'); + + CREATE TABLE e(e); + INSERT INTO e VALUES('v1'), ('v2'); + } {} + + do_faultsim_test 1.$enc.1 -faults oom* -body { + execsql { SELECT group_concat(e, (SELECT s FROM s WHERE i=1)) FROM e } + } + + do_faultsim_test 1.$enc.2 -faults oom-t* -body { + execsql { SELECT group_concat(e, (SELECT s FROM s WHERE i=2)) FROM e } + } + + do_faultsim_test 1.$enc.3 -faults oom-t* -prep { + set ::STMT [sqlite3_prepare db {SELECT group_concat(e, ?) FROM e} -1 dummy] + sqlite3_bind_text $::STMT 1 ",0123456789," 12 + } -body { + while { "SQLITE_ROW"==[sqlite3_step $::STMT] } { } + } -test { + sqlite3_finalize $::STMT + } +} + +finish_test diff --git a/test/instr.test b/test/instr.test index c8be4862b9..2caf3bce3b 100644 --- a/test/instr.test +++ b/test/instr.test @@ -248,4 +248,13 @@ do_execsql_test instr-1.62 { SELECT coalesce(instr(NULL,NULL), 999); } {999} +do_execsql_test instr-1.63 { + SELECT instr(X'', 'abc') +} 0 +do_execsql_test instr-1.64 { + CREATE TABLE x1(a, b); + INSERT INTO x1 VALUES(X'', 'abc'); + SELECT instr(a, b) FROM x1; +} 0 + finish_test diff --git a/test/instrfault.test b/test/instrfault.test index e2d93e742d..0ddb12c84b 100644 --- a/test/instrfault.test +++ b/test/instrfault.test @@ -29,6 +29,8 @@ foreach {enc} { utf16 } { reset_db + sqlite3_db_config_lookaside db 0 0 0 + execsql "PRAGMA encoding = $enc" do_execsql_test 1.$enc.1 { CREATE TABLE t1(n, h); @@ -63,6 +65,28 @@ foreach {enc} { faultsim_test_result {0 31} sqlite3_finalize $::stmt } + + do_faultsim_test 1.$enc.4 -faults oom-t* -prep { + set ::stmt [sqlite3_prepare_v2 db "SELECT instr(?, ?)" -1 dummy] + sqlite3_bind_blob $::stmt 1 $::HAYSTACK [string length $::HAYSTACK] + sqlite3_bind_text $::stmt 2 $::NEEDLE [string length $::NEEDLE] + } -body { + set rc [sqlite3_step $::stmt] + if {$rc=="SQLITE_NOMEM"} { error "out of memory" } + sqlite3_column_int $::stmt 0 + } -test { + faultsim_test_result {0 31} + sqlite3_finalize $::stmt + } + + do_execsql_test 1.$enc.5.0 { + CREATE TABLE h1(a, b); + INSERT INTO h1 VALUES('abcdefg%200hijkl', randomblob(200)); + INSERT INTO h1 SELECT b, a FROM h1; + } + do_faultsim_test 1.$enc.5 -faults oom-t* -body { + execsql { SELECT rowid FROM h1 WHERE instr(a,b) } + } -test {} } finish_test From eb25713e9151f0b7dfdb5eee45230cfe86d27f32 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 31 Dec 2016 14:33:05 +0000 Subject: [PATCH 1141/1484] Minor #include change to speedtest1.c so that it will compile under MSVC. FossilOrigin-Name: 8c28fde004678c85524770969eb001719b109179 --- manifest | 17 ++++++++++------- manifest.uuid | 2 +- test/speedtest1.c | 6 +++++- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 0b232f2882..99ed22e9a4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\scrash\sthat\scould\soccur\sfollowing\san\sOOM\sin\sthe\sgroup_concat()\sfunction\nif\sthe\ssecond\sargument\sis\san\sSQLITE_BLOB\svalue. -D 2016-12-30T17:40:14.373 +C Minor\s#include\schange\sto\sspeedtest1.c\sso\sthat\sit\swill\scompile\sunder\sMSVC. +D 2016-12-31T14:33:05.615 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -1127,7 +1127,7 @@ F test/speed3.test 694affeb9100526007436334cf7d08f3d74b85ef F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715 F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b -F test/speedtest1.c 0c92fd0db4cb778e3b6968db0ea859e28f077823 +F test/speedtest1.c 2feca857787efbcb8aefcc7b6fdc83455bcaa582 F test/spellfix.test f9c1f431e2c096c8775fec032952320c0e4700db F test/spellfix2.test dfc8f519a3fc204cb2dfa8b4f29821ae90f6f8c3 F test/spellfix3.test 0f9efaaa502a0e0a09848028518a6fb096c8ad33 @@ -1541,7 +1541,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a0971e713682a73d8c7c20511db256c20d2f6388 -R b2119513a85656f5ab1ba46bed3bca22 -U dan -Z b8d94ab9819b45ed8f5f9b27f33e84f7 +P 14d855d2b2b5b3485e0673d11405db7266b34c6d +R 4e28a4a24a558a17288e2b686fdb973b +T *branch * speedtest1 +T *sym-speedtest1 * +T -sym-trunk * +U drh +Z cb0ac3a36d5b0ce57e9784586a6bed06 diff --git a/manifest.uuid b/manifest.uuid index c1f02179dd..3005918343 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -14d855d2b2b5b3485e0673d11405db7266b34c6d \ No newline at end of file +8c28fde004678c85524770969eb001719b109179 \ No newline at end of file diff --git a/test/speedtest1.c b/test/speedtest1.c index d568aada0a..09aef40fdf 100644 --- a/test/speedtest1.c +++ b/test/speedtest1.c @@ -50,7 +50,11 @@ static const char zHelp[] = #include #include #include -#include +#ifndef _WIN32 +# include +#else +# include +#endif #define ISSPACE(X) isspace((unsigned char)(X)) #define ISDIGIT(X) isdigit((unsigned char)(X)) From aa430bfb00ecdff02fde7709c61b720fb789eac3 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 31 Dec 2016 18:37:50 +0000 Subject: [PATCH 1142/1484] In speedtest1.c, make the "--lookaside 0 0" option completely disable lookaside. FossilOrigin-Name: 52b99bcbf18f34196ec29f829c6af539e0d05524 --- manifest | 15 ++++++--------- manifest.uuid | 2 +- test/speedtest1.c | 4 ++-- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 99ed22e9a4..4cfc3df485 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Minor\s#include\schange\sto\sspeedtest1.c\sso\sthat\sit\swill\scompile\sunder\sMSVC. -D 2016-12-31T14:33:05.615 +C In\sspeedtest1.c,\smake\sthe\s"--lookaside\s0\s0"\soption\scompletely\sdisable\slookaside. +D 2016-12-31T18:37:50.583 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -1127,7 +1127,7 @@ F test/speed3.test 694affeb9100526007436334cf7d08f3d74b85ef F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715 F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b -F test/speedtest1.c 2feca857787efbcb8aefcc7b6fdc83455bcaa582 +F test/speedtest1.c 4e8ea6165046f02e1cfe0f4700256e91c981ec10 F test/spellfix.test f9c1f431e2c096c8775fec032952320c0e4700db F test/spellfix2.test dfc8f519a3fc204cb2dfa8b4f29821ae90f6f8c3 F test/spellfix3.test 0f9efaaa502a0e0a09848028518a6fb096c8ad33 @@ -1541,10 +1541,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 14d855d2b2b5b3485e0673d11405db7266b34c6d -R 4e28a4a24a558a17288e2b686fdb973b -T *branch * speedtest1 -T *sym-speedtest1 * -T -sym-trunk * +P 8c28fde004678c85524770969eb001719b109179 +R acfc06f8e952c64d6314c2acd8585e0b U drh -Z cb0ac3a36d5b0ce57e9784586a6bed06 +Z 4942b94b2df861c6d70e7d58a0ed32ea diff --git a/manifest.uuid b/manifest.uuid index 3005918343..670dc579e2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8c28fde004678c85524770969eb001719b109179 \ No newline at end of file +52b99bcbf18f34196ec29f829c6af539e0d05524 \ No newline at end of file diff --git a/test/speedtest1.c b/test/speedtest1.c index 09aef40fdf..02d55d5974 100644 --- a/test/speedtest1.c +++ b/test/speedtest1.c @@ -1378,7 +1378,7 @@ int main(int argc, char **argv){ int doIncrvac = 0; /* True for --incrvacuum */ const char *zJMode = 0; /* Journal mode */ const char *zKey = 0; /* Encryption key */ - int nLook = 0, szLook = 0; /* --lookaside configuration */ + int nLook = -1, szLook = 0; /* --lookaside configuration */ int noSync = 0; /* True for --nosync */ int pageSize = 0; /* Desired page size. 0 means default */ int nPCache = 0, szPCache = 0;/* --pcache configuration */ @@ -1562,7 +1562,7 @@ int main(int argc, char **argv){ rc = sqlite3_config(SQLITE_CONFIG_SCRATCH, pScratch, szScratch, nScratch); if( rc ) fatal_error("scratch configuration failed: %d\n", rc); } - if( nLook>0 ){ + if( nLook>=0 ){ sqlite3_config(SQLITE_CONFIG_LOOKASIDE, 0, 0); } #endif From e2b45d17894ab0a4974bd3488ef06e4f5461b7a1 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 31 Dec 2016 21:55:23 +0000 Subject: [PATCH 1143/1484] Add the --help and --all options to the wordcount test utility. FossilOrigin-Name: 18baeadfc89f6252e38dbc22904b11c5b56347ee --- manifest | 17 +- manifest.uuid | 2 +- test/wordcount.c | 472 ++++++++++++++++++++++++++++------------------- 3 files changed, 293 insertions(+), 198 deletions(-) diff --git a/manifest b/manifest index 0b232f2882..aa7a0793dc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\scrash\sthat\scould\soccur\sfollowing\san\sOOM\sin\sthe\sgroup_concat()\sfunction\nif\sthe\ssecond\sargument\sis\san\sSQLITE_BLOB\svalue. -D 2016-12-30T17:40:14.373 +C Add\sthe\s--help\sand\s--all\soptions\sto\sthe\swordcount\stest\sutility. +D 2016-12-31T21:55:23.877 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -1449,7 +1449,7 @@ F test/without_rowid3.test 2724c787a51a5dce09d078453a758117b4b728f1 F test/without_rowid4.test 4e08bcbaee0399f35d58b5581881e7a6243d458a F test/without_rowid5.test 89b1c587bd92a0590e440da33e7666bf4891572a F test/without_rowid6.test 1f99644e6508447fb050f73697350c7ceca3392e -F test/wordcount.c 97856eec21fd00d77da720007b1888c383f63dcf +F test/wordcount.c 06efb84b7c48a4973c2c24ea06c93d00bce24389 F test/zeroblob.test 3857870fe681b8185654414a9bccfde80b62a0fa F test/zerodamage.test e59a56443d6298ecf7435f618f0b27654f0c849e F tool/GetFile.cs a15e08acb5dd7539b75ba23501581d7c2b462cb5 @@ -1541,7 +1541,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a0971e713682a73d8c7c20511db256c20d2f6388 -R b2119513a85656f5ab1ba46bed3bca22 -U dan -Z b8d94ab9819b45ed8f5f9b27f33e84f7 +P 14d855d2b2b5b3485e0673d11405db7266b34c6d +R fe34c48679c60f27af86fde5a781f642 +T *branch * wordcount-enhancement +T *sym-wordcount-enhancement * +T -sym-trunk * +U drh +Z 8bab216aa01a50924e317f1b569b8185 diff --git a/manifest.uuid b/manifest.uuid index c1f02179dd..6e3956dcf2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -14d855d2b2b5b3485e0673d11405db7266b34c6d \ No newline at end of file +18baeadfc89f6252e38dbc22904b11c5b56347ee \ No newline at end of file diff --git a/test/wordcount.c b/test/wordcount.c index 5002918c5e..bc1d499f15 100644 --- a/test/wordcount.c +++ b/test/wordcount.c @@ -13,24 +13,6 @@ ** ** Option: ** -** --without-rowid Use a WITHOUT ROWID table to store the words. -** --insert Use INSERT mode (the default) -** --replace Use REPLACE mode -** --select Use SELECT mode -** --update Use UPDATE mode -** --delete Use DELETE mode -** --query Use QUERY mode -** --nocase Add the NOCASE collating sequence to the words. -** --trace Enable sqlite3_trace() output. -** --summary Show summary information on the collected data. -** --stats Show sqlite3_status() results at the end. -** --pagesize NNN Use a page size of NNN -** --cachesize NNN Use a cache size of NNN -** --commit NNN Commit after every NNN operations -** --nosync Use PRAGMA synchronous=OFF -** --journal MMMM Use PRAGMA journal_mode=MMMM -** --timer Time the operation of this program -** --tag NAME Tag all output using NAME. Use only stdout. ** ** Modes: ** @@ -81,8 +63,36 @@ #include #include #include "sqlite3.h" +#ifndef _WIN32 +# include +#else +# include +#endif #define ISALPHA(X) isalpha((unsigned char)(X)) +const char zHelp[] = +"Usage: wordcount [OPTIONS] DATABASE [INPUT]\n" +" --all Repeat the test for all test modes\n" +" --cachesize NNN Use a cache size of NNN\n" +" --commit NNN Commit after every NNN operations\n" +" --delete Use DELETE mode\n" +" --insert Use INSERT mode (the default)\n" +" --journal MMMM Use PRAGMA journal_mode=MMMM\n" +" --nocase Add the NOCASE collating sequence to the words.\n" +" --nosync Use PRAGMA synchronous=OFF\n" +" --pagesize NNN Use a page size of NNN\n" +" --query Use QUERY mode\n" +" --replace Use REPLACE mode\n" +" --select Use SELECT mode\n" +" --stats Show sqlite3_status() results at the end.\n" +" --summary Show summary information on the collected data.\n" +" --tag NAME Tag all output using NAME. Use only stdout.\n" +" --timer Time the operation of this program\n" +" --trace Enable sqlite3_trace() output.\n" +" --update Use UPDATE mode\n" +" --without-rowid Use a WITHOUT ROWID table to store the words.\n" +; + /* Output tag */ char *zTag = "--"; @@ -110,6 +120,12 @@ static void fatal_error(const char *zMsg, ...){ exit(1); } +/* Print a usage message and quit */ +static void usage(void){ + printf("%s",zHelp); + exit(0); +} + /* The sqlite3_trace() callback function */ static void traceCallback(void *NotUsed, const char *zSql){ printf("%s;\n", zSql); @@ -189,7 +205,6 @@ static void checksumFinalize(sqlite3_context *context){ } } - /* Define operating modes */ #define MODE_INSERT 0 #define MODE_REPLACE 1 @@ -197,12 +212,50 @@ static void checksumFinalize(sqlite3_context *context){ #define MODE_UPDATE 3 #define MODE_DELETE 4 #define MODE_QUERY 5 +#define MODE_COUNT 6 +#define MODE_ALL (-1) + +/* Mode names */ +static const char *azMode[] = { + "--insert", + "--replace", + "--select", + "--update", + "--delete", + "--query" +}; + +/* +** Determine if another iteration of the test is required. Return true +** if so. Return zero if all iterations have finished. +*/ +static int allLoop( + int iMode, /* The selected test mode */ + int *piLoopCnt, /* Iteration loop counter */ + int *piMode2, /* The test mode to use on the next iteration */ + int *pUseWithoutRowid /* Whether or not to use --without-rowid */ +){ + int i; + if( iMode!=MODE_ALL ){ + if( *piLoopCnt ) return 0; + *piMode2 = iMode; + *piLoopCnt = 1; + return 1; + } + if( (*piLoopCnt)>=MODE_COUNT*2 ) return 0; + i = (*piLoopCnt)++; + *pUseWithoutRowid = i&1; + *piMode2 = i>>1; + return 1; +} int main(int argc, char **argv){ const char *zFileToRead = 0; /* Input file. NULL for stdin */ const char *zDbName = 0; /* Name of the database file to create */ int useWithoutRowid = 0; /* True for --without-rowid */ int iMode = MODE_INSERT; /* One of MODE_xxxxx */ + int iMode2; /* Mode to use for current --all iteration */ + int iLoopCnt = 0; /* Which iteration when running --all */ int useNocase = 0; /* True for --nocase */ int doTrace = 0; /* True for --trace */ int showStats = 0; /* True for --stats */ @@ -226,7 +279,8 @@ int main(int argc, char **argv){ int iCur, iHiwtr; /* Statistics values, current and "highwater" */ FILE *pTimer = stderr; /* Output channel for the timer */ sqlite3_int64 sumCnt = 0; /* Sum in QUERY mode */ - sqlite3_int64 startTime; + sqlite3_int64 startTime; /* Time of start */ + sqlite3_int64 totalTime = 0; /* Total time */ char zInput[2000]; /* A single line of input */ /* Process command-line arguments */ @@ -248,6 +302,9 @@ int main(int argc, char **argv){ iMode = MODE_DELETE; }else if( strcmp(z,"query")==0 ){ iMode = MODE_QUERY; + }else if( strcmp(z,"all")==0 ){ + iMode = MODE_ALL; + showTimer = -99; }else if( strcmp(z,"nocase")==0 ){ useNocase = 1; }else if( strcmp(z,"trace")==0 ){ @@ -274,23 +331,30 @@ int main(int argc, char **argv){ }else if( strcmp(z,"tag")==0 && i0 && (nOp%commitInterval)==0 ){ + sqlite3_exec(db, "COMMIT; BEGIN IMMEDIATE", 0, 0, 0); } } - i = j-1; - - /* Increment the operation counter. Do a COMMIT if it is time. */ - nOp++; - if( commitInterval>0 && (nOp%commitInterval)==0 ){ - sqlite3_exec(db, "COMMIT; BEGIN IMMEDIATE", 0, 0, 0); + } + sqlite3_exec(db, "COMMIT", 0, 0, 0); + sqlite3_finalize(pInsert); pInsert = 0; + sqlite3_finalize(pUpdate); pUpdate = 0; + sqlite3_finalize(pSelect); pSelect = 0; + sqlite3_finalize(pDelete); pDelete = 0; + + if( iMode2==MODE_QUERY && iMode!=MODE_ALL ){ + printf("%s sum of cnt: %lld\n", zTag, sumCnt); + rc = sqlite3_prepare_v2(db,"SELECT sum(cnt*cnt) FROM wordcount", -1, + &pSelect, 0); + if( rc==SQLITE_OK && sqlite3_step(pSelect)==SQLITE_ROW ){ + printf("%s double-check: %lld\n", zTag,sqlite3_column_int64(pSelect,0)); + } + sqlite3_finalize(pSelect); + } + + + if( showTimer ){ + sqlite3_int64 elapseTime = realTime() - startTime; + totalTime += elapseTime; + fprintf(pTimer, "%3d.%03d wordcount", (int)(elapseTime/1000), + (int)(elapseTime%1000)); + if( iMode==MODE_ALL ){ + fprintf(pTimer, " %s%s\n", azMode[iMode2], + useWithoutRowid? " --without-rowid" : ""); + }else{ + for(i=1; i Date: Sun, 1 Jan 2017 12:44:07 +0000 Subject: [PATCH 1144/1484] Detect row-value comparison size mismatches even when the size of one operand is obscured by an unexpanded subquery. FossilOrigin-Name: 2c4d167ccd4be591487f404de9ee629fd484c8bf --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/expr.c | 5 ++++- test/rowvalue.test | 18 ++++++++++++++++++ 4 files changed, 31 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 0b232f2882..7cd8871212 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\scrash\sthat\scould\soccur\sfollowing\san\sOOM\sin\sthe\sgroup_concat()\sfunction\nif\sthe\ssecond\sargument\sis\san\sSQLITE_BLOB\svalue. -D 2016-12-30T17:40:14.373 +C Detect\srow-value\scomparison\ssize\smismatches\seven\swhen\sthe\ssize\sof\sone\noperand\sis\sobscured\sby\san\sunexpanded\ssubquery. +D 2017-01-01T12:44:07.208 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -341,7 +341,7 @@ F src/ctime.c 9f2296a4e5d26ebf0e0d95a0af4628f1ea694e7a F src/date.c dc3f1391d9297f8c748132813aaffcb117090d6e F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c c8bc10d145c9666a34ae906250326fdaa8d58fa5 -F src/expr.c a90e37bc542abe33890cafccacbf8a7db9cb5401 +F src/expr.c 3b662f58b50ba12c004b2d9bd8d3ff5fddbbae7f F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 2e9aabe1aee76273aff8a84ee92c464e095400ae F src/func.c d8582ee91975975645f206db332c38f534b783ad @@ -1035,7 +1035,7 @@ F test/rollbackfault.test 0e646aeab8840c399cfbfa43daab46fd609cf04a F test/rowallock.test 3f88ec6819489d0b2341c7a7528ae17c053ab7cc F test/rowhash.test 0bc1d31415e4575d10cacf31e1a66b5cc0f8be81 F test/rowid.test 5b7509f384f4f6fae1af3c8c104c8ca299fea18d -F test/rowvalue.test cacc565ed7e3ac467866af6705dd99020fdf2ee2 +F test/rowvalue.test 1701fb786188e9fb7934a7c155bd9cc587d9b677 F test/rowvalue2.test 060d238b7e5639a7c5630cb5e63e311b44efef2b F test/rowvalue3.test 3068f508753af69884b12125995f023da0dbb256 F test/rowvalue4.test 4b556d7de161a0dd8cff095c336e913986398bea @@ -1541,7 +1541,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a0971e713682a73d8c7c20511db256c20d2f6388 -R b2119513a85656f5ab1ba46bed3bca22 -U dan -Z b8d94ab9819b45ed8f5f9b27f33e84f7 +P 14d855d2b2b5b3485e0673d11405db7266b34c6d +R b92eb609c667e98735c96cb1ee09a168 +U drh +Z 9505a22a16b780a1bca3bac5d386a771 diff --git a/manifest.uuid b/manifest.uuid index c1f02179dd..cff1cb49da 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -14d855d2b2b5b3485e0673d11405db7266b34c6d \ No newline at end of file +2c4d167ccd4be591487f404de9ee629fd484c8bf \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index ecc6c7928b..b23f17983b 100644 --- a/src/expr.c +++ b/src/expr.c @@ -527,7 +527,10 @@ static void codeVectorCompare( u8 opx = op; int addrDone = sqlite3VdbeMakeLabel(v); - assert( nLeft==sqlite3ExprVectorSize(pRight) ); + if( nLeft!=sqlite3ExprVectorSize(pRight) ){ + sqlite3ErrorMsg(pParse, "row value misused"); + return; + } assert( pExpr->op==TK_EQ || pExpr->op==TK_NE || pExpr->op==TK_IS || pExpr->op==TK_ISNOT || pExpr->op==TK_LT || pExpr->op==TK_GT diff --git a/test/rowvalue.test b/test/rowvalue.test index 1e59bb5df9..affc455406 100644 --- a/test/rowvalue.test +++ b/test/rowvalue.test @@ -315,5 +315,23 @@ foreach {tn n sql} { do_catchsql_test 14.2.$tn $sql [list 1 $err] } +#-------------------------------------------------------------------------- +# Test for vector size mismatches concealed by unexpanded subqueries. +# +do_catchsql_test 15.1 { + DETACH (SELECT * FROM (SELECT 1,2))<3; +} {1 {row value misused}} +do_catchsql_test 15.2 { + UPDATE x1 SET a=(SELECT * FROM (SELECT b,2))<3; +} {1 {row value misused}} +do_catchsql_test 15.3 { + UPDATE x1 SET a=NULL WHERE a<(SELECT * FROM (SELECT b,2)); +} {1 {sub-select returns 2 columns - expected 1}} +do_catchsql_test 15.4 { + DELETE FROM x1 WHERE a<(SELECT * FROM (SELECT b,2)); +} {1 {sub-select returns 2 columns - expected 1}} +do_catchsql_test 15.5 { + INSERT INTO x1(a,b) VALUES(1,(SELECT * FROM (SELECT 1,2))<3); +} {1 {row value misused}} finish_test From e772bc7d303fbb36fc7c356220434551092864ee Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 2 Jan 2017 11:57:58 +0000 Subject: [PATCH 1145/1484] Version 3.16.0 FossilOrigin-Name: 04ac0b75b1716541b2b97704f4809cb7ef19cccf --- manifest | 11 +++++++---- manifest.uuid | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/manifest b/manifest index 7cd8871212..d4ebf16201 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Detect\srow-value\scomparison\ssize\smismatches\seven\swhen\sthe\ssize\sof\sone\noperand\sis\sobscured\sby\san\sunexpanded\ssubquery. -D 2017-01-01T12:44:07.208 +C Version\s3.16.0 +D 2017-01-02T11:57:58.484 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -1541,7 +1541,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 14d855d2b2b5b3485e0673d11405db7266b34c6d +P 2c4d167ccd4be591487f404de9ee629fd484c8bf R b92eb609c667e98735c96cb1ee09a168 +T +bgcolor * #d0c0ff +T +sym-release * +T +sym-version-3.16.0 * U drh -Z 9505a22a16b780a1bca3bac5d386a771 +Z d8ea167822373183dd9b5b971ee1941f diff --git a/manifest.uuid b/manifest.uuid index cff1cb49da..8830544683 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2c4d167ccd4be591487f404de9ee629fd484c8bf \ No newline at end of file +04ac0b75b1716541b2b97704f4809cb7ef19cccf \ No newline at end of file From 38eef3217237f7066e08763100a9147247d135df Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 2 Jan 2017 18:19:29 +0000 Subject: [PATCH 1146/1484] Avoid unnecessary calls to sqlite3BtreeEnterAll() and sqlite3BtreeLeaveAll() when no btree is using shared-cache. FossilOrigin-Name: cfb3158204628eb2fd170090a7f212df0e4ce6c9 --- manifest | 18 ++++++++---------- manifest.uuid | 2 +- src/attach.c | 1 + src/btmutex.c | 17 ++++++++++++++--- src/sqliteInt.h | 1 + 5 files changed, 25 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index a798f9f3b2..ce0e372345 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\s--all\soption\sto\sthe\swordcount\stest\sprogram.\nFix\sthe\sspeedtest1\stest\sprogram\sso\sthat\sit\sbuilds\son\sMSVC\sand\sso\sthat\nthe\s--lookaside\s0\s0\soption\sworks. -D 2017-01-02T12:20:15.832 +C Avoid\sunnecessary\scalls\sto\ssqlite3BtreeEnterAll()\sand\ssqlite3BtreeLeaveAll()\nwhen\sno\sbtree\sis\susing\sshared-cache. +D 2017-01-02T18:19:29.939 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -326,11 +326,11 @@ F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F src/alter.c 3b23977620ce9662ac54443f65b87ba996e36121 F src/analyze.c 3c4a63ff7a55faefecf6eb1589932fdbc06b2415 -F src/attach.c f6725410c184a80d8141b294fdf98a854c8a52b5 +F src/attach.c 8c476f8bd5d2afe11d925f890d30e527e5b0ce43 F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792 F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 -F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 +F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca F src/btree.c d2c100618784bd89c089fcef03ff6e789768ecae F src/btree.h 2349a588abcd7e0c04f984e15c5c777b61637583 F src/btreeInt.h 10c4b77c2fb399580babbcc7cf652ac10dba796e @@ -393,7 +393,7 @@ F src/shell.c 6095531aa900decdaa765e0f3993fba7153c92c1 F src/sqlite.h.in e8e2d108d82647f0a812fdb74accf91c1ec08ddc F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae -F src/sqliteInt.h 2075e22d50833ca2d9956d0b7a6bfb845ad05dd2 +F src/sqliteInt.h 888327a4317e1964a4e5a25bbfc120dbac8c4233 F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 @@ -1541,9 +1541,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 04ac0b75b1716541b2b97704f4809cb7ef19cccf 52b99bcbf18f34196ec29f829c6af539e0d05524 18baeadfc89f6252e38dbc22904b11c5b56347ee -R a26429a509129cc5febe3f6ebd513158 -T +closed 18baeadfc89f6252e38dbc22904b11c5b56347ee -T +closed 52b99bcbf18f34196ec29f829c6af539e0d05524 +P cb338f367e5408861bd7c0fbf74cebdbd8e3c515 +R 798126287b9302c9bcee15ee1adce328 U drh -Z d72e378c183574c55944435f3600ca45 +Z 06f058ccdbc97bbfa12f1395c017e654 diff --git a/manifest.uuid b/manifest.uuid index 69f43d2a9c..0596e2e009 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cb338f367e5408861bd7c0fbf74cebdbd8e3c515 \ No newline at end of file +cfb3158204628eb2fd170090a7f212df0e4ce6c9 \ No newline at end of file diff --git a/src/attach.c b/src/attach.c index 4fe97bacea..393c46ccb6 100644 --- a/src/attach.c +++ b/src/attach.c @@ -137,6 +137,7 @@ static void attachFunc( rc = sqlite3BtreeOpen(pVfs, zPath, db, &aNew->pBt, 0, flags); sqlite3_free( zPath ); db->nDb++; + db->skipBtreeMutex = 0; if( rc==SQLITE_CONSTRAINT ){ rc = SQLITE_ERROR; zErrDyn = sqlite3MPrintf(db, "database is already attached"); diff --git a/src/btmutex.c b/src/btmutex.c index c1ebff9604..ddffb67fa4 100644 --- a/src/btmutex.c +++ b/src/btmutex.c @@ -183,16 +183,24 @@ int sqlite3BtreeHoldsMutex(Btree *p){ ** two or more btrees in common both try to lock all their btrees ** at the same instant. */ -void sqlite3BtreeEnterAll(sqlite3 *db){ +static void SQLITE_NOINLINE btreeEnterAll(sqlite3 *db){ int i; + int skipOk = 1; Btree *p; assert( sqlite3_mutex_held(db->mutex) ); for(i=0; inDb; i++){ p = db->aDb[i].pBt; - if( p ) sqlite3BtreeEnter(p); + if( p && p->sharable ){ + sqlite3BtreeEnter(p); + skipOk = 0; + } } + db->skipBtreeMutex = skipOk; } -void sqlite3BtreeLeaveAll(sqlite3 *db){ +void sqlite3BtreeEnterAll(sqlite3 *db){ + if( db->skipBtreeMutex==0 ) btreeEnterAll(db); +} +static void SQLITE_NOINLINE btreeLeaveAll(sqlite3 *db){ int i; Btree *p; assert( sqlite3_mutex_held(db->mutex) ); @@ -201,6 +209,9 @@ void sqlite3BtreeLeaveAll(sqlite3 *db){ if( p ) sqlite3BtreeLeave(p); } } +void sqlite3BtreeLeaveAll(sqlite3 *db){ + if( db->skipBtreeMutex==0 ) btreeLeaveAll(db); +} #ifndef NDEBUG /* diff --git a/src/sqliteInt.h b/src/sqliteInt.h index d78d2072de..6a01029b87 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1296,6 +1296,7 @@ struct sqlite3 { u8 vtabOnConflict; /* Value to return for s3_vtab_on_conflict() */ u8 isTransactionSavepoint; /* True if the outermost savepoint is a TS */ u8 mTrace; /* zero or more SQLITE_TRACE flags */ + u8 skipBtreeMutex; /* True if no shared-cache backends */ int nextPagesize; /* Pagesize after VACUUM if >0 */ u32 magic; /* Magic number for detect library misuse */ int nChange; /* Value returned by sqlite3_changes() */ From 83a4f47d5716491b5f251989aa2555887b737b42 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 2 Jan 2017 18:40:03 +0000 Subject: [PATCH 1147/1484] Change SQLITE_DEFAULT_PCACHE_INITSZ from 100 to 20, which is experimentally determined to be slightly faster. FossilOrigin-Name: 12d9493cb29307aec65ceccc68e802e4d0f18112 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/sqliteInt.h | 5 ++++- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index ce0e372345..ceb0cb0d6e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sunnecessary\scalls\sto\ssqlite3BtreeEnterAll()\sand\ssqlite3BtreeLeaveAll()\nwhen\sno\sbtree\sis\susing\sshared-cache. -D 2017-01-02T18:19:29.939 +C Change\sSQLITE_DEFAULT_PCACHE_INITSZ\sfrom\s100\sto\s20,\swhich\sis\sexperimentally\ndetermined\sto\sbe\sslightly\sfaster. +D 2017-01-02T18:40:03.649 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -393,7 +393,7 @@ F src/shell.c 6095531aa900decdaa765e0f3993fba7153c92c1 F src/sqlite.h.in e8e2d108d82647f0a812fdb74accf91c1ec08ddc F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae -F src/sqliteInt.h 888327a4317e1964a4e5a25bbfc120dbac8c4233 +F src/sqliteInt.h 943ba94907e64b4325ff99583bdca166a8278331 F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 @@ -1541,7 +1541,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P cb338f367e5408861bd7c0fbf74cebdbd8e3c515 -R 798126287b9302c9bcee15ee1adce328 +P cfb3158204628eb2fd170090a7f212df0e4ce6c9 +R 3819f84452eff5f7c73531633215c7e7 U drh -Z 06f058ccdbc97bbfa12f1395c017e654 +Z 6e195a33776011226e5f03369118edd7 diff --git a/manifest.uuid b/manifest.uuid index 0596e2e009..dd50d9f15e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cfb3158204628eb2fd170090a7f212df0e4ce6c9 \ No newline at end of file +12d9493cb29307aec65ceccc68e802e4d0f18112 \ No newline at end of file diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 6a01029b87..655d51783d 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -587,9 +587,12 @@ ** pagecaches for each database connection. A positive number is the ** number of pages. A negative number N translations means that a buffer ** of -1024*N bytes is allocated and used for as many pages as it will hold. +** +** The default value of "20" was choosen to minimize the run-time of the +** speedtest1 test program with options: --shrink-memory --reprepare */ #ifndef SQLITE_DEFAULT_PCACHE_INITSZ -# define SQLITE_DEFAULT_PCACHE_INITSZ 100 +# define SQLITE_DEFAULT_PCACHE_INITSZ 20 #endif /* From 56d65cd7b98532849f1abe83fd6a1ba535b6adf5 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 2 Jan 2017 19:02:20 +0000 Subject: [PATCH 1148/1484] Provide the SQLITE_DEFAULT_LOOKASIDE compile-time option and make it's default value be 1200,100 (raised from 512,125 in the latest release). FossilOrigin-Name: 584da48f9e818f25134e0a62fb7e84f07019511f --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/global.c | 16 ++++++++++++++-- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index ceb0cb0d6e..e54d5c38a3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sSQLITE_DEFAULT_PCACHE_INITSZ\sfrom\s100\sto\s20,\swhich\sis\sexperimentally\ndetermined\sto\sbe\sslightly\sfaster. -D 2017-01-02T18:40:03.649 +C Provide\sthe\sSQLITE_DEFAULT_LOOKASIDE\scompile-time\soption\sand\smake\sit's\sdefault\nvalue\sbe\s1200,100\s(raised\sfrom\s512,125\sin\sthe\slatest\srelease). +D 2017-01-02T19:02:20.627 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -345,7 +345,7 @@ F src/expr.c 3b662f58b50ba12c004b2d9bd8d3ff5fddbbae7f F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 2e9aabe1aee76273aff8a84ee92c464e095400ae F src/func.c d8582ee91975975645f206db332c38f534b783ad -F src/global.c dcdb89f30b7aa531c5660030af106bc5bc48ef2e +F src/global.c 4a34512d82fc5aa13c802db06bcfff5e1d3de955 F src/hash.c 63d0ee752a3b92d4695b2b1f5259c4621b2cfebd F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4 F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da @@ -1541,7 +1541,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P cfb3158204628eb2fd170090a7f212df0e4ce6c9 -R 3819f84452eff5f7c73531633215c7e7 +P 12d9493cb29307aec65ceccc68e802e4d0f18112 +R 787ccf579b7b160280cc3d40eebe4332 U drh -Z 6e195a33776011226e5f03369118edd7 +Z 23c3cb021f3ef702d9251ac032d5cda4 diff --git a/manifest.uuid b/manifest.uuid index dd50d9f15e..b189a075f2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -12d9493cb29307aec65ceccc68e802e4d0f18112 \ No newline at end of file +584da48f9e818f25134e0a62fb7e84f07019511f \ No newline at end of file diff --git a/src/global.c b/src/global.c index ff6c7dba52..a105135561 100644 --- a/src/global.c +++ b/src/global.c @@ -169,6 +169,19 @@ const unsigned char sqlite3CtypeMap[256] = { # define SQLITE_STMTJRNL_SPILL (64*1024) #endif +/* +** The default lookaside-configuration, the format "SZ,N". SZ is the +** number of bytes in each lookaside slot (should be a multiple of 8) +** and N is the number of slots. The lookaside-configuration can be +** changed as start-time using sqlite3_config(SQLITE_CONFIG_LOOKASIDE) +** or at run-time for an individual database connection using +** sqlite3_db_config(db, SQLITE_DBCONFIG_LOOKASIDE); +*/ +#ifndef SQLITE_DEFAULT_LOOKASIDE +# define SQLITE_DEFAULT_LOOKASIDE 1200,100 +#endif + + /* ** The following singleton contains the global configuration for ** the SQLite library. @@ -181,8 +194,7 @@ SQLITE_WSD struct Sqlite3Config sqlite3Config = { SQLITE_ALLOW_COVERING_INDEX_SCAN, /* bUseCis */ 0x7ffffffe, /* mxStrlen */ 0, /* neverCorrupt */ - 512, /* szLookaside */ - 125, /* nLookaside */ + SQLITE_DEFAULT_LOOKASIDE, /* szLookaside, nLookaside */ SQLITE_STMTJRNL_SPILL, /* nStmtSpill */ {0,0,0,0,0,0,0,0}, /* m */ {0,0,0,0,0,0,0,0,0}, /* mutex */ From 63a49ce0b21debee5743168266e85de487c50dae Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 2 Jan 2017 19:10:14 +0000 Subject: [PATCH 1149/1484] Increase the version number to 3.17.0 for the next release cycle. FossilOrigin-Name: 16415b5aad445c9e4e849018b48538d74eec8944 --- VERSION | 2 +- configure | 19 ++++++++++--------- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 19 insertions(+), 18 deletions(-) diff --git a/VERSION b/VERSION index 1eeac129c5..3f67e25cea 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.16.0 +3.17.0 diff --git a/configure b/configure index 598b0dd7d9..be7c89143b 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.16.0. +# Generated by GNU Autoconf 2.69 for sqlite 3.17.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.16.0' -PACKAGE_STRING='sqlite 3.16.0' +PACKAGE_VERSION='3.17.0' +PACKAGE_STRING='sqlite 3.17.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.16.0 to adapt to many kinds of systems. +\`configure' configures sqlite 3.17.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.16.0:";; + short | recursive ) echo "Configuration of sqlite 3.17.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.16.0 +sqlite configure 3.17.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.16.0, which was +It was created by sqlite $as_me 3.17.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.16.0, which was +This file was extended by sqlite $as_me 3.17.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.16.0 +sqlite config.status 3.17.0 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" @@ -13829,3 +13829,4 @@ if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi + diff --git a/manifest b/manifest index e54d5c38a3..97114a6629 100644 --- a/manifest +++ b/manifest @@ -1,10 +1,10 @@ -C Provide\sthe\sSQLITE_DEFAULT_LOOKASIDE\scompile-time\soption\sand\smake\sit's\sdefault\nvalue\sbe\s1200,100\s(raised\sfrom\s512,125\sin\sthe\slatest\srelease). -D 2017-01-02T19:02:20.627 +C Increase\sthe\sversion\snumber\sto\s3.17.0\sfor\sthe\snext\srelease\scycle. +D 2017-01-02T19:10:14.396 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7 -F VERSION 661b3e6a778cfbfd7bdce8bbb1545b22f4b6f09e +F VERSION cddd8d88dc8202afa0ebc96da61fc4acbd1e96a5 F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 @@ -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 adbf03e758431e886bba5ab04b5adfbd496d7b24 x +F configure fcfa56d5d66668c9263dc007724f62acff06dc83 x F configure.ac 605173e829ab64514ed89f9b53d0da1739d7b0a0 F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad F doc/lemon.html b5a3c07d33ecb8e019ce8f7660fe2dbbad9d7977 @@ -1541,7 +1541,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 12d9493cb29307aec65ceccc68e802e4d0f18112 -R 787ccf579b7b160280cc3d40eebe4332 +P 584da48f9e818f25134e0a62fb7e84f07019511f +R d97b559f497d0a265e23fba942228550 U drh -Z 23c3cb021f3ef702d9251ac032d5cda4 +Z 24a7fb491cd5a499becb9d53b759e62e diff --git a/manifest.uuid b/manifest.uuid index b189a075f2..d36e63c320 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -584da48f9e818f25134e0a62fb7e84f07019511f \ No newline at end of file +16415b5aad445c9e4e849018b48538d74eec8944 \ No newline at end of file From 47073f62bf607208b00d19cd9059f2acb275778e Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 2 Jan 2017 22:36:32 +0000 Subject: [PATCH 1150/1484] Proposed fix for the row-value TRIGGER UPDATE problem described in ticket [8c9458e7]. FossilOrigin-Name: 61a442ea2ceec2cbd327dae0ff5214e1f3c69ec0 --- manifest | 15 +++++++++------ manifest.uuid | 2 +- src/expr.c | 17 ++++++++++++++++- 3 files changed, 26 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 97114a6629..96cb82ef9a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Increase\sthe\sversion\snumber\sto\s3.17.0\sfor\sthe\snext\srelease\scycle. -D 2017-01-02T19:10:14.396 +C Proposed\sfix\sfor\sthe\srow-value\sTRIGGER\sUPDATE\sproblem\sdescribed\sin\s\nticket\s[8c9458e7]. +D 2017-01-02T22:36:32.292 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -341,7 +341,7 @@ F src/ctime.c 9f2296a4e5d26ebf0e0d95a0af4628f1ea694e7a F src/date.c dc3f1391d9297f8c748132813aaffcb117090d6e F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c c8bc10d145c9666a34ae906250326fdaa8d58fa5 -F src/expr.c 3b662f58b50ba12c004b2d9bd8d3ff5fddbbae7f +F src/expr.c d438df533ef4dc803260527cee353d3d7df89ba3 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 2e9aabe1aee76273aff8a84ee92c464e095400ae F src/func.c d8582ee91975975645f206db332c38f534b783ad @@ -1541,7 +1541,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 584da48f9e818f25134e0a62fb7e84f07019511f -R d97b559f497d0a265e23fba942228550 +P 16415b5aad445c9e4e849018b48538d74eec8944 +R 0fc45eecde9c7ee8bfeff4a5566dee47 +T *branch * rowvalue-update-trigger +T *sym-rowvalue-update-trigger * +T -sym-trunk * U drh -Z 24a7fb491cd5a499becb9d53b759e62e +Z 681d88dc64ba5dba1f04ffca46eb2b75 diff --git a/manifest.uuid b/manifest.uuid index d36e63c320..2e2ff06ae3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -16415b5aad445c9e4e849018b48538d74eec8944 \ No newline at end of file +61a442ea2ceec2cbd327dae0ff5214e1f3c69ec0 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index b23f17983b..ebc9ca6b0c 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1088,7 +1088,7 @@ static int dupedExprStructSize(Expr *p, int flags){ assert( flags==EXPRDUP_REDUCE || flags==0 ); /* Only one flag value allowed */ assert( EXPR_FULLSIZE<=0xfff ); assert( (0xfff & (EP_Reduced|EP_TokenOnly))==0 ); - if( 0==flags ){ + if( 0==flags || p->op==TK_SELECT_COLUMN ){ nSize = EXPR_FULLSIZE; }else{ assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) ); @@ -1231,6 +1231,8 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int dupFlags, u8 **pzBuffer){ if( !ExprHasProperty(p, EP_TokenOnly|EP_Leaf) ){ if( pNew->op==TK_SELECT_COLUMN ){ pNew->pLeft = p->pLeft; + assert( p->iColumn==0 || p->pRight==0 ); + assert( p->pRight==0 || p->pRight==p->pLeft ); }else{ pNew->pLeft = sqlite3ExprDup(db, p->pLeft, 0); } @@ -1307,7 +1309,20 @@ ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p, int flags){ pOldItem = p->a; for(i=0; inExpr; i++, pItem++, pOldItem++){ Expr *pOldExpr = pOldItem->pExpr; + Expr *pNewExpr; pItem->pExpr = sqlite3ExprDup(db, pOldExpr, flags); + if( pOldExpr + && pOldExpr->op==TK_SELECT_COLUMN + && (pNewExpr = pItem->pExpr)!=0 + ){ + assert( pNewExpr->iColumn==0 || i>0 ); + if( pNewExpr->iColumn==0 ){ + assert( pOldExpr->pLeft==pOldExpr->pRight ); + pNewExpr->pLeft = pNewExpr->pRight; + }else if( pItem[-1].pExpr!=0 ){ + pNewExpr->pLeft = pItem[-1].pExpr->pLeft; + } + } pItem->zName = sqlite3DbStrDup(db, pOldItem->zName); pItem->zSpan = sqlite3DbStrDup(db, pOldItem->zSpan); pItem->sortOrder = pOldItem->sortOrder; From 3f50bb84f55e33df406bc69d2369a4bec223ef4e Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 2 Jan 2017 23:18:35 +0000 Subject: [PATCH 1151/1484] Put an ALWAYS() on an unreachable branch in the sqlite3ExprListDup() routine. FossilOrigin-Name: 2caaaab5e07f6b76d66fbe4e93a4b956937427d8 --- manifest | 15 ++++++--------- manifest.uuid | 2 +- src/expr.c | 3 ++- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 96cb82ef9a..4e23e69744 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Proposed\sfix\sfor\sthe\srow-value\sTRIGGER\sUPDATE\sproblem\sdescribed\sin\s\nticket\s[8c9458e7]. -D 2017-01-02T22:36:32.292 +C Put\san\sALWAYS()\son\san\sunreachable\sbranch\sin\sthe\ssqlite3ExprListDup()\sroutine. +D 2017-01-02T23:18:35.959 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -341,7 +341,7 @@ F src/ctime.c 9f2296a4e5d26ebf0e0d95a0af4628f1ea694e7a F src/date.c dc3f1391d9297f8c748132813aaffcb117090d6e F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c c8bc10d145c9666a34ae906250326fdaa8d58fa5 -F src/expr.c d438df533ef4dc803260527cee353d3d7df89ba3 +F src/expr.c c2be1c1ae369dc14ba9e76831466b3a494986872 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 2e9aabe1aee76273aff8a84ee92c464e095400ae F src/func.c d8582ee91975975645f206db332c38f534b783ad @@ -1541,10 +1541,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 16415b5aad445c9e4e849018b48538d74eec8944 -R 0fc45eecde9c7ee8bfeff4a5566dee47 -T *branch * rowvalue-update-trigger -T *sym-rowvalue-update-trigger * -T -sym-trunk * +P 61a442ea2ceec2cbd327dae0ff5214e1f3c69ec0 +R 979198fba9d353741bbbde77f8690ab1 U drh -Z 681d88dc64ba5dba1f04ffca46eb2b75 +Z 3d9af2cb6ce914fdb21ee160bd6a1c90 diff --git a/manifest.uuid b/manifest.uuid index 2e2ff06ae3..d239c8fce4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -61a442ea2ceec2cbd327dae0ff5214e1f3c69ec0 \ No newline at end of file +2caaaab5e07f6b76d66fbe4e93a4b956937427d8 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index ebc9ca6b0c..072c420780 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1311,6 +1311,7 @@ ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p, int flags){ Expr *pOldExpr = pOldItem->pExpr; Expr *pNewExpr; pItem->pExpr = sqlite3ExprDup(db, pOldExpr, flags); + assert( pItem->pExpr==0 || db->mallocFailed==0 ); if( pOldExpr && pOldExpr->op==TK_SELECT_COLUMN && (pNewExpr = pItem->pExpr)!=0 @@ -1319,7 +1320,7 @@ ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p, int flags){ if( pNewExpr->iColumn==0 ){ assert( pOldExpr->pLeft==pOldExpr->pRight ); pNewExpr->pLeft = pNewExpr->pRight; - }else if( pItem[-1].pExpr!=0 ){ + }else if( ALWAYS(pItem[-1].pExpr!=0) ){ pNewExpr->pLeft = pItem[-1].pExpr->pLeft; } } From 90a7eae84c2d6d67a5983e07cc84e0c7de7ec830 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 2 Jan 2017 23:43:03 +0000 Subject: [PATCH 1152/1484] Test cases for the row-value UPDATE TRIGGER fix. FossilOrigin-Name: b9b964373c89a491649f366ad7d70ae4d69b891d --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/rowvalue.test | 21 +++++++++++++++++++++ 3 files changed, 28 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 4e23e69744..b47ade3365 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Put\san\sALWAYS()\son\san\sunreachable\sbranch\sin\sthe\ssqlite3ExprListDup()\sroutine. -D 2017-01-02T23:18:35.959 +C Test\scases\sfor\sthe\srow-value\sUPDATE\sTRIGGER\sfix. +D 2017-01-02T23:43:03.976 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -1035,7 +1035,7 @@ F test/rollbackfault.test 0e646aeab8840c399cfbfa43daab46fd609cf04a F test/rowallock.test 3f88ec6819489d0b2341c7a7528ae17c053ab7cc F test/rowhash.test 0bc1d31415e4575d10cacf31e1a66b5cc0f8be81 F test/rowid.test 5b7509f384f4f6fae1af3c8c104c8ca299fea18d -F test/rowvalue.test 1701fb786188e9fb7934a7c155bd9cc587d9b677 +F test/rowvalue.test f4a60835c949ec4b8ddc15d78d8a9b412b805875 F test/rowvalue2.test 060d238b7e5639a7c5630cb5e63e311b44efef2b F test/rowvalue3.test 3068f508753af69884b12125995f023da0dbb256 F test/rowvalue4.test 4b556d7de161a0dd8cff095c336e913986398bea @@ -1541,7 +1541,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 61a442ea2ceec2cbd327dae0ff5214e1f3c69ec0 -R 979198fba9d353741bbbde77f8690ab1 +P 2caaaab5e07f6b76d66fbe4e93a4b956937427d8 +R 1083f74702d2e1110eb1d37d8553d935 U drh -Z 3d9af2cb6ce914fdb21ee160bd6a1c90 +Z d43bfd5db806552d45260c4ffdcc3bd0 diff --git a/manifest.uuid b/manifest.uuid index d239c8fce4..1c1f56c2bc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2caaaab5e07f6b76d66fbe4e93a4b956937427d8 \ No newline at end of file +b9b964373c89a491649f366ad7d70ae4d69b891d \ No newline at end of file diff --git a/test/rowvalue.test b/test/rowvalue.test index affc455406..eacfd37ba2 100644 --- a/test/rowvalue.test +++ b/test/rowvalue.test @@ -334,4 +334,25 @@ do_catchsql_test 15.5 { INSERT INTO x1(a,b) VALUES(1,(SELECT * FROM (SELECT 1,2))<3); } {1 {row value misused}} +#------------------------------------------------------------------------- +# Row-values used in UPDATE statements within TRIGGERs +# +# Ticket https://www.sqlite.org/src/info/8c9458e703666e1a +# +do_execsql_test 16.1 { + CREATE TABLE t16a(a,b,c); + INSERT INTO t16a VALUES(1,2,3); + CREATE TABLE t16b(x); + INSERT INTO t16b(x) VALUES(1); + CREATE TRIGGER t16r AFTER UPDATE ON t16b BEGIN + UPDATE t16a SET (a,b,c)=(SELECT new.x,new.x+1,new.x+2); + END; + UPDATE t16b SET x=7; + SELECT * FROM t16a; +} {7 8 9} +do_execsql_test 16.2 { + UPDATE t16b SET x=97; + SELECT * FROM t16a; +} {97 98 99} + finish_test From b163748e885af01e6eede23fff4e7aa7e8ee3620 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 3 Jan 2017 00:27:16 +0000 Subject: [PATCH 1153/1484] Improved assert()s on the sqlite3ExprListDup() logic for TK_SELECT_COLUMN. FossilOrigin-Name: 14da99d41f7968bf816203b4ae11c1f0d1ee0b5d --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/expr.c | 12 ++++++++---- 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index b47ade3365..d80ba5db3d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Test\scases\sfor\sthe\srow-value\sUPDATE\sTRIGGER\sfix. -D 2017-01-02T23:43:03.976 +C Improved\sassert()s\son\sthe\ssqlite3ExprListDup()\slogic\sfor\sTK_SELECT_COLUMN. +D 2017-01-03T00:27:16.468 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -341,7 +341,7 @@ F src/ctime.c 9f2296a4e5d26ebf0e0d95a0af4628f1ea694e7a F src/date.c dc3f1391d9297f8c748132813aaffcb117090d6e F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c c8bc10d145c9666a34ae906250326fdaa8d58fa5 -F src/expr.c c2be1c1ae369dc14ba9e76831466b3a494986872 +F src/expr.c e115097aa866a462051ac8430757638dc1d73f1c F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 2e9aabe1aee76273aff8a84ee92c464e095400ae F src/func.c d8582ee91975975645f206db332c38f534b783ad @@ -1541,7 +1541,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 2caaaab5e07f6b76d66fbe4e93a4b956937427d8 -R 1083f74702d2e1110eb1d37d8553d935 +P b9b964373c89a491649f366ad7d70ae4d69b891d +R b890811ca8348b8ceda7efec0ae53743 U drh -Z d43bfd5db806552d45260c4ffdcc3bd0 +Z f487608154c66bed79f05de2b11f93c4 diff --git a/manifest.uuid b/manifest.uuid index 1c1f56c2bc..313a7e2928 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b9b964373c89a491649f366ad7d70ae4d69b891d \ No newline at end of file +14da99d41f7968bf816203b4ae11c1f0d1ee0b5d \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 072c420780..6d4b48fae3 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1295,6 +1295,7 @@ ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p, int flags){ ExprList *pNew; struct ExprList_item *pItem, *pOldItem; int i; + Expr *pPriorSelectCol = 0; assert( db!=0 ); if( p==0 ) return 0; pNew = sqlite3DbMallocRawNN(db, sizeof(*pNew) ); @@ -1311,7 +1312,6 @@ ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p, int flags){ Expr *pOldExpr = pOldItem->pExpr; Expr *pNewExpr; pItem->pExpr = sqlite3ExprDup(db, pOldExpr, flags); - assert( pItem->pExpr==0 || db->mallocFailed==0 ); if( pOldExpr && pOldExpr->op==TK_SELECT_COLUMN && (pNewExpr = pItem->pExpr)!=0 @@ -1319,9 +1319,13 @@ ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p, int flags){ assert( pNewExpr->iColumn==0 || i>0 ); if( pNewExpr->iColumn==0 ){ assert( pOldExpr->pLeft==pOldExpr->pRight ); - pNewExpr->pLeft = pNewExpr->pRight; - }else if( ALWAYS(pItem[-1].pExpr!=0) ){ - pNewExpr->pLeft = pItem[-1].pExpr->pLeft; + pPriorSelectCol = pNewExpr->pLeft = pNewExpr->pRight; + }else{ + assert( i>0 ); + assert( pItem[-1].pExpr!=0 ); + assert( pNewExpr->iColumn==pItem[-1].pExpr->iColumn+1 ); + assert( pPriorSelectCol==pItem[-1].pExpr->pLeft ); + pNewExpr->pLeft = pPriorSelectCol; } } pItem->zName = sqlite3DbStrDup(db, pOldItem->zName); From 966e29116099869ccc3145ef5bd6e7ff1b1351ec Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 3 Jan 2017 02:58:01 +0000 Subject: [PATCH 1154/1484] Improvements to the way vector assignment size checking is done. Size checks when the RHS is a SELECT are deferred until after "*" wildcards are expanded. FossilOrigin-Name: 696219b11049930cdbc38f574820f4bbaf8621bb --- manifest | 15 +++++++++------ manifest.uuid | 2 +- src/expr.c | 36 ++++++++++++++++++++++++++++++------ 3 files changed, 40 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 8e4c629d8f..4c09a2f8c3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\srow-values\sin\sUPDATE\sstatements\swithin\sTRIGGER\sproblem\sidentified\nby\sticket\s[8c9458e7]. -D 2017-01-03T01:24:10.074 +C Improvements\sto\sthe\sway\svector\sassignment\ssize\schecking\sis\sdone.\s\sSize\schecks\nwhen\sthe\sRHS\sis\sa\sSELECT\sare\sdeferred\suntil\safter\s"*"\swildcards\sare\sexpanded. +D 2017-01-03T02:58:01.890 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -341,7 +341,7 @@ F src/ctime.c 9f2296a4e5d26ebf0e0d95a0af4628f1ea694e7a F src/date.c dc3f1391d9297f8c748132813aaffcb117090d6e F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c c8bc10d145c9666a34ae906250326fdaa8d58fa5 -F src/expr.c e115097aa866a462051ac8430757638dc1d73f1c +F src/expr.c 1df03961abc008b46154edca14bcbb38e7a3be90 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 2e9aabe1aee76273aff8a84ee92c464e095400ae F src/func.c d8582ee91975975645f206db332c38f534b783ad @@ -1541,7 +1541,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 16415b5aad445c9e4e849018b48538d74eec8944 14da99d41f7968bf816203b4ae11c1f0d1ee0b5d -R b890811ca8348b8ceda7efec0ae53743 +P f12ed3ce0bfb2d94c9baad23fdcbd816c72439a1 +R c698fe9c623530e3a7438be4c43f0c89 +T *branch * vector-size-check +T *sym-vector-size-check * +T -sym-trunk * U drh -Z 378863182d1610dbd664d17105221a9b +Z 0057cd8fc280f2ed6a1015934452d1e9 diff --git a/manifest.uuid b/manifest.uuid index 2c93085aae..9a1e5a3e10 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f12ed3ce0bfb2d94c9baad23fdcbd816c72439a1 \ No newline at end of file +696219b11049930cdbc38f574820f4bbaf8621bb \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 6d4b48fae3..6e615fe041 100644 --- a/src/expr.c +++ b/src/expr.c @@ -414,9 +414,10 @@ Expr *sqlite3ExprForVectorField( assert( pVector->flags & EP_xIsSelect ); /* The TK_SELECT_COLUMN Expr node: ** - ** pLeft: pVector containing TK_SELECT + ** pLeft: pVector containing TK_SELECT. Not deleted. ** pRight: not used. But recursively deleted. ** iColumn: Index of a column in pVector + ** iTable: 0 or the number of columns on the LHS of an assignment ** pLeft->iTable: First in an array of register holding result, or 0 ** if the result is not yet computed. ** @@ -1519,13 +1520,19 @@ ExprList *sqlite3ExprListAppendVector( ** exit prior to this routine being invoked */ if( NEVER(pColumns==0) ) goto vector_append_error; if( pExpr==0 ) goto vector_append_error; - n = sqlite3ExprVectorSize(pExpr); - if( pColumns->nId!=n ){ + + /* If the RHS is a vector, then we can immediately check to see that + ** the size of the RHS and LHS match. But if the RHS is a SELECT, + ** wildcards ("*") in the result set of the SELECT must be expanded before + ** we can do the size check, so defer the size check until code generation. + */ + if( pExpr->op!=TK_SELECT && pColumns->nId!=(n=sqlite3ExprVectorSize(pExpr)) ){ sqlite3ErrorMsg(pParse, "%d columns assigned %d values", pColumns->nId, n); goto vector_append_error; } - for(i=0; inId; i++){ Expr *pSubExpr = sqlite3ExprForVectorField(pParse, pExpr, i); pList = sqlite3ExprListAppend(pParse, pList, pSubExpr); if( pList ){ @@ -1534,11 +1541,20 @@ ExprList *sqlite3ExprListAppendVector( pColumns->a[i].zName = 0; } } + if( pExpr->op==TK_SELECT ){ if( pList && pList->a[iFirst].pExpr ){ - assert( pList->a[iFirst].pExpr->op==TK_SELECT_COLUMN ); - pList->a[iFirst].pExpr->pRight = pExpr; + Expr *pFirst = pList->a[iFirst].pExpr; + assert( pFirst->op==TK_SELECT_COLUMN ); + + /* Store the SELECT statement in pRight so it will be deleted when + ** sqlite3ExprListDelete() is called */ + pFirst->pRight = pExpr; pExpr = 0; + + /* Remember the size of the LHS in iTable so that we can check that + ** the RHS and LHS sizes match during code generation. */ + pFirst->iTable = pColumns->nId; } } @@ -3732,9 +3748,17 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ break; } case TK_SELECT_COLUMN: { + int n; if( pExpr->pLeft->iTable==0 ){ pExpr->pLeft->iTable = sqlite3CodeSubselect(pParse, pExpr->pLeft, 0, 0); } + assert( pExpr->iTable==0 || pExpr->pLeft->op==TK_SELECT ); + if( pExpr->iTable + && pExpr->iTable!=(n = sqlite3ExprVectorSize(pExpr->pLeft)) + ){ + sqlite3ErrorMsg(pParse, "%d columns assigned %d values", + pExpr->iTable, n); + } return pExpr->pLeft->iTable + pExpr->iColumn; } case TK_IN: { From f299edb0b01e5e2d47e00b3c91c95148e9e404af Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 3 Jan 2017 08:11:24 +0000 Subject: [PATCH 1155/1484] Add test cases for the fix in [f12ed3ce]. No problems discovered. FossilOrigin-Name: 548532fdcf84d565c17aed79a6b595e8b62a3ab4 --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/rowvalue.test | 39 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 47 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 8e4c629d8f..3b71f51466 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\srow-values\sin\sUPDATE\sstatements\swithin\sTRIGGER\sproblem\sidentified\nby\sticket\s[8c9458e7]. -D 2017-01-03T01:24:10.074 +C Add\stest\scases\sfor\sthe\sfix\sin\s[f12ed3ce].\sNo\sproblems\sdiscovered. +D 2017-01-03T08:11:24.174 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -1035,7 +1035,7 @@ F test/rollbackfault.test 0e646aeab8840c399cfbfa43daab46fd609cf04a F test/rowallock.test 3f88ec6819489d0b2341c7a7528ae17c053ab7cc F test/rowhash.test 0bc1d31415e4575d10cacf31e1a66b5cc0f8be81 F test/rowid.test 5b7509f384f4f6fae1af3c8c104c8ca299fea18d -F test/rowvalue.test f4a60835c949ec4b8ddc15d78d8a9b412b805875 +F test/rowvalue.test 44f3492f415cc9f374e8388a5eb61503eaca5230 F test/rowvalue2.test 060d238b7e5639a7c5630cb5e63e311b44efef2b F test/rowvalue3.test 3068f508753af69884b12125995f023da0dbb256 F test/rowvalue4.test 4b556d7de161a0dd8cff095c336e913986398bea @@ -1541,7 +1541,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 16415b5aad445c9e4e849018b48538d74eec8944 14da99d41f7968bf816203b4ae11c1f0d1ee0b5d -R b890811ca8348b8ceda7efec0ae53743 -U drh -Z 378863182d1610dbd664d17105221a9b +P f12ed3ce0bfb2d94c9baad23fdcbd816c72439a1 +R 298b63c32ca2b85940ec74df8ee62812 +U dan +Z 3afa5dd8c67c33d60fe04c75fb510b3b diff --git a/manifest.uuid b/manifest.uuid index 2c93085aae..0a908d9d8a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f12ed3ce0bfb2d94c9baad23fdcbd816c72439a1 \ No newline at end of file +548532fdcf84d565c17aed79a6b595e8b62a3ab4 \ No newline at end of file diff --git a/test/rowvalue.test b/test/rowvalue.test index eacfd37ba2..5f2701c733 100644 --- a/test/rowvalue.test +++ b/test/rowvalue.test @@ -355,4 +355,43 @@ do_execsql_test 16.2 { SELECT * FROM t16a; } {97 98 99} +do_execsql_test 16.3 { + CREATE TABLE t16c(a, b, c, d, e); + INSERT INTO t16c VALUES(1, 'a', 'b', 'c', 'd'); + CREATE TRIGGER t16c1 AFTER INSERT ON t16c BEGIN + UPDATE t16c SET (c, d) = (SELECT 'A', 'B'), (e, b) = (SELECT 'C', 'D') + WHERE a = new.a-1; + END; + + SELECT * FROM t16c; +} {1 a b c d} + +do_execsql_test 16.4 { + INSERT INTO t16c VALUES(2, 'w', 'x', 'y', 'z'); + SELECT * FROM t16c; +} { + 1 D A B C + 2 w x y z +} + +do_execsql_test 16.5 { + DROP TRIGGER t16c1; + PRAGMA recursive_triggers = 1; + INSERT INTO t16c VALUES(3, 'i', 'ii', 'iii', 'iv'); + CREATE TRIGGER t16c1 AFTER UPDATE ON t16c WHEN new.a>1 BEGIN + UPDATE t16c SET (e, d) = ( + SELECT b, c FROM t16c WHERE a = new.a-1 + ), (c, b) = ( + SELECT d, e FROM t16c WHERE a = new.a-1 + ) WHERE a = new.a-1; + END; + + UPDATE t16c SET a=a WHERE a=3; + SELECT * FROM t16c; +} { + 1 C B A D + 2 z y x w + 3 i ii iii iv +} + finish_test From b67343d075211fec9f67967903f95a7549464fed Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 3 Jan 2017 11:59:54 +0000 Subject: [PATCH 1156/1484] Fix a typo on a comment. No code changes. FossilOrigin-Name: abc27b6023e28a717bfa15648ddc152bda9c7b96 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/expr.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 3b71f51466..722fbd9e77 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\stest\scases\sfor\sthe\sfix\sin\s[f12ed3ce].\sNo\sproblems\sdiscovered. -D 2017-01-03T08:11:24.174 +C Fix\sa\stypo\son\sa\scomment.\s\sNo\scode\schanges. +D 2017-01-03T11:59:54.675 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -341,7 +341,7 @@ F src/ctime.c 9f2296a4e5d26ebf0e0d95a0af4628f1ea694e7a F src/date.c dc3f1391d9297f8c748132813aaffcb117090d6e F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c c8bc10d145c9666a34ae906250326fdaa8d58fa5 -F src/expr.c e115097aa866a462051ac8430757638dc1d73f1c +F src/expr.c b5f55c29553c762b5d3ae3768b95b5d4e8c0303f F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 2e9aabe1aee76273aff8a84ee92c464e095400ae F src/func.c d8582ee91975975645f206db332c38f534b783ad @@ -1541,7 +1541,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P f12ed3ce0bfb2d94c9baad23fdcbd816c72439a1 -R 298b63c32ca2b85940ec74df8ee62812 -U dan -Z 3afa5dd8c67c33d60fe04c75fb510b3b +P 548532fdcf84d565c17aed79a6b595e8b62a3ab4 +R d91f1b1dc02838ee4304e6741bf506fa +U drh +Z a4929362969af97c45531df857286989 diff --git a/manifest.uuid b/manifest.uuid index 0a908d9d8a..070a84a61c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -548532fdcf84d565c17aed79a6b595e8b62a3ab4 \ No newline at end of file +abc27b6023e28a717bfa15648ddc152bda9c7b96 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 6d4b48fae3..f01cba6fd7 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1502,7 +1502,7 @@ no_mem: ** Or: (a,b,c) = (SELECT x,y,z FROM ....) ** ** For each term of the vector assignment, append new entries to the -** expression list pList. In the case of a subquery on the LHS, append +** expression list pList. In the case of a subquery on the RHS, append ** TK_SELECT_COLUMN expressions. */ ExprList *sqlite3ExprListAppendVector( From 542407513770711e5dfc1c0194c3269df25b0f5c Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 3 Jan 2017 14:39:30 +0000 Subject: [PATCH 1157/1484] Put the affinity() function implementation inside of #ifdef SQLITE_DEBUG. FossilOrigin-Name: f778f58ae4ea3e16f51b94591a2c1e563dcb0cde --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/expr.c | 2 ++ src/func.c | 2 ++ 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 4333aa5ff1..cfdb40bc31 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sall\sthe\slatest\schanges\sfrom\strunk. -D 2017-01-03T14:30:28.465 +C Put\sthe\saffinity()\sfunction\simplementation\sinside\sof\s#ifdef\sSQLITE_DEBUG. +D 2017-01-03T14:39:30.860 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -341,10 +341,10 @@ F src/ctime.c 9f2296a4e5d26ebf0e0d95a0af4628f1ea694e7a F src/date.c dc3f1391d9297f8c748132813aaffcb117090d6e F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c c8bc10d145c9666a34ae906250326fdaa8d58fa5 -F src/expr.c 3cf3bb3b5de2494d0f7b30c999984fd2918b4ef5 +F src/expr.c 449cbb8b9857ff8eb685b72555086818a178858c F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 2e9aabe1aee76273aff8a84ee92c464e095400ae -F src/func.c 04350956b6e45800f71e02e0ffeae2a35aff2634 +F src/func.c c67273e1ec08abbdcc14c189892a3ff6eeece86b F src/global.c 4a34512d82fc5aa13c802db06bcfff5e1d3de955 F src/hash.c 63d0ee752a3b92d4695b2b1f5259c4621b2cfebd F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4 @@ -1541,7 +1541,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 57e40e1cb1bcd3dd8473d2fdeecc9c7ff3d6192b 36944be6be5c42096f5da84187ff203af26b08ae -R e122a5b19a6af1a9b03b2065c0a3a3fe +P c27cd8a8127b81d3176f6a5b9915c9b3c69574fb +R 4de702ec2e06c17a2db8893398d4255a U drh -Z 5f2d809963b79f73c941be08881302f0 +Z f4b6e6ab3f6bbd45ad65d1c563858923 diff --git a/manifest.uuid b/manifest.uuid index 34459e334c..917453ab54 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c27cd8a8127b81d3176f6a5b9915c9b3c69574fb \ No newline at end of file +f778f58ae4ea3e16f51b94591a2c1e563dcb0cde \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 6497d39cf9..3bb0ca03f1 100644 --- a/src/expr.c +++ b/src/expr.c @@ -3660,6 +3660,7 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ return sqlite3ExprCodeTarget(pParse, pFarg->a[0].pExpr, target); } +#ifdef SQLITE_DEBUG /* The AFFINITY() function evaluates to a string that describes ** the type affinity of the argument. This is used for testing of ** the SQLite type logic. @@ -3673,6 +3674,7 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ aff ? azAff[aff-SQLITE_AFF_BLOB] : "none"); return target; } +#endif for(i=0; ia[i].pExpr) ){ diff --git a/src/func.c b/src/func.c index e156e2c9d3..885725bc6b 100644 --- a/src/func.c +++ b/src/func.c @@ -1775,7 +1775,9 @@ void sqlite3RegisterBuiltinFunctions(void){ FUNCTION2(unlikely, 1, 0, 0, noopFunc, SQLITE_FUNC_UNLIKELY), FUNCTION2(likelihood, 2, 0, 0, noopFunc, SQLITE_FUNC_UNLIKELY), FUNCTION2(likely, 1, 0, 0, noopFunc, SQLITE_FUNC_UNLIKELY), +#ifdef SQLITE_DEBUG FUNCTION2(affinity, 1, 0, 0, noopFunc, SQLITE_FUNC_AFFINITY), +#endif FUNCTION(ltrim, 1, 1, 0, trimFunc ), FUNCTION(ltrim, 2, 1, 0, trimFunc ), FUNCTION(rtrim, 1, 2, 0, trimFunc ), From 4a47761e0dfa3d62feae632d90c6fb22d1d0df3f Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 3 Jan 2017 17:33:43 +0000 Subject: [PATCH 1158/1484] Make use of the __buildin_OP_overflow() functions from GCC when doing 64-bit signed integer arithmetic. FossilOrigin-Name: 82cbebb8ee4484f13e5f48d305e20e73063f273e --- manifest | 16 +++++++++------- manifest.uuid | 2 +- src/util.c | 15 +++++++++++++++ 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index cff39d7dca..7ec2dbb8d2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sexperimental\saffinity()\sSQL\sfunction\swhen\sSQLITE_DEBUG\sis\sdefined. -D 2017-01-03T14:45:35.313 +C Make\suse\sof\sthe\s__buildin_OP_overflow()\sfunctions\sfrom\sGCC\swhen\sdoing\n64-bit\ssigned\sinteger\sarithmetic. +D 2017-01-03T17:33:43.523 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -453,7 +453,7 @@ F src/treeview.c 4e44ade3bfe59d82005039f72e09333ce2b4162c F src/trigger.c c9f0810043b265724fdb1bdd466894f984dfc182 F src/update.c 1da7c462110bffed442a42884cb0d528c1db46d8 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c -F src/util.c 1534060bc034cdc51381c040c8bd6252dbcb64c9 +F src/util.c 8c3d2aa11bacd984caf8067ed5b857de3fb53b81 F src/vacuum.c 33c174b28886b2faf26e503b5a49a1c01a9b1c16 F src/vdbe.c 88bd6c32b333580d2661ac3afe33369757fb1522 F src/vdbe.h 50ee139f9c68fff91be1d717ed3a6abbd496919c @@ -1541,8 +1541,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 36944be6be5c42096f5da84187ff203af26b08ae f778f58ae4ea3e16f51b94591a2c1e563dcb0cde -R 4de702ec2e06c17a2db8893398d4255a -T +closed f778f58ae4ea3e16f51b94591a2c1e563dcb0cde +P bed0eaa5f50112e64fc97a2afdc9d56cf8f5026a +R 082101997f3f378fcfea5fe538ad3ab9 +T *branch * gnu-safe-math +T *sym-gnu-safe-math * +T -sym-trunk * U drh -Z ab80b4c4af6ffab14c74e7e3612d1ec8 +Z 54548663084083c7fef96c176f102936 diff --git a/manifest.uuid b/manifest.uuid index 1ef467555f..f1ed017db3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bed0eaa5f50112e64fc97a2afdc9d56cf8f5026a \ No newline at end of file +82cbebb8ee4484f13e5f48d305e20e73063f273e \ No newline at end of file diff --git a/src/util.c b/src/util.c index b9684c6c01..4a2266ee69 100644 --- a/src/util.c +++ b/src/util.c @@ -1279,6 +1279,10 @@ int sqlite3SafetyCheckSickOrOk(sqlite3 *db){ ** overflow, leave *pA unchanged and return 1. */ int sqlite3AddInt64(i64 *pA, i64 iB){ +#if !defined(SQLITE_DISABLE_INTRINSIC) \ + && defined(__GNUC__) && GCC_VERSION>=5004000 + return __builtin_add_overflow(*pA, iB, pA); +#else i64 iA = *pA; testcase( iA==0 ); testcase( iA==1 ); testcase( iB==-1 ); testcase( iB==0 ); @@ -1293,8 +1297,13 @@ int sqlite3AddInt64(i64 *pA, i64 iB){ } *pA += iB; return 0; +#endif } int sqlite3SubInt64(i64 *pA, i64 iB){ +#if !defined(SQLITE_DISABLE_INTRINSIC) \ + && defined(__GNUC__) && GCC_VERSION>=5004000 + return __builtin_sub_overflow(*pA, iB, pA); +#else testcase( iB==SMALLEST_INT64+1 ); if( iB==SMALLEST_INT64 ){ testcase( (*pA)==(-1) ); testcase( (*pA)==0 ); @@ -1304,8 +1313,13 @@ int sqlite3SubInt64(i64 *pA, i64 iB){ }else{ return sqlite3AddInt64(pA, -iB); } +#endif } int sqlite3MulInt64(i64 *pA, i64 iB){ +#if !defined(SQLITE_DISABLE_INTRINSIC) \ + && defined(__GNUC__) && GCC_VERSION>=5004000 + return __builtin_mul_overflow(*pA, iB, pA); +#else i64 iA = *pA; if( iB>0 ){ if( iA>LARGEST_INT64/iB ) return 1; @@ -1321,6 +1335,7 @@ int sqlite3MulInt64(i64 *pA, i64 iB){ } *pA = iA*iB; return 0; +#endif } /* From eea46aeafc8ae4ca1f4a86961ac1132cb528a00e Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 3 Jan 2017 18:05:04 +0000 Subject: [PATCH 1159/1484] Use the GCC built-in __sync_fetch_and_sub() to make the sqlite3StatusDown() routine atomic, and thereby avoid some mutexing. FossilOrigin-Name: f69ce75b3d94331fdbfa2f3a27d61db24c285d2b --- manifest | 19 ++++++++----------- manifest.uuid | 2 +- src/malloc.c | 8 ++++++++ src/sqliteInt.h | 9 +++++++++ src/status.c | 7 ++++++- 5 files changed, 32 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 7ec2dbb8d2..2d378a63aa 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\suse\sof\sthe\s__buildin_OP_overflow()\sfunctions\sfrom\sGCC\swhen\sdoing\n64-bit\ssigned\sinteger\sarithmetic. -D 2017-01-03T17:33:43.523 +C Use\sthe\sGCC\sbuilt-in\s__sync_fetch_and_sub()\sto\smake\sthe\ssqlite3StatusDown()\nroutine\satomic,\sand\sthereby\savoid\ssome\smutexing. +D 2017-01-03T18:05:04.175 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -354,7 +354,7 @@ F src/insert.c 91ba5d0143e66479081536ebbaff1850ec9f57d9 F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e F src/loadext.c 5d6642d141c07d366e43d359e94ec9de47add41d F src/main.c e207b81542d13b9f13d61e78ca441f9781f055b0 -F src/malloc.c f3fad34cd570022abca558c573f1761fb09a8212 +F src/malloc.c 254c1cf31c2f3783bfe49dc8e7adde3c850f2289 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3 @@ -393,9 +393,9 @@ F src/shell.c 6095531aa900decdaa765e0f3993fba7153c92c1 F src/sqlite.h.in e8e2d108d82647f0a812fdb74accf91c1ec08ddc F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae -F src/sqliteInt.h 2c22eae7a29f17e0dfee9737d4844d7c08cc38cd +F src/sqliteInt.h ae113e82230109e0964c3d93efed55700d8eec5e F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 -F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 +F src/status.c 56174fdb52d1e8a0e9f3976e82d06a5cd0a1c2c3 F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 F src/tclsqlite.c 205c66b9b81d97978a155caa3ef5be9c4de2b174 F src/test1.c 8a98191a1da8e100f77cdb5cc716df67d405028d @@ -1541,10 +1541,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P bed0eaa5f50112e64fc97a2afdc9d56cf8f5026a -R 082101997f3f378fcfea5fe538ad3ab9 -T *branch * gnu-safe-math -T *sym-gnu-safe-math * -T -sym-trunk * +P 82cbebb8ee4484f13e5f48d305e20e73063f273e +R 799d9858a7a6a1551985c372ac93d54d U drh -Z 54548663084083c7fef96c176f102936 +Z efd83d8962e4e3c856ce381388686c40 diff --git a/manifest.uuid b/manifest.uuid index f1ed017db3..0aa7e0c273 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -82cbebb8ee4484f13e5f48d305e20e73063f273e \ No newline at end of file +f69ce75b3d94331fdbfa2f3a27d61db24c285d2b \ No newline at end of file diff --git a/src/malloc.c b/src/malloc.c index 84191c78a1..5f2f406425 100644 --- a/src/malloc.c +++ b/src/malloc.c @@ -376,12 +376,16 @@ void sqlite3ScratchFree(void *p){ sqlite3MemdebugSetType(p, MEMTYPE_HEAP); if( sqlite3GlobalConfig.bMemstat ){ int iSize = sqlite3MallocSize(p); +#ifndef SQLITE_ATOMIC_STATUS_DOWN sqlite3_mutex_enter(mem0.mutex); +#endif sqlite3StatusDown(SQLITE_STATUS_SCRATCH_OVERFLOW, iSize); sqlite3StatusDown(SQLITE_STATUS_MEMORY_USED, iSize); sqlite3StatusDown(SQLITE_STATUS_MALLOC_COUNT, 1); sqlite3GlobalConfig.m.xFree(p); +#ifndef SQLITE_ATOMIC_STATUS_DOWN sqlite3_mutex_leave(mem0.mutex); +#endif }else{ sqlite3GlobalConfig.m.xFree(p); } @@ -440,11 +444,15 @@ void sqlite3_free(void *p){ assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) ); if( sqlite3GlobalConfig.bMemstat ){ +#ifndef SQLITE_ATOMIC_STATUS_DOWN sqlite3_mutex_enter(mem0.mutex); +#endif sqlite3StatusDown(SQLITE_STATUS_MEMORY_USED, sqlite3MallocSize(p)); sqlite3StatusDown(SQLITE_STATUS_MALLOC_COUNT, 1); sqlite3GlobalConfig.m.xFree(p); +#ifndef SQLITE_ATOMIC_STATUS_DOWN sqlite3_mutex_leave(mem0.mutex); +#endif }else{ sqlite3GlobalConfig.m.xFree(p); } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 31cedf40e7..c034d6841e 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -228,6 +228,15 @@ # define SQLITE_NOINLINE #endif +/* +** The SQLITE_ATOMIC_STATUS_DOWN macro is defined if and only if +** the sqlite3StatusDown() function is threadsafe. +*/ +#if !defined(SQLITE_DISABLE_INTRINSIC) \ + && defined(__GNUC__) && GCC_VERSION>=4004000 +# define SQLITE_ATOMIC_STATUS_DOWN 1 +#endif + /* ** Make sure that the compiler intrinsics we desire are enabled when ** compiling with an appropriate version of MSVC unless prevented by diff --git a/src/status.c b/src/status.c index 24dcad4572..5e8fbc2ee2 100644 --- a/src/status.c +++ b/src/status.c @@ -100,11 +100,16 @@ void sqlite3StatusUp(int op, int N){ void sqlite3StatusDown(int op, int N){ wsdStatInit; assert( N>=0 ); + assert( op>=0 && op=4004000 + (void)__sync_fetch_and_sub(&wsdStat.nowValue[op], N); +#else assert( op>=0 && op=0 && op Date: Tue, 3 Jan 2017 20:01:24 +0000 Subject: [PATCH 1160/1484] Use the CLANG_VERSION macro to control clang-specific features. FossilOrigin-Name: f8ebeec211483503e135104ef977b3c384a1d789 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/sqliteInt.h | 10 +++++++++- src/status.c | 2 +- src/util.c | 10 +++++----- 5 files changed, 24 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index 2d378a63aa..4393faecba 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Use\sthe\sGCC\sbuilt-in\s__sync_fetch_and_sub()\sto\smake\sthe\ssqlite3StatusDown()\nroutine\satomic,\sand\sthereby\savoid\ssome\smutexing. -D 2017-01-03T18:05:04.175 +C Use\sthe\sCLANG_VERSION\smacro\sto\scontrol\sclang-specific\sfeatures. +D 2017-01-03T20:01:24.105 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -393,9 +393,9 @@ F src/shell.c 6095531aa900decdaa765e0f3993fba7153c92c1 F src/sqlite.h.in e8e2d108d82647f0a812fdb74accf91c1ec08ddc F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae -F src/sqliteInt.h ae113e82230109e0964c3d93efed55700d8eec5e +F src/sqliteInt.h 898cfcd9e0a40df15258cd86255bf9bee411e36d F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 -F src/status.c 56174fdb52d1e8a0e9f3976e82d06a5cd0a1c2c3 +F src/status.c 1b1e64fbce135bc178a6481433422a32f433ba37 F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 F src/tclsqlite.c 205c66b9b81d97978a155caa3ef5be9c4de2b174 F src/test1.c 8a98191a1da8e100f77cdb5cc716df67d405028d @@ -453,7 +453,7 @@ F src/treeview.c 4e44ade3bfe59d82005039f72e09333ce2b4162c F src/trigger.c c9f0810043b265724fdb1bdd466894f984dfc182 F src/update.c 1da7c462110bffed442a42884cb0d528c1db46d8 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c -F src/util.c 8c3d2aa11bacd984caf8067ed5b857de3fb53b81 +F src/util.c a88b0466fddf445ce752226d4698ca3faada620a F src/vacuum.c 33c174b28886b2faf26e503b5a49a1c01a9b1c16 F src/vdbe.c 88bd6c32b333580d2661ac3afe33369757fb1522 F src/vdbe.h 50ee139f9c68fff91be1d717ed3a6abbd496919c @@ -1541,7 +1541,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 82cbebb8ee4484f13e5f48d305e20e73063f273e -R 799d9858a7a6a1551985c372ac93d54d +P f69ce75b3d94331fdbfa2f3a27d61db24c285d2b +R 576384b00d5b84002b3bf9bfa5fd1c23 U drh -Z efd83d8962e4e3c856ce381388686c40 +Z df7fbae7b850ad1f1ec95f7decb0f63b diff --git a/manifest.uuid b/manifest.uuid index 0aa7e0c273..70bf8dddad 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f69ce75b3d94331fdbfa2f3a27d61db24c285d2b \ No newline at end of file +f8ebeec211483503e135104ef977b3c384a1d789 \ No newline at end of file diff --git a/src/sqliteInt.h b/src/sqliteInt.h index c034d6841e..e57453e679 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -110,6 +110,14 @@ # define GCC_VERSION 0 #endif +/* What version of CLANG is being used. 0 means GCC is not being used */ +#ifdef __clang__ +# define CLANG_VERSION \ + (__clang_major__*1000000+__clang_minor__*1000+__clang_patchlevel__) +#else +# define CLANG_VERSION 0 +#endif + /* Needed for various definitions... */ #if defined(__GNUC__) && !defined(_GNU_SOURCE) # define _GNU_SOURCE @@ -233,7 +241,7 @@ ** the sqlite3StatusDown() function is threadsafe. */ #if !defined(SQLITE_DISABLE_INTRINSIC) \ - && defined(__GNUC__) && GCC_VERSION>=4004000 + && (GCC_VERSION>=4004000 || CLANG_VERSION>=3000000) # define SQLITE_ATOMIC_STATUS_DOWN 1 #endif diff --git a/src/status.c b/src/status.c index 5e8fbc2ee2..f36f36724d 100644 --- a/src/status.c +++ b/src/status.c @@ -102,7 +102,7 @@ void sqlite3StatusDown(int op, int N){ assert( N>=0 ); assert( op>=0 && op=4004000 + && (GCC_VERSION>=4004000 || CLANG_VERSION>=3000000) (void)__sync_fetch_and_sub(&wsdStat.nowValue[op], N); #else assert( op>=0 && op=4003000 + && (GCC_VERSION>=4003000 || CLANG_VERSION>=3000000) u32 x; memcpy(&x,p,4); return __builtin_bswap32(x); @@ -1159,7 +1159,7 @@ void sqlite3Put4byte(unsigned char *p, u32 v){ #if SQLITE_BYTEORDER==4321 memcpy(p,&v,4); #elif SQLITE_BYTEORDER==1234 && !defined(SQLITE_DISABLE_INTRINSIC) \ - && defined(__GNUC__) && GCC_VERSION>=4003000 + && (GCC_VERSION>=4003000 || CLANG_VERSION>=3000000) u32 x = __builtin_bswap32(v); memcpy(p,&x,4); #elif SQLITE_BYTEORDER==1234 && !defined(SQLITE_DISABLE_INTRINSIC) \ @@ -1280,7 +1280,7 @@ int sqlite3SafetyCheckSickOrOk(sqlite3 *db){ */ int sqlite3AddInt64(i64 *pA, i64 iB){ #if !defined(SQLITE_DISABLE_INTRINSIC) \ - && defined(__GNUC__) && GCC_VERSION>=5004000 + && (GCC_VERSION>=5004000 || CLANG_VERSION>=4000000) return __builtin_add_overflow(*pA, iB, pA); #else i64 iA = *pA; @@ -1301,7 +1301,7 @@ int sqlite3AddInt64(i64 *pA, i64 iB){ } int sqlite3SubInt64(i64 *pA, i64 iB){ #if !defined(SQLITE_DISABLE_INTRINSIC) \ - && defined(__GNUC__) && GCC_VERSION>=5004000 + && (GCC_VERSION>=5004000 || CLANG_VERSION>=4000000) return __builtin_sub_overflow(*pA, iB, pA); #else testcase( iB==SMALLEST_INT64+1 ); @@ -1317,7 +1317,7 @@ int sqlite3SubInt64(i64 *pA, i64 iB){ } int sqlite3MulInt64(i64 *pA, i64 iB){ #if !defined(SQLITE_DISABLE_INTRINSIC) \ - && defined(__GNUC__) && GCC_VERSION>=5004000 + && (GCC_VERSION>=5004000 || CLANG_VERSION>=4000000) return __builtin_mul_overflow(*pA, iB, pA); #else i64 iA = *pA; From 5c6b944d167c673779e5f7e83b0018b278ffe8f4 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 3 Jan 2017 21:03:37 +0000 Subject: [PATCH 1161/1484] Fix a typo in a comment. FossilOrigin-Name: ae087123db8e7d47b25a8d0a98cfd62e85e42fc6 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/sqliteInt.h | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 4393faecba..d9637641de 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Use\sthe\sCLANG_VERSION\smacro\sto\scontrol\sclang-specific\sfeatures. -D 2017-01-03T20:01:24.105 +C Fix\sa\stypo\sin\sa\scomment. +D 2017-01-03T21:03:37.691 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -393,7 +393,7 @@ F src/shell.c 6095531aa900decdaa765e0f3993fba7153c92c1 F src/sqlite.h.in e8e2d108d82647f0a812fdb74accf91c1ec08ddc F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae -F src/sqliteInt.h 898cfcd9e0a40df15258cd86255bf9bee411e36d +F src/sqliteInt.h 7bfbca79001b3553d08a5884278e57696368a794 F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c 1b1e64fbce135bc178a6481433422a32f433ba37 F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 @@ -1541,7 +1541,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P f69ce75b3d94331fdbfa2f3a27d61db24c285d2b -R 576384b00d5b84002b3bf9bfa5fd1c23 +P f8ebeec211483503e135104ef977b3c384a1d789 +R f0ff94e8e63c383f0258ddac073c3711 U drh -Z df7fbae7b850ad1f1ec95f7decb0f63b +Z daa7f757074b48f5fb7e720dfd32b54f diff --git a/manifest.uuid b/manifest.uuid index 70bf8dddad..dcab54e3d1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f8ebeec211483503e135104ef977b3c384a1d789 \ No newline at end of file +ae087123db8e7d47b25a8d0a98cfd62e85e42fc6 \ No newline at end of file diff --git a/src/sqliteInt.h b/src/sqliteInt.h index e57453e679..c7be0ecd1c 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -110,7 +110,7 @@ # define GCC_VERSION 0 #endif -/* What version of CLANG is being used. 0 means GCC is not being used */ +/* What version of CLANG is being used. 0 means CLANG is not being used */ #ifdef __clang__ # define CLANG_VERSION \ (__clang_major__*1000000+__clang_minor__*1000+__clang_patchlevel__) From 7433ae5df65c2d1d3fded425c431150b91674144 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 3 Jan 2017 21:50:49 +0000 Subject: [PATCH 1162/1484] Back out the use of __sync_fetch_and_sub() as it does not appear to work. FossilOrigin-Name: 4c2efd4239bf07eb4b92d4af54edd68ee6312670 --- manifest | 17 +++++++++-------- manifest.uuid | 2 +- src/malloc.c | 8 -------- src/sqliteInt.h | 9 --------- src/status.c | 7 +------ 5 files changed, 11 insertions(+), 32 deletions(-) diff --git a/manifest b/manifest index d9637641de..b1dbc792e4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\stypo\sin\sa\scomment. -D 2017-01-03T21:03:37.691 +C Back\sout\sthe\suse\sof\s__sync_fetch_and_sub()\sas\sit\sdoes\snot\sappear\sto\swork. +D 2017-01-03T21:50:49.166 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -354,7 +354,7 @@ F src/insert.c 91ba5d0143e66479081536ebbaff1850ec9f57d9 F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e F src/loadext.c 5d6642d141c07d366e43d359e94ec9de47add41d F src/main.c e207b81542d13b9f13d61e78ca441f9781f055b0 -F src/malloc.c 254c1cf31c2f3783bfe49dc8e7adde3c850f2289 +F src/malloc.c f3fad34cd570022abca558c573f1761fb09a8212 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3 @@ -393,9 +393,9 @@ F src/shell.c 6095531aa900decdaa765e0f3993fba7153c92c1 F src/sqlite.h.in e8e2d108d82647f0a812fdb74accf91c1ec08ddc F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae -F src/sqliteInt.h 7bfbca79001b3553d08a5884278e57696368a794 +F src/sqliteInt.h f3450b70cfd99b434304225cf3b95de9cb4a9536 F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 -F src/status.c 1b1e64fbce135bc178a6481433422a32f433ba37 +F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 F src/tclsqlite.c 205c66b9b81d97978a155caa3ef5be9c4de2b174 F src/test1.c 8a98191a1da8e100f77cdb5cc716df67d405028d @@ -1541,7 +1541,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 f8ebeec211483503e135104ef977b3c384a1d789 -R f0ff94e8e63c383f0258ddac073c3711 +P ae087123db8e7d47b25a8d0a98cfd62e85e42fc6 +Q -f69ce75b3d94331fdbfa2f3a27d61db24c285d2b +R 4be5114c40ec1b8757eebb3b6a7e4284 U drh -Z daa7f757074b48f5fb7e720dfd32b54f +Z 7a47fa67b122b20ade3d4fbc1714217d diff --git a/manifest.uuid b/manifest.uuid index dcab54e3d1..2a6301b72a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ae087123db8e7d47b25a8d0a98cfd62e85e42fc6 \ No newline at end of file +4c2efd4239bf07eb4b92d4af54edd68ee6312670 \ No newline at end of file diff --git a/src/malloc.c b/src/malloc.c index 5f2f406425..84191c78a1 100644 --- a/src/malloc.c +++ b/src/malloc.c @@ -376,16 +376,12 @@ void sqlite3ScratchFree(void *p){ sqlite3MemdebugSetType(p, MEMTYPE_HEAP); if( sqlite3GlobalConfig.bMemstat ){ int iSize = sqlite3MallocSize(p); -#ifndef SQLITE_ATOMIC_STATUS_DOWN sqlite3_mutex_enter(mem0.mutex); -#endif sqlite3StatusDown(SQLITE_STATUS_SCRATCH_OVERFLOW, iSize); sqlite3StatusDown(SQLITE_STATUS_MEMORY_USED, iSize); sqlite3StatusDown(SQLITE_STATUS_MALLOC_COUNT, 1); sqlite3GlobalConfig.m.xFree(p); -#ifndef SQLITE_ATOMIC_STATUS_DOWN sqlite3_mutex_leave(mem0.mutex); -#endif }else{ sqlite3GlobalConfig.m.xFree(p); } @@ -444,15 +440,11 @@ void sqlite3_free(void *p){ assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) ); if( sqlite3GlobalConfig.bMemstat ){ -#ifndef SQLITE_ATOMIC_STATUS_DOWN sqlite3_mutex_enter(mem0.mutex); -#endif sqlite3StatusDown(SQLITE_STATUS_MEMORY_USED, sqlite3MallocSize(p)); sqlite3StatusDown(SQLITE_STATUS_MALLOC_COUNT, 1); sqlite3GlobalConfig.m.xFree(p); -#ifndef SQLITE_ATOMIC_STATUS_DOWN sqlite3_mutex_leave(mem0.mutex); -#endif }else{ sqlite3GlobalConfig.m.xFree(p); } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index c7be0ecd1c..0257e721bc 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -236,15 +236,6 @@ # define SQLITE_NOINLINE #endif -/* -** The SQLITE_ATOMIC_STATUS_DOWN macro is defined if and only if -** the sqlite3StatusDown() function is threadsafe. -*/ -#if !defined(SQLITE_DISABLE_INTRINSIC) \ - && (GCC_VERSION>=4004000 || CLANG_VERSION>=3000000) -# define SQLITE_ATOMIC_STATUS_DOWN 1 -#endif - /* ** Make sure that the compiler intrinsics we desire are enabled when ** compiling with an appropriate version of MSVC unless prevented by diff --git a/src/status.c b/src/status.c index f36f36724d..24dcad4572 100644 --- a/src/status.c +++ b/src/status.c @@ -100,16 +100,11 @@ void sqlite3StatusUp(int op, int N){ void sqlite3StatusDown(int op, int N){ wsdStatInit; assert( N>=0 ); - assert( op>=0 && op=4004000 || CLANG_VERSION>=3000000) - (void)__sync_fetch_and_sub(&wsdStat.nowValue[op], N); -#else assert( op>=0 && op=0 && op Date: Wed, 4 Jan 2017 00:26:28 +0000 Subject: [PATCH 1163/1484] Changes to the printf implementation for better performance. FossilOrigin-Name: acdb8f6f10953ed4290aadc9e026edd57d1dd21a --- manifest | 16 +++++++++------- manifest.uuid | 2 +- src/printf.c | 51 ++++++++++++++++++++++++++------------------------- 3 files changed, 36 insertions(+), 33 deletions(-) diff --git a/manifest b/manifest index c7180b2831..f96bb61029 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Use\scompiler\sintrinsic\sfunctions\sfor\ssigned\sinteger\smath\swhen\soverflow\ndetection\sis\sneeded. -D 2017-01-03T21:57:11.355 +C Changes\sto\sthe\sprintf\simplementation\sfor\sbetter\sperformance. +D 2017-01-04T00:26:28.506 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -384,7 +384,7 @@ F src/pcache1.c e3967219b2a92b9edcb9324a4ba75009090d3953 F src/pragma.c 5a23557e490e7ac5afef097efc4b59dce5b482c2 F src/pragma.h f9b221b2c8949ea941dbee49934299e4ed5af41c F src/prepare.c b1140c3d0cf59bc85ace00ce363153041b424b7a -F src/printf.c 0c8579432f47948d9be5077eb590e8c4a01be667 +F src/printf.c ff10a9b9902cd2afe5f655f3013c6307d969b1fd F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c bb070cf5f23611c44ab7e4788803684e385fc3fb F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac @@ -1541,8 +1541,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P bed0eaa5f50112e64fc97a2afdc9d56cf8f5026a 4c2efd4239bf07eb4b92d4af54edd68ee6312670 -R 4be5114c40ec1b8757eebb3b6a7e4284 -T +closed 4c2efd4239bf07eb4b92d4af54edd68ee6312670 +P d3ac32a6e7f1823450feb3d1089802542090d164 +R 1c116e0d91d0fafdc790fe63a7695a8d +T *branch * printf-optimization +T *sym-printf-optimization * +T -sym-trunk * U drh -Z 6bd6e679c9840443d9b2f38c8bc4573f +Z 6815c125f61af9819176bed00aaf68bc diff --git a/manifest.uuid b/manifest.uuid index 42e6e71ba8..f29f466e92 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d3ac32a6e7f1823450feb3d1089802542090d164 \ No newline at end of file +acdb8f6f10953ed4290aadc9e026edd57d1dd21a \ No newline at end of file diff --git a/src/printf.c b/src/printf.c index 91b753e04f..ede86f1208 100644 --- a/src/printf.c +++ b/src/printf.c @@ -59,7 +59,6 @@ typedef struct et_info { /* Information about each format field */ ** Allowed values for et_info.flags */ #define FLAG_SIGNED 1 /* True if the value to convert is signed */ -#define FLAG_INTERN 2 /* True if for internal use only */ #define FLAG_STRING 4 /* Allow infinity precision */ @@ -93,11 +92,10 @@ static const et_info fmtinfo[] = { { '%', 0, 0, etPERCENT, 0, 0 }, { 'p', 16, 0, etPOINTER, 0, 1 }, -/* All the rest have the FLAG_INTERN bit set and are thus for internal -** use only */ - { 'T', 0, 2, etTOKEN, 0, 0 }, - { 'S', 0, 2, etSRCLIST, 0, 0 }, - { 'r', 10, 3, etORDINAL, 0, 0 }, + /* All the rest are undocumented and are for internal use only */ + { 'T', 0, 0, etTOKEN, 0, 0 }, + { 'S', 0, 0, etSRCLIST, 0, 0 }, + { 'r', 10, 1, etORDINAL, 0, 0 }, }; /* @@ -191,7 +189,6 @@ void sqlite3VXPrintf( etByte done; /* Loop termination flag */ etByte xtype = etINVALID; /* Conversion paradigm */ u8 bArgList; /* True for SQLITE_PRINTF_SQLFUNC */ - u8 useIntern; /* Ok to use internal conversions (ex: %T) */ char prefix; /* Prefix character. "+" or "-" or " " or '\0'. */ sqlite_uint64 longvalue; /* Value for integer types */ LONGDOUBLE_TYPE realvalue; /* Value for real types */ @@ -210,13 +207,11 @@ void sqlite3VXPrintf( char buf[etBUFSIZE]; /* Conversion buffer */ bufpt = 0; - if( pAccum->printfFlags ){ - if( (bArgList = (pAccum->printfFlags & SQLITE_PRINTF_SQLFUNC))!=0 ){ - pArgList = va_arg(ap, PrintfArguments*); - } - useIntern = pAccum->printfFlags & SQLITE_PRINTF_INTERNAL; + if( (pAccum->printfFlags & SQLITE_PRINTF_SQLFUNC)!=0 ){ + pArgList = va_arg(ap, PrintfArguments*); + bArgList = 1; }else{ - bArgList = useIntern = 0; + bArgList = 0; } for(; (c=(*fmt))!=0; ++fmt){ if( c!='%' ){ @@ -328,11 +323,7 @@ void sqlite3VXPrintf( for(idx=0; idxflags & FLAG_INTERN)==0 ){ - xtype = infop->type; - }else{ - return; - } + xtype = infop->type; break; } } @@ -701,7 +692,9 @@ void sqlite3VXPrintf( break; } case etTOKEN: { - Token *pToken = va_arg(ap, Token*); + Token *pToken; + if( (pAccum->printfFlags & SQLITE_PRINTF_INTERNAL)==0 ) return; + pToken = va_arg(ap, Token*); assert( bArgList==0 ); if( pToken && pToken->n ){ sqlite3StrAccumAppend(pAccum, (const char*)pToken->z, pToken->n); @@ -710,9 +703,13 @@ void sqlite3VXPrintf( break; } case etSRCLIST: { - SrcList *pSrc = va_arg(ap, SrcList*); - int k = va_arg(ap, int); - struct SrcList_item *pItem = &pSrc->a[k]; + SrcList *pSrc; + int k; + struct SrcList_item *pItem; + if( (pAccum->printfFlags & SQLITE_PRINTF_INTERNAL)==0 ) return; + pSrc = va_arg(ap, SrcList*); + k = va_arg(ap, int); + pItem = &pSrc->a[k]; assert( bArgList==0 ); assert( k>=0 && knSrc ); if( pItem->zDatabase ){ @@ -734,9 +731,13 @@ void sqlite3VXPrintf( ** the output. */ width -= length; - if( width>0 && !flag_leftjustify ) sqlite3AppendChar(pAccum, width, ' '); - sqlite3StrAccumAppend(pAccum, bufpt, length); - if( width>0 && flag_leftjustify ) sqlite3AppendChar(pAccum, width, ' '); + if( width>0 ){ + if( !flag_leftjustify ) sqlite3AppendChar(pAccum, width, ' '); + sqlite3StrAccumAppend(pAccum, bufpt, length); + if( flag_leftjustify ) sqlite3AppendChar(pAccum, width, ' '); + }else{ + sqlite3StrAccumAppend(pAccum, bufpt, length); + } if( zExtra ){ sqlite3DbFree(pAccum->db, zExtra); From 1e9b53f9bcd39a4e365f105d880dd89d0e637673 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 4 Jan 2017 01:07:24 +0000 Subject: [PATCH 1164/1484] Attempt to factor out constant functions from the interior of table scans, since functions can often be expensive to compute. FossilOrigin-Name: 62e9270a8057d758621da33adb27fad14225f95d --- manifest | 18 ++++++++++-------- manifest.uuid | 2 +- src/expr.c | 39 ++++++++++++++++++++++++++------------- src/sqliteInt.h | 2 +- 4 files changed, 38 insertions(+), 23 deletions(-) diff --git a/manifest b/manifest index c7180b2831..0bd958e359 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Use\scompiler\sintrinsic\sfunctions\sfor\ssigned\sinteger\smath\swhen\soverflow\ndetection\sis\sneeded. -D 2017-01-03T21:57:11.355 +C Attempt\sto\sfactor\sout\sconstant\sfunctions\sfrom\sthe\sinterior\sof\stable\sscans,\nsince\sfunctions\scan\soften\sbe\sexpensive\sto\scompute. +D 2017-01-04T01:07:24.603 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -341,7 +341,7 @@ F src/ctime.c 9f2296a4e5d26ebf0e0d95a0af4628f1ea694e7a F src/date.c dc3f1391d9297f8c748132813aaffcb117090d6e F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c c8bc10d145c9666a34ae906250326fdaa8d58fa5 -F src/expr.c 449cbb8b9857ff8eb685b72555086818a178858c +F src/expr.c 8ba6e4ee13cab031bab897d871cf51678cbdd57e F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 2e9aabe1aee76273aff8a84ee92c464e095400ae F src/func.c c67273e1ec08abbdcc14c189892a3ff6eeece86b @@ -393,7 +393,7 @@ F src/shell.c 6095531aa900decdaa765e0f3993fba7153c92c1 F src/sqlite.h.in e8e2d108d82647f0a812fdb74accf91c1ec08ddc F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae -F src/sqliteInt.h f3450b70cfd99b434304225cf3b95de9cb4a9536 +F src/sqliteInt.h ba08d9eb983697be3eb7ee8d41d1121177694f59 F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 @@ -1541,8 +1541,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P bed0eaa5f50112e64fc97a2afdc9d56cf8f5026a 4c2efd4239bf07eb4b92d4af54edd68ee6312670 -R 4be5114c40ec1b8757eebb3b6a7e4284 -T +closed 4c2efd4239bf07eb4b92d4af54edd68ee6312670 +P d3ac32a6e7f1823450feb3d1089802542090d164 +R c8a0edce7fe1361197ea989faff6405e +T *branch * factor-constant-funcs +T *sym-factor-constant-funcs * +T -sym-trunk * U drh -Z 6bd6e679c9840443d9b2f38c8bc4573f +Z 75605860ea44512895bed0398cfff7b7 diff --git a/manifest.uuid b/manifest.uuid index 42e6e71ba8..f5c8571ca5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d3ac32a6e7f1823450feb3d1089802542090d164 \ No newline at end of file +62e9270a8057d758621da33adb27fad14225f95d \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 3bb0ca03f1..2fb5dff8c9 100644 --- a/src/expr.c +++ b/src/expr.c @@ -3612,6 +3612,9 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ u8 enc = ENC(db); /* The text encoding used by this database */ CollSeq *pColl = 0; /* A collating sequence */ + if( ConstFactorOk(pParse) && sqlite3ExprIsConstantNotJoin(pExpr) ){ + return sqlite3ExprCodeAtInit(pParse, pExpr, -1, 1); + } assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); if( ExprHasProperty(pExpr, EP_TokenOnly) ){ pFarg = 0; @@ -3992,8 +3995,16 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ /* ** Factor out the code of the given expression to initialization time. +** +** If regDest>=0 then the result is always stored in that register. +** If regDest<0 then this routine is free to store the value whereever +** it wants. The register where the expression is stored is returned. +** +** If regDest<0 and an equivalent expression already exists elsewhere +** in the initialization expressions, then routine just returns the +** register of the prior occurrance. */ -void sqlite3ExprCodeAtInit( +int sqlite3ExprCodeAtInit( Parse *pParse, /* Parsing context */ Expr *pExpr, /* The expression to code when the VDBE initializes */ int regDest, /* Store the value in this register */ @@ -4002,6 +4013,18 @@ void sqlite3ExprCodeAtInit( ExprList *p; assert( ConstFactorOk(pParse) ); p = pParse->pConstExpr; + if( regDest<0 ){ + if( p && reusable ){ + struct ExprList_item *pItem; + int i; + for(pItem=p->a, i=p->nExpr; i>0; pItem++, i--){ + if( pItem->reusable && sqlite3ExprCompare(pItem->pExpr,pExpr,-1)==0 ){ + return pItem->u.iConstExprReg; + } + } + } + regDest = ++pParse->nMem; + } pExpr = sqlite3ExprDup(pParse->db, pExpr, 0); p = sqlite3ExprListAppend(pParse, p, pExpr); if( p ){ @@ -4010,6 +4033,7 @@ void sqlite3ExprCodeAtInit( pItem->reusable = reusable; } pParse->pConstExpr = p; + return regDest; } /* @@ -4032,19 +4056,8 @@ int sqlite3ExprCodeTemp(Parse *pParse, Expr *pExpr, int *pReg){ && pExpr->op!=TK_REGISTER && sqlite3ExprIsConstantNotJoin(pExpr) ){ - ExprList *p = pParse->pConstExpr; - int i; *pReg = 0; - if( p ){ - struct ExprList_item *pItem; - for(pItem=p->a, i=p->nExpr; i>0; pItem++, i--){ - if( pItem->reusable && sqlite3ExprCompare(pItem->pExpr,pExpr,-1)==0 ){ - return pItem->u.iConstExprReg; - } - } - } - r2 = ++pParse->nMem; - sqlite3ExprCodeAtInit(pParse, pExpr, r2, 1); + r2 = sqlite3ExprCodeAtInit(pParse, pExpr, -1, 1); }else{ int r1 = sqlite3GetTempReg(pParse); r2 = sqlite3ExprCodeTarget(pParse, pExpr, r1); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 0257e721bc..47fb1b55e4 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3716,7 +3716,7 @@ void sqlite3ExprCacheAffinityChange(Parse*, int, int); void sqlite3ExprCode(Parse*, Expr*, int); void sqlite3ExprCodeCopy(Parse*, Expr*, int); void sqlite3ExprCodeFactorable(Parse*, Expr*, int); -void sqlite3ExprCodeAtInit(Parse*, Expr*, int, u8); +int sqlite3ExprCodeAtInit(Parse*, Expr*, int, u8); int sqlite3ExprCodeTemp(Parse*, Expr*, int*); int sqlite3ExprCodeTarget(Parse*, Expr*, int); void sqlite3ExprCodeAndCache(Parse*, Expr*, int); From ad879ffdb5387e9f4a2eafd3144bc121339c0a40 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 4 Jan 2017 04:10:02 +0000 Subject: [PATCH 1165/1484] Clean up the implementation of constant function factorization. FossilOrigin-Name: 2ab997e47998d261bd6190bbce5c09f3fbd4cfd3 --- manifest | 17 +++++++---------- manifest.uuid | 2 +- src/expr.c | 43 ++++++++++++++++++++----------------------- src/sqliteInt.h | 2 +- 4 files changed, 29 insertions(+), 35 deletions(-) diff --git a/manifest b/manifest index 0bd958e359..57528b4fdd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Attempt\sto\sfactor\sout\sconstant\sfunctions\sfrom\sthe\sinterior\sof\stable\sscans,\nsince\sfunctions\scan\soften\sbe\sexpensive\sto\scompute. -D 2017-01-04T01:07:24.603 +C Clean\sup\sthe\simplementation\sof\sconstant\sfunction\sfactorization. +D 2017-01-04T04:10:02.788 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -341,7 +341,7 @@ F src/ctime.c 9f2296a4e5d26ebf0e0d95a0af4628f1ea694e7a F src/date.c dc3f1391d9297f8c748132813aaffcb117090d6e F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c c8bc10d145c9666a34ae906250326fdaa8d58fa5 -F src/expr.c 8ba6e4ee13cab031bab897d871cf51678cbdd57e +F src/expr.c 9e60a71c788a00328652ed37b9f6b6b4374592a3 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 2e9aabe1aee76273aff8a84ee92c464e095400ae F src/func.c c67273e1ec08abbdcc14c189892a3ff6eeece86b @@ -393,7 +393,7 @@ F src/shell.c 6095531aa900decdaa765e0f3993fba7153c92c1 F src/sqlite.h.in e8e2d108d82647f0a812fdb74accf91c1ec08ddc F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae -F src/sqliteInt.h ba08d9eb983697be3eb7ee8d41d1121177694f59 +F src/sqliteInt.h 9fdfb8789b27a621f3401468bc1705c32308f877 F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 @@ -1541,10 +1541,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d3ac32a6e7f1823450feb3d1089802542090d164 -R c8a0edce7fe1361197ea989faff6405e -T *branch * factor-constant-funcs -T *sym-factor-constant-funcs * -T -sym-trunk * +P 62e9270a8057d758621da33adb27fad14225f95d +R 1aa2a1487ef2ae3f764297787590ccdb U drh -Z 75605860ea44512895bed0398cfff7b7 +Z 020211a07112e857de5c9ad202e08252 diff --git a/manifest.uuid b/manifest.uuid index f5c8571ca5..aabd0aa958 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -62e9270a8057d758621da33adb27fad14225f95d \ No newline at end of file +2ab997e47998d261bd6190bbce5c09f3fbd4cfd3 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 2fb5dff8c9..d6133c0d74 100644 --- a/src/expr.c +++ b/src/expr.c @@ -3613,7 +3613,9 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ CollSeq *pColl = 0; /* A collating sequence */ if( ConstFactorOk(pParse) && sqlite3ExprIsConstantNotJoin(pExpr) ){ - return sqlite3ExprCodeAtInit(pParse, pExpr, -1, 1); + /* SQL function can be expensive. So try to move constant functions + ** out of the inner loop, even if that means an extra OP_Copy. */ + return sqlite3ExprCodeAtInit(pParse, pExpr, -1); } assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); if( ExprHasProperty(pExpr, EP_TokenOnly) ){ @@ -3996,41 +3998,36 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ /* ** Factor out the code of the given expression to initialization time. ** -** If regDest>=0 then the result is always stored in that register. -** If regDest<0 then this routine is free to store the value whereever -** it wants. The register where the expression is stored is returned. -** -** If regDest<0 and an equivalent expression already exists elsewhere -** in the initialization expressions, then routine just returns the -** register of the prior occurrance. +** If regDest>=0 then the result is always stored in that register and the +** result is not reusable. If regDest<0 then this routine is free to +** store the value whereever it wants. The register where the expression +** is stored is returned. When regDest<0, two identical expressions will +** code to the same register. */ int sqlite3ExprCodeAtInit( Parse *pParse, /* Parsing context */ Expr *pExpr, /* The expression to code when the VDBE initializes */ - int regDest, /* Store the value in this register */ - u8 reusable /* True if this expression is reusable */ + int regDest /* Store the value in this register */ ){ ExprList *p; assert( ConstFactorOk(pParse) ); p = pParse->pConstExpr; - if( regDest<0 ){ - if( p && reusable ){ - struct ExprList_item *pItem; - int i; - for(pItem=p->a, i=p->nExpr; i>0; pItem++, i--){ - if( pItem->reusable && sqlite3ExprCompare(pItem->pExpr,pExpr,-1)==0 ){ - return pItem->u.iConstExprReg; - } + if( regDest<0 && p ){ + struct ExprList_item *pItem; + int i; + for(pItem=p->a, i=p->nExpr; i>0; pItem++, i--){ + if( pItem->reusable && sqlite3ExprCompare(pItem->pExpr,pExpr,-1)==0 ){ + return pItem->u.iConstExprReg; } } - regDest = ++pParse->nMem; } pExpr = sqlite3ExprDup(pParse->db, pExpr, 0); p = sqlite3ExprListAppend(pParse, p, pExpr); if( p ){ struct ExprList_item *pItem = &p->a[p->nExpr-1]; + pItem->reusable = regDest<0; + if( regDest<0 ) regDest = ++pParse->nMem; pItem->u.iConstExprReg = regDest; - pItem->reusable = reusable; } pParse->pConstExpr = p; return regDest; @@ -4057,7 +4054,7 @@ int sqlite3ExprCodeTemp(Parse *pParse, Expr *pExpr, int *pReg){ && sqlite3ExprIsConstantNotJoin(pExpr) ){ *pReg = 0; - r2 = sqlite3ExprCodeAtInit(pParse, pExpr, -1, 1); + r2 = sqlite3ExprCodeAtInit(pParse, pExpr, -1); }else{ int r1 = sqlite3GetTempReg(pParse); r2 = sqlite3ExprCodeTarget(pParse, pExpr, r1); @@ -4111,7 +4108,7 @@ void sqlite3ExprCodeCopy(Parse *pParse, Expr *pExpr, int target){ */ void sqlite3ExprCodeFactorable(Parse *pParse, Expr *pExpr, int target){ if( pParse->okConstFactor && sqlite3ExprIsConstant(pExpr) ){ - sqlite3ExprCodeAtInit(pParse, pExpr, target, 0); + sqlite3ExprCodeAtInit(pParse, pExpr, target); }else{ sqlite3ExprCode(pParse, pExpr, target); } @@ -4183,7 +4180,7 @@ int sqlite3ExprCodeExprList( sqlite3VdbeAddOp2(v, copyOp, j+srcReg-1, target+i); } }else if( (flags & SQLITE_ECEL_FACTOR)!=0 && sqlite3ExprIsConstant(pExpr) ){ - sqlite3ExprCodeAtInit(pParse, pExpr, target+i, 0); + sqlite3ExprCodeAtInit(pParse, pExpr, target+i); }else{ int inReg = sqlite3ExprCodeTarget(pParse, pExpr, target+i); if( inReg!=target+i ){ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 47fb1b55e4..8cfa0f88f7 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3716,7 +3716,7 @@ void sqlite3ExprCacheAffinityChange(Parse*, int, int); void sqlite3ExprCode(Parse*, Expr*, int); void sqlite3ExprCodeCopy(Parse*, Expr*, int); void sqlite3ExprCodeFactorable(Parse*, Expr*, int); -int sqlite3ExprCodeAtInit(Parse*, Expr*, int, u8); +int sqlite3ExprCodeAtInit(Parse*, Expr*, int); int sqlite3ExprCodeTemp(Parse*, Expr*, int*); int sqlite3ExprCodeTarget(Parse*, Expr*, int); void sqlite3ExprCodeAndCache(Parse*, Expr*, int); From 87e1e56b5b4a748f55f16eae5f7ea7789e959516 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 4 Jan 2017 14:53:53 +0000 Subject: [PATCH 1166/1484] Adjust filename creation in test_sqllog.c so that it uses leading zeros on counters, so that files appear in order when sorted lexicographically. FossilOrigin-Name: 8d670973595bd01ffc9b2ab53b965e6d6d22c573 --- manifest | 13 ++++++------- manifest.uuid | 2 +- src/test_sqllog.c | 6 +++--- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 5537df9b56..e7b721c8dd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Performance\senhancements\sin\sthe\sprintf\simplementation. -D 2017-01-04T13:09:05.205 +C Adjust\sfilename\screation\sin\stest_sqllog.c\sso\sthat\sit\suses\sleading\szeros\son\ncounters,\sso\sthat\sfiles\sappear\sin\sorder\swhen\ssorted\slexicographically. +D 2017-01-04T14:53:53.255 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -437,7 +437,7 @@ F src/test_quota.h 2a8ad1952d1d2ca9af0ce0465e56e6c023b5e15d F src/test_rtree.c 671f3fae50ff116ef2e32a3bf1fe21b5615b4b7b F src/test_schema.c f575932cb6274d12147a77e13ea4b49d52408513 F src/test_server.c a2615049954cbb9cfb4a62e18e2f0616e4dc38fe -F src/test_sqllog.c 0d138a8180a312bf996b37fa66da5c5799d4d57b +F src/test_sqllog.c 11e6ce7575f489155c604ac4b439f2ac1d3d5aef F src/test_superlock.c 4839644b9201da822f181c5bc406c0b2385f672e F src/test_syscall.c 1073306ba2e9bfc886771871a13d3de281ed3939 F src/test_tclvar.c df9fe1213c2634687a9ca0b0bec0d2119d359ae3 @@ -1541,8 +1541,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 80ad317f89c46db0d0d252aefdc036a34a61183d acdb8f6f10953ed4290aadc9e026edd57d1dd21a -R 453bc3e8602c7bb439b629ea6b93f15d -T +closed acdb8f6f10953ed4290aadc9e026edd57d1dd21a +P 82e4001b8caef7b31967f3edcbc1a545c081bdbc +R 3e81c0bc63e48e38a06c9f06294caaaf U drh -Z dbaca9d347b9ae9a5363e21ffbe64c98 +Z 0ca8dd088b039fc660aef4a4ad2583af diff --git a/manifest.uuid b/manifest.uuid index 5b12fe0530..6f5e8babb5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -82e4001b8caef7b31967f3edcbc1a545c081bdbc \ No newline at end of file +8d670973595bd01ffc9b2ab53b965e6d6d22c573 \ No newline at end of file diff --git a/src/test_sqllog.c b/src/test_sqllog.c index 31d5ad2f5b..9b207cf07b 100644 --- a/src/test_sqllog.c +++ b/src/test_sqllog.c @@ -313,7 +313,7 @@ static void sqllogCopydb(struct SLConn *p, const char *zSearch, int bLog){ /* Generate a file-name to use for the copy of this database */ iDb = sqllogglobal.iNextDb++; - zInit = sqlite3_mprintf("%s_%d.db", sqllogglobal.zPrefix, iDb); + zInit = sqlite3_mprintf("%s_%02d.db", sqllogglobal.zPrefix, iDb); /* Create the backup */ assert( sqllogglobal.bRec==0 ); @@ -376,7 +376,7 @@ static void sqllogOpenlog(struct SLConn *p){ char *zVar = getenv(ENVIRONMENT_VARIABLE1_NAME); if( zVar==0 || strlen(zVar)+10>=(sizeof(sqllogglobal.zPrefix)) ) return; sqlite3_snprintf(sizeof(sqllogglobal.zPrefix), sqllogglobal.zPrefix, - "%s/sqllog_%d", zVar, getProcessId()); + "%s/sqllog_%05d", zVar, getProcessId()); sqlite3_snprintf(sizeof(sqllogglobal.zIdx), sqllogglobal.zIdx, "%s.idx", sqllogglobal.zPrefix); if( getenv(ENVIRONMENT_VARIABLE2_NAME) ){ @@ -387,7 +387,7 @@ static void sqllogOpenlog(struct SLConn *p){ } /* Open the log file */ - zLog = sqlite3_mprintf("%s_%d.sql", sqllogglobal.zPrefix, p->iLog); + zLog = sqlite3_mprintf("%s_%05d.sql", sqllogglobal.zPrefix, p->iLog); p->fd = fopen(zLog, "w"); sqlite3_free(zLog); if( p->fd==0 ){ From 4e1f0efb4de9a6bb53b0979d9a5b700a77253277 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 4 Jan 2017 20:13:51 +0000 Subject: [PATCH 1167/1484] Possible fix for 30027b61. There may still be problems surrounding foreign key processing. FossilOrigin-Name: 71ccb1f4c490fdebc7008e884384e7809b849742 --- manifest | 18 +++++++----- manifest.uuid | 2 +- src/insert.c | 8 ++++-- test/triggerF.test | 72 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 90 insertions(+), 10 deletions(-) create mode 100644 test/triggerF.test diff --git a/manifest b/manifest index e7b721c8dd..a9b1e4263e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Adjust\sfilename\screation\sin\stest_sqllog.c\sso\sthat\sit\suses\sleading\szeros\son\ncounters,\sso\sthat\sfiles\sappear\sin\sorder\swhen\ssorted\slexicographically. -D 2017-01-04T14:53:53.255 +C Possible\sfix\sfor\s30027b61.\sThere\smay\sstill\sbe\sproblems\ssurrounding\sforeign\skey\nprocessing. +D 2017-01-04T20:13:51.856 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -350,7 +350,7 @@ F src/hash.c 63d0ee752a3b92d4695b2b1f5259c4621b2cfebd F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4 F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 -F src/insert.c 91ba5d0143e66479081536ebbaff1850ec9f57d9 +F src/insert.c 1e0c2b61265518a31929a10ca28102a7911d2e69 F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e F src/loadext.c 5d6642d141c07d366e43d359e94ec9de47add41d F src/main.c e207b81542d13b9f13d61e78ca441f9781f055b0 @@ -1336,6 +1336,7 @@ F test/triggerB.test 56780c031b454abac2340dbb3b71ac5c56c3d7fe F test/triggerC.test 302d8995f5ffe63bbc15053abb3ef7a39cf5a092 F test/triggerD.test 8e7f3921a92a5797d472732108109e44575fa650 F test/triggerE.test 15fa63f1097db1f83dd62d121616006978063d1f +F test/triggerF.test 55b1eb13433997faac3a4948c1d8252f6c8c636b F test/tt3_checkpoint.c 9e75cf7c1c364f52e1c47fd0f14c4340a9db0fe1 F test/tt3_index.c 39eec10a35f57672225be4d182862152896dee4a F test/tt3_lookaside1.c 0377e202c3c2a50d688cb65ba203afeda6fafeb9 @@ -1541,7 +1542,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 82e4001b8caef7b31967f3edcbc1a545c081bdbc -R 3e81c0bc63e48e38a06c9f06294caaaf -U drh -Z 0ca8dd088b039fc660aef4a4ad2583af +P 8d670973595bd01ffc9b2ab53b965e6d6d22c573 +R 18f979ea5ceac35d70bae9aad4eb77f0 +T *branch * replace-fix +T *sym-replace-fix * +T -sym-trunk * +U dan +Z a4497840837bb26a5ad3bdf1e588e388 diff --git a/manifest.uuid b/manifest.uuid index 6f5e8babb5..56c42e692c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8d670973595bd01ffc9b2ab53b965e6d6d22c573 \ No newline at end of file +71ccb1f4c490fdebc7008e884384e7809b849742 \ No newline at end of file diff --git a/src/insert.c b/src/insert.c index 27e05d4de6..2cc0457a99 100644 --- a/src/insert.c +++ b/src/insert.c @@ -1550,8 +1550,12 @@ void sqlite3GenerateConstraintChecks( } if( ix==0 && pPk==pIdx && onError==OE_Replace && pPk->pNext==0 ){ - sqlite3VdbeResolveLabel(v, addrUniqueOk); - continue; + if( 0==(db->flags&SQLITE_RecTriggers) + || 0==sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0) + ){ + sqlite3VdbeResolveLabel(v, addrUniqueOk); + continue; + } } diff --git a/test/triggerF.test b/test/triggerF.test new file mode 100644 index 0000000000..d5e3565edd --- /dev/null +++ b/test/triggerF.test @@ -0,0 +1,72 @@ +# 2017 January 4 +# +# 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. +# +#*********************************************************************** +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix triggerF +ifcapable {!trigger} { + finish_test + return +} + + +foreach {tn sql log} { + 1 { } { } + + 2 { + CREATE TRIGGER trd AFTER DELETE ON t1 BEGIN + INSERT INTO log VALUES(old.a || old.b || (SELECT count(*) FROM t1)); + END; + } {1one2 2two1 3three1} + + 3 { + CREATE TRIGGER trd BEFORE DELETE ON t1 BEGIN + INSERT INTO log VALUES(old.a || old.b || (SELECT count(*) FROM t1)); + END; + } {1one3 2two2 3three2} + + 4 { + CREATE TRIGGER tr1 AFTER DELETE ON t1 BEGIN + INSERT INTO log VALUES(old.a || old.b || (SELECT count(*) FROM t1)); + END; + CREATE TRIGGER tr2 BEFORE DELETE ON t1 BEGIN + INSERT INTO log VALUES(old.a || old.b || (SELECT count(*) FROM t1)); + END; + } {1one3 1one2 2two2 2two1 3three2 3three1} + +} { + reset_db + do_execsql_test 1.$tn.0 { + PRAGMA recursive_triggers = on; + CREATE TABLE t1(a INT PRIMARY KEY, b) WITHOUT ROWID; + CREATE TABLE log(t); + } + + execsql $sql + + do_execsql_test 1.$tn.1 { + INSERT INTO t1 VALUES(1, 'one'); + INSERT INTO t1 VALUES(2, 'two'); + INSERT INTO t1 VALUES(3, 'three'); + + DELETE FROM t1 WHERE a=1; + INSERT OR REPLACE INTO t1 VALUES(2, 'three'); + UPDATE OR REPLACE t1 SET a=3 WHERE a=2; + } + + do_execsql_test 1.$tn.2 { + SELECT * FROM log ORDER BY rowid; + } $log +} + +finish_test + From 801f55d837dc353f9bb0b4031849d2538cd56b3f Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 4 Jan 2017 22:02:56 +0000 Subject: [PATCH 1168/1484] Improved the comment on the block of code the provides the performance optimization originally added by check-in [925840cfdb]. The original check-in omitted condition 4, which was the cause of bug [30027b613b]. FossilOrigin-Name: c6506b82aa6583ccde5f673c79526d5f3920b67a --- manifest | 17 +++++++---------- manifest.uuid | 2 +- src/insert.c | 22 ++++++++++++++-------- 3 files changed, 22 insertions(+), 19 deletions(-) diff --git a/manifest b/manifest index a9b1e4263e..c942787502 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Possible\sfix\sfor\s30027b61.\sThere\smay\sstill\sbe\sproblems\ssurrounding\sforeign\skey\nprocessing. -D 2017-01-04T20:13:51.856 +C Improved\sthe\scomment\son\sthe\sblock\sof\scode\sthe\sprovides\sthe\sperformance\noptimization\soriginally\sadded\sby\scheck-in\s[925840cfdb].\s\sThe\soriginal\ncheck-in\somitted\scondition\s4,\swhich\swas\sthe\scause\sof\sbug\s[30027b613b]. +D 2017-01-04T22:02:56.715 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -350,7 +350,7 @@ F src/hash.c 63d0ee752a3b92d4695b2b1f5259c4621b2cfebd F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4 F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 -F src/insert.c 1e0c2b61265518a31929a10ca28102a7911d2e69 +F src/insert.c 895995aca4c6de8118d405c6c2d5fa7fd05bdb58 F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e F src/loadext.c 5d6642d141c07d366e43d359e94ec9de47add41d F src/main.c e207b81542d13b9f13d61e78ca441f9781f055b0 @@ -1542,10 +1542,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 8d670973595bd01ffc9b2ab53b965e6d6d22c573 -R 18f979ea5ceac35d70bae9aad4eb77f0 -T *branch * replace-fix -T *sym-replace-fix * -T -sym-trunk * -U dan -Z a4497840837bb26a5ad3bdf1e588e388 +P 71ccb1f4c490fdebc7008e884384e7809b849742 +R c29c3a3cb5ccbc5f6d29ccf66ed137b5 +U drh +Z 68ffb3e06be0aa51c5e3b069bb78bd06 diff --git a/manifest.uuid b/manifest.uuid index 56c42e692c..a921fd8581 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -71ccb1f4c490fdebc7008e884384e7809b849742 \ No newline at end of file +c6506b82aa6583ccde5f673c79526d5f3920b67a \ No newline at end of file diff --git a/src/insert.c b/src/insert.c index 2cc0457a99..bd6efe68b4 100644 --- a/src/insert.c +++ b/src/insert.c @@ -1549,16 +1549,22 @@ void sqlite3GenerateConstraintChecks( onError = OE_Abort; } - if( ix==0 && pPk==pIdx && onError==OE_Replace && pPk->pNext==0 ){ - if( 0==(db->flags&SQLITE_RecTriggers) - || 0==sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0) - ){ - sqlite3VdbeResolveLabel(v, addrUniqueOk); - continue; - } + /* Collision detection may be omitted if all of the following are true: + ** (1) The conflict resolution algorithm is REPLACE + ** (2) The table is a WITHOUT ROWID table + ** (3) There are no secondary indexes on the table + ** (4) No delete triggers need to be fired if there is a conflict + */ + if( (ix==0 && pIdx->pNext==0) /* Condition 3 */ + && pPk==pIdx /* Condition 2 */ + && onError==OE_Replace /* Condition 1 */ + && ( 0==(db->flags&SQLITE_RecTriggers) || /* Condition 4 */ + 0==sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0)) + ){ + sqlite3VdbeResolveLabel(v, addrUniqueOk); + continue; } - /* Check to see if the new index entry will be unique */ sqlite3VdbeAddOp4Int(v, OP_NoConflict, iThisCur, addrUniqueOk, regIdx, pIdx->nKeyCol); VdbeCoverage(v); From f9a12a106bb54616aefd4365dc89764698c58317 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 5 Jan 2017 06:57:42 +0000 Subject: [PATCH 1169/1484] Fix some problems with foreign key processing within REPLACE ops on WITHOUT ROWID tables with no triggers or auxiliary indexes. FossilOrigin-Name: c1220b1af62629d7fc2178512786d613cd7ea711 --- manifest | 16 ++++++------- manifest.uuid | 2 +- src/insert.c | 3 +++ test/fkey8.test | 62 +++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 74 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index c942787502..e193ec6891 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improved\sthe\scomment\son\sthe\sblock\sof\scode\sthe\sprovides\sthe\sperformance\noptimization\soriginally\sadded\sby\scheck-in\s[925840cfdb].\s\sThe\soriginal\ncheck-in\somitted\scondition\s4,\swhich\swas\sthe\scause\sof\sbug\s[30027b613b]. -D 2017-01-04T22:02:56.715 +C Fix\ssome\sproblems\swith\sforeign\skey\sprocessing\swithin\sREPLACE\sops\son\sWITHOUT\nROWID\stables\swith\sno\striggers\sor\sauxiliary\sindexes. +D 2017-01-05T06:57:42.773 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -350,7 +350,7 @@ F src/hash.c 63d0ee752a3b92d4695b2b1f5259c4621b2cfebd F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4 F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 -F src/insert.c 895995aca4c6de8118d405c6c2d5fa7fd05bdb58 +F src/insert.c 7af46a3be2656f5e13791464625d93d6b07b8612 F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e F src/loadext.c 5d6642d141c07d366e43d359e94ec9de47add41d F src/main.c e207b81542d13b9f13d61e78ca441f9781f055b0 @@ -692,7 +692,7 @@ F test/fkey4.test 86446017011273aad8f9a99c1a65019e7bd9ca9d F test/fkey5.test 5a373303f201ac03c22ba1ef17a733d3f56e611a F test/fkey6.test d078a1e323a740062bed38df32b8a736fd320dc0 F test/fkey7.test 72e915890ee4a005daaf3002cb208e8fe973ac13 -F test/fkey8.test 7bd1dd0174a0e29a90c62c517b9e2a410a0b345d +F test/fkey8.test e5372e32cdb4481f121ec3550703eeb7b4e0762c F test/fkey_malloc.test 594a7ea1fbab553c036c70813cd8bd9407d63749 F test/fordelete.test eb93a2f34137bb87bdab88fcab06c0bd92719aff F test/format4.test 1f0cac8ff3895e9359ed87e41aaabee982a812eb @@ -1542,7 +1542,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 71ccb1f4c490fdebc7008e884384e7809b849742 -R c29c3a3cb5ccbc5f6d29ccf66ed137b5 -U drh -Z 68ffb3e06be0aa51c5e3b069bb78bd06 +P c6506b82aa6583ccde5f673c79526d5f3920b67a +R ac4cdd0cd76febea0a8fc5828138512e +U dan +Z e2928fc07526fbb564fe7a7909e18ee6 diff --git a/manifest.uuid b/manifest.uuid index a921fd8581..319efeacf2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c6506b82aa6583ccde5f673c79526d5f3920b67a \ No newline at end of file +c1220b1af62629d7fc2178512786d613cd7ea711 \ No newline at end of file diff --git a/src/insert.c b/src/insert.c index bd6efe68b4..e261c1994e 100644 --- a/src/insert.c +++ b/src/insert.c @@ -1554,12 +1554,15 @@ void sqlite3GenerateConstraintChecks( ** (2) The table is a WITHOUT ROWID table ** (3) There are no secondary indexes on the table ** (4) No delete triggers need to be fired if there is a conflict + ** (5) No FK constraint counters need to be updated if a conflict occurs. */ if( (ix==0 && pIdx->pNext==0) /* Condition 3 */ && pPk==pIdx /* Condition 2 */ && onError==OE_Replace /* Condition 1 */ && ( 0==(db->flags&SQLITE_RecTriggers) || /* Condition 4 */ 0==sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0)) + && ( 0==(db->flags&SQLITE_ForeignKeys) || /* Condition 5 */ + (0==pTab->pFKey && 0==sqlite3FkReferences(pTab))) ){ sqlite3VdbeResolveLabel(v, addrUniqueOk); continue; diff --git a/test/fkey8.test b/test/fkey8.test index b4b6bb75e7..4269c20a92 100644 --- a/test/fkey8.test +++ b/test/fkey8.test @@ -101,5 +101,67 @@ foreach {tn use_stmt sql schema} { } $use_stmt } +#------------------------------------------------------------------------- +# The following tests check that foreign key constaint counters are +# correctly updated for any implicit DELETE operations that occur +# when a REPLACE command is executed against a WITHOUT ROWID table +# that has no triggers or auxiliary indexes. +# +reset_db +do_execsql_test 2.1.0 { + PRAGMA foreign_keys = on; + CREATE TABLE p1(a PRIMARY KEY, b) WITHOUT ROWID; + CREATE TABLE c1(x REFERENCES p1 DEFERRABLE INITIALLY DEFERRED); + + INSERT INTO p1 VALUES(1, 'one'); + INSERT INTO p1 VALUES(2, 'two'); + INSERT INTO c1 VALUES(1); + INSERT INTO c1 VALUES(2); +} + +do_catchsql_test 2.1.2 { + BEGIN; + DELETE FROM p1 WHERE a=1; + INSERT OR REPLACE INTO p1 VALUES(2, 'two'); + COMMIT; +} {1 {FOREIGN KEY constraint failed}} + +reset_db +do_execsql_test 2.2.0 { + PRAGMA foreign_keys = on; + CREATE TABLE p2(a PRIMARY KEY, b); + CREATE TABLE c2( + x PRIMARY KEY, + y REFERENCES p2 DEFERRABLE INITIALLY DEFERRED + ) WITHOUT ROWID; +} + +do_catchsql_test 2.2.1 { + BEGIN; + INSERT INTO c2 VALUES(13, 13); + INSERT OR REPLACE INTO c2 VALUES(13, 13); + DELETE FROM c2; + COMMIT; +} {0 {}} + +reset_db +do_execsql_test 2.3.0 { + PRAGMA foreign_keys = on; + CREATE TABLE p3(a PRIMARY KEY, b) WITHOUT ROWID; + CREATE TABLE c3(x REFERENCES p3); + + INSERT INTO p3 VALUES(1, 'one'); + INSERT INTO p3 VALUES(2, 'two'); + INSERT INTO c3 VALUES(1); + INSERT INTO c3 VALUES(2); + + CREATE TRIGGER p3d AFTER DELETE ON p3 WHEN old.a=1 BEGIN + INSERT OR REPLACE INTO p3 VALUES(2, 'three'); + END; +} + +do_catchsql_test 2.3.1 { + DELETE FROM p3 WHERE a=1 +} {1 {FOREIGN KEY constraint failed}} finish_test From 34d04d64f046f4a7fd514b11690982a9c213cc2e Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 5 Jan 2017 07:58:29 +0000 Subject: [PATCH 1170/1484] Ensure that the sqlite3_value_text() interface returns a buffer that is long enough to hold the complete string plus the zero terminator even when the input is a zeroblob. Fix for a problem detected by OSS-Fuzz. FossilOrigin-Name: 2dc7eeb5b4d2eaf1d843eda56f339fd4cc80d78e --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbemem.c | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index e7b721c8dd..11b92262e5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Adjust\sfilename\screation\sin\stest_sqllog.c\sso\sthat\sit\suses\sleading\szeros\son\ncounters,\sso\sthat\sfiles\sappear\sin\sorder\swhen\ssorted\slexicographically. -D 2017-01-04T14:53:53.255 +C Ensure\sthat\sthe\ssqlite3_value_text()\sinterface\sreturns\sa\sbuffer\sthat\sis\slong\nenough\sto\shold\sthe\scomplete\sstring\splus\sthe\szero\sterminator\seven\swhen\sthe\ninput\sis\sa\szeroblob.\s\sFix\sfor\sa\sproblem\sdetected\sby\sOSS-Fuzz. +D 2017-01-05T07:58:29.579 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -461,7 +461,7 @@ F src/vdbeInt.h 281cb70332dc8b593b8c7afe776f3a2ba7d4255e F src/vdbeapi.c d6ebaa465f070eb1af8ba4e7b34583ece87bdd24 F src/vdbeaux.c 12919c5aa354296d6b9ba808bca3e9dda836858c F src/vdbeblob.c f4f98ea672b242f807c08c92c7faaa79e5091b65 -F src/vdbemem.c d3fd85b7b7ef3eb75de29c6d7e1d10d3ca78b4fd +F src/vdbemem.c 3b5a9a5b375458d3e12a50ae1aaa41eeec2175fd F src/vdbesort.c eda25cb2d1727efca6f7862fea32b8aa33c0face F src/vdbetrace.c 41963d5376f0349842b5fc4aaaaacd7d9cdc0834 F src/vtab.c c4bbe0f870f52036553f8098aee0703997f0577a @@ -1541,7 +1541,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 82e4001b8caef7b31967f3edcbc1a545c081bdbc -R 3e81c0bc63e48e38a06c9f06294caaaf +P 8d670973595bd01ffc9b2ab53b965e6d6d22c573 +R f2b908372cb97d182889cac8f27ffb0c U drh -Z 0ca8dd088b039fc660aef4a4ad2583af +Z d916bc14abfb5518aa5597948225eb7d diff --git a/manifest.uuid b/manifest.uuid index 6f5e8babb5..8d31214e24 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8d670973595bd01ffc9b2ab53b965e6d6d22c573 \ No newline at end of file +2dc7eeb5b4d2eaf1d843eda56f339fd4cc80d78e \ No newline at end of file diff --git a/src/vdbemem.c b/src/vdbemem.c index 9a73b62777..656e19bfa8 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -1010,6 +1010,7 @@ static SQLITE_NOINLINE const void *valueToText(sqlite3_value* pVal, u8 enc){ assert( (pVal->flags & MEM_RowSet)==0 ); assert( (pVal->flags & (MEM_Null))==0 ); if( pVal->flags & (MEM_Blob|MEM_Str) ){ + if( ExpandBlob(pVal) ) return 0; pVal->flags |= MEM_Str; if( pVal->enc != (enc & ~SQLITE_UTF16_ALIGNED) ){ sqlite3VdbeChangeEncoding(pVal, enc & ~SQLITE_UTF16_ALIGNED); From ac56ab7e4881dcf4064b79099ba29db967972e54 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 5 Jan 2017 17:23:11 +0000 Subject: [PATCH 1171/1484] Fix handling the case where a sub-query in a FROM clause is itself a UNION ALL, and one side of that UNION ALL is a query on a view that includes an ORDER BY. Fix for ticket [190c2507]. FossilOrigin-Name: 590ca83b8e8cdd5d24ed7f10f43e540aa0627f22 --- manifest | 17 ++++++++--------- manifest.uuid | 2 +- src/select.c | 4 ++-- test/selectC.test | 34 ++++++++++++++++++++++++++++++++++ 4 files changed, 45 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 406575903b..a63cb41c6a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sproblems\sin\strigger\sand\sforeign\skey\shandling\swhen\sdoing\sREPLACE\son\sa\nWITHOUT\sROWID\stable\sthat\shas\sno\ssecondary\sindexes. -D 2017-01-05T13:50:12.504 +C Fix\shandling\sthe\scase\swhere\sa\ssub-query\sin\sa\sFROM\sclause\sis\sitself\sa\sUNION\nALL,\sand\sone\sside\sof\sthat\sUNION\sALL\sis\sa\squery\son\sa\sview\sthat\sincludes\san\nORDER\sBY.\sFix\sfor\sticket\s[190c2507]. +D 2017-01-05T17:23:11.079 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -388,7 +388,7 @@ F src/printf.c ff10a9b9902cd2afe5f655f3013c6307d969b1fd F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c bb070cf5f23611c44ab7e4788803684e385fc3fb F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac -F src/select.c dfb6cadc3dcfba1b1bdbfba62ebba2b4b673413e +F src/select.c 4437d9d5d56b6ffdedabf394c7fe3a07ff521ce9 F src/shell.c 6095531aa900decdaa765e0f3993fba7153c92c1 F src/sqlite.h.in e8e2d108d82647f0a812fdb74accf91c1ec08ddc F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1073,7 +1073,7 @@ F test/select8.test 8c8f5ae43894c891efc5755ed905467d1d67ad5d F test/select9.test aebc2bb0c3bc44606125033cbcaac2c8d1f33a95 F test/selectA.test 101e722370ac6e84978c2958b8931c78b10a1709 F test/selectB.test 954e4e49cf1f896d61794e440669e03a27ceea25 -F test/selectC.test 871fb55d884d3de5943c4057ebd22c2459e71977 +F test/selectC.test e25243f8ca503e06f252eb0218976d07cfeceac3 F test/selectD.test b0f02a04ef7737decb24e08be2c39b9664b43394 F test/selectE.test a8730ca330fcf40ace158f134f4fe0eb00c7edbf F test/selectF.test 21c94e6438f76537b72532fa9fd4710cdd455fc3 @@ -1542,8 +1542,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 2dc7eeb5b4d2eaf1d843eda56f339fd4cc80d78e c1220b1af62629d7fc2178512786d613cd7ea711 -R 0a003593029beee0fa918d480996f76b -T +closed c1220b1af62629d7fc2178512786d613cd7ea711 -U drh -Z e1a141b0e862b9e3c1acfc1860dde6a3 +P 571f166ea8721e2322965b6f23e758b78d13baca +R 5877f43df188f502f476d2f10520ec1c +U dan +Z 5cce284946e3a767bc44d73b1e732025 diff --git a/manifest.uuid b/manifest.uuid index 7ab76f290b..b593a2938f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -571f166ea8721e2322965b6f23e758b78d13baca \ No newline at end of file +590ca83b8e8cdd5d24ed7f10f43e540aa0627f22 \ No newline at end of file diff --git a/src/select.c b/src/select.c index e5f4c7fcdf..75ae082e96 100644 --- a/src/select.c +++ b/src/select.c @@ -742,8 +742,7 @@ static void selectInnerLoop( }else{ ecelFlags = 0; } - assert( eDest!=SRT_Table || pSort==0 ); - if( pSort && hasDistinct==0 && eDest!=SRT_EphemTab ){ + if( pSort && hasDistinct==0 && eDest!=SRT_EphemTab && eDest!=SRT_Table ){ /* For each expression in pEList that is a copy of an expression in ** the ORDER BY clause (pSort->pOrderBy), set the associated ** iOrderByCol value to one more than the index of the ORDER BY @@ -1285,6 +1284,7 @@ static void generateSortTail( VdbeComment((v, "%s", aOutEx[i].zName ? aOutEx[i].zName : aOutEx[i].zSpan)); } switch( eDest ){ + case SRT_Table: case SRT_EphemTab: { sqlite3VdbeAddOp2(v, OP_NewRowid, iParm, regRowid); sqlite3VdbeAddOp3(v, OP_Insert, iParm, regRow, regRowid); diff --git a/test/selectC.test b/test/selectC.test index dedac41fc4..4d79963007 100644 --- a/test/selectC.test +++ b/test/selectC.test @@ -14,6 +14,7 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl +set testprefix selectC # Ticket # do_test selectC-1.1 { @@ -233,4 +234,37 @@ do_execsql_test selectC-4.3 { select a, udf() from (select distinct a, b from t_distinct_bug) } {1 1 1 2 1 3} +#------------------------------------------------------------------------- +# Test that the problem in ticket #190c2507 has been fixed. +# +do_execsql_test 5.0 { + CREATE TABLE x1(a); + CREATE TABLE x2(b); + CREATE TABLE x3(c); + CREATE VIEW vvv AS SELECT b FROM x2 ORDER BY 1; + + INSERT INTO x1 VALUES('a'), ('b'); + INSERT INTO x2 VALUES(22), (23), (25), (24), (21); + INSERT INTO x3 VALUES(302), (303), (301); +} + +do_execsql_test 5.1 { + CREATE TABLE x4 AS SELECT b FROM vvv UNION ALL SELECT c from x3; + SELECT * FROM x4; +} {21 22 23 24 25 302 303 301} + +do_execsql_test 5.2 { + SELECT * FROM x1, x4 +} { + a 21 a 22 a 23 a 24 a 25 a 302 a 303 a 301 + b 21 b 22 b 23 b 24 b 25 b 302 b 303 b 301 +} + +do_execsql_test 5.3 { + SELECT * FROM x1, (SELECT b FROM vvv UNION ALL SELECT c from x3); +} { + a 21 a 22 a 23 a 24 a 25 a 302 a 303 a 301 + b 21 b 22 b 23 b 24 b 25 b 302 b 303 b 301 +} + finish_test From 9e1ab1a8a43c1d8fa5aabbd08aad7c917ba5b510 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 5 Jan 2017 19:32:48 +0000 Subject: [PATCH 1172/1484] Ensure that sqlite3_column_count() returns 0 for the "set" mode of "get/set" PRAGMA statements that do not return a value in that case (e.g. page_size, cache_size, auto_vacuum). FossilOrigin-Name: 5c05d8ec5e895661dae2de30c73dfdeaff93511e --- manifest | 24 +++++++----- manifest.uuid | 2 +- src/pragma.c | 13 ++++++- src/pragma.h | 89 ++++++++++++++++++++++---------------------- src/vdbe.h | 2 + src/vdbeaux.c | 16 ++++++++ test/pragma4.test | 73 ++++++++++++++++++++++++++++++++++++ tool/mkpragmatab.tcl | 32 +++++++++------- 8 files changed, 181 insertions(+), 70 deletions(-) create mode 100644 test/pragma4.test diff --git a/manifest b/manifest index a63cb41c6a..11b3fdb8d5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\shandling\sthe\scase\swhere\sa\ssub-query\sin\sa\sFROM\sclause\sis\sitself\sa\sUNION\nALL,\sand\sone\sside\sof\sthat\sUNION\sALL\sis\sa\squery\son\sa\sview\sthat\sincludes\san\nORDER\sBY.\sFix\sfor\sticket\s[190c2507]. -D 2017-01-05T17:23:11.079 +C Ensure\sthat\ssqlite3_column_count()\sreturns\s0\sfor\sthe\s"set"\smode\sof\s"get/set"\nPRAGMA\sstatements\sthat\sdo\snot\sreturn\sa\svalue\sin\sthat\scase\s(e.g.\spage_size,\ncache_size,\sauto_vacuum). +D 2017-01-05T19:32:48.544 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -381,8 +381,8 @@ F src/parse.y 29153738a7322054359320eb00b5a4cd44389f20 F src/pcache.c 51070ec9b8251bbf9c6ea3d35fd96a458752929e F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 F src/pcache1.c e3967219b2a92b9edcb9324a4ba75009090d3953 -F src/pragma.c 5a23557e490e7ac5afef097efc4b59dce5b482c2 -F src/pragma.h f9b221b2c8949ea941dbee49934299e4ed5af41c +F src/pragma.c 0e7a7c6f1c6fd8ff50c0fff65b8bb80174bc49c5 +F src/pragma.h 27fd6a8a051d6ea09bb656ce8a01dfc76f101956 F src/prepare.c b1140c3d0cf59bc85ace00ce363153041b424b7a F src/printf.c ff10a9b9902cd2afe5f655f3013c6307d969b1fd F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 @@ -456,10 +456,10 @@ F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c a88b0466fddf445ce752226d4698ca3faada620a F src/vacuum.c 33c174b28886b2faf26e503b5a49a1c01a9b1c16 F src/vdbe.c 88bd6c32b333580d2661ac3afe33369757fb1522 -F src/vdbe.h 50ee139f9c68fff91be1d717ed3a6abbd496919c +F src/vdbe.h b0866e4191f096f1c987a84b042c3599bdf5423b F src/vdbeInt.h 281cb70332dc8b593b8c7afe776f3a2ba7d4255e F src/vdbeapi.c d6ebaa465f070eb1af8ba4e7b34583ece87bdd24 -F src/vdbeaux.c 12919c5aa354296d6b9ba808bca3e9dda836858c +F src/vdbeaux.c 35c9a9908174e5a26c96d15e1f98214814a39147 F src/vdbeblob.c f4f98ea672b242f807c08c92c7faaa79e5091b65 F src/vdbemem.c 3b5a9a5b375458d3e12a50ae1aaa41eeec2175fd F src/vdbesort.c eda25cb2d1727efca6f7862fea32b8aa33c0face @@ -1010,6 +1010,7 @@ F test/permutations.test cd0b7bc04bf5e50d3a993d24c834d591f7d4f5fe F test/pragma.test 1e94755164a3a3264cd39836de4bebcb7809e5f8 F test/pragma2.test e5d5c176360c321344249354c0c16aec46214c9f F test/pragma3.test 14c12bc5352b1e100e0b6b44f371053a81ccf8ed +F test/pragma4.test 30533f846aa8b44d8d48f5dce2fe2b672dbb57c5 F test/printf.test b3ff34e73d59124140eaf89f7672e21bc2ca5fcc F test/printf2.test 0b61566dd1c0f0b802f59dffa228c5dc5aa6b054 F test/progress.test ebab27f670bd0d4eb9d20d49cef96e68141d92fb @@ -1480,7 +1481,7 @@ F tool/mkmsvcmin.tcl 2f12f7fa8858bbe61cf81820a2da96c79ed1ca8d F tool/mkopcodec.tcl d1b6362bd3aa80d5520d4d6f3765badf01f6c43c F tool/mkopcodeh.tcl a01d2c1d8a6205b03fc635adf3735b4c523befd3 F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e -F tool/mkpragmatab.tcl a30ee93515135466fc49ae881f75da07ebcafd19 +F tool/mkpragmatab.tcl 1b2c06e1da539a1f1fbeba2d26041024012cf1e7 F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 F tool/mksqlite3c-noext.tcl fef88397668ae83166735c41af99d79f56afaabb F tool/mksqlite3c.tcl 06b2e6a0f21cc0a5d70fbbd136b3e0a96470645e @@ -1542,7 +1543,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 571f166ea8721e2322965b6f23e758b78d13baca -R 5877f43df188f502f476d2f10520ec1c +P 590ca83b8e8cdd5d24ed7f10f43e540aa0627f22 +R 3cc0f54ce943c87173e4fcd78a65cfb2 +T *branch * pragma-columncount-fix +T *sym-pragma-columncount-fix * +T -sym-trunk * U dan -Z 5cce284946e3a767bc44d73b1e732025 +Z 05a2a3933bf879333729a3bc0a191043 diff --git a/manifest.uuid b/manifest.uuid index b593a2938f..56d578e48a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -590ca83b8e8cdd5d24ed7f10f43e540aa0627f22 \ No newline at end of file +5c05d8ec5e895661dae2de30c73dfdeaff93511e \ No newline at end of file diff --git a/src/pragma.c b/src/pragma.c index 6f2e0b545d..5251d0cd26 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -408,7 +408,9 @@ void sqlite3Pragma( } /* Register the result column names for pragmas that return results */ - if( (pPragma->mPragFlg & PragFlg_NoColumns)==0 ){ + if( (pPragma->mPragFlg & PragFlg_NoColumns)==0 + && ((pPragma->mPragFlg & PragFlg_NoColumns1)==0 || zRight==0) + ){ setPragmaResultColumnNames(v, pPragma); } @@ -1953,6 +1955,15 @@ void sqlite3Pragma( } /* End of the PRAGMA switch */ + /* The following block is a no-op unless SQLITE_DEBUG is defined. Its only + ** purpose is to execute assert() statements to verify that if the + ** PragFlg_NoColumns1 flag is set and the caller specified an argument + ** to the PRAGMA, the implementation has not added any OP_ResultRow + ** instructions to the VM. */ + if( (pPragma->mPragFlg & PragFlg_NoColumns1) && zRight ){ + sqlite3VdbeVerifyNoResultRow(v); + } + pragma_out: sqlite3DbFree(db, zLeft); sqlite3DbFree(db, zRight); diff --git a/src/pragma.h b/src/pragma.h index b854b4f38c..49a4080fe9 100644 --- a/src/pragma.h +++ b/src/pragma.h @@ -52,11 +52,12 @@ /* Property flags associated with various pragma. */ #define PragFlg_NeedSchema 0x01 /* Force schema load before running */ #define PragFlg_NoColumns 0x02 /* OP_ResultRow called with zero columns */ -#define PragFlg_ReadOnly 0x04 /* Read-only HEADER_VALUE */ -#define PragFlg_Result0 0x08 /* Acts as query when no argument */ -#define PragFlg_Result1 0x10 /* Acts as query when has one argument */ -#define PragFlg_SchemaOpt 0x20 /* Schema restricts name search if present */ -#define PragFlg_SchemaReq 0x40 /* Schema required - "main" is default */ +#define PragFlg_NoColumns1 0x04 /* zero columns if RHS argument is present */ +#define PragFlg_ReadOnly 0x08 /* Read-only HEADER_VALUE */ +#define PragFlg_Result0 0x10 /* Acts as query when no argument */ +#define PragFlg_Result1 0x20 /* Acts as query when has one argument */ +#define PragFlg_SchemaOpt 0x40 /* Schema restricts name search if present */ +#define PragFlg_SchemaReq 0x80 /* Schema required - "main" is default */ /* Names of columns for pragmas that return multi-column result ** or that return single-column results where the name of the @@ -133,14 +134,14 @@ static const PragmaName aPragmaName[] = { #if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) {/* zName: */ "application_id", /* ePragTyp: */ PragTyp_HEADER_VALUE, - /* ePragFlg: */ PragFlg_Result0, + /* ePragFlg: */ PragFlg_NoColumns1|PragFlg_Result0, /* ColNames: */ 0, 0, /* iArg: */ BTREE_APPLICATION_ID }, #endif #if !defined(SQLITE_OMIT_AUTOVACUUM) {/* zName: */ "auto_vacuum", /* ePragTyp: */ PragTyp_AUTO_VACUUM, - /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq, + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ 0 }, #endif @@ -148,7 +149,7 @@ static const PragmaName aPragmaName[] = { #if !defined(SQLITE_OMIT_AUTOMATIC_INDEX) {/* zName: */ "automatic_index", /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ SQLITE_AutoIndex }, #endif @@ -161,14 +162,14 @@ static const PragmaName aPragmaName[] = { #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) {/* zName: */ "cache_size", /* ePragTyp: */ PragTyp_CACHE_SIZE, - /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq, + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) {/* zName: */ "cache_spill", /* ePragTyp: */ PragTyp_CACHE_SPILL, - /* ePragFlg: */ PragFlg_Result0|PragFlg_SchemaReq, + /* ePragFlg: */ PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ 0 }, #endif @@ -179,13 +180,13 @@ static const PragmaName aPragmaName[] = { /* iArg: */ 0 }, {/* zName: */ "cell_size_check", /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ SQLITE_CellSizeCk }, #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) {/* zName: */ "checkpoint_fullfsync", /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ SQLITE_CkptFullFSync }, #endif @@ -206,21 +207,21 @@ static const PragmaName aPragmaName[] = { #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) {/* zName: */ "count_changes", /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ SQLITE_CountRows }, #endif #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_OS_WIN {/* zName: */ "data_store_directory", /* ePragTyp: */ PragTyp_DATA_STORE_DIRECTORY, - /* ePragFlg: */ 0, + /* ePragFlg: */ PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) {/* zName: */ "data_version", /* ePragTyp: */ PragTyp_HEADER_VALUE, - /* ePragFlg: */ PragFlg_Result0|PragFlg_ReadOnly, + /* ePragFlg: */ PragFlg_ReadOnly|PragFlg_Result0, /* ColNames: */ 0, 0, /* iArg: */ BTREE_DATA_VERSION }, #endif @@ -234,7 +235,7 @@ static const PragmaName aPragmaName[] = { #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED) {/* zName: */ "default_cache_size", /* ePragTyp: */ PragTyp_DEFAULT_CACHE_SIZE, - /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq, + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1, /* ColNames: */ 0, 1, /* iArg: */ 0 }, #endif @@ -242,7 +243,7 @@ static const PragmaName aPragmaName[] = { #if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) {/* zName: */ "defer_foreign_keys", /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ SQLITE_DeferFKs }, #endif @@ -250,14 +251,14 @@ static const PragmaName aPragmaName[] = { #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) {/* zName: */ "empty_result_callbacks", /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ SQLITE_NullCallback }, #endif #if !defined(SQLITE_OMIT_UTF16) {/* zName: */ "encoding", /* ePragTyp: */ PragTyp_ENCODING, - /* ePragFlg: */ PragFlg_Result0, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ 0 }, #endif @@ -279,7 +280,7 @@ static const PragmaName aPragmaName[] = { #if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) {/* zName: */ "foreign_keys", /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ SQLITE_ForeignKeys }, #endif @@ -287,19 +288,19 @@ static const PragmaName aPragmaName[] = { #if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) {/* zName: */ "freelist_count", /* ePragTyp: */ PragTyp_HEADER_VALUE, - /* ePragFlg: */ PragFlg_Result0|PragFlg_ReadOnly, + /* ePragFlg: */ PragFlg_ReadOnly|PragFlg_Result0, /* ColNames: */ 0, 0, /* iArg: */ BTREE_FREE_PAGE_COUNT }, #endif #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) {/* zName: */ "full_column_names", /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ SQLITE_FullColNames }, {/* zName: */ "fullfsync", /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ SQLITE_FullFSync }, #endif @@ -319,7 +320,7 @@ static const PragmaName aPragmaName[] = { #if !defined(SQLITE_OMIT_CHECK) {/* zName: */ "ignore_check_constraints", /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ SQLITE_IgnoreChecks }, #endif @@ -377,14 +378,14 @@ static const PragmaName aPragmaName[] = { #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) {/* zName: */ "legacy_file_format", /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ SQLITE_LegacyFileFmt }, #endif #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_ENABLE_LOCKING_STYLE {/* zName: */ "lock_proxy_file", /* ePragTyp: */ PragTyp_LOCK_PROXY_FILE, - /* ePragFlg: */ 0, + /* ePragFlg: */ PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ 0 }, #endif @@ -418,7 +419,7 @@ static const PragmaName aPragmaName[] = { /* iArg: */ 0 }, {/* zName: */ "page_size", /* ePragTyp: */ PragTyp_PAGE_SIZE, - /* ePragFlg: */ PragFlg_Result0|PragFlg_SchemaReq, + /* ePragFlg: */ PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ 0 }, #endif @@ -432,7 +433,7 @@ static const PragmaName aPragmaName[] = { #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) {/* zName: */ "query_only", /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ SQLITE_QueryOnly }, #endif @@ -446,12 +447,12 @@ static const PragmaName aPragmaName[] = { #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) {/* zName: */ "read_uncommitted", /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ SQLITE_ReadUncommitted }, {/* zName: */ "recursive_triggers", /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ SQLITE_RecTriggers }, #endif @@ -465,14 +466,14 @@ static const PragmaName aPragmaName[] = { #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) {/* zName: */ "reverse_unordered_selects", /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ SQLITE_ReverseOrder }, #endif #if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) {/* zName: */ "schema_version", /* ePragTyp: */ PragTyp_HEADER_VALUE, - /* ePragFlg: */ PragFlg_Result0, + /* ePragFlg: */ PragFlg_NoColumns1|PragFlg_Result0, /* ColNames: */ 0, 0, /* iArg: */ BTREE_SCHEMA_VERSION }, #endif @@ -486,7 +487,7 @@ static const PragmaName aPragmaName[] = { #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) {/* zName: */ "short_column_names", /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ SQLITE_ShortColNames }, #endif @@ -504,7 +505,7 @@ static const PragmaName aPragmaName[] = { #if defined(SQLITE_DEBUG) {/* zName: */ "sql_trace", /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ SQLITE_SqlTrace }, #endif @@ -519,7 +520,7 @@ static const PragmaName aPragmaName[] = { #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) {/* zName: */ "synchronous", /* ePragTyp: */ PragTyp_SYNCHRONOUS, - /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq, + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ 0 }, #endif @@ -533,12 +534,12 @@ static const PragmaName aPragmaName[] = { #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) {/* zName: */ "temp_store", /* ePragTyp: */ PragTyp_TEMP_STORE, - /* ePragFlg: */ PragFlg_Result0, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ 0 }, {/* zName: */ "temp_store_directory", /* ePragTyp: */ PragTyp_TEMP_STORE_DIRECTORY, - /* ePragFlg: */ 0, + /* ePragFlg: */ PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ 0 }, #endif @@ -550,7 +551,7 @@ static const PragmaName aPragmaName[] = { #if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) {/* zName: */ "user_version", /* ePragTyp: */ PragTyp_HEADER_VALUE, - /* ePragFlg: */ PragFlg_Result0, + /* ePragFlg: */ PragFlg_NoColumns1|PragFlg_Result0, /* ColNames: */ 0, 0, /* iArg: */ BTREE_USER_VERSION }, #endif @@ -558,27 +559,27 @@ static const PragmaName aPragmaName[] = { #if defined(SQLITE_DEBUG) {/* zName: */ "vdbe_addoptrace", /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ SQLITE_VdbeAddopTrace }, {/* zName: */ "vdbe_debug", /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ SQLITE_SqlTrace|SQLITE_VdbeListing|SQLITE_VdbeTrace }, {/* zName: */ "vdbe_eqp", /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ SQLITE_VdbeEQP }, {/* zName: */ "vdbe_listing", /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ SQLITE_VdbeListing }, {/* zName: */ "vdbe_trace", /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ SQLITE_VdbeTrace }, #endif @@ -598,7 +599,7 @@ static const PragmaName aPragmaName[] = { #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) {/* zName: */ "writable_schema", /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ SQLITE_WriteSchema|SQLITE_RecoveryMode }, #endif diff --git a/src/vdbe.h b/src/vdbe.h index 925ba08e50..feaf116807 100644 --- a/src/vdbe.h +++ b/src/vdbe.h @@ -183,8 +183,10 @@ int sqlite3VdbeAddOp4Int(Vdbe*,int,int,int,int,int); void sqlite3VdbeEndCoroutine(Vdbe*,int); #if defined(SQLITE_DEBUG) && !defined(SQLITE_TEST_REALLOC_STRESS) void sqlite3VdbeVerifyNoMallocRequired(Vdbe *p, int N); + void sqlite3VdbeVerifyNoResultRow(Vdbe *p); #else # define sqlite3VdbeVerifyNoMallocRequired(A,B) +# define sqlite3VdbeVerifyNoResultRow(A) #endif VdbeOp *sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp, int iLineno); void sqlite3VdbeAddParseSchemaOp(Vdbe*,int,char*); diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 7c9a295c92..85d273f1ec 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -648,6 +648,22 @@ void sqlite3VdbeVerifyNoMallocRequired(Vdbe *p, int N){ } #endif +/* +** Verify that the VM passed as the only argument does not contain +** an OP_ResultRow opcode. Fail an assert() if it does. This is used +** by code in pragma.c to ensure that the implementation of certain +** pragmas comports with the flags specified in the mkpragmatab.tcl +** script. +*/ +#if defined(SQLITE_DEBUG) && !defined(SQLITE_TEST_REALLOC_STRESS) +void sqlite3VdbeVerifyNoResultRow(Vdbe *p){ + int i; + for(i=0; inOp; i++){ + assert( p->aOp[i].opcode!=OP_ResultRow ); + } +} +#endif + /* ** This function returns a pointer to the array of opcodes associated with ** the Vdbe passed as the first argument. It is the callers responsibility diff --git a/test/pragma4.test b/test/pragma4.test new file mode 100644 index 0000000000..2fa9bd09bc --- /dev/null +++ b/test/pragma4.test @@ -0,0 +1,73 @@ +# 2017 Jan 4 +# +# 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 regression tests for SQLite library. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix pragma4 + +proc do_pragma_ncol_test {tn sql nCol} { + set ::stmt 0 + set ::stmt [sqlite3_prepare_v2 db $sql -1 dummy] + uplevel [list do_test $tn { sqlite3_column_count $::stmt } $nCol] + sqlite3_finalize $::stmt +} + +# If there is no RHS argument, the following PRAGMA statements operate as +# queries, returning a single row containing a single column. +# +# Or, if there is RHS argument, they return zero rows of zero columns. +# +foreach {tn sql} { + 1 "PRAGMA application_id = 10" + 2 "PRAGMA automatic_index = 1" + 3 "PRAGMA auto_vacuum = 1" + 4 "PRAGMA cache_size = -100" + 5 "PRAGMA cache_spill = 1" + 6 "PRAGMA cell_size_check = 1" + 7 "PRAGMA checkpoint_fullfsync = 1" + 8 "PRAGMA count_changes = 1" + 9 "PRAGMA default_cache_size = 100" + 10 "PRAGMA defer_foreign_keys = 1" + 11 "PRAGMA empty_result_callbacks = 1" + 12 "PRAGMA encoding = 'utf-8'" + 13 "PRAGMA foreign_keys = 1" + 14 "PRAGMA full_column_names = 1" + 15 "PRAGMA fullfsync = 1" + 16 "PRAGMA ignore_check_constraints = 1" + 17 "PRAGMA legacy_file_format = 1" + 18 "PRAGMA page_size = 511" + 19 "PRAGMA page_size = 512" + 20 "PRAGMA query_only = false" + 21 "PRAGMA read_uncommitted = true" + 22 "PRAGMA recursive_triggers = false" + 23 "PRAGMA reverse_unordered_selects = false" + 24 "PRAGMA schema_version = 211" + 25 "PRAGMA short_column_names = 1" + 26 "PRAGMA synchronous = full" + 27 "PRAGMA temp_store_directory = '/tmp'" + 28 "PRAGMA temp_store_directory = ''" + 29 "PRAGMA temp_store = memory" + 30 "PRAGMA user_version = 405" + 31 "PRAGMA writable_schema = 1" +} { + reset_db + + # Without RHS: + do_pragma_ncol_test 1.$tn.1 [lindex [split $sql =] 0] 1 + + # With RHS: + do_pragma_ncol_test 1.$tn.2 $sql 0 +} + + +finish_test diff --git a/tool/mkpragmatab.tcl b/tool/mkpragmatab.tcl index d9e100366c..c081a10474 100644 --- a/tool/mkpragmatab.tcl +++ b/tool/mkpragmatab.tcl @@ -18,6 +18,7 @@ set flagMeaning(Result1) {Acts as query when has one argument} set flagMeaning(SchemaReq) {Schema required - "main" is default} set flagMeaning(SchemaOpt) {Schema restricts name search if present} set flagMeaning(NoColumns) {OP_ResultRow called with zero columns} +set flagMeaning(NoColumns1) {zero columns if RHS argument is present} set pragma_def { NAME: full_column_names @@ -56,7 +57,7 @@ set pragma_def { IF: !defined(SQLITE_OMIT_FLAG_PRAGMAS) NAME: cache_spill - FLAG: Result0 SchemaReq + FLAG: Result0 SchemaReq NoColumns1 IF: !defined(SQLITE_OMIT_FLAG_PRAGMAS) NAME: reverse_unordered_selects @@ -149,12 +150,12 @@ set pragma_def { ARG: SQLITE_CellSizeCk NAME: default_cache_size - FLAG: NeedSchema Result0 SchemaReq + FLAG: NeedSchema Result0 SchemaReq NoColumns1 COLS: cache_size IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED) NAME: page_size - FLAG: Result0 SchemaReq + FLAG: Result0 SchemaReq NoColumns1 IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS) NAME: secure_delete @@ -183,14 +184,14 @@ set pragma_def { IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS) NAME: cache_size - FLAG: NeedSchema Result0 SchemaReq + FLAG: NeedSchema Result0 SchemaReq NoColumns1 IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS) NAME: mmap_size IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS) NAME: auto_vacuum - FLAG: NeedSchema Result0 SchemaReq + FLAG: NeedSchema Result0 SchemaReq NoColumns1 IF: !defined(SQLITE_OMIT_AUTOVACUUM) NAME: incremental_vacuum @@ -198,20 +199,23 @@ set pragma_def { IF: !defined(SQLITE_OMIT_AUTOVACUUM) NAME: temp_store - FLAG: Result0 + FLAG: Result0 NoColumns1 IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS) NAME: temp_store_directory + FLAG: NoColumns1 IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS) NAME: data_store_directory + FLAG: NoColumns1 IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_OS_WIN NAME: lock_proxy_file + FLAG: NoColumns1 IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_ENABLE_LOCKING_STYLE NAME: synchronous - FLAG: NeedSchema Result0 SchemaReq + FLAG: NeedSchema Result0 SchemaReq NoColumns1 IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS) NAME: table_info @@ -278,34 +282,37 @@ set pragma_def { IF: !defined(SQLITE_OMIT_INTEGRITY_CHECK) NAME: encoding - FLAG: Result0 + FLAG: Result0 NoColumns1 IF: !defined(SQLITE_OMIT_UTF16) NAME: schema_version TYPE: HEADER_VALUE ARG: BTREE_SCHEMA_VERSION + FLAG: NoColumns1 Result0 IF: !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) NAME: user_version TYPE: HEADER_VALUE ARG: BTREE_USER_VERSION + FLAG: NoColumns1 Result0 IF: !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) NAME: data_version TYPE: HEADER_VALUE ARG: BTREE_DATA_VERSION - FLAG: ReadOnly + FLAG: ReadOnly Result0 IF: !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) NAME: freelist_count TYPE: HEADER_VALUE ARG: BTREE_FREE_PAGE_COUNT - FLAG: ReadOnly + FLAG: ReadOnly Result0 IF: !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) NAME: application_id TYPE: HEADER_VALUE ARG: BTREE_APPLICATION_ID + FLAG: NoColumns1 Result0 IF: !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) NAME: compile_options @@ -408,10 +415,7 @@ foreach line [split $pragma_def \n] { } elseif {$id=="TYPE"} { set type $val if {$type=="FLAG"} { - lappend flags Result0 NoColumns - } - if {$type=="HEADER_VALUE"} { - lappend flags Result0 + lappend flags Result0 NoColumns1 } } elseif {$id=="ARG"} { set arg $val From 817be73bfc5a253972be57a71ffc2c304683f5e7 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Fri, 6 Jan 2017 00:02:51 +0000 Subject: [PATCH 1173/1484] Remove several non-portable tests for the deprecated temp_store_directory PRAGMA. FossilOrigin-Name: 28d87789141d816e0bce6d3965ce84c79b803218 --- manifest | 15 +++++++-------- manifest.uuid | 2 +- test/pragma4.test | 6 ++---- 3 files changed, 10 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 7c8102a95e..b2cb0deb1e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Ensure\sthat\ssqlite3_column_count()\sreturns\s0\sfor\sthe\s"set"\smode\sof\s"get/set"\nPRAGMA\sstatements\sthat\sdo\snot\sreturn\sa\svalue\sin\sthat\scase\s(e.g.\spage_size,\ncache_size,\sauto_vacuum). -D 2017-01-05T20:00:08.469 +C Remove\sseveral\snon-portable\stests\sfor\sthe\sdeprecated\stemp_store_directory\sPRAGMA. +D 2017-01-06T00:02:51.046 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -1010,7 +1010,7 @@ F test/permutations.test cd0b7bc04bf5e50d3a993d24c834d591f7d4f5fe F test/pragma.test 1e94755164a3a3264cd39836de4bebcb7809e5f8 F test/pragma2.test e5d5c176360c321344249354c0c16aec46214c9f F test/pragma3.test 14c12bc5352b1e100e0b6b44f371053a81ccf8ed -F test/pragma4.test 30533f846aa8b44d8d48f5dce2fe2b672dbb57c5 +F test/pragma4.test 79333554eb18567ae21ee1df980a5b2442d38910 F test/printf.test b3ff34e73d59124140eaf89f7672e21bc2ca5fcc F test/printf2.test 0b61566dd1c0f0b802f59dffa228c5dc5aa6b054 F test/progress.test ebab27f670bd0d4eb9d20d49cef96e68141d92fb @@ -1543,8 +1543,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 590ca83b8e8cdd5d24ed7f10f43e540aa0627f22 5c05d8ec5e895661dae2de30c73dfdeaff93511e -R 3cc0f54ce943c87173e4fcd78a65cfb2 -T +closed 5c05d8ec5e895661dae2de30c73dfdeaff93511e -U dan -Z 32693c8b1d3e16da4e9a701cf8e54e3f +P 2f57939a5583ae420b525c7e0f0dcda8626fe992 +R fe38b9aa03d8e8ab9362e6172ccc3a88 +U mistachkin +Z 07de6a6fd8f3c259d9e548da02c451b3 diff --git a/manifest.uuid b/manifest.uuid index f5231b6587..b3f7ca7a13 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2f57939a5583ae420b525c7e0f0dcda8626fe992 \ No newline at end of file +28d87789141d816e0bce6d3965ce84c79b803218 \ No newline at end of file diff --git a/test/pragma4.test b/test/pragma4.test index 2fa9bd09bc..3a4514901b 100644 --- a/test/pragma4.test +++ b/test/pragma4.test @@ -23,7 +23,7 @@ proc do_pragma_ncol_test {tn sql nCol} { } # If there is no RHS argument, the following PRAGMA statements operate as -# queries, returning a single row containing a single column. +# queries, returning a single row containing a single column. # # Or, if there is RHS argument, they return zero rows of zero columns. # @@ -54,8 +54,6 @@ foreach {tn sql} { 24 "PRAGMA schema_version = 211" 25 "PRAGMA short_column_names = 1" 26 "PRAGMA synchronous = full" - 27 "PRAGMA temp_store_directory = '/tmp'" - 28 "PRAGMA temp_store_directory = ''" 29 "PRAGMA temp_store = memory" 30 "PRAGMA user_version = 405" 31 "PRAGMA writable_schema = 1" @@ -64,7 +62,7 @@ foreach {tn sql} { # Without RHS: do_pragma_ncol_test 1.$tn.1 [lindex [split $sql =] 0] 1 - + # With RHS: do_pragma_ncol_test 1.$tn.2 $sql 0 } From 3d775e7586c0d12ab25e98c91b2b2555a9220638 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 6 Jan 2017 01:09:43 +0000 Subject: [PATCH 1174/1484] Clarify the documentation on sqlite3_column_count(). FossilOrigin-Name: 9ea0baddd893e54ec79399ae83033ae139650535 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/sqlite.h.in | 8 ++++++-- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index b2cb0deb1e..76c54f19bf 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sseveral\snon-portable\stests\sfor\sthe\sdeprecated\stemp_store_directory\sPRAGMA. -D 2017-01-06T00:02:51.046 +C Clarify\sthe\sdocumentation\son\ssqlite3_column_count(). +D 2017-01-06T01:09:43.612 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -390,7 +390,7 @@ F src/resolve.c bb070cf5f23611c44ab7e4788803684e385fc3fb F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c 4437d9d5d56b6ffdedabf394c7fe3a07ff521ce9 F src/shell.c 6095531aa900decdaa765e0f3993fba7153c92c1 -F src/sqlite.h.in e8e2d108d82647f0a812fdb74accf91c1ec08ddc +F src/sqlite.h.in 29bda4bee01248a5650567d7a22fac39bad1b542 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae F src/sqliteInt.h 9fdfb8789b27a621f3401468bc1705c32308f877 @@ -1543,7 +1543,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 2f57939a5583ae420b525c7e0f0dcda8626fe992 -R fe38b9aa03d8e8ab9362e6172ccc3a88 -U mistachkin -Z 07de6a6fd8f3c259d9e548da02c451b3 +P 28d87789141d816e0bce6d3965ce84c79b803218 +R e3a76d24c91b951960fc78f33b2e8a32 +U drh +Z 1cf489d9fb6392442bdd62aaa6400c28 diff --git a/manifest.uuid b/manifest.uuid index b3f7ca7a13..1c75ad6a44 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -28d87789141d816e0bce6d3965ce84c79b803218 \ No newline at end of file +9ea0baddd893e54ec79399ae83033ae139650535 \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index caa89721e1..1bcb62256c 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -3896,8 +3896,12 @@ int sqlite3_clear_bindings(sqlite3_stmt*); ** METHOD: sqlite3_stmt ** ** ^Return the number of columns in the result set returned by the -** [prepared statement]. ^This routine returns 0 if pStmt is an SQL -** statement that does not return data (for example an [UPDATE]). +** [prepared statement]. ^If this routine returns 0, that means the +** [prepared statement] returns no data (for example an [UPDATE]). +** ^However, just because this routine returns a positive number does not +** mean that one or more rows of data will be returned. ^A SELECT statement +** will always have a positive sqlite3_column_count() but depending on the +** WHERE clause constraints and the table content, it might return no rows. ** ** See also: [sqlite3_data_count()] */ From 1439a1e80f924e5bd7484f95fb1bab0a5ec2252a Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 6 Jan 2017 11:55:03 +0000 Subject: [PATCH 1175/1484] Improve handling of corrupt data in fts5. FossilOrigin-Name: 609ac1c73f7c2b48a571c178a72383996a9538fe --- ext/fts5/fts5_index.c | 7 ++++--- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index 46517e1aeb..750e0ca82d 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -2039,7 +2039,7 @@ static void fts5SegIterNext( else if( pLeaf->nn>pLeaf->szLeaf ){ pIter->iPgidxOff = pLeaf->szLeaf + fts5GetVarint32( &pLeaf->p[pLeaf->szLeaf], iOff - ); + ); pIter->iLeafOffset = iOff; pIter->iEndofDoclist = iOff; bNewTerm = 1; @@ -2073,6 +2073,7 @@ static void fts5SegIterNext( */ int nSz; assert( p->rc==SQLITE_OK ); + assert( pIter->iLeafOffset<=pIter->pLeaf->nn ); fts5FastGetVarint32(pIter->pLeaf->p, pIter->iLeafOffset, nSz); pIter->bDel = (nSz & 0x0001); pIter->nPos = nSz>>1; @@ -3067,7 +3068,7 @@ static void fts5ChunkIterate( break; }else{ pgno++; - pData = fts5DataRead(p, FTS5_SEGMENT_ROWID(pSeg->pSeg->iSegid, pgno)); + pData = fts5LeafRead(p, FTS5_SEGMENT_ROWID(pSeg->pSeg->iSegid, pgno)); if( pData==0 ) break; pChunk = &pData->p[4]; nChunk = MIN(nRem, pData->szLeaf - 4); @@ -5829,7 +5830,7 @@ static void fts5IndexIntegrityCheckSegment( ** ignore this b-tree entry. Otherwise, load it into memory. */ if( iIdxLeafpgnoFirst ) continue; iRow = FTS5_SEGMENT_ROWID(pSeg->iSegid, iIdxLeaf); - pLeaf = fts5DataRead(p, iRow); + pLeaf = fts5LeafRead(p, iRow); if( pLeaf==0 ) break; /* Check that the leaf contains at least one term, and that it is equal diff --git a/manifest b/manifest index 76c54f19bf..2c3a5de518 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Clarify\sthe\sdocumentation\son\ssqlite3_column_count(). -D 2017-01-06T01:09:43.612 +C Improve\shandling\sof\scorrupt\sdata\sin\sfts5. +D 2017-01-06T11:55:03.576 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -104,7 +104,7 @@ F ext/fts5/fts5_buffer.c 4c1502d4c956cd092c89ce4480867f9d8bf325cd F ext/fts5/fts5_config.c 5af9c360e99669d29f06492c370892394aba0857 F ext/fts5/fts5_expr.c dc2cee9f56b1818b85df59304b8104a5dfb8ab60 F ext/fts5/fts5_hash.c 880998e596b60f078348d48732ca4ad9a90caad2 -F ext/fts5/fts5_index.c fdbe46da11e81c1817cd4cb2de25ffdb4dd83711 +F ext/fts5/fts5_index.c f67032a9a529ba52a545e6e3ab970764199c05d4 F ext/fts5/fts5_main.c f85281445dcf8be32d18841c93a6f90fe27dbfe2 F ext/fts5/fts5_storage.c de0ed8a06738bde433afe11e92295ceaffbc4e58 F ext/fts5/fts5_tcl.c 4a901f00c8553740dba63511603f5527d741c26a @@ -1543,7 +1543,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 28d87789141d816e0bce6d3965ce84c79b803218 -R e3a76d24c91b951960fc78f33b2e8a32 -U drh -Z 1cf489d9fb6392442bdd62aaa6400c28 +P 9ea0baddd893e54ec79399ae83033ae139650535 +R 44d29edf796e0dea15e29c7ababbe2c4 +U dan +Z 2fd88d4ddce12153e4aca3cee686cd44 diff --git a/manifest.uuid b/manifest.uuid index 1c75ad6a44..e770ae0a32 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9ea0baddd893e54ec79399ae83033ae139650535 \ No newline at end of file +609ac1c73f7c2b48a571c178a72383996a9538fe \ No newline at end of file From e1ff3f5e11e866940b25c140cce9c2e3953c513f Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 6 Jan 2017 13:49:40 +0000 Subject: [PATCH 1176/1484] Ensure that "PRAGMA case_sensitive_like" and "PRAGMA shrink_memory" set the number of output columns to 0 (as they are statements that return no data). FossilOrigin-Name: 6696cd1878be4bd44a24841b04163e52d847711e --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/pragma.h | 4 ++-- test/pragma4.test | 13 +++++++++++++ tool/mkpragmatab.tcl | 2 ++ 5 files changed, 26 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 2c3a5de518..67b3b622ee 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improve\shandling\sof\scorrupt\sdata\sin\sfts5. -D 2017-01-06T11:55:03.576 +C Ensure\sthat\s"PRAGMA\scase_sensitive_like"\sand\s"PRAGMA\sshrink_memory"\sset\sthe\nnumber\sof\soutput\scolumns\sto\s0\s(as\sthey\sare\sstatements\sthat\sreturn\sno\sdata). +D 2017-01-06T13:49:40.112 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -382,7 +382,7 @@ F src/pcache.c 51070ec9b8251bbf9c6ea3d35fd96a458752929e F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 F src/pcache1.c e3967219b2a92b9edcb9324a4ba75009090d3953 F src/pragma.c 0e7a7c6f1c6fd8ff50c0fff65b8bb80174bc49c5 -F src/pragma.h 27fd6a8a051d6ea09bb656ce8a01dfc76f101956 +F src/pragma.h 61aa5389118594bebb28120a6720401aee34ce1a F src/prepare.c b1140c3d0cf59bc85ace00ce363153041b424b7a F src/printf.c ff10a9b9902cd2afe5f655f3013c6307d969b1fd F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 @@ -1010,7 +1010,7 @@ F test/permutations.test cd0b7bc04bf5e50d3a993d24c834d591f7d4f5fe F test/pragma.test 1e94755164a3a3264cd39836de4bebcb7809e5f8 F test/pragma2.test e5d5c176360c321344249354c0c16aec46214c9f F test/pragma3.test 14c12bc5352b1e100e0b6b44f371053a81ccf8ed -F test/pragma4.test 79333554eb18567ae21ee1df980a5b2442d38910 +F test/pragma4.test 6e85b6eab8e61ffc9c7db59d842276674e8e3264 F test/printf.test b3ff34e73d59124140eaf89f7672e21bc2ca5fcc F test/printf2.test 0b61566dd1c0f0b802f59dffa228c5dc5aa6b054 F test/progress.test ebab27f670bd0d4eb9d20d49cef96e68141d92fb @@ -1481,7 +1481,7 @@ F tool/mkmsvcmin.tcl 2f12f7fa8858bbe61cf81820a2da96c79ed1ca8d F tool/mkopcodec.tcl d1b6362bd3aa80d5520d4d6f3765badf01f6c43c F tool/mkopcodeh.tcl a01d2c1d8a6205b03fc635adf3735b4c523befd3 F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e -F tool/mkpragmatab.tcl 1b2c06e1da539a1f1fbeba2d26041024012cf1e7 +F tool/mkpragmatab.tcl ebb4bfcd2f8010e0a3934b6118db4b5f2f5edf5c F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 F tool/mksqlite3c-noext.tcl fef88397668ae83166735c41af99d79f56afaabb F tool/mksqlite3c.tcl 06b2e6a0f21cc0a5d70fbbd136b3e0a96470645e @@ -1543,7 +1543,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 9ea0baddd893e54ec79399ae83033ae139650535 -R 44d29edf796e0dea15e29c7ababbe2c4 +P 609ac1c73f7c2b48a571c178a72383996a9538fe +R 812971df62a9791f0bfb0122470a2213 U dan -Z 2fd88d4ddce12153e4aca3cee686cd44 +Z ebefd6b7654323e8a23a6cf648753c0a diff --git a/manifest.uuid b/manifest.uuid index e770ae0a32..865cc47649 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -609ac1c73f7c2b48a571c178a72383996a9538fe \ No newline at end of file +6696cd1878be4bd44a24841b04163e52d847711e \ No newline at end of file diff --git a/src/pragma.h b/src/pragma.h index 49a4080fe9..5d8d0aa35b 100644 --- a/src/pragma.h +++ b/src/pragma.h @@ -175,7 +175,7 @@ static const PragmaName aPragmaName[] = { #endif {/* zName: */ "case_sensitive_like", /* ePragTyp: */ PragTyp_CASE_SENSITIVE_LIKE, - /* ePragFlg: */ 0, + /* ePragFlg: */ PragFlg_NoColumns, /* ColNames: */ 0, 0, /* iArg: */ 0 }, {/* zName: */ "cell_size_check", @@ -493,7 +493,7 @@ static const PragmaName aPragmaName[] = { #endif {/* zName: */ "shrink_memory", /* ePragTyp: */ PragTyp_SHRINK_MEMORY, - /* ePragFlg: */ 0, + /* ePragFlg: */ PragFlg_NoColumns, /* ColNames: */ 0, 0, /* iArg: */ 0 }, {/* zName: */ "soft_heap_limit", diff --git a/test/pragma4.test b/test/pragma4.test index 3a4514901b..9a89b247de 100644 --- a/test/pragma4.test +++ b/test/pragma4.test @@ -67,5 +67,18 @@ foreach {tn sql} { do_pragma_ncol_test 1.$tn.2 $sql 0 } +# These pragmas should never return any values. +# +foreach {tn sql} { + 1 "PRAGMA shrink_memory" + 2 "PRAGMA shrink_memory = 10" + 3 "PRAGMA case_sensitive_like = 0" + 4 "PRAGMA case_sensitive_like = 1" + 5 "PRAGMA case_sensitive_like" +} { + + do_pragma_ncol_test 1.$tn.1 $sql 0 +} + finish_test diff --git a/tool/mkpragmatab.tcl b/tool/mkpragmatab.tcl index c081a10474..c22f72d491 100644 --- a/tool/mkpragmatab.tcl +++ b/tool/mkpragmatab.tcl @@ -271,6 +271,7 @@ set pragma_def { IF: defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_PARSER_TRACE) NAME: case_sensitive_like + FLAG: NoColumns NAME: integrity_check FLAG: NeedSchema @@ -328,6 +329,7 @@ set pragma_def { IF: !defined(SQLITE_OMIT_WAL) NAME: shrink_memory + FLAG: NoColumns NAME: busy_timeout FLAG: Result0 From a67b5cb6b32c61588eefdb76099545fcfcd3fcc0 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 7 Jan 2017 00:56:01 +0000 Subject: [PATCH 1177/1484] Avoid duplicate b-tree searches in the duplicate row detector used to implement DISTINCT. FossilOrigin-Name: d577dda0a7fbfacda57e8cad2bc4651d2a05d813 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/select.c | 1 + 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 67b3b622ee..4e1872ccaf 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Ensure\sthat\s"PRAGMA\scase_sensitive_like"\sand\s"PRAGMA\sshrink_memory"\sset\sthe\nnumber\sof\soutput\scolumns\sto\s0\s(as\sthey\sare\sstatements\sthat\sreturn\sno\sdata). -D 2017-01-06T13:49:40.112 +C Avoid\sduplicate\sb-tree\ssearches\sin\sthe\sduplicate\srow\sdetector\sused\sto\nimplement\sDISTINCT. +D 2017-01-07T00:56:01.383 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -388,7 +388,7 @@ F src/printf.c ff10a9b9902cd2afe5f655f3013c6307d969b1fd F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c bb070cf5f23611c44ab7e4788803684e385fc3fb F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac -F src/select.c 4437d9d5d56b6ffdedabf394c7fe3a07ff521ce9 +F src/select.c 533e55a4067278fef76eff951462383d4147880f F src/shell.c 6095531aa900decdaa765e0f3993fba7153c92c1 F src/sqlite.h.in 29bda4bee01248a5650567d7a22fac39bad1b542 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1543,7 +1543,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 609ac1c73f7c2b48a571c178a72383996a9538fe -R 812971df62a9791f0bfb0122470a2213 -U dan -Z ebefd6b7654323e8a23a6cf648753c0a +P 6696cd1878be4bd44a24841b04163e52d847711e +R fe79848e4bc76903961662bd26c28411 +U drh +Z 1f3f3bb84e2a0b8cdaa2372e378cb7b9 diff --git a/manifest.uuid b/manifest.uuid index 865cc47649..034f53423a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6696cd1878be4bd44a24841b04163e52d847711e \ No newline at end of file +d577dda0a7fbfacda57e8cad2bc4651d2a05d813 \ No newline at end of file diff --git a/src/select.c b/src/select.c index 75ae082e96..e750fd324d 100644 --- a/src/select.c +++ b/src/select.c @@ -657,6 +657,7 @@ static void codeDistinct( sqlite3VdbeAddOp4Int(v, OP_Found, iTab, addrRepeat, iMem, N); VdbeCoverage(v); sqlite3VdbeAddOp3(v, OP_MakeRecord, iMem, N, r1); sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iTab, r1, iMem, N); + sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); sqlite3ReleaseTempReg(pParse, r1); } From ad1d9a870742dc5525ca1e884bbdb8cc66dd45e6 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 7 Jan 2017 03:26:50 +0000 Subject: [PATCH 1178/1484] Avoid an unnecessary btree seek while deleting an index entry due to a conflict on a REPLACE operation. FossilOrigin-Name: f0495c5133d0dc04d63521136d6b9ca440792cdf --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/delete.c | 2 +- src/insert.c | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 4e1872ccaf..c1d7de4c1b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sduplicate\sb-tree\ssearches\sin\sthe\sduplicate\srow\sdetector\sused\sto\nimplement\sDISTINCT. -D 2017-01-07T00:56:01.383 +C Avoid\san\sunnecessary\sbtree\sseek\swhile\sdeleting\san\sindex\sentry\sdue\sto\sa\sconflict\non\sa\sREPLACE\soperation. +D 2017-01-07T03:26:50.193 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -340,7 +340,7 @@ F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 9f2296a4e5d26ebf0e0d95a0af4628f1ea694e7a F src/date.c dc3f1391d9297f8c748132813aaffcb117090d6e F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d -F src/delete.c c8bc10d145c9666a34ae906250326fdaa8d58fa5 +F src/delete.c 1a443cedfff0420959416a09f55119973f803593 F src/expr.c f06f41e5e5daca10fb090e70a2502dcc0dbc992b F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 2e9aabe1aee76273aff8a84ee92c464e095400ae @@ -350,7 +350,7 @@ F src/hash.c 63d0ee752a3b92d4695b2b1f5259c4621b2cfebd F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4 F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 -F src/insert.c 7af46a3be2656f5e13791464625d93d6b07b8612 +F src/insert.c ad2a0b2757a23b6f9297ee414eeab22b52fbde75 F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e F src/loadext.c 5d6642d141c07d366e43d359e94ec9de47add41d F src/main.c e207b81542d13b9f13d61e78ca441f9781f055b0 @@ -1543,7 +1543,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 6696cd1878be4bd44a24841b04163e52d847711e -R fe79848e4bc76903961662bd26c28411 +P d577dda0a7fbfacda57e8cad2bc4651d2a05d813 +R 9a736b4439c4e25faa8492f344a490a5 U drh -Z 1f3f3bb84e2a0b8cdaa2372e378cb7b9 +Z c755348d5a4bd2ab8fd825f60cd77850 diff --git a/manifest.uuid b/manifest.uuid index 034f53423a..c1cc73a62a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d577dda0a7fbfacda57e8cad2bc4651d2a05d813 \ No newline at end of file +f0495c5133d0dc04d63521136d6b9ca440792cdf \ No newline at end of file diff --git a/src/delete.c b/src/delete.c index 9ec8ed59e3..5a75e606e2 100644 --- a/src/delete.c +++ b/src/delete.c @@ -716,7 +716,7 @@ void sqlite3GenerateRowDelete( if( eMode!=ONEPASS_OFF ){ sqlite3VdbeChangeP5(v, OPFLAG_AUXDELETE); } - if( iIdxNoSeek>=0 ){ + if( iIdxNoSeek>=0 && iIdxNoSeek!=iDataCur ){ sqlite3VdbeAddOp1(v, OP_Delete, iIdxNoSeek); } if( eMode==ONEPASS_MULTI ) p5 |= OPFLAG_SAVEPOSITION; diff --git a/src/insert.c b/src/insert.c index e261c1994e..e55ea2d9fb 100644 --- a/src/insert.c +++ b/src/insert.c @@ -1651,7 +1651,7 @@ void sqlite3GenerateConstraintChecks( } sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur, regR, nPkField, 0, OE_Replace, - (pIdx==pPk ? ONEPASS_SINGLE : ONEPASS_OFF), -1); + (pIdx==pPk ? ONEPASS_SINGLE : ONEPASS_OFF), iThisCur); seenReplace = 1; break; } From 4cef5b1c812cf5739251039d7d5d0e1223fe0caf Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 7 Jan 2017 14:26:28 +0000 Subject: [PATCH 1179/1484] Critical fix to the previous check-in so that it works when there are BEFORE triggers that move the cursor before the OP_Delete has a chance to be applied. FossilOrigin-Name: db2c0960ffb3b396b20e0441d3edb812254c82bc --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/delete.c | 21 +++++++++------------ src/insert.c | 3 ++- 4 files changed, 19 insertions(+), 21 deletions(-) diff --git a/manifest b/manifest index c1d7de4c1b..769b92f991 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\san\sunnecessary\sbtree\sseek\swhile\sdeleting\san\sindex\sentry\sdue\sto\sa\sconflict\non\sa\sREPLACE\soperation. -D 2017-01-07T03:26:50.193 +C Critical\sfix\sto\sthe\sprevious\scheck-in\sso\sthat\sit\sworks\swhen\sthere\sare\nBEFORE\striggers\sthat\smove\sthe\scursor\sbefore\sthe\sOP_Delete\shas\sa\schance\sto\nbe\sapplied. +D 2017-01-07T14:26:28.809 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -340,7 +340,7 @@ F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 9f2296a4e5d26ebf0e0d95a0af4628f1ea694e7a F src/date.c dc3f1391d9297f8c748132813aaffcb117090d6e F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d -F src/delete.c 1a443cedfff0420959416a09f55119973f803593 +F src/delete.c 4220f4feee7fddefc1e73e5ade1ed82ffe8dc92a F src/expr.c f06f41e5e5daca10fb090e70a2502dcc0dbc992b F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 2e9aabe1aee76273aff8a84ee92c464e095400ae @@ -350,7 +350,7 @@ F src/hash.c 63d0ee752a3b92d4695b2b1f5259c4621b2cfebd F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4 F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 -F src/insert.c ad2a0b2757a23b6f9297ee414eeab22b52fbde75 +F src/insert.c 3b7fbb149ef249269bfbedabbe8fd706ef9a2317 F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e F src/loadext.c 5d6642d141c07d366e43d359e94ec9de47add41d F src/main.c e207b81542d13b9f13d61e78ca441f9781f055b0 @@ -1543,7 +1543,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d577dda0a7fbfacda57e8cad2bc4651d2a05d813 -R 9a736b4439c4e25faa8492f344a490a5 +P f0495c5133d0dc04d63521136d6b9ca440792cdf +R 21f1a5c5760681e8d66bbbeed4342953 U drh -Z c755348d5a4bd2ab8fd825f60cd77850 +Z 06625003bcd408124313c9f36986c7f6 diff --git a/manifest.uuid b/manifest.uuid index c1cc73a62a..ce6b8d600a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f0495c5133d0dc04d63521136d6b9ca440792cdf \ No newline at end of file +db2c0960ffb3b396b20e0441d3edb812254c82bc \ No newline at end of file diff --git a/src/delete.c b/src/delete.c index 5a75e606e2..db00803996 100644 --- a/src/delete.c +++ b/src/delete.c @@ -519,10 +519,7 @@ void sqlite3DeleteFrom( #endif { int count = (pParse->nested==0); /* True to count changes */ - int iIdxNoSeek = -1; - if( bComplex==0 && aiCurOnePass[1]!=iDataCur ){ - iIdxNoSeek = aiCurOnePass[1]; - } + int iIdxNoSeek = bComplex ? -1 : aiCurOnePass[1]; sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur, iKey, nKey, count, OE_Default, eOnePass, iIdxNoSeek); } @@ -604,15 +601,15 @@ delete_from_cleanup: ** ** If eMode is ONEPASS_MULTI, then this call is being made as part ** of a ONEPASS delete that affects multiple rows. In this case, if -** iIdxNoSeek is a valid cursor number (>=0), then its position should -** be preserved following the delete operation. Or, if iIdxNoSeek is not -** a valid cursor number, the position of iDataCur should be preserved -** instead. +** iIdxNoSeek is a valid cursor number (>=0) and is not the same as +** iDataCur, then its position should be preserved following the delete +** operation. Or, if iIdxNoSeek is not a valid cursor number, the +** position of iDataCur should be preserved instead. ** ** iIdxNoSeek: -** If iIdxNoSeek is a valid cursor number (>=0), then it identifies an -** index cursor (from within array of cursors starting at iIdxCur) that -** already points to the index entry to be deleted. +** If iIdxNoSeek is a valid cursor number (>=0) not equal to iDataCur, +** then it identifies an index cursor (from within array of cursors +** starting at iIdxCur) that already points to the index entry to be deleted. */ void sqlite3GenerateRowDelete( Parse *pParse, /* Parsing context */ @@ -683,7 +680,7 @@ void sqlite3GenerateRowDelete( /* If any BEFORE triggers were coded, then seek the cursor to the ** row to be deleted again. It may be that the BEFORE triggers moved - ** the cursor or of already deleted the row that the cursor was + ** the cursor or already deleted the row that the cursor was ** pointing to. */ if( addrStart Date: Sat, 7 Jan 2017 14:47:03 +0000 Subject: [PATCH 1180/1484] Improvements to the iIdxNoSeek optimization of sqlite3GenerateRowDelete() so that it is automatically disabled for BEFORE triggers but works in all other cases. FossilOrigin-Name: 3178ec4c27efc4ff84bcd17ddb17ec50a6ac96b3 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/delete.c | 10 ++++++++-- src/insert.c | 3 +-- 4 files changed, 17 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 769b92f991..ec76e312ce 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Critical\sfix\sto\sthe\sprevious\scheck-in\sso\sthat\sit\sworks\swhen\sthere\sare\nBEFORE\striggers\sthat\smove\sthe\scursor\sbefore\sthe\sOP_Delete\shas\sa\schance\sto\nbe\sapplied. -D 2017-01-07T14:26:28.809 +C Improvements\sto\sthe\siIdxNoSeek\soptimization\sof\ssqlite3GenerateRowDelete()\nso\sthat\sit\sis\sautomatically\sdisabled\sfor\sBEFORE\striggers\sbut\sworks\sin\sall\nother\scases. +D 2017-01-07T14:47:03.531 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -340,7 +340,7 @@ F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 9f2296a4e5d26ebf0e0d95a0af4628f1ea694e7a F src/date.c dc3f1391d9297f8c748132813aaffcb117090d6e F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d -F src/delete.c 4220f4feee7fddefc1e73e5ade1ed82ffe8dc92a +F src/delete.c a84f6229ccb9448460c287248024ceb70e10baab F src/expr.c f06f41e5e5daca10fb090e70a2502dcc0dbc992b F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 2e9aabe1aee76273aff8a84ee92c464e095400ae @@ -350,7 +350,7 @@ F src/hash.c 63d0ee752a3b92d4695b2b1f5259c4621b2cfebd F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4 F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 -F src/insert.c 3b7fbb149ef249269bfbedabbe8fd706ef9a2317 +F src/insert.c ad2a0b2757a23b6f9297ee414eeab22b52fbde75 F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e F src/loadext.c 5d6642d141c07d366e43d359e94ec9de47add41d F src/main.c e207b81542d13b9f13d61e78ca441f9781f055b0 @@ -1543,7 +1543,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P f0495c5133d0dc04d63521136d6b9ca440792cdf -R 21f1a5c5760681e8d66bbbeed4342953 +P db2c0960ffb3b396b20e0441d3edb812254c82bc +R 7bbc97d23d01181c7fdd8aa9c81894e1 U drh -Z 06625003bcd408124313c9f36986c7f6 +Z 5c5df114c2b0c58ce035451bb180f71f diff --git a/manifest.uuid b/manifest.uuid index ce6b8d600a..c040ce2769 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -db2c0960ffb3b396b20e0441d3edb812254c82bc \ No newline at end of file +3178ec4c27efc4ff84bcd17ddb17ec50a6ac96b3 \ No newline at end of file diff --git a/src/delete.c b/src/delete.c index db00803996..1a5edb59d8 100644 --- a/src/delete.c +++ b/src/delete.c @@ -519,9 +519,8 @@ void sqlite3DeleteFrom( #endif { int count = (pParse->nested==0); /* True to count changes */ - int iIdxNoSeek = bComplex ? -1 : aiCurOnePass[1]; sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur, - iKey, nKey, count, OE_Default, eOnePass, iIdxNoSeek); + iKey, nKey, count, OE_Default, eOnePass, aiCurOnePass[1]); } /* End of the loop over all rowids/primary-keys. */ @@ -610,6 +609,8 @@ delete_from_cleanup: ** If iIdxNoSeek is a valid cursor number (>=0) not equal to iDataCur, ** then it identifies an index cursor (from within array of cursors ** starting at iIdxCur) that already points to the index entry to be deleted. +** Except, this optimization is disabled if there are BEFORE triggers since +** the trigger body might have moved the cursor. */ void sqlite3GenerateRowDelete( Parse *pParse, /* Parsing context */ @@ -682,11 +683,16 @@ void sqlite3GenerateRowDelete( ** row to be deleted again. It may be that the BEFORE triggers moved ** the cursor or already deleted the row that the cursor was ** pointing to. + ** + ** Also disable the iIdxNoSeek optimization since the BEFORE trigger + ** may have moved that cursor. */ if( addrStart=0 ); + iIdxNoSeek = -1; } /* Do FK processing. This call checks that any FK constraints that diff --git a/src/insert.c b/src/insert.c index 4f407a2cbd..e55ea2d9fb 100644 --- a/src/insert.c +++ b/src/insert.c @@ -1651,8 +1651,7 @@ void sqlite3GenerateConstraintChecks( } sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur, regR, nPkField, 0, OE_Replace, - (pIdx==pPk ? ONEPASS_SINGLE : ONEPASS_OFF), - (pTrigger ? -1 : iThisCur)); + (pIdx==pPk ? ONEPASS_SINGLE : ONEPASS_OFF), iThisCur); seenReplace = 1; break; } From f4e994b23adc5bb62356af81d9fd194796bc22cf Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 9 Jan 2017 13:43:09 +0000 Subject: [PATCH 1181/1484] Add the SQLITE_UINT64_TYPE compile-time option. FossilOrigin-Name: a5fe03bc419d9c7e6068ed38810e3f183de179b5 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/sqlite.h.in | 6 +++++- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index ec76e312ce..9ab624a73c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improvements\sto\sthe\siIdxNoSeek\soptimization\sof\ssqlite3GenerateRowDelete()\nso\sthat\sit\sis\sautomatically\sdisabled\sfor\sBEFORE\striggers\sbut\sworks\sin\sall\nother\scases. -D 2017-01-07T14:47:03.531 +C Add\sthe\sSQLITE_UINT64_TYPE\scompile-time\soption. +D 2017-01-09T13:43:09.245 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -390,7 +390,7 @@ F src/resolve.c bb070cf5f23611c44ab7e4788803684e385fc3fb F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c 533e55a4067278fef76eff951462383d4147880f F src/shell.c 6095531aa900decdaa765e0f3993fba7153c92c1 -F src/sqlite.h.in 29bda4bee01248a5650567d7a22fac39bad1b542 +F src/sqlite.h.in e71655293c9bde26939496f3aac9d1821d2c07a2 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae F src/sqliteInt.h 9fdfb8789b27a621f3401468bc1705c32308f877 @@ -1543,7 +1543,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P db2c0960ffb3b396b20e0441d3edb812254c82bc -R 7bbc97d23d01181c7fdd8aa9c81894e1 +P 3178ec4c27efc4ff84bcd17ddb17ec50a6ac96b3 +R ff5d1e49d008400e89044e5b599d5e72 U drh -Z 5c5df114c2b0c58ce035451bb180f71f +Z 9ff193ccbc51dd8562e9e65994630a91 diff --git a/manifest.uuid b/manifest.uuid index c040ce2769..c450905317 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3178ec4c27efc4ff84bcd17ddb17ec50a6ac96b3 \ No newline at end of file +a5fe03bc419d9c7e6068ed38810e3f183de179b5 \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 1bcb62256c..7d7e70f901 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -259,7 +259,11 @@ typedef struct sqlite3 sqlite3; */ #ifdef SQLITE_INT64_TYPE typedef SQLITE_INT64_TYPE sqlite_int64; - typedef unsigned SQLITE_INT64_TYPE sqlite_uint64; +# ifdef SQLITE_UINT64_TYPE + typedef SQLITE_UINT64_TYPE sqlite_uint64; +# else + typedef unsigned SQLITE_INT64_TYPE sqlite_uint64; +# endif #elif defined(_MSC_VER) || defined(__BORLANDC__) typedef __int64 sqlite_int64; typedef unsigned __int64 sqlite_uint64; From e7b554d615072f16896a6879f582c935fa252a12 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 9 Jan 2017 15:44:25 +0000 Subject: [PATCH 1182/1484] Modify the OP_RowData opcode so that when P3!=0 it is allowed to hold an ephemeral copy of the content. This avoids unnecessary memcpy() operations in the xfer-optimization and VACUUM. FossilOrigin-Name: 6e106acd74da3baa5c308a76443d2f0a7c904e5e --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/insert.c | 4 ++-- src/vdbe.c | 27 +++++++++++++++++---------- 4 files changed, 27 insertions(+), 20 deletions(-) diff --git a/manifest b/manifest index 9ab624a73c..5fc4d50822 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sSQLITE_UINT64_TYPE\scompile-time\soption. -D 2017-01-09T13:43:09.245 +C Modify\sthe\sOP_RowData\sopcode\sso\sthat\swhen\sP3!=0\sit\sis\sallowed\sto\shold\san\nephemeral\scopy\sof\sthe\scontent.\s\sThis\savoids\sunnecessary\smemcpy()\soperations\nin\sthe\sxfer-optimization\sand\sVACUUM. +D 2017-01-09T15:44:25.721 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -350,7 +350,7 @@ F src/hash.c 63d0ee752a3b92d4695b2b1f5259c4621b2cfebd F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4 F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 -F src/insert.c ad2a0b2757a23b6f9297ee414eeab22b52fbde75 +F src/insert.c 7761fd63136771d411f096f4d7a1af9c5057ddd4 F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e F src/loadext.c 5d6642d141c07d366e43d359e94ec9de47add41d F src/main.c e207b81542d13b9f13d61e78ca441f9781f055b0 @@ -455,7 +455,7 @@ F src/update.c 1da7c462110bffed442a42884cb0d528c1db46d8 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c a88b0466fddf445ce752226d4698ca3faada620a F src/vacuum.c 33c174b28886b2faf26e503b5a49a1c01a9b1c16 -F src/vdbe.c 88bd6c32b333580d2661ac3afe33369757fb1522 +F src/vdbe.c b7f39cec8b572df61cdbd26426e285f8fd759db3 F src/vdbe.h b0866e4191f096f1c987a84b042c3599bdf5423b F src/vdbeInt.h 281cb70332dc8b593b8c7afe776f3a2ba7d4255e F src/vdbeapi.c d6ebaa465f070eb1af8ba4e7b34583ece87bdd24 @@ -1543,7 +1543,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 3178ec4c27efc4ff84bcd17ddb17ec50a6ac96b3 -R ff5d1e49d008400e89044e5b599d5e72 +P a5fe03bc419d9c7e6068ed38810e3f183de179b5 +R 1f3e0de052f41632eb2fb92e1db69d89 U drh -Z 9ff193ccbc51dd8562e9e65994630a91 +Z 8ba5841c95779521fe8c2f52b8a5492f diff --git a/manifest.uuid b/manifest.uuid index c450905317..78d290dd0b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a5fe03bc419d9c7e6068ed38810e3f183de179b5 \ No newline at end of file +6e106acd74da3baa5c308a76443d2f0a7c904e5e \ No newline at end of file diff --git a/src/insert.c b/src/insert.c index e55ea2d9fb..a33ee12353 100644 --- a/src/insert.c +++ b/src/insert.c @@ -2138,7 +2138,7 @@ static int xferOptimization( addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, regRowid); assert( (pDest->tabFlags & TF_Autoincrement)==0 ); } - sqlite3VdbeAddOp2(v, OP_RowData, iSrc, regData); + sqlite3VdbeAddOp3(v, OP_RowData, iSrc, regData, 1); if( db->flags & SQLITE_Vacuum ){ sqlite3VdbeAddOp3(v, OP_Last, iDest, 0, -1); insFlags = OPFLAG_NCHANGE|OPFLAG_LASTROWID| @@ -2170,7 +2170,7 @@ static int xferOptimization( sqlite3VdbeChangeP5(v, OPFLAG_BULKCSR); VdbeComment((v, "%s", pDestIdx->zName)); addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0); VdbeCoverage(v); - sqlite3VdbeAddOp2(v, OP_RowData, iSrc, regData); + sqlite3VdbeAddOp3(v, OP_RowData, iSrc, regData, 1); if( db->flags & SQLITE_Vacuum ){ /* This INSERT command is part of a VACUUM operation, which guarantees ** that the destination table is empty. If all indexed columns use diff --git a/src/vdbe.c b/src/vdbe.c index 5e707a6232..698092eb51 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -4632,7 +4632,7 @@ case OP_SorterData: { break; } -/* Opcode: RowData P1 P2 * * * +/* Opcode: RowData P1 P2 P3 * * ** Synopsis: r[P2]=data ** ** Write into register P2 the complete row content for the row at @@ -4646,14 +4646,26 @@ case OP_SorterData: { ** ** If the P1 cursor must be pointing to a valid row (not a NULL row) ** of a real table, not a pseudo-table. +** +** If P3!=0 then this opcode is allowed to make an ephermeral pointer +** into the database page. That means that the content of the output +** register will be invalidated as soon as the cursor moves - including +** moves caused by other cursors that "save" the the current cursors +** position in order that they can write to the same table. If P3==0 +** then a copy of the data is made into memory. P3!=0 is faster, but +** P3==0 is safer. +** +** If P3!=0 then the content of the P2 register is unsuitable for use +** in OP_Result and any OP_Result will invalidate the P2 register content. +** The P2 register content is invalided by opcodes like OP_Function or +** by any use of another cursor pointing to the same table. */ case OP_RowData: { VdbeCursor *pC; BtCursor *pCrsr; u32 n; - pOut = &aMem[pOp->p2]; - memAboutToChange(p, pOut); + pOut = out2Prerelease(p, pOp); assert( pOp->p1>=0 && pOp->p1nCursor ); pC = p->apCsr[pOp->p1]; @@ -4684,14 +4696,9 @@ case OP_RowData: { goto too_big; } testcase( n==0 ); - if( sqlite3VdbeMemClearAndResize(pOut, MAX(n,32)) ){ - goto no_mem; - } - pOut->n = n; - MemSetTypeFlag(pOut, MEM_Blob); - rc = sqlite3BtreePayload(pCrsr, 0, n, pOut->z); + rc = sqlite3VdbeMemFromBtree(pCrsr, 0, n, pOut); if( rc ) goto abort_due_to_error; - pOut->enc = SQLITE_UTF8; /* In case the blob is ever cast to text */ + if( !pOp->p3 ) Deephemeralize(pOut); UPDATE_MAX_BLOBSIZE(pOut); REGISTER_TRACE(pOp->p2, pOut); break; From ab61cf7d936bac8031d21803b6664cb4e5fc086e Mon Sep 17 00:00:00 2001 From: mistachkin Date: Mon, 9 Jan 2017 18:22:54 +0000 Subject: [PATCH 1183/1484] Fix typo in a comment. No changes to code. FossilOrigin-Name: d38fd22935b1572f4481b39c2f9274329b18ea99 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/vdbe.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 5fc4d50822..01cee64cec 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Modify\sthe\sOP_RowData\sopcode\sso\sthat\swhen\sP3!=0\sit\sis\sallowed\sto\shold\san\nephemeral\scopy\sof\sthe\scontent.\s\sThis\savoids\sunnecessary\smemcpy()\soperations\nin\sthe\sxfer-optimization\sand\sVACUUM. -D 2017-01-09T15:44:25.721 +C Fix\stypo\sin\sa\scomment.\s\sNo\schanges\sto\scode. +D 2017-01-09T18:22:54.898 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -455,7 +455,7 @@ F src/update.c 1da7c462110bffed442a42884cb0d528c1db46d8 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c a88b0466fddf445ce752226d4698ca3faada620a F src/vacuum.c 33c174b28886b2faf26e503b5a49a1c01a9b1c16 -F src/vdbe.c b7f39cec8b572df61cdbd26426e285f8fd759db3 +F src/vdbe.c 5c7338cc8b28c76a9fb680e18640fee948ae29b2 F src/vdbe.h b0866e4191f096f1c987a84b042c3599bdf5423b F src/vdbeInt.h 281cb70332dc8b593b8c7afe776f3a2ba7d4255e F src/vdbeapi.c d6ebaa465f070eb1af8ba4e7b34583ece87bdd24 @@ -1543,7 +1543,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a5fe03bc419d9c7e6068ed38810e3f183de179b5 -R 1f3e0de052f41632eb2fb92e1db69d89 -U drh -Z 8ba5841c95779521fe8c2f52b8a5492f +P 6e106acd74da3baa5c308a76443d2f0a7c904e5e +R bda8577547e21933c26bcd960cf7cb5b +U mistachkin +Z 7c89ce1d26860a2c4a6e46981671fc16 diff --git a/manifest.uuid b/manifest.uuid index 78d290dd0b..27218e961a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6e106acd74da3baa5c308a76443d2f0a7c904e5e \ No newline at end of file +d38fd22935b1572f4481b39c2f9274329b18ea99 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 698092eb51..3f165d9e89 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -4657,7 +4657,7 @@ case OP_SorterData: { ** ** If P3!=0 then the content of the P2 register is unsuitable for use ** in OP_Result and any OP_Result will invalidate the P2 register content. -** The P2 register content is invalided by opcodes like OP_Function or +** The P2 register content is invalidated by opcodes like OP_Function or ** by any use of another cursor pointing to the same table. */ case OP_RowData: { From 7441df72be8d36089c31f21a6157cbbbdfe6d212 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 9 Jan 2017 19:27:04 +0000 Subject: [PATCH 1184/1484] Performance optimization and size reduction in the OP_Variable opcode. FossilOrigin-Name: 237aa97452e20c312f256a8fd62531e3d447f84b --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/vdbe.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 01cee64cec..10b70530cc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\stypo\sin\sa\scomment.\s\sNo\schanges\sto\scode. -D 2017-01-09T18:22:54.898 +C Performance\soptimization\sand\ssize\sreduction\sin\sthe\sOP_Variable\sopcode. +D 2017-01-09T19:27:04.729 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -455,7 +455,7 @@ F src/update.c 1da7c462110bffed442a42884cb0d528c1db46d8 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c a88b0466fddf445ce752226d4698ca3faada620a F src/vacuum.c 33c174b28886b2faf26e503b5a49a1c01a9b1c16 -F src/vdbe.c 5c7338cc8b28c76a9fb680e18640fee948ae29b2 +F src/vdbe.c 51f0fb39cdd5f2307009887ff9aef075d5926a04 F src/vdbe.h b0866e4191f096f1c987a84b042c3599bdf5423b F src/vdbeInt.h 281cb70332dc8b593b8c7afe776f3a2ba7d4255e F src/vdbeapi.c d6ebaa465f070eb1af8ba4e7b34583ece87bdd24 @@ -1543,7 +1543,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 6e106acd74da3baa5c308a76443d2f0a7c904e5e -R bda8577547e21933c26bcd960cf7cb5b -U mistachkin -Z 7c89ce1d26860a2c4a6e46981671fc16 +P d38fd22935b1572f4481b39c2f9274329b18ea99 +R 7ff563d3f468514013639946cf62a576 +U drh +Z 47a0f13bc9d8903e7619705d6d0461a8 diff --git a/manifest.uuid b/manifest.uuid index 27218e961a..7009855f8c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d38fd22935b1572f4481b39c2f9274329b18ea99 \ No newline at end of file +237aa97452e20c312f256a8fd62531e3d447f84b \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 3f165d9e89..3f8dbd34c0 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -1195,7 +1195,7 @@ case OP_Variable: { /* out2 */ if( sqlite3VdbeMemTooBig(pVar) ){ goto too_big; } - pOut = out2Prerelease(p, pOp); + pOut = &aMem[pOp->p2]; sqlite3VdbeMemShallowCopy(pOut, pVar, MEM_Static); UPDATE_MAX_BLOBSIZE(pOut); break; From e4a8b8769e38fa62bfbada282b4a07cc8aea4ece Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 9 Jan 2017 19:55:19 +0000 Subject: [PATCH 1185/1484] Remove a redundant assignment statement. FossilOrigin-Name: a5fa09657bd6c4ea5fe6712b0f8af2170cbe0381 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 1 - 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 10b70530cc..6f2234dddb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Performance\soptimization\sand\ssize\sreduction\sin\sthe\sOP_Variable\sopcode. -D 2017-01-09T19:27:04.729 +C Remove\sa\sredundant\sassignment\sstatement. +D 2017-01-09T19:55:19.701 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -455,7 +455,7 @@ F src/update.c 1da7c462110bffed442a42884cb0d528c1db46d8 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c a88b0466fddf445ce752226d4698ca3faada620a F src/vacuum.c 33c174b28886b2faf26e503b5a49a1c01a9b1c16 -F src/vdbe.c 51f0fb39cdd5f2307009887ff9aef075d5926a04 +F src/vdbe.c 4c239b73d8df6ccd82842e2de0a882be46f6152d F src/vdbe.h b0866e4191f096f1c987a84b042c3599bdf5423b F src/vdbeInt.h 281cb70332dc8b593b8c7afe776f3a2ba7d4255e F src/vdbeapi.c d6ebaa465f070eb1af8ba4e7b34583ece87bdd24 @@ -1543,7 +1543,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d38fd22935b1572f4481b39c2f9274329b18ea99 -R 7ff563d3f468514013639946cf62a576 +P 237aa97452e20c312f256a8fd62531e3d447f84b +R 3d5f5ba0e62157717b12def8c248d9db U drh -Z 47a0f13bc9d8903e7619705d6d0461a8 +Z 6d8150e7f23763db279bf09c6fea02eb diff --git a/manifest.uuid b/manifest.uuid index 7009855f8c..5e3236a559 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -237aa97452e20c312f256a8fd62531e3d447f84b \ No newline at end of file +a5fa09657bd6c4ea5fe6712b0f8af2170cbe0381 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 3f8dbd34c0..7f6f21b6ea 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -5208,7 +5208,6 @@ case OP_IdxRowid: { /* out2 */ }else{ pOut = out2Prerelease(p, pOp); pOut->u.i = rowid; - pOut->flags = MEM_Int; } }else{ assert( pOp->opcode==OP_IdxRowid ); From d9bcb32ebb4b94df6c241bc09080cd0832d3a01b Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 10 Jan 2017 15:08:06 +0000 Subject: [PATCH 1186/1484] Fix a potential assertion fault discovered by OSS-Fuzz. FossilOrigin-Name: 71c03b59b645884ebd6b9e18713cd2eb8c949870 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/whereexpr.c | 10 +++++----- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 6f2234dddb..263f2b60cf 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sa\sredundant\sassignment\sstatement. -D 2017-01-09T19:55:19.701 +C Fix\sa\spotential\sassertion\sfault\sdiscovered\sby\sOSS-Fuzz. +D 2017-01-10T15:08:06.289 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -472,7 +472,7 @@ F src/walker.c 91a6df7435827e41cff6bb7df50ea00934ee78b0 F src/where.c 6bbf9284f4f15a6fa48663d033870cc0d7f5ee66 F src/whereInt.h 2bcc3d176e6091cb8f50a30b65c006e88a73614d F src/wherecode.c e04ac8f24c3ac8621df6c3be3ac8c7d4fa893745 -F src/whereexpr.c 87ecdf24beba4498e4380b31c4131febb0a6ceaa +F src/whereexpr.c 24e452bcc36ac19130706357bbec4c1419931222 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1543,7 +1543,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 237aa97452e20c312f256a8fd62531e3d447f84b -R 3d5f5ba0e62157717b12def8c248d9db +P a5fa09657bd6c4ea5fe6712b0f8af2170cbe0381 +R 9d11b71201b21d28f9619103dd00f618 U drh -Z 6d8150e7f23763db279bf09c6fea02eb +Z 82e96cf4e2e496f2e42165b862cbc10e diff --git a/manifest.uuid b/manifest.uuid index 5e3236a559..9a414db70b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a5fa09657bd6c4ea5fe6712b0f8af2170cbe0381 \ No newline at end of file +71c03b59b645884ebd6b9e18713cd2eb8c949870 \ No newline at end of file diff --git a/src/whereexpr.c b/src/whereexpr.c index 4bb161044e..27c6ebc2f1 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -913,6 +913,7 @@ static void exprAnalyze( Parse *pParse = pWInfo->pParse; /* Parsing context */ sqlite3 *db = pParse->db; /* Database connection */ unsigned char eOp2; /* op2 value for LIKE/REGEXP/GLOB */ + int nLeft; /* Number of elements on left side vector */ if( db->mallocFailed ){ return; @@ -1184,13 +1185,12 @@ static void exprAnalyze( ** is not a sub-select. */ if( pWC->op==TK_AND && (pExpr->op==TK_EQ || pExpr->op==TK_IS) - && sqlite3ExprIsVector(pExpr->pLeft) + && (nLeft = sqlite3ExprVectorSize(pExpr->pLeft))>1 + && sqlite3ExprVectorSize(pExpr->pRight)==nLeft && ( (pExpr->pLeft->flags & EP_xIsSelect)==0 - || (pExpr->pRight->flags & EP_xIsSelect)==0 - )){ - int nLeft = sqlite3ExprVectorSize(pExpr->pLeft); + || (pExpr->pRight->flags & EP_xIsSelect)==0) + ){ int i; - assert( nLeft==sqlite3ExprVectorSize(pExpr->pRight) ); for(i=0; i Date: Tue, 10 Jan 2017 16:09:46 +0000 Subject: [PATCH 1187/1484] Avoid unnecessary calls to the xRoundup() method of the memory allocator when the soft heap limit is not set. FossilOrigin-Name: 4209b89eab01814228a178963238e0dffffad2a4 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/malloc.c | 12 +++++------- 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index 263f2b60cf..d85a6d5b2c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\spotential\sassertion\sfault\sdiscovered\sby\sOSS-Fuzz. -D 2017-01-10T15:08:06.289 +C Avoid\sunnecessary\scalls\sto\sthe\sxRoundup()\smethod\sof\sthe\smemory\sallocator\swhen\nthe\ssoft\sheap\slimit\sis\snot\sset. +D 2017-01-10T16:09:46.718 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -354,7 +354,7 @@ F src/insert.c 7761fd63136771d411f096f4d7a1af9c5057ddd4 F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e F src/loadext.c 5d6642d141c07d366e43d359e94ec9de47add41d F src/main.c e207b81542d13b9f13d61e78ca441f9781f055b0 -F src/malloc.c f3fad34cd570022abca558c573f1761fb09a8212 +F src/malloc.c c36ef8fa6e4cc53ec258c5aa3ad86eb47350cc3d F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3 @@ -1543,7 +1543,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a5fa09657bd6c4ea5fe6712b0f8af2170cbe0381 -R 9d11b71201b21d28f9619103dd00f618 +P 71c03b59b645884ebd6b9e18713cd2eb8c949870 +R 631021f153b5b713372ffbd6126c74cb U drh -Z 82e96cf4e2e496f2e42165b862cbc10e +Z 02d94bfa17296c03c0e8153386f8771f diff --git a/manifest.uuid b/manifest.uuid index 9a414db70b..5b72849afa 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -71c03b59b645884ebd6b9e18713cd2eb8c949870 \ No newline at end of file +4209b89eab01814228a178963238e0dffffad2a4 \ No newline at end of file diff --git a/src/malloc.c b/src/malloc.c index 84191c78a1..053b57b47f 100644 --- a/src/malloc.c +++ b/src/malloc.c @@ -217,14 +217,13 @@ static void sqlite3MallocAlarm(int nByte){ ** Do a memory allocation with statistics and alarms. Assume the ** lock is already held. */ -static int mallocWithAlarm(int n, void **pp){ - int nFull; +static void mallocWithAlarm(int n, void **pp){ void *p; assert( sqlite3_mutex_held(mem0.mutex) ); - nFull = sqlite3GlobalConfig.m.xRoundup(n); sqlite3StatusHighwater(SQLITE_STATUS_MALLOC_SIZE, n); if( mem0.alarmThreshold>0 ){ sqlite3_int64 nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED); + int nFull = sqlite3GlobalConfig.m.xRoundup(n); if( nUsed >= mem0.alarmThreshold - nFull ){ mem0.nearlyFull = 1; sqlite3MallocAlarm(nFull); @@ -232,20 +231,19 @@ static int mallocWithAlarm(int n, void **pp){ mem0.nearlyFull = 0; } } - p = sqlite3GlobalConfig.m.xMalloc(nFull); + p = sqlite3GlobalConfig.m.xMalloc(n); #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT if( p==0 && mem0.alarmThreshold>0 ){ sqlite3MallocAlarm(nFull); - p = sqlite3GlobalConfig.m.xMalloc(nFull); + p = sqlite3GlobalConfig.m.xMalloc(n); } #endif if( p ){ - nFull = sqlite3MallocSize(p); + int nFull = sqlite3MallocSize(p); sqlite3StatusUp(SQLITE_STATUS_MEMORY_USED, nFull); sqlite3StatusUp(SQLITE_STATUS_MALLOC_COUNT, 1); } *pp = p; - return nFull; } /* From 8e36ddd37e5d664c30c20fb9f2e238229f4ad078 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 10 Jan 2017 17:33:43 +0000 Subject: [PATCH 1188/1484] Throw an error if the ON clause of a LEFT JOIN references tables to the right of the ON clause. Fix for ticket [25e335f802dd]. FossilOrigin-Name: c92ecff2ec5f178433d21f25c653d0fdd9128d7c --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/whereexpr.c | 4 ++++ 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index d85a6d5b2c..e94ce3d85b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sunnecessary\scalls\sto\sthe\sxRoundup()\smethod\sof\sthe\smemory\sallocator\swhen\nthe\ssoft\sheap\slimit\sis\snot\sset. -D 2017-01-10T16:09:46.718 +C Throw\san\serror\sif\sthe\sON\sclause\sof\sa\sLEFT\sJOIN\sreferences\stables\sto\sthe\sright\nof\sthe\sON\sclause.\s\sFix\sfor\sticket\s[25e335f802dd]. +D 2017-01-10T17:33:43.685 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -472,7 +472,7 @@ F src/walker.c 91a6df7435827e41cff6bb7df50ea00934ee78b0 F src/where.c 6bbf9284f4f15a6fa48663d033870cc0d7f5ee66 F src/whereInt.h 2bcc3d176e6091cb8f50a30b65c006e88a73614d F src/wherecode.c e04ac8f24c3ac8621df6c3be3ac8c7d4fa893745 -F src/whereexpr.c 24e452bcc36ac19130706357bbec4c1419931222 +F src/whereexpr.c 35ad025389a632a3987a35617c878be3b3d70dc6 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1543,7 +1543,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 71c03b59b645884ebd6b9e18713cd2eb8c949870 -R 631021f153b5b713372ffbd6126c74cb +P 4209b89eab01814228a178963238e0dffffad2a4 +R f2db398370e2f9344a20853ca8cb314d U drh -Z 02d94bfa17296c03c0e8153386f8771f +Z 014b9abce2c0eec156f7bce8e0868d39 diff --git a/manifest.uuid b/manifest.uuid index 5b72849afa..907b8ba384 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4209b89eab01814228a178963238e0dffffad2a4 \ No newline at end of file +c92ecff2ec5f178433d21f25c653d0fdd9128d7c \ No newline at end of file diff --git a/src/whereexpr.c b/src/whereexpr.c index 27c6ebc2f1..826d329b7f 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -943,6 +943,10 @@ static void exprAnalyze( prereqAll |= x; extraRight = x-1; /* ON clause terms may not be used with an index ** on left table of a LEFT JOIN. Ticket #3015 */ + if( (prereqAll>>1)>=x ){ + sqlite3ErrorMsg(pParse, "ON clause references tables to its right"); + return; + } } pTerm->prereqAll = prereqAll; pTerm->leftCursor = -1; From f112f0b3deb251173c6695769bf2f622bbaadfb6 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 10 Jan 2017 17:37:49 +0000 Subject: [PATCH 1189/1484] Add a test case for ticket [25e335f802dd]. FossilOrigin-Name: e500c15a9f55aed1601f7c14169dd56fd76f1fdd --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/join2.test | 22 +++++++++++++++++++++- 3 files changed, 29 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index e94ce3d85b..d7b4aa7e62 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Throw\san\serror\sif\sthe\sON\sclause\sof\sa\sLEFT\sJOIN\sreferences\stables\sto\sthe\sright\nof\sthe\sON\sclause.\s\sFix\sfor\sticket\s[25e335f802dd]. -D 2017-01-10T17:33:43.685 +C Add\sa\stest\scase\sfor\sticket\s[25e335f802dd]. +D 2017-01-10T17:37:49.188 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -880,7 +880,7 @@ F test/ioerr4.test f130fe9e71008577b342b8874d52984bd04ede2c F test/ioerr5.test 2edfa4fb0f896f733071303b42224df8bedd9da4 F test/ioerr6.test a395a6ab144b26a9e3e21059a1ab6a7149cca65b F test/join.test f9d4a28dec81c6e9dc21b73518e024d73b5ebf57 -F test/join2.test f2171c265e57ee298a27e57e7051d22962f9f324 +F test/join2.test a48f723c5692e2cbb23a9297ac2720cb77d51a70 F test/join3.test 6f0c774ff1ba0489e6c88a3e77b9d3528fb4fda0 F test/join4.test 1a352e4e267114444c29266ce79e941af5885916 F test/join5.test bc98ea4b4e5003f5b1453701ebb8cd7d1c01a550 @@ -1543,7 +1543,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 4209b89eab01814228a178963238e0dffffad2a4 -R f2db398370e2f9344a20853ca8cb314d -U drh -Z 014b9abce2c0eec156f7bce8e0868d39 +P c92ecff2ec5f178433d21f25c653d0fdd9128d7c +R e5ba5e796b740bb6ab62d42fde094373 +U dan +Z ef9b8c72a2a40eee5e78f0752f5e6ce0 diff --git a/manifest.uuid b/manifest.uuid index 907b8ba384..34fbf06d32 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c92ecff2ec5f178433d21f25c653d0fdd9128d7c \ No newline at end of file +e500c15a9f55aed1601f7c14169dd56fd76f1fdd \ No newline at end of file diff --git a/test/join2.test b/test/join2.test index 0f558c5a3d..9372e770c3 100644 --- a/test/join2.test +++ b/test/join2.test @@ -12,10 +12,10 @@ # # This file implements tests for joins, including outer joins. # -# $Id: join2.test,v 1.2 2005/01/21 03:12:16 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl +set testprefix join2 do_test join2-1.1 { execsql { @@ -72,4 +72,24 @@ ifcapable subquery { } {1 11 111 1111 2 22 {} {} 3 33 {} {}} } +#------------------------------------------------------------------------- +# Check that ticket [25e335f802ddc] has been resolved. It should be an +# error for the ON clause of a LEFT JOIN to refer to a table to its right. +# +do_execsql_test 2.0 { + CREATE TABLE aa(a); + CREATE TABLE bb(b); + CREATE TABLE cc(c); + INSERT INTO aa VALUES('one'); + INSERT INTO bb VALUES('one'); + INSERT INTO cc VALUES('one'); +} + +do_catchsql_test 2.1 { + SELECT * FROM aa LEFT JOIN cc ON (a=b) JOIN bb ON (b=c); +} {1 {ON clause references tables to its right}} +do_catchsql_test 2.2 { + SELECT * FROM aa JOIN cc ON (a=b) JOIN bb ON (b=c); +} {0 {one one one}} + finish_test From f91c1318f48febae7d3aac6c14b70068f1a2c375 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 10 Jan 2017 20:04:38 +0000 Subject: [PATCH 1190/1484] Changes to allow some multi-row UPDATE statements to avoid the two-pass approach. FossilOrigin-Name: 46db23ccd116ce5b9d949f9293be8a2818411b46 --- manifest | 30 ++++++----- manifest.uuid | 2 +- src/btree.c | 31 +++++++++-- src/btree.h | 5 +- src/insert.c | 10 +++- src/select.c | 2 +- src/sqliteInt.h | 4 +- src/update.c | 129 +++++++++++++++++++++++++++++----------------- src/vdbe.c | 4 +- src/where.c | 3 +- test/update2.test | 84 ++++++++++++++++++++++++++++++ 11 files changed, 228 insertions(+), 76 deletions(-) create mode 100644 test/update2.test diff --git a/manifest b/manifest index d7b4aa7e62..e5b56745a1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sa\stest\scase\sfor\sticket\s[25e335f802dd]. -D 2017-01-10T17:37:49.188 +C Changes\sto\sallow\ssome\smulti-row\sUPDATE\sstatements\sto\savoid\sthe\stwo-pass\napproach. +D 2017-01-10T20:04:38.186 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -331,8 +331,8 @@ F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792 F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca -F src/btree.c d2c100618784bd89c089fcef03ff6e789768ecae -F src/btree.h 2349a588abcd7e0c04f984e15c5c777b61637583 +F src/btree.c 44e9612965f63bef288673b81faa43e765bcac5f +F src/btree.h e6d352808956ec163a17f832193a3e198b3fb0ac F src/btreeInt.h 10c4b77c2fb399580babbcc7cf652ac10dba796e F src/build.c 9e799f1edd910dfa8a0bc29bd390d35d310596af F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 @@ -350,7 +350,7 @@ F src/hash.c 63d0ee752a3b92d4695b2b1f5259c4621b2cfebd F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4 F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 -F src/insert.c 7761fd63136771d411f096f4d7a1af9c5057ddd4 +F src/insert.c 05e47e2de7b712a3a4148cd469e5f60873f5ef13 F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e F src/loadext.c 5d6642d141c07d366e43d359e94ec9de47add41d F src/main.c e207b81542d13b9f13d61e78ca441f9781f055b0 @@ -388,12 +388,12 @@ F src/printf.c ff10a9b9902cd2afe5f655f3013c6307d969b1fd F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c bb070cf5f23611c44ab7e4788803684e385fc3fb F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac -F src/select.c 533e55a4067278fef76eff951462383d4147880f +F src/select.c 3856db523b942062bca8722ba03b61c324ff94d6 F src/shell.c 6095531aa900decdaa765e0f3993fba7153c92c1 F src/sqlite.h.in e71655293c9bde26939496f3aac9d1821d2c07a2 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae -F src/sqliteInt.h 9fdfb8789b27a621f3401468bc1705c32308f877 +F src/sqliteInt.h bec6274d8991528bc12d9a34d01fe84bdf6d00d9 F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 @@ -451,11 +451,11 @@ F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c 5c2f516876fc27fbd7753913f032f49eb89e83b5 F src/treeview.c 4e44ade3bfe59d82005039f72e09333ce2b4162c F src/trigger.c c9f0810043b265724fdb1bdd466894f984dfc182 -F src/update.c 1da7c462110bffed442a42884cb0d528c1db46d8 +F src/update.c 77a02122e040b8c6e1f13db9ef203e2224dae8f8 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c a88b0466fddf445ce752226d4698ca3faada620a F src/vacuum.c 33c174b28886b2faf26e503b5a49a1c01a9b1c16 -F src/vdbe.c 4c239b73d8df6ccd82842e2de0a882be46f6152d +F src/vdbe.c c7add5978cb84ae3a7bcb16f8b56cb3bbdf04b7e F src/vdbe.h b0866e4191f096f1c987a84b042c3599bdf5423b F src/vdbeInt.h 281cb70332dc8b593b8c7afe776f3a2ba7d4255e F src/vdbeapi.c d6ebaa465f070eb1af8ba4e7b34583ece87bdd24 @@ -469,7 +469,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 40c543f0a2195d1b0dc88ef12142bea690009344 F src/wal.h 06b2a0b599cc0f53ea97f497cf8c6b758c999f71 F src/walker.c 91a6df7435827e41cff6bb7df50ea00934ee78b0 -F src/where.c 6bbf9284f4f15a6fa48663d033870cc0d7f5ee66 +F src/where.c bc71775e23d23334e8f449aa31012d692dc09cb2 F src/whereInt.h 2bcc3d176e6091cb8f50a30b65c006e88a73614d F src/wherecode.c e04ac8f24c3ac8621df6c3be3ac8c7d4fa893745 F src/whereexpr.c 35ad025389a632a3987a35617c878be3b3d70dc6 @@ -1351,6 +1351,7 @@ F test/unique2.test 3674e9f2a3f1fbbfd4772ac74b7a97090d0f77d2 F test/unixexcl.test d936ba2b06794018e136418addd59a2354eeae97 F test/unordered.test ca7adce0419e4ca0c50f039885e76ed2c531eda8 F test/update.test 6c68446b8a0a33d522a7c72b320934596a2d7d32 +F test/update2.test e7f23b8ed101b7113c198bbd6f78f508718725c1 F test/uri.test 3481026f00ade6dfe8adb7acb6e1e47b04369568 F test/uri2.test 9d3ba7a53ee167572d53a298ee4a5d38ec4a8fb7 F test/userauth01.test e740a2697a7b40d7c5003a7d7edaee16acd349a9 @@ -1543,7 +1544,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P c92ecff2ec5f178433d21f25c653d0fdd9128d7c -R e5ba5e796b740bb6ab62d42fde094373 +P e500c15a9f55aed1601f7c14169dd56fd76f1fdd +R 210f82ca33b63d0d25de1e8cfd9403fd +T *branch * onepass-update +T *sym-onepass-update * +T -sym-trunk * U dan -Z ef9b8c72a2a40eee5e78f0752f5e6ce0 +Z 00c5ac8bc1c536bfb67f723788417749 diff --git a/manifest.uuid b/manifest.uuid index 34fbf06d32..00d064c0e5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e500c15a9f55aed1601f7c14169dd56fd76f1fdd \ No newline at end of file +46db23ccd116ce5b9d949f9293be8a2818411b46 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index f869761625..60f886bf5a 100644 --- a/src/btree.c +++ b/src/btree.c @@ -7948,7 +7948,7 @@ static int balance(BtCursor *pCur){ int sqlite3BtreeInsert( BtCursor *pCur, /* Insert data into the table of this cursor */ const BtreePayload *pX, /* Content of the row to be inserted */ - int appendBias, /* True if this is likely an append */ + int flags, /* True if this is likely an append */ int seekResult /* Result of prior MovetoUnpacked() call */ ){ int rc; @@ -7961,6 +7961,8 @@ int sqlite3BtreeInsert( unsigned char *oldCell; unsigned char *newCell = 0; + assert( (flags & (BTREE_SAVEPOSITION|BTREE_APPEND))==flags ); + if( pCur->eState==CURSOR_FAULT ){ assert( pCur->skipNext!=SQLITE_OK ); return pCur->skipNext; @@ -8001,6 +8003,11 @@ int sqlite3BtreeInsert( ** cursors open on the row being replaced */ invalidateIncrblobCursors(p, pX->nKey, 0); + /* If BTREE_SAVEPOSITION is set, the cursor must already be pointing + ** to a row with the same key as the new entry being inserted. */ + assert( (flags & BTREE_SAVEPOSITION)==0 || + ((pCur->curFlags&BTCF_ValidNKey)!=0 && pX->nKey==pCur->info.nKey) ); + /* If the cursor is currently on the last row and we are appending a ** new row onto the end, set the "loc" to avoid an unnecessary ** btreeMoveto() call */ @@ -8010,10 +8017,10 @@ int sqlite3BtreeInsert( && pCur->info.nKey==pX->nKey-1 ){ loc = -1; }else if( loc==0 ){ - rc = sqlite3BtreeMovetoUnpacked(pCur, 0, pX->nKey, appendBias, &loc); + rc = sqlite3BtreeMovetoUnpacked(pCur, 0, pX->nKey, flags!=0, &loc); if( rc ) return rc; } - }else if( loc==0 ){ + }else if( loc==0 && (flags & BTREE_SAVEPOSITION)==0 ){ if( pX->nMem ){ UnpackedRecord r; r.pKeyInfo = pCur->pKeyInfo; @@ -8024,9 +8031,9 @@ int sqlite3BtreeInsert( r.r1 = 0; r.r2 = 0; r.eqSeen = 0; - rc = sqlite3BtreeMovetoUnpacked(pCur, &r, 0, appendBias, &loc); + rc = sqlite3BtreeMovetoUnpacked(pCur, &r, 0, flags!=0, &loc); }else{ - rc = btreeMoveto(pCur, pX->pKey, pX->nKey, appendBias, &loc); + rc = btreeMoveto(pCur, pX->pKey, pX->nKey, flags!=0, &loc); } if( rc ) return rc; } @@ -8114,6 +8121,20 @@ int sqlite3BtreeInsert( ** from trying to save the current position of the cursor. */ pCur->apPage[pCur->iPage]->nOverflow = 0; pCur->eState = CURSOR_INVALID; + if( (flags & BTREE_SAVEPOSITION) && rc==SQLITE_OK ){ + rc = moveToRoot(pCur); + if( pCur->pKeyInfo && rc==SQLITE_OK ){ + assert( pCur->pKey==0 ); + pCur->pKey = sqlite3Malloc( pX->nKey ); + if( pCur->pKey==0 ){ + rc = SQLITE_NOMEM; + }else{ + memcpy(pCur->pKey, pX->pKey, pX->nKey); + } + } + pCur->eState = CURSOR_REQUIRESEEK; + pCur->nKey = pX->nKey; + } } assert( pCur->apPage[pCur->iPage]->nOverflow==0 ); diff --git a/src/btree.h b/src/btree.h index 5e54125d39..ae57468e3f 100644 --- a/src/btree.h +++ b/src/btree.h @@ -249,9 +249,10 @@ int sqlite3BtreeCursorHasMoved(BtCursor*); int sqlite3BtreeCursorRestore(BtCursor*, int*); int sqlite3BtreeDelete(BtCursor*, u8 flags); -/* Allowed flags for the 2nd argument to sqlite3BtreeDelete() */ +/* Allowed flags for sqlite3BtreeDelete() and sqlite3BtreeInsert() */ #define BTREE_SAVEPOSITION 0x02 /* Leave cursor pointing at NEXT or PREV */ #define BTREE_AUXDELETE 0x04 /* not the primary delete operation */ +#define BTREE_APPEND 0x08 /* Insert is likely an append */ /* An instance of the BtreePayload object describes the content of a single ** entry in either an index or table btree. @@ -282,7 +283,7 @@ struct BtreePayload { }; int sqlite3BtreeInsert(BtCursor*, const BtreePayload *pPayload, - int bias, int seekResult); + int flags, int seekResult); int sqlite3BtreeFirst(BtCursor*, int *pRes); int sqlite3BtreeLast(BtCursor*, int *pRes); int sqlite3BtreeNext(BtCursor*, int *pRes); diff --git a/src/insert.c b/src/insert.c index a33ee12353..93c22ae3f5 100644 --- a/src/insert.c +++ b/src/insert.c @@ -1684,7 +1684,7 @@ void sqlite3CompleteInsertion( int iIdxCur, /* First index cursor */ int regNewData, /* Range of content */ int *aRegIdx, /* Register used by each index. 0 for unused indices */ - int isUpdate, /* True for UPDATE, False for INSERT */ + int update_flags, /* True for UPDATE, False for INSERT */ int appendBias, /* True if this is likely to be an append */ int useSeekResult /* True to set the USESEEKRESULT flag on OP_[Idx]Insert */ ){ @@ -1696,6 +1696,11 @@ void sqlite3CompleteInsertion( int i; /* Loop counter */ u8 bAffinityDone = 0; /* True if OP_Affinity has been run already */ + assert( update_flags==0 + || update_flags==OPFLAG_ISUPDATE + || update_flags==(OPFLAG_ISUPDATE|OPFLAG_SAVEPOSITION) + ); + v = sqlite3GetVdbe(pParse); assert( v!=0 ); assert( pTab->pSelect==0 ); /* This table is not a VIEW */ @@ -1714,6 +1719,7 @@ void sqlite3CompleteInsertion( if( IsPrimaryKeyIndex(pIdx) && !HasRowid(pTab) ){ assert( pParse->nested==0 ); pik_flags |= OPFLAG_NCHANGE; + pik_flags |= (update_flags & OPFLAG_SAVEPOSITION); } sqlite3VdbeChangeP5(v, pik_flags); } @@ -1729,7 +1735,7 @@ void sqlite3CompleteInsertion( pik_flags = 0; }else{ pik_flags = OPFLAG_NCHANGE; - pik_flags |= (isUpdate?OPFLAG_ISUPDATE:OPFLAG_LASTROWID); + pik_flags |= (update_flags?update_flags:OPFLAG_LASTROWID); } if( appendBias ){ pik_flags |= OPFLAG_APPEND; diff --git a/src/select.c b/src/select.c index e750fd324d..ed6221309f 100644 --- a/src/select.c +++ b/src/select.c @@ -5652,7 +5652,7 @@ int sqlite3Select( ** of output. */ resetAccumulator(pParse, &sAggInfo); - pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pMinMax,0,flag,0); + pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pMinMax, 0,flag,0); if( pWInfo==0 ){ sqlite3ExprListDelete(db, pDel); goto select_end; diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 8cfa0f88f7..3215a7f865 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3041,7 +3041,7 @@ struct AuthContext { #define OPFLAG_NCHANGE 0x01 /* OP_Insert: Set to update db->nChange */ /* Also used in P2 (not P5) of OP_Delete */ #define OPFLAG_EPHEM 0x01 /* OP_Column: Ephemeral output is ok */ -#define OPFLAG_LASTROWID 0x02 /* Set to update db->lastRowid */ +#define OPFLAG_LASTROWID 0x20 /* Set to update db->lastRowid */ #define OPFLAG_ISUPDATE 0x04 /* This OP_Insert is an sql UPDATE */ #define OPFLAG_APPEND 0x08 /* This is likely to be an append */ #define OPFLAG_USESEEKRESULT 0x10 /* Try to avoid a seek in BtreeInsert() */ @@ -3055,7 +3055,7 @@ struct AuthContext { #define OPFLAG_FORDELETE 0x08 /* OP_Open should use BTREE_FORDELETE */ #define OPFLAG_P2ISREG 0x10 /* P2 to OP_Open** is a register number */ #define OPFLAG_PERMUTE 0x01 /* OP_Compare: use the permutation */ -#define OPFLAG_SAVEPOSITION 0x02 /* OP_Delete: keep cursor position */ +#define OPFLAG_SAVEPOSITION 0x02 /* OP_Delete/Insert: save cursor pos */ #define OPFLAG_AUXDELETE 0x04 /* OP_Delete: index in a DELETE op */ /* diff --git a/src/update.c b/src/update.c index 5f89e31dac..c99a4b6e8c 100644 --- a/src/update.c +++ b/src/update.c @@ -105,7 +105,7 @@ void sqlite3Update( int iDataCur; /* Cursor for the canonical data btree */ int iIdxCur; /* Cursor for the first index */ sqlite3 *db; /* The database structure */ - int *aRegIdx = 0; /* One register assigned to each index to be updated */ + int *aRegIdx = 0; /* First register in array assigned to each index */ int *aXRef = 0; /* aXRef[i] is the index in pChanges->a[] of the ** an expression for the i-th column of the table. ** aXRef[i]==-1 if the i-th column is not changed. */ @@ -117,10 +117,11 @@ void sqlite3Update( AuthContext sContext; /* The authorization context */ NameContext sNC; /* The name-context to resolve expressions in */ int iDb; /* Database containing the table being updated */ - int okOnePass; /* True for one-pass algorithm without the FIFO */ + int eOnePass; /* ONEPASS_XXX value from where.c */ int hasFK; /* True if foreign key processing is required */ int labelBreak; /* Jump here to break out of UPDATE loop */ int labelContinue; /* Jump here to continue next step of UPDATE loop */ + int flags; /* Flags for sqlite3WhereBegin() */ #ifndef SQLITE_OMIT_TRIGGER int isView; /* True when updating a view (INSTEAD OF trigger) */ @@ -131,6 +132,9 @@ void sqlite3Update( int iEph = 0; /* Ephemeral table holding all primary key values */ int nKey = 0; /* Number of elements in regKey for WITHOUT ROWID */ int aiCurOnePass[2]; /* The write cursors opened by WHERE_ONEPASS */ + int addrOpen; /* Address of OP_OpenEphemeral */ + int iPk; /* First of nPk cells holding PRIMARY KEY value */ + i16 nPk; /* Number of components of the PRIMARY KEY */ /* Register Allocations */ int regRowCount = 0; /* A count of rows changed */ @@ -349,51 +353,70 @@ void sqlite3Update( } #endif - /* Begin the database scan - */ + /* Initialize the count of updated rows */ + if( (db->flags & SQLITE_CountRows) && !pParse->pTriggerTab ){ + regRowCount = ++pParse->nMem; + sqlite3VdbeAddOp2(v, OP_Integer, 0, regRowCount); + } + if( HasRowid(pTab) ){ sqlite3VdbeAddOp3(v, OP_Null, 0, regRowSet, regOldRowid); - pWInfo = sqlite3WhereBegin( - pParse, pTabList, pWhere, 0, 0, - WHERE_ONEPASS_DESIRED | WHERE_SEEK_TABLE, iIdxCur - ); - if( pWInfo==0 ) goto update_cleanup; - okOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass); - - /* Remember the rowid of every item to be updated. - */ - sqlite3VdbeAddOp2(v, OP_Rowid, iDataCur, regOldRowid); - if( !okOnePass ){ - sqlite3VdbeAddOp2(v, OP_RowSetAdd, regRowSet, regOldRowid); - } - - /* End the database scan loop. - */ - sqlite3WhereEnd(pWInfo); }else{ - int iPk; /* First of nPk memory cells holding PRIMARY KEY value */ - i16 nPk; /* Number of components of the PRIMARY KEY */ - int addrOpen; /* Address of the OpenEphemeral instruction */ - assert( pPk!=0 ); nPk = pPk->nKeyCol; iPk = pParse->nMem+1; pParse->nMem += nPk; regKey = ++pParse->nMem; iEph = pParse->nTab++; + sqlite3VdbeAddOp2(v, OP_Null, 0, iPk); addrOpen = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iEph, nPk); sqlite3VdbeSetP4KeyInfo(pParse, pPk); - pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0, - WHERE_ONEPASS_DESIRED, iIdxCur); - if( pWInfo==0 ) goto update_cleanup; - okOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass); + } + + /* Begin the database scan. */ + flags = WHERE_ONEPASS_DESIRED | WHERE_SEEK_TABLE; + if( pParse->nested==0 && pTrigger==0 && hasFK==0 && chngKey==0 ){ + flags |= WHERE_ONEPASS_MULTIROW; + } + pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0, flags, iIdxCur); + if( pWInfo==0 ) goto update_cleanup; + + /* A one-pass strategy that might update more than one row may not + ** be used if any column of the index used for the scan is being + ** updated. Otherwise, if there is an index on "b", statements like + ** the following could create an infinite loop: + ** + ** UPDATE t1 SET b=b+1 WHERE b>? + ** + ** Fall back to ONEPASS_OFF if where.c has selected a ONEPASS_MULTI + ** strategy that uses an index for which one or more columns are being + ** updated. */ + eOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass); + if( eOnePass==ONEPASS_MULTI ){ + int iCur = aiCurOnePass[1]; + if( iCur>=0 && aToOpen[iCur-iBaseCur] ) eOnePass = ONEPASS_OFF; + } + + if( HasRowid(pTab) ){ + /* Read the rowid of the current row of the WHERE scan. In ONEPASS_OFF + ** mode, write the rowid into the FIFO. In either of the one-pass modes, + ** leave it in register regOldRowid. */ + sqlite3VdbeAddOp2(v, OP_Rowid, iDataCur, regOldRowid); + if( eOnePass==ONEPASS_OFF ){ + sqlite3VdbeAddOp2(v, OP_RowSetAdd, regRowSet, regOldRowid); + } + }else{ + /* Read the PK of the current row into an array of registers. In + ** ONEPASS_OFF mode, serialize the array into a record and store it in + ** the ephemeral table. Or, in ONEPASS_SINGLE or MULTI mode, change + ** the OP_OpenEphemeral instruction to a Noop (the ephemeral table + ** is not required) and leave the PK fields in the array of registers. */ for(i=0; iaiColumn[i]>=0 ); - sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, pPk->aiColumn[i], - iPk+i); + sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur,pPk->aiColumn[i],iPk+i); } - if( okOnePass ){ + if( eOnePass ){ sqlite3VdbeChangeToNoop(v, addrOpen); nKey = nPk; regKey = iPk; @@ -402,18 +425,15 @@ void sqlite3Update( sqlite3IndexAffinityStr(db, pPk), nPk); sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iEph, regKey, iPk, nPk); } - sqlite3WhereEnd(pWInfo); } - /* Initialize the count of updated rows - */ - if( (db->flags & SQLITE_CountRows) && !pParse->pTriggerTab ){ - regRowCount = ++pParse->nMem; - sqlite3VdbeAddOp2(v, OP_Integer, 0, regRowCount); + if( eOnePass!=ONEPASS_MULTI ){ + sqlite3WhereEnd(pWInfo); } labelBreak = sqlite3VdbeMakeLabel(v); if( !isView ){ + int iAddrOnce = 0; /* ** Open every index that needs updating. Note that if any ** index could potentially invoke a REPLACE conflict resolution @@ -430,22 +450,31 @@ void sqlite3Update( } } } - if( okOnePass ){ + if( eOnePass!=ONEPASS_OFF ){ if( aiCurOnePass[0]>=0 ) aToOpen[aiCurOnePass[0]-iBaseCur] = 0; if( aiCurOnePass[1]>=0 ) aToOpen[aiCurOnePass[1]-iBaseCur] = 0; } + + if( eOnePass==ONEPASS_MULTI && (nIdx-(aiCurOnePass[1]>=0))>0 ){ + iAddrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); + } sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, 0, iBaseCur, aToOpen, 0, 0); + if( iAddrOnce ) sqlite3VdbeJumpHere(v, iAddrOnce); } /* Top of the update loop */ - if( okOnePass ){ - if( aToOpen[iDataCur-iBaseCur] && !isView ){ + if( eOnePass!=ONEPASS_OFF ){ + if( !isView && aiCurOnePass[0]!=iDataCur && aiCurOnePass[1]!=iDataCur ){ assert( pPk ); sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelBreak, regKey, nKey); VdbeCoverageNeverTaken(v); } - labelContinue = labelBreak; + if( eOnePass==ONEPASS_SINGLE ){ + labelContinue = labelBreak; + }else{ + labelContinue = sqlite3VdbeMakeLabel(v); + } sqlite3VdbeAddOp2(v, OP_IsNull, pPk ? regKey : regOldRowid, labelBreak); VdbeCoverageIf(v, pPk==0); VdbeCoverageIf(v, pPk!=0); @@ -606,14 +635,14 @@ void sqlite3Update( assert( regNew==regNewRowid+1 ); #ifdef SQLITE_ENABLE_PREUPDATE_HOOK sqlite3VdbeAddOp3(v, OP_Delete, iDataCur, - OPFLAG_ISUPDATE | ((hasFK || chngKey || pPk!=0) ? 0 : OPFLAG_ISNOOP), + OPFLAG_ISUPDATE | ((hasFK || chngKey) ? 0 : OPFLAG_ISNOOP), regNewRowid ); if( !pParse->nested ){ sqlite3VdbeAppendP4(v, pTab, P4_TABLE); } #else - if( hasFK || chngKey || pPk!=0 ){ + if( hasFK || chngKey ){ sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, 0); } #endif @@ -626,8 +655,11 @@ void sqlite3Update( } /* Insert the new index entries and the new record. */ - sqlite3CompleteInsertion(pParse, pTab, iDataCur, iIdxCur, - regNewRowid, aRegIdx, 1, 0, 0); + sqlite3CompleteInsertion( + pParse, pTab, iDataCur, iIdxCur, regNewRowid, aRegIdx, + OPFLAG_ISUPDATE | (eOnePass==ONEPASS_MULTI ? OPFLAG_SAVEPOSITION : 0), + 0, 0 + ); /* Do any ON CASCADE, SET NULL or SET DEFAULT operations required to ** handle rows (possibly in other tables) that refer via a foreign key @@ -649,8 +681,11 @@ void sqlite3Update( /* Repeat the above with the next record to be updated, until ** all record selected by the WHERE clause have been updated. */ - if( okOnePass ){ + if( eOnePass==ONEPASS_SINGLE ){ /* Nothing to do at end-of-loop for a single-pass */ + }else if( eOnePass==ONEPASS_MULTI ){ + sqlite3VdbeResolveLabel(v, labelContinue); + sqlite3WhereEnd(pWInfo); }else if( pPk ){ sqlite3VdbeResolveLabel(v, labelContinue); sqlite3VdbeAddOp2(v, OP_Next, iEph, addrTop); VdbeCoverage(v); diff --git a/src/vdbe.c b/src/vdbe.c index 7f6f21b6ea..cbb7867512 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -4421,7 +4421,7 @@ case OP_InsertInt: { } x.pKey = 0; rc = sqlite3BtreeInsert(pC->uc.pCursor, &x, - (pOp->p5 & OPFLAG_APPEND)!=0, seekResult + (pOp->p5 & (OPFLAG_APPEND|OPFLAG_SAVEPOSITION)), seekResult ); pC->deferredMoveto = 0; pC->cacheStatus = CACHE_STALE; @@ -5086,7 +5086,7 @@ case OP_IdxInsert: { /* in2 */ x.aMem = aMem + pOp->p3; x.nMem = (u16)pOp->p4.i; rc = sqlite3BtreeInsert(pC->uc.pCursor, &x, - (pOp->p5 & OPFLAG_APPEND)!=0, + (pOp->p5 & (OPFLAG_APPEND|OPFLAG_SAVEPOSITION)), ((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0) ); assert( pC->deferredMoveto==0 ); diff --git a/src/where.c b/src/where.c index 81cc1f131b..4951f6a1b4 100644 --- a/src/where.c +++ b/src/where.c @@ -4949,7 +4949,8 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ pOp->p2 = x; pOp->p1 = pLevel->iIdxCur; } - assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 || x>=0 ); + assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 || x>=0 + || pWInfo->eOnePass ); }else if( pOp->opcode==OP_Rowid ){ pOp->p1 = pLevel->iIdxCur; pOp->opcode = OP_IdxRowid; diff --git a/test/update2.test b/test/update2.test new file mode 100644 index 0000000000..fad31ec423 --- /dev/null +++ b/test/update2.test @@ -0,0 +1,84 @@ +# 2017 January 9 +# +# 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. +# +#*********************************************************************** +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix update2 + +db func repeat [list string repeat] + +#------------------------------------------------------------------------- +# 1.1.* A one-pass UPDATE that does balance() operations on the IPK index +# that it is scanning. +# +# 1.2.* Same again, but with a WITHOUT ROWID table. +# +set nrow [expr 10] +do_execsql_test 1.1.0 { + CREATE TABLE t1(a INTEGER PRIMARY KEY, b); + CREATE TABLE t2(a INTEGER PRIMARY KEY, b); + WITH s(i) AS ( SELECT 0 UNION ALL SELECT i+1 FROM s WHERE i<$nrow ) + INSERT INTO t1(b) SELECT char((i % 26) + 65) FROM s; + INSERT INTO t2 SELECT * FROM t1; +} + +do_execsql_test 1.1.1 { + UPDATE t1 SET b = repeat(b, 100) +} + +do_execsql_test 1.1.2 { + SELECT * FROM t1; +} [db eval { SELECT a, repeat(b, 100) FROM t2 }] + +do_execsql_test 1.2.0 { + DROP TABLE t1; + CREATE TABLE t1(a INT PRIMARY KEY, b) WITHOUT ROWID; + WITH s(i) AS ( SELECT 0 UNION ALL SELECT i+1 FROM s WHERE i<$nrow ) + INSERT INTO t1(a, b) SELECT i+1, char((i % 26) + 65) FROM s; +} + +#explain_i { UPDATE t1 SET b = repeat(b, 100) } +do_execsql_test 1.2.1 { + UPDATE t1 SET b = repeat(b, 100) +} + +do_execsql_test 1.2.2 { + SELECT * FROM t1; +} [db eval { SELECT a, repeat(b, 100) FROM t2 }] + + +#------------------------------------------------------------------------- +# A one-pass UPDATE that does balance() operations on the IPK index +# that it is scanning. +# +do_execsql_test 2.1 { + CREATE TABLE t3(a PRIMARY KEY, b, c); + CREATE INDEX t3i ON t3(b); +} {} +do_execsql_test 2.2 { UPDATE t3 SET c=1 WHERE b=? } {} +do_execsql_test 2.3 { UPDATE t3 SET c=1 WHERE rowid=? } {} + +#------------------------------------------------------------------------- +# +do_execsql_test 3.0 { + CREATE TABLE t4(a PRIMARY KEY, b, c) WITHOUT ROWID; + CREATE INDEX t4c ON t4(c); + INSERT INTO t4 VALUES(1, 2, 3); + INSERT INTO t4 VALUES(2, 3, 4); +} + +do_execsql_test 3.1 { + UPDATE t4 SET c=c+2 WHERE c>2; + SELECT a, c FROM t4 ORDER BY a; +} {1 5 2 6} + +finish_test From 785d8ed0d4d5f038b6731420b3daff1798711b48 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 11 Jan 2017 14:15:29 +0000 Subject: [PATCH 1191/1484] In the STAT4 computations, ensure that the aAvgEq values do not go negative. FossilOrigin-Name: f58f75b5a06f88ba97bd1a02bee621c64691c6f8 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/analyze.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index d7b4aa7e62..60b608e6c7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sa\stest\scase\sfor\sticket\s[25e335f802dd]. -D 2017-01-10T17:37:49.188 +C In\sthe\sSTAT4\scomputations,\sensure\sthat\sthe\saAvgEq\svalues\sdo\snot\sgo\snegative. +D 2017-01-11T14:15:29.635 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -325,7 +325,7 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F src/alter.c 3b23977620ce9662ac54443f65b87ba996e36121 -F src/analyze.c 3c4a63ff7a55faefecf6eb1589932fdbc06b2415 +F src/analyze.c 317dbaf31c16050582b09bf4f323b4e0f1813251 F src/attach.c 8c476f8bd5d2afe11d925f890d30e527e5b0ce43 F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792 F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b @@ -1543,7 +1543,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P c92ecff2ec5f178433d21f25c653d0fdd9128d7c -R e5ba5e796b740bb6ab62d42fde094373 -U dan -Z ef9b8c72a2a40eee5e78f0752f5e6ce0 +P e500c15a9f55aed1601f7c14169dd56fd76f1fdd +R 5c2e2ea0b7d53513cb0d1e5b25773986 +U drh +Z ed5473ac37dfd76118f46ef5f94f7fb6 diff --git a/manifest.uuid b/manifest.uuid index 34fbf06d32..1657a590c9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e500c15a9f55aed1601f7c14169dd56fd76f1fdd \ No newline at end of file +f58f75b5a06f88ba97bd1a02bee621c64691c6f8 \ No newline at end of file diff --git a/src/analyze.c b/src/analyze.c index c480a0c507..c079132f4a 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -1615,7 +1615,7 @@ static void initAvgEq(Index *pIdx){ } } - if( nDist100>nSum100 ){ + if( nDist100>nSum100 && sumEq Date: Wed, 11 Jan 2017 15:42:14 +0000 Subject: [PATCH 1192/1484] Fix a problem preventing UPDATE statements that use a range-scan on the PK index of a WITHOUT ROWID table from using a one-pass strategy. FossilOrigin-Name: cab86c90945126c24c40cf2dedd053a8c46d00d6 --- manifest | 17 +++++++---------- manifest.uuid | 2 +- src/update.c | 5 ++++- test/update2.test | 34 ++++++++++++++++++++++++++++++++++ 4 files changed, 46 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index e5b56745a1..5190754865 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Changes\sto\sallow\ssome\smulti-row\sUPDATE\sstatements\sto\savoid\sthe\stwo-pass\napproach. -D 2017-01-10T20:04:38.186 +C Fix\sa\sproblem\spreventing\sUPDATE\sstatements\sthat\suse\sa\srange-scan\son\sthe\sPK\nindex\sof\sa\sWITHOUT\sROWID\stable\sfrom\susing\sa\sone-pass\sstrategy. +D 2017-01-11T15:42:14.353 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -451,7 +451,7 @@ F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c 5c2f516876fc27fbd7753913f032f49eb89e83b5 F src/treeview.c 4e44ade3bfe59d82005039f72e09333ce2b4162c F src/trigger.c c9f0810043b265724fdb1bdd466894f984dfc182 -F src/update.c 77a02122e040b8c6e1f13db9ef203e2224dae8f8 +F src/update.c 117bb080654b8c382b590b369f174ec11cca5bb0 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c a88b0466fddf445ce752226d4698ca3faada620a F src/vacuum.c 33c174b28886b2faf26e503b5a49a1c01a9b1c16 @@ -1351,7 +1351,7 @@ F test/unique2.test 3674e9f2a3f1fbbfd4772ac74b7a97090d0f77d2 F test/unixexcl.test d936ba2b06794018e136418addd59a2354eeae97 F test/unordered.test ca7adce0419e4ca0c50f039885e76ed2c531eda8 F test/update.test 6c68446b8a0a33d522a7c72b320934596a2d7d32 -F test/update2.test e7f23b8ed101b7113c198bbd6f78f508718725c1 +F test/update2.test 2b678973f882d11496f998c01b310be4c4a65a70 F test/uri.test 3481026f00ade6dfe8adb7acb6e1e47b04369568 F test/uri2.test 9d3ba7a53ee167572d53a298ee4a5d38ec4a8fb7 F test/userauth01.test e740a2697a7b40d7c5003a7d7edaee16acd349a9 @@ -1544,10 +1544,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e500c15a9f55aed1601f7c14169dd56fd76f1fdd -R 210f82ca33b63d0d25de1e8cfd9403fd -T *branch * onepass-update -T *sym-onepass-update * -T -sym-trunk * +P 46db23ccd116ce5b9d949f9293be8a2818411b46 +R a3998d49adecb7e21ad8d0444ff44124 U dan -Z 00c5ac8bc1c536bfb67f723788417749 +Z c5a6bc3f18beb290c2a3c904ee96a0c7 diff --git a/manifest.uuid b/manifest.uuid index 00d064c0e5..294d40d293 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -46db23ccd116ce5b9d949f9293be8a2818411b46 \ No newline at end of file +cab86c90945126c24c40cf2dedd053a8c46d00d6 \ No newline at end of file diff --git a/src/update.c b/src/update.c index c99a4b6e8c..acf43034ff 100644 --- a/src/update.c +++ b/src/update.c @@ -395,7 +395,10 @@ void sqlite3Update( eOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass); if( eOnePass==ONEPASS_MULTI ){ int iCur = aiCurOnePass[1]; - if( iCur>=0 && aToOpen[iCur-iBaseCur] ) eOnePass = ONEPASS_OFF; + if( iCur>=0 && iCur!=iDataCur && aToOpen[iCur-iBaseCur] ){ + eOnePass = ONEPASS_OFF; + } + assert( iCur!=iDataCur || !HasRowid(pTab) ); } if( HasRowid(pTab) ){ diff --git a/test/update2.test b/test/update2.test index fad31ec423..8aafb2438b 100644 --- a/test/update2.test +++ b/test/update2.test @@ -81,4 +81,38 @@ do_execsql_test 3.1 { SELECT a, c FROM t4 ORDER BY a; } {1 5 2 6} +#------------------------------------------------------------------------- +# +foreach {tn sql} { + 1 { CREATE TABLE b1(a INTEGER PRIMARY KEY, b, c) } + 2 { CREATE TABLE b1(a INT PRIMARY KEY, b, c) WITHOUT ROWID } +} { + execsql { DROP TABLE IF EXISTS b1 } + execsql $sql + do_execsql_test 4.$tn.0 { + CREATE UNIQUE INDEX b1c ON b1(c); + + INSERT INTO b1 VALUES(1, 'a', 1); + INSERT INTO b1 VALUES(2, 'b', 15); + INSERT INTO b1 VALUES(3, 'c', 3); + INSERT INTO b1 VALUES(4, 'd', 4); + INSERT INTO b1 VALUES(5, 'e', 5); + INSERT INTO b1 VALUES(6, 'f', 6); + INSERT INTO b1 VALUES(7, 'g', 7); + } + + do_execsql_test 4.$tn.1 { + UPDATE OR REPLACE b1 SET c=c+10 WHERE a BETWEEN 4 AND 7; + SELECT * FROM b1 ORDER BY a; + } { + 1 a 1 + 3 c 3 + 4 d 14 + 5 e 15 + 6 f 16 + 7 g 17 + } +} + + finish_test From 2c6fec21dc38810eacc702467f2b909f7325608f Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 11 Jan 2017 19:03:08 +0000 Subject: [PATCH 1193/1484] Fix a problem with single-pass multi-row UPDATE statements that invoke REPLACE conflict handling. FossilOrigin-Name: 0a2b8e1b9dc600b5a93622e8eea6218649df5e0f --- manifest | 14 ++++----- manifest.uuid | 2 +- src/update.c | 46 +++++++++++++++--------------- test/update2.test | 72 +++++++++++++++++++++++++++++++++++++++++++---- 4 files changed, 99 insertions(+), 35 deletions(-) diff --git a/manifest b/manifest index 5190754865..95612d61fb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\spreventing\sUPDATE\sstatements\sthat\suse\sa\srange-scan\son\sthe\sPK\nindex\sof\sa\sWITHOUT\sROWID\stable\sfrom\susing\sa\sone-pass\sstrategy. -D 2017-01-11T15:42:14.353 +C Fix\sa\sproblem\swith\ssingle-pass\smulti-row\sUPDATE\sstatements\sthat\sinvoke\sREPLACE\nconflict\shandling. +D 2017-01-11T19:03:08.308 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -451,7 +451,7 @@ F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c 5c2f516876fc27fbd7753913f032f49eb89e83b5 F src/treeview.c 4e44ade3bfe59d82005039f72e09333ce2b4162c F src/trigger.c c9f0810043b265724fdb1bdd466894f984dfc182 -F src/update.c 117bb080654b8c382b590b369f174ec11cca5bb0 +F src/update.c 4ed0fcccccd6488ee8a3bc02df10979b503f25d7 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c a88b0466fddf445ce752226d4698ca3faada620a F src/vacuum.c 33c174b28886b2faf26e503b5a49a1c01a9b1c16 @@ -1351,7 +1351,7 @@ F test/unique2.test 3674e9f2a3f1fbbfd4772ac74b7a97090d0f77d2 F test/unixexcl.test d936ba2b06794018e136418addd59a2354eeae97 F test/unordered.test ca7adce0419e4ca0c50f039885e76ed2c531eda8 F test/update.test 6c68446b8a0a33d522a7c72b320934596a2d7d32 -F test/update2.test 2b678973f882d11496f998c01b310be4c4a65a70 +F test/update2.test 7f72ef307d58be09a8ef61db23a7ef60e5af019d F test/uri.test 3481026f00ade6dfe8adb7acb6e1e47b04369568 F test/uri2.test 9d3ba7a53ee167572d53a298ee4a5d38ec4a8fb7 F test/userauth01.test e740a2697a7b40d7c5003a7d7edaee16acd349a9 @@ -1544,7 +1544,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 46db23ccd116ce5b9d949f9293be8a2818411b46 -R a3998d49adecb7e21ad8d0444ff44124 +P cab86c90945126c24c40cf2dedd053a8c46d00d6 +R 91b60fc45aced248f038aee86694df0e U dan -Z c5a6bc3f18beb290c2a3c904ee96a0c7 +Z f69bdc261645bb06f02a001c239441ef diff --git a/manifest.uuid b/manifest.uuid index 294d40d293..c670eb3052 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cab86c90945126c24c40cf2dedd053a8c46d00d6 \ No newline at end of file +0a2b8e1b9dc600b5a93622e8eea6218649df5e0f \ No newline at end of file diff --git a/src/update.c b/src/update.c index acf43034ff..242d36b739 100644 --- a/src/update.c +++ b/src/update.c @@ -135,6 +135,7 @@ void sqlite3Update( int addrOpen; /* Address of OP_OpenEphemeral */ int iPk; /* First of nPk cells holding PRIMARY KEY value */ i16 nPk; /* Number of components of the PRIMARY KEY */ + int bReplace = 0; /* True if REPLACE conflict resolution might happen */ /* Register Allocations */ int regRowCount = 0; /* A count of rows changed */ @@ -294,6 +295,11 @@ void sqlite3Update( if( iIdxCol<0 || aXRef[iIdxCol]>=0 ){ reg = ++pParse->nMem; pParse->nMem += pIdx->nColumn; + if( (onError==OE_Replace) + || (onError==OE_Default && pIdx->onError==OE_Replace) + ){ + bReplace = 1; + } break; } } @@ -301,6 +307,11 @@ void sqlite3Update( if( reg==0 ) aToOpen[j+1] = 0; aRegIdx[j] = reg; } + if( bReplace ){ + /* If REPLACE conflict resolution might be invoked, open cursors on all + ** indexes in case they are needed to delete records. */ + memset(aToOpen, 1, nIdx+1); + } /* Begin generating code. */ v = sqlite3GetVdbe(pParse); @@ -374,9 +385,15 @@ void sqlite3Update( sqlite3VdbeSetP4KeyInfo(pParse, pPk); } - /* Begin the database scan. */ + /* Begin the database scan. + ** + ** Do not consider a single-pass strategy for a multi-row update if + ** there are any triggers or foreign keys to process, or rows may + ** be deleted as a result of REPLACE conflict handling. Any of these + ** things might disturb a cursor being used to scan through the table + ** or index, causing a single-pass approach to malfunction. */ flags = WHERE_ONEPASS_DESIRED | WHERE_SEEK_TABLE; - if( pParse->nested==0 && pTrigger==0 && hasFK==0 && chngKey==0 ){ + if( !pParse->nested && !pTrigger && !hasFK && !chngKey && !bReplace ){ flags |= WHERE_ONEPASS_MULTIROW; } pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0, flags, iIdxCur); @@ -436,34 +453,20 @@ void sqlite3Update( labelBreak = sqlite3VdbeMakeLabel(v); if( !isView ){ - int iAddrOnce = 0; - /* - ** Open every index that needs updating. Note that if any - ** index could potentially invoke a REPLACE conflict resolution - ** action, then we need to open all indices because we might need - ** to be deleting some records. - */ - if( onError==OE_Replace ){ - memset(aToOpen, 1, nIdx+1); - }else{ - for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ - if( pIdx->onError==OE_Replace ){ - memset(aToOpen, 1, nIdx+1); - break; - } - } - } + int addrOnce = 0; + + /* Open every index that needs updating. */ if( eOnePass!=ONEPASS_OFF ){ if( aiCurOnePass[0]>=0 ) aToOpen[aiCurOnePass[0]-iBaseCur] = 0; if( aiCurOnePass[1]>=0 ) aToOpen[aiCurOnePass[1]-iBaseCur] = 0; } if( eOnePass==ONEPASS_MULTI && (nIdx-(aiCurOnePass[1]>=0))>0 ){ - iAddrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); + addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); } sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, 0, iBaseCur, aToOpen, 0, 0); - if( iAddrOnce ) sqlite3VdbeJumpHere(v, iAddrOnce); + if( addrOnce ) sqlite3VdbeJumpHere(v, addrOnce); } /* Top of the update loop */ @@ -602,7 +605,6 @@ void sqlite3Update( if( !isView ){ int addr1 = 0; /* Address of jump instruction */ - int bReplace = 0; /* True if REPLACE conflict resolution might happen */ /* Do constraint checks. */ assert( regOldRowid>0 ); diff --git a/test/update2.test b/test/update2.test index 8aafb2438b..61ac9792da 100644 --- a/test/update2.test +++ b/test/update2.test @@ -84,14 +84,20 @@ do_execsql_test 3.1 { #------------------------------------------------------------------------- # foreach {tn sql} { - 1 { CREATE TABLE b1(a INTEGER PRIMARY KEY, b, c) } - 2 { CREATE TABLE b1(a INT PRIMARY KEY, b, c) WITHOUT ROWID } + 1 { + CREATE TABLE b1(a INTEGER PRIMARY KEY, b, c); + CREATE TABLE c1(a INTEGER PRIMARY KEY, b, c, d) + } + 2 { + CREATE TABLE b1(a INT PRIMARY KEY, b, c) WITHOUT ROWID; + CREATE TABLE c1(a INT PRIMARY KEY, b, c, d) WITHOUT ROWID; + } } { - execsql { DROP TABLE IF EXISTS b1 } + execsql { DROP TABLE IF EXISTS b1; DROP TABLE IF EXISTS c1; } execsql $sql + do_execsql_test 4.$tn.0 { CREATE UNIQUE INDEX b1c ON b1(c); - INSERT INTO b1 VALUES(1, 'a', 1); INSERT INTO b1 VALUES(2, 'b', 15); INSERT INTO b1 VALUES(3, 'c', 3); @@ -112,7 +118,63 @@ foreach {tn sql} { 6 f 16 7 g 17 } + + do_execsql_test 4.$tn.2 { + CREATE INDEX c1d ON c1(d, b); + CREATE UNIQUE INDEX c1c ON c1(c, b); + + INSERT INTO c1 VALUES(1, 'a', 1, 1); + INSERT INTO c1 VALUES(2, 'a', 15, 2); + INSERT INTO c1 VALUES(3, 'a', 3, 3); + INSERT INTO c1 VALUES(4, 'a', 4, 4); + INSERT INTO c1 VALUES(5, 'a', 5, 5); + INSERT INTO c1 VALUES(6, 'a', 6, 6); + INSERT INTO c1 VALUES(7, 'a', 7, 7); + } + + do_execsql_test 4.$tn.3 { + UPDATE OR REPLACE c1 SET c=c+10 WHERE d BETWEEN 4 AND 7; + SELECT * FROM c1 ORDER BY a; + } { + 1 a 1 1 + 3 a 3 3 + 4 a 14 4 + 5 a 15 5 + 6 a 16 6 + 7 a 17 7 + } + + do_execsql_test 4.$tn.4 { PRAGMA integrity_check } ok + + do_execsql_test 4.$tn.5 { + DROP INDEX c1d; + DROP INDEX c1c; + DELETE FROM c1; + + INSERT INTO c1 VALUES(1, 'a', 1, 1); + INSERT INTO c1 VALUES(2, 'a', 15, 2); + INSERT INTO c1 VALUES(3, 'a', 3, 3); + INSERT INTO c1 VALUES(4, 'a', 4, 4); + INSERT INTO c1 VALUES(5, 'a', 5, 5); + INSERT INTO c1 VALUES(6, 'a', 6, 6); + INSERT INTO c1 VALUES(7, 'a', 7, 7); + + CREATE INDEX c1d ON c1(d); + CREATE UNIQUE INDEX c1c ON c1(c); + } + + do_execsql_test 4.$tn.6 { + UPDATE OR REPLACE c1 SET c=c+10 WHERE d BETWEEN 4 AND 7; + SELECT * FROM c1 ORDER BY a; + } { + 1 a 1 1 + 3 a 3 3 + 4 a 14 4 + 5 a 15 5 + 6 a 16 6 + 7 a 17 7 + } } - finish_test + From e206ea7f480e7d68db9aaa7e3415bef3f66d3be6 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 11 Jan 2017 20:10:30 +0000 Subject: [PATCH 1194/1484] Fix a problem causing the pre-update hook to be passed an incorrect rowid value in some single-pass multi-row updates. FossilOrigin-Name: 62257eb53c13d4c7ed128d5d89f6f10d4aff945c --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/update.c | 4 ++++ 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 95612d61fb..dc4ff7c1a4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\swith\ssingle-pass\smulti-row\sUPDATE\sstatements\sthat\sinvoke\sREPLACE\nconflict\shandling. -D 2017-01-11T19:03:08.308 +C Fix\sa\sproblem\scausing\sthe\spre-update\shook\sto\sbe\spassed\san\sincorrect\srowid\nvalue\sin\ssome\ssingle-pass\smulti-row\supdates. +D 2017-01-11T20:10:30.712 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -451,7 +451,7 @@ F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c 5c2f516876fc27fbd7753913f032f49eb89e83b5 F src/treeview.c 4e44ade3bfe59d82005039f72e09333ce2b4162c F src/trigger.c c9f0810043b265724fdb1bdd466894f984dfc182 -F src/update.c 4ed0fcccccd6488ee8a3bc02df10979b503f25d7 +F src/update.c 715bbfe276c9d008482cdb0ecd86ff996dba3b6c F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c a88b0466fddf445ce752226d4698ca3faada620a F src/vacuum.c 33c174b28886b2faf26e503b5a49a1c01a9b1c16 @@ -1544,7 +1544,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P cab86c90945126c24c40cf2dedd053a8c46d00d6 -R 91b60fc45aced248f038aee86694df0e +P 0a2b8e1b9dc600b5a93622e8eea6218649df5e0f +R d791ce37848d763756ad4c9c28aa682a U dan -Z f69bdc261645bb06f02a001c239441ef +Z 064d431f5a23ac6118a97592b16afa49 diff --git a/manifest.uuid b/manifest.uuid index c670eb3052..19077faa6c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0a2b8e1b9dc600b5a93622e8eea6218649df5e0f \ No newline at end of file +62257eb53c13d4c7ed128d5d89f6f10d4aff945c \ No newline at end of file diff --git a/src/update.c b/src/update.c index 242d36b739..e1cbc21da2 100644 --- a/src/update.c +++ b/src/update.c @@ -643,6 +643,10 @@ void sqlite3Update( OPFLAG_ISUPDATE | ((hasFK || chngKey) ? 0 : OPFLAG_ISNOOP), regNewRowid ); + if( eOnePass==ONEPASS_MULTI ){ + assert( hasFK==0 && chngKey==0 ); + sqlite3VdbeChangeP5(v, OPFLAG_SAVEPOSITION); + } if( !pParse->nested ){ sqlite3VdbeAppendP4(v, pTab, P4_TABLE); } From ea8f0a155e64ec6ea300ed5c77a96397e77b0edb Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 12 Jan 2017 11:50:08 +0000 Subject: [PATCH 1195/1484] Make sure Tcl_AppendResult() always has a NULL-pointer argument at the end. FossilOrigin-Name: c07aef6f909fe35de110f0b180dbf5aa4c226af3 --- manifest | 15 +++++++-------- manifest.uuid | 2 +- src/tclsqlite.c | 8 ++++---- 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 62ade5afe1..7f69b73c9c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Changes\sto\sallow\ssome\smulti-row\sUPDATE\sstatements\sto\savoid\sthe\stwo-pass\napproach. -D 2017-01-11T21:03:53.460 +C Make\ssure\sTcl_AppendResult()\salways\shas\sa\sNULL-pointer\sargument\sat\sthe\send. +D 2017-01-12T11:50:08.746 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -397,7 +397,7 @@ F src/sqliteInt.h bec6274d8991528bc12d9a34d01fe84bdf6d00d9 F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 -F src/tclsqlite.c 205c66b9b81d97978a155caa3ef5be9c4de2b174 +F src/tclsqlite.c 418f5e5e0840425a7e5b33f3600dccd378a57549 F src/test1.c 8a98191a1da8e100f77cdb5cc716df67d405028d F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5 F src/test3.c d03f5b5da9a2410b7a91c64b0d3306ed28ab6fee @@ -1544,8 +1544,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P f58f75b5a06f88ba97bd1a02bee621c64691c6f8 62257eb53c13d4c7ed128d5d89f6f10d4aff945c -R a5d3781c66cde36056f7269332c03001 -T +closed 62257eb53c13d4c7ed128d5d89f6f10d4aff945c -U dan -Z 8a4ce767e7a0e27eb39847a70d667c24 +P 7ae6104a3e0d1d2cacfe2be732f0220a53908132 +R c90de156797531d5a59462fa9fb70f0d +U drh +Z 140d8d1b5e4e9e613293d0d1ce895be9 diff --git a/manifest.uuid b/manifest.uuid index 5a73a263e8..061e989144 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7ae6104a3e0d1d2cacfe2be732f0220a53908132 \ No newline at end of file +c07aef6f909fe35de110f0b180dbf5aa4c226af3 \ No newline at end of file diff --git a/src/tclsqlite.c b/src/tclsqlite.c index 1d87c9b331..5b52bf0c91 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -2307,7 +2307,7 @@ static int SQLITE_TCLAPI DbObjCmd( } in = fopen(zFile, "rb"); if( in==0 ){ - Tcl_AppendResult(interp, "Error: cannot open file: ", zFile, NULL); + Tcl_AppendResult(interp, "Error: cannot open file: ", zFile, (char*)0); sqlite3_finalize(pStmt); return TCL_ERROR; } @@ -2536,7 +2536,7 @@ static int SQLITE_TCLAPI DbObjCmd( int n = strlen30(z); if( n>2 && strncmp(z, "-argcount",n)==0 ){ if( i==(objc-2) ){ - Tcl_AppendResult(interp, "option requires an argument: ", z, 0); + Tcl_AppendResult(interp, "option requires an argument: ", z,(char*)0); return TCL_ERROR; } if( Tcl_GetIntFromObj(interp, objv[i+1], &nArg) ) return TCL_ERROR; @@ -2551,7 +2551,7 @@ static int SQLITE_TCLAPI DbObjCmd( flags |= SQLITE_DETERMINISTIC; }else{ Tcl_AppendResult(interp, "bad option \"", z, - "\": must be -argcount or -deterministic", 0 + "\": must be -argcount or -deterministic", (char*)0 ); return TCL_ERROR; } @@ -3208,7 +3208,7 @@ static int SQLITE_TCLAPI DbObjCmd( pObj = Tcl_NewStringObj((char*)sqlite3_value_text(pValue), -1); Tcl_SetObjResult(interp, pObj); }else{ - Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), 0); + Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), (char*)0); return TCL_ERROR; } } From 24be549329cda7f0628fc119742b649f303027c2 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 12 Jan 2017 11:52:47 +0000 Subject: [PATCH 1196/1484] Remove invalid test case from cursorhints2.test FossilOrigin-Name: 163cc1b2f7100827d5803b81dcd97a1417744f66 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/cursorhint2.test | 10 ++++++---- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 7f69b73c9c..ecc1cabab4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\ssure\sTcl_AppendResult()\salways\shas\sa\sNULL-pointer\sargument\sat\sthe\send. -D 2017-01-12T11:50:08.746 +C Remove\sinvalid\stest\scase\sfrom\scursorhints2.test +D 2017-01-12T11:52:47.951 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -626,7 +626,7 @@ F test/cse.test 277350a26264495e86b1785f34d2d0c8600e021c F test/csv01.test e0ba3caaa57e4c667a0b45977689fb8082f14348 F test/ctime.test ff6c38e822459d6ca743c34901caf57740b08b54 F test/cursorhint.test 7bc346788390475e77a345da2b92270d04d35856 -F test/cursorhint2.test fa41f0d997e67db921d08c31e73111b32811201a +F test/cursorhint2.test 8457e93d97f665f23f97cdbc8477d16e3480331b F test/date.test a6a5a48b90907bca9fbcc79a30be5a715c1ab2fc F test/dbfuzz.c 8cc2bdb818b4483a052f9f80f96be74cbd9a6e1d F test/dbstatus.test 73149851b3aff14fc6db478e58f9083a66422cf5 @@ -1544,7 +1544,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 7ae6104a3e0d1d2cacfe2be732f0220a53908132 -R c90de156797531d5a59462fa9fb70f0d +P c07aef6f909fe35de110f0b180dbf5aa4c226af3 +R c1c1751767bcc81e2bffd9195a0f35dd U drh -Z 140d8d1b5e4e9e613293d0d1ce895be9 +Z 744c5ff27f4cf888c7a2ae696c740d23 diff --git a/manifest.uuid b/manifest.uuid index 061e989144..daa470f6ca 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c07aef6f909fe35de110f0b180dbf5aa4c226af3 \ No newline at end of file +163cc1b2f7100827d5803b81dcd97a1417744f66 \ No newline at end of file diff --git a/test/cursorhint2.test b/test/cursorhint2.test index bc447d0f22..616235b376 100644 --- a/test/cursorhint2.test +++ b/test/cursorhint2.test @@ -91,10 +91,12 @@ do_extract_hints_test 1.6 { t2 {EQ(r[2],c0)} t3 {EQ(r[6],c1)} } -do_extract_hints_test 1.7 { - SELECT * FROM t1 LEFT JOIN t2 ON (a=c AND d=e) LEFT JOIN t3 ON (d=f); -} { - t2 {EQ(r[2],c0)} t3 {AND(EQ(r[6],c0),EQ(r[7],c1))} +if 0 { + do_extract_hints_test 1.7 { + SELECT * FROM t1 LEFT JOIN t2 ON (a=c AND d=e) LEFT JOIN t3 ON (d=f); + } { + t2 {EQ(r[2],c0)} t3 {AND(EQ(r[6],c0),EQ(r[7],c1))} + } } #------------------------------------------------------------------------- From b701c9a6c3bf9efef49e0a4dfa9905de9a25a06e Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 12 Jan 2017 15:11:03 +0000 Subject: [PATCH 1197/1484] Improved detection of cells that extend into the reserved space at the end of the page while adjusting overflow page pointers during autovacuum. FossilOrigin-Name: 8097712c9c1f4ea16bc5dd462da248ef98896061 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btree.c | 14 ++++++++------ 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index ecc1cabab4..64318a45bb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sinvalid\stest\scase\sfrom\scursorhints2.test -D 2017-01-12T11:52:47.951 +C Improved\sdetection\sof\scells\sthat\sextend\sinto\sthe\sreserved\sspace\sat\sthe\send\nof\sthe\spage\swhile\sadjusting\soverflow\spage\spointers\sduring\sautovacuum. +D 2017-01-12T15:11:03.724 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -331,7 +331,7 @@ F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792 F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca -F src/btree.c 44e9612965f63bef288673b81faa43e765bcac5f +F src/btree.c 90f8b15ec9baf65d5bfff65bdaee773b928836c1 F src/btree.h e6d352808956ec163a17f832193a3e198b3fb0ac F src/btreeInt.h 10c4b77c2fb399580babbcc7cf652ac10dba796e F src/build.c 9e799f1edd910dfa8a0bc29bd390d35d310596af @@ -1544,7 +1544,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P c07aef6f909fe35de110f0b180dbf5aa4c226af3 -R c1c1751767bcc81e2bffd9195a0f35dd +P 163cc1b2f7100827d5803b81dcd97a1417744f66 +R d095162836679cc779e9b3972f22e3ea U drh -Z 744c5ff27f4cf888c7a2ae696c740d23 +Z e05f25d6fff0c473a188620363f2fa54 diff --git a/manifest.uuid b/manifest.uuid index daa470f6ca..ae5d12009d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -163cc1b2f7100827d5803b81dcd97a1417744f66 \ No newline at end of file +8097712c9c1f4ea16bc5dd462da248ef98896061 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 60f886bf5a..99e9741b6f 100644 --- a/src/btree.c +++ b/src/btree.c @@ -3356,12 +3356,14 @@ static int modifyPagePointer(MemPage *pPage, Pgno iFrom, Pgno iTo, u8 eType){ if( eType==PTRMAP_OVERFLOW1 ){ CellInfo info; pPage->xParseCell(pPage, pCell, &info); - if( info.nLocalaData+pPage->maskPage - && iFrom==get4byte(pCell+info.nSize-4) - ){ - put4byte(pCell+info.nSize-4, iTo); - break; + if( info.nLocal pPage->aData+pPage->pBt->usableSize ){ + return SQLITE_CORRUPT_BKPT; + } + if( iFrom==get4byte(pCell+info.nSize-4) ){ + put4byte(pCell+info.nSize-4, iTo); + break; + } } }else{ if( get4byte(pCell)==iFrom ){ From 70d90a2c37482a9b8a5566ef47bc4101f5073184 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 12 Jan 2017 16:14:33 +0000 Subject: [PATCH 1198/1484] Remove an unnecessary corruption test from the btree balancer. If corruption is present, it will be found harmlessly by later tests. FossilOrigin-Name: bddf39562d08e259c43dd59b82afb62fe0eb2eef --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btree.c | 1 - 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 64318a45bb..338a7ee537 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improved\sdetection\sof\scells\sthat\sextend\sinto\sthe\sreserved\sspace\sat\sthe\send\nof\sthe\spage\swhile\sadjusting\soverflow\spage\spointers\sduring\sautovacuum. -D 2017-01-12T15:11:03.724 +C Remove\san\sunnecessary\scorruption\stest\sfrom\sthe\sbtree\sbalancer.\s\sIf\scorruption\nis\spresent,\sit\swill\sbe\sfound\sharmlessly\sby\slater\stests. +D 2017-01-12T16:14:33.708 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -331,7 +331,7 @@ F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792 F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca -F src/btree.c 90f8b15ec9baf65d5bfff65bdaee773b928836c1 +F src/btree.c 5f8642134a2b56d0909f6196d7a1b0731cf4188a F src/btree.h e6d352808956ec163a17f832193a3e198b3fb0ac F src/btreeInt.h 10c4b77c2fb399580babbcc7cf652ac10dba796e F src/build.c 9e799f1edd910dfa8a0bc29bd390d35d310596af @@ -1544,7 +1544,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 163cc1b2f7100827d5803b81dcd97a1417744f66 -R d095162836679cc779e9b3972f22e3ea +P 8097712c9c1f4ea16bc5dd462da248ef98896061 +R c3fb4d0a8856fd8a9a7ac25a5dcf6c2d U drh -Z e05f25d6fff0c473a188620363f2fa54 +Z 126b06a4044b551a39fa62a47a4fd8cf diff --git a/manifest.uuid b/manifest.uuid index ae5d12009d..0dbbd81794 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8097712c9c1f4ea16bc5dd462da248ef98896061 \ No newline at end of file +bddf39562d08e259c43dd59b82afb62fe0eb2eef \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 99e9741b6f..c635e15718 100644 --- a/src/btree.c +++ b/src/btree.c @@ -7271,7 +7271,6 @@ static int balance_nonroot( for(i=0; inFree; - if( szNew[i]<0 ){ rc = SQLITE_CORRUPT_BKPT; goto balance_cleanup; } for(j=0; jnOverflow; j++){ szNew[i] += 2 + p->xCellSize(p, p->apOvfl[j]); } From ae051a8970d0f50869fb8a36a5d51a13a8c929c0 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 12 Jan 2017 16:21:54 +0000 Subject: [PATCH 1199/1484] Fix harmless compiler warnings in the UPDATE code generator. FossilOrigin-Name: 385db266673abaf7013ffad09b28014c246547ef --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/update.c | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 338a7ee537..1e60a98460 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\san\sunnecessary\scorruption\stest\sfrom\sthe\sbtree\sbalancer.\s\sIf\scorruption\nis\spresent,\sit\swill\sbe\sfound\sharmlessly\sby\slater\stests. -D 2017-01-12T16:14:33.708 +C Fix\sharmless\scompiler\swarnings\sin\sthe\sUPDATE\scode\sgenerator. +D 2017-01-12T16:21:54.480 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -451,7 +451,7 @@ F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c 5c2f516876fc27fbd7753913f032f49eb89e83b5 F src/treeview.c 4e44ade3bfe59d82005039f72e09333ce2b4162c F src/trigger.c c9f0810043b265724fdb1bdd466894f984dfc182 -F src/update.c 715bbfe276c9d008482cdb0ecd86ff996dba3b6c +F src/update.c 4e21634dde80a59b85f4d59eca75e3b5a5001fd4 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c a88b0466fddf445ce752226d4698ca3faada620a F src/vacuum.c 33c174b28886b2faf26e503b5a49a1c01a9b1c16 @@ -1544,7 +1544,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 8097712c9c1f4ea16bc5dd462da248ef98896061 -R c3fb4d0a8856fd8a9a7ac25a5dcf6c2d +P bddf39562d08e259c43dd59b82afb62fe0eb2eef +R c1f97b0b1d9fb4e22bf29bd06fe30297 U drh -Z 126b06a4044b551a39fa62a47a4fd8cf +Z a2b5fe338be7534e4379cc3897438f5d diff --git a/manifest.uuid b/manifest.uuid index 0dbbd81794..da8dc7b7b9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bddf39562d08e259c43dd59b82afb62fe0eb2eef \ No newline at end of file +385db266673abaf7013ffad09b28014c246547ef \ No newline at end of file diff --git a/src/update.c b/src/update.c index e1cbc21da2..8bdb740c16 100644 --- a/src/update.c +++ b/src/update.c @@ -132,9 +132,9 @@ void sqlite3Update( int iEph = 0; /* Ephemeral table holding all primary key values */ int nKey = 0; /* Number of elements in regKey for WITHOUT ROWID */ int aiCurOnePass[2]; /* The write cursors opened by WHERE_ONEPASS */ - int addrOpen; /* Address of OP_OpenEphemeral */ - int iPk; /* First of nPk cells holding PRIMARY KEY value */ - i16 nPk; /* Number of components of the PRIMARY KEY */ + int addrOpen = 0; /* Address of OP_OpenEphemeral */ + int iPk = 0; /* First of nPk cells holding PRIMARY KEY value */ + i16 nPk = 0; /* Number of components of the PRIMARY KEY */ int bReplace = 0; /* True if REPLACE conflict resolution might happen */ /* Register Allocations */ From 7b20a15d1380ed7b2415e3b489695dbcd016c039 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 12 Jan 2017 19:10:55 +0000 Subject: [PATCH 1200/1484] Remove a branch that is probably unreachable, and which adds no value. FossilOrigin-Name: 9acc72381ccd5e36f3ffdf7e7fbefc5a15701eb4 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btree.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 1e60a98460..000de47de4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\scompiler\swarnings\sin\sthe\sUPDATE\scode\sgenerator. -D 2017-01-12T16:21:54.480 +C Remove\sa\sbranch\sthat\sis\sprobably\sunreachable,\sand\swhich\sadds\sno\svalue. +D 2017-01-12T19:10:55.750 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -331,7 +331,7 @@ F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792 F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca -F src/btree.c 5f8642134a2b56d0909f6196d7a1b0731cf4188a +F src/btree.c 69966fb2c574954cd3216f09407c9a02c52d3bd7 F src/btree.h e6d352808956ec163a17f832193a3e198b3fb0ac F src/btreeInt.h 10c4b77c2fb399580babbcc7cf652ac10dba796e F src/build.c 9e799f1edd910dfa8a0bc29bd390d35d310596af @@ -1544,7 +1544,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P bddf39562d08e259c43dd59b82afb62fe0eb2eef -R c1f97b0b1d9fb4e22bf29bd06fe30297 +P 385db266673abaf7013ffad09b28014c246547ef +R fc07cbd5c2e564fa0b0693e0166fd1a4 U drh -Z a2b5fe338be7534e4379cc3897438f5d +Z 1662f62ac3b6c5068ca23b30e30b82dc diff --git a/manifest.uuid b/manifest.uuid index da8dc7b7b9..644e2b84c1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -385db266673abaf7013ffad09b28014c246547ef \ No newline at end of file +9acc72381ccd5e36f3ffdf7e7fbefc5a15701eb4 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index c635e15718..7b56867646 100644 --- a/src/btree.c +++ b/src/btree.c @@ -8124,7 +8124,7 @@ int sqlite3BtreeInsert( pCur->eState = CURSOR_INVALID; if( (flags & BTREE_SAVEPOSITION) && rc==SQLITE_OK ){ rc = moveToRoot(pCur); - if( pCur->pKeyInfo && rc==SQLITE_OK ){ + if( pCur->pKeyInfo ){ assert( pCur->pKey==0 ); pCur->pKey = sqlite3Malloc( pX->nKey ); if( pCur->pKey==0 ){ From be7a0cee4eb3be876182a23f004b4de2d8f2103f Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 13 Jan 2017 12:53:35 +0000 Subject: [PATCH 1201/1484] Fix the build for SQLITE_ENABLE_MEMORY_MANAGEMENT. FossilOrigin-Name: 8c85b8fdd7f0ba65fba83361d361a567b797a184 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/malloc.c | 5 +++-- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 000de47de4..21c132777c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sa\sbranch\sthat\sis\sprobably\sunreachable,\sand\swhich\sadds\sno\svalue. -D 2017-01-12T19:10:55.750 +C Fix\sthe\sbuild\sfor\sSQLITE_ENABLE_MEMORY_MANAGEMENT. +D 2017-01-13T12:53:35.623 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -354,7 +354,7 @@ F src/insert.c 05e47e2de7b712a3a4148cd469e5f60873f5ef13 F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e F src/loadext.c 5d6642d141c07d366e43d359e94ec9de47add41d F src/main.c e207b81542d13b9f13d61e78ca441f9781f055b0 -F src/malloc.c c36ef8fa6e4cc53ec258c5aa3ad86eb47350cc3d +F src/malloc.c fc1b9f445290f2145da48fc08730c26e6082b640 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3 @@ -1544,7 +1544,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 385db266673abaf7013ffad09b28014c246547ef -R fc07cbd5c2e564fa0b0693e0166fd1a4 +P 9acc72381ccd5e36f3ffdf7e7fbefc5a15701eb4 +R 538795cf3f379197890291f480545c18 U drh -Z 1662f62ac3b6c5068ca23b30e30b82dc +Z 8d3190b0c41cbb057e375dc759a5947e diff --git a/manifest.uuid b/manifest.uuid index 644e2b84c1..a786fc5f1c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9acc72381ccd5e36f3ffdf7e7fbefc5a15701eb4 \ No newline at end of file +8c85b8fdd7f0ba65fba83361d361a567b797a184 \ No newline at end of file diff --git a/src/malloc.c b/src/malloc.c index 053b57b47f..0a3d891e9b 100644 --- a/src/malloc.c +++ b/src/malloc.c @@ -219,11 +219,12 @@ static void sqlite3MallocAlarm(int nByte){ */ static void mallocWithAlarm(int n, void **pp){ void *p; + int nFull = 0; assert( sqlite3_mutex_held(mem0.mutex) ); sqlite3StatusHighwater(SQLITE_STATUS_MALLOC_SIZE, n); if( mem0.alarmThreshold>0 ){ sqlite3_int64 nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED); - int nFull = sqlite3GlobalConfig.m.xRoundup(n); + nFull = sqlite3GlobalConfig.m.xRoundup(n); if( nUsed >= mem0.alarmThreshold - nFull ){ mem0.nearlyFull = 1; sqlite3MallocAlarm(nFull); @@ -239,7 +240,7 @@ static void mallocWithAlarm(int n, void **pp){ } #endif if( p ){ - int nFull = sqlite3MallocSize(p); + nFull = sqlite3MallocSize(p); sqlite3StatusUp(SQLITE_STATUS_MEMORY_USED, nFull); sqlite3StatusUp(SQLITE_STATUS_MALLOC_COUNT, 1); } From ef2f5925d8b4f9862110c5bea0c18fe131608974 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 13 Jan 2017 18:24:37 +0000 Subject: [PATCH 1202/1484] Fix a problem preventing resumption of RBU operations after recovering from a process or system failure that occurs during the incremental-checkpoint phase. FossilOrigin-Name: 97914266cb4ec63b0c9185ab139673139bd2f0ed --- ext/rbu/rburesume.test | 254 +++++++++++++++++++++++++++++++++++++++++ ext/rbu/sqlite3rbu.c | 2 +- manifest | 15 +-- manifest.uuid | 2 +- 4 files changed, 264 insertions(+), 9 deletions(-) create mode 100644 ext/rbu/rburesume.test diff --git a/ext/rbu/rburesume.test b/ext/rbu/rburesume.test new file mode 100644 index 0000000000..d03894e135 --- /dev/null +++ b/ext/rbu/rburesume.test @@ -0,0 +1,254 @@ +# 2017 January 13 +# +# 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 contains tests for resumption of RBU operations in the +# case where the previous RBU process crashed. +# + +source [file join [file dirname [info script]] rbu_common.tcl] +set ::testprefix rburesume + +forcedelete test.db-shm test.db-oal +do_execsql_test 1.0 { + CREATE TABLE t1(a PRIMARY KEY, b, c); + CREATE INDEX t1a ON t1(a); + CREATE INDEX t1b ON t1(b); + CREATE INDEX t1c ON t1(c); + WITH s(i) AS ( + VALUES(1) UNION ALL SELECT i+1 FROM s WHERE i<50 + ) + INSERT INTO t1 SELECT randomblob(50), randomblob(75), randomblob(100) FROM s; +} +db_save_and_close + +do_test 1.1 { + list [file exists test.db] \ + [file exists test.db-wal] \ + [file exists test.db-shm] \ + [file exists test.db-oal] +} {1 0 0 0} + +# Each iteration of the following loop: +# +# 1. Restores the db to the state it was in following test case 1.0 +# 2. Opens an RBU vacuum and steps it $n times. +# 3. Closes the RBU vacuum handled opened in (2). +# 4. Opens a second RBU vacuum handle, resumes and completes the vacuum op. +# +# The loop runs until $n is large enough that step (2) vacuums the entire +# database. +# +for {set n 1} {$n < 5000} {incr n} { + db_restore + forcedelete state.db + sqlite3rbu_vacuum rbu test.db state.db + for {set i 0} {$i<$n} {incr i} { + set rc [rbu step] + if {$rc == "SQLITE_DONE"} break + } + rbu close + if {$rc == "SQLITE_DONE"} break + + do_test 1.2.$n.1 { + sqlite3rbu_vacuum rbu test.db state.db + while {[rbu step]=="SQLITE_OK"} {} + rbu close + } {SQLITE_DONE} + + do_test 1.2.$n.2 { + sqlite3 db2 test.db + db2 eval { + SELECT count(*) FROM t1; + PRAGMA integrity_check; + } + } {50 ok} + db2 close +} + +# Each iteration of this loop: +# +# 1. Restores the db to the state it was in following test case 1.0 +# 2. Opens an RBU vacuum and steps it $n times. +# 3. Takes a copy of all database files and the state db. +# 4. Opens a second RBU vacuum handle on the copy, resumes and completes the +# vacuum op. +# +# The loop runs until $n is large enough that step (2) vacuums the entire +# database. +# +for {set n 1} {$n < 5000} {incr n} { + db_restore + forcedelete state.db state.db-shm state.db-oal state.db-wal + sqlite3rbu_vacuum rbu test.db state.db + for {set i 0} {$i<$n} {incr i} { + set rc [rbu step] + if {$rc == "SQLITE_DONE"} break + } + if {$rc == "SQLITE_DONE"} { + rbu close + break + } + + foreach f {test.db test.db-oal test.db-wal test.db-shm test.db-vacuum} { + set f2 [string map [list test.db test.db2] $f] + if {[file exists $f]} { + forcecopy $f $f2 + } else { + forcedelete $f2 + } + } + forcecopy state.db state.db2 + rbu close + + do_test 1.3.$n.1 { + sqlite3rbu_vacuum rbu test.db2 state.db2 + while {[rbu step]=="SQLITE_OK"} {} + rbu close + } {SQLITE_DONE} + + do_test 1.3.$n.2 { + sqlite3 db2 test.db2 + db2 eval { + SELECT count(*) FROM t1; + PRAGMA integrity_check; + } + } {50 ok} + db2 close +} + +# Each iteration of this loop: +# +# 1. Restores the db to the state it was in following test case 1.0 +# 2. Opens an RBU vacuum and steps it 10 times. Then closes it. +# 2. Opens an RBU vacuum and steps it $n times. +# 3. Takes a copy of all database files and the state db. +# 4. Opens a second RBU vacuum handle on the copy, resumes and completes the +# vacuum op. +# +# The loop runs until $n is large enough that step (3) vacuums the entire +# database. +# +for {set n 1} {$n < 5000} {incr n} { + db_restore + forcedelete state.db state.db-shm state.db-oal state.db-wal + + sqlite3rbu_vacuum rbu test.db state.db + for {set i 0} {$i<10} {incr i} { + rbu step + } + rbu close + + sqlite3rbu_vacuum rbu test.db state.db + for {set i 0} {$i<$n} {incr i} { + set rc [rbu step] + if {$rc == "SQLITE_DONE"} break + } + if {$rc == "SQLITE_DONE"} { + rbu close + break + } + + foreach f {test.db test.db-oal test.db-wal test.db-shm test.db-vacuum} { + set f2 [string map [list test.db test.db2] $f] + if {[file exists $f]} { + forcecopy $f $f2 + } else { + forcedelete $f2 + } + } + forcecopy state.db state.db2 + rbu close + + do_test 1.4.$n.1 { + sqlite3rbu_vacuum rbu test.db2 state.db2 + while {[rbu step]=="SQLITE_OK"} {} + rbu close + } {SQLITE_DONE} + + do_test 1.4.$n.2 { + sqlite3 db2 test.db2 + db2 eval { + SELECT count(*) FROM t1; + PRAGMA integrity_check; + } + } {50 ok} + db2 close +} + +forcedelete rbu.db +do_test 2.0 { + sqlite3 db2 rbu.db + db2 eval { + CREATE TABLE data_t1(a, b, c, rbu_control); + WITH s(i) AS ( + VALUES(1) UNION ALL SELECT i+1 FROM s WHERE i<10 + ) + INSERT INTO data_t1 + SELECT randomblob(50), randomblob(75), randomblob(100), 0 FROM s; + } + db2 close +} {} + +# Each iteration of this loop: +# +# 1. Restores the db to the state it was in following test case 1.0 +# 2. Opens an RBU handle to apply the RBU update created in test case 2.0. +# 3. Steps the RBU handle $n times. +# 4. Takes a copy of all database files and the state db. +# 5. Opens a second RBU handle on the copy, resumes and completes the +# RBU op. Checks it worked as expected. +# +# The loop runs until $n is large enough that step (3) applies the entire +# update. +# +for {set n 1} {$n < 5000} {incr n} { + db_restore + forcedelete state.db state.db-shm state.db-oal state.db-wal + sqlite3rbu rbu test.db rbu.db state.db + + for {set i 0} {$i<$n} {incr i} { + set rc [rbu step] + if {$rc == "SQLITE_DONE"} break + } + if {$rc == "SQLITE_DONE"} { + rbu close + break + } + + foreach f {test.db test.db-oal test.db-wal test.db-shm test.db-vacuum} { + set f2 [string map [list test.db test.db2] $f] + if {[file exists $f]} { + forcecopy $f $f2 + } else { + forcedelete $f2 + } + } + forcecopy state.db state.db2 + rbu close + + do_test 2.$n.1 { + sqlite3rbu rbu test.db2 rbu.db state.db2 + while {[rbu step]=="SQLITE_OK"} {} + rbu close + } {SQLITE_DONE} + + do_test 2.$n.2 { + sqlite3 db2 test.db2 + db2 eval { + SELECT count(*) FROM t1; + PRAGMA integrity_check; + } + } {60 ok} + db2 close +} + +finish_test + diff --git a/ext/rbu/sqlite3rbu.c b/ext/rbu/sqlite3rbu.c index 746469a8af..235ba3fe2a 100644 --- a/ext/rbu/sqlite3rbu.c +++ b/ext/rbu/sqlite3rbu.c @@ -2408,7 +2408,7 @@ static void rbuOpenDatabase(sqlite3rbu *p){ }else{ RbuState *pState = rbuLoadState(p); if( pState ){ - bOpen = (pState->eStage>RBU_STAGE_MOVE); + bOpen = (pState->eStage>=RBU_STAGE_MOVE); rbuFreeState(pState); } } diff --git a/manifest b/manifest index 21c132777c..d943af7804 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\sbuild\sfor\sSQLITE_ENABLE_MEMORY_MANAGEMENT. -D 2017-01-13T12:53:35.623 +C Fix\sa\sproblem\spreventing\sresumption\sof\sRBU\soperations\safter\srecovering\sfrom\sa\nprocess\sor\ssystem\sfailure\sthat\soccurs\sduring\sthe\sincremental-checkpoint\sphase. +D 2017-01-13T18:24:37.297 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -254,10 +254,11 @@ F ext/rbu/rbufault2.test 9a7f19edd6ea35c4c9f807d8a3db0a03a5670c06 F ext/rbu/rbufault3.test 54a399888ac4af44c68f9f58afbed23149428bca F ext/rbu/rbufts.test 828cd689da825f0a7b7c53ffc1f6f7fdb6fa5bda F ext/rbu/rbuprogress.test e3e25fb7622641b8f2df7c6b7a7eb6fddfc46a4b +F ext/rbu/rburesume.test 8acb77f4a422ff55acfcfc9cc15a5cb210b1de83 F ext/rbu/rbusave.test 0f43b6686084f426ddd040b878426452fd2c2f48 F ext/rbu/rbuvacuum.test 4a977447c15c2581ab668781d9ef4294382530e0 F ext/rbu/rbuvacuum2.test 2569205b74ff40fbf3bda2fce33a58eb40eebdcc -F ext/rbu/sqlite3rbu.c e074c38798b90591f7f0cf0032d62f152ce5a95e +F ext/rbu/sqlite3rbu.c 4ca89fbe9ca501da17f338d580d3f19d59fc6053 F ext/rbu/sqlite3rbu.h 6fb6294c34a9ca93b5894a33bca530c6f08decba F ext/rbu/test_rbu.c 5aa22616afac6f71ebd3d9bc9bf1006cfabcca88 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 @@ -1544,7 +1545,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 9acc72381ccd5e36f3ffdf7e7fbefc5a15701eb4 -R 538795cf3f379197890291f480545c18 -U drh -Z 8d3190b0c41cbb057e375dc759a5947e +P 8c85b8fdd7f0ba65fba83361d361a567b797a184 +R dc62936e86267740ae9736f88160b05f +U dan +Z f2366ce5ecd39574b5b5eb81b3b99a63 diff --git a/manifest.uuid b/manifest.uuid index a786fc5f1c..e44a5e6607 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8c85b8fdd7f0ba65fba83361d361a567b797a184 \ No newline at end of file +97914266cb4ec63b0c9185ab139673139bd2f0ed \ No newline at end of file From ce31643fd9d7989a90a6cd73d8b5dd4896e323eb Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 16 Jan 2017 16:01:50 +0000 Subject: [PATCH 1203/1484] Add test cases for tickets [91e2e8ba6ff2e2] and [7ffd1ca1d2ad4ec]. FossilOrigin-Name: 9d0dfe0b088a5917afa06207ca3ac5618e3da82f --- manifest | 16 +++++--- manifest.uuid | 2 +- test/affinity3.test | 91 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 102 insertions(+), 7 deletions(-) create mode 100644 test/affinity3.test diff --git a/manifest b/manifest index d943af7804..9eb1084776 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\spreventing\sresumption\sof\sRBU\soperations\safter\srecovering\sfrom\sa\nprocess\sor\ssystem\sfailure\sthat\soccurs\sduring\sthe\sincremental-checkpoint\sphase. -D 2017-01-13T18:24:37.297 +C Add\stest\scases\sfor\stickets\s[91e2e8ba6ff2e2]\sand\s[7ffd1ca1d2ad4ec]. +D 2017-01-16T16:01:50.379 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -476,6 +476,7 @@ F src/wherecode.c e04ac8f24c3ac8621df6c3be3ac8c7d4fa893745 F src/whereexpr.c 35ad025389a632a3987a35617c878be3b3d70dc6 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd +F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/aggnested.test b35b4cd69fc913f90d39a575e171e1116c3a4bb7 F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87 @@ -1545,7 +1546,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 8c85b8fdd7f0ba65fba83361d361a567b797a184 -R dc62936e86267740ae9736f88160b05f -U dan -Z f2366ce5ecd39574b5b5eb81b3b99a63 +P 97914266cb4ec63b0c9185ab139673139bd2f0ed +R b7007367e54a15c0816f3ba9a91a394f +T *branch * automatic-index-affinity +T *sym-automatic-index-affinity * +T -sym-trunk * +U drh +Z 2b3d4a827097e1fdb9a913f5a46e57c3 diff --git a/manifest.uuid b/manifest.uuid index e44a5e6607..48c1698079 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -97914266cb4ec63b0c9185ab139673139bd2f0ed \ No newline at end of file +9d0dfe0b088a5917afa06207ca3ac5618e3da82f \ No newline at end of file diff --git a/test/affinity3.test b/test/affinity3.test new file mode 100644 index 0000000000..a335618a74 --- /dev/null +++ b/test/affinity3.test @@ -0,0 +1,91 @@ +# 2017-01-16 +# +# 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. +# +#*********************************************************************** +# +# Test cases for bugs: +# +# https://www.sqlite.org/src/info/91e2e8ba6ff2e2 +# https://www.sqlite.org/src/info/7ffd1ca1d2ad4ecf +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +# Ticket https://www.sqlite.org/src/info/91e2e8ba6ff2e2 (2011-09-19) +# Automatic index causes undesired type conversions +# +do_execsql_test affinity3-100 { + CREATE TABLE customer (id INT PRIMARY KEY); + CREATE TABLE apr (id INT PRIMARY KEY, apr REAL); + + CREATE VIEW v1 AS + SELECT c.id, i.apr + FROM customer c + LEFT JOIN apr i ON i.id=c.id; + + CREATE VIEW v2 AS + SELECT c.id, v1.apr + FROM customer c + LEFT JOIN v1 ON v1.id=c.id; + + INSERT INTO customer (id) VALUES (1); + INSERT INTO apr (id, apr) VALUES (1, 12); + INSERT INTO customer (id) VALUES (2); + INSERT INTO apr (id, apr) VALUES (2, 12.01); +} +do_execsql_test affinity3-110 { + PRAGMA automatic_index=ON; + SELECT id, (apr / 100), typeof(apr) apr_type FROM v1; +} {1 0.12 real 2 0.1201 real} +do_execsql_test affinity3-120 { + SELECT id, (apr / 100), typeof(apr) apr_type FROM v2; +} {1 0.12 real 2 0.1201 real} +do_execsql_test affinity3-130 { + PRAGMA automatic_index=OFF; + SELECT id, (apr / 100), typeof(apr) apr_type FROM v1; +} {1 0.12 real 2 0.1201 real} +do_execsql_test affinity3-140 { + SELECT id, (apr / 100), typeof(apr) apr_type FROM v2; +} {1 0.12 real 2 0.1201 real} + +# Ticket https://www.sqlite.org/src/info/7ffd1ca1d2ad4ecf (2017-01-16) +# Incorrect affinity when using automatic indexes +# +do_execsql_test affinity3-200 { + CREATE TABLE map_integer (id INT, name); + INSERT INTO map_integer VALUES(1,'a'); + CREATE TABLE map_text (id TEXT, name); + INSERT INTO map_text VALUES('4','e'); + CREATE TABLE data (id TEXT, name); + INSERT INTO data VALUES(1,'abc'); + INSERT INTO data VALUES('4','xyz'); + CREATE VIEW idmap as + SELECT * FROM map_integer + UNION SELECT * FROM map_text; + CREATE TABLE mzed AS SELECT * FROM idmap; +} + +do_execsql_test affinity3-210 { + PRAGMA automatic_index=ON; + SELECT * FROM data JOIN idmap USING(id); +} {1 abc a 4 xyz e} +do_execsql_test affinity3-220 { + SELECT * FROM data JOIN mzed USING(id); +} {1 abc a 4 xyz e} + +do_execsql_test affinity3-250 { + PRAGMA automatic_index=OFF; + SELECT * FROM data JOIN idmap USING(id); +} {1 abc a 4 xyz e} +do_execsql_test affinity3-260 { + SELECT * FROM data JOIN mzed USING(id); +} {1 abc a 4 xyz e} + +finish_test From da060052e3d6436e5998f94bb7c92ce1a70d5004 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 16 Jan 2017 16:43:02 +0000 Subject: [PATCH 1204/1484] Back out check-in [0b3174e0b1364c] and replace it with a better fix for ticket [91e2e8ba6ff2e2] - a fix that does not cause the problem identified by ticket [7ffd1ca1d2ad4ec]. FossilOrigin-Name: 0613665274346917f5482f9210bf0c60a0fed7d9 --- manifest | 17 +++++++---------- manifest.uuid | 2 +- src/delete.c | 4 ++++ src/update.c | 10 +++++----- 4 files changed, 17 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index 9eb1084776..c9e37e2c9e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\stest\scases\sfor\stickets\s[91e2e8ba6ff2e2]\sand\s[7ffd1ca1d2ad4ec]. -D 2017-01-16T16:01:50.379 +C Back\sout\scheck-in\s[0b3174e0b1364c]\sand\sreplace\sit\swith\sa\sbetter\sfix\nfor\sticket\s[91e2e8ba6ff2e2]\s-\sa\sfix\sthat\sdoes\snot\scause\sthe\sproblem\nidentified\sby\sticket\s[7ffd1ca1d2ad4ec]. +D 2017-01-16T16:43:02.076 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -341,7 +341,7 @@ F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 9f2296a4e5d26ebf0e0d95a0af4628f1ea694e7a F src/date.c dc3f1391d9297f8c748132813aaffcb117090d6e F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d -F src/delete.c a84f6229ccb9448460c287248024ceb70e10baab +F src/delete.c 8a444fea8340989d6b1be2e122c55bfc61ce69be F src/expr.c f06f41e5e5daca10fb090e70a2502dcc0dbc992b F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 2e9aabe1aee76273aff8a84ee92c464e095400ae @@ -452,7 +452,7 @@ F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c 5c2f516876fc27fbd7753913f032f49eb89e83b5 F src/treeview.c 4e44ade3bfe59d82005039f72e09333ce2b4162c F src/trigger.c c9f0810043b265724fdb1bdd466894f984dfc182 -F src/update.c 4e21634dde80a59b85f4d59eca75e3b5a5001fd4 +F src/update.c b356b29d04c71f33c779f2cb557cf953819bdd7a F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c a88b0466fddf445ce752226d4698ca3faada620a F src/vacuum.c 33c174b28886b2faf26e503b5a49a1c01a9b1c16 @@ -1546,10 +1546,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 97914266cb4ec63b0c9185ab139673139bd2f0ed -R b7007367e54a15c0816f3ba9a91a394f -T *branch * automatic-index-affinity -T *sym-automatic-index-affinity * -T -sym-trunk * +P 9d0dfe0b088a5917afa06207ca3ac5618e3da82f +R d9bec5fa752ad661e71dee0a4ee8e911 U drh -Z 2b3d4a827097e1fdb9a913f5a46e57c3 +Z 5e9d81347f66aedf2ffc7c8c671d9f61 diff --git a/manifest.uuid b/manifest.uuid index 48c1698079..d656223073 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9d0dfe0b088a5917afa06207ca3ac5618e3da82f \ No newline at end of file +0613665274346917f5482f9210bf0c60a0fed7d9 \ No newline at end of file diff --git a/src/delete.c b/src/delete.c index 1a5edb59d8..1d31622237 100644 --- a/src/delete.c +++ b/src/delete.c @@ -873,6 +873,10 @@ int sqlite3GenerateIndexKey( } if( regOut ){ sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol, regOut); + if( pIdx->pTable->pSelect ){ + const char *zAff = sqlite3IndexAffinityStr(pParse->db, pIdx); + sqlite3VdbeChangeP4(v, -1, zAff, P4_TRANSIENT); + } } sqlite3ReleaseTempRange(pParse, regBase, nCol); return regBase; diff --git a/src/update.c b/src/update.c index 8bdb740c16..45af001c3e 100644 --- a/src/update.c +++ b/src/update.c @@ -71,12 +71,12 @@ void sqlite3ColumnDefault(Vdbe *v, Table *pTab, int i, int iReg){ if( pValue ){ sqlite3VdbeAppendP4(v, pValue, P4_MEM); } -#ifndef SQLITE_OMIT_FLOATING_POINT - if( pTab->aCol[i].affinity==SQLITE_AFF_REAL ){ - sqlite3VdbeAddOp1(v, OP_RealAffinity, iReg); - } -#endif } +#ifndef SQLITE_OMIT_FLOATING_POINT + if( pTab->aCol[i].affinity==SQLITE_AFF_REAL ){ + sqlite3VdbeAddOp1(v, OP_RealAffinity, iReg); + } +#endif } /* From c711f53f30a5c1c7017deb2a77a18d806c936fba Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 17 Jan 2017 00:10:58 +0000 Subject: [PATCH 1205/1484] Disable intrinsic functions for Windows using Clang, due to reports of linkage errors. This causes a 0.6% performance reduction. We will want to revisit this change in the future. FossilOrigin-Name: 7fd560c6d2ff470b755ad118287a0a8825b3009e --- manifest | 13 ++++++------- manifest.uuid | 2 +- src/sqliteInt.h | 2 +- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index a9e3f89018..2715f1f973 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Back\sout\scheck-in\s[0b3174e0b1364c]\sand\sreplace\sit\swith\sa\sbetter\sfix\sfor\s\\ticket\s[91e2e8ba6ff2e2]\s-\sa\sfix\sthat\sdoes\snot\scause\sthe\sproblem\sidentified\sby\s\nticket\s[7ffd1ca1d2ad4ec].\sAdd\snew\stest\scases\sfor\sboth\stickets. -D 2017-01-16T18:10:17.967 +C Disable\sintrinsic\sfunctions\sfor\sWindows\susing\sClang,\sdue\sto\sreports\sof\nlinkage\serrors.\s\sThis\scauses\sa\s0.6%\sperformance\sreduction.\s\sWe\swill\swant\sto\nrevisit\sthis\schange\sin\sthe\sfuture. +D 2017-01-17T00:10:58.166 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -394,7 +394,7 @@ F src/shell.c 6095531aa900decdaa765e0f3993fba7153c92c1 F src/sqlite.h.in e71655293c9bde26939496f3aac9d1821d2c07a2 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae -F src/sqliteInt.h bec6274d8991528bc12d9a34d01fe84bdf6d00d9 +F src/sqliteInt.h ce3e07c720b0cebc8887ea86b3b128da0913c5d3 F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 @@ -1546,8 +1546,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 97914266cb4ec63b0c9185ab139673139bd2f0ed 0613665274346917f5482f9210bf0c60a0fed7d9 -R d9bec5fa752ad661e71dee0a4ee8e911 -T +closed 0613665274346917f5482f9210bf0c60a0fed7d9 +P 9b64af7b5201a8700ae9e384b04714ca18df7449 +R 2a65551e28553413c063bc022e23faf5 U drh -Z 535f9cb18662b936eb37d1700bf0881b +Z 6f331e0f247acb77a734fb284e31d3c4 diff --git a/manifest.uuid b/manifest.uuid index 970b95dbeb..30780fc11a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9b64af7b5201a8700ae9e384b04714ca18df7449 \ No newline at end of file +7fd560c6d2ff470b755ad118287a0a8825b3009e \ No newline at end of file diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 3215a7f865..d5ac957d22 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -111,7 +111,7 @@ #endif /* What version of CLANG is being used. 0 means CLANG is not being used */ -#ifdef __clang__ +#if defined(__clang__) && !defined(_WIN32) # define CLANG_VERSION \ (__clang_major__*1000000+__clang_minor__*1000+__clang_patchlevel__) #else From 25fd2e247bca3d0ddf9a88260bcea7ddfac268bb Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 17 Jan 2017 10:41:42 +0000 Subject: [PATCH 1206/1484] Fix a problem that could cause a spurious SQLITE_NOMEM error when attempting to resume an RBU operation if the previous client failed right after completing the incremental checkpoint. Also a "cannot vacuum wal db" error that could occur when resuming an RBU vacuum if an error (OOM or IO error) occurs during the incremental checkpoint. FossilOrigin-Name: 681d96eb822e606da53700867191d4738bda20c8 --- ext/rbu/rbufault4.test | 66 +++++++++++++++++++++++++++++++++++++++++ ext/rbu/rbuvacuum2.test | 31 +++++++++++++++++++ ext/rbu/sqlite3rbu.c | 37 ++++++++++++++++++----- manifest | 17 ++++++----- manifest.uuid | 2 +- 5 files changed, 137 insertions(+), 16 deletions(-) create mode 100644 ext/rbu/rbufault4.test diff --git a/ext/rbu/rbufault4.test b/ext/rbu/rbufault4.test new file mode 100644 index 0000000000..fe6cc90dc9 --- /dev/null +++ b/ext/rbu/rbufault4.test @@ -0,0 +1,66 @@ +# 2014 October 22 +# +# 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. +# +#*********************************************************************** +# + +if {![info exists testdir]} { + set testdir [file join [file dirname [info script]] .. .. test] +} +source $testdir/tester.tcl +source $testdir/malloc_common.tcl +set ::testprefix rbufault4 + +for {set tn 1} {1} {incr tn} { + reset_db + do_execsql_test 1.0 { + CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c); + CREATE INDEX i1b ON t1(b); + CREATE INDEX i1c ON t1(c); + INSERT INTO t1 VALUES(1, 2, 3); + INSERT INTO t1 VALUES(4, 5, 6); + } + + forcedelete test.db2 + sqlite3rbu_vacuum rbu test.db test.db2 + for {set i 0} {$i < $tn} {incr i} { rbu step } + set rc [rbu close] + if {$rc!="SQLITE_OK"} { + if {$rc!="SQLITE_DONE"} {error $rc} + break + } + faultsim_save + + do_faultsim_test $tn -faults oom-t* -prep { + faultsim_restore + } -body { + sqlite3rbu_vacuum rbu test.db test.db2 + while 1 { + set rc [rbu step] + if {$rc=="SQLITE_DONE"} break + if {$rc!="SQLITE_OK"} { error $rc } + } + } -test { + catch {rbu close} + faultsim_test_result {0 {}} {1 SQLITE_NOMEM} {1 SQLITE_IOERR_NOMEM} + + sqlite3rbu_vacuum rbu test.db test.db2 + while {[rbu step]=="SQLITE_OK"} {} + set trc [rbu close] + if {$trc!="SQLITE_DONE"} { error "Got $trc instead of SQLITE_DONE!" } + + set rc [db one {PRAGMA integrity_check}] + if {$rc!="ok"} { error "Got $rc instead of ok!" } + } +} + + + +finish_test + diff --git a/ext/rbu/rbuvacuum2.test b/ext/rbu/rbuvacuum2.test index bd38660320..0a1fe3da94 100644 --- a/ext/rbu/rbuvacuum2.test +++ b/ext/rbu/rbuvacuum2.test @@ -199,6 +199,37 @@ if {$::tcl_platform(platform)=="unix"} { } } +#------------------------------------------------------------------------- +# Test the outcome of some other connection running a checkpoint while +# the incremental checkpoint is suspended. +# +reset_db +do_execsql_test 6.0 { + CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c); + CREATE INDEX i1b ON t1(b); + CREATE INDEX i1c ON t1(c); + INSERT INTO t1 VALUES(1, 2, 3); + INSERT INTO t1 VALUES(4, 5, 6); +} +forcedelete test.db2 + +do_test 6.1 { + sqlite3rbu_vacuum rbu test.db test.db2 + while {[rbu state]!="checkpoint"} { rbu step } + rbu close +} {SQLITE_OK} + +do_execsql_test 6.2 { + SELECT 1 FROM sqlite_master LIMIT 1; + PRAGMA wal_checkpoint; +} {1 0 4 4} + +do_test 6.3 { + sqlite3rbu_vacuum rbu test.db test.db2 + while {[rbu step]!="SQLITE_DONE"} { rbu step } + rbu close + execsql { PRAGMA integrity_check } +} {ok} finish_test diff --git a/ext/rbu/sqlite3rbu.c b/ext/rbu/sqlite3rbu.c index 235ba3fe2a..48c69115ee 100644 --- a/ext/rbu/sqlite3rbu.c +++ b/ext/rbu/sqlite3rbu.c @@ -2333,7 +2333,7 @@ static RbuState *rbuLoadState(sqlite3rbu *p){ ** Open the database handle and attach the RBU database as "rbu". If an ** error occurs, leave an error code and message in the RBU handle. */ -static void rbuOpenDatabase(sqlite3rbu *p){ +static void rbuOpenDatabase(sqlite3rbu *p, int *pbRetry){ assert( p->rc || (p->dbMain==0 && p->dbRbu==0) ); assert( p->rc || rbuIsVacuum(p) || p->zTarget!=0 ); @@ -2420,6 +2420,15 @@ static void rbuOpenDatabase(sqlite3rbu *p){ if( !rbuIsVacuum(p) ){ p->dbMain = rbuOpenDbhandle(p, p->zTarget, 1); }else if( p->pRbuFd->pWalFd ){ + if( pbRetry ){ + p->pRbuFd->bNolock = 0; + sqlite3_close(p->dbRbu); + sqlite3_close(p->dbMain); + p->dbMain = 0; + p->dbRbu = 0; + *pbRetry = 1; + return; + } p->rc = SQLITE_ERROR; p->zErrmsg = sqlite3_mprintf("cannot vacuum wal mode database"); }else{ @@ -2600,16 +2609,18 @@ static void rbuSetupCheckpoint(sqlite3rbu *p, RbuState *pState){ if( rc2!=SQLITE_INTERNAL ) p->rc = rc2; } - if( p->rc==SQLITE_OK ){ + if( p->rc==SQLITE_OK && p->nFrame>0 ){ p->eStage = RBU_STAGE_CKPT; p->nStep = (pState ? pState->nRow : 0); p->aBuf = rbuMalloc(p, p->pgsz); p->iWalCksum = rbuShmChecksum(p); } - if( p->rc==SQLITE_OK && pState && pState->iWalCksum!=p->iWalCksum ){ - p->rc = SQLITE_DONE; - p->eStage = RBU_STAGE_DONE; + if( p->rc==SQLITE_OK ){ + if( p->nFrame==0 || (pState && pState->iWalCksum!=p->iWalCksum) ){ + p->rc = SQLITE_DONE; + p->eStage = RBU_STAGE_DONE; + } } } @@ -2782,7 +2793,7 @@ static void rbuMoveOalFile(sqlite3rbu *p){ #endif if( p->rc==SQLITE_OK ){ - rbuOpenDatabase(p); + rbuOpenDatabase(p, 0); rbuSetupCheckpoint(p, 0); } } @@ -3493,6 +3504,7 @@ static sqlite3rbu *openRbuHandle( /* Open the target, RBU and state databases */ if( p->rc==SQLITE_OK ){ char *pCsr = (char*)&p[1]; + int bRetry = 0; if( zTarget ){ p->zTarget = pCsr; memcpy(p->zTarget, zTarget, nTarget+1); @@ -3504,7 +3516,18 @@ static sqlite3rbu *openRbuHandle( if( zState ){ p->zState = rbuMPrintf(p, "%s", zState); } - rbuOpenDatabase(p); + + /* If the first attempt to open the database file fails and the bRetry + ** flag it set, this means that the db was not opened because it seemed + ** to be a wal-mode db. But, this may have happened due to an earlier + ** RBU vacuum operation leaving an old wal file in the directory. + ** If this is the case, it will have been checkpointed and deleted + ** when the handle was closed and a second attempt to open the + ** database may succeed. */ + rbuOpenDatabase(p, &bRetry); + if( bRetry ){ + rbuOpenDatabase(p, 0); + } } if( p->rc==SQLITE_OK ){ diff --git a/manifest b/manifest index 2715f1f973..e888f901e2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Disable\sintrinsic\sfunctions\sfor\sWindows\susing\sClang,\sdue\sto\sreports\sof\nlinkage\serrors.\s\sThis\scauses\sa\s0.6%\sperformance\sreduction.\s\sWe\swill\swant\sto\nrevisit\sthis\schange\sin\sthe\sfuture. -D 2017-01-17T00:10:58.166 +C Fix\sa\sproblem\sthat\scould\scause\sa\sspurious\sSQLITE_NOMEM\serror\swhen\sattempting\nto\sresume\san\sRBU\soperation\sif\sthe\sprevious\sclient\sfailed\sright\safter\ncompleting\sthe\sincremental\scheckpoint.\sAlso\sa\s"cannot\svacuum\swal\sdb"\serror\nthat\scould\soccur\swhen\sresuming\san\sRBU\svacuum\sif\san\serror\s(OOM\sor\sIO\serror)\noccurs\sduring\sthe\sincremental\scheckpoint. +D 2017-01-17T10:41:42.780 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -252,13 +252,14 @@ F ext/rbu/rbudor.test 99b05cc0df613e962c2c8085cfb05686a09cf315 F ext/rbu/rbufault.test cc0be8d5d392d98b0c2d6a51be377ea989250a89 F ext/rbu/rbufault2.test 9a7f19edd6ea35c4c9f807d8a3db0a03a5670c06 F ext/rbu/rbufault3.test 54a399888ac4af44c68f9f58afbed23149428bca +F ext/rbu/rbufault4.test 34e70701cbec51571ffbd9fbf9d4e0f2ec495ca7 F ext/rbu/rbufts.test 828cd689da825f0a7b7c53ffc1f6f7fdb6fa5bda F ext/rbu/rbuprogress.test e3e25fb7622641b8f2df7c6b7a7eb6fddfc46a4b F ext/rbu/rburesume.test 8acb77f4a422ff55acfcfc9cc15a5cb210b1de83 F ext/rbu/rbusave.test 0f43b6686084f426ddd040b878426452fd2c2f48 F ext/rbu/rbuvacuum.test 4a977447c15c2581ab668781d9ef4294382530e0 -F ext/rbu/rbuvacuum2.test 2569205b74ff40fbf3bda2fce33a58eb40eebdcc -F ext/rbu/sqlite3rbu.c 4ca89fbe9ca501da17f338d580d3f19d59fc6053 +F ext/rbu/rbuvacuum2.test 2074ab14fe66e1c7e7210c62562650dcd215bbaa +F ext/rbu/sqlite3rbu.c bb0de6cdbdb14a7d55a097238a434b7e99caf318 F ext/rbu/sqlite3rbu.h 6fb6294c34a9ca93b5894a33bca530c6f08decba F ext/rbu/test_rbu.c 5aa22616afac6f71ebd3d9bc9bf1006cfabcca88 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 @@ -1546,7 +1547,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 9b64af7b5201a8700ae9e384b04714ca18df7449 -R 2a65551e28553413c063bc022e23faf5 -U drh -Z 6f331e0f247acb77a734fb284e31d3c4 +P 7fd560c6d2ff470b755ad118287a0a8825b3009e +R 3b5f909693e02732236a5ff9d24ebb43 +U dan +Z 623656530433c4c90deab7fe9f3d0d79 diff --git a/manifest.uuid b/manifest.uuid index 30780fc11a..4ce4080714 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7fd560c6d2ff470b755ad118287a0a8825b3009e \ No newline at end of file +681d96eb822e606da53700867191d4738bda20c8 \ No newline at end of file From 8a9e83583bc378043e7ba677bb5f40af4614d641 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Wed, 18 Jan 2017 22:16:20 +0000 Subject: [PATCH 1207/1484] Fix handling of initial hidden and/or system files in the opendir() implementation for Windows. No changes to non-test code. FossilOrigin-Name: 26dd42b462dc621b8b0a2295fc91d3e61ac732b6 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/test_windirent.c | 16 +++++++++++++--- 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index e888f901e2..4727a38a08 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\sthat\scould\scause\sa\sspurious\sSQLITE_NOMEM\serror\swhen\sattempting\nto\sresume\san\sRBU\soperation\sif\sthe\sprevious\sclient\sfailed\sright\safter\ncompleting\sthe\sincremental\scheckpoint.\sAlso\sa\s"cannot\svacuum\swal\sdb"\serror\nthat\scould\soccur\swhen\sresuming\san\sRBU\svacuum\sif\san\serror\s(OOM\sor\sIO\serror)\noccurs\sduring\sthe\sincremental\scheckpoint. -D 2017-01-17T10:41:42.780 +C Fix\shandling\sof\sinitial\shidden\sand/or\ssystem\sfiles\sin\sthe\sopendir()\simplementation\sfor\sWindows.\s\sNo\schanges\sto\snon-test\scode. +D 2017-01-18T22:16:20.672 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -446,7 +446,7 @@ F src/test_tclvar.c df9fe1213c2634687a9ca0b0bec0d2119d359ae3 F src/test_thread.c 911d15fb14e19c0c542bdc8aabf981c2f10a4858 F src/test_vfs.c f0186261a24de2671d080bcd8050732f0cb64f6e F src/test_vfstrace.c bab9594adc976cbe696ff3970728830b4c5ed698 -F src/test_windirent.c 600398db0198ca1c77ca183831bf456746b6f5c4 +F src/test_windirent.c 5234b0c38bda5cb7dfc031db6a594af2cbcf7fb7 F src/test_windirent.h 7edc57e2faa727026dbd5d010dd0e2e665d5aa01 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c @@ -1547,7 +1547,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 7fd560c6d2ff470b755ad118287a0a8825b3009e -R 3b5f909693e02732236a5ff9d24ebb43 -U dan -Z 623656530433c4c90deab7fe9f3d0d79 +P 681d96eb822e606da53700867191d4738bda20c8 +R 728f11ac297b564a808bf2eb4a24c6c8 +U mistachkin +Z 724393d72bdc7af5ff5eea47dd7cb77d diff --git a/manifest.uuid b/manifest.uuid index 4ce4080714..a40c13f3d9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -681d96eb822e606da53700867191d4738bda20c8 \ No newline at end of file +26dd42b462dc621b8b0a2295fc91d3e61ac732b6 \ No newline at end of file diff --git a/src/test_windirent.c b/src/test_windirent.c index 044bc7f414..450e4c3cc7 100644 --- a/src/test_windirent.c +++ b/src/test_windirent.c @@ -63,6 +63,7 @@ LPDIR opendir( dirname = windirent_getenv("SystemDrive"); } + memset(&data, 0, sizeof(struct _finddata_t)); _snprintf(data.name, namesize, "%s\\*", dirname); dirp->d_handle = _findfirst(data.name, &data); @@ -71,12 +72,19 @@ LPDIR opendir( return NULL; } - /* TODO: Remove this block to allow hidden and system files. */ + /* TODO: Remove this block to allow hidden and/or system files. */ if( data.attrib&_A_HIDDEN || data.attrib&_A_SYSTEM ){ +next: + + memset(&data, 0, sizeof(struct _finddata_t)); if( _findnext(dirp->d_handle, &data)==-1 ){ closedir(dirp); return NULL; } + + /* TODO: Remove this block to allow hidden and/or system files. */ + if( data.attrib&_A_HIDDEN ) goto next; + if( data.attrib&_A_SYSTEM ) goto next; } dirp->d_first.d_attributes = data.attrib; @@ -105,9 +113,10 @@ LPDIRENT readdir( next: + memset(&data, 0, sizeof(struct _finddata_t)); if( _findnext(dirp->d_handle, &data)==-1 ) return NULL; - /* TODO: Remove this block to allow hidden and system files. */ + /* TODO: Remove this block to allow hidden and/or system files. */ if( data.attrib&_A_HIDDEN ) goto next; if( data.attrib&_A_SYSTEM ) goto next; @@ -146,12 +155,13 @@ INT readdir_r( next: + memset(&data, 0, sizeof(struct _finddata_t)); if( _findnext(dirp->d_handle, &data)==-1 ){ *result = NULL; return ENOENT; } - /* TODO: Remove this block to allow hidden and system files. */ + /* TODO: Remove this block to allow hidden and/or system files. */ if( data.attrib&_A_HIDDEN ) goto next; if( data.attrib&_A_SYSTEM ) goto next; From 7059138a0811ea83b98753b632742a4aa71e7c4d Mon Sep 17 00:00:00 2001 From: mistachkin Date: Wed, 18 Jan 2017 22:16:34 +0000 Subject: [PATCH 1208/1484] Make the vtabH-3.1 test more portable and robust. FossilOrigin-Name: d3c91c1fb345fbcbfc60a897bebf771c795430c9 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/vtabH.test | 47 +++++++++++++++++++++++++++++++---------------- 3 files changed, 38 insertions(+), 23 deletions(-) diff --git a/manifest b/manifest index 4727a38a08..68a0430236 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\shandling\sof\sinitial\shidden\sand/or\ssystem\sfiles\sin\sthe\sopendir()\simplementation\sfor\sWindows.\s\sNo\schanges\sto\snon-test\scode. -D 2017-01-18T22:16:20.672 +C Make\sthe\svtabH-3.1\stest\smore\sportable\sand\srobust. +D 2017-01-18T22:16:34.363 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -1383,7 +1383,7 @@ F test/vtabC.test 4528f459a13136f982e75614d120aef165f17292 F test/vtabD.test 05b3f1d77117271671089e48719524b676842e96 F test/vtabE.test d5024aa42754962f6bb0afd261681686488e7afe F test/vtabF.test 1918844c7c902f6a16c8dacf1ec8f84886d6e78b -F test/vtabH.test 97f61b0253260831af6232163f7852e2653baed6 +F test/vtabH.test a99d22d77e7ad367ea95df7c7c953320980bf63f F test/vtabI.test 751b07636700dbdea328e4265b6077ccd6811a3f F test/vtab_alter.test 9e374885248f69e251bdaacf480b04a197f125e5 F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8 @@ -1547,7 +1547,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 681d96eb822e606da53700867191d4738bda20c8 -R 728f11ac297b564a808bf2eb4a24c6c8 +P 26dd42b462dc621b8b0a2295fc91d3e61ac732b6 +R ea3d0fbdb25858ca04efea2603f3e30f U mistachkin -Z 724393d72bdc7af5ff5eea47dd7cb77d +Z 79e95e457c2d340f3ec156d2b8c6aa1c diff --git a/manifest.uuid b/manifest.uuid index a40c13f3d9..93490dc381 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -26dd42b462dc621b8b0a2295fc91d3e61ac732b6 \ No newline at end of file +d3c91c1fb345fbcbfc60a897bebf771c795430c9 \ No newline at end of file diff --git a/test/vtabH.test b/test/vtabH.test index f2a116f350..678557385a 100644 --- a/test/vtabH.test +++ b/test/vtabH.test @@ -121,29 +121,43 @@ if {$tcl_platform(platform)!="windows" || \ SELECT name FROM fsdir WHERE dir = '.' AND name = '.' } {test.db .} + proc sort_files { names {nocase false} } { + if {$nocase && $::tcl_platform(platform) eq "windows"} { + return [lsort -dictionary -nocase $names] + } else { + return [lsort $names] + } + } + proc list_root_files {} { if {$::tcl_platform(platform) eq "windows"} { - set res [list] - foreach name [glob -directory $::env(fstreeDrive)/ -- *] { + set res [list]; set dir $::env(fstreeDrive)/; set names [list] + eval lappend names [glob -nocomplain -directory $dir -- *] + foreach name $names { if {[string index [file tail $name] 0] eq "."} continue + if {[file attributes $name -hidden]} continue + if {[file attributes $name -system]} continue lappend res $name } - return $res + return [sort_files $res true] } else { - return [string map {/ {}} [glob /*]] + return [sort_files [string map {/ {}} [glob -nocomplain -- /*]]] } } proc list_files { pattern } { if {$::tcl_platform(platform) eq "windows"} { - set res [list] - foreach name [glob -nocomplain $pattern] { + set res [list]; set names [list] + eval lappend names [glob -nocomplain -- $pattern] + foreach name $names { if {[string index [file tail $name] 0] eq "."} continue + if {[file attributes $name -hidden]} continue + if {[file attributes $name -system]} continue lappend res $name } - return $res + return [sort_files $res] } else { - return [glob -nocomplain $pattern] + return [sort_files [glob -nocomplain -- $pattern]] } } @@ -153,18 +167,19 @@ if {$tcl_platform(platform)!="windows" || \ # set res [list] set root_files [list_root_files] - set num_root_files [llength $root_files] - set lim_root_files [expr {$num_root_files > 5 ? 5 : $num_root_files}] - foreach p [lrange $root_files 0 [expr {$lim_root_files - 1}]] { + foreach p $root_files { if {$::tcl_platform(platform) eq "windows"} { - if {[regexp {\$} $p]} {incr lim_root_files -1} else {lappend res $p} + if {![regexp {\$} $p]} {lappend res $p} } else { lappend res "/$p" } } - do_execsql_test 3.1 [subst { - SELECT path FROM fstree WHERE path NOT GLOB '*\$*' LIMIT $lim_root_files; - }] $res + set num_root_files [llength $root_files] + do_test 3.1 { + sort_files [execsql { + SELECT path FROM fstree WHERE path NOT GLOB '*\$*' LIMIT $num_root_files; + }] true + } [sort_files $res true] # Read all entries in the current directory. # @@ -182,7 +197,7 @@ if {$tcl_platform(platform)!="windows" || \ set res [contents $pwd] do_execsql_test 3.2 { SELECT path FROM fstree WHERE path GLOB $pwd ORDER BY 1 - } [lsort $res] + } [sort_files $res] # Add some sub-directories and files to the current directory. # From d3e73d6c1c3161111d494e84859a640d3357c3e7 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Wed, 18 Jan 2017 22:19:01 +0000 Subject: [PATCH 1209/1484] Remove superfluous option to Tcl 'lsort' in the vtabH test file. FossilOrigin-Name: b92cc6e58ae31cbe6600a522beb5485f7add04b2 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/vtabH.test | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 68a0430236..416ccf1043 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\sthe\svtabH-3.1\stest\smore\sportable\sand\srobust. -D 2017-01-18T22:16:34.363 +C Remove\ssuperfluous\soption\sto\sTcl\s'lsort'\sin\sthe\svtabH\stest\sfile. +D 2017-01-18T22:19:01.508 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -1383,7 +1383,7 @@ F test/vtabC.test 4528f459a13136f982e75614d120aef165f17292 F test/vtabD.test 05b3f1d77117271671089e48719524b676842e96 F test/vtabE.test d5024aa42754962f6bb0afd261681686488e7afe F test/vtabF.test 1918844c7c902f6a16c8dacf1ec8f84886d6e78b -F test/vtabH.test a99d22d77e7ad367ea95df7c7c953320980bf63f +F test/vtabH.test a2912cd3ea3386aecc3cb74ebfdfcc4e6d4b7dd3 F test/vtabI.test 751b07636700dbdea328e4265b6077ccd6811a3f F test/vtab_alter.test 9e374885248f69e251bdaacf480b04a197f125e5 F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8 @@ -1547,7 +1547,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 26dd42b462dc621b8b0a2295fc91d3e61ac732b6 -R ea3d0fbdb25858ca04efea2603f3e30f +P d3c91c1fb345fbcbfc60a897bebf771c795430c9 +R 2cfcfd69ff656c8eb0c9b18b58b2f78e U mistachkin -Z 79e95e457c2d340f3ec156d2b8c6aa1c +Z e24ce1e7a409b1f16613abdf400a1354 diff --git a/manifest.uuid b/manifest.uuid index 93490dc381..936488379e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d3c91c1fb345fbcbfc60a897bebf771c795430c9 \ No newline at end of file +b92cc6e58ae31cbe6600a522beb5485f7add04b2 \ No newline at end of file diff --git a/test/vtabH.test b/test/vtabH.test index 678557385a..3ce457ff0b 100644 --- a/test/vtabH.test +++ b/test/vtabH.test @@ -123,7 +123,7 @@ if {$tcl_platform(platform)!="windows" || \ proc sort_files { names {nocase false} } { if {$nocase && $::tcl_platform(platform) eq "windows"} { - return [lsort -dictionary -nocase $names] + return [lsort -nocase $names] } else { return [lsort $names] } From aac853bae8281e32319c1e5382e2893fa5fb7492 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Wed, 18 Jan 2017 22:47:42 +0000 Subject: [PATCH 1210/1484] In the 'windirent' test module, use a macro for the hidden/system attribute checking. FossilOrigin-Name: a84a08d0716656dc0b26eafb1841c48d83c67ef2 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/test_windirent.c | 11 ++++------- src/test_windirent.h | 11 +++++++++++ 4 files changed, 23 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index 416ccf1043..9c7ce9a588 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\ssuperfluous\soption\sto\sTcl\s'lsort'\sin\sthe\svtabH\stest\sfile. -D 2017-01-18T22:19:01.508 +C In\sthe\s'windirent'\stest\smodule,\suse\sa\smacro\sfor\sthe\shidden/system\sattribute\schecking. +D 2017-01-18T22:47:42.937 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -446,8 +446,8 @@ F src/test_tclvar.c df9fe1213c2634687a9ca0b0bec0d2119d359ae3 F src/test_thread.c 911d15fb14e19c0c542bdc8aabf981c2f10a4858 F src/test_vfs.c f0186261a24de2671d080bcd8050732f0cb64f6e F src/test_vfstrace.c bab9594adc976cbe696ff3970728830b4c5ed698 -F src/test_windirent.c 5234b0c38bda5cb7dfc031db6a594af2cbcf7fb7 -F src/test_windirent.h 7edc57e2faa727026dbd5d010dd0e2e665d5aa01 +F src/test_windirent.c 17f91f5f2aa1bb7328abb49414c363b5d2a9d3ff +F src/test_windirent.h 5d67483a55442e31e1bde0f4a230e6e932ad5906 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c 5c2f516876fc27fbd7753913f032f49eb89e83b5 @@ -1547,7 +1547,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d3c91c1fb345fbcbfc60a897bebf771c795430c9 -R 2cfcfd69ff656c8eb0c9b18b58b2f78e +P b92cc6e58ae31cbe6600a522beb5485f7add04b2 +R 28b62fae1b56b071f03984b3c0c7d517 U mistachkin -Z e24ce1e7a409b1f16613abdf400a1354 +Z 8396ae361cfa963c7c2449732ae79bb0 diff --git a/manifest.uuid b/manifest.uuid index 936488379e..0a876335c4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b92cc6e58ae31cbe6600a522beb5485f7add04b2 \ No newline at end of file +a84a08d0716656dc0b26eafb1841c48d83c67ef2 \ No newline at end of file diff --git a/src/test_windirent.c b/src/test_windirent.c index 450e4c3cc7..ca78d345d9 100644 --- a/src/test_windirent.c +++ b/src/test_windirent.c @@ -73,7 +73,7 @@ LPDIR opendir( } /* TODO: Remove this block to allow hidden and/or system files. */ - if( data.attrib&_A_HIDDEN || data.attrib&_A_SYSTEM ){ + if( is_filtered(data) ){ next: memset(&data, 0, sizeof(struct _finddata_t)); @@ -83,8 +83,7 @@ next: } /* TODO: Remove this block to allow hidden and/or system files. */ - if( data.attrib&_A_HIDDEN ) goto next; - if( data.attrib&_A_SYSTEM ) goto next; + if( is_filtered(data) ) goto next; } dirp->d_first.d_attributes = data.attrib; @@ -117,8 +116,7 @@ next: if( _findnext(dirp->d_handle, &data)==-1 ) return NULL; /* TODO: Remove this block to allow hidden and/or system files. */ - if( data.attrib&_A_HIDDEN ) goto next; - if( data.attrib&_A_SYSTEM ) goto next; + if( is_filtered(data) ) goto next; dirp->d_next.d_ino++; dirp->d_next.d_attributes = data.attrib; @@ -162,8 +160,7 @@ next: } /* TODO: Remove this block to allow hidden and/or system files. */ - if( data.attrib&_A_HIDDEN ) goto next; - if( data.attrib&_A_SYSTEM ) goto next; + if( is_filtered(data) ) goto next; entry->d_ino = (ino_t)-1; /* not available */ entry->d_attributes = data.attrib; diff --git a/src/test_windirent.h b/src/test_windirent.h index be454988e3..578e2a7c22 100644 --- a/src/test_windirent.h +++ b/src/test_windirent.h @@ -92,6 +92,17 @@ struct DIR { DIRENT d_next; /* DIRENT constructed based on "_findnext". */ }; +/* +** Provide a macro, for use by the implementation, to determine if a +** particular directory entry should be skipped over when searching for +** the next directory entry that should be returned by the readdir() or +** readdir_r() functions. +*/ + +#ifndef is_filtered +# define is_filtered(a) ((((a).attrib)&_A_HIDDEN) || (((a).attrib)&_A_SYSTEM)) +#endif + /* ** Provide the function prototype for the POSIX compatiable getenv() ** function. This function is not thread-safe. From 2f31d0204960ccfae468cef94a0447311b9bb143 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Thu, 19 Jan 2017 18:20:36 +0000 Subject: [PATCH 1211/1484] In the 'vtshim' extension, avoid accessing freed memory when handling errors from xCreate/xConnect. FossilOrigin-Name: ffd559afd32dcdce9c733ebccdee88fda9b689cf --- ext/misc/vtshim.c | 2 ++ manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/ext/misc/vtshim.c b/ext/misc/vtshim.c index 01348e8d3e..0709a26a7f 100644 --- a/ext/misc/vtshim.c +++ b/ext/misc/vtshim.c @@ -95,6 +95,7 @@ static int vtshimCreate( if( rc ){ sqlite3_free(pNew); *ppVtab = 0; + return rc; } pNew->pAux = pAux; pNew->ppPrev = &pAux->pAllVtab; @@ -133,6 +134,7 @@ static int vtshimConnect( if( rc ){ sqlite3_free(pNew); *ppVtab = 0; + return rc; } pNew->pAux = pAux; pNew->ppPrev = &pAux->pAllVtab; diff --git a/manifest b/manifest index 9c7ce9a588..eab928e083 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\sthe\s'windirent'\stest\smodule,\suse\sa\smacro\sfor\sthe\shidden/system\sattribute\schecking. -D 2017-01-18T22:47:42.937 +C In\sthe\s'vtshim'\sextension,\savoid\saccessing\sfreed\smemory\swhen\shandling\serrors\sfrom\sxCreate/xConnect. +D 2017-01-19T18:20:36.317 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -227,7 +227,7 @@ F ext/misc/spellfix.c a4723b6aff748a417b5091b68a46443265c40f0d F ext/misc/totype.c 4a167594e791abeed95e0a8db028822b5e8fe512 F ext/misc/vfslog.c fe40fab5c077a40477f7e5eba994309ecac6cc95 F ext/misc/vfsstat.c bf10ef0bc51e1ad6756629e1edb142f7a8db1178 -F ext/misc/vtshim.c babb0dc2bf116029e3e7c9a618b8a1377045303e +F ext/misc/vtshim.c 1976e6dd68dd0d64508c91a6dfab8e75f8aaf6cd F ext/misc/wholenumber.c 784b12543d60702ebdd47da936e278aa03076212 F ext/rbu/rbu.c b2c0b5e6ae1a89affc0edfc127ebfa5f637a0ce4 F ext/rbu/rbu1.test 43836fac8c7179a358eaf38a8a1ef3d6e6285842 @@ -1547,7 +1547,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b92cc6e58ae31cbe6600a522beb5485f7add04b2 -R 28b62fae1b56b071f03984b3c0c7d517 +P a84a08d0716656dc0b26eafb1841c48d83c67ef2 +R 37615874230b85a181e9596f7f8a21ff U mistachkin -Z 8396ae361cfa963c7c2449732ae79bb0 +Z 99974373edae111c658f7548f0073df4 diff --git a/manifest.uuid b/manifest.uuid index 0a876335c4..01c9585ffd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a84a08d0716656dc0b26eafb1841c48d83c67ef2 \ No newline at end of file +ffd559afd32dcdce9c733ebccdee88fda9b689cf \ No newline at end of file From 8674e49214c8d9a0e23cf46c15d6bd4b74b00c4d Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 19 Jan 2017 21:20:11 +0000 Subject: [PATCH 1212/1484] If compiled with SQLITE_INLINE_MEMCPY, all memcpy() calls are replaced with in-line code. With that change, cachegrind shows which memcpy() calls are taking the most time. This is a performance-measurement hack only and is not for production use. FossilOrigin-Name: 9ed38521617136223a667988aed40e25797faf84 --- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- src/loadext.c | 1 - src/resolve.c | 2 -- src/sqliteInt.h | 12 ++++++++++++ src/table.c | 2 -- 6 files changed, 23 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index eab928e083..6c86b1eb77 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\sthe\s'vtshim'\sextension,\savoid\saccessing\sfreed\smemory\swhen\shandling\serrors\sfrom\sxCreate/xConnect. -D 2017-01-19T18:20:36.317 +C If\scompiled\swith\sSQLITE_INLINE_MEMCPY,\sall\smemcpy()\scalls\sare\sreplaced\swith\nin-line\scode.\s\sWith\sthat\schange,\scachegrind\sshows\swhich\smemcpy()\scalls\nare\staking\sthe\smost\stime.\s\sThis\sis\sa\sperformance-measurement\shack\sonly\sand\nis\snot\sfor\sproduction\suse. +D 2017-01-19T21:20:11.204 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -354,7 +354,7 @@ F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 F src/insert.c 05e47e2de7b712a3a4148cd469e5f60873f5ef13 F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e -F src/loadext.c 5d6642d141c07d366e43d359e94ec9de47add41d +F src/loadext.c a68d8d1d14cf7488bb29dc5311cb1ce9a4404258 F src/main.c e207b81542d13b9f13d61e78ca441f9781f055b0 F src/malloc.c fc1b9f445290f2145da48fc08730c26e6082b640 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 @@ -388,17 +388,17 @@ F src/pragma.h 61aa5389118594bebb28120a6720401aee34ce1a F src/prepare.c b1140c3d0cf59bc85ace00ce363153041b424b7a F src/printf.c ff10a9b9902cd2afe5f655f3013c6307d969b1fd F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 -F src/resolve.c bb070cf5f23611c44ab7e4788803684e385fc3fb +F src/resolve.c f9bc0de45a30a450da47b3766de00be89bf9be79 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c 3856db523b942062bca8722ba03b61c324ff94d6 F src/shell.c 6095531aa900decdaa765e0f3993fba7153c92c1 F src/sqlite.h.in e71655293c9bde26939496f3aac9d1821d2c07a2 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae -F src/sqliteInt.h ce3e07c720b0cebc8887ea86b3b128da0913c5d3 +F src/sqliteInt.h 525c061ae9aafc8d4720a018d82f0936d9eee5ab F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 -F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 +F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 F src/tclsqlite.c 418f5e5e0840425a7e5b33f3600dccd378a57549 F src/test1.c 8a98191a1da8e100f77cdb5cc716df67d405028d F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5 @@ -1547,7 +1547,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a84a08d0716656dc0b26eafb1841c48d83c67ef2 -R 37615874230b85a181e9596f7f8a21ff -U mistachkin -Z 99974373edae111c658f7548f0073df4 +P ffd559afd32dcdce9c733ebccdee88fda9b689cf +R fad09dad35bb606057a537179db15d76 +U drh +Z 52e9f95dbec08dacc595dc3f0b2e0450 diff --git a/manifest.uuid b/manifest.uuid index 01c9585ffd..17bbd5a1dd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ffd559afd32dcdce9c733ebccdee88fda9b689cf \ No newline at end of file +9ed38521617136223a667988aed40e25797faf84 \ No newline at end of file diff --git a/src/loadext.c b/src/loadext.c index 6011fd2bf8..3296be60dd 100644 --- a/src/loadext.c +++ b/src/loadext.c @@ -18,7 +18,6 @@ #endif #include "sqlite3ext.h" #include "sqliteInt.h" -#include #ifndef SQLITE_OMIT_LOAD_EXTENSION /* diff --git a/src/resolve.c b/src/resolve.c index dac73e5fa9..7d89b6fec5 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -15,8 +15,6 @@ ** table and column. */ #include "sqliteInt.h" -#include -#include /* ** Walk the expression tree pExpr and increase the aggregate function diff --git a/src/sqliteInt.h b/src/sqliteInt.h index d5ac957d22..6344cac5f1 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -511,6 +511,18 @@ #include #include +/* +** Use a macro to replace memcpy() if compiled with SQLITE_INLINE_MEMCPY. +** This allows better measurements of where memcpy() is used when running +** cachegrind. But this macro version of memcpy() is very slow so it +** should not be used in production. This is a performance measurement +** hack only. +*/ +#ifdef SQLITE_INLINE_MEMCPY +# define memcpy(D,S,N) {char*xxd=(char*)(D);const char*xxs=(const char*)(S);\ + int xxn=(N);while(xxn-->0)*(xxd++)=*(xxs++);} +#endif + /* ** If compiling for a processor that lacks floating point support, ** substitute integer for floating-point diff --git a/src/table.c b/src/table.c index a50d83ce63..c79255f990 100644 --- a/src/table.c +++ b/src/table.c @@ -17,8 +17,6 @@ ** if they are not used. */ #include "sqliteInt.h" -#include -#include #ifndef SQLITE_OMIT_GET_TABLE From 4df65fc20f617dbd01028e5987c1b1dcb0ca70aa Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 20 Jan 2017 00:40:26 +0000 Subject: [PATCH 1213/1484] Minor performance optimizations to sqlite3_blob_open() and sqlite3_blob_reopen(). FossilOrigin-Name: 52a61967d920047ea0b4409b79793e05c0128964 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbeblob.c | 30 +++++++++++++++++------------- 3 files changed, 24 insertions(+), 20 deletions(-) diff --git a/manifest b/manifest index 6c86b1eb77..c04cd81412 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C If\scompiled\swith\sSQLITE_INLINE_MEMCPY,\sall\smemcpy()\scalls\sare\sreplaced\swith\nin-line\scode.\s\sWith\sthat\schange,\scachegrind\sshows\swhich\smemcpy()\scalls\nare\staking\sthe\smost\stime.\s\sThis\sis\sa\sperformance-measurement\shack\sonly\sand\nis\snot\sfor\sproduction\suse. -D 2017-01-19T21:20:11.204 +C Minor\sperformance\soptimizations\sto\ssqlite3_blob_open()\sand\nsqlite3_blob_reopen(). +D 2017-01-20T00:40:26.827 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -462,7 +462,7 @@ F src/vdbe.h b0866e4191f096f1c987a84b042c3599bdf5423b F src/vdbeInt.h 281cb70332dc8b593b8c7afe776f3a2ba7d4255e F src/vdbeapi.c d6ebaa465f070eb1af8ba4e7b34583ece87bdd24 F src/vdbeaux.c 35c9a9908174e5a26c96d15e1f98214814a39147 -F src/vdbeblob.c f4f98ea672b242f807c08c92c7faaa79e5091b65 +F src/vdbeblob.c fe3694fcc3cf2cad395416f5289bd0e935c2659d F src/vdbemem.c 3b5a9a5b375458d3e12a50ae1aaa41eeec2175fd F src/vdbesort.c eda25cb2d1727efca6f7862fea32b8aa33c0face F src/vdbetrace.c 41963d5376f0349842b5fc4aaaaacd7d9cdc0834 @@ -1547,7 +1547,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ffd559afd32dcdce9c733ebccdee88fda9b689cf -R fad09dad35bb606057a537179db15d76 +P 9ed38521617136223a667988aed40e25797faf84 +R b4a609734c03fe3500908ef05ac99d6b U drh -Z 52e9f95dbec08dacc595dc3f0b2e0450 +Z 622609d2384fcdd28fbe219ab3e3b191 diff --git a/manifest.uuid b/manifest.uuid index 17bbd5a1dd..14542d0a86 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9ed38521617136223a667988aed40e25797faf84 \ No newline at end of file +52a61967d920047ea0b4409b79793e05c0128964 \ No newline at end of file diff --git a/src/vdbeblob.c b/src/vdbeblob.c index 520d16c985..b2902ba321 100644 --- a/src/vdbeblob.c +++ b/src/vdbeblob.c @@ -57,12 +57,17 @@ static int blobSeekToRow(Incrblob *p, sqlite3_int64 iRow, char **pzErr){ char *zErr = 0; /* Error message */ Vdbe *v = (Vdbe *)p->pStmt; - /* Set the value of the SQL statements only variable to integer iRow. - ** This is done directly instead of using sqlite3_bind_int64() to avoid - ** triggering asserts related to mutexes. + /* Set the value of register r[1] in the SQL statement to integer iRow. + ** This is done directly as a performance optimization */ - assert( v->aVar[0].flags&MEM_Int ); - v->aVar[0].u.i = iRow; + v->aMem[1].flags = MEM_Int; + v->aMem[1].u.i = iRow; + + /* If the statement has been run before (and is paused at the OP_ResultRow) + ** then back it up to the point where it does the OP_SeekRowid. This could + ** have been down with an extra OP_Goto, but simply setting the program + ** counter is faster. */ + if( v->pc>3 ) v->pc = 3; rc = sqlite3_step(p->pStmt); if( rc==SQLITE_ROW ){ @@ -257,12 +262,11 @@ int sqlite3_blob_open( static const VdbeOpList openBlob[] = { {OP_TableLock, 0, 0, 0}, /* 0: Acquire a read or write lock */ {OP_OpenRead, 0, 0, 0}, /* 1: Open a cursor */ - {OP_Variable, 1, 1, 0}, /* 2: Move ?1 into reg[1] */ - {OP_NotExists, 0, 7, 1}, /* 3: Seek the cursor */ - {OP_Column, 0, 0, 1}, /* 4 */ - {OP_ResultRow, 1, 0, 0}, /* 5 */ - {OP_Goto, 0, 2, 0}, /* 6 */ - {OP_Halt, 0, 0, 0}, /* 7 */ + /* blobSeekToRow() will initialize r[1] to the desired rowid */ + {OP_NotExists, 0, 5, 1}, /* 2: Seek the cursor to rowid=r[1] */ + {OP_Column, 0, 0, 1}, /* 3 */ + {OP_ResultRow, 1, 0, 0}, /* 4 */ + {OP_Halt, 0, 0, 0}, /* 5 */ }; Vdbe *v = (Vdbe *)pBlob->pStmt; int iDb = sqlite3SchemaToIndex(db, pTab->pSchema); @@ -306,9 +310,9 @@ int sqlite3_blob_open( */ aOp[1].p4type = P4_INT32; aOp[1].p4.i = pTab->nCol+1; - aOp[4].p2 = pTab->nCol; + aOp[3].p2 = pTab->nCol; - pParse->nVar = 1; + pParse->nVar = 0; pParse->nMem = 1; pParse->nTab = 1; sqlite3VdbeMakeReady(v, pParse); From 508286701a5d2a8d893155c6cba1bf9b44cea0ca Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 20 Jan 2017 16:09:12 +0000 Subject: [PATCH 1214/1484] Get the "--testset rtree" option working on speedtest1. Add the --rtree, --lookaside, and --clang options to the speed-check.sh script. FossilOrigin-Name: 87b640c8d07a76b2bc7e896e01965cc09e06f77b --- main.mk | 2 +- manifest | 16 ++++++++-------- manifest.uuid | 2 +- test/speedtest1.c | 28 ++++++++++------------------ tool/speed-check.sh | 19 ++++++++++++++++--- 5 files changed, 36 insertions(+), 31 deletions(-) diff --git a/main.mk b/main.mk index e07b964d67..3b6e7f8609 100644 --- a/main.mk +++ b/main.mk @@ -893,7 +893,7 @@ wordcount$(EXE): $(TOP)/test/wordcount.c sqlite3.c $(TOP)/test/wordcount.c sqlite3.c speedtest1$(EXE): $(TOP)/test/speedtest1.c sqlite3.o - $(TCC) -I. $(OTAFLAGS) -o speedtest1$(EXE) $(TOP)/test/speedtest1.c sqlite3.o $(THREADLIB) + $(TCCX) -I. $(OTAFLAGS) -o speedtest1$(EXE) $(TOP)/test/speedtest1.c sqlite3.o $(THREADLIB) rbu$(EXE): $(TOP)/ext/rbu/rbu.c $(TOP)/ext/rbu/sqlite3rbu.c sqlite3.o $(TCC) -I. -o rbu$(EXE) $(TOP)/ext/rbu/rbu.c sqlite3.o \ diff --git a/manifest b/manifest index c04cd81412..b018d640fc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Minor\sperformance\soptimizations\sto\ssqlite3_blob_open()\sand\nsqlite3_blob_reopen(). -D 2017-01-20T00:40:26.827 +C Get\sthe\s"--testset\srtree"\soption\sworking\son\sspeedtest1.\s\sAdd\sthe\s--rtree,\n--lookaside,\sand\s--clang\soptions\sto\sthe\sspeed-check.sh\sscript. +D 2017-01-20T16:09:12.221 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -314,7 +314,7 @@ F ext/userauth/userauth.c 5fa3bdb492f481bbc1709fc83c91ebd13460c69e F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60 -F main.mk 2cf5f0362c5687fd8e912c3a327b49a2e8ba0f9b +F main.mk 8f620f3418d7252a3f428f5aacf674b5507807a8 F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 @@ -1131,7 +1131,7 @@ F test/speed3.test 694affeb9100526007436334cf7d08f3d74b85ef F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715 F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b -F test/speedtest1.c 4e8ea6165046f02e1cfe0f4700256e91c981ec10 +F test/speedtest1.c 02fe15bb784c5276a083ffe9969cc51e0bce7644 F test/spellfix.test f9c1f431e2c096c8775fec032952320c0e4700db F test/spellfix2.test dfc8f519a3fc204cb2dfa8b4f29821ae90f6f8c3 F test/spellfix3.test 0f9efaaa502a0e0a09848028518a6fb096c8ad33 @@ -1507,7 +1507,7 @@ F tool/showstat4.c b14159aa062f661b394ba37b6b7b94bfb8012ab9 F tool/showwal.c ec79959834f7b21f1e0a2aa52bb7c056d2203977 F tool/soak1.tcl 8d407956e1a45b485a8e072470a3e629a27037fe F tool/spaceanal.tcl ab7d9bf68062907282a64b3e12ccbfad47193c5a -F tool/speed-check.sh e6ca0695b047af64201ebe0ef452e423f55d78b1 +F tool/speed-check.sh 65ac2f5b00771b9dcefb95bebae1aab76c537ea3 F tool/speedtest.tcl 06c76698485ccf597b9e7dbb1ac70706eb873355 F tool/speedtest16.c ecb6542862151c3e6509bbc00509b234562ae81e F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff @@ -1547,7 +1547,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 9ed38521617136223a667988aed40e25797faf84 -R b4a609734c03fe3500908ef05ac99d6b +P 52a61967d920047ea0b4409b79793e05c0128964 +R 4e64e669335e5bcf79eed63ea8c1840b U drh -Z 622609d2384fcdd28fbe219ab3e3b191 +Z 6f7214599f293ddc9e6d41b975d33fdf diff --git a/manifest.uuid b/manifest.uuid index 14542d0a86..55a46f0885 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -52a61967d920047ea0b4409b79793e05c0128964 \ No newline at end of file +87b640c8d07a76b2bc7e896e01965cc09e06f77b \ No newline at end of file diff --git a/test/speedtest1.c b/test/speedtest1.c index 02d55d5974..f5b79915c8 100644 --- a/test/speedtest1.c +++ b/test/speedtest1.c @@ -61,9 +61,6 @@ static const char zHelp[] = #if SQLITE_VERSION_NUMBER<3005000 # define sqlite3_int64 sqlite_int64 #endif -#ifdef SQLITE_ENABLE_RBU -# include "sqlite3rbu.h" -#endif /* All global state is held in this structure */ static struct Global { @@ -1181,10 +1178,10 @@ void testset_rtree(int p1, int p2){ unsigned mxCoord; unsigned x0, x1, y0, y1, z0, z1; unsigned iStep; - int *aCheck = sqlite3_malloc( sizeof(int)*g.szTest*100 ); + int *aCheck = sqlite3_malloc( sizeof(int)*g.szTest*500 ); mxCoord = 15000; - n = g.szTest*100; + n = g.szTest*500; speedtest1_begin_test(100, "%d INSERTs into an r-tree", n); speedtest1_exec("BEGIN"); speedtest1_exec("CREATE VIRTUAL TABLE rt1 USING rtree(id,x0,x1,y0,y1,z0,z1)"); @@ -1207,11 +1204,11 @@ void testset_rtree(int p1, int p2){ speedtest1_end_test(); speedtest1_begin_test(101, "Copy from rtree to a regular table"); - speedtest1_exec(" TABLE t1(id INTEGER PRIMARY KEY,x0,x1,y0,y1,z0,z1)"); + speedtest1_exec("CREATE TABLE t1(id INTEGER PRIMARY KEY,x0,x1,y0,y1,z0,z1)"); speedtest1_exec("INSERT INTO t1 SELECT * FROM rt1"); speedtest1_end_test(); - n = g.szTest*20; + n = g.szTest*100; speedtest1_begin_test(110, "%d one-dimensional intersect slice queries", n); speedtest1_prepare("SELECT count(*) FROM rt1 WHERE x0>=?1 AND x1<=?2"); iStep = mxCoord/n; @@ -1224,7 +1221,7 @@ void testset_rtree(int p1, int p2){ speedtest1_end_test(); if( g.bVerify ){ - n = g.szTest*20; + n = g.szTest*100; speedtest1_begin_test(111, "Verify result from 1-D intersect slice queries"); speedtest1_prepare("SELECT count(*) FROM t1 WHERE x0>=?1 AND x1<=?2"); iStep = mxCoord/n; @@ -1240,7 +1237,7 @@ void testset_rtree(int p1, int p2){ speedtest1_end_test(); } - n = g.szTest*20; + n = g.szTest*100; speedtest1_begin_test(120, "%d one-dimensional overlap slice queries", n); speedtest1_prepare("SELECT count(*) FROM rt1 WHERE y1>=?1 AND y0<=?2"); iStep = mxCoord/n; @@ -1253,7 +1250,7 @@ void testset_rtree(int p1, int p2){ speedtest1_end_test(); if( g.bVerify ){ - n = g.szTest*20; + n = g.szTest*100; speedtest1_begin_test(121, "Verify result from 1-D overlap slice queries"); speedtest1_prepare("SELECT count(*) FROM t1 WHERE y1>=?1 AND y0<=?2"); iStep = mxCoord/n; @@ -1270,7 +1267,7 @@ void testset_rtree(int p1, int p2){ } - n = g.szTest*20; + n = g.szTest*100; speedtest1_begin_test(125, "%d custom geometry callback queries", n); sqlite3_rtree_geometry_callback(g.db, "xslice", xsliceGeometryCallback, 0); speedtest1_prepare("SELECT count(*) FROM rt1 WHERE id MATCH xslice(?1,?2)"); @@ -1286,7 +1283,7 @@ void testset_rtree(int p1, int p2){ } speedtest1_end_test(); - n = g.szTest*80; + n = g.szTest*400; speedtest1_begin_test(130, "%d three-dimensional intersect box queries", n); speedtest1_prepare("SELECT count(*) FROM rt1 WHERE x1>=?1 AND x0<=?2" " AND y1>=?1 AND y0<=?2 AND z1>=?1 AND z0<=?2"); @@ -1299,7 +1296,7 @@ void testset_rtree(int p1, int p2){ } speedtest1_end_test(); - n = g.szTest*100; + n = g.szTest*500; speedtest1_begin_test(140, "%d rowid queries", n); speedtest1_prepare("SELECT * FROM rt1 WHERE id=?1"); for(i=1; i<=n; i++){ @@ -1458,11 +1455,6 @@ int main(int argc, char **argv){ noSync = 1; }else if( strcmp(z,"notnull")==0 ){ g.zNN = "NOT NULL"; -#ifdef SQLITE_ENABLE_RBU - }else if( strcmp(z,"rbu")==0 ){ - sqlite3ota_create_vfs("rbu", 0); - sqlite3_vfs_register(sqlite3_vfs_find("rbu"), 1); -#endif }else if( strcmp(z,"pagesize")==0 ){ if( i>=argc-1 ) fatal_error("missing argument on %s\n", argv[i]); pageSize = integerValue(argv[++i]); diff --git a/tool/speed-check.sh b/tool/speed-check.sh index d6e7eb6d25..c6f587e177 100644 --- a/tool/speed-check.sh +++ b/tool/speed-check.sh @@ -23,6 +23,7 @@ NAME=$1 shift #CC_OPTS="-DSQLITE_ENABLE_RTREE -DSQLITE_ENABLE_MEMSYS5" CC_OPTS="-DSQLITE_ENABLE_MEMSYS5" +CC=gcc SPEEDTEST_OPTS="--shrink-memory --reprepare --stats --heap 10000000 64" SIZE=5 LEAN_OPTS="-DSQLITE_THREADSAFE=0" @@ -80,11 +81,19 @@ while test "$1" != ""; do --lean) CC_OPTS="$CC_OPTS $LEAN_OPTS" ;; + --clang) + CC=clang + ;; --heap) CC_OPTS="$CC_OPTS -DSQLITE_ENABLE_MEMSYS5" shift; SPEEDTEST_OPTS="$SPEEDTEST_OPTS --heap $1 64" ;; + --lookaside) + shift; + SPEEDTEST_OPTS="$SPEEDTEST_OPTS --lookaside $1 $2" + shift; + ;; --repeat) CC_OPTS="$CC_OPTS -DSQLITE_ENABLE_RCACHE" shift; @@ -94,6 +103,10 @@ while test "$1" != ""; do shift; SPEEDTEST_OPTS="$SPEEDTEST_OPTS --mmap $1" ;; + --rtree) + SPEEDTEST_OPTS="$SPEEDTEST_OPTS --testset rtree" + CC_OPTS="$CC_OPTS -DSQLITE_ENABLE_RTREE" + ;; *) CC_OPTS="$CC_OPTS $1" ;; @@ -105,15 +118,15 @@ echo "NAME = $NAME" | tee summary-$NAME.txt echo "SPEEDTEST_OPTS = $SPEEDTEST_OPTS" | tee -a summary-$NAME.txt echo "CC_OPTS = $CC_OPTS" | tee -a summary-$NAME.txt rm -f cachegrind.out.* speedtest1 speedtest1.db sqlite3.o -gcc -g -Os -Wall -I. $CC_OPTS -c sqlite3.c +$CC -g -Os -Wall -I. $CC_OPTS -c sqlite3.c size sqlite3.o | tee -a summary-$NAME.txt if test $doExplain -eq 1; then - gcc -g -Os -Wall -I. $CC_OPTS \ + $CC -g -Os -Wall -I. $CC_OPTS \ -DSQLITE_ENABLE_EXPLAIN_COMMENTS \ ./shell.c ./sqlite3.c -o sqlite3 -ldl -lpthread fi SRC=./speedtest1.c -gcc -g -Os -Wall -I. $CC_OPTS $SRC ./sqlite3.o -o speedtest1 -ldl -lpthread +$CC -g -Os -Wall -I. $CC_OPTS $SRC ./sqlite3.o -o speedtest1 -ldl -lpthread ls -l speedtest1 | tee -a summary-$NAME.txt if test $doCachegrind -eq 1; then valgrind --tool=cachegrind ./speedtest1 speedtest1.db \ From befcd8ad84f843cf384d754a8fd203b1945acb59 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 20 Jan 2017 16:46:20 +0000 Subject: [PATCH 1215/1484] Add option "--stats" to test program kvtest. Specifying --stats causes kvtest to output information similar to the shell tool option of the same name. FossilOrigin-Name: 90291327fc127671d9847a4a2ce1ed47a408cfc6 --- manifest | 14 +++--- manifest.uuid | 2 +- test/kvtest.c | 125 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 133 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index b018d640fc..882b5a775a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Get\sthe\s"--testset\srtree"\soption\sworking\son\sspeedtest1.\s\sAdd\sthe\s--rtree,\n--lookaside,\sand\s--clang\soptions\sto\sthe\sspeed-check.sh\sscript. -D 2017-01-20T16:09:12.221 +C Add\soption\s"--stats"\sto\stest\sprogram\skvtest.\sSpecifying\s--stats\scauses\skvtest\nto\soutput\sinformation\ssimilar\sto\sthe\sshell\stool\soption\sof\sthe\ssame\sname. +D 2017-01-20T16:46:20.421 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -898,7 +898,7 @@ F test/json101.test c0897616f32d95431f37fd291cb78742181980ac F test/json102.test bf3fe7a706d30936a76a0f7a0375e1e8e73aff5a F test/json103.test c5f6b85e69de05f6b3195f9f9d5ce9cd179099a0 F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff -F test/kvtest.c 2c66ddefcd03c2caa337f6dd79e6c82368af83df +F test/kvtest.c da3fddb003221d3d9726afd959d9c6017516fd02 F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63 F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200 F test/like.test 0603f4fa0dad50987f70032c05800cbfa8985302 @@ -1547,7 +1547,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 52a61967d920047ea0b4409b79793e05c0128964 -R 4e64e669335e5bcf79eed63ea8c1840b -U drh -Z 6f7214599f293ddc9e6d41b975d33fdf +P 87b640c8d07a76b2bc7e896e01965cc09e06f77b +R b9affb78955ec88bf34da37dcc1dd9ef +U dan +Z 3096b993434f8157eb2ffff3d1e5a264 diff --git a/manifest.uuid b/manifest.uuid index 55a46f0885..f7dbcbe1e3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -87b640c8d07a76b2bc7e896e01965cc09e06f77b \ No newline at end of file +90291327fc127671d9847a4a2ce1ed47a408cfc6 \ No newline at end of file diff --git a/test/kvtest.c b/test/kvtest.c index 877605aced..8458ef919c 100644 --- a/test/kvtest.c +++ b/test/kvtest.c @@ -87,6 +87,7 @@ static const char zHelp[] = " --max-id N Maximum blob key to use\n" " --random Read blobs in a random order\n" " --start N Start reading with this blob key\n" +" --stats Output operating stats before exiting\n" ; /* Reference resources used */ @@ -369,6 +370,122 @@ static sqlite3_int64 timeOfDay(void){ return t; } +#ifdef __linux__ +/* +** Attempt to display I/O stats on Linux using /proc/PID/io +*/ +static void displayLinuxIoStats(FILE *out){ + FILE *in; + char z[200]; + sqlite3_snprintf(sizeof(z), z, "/proc/%d/io", getpid()); + in = fopen(z, "rb"); + if( in==0 ) return; + while( fgets(z, sizeof(z), in)!=0 ){ + static const struct { + const char *zPattern; + const char *zDesc; + } aTrans[] = { + { "rchar: ", "Bytes received by read():" }, + { "wchar: ", "Bytes sent to write():" }, + { "syscr: ", "Read() system calls:" }, + { "syscw: ", "Write() system calls:" }, + { "read_bytes: ", "Bytes read from storage:" }, + { "write_bytes: ", "Bytes written to storage:" }, + { "cancelled_write_bytes: ", "Cancelled write bytes:" }, + }; + int i; + for(i=0; i Date: Fri, 20 Jan 2017 16:47:34 +0000 Subject: [PATCH 1216/1484] Fix a typo in the help message for kvtest. FossilOrigin-Name: 8971d98f25a4f5fb060db8ed6a4b06f083122a50 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/kvtest.c | 8 ++++---- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 882b5a775a..5ca437cb49 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\soption\s"--stats"\sto\stest\sprogram\skvtest.\sSpecifying\s--stats\scauses\skvtest\nto\soutput\sinformation\ssimilar\sto\sthe\sshell\stool\soption\sof\sthe\ssame\sname. -D 2017-01-20T16:46:20.421 +C Fix\sa\stypo\sin\sthe\shelp\smessage\sfor\skvtest. +D 2017-01-20T16:47:34.130 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -898,7 +898,7 @@ F test/json101.test c0897616f32d95431f37fd291cb78742181980ac F test/json102.test bf3fe7a706d30936a76a0f7a0375e1e8e73aff5a F test/json103.test c5f6b85e69de05f6b3195f9f9d5ce9cd179099a0 F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff -F test/kvtest.c da3fddb003221d3d9726afd959d9c6017516fd02 +F test/kvtest.c 371a2a0cb05840ed4a31c65c1d12a554c2fe556b F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63 F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200 F test/like.test 0603f4fa0dad50987f70032c05800cbfa8985302 @@ -1547,7 +1547,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 87b640c8d07a76b2bc7e896e01965cc09e06f77b -R b9affb78955ec88bf34da37dcc1dd9ef +P 90291327fc127671d9847a4a2ce1ed47a408cfc6 +R a902108b38beec2205eaeba771709e26 U dan -Z 3096b993434f8157eb2ffff3d1e5a264 +Z 09bc78c7c0c7ebb44e280cf03b306ae8 diff --git a/manifest.uuid b/manifest.uuid index f7dbcbe1e3..4b97c1dc13 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -90291327fc127671d9847a4a2ce1ed47a408cfc6 \ No newline at end of file +8971d98f25a4f5fb060db8ed6a4b06f083122a50 \ No newline at end of file diff --git a/test/kvtest.c b/test/kvtest.c index 8458ef919c..2e997287e8 100644 --- a/test/kvtest.c +++ b/test/kvtest.c @@ -61,20 +61,20 @@ ** ./kvtest run x1 --count 10000 --max-id 1000000 */ static const char zHelp[] = -"Usage: kvhelp COMMAND ARGS...\n" +"Usage: kvtest COMMAND ARGS...\n" "\n" -" kvhelp init DBFILE --count N --size M --pagesize X\n" +" kvtest init DBFILE --count N --size M --pagesize X\n" "\n" " Generate a new test database file named DBFILE containing N\n" " BLOBs each of size M bytes. The page size of the new database\n" " file will be X\n" "\n" -" kvhelp export DBFILE DIRECTORY\n" +" kvtest export DBFILE DIRECTORY\n" "\n" " Export all the blobs in the kv table of DBFILE into separate\n" " files in DIRECTORY.\n" "\n" -" kvhelp run DBFILE [options]\n" +" kvtest run DBFILE [options]\n" "\n" " Run a performance test. DBFILE can be either the name of a\n" " database or a directory containing sample files. Options:\n" From cd645530157e1e754cf0fa37c3815a2253d01124 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 20 Jan 2017 20:43:14 +0000 Subject: [PATCH 1217/1484] Minor performance optimization and size reduction to the accessPayload() routine in btree.c. FossilOrigin-Name: 264e5c10d7144910b3223b64546567fa20e4bc65 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/btree.c | 15 ++++++++------- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index 5ca437cb49..9780aa2959 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\stypo\sin\sthe\shelp\smessage\sfor\skvtest. -D 2017-01-20T16:47:34.130 +C Minor\sperformance\soptimization\sand\ssize\sreduction\sto\sthe\saccessPayload()\nroutine\sin\sbtree.c. +D 2017-01-20T20:43:14.971 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -333,7 +333,7 @@ F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792 F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca -F src/btree.c 69966fb2c574954cd3216f09407c9a02c52d3bd7 +F src/btree.c e6b8f39d7dd1ad65f1747956de36f2595172a23d F src/btree.h e6d352808956ec163a17f832193a3e198b3fb0ac F src/btreeInt.h 10c4b77c2fb399580babbcc7cf652ac10dba796e F src/build.c 9e799f1edd910dfa8a0bc29bd390d35d310596af @@ -1547,7 +1547,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 90291327fc127671d9847a4a2ce1ed47a408cfc6 -R a902108b38beec2205eaeba771709e26 -U dan -Z 09bc78c7c0c7ebb44e280cf03b306ae8 +P 8971d98f25a4f5fb060db8ed6a4b06f083122a50 +R 6803846831f043d39b9c85f99ff10309 +U drh +Z 62cd4db9c45f8ac36491823fd1143808 diff --git a/manifest.uuid b/manifest.uuid index 4b97c1dc13..6d1f724a7b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8971d98f25a4f5fb060db8ed6a4b06f083122a50 \ No newline at end of file +264e5c10d7144910b3223b64546567fa20e4bc65 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 7b56867646..fb05655912 100644 --- a/src/btree.c +++ b/src/btree.c @@ -4523,16 +4523,14 @@ static int accessPayload( pCur->aOverflow, nOvfl*2*sizeof(Pgno) ); if( aNew==0 ){ - rc = SQLITE_NOMEM_BKPT; + return SQLITE_NOMEM_BKPT; }else{ pCur->nOvflAlloc = nOvfl*2; pCur->aOverflow = aNew; } } - if( rc==SQLITE_OK ){ - memset(pCur->aOverflow, 0, nOvfl*sizeof(Pgno)); - pCur->curFlags |= BTCF_ValidOvfl; - } + memset(pCur->aOverflow, 0, nOvfl*sizeof(Pgno)); + pCur->curFlags |= BTCF_ValidOvfl; } /* If the overflow page-list cache has been allocated and the @@ -4547,8 +4545,8 @@ static int accessPayload( offset = (offset%ovflSize); } - for( ; rc==SQLITE_OK && amt>0 && nextPage; iIdx++){ - + assert( rc==SQLITE_OK && amt>0 ); + while( nextPage ){ /* If required, populate the overflow page-list cache. */ if( (pCur->curFlags & BTCF_ValidOvfl)!=0 ){ assert( pCur->aOverflow[iIdx]==0 @@ -4637,6 +4635,9 @@ static int accessPayload( amt -= a; pBuf += a; } + if( amt==0 ) break; + if( rc ) break; + iIdx++; } } From 36cae856eef6769c83da403bd73247c12474142f Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 21 Jan 2017 14:11:28 +0000 Subject: [PATCH 1218/1484] Remove an unnecessary sqlite3_bind_int64() call from sqlite3_blob_open(). Also other minor refactoring of the sqlite3_blob implementation. FossilOrigin-Name: 9d197a532349f4b1caf66bbed70ca46df86cb86f --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbeblob.c | 22 ++++++++++------------ 3 files changed, 17 insertions(+), 19 deletions(-) diff --git a/manifest b/manifest index 9780aa2959..f0f41d4642 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Minor\sperformance\soptimization\sand\ssize\sreduction\sto\sthe\saccessPayload()\nroutine\sin\sbtree.c. -D 2017-01-20T20:43:14.971 +C Remove\san\sunnecessary\ssqlite3_bind_int64()\scall\sfrom\ssqlite3_blob_open().\nAlso\sother\sminor\srefactoring\sof\sthe\ssqlite3_blob\simplementation. +D 2017-01-21T14:11:28.343 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -462,7 +462,7 @@ F src/vdbe.h b0866e4191f096f1c987a84b042c3599bdf5423b F src/vdbeInt.h 281cb70332dc8b593b8c7afe776f3a2ba7d4255e F src/vdbeapi.c d6ebaa465f070eb1af8ba4e7b34583ece87bdd24 F src/vdbeaux.c 35c9a9908174e5a26c96d15e1f98214814a39147 -F src/vdbeblob.c fe3694fcc3cf2cad395416f5289bd0e935c2659d +F src/vdbeblob.c 824f360105b8cd43c2ec8c4611fd3b162a3a3eed F src/vdbemem.c 3b5a9a5b375458d3e12a50ae1aaa41eeec2175fd F src/vdbesort.c eda25cb2d1727efca6f7862fea32b8aa33c0face F src/vdbetrace.c 41963d5376f0349842b5fc4aaaaacd7d9cdc0834 @@ -1547,7 +1547,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 8971d98f25a4f5fb060db8ed6a4b06f083122a50 -R 6803846831f043d39b9c85f99ff10309 +P 264e5c10d7144910b3223b64546567fa20e4bc65 +R 8ac11845f3680b4a63ed584c4ec0c997 U drh -Z 62cd4db9c45f8ac36491823fd1143808 +Z e8ceb26091bad5772496cc1502eaca7e diff --git a/manifest.uuid b/manifest.uuid index 6d1f724a7b..ca6ba2e6ad 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -264e5c10d7144910b3223b64546567fa20e4bc65 \ No newline at end of file +9d197a532349f4b1caf66bbed70ca46df86cb86f \ No newline at end of file diff --git a/src/vdbeblob.c b/src/vdbeblob.c index b2902ba321..70a68b4015 100644 --- a/src/vdbeblob.c +++ b/src/vdbeblob.c @@ -23,10 +23,10 @@ */ typedef struct Incrblob Incrblob; struct Incrblob { - int flags; /* Copy of "flags" passed to sqlite3_blob_open() */ int nByte; /* Size of open blob, in bytes */ int iOffset; /* Byte offset of blob in cursor data */ - int iCol; /* Table column this handle is open on */ + u16 iCol; /* Table column this handle is open on */ + u8 isPureKV; /* True if pTab is a pure key/value table */ BtCursor *pCsr; /* Cursor pointing at blob row */ sqlite3_stmt *pStmt; /* Statement holding cursor open */ sqlite3 *db; /* The associated database */ @@ -117,7 +117,7 @@ int sqlite3_blob_open( const char *zTable, /* The table containing the blob */ const char *zColumn, /* The column containing the blob */ sqlite_int64 iRow, /* The row containing the glob */ - int flags, /* True -> read/write access, false -> read-only */ + int wrFlag, /* True -> read/write access, false -> read-only */ sqlite3_blob **ppBlob /* Handle for accessing the blob returned here */ ){ int nAttempt = 0; @@ -139,7 +139,7 @@ int sqlite3_blob_open( return SQLITE_MISUSE_BKPT; } #endif - flags = !!flags; /* flags = (flags ? 1 : 0); */ + wrFlag = !!wrFlag; /* wrFlag = (wrFlag ? 1 : 0); */ sqlite3_mutex_enter(db->mutex); @@ -199,9 +199,8 @@ int sqlite3_blob_open( /* If the value is being opened for writing, check that the ** column is not indexed, and that it is not part of a foreign key. - ** It is against the rules to open a column to which either of these - ** descriptions applies for writing. */ - if( flags ){ + */ + if( wrFlag ){ const char *zFault = 0; Index *pIdx; #ifndef SQLITE_OMIT_FOREIGN_KEY @@ -272,7 +271,7 @@ int sqlite3_blob_open( int iDb = sqlite3SchemaToIndex(db, pTab->pSchema); VdbeOp *aOp; - sqlite3VdbeAddOp4Int(v, OP_Transaction, iDb, flags, + sqlite3VdbeAddOp4Int(v, OP_Transaction, iDb, wrFlag, pTab->pSchema->schema_cookie, pTab->pSchema->iGeneration); sqlite3VdbeChangeP5(v, 1); @@ -289,7 +288,7 @@ int sqlite3_blob_open( #else aOp[0].p1 = iDb; aOp[0].p2 = pTab->tnum; - aOp[0].p3 = flags; + aOp[0].p3 = wrFlag; sqlite3VdbeChangeP4(v, 1, pTab->zName, P4_TRANSIENT); } if( db->mallocFailed==0 ){ @@ -297,7 +296,7 @@ int sqlite3_blob_open( /* Remove either the OP_OpenWrite or OpenRead. Set the P2 ** parameter of the other to pTab->tnum. */ - if( flags ) aOp[1].opcode = OP_OpenWrite; + if( wrFlag ) aOp[1].opcode = OP_OpenWrite; aOp[1].p2 = pTab->tnum; aOp[1].p3 = iDb; @@ -319,14 +318,13 @@ int sqlite3_blob_open( } } - pBlob->flags = flags; + pBlob->isPureKV = (pTab->nCol==2 && pTab->iPKey==0); pBlob->iCol = iCol; pBlob->db = db; sqlite3BtreeLeaveAll(db); if( db->mallocFailed ){ goto blob_open_out; } - sqlite3_bind_int64(pBlob->pStmt, 1, iRow); rc = blobSeekToRow(pBlob, iRow, &zErr); } while( (++nAttempt) Date: Sat, 21 Jan 2017 15:55:41 +0000 Subject: [PATCH 1219/1484] In the kvtest.c test utility, reuse the buffer into which blobs are read, rather than reallocating it for each row. This is a closer match to how other test programs work, and thus provides a better comparison. FossilOrigin-Name: 0d1ad13a296b22d6fe36879b56f99bd6af1acd3a --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/kvtest.c | 8 ++++++-- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index f0f41d4642..17270cb285 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\san\sunnecessary\ssqlite3_bind_int64()\scall\sfrom\ssqlite3_blob_open().\nAlso\sother\sminor\srefactoring\sof\sthe\ssqlite3_blob\simplementation. -D 2017-01-21T14:11:28.343 +C In\sthe\skvtest.c\stest\sutility,\sreuse\sthe\sbuffer\sinto\swhich\sblobs\sare\sread,\nrather\sthan\sreallocating\sit\sfor\seach\srow.\s\sThis\sis\sa\scloser\smatch\sto\show\nother\stest\sprograms\swork,\sand\sthus\sprovides\sa\sbetter\scomparison. +D 2017-01-21T15:55:41.656 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -898,7 +898,7 @@ F test/json101.test c0897616f32d95431f37fd291cb78742181980ac F test/json102.test bf3fe7a706d30936a76a0f7a0375e1e8e73aff5a F test/json103.test c5f6b85e69de05f6b3195f9f9d5ce9cd179099a0 F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff -F test/kvtest.c 371a2a0cb05840ed4a31c65c1d12a554c2fe556b +F test/kvtest.c 9e428931f0733b5ba65b6b5abd95b27320e875a3 F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63 F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200 F test/like.test 0603f4fa0dad50987f70032c05800cbfa8985302 @@ -1547,7 +1547,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 264e5c10d7144910b3223b64546567fa20e4bc65 -R 8ac11845f3680b4a63ed584c4ec0c997 +P 9d197a532349f4b1caf66bbed70ca46df86cb86f +R 2ba22a751baba0a74113cf71f6292807 U drh -Z e8ceb26091bad5772496cc1502eaca7e +Z 28f64e9f53e7fb024862aee0e897381f diff --git a/manifest.uuid b/manifest.uuid index ca6ba2e6ad..1b9ab055af 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9d197a532349f4b1caf66bbed70ca46df86cb86f \ No newline at end of file +0d1ad13a296b22d6fe36879b56f99bd6af1acd3a \ No newline at end of file diff --git a/test/kvtest.c b/test/kvtest.c index 2e997287e8..d895af030f 100644 --- a/test/kvtest.c +++ b/test/kvtest.c @@ -516,6 +516,7 @@ static int runMain(int argc, char **argv){ int nData = 0; /* Bytes of data */ sqlite3_int64 nTotal = 0; /* Total data read */ unsigned char *pData; /* Content of the blob */ + int nAlloc = 0; /* Space allocated for pData[] */ assert( strcmp(argv[1],"run")==0 ); @@ -621,14 +622,16 @@ static int runMain(int argc, char **argv){ } if( rc==SQLITE_OK ){ nData = sqlite3_blob_bytes(pBlob); - pData = sqlite3_malloc( nData+1 ); + if( nAlloc Date: Sat, 21 Jan 2017 16:27:56 +0000 Subject: [PATCH 1220/1484] Change sqlite3_blob_reopen() to call sqlite3VdbeExec() directly rather than going through sqlite3_step(). Performance enhancement. FossilOrigin-Name: 347df3c1fd7322e7aacaf1e9f8be81830947c482 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbeblob.c | 14 +++++++++----- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 17270cb285..334c7a3604 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\sthe\skvtest.c\stest\sutility,\sreuse\sthe\sbuffer\sinto\swhich\sblobs\sare\sread,\nrather\sthan\sreallocating\sit\sfor\seach\srow.\s\sThis\sis\sa\scloser\smatch\sto\show\nother\stest\sprograms\swork,\sand\sthus\sprovides\sa\sbetter\scomparison. -D 2017-01-21T15:55:41.656 +C Change\ssqlite3_blob_reopen()\sto\scall\ssqlite3VdbeExec()\sdirectly\srather\sthan\ngoing\sthrough\ssqlite3_step().\s\sPerformance\senhancement. +D 2017-01-21T16:27:56.517 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -462,7 +462,7 @@ F src/vdbe.h b0866e4191f096f1c987a84b042c3599bdf5423b F src/vdbeInt.h 281cb70332dc8b593b8c7afe776f3a2ba7d4255e F src/vdbeapi.c d6ebaa465f070eb1af8ba4e7b34583ece87bdd24 F src/vdbeaux.c 35c9a9908174e5a26c96d15e1f98214814a39147 -F src/vdbeblob.c 824f360105b8cd43c2ec8c4611fd3b162a3a3eed +F src/vdbeblob.c 2159f36d2c3e7ed24e3ebe99a9a4b462248c0665 F src/vdbemem.c 3b5a9a5b375458d3e12a50ae1aaa41eeec2175fd F src/vdbesort.c eda25cb2d1727efca6f7862fea32b8aa33c0face F src/vdbetrace.c 41963d5376f0349842b5fc4aaaaacd7d9cdc0834 @@ -1547,7 +1547,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 9d197a532349f4b1caf66bbed70ca46df86cb86f -R 2ba22a751baba0a74113cf71f6292807 +P 0d1ad13a296b22d6fe36879b56f99bd6af1acd3a +R 6bebf342d641742884692400aca75850 U drh -Z 28f64e9f53e7fb024862aee0e897381f +Z fb104ae24cf906c93b7fa008d273f235 diff --git a/manifest.uuid b/manifest.uuid index 1b9ab055af..56e58c0ea3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0d1ad13a296b22d6fe36879b56f99bd6af1acd3a \ No newline at end of file +347df3c1fd7322e7aacaf1e9f8be81830947c482 \ No newline at end of file diff --git a/src/vdbeblob.c b/src/vdbeblob.c index 70a68b4015..1efd4c9243 100644 --- a/src/vdbeblob.c +++ b/src/vdbeblob.c @@ -26,7 +26,6 @@ struct Incrblob { int nByte; /* Size of open blob, in bytes */ int iOffset; /* Byte offset of blob in cursor data */ u16 iCol; /* Table column this handle is open on */ - u8 isPureKV; /* True if pTab is a pure key/value table */ BtCursor *pCsr; /* Cursor pointing at blob row */ sqlite3_stmt *pStmt; /* Statement holding cursor open */ sqlite3 *db; /* The associated database */ @@ -56,6 +55,7 @@ static int blobSeekToRow(Incrblob *p, sqlite3_int64 iRow, char **pzErr){ int rc; /* Error code */ char *zErr = 0; /* Error message */ Vdbe *v = (Vdbe *)p->pStmt; + sqlite3 *db = v->db; /* Set the value of register r[1] in the SQL statement to integer iRow. ** This is done directly as a performance optimization @@ -67,9 +67,14 @@ static int blobSeekToRow(Incrblob *p, sqlite3_int64 iRow, char **pzErr){ ** then back it up to the point where it does the OP_SeekRowid. This could ** have been down with an extra OP_Goto, but simply setting the program ** counter is faster. */ - if( v->pc>3 ) v->pc = 3; - - rc = sqlite3_step(p->pStmt); + if( v->pc>3 ){ + v->pc = 3; + db->nVdbeExec++; + rc = sqlite3VdbeExec((Vdbe*)p->pStmt); + db->nVdbeExec--; + }else{ + rc = sqlite3_step(p->pStmt); + } if( rc==SQLITE_ROW ){ VdbeCursor *pC = v->apCsr[0]; u32 type = pC->aType[p->iCol]; @@ -318,7 +323,6 @@ int sqlite3_blob_open( } } - pBlob->isPureKV = (pTab->nCol==2 && pTab->iPKey==0); pBlob->iCol = iCol; pBlob->db = db; sqlite3BtreeLeaveAll(db); From 451e76d5b594d48d3450057ac542c7635b74b021 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 21 Jan 2017 16:54:19 +0000 Subject: [PATCH 1221/1484] B-tree optimization: When seeking on a rowid table that has already been positioned, check to see if the new row happens to be the next row on the same leaf page. That is a reasonably common case, and if it is true it avoids a full binary search. FossilOrigin-Name: 8e5cfb2039126da7689c4b1c88760f10e1234eaf --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btree.c | 18 +++++++++++++++--- 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 334c7a3604..cbd159d22a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\ssqlite3_blob_reopen()\sto\scall\ssqlite3VdbeExec()\sdirectly\srather\sthan\ngoing\sthrough\ssqlite3_step().\s\sPerformance\senhancement. -D 2017-01-21T16:27:56.517 +C B-tree\soptimization:\s\sWhen\sseeking\son\sa\srowid\stable\sthat\shas\salready\sbeen\npositioned,\scheck\sto\ssee\sif\sthe\snew\srow\shappens\sto\sbe\sthe\snext\srow\son\sthe\nsame\sleaf\spage.\s\sThat\sis\sa\sreasonably\scommon\scase,\sand\sif\sit\sis\strue\sit\navoids\sa\sfull\sbinary\ssearch. +D 2017-01-21T16:54:19.338 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -333,7 +333,7 @@ F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792 F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca -F src/btree.c e6b8f39d7dd1ad65f1747956de36f2595172a23d +F src/btree.c 972b7e1346eb2f4369cf8cc43117c728e2bd9cd4 F src/btree.h e6d352808956ec163a17f832193a3e198b3fb0ac F src/btreeInt.h 10c4b77c2fb399580babbcc7cf652ac10dba796e F src/build.c 9e799f1edd910dfa8a0bc29bd390d35d310596af @@ -1547,7 +1547,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 0d1ad13a296b22d6fe36879b56f99bd6af1acd3a -R 6bebf342d641742884692400aca75850 +P 347df3c1fd7322e7aacaf1e9f8be81830947c482 +R 3888200d85fb0a6e771ec0a3c9f2e5a8 U drh -Z fb104ae24cf906c93b7fa008d273f235 +Z 4b0826cf6fb92296cc5aa9f45d953141 diff --git a/manifest.uuid b/manifest.uuid index 56e58c0ea3..ac357ef297 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -347df3c1fd7322e7aacaf1e9f8be81830947c482 \ No newline at end of file +8e5cfb2039126da7689c4b1c88760f10e1234eaf \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index fb05655912..8b095b57b0 100644 --- a/src/btree.c +++ b/src/btree.c @@ -5091,9 +5091,21 @@ int sqlite3BtreeMovetoUnpacked( *pRes = 0; return SQLITE_OK; } - if( (pCur->curFlags & BTCF_AtLast)!=0 && pCur->info.nKeyinfo.nKeycurFlags & BTCF_AtLast)!=0 ){ + *pRes = -1; + return SQLITE_OK; + } + if( pCur->aiIdx[pCur->iPage]+1apPage[pCur->iPage]->nCell ){ + pCur->aiIdx[pCur->iPage]++; + pCur->info.nSize = 0; + pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl); + getCellInfo(pCur); + if( pCur->info.nKey==intKey ){ + *pRes = 0; + return SQLITE_OK; + } + } } } From 7f11afaba17fdc24ef01775613e4052a4100bbcf Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 21 Jan 2017 21:47:54 +0000 Subject: [PATCH 1222/1484] A better implementation of the moveto-neighbor optimization that checks for nearby rows on adjacent pages. FossilOrigin-Name: 2c4ecb85a475b9063aa8a3bb517ac181a7ded649 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btree.c | 21 +++++++++++++-------- 3 files changed, 20 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index cbd159d22a..95352ee96a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C B-tree\soptimization:\s\sWhen\sseeking\son\sa\srowid\stable\sthat\shas\salready\sbeen\npositioned,\scheck\sto\ssee\sif\sthe\snew\srow\shappens\sto\sbe\sthe\snext\srow\son\sthe\nsame\sleaf\spage.\s\sThat\sis\sa\sreasonably\scommon\scase,\sand\sif\sit\sis\strue\sit\navoids\sa\sfull\sbinary\ssearch. -D 2017-01-21T16:54:19.338 +C A\sbetter\simplementation\sof\sthe\smoveto-neighbor\soptimization\sthat\schecks\sfor\nnearby\srows\son\sadjacent\spages. +D 2017-01-21T21:47:54.621 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -333,7 +333,7 @@ F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792 F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca -F src/btree.c 972b7e1346eb2f4369cf8cc43117c728e2bd9cd4 +F src/btree.c f1b36bcfb1f9532ce64fe534153f11b8e2595d8b F src/btree.h e6d352808956ec163a17f832193a3e198b3fb0ac F src/btreeInt.h 10c4b77c2fb399580babbcc7cf652ac10dba796e F src/build.c 9e799f1edd910dfa8a0bc29bd390d35d310596af @@ -1547,7 +1547,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 347df3c1fd7322e7aacaf1e9f8be81830947c482 -R 3888200d85fb0a6e771ec0a3c9f2e5a8 +P 8e5cfb2039126da7689c4b1c88760f10e1234eaf +R 9f1865839aca85688e5829c506350f09 U drh -Z 4b0826cf6fb92296cc5aa9f45d953141 +Z fbf63ba541a6f5ec3e59c684016e63a0 diff --git a/manifest.uuid b/manifest.uuid index ac357ef297..478c310b27 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8e5cfb2039126da7689c4b1c88760f10e1234eaf \ No newline at end of file +2c4ecb85a475b9063aa8a3bb517ac181a7ded649 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 8b095b57b0..b6bc66ea85 100644 --- a/src/btree.c +++ b/src/btree.c @@ -5096,14 +5096,19 @@ int sqlite3BtreeMovetoUnpacked( *pRes = -1; return SQLITE_OK; } - if( pCur->aiIdx[pCur->iPage]+1apPage[pCur->iPage]->nCell ){ - pCur->aiIdx[pCur->iPage]++; - pCur->info.nSize = 0; - pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl); - getCellInfo(pCur); - if( pCur->info.nKey==intKey ){ - *pRes = 0; - return SQLITE_OK; + /* If the requested key is one more than the previous key, then + ** try to get there using sqlite3BtreeNext() rather than a full + ** binary search. This is an optimization only. The correct answer + ** is still obtained without this ase, only a little more slowely */ + if( pCur->info.nKey+1==intKey && !pCur->skipNext ){ + *pRes = 0; + rc = sqlite3BtreeNext(pCur, pRes); + if( rc ) return rc; + if( *pRes==0 ){ + getCellInfo(pCur); + if( pCur->info.nKey==intKey ){ + return SQLITE_OK; + } } } } From eacb4412b1e15d5f0890888ea51d2c2af65abbf8 Mon Sep 17 00:00:00 2001 From: drh Date: Sun, 22 Jan 2017 00:11:07 +0000 Subject: [PATCH 1223/1484] Fix an initialized variable in kvtest. FossilOrigin-Name: ed62c5a6562262709128099f757ae60807a930d7 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/kvtest.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 334c7a3604..09f825982a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\ssqlite3_blob_reopen()\sto\scall\ssqlite3VdbeExec()\sdirectly\srather\sthan\ngoing\sthrough\ssqlite3_step().\s\sPerformance\senhancement. -D 2017-01-21T16:27:56.517 +C Fix\san\sinitialized\svariable\sin\skvtest. +D 2017-01-22T00:11:07.052 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -898,7 +898,7 @@ F test/json101.test c0897616f32d95431f37fd291cb78742181980ac F test/json102.test bf3fe7a706d30936a76a0f7a0375e1e8e73aff5a F test/json103.test c5f6b85e69de05f6b3195f9f9d5ce9cd179099a0 F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff -F test/kvtest.c 9e428931f0733b5ba65b6b5abd95b27320e875a3 +F test/kvtest.c 9f0efc313b7bbef9022e9e3fe699d99f5bdc7efa F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63 F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200 F test/like.test 0603f4fa0dad50987f70032c05800cbfa8985302 @@ -1547,7 +1547,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 0d1ad13a296b22d6fe36879b56f99bd6af1acd3a -R 6bebf342d641742884692400aca75850 +P 347df3c1fd7322e7aacaf1e9f8be81830947c482 +R 47630561b257ab51d84219dbb1624512 U drh -Z fb104ae24cf906c93b7fa008d273f235 +Z d718277d52e4c47c008f4f640e1286d7 diff --git a/manifest.uuid b/manifest.uuid index 56e58c0ea3..b5d52cb040 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -347df3c1fd7322e7aacaf1e9f8be81830947c482 \ No newline at end of file +ed62c5a6562262709128099f757ae60807a930d7 \ No newline at end of file diff --git a/test/kvtest.c b/test/kvtest.c index d895af030f..6847d03a44 100644 --- a/test/kvtest.c +++ b/test/kvtest.c @@ -515,7 +515,7 @@ static int runMain(int argc, char **argv){ sqlite3_int64 tmElapsed; /* Elapsed time */ int nData = 0; /* Bytes of data */ sqlite3_int64 nTotal = 0; /* Total data read */ - unsigned char *pData; /* Content of the blob */ + unsigned char *pData = 0; /* Content of the blob */ int nAlloc = 0; /* Space allocated for pData[] */ From 35f30d339847c340b8f3c3019b722d1d52835cc2 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Sun, 22 Jan 2017 02:04:05 +0000 Subject: [PATCH 1224/1484] Fixes to documentation comments in the public header file. FossilOrigin-Name: 772dcb08f400f20d4dbfb74df39de78da24ee5fd --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/sqlite.h.in | 5 ++++- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 09f825982a..0ba3b67a5d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\sinitialized\svariable\sin\skvtest. -D 2017-01-22T00:11:07.052 +C Fixes\sto\sdocumentation\scomments\sin\sthe\spublic\sheader\sfile. +D 2017-01-22T02:04:05.790 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -392,7 +392,7 @@ F src/resolve.c f9bc0de45a30a450da47b3766de00be89bf9be79 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c 3856db523b942062bca8722ba03b61c324ff94d6 F src/shell.c 6095531aa900decdaa765e0f3993fba7153c92c1 -F src/sqlite.h.in e71655293c9bde26939496f3aac9d1821d2c07a2 +F src/sqlite.h.in 1971ab9709e010d52a02a1a6276d5a2f9b947476 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae F src/sqliteInt.h 525c061ae9aafc8d4720a018d82f0936d9eee5ab @@ -1547,7 +1547,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 347df3c1fd7322e7aacaf1e9f8be81830947c482 -R 47630561b257ab51d84219dbb1624512 -U drh -Z d718277d52e4c47c008f4f640e1286d7 +P ed62c5a6562262709128099f757ae60807a930d7 +R 46519c248d38b7b1891c031deb62dd78 +U mistachkin +Z c8163604b14219f9ecc118cfce9ce251 diff --git a/manifest.uuid b/manifest.uuid index b5d52cb040..8d815a1227 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ed62c5a6562262709128099f757ae60807a930d7 \ No newline at end of file +772dcb08f400f20d4dbfb74df39de78da24ee5fd \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 7d7e70f901..87d5d121cb 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -576,7 +576,7 @@ int sqlite3_exec( ** file that were written at the application level might have changed ** and that adjacent bytes, even bytes within the same sector are ** guaranteed to be unchanged. The SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN -** flag indicate that a file cannot be deleted when open. The +** flag indicates that a file cannot be deleted when open. The ** SQLITE_IOCAP_IMMUTABLE flag indicates that the file is on ** read-only media and cannot be changed even by processes with ** elevated privileges. @@ -726,6 +726,9 @@ struct sqlite3_file { **

    =M~ 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

  • [SQLITE_IOCAP_ATOMIC64K] **
  • [SQLITE_IOCAP_SAFE_APPEND] **
  • [SQLITE_IOCAP_SEQUENTIAL] +**
  • [SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN] +**
  • [SQLITE_IOCAP_POWERSAFE_OVERWRITE] +**
  • [SQLITE_IOCAP_IMMUTABLE] ** ** ** The SQLITE_IOCAP_ATOMIC property means that all writes of From 38305ab55ffa3f02c81e4632a5e24d56b97105ab Mon Sep 17 00:00:00 2001 From: drh Date: Sun, 22 Jan 2017 16:34:35 +0000 Subject: [PATCH 1225/1484] Fix an uninitialized variable in the command-line shell. FossilOrigin-Name: 06b8001ade62bc59e6ae20f761167a81d85a4272 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/shell.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 0ba3b67a5d..9083b4695c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fixes\sto\sdocumentation\scomments\sin\sthe\spublic\sheader\sfile. -D 2017-01-22T02:04:05.790 +C Fix\san\suninitialized\svariable\sin\sthe\scommand-line\sshell. +D 2017-01-22T16:34:35.577 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -391,7 +391,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c f9bc0de45a30a450da47b3766de00be89bf9be79 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c 3856db523b942062bca8722ba03b61c324ff94d6 -F src/shell.c 6095531aa900decdaa765e0f3993fba7153c92c1 +F src/shell.c 59de9acab4423a536277653f2a9dcdd1307989f3 F src/sqlite.h.in 1971ab9709e010d52a02a1a6276d5a2f9b947476 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae @@ -1547,7 +1547,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ed62c5a6562262709128099f757ae60807a930d7 -R 46519c248d38b7b1891c031deb62dd78 -U mistachkin -Z c8163604b14219f9ecc118cfce9ce251 +P 772dcb08f400f20d4dbfb74df39de78da24ee5fd +R 2e31ebcfccc9f64daf4bbf7d84d2d498 +U drh +Z 386761af3eaa734f6328de143132fe67 diff --git a/manifest.uuid b/manifest.uuid index 8d815a1227..7dd55bd0de 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -772dcb08f400f20d4dbfb74df39de78da24ee5fd \ No newline at end of file +06b8001ade62bc59e6ae20f761167a81d85a4272 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index b0928ce792..db4362dd32 100644 --- a/src/shell.c +++ b/src/shell.c @@ -5297,7 +5297,7 @@ static int do_meta_command(char *zLine, ShellState *p){ if( c=='v' && strncmp(azArg[0], "vfsinfo", n)==0 ){ const char *zDbName = nArg==2 ? azArg[1] : "main"; - sqlite3_vfs *pVfs; + sqlite3_vfs *pVfs = 0; if( p->db ){ sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFS_POINTER, &pVfs); if( pVfs ){ From 1b9fd2651bf2a04885038a991404e8623899b658 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 23 Jan 2017 07:06:27 +0000 Subject: [PATCH 1226/1484] Fix a problem preventing FTS5 from correctly passing the FTS5_TOKENIZE_PREFIX flag to custom tokenizer implementations. FossilOrigin-Name: 03c601344ed56b316bcc5fd02f6648b0009ba61b --- ext/fts5/fts5_expr.c | 2 +- ext/fts5/test/fts5synonym.test | 2 +- ext/fts5/test/fts5tokenizer.test | 39 ++++++++++++++++++++++++++++++++ manifest | 18 +++++++-------- manifest.uuid | 2 +- 5 files changed, 51 insertions(+), 12 deletions(-) diff --git a/ext/fts5/fts5_expr.c b/ext/fts5/fts5_expr.c index 9dcd88a5bc..209748bbf5 100644 --- a/ext/fts5/fts5_expr.c +++ b/ext/fts5/fts5_expr.c @@ -1601,7 +1601,7 @@ Fts5ExprPhrase *sqlite3Fts5ParseTerm( rc = fts5ParseStringFromToken(pToken, &z); if( rc==SQLITE_OK ){ - int flags = FTS5_TOKENIZE_QUERY | (bPrefix ? FTS5_TOKENIZE_QUERY : 0); + int flags = FTS5_TOKENIZE_QUERY | (bPrefix ? FTS5_TOKENIZE_PREFIX : 0); int n; sqlite3Fts5Dequote(z); n = (int)strlen(z); diff --git a/ext/fts5/test/fts5synonym.test b/ext/fts5/test/fts5synonym.test index 185dda3ff4..6243663123 100644 --- a/ext/fts5/test/fts5synonym.test +++ b/ext/fts5/test/fts5synonym.test @@ -152,7 +152,7 @@ foreach {tn expr res} { 1 {abc} {"abc"} 2 {one} {"one"|"i"|"1"} 3 {3} {"3"|"iii"|"three"} - 4 {3*} {"3"|"iii"|"three" *} + 4 {3*} {"3" *} } { do_execsql_test 4.1.$tn { SELECT fts5_expr($expr, 'tokenize=tclnum') diff --git a/ext/fts5/test/fts5tokenizer.test b/ext/fts5/test/fts5tokenizer.test index 9316d3c234..f68aa19a10 100644 --- a/ext/fts5/test/fts5tokenizer.test +++ b/ext/fts5/test/fts5tokenizer.test @@ -262,5 +262,44 @@ do_execsql_test 8.3 { brown dog fox jump lazi over quick the } +#------------------------------------------------------------------------- +# Check that the FTS5_TOKENIZE_PREFIX flag is passed to the tokenizer +# implementation. +# +reset_db +proc tcl_create {args} { return "tcl_tokenize" } +sqlite3_fts5_create_tokenizer db tcl tcl_create +set ::flags [list] +proc tcl_tokenize {tflags text} { + lappend ::flags $tflags + foreach {w iStart iEnd} [fts5_tokenize_split $text] { + sqlite3_fts5_token $w $iStart $iEnd + } +} + +do_execsql_test 9.1.1 { + CREATE VIRTUAL TABLE t1 USING fts5(a, tokenize=tcl); + INSERT INTO t1 VALUES('abc'); + INSERT INTO t1 VALUES('xyz'); +} {} +do_test 9.1.2 { set ::flags } {document document} + +set ::flags [list] +do_execsql_test 9.2.1 { SELECT * FROM t1('abc'); } {abc} +do_test 9.2.2 { set ::flags } {query} + +set ::flags [list] +do_execsql_test 9.3.1 { SELECT * FROM t1('ab*'); } {abc} +do_test 9.3.2 { set ::flags } {prefixquery} + +set ::flags [list] +do_execsql_test 9.4.1 { SELECT * FROM t1('"abc xyz" *'); } {} +do_test 9.4.2 { set ::flags } {prefixquery} + +set ::flags [list] +do_execsql_test 9.5.1 { SELECT * FROM t1('"abc xyz*"'); } {} +do_test 9.5.2 { set ::flags } {query} + + finish_test diff --git a/manifest b/manifest index 9083b4695c..722072798a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\suninitialized\svariable\sin\sthe\scommand-line\sshell. -D 2017-01-22T16:34:35.577 +C Fix\sa\sproblem\spreventing\sFTS5\sfrom\scorrectly\spassing\sthe\sFTS5_TOKENIZE_PREFIX\nflag\sto\scustom\stokenizer\simplementations. +D 2017-01-23T07:06:27.840 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -102,7 +102,7 @@ F ext/fts5/fts5Int.h b2eda36e0f224365c8e23dc8f559311834f1c13f F ext/fts5/fts5_aux.c 67acf8d51723cf28ffc3828210ba662df4b8d267 F ext/fts5/fts5_buffer.c 4c1502d4c956cd092c89ce4480867f9d8bf325cd F ext/fts5/fts5_config.c 5af9c360e99669d29f06492c370892394aba0857 -F ext/fts5/fts5_expr.c dc2cee9f56b1818b85df59304b8104a5dfb8ab60 +F ext/fts5/fts5_expr.c 33f0e8063ac7360bcd71c0ff0dcbacdc05fffe50 F ext/fts5/fts5_hash.c 880998e596b60f078348d48732ca4ad9a90caad2 F ext/fts5/fts5_index.c f67032a9a529ba52a545e6e3ab970764199c05d4 F ext/fts5/fts5_main.c f85281445dcf8be32d18841c93a6f90fe27dbfe2 @@ -184,11 +184,11 @@ F ext/fts5/test/fts5rowid.test 16908a99d6efc9ba21081b4f2b86b3fc699839a6 F ext/fts5/test/fts5simple.test 5da9b15ed534eb0be9f279d8a2bb2e24d30e4e38 F ext/fts5/test/fts5simple2.test 00839031878f52391562594fdab0503e424ee071 F ext/fts5/test/fts5simple3.test 25faa8cb8ad470c6f01f670bcc1317c19a89f091 -F ext/fts5/test/fts5synonym.test 6475d189c2e20d60795808f83e36bf9318708d48 +F ext/fts5/test/fts5synonym.test f964f9a98580dec06c995d4638ecb36eee60ae4a F ext/fts5/test/fts5synonym2.test aa4c43bd3b691ff80f658cb064f5ab40690e834e F ext/fts5/test/fts5tok1.test beb894c6f3468f10a574302f69ebe4436b0287c7 F ext/fts5/test/fts5tok2.test dcacb32d4a2a3f0dd3215d4a3987f78ae4be21a2 -F ext/fts5/test/fts5tokenizer.test ea4df698b35cc427ebf2ba22829d0e28386d8c89 +F ext/fts5/test/fts5tokenizer.test f64ab5fe48fa1317ff6315264bfe26e73cbdefde F ext/fts5/test/fts5unicode.test fbef8d8a3b4b88470536cc57604a82ca52e51841 F ext/fts5/test/fts5unicode2.test 529ac7e8648c943bc87bfed1e427128a2f3f9e33 F ext/fts5/test/fts5unicode3.test 35c3d02aa7acf7d43d8de3bfe32c15ba96e8928e @@ -1547,7 +1547,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 772dcb08f400f20d4dbfb74df39de78da24ee5fd -R 2e31ebcfccc9f64daf4bbf7d84d2d498 -U drh -Z 386761af3eaa734f6328de143132fe67 +P 06b8001ade62bc59e6ae20f761167a81d85a4272 +R 21442fb50b7964f67b800e2f23be99a7 +U dan +Z 98433cafc41c67731096a39c749dcd19 diff --git a/manifest.uuid b/manifest.uuid index 7dd55bd0de..6e356c14ae 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -06b8001ade62bc59e6ae20f761167a81d85a4272 \ No newline at end of file +03c601344ed56b316bcc5fd02f6648b0009ba61b \ No newline at end of file From 65c4c0b02d4c7146659185d43815d6b99fc4df7b Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 23 Jan 2017 15:58:09 +0000 Subject: [PATCH 1227/1484] Add the missing SQLITE_API symbol to test_delete.c (it is not added automatically as this file is not part of the amalgamation). FossilOrigin-Name: 7a4f512ddf9e7e718389c80930d6268ab598459c --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/test_delete.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 722072798a..09b8ee5078 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\spreventing\sFTS5\sfrom\scorrectly\spassing\sthe\sFTS5_TOKENIZE_PREFIX\nflag\sto\scustom\stokenizer\simplementations. -D 2017-01-23T07:06:27.840 +C Add\sthe\smissing\sSQLITE_API\ssymbol\sto\stest_delete.c\s(it\sis\snot\sadded\nautomatically\sas\sthis\sfile\sis\snot\spart\sof\sthe\samalgamation). +D 2017-01-23T15:58:09.428 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -416,7 +416,7 @@ F src/test_bestindex.c d23f80d334c59662af69191854c76b8d3d0c8c96 F src/test_blob.c 6a4c7920d1d9c6cc0f7aa50c89c4f80016aeda83 F src/test_btree.c 8b2dc8b8848cf3a4db93f11578f075e82252a274 F src/test_config.c 83179ea845479b5be9a651d014649e3f2722a1fe -F src/test_delete.c 8499d4d323f2ec8e28301deb3d6ddd8eef8b8139 +F src/test_delete.c af7eab5702f853fb1c62a5f7665e2234cf1ae17b F src/test_demovfs.c a0c3bdd45ed044115c2c9f7779e56eafff18741e F src/test_devsym.c 4e58dec2602d8e139ca08659f62a62450587cb58 F src/test_fs.c e16cbe68d3b107e00a907c20a9a02629870eb69b @@ -1547,7 +1547,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 06b8001ade62bc59e6ae20f761167a81d85a4272 -R 21442fb50b7964f67b800e2f23be99a7 +P 03c601344ed56b316bcc5fd02f6648b0009ba61b +R 9417217ad349116acb540369984c5408 U dan -Z 98433cafc41c67731096a39c749dcd19 +Z b2f31778ddace8b8427e4711f64f3edb diff --git a/manifest.uuid b/manifest.uuid index 6e356c14ae..e9d2ae6e41 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -03c601344ed56b316bcc5fd02f6648b0009ba61b \ No newline at end of file +7a4f512ddf9e7e718389c80930d6268ab598459c \ No newline at end of file diff --git a/src/test_delete.c b/src/test_delete.c index 731f11e257..ca61965b27 100644 --- a/src/test_delete.c +++ b/src/test_delete.c @@ -80,7 +80,7 @@ static int sqlite3DeleteUnlinkIfExists(const char *zFile, int *pbExists){ ** Delete the database file identified by the string argument passed to this ** function. The string must contain a filename, not an SQLite URI. */ -int sqlite3_delete_database( +SQLITE_API int sqlite3_delete_database( const char *zFile /* File to delete */ ){ char *zBuf; /* Buffer to sprintf() filenames to */ From bace3240820b16b15547f3433bf5805f1656c012 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 23 Jan 2017 18:40:15 +0000 Subject: [PATCH 1228/1484] Add the --mmap option to the kvtest utility program. FossilOrigin-Name: 4948f7e6d2a1cfce36a7aab2f5b65be07c285ac3 --- manifest | 13 ++++++------- manifest.uuid | 2 +- test/kvtest.c | 9 +++++++++ 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 3e45f5ecce..d96fa45b3e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Optimization:\sTry\sto\savoid\sunnecessary\sbtree\ssearching\swhen\srepositioning\s\na\scursor\sto\sthe\snext\srow. -D 2017-01-23T16:56:18.240 +C Add\sthe\s--mmap\soption\sto\sthe\skvtest\sutility\sprogram. +D 2017-01-23T18:40:15.799 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -898,7 +898,7 @@ F test/json101.test c0897616f32d95431f37fd291cb78742181980ac F test/json102.test bf3fe7a706d30936a76a0f7a0375e1e8e73aff5a F test/json103.test c5f6b85e69de05f6b3195f9f9d5ce9cd179099a0 F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff -F test/kvtest.c 9f0efc313b7bbef9022e9e3fe699d99f5bdc7efa +F test/kvtest.c 87e6e974eb9e1502e00e77bc2831f3c9174a6dfb F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63 F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200 F test/like.test 0603f4fa0dad50987f70032c05800cbfa8985302 @@ -1547,8 +1547,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 7a4f512ddf9e7e718389c80930d6268ab598459c 2c4ecb85a475b9063aa8a3bb517ac181a7ded649 -R 29a4885c53e914cde79778fd2e323ab3 -T +closed 2c4ecb85a475b9063aa8a3bb517ac181a7ded649 +P ee793d30c1dc1f78f49e6230d17750eceedbd8ed +R c50065d103fe6e8d8104ae7a368dc7b9 U drh -Z 5710c3bf174cb3e3f9b43957024c6c5f +Z a1392fb7660aa1d68b81ecf426bbd2cf diff --git a/manifest.uuid b/manifest.uuid index 2e7c43d757..28766bd75a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ee793d30c1dc1f78f49e6230d17750eceedbd8ed \ No newline at end of file +4948f7e6d2a1cfce36a7aab2f5b65be07c285ac3 \ No newline at end of file diff --git a/test/kvtest.c b/test/kvtest.c index 6847d03a44..f87e4940ef 100644 --- a/test/kvtest.c +++ b/test/kvtest.c @@ -513,6 +513,7 @@ static int runMain(int argc, char **argv){ sqlite3_blob *pBlob = 0; /* Handle for incremental Blob I/O */ sqlite3_int64 tmStart; /* Start time */ sqlite3_int64 tmElapsed; /* Elapsed time */ + int mmapSize = 0; /* --mmap N argument */ int nData = 0; /* Bytes of data */ sqlite3_int64 nTotal = 0; /* Total data read */ unsigned char *pData = 0; /* Content of the blob */ @@ -535,6 +536,12 @@ static int runMain(int argc, char **argv){ if( nCount<1 ) fatalError("the --count must be positive"); continue; } + if( strcmp(z, "-mmap")==0 ){ + if( i==argc-1 ) fatalError("missing argument on \"%s\"", argv[i]); + mmapSize = atoi(argv[++i]); + if( nCount<0 ) fatalError("the --mmap must be non-negative"); + continue; + } if( strcmp(z, "-max-id")==0 ){ if( i==argc-1 ) fatalError("missing argument on \"%s\"", argv[i]); iMax = atoi(argv[++i]); @@ -581,6 +588,8 @@ static int runMain(int argc, char **argv){ if( rc ){ fatalError("cannot open database \"%s\": %s", zDb, sqlite3_errmsg(db)); } + zSql = sqlite3_mprintf("PRAGMA mmap_size=%d", mmapSize); + sqlite3_exec(db, zSql, 0, 0, 0); zSql = sqlite3_mprintf("PRAGMA cache_size=%d", iCache); sqlite3_exec(db, zSql, 0, 0, 0); sqlite3_free(zSql); From d1b2566b07744604a96593ea174f82e174eaa7f4 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 23 Jan 2017 19:11:38 +0000 Subject: [PATCH 1229/1484] Document the --mmap option in the --help screen for kvtest. Enhance kvtest so that numeric arguments can have suffixes like "K" or "M". Add kvtest to the unix makefiles. FossilOrigin-Name: 175bda87288c7ce15b163316159f53a60822ccad --- Makefile.in | 9 ++++-- main.mk | 9 ++++-- manifest | 16 +++++------ manifest.uuid | 2 +- test/kvtest.c | 76 +++++++++++++++++++++++++++++++++++++++++++++------ 5 files changed, 91 insertions(+), 21 deletions(-) diff --git a/Makefile.in b/Makefile.in index b961070c23..d5fa831e6b 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1177,8 +1177,13 @@ LogEst$(TEXE): $(TOP)/tool/logest.c sqlite3.h wordcount$(TEXE): $(TOP)/test/wordcount.c sqlite3.lo $(LTLINK) -o $@ $(TOP)/test/wordcount.c sqlite3.lo $(TLIBS) -speedtest1$(TEXE): $(TOP)/test/speedtest1.c sqlite3.lo - $(LTLINK) -o $@ $(TOP)/test/speedtest1.c sqlite3.lo $(TLIBS) +speedtest1$(TEXE): $(TOP)/test/speedtest1.c sqlite3.c + $(LTLINK) $(ST_OPT) -o $@ $(TOP)/test/speedtest1.c sqlite3.c $(TLIBS) + +KV_OPT += -DSQLITE_DIRECT_OVERFLOW_READ + +kvtest$(TEXE): $(TOP)/test/kvtest.c sqlite3.c + $(LTLINK) $(KV_OPT) -o $@ $(TOP)/test/kvtest.c sqlite3.c $(TLIBS) rbu$(EXE): $(TOP)/ext/rbu/rbu.c $(TOP)/ext/rbu/sqlite3rbu.c sqlite3.lo $(LTLINK) -I. -o $@ $(TOP)/ext/rbu/rbu.c sqlite3.lo $(TLIBS) diff --git a/main.mk b/main.mk index 3b6e7f8609..17e6468e10 100644 --- a/main.mk +++ b/main.mk @@ -478,6 +478,8 @@ SHELL_OPT += -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1 FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 DBFUZZ_OPT = +KV_OPT = -DSQLITE_THREADSAFE=0 -DSQLITE_DIRECT_OVERFLOW_READ +ST_OPT = -DSQLITE_THREADSAFE=0 # This is the default Makefile target. The objects listed here # are what get build when you type just "make" with no arguments. @@ -892,8 +894,11 @@ wordcount$(EXE): $(TOP)/test/wordcount.c sqlite3.c $(TCC) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -o wordcount$(EXE) \ $(TOP)/test/wordcount.c sqlite3.c -speedtest1$(EXE): $(TOP)/test/speedtest1.c sqlite3.o - $(TCCX) -I. $(OTAFLAGS) -o speedtest1$(EXE) $(TOP)/test/speedtest1.c sqlite3.o $(THREADLIB) +speedtest1$(EXE): $(TOP)/test/speedtest1.c sqlite3.c + $(TCCX) -I. $(ST_OPT) -o speedtest1$(EXE) $(TOP)/test/speedtest1.c sqlite3.c $(THREADLIB) + +kvtest$(EXE): $(TOP)/test/kvtest.c sqlite3.c + $(TCCX) -I. $(KV+OPT) -o kvtest$(EXE) $(TOP)/test/kvtest.c sqlite3.c $(THREADLIB) rbu$(EXE): $(TOP)/ext/rbu/rbu.c $(TOP)/ext/rbu/sqlite3rbu.c sqlite3.o $(TCC) -I. -o rbu$(EXE) $(TOP)/ext/rbu/rbu.c sqlite3.o \ diff --git a/manifest b/manifest index d96fa45b3e..f8cd52fc5b 100644 --- a/manifest +++ b/manifest @@ -1,6 +1,6 @@ -C Add\sthe\s--mmap\soption\sto\sthe\skvtest\sutility\sprogram. -D 2017-01-23T18:40:15.799 -F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e +C Document\sthe\s--mmap\soption\sin\sthe\s--help\sscreen\sfor\skvtest.\s\sEnhance\skvtest\sso\nthat\snumeric\sarguments\scan\shave\ssuffixes\slike\s"K"\sor\s"M".\s\sAdd\skvtest\sto\sthe\nunix\smakefiles. +D 2017-01-23T19:11:38.113 +F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7 @@ -314,7 +314,7 @@ F ext/userauth/userauth.c 5fa3bdb492f481bbc1709fc83c91ebd13460c69e F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60 -F main.mk 8f620f3418d7252a3f428f5aacf674b5507807a8 +F main.mk afc52937b4e5fe08678e8d5a4fe4487d44e3bc61 F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 @@ -898,7 +898,7 @@ F test/json101.test c0897616f32d95431f37fd291cb78742181980ac F test/json102.test bf3fe7a706d30936a76a0f7a0375e1e8e73aff5a F test/json103.test c5f6b85e69de05f6b3195f9f9d5ce9cd179099a0 F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff -F test/kvtest.c 87e6e974eb9e1502e00e77bc2831f3c9174a6dfb +F test/kvtest.c d2d7c434023498237cf731df21ca0687bf103858 F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63 F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200 F test/like.test 0603f4fa0dad50987f70032c05800cbfa8985302 @@ -1547,7 +1547,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ee793d30c1dc1f78f49e6230d17750eceedbd8ed -R c50065d103fe6e8d8104ae7a368dc7b9 +P 4948f7e6d2a1cfce36a7aab2f5b65be07c285ac3 +R 9f530d22e2b0a16555eacd054431a10f U drh -Z a1392fb7660aa1d68b81ecf426bbd2cf +Z 4864426d37a32c6f04be82da7889e371 diff --git a/manifest.uuid b/manifest.uuid index 28766bd75a..82e31c7d74 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4948f7e6d2a1cfce36a7aab2f5b65be07c285ac3 \ No newline at end of file +175bda87288c7ce15b163316159f53a60822ccad \ No newline at end of file diff --git a/test/kvtest.c b/test/kvtest.c index f87e4940ef..c82a3f899e 100644 --- a/test/kvtest.c +++ b/test/kvtest.c @@ -85,6 +85,7 @@ static const char zHelp[] = " --count N Read N blobs\n" " --desc Read blobs in descending order\n" " --max-id N Maximum blob key to use\n" +" --mmap N Mmap as much as N bytes of DBFILE\n" " --random Read blobs in a random order\n" " --start N Start reading with this blob key\n" " --stats Output operating stats before exiting\n" @@ -132,6 +133,64 @@ static void fatalError(const char *zFormat, ...){ exit(1); } +/* +** Return the value of a hexadecimal digit. Return -1 if the input +** is not a hex digit. +*/ +static int hexDigitValue(char c){ + if( c>='0' && c<='9' ) return c - '0'; + if( c>='a' && c<='f' ) return c - 'a' + 10; + if( c>='A' && c<='F' ) return c - 'A' + 10; + return -1; +} + +/* +** Interpret zArg as an integer value, possibly with suffixes. +*/ +static int integerValue(const char *zArg){ + int v = 0; + static const struct { char *zSuffix; int iMult; } aMult[] = { + { "KiB", 1024 }, + { "MiB", 1024*1024 }, + { "GiB", 1024*1024*1024 }, + { "KB", 1000 }, + { "MB", 1000000 }, + { "GB", 1000000000 }, + { "K", 1000 }, + { "M", 1000000 }, + { "G", 1000000000 }, + }; + int i; + int isNeg = 0; + if( zArg[0]=='-' ){ + isNeg = 1; + zArg++; + }else if( zArg[0]=='+' ){ + zArg++; + } + if( zArg[0]=='0' && zArg[1]=='x' ){ + int x; + zArg += 2; + while( (x = hexDigitValue(zArg[0]))>=0 ){ + v = (v<<4) + x; + zArg++; + } + }else{ + while( zArg[0]>='0' && zArg[0]<='9' ){ + v = v*10 + zArg[0] - '0'; + zArg++; + } + } + for(i=0; i65536 || ((pgsz-1)&pgsz)!=0 ){ fatalError("the --pagesize must be power of 2 between 512 and 65536"); } @@ -491,6 +550,7 @@ static int display_stats( #define ORDER_DESC 2 #define ORDER_RANDOM 3 + /* ** Run a performance test */ @@ -532,31 +592,31 @@ static int runMain(int argc, char **argv){ if( z[1]=='-' ) z++; if( strcmp(z, "-count")==0 ){ if( i==argc-1 ) fatalError("missing argument on \"%s\"", argv[i]); - nCount = atoi(argv[++i]); + nCount = integerValue(argv[++i]); if( nCount<1 ) fatalError("the --count must be positive"); continue; } if( strcmp(z, "-mmap")==0 ){ if( i==argc-1 ) fatalError("missing argument on \"%s\"", argv[i]); - mmapSize = atoi(argv[++i]); + mmapSize = integerValue(argv[++i]); if( nCount<0 ) fatalError("the --mmap must be non-negative"); continue; } if( strcmp(z, "-max-id")==0 ){ if( i==argc-1 ) fatalError("missing argument on \"%s\"", argv[i]); - iMax = atoi(argv[++i]); + iMax = integerValue(argv[++i]); if( iMax<1 ) fatalError("the --max-id must be positive"); continue; } if( strcmp(z, "-start")==0 ){ if( i==argc-1 ) fatalError("missing argument on \"%s\"", argv[i]); - iKey = atoi(argv[++i]); + iKey = integerValue(argv[++i]); if( iKey<1 ) fatalError("the --start must be positive"); continue; } if( strcmp(z, "-cache-size")==0 ){ if( i==argc-1 ) fatalError("missing argument on \"%s\"", argv[i]); - iCache = atoi(argv[++i]); + iCache = integerValue(argv[++i]); continue; } if( strcmp(z, "-random")==0 ){ From 210b0d0eb311e2fc2ece5c71a196811479f5f349 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 25 Jan 2017 04:41:34 +0000 Subject: [PATCH 1230/1484] Ensure that sqlite3_blob_reopen() correctly handles short rows. Proposed fix for ticket [e6e962d6b0f06f46e]. Further testing needed. FossilOrigin-Name: 57d8dad35c2a9ab635e954dce7f3986ae1ca8ed2 --- manifest | 15 +++++++++------ manifest.uuid | 2 +- src/vdbeblob.c | 4 +++- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index f8cd52fc5b..2325ce2625 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Document\sthe\s--mmap\soption\sin\sthe\s--help\sscreen\sfor\skvtest.\s\sEnhance\skvtest\sso\nthat\snumeric\sarguments\scan\shave\ssuffixes\slike\s"K"\sor\s"M".\s\sAdd\skvtest\sto\sthe\nunix\smakefiles. -D 2017-01-23T19:11:38.113 +C Ensure\sthat\ssqlite3_blob_reopen()\scorrectly\shandles\sshort\srows.\nProposed\sfix\sfor\sticket\s[e6e962d6b0f06f46e].\s\sFurther\stesting\sneeded. +D 2017-01-25T04:41:34.251 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -462,7 +462,7 @@ F src/vdbe.h b0866e4191f096f1c987a84b042c3599bdf5423b F src/vdbeInt.h 281cb70332dc8b593b8c7afe776f3a2ba7d4255e F src/vdbeapi.c d6ebaa465f070eb1af8ba4e7b34583ece87bdd24 F src/vdbeaux.c 35c9a9908174e5a26c96d15e1f98214814a39147 -F src/vdbeblob.c 2159f36d2c3e7ed24e3ebe99a9a4b462248c0665 +F src/vdbeblob.c 2b3d1ad915dbe5dc92c48759dc18fa8c697e78e5 F src/vdbemem.c 3b5a9a5b375458d3e12a50ae1aaa41eeec2175fd F src/vdbesort.c eda25cb2d1727efca6f7862fea32b8aa33c0face F src/vdbetrace.c 41963d5376f0349842b5fc4aaaaacd7d9cdc0834 @@ -1547,7 +1547,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 4948f7e6d2a1cfce36a7aab2f5b65be07c285ac3 -R 9f530d22e2b0a16555eacd054431a10f +P 175bda87288c7ce15b163316159f53a60822ccad +R 344bedd0898a54c0d1255ff2528051f8 +T *branch * blob_reopen-fix +T *sym-blob_reopen-fix * +T -sym-trunk * U drh -Z 4864426d37a32c6f04be82da7889e371 +Z ac35e85a79d80d6e1f6100309e724651 diff --git a/manifest.uuid b/manifest.uuid index 82e31c7d74..1d4e697bcd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -175bda87288c7ce15b163316159f53a60822ccad \ No newline at end of file +57d8dad35c2a9ab635e954dce7f3986ae1ca8ed2 \ No newline at end of file diff --git a/src/vdbeblob.c b/src/vdbeblob.c index 1efd4c9243..810f78860f 100644 --- a/src/vdbeblob.c +++ b/src/vdbeblob.c @@ -77,7 +77,9 @@ static int blobSeekToRow(Incrblob *p, sqlite3_int64 iRow, char **pzErr){ } if( rc==SQLITE_ROW ){ VdbeCursor *pC = v->apCsr[0]; - u32 type = pC->aType[p->iCol]; + u32 type = pC->nHdrParsed>p->iCol ? pC->aType[p->iCol] : 0; + testcase( pC->nHdrParsed==p->iCol ); + testcase( pC->nHdrParsed==p->iCol+1 ); if( type<12 ){ zErr = sqlite3MPrintf(p->db, "cannot open value of type %s", type==0?"null": type==7?"real": "integer" From 666d34c791536557855c3efd58a9a1c3ec7e59a0 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 25 Jan 2017 13:54:27 +0000 Subject: [PATCH 1231/1484] Fix SQLITEINT_H macro usage in two extensions. FossilOrigin-Name: 0803390c152141c9ab4e7a28406b2a5d72a5c2fa --- ext/misc/json1.c | 2 +- ext/userauth/userauth.c | 2 +- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/ext/misc/json1.c b/ext/misc/json1.c index 327ad57500..3063f9f261 100644 --- a/ext/misc/json1.c +++ b/ext/misc/json1.c @@ -22,7 +22,7 @@ ** how JSONB might improve on that.) */ #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_JSON1) -#if !defined(_SQLITEINT_H_) +#if !defined(SQLITEINT_H) #include "sqlite3ext.h" #endif SQLITE_EXTENSION_INIT1 diff --git a/ext/userauth/userauth.c b/ext/userauth/userauth.c index 6ce99053d3..a3d346c05c 100644 --- a/ext/userauth/userauth.c +++ b/ext/userauth/userauth.c @@ -22,7 +22,7 @@ ** directory as this file for additional information. */ #ifdef SQLITE_USER_AUTHENTICATION -#ifndef _SQLITEINT_H_ +#ifndef SQLITEINT_H # include "sqliteInt.h" #endif diff --git a/manifest b/manifest index f8cd52fc5b..01c84dc4e5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Document\sthe\s--mmap\soption\sin\sthe\s--help\sscreen\sfor\skvtest.\s\sEnhance\skvtest\sso\nthat\snumeric\sarguments\scan\shave\ssuffixes\slike\s"K"\sor\s"M".\s\sAdd\skvtest\sto\sthe\nunix\smakefiles. -D 2017-01-23T19:11:38.113 +C Fix\sSQLITEINT_H\smacro\susage\sin\stwo\sextensions. +D 2017-01-25T13:54:27.195 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -213,7 +213,7 @@ F ext/misc/eval.c f971962e92ebb8b0a4e6b62949463ee454d88fa2 F ext/misc/fileio.c d4171c815d6543a9edef8308aab2951413cd8d0f F ext/misc/fuzzer.c 7c64b8197bb77b7d64eff7cac7848870235d4c25 F ext/misc/ieee754.c f190d0cc5182529acb15babd177781be1ac1718c -F ext/misc/json1.c e0797ef1bfa637429ceab9140ecba620809ee02a +F ext/misc/json1.c 552a7d730863419e05dc947265b28bd411680e2e F ext/misc/memvfs.c e5225bc22e79dde6b28380f3a068ddf600683a33 F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342 F ext/misc/percentile.c 92699c8cd7d517ff610e6037e56506f8904dae2e @@ -310,7 +310,7 @@ F ext/session/sqlite3session.h 9345166bd8f80562145586cf817f707de5ecada2 F ext/session/test_session.c eb0bd6c1ea791c1d66ee4ef94c16500dad936386 F ext/userauth/sqlite3userauth.h 19cb6f0e31316d0ee4afdfb7a85ef9da3333a220 F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04 -F ext/userauth/userauth.c 5fa3bdb492f481bbc1709fc83c91ebd13460c69e +F ext/userauth/userauth.c 3410be31283abba70255d71fd24734e017a4497f F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60 @@ -1547,7 +1547,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 4948f7e6d2a1cfce36a7aab2f5b65be07c285ac3 -R 9f530d22e2b0a16555eacd054431a10f +P 175bda87288c7ce15b163316159f53a60822ccad +R a9fb164433cc898aa04fd742715e395e U drh -Z 4864426d37a32c6f04be82da7889e371 +Z 35bb9e1641d0b89bf56f9577622d86ef diff --git a/manifest.uuid b/manifest.uuid index 82e31c7d74..94c54c55e9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -175bda87288c7ce15b163316159f53a60822ccad \ No newline at end of file +0803390c152141c9ab4e7a28406b2a5d72a5c2fa \ No newline at end of file From 585ce1923c7c45bd0bf4da4ad957b6421785d1f0 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 25 Jan 2017 14:58:27 +0000 Subject: [PATCH 1232/1484] Experimental enhancement to automatically trim NULL values from the end of records, for a reduced disk footprint. This change also involves increasing the P5 operand from 8 to 16 bits. FossilOrigin-Name: 118ded403b95050b74ae2b03919c43d614094a32 --- manifest | 24 +++++++++++++----------- manifest.uuid | 2 +- src/insert.c | 18 ++++++++++++++++++ src/sqliteInt.h | 1 + src/vdbe.c | 12 ++++++++++++ src/vdbe.h | 5 ++--- src/vdbeaux.c | 2 +- 7 files changed, 48 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index edea9fbb44..86115ea620 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Ensure\sthat\ssqlite3_blob_reopen()\scorrectly\shandles\sshort\srows.\s\nFix\sfor\sticket\s[e6e962d6b0f06f46e]. -D 2017-01-25T14:38:19.847 +C Experimental\senhancement\sto\sautomatically\strim\sNULL\svalues\sfrom\sthe\send\sof\nrecords,\sfor\sa\sreduced\sdisk\sfootprint.\s\sThis\schange\salso\sinvolves\sincreasing\nthe\sP5\soperand\sfrom\s8\sto\s16\sbits. +D 2017-01-25T14:58:27.321 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -352,7 +352,7 @@ F src/hash.c 63d0ee752a3b92d4695b2b1f5259c4621b2cfebd F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4 F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 -F src/insert.c 05e47e2de7b712a3a4148cd469e5f60873f5ef13 +F src/insert.c 07ccec2c1fb32dd2c5fbfd63426e98dc2a79a0fa F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e F src/loadext.c a68d8d1d14cf7488bb29dc5311cb1ce9a4404258 F src/main.c e207b81542d13b9f13d61e78ca441f9781f055b0 @@ -395,7 +395,7 @@ F src/shell.c 59de9acab4423a536277653f2a9dcdd1307989f3 F src/sqlite.h.in 1971ab9709e010d52a02a1a6276d5a2f9b947476 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae -F src/sqliteInt.h 525c061ae9aafc8d4720a018d82f0936d9eee5ab +F src/sqliteInt.h dc587b0727c2bc888d78d200d891620080567691 F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 @@ -457,11 +457,11 @@ F src/update.c b356b29d04c71f33c779f2cb557cf953819bdd7a F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c a88b0466fddf445ce752226d4698ca3faada620a F src/vacuum.c 33c174b28886b2faf26e503b5a49a1c01a9b1c16 -F src/vdbe.c c7add5978cb84ae3a7bcb16f8b56cb3bbdf04b7e -F src/vdbe.h b0866e4191f096f1c987a84b042c3599bdf5423b +F src/vdbe.c b1f2448184fa58c66fc94591004b1258964ef9da +F src/vdbe.h 59998ffd71d7caa8886bc78dafaf8caeccd4c13c F src/vdbeInt.h 281cb70332dc8b593b8c7afe776f3a2ba7d4255e F src/vdbeapi.c d6ebaa465f070eb1af8ba4e7b34583ece87bdd24 -F src/vdbeaux.c 35c9a9908174e5a26c96d15e1f98214814a39147 +F src/vdbeaux.c 8a2446741a2ec1072e744bc50f69b8b9e6c36592 F src/vdbeblob.c 2b3d1ad915dbe5dc92c48759dc18fa8c697e78e5 F src/vdbemem.c 3b5a9a5b375458d3e12a50ae1aaa41eeec2175fd F src/vdbesort.c eda25cb2d1727efca6f7862fea32b8aa33c0face @@ -1547,8 +1547,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 0803390c152141c9ab4e7a28406b2a5d72a5c2fa 57d8dad35c2a9ab635e954dce7f3986ae1ca8ed2 -R d15a5cee6a51c7118a4d78b7d0cbd2de -T +closed 57d8dad35c2a9ab635e954dce7f3986ae1ca8ed2 +P 8cd1a4451cce1fe28f462800e2be1dee1735c0d0 +R 8038c1c21360d07be65589e30167ecdf +T *branch * trim-nulls +T *sym-trim-nulls * +T -sym-trunk * U drh -Z f9af43b146da8d8246d0b97014ae0d3a +Z d170ee380cb17c0b674fe48dc7bc03d5 diff --git a/manifest.uuid b/manifest.uuid index d15e64c7de..6aea75dca3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8cd1a4451cce1fe28f462800e2be1dee1735c0d0 \ No newline at end of file +118ded403b95050b74ae2b03919c43d614094a32 \ No newline at end of file diff --git a/src/insert.c b/src/insert.c index 93c22ae3f5..5bb8ba2ff9 100644 --- a/src/insert.c +++ b/src/insert.c @@ -1668,6 +1668,23 @@ void sqlite3GenerateConstraintChecks( VdbeModuleComment((v, "END: GenCnstCks(%d)", seenReplace)); } +/* +** Change the P5 operand on the last opcode (which should be an OP_MakeRecord) +** to be the number of columns in table pTab that must not be NULL-trimmed. +** +** Or if no columns of pTab may be NULL-trimmed, leave P5 at zero. +*/ +void sqlite3SetMakeRecordP5(Vdbe *v, Table *pTab){ + u16 i; + + /* Records with omitted columns are only allowed for schema format + ** version 2 and later (SQLite version 3.1.4, 2005-02-20). */ + if( pTab->pSchema->file_format<2 ) return; + + for(i=pTab->nCol; i>1 && pTab->aCol[i-1].pDflt==0; i--){} + sqlite3VdbeChangeP5(v, i); +} + /* ** This routine generates code to finish the INSERT or UPDATE operation ** that was started by a prior call to sqlite3GenerateConstraintChecks. @@ -1727,6 +1744,7 @@ void sqlite3CompleteInsertion( regData = regNewData + 1; regRec = sqlite3GetTempReg(pParse); sqlite3VdbeAddOp3(v, OP_MakeRecord, regData, pTab->nCol, regRec); + sqlite3SetMakeRecordP5(v, pTab); if( !bAffinityDone ){ sqlite3TableAffinity(v, pTab, 0); sqlite3ExprCacheAffinityChange(pParse, regData, pTab->nCol); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 6344cac5f1..ceae4dcb1f 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3790,6 +3790,7 @@ int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int, int*,Index*,int); void sqlite3ResolvePartIdxLabel(Parse*,int); void sqlite3GenerateConstraintChecks(Parse*,Table*,int*,int,int,int,int, u8,u8,int,int*,int*); +void sqlite3SetMakeRecordP5(Vdbe*,Table*); void sqlite3CompleteInsertion(Parse*,Table*,int,int,int,int*,int,int,int); int sqlite3OpenTableAndIndices(Parse*, Table*, int, u8, int, u8*, int*, int*); void sqlite3BeginWriteOperation(Parse*, int, int); diff --git a/src/vdbe.c b/src/vdbe.c index cbb7867512..88010a9a6f 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2777,6 +2777,18 @@ case OP_MakeRecord: { }while( zAffinity[0] ); } + /* NULLs can be safely trimmed from the end of the record, as long as + ** as the schema format is 2 or more and none of the omitted columns + ** have a non-NULL default value. Also, the record must be left with + ** at least one field. If P5>0 then it will be one more than the + ** index of the right-most column with a non-NULL default value */ + if( pOp->p5 ){ + while( (pLast->flags & MEM_Null)!=0 && nField>pOp->p5 ){ + pLast--; + nField--; + } + } + /* Loop through the elements that will make up the record to figure ** out how much space is required for the new record. */ diff --git a/src/vdbe.h b/src/vdbe.h index feaf116807..a35f3be344 100644 --- a/src/vdbe.h +++ b/src/vdbe.h @@ -41,8 +41,7 @@ typedef struct SubProgram SubProgram; struct VdbeOp { u8 opcode; /* What operation to perform */ signed char p4type; /* One of the P4_xxx constants for p4 */ - u8 notUsed1; - u8 p5; /* Fifth parameter is an unsigned character */ + u16 p5; /* Fifth parameter is an unsigned 16-bit integer */ int p1; /* First operand */ int p2; /* Second parameter (often the jump destination) */ int p3; /* The third parameter */ @@ -194,7 +193,7 @@ void sqlite3VdbeChangeOpcode(Vdbe*, u32 addr, u8); void sqlite3VdbeChangeP1(Vdbe*, u32 addr, int P1); void sqlite3VdbeChangeP2(Vdbe*, u32 addr, int P2); void sqlite3VdbeChangeP3(Vdbe*, u32 addr, int P3); -void sqlite3VdbeChangeP5(Vdbe*, u8 P5); +void sqlite3VdbeChangeP5(Vdbe*, u16 P5); void sqlite3VdbeJumpHere(Vdbe*, int addr); int sqlite3VdbeChangeToNoop(Vdbe*, int addr); int sqlite3VdbeDeletePriorOpcode(Vdbe*, u8 op); diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 85d273f1ec..cd423ed5b5 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -783,7 +783,7 @@ void sqlite3VdbeChangeP2(Vdbe *p, u32 addr, int val){ void sqlite3VdbeChangeP3(Vdbe *p, u32 addr, int val){ sqlite3VdbeGetOp(p,addr)->p3 = val; } -void sqlite3VdbeChangeP5(Vdbe *p, u8 p5){ +void sqlite3VdbeChangeP5(Vdbe *p, u16 p5){ assert( p->nOp>0 || p->db->mallocFailed ); if( p->nOp>0 ) p->aOp[p->nOp-1].p5 = p5; } From 2a86c1962c04e6f3fbec04121dc7b69e2a702648 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 25 Jan 2017 17:44:13 +0000 Subject: [PATCH 1233/1484] Fix a problem with the pre-update hook on this branch. FossilOrigin-Name: 6fc4fbfa29cfa795edf32e4a1f2d0eceb3007f68 --- manifest | 23 ++++++++++------------- manifest.uuid | 2 +- src/vdbeapi.c | 10 ++++------ src/vdbeaux.c | 8 ++++---- test/hook.test | 36 ++++++++++++++++++++++++++++++++++++ test/tester.tcl | 2 +- 6 files changed, 56 insertions(+), 25 deletions(-) diff --git a/manifest b/manifest index 86115ea620..0fa8005bed 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Experimental\senhancement\sto\sautomatically\strim\sNULL\svalues\sfrom\sthe\send\sof\nrecords,\sfor\sa\sreduced\sdisk\sfootprint.\s\sThis\schange\salso\sinvolves\sincreasing\nthe\sP5\soperand\sfrom\s8\sto\s16\sbits. -D 2017-01-25T14:58:27.321 +C Fix\sa\sproblem\swith\sthe\spre-update\shook\son\sthis\sbranch. +D 2017-01-25T17:44:13.969 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -460,8 +460,8 @@ F src/vacuum.c 33c174b28886b2faf26e503b5a49a1c01a9b1c16 F src/vdbe.c b1f2448184fa58c66fc94591004b1258964ef9da F src/vdbe.h 59998ffd71d7caa8886bc78dafaf8caeccd4c13c F src/vdbeInt.h 281cb70332dc8b593b8c7afe776f3a2ba7d4255e -F src/vdbeapi.c d6ebaa465f070eb1af8ba4e7b34583ece87bdd24 -F src/vdbeaux.c 8a2446741a2ec1072e744bc50f69b8b9e6c36592 +F src/vdbeapi.c 9a44ed2f4fcb5a10dec9da5af95293d31830f268 +F src/vdbeaux.c 7c19b78999faae833e1be66dfa4e3deaf334d739 F src/vdbeblob.c 2b3d1ad915dbe5dc92c48759dc18fa8c697e78e5 F src/vdbemem.c 3b5a9a5b375458d3e12a50ae1aaa41eeec2175fd F src/vdbesort.c eda25cb2d1727efca6f7862fea32b8aa33c0face @@ -832,7 +832,7 @@ F test/gcfault.test dd28c228a38976d6336a3fc42d7e5f1ad060cb8c F test/genesis.tcl 1e2e2e8e5cc4058549a154ff1892fe5c9de19f98 F test/hexlit.test 4a6a5f46e3c65c4bf1fa06f5dd5a9507a5627751 F test/hidden.test 23c1393a79e846d68fd902d72c85d5e5dcf98711 -F test/hook.test 3a01b876691f9151d3e44562354f7d663ff90fce +F test/hook.test 09b8ce2226776b10bf74344e67d81291a49801f6 F test/icu.test 73956798bace8982909c00476b216714a6d0559a F test/ieee754.test 806fc0ce7f305f57e3331eaceeddcfec9339e607 F test/imposter1.test c3f1db2d3db2c24611a6596a3fc0ffc14f1466c8 @@ -1163,7 +1163,7 @@ F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30 F test/temptable2.test cd396beb41117a5302fff61767c35fa4270a0d5e F test/temptable3.test d11a0974e52b347e45ee54ef1923c91ed91e4637 F test/temptrigger.test 38f0ca479b1822d3117069e014daabcaacefffcc -F test/tester.tcl 4ce5afd5e192db4cae178e1a983b060e0f08c5d6 +F test/tester.tcl 2a49c1aff731f380ea640106377e19611a1443ae F test/thread001.test 9f22fd3525a307ff42a326b6bc7b0465be1745a5 F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58 F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7 @@ -1547,10 +1547,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 8cd1a4451cce1fe28f462800e2be1dee1735c0d0 -R 8038c1c21360d07be65589e30167ecdf -T *branch * trim-nulls -T *sym-trim-nulls * -T -sym-trunk * -U drh -Z d170ee380cb17c0b674fe48dc7bc03d5 +P 118ded403b95050b74ae2b03919c43d614094a32 +R b2da1f7f2be6fc581980d1f7d80d3a07 +U dan +Z e5faacbef3e7f4e557b616df3270ec25 diff --git a/manifest.uuid b/manifest.uuid index 6aea75dca3..eaecf9f4a3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -118ded403b95050b74ae2b03919c43d614094a32 \ No newline at end of file +6fc4fbfa29cfa795edf32e4a1f2d0eceb3007f68 \ No newline at end of file diff --git a/src/vdbeapi.c b/src/vdbeapi.c index 32794de9a0..91edd34022 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -1776,13 +1776,11 @@ int sqlite3_preupdate_new(sqlite3 *db, int iIdx, sqlite3_value **ppValue){ } p->pNewUnpacked = pUnpack; } - if( iIdx>=pUnpack->nField ){ + pMem = &pUnpack->aMem[iIdx]; + if( iIdx==p->pTab->iPKey ){ + sqlite3VdbeMemSetInt64(pMem, p->iKey2); + }else if( iIdx>=pUnpack->nField ){ pMem = (sqlite3_value *)columnNullValue(); - }else{ - pMem = &pUnpack->aMem[iIdx]; - if( iIdx==p->pTab->iPKey ){ - sqlite3VdbeMemSetInt64(pMem, p->iKey2); - } } }else{ /* For an UPDATE, memory cell (p->iNewReg+1+iIdx) contains the required diff --git a/src/vdbeaux.c b/src/vdbeaux.c index cd423ed5b5..44f2ad38f4 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -4585,10 +4585,10 @@ void sqlite3VtabImportErrmsg(Vdbe *p, sqlite3_vtab *pVtab){ ** This function is used to free UnpackedRecord structures allocated by ** the vdbeUnpackRecord() function found in vdbeapi.c. */ -static void vdbeFreeUnpacked(sqlite3 *db, UnpackedRecord *p){ +static void vdbeFreeUnpacked(sqlite3 *db, int nField, UnpackedRecord *p){ if( p ){ int i; - for(i=0; inField; i++){ + for(i=0; iaMem[i]; if( pMem->zMalloc ) sqlite3VdbeMemRelease(pMem); } @@ -4647,8 +4647,8 @@ void sqlite3VdbePreUpdateHook( db->xPreUpdateCallback(db->pPreUpdateArg, db, op, zDb, zTbl, iKey1, iKey2); db->pPreUpdate = 0; sqlite3DbFree(db, preupdate.aRecord); - vdbeFreeUnpacked(db, preupdate.pUnpacked); - vdbeFreeUnpacked(db, preupdate.pNewUnpacked); + vdbeFreeUnpacked(db, preupdate.keyinfo.nField+1, preupdate.pUnpacked); + vdbeFreeUnpacked(db, preupdate.keyinfo.nField+1, preupdate.pNewUnpacked); if( preupdate.aNew ){ int i; for(i=0; inField; i++){ diff --git a/test/hook.test b/test/hook.test index 8f095c9e8d..c576449502 100644 --- a/test/hook.test +++ b/test/hook.test @@ -854,4 +854,40 @@ do_preupdate_test 8.1 { } { } +#------------------------------------------------------------------------- +reset_db +db preupdate hook preupdate_hook +do_execsql_test 9.0 { + CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c); + CREATE TABLE t2(a, b INTEGER PRIMARY KEY); +} +do_preupdate_test 9.1 { + INSERT INTO t1 VALUES(456, NULL, NULL); +} { + INSERT main t1 456 456 0 456 {} {} +} +do_execsql_test 9.2 { + ALTER TABLE t1 ADD COLUMN d; +} +do_preupdate_test 9.3 { + INSERT INTO t1(a, b, c) VALUES(457, NULL, NULL); +} { + INSERT main t1 457 457 0 457 {} {} {} +} +do_preupdate_test 9.4 { + DELETE FROM t1 WHERE a=456 +} { + DELETE main t1 456 456 0 456 {} {} {} +} +do_preupdate_test 9.5 { + INSERT INTO t2 DEFAULT VALUES; +} { + INSERT main t2 1 1 0 {} 1 +} +do_preupdate_test 9.6 { + INSERT INTO t1 DEFAULT VALUES; +} { + INSERT main t1 458 458 0 458 {} {} {} +} + finish_test diff --git a/test/tester.tcl b/test/tester.tcl index 814788ba45..8cc501a182 100644 --- a/test/tester.tcl +++ b/test/tester.tcl @@ -461,7 +461,7 @@ if {[info exists cmdlinearg]==0} { } {^-+backtrace=.+$} { foreach {dummy cmdlinearg(backtrace)} [split $a =] break - sqlite3_memdebug_backtrace $value + sqlite3_memdebug_backtrace $cmdlinearg(backtrace) } {^-+binarylog=.+$} { foreach {dummy cmdlinearg(binarylog)} [split $a =] break From d47e1ccb57ee3693ddf91162a0f38934007fef7e Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 25 Jan 2017 18:12:46 +0000 Subject: [PATCH 1234/1484] Fix a test script problem in exclusive2.test causing it to fail on this branch. FossilOrigin-Name: f66614dc78e32d2d369518200b3322cd97990ffe --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/exclusive2.test | 16 ++++++++-------- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index 0fa8005bed..88faa9a140 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\swith\sthe\spre-update\shook\son\sthis\sbranch. -D 2017-01-25T17:44:13.969 +C Fix\sa\stest\sscript\sproblem\sin\sexclusive2.test\scausing\sit\sto\sfail\son\sthis\nbranch. +D 2017-01-25T18:12:46.110 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -679,7 +679,7 @@ F test/eqp.test 3fe051af50921284189d1970eb653f9fcf5117d2 F test/errmsg.test f31592a594b44ee121371d25ddd5d63497bb3401 F test/eval.test a64c9105d6ff163df7cf09d6ac29cdad5922078c F test/exclusive.test 9a57bd66e39144b888ca75c309914fcdefb4e3f9 -F test/exclusive2.test 32798111aae78a5deec980eee383213f189df308 +F test/exclusive2.test 984090e8e9d1b331d2e8111daf6e5d61dda0bef7 F test/exec.test e949714dc127eaa5ecc7d723efec1ec27118fdd7 F test/exists.test 79a75323c78f02bbe9c251ea502a092f9ef63dac F test/expr.test 66a2c9ac34f74f036faa4092f5402c7d3162fc93 @@ -1547,7 +1547,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 118ded403b95050b74ae2b03919c43d614094a32 -R b2da1f7f2be6fc581980d1f7d80d3a07 +P 6fc4fbfa29cfa795edf32e4a1f2d0eceb3007f68 +R c06506894b1f7b9de189bb73f3ac7abf U dan -Z e5faacbef3e7f4e557b616df3270ec25 +Z 47f4a5e852dc6941a6a828eee1ba5cee diff --git a/manifest.uuid b/manifest.uuid index eaecf9f4a3..947e5dcd6a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6fc4fbfa29cfa795edf32e4a1f2d0eceb3007f68 \ No newline at end of file +f66614dc78e32d2d369518200b3322cd97990ffe \ No newline at end of file diff --git a/test/exclusive2.test b/test/exclusive2.test index 712363e762..92fcd76ab3 100644 --- a/test/exclusive2.test +++ b/test/exclusive2.test @@ -121,13 +121,13 @@ do_test exclusive2-1.1 { execsql { BEGIN; CREATE TABLE t1(a, b); - INSERT INTO t1(a) VALUES(randstr(10, 400)); - INSERT INTO t1(a) VALUES(randstr(10, 400)); - INSERT INTO t1(a) SELECT randstr(10, 400) FROM t1; - INSERT INTO t1(a) SELECT randstr(10, 400) FROM t1; - INSERT INTO t1(a) SELECT randstr(10, 400) FROM t1; - INSERT INTO t1(a) SELECT randstr(10, 400) FROM t1; - INSERT INTO t1(a) SELECT randstr(10, 400) FROM t1; + INSERT INTO t1(a, b) VALUES(randstr(10, 400), 0); + INSERT INTO t1(a, b) VALUES(randstr(10, 400), 0); + INSERT INTO t1(a, b) SELECT randstr(10, 400), 0 FROM t1; + INSERT INTO t1(a, b) SELECT randstr(10, 400), 0 FROM t1; + INSERT INTO t1(a, b) SELECT randstr(10, 400), 0 FROM t1; + INSERT INTO t1(a, b) SELECT randstr(10, 400), 0 FROM t1; + INSERT INTO t1(a, b) SELECT randstr(10, 400), 0 FROM t1; COMMIT; SELECT count(*) FROM t1; } @@ -154,7 +154,7 @@ do_test exclusive2-1.4 { } $::sig do_test exclusive2-1.5 { execsql { - UPDATE t1 SET b=a, a=NULL; + UPDATE t1 SET b=a, a=0; } db2 expr {[t1sig db2] eq $::sig} } 0 From 7271d7a19c2d651146fed05680e1b393c4901d2c Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 25 Jan 2017 18:53:27 +0000 Subject: [PATCH 1235/1484] Fix another pre-update hook issue, this time in sqlite3preupdate_old(). FossilOrigin-Name: c7651d21bfdfd9b8cf04b26e0264bc58c03d247f --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/vdbeapi.c | 18 ++++++++---------- test/hook.test | 15 +++++++++++++++ 4 files changed, 31 insertions(+), 18 deletions(-) diff --git a/manifest b/manifest index 88faa9a140..e160f9e3f6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\stest\sscript\sproblem\sin\sexclusive2.test\scausing\sit\sto\sfail\son\sthis\nbranch. -D 2017-01-25T18:12:46.110 +C Fix\sanother\spre-update\shook\sissue,\sthis\stime\sin\ssqlite3preupdate_old(). +D 2017-01-25T18:53:27.729 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -460,7 +460,7 @@ F src/vacuum.c 33c174b28886b2faf26e503b5a49a1c01a9b1c16 F src/vdbe.c b1f2448184fa58c66fc94591004b1258964ef9da F src/vdbe.h 59998ffd71d7caa8886bc78dafaf8caeccd4c13c F src/vdbeInt.h 281cb70332dc8b593b8c7afe776f3a2ba7d4255e -F src/vdbeapi.c 9a44ed2f4fcb5a10dec9da5af95293d31830f268 +F src/vdbeapi.c 7a65f10684982daecfce50f557f2632b7f20b198 F src/vdbeaux.c 7c19b78999faae833e1be66dfa4e3deaf334d739 F src/vdbeblob.c 2b3d1ad915dbe5dc92c48759dc18fa8c697e78e5 F src/vdbemem.c 3b5a9a5b375458d3e12a50ae1aaa41eeec2175fd @@ -832,7 +832,7 @@ F test/gcfault.test dd28c228a38976d6336a3fc42d7e5f1ad060cb8c F test/genesis.tcl 1e2e2e8e5cc4058549a154ff1892fe5c9de19f98 F test/hexlit.test 4a6a5f46e3c65c4bf1fa06f5dd5a9507a5627751 F test/hidden.test 23c1393a79e846d68fd902d72c85d5e5dcf98711 -F test/hook.test 09b8ce2226776b10bf74344e67d81291a49801f6 +F test/hook.test f6a48d33817f0ca1a39a4d6605fe7e9da8077522 F test/icu.test 73956798bace8982909c00476b216714a6d0559a F test/ieee754.test 806fc0ce7f305f57e3331eaceeddcfec9339e607 F test/imposter1.test c3f1db2d3db2c24611a6596a3fc0ffc14f1466c8 @@ -1547,7 +1547,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 6fc4fbfa29cfa795edf32e4a1f2d0eceb3007f68 -R c06506894b1f7b9de189bb73f3ac7abf +P f66614dc78e32d2d369518200b3322cd97990ffe +R b9395615953abce115528c9bb805cca4 U dan -Z 47f4a5e852dc6941a6a828eee1ba5cee +Z c5b3bc3bd2550d6ddb6d6d5566bf3773 diff --git a/manifest.uuid b/manifest.uuid index 947e5dcd6a..5de3845661 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f66614dc78e32d2d369518200b3322cd97990ffe \ No newline at end of file +c7651d21bfdfd9b8cf04b26e0264bc58c03d247f \ No newline at end of file diff --git a/src/vdbeapi.c b/src/vdbeapi.c index 91edd34022..7ecdac87c3 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -1660,6 +1660,7 @@ static UnpackedRecord *vdbeUnpackRecord( */ int sqlite3_preupdate_old(sqlite3 *db, int iIdx, sqlite3_value **ppValue){ PreUpdate *p = db->pPreUpdate; + Mem *pMem; int rc = SQLITE_OK; /* Test that this call is being made from within an SQLITE_DELETE or @@ -1693,17 +1694,14 @@ int sqlite3_preupdate_old(sqlite3 *db, int iIdx, sqlite3_value **ppValue){ p->aRecord = aRec; } - if( iIdx>=p->pUnpacked->nField ){ + pMem = *ppValue = &p->pUnpacked->aMem[iIdx]; + if( iIdx==p->pTab->iPKey ){ + sqlite3VdbeMemSetInt64(pMem, p->iKey1); + }else if( iIdx>=p->pUnpacked->nField ){ *ppValue = (sqlite3_value *)columnNullValue(); - }else{ - Mem *pMem = *ppValue = &p->pUnpacked->aMem[iIdx]; - *ppValue = &p->pUnpacked->aMem[iIdx]; - if( iIdx==p->pTab->iPKey ){ - sqlite3VdbeMemSetInt64(pMem, p->iKey1); - }else if( p->pTab->aCol[iIdx].affinity==SQLITE_AFF_REAL ){ - if( pMem->flags & MEM_Int ){ - sqlite3VdbeMemRealify(pMem); - } + }else if( p->pTab->aCol[iIdx].affinity==SQLITE_AFF_REAL ){ + if( pMem->flags & MEM_Int ){ + sqlite3VdbeMemRealify(pMem); } } diff --git a/test/hook.test b/test/hook.test index c576449502..0c24ec7313 100644 --- a/test/hook.test +++ b/test/hook.test @@ -890,4 +890,19 @@ do_preupdate_test 9.6 { INSERT main t1 458 458 0 458 {} {} {} } + +do_execsql_test 10.0 { + CREATE TABLE t3(a, b INTEGER PRIMARY KEY); +} +do_preupdate_test 10.1 { + INSERT INTO t3 DEFAULT VALUES +} { + INSERT main t3 1 1 0 {} 1 +} +do_execsql_test 10.2 { SELECT * FROM t3 } {{} 1} +do_preupdate_test 10.3 { + DELETE FROM t3 WHERE b=1 +} {DELETE main t3 1 1 0 {} 1} + + finish_test From 87f500ce43c2fa0b5797b92149513c530a3983f6 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 26 Jan 2017 00:58:27 +0000 Subject: [PATCH 1236/1484] Modify the ICU extension to use a static initializer, as VC++ complains about a dynamic initialization. Maybe the dynamic structure initialization is a GCC extension. FossilOrigin-Name: 50e60cb44fd3687dde5551d02bad60c323beaabc --- ext/icu/icu.c | 44 +++++++++++++++++++++----------------------- manifest | 13 ++++++------- manifest.uuid | 2 +- 3 files changed, 28 insertions(+), 31 deletions(-) diff --git a/ext/icu/icu.c b/ext/icu/icu.c index d2beaa3353..50518d08a7 100644 --- a/ext/icu/icu.c +++ b/ext/icu/icu.c @@ -493,38 +493,36 @@ static void icuLoadCollation( ** Register the ICU extension functions with database db. */ int sqlite3IcuInit(sqlite3 *db){ - struct IcuScalar { + static const struct IcuScalar { const char *zName; /* Function name */ - int nArg; /* Number of arguments */ - int enc; /* Optimal text encoding */ - void *pContext; /* sqlite3_user_data() context */ + unsigned char nArg; /* Number of arguments */ + unsigned short enc; /* Optimal text encoding */ + unsigned char iContext; /* sqlite3_user_data() context */ void (*xFunc)(sqlite3_context*,int,sqlite3_value**); } scalars[] = { - {"regexp", 2, SQLITE_ANY|SQLITE_DETERMINISTIC, 0, icuRegexpFunc}, - - {"lower", 1, SQLITE_UTF16|SQLITE_DETERMINISTIC, 0, icuCaseFunc16}, - {"lower", 2, SQLITE_UTF16|SQLITE_DETERMINISTIC, 0, icuCaseFunc16}, - {"upper", 1, SQLITE_UTF16|SQLITE_DETERMINISTIC, (void*)1, icuCaseFunc16}, - {"upper", 2, SQLITE_UTF16|SQLITE_DETERMINISTIC, (void*)1, icuCaseFunc16}, - - {"lower", 1, SQLITE_UTF8|SQLITE_DETERMINISTIC, 0, icuCaseFunc16}, - {"lower", 2, SQLITE_UTF8|SQLITE_DETERMINISTIC, 0, icuCaseFunc16}, - {"upper", 1, SQLITE_UTF8|SQLITE_DETERMINISTIC, (void*)1, icuCaseFunc16}, - {"upper", 2, SQLITE_UTF8|SQLITE_DETERMINISTIC, (void*)1, icuCaseFunc16}, - - {"like", 2, SQLITE_UTF8|SQLITE_DETERMINISTIC, 0, icuLikeFunc}, - {"like", 3, SQLITE_UTF8|SQLITE_DETERMINISTIC, 0, icuLikeFunc}, - - {"icu_load_collation", 2, SQLITE_UTF8, (void*)db, icuLoadCollation}, + {"icu_load_collation", 2, SQLITE_UTF8, 255, icuLoadCollation}, + {"regexp", 2, SQLITE_ANY|SQLITE_DETERMINISTIC, 0, icuRegexpFunc}, + {"lower", 1, SQLITE_UTF16|SQLITE_DETERMINISTIC, 0, icuCaseFunc16}, + {"lower", 2, SQLITE_UTF16|SQLITE_DETERMINISTIC, 0, icuCaseFunc16}, + {"upper", 1, SQLITE_UTF16|SQLITE_DETERMINISTIC, 1, icuCaseFunc16}, + {"upper", 2, SQLITE_UTF16|SQLITE_DETERMINISTIC, 1, icuCaseFunc16}, + {"lower", 1, SQLITE_UTF8|SQLITE_DETERMINISTIC, 0, icuCaseFunc16}, + {"lower", 2, SQLITE_UTF8|SQLITE_DETERMINISTIC, 0, icuCaseFunc16}, + {"upper", 1, SQLITE_UTF8|SQLITE_DETERMINISTIC, 1, icuCaseFunc16}, + {"upper", 2, SQLITE_UTF8|SQLITE_DETERMINISTIC, 1, icuCaseFunc16}, + {"like", 2, SQLITE_UTF8|SQLITE_DETERMINISTIC, 0, icuLikeFunc}, + {"like", 3, SQLITE_UTF8|SQLITE_DETERMINISTIC, 0, icuLikeFunc}, }; - int rc = SQLITE_OK; int i; + for(i=0; rc==SQLITE_OK && i<(int)(sizeof(scalars)/sizeof(scalars[0])); i++){ - struct IcuScalar *p = &scalars[i]; + const struct IcuScalar *p = &scalars[i]; rc = sqlite3_create_function( - db, p->zName, p->nArg, p->enc, p->pContext, p->xFunc, 0, 0 + db, p->zName, p->nArg, p->enc, + p->iContext==255 ? (void*)db : (void*)(((char*)0)+p->iContext), + p->xFunc, 0, 0 ); } diff --git a/manifest b/manifest index b6cd8613f4..70cd2eef66 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Trim\sNULL\svalues\soff\sthe\send\sof\srecords\swhen\sthe\sSQLITE_ENABLE_TRIM_NULLS\ncompile-time\soption\sis\sused.\s\sIncrease\sthe\ssize\sof\sthe\sP5\soperand\sto\s16\sbits.\nFix\sa\sproblem\swith\sshort\srecords\sin\sthe\ssessions\sextension. -D 2017-01-25T20:55:11.502 +C Modify\sthe\sICU\sextension\sto\suse\sa\sstatic\sinitializer,\sas\sVC++\scomplains\sabout\na\sdynamic\sinitialization.\s\sMaybe\sthe\sdynamic\sstructure\sinitialization\sis\sa\nGCC\sextension. +D 2017-01-26T00:58:27.622 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -202,7 +202,7 @@ F ext/fts5/tool/loadfts5.tcl 95b03429ee6b138645703c6ca192c3ac96eaf093 F ext/fts5/tool/mkfts5c.tcl d1c2a9ab8e0ec690a52316f33dd9b1d379942f45 F ext/fts5/tool/showfts5.tcl d54da0e067306663e2d5d523965ca487698e722c F ext/icu/README.txt d9fbbad0c2f647c3fdf715fc9fd64af53aedfc43 -F ext/icu/icu.c 03ff6f90f3004a7e5a86205b581b2b7035ebf6e1 +F ext/icu/icu.c bae1dde13091b425bbed119a09a11aee14644764 F ext/icu/sqliteicu.h 728867a802baa5a96de7495e9689a8e01715ef37 F ext/misc/amatch.c 211108e201105e4bb0c076527b8cfd34330fc234 F ext/misc/carray.c 40c27641010a4dc67e3690bdb7c9d36ca58b3c2d @@ -1547,8 +1547,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 8cd1a4451cce1fe28f462800e2be1dee1735c0d0 c7651d21bfdfd9b8cf04b26e0264bc58c03d247f -R 97e00d1e041d69da0e0a6af8a75ee1a0 -T +closed c7651d21bfdfd9b8cf04b26e0264bc58c03d247f +P 4801bd59a01dcc11a3eb9e776e7599b36f162d2a +R 11380cdeca896e71dff2973b03351379 U drh -Z 857c1b54405ac0784389a22078eb728f +Z dca6dbb559e3b4e2e7d7b023b68a9123 diff --git a/manifest.uuid b/manifest.uuid index 854e8f8a47..6734156cad 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4801bd59a01dcc11a3eb9e776e7599b36f162d2a \ No newline at end of file +50e60cb44fd3687dde5551d02bad60c323beaabc \ No newline at end of file From 2b15f6e11bad7e8faeef497aadf6b5df8bf229c4 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 26 Jan 2017 01:54:39 +0000 Subject: [PATCH 1237/1484] Enhancements to the kvtest utility program. Add the --jmode option. Improved output formatting. FossilOrigin-Name: 62a4851ccf88837d1c16dae8204f7f264e80e3c9 --- manifest | 12 +++++----- manifest.uuid | 2 +- test/kvtest.c | 61 ++++++++++++++++++++++++++++++++++++--------------- 3 files changed, 50 insertions(+), 25 deletions(-) diff --git a/manifest b/manifest index 70cd2eef66..46dc00f8c4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Modify\sthe\sICU\sextension\sto\suse\sa\sstatic\sinitializer,\sas\sVC++\scomplains\sabout\na\sdynamic\sinitialization.\s\sMaybe\sthe\sdynamic\sstructure\sinitialization\sis\sa\nGCC\sextension. -D 2017-01-26T00:58:27.622 +C Enhancements\sto\sthe\skvtest\sutility\sprogram.\s\sAdd\sthe\s--jmode\soption.\s\nImproved\soutput\sformatting. +D 2017-01-26T01:54:39.591 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -898,7 +898,7 @@ F test/json101.test c0897616f32d95431f37fd291cb78742181980ac F test/json102.test bf3fe7a706d30936a76a0f7a0375e1e8e73aff5a F test/json103.test c5f6b85e69de05f6b3195f9f9d5ce9cd179099a0 F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff -F test/kvtest.c d2d7c434023498237cf731df21ca0687bf103858 +F test/kvtest.c dc6e5e9066fa5e19f7368c7dfbe8c6b9642a706f F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63 F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200 F test/like.test 0603f4fa0dad50987f70032c05800cbfa8985302 @@ -1547,7 +1547,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 4801bd59a01dcc11a3eb9e776e7599b36f162d2a -R 11380cdeca896e71dff2973b03351379 +P 50e60cb44fd3687dde5551d02bad60c323beaabc +R 6c49e01bee6ced9ad603e50cc8404852 U drh -Z dca6dbb559e3b4e2e7d7b023b68a9123 +Z 5b3363ef063097392f2b7107d7fe03e8 diff --git a/manifest.uuid b/manifest.uuid index 6734156cad..7d6c267913 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -50e60cb44fd3687dde5551d02bad60c323beaabc \ No newline at end of file +62a4851ccf88837d1c16dae8204f7f264e80e3c9 \ No newline at end of file diff --git a/test/kvtest.c b/test/kvtest.c index c82a3f899e..765a7ee968 100644 --- a/test/kvtest.c +++ b/test/kvtest.c @@ -79,16 +79,17 @@ static const char zHelp[] = " Run a performance test. DBFILE can be either the name of a\n" " database or a directory containing sample files. Options:\n" "\n" -" --asc Read blobs in ascending order\n" -" --blob-api Use the BLOB API\n" -" --cache-size N Database cache size\n" -" --count N Read N blobs\n" -" --desc Read blobs in descending order\n" -" --max-id N Maximum blob key to use\n" -" --mmap N Mmap as much as N bytes of DBFILE\n" -" --random Read blobs in a random order\n" -" --start N Start reading with this blob key\n" -" --stats Output operating stats before exiting\n" +" --asc Read blobs in ascending order\n" +" --blob-api Use the BLOB API\n" +" --cache-size N Database cache size\n" +" --count N Read N blobs\n" +" --desc Read blobs in descending order\n" +" --max-id N Maximum blob key to use\n" +" --mmap N Mmap as much as N bytes of DBFILE\n" +" --jmode MODE Set MODE journal mode prior to starting\n" +" --random Read blobs in a random order\n" +" --start N Start reading with this blob key\n" +" --stats Output operating stats before exiting\n" ; /* Reference resources used */ @@ -539,9 +540,6 @@ static int display_stats( displayLinuxIoStats(out); #endif - /* Do not remove this machine readable comment: extra-stats-output-here */ - - fprintf(out, "\n"); return 0; } @@ -562,7 +560,7 @@ static int runMain(int argc, char **argv){ int nCount = 1000; /* Number of blob fetch operations */ int nExtra = 0; /* Extra cycles */ int iKey = 1; /* Next blob key */ - int iMax = 1000; /* Largest allowed key */ + int iMax = 0; /* Largest allowed key */ int iPagesize = 0; /* Database page size */ int iCache = 1000; /* Database cache size in kibibytes */ int bBlobApi = 0; /* Use the incremental blob I/O API */ @@ -578,6 +576,7 @@ static int runMain(int argc, char **argv){ sqlite3_int64 nTotal = 0; /* Total data read */ unsigned char *pData = 0; /* Content of the blob */ int nAlloc = 0; /* Space allocated for pData[] */ + const char *zJMode = 0; /* Journal mode */ assert( strcmp(argv[1],"run")==0 ); @@ -605,7 +604,6 @@ static int runMain(int argc, char **argv){ if( strcmp(z, "-max-id")==0 ){ if( i==argc-1 ) fatalError("missing argument on \"%s\"", argv[i]); iMax = integerValue(argv[++i]); - if( iMax<1 ) fatalError("the --max-id must be positive"); continue; } if( strcmp(z, "-start")==0 ){ @@ -619,6 +617,11 @@ static int runMain(int argc, char **argv){ iCache = integerValue(argv[++i]); continue; } + if( strcmp(z, "-jmode")==0 ){ + if( i==argc-1 ) fatalError("missing argument on \"%s\"", argv[i]); + zJMode = argv[++i]; + continue; + } if( strcmp(z, "-random")==0 ){ eOrder = ORDER_RANDOM; continue; @@ -667,8 +670,29 @@ static int runMain(int argc, char **argv){ } sqlite3_finalize(pStmt); pStmt = 0; + if( zJMode ){ + zSql = sqlite3_mprintf("PRAGMA journal_mode=%Q", zJMode); + sqlite3_exec(db, zSql, 0, 0, 0); + sqlite3_free(zSql); + } + sqlite3_prepare_v2(db, "PRAGMA journal_mode", -1, &pStmt, 0); + if( sqlite3_step(pStmt)==SQLITE_ROW ){ + zJMode = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0)); + }else{ + zJMode = "???"; + } + sqlite3_finalize(pStmt); + if( iMax<=0 ){ + sqlite3_prepare_v2(db, "SELECT max(k) FROM kv", -1, &pStmt, 0); + if( sqlite3_step(pStmt)==SQLITE_ROW ){ + iMax = sqlite3_column_int(pStmt, 0); + } + sqlite3_finalize(pStmt); + } + pStmt = 0; sqlite3_exec(db, "BEGIN", 0, 0, 0); } + if( iMax<=0 ) iMax = 1000; for(i=0; i Date: Thu, 26 Jan 2017 02:26:02 +0000 Subject: [PATCH 1238/1484] Make SQLITE_DIRECT_OVERFLOW_READ work for in WAL mode as long as the page being read is not in the the -wal file. FossilOrigin-Name: 9879be1899adf5634f551a2077b15ccb1133e4e3 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/btree.c | 4 ++-- src/pager.c | 18 ++++++++++++------ src/pager.h | 6 ++++-- 5 files changed, 27 insertions(+), 19 deletions(-) diff --git a/manifest b/manifest index 46dc00f8c4..133861bb31 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhancements\sto\sthe\skvtest\sutility\sprogram.\s\sAdd\sthe\s--jmode\soption.\s\nImproved\soutput\sformatting. -D 2017-01-26T01:54:39.591 +C Make\sSQLITE_DIRECT_OVERFLOW_READ\swork\sfor\sin\sWAL\smode\sas\slong\sas\sthe\spage\nbeing\sread\sis\snot\sin\sthe\sthe\s-wal\sfile. +D 2017-01-26T02:26:02.936 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -333,7 +333,7 @@ F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792 F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca -F src/btree.c f1b36bcfb1f9532ce64fe534153f11b8e2595d8b +F src/btree.c 4a4ae5fd82ee576b85163277610d8b8174831f16 F src/btree.h e6d352808956ec163a17f832193a3e198b3fb0ac F src/btreeInt.h 10c4b77c2fb399580babbcc7cf652ac10dba796e F src/build.c 9e799f1edd910dfa8a0bc29bd390d35d310596af @@ -377,8 +377,8 @@ F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586 F src/os_unix.c 30e2c43e4955db990e5b5a81e901f8aa74cc8820 F src/os_win.c cf90abd4e50d9f56d2c20ce8e005aff55d7bd8e9 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a -F src/pager.c 9dc72d23eebbdf992bd69f2ab954d0d3a27c7340 -F src/pager.h d1e944291030351f362a0a7da9b5c3e34e603e39 +F src/pager.c ff1232b3088a39806035ecfac4fffeb22717d80b +F src/pager.h f2a99646c5533ffe11afa43e9e0bea74054e4efa F src/parse.y 29153738a7322054359320eb00b5a4cd44389f20 F src/pcache.c 51070ec9b8251bbf9c6ea3d35fd96a458752929e F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 @@ -1547,7 +1547,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 50e60cb44fd3687dde5551d02bad60c323beaabc -R 6c49e01bee6ced9ad603e50cc8404852 +P 62a4851ccf88837d1c16dae8204f7f264e80e3c9 +R 5def997b16301f95d47461ef6a1c2e30 U drh -Z 5b3363ef063097392f2b7107d7fe03e8 +Z c8beae43adff961172e88276d51d2aaf diff --git a/manifest.uuid b/manifest.uuid index 7d6c267913..3045549ece 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -62a4851ccf88837d1c16dae8204f7f264e80e3c9 \ No newline at end of file +9879be1899adf5634f551a2077b15ccb1133e4e3 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index b6bc66ea85..016e7f6cca 100644 --- a/src/btree.c +++ b/src/btree.c @@ -4593,7 +4593,7 @@ static int accessPayload( ** 2) data is required from the start of this overflow page, and ** 3) the database is file-backed, and ** 4) there is no open write-transaction, and - ** 5) the database is not a WAL database, + ** 5) the page is not in the WAL file ** 6) all data from the page is being read. ** 7) at least 4 bytes have already been read into the output buffer ** @@ -4606,7 +4606,7 @@ static int accessPayload( && (bEnd || a==ovflSize) /* (6) */ && pBt->inTransaction==TRANS_READ /* (4) */ && (fd = sqlite3PagerFile(pBt->pPager))->pMethods /* (3) */ - && 0==sqlite3PagerUseWal(pBt->pPager) /* (5) */ + && 0==sqlite3PagerUseWal(pBt->pPager, nextPage) /* (5) */ && &pBuf[-4]>=pBufStart /* (7) */ ){ u8 aSave[4]; diff --git a/src/pager.c b/src/pager.c index 5813b4db47..40c4dd9d88 100644 --- a/src/pager.c +++ b/src/pager.c @@ -814,14 +814,20 @@ static const unsigned char aJournalMagic[] = { #define isOpen(pFd) ((pFd)->pMethods!=0) /* -** Return true if this pager uses a write-ahead log instead of the usual -** rollback journal. Otherwise false. +** Return true if this pager uses a write-ahead log to read page pgno. +** Return false if the pager reads pgno directly from the database. */ -#ifndef SQLITE_OMIT_WAL -int sqlite3PagerUseWal(Pager *pPager){ - return (pPager->pWal!=0); +#if !defined(SQLITE_OMIT_WAL) && defined(SQLITE_DIRECT_OVERFLOW_READ) +int sqlite3PagerUseWal(Pager *pPager, Pgno pgno){ + u32 iRead = 0; + int rc; + if( pPager->pWal==0 ) return 0; + rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iRead); + return rc || iRead; } -# define pagerUseWal(x) sqlite3PagerUseWal(x) +#endif +#ifndef SQLITE_OMIT_WAL +# define pagerUseWal(x) ((x)->pWal!=0) #else # define pagerUseWal(x) 0 # define pagerRollbackWal(x) 0 diff --git a/src/pager.h b/src/pager.h index dd57f598bd..585ef29497 100644 --- a/src/pager.h +++ b/src/pager.h @@ -178,14 +178,16 @@ int sqlite3PagerSharedLock(Pager *pPager); int sqlite3PagerWalCallback(Pager *pPager); int sqlite3PagerOpenWal(Pager *pPager, int *pisOpen); int sqlite3PagerCloseWal(Pager *pPager, sqlite3*); - int sqlite3PagerUseWal(Pager *pPager); +# ifdef SQLITE_DIRECT_OVERFLOW_READ + int sqlite3PagerUseWal(Pager *pPager, Pgno); +# endif # ifdef SQLITE_ENABLE_SNAPSHOT int sqlite3PagerSnapshotGet(Pager *pPager, sqlite3_snapshot **ppSnapshot); int sqlite3PagerSnapshotOpen(Pager *pPager, sqlite3_snapshot *pSnapshot); int sqlite3PagerSnapshotRecover(Pager *pPager); # endif #else -# define sqlite3PagerUseWal(x) 0 +# define sqlite3PagerUseWal(x,y) 0 #endif #ifdef SQLITE_ENABLE_ZIPVFS From 8bb9fd3b457559e3dfee0b1fecf6ce7826de2636 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 26 Jan 2017 16:27:32 +0000 Subject: [PATCH 1239/1484] Minor simplification and performance optimization for Direct Overflow Read. FossilOrigin-Name: 3e96d6efa867b765c8acf1454014b1e71b2e4f21 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btree.c | 24 +++++++++--------------- 3 files changed, 16 insertions(+), 22 deletions(-) diff --git a/manifest b/manifest index 133861bb31..90d70de805 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\sSQLITE_DIRECT_OVERFLOW_READ\swork\sfor\sin\sWAL\smode\sas\slong\sas\sthe\spage\nbeing\sread\sis\snot\sin\sthe\sthe\s-wal\sfile. -D 2017-01-26T02:26:02.936 +C Minor\ssimplification\sand\sperformance\soptimization\sfor\sDirect\sOverflow\sRead. +D 2017-01-26T16:27:32.813 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -333,7 +333,7 @@ F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792 F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca -F src/btree.c 4a4ae5fd82ee576b85163277610d8b8174831f16 +F src/btree.c a168da7c4fff00dbd939c49ad4445d378eff1b11 F src/btree.h e6d352808956ec163a17f832193a3e198b3fb0ac F src/btreeInt.h 10c4b77c2fb399580babbcc7cf652ac10dba796e F src/build.c 9e799f1edd910dfa8a0bc29bd390d35d310596af @@ -1547,7 +1547,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 62a4851ccf88837d1c16dae8204f7f264e80e3c9 -R 5def997b16301f95d47461ef6a1c2e30 +P 9879be1899adf5634f551a2077b15ccb1133e4e3 +R d7cd9a6ab86d59aef41165d7cf109b11 U drh -Z c8beae43adff961172e88276d51d2aaf +Z 50b1b915cab08ae10917e730aa3424e6 diff --git a/manifest.uuid b/manifest.uuid index 3045549ece..d3b805d95a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9879be1899adf5634f551a2077b15ccb1133e4e3 \ No newline at end of file +3e96d6efa867b765c8acf1454014b1e71b2e4f21 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 016e7f6cca..3150026a58 100644 --- a/src/btree.c +++ b/src/btree.c @@ -4460,8 +4460,7 @@ static int accessPayload( MemPage *pPage = pCur->apPage[pCur->iPage]; /* Btree page of current entry */ BtShared *pBt = pCur->pBt; /* Btree this cursor belongs to */ #ifdef SQLITE_DIRECT_OVERFLOW_READ - unsigned char * const pBufStart = pBuf; - int bEnd; /* True if reading to end of data */ + unsigned char * const pBufStart = pBuf; /* Start of original out buffer */ #endif assert( pPage ); @@ -4472,9 +4471,6 @@ static int accessPayload( getCellInfo(pCur); aPayload = pCur->info.pPayload; -#ifdef SQLITE_DIRECT_OVERFLOW_READ - bEnd = offset+amt==pCur->info.nPayload; -#endif assert( offset+amt <= pCur->info.nPayload ); assert( aPayload > pPage->aData ); @@ -4579,7 +4575,7 @@ static int accessPayload( ** range of data that is being read (eOp==0) or written (eOp!=0). */ #ifdef SQLITE_DIRECT_OVERFLOW_READ - sqlite3_file *fd; + sqlite3_file *fd; /* File from which to do direct overflow read */ #endif int a = amt; if( a + offset > ovflSize ){ @@ -4591,11 +4587,10 @@ static int accessPayload( ** ** 1) this is a read operation, and ** 2) data is required from the start of this overflow page, and - ** 3) the database is file-backed, and - ** 4) there is no open write-transaction, and + ** 3) there is no open write-transaction, and + ** 4) the database is file-backed, and ** 5) the page is not in the WAL file - ** 6) all data from the page is being read. - ** 7) at least 4 bytes have already been read into the output buffer + ** 6) at least 4 bytes have already been read into the output buffer ** ** then data can be read directly from the database file into the ** output buffer, bypassing the page-cache altogether. This speeds @@ -4603,15 +4598,14 @@ static int accessPayload( */ if( (eOp&0x01)==0 /* (1) */ && offset==0 /* (2) */ - && (bEnd || a==ovflSize) /* (6) */ - && pBt->inTransaction==TRANS_READ /* (4) */ - && (fd = sqlite3PagerFile(pBt->pPager))->pMethods /* (3) */ + && pBt->inTransaction==TRANS_READ /* (3) */ + && (fd = sqlite3PagerFile(pBt->pPager))->pMethods /* (4) */ && 0==sqlite3PagerUseWal(pBt->pPager, nextPage) /* (5) */ - && &pBuf[-4]>=pBufStart /* (7) */ + && &pBuf[-4]>=pBufStart /* (6) */ ){ u8 aSave[4]; u8 *aWrite = &pBuf[-4]; - assert( aWrite>=pBufStart ); /* hence (7) */ + assert( aWrite>=pBufStart ); /* due to (6) */ memcpy(aSave, aWrite, 4); rc = sqlite3OsRead(fd, aWrite, a+4, (i64)pBt->pageSize*(nextPage-1)); nextPage = get4byte(aWrite); From 83ec2761faa8e84345aa43927d2de73b0c96131f Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 26 Jan 2017 16:54:47 +0000 Subject: [PATCH 1240/1484] Performance optimization to sqlite3_blob_read(). FossilOrigin-Name: 7459f4b7ed4007d9ec44c3bf0fcba04f5f8540a9 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btree.c | 27 ++++++++++++++++++++------- 3 files changed, 27 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index 90d70de805..54fc47c9d1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Minor\ssimplification\sand\sperformance\soptimization\sfor\sDirect\sOverflow\sRead. -D 2017-01-26T16:27:32.813 +C Performance\soptimization\sto\ssqlite3_blob_read(). +D 2017-01-26T16:54:47.281 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -333,7 +333,7 @@ F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792 F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca -F src/btree.c a168da7c4fff00dbd939c49ad4445d378eff1b11 +F src/btree.c 6fe6a5853148b623c4f5e288ae916180632ebbd3 F src/btree.h e6d352808956ec163a17f832193a3e198b3fb0ac F src/btreeInt.h 10c4b77c2fb399580babbcc7cf652ac10dba796e F src/build.c 9e799f1edd910dfa8a0bc29bd390d35d310596af @@ -1547,7 +1547,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 9879be1899adf5634f551a2077b15ccb1133e4e3 -R d7cd9a6ab86d59aef41165d7cf109b11 +P 3e96d6efa867b765c8acf1454014b1e71b2e4f21 +R 252dcd60be80c6c5c6ba84d2de14b6df U drh -Z 50b1b915cab08ae10917e730aa3424e6 +Z 39fbcc21c34e29a424df0af03b3f8d43 diff --git a/manifest.uuid b/manifest.uuid index d3b805d95a..051cfd0da2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3e96d6efa867b765c8acf1454014b1e71b2e4f21 \ No newline at end of file +7459f4b7ed4007d9ec44c3bf0fcba04f5f8540a9 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 3150026a58..0a2106e04b 100644 --- a/src/btree.c +++ b/src/btree.c @@ -4665,21 +4665,34 @@ int sqlite3BtreePayload(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){ assert( pCur->aiIdx[pCur->iPage]apPage[pCur->iPage]->nCell ); return accessPayload(pCur, offset, amt, (unsigned char*)pBuf, 0); } + +/* +** This variant of sqlite3BtreePayload() works even if the cursor has not +** in the CURSOR_VALID state. It is only used by the sqlite3_blob_read() +** interface. +*/ #ifndef SQLITE_OMIT_INCRBLOB -int sqlite3BtreePayloadChecked(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){ +static SQLITE_NOINLINE int accessPayloadChecked( + BtCursor *pCur, + u32 offset, + u32 amt, + void *pBuf +){ int rc; if ( pCur->eState==CURSOR_INVALID ){ return SQLITE_ABORT; } assert( cursorOwnsBtShared(pCur) ); rc = restoreCursorPosition(pCur); - if( rc==SQLITE_OK ){ - assert( pCur->eState==CURSOR_VALID ); - assert( pCur->iPage>=0 && pCur->apPage[pCur->iPage] ); - assert( pCur->aiIdx[pCur->iPage]apPage[pCur->iPage]->nCell ); - rc = accessPayload(pCur, offset, amt, pBuf, 0); + return rc ? rc : accessPayload(pCur, offset, amt, pBuf, 0); +} +int sqlite3BtreePayloadChecked(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){ + if( pCur->eState==CURSOR_VALID ){ + assert( cursorOwnsBtShared(pCur) ); + return accessPayload(pCur, offset, amt, pBuf, 0); + }else{ + return accessPayloadChecked(pCur, offset, amt, pBuf); } - return rc; } #endif /* SQLITE_OMIT_INCRBLOB */ From d08406477afd21551ea6caadfb70c63a4dab23be Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 26 Jan 2017 17:11:18 +0000 Subject: [PATCH 1241/1484] Performance optimization in sqlite3VdbeCloseStatement(). FossilOrigin-Name: 1e96e5ec1ee617cb5b5cbdc5a2ee79c8cc35821d --- manifest | 12 ++++---- manifest.uuid | 2 +- src/vdbeaux.c | 77 +++++++++++++++++++++++++-------------------------- 3 files changed, 45 insertions(+), 46 deletions(-) diff --git a/manifest b/manifest index 54fc47c9d1..11ce60cdc3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Performance\soptimization\sto\ssqlite3_blob_read(). -D 2017-01-26T16:54:47.281 +C Performance\soptimization\sin\ssqlite3VdbeCloseStatement(). +D 2017-01-26T17:11:18.355 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -461,7 +461,7 @@ F src/vdbe.c 1fa3e8f3ee1cdfc56d9559bca9ca2c84e4a398be F src/vdbe.h 59998ffd71d7caa8886bc78dafaf8caeccd4c13c F src/vdbeInt.h 281cb70332dc8b593b8c7afe776f3a2ba7d4255e F src/vdbeapi.c 7a65f10684982daecfce50f557f2632b7f20b198 -F src/vdbeaux.c 7c19b78999faae833e1be66dfa4e3deaf334d739 +F src/vdbeaux.c 6847b02aa2db536ed15d90f1fdc2923afef93c5b F src/vdbeblob.c 2b3d1ad915dbe5dc92c48759dc18fa8c697e78e5 F src/vdbemem.c 3b5a9a5b375458d3e12a50ae1aaa41eeec2175fd F src/vdbesort.c eda25cb2d1727efca6f7862fea32b8aa33c0face @@ -1547,7 +1547,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 3e96d6efa867b765c8acf1454014b1e71b2e4f21 -R 252dcd60be80c6c5c6ba84d2de14b6df +P 7459f4b7ed4007d9ec44c3bf0fcba04f5f8540a9 +R b420e83a1f23766d77baebce9b33f9ae U drh -Z 39fbcc21c34e29a424df0af03b3f8d43 +Z 2c16f151f6d1962e9b2a5835576e2c7c diff --git a/manifest.uuid b/manifest.uuid index 051cfd0da2..9f15fbe8cb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7459f4b7ed4007d9ec44c3bf0fcba04f5f8540a9 \ No newline at end of file +1e96e5ec1ee617cb5b5cbdc5a2ee79c8cc35821d \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 44f2ad38f4..23c31d4029 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -2497,60 +2497,59 @@ static void checkActiveVdbeCnt(sqlite3 *db){ ** If an IO error occurs, an SQLITE_IOERR_XXX error code is returned. ** Otherwise SQLITE_OK. */ -int sqlite3VdbeCloseStatement(Vdbe *p, int eOp){ +static SQLITE_NOINLINE int vdbeCloseStatement(Vdbe *p, int eOp){ sqlite3 *const db = p->db; int rc = SQLITE_OK; + int i; + const int iSavepoint = p->iStatement-1; - /* If p->iStatement is greater than zero, then this Vdbe opened a - ** statement transaction that should be closed here. The only exception - ** is that an IO error may have occurred, causing an emergency rollback. - ** In this case (db->nStatement==0), and there is nothing to do. - */ - if( db->nStatement && p->iStatement ){ - int i; - const int iSavepoint = p->iStatement-1; + assert( eOp==SAVEPOINT_ROLLBACK || eOp==SAVEPOINT_RELEASE); + assert( db->nStatement>0 ); + assert( p->iStatement==(db->nStatement+db->nSavepoint) ); - assert( eOp==SAVEPOINT_ROLLBACK || eOp==SAVEPOINT_RELEASE); - assert( db->nStatement>0 ); - assert( p->iStatement==(db->nStatement+db->nSavepoint) ); - - for(i=0; inDb; i++){ - int rc2 = SQLITE_OK; - Btree *pBt = db->aDb[i].pBt; - if( pBt ){ - if( eOp==SAVEPOINT_ROLLBACK ){ - rc2 = sqlite3BtreeSavepoint(pBt, SAVEPOINT_ROLLBACK, iSavepoint); - } - if( rc2==SQLITE_OK ){ - rc2 = sqlite3BtreeSavepoint(pBt, SAVEPOINT_RELEASE, iSavepoint); - } - if( rc==SQLITE_OK ){ - rc = rc2; - } - } - } - db->nStatement--; - p->iStatement = 0; - - if( rc==SQLITE_OK ){ + for(i=0; inDb; i++){ + int rc2 = SQLITE_OK; + Btree *pBt = db->aDb[i].pBt; + if( pBt ){ if( eOp==SAVEPOINT_ROLLBACK ){ - rc = sqlite3VtabSavepoint(db, SAVEPOINT_ROLLBACK, iSavepoint); + rc2 = sqlite3BtreeSavepoint(pBt, SAVEPOINT_ROLLBACK, iSavepoint); + } + if( rc2==SQLITE_OK ){ + rc2 = sqlite3BtreeSavepoint(pBt, SAVEPOINT_RELEASE, iSavepoint); } if( rc==SQLITE_OK ){ - rc = sqlite3VtabSavepoint(db, SAVEPOINT_RELEASE, iSavepoint); + rc = rc2; } } + } + db->nStatement--; + p->iStatement = 0; - /* If the statement transaction is being rolled back, also restore the - ** database handles deferred constraint counter to the value it had when - ** the statement transaction was opened. */ + if( rc==SQLITE_OK ){ if( eOp==SAVEPOINT_ROLLBACK ){ - db->nDeferredCons = p->nStmtDefCons; - db->nDeferredImmCons = p->nStmtDefImmCons; + rc = sqlite3VtabSavepoint(db, SAVEPOINT_ROLLBACK, iSavepoint); } + if( rc==SQLITE_OK ){ + rc = sqlite3VtabSavepoint(db, SAVEPOINT_RELEASE, iSavepoint); + } + } + + /* If the statement transaction is being rolled back, also restore the + ** database handles deferred constraint counter to the value it had when + ** the statement transaction was opened. */ + if( eOp==SAVEPOINT_ROLLBACK ){ + db->nDeferredCons = p->nStmtDefCons; + db->nDeferredImmCons = p->nStmtDefImmCons; } return rc; } +int sqlite3VdbeCloseStatement(Vdbe *p, int eOp){ + if( p->db->nStatement && p->iStatement ){ + return vdbeCloseStatement(p, eOp); + } + return SQLITE_OK; +} + /* ** This function is called when a transaction opened by the database From fae58d51cee559af3c71860dce26ee0007f4780d Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 26 Jan 2017 17:26:44 +0000 Subject: [PATCH 1242/1484] Remove the obsolete lastRowid cache from the sqlite3VdbeExec() for a size reduction and performance improvement. FossilOrigin-Name: b4803184652e5f4f823c1521412bc480baeb3dbf --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 11 +++-------- 3 files changed, 10 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index 11ce60cdc3..2bd3d3e394 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Performance\soptimization\sin\ssqlite3VdbeCloseStatement(). -D 2017-01-26T17:11:18.355 +C Remove\sthe\sobsolete\slastRowid\scache\sfrom\sthe\ssqlite3VdbeExec()\sfor\sa\ssize\nreduction\sand\sperformance\simprovement. +D 2017-01-26T17:26:44.998 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -457,7 +457,7 @@ F src/update.c b356b29d04c71f33c779f2cb557cf953819bdd7a F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c a88b0466fddf445ce752226d4698ca3faada620a F src/vacuum.c 33c174b28886b2faf26e503b5a49a1c01a9b1c16 -F src/vdbe.c 1fa3e8f3ee1cdfc56d9559bca9ca2c84e4a398be +F src/vdbe.c 96f1639399feb97500d927219b87183aad3ef94c F src/vdbe.h 59998ffd71d7caa8886bc78dafaf8caeccd4c13c F src/vdbeInt.h 281cb70332dc8b593b8c7afe776f3a2ba7d4255e F src/vdbeapi.c 7a65f10684982daecfce50f557f2632b7f20b198 @@ -1547,7 +1547,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 7459f4b7ed4007d9ec44c3bf0fcba04f5f8540a9 -R b420e83a1f23766d77baebce9b33f9ae +P 1e96e5ec1ee617cb5b5cbdc5a2ee79c8cc35821d +R f17134692e3127e9f97d9e12f2b91a46 U drh -Z 2c16f151f6d1962e9b2a5835576e2c7c +Z 7f3d9d2e9e1038bd56eb8c4623402887 diff --git a/manifest.uuid b/manifest.uuid index 9f15fbe8cb..313588dfbb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1e96e5ec1ee617cb5b5cbdc5a2ee79c8cc35821d \ No newline at end of file +b4803184652e5f4f823c1521412bc480baeb3dbf \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 6838acccd5..afb23007c6 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -584,7 +584,6 @@ int sqlite3VdbeExec( Mem *pIn3 = 0; /* 3rd input operand */ Mem *pOut = 0; /* Output operand */ int *aPermute = 0; /* Permutation of columns for OP_Compare */ - i64 lastRowid = db->lastRowid; /* Saved value of the last insert ROWID */ #ifdef VDBE_PROFILE u64 start; /* CPU clock count at start of opcode */ #endif @@ -960,7 +959,6 @@ case OP_Halt: { p->nFrame--; sqlite3VdbeSetChanges(db, p->nChange); pcx = sqlite3VdbeFrameRestore(pFrame); - lastRowid = db->lastRowid; if( pOp->p2==OE_Ignore ){ /* Instruction pcx is the OP_Program that invoked the sub-program ** currently being halted. If the p2 instruction of this OP_Halt @@ -1682,9 +1680,7 @@ case OP_Function: { #endif MemSetTypeFlag(pCtx->pOut, MEM_Null); pCtx->fErrorOrAux = 0; - db->lastRowid = lastRowid; (*pCtx->pFunc->xSFunc)(pCtx, pCtx->argc, pCtx->argv);/* IMP: R-24505-23230 */ - lastRowid = db->lastRowid; /* Remember rowid changes made by xSFunc */ /* If the function returned an error, throw an exception */ if( pCtx->fErrorOrAux ){ @@ -4418,7 +4414,7 @@ case OP_InsertInt: { #endif if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++; - if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = lastRowid = x.nKey; + if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = x.nKey; if( pData->flags & MEM_Null ){ x.pData = 0; x.nData = 0; @@ -5863,7 +5859,7 @@ case OP_Program: { /* jump */ p->nFrame++; pFrame->pParent = p->pFrame; - pFrame->lastRowid = lastRowid; + pFrame->lastRowid = db->lastRowid; pFrame->nChange = p->nChange; pFrame->nDbChange = p->db->nChange; assert( pFrame->pAuxData==0 ); @@ -6804,7 +6800,7 @@ case OP_VUpdate: { sqlite3VtabImportErrmsg(p, pVtab); if( rc==SQLITE_OK && pOp->p1 ){ assert( nArg>1 && apArg[0] && (apArg[0]->flags&MEM_Null) ); - db->lastRowid = lastRowid = rowid; + db->lastRowid = rowid; } if( (rc&0xff)==SQLITE_CONSTRAINT && pOp->p4.pVtab->bConstraint ){ if( pOp->p5==OE_Ignore ){ @@ -7040,7 +7036,6 @@ abort_due_to_error: ** release the mutexes on btrees that were acquired at the ** top. */ vdbe_return: - db->lastRowid = lastRowid; testcase( nVmStep>0 ); p->aCounter[SQLITE_STMTSTATUS_VM_STEP] += (int)nVmStep; sqlite3VdbeLeave(p); From b7dab70a92e243559a97e6dbc7c81d930a6c46aa Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 26 Jan 2017 18:00:00 +0000 Subject: [PATCH 1243/1484] Improvement to the OP_Permutation opcode to prevent it from using CPU cycles for initialization in prepared statements that do not use that opcode. FossilOrigin-Name: b4a98f65564a0d9fba2fef95ebd00a39b3e1e572 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 20 ++++++++++++++------ 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 2bd3d3e394..f2f739774b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sthe\sobsolete\slastRowid\scache\sfrom\sthe\ssqlite3VdbeExec()\sfor\sa\ssize\nreduction\sand\sperformance\simprovement. -D 2017-01-26T17:26:44.998 +C Improvement\sto\sthe\sOP_Permutation\sopcode\sto\sprevent\sit\sfrom\susing\sCPU\scycles\nfor\sinitialization\sin\sprepared\sstatements\sthat\sdo\snot\suse\sthat\sopcode. +D 2017-01-26T18:00:00.328 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -457,7 +457,7 @@ F src/update.c b356b29d04c71f33c779f2cb557cf953819bdd7a F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c a88b0466fddf445ce752226d4698ca3faada620a F src/vacuum.c 33c174b28886b2faf26e503b5a49a1c01a9b1c16 -F src/vdbe.c 96f1639399feb97500d927219b87183aad3ef94c +F src/vdbe.c c27cc34be1d9169c1c191238025781684bdcd4ec F src/vdbe.h 59998ffd71d7caa8886bc78dafaf8caeccd4c13c F src/vdbeInt.h 281cb70332dc8b593b8c7afe776f3a2ba7d4255e F src/vdbeapi.c 7a65f10684982daecfce50f557f2632b7f20b198 @@ -1547,7 +1547,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 1e96e5ec1ee617cb5b5cbdc5a2ee79c8cc35821d -R f17134692e3127e9f97d9e12f2b91a46 +P b4803184652e5f4f823c1521412bc480baeb3dbf +R 5d2cc4b6c4ee841c772ca9230a25766d U drh -Z 7f3d9d2e9e1038bd56eb8c4623402887 +Z 39169c59805d0271c33a4d8ecd6430ca diff --git a/manifest.uuid b/manifest.uuid index 313588dfbb..bf55d47b01 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b4803184652e5f4f823c1521412bc480baeb3dbf \ No newline at end of file +b4a98f65564a0d9fba2fef95ebd00a39b3e1e572 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index afb23007c6..ded4462398 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -583,7 +583,6 @@ int sqlite3VdbeExec( Mem *pIn2 = 0; /* 2nd input operand */ Mem *pIn3 = 0; /* 3rd input operand */ Mem *pOut = 0; /* Output operand */ - int *aPermute = 0; /* Permutation of columns for OP_Compare */ #ifdef VDBE_PROFILE u64 start; /* CPU clock count at start of opcode */ #endif @@ -2136,8 +2135,8 @@ case OP_ElseNotEq: { /* same as TK_ESCAPE, jump */ /* Opcode: Permutation * * * P4 * ** -** Set the permutation used by the OP_Compare operator to be the array -** of integers in P4. +** Set the permutation used by the OP_Compare operator in the next +** instruction. The permutation is stored in the P4 operand. ** ** The permutation is only valid until the next OP_Compare that has ** the OPFLAG_PERMUTE bit set in P5. Typically the OP_Permutation should @@ -2149,7 +2148,8 @@ case OP_ElseNotEq: { /* same as TK_ESCAPE, jump */ case OP_Permutation: { assert( pOp->p4type==P4_INTARRAY ); assert( pOp->p4.ai ); - aPermute = pOp->p4.ai + 1; + assert( pOp[1].opcode==OP_Compare ); + assert( pOp[1].p5 & OPFLAG_PERMUTE ); break; } @@ -2182,8 +2182,17 @@ case OP_Compare: { int idx; CollSeq *pColl; /* Collating sequence to use on this term */ int bRev; /* True for DESCENDING sort order */ + int *aPermute; /* The permutation */ - if( (pOp->p5 & OPFLAG_PERMUTE)==0 ) aPermute = 0; + if( (pOp->p5 & OPFLAG_PERMUTE)==0 ){ + aPermute = 0; + }else{ + assert( pOp>aOp ); + assert( pOp[-1].opcode==OP_Permutation ); + assert( pOp[-1].p4type==P4_INTARRAY ); + aPermute = pOp[-1].p4.ai + 1; + assert( aPermute!=0 ); + } n = pOp->p3; pKeyInfo = pOp->p4.pKeyInfo; assert( n>0 ); @@ -2216,7 +2225,6 @@ case OP_Compare: { break; } } - aPermute = 0; break; } From 945b094632adb0bc835f4dacca84c7e3f7883dc6 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 26 Jan 2017 21:30:00 +0000 Subject: [PATCH 1244/1484] Remove an unreachable branch in the error handling logic for sqlite3BtreePayloadChecked(). FossilOrigin-Name: 293bf3ed7e40745349c83b202b27ed1b48517e1a --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btree.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index f2f739774b..1a7e283a21 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improvement\sto\sthe\sOP_Permutation\sopcode\sto\sprevent\sit\sfrom\susing\sCPU\scycles\nfor\sinitialization\sin\sprepared\sstatements\sthat\sdo\snot\suse\sthat\sopcode. -D 2017-01-26T18:00:00.328 +C Remove\san\sunreachable\sbranch\sin\sthe\serror\shandling\slogic\sfor\nsqlite3BtreePayloadChecked(). +D 2017-01-26T21:30:00.788 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -333,7 +333,7 @@ F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792 F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca -F src/btree.c 6fe6a5853148b623c4f5e288ae916180632ebbd3 +F src/btree.c bd72bb69abc7f3f3513308b9dd3749194b5d66d1 F src/btree.h e6d352808956ec163a17f832193a3e198b3fb0ac F src/btreeInt.h 10c4b77c2fb399580babbcc7cf652ac10dba796e F src/build.c 9e799f1edd910dfa8a0bc29bd390d35d310596af @@ -1547,7 +1547,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b4803184652e5f4f823c1521412bc480baeb3dbf -R 5d2cc4b6c4ee841c772ca9230a25766d +P b4a98f65564a0d9fba2fef95ebd00a39b3e1e572 +R 9abdd03cd61c16f0272c0fd74c72cba7 U drh -Z 39169c59805d0271c33a4d8ecd6430ca +Z 4b9455997c313589c1136c73cb07a07d diff --git a/manifest.uuid b/manifest.uuid index bf55d47b01..f992289f01 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b4a98f65564a0d9fba2fef95ebd00a39b3e1e572 \ No newline at end of file +293bf3ed7e40745349c83b202b27ed1b48517e1a \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 0a2106e04b..e4a7aa160f 100644 --- a/src/btree.c +++ b/src/btree.c @@ -4683,7 +4683,7 @@ static SQLITE_NOINLINE int accessPayloadChecked( return SQLITE_ABORT; } assert( cursorOwnsBtShared(pCur) ); - rc = restoreCursorPosition(pCur); + rc = btreeRestoreCursorPosition(pCur); return rc ? rc : accessPayload(pCur, offset, amt, pBuf, 0); } int sqlite3BtreePayloadChecked(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){ From 42e28f12a31d38c22163b782dde53df195d894f3 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 27 Jan 2017 00:31:59 +0000 Subject: [PATCH 1245/1484] Simplify the accessPayload() routine so that it always populates the overflow page cache. In the one case where populating the page cache can lead to problems, simply invalidate the cache as soon as accessPayload() returns. This simplification reduces code size and helps accessPayload() to run a little faster. This backs out the eOp==2 mode of accessPayload() added by check-in [da59198505]. FossilOrigin-Name: 68e7a8c6765649195ef1ad9407d87d44a307b462 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btree.c | 43 +++++++++++++++++-------------------------- 3 files changed, 24 insertions(+), 33 deletions(-) diff --git a/manifest b/manifest index 1a7e283a21..0ab648517f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\san\sunreachable\sbranch\sin\sthe\serror\shandling\slogic\sfor\nsqlite3BtreePayloadChecked(). -D 2017-01-26T21:30:00.788 +C Simplify\sthe\saccessPayload()\sroutine\sso\sthat\sit\salways\spopulates\sthe\soverflow\npage\scache.\s\sIn\sthe\sone\scase\swhere\spopulating\sthe\spage\scache\scan\slead\sto\s\nproblems,\ssimply\sinvalidate\sthe\scache\sas\ssoon\sas\saccessPayload()\sreturns.\s\s\nThis\ssimplification\sreduces\scode\ssize\sand\shelps\saccessPayload()\sto\srun\sa\s\nlittle\sfaster.\s\sThis\sbacks\sout\sthe\seOp==2\smode\sof\saccessPayload()\sadded\sby\s\ncheck-in\s[da59198505]. +D 2017-01-27T00:31:59.289 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -333,7 +333,7 @@ F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792 F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca -F src/btree.c bd72bb69abc7f3f3513308b9dd3749194b5d66d1 +F src/btree.c d42f290214e6615020b61866fe0747f02614964e F src/btree.h e6d352808956ec163a17f832193a3e198b3fb0ac F src/btreeInt.h 10c4b77c2fb399580babbcc7cf652ac10dba796e F src/build.c 9e799f1edd910dfa8a0bc29bd390d35d310596af @@ -1547,7 +1547,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b4a98f65564a0d9fba2fef95ebd00a39b3e1e572 -R 9abdd03cd61c16f0272c0fd74c72cba7 +P 293bf3ed7e40745349c83b202b27ed1b48517e1a +R ec063431f8eb3294f488a586b69214cb U drh -Z 4b9455997c313589c1136c73cb07a07d +Z 81eb07f579988e3e7128daaaea36d064 diff --git a/manifest.uuid b/manifest.uuid index f992289f01..6d62a1cc6d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -293bf3ed7e40745349c83b202b27ed1b48517e1a \ No newline at end of file +68e7a8c6765649195ef1ad9407d87d44a307b462 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index e4a7aa160f..2575c774cf 100644 --- a/src/btree.c +++ b/src/btree.c @@ -4424,7 +4424,6 @@ static int copyPayload( ** ** 0: The operation is a read. Populate the overflow cache. ** 1: The operation is a write. Populate the overflow cache. -** 2: The operation is a read. Do not populate the overflow cache. ** ** A total of "amt" bytes are read or written beginning at "offset". ** Data is read to or from the buffer pBuf. @@ -4432,13 +4431,13 @@ static int copyPayload( ** The content being read or written might appear on the main page ** or be scattered out on multiple overflow pages. ** -** If the current cursor entry uses one or more overflow pages and the -** eOp argument is not 2, this function may allocate space for and lazily -** populates the overflow page-list cache array (BtCursor.aOverflow). +** If the current cursor entry uses one or more overflow pages +** this function may allocate space for and lazily populate +** the overflow page-list cache array (BtCursor.aOverflow). ** Subsequent calls use this cache to make seeking to the supplied offset ** more efficient. ** -** Once an overflow page-list cache has been allocated, it may be +** Once an overflow page-list cache has been allocated, it must be ** invalidated if some other cursor writes to the same table, or if ** the cursor is moved to a different row. Additionally, in auto-vacuum ** mode, the following events may invalidate an overflow page-list cache. @@ -4464,10 +4463,10 @@ static int accessPayload( #endif assert( pPage ); + assert( eOp==0 || eOp==1 ); assert( pCur->eState==CURSOR_VALID ); assert( pCur->aiIdx[pCur->iPage]nCell ); assert( cursorHoldsMutex(pCur) ); - assert( eOp!=2 || offset==0 ); /* Always start from beginning for eOp==2 */ getCellInfo(pCur); aPayload = pCur->info.pPayload; @@ -4489,7 +4488,7 @@ static int accessPayload( if( a+offset>pCur->info.nLocal ){ a = pCur->info.nLocal - offset; } - rc = copyPayload(&aPayload[offset], pBuf, a, (eOp & 0x01), pPage->pDbPage); + rc = copyPayload(&aPayload[offset], pBuf, a, eOp, pPage->pDbPage); offset = 0; pBuf += a; amt -= a; @@ -4505,14 +4504,13 @@ static int accessPayload( nextPage = get4byte(&aPayload[pCur->info.nLocal]); /* If the BtCursor.aOverflow[] has not been allocated, allocate it now. - ** Except, do not allocate aOverflow[] for eOp==2. ** ** The aOverflow[] array is sized at one entry for each overflow page ** in the overflow chain. The page number of the first overflow page is ** stored in aOverflow[0], etc. A value of 0 in the aOverflow[] array ** means "not yet known" (the cache is lazily populated). */ - if( eOp!=2 && (pCur->curFlags & BTCF_ValidOvfl)==0 ){ + if( (pCur->curFlags & BTCF_ValidOvfl)==0 ){ int nOvfl = (pCur->info.nPayload-pCur->info.nLocal+ovflSize-1)/ovflSize; if( nOvfl>pCur->nOvflAlloc ){ Pgno *aNew = (Pgno*)sqlite3Realloc( @@ -4533,9 +4531,7 @@ static int accessPayload( ** entry for the first required overflow page is valid, skip ** directly to it. */ - if( (pCur->curFlags & BTCF_ValidOvfl)!=0 - && pCur->aOverflow[offset/ovflSize] - ){ + if( pCur->aOverflow[offset/ovflSize] ){ iIdx = (offset/ovflSize); nextPage = pCur->aOverflow[iIdx]; offset = (offset%ovflSize); @@ -4544,12 +4540,10 @@ static int accessPayload( assert( rc==SQLITE_OK && amt>0 ); while( nextPage ){ /* If required, populate the overflow page-list cache. */ - if( (pCur->curFlags & BTCF_ValidOvfl)!=0 ){ - assert( pCur->aOverflow[iIdx]==0 - || pCur->aOverflow[iIdx]==nextPage - || CORRUPT_DB ); - pCur->aOverflow[iIdx] = nextPage; - } + assert( pCur->aOverflow[iIdx]==0 + || pCur->aOverflow[iIdx]==nextPage + || CORRUPT_DB ); + pCur->aOverflow[iIdx] = nextPage; if( offset>=ovflSize ){ /* The only reason to read this page is to obtain the page @@ -4557,11 +4551,7 @@ static int accessPayload( ** data is not required. So first try to lookup the overflow ** page-list cache, if any, then fall back to the getOverflowPage() ** function. - ** - ** Note that the aOverflow[] array must be allocated because eOp!=2 - ** here. If eOp==2, then offset==0 and this branch is never taken. */ - assert( eOp!=2 ); assert( pCur->curFlags & BTCF_ValidOvfl ); assert( pCur->pBtree->db==pBt->db ); if( pCur->aOverflow[iIdx+1] ){ @@ -4596,7 +4586,7 @@ static int accessPayload( ** output buffer, bypassing the page-cache altogether. This speeds ** up loading large records that span many overflow pages. */ - if( (eOp&0x01)==0 /* (1) */ + if( eOp==0 /* (1) */ && offset==0 /* (2) */ && pBt->inTransaction==TRANS_READ /* (3) */ && (fd = sqlite3PagerFile(pBt->pPager))->pMethods /* (4) */ @@ -4616,12 +4606,12 @@ static int accessPayload( { DbPage *pDbPage; rc = sqlite3PagerGet(pBt->pPager, nextPage, &pDbPage, - ((eOp&0x01)==0 ? PAGER_GET_READONLY : 0) + (eOp==0 ? PAGER_GET_READONLY : 0) ); if( rc==SQLITE_OK ){ aPayload = sqlite3PagerGetData(pDbPage); nextPage = get4byte(aPayload); - rc = copyPayload(&aPayload[offset+4], pBuf, a, (eOp&0x01), pDbPage); + rc = copyPayload(&aPayload[offset+4], pBuf, a, eOp, pDbPage); sqlite3PagerUnref(pDbPage); offset = 0; } @@ -5253,7 +5243,8 @@ int sqlite3BtreeMovetoUnpacked( goto moveto_finish; } pCur->aiIdx[pCur->iPage] = (u16)idx; - rc = accessPayload(pCur, 0, nCell, (unsigned char*)pCellKey, 2); + rc = accessPayload(pCur, 0, nCell, (unsigned char*)pCellKey, 0); + pCur->curFlags &= ~BTCF_ValidOvfl; if( rc ){ sqlite3_free(pCellKey); goto moveto_finish; From cdf360a0d5c3edfb49a44a7de9b39052f9562d2e Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 27 Jan 2017 01:13:49 +0000 Subject: [PATCH 1246/1484] Performance optimization in accessPayload(). FossilOrigin-Name: ebb1fd98d4e448aa6d8f1e5be7ddc5bedb3db95b --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btree.c | 20 ++++++++++---------- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/manifest b/manifest index 0ab648517f..f9f99a3dde 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Simplify\sthe\saccessPayload()\sroutine\sso\sthat\sit\salways\spopulates\sthe\soverflow\npage\scache.\s\sIn\sthe\sone\scase\swhere\spopulating\sthe\spage\scache\scan\slead\sto\s\nproblems,\ssimply\sinvalidate\sthe\scache\sas\ssoon\sas\saccessPayload()\sreturns.\s\s\nThis\ssimplification\sreduces\scode\ssize\sand\shelps\saccessPayload()\sto\srun\sa\s\nlittle\sfaster.\s\sThis\sbacks\sout\sthe\seOp==2\smode\sof\saccessPayload()\sadded\sby\s\ncheck-in\s[da59198505]. -D 2017-01-27T00:31:59.289 +C Performance\soptimization\sin\saccessPayload(). +D 2017-01-27T01:13:49.702 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -333,7 +333,7 @@ F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792 F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca -F src/btree.c d42f290214e6615020b61866fe0747f02614964e +F src/btree.c 1329274c46bc554daf7acde825f72f76f66647ec F src/btree.h e6d352808956ec163a17f832193a3e198b3fb0ac F src/btreeInt.h 10c4b77c2fb399580babbcc7cf652ac10dba796e F src/build.c 9e799f1edd910dfa8a0bc29bd390d35d310596af @@ -1547,7 +1547,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 293bf3ed7e40745349c83b202b27ed1b48517e1a -R ec063431f8eb3294f488a586b69214cb +P 68e7a8c6765649195ef1ad9407d87d44a307b462 +R cab1deb289447016960f1fadc0c9e121 U drh -Z 81eb07f579988e3e7128daaaea36d064 +Z 955f6c694c099beee31ec142603efb52 diff --git a/manifest.uuid b/manifest.uuid index 6d62a1cc6d..a23f86a1ed 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -68e7a8c6765649195ef1ad9407d87d44a307b462 \ No newline at end of file +ebb1fd98d4e448aa6d8f1e5be7ddc5bedb3db95b \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 2575c774cf..54664043d4 100644 --- a/src/btree.c +++ b/src/btree.c @@ -4525,16 +4525,16 @@ static int accessPayload( } memset(pCur->aOverflow, 0, nOvfl*sizeof(Pgno)); pCur->curFlags |= BTCF_ValidOvfl; - } - - /* If the overflow page-list cache has been allocated and the - ** entry for the first required overflow page is valid, skip - ** directly to it. - */ - if( pCur->aOverflow[offset/ovflSize] ){ - iIdx = (offset/ovflSize); - nextPage = pCur->aOverflow[iIdx]; - offset = (offset%ovflSize); + }else{ + /* If the overflow page-list cache has been allocated and the + ** entry for the first required overflow page is valid, skip + ** directly to it. + */ + if( pCur->aOverflow[offset/ovflSize] ){ + iIdx = (offset/ovflSize); + nextPage = pCur->aOverflow[iIdx]; + offset = (offset%ovflSize); + } } assert( rc==SQLITE_OK && amt>0 ); From 6ee610bfc021ade4f83261932180b9492fb639c8 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 27 Jan 2017 01:25:00 +0000 Subject: [PATCH 1247/1484] Another micro-optimization in accessPayload(). Slightly smaller and faster. FossilOrigin-Name: c012619b65d70b4ef6cf33532ef57d7f8ba42d74 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btree.c | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index f9f99a3dde..f94e40935d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Performance\soptimization\sin\saccessPayload(). -D 2017-01-27T01:13:49.702 +C Another\smicro-optimization\sin\saccessPayload().\s\sSlightly\ssmaller\sand\sfaster. +D 2017-01-27T01:25:00.940 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -333,7 +333,7 @@ F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792 F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca -F src/btree.c 1329274c46bc554daf7acde825f72f76f66647ec +F src/btree.c 6a63fa34e6fe86e87090e41963c0f2fcf9d3e16d F src/btree.h e6d352808956ec163a17f832193a3e198b3fb0ac F src/btreeInt.h 10c4b77c2fb399580babbcc7cf652ac10dba796e F src/build.c 9e799f1edd910dfa8a0bc29bd390d35d310596af @@ -1547,7 +1547,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 68e7a8c6765649195ef1ad9407d87d44a307b462 -R cab1deb289447016960f1fadc0c9e121 +P ebb1fd98d4e448aa6d8f1e5be7ddc5bedb3db95b +R 63992a28f021aa7b8223daa601910fb3 U drh -Z 955f6c694c099beee31ec142603efb52 +Z 78e3ca04c2459249956256691b4d7091 diff --git a/manifest.uuid b/manifest.uuid index a23f86a1ed..23c39251fa 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ebb1fd98d4e448aa6d8f1e5be7ddc5bedb3db95b \ No newline at end of file +c012619b65d70b4ef6cf33532ef57d7f8ba42d74 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 54664043d4..45a1c5a0f8 100644 --- a/src/btree.c +++ b/src/btree.c @@ -4617,16 +4617,16 @@ static int accessPayload( } } amt -= a; + if( amt==0 ) return rc; pBuf += a; } - if( amt==0 ) break; if( rc ) break; iIdx++; } } if( rc==SQLITE_OK && amt>0 ){ - return SQLITE_CORRUPT_BKPT; + return SQLITE_CORRUPT_BKPT; /* Overflow chain ends prematurely */ } return rc; } From 7aee83b935ccdd9031ffc2e4ab599cd8f5656981 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 27 Jan 2017 01:52:42 +0000 Subject: [PATCH 1248/1484] In the command-line shell, enhance the ".mode" command so that it restores the default column and row separators for modes "line", "list", "column", and "tcl". FossilOrigin-Name: 58f02e6eae8fc9e2577fe435b0282fb46af3960d --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/shell.c | 5 +++++ 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index f94e40935d..24e35fa9c7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Another\smicro-optimization\sin\saccessPayload().\s\sSlightly\ssmaller\sand\sfaster. -D 2017-01-27T01:25:00.940 +C In\sthe\scommand-line\sshell,\senhance\sthe\s".mode"\scommand\sso\sthat\sit\srestores\sthe\ndefault\scolumn\sand\srow\sseparators\sfor\smodes\s"line",\s"list",\s"column",\sand\n"tcl". +D 2017-01-27T01:52:42.481 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -391,7 +391,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c f9bc0de45a30a450da47b3766de00be89bf9be79 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c 3856db523b942062bca8722ba03b61c324ff94d6 -F src/shell.c 59de9acab4423a536277653f2a9dcdd1307989f3 +F src/shell.c a84e453c213f3e0d6935a582024da4e242f85a19 F src/sqlite.h.in 1971ab9709e010d52a02a1a6276d5a2f9b947476 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae @@ -1547,7 +1547,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ebb1fd98d4e448aa6d8f1e5be7ddc5bedb3db95b -R 63992a28f021aa7b8223daa601910fb3 +P c012619b65d70b4ef6cf33532ef57d7f8ba42d74 +R dc9b2fbf482ea9dbd0fd27947b6ee819 U drh -Z 78e3ca04c2459249956256691b4d7091 +Z 49761a5cfc1a2c7c58e7f0cde30087c6 diff --git a/manifest.uuid b/manifest.uuid index 23c39251fa..beee9d8c88 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c012619b65d70b4ef6cf33532ef57d7f8ba42d74 \ No newline at end of file +58f02e6eae8fc9e2577fe435b0282fb46af3960d \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index db4362dd32..0e553d9fbb 100644 --- a/src/shell.c +++ b/src/shell.c @@ -4288,15 +4288,20 @@ static int do_meta_command(char *zLine, ShellState *p){ int c2 = zMode[0]; if( c2=='l' && n2>2 && strncmp(azArg[1],"lines",n2)==0 ){ p->mode = MODE_Line; + sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row); }else if( c2=='c' && strncmp(azArg[1],"columns",n2)==0 ){ p->mode = MODE_Column; + sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row); }else if( c2=='l' && n2>2 && strncmp(azArg[1],"list",n2)==0 ){ p->mode = MODE_List; + sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Column); + sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row); }else if( c2=='h' && strncmp(azArg[1],"html",n2)==0 ){ p->mode = MODE_Html; }else if( c2=='t' && strncmp(azArg[1],"tcl",n2)==0 ){ p->mode = MODE_Tcl; sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Space); + sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row); }else if( c2=='c' && strncmp(azArg[1],"csv",n2)==0 ){ p->mode = MODE_Csv; sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma); From 9ec82ff2ba27094ce75b0a3ea53063b72d803c13 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 27 Jan 2017 13:14:12 +0000 Subject: [PATCH 1249/1484] Alternative ICU fix (compare to check-in [50e60cb4]) that avoids casting integers to pointers. FossilOrigin-Name: d9752c8f7c55426fd7d2b877c5cc3784f93b5349 --- ext/icu/icu.c | 4 ++-- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/ext/icu/icu.c b/ext/icu/icu.c index 50518d08a7..7c37812d86 100644 --- a/ext/icu/icu.c +++ b/ext/icu/icu.c @@ -500,7 +500,7 @@ int sqlite3IcuInit(sqlite3 *db){ unsigned char iContext; /* sqlite3_user_data() context */ void (*xFunc)(sqlite3_context*,int,sqlite3_value**); } scalars[] = { - {"icu_load_collation", 2, SQLITE_UTF8, 255, icuLoadCollation}, + {"icu_load_collation", 2, SQLITE_UTF8, 1, icuLoadCollation}, {"regexp", 2, SQLITE_ANY|SQLITE_DETERMINISTIC, 0, icuRegexpFunc}, {"lower", 1, SQLITE_UTF16|SQLITE_DETERMINISTIC, 0, icuCaseFunc16}, {"lower", 2, SQLITE_UTF16|SQLITE_DETERMINISTIC, 0, icuCaseFunc16}, @@ -521,7 +521,7 @@ int sqlite3IcuInit(sqlite3 *db){ const struct IcuScalar *p = &scalars[i]; rc = sqlite3_create_function( db, p->zName, p->nArg, p->enc, - p->iContext==255 ? (void*)db : (void*)(((char*)0)+p->iContext), + p->iContext ? (void*)db : (void*)0, p->xFunc, 0, 0 ); } diff --git a/manifest b/manifest index 24e35fa9c7..1c84aea007 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\sthe\scommand-line\sshell,\senhance\sthe\s".mode"\scommand\sso\sthat\sit\srestores\sthe\ndefault\scolumn\sand\srow\sseparators\sfor\smodes\s"line",\s"list",\s"column",\sand\n"tcl". -D 2017-01-27T01:52:42.481 +C Alternative\sICU\sfix\s(compare\sto\scheck-in\s[50e60cb4])\sthat\savoids\scasting\nintegers\sto\spointers. +D 2017-01-27T13:14:12.467 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -202,7 +202,7 @@ F ext/fts5/tool/loadfts5.tcl 95b03429ee6b138645703c6ca192c3ac96eaf093 F ext/fts5/tool/mkfts5c.tcl d1c2a9ab8e0ec690a52316f33dd9b1d379942f45 F ext/fts5/tool/showfts5.tcl d54da0e067306663e2d5d523965ca487698e722c F ext/icu/README.txt d9fbbad0c2f647c3fdf715fc9fd64af53aedfc43 -F ext/icu/icu.c bae1dde13091b425bbed119a09a11aee14644764 +F ext/icu/icu.c 84900472a088a3a172c6c079f58a1d3a1952c332 F ext/icu/sqliteicu.h 728867a802baa5a96de7495e9689a8e01715ef37 F ext/misc/amatch.c 211108e201105e4bb0c076527b8cfd34330fc234 F ext/misc/carray.c 40c27641010a4dc67e3690bdb7c9d36ca58b3c2d @@ -1547,7 +1547,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P c012619b65d70b4ef6cf33532ef57d7f8ba42d74 -R dc9b2fbf482ea9dbd0fd27947b6ee819 +P 58f02e6eae8fc9e2577fe435b0282fb46af3960d +R 4a4a07080dc840a599a4cd01566373f4 U drh -Z 49761a5cfc1a2c7c58e7f0cde30087c6 +Z 816a99767333ba2de388be8cc7b0ed87 diff --git a/manifest.uuid b/manifest.uuid index beee9d8c88..92d5c8ac0b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -58f02e6eae8fc9e2577fe435b0282fb46af3960d \ No newline at end of file +d9752c8f7c55426fd7d2b877c5cc3784f93b5349 \ No newline at end of file From 50133dea285803571214c3459f1ce4d79eea25ec Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 27 Jan 2017 17:02:26 +0000 Subject: [PATCH 1250/1484] Fix a problem causing the pre-update hook to be invoked by DROP TABLE statements. FossilOrigin-Name: fbb6bf1b69cfd581b4ffd778c344e3fbd9c9406f --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/delete.c | 4 +++- test/hook.test | 10 ++++++---- 4 files changed, 18 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index 1c84aea007..55464d8c36 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Alternative\sICU\sfix\s(compare\sto\scheck-in\s[50e60cb4])\sthat\savoids\scasting\nintegers\sto\spointers. -D 2017-01-27T13:14:12.467 +C Fix\sa\sproblem\scausing\sthe\spre-update\shook\sto\sbe\sinvoked\sby\sDROP\sTABLE\nstatements. +D 2017-01-27T17:02:26.115 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -342,7 +342,7 @@ F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 9f2296a4e5d26ebf0e0d95a0af4628f1ea694e7a F src/date.c dc3f1391d9297f8c748132813aaffcb117090d6e F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d -F src/delete.c 8a444fea8340989d6b1be2e122c55bfc61ce69be +F src/delete.c 0d9d5549d42e79ce4d82ff1db1e6c81e36d2f67c F src/expr.c f06f41e5e5daca10fb090e70a2502dcc0dbc992b F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 2e9aabe1aee76273aff8a84ee92c464e095400ae @@ -832,7 +832,7 @@ F test/gcfault.test dd28c228a38976d6336a3fc42d7e5f1ad060cb8c F test/genesis.tcl 1e2e2e8e5cc4058549a154ff1892fe5c9de19f98 F test/hexlit.test 4a6a5f46e3c65c4bf1fa06f5dd5a9507a5627751 F test/hidden.test 23c1393a79e846d68fd902d72c85d5e5dcf98711 -F test/hook.test f6a48d33817f0ca1a39a4d6605fe7e9da8077522 +F test/hook.test dbc0b87756e1e20e7497b56889c9e9cd2f8cc2b5 F test/icu.test 73956798bace8982909c00476b216714a6d0559a F test/ieee754.test 806fc0ce7f305f57e3331eaceeddcfec9339e607 F test/imposter1.test c3f1db2d3db2c24611a6596a3fc0ffc14f1466c8 @@ -1547,7 +1547,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 58f02e6eae8fc9e2577fe435b0282fb46af3960d -R 4a4a07080dc840a599a4cd01566373f4 -U drh -Z 816a99767333ba2de388be8cc7b0ed87 +P d9752c8f7c55426fd7d2b877c5cc3784f93b5349 +R 7c4166e1e335b0337f6f8b4996b52965 +U dan +Z 241b65c68385a1329b03731baa61f118 diff --git a/manifest.uuid b/manifest.uuid index 92d5c8ac0b..e1bf32dbf9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d9752c8f7c55426fd7d2b877c5cc3784f93b5349 \ No newline at end of file +fbb6bf1b69cfd581b4ffd778c344e3fbd9c9406f \ No newline at end of file diff --git a/src/delete.c b/src/delete.c index 1d31622237..0683f9b9dd 100644 --- a/src/delete.c +++ b/src/delete.c @@ -715,7 +715,9 @@ void sqlite3GenerateRowDelete( u8 p5 = 0; sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur,0,iIdxNoSeek); sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, (count?OPFLAG_NCHANGE:0)); - sqlite3VdbeAppendP4(v, (char*)pTab, P4_TABLE); + if( pParse->nested==0 ){ + sqlite3VdbeAppendP4(v, (char*)pTab, P4_TABLE); + } if( eMode!=ONEPASS_OFF ){ sqlite3VdbeChangeP5(v, OPFLAG_AUXDELETE); } diff --git a/test/hook.test b/test/hook.test index 0c24ec7313..9ba220cded 100644 --- a/test/hook.test +++ b/test/hook.test @@ -849,10 +849,12 @@ do_preupdate_test 7.6.4 { } # No preupdate callbacks for modifying sqlite_master. -do_preupdate_test 8.1 { - CREATE TABLE x1(x, y); -} { -} +do_preupdate_test 8.1 { CREATE TABLE x1(x, y); } { } +do_preupdate_test 8.2 { ALTER TABLE x1 ADD COLUMN z } { } +do_preupdate_test 8.3 { ALTER TABLE x1 RENAME TO y1 } { } +do_preupdate_test 8.4 { CREATE INDEX y1x ON y1(x) } { } +do_preupdate_test 8.5 { CREATE VIEW v1 AS SELECT * FROM y1 } { } +do_preupdate_test 8.6 { DROP TABLE y1 } { } #------------------------------------------------------------------------- reset_db From cc04dacb8545a29a7f22a228277c69dbbe8628ba Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 27 Jan 2017 19:27:38 +0000 Subject: [PATCH 1251/1484] Add the sha1.c loadable extension that implements the sha1() and sha1_query() SQL functions. FossilOrigin-Name: 24e77c1cef163a9822635570b3211789ff23d5c9 --- ext/misc/sha1.c | 399 ++++++++++++++++++++++++++++++++++++++++++++++++ manifest | 13 +- manifest.uuid | 2 +- 3 files changed, 407 insertions(+), 7 deletions(-) create mode 100644 ext/misc/sha1.c diff --git a/ext/misc/sha1.c b/ext/misc/sha1.c new file mode 100644 index 0000000000..dbf15a95ef --- /dev/null +++ b/ext/misc/sha1.c @@ -0,0 +1,399 @@ +/* +** 2017-01-27 +** +** 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 SQLite extension implements a functions that compute SHA1 hashes. +** Two SQL functions are implemented: +** +** sha1(X) +** sha1_query(Y) +** +** The sha1(X) function computes the SHA1 hash of the input X, or NULL if +** X is NULL. +** +** The sha1_query(Y) function evalutes all queries in the SQL statements of Y +** and returns a hash of their results. +*/ +#include "sqlite3ext.h" +SQLITE_EXTENSION_INIT1 +#include +#include +#include + +/****************************************************************************** +** The Hash Engine +*/ +/* Context for the SHA1 hash */ +typedef struct SHA1Context SHA1Context; +struct SHA1Context { + unsigned int state[5]; + unsigned int count[2]; + unsigned char buffer[64]; +}; + + +#if __GNUC__ && (defined(__i386__) || defined(__x86_64__)) +/* + * GCC by itself only generates left rotates. Use right rotates if + * possible to be kinder to dinky implementations with iterative rotate + * instructions. + */ +#define SHA_ROT(op, x, k) \ + ({ unsigned int y; asm(op " %1,%0" : "=r" (y) : "I" (k), "0" (x)); y; }) +#define rol(x,k) SHA_ROT("roll", x, k) +#define ror(x,k) SHA_ROT("rorl", x, k) + +#else +/* Generic C equivalent */ +#define SHA_ROT(x,l,r) ((x) << (l) | (x) >> (r)) +#define rol(x,k) SHA_ROT(x,k,32-(k)) +#define ror(x,k) SHA_ROT(x,32-(k),k) +#endif + + +#define blk0le(i) (block[i] = (ror(block[i],8)&0xFF00FF00) \ + |(rol(block[i],8)&0x00FF00FF)) +#define blk0be(i) block[i] +#define blk(i) (block[i&15] = rol(block[(i+13)&15]^block[(i+8)&15] \ + ^block[(i+2)&15]^block[i&15],1)) + +/* + * (R0+R1), R2, R3, R4 are the different operations (rounds) used in SHA1 + * + * Rl0() for little-endian and Rb0() for big-endian. Endianness is + * determined at run-time. + */ +#define Rl0(v,w,x,y,z,i) \ + z+=((w&(x^y))^y)+blk0le(i)+0x5A827999+rol(v,5);w=ror(w,2); +#define Rb0(v,w,x,y,z,i) \ + z+=((w&(x^y))^y)+blk0be(i)+0x5A827999+rol(v,5);w=ror(w,2); +#define R1(v,w,x,y,z,i) \ + z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=ror(w,2); +#define R2(v,w,x,y,z,i) \ + z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=ror(w,2); +#define R3(v,w,x,y,z,i) \ + z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=ror(w,2); +#define R4(v,w,x,y,z,i) \ + z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=ror(w,2); + +/* + * Hash a single 512-bit block. This is the core of the algorithm. + */ +#define a qq[0] +#define b qq[1] +#define c qq[2] +#define d qq[3] +#define e qq[4] + +void SHA1Transform(unsigned int state[5], const unsigned char buffer[64]){ + unsigned int qq[5]; /* a, b, c, d, e; */ + static int one = 1; + unsigned int block[16]; + memcpy(block, buffer, 64); + memcpy(qq,state,5*sizeof(unsigned int)); + + /* Copy p->state[] to working vars */ + /* + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; + */ + + /* 4 rounds of 20 operations each. Loop unrolled. */ + if( 1 == *(unsigned char*)&one ){ + Rl0(a,b,c,d,e, 0); Rl0(e,a,b,c,d, 1); Rl0(d,e,a,b,c, 2); Rl0(c,d,e,a,b, 3); + Rl0(b,c,d,e,a, 4); Rl0(a,b,c,d,e, 5); Rl0(e,a,b,c,d, 6); Rl0(d,e,a,b,c, 7); + Rl0(c,d,e,a,b, 8); Rl0(b,c,d,e,a, 9); Rl0(a,b,c,d,e,10); Rl0(e,a,b,c,d,11); + Rl0(d,e,a,b,c,12); Rl0(c,d,e,a,b,13); Rl0(b,c,d,e,a,14); Rl0(a,b,c,d,e,15); + }else{ + Rb0(a,b,c,d,e, 0); Rb0(e,a,b,c,d, 1); Rb0(d,e,a,b,c, 2); Rb0(c,d,e,a,b, 3); + Rb0(b,c,d,e,a, 4); Rb0(a,b,c,d,e, 5); Rb0(e,a,b,c,d, 6); Rb0(d,e,a,b,c, 7); + Rb0(c,d,e,a,b, 8); Rb0(b,c,d,e,a, 9); Rb0(a,b,c,d,e,10); Rb0(e,a,b,c,d,11); + Rb0(d,e,a,b,c,12); Rb0(c,d,e,a,b,13); Rb0(b,c,d,e,a,14); Rb0(a,b,c,d,e,15); + } + R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); + R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); + R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); + R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); + R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); + R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); + R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); + R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); + R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); + R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); + R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); + R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); + R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); + R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); + R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); + R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); + + /* Add the working vars back into context.state[] */ + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + state[4] += e; +} + + +/* Initialize a SHA1 context */ +static void hash_init(SHA1Context *p){ + /* SHA1 initialization constants */ + p->state[0] = 0x67452301; + p->state[1] = 0xEFCDAB89; + p->state[2] = 0x98BADCFE; + p->state[3] = 0x10325476; + p->state[4] = 0xC3D2E1F0; + p->count[0] = p->count[1] = 0; +} + +/* Add new content to the SHA1 hash */ +static void hash_step( + SHA1Context *p, /* Add content to this context */ + const unsigned char *data, /* Data to be added */ + unsigned int len /* Number of bytes in data */ +){ + unsigned int i, j; + + j = p->count[0]; + if( (p->count[0] += len << 3) < j ){ + p->count[1] += (len>>29)+1; + } + j = (j >> 3) & 63; + if( (j + len) > 63 ){ + (void)memcpy(&p->buffer[j], data, (i = 64-j)); + SHA1Transform(p->state, p->buffer); + for(; i + 63 < len; i += 64){ + SHA1Transform(p->state, &data[i]); + } + j = 0; + }else{ + i = 0; + } + (void)memcpy(&p->buffer[j], &data[i], len - i); +} + +/* Compute a string using sqlite3_vsnprintf() and hash it */ +static void hash_step_vformat( + SHA1Context *p, /* Add content to this context */ + const char *zFormat, + ... +){ + va_list ap; + int n; + char zBuf[50]; + va_start(ap, zFormat); + sqlite3_vsnprintf(sizeof(zBuf),zBuf,zFormat,ap); + va_end(ap); + n = (int)strlen(zBuf); + hash_step(p, (unsigned char*)zBuf, n); +} + + +/* Add padding and compute the message digest. Render the +** message digest as lower-case hexadecimal and put it into +** zOut[]. zOut[] must be at least 41 bytes long. */ +static void hash_finish( + SHA1Context *p, /* The SHA1 context to finish and render */ + char *zOut /* Store hexadecimal hash here */ +){ + unsigned int i; + unsigned char finalcount[8]; + unsigned char digest[20]; + static const char zEncode[] = "0123456789abcdef"; + + for (i = 0; i < 8; i++){ + finalcount[i] = (unsigned char)((p->count[(i >= 4 ? 0 : 1)] + >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */ + } + hash_step(p, (const unsigned char *)"\200", 1); + while ((p->count[0] & 504) != 448){ + hash_step(p, (const unsigned char *)"\0", 1); + } + hash_step(p, finalcount, 8); /* Should cause a SHA1Transform() */ + for (i = 0; i < 20; i++){ + digest[i] = (unsigned char)((p->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); + } + for(i=0; i<20; i++){ + zOut[i*2] = zEncode[(digest[i]>>4)&0xf]; + zOut[i*2+1] = zEncode[digest[i] & 0xf]; + } + zOut[i*2]= 0; +} +/* End of the hashing logic +*****************************************************************************/ + +/* +** Implementation of the sha1(X) function. +** +** Return a lower-case hexadecimal rendering of the SHA1 hash of the +** argument X. If X is a BLOB, it is hashed as is. For all other +** types of input, X is converted into a UTF-8 string and the string +** is hash without the trailing 0x00 terminator. The hash of a NULL +** value is NULL. +*/ +static void sha1Func( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + SHA1Context cx; + int eType = sqlite3_value_type(argv[0]); + int nByte = sqlite3_value_bytes(argv[0]); + char zOut[44]; + + if( eType==SQLITE_NULL ) return; + hash_init(&cx); + if( eType==SQLITE_BLOB ){ + hash_step(&cx, sqlite3_value_blob(argv[0]), nByte); + }else{ + hash_step(&cx, sqlite3_value_text(argv[0]), nByte); + } + hash_finish(&cx, zOut); + sqlite3_result_text(context, zOut, 40, SQLITE_TRANSIENT); +} + +/* +** Implementation of the sha1_query(SQL) function. +** +** This function compiles and runs the SQL statement(s) given in the +** argument. The results are hashed using SHA1 and that hash is returned. +** +** The original SQL text is included as part of the hash. +** +** The hash is not just a concatenation of the outputs. Each query +** is delimited and each row and value within the query is delimited, +** with all values being marked with their datatypes. +*/ +static void sha1QueryFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + sqlite3 *db = sqlite3_context_db_handle(context); + const char *zSql = (const char*)sqlite3_value_text(argv[0]); + sqlite3_stmt *pStmt = 0; + int nCol; /* Number of columns in the result set */ + int i; /* Loop counter */ + int rc; + int n; + const char *z; + SHA1Context cx; + char zOut[44]; + + if( zSql==0 ) return; + hash_init(&cx); + while( zSql[0] ){ + rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zSql); + if( rc ){ + char *zMsg = sqlite3_mprintf("error SQL statement [%s]: %s", + zSql, sqlite3_errmsg(db)); + sqlite3_finalize(pStmt); + sqlite3_result_error(context, zMsg, -1); + sqlite3_free(zMsg); + return; + } + if( !sqlite3_stmt_readonly(pStmt) ){ + char *zMsg = sqlite3_mprintf("non-query: [%s]", sqlite3_sql(pStmt)); + sqlite3_finalize(pStmt); + sqlite3_result_error(context, zMsg, -1); + sqlite3_free(zMsg); + return; + } + nCol = sqlite3_column_count(pStmt); + z = sqlite3_sql(pStmt); + n = (int)strlen(z); + hash_step_vformat(&cx,"S%d:",n); + hash_step(&cx,(unsigned char*)z,n); + + /* Compute a hash over the result of the query */ + while( SQLITE_ROW==sqlite3_step(pStmt) ){ + hash_step(&cx,(const unsigned char*)"R",1); + for(i=0; i=1; j--){ + x[j] = u & 0xff; + u >>= 8; + } + x[0] = 'I'; + hash_step(&cx, x, 9); + break; + } + case SQLITE_FLOAT: { + sqlite3_uint64 u; + int j; + unsigned char x[8]; + double r = sqlite3_column_double(pStmt,i); + memcpy(&u, &r, 8); + for(j=8; j>=1; j--){ + x[j] = u & 0xff; + u >>= 8; + } + x[0] = 'F'; + hash_step(&cx,x,9); + break; + } + case SQLITE_TEXT: { + int n = sqlite3_column_bytes(pStmt, i); + const unsigned char *z = sqlite3_column_text(pStmt, i); + hash_step_vformat(&cx,"T%d:",n); + hash_step(&cx, z, n); + break; + } + case SQLITE_BLOB: { + int n = sqlite3_column_bytes(pStmt, i); + const unsigned char *z = sqlite3_column_blob(pStmt, i); + hash_step_vformat(&cx,"B%d:",n); + hash_step(&cx, z, n); + break; + } + } + } + } + sqlite3_finalize(pStmt); + } + hash_finish(&cx, zOut); + sqlite3_result_text(context, zOut, 40, SQLITE_TRANSIENT); +} + + +#ifdef _WIN32 +__declspec(dllexport) +#endif +int sqlite3_sha_init( + sqlite3 *db, + char **pzErrMsg, + const sqlite3_api_routines *pApi +){ + int rc = SQLITE_OK; + SQLITE_EXTENSION_INIT2(pApi); + (void)pzErrMsg; /* Unused parameter */ + rc = sqlite3_create_function(db, "sha1", 1, SQLITE_UTF8, 0, + sha1Func, 0, 0); + if( rc==SQLITE_OK ){ + rc = sqlite3_create_function(db, "sha1_query", 1, SQLITE_UTF8, 0, + sha1QueryFunc, 0, 0); + } + return rc; +} diff --git a/manifest b/manifest index 55464d8c36..5468756e11 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\scausing\sthe\spre-update\shook\sto\sbe\sinvoked\sby\sDROP\sTABLE\nstatements. -D 2017-01-27T17:02:26.115 +C Add\sthe\ssha1.c\sloadable\sextension\sthat\simplements\sthe\ssha1()\sand\ssha1_query()\nSQL\sfunctions. +D 2017-01-27T19:27:38.700 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -222,6 +222,7 @@ F ext/misc/remember.c 8440f8d0b452c5cdefb62b57135ccd1267aa729d F ext/misc/rot13.c 1ac6f95f99b575907b9b09c81a349114cf9be45a F ext/misc/scrub.c 1c5bfb8b0cd18b602fcb55755e84abf0023ac2fb F ext/misc/series.c e11e534ada797d5b816d7e7a93c022306563ca35 +F ext/misc/sha1.c b2e4eb8e26f09701ec15548395baf698f00e5895 F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52 F ext/misc/spellfix.c a4723b6aff748a417b5091b68a46443265c40f0d F ext/misc/totype.c 4a167594e791abeed95e0a8db028822b5e8fe512 @@ -1547,7 +1548,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d9752c8f7c55426fd7d2b877c5cc3784f93b5349 -R 7c4166e1e335b0337f6f8b4996b52965 -U dan -Z 241b65c68385a1329b03731baa61f118 +P fbb6bf1b69cfd581b4ffd778c344e3fbd9c9406f +R 389e8cfe151c91b893dde5f7934ffeac +U drh +Z 4597f51eb6c4ecdd76ade7480dc74dac diff --git a/manifest.uuid b/manifest.uuid index e1bf32dbf9..4866d1d1f8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fbb6bf1b69cfd581b4ffd778c344e3fbd9c9406f \ No newline at end of file +24e77c1cef163a9822635570b3211789ff23d5c9 \ No newline at end of file From 2d2e4f389584fec0b27100107b18bb835ddeba94 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 28 Jan 2017 06:50:15 +0000 Subject: [PATCH 1252/1484] Fix a typo in the docs for sqlite3_update_hook(). FossilOrigin-Name: 7c029655cc3369a1e46741fdd3701d36d420b28b --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/sqlite.h.in | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 5468756e11..41ba2e4d2c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\ssha1.c\sloadable\sextension\sthat\simplements\sthe\ssha1()\sand\ssha1_query()\nSQL\sfunctions. -D 2017-01-27T19:27:38.700 +C Fix\sa\stypo\sin\sthe\sdocs\sfor\ssqlite3_update_hook(). +D 2017-01-28T06:50:15.642 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -393,7 +393,7 @@ F src/resolve.c f9bc0de45a30a450da47b3766de00be89bf9be79 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c 3856db523b942062bca8722ba03b61c324ff94d6 F src/shell.c a84e453c213f3e0d6935a582024da4e242f85a19 -F src/sqlite.h.in 1971ab9709e010d52a02a1a6276d5a2f9b947476 +F src/sqlite.h.in eefd49aa3aae3b4acd7d7e2f8f9b0db8ae0aff3b F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae F src/sqliteInt.h 341ce9e5b0397771fa6bd9dadb8ef4cbbd6224d0 @@ -1548,7 +1548,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P fbb6bf1b69cfd581b4ffd778c344e3fbd9c9406f -R 389e8cfe151c91b893dde5f7934ffeac -U drh -Z 4597f51eb6c4ecdd76ade7480dc74dac +P 24e77c1cef163a9822635570b3211789ff23d5c9 +R f1c881d122d9ce415eab840d4253340a +U dan +Z 83c68a9a3025b00f2574a4c70122bf9b diff --git a/manifest.uuid b/manifest.uuid index 4866d1d1f8..140867e588 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -24e77c1cef163a9822635570b3211789ff23d5c9 \ No newline at end of file +7c029655cc3369a1e46741fdd3701d36d420b28b \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 87d5d121cb..0bf386f72a 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -5417,7 +5417,7 @@ void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*); ** ^The update hook is not invoked when [WITHOUT ROWID] tables are modified. ** ** ^In the current implementation, the update hook -** is not invoked when duplication rows are deleted because of an +** is not invoked when conflicting rows are deleted because of an ** [ON CONFLICT | ON CONFLICT REPLACE] clause. ^Nor is the update hook ** invoked when rows are deleted using the [truncate optimization]. ** The exceptions defined in this paragraph might change in a future From 27c846773497d27eb6f04f7f7b03d073b99b319d Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 28 Jan 2017 13:40:55 +0000 Subject: [PATCH 1253/1484] In the speed-check.sh script, automatically invoke "fossil test-diff --tk" on the cachegrind output against trunk, if not generating a trunk run. FossilOrigin-Name: aa1ab37100a91ab4bb91d50a1267c26967efcb21 --- manifest | 14 +++++++------- manifest.uuid | 2 +- tool/speed-check.sh | 3 +++ 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 41ba2e4d2c..3e4c3fcfe4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\stypo\sin\sthe\sdocs\sfor\ssqlite3_update_hook(). -D 2017-01-28T06:50:15.642 +C In\sthe\sspeed-check.sh\sscript,\sautomatically\sinvoke\s"fossil\stest-diff\s--tk"\son\nthe\scachegrind\soutput\sagainst\strunk,\sif\snot\sgenerating\sa\strunk\srun. +D 2017-01-28T13:40:55.453 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -1508,7 +1508,7 @@ F tool/showstat4.c b14159aa062f661b394ba37b6b7b94bfb8012ab9 F tool/showwal.c ec79959834f7b21f1e0a2aa52bb7c056d2203977 F tool/soak1.tcl 8d407956e1a45b485a8e072470a3e629a27037fe F tool/spaceanal.tcl ab7d9bf68062907282a64b3e12ccbfad47193c5a -F tool/speed-check.sh 65ac2f5b00771b9dcefb95bebae1aab76c537ea3 +F tool/speed-check.sh 9630ba0468b609c52f48309243d4eb6e9c34deda F tool/speedtest.tcl 06c76698485ccf597b9e7dbb1ac70706eb873355 F tool/speedtest16.c ecb6542862151c3e6509bbc00509b234562ae81e F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff @@ -1548,7 +1548,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 24e77c1cef163a9822635570b3211789ff23d5c9 -R f1c881d122d9ce415eab840d4253340a -U dan -Z 83c68a9a3025b00f2574a4c70122bf9b +P 7c029655cc3369a1e46741fdd3701d36d420b28b +R e044c4e027113b10098b21316c3901f3 +U drh +Z 82ae1e57a20d4dbe9187373cc6493ae1 diff --git a/manifest.uuid b/manifest.uuid index 140867e588..fc7ceb70f4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7c029655cc3369a1e46741fdd3701d36d420b28b \ No newline at end of file +aa1ab37100a91ab4bb91d50a1267c26967efcb21 \ No newline at end of file diff --git a/tool/speed-check.sh b/tool/speed-check.sh index c6f587e177..1e1389f2fd 100644 --- a/tool/speed-check.sh +++ b/tool/speed-check.sh @@ -142,3 +142,6 @@ fi if test $doExplain -eq 1; then ./speedtest1 --explain $SPEEDTEST_OPTS | ./sqlite3 >explain-$NAME.txt fi +if test "$NAME" != "trunk"; then + fossil test-diff --tk cout-trunk.txt cout-$NAME.txt +fi From 6034d476186cda5b18f6003b8c3f66cb0e216d16 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 28 Jan 2017 15:26:14 +0000 Subject: [PATCH 1254/1484] Updates to the sqlite3_blob documentation. No changes to code. FossilOrigin-Name: 426b440a5745f9c431c6a3d9ba542af61a6a83fb --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/sqlite.h.in | 14 ++++++++++++-- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 3e4c3fcfe4..6c861e5ee0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\sthe\sspeed-check.sh\sscript,\sautomatically\sinvoke\s"fossil\stest-diff\s--tk"\son\nthe\scachegrind\soutput\sagainst\strunk,\sif\snot\sgenerating\sa\strunk\srun. -D 2017-01-28T13:40:55.453 +C Updates\sto\sthe\ssqlite3_blob\sdocumentation.\s\sNo\schanges\sto\scode. +D 2017-01-28T15:26:14.397 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -393,7 +393,7 @@ F src/resolve.c f9bc0de45a30a450da47b3766de00be89bf9be79 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c 3856db523b942062bca8722ba03b61c324ff94d6 F src/shell.c a84e453c213f3e0d6935a582024da4e242f85a19 -F src/sqlite.h.in eefd49aa3aae3b4acd7d7e2f8f9b0db8ae0aff3b +F src/sqlite.h.in a14cd1f946b9565c4d801c4adeeaa4543fbd6eb4 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae F src/sqliteInt.h 341ce9e5b0397771fa6bd9dadb8ef4cbbd6224d0 @@ -1548,7 +1548,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 7c029655cc3369a1e46741fdd3701d36d420b28b -R e044c4e027113b10098b21316c3901f3 +P aa1ab37100a91ab4bb91d50a1267c26967efcb21 +R e94128da2458d76e1f9232d83fbb5c60 U drh -Z 82ae1e57a20d4dbe9187373cc6493ae1 +Z 85ea4b53c0f0f74a70744dcf483d3a5b diff --git a/manifest.uuid b/manifest.uuid index fc7ceb70f4..6d893bf0fe 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -aa1ab37100a91ab4bb91d50a1267c26967efcb21 \ No newline at end of file +426b440a5745f9c431c6a3d9ba542af61a6a83fb \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 0bf386f72a..d80de6d519 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -6199,6 +6199,12 @@ typedef struct sqlite3_blob sqlite3_blob; ** [database connection] error code and message accessible via ** [sqlite3_errcode()] and [sqlite3_errmsg()] and related functions. ** +** A BLOB referenced by sqlite3_blob_open() and be read using the +** [sqlite3_blob_read()] interface and modified by using +** [sqlite3_blob_write()]. The [BLOB handle] can be moved to a +** different row of the same table using the [sqlite3_blob_reopen()] +** interface. However, the column, table, or database of a [BLOB handle] +** cannot be changed once after the [BLOB handle] is opened. ** ** ^(If the row that a BLOB handle points to is modified by an ** [UPDATE], [DELETE], or by [ON CONFLICT] side-effects @@ -6222,6 +6228,10 @@ typedef struct sqlite3_blob sqlite3_blob; ** ** To avoid a resource leak, every open [BLOB handle] should eventually ** be released by a call to [sqlite3_blob_close()]. +** +** See also: [sqlite3_blob_close()], +** [sqlite3_blob_reopen()], [sqlite3_blob_read()], +** [sqlite3_blob_bytes()], [sqlite3_blob_write()]. */ int sqlite3_blob_open( sqlite3*, @@ -6237,11 +6247,11 @@ int sqlite3_blob_open( ** CAPI3REF: Move a BLOB Handle to a New Row ** METHOD: sqlite3_blob ** -** ^This function is used to move an existing blob handle so that it points +** ^This function is used to move an existing [BLOB handle] so that it points ** to a different row of the same database table. ^The new row is identified ** by the rowid value passed as the second argument. Only the row can be ** changed. ^The database, table and column on which the blob handle is open -** remain the same. Moving an existing blob handle to a new row can be +** remain the same. Moving an existing [BLOB handle] to a new row is ** faster than closing the existing handle and opening a new one. ** ** ^(The new row must meet the same criteria as for [sqlite3_blob_open()] - From f64ece143c4d71a5d8f8a67cd643cd0ef683c29e Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 28 Jan 2017 19:45:34 +0000 Subject: [PATCH 1255/1484] Avoid redundant table b-tree cursor seeks in UPDATE statements that use the two-pass strategy. FossilOrigin-Name: dc555b1039c6930f6d15355c698ff917a85e8056 --- ext/session/session1.test | 19 +++++++++++++++++++ manifest | 22 +++++++++++----------- manifest.uuid | 2 +- src/sqliteInt.h | 2 +- src/update.c | 2 +- src/wherecode.c | 5 ++++- test/update2.test | 25 +++++++++++++++++++++++++ 7 files changed, 62 insertions(+), 15 deletions(-) diff --git a/ext/session/session1.test b/ext/session/session1.test index 09d35af7fc..5216824bdd 100644 --- a/ext/session/session1.test +++ b/ext/session/session1.test @@ -582,4 +582,23 @@ do_iterator_test 11.2 * { } { } +reset_db +do_execsql_test 12.1 { + CREATE TABLE t1(r INTEGER PRIMARY KEY, a, b); + CREATE INDEX i1 ON t1(a); + INSERT INTO t1 VALUES(1, 1, 1); + INSERT INTO t1 VALUES(2, 1, 2); + INSERT INTO t1 VALUES(3, 1, 3); +} + +do_iterator_test 12.2 * { + UPDATE t1 SET b='one' WHERE a=1; +} { + {UPDATE t1 0 X.. {i 1 {} {} i 1} {{} {} {} {} t one}} + {UPDATE t1 0 X.. {i 2 {} {} i 2} {{} {} {} {} t one}} + {UPDATE t1 0 X.. {i 3 {} {} i 3} {{} {} {} {} t one}} +} + + + finish_test diff --git a/manifest b/manifest index 6c861e5ee0..ddbf2ea5df 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Updates\sto\sthe\ssqlite3_blob\sdocumentation.\s\sNo\schanges\sto\scode. -D 2017-01-28T15:26:14.397 +C Avoid\sredundant\stable\sb-tree\scursor\sseeks\sin\sUPDATE\sstatements\sthat\suse\sthe\ntwo-pass\sstrategy. +D 2017-01-28T19:45:34.617 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -288,7 +288,7 @@ F ext/rtree/sqlite3rtree.h 9c5777af3d2921c7b4ae4954e8e5697502289d28 F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 F ext/session/changeset.c 4ccbaa4531944c24584bf6a61ba3a39c62b6267a -F ext/session/session1.test e5125b216d1e8c91e0984b361b0b68529e7c5dfb +F ext/session/session1.test 482e9b861169d0b7e283e1563a28c0fa32779fa5 F ext/session/session2.test 284de45abae4cc1082bc52012ee81521d5ac58e0 F ext/session/session3.test a7a9ce59b8d1e49e2cc23d81421ac485be0eea01 F ext/session/session4.test 457b02bdc349eb01151e54de014df77abd3c08c8 @@ -396,7 +396,7 @@ F src/shell.c a84e453c213f3e0d6935a582024da4e242f85a19 F src/sqlite.h.in a14cd1f946b9565c4d801c4adeeaa4543fbd6eb4 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae -F src/sqliteInt.h 341ce9e5b0397771fa6bd9dadb8ef4cbbd6224d0 +F src/sqliteInt.h c246370f9d8de3af36052d7860cd35c0e2daea6a F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 @@ -454,7 +454,7 @@ F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c 5c2f516876fc27fbd7753913f032f49eb89e83b5 F src/treeview.c 4e44ade3bfe59d82005039f72e09333ce2b4162c F src/trigger.c c9f0810043b265724fdb1bdd466894f984dfc182 -F src/update.c b356b29d04c71f33c779f2cb557cf953819bdd7a +F src/update.c 456d4a4656f8a03c2abc88a51b19172197400e58 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c a88b0466fddf445ce752226d4698ca3faada620a F src/vacuum.c 33c174b28886b2faf26e503b5a49a1c01a9b1c16 @@ -474,7 +474,7 @@ F src/wal.h 06b2a0b599cc0f53ea97f497cf8c6b758c999f71 F src/walker.c 91a6df7435827e41cff6bb7df50ea00934ee78b0 F src/where.c bc71775e23d23334e8f449aa31012d692dc09cb2 F src/whereInt.h 2bcc3d176e6091cb8f50a30b65c006e88a73614d -F src/wherecode.c e04ac8f24c3ac8621df6c3be3ac8c7d4fa893745 +F src/wherecode.c 99a8ced164c75edf41b3a865a75381c9adb38b28 F src/whereexpr.c 35ad025389a632a3987a35617c878be3b3d70dc6 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -1355,7 +1355,7 @@ F test/unique2.test 3674e9f2a3f1fbbfd4772ac74b7a97090d0f77d2 F test/unixexcl.test d936ba2b06794018e136418addd59a2354eeae97 F test/unordered.test ca7adce0419e4ca0c50f039885e76ed2c531eda8 F test/update.test 6c68446b8a0a33d522a7c72b320934596a2d7d32 -F test/update2.test 7f72ef307d58be09a8ef61db23a7ef60e5af019d +F test/update2.test 81772e5c9b93d1006d66d65e9a1327281bdec4e8 F test/uri.test 3481026f00ade6dfe8adb7acb6e1e47b04369568 F test/uri2.test 9d3ba7a53ee167572d53a298ee4a5d38ec4a8fb7 F test/userauth01.test e740a2697a7b40d7c5003a7d7edaee16acd349a9 @@ -1548,7 +1548,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P aa1ab37100a91ab4bb91d50a1267c26967efcb21 -R e94128da2458d76e1f9232d83fbb5c60 -U drh -Z 85ea4b53c0f0f74a70744dcf483d3a5b +P 426b440a5745f9c431c6a3d9ba542af61a6a83fb +R cb9f34739a33405b5f0617b1ee3426fc +U dan +Z 2ac8b1778a518257277e1132fa6dad3a diff --git a/manifest.uuid b/manifest.uuid index 6d893bf0fe..0e49c05605 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -426b440a5745f9c431c6a3d9ba542af61a6a83fb \ No newline at end of file +dc555b1039c6930f6d15355c698ff917a85e8056 \ No newline at end of file diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 7ea8748b73..3f0da18e9c 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2592,7 +2592,7 @@ struct SrcList { #define WHERE_SORTBYGROUP 0x0200 /* Support sqlite3WhereIsSorted() */ #define WHERE_SEEK_TABLE 0x0400 /* Do not defer seeks on main table */ #define WHERE_ORDERBY_LIMIT 0x0800 /* ORDERBY+LIMIT on the inner loop */ - /* 0x1000 not currently used */ +#define WHERE_SEEK_UNIQ_TABLE 0x1000 /* Do not defer seeks if unique */ /* 0x2000 not currently used */ #define WHERE_USE_LIMIT 0x4000 /* Use the LIMIT in cost estimates */ /* 0x8000 not currently used */ diff --git a/src/update.c b/src/update.c index 45af001c3e..8fca7eb988 100644 --- a/src/update.c +++ b/src/update.c @@ -392,7 +392,7 @@ void sqlite3Update( ** be deleted as a result of REPLACE conflict handling. Any of these ** things might disturb a cursor being used to scan through the table ** or index, causing a single-pass approach to malfunction. */ - flags = WHERE_ONEPASS_DESIRED | WHERE_SEEK_TABLE; + flags = WHERE_ONEPASS_DESIRED|WHERE_SEEK_UNIQ_TABLE; if( !pParse->nested && !pTrigger && !hasFK && !chngKey && !bReplace ){ flags |= WHERE_ONEPASS_MULTIROW; } diff --git a/src/wherecode.c b/src/wherecode.c index 032c56fef3..58e040628a 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -1591,7 +1591,10 @@ Bitmask sqlite3WhereCodeOneLoopStart( if( omitTable ){ /* pIdx is a covering index. No need to access the main table. */ }else if( HasRowid(pIdx->pTable) ){ - if( (pWInfo->wctrlFlags & WHERE_SEEK_TABLE)!=0 ){ + if( (pWInfo->wctrlFlags & WHERE_SEEK_TABLE) || ( + (pWInfo->wctrlFlags & WHERE_SEEK_UNIQ_TABLE) + && (pWInfo->eOnePass==ONEPASS_SINGLE) + )){ iRowidReg = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, iRowidReg); sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg); diff --git a/test/update2.test b/test/update2.test index 61ac9792da..6a359d11a9 100644 --- a/test/update2.test +++ b/test/update2.test @@ -176,5 +176,30 @@ foreach {tn sql} { } } +#------------------------------------------------------------------------- +# +do_execsql_test 5.0 { + CREATE TABLE x1(a INTEGER PRIMARY KEY, b, c); + CREATE INDEX x1c ON x1(b, c); + INSERT INTO x1 VALUES(1, 'a', 1); + INSERT INTO x1 VALUES(2, 'a', 2); + INSERT INTO x1 VALUES(3, 'a', 3); +} + +do_execsql_test 5.1.1 { + UPDATE x1 SET c=c+1 WHERE b='a'; +} + +do_execsql_test 5.1.2 { + SELECT * FROM x1; +} {1 a 2 2 a 3 3 a 4} + +do_test 5.2 { + catch { array unset A } + db eval { EXPLAIN UPDATE x1 SET c=c+1 WHERE b='a' } { incr A($opcode) } + set A(NotExists) +} {1} + + finish_test From 51b15c3871a264dc4867eeda97faed19f86bdb2b Mon Sep 17 00:00:00 2001 From: mistachkin Date: Sat, 28 Jan 2017 19:53:51 +0000 Subject: [PATCH 1256/1484] Fix a couple comment typos. No changes to code. FossilOrigin-Name: 2a2e7d86b275c970726f642a37a098950a3b906e --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/sqlite.h.in | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index ddbf2ea5df..02a68de80a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sredundant\stable\sb-tree\scursor\sseeks\sin\sUPDATE\sstatements\sthat\suse\sthe\ntwo-pass\sstrategy. -D 2017-01-28T19:45:34.617 +C Fix\sa\scouple\scomment\stypos.\s\sNo\schanges\sto\scode. +D 2017-01-28T19:53:51.613 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -393,7 +393,7 @@ F src/resolve.c f9bc0de45a30a450da47b3766de00be89bf9be79 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c 3856db523b942062bca8722ba03b61c324ff94d6 F src/shell.c a84e453c213f3e0d6935a582024da4e242f85a19 -F src/sqlite.h.in a14cd1f946b9565c4d801c4adeeaa4543fbd6eb4 +F src/sqlite.h.in 8fd2b1a4e4aac023d4533313442528b81105fab3 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae F src/sqliteInt.h c246370f9d8de3af36052d7860cd35c0e2daea6a @@ -1548,7 +1548,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 426b440a5745f9c431c6a3d9ba542af61a6a83fb -R cb9f34739a33405b5f0617b1ee3426fc -U dan -Z 2ac8b1778a518257277e1132fa6dad3a +P dc555b1039c6930f6d15355c698ff917a85e8056 +R 85ad9229fc7d18817a896fd231c69045 +U mistachkin +Z 8ca9913e082eb1ea0368f4a7e44ff324 diff --git a/manifest.uuid b/manifest.uuid index 0e49c05605..d337122ecd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -dc555b1039c6930f6d15355c698ff917a85e8056 \ No newline at end of file +2a2e7d86b275c970726f642a37a098950a3b906e \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index d80de6d519..b0ec7f7e15 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -6199,12 +6199,12 @@ typedef struct sqlite3_blob sqlite3_blob; ** [database connection] error code and message accessible via ** [sqlite3_errcode()] and [sqlite3_errmsg()] and related functions. ** -** A BLOB referenced by sqlite3_blob_open() and be read using the +** A BLOB referenced by sqlite3_blob_open() may be read using the ** [sqlite3_blob_read()] interface and modified by using ** [sqlite3_blob_write()]. The [BLOB handle] can be moved to a ** different row of the same table using the [sqlite3_blob_reopen()] ** interface. However, the column, table, or database of a [BLOB handle] -** cannot be changed once after the [BLOB handle] is opened. +** cannot be changed after the [BLOB handle] is opened. ** ** ^(If the row that a BLOB handle points to is modified by an ** [UPDATE], [DELETE], or by [ON CONFLICT] side-effects From d26cc54183849acb2f53537e67e5968ada4619d9 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 28 Jan 2017 20:46:37 +0000 Subject: [PATCH 1257/1484] In the amalgamation, allocate the parser engine object from stack rather than from heap, for improved performance. This only happens in the amalgamation, since otherwise the sqlite3RunParser() routine does not know the object size. FossilOrigin-Name: 4fe879d4b5da6ae0688a7a99004683a234966597 --- manifest | 20 +++++++------- manifest.uuid | 2 +- src/parse.y | 13 +++++++++ src/sqliteInt.h | 6 +++-- src/tokenize.c | 12 +++++++++ tool/lempar.c | 71 ++++++++++++++++++++++++++++++------------------- 6 files changed, 84 insertions(+), 40 deletions(-) diff --git a/manifest b/manifest index 02a68de80a..332ad282a9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\scouple\scomment\stypos.\s\sNo\schanges\sto\scode. -D 2017-01-28T19:53:51.613 +C In\sthe\samalgamation,\sallocate\sthe\sparser\sengine\sobject\sfrom\sstack\srather\sthan\nfrom\sheap,\sfor\simproved\sperformance.\s\sThis\sonly\shappens\sin\sthe\samalgamation,\nsince\sotherwise\sthe\ssqlite3RunParser()\sroutine\sdoes\snot\sknow\sthe\sobject\ssize. +D 2017-01-28T20:46:37.958 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -380,7 +380,7 @@ F src/os_win.c cf90abd4e50d9f56d2c20ce8e005aff55d7bd8e9 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c ff1232b3088a39806035ecfac4fffeb22717d80b F src/pager.h f2a99646c5533ffe11afa43e9e0bea74054e4efa -F src/parse.y 29153738a7322054359320eb00b5a4cd44389f20 +F src/parse.y 591704fce84f814d9a3642774c1f011d38f4149c F src/pcache.c 51070ec9b8251bbf9c6ea3d35fd96a458752929e F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 F src/pcache1.c e3967219b2a92b9edcb9324a4ba75009090d3953 @@ -396,7 +396,7 @@ F src/shell.c a84e453c213f3e0d6935a582024da4e242f85a19 F src/sqlite.h.in 8fd2b1a4e4aac023d4533313442528b81105fab3 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae -F src/sqliteInt.h c246370f9d8de3af36052d7860cd35c0e2daea6a +F src/sqliteInt.h fd6815792077b7dc69f5167117cc5727fe95ed5a F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 @@ -451,7 +451,7 @@ F src/test_windirent.c 17f91f5f2aa1bb7328abb49414c363b5d2a9d3ff F src/test_windirent.h 5d67483a55442e31e1bde0f4a230e6e932ad5906 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c -F src/tokenize.c 5c2f516876fc27fbd7753913f032f49eb89e83b5 +F src/tokenize.c 25ccc63ae2c4163933221f3181c9982b47cd08d2 F src/treeview.c 4e44ade3bfe59d82005039f72e09333ce2b4162c F src/trigger.c c9f0810043b265724fdb1bdd466894f984dfc182 F src/update.c 456d4a4656f8a03c2abc88a51b19172197400e58 @@ -1476,7 +1476,7 @@ F tool/genfkey.README cf68fddd4643bbe3ff8e31b8b6d8b0a1b85e20f4 F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5 F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce F tool/lemon.c 5ccba178a8e8a4b21e1c9232944d23973da38ad7 -F tool/lempar.c 320d630b44da693407684c64d9fa91a163419dac +F tool/lempar.c db1bdb4821f2d8fbd76e577cf3ab18642c8d08d1 F tool/libvers.c caafc3b689638a1d88d44bc5f526c2278760d9b9 F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862 F tool/logest.c 11346aa019e2e77a00902aa7d0cabd27bd2e8cca @@ -1548,7 +1548,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P dc555b1039c6930f6d15355c698ff917a85e8056 -R 85ad9229fc7d18817a896fd231c69045 -U mistachkin -Z 8ca9913e082eb1ea0368f4a7e44ff324 +P 2a2e7d86b275c970726f642a37a098950a3b906e +R 9e84d1f95c544016e0312212ee6f639c +U drh +Z 9df531d71c0beb5e9e8a394dca7276a3 diff --git a/manifest.uuid b/manifest.uuid index d337122ecd..87236c5ed3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2a2e7d86b275c970726f642a37a098950a3b906e \ No newline at end of file +4fe879d4b5da6ae0688a7a99004683a234966597 \ No newline at end of file diff --git a/src/parse.y b/src/parse.y index c9dbc767cd..9cada2a1be 100644 --- a/src/parse.y +++ b/src/parse.y @@ -65,6 +65,19 @@ */ #define YYPARSEFREENEVERNULL 1 +/* +** In the amalgamation, the parse.c file generated by lemon and the +** tokenize.c file are concatenated. In that case, sqlite3RunParser() +** has access to the the size of the yyParser object and so the parser +** engine can be allocated from stack. In that case, only the +** sqlite3ParserInit() and sqlite3ParserFinalize() routines are invoked +** and the sqlite3ParserAlloc() and sqlite3ParserFree() routines can be +** omitted. +*/ +#ifdef SQLITE_AMALGAMATION +# define sqlite3Parser_ENGINEALWAYSONSTACK 1 +#endif + /* ** Alternative datatype for the argument to the malloc() routine passed ** into sqlite3ParserAlloc(). The default is size_t. diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 3f0da18e9c..4b7bdf5937 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -4073,8 +4073,10 @@ char sqlite3IndexColumnAffinity(sqlite3*, Index*, int); /* ** The interface to the LEMON-generated parser */ -void *sqlite3ParserAlloc(void*(*)(u64)); -void sqlite3ParserFree(void*, void(*)(void*)); +#ifndef SQLITE_AMALGAMATION + void *sqlite3ParserAlloc(void*(*)(u64)); + void sqlite3ParserFree(void*, void(*)(void*)); +#endif void sqlite3Parser(void*, int, Token, Parse*); #ifdef YYTRACKMAXSTACKDEPTH int sqlite3ParserStackPeak(void*); diff --git a/src/tokenize.c b/src/tokenize.c index c400dcd554..7bb1179e20 100644 --- a/src/tokenize.c +++ b/src/tokenize.c @@ -481,6 +481,9 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){ int lastTokenParsed = -1; /* type of the previous token */ sqlite3 *db = pParse->db; /* The database connection */ int mxSqlLen; /* Max length of an SQL string */ +#ifdef sqlite3Parser_ENGINEALWAYSONSTACK + unsigned char zSpace[sizeof(yyParser)]; /* Space for parser engine object */ +#endif assert( zSql!=0 ); mxSqlLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH]; @@ -492,11 +495,16 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){ i = 0; assert( pzErrMsg!=0 ); /* sqlite3ParserTrace(stdout, "parser: "); */ +#ifdef sqlite3Parser_ENGINEALWAYSONSTACK + pEngine = zSpace; + sqlite3ParserInit(pEngine); +#else pEngine = sqlite3ParserAlloc(sqlite3Malloc); if( pEngine==0 ){ sqlite3OomFault(db); return SQLITE_NOMEM_BKPT; } +#endif assert( pParse->pNewTable==0 ); assert( pParse->pNewTrigger==0 ); assert( pParse->nVar==0 ); @@ -548,7 +556,11 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){ ); sqlite3_mutex_leave(sqlite3MallocMutex()); #endif /* YYDEBUG */ +#ifdef sqlite3Parser_ENGINEALWAYSONSTACK + sqlite3ParserFinalize(pEngine); +#else sqlite3ParserFree(pEngine, sqlite3_free); +#endif if( db->mallocFailed ){ pParse->rc = SQLITE_NOMEM_BKPT; } diff --git a/tool/lempar.c b/tool/lempar.c index dab8343f3a..21ed9d79ab 100644 --- a/tool/lempar.c +++ b/tool/lempar.c @@ -316,6 +316,31 @@ static int yyGrowStack(yyParser *p){ # define YYMALLOCARGTYPE size_t #endif +/* Initialize a new parser that has already been allocated. +*/ +void ParseInit(void *yypParser){ + yyParser *pParser = (yyParser*)yypParser; +#ifdef YYTRACKMAXSTACKDEPTH + pParser->yyhwm = 0; +#endif +#if YYSTACKDEPTH<=0 + pParser->yytos = NULL; + pParser->yystack = NULL; + pParser->yystksz = 0; + if( yyGrowStack(pParser) ){ + pParser->yystack = &pParser->yystk0; + pParser->yystksz = 1; + } +#endif +#ifndef YYNOERRORRECOVERY + pParser->yyerrcnt = -1; +#endif + pParser->yytos = pParser->yystack; + pParser->yystack[0].stateno = 0; + pParser->yystack[0].major = 0; +} + +#ifndef Parse_ENGINEALWAYSONSTACK /* ** This function allocates a new parser. ** The only argument is a pointer to a function which works like @@ -331,28 +356,11 @@ static int yyGrowStack(yyParser *p){ void *ParseAlloc(void *(*mallocProc)(YYMALLOCARGTYPE)){ yyParser *pParser; pParser = (yyParser*)(*mallocProc)( (YYMALLOCARGTYPE)sizeof(yyParser) ); - if( pParser ){ -#ifdef YYTRACKMAXSTACKDEPTH - pParser->yyhwm = 0; -#endif -#if YYSTACKDEPTH<=0 - pParser->yytos = NULL; - pParser->yystack = NULL; - pParser->yystksz = 0; - if( yyGrowStack(pParser) ){ - pParser->yystack = &pParser->yystk0; - pParser->yystksz = 1; - } -#endif -#ifndef YYNOERRORRECOVERY - pParser->yyerrcnt = -1; -#endif - pParser->yytos = pParser->yystack; - pParser->yystack[0].stateno = 0; - pParser->yystack[0].major = 0; - } + if( pParser ) ParseInit(pParser); return pParser; } +#endif /* Parse_ENGINEALWAYSONSTACK */ + /* The following function deletes the "minor type" or semantic value ** associated with a symbol. The symbol can be either a terminal @@ -406,6 +414,18 @@ static void yy_pop_parser_stack(yyParser *pParser){ yy_destructor(pParser, yytos->major, &yytos->minor); } +/* +** Clear all secondary memory allocations from the parser +*/ +void ParseFinalize(void *p){ + yyParser *pParser = (yyParser*)p; + while( pParser->yytos>pParser->yystack ) yy_pop_parser_stack(pParser); +#if YYSTACKDEPTH<=0 + if( pParser->yystack!=&pParser->yystk0 ) free(pParser->yystack); +#endif +} + +#ifndef Parse_ENGINEALWAYSONSTACK /* ** Deallocate and destroy a parser. Destructors are called for ** all stack elements before shutting the parser down. @@ -418,16 +438,13 @@ void ParseFree( void *p, /* The parser to be deleted */ void (*freeProc)(void*) /* Function used to reclaim memory */ ){ - yyParser *pParser = (yyParser*)p; #ifndef YYPARSEFREENEVERNULL - if( pParser==0 ) return; + if( p==0 ) return; #endif - while( pParser->yytos>pParser->yystack ) yy_pop_parser_stack(pParser); -#if YYSTACKDEPTH<=0 - if( pParser->yystack!=&pParser->yystk0 ) free(pParser->yystack); -#endif - (*freeProc)((void*)pParser); + ParseFinalize(p); + (*freeProc)(p); } +#endif /* Parse_ENGINEALWAYSONSTACK */ /* ** Return the peak depth of the stack for a parser. From e7eeeb99f7827fc2838cf730adfb58f5419a41e7 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 30 Jan 2017 11:38:19 +0000 Subject: [PATCH 1258/1484] Fix building with SQLITE_OMIT_FOREIGN_KEY defined. FossilOrigin-Name: e93d2c49a44af994ff10cc9cc7eafacd5a4f73ab --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/sqliteInt.h | 1 + 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 332ad282a9..229623bcc5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\sthe\samalgamation,\sallocate\sthe\sparser\sengine\sobject\sfrom\sstack\srather\sthan\nfrom\sheap,\sfor\simproved\sperformance.\s\sThis\sonly\shappens\sin\sthe\samalgamation,\nsince\sotherwise\sthe\ssqlite3RunParser()\sroutine\sdoes\snot\sknow\sthe\sobject\ssize. -D 2017-01-28T20:46:37.958 +C Fix\sbuilding\swith\sSQLITE_OMIT_FOREIGN_KEY\sdefined. +D 2017-01-30T11:38:19.468 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -396,7 +396,7 @@ F src/shell.c a84e453c213f3e0d6935a582024da4e242f85a19 F src/sqlite.h.in 8fd2b1a4e4aac023d4533313442528b81105fab3 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae -F src/sqliteInt.h fd6815792077b7dc69f5167117cc5727fe95ed5a +F src/sqliteInt.h 6f29b23415ce207c2fda61054bf244b74f96359c F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 @@ -1548,7 +1548,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 2a2e7d86b275c970726f642a37a098950a3b906e -R 9e84d1f95c544016e0312212ee6f639c -U drh -Z 9df531d71c0beb5e9e8a394dca7276a3 +P 4fe879d4b5da6ae0688a7a99004683a234966597 +R c0ed5c24fdff676195cd77401e89700b +U dan +Z 6d1b138d17ccacee0c622f2ed331ca89 diff --git a/manifest.uuid b/manifest.uuid index 87236c5ed3..eec33fc0a4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4fe879d4b5da6ae0688a7a99004683a234966597 \ No newline at end of file +e93d2c49a44af994ff10cc9cc7eafacd5a4f73ab \ No newline at end of file diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 4b7bdf5937..4a28ebcd5a 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -4186,6 +4186,7 @@ const char *sqlite3JournalModename(int); #define sqlite3FkDropTable(a,b,c) #define sqlite3FkOldmask(a,b) 0 #define sqlite3FkRequired(a,b,c,d) 0 + #define sqlite3FkReferences(a) 0 #endif #ifndef SQLITE_OMIT_FOREIGN_KEY void sqlite3FkDelete(sqlite3 *, Table*); From cb9a364390f2db2bb9340045e7973d3f639110bb Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 30 Jan 2017 19:44:53 +0000 Subject: [PATCH 1259/1484] Experimental change to invoke the preupdate hook when WITHOUT ROWID tables are written. FossilOrigin-Name: 856f8604c59c8fdd9bfb7d86fc0e212f091ab49a --- ext/session/session1.test | 245 +++++++++++++++++++----------------- ext/session/sessionwor.test | 57 +++++++++ manifest | 27 ++-- manifest.uuid | 2 +- src/insert.c | 17 ++- src/vdbe.c | 13 +- src/vdbeInt.h | 1 + src/vdbeapi.c | 6 + src/vdbeaux.c | 11 +- test/hook2.test | 218 ++++++++++++++++++++++++++++++++ 10 files changed, 458 insertions(+), 139 deletions(-) create mode 100644 ext/session/sessionwor.test create mode 100644 test/hook2.test diff --git a/ext/session/session1.test b/ext/session/session1.test index 5216824bdd..c96c248c5e 100644 --- a/ext/session/session1.test +++ b/ext/session/session1.test @@ -20,46 +20,61 @@ ifcapable !session {finish_test; return} set testprefix session1 -do_execsql_test 1.0 { - CREATE TABLE t1(x PRIMARY KEY, y); +# Run all tests in this file twice. Once with "WITHOUT ROWID", and once +# with regular rowid tables. +# +foreach {tn trailing} { + 1 "" + 2 " WITHOUT ROWID " +} { +eval [string map [list %WR% $trailing] { + +db close +forcedelete test.db test.db2 +reset_db + +do_execsql_test $tn.1.0 { + CREATE TABLE t1(x PRIMARY KEY, y) %WR%; INSERT INTO t1 VALUES('abc', 'def'); } #------------------------------------------------------------------------- # Test creating, attaching tables to and deleting session objects. # -do_test 1.1 { sqlite3session S db main } {S} -do_test 1.2 { S delete } {} -do_test 1.3 { sqlite3session S db main } {S} -do_test 1.4 { S attach t1 } {} -do_test 1.5 { S delete } {} -do_test 1.6 { sqlite3session S db main } {S} -do_test 1.7 { S attach t1 ; S attach t2 ; S attach t3 } {} -do_test 1.8 { S attach t1 ; S attach t2 ; S attach t3 } {} -do_test 1.9 { S delete } {} -do_test 1.10 { +do_test $tn.1.1 { sqlite3session S db main } {S} +do_test $tn.1.2 { S delete } {} +do_test $tn.1.3 { sqlite3session S db main } {S} +do_test $tn.1.4 { S attach t1 } {} +do_test $tn.1.5 { S delete } {} +do_test $tn.1.6 { sqlite3session S db main } {S} +do_test $tn.1.7 { S attach t1 ; S attach t2 ; S attach t3 } {} +do_test $tn.1.8 { S attach t1 ; S attach t2 ; S attach t3 } {} +do_test $tn.1.9 { S delete } {} +do_test $tn.1.10 { sqlite3session S db main S attach t1 execsql { INSERT INTO t1 VALUES('ghi', 'jkl') } } {} -do_test 1.11 { S delete } {} -do_test 1.12 { - sqlite3session S db main - S attach t1 - execsql { INSERT INTO t1 VALUES('mno', 'pqr') } - execsql { UPDATE t1 SET x = 111 WHERE rowid = 1 } - execsql { DELETE FROM t1 WHERE rowid = 2 } -} {} -do_test 1.13 { - S changeset - S delete -} {} +do_test $tn.1.11 { S delete } {} +if {$tn==1} { + do_test $tn.1.12 { + sqlite3session S db main + S attach t1 + execsql { INSERT INTO t1 VALUES('mno', 'pqr') } + execsql { UPDATE t1 SET x = 111 WHERE rowid = 1 } + execsql { DELETE FROM t1 WHERE rowid = 2 } + } {} + do_test $tn.1.13 { + S changeset + S delete + } {} +} #------------------------------------------------------------------------- # Simple changeset tests. Also test the sqlite3changeset_invert() # function. # -do_test 2.1.1 { +do_test $tn.2.1.1 { execsql { DELETE FROM t1 } sqlite3session S db main S attach t1 @@ -67,36 +82,36 @@ do_test 2.1.1 { execsql { INSERT INTO t1 VALUES(2, 'Ayutthaya') } execsql { INSERT INTO t1 VALUES(3, 'Thonburi') } } {} -do_changeset_test 2.1.2 S { +do_changeset_test $tn.2.1.2 S { {INSERT t1 0 X. {} {i 1 t Sukhothai}} {INSERT t1 0 X. {} {i 2 t Ayutthaya}} {INSERT t1 0 X. {} {i 3 t Thonburi}} } -do_changeset_invert_test 2.1.3 S { +do_changeset_invert_test $tn.2.1.3 S { {DELETE t1 0 X. {i 1 t Sukhothai} {}} {DELETE t1 0 X. {i 2 t Ayutthaya} {}} {DELETE t1 0 X. {i 3 t Thonburi} {}} } -do_test 2.1.4 { S delete } {} +do_test $tn.2.1.4 { S delete } {} -do_test 2.2.1 { +do_test $tn.2.2.1 { sqlite3session S db main S attach t1 execsql { DELETE FROM t1 WHERE 1 } } {} -do_changeset_test 2.2.2 S { +do_changeset_test $tn.2.2.2 S { {DELETE t1 0 X. {i 1 t Sukhothai} {}} {DELETE t1 0 X. {i 2 t Ayutthaya} {}} {DELETE t1 0 X. {i 3 t Thonburi} {}} } -do_changeset_invert_test 2.2.3 S { +do_changeset_invert_test $tn.2.2.3 S { {INSERT t1 0 X. {} {i 1 t Sukhothai}} {INSERT t1 0 X. {} {i 2 t Ayutthaya}} {INSERT t1 0 X. {} {i 3 t Thonburi}} } -do_test 2.2.4 { S delete } {} +do_test $tn.2.2.4 { S delete } {} -do_test 2.3.1 { +do_test $tn.2.3.1 { execsql { DELETE FROM t1 } sqlite3session S db main execsql { INSERT INTO t1 VALUES(1, 'Sukhothai') } @@ -110,7 +125,7 @@ do_test 2.3.1 { } } {} -do_changeset_test 2.3.2 S { +do_changeset_test $tn.2.3.2 S { {INSERT t1 0 X. {} {i 10 t Sukhothai}} {DELETE t1 0 X. {i 1 t Sukhothai} {}} {UPDATE t1 0 X. {i 2 t Ayutthaya} {{} {} t Surin}} @@ -118,24 +133,24 @@ do_changeset_test 2.3.2 S { {INSERT t1 0 X. {} {i 20 t Thapae}} } -do_changeset_invert_test 2.3.3 S { +do_changeset_invert_test $tn.2.3.3 S { {DELETE t1 0 X. {i 10 t Sukhothai} {}} {INSERT t1 0 X. {} {i 1 t Sukhothai}} {UPDATE t1 0 X. {i 2 t Surin} {{} {} t Ayutthaya}} {INSERT t1 0 X. {} {i 3 t Thonburi}} {DELETE t1 0 X. {i 20 t Thapae} {}} } -do_test 2.3.4 { S delete } {} +do_test $tn.2.3.4 { S delete } {} -do_test 2.4.1 { +do_test $tn.2.4.1 { sqlite3session S db main S attach t1 execsql { INSERT INTO t1 VALUES(100, 'Bangkok') } execsql { DELETE FROM t1 WHERE x = 100 } } {} -do_changeset_test 2.4.2 S {} -do_changeset_invert_test 2.4.3 S {} -do_test 2.4.4 { S delete } {} +do_changeset_test $tn.2.4.2 S {} +do_changeset_invert_test $tn.2.4.3 S {} +do_test $tn.2.4.4 { S delete } {} #------------------------------------------------------------------------- # Test the application of simple changesets. These tests also test that @@ -189,16 +204,16 @@ proc do_db2_test {testname sql {result {}}} { # Test INSERT changesets. # -do_test 3.1.0 { - execsql { CREATE TABLE t1(a PRIMARY KEY, b NOT NULL) } db2 +do_test $tn.3.1.0 { + execsql { CREATE TABLE t1(a PRIMARY KEY, b NOT NULL) %WR% } db2 execsql { - CREATE TABLE t1(a PRIMARY KEY, b); + CREATE TABLE t1(a PRIMARY KEY, b) %WR%; INSERT INTO t1 VALUES(1, 'one'); INSERT INTO t1 VALUES(2, 'two'); } db } {} -do_db2_test 3.1.1 "INSERT INTO t1 VALUES(6, 'VI')" -do_conflict_test 3.1.2 -tables t1 -sql { +do_db2_test $tn.3.1.1 "INSERT INTO t1 VALUES(6, 'VI')" +do_conflict_test $tn.3.1.2 -tables t1 -sql { INSERT INTO t1 VALUES(3, 'three'); INSERT INTO t1 VALUES(4, 'four'); INSERT INTO t1 VALUES(5, 'five'); @@ -210,34 +225,34 @@ do_conflict_test 3.1.2 -tables t1 -sql { {INSERT t1 CONSTRAINT {i 8 n {}}} } -do_db2_test 3.1.3 "SELECT * FROM t1" { - 6 VI 3 three 4 four 5 five 7 seven +do_db2_test $tn.3.1.3 "SELECT * FROM t1 ORDER BY a" { + 3 three 4 four 5 five 6 VI 7 seven } -do_execsql_test 3.1.4 "SELECT * FROM t1" { +do_execsql_test $tn.3.1.4 "SELECT * FROM t1" { 1 one 2 two 3 three 4 four 5 five 6 six 7 seven 8 {} } # Test DELETE changesets. # -do_execsql_test 3.2.1 { +do_execsql_test $tn.3.2.1 { PRAGMA foreign_keys = on; - CREATE TABLE t2(a PRIMARY KEY, b); + CREATE TABLE t2(a PRIMARY KEY, b)%WR%; CREATE TABLE t3(c, d REFERENCES t2); INSERT INTO t2 VALUES(1, 'one'); INSERT INTO t2 VALUES(2, 'two'); INSERT INTO t2 VALUES(3, 'three'); INSERT INTO t2 VALUES(4, 'four'); } -do_db2_test 3.2.2 { +do_db2_test $tn.3.2.2 { PRAGMA foreign_keys = on; - CREATE TABLE t2(a PRIMARY KEY, b); + CREATE TABLE t2(a PRIMARY KEY, b)%WR%; CREATE TABLE t3(c, d REFERENCES t2); INSERT INTO t2 VALUES(1, 'one'); INSERT INTO t2 VALUES(2, 'two'); INSERT INTO t2 VALUES(4, 'five'); INSERT INTO t3 VALUES('i', 1); } -do_conflict_test 3.2.3 -tables t2 -sql { +do_conflict_test $tn.3.2.3 -tables t2 -sql { DELETE FROM t2 WHERE a = 1; DELETE FROM t2 WHERE a = 2; DELETE FROM t2 WHERE a = 3; @@ -247,26 +262,26 @@ do_conflict_test 3.2.3 -tables t2 -sql { {DELETE t2 DATA {i 4 t four} {i 4 t five}} {FOREIGN_KEY 1} } -do_execsql_test 3.2.4 "SELECT * FROM t2" {} -do_db2_test 3.2.5 "SELECT * FROM t2" {4 five} +do_execsql_test $tn.3.2.4 "SELECT * FROM t2" {} +do_db2_test $tn.3.2.5 "SELECT * FROM t2" {4 five} # Test UPDATE changesets. # -do_execsql_test 3.3.1 { - CREATE TABLE t4(a, b, c, PRIMARY KEY(b, c)); +do_execsql_test $tn.3.3.1 { + CREATE TABLE t4(a, b, c, PRIMARY KEY(b, c))%WR%; INSERT INTO t4 VALUES(1, 2, 3); INSERT INTO t4 VALUES(4, 5, 6); INSERT INTO t4 VALUES(7, 8, 9); INSERT INTO t4 VALUES(10, 11, 12); } -do_db2_test 3.3.2 { - CREATE TABLE t4(a NOT NULL, b, c, PRIMARY KEY(b, c)); +do_db2_test $tn.3.3.2 { + CREATE TABLE t4(a NOT NULL, b, c, PRIMARY KEY(b, c))%WR%; INSERT INTO t4 VALUES(0, 2, 3); INSERT INTO t4 VALUES(4, 5, 7); INSERT INTO t4 VALUES(7, 8, 9); INSERT INTO t4 VALUES(10, 11, 12); } -do_conflict_test 3.3.3 -tables t4 -sql { +do_conflict_test $tn.3.3.3 -tables t4 -sql { UPDATE t4 SET a = -1 WHERE b = 2; UPDATE t4 SET a = -1 WHERE b = 5; UPDATE t4 SET a = NULL WHERE c = 9; @@ -276,8 +291,8 @@ do_conflict_test 3.3.3 -tables t4 -sql { {UPDATE t4 NOTFOUND {i 4 i 5 i 6} {i -1 {} {} {} {}}} {UPDATE t4 CONSTRAINT {i 7 i 8 i 9} {n {} {} {} {} {}}} } -do_db2_test 3.3.4 { SELECT * FROM t4 } {0 2 3 4 5 7 7 8 9 x 11 12} -do_execsql_test 3.3.5 { SELECT * FROM t4 } {-1 2 3 -1 5 6 {} 8 9 x 11 12} +do_db2_test $tn.3.3.4 { SELECT * FROM t4 } {0 2 3 4 5 7 7 8 9 x 11 12} +do_execsql_test $tn.3.3.5 { SELECT * FROM t4 } {-1 2 3 -1 5 6 {} 8 9 x 11 12} #------------------------------------------------------------------------- # This next block of tests verifies that values returned by the conflict @@ -297,16 +312,16 @@ proc xConflict {args} { return $::conflict_return } -foreach {tn conflict_return after} { +foreach {tn2 conflict_return after} { 1 OMIT {1 2 value1 4 5 7 10 x x} 2 REPLACE {1 2 value1 4 5 value2 10 8 9} } { test_reset - do_test 4.$tn.1 { + do_test $tn.4.$tn2.1 { foreach db {db db2} { execsql { - CREATE TABLE t1(a, b, c, PRIMARY KEY(a)); + CREATE TABLE t1(a, b, c, PRIMARY KEY(a))%WR%; INSERT INTO t1 VALUES(1, 2, 3); INSERT INTO t1 VALUES(4, 5, 6); INSERT INTO t1 VALUES(7, 8, 9); @@ -318,7 +333,7 @@ foreach {tn conflict_return after} { } db2 } {} - do_conflict_test 4.$tn.2 -tables t1 -sql { + do_conflict_test $tn.4.$tn2.2 -tables t1 -sql { UPDATE t1 SET c = 'value1' WHERE a = 1; -- no conflict UPDATE t1 SET c = 'value2' WHERE a = 4; -- DATA conflict UPDATE t1 SET a = 10 WHERE a = 7; -- CONFLICT conflict @@ -327,19 +342,19 @@ foreach {tn conflict_return after} { {UPDATE t1 DATA {i 4 {} {} i 6} {{} {} {} {} t value2} {i 4 i 5 i 7}} } - do_db2_test 4.$tn.3 "SELECT * FROM t1 ORDER BY a" $after + do_db2_test $tn.4.$tn2.3 "SELECT * FROM t1 ORDER BY a" $after } -foreach {tn conflict_return} { +foreach {tn2 conflict_return} { 1 OMIT 2 REPLACE } { test_reset - do_test 5.$tn.1 { + do_test $tn.5.$tn2.1 { # Create an identical schema in both databases. set schema { - CREATE TABLE "'foolish name'"(x, y, z, PRIMARY KEY(x, y)); + CREATE TABLE "'foolish name'"(x, y, z, PRIMARY KEY(x, y))%WR%; } execsql $schema db execsql $schema db2 @@ -354,7 +369,7 @@ foreach {tn conflict_return} { } {} - do_conflict_test 5.$tn.2 -tables {{'foolish name'}} -sql { + do_conflict_test $tn.5.$tn2.2 -tables {{'foolish name'}} -sql { INSERT INTO "'foolish name'" VALUES('one', 'two', 2); } -conflicts { {INSERT {'foolish name'} CONFLICT {t one t two i 2} {t one t two t i}} @@ -362,14 +377,14 @@ foreach {tn conflict_return} { set res(REPLACE) {one one ii one two 2 two two ii} set res(OMIT) {one one ii one two i two two ii} - do_db2_test 5.$tn.3 { + do_db2_test $tn.5.$tn2.3 { SELECT * FROM "'foolish name'" ORDER BY x, y } $res($conflict_return) - do_test 5.$tn.1 { + do_test $tn.5.$tn2.1 { set schema { - CREATE TABLE d1("z""z" PRIMARY KEY, y); + CREATE TABLE d1("z""z" PRIMARY KEY, y)%WR%; INSERT INTO d1 VALUES(1, 'one'); INSERT INTO d1 VALUES(2, 'two'); } @@ -382,7 +397,7 @@ foreach {tn conflict_return} { } {} - do_conflict_test 5.$tn.2 -tables d1 -sql { + do_conflict_test $tn.5.$tn2.2 -tables d1 -sql { DELETE FROM d1 WHERE "z""z" = 2; } -conflicts { {DELETE d1 DATA {i 2 t two} {i 2 t TWO}} @@ -390,7 +405,7 @@ foreach {tn conflict_return} { set res(REPLACE) {1 one} set res(OMIT) {1 one 2 TWO} - do_db2_test 5.$tn.3 "SELECT * FROM d1" $res($conflict_return) + do_db2_test $tn.5.$tn2.3 "SELECT * FROM d1" $res($conflict_return) } #------------------------------------------------------------------------- @@ -398,10 +413,10 @@ foreach {tn conflict_return} { # test_reset set schema { - CREATE TABLE t1(a COLLATE nocase PRIMARY KEY, b); - CREATE TABLE t2(a, b PRIMARY KEY); + CREATE TABLE t1(a COLLATE nocase PRIMARY KEY, b)%WR%; + CREATE TABLE t2(a, b PRIMARY KEY)%WR%; } -do_test 6.0 { +do_test $tn.6.0 { execsql $schema db execsql $schema db2 execsql { @@ -411,7 +426,7 @@ do_test 6.0 { } {} set conflict_return "" -do_conflict_test 6.1 -tables {t1 t2} -sql { +do_conflict_test $tn.6.1 -tables {t1 t2} -sql { INSERT INTO t1 VALUES('1', '2'); INSERT INTO t1 VALUES('A', 'B'); INSERT INTO t2 VALUES('A', 'B'); @@ -419,8 +434,8 @@ do_conflict_test 6.1 -tables {t1 t2} -sql { {INSERT t1 CONFLICT {t A t B} {t a t b}} } -do_db2_test 6.2 "SELECT * FROM t1" {a b 1 2} -do_db2_test 6.3 "SELECT * FROM t2" {a b A B} +do_db2_test $tn.6.2 "SELECT * FROM t1 ORDER BY a" {1 2 a b} +do_db2_test $tn.6.3 "SELECT * FROM t2 ORDER BY a" {A B a b} #------------------------------------------------------------------------- # Test that session objects are not confused by changes to table in @@ -429,10 +444,10 @@ do_db2_test 6.3 "SELECT * FROM t2" {a b A B} catch { db2 close } drop_all_tables forcedelete test.db2 -do_iterator_test 7.1 * { +do_iterator_test $tn.7.1 * { ATTACH 'test.db2' AS aux; - CREATE TABLE main.t1(x PRIMARY KEY, y); - CREATE TABLE aux.t1(x PRIMARY KEY, y); + CREATE TABLE main.t1(x PRIMARY KEY, y)%WR%; + CREATE TABLE aux.t1(x PRIMARY KEY, y)%WR%; INSERT INTO main.t1 VALUES('one', 1); INSERT INTO main.t1 VALUES('two', 2); @@ -446,10 +461,10 @@ do_iterator_test 7.1 * { #------------------------------------------------------------------------- # Test the sqlite3session_isempty() function. # -do_test 8.1 { +do_test $tn.8.1 { execsql { - CREATE TABLE t5(x PRIMARY KEY, y); - CREATE TABLE t6(x PRIMARY KEY, y); + CREATE TABLE t5(x PRIMARY KEY, y)%WR%; + CREATE TABLE t6(x PRIMARY KEY, y)%WR%; INSERT INTO t5 VALUES('a', 'b'); INSERT INTO t6 VALUES('a', 'b'); } @@ -458,20 +473,20 @@ do_test 8.1 { S isempty } {1} -do_test 8.2 { +do_test $tn.8.2 { execsql { DELETE FROM t5 } S isempty } {0} -do_test 8.3 { +do_test $tn.8.3 { S delete sqlite3session S db main S attach t5 execsql { DELETE FROM t5 } S isempty } {1} -do_test 8.4 { S delete } {} +do_test $tn.8.4 { S delete } {} -do_test 8.5 { +do_test $tn.8.5 { sqlite3session S db main S attach t5 S attach t6 @@ -479,7 +494,7 @@ do_test 8.5 { S isempty } {0} -do_test 8.6 { +do_test $tn.8.6 { S delete sqlite3session S db main S attach t5 @@ -487,20 +502,20 @@ do_test 8.6 { execsql { INSERT INTO t6 VALUES(1, 2) } S isempty } {0} -do_test 8.7 { S delete } {} +do_test $tn.8.7 { S delete } {} #------------------------------------------------------------------------- # -do_execsql_test 9.1 { - CREATE TABLE t7(a, b, c, d, e PRIMARY KEY, f, g); +do_execsql_test $tn.9.1 { + CREATE TABLE t7(a, b, c, d, e PRIMARY KEY, f, g)%WR%; INSERT INTO t7 VALUES(1, 1, 1, 1, 1, 1, 1); } -do_test 9.2 { +do_test $tn.9.2 { sqlite3session S db main S attach * execsql { UPDATE t7 SET b=2, d=2 } } {} -do_changeset_test 9.2 S {{UPDATE t7 0 ....X.. {{} {} i 1 {} {} i 1 i 1 {} {} {} {}} {{} {} i 2 {} {} i 2 {} {} {} {} {} {}}}} +do_changeset_test $tn.9.2 S {{UPDATE t7 0 ....X.. {{} {} i 1 {} {} i 1 i 1 {} {} {} {}} {{} {} i 2 {} {} i 2 {} {} {} {} {} {}}}} S delete catch { db2 close } @@ -509,9 +524,9 @@ catch { db2 close } # reset_db set tblname [string repeat tblname123 100] -do_test 10.1.1 { +do_test $tn.10.1.1 { execsql " - CREATE TABLE $tblname (a PRIMARY KEY, b); + CREATE TABLE $tblname (a PRIMARY KEY, b)%WR%; INSERT INTO $tblname VALUES('xyz', 'def'); " sqlite3session S db main @@ -522,18 +537,18 @@ do_test 10.1.1 { " } {} breakpoint -do_changeset_test 10.1.2 S " +do_changeset_test $tn.10.1.2 S " {INSERT $tblname 0 X. {} {t uvw t abc}} {DELETE $tblname 0 X. {t xyz t def} {}} " -do_test 10.1.4 { S delete } {} +do_test $tn.10.1.4 { S delete } {} #--------------------------------------------------------------- reset_db -do_execsql_test 11.1 { +do_execsql_test $tn.11.1 { CREATE TABLE t1(a, b); } -do_test 11.2 { +do_test $tn.11.2 { sqlite3session S db main S attach t1 execsql { @@ -550,9 +565,9 @@ S delete # reset_db set tblname [string repeat tblname123 100] -do_test 10.1.1 { +do_test $tn.10.1.1 { execsql " - CREATE TABLE $tblname (a PRIMARY KEY, b); + CREATE TABLE $tblname (a PRIMARY KEY, b)%WR%; INSERT INTO $tblname VALUES('xyz', 'def'); " sqlite3session S db main @@ -563,35 +578,35 @@ do_test 10.1.1 { " } {} breakpoint -do_changeset_test 10.1.2 S " +do_changeset_test $tn.10.1.2 S " {INSERT $tblname 0 X. {} {t uvw t abc}} {DELETE $tblname 0 X. {t xyz t def} {}} " -do_test 10.1.4 { S delete } {} +do_test $tn.10.1.4 { S delete } {} #------------------------------------------------------------------------- # Test the effect of updating a column from 0.0 to 0.0. # reset_db -do_execsql_test 11.1 { - CREATE TABLE t1(a INTEGER PRIMARY KEY, b REAL); +do_execsql_test $tn.11.1 { + CREATE TABLE t1(a INTEGER PRIMARY KEY, b REAL)%WR%; INSERT INTO t1 VALUES(1, 0.0); } -do_iterator_test 11.2 * { +do_iterator_test $tn.11.2 * { UPDATE t1 SET b = 0.0; } { } reset_db -do_execsql_test 12.1 { - CREATE TABLE t1(r INTEGER PRIMARY KEY, a, b); +do_execsql_test $tn.12.1 { + CREATE TABLE t1(r INTEGER PRIMARY KEY, a, b)%WR%; CREATE INDEX i1 ON t1(a); INSERT INTO t1 VALUES(1, 1, 1); INSERT INTO t1 VALUES(2, 1, 2); INSERT INTO t1 VALUES(3, 1, 3); } -do_iterator_test 12.2 * { +do_iterator_test $tn.12.2 * { UPDATE t1 SET b='one' WHERE a=1; } { {UPDATE t1 0 X.. {i 1 {} {} i 1} {{} {} {} {} t one}} @@ -599,6 +614,8 @@ do_iterator_test 12.2 * { {UPDATE t1 0 X.. {i 3 {} {} i 3} {{} {} {} {} t one}} } +}] +} finish_test diff --git a/ext/session/sessionwor.test b/ext/session/sessionwor.test new file mode 100644 index 0000000000..d906a92b62 --- /dev/null +++ b/ext/session/sessionwor.test @@ -0,0 +1,57 @@ +# 2017 Jan 31 +# +# 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. +# +#*********************************************************************** +# +# The focus of this file is testing the session module. Specifically, +# testing support for WITHOUT ROWID tables. +# + +if {![info exists testdir]} { + set testdir [file join [file dirname [info script]] .. .. test] +} +source [file join [file dirname [info script]] session_common.tcl] +source $testdir/tester.tcl +ifcapable !session {finish_test; return} + +set testprefix sessionwor + +proc test_reset {} { + catch { db close } + catch { db2 close } + forcedelete test.db test.db2 + sqlite3 db test.db + sqlite3 db2 test.db2 +} + + +do_execsql_test 1.0 { + CREATE TABLE t1(a PRIMARY KEY, b) WITHOUT ROWID; +} + +do_iterator_test 1.1 t1 { + INSERT INTO t1 VALUES('one', 'two'); +} { + {INSERT t1 0 X. {} {t one t two}} +} + +do_iterator_test 1.2 t1 { + UPDATE t1 SET b='three' +} { + {UPDATE t1 0 X. {t one t two} {{} {} t three}} +} + +do_iterator_test 1.3 t1 { + DELETE FROM t1; +} { + {DELETE t1 0 X. {t one t three} {}} +} + +finish_test + diff --git a/manifest b/manifest index 229623bcc5..c93ba97d64 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sbuilding\swith\sSQLITE_OMIT_FOREIGN_KEY\sdefined. -D 2017-01-30T11:38:19.468 +C Experimental\schange\sto\sinvoke\sthe\spreupdate\shook\swhen\sWITHOUT\sROWID\stables\sare\nwritten. +D 2017-01-30T19:44:53.682 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -288,7 +288,7 @@ F ext/rtree/sqlite3rtree.h 9c5777af3d2921c7b4ae4954e8e5697502289d28 F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 F ext/session/changeset.c 4ccbaa4531944c24584bf6a61ba3a39c62b6267a -F ext/session/session1.test 482e9b861169d0b7e283e1563a28c0fa32779fa5 +F ext/session/session1.test c8a50e0e8581dc1a00e832aa59bb61f180404d44 F ext/session/session2.test 284de45abae4cc1082bc52012ee81521d5ac58e0 F ext/session/session3.test a7a9ce59b8d1e49e2cc23d81421ac485be0eea01 F ext/session/session4.test 457b02bdc349eb01151e54de014df77abd3c08c8 @@ -306,6 +306,7 @@ F ext/session/sessionG.test 01ef705096a9d3984eebdcca79807a211dee1b60 F ext/session/session_common.tcl 9b696a341cf1d3744823715ed92bb19749b6c3d4 F ext/session/sessionfault.test da273f2712b6411e85e71465a1733b8501dbf6f7 F ext/session/sessionfault2.test 04aa0bc9aa70ea43d8de82c4f648db4de1e990b0 +F ext/session/sessionwor.test 2f3744236dc8b170a695b7d8ddc8c743c7e79fdc F ext/session/sqlite3session.c c61a43396368ec00dc127f7bc647e9bd6a4ee5fb F ext/session/sqlite3session.h 9345166bd8f80562145586cf817f707de5ecada2 F ext/session/test_session.c eb0bd6c1ea791c1d66ee4ef94c16500dad936386 @@ -353,7 +354,7 @@ F src/hash.c 63d0ee752a3b92d4695b2b1f5259c4621b2cfebd F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4 F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 -F src/insert.c 8183e1778ec42d26732bec8c98aeffa8af13038f +F src/insert.c 444354c23d4d140a57d6eb46f34e376a7f8f62e8 F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e F src/loadext.c a68d8d1d14cf7488bb29dc5311cb1ce9a4404258 F src/main.c e207b81542d13b9f13d61e78ca441f9781f055b0 @@ -458,11 +459,11 @@ F src/update.c 456d4a4656f8a03c2abc88a51b19172197400e58 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c a88b0466fddf445ce752226d4698ca3faada620a F src/vacuum.c 33c174b28886b2faf26e503b5a49a1c01a9b1c16 -F src/vdbe.c c27cc34be1d9169c1c191238025781684bdcd4ec +F src/vdbe.c 57f41c8c74ceb757abbd4cda72c44fc40d57f425 F src/vdbe.h 59998ffd71d7caa8886bc78dafaf8caeccd4c13c -F src/vdbeInt.h 281cb70332dc8b593b8c7afe776f3a2ba7d4255e -F src/vdbeapi.c 7a65f10684982daecfce50f557f2632b7f20b198 -F src/vdbeaux.c 6847b02aa2db536ed15d90f1fdc2923afef93c5b +F src/vdbeInt.h 4e4b15b2e1330e1636e4e01974eab2b0b985092f +F src/vdbeapi.c 3e4a8893feeb78620f4aac4ac5b85d92255b97e1 +F src/vdbeaux.c b9a36e530e6525ca9d9a685bc7b1d01fa77b5cf8 F src/vdbeblob.c 2b3d1ad915dbe5dc92c48759dc18fa8c697e78e5 F src/vdbemem.c 3b5a9a5b375458d3e12a50ae1aaa41eeec2175fd F src/vdbesort.c eda25cb2d1727efca6f7862fea32b8aa33c0face @@ -834,6 +835,7 @@ F test/genesis.tcl 1e2e2e8e5cc4058549a154ff1892fe5c9de19f98 F test/hexlit.test 4a6a5f46e3c65c4bf1fa06f5dd5a9507a5627751 F test/hidden.test 23c1393a79e846d68fd902d72c85d5e5dcf98711 F test/hook.test dbc0b87756e1e20e7497b56889c9e9cd2f8cc2b5 +F test/hook2.test b9ff3b8c6519fb67f33192f1afe86e7782ee4ac8 F test/icu.test 73956798bace8982909c00476b216714a6d0559a F test/ieee754.test 806fc0ce7f305f57e3331eaceeddcfec9339e607 F test/imposter1.test c3f1db2d3db2c24611a6596a3fc0ffc14f1466c8 @@ -1548,7 +1550,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 4fe879d4b5da6ae0688a7a99004683a234966597 -R c0ed5c24fdff676195cd77401e89700b +P e93d2c49a44af994ff10cc9cc7eafacd5a4f73ab +R f7cc20c31f0badea537c676e1225b282 +T *branch * preupdate-without-rowid +T *sym-preupdate-without-rowid * +T -sym-trunk * U dan -Z 6d1b138d17ccacee0c622f2ed331ca89 +Z 812bce2fe1496eddb1cec5705157fb44 diff --git a/manifest.uuid b/manifest.uuid index eec33fc0a4..67552c1672 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e93d2c49a44af994ff10cc9cc7eafacd5a4f73ab \ No newline at end of file +856f8604c59c8fdd9bfb7d86fc0e212f091ab49a \ No newline at end of file diff --git a/src/insert.c b/src/insert.c index 5370ef77ed..894bfc2cc1 100644 --- a/src/insert.c +++ b/src/insert.c @@ -1730,16 +1730,23 @@ void sqlite3CompleteInsertion( sqlite3VdbeAddOp2(v, OP_IsNull, aRegIdx[i], sqlite3VdbeCurrentAddr(v)+2); VdbeCoverage(v); } - sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iIdxCur+i, aRegIdx[i], - aRegIdx[i]+1, - pIdx->uniqNotNull ? pIdx->nKeyCol: pIdx->nColumn); - pik_flags = 0; - if( useSeekResult ) pik_flags = OPFLAG_USESEEKRESULT; + pik_flags = (useSeekResult ? OPFLAG_USESEEKRESULT : 0); if( IsPrimaryKeyIndex(pIdx) && !HasRowid(pTab) ){ assert( pParse->nested==0 ); pik_flags |= OPFLAG_NCHANGE; pik_flags |= (update_flags & OPFLAG_SAVEPOSITION); +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK + if( update_flags==0 ){ + sqlite3VdbeAddOp4(v, OP_InsertInt, + iIdxCur+i, aRegIdx[i], 0, (char*)pTab, P4_TABLE + ); + sqlite3VdbeChangeP5(v, OPFLAG_ISNOOP); + } +#endif } + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iIdxCur+i, aRegIdx[i], + aRegIdx[i]+1, + pIdx->uniqNotNull ? pIdx->nKeyCol: pIdx->nColumn); sqlite3VdbeChangeP5(v, pik_flags); } if( !HasRowid(pTab) ) return; diff --git a/src/vdbe.c b/src/vdbe.c index ded4462398..5462e541c5 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -4384,7 +4384,7 @@ case OP_InsertInt: { assert( pC!=0 ); assert( pC->eCurType==CURTYPE_BTREE ); assert( pC->uc.pCursor!=0 ); - assert( pC->isTable ); + assert( (pOp->p5 & OPFLAG_ISNOOP) || pC->isTable ); assert( pOp->p4type==P4_TABLE || pOp->p4type>=P4_STATIC ); REGISTER_TRACE(pOp->p2, pData); @@ -4400,11 +4400,10 @@ case OP_InsertInt: { } if( pOp->p4type==P4_TABLE && HAS_UPDATE_HOOK(db) ){ - assert( pC->isTable ); assert( pC->iDb>=0 ); zDb = db->aDb[pC->iDb].zDbSName; pTab = pOp->p4.pTab; - assert( HasRowid(pTab) ); + assert( (pOp->p5 & OPFLAG_ISNOOP) || HasRowid(pTab) ); op = ((pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT); }else{ pTab = 0; /* Not needed. Silence a comiler warning. */ @@ -4419,6 +4418,7 @@ case OP_InsertInt: { ){ sqlite3VdbePreUpdateHook(p, pC, SQLITE_INSERT, zDb, pTab, x.nKey, pOp->p2); } + if( pOp->p5 & OPFLAG_ISNOOP ) break; #endif if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++; @@ -4531,8 +4531,11 @@ case OP_Delete: { #ifdef SQLITE_ENABLE_PREUPDATE_HOOK /* Invoke the pre-update-hook if required. */ - if( db->xPreUpdateCallback && pOp->p4.pTab && HasRowid(pTab) ){ - assert( !(opflags & OPFLAG_ISUPDATE) || (aMem[pOp->p3].flags & MEM_Int) ); + if( db->xPreUpdateCallback && pOp->p4.pTab ){ + assert( !(opflags & OPFLAG_ISUPDATE) + || HasRowid(pTab)==0 + || (aMem[pOp->p3].flags & MEM_Int) + ); sqlite3VdbePreUpdateHook(p, pC, (opflags & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_DELETE, zDb, pTab, pC->movetoTarget, diff --git a/src/vdbeInt.h b/src/vdbeInt.h index 3e6bb06889..989cdfd346 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -434,6 +434,7 @@ struct PreUpdate { i64 iKey2; /* Second key value passed to hook */ Mem *aNew; /* Array of new.* values */ Table *pTab; /* Schema object being upated */ + Index *pPk; /* PK index if pTab is WITHOUT ROWID */ }; /* diff --git a/src/vdbeapi.c b/src/vdbeapi.c index 7ecdac87c3..6eb97f1d1d 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -1669,6 +1669,9 @@ int sqlite3_preupdate_old(sqlite3 *db, int iIdx, sqlite3_value **ppValue){ rc = SQLITE_MISUSE_BKPT; goto preupdate_old_out; } + if( p->pPk ){ + iIdx = sqlite3ColumnOfIndex(p->pPk, iIdx); + } if( iIdx>=p->pCsr->nField || iIdx<0 ){ rc = SQLITE_RANGE; goto preupdate_old_out; @@ -1754,6 +1757,9 @@ int sqlite3_preupdate_new(sqlite3 *db, int iIdx, sqlite3_value **ppValue){ rc = SQLITE_MISUSE_BKPT; goto preupdate_new_out; } + if( p->pPk && p->op!=SQLITE_UPDATE ){ + iIdx = sqlite3ColumnOfIndex(p->pPk, iIdx); + } if( iIdx>=p->pCsr->nField || iIdx<0 ){ rc = SQLITE_RANGE; goto preupdate_new_out; diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 23c31d4029..68f6a5acc8 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -4620,10 +4620,15 @@ void sqlite3VdbePreUpdateHook( assert( db->pPreUpdate==0 ); memset(&preupdate, 0, sizeof(PreUpdate)); - if( op==SQLITE_UPDATE ){ - iKey2 = v->aMem[iReg].u.i; + if( HasRowid(pTab)==0 ){ + iKey1 = iKey2 = 0; + preupdate.pPk = sqlite3PrimaryKeyIndex(pTab); }else{ - iKey2 = iKey1; + if( op==SQLITE_UPDATE ){ + iKey2 = v->aMem[iReg].u.i; + }else{ + iKey2 = iKey1; + } } assert( pCsr->nField==pTab->nCol diff --git a/test/hook2.test b/test/hook2.test new file mode 100644 index 0000000000..9ae1103a7d --- /dev/null +++ b/test/hook2.test @@ -0,0 +1,218 @@ +# 2017 Jan 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. +# +#*********************************************************************** +# The tests in this file focus on the pre-update hook. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set ::testprefix hook2 + +ifcapable !preupdate { + finish_test + return +} + +#------------------------------------------------------------------------- +proc do_preupdate_test {tn sql x} { + set X [list] + foreach elem $x {lappend X $elem} + uplevel do_test $tn [list " + set ::preupdate \[list\] + execsql { $sql } + set ::preupdate + "] [list $X] +} + +proc preupdate_hook {args} { + set type [lindex $args 0] + eval lappend ::preupdate $args + if {$type != "INSERT"} { + for {set i 0} {$i < [db preupdate count]} {incr i} { + lappend ::preupdate [db preupdate old $i] + } + } + if {$type != "DELETE"} { + for {set i 0} {$i < [db preupdate count]} {incr i} { + set rc [catch { db preupdate new $i } v] + lappend ::preupdate $v + } + } +} + +#------------------------------------------------------------------------- +# Simple tests - INSERT, UPDATE and DELETE on a WITHOUT ROWID table. +# +db preupdate hook preupdate_hook +do_execsql_test 1.0 { + CREATE TABLE t1(a PRIMARY KEY, b) WITHOUT ROWID; +} +do_preupdate_test 1.1 { + INSERT INTO t1 VALUES('one', 1); +} { + INSERT main t1 0 0 one 1 +} +do_preupdate_test 1.2 { + UPDATE t1 SET b=2 WHERE a='one'; +} { + UPDATE main t1 0 0 one 1 one 2 +} +do_preupdate_test 1.3 { + DELETE FROM t1 WHERE a='one'; +} { + DELETE main t1 0 0 one 2 +} + +#------------------------------------------------------------------------- +# Some more complex tests for the pre-update callback on WITHOUT ROWID +# tables. +# +# 2.1.1 - INSERT statement. +# 2.1.2 - INSERT INTO ... SELECT statement. +# 2.1.3 - REPLACE INTO ... (PK conflict) +# 2.1.4 - REPLACE INTO ... (other index conflicts) +# 2.1.5 - REPLACE INTO ... (both PK and other index conflicts) +# +# 2.2.1 - DELETE statement. +# 2.2.2 - DELETE statement that uses the truncate optimization. +# +# 2.3.1 - UPDATE statement. +# 2.3.2 - UPDATE statement that modifies the PK. +# 2.3.3 - UPDATE OR REPLACE ... (PK conflict). +# 2.3.4 - UPDATE OR REPLACE ... (other index conflicts) +# 2.3.4 - UPDATE OR REPLACE ... (both PK and other index conflicts) +# +do_execsql_test 2.0 { + CREATE TABLE t2(a DEFAULT 4, b, c, PRIMARY KEY(b, c)) WITHOUT ROWID; + CREATE UNIQUE INDEX t2a ON t2(a); +} + +do_preupdate_test 2.1.1 { + INSERT INTO t2(b, c) VALUES(1, 1); +} { + INSERT main t2 0 0 4 1 1 +} + +do_execsql_test 2.1.2.0 { + CREATE TABLE d1(a DEFAULT 4, b, c, PRIMARY KEY(b, c)) WITHOUT ROWID; + CREATE UNIQUE INDEX d1a ON d1(a); + INSERT INTO d1 VALUES(1, 2, 3); + INSERT INTO d1 VALUES(11, 12, 13); +} +do_preupdate_test 2.1.2.1 { + INSERT INTO t2 SELECT * FROM d1; +} { + INSERT main t2 0 0 1 2 3 + INSERT main t2 0 0 11 12 13 +} +do_preupdate_test 2.1.2.2 { + INSERT INTO t2 SELECT a+20, b+20, c+20 FROM d1; +} { + INSERT main t2 0 0 21 22 23 + INSERT main t2 0 0 31 32 33 +} +do_execsql_test 2.1.2.3 { + SELECT * FROM t2 ORDER BY b, c; +} { + 4 1 1 + 1 2 3 + 11 12 13 + 21 22 23 + 31 32 33 +} +do_preupdate_test 2.1.3 { + REPLACE INTO t2 VALUES(45, 22, 23); +} { + DELETE main t2 0 0 21 22 23 + INSERT main t2 0 0 45 22 23 +} +do_preupdate_test 2.1.4 { + REPLACE INTO t2 VALUES(11, 100, 100); +} { + DELETE main t2 0 0 11 12 13 + INSERT main t2 0 0 11 100 100 +} +do_preupdate_test 2.1.5 { + REPLACE INTO t2(c, b) VALUES(33, 32) +} { + DELETE main t2 0 0 4 1 1 + DELETE main t2 0 0 31 32 33 + INSERT main t2 0 0 4 32 33 +} + +do_execsql_test 2.2.0 { + SELECT * FROM t2 ORDER BY b,c; +} { + 1 2 3 + 45 22 23 + 4 32 33 + 11 100 100 +} +do_preupdate_test 2.2.1 { + DELETE FROM t2 WHERE b=22; +} { + DELETE main t2 0 0 45 22 23 +} +do_preupdate_test 2.2.2 { + DELETE FROM t2; +} { + DELETE main t2 0 0 1 2 3 + DELETE main t2 0 0 4 32 33 + DELETE main t2 0 0 11 100 100 +} + +do_execsql_test 2.3.0 { + CREATE TABLE t3(x, y PRIMARY KEY, z UNIQUE) WITHOUT ROWID; + INSERT INTO t3 VALUES('a', 'b', 'c'); + INSERT INTO t3 VALUES('d', 'e', 'f'); + + INSERT INTO t3 VALUES(1, 1, 1); + INSERT INTO t3 VALUES(2, 2, 2); + INSERT INTO t3 VALUES(3, 3, 3); +} + +do_preupdate_test 2.3.1 { + UPDATE t3 SET x=4 WHERE y IN ('b', 'e', 'x'); +} { + UPDATE main t3 0 0 a b c 4 b c + UPDATE main t3 0 0 d e f 4 e f +} + +do_preupdate_test 2.3.2 { + UPDATE t3 SET y=y||y WHERE z IN('c', 'f'); +} { + UPDATE main t3 0 0 4 b c 4 bb c + UPDATE main t3 0 0 4 e f 4 ee f +} + +do_preupdate_test 2.3.3 { + UPDATE OR REPLACE t3 SET y='bb' WHERE z='f' +} { + DELETE main t3 0 0 4 bb c + UPDATE main t3 0 0 4 ee f 4 bb f +} + +do_preupdate_test 2.3.4 { + UPDATE OR REPLACE t3 SET z=2 WHERE y=1; +} { + DELETE main t3 0 0 2 2 2 + UPDATE main t3 0 0 1 1 1 1 1 2 +} + +do_preupdate_test 2.3.5 { + UPDATE OR REPLACE t3 SET z=2, y='bb' WHERE y=3; +} { + DELETE main t3 0 0 1 1 2 + DELETE main t3 0 0 4 bb f + UPDATE main t3 0 0 3 3 3 3 bb 2 +} + + +finish_test From 18814dfb7eb1811c7e993860a52246bee3743b94 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 31 Jan 2017 03:52:34 +0000 Subject: [PATCH 1260/1484] Performance optimization in sqlite3ExprAssignVarNumber(). FossilOrigin-Name: 5987ca1ff94ed3c1666f783bb15b16158aa7e1db --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/expr.c | 8 +++++++- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 229623bcc5..96a31247b7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sbuilding\swith\sSQLITE_OMIT_FOREIGN_KEY\sdefined. -D 2017-01-30T11:38:19.468 +C Performance\soptimization\sin\ssqlite3ExprAssignVarNumber(). +D 2017-01-31T03:52:34.839 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -344,7 +344,7 @@ F src/ctime.c 9f2296a4e5d26ebf0e0d95a0af4628f1ea694e7a F src/date.c dc3f1391d9297f8c748132813aaffcb117090d6e F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c 0d9d5549d42e79ce4d82ff1db1e6c81e36d2f67c -F src/expr.c f06f41e5e5daca10fb090e70a2502dcc0dbc992b +F src/expr.c 27ac552489a34fc85202084dda32d0a2a0664bfb F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 2e9aabe1aee76273aff8a84ee92c464e095400ae F src/func.c c67273e1ec08abbdcc14c189892a3ff6eeece86b @@ -1548,7 +1548,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 4fe879d4b5da6ae0688a7a99004683a234966597 -R c0ed5c24fdff676195cd77401e89700b -U dan -Z 6d1b138d17ccacee0c622f2ed331ca89 +P e93d2c49a44af994ff10cc9cc7eafacd5a4f73ab +R e1972f457267c7c1c09dde68002ccdbd +U drh +Z 4723986ca78be7a36581ca020c177062 diff --git a/manifest.uuid b/manifest.uuid index eec33fc0a4..5663814ec3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e93d2c49a44af994ff10cc9cc7eafacd5a4f73ab \ No newline at end of file +5987ca1ff94ed3c1666f783bb15b16158aa7e1db \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 154d078ff7..9bf8936765 100644 --- a/src/expr.c +++ b/src/expr.c @@ -967,7 +967,13 @@ void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr, u32 n){ /* Wildcard of the form "?nnn". Convert "nnn" to an integer and ** use it as the variable number */ i64 i; - int bOk = 0==sqlite3Atoi64(&z[1], &i, n-1, SQLITE_UTF8); + int bOk; + if( n==2 ){ /*OPTIMIZATION-IF-TRUE*/ + i = z[1]-'0'; /* The common case of ?N for a single digit N */ + bOk = 1; + }else{ + bOk = 0==sqlite3Atoi64(&z[1], &i, n-1, SQLITE_UTF8); + } x = (ynVar)i; testcase( i==0 ); testcase( i==1 ); From 8e74e7ba4c54ca46412bbfe3689d589a4b0d625a Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 31 Jan 2017 12:41:48 +0000 Subject: [PATCH 1261/1484] Further minor enhancement and size reduction in sqlite3ExprAssignVarNumber(). FossilOrigin-Name: eacfdcf25796ea29b5e63499c3d7397498305ad9 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/expr.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 96a31247b7..5c0df4b7d4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Performance\soptimization\sin\ssqlite3ExprAssignVarNumber(). -D 2017-01-31T03:52:34.839 +C Further\sminor\senhancement\sand\ssize\sreduction\sin\s\nsqlite3ExprAssignVarNumber(). +D 2017-01-31T12:41:48.800 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -344,7 +344,7 @@ F src/ctime.c 9f2296a4e5d26ebf0e0d95a0af4628f1ea694e7a F src/date.c dc3f1391d9297f8c748132813aaffcb117090d6e F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c 0d9d5549d42e79ce4d82ff1db1e6c81e36d2f67c -F src/expr.c 27ac552489a34fc85202084dda32d0a2a0664bfb +F src/expr.c d7ef6fdb70bc18259d7d36b22aa0bc4845c5c5b9 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 2e9aabe1aee76273aff8a84ee92c464e095400ae F src/func.c c67273e1ec08abbdcc14c189892a3ff6eeece86b @@ -1548,7 +1548,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e93d2c49a44af994ff10cc9cc7eafacd5a4f73ab -R e1972f457267c7c1c09dde68002ccdbd +P 5987ca1ff94ed3c1666f783bb15b16158aa7e1db +R 877cd166cfa1886b85d3c173dceec467 U drh -Z 4723986ca78be7a36581ca020c177062 +Z 12e7b02d2001dbb9bba0a7e780630702 diff --git a/manifest.uuid b/manifest.uuid index 5663814ec3..e94ba71f96 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5987ca1ff94ed3c1666f783bb15b16158aa7e1db \ No newline at end of file +eacfdcf25796ea29b5e63499c3d7397498305ad9 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 9bf8936765..18035bd421 100644 --- a/src/expr.c +++ b/src/expr.c @@ -974,7 +974,6 @@ void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr, u32 n){ }else{ bOk = 0==sqlite3Atoi64(&z[1], &i, n-1, SQLITE_UTF8); } - x = (ynVar)i; testcase( i==0 ); testcase( i==1 ); testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]-1 ); @@ -984,6 +983,7 @@ void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr, u32 n){ db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]); return; } + x = (ynVar)i; if( x>pParse->nVar ){ pParse->nVar = (int)x; doAdd = 1; From 1379521f4a6ef1ee68abb457a56f81292af69cb0 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 31 Jan 2017 15:27:04 +0000 Subject: [PATCH 1262/1484] Fix a typo in a comment. FossilOrigin-Name: bd22bf9cbe028e9811ca3afaadafd90312cb0fc9 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 5c0df4b7d4..8e4b6f544a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Further\sminor\senhancement\sand\ssize\sreduction\sin\s\nsqlite3ExprAssignVarNumber(). -D 2017-01-31T12:41:48.800 +C Fix\sa\stypo\sin\sa\scomment. +D 2017-01-31T15:27:04.928 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -458,7 +458,7 @@ F src/update.c 456d4a4656f8a03c2abc88a51b19172197400e58 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c a88b0466fddf445ce752226d4698ca3faada620a F src/vacuum.c 33c174b28886b2faf26e503b5a49a1c01a9b1c16 -F src/vdbe.c c27cc34be1d9169c1c191238025781684bdcd4ec +F src/vdbe.c a5bcdb61862cd995126ec4993121e04fe409c6e0 F src/vdbe.h 59998ffd71d7caa8886bc78dafaf8caeccd4c13c F src/vdbeInt.h 281cb70332dc8b593b8c7afe776f3a2ba7d4255e F src/vdbeapi.c 7a65f10684982daecfce50f557f2632b7f20b198 @@ -1548,7 +1548,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 5987ca1ff94ed3c1666f783bb15b16158aa7e1db -R 877cd166cfa1886b85d3c173dceec467 +P eacfdcf25796ea29b5e63499c3d7397498305ad9 +R 08311637f9a8170c29c38d1bfabeb653 U drh -Z 12e7b02d2001dbb9bba0a7e780630702 +Z 855f1082721037fd6fefeb16ca2ac959 diff --git a/manifest.uuid b/manifest.uuid index e94ba71f96..61e2f28112 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -eacfdcf25796ea29b5e63499c3d7397498305ad9 \ No newline at end of file +bd22bf9cbe028e9811ca3afaadafd90312cb0fc9 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index ded4462398..0e3a6f5baa 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -4407,7 +4407,7 @@ case OP_InsertInt: { assert( HasRowid(pTab) ); op = ((pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT); }else{ - pTab = 0; /* Not needed. Silence a comiler warning. */ + pTab = 0; /* Not needed. Silence a compiler warning. */ zDb = 0; /* Not needed. Silence a compiler warning. */ } From 9dc7ad1d7e1286fe0d3d30117adae154c6abf6de Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 31 Jan 2017 15:29:05 +0000 Subject: [PATCH 1263/1484] Add the "stat" command to kvtest.c. Also add the --variance option to the "init" command. Add the tool/kvtest-speed.sh script used for doing performance testing on key/value access patterns. FossilOrigin-Name: b63deed600b1a457a6960ebad5645f4de9c56e5d --- manifest | 13 +++---- manifest.uuid | 2 +- test/kvtest.c | 80 ++++++++++++++++++++++++++++++++++++++++++-- tool/kvtest-speed.sh | 36 ++++++++++++++++++++ 4 files changed, 121 insertions(+), 10 deletions(-) create mode 100644 tool/kvtest-speed.sh diff --git a/manifest b/manifest index 8e4b6f544a..e0848cf122 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\stypo\sin\sa\scomment. -D 2017-01-31T15:27:04.928 +C Add\sthe\s"stat"\scommand\sto\skvtest.c.\s\sAlso\sadd\sthe\s--variance\soption\sto\sthe\n"init"\scommand.\s\sAdd\sthe\stool/kvtest-speed.sh\sscript\sused\sfor\sdoing\s\nperformance\stesting\son\skey/value\saccess\spatterns. +D 2017-01-31T15:29:05.242 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -899,7 +899,7 @@ F test/json101.test c0897616f32d95431f37fd291cb78742181980ac F test/json102.test bf3fe7a706d30936a76a0f7a0375e1e8e73aff5a F test/json103.test c5f6b85e69de05f6b3195f9f9d5ce9cd179099a0 F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff -F test/kvtest.c dc6e5e9066fa5e19f7368c7dfbe8c6b9642a706f +F test/kvtest.c 7a3c38ee56b9cc45dc5a5edc50fd9bc9425659a9 F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63 F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200 F test/like.test 0603f4fa0dad50987f70032c05800cbfa8985302 @@ -1475,6 +1475,7 @@ F tool/fuzzershell.c dbf6c26eef936ec78cb0707570de3a4308b2507e F tool/genfkey.README cf68fddd4643bbe3ff8e31b8b6d8b0a1b85e20f4 F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5 F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce +F tool/kvtest-speed.sh d6c7c2b5787f44c3be2ed01c8463223032ee598b F tool/lemon.c 5ccba178a8e8a4b21e1c9232944d23973da38ad7 F tool/lempar.c db1bdb4821f2d8fbd76e577cf3ab18642c8d08d1 F tool/libvers.c caafc3b689638a1d88d44bc5f526c2278760d9b9 @@ -1548,7 +1549,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P eacfdcf25796ea29b5e63499c3d7397498305ad9 -R 08311637f9a8170c29c38d1bfabeb653 +P bd22bf9cbe028e9811ca3afaadafd90312cb0fc9 +R 561f5ef3a58c98c17f69cad51ae91935 U drh -Z 855f1082721037fd6fefeb16ca2ac959 +Z 35fd92fc5491c4b603aa832f4a4ebf7a diff --git a/manifest.uuid b/manifest.uuid index 61e2f28112..69a91341ca 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bd22bf9cbe028e9811ca3afaadafd90312cb0fc9 \ No newline at end of file +b63deed600b1a457a6960ebad5645f4de9c56e5d \ No newline at end of file diff --git a/test/kvtest.c b/test/kvtest.c index 765a7ee968..2a108aa470 100644 --- a/test/kvtest.c +++ b/test/kvtest.c @@ -67,13 +67,19 @@ static const char zHelp[] = "\n" " Generate a new test database file named DBFILE containing N\n" " BLOBs each of size M bytes. The page size of the new database\n" -" file will be X\n" +" file will be X. Additional options:\n" +"\n" +" --variance V Randomly vary M by plus or minus V\n" "\n" " kvtest export DBFILE DIRECTORY\n" "\n" " Export all the blobs in the kv table of DBFILE into separate\n" " files in DIRECTORY.\n" "\n" +" kvtest stat DBFILE\n" +"\n" +" Display summary information about DBFILE\n" +"\n" " kvtest run DBFILE [options]\n" "\n" " Run a performance test. DBFILE can be either the name of a\n" @@ -251,6 +257,7 @@ static int initMain(int argc, char **argv){ int i, rc; int nCount = 1000; int sz = 10000; + int iVariance = 0; int pgsz = 4096; sqlite3 *db; char *zSql; @@ -275,6 +282,11 @@ static int initMain(int argc, char **argv){ if( sz<1 ) fatalError("the --size must be positive"); continue; } + if( strcmp(z, "-variance")==0 ){ + if( i==argc-1 ) fatalError("missing argument on \"%s\"", argv[i]); + iVariance = integerValue(argv[++i]); + continue; + } if( strcmp(z, "-pagesize")==0 ){ if( i==argc-1 ) fatalError("missing argument on \"%s\"", argv[i]); pgsz = integerValue(argv[++i]); @@ -296,9 +308,9 @@ static int initMain(int argc, char **argv){ "BEGIN;\n" "CREATE TABLE kv(k INTEGER PRIMARY KEY, v BLOB);\n" "WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<%d)" - " INSERT INTO kv(k,v) SELECT x, randomblob(%d) FROM c;\n" + " INSERT INTO kv(k,v) SELECT x, randomblob(%d+(random()%%(%d))) FROM c;\n" "COMMIT;\n", - pgsz, nCount, sz + pgsz, nCount, sz, iVariance ); rc = sqlite3_exec(db, zSql, 0, 0, &zErrMsg); if( rc ) fatalError("database create failed: %s", zErrMsg); @@ -307,6 +319,65 @@ static int initMain(int argc, char **argv){ return 0; } +/* +** Analyze an existing database file. Report its content. +*/ +static int statMain(int argc, char **argv){ + char *zDb; + int i, rc; + sqlite3 *db; + char *zSql; + sqlite3_stmt *pStmt; + + assert( strcmp(argv[1],"stat")==0 ); + assert( argc>=3 ); + zDb = argv[2]; + for(i=3; i&1 | tee summary-kvtest-$NAME.txt +mv cachegrind.out.[1-9][0-9]* cachegrind.out.$NAME +cg_anno.tcl cachegrind.out.$NAME >cout-kvtest-sql-$NAME.txt + +# Second run using the sqlite3_blob object +rm cachegrind.out.[1-9][0-9]* +valgrind --tool=cachegrind ./kvtest run kvtest.db $KVARGS --blob-api 2>&1 | tee -a summary-kvtest-$NAME.txt +mv cachegrind.out.[1-9][0-9]* cachegrind.out.$NAME +cg_anno.tcl cachegrind.out.$NAME >cout-kvtest-$NAME.txt + +# Diff the sqlite3_blob API analysis for non-trunk runs. +if test "$NAME" != "trunk"; then + fossil test-diff --tk cout-kvtest-trunk.txt cout-kvtest-$NAME.txt & +fi From 78a9e92ecf15afb4a3550c8bb8f998928fae3314 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 31 Jan 2017 16:34:51 +0000 Subject: [PATCH 1264/1484] Remove an unnecessary initialization of the pOp variable in sqlite3VdbeExec(). FossilOrigin-Name: 02f6293f278f7b0a0f4876f5c6a0f4dc42620d79 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index e0848cf122..6b12ff4cc5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\s"stat"\scommand\sto\skvtest.c.\s\sAlso\sadd\sthe\s--variance\soption\sto\sthe\n"init"\scommand.\s\sAdd\sthe\stool/kvtest-speed.sh\sscript\sused\sfor\sdoing\s\nperformance\stesting\son\skey/value\saccess\spatterns. -D 2017-01-31T15:29:05.242 +C Remove\san\sunnecessary\sinitialization\sof\sthe\spOp\svariable\sin\ssqlite3VdbeExec(). +D 2017-01-31T16:34:51.236 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -458,7 +458,7 @@ F src/update.c 456d4a4656f8a03c2abc88a51b19172197400e58 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c a88b0466fddf445ce752226d4698ca3faada620a F src/vacuum.c 33c174b28886b2faf26e503b5a49a1c01a9b1c16 -F src/vdbe.c a5bcdb61862cd995126ec4993121e04fe409c6e0 +F src/vdbe.c 7c53c4b66e5fdf4a59272a7af3826d6a36eb72ae F src/vdbe.h 59998ffd71d7caa8886bc78dafaf8caeccd4c13c F src/vdbeInt.h 281cb70332dc8b593b8c7afe776f3a2ba7d4255e F src/vdbeapi.c 7a65f10684982daecfce50f557f2632b7f20b198 @@ -1549,7 +1549,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P bd22bf9cbe028e9811ca3afaadafd90312cb0fc9 -R 561f5ef3a58c98c17f69cad51ae91935 +P b63deed600b1a457a6960ebad5645f4de9c56e5d +R 30ecebc065226e07a2ed70b2eff6d7d3 U drh -Z 35fd92fc5491c4b603aa832f4a4ebf7a +Z 105450e93cb94372d4615eab06f395ed diff --git a/manifest.uuid b/manifest.uuid index 69a91341ca..7c7400a4e6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b63deed600b1a457a6960ebad5645f4de9c56e5d \ No newline at end of file +02f6293f278f7b0a0f4876f5c6a0f4dc42620d79 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 0e3a6f5baa..c6918c5f2a 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -562,7 +562,7 @@ int sqlite3VdbeExec( Vdbe *p /* The VDBE */ ){ Op *aOp = p->aOp; /* Copy of p->aOp */ - Op *pOp = aOp; /* Current operation */ + Op *pOp; /* Current operation */ #if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) Op *pOrigOp; /* Value of pOp at the top of the loop */ #endif From d59bcbdee7241f103b0ec9ed456d0ce3637ac2b0 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 31 Jan 2017 16:43:36 +0000 Subject: [PATCH 1265/1484] Remove another unnecessary local variable initialization from sqlite3VdbeExec() FossilOrigin-Name: 2361b03b61311aab9b9ec9de040bbb73be31be0d --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 6b12ff4cc5..763bbd12a7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\san\sunnecessary\sinitialization\sof\sthe\spOp\svariable\sin\ssqlite3VdbeExec(). -D 2017-01-31T16:34:51.236 +C Remove\sanother\sunnecessary\slocal\svariable\sinitialization\sfrom\ssqlite3VdbeExec() +D 2017-01-31T16:43:36.486 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -458,7 +458,7 @@ F src/update.c 456d4a4656f8a03c2abc88a51b19172197400e58 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c a88b0466fddf445ce752226d4698ca3faada620a F src/vacuum.c 33c174b28886b2faf26e503b5a49a1c01a9b1c16 -F src/vdbe.c 7c53c4b66e5fdf4a59272a7af3826d6a36eb72ae +F src/vdbe.c c0e9bd3fc0f1909e76930e88860ec66edc201d62 F src/vdbe.h 59998ffd71d7caa8886bc78dafaf8caeccd4c13c F src/vdbeInt.h 281cb70332dc8b593b8c7afe776f3a2ba7d4255e F src/vdbeapi.c 7a65f10684982daecfce50f557f2632b7f20b198 @@ -1549,7 +1549,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b63deed600b1a457a6960ebad5645f4de9c56e5d -R 30ecebc065226e07a2ed70b2eff6d7d3 +P 02f6293f278f7b0a0f4876f5c6a0f4dc42620d79 +R f0488c71d9bf7cc95008ff5cdb6232cc U drh -Z 105450e93cb94372d4615eab06f395ed +Z 567d0d39f344217652f484cd397a1b36 diff --git a/manifest.uuid b/manifest.uuid index 7c7400a4e6..1b110b97c9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -02f6293f278f7b0a0f4876f5c6a0f4dc42620d79 \ No newline at end of file +2361b03b61311aab9b9ec9de040bbb73be31be0d \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index c6918c5f2a..b133c7ec85 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -597,7 +597,7 @@ int sqlite3VdbeExec( } assert( p->rc==SQLITE_OK || (p->rc&0xff)==SQLITE_BUSY ); assert( p->bIsReader || p->readOnly!=0 ); - p->rc = SQLITE_OK; +// p->rc = SQLITE_OK; p->iCurrentTime = 0; assert( p->explain==0 ); p->pResultSet = 0; From 0caad09585bd83f287fcb31c968d656c4dbe9fda Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 31 Jan 2017 16:49:01 +0000 Subject: [PATCH 1266/1484] Remove a C99-style comment. Fixes to the kvtest-speed.sh script. FossilOrigin-Name: 91eb6b628e278d20eccc647293e5b30765163e12 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/vdbe.c | 1 - tool/kvtest-speed.sh | 5 ++--- 4 files changed, 10 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 763bbd12a7..3c10f176f0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sanother\sunnecessary\slocal\svariable\sinitialization\sfrom\ssqlite3VdbeExec() -D 2017-01-31T16:43:36.486 +C Remove\sa\sC99-style\scomment.\s\sFixes\sto\sthe\skvtest-speed.sh\sscript. +D 2017-01-31T16:49:01.913 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -458,7 +458,7 @@ F src/update.c 456d4a4656f8a03c2abc88a51b19172197400e58 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c a88b0466fddf445ce752226d4698ca3faada620a F src/vacuum.c 33c174b28886b2faf26e503b5a49a1c01a9b1c16 -F src/vdbe.c c0e9bd3fc0f1909e76930e88860ec66edc201d62 +F src/vdbe.c d3765f4d8f667b8d10232b2a1d0498497f3ac09f F src/vdbe.h 59998ffd71d7caa8886bc78dafaf8caeccd4c13c F src/vdbeInt.h 281cb70332dc8b593b8c7afe776f3a2ba7d4255e F src/vdbeapi.c 7a65f10684982daecfce50f557f2632b7f20b198 @@ -1475,7 +1475,7 @@ F tool/fuzzershell.c dbf6c26eef936ec78cb0707570de3a4308b2507e F tool/genfkey.README cf68fddd4643bbe3ff8e31b8b6d8b0a1b85e20f4 F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5 F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce -F tool/kvtest-speed.sh d6c7c2b5787f44c3be2ed01c8463223032ee598b +F tool/kvtest-speed.sh 4761a9c4b3530907562314d7757995787f7aef8f F tool/lemon.c 5ccba178a8e8a4b21e1c9232944d23973da38ad7 F tool/lempar.c db1bdb4821f2d8fbd76e577cf3ab18642c8d08d1 F tool/libvers.c caafc3b689638a1d88d44bc5f526c2278760d9b9 @@ -1549,7 +1549,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 02f6293f278f7b0a0f4876f5c6a0f4dc42620d79 -R f0488c71d9bf7cc95008ff5cdb6232cc +P 2361b03b61311aab9b9ec9de040bbb73be31be0d +R 085c25b2bd73ed43799df664becffebf U drh -Z 567d0d39f344217652f484cd397a1b36 +Z 9d1629688efb4c919cbb0184aee51efa diff --git a/manifest.uuid b/manifest.uuid index 1b110b97c9..80341cb011 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2361b03b61311aab9b9ec9de040bbb73be31be0d \ No newline at end of file +91eb6b628e278d20eccc647293e5b30765163e12 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index b133c7ec85..049c8243f6 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -597,7 +597,6 @@ int sqlite3VdbeExec( } assert( p->rc==SQLITE_OK || (p->rc&0xff)==SQLITE_BUSY ); assert( p->bIsReader || p->readOnly!=0 ); -// p->rc = SQLITE_OK; p->iCurrentTime = 0; assert( p->explain==0 ); p->pResultSet = 0; diff --git a/tool/kvtest-speed.sh b/tool/kvtest-speed.sh index 8dc852bef5..5f2c8345be 100644 --- a/tool/kvtest-speed.sh +++ b/tool/kvtest-speed.sh @@ -21,11 +21,10 @@ gcc -g -Os -I. $OPTS $* kvtest.c sqlite3.c -o kvtest # First run using SQL rm cachegrind.out.[1-9][0-9]* valgrind --tool=cachegrind ./kvtest run kvtest.db $KVARGS 2>&1 | tee summary-kvtest-$NAME.txt -mv cachegrind.out.[1-9][0-9]* cachegrind.out.$NAME -cg_anno.tcl cachegrind.out.$NAME >cout-kvtest-sql-$NAME.txt +mv cachegrind.out.[1-9][0-9]* cachegrind.out.sql-$NAME +cg_anno.tcl cachegrind.out.sql-$NAME >cout-kvtest-sql-$NAME.txt # Second run using the sqlite3_blob object -rm cachegrind.out.[1-9][0-9]* valgrind --tool=cachegrind ./kvtest run kvtest.db $KVARGS --blob-api 2>&1 | tee -a summary-kvtest-$NAME.txt mv cachegrind.out.[1-9][0-9]* cachegrind.out.$NAME cg_anno.tcl cachegrind.out.$NAME >cout-kvtest-$NAME.txt From 610e17bd91bca66ec7c03d7e60c2024e32ac989b Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 31 Jan 2017 17:31:30 +0000 Subject: [PATCH 1267/1484] Add a speed-test program for the sessions module. FossilOrigin-Name: 25f1275fe3e940c1d9a7b013cb3744304b2eda1e --- ext/session/session_speed_test.c | 360 +++++++++++++++++++++++++++++++ manifest | 11 +- manifest.uuid | 2 +- 3 files changed, 367 insertions(+), 6 deletions(-) create mode 100644 ext/session/session_speed_test.c diff --git a/ext/session/session_speed_test.c b/ext/session/session_speed_test.c new file mode 100644 index 0000000000..14b97ea07b --- /dev/null +++ b/ext/session/session_speed_test.c @@ -0,0 +1,360 @@ +/* +** 2017 January 31 +** +** 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 contains the source code for a standalone program used to +** test the performance of the sessions module. Compile and run: +** +** ./session_speed_test -help +** +** for details. +*/ + +#include "sqlite3.h" +#include +#include +#include +#include +#include + +/************************************************************************* +** Start of generic command line parser. +*/ +#define CMDLINE_BARE 0 +#define CMDLINE_INTEGER 1 +#define CMDLINE_STRING 2 +#define CMDLINE_BOOLEAN 3 + +typedef struct CmdLineOption CmdLineOption; +struct CmdLineOption { + const char *zText; /* Name of command line option */ + const char *zHelp; /* Help text for option */ + int eType; /* One of the CMDLINE_* values */ + int iOff; /* Offset of output variable */ +}; + +#define CMDLINE_INT32(x,y,z) {x, y, CMDLINE_INTEGER, z} +#define CMDLINE_BOOL(x,y,z) {x, y, CMDLINE_BOOLEAN, z} +#define CMDLINE_TEXT(x,y,z) {x, y, CMDLINE_STRING, z} +#define CMDLINE_NONE(x,y,z) {x, y, CMDLINE_BARE, z} + +static void option_requires_argument_error(CmdLineOption *pOpt){ + fprintf(stderr, "Option requires a%s argument: %s\n", + pOpt->eType==CMDLINE_INTEGER ? "n integer" : + pOpt->eType==CMDLINE_STRING ? " string" : " boolean", + pOpt->zText + ); + exit(1); +} + +static void ambiguous_option_error(const char *zArg){ + fprintf(stderr, "Option is ambiguous: %s\n", zArg); + exit(1); +} + +static void unknown_option_error( + const char *zArg, + CmdLineOption *aOpt, + const char *zHelp +){ + int i; + fprintf(stderr, "Unknown option: %s\n", zArg); + fprintf(stderr, "\nOptions are:\n"); + fprintf(stderr, " % -30sEcho command line options\n", "-cmdline:verbose"); + for(i=0; aOpt[i].zText; i++){ + int eType = aOpt[i].eType; + char *zOpt = sqlite3_mprintf("%s %s", aOpt[i].zText, + eType==CMDLINE_BARE ? "" : + eType==CMDLINE_INTEGER ? "N" : + eType==CMDLINE_BOOLEAN ? "BOOLEAN" : "TEXT" + ); + fprintf(stderr, " % -30s%s\n", zOpt, aOpt[i].zHelp); + sqlite3_free(zOpt); + } + if( zHelp ){ + fprintf(stderr, "\n%s\n", zHelp); + } + exit(1); +} + +static int get_integer_option(CmdLineOption *pOpt, const char *zArg){ + int i = 0; + int iRet = 0; + int bSign = 1; + if( zArg[0]=='-' ){ + bSign = -1; + i = 1; + } + while( zArg[i] ){ + if( zArg[i]<'0' || zArg[i]>'9' ) option_requires_argument_error(pOpt); + iRet = iRet*10 + (zArg[i] - '0'); + i++; + } + return (iRet*bSign); +} + +static int get_boolean_option(CmdLineOption *pOpt, const char *zArg){ + if( 0==sqlite3_stricmp(zArg, "true") ) return 1; + if( 0==sqlite3_stricmp(zArg, "1") ) return 1; + if( 0==sqlite3_stricmp(zArg, "0") ) return 0; + if( 0==sqlite3_stricmp(zArg, "false") ) return 0; + option_requires_argument_error(pOpt); + return 0; +} + +static void parse_command_line( + int argc, + char **argv, + int iStart, + CmdLineOption *aOpt, + void *pStruct, + const char *zHelp +){ + char *pOut = (char*)pStruct; + int bVerbose = 0; + int iArg; + + for(iArg=iStart; iArgzText, zArg, nArg) ){ + if( nMatch ){ + ambiguous_option_error(zArg); + } + nMatch++; + if( pOpt->eType==CMDLINE_BARE ){ + *(int*)(&pOut[pOpt->iOff]) = 1; + }else{ + iArg++; + if( iArg==argc ){ + option_requires_argument_error(pOpt); + } + switch( pOpt->eType ){ + case CMDLINE_INTEGER: + *(int*)(&pOut[pOpt->iOff]) = get_integer_option(pOpt, argv[iArg]); + break; + case CMDLINE_STRING: + *(const char**)(&pOut[pOpt->iOff]) = argv[iArg]; + break; + case CMDLINE_BOOLEAN: + *(int*)(&pOut[pOpt->iOff]) = get_boolean_option(pOpt, argv[iArg]); + break; + } + } + } + } + + if( nMatch==0 && 0==sqlite3_strnicmp("-cmdline:verbose", zArg, nArg) ){ + bVerbose = 1; + nMatch = 1; + } + + if( nMatch==0 ){ + unknown_option_error(zArg, aOpt, zHelp); + } + } + + if( bVerbose ){ + int iOpt; + fprintf(stdout, "Options are: "); + for(iOpt=0; aOpt[iOpt].zText; iOpt++){ + CmdLineOption *pOpt = &aOpt[iOpt]; + if( pOpt->eType!=CMDLINE_BARE || *(int*)(&pOut[pOpt->iOff]) ){ + fprintf(stdout, "%s ", pOpt->zText); + } + switch( pOpt->eType ){ + case CMDLINE_INTEGER: + fprintf(stdout, "%d ", *(int*)(&pOut[pOpt->iOff])); + break; + case CMDLINE_BOOLEAN: + fprintf(stdout, "%d ", *(int*)(&pOut[pOpt->iOff])); + break; + case CMDLINE_STRING: + fprintf(stdout, "%s ", *(const char**)(&pOut[pOpt->iOff])); + break; + } + } + fprintf(stdout, "\n"); + } +} +/* +** End of generic command line parser. +*************************************************************************/ + +static void abort_due_to_error(int rc){ + fprintf(stderr, "Error: %d\n"); + exit(-1); +} + +static void execsql(sqlite3 *db, const char *zSql){ + int rc = sqlite3_exec(db, zSql, 0, 0, 0); + if( rc!=SQLITE_OK ) abort_due_to_error(rc); +} + +static int xConflict(void *pCtx, int eConflict, sqlite3_changeset_iter *p){ + return SQLITE_CHANGESET_ABORT; +} + +static void run_test( + sqlite3 *db, + sqlite3 *db2, + int nRow, + const char *zSql +){ + sqlite3_session *pSession = 0; + sqlite3_stmt *pStmt = 0; + int rc; + int i; + int nChangeset; + void *pChangeset; + + /* Attach a session object to database db */ + rc = sqlite3session_create(db, "main", &pSession); + if( rc!=SQLITE_OK ) abort_due_to_error(rc); + + /* Configure the session to capture changes on all tables */ + rc = sqlite3session_attach(pSession, 0); + if( rc!=SQLITE_OK ) abort_due_to_error(rc); + + /* Prepare the SQL statement */ + rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0); + if( rc!=SQLITE_OK ) abort_due_to_error(rc); + + /* Open a transaction */ + execsql(db, "BEGIN"); + + /* Execute the SQL statement nRow times */ + for(i=0; i Date: Tue, 31 Jan 2017 19:02:15 +0000 Subject: [PATCH 1268/1484] Simplifications to blobSeekToRow(). FossilOrigin-Name: 495ea824093ff535734c22c3115384c08f855c02 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbeblob.c | 5 +---- 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 3c10f176f0..fa96e1cee3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sa\sC99-style\scomment.\s\sFixes\sto\sthe\skvtest-speed.sh\sscript. -D 2017-01-31T16:49:01.913 +C Simplifications\sto\sblobSeekToRow(). +D 2017-01-31T19:02:15.083 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -463,7 +463,7 @@ F src/vdbe.h 59998ffd71d7caa8886bc78dafaf8caeccd4c13c F src/vdbeInt.h 281cb70332dc8b593b8c7afe776f3a2ba7d4255e F src/vdbeapi.c 7a65f10684982daecfce50f557f2632b7f20b198 F src/vdbeaux.c 6847b02aa2db536ed15d90f1fdc2923afef93c5b -F src/vdbeblob.c 2b3d1ad915dbe5dc92c48759dc18fa8c697e78e5 +F src/vdbeblob.c 359891617358deefc85bef7bcf787fa6b77facb9 F src/vdbemem.c 3b5a9a5b375458d3e12a50ae1aaa41eeec2175fd F src/vdbesort.c eda25cb2d1727efca6f7862fea32b8aa33c0face F src/vdbetrace.c 41963d5376f0349842b5fc4aaaaacd7d9cdc0834 @@ -1549,7 +1549,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 2361b03b61311aab9b9ec9de040bbb73be31be0d -R 085c25b2bd73ed43799df664becffebf +P 91eb6b628e278d20eccc647293e5b30765163e12 +R 793d15c782afd1bb1c67c16147a858a7 U drh -Z 9d1629688efb4c919cbb0184aee51efa +Z 0d3326b5592bbe49f8801dfaea3a7026 diff --git a/manifest.uuid b/manifest.uuid index 80341cb011..fb73fe6210 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -91eb6b628e278d20eccc647293e5b30765163e12 \ No newline at end of file +495ea824093ff535734c22c3115384c08f855c02 \ No newline at end of file diff --git a/src/vdbeblob.c b/src/vdbeblob.c index 810f78860f..5692c1c606 100644 --- a/src/vdbeblob.c +++ b/src/vdbeblob.c @@ -55,7 +55,6 @@ static int blobSeekToRow(Incrblob *p, sqlite3_int64 iRow, char **pzErr){ int rc; /* Error code */ char *zErr = 0; /* Error message */ Vdbe *v = (Vdbe *)p->pStmt; - sqlite3 *db = v->db; /* Set the value of register r[1] in the SQL statement to integer iRow. ** This is done directly as a performance optimization @@ -69,9 +68,7 @@ static int blobSeekToRow(Incrblob *p, sqlite3_int64 iRow, char **pzErr){ ** counter is faster. */ if( v->pc>3 ){ v->pc = 3; - db->nVdbeExec++; - rc = sqlite3VdbeExec((Vdbe*)p->pStmt); - db->nVdbeExec--; + rc = sqlite3VdbeExec(v); }else{ rc = sqlite3_step(p->pStmt); } From fcbd6cdb41a8f338ed3c953405b4256cdfaba6c2 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 31 Jan 2017 21:22:03 +0000 Subject: [PATCH 1269/1484] R-TREE optimization: unwrap the coordinate decode loop in rtreeCallbackConstraint(). FossilOrigin-Name: 0bf7b51896ec441f62490964c7a44a3c75c6b7e2 --- ext/rtree/rtree.c | 10 +++++++--- manifest | 13 ++++++------- manifest.uuid | 2 +- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/ext/rtree/rtree.c b/ext/rtree/rtree.c index c7de6ac123..d69c966ddd 100644 --- a/ext/rtree/rtree.c +++ b/ext/rtree/rtree.c @@ -966,10 +966,14 @@ static int rtreeCallbackConstraint( if( pConstraint->op==RTREE_QUERY && pSearch->iLevel==1 ){ pInfo->iRowid = readInt64(pCellData); } - pCellData += 8; - for(i=0; i=2 && (nCoord&1)==0 ); + i = 0; + do{ + pCellData += 8; RTREE_DECODE_COORD(eInt, pCellData, aCoord[i]); - } + RTREE_DECODE_COORD(eInt, (pCellData+4), aCoord[i+1]); + i+= 2; + }while( iop==RTREE_MATCH ){ rc = pConstraint->u.xGeom((sqlite3_rtree_geometry*)pInfo, nCoord, aCoord, &i); diff --git a/manifest b/manifest index a8c339e791..cb6735cb6d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Very\ssmall\sperformance\simprovements\sand\ssize\sreductions\sin\s\nsqlite3VdbeExec()\sand\sblobSeekToRow(). -D 2017-01-31T19:10:42.671 +C R-TREE\soptimization:\sunwrap\sthe\scoordinate\sdecode\sloop\sin\nrtreeCallbackConstraint(). +D 2017-01-31T21:22:03.245 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -264,7 +264,7 @@ F ext/rbu/sqlite3rbu.c bb0de6cdbdb14a7d55a097238a434b7e99caf318 F ext/rbu/sqlite3rbu.h 6fb6294c34a9ca93b5894a33bca530c6f08decba F ext/rbu/test_rbu.c 5aa22616afac6f71ebd3d9bc9bf1006cfabcca88 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 -F ext/rtree/rtree.c 078fc27417b48aaebe988621bf96ef0e1645b201 +F ext/rtree/rtree.c 81fea8b100c6195f8a42119109d6ec2016e613f3 F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e F ext/rtree/rtree1.test 42dadfc7b44a436cd74a1bebc0b9b689e4eaf7ec F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba @@ -1549,8 +1549,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b63deed600b1a457a6960ebad5645f4de9c56e5d 495ea824093ff535734c22c3115384c08f855c02 -R 793d15c782afd1bb1c67c16147a858a7 -T +closed 495ea824093ff535734c22c3115384c08f855c02 +P 85dddf2b453b8afaf1f485b96084d31e22f97dda +R 80f20a76d631de95caa5095989ae297f U drh -Z c7f2b5c04f4a8cad3ed5cf73468bb400 +Z d89e7b06786861fbe2704ca06b1411f8 diff --git a/manifest.uuid b/manifest.uuid index 321250201a..0415fad4fb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -85dddf2b453b8afaf1f485b96084d31e22f97dda \ No newline at end of file +0bf7b51896ec441f62490964c7a44a3c75c6b7e2 \ No newline at end of file From 35497fccbe358dda7b95e1a4c109020725877f0b Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 1 Feb 2017 01:34:15 +0000 Subject: [PATCH 1270/1484] Improved comments on the statGet() implementation in ANALYZE. No changes to code. FossilOrigin-Name: 9663eea2a16bb4eec71476d307a3722a768308c3 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/analyze.c | 6 ++++++ 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index cb6735cb6d..cd07701b23 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C R-TREE\soptimization:\sunwrap\sthe\scoordinate\sdecode\sloop\sin\nrtreeCallbackConstraint(). -D 2017-01-31T21:22:03.245 +C Improved\scomments\son\sthe\sstatGet()\simplementation\sin\sANALYZE.\s\sNo\schanges\nto\scode. +D 2017-02-01T01:34:15.043 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -328,7 +328,7 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F src/alter.c 3b23977620ce9662ac54443f65b87ba996e36121 -F src/analyze.c 317dbaf31c16050582b09bf4f323b4e0f1813251 +F src/analyze.c ac7a5d7e3cee07d074697904e00e4a8ab7b2b4f5 F src/attach.c 8c476f8bd5d2afe11d925f890d30e527e5b0ce43 F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792 F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b @@ -1549,7 +1549,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 85dddf2b453b8afaf1f485b96084d31e22f97dda -R 80f20a76d631de95caa5095989ae297f +P 0bf7b51896ec441f62490964c7a44a3c75c6b7e2 +R bb550435b988e435dcc2fd1779602487 U drh -Z d89e7b06786861fbe2704ca06b1411f8 +Z 36c251bda157d6101f2fb97842697f89 diff --git a/manifest.uuid b/manifest.uuid index 0415fad4fb..1081a26f59 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0bf7b51896ec441f62490964c7a44a3c75c6b7e2 \ No newline at end of file +9663eea2a16bb4eec71476d307a3722a768308c3 \ No newline at end of file diff --git a/src/analyze.c b/src/analyze.c index c079132f4a..890ae7c3b2 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -797,6 +797,12 @@ static const FuncDef statPushFuncdef = { ** The content to returned is determined by the parameter J ** which is one of the STAT_GET_xxxx values defined above. ** +** The stat_get(P,J) function is not available to generic SQL. It is +** inserted as part of a manually constructed bytecode program. (See +** the callStatGet() routine below.) It is guaranteed that the P +** parameter will always be a poiner to a Stat4Accum object, never a +** NULL. +** ** If neither STAT3 nor STAT4 are enabled, then J is always ** STAT_GET_STAT1 and is hence omitted and this routine becomes ** a one-parameter function, stat_get(P), that always returns the From 14494fa712d71370eb92e15c4e4db20534fcd832 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 1 Feb 2017 02:25:28 +0000 Subject: [PATCH 1271/1484] More RTREE performance optimizations related to decoding values. FossilOrigin-Name: c5395e7496d0cd593f5e16ee5f6719d020dc0c66 --- ext/rtree/rtree.c | 18 +++++++++++++++++- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/ext/rtree/rtree.c b/ext/rtree/rtree.c index d69c966ddd..f1db60b22f 100644 --- a/ext/rtree/rtree.c +++ b/ext/rtree/rtree.c @@ -370,12 +370,20 @@ static int readInt16(u8 *p){ return (p[0]<<8) + p[1]; } static void readCoord(u8 *p, RtreeCoord *pCoord){ +#if defined(SQLITE_BYTEORDER) && SQLITE_BYTEORDER==1234 + memcpy(&pCoord->u, p, 4); + pCoord->u = ((pCoord->u>>24)&0xff)|((pCoord->u>>8)&0xff00)| + ((pCoord->u&0xff)<<24)|((pCoord->u&0xff00)<<8); +#elif defined(SQLITE_BYTEORDER) && SQLITE_BYTEORDER==4321 + memcpy(&pCoord->u, p, 4); +#else pCoord->u = ( (((u32)p[0]) << 24) + (((u32)p[1]) << 16) + (((u32)p[2]) << 8) + (((u32)p[3]) << 0) ); +#endif } static i64 readInt64(u8 *p){ return ( @@ -736,13 +744,21 @@ static void nodeGetCell( ){ u8 *pData; RtreeCoord *pCoord; - int ii; + int ii = 0; pCell->iRowid = nodeGetRowid(pRtree, pNode, iCell); pData = pNode->zData + (12 + pRtree->nBytesPerCell*iCell); pCoord = pCell->aCoord; + do{ + readCoord(pData, &pCoord[ii]); + readCoord(pData+4, &pCoord[ii+1]); + pData += 8; + ii += 2; + }while( iinDim*2 ); +#if 0 for(ii=0; iinDim*2; ii++){ readCoord(&pData[ii*4], &pCoord[ii]); } +#endif } diff --git a/manifest b/manifest index cd07701b23..3a5177423f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improved\scomments\son\sthe\sstatGet()\simplementation\sin\sANALYZE.\s\sNo\schanges\nto\scode. -D 2017-02-01T01:34:15.043 +C More\sRTREE\sperformance\soptimizations\srelated\sto\sdecoding\svalues. +D 2017-02-01T02:25:28.535 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -264,7 +264,7 @@ F ext/rbu/sqlite3rbu.c bb0de6cdbdb14a7d55a097238a434b7e99caf318 F ext/rbu/sqlite3rbu.h 6fb6294c34a9ca93b5894a33bca530c6f08decba F ext/rbu/test_rbu.c 5aa22616afac6f71ebd3d9bc9bf1006cfabcca88 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 -F ext/rtree/rtree.c 81fea8b100c6195f8a42119109d6ec2016e613f3 +F ext/rtree/rtree.c f66b3d232ea98285548107caaac55f110a0b6709 F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e F ext/rtree/rtree1.test 42dadfc7b44a436cd74a1bebc0b9b689e4eaf7ec F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba @@ -1549,7 +1549,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 0bf7b51896ec441f62490964c7a44a3c75c6b7e2 -R bb550435b988e435dcc2fd1779602487 +P 9663eea2a16bb4eec71476d307a3722a768308c3 +R 5d2055e5a67aa8455e161eeb4945e6a1 U drh -Z 36c251bda157d6101f2fb97842697f89 +Z 3923bc85bfbb1c570a9230cd663fc66b diff --git a/manifest.uuid b/manifest.uuid index 1081a26f59..becf54d88b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9663eea2a16bb4eec71476d307a3722a768308c3 \ No newline at end of file +c5395e7496d0cd593f5e16ee5f6719d020dc0c66 \ No newline at end of file From f6c69221e3b5f48fceb5e3664746716ea7e31f46 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 1 Feb 2017 14:19:43 +0000 Subject: [PATCH 1272/1484] Update the documentation comment in sqlite.h.in for sqlite3_preupdate_hook(). FossilOrigin-Name: 7f8570208c06c056d426e9299d9930181a0464f8 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/sqlite.h.in | 24 ++++++++++++++---------- 3 files changed, 21 insertions(+), 17 deletions(-) diff --git a/manifest b/manifest index 01669f9e0e..b3f47391f1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Changes\sso\sthat\sthe\spre-update\shook\sand\sthe\ssessions\smodule\swork\swith\sWITHOUT\nROWID\stables. -D 2017-02-01T14:10:24.369 +C Update\sthe\sdocumentation\scomment\sin\ssqlite.h.in\sfor\ssqlite3_preupdate_hook(). +D 2017-02-01T14:19:43.743 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -395,7 +395,7 @@ F src/resolve.c f9bc0de45a30a450da47b3766de00be89bf9be79 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c 3856db523b942062bca8722ba03b61c324ff94d6 F src/shell.c a84e453c213f3e0d6935a582024da4e242f85a19 -F src/sqlite.h.in 8fd2b1a4e4aac023d4533313442528b81105fab3 +F src/sqlite.h.in 751ff125eb159c8f92c182b8df980a5e4f50e966 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae F src/sqliteInt.h 6f29b23415ce207c2fda61054bf244b74f96359c @@ -1552,7 +1552,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P c5395e7496d0cd593f5e16ee5f6719d020dc0c66 25f1275fe3e940c1d9a7b013cb3744304b2eda1e -R f7a2435ee7007416912dcdfda9016a2c +P 964bdc27f8f1b1db2e5c0c2a65c8156614cbe087 +R c3a8e9059dd92e8c282633700ca50a30 U dan -Z 84db606ff358cb3acbf24f0cef50dec1 +Z fded3ef392ff672f8205c955a05c2af4 diff --git a/manifest.uuid b/manifest.uuid index f45e6e6220..dda985aaff 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -964bdc27f8f1b1db2e5c0c2a65c8156614cbe087 \ No newline at end of file +7f8570208c06c056d426e9299d9930181a0464f8 \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index b0ec7f7e15..eaa75fc249 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -8180,7 +8180,7 @@ int sqlite3_db_cacheflush(sqlite3*); ** ** ^The [sqlite3_preupdate_hook()] interface registers a callback function ** that is invoked prior to each [INSERT], [UPDATE], and [DELETE] operation -** on a [rowid table]. +** on a database table. ** ^At most one preupdate hook may be registered at a time on a single ** [database connection]; each call to [sqlite3_preupdate_hook()] overrides ** the previous setting. @@ -8189,9 +8189,9 @@ int sqlite3_db_cacheflush(sqlite3*); ** ^The third parameter to [sqlite3_preupdate_hook()] is passed through as ** the first parameter to callbacks. ** -** ^The preupdate hook only fires for changes to [rowid tables]; the preupdate -** hook is not invoked for changes to [virtual tables] or [WITHOUT ROWID] -** tables. +** ^The preupdate hook only fires for changes to real database tables; the +** preupdate hook is not invoked for changes to [virtual tables] or to +** system tables like sqlite_master or sqlite_stat1. ** ** ^The second parameter to the preupdate callback is a pointer to ** the [database connection] that registered the preupdate hook. @@ -8205,12 +8205,16 @@ int sqlite3_db_cacheflush(sqlite3*); ** databases.)^ ** ^The fifth parameter to the preupdate callback is the name of the ** table that is being modified. -** ^The sixth parameter to the preupdate callback is the initial [rowid] of the -** row being changes for SQLITE_UPDATE and SQLITE_DELETE changes and is -** undefined for SQLITE_INSERT changes. -** ^The seventh parameter to the preupdate callback is the final [rowid] of -** the row being changed for SQLITE_UPDATE and SQLITE_INSERT changes and is -** undefined for SQLITE_DELETE changes. +** +** For an UPDATE or DELETE operation on a [rowid table], the sixth +** parameter passed to the preupdate callback is the initial [rowid] of the +** row being modified or deleted. For an INSERT operation on a rowid table, +** or any operation on a WITHOUT ROWID table, the value of the sixth +** parameter is undefined. For an INSERT or UPDATE on a rowid table the +** seventh parameter is the final rowid value of the row being inserted +** or updated. The value of the seventh parameter passed to the callback +** function is not defined for operations on WITHOUT ROWID tables, or for +** INSERT operations on rowid tables. ** ** The [sqlite3_preupdate_old()], [sqlite3_preupdate_new()], ** [sqlite3_preupdate_count()], and [sqlite3_preupdate_depth()] interfaces From 1650fcb1b5627ec7ab2a514b9a42920e8e739ac7 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 1 Feb 2017 15:19:29 +0000 Subject: [PATCH 1273/1484] Fix the build by making the OPFLAG_ISNOOP macro available unconditionally. FossilOrigin-Name: 510933cb24c5bf883265af3a6075e60a4b5ffa37 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/sqliteInt.h | 2 -- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index b3f47391f1..8145330051 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\sthe\sdocumentation\scomment\sin\ssqlite.h.in\sfor\ssqlite3_preupdate_hook(). -D 2017-02-01T14:19:43.743 +C Fix\sthe\sbuild\sby\smaking\sthe\sOPFLAG_ISNOOP\smacro\savailable\sunconditionally. +D 2017-02-01T15:19:29.202 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -398,7 +398,7 @@ F src/shell.c a84e453c213f3e0d6935a582024da4e242f85a19 F src/sqlite.h.in 751ff125eb159c8f92c182b8df980a5e4f50e966 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae -F src/sqliteInt.h 6f29b23415ce207c2fda61054bf244b74f96359c +F src/sqliteInt.h 3724c48e82605b471bbf7e41109b5850c6e89f31 F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 @@ -1552,7 +1552,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 964bdc27f8f1b1db2e5c0c2a65c8156614cbe087 -R c3a8e9059dd92e8c282633700ca50a30 -U dan -Z fded3ef392ff672f8205c955a05c2af4 +P 7f8570208c06c056d426e9299d9930181a0464f8 +R bbb1f490f7311ec1c087c3ef4607e5e0 +U drh +Z 645035379b970696e5aed344f8a4be19 diff --git a/manifest.uuid b/manifest.uuid index dda985aaff..0823e8bab6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7f8570208c06c056d426e9299d9930181a0464f8 \ No newline at end of file +510933cb24c5bf883265af3a6075e60a4b5ffa37 \ No newline at end of file diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 4a28ebcd5a..3faf9d3982 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3057,9 +3057,7 @@ struct AuthContext { #define OPFLAG_ISUPDATE 0x04 /* This OP_Insert is an sql UPDATE */ #define OPFLAG_APPEND 0x08 /* This is likely to be an append */ #define OPFLAG_USESEEKRESULT 0x10 /* Try to avoid a seek in BtreeInsert() */ -#ifdef SQLITE_ENABLE_PREUPDATE_HOOK #define OPFLAG_ISNOOP 0x40 /* OP_Delete does pre-update-hook only */ -#endif #define OPFLAG_LENGTHARG 0x40 /* OP_Column only used for length() */ #define OPFLAG_TYPEOFARG 0x80 /* OP_Column only used for typeof() */ #define OPFLAG_BULKCSR 0x01 /* OP_Open** used to open bulk cursor */ From 03626e38127d4d0667eb23243c479719c1d30b9a Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 1 Feb 2017 15:24:32 +0000 Subject: [PATCH 1274/1484] Use compiler intrinsic functions (when available) for byteswapping in RTREE. FossilOrigin-Name: 82fcd54a5941c20895ffc22d8009c1ebdae44eda --- ext/rtree/rtree.c | 142 ++++++++++++++++++++++++++++++++++++++++------ manifest | 12 ++-- manifest.uuid | 2 +- 3 files changed, 131 insertions(+), 25 deletions(-) diff --git a/ext/rtree/rtree.c b/ext/rtree/rtree.c index f1db60b22f..637fb79d05 100644 --- a/ext/rtree/rtree.c +++ b/ext/rtree/rtree.c @@ -362,6 +362,65 @@ struct RtreeMatchArg { # define MIN(x,y) ((x) > (y) ? (y) : (x)) #endif +/* What version of GCC is being used. 0 means GCC is not being used */ +#ifndef GCC_VERSION +#ifdef __GNUC__ +# define GCC_VERSION (__GNUC__*1000000+__GNUC_MINOR__*1000+__GNUC_PATCHLEVEL__) +#else +# define GCC_VERSION 0 +#endif +#endif + +/* What version of CLANG is being used. 0 means CLANG is not being used */ +#ifndef CLANG_VERSION +#if defined(__clang__) && !defined(_WIN32) +# define CLANG_VERSION \ + (__clang_major__*1000000+__clang_minor__*1000+__clang_patchlevel__) +#else +# define CLANG_VERSION 0 +#endif +#endif + +/* The testcase() macro should already be defined in the amalgamation. If +** it is not, make it a no-op. +*/ +#ifndef SQLITE_AMALGMATION +# define testcase(X) +#endif + +/* +** Macros to determine whether the machine is big or little endian, +** and whether or not that determination is run-time or compile-time. +** +** For best performance, an attempt is made to guess at the byte-order +** using C-preprocessor macros. If that is unsuccessful, or if +** -DSQLITE_RUNTIME_BYTEORDER=1 is set, then byte-order is determined +** at run-time. +*/ +#ifndef SQLITE_BYTEORDER +#if (defined(i386) || defined(__i386__) || defined(_M_IX86) || \ + defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \ + defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) || \ + defined(__arm__)) && !defined(SQLITE_RUNTIME_BYTEORDER) +# define SQLITE_BYTEORDER 1234 +#endif +#if (defined(sparc) || defined(__ppc__)) \ + && !defined(SQLITE_RUNTIME_BYTEORDER) +# define SQLITE_BYTEORDER 4321 +#endif +# define SQLITE_BYTEORDER 0 /* 0 means "unknown at compile-time" */ +#endif + + +/* What version of MSVC is being used. 0 means MSVC is not being used */ +#ifndef MSVC_VERSION +#if defined(_MSC_VER) +# define MSVC_VERSION _MSC_VER +#else +# define MSVC_VERSION 0 +#endif +#endif + /* ** Functions to deserialize a 16 bit integer, 32 bit real number and ** 64 bit integer. The deserialized value is returned. @@ -370,12 +429,16 @@ static int readInt16(u8 *p){ return (p[0]<<8) + p[1]; } static void readCoord(u8 *p, RtreeCoord *pCoord){ -#if defined(SQLITE_BYTEORDER) && SQLITE_BYTEORDER==1234 - memcpy(&pCoord->u, p, 4); + assert( ((((char*)p) - (char*)0)&3)==0 ); /* p is always 4-byte aligned */ +#if SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300 + pCoord->u = _byteswap_ulong(*(u32*)p); +#elif SQLITE_BYTEORDER==1234 && (GCC_VERSION>=4003000 || CLANG_VERSION>=3000000) + pCoord->u = __builtin_bswap32(*(u32*)p); +#elif SQLITE_BYTEORDER==1234 pCoord->u = ((pCoord->u>>24)&0xff)|((pCoord->u>>8)&0xff00)| ((pCoord->u&0xff)<<24)|((pCoord->u&0xff00)<<8); -#elif defined(SQLITE_BYTEORDER) && SQLITE_BYTEORDER==4321 - memcpy(&pCoord->u, p, 4); +#elif SQLITE_BYTEORDER==4321 + pCoord->u = *(u32*)p; #else pCoord->u = ( (((u32)p[0]) << 24) + @@ -386,6 +449,20 @@ static void readCoord(u8 *p, RtreeCoord *pCoord){ #endif } static i64 readInt64(u8 *p){ + testcase( ((((char*)p) - (char*)0)&7)!=0 ); /* not always 8-byte aligned */ +#if SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300 + u64 x; + memcpy(&x, p, 8); + return (i64)_byteswap_uint64(x); +#elif SQLITE_BYTEORDER==1234 && (GCC_VERSION>=4003000 || CLANG_VERSION>=3000000) + u64 x; + memcpy(&x, p, 8); + return (i64)__builtin_bswap64(x); +#elif SQLITE_BYTEORDER==4321 + i64 x; + memcpy(&x, p, 8); + return x; +#else return ( (((i64)p[0]) << 56) + (((i64)p[1]) << 48) + @@ -396,6 +473,7 @@ static i64 readInt64(u8 *p){ (((i64)p[6]) << 8) + (((i64)p[7]) << 0) ); +#endif } /* @@ -410,16 +488,38 @@ static int writeInt16(u8 *p, int i){ } static int writeCoord(u8 *p, RtreeCoord *pCoord){ u32 i; + assert( ((((char*)p) - (char*)0)&3)==0 ); /* p is always 4-byte aligned */ assert( sizeof(RtreeCoord)==4 ); assert( sizeof(u32)==4 ); +#if SQLITE_BYTEORDER==1234 && (GCC_VERSION>=4003000 || CLANG_VERSION>=3000000) + i = __builtin_bswap32(pCoord->u); + memcpy(p, &i, 4); +#elif SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300 + i = _byteswap_ulong(pCoord->u); + memcpy(p, &i, 4); +#elif SQLITE_BYTEORDER==4321 + i = pCoord->u; + memcpy(p, &i, 4); +#else i = pCoord->u; p[0] = (i>>24)&0xFF; p[1] = (i>>16)&0xFF; p[2] = (i>> 8)&0xFF; p[3] = (i>> 0)&0xFF; +#endif return 4; } static int writeInt64(u8 *p, i64 i){ + testcase( ((((char*)p) - (char*)0)&7)!=0 ); /* Not always 8-byte aligned */ +#if SQLITE_BYTEORDER==1234 && (GCC_VERSION>=4003000 || CLANG_VERSION>=3000000) + i = (i64)__builtin_bswap64((u64)i); + memcpy(p, &i, 8); +#elif SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300 + i = (i64)_byteswap_uint64((u64)i); + memcpy(p, &i, 8); +#elif SQLITE_BYTEORDER==4321 + memcpy(p, &i, 8); +#else p[0] = (i>>56)&0xFF; p[1] = (i>>48)&0xFF; p[2] = (i>>40)&0xFF; @@ -428,6 +528,7 @@ static int writeInt64(u8 *p, i64 i){ p[5] = (i>>16)&0xFF; p[6] = (i>> 8)&0xFF; p[7] = (i>> 0)&0xFF; +#endif return 8; } @@ -754,11 +855,6 @@ static void nodeGetCell( pData += 8; ii += 2; }while( iinDim*2 ); -#if 0 - for(ii=0; iinDim*2; ii++){ - readCoord(&pData[ii*4], &pCoord[ii]); - } -#endif } @@ -927,15 +1023,22 @@ static int rtreeEof(sqlite3_vtab_cursor *cur){ ** false. a[] is the four bytes of the on-disk record to be decoded. ** Store the results in "r". ** -** There are three versions of this macro, one each for little-endian and -** big-endian processors and a third generic implementation. The endian- -** specific implementations are much faster and are preferred if the -** processor endianness is known at compile-time. The SQLITE_BYTEORDER -** macro is part of sqliteInt.h and hence the endian-specific -** implementation will only be used if this module is compiled as part -** of the amalgamation. +** There are five versions of this macro. The last one is generic. The +** other four are various architectures-specific optimizations. */ -#if defined(SQLITE_BYTEORDER) && SQLITE_BYTEORDER==1234 +#if SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300 +#define RTREE_DECODE_COORD(eInt, a, r) { \ + RtreeCoord c; /* Coordinate decoded */ \ + c.u = _byteswap_ulong(*(u32*)a); \ + r = eInt ? (sqlite3_rtree_dbl)c.i : (sqlite3_rtree_dbl)c.f; \ +} +#elif SQLITE_BYTEORDER==1234 && (GCC_VERSION>=4003000 || CLANG_VERSION>=3000000) +#define RTREE_DECODE_COORD(eInt, a, r) { \ + RtreeCoord c; /* Coordinate decoded */ \ + c.u = __builtin_bswap32(*(u32*)a); \ + r = eInt ? (sqlite3_rtree_dbl)c.i : (sqlite3_rtree_dbl)c.f; \ +} +#elif SQLITE_BYTEORDER==1234 #define RTREE_DECODE_COORD(eInt, a, r) { \ RtreeCoord c; /* Coordinate decoded */ \ memcpy(&c.u,a,4); \ @@ -943,7 +1046,7 @@ static int rtreeEof(sqlite3_vtab_cursor *cur){ ((c.u&0xff)<<24)|((c.u&0xff00)<<8); \ r = eInt ? (sqlite3_rtree_dbl)c.i : (sqlite3_rtree_dbl)c.f; \ } -#elif defined(SQLITE_BYTEORDER) && SQLITE_BYTEORDER==4321 +#elif SQLITE_BYTEORDER==4321 #define RTREE_DECODE_COORD(eInt, a, r) { \ RtreeCoord c; /* Coordinate decoded */ \ memcpy(&c.u,a,4); \ @@ -986,6 +1089,7 @@ static int rtreeCallbackConstraint( i = 0; do{ pCellData += 8; + assert( ((((char*)pCellData) - (char*)0)&3)==0 ); /* 4-byte aligned */ RTREE_DECODE_COORD(eInt, pCellData, aCoord[i]); RTREE_DECODE_COORD(eInt, (pCellData+4), aCoord[i+1]); i+= 2; @@ -1029,6 +1133,7 @@ static void rtreeNonleafConstraint( assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE || p->op==RTREE_GT || p->op==RTREE_EQ ); + assert( ((((char*)pCellData) - (char*)0)&3)==0 ); /* 4-byte aligned */ switch( p->op ){ case RTREE_LE: case RTREE_LT: @@ -1069,6 +1174,7 @@ static void rtreeLeafConstraint( assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE || p->op==RTREE_GT || p->op==RTREE_EQ ); pCellData += 8 + p->iCoord*4; + assert( ((((char*)pCellData) - (char*)0)&3)==0 ); /* 4-byte aligned */ RTREE_DECODE_COORD(eInt, pCellData, xN); switch( p->op ){ case RTREE_LE: if( xN <= p->u.rValue ) return; break; diff --git a/manifest b/manifest index 8145330051..bc185a2197 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\sbuild\sby\smaking\sthe\sOPFLAG_ISNOOP\smacro\savailable\sunconditionally. -D 2017-02-01T15:19:29.202 +C Use\scompiler\sintrinsic\sfunctions\s(when\savailable)\sfor\sbyteswapping\sin\sRTREE. +D 2017-02-01T15:24:32.835 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -264,7 +264,7 @@ F ext/rbu/sqlite3rbu.c bb0de6cdbdb14a7d55a097238a434b7e99caf318 F ext/rbu/sqlite3rbu.h 6fb6294c34a9ca93b5894a33bca530c6f08decba F ext/rbu/test_rbu.c 5aa22616afac6f71ebd3d9bc9bf1006cfabcca88 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 -F ext/rtree/rtree.c f66b3d232ea98285548107caaac55f110a0b6709 +F ext/rtree/rtree.c d8ef14e964a9390197ba7e511aa47b89dc39416c F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e F ext/rtree/rtree1.test 42dadfc7b44a436cd74a1bebc0b9b689e4eaf7ec F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba @@ -1552,7 +1552,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 7f8570208c06c056d426e9299d9930181a0464f8 -R bbb1f490f7311ec1c087c3ef4607e5e0 +P 510933cb24c5bf883265af3a6075e60a4b5ffa37 +R 13778722a0ec2443f74339612adbbcf9 U drh -Z 645035379b970696e5aed344f8a4be19 +Z b1e5b219635e474580d8132f194fff51 diff --git a/manifest.uuid b/manifest.uuid index 0823e8bab6..6e2e6a9d62 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -510933cb24c5bf883265af3a6075e60a4b5ffa37 \ No newline at end of file +82fcd54a5941c20895ffc22d8009c1ebdae44eda \ No newline at end of file From 0e6f67b7545d37f47fa5bdd6907c857a73da3e57 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 1 Feb 2017 15:49:02 +0000 Subject: [PATCH 1275/1484] Precompute the nDim2 value in the Rtree object and use that to make loops over coordinates faster. FossilOrigin-Name: f1f3c8cc733a05c12dd980f2dfa0ab4ccd76c04b --- ext/rtree/rtree.c | 43 +++++++++++++++++++++++++------------------ manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 32 insertions(+), 25 deletions(-) diff --git a/ext/rtree/rtree.c b/ext/rtree/rtree.c index 637fb79d05..7e8b7b2b48 100644 --- a/ext/rtree/rtree.c +++ b/ext/rtree/rtree.c @@ -116,6 +116,7 @@ struct Rtree { sqlite3 *db; /* Host database connection */ int iNodeSize; /* Size in bytes of each node in the node table */ u8 nDim; /* Number of dimensions */ + u8 nDim2; /* Twice the number of dimensions */ u8 eCoordType; /* RTREE_COORD_REAL32 or RTREE_COORD_INT32 */ u8 nBytesPerCell; /* Bytes consumed per cell */ int iDepth; /* Current depth of the r-tree structure */ @@ -711,7 +712,7 @@ static void nodeOverwriteCell( int ii; u8 *p = &pNode->zData[4 + pRtree->nBytesPerCell*iCell]; p += writeInt64(p, pCell->iRowid); - for(ii=0; ii<(pRtree->nDim*2); ii++){ + for(ii=0; iinDim2; ii++){ p += writeCoord(p, &pCell->aCoord[ii]); } pNode->isDirty = 1; @@ -854,7 +855,7 @@ static void nodeGetCell( readCoord(pData+4, &pCoord[ii+1]); pData += 8; ii += 2; - }while( iinDim*2 ); + }while( iinDim2 ); } @@ -1712,7 +1713,7 @@ static int rtreeFilter( if( rc!=SQLITE_OK ){ break; } - p->pInfo->nCoord = pRtree->nDim*2; + p->pInfo->nCoord = pRtree->nDim2; p->pInfo->anQueue = pCsr->anQueue; p->pInfo->mxLevel = pRtree->iDepth + 1; }else{ @@ -1878,10 +1879,11 @@ static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ ** Return the N-dimensional volumn of the cell stored in *p. */ static RtreeDValue cellArea(Rtree *pRtree, RtreeCell *p){ - RtreeDValue area = (RtreeDValue)1; + RtreeDValue area; int ii; - for(ii=0; ii<(pRtree->nDim*2); ii+=2){ - area = (area * (DCOORD(p->aCoord[ii+1]) - DCOORD(p->aCoord[ii]))); + area = DCOORD(p->aCoord[1]) - DCOORD(p->aCoord[0]); + for(ii=2; iinDim2; ii+=2){ + area *= DCOORD(p->aCoord[ii+1]) - DCOORD(p->aCoord[ii]); } return area; } @@ -1891,9 +1893,10 @@ static RtreeDValue cellArea(Rtree *pRtree, RtreeCell *p){ ** of the objects size in each dimension. */ static RtreeDValue cellMargin(Rtree *pRtree, RtreeCell *p){ - RtreeDValue margin = (RtreeDValue)0; + RtreeDValue margin; int ii; - for(ii=0; ii<(pRtree->nDim*2); ii+=2){ + margin = DCOORD(p->aCoord[1]) - DCOORD(p->aCoord[0]); + for(ii=2; iinDim2; ii+=2){ margin += (DCOORD(p->aCoord[ii+1]) - DCOORD(p->aCoord[ii])); } return margin; @@ -1903,17 +1906,19 @@ static RtreeDValue cellMargin(Rtree *pRtree, RtreeCell *p){ ** Store the union of cells p1 and p2 in p1. */ static void cellUnion(Rtree *pRtree, RtreeCell *p1, RtreeCell *p2){ - int ii; + int ii = 0; if( pRtree->eCoordType==RTREE_COORD_REAL32 ){ - for(ii=0; ii<(pRtree->nDim*2); ii+=2){ + do{ p1->aCoord[ii].f = MIN(p1->aCoord[ii].f, p2->aCoord[ii].f); p1->aCoord[ii+1].f = MAX(p1->aCoord[ii+1].f, p2->aCoord[ii+1].f); - } + ii += 2; + }while( iinDim2 ); }else{ - for(ii=0; ii<(pRtree->nDim*2); ii+=2){ + do{ p1->aCoord[ii].i = MIN(p1->aCoord[ii].i, p2->aCoord[ii].i); p1->aCoord[ii+1].i = MAX(p1->aCoord[ii+1].i, p2->aCoord[ii+1].i); - } + ii += 2; + }while( iinDim2 ); } } @@ -1924,7 +1929,7 @@ static void cellUnion(Rtree *pRtree, RtreeCell *p1, RtreeCell *p2){ static int cellContains(Rtree *pRtree, RtreeCell *p1, RtreeCell *p2){ int ii; int isInt = (pRtree->eCoordType==RTREE_COORD_INT32); - for(ii=0; ii<(pRtree->nDim*2); ii+=2){ + for(ii=0; iinDim2; ii+=2){ RtreeCoord *a1 = &p1->aCoord[ii]; RtreeCoord *a2 = &p2->aCoord[ii]; if( (!isInt && (a2[0].fa1[1].f)) @@ -1959,7 +1964,7 @@ static RtreeDValue cellOverlap( for(ii=0; iinDim*2); jj+=2){ + for(jj=0; jjnDim2; jj+=2){ RtreeDValue x1, x2; x1 = MAX(DCOORD(p->aCoord[jj]), DCOORD(aCell[ii].aCoord[jj])); x2 = MIN(DCOORD(p->aCoord[jj+1]), DCOORD(aCell[ii].aCoord[jj+1])); @@ -3015,7 +3020,7 @@ static int rtreeUpdate( ** This problem was discovered after years of use, so we silently ignore ** these kinds of misdeclared tables to avoid breaking any legacy. */ - assert( nData<=(pRtree->nDim*2 + 3) ); + assert( nData<=(pRtree->nDim2 + 3) ); #ifndef SQLITE_RTREE_INT_ONLY if( pRtree->eCoordType==RTREE_COORD_REAL32 ){ @@ -3393,7 +3398,8 @@ static int rtreeInit( pRtree->zDb = (char *)&pRtree[1]; pRtree->zName = &pRtree->zDb[nDb+1]; pRtree->nDim = (argc-4)/2; - pRtree->nBytesPerCell = 8 + pRtree->nDim*4*2; + pRtree->nDim2 = argc - 4; + pRtree->nBytesPerCell = 8 + pRtree->nDim2*4; pRtree->eCoordType = eCoordType; memcpy(pRtree->zDb, argv[1], nDb); memcpy(pRtree->zName, argv[2], nName); @@ -3468,6 +3474,7 @@ static void rtreenode(sqlite3_context *ctx, int nArg, sqlite3_value **apArg){ memset(&node, 0, sizeof(RtreeNode)); memset(&tree, 0, sizeof(Rtree)); tree.nDim = sqlite3_value_int(apArg[0]); + tree.nDim2 = tree.nDim*2; tree.nBytesPerCell = 8 + 8 * tree.nDim; node.zData = (u8 *)sqlite3_value_blob(apArg[1]); @@ -3480,7 +3487,7 @@ static void rtreenode(sqlite3_context *ctx, int nArg, sqlite3_value **apArg){ nodeGetCell(&tree, &node, ii, &cell); sqlite3_snprintf(512-nCell,&zCell[nCell],"%lld", cell.iRowid); nCell = (int)strlen(zCell); - for(jj=0; jj Date: Wed, 1 Feb 2017 16:41:30 +0000 Subject: [PATCH 1276/1484] Completely unroll the dimension loop inside of cellArea() in RTREE. FossilOrigin-Name: 3c4c0126c287f844220b65e00fec17c059fbb7c8 --- ext/rtree/rtree.c | 26 +++++++++++++++++++++----- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 28 insertions(+), 12 deletions(-) diff --git a/ext/rtree/rtree.c b/ext/rtree/rtree.c index 7e8b7b2b48..4d67d67044 100644 --- a/ext/rtree/rtree.c +++ b/ext/rtree/rtree.c @@ -1879,11 +1879,27 @@ static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ ** Return the N-dimensional volumn of the cell stored in *p. */ static RtreeDValue cellArea(Rtree *pRtree, RtreeCell *p){ - RtreeDValue area; - int ii; - area = DCOORD(p->aCoord[1]) - DCOORD(p->aCoord[0]); - for(ii=2; iinDim2; ii+=2){ - area *= DCOORD(p->aCoord[ii+1]) - DCOORD(p->aCoord[ii]); + RtreeDValue area = (RtreeDValue)1; + assert( pRtree->nDim>=1 && pRtree->nDim<=5 ); +#ifndef SQLITE_RTREE_INT_ONLY + if( pRtree->eCoordType==RTREE_COORD_REAL32 ){ + switch( pRtree->nDim ){ + case 5: area = p->aCoord[9].f - p->aCoord[8].f; + case 4: area *= p->aCoord[7].f - p->aCoord[6].f; + case 3: area *= p->aCoord[5].f - p->aCoord[4].f; + case 2: area *= p->aCoord[3].f - p->aCoord[2].f; + default: area *= p->aCoord[1].f - p->aCoord[0].f; + } + }else +#endif + { + switch( pRtree->nDim ){ + case 5: area = p->aCoord[9].i - p->aCoord[8].i; + case 4: area *= p->aCoord[7].i - p->aCoord[6].i; + case 3: area *= p->aCoord[5].i - p->aCoord[4].i; + case 2: area *= p->aCoord[3].i - p->aCoord[2].i; + default: area *= p->aCoord[1].i - p->aCoord[0].i; + } } return area; } diff --git a/manifest b/manifest index 47d8c1d927..62887ba814 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Precompute\sthe\snDim2\svalue\sin\sthe\sRtree\sobject\sand\suse\sthat\sto\smake\sloops\nover\scoordinates\sfaster. -D 2017-02-01T15:49:02.390 +C Completely\sunroll\sthe\sdimension\sloop\sinside\sof\scellArea()\sin\sRTREE. +D 2017-02-01T16:41:30.471 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -264,7 +264,7 @@ F ext/rbu/sqlite3rbu.c bb0de6cdbdb14a7d55a097238a434b7e99caf318 F ext/rbu/sqlite3rbu.h 6fb6294c34a9ca93b5894a33bca530c6f08decba F ext/rbu/test_rbu.c 5aa22616afac6f71ebd3d9bc9bf1006cfabcca88 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 -F ext/rtree/rtree.c bc73bae0af0d44f92b7d6cb513b719c1e89a7a20 +F ext/rtree/rtree.c 60df707ce5ae232351fc7fc8e916738b1a06bf26 F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e F ext/rtree/rtree1.test 42dadfc7b44a436cd74a1bebc0b9b689e4eaf7ec F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba @@ -1552,7 +1552,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 82fcd54a5941c20895ffc22d8009c1ebdae44eda -R 2d19b39f1fe0fa1365532dfac9c432a7 +P f1f3c8cc733a05c12dd980f2dfa0ab4ccd76c04b +R f244aabca54009b102530102725b0e43 U drh -Z 1d3fc5da859da34aeaaaf616405346d2 +Z 396b9b4a99bf06a5c73ba01696403f75 diff --git a/manifest.uuid b/manifest.uuid index 5d3a3937af..a4a1237e47 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f1f3c8cc733a05c12dd980f2dfa0ab4ccd76c04b \ No newline at end of file +3c4c0126c287f844220b65e00fec17c059fbb7c8 \ No newline at end of file From 31a13495153ece728af9641e4327f009088cab3f Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 1 Feb 2017 17:08:56 +0000 Subject: [PATCH 1277/1484] Unwind the RTREE dimension loop inside of rtreeCallbackConstraint(). FossilOrigin-Name: 4854ea9c18e7d8066c90b41568d0fae97b01ea6d --- ext/rtree/rtree.c | 41 ++++++++++++++++++++++++++++++++--------- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 39 insertions(+), 16 deletions(-) diff --git a/ext/rtree/rtree.c b/ext/rtree/rtree.c index 4d67d67044..ac76c18485 100644 --- a/ext/rtree/rtree.c +++ b/ext/rtree/rtree.c @@ -1078,6 +1078,7 @@ static int rtreeCallbackConstraint( sqlite3_rtree_query_info *pInfo = pConstraint->pInfo; /* Callback info */ int nCoord = pInfo->nCoord; /* No. of coordinates */ int rc; /* Callback return code */ + RtreeCoord c; /* Translator union */ sqlite3_rtree_dbl aCoord[RTREE_MAX_DIMENSIONS*2]; /* Decoded coordinates */ assert( pConstraint->op==RTREE_MATCH || pConstraint->op==RTREE_QUERY ); @@ -1086,15 +1087,37 @@ static int rtreeCallbackConstraint( if( pConstraint->op==RTREE_QUERY && pSearch->iLevel==1 ){ pInfo->iRowid = readInt64(pCellData); } - assert( nCoord>=2 && (nCoord&1)==0 ); - i = 0; - do{ - pCellData += 8; - assert( ((((char*)pCellData) - (char*)0)&3)==0 ); /* 4-byte aligned */ - RTREE_DECODE_COORD(eInt, pCellData, aCoord[i]); - RTREE_DECODE_COORD(eInt, (pCellData+4), aCoord[i+1]); - i+= 2; - }while( iop==RTREE_MATCH ){ rc = pConstraint->u.xGeom((sqlite3_rtree_geometry*)pInfo, nCoord, aCoord, &i); diff --git a/manifest b/manifest index 62887ba814..8bb675991a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Completely\sunroll\sthe\sdimension\sloop\sinside\sof\scellArea()\sin\sRTREE. -D 2017-02-01T16:41:30.471 +C Unwind\sthe\sRTREE\sdimension\sloop\sinside\sof\srtreeCallbackConstraint(). +D 2017-02-01T17:08:56.249 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -264,7 +264,7 @@ F ext/rbu/sqlite3rbu.c bb0de6cdbdb14a7d55a097238a434b7e99caf318 F ext/rbu/sqlite3rbu.h 6fb6294c34a9ca93b5894a33bca530c6f08decba F ext/rbu/test_rbu.c 5aa22616afac6f71ebd3d9bc9bf1006cfabcca88 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 -F ext/rtree/rtree.c 60df707ce5ae232351fc7fc8e916738b1a06bf26 +F ext/rtree/rtree.c f2c8604fcdbe13f960c5f0b97acbc2a870b72bf2 F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e F ext/rtree/rtree1.test 42dadfc7b44a436cd74a1bebc0b9b689e4eaf7ec F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba @@ -1552,7 +1552,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P f1f3c8cc733a05c12dd980f2dfa0ab4ccd76c04b -R f244aabca54009b102530102725b0e43 +P 3c4c0126c287f844220b65e00fec17c059fbb7c8 +R f35bf88856ef1a64759d9b647928073d U drh -Z 396b9b4a99bf06a5c73ba01696403f75 +Z 9add4b4d28dce63431ad3a0684bb5601 diff --git a/manifest.uuid b/manifest.uuid index a4a1237e47..8728c8d9a3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3c4c0126c287f844220b65e00fec17c059fbb7c8 \ No newline at end of file +4854ea9c18e7d8066c90b41568d0fae97b01ea6d \ No newline at end of file From 8c5e8feb35641dc8fc8b3512aa79fd0fcfff775e Mon Sep 17 00:00:00 2001 From: mistachkin Date: Wed, 1 Feb 2017 22:32:49 +0000 Subject: [PATCH 1278/1484] Add an option to the MSVC makefile to enable treating warnings as errors. FossilOrigin-Name: 6a378c29b43d61313ca9daa599e59d8eeeed9a27 --- Makefile.msc | 13 +++++++++++++ autoconf/Makefile.msc | 13 +++++++++++++ manifest | 16 ++++++++-------- manifest.uuid | 2 +- 4 files changed, 35 insertions(+), 9 deletions(-) diff --git a/Makefile.msc b/Makefile.msc index d4aba301fb..4a29f913c8 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -24,6 +24,13 @@ USE_AMALGAMATION = 1 USE_FULLWARN = 0 !ENDIF +# Set this non-0 to enable treating warnings as errors (-WX, etc) when +# compiling. +# +!IFNDEF USE_FATAL_WARN +USE_FATAL_WARN = 0 +!ENDIF + # Set this non-0 to enable full runtime error checks (-RTC1, etc). This # has no effect if (any) optimizations are enabled. # @@ -493,6 +500,12 @@ TCC = $(CC) -nologo -W4 -DINCLUDE_MSVC_H=1 $(CCOPTS) $(TCCOPTS) TCC = $(CC) -nologo -W3 $(CCOPTS) $(TCCOPTS) !ENDIF +# Check if warnings should be treated as errors when compiling. +# +!IF $(USE_FATAL_WARN)!=0 +TCC = $(TCC) -WX +!ENDIF + TCC = $(TCC) -DSQLITE_OS_WIN=1 -I. -I$(TOP) -I$(TOP)\src -fp:precise RCC = $(RC) -DSQLITE_OS_WIN=1 -I. -I$(TOP) -I$(TOP)\src $(RCOPTS) $(RCCOPTS) diff --git a/autoconf/Makefile.msc b/autoconf/Makefile.msc index b53e2370eb..32d03dbf35 100644 --- a/autoconf/Makefile.msc +++ b/autoconf/Makefile.msc @@ -24,6 +24,13 @@ TOP = . USE_FULLWARN = 0 !ENDIF +# Set this non-0 to enable treating warnings as errors (-WX, etc) when +# compiling. +# +!IFNDEF USE_FATAL_WARN +USE_FATAL_WARN = 0 +!ENDIF + # Set this non-0 to enable full runtime error checks (-RTC1, etc). This # has no effect if (any) optimizations are enabled. # @@ -454,6 +461,12 @@ TCC = $(CC) -nologo -W4 -DINCLUDE_MSVC_H=1 $(CCOPTS) $(TCCOPTS) TCC = $(CC) -nologo -W3 $(CCOPTS) $(TCCOPTS) !ENDIF +# Check if warnings should be treated as errors when compiling. +# +!IF $(USE_FATAL_WARN)!=0 +TCC = $(TCC) -WX +!ENDIF + TCC = $(TCC) -DSQLITE_OS_WIN=1 -I. -I$(TOP) -fp:precise RCC = $(RC) -DSQLITE_OS_WIN=1 -I. -I$(TOP) $(RCOPTS) $(RCCOPTS) diff --git a/manifest b/manifest index 8bb675991a..2bea70b5b4 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -C Unwind\sthe\sRTREE\sdimension\sloop\sinside\sof\srtreeCallbackConstraint(). -D 2017-02-01T17:08:56.249 +C Add\san\soption\sto\sthe\sMSVC\smakefile\sto\senable\streating\swarnings\sas\serrors. +D 2017-02-01T22:32:49.021 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 -F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da +F Makefile.msc ba953c8921fc7e18333f61898007206de7e23964 F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7 F VERSION cddd8d88dc8202afa0ebc96da61fc4acbd1e96a5 F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 @@ -11,7 +11,7 @@ F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am 1a47d071e3d5435f8f7ebff7eb6703848bbd65d4 -F autoconf/Makefile.msc b6d27f735911fd09a589d3c966936c47a5850c17 +F autoconf/Makefile.msc 3f29e0fc2a78e113250d79a5da375c1d8d8c06b0 F autoconf/README.first 6c4f34fe115ff55d4e8dbfa3cecf04a0188292f7 F autoconf/README.txt 4f04b0819303aabaa35fff5f7b257fb0c1ef95f1 F autoconf/configure.ac cacf2616abf6e4a569bde2ef365c143caeec40bc @@ -1552,7 +1552,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 3c4c0126c287f844220b65e00fec17c059fbb7c8 -R f35bf88856ef1a64759d9b647928073d -U drh -Z 9add4b4d28dce63431ad3a0684bb5601 +P 4854ea9c18e7d8066c90b41568d0fae97b01ea6d +R edeb8ee1db3973795f07ac14a992bc66 +U mistachkin +Z 3bfb007e12a85d09e541803b4d02a604 diff --git a/manifest.uuid b/manifest.uuid index 8728c8d9a3..72864f657b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4854ea9c18e7d8066c90b41568d0fae97b01ea6d \ No newline at end of file +6a378c29b43d61313ca9daa599e59d8eeeed9a27 \ No newline at end of file From 2e525322172e49823cc72daa0e84e5a84b5d2f62 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Wed, 1 Feb 2017 22:43:08 +0000 Subject: [PATCH 1279/1484] Fix harmless compiler warnings seen with MSVC. FossilOrigin-Name: 997f765bc6706769ae15f3e719354473e02bd78b --- ext/fts3/fts3.c | 8 ++++---- ext/rtree/rtree.c | 14 +++++++------- manifest | 19 +++++++++++-------- manifest.uuid | 2 +- src/pragma.c | 2 +- 5 files changed, 24 insertions(+), 21 deletions(-) diff --git a/ext/fts3/fts3.c b/ext/fts3/fts3.c index 748faefec5..c12e3d2156 100644 --- a/ext/fts3/fts3.c +++ b/ext/fts3/fts3.c @@ -1363,9 +1363,9 @@ static int fts3InitVtab( p->pTokenizer = pTokenizer; p->nMaxPendingData = FTS3_MAX_PENDING_DATA; p->bHasDocsize = (isFts4 && bNoDocsize==0); - p->bHasStat = isFts4; - p->bFts4 = isFts4; - p->bDescIdx = bDescIdx; + p->bHasStat = (u8)isFts4; + p->bFts4 = (u8)isFts4; + p->bDescIdx = (u8)bDescIdx; p->nAutoincrmerge = 0xff; /* 0xff means setting unknown */ p->zContentTbl = zContent; p->zLanguageid = zLanguageid; @@ -3422,7 +3422,7 @@ static int fts3SetHasStat(Fts3Table *p){ if( rc==SQLITE_OK ){ int bHasStat = (sqlite3_step(pStmt)==SQLITE_ROW); rc = sqlite3_finalize(pStmt); - if( rc==SQLITE_OK ) p->bHasStat = bHasStat; + if( rc==SQLITE_OK ) p->bHasStat = (u8)bHasStat; } sqlite3_free(zSql); }else{ diff --git a/ext/rtree/rtree.c b/ext/rtree/rtree.c index ac76c18485..ac84562590 100644 --- a/ext/rtree/rtree.c +++ b/ext/rtree/rtree.c @@ -1515,7 +1515,7 @@ static int rtreeStepToLeaf(RtreeCursor *pCur){ if( rScoreeWithin = eWithin; + p->eWithin = (u8)eWithin; p->id = x.id; p->iCell = x.iCell; RTREE_QUEUE_TRACE(pCur, "PUSH-S:"); @@ -1703,7 +1703,7 @@ static int rtreeFilter( p->id = iNode; p->eWithin = PARTLY_WITHIN; rc = nodeRowidIndex(pRtree, pLeaf, iRowid, &iCell); - p->iCell = iCell; + p->iCell = (u8)iCell; RTREE_QUEUE_TRACE(pCsr, "PUSH-F1:"); }else{ pCsr->atEOF = 1; @@ -1751,7 +1751,7 @@ static int rtreeFilter( } if( rc==SQLITE_OK ){ RtreeSearchPoint *pNew; - pNew = rtreeSearchPointNew(pCsr, RTREE_ZERO, pRtree->iDepth+1); + pNew = rtreeSearchPointNew(pCsr, RTREE_ZERO, (u8)(pRtree->iDepth+1)); if( pNew==0 ) return SQLITE_NOMEM; pNew->id = 1; pNew->iCell = 0; @@ -1879,7 +1879,7 @@ static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ break; } zIdxStr[iIdx++] = op; - zIdxStr[iIdx++] = p->iColumn - 1 + '0'; + zIdxStr[iIdx++] = (char)(p->iColumn - 1 + '0'); pIdxInfo->aConstraintUsage[ii].argvIndex = (iIdx/2); pIdxInfo->aConstraintUsage[ii].omit = 1; } @@ -3436,10 +3436,10 @@ static int rtreeInit( pRtree->base.pModule = &rtreeModule; pRtree->zDb = (char *)&pRtree[1]; pRtree->zName = &pRtree->zDb[nDb+1]; - pRtree->nDim = (argc-4)/2; + pRtree->nDim = (u8)((argc-4)/2); pRtree->nDim2 = argc - 4; pRtree->nBytesPerCell = 8 + pRtree->nDim2*4; - pRtree->eCoordType = eCoordType; + pRtree->eCoordType = (u8)eCoordType; memcpy(pRtree->zDb, argv[1], nDb); memcpy(pRtree->zName, argv[2], nName); @@ -3512,7 +3512,7 @@ static void rtreenode(sqlite3_context *ctx, int nArg, sqlite3_value **apArg){ UNUSED_PARAMETER(nArg); memset(&node, 0, sizeof(RtreeNode)); memset(&tree, 0, sizeof(Rtree)); - tree.nDim = sqlite3_value_int(apArg[0]); + tree.nDim = (u8)sqlite3_value_int(apArg[0]); tree.nDim2 = tree.nDim*2; tree.nBytesPerCell = 8 + 8 * tree.nDim; node.zData = (u8 *)sqlite3_value_blob(apArg[1]); diff --git a/manifest b/manifest index 2bea70b5b4..1d0d458233 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\san\soption\sto\sthe\sMSVC\smakefile\sto\senable\streating\swarnings\sas\serrors. -D 2017-02-01T22:32:49.021 +C Fix\sharmless\scompiler\swarnings\sseen\swith\sMSVC. +D 2017-02-01T22:43:08.270 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc ba953c8921fc7e18333f61898007206de7e23964 @@ -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 e028eb13432f108d2e22cded019fc980700e4e00 +F ext/fts3/fts3.c 5a8cafedffd101e9946f8909ecf8d34aaa383b4d F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe F ext/fts3/fts3Int.h 89d0bd4595a0de384dac78e94b803de12586e8dd F ext/fts3/fts3_aux.c 9edc3655fcb287f0467d0a4b886a01c6185fe9f1 @@ -264,7 +264,7 @@ F ext/rbu/sqlite3rbu.c bb0de6cdbdb14a7d55a097238a434b7e99caf318 F ext/rbu/sqlite3rbu.h 6fb6294c34a9ca93b5894a33bca530c6f08decba F ext/rbu/test_rbu.c 5aa22616afac6f71ebd3d9bc9bf1006cfabcca88 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 -F ext/rtree/rtree.c f2c8604fcdbe13f960c5f0b97acbc2a870b72bf2 +F ext/rtree/rtree.c 880edfc9a342c130fb2e220c4d7471729e764334 F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e F ext/rtree/rtree1.test 42dadfc7b44a436cd74a1bebc0b9b689e4eaf7ec F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba @@ -386,7 +386,7 @@ F src/parse.y 591704fce84f814d9a3642774c1f011d38f4149c F src/pcache.c 51070ec9b8251bbf9c6ea3d35fd96a458752929e F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 F src/pcache1.c e3967219b2a92b9edcb9324a4ba75009090d3953 -F src/pragma.c 0e7a7c6f1c6fd8ff50c0fff65b8bb80174bc49c5 +F src/pragma.c 7831956012f5d764761fbd023e59b0ffc08f5e8d F src/pragma.h 61aa5389118594bebb28120a6720401aee34ce1a F src/prepare.c b1140c3d0cf59bc85ace00ce363153041b424b7a F src/printf.c ff10a9b9902cd2afe5f655f3013c6307d969b1fd @@ -1552,7 +1552,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 4854ea9c18e7d8066c90b41568d0fae97b01ea6d -R edeb8ee1db3973795f07ac14a992bc66 +P 6a378c29b43d61313ca9daa599e59d8eeeed9a27 +R 1fd2d9b1d5e3d137e94e02ebe9288650 +T *branch * msvcWarn +T *sym-msvcWarn * +T -sym-trunk * U mistachkin -Z 3bfb007e12a85d09e541803b4d02a604 +Z c7bdc5431b2e37708dfabf3606031db2 diff --git a/manifest.uuid b/manifest.uuid index 72864f657b..365c5fd48f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6a378c29b43d61313ca9daa599e59d8eeeed9a27 \ No newline at end of file +997f765bc6706769ae15f3e719354473e02bd78b \ No newline at end of file diff --git a/src/pragma.c b/src/pragma.c index 5251d0cd26..b1775a4082 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -279,7 +279,7 @@ const char *sqlite3JournalModename(int eMode){ ** Locate a pragma in the aPragmaName[] array. */ static const PragmaName *pragmaLocate(const char *zName){ - int upr, lwr, mid, rc; + int upr, lwr, mid = 0, rc; lwr = 0; upr = ArraySize(aPragmaName)-1; while( lwr<=upr ){ From 2fa517bf2a8dbc4e76464675a0e5ef5af776bfa3 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Wed, 1 Feb 2017 22:59:29 +0000 Subject: [PATCH 1280/1484] Fix C99-style variable declaration issue seen with older versions of MSVC. FossilOrigin-Name: 54d285464a222c59327eb6c917c1cc0125a55a27 --- ext/rtree/rtree.c | 5 ++++- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/ext/rtree/rtree.c b/ext/rtree/rtree.c index ac76c18485..fe89835972 100644 --- a/ext/rtree/rtree.c +++ b/ext/rtree/rtree.c @@ -450,20 +450,23 @@ static void readCoord(u8 *p, RtreeCoord *pCoord){ #endif } static i64 readInt64(u8 *p){ - testcase( ((((char*)p) - (char*)0)&7)!=0 ); /* not always 8-byte aligned */ #if SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300 u64 x; + testcase( ((((char*)p) - (char*)0)&7)!=0 ); /* not always 8-byte aligned */ memcpy(&x, p, 8); return (i64)_byteswap_uint64(x); #elif SQLITE_BYTEORDER==1234 && (GCC_VERSION>=4003000 || CLANG_VERSION>=3000000) u64 x; + testcase( ((((char*)p) - (char*)0)&7)!=0 ); /* not always 8-byte aligned */ memcpy(&x, p, 8); return (i64)__builtin_bswap64(x); #elif SQLITE_BYTEORDER==4321 i64 x; + testcase( ((((char*)p) - (char*)0)&7)!=0 ); /* not always 8-byte aligned */ memcpy(&x, p, 8); return x; #else + testcase( ((((char*)p) - (char*)0)&7)!=0 ); /* not always 8-byte aligned */ return ( (((i64)p[0]) << 56) + (((i64)p[1]) << 48) + diff --git a/manifest b/manifest index 2bea70b5b4..aa07fecd68 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\san\soption\sto\sthe\sMSVC\smakefile\sto\senable\streating\swarnings\sas\serrors. -D 2017-02-01T22:32:49.021 +C Fix\sC99-style\svariable\sdeclaration\sissue\sseen\swith\solder\sversions\sof\sMSVC. +D 2017-02-01T22:59:29.767 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc ba953c8921fc7e18333f61898007206de7e23964 @@ -264,7 +264,7 @@ F ext/rbu/sqlite3rbu.c bb0de6cdbdb14a7d55a097238a434b7e99caf318 F ext/rbu/sqlite3rbu.h 6fb6294c34a9ca93b5894a33bca530c6f08decba F ext/rbu/test_rbu.c 5aa22616afac6f71ebd3d9bc9bf1006cfabcca88 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 -F ext/rtree/rtree.c f2c8604fcdbe13f960c5f0b97acbc2a870b72bf2 +F ext/rtree/rtree.c 58d3fa51e270b93e1d4ceb7ffb5c0f3b85cb4129 F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e F ext/rtree/rtree1.test 42dadfc7b44a436cd74a1bebc0b9b689e4eaf7ec F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba @@ -1552,7 +1552,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 4854ea9c18e7d8066c90b41568d0fae97b01ea6d -R edeb8ee1db3973795f07ac14a992bc66 +P 6a378c29b43d61313ca9daa599e59d8eeeed9a27 +R 464fa6ae427ab1455a9a5204291b6a50 U mistachkin -Z 3bfb007e12a85d09e541803b4d02a604 +Z 85455f002136d0ca47deec93d577c815 diff --git a/manifest.uuid b/manifest.uuid index 72864f657b..93c65ce658 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6a378c29b43d61313ca9daa599e59d8eeeed9a27 \ No newline at end of file +54d285464a222c59327eb6c917c1cc0125a55a27 \ No newline at end of file From 5f7b95f73b9b6e157a9cfb90836dbac42cd4c97b Mon Sep 17 00:00:00 2001 From: mistachkin Date: Wed, 1 Feb 2017 23:03:54 +0000 Subject: [PATCH 1281/1484] Backout the change in [02f6293f27] as it causes MSVC to complain. FossilOrigin-Name: aaae74d06f4865818465cfdb440258ae8a5b985a --- manifest | 13 +++++++------ manifest.uuid | 2 +- src/vdbe.c | 2 +- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index aa07fecd68..257674eec1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sC99-style\svariable\sdeclaration\sissue\sseen\swith\solder\sversions\sof\sMSVC. -D 2017-02-01T22:59:29.767 +C Backout\sthe\schange\sin\s[02f6293f27]\sas\sit\scauses\sMSVC\sto\scomplain. +D 2017-02-01T23:03:54.479 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc ba953c8921fc7e18333f61898007206de7e23964 @@ -460,7 +460,7 @@ F src/update.c 456d4a4656f8a03c2abc88a51b19172197400e58 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c a88b0466fddf445ce752226d4698ca3faada620a F src/vacuum.c 33c174b28886b2faf26e503b5a49a1c01a9b1c16 -F src/vdbe.c ec059d331da77cb2e3e8af3fb7e40443ed148fbd +F src/vdbe.c e7b1e860140f1d1803c6f4176b1e8f3801f3a290 F src/vdbe.h 59998ffd71d7caa8886bc78dafaf8caeccd4c13c F src/vdbeInt.h 4e4b15b2e1330e1636e4e01974eab2b0b985092f F src/vdbeapi.c 3e4a8893feeb78620f4aac4ac5b85d92255b97e1 @@ -1552,7 +1552,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 6a378c29b43d61313ca9daa599e59d8eeeed9a27 -R 464fa6ae427ab1455a9a5204291b6a50 +P 54d285464a222c59327eb6c917c1cc0125a55a27 +Q -02f6293f278f7b0a0f4876f5c6a0f4dc42620d79 +R c167920e65eb1311d91ae6d6e9361130 U mistachkin -Z 85455f002136d0ca47deec93d577c815 +Z 464bc0b25a9ceacfcf91d7e8480e3c64 diff --git a/manifest.uuid b/manifest.uuid index 93c65ce658..6df479bdb3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -54d285464a222c59327eb6c917c1cc0125a55a27 \ No newline at end of file +aaae74d06f4865818465cfdb440258ae8a5b985a \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index c8b3db8cf2..cb8a039abb 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -562,7 +562,7 @@ int sqlite3VdbeExec( Vdbe *p /* The VDBE */ ){ Op *aOp = p->aOp; /* Copy of p->aOp */ - Op *pOp; /* Current operation */ + Op *pOp = aOp; /* Current operation */ #if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) Op *pOrigOp; /* Value of pOp at the top of the loop */ #endif From 2343c7eb3f0f6fbb4d3719a09ac31bfb33a357d4 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 2 Feb 2017 00:46:55 +0000 Subject: [PATCH 1282/1484] This is an experimental patch that ensures that all cursors have their position saved prior to starting a ROLLBACK TO. FossilOrigin-Name: 01d97e5b6502b1811b52a681f445e1aaae6c0ee6 --- manifest | 18 ++++++++++-------- manifest.uuid | 2 +- src/btree.c | 7 ++++++- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 6459c8e5ad..4cc36f422d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\scompiler\swarnings\sseen\swith\sMSVC. -D 2017-02-01T23:06:17.747 +C This\sis\san\sexperimental\spatch\sthat\sensures\sthat\sall\scursors\shave\stheir\sposition\nsaved\sprior\sto\sstarting\sa\sROLLBACK\sTO. +D 2017-02-02T00:46:55.000 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc ba953c8921fc7e18333f61898007206de7e23964 @@ -336,7 +336,7 @@ F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792 F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca -F src/btree.c 6a63fa34e6fe86e87090e41963c0f2fcf9d3e16d +F src/btree.c 9fe65ab418d99e80289f024016b5e5e74c3059dd F src/btree.h e6d352808956ec163a17f832193a3e198b3fb0ac F src/btreeInt.h 10c4b77c2fb399580babbcc7cf652ac10dba796e F src/build.c 9e799f1edd910dfa8a0bc29bd390d35d310596af @@ -1552,8 +1552,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P aaae74d06f4865818465cfdb440258ae8a5b985a 997f765bc6706769ae15f3e719354473e02bd78b -R 939bce209d57b72db3d58f9894d61374 -T +closed 997f765bc6706769ae15f3e719354473e02bd78b -U mistachkin -Z c2a7081e9858115a573bd4695718af54 +P 0c66cf0f0a9ada2ddcb8d61001ef791b86226416 +R 329580c21139f900f64001f6acfc9557 +T *branch * savepoint-rollback +T *sym-savepoint-rollback * +T -sym-trunk * +U drh +Z 5087946e64391fb6ac59f69d722efdd6 diff --git a/manifest.uuid b/manifest.uuid index 0e34341685..9d5ad1c981 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0c66cf0f0a9ada2ddcb8d61001ef791b86226416 \ No newline at end of file +01d97e5b6502b1811b52a681f445e1aaae6c0ee6 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 45a1c5a0f8..de553423b8 100644 --- a/src/btree.c +++ b/src/btree.c @@ -4038,7 +4038,12 @@ int sqlite3BtreeSavepoint(Btree *p, int op, int iSavepoint){ assert( op==SAVEPOINT_RELEASE || op==SAVEPOINT_ROLLBACK ); assert( iSavepoint>=0 || (iSavepoint==-1 && op==SAVEPOINT_ROLLBACK) ); sqlite3BtreeEnter(p); - rc = sqlite3PagerSavepoint(pBt->pPager, op, iSavepoint); + if( op==SAVEPOINT_ROLLBACK ){ + rc = saveAllCursors(pBt, 0, 0); + } + if( rc==SQLITE_OK ){ + rc = sqlite3PagerSavepoint(pBt->pPager, op, iSavepoint); + } if( rc==SQLITE_OK ){ if( iSavepoint<0 && (pBt->btsFlags & BTS_INITIALLY_EMPTY)!=0 ){ pBt->nPage = 0; From 6d683c5c6e7cfbd3393f64e6520caef5a5921a53 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 2 Feb 2017 02:28:45 +0000 Subject: [PATCH 1283/1484] Use the sqlite3_blob interface for reading values from the %_node shadow table in RTREE. This is a work in progress. There are still some minor problems. FossilOrigin-Name: fc4917d730b29b0bf60fea5e0166728635783e9c --- ext/rtree/rtree.c | 106 ++++++++++++++++++++++++++++++++++------------ manifest | 18 ++++---- manifest.uuid | 2 +- 3 files changed, 88 insertions(+), 38 deletions(-) diff --git a/ext/rtree/rtree.c b/ext/rtree/rtree.c index 66cca987da..eae9ef819a 100644 --- a/ext/rtree/rtree.c +++ b/ext/rtree/rtree.c @@ -133,6 +133,9 @@ struct Rtree { RtreeNode *pDeleted; int iReinsertHeight; /* Height of sub-trees Reinsert() has run on */ + /* Blob I/O on xxx_node */ + sqlite3_blob *pNodeBlob; + /* Statements to read/write/delete a record from xxx_node */ sqlite3_stmt *pReadNode; sqlite3_stmt *pWriteNode; @@ -615,6 +618,16 @@ static RtreeNode *nodeNew(Rtree *pRtree, RtreeNode *pParent){ return pNode; } +/* +** Clear the Rtree.pNodeBlob object +*/ +static void nodeBlobReset(Rtree *pRtree){ + if( pRtree->pNodeBlob ){ + sqlite3_blob_close(pRtree->pNodeBlob); + pRtree->pNodeBlob = 0; + } +} + /* ** Obtain a reference to an r-tree node. */ @@ -624,9 +637,8 @@ static int nodeAcquire( RtreeNode *pParent, /* Either the parent node or NULL */ RtreeNode **ppNode /* OUT: Acquired node */ ){ - int rc; - int rc2 = SQLITE_OK; - RtreeNode *pNode; + int rc = SQLITE_OK; + RtreeNode *pNode = 0; /* Check if the requested node is already in the hash table. If so, ** increase its reference count and return it. @@ -642,28 +654,42 @@ static int nodeAcquire( return SQLITE_OK; } - sqlite3_bind_int64(pRtree->pReadNode, 1, iNode); - rc = sqlite3_step(pRtree->pReadNode); - if( rc==SQLITE_ROW ){ - const u8 *zBlob = sqlite3_column_blob(pRtree->pReadNode, 0); - if( pRtree->iNodeSize==sqlite3_column_bytes(pRtree->pReadNode, 0) ){ - pNode = (RtreeNode *)sqlite3_malloc(sizeof(RtreeNode)+pRtree->iNodeSize); - if( !pNode ){ - rc2 = SQLITE_NOMEM; - }else{ - pNode->pParent = pParent; - pNode->zData = (u8 *)&pNode[1]; - pNode->nRef = 1; - pNode->iNode = iNode; - pNode->isDirty = 0; - pNode->pNext = 0; - memcpy(pNode->zData, zBlob, pRtree->iNodeSize); - nodeReference(pParent); - } + if( pRtree->pNodeBlob ){ + sqlite3_blob *pBlob = pRtree->pNodeBlob; + pRtree->pNodeBlob = 0; + rc = sqlite3_blob_reopen(pBlob, iNode); + pRtree->pNodeBlob = pBlob; + if( rc ){ + nodeBlobReset(pRtree); + if( rc==SQLITE_NOMEM ) return rc; + } + } + if( pRtree->pNodeBlob==0 ){ + char *zTab = sqlite3_mprintf("%s_node", pRtree->zName); + if( zTab==0 ) return SQLITE_NOMEM; + rc = sqlite3_blob_open(pRtree->db, pRtree->zDb, zTab, "data", iNode, 0, + &pRtree->pNodeBlob); + sqlite3_free(zTab); + } + if( rc ){ + nodeBlobReset(pRtree); + *ppNode = 0; + }else if( pRtree->iNodeSize==sqlite3_blob_bytes(pRtree->pNodeBlob) ){ + pNode = (RtreeNode *)sqlite3_malloc(sizeof(RtreeNode)+pRtree->iNodeSize); + if( !pNode ){ + rc = SQLITE_NOMEM; + }else{ + pNode->pParent = pParent; + pNode->zData = (u8 *)&pNode[1]; + pNode->nRef = 1; + pNode->iNode = iNode; + pNode->isDirty = 0; + pNode->pNext = 0; + rc = sqlite3_blob_read(pRtree->pNodeBlob, pNode->zData, + pRtree->iNodeSize, 0); + nodeReference(pParent); } } - rc = sqlite3_reset(pRtree->pReadNode); - if( rc==SQLITE_OK ) rc = rc2; /* If the root node was just loaded, set pRtree->iDepth to the height ** of the r-tree structure. A height of zero means all data is stored on @@ -909,6 +935,7 @@ static void rtreeReference(Rtree *pRtree){ static void rtreeRelease(Rtree *pRtree){ pRtree->nBusy--; if( pRtree->nBusy==0 ){ + nodeBlobReset(pRtree); sqlite3_finalize(pRtree->pReadNode); sqlite3_finalize(pRtree->pWriteNode); sqlite3_finalize(pRtree->pDeleteNode); @@ -947,6 +974,7 @@ static int rtreeDestroy(sqlite3_vtab *pVtab){ if( !zCreate ){ rc = SQLITE_NOMEM; }else{ + nodeBlobReset(pRtree); rc = sqlite3_exec(pRtree->db, zCreate, 0, 0, 0); sqlite3_free(zCreate); } @@ -3152,6 +3180,27 @@ constraint: return rc; } +/* +** Called when a transaction starts. +** This is a no-op. But the Virtual Table mechanism needs a method +** here or else it will never call the xRollback and xCommit methods, +** and those methods are necessary for clearing the sqlite3_blob object. +*/ +static int rtreeBeginTransaction(sqlite3_vtab *pVtab){ + (void)pVtab; + return SQLITE_OK; +} + +/* +** Called when a transaction completes (either by COMMIT or ROLLBACK). +** The sqlite3_blob object should be released at this point. +*/ +static int rtreeEndTransaction(sqlite3_vtab *pVtab){ + Rtree *pRtree = (Rtree *)pVtab; + nodeBlobReset(pRtree); + return SQLITE_OK; +} + /* ** The xRename method for rtree module virtual tables. */ @@ -3173,6 +3222,7 @@ static int rtreeRename(sqlite3_vtab *pVtab, const char *zNewName){ return rc; } + /* ** This function populates the pRtree->nRowEst variable with an estimate ** of the number of rows in the virtual table. If possible, this is based @@ -3232,15 +3282,15 @@ static sqlite3_module rtreeModule = { rtreeColumn, /* xColumn - read data */ rtreeRowid, /* xRowid - read data */ rtreeUpdate, /* xUpdate - write data */ - 0, /* xBegin - begin transaction */ + rtreeBeginTransaction, /* xBegin - begin transaction */ 0, /* xSync - sync transaction */ - 0, /* xCommit - commit transaction */ - 0, /* xRollback - rollback transaction */ + rtreeEndTransaction, /* xCommit - commit transaction */ + rtreeEndTransaction, /* xRollback - rollback transaction */ 0, /* xFindFunction - function overloading */ rtreeRename, /* xRename - rename the table */ 0, /* xSavepoint */ 0, /* xRelease */ - 0 /* xRollbackTo */ + 0, /* xRollbackTo */ }; static int rtreeSqlInit( @@ -3440,7 +3490,7 @@ static int rtreeInit( pRtree->zDb = (char *)&pRtree[1]; pRtree->zName = &pRtree->zDb[nDb+1]; pRtree->nDim = (u8)((argc-4)/2); - pRtree->nDim2 = argc - 4; + pRtree->nDim2 = pRtree->nDim*2; pRtree->nBytesPerCell = 8 + pRtree->nDim2*4; pRtree->eCoordType = (u8)eCoordType; memcpy(pRtree->zDb, argv[1], nDb); diff --git a/manifest b/manifest index 4cc36f422d..65dc3b7b4d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C This\sis\san\sexperimental\spatch\sthat\sensures\sthat\sall\scursors\shave\stheir\sposition\nsaved\sprior\sto\sstarting\sa\sROLLBACK\sTO. -D 2017-02-02T00:46:55.000 +C Use\sthe\ssqlite3_blob\sinterface\sfor\sreading\svalues\sfrom\sthe\s%_node\sshadow\ntable\sin\sRTREE.\s\sThis\sis\sa\swork\sin\sprogress.\s\sThere\sare\sstill\ssome\sminor\nproblems. +D 2017-02-02T02:28:45.543 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc ba953c8921fc7e18333f61898007206de7e23964 @@ -264,7 +264,7 @@ F ext/rbu/sqlite3rbu.c bb0de6cdbdb14a7d55a097238a434b7e99caf318 F ext/rbu/sqlite3rbu.h 6fb6294c34a9ca93b5894a33bca530c6f08decba F ext/rbu/test_rbu.c 5aa22616afac6f71ebd3d9bc9bf1006cfabcca88 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 -F ext/rtree/rtree.c 70f2488eef5c04dccf15a52cbd4961492124f825 +F ext/rtree/rtree.c 73c4308585c47a7500b9e98617e45a62f8564ddb F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e F ext/rtree/rtree1.test 42dadfc7b44a436cd74a1bebc0b9b689e4eaf7ec F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba @@ -1552,10 +1552,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 0c66cf0f0a9ada2ddcb8d61001ef791b86226416 -R 329580c21139f900f64001f6acfc9557 -T *branch * savepoint-rollback -T *sym-savepoint-rollback * -T -sym-trunk * +P 01d97e5b6502b1811b52a681f445e1aaae6c0ee6 +R 79c2c34c9473af6d4e0161547969b398 +T *branch * rtree-sqlite3_blob +T *sym-rtree-sqlite3_blob * +T -sym-savepoint-rollback * U drh -Z 5087946e64391fb6ac59f69d722efdd6 +Z fc394298cc4191cf41d9c752fa550c9c diff --git a/manifest.uuid b/manifest.uuid index 9d5ad1c981..099f46fdff 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -01d97e5b6502b1811b52a681f445e1aaae6c0ee6 \ No newline at end of file +fc4917d730b29b0bf60fea5e0166728635783e9c \ No newline at end of file From 2033d1c8ca2698a874709b87c04caba559985985 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 2 Feb 2017 14:40:06 +0000 Subject: [PATCH 1284/1484] Change RTREE so that the sqlite3_blob object is closed whenever the cursor count drops to zero and there is not a pending write transaction. FossilOrigin-Name: 9bb4eafe1a60176ed2e731bb7e3067c0b8a46615 --- ext/rtree/rtree.c | 26 +++++++++++++++++++------- ext/rtree/rtreeA.test | 2 +- manifest | 17 +++++++---------- manifest.uuid | 2 +- 4 files changed, 28 insertions(+), 19 deletions(-) diff --git a/ext/rtree/rtree.c b/ext/rtree/rtree.c index eae9ef819a..92ddcf526e 100644 --- a/ext/rtree/rtree.c +++ b/ext/rtree/rtree.c @@ -119,11 +119,13 @@ struct Rtree { u8 nDim2; /* Twice the number of dimensions */ u8 eCoordType; /* RTREE_COORD_REAL32 or RTREE_COORD_INT32 */ u8 nBytesPerCell; /* Bytes consumed per cell */ + u8 inWrTrans; /* True if inside write transaction */ int iDepth; /* Current depth of the r-tree structure */ char *zDb; /* Name of database containing r-tree table */ char *zName; /* Name of r-tree table */ - int nBusy; /* Current number of users of this structure */ + u32 nBusy; /* Current number of users of this structure */ i64 nRowEst; /* Estimated number of rows in this table */ + u32 nCursor; /* Number of open cursors */ /* List of nodes removed during a CondenseTree operation. List is ** linked together via the pointer normally used for hash chains - @@ -622,7 +624,7 @@ static RtreeNode *nodeNew(Rtree *pRtree, RtreeNode *pParent){ ** Clear the Rtree.pNodeBlob object */ static void nodeBlobReset(Rtree *pRtree){ - if( pRtree->pNodeBlob ){ + if( pRtree->pNodeBlob && pRtree->inWrTrans==0 && pRtree->nCursor==0 ){ sqlite3_blob_close(pRtree->pNodeBlob); pRtree->pNodeBlob = 0; } @@ -661,7 +663,7 @@ static int nodeAcquire( pRtree->pNodeBlob = pBlob; if( rc ){ nodeBlobReset(pRtree); - if( rc==SQLITE_NOMEM ) return rc; + if( rc==SQLITE_NOMEM ) return SQLITE_NOMEM; } } if( pRtree->pNodeBlob==0 ){ @@ -674,6 +676,9 @@ static int nodeAcquire( if( rc ){ nodeBlobReset(pRtree); *ppNode = 0; + /* If unable to open an sqlite3_blob on the desired row, that can only + ** be because the shadow tables hold erroneous data. */ + if( rc==SQLITE_ERROR ) rc = SQLITE_CORRUPT_VTAB; }else if( pRtree->iNodeSize==sqlite3_blob_bytes(pRtree->pNodeBlob) ){ pNode = (RtreeNode *)sqlite3_malloc(sizeof(RtreeNode)+pRtree->iNodeSize); if( !pNode ){ @@ -935,6 +940,8 @@ static void rtreeReference(Rtree *pRtree){ static void rtreeRelease(Rtree *pRtree){ pRtree->nBusy--; if( pRtree->nBusy==0 ){ + pRtree->inWrTrans = 0; + pRtree->nCursor = 0; nodeBlobReset(pRtree); sqlite3_finalize(pRtree->pReadNode); sqlite3_finalize(pRtree->pWriteNode); @@ -990,6 +997,7 @@ static int rtreeDestroy(sqlite3_vtab *pVtab){ */ static int rtreeOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){ int rc = SQLITE_NOMEM; + Rtree *pRtree = (Rtree *)pVTab; RtreeCursor *pCsr; pCsr = (RtreeCursor *)sqlite3_malloc(sizeof(RtreeCursor)); @@ -997,6 +1005,7 @@ static int rtreeOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){ memset(pCsr, 0, sizeof(RtreeCursor)); pCsr->base.pVtab = pVTab; rc = SQLITE_OK; + pRtree->nCursor++; } *ppCursor = (sqlite3_vtab_cursor *)pCsr; @@ -1029,10 +1038,13 @@ static int rtreeClose(sqlite3_vtab_cursor *cur){ Rtree *pRtree = (Rtree *)(cur->pVtab); int ii; RtreeCursor *pCsr = (RtreeCursor *)cur; + assert( pRtree->nCursor>0 ); freeCursorConstraints(pCsr); sqlite3_free(pCsr->aPoint); for(ii=0; iiaNode[ii]); sqlite3_free(pCsr); + pRtree->nCursor--; + nodeBlobReset(pRtree); return SQLITE_OK; } @@ -3182,12 +3194,11 @@ constraint: /* ** Called when a transaction starts. -** This is a no-op. But the Virtual Table mechanism needs a method -** here or else it will never call the xRollback and xCommit methods, -** and those methods are necessary for clearing the sqlite3_blob object. */ static int rtreeBeginTransaction(sqlite3_vtab *pVtab){ - (void)pVtab; + Rtree *pRtree = (Rtree *)pVtab; + assert( pRtree->inWrTrans==0 ); + pRtree->inWrTrans++; return SQLITE_OK; } @@ -3197,6 +3208,7 @@ static int rtreeBeginTransaction(sqlite3_vtab *pVtab){ */ static int rtreeEndTransaction(sqlite3_vtab *pVtab){ Rtree *pRtree = (Rtree *)pVtab; + pRtree->inWrTrans = 0; nodeBlobReset(pRtree); return SQLITE_OK; } diff --git a/ext/rtree/rtreeA.test b/ext/rtree/rtreeA.test index e377b013c1..84644e9ede 100644 --- a/ext/rtree/rtreeA.test +++ b/ext/rtree/rtreeA.test @@ -109,7 +109,7 @@ do_corruption_tests rtreeA-1.1 { } do_execsql_test rtreeA-1.2.0 { DROP TABLE t1_node } {} -do_corruption_tests rtreeA-1.2 -error "SQL logic error or missing database" { +do_corruption_tests rtreeA-1.2 -error "database disk image is malformed" { 1 "SELECT * FROM t1" 2 "SELECT * FROM t1 WHERE rowid=5" 3 "INSERT INTO t1 VALUES(1000, 1, 2, 3, 4)" diff --git a/manifest b/manifest index 65dc3b7b4d..5b06a60ca8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Use\sthe\ssqlite3_blob\sinterface\sfor\sreading\svalues\sfrom\sthe\s%_node\sshadow\ntable\sin\sRTREE.\s\sThis\sis\sa\swork\sin\sprogress.\s\sThere\sare\sstill\ssome\sminor\nproblems. -D 2017-02-02T02:28:45.543 +C Change\sRTREE\sso\sthat\sthe\ssqlite3_blob\sobject\sis\sclosed\swhenever\sthe\scursor\ncount\sdrops\sto\szero\sand\sthere\sis\snot\sa\spending\swrite\stransaction. +D 2017-02-02T14:40:06.876 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc ba953c8921fc7e18333f61898007206de7e23964 @@ -264,7 +264,7 @@ F ext/rbu/sqlite3rbu.c bb0de6cdbdb14a7d55a097238a434b7e99caf318 F ext/rbu/sqlite3rbu.h 6fb6294c34a9ca93b5894a33bca530c6f08decba F ext/rbu/test_rbu.c 5aa22616afac6f71ebd3d9bc9bf1006cfabcca88 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 -F ext/rtree/rtree.c 73c4308585c47a7500b9e98617e45a62f8564ddb +F ext/rtree/rtree.c df33d86df608a16516a95c6d184a5ed9988d2bc9 F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e F ext/rtree/rtree1.test 42dadfc7b44a436cd74a1bebc0b9b689e4eaf7ec F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba @@ -275,7 +275,7 @@ F ext/rtree/rtree6.test 773a90db2dce6a8353dd0d5b64bca69b29761196 F ext/rtree/rtree7.test 1fa710b9e6bf997a0c1a537b81be7bb6fded1971 F ext/rtree/rtree8.test db79c812f9e4a11f9b1f3f9934007884610a713a F ext/rtree/rtree9.test b5eb13849545dfd271a54ff16784cb00d8792aea -F ext/rtree/rtreeA.test ace05e729a36e342d40cf94e9efc7b4723d9dcdf +F ext/rtree/rtreeA.test ac8b503931f2f397cc3c3303354e1e085dcadb86 F ext/rtree/rtreeB.test c85f9ce78766c4e68b8b89fbf2979ee9cfa82b4e F ext/rtree/rtreeC.test c0a9c67f2efa98b6fae12acb8a28348d231a481d F ext/rtree/rtreeD.test bdfaaf26df8b4eea7364039aca9150bc1e1f8825 @@ -1552,10 +1552,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 01d97e5b6502b1811b52a681f445e1aaae6c0ee6 -R 79c2c34c9473af6d4e0161547969b398 -T *branch * rtree-sqlite3_blob -T *sym-rtree-sqlite3_blob * -T -sym-savepoint-rollback * +P fc4917d730b29b0bf60fea5e0166728635783e9c +R 0b53bd94b2e2abfad755fb806046ae11 U drh -Z fc394298cc4191cf41d9c752fa550c9c +Z 9c59d9d407f6159f87ae8b113cdc33c2 diff --git a/manifest.uuid b/manifest.uuid index 099f46fdff..0b51f62de3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fc4917d730b29b0bf60fea5e0166728635783e9c \ No newline at end of file +9bb4eafe1a60176ed2e731bb7e3067c0b8a46615 \ No newline at end of file From 413e207e316ae584dd2218905ab02522cc8e5a33 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 2 Feb 2017 15:35:54 +0000 Subject: [PATCH 1285/1484] The sqlite3_blob_close() interface can cause recursive invocations of nodeBlobReset() in RTREE. Make sure that does not cause problems. FossilOrigin-Name: 88333441cbf26bfde2acebf2a3f75b5ebbdfb0ae --- ext/rtree/rtree.c | 3 ++- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/ext/rtree/rtree.c b/ext/rtree/rtree.c index 92ddcf526e..c5998d2548 100644 --- a/ext/rtree/rtree.c +++ b/ext/rtree/rtree.c @@ -625,8 +625,9 @@ static RtreeNode *nodeNew(Rtree *pRtree, RtreeNode *pParent){ */ static void nodeBlobReset(Rtree *pRtree){ if( pRtree->pNodeBlob && pRtree->inWrTrans==0 && pRtree->nCursor==0 ){ - sqlite3_blob_close(pRtree->pNodeBlob); + sqlite3_blob *pBlob = pRtree->pNodeBlob; pRtree->pNodeBlob = 0; + sqlite3_blob_close(pBlob); } } diff --git a/manifest b/manifest index 5b06a60ca8..f8a355c0e7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sRTREE\sso\sthat\sthe\ssqlite3_blob\sobject\sis\sclosed\swhenever\sthe\scursor\ncount\sdrops\sto\szero\sand\sthere\sis\snot\sa\spending\swrite\stransaction. -D 2017-02-02T14:40:06.876 +C The\ssqlite3_blob_close()\sinterface\scan\scause\srecursive\sinvocations\sof\nnodeBlobReset()\sin\sRTREE.\s\sMake\ssure\sthat\sdoes\snot\scause\sproblems. +D 2017-02-02T15:35:54.700 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc ba953c8921fc7e18333f61898007206de7e23964 @@ -264,7 +264,7 @@ F ext/rbu/sqlite3rbu.c bb0de6cdbdb14a7d55a097238a434b7e99caf318 F ext/rbu/sqlite3rbu.h 6fb6294c34a9ca93b5894a33bca530c6f08decba F ext/rbu/test_rbu.c 5aa22616afac6f71ebd3d9bc9bf1006cfabcca88 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 -F ext/rtree/rtree.c df33d86df608a16516a95c6d184a5ed9988d2bc9 +F ext/rtree/rtree.c 93fd417d6f566caa49a548c915a27125a1b405c3 F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e F ext/rtree/rtree1.test 42dadfc7b44a436cd74a1bebc0b9b689e4eaf7ec F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba @@ -1552,7 +1552,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P fc4917d730b29b0bf60fea5e0166728635783e9c -R 0b53bd94b2e2abfad755fb806046ae11 +P 9bb4eafe1a60176ed2e731bb7e3067c0b8a46615 +R 6cebe0517919da4320850125e35977ce U drh -Z 9c59d9d407f6159f87ae8b113cdc33c2 +Z 7ae516135e0fc0897102b9fc210a106c diff --git a/manifest.uuid b/manifest.uuid index 0b51f62de3..ee09db23cc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9bb4eafe1a60176ed2e731bb7e3067c0b8a46615 \ No newline at end of file +88333441cbf26bfde2acebf2a3f75b5ebbdfb0ae \ No newline at end of file From ce655a236773fafcd3ce751b23cd217a96e5467b Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 2 Feb 2017 16:08:27 +0000 Subject: [PATCH 1286/1484] Fix a potential uninitialized (though harmless) variable in RTREE. FossilOrigin-Name: a1c74e09d63aca630d022ed074866433eed6b493 --- ext/rtree/rtree.c | 6 +++--- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/ext/rtree/rtree.c b/ext/rtree/rtree.c index c5998d2548..432c72781e 100644 --- a/ext/rtree/rtree.c +++ b/ext/rtree/rtree.c @@ -1118,7 +1118,6 @@ static int rtreeCallbackConstraint( sqlite3_rtree_dbl *prScore, /* OUT: score for the cell */ int *peWithin /* OUT: visibility of the cell */ ){ - int i; /* Loop counter */ sqlite3_rtree_query_info *pInfo = pConstraint->pInfo; /* Callback info */ int nCoord = pInfo->nCoord; /* No. of coordinates */ int rc; /* Callback return code */ @@ -1163,9 +1162,10 @@ static int rtreeCallbackConstraint( } } if( pConstraint->op==RTREE_MATCH ){ + int eWithin = 0; rc = pConstraint->u.xGeom((sqlite3_rtree_geometry*)pInfo, - nCoord, aCoord, &i); - if( i==0 ) *peWithin = NOT_WITHIN; + nCoord, aCoord, &eWithin); + if( eWithin==0 ) *peWithin = NOT_WITHIN; *prScore = RTREE_ZERO; }else{ pInfo->aCoord = aCoord; diff --git a/manifest b/manifest index f8a355c0e7..0fcd596e1e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C The\ssqlite3_blob_close()\sinterface\scan\scause\srecursive\sinvocations\sof\nnodeBlobReset()\sin\sRTREE.\s\sMake\ssure\sthat\sdoes\snot\scause\sproblems. -D 2017-02-02T15:35:54.700 +C Fix\sa\spotential\suninitialized\s(though\sharmless)\svariable\sin\sRTREE. +D 2017-02-02T16:08:27.041 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc ba953c8921fc7e18333f61898007206de7e23964 @@ -264,7 +264,7 @@ F ext/rbu/sqlite3rbu.c bb0de6cdbdb14a7d55a097238a434b7e99caf318 F ext/rbu/sqlite3rbu.h 6fb6294c34a9ca93b5894a33bca530c6f08decba F ext/rbu/test_rbu.c 5aa22616afac6f71ebd3d9bc9bf1006cfabcca88 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 -F ext/rtree/rtree.c 93fd417d6f566caa49a548c915a27125a1b405c3 +F ext/rtree/rtree.c e1b77d0f32241f3c09ab0bc7cf7be5d263902978 F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e F ext/rtree/rtree1.test 42dadfc7b44a436cd74a1bebc0b9b689e4eaf7ec F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba @@ -1552,7 +1552,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 9bb4eafe1a60176ed2e731bb7e3067c0b8a46615 -R 6cebe0517919da4320850125e35977ce +P 88333441cbf26bfde2acebf2a3f75b5ebbdfb0ae +R 6c083917a4ecdc09328902e3d7d74ce0 U drh -Z 7ae516135e0fc0897102b9fc210a106c +Z 3e4bf024e32b2f321d57a48b2d7cd9ed diff --git a/manifest.uuid b/manifest.uuid index ee09db23cc..507bf4c42c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -88333441cbf26bfde2acebf2a3f75b5ebbdfb0ae \ No newline at end of file +a1c74e09d63aca630d022ed074866433eed6b493 \ No newline at end of file From 3accc7e1af59b89cc54df381ddf67dc96487103f Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 2 Feb 2017 16:30:25 +0000 Subject: [PATCH 1287/1484] Remove the unused pReadNode prepared statement from each RTREE object. FossilOrigin-Name: e51dc0ec60d45cd57564735b6b2bb254a588533e --- ext/rtree/rtree.c | 24 ++++++++++-------------- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 17 insertions(+), 21 deletions(-) diff --git a/ext/rtree/rtree.c b/ext/rtree/rtree.c index 432c72781e..9e6f0e082a 100644 --- a/ext/rtree/rtree.c +++ b/ext/rtree/rtree.c @@ -139,7 +139,6 @@ struct Rtree { sqlite3_blob *pNodeBlob; /* Statements to read/write/delete a record from xxx_node */ - sqlite3_stmt *pReadNode; sqlite3_stmt *pWriteNode; sqlite3_stmt *pDeleteNode; @@ -944,7 +943,6 @@ static void rtreeRelease(Rtree *pRtree){ pRtree->inWrTrans = 0; pRtree->nCursor = 0; nodeBlobReset(pRtree); - sqlite3_finalize(pRtree->pReadNode); sqlite3_finalize(pRtree->pWriteNode); sqlite3_finalize(pRtree->pDeleteNode); sqlite3_finalize(pRtree->pReadRowid); @@ -3315,10 +3313,9 @@ static int rtreeSqlInit( ){ int rc = SQLITE_OK; - #define N_STATEMENT 9 + #define N_STATEMENT 8 static const char *azSql[N_STATEMENT] = { - /* Read and write the xxx_node table */ - "SELECT data FROM '%q'.'%q_node' WHERE nodeno = :1", + /* Write the xxx_node table */ "INSERT OR REPLACE INTO '%q'.'%q_node' VALUES(:1, :2)", "DELETE FROM '%q'.'%q_node' WHERE nodeno = :1", @@ -3356,15 +3353,14 @@ static int rtreeSqlInit( } } - appStmt[0] = &pRtree->pReadNode; - appStmt[1] = &pRtree->pWriteNode; - appStmt[2] = &pRtree->pDeleteNode; - appStmt[3] = &pRtree->pReadRowid; - appStmt[4] = &pRtree->pWriteRowid; - appStmt[5] = &pRtree->pDeleteRowid; - appStmt[6] = &pRtree->pReadParent; - appStmt[7] = &pRtree->pWriteParent; - appStmt[8] = &pRtree->pDeleteParent; + appStmt[0] = &pRtree->pWriteNode; + appStmt[1] = &pRtree->pDeleteNode; + appStmt[2] = &pRtree->pReadRowid; + appStmt[3] = &pRtree->pWriteRowid; + appStmt[4] = &pRtree->pDeleteRowid; + appStmt[5] = &pRtree->pReadParent; + appStmt[6] = &pRtree->pWriteParent; + appStmt[7] = &pRtree->pDeleteParent; rc = rtreeQueryStat1(db, pRtree); for(i=0; i Date: Thu, 2 Feb 2017 19:24:05 +0000 Subject: [PATCH 1288/1484] Fix issues in the sha1 extension seen with MSVC. FossilOrigin-Name: 5a0da77c22ebc7db5e63b1520d30f3ad97b9bb3b --- ext/misc/sha1.c | 42 +++++++++++++++++++++++++----------------- manifest | 13 ++++++------- manifest.uuid | 2 +- 3 files changed, 32 insertions(+), 25 deletions(-) diff --git a/ext/misc/sha1.c b/ext/misc/sha1.c index dbf15a95ef..e2843bdefa 100644 --- a/ext/misc/sha1.c +++ b/ext/misc/sha1.c @@ -87,12 +87,6 @@ struct SHA1Context { /* * Hash a single 512-bit block. This is the core of the algorithm. */ -#define a qq[0] -#define b qq[1] -#define c qq[2] -#define d qq[3] -#define e qq[4] - void SHA1Transform(unsigned int state[5], const unsigned char buffer[64]){ unsigned int qq[5]; /* a, b, c, d, e; */ static int one = 1; @@ -100,6 +94,12 @@ void SHA1Transform(unsigned int state[5], const unsigned char buffer[64]){ memcpy(block, buffer, 64); memcpy(qq,state,5*sizeof(unsigned int)); +#define a qq[0] +#define b qq[1] +#define c qq[2] +#define d qq[3] +#define e qq[4] + /* Copy p->state[] to working vars */ /* a = state[0]; @@ -144,6 +144,12 @@ void SHA1Transform(unsigned int state[5], const unsigned char buffer[64]){ state[2] += c; state[3] += d; state[4] += e; + +#undef a +#undef b +#undef c +#undef d +#undef e } @@ -253,6 +259,7 @@ static void sha1Func( int nByte = sqlite3_value_bytes(argv[0]); char zOut[44]; + assert( argc==1 ); if( eType==SQLITE_NULL ) return; hash_init(&cx); if( eType==SQLITE_BLOB ){ @@ -292,6 +299,7 @@ static void sha1QueryFunc( SHA1Context cx; char zOut[44]; + assert( argc==1 ); if( zSql==0 ) return; hash_init(&cx); while( zSql[0] ){ @@ -343,7 +351,7 @@ static void sha1QueryFunc( case SQLITE_FLOAT: { sqlite3_uint64 u; int j; - unsigned char x[8]; + unsigned char x[9]; double r = sqlite3_column_double(pStmt,i); memcpy(&u, &r, 8); for(j=8; j>=1; j--){ @@ -355,17 +363,17 @@ static void sha1QueryFunc( break; } case SQLITE_TEXT: { - int n = sqlite3_column_bytes(pStmt, i); - const unsigned char *z = sqlite3_column_text(pStmt, i); - hash_step_vformat(&cx,"T%d:",n); - hash_step(&cx, z, n); + int n2 = sqlite3_column_bytes(pStmt, i); + const unsigned char *z2 = sqlite3_column_text(pStmt, i); + hash_step_vformat(&cx,"T%d:",n2); + hash_step(&cx, z2, n2); break; } case SQLITE_BLOB: { - int n = sqlite3_column_bytes(pStmt, i); - const unsigned char *z = sqlite3_column_blob(pStmt, i); - hash_step_vformat(&cx,"B%d:",n); - hash_step(&cx, z, n); + int n2 = sqlite3_column_bytes(pStmt, i); + const unsigned char *z2 = sqlite3_column_blob(pStmt, i); + hash_step_vformat(&cx,"B%d:",n2); + hash_step(&cx, z2, n2); break; } } @@ -382,8 +390,8 @@ static void sha1QueryFunc( __declspec(dllexport) #endif int sqlite3_sha_init( - sqlite3 *db, - char **pzErrMsg, + sqlite3 *db, + char **pzErrMsg, const sqlite3_api_routines *pApi ){ int rc = SQLITE_OK; diff --git a/manifest b/manifest index 6459c8e5ad..9d4630c832 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\scompiler\swarnings\sseen\swith\sMSVC. -D 2017-02-01T23:06:17.747 +C Fix\sissues\sin\sthe\ssha1\sextension\sseen\swith\sMSVC. +D 2017-02-02T19:24:05.672 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc ba953c8921fc7e18333f61898007206de7e23964 @@ -222,7 +222,7 @@ F ext/misc/remember.c 8440f8d0b452c5cdefb62b57135ccd1267aa729d F ext/misc/rot13.c 1ac6f95f99b575907b9b09c81a349114cf9be45a F ext/misc/scrub.c 1c5bfb8b0cd18b602fcb55755e84abf0023ac2fb F ext/misc/series.c e11e534ada797d5b816d7e7a93c022306563ca35 -F ext/misc/sha1.c b2e4eb8e26f09701ec15548395baf698f00e5895 +F ext/misc/sha1.c 0b9e9b855354910d3ca467bf39099d570e73db56 F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52 F ext/misc/spellfix.c a4723b6aff748a417b5091b68a46443265c40f0d F ext/misc/totype.c 4a167594e791abeed95e0a8db028822b5e8fe512 @@ -1552,8 +1552,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P aaae74d06f4865818465cfdb440258ae8a5b985a 997f765bc6706769ae15f3e719354473e02bd78b -R 939bce209d57b72db3d58f9894d61374 -T +closed 997f765bc6706769ae15f3e719354473e02bd78b +P 0c66cf0f0a9ada2ddcb8d61001ef791b86226416 +R 531254e92dc453ecbaf40de729caeadd U mistachkin -Z c2a7081e9858115a573bd4695718af54 +Z 7da98715c0c2c155a034ba4275d6d8fe diff --git a/manifest.uuid b/manifest.uuid index 0e34341685..9e12c1be98 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0c66cf0f0a9ada2ddcb8d61001ef791b86226416 \ No newline at end of file +5a0da77c22ebc7db5e63b1520d30f3ad97b9bb3b \ No newline at end of file From a7466205ca7f5663605b48375ade5f7389d915a5 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 3 Feb 2017 14:44:52 +0000 Subject: [PATCH 1289/1484] Modify the sqlite3SelectDup() routine to avoid recursing on Select.pPrior. FossilOrigin-Name: a7674ead5be986c66f7d61d598adc7e5728bcd30 --- manifest | 18 +++++++++------- manifest.uuid | 2 +- src/expr.c | 60 +++++++++++++++++++++++++++++---------------------- 3 files changed, 45 insertions(+), 35 deletions(-) diff --git a/manifest b/manifest index a07bc6f332..24ce068e9c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Ensure\sthat\sall\scursors\shave\stheir\spositions\ssaved\sprior\sto\srolling\sback\na\ssavepoint. -D 2017-02-02T20:32:28.731 +C Modify\sthe\ssqlite3SelectDup()\sroutine\sto\savoid\srecursing\son\sSelect.pPrior. +D 2017-02-03T14:44:52.406 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc ba953c8921fc7e18333f61898007206de7e23964 @@ -346,7 +346,7 @@ F src/ctime.c 9f2296a4e5d26ebf0e0d95a0af4628f1ea694e7a F src/date.c dc3f1391d9297f8c748132813aaffcb117090d6e F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c 0d9d5549d42e79ce4d82ff1db1e6c81e36d2f67c -F src/expr.c d7ef6fdb70bc18259d7d36b22aa0bc4845c5c5b9 +F src/expr.c d29114e9b709eaeaaa18553a5bbe60a19302aeef F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 2e9aabe1aee76273aff8a84ee92c464e095400ae F src/func.c c67273e1ec08abbdcc14c189892a3ff6eeece86b @@ -1552,8 +1552,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 5a0da77c22ebc7db5e63b1520d30f3ad97b9bb3b 01d97e5b6502b1811b52a681f445e1aaae6c0ee6 -R f67fbd165c607c8ab8b9fb8cff6e4d0d -T +closed 01d97e5b6502b1811b52a681f445e1aaae6c0ee6 -U drh -Z d16d6898d272ff11e9984476ae1d9ef3 +P 8e03a8e95fada5c24d369672a71f6e02288051da +R c80f7dbbf5f0044354e4b463e716c13e +T *branch * recursive-selectdup +T *sym-recursive-selectdup * +T -sym-trunk * +U dan +Z f43da81961eb4c39992192293f7e5a2c diff --git a/manifest.uuid b/manifest.uuid index 792cc0b3a3..a72c232e1b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8e03a8e95fada5c24d369672a71f6e02288051da \ No newline at end of file +a7674ead5be986c66f7d61d598adc7e5728bcd30 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 18035bd421..f1e8667b39 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1418,33 +1418,41 @@ IdList *sqlite3IdListDup(sqlite3 *db, IdList *p){ } return pNew; } -Select *sqlite3SelectDup(sqlite3 *db, Select *p, int flags){ - Select *pNew, *pPrior; +Select *sqlite3SelectDup(sqlite3 *db, Select *pDup, int flags){ + Select *pRet = 0; + Select *pNext = 0; + Select **pp = &pRet; + Select *p; + assert( db!=0 ); - if( p==0 ) return 0; - pNew = sqlite3DbMallocRawNN(db, sizeof(*p) ); - if( pNew==0 ) return 0; - pNew->pEList = sqlite3ExprListDup(db, p->pEList, flags); - pNew->pSrc = sqlite3SrcListDup(db, p->pSrc, flags); - pNew->pWhere = sqlite3ExprDup(db, p->pWhere, flags); - pNew->pGroupBy = sqlite3ExprListDup(db, p->pGroupBy, flags); - pNew->pHaving = sqlite3ExprDup(db, p->pHaving, flags); - pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy, flags); - pNew->op = p->op; - pNew->pPrior = pPrior = sqlite3SelectDup(db, p->pPrior, flags); - if( pPrior ) pPrior->pNext = pNew; - pNew->pNext = 0; - pNew->pLimit = sqlite3ExprDup(db, p->pLimit, flags); - pNew->pOffset = sqlite3ExprDup(db, p->pOffset, flags); - pNew->iLimit = 0; - pNew->iOffset = 0; - pNew->selFlags = p->selFlags & ~SF_UsesEphemeral; - pNew->addrOpenEphm[0] = -1; - pNew->addrOpenEphm[1] = -1; - pNew->nSelectRow = p->nSelectRow; - pNew->pWith = withDup(db, p->pWith); - sqlite3SelectSetName(pNew, p->zSelName); - return pNew; + for(p=pDup; p; p=p->pPrior){ + Select *pNew = sqlite3DbMallocRawNN(db, sizeof(*p) ); + if( pNew==0 ) break; + pNew->pEList = sqlite3ExprListDup(db, p->pEList, flags); + pNew->pSrc = sqlite3SrcListDup(db, p->pSrc, flags); + pNew->pWhere = sqlite3ExprDup(db, p->pWhere, flags); + pNew->pGroupBy = sqlite3ExprListDup(db, p->pGroupBy, flags); + pNew->pHaving = sqlite3ExprDup(db, p->pHaving, flags); + pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy, flags); + pNew->op = p->op; + pNew->pNext = pNext; + pNew->pPrior = 0; + pNew->pLimit = sqlite3ExprDup(db, p->pLimit, flags); + pNew->pOffset = sqlite3ExprDup(db, p->pOffset, flags); + pNew->iLimit = 0; + pNew->iOffset = 0; + pNew->selFlags = p->selFlags & ~SF_UsesEphemeral; + pNew->addrOpenEphm[0] = -1; + pNew->addrOpenEphm[1] = -1; + pNew->nSelectRow = p->nSelectRow; + pNew->pWith = withDup(db, p->pWith); + sqlite3SelectSetName(pNew, p->zSelName); + *pp = pNew; + pp = &pNew->pPrior; + pNext = pNew; + } + + return pRet; } #else Select *sqlite3SelectDup(sqlite3 *db, Select *p, int flags){ From 59a40db3d2b5cbec56aa12cd0eee403a95c70933 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 3 Feb 2017 15:16:25 +0000 Subject: [PATCH 1290/1484] Improved tests for the carray() table-valued function. FossilOrigin-Name: 83a099f139aba03edac19c890a0019e922032a25 --- manifest | 13 ++++++------- manifest.uuid | 2 +- test/tabfunc01.test | 40 ++++++++++++++++++++++++---------------- 3 files changed, 31 insertions(+), 24 deletions(-) diff --git a/manifest b/manifest index a07bc6f332..b4fd3e2062 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Ensure\sthat\sall\scursors\shave\stheir\spositions\ssaved\sprior\sto\srolling\sback\na\ssavepoint. -D 2017-02-02T20:32:28.731 +C Improved\stests\sfor\sthe\scarray()\stable-valued\sfunction. +D 2017-02-03T15:16:25.769 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc ba953c8921fc7e18333f61898007206de7e23964 @@ -1155,7 +1155,7 @@ F test/symlink.test c9ebe7330d228249e447038276bfc8a7b22f4849 F test/sync.test 2f84bdbc2b2df1fcb0220575b4b9f8cea94b7529 F test/syscall.test f59ba4e25f7ba4a4c031026cc2ef8b6e4b4c639c F test/sysfault.test c9f2b0d8d677558f74de750c75e12a5454719d04 -F test/tabfunc01.test 8b2ef53caa37854864c89e1e57e8a10efd4f5e43 +F test/tabfunc01.test 699251cb99651415218a891384510a685c7ab012 F test/table.test b708f3e5fa2542fa51dfab21fc07b36ea445cb2f F test/tableapi.test 2674633fa95d80da917571ebdd759a14d9819126 F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930 @@ -1552,8 +1552,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 5a0da77c22ebc7db5e63b1520d30f3ad97b9bb3b 01d97e5b6502b1811b52a681f445e1aaae6c0ee6 -R f67fbd165c607c8ab8b9fb8cff6e4d0d -T +closed 01d97e5b6502b1811b52a681f445e1aaae6c0ee6 +P 8e03a8e95fada5c24d369672a71f6e02288051da +R 408679a2eb27f8712868946a0e8b1f65 U drh -Z d16d6898d272ff11e9984476ae1d9ef3 +Z 773cdc68fe82e971a45f4eb8ed248cd4 diff --git a/manifest.uuid b/manifest.uuid index 792cc0b3a3..14c0befdff 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8e03a8e95fada5c24d369672a71f6e02288051da \ No newline at end of file +83a099f139aba03edac19c890a0019e922032a25 \ No newline at end of file diff --git a/test/tabfunc01.test b/test/tabfunc01.test index f25d070847..dcaafa420c 100644 --- a/test/tabfunc01.test +++ b/test/tabfunc01.test @@ -148,60 +148,68 @@ do_execsql_test tabfunc01-600 { do_test tabfunc01-700 { - set PTR [intarray_addr 5 7 13 17 23] + set PTR1 [intarray_addr 5 7 13 17 23] db eval { - SELECT b FROM t600, carray($PTR,5) WHERE a=value; + SELECT b FROM t600, carray($PTR1,5) WHERE a=value; } } {(005) (007) (013) (017) (023)} do_test tabfunc01-701 { db eval { - SELECT b FROM t600 WHERE a IN carray($PTR,5,'int32'); + SELECT b FROM t600 WHERE a IN carray($PTR1,5,'int32'); } } {(005) (007) (013) (017) (023)} do_test tabfunc01-702 { db eval { - SELECT b FROM t600 WHERE a IN carray($PTR,4,'int32'); + SELECT b FROM t600 WHERE a IN carray($PTR1,4,'int32'); } } {(005) (007) (013) (017)} do_catchsql_test tabfunc01-710 { - SELECT b FROM t600 WHERE a IN carray($PTR,5,'int33'); + SELECT b FROM t600 WHERE a IN carray($PTR1,5,'int33'); } {1 {unknown datatype: 'int33'}} do_test tabfunc01-720 { - set PTR [int64array_addr 5 7 13 17 23] + set PTR2 [int64array_addr 5 7 13 17 23] db eval { - SELECT b FROM t600, carray($PTR,5,'int64') WHERE a=value; + SELECT b FROM t600, carray($PTR2,5,'int64') WHERE a=value; } } {(005) (007) (013) (017) (023)} do_test tabfunc01-721 { db eval { - SELECT remember(123,$PTR); - SELECT value FROM carray($PTR,5,'int64'); + SELECT remember(123,$PTR2); + SELECT value FROM carray($PTR2,5,'int64'); } } {123 123 7 13 17 23} do_test tabfunc01-722 { - set PTR2 [expr {$PTR+16}] + set PTR3 [expr {$PTR2+16}] db eval { - SELECT remember(987,$PTR2); - SELECT value FROM carray($PTR,5,'int64'); + SELECT remember(987,$PTR3); + SELECT value FROM carray($PTR2,5,'int64'); } } {987 123 7 987 17 23} do_test tabfunc01-730 { - set PTR [doublearray_addr 5.0 7.0 13.0 17.0 23.0] + set PTR4 [doublearray_addr 5.0 7.0 13.0 17.0 23.0] db eval { - SELECT b FROM t600, carray($PTR,5,'double') WHERE a=value; + SELECT b FROM t600, carray($PTR4,5,'double') WHERE a=value; } } {(005) (007) (013) (017) (023)} do_test tabfunc01-740 { - set PTR [textarray_addr 5 7 13 17 23] + set PTR5 [textarray_addr x5 x7 x13 x17 x23] db eval { - SELECT b FROM t600, carray($PTR,5,'char*') WHERE a=value; + SELECT b FROM t600, carray($PTR5,5,'char*') WHERE a=trim(value,'x'); } } {(005) (007) (013) (017) (023)} +do_test tabfunc01-750 { + db eval { + SELECT aa.value, bb.value, '|' + FROM carray($PTR4,5,'double') AS aa + JOIN carray($PTR5,5,'char*') AS bb ON aa.rowid=bb.rowid; + } +} {5.0 x5 | 7.0 x7 | 13.0 x13 | 17.0 x17 | 23.0 x23 |} +# Free up memory allocations intarray_addr int64array_addr doublearray_addr From 067cd837fbe3014b8876dc4f752babcef0ce5506 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 3 Feb 2017 19:16:39 +0000 Subject: [PATCH 1291/1484] Avoid a performance problem when very large "VALUES(..), (..), (..)" terms are used in queries. FossilOrigin-Name: f5306ad6816cc377036685cdae227e762885229c --- manifest | 15 ++++++--------- manifest.uuid | 2 +- src/select.c | 28 ++++++++++++++++++---------- 3 files changed, 25 insertions(+), 20 deletions(-) diff --git a/manifest b/manifest index 24ce068e9c..9a2d78f7e1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Modify\sthe\ssqlite3SelectDup()\sroutine\sto\savoid\srecursing\son\sSelect.pPrior. -D 2017-02-03T14:44:52.406 +C Avoid\sa\sperformance\sproblem\swhen\svery\slarge\s"VALUES(..),\s(..),\s(..)"\sterms\sare\nused\sin\squeries. +D 2017-02-03T19:16:39.919 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc ba953c8921fc7e18333f61898007206de7e23964 @@ -393,7 +393,7 @@ F src/printf.c ff10a9b9902cd2afe5f655f3013c6307d969b1fd F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c f9bc0de45a30a450da47b3766de00be89bf9be79 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac -F src/select.c 3856db523b942062bca8722ba03b61c324ff94d6 +F src/select.c d12f3539f80db38b09015561b569e0eb1c4b6c5f F src/shell.c a84e453c213f3e0d6935a582024da4e242f85a19 F src/sqlite.h.in 751ff125eb159c8f92c182b8df980a5e4f50e966 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1552,10 +1552,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 8e03a8e95fada5c24d369672a71f6e02288051da -R c80f7dbbf5f0044354e4b463e716c13e -T *branch * recursive-selectdup -T *sym-recursive-selectdup * -T -sym-trunk * +P a7674ead5be986c66f7d61d598adc7e5728bcd30 +R 1275850dbdc882ce3db2a9a335b19414 U dan -Z f43da81961eb4c39992192293f7e5a2c +Z aab63e41186ee170ee1c431b74360517 diff --git a/manifest.uuid b/manifest.uuid index a72c232e1b..c0409900d6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a7674ead5be986c66f7d61d598adc7e5728bcd30 \ No newline at end of file +f5306ad6816cc377036685cdae227e762885229c \ No newline at end of file diff --git a/src/select.c b/src/select.c index ed6221309f..d817ebd074 100644 --- a/src/select.c +++ b/src/select.c @@ -4186,7 +4186,15 @@ static int withExpand( pCte->zCteErr = "circular reference: %s"; pSavedWith = pParse->pWith; pParse->pWith = pWith; - sqlite3WalkSelect(pWalker, bMayRecursive ? pSel->pPrior : pSel); + if( bMayRecursive ){ + Select *pPrior = pSel->pPrior; + assert( pPrior->pWith==0 ); + pPrior->pWith = pSel->pWith; + sqlite3WalkSelect(pWalker, pPrior); + pPrior->pWith = 0; + }else{ + sqlite3WalkSelect(pWalker, pSel); + } pParse->pWith = pWith; for(pLeft=pSel; pLeft->pPrior; pLeft=pLeft->pPrior); @@ -4230,10 +4238,12 @@ static int withExpand( */ static void selectPopWith(Walker *pWalker, Select *p){ Parse *pParse = pWalker->pParse; - With *pWith = findRightmost(p)->pWith; - if( pWith!=0 ){ - assert( pParse->pWith==pWith ); - pParse->pWith = pWith->pOuter; + if( pParse->pWith && p->pPrior==0 ){ + With *pWith = findRightmost(p)->pWith; + if( pWith!=0 ){ + assert( pParse->pWith==pWith ); + pParse->pWith = pWith->pOuter; + } } } #else @@ -4283,8 +4293,8 @@ static int selectExpander(Walker *pWalker, Select *p){ } pTabList = p->pSrc; pEList = p->pEList; - if( pWalker->xSelectCallback2==selectPopWith ){ - sqlite3WithPush(pParse, findRightmost(p)->pWith, 0); + if( p->pWith ){ + sqlite3WithPush(pParse, p->pWith, 0); } /* Make sure cursor numbers have been assigned to all entries in @@ -4571,9 +4581,7 @@ static void sqlite3SelectExpand(Parse *pParse, Select *pSelect){ sqlite3WalkSelect(&w, pSelect); } w.xSelectCallback = selectExpander; - if( (pSelect->selFlags & SF_MultiValue)==0 ){ - w.xSelectCallback2 = selectPopWith; - } + w.xSelectCallback2 = selectPopWith; sqlite3WalkSelect(&w, pSelect); } From 010e312f8fd5f0e73ed83740c3778f3a4e354b35 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 4 Feb 2017 13:12:12 +0000 Subject: [PATCH 1292/1484] Close sqlite3_blob objects on xSync rather than waiting until xCommit. FossilOrigin-Name: 95ee745fceb4a48c683f34c404c380fe5e7d684a --- ext/rtree/rtree.c | 2 +- manifest | 15 +++++++++------ manifest.uuid | 2 +- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/ext/rtree/rtree.c b/ext/rtree/rtree.c index 9e6f0e082a..c46bce7d37 100644 --- a/ext/rtree/rtree.c +++ b/ext/rtree/rtree.c @@ -3294,7 +3294,7 @@ static sqlite3_module rtreeModule = { rtreeRowid, /* xRowid - read data */ rtreeUpdate, /* xUpdate - write data */ rtreeBeginTransaction, /* xBegin - begin transaction */ - 0, /* xSync - sync transaction */ + rtreeEndTransaction, /* xSync - sync transaction */ rtreeEndTransaction, /* xCommit - commit transaction */ rtreeEndTransaction, /* xRollback - rollback transaction */ 0, /* xFindFunction - function overloading */ diff --git a/manifest b/manifest index ea1bf5a3bf..e59dba6295 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sthe\sunused\spReadNode\sprepared\sstatement\sfrom\seach\sRTREE\sobject. -D 2017-02-02T16:30:25.555 +C Close\ssqlite3_blob\sobjects\son\sxSync\srather\sthan\swaiting\suntil\sxCommit. +D 2017-02-04T13:12:12.865 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc ba953c8921fc7e18333f61898007206de7e23964 @@ -264,7 +264,7 @@ F ext/rbu/sqlite3rbu.c bb0de6cdbdb14a7d55a097238a434b7e99caf318 F ext/rbu/sqlite3rbu.h 6fb6294c34a9ca93b5894a33bca530c6f08decba F ext/rbu/test_rbu.c 5aa22616afac6f71ebd3d9bc9bf1006cfabcca88 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 -F ext/rtree/rtree.c be9d44f5707c5a73887d3ac3ad14a355e9b92b58 +F ext/rtree/rtree.c ed39c157eab89ce014675f07601f2813c9f54e9c F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e F ext/rtree/rtree1.test 42dadfc7b44a436cd74a1bebc0b9b689e4eaf7ec F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba @@ -1552,7 +1552,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a1c74e09d63aca630d022ed074866433eed6b493 -R b4b0a5df6a2ab40920c13363cd1d25e9 +P e51dc0ec60d45cd57564735b6b2bb254a588533e +R a16debe67e7399020e94d725cd2d4af7 +T *branch * rtree-blob-agressive-release +T *sym-rtree-blob-agressive-release * +T -sym-rtree-sqlite3_blob * U drh -Z 5406bbb7ccb82072da8c73ecd9c87865 +Z a61d538b0d9c1a9c54d88c1f71c254d7 diff --git a/manifest.uuid b/manifest.uuid index dda662b8b9..be149e116e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e51dc0ec60d45cd57564735b6b2bb254a588533e \ No newline at end of file +95ee745fceb4a48c683f34c404c380fe5e7d684a \ No newline at end of file From ff677b20fc34a4fd7b4c0ab3c499ec355d631ad2 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 4 Feb 2017 17:33:30 +0000 Subject: [PATCH 1293/1484] Allow sqlite3session_apply() to apply changesets to tables that have been extended using ALTER TABLE ADD COLUMN. FossilOrigin-Name: b20ff81ff9c8af500ea96e0ba9d34524220a89f1 --- ext/session/session3.test | 5 +- ext/session/session_common.tcl | 13 +- ext/session/sessionat.test | 216 +++++++++++++++++++++++++++++++++ ext/session/sqlite3session.c | 39 ++++-- ext/session/sqlite3session.h | 25 ++-- manifest | 24 ++-- manifest.uuid | 2 +- test/tester.tcl | 31 ++++- 8 files changed, 312 insertions(+), 43 deletions(-) create mode 100644 ext/session/sessionat.test diff --git a/ext/session/session3.test b/ext/session/session3.test index e15407c2eb..ba316348ef 100644 --- a/ext/session/session3.test +++ b/ext/session/session3.test @@ -63,7 +63,10 @@ do_test 1.2.1 { INSERT INTO t1 VALUES(7, 8); } set ::log -} {SQLITE_SCHEMA {sqlite3changeset_apply(): table t1 has 3 columns, expected 2}} +} {} +do_test 1.2.2 { + db2 eval { SELECT * FROM t1 } +} {5 6 {} 7 8 {}} do_test 1.3.0 { execsql { diff --git a/ext/session/session_common.tcl b/ext/session/session_common.tcl index 06b05509b1..d4804d924f 100644 --- a/ext/session/session_common.tcl +++ b/ext/session/session_common.tcl @@ -33,16 +33,11 @@ proc do_changeset_invert_test {tn session res} { proc do_conflict_test {tn args} { - proc xConflict {args} { - lappend ::xConflict $args - return "" - } - proc bgerror {args} { set ::background_error $args } - set O(-tables) [list] set O(-sql) [list] set O(-conflicts) [list] + set O(-policy) "OMIT" array set V $args foreach key [array names V] { @@ -50,6 +45,12 @@ proc do_conflict_test {tn args} { } array set O $args + proc xConflict {args} [subst -nocommands { + lappend ::xConflict [set args] + return $O(-policy) + }] + proc bgerror {args} { set ::background_error $args } + sqlite3session S db main foreach t $O(-tables) { S attach $t } execsql $O(-sql) diff --git a/ext/session/sessionat.test b/ext/session/sessionat.test new file mode 100644 index 0000000000..a96cbcae42 --- /dev/null +++ b/ext/session/sessionat.test @@ -0,0 +1,216 @@ +# 2017 February 04 +# +# 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. +# +#*********************************************************************** +# +# Tests for the sessions module. Specifically, that a changeset can +# be applied after ALTER TABLE ADD COLUMN has been used to add +# columns to tables. +# + +if {![info exists testdir]} { + set testdir [file join [file dirname [info script]] .. .. test] +} +source [file join [file dirname [info script]] session_common.tcl] +source $testdir/tester.tcl +ifcapable !session {finish_test; return} + +set testprefix sessionat + +db close +sqlite3_shutdown +test_sqlite3_log log +proc log {code msg} { lappend ::log $code $msg } + +proc reset_test {} { + catch { db close } + catch { db2 close } + forcedelete test.db test.db2 + sqlite3 db test.db + sqlite3 db2 test.db2 +} + + +# Run all tests in this file twice. Once with "WITHOUT ROWID", and once +# with regular rowid tables. +# +# ?.1.*: Test that PK inconsistencies are detected if one or more of the PK +# columns are not present in the changeset. +# +# ?.2.*: Test that it is not possible to apply a changeset with N columns +# to a db with fewer than N columns. +# +# ?.3.*: Test some INSERT, UPDATE and DELETE operations that do not +# require conflict handling. +# +# ?.4.*: Test some INSERT, UPDATE and DELETE operations that do require +# conflict handling. +# +# ?.5.*: Test that attempting to concat two changesets with different +# numbers of columns for the same table is an error. +# +foreach {tn trailing} { + sessionat-ipk "" + sessionat-wor " WITHOUT ROWID " +} { +eval [string map [list %WR% $trailing] { + reset_test + + #----------------------------------------------------------------------- + do_execsql_test $tn.1.0 { + CREATE TABLE t1(a, b, PRIMARY KEY(a)) %WR%; + } + do_execsql_test -db db2 $tn.1.1 { + CREATE TABLE t1(a, b, c, PRIMARY KEY(a, c)) %WR%; + } + do_test $tn.1.2 { + set ::log {} + do_then_apply_sql { INSERT INTO t1 VALUES('one', 'two') } + set ::log + } [list \ + SQLITE_SCHEMA {sqlite3changeset_apply(): primary key mismatch for table t1} + ] + do_execsql_test $tn.1.3 { SELECT * FROM t1 } {one two} + do_execsql_test -db db2 $tn.1.4 { SELECT * FROM t1 } {} + + #----------------------------------------------------------------------- + do_execsql_test $tn.2.0 { + CREATE TABLE t2(x, y, z, PRIMARY KEY(x)) %WR%; + } + do_execsql_test -db db2 $tn.2.1 { + CREATE TABLE t2(x, y, PRIMARY KEY(x)) %WR%; + } + do_test $tn.2.2 { + db cache flush + set ::log {} + do_then_apply_sql { INSERT INTO t2 VALUES(1, 2, 3) } + set ::log + } [list SQLITE_SCHEMA \ + {sqlite3changeset_apply(): table t2 has 2 columns, expected 3 or more} + ] + do_execsql_test $tn.2.3 { SELECT * FROM t2 } {1 2 3} + do_execsql_test -db db2 $tn.2.4 { SELECT * FROM t2 } {} + + #----------------------------------------------------------------------- + do_execsql_test $tn.3.0 { + CREATE TABLE t3(a, b, PRIMARY KEY(b)) %WR%; + } + do_execsql_test -db db2 $tn.3.1 { + CREATE TABLE t3(a, b, c DEFAULT 'D', PRIMARY KEY(b)) %WR%; + } + do_test $tn.3.2 { + do_then_apply_sql { + INSERT INTO t3 VALUES(1, 2); + INSERT INTO t3 VALUES(3, 4); + INSERT INTO t3 VALUES(5, 6); + }; + db2 eval {SELECT * FROM t3} + } {1 2 D 3 4 D 5 6 D} + do_test $tn.3.3 { + do_then_apply_sql { + UPDATE t3 SET a=45 WHERE b=4; + DELETE FROM t3 WHERE a=5; + }; + db2 eval {SELECT * FROM t3} + } {1 2 D 45 4 D} + + #----------------------------------------------------------------------- + # 4.1: INSERT statements + # 4.2: DELETE statements + # 4.3: UPDATE statements + # + do_execsql_test $tn.4.1.0 { + CREATE TABLE t4(x INTEGER PRIMARY KEY, y) %WR%; + } + do_execsql_test -db db2 $tn.4.1.1 { + CREATE TABLE t4(x INTEGER PRIMARY KEY, y, z) %WR%; + INSERT INTO t4 VALUES(1, 2, 3); + INSERT INTO t4 VALUES(4, 5, 6); + } + do_conflict_test $tn.4.1.2 -tables t4 -sql { + INSERT INTO t4 VALUES(10, 20); + INSERT INTO t4 VALUES(4, 11); + } -conflicts { + {INSERT t4 CONFLICT {i 4 i 11} {i 4 i 5}} + } + do_execsql_test -db db2 $tn.4.1.3 { + SELECT * FROM t4 ORDER BY x + } {1 2 3 4 5 6 10 20 {}} + do_conflict_test $tn.4.1.4 -policy REPLACE -tables t4 -sql { + INSERT INTO t4 VALUES(1, 11); + } -conflicts { + {INSERT t4 CONFLICT {i 1 i 11} {i 1 i 2}} + } + do_execsql_test -db db2 $tn.4.1.5 { + SELECT * FROM t4 ORDER BY x + } {1 11 {} 4 5 6 10 20 {}} + + do_execsql_test $tn.4.2.0 { + DELETE FROM t4; + INSERT INTO t4 VALUES(1, 'A'); + INSERT INTO t4 VALUES(2, 'B'); + INSERT INTO t4 VALUES(3, 'C'); + INSERT INTO t4 VALUES(4, 'D'); + } + do_execsql_test -db db2 $tn.4.2.1 { + DELETE FROM t4; + INSERT INTO t4 VALUES(1, 'A', 'a'); + INSERT INTO t4 VALUES(3, 'C', 'c'); + INSERT INTO t4 VALUES(4, 'E', 'd'); + } + do_conflict_test $tn.4.2.2 -tables t4 -sql { + DELETE FROM t4 WHERE x=2; + DELETE FROM t4 WHERE x=4; + } -conflicts { + {DELETE t4 NOTFOUND {i 2 t B}} + {DELETE t4 DATA {i 4 t D} {i 4 t E}} + } + + do_execsql_test $tn.4.3.0 { + CREATE TABLE t5(a, b, c PRIMARY KEY) %WR%; + INSERT INTO t5 VALUES(1,1,1), (2,2,2), (3,3,3), (4,4,4); + } + do_execsql_test -db db2 $tn.4.3.1 { + CREATE TABLE t5(a, b, c PRIMARY KEY, d CHECK(b!=10)) %WR%; + INSERT INTO t5 VALUES (2,2,2,2), (3,8,3,3), (4,4,4,4); + } + do_conflict_test $tn.4.3.2 -tables t5 -sql { + UPDATE t5 SET a=4 WHERE c=1; + UPDATE t5 SET b=9 WHERE c=3; + UPDATE t5 SET b=10 WHERE c=2; + } -conflicts { + {UPDATE t5 NOTFOUND {i 1 {} {} i 1} {i 4 {} {} {} {}}} + {UPDATE t5 DATA {{} {} i 3 i 3} {{} {} i 9 {} {}} {i 3 i 8 i 3}} + {UPDATE t5 CONSTRAINT {{} {} i 2 i 2} {{} {} i 10 {} {}}} + } + + #----------------------------------------------------------------------- + do_execsql_test $tn.5.0 { + CREATE TABLE t6(a, b, c, PRIMARY KEY(a, b)) %WR%; + } + do_execsql_test -db db2 $tn.5.1 { + CREATE TABLE t6(a, b, c, d, e, PRIMARY KEY(a, b)) %WR%; + } + do_test $tn.5.2 { + set c1 [sql_exec_changeset db { + INSERT INTO t6 VALUES(1, 1, 1); + INSERT INTO t6 VALUES(2, 2, 2); + }] + set c2 [sql_exec_changeset db2 { + INSERT INTO t6 VALUES(3, 3, 3, 3, 3); + INSERT INTO t6 VALUES(4, 4, 4, 4, 4); + }] + list [catch { sqlite3changeset_concat $c1 $c2} msg] $msg + } {1 SQLITE_SCHEMA} + +}] +} + + +finish_test diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index 50793df0a0..8dde8501a3 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -3028,7 +3028,7 @@ int sqlite3changeset_conflict( if( !pIter->pConflict ){ return SQLITE_MISUSE; } - if( iVal<0 || iVal>=sqlite3_column_count(pIter->pConflict) ){ + if( iVal<0 || iVal>=pIter->nCol ){ return SQLITE_RANGE; } *ppValue = sqlite3_column_value(pIter->pConflict, iVal); @@ -3495,7 +3495,13 @@ static int sessionInsertRow( sessionAppendStr(&buf, "INSERT INTO main.", &rc); sessionAppendIdent(&buf, zTab, &rc); - sessionAppendStr(&buf, " VALUES(?", &rc); + sessionAppendStr(&buf, "(", &rc); + for(i=0; inCol; i++){ + if( i!=0 ) sessionAppendStr(&buf, ", ", &rc); + sessionAppendIdent(&buf, p->azCol[i], &rc); + } + + sessionAppendStr(&buf, ") VALUES(?", &rc); for(i=1; inCol; i++){ sessionAppendStr(&buf, ", ?", &rc); } @@ -4041,11 +4047,17 @@ static int sessionChangesetApply( nTab = (int)strlen(zTab); sApply.azCol = (const char **)zTab; }else{ + int nMinCol = 0; + int i; + sqlite3changeset_pk(pIter, &abPK, 0); rc = sessionTableInfo( db, "main", zNew, &sApply.nCol, &zTab, &sApply.azCol, &sApply.abPK ); if( rc!=SQLITE_OK ) break; + for(i=0; i For each row (primary key) that exists in both tables, but features -** different in each, an UPDATE record is added to the session. +** different non-PK values in each, an UPDATE record is added to the +** session. ** ** ** To clarify, if this function is called and then a changeset constructed @@ -904,7 +905,7 @@ void sqlite3changegroup_delete(sqlite3_changegroup*); **
      **
    • The table has the same name as the name recorded in the ** changeset, and -**
    • The table has the same number of columns as recorded in the +**
    • The table has at least as many columns as recorded in the ** changeset, and **
    • The table has primary key columns in the same position as ** recorded in the changeset. @@ -949,7 +950,11 @@ void sqlite3changegroup_delete(sqlite3_changegroup*); ** If a row with matching primary key values is found, but one or more of ** the non-primary key fields contains a value different from the original ** row value stored in the changeset, the conflict-handler function is -** invoked with [SQLITE_CHANGESET_DATA] as the second argument. +** invoked with [SQLITE_CHANGESET_DATA] as the second argument. If the +** database table has more columns than are recorded in the changeset, +** only the values of those non-primary key fields are compared against +** the current database contents - any trailing database table columns +** are ignored. ** ** If no row with matching primary key values is found in the database, ** the conflict-handler function is invoked with [SQLITE_CHANGESET_NOTFOUND] @@ -964,7 +969,9 @@ void sqlite3changegroup_delete(sqlite3_changegroup*); ** **
      INSERT Changes
      ** For each INSERT change, an attempt is made to insert the new row into -** the database. +** the database. If the changeset row contains fewer fields than the +** database table, the trailing fields are populated with their default +** values. ** ** If the attempt to insert the row fails because the database already ** contains a row with the same primary key values, the conflict handler @@ -982,13 +989,13 @@ void sqlite3changegroup_delete(sqlite3_changegroup*); ** For each UPDATE change, this function checks if the target database ** contains a row with the same primary key value (or values) as the ** original row values stored in the changeset. If it does, and the values -** stored in all non-primary key columns also match the values stored in -** the changeset the row is updated within the target database. +** stored in all modified non-primary key columns also match the values +** stored in the changeset the row is updated within the target database. ** ** If a row with matching primary key values is found, but one or more of -** the non-primary key fields contains a value different from an original -** row value stored in the changeset, the conflict-handler function is -** invoked with [SQLITE_CHANGESET_DATA] as the second argument. Since +** the modified non-primary key fields contains a value different from an +** original row value stored in the changeset, the conflict-handler function +** is invoked with [SQLITE_CHANGESET_DATA] as the second argument. Since ** UPDATE changes only contain values for non-primary key fields that are ** to be modified, only those fields need to match the original values to ** avoid the SQLITE_CHANGESET_DATA conflict-handler callback. diff --git a/manifest b/manifest index 1e02448111..0c44921e62 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\sRTREE,\suse\san\ssqlite3_blob\sobject\srather\sthan\san\ssqlite3_stmt\sobject\nfor\sreading\scontent\sout\sof\sthe\s%_node\sshadow\stable. -D 2017-02-04T14:24:05.401 +C Allow\ssqlite3session_apply()\sto\sapply\schangesets\sto\stables\sthat\shave\sbeen\nextended\susing\sALTER\sTABLE\sADD\sCOLUMN. +D 2017-02-04T17:33:30.792 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc ba953c8921fc7e18333f61898007206de7e23964 @@ -290,7 +290,7 @@ F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 F ext/session/changeset.c 4ccbaa4531944c24584bf6a61ba3a39c62b6267a F ext/session/session1.test c8a50e0e8581dc1a00e832aa59bb61f180404d44 F ext/session/session2.test 284de45abae4cc1082bc52012ee81521d5ac58e0 -F ext/session/session3.test a7a9ce59b8d1e49e2cc23d81421ac485be0eea01 +F ext/session/session3.test ce9ce3dfa489473987f899e9f6a0f2db9bde3479 F ext/session/session4.test 457b02bdc349eb01151e54de014df77abd3c08c8 F ext/session/session5.test 716bc6fafd625ce60dfa62ae128971628c1a1169 F ext/session/session6.test 443789bc2fca12e4f7075cf692c60b8a2bea1a26 @@ -303,13 +303,14 @@ F ext/session/sessionD.test d4744c78334162851d2a2f285c7e603e31b49aa2 F ext/session/sessionE.test e60a238c47f0feb3bb707e7f35e22be09c7e8f26 F ext/session/sessionF.test c2f178d4dfd723a5fd94a730ea2ccb44c669e3ce F ext/session/sessionG.test 01ef705096a9d3984eebdcca79807a211dee1b60 -F ext/session/session_common.tcl 9b696a341cf1d3744823715ed92bb19749b6c3d4 +F ext/session/session_common.tcl 7776eda579773113b30c7abfd4545c445228cb73 F ext/session/session_speed_test.c edc1f96fd5e0e4b16eb03e2a73041013d59e8723 +F ext/session/sessionat.test b25d61d663ebc795506bf74079dc4ba0092fad25 F ext/session/sessionfault.test da273f2712b6411e85e71465a1733b8501dbf6f7 F ext/session/sessionfault2.test 04aa0bc9aa70ea43d8de82c4f648db4de1e990b0 F ext/session/sessionwor.test 2f3744236dc8b170a695b7d8ddc8c743c7e79fdc -F ext/session/sqlite3session.c c61a43396368ec00dc127f7bc647e9bd6a4ee5fb -F ext/session/sqlite3session.h 9345166bd8f80562145586cf817f707de5ecada2 +F ext/session/sqlite3session.c 13642d9c754cc18f17e141f82860d269e2adf920 +F ext/session/sqlite3session.h d4db650adfcc7a4360e9f12a09c2d117b1db6b53 F ext/session/test_session.c eb0bd6c1ea791c1d66ee4ef94c16500dad936386 F ext/userauth/sqlite3userauth.h 19cb6f0e31316d0ee4afdfb7a85ef9da3333a220 F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04 @@ -1167,7 +1168,7 @@ F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30 F test/temptable2.test cd396beb41117a5302fff61767c35fa4270a0d5e F test/temptable3.test d11a0974e52b347e45ee54ef1923c91ed91e4637 F test/temptrigger.test 38f0ca479b1822d3117069e014daabcaacefffcc -F test/tester.tcl 2a49c1aff731f380ea640106377e19611a1443ae +F test/tester.tcl 67835ac17e90055f24a9cf52e5c5bce0dd511c74 F test/thread001.test 9f22fd3525a307ff42a326b6bc7b0465be1745a5 F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58 F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7 @@ -1552,8 +1553,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 5706d4708a30eb54da0ecbb6eb02f54746c390d9 95ee745fceb4a48c683f34c404c380fe5e7d684a -R ad6ed02dcc60e4bca51c672c64ac9b20 -T +closed 95ee745fceb4a48c683f34c404c380fe5e7d684a -U drh -Z c59d505acee8b5f741c72c39e5c6cdac +P 97ccf3e4de11ffea46993cb7fb7ab559b9810705 +R cad52333a5be0dfe0e9c0b2fb42ed068 +U dan +Z 4713f44978189d862833bfda87ecea6f diff --git a/manifest.uuid b/manifest.uuid index 99286a49a0..ffbedec871 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -97ccf3e4de11ffea46993cb7fb7ab559b9810705 \ No newline at end of file +b20ff81ff9c8af500ea96e0ba9d34524220a89f1 \ No newline at end of file diff --git a/test/tester.tcl b/test/tester.tcl index 8cc501a182..1da89fec26 100644 --- a/test/tester.tcl +++ b/test/tester.tcl @@ -919,10 +919,37 @@ proc normalize_list {L} { set L2 } -proc do_execsql_test {testname sql {result {}}} { +# Either: +# +# do_execsql_test TESTNAME SQL ?RES? +# do_execsql_test -db DB TESTNAME SQL ?RES? +# +proc do_execsql_test {args} { + set db db + if {[lindex $args 0]=="-db"} { + set db [lindex $args 1] + set args [lrange $args 2 end] + } + + if {[llength $args]==2} { + foreach {testname sql} $args {} + set result "" + } elseif {[llength $args]==3} { + foreach {testname sql result} $args {} + } else { + error [string trim { + wrong # args: should be "do_execsql_test ?-db DB? testname sql ?result?" + }] + } + fix_testname testname - uplevel do_test [list $testname] [list "execsql {$sql}"] [list [list {*}$result]] + + uplevel do_test \ + [list $testname] \ + [list "execsql {$sql} $db"] \ + [list [list {*}$result]] } + proc do_catchsql_test {testname sql result} { fix_testname testname uplevel do_test [list $testname] [list "catchsql {$sql}"] [list $result] From 238390c3b4f9e1ac568e268d716bfd5497d38e69 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 4 Feb 2017 20:15:51 +0000 Subject: [PATCH 1294/1484] Simplification to the error handling to extension loading in sqlite3_open(). FossilOrigin-Name: ec8ff892ac9c6a8f81bcf69f1933f4bb69faa743 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/main.c | 34 +++++++++++++++++----------------- 3 files changed, 25 insertions(+), 25 deletions(-) diff --git a/manifest b/manifest index 0c44921e62..3a187ee6a7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Allow\ssqlite3session_apply()\sto\sapply\schangesets\sto\stables\sthat\shave\sbeen\nextended\susing\sALTER\sTABLE\sADD\sCOLUMN. -D 2017-02-04T17:33:30.792 +C Simplification\sto\sthe\serror\shandling\sto\sextension\sloading\sin\s\nsqlite3_open(). +D 2017-02-04T20:15:51.171 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc ba953c8921fc7e18333f61898007206de7e23964 @@ -359,7 +359,7 @@ F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 F src/insert.c 444354c23d4d140a57d6eb46f34e376a7f8f62e8 F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e F src/loadext.c a68d8d1d14cf7488bb29dc5311cb1ce9a4404258 -F src/main.c e207b81542d13b9f13d61e78ca441f9781f055b0 +F src/main.c eb4f5034ede07e1777e3e31fb2059a0046f499af F src/malloc.c fc1b9f445290f2145da48fc08730c26e6082b640 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b @@ -1553,7 +1553,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 97ccf3e4de11ffea46993cb7fb7ab559b9810705 -R cad52333a5be0dfe0e9c0b2fb42ed068 -U dan -Z 4713f44978189d862833bfda87ecea6f +P b20ff81ff9c8af500ea96e0ba9d34524220a89f1 +R 001e21c81e4051080c5d23cc6f975774 +U drh +Z 5c4d22afe8177f7d6c2b43d525198743 diff --git a/manifest.uuid b/manifest.uuid index ffbedec871..77acfcf115 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b20ff81ff9c8af500ea96e0ba9d34524220a89f1 \ No newline at end of file +ec8ff892ac9c6a8f81bcf69f1933f4bb69faa743 \ No newline at end of file diff --git a/src/main.c b/src/main.c index 9aad8fdd4c..e771c8eb04 100644 --- a/src/main.c +++ b/src/main.c @@ -2989,13 +2989,13 @@ static int openDatabase( if( rc==SQLITE_OK ){ sqlite3AutoLoadExtensions(db); rc = sqlite3_errcode(db); - if( rc!=SQLITE_OK ){ - goto opendb_out; - } } + testcase( rc!=SQLITE_OK && rc!=SQLITE_NOMEM ); + testcase( rc!=SQLITE_OK && !db->mallocFailed ); + #ifdef SQLITE_ENABLE_FTS1 - if( !db->mallocFailed ){ + if( !db->mallocFailed && rc==SQLITE_OK ){ extern int sqlite3Fts1Init(sqlite3*); rc = sqlite3Fts1Init(db); } @@ -3038,23 +3038,23 @@ static int openDatabase( } #endif - /* -DSQLITE_DEFAULT_LOCKING_MODE=1 makes EXCLUSIVE the default locking - ** mode. -DSQLITE_DEFAULT_LOCKING_MODE=0 make NORMAL the default locking - ** mode. Doing nothing at all also makes NORMAL the default. - */ + if( rc==SQLITE_OK ){ + /* -DSQLITE_DEFAULT_LOCKING_MODE=1 makes EXCLUSIVE the default locking + ** mode. -DSQLITE_DEFAULT_LOCKING_MODE=0 make NORMAL the default locking + ** mode. Doing nothing at all also makes NORMAL the default. + */ #ifdef SQLITE_DEFAULT_LOCKING_MODE - db->dfltLockMode = SQLITE_DEFAULT_LOCKING_MODE; - sqlite3PagerLockingMode(sqlite3BtreePager(db->aDb[0].pBt), - SQLITE_DEFAULT_LOCKING_MODE); + db->dfltLockMode = SQLITE_DEFAULT_LOCKING_MODE; + sqlite3PagerLockingMode(sqlite3BtreePager(db->aDb[0].pBt), + SQLITE_DEFAULT_LOCKING_MODE); #endif - if( rc ) sqlite3Error(db, rc); + /* Enable the lookaside-malloc subsystem */ + setupLookaside(db, 0, sqlite3GlobalConfig.szLookaside, + sqlite3GlobalConfig.nLookaside); - /* Enable the lookaside-malloc subsystem */ - setupLookaside(db, 0, sqlite3GlobalConfig.szLookaside, - sqlite3GlobalConfig.nLookaside); - - sqlite3_wal_autocheckpoint(db, SQLITE_DEFAULT_WAL_AUTOCHECKPOINT); + sqlite3_wal_autocheckpoint(db, SQLITE_DEFAULT_WAL_AUTOCHECKPOINT); + } opendb_out: if( db ){ From 9630f3ba085cf4d3a4b9b198153470cf2fd8fea8 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 6 Feb 2017 01:19:07 +0000 Subject: [PATCH 1295/1484] Remove incorrect testcase() macros from R-Tree. FossilOrigin-Name: 853a58a75ecbd01ebbf7e07fbd8c4fc9bef54a99 --- ext/rtree/rtree.c | 5 ----- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 7 insertions(+), 12 deletions(-) diff --git a/ext/rtree/rtree.c b/ext/rtree/rtree.c index 5ea7824e2a..6399d225c2 100644 --- a/ext/rtree/rtree.c +++ b/ext/rtree/rtree.c @@ -456,21 +456,17 @@ static void readCoord(u8 *p, RtreeCoord *pCoord){ static i64 readInt64(u8 *p){ #if SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300 u64 x; - testcase( ((((char*)p) - (char*)0)&7)!=0 ); /* not always 8-byte aligned */ memcpy(&x, p, 8); return (i64)_byteswap_uint64(x); #elif SQLITE_BYTEORDER==1234 && (GCC_VERSION>=4003000 || CLANG_VERSION>=3000000) u64 x; - testcase( ((((char*)p) - (char*)0)&7)!=0 ); /* not always 8-byte aligned */ memcpy(&x, p, 8); return (i64)__builtin_bswap64(x); #elif SQLITE_BYTEORDER==4321 i64 x; - testcase( ((((char*)p) - (char*)0)&7)!=0 ); /* not always 8-byte aligned */ memcpy(&x, p, 8); return x; #else - testcase( ((((char*)p) - (char*)0)&7)!=0 ); /* not always 8-byte aligned */ return ( (((i64)p[0]) << 56) + (((i64)p[1]) << 48) + @@ -518,7 +514,6 @@ static int writeCoord(u8 *p, RtreeCoord *pCoord){ return 4; } static int writeInt64(u8 *p, i64 i){ - testcase( ((((char*)p) - (char*)0)&7)!=0 ); /* Not always 8-byte aligned */ #if SQLITE_BYTEORDER==1234 && (GCC_VERSION>=4003000 || CLANG_VERSION>=3000000) i = (i64)__builtin_bswap64((u64)i); memcpy(p, &i, 8); diff --git a/manifest b/manifest index 3a187ee6a7..fb8fafb97b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Simplification\sto\sthe\serror\shandling\sto\sextension\sloading\sin\s\nsqlite3_open(). -D 2017-02-04T20:15:51.171 +C Remove\sincorrect\stestcase()\smacros\sfrom\sR-Tree. +D 2017-02-06T01:19:07.230 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc ba953c8921fc7e18333f61898007206de7e23964 @@ -264,7 +264,7 @@ F ext/rbu/sqlite3rbu.c bb0de6cdbdb14a7d55a097238a434b7e99caf318 F ext/rbu/sqlite3rbu.h 6fb6294c34a9ca93b5894a33bca530c6f08decba F ext/rbu/test_rbu.c 5aa22616afac6f71ebd3d9bc9bf1006cfabcca88 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 -F ext/rtree/rtree.c 0c229d23ce7b9bc69365281689065f3cbbe4561e +F ext/rtree/rtree.c d40feeeee43736bb96fce8a73385ca721c207d4a F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e F ext/rtree/rtree1.test 42dadfc7b44a436cd74a1bebc0b9b689e4eaf7ec F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba @@ -1553,7 +1553,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b20ff81ff9c8af500ea96e0ba9d34524220a89f1 -R 001e21c81e4051080c5d23cc6f975774 +P ec8ff892ac9c6a8f81bcf69f1933f4bb69faa743 +R b0af6ea2fd6b4dd25607ca94e5b23382 U drh -Z 5c4d22afe8177f7d6c2b43d525198743 +Z 0dd488b4639ebd89796370a35153554a diff --git a/manifest.uuid b/manifest.uuid index 77acfcf115..7fef035644 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ec8ff892ac9c6a8f81bcf69f1933f4bb69faa743 \ No newline at end of file +853a58a75ecbd01ebbf7e07fbd8c4fc9bef54a99 \ No newline at end of file From 809955b504cbb41daa14152647b990cb36b0965b Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 6 Feb 2017 07:37:50 +0000 Subject: [PATCH 1296/1484] Fix a bug in kvtest causing "init --variance 0" runs to generate single byte blob values only. FossilOrigin-Name: 6b0276f968d3c6430076c6e540907cf840d0f398 --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/kvtest.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index fb8fafb97b..bd1b152de9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sincorrect\stestcase()\smacros\sfrom\sR-Tree. -D 2017-02-06T01:19:07.230 +C Fix\sa\sbug\sin\skvtest\scausing\s"init\s--variance\s0"\sruns\sto\sgenerate\ssingle\sbyte\nblob\svalues\sonly. +D 2017-02-06T07:37:50.092 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc ba953c8921fc7e18333f61898007206de7e23964 @@ -903,7 +903,7 @@ F test/json101.test c0897616f32d95431f37fd291cb78742181980ac F test/json102.test bf3fe7a706d30936a76a0f7a0375e1e8e73aff5a F test/json103.test c5f6b85e69de05f6b3195f9f9d5ce9cd179099a0 F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff -F test/kvtest.c 7a3c38ee56b9cc45dc5a5edc50fd9bc9425659a9 +F test/kvtest.c 156281b4ed688e9aabf1fbcdc5dec0487b267026 F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63 F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200 F test/like.test 0603f4fa0dad50987f70032c05800cbfa8985302 @@ -1553,7 +1553,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ec8ff892ac9c6a8f81bcf69f1933f4bb69faa743 -R b0af6ea2fd6b4dd25607ca94e5b23382 -U drh -Z 0dd488b4639ebd89796370a35153554a +P 853a58a75ecbd01ebbf7e07fbd8c4fc9bef54a99 +R 921673f8e8c6498440ee3e75a7e902ee +U dan +Z ce0aba82a1b0f2c7c9c23b4307d78840 diff --git a/manifest.uuid b/manifest.uuid index 7fef035644..91838993f7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -853a58a75ecbd01ebbf7e07fbd8c4fc9bef54a99 \ No newline at end of file +6b0276f968d3c6430076c6e540907cf840d0f398 \ No newline at end of file diff --git a/test/kvtest.c b/test/kvtest.c index 2a108aa470..77ee02a4ff 100644 --- a/test/kvtest.c +++ b/test/kvtest.c @@ -310,7 +310,7 @@ static int initMain(int argc, char **argv){ "WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<%d)" " INSERT INTO kv(k,v) SELECT x, randomblob(%d+(random()%%(%d))) FROM c;\n" "COMMIT;\n", - pgsz, nCount, sz, iVariance + pgsz, nCount, sz, iVariance+1 ); rc = sqlite3_exec(db, zSql, 0, 0, &zErrMsg); if( rc ) fatalError("database create failed: %s", zErrMsg); From 943aa77a8a68d7e6341d1189537d05e05f37afc0 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 6 Feb 2017 15:27:44 +0000 Subject: [PATCH 1297/1484] Add the "max-limits" utility program to the tools/ subdirectory. FossilOrigin-Name: c54173b6c1acbb41ed9c323099e94b8e02c6c895 --- manifest | 13 +++++++------ manifest.uuid | 2 +- tool/max-limits.c | 41 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 7 deletions(-) create mode 100644 tool/max-limits.c diff --git a/manifest b/manifest index bd1b152de9..ba5d6d8cf1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sbug\sin\skvtest\scausing\s"init\s--variance\s0"\sruns\sto\sgenerate\ssingle\sbyte\nblob\svalues\sonly. -D 2017-02-06T07:37:50.092 +C Add\sthe\s"max-limits"\sutility\sprogram\sto\sthe\stools/\ssubdirectory. +D 2017-02-06T15:27:44.567 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc ba953c8921fc7e18333f61898007206de7e23964 @@ -1485,6 +1485,7 @@ F tool/lempar.c db1bdb4821f2d8fbd76e577cf3ab18642c8d08d1 F tool/libvers.c caafc3b689638a1d88d44bc5f526c2278760d9b9 F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862 F tool/logest.c 11346aa019e2e77a00902aa7d0cabd27bd2e8cca +F tool/max-limits.c cbb635fbb37ae4d05f240bfb5b5270bb63c54439 F tool/mkautoconfamal.sh e855df211ecbcc7131dee817110ff386cfb112f7 F tool/mkkeywordhash.c f7f3b342211ac6a14258b9726d5b97cf4f548f22 F tool/mkmsvcmin.tcl 2f12f7fa8858bbe61cf81820a2da96c79ed1ca8d @@ -1553,7 +1554,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 853a58a75ecbd01ebbf7e07fbd8c4fc9bef54a99 -R 921673f8e8c6498440ee3e75a7e902ee -U dan -Z ce0aba82a1b0f2c7c9c23b4307d78840 +P 6b0276f968d3c6430076c6e540907cf840d0f398 +R f80944376543a94e77dae99832d50174 +U drh +Z ae78f6b03eb9477204e774bb8b71a31e diff --git a/manifest.uuid b/manifest.uuid index 91838993f7..c191fc2bb5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6b0276f968d3c6430076c6e540907cf840d0f398 \ No newline at end of file +c54173b6c1acbb41ed9c323099e94b8e02c6c895 \ No newline at end of file diff --git a/tool/max-limits.c b/tool/max-limits.c new file mode 100644 index 0000000000..d019974426 --- /dev/null +++ b/tool/max-limits.c @@ -0,0 +1,41 @@ +/* +** Link this program against an SQLite library of unknown provenance in order +** to display the compile-time maximum values for various settings. +*/ +#include "sqlite3.h" +#include + +static const struct { + int eCode; + char *zName; +} aLimit[] = { + { SQLITE_LIMIT_LENGTH, "SQLITE_MAX_LENGTH" }, + { SQLITE_LIMIT_SQL_LENGTH, "SQLITE_MAX_SQL_LENGTH" }, + { SQLITE_LIMIT_COLUMN, "SQLITE_MAX_COLUMN" }, + { SQLITE_LIMIT_EXPR_DEPTH, "SQLITE_MAX_EXPR_DEPTH" }, + { SQLITE_LIMIT_COMPOUND_SELECT, "SQLITE_MAX_COMPOUND_SELECT" }, + { SQLITE_LIMIT_VDBE_OP, "SQLITE_MAX_VDBE_OP" }, + { SQLITE_LIMIT_FUNCTION_ARG, "SQLITE_MAX_FUNCTION_ARG" }, + { SQLITE_LIMIT_ATTACHED, "SQLITE_MAX_ATTACHED" }, + { SQLITE_LIMIT_LIKE_PATTERN_LENGTH, "SQLITE_MAX_LIKE_PATTERN_LENGTH" }, + { SQLITE_LIMIT_VARIABLE_NUMBER, "SQLITE_MAX_VARIABLE_NUMBER" }, + { SQLITE_LIMIT_TRIGGER_DEPTH, "SQLITE_MAX_TRIGGER_DEPTH" }, + { SQLITE_LIMIT_WORKER_THREADS, "SQLITE_MAX_WORKER_THREADS" }, +}; + +static int maxLimit(sqlite3 *db, int eCode){ + int iOrig = sqlite3_limit(db, eCode, 0x7fffffff); + return sqlite3_limit(db, eCode, iOrig); +} + +int main(int argc, char **argv){ + sqlite3 *db; + int j, rc; + rc = sqlite3_open(":memory:", &db); + if( rc==SQLITE_OK ){ + for(j=0; j Date: Mon, 6 Feb 2017 16:52:32 +0000 Subject: [PATCH 1298/1484] Remove a small amount of unnecessary code from R-Tree. FossilOrigin-Name: e5aea894267addb4dc9b21de24a20417b0be508a --- ext/rtree/rtree.c | 18 ++---------------- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 23 deletions(-) diff --git a/ext/rtree/rtree.c b/ext/rtree/rtree.c index 6399d225c2..4d77be827f 100644 --- a/ext/rtree/rtree.c +++ b/ext/rtree/rtree.c @@ -1611,7 +1611,6 @@ static int rtreeColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){ if( i==0 ){ sqlite3_result_int64(ctx, nodeGetRowid(pRtree, pNode, p->iCell)); }else{ - if( rc ) return rc; nodeGetCoord(pRtree, pNode, p->iCell, i-1, &c); #ifndef SQLITE_RTREE_INT_ONLY if( pRtree->eCoordType==RTREE_COORD_REAL32 ){ @@ -1806,19 +1805,6 @@ static int rtreeFilter( return rc; } -/* -** Set the pIdxInfo->estimatedRows variable to nRow. Unless this -** extension is currently being used by a version of SQLite too old to -** support estimatedRows. In that case this function is a no-op. -*/ -static void setEstimatedRows(sqlite3_index_info *pIdxInfo, i64 nRow){ -#if SQLITE_VERSION_NUMBER>=3008002 - if( sqlite3_libversion_number()>=3008002 ){ - pIdxInfo->estimatedRows = nRow; - } -#endif -} - /* ** Rtree virtual table module xBestIndex method. There are three ** table scan strategies to choose from (in order from most to @@ -1898,7 +1884,7 @@ static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ ** a single row. */ pIdxInfo->estimatedCost = 30.0; - setEstimatedRows(pIdxInfo, 1); + pIdxInfo->estimatedRows = 1; return SQLITE_OK; } @@ -1930,7 +1916,7 @@ static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ nRow = pRtree->nRowEst >> (iIdx/2); pIdxInfo->estimatedCost = (double)6.0 * (double)nRow; - setEstimatedRows(pIdxInfo, nRow); + pIdxInfo->estimatedRows = nRow; return rc; } diff --git a/manifest b/manifest index ba5d6d8cf1..b224942f12 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\s"max-limits"\sutility\sprogram\sto\sthe\stools/\ssubdirectory. -D 2017-02-06T15:27:44.567 +C Remove\sa\ssmall\samount\sof\sunnecessary\scode\sfrom\sR-Tree. +D 2017-02-06T16:52:32.895 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc ba953c8921fc7e18333f61898007206de7e23964 @@ -264,7 +264,7 @@ F ext/rbu/sqlite3rbu.c bb0de6cdbdb14a7d55a097238a434b7e99caf318 F ext/rbu/sqlite3rbu.h 6fb6294c34a9ca93b5894a33bca530c6f08decba F ext/rbu/test_rbu.c 5aa22616afac6f71ebd3d9bc9bf1006cfabcca88 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 -F ext/rtree/rtree.c d40feeeee43736bb96fce8a73385ca721c207d4a +F ext/rtree/rtree.c 2f7785eec412bcf289d5088ed74abe9855e8a5d5 F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e F ext/rtree/rtree1.test 42dadfc7b44a436cd74a1bebc0b9b689e4eaf7ec F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba @@ -1554,7 +1554,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 6b0276f968d3c6430076c6e540907cf840d0f398 -R f80944376543a94e77dae99832d50174 +P c54173b6c1acbb41ed9c323099e94b8e02c6c895 +R 826a4ad10a5c86df22518befe7373210 U drh -Z ae78f6b03eb9477204e774bb8b71a31e +Z 369aa1878a60b61dc52ce9554d8934f7 diff --git a/manifest.uuid b/manifest.uuid index c191fc2bb5..4b0d774976 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c54173b6c1acbb41ed9c323099e94b8e02c6c895 \ No newline at end of file +e5aea894267addb4dc9b21de24a20417b0be508a \ No newline at end of file From b18bf843f7c2574059e93d41a087485b38e057c4 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 7 Feb 2017 00:55:47 +0000 Subject: [PATCH 1299/1484] Fix a minor typo in a comment in R-Tree. No changes to code. FossilOrigin-Name: f77ee9e941f22b0b2e88871df4466fdde9cde131 --- ext/rtree/rtree.c | 2 +- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/ext/rtree/rtree.c b/ext/rtree/rtree.c index 4d77be827f..0241a6279a 100644 --- a/ext/rtree/rtree.c +++ b/ext/rtree/rtree.c @@ -1304,7 +1304,7 @@ static int rtreeSearchPointCompare( } /* -** Interchange to search points in a cursor. +** Interchange two search points in a cursor. */ static void rtreeSearchPointSwap(RtreeCursor *p, int i, int j){ RtreeSearchPoint t = p->aPoint[i]; diff --git a/manifest b/manifest index b224942f12..6545db5863 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sa\ssmall\samount\sof\sunnecessary\scode\sfrom\sR-Tree. -D 2017-02-06T16:52:32.895 +C Fix\sa\sminor\stypo\sin\sa\scomment\sin\sR-Tree.\s\sNo\schanges\sto\scode. +D 2017-02-07T00:55:47.045 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc ba953c8921fc7e18333f61898007206de7e23964 @@ -264,7 +264,7 @@ F ext/rbu/sqlite3rbu.c bb0de6cdbdb14a7d55a097238a434b7e99caf318 F ext/rbu/sqlite3rbu.h 6fb6294c34a9ca93b5894a33bca530c6f08decba F ext/rbu/test_rbu.c 5aa22616afac6f71ebd3d9bc9bf1006cfabcca88 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 -F ext/rtree/rtree.c 2f7785eec412bcf289d5088ed74abe9855e8a5d5 +F ext/rtree/rtree.c 76311736628e87fd780dfbbbf5813bf1f9bf2329 F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e F ext/rtree/rtree1.test 42dadfc7b44a436cd74a1bebc0b9b689e4eaf7ec F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba @@ -1554,7 +1554,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P c54173b6c1acbb41ed9c323099e94b8e02c6c895 -R 826a4ad10a5c86df22518befe7373210 +P e5aea894267addb4dc9b21de24a20417b0be508a +R d0b5dcf12941f0f1570d0961d3cc15da U drh -Z 369aa1878a60b61dc52ce9554d8934f7 +Z 7c46a9478c1e693d3d76de1002d9aeea diff --git a/manifest.uuid b/manifest.uuid index 4b0d774976..b66e0e2d13 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e5aea894267addb4dc9b21de24a20417b0be508a \ No newline at end of file +f77ee9e941f22b0b2e88871df4466fdde9cde131 \ No newline at end of file From 76f63789f2815873d05bdd039c0c49ce5ffb070b Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 7 Feb 2017 03:44:42 +0000 Subject: [PATCH 1300/1484] Back out [ec8ff892ac] which is causing missed OOM errors on some tests. FossilOrigin-Name: 0611770d6a2fcb9fa0bedee19df9916820ae8f3b --- manifest | 13 +++++++------ manifest.uuid | 2 +- src/main.c | 34 +++++++++++++++++----------------- 3 files changed, 25 insertions(+), 24 deletions(-) diff --git a/manifest b/manifest index 6545db5863..7dcfa25be5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sminor\stypo\sin\sa\scomment\sin\sR-Tree.\s\sNo\schanges\sto\scode. -D 2017-02-07T00:55:47.045 +C Back\sout\s[ec8ff892ac]\swhich\sis\scausing\smissed\sOOM\serrors\son\ssome\stests. +D 2017-02-07T03:44:42.867 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc ba953c8921fc7e18333f61898007206de7e23964 @@ -359,7 +359,7 @@ F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 F src/insert.c 444354c23d4d140a57d6eb46f34e376a7f8f62e8 F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e F src/loadext.c a68d8d1d14cf7488bb29dc5311cb1ce9a4404258 -F src/main.c eb4f5034ede07e1777e3e31fb2059a0046f499af +F src/main.c e207b81542d13b9f13d61e78ca441f9781f055b0 F src/malloc.c fc1b9f445290f2145da48fc08730c26e6082b640 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b @@ -1554,7 +1554,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 e5aea894267addb4dc9b21de24a20417b0be508a -R d0b5dcf12941f0f1570d0961d3cc15da +P f77ee9e941f22b0b2e88871df4466fdde9cde131 +Q -ec8ff892ac9c6a8f81bcf69f1933f4bb69faa743 +R ebea043e9962974403d836188c02b08f U drh -Z 7c46a9478c1e693d3d76de1002d9aeea +Z a87f51011f00704857e3612bb8043da6 diff --git a/manifest.uuid b/manifest.uuid index b66e0e2d13..1b41d3e917 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f77ee9e941f22b0b2e88871df4466fdde9cde131 \ No newline at end of file +0611770d6a2fcb9fa0bedee19df9916820ae8f3b \ No newline at end of file diff --git a/src/main.c b/src/main.c index e771c8eb04..9aad8fdd4c 100644 --- a/src/main.c +++ b/src/main.c @@ -2989,13 +2989,13 @@ static int openDatabase( if( rc==SQLITE_OK ){ sqlite3AutoLoadExtensions(db); rc = sqlite3_errcode(db); + if( rc!=SQLITE_OK ){ + goto opendb_out; + } } - testcase( rc!=SQLITE_OK && rc!=SQLITE_NOMEM ); - testcase( rc!=SQLITE_OK && !db->mallocFailed ); - #ifdef SQLITE_ENABLE_FTS1 - if( !db->mallocFailed && rc==SQLITE_OK ){ + if( !db->mallocFailed ){ extern int sqlite3Fts1Init(sqlite3*); rc = sqlite3Fts1Init(db); } @@ -3038,23 +3038,23 @@ static int openDatabase( } #endif - if( rc==SQLITE_OK ){ - /* -DSQLITE_DEFAULT_LOCKING_MODE=1 makes EXCLUSIVE the default locking - ** mode. -DSQLITE_DEFAULT_LOCKING_MODE=0 make NORMAL the default locking - ** mode. Doing nothing at all also makes NORMAL the default. - */ + /* -DSQLITE_DEFAULT_LOCKING_MODE=1 makes EXCLUSIVE the default locking + ** mode. -DSQLITE_DEFAULT_LOCKING_MODE=0 make NORMAL the default locking + ** mode. Doing nothing at all also makes NORMAL the default. + */ #ifdef SQLITE_DEFAULT_LOCKING_MODE - db->dfltLockMode = SQLITE_DEFAULT_LOCKING_MODE; - sqlite3PagerLockingMode(sqlite3BtreePager(db->aDb[0].pBt), - SQLITE_DEFAULT_LOCKING_MODE); + db->dfltLockMode = SQLITE_DEFAULT_LOCKING_MODE; + sqlite3PagerLockingMode(sqlite3BtreePager(db->aDb[0].pBt), + SQLITE_DEFAULT_LOCKING_MODE); #endif - /* Enable the lookaside-malloc subsystem */ - setupLookaside(db, 0, sqlite3GlobalConfig.szLookaside, - sqlite3GlobalConfig.nLookaside); + if( rc ) sqlite3Error(db, rc); - sqlite3_wal_autocheckpoint(db, SQLITE_DEFAULT_WAL_AUTOCHECKPOINT); - } + /* Enable the lookaside-malloc subsystem */ + setupLookaside(db, 0, sqlite3GlobalConfig.szLookaside, + sqlite3GlobalConfig.nLookaside); + + sqlite3_wal_autocheckpoint(db, SQLITE_DEFAULT_WAL_AUTOCHECKPOINT); opendb_out: if( db ){ From edd9bcb372774046fe940329ce96bdd9c7ca30f4 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 7 Feb 2017 12:58:38 +0000 Subject: [PATCH 1301/1484] Make the cellMargin() routine of R-Tree slightly smaller and faster while also fixing a harmless compiler warning. FossilOrigin-Name: 07fe6228208684d579c4f6c334c90eb6262a9233 --- ext/rtree/rtree.c | 10 +++++----- manifest | 13 ++++++------- manifest.uuid | 2 +- 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/ext/rtree/rtree.c b/ext/rtree/rtree.c index 0241a6279a..e898e34b79 100644 --- a/ext/rtree/rtree.c +++ b/ext/rtree/rtree.c @@ -1955,12 +1955,12 @@ static RtreeDValue cellArea(Rtree *pRtree, RtreeCell *p){ ** of the objects size in each dimension. */ static RtreeDValue cellMargin(Rtree *pRtree, RtreeCell *p){ - RtreeDValue margin; - int ii; - margin = DCOORD(p->aCoord[1]) - DCOORD(p->aCoord[0]); - for(ii=2; iinDim2; ii+=2){ + RtreeDValue margin = 0; + int ii = pRtree->nDim2 - 2; + do{ margin += (DCOORD(p->aCoord[ii+1]) - DCOORD(p->aCoord[ii])); - } + ii -= 2; + }while( ii>=0 ); return margin; } diff --git a/manifest b/manifest index 7dcfa25be5..255e0df908 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Back\sout\s[ec8ff892ac]\swhich\sis\scausing\smissed\sOOM\serrors\son\ssome\stests. -D 2017-02-07T03:44:42.867 +C Make\sthe\scellMargin()\sroutine\sof\sR-Tree\sslightly\ssmaller\sand\sfaster\swhile\salso\nfixing\sa\sharmless\scompiler\swarning. +D 2017-02-07T12:58:38.284 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc ba953c8921fc7e18333f61898007206de7e23964 @@ -264,7 +264,7 @@ F ext/rbu/sqlite3rbu.c bb0de6cdbdb14a7d55a097238a434b7e99caf318 F ext/rbu/sqlite3rbu.h 6fb6294c34a9ca93b5894a33bca530c6f08decba F ext/rbu/test_rbu.c 5aa22616afac6f71ebd3d9bc9bf1006cfabcca88 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 -F ext/rtree/rtree.c 76311736628e87fd780dfbbbf5813bf1f9bf2329 +F ext/rtree/rtree.c 773fbf1217a12607a5898eeb5193974b6d2bdad4 F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e F ext/rtree/rtree1.test 42dadfc7b44a436cd74a1bebc0b9b689e4eaf7ec F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba @@ -1554,8 +1554,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P f77ee9e941f22b0b2e88871df4466fdde9cde131 -Q -ec8ff892ac9c6a8f81bcf69f1933f4bb69faa743 -R ebea043e9962974403d836188c02b08f +P 0611770d6a2fcb9fa0bedee19df9916820ae8f3b +R b3ac1d676d5ca604a8be68bb866fbceb U drh -Z a87f51011f00704857e3612bb8043da6 +Z 3ad4f65e4d593a16597f73c400a250b4 diff --git a/manifest.uuid b/manifest.uuid index 1b41d3e917..865247349a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0611770d6a2fcb9fa0bedee19df9916820ae8f3b \ No newline at end of file +07fe6228208684d579c4f6c334c90eb6262a9233 \ No newline at end of file From 364ca6a90e59f6453ff4b136fbce617f8743649a Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 7 Feb 2017 13:51:48 +0000 Subject: [PATCH 1302/1484] Fix SQLITE_BYTEORDER #defines in R-Tree when compiled separately from the amalgamation. FossilOrigin-Name: a136609c98ed3cc673c5a3c2578d49db3f2518d1 --- ext/rtree/rtree.c | 6 +++--- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/ext/rtree/rtree.c b/ext/rtree/rtree.c index e898e34b79..a288272517 100644 --- a/ext/rtree/rtree.c +++ b/ext/rtree/rtree.c @@ -408,13 +408,13 @@ struct RtreeMatchArg { defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) || \ defined(__arm__)) && !defined(SQLITE_RUNTIME_BYTEORDER) # define SQLITE_BYTEORDER 1234 -#endif -#if (defined(sparc) || defined(__ppc__)) \ +#elif (defined(sparc) || defined(__ppc__)) \ && !defined(SQLITE_RUNTIME_BYTEORDER) # define SQLITE_BYTEORDER 4321 -#endif +#else # define SQLITE_BYTEORDER 0 /* 0 means "unknown at compile-time" */ #endif +#endif /* What version of MSVC is being used. 0 means MSVC is not being used */ diff --git a/manifest b/manifest index 255e0df908..1e7c95b554 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\sthe\scellMargin()\sroutine\sof\sR-Tree\sslightly\ssmaller\sand\sfaster\swhile\salso\nfixing\sa\sharmless\scompiler\swarning. -D 2017-02-07T12:58:38.284 +C Fix\sSQLITE_BYTEORDER\s#defines\sin\sR-Tree\swhen\scompiled\sseparately\sfrom\sthe\namalgamation. +D 2017-02-07T13:51:48.651 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc ba953c8921fc7e18333f61898007206de7e23964 @@ -264,7 +264,7 @@ F ext/rbu/sqlite3rbu.c bb0de6cdbdb14a7d55a097238a434b7e99caf318 F ext/rbu/sqlite3rbu.h 6fb6294c34a9ca93b5894a33bca530c6f08decba F ext/rbu/test_rbu.c 5aa22616afac6f71ebd3d9bc9bf1006cfabcca88 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 -F ext/rtree/rtree.c 773fbf1217a12607a5898eeb5193974b6d2bdad4 +F ext/rtree/rtree.c 97b6560be68c20d27169ec14b805609f3ca4d90f F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e F ext/rtree/rtree1.test 42dadfc7b44a436cd74a1bebc0b9b689e4eaf7ec F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba @@ -1554,7 +1554,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 0611770d6a2fcb9fa0bedee19df9916820ae8f3b -R b3ac1d676d5ca604a8be68bb866fbceb +P 07fe6228208684d579c4f6c334c90eb6262a9233 +R fb7b4c31979a0a5dd9190e2f71115220 U drh -Z 3ad4f65e4d593a16597f73c400a250b4 +Z e9cc05bda60d84b045dd690e40ba6bd5 diff --git a/manifest.uuid b/manifest.uuid index 865247349a..cbfdaf9434 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -07fe6228208684d579c4f6c334c90eb6262a9233 \ No newline at end of file +a136609c98ed3cc673c5a3c2578d49db3f2518d1 \ No newline at end of file From 821fad51b4b93980dca0b886b760645d097b41ab Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 7 Feb 2017 14:22:39 +0000 Subject: [PATCH 1303/1484] Fix a test case to account for the fact that sqlite3_blob_reopen() now returns SQLITE_IOERR_NOMEM instead of SQLITE_NOMEM if an OOM occurs in the VFS layer. FossilOrigin-Name: e11cc52389f61f6421179281877b119c02286121 --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/incrblobfault.test | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 1e7c95b554..eb4d617f5c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sSQLITE_BYTEORDER\s#defines\sin\sR-Tree\swhen\scompiled\sseparately\sfrom\sthe\namalgamation. -D 2017-02-07T13:51:48.651 +C Fix\sa\stest\scase\sto\saccount\sfor\sthe\sfact\sthat\ssqlite3_blob_reopen()\snow\sreturns\nSQLITE_IOERR_NOMEM\sinstead\sof\sSQLITE_NOMEM\sif\san\sOOM\soccurs\sin\sthe\sVFS\slayer. +D 2017-02-07T14:22:39.073 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc ba953c8921fc7e18333f61898007206de7e23964 @@ -851,7 +851,7 @@ F test/incrblob2.test a5ce5ed1d0b01e2ed347245a21170372528af0a5 F test/incrblob3.test d8d036fde015d4a159cd3cbae9d29003b37227a4 F test/incrblob4.test 21a52a6843a56cdcce968c6a86b72a7066d0e6ba F test/incrblob_err.test 69f9247fed50278d48ea710d1a8f9cdb09e4c0b8 -F test/incrblobfault.test 280474078f6da9e732cd2a215d3d854969014b6e +F test/incrblobfault.test 74dd8ac108304cea0b4a0df6df63a1567e558758 F test/incrcorrupt.test 6c567fbf870aa9e91866fe52ce6f200cd548939a F test/incrvacuum.test d2a6ddf5e429720b5fe502766af747915ccf6c32 F test/incrvacuum2.test 7d26cfda66c7e55898d196de54ac4ec7d86a4e3d @@ -1554,7 +1554,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 07fe6228208684d579c4f6c334c90eb6262a9233 -R fb7b4c31979a0a5dd9190e2f71115220 -U drh -Z e9cc05bda60d84b045dd690e40ba6bd5 +P a136609c98ed3cc673c5a3c2578d49db3f2518d1 +R b322167caccfbef7ed8b051ff68195b2 +U dan +Z ce20f1c1fe7e20be76a40b05210db04c diff --git a/manifest.uuid b/manifest.uuid index cbfdaf9434..dd14d6d04e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a136609c98ed3cc673c5a3c2578d49db3f2518d1 \ No newline at end of file +e11cc52389f61f6421179281877b119c02286121 \ No newline at end of file diff --git a/test/incrblobfault.test b/test/incrblobfault.test index 0c1d93d460..10c2c8ecb4 100644 --- a/test/incrblobfault.test +++ b/test/incrblobfault.test @@ -52,7 +52,7 @@ do_faultsim_test 2 -prep { error [sqlite3_errmsg db] } } -test { - faultsim_test_result {1 {no such rowid: -1}} + faultsim_test_result {1 {no such rowid: -1}} {1 {disk I/O error}} close $::blob } From 9fcb6ddc1e4eba176fdd32cb7b8968ba81e9c629 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 7 Feb 2017 14:45:18 +0000 Subject: [PATCH 1304/1484] Fix a build problem affecting non-amalgamation rtree builds. FossilOrigin-Name: bb7f445ba1df53cd4a169612b18fc533016102b7 --- ext/rtree/rtree.c | 1 + manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/ext/rtree/rtree.c b/ext/rtree/rtree.c index a288272517..1e3e65ecc9 100644 --- a/ext/rtree/rtree.c +++ b/ext/rtree/rtree.c @@ -68,6 +68,7 @@ #ifndef SQLITE_AMALGAMATION #include "sqlite3rtree.h" typedef sqlite3_int64 i64; +typedef sqlite3_uint64 u64; typedef unsigned char u8; typedef unsigned short u16; typedef unsigned int u32; diff --git a/manifest b/manifest index eb4d617f5c..4651930793 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\stest\scase\sto\saccount\sfor\sthe\sfact\sthat\ssqlite3_blob_reopen()\snow\sreturns\nSQLITE_IOERR_NOMEM\sinstead\sof\sSQLITE_NOMEM\sif\san\sOOM\soccurs\sin\sthe\sVFS\slayer. -D 2017-02-07T14:22:39.073 +C Fix\sa\sbuild\sproblem\saffecting\snon-amalgamation\srtree\sbuilds. +D 2017-02-07T14:45:18.924 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc ba953c8921fc7e18333f61898007206de7e23964 @@ -264,7 +264,7 @@ F ext/rbu/sqlite3rbu.c bb0de6cdbdb14a7d55a097238a434b7e99caf318 F ext/rbu/sqlite3rbu.h 6fb6294c34a9ca93b5894a33bca530c6f08decba F ext/rbu/test_rbu.c 5aa22616afac6f71ebd3d9bc9bf1006cfabcca88 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 -F ext/rtree/rtree.c 97b6560be68c20d27169ec14b805609f3ca4d90f +F ext/rtree/rtree.c d92be99e3a662e1934658201f0fc7ad51b44325a F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e F ext/rtree/rtree1.test 42dadfc7b44a436cd74a1bebc0b9b689e4eaf7ec F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba @@ -1554,7 +1554,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a136609c98ed3cc673c5a3c2578d49db3f2518d1 -R b322167caccfbef7ed8b051ff68195b2 +P e11cc52389f61f6421179281877b119c02286121 +R ba6eaa451f165f44792dd902ec15651c U dan -Z ce20f1c1fe7e20be76a40b05210db04c +Z 82882b9c6c63f305c028e634c6349ae2 diff --git a/manifest.uuid b/manifest.uuid index dd14d6d04e..f33ceba2a3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e11cc52389f61f6421179281877b119c02286121 \ No newline at end of file +bb7f445ba1df53cd4a169612b18fc533016102b7 \ No newline at end of file From 2e9dceb432cca5f58f4c4b474c9348038492e56f Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 7 Feb 2017 16:15:48 +0000 Subject: [PATCH 1305/1484] Update an error message in corruptC.test. FossilOrigin-Name: 722e57fe61162a82b8001c7b1d3e06174caa90b9 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/corruptC.test | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 4651930793..0378ad6c62 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sbuild\sproblem\saffecting\snon-amalgamation\srtree\sbuilds. -D 2017-02-07T14:45:18.924 +C Update\san\serror\smessage\sin\scorruptC.test. +D 2017-02-07T16:15:48.783 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc ba953c8921fc7e18333f61898007206de7e23964 @@ -607,7 +607,7 @@ F test/corrupt8.test 2399dfe40d2c0c63af86706e30f3e6302a8d0516 F test/corrupt9.test 730a3db08d4ab9aa43392ea30d9c2b4879cbff85 F test/corruptA.test 53e56dafd180addcdadb402244b8cb9771d2ba26 F test/corruptB.test 73a8d6c0b9833697ecf16b63e3c5c05c945b5dec -F test/corruptC.test 4ef10844eba5213bd262f4d96784d7fcda114afe +F test/corruptC.test 46ec43bd90a02fd7b37ad8a7a949c55aa5717f89 F test/corruptD.test b3c205fac7952b1de645ce44bb02335cd9e3e040 F test/corruptE.test 82ccf4f8f543fdbedd4aa42c709cb077f7374c62 F test/corruptF.test be9fde98e4c93648f1ba52b74e5318edc8f59fe4 @@ -1554,7 +1554,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e11cc52389f61f6421179281877b119c02286121 -R ba6eaa451f165f44792dd902ec15651c +P bb7f445ba1df53cd4a169612b18fc533016102b7 +R 1228beaef5172fbebdd4d0250089ef1e U dan -Z 82882b9c6c63f305c028e634c6349ae2 +Z cdab5e1aea1876be0fe4dd420440969d diff --git a/manifest.uuid b/manifest.uuid index f33ceba2a3..9aa189d3e7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bb7f445ba1df53cd4a169612b18fc533016102b7 \ No newline at end of file +722e57fe61162a82b8001c7b1d3e06174caa90b9 \ No newline at end of file diff --git a/test/corruptC.test b/test/corruptC.test index e2fb1f33c4..f404e4fb5b 100644 --- a/test/corruptC.test +++ b/test/corruptC.test @@ -164,7 +164,7 @@ do_test corruptC-2.5 { catchsql {BEGIN; UPDATE t2 SET y='abcdef-uvwxyz'; ROLLBACK;} catchsql {PRAGMA integrity_check} } {0 {{*** in database main *** -Page 4: btreeInitPage() returns error code 11}}} +On tree page 4 cell 19: Extends off end of page}}} # {0 {{*** in database main *** # Corruption detected in cell 710 on page 4 From b9e9bc1de62a877a3c18baede844dd07d7ed7775 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 7 Feb 2017 17:36:12 +0000 Subject: [PATCH 1306/1484] Add the initial version of the "dbselftest" utility program. FossilOrigin-Name: 1fcac8365e0f7bcfd55442d718da6626c864d45a --- Makefile.in | 5 + main.mk | 7 +- manifest | 17 +- manifest.uuid | 2 +- test/dbselftest.c | 605 ++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 626 insertions(+), 10 deletions(-) create mode 100644 test/dbselftest.c diff --git a/Makefile.in b/Makefile.in index d5fa831e6b..740b49c08f 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1185,6 +1185,11 @@ KV_OPT += -DSQLITE_DIRECT_OVERFLOW_READ kvtest$(TEXE): $(TOP)/test/kvtest.c sqlite3.c $(LTLINK) $(KV_OPT) -o $@ $(TOP)/test/kvtest.c sqlite3.c $(TLIBS) +DBSELFTEST_OPT += -DSQLITE_ENABLE_RTREE -DSQLITE_ENABLE_FTS4 + +dbselftest$(TEXE): $(TOP)/test/dbselftest.c sqlite3.c + $(LTLINK) $(DBSELFTEST_OPT) -o $@ $(TOP)/test/dbselftest.c sqlite3.c $(TLIBS) + rbu$(EXE): $(TOP)/ext/rbu/rbu.c $(TOP)/ext/rbu/sqlite3rbu.c sqlite3.lo $(LTLINK) -I. -o $@ $(TOP)/ext/rbu/rbu.c sqlite3.lo $(TLIBS) diff --git a/main.mk b/main.mk index 17e6468e10..85ed76a143 100644 --- a/main.mk +++ b/main.mk @@ -479,6 +479,8 @@ FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1 FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 DBFUZZ_OPT = KV_OPT = -DSQLITE_THREADSAFE=0 -DSQLITE_DIRECT_OVERFLOW_READ +DBSELFTEST_OPT = -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION +DBSELFTEST_OPT += -DSQLITE_ENABLE_RTREE -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS5 ST_OPT = -DSQLITE_THREADSAFE=0 # This is the default Makefile target. The objects listed here @@ -898,7 +900,10 @@ speedtest1$(EXE): $(TOP)/test/speedtest1.c sqlite3.c $(TCCX) -I. $(ST_OPT) -o speedtest1$(EXE) $(TOP)/test/speedtest1.c sqlite3.c $(THREADLIB) kvtest$(EXE): $(TOP)/test/kvtest.c sqlite3.c - $(TCCX) -I. $(KV+OPT) -o kvtest$(EXE) $(TOP)/test/kvtest.c sqlite3.c $(THREADLIB) + $(TCCX) -I. $(KV_OPT) -o kvtest$(EXE) $(TOP)/test/kvtest.c sqlite3.c $(THREADLIB) + +dbselftest$(EXE): $(TOP)/test/dbselftest.c sqlite3.c + $(TCCX) -I. $(DBSELFTEST_OPT) -o dbselftest$(EXE) $(TOP)/test/dbselftest.c sqlite3.c $(THREADLIB) rbu$(EXE): $(TOP)/ext/rbu/rbu.c $(TOP)/ext/rbu/sqlite3rbu.c sqlite3.o $(TCC) -I. -o rbu$(EXE) $(TOP)/ext/rbu/rbu.c sqlite3.o \ diff --git a/manifest b/manifest index 0378ad6c62..2432d3968f 100644 --- a/manifest +++ b/manifest @@ -1,6 +1,6 @@ -C Update\san\serror\smessage\sin\scorruptC.test. -D 2017-02-07T16:15:48.783 -F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc +C Add\sthe\sinitial\sversion\sof\sthe\s"dbselftest"\sutility\sprogram. +D 2017-02-07T17:36:12.948 +F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc ba953c8921fc7e18333f61898007206de7e23964 F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7 @@ -318,7 +318,7 @@ F ext/userauth/userauth.c 3410be31283abba70255d71fd24734e017a4497f F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60 -F main.mk afc52937b4e5fe08678e8d5a4fe4487d44e3bc61 +F main.mk 08e0b151abb46353c677ac4974b50c6077f85eee F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 @@ -636,6 +636,7 @@ F test/cursorhint.test 7bc346788390475e77a345da2b92270d04d35856 F test/cursorhint2.test 8457e93d97f665f23f97cdbc8477d16e3480331b F test/date.test a6a5a48b90907bca9fbcc79a30be5a715c1ab2fc F test/dbfuzz.c 8cc2bdb818b4483a052f9f80f96be74cbd9a6e1d +F test/dbselftest.c eeb95d09932b4dc79e5886bd8cf5d812e7d28d94 F test/dbstatus.test 73149851b3aff14fc6db478e58f9083a66422cf5 F test/dbstatus2.test e93ab03bfae6d62d4d935f20de928c19ca0ed0ab F test/default.test 0cb49b1c315a0d81c81d775e407f66906a2a604d @@ -1554,7 +1555,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P bb7f445ba1df53cd4a169612b18fc533016102b7 -R 1228beaef5172fbebdd4d0250089ef1e -U dan -Z cdab5e1aea1876be0fe4dd420440969d +P 722e57fe61162a82b8001c7b1d3e06174caa90b9 +R 9f073837e9cdb1ff055e4a2a2994d017 +U drh +Z f48b3d2fea77878a00660f4925462068 diff --git a/manifest.uuid b/manifest.uuid index 9aa189d3e7..e2570868a3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -722e57fe61162a82b8001c7b1d3e06174caa90b9 \ No newline at end of file +1fcac8365e0f7bcfd55442d718da6626c864d45a \ No newline at end of file diff --git a/test/dbselftest.c b/test/dbselftest.c new file mode 100644 index 0000000000..1c6f8d8b9f --- /dev/null +++ b/test/dbselftest.c @@ -0,0 +1,605 @@ +/* +** 2017-02-07 +** +** 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 program implements an SQLite database self-verification utility. +** Usage: +** +** dbselftest DATABASE +** +** This program reads the "selftest" table in DATABASE, in rowid order, +** and runs each of the tests described there, reporting results at the +** end. +** +** The intent of this program is to have a set of test database files that +** can be run using future versions of SQLite in order to verify that +** legacy database files continue to be readable. In other words, the +** intent is to confirm that there have been no breaking changes in the +** file format. The program can also be used to verify that database files +** are fully compatible between different architectures. +** +** The selftest table looks like this: +** +** CREATE TABLE selftest ( +** id INTEGER PRIMARY KEY, -- Run tests in ascending order +** op TEXT, -- "test", "regexp", "print", etc. +** cmdtxt TEXT, -- Usually the SQL to be run +** expected TEXT -- Expected results +** ); +** +*/ +#include +#include +#include +#include +#include +#include "sqlite3.h" + +static const char zHelp[] = + "Usage: dbselftest [OPTIONS] DBFILE\n" + "\n" + " --init Create the selftest table\n" + " -q Suppress most output. Errors only\n" + " -v Show extra output\n" +; + + +/****************************************************************************** +** The following code from ext/misc/sha1.c +** +** Context for the SHA1 hash +*/ +typedef struct SHA1Context SHA1Context; +struct SHA1Context { + unsigned int state[5]; + unsigned int count[2]; + unsigned char buffer[64]; +}; + + +#if __GNUC__ && (defined(__i386__) || defined(__x86_64__)) +/* + * GCC by itself only generates left rotates. Use right rotates if + * possible to be kinder to dinky implementations with iterative rotate + * instructions. + */ +#define SHA_ROT(op, x, k) \ + ({ unsigned int y; asm(op " %1,%0" : "=r" (y) : "I" (k), "0" (x)); y; }) +#define rol(x,k) SHA_ROT("roll", x, k) +#define ror(x,k) SHA_ROT("rorl", x, k) + +#else +/* Generic C equivalent */ +#define SHA_ROT(x,l,r) ((x) << (l) | (x) >> (r)) +#define rol(x,k) SHA_ROT(x,k,32-(k)) +#define ror(x,k) SHA_ROT(x,32-(k),k) +#endif + + +#define blk0le(i) (block[i] = (ror(block[i],8)&0xFF00FF00) \ + |(rol(block[i],8)&0x00FF00FF)) +#define blk0be(i) block[i] +#define blk(i) (block[i&15] = rol(block[(i+13)&15]^block[(i+8)&15] \ + ^block[(i+2)&15]^block[i&15],1)) + +/* + * (R0+R1), R2, R3, R4 are the different operations (rounds) used in SHA1 + * + * Rl0() for little-endian and Rb0() for big-endian. Endianness is + * determined at run-time. + */ +#define Rl0(v,w,x,y,z,i) \ + z+=((w&(x^y))^y)+blk0le(i)+0x5A827999+rol(v,5);w=ror(w,2); +#define Rb0(v,w,x,y,z,i) \ + z+=((w&(x^y))^y)+blk0be(i)+0x5A827999+rol(v,5);w=ror(w,2); +#define R1(v,w,x,y,z,i) \ + z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=ror(w,2); +#define R2(v,w,x,y,z,i) \ + z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=ror(w,2); +#define R3(v,w,x,y,z,i) \ + z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=ror(w,2); +#define R4(v,w,x,y,z,i) \ + z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=ror(w,2); + +/* + * Hash a single 512-bit block. This is the core of the algorithm. + */ +void SHA1Transform(unsigned int state[5], const unsigned char buffer[64]){ + unsigned int qq[5]; /* a, b, c, d, e; */ + static int one = 1; + unsigned int block[16]; + memcpy(block, buffer, 64); + memcpy(qq,state,5*sizeof(unsigned int)); + +#define a qq[0] +#define b qq[1] +#define c qq[2] +#define d qq[3] +#define e qq[4] + + /* Copy p->state[] to working vars */ + /* + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; + */ + + /* 4 rounds of 20 operations each. Loop unrolled. */ + if( 1 == *(unsigned char*)&one ){ + Rl0(a,b,c,d,e, 0); Rl0(e,a,b,c,d, 1); Rl0(d,e,a,b,c, 2); Rl0(c,d,e,a,b, 3); + Rl0(b,c,d,e,a, 4); Rl0(a,b,c,d,e, 5); Rl0(e,a,b,c,d, 6); Rl0(d,e,a,b,c, 7); + Rl0(c,d,e,a,b, 8); Rl0(b,c,d,e,a, 9); Rl0(a,b,c,d,e,10); Rl0(e,a,b,c,d,11); + Rl0(d,e,a,b,c,12); Rl0(c,d,e,a,b,13); Rl0(b,c,d,e,a,14); Rl0(a,b,c,d,e,15); + }else{ + Rb0(a,b,c,d,e, 0); Rb0(e,a,b,c,d, 1); Rb0(d,e,a,b,c, 2); Rb0(c,d,e,a,b, 3); + Rb0(b,c,d,e,a, 4); Rb0(a,b,c,d,e, 5); Rb0(e,a,b,c,d, 6); Rb0(d,e,a,b,c, 7); + Rb0(c,d,e,a,b, 8); Rb0(b,c,d,e,a, 9); Rb0(a,b,c,d,e,10); Rb0(e,a,b,c,d,11); + Rb0(d,e,a,b,c,12); Rb0(c,d,e,a,b,13); Rb0(b,c,d,e,a,14); Rb0(a,b,c,d,e,15); + } + R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); + R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); + R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); + R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); + R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); + R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); + R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); + R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); + R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); + R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); + R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); + R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); + R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); + R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); + R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); + R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); + + /* Add the working vars back into context.state[] */ + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + state[4] += e; + +#undef a +#undef b +#undef c +#undef d +#undef e +} + + +/* Initialize a SHA1 context */ +static void hash_init(SHA1Context *p){ + /* SHA1 initialization constants */ + p->state[0] = 0x67452301; + p->state[1] = 0xEFCDAB89; + p->state[2] = 0x98BADCFE; + p->state[3] = 0x10325476; + p->state[4] = 0xC3D2E1F0; + p->count[0] = p->count[1] = 0; +} + +/* Add new content to the SHA1 hash */ +static void hash_step( + SHA1Context *p, /* Add content to this context */ + const unsigned char *data, /* Data to be added */ + unsigned int len /* Number of bytes in data */ +){ + unsigned int i, j; + + j = p->count[0]; + if( (p->count[0] += len << 3) < j ){ + p->count[1] += (len>>29)+1; + } + j = (j >> 3) & 63; + if( (j + len) > 63 ){ + (void)memcpy(&p->buffer[j], data, (i = 64-j)); + SHA1Transform(p->state, p->buffer); + for(; i + 63 < len; i += 64){ + SHA1Transform(p->state, &data[i]); + } + j = 0; + }else{ + i = 0; + } + (void)memcpy(&p->buffer[j], &data[i], len - i); +} + +/* Compute a string using sqlite3_vsnprintf() and hash it */ +static void hash_step_vformat( + SHA1Context *p, /* Add content to this context */ + const char *zFormat, + ... +){ + va_list ap; + int n; + char zBuf[50]; + va_start(ap, zFormat); + sqlite3_vsnprintf(sizeof(zBuf),zBuf,zFormat,ap); + va_end(ap); + n = (int)strlen(zBuf); + hash_step(p, (unsigned char*)zBuf, n); +} + + +/* Add padding and compute the message digest. Render the +** message digest as lower-case hexadecimal and put it into +** zOut[]. zOut[] must be at least 41 bytes long. */ +static void hash_finish( + SHA1Context *p, /* The SHA1 context to finish and render */ + char *zOut /* Store hexadecimal hash here */ +){ + unsigned int i; + unsigned char finalcount[8]; + unsigned char digest[20]; + static const char zEncode[] = "0123456789abcdef"; + + for (i = 0; i < 8; i++){ + finalcount[i] = (unsigned char)((p->count[(i >= 4 ? 0 : 1)] + >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */ + } + hash_step(p, (const unsigned char *)"\200", 1); + while ((p->count[0] & 504) != 448){ + hash_step(p, (const unsigned char *)"\0", 1); + } + hash_step(p, finalcount, 8); /* Should cause a SHA1Transform() */ + for (i = 0; i < 20; i++){ + digest[i] = (unsigned char)((p->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); + } + for(i=0; i<20; i++){ + zOut[i*2] = zEncode[(digest[i]>>4)&0xf]; + zOut[i*2+1] = zEncode[digest[i] & 0xf]; + } + zOut[i*2]= 0; +} + +/* +** Implementation of the sha1(X) function. +** +** Return a lower-case hexadecimal rendering of the SHA1 hash of the +** argument X. If X is a BLOB, it is hashed as is. For all other +** types of input, X is converted into a UTF-8 string and the string +** is hash without the trailing 0x00 terminator. The hash of a NULL +** value is NULL. +*/ +static void sha1Func( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + SHA1Context cx; + int eType = sqlite3_value_type(argv[0]); + int nByte = sqlite3_value_bytes(argv[0]); + char zOut[44]; + + assert( argc==1 ); + if( eType==SQLITE_NULL ) return; + hash_init(&cx); + if( eType==SQLITE_BLOB ){ + hash_step(&cx, sqlite3_value_blob(argv[0]), nByte); + }else{ + hash_step(&cx, sqlite3_value_text(argv[0]), nByte); + } + hash_finish(&cx, zOut); + sqlite3_result_text(context, zOut, 40, SQLITE_TRANSIENT); +} + +/* +** Implementation of the sha1_query(SQL) function. +** +** This function compiles and runs the SQL statement(s) given in the +** argument. The results are hashed using SHA1 and that hash is returned. +** +** The original SQL text is included as part of the hash. +** +** The hash is not just a concatenation of the outputs. Each query +** is delimited and each row and value within the query is delimited, +** with all values being marked with their datatypes. +*/ +static void sha1QueryFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + sqlite3 *db = sqlite3_context_db_handle(context); + const char *zSql = (const char*)sqlite3_value_text(argv[0]); + sqlite3_stmt *pStmt = 0; + int nCol; /* Number of columns in the result set */ + int i; /* Loop counter */ + int rc; + int n; + const char *z; + SHA1Context cx; + char zOut[44]; + + assert( argc==1 ); + if( zSql==0 ) return; + hash_init(&cx); + while( zSql[0] ){ + rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zSql); + if( rc ){ + char *zMsg = sqlite3_mprintf("error SQL statement [%s]: %s", + zSql, sqlite3_errmsg(db)); + sqlite3_finalize(pStmt); + sqlite3_result_error(context, zMsg, -1); + sqlite3_free(zMsg); + return; + } + if( !sqlite3_stmt_readonly(pStmt) ){ + char *zMsg = sqlite3_mprintf("non-query: [%s]", sqlite3_sql(pStmt)); + sqlite3_finalize(pStmt); + sqlite3_result_error(context, zMsg, -1); + sqlite3_free(zMsg); + return; + } + nCol = sqlite3_column_count(pStmt); + z = sqlite3_sql(pStmt); + n = (int)strlen(z); + hash_step_vformat(&cx,"S%d:",n); + hash_step(&cx,(unsigned char*)z,n); + + /* Compute a hash over the result of the query */ + while( SQLITE_ROW==sqlite3_step(pStmt) ){ + hash_step(&cx,(const unsigned char*)"R",1); + for(i=0; i=1; j--){ + x[j] = u & 0xff; + u >>= 8; + } + x[0] = 'I'; + hash_step(&cx, x, 9); + break; + } + case SQLITE_FLOAT: { + sqlite3_uint64 u; + int j; + unsigned char x[9]; + double r = sqlite3_column_double(pStmt,i); + memcpy(&u, &r, 8); + for(j=8; j>=1; j--){ + x[j] = u & 0xff; + u >>= 8; + } + x[0] = 'F'; + hash_step(&cx,x,9); + break; + } + case SQLITE_TEXT: { + int n2 = sqlite3_column_bytes(pStmt, i); + const unsigned char *z2 = sqlite3_column_text(pStmt, i); + hash_step_vformat(&cx,"T%d:",n2); + hash_step(&cx, z2, n2); + break; + } + case SQLITE_BLOB: { + int n2 = sqlite3_column_bytes(pStmt, i); + const unsigned char *z2 = sqlite3_column_blob(pStmt, i); + hash_step_vformat(&cx,"B%d:",n2); + hash_step(&cx, z2, n2); + break; + } + } + } + } + sqlite3_finalize(pStmt); + } + hash_finish(&cx, zOut); + sqlite3_result_text(context, zOut, 40, SQLITE_TRANSIENT); +} +/* End of ext/misc/sha1.c +******************************************************************************/ + +/* How much output to display */ +#define VOLUME_MIN 0 +#define VOLUME_OFF 0 +#define VOLUME_ERROR_ONLY 1 +#define VOLUME_LOW 2 +#define VOLUME_ECHO 3 +#define VOLUME_VERBOSE 4 +#define VOLUME_MAX 4 + +/* A string accumulator +*/ +typedef struct Str { + char *z; /* Accumulated text */ + int n; /* Bytes of z[] used so far */ + int nAlloc; /* Bytes allocated for z[] */ +} Str; + +/* Append text to the Str object +*/ +static void strAppend(Str *p, const char *z){ + int n = (int)strlen(z); + if( p->n+n >= p->nAlloc ){ + p->nAlloc += p->n+n + 100; + p->z = sqlite3_realloc(p->z, p->nAlloc); + if( z==0 ){ + printf("Could not allocate %d bytes\n", p->nAlloc); + exit(1); + } + } + memcpy(p->z+n, z, n+1); + p->n += n; +} + +/* This is an sqlite3_exec() callback that will capture all +** output in a Str. +** +** Columns are separated by ",". Rows are separated by "|". +*/ +static int execCallback(void *pStr, int argc, char **argv, char **colv){ + int i; + Str *p = (Str*)pStr; + if( p->n ) strAppend(p, "|"); + for(i=0; i0 ) strAppend(p, ","); + strAppend(p, z); + } + return 0; +} + +int main(int argc, char **argv){ + int eVolume = VOLUME_LOW; /* How much output to display */ + const char *zDb = 0; /* Name of the database file */ + int doInit = 0; /* True if --init is present */ + sqlite3 *db = 0; /* Open database connection */ + int rc; /* Return code from API calls */ + char *zErrMsg = 0; /* An error message return */ + char **azTest; /* Content of the selftest table */ + int nRow = 0, nCol = 0; /* Rows and columns in azTest[] */ + int i; /* Loop counter */ + int nErr = 0; /* Number of errors */ + Str str; /* Result accumulator */ + + for(i=1; iVOLUME_MIN) eVolume--; + }else + if( strcmp(z, "-v")==0 ){ + if( eVolume=VOLUME_LOW ){ + printf("SQLite %s\n", sqlite3_sourceid()); + } + memset(&str, 0, sizeof(str)); + strAppend(&str, "\n"); + for(i=1; i<=nRow; i++){ + int tno = atoi(azTest[i*nCol]); + const char *zOp = azTest[i*nCol+1]; + const char *zSql = azTest[i*nCol+2]; + const char *zAns = azTest[i*nCol+3]; + + if( eVolume>=VOLUME_ECHO ){ + char *zQuote = sqlite3_mprintf("%q", zSql); + printf("%d: %s %s\n", tno, zOp, zSql); + sqlite3_free(zQuote); + } + if( strcmp(zOp,"memo")==0 ){ + if( eVolume>=VOLUME_LOW ){ + printf("%s\n", zSql); + } + }else + if( strcmp(zOp,"run")==0 ){ + str.n = 0; + str.z[0] = 0; + zErrMsg = 0; + rc = sqlite3_exec(db, zSql, execCallback, &str, &zErrMsg); + if( eVolume>=VOLUME_VERBOSE ){ + printf("Result: %s\n", str.z); + } + if( rc || zErrMsg ){ + nErr++; + if( eVolume>=VOLUME_ERROR_ONLY ){ + printf("%d: error-code-%d: %s\n", tno, rc, zErrMsg); + } + sqlite3_free(zErrMsg); + }else if( strcmp(zAns,str.z)!=0 ){ + nErr++; + if( eVolume>=VOLUME_ERROR_ONLY ){ + printf("%d: Expected: [%s]\n", tno, zAns); + printf("%d: Got: [%s]\n", tno, str.z); + } + } + }else + { + printf("Unknown operation \"%s\" on selftest line %d\n", zOp, tno); + return 1; + } + } + sqlite3_free_table(azTest); + sqlite3_close(db); + if( eVolume>=VOLUME_LOW || (nErr>0 && eVolume>=VOLUME_ERROR_ONLY) ){ + printf("%d errors out of %d tests\n", nErr, nRow); + } + return nErr; +} From a7fc253d42ba787c60c33dc6e760fad5796ba817 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 7 Feb 2017 19:23:51 +0000 Subject: [PATCH 1307/1484] Update a test parameter in malloc5.test to account for the increase in default lookaside buffer size. FossilOrigin-Name: be82d5ae20ba62a165bdc28766a8dc8049abcac6 --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/malloc5.test | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 2432d3968f..36862460f4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sinitial\sversion\sof\sthe\s"dbselftest"\sutility\sprogram. -D 2017-02-07T17:36:12.948 +C Update\sa\stest\sparameter\sin\smalloc5.test\sto\saccount\sfor\sthe\sincrease\sin\sdefault\nlookaside\sbuffer\ssize. +D 2017-02-07T19:23:51.831 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc ba953c8921fc7e18333f61898007206de7e23964 @@ -928,7 +928,7 @@ F test/make-where7.tcl 05c16b5d4f5d6512881dfec560cb793915932ef9 F test/malloc.test 21c213365f2cca95ab2d7dc078dc8525f96065f8 F test/malloc3.test e3b32c724b5a124b57cb0ed177f675249ad0c66a F test/malloc4.test 957337613002b7058a85116493a262f679f3a261 -F test/malloc5.test 02ed7c5313f0a68d95f2dfca8c8962132bd1f04b +F test/malloc5.test 192d0b5ee1d023a07d5164c34cf47d010da73da1 F test/malloc6.test 2f039d9821927eacae43e1831f815e157659a151 F test/malloc7.test 7c68a32942858bc715284856c5507446bba88c3a F test/malloc8.test 9b7a3f8cb9cf0b12fff566e80a980b1767bd961d @@ -1555,7 +1555,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 722e57fe61162a82b8001c7b1d3e06174caa90b9 -R 9f073837e9cdb1ff055e4a2a2994d017 -U drh -Z f48b3d2fea77878a00660f4925462068 +P 1fcac8365e0f7bcfd55442d718da6626c864d45a +R d6f712b168d87479bbb4e9d5c8c40830 +U dan +Z 0f2ec469c3345d822f702c8d7a665aee diff --git a/manifest.uuid b/manifest.uuid index e2570868a3..7b0c1f1a48 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1fcac8365e0f7bcfd55442d718da6626c864d45a \ No newline at end of file +be82d5ae20ba62a165bdc28766a8dc8049abcac6 \ No newline at end of file diff --git a/test/malloc5.test b/test/malloc5.test index 8f0db04c2a..8114005e8b 100644 --- a/test/malloc5.test +++ b/test/malloc5.test @@ -236,12 +236,12 @@ do_test malloc5-4.2 { db eval {PRAGMA cache_size=1} db cache flush sqlite3_release_memory - sqlite3_soft_heap_limit 100000 + sqlite3_soft_heap_limit 200000 sqlite3_memory_highwater 1 execsql {SELECT * FROM abc} set nMaxBytes [sqlite3_memory_highwater 1] puts -nonewline " (Highwater mark: $nMaxBytes) " - expr $nMaxBytes <= 110000 + expr $nMaxBytes <= 210000 } {1} do_test malloc5-4.3 { # Check that the content of table abc is at least roughly as expected. From 18b20c981d47127ffeb8b38e6a654caea650f25d Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 7 Feb 2017 19:36:14 +0000 Subject: [PATCH 1308/1484] Omit fts5fault1.test from the inmemory_journal permutation. FossilOrigin-Name: cb1e83f9583bf93ce7583d9f5e97272e2d43cfb8 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/permutations.test | 4 ++++ 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 36862460f4..854ed84459 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\sa\stest\sparameter\sin\smalloc5.test\sto\saccount\sfor\sthe\sincrease\sin\sdefault\nlookaside\sbuffer\ssize. -D 2017-02-07T19:23:51.831 +C Omit\sfts5fault1.test\sfrom\sthe\sinmemory_journal\spermutation. +D 2017-02-07T19:36:14.794 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc ba953c8921fc7e18333f61898007206de7e23964 @@ -1015,7 +1015,7 @@ F test/parser1.test 391b9bf9a229547a129c61ac345ed1a6f5eb1854 F test/pcache.test c8acbedd3b6fd0f9a7ca887a83b11d24a007972b F test/pcache2.test af7f3deb1a819f77a6d0d81534e97d1cf62cd442 F test/percentile.test 4243af26b8f3f4555abe166f723715a1f74c77ff -F test/permutations.test cd0b7bc04bf5e50d3a993d24c834d591f7d4f5fe +F test/permutations.test 46ad98770d3c04ce2418cab2cc527647bfe961a7 F test/pragma.test 1e94755164a3a3264cd39836de4bebcb7809e5f8 F test/pragma2.test e5d5c176360c321344249354c0c16aec46214c9f F test/pragma3.test 14c12bc5352b1e100e0b6b44f371053a81ccf8ed @@ -1555,7 +1555,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 1fcac8365e0f7bcfd55442d718da6626c864d45a -R d6f712b168d87479bbb4e9d5c8c40830 +P be82d5ae20ba62a165bdc28766a8dc8049abcac6 +R 4c6aa653d353c19152ed7b2aaba4bc83 U dan -Z 0f2ec469c3345d822f702c8d7a665aee +Z 450aa5587fc5eb1e148efd8100bf109e diff --git a/manifest.uuid b/manifest.uuid index 7b0c1f1a48..026b45bd03 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -be82d5ae20ba62a165bdc28766a8dc8049abcac6 \ No newline at end of file +cb1e83f9583bf93ce7583d9f5e97272e2d43cfb8 \ No newline at end of file diff --git a/test/permutations.test b/test/permutations.test index f8880da225..7f81dcbb27 100644 --- a/test/permutations.test +++ b/test/permutations.test @@ -754,6 +754,10 @@ test_suite "inmemory_journal" -description { # This test assumes a journal file is created on disk. delete_db.test + + # This test depends on a successful recovery from the pager error + # state. Which is not possible with an in-memory journal + fts5fault1.test }] ifcapable mem3 { From cbc65e5f4f3fc24a0cfe17eb723f4439cb7bc01e Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 7 Feb 2017 20:51:38 +0000 Subject: [PATCH 1309/1484] The dbselftest utility now generates hashes in the selftest table with --init. It also accepts multiple database files on the command-line. FossilOrigin-Name: e68829c9bbc69bf4a0dc057e0a6e977f2fac79be --- manifest | 14 +- manifest.uuid | 2 +- test/dbselftest.c | 497 +++++++++++++++++++++++++++++++--------------- 3 files changed, 347 insertions(+), 166 deletions(-) diff --git a/manifest b/manifest index 854ed84459..a37a9e38bf 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Omit\sfts5fault1.test\sfrom\sthe\sinmemory_journal\spermutation. -D 2017-02-07T19:36:14.794 +C The\sdbselftest\sutility\snow\sgenerates\shashes\sin\sthe\sselftest\stable\swith\s--init.\nIt\salso\saccepts\smultiple\sdatabase\sfiles\son\sthe\scommand-line. +D 2017-02-07T20:51:38.461 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc ba953c8921fc7e18333f61898007206de7e23964 @@ -636,7 +636,7 @@ F test/cursorhint.test 7bc346788390475e77a345da2b92270d04d35856 F test/cursorhint2.test 8457e93d97f665f23f97cdbc8477d16e3480331b F test/date.test a6a5a48b90907bca9fbcc79a30be5a715c1ab2fc F test/dbfuzz.c 8cc2bdb818b4483a052f9f80f96be74cbd9a6e1d -F test/dbselftest.c eeb95d09932b4dc79e5886bd8cf5d812e7d28d94 +F test/dbselftest.c 4bf86fe04dc2d0d58dabc5e6b7a06fa4ef7827ea F test/dbstatus.test 73149851b3aff14fc6db478e58f9083a66422cf5 F test/dbstatus2.test e93ab03bfae6d62d4d935f20de928c19ca0ed0ab F test/default.test 0cb49b1c315a0d81c81d775e407f66906a2a604d @@ -1555,7 +1555,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P be82d5ae20ba62a165bdc28766a8dc8049abcac6 -R 4c6aa653d353c19152ed7b2aaba4bc83 -U dan -Z 450aa5587fc5eb1e148efd8100bf109e +P cb1e83f9583bf93ce7583d9f5e97272e2d43cfb8 +R 64e5750ab44994d5b187d93e5c4a1318 +U drh +Z f3a9d081d357071c2c4fc7a23224549e diff --git a/manifest.uuid b/manifest.uuid index 026b45bd03..6596630605 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cb1e83f9583bf93ce7583d9f5e97272e2d43cfb8 \ No newline at end of file +e68829c9bbc69bf4a0dc057e0a6e977f2fac79be \ No newline at end of file diff --git a/test/dbselftest.c b/test/dbselftest.c index 1c6f8d8b9f..d8a9c331de 100644 --- a/test/dbselftest.c +++ b/test/dbselftest.c @@ -13,7 +13,7 @@ ** This program implements an SQLite database self-verification utility. ** Usage: ** -** dbselftest DATABASE +** dbselftest DATABASE ... ** ** This program reads the "selftest" table in DATABASE, in rowid order, ** and runs each of the tests described there, reporting results at the @@ -44,7 +44,7 @@ #include "sqlite3.h" static const char zHelp[] = - "Usage: dbselftest [OPTIONS] DBFILE\n" + "Usage: dbselftest [OPTIONS] DBFILE ...\n" "\n" " --init Create the selftest table\n" " -q Suppress most output. Errors only\n" @@ -294,6 +294,101 @@ static void sha1Func( sqlite3_result_text(context, zOut, 40, SQLITE_TRANSIENT); } +/* +** Run a prepared statement and compute the SHA1 hash on the +** result rows. +*/ +static void sha1RunStatement(SHA1Context *pCtx, sqlite3_stmt *pStmt){ + int nCol = sqlite3_column_count(pStmt); + const char *z = sqlite3_sql(pStmt); + int n = (int)strlen(z); + + hash_step_vformat(pCtx,"S%d:",n); + hash_step(pCtx,(unsigned char*)z,n); + + /* Compute a hash over the result of the query */ + while( SQLITE_ROW==sqlite3_step(pStmt) ){ + int i; + hash_step(pCtx,(const unsigned char*)"R",1); + for(i=0; i=1; j--){ + x[j] = u & 0xff; + u >>= 8; + } + x[0] = 'I'; + hash_step(pCtx, x, 9); + break; + } + case SQLITE_FLOAT: { + sqlite3_uint64 u; + int j; + unsigned char x[9]; + double r = sqlite3_column_double(pStmt,i); + memcpy(&u, &r, 8); + for(j=8; j>=1; j--){ + x[j] = u & 0xff; + u >>= 8; + } + x[0] = 'F'; + hash_step(pCtx,x,9); + break; + } + case SQLITE_TEXT: { + int n2 = sqlite3_column_bytes(pStmt, i); + const unsigned char *z2 = sqlite3_column_text(pStmt, i); + hash_step_vformat(pCtx,"T%d:",n2); + hash_step(pCtx, z2, n2); + break; + } + case SQLITE_BLOB: { + int n2 = sqlite3_column_bytes(pStmt, i); + const unsigned char *z2 = sqlite3_column_blob(pStmt, i); + hash_step_vformat(pCtx,"B%d:",n2); + hash_step(pCtx, z2, n2); + break; + } + } + } + } +} + +/* +** Run one or more statements of SQL. Compute a SHA1 hash of the output. +*/ +static int sha1Exec( + sqlite3 *db, /* Run against this database connection */ + const char *zSql, /* The SQL to be run */ + char *zOut /* Store the SHA1 hash as hexadecimal in this buffer */ +){ + sqlite3_stmt *pStmt = 0; /* A prepared statement */ + int rc; /* Result of an API call */ + SHA1Context cx; /* The SHA1 hash context */ + + hash_init(&cx); + while( zSql[0] ){ + rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zSql); + if( rc ){ + sqlite3_finalize(pStmt); + return rc; + } + sha1RunStatement(&cx, pStmt); + sqlite3_finalize(pStmt); + } + hash_finish(&cx, zOut); + return SQLITE_OK; +} + /* ** Implementation of the sha1_query(SQL) function. ** @@ -314,11 +409,7 @@ static void sha1QueryFunc( sqlite3 *db = sqlite3_context_db_handle(context); const char *zSql = (const char*)sqlite3_value_text(argv[0]); sqlite3_stmt *pStmt = 0; - int nCol; /* Number of columns in the result set */ - int i; /* Loop counter */ int rc; - int n; - const char *z; SHA1Context cx; char zOut[44]; @@ -342,66 +433,7 @@ static void sha1QueryFunc( sqlite3_free(zMsg); return; } - nCol = sqlite3_column_count(pStmt); - z = sqlite3_sql(pStmt); - n = (int)strlen(z); - hash_step_vformat(&cx,"S%d:",n); - hash_step(&cx,(unsigned char*)z,n); - - /* Compute a hash over the result of the query */ - while( SQLITE_ROW==sqlite3_step(pStmt) ){ - hash_step(&cx,(const unsigned char*)"R",1); - for(i=0; i=1; j--){ - x[j] = u & 0xff; - u >>= 8; - } - x[0] = 'I'; - hash_step(&cx, x, 9); - break; - } - case SQLITE_FLOAT: { - sqlite3_uint64 u; - int j; - unsigned char x[9]; - double r = sqlite3_column_double(pStmt,i); - memcpy(&u, &r, 8); - for(j=8; j>=1; j--){ - x[j] = u & 0xff; - u >>= 8; - } - x[0] = 'F'; - hash_step(&cx,x,9); - break; - } - case SQLITE_TEXT: { - int n2 = sqlite3_column_bytes(pStmt, i); - const unsigned char *z2 = sqlite3_column_text(pStmt, i); - hash_step_vformat(&cx,"T%d:",n2); - hash_step(&cx, z2, n2); - break; - } - case SQLITE_BLOB: { - int n2 = sqlite3_column_bytes(pStmt, i); - const unsigned char *z2 = sqlite3_column_blob(pStmt, i); - hash_step_vformat(&cx,"B%d:",n2); - hash_step(&cx, z2, n2); - break; - } - } - } - } + sha1RunStatement(&cx, pStmt); sqlite3_finalize(pStmt); } hash_finish(&cx, zOut); @@ -439,7 +471,7 @@ static void strAppend(Str *p, const char *z){ exit(1); } } - memcpy(p->z+n, z, n+1); + memcpy(p->z+p->n, z, n+1); p->n += n; } @@ -461,9 +493,138 @@ static int execCallback(void *pStr, int argc, char **argv, char **colv){ return 0; } +/* +** Run an SQL statement constructing using sqlite3_vmprintf(). +** Return the number of errors. +*/ +static int runSql(sqlite3 *db, const char *zFormat, ...){ + char *zSql; + char *zErr = 0; + int rc; + int nErr = 0; + va_list ap; + + va_start(ap, zFormat); + zSql = sqlite3_vmprintf(zFormat, ap); + va_end(ap); + if( zSql==0 ){ + printf("Out of memory\n"); + exit(1); + } + rc = sqlite3_exec(db, zSql, 0, 0, &zErr); + if( rc || zErr ){ + printf("SQL error in [%s]: code=%d: %s\n", zSql, rc, zErr); + nErr++; + } + sqlite3_free(zSql); + return nErr; +} + +/* +** Generate a prepared statement using a formatted string. +*/ +static sqlite3_stmt *prepareSql(sqlite3 *db, const char *zFormat, ...){ + char *zSql; + int rc; + sqlite3_stmt *pStmt = 0; + va_list ap; + + va_start(ap, zFormat); + zSql = sqlite3_vmprintf(zFormat, ap); + va_end(ap); + if( zSql==0 ){ + printf("Out of memory\n"); + exit(1); + } + rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); + if( rc ){ + printf("SQL error in [%s]: code=%d: %s\n", zSql, rc, sqlite3_errmsg(db)); + sqlite3_finalize(pStmt); + pStmt = 0; + } + sqlite3_free(zSql); + return pStmt; +} + +/* +** Construct the standard selftest configuration for the database. +*/ +static int buildSelftestTable(sqlite3 *db){ + int rc; + sqlite3_stmt *pStmt; + int tno = 110; + char *zSql; + char zHash[50]; + + rc = runSql(db, + "CREATE TABLE IF NOT EXISTS selftest(\n" + " tno INTEGER PRIMARY KEY, -- test number\n" + " op TEXT, -- what kind of test\n" + " sql TEXT, -- SQL text for the test\n" + " ans TEXT -- expected answer\n" + ");" + "INSERT INTO selftest" + " VALUES(100,'memo','Hashes generated using --init',NULL);" + ); + if( rc ) return 1; + tno = 110; + zSql = "SELECT type,name,tbl_name,sql FROM sqlite_master"; + sha1Exec(db, zSql, zHash); + rc = runSql(db, + "INSERT INTO selftest(tno,op,sql,ans)" + " VALUES(%d,'sha1',%Q,%Q)", tno, zSql, zHash); + tno += 10; + pStmt = prepareSql(db, + "SELECT lower(name) FROM sqlite_master" + " WHERE type='table' AND sql NOT GLOB 'CREATE VIRTUAL*'" + " AND name<>'selftest'" + " ORDER BY 1"); + if( pStmt==0 ) return 1; + while( SQLITE_ROW==sqlite3_step(pStmt) ){ + zSql = sqlite3_mprintf("SELECT * FROM \"%w\" NOT INDEXED", + sqlite3_column_text(pStmt, 0)); + if( zSql==0 ){ + printf("Of of memory\n"); + exit(1); + } + sha1Exec(db, zSql, zHash); + rc = runSql(db, + "INSERT INTO selftest(tno,op,sql,ans)" + " VALUES(%d,'sha1',%Q,%Q)", tno, zSql, zHash); + tno += 10; + sqlite3_free(zSql); + if( rc ) break; + } + sqlite3_finalize(pStmt); + if( rc ) return 1; + rc = runSql(db, + "INSERT INTO selftest(tno,op,sql,ans)" + " VALUES(%d,'run','PRAGMA integrity_check','ok');", tno); + if( rc ) return 1; + return rc; +} + +/* +** Return true if the named table exists +*/ +static int tableExists(sqlite3 *db, const char *zTab){ + return sqlite3_table_column_metadata(db, "main", zTab, 0, 0, 0, 0, 0, 0) + == SQLITE_OK; +} + +/* +** Default selftest table content, for use when there is no selftest table +*/ +static char *azDefaultTest[] = { + 0, 0, 0, 0, + "0", "memo", "Missing SELFTEST table - default checks only", "", + "1", "run", "PRAGMA integrity_check", "ok" +}; + int main(int argc, char **argv){ int eVolume = VOLUME_LOW; /* How much output to display */ - const char *zDb = 0; /* Name of the database file */ + const char **azDb = 0; /* Name of the database file */ + int nDb = 0; /* Number of database files to check */ int doInit = 0; /* True if --init is present */ sqlite3 *db = 0; /* Open database connection */ int rc; /* Return code from API calls */ @@ -472,7 +633,9 @@ int main(int argc, char **argv){ int nRow = 0, nCol = 0; /* Rows and columns in azTest[] */ int i; /* Loop counter */ int nErr = 0; /* Number of errors */ + int iDb; /* Loop counter for databases */ Str str; /* Result accumulator */ + int nTest = 0; /* Number of tests run */ for(i=1; i=VOLUME_LOW ){ @@ -553,53 +678,109 @@ int main(int argc, char **argv){ } memset(&str, 0, sizeof(str)); strAppend(&str, "\n"); - for(i=1; i<=nRow; i++){ - int tno = atoi(azTest[i*nCol]); - const char *zOp = azTest[i*nCol+1]; - const char *zSql = azTest[i*nCol+2]; - const char *zAns = azTest[i*nCol+3]; - - if( eVolume>=VOLUME_ECHO ){ - char *zQuote = sqlite3_mprintf("%q", zSql); - printf("%d: %s %s\n", tno, zOp, zSql); - sqlite3_free(zQuote); - } - if( strcmp(zOp,"memo")==0 ){ - if( eVolume>=VOLUME_LOW ){ - printf("%s\n", zSql); - } - }else - if( strcmp(zOp,"run")==0 ){ - str.n = 0; - str.z[0] = 0; - zErrMsg = 0; - rc = sqlite3_exec(db, zSql, execCallback, &str, &zErrMsg); - if( eVolume>=VOLUME_VERBOSE ){ - printf("Result: %s\n", str.z); - } - if( rc || zErrMsg ){ - nErr++; - if( eVolume>=VOLUME_ERROR_ONLY ){ - printf("%d: error-code-%d: %s\n", tno, rc, zErrMsg); - } - sqlite3_free(zErrMsg); - }else if( strcmp(zAns,str.z)!=0 ){ - nErr++; - if( eVolume>=VOLUME_ERROR_ONLY ){ - printf("%d: Expected: [%s]\n", tno, zAns); - printf("%d: Got: [%s]\n", tno, str.z); - } - } - }else - { - printf("Unknown operation \"%s\" on selftest line %d\n", zOp, tno); + for(iDb=0; iDb=VOLUME_ECHO ){ + char *zQuote = sqlite3_mprintf("%q", zSql); + printf("%d: %s %s\n", tno, zOp, zSql); + sqlite3_free(zQuote); + } + if( strcmp(zOp,"memo")==0 ){ + if( eVolume>=VOLUME_LOW ){ + printf("%s: %s\n", azDb[iDb], zSql); + } + }else + if( strcmp(zOp,"sha1")==0 ){ + char zOut[44]; + rc = sha1Exec(db, zSql, zOut); + nTest++; + if( eVolume>=VOLUME_VERBOSE ){ + printf("Result: %s\n", zOut); + } + if( rc ){ + nErr++; + if( eVolume>=VOLUME_ERROR_ONLY ){ + printf("%d: error-code-%d: %s\n", tno, rc, sqlite3_errmsg(db)); + } + }else if( strcmp(zAns,zOut)!=0 ){ + nErr++; + if( eVolume>=VOLUME_ERROR_ONLY ){ + printf("%d: Expected: [%s]\n", tno, zAns); + printf("%d: Got: [%s]\n", tno, zOut); + } + } + }else + if( strcmp(zOp,"run")==0 ){ + str.n = 0; + str.z[0] = 0; + zErrMsg = 0; + rc = sqlite3_exec(db, zSql, execCallback, &str, &zErrMsg); + nTest++; + if( eVolume>=VOLUME_VERBOSE ){ + printf("Result: %s\n", str.z); + } + if( rc || zErrMsg ){ + nErr++; + if( eVolume>=VOLUME_ERROR_ONLY ){ + printf("%d: error-code-%d: %s\n", tno, rc, zErrMsg); + } + sqlite3_free(zErrMsg); + }else if( strcmp(zAns,str.z)!=0 ){ + nErr++; + if( eVolume>=VOLUME_ERROR_ONLY ){ + printf("%d: Expected: [%s]\n", tno, zAns); + printf("%d: Got: [%s]\n", tno, str.z); + } + } + }else + { + printf("Unknown operation \"%s\" on selftest line %d\n", zOp, tno); + return 1; + } + } + if( azTest!=azDefaultTest ) sqlite3_free_table(azTest); } - sqlite3_free_table(azTest); - sqlite3_close(db); if( eVolume>=VOLUME_LOW || (nErr>0 && eVolume>=VOLUME_ERROR_ONLY) ){ - printf("%d errors out of %d tests\n", nErr, nRow); + printf("%d errors out of %d tests on %d databases\n", nErr, nTest, nDb); } return nErr; } From b67e1754489a6701271868564ed4ba7e05f5ce5e Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 7 Feb 2017 20:57:00 +0000 Subject: [PATCH 1310/1484] Fix harmless compiler warnings in kvtest.c FossilOrigin-Name: db6b39937dd9d6fcd5fcc582c8dd529caad755da --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/kvtest.c | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index a37a9e38bf..2284814a6d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C The\sdbselftest\sutility\snow\sgenerates\shashes\sin\sthe\sselftest\stable\swith\s--init.\nIt\salso\saccepts\smultiple\sdatabase\sfiles\son\sthe\scommand-line. -D 2017-02-07T20:51:38.461 +C Fix\sharmless\scompiler\swarnings\sin\skvtest.c +D 2017-02-07T20:57:00.794 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc ba953c8921fc7e18333f61898007206de7e23964 @@ -904,7 +904,7 @@ F test/json101.test c0897616f32d95431f37fd291cb78742181980ac F test/json102.test bf3fe7a706d30936a76a0f7a0375e1e8e73aff5a F test/json103.test c5f6b85e69de05f6b3195f9f9d5ce9cd179099a0 F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff -F test/kvtest.c 156281b4ed688e9aabf1fbcdc5dec0487b267026 +F test/kvtest.c b9a9822dda05a1aa481215a52e2fc93cd8b22ee5 F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63 F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200 F test/like.test 0603f4fa0dad50987f70032c05800cbfa8985302 @@ -1555,7 +1555,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P cb1e83f9583bf93ce7583d9f5e97272e2d43cfb8 -R 64e5750ab44994d5b187d93e5c4a1318 +P e68829c9bbc69bf4a0dc057e0a6e977f2fac79be +R e8e95a0beaf31ff9600f2388a71f8dcd U drh -Z f3a9d081d357071c2c4fc7a23224549e +Z 62b1a410058a970df83f462c97cdf484 diff --git a/manifest.uuid b/manifest.uuid index 6596630605..473f751fff 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e68829c9bbc69bf4a0dc057e0a6e977f2fac79be \ No newline at end of file +db6b39937dd9d6fcd5fcc582c8dd529caad755da \ No newline at end of file diff --git a/test/kvtest.c b/test/kvtest.c index 77ee02a4ff..4fa733f1a7 100644 --- a/test/kvtest.c +++ b/test/kvtest.c @@ -473,13 +473,13 @@ static unsigned char *readFile(const char *zName, int *pnByte){ if( in==0 ) return 0; pBuf = sqlite3_malloc64( nIn ); if( pBuf==0 ) return 0; - nRead = fread(pBuf, nIn, 1, in); + nRead = fread(pBuf, (size_t)nIn, 1, in); fclose(in); if( nRead!=1 ){ sqlite3_free(pBuf); return 0; } - if( pnByte ) *pnByte = nIn; + if( pnByte ) *pnByte = (int)nIn; return pBuf; } From 134e527091d86f164b42a47b3777ac71a335ff18 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 7 Feb 2017 21:00:44 +0000 Subject: [PATCH 1311/1484] Fix harmless compiler warnings in dbfuzz. FossilOrigin-Name: 61242267824135a9d5438ec15e3352a2f21dc2fc --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/dbfuzz.c | 8 ++++---- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 2284814a6d..cf619e924e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\scompiler\swarnings\sin\skvtest.c -D 2017-02-07T20:57:00.794 +C Fix\sharmless\scompiler\swarnings\sin\sdbfuzz. +D 2017-02-07T21:00:44.802 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc ba953c8921fc7e18333f61898007206de7e23964 @@ -635,7 +635,7 @@ F test/ctime.test ff6c38e822459d6ca743c34901caf57740b08b54 F test/cursorhint.test 7bc346788390475e77a345da2b92270d04d35856 F test/cursorhint2.test 8457e93d97f665f23f97cdbc8477d16e3480331b F test/date.test a6a5a48b90907bca9fbcc79a30be5a715c1ab2fc -F test/dbfuzz.c 8cc2bdb818b4483a052f9f80f96be74cbd9a6e1d +F test/dbfuzz.c 73047c920d6210e5912c87cdffd9a1c281d4252e F test/dbselftest.c 4bf86fe04dc2d0d58dabc5e6b7a06fa4ef7827ea F test/dbstatus.test 73149851b3aff14fc6db478e58f9083a66422cf5 F test/dbstatus2.test e93ab03bfae6d62d4d935f20de928c19ca0ed0ab @@ -1555,7 +1555,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e68829c9bbc69bf4a0dc057e0a6e977f2fac79be -R e8e95a0beaf31ff9600f2388a71f8dcd +P db6b39937dd9d6fcd5fcc582c8dd529caad755da +R f5b20543ad5a9de57f328e5cb19dc17f U drh -Z 62b1a410058a970df83f462c97cdf484 +Z 556fccfd2bf9ea9a682f73b7b4dda1ae diff --git a/manifest.uuid b/manifest.uuid index 473f751fff..db9339c4af 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -db6b39937dd9d6fcd5fcc582c8dd529caad755da \ No newline at end of file +61242267824135a9d5438ec15e3352a2f21dc2fc \ No newline at end of file diff --git a/test/dbfuzz.c b/test/dbfuzz.c index 2de97c35cb..ca1c6ea217 100644 --- a/test/dbfuzz.c +++ b/test/dbfuzz.c @@ -458,7 +458,7 @@ static void StrAppend(Str *p, const char *z){ sqlite3_uint64 nNew; if( p->oomErr ) return; nNew = p->nAlloc*2 + 100 + n; - zNew = sqlite3_realloc(p->z, nNew); + zNew = sqlite3_realloc64(p->z, nNew); if( zNew==0 ){ sqlite3_free(p->z); memset(p, 0, sizeof(*p)); @@ -468,7 +468,7 @@ static void StrAppend(Str *p, const char *z){ p->z = zNew; p->nAlloc = nNew; } - memcpy(p->z + p->n, z, n); + memcpy(p->z + p->n, z, (int)n); p->n += n; p->z[p->n] = 0; } @@ -647,7 +647,7 @@ static void runSql(sqlite3 *db, const char *zSql, unsigned runFlags){ int main(int argc, char **argv){ int i; /* Loop counter */ int nDb = 0; /* Number of databases to fuzz */ - const char **azDb = 0; /* Names of the databases (limit: 20) */ + char **azDb = 0; /* Names of the databases (limit: 20) */ int verboseFlag = 0; /* True for extra output */ int noLookaside = 0; /* Disable lookaside if true */ int vdbeLimitFlag = 0; /* Stop after 100,000 VDBE ops */ @@ -660,7 +660,7 @@ int main(int argc, char **argv){ unsigned runFlags = 0; /* Flags passed to runSql */ for(i=1; i Date: Tue, 7 Feb 2017 21:09:34 +0000 Subject: [PATCH 1312/1484] MSVC makefile enhancments for several command line tools and the session extensions. FossilOrigin-Name: fc1dfe870279531d77ffb18a9ca4b4dcbc7aab8d --- Makefile.msc | 41 ++++++++++++++++++++++++++++------------- autoconf/Makefile.msc | 2 +- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- tool/mkmsvcmin.tcl | 2 +- tool/mksqlite3h.tcl | 12 ++++++++++-- 6 files changed, 51 insertions(+), 28 deletions(-) diff --git a/Makefile.msc b/Makefile.msc index 4a29f913c8..8b98fe4cac 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -1512,6 +1512,10 @@ FUZZERSHELL_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1 FUZZCHECK_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_OSS_FUZZ FUZZCHECK_SRC = $(TOP)\test\fuzzcheck.c $(TOP)\test\ossfuzz.c OSSSHELL_SRC = $(TOP)\test\ossshell.c $(TOP)\test\ossfuzz.c +DBFUZZ_COMPILE_OPTS = -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION +KV_COMPILE_OPTS = -DSQLITE_THREADSAFE=0 -DSQLITE_DIRECT_OVERFLOW_READ +DBSELFTEST_COMPILE_OPTS = -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_ENABLE_RTREE -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS5 +ST_COMPILE_OPTS = -DSQLITE_THREADSAFE=0 # Standard options to testfixture. # @@ -1554,7 +1558,7 @@ $(SQLITE3DLL): $(LIBOBJ) $(LIBRESOBJS) $(CORE_LINK_DEP) sqlite3.def: libsqlite3.lib echo EXPORTS > sqlite3.def dumpbin /all libsqlite3.lib \ - | $(TCLSH_CMD) $(TOP)\tool\replace.tcl include "^\s+1 _?(sqlite3_[^@]*)(?:@\d+)?$$" \1 \ + | $(TCLSH_CMD) $(TOP)\tool\replace.tcl include "^\s+1 _?(sqlite3(?:session|changeset)?_[^@]*)(?:@\d+)?$$" \1 \ | sort >> sqlite3.def # <> @@ -1581,6 +1585,9 @@ sourcetest: srcck1.exe sqlite3.c fuzzershell.exe: $(TOP)\tool\fuzzershell.c $(SQLITE3C) $(SQLITE3H) $(LTLINK) $(NO_WARN) $(FUZZERSHELL_COMPILE_OPTS) $(TOP)\tool\fuzzershell.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) +dbfuzz.exe: $(TOP)\test\dbfuzz.c $(SQLITE3C) $(SQLITE3H) + $(LTLINK) $(NO_WARN) $(DBFUZZ_COMPILE_OPTS) $(TOP)\test\dbfuzz.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) + fuzzcheck.exe: $(FUZZCHECK_SRC) $(SQLITE3C) $(SQLITE3H) $(LTLINK) $(NO_WARN) $(FUZZCHECK_COMPILE_OPTS) $(FUZZCHECK_SRC) $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) @@ -2177,46 +2184,54 @@ testloadext.dll: testloadext.lo $(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /DLL /OUT:$@ testloadext.lo showdb.exe: $(TOP)\tool\showdb.c $(SQLITE3C) $(SQLITE3H) - $(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \ + $(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \ $(TOP)\tool\showdb.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) showstat4.exe: $(TOP)\tool\showstat4.c $(SQLITE3C) $(SQLITE3H) - $(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \ + $(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \ $(TOP)\tool\showstat4.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) showjournal.exe: $(TOP)\tool\showjournal.c $(SQLITE3C) $(SQLITE3H) - $(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \ + $(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \ $(TOP)\tool\showjournal.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) showwal.exe: $(TOP)\tool\showwal.c $(SQLITE3C) $(SQLITE3H) - $(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \ + $(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \ $(TOP)\tool\showwal.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) -changeset.exe: $(TOP)\ext\session\changeset.c $(SQLITE3C) - $(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \ +changeset.exe: $(TOP)\ext\session\changeset.c $(SQLITE3C) $(SQLITE3H) + $(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \ + -DSQLITE_ENABLE_SESSION=1 -DSQLITE_ENABLE_PREUPDATE_HOOK=1 \ $(TOP)\ext\session\changeset.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) fts3view.exe: $(TOP)\ext\fts3\tool\fts3view.c $(SQLITE3C) $(SQLITE3H) - $(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \ + $(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \ $(TOP)\ext\fts3\tool\fts3view.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) rollback-test.exe: $(TOP)\tool\rollback-test.c $(SQLITE3C) $(SQLITE3H) - $(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \ + $(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \ $(TOP)\tool\rollback-test.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) LogEst.exe: $(TOP)\tool\logest.c $(SQLITE3H) - $(LTLINK) $(NO_WARN) -Fe$@ $(TOP)\tool\LogEst.c /link $(LDFLAGS) $(LTLINKOPTS) + $(LTLINK) $(NO_WARN) $(TOP)\tool\LogEst.c /link $(LDFLAGS) $(LTLINKOPTS) wordcount.exe: $(TOP)\test\wordcount.c $(SQLITE3C) $(SQLITE3H) - $(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \ + $(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \ $(TOP)\test\wordcount.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) speedtest1.exe: $(TOP)\test\speedtest1.c $(SQLITE3C) $(SQLITE3H) - $(LTLINK) $(NO_WARN) -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \ + $(LTLINK) $(NO_WARN) $(ST_COMPILE_OPTS) -DSQLITE_OMIT_LOAD_EXTENSION \ $(TOP)\test\speedtest1.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) +kvtest.exe: $(TOP)\test\kvtest.c $(SQLITE3C) $(SQLITE3H) + $(LTLINK) $(NO_WARN) $(KV_COMPILE_OPTS) \ + $(TOP)\test\kvtest.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) + +dbselftest.exe: $(TOP)\test\dbselftest.c $(SQLITE3C) $(SQLITE3H) + $(LTLINK) $(NO_WARN) $(DBSELFTEST_COMPILE_OPTS) $(TOP)\test\dbselftest.c $(SQLITE3C) + rbu.exe: $(TOP)\ext\rbu\rbu.c $(TOP)\ext\rbu\sqlite3rbu.c $(SQLITE3C) $(SQLITE3H) - $(LTLINK) $(NO_WARN) -DSQLITE_ENABLE_RBU -Fe$@ \ + $(LTLINK) $(NO_WARN) -DSQLITE_ENABLE_RBU \ $(TOP)\ext\rbu\rbu.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) moreclean: clean diff --git a/autoconf/Makefile.msc b/autoconf/Makefile.msc index 32d03dbf35..32ef1c5434 100644 --- a/autoconf/Makefile.msc +++ b/autoconf/Makefile.msc @@ -950,7 +950,7 @@ Replace.exe: sqlite3.def: Replace.exe $(LIBOBJ) echo EXPORTS > sqlite3.def dumpbin /all $(LIBOBJ) \ - | .\Replace.exe "^\s+/EXPORT:_?(sqlite3_[^@,]*)(?:@\d+|,DATA)?$$" $$1 true \ + | .\Replace.exe "^\s+/EXPORT:_?(sqlite3(?:session|changeset)?_[^@,]*)(?:@\d+|,DATA)?$$" $$1 true \ | sort >> sqlite3.def $(SQLITE3EXE): $(TOP)\shell.c $(SHELL_CORE_DEP) $(LIBRESOBJS) $(SHELL_CORE_SRC) $(SQLITE3H) diff --git a/manifest b/manifest index cf619e924e..a3e5404e7d 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -C Fix\sharmless\scompiler\swarnings\sin\sdbfuzz. -D 2017-02-07T21:00:44.802 +C MSVC\smakefile\senhancments\sfor\sseveral\scommand\sline\stools\sand\sthe\ssession\sextensions. +D 2017-02-07T21:09:34.792 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 -F Makefile.msc ba953c8921fc7e18333f61898007206de7e23964 +F Makefile.msc 067a6766f800cc8d72845ab61f8de4ffe8f3fc99 F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7 F VERSION cddd8d88dc8202afa0ebc96da61fc4acbd1e96a5 F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 @@ -11,7 +11,7 @@ F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am 1a47d071e3d5435f8f7ebff7eb6703848bbd65d4 -F autoconf/Makefile.msc 3f29e0fc2a78e113250d79a5da375c1d8d8c06b0 +F autoconf/Makefile.msc 3de603bcec5c07462801a20fd7dc1b871400af99 F autoconf/README.first 6c4f34fe115ff55d4e8dbfa3cecf04a0188292f7 F autoconf/README.txt 4f04b0819303aabaa35fff5f7b257fb0c1ef95f1 F autoconf/configure.ac cacf2616abf6e4a569bde2ef365c143caeec40bc @@ -1489,7 +1489,7 @@ F tool/logest.c 11346aa019e2e77a00902aa7d0cabd27bd2e8cca F tool/max-limits.c cbb635fbb37ae4d05f240bfb5b5270bb63c54439 F tool/mkautoconfamal.sh e855df211ecbcc7131dee817110ff386cfb112f7 F tool/mkkeywordhash.c f7f3b342211ac6a14258b9726d5b97cf4f548f22 -F tool/mkmsvcmin.tcl 2f12f7fa8858bbe61cf81820a2da96c79ed1ca8d +F tool/mkmsvcmin.tcl 95b37e202cbed873aa8ffdbb493b9db45927be2b F tool/mkopcodec.tcl d1b6362bd3aa80d5520d4d6f3765badf01f6c43c F tool/mkopcodeh.tcl a01d2c1d8a6205b03fc635adf3735b4c523befd3 F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e @@ -1497,7 +1497,7 @@ F tool/mkpragmatab.tcl ebb4bfcd2f8010e0a3934b6118db4b5f2f5edf5c F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 F tool/mksqlite3c-noext.tcl fef88397668ae83166735c41af99d79f56afaabb F tool/mksqlite3c.tcl 06b2e6a0f21cc0a5d70fbbd136b3e0a96470645e -F tool/mksqlite3h.tcl c006c4e5da57c649b24b689511dcd270dd7b0249 +F tool/mksqlite3h.tcl b9836752c3d08f9fab2dfc0017ca9fd5d90ac863 F tool/mksqlite3internalh.tcl eb994013e833359137eb53a55acdad0b5ae1049b F tool/mkvsix.tcl b9e0777a213c23156b6542842c238479e496ebf5 F tool/offsets.c fe4262fdfa378e8f5499a42136d17bf3b98f6091 @@ -1555,7 +1555,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P db6b39937dd9d6fcd5fcc582c8dd529caad755da -R f5b20543ad5a9de57f328e5cb19dc17f -U drh -Z 556fccfd2bf9ea9a682f73b7b4dda1ae +P 61242267824135a9d5438ec15e3352a2f21dc2fc +R 2db6df3e55ca3fe258c2e43d80c841d4 +U mistachkin +Z ad604e11dbe50606213e8f571c7cab8e diff --git a/manifest.uuid b/manifest.uuid index db9339c4af..4a692b1501 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -61242267824135a9d5438ec15e3352a2f21dc2fc \ No newline at end of file +fc1dfe870279531d77ffb18a9ca4b4dcbc7aab8d \ No newline at end of file diff --git a/tool/mkmsvcmin.tcl b/tool/mkmsvcmin.tcl index 88e7f9184e..bdd02be1fb 100644 --- a/tool/mkmsvcmin.tcl +++ b/tool/mkmsvcmin.tcl @@ -83,7 +83,7 @@ Replace.exe: sqlite3.def: Replace.exe $(LIBOBJ) echo EXPORTS > sqlite3.def dumpbin /all $(LIBOBJ) \\ - | .\Replace.exe "^\s+/EXPORT:_?(sqlite3_[^@,]*)(?:@\d+|,DATA)?$$" $$1 true \\ + | .\Replace.exe "^\s+/EXPORT:_?(sqlite3(?:session|changeset)?_[^@,]*)(?:@\d+|,DATA)?$$" $$1 true \\ | sort >> sqlite3.def }]] diff --git a/tool/mksqlite3h.tcl b/tool/mksqlite3h.tcl index 4f8a1fd497..9d307d1b1e 100644 --- a/tool/mksqlite3h.tcl +++ b/tool/mksqlite3h.tcl @@ -73,7 +73,13 @@ close $in # Set up patterns for recognizing API declarations. # set varpattern {^[a-zA-Z][a-zA-Z_0-9 *]+sqlite3_[_a-zA-Z0-9]+(\[|;| =)} -set declpattern {^ *([a-zA-Z][a-zA-Z_0-9 ]+ \**)(sqlite3_[_a-zA-Z0-9]+)(\(.*)$} +set declpattern1 {^ *([a-zA-Z][a-zA-Z_0-9 ]+ \**)(sqlite3_[_a-zA-Z0-9]+)(\(.*)$} + +set declpattern2 \ + {^ *([a-zA-Z][a-zA-Z_0-9 ]+ \**)(sqlite3session_[_a-zA-Z0-9]+)(\(.*)$} + +set declpattern3 \ + {^ *([a-zA-Z][a-zA-Z_0-9 ]+ \**)(sqlite3changeset_[_a-zA-Z0-9]+)(\(.*)$} # Force the output to use unix line endings, even on Windows. fconfigure stdout -translation lf @@ -121,7 +127,9 @@ foreach file $filelist { if {[regexp $varpattern $line] && ![regexp {^ *typedef} $line]} { set line "SQLITE_API $line" } else { - if {[regexp $declpattern $line all rettype funcname rest]} { + if {[regexp $declpattern1 $line all rettype funcname rest] || \ + [regexp $declpattern2 $line all rettype funcname rest] || \ + [regexp $declpattern3 $line all rettype funcname rest]} { set line SQLITE_API append line " " [string trim $rettype] if {[string index $rettype end] ne "*"} { From ec26ce33281a2ae08852d729f41fd0c1cce09a5e Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 7 Feb 2017 21:44:40 +0000 Subject: [PATCH 1313/1484] When generating the hash on the sqlite_master table in dbselftest, use an ORDER BY clause, since the sqlite_master table is reordered by VACUUM. FossilOrigin-Name: c8bfd99b96608a08f934f46b4e1a4d0f1cc69ea7 --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/dbselftest.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index a3e5404e7d..e98ee3d2a4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C MSVC\smakefile\senhancments\sfor\sseveral\scommand\sline\stools\sand\sthe\ssession\sextensions. -D 2017-02-07T21:09:34.792 +C When\sgenerating\sthe\shash\son\sthe\ssqlite_master\stable\sin\sdbselftest,\suse\san\nORDER\sBY\sclause,\ssince\sthe\ssqlite_master\stable\sis\sreordered\sby\sVACUUM. +D 2017-02-07T21:44:40.303 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 067a6766f800cc8d72845ab61f8de4ffe8f3fc99 @@ -636,7 +636,7 @@ F test/cursorhint.test 7bc346788390475e77a345da2b92270d04d35856 F test/cursorhint2.test 8457e93d97f665f23f97cdbc8477d16e3480331b F test/date.test a6a5a48b90907bca9fbcc79a30be5a715c1ab2fc F test/dbfuzz.c 73047c920d6210e5912c87cdffd9a1c281d4252e -F test/dbselftest.c 4bf86fe04dc2d0d58dabc5e6b7a06fa4ef7827ea +F test/dbselftest.c b2e6cfac59066dbcb7334b66304bb15a5508dd42 F test/dbstatus.test 73149851b3aff14fc6db478e58f9083a66422cf5 F test/dbstatus2.test e93ab03bfae6d62d4d935f20de928c19ca0ed0ab F test/default.test 0cb49b1c315a0d81c81d775e407f66906a2a604d @@ -1555,7 +1555,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 61242267824135a9d5438ec15e3352a2f21dc2fc -R 2db6df3e55ca3fe258c2e43d80c841d4 -U mistachkin -Z ad604e11dbe50606213e8f571c7cab8e +P fc1dfe870279531d77ffb18a9ca4b4dcbc7aab8d +R f274165d340f013add78e0f37722933a +U drh +Z fc92264580c9fd0c7c0e56ba0825054f diff --git a/manifest.uuid b/manifest.uuid index 4a692b1501..b6d3f806f6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fc1dfe870279531d77ffb18a9ca4b4dcbc7aab8d \ No newline at end of file +c8bfd99b96608a08f934f46b4e1a4d0f1cc69ea7 \ No newline at end of file diff --git a/test/dbselftest.c b/test/dbselftest.c index d8a9c331de..3a238bce16 100644 --- a/test/dbselftest.c +++ b/test/dbselftest.c @@ -568,7 +568,7 @@ static int buildSelftestTable(sqlite3 *db){ ); if( rc ) return 1; tno = 110; - zSql = "SELECT type,name,tbl_name,sql FROM sqlite_master"; + zSql = "SELECT type,name,tbl_name,sql FROM sqlite_master ORDER BY name"; sha1Exec(db, zSql, zHash); rc = runSql(db, "INSERT INTO selftest(tno,op,sql,ans)" From 0356ebd0a55ef92febfb8943bdf3e08542629de8 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 8 Feb 2017 12:18:05 +0000 Subject: [PATCH 1314/1484] Round up the size of all memory allocations to a multiple of 8 bytes when using the system memory allocator. FossilOrigin-Name: c46e06fab4465128ac3364bafef5fa3d016796d0 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/mem1.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index e98ee3d2a4..ee914ed3f5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C When\sgenerating\sthe\shash\son\sthe\ssqlite_master\stable\sin\sdbselftest,\suse\san\nORDER\sBY\sclause,\ssince\sthe\ssqlite_master\stable\sis\sreordered\sby\sVACUUM. -D 2017-02-07T21:44:40.303 +C Round\sup\sthe\ssize\sof\sall\smemory\sallocations\sto\sa\smultiple\sof\s8\sbytes\swhen\nusing\sthe\ssystem\smemory\sallocator. +D 2017-02-08T12:18:05.716 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 067a6766f800cc8d72845ab61f8de4ffe8f3fc99 @@ -362,7 +362,7 @@ F src/loadext.c a68d8d1d14cf7488bb29dc5311cb1ce9a4404258 F src/main.c e207b81542d13b9f13d61e78ca441f9781f055b0 F src/malloc.c fc1b9f445290f2145da48fc08730c26e6082b640 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 -F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b +F src/mem1.c d5214ba7ca6315702d4dc19c6a28c28374aabf0f F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3 F src/mem3.c 8768ac94694f31ffaf8b4d0ea5dc08af7010a35a F src/mem5.c 9bf955937b07f8c32541c8a9991f33ce3173d944 @@ -1555,7 +1555,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P fc1dfe870279531d77ffb18a9ca4b4dcbc7aab8d -R f274165d340f013add78e0f37722933a +P c8bfd99b96608a08f934f46b4e1a4d0f1cc69ea7 +R 18730fab1d81ceb35863e5f55cd414cf U drh -Z fc92264580c9fd0c7c0e56ba0825054f +Z e4ad513632515387e7941b963a76aac0 diff --git a/manifest.uuid b/manifest.uuid index b6d3f806f6..876796e051 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c8bfd99b96608a08f934f46b4e1a4d0f1cc69ea7 \ No newline at end of file +c46e06fab4465128ac3364bafef5fa3d016796d0 \ No newline at end of file diff --git a/src/mem1.c b/src/mem1.c index b960ccfd47..28055190e0 100644 --- a/src/mem1.c +++ b/src/mem1.c @@ -125,7 +125,7 @@ static malloc_zone_t* _sqliteZone_; */ static void *sqlite3MemMalloc(int nByte){ #ifdef SQLITE_MALLOCSIZE - void *p = SQLITE_MALLOC( nByte ); + void *p = SQLITE_MALLOC( ROUND8(nByte) ); if( p==0 ){ testcase( sqlite3GlobalConfig.xLog!=0 ); sqlite3_log(SQLITE_NOMEM, "failed to allocate %u bytes of memory", nByte); From 087a29c78be60f5b3c5c9718c3f1843a97781a74 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 8 Feb 2017 16:01:57 +0000 Subject: [PATCH 1315/1484] Always invoke the xRoundup() method of the memory allocator before calling xMalloc(). FossilOrigin-Name: 77b470b0df73dc5ae5ad2f0170ef7c50558c7c88 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/malloc.c | 16 ++++++++++++---- src/mem1.c | 6 ++++-- 4 files changed, 24 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index ee914ed3f5..8fb5d8e602 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Round\sup\sthe\ssize\sof\sall\smemory\sallocations\sto\sa\smultiple\sof\s8\sbytes\swhen\nusing\sthe\ssystem\smemory\sallocator. -D 2017-02-08T12:18:05.716 +C Always\sinvoke\sthe\sxRoundup()\smethod\sof\sthe\smemory\sallocator\sbefore\scalling\nxMalloc(). +D 2017-02-08T16:01:57.242 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 067a6766f800cc8d72845ab61f8de4ffe8f3fc99 @@ -360,9 +360,9 @@ F src/insert.c 444354c23d4d140a57d6eb46f34e376a7f8f62e8 F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e F src/loadext.c a68d8d1d14cf7488bb29dc5311cb1ce9a4404258 F src/main.c e207b81542d13b9f13d61e78ca441f9781f055b0 -F src/malloc.c fc1b9f445290f2145da48fc08730c26e6082b640 +F src/malloc.c dc2b84cd320e0498ef4209772d66f353df6e4eb2 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 -F src/mem1.c d5214ba7ca6315702d4dc19c6a28c28374aabf0f +F src/mem1.c fd7cd6fe21d46fe0a4186367dd8dc26d87b787eb F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3 F src/mem3.c 8768ac94694f31ffaf8b4d0ea5dc08af7010a35a F src/mem5.c 9bf955937b07f8c32541c8a9991f33ce3173d944 @@ -1555,7 +1555,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P c8bfd99b96608a08f934f46b4e1a4d0f1cc69ea7 -R 18730fab1d81ceb35863e5f55cd414cf +P c46e06fab4465128ac3364bafef5fa3d016796d0 +R 4a0a823e254c393eb2ca1b8aee7648b4 U drh -Z e4ad513632515387e7941b963a76aac0 +Z f41f90df67587790eae7117dc459eaeb diff --git a/manifest.uuid b/manifest.uuid index 876796e051..e1604708ad 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c46e06fab4465128ac3364bafef5fa3d016796d0 \ No newline at end of file +77b470b0df73dc5ae5ad2f0170ef7c50558c7c88 \ No newline at end of file diff --git a/src/malloc.c b/src/malloc.c index 0a3d891e9b..47064aafba 100644 --- a/src/malloc.c +++ b/src/malloc.c @@ -219,12 +219,20 @@ static void sqlite3MallocAlarm(int nByte){ */ static void mallocWithAlarm(int n, void **pp){ void *p; - int nFull = 0; + int nFull; assert( sqlite3_mutex_held(mem0.mutex) ); + assert( n>0 ); + + /* In Firefox (circa 2017-02-08), xRoundup is remapped to an internal + ** implementation of malloc_good_size(), which must be called in debug + ** mode and specifically when the DMD "Dark Matter Detector" is enabled + ** or else a crash results. Hence, do not attempt to optimization out + ** the following xRoundup() call. */ + nFull = sqlite3GlobalConfig.m.xRoundup(n); + sqlite3StatusHighwater(SQLITE_STATUS_MALLOC_SIZE, n); if( mem0.alarmThreshold>0 ){ sqlite3_int64 nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED); - nFull = sqlite3GlobalConfig.m.xRoundup(n); if( nUsed >= mem0.alarmThreshold - nFull ){ mem0.nearlyFull = 1; sqlite3MallocAlarm(nFull); @@ -232,11 +240,11 @@ static void mallocWithAlarm(int n, void **pp){ mem0.nearlyFull = 0; } } - p = sqlite3GlobalConfig.m.xMalloc(n); + p = sqlite3GlobalConfig.m.xMalloc(nFull); #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT if( p==0 && mem0.alarmThreshold>0 ){ sqlite3MallocAlarm(nFull); - p = sqlite3GlobalConfig.m.xMalloc(n); + p = sqlite3GlobalConfig.m.xMalloc(nFull); } #endif if( p ){ diff --git a/src/mem1.c b/src/mem1.c index 28055190e0..efc84c41d7 100644 --- a/src/mem1.c +++ b/src/mem1.c @@ -125,7 +125,9 @@ static malloc_zone_t* _sqliteZone_; */ static void *sqlite3MemMalloc(int nByte){ #ifdef SQLITE_MALLOCSIZE - void *p = SQLITE_MALLOC( ROUND8(nByte) ); + void *p; + testcase( ROUND8(nByte)==nByte ); + p = SQLITE_MALLOC( nByte ); if( p==0 ){ testcase( sqlite3GlobalConfig.xLog!=0 ); sqlite3_log(SQLITE_NOMEM, "failed to allocate %u bytes of memory", nByte); @@ -134,7 +136,7 @@ static void *sqlite3MemMalloc(int nByte){ #else sqlite3_int64 *p; assert( nByte>0 ); - nByte = ROUND8(nByte); + testcase( ROUND8(nByte)!=nByte ); p = SQLITE_MALLOC( nByte+8 ); if( p ){ p[0] = nByte; From 40b84365e41e5d1183fbcc1df6da67e611830210 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Wed, 8 Feb 2017 18:13:46 +0000 Subject: [PATCH 1316/1484] Typo fixes in comment. No changes to code. FossilOrigin-Name: c09dd5c0befaf5028abfead8114bd74a30ffe5d4 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/malloc.c | 6 +++--- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 8fb5d8e602..cbc9d6ee92 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Always\sinvoke\sthe\sxRoundup()\smethod\sof\sthe\smemory\sallocator\sbefore\scalling\nxMalloc(). -D 2017-02-08T16:01:57.242 +C Typo\sfixes\sin\scomment.\s\sNo\schanges\sto\scode. +D 2017-02-08T18:13:46.938 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 067a6766f800cc8d72845ab61f8de4ffe8f3fc99 @@ -360,7 +360,7 @@ F src/insert.c 444354c23d4d140a57d6eb46f34e376a7f8f62e8 F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e F src/loadext.c a68d8d1d14cf7488bb29dc5311cb1ce9a4404258 F src/main.c e207b81542d13b9f13d61e78ca441f9781f055b0 -F src/malloc.c dc2b84cd320e0498ef4209772d66f353df6e4eb2 +F src/malloc.c f345c60d093d6c6cf451b99a7344a123b1a70fd9 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c fd7cd6fe21d46fe0a4186367dd8dc26d87b787eb F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3 @@ -1555,7 +1555,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P c46e06fab4465128ac3364bafef5fa3d016796d0 -R 4a0a823e254c393eb2ca1b8aee7648b4 -U drh -Z f41f90df67587790eae7117dc459eaeb +P 77b470b0df73dc5ae5ad2f0170ef7c50558c7c88 +R 52473535d67a86108597185ae6d56e08 +U mistachkin +Z 77244f34774b49c249d3e5a9b6027fee diff --git a/manifest.uuid b/manifest.uuid index e1604708ad..0e6917c22f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -77b470b0df73dc5ae5ad2f0170ef7c50558c7c88 \ No newline at end of file +c09dd5c0befaf5028abfead8114bd74a30ffe5d4 \ No newline at end of file diff --git a/src/malloc.c b/src/malloc.c index 47064aafba..e7714aa103 100644 --- a/src/malloc.c +++ b/src/malloc.c @@ -223,11 +223,11 @@ static void mallocWithAlarm(int n, void **pp){ assert( sqlite3_mutex_held(mem0.mutex) ); assert( n>0 ); - /* In Firefox (circa 2017-02-08), xRoundup is remapped to an internal + /* In Firefox (circa 2017-02-08), xRoundup() is remapped to an internal ** implementation of malloc_good_size(), which must be called in debug ** mode and specifically when the DMD "Dark Matter Detector" is enabled - ** or else a crash results. Hence, do not attempt to optimization out - ** the following xRoundup() call. */ + ** or else a crash results. Hence, do not attempt to optimize out the + ** following xRoundup() call. */ nFull = sqlite3GlobalConfig.m.xRoundup(n); sqlite3StatusHighwater(SQLITE_STATUS_MALLOC_SIZE, n); From 18fdde21b8f7b484c1aa32b601b83309876c91d9 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 8 Feb 2017 19:10:47 +0000 Subject: [PATCH 1317/1484] Avoid preparing a SELECT statement each time an UPDATE or DELETE by docid is executed against an fts3 table. FossilOrigin-Name: 9962c10a5c6672bd82b2bf640d878fcdac0b815a --- ext/fts3/fts3.c | 50 +++++++++++++++++++++++++++++++++------------- ext/fts3/fts3Int.h | 2 ++ manifest | 19 ++++++++++-------- manifest.uuid | 2 +- 4 files changed, 50 insertions(+), 23 deletions(-) diff --git a/ext/fts3/fts3.c b/ext/fts3/fts3.c index c12e3d2156..7c931c42d4 100644 --- a/ext/fts3/fts3.c +++ b/ext/fts3/fts3.c @@ -492,6 +492,7 @@ static int fts3DisconnectMethod(sqlite3_vtab *pVtab){ assert( p->pSegments==0 ); /* Free any prepared statements held */ + sqlite3_finalize(p->pSeekStmt); for(i=0; iaStmt); i++){ sqlite3_finalize(p->aStmt[i]); } @@ -1680,6 +1681,26 @@ static int fts3OpenMethod(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCsr){ return SQLITE_OK; } +/* +** Finalize the statement handle at pCsr->pStmt. +** +** Or, if that statement handle is one created by fts3CursorSeekStmt(), +** and the Fts3Table.pSeekStmt slot is currently NULL, save the statement +** pointer there instead of finalizing it. +*/ +static void fts3CursorFinalizeStmt(Fts3Cursor *pCsr){ + if( pCsr->bSeekStmt ){ + Fts3Table *p = (Fts3Table *)pCsr->base.pVtab; + if( p->pSeekStmt==0 ){ + p->pSeekStmt = pCsr->pStmt; + sqlite3_reset(pCsr->pStmt); + pCsr->pStmt = 0; + } + pCsr->bSeekStmt = 0; + } + sqlite3_finalize(pCsr->pStmt); +} + /* ** Close the cursor. For additional information see the documentation ** on the xClose method of the virtual table interface. @@ -1687,7 +1708,7 @@ static int fts3OpenMethod(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCsr){ static int fts3CloseMethod(sqlite3_vtab_cursor *pCursor){ Fts3Cursor *pCsr = (Fts3Cursor *)pCursor; assert( ((Fts3Table *)pCsr->base.pVtab)->pSegments==0 ); - sqlite3_finalize(pCsr->pStmt); + fts3CursorFinalizeStmt(pCsr); sqlite3Fts3ExprFree(pCsr->pExpr); sqlite3Fts3FreeDeferredTokens(pCsr); sqlite3_free(pCsr->aDoclist); @@ -1705,20 +1726,23 @@ static int fts3CloseMethod(sqlite3_vtab_cursor *pCursor){ ** ** (or the equivalent for a content=xxx table) and set pCsr->pStmt to ** it. If an error occurs, return an SQLite error code. -** -** Otherwise, set *ppStmt to point to pCsr->pStmt and return SQLITE_OK. */ -static int fts3CursorSeekStmt(Fts3Cursor *pCsr, sqlite3_stmt **ppStmt){ +static int fts3CursorSeekStmt(Fts3Cursor *pCsr){ int rc = SQLITE_OK; if( pCsr->pStmt==0 ){ Fts3Table *p = (Fts3Table *)pCsr->base.pVtab; char *zSql; - zSql = sqlite3_mprintf("SELECT %s WHERE rowid = ?", p->zReadExprlist); - if( !zSql ) return SQLITE_NOMEM; - rc = sqlite3_prepare_v2(p->db, zSql, -1, &pCsr->pStmt, 0); - sqlite3_free(zSql); + if( p->pSeekStmt ){ + pCsr->pStmt = p->pSeekStmt; + p->pSeekStmt = 0; + }else{ + zSql = sqlite3_mprintf("SELECT %s WHERE rowid = ?", p->zReadExprlist); + if( !zSql ) return SQLITE_NOMEM; + rc = sqlite3_prepare_v2(p->db, zSql, -1, &pCsr->pStmt, 0); + sqlite3_free(zSql); + } + if( rc==SQLITE_OK ) pCsr->bSeekStmt = 1; } - *ppStmt = pCsr->pStmt; return rc; } @@ -1730,9 +1754,7 @@ static int fts3CursorSeekStmt(Fts3Cursor *pCsr, sqlite3_stmt **ppStmt){ static int fts3CursorSeek(sqlite3_context *pContext, Fts3Cursor *pCsr){ int rc = SQLITE_OK; if( pCsr->isRequireSeek ){ - sqlite3_stmt *pStmt = 0; - - rc = fts3CursorSeekStmt(pCsr, &pStmt); + rc = fts3CursorSeekStmt(pCsr); if( rc==SQLITE_OK ){ sqlite3_bind_int64(pCsr->pStmt, 1, pCsr->iPrevId); pCsr->isRequireSeek = 0; @@ -3190,7 +3212,7 @@ static int fts3FilterMethod( assert( iIdx==nVal ); /* In case the cursor has been used before, clear it now. */ - sqlite3_finalize(pCsr->pStmt); + fts3CursorFinalizeStmt(pCsr); sqlite3_free(pCsr->aDoclist); sqlite3Fts3MIBufferFree(pCsr->pMIBuffer); sqlite3Fts3ExprFree(pCsr->pExpr); @@ -3258,7 +3280,7 @@ static int fts3FilterMethod( rc = SQLITE_NOMEM; } }else if( eSearch==FTS3_DOCID_SEARCH ){ - rc = fts3CursorSeekStmt(pCsr, &pCsr->pStmt); + rc = fts3CursorSeekStmt(pCsr); if( rc==SQLITE_OK ){ rc = sqlite3_bind_value(pCsr->pStmt, 1, pCons); } diff --git a/ext/fts3/fts3Int.h b/ext/fts3/fts3Int.h index 0c86c4217e..c3cab9d821 100644 --- a/ext/fts3/fts3Int.h +++ b/ext/fts3/fts3Int.h @@ -230,6 +230,7 @@ struct Fts3Table { ** statements is run and reset within a single virtual table API call. */ sqlite3_stmt *aStmt[40]; + sqlite3_stmt *pSeekStmt; /* Cache for fts3CursorSeekStmt() */ char *zReadExprlist; char *zWriteExprlist; @@ -299,6 +300,7 @@ struct Fts3Cursor { i16 eSearch; /* Search strategy (see below) */ u8 isEof; /* True if at End Of Results */ u8 isRequireSeek; /* True if must seek pStmt to %_content row */ + u8 bSeekStmt; /* True if pStmt is a seek */ sqlite3_stmt *pStmt; /* Prepared statement in use by the cursor */ Fts3Expr *pExpr; /* Parsed MATCH query string */ int iLangid; /* Language being queried for */ diff --git a/manifest b/manifest index cbc9d6ee92..ebac74811d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Typo\sfixes\sin\scomment.\s\sNo\schanges\sto\scode. -D 2017-02-08T18:13:46.938 +C Avoid\spreparing\sa\sSELECT\sstatement\seach\stime\san\sUPDATE\sor\sDELETE\nby\sdocid\sis\sexecuted\sagainst\san\sfts3\stable. +D 2017-02-08T19:10:47.175 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 067a6766f800cc8d72845ab61f8de4ffe8f3fc99 @@ -70,9 +70,9 @@ 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 5a8cafedffd101e9946f8909ecf8d34aaa383b4d +F ext/fts3/fts3.c c4d7eecb12de9749851bcab6e5ca616a5803047a F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe -F ext/fts3/fts3Int.h 89d0bd4595a0de384dac78e94b803de12586e8dd +F ext/fts3/fts3Int.h eb2502000148e80913b965db3e59f29251266d0a F ext/fts3/fts3_aux.c 9edc3655fcb287f0467d0a4b886a01c6185fe9f1 F ext/fts3/fts3_expr.c dfd571a24412779ac01f25c01d888c6ef7b2d0ef F ext/fts3/fts3_hash.c 29b986e43f4e9dd40110eafa377dc0d63c422c60 @@ -1555,7 +1555,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 77b470b0df73dc5ae5ad2f0170ef7c50558c7c88 -R 52473535d67a86108597185ae6d56e08 -U mistachkin -Z 77244f34774b49c249d3e5a9b6027fee +P c09dd5c0befaf5028abfead8114bd74a30ffe5d4 +R fbd7643b7e0c4a3c885d2a6aeb5fecfa +T *branch * fts3-seekstmt-cache +T *sym-fts3-seekstmt-cache * +T -sym-trunk * +U dan +Z dc34c96dc2a3bdce03fc410bb45d9619 diff --git a/manifest.uuid b/manifest.uuid index 0e6917c22f..a8184cc911 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c09dd5c0befaf5028abfead8114bd74a30ffe5d4 \ No newline at end of file +9962c10a5c6672bd82b2bf640d878fcdac0b815a \ No newline at end of file From a39284bfa879ef817476854c16ed5a45ec2a1def Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 9 Feb 2017 17:12:22 +0000 Subject: [PATCH 1318/1484] Cleanup the usage of the SQLITE_DISABLE_INTRINSIC compile-time option. Remove the SQLITE_RUNTIME_BYTEORDER compile-time option. Use -DSQLITE_BYTEORDER=0 instead. Fix a bug in R-Tree that occurs when compiling on a known little-endian machine without the use of intrinsic byteswapping functions. FossilOrigin-Name: 798fb9d70d2e5f95e64237b04d6692360133381a --- ext/rtree/rtree.c | 23 +++++++++-------------- manifest | 22 +++++++++++----------- manifest.uuid | 2 +- src/btreeInt.h | 6 ++---- src/mutex_w32.c | 3 +-- src/sqliteInt.h | 48 +++++++++++++++++++++++++++++------------------ src/util.c | 21 +++++++-------------- 7 files changed, 61 insertions(+), 64 deletions(-) diff --git a/ext/rtree/rtree.c b/ext/rtree/rtree.c index 1e3e65ecc9..205939ddc6 100644 --- a/ext/rtree/rtree.c +++ b/ext/rtree/rtree.c @@ -370,7 +370,7 @@ struct RtreeMatchArg { /* What version of GCC is being used. 0 means GCC is not being used */ #ifndef GCC_VERSION -#ifdef __GNUC__ +#if defined(__GNUC__) && !defined(SQLITE_DISABLE_INTRINSIC) # define GCC_VERSION (__GNUC__*1000000+__GNUC_MINOR__*1000+__GNUC_PATCHLEVEL__) #else # define GCC_VERSION 0 @@ -379,7 +379,7 @@ struct RtreeMatchArg { /* What version of CLANG is being used. 0 means CLANG is not being used */ #ifndef CLANG_VERSION -#if defined(__clang__) && !defined(_WIN32) +#if defined(__clang__) && !defined(_WIN32) && !defined(SQLITE_DISABLE_INTRINSIC) # define CLANG_VERSION \ (__clang_major__*1000000+__clang_minor__*1000+__clang_patchlevel__) #else @@ -404,13 +404,12 @@ struct RtreeMatchArg { ** at run-time. */ #ifndef SQLITE_BYTEORDER -#if (defined(i386) || defined(__i386__) || defined(_M_IX86) || \ - defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \ - defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) || \ - defined(__arm__)) && !defined(SQLITE_RUNTIME_BYTEORDER) +#if defined(i386) || defined(__i386__) || defined(_M_IX86) || \ + defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \ + defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) || \ + defined(__arm__) # define SQLITE_BYTEORDER 1234 -#elif (defined(sparc) || defined(__ppc__)) \ - && !defined(SQLITE_RUNTIME_BYTEORDER) +#elif defined(sparc) || defined(__ppc__) # define SQLITE_BYTEORDER 4321 #else # define SQLITE_BYTEORDER 0 /* 0 means "unknown at compile-time" */ @@ -420,7 +419,7 @@ struct RtreeMatchArg { /* What version of MSVC is being used. 0 means MSVC is not being used */ #ifndef MSVC_VERSION -#if defined(_MSC_VER) +#if defined(_MSC_VER) && !defined(SQLITE_DISABLE_INTRINSIC) # define MSVC_VERSION _MSC_VER #else # define MSVC_VERSION 0 @@ -440,9 +439,6 @@ static void readCoord(u8 *p, RtreeCoord *pCoord){ pCoord->u = _byteswap_ulong(*(u32*)p); #elif SQLITE_BYTEORDER==1234 && (GCC_VERSION>=4003000 || CLANG_VERSION>=3000000) pCoord->u = __builtin_bswap32(*(u32*)p); -#elif SQLITE_BYTEORDER==1234 - pCoord->u = ((pCoord->u>>24)&0xff)|((pCoord->u>>8)&0xff00)| - ((pCoord->u&0xff)<<24)|((pCoord->u&0xff00)<<8); #elif SQLITE_BYTEORDER==4321 pCoord->u = *(u32*)p; #else @@ -486,10 +482,9 @@ static i64 readInt64(u8 *p){ ** 64 bit integer. The value returned is the number of bytes written ** to the argument buffer (always 2, 4 and 8 respectively). */ -static int writeInt16(u8 *p, int i){ +static void writeInt16(u8 *p, int i){ p[0] = (i>> 8)&0xFF; p[1] = (i>> 0)&0xFF; - return 2; } static int writeCoord(u8 *p, RtreeCoord *pCoord){ u32 i; diff --git a/manifest b/manifest index 5f267df71a..3dd0a8d9c4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\spreparing\sa\sSELECT\sstatement\seach\stime\san\sUPDATE\sor\sDELETE\sby\sdocid\sis\nexecuted\sagainst\san\sfts3\stable. -D 2017-02-08T19:12:36.968 +C Cleanup\sthe\susage\sof\sthe\sSQLITE_DISABLE_INTRINSIC\scompile-time\soption.\nRemove\sthe\sSQLITE_RUNTIME_BYTEORDER\scompile-time\soption.\s\sUse\n-DSQLITE_BYTEORDER=0\sinstead.\s\sFix\sa\sbug\sin\sR-Tree\sthat\soccurs\swhen\scompiling\non\sa\sknown\slittle-endian\smachine\swithout\sthe\suse\sof\sintrinsic\sbyteswapping\nfunctions. +D 2017-02-09T17:12:22.122 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 067a6766f800cc8d72845ab61f8de4ffe8f3fc99 @@ -264,7 +264,7 @@ F ext/rbu/sqlite3rbu.c bb0de6cdbdb14a7d55a097238a434b7e99caf318 F ext/rbu/sqlite3rbu.h 6fb6294c34a9ca93b5894a33bca530c6f08decba F ext/rbu/test_rbu.c 5aa22616afac6f71ebd3d9bc9bf1006cfabcca88 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 -F ext/rtree/rtree.c d92be99e3a662e1934658201f0fc7ad51b44325a +F ext/rtree/rtree.c 358796a385de74e40ed66c103df77ba3c2e98fab F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e F ext/rtree/rtree1.test 42dadfc7b44a436cd74a1bebc0b9b689e4eaf7ec F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba @@ -339,7 +339,7 @@ F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca F src/btree.c 9fe65ab418d99e80289f024016b5e5e74c3059dd F src/btree.h e6d352808956ec163a17f832193a3e198b3fb0ac -F src/btreeInt.h 10c4b77c2fb399580babbcc7cf652ac10dba796e +F src/btreeInt.h 429bbfebae05ab3beb1c4508ba94c292036c660f F src/build.c 9e799f1edd910dfa8a0bc29bd390d35d310596af F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e @@ -372,7 +372,7 @@ F src/mutex.c 8e45800ee78e0cd1f1f3fe8e398853307f4a085c F src/mutex.h 779d588e3b7756ec3ecf7d78cde1d84aba414f85 F src/mutex_noop.c 9d4309c075ba9cc7249e19412d3d62f7f94839c4 F src/mutex_unix.c 27bb6cc49485ee46711a6580ab7b3f1402211d23 -F src/mutex_w32.c 5e6fe1c298fb5a8a15aaed4161d5759311431c17 +F src/mutex_w32.c 00bbf37d80fb763a8159b83cc3cbde0f91d37f7b F src/notify.c 9711a7575036f0d3040ba61bc6e217f13a9888e7 F src/os.c add02933b1dce7a39a005b00a2f5364b763e9a24 F src/os.h 8e976e59eb4ca1c0fca6d35ee803e38951cb0343 @@ -399,7 +399,7 @@ F src/shell.c a84e453c213f3e0d6935a582024da4e242f85a19 F src/sqlite.h.in 751ff125eb159c8f92c182b8df980a5e4f50e966 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae -F src/sqliteInt.h 3724c48e82605b471bbf7e41109b5850c6e89f31 +F src/sqliteInt.h 4dc66ec1948765f151899333f7a55267d807d099 F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 @@ -459,7 +459,7 @@ F src/treeview.c 4e44ade3bfe59d82005039f72e09333ce2b4162c F src/trigger.c c9f0810043b265724fdb1bdd466894f984dfc182 F src/update.c 456d4a4656f8a03c2abc88a51b19172197400e58 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c -F src/util.c a88b0466fddf445ce752226d4698ca3faada620a +F src/util.c 3d2ce209a89b95cf35bffa16440f57368576e2ee F src/vacuum.c 33c174b28886b2faf26e503b5a49a1c01a9b1c16 F src/vdbe.c e7b1e860140f1d1803c6f4176b1e8f3801f3a290 F src/vdbe.h 59998ffd71d7caa8886bc78dafaf8caeccd4c13c @@ -1555,7 +1555,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P c09dd5c0befaf5028abfead8114bd74a30ffe5d4 9962c10a5c6672bd82b2bf640d878fcdac0b815a -R fbd7643b7e0c4a3c885d2a6aeb5fecfa -U dan -Z a7e2195607498eebba62ce2716ddc0de +P 1afec5758b624e6a066d4e7ef50695095e9d7ff1 +R d99a1e96a3817ca7543fc882a1f70881 +U drh +Z 871c0b5ab0829dba2d37da91622734c8 diff --git a/manifest.uuid b/manifest.uuid index 6a403cde77..afdafcf9aa 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1afec5758b624e6a066d4e7ef50695095e9d7ff1 \ No newline at end of file +798fb9d70d2e5f95e64237b04d6692360133381a \ No newline at end of file diff --git a/src/btreeInt.h b/src/btreeInt.h index fc2182b634..0d79edd639 100644 --- a/src/btreeInt.h +++ b/src/btreeInt.h @@ -692,11 +692,9 @@ struct IntegrityCk { */ #if SQLITE_BYTEORDER==4321 # define get2byteAligned(x) (*(u16*)(x)) -#elif SQLITE_BYTEORDER==1234 && !defined(SQLITE_DISABLE_INTRINSIC) \ - && GCC_VERSION>=4008000 +#elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4008000 # define get2byteAligned(x) __builtin_bswap16(*(u16*)(x)) -#elif SQLITE_BYTEORDER==1234 && !defined(SQLITE_DISABLE_INTRINSIC) \ - && defined(_MSC_VER) && _MSC_VER>=1300 +#elif SQLITE_BYTEORDER==1234 && MSCV_VERSION>=1300 # define get2byteAligned(x) _byteswap_ushort(*(u16*)(x)) #else # define get2byteAligned(x) ((x)[0]<<8 | (x)[1]) diff --git a/src/mutex_w32.c b/src/mutex_w32.c index 9570bdc0bf..e0bdf9e43b 100644 --- a/src/mutex_w32.c +++ b/src/mutex_w32.c @@ -87,8 +87,7 @@ void sqlite3MemoryBarrier(void){ SQLITE_MEMORY_BARRIER; #elif defined(__GNUC__) __sync_synchronize(); -#elif !defined(SQLITE_DISABLE_INTRINSIC) && \ - defined(_MSC_VER) && _MSC_VER>=1300 +#elif MSCV_VERSION>=1300 _ReadWriteBarrier(); #elif defined(MemoryBarrier) MemoryBarrier(); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 3faf9d3982..f9768895ae 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -103,20 +103,28 @@ # define _LARGEFILE_SOURCE 1 #endif -/* What version of GCC is being used. 0 means GCC is not being used */ -#ifdef __GNUC__ +/* The GCC_VERSION, CLANG_VERSION, and MSVC_VERSION macros are used to +** conditionally include optimizations for each of these compilers. A +** value of 0 means that compiler is not being used. The +** SQLITE_DISABLE_INTRINSIC macro means do not use any compiler-specific +** optimizations, and hence set all compiler macros to 0 +*/ +#if defined(__GNUC__) && !defined(SQLITE_DISABLE_INTRINSIC) # define GCC_VERSION (__GNUC__*1000000+__GNUC_MINOR__*1000+__GNUC_PATCHLEVEL__) #else # define GCC_VERSION 0 #endif - -/* What version of CLANG is being used. 0 means CLANG is not being used */ -#if defined(__clang__) && !defined(_WIN32) +#if defined(__clang__) && !defined(_WIN32) && !defined(SQLITE_DISABLE_INTRINSIC) # define CLANG_VERSION \ (__clang_major__*1000000+__clang_minor__*1000+__clang_patchlevel__) #else # define CLANG_VERSION 0 #endif +#if defined(_MSC_VER) && !defined(SQLITE_DISABLE_INTRINSIC) +# define MSVC_VERSION _MSC_VER +#else +# define MSVC_VERSION 0 +#endif /* Needed for various definitions... */ #if defined(__GNUC__) && !defined(_GNU_SOURCE) @@ -247,6 +255,7 @@ # include # pragma intrinsic(_byteswap_ushort) # pragma intrinsic(_byteswap_ulong) +# pragma intrinsic(_byteswap_uint64) # pragma intrinsic(_ReadWriteBarrier) # else # include @@ -787,32 +796,35 @@ typedef INT16_TYPE LogEst; ** ** For best performance, an attempt is made to guess at the byte-order ** using C-preprocessor macros. If that is unsuccessful, or if -** -DSQLITE_RUNTIME_BYTEORDER=1 is set, then byte-order is determined +** -DSQLITE_BYTEORDER=0 is set, then byte-order is determined ** at run-time. */ -#if (defined(i386) || defined(__i386__) || defined(_M_IX86) || \ +#ifndef SQLITE_BYTEORDER +# if defined(i386) || defined(__i386__) || defined(_M_IX86) || \ defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \ defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) || \ - defined(__arm__)) && !defined(SQLITE_RUNTIME_BYTEORDER) -# define SQLITE_BYTEORDER 1234 -# define SQLITE_BIGENDIAN 0 -# define SQLITE_LITTLEENDIAN 1 -# define SQLITE_UTF16NATIVE SQLITE_UTF16LE + defined(__arm__) +# define SQLITE_BYTEORDER 1234 +# elif defined(sparc) || defined(__ppc__) +# define SQLITE_BYTEORDER 4321 +# else +# define SQLITE_BYTEORDER 0 +# endif #endif -#if (defined(sparc) || defined(__ppc__)) \ - && !defined(SQLITE_RUNTIME_BYTEORDER) -# define SQLITE_BYTEORDER 4321 +#if SQLITE_BYTEORDER==4321 # define SQLITE_BIGENDIAN 1 # define SQLITE_LITTLEENDIAN 0 # define SQLITE_UTF16NATIVE SQLITE_UTF16BE -#endif -#if !defined(SQLITE_BYTEORDER) +#elif SQLITE_BYTEORDER==1234 +# define SQLITE_BIGENDIAN 0 +# define SQLITE_LITTLEENDIAN 1 +# define SQLITE_UTF16NATIVE SQLITE_UTF16LE +#else # ifdef SQLITE_AMALGAMATION const int sqlite3one = 1; # else extern const int sqlite3one; # endif -# define SQLITE_BYTEORDER 0 /* 0 means "unknown at compile-time" */ # define SQLITE_BIGENDIAN (*(char *)(&sqlite3one)==0) # define SQLITE_LITTLEENDIAN (*(char *)(&sqlite3one)==1) # define SQLITE_UTF16NATIVE (SQLITE_BIGENDIAN?SQLITE_UTF16BE:SQLITE_UTF16LE) diff --git a/src/util.c b/src/util.c index ca14ab8526..c6d2bae3a7 100644 --- a/src/util.c +++ b/src/util.c @@ -1140,13 +1140,11 @@ u32 sqlite3Get4byte(const u8 *p){ u32 x; memcpy(&x,p,4); return x; -#elif SQLITE_BYTEORDER==1234 && !defined(SQLITE_DISABLE_INTRINSIC) \ - && (GCC_VERSION>=4003000 || CLANG_VERSION>=3000000) +#elif SQLITE_BYTEORDER==1234 && (GCC_VERSION>=4003000 || CLANG_VERSION>=3000000) u32 x; memcpy(&x,p,4); return __builtin_bswap32(x); -#elif SQLITE_BYTEORDER==1234 && !defined(SQLITE_DISABLE_INTRINSIC) \ - && defined(_MSC_VER) && _MSC_VER>=1300 +#elif SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300 u32 x; memcpy(&x,p,4); return _byteswap_ulong(x); @@ -1158,12 +1156,10 @@ u32 sqlite3Get4byte(const u8 *p){ void sqlite3Put4byte(unsigned char *p, u32 v){ #if SQLITE_BYTEORDER==4321 memcpy(p,&v,4); -#elif SQLITE_BYTEORDER==1234 && !defined(SQLITE_DISABLE_INTRINSIC) \ - && (GCC_VERSION>=4003000 || CLANG_VERSION>=3000000) +#elif SQLITE_BYTEORDER==1234 && (GCC_VERSION>=4003000 || CLANG_VERSION>=3000000) u32 x = __builtin_bswap32(v); memcpy(p,&x,4); -#elif SQLITE_BYTEORDER==1234 && !defined(SQLITE_DISABLE_INTRINSIC) \ - && defined(_MSC_VER) && _MSC_VER>=1300 +#elif SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300 u32 x = _byteswap_ulong(v); memcpy(p,&x,4); #else @@ -1279,8 +1275,7 @@ int sqlite3SafetyCheckSickOrOk(sqlite3 *db){ ** overflow, leave *pA unchanged and return 1. */ int sqlite3AddInt64(i64 *pA, i64 iB){ -#if !defined(SQLITE_DISABLE_INTRINSIC) \ - && (GCC_VERSION>=5004000 || CLANG_VERSION>=4000000) +#if GCC_VERSION>=5004000 || CLANG_VERSION>=4000000 return __builtin_add_overflow(*pA, iB, pA); #else i64 iA = *pA; @@ -1300,8 +1295,7 @@ int sqlite3AddInt64(i64 *pA, i64 iB){ #endif } int sqlite3SubInt64(i64 *pA, i64 iB){ -#if !defined(SQLITE_DISABLE_INTRINSIC) \ - && (GCC_VERSION>=5004000 || CLANG_VERSION>=4000000) +#if GCC_VERSION>=5004000 || CLANG_VERSION>=4000000 return __builtin_sub_overflow(*pA, iB, pA); #else testcase( iB==SMALLEST_INT64+1 ); @@ -1316,8 +1310,7 @@ int sqlite3SubInt64(i64 *pA, i64 iB){ #endif } int sqlite3MulInt64(i64 *pA, i64 iB){ -#if !defined(SQLITE_DISABLE_INTRINSIC) \ - && (GCC_VERSION>=5004000 || CLANG_VERSION>=4000000) +#if GCC_VERSION>=5004000 || CLANG_VERSION>=4000000 return __builtin_mul_overflow(*pA, iB, pA); #else i64 iA = *pA; From 2c338a9d9ad1f05269a4d44e5bf9fdaeac51a95c Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 10 Feb 2017 19:38:36 +0000 Subject: [PATCH 1319/1484] Add the "," flag to printf(). FossilOrigin-Name: 064445b12f99f76e9a12957be97edd520ab3ae27 --- manifest | 14 +++---- manifest.uuid | 2 +- src/printf.c | 97 +++++++++++++++++++++++++++-------------------- test/printf2.test | 31 +++++++++++++++ 4 files changed, 94 insertions(+), 50 deletions(-) diff --git a/manifest b/manifest index 3dd0a8d9c4..53d7e16ed6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Cleanup\sthe\susage\sof\sthe\sSQLITE_DISABLE_INTRINSIC\scompile-time\soption.\nRemove\sthe\sSQLITE_RUNTIME_BYTEORDER\scompile-time\soption.\s\sUse\n-DSQLITE_BYTEORDER=0\sinstead.\s\sFix\sa\sbug\sin\sR-Tree\sthat\soccurs\swhen\scompiling\non\sa\sknown\slittle-endian\smachine\swithout\sthe\suse\sof\sintrinsic\sbyteswapping\nfunctions. -D 2017-02-09T17:12:22.122 +C Add\sthe\s","\sflag\sto\sprintf(). +D 2017-02-10T19:38:36.506 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 067a6766f800cc8d72845ab61f8de4ffe8f3fc99 @@ -390,7 +390,7 @@ F src/pcache1.c e3967219b2a92b9edcb9324a4ba75009090d3953 F src/pragma.c 7831956012f5d764761fbd023e59b0ffc08f5e8d F src/pragma.h 61aa5389118594bebb28120a6720401aee34ce1a F src/prepare.c b1140c3d0cf59bc85ace00ce363153041b424b7a -F src/printf.c ff10a9b9902cd2afe5f655f3013c6307d969b1fd +F src/printf.c 67427bbee66d891fc6f6f5aada857e9cdb368c1c F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c f9bc0de45a30a450da47b3766de00be89bf9be79 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac @@ -1021,7 +1021,7 @@ F test/pragma2.test e5d5c176360c321344249354c0c16aec46214c9f F test/pragma3.test 14c12bc5352b1e100e0b6b44f371053a81ccf8ed F test/pragma4.test 6e85b6eab8e61ffc9c7db59d842276674e8e3264 F test/printf.test b3ff34e73d59124140eaf89f7672e21bc2ca5fcc -F test/printf2.test 0b61566dd1c0f0b802f59dffa228c5dc5aa6b054 +F test/printf2.test 9e6db85f81c63f2367c34a9d7db384088bd374ad F test/progress.test ebab27f670bd0d4eb9d20d49cef96e68141d92fb F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc F test/queryonly.test 5f653159e0f552f0552d43259890c1089391dcca @@ -1555,7 +1555,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 1afec5758b624e6a066d4e7ef50695095e9d7ff1 -R d99a1e96a3817ca7543fc882a1f70881 +P 798fb9d70d2e5f95e64237b04d6692360133381a +R c3dc7f748658995c87bb25e10706fab3 U drh -Z 871c0b5ab0829dba2d37da91622734c8 +Z 3add84968b9ef1dfcf3d7b3eaefd30ad diff --git a/manifest.uuid b/manifest.uuid index afdafcf9aa..8090b2db36 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -798fb9d70d2e5f95e64237b04d6692360133381a \ No newline at end of file +064445b12f99f76e9a12957be97edd520ab3ae27 \ No newline at end of file diff --git a/src/printf.c b/src/printf.c index ede86f1208..241338b266 100644 --- a/src/printf.c +++ b/src/printf.c @@ -15,7 +15,7 @@ ** Conversion types fall into various categories as defined by the ** following enumeration. */ -#define etRADIX 0 /* Integer types. %d, %x, %o, and so forth */ +#define etRADIX 0 /* non-decimal integer types. %x %o */ #define etFLOAT 1 /* Floating point. %f */ #define etEXP 2 /* Exponentional notation. %e and %E */ #define etGENERIC 3 /* Floating or exponential, depending on exponent. %g */ @@ -33,8 +33,9 @@ #define etPOINTER 13 /* The %p conversion */ #define etSQLESCAPE3 14 /* %w -> Strings with '\"' doubled */ #define etORDINAL 15 /* %r -> 1st, 2nd, 3rd, 4th, etc. English only */ +#define etDECIMAL 16 /* %d or %u, but not %x, %o */ -#define etINVALID 16 /* Any unrecognized conversion type */ +#define etINVALID 17 /* Any unrecognized conversion type */ /* @@ -58,8 +59,8 @@ typedef struct et_info { /* Information about each format field */ /* ** Allowed values for et_info.flags */ -#define FLAG_SIGNED 1 /* True if the value to convert is signed */ -#define FLAG_STRING 4 /* Allow infinity precision */ +#define FLAG_SIGNED 1 /* True if the value to convert is signed */ +#define FLAG_STRING 4 /* Allow infinite precision */ /* @@ -69,7 +70,7 @@ typedef struct et_info { /* Information about each format field */ static const char aDigits[] = "0123456789ABCDEF0123456789abcdef"; static const char aPrefix[] = "-x0\000X0"; static const et_info fmtinfo[] = { - { 'd', 10, 1, etRADIX, 0, 0 }, + { 'd', 10, 1, etDECIMAL, 0, 0 }, { 's', 0, 4, etSTRING, 0, 0 }, { 'g', 0, 1, etGENERIC, 30, 0 }, { 'z', 0, 4, etDYNSTRING, 0, 0 }, @@ -78,7 +79,7 @@ static const et_info fmtinfo[] = { { 'w', 0, 4, etSQLESCAPE3, 0, 0 }, { 'c', 0, 0, etCHARX, 0, 0 }, { 'o', 8, 0, etRADIX, 0, 2 }, - { 'u', 10, 0, etRADIX, 0, 0 }, + { 'u', 10, 0, etDECIMAL, 0, 0 }, { 'x', 16, 0, etRADIX, 16, 1 }, { 'X', 16, 0, etRADIX, 0, 4 }, #ifndef SQLITE_OMIT_FLOATING_POINT @@ -87,7 +88,7 @@ static const et_info fmtinfo[] = { { 'E', 0, 1, etEXP, 14, 0 }, { 'G', 0, 1, etGENERIC, 14, 0 }, #endif - { 'i', 10, 1, etRADIX, 0, 0 }, + { 'i', 10, 1, etDECIMAL, 0, 0 }, { 'n', 0, 0, etSIZE, 0, 0 }, { '%', 0, 0, etPERCENT, 0, 0 }, { 'p', 16, 0, etPOINTER, 0, 1 }, @@ -179,14 +180,13 @@ void sqlite3VXPrintf( int idx; /* A general purpose loop counter */ int width; /* Width of the current field */ etByte flag_leftjustify; /* True if "-" flag is present */ - etByte flag_plussign; /* True if "+" flag is present */ - etByte flag_blanksign; /* True if " " flag is present */ + etByte flag_prefix; /* '+' or ' ' or 0 for prefix */ etByte flag_alternateform; /* True if "#" flag is present */ etByte flag_altform2; /* True if "!" flag is present */ etByte flag_zeropad; /* True if field width constant starts with zero */ - etByte flag_long; /* True if "l" flag is present */ - etByte flag_longlong; /* True if the "ll" flag is present */ + etByte flag_long; /* 1 for the "l" flag, 2 for "ll", 0 by default */ etByte done; /* Loop termination flag */ + etByte cThousand; /* Thousands separator for %d and %u */ etByte xtype = etINVALID; /* Conversion paradigm */ u8 bArgList; /* True for SQLITE_PRINTF_SQLFUNC */ char prefix; /* Prefix character. "+" or "-" or " " or '\0'. */ @@ -229,17 +229,18 @@ void sqlite3VXPrintf( break; } /* Find out what flags are present */ - flag_leftjustify = flag_plussign = flag_blanksign = + flag_leftjustify = flag_prefix = cThousand = flag_alternateform = flag_altform2 = flag_zeropad = 0; done = 0; do{ switch( c ){ case '-': flag_leftjustify = 1; break; - case '+': flag_plussign = 1; break; - case ' ': flag_blanksign = 1; break; + case '+': flag_prefix = '+'; break; + case ' ': flag_prefix = ' '; break; case '#': flag_alternateform = 1; break; case '!': flag_altform2 = 1; break; case '0': flag_zeropad = 1; break; + case ',': cThousand = ','; break; default: done = 1; break; } }while( !done && (c=(*++fmt))!=0 ); @@ -309,13 +310,11 @@ void sqlite3VXPrintf( flag_long = 1; c = *++fmt; if( c=='l' ){ - flag_longlong = 1; + flag_long = 2; c = *++fmt; - }else{ - flag_longlong = 0; } }else{ - flag_long = flag_longlong = 0; + flag_long = 0; } /* Fetch the info entry for the field */ infop = &fmtinfo[0]; @@ -333,15 +332,11 @@ void sqlite3VXPrintf( ** ** flag_alternateform TRUE if a '#' is present. ** flag_altform2 TRUE if a '!' is present. - ** flag_plussign TRUE if a '+' is present. + ** flag_prefix '+' or ' ' or zero ** flag_leftjustify TRUE if a '-' is present or if the ** field width was negative. ** flag_zeropad TRUE if the width began with 0. - ** flag_long TRUE if the letter 'l' (ell) prefixed - ** the conversion character. - ** flag_longlong TRUE if the letter 'll' (ell ell) prefixed - ** the conversion character. - ** flag_blanksign TRUE if a ' ' is present. + ** flag_long 1 for "l", 2 for "ll" ** width The specified field width. This is ** always non-negative. Zero is the default. ** precision The specified precision. The default @@ -351,19 +346,24 @@ void sqlite3VXPrintf( */ switch( xtype ){ case etPOINTER: - flag_longlong = sizeof(char*)==sizeof(i64); - flag_long = sizeof(char*)==sizeof(long int); + flag_long = sizeof(char*)==sizeof(i64) ? 2 : + sizeof(char*)==sizeof(long int) ? 1 : 0; /* Fall through into the next case */ case etORDINAL: - case etRADIX: + case etRADIX: + cThousand = 0; + /* Fall through into the next case */ + case etDECIMAL: if( infop->flags & FLAG_SIGNED ){ i64 v; if( bArgList ){ v = getIntArg(pArgList); - }else if( flag_longlong ){ - v = va_arg(ap,i64); }else if( flag_long ){ - v = va_arg(ap,long int); + if( flag_long==2 ){ + v = va_arg(ap,i64) ; + }else{ + v = va_arg(ap,long int); + } }else{ v = va_arg(ap,int); } @@ -376,17 +376,17 @@ void sqlite3VXPrintf( prefix = '-'; }else{ longvalue = v; - if( flag_plussign ) prefix = '+'; - else if( flag_blanksign ) prefix = ' '; - else prefix = 0; + prefix = flag_prefix; } }else{ if( bArgList ){ longvalue = (u64)getIntArg(pArgList); - }else if( flag_longlong ){ - longvalue = va_arg(ap,u64); }else if( flag_long ){ - longvalue = va_arg(ap,unsigned long int); + if( flag_long==2 ){ + longvalue = va_arg(ap,u64); + }else{ + longvalue = va_arg(ap,unsigned long int); + } }else{ longvalue = va_arg(ap,unsigned int); } @@ -396,11 +396,11 @@ void sqlite3VXPrintf( if( flag_zeropad && precision0 ); } length = (int)(&zOut[nOut-1]-bufpt); - for(idx=precision-length; idx>0; idx--){ + while( precision>length ){ *(--bufpt) = '0'; /* Zero pad */ + length++; + } + if( cThousand ){ + int nn = (length - 1)/3; /* Number of "," to insert */ + int ix = (length - 1)%3 + 1; + bufpt -= nn; + for(idx=0; nn>0; idx++){ + bufpt[idx] = bufpt[idx+nn]; + ix--; + if( ix==0 ){ + bufpt[++idx] = cThousand; + nn--; + ix = 3; + } + } } if( prefix ) *(--bufpt) = prefix; /* Add sign */ if( flag_alternateform && infop->prefix ){ /* Add "0" or "0x" */ @@ -454,9 +469,7 @@ void sqlite3VXPrintf( realvalue = -realvalue; prefix = '-'; }else{ - if( flag_plussign ) prefix = '+'; - else if( flag_blanksign ) prefix = ' '; - else prefix = 0; + prefix = flag_prefix; } if( xtype==etGENERIC && precision>0 ) precision--; testcase( precision>0xfff ); diff --git a/test/printf2.test b/test/printf2.test index fb031bd68f..d30966d167 100644 --- a/test/printf2.test +++ b/test/printf2.test @@ -116,6 +116,37 @@ do_execsql_test printf2-3.5 { SELECT printf('|%7.8c|%-7.8c|','*','*'); } {|********|********|} +# The "," separator +do_execsql_test printf2-4.1 { + SELECT printf('|%,d|%,d|',0,-1); +} {|0|-1|} +do_execsql_test printf2-4.2 { + SELECT printf('|%,d|%,d|',12,-12); +} {|12|-12|} +do_execsql_test printf2-4.3 { + SELECT printf('|%,d|%,d|',123,-123); +} {|123|-123|} +do_execsql_test printf2-4.4 { + SELECT printf('|%,d|%,d|',1234,-1234); +} {|1,234|-1,234|} +do_execsql_test printf2-4.5 { + SELECT printf('|%,d|%,d|',12345,-12345); +} {|12,345|-12,345|} +do_execsql_test printf2-4.6 { + SELECT printf('|%,d|%,d|',123456,-123456); +} {|123,456|-123,456|} +do_execsql_test printf2-4.7 { + SELECT printf('|%,d|%,d|',1234567,-1234567); +} {|1,234,567|-1,234,567|} +do_execsql_test printf2-4.8 { + SELECT printf('|%,d|%,d|',12345678,-12345678); +} {|12,345,678|-12,345,678|} +do_execsql_test printf2-4.9 { + SELECT printf('|%,d|%,d|',123456789,-123456789); +} {|123,456,789|-123,456,789|} +do_execsql_test printf2-4.10 { + SELECT printf('|%,d|%,d|',1234567890,-1234567890); +} {|1,234,567,890|-1,234,567,890|} From 1c84bd478776a79b7ba5f8c73743a873ee7c4994 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 10 Feb 2017 21:37:57 +0000 Subject: [PATCH 1320/1484] Enhance the LIKE optimization so that it works for arbitrary expressions on the LHS as long as the pattern on the RHS does not begin with a digit or a minus sign. FossilOrigin-Name: 158290c0abafde67ee3f2363f0b6646887841df3 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/whereexpr.c | 26 +++++++++++++++++--------- test/vtab1.test | 28 ++++++++++++++-------------- test/vtabH.test | 8 ++++---- 5 files changed, 44 insertions(+), 36 deletions(-) diff --git a/manifest b/manifest index 53d7e16ed6..9d7931aab5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\s","\sflag\sto\sprintf(). -D 2017-02-10T19:38:36.506 +C Enhance\sthe\sLIKE\soptimization\sso\sthat\sit\sworks\sfor\sarbitrary\sexpressions\son\nthe\sLHS\sas\slong\sas\sthe\spattern\son\sthe\sRHS\sdoes\snot\sbegin\swith\sa\sdigit\sor\na\sminus\ssign. +D 2017-02-10T21:37:57.808 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 067a6766f800cc8d72845ab61f8de4ffe8f3fc99 @@ -478,7 +478,7 @@ F src/walker.c 91a6df7435827e41cff6bb7df50ea00934ee78b0 F src/where.c bc71775e23d23334e8f449aa31012d692dc09cb2 F src/whereInt.h 2bcc3d176e6091cb8f50a30b65c006e88a73614d F src/wherecode.c 99a8ced164c75edf41b3a865a75381c9adb38b28 -F src/whereexpr.c 35ad025389a632a3987a35617c878be3b3d70dc6 +F src/whereexpr.c 980109826ba02750421c3fa7ab0ecabbac0a639d F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d @@ -1374,7 +1374,7 @@ F test/vacuummem.test 7b42abb3208bd82dd23a7536588396f295a314f2 F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102 F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661 F test/view.test 765802c7a66d37fabd5ac8e2f2dbe572b43eb9ab -F test/vtab1.test 7c4b81abd88361ada9cbe414c459efca26be6bda +F test/vtab1.test ed4a576231d8a36e70fd18e2b79b621b31e7f22a F test/vtab2.test f8cd1bb9aba7143eba97812d9617880a36d247ad F test/vtab3.test b45f47d20f225ccc9c28dc915d92740c2dee311e F test/vtab4.test 8e73ed268f3d596bc3590f45fc948fb40f28e9c3 @@ -1389,7 +1389,7 @@ F test/vtabC.test 4528f459a13136f982e75614d120aef165f17292 F test/vtabD.test 05b3f1d77117271671089e48719524b676842e96 F test/vtabE.test d5024aa42754962f6bb0afd261681686488e7afe F test/vtabF.test 1918844c7c902f6a16c8dacf1ec8f84886d6e78b -F test/vtabH.test a2912cd3ea3386aecc3cb74ebfdfcc4e6d4b7dd3 +F test/vtabH.test 5f9253eb9e41ba9fe94f4aa3e9230191893d7764 F test/vtabI.test 751b07636700dbdea328e4265b6077ccd6811a3f F test/vtab_alter.test 9e374885248f69e251bdaacf480b04a197f125e5 F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8 @@ -1555,7 +1555,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 798fb9d70d2e5f95e64237b04d6692360133381a -R c3dc7f748658995c87bb25e10706fab3 +P 064445b12f99f76e9a12957be97edd520ab3ae27 +R db970521e4fc7396c9c380bbcef0e8ad U drh -Z 3add84968b9ef1dfcf3d7b3eaefd30ad +Z 2c915b2d7e6621ed4f4d2fbc11d0cc6c diff --git a/manifest.uuid b/manifest.uuid index 8090b2db36..0e09e9b731 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -064445b12f99f76e9a12957be97edd520ab3ae27 \ No newline at end of file +158290c0abafde67ee3f2363f0b6646887841df3 \ No newline at end of file diff --git a/src/whereexpr.c b/src/whereexpr.c index 826d329b7f..f511452e52 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -213,15 +213,6 @@ static int isLikeOrGlob( #endif pList = pExpr->x.pList; pLeft = pList->a[1].pExpr; - if( pLeft->op!=TK_COLUMN - || sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT - || IsVirtual(pLeft->pTab) /* Value might be numeric */ - ){ - /* IMP: R-02065-49465 The left-hand side of the LIKE or GLOB operator must - ** be the name of an indexed column with TEXT affinity. */ - return 0; - } - assert( pLeft->iColumn!=(-1) ); /* Because IPK never has AFF_TEXT */ pRight = sqlite3ExprSkipCollate(pList->a[0].pExpr); op = pRight->op; @@ -238,6 +229,23 @@ static int isLikeOrGlob( z = pRight->u.zToken; } if( z ){ + + /* If the RHS begins with a digit or a minus sign, then the LHS must + ** be an ordinary column (not a virtual table column) with TEXT affinity. + ** Otherwise the LHS might be numeric and "lhs >= rhs" would be false + ** even though "lhs LIKE rhs" is true. But if the RHS does not start + ** with a digit or '-', then "lhs LIKE rhs" will always be false if + ** the LHS is numeric and so the optimization still works. + */ + if( sqlite3Isdigit(z[0]) || z[0]=='-' ){ + if( pLeft->op!=TK_COLUMN + || sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT + || IsVirtual(pLeft->pTab) /* Value might be numeric */ + ){ + sqlite3ValueFree(pVal); + return 0; + } + } cnt = 0; while( (c=z[cnt])!=0 && c!=wc[0] && c!=wc[1] && c!=wc[2] ){ cnt++; diff --git a/test/vtab1.test b/test/vtab1.test index 6b6a0e2683..59ab959746 100644 --- a/test/vtab1.test +++ b/test/vtab1.test @@ -1295,25 +1295,25 @@ do_execsql_test 18.1.0 { CREATE INDEX i6 ON t6(b, a); INSERT INTO t6 VALUES(1, 'Peter'); INSERT INTO t6 VALUES(2, 'Andrew'); - INSERT INTO t6 VALUES(3, 'James'); - INSERT INTO t6 VALUES(4, 'John'); + INSERT INTO t6 VALUES(3, '8James'); + INSERT INTO t6 VALUES(4, '8John'); INSERT INTO t6 VALUES(5, 'Phillip'); INSERT INTO t6 VALUES(6, 'Bartholomew'); CREATE VIRTUAL TABLE e6 USING echo(t6); } foreach {tn sql res filter} { - 1.1 "SELECT a FROM e6 WHERE b>'James'" {4 1 5} - {xFilter {SELECT rowid, a, b FROM 't6' WHERE b > ?} James} + 1.1 "SELECT a FROM e6 WHERE b>'8James'" {4 2 6 1 5} + {xFilter {SELECT rowid, a, b FROM 't6' WHERE b > ?} 8James} - 1.2 "SELECT a FROM e6 WHERE b>='J' AND b<'K'" {3 4} - {xFilter {SELECT rowid, a, b FROM 't6' WHERE b >= ? AND b < ?} J K} + 1.2 "SELECT a FROM e6 WHERE b>='8' AND b<'9'" {3 4} + {xFilter {SELECT rowid, a, b FROM 't6' WHERE b >= ? AND b < ?} 8 9} - 1.3 "SELECT a FROM e6 WHERE b LIKE 'J%'" {3 4} - {xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} J%} + 1.3 "SELECT a FROM e6 WHERE b LIKE '8J%'" {3 4} + {xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} 8J%} - 1.4 "SELECT a FROM e6 WHERE b LIKE 'j%'" {3 4} - {xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} j%} + 1.4 "SELECT a FROM e6 WHERE b LIKE '8j%'" {3 4} + {xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} 8j%} } { set echo_module {} do_execsql_test 18.$tn.1 $sql $res @@ -1322,11 +1322,11 @@ foreach {tn sql res filter} { do_execsql_test 18.2.0 { PRAGMA case_sensitive_like = ON } foreach {tn sql res filter} { - 2.1 "SELECT a FROM e6 WHERE b LIKE 'J%'" {3 4} - {xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} J%} + 2.1 "SELECT a FROM e6 WHERE b LIKE '8J%'" {3 4} + {xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} 8J%} - 2.2 "SELECT a FROM e6 WHERE b LIKE 'j%'" {} - {xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} j%} + 2.2 "SELECT a FROM e6 WHERE b LIKE '8j%'" {} + {xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} 8j%} } { set echo_module {} do_execsql_test 18.$tn.1 $sql $res diff --git a/test/vtabH.test b/test/vtabH.test index 3ce457ff0b..c5684ff516 100644 --- a/test/vtabH.test +++ b/test/vtabH.test @@ -31,14 +31,14 @@ do_execsql_test 1.0 { } foreach {tn sql expect} { - 1 "SELECT * FROM e6 WHERE b LIKE 'abc'" { + 1 "SELECT * FROM e6 WHERE b LIKE '8abc'" { xBestIndex {SELECT rowid, a, b FROM 't6' WHERE b like ?} - xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} abc + xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} 8abc } - 2 "SELECT * FROM e6 WHERE b GLOB 'abc'" { + 2 "SELECT * FROM e6 WHERE b GLOB '8abc'" { xBestIndex {SELECT rowid, a, b FROM 't6' WHERE b glob ?} - xFilter {SELECT rowid, a, b FROM 't6' WHERE b glob ?} abc + xFilter {SELECT rowid, a, b FROM 't6' WHERE b glob ?} 8abc } } { do_test 1.$tn { From 653a5f4e7141ba137721d3ffb79ec89334195962 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 10 Feb 2017 21:40:04 +0000 Subject: [PATCH 1321/1484] Bump the version number up to 3.18.0. FossilOrigin-Name: 7520c238558346d421e3c24cb7d17a54d1aa56b2 --- VERSION | 2 +- configure | 18 +++++++++--------- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/VERSION b/VERSION index 3f67e25cea..c5b45eb7b1 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.17.0 +3.18.0 diff --git a/configure b/configure index be7c89143b..628e23f2d0 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.17.0. +# Generated by GNU Autoconf 2.69 for sqlite 3.18.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.17.0' -PACKAGE_STRING='sqlite 3.17.0' +PACKAGE_VERSION='3.18.0' +PACKAGE_STRING='sqlite 3.18.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.17.0 to adapt to many kinds of systems. +\`configure' configures sqlite 3.18.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.17.0:";; + short | recursive ) echo "Configuration of sqlite 3.18.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.17.0 +sqlite configure 3.18.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.17.0, which was +It was created by sqlite $as_me 3.18.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.17.0, which was +This file was extended by sqlite $as_me 3.18.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.17.0 +sqlite config.status 3.18.0 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/manifest b/manifest index 9d7931aab5..67413c58d2 100644 --- a/manifest +++ b/manifest @@ -1,10 +1,10 @@ -C Enhance\sthe\sLIKE\soptimization\sso\sthat\sit\sworks\sfor\sarbitrary\sexpressions\son\nthe\sLHS\sas\slong\sas\sthe\spattern\son\sthe\sRHS\sdoes\snot\sbegin\swith\sa\sdigit\sor\na\sminus\ssign. -D 2017-02-10T21:37:57.808 +C Bump\sthe\sversion\snumber\sup\sto\s3.18.0. +D 2017-02-10T21:40:04.693 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 067a6766f800cc8d72845ab61f8de4ffe8f3fc99 F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7 -F VERSION cddd8d88dc8202afa0ebc96da61fc4acbd1e96a5 +F VERSION 3605fa447e4623f5ff4a6adc97b1fde9a257b8f2 F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 @@ -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 fcfa56d5d66668c9263dc007724f62acff06dc83 x +F configure b15d030a8ae2e672d76c97b6667dacb98934a467 x F configure.ac 605173e829ab64514ed89f9b53d0da1739d7b0a0 F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad F doc/lemon.html b5a3c07d33ecb8e019ce8f7660fe2dbbad9d7977 @@ -1555,7 +1555,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 064445b12f99f76e9a12957be97edd520ab3ae27 -R db970521e4fc7396c9c380bbcef0e8ad +P 158290c0abafde67ee3f2363f0b6646887841df3 +R 48ad943b0cb23a44970ddc9873b9da0a U drh -Z 2c915b2d7e6621ed4f4d2fbc11d0cc6c +Z faf6e7fd0bb1d717431a908ec9819058 diff --git a/manifest.uuid b/manifest.uuid index 0e09e9b731..461c4b68e4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -158290c0abafde67ee3f2363f0b6646887841df3 \ No newline at end of file +7520c238558346d421e3c24cb7d17a54d1aa56b2 \ No newline at end of file From 13ac46eea2effd6e6f6033e062b760665bf4b7d3 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 11 Feb 2017 13:51:23 +0000 Subject: [PATCH 1322/1484] Ensure that indexed expressions with collating sequences are handled correctly. Proposed fix for ticket [eb703ba7b50c1a5]. FossilOrigin-Name: 9689d04b8250139e32078b2aa9748edcc6231bcd --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/expr.c | 2 +- src/where.c | 1 + test/indexexpr1.test | 10 ++++++++++ 5 files changed, 21 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 67413c58d2..c25697f824 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Bump\sthe\sversion\snumber\sup\sto\s3.18.0. -D 2017-02-10T21:40:04.693 +C Ensure\sthat\sindexed\sexpressions\swith\scollating\ssequences\sare\shandled\ncorrectly.\s\sProposed\sfix\sfor\sticket\s[eb703ba7b50c1a5]. +D 2017-02-11T13:51:23.762 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 067a6766f800cc8d72845ab61f8de4ffe8f3fc99 @@ -347,7 +347,7 @@ F src/ctime.c 9f2296a4e5d26ebf0e0d95a0af4628f1ea694e7a F src/date.c dc3f1391d9297f8c748132813aaffcb117090d6e F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c 0d9d5549d42e79ce4d82ff1db1e6c81e36d2f67c -F src/expr.c d29114e9b709eaeaaa18553a5bbe60a19302aeef +F src/expr.c c218ec8cfc12b2c5b354660ce7285dfaf43305e9 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 2e9aabe1aee76273aff8a84ee92c464e095400ae F src/func.c c67273e1ec08abbdcc14c189892a3ff6eeece86b @@ -475,7 +475,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 40c543f0a2195d1b0dc88ef12142bea690009344 F src/wal.h 06b2a0b599cc0f53ea97f497cf8c6b758c999f71 F src/walker.c 91a6df7435827e41cff6bb7df50ea00934ee78b0 -F src/where.c bc71775e23d23334e8f449aa31012d692dc09cb2 +F src/where.c b0d81c6f24ea6aebb249c92c5d78ec8ab1452523 F src/whereInt.h 2bcc3d176e6091cb8f50a30b65c006e88a73614d F src/wherecode.c 99a8ced164c75edf41b3a865a75381c9adb38b28 F src/whereexpr.c 980109826ba02750421c3fa7ab0ecabbac0a639d @@ -867,7 +867,7 @@ F test/index6.test b4fc812290067a578b98bb2667b676db89e202a7 F test/index7.test 7feababe16f2091b229c22aff2bcc1d4d6b9d2bb F test/index8.test bc2e3db70e8e62459aaa1bd7e4a9b39664f8f9d7 F test/indexedby.test 9c4cd331224e57f79fbf411ae245e6272d415985 -F test/indexexpr1.test 7d243fac508b4a99fb900ffe34eb488312cfce84 +F test/indexexpr1.test 038b3befa74e5a75126b6e9dd2ae5df61c1c7cf7 F test/indexfault.test 31d4ab9a7d2f6e9616933eb079722362a883eb1d F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7 F test/insert.test 38742b5e9601c8f8d76e9b7555f7270288c2d371 @@ -1555,7 +1555,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 158290c0abafde67ee3f2363f0b6646887841df3 -R 48ad943b0cb23a44970ddc9873b9da0a +P 7520c238558346d421e3c24cb7d17a54d1aa56b2 +R 89fd81518c2edceda83a282bdfdfc51e U drh -Z faf6e7fd0bb1d717431a908ec9819058 +Z 86c7ba615f1277d92ec3bd479587e4c2 diff --git a/manifest.uuid b/manifest.uuid index 461c4b68e4..9191af5c88 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7520c238558346d421e3c24cb7d17a54d1aa56b2 \ No newline at end of file +9689d04b8250139e32078b2aa9748edcc6231bcd \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index f1e8667b39..ff4f1b5ade 100644 --- a/src/expr.c +++ b/src/expr.c @@ -231,7 +231,7 @@ static char comparisonAffinity(Expr *pExpr){ aff = sqlite3CompareAffinity(pExpr->pRight, aff); }else if( ExprHasProperty(pExpr, EP_xIsSelect) ){ aff = sqlite3CompareAffinity(pExpr->x.pSelect->pEList->a[0].pExpr, aff); - }else if( NEVER(aff==0) ){ + }else if( aff==0 ){ aff = SQLITE_AFF_BLOB; } return aff; diff --git a/src/where.c b/src/where.c index 4951f6a1b4..80dfa20ed1 100644 --- a/src/where.c +++ b/src/where.c @@ -308,6 +308,7 @@ static WhereTerm *whereScanInit( iColumn = pIdx->aiColumn[j]; if( iColumn==XN_EXPR ){ pScan->pIdxExpr = pIdx->aColExpr->a[j].pExpr; + pScan->zCollName = pIdx->azColl[j]; }else if( iColumn==pIdx->pTable->iPKey ){ iColumn = XN_ROWID; }else if( iColumn>=0 ){ diff --git a/test/indexexpr1.test b/test/indexexpr1.test index cd72430d91..2b375a5855 100644 --- a/test/indexexpr1.test +++ b/test/indexexpr1.test @@ -370,4 +370,14 @@ do_execsql_test indexexpr1-1200.4 { 0 0 0 2 0 4 2 0 2 2 4 0 } +# Ticket https://www.sqlite.org/src/tktview/eb703ba7b50c1a +# Incorrect result using an index on an expression with a collating function +# +do_execsql_test indexexpr1-1300.1 { + CREATE TABLE t1300(a INTEGER PRIMARY KEY, b); + INSERT INTO t1300 VALUES(1,'coffee'),(2,'COFFEE'),(3,'stress'),(4,'STRESS'); + CREATE INDEX t1300bexpr ON t1300( substr(b,4) ); + SELECT a FROM t1300 WHERE substr(b,4)='ess' COLLATE nocase ORDER BY +a; +} {3 4} + finish_test From f9463dfbcf8069bb1df1dd3407bc6e2837f9cee6 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 11 Feb 2017 14:59:58 +0000 Subject: [PATCH 1323/1484] Fix indexes on expressions so that they can be actually used with a COLLATE clause. FossilOrigin-Name: e464b919f76520b45bb58983c6702db59d820ee4 --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/expr.c | 11 +++++++++++ src/sqliteInt.h | 1 + src/where.c | 3 ++- src/whereexpr.c | 2 +- 6 files changed, 25 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index c25697f824..aff48f9780 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Ensure\sthat\sindexed\sexpressions\swith\scollating\ssequences\sare\shandled\ncorrectly.\s\sProposed\sfix\sfor\sticket\s[eb703ba7b50c1a5]. -D 2017-02-11T13:51:23.762 +C Fix\sindexes\son\sexpressions\sso\sthat\sthey\scan\sbe\sactually\sused\swith\na\sCOLLATE\sclause. +D 2017-02-11T14:59:58.753 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 067a6766f800cc8d72845ab61f8de4ffe8f3fc99 @@ -347,7 +347,7 @@ F src/ctime.c 9f2296a4e5d26ebf0e0d95a0af4628f1ea694e7a F src/date.c dc3f1391d9297f8c748132813aaffcb117090d6e F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c 0d9d5549d42e79ce4d82ff1db1e6c81e36d2f67c -F src/expr.c c218ec8cfc12b2c5b354660ce7285dfaf43305e9 +F src/expr.c 4748f51a680ded80332aca51cc51548c60758fe9 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 2e9aabe1aee76273aff8a84ee92c464e095400ae F src/func.c c67273e1ec08abbdcc14c189892a3ff6eeece86b @@ -399,7 +399,7 @@ F src/shell.c a84e453c213f3e0d6935a582024da4e242f85a19 F src/sqlite.h.in 751ff125eb159c8f92c182b8df980a5e4f50e966 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae -F src/sqliteInt.h 4dc66ec1948765f151899333f7a55267d807d099 +F src/sqliteInt.h c3f878dcbe947938f9e0984644f1902dd9051094 F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 @@ -475,10 +475,10 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 40c543f0a2195d1b0dc88ef12142bea690009344 F src/wal.h 06b2a0b599cc0f53ea97f497cf8c6b758c999f71 F src/walker.c 91a6df7435827e41cff6bb7df50ea00934ee78b0 -F src/where.c b0d81c6f24ea6aebb249c92c5d78ec8ab1452523 +F src/where.c 6397fab50fdbf9bde76c574ce07b3b776eb28b34 F src/whereInt.h 2bcc3d176e6091cb8f50a30b65c006e88a73614d F src/wherecode.c 99a8ced164c75edf41b3a865a75381c9adb38b28 -F src/whereexpr.c 980109826ba02750421c3fa7ab0ecabbac0a639d +F src/whereexpr.c 130cdd1a43af71b19755270fb1224874cf55158c F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d @@ -1555,7 +1555,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 7520c238558346d421e3c24cb7d17a54d1aa56b2 -R 89fd81518c2edceda83a282bdfdfc51e +P 9689d04b8250139e32078b2aa9748edcc6231bcd +R e95d56d566e83b0838849dba73bfcd3a U drh -Z 86c7ba615f1277d92ec3bd479587e4c2 +Z 0aabcf0e8948d008893cd3f00b6802af diff --git a/manifest.uuid b/manifest.uuid index 9191af5c88..85764546dc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9689d04b8250139e32078b2aa9748edcc6231bcd \ No newline at end of file +e464b919f76520b45bb58983c6702db59d820ee4 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index ff4f1b5ade..6a1a9288a1 100644 --- a/src/expr.c +++ b/src/expr.c @@ -4680,6 +4680,17 @@ int sqlite3ExprListCompare(ExprList *pA, ExprList *pB, int iTab){ return 0; } +/* +** Like sqlite3ExprCompare() except COLLATE operators at the top-level +** are ignored. +*/ +int sqlite3ExprCompareSkip(Expr *pA, Expr *pB, int iTab){ + return sqlite3ExprCompare( + sqlite3ExprSkipCollate(pA), + sqlite3ExprSkipCollate(pB), + iTab); +} + /* ** Return true if we can prove the pE2 will always be true if pE1 is ** true. Return false if we cannot complete the proof or if pE2 might diff --git a/src/sqliteInt.h b/src/sqliteInt.h index f9768895ae..23b4dd9460 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3762,6 +3762,7 @@ void sqlite3Vacuum(Parse*,Token*); int sqlite3RunVacuum(char**, sqlite3*, int); char *sqlite3NameFromToken(sqlite3*, Token*); int sqlite3ExprCompare(Expr*, Expr*, int); +int sqlite3ExprCompareSkip(Expr*, Expr*, int); int sqlite3ExprListCompare(ExprList*, ExprList*, int); int sqlite3ExprImpliesExpr(Expr*, Expr*, int); void sqlite3ExprAnalyzeAggregates(NameContext*, Expr*); diff --git a/src/where.c b/src/where.c index 80dfa20ed1..4c533aa493 100644 --- a/src/where.c +++ b/src/where.c @@ -209,7 +209,8 @@ static WhereTerm *whereScanNext(WhereScan *pScan){ if( pTerm->leftCursor==iCur && pTerm->u.leftColumn==iColumn && (iColumn!=XN_EXPR - || sqlite3ExprCompare(pTerm->pExpr->pLeft,pScan->pIdxExpr,iCur)==0) + || sqlite3ExprCompareSkip(pTerm->pExpr->pLeft, + pScan->pIdxExpr,iCur)==0) && (pScan->iEquiv<=1 || !ExprHasProperty(pTerm->pExpr, EP_FromJoin)) ){ if( (pTerm->eOperator & WO_EQUIV)!=0 diff --git a/src/whereexpr.c b/src/whereexpr.c index f511452e52..248b5349db 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -874,7 +874,7 @@ static int exprMightBeIndexed( if( pIdx->aColExpr==0 ) continue; for(i=0; inKeyCol; i++){ if( pIdx->aiColumn[i]!=XN_EXPR ) continue; - if( sqlite3ExprCompare(pExpr, pIdx->aColExpr->a[i].pExpr, iCur)==0 ){ + if( sqlite3ExprCompareSkip(pExpr, pIdx->aColExpr->a[i].pExpr, iCur)==0 ){ *piCur = iCur; *piColumn = XN_EXPR; return 1; From ac279be98ebbe5cce899c549f12d16204d460a67 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 13 Feb 2017 13:20:02 +0000 Subject: [PATCH 1324/1484] Avoid a duplication #define in FTS5 FossilOrigin-Name: c447441cff1884d6fe5f0a76d64b3e7d908584a1 --- ext/fts5/fts5Int.h | 4 +++- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/ext/fts5/fts5Int.h b/ext/fts5/fts5Int.h index 9ef338e821..d350856573 100644 --- a/ext/fts5/fts5Int.h +++ b/ext/fts5/fts5Int.h @@ -30,7 +30,9 @@ typedef short i16; typedef sqlite3_int64 i64; typedef sqlite3_uint64 u64; -#define ArraySize(x) ((int)(sizeof(x) / sizeof(x[0]))) +#ifndef ArraySize +# define ArraySize(x) ((int)(sizeof(x) / sizeof(x[0]))) +#endif #define testcase(x) #define ALWAYS(x) 1 diff --git a/manifest b/manifest index aff48f9780..b5ae3ca250 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sindexes\son\sexpressions\sso\sthat\sthey\scan\sbe\sactually\sused\swith\na\sCOLLATE\sclause. -D 2017-02-11T14:59:58.753 +C Avoid\sa\sduplication\s#define\sin\sFTS5 +D 2017-02-13T13:20:02.419 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 067a6766f800cc8d72845ab61f8de4ffe8f3fc99 @@ -98,7 +98,7 @@ F ext/fts3/unicode/mkunicode.tcl 2debed3f582d77b3fdd0b8830880250021571fd8 F ext/fts3/unicode/parseunicode.tcl da577d1384810fb4e2b209bf3313074353193e95 F ext/fts5/extract_api_docs.tcl a36e54ec777172ddd3f9a88daf593b00848368e0 F ext/fts5/fts5.h 62f3e33ceeb9a428db139f9c012186b371da1cc7 -F ext/fts5/fts5Int.h b2eda36e0f224365c8e23dc8f559311834f1c13f +F ext/fts5/fts5Int.h c629b24d2b92b99596f3b8e82289fddca06df6e1 F ext/fts5/fts5_aux.c 67acf8d51723cf28ffc3828210ba662df4b8d267 F ext/fts5/fts5_buffer.c 4c1502d4c956cd092c89ce4480867f9d8bf325cd F ext/fts5/fts5_config.c 5af9c360e99669d29f06492c370892394aba0857 @@ -1555,7 +1555,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 9689d04b8250139e32078b2aa9748edcc6231bcd -R e95d56d566e83b0838849dba73bfcd3a +P e464b919f76520b45bb58983c6702db59d820ee4 +R 8c09ada0ea1970f0e52c7f9e3e6704e9 U drh -Z 0aabcf0e8948d008893cd3f00b6802af +Z 6a635e248bfa56654adaa33accae463e diff --git a/manifest.uuid b/manifest.uuid index 85764546dc..a7d1b63450 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e464b919f76520b45bb58983c6702db59d820ee4 \ No newline at end of file +c447441cff1884d6fe5f0a76d64b3e7d908584a1 \ No newline at end of file From 30a5831c45f5c51840fb8017bc1024e1bb058b53 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 13 Feb 2017 13:26:33 +0000 Subject: [PATCH 1325/1484] Fix typos in using the MSVC_VERSION macro. FossilOrigin-Name: f3b65926b1f439adb95e3bbce8e58785b8cf8427 --- manifest | 15 ++++++++------- manifest.uuid | 2 +- src/btreeInt.h | 2 +- src/mutex_w32.c | 2 +- 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index b5ae3ca250..fbd6c3cbf1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sa\sduplication\s#define\sin\sFTS5 -D 2017-02-13T13:20:02.419 +C Fix\stypos\sin\susing\sthe\sMSVC_VERSION\smacro. +D 2017-02-13T13:26:33.213 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 067a6766f800cc8d72845ab61f8de4ffe8f3fc99 @@ -339,7 +339,7 @@ F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca F src/btree.c 9fe65ab418d99e80289f024016b5e5e74c3059dd F src/btree.h e6d352808956ec163a17f832193a3e198b3fb0ac -F src/btreeInt.h 429bbfebae05ab3beb1c4508ba94c292036c660f +F src/btreeInt.h cd55d39d9916270837a88c12e701047cba0729b0 F src/build.c 9e799f1edd910dfa8a0bc29bd390d35d310596af F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e @@ -372,7 +372,7 @@ F src/mutex.c 8e45800ee78e0cd1f1f3fe8e398853307f4a085c F src/mutex.h 779d588e3b7756ec3ecf7d78cde1d84aba414f85 F src/mutex_noop.c 9d4309c075ba9cc7249e19412d3d62f7f94839c4 F src/mutex_unix.c 27bb6cc49485ee46711a6580ab7b3f1402211d23 -F src/mutex_w32.c 00bbf37d80fb763a8159b83cc3cbde0f91d37f7b +F src/mutex_w32.c 3631e57d056062807ae2c92b79f3d1c05f04ecfe F src/notify.c 9711a7575036f0d3040ba61bc6e217f13a9888e7 F src/os.c add02933b1dce7a39a005b00a2f5364b763e9a24 F src/os.h 8e976e59eb4ca1c0fca6d35ee803e38951cb0343 @@ -1555,7 +1555,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 e464b919f76520b45bb58983c6702db59d820ee4 -R 8c09ada0ea1970f0e52c7f9e3e6704e9 +P c447441cff1884d6fe5f0a76d64b3e7d908584a1 +Q +25ebadd096ce98fd0f9fab809969d34b958794f6 +R 0d77a6b89e0c4cc810773e50b9f58357 U drh -Z 6a635e248bfa56654adaa33accae463e +Z 66e01577a77088f99ecc22522d190a03 diff --git a/manifest.uuid b/manifest.uuid index a7d1b63450..e47a2c37d8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c447441cff1884d6fe5f0a76d64b3e7d908584a1 \ No newline at end of file +f3b65926b1f439adb95e3bbce8e58785b8cf8427 \ No newline at end of file diff --git a/src/btreeInt.h b/src/btreeInt.h index 0d79edd639..b01163c33f 100644 --- a/src/btreeInt.h +++ b/src/btreeInt.h @@ -694,7 +694,7 @@ struct IntegrityCk { # define get2byteAligned(x) (*(u16*)(x)) #elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4008000 # define get2byteAligned(x) __builtin_bswap16(*(u16*)(x)) -#elif SQLITE_BYTEORDER==1234 && MSCV_VERSION>=1300 +#elif SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300 # define get2byteAligned(x) _byteswap_ushort(*(u16*)(x)) #else # define get2byteAligned(x) ((x)[0]<<8 | (x)[1]) diff --git a/src/mutex_w32.c b/src/mutex_w32.c index e0bdf9e43b..505c8fab7e 100644 --- a/src/mutex_w32.c +++ b/src/mutex_w32.c @@ -87,7 +87,7 @@ void sqlite3MemoryBarrier(void){ SQLITE_MEMORY_BARRIER; #elif defined(__GNUC__) __sync_synchronize(); -#elif MSCV_VERSION>=1300 +#elif MSVC_VERSION>=1300 _ReadWriteBarrier(); #elif defined(MemoryBarrier) MemoryBarrier(); From d879e3eb8d1326182ae33fc0ecd47563add7e2b5 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 13 Feb 2017 13:35:55 +0000 Subject: [PATCH 1326/1484] Change all legacy instances of "#if SQLITE_DEBUG" to "#ifdef SQLITE_DEBUG" for consistency. FossilOrigin-Name: 670f10b24230863688270d12ac519609ade2302b --- manifest | 25 ++++++++++++------------- manifest.uuid | 2 +- src/btree.c | 4 ++-- src/ctime.c | 2 +- src/expr.c | 2 +- src/malloc.c | 4 ++-- src/pcache.c | 2 +- src/vdbe.c | 2 +- src/vdbeaux.c | 4 ++-- 9 files changed, 23 insertions(+), 24 deletions(-) diff --git a/manifest b/manifest index fbd6c3cbf1..2ceff8b1f9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\stypos\sin\susing\sthe\sMSVC_VERSION\smacro. -D 2017-02-13T13:26:33.213 +C Change\sall\slegacy\sinstances\sof\s"#if\sSQLITE_DEBUG"\sto\s"#ifdef\sSQLITE_DEBUG"\sfor\nconsistency. +D 2017-02-13T13:35:55.526 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 067a6766f800cc8d72845ab61f8de4ffe8f3fc99 @@ -337,17 +337,17 @@ F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792 F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca -F src/btree.c 9fe65ab418d99e80289f024016b5e5e74c3059dd +F src/btree.c 3ae66974881e74df9909093818b4c3428f8d7982 F src/btree.h e6d352808956ec163a17f832193a3e198b3fb0ac F src/btreeInt.h cd55d39d9916270837a88c12e701047cba0729b0 F src/build.c 9e799f1edd910dfa8a0bc29bd390d35d310596af F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e -F src/ctime.c 9f2296a4e5d26ebf0e0d95a0af4628f1ea694e7a +F src/ctime.c a9984df73898c042a5cfc8f9d8e7723d02bc35c9 F src/date.c dc3f1391d9297f8c748132813aaffcb117090d6e F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c 0d9d5549d42e79ce4d82ff1db1e6c81e36d2f67c -F src/expr.c 4748f51a680ded80332aca51cc51548c60758fe9 +F src/expr.c 38bd92fcbd86b3904bfa29e477412e374b7df5a2 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 2e9aabe1aee76273aff8a84ee92c464e095400ae F src/func.c c67273e1ec08abbdcc14c189892a3ff6eeece86b @@ -360,7 +360,7 @@ F src/insert.c 444354c23d4d140a57d6eb46f34e376a7f8f62e8 F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e F src/loadext.c a68d8d1d14cf7488bb29dc5311cb1ce9a4404258 F src/main.c e207b81542d13b9f13d61e78ca441f9781f055b0 -F src/malloc.c f345c60d093d6c6cf451b99a7344a123b1a70fd9 +F src/malloc.c d0a1474236486165bcb349af82e2a6560178bf7b F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c fd7cd6fe21d46fe0a4186367dd8dc26d87b787eb F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3 @@ -384,7 +384,7 @@ F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c ff1232b3088a39806035ecfac4fffeb22717d80b F src/pager.h f2a99646c5533ffe11afa43e9e0bea74054e4efa F src/parse.y 591704fce84f814d9a3642774c1f011d38f4149c -F src/pcache.c 51070ec9b8251bbf9c6ea3d35fd96a458752929e +F src/pcache.c 62835bed959e2914edd26afadfecce29ece0e870 F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 F src/pcache1.c e3967219b2a92b9edcb9324a4ba75009090d3953 F src/pragma.c 7831956012f5d764761fbd023e59b0ffc08f5e8d @@ -461,11 +461,11 @@ F src/update.c 456d4a4656f8a03c2abc88a51b19172197400e58 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c 3d2ce209a89b95cf35bffa16440f57368576e2ee F src/vacuum.c 33c174b28886b2faf26e503b5a49a1c01a9b1c16 -F src/vdbe.c e7b1e860140f1d1803c6f4176b1e8f3801f3a290 +F src/vdbe.c 16f378640570c24442fd7191b136b5d6380f5c7b F src/vdbe.h 59998ffd71d7caa8886bc78dafaf8caeccd4c13c F src/vdbeInt.h 4e4b15b2e1330e1636e4e01974eab2b0b985092f F src/vdbeapi.c 3e4a8893feeb78620f4aac4ac5b85d92255b97e1 -F src/vdbeaux.c b9a36e530e6525ca9d9a685bc7b1d01fa77b5cf8 +F src/vdbeaux.c 4122458d33318ab039c4b5da1ca4e7c9221c38e4 F src/vdbeblob.c 359891617358deefc85bef7bcf787fa6b77facb9 F src/vdbemem.c 3b5a9a5b375458d3e12a50ae1aaa41eeec2175fd F src/vdbesort.c eda25cb2d1727efca6f7862fea32b8aa33c0face @@ -1555,8 +1555,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P c447441cff1884d6fe5f0a76d64b3e7d908584a1 -Q +25ebadd096ce98fd0f9fab809969d34b958794f6 -R 0d77a6b89e0c4cc810773e50b9f58357 +P f3b65926b1f439adb95e3bbce8e58785b8cf8427 +R 9a737f02698a8160ed54e0df3f0a03b5 U drh -Z 66e01577a77088f99ecc22522d190a03 +Z 858958ba65336814a070740bd151ce33 diff --git a/manifest.uuid b/manifest.uuid index e47a2c37d8..897adb27e8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f3b65926b1f439adb95e3bbce8e58785b8cf8427 \ No newline at end of file +670f10b24230863688270d12ac519609ade2302b \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index de553423b8..e78ffef1be 100644 --- a/src/btree.c +++ b/src/btree.c @@ -4776,7 +4776,7 @@ static int moveToChild(BtCursor *pCur, u32 newPgno){ pCur, pCur->curPagerFlags); } -#if SQLITE_DEBUG +#ifdef SQLITE_DEBUG /* ** Page pParent is an internal (non-leaf) tree page. This function ** asserts that page number iChild is the left-child if the iIdx'th @@ -6163,7 +6163,7 @@ static int fillInCell( ** Use a call to btreeParseCellPtr() to verify that the values above ** were computed correctly. */ -#if SQLITE_DEBUG +#ifdef SQLITE_DEBUG { CellInfo info; pPage->xParseCell(pPage, pCell, &info); diff --git a/src/ctime.c b/src/ctime.c index 969bbc73d2..3db3192095 100644 --- a/src/ctime.c +++ b/src/ctime.c @@ -57,7 +57,7 @@ static const char * const azCompileOpt[] = { #if SQLITE_COVERAGE_TEST "COVERAGE_TEST", #endif -#if SQLITE_DEBUG +#ifdef SQLITE_DEBUG "DEBUG", #endif #if SQLITE_DEFAULT_LOCKING_MODE diff --git a/src/expr.c b/src/expr.c index 6a1a9288a1..505e56a272 100644 --- a/src/expr.c +++ b/src/expr.c @@ -3272,7 +3272,7 @@ void sqlite3ExprCodeGetColumnToReg( void sqlite3ExprCacheClear(Parse *pParse){ int i; -#if SQLITE_DEBUG +#ifdef SQLITE_DEBUG if( pParse->db->flags & SQLITE_VdbeAddopTrace ){ printf("CLEAR\n"); } diff --git a/src/malloc.c b/src/malloc.c index e7714aa103..0fdc8d73ff 100644 --- a/src/malloc.c +++ b/src/malloc.c @@ -418,7 +418,7 @@ int sqlite3MallocSize(void *p){ int sqlite3DbMallocSize(sqlite3 *db, void *p){ assert( p!=0 ); if( db==0 || !isLookaside(db,p) ){ -#if SQLITE_DEBUG +#ifdef SQLITE_DEBUG if( db==0 ){ assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) ); assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); @@ -479,7 +479,7 @@ void sqlite3DbFree(sqlite3 *db, void *p){ } if( isLookaside(db, p) ){ LookasideSlot *pBuf = (LookasideSlot*)p; -#if SQLITE_DEBUG +#ifdef SQLITE_DEBUG /* Trash all content in the buffer being freed */ memset(p, 0xaa, db->lookaside.sz); #endif diff --git a/src/pcache.c b/src/pcache.c index 0fc44c5499..dc7d00f306 100644 --- a/src/pcache.c +++ b/src/pcache.c @@ -104,7 +104,7 @@ struct PCache { ** ** assert( sqlite3PcachePageSanity(pPg) ); */ -#if SQLITE_DEBUG +#ifdef SQLITE_DEBUG int sqlite3PcachePageSanity(PgHdr *pPg){ PCache *pCache; assert( pPg!=0 ); diff --git a/src/vdbe.c b/src/vdbe.c index cb8a039abb..7f286b2c6d 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2198,7 +2198,7 @@ case OP_Compare: { assert( pKeyInfo!=0 ); p1 = pOp->p1; p2 = pOp->p2; -#if SQLITE_DEBUG +#ifdef SQLITE_DEBUG if( aPermute ){ int k, mx = 0; for(k=0; kmx ) mx = aPermute[k]; diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 68f6a5acc8..cf062cf01d 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -3562,7 +3562,7 @@ void sqlite3VdbeRecordUnpack( p->nField = u; } -#if SQLITE_DEBUG +#ifdef SQLITE_DEBUG /* ** This function compares two index or table record keys in the same way ** as the sqlite3VdbeRecordCompare() routine. Unlike VdbeRecordCompare(), @@ -3667,7 +3667,7 @@ debugCompareEnd: } #endif -#if SQLITE_DEBUG +#ifdef SQLITE_DEBUG /* ** Count the number of fields (a.k.a. columns) in the record given by ** pKey,nKey. The verify that this count is less than or equal to the From a8207f488fdf5008516996b5b784f86f572f194a Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 14 Feb 2017 15:57:11 +0000 Subject: [PATCH 1327/1484] Add the new "--testset orm" to the speedtest1 utility. FossilOrigin-Name: 1836adc1d1f8e496ae0a07bf0fc933a19dc8fee5 --- manifest | 12 +- manifest.uuid | 2 +- test/speedtest1.c | 273 +++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 279 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 2ceff8b1f9..209981b594 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sall\slegacy\sinstances\sof\s"#if\sSQLITE_DEBUG"\sto\s"#ifdef\sSQLITE_DEBUG"\sfor\nconsistency. -D 2017-02-13T13:35:55.526 +C Add\sthe\snew\s"--testset\sorm"\sto\sthe\sspeedtest1\sutility. +D 2017-02-14T15:57:11.586 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 067a6766f800cc8d72845ab61f8de4ffe8f3fc99 @@ -1137,7 +1137,7 @@ F test/speed3.test 694affeb9100526007436334cf7d08f3d74b85ef F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715 F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b -F test/speedtest1.c 02fe15bb784c5276a083ffe9969cc51e0bce7644 +F test/speedtest1.c 89795b8e11f2e4d1e14882d5f03731f4bc49962a F test/spellfix.test f9c1f431e2c096c8775fec032952320c0e4700db F test/spellfix2.test dfc8f519a3fc204cb2dfa8b4f29821ae90f6f8c3 F test/spellfix3.test 0f9efaaa502a0e0a09848028518a6fb096c8ad33 @@ -1555,7 +1555,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P f3b65926b1f439adb95e3bbce8e58785b8cf8427 -R 9a737f02698a8160ed54e0df3f0a03b5 +P 670f10b24230863688270d12ac519609ade2302b +R 2249f4f56d1658c4b20a6cc317c60c9d U drh -Z 858958ba65336814a070740bd151ce33 +Z 47dad88b095b1c4793f875e17e9e4c4b diff --git a/manifest.uuid b/manifest.uuid index 897adb27e8..eed33597ba 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -670f10b24230863688270d12ac519609ade2302b \ No newline at end of file +1836adc1d1f8e496ae0a07bf0fc933a19dc8fee5 \ No newline at end of file diff --git a/test/speedtest1.c b/test/speedtest1.c index f5b79915c8..075b2e24aa 100644 --- a/test/speedtest1.c +++ b/test/speedtest1.c @@ -33,7 +33,7 @@ static const char zHelp[] = " --size N Relative test size. Default=100\n" " --stats Show statistics at the end\n" " --temp N N from 0 to 9. 0: no temp table. 9: all temp tables\n" - " --testset T Run test-set T\n" + " --testset T Run test-set T (main, cte, rtree, orm, debug)\n" " --trace Turn on SQL tracing\n" " --threads N Use up to N threads for sorting\n" " --utf16be Set text encoding to UTF-16BE\n" @@ -1307,6 +1307,275 @@ void testset_rtree(int p1, int p2){ } #endif /* SQLITE_ENABLE_RTREE */ +/* +** A testset that does key/value storage on tables with many columns. +** This is the kind of workload generated by ORMs such as CoreData. +*/ +void testset_orm(void){ + unsigned i, j, n; + unsigned nRow; + unsigned x1, len; + char zNum[2000]; /* A number name */ + static const char zType[] = /* Types for all non-PK columns, in order */ + "IBBIIITIVVITBTBFBFITTFBTBVBVIFTBBFITFFVBIFIVBVVVBTVTIBBFFIVIBTB" + "TVTTFTVTVFFIITIFBITFTTFFFVBIIBTTITFTFFVVVFIIITVBBVFFTVVB"; + + nRow = n = g.szTest*250; + speedtest1_begin_test(100, "Fill %d rows", n); + speedtest1_exec( + "BEGIN;" + "CREATE TABLE ZLOOKSLIKECOREDATA (" + " ZPK INTEGER PRIMARY KEY," + " ZTERMFITTINGHOUSINGCOMMAND INTEGER," + " ZBRIEFGOBYDODGERHEIGHT BLOB," + " ZCAPABLETRIPDOORALMOND BLOB," + " ZDEPOSITPAIRCOLLEGECOMET INTEGER," + " ZFRAMEENTERSIMPLEMOUTH INTEGER," + " ZHOPEFULGATEHOLECHALK INTEGER," + " ZSLEEPYUSERGRANDBOWL TIMESTAMP," + " ZDEWPEACHCAREERCELERY INTEGER," + " ZHANGERLITHIUMDINNERMEET VARCHAR," + " ZCLUBRELEASELIZARDADVICE VARCHAR," + " ZCHARGECLICKHUMANEHIRE INTEGER," + " ZFINGERDUEPIZZAOPTION TIMESTAMP," + " ZFLYINGDOCTORTABLEMELODY BLOB," + " ZLONGFINLEAVEIMAGEOIL TIMESTAMP," + " ZFAMILYVISUALOWNERMATTER BLOB," + " ZGOLDYOUNGINITIALNOSE FLOAT," + " ZCAUSESALAMITERMCYAN BLOB," + " ZSPREADMOTORBISCUITBACON FLOAT," + " ZGIFTICEFISHGLUEHAIR INTEGER," + " ZNOTICEPEARPOLICYJUICE TIMESTAMP," + " ZBANKBUFFALORECOVERORBIT TIMESTAMP," + " ZLONGDIETESSAYNATURE FLOAT," + " ZACTIONRANGEELEGANTNEUTRON BLOB," + " ZCADETBRIGHTPLANETBANK TIMESTAMP," + " ZAIRFORGIVEHEADFROG BLOB," + " ZSHARKJUSTFRUITMOVIE VARCHAR," + " ZFARMERMORNINGMIRRORCONCERN BLOB," + " ZWOODPOETRYCOBBLERBENCH VARCHAR," + " ZHAFNIUMSCRIPTSALADMOTOR INTEGER," + " ZPROBLEMCLUBPOPOVERJELLY FLOAT," + " ZEIGHTLEADERWORKERMOST TIMESTAMP," + " ZGLASSRESERVEBARIUMMEAL BLOB," + " ZCLAMBITARUGULAFAJITA BLOB," + " ZDECADEJOYOUSWAVEHABIT FLOAT," + " ZCOMPANYSUMMERFIBERELF INTEGER," + " ZTREATTESTQUILLCHARGE TIMESTAMP," + " ZBROWBALANCEKEYCHOWDER FLOAT," + " ZPEACHCOPPERDINNERLAKE FLOAT," + " ZDRYWALLBEYONDBROWNBOWL VARCHAR," + " ZBELLYCRASHITEMLACK BLOB," + " ZTENNISCYCLEBILLOFFICER INTEGER," + " ZMALLEQUIPTHANKSGLUE FLOAT," + " ZMISSREPLYHUMANLIVING INTEGER," + " ZKIWIVISUALPRIDEAPPLE VARCHAR," + " ZWISHHITSKINMOTOR BLOB," + " ZCALMRACCOONPROGRAMDEBIT VARCHAR," + " ZSHINYASSISTLIVINGCRAB VARCHAR," + " ZRESOLVEWRISTWRAPAPPLE VARCHAR," + " ZAPPEALSIMPLESECONDHOUSING BLOB," + " ZCORNERANCHORTAPEDIVER TIMESTAMP," + " ZMEMORYREQUESTSOURCEBIG VARCHAR," + " ZTRYFACTKEEPMILK TIMESTAMP," + " ZDIVERPAINTLEATHEREASY INTEGER," + " ZSORTMISTYQUOTECABBAGE BLOB," + " ZTUNEGASBUFFALOCAPITAL BLOB," + " ZFILLSTOPLAWJOYFUL FLOAT," + " ZSTEELCAREFULPLATENUMBER FLOAT," + " ZGIVEVIVIDDIVINEMEANING INTEGER," + " ZTREATPACKFUTURECONVERT VARCHAR," + " ZCALMLYGEMFINISHEFFECT INTEGER," + " ZCABBAGESOCKEASEMINUTE BLOB," + " ZPLANETFAMILYPUREMEMORY TIMESTAMP," + " ZMERRYCRACKTRAINLEADER BLOB," + " ZMINORWAYPAPERCLASSY TIMESTAMP," + " ZEAGLELINEMINEMAIL VARCHAR," + " ZRESORTYARDGREENLET TIMESTAMP," + " ZYARDOREGANOVIVIDJEWEL TIMESTAMP," + " ZPURECAKEVIVIDNEATLY FLOAT," + " ZASKCONTACTMONITORFUN TIMESTAMP," + " ZMOVEWHOGAMMAINCH VARCHAR," + " ZLETTUCEBIRDMEETDEBATE TIMESTAMP," + " ZGENENATURALHEARINGKITE VARCHAR," + " ZMUFFINDRYERDRAWFORTUNE FLOAT," + " ZGRAYSURVEYWIRELOVE FLOAT," + " ZPLIERSPRINTASKOREGANO INTEGER," + " ZTRAVELDRIVERCONTESTLILY INTEGER," + " ZHUMORSPICESANDKIDNEY TIMESTAMP," + " ZARSENICSAMPLEWAITMUON INTEGER," + " ZLACEADDRESSGROUNDCAREFUL FLOAT," + " ZBAMBOOMESSWASABIEVENING BLOB," + " ZONERELEASEAVERAGENURSE INTEGER," + " ZRADIANTWHENTRYCARD TIMESTAMP," + " ZREWARDINSIDEMANGOINTENSE FLOAT," + " ZNEATSTEWPARTIRON TIMESTAMP," + " ZOUTSIDEPEAHENCOUNTICE TIMESTAMP," + " ZCREAMEVENINGLIPBRANCH FLOAT," + " ZWHALEMATHAVOCADOCOPPER FLOAT," + " ZLIFEUSELEAFYBELL FLOAT," + " ZWEALTHLINENGLEEFULDAY VARCHAR," + " ZFACEINVITETALKGOLD BLOB," + " ZWESTAMOUNTAFFECTHEARING INTEGER," + " ZDELAYOUTCOMEHORNAGENCY INTEGER," + " ZBIGTHINKCONVERTECONOMY BLOB," + " ZBASEGOUDAREGULARFORGIVE TIMESTAMP," + " ZPATTERNCLORINEGRANDCOLBY TIMESTAMP," + " ZCYANBASEFEEDADROIT INTEGER," + " ZCARRYFLOORMINNOWDRAGON TIMESTAMP," + " ZIMAGEPENCILOTHERBOTTOM FLOAT," + " ZXENONFLIGHTPALEAPPLE TIMESTAMP," + " ZHERRINGJOKEFEATUREHOPEFUL FLOAT," + " ZCAPYEARLYRIVETBRUSH FLOAT," + " ZAGEREEDFROGBASKET VARCHAR," + " ZUSUALBODYHALIBUTDIAMOND VARCHAR," + " ZFOOTTAPWORDENTRY VARCHAR," + " ZDISHKEEPBLESTMONITOR FLOAT," + " ZBROADABLESOLIDCASUAL INTEGER," + " ZSQUAREGLEEFULCHILDLIGHT INTEGER," + " ZHOLIDAYHEADPONYDETAIL INTEGER," + " ZGENERALRESORTSKYOPEN TIMESTAMP," + " ZGLADSPRAYKIDNEYGUPPY VARCHAR," + " ZSWIMHEAVYMENTIONKIND BLOB," + " ZMESSYSULFURDREAMFESTIVE BLOB," + " ZSKYSKYCLASSICBRIEF VARCHAR," + " ZDILLASKHOKILEMON FLOAT," + " ZJUNIORSHOWPRESSNOVA FLOAT," + " ZSIZETOEAWARDFRESH TIMESTAMP," + " ZKEYFAILAPRICOTMETAL VARCHAR," + " ZHANDYREPAIRPROTONAIRPORT VARCHAR," + " ZPOSTPROTEINHANDLEACTOR BLOB" + ");" + ); + speedtest1_prepare( + "INSERT INTO ZLOOKSLIKECOREDATA(ZPK,ZAIRFORGIVEHEADFROG," + "ZGIFTICEFISHGLUEHAIR,ZDELAYOUTCOMEHORNAGENCY,ZSLEEPYUSERGRANDBOWL," + "ZGLASSRESERVEBARIUMMEAL,ZBRIEFGOBYDODGERHEIGHT," + "ZBAMBOOMESSWASABIEVENING,ZFARMERMORNINGMIRRORCONCERN," + "ZTREATPACKFUTURECONVERT,ZCAUSESALAMITERMCYAN,ZCALMRACCOONPROGRAMDEBIT," + "ZHOLIDAYHEADPONYDETAIL,ZWOODPOETRYCOBBLERBENCH,ZHAFNIUMSCRIPTSALADMOTOR," + "ZUSUALBODYHALIBUTDIAMOND,ZOUTSIDEPEAHENCOUNTICE,ZDIVERPAINTLEATHEREASY," + "ZWESTAMOUNTAFFECTHEARING,ZSIZETOEAWARDFRESH,ZDEWPEACHCAREERCELERY," + "ZSTEELCAREFULPLATENUMBER,ZCYANBASEFEEDADROIT,ZCALMLYGEMFINISHEFFECT," + "ZHANDYREPAIRPROTONAIRPORT,ZGENENATURALHEARINGKITE,ZBROADABLESOLIDCASUAL," + "ZPOSTPROTEINHANDLEACTOR,ZLACEADDRESSGROUNDCAREFUL,ZIMAGEPENCILOTHERBOTTOM," + "ZPROBLEMCLUBPOPOVERJELLY,ZPATTERNCLORINEGRANDCOLBY,ZNEATSTEWPARTIRON," + "ZAPPEALSIMPLESECONDHOUSING,ZMOVEWHOGAMMAINCH,ZTENNISCYCLEBILLOFFICER," + "ZSHARKJUSTFRUITMOVIE,ZKEYFAILAPRICOTMETAL,ZCOMPANYSUMMERFIBERELF," + "ZTERMFITTINGHOUSINGCOMMAND,ZRESORTYARDGREENLET,ZCABBAGESOCKEASEMINUTE," + "ZSQUAREGLEEFULCHILDLIGHT,ZONERELEASEAVERAGENURSE,ZBIGTHINKCONVERTECONOMY," + "ZPLIERSPRINTASKOREGANO,ZDECADEJOYOUSWAVEHABIT,ZDRYWALLBEYONDBROWNBOWL," + "ZCLUBRELEASELIZARDADVICE,ZWHALEMATHAVOCADOCOPPER,ZBELLYCRASHITEMLACK," + "ZLETTUCEBIRDMEETDEBATE,ZCAPABLETRIPDOORALMOND,ZRADIANTWHENTRYCARD," + "ZCAPYEARLYRIVETBRUSH,ZAGEREEDFROGBASKET,ZSWIMHEAVYMENTIONKIND," + "ZTRAVELDRIVERCONTESTLILY,ZGLADSPRAYKIDNEYGUPPY,ZBANKBUFFALORECOVERORBIT," + "ZFINGERDUEPIZZAOPTION,ZCLAMBITARUGULAFAJITA,ZLONGFINLEAVEIMAGEOIL," + "ZLONGDIETESSAYNATURE,ZJUNIORSHOWPRESSNOVA,ZHOPEFULGATEHOLECHALK," + "ZDEPOSITPAIRCOLLEGECOMET,ZWEALTHLINENGLEEFULDAY,ZFILLSTOPLAWJOYFUL," + "ZTUNEGASBUFFALOCAPITAL,ZGRAYSURVEYWIRELOVE,ZCORNERANCHORTAPEDIVER," + "ZREWARDINSIDEMANGOINTENSE,ZCADETBRIGHTPLANETBANK,ZPLANETFAMILYPUREMEMORY," + "ZTREATTESTQUILLCHARGE,ZCREAMEVENINGLIPBRANCH,ZSKYSKYCLASSICBRIEF," + "ZARSENICSAMPLEWAITMUON,ZBROWBALANCEKEYCHOWDER,ZFLYINGDOCTORTABLEMELODY," + "ZHANGERLITHIUMDINNERMEET,ZNOTICEPEARPOLICYJUICE,ZSHINYASSISTLIVINGCRAB," + "ZLIFEUSELEAFYBELL,ZFACEINVITETALKGOLD,ZGENERALRESORTSKYOPEN," + "ZPURECAKEVIVIDNEATLY,ZKIWIVISUALPRIDEAPPLE,ZMESSYSULFURDREAMFESTIVE," + "ZCHARGECLICKHUMANEHIRE,ZHERRINGJOKEFEATUREHOPEFUL,ZYARDOREGANOVIVIDJEWEL," + "ZFOOTTAPWORDENTRY,ZWISHHITSKINMOTOR,ZBASEGOUDAREGULARFORGIVE," + "ZMUFFINDRYERDRAWFORTUNE,ZACTIONRANGEELEGANTNEUTRON,ZTRYFACTKEEPMILK," + "ZPEACHCOPPERDINNERLAKE,ZFRAMEENTERSIMPLEMOUTH,ZMERRYCRACKTRAINLEADER," + "ZMEMORYREQUESTSOURCEBIG,ZCARRYFLOORMINNOWDRAGON,ZMINORWAYPAPERCLASSY," + "ZDILLASKHOKILEMON,ZRESOLVEWRISTWRAPAPPLE,ZASKCONTACTMONITORFUN," + "ZGIVEVIVIDDIVINEMEANING,ZEIGHTLEADERWORKERMOST,ZMISSREPLYHUMANLIVING," + "ZXENONFLIGHTPALEAPPLE,ZSORTMISTYQUOTECABBAGE,ZEAGLELINEMINEMAIL," + "ZFAMILYVISUALOWNERMATTER,ZSPREADMOTORBISCUITBACON,ZDISHKEEPBLESTMONITOR," + "ZMALLEQUIPTHANKSGLUE,ZGOLDYOUNGINITIALNOSE,ZHUMORSPICESANDKIDNEY)" + "VALUES(?1,?26,?20,?93,?8,?33,?3,?81,?28,?60,?18,?47,?109,?29,?30,?104,?86," + "?54,?92,?117,?9,?58,?97,?61,?119,?73,?107,?120,?80,?99,?31,?96,?85,?50,?71," + "?42,?27,?118,?36,?2,?67,?62,?108,?82,?94,?76,?35,?40,?11,?88,?41,?72,?4," + "?83,?102,?103,?112,?77,?111,?22,?13,?34,?15,?23,?116,?7,?5,?90,?57,?56," + "?75,?51,?84,?25,?63,?37,?87,?114,?79,?38,?14,?10,?21,?48,?89,?91,?110," + "?69,?45,?113,?12,?101,?68,?105,?46,?95,?74,?24,?53,?39,?6,?64,?52,?98," + "?65,?115,?49,?70,?59,?32,?44,?100,?55,?66,?16,?19,?106,?43,?17,?78);" + ); + for(i=0; i Date: Tue, 14 Feb 2017 15:58:58 +0000 Subject: [PATCH 1328/1484] Fix a testcase number on the ORM testset of speedtest1. FossilOrigin-Name: 58b2f911eec2e3eb9944dd6d8573ff5c7bd43f70 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/speedtest1.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 209981b594..eae1f1a83e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\snew\s"--testset\sorm"\sto\sthe\sspeedtest1\sutility. -D 2017-02-14T15:57:11.586 +C Fix\sa\stestcase\snumber\son\sthe\sORM\stestset\sof\sspeedtest1. +D 2017-02-14T15:58:58.551 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 067a6766f800cc8d72845ab61f8de4ffe8f3fc99 @@ -1137,7 +1137,7 @@ F test/speed3.test 694affeb9100526007436334cf7d08f3d74b85ef F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715 F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b -F test/speedtest1.c 89795b8e11f2e4d1e14882d5f03731f4bc49962a +F test/speedtest1.c 4f7a10a3db37a5d9ab673244b8c87f77fa8ab913 F test/spellfix.test f9c1f431e2c096c8775fec032952320c0e4700db F test/spellfix2.test dfc8f519a3fc204cb2dfa8b4f29821ae90f6f8c3 F test/spellfix3.test 0f9efaaa502a0e0a09848028518a6fb096c8ad33 @@ -1555,7 +1555,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 670f10b24230863688270d12ac519609ade2302b -R 2249f4f56d1658c4b20a6cc317c60c9d +P 1836adc1d1f8e496ae0a07bf0fc933a19dc8fee5 +R db256bb9d4f2af476591a168e0c752ad U drh -Z 47dad88b095b1c4793f875e17e9e4c4b +Z 52eb4a5120830a27e32049ce6ccc32b2 diff --git a/manifest.uuid b/manifest.uuid index eed33597ba..a19db54686 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1836adc1d1f8e496ae0a07bf0fc933a19dc8fee5 \ No newline at end of file +58b2f911eec2e3eb9944dd6d8573ff5c7bd43f70 \ No newline at end of file diff --git a/test/speedtest1.c b/test/speedtest1.c index 075b2e24aa..2117e66ce3 100644 --- a/test/speedtest1.c +++ b/test/speedtest1.c @@ -1524,7 +1524,7 @@ void testset_orm(void){ speedtest1_end_test(); n = g.szTest*250; - speedtest1_begin_test(100, "Query %d rows by rowid", n); + speedtest1_begin_test(110, "Query %d rows by rowid", n); speedtest1_prepare( "SELECT ZCYANBASEFEEDADROIT,ZJUNIORSHOWPRESSNOVA,ZCAUSESALAMITERMCYAN," "ZHOPEFULGATEHOLECHALK,ZHUMORSPICESANDKIDNEY,ZSWIMHEAVYMENTIONKIND," From d2f92c26d58a12761a3a2d6cfdf17ad50a007932 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 14 Feb 2017 16:30:13 +0000 Subject: [PATCH 1329/1484] More realistic lengths of string values in speedtest1 with --testset orm. FossilOrigin-Name: e4731fd65f9698817690b741cc454f25e8e871e6 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/speedtest1.c | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index eae1f1a83e..9b10871ba3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\stestcase\snumber\son\sthe\sORM\stestset\sof\sspeedtest1. -D 2017-02-14T15:58:58.551 +C More\srealistic\slengths\sof\sstring\svalues\sin\sspeedtest1\swith\s--testset\sorm. +D 2017-02-14T16:30:13.697 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 067a6766f800cc8d72845ab61f8de4ffe8f3fc99 @@ -1137,7 +1137,7 @@ F test/speed3.test 694affeb9100526007436334cf7d08f3d74b85ef F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715 F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b -F test/speedtest1.c 4f7a10a3db37a5d9ab673244b8c87f77fa8ab913 +F test/speedtest1.c 7b1ab42b097b484c18d99e1d1c71a6a0c9c87a7a F test/spellfix.test f9c1f431e2c096c8775fec032952320c0e4700db F test/spellfix2.test dfc8f519a3fc204cb2dfa8b4f29821ae90f6f8c3 F test/spellfix3.test 0f9efaaa502a0e0a09848028518a6fb096c8ad33 @@ -1555,7 +1555,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 1836adc1d1f8e496ae0a07bf0fc933a19dc8fee5 -R db256bb9d4f2af476591a168e0c752ad +P 58b2f911eec2e3eb9944dd6d8573ff5c7bd43f70 +R 20b26eda0719e5594bae6bc77f8993f3 U drh -Z 52eb4a5120830a27e32049ce6ccc32b2 +Z ceef40c49fe3ba25325b7e3939c1bded diff --git a/manifest.uuid b/manifest.uuid index a19db54686..38bf6ebaca 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -58b2f911eec2e3eb9944dd6d8573ff5c7bd43f70 \ No newline at end of file +e4731fd65f9698817690b741cc454f25e8e871e6 \ No newline at end of file diff --git a/test/speedtest1.c b/test/speedtest1.c index 2117e66ce3..db3a558a38 100644 --- a/test/speedtest1.c +++ b/test/speedtest1.c @@ -1499,14 +1499,14 @@ void testset_orm(void){ ); for(i=0; i Date: Tue, 14 Feb 2017 20:00:16 +0000 Subject: [PATCH 1330/1484] Enable the SQLITE_ENABLE_NULL_TRIM option for WITHOUT ROWID tables. FossilOrigin-Name: 54836270c9c0bfa5910f7ad74ec238b9d7ddee5f --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/insert.c | 10 ++++++++-- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 9b10871ba3..66d9fc8753 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C More\srealistic\slengths\sof\sstring\svalues\sin\sspeedtest1\swith\s--testset\sorm. -D 2017-02-14T16:30:13.697 +C Enable\sthe\sSQLITE_ENABLE_NULL_TRIM\soption\sfor\sWITHOUT\sROWID\stables. +D 2017-02-14T20:00:16.259 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 067a6766f800cc8d72845ab61f8de4ffe8f3fc99 @@ -356,7 +356,7 @@ F src/hash.c 63d0ee752a3b92d4695b2b1f5259c4621b2cfebd F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4 F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 -F src/insert.c 444354c23d4d140a57d6eb46f34e376a7f8f62e8 +F src/insert.c 891f6789bafca1f0a3b4f7cbb9c363229eaec828 F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e F src/loadext.c a68d8d1d14cf7488bb29dc5311cb1ce9a4404258 F src/main.c e207b81542d13b9f13d61e78ca441f9781f055b0 @@ -1555,7 +1555,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 58b2f911eec2e3eb9944dd6d8573ff5c7bd43f70 -R 20b26eda0719e5594bae6bc77f8993f3 +P e4731fd65f9698817690b741cc454f25e8e871e6 +R 239d7ae4b4c76fa68b6a3d5959c5ddbe U drh -Z ceef40c49fe3ba25325b7e3939c1bded +Z 558f1297c34d38d9f2c9884a0e7f3db0 diff --git a/manifest.uuid b/manifest.uuid index 38bf6ebaca..545a5042ea 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e4731fd65f9698817690b741cc454f25e8e871e6 \ No newline at end of file +54836270c9c0bfa5910f7ad74ec238b9d7ddee5f \ No newline at end of file diff --git a/src/insert.c b/src/insert.c index 894bfc2cc1..897a048ac9 100644 --- a/src/insert.c +++ b/src/insert.c @@ -1527,6 +1527,9 @@ void sqlite3GenerateConstraintChecks( } sqlite3VdbeAddOp3(v, OP_MakeRecord, regIdx, pIdx->nColumn, aRegIdx[ix]); VdbeComment((v, "for %s", pIdx->zName)); +#ifdef SQLITE_ENABLE_NULL_TRIM + if( pIdx->idxType==2 ) sqlite3SetMakeRecordP5(v, pIdx->pTable); +#endif /* In an UPDATE operation, if this index is the PRIMARY KEY index ** of a WITHOUT ROWID table and there has been no change the @@ -1682,8 +1685,11 @@ void sqlite3SetMakeRecordP5(Vdbe *v, Table *pTab){ ** version 2 and later (SQLite version 3.1.4, 2005-02-20). */ if( pTab->pSchema->file_format<2 ) return; - for(i=pTab->nCol; i>1 && pTab->aCol[i-1].pDflt==0; i--){} - sqlite3VdbeChangeP5(v, i); + for(i=pTab->nCol-1; i>0; i--){ + if( pTab->aCol[i].pDflt!=0 ) break; + if( pTab->aCol[i].colFlags & COLFLAG_PRIMKEY ) break; + } + sqlite3VdbeChangeP5(v, i+1); } #endif From 0c5cd969b8930871b2405790c6be5cb2220a2462 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 14 Feb 2017 21:47:46 +0000 Subject: [PATCH 1331/1484] Clarification of the help text for the command-line shell. FossilOrigin-Name: ca4f1e4962df64ae756c286f3795af7d6f692cdd --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/shell.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 66d9fc8753..28095b65b6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enable\sthe\sSQLITE_ENABLE_NULL_TRIM\soption\sfor\sWITHOUT\sROWID\stables. -D 2017-02-14T20:00:16.259 +C Clarification\sof\sthe\shelp\stext\sfor\sthe\scommand-line\sshell. +D 2017-02-14T21:47:46.389 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 067a6766f800cc8d72845ab61f8de4ffe8f3fc99 @@ -395,7 +395,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c f9bc0de45a30a450da47b3766de00be89bf9be79 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c d12f3539f80db38b09015561b569e0eb1c4b6c5f -F src/shell.c a84e453c213f3e0d6935a582024da4e242f85a19 +F src/shell.c a661e7ccd202b16cb5321999354699e5ee018fb2 F src/sqlite.h.in 751ff125eb159c8f92c182b8df980a5e4f50e966 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae @@ -1555,7 +1555,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e4731fd65f9698817690b741cc454f25e8e871e6 -R 239d7ae4b4c76fa68b6a3d5959c5ddbe +P 54836270c9c0bfa5910f7ad74ec238b9d7ddee5f +R 81ac83b9aa3d80dbb34372d0527e01bd U drh -Z 558f1297c34d38d9f2c9884a0e7f3db0 +Z 42f594c3c0159a4f4af8ef6e693c76a8 diff --git a/manifest.uuid b/manifest.uuid index 545a5042ea..da9b31e873 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -54836270c9c0bfa5910f7ad74ec238b9d7ddee5f \ No newline at end of file +ca4f1e4962df64ae756c286f3795af7d6f692cdd \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 0e553d9fbb..fe62bfc8a1 100644 --- a/src/shell.c +++ b/src/shell.c @@ -2212,7 +2212,7 @@ static char zHelp[] = " html HTML
  • code\n" " insert SQL insert statements for TABLE\n" " line One value per line\n" - " list Values delimited by .separator strings\n" + " list Values delimited by \"|\"\n" " quote Escape answers as for SQL\n" " tabs Tab-separated values\n" " tcl TCL list elements\n" From dd22c09af8ab8208a676effac377df1969cdb1a3 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Wed, 15 Feb 2017 01:39:28 +0000 Subject: [PATCH 1332/1484] In the blob test code, avoid crashing on low-memory systems by using Tcl_AttemptAlloc(). FossilOrigin-Name: 1d267757a89d9267ee9c201373f801eb9772ab04 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/test_blob.c | 6 +++++- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 28095b65b6..1dd8b1f184 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Clarification\sof\sthe\shelp\stext\sfor\sthe\scommand-line\sshell. -D 2017-02-14T21:47:46.389 +C In\sthe\sblob\stest\scode,\savoid\scrashing\son\slow-memory\ssystems\sby\susing\sTcl_AttemptAlloc(). +D 2017-02-15T01:39:28.000 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 067a6766f800cc8d72845ab61f8de4ffe8f3fc99 @@ -417,7 +417,7 @@ F src/test_async.c 195ab49da082053fdb0f949c114b806a49ca770a F src/test_autoext.c 915d245e736652a219a907909bb6710f0d587871 F src/test_backup.c bf5da90c9926df0a4b941f2d92825a01bbe090a0 F src/test_bestindex.c d23f80d334c59662af69191854c76b8d3d0c8c96 -F src/test_blob.c 6a4c7920d1d9c6cc0f7aa50c89c4f80016aeda83 +F src/test_blob.c f65ac717da2618691cf9dad094e6da0219dcd208 F src/test_btree.c 8b2dc8b8848cf3a4db93f11578f075e82252a274 F src/test_config.c 83179ea845479b5be9a651d014649e3f2722a1fe F src/test_delete.c af7eab5702f853fb1c62a5f7665e2234cf1ae17b @@ -1555,7 +1555,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 54836270c9c0bfa5910f7ad74ec238b9d7ddee5f -R 81ac83b9aa3d80dbb34372d0527e01bd -U drh -Z 42f594c3c0159a4f4af8ef6e693c76a8 +P ca4f1e4962df64ae756c286f3795af7d6f692cdd +R 91e8830a4e86062346b40a8d7a630a58 +U mistachkin +Z 631cc99fc676ac52e315c4b1825161e1 diff --git a/manifest.uuid b/manifest.uuid index da9b31e873..50375fa2e4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ca4f1e4962df64ae756c286f3795af7d6f692cdd \ No newline at end of file +1d267757a89d9267ee9c201373f801eb9772ab04 \ No newline at end of file diff --git a/src/test_blob.c b/src/test_blob.c index 7fa733bee9..118f210738 100644 --- a/src/test_blob.c +++ b/src/test_blob.c @@ -239,7 +239,11 @@ static int SQLITE_TCLAPI test_blob_read( } if( nByte>0 ){ - zBuf = (unsigned char *)Tcl_Alloc(nByte); + zBuf = (unsigned char *)Tcl_AttemptAlloc(nByte); + if( zBuf==0 ){ + Tcl_AppendResult(interp, "out of memory", 0); + return TCL_ERROR; + } } rc = sqlite3_blob_read(pBlob, zBuf, nByte, iOffset); if( rc==SQLITE_OK ){ From d742367ab58014c121fb450797c4832d795af3eb Mon Sep 17 00:00:00 2001 From: mistachkin Date: Wed, 15 Feb 2017 04:16:56 +0000 Subject: [PATCH 1333/1484] Further reforms to Tcl_*Alloc() usage. FossilOrigin-Name: ee1e689633e517ce46307b9afbf1eda03482c928 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/tclsqlite.c | 4 ---- src/test6.c | 4 ++-- 4 files changed, 10 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index 1dd8b1f184..755e760073 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\sthe\sblob\stest\scode,\savoid\scrashing\son\slow-memory\ssystems\sby\susing\sTcl_AttemptAlloc(). -D 2017-02-15T01:39:28.000 +C Further\sreforms\sto\sTcl_*Alloc()\susage. +D 2017-02-15T04:16:56.208 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 067a6766f800cc8d72845ab61f8de4ffe8f3fc99 @@ -403,13 +403,13 @@ F src/sqliteInt.h c3f878dcbe947938f9e0984644f1902dd9051094 F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 -F src/tclsqlite.c 418f5e5e0840425a7e5b33f3600dccd378a57549 +F src/tclsqlite.c 6c2151b6d8d98e183a04466d40df8889c0574d79 F src/test1.c 8a98191a1da8e100f77cdb5cc716df67d405028d F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5 F src/test3.c d03f5b5da9a2410b7a91c64b0d3306ed28ab6fee F src/test4.c 18ec393bb4d0ad1de729f0b94da7267270f3d8e6 F src/test5.c 328aae2c010c57a9829d255dc099d6899311672d -F src/test6.c 55aa2775c154415dcf4ed7cd1e19a193122b3a02 +F src/test6.c 121060d2e79a4f5047eb12b5135b23a6a7a5af01 F src/test7.c 5612e9aecf934d6df7bba6ce861fdf5ba5456010 F src/test8.c 4f4904721167b32f7a4fa8c7b32a07a673d6cc86 F src/test9.c 12e5ba554d2d1cbe0158f6ab3f7ffcd7a86ee4e5 @@ -1555,7 +1555,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ca4f1e4962df64ae756c286f3795af7d6f692cdd -R 91e8830a4e86062346b40a8d7a630a58 +P 1d267757a89d9267ee9c201373f801eb9772ab04 +R f321de2fcbd363565a0432a788265485 U mistachkin -Z 631cc99fc676ac52e315c4b1825161e1 +Z c20a15243be58007e25bc4aac5180d1c diff --git a/manifest.uuid b/manifest.uuid index 50375fa2e4..5be845459d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1d267757a89d9267ee9c201373f801eb9772ab04 \ No newline at end of file +ee1e689633e517ce46307b9afbf1eda03482c928 \ No newline at end of file diff --git a/src/tclsqlite.c b/src/tclsqlite.c index 5b52bf0c91..9df023b45c 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -3405,10 +3405,6 @@ static int SQLITE_TCLAPI DbMain( } zErrMsg = 0; p = (SqliteDb*)Tcl_Alloc( sizeof(*p) ); - if( p==0 ){ - Tcl_SetResult(interp, (char *)"malloc failed", TCL_STATIC); - return TCL_ERROR; - } memset(p, 0, sizeof(*p)); zFile = Tcl_GetStringFromObj(objv[2], 0); zFile = Tcl_TranslateFileName(interp, zFile, &translatedFilename); diff --git a/src/test6.c b/src/test6.c index 5304bcc31f..a103b9619e 100644 --- a/src/test6.c +++ b/src/test6.c @@ -161,13 +161,13 @@ static CrashGlobal g = {0, 0, SQLITE_DEFAULT_SECTOR_SIZE, 0, 0}; static int sqlite3CrashTestEnable = 0; static void *crash_malloc(int nByte){ - return (void *)Tcl_Alloc((size_t)nByte); + return (void *)Tcl_AttemptAlloc((size_t)nByte); } static void crash_free(void *p){ Tcl_Free(p); } static void *crash_realloc(void *p, int n){ - return (void *)Tcl_Realloc(p, (size_t)n); + return (void *)Tcl_AttemptRealloc(p, (size_t)n); } /* From dc5ece86ae370248de47a64ea1a022a2fa27e999 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 15 Feb 2017 15:09:09 +0000 Subject: [PATCH 1334/1484] Remove the CLANG_VERSION macro, since we have learned that version numbers in clang are "marketing" and are inconsistent and unreliable. Builds using clang will still use the GCC_VERSION macro since clang works hard to be gcc compatible. FossilOrigin-Name: 810d29320b853b3a01aa50d8f2a0bceacf79e0aa --- ext/rtree/rtree.c | 26 ++++++++++---------------- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/sqliteInt.h | 15 ++++++++------- src/util.c | 10 +++++----- 5 files changed, 33 insertions(+), 38 deletions(-) diff --git a/ext/rtree/rtree.c b/ext/rtree/rtree.c index 205939ddc6..63838a4eef 100644 --- a/ext/rtree/rtree.c +++ b/ext/rtree/rtree.c @@ -368,7 +368,11 @@ struct RtreeMatchArg { # define MIN(x,y) ((x) > (y) ? (y) : (x)) #endif -/* What version of GCC is being used. 0 means GCC is not being used */ +/* What version of GCC is being used. 0 means GCC is not being used . +** Note that the GCC_VERSION macro will also be set correctly when using +** clang, since clang works hard to be gcc compatible. So the gcc +** optimizations will also work when compiling with clang. +*/ #ifndef GCC_VERSION #if defined(__GNUC__) && !defined(SQLITE_DISABLE_INTRINSIC) # define GCC_VERSION (__GNUC__*1000000+__GNUC_MINOR__*1000+__GNUC_PATCHLEVEL__) @@ -377,16 +381,6 @@ struct RtreeMatchArg { #endif #endif -/* What version of CLANG is being used. 0 means CLANG is not being used */ -#ifndef CLANG_VERSION -#if defined(__clang__) && !defined(_WIN32) && !defined(SQLITE_DISABLE_INTRINSIC) -# define CLANG_VERSION \ - (__clang_major__*1000000+__clang_minor__*1000+__clang_patchlevel__) -#else -# define CLANG_VERSION 0 -#endif -#endif - /* The testcase() macro should already be defined in the amalgamation. If ** it is not, make it a no-op. */ @@ -437,7 +431,7 @@ static void readCoord(u8 *p, RtreeCoord *pCoord){ assert( ((((char*)p) - (char*)0)&3)==0 ); /* p is always 4-byte aligned */ #if SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300 pCoord->u = _byteswap_ulong(*(u32*)p); -#elif SQLITE_BYTEORDER==1234 && (GCC_VERSION>=4003000 || CLANG_VERSION>=3000000) +#elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000 pCoord->u = __builtin_bswap32(*(u32*)p); #elif SQLITE_BYTEORDER==4321 pCoord->u = *(u32*)p; @@ -455,7 +449,7 @@ static i64 readInt64(u8 *p){ u64 x; memcpy(&x, p, 8); return (i64)_byteswap_uint64(x); -#elif SQLITE_BYTEORDER==1234 && (GCC_VERSION>=4003000 || CLANG_VERSION>=3000000) +#elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000 u64 x; memcpy(&x, p, 8); return (i64)__builtin_bswap64(x); @@ -491,7 +485,7 @@ static int writeCoord(u8 *p, RtreeCoord *pCoord){ assert( ((((char*)p) - (char*)0)&3)==0 ); /* p is always 4-byte aligned */ assert( sizeof(RtreeCoord)==4 ); assert( sizeof(u32)==4 ); -#if SQLITE_BYTEORDER==1234 && (GCC_VERSION>=4003000 || CLANG_VERSION>=3000000) +#if SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000 i = __builtin_bswap32(pCoord->u); memcpy(p, &i, 4); #elif SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300 @@ -510,7 +504,7 @@ static int writeCoord(u8 *p, RtreeCoord *pCoord){ return 4; } static int writeInt64(u8 *p, i64 i){ -#if SQLITE_BYTEORDER==1234 && (GCC_VERSION>=4003000 || CLANG_VERSION>=3000000) +#if SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000 i = (i64)__builtin_bswap64((u64)i); memcpy(p, &i, 8); #elif SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300 @@ -1066,7 +1060,7 @@ static int rtreeEof(sqlite3_vtab_cursor *cur){ c.u = _byteswap_ulong(*(u32*)a); \ r = eInt ? (sqlite3_rtree_dbl)c.i : (sqlite3_rtree_dbl)c.f; \ } -#elif SQLITE_BYTEORDER==1234 && (GCC_VERSION>=4003000 || CLANG_VERSION>=3000000) +#elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000 #define RTREE_DECODE_COORD(eInt, a, r) { \ RtreeCoord c; /* Coordinate decoded */ \ c.u = __builtin_bswap32(*(u32*)a); \ diff --git a/manifest b/manifest index 755e760073..c24bc286f6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Further\sreforms\sto\sTcl_*Alloc()\susage. -D 2017-02-15T04:16:56.208 +C Remove\sthe\sCLANG_VERSION\smacro,\ssince\swe\shave\slearned\sthat\sversion\snumbers\sin\nclang\sare\s"marketing"\sand\sare\sinconsistent\sand\sunreliable.\s\sBuilds\susing\sclang\nwill\sstill\suse\sthe\sGCC_VERSION\smacro\ssince\sclang\sworks\shard\sto\sbe\sgcc\ncompatible. +D 2017-02-15T15:09:09.031 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 067a6766f800cc8d72845ab61f8de4ffe8f3fc99 @@ -264,7 +264,7 @@ F ext/rbu/sqlite3rbu.c bb0de6cdbdb14a7d55a097238a434b7e99caf318 F ext/rbu/sqlite3rbu.h 6fb6294c34a9ca93b5894a33bca530c6f08decba F ext/rbu/test_rbu.c 5aa22616afac6f71ebd3d9bc9bf1006cfabcca88 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 -F ext/rtree/rtree.c 358796a385de74e40ed66c103df77ba3c2e98fab +F ext/rtree/rtree.c 3f3a595dba485e340246fa2c8ba330a6b9768b00 F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e F ext/rtree/rtree1.test 42dadfc7b44a436cd74a1bebc0b9b689e4eaf7ec F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba @@ -399,7 +399,7 @@ F src/shell.c a661e7ccd202b16cb5321999354699e5ee018fb2 F src/sqlite.h.in 751ff125eb159c8f92c182b8df980a5e4f50e966 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae -F src/sqliteInt.h c3f878dcbe947938f9e0984644f1902dd9051094 +F src/sqliteInt.h 4f85005b109c1a7eab3110cb4568fe30a5389bda F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 @@ -459,7 +459,7 @@ F src/treeview.c 4e44ade3bfe59d82005039f72e09333ce2b4162c F src/trigger.c c9f0810043b265724fdb1bdd466894f984dfc182 F src/update.c 456d4a4656f8a03c2abc88a51b19172197400e58 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c -F src/util.c 3d2ce209a89b95cf35bffa16440f57368576e2ee +F src/util.c ca8440ede81e155d15cff7c101654f60b55a9ae6 F src/vacuum.c 33c174b28886b2faf26e503b5a49a1c01a9b1c16 F src/vdbe.c 16f378640570c24442fd7191b136b5d6380f5c7b F src/vdbe.h 59998ffd71d7caa8886bc78dafaf8caeccd4c13c @@ -1555,7 +1555,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 1d267757a89d9267ee9c201373f801eb9772ab04 -R f321de2fcbd363565a0432a788265485 -U mistachkin -Z c20a15243be58007e25bc4aac5180d1c +P ee1e689633e517ce46307b9afbf1eda03482c928 +R 09fd15812127544dc0546a143adbc35f +U drh +Z f21515d79bd695dc7bd9e01927424a91 diff --git a/manifest.uuid b/manifest.uuid index 5be845459d..f9059a7c49 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ee1e689633e517ce46307b9afbf1eda03482c928 \ No newline at end of file +810d29320b853b3a01aa50d8f2a0bceacf79e0aa \ No newline at end of file diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 23b4dd9460..a65bb25a4d 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -103,23 +103,24 @@ # define _LARGEFILE_SOURCE 1 #endif -/* The GCC_VERSION, CLANG_VERSION, and MSVC_VERSION macros are used to +/* The GCC_VERSION and MSVC_VERSION macros are used to ** conditionally include optimizations for each of these compilers. A ** value of 0 means that compiler is not being used. The ** SQLITE_DISABLE_INTRINSIC macro means do not use any compiler-specific ** optimizations, and hence set all compiler macros to 0 +** +** There was once also a CLANG_VERSION macro. However, we learn that the +** version numbers in clang are for "marketing" only and are inconsistent +** and unreliable. Fortunately, all versions of clang also recognize the +** gcc version numbers and have reasonable settings for gcc version numbers, +** so the GCC_VERSION macro will be set to a correct non-zero value even +** when compiling with clang. */ #if defined(__GNUC__) && !defined(SQLITE_DISABLE_INTRINSIC) # define GCC_VERSION (__GNUC__*1000000+__GNUC_MINOR__*1000+__GNUC_PATCHLEVEL__) #else # define GCC_VERSION 0 #endif -#if defined(__clang__) && !defined(_WIN32) && !defined(SQLITE_DISABLE_INTRINSIC) -# define CLANG_VERSION \ - (__clang_major__*1000000+__clang_minor__*1000+__clang_patchlevel__) -#else -# define CLANG_VERSION 0 -#endif #if defined(_MSC_VER) && !defined(SQLITE_DISABLE_INTRINSIC) # define MSVC_VERSION _MSC_VER #else diff --git a/src/util.c b/src/util.c index c6d2bae3a7..9b6f4f9e1d 100644 --- a/src/util.c +++ b/src/util.c @@ -1140,7 +1140,7 @@ u32 sqlite3Get4byte(const u8 *p){ u32 x; memcpy(&x,p,4); return x; -#elif SQLITE_BYTEORDER==1234 && (GCC_VERSION>=4003000 || CLANG_VERSION>=3000000) +#elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000 u32 x; memcpy(&x,p,4); return __builtin_bswap32(x); @@ -1156,7 +1156,7 @@ u32 sqlite3Get4byte(const u8 *p){ void sqlite3Put4byte(unsigned char *p, u32 v){ #if SQLITE_BYTEORDER==4321 memcpy(p,&v,4); -#elif SQLITE_BYTEORDER==1234 && (GCC_VERSION>=4003000 || CLANG_VERSION>=3000000) +#elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000 u32 x = __builtin_bswap32(v); memcpy(p,&x,4); #elif SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300 @@ -1275,7 +1275,7 @@ int sqlite3SafetyCheckSickOrOk(sqlite3 *db){ ** overflow, leave *pA unchanged and return 1. */ int sqlite3AddInt64(i64 *pA, i64 iB){ -#if GCC_VERSION>=5004000 || CLANG_VERSION>=4000000 +#if GCC_VERSION>=5004000 return __builtin_add_overflow(*pA, iB, pA); #else i64 iA = *pA; @@ -1295,7 +1295,7 @@ int sqlite3AddInt64(i64 *pA, i64 iB){ #endif } int sqlite3SubInt64(i64 *pA, i64 iB){ -#if GCC_VERSION>=5004000 || CLANG_VERSION>=4000000 +#if GCC_VERSION>=5004000 return __builtin_sub_overflow(*pA, iB, pA); #else testcase( iB==SMALLEST_INT64+1 ); @@ -1310,7 +1310,7 @@ int sqlite3SubInt64(i64 *pA, i64 iB){ #endif } int sqlite3MulInt64(i64 *pA, i64 iB){ -#if GCC_VERSION>=5004000 || CLANG_VERSION>=4000000 +#if GCC_VERSION>=5004000 return __builtin_mul_overflow(*pA, iB, pA); #else i64 iA = *pA; From 0d5b3b7665f895942be4002d46c2e0cf20765f8f Mon Sep 17 00:00:00 2001 From: mistachkin Date: Wed, 15 Feb 2017 18:30:57 +0000 Subject: [PATCH 1335/1484] Minor enhancement to mutex tracing on Win32. FossilOrigin-Name: 830b9235673be55f0c932fb157de03725e648c25 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/mutex_w32.c | 12 ++++++------ 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index c24bc286f6..7421867390 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sthe\sCLANG_VERSION\smacro,\ssince\swe\shave\slearned\sthat\sversion\snumbers\sin\nclang\sare\s"marketing"\sand\sare\sinconsistent\sand\sunreliable.\s\sBuilds\susing\sclang\nwill\sstill\suse\sthe\sGCC_VERSION\smacro\ssince\sclang\sworks\shard\sto\sbe\sgcc\ncompatible. -D 2017-02-15T15:09:09.031 +C Minor\senhancement\sto\smutex\stracing\son\sWin32. +D 2017-02-15T18:30:57.375 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 067a6766f800cc8d72845ab61f8de4ffe8f3fc99 @@ -372,7 +372,7 @@ F src/mutex.c 8e45800ee78e0cd1f1f3fe8e398853307f4a085c F src/mutex.h 779d588e3b7756ec3ecf7d78cde1d84aba414f85 F src/mutex_noop.c 9d4309c075ba9cc7249e19412d3d62f7f94839c4 F src/mutex_unix.c 27bb6cc49485ee46711a6580ab7b3f1402211d23 -F src/mutex_w32.c 3631e57d056062807ae2c92b79f3d1c05f04ecfe +F src/mutex_w32.c a898fa969823b100c0f5fdc57e54c9a1e419ab4d F src/notify.c 9711a7575036f0d3040ba61bc6e217f13a9888e7 F src/os.c add02933b1dce7a39a005b00a2f5364b763e9a24 F src/os.h 8e976e59eb4ca1c0fca6d35ee803e38951cb0343 @@ -1555,7 +1555,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ee1e689633e517ce46307b9afbf1eda03482c928 -R 09fd15812127544dc0546a143adbc35f -U drh -Z f21515d79bd695dc7bd9e01927424a91 +P 810d29320b853b3a01aa50d8f2a0bceacf79e0aa +R 91fee55f54fe2e54254ba44f0240778d +U mistachkin +Z 72fbc76e1b27f40edc76050b0de83496 diff --git a/manifest.uuid b/manifest.uuid index f9059a7c49..54948777cb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -810d29320b853b3a01aa50d8f2a0bceacf79e0aa \ No newline at end of file +830b9235673be55f0c932fb157de03725e648c25 \ No newline at end of file diff --git a/src/mutex_w32.c b/src/mutex_w32.c index 505c8fab7e..9da93cf319 100644 --- a/src/mutex_w32.c +++ b/src/mutex_w32.c @@ -298,8 +298,8 @@ static void winMutexEnter(sqlite3_mutex *p){ p->owner = tid; p->nRef++; if( p->trace ){ - OSTRACE(("ENTER-MUTEX tid=%lu, mutex=%p (%d), nRef=%d\n", - tid, p, p->trace, p->nRef)); + OSTRACE(("ENTER-MUTEX tid=%lu, mutex(%d)=%p (%d), nRef=%d\n", + tid, p->id, p, p->trace, p->nRef)); } #endif } @@ -341,8 +341,8 @@ static int winMutexTry(sqlite3_mutex *p){ #endif #ifdef SQLITE_DEBUG if( p->trace ){ - OSTRACE(("TRY-MUTEX tid=%lu, mutex=%p (%d), owner=%lu, nRef=%d, rc=%s\n", - tid, p, p->trace, p->owner, p->nRef, sqlite3ErrName(rc))); + OSTRACE(("TRY-MUTEX tid=%lu, mutex(%d)=%p (%d), owner=%lu, nRef=%d, rc=%s\n", + tid, p->id, p, p->trace, p->owner, p->nRef, sqlite3ErrName(rc))); } #endif return rc; @@ -370,8 +370,8 @@ static void winMutexLeave(sqlite3_mutex *p){ LeaveCriticalSection(&p->mutex); #ifdef SQLITE_DEBUG if( p->trace ){ - OSTRACE(("LEAVE-MUTEX tid=%lu, mutex=%p (%d), nRef=%d\n", - tid, p, p->trace, p->nRef)); + OSTRACE(("LEAVE-MUTEX tid=%lu, mutex(%d)=%p (%d), nRef=%d\n", + tid, p->id, p, p->trace, p->nRef)); } #endif } From 3a3b420abba7630d47eb28636bd59ca1fb319819 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 15 Feb 2017 22:36:15 +0000 Subject: [PATCH 1336/1484] Query planner optimization to detect empty tables in a join early and bail out without doing excess work. FossilOrigin-Name: 58797e9bafa95709e0f706a15f42f93b409e2db5 --- manifest | 15 ++++++------- manifest.uuid | 2 +- src/wherecode.c | 10 +++++++-- test/emptytable.test | 50 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 67 insertions(+), 10 deletions(-) create mode 100644 test/emptytable.test diff --git a/manifest b/manifest index 7421867390..b98e432695 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Minor\senhancement\sto\smutex\stracing\son\sWin32. -D 2017-02-15T18:30:57.375 +C Query\splanner\soptimization\sto\sdetect\sempty\stables\sin\sa\sjoin\searly\sand\sbail\sout\nwithout\sdoing\sexcess\swork. +D 2017-02-15T22:36:15.061 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 067a6766f800cc8d72845ab61f8de4ffe8f3fc99 @@ -477,7 +477,7 @@ F src/wal.h 06b2a0b599cc0f53ea97f497cf8c6b758c999f71 F src/walker.c 91a6df7435827e41cff6bb7df50ea00934ee78b0 F src/where.c 6397fab50fdbf9bde76c574ce07b3b776eb28b34 F src/whereInt.h 2bcc3d176e6091cb8f50a30b65c006e88a73614d -F src/wherecode.c 99a8ced164c75edf41b3a865a75381c9adb38b28 +F src/wherecode.c 677e95413c472c0b413023b6b69a47f40fce1b04 F src/whereexpr.c 130cdd1a43af71b19755270fb1224874cf55158c F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -676,6 +676,7 @@ F test/e_wal.test ae9a593207a77d711443ee69ffe081fda9243625 F test/e_walauto.test 248af31e73c98df23476a22bdb815524c9dc3ba8 F test/e_walckpt.test 28c371a6bb5e5fe7f31679c1df1763a19d19e8a0 F test/e_walhook.test 4c0613a0c76e7a9d5c4c211e1b4cbcc1143914df +F test/emptytable.test a38110becbdfa6325cd65cb588dca658cd885f62 F test/enc.test e54531cd6bf941ee6760be041dff19a104c7acea F test/enc2.test 83437a79ba1545a55fb549309175c683fb334473 F test/enc3.test 6807f7a7740a00361ca8d0ccd66bc60c8dc5f2b6 @@ -1555,7 +1556,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 810d29320b853b3a01aa50d8f2a0bceacf79e0aa -R 91fee55f54fe2e54254ba44f0240778d -U mistachkin -Z 72fbc76e1b27f40edc76050b0de83496 +P 830b9235673be55f0c932fb157de03725e648c25 +R 32e948726be0c8ec843ec4b81e44685b +U drh +Z 345aeb62ab5f52d0700dc3107ec5c535 diff --git a/manifest.uuid b/manifest.uuid index 54948777cb..8b9eddf3bb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -830b9235673be55f0c932fb157de03725e648c25 \ No newline at end of file +58797e9bafa95709e0f706a15f42f93b409e2db5 \ No newline at end of file diff --git a/src/wherecode.c b/src/wherecode.c index 58e040628a..4fd5e16fac 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -1062,6 +1062,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( Vdbe *v; /* The prepared stmt under constructions */ struct SrcList_item *pTabItem; /* FROM clause term being coded */ int addrBrk; /* Jump here to break out of the loop */ + int addrHalt; /* addrBrk for the outermost loop */ int addrCont; /* Jump here to continue with next cycle */ int iRowidReg = 0; /* Rowid is stored in this register, if not zero */ int iReleaseReg = 0; /* Temp register to free before returning */ @@ -1103,6 +1104,11 @@ Bitmask sqlite3WhereCodeOneLoopStart( VdbeComment((v, "init LEFT JOIN no-match flag")); } + /* Compute a safe address to jump to if we discover that the table for + ** this loop is empty and can never contribute content. */ + for(j=iLevel; j>0 && pWInfo->a[j].iLeftJoin==0; j--){} + addrHalt = pWInfo->a[j].addrBrk; + /* Special case of a FROM clause subquery implemented as a co-routine */ if( pTabItem->fg.viaCoroutine ){ int regYield = pTabItem->regReturn; @@ -1287,7 +1293,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( sqlite3ExprCacheAffinityChange(pParse, r1, 1); sqlite3ReleaseTempReg(pParse, rTemp); }else{ - sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iCur, addrBrk); + sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iCur, addrHalt); VdbeCoverageIf(v, bRev==0); VdbeCoverageIf(v, bRev!=0); } @@ -1933,7 +1939,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( codeCursorHint(pTabItem, pWInfo, pLevel, 0); pLevel->op = aStep[bRev]; pLevel->p1 = iCur; - pLevel->p2 = 1 + sqlite3VdbeAddOp2(v, aStart[bRev], iCur, addrBrk); + pLevel->p2 = 1 + sqlite3VdbeAddOp2(v, aStart[bRev], iCur, addrHalt); VdbeCoverageIf(v, bRev==0); VdbeCoverageIf(v, bRev!=0); pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP; diff --git a/test/emptytable.test b/test/emptytable.test new file mode 100644 index 0000000000..79cd16e913 --- /dev/null +++ b/test/emptytable.test @@ -0,0 +1,50 @@ +# 2017-02-15 +# +# 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. +# +#*********************************************************************** +# +# Test cases to show that a join involving an empty table is very fast. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +# Build some test data +# +do_execsql_test emptytable-100 { + CREATE TABLE t1(a); + WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<100) + INSERT INTO t1(a) SELECT x FROM c; + CREATE TABLE empty(x); + SELECT count(*) FROM t1; +} {100} + +# Interrupt queries after 1M cycles to prevent burning excess CPU +proc stopDb {args} { + db interrupt +} +db progress 1000000 {stopDb} + +# Prior to the query planner optimization on 2017-02-15, this query would +# take a ridiculous amount of time. If that optimization stops working, +# the result here will be in interrupt for running too long. +# +do_catchsql_test emptytable-110 { + SELECT count(*) FROM t1, t1, t1, t1, t1, t1, empty; +} {0 0} + +do_catchsql_test emptytable-120 { + SELECT count(*) FROM t1, t1 LEFT JOIN empty; +} {0 10000} +do_catchsql_test emptytable-121 { + SELECT count(*) FROM t1, t1 LEFT JOIN t1, empty; +} {0 0} + + +finish_test From 44266ec651506ff7409a65852f21e5ebab5e5c94 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 16 Feb 2017 14:48:08 +0000 Subject: [PATCH 1337/1484] Always use the IsVirtual() macro to determine if a Table object is a virtual table. Slightly smaller and faster code. FossilOrigin-Name: 6affb1c89d87288cad87dde5a533832cdf06b8aa --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/insert.c | 4 ++-- src/sqliteInt.h | 4 ++-- src/vtab.c | 14 ++++++-------- 5 files changed, 19 insertions(+), 21 deletions(-) diff --git a/manifest b/manifest index b98e432695..db4da4c16d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Query\splanner\soptimization\sto\sdetect\sempty\stables\sin\sa\sjoin\searly\sand\sbail\sout\nwithout\sdoing\sexcess\swork. -D 2017-02-15T22:36:15.061 +C Always\suse\sthe\sIsVirtual()\smacro\sto\sdetermine\sif\sa\sTable\sobject\sis\sa\svirtual\ntable.\s\sSlightly\ssmaller\sand\sfaster\scode. +D 2017-02-16T14:48:08.387 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 067a6766f800cc8d72845ab61f8de4ffe8f3fc99 @@ -356,7 +356,7 @@ F src/hash.c 63d0ee752a3b92d4695b2b1f5259c4621b2cfebd F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4 F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 -F src/insert.c 891f6789bafca1f0a3b4f7cbb9c363229eaec828 +F src/insert.c 3ed64afc49c0a2221e397b9f65d231ffbef506fe F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e F src/loadext.c a68d8d1d14cf7488bb29dc5311cb1ce9a4404258 F src/main.c e207b81542d13b9f13d61e78ca441f9781f055b0 @@ -399,7 +399,7 @@ F src/shell.c a661e7ccd202b16cb5321999354699e5ee018fb2 F src/sqlite.h.in 751ff125eb159c8f92c182b8df980a5e4f50e966 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae -F src/sqliteInt.h 4f85005b109c1a7eab3110cb4568fe30a5389bda +F src/sqliteInt.h b4a3871bda47ff79b4be612a2ab89775fa737583 F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 @@ -470,7 +470,7 @@ F src/vdbeblob.c 359891617358deefc85bef7bcf787fa6b77facb9 F src/vdbemem.c 3b5a9a5b375458d3e12a50ae1aaa41eeec2175fd F src/vdbesort.c eda25cb2d1727efca6f7862fea32b8aa33c0face F src/vdbetrace.c 41963d5376f0349842b5fc4aaaaacd7d9cdc0834 -F src/vtab.c c4bbe0f870f52036553f8098aee0703997f0577a +F src/vtab.c f7f26f9db3c328824674d0ed4fd9a961a9919186 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 40c543f0a2195d1b0dc88ef12142bea690009344 F src/wal.h 06b2a0b599cc0f53ea97f497cf8c6b758c999f71 @@ -1556,7 +1556,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 830b9235673be55f0c932fb157de03725e648c25 -R 32e948726be0c8ec843ec4b81e44685b +P 58797e9bafa95709e0f706a15f42f93b409e2db5 +R db3fb8708d0cf4bffde97f5d6d76493c U drh -Z 345aeb62ab5f52d0700dc3107ec5c535 +Z 8764b23fc3772844f5b9c915005803c6 diff --git a/manifest.uuid b/manifest.uuid index 8b9eddf3bb..c7ccabdfe1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -58797e9bafa95709e0f706a15f42f93b409e2db5 \ No newline at end of file +6affb1c89d87288cad87dde5a533832cdf06b8aa \ No newline at end of file diff --git a/src/insert.c b/src/insert.c index 897a048ac9..f1f3807244 100644 --- a/src/insert.c +++ b/src/insert.c @@ -1979,7 +1979,7 @@ static int xferOptimization( return 0; /* tab1 must not have triggers */ } #ifndef SQLITE_OMIT_VIRTUALTABLE - if( pDest->tabFlags & TF_Virtual ){ + if( IsVirtual(pDest) ){ return 0; /* tab1 must not be a virtual table */ } #endif @@ -2041,7 +2041,7 @@ static int xferOptimization( return 0; /* source and destination must both be WITHOUT ROWID or not */ } #ifndef SQLITE_OMIT_VIRTUALTABLE - if( pSrc->tabFlags & TF_Virtual ){ + if( IsVirtual(pSrc) ){ return 0; /* tab2 must not be a virtual table */ } #endif diff --git a/src/sqliteInt.h b/src/sqliteInt.h index a65bb25a4d..c8f42e315c 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1883,7 +1883,7 @@ struct Table { #define TF_Ephemeral 0x02 /* An ephemeral table */ #define TF_HasPrimaryKey 0x04 /* Table has a primary key */ #define TF_Autoincrement 0x08 /* Integer primary key is autoincrement */ -#define TF_Virtual 0x10 /* Is a virtual table */ +/* available for reuse: 0x10 */ #define TF_WithoutRowid 0x20 /* No rowid. PRIMARY KEY is the key */ #define TF_NoVisibleRowid 0x40 /* No user-visible "rowid" column */ #define TF_OOOHidden 0x80 /* Out-of-Order hidden columns */ @@ -1895,7 +1895,7 @@ struct Table { ** table support is omitted from the build. */ #ifndef SQLITE_OMIT_VIRTUALTABLE -# define IsVirtual(X) (((X)->tabFlags & TF_Virtual)!=0) +# define IsVirtual(X) ((X)->nModuleArg) #else # define IsVirtual(X) 0 #endif diff --git a/src/vtab.c b/src/vtab.c index 30079cbb5e..d68ec8f627 100644 --- a/src/vtab.c +++ b/src/vtab.c @@ -339,7 +339,6 @@ void sqlite3VtabBeginParse( iDb = sqlite3SchemaToIndex(db, pTable->pSchema); assert( iDb>=0 ); - pTable->tabFlags |= TF_Virtual; pTable->nModuleArg = 0; addModuleArgument(db, pTable, sqlite3NameFromToken(db, pModuleName)); addModuleArgument(db, pTable, 0); @@ -628,7 +627,7 @@ int sqlite3VtabCallConnect(Parse *pParse, Table *pTab){ int rc; assert( pTab ); - if( (pTab->tabFlags & TF_Virtual)==0 || sqlite3GetVTable(db, pTab) ){ + if( !IsVirtual(pTab) || sqlite3GetVTable(db, pTab) ){ return SQLITE_OK; } @@ -698,7 +697,7 @@ int sqlite3VtabCallCreate(sqlite3 *db, int iDb, const char *zTab, char **pzErr){ const char *zMod; pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zDbSName); - assert( pTab && (pTab->tabFlags & TF_Virtual)!=0 && !pTab->pVTable ); + assert( pTab && IsVirtual(pTab) && !pTab->pVTable ); /* Locate the required virtual table module */ zMod = pTab->azModuleArg[0]; @@ -752,7 +751,7 @@ int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){ return SQLITE_MISUSE_BKPT; } pTab = pCtx->pTab; - assert( (pTab->tabFlags & TF_Virtual)!=0 ); + assert( IsVirtual(pTab) ); pParse = sqlite3StackAllocZero(db, sizeof(*pParse)); if( pParse==0 ){ @@ -766,7 +765,7 @@ int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){ && pParse->pNewTable && !db->mallocFailed && !pParse->pNewTable->pSelect - && (pParse->pNewTable->tabFlags & TF_Virtual)==0 + && !IsVirtual(pParse->pNewTable) ){ if( !pTab->aCol ){ Table *pNew = pParse->pNewTable; @@ -1055,7 +1054,7 @@ FuncDef *sqlite3VtabOverloadFunction( if( pExpr->op!=TK_COLUMN ) return pDef; pTab = pExpr->pTab; if( NEVER(pTab==0) ) return pDef; - if( (pTab->tabFlags & TF_Virtual)==0 ) return pDef; + if( !IsVirtual(pTab) ) return pDef; pVtab = sqlite3GetVTable(db, pTab)->pVtab; assert( pVtab!=0 ); assert( pVtab->pModule!=0 ); @@ -1150,7 +1149,6 @@ int sqlite3VtabEponymousTableInit(Parse *pParse, Module *pMod){ pMod->pEpoTab = pTab; pTab->nTabRef = 1; pTab->pSchema = db->aDb[0].pSchema; - pTab->tabFlags |= TF_Virtual; pTab->nModuleArg = 0; pTab->iPKey = -1; addModuleArgument(db, pTab, sqlite3DbStrDup(db, pTab->zName)); @@ -1222,7 +1220,7 @@ int sqlite3_vtab_config(sqlite3 *db, int op, ...){ if( !p ){ rc = SQLITE_MISUSE_BKPT; }else{ - assert( p->pTab==0 || (p->pTab->tabFlags & TF_Virtual)!=0 ); + assert( p->pTab==0 || IsVirtual(p->pTab) ); p->pVTable->bConstraint = (u8)va_arg(ap, int); } break; From b6bf97b384b272285b649a031cfe150d89b2475c Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 16 Feb 2017 15:06:06 +0000 Subject: [PATCH 1338/1484] Remove two redundant initializations from the virtual table logic. FossilOrigin-Name: 6bd82b95a6b78bb60569af4da58ef4b9f997fe7b --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vtab.c | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index db4da4c16d..f9083dc9e5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Always\suse\sthe\sIsVirtual()\smacro\sto\sdetermine\sif\sa\sTable\sobject\sis\sa\svirtual\ntable.\s\sSlightly\ssmaller\sand\sfaster\scode. -D 2017-02-16T14:48:08.387 +C Remove\stwo\sredundant\sinitializations\sfrom\sthe\svirtual\stable\slogic. +D 2017-02-16T15:06:06.357 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 067a6766f800cc8d72845ab61f8de4ffe8f3fc99 @@ -470,7 +470,7 @@ F src/vdbeblob.c 359891617358deefc85bef7bcf787fa6b77facb9 F src/vdbemem.c 3b5a9a5b375458d3e12a50ae1aaa41eeec2175fd F src/vdbesort.c eda25cb2d1727efca6f7862fea32b8aa33c0face F src/vdbetrace.c 41963d5376f0349842b5fc4aaaaacd7d9cdc0834 -F src/vtab.c f7f26f9db3c328824674d0ed4fd9a961a9919186 +F src/vtab.c 007513c2ef52472fcdea6a741683d50662e82790 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 40c543f0a2195d1b0dc88ef12142bea690009344 F src/wal.h 06b2a0b599cc0f53ea97f497cf8c6b758c999f71 @@ -1556,7 +1556,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 58797e9bafa95709e0f706a15f42f93b409e2db5 -R db3fb8708d0cf4bffde97f5d6d76493c +P 6affb1c89d87288cad87dde5a533832cdf06b8aa +R a7d037042c5db23b2b7803c8953ffd29 U drh -Z 8764b23fc3772844f5b9c915005803c6 +Z 51668c807e51ffc5d9cef025e62b59da diff --git a/manifest.uuid b/manifest.uuid index c7ccabdfe1..af3072342a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6affb1c89d87288cad87dde5a533832cdf06b8aa \ No newline at end of file +6bd82b95a6b78bb60569af4da58ef4b9f997fe7b \ No newline at end of file diff --git a/src/vtab.c b/src/vtab.c index d68ec8f627..48891034d5 100644 --- a/src/vtab.c +++ b/src/vtab.c @@ -339,7 +339,7 @@ void sqlite3VtabBeginParse( iDb = sqlite3SchemaToIndex(db, pTable->pSchema); assert( iDb>=0 ); - pTable->nModuleArg = 0; + assert( pTable->nModuleArg==0 ); addModuleArgument(db, pTable, sqlite3NameFromToken(db, pModuleName)); addModuleArgument(db, pTable, 0); addModuleArgument(db, pTable, sqlite3DbStrDup(db, pTable->zName)); @@ -1149,7 +1149,7 @@ int sqlite3VtabEponymousTableInit(Parse *pParse, Module *pMod){ pMod->pEpoTab = pTab; pTab->nTabRef = 1; pTab->pSchema = db->aDb[0].pSchema; - pTab->nModuleArg = 0; + assert( pTab->nModuleArg==0 ); pTab->iPKey = -1; addModuleArgument(db, pTab, sqlite3DbStrDup(db, pTab->zName)); addModuleArgument(db, pTab, 0); From 6f271a421d5def6053a2dbb3750169cdcf5ea6b0 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 16 Feb 2017 15:57:30 +0000 Subject: [PATCH 1339/1484] Increase Table.tabFlags from 8 to 32 bits. FossilOrigin-Name: 7e14044c65f64322769bcad4640a5896be0a1687 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/sqliteInt.h | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index f9083dc9e5..c8783138e0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\stwo\sredundant\sinitializations\sfrom\sthe\svirtual\stable\slogic. -D 2017-02-16T15:06:06.357 +C Increase\sTable.tabFlags\sfrom\s8\sto\s32\sbits. +D 2017-02-16T15:57:30.827 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 067a6766f800cc8d72845ab61f8de4ffe8f3fc99 @@ -399,7 +399,7 @@ F src/shell.c a661e7ccd202b16cb5321999354699e5ee018fb2 F src/sqlite.h.in 751ff125eb159c8f92c182b8df980a5e4f50e966 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae -F src/sqliteInt.h b4a3871bda47ff79b4be612a2ab89775fa737583 +F src/sqliteInt.h edd1ffa288c28d9aa316ad352a75ce1c12bcc005 F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 @@ -1556,7 +1556,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 6affb1c89d87288cad87dde5a533832cdf06b8aa -R a7d037042c5db23b2b7803c8953ffd29 +P 6bd82b95a6b78bb60569af4da58ef4b9f997fe7b +R 5056d17e833da8353f5af9a38b309f26 U drh -Z 51668c807e51ffc5d9cef025e62b59da +Z 46bea1f1d9f6eb27acec6234891ad166 diff --git a/manifest.uuid b/manifest.uuid index af3072342a..890afb62ef 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6bd82b95a6b78bb60569af4da58ef4b9f997fe7b \ No newline at end of file +7e14044c65f64322769bcad4640a5896be0a1687 \ No newline at end of file diff --git a/src/sqliteInt.h b/src/sqliteInt.h index c8f42e315c..f2f2cece7a 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1848,6 +1848,7 @@ struct Table { /* ... also used as column name list in a VIEW */ int tnum; /* Root BTree page for this table */ u32 nTabRef; /* Number of pointers to this Table */ + u32 tabFlags; /* Mask of TF_* values */ i16 iPKey; /* If not negative, use aCol[iPKey] as the rowid */ i16 nCol; /* Number of columns in this table */ LogEst nRowLogEst; /* Estimated rows in table - from sqlite_stat1 table */ @@ -1855,7 +1856,6 @@ struct Table { #ifdef SQLITE_ENABLE_COSTMULT LogEst costMult; /* Cost multiplier for using this table */ #endif - u8 tabFlags; /* Mask of TF_* values */ u8 keyConf; /* What to do in case of uniqueness conflict on iPKey */ #ifndef SQLITE_OMIT_ALTERTABLE int addColOffset; /* Offset in CREATE TABLE stmt to add a new column */ From c5f4816fc5f5716bb4f09fb429b2246145ca166a Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 16 Feb 2017 16:26:53 +0000 Subject: [PATCH 1340/1484] Fix a comment on a field of the ExprList object. No changes to code. FossilOrigin-Name: bb8e264227175fc93f1c86a0083f8ad6c4ce2dc7 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/sqliteInt.h | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index c8783138e0..2f0acb041e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Increase\sTable.tabFlags\sfrom\s8\sto\s32\sbits. -D 2017-02-16T15:57:30.827 +C Fix\sa\scomment\son\sa\sfield\sof\sthe\sExprList\sobject.\s\sNo\schanges\sto\scode. +D 2017-02-16T16:26:53.932 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 067a6766f800cc8d72845ab61f8de4ffe8f3fc99 @@ -399,7 +399,7 @@ F src/shell.c a661e7ccd202b16cb5321999354699e5ee018fb2 F src/sqlite.h.in 751ff125eb159c8f92c182b8df980a5e4f50e966 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae -F src/sqliteInt.h edd1ffa288c28d9aa316ad352a75ce1c12bcc005 +F src/sqliteInt.h 46fe8e5aee3825d77fa771216ef263dc947030e7 F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 @@ -1556,7 +1556,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 6bd82b95a6b78bb60569af4da58ef4b9f997fe7b -R 5056d17e833da8353f5af9a38b309f26 +P 7e14044c65f64322769bcad4640a5896be0a1687 +R 1b3160298650a3391d35f7b330db72f9 U drh -Z 46bea1f1d9f6eb27acec6234891ad166 +Z 62831885c60053730e2b44cb5ef10954 diff --git a/manifest.uuid b/manifest.uuid index 890afb62ef..878e0d699a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7e14044c65f64322769bcad4640a5896be0a1687 \ No newline at end of file +bb8e264227175fc93f1c86a0083f8ad6c4ce2dc7 \ No newline at end of file diff --git a/src/sqliteInt.h b/src/sqliteInt.h index f2f2cece7a..9a53d33626 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2440,7 +2440,7 @@ struct Expr { struct ExprList { int nExpr; /* Number of expressions on the list */ struct ExprList_item { /* For each expression in the list */ - Expr *pExpr; /* The list of expressions */ + Expr *pExpr; /* The parse tree for this expression */ char *zName; /* Token associated with this expression */ char *zSpan; /* Original text of the expression */ u8 sortOrder; /* 1 for DESC or 0 for ASC */ From 5c258dc1cc40a09cbfb51857fe208db60b234d64 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 16 Feb 2017 17:18:07 +0000 Subject: [PATCH 1341/1484] Change two MallocZero() calls into MallocRaw() to avoid unnecessary memset(). FossilOrigin-Name: ff5e733cbffd73faa4046e0f1c7f24bb6e131738 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/expr.c | 2 +- src/legacy.c | 3 ++- 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 2f0acb041e..e0da0536b9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\scomment\son\sa\sfield\sof\sthe\sExprList\sobject.\s\sNo\schanges\sto\scode. -D 2017-02-16T16:26:53.932 +C Change\stwo\sMallocZero()\scalls\sinto\sMallocRaw()\sto\savoid\sunnecessary\smemset(). +D 2017-02-16T17:18:07.363 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 067a6766f800cc8d72845ab61f8de4ffe8f3fc99 @@ -347,7 +347,7 @@ F src/ctime.c a9984df73898c042a5cfc8f9d8e7723d02bc35c9 F src/date.c dc3f1391d9297f8c748132813aaffcb117090d6e F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c 0d9d5549d42e79ce4d82ff1db1e6c81e36d2f67c -F src/expr.c 38bd92fcbd86b3904bfa29e477412e374b7df5a2 +F src/expr.c 8a29e9b72d4b642189999c41782cd6c5bc43512f F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 2e9aabe1aee76273aff8a84ee92c464e095400ae F src/func.c c67273e1ec08abbdcc14c189892a3ff6eeece86b @@ -357,7 +357,7 @@ F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4 F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 F src/insert.c 3ed64afc49c0a2221e397b9f65d231ffbef506fe -F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e +F src/legacy.c e88ed13c2d531decde75d42c2e35623fb9ce3cb0 F src/loadext.c a68d8d1d14cf7488bb29dc5311cb1ce9a4404258 F src/main.c e207b81542d13b9f13d61e78ca441f9781f055b0 F src/malloc.c d0a1474236486165bcb349af82e2a6560178bf7b @@ -1556,7 +1556,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 7e14044c65f64322769bcad4640a5896be0a1687 -R 1b3160298650a3391d35f7b330db72f9 +P bb8e264227175fc93f1c86a0083f8ad6c4ce2dc7 +R 99427a1cfe699c929367ef60ee07c16f U drh -Z 62831885c60053730e2b44cb5ef10954 +Z 3888dc5073b69fac4d8570651367948c diff --git a/manifest.uuid b/manifest.uuid index 878e0d699a..21b82efc27 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bb8e264227175fc93f1c86a0083f8ad6c4ce2dc7 \ No newline at end of file +ff5e733cbffd73faa4046e0f1c7f24bb6e131738 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 505e56a272..2bf76eb0d7 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2367,7 +2367,7 @@ static char *exprINAffinity(Parse *pParse, Expr *pExpr){ char *zRet; assert( pExpr->op==TK_IN ); - zRet = sqlite3DbMallocZero(pParse->db, nVal+1); + zRet = sqlite3DbMallocRaw(pParse->db, nVal+1); if( zRet ){ int i; for(i=0; iflags&SQLITE_NullCallback)) ){ if( !callbackIsInit ){ - azCols = sqlite3DbMallocZero(db, 2*nCol*sizeof(const char*) + 1); + azCols = sqlite3DbMallocRaw(db, (2*nCol+1)*sizeof(const char*)); if( azCols==0 ){ goto exec_out; } @@ -94,6 +94,7 @@ int sqlite3_exec( goto exec_out; } } + azVals[i] = 0; } if( xCallback(pArg, nCol, azVals, azCols) ){ /* EVIDENCE-OF: R-38229-40159 If the callback function to From e9ba910f0d358a93c95ca615b0b6c0e08fe97691 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 16 Feb 2017 20:52:52 +0000 Subject: [PATCH 1342/1484] Change the name of WhereInfo.pDistinctSet to pResultSet, since it is now used for more than just DISTINCT processing. FossilOrigin-Name: 9fc5cd505fe6ab043519d68e999d2285e22452af --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/where.c | 16 ++++++++-------- src/whereInt.h | 2 +- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/manifest b/manifest index e0da0536b9..4ce84926b2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\stwo\sMallocZero()\scalls\sinto\sMallocRaw()\sto\savoid\sunnecessary\smemset(). -D 2017-02-16T17:18:07.363 +C Change\sthe\sname\sof\sWhereInfo.pDistinctSet\sto\spResultSet,\ssince\sit\sis\snow\nused\sfor\smore\sthan\sjust\sDISTINCT\sprocessing. +D 2017-02-16T20:52:52.517 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 067a6766f800cc8d72845ab61f8de4ffe8f3fc99 @@ -475,8 +475,8 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 40c543f0a2195d1b0dc88ef12142bea690009344 F src/wal.h 06b2a0b599cc0f53ea97f497cf8c6b758c999f71 F src/walker.c 91a6df7435827e41cff6bb7df50ea00934ee78b0 -F src/where.c 6397fab50fdbf9bde76c574ce07b3b776eb28b34 -F src/whereInt.h 2bcc3d176e6091cb8f50a30b65c006e88a73614d +F src/where.c 01baf58b72f3ddb7793cdee2871f751e3e09b35e +F src/whereInt.h c0b092180f04608d80c258174b0a14a1f9c8d02f F src/wherecode.c 677e95413c472c0b413023b6b69a47f40fce1b04 F src/whereexpr.c 130cdd1a43af71b19755270fb1224874cf55158c F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 @@ -1556,7 +1556,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P bb8e264227175fc93f1c86a0083f8ad6c4ce2dc7 -R 99427a1cfe699c929367ef60ee07c16f +P ff5e733cbffd73faa4046e0f1c7f24bb6e131738 +R 771ea12d7c4097594afa32049854d91e U drh -Z 3888dc5073b69fac4d8570651367948c +Z f13a633082a8173e1922e71dbb49e7e9 diff --git a/manifest.uuid b/manifest.uuid index 21b82efc27..fe9afd07d4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ff5e733cbffd73faa4046e0f1c7f24bb6e131738 \ No newline at end of file +9fc5cd505fe6ab043519d68e999d2285e22452af \ No newline at end of file diff --git a/src/where.c b/src/where.c index 4c533aa493..f2bf400a2d 100644 --- a/src/where.c +++ b/src/where.c @@ -4114,9 +4114,9 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ && nRowEst ){ Bitmask notUsed; - int rc = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pDistinctSet, pFrom, + int rc = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pResultSet, pFrom, WHERE_DISTINCTBY, nLoop-1, pFrom->aLoop[nLoop-1], ¬Used); - if( rc==pWInfo->pDistinctSet->nExpr ){ + if( rc==pWInfo->pResultSet->nExpr ){ pWInfo->eDistinct = WHERE_DISTINCT_ORDERED; } } @@ -4353,7 +4353,7 @@ WhereInfo *sqlite3WhereBegin( SrcList *pTabList, /* FROM clause: A list of all tables to be scanned */ Expr *pWhere, /* The WHERE clause */ ExprList *pOrderBy, /* An ORDER BY (or GROUP BY) clause, or NULL */ - ExprList *pDistinctSet, /* Try not to output two rows that duplicate these */ + ExprList *pResultSet, /* Query result set. Req'd for DISTINCT */ u16 wctrlFlags, /* The WHERE_* flags defined in sqliteInt.h */ int iAuxArg /* If WHERE_OR_SUBCLAUSE is set, index cursor number ** If WHERE_USE_LIMIT, then the limit amount */ @@ -4429,7 +4429,7 @@ WhereInfo *sqlite3WhereBegin( pWInfo->pParse = pParse; pWInfo->pTabList = pTabList; pWInfo->pOrderBy = pOrderBy; - pWInfo->pDistinctSet = pDistinctSet; + pWInfo->pResultSet = pResultSet; pWInfo->aiCurOnePass[0] = pWInfo->aiCurOnePass[1] = -1; pWInfo->nLevel = nTabList; pWInfo->iBreak = pWInfo->iContinue = sqlite3VdbeMakeLabel(v); @@ -4507,13 +4507,13 @@ WhereInfo *sqlite3WhereBegin( if( db->mallocFailed ) goto whereBeginError; if( wctrlFlags & WHERE_WANT_DISTINCT ){ - if( isDistinctRedundant(pParse, pTabList, &pWInfo->sWC, pDistinctSet) ){ + if( isDistinctRedundant(pParse, pTabList, &pWInfo->sWC, pResultSet) ){ /* The DISTINCT marking is pointless. Ignore it. */ pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE; }else if( pOrderBy==0 ){ /* Try to ORDER BY the result set to make distinct processing easier */ pWInfo->wctrlFlags |= WHERE_DISTINCTBY; - pWInfo->pOrderBy = pDistinctSet; + pWInfo->pOrderBy = pResultSet; } } @@ -4589,10 +4589,10 @@ WhereInfo *sqlite3WhereBegin( #endif /* Attempt to omit tables from the join that do not effect the result */ if( pWInfo->nLevel>=2 - && pDistinctSet!=0 + && pResultSet!=0 && OptimizationEnabled(db, SQLITE_OmitNoopJoin) ){ - Bitmask tabUsed = sqlite3WhereExprListUsage(pMaskSet, pDistinctSet); + Bitmask tabUsed = sqlite3WhereExprListUsage(pMaskSet, pResultSet); if( sWLB.pOrderBy ){ tabUsed |= sqlite3WhereExprListUsage(pMaskSet, sWLB.pOrderBy); } diff --git a/src/whereInt.h b/src/whereInt.h index fd6ebe77b4..c6195f53ed 100644 --- a/src/whereInt.h +++ b/src/whereInt.h @@ -411,7 +411,7 @@ struct WhereInfo { Parse *pParse; /* Parsing and code generating context */ SrcList *pTabList; /* List of tables in the join */ ExprList *pOrderBy; /* The ORDER BY clause or NULL */ - ExprList *pDistinctSet; /* DISTINCT over all these values */ + ExprList *pResultSet; /* Result set of the query */ LogEst iLimit; /* LIMIT if wctrlFlags has WHERE_USE_LIMIT */ int aiCurOnePass[2]; /* OP_OpenWrite cursors for the ONEPASS opt */ int iContinue; /* Jump here to continue with next record */ From 2b44fd94baa4f9934c646eacf1a5be56760eb146 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 17 Feb 2017 01:43:51 +0000 Subject: [PATCH 1343/1484] Enable the ".wheretrace" and ".selecttrace" extensions in the command-line shell when compiled on Windows using DEBUG=3 or higher. Fix a harmless warning in the shell that comes up when compiled this way. FossilOrigin-Name: 8a03be1dc42737ba0712d33f639ea26dc243b20e --- Makefile.msc | 1 + manifest | 14 +++++++------- manifest.uuid | 2 +- src/shell.c | 2 +- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/Makefile.msc b/Makefile.msc index 8b98fe4cac..317f68fa9b 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -745,6 +745,7 @@ RCC = $(RCC) -DSQLITE_ENABLE_API_ARMOR=1 !IF $(DEBUG)>2 TCC = $(TCC) -DSQLITE_DEBUG=1 +TCC = $(TCC) -DSQLITE_ENABLE_WHERETRACE -DSQLITE_ENABLE_SELECTTRACE RCC = $(RCC) -DSQLITE_DEBUG=1 !ENDIF diff --git a/manifest b/manifest index 4ce84926b2..d52e7b226a 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -C Change\sthe\sname\sof\sWhereInfo.pDistinctSet\sto\spResultSet,\ssince\sit\sis\snow\nused\sfor\smore\sthan\sjust\sDISTINCT\sprocessing. -D 2017-02-16T20:52:52.517 +C Enable\sthe\s".wheretrace"\sand\s".selecttrace"\sextensions\sin\sthe\scommand-line\nshell\swhen\scompiled\son\sWindows\susing\sDEBUG=3\sor\shigher.\s\sFix\sa\sharmless\nwarning\sin\sthe\sshell\sthat\scomes\sup\swhen\scompiled\sthis\sway. +D 2017-02-17T01:43:51.171 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 -F Makefile.msc 067a6766f800cc8d72845ab61f8de4ffe8f3fc99 +F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7 F VERSION 3605fa447e4623f5ff4a6adc97b1fde9a257b8f2 F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 @@ -395,7 +395,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c f9bc0de45a30a450da47b3766de00be89bf9be79 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c d12f3539f80db38b09015561b569e0eb1c4b6c5f -F src/shell.c a661e7ccd202b16cb5321999354699e5ee018fb2 +F src/shell.c bb8e20789499aec921a01d8744c616b81b8214f1 F src/sqlite.h.in 751ff125eb159c8f92c182b8df980a5e4f50e966 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae @@ -1556,7 +1556,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ff5e733cbffd73faa4046e0f1c7f24bb6e131738 -R 771ea12d7c4097594afa32049854d91e +P 9fc5cd505fe6ab043519d68e999d2285e22452af +R f90eded334f732494d0503ad2f56a8b5 U drh -Z f13a633082a8173e1922e71dbb49e7e9 +Z 4e5822b5948bc4c5b310214a2902dbfe diff --git a/manifest.uuid b/manifest.uuid index fe9afd07d4..2379d6ab79 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9fc5cd505fe6ab043519d68e999d2285e22452af \ No newline at end of file +8a03be1dc42737ba0712d33f639ea26dc243b20e \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index fe62bfc8a1..fbbbea9d79 100644 --- a/src/shell.c +++ b/src/shell.c @@ -4614,7 +4614,7 @@ static int do_meta_command(char *zLine, ShellState *p){ #if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE) if( c=='s' && n==11 && strncmp(azArg[0], "selecttrace", n)==0 ){ - sqlite3SelectTrace = integerValue(azArg[1]); + sqlite3SelectTrace = (int)integerValue(azArg[1]); }else #endif From 7898bfff26aec968ec23a46dc05947e070a83c5d Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 17 Feb 2017 02:04:31 +0000 Subject: [PATCH 1344/1484] Fix a test case that was made to fail by the LIKE optimization enhancement in check-in [158290c0ab] but which went unnoticed because test builds were running with ICU enabled and ICU disables the LIKE optimization. FossilOrigin-Name: 218b2bbb0de07288889f6762d4461ea8acd78969 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/tkt-78e04e52ea.test | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index d52e7b226a..dc0eaa5c63 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enable\sthe\s".wheretrace"\sand\s".selecttrace"\sextensions\sin\sthe\scommand-line\nshell\swhen\scompiled\son\sWindows\susing\sDEBUG=3\sor\shigher.\s\sFix\sa\sharmless\nwarning\sin\sthe\sshell\sthat\scomes\sup\swhen\scompiled\sthis\sway. -D 2017-02-17T01:43:51.171 +C Fix\sa\stest\scase\sthat\swas\smade\sto\sfail\sby\sthe\sLIKE\soptimization\senhancement\nin\scheck-in\s[158290c0ab]\sbut\swhich\swent\sunnoticed\sbecause\stest\sbuilds\swere\nrunning\swith\sICU\senabled\sand\sICU\sdisables\sthe\sLIKE\soptimization. +D 2017-02-17T02:04:31.068 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 @@ -1206,7 +1206,7 @@ F test/tkt-5e10420e8d.test 904d1687b3c06d43e5b3555bbcf6802e7c0ffd84 F test/tkt-5ee23731f.test 9db6e1d7209dc0794948b260d6f82b2b1de83a9f F test/tkt-6bfb98dfc0.test 24780633627b5cfc0635a5500c2389ebfb563336 F test/tkt-752e1646fc.test ea78d88d14fe9866bdd991c634483334639e13bf -F test/tkt-78e04e52ea.test 813779f8888f3ca226df656c4eef078f9635f3c9 +F test/tkt-78e04e52ea.test 1b2e6bf4f1d9887b216b6da774e5f25915ec8118 F test/tkt-7a31705a7e6.test e75a2bba4eec801b92c8040eb22096ac6d35e844 F test/tkt-7bbfb7d442.test 7b2cd79c7a17ae6750e75ec1a7846712a69c9d18 F test/tkt-80ba201079.test 105a721e6aad0ae3c5946d7615d1e4d03f6145b8 @@ -1556,7 +1556,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 9fc5cd505fe6ab043519d68e999d2285e22452af -R f90eded334f732494d0503ad2f56a8b5 +P 8a03be1dc42737ba0712d33f639ea26dc243b20e +R b29803fdd4fd514ba7baa53a58b26311 U drh -Z 4e5822b5948bc4c5b310214a2902dbfe +Z af65459984ca8c135fabce3c62812860 diff --git a/manifest.uuid b/manifest.uuid index 2379d6ab79..d642d67abe 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8a03be1dc42737ba0712d33f639ea26dc243b20e \ No newline at end of file +218b2bbb0de07288889f6762d4461ea8acd78969 \ No newline at end of file diff --git a/test/tkt-78e04e52ea.test b/test/tkt-78e04e52ea.test index 975e5b3d1c..963ecf18d1 100644 --- a/test/tkt-78e04e52ea.test +++ b/test/tkt-78e04e52ea.test @@ -42,7 +42,7 @@ do_test tkt-78e04-1.3 { } {} do_test tkt-78e04-1.4 { execsql { - EXPLAIN QUERY PLAN SELECT "" FROM "" WHERE "" LIKE 'abc%'; + EXPLAIN QUERY PLAN SELECT "" FROM "" WHERE "" LIKE '1abc%'; } } {0 0 0 {SCAN TABLE USING COVERING INDEX i1}} do_test tkt-78e04-1.5 { From 33bec3f5e89787125b56243ab7de2fe9353b8b8a Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 17 Feb 2017 13:38:15 +0000 Subject: [PATCH 1345/1484] Enhance the Index and Table objects so that they remember if their stats come from the sqlite_stat1 table. Make the "PRAGMA stats" an SQLITE_DEBUG only pragma. Add the flags column to "PRAGMA stats". These are all preliminary steps toward a "PRAGMA analyze_ifneeded;" feature. FossilOrigin-Name: 85026c8ee143bbd46565660fff8346ef81421546 --- manifest | 25 +++++---- manifest.uuid | 2 +- src/analyze.c | 22 ++++++-- src/build.c | 3 + src/pragma.c | 18 +++--- src/pragma.h | 129 ++++++++++++++++++++++--------------------- src/sqliteInt.h | 18 +++--- tool/mkpragmatab.tcl | 4 +- 8 files changed, 121 insertions(+), 100 deletions(-) diff --git a/manifest b/manifest index dc0eaa5c63..04051afae1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\stest\scase\sthat\swas\smade\sto\sfail\sby\sthe\sLIKE\soptimization\senhancement\nin\scheck-in\s[158290c0ab]\sbut\swhich\swent\sunnoticed\sbecause\stest\sbuilds\swere\nrunning\swith\sICU\senabled\sand\sICU\sdisables\sthe\sLIKE\soptimization. -D 2017-02-17T02:04:31.068 +C Enhance\sthe\sIndex\sand\sTable\sobjects\sso\sthat\sthey\sremember\sif\stheir\sstats\scome\nfrom\sthe\ssqlite_stat1\stable.\s\sMake\sthe\s"PRAGMA\sstats"\san\sSQLITE_DEBUG\sonly\npragma.\s\sAdd\sthe\sflags\scolumn\sto\s"PRAGMA\sstats".\s\sThese\sare\sall\spreliminary\nsteps\stoward\sa\s"PRAGMA\sanalyze_ifneeded;"\sfeature. +D 2017-02-17T13:38:15.256 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 @@ -331,7 +331,7 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F src/alter.c 3b23977620ce9662ac54443f65b87ba996e36121 -F src/analyze.c ac7a5d7e3cee07d074697904e00e4a8ab7b2b4f5 +F src/analyze.c 1b7197d619788353437d390de42a9bccbb4aa2ac F src/attach.c 8c476f8bd5d2afe11d925f890d30e527e5b0ce43 F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792 F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b @@ -340,7 +340,7 @@ F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca F src/btree.c 3ae66974881e74df9909093818b4c3428f8d7982 F src/btree.h e6d352808956ec163a17f832193a3e198b3fb0ac F src/btreeInt.h cd55d39d9916270837a88c12e701047cba0729b0 -F src/build.c 9e799f1edd910dfa8a0bc29bd390d35d310596af +F src/build.c 2e05d0360568f40dc583461f2211f020ff282ee4 F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c a9984df73898c042a5cfc8f9d8e7723d02bc35c9 @@ -387,8 +387,8 @@ F src/parse.y 591704fce84f814d9a3642774c1f011d38f4149c F src/pcache.c 62835bed959e2914edd26afadfecce29ece0e870 F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 F src/pcache1.c e3967219b2a92b9edcb9324a4ba75009090d3953 -F src/pragma.c 7831956012f5d764761fbd023e59b0ffc08f5e8d -F src/pragma.h 61aa5389118594bebb28120a6720401aee34ce1a +F src/pragma.c d4918a737f0bf1ad825654ebf07c4d009ff0ca63 +F src/pragma.h cea24a631982fd1a26fcddd46f596d22303b4247 F src/prepare.c b1140c3d0cf59bc85ace00ce363153041b424b7a F src/printf.c 67427bbee66d891fc6f6f5aada857e9cdb368c1c F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 @@ -399,7 +399,7 @@ F src/shell.c bb8e20789499aec921a01d8744c616b81b8214f1 F src/sqlite.h.in 751ff125eb159c8f92c182b8df980a5e4f50e966 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae -F src/sqliteInt.h 46fe8e5aee3825d77fa771216ef263dc947030e7 +F src/sqliteInt.h 54bc20855f2a1a99a1b726f1384b5ce9ab67a0ff F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 @@ -1494,7 +1494,7 @@ F tool/mkmsvcmin.tcl 95b37e202cbed873aa8ffdbb493b9db45927be2b F tool/mkopcodec.tcl d1b6362bd3aa80d5520d4d6f3765badf01f6c43c F tool/mkopcodeh.tcl a01d2c1d8a6205b03fc635adf3735b4c523befd3 F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e -F tool/mkpragmatab.tcl ebb4bfcd2f8010e0a3934b6118db4b5f2f5edf5c +F tool/mkpragmatab.tcl 9c0a855e0daf83e54ffd9fd438260cd0c92f25d0 F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 F tool/mksqlite3c-noext.tcl fef88397668ae83166735c41af99d79f56afaabb F tool/mksqlite3c.tcl 06b2e6a0f21cc0a5d70fbbd136b3e0a96470645e @@ -1556,7 +1556,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 8a03be1dc42737ba0712d33f639ea26dc243b20e -R b29803fdd4fd514ba7baa53a58b26311 +P 218b2bbb0de07288889f6762d4461ea8acd78969 +R af8aeffdf276070e8e8912906300a1a4 +T *branch * auto-analyze +T *sym-auto-analyze * +T -sym-trunk * U drh -Z af65459984ca8c135fabce3c62812860 +Z f8720207819c88fb362c87de069d287a diff --git a/manifest.uuid b/manifest.uuid index d642d67abe..fd9de00f55 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -218b2bbb0de07288889f6762d4461ea8acd78969 \ No newline at end of file +85026c8ee143bbd46565660fff8346ef81421546 \ No newline at end of file diff --git a/src/analyze.c b/src/analyze.c index 890ae7c3b2..3ecf469cd3 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -1532,7 +1532,11 @@ static int analysisLoader(void *pData, int argc, char **argv, char **NotUsed){ #endif pIndex->bUnordered = 0; decodeIntArray((char*)z, nCol, aiRowEst, pIndex->aiRowLogEst, pIndex); - if( pIndex->pPartIdxWhere==0 ) pTable->nRowLogEst = pIndex->aiRowLogEst[0]; + pIndex->hasStat1 = 1; + if( pIndex->pPartIdxWhere==0 ){ + pTable->nRowLogEst = pIndex->aiRowLogEst[0]; + pTable->tabFlags |= TF_HasStat1; + } }else{ Index fakeIdx; fakeIdx.szIdxRow = pTable->szTabRow; @@ -1541,6 +1545,7 @@ static int analysisLoader(void *pData, int argc, char **argv, char **NotUsed){ #endif decodeIntArray((char*)z, 1, 0, &pTable->nRowLogEst, &fakeIdx); pTable->szTabRow = fakeIdx.szIdxRow; + pTable->tabFlags |= TF_HasStat1; } return 0; @@ -1835,15 +1840,20 @@ int sqlite3AnalysisLoad(sqlite3 *db, int iDb){ HashElem *i; char *zSql; int rc = SQLITE_OK; + Schema *pSchema = db->aDb[iDb].pSchema; assert( iDb>=0 && iDbnDb ); assert( db->aDb[iDb].pBt!=0 ); /* Clear any prior statistics */ assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); - for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){ + for(i=sqliteHashFirst(&pSchema->tblHash); i; i=sqliteHashNext(i)){ + Table *pTab = sqliteHashData(i); + pTab->tabFlags &= ~TF_HasStat1; + } + for(i=sqliteHashFirst(&pSchema->idxHash); i; i=sqliteHashNext(i)){ Index *pIdx = sqliteHashData(i); - pIdx->aiRowLogEst[0] = 0; + pIdx->hasStat1 = 0; #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 sqlite3DeleteIndexSamples(db, pIdx); pIdx->aSample = 0; @@ -1866,9 +1876,9 @@ int sqlite3AnalysisLoad(sqlite3 *db, int iDb){ /* Set appropriate defaults on all indexes not in the sqlite_stat1 table */ assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); - for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){ + for(i=sqliteHashFirst(&pSchema->idxHash); i; i=sqliteHashNext(i)){ Index *pIdx = sqliteHashData(i); - if( pIdx->aiRowLogEst[0]==0 ) sqlite3DefaultRowEst(pIdx); + if( !pIdx->hasStat1 ) sqlite3DefaultRowEst(pIdx); } /* Load the statistics from the sqlite_stat4 table. */ @@ -1878,7 +1888,7 @@ int sqlite3AnalysisLoad(sqlite3 *db, int iDb){ rc = loadStat4(db, sInfo.zDatabase); db->lookaside.bDisable--; } - for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){ + for(i=sqliteHashFirst(&pSchema->idxHash); i; i=sqliteHashNext(i)){ Index *pIdx = sqliteHashData(i); sqlite3_free(pIdx->aiRowEst); pIdx->aiRowEst = 0; diff --git a/src/build.c b/src/build.c index cd9c81be82..f85c55f0a1 100644 --- a/src/build.c +++ b/src/build.c @@ -3454,6 +3454,9 @@ void sqlite3DefaultRowEst(Index *pIdx){ int nCopy = MIN(ArraySize(aVal), pIdx->nKeyCol); int i; + /* Indexes with default row estimates should not have stat1 data */ + assert( !pIdx->hasStat1 ); + /* Set the first entry (number of rows in the index) to the estimated ** number of rows in the table, or half the number of rows in the table ** for a partial index. But do not let the estimate drop below 10. */ diff --git a/src/pragma.c b/src/pragma.c index b1775a4082..f28ff9d13c 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -1098,29 +1098,33 @@ void sqlite3Pragma( } break; +#ifdef SQLITE_DEBUG case PragTyp_STATS: { Index *pIdx; HashElem *i; - pParse->nMem = 4; + pParse->nMem = 5; sqlite3CodeVerifySchema(pParse, iDb); for(i=sqliteHashFirst(&pDb->pSchema->tblHash); i; i=sqliteHashNext(i)){ Table *pTab = sqliteHashData(i); - sqlite3VdbeMultiLoad(v, 1, "ssii", + sqlite3VdbeMultiLoad(v, 1, "ssiii", pTab->zName, 0, pTab->szTabRow, - pTab->nRowLogEst); - sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 4); + pTab->nRowLogEst, + pTab->tabFlags); + sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 5); for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ - sqlite3VdbeMultiLoad(v, 2, "sii", + sqlite3VdbeMultiLoad(v, 2, "siii", pIdx->zName, pIdx->szIdxRow, - pIdx->aiRowLogEst[0]); - sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 4); + pIdx->aiRowLogEst[0], + pIdx->hasStat1); + sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 5); } } } break; +#endif case PragTyp_INDEX_INFO: if( zRight ){ Index *pIdx; diff --git a/src/pragma.h b/src/pragma.h index 5d8d0aa35b..2a96ecaa43 100644 --- a/src/pragma.h +++ b/src/pragma.h @@ -34,20 +34,20 @@ #define PragTyp_SECURE_DELETE 26 #define PragTyp_SHRINK_MEMORY 27 #define PragTyp_SOFT_HEAP_LIMIT 28 -#define PragTyp_STATS 29 -#define PragTyp_SYNCHRONOUS 30 -#define PragTyp_TABLE_INFO 31 -#define PragTyp_TEMP_STORE 32 -#define PragTyp_TEMP_STORE_DIRECTORY 33 -#define PragTyp_THREADS 34 -#define PragTyp_WAL_AUTOCHECKPOINT 35 -#define PragTyp_WAL_CHECKPOINT 36 -#define PragTyp_ACTIVATE_EXTENSIONS 37 -#define PragTyp_HEXKEY 38 -#define PragTyp_KEY 39 -#define PragTyp_REKEY 40 -#define PragTyp_LOCK_STATUS 41 -#define PragTyp_PARSER_TRACE 42 +#define PragTyp_SYNCHRONOUS 29 +#define PragTyp_TABLE_INFO 30 +#define PragTyp_TEMP_STORE 31 +#define PragTyp_TEMP_STORE_DIRECTORY 32 +#define PragTyp_THREADS 33 +#define PragTyp_WAL_AUTOCHECKPOINT 34 +#define PragTyp_WAL_CHECKPOINT 35 +#define PragTyp_ACTIVATE_EXTENSIONS 36 +#define PragTyp_HEXKEY 37 +#define PragTyp_KEY 38 +#define PragTyp_REKEY 39 +#define PragTyp_LOCK_STATUS 40 +#define PragTyp_PARSER_TRACE 41 +#define PragTyp_STATS 42 /* Property flags associated with various pragma. */ #define PragFlg_NeedSchema 0x01 /* Force schema load before running */ @@ -75,43 +75,44 @@ static const char *const pragCName[] = { /* 8 */ "index", /* 9 */ "width", /* 10 */ "height", - /* 11 */ "seqno", /* Used by: index_info */ - /* 12 */ "cid", - /* 13 */ "name", - /* 14 */ "seqno", /* Used by: index_xinfo */ - /* 15 */ "cid", - /* 16 */ "name", - /* 17 */ "desc", - /* 18 */ "coll", - /* 19 */ "key", - /* 20 */ "seq", /* Used by: index_list */ - /* 21 */ "name", - /* 22 */ "unique", - /* 23 */ "origin", - /* 24 */ "partial", - /* 25 */ "seq", /* Used by: database_list */ - /* 26 */ "name", - /* 27 */ "file", - /* 28 */ "seq", /* Used by: collation_list */ - /* 29 */ "name", - /* 30 */ "id", /* Used by: foreign_key_list */ - /* 31 */ "seq", - /* 32 */ "table", - /* 33 */ "from", - /* 34 */ "to", - /* 35 */ "on_update", - /* 36 */ "on_delete", - /* 37 */ "match", - /* 38 */ "table", /* Used by: foreign_key_check */ - /* 39 */ "rowid", - /* 40 */ "parent", - /* 41 */ "fkid", - /* 42 */ "busy", /* Used by: wal_checkpoint */ - /* 43 */ "log", - /* 44 */ "checkpointed", - /* 45 */ "timeout", /* Used by: busy_timeout */ - /* 46 */ "database", /* Used by: lock_status */ - /* 47 */ "status", + /* 11 */ "flags", + /* 12 */ "seqno", /* Used by: index_info */ + /* 13 */ "cid", + /* 14 */ "name", + /* 15 */ "seqno", /* Used by: index_xinfo */ + /* 16 */ "cid", + /* 17 */ "name", + /* 18 */ "desc", + /* 19 */ "coll", + /* 20 */ "key", + /* 21 */ "seq", /* Used by: index_list */ + /* 22 */ "name", + /* 23 */ "unique", + /* 24 */ "origin", + /* 25 */ "partial", + /* 26 */ "seq", /* Used by: database_list */ + /* 27 */ "name", + /* 28 */ "file", + /* 29 */ "seq", /* Used by: collation_list */ + /* 30 */ "name", + /* 31 */ "id", /* Used by: foreign_key_list */ + /* 32 */ "seq", + /* 33 */ "table", + /* 34 */ "from", + /* 35 */ "to", + /* 36 */ "on_update", + /* 37 */ "on_delete", + /* 38 */ "match", + /* 39 */ "table", /* Used by: foreign_key_check */ + /* 40 */ "rowid", + /* 41 */ "parent", + /* 42 */ "fkid", + /* 43 */ "busy", /* Used by: wal_checkpoint */ + /* 44 */ "log", + /* 45 */ "checkpointed", + /* 46 */ "timeout", /* Used by: busy_timeout */ + /* 47 */ "database", /* Used by: lock_status */ + /* 48 */ "status", }; /* Definitions of all built-in pragmas */ @@ -157,7 +158,7 @@ static const PragmaName aPragmaName[] = { {/* zName: */ "busy_timeout", /* ePragTyp: */ PragTyp_BUSY_TIMEOUT, /* ePragFlg: */ PragFlg_Result0, - /* ColNames: */ 45, 1, + /* ColNames: */ 46, 1, /* iArg: */ 0 }, #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) {/* zName: */ "cache_size", @@ -194,7 +195,7 @@ static const PragmaName aPragmaName[] = { {/* zName: */ "collation_list", /* ePragTyp: */ PragTyp_COLLATION_LIST, /* ePragFlg: */ PragFlg_Result0, - /* ColNames: */ 28, 2, + /* ColNames: */ 29, 2, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_COMPILEOPTION_DIAGS) @@ -229,7 +230,7 @@ static const PragmaName aPragmaName[] = { {/* zName: */ "database_list", /* ePragTyp: */ PragTyp_DATABASE_LIST, /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0, - /* ColNames: */ 25, 3, + /* ColNames: */ 26, 3, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED) @@ -266,14 +267,14 @@ static const PragmaName aPragmaName[] = { {/* zName: */ "foreign_key_check", /* ePragTyp: */ PragTyp_FOREIGN_KEY_CHECK, /* ePragFlg: */ PragFlg_NeedSchema, - /* ColNames: */ 38, 4, + /* ColNames: */ 39, 4, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_FOREIGN_KEY) {/* zName: */ "foreign_key_list", /* ePragTyp: */ PragTyp_FOREIGN_KEY_LIST, /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt, - /* ColNames: */ 30, 8, + /* ColNames: */ 31, 8, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) @@ -336,17 +337,17 @@ static const PragmaName aPragmaName[] = { {/* zName: */ "index_info", /* ePragTyp: */ PragTyp_INDEX_INFO, /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt, - /* ColNames: */ 11, 3, + /* ColNames: */ 12, 3, /* iArg: */ 0 }, {/* zName: */ "index_list", /* ePragTyp: */ PragTyp_INDEX_LIST, /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt, - /* ColNames: */ 20, 5, + /* ColNames: */ 21, 5, /* iArg: */ 0 }, {/* zName: */ "index_xinfo", /* ePragTyp: */ PragTyp_INDEX_INFO, /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt, - /* ColNames: */ 14, 6, + /* ColNames: */ 15, 6, /* iArg: */ 1 }, #endif #if !defined(SQLITE_OMIT_INTEGRITY_CHECK) @@ -393,7 +394,7 @@ static const PragmaName aPragmaName[] = { {/* zName: */ "lock_status", /* ePragTyp: */ PragTyp_LOCK_STATUS, /* ePragFlg: */ PragFlg_Result0, - /* ColNames: */ 46, 2, + /* ColNames: */ 47, 2, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) @@ -510,11 +511,11 @@ static const PragmaName aPragmaName[] = { /* iArg: */ SQLITE_SqlTrace }, #endif #endif -#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) +#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) && defined(SQLITE_DEBUG) {/* zName: */ "stats", /* ePragTyp: */ PragTyp_STATS, /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq, - /* ColNames: */ 7, 4, + /* ColNames: */ 7, 5, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) @@ -593,7 +594,7 @@ static const PragmaName aPragmaName[] = { {/* zName: */ "wal_checkpoint", /* ePragTyp: */ PragTyp_WAL_CHECKPOINT, /* ePragFlg: */ PragFlg_NeedSchema, - /* ColNames: */ 42, 3, + /* ColNames: */ 43, 3, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) @@ -604,4 +605,4 @@ static const PragmaName aPragmaName[] = { /* iArg: */ SQLITE_WriteSchema|SQLITE_RecoveryMode }, #endif }; -/* Number of pragmas: 60 on by default, 73 total. */ +/* Number of pragmas: 59 on by default, 73 total. */ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 9a53d33626..6d58157b1b 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1879,15 +1879,14 @@ struct Table { ** the TF_OOOHidden attribute would apply in this case. Such tables require ** special handling during INSERT processing. */ -#define TF_Readonly 0x01 /* Read-only system table */ -#define TF_Ephemeral 0x02 /* An ephemeral table */ -#define TF_HasPrimaryKey 0x04 /* Table has a primary key */ -#define TF_Autoincrement 0x08 /* Integer primary key is autoincrement */ -/* available for reuse: 0x10 */ -#define TF_WithoutRowid 0x20 /* No rowid. PRIMARY KEY is the key */ -#define TF_NoVisibleRowid 0x40 /* No user-visible "rowid" column */ -#define TF_OOOHidden 0x80 /* Out-of-Order hidden columns */ - +#define TF_Readonly 0x0001 /* Read-only system table */ +#define TF_Ephemeral 0x0002 /* An ephemeral table */ +#define TF_HasPrimaryKey 0x0004 /* Table has a primary key */ +#define TF_Autoincrement 0x0008 /* Integer primary key is autoincrement */ +#define TF_HasStat1 0x0010 /* Has STAT1 data */ +#define TF_WithoutRowid 0x0020 /* No rowid. PRIMARY KEY is the key */ +#define TF_NoVisibleRowid 0x0040 /* No user-visible "rowid" column */ +#define TF_OOOHidden 0x0080 /* Out-of-Order hidden columns */ /* ** Test to see whether or not a table is a virtual table. This is @@ -2130,6 +2129,7 @@ struct Index { unsigned isResized:1; /* True if resizeIndexObject() has been called */ unsigned isCovering:1; /* True if this is a covering index */ unsigned noSkipScan:1; /* Do not try to use skip-scan if true */ + unsigned hasStat1:1; /* True if stat1 data has been loaded */ #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 int nSample; /* Number of elements in aSample[] */ int nSampleCol; /* Size of IndexSample.anEq[] and so on */ diff --git a/tool/mkpragmatab.tcl b/tool/mkpragmatab.tcl index c22f72d491..1c8bad54d3 100644 --- a/tool/mkpragmatab.tcl +++ b/tool/mkpragmatab.tcl @@ -225,8 +225,8 @@ set pragma_def { NAME: stats FLAG: NeedSchema Result0 SchemaReq - COLS: table index width height - IF: !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) + COLS: table index width height flags + IF: !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) && defined(SQLITE_DEBUG) NAME: index_info TYPE: INDEX_INFO From a3928dd7bee435f2cf4288b336968f6334376d39 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 17 Feb 2017 15:26:36 +0000 Subject: [PATCH 1346/1484] Set the TF_StatsUsed flag on tables when the query planner outcome is affected by the sqlite_stat1 data. Also, change the column names of the "PRAGMA stats" command so that they are not keywords. FossilOrigin-Name: fb2b8ae8310e4ea4b42354bbf36c3084a9d5c6d7 --- manifest | 24 ++++---- manifest.uuid | 2 +- src/pragma.h | 10 ++-- src/sqliteInt.h | 7 ++- src/where.c | 13 +++++ src/whereInt.h | 5 ++ test/autoanalyze1.test | 124 +++++++++++++++++++++++++++++++++++++++++ tool/mkpragmatab.tcl | 2 +- 8 files changed, 165 insertions(+), 22 deletions(-) create mode 100644 test/autoanalyze1.test diff --git a/manifest b/manifest index 04051afae1..360ecf7903 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\sthe\sIndex\sand\sTable\sobjects\sso\sthat\sthey\sremember\sif\stheir\sstats\scome\nfrom\sthe\ssqlite_stat1\stable.\s\sMake\sthe\s"PRAGMA\sstats"\san\sSQLITE_DEBUG\sonly\npragma.\s\sAdd\sthe\sflags\scolumn\sto\s"PRAGMA\sstats".\s\sThese\sare\sall\spreliminary\nsteps\stoward\sa\s"PRAGMA\sanalyze_ifneeded;"\sfeature. -D 2017-02-17T13:38:15.256 +C Set\sthe\sTF_StatsUsed\sflag\son\stables\swhen\sthe\squery\splanner\soutcome\sis\naffected\sby\sthe\ssqlite_stat1\sdata.\s\sAlso,\schange\sthe\scolumn\snames\sof\sthe\n"PRAGMA\sstats"\scommand\sso\sthat\sthey\sare\snot\skeywords. +D 2017-02-17T15:26:36.765 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 @@ -388,7 +388,7 @@ F src/pcache.c 62835bed959e2914edd26afadfecce29ece0e870 F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 F src/pcache1.c e3967219b2a92b9edcb9324a4ba75009090d3953 F src/pragma.c d4918a737f0bf1ad825654ebf07c4d009ff0ca63 -F src/pragma.h cea24a631982fd1a26fcddd46f596d22303b4247 +F src/pragma.h 9e65a9033cce7387c27cd89aecb2b2f205d1edf7 F src/prepare.c b1140c3d0cf59bc85ace00ce363153041b424b7a F src/printf.c 67427bbee66d891fc6f6f5aada857e9cdb368c1c F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 @@ -399,7 +399,7 @@ F src/shell.c bb8e20789499aec921a01d8744c616b81b8214f1 F src/sqlite.h.in 751ff125eb159c8f92c182b8df980a5e4f50e966 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae -F src/sqliteInt.h 54bc20855f2a1a99a1b726f1384b5ce9ab67a0ff +F src/sqliteInt.h 5d50606deed2b38b35fb1b5e4ab658f8faa37d4a F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 @@ -475,8 +475,8 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 40c543f0a2195d1b0dc88ef12142bea690009344 F src/wal.h 06b2a0b599cc0f53ea97f497cf8c6b758c999f71 F src/walker.c 91a6df7435827e41cff6bb7df50ea00934ee78b0 -F src/where.c 01baf58b72f3ddb7793cdee2871f751e3e09b35e -F src/whereInt.h c0b092180f04608d80c258174b0a14a1f9c8d02f +F src/where.c 1a3a8adb717a20f17c186f3baa22b0b5f3a5ab13 +F src/whereInt.h 2d50c2b74a33be44cb68fdecee30b4d93552f1f4 F src/wherecode.c 677e95413c472c0b413023b6b69a47f40fce1b04 F src/whereexpr.c 130cdd1a43af71b19755270fb1224874cf55158c F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 @@ -521,6 +521,7 @@ F test/attachmalloc.test 3a4bfca9545bfe906a8d2e622de10fbac5b711b0 F test/auth.test c6ede04bee65637ff354b43fc1235aa560c0863e F test/auth2.test 9eb7fce9f34bf1f50d3f366fb3e606be5a2000a1 F test/auth3.test 0d48b901cf111c14b4b1b5205c7d28f1a278190f +F test/autoanalyze1.test b31c18e73cf4e97b896288d8c817fce743f23e76 F test/autoinc.test 6ae8fb69c9f656962464ae4e6667045d0dfc3b46 F test/autoindex1.test 14b63a9f1e405fe6d5bfc8c8d00249c2ebaf13ea F test/autoindex2.test 12ef578928102baaa0dc23ad397601a2f4ecb0df @@ -1494,7 +1495,7 @@ F tool/mkmsvcmin.tcl 95b37e202cbed873aa8ffdbb493b9db45927be2b F tool/mkopcodec.tcl d1b6362bd3aa80d5520d4d6f3765badf01f6c43c F tool/mkopcodeh.tcl a01d2c1d8a6205b03fc635adf3735b4c523befd3 F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e -F tool/mkpragmatab.tcl 9c0a855e0daf83e54ffd9fd438260cd0c92f25d0 +F tool/mkpragmatab.tcl c955db934f7b1d800081447042cef692f26b2516 F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 F tool/mksqlite3c-noext.tcl fef88397668ae83166735c41af99d79f56afaabb F tool/mksqlite3c.tcl 06b2e6a0f21cc0a5d70fbbd136b3e0a96470645e @@ -1556,10 +1557,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 218b2bbb0de07288889f6762d4461ea8acd78969 -R af8aeffdf276070e8e8912906300a1a4 -T *branch * auto-analyze -T *sym-auto-analyze * -T -sym-trunk * +P 85026c8ee143bbd46565660fff8346ef81421546 +R 7cc0cc258beb93b198b99dc8e7b58520 U drh -Z f8720207819c88fb362c87de069d287a +Z 76eea0dfcfb8fa07347b6cdca98e2297 diff --git a/manifest.uuid b/manifest.uuid index fd9de00f55..1142241825 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -85026c8ee143bbd46565660fff8346ef81421546 \ No newline at end of file +fb2b8ae8310e4ea4b42354bbf36c3084a9d5c6d7 \ No newline at end of file diff --git a/src/pragma.h b/src/pragma.h index 2a96ecaa43..1592bbd2d5 100644 --- a/src/pragma.h +++ b/src/pragma.h @@ -71,11 +71,11 @@ static const char *const pragCName[] = { /* 4 */ "notnull", /* 5 */ "dflt_value", /* 6 */ "pk", - /* 7 */ "table", /* Used by: stats */ - /* 8 */ "index", - /* 9 */ "width", - /* 10 */ "height", - /* 11 */ "flags", + /* 7 */ "tbl", /* Used by: stats */ + /* 8 */ "idx", + /* 9 */ "wdth", + /* 10 */ "hght", + /* 11 */ "flgs", /* 12 */ "seqno", /* Used by: index_info */ /* 13 */ "cid", /* 14 */ "name", diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 6d58157b1b..3c75f2ff6e 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1883,10 +1883,13 @@ struct Table { #define TF_Ephemeral 0x0002 /* An ephemeral table */ #define TF_HasPrimaryKey 0x0004 /* Table has a primary key */ #define TF_Autoincrement 0x0008 /* Integer primary key is autoincrement */ -#define TF_HasStat1 0x0010 /* Has STAT1 data */ +#define TF_HasStat1 0x0010 /* nRowLogEst set from sqlite_stat1 */ #define TF_WithoutRowid 0x0020 /* No rowid. PRIMARY KEY is the key */ #define TF_NoVisibleRowid 0x0040 /* No user-visible "rowid" column */ #define TF_OOOHidden 0x0080 /* Out-of-Order hidden columns */ +#define TF_SizeChng 0x0100 /* nRowLogEst might be inaccurate */ +#define TF_StatsUsed 0x0200 /* Query planner decisions affected by + ** Index.aiRowLogEst[] values */ /* ** Test to see whether or not a table is a virtual table. This is @@ -2129,7 +2132,7 @@ struct Index { unsigned isResized:1; /* True if resizeIndexObject() has been called */ unsigned isCovering:1; /* True if this is a covering index */ unsigned noSkipScan:1; /* Do not try to use skip-scan if true */ - unsigned hasStat1:1; /* True if stat1 data has been loaded */ + unsigned hasStat1:1; /* aiRowLogEst values come from sqlite_stat1 */ #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 int nSample; /* Number of elements in aSample[] */ int nSampleCol; /* Size of IndexSample.anEq[] and so on */ diff --git a/src/where.c b/src/where.c index f2bf400a2d..8d0dbb0979 100644 --- a/src/where.c +++ b/src/where.c @@ -2387,6 +2387,11 @@ static int whereLoopAddBtreeIndex( continue; } + if( IsUniqueIndex(pProbe) && saved_nEq==pProbe->nKeyCol-1 ){ + pBuilder->bldFlags |= SQLITE_BLDF_UNIQUE; + }else{ + pBuilder->bldFlags |= SQLITE_BLDF_INDEXED; + } pNew->wsFlags = saved_wsFlags; pNew->u.btree.nEq = saved_nEq; pNew->u.btree.nBtm = saved_nBtm; @@ -2934,7 +2939,15 @@ static int whereLoopAddBtree( } } + pBuilder->bldFlags = 0; rc = whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, 0); + if( pBuilder->bldFlags==SQLITE_BLDF_INDEXED ){ + /* If a non-unique index is used, or if a prefix of the key for + ** unique index is used (making the index functionally non-unique) + ** then the sqlite_stat1 data becomes important for scoring the + ** plan */ + pTab->tabFlags |= TF_StatsUsed; + } #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 sqlite3Stat4ProbeFree(pBuilder->pRec); pBuilder->nRecValid = 0; diff --git a/src/whereInt.h b/src/whereInt.h index c6195f53ed..f065fae6ba 100644 --- a/src/whereInt.h +++ b/src/whereInt.h @@ -395,8 +395,13 @@ struct WhereLoopBuilder { UnpackedRecord *pRec; /* Probe for stat4 (if required) */ int nRecValid; /* Number of valid fields currently in pRec */ #endif + unsigned int bldFlags; /* SQLITE_BLDF_* flags */ }; +/* Allowed values for WhereLoopBuider.bldFlags */ +#define SQLITE_BLDF_INDEXED 0x0001 /* An index is used */ +#define SQLITE_BLDF_UNIQUE 0x0002 /* All keys of a UNIQUE index used */ + /* ** The WHERE clause processing routine has two halves. The ** first part does the start of the WHERE loop and the second diff --git a/test/autoanalyze1.test b/test/autoanalyze1.test new file mode 100644 index 0000000000..c36e0fcbc7 --- /dev/null +++ b/test/autoanalyze1.test @@ -0,0 +1,124 @@ +# 2017-02-17 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# This file implements tests for the logic used to estimate when +# running ANALYZE would be beneficial. +# +# Note that this test uses some hard-coded bitmask values from sqliteInt.h. +# If any of the following constants changes: +# +# define TF_HasStat1 0x0010 +# define TF_SizeChng 0x0100 +# define TF_StatsUsed 0x0200 +# +# then some of the magic numbers in test results below might need to be +# adjusted. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +# There is nothing to test if ANALYZE is disable for this build. +# These tests also use "PRAGMA stats" which are only enabled for +# debugging builds. +# +ifcapable {!debug || !analyze} { + finish_test + return +} + +do_execsql_test autoanalyze1-100 { + -- Build up a test table with some indexes + CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c, d); + CREATE UNIQUE INDEX t1bc ON t1(b,c); + CREATE INDEX t1d ON t1(d); + WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<100) + INSERT INTO t1(a,b,c,d) SELECT x, x, x, x FROM c; + -- Verify that the hasStat1 flag is clear on on indexes + SELECT idx, flgs FROM pragma_stats + WHERE idx IS NOT NULL + ORDER BY idx; + -- Verify that the TF_HasStat1 flag is clear on the table + SELECT tbl, (flgs & 0x10)!=0 FROM pragma_stats WHERE tbl='t1' AND idx IS NULL; +} {t1bc 0 t1d 0 t1 0} + +# No use of stat1 recorded so far +do_execsql_test autoanalyze1-110 { + SELECT (flgs & 0x0200)!=0 FROM pragma_stats WHERE tbl='t1' AND idx IS NULL; +} {0} + +# Access using a unique index does not set the TF_StatsUsed flag. +# +do_execsql_test autoanalyze1-200 { + SELECT * FROM t1 WHERE a=55; +} {55 55 55 55} +do_execsql_test autoanalyze1-201 { + SELECT (flgs & 0x0200)!=0 FROM pragma_stats WHERE tbl='t1' AND idx IS NULL; +} {0} + +do_execsql_test autoanalyze1-210 { + SELECT * FROM t1 WHERE a IN (55,199,299); +} {55 55 55 55} +do_execsql_test autoanalyze1-211 { + SELECT (flgs & 0x0200)!=0 FROM pragma_stats WHERE tbl='t1' AND idx IS NULL; +} {0} + +do_execsql_test autoanalyze1-220 { + SELECT * FROM t1 WHERE (b,c)=(45,45); +} {45 45 45 45} +do_execsql_test autoanalyze1-221 { + SELECT (flgs & 0x0200)!=0 FROM pragma_stats WHERE tbl='t1' AND idx IS NULL; +} {0} + +# Any use of the non-unique t1d index triggers the use of stats. +# +sqlite3 db test.db +do_execsql_test autoanalyze1-300 { + SELECT * FROM t1 WHERE d=45; +} {45 45 45 45} +do_execsql_test autoanalyze1-301 { + SELECT (flgs & 0x0200)!=0 FROM pragma_stats WHERE tbl='t1' AND idx IS NULL; +} {1} + +sqlite3 db test.db +do_execsql_test autoanalyze1-310 { + SELECT * FROM t1 WHERE d=45 AND a=45; +} {45 45 45 45} +do_execsql_test autoanalyze1-311 { + SELECT (flgs & 0x0200)!=0 FROM pragma_stats WHERE tbl='t1' AND idx IS NULL; +} {0} ;# The ROWID lookup short-circuits the d=45 constraint + +sqlite3 db test.db +do_execsql_test autoanalyze1-320 { + SELECT * FROM t1 WHERE d=45 AND a IN (45,46); +} {45 45 45 45} +do_execsql_test autoanalyze1-321 { + SELECT (flgs & 0x0200)!=0 FROM pragma_stats WHERE tbl='t1' AND idx IS NULL; +} {1} + +# Any use of prefix of a unique index triggers the use of stats +# +sqlite3 db test.db +do_execsql_test autoanalyze1-400 { + SELECT * FROM t1 WHERE b=45; +} {45 45 45 45} +do_execsql_test autoanalyze1-401 { + SELECT (flgs & 0x0200)!=0 FROM pragma_stats WHERE tbl='t1' AND idx IS NULL; +} {1} + +# The TF_StatsUsed flag is reset when the database is reopened +# +sqlite3 db test.db +do_execsql_test autoanalyze1-500 { + SELECT (flgs & 0x0200)!=0 FROM pragma_stats WHERE tbl='t1' AND idx IS NULL; +} {0} + +finish_test diff --git a/tool/mkpragmatab.tcl b/tool/mkpragmatab.tcl index 1c8bad54d3..005c4bc48e 100644 --- a/tool/mkpragmatab.tcl +++ b/tool/mkpragmatab.tcl @@ -225,7 +225,7 @@ set pragma_def { NAME: stats FLAG: NeedSchema Result0 SchemaReq - COLS: table index width height flags + COLS: tbl idx wdth hght flgs IF: !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) && defined(SQLITE_DEBUG) NAME: index_info From 72052a73a3d1fc75015aa4123bea9af2f5a58e3f Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 17 Feb 2017 16:26:34 +0000 Subject: [PATCH 1347/1484] Add the "PRAGMA analyze_as_needed" command. FossilOrigin-Name: e93db2373127d31d33ec46ef918fa9386bb664a6 --- manifest | 22 +++++------ manifest.uuid | 2 +- src/analyze.c | 88 ++++++++++++++++++++++++++++++----------- src/parse.y | 4 +- src/pragma.c | 8 ++++ src/pragma.h | 94 +++++++++++++++++++++++--------------------- src/sqliteInt.h | 2 +- tool/mkpragmatab.tcl | 3 ++ 8 files changed, 141 insertions(+), 82 deletions(-) diff --git a/manifest b/manifest index 360ecf7903..9d27e603a6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Set\sthe\sTF_StatsUsed\sflag\son\stables\swhen\sthe\squery\splanner\soutcome\sis\naffected\sby\sthe\ssqlite_stat1\sdata.\s\sAlso,\schange\sthe\scolumn\snames\sof\sthe\n"PRAGMA\sstats"\scommand\sso\sthat\sthey\sare\snot\skeywords. -D 2017-02-17T15:26:36.765 +C Add\sthe\s"PRAGMA\sanalyze_as_needed"\scommand. +D 2017-02-17T16:26:34.780 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 @@ -331,7 +331,7 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F src/alter.c 3b23977620ce9662ac54443f65b87ba996e36121 -F src/analyze.c 1b7197d619788353437d390de42a9bccbb4aa2ac +F src/analyze.c 39206f31ca136a0a4d4f1d6bfd00bc81c6b3e5ec F src/attach.c 8c476f8bd5d2afe11d925f890d30e527e5b0ce43 F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792 F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b @@ -383,12 +383,12 @@ F src/os_win.c cf90abd4e50d9f56d2c20ce8e005aff55d7bd8e9 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c ff1232b3088a39806035ecfac4fffeb22717d80b F src/pager.h f2a99646c5533ffe11afa43e9e0bea74054e4efa -F src/parse.y 591704fce84f814d9a3642774c1f011d38f4149c +F src/parse.y d5695ae4887a52352b1b8a3e3623477c7e79abeb F src/pcache.c 62835bed959e2914edd26afadfecce29ece0e870 F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 F src/pcache1.c e3967219b2a92b9edcb9324a4ba75009090d3953 -F src/pragma.c d4918a737f0bf1ad825654ebf07c4d009ff0ca63 -F src/pragma.h 9e65a9033cce7387c27cd89aecb2b2f205d1edf7 +F src/pragma.c e8b2ea66dfb1b90c53b920c08914ac26b109053a +F src/pragma.h 065e184494f12e94111da1ab6984faa7b6142e68 F src/prepare.c b1140c3d0cf59bc85ace00ce363153041b424b7a F src/printf.c 67427bbee66d891fc6f6f5aada857e9cdb368c1c F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 @@ -399,7 +399,7 @@ F src/shell.c bb8e20789499aec921a01d8744c616b81b8214f1 F src/sqlite.h.in 751ff125eb159c8f92c182b8df980a5e4f50e966 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae -F src/sqliteInt.h 5d50606deed2b38b35fb1b5e4ab658f8faa37d4a +F src/sqliteInt.h 85706e0963964336270590a1e508dec78540bc5c F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 @@ -1495,7 +1495,7 @@ F tool/mkmsvcmin.tcl 95b37e202cbed873aa8ffdbb493b9db45927be2b F tool/mkopcodec.tcl d1b6362bd3aa80d5520d4d6f3765badf01f6c43c F tool/mkopcodeh.tcl a01d2c1d8a6205b03fc635adf3735b4c523befd3 F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e -F tool/mkpragmatab.tcl c955db934f7b1d800081447042cef692f26b2516 +F tool/mkpragmatab.tcl 6fd5ecb4a8debee39e3bb4e63f0634f69edfb861 F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 F tool/mksqlite3c-noext.tcl fef88397668ae83166735c41af99d79f56afaabb F tool/mksqlite3c.tcl 06b2e6a0f21cc0a5d70fbbd136b3e0a96470645e @@ -1557,7 +1557,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 85026c8ee143bbd46565660fff8346ef81421546 -R 7cc0cc258beb93b198b99dc8e7b58520 +P fb2b8ae8310e4ea4b42354bbf36c3084a9d5c6d7 +R 23ff1c8d68460fd739a12857d6287bf8 U drh -Z 76eea0dfcfb8fa07347b6cdca98e2297 +Z 4884503796ef3cb7f91c7100ffa75ea8 diff --git a/manifest.uuid b/manifest.uuid index 1142241825..f532ee84dd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fb2b8ae8310e4ea4b42354bbf36c3084a9d5c6d7 \ No newline at end of file +e93db2373127d31d33ec46ef918fa9386bb664a6 \ No newline at end of file diff --git a/src/analyze.c b/src/analyze.c index 3ecf469cd3..34de7fc744 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -1286,28 +1286,66 @@ static void loadAnalysis(Parse *pParse, int iDb){ } /* -** Generate code that will do an analysis of an entire database +** Return true if table pTab is in need of being reanalyzed. */ -static void analyzeDatabase(Parse *pParse, int iDb){ +static int analyzeNeeded(Table *pTab){ + Index *pIdx; + if( (pTab->tabFlags & TF_StatsUsed)==0 ) return 0; + if( (pTab->tabFlags & TF_SizeChng)!=0 ) return 1; + for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + if( !pIdx->hasStat1 ) return 1; + } + return 0; +} + +/* +** Generate code that will do an analysis of an entire database. +** +** Return a count of the number of tables actually analyzed. Return 0 +** if nothing was analyzed. +*/ +static int analyzeDatabase(Parse *pParse, int iDbReq, int onlyIfNeeded){ sqlite3 *db = pParse->db; - Schema *pSchema = db->aDb[iDb].pSchema; /* Schema of database iDb */ + Schema *pSchema; HashElem *k; int iStatCur; int iMem; int iTab; + int iDb; /* Database currently being analyzed */ + int iDbFirst, iDbLast; /* Range of databases to be analyzed */ + int cnt; /* Number of tables analyzed in a single database */ + int allCnt = 0; /* Number of tables analyzed across all databases */ - sqlite3BeginWriteOperation(pParse, 0, iDb); - iStatCur = pParse->nTab; - pParse->nTab += 3; - openStatTable(pParse, iDb, iStatCur, 0, 0); - iMem = pParse->nMem+1; - iTab = pParse->nTab; - assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); - for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){ - Table *pTab = (Table*)sqliteHashData(k); - analyzeOneTable(pParse, pTab, 0, iStatCur, iMem, iTab); + if( iDbReq>=0 ){ + iDbFirst = iDbLast = iDbReq; + }else{ + iDbFirst = 0; + iDbLast = db->nDb-1; } - loadAnalysis(pParse, iDb); + for(iDb=iDbFirst; iDb<=iDbLast; iDb++){ + if( iDb==1 ) continue; /* Do not analyze the TEMP database */ + pSchema = db->aDb[iDb].pSchema; + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + cnt = 0; + for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){ + Table *pTab = (Table*)sqliteHashData(k); + if( !onlyIfNeeded || analyzeNeeded(pTab) ){ + if( cnt==0 ){ + sqlite3BeginWriteOperation(pParse, 0, iDb); + iStatCur = pParse->nTab; + pParse->nTab += 3; + openStatTable(pParse, iDb, iStatCur, 0, 0); + iMem = pParse->nMem+1; + iTab = pParse->nTab; + } + analyzeOneTable(pParse, pTab, 0, iStatCur, iMem, iTab); + cnt++; + allCnt++; + } + } + if( cnt ) loadAnalysis(pParse, iDb); + } + return allCnt; } /* @@ -1345,16 +1383,21 @@ static void analyzeTable(Parse *pParse, Table *pTab, Index *pOnlyIdx){ ** Form 1 causes all indices in all attached databases to be analyzed. ** Form 2 analyzes all indices the single database named. ** Form 3 analyzes all indices associated with the named table. +** +** If pName1 and pName2 are both NULL and if the ifNeeded flag is true, +** this routine computes an conditional ANALYZE on only those tables +** are believed to be in need of analysis. The conditional analysis +** might well be a no-op. */ -void sqlite3Analyze(Parse *pParse, Token *pName1, Token *pName2){ +void sqlite3Analyze(Parse *pParse, Token *pName1, Token *pName2, int ifNeeded){ sqlite3 *db = pParse->db; int iDb; - int i; char *z, *zDb; Table *pTab; Index *pIdx; Token *pTableName; Vdbe *v; + int needExpire = 1; /* Read the database schema. If an error occurs, leave an error message ** and code in pParse and return NULL. */ @@ -1366,15 +1409,12 @@ void sqlite3Analyze(Parse *pParse, Token *pName1, Token *pName2){ assert( pName2!=0 || pName1==0 ); if( pName1==0 ){ /* Form 1: Analyze everything */ - for(i=0; inDb; i++){ - if( i==1 ) continue; /* Do not analyze the TEMP database */ - analyzeDatabase(pParse, i); - } + needExpire = analyzeDatabase(pParse, -1, ifNeeded) || ifNeeded==0; }else if( pName2->n==0 ){ /* Form 2: Analyze the database or table named */ iDb = sqlite3FindDb(db, pName1); if( iDb>=0 ){ - analyzeDatabase(pParse, iDb); + analyzeDatabase(pParse, iDb, 0); }else{ z = sqlite3NameFromToken(db, pName1); if( z ){ @@ -1402,8 +1442,10 @@ void sqlite3Analyze(Parse *pParse, Token *pName1, Token *pName2){ } } } - v = sqlite3GetVdbe(pParse); - if( v ) sqlite3VdbeAddOp0(v, OP_Expire); + if( needExpire ){ + v = sqlite3GetVdbe(pParse); + if( v ) sqlite3VdbeAddOp0(v, OP_Expire); + } } /* diff --git a/src/parse.y b/src/parse.y index 9cada2a1be..ff03c128ac 100644 --- a/src/parse.y +++ b/src/parse.y @@ -1512,8 +1512,8 @@ cmd ::= REINDEX nm(X) dbnm(Y). {sqlite3Reindex(pParse, &X, &Y);} /////////////////////////////////// ANALYZE /////////////////////////////////// %ifndef SQLITE_OMIT_ANALYZE -cmd ::= ANALYZE. {sqlite3Analyze(pParse, 0, 0);} -cmd ::= ANALYZE nm(X) dbnm(Y). {sqlite3Analyze(pParse, &X, &Y);} +cmd ::= ANALYZE. {sqlite3Analyze(pParse, 0, 0, 0);} +cmd ::= ANALYZE nm(X) dbnm(Y). {sqlite3Analyze(pParse, &X, &Y, 0);} %endif //////////////////////// ALTER TABLE table ... //////////////////////////////// diff --git a/src/pragma.c b/src/pragma.c index f28ff9d13c..789751958c 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -1828,6 +1828,14 @@ void sqlite3Pragma( break; } + /* + ** PRAGMA analyze_as_needed + */ + case PragTyp_ANALYZE_AS_NEEDED: { + sqlite3Analyze(pParse, 0, 0, 1); + break; + } + /* ** PRAGMA busy_timeout ** PRAGMA busy_timeout = N diff --git a/src/pragma.h b/src/pragma.h index 1592bbd2d5..ba107ec07e 100644 --- a/src/pragma.h +++ b/src/pragma.h @@ -5,49 +5,50 @@ */ /* The various pragma types */ -#define PragTyp_HEADER_VALUE 0 -#define PragTyp_AUTO_VACUUM 1 -#define PragTyp_FLAG 2 -#define PragTyp_BUSY_TIMEOUT 3 -#define PragTyp_CACHE_SIZE 4 -#define PragTyp_CACHE_SPILL 5 -#define PragTyp_CASE_SENSITIVE_LIKE 6 -#define PragTyp_COLLATION_LIST 7 -#define PragTyp_COMPILE_OPTIONS 8 -#define PragTyp_DATA_STORE_DIRECTORY 9 -#define PragTyp_DATABASE_LIST 10 -#define PragTyp_DEFAULT_CACHE_SIZE 11 -#define PragTyp_ENCODING 12 -#define PragTyp_FOREIGN_KEY_CHECK 13 -#define PragTyp_FOREIGN_KEY_LIST 14 -#define PragTyp_INCREMENTAL_VACUUM 15 -#define PragTyp_INDEX_INFO 16 -#define PragTyp_INDEX_LIST 17 -#define PragTyp_INTEGRITY_CHECK 18 -#define PragTyp_JOURNAL_MODE 19 -#define PragTyp_JOURNAL_SIZE_LIMIT 20 -#define PragTyp_LOCK_PROXY_FILE 21 -#define PragTyp_LOCKING_MODE 22 -#define PragTyp_PAGE_COUNT 23 -#define PragTyp_MMAP_SIZE 24 -#define PragTyp_PAGE_SIZE 25 -#define PragTyp_SECURE_DELETE 26 -#define PragTyp_SHRINK_MEMORY 27 -#define PragTyp_SOFT_HEAP_LIMIT 28 -#define PragTyp_SYNCHRONOUS 29 -#define PragTyp_TABLE_INFO 30 -#define PragTyp_TEMP_STORE 31 -#define PragTyp_TEMP_STORE_DIRECTORY 32 -#define PragTyp_THREADS 33 -#define PragTyp_WAL_AUTOCHECKPOINT 34 -#define PragTyp_WAL_CHECKPOINT 35 -#define PragTyp_ACTIVATE_EXTENSIONS 36 -#define PragTyp_HEXKEY 37 -#define PragTyp_KEY 38 -#define PragTyp_REKEY 39 -#define PragTyp_LOCK_STATUS 40 -#define PragTyp_PARSER_TRACE 41 -#define PragTyp_STATS 42 +#define PragTyp_ANALYZE_AS_NEEDED 0 +#define PragTyp_HEADER_VALUE 1 +#define PragTyp_AUTO_VACUUM 2 +#define PragTyp_FLAG 3 +#define PragTyp_BUSY_TIMEOUT 4 +#define PragTyp_CACHE_SIZE 5 +#define PragTyp_CACHE_SPILL 6 +#define PragTyp_CASE_SENSITIVE_LIKE 7 +#define PragTyp_COLLATION_LIST 8 +#define PragTyp_COMPILE_OPTIONS 9 +#define PragTyp_DATA_STORE_DIRECTORY 10 +#define PragTyp_DATABASE_LIST 11 +#define PragTyp_DEFAULT_CACHE_SIZE 12 +#define PragTyp_ENCODING 13 +#define PragTyp_FOREIGN_KEY_CHECK 14 +#define PragTyp_FOREIGN_KEY_LIST 15 +#define PragTyp_INCREMENTAL_VACUUM 16 +#define PragTyp_INDEX_INFO 17 +#define PragTyp_INDEX_LIST 18 +#define PragTyp_INTEGRITY_CHECK 19 +#define PragTyp_JOURNAL_MODE 20 +#define PragTyp_JOURNAL_SIZE_LIMIT 21 +#define PragTyp_LOCK_PROXY_FILE 22 +#define PragTyp_LOCKING_MODE 23 +#define PragTyp_PAGE_COUNT 24 +#define PragTyp_MMAP_SIZE 25 +#define PragTyp_PAGE_SIZE 26 +#define PragTyp_SECURE_DELETE 27 +#define PragTyp_SHRINK_MEMORY 28 +#define PragTyp_SOFT_HEAP_LIMIT 29 +#define PragTyp_SYNCHRONOUS 30 +#define PragTyp_TABLE_INFO 31 +#define PragTyp_TEMP_STORE 32 +#define PragTyp_TEMP_STORE_DIRECTORY 33 +#define PragTyp_THREADS 34 +#define PragTyp_WAL_AUTOCHECKPOINT 35 +#define PragTyp_WAL_CHECKPOINT 36 +#define PragTyp_ACTIVATE_EXTENSIONS 37 +#define PragTyp_HEXKEY 38 +#define PragTyp_KEY 39 +#define PragTyp_REKEY 40 +#define PragTyp_LOCK_STATUS 41 +#define PragTyp_PARSER_TRACE 42 +#define PragTyp_STATS 43 /* Property flags associated with various pragma. */ #define PragFlg_NeedSchema 0x01 /* Force schema load before running */ @@ -132,6 +133,11 @@ static const PragmaName aPragmaName[] = { /* ColNames: */ 0, 0, /* iArg: */ 0 }, #endif + {/* zName: */ "analyze_as_needed", + /* ePragTyp: */ PragTyp_ANALYZE_AS_NEEDED, + /* ePragFlg: */ PragFlg_NoColumns, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, #if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) {/* zName: */ "application_id", /* ePragTyp: */ PragTyp_HEADER_VALUE, @@ -605,4 +611,4 @@ static const PragmaName aPragmaName[] = { /* iArg: */ SQLITE_WriteSchema|SQLITE_RecoveryMode }, #endif }; -/* Number of pragmas: 59 on by default, 73 total. */ +/* Number of pragmas: 60 on by default, 74 total. */ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 3c75f2ff6e..f590c85f93 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -4028,7 +4028,7 @@ void sqlite3AlterFinishAddColumn(Parse *, Token *); void sqlite3AlterBeginAddColumn(Parse *, SrcList *); CollSeq *sqlite3GetCollSeq(Parse*, u8, CollSeq *, const char*); char sqlite3AffinityType(const char*, u8*); -void sqlite3Analyze(Parse*, Token*, Token*); +void sqlite3Analyze(Parse*, Token*, Token*, int); int sqlite3InvokeBusyHandler(BusyHandler*); int sqlite3FindDb(sqlite3*, Token*); int sqlite3FindDbName(sqlite3 *, const char *); diff --git a/tool/mkpragmatab.tcl b/tool/mkpragmatab.tcl index 005c4bc48e..2201ea1306 100644 --- a/tool/mkpragmatab.tcl +++ b/tool/mkpragmatab.tcl @@ -361,6 +361,9 @@ set pragma_def { NAME: threads FLAG: Result0 + + NAME: analyze_as_needed + FLAG: NoColumns } # Open the output file From 5e98e838da57d5d70c1b3321c73e82206f5c8457 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 17 Feb 2017 19:24:06 +0000 Subject: [PATCH 1348/1484] The analyze_as_needed pragma now responds to table size growth and will automatically rerun the analysis after each 10x size increase. FossilOrigin-Name: bfbdd07409688fac4ccddbab3639745f6152e23d --- manifest | 22 ++++++++++----------- manifest.uuid | 2 +- src/analyze.c | 43 +++++++++++++++++++++++++++++++++--------- src/btree.c | 19 +++++++++++++++++++ src/btree.h | 1 + src/sqliteInt.h | 3 +-- src/vdbe.c | 27 ++++++++++++++++++++++++++ test/autoanalyze1.test | 21 ++++++++++----------- 8 files changed, 104 insertions(+), 34 deletions(-) diff --git a/manifest b/manifest index 9d27e603a6..42a11a725c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\s"PRAGMA\sanalyze_as_needed"\scommand. -D 2017-02-17T16:26:34.780 +C The\sanalyze_as_needed\spragma\snow\sresponds\sto\stable\ssize\sgrowth\sand\swill\nautomatically\srerun\sthe\sanalysis\safter\seach\s10x\ssize\sincrease. +D 2017-02-17T19:24:06.618 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 @@ -331,14 +331,14 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F src/alter.c 3b23977620ce9662ac54443f65b87ba996e36121 -F src/analyze.c 39206f31ca136a0a4d4f1d6bfd00bc81c6b3e5ec +F src/analyze.c acef9c48eac30438e82f39eb8df6682c6e33942e F src/attach.c 8c476f8bd5d2afe11d925f890d30e527e5b0ce43 F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792 F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca -F src/btree.c 3ae66974881e74df9909093818b4c3428f8d7982 -F src/btree.h e6d352808956ec163a17f832193a3e198b3fb0ac +F src/btree.c e7d724b02365d88920171caf0c919aa96d9b19e3 +F src/btree.h bf64dfeeddeebdb775a5eba0098bbc00d073290d F src/btreeInt.h cd55d39d9916270837a88c12e701047cba0729b0 F src/build.c 2e05d0360568f40dc583461f2211f020ff282ee4 F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 @@ -399,7 +399,7 @@ F src/shell.c bb8e20789499aec921a01d8744c616b81b8214f1 F src/sqlite.h.in 751ff125eb159c8f92c182b8df980a5e4f50e966 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae -F src/sqliteInt.h 85706e0963964336270590a1e508dec78540bc5c +F src/sqliteInt.h 60c38b84a796cc9d0a9a794cca254b09898b9cc5 F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 @@ -461,7 +461,7 @@ F src/update.c 456d4a4656f8a03c2abc88a51b19172197400e58 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c ca8440ede81e155d15cff7c101654f60b55a9ae6 F src/vacuum.c 33c174b28886b2faf26e503b5a49a1c01a9b1c16 -F src/vdbe.c 16f378640570c24442fd7191b136b5d6380f5c7b +F src/vdbe.c ac8538b96af5c63d6f18484ffd981d4f44db0073 F src/vdbe.h 59998ffd71d7caa8886bc78dafaf8caeccd4c13c F src/vdbeInt.h 4e4b15b2e1330e1636e4e01974eab2b0b985092f F src/vdbeapi.c 3e4a8893feeb78620f4aac4ac5b85d92255b97e1 @@ -521,7 +521,7 @@ F test/attachmalloc.test 3a4bfca9545bfe906a8d2e622de10fbac5b711b0 F test/auth.test c6ede04bee65637ff354b43fc1235aa560c0863e F test/auth2.test 9eb7fce9f34bf1f50d3f366fb3e606be5a2000a1 F test/auth3.test 0d48b901cf111c14b4b1b5205c7d28f1a278190f -F test/autoanalyze1.test b31c18e73cf4e97b896288d8c817fce743f23e76 +F test/autoanalyze1.test 1ba80d5e1412d46503566b70741a5eea060da929 F test/autoinc.test 6ae8fb69c9f656962464ae4e6667045d0dfc3b46 F test/autoindex1.test 14b63a9f1e405fe6d5bfc8c8d00249c2ebaf13ea F test/autoindex2.test 12ef578928102baaa0dc23ad397601a2f4ecb0df @@ -1557,7 +1557,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P fb2b8ae8310e4ea4b42354bbf36c3084a9d5c6d7 -R 23ff1c8d68460fd739a12857d6287bf8 +P e93db2373127d31d33ec46ef918fa9386bb664a6 +R 484e61dbf95be1098adb3acfa069e723 U drh -Z 4884503796ef3cb7f91c7100ffa75ea8 +Z 81466028927592a195c5763d3460fcde diff --git a/manifest.uuid b/manifest.uuid index f532ee84dd..8be7eeb5b9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e93db2373127d31d33ec46ef918fa9386bb664a6 \ No newline at end of file +bfbdd07409688fac4ccddbab3639745f6152e23d \ No newline at end of file diff --git a/src/analyze.c b/src/analyze.c index 34de7fc744..082713fd23 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -958,10 +958,12 @@ static void analyzeOneTable( Index *pOnlyIdx, /* If not NULL, only analyze this one index */ int iStatCur, /* Index of VdbeCursor that writes the sqlite_stat1 table */ int iMem, /* Available memory locations begin here */ - int iTab /* Next available cursor */ + int iTab, /* Next available cursor */ + LogEst szOld /* Run the analysis if table row count is larger than this */ ){ sqlite3 *db = pParse->db; /* Database handle */ Index *pIdx; /* An index to being analyzed */ + int addrSizeCk = 0; /* Address of the IfSmaller */ int iIdxCur; /* Cursor open on index being analyzed */ int iTabCur; /* Table cursor */ Vdbe *v; /* The virtual machine being built up */ @@ -1014,6 +1016,9 @@ static void analyzeOneTable( iIdxCur = iTab++; pParse->nTab = MAX(pParse->nTab, iTab); sqlite3OpenTable(pParse, iTabCur, iDb, pTab, OP_OpenRead); + if( szOld>0 ){ + addrSizeCk = sqlite3VdbeAddOp3(v, OP_IfSmaller, iTabCur, 0, szOld); + } sqlite3VdbeLoadString(v, regTabname, pTab->zName); for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ @@ -1271,6 +1276,7 @@ static void analyzeOneTable( sqlite3VdbeChangeP5(v, OPFLAG_APPEND); sqlite3VdbeJumpHere(v, jZeroRows); } + sqlite3VdbeJumpHere(v, addrSizeCk); } @@ -1286,16 +1292,33 @@ static void loadAnalysis(Parse *pParse, int iDb){ } /* -** Return true if table pTab is in need of being reanalyzed. +** Return true if table pTab might need to being reanalyzed. Return +** false if we know that pTab should not be reanalyzed. +** +** If returning true, also set *pThreshold to a size threshold that +** will determine at run-time whether or not the reanalysis occurs. +** The reanalysis will only occur if the size of the table is greater +** than the threshold. Not that the threshold is a logarithmic LogEst +** value. */ -static int analyzeNeeded(Table *pTab){ +static int analyzeNeeded(Table *pTab, LogEst *pThreshold){ Index *pIdx; if( (pTab->tabFlags & TF_StatsUsed)==0 ) return 0; - if( (pTab->tabFlags & TF_SizeChng)!=0 ) return 1; + + /* If TF_StatsUsed is true, then we might need to reanalyze. But + ** only reanalyze if the table size has grown by a factor of 10 or more */ + *pThreshold = pTab->nRowLogEst + 33; assert( sqlite3LogEst(10)==33 ); + + /* Except, if any of the indexes of the table do not have valid + ** sqlite_stat1 entries, then set the size threshold to zero to + ** ensure the analysis will always occur. */ for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ - if( !pIdx->hasStat1 ) return 1; + if( !pIdx->hasStat1 ){ + *pThreshold = 0; + break; + } } - return 0; + return 1; } /* @@ -1329,7 +1352,8 @@ static int analyzeDatabase(Parse *pParse, int iDbReq, int onlyIfNeeded){ cnt = 0; for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){ Table *pTab = (Table*)sqliteHashData(k); - if( !onlyIfNeeded || analyzeNeeded(pTab) ){ + LogEst szThreshold = 0; + if( !onlyIfNeeded || analyzeNeeded(pTab, &szThreshold) ){ if( cnt==0 ){ sqlite3BeginWriteOperation(pParse, 0, iDb); iStatCur = pParse->nTab; @@ -1338,7 +1362,7 @@ static int analyzeDatabase(Parse *pParse, int iDbReq, int onlyIfNeeded){ iMem = pParse->nMem+1; iTab = pParse->nTab; } - analyzeOneTable(pParse, pTab, 0, iStatCur, iMem, iTab); + analyzeOneTable(pParse, pTab, 0, iStatCur, iMem, iTab, szThreshold); cnt++; allCnt++; } @@ -1368,7 +1392,8 @@ static void analyzeTable(Parse *pParse, Table *pTab, Index *pOnlyIdx){ }else{ openStatTable(pParse, iDb, iStatCur, pTab->zName, "tbl"); } - analyzeOneTable(pParse, pTab, pOnlyIdx, iStatCur,pParse->nMem+1,pParse->nTab); + analyzeOneTable(pParse, pTab, pOnlyIdx, iStatCur,pParse->nMem+1, + pParse->nTab, 0); loadAnalysis(pParse, iDb); } diff --git a/src/btree.c b/src/btree.c index e78ffef1be..8aed08cb36 100644 --- a/src/btree.c +++ b/src/btree.c @@ -5319,6 +5319,25 @@ int sqlite3BtreeEof(BtCursor *pCur){ return (CURSOR_VALID!=pCur->eState); } +/* +** Return an estimate for the number of rows in the table that pCur is +** pointing to. Return a negative number if no estimate is currently +** available. +*/ +i64 sqlite3BtreeRowCountEst(BtCursor *pCur){ + i64 n; + u8 i; + + assert( cursorOwnsBtShared(pCur) ); + assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); + if( pCur->eState!=CURSOR_VALID ) return -1; + if( pCur->apPage[pCur->iPage-1]->leaf==0 ) return -1; + for(n=1, i=0; iiPage; i++){ + n *= pCur->apPage[i]->nCell; + } + return n; +} + /* ** Advance the cursor to the next entry in the database. If ** successful then set *pRes=0. If the cursor diff --git a/src/btree.h b/src/btree.h index ae57468e3f..0e017f5300 100644 --- a/src/btree.h +++ b/src/btree.h @@ -296,6 +296,7 @@ u32 sqlite3BtreePayloadSize(BtCursor*); char *sqlite3BtreeIntegrityCheck(Btree*, int *aRoot, int nRoot, int, int*); struct Pager *sqlite3BtreePager(Btree*); +i64 sqlite3BtreeRowCountEst(BtCursor*); #ifndef SQLITE_OMIT_INCRBLOB int sqlite3BtreePayloadChecked(BtCursor*, u32 offset, u32 amt, void*); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index f590c85f93..d9cad11bcf 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1887,8 +1887,7 @@ struct Table { #define TF_WithoutRowid 0x0020 /* No rowid. PRIMARY KEY is the key */ #define TF_NoVisibleRowid 0x0040 /* No user-visible "rowid" column */ #define TF_OOOHidden 0x0080 /* Out-of-Order hidden columns */ -#define TF_SizeChng 0x0100 /* nRowLogEst might be inaccurate */ -#define TF_StatsUsed 0x0200 /* Query planner decisions affected by +#define TF_StatsUsed 0x0100 /* Query planner decisions affected by ** Index.aiRowLogEst[] values */ /* diff --git a/src/vdbe.c b/src/vdbe.c index 7f286b2c6d..b595c4fb01 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -4847,6 +4847,33 @@ case OP_Last: { /* jump */ break; } +/* Opcode: IfSmaller P1 P2 P3 * * +** +** Estimate the number of rows in the table P1. Jump to P2 if that +** estimate is less than approximately 2**(0.1*P3). +*/ +case OP_IfSmaller: { /* jump */ + VdbeCursor *pC; + BtCursor *pCrsr; + int res; + i64 sz; + + assert( pOp->p1>=0 && pOp->p1nCursor ); + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); + pCrsr = pC->uc.pCursor; + assert( pCrsr ); + rc = sqlite3BtreeFirst(pCrsr, &res); + if( rc ) goto abort_due_to_error; + if( res==0 ){ + sz = sqlite3BtreeRowCountEst(pCrsr); + if( ALWAYS(sz>=0) && sqlite3LogEst((u64)sz)p3 ) res = 1; + } + VdbeBranchTaken(res!=0,2); + if( res ) goto jump_to_p2; + break; +} + /* Opcode: SorterSort P1 P2 * * * ** diff --git a/test/autoanalyze1.test b/test/autoanalyze1.test index c36e0fcbc7..77e767a89e 100644 --- a/test/autoanalyze1.test +++ b/test/autoanalyze1.test @@ -16,8 +16,7 @@ # If any of the following constants changes: # # define TF_HasStat1 0x0010 -# define TF_SizeChng 0x0100 -# define TF_StatsUsed 0x0200 +# define TF_StatsUsed 0x0100 # # then some of the magic numbers in test results below might need to be # adjusted. @@ -52,7 +51,7 @@ do_execsql_test autoanalyze1-100 { # No use of stat1 recorded so far do_execsql_test autoanalyze1-110 { - SELECT (flgs & 0x0200)!=0 FROM pragma_stats WHERE tbl='t1' AND idx IS NULL; + SELECT (flgs & 0x0100)!=0 FROM pragma_stats WHERE tbl='t1' AND idx IS NULL; } {0} # Access using a unique index does not set the TF_StatsUsed flag. @@ -61,21 +60,21 @@ do_execsql_test autoanalyze1-200 { SELECT * FROM t1 WHERE a=55; } {55 55 55 55} do_execsql_test autoanalyze1-201 { - SELECT (flgs & 0x0200)!=0 FROM pragma_stats WHERE tbl='t1' AND idx IS NULL; + SELECT (flgs & 0x0100)!=0 FROM pragma_stats WHERE tbl='t1' AND idx IS NULL; } {0} do_execsql_test autoanalyze1-210 { SELECT * FROM t1 WHERE a IN (55,199,299); } {55 55 55 55} do_execsql_test autoanalyze1-211 { - SELECT (flgs & 0x0200)!=0 FROM pragma_stats WHERE tbl='t1' AND idx IS NULL; + SELECT (flgs & 0x0100)!=0 FROM pragma_stats WHERE tbl='t1' AND idx IS NULL; } {0} do_execsql_test autoanalyze1-220 { SELECT * FROM t1 WHERE (b,c)=(45,45); } {45 45 45 45} do_execsql_test autoanalyze1-221 { - SELECT (flgs & 0x0200)!=0 FROM pragma_stats WHERE tbl='t1' AND idx IS NULL; + SELECT (flgs & 0x0100)!=0 FROM pragma_stats WHERE tbl='t1' AND idx IS NULL; } {0} # Any use of the non-unique t1d index triggers the use of stats. @@ -85,7 +84,7 @@ do_execsql_test autoanalyze1-300 { SELECT * FROM t1 WHERE d=45; } {45 45 45 45} do_execsql_test autoanalyze1-301 { - SELECT (flgs & 0x0200)!=0 FROM pragma_stats WHERE tbl='t1' AND idx IS NULL; + SELECT (flgs & 0x0100)!=0 FROM pragma_stats WHERE tbl='t1' AND idx IS NULL; } {1} sqlite3 db test.db @@ -93,7 +92,7 @@ do_execsql_test autoanalyze1-310 { SELECT * FROM t1 WHERE d=45 AND a=45; } {45 45 45 45} do_execsql_test autoanalyze1-311 { - SELECT (flgs & 0x0200)!=0 FROM pragma_stats WHERE tbl='t1' AND idx IS NULL; + SELECT (flgs & 0x0100)!=0 FROM pragma_stats WHERE tbl='t1' AND idx IS NULL; } {0} ;# The ROWID lookup short-circuits the d=45 constraint sqlite3 db test.db @@ -101,7 +100,7 @@ do_execsql_test autoanalyze1-320 { SELECT * FROM t1 WHERE d=45 AND a IN (45,46); } {45 45 45 45} do_execsql_test autoanalyze1-321 { - SELECT (flgs & 0x0200)!=0 FROM pragma_stats WHERE tbl='t1' AND idx IS NULL; + SELECT (flgs & 0x0100)!=0 FROM pragma_stats WHERE tbl='t1' AND idx IS NULL; } {1} # Any use of prefix of a unique index triggers the use of stats @@ -111,14 +110,14 @@ do_execsql_test autoanalyze1-400 { SELECT * FROM t1 WHERE b=45; } {45 45 45 45} do_execsql_test autoanalyze1-401 { - SELECT (flgs & 0x0200)!=0 FROM pragma_stats WHERE tbl='t1' AND idx IS NULL; + SELECT (flgs & 0x0100)!=0 FROM pragma_stats WHERE tbl='t1' AND idx IS NULL; } {1} # The TF_StatsUsed flag is reset when the database is reopened # sqlite3 db test.db do_execsql_test autoanalyze1-500 { - SELECT (flgs & 0x0200)!=0 FROM pragma_stats WHERE tbl='t1' AND idx IS NULL; + SELECT (flgs & 0x0100)!=0 FROM pragma_stats WHERE tbl='t1' AND idx IS NULL; } {0} finish_test From f196972c73caf56506e570818d16d024963d5b5f Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 17 Feb 2017 23:52:00 +0000 Subject: [PATCH 1349/1484] Fix the #endif location for an #ifndef SQLITE_UNTESTABLE macro in the command-line shell. FossilOrigin-Name: 8cc9d74c176a78aeebfbb39198c21b5dd547ff52 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/shell.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index dc0eaa5c63..f6dcc6d61d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\stest\scase\sthat\swas\smade\sto\sfail\sby\sthe\sLIKE\soptimization\senhancement\nin\scheck-in\s[158290c0ab]\sbut\swhich\swent\sunnoticed\sbecause\stest\sbuilds\swere\nrunning\swith\sICU\senabled\sand\sICU\sdisables\sthe\sLIKE\soptimization. -D 2017-02-17T02:04:31.068 +C Fix\sthe\s#endif\slocation\sfor\san\s#ifndef\sSQLITE_UNTESTABLE\smacro\sin\sthe\ncommand-line\sshell. +D 2017-02-17T23:52:00.611 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 @@ -395,7 +395,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c f9bc0de45a30a450da47b3766de00be89bf9be79 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c d12f3539f80db38b09015561b569e0eb1c4b6c5f -F src/shell.c bb8e20789499aec921a01d8744c616b81b8214f1 +F src/shell.c bf976d5301be9d8a4c52852c97909cc9a41ee20d F src/sqlite.h.in 751ff125eb159c8f92c182b8df980a5e4f50e966 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae @@ -1556,7 +1556,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 8a03be1dc42737ba0712d33f639ea26dc243b20e -R b29803fdd4fd514ba7baa53a58b26311 +P 218b2bbb0de07288889f6762d4461ea8acd78969 +R ac73be2e300a373fc7f110abc87089ba U drh -Z af65459984ca8c135fabce3c62812860 +Z 57022d1bdb1e12a8cd90064785570f14 diff --git a/manifest.uuid b/manifest.uuid index d642d67abe..ce8096c87e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -218b2bbb0de07288889f6762d4461ea8acd78969 \ No newline at end of file +8cc9d74c176a78aeebfbb39198c21b5dd547ff52 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index fbbbea9d79..f1c7f3c157 100644 --- a/src/shell.c +++ b/src/shell.c @@ -5192,6 +5192,7 @@ static int do_meta_command(char *zLine, ShellState *p){ } } }else +#endif /* !defined(SQLITE_UNTESTABLE) */ if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 ){ open_db(p, 0); @@ -5228,7 +5229,6 @@ static int do_meta_command(char *zLine, ShellState *p){ } #endif }else -#endif /* !defined(SQLITE_UNTESTABLE) */ #if SQLITE_USER_AUTHENTICATION if( c=='u' && strncmp(azArg[0], "user", n)==0 ){ From 182e84c116eb9b6f3e9dc3ee1a694e302cf6c08d Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 18 Feb 2017 02:19:02 +0000 Subject: [PATCH 1350/1484] In the analyze_as_needed pragma, avoid running unnecessary OP_LoadAnalysis and OP_Expire opcodes. Make the analyze_as_needed pragma responsive to the schema name. FossilOrigin-Name: 882599a4a7ea92c9e7752e0745475508e58a11c3 --- manifest | 18 +++++----- manifest.uuid | 2 +- src/analyze.c | 90 ++++++++++++++++++++++++++----------------------- src/parse.y | 4 +-- src/pragma.c | 2 +- src/sqliteInt.h | 3 +- 6 files changed, 63 insertions(+), 56 deletions(-) diff --git a/manifest b/manifest index 42a11a725c..d311cdbbf3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C The\sanalyze_as_needed\spragma\snow\sresponds\sto\stable\ssize\sgrowth\sand\swill\nautomatically\srerun\sthe\sanalysis\safter\seach\s10x\ssize\sincrease. -D 2017-02-17T19:24:06.618 +C In\sthe\sanalyze_as_needed\spragma,\savoid\srunning\sunnecessary\sOP_LoadAnalysis\s\nand\sOP_Expire\sopcodes.\s\sMake\sthe\sanalyze_as_needed\spragma\sresponsive\sto\sthe\nschema\sname. +D 2017-02-18T02:19:02.183 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 @@ -331,7 +331,7 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F src/alter.c 3b23977620ce9662ac54443f65b87ba996e36121 -F src/analyze.c acef9c48eac30438e82f39eb8df6682c6e33942e +F src/analyze.c eb50045b8f2e0d8a0a36a2158a65afe098d9a3bb F src/attach.c 8c476f8bd5d2afe11d925f890d30e527e5b0ce43 F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792 F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b @@ -383,11 +383,11 @@ F src/os_win.c cf90abd4e50d9f56d2c20ce8e005aff55d7bd8e9 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c ff1232b3088a39806035ecfac4fffeb22717d80b F src/pager.h f2a99646c5533ffe11afa43e9e0bea74054e4efa -F src/parse.y d5695ae4887a52352b1b8a3e3623477c7e79abeb +F src/parse.y 591704fce84f814d9a3642774c1f011d38f4149c F src/pcache.c 62835bed959e2914edd26afadfecce29ece0e870 F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 F src/pcache1.c e3967219b2a92b9edcb9324a4ba75009090d3953 -F src/pragma.c e8b2ea66dfb1b90c53b920c08914ac26b109053a +F src/pragma.c cf0f101d2986d258699cbbd249392858ec9a6b7e F src/pragma.h 065e184494f12e94111da1ab6984faa7b6142e68 F src/prepare.c b1140c3d0cf59bc85ace00ce363153041b424b7a F src/printf.c 67427bbee66d891fc6f6f5aada857e9cdb368c1c @@ -399,7 +399,7 @@ F src/shell.c bb8e20789499aec921a01d8744c616b81b8214f1 F src/sqlite.h.in 751ff125eb159c8f92c182b8df980a5e4f50e966 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae -F src/sqliteInt.h 60c38b84a796cc9d0a9a794cca254b09898b9cc5 +F src/sqliteInt.h 70abfa92e02688f1d189bf63fd25d309ca8d8d1e F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 @@ -1557,7 +1557,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e93db2373127d31d33ec46ef918fa9386bb664a6 -R 484e61dbf95be1098adb3acfa069e723 +P bfbdd07409688fac4ccddbab3639745f6152e23d +R 1c1b7451b307830f90322e6d51007af7 U drh -Z 81466028927592a195c5763d3460fcde +Z 2d7c806c83a06bb426974433c00a5916 diff --git a/manifest.uuid b/manifest.uuid index 8be7eeb5b9..9825130b6a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bfbdd07409688fac4ccddbab3639745f6152e23d \ No newline at end of file +882599a4a7ea92c9e7752e0745475508e58a11c3 \ No newline at end of file diff --git a/src/analyze.c b/src/analyze.c index 082713fd23..c30027aec9 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -971,6 +971,7 @@ static void analyzeOneTable( int jZeroRows = -1; /* Jump from here if number of rows is zero */ int iDb; /* Index of database containing pTab */ u8 needTableCnt = 1; /* True to count the table */ + int regWorkDone = iMem++; /* Set to 1 if any work is done */ int regNewRowid = iMem++; /* Rowid for the inserted record */ int regStat4 = iMem++; /* Register to hold Stat4Accum object */ int regChng = iMem++; /* Index of changed index field */ @@ -1018,7 +1019,7 @@ static void analyzeOneTable( sqlite3OpenTable(pParse, iTabCur, iDb, pTab, OP_OpenRead); if( szOld>0 ){ addrSizeCk = sqlite3VdbeAddOp3(v, OP_IfSmaller, iTabCur, 0, szOld); - } + } sqlite3VdbeLoadString(v, regTabname, pTab->zName); for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ @@ -1276,21 +1277,11 @@ static void analyzeOneTable( sqlite3VdbeChangeP5(v, OPFLAG_APPEND); sqlite3VdbeJumpHere(v, jZeroRows); } + sqlite3VdbeAddOp2(v, OP_Integer, 1, regWorkDone); + VdbeComment((v, "work was done")); sqlite3VdbeJumpHere(v, addrSizeCk); } - -/* -** Generate code that will cause the most recent index analysis to -** be loaded into internal hash tables where is can be used. -*/ -static void loadAnalysis(Parse *pParse, int iDb){ - Vdbe *v = sqlite3GetVdbe(pParse); - if( v ){ - sqlite3VdbeAddOp1(v, OP_LoadAnalysis, iDb); - } -} - /* ** Return true if table pTab might need to being reanalyzed. Return ** false if we know that pTab should not be reanalyzed. @@ -1322,54 +1313,70 @@ static int analyzeNeeded(Table *pTab, LogEst *pThreshold){ } /* -** Generate code that will do an analysis of an entire database. +** Generate code that will do an analysis of an entire database, or +** all databases in the connection if iDbReq is negative. ** -** Return a count of the number of tables actually analyzed. Return 0 -** if nothing was analyzed. +** If onlyIfNeeded is true, then only run the analysis if SQLite thinks +** it is actually needed. */ -static int analyzeDatabase(Parse *pParse, int iDbReq, int onlyIfNeeded){ +void sqlite3AnalyzeDatabase( + Parse *pParse, /* The parsing context */ + int iDbReq, /* Which schema to analyze. -1 for all (except TEMP) */ + int onlyIfNeeded /* Only do the analysis if needed, when true */ +){ sqlite3 *db = pParse->db; Schema *pSchema; HashElem *k; - int iStatCur; - int iMem; - int iTab; + int iStatCur = 0; + int iMem = 0; + int iTab = 0; int iDb; /* Database currently being analyzed */ int iDbFirst, iDbLast; /* Range of databases to be analyzed */ - int cnt; /* Number of tables analyzed in a single database */ - int allCnt = 0; /* Number of tables analyzed across all databases */ + int bStatTabs = 0; + Vdbe *v = sqlite3GetVdbe(pParse); + int nHit = 0; + unsigned char aHit[SQLITE_MAX_ATTACHED+2]; + if( v==0 ) return; if( iDbReq>=0 ){ iDbFirst = iDbLast = iDbReq; }else{ iDbFirst = 0; iDbLast = db->nDb-1; } - for(iDb=iDbFirst; iDb<=iDbLast; iDb++){ + for(iDb=iDbFirst; iDb<=iDbLast; iDb++, bStatTabs=0){ if( iDb==1 ) continue; /* Do not analyze the TEMP database */ pSchema = db->aDb[iDb].pSchema; assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); - cnt = 0; for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){ Table *pTab = (Table*)sqliteHashData(k); LogEst szThreshold = 0; if( !onlyIfNeeded || analyzeNeeded(pTab, &szThreshold) ){ - if( cnt==0 ){ - sqlite3BeginWriteOperation(pParse, 0, iDb); + if( iMem==0 ){ iStatCur = pParse->nTab; pParse->nTab += 3; - openStatTable(pParse, iDb, iStatCur, 0, 0); iMem = pParse->nMem+1; iTab = pParse->nTab; + sqlite3VdbeAddOp2(v, OP_Integer, 0, iMem); + } + if( !bStatTabs ){ + aHit[nHit++] = iDb; + sqlite3BeginWriteOperation(pParse, 0, iDb); + openStatTable(pParse, iDb, iStatCur, 0, 0); + bStatTabs = 1; } analyzeOneTable(pParse, pTab, 0, iStatCur, iMem, iTab, szThreshold); - cnt++; - allCnt++; } } - if( cnt ) loadAnalysis(pParse, iDb); } - return allCnt; + if( iMem ){ + int addrTop = sqlite3VdbeAddOp1(v, OP_IfNot, iMem); VdbeCoverage(v); + for(iDb=0; iDbdb) ); @@ -1392,9 +1400,13 @@ static void analyzeTable(Parse *pParse, Table *pTab, Index *pOnlyIdx){ }else{ openStatTable(pParse, iDb, iStatCur, pTab->zName, "tbl"); } - analyzeOneTable(pParse, pTab, pOnlyIdx, iStatCur,pParse->nMem+1, + analyzeOneTable(pParse, pTab, pOnlyIdx, iStatCur, pParse->nMem+1, pParse->nTab, 0); - loadAnalysis(pParse, iDb); + v = sqlite3GetVdbe(pParse); + if( v ){ + sqlite3VdbeAddOp1(v, OP_LoadAnalysis, iDb); + sqlite3VdbeAddOp0(v, OP_Expire); + } } /* @@ -1414,15 +1426,13 @@ static void analyzeTable(Parse *pParse, Table *pTab, Index *pOnlyIdx){ ** are believed to be in need of analysis. The conditional analysis ** might well be a no-op. */ -void sqlite3Analyze(Parse *pParse, Token *pName1, Token *pName2, int ifNeeded){ +void sqlite3Analyze(Parse *pParse, Token *pName1, Token *pName2){ sqlite3 *db = pParse->db; int iDb; char *z, *zDb; Table *pTab; Index *pIdx; Token *pTableName; - Vdbe *v; - int needExpire = 1; /* Read the database schema. If an error occurs, leave an error message ** and code in pParse and return NULL. */ @@ -1434,12 +1444,12 @@ void sqlite3Analyze(Parse *pParse, Token *pName1, Token *pName2, int ifNeeded){ assert( pName2!=0 || pName1==0 ); if( pName1==0 ){ /* Form 1: Analyze everything */ - needExpire = analyzeDatabase(pParse, -1, ifNeeded) || ifNeeded==0; + sqlite3AnalyzeDatabase(pParse, -1, 0); }else if( pName2->n==0 ){ /* Form 2: Analyze the database or table named */ iDb = sqlite3FindDb(db, pName1); if( iDb>=0 ){ - analyzeDatabase(pParse, iDb, 0); + sqlite3AnalyzeDatabase(pParse, iDb, 0); }else{ z = sqlite3NameFromToken(db, pName1); if( z ){ @@ -1467,10 +1477,6 @@ void sqlite3Analyze(Parse *pParse, Token *pName1, Token *pName2, int ifNeeded){ } } } - if( needExpire ){ - v = sqlite3GetVdbe(pParse); - if( v ) sqlite3VdbeAddOp0(v, OP_Expire); - } } /* diff --git a/src/parse.y b/src/parse.y index ff03c128ac..9cada2a1be 100644 --- a/src/parse.y +++ b/src/parse.y @@ -1512,8 +1512,8 @@ cmd ::= REINDEX nm(X) dbnm(Y). {sqlite3Reindex(pParse, &X, &Y);} /////////////////////////////////// ANALYZE /////////////////////////////////// %ifndef SQLITE_OMIT_ANALYZE -cmd ::= ANALYZE. {sqlite3Analyze(pParse, 0, 0, 0);} -cmd ::= ANALYZE nm(X) dbnm(Y). {sqlite3Analyze(pParse, &X, &Y, 0);} +cmd ::= ANALYZE. {sqlite3Analyze(pParse, 0, 0);} +cmd ::= ANALYZE nm(X) dbnm(Y). {sqlite3Analyze(pParse, &X, &Y);} %endif //////////////////////// ALTER TABLE table ... //////////////////////////////// diff --git a/src/pragma.c b/src/pragma.c index 789751958c..3bcf62f69f 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -1832,7 +1832,7 @@ void sqlite3Pragma( ** PRAGMA analyze_as_needed */ case PragTyp_ANALYZE_AS_NEEDED: { - sqlite3Analyze(pParse, 0, 0, 1); + sqlite3AnalyzeDatabase(pParse, zDb ? iDb : -1, 1); break; } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index d9cad11bcf..218c2c6af6 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -4027,7 +4027,8 @@ void sqlite3AlterFinishAddColumn(Parse *, Token *); void sqlite3AlterBeginAddColumn(Parse *, SrcList *); CollSeq *sqlite3GetCollSeq(Parse*, u8, CollSeq *, const char*); char sqlite3AffinityType(const char*, u8*); -void sqlite3Analyze(Parse*, Token*, Token*, int); +void sqlite3Analyze(Parse*, Token*, Token*); +void sqlite3AnalyzeDatabase(Parse*,int,int); int sqlite3InvokeBusyHandler(BusyHandler*); int sqlite3FindDb(sqlite3*, Token*); int sqlite3FindDbName(sqlite3 *, const char *); From dfe11bae9944fa05066314dd9063ff834fd60dae Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 18 Feb 2017 02:42:54 +0000 Subject: [PATCH 1351/1484] Fix errors in the table resize detection. FossilOrigin-Name: 4229caec0b60a1617b9d5ff94b47271cbd7be1e0 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/analyze.c | 8 +++++--- src/btree.c | 4 ++-- 4 files changed, 15 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index d311cdbbf3..5af18e20b2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\sthe\sanalyze_as_needed\spragma,\savoid\srunning\sunnecessary\sOP_LoadAnalysis\s\nand\sOP_Expire\sopcodes.\s\sMake\sthe\sanalyze_as_needed\spragma\sresponsive\sto\sthe\nschema\sname. -D 2017-02-18T02:19:02.183 +C Fix\serrors\sin\sthe\stable\sresize\sdetection. +D 2017-02-18T02:42:54.892 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 @@ -331,13 +331,13 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F src/alter.c 3b23977620ce9662ac54443f65b87ba996e36121 -F src/analyze.c eb50045b8f2e0d8a0a36a2158a65afe098d9a3bb +F src/analyze.c e01e5362ba2ac8430ab7833022afb6081ade8315 F src/attach.c 8c476f8bd5d2afe11d925f890d30e527e5b0ce43 F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792 F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca -F src/btree.c e7d724b02365d88920171caf0c919aa96d9b19e3 +F src/btree.c a4ab1fb5cdeea88c4f76216e41cfecfa505c8c43 F src/btree.h bf64dfeeddeebdb775a5eba0098bbc00d073290d F src/btreeInt.h cd55d39d9916270837a88c12e701047cba0729b0 F src/build.c 2e05d0360568f40dc583461f2211f020ff282ee4 @@ -1557,7 +1557,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P bfbdd07409688fac4ccddbab3639745f6152e23d -R 1c1b7451b307830f90322e6d51007af7 +P 882599a4a7ea92c9e7752e0745475508e58a11c3 +R cf9f80fd407d6e9e7cfac9c2957017b5 U drh -Z 2d7c806c83a06bb426974433c00a5916 +Z 225df65ba1e601aba9cbc975df68b3a8 diff --git a/manifest.uuid b/manifest.uuid index 9825130b6a..07d49087a1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -882599a4a7ea92c9e7752e0745475508e58a11c3 \ No newline at end of file +4229caec0b60a1617b9d5ff94b47271cbd7be1e0 \ No newline at end of file diff --git a/src/analyze.c b/src/analyze.c index c30027aec9..118cdb9383 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -1019,6 +1019,7 @@ static void analyzeOneTable( sqlite3OpenTable(pParse, iTabCur, iDb, pTab, OP_OpenRead); if( szOld>0 ){ addrSizeCk = sqlite3VdbeAddOp3(v, OP_IfSmaller, iTabCur, 0, szOld); + VdbeCoverage(v); } sqlite3VdbeLoadString(v, regTabname, pTab->zName); @@ -1296,9 +1297,10 @@ static int analyzeNeeded(Table *pTab, LogEst *pThreshold){ Index *pIdx; if( (pTab->tabFlags & TF_StatsUsed)==0 ) return 0; - /* If TF_StatsUsed is true, then we might need to reanalyze. But - ** only reanalyze if the table size has grown by a factor of 10 or more */ - *pThreshold = pTab->nRowLogEst + 33; assert( sqlite3LogEst(10)==33 ); + /* If TF_StatsUsed is true, then we might need to reanalyze. + ** TUNING: Only reanalyze if the table size has grown by a factor + ** of 25 or more. */ + *pThreshold = pTab->nRowLogEst + 46; assert( sqlite3LogEst(25)==46 ); /* Except, if any of the indexes of the table do not have valid ** sqlite_stat1 entries, then set the size threshold to zero to diff --git a/src/btree.c b/src/btree.c index 8aed08cb36..4d31661f10 100644 --- a/src/btree.c +++ b/src/btree.c @@ -5331,8 +5331,8 @@ i64 sqlite3BtreeRowCountEst(BtCursor *pCur){ assert( cursorOwnsBtShared(pCur) ); assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); if( pCur->eState!=CURSOR_VALID ) return -1; - if( pCur->apPage[pCur->iPage-1]->leaf==0 ) return -1; - for(n=1, i=0; iiPage; i++){ + if( pCur->apPage[pCur->iPage]->leaf==0 ) return -1; + for(n=1, i=0; i<=pCur->iPage; i++){ n *= pCur->apPage[i]->nCell; } return n; From eeea412a9d2b26f9f82157899520e3ad2e2ee34f Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 18 Feb 2017 13:47:11 +0000 Subject: [PATCH 1352/1484] Add the SQLITE_BUG_COMPATIBLE_20160819 compile-time option to omit the error message when an unrecognized argument is provided to the VACUUM command. FossilOrigin-Name: 491814272dce7e937b4734fcbc2ad69e12377b56 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vacuum.c | 21 +++++++++++++++++++-- 3 files changed, 26 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index f6dcc6d61d..44763338e4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\s#endif\slocation\sfor\san\s#ifndef\sSQLITE_UNTESTABLE\smacro\sin\sthe\ncommand-line\sshell. -D 2017-02-17T23:52:00.611 +C Add\sthe\sSQLITE_BUG_COMPATIBLE_20160819\scompile-time\soption\sto\somit\sthe\serror\nmessage\swhen\san\sunrecognized\sargument\sis\sprovided\sto\sthe\sVACUUM\scommand. +D 2017-02-18T13:47:11.181 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 @@ -460,7 +460,7 @@ F src/trigger.c c9f0810043b265724fdb1bdd466894f984dfc182 F src/update.c 456d4a4656f8a03c2abc88a51b19172197400e58 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c ca8440ede81e155d15cff7c101654f60b55a9ae6 -F src/vacuum.c 33c174b28886b2faf26e503b5a49a1c01a9b1c16 +F src/vacuum.c 1fe4555cd8c9b263afb85b5b4ee3a4a4181ad569 F src/vdbe.c 16f378640570c24442fd7191b136b5d6380f5c7b F src/vdbe.h 59998ffd71d7caa8886bc78dafaf8caeccd4c13c F src/vdbeInt.h 4e4b15b2e1330e1636e4e01974eab2b0b985092f @@ -1556,7 +1556,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 218b2bbb0de07288889f6762d4461ea8acd78969 -R ac73be2e300a373fc7f110abc87089ba +P 8cc9d74c176a78aeebfbb39198c21b5dd547ff52 +R 57839b570efd132c834489fe34d93e5e U drh -Z 57022d1bdb1e12a8cd90064785570f14 +Z 38cfd439ab0cfeae01cbf1d291727475 diff --git a/manifest.uuid b/manifest.uuid index ce8096c87e..557d9a7e8b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8cc9d74c176a78aeebfbb39198c21b5dd547ff52 \ No newline at end of file +491814272dce7e937b4734fcbc2ad69e12377b56 \ No newline at end of file diff --git a/src/vacuum.c b/src/vacuum.c index 25b1258510..9e471b8d9c 100644 --- a/src/vacuum.c +++ b/src/vacuum.c @@ -98,8 +98,25 @@ static int execSqlF(sqlite3 *db, char **pzErrMsg, const char *zSql, ...){ */ void sqlite3Vacuum(Parse *pParse, Token *pNm){ Vdbe *v = sqlite3GetVdbe(pParse); - int iDb = pNm ? sqlite3TwoPartName(pParse, pNm, pNm, &pNm) : 0; - if( v && (iDb>=2 || iDb==0) ){ + int iDb = 0; + if( v==0 ) return; + if( pNm ){ +#ifndef SQLITE_BUG_COMPATIBLE_20160819 + /* Default behavior: Report an error if the argument to VACUUM is + ** not recognized */ + iDb = sqlite3TwoPartName(pParse, pNm, pNm, &pNm); + if( iDb<0 ) return; +#else + /* When SQLITE_BUG_COMPATIBLE_20160819 is defined, unrecognized arguments + ** to VACUUM are silently ignored. This is a back-out of a bug fix that + ** occurred on 2016-08-19 (https://www.sqlite.org/src/info/083f9e6270). + ** The buggy behavior is required for binary compatibility with some + ** legacy applications. */ + iDb = sqlite3FindDb(pParse->db, pNm); + if( iDb<0 ) iDb = 0; +#endif + } + if( iDb!=1 ){ sqlite3VdbeAddOp1(v, OP_Vacuum, iDb); sqlite3VdbeUsesBtree(v, iDb); } From 4a54bb579480352dce25d2982b2f266c58255248 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 18 Feb 2017 15:58:52 +0000 Subject: [PATCH 1353/1484] Add the OP_SqlExec opcode and use it to implement "PRAGMA analyze_as_needed", invoking ANALYZE subcommands as necessary. This simplifies the implementation. FossilOrigin-Name: d386015f5e7ecdd951d70db56b7bbd858be7ad90 --- manifest | 18 +++--- manifest.uuid | 2 +- src/analyze.c | 157 +++++++++++++----------------------------------- src/pragma.c | 36 ++++++++++- src/sqliteInt.h | 1 - src/vdbe.c | 10 +++ 6 files changed, 96 insertions(+), 128 deletions(-) diff --git a/manifest b/manifest index 5af18e20b2..984bdbb4fc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\serrors\sin\sthe\stable\sresize\sdetection. -D 2017-02-18T02:42:54.892 +C Add\sthe\sOP_SqlExec\sopcode\sand\suse\sit\sto\simplement\s"PRAGMA\sanalyze_as_needed",\ninvoking\sANALYZE\ssubcommands\sas\snecessary.\s\sThis\ssimplifies\sthe\simplementation. +D 2017-02-18T15:58:52.451 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 @@ -331,7 +331,7 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F src/alter.c 3b23977620ce9662ac54443f65b87ba996e36121 -F src/analyze.c e01e5362ba2ac8430ab7833022afb6081ade8315 +F src/analyze.c 1b7197d619788353437d390de42a9bccbb4aa2ac F src/attach.c 8c476f8bd5d2afe11d925f890d30e527e5b0ce43 F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792 F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b @@ -387,7 +387,7 @@ F src/parse.y 591704fce84f814d9a3642774c1f011d38f4149c F src/pcache.c 62835bed959e2914edd26afadfecce29ece0e870 F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 F src/pcache1.c e3967219b2a92b9edcb9324a4ba75009090d3953 -F src/pragma.c cf0f101d2986d258699cbbd249392858ec9a6b7e +F src/pragma.c 1ed159f6fed5af7f5b095f55bdefcb0848956397 F src/pragma.h 065e184494f12e94111da1ab6984faa7b6142e68 F src/prepare.c b1140c3d0cf59bc85ace00ce363153041b424b7a F src/printf.c 67427bbee66d891fc6f6f5aada857e9cdb368c1c @@ -399,7 +399,7 @@ F src/shell.c bb8e20789499aec921a01d8744c616b81b8214f1 F src/sqlite.h.in 751ff125eb159c8f92c182b8df980a5e4f50e966 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae -F src/sqliteInt.h 70abfa92e02688f1d189bf63fd25d309ca8d8d1e +F src/sqliteInt.h 87857c2b8d8825e22970ce3f466b8618ee55b44e F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 @@ -461,7 +461,7 @@ F src/update.c 456d4a4656f8a03c2abc88a51b19172197400e58 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c ca8440ede81e155d15cff7c101654f60b55a9ae6 F src/vacuum.c 33c174b28886b2faf26e503b5a49a1c01a9b1c16 -F src/vdbe.c ac8538b96af5c63d6f18484ffd981d4f44db0073 +F src/vdbe.c 02f9db522c73ba4e1743585e9fd6f8ac6c71515b F src/vdbe.h 59998ffd71d7caa8886bc78dafaf8caeccd4c13c F src/vdbeInt.h 4e4b15b2e1330e1636e4e01974eab2b0b985092f F src/vdbeapi.c 3e4a8893feeb78620f4aac4ac5b85d92255b97e1 @@ -1557,7 +1557,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 882599a4a7ea92c9e7752e0745475508e58a11c3 -R cf9f80fd407d6e9e7cfac9c2957017b5 +P 4229caec0b60a1617b9d5ff94b47271cbd7be1e0 +R 03be76497e56750b0101f816e3587990 U drh -Z 225df65ba1e601aba9cbc975df68b3a8 +Z 8d178351b984357dd4d18d50fe476798 diff --git a/manifest.uuid b/manifest.uuid index 07d49087a1..323aca9202 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4229caec0b60a1617b9d5ff94b47271cbd7be1e0 \ No newline at end of file +d386015f5e7ecdd951d70db56b7bbd858be7ad90 \ No newline at end of file diff --git a/src/analyze.c b/src/analyze.c index 118cdb9383..3ecf469cd3 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -958,12 +958,10 @@ static void analyzeOneTable( Index *pOnlyIdx, /* If not NULL, only analyze this one index */ int iStatCur, /* Index of VdbeCursor that writes the sqlite_stat1 table */ int iMem, /* Available memory locations begin here */ - int iTab, /* Next available cursor */ - LogEst szOld /* Run the analysis if table row count is larger than this */ + int iTab /* Next available cursor */ ){ sqlite3 *db = pParse->db; /* Database handle */ Index *pIdx; /* An index to being analyzed */ - int addrSizeCk = 0; /* Address of the IfSmaller */ int iIdxCur; /* Cursor open on index being analyzed */ int iTabCur; /* Table cursor */ Vdbe *v; /* The virtual machine being built up */ @@ -971,7 +969,6 @@ static void analyzeOneTable( int jZeroRows = -1; /* Jump from here if number of rows is zero */ int iDb; /* Index of database containing pTab */ u8 needTableCnt = 1; /* True to count the table */ - int regWorkDone = iMem++; /* Set to 1 if any work is done */ int regNewRowid = iMem++; /* Rowid for the inserted record */ int regStat4 = iMem++; /* Register to hold Stat4Accum object */ int regChng = iMem++; /* Index of changed index field */ @@ -1017,10 +1014,6 @@ static void analyzeOneTable( iIdxCur = iTab++; pParse->nTab = MAX(pParse->nTab, iTab); sqlite3OpenTable(pParse, iTabCur, iDb, pTab, OP_OpenRead); - if( szOld>0 ){ - addrSizeCk = sqlite3VdbeAddOp3(v, OP_IfSmaller, iTabCur, 0, szOld); - VdbeCoverage(v); - } sqlite3VdbeLoadString(v, regTabname, pTab->zName); for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ @@ -1278,107 +1271,43 @@ static void analyzeOneTable( sqlite3VdbeChangeP5(v, OPFLAG_APPEND); sqlite3VdbeJumpHere(v, jZeroRows); } - sqlite3VdbeAddOp2(v, OP_Integer, 1, regWorkDone); - VdbeComment((v, "work was done")); - sqlite3VdbeJumpHere(v, addrSizeCk); } -/* -** Return true if table pTab might need to being reanalyzed. Return -** false if we know that pTab should not be reanalyzed. -** -** If returning true, also set *pThreshold to a size threshold that -** will determine at run-time whether or not the reanalysis occurs. -** The reanalysis will only occur if the size of the table is greater -** than the threshold. Not that the threshold is a logarithmic LogEst -** value. -*/ -static int analyzeNeeded(Table *pTab, LogEst *pThreshold){ - Index *pIdx; - if( (pTab->tabFlags & TF_StatsUsed)==0 ) return 0; - - /* If TF_StatsUsed is true, then we might need to reanalyze. - ** TUNING: Only reanalyze if the table size has grown by a factor - ** of 25 or more. */ - *pThreshold = pTab->nRowLogEst + 46; assert( sqlite3LogEst(25)==46 ); - - /* Except, if any of the indexes of the table do not have valid - ** sqlite_stat1 entries, then set the size threshold to zero to - ** ensure the analysis will always occur. */ - for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ - if( !pIdx->hasStat1 ){ - *pThreshold = 0; - break; - } - } - return 1; -} /* -** Generate code that will do an analysis of an entire database, or -** all databases in the connection if iDbReq is negative. -** -** If onlyIfNeeded is true, then only run the analysis if SQLite thinks -** it is actually needed. +** Generate code that will cause the most recent index analysis to +** be loaded into internal hash tables where is can be used. */ -void sqlite3AnalyzeDatabase( - Parse *pParse, /* The parsing context */ - int iDbReq, /* Which schema to analyze. -1 for all (except TEMP) */ - int onlyIfNeeded /* Only do the analysis if needed, when true */ -){ - sqlite3 *db = pParse->db; - Schema *pSchema; - HashElem *k; - int iStatCur = 0; - int iMem = 0; - int iTab = 0; - int iDb; /* Database currently being analyzed */ - int iDbFirst, iDbLast; /* Range of databases to be analyzed */ - int bStatTabs = 0; +static void loadAnalysis(Parse *pParse, int iDb){ Vdbe *v = sqlite3GetVdbe(pParse); - int nHit = 0; - unsigned char aHit[SQLITE_MAX_ATTACHED+2]; + if( v ){ + sqlite3VdbeAddOp1(v, OP_LoadAnalysis, iDb); + } +} - if( v==0 ) return; - if( iDbReq>=0 ){ - iDbFirst = iDbLast = iDbReq; - }else{ - iDbFirst = 0; - iDbLast = db->nDb-1; - } - for(iDb=iDbFirst; iDb<=iDbLast; iDb++, bStatTabs=0){ - if( iDb==1 ) continue; /* Do not analyze the TEMP database */ - pSchema = db->aDb[iDb].pSchema; - assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); - for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){ - Table *pTab = (Table*)sqliteHashData(k); - LogEst szThreshold = 0; - if( !onlyIfNeeded || analyzeNeeded(pTab, &szThreshold) ){ - if( iMem==0 ){ - iStatCur = pParse->nTab; - pParse->nTab += 3; - iMem = pParse->nMem+1; - iTab = pParse->nTab; - sqlite3VdbeAddOp2(v, OP_Integer, 0, iMem); - } - if( !bStatTabs ){ - aHit[nHit++] = iDb; - sqlite3BeginWriteOperation(pParse, 0, iDb); - openStatTable(pParse, iDb, iStatCur, 0, 0); - bStatTabs = 1; - } - analyzeOneTable(pParse, pTab, 0, iStatCur, iMem, iTab, szThreshold); - } - } - } - if( iMem ){ - int addrTop = sqlite3VdbeAddOp1(v, OP_IfNot, iMem); VdbeCoverage(v); - for(iDb=0; iDbdb; + Schema *pSchema = db->aDb[iDb].pSchema; /* Schema of database iDb */ + HashElem *k; + int iStatCur; + int iMem; + int iTab; + + sqlite3BeginWriteOperation(pParse, 0, iDb); + iStatCur = pParse->nTab; + pParse->nTab += 3; + openStatTable(pParse, iDb, iStatCur, 0, 0); + iMem = pParse->nMem+1; + iTab = pParse->nTab; + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){ + Table *pTab = (Table*)sqliteHashData(k); + analyzeOneTable(pParse, pTab, 0, iStatCur, iMem, iTab); } + loadAnalysis(pParse, iDb); } /* @@ -1389,7 +1318,6 @@ void sqlite3AnalyzeDatabase( static void analyzeTable(Parse *pParse, Table *pTab, Index *pOnlyIdx){ int iDb; int iStatCur; - Vdbe *v; assert( pTab!=0 ); assert( sqlite3BtreeHoldsAllMutexes(pParse->db) ); @@ -1402,13 +1330,8 @@ static void analyzeTable(Parse *pParse, Table *pTab, Index *pOnlyIdx){ }else{ openStatTable(pParse, iDb, iStatCur, pTab->zName, "tbl"); } - analyzeOneTable(pParse, pTab, pOnlyIdx, iStatCur, pParse->nMem+1, - pParse->nTab, 0); - v = sqlite3GetVdbe(pParse); - if( v ){ - sqlite3VdbeAddOp1(v, OP_LoadAnalysis, iDb); - sqlite3VdbeAddOp0(v, OP_Expire); - } + analyzeOneTable(pParse, pTab, pOnlyIdx, iStatCur,pParse->nMem+1,pParse->nTab); + loadAnalysis(pParse, iDb); } /* @@ -1422,19 +1345,16 @@ static void analyzeTable(Parse *pParse, Table *pTab, Index *pOnlyIdx){ ** Form 1 causes all indices in all attached databases to be analyzed. ** Form 2 analyzes all indices the single database named. ** Form 3 analyzes all indices associated with the named table. -** -** If pName1 and pName2 are both NULL and if the ifNeeded flag is true, -** this routine computes an conditional ANALYZE on only those tables -** are believed to be in need of analysis. The conditional analysis -** might well be a no-op. */ void sqlite3Analyze(Parse *pParse, Token *pName1, Token *pName2){ sqlite3 *db = pParse->db; int iDb; + int i; char *z, *zDb; Table *pTab; Index *pIdx; Token *pTableName; + Vdbe *v; /* Read the database schema. If an error occurs, leave an error message ** and code in pParse and return NULL. */ @@ -1446,12 +1366,15 @@ void sqlite3Analyze(Parse *pParse, Token *pName1, Token *pName2){ assert( pName2!=0 || pName1==0 ); if( pName1==0 ){ /* Form 1: Analyze everything */ - sqlite3AnalyzeDatabase(pParse, -1, 0); + for(i=0; inDb; i++){ + if( i==1 ) continue; /* Do not analyze the TEMP database */ + analyzeDatabase(pParse, i); + } }else if( pName2->n==0 ){ /* Form 2: Analyze the database or table named */ iDb = sqlite3FindDb(db, pName1); if( iDb>=0 ){ - sqlite3AnalyzeDatabase(pParse, iDb, 0); + analyzeDatabase(pParse, iDb); }else{ z = sqlite3NameFromToken(db, pName1); if( z ){ @@ -1479,6 +1402,8 @@ void sqlite3Analyze(Parse *pParse, Token *pName1, Token *pName2){ } } } + v = sqlite3GetVdbe(pParse); + if( v ) sqlite3VdbeAddOp0(v, OP_Expire); } /* diff --git a/src/pragma.c b/src/pragma.c index 3bcf62f69f..49d711ded7 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -1832,7 +1832,41 @@ void sqlite3Pragma( ** PRAGMA analyze_as_needed */ case PragTyp_ANALYZE_AS_NEEDED: { - sqlite3AnalyzeDatabase(pParse, zDb ? iDb : -1, 1); + int iDbLast; + int iTabCur; + HashElem *k; + Schema *pSchema; + Table *pTab; + Index *pIdx; + LogEst szThreshold; + char *zSubSql; + + iTabCur = pParse->nTab++; + for(iDbLast = zDb?iDb:db->nDb-1; iDb<=iDbLast; iDb++){ + if( iDb==1 ) continue; + sqlite3CodeVerifySchema(pParse, iDb); + pSchema = db->aDb[iDb].pSchema; + for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){ + pTab = (Table*)sqliteHashData(k); + if( (pTab->tabFlags & TF_StatsUsed)==0 ) continue; + szThreshold = pTab->nRowLogEst + 46; assert( sqlite3LogEst(25)==46 ); + for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + if( !pIdx->hasStat1 ){ + szThreshold = 0; + break; + } + } + if( szThreshold ){ + sqlite3OpenTable(pParse, iTabCur, iDb, pTab, OP_OpenRead); + sqlite3VdbeAddOp3(v, OP_IfSmaller, iTabCur, + sqlite3VdbeCurrentAddr(v)+2, szThreshold); + VdbeCoverage(v); + } + zSubSql = sqlite3MPrintf(db, "ANALYZE \"%w\".\"%w\"", + db->aDb[iDb].zDbSName, pTab->zName); + sqlite3VdbeAddOp4(v, OP_SqlExec, 0, 0, 0, zSubSql, P4_DYNAMIC); + } + } break; } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 218c2c6af6..19c7481223 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -4028,7 +4028,6 @@ void sqlite3AlterBeginAddColumn(Parse *, SrcList *); CollSeq *sqlite3GetCollSeq(Parse*, u8, CollSeq *, const char*); char sqlite3AffinityType(const char*, u8*); void sqlite3Analyze(Parse*, Token*, Token*); -void sqlite3AnalyzeDatabase(Parse*,int,int); int sqlite3InvokeBusyHandler(BusyHandler*); int sqlite3FindDb(sqlite3*, Token*); int sqlite3FindDbName(sqlite3 *, const char *); diff --git a/src/vdbe.c b/src/vdbe.c index b595c4fb01..b8050e8d50 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -5518,6 +5518,16 @@ case OP_CreateTable: { /* out2 */ break; } +/* Opcode: SqlExec * * * P4 * +** +** Run the SQL statement or statements specified in the P4 string. +*/ +case OP_SqlExec: { + rc = sqlite3_exec(db, pOp->p4.z, 0, 0, 0); + if( rc ) goto abort_due_to_error; + break; +} + /* Opcode: ParseSchema P1 * * P4 * ** ** Read and parse all entries from the SQLITE_MASTER table of database P1 From 99d5b4cde6c64a514d9531494bb6875bf5b2a46c Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 18 Feb 2017 22:52:40 +0000 Subject: [PATCH 1354/1484] Updated comments. No code changes. FossilOrigin-Name: e842ad391e62df273a5b1ed569d42ea46d03a99b --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/pragma.c | 41 ++++++++++++++++++++++++++++++++--------- 3 files changed, 39 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index 984bdbb4fc..420fc4058d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sOP_SqlExec\sopcode\sand\suse\sit\sto\simplement\s"PRAGMA\sanalyze_as_needed",\ninvoking\sANALYZE\ssubcommands\sas\snecessary.\s\sThis\ssimplifies\sthe\simplementation. -D 2017-02-18T15:58:52.451 +C Updated\scomments.\s\sNo\scode\schanges. +D 2017-02-18T22:52:40.654 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 @@ -387,7 +387,7 @@ F src/parse.y 591704fce84f814d9a3642774c1f011d38f4149c F src/pcache.c 62835bed959e2914edd26afadfecce29ece0e870 F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 F src/pcache1.c e3967219b2a92b9edcb9324a4ba75009090d3953 -F src/pragma.c 1ed159f6fed5af7f5b095f55bdefcb0848956397 +F src/pragma.c 8a35509e8f60746fbdcde5312ddfd177c46c7e9c F src/pragma.h 065e184494f12e94111da1ab6984faa7b6142e68 F src/prepare.c b1140c3d0cf59bc85ace00ce363153041b424b7a F src/printf.c 67427bbee66d891fc6f6f5aada857e9cdb368c1c @@ -1557,7 +1557,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 4229caec0b60a1617b9d5ff94b47271cbd7be1e0 -R 03be76497e56750b0101f816e3587990 +P d386015f5e7ecdd951d70db56b7bbd858be7ad90 +R bb5056af5425096e2e052e924ae83b2e U drh -Z 8d178351b984357dd4d18d50fe476798 +Z a573182d78be17d037798d5840f110fc diff --git a/manifest.uuid b/manifest.uuid index 323aca9202..d08504dc8d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d386015f5e7ecdd951d70db56b7bbd858be7ad90 \ No newline at end of file +e842ad391e62df273a5b1ed569d42ea46d03a99b \ No newline at end of file diff --git a/src/pragma.c b/src/pragma.c index 49d711ded7..3aa07e8d18 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -1830,16 +1830,33 @@ void sqlite3Pragma( /* ** PRAGMA analyze_as_needed + ** PRAGMA schema.analyze_as_needed + ** + ** This pragma runs ANALYZE on any tables which would have benefitted + ** from having recent statistics at some point since the start of the + ** current connection. Only tables in "schema" are analyzed in the + ** second form. In the first form, all tables except TEMP tables are + ** checked. + ** + ** A table is analyzed only if both of the following are true: + ** + ** (1) The query planner used sqlite_stat1-style statistics for one or + ** more indexes of the table at some point during the lifetime of + ** the current connection. + ** + ** (2) One or more indexes of the table are currently unanalyzed OR + ** the number of rows in the table has increased by 25 times or more + ** since the last time ANALYZE was run. */ case PragTyp_ANALYZE_AS_NEEDED: { - int iDbLast; - int iTabCur; - HashElem *k; - Schema *pSchema; - Table *pTab; - Index *pIdx; - LogEst szThreshold; - char *zSubSql; + int iDbLast; /* Loop termination point for the schema loop */ + int iTabCur; /* Cursor for a table whose size needs checking */ + HashElem *k; /* Loop over tables of a schema */ + Schema *pSchema; /* The current schema */ + Table *pTab; /* A table in the schema */ + Index *pIdx; /* An index of the table */ + LogEst szThreshold; /* Size threshold above which reanalysis is needd */ + char *zSubSql; /* SQL statement for the OP_SqlExec opcode */ iTabCur = pParse->nTab++; for(iDbLast = zDb?iDb:db->nDb-1; iDb<=iDbLast; iDb++){ @@ -1848,11 +1865,17 @@ void sqlite3Pragma( pSchema = db->aDb[iDb].pSchema; for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){ pTab = (Table*)sqliteHashData(k); + + /* If table pTab has not been used in a way that would benefit from + ** having analysis statistics during the current session, then skip it. + ** This also has the effect of skipping virtual tables and views */ if( (pTab->tabFlags & TF_StatsUsed)==0 ) continue; + + /* Reanalyze if the table is 25 times larger than the last analysis */ szThreshold = pTab->nRowLogEst + 46; assert( sqlite3LogEst(25)==46 ); for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ if( !pIdx->hasStat1 ){ - szThreshold = 0; + szThreshold = 0; /* Always analyze if any index lacks statistics */ break; } } From 7e84b377a911ae9fb882dcf9eba23f90b59a849c Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 20 Feb 2017 14:30:17 +0000 Subject: [PATCH 1355/1484] Small grammar simplification. FossilOrigin-Name: 0d8a868acd74fb1d076f23fda58b841bb7e6900b --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/parse.y | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 44763338e4..ab58b869fe 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sSQLITE_BUG_COMPATIBLE_20160819\scompile-time\soption\sto\somit\sthe\serror\nmessage\swhen\san\sunrecognized\sargument\sis\sprovided\sto\sthe\sVACUUM\scommand. -D 2017-02-18T13:47:11.181 +C Small\sgrammar\ssimplification. +D 2017-02-20T14:30:17.816 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 @@ -383,7 +383,7 @@ F src/os_win.c cf90abd4e50d9f56d2c20ce8e005aff55d7bd8e9 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c ff1232b3088a39806035ecfac4fffeb22717d80b F src/pager.h f2a99646c5533ffe11afa43e9e0bea74054e4efa -F src/parse.y 591704fce84f814d9a3642774c1f011d38f4149c +F src/parse.y af8830094f4aecb91cb69721f3601ad10c36abc4 F src/pcache.c 62835bed959e2914edd26afadfecce29ece0e870 F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 F src/pcache1.c e3967219b2a92b9edcb9324a4ba75009090d3953 @@ -1556,7 +1556,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 8cc9d74c176a78aeebfbb39198c21b5dd547ff52 -R 57839b570efd132c834489fe34d93e5e +P 491814272dce7e937b4734fcbc2ad69e12377b56 +R b4cf79fa4c0fd30460236bc8c090e993 U drh -Z 38cfd439ab0cfeae01cbf1d291727475 +Z 32b02aa6638f1e40c7df4614e1f90d4a diff --git a/manifest.uuid b/manifest.uuid index 557d9a7e8b..c411ab59d6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -491814272dce7e937b4734fcbc2ad69e12377b56 \ No newline at end of file +0d8a868acd74fb1d076f23fda58b841bb7e6900b \ No newline at end of file diff --git a/src/parse.y b/src/parse.y index 9cada2a1be..0949e97d16 100644 --- a/src/parse.y +++ b/src/parse.y @@ -1000,7 +1000,7 @@ expr(A) ::= expr(A) STAR|SLASH|REM(OP) expr(Y). {spanBinaryExpr(pParse,@OP,&A,&Y);} expr(A) ::= expr(A) CONCAT(OP) expr(Y). {spanBinaryExpr(pParse,@OP,&A,&Y);} %type likeop {Token} -likeop(A) ::= LIKE_KW|MATCH(X). {A=X;/*A-overwrites-X*/} +likeop(A) ::= LIKE_KW|MATCH(A). likeop(A) ::= NOT LIKE_KW|MATCH(X). {A=X; A.n|=0x80000000; /*A-overwrite-X*/} expr(A) ::= expr(A) likeop(OP) expr(Y). [LIKE_KW] { ExprList *pList; From 5e6710ab6540e45cfb79d85609f28c496d5b6f25 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Mon, 20 Feb 2017 19:13:37 +0000 Subject: [PATCH 1356/1484] Avoid unsigned integer overflows for SQLITE_WIN32_HEAP_INIT_SIZE when the Win32 heap subsystem is used with very large values of SQLITE_DEFAULT_CACHE_SIZE and/or SQLITE_DEFAULT_PAGE_SIZE. FossilOrigin-Name: 96b6a98e5e4cb0ddbfcd78b05bfbfcd8976e9f32 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/os_win.c | 52 ++++++++++++++++++++++++++++++++++++++++++++------- 3 files changed, 53 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index ab58b869fe..34aa979a22 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Small\sgrammar\ssimplification. -D 2017-02-20T14:30:17.816 +C Avoid\sunsigned\sinteger\soverflows\sfor\sSQLITE_WIN32_HEAP_INIT_SIZE\swhen\sthe\sWin32\sheap\ssubsystem\sis\sused\swith\svery\slarge\svalues\sof\sSQLITE_DEFAULT_CACHE_SIZE\sand/or\sSQLITE_DEFAULT_PAGE_SIZE. +D 2017-02-20T19:13:37.359 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 @@ -379,7 +379,7 @@ F src/os.h 8e976e59eb4ca1c0fca6d35ee803e38951cb0343 F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85 F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586 F src/os_unix.c 30e2c43e4955db990e5b5a81e901f8aa74cc8820 -F src/os_win.c cf90abd4e50d9f56d2c20ce8e005aff55d7bd8e9 +F src/os_win.c c97c79fe19dfb0a14c89b78280beabd9ac28acb1 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c ff1232b3088a39806035ecfac4fffeb22717d80b F src/pager.h f2a99646c5533ffe11afa43e9e0bea74054e4efa @@ -1556,7 +1556,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 491814272dce7e937b4734fcbc2ad69e12377b56 -R b4cf79fa4c0fd30460236bc8c090e993 -U drh -Z 32b02aa6638f1e40c7df4614e1f90d4a +P 0d8a868acd74fb1d076f23fda58b841bb7e6900b +R 42e490f947871a7f92e95baf4bc40d36 +U mistachkin +Z 144582bee7eff0d5ee39c945bf2670f2 diff --git a/manifest.uuid b/manifest.uuid index c411ab59d6..60aeb2563f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0d8a868acd74fb1d076f23fda58b841bb7e6900b \ No newline at end of file +96b6a98e5e4cb0ddbfcd78b05bfbfcd8976e9f32 \ No newline at end of file diff --git a/src/os_win.c b/src/os_win.c index 2cb5f7b0c8..8d75d8bec5 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -352,7 +352,34 @@ struct winVfsAppData { ****************************************************************************** */ #ifndef SQLITE_WIN32_HEAP_CREATE -# define SQLITE_WIN32_HEAP_CREATE (TRUE) +# define SQLITE_WIN32_HEAP_CREATE (TRUE) +#endif + +/* + * This is the maximum possible initial size of the Win32-specific heap, in + * bytes. + */ +#ifndef SQLITE_WIN32_HEAP_MAX_INIT_SIZE +# define SQLITE_WIN32_HEAP_MAX_INIT_SIZE (4294967295U) +#endif + +/* + * This is the extra space for the initial size of the Win32-specific heap, + * in bytes. This value may be zero. + */ +#ifndef SQLITE_WIN32_HEAP_INIT_EXTRA +# define SQLITE_WIN32_HEAP_INIT_EXTRA (4194304) +#endif + +/* + * Calculate the maximum legal cache size, in pages, based on the maximum + * possible initial heap size and the default page size, setting aside the + * needed extra space. + */ +#ifndef SQLITE_WIN32_MAX_CACHE_SIZE +# define SQLITE_WIN32_MAX_CACHE_SIZE (((SQLITE_WIN32_HEAP_MAX_INIT_SIZE) - \ + (SQLITE_WIN32_HEAP_INIT_EXTRA)) / \ + (SQLITE_DEFAULT_PAGE_SIZE)) #endif /* @@ -361,25 +388,36 @@ struct winVfsAppData { */ #ifndef SQLITE_WIN32_CACHE_SIZE # if SQLITE_DEFAULT_CACHE_SIZE>=0 -# define SQLITE_WIN32_CACHE_SIZE (SQLITE_DEFAULT_CACHE_SIZE) +# define SQLITE_WIN32_CACHE_SIZE (SQLITE_DEFAULT_CACHE_SIZE) # else -# define SQLITE_WIN32_CACHE_SIZE (-(SQLITE_DEFAULT_CACHE_SIZE)) +# define SQLITE_WIN32_CACHE_SIZE (-(SQLITE_DEFAULT_CACHE_SIZE)) # endif #endif +/* + * Make sure that the calculated cache size, in pages, cannot cause the + * initial size of the Win32-specific heap to exceed the maximum amount + * of memory that can be specified in the call to HeapCreate. + */ +#if SQLITE_WIN32_CACHE_SIZE>=SQLITE_WIN32_MAX_CACHE_SIZE +# undef SQLITE_WIN32_CACHE_SIZE +# define SQLITE_WIN32_CACHE_SIZE (2000) +#endif + /* * The initial size of the Win32-specific heap. This value may be zero. */ #ifndef SQLITE_WIN32_HEAP_INIT_SIZE -# define SQLITE_WIN32_HEAP_INIT_SIZE ((SQLITE_WIN32_CACHE_SIZE) * \ - (SQLITE_DEFAULT_PAGE_SIZE) + 4194304) +# define SQLITE_WIN32_HEAP_INIT_SIZE ((SQLITE_WIN32_CACHE_SIZE) * \ + (SQLITE_DEFAULT_PAGE_SIZE) + \ + (SQLITE_WIN32_HEAP_INIT_EXTRA)) #endif /* * The maximum size of the Win32-specific heap. This value may be zero. */ #ifndef SQLITE_WIN32_HEAP_MAX_SIZE -# define SQLITE_WIN32_HEAP_MAX_SIZE (0) +# define SQLITE_WIN32_HEAP_MAX_SIZE (0) #endif /* @@ -387,7 +425,7 @@ struct winVfsAppData { * zero for the default behavior. */ #ifndef SQLITE_WIN32_HEAP_FLAGS -# define SQLITE_WIN32_HEAP_FLAGS (0) +# define SQLITE_WIN32_HEAP_FLAGS (0) #endif From 4689956b9e0dfad404a0b103d7903b8cbfddb48f Mon Sep 17 00:00:00 2001 From: mistachkin Date: Mon, 20 Feb 2017 23:32:04 +0000 Subject: [PATCH 1357/1484] Correct a harmless typo in the previous check-in. FossilOrigin-Name: 1589db012ef1389bf84399fccf96d143b2ac4c0f --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/os_win.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 34aa979a22..b9e136d680 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sunsigned\sinteger\soverflows\sfor\sSQLITE_WIN32_HEAP_INIT_SIZE\swhen\sthe\sWin32\sheap\ssubsystem\sis\sused\swith\svery\slarge\svalues\sof\sSQLITE_DEFAULT_CACHE_SIZE\sand/or\sSQLITE_DEFAULT_PAGE_SIZE. -D 2017-02-20T19:13:37.359 +C Correct\sa\sharmless\stypo\sin\sthe\sprevious\scheck-in. +D 2017-02-20T23:32:04.979 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 @@ -379,7 +379,7 @@ F src/os.h 8e976e59eb4ca1c0fca6d35ee803e38951cb0343 F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85 F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586 F src/os_unix.c 30e2c43e4955db990e5b5a81e901f8aa74cc8820 -F src/os_win.c c97c79fe19dfb0a14c89b78280beabd9ac28acb1 +F src/os_win.c 2a6c73eef01c51a048cc4ddccd57f981afbec18a F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c ff1232b3088a39806035ecfac4fffeb22717d80b F src/pager.h f2a99646c5533ffe11afa43e9e0bea74054e4efa @@ -1556,7 +1556,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 0d8a868acd74fb1d076f23fda58b841bb7e6900b -R 42e490f947871a7f92e95baf4bc40d36 +P 96b6a98e5e4cb0ddbfcd78b05bfbfcd8976e9f32 +R a6d884232566cde130b9b77412776230 U mistachkin -Z 144582bee7eff0d5ee39c945bf2670f2 +Z c97450fc686b8c32bf5204625d8622fc diff --git a/manifest.uuid b/manifest.uuid index 60aeb2563f..a4b5b98287 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -96b6a98e5e4cb0ddbfcd78b05bfbfcd8976e9f32 \ No newline at end of file +1589db012ef1389bf84399fccf96d143b2ac4c0f \ No newline at end of file diff --git a/src/os_win.c b/src/os_win.c index 8d75d8bec5..a87d7d0925 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -399,7 +399,7 @@ struct winVfsAppData { * initial size of the Win32-specific heap to exceed the maximum amount * of memory that can be specified in the call to HeapCreate. */ -#if SQLITE_WIN32_CACHE_SIZE>=SQLITE_WIN32_MAX_CACHE_SIZE +#if SQLITE_WIN32_CACHE_SIZE>SQLITE_WIN32_MAX_CACHE_SIZE # undef SQLITE_WIN32_CACHE_SIZE # define SQLITE_WIN32_CACHE_SIZE (2000) #endif From e3247822549c6ef80b33baaffb0f4698ef9861bc Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 21 Feb 2017 15:27:22 +0000 Subject: [PATCH 1358/1484] Very small enhancement to dispatch speed for SQL functions. FossilOrigin-Name: 3c3228ed16ed8a72630bd56bb9192ee3c7f82093 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/vdbe.c | 14 +++++++------- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index b9e136d680..ec707ac5ad 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Correct\sa\sharmless\stypo\sin\sthe\sprevious\scheck-in. -D 2017-02-20T23:32:04.979 +C Very\ssmall\senhancement\sto\sdispatch\sspeed\sfor\sSQL\sfunctions. +D 2017-02-21T15:27:22.044 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 @@ -461,7 +461,7 @@ F src/update.c 456d4a4656f8a03c2abc88a51b19172197400e58 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c ca8440ede81e155d15cff7c101654f60b55a9ae6 F src/vacuum.c 1fe4555cd8c9b263afb85b5b4ee3a4a4181ad569 -F src/vdbe.c 16f378640570c24442fd7191b136b5d6380f5c7b +F src/vdbe.c 16542e327eb38763490473dc0e9e9396924f30b2 F src/vdbe.h 59998ffd71d7caa8886bc78dafaf8caeccd4c13c F src/vdbeInt.h 4e4b15b2e1330e1636e4e01974eab2b0b985092f F src/vdbeapi.c 3e4a8893feeb78620f4aac4ac5b85d92255b97e1 @@ -1556,7 +1556,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 96b6a98e5e4cb0ddbfcd78b05bfbfcd8976e9f32 -R a6d884232566cde130b9b77412776230 -U mistachkin -Z c97450fc686b8c32bf5204625d8622fc +P 1589db012ef1389bf84399fccf96d143b2ac4c0f +R e3362d21e61dd042dd5284f17843c5d9 +U drh +Z 12602c247389d019265df8c626a67cf1 diff --git a/manifest.uuid b/manifest.uuid index a4b5b98287..451bfd624c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1589db012ef1389bf84399fccf96d143b2ac4c0f \ No newline at end of file +3c3228ed16ed8a72630bd56bb9192ee3c7f82093 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 7f286b2c6d..97aa519df1 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -1669,21 +1669,21 @@ case OP_Function: { for(i=pCtx->argc-1; i>=0; i--) pCtx->argv[i] = &aMem[pOp->p2+i]; } - memAboutToChange(p, pCtx->pOut); + memAboutToChange(p, pOut); #ifdef SQLITE_DEBUG for(i=0; iargc; i++){ assert( memIsValid(pCtx->argv[i]) ); REGISTER_TRACE(pOp->p2+i, pCtx->argv[i]); } #endif - MemSetTypeFlag(pCtx->pOut, MEM_Null); + MemSetTypeFlag(pOut, MEM_Null); pCtx->fErrorOrAux = 0; (*pCtx->pFunc->xSFunc)(pCtx, pCtx->argc, pCtx->argv);/* IMP: R-24505-23230 */ /* If the function returned an error, throw an exception */ if( pCtx->fErrorOrAux ){ if( pCtx->isError ){ - sqlite3VdbeError(p, "%s", sqlite3_value_text(pCtx->pOut)); + sqlite3VdbeError(p, "%s", sqlite3_value_text(pOut)); rc = pCtx->isError; } sqlite3VdbeDeleteAuxData(db, &p->pAuxData, pCtx->iOp, pOp->p1); @@ -1692,12 +1692,12 @@ case OP_Function: { /* Copy the result of the function into register P3 */ if( pOut->flags & (MEM_Str|MEM_Blob) ){ - sqlite3VdbeChangeEncoding(pCtx->pOut, encoding); - if( sqlite3VdbeMemTooBig(pCtx->pOut) ) goto too_big; + sqlite3VdbeChangeEncoding(pOut, encoding); + if( sqlite3VdbeMemTooBig(pOut) ) goto too_big; } - REGISTER_TRACE(pOp->p3, pCtx->pOut); - UPDATE_MAX_BLOBSIZE(pCtx->pOut); + REGISTER_TRACE(pOp->p3, pOut); + UPDATE_MAX_BLOBSIZE(pOut); break; } From f0e808c60b66cae45cbcf3c0fffb1e08776e879e Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 21 Feb 2017 17:52:58 +0000 Subject: [PATCH 1359/1484] Fix an FTS5 problem that could cause a crash when certain queries were interrupted using sqlite3_interrupt(). FossilOrigin-Name: e400909f313c317b7b67be6eb867ed61df7383dc --- ext/fts5/fts5_expr.c | 15 +++++- ext/fts5/test/fts5faultD.test | 87 +++++++++++++++++++++++++++++++++++ manifest | 15 +++--- manifest.uuid | 2 +- 4 files changed, 109 insertions(+), 10 deletions(-) create mode 100644 ext/fts5/test/fts5faultD.test diff --git a/ext/fts5/fts5_expr.c b/ext/fts5/fts5_expr.c index 209748bbf5..e18691ad0b 100644 --- a/ext/fts5/fts5_expr.c +++ b/ext/fts5/fts5_expr.c @@ -1110,7 +1110,10 @@ static int fts5ExprNodeNext_OR( || (bFromValid && fts5RowidCmp(pExpr, p1->iRowid, iFrom)<0) ){ int rc = fts5ExprNodeNext(pExpr, p1, bFromValid, iFrom); - if( rc!=SQLITE_OK ) return rc; + if( rc!=SQLITE_OK ){ + pNode->bNomatch = 0; + return rc; + } } } } @@ -1141,7 +1144,10 @@ static int fts5ExprNodeTest_AND( if( cmp>0 ){ /* Advance pChild until it points to iLast or laster */ rc = fts5ExprNodeNext(pExpr, pChild, 1, iLast); - if( rc!=SQLITE_OK ) return rc; + if( rc!=SQLITE_OK ){ + pAnd->bNomatch = 0; + return rc; + } } /* If the child node is now at EOF, so is the parent AND node. Otherwise, @@ -1180,6 +1186,8 @@ static int fts5ExprNodeNext_AND( int rc = fts5ExprNodeNext(pExpr, pNode->apChild[0], bFromValid, iFrom); if( rc==SQLITE_OK ){ rc = fts5ExprNodeTest_AND(pExpr, pNode); + }else{ + pNode->bNomatch = 0; } return rc; } @@ -1222,6 +1230,9 @@ static int fts5ExprNodeNext_NOT( if( rc==SQLITE_OK ){ rc = fts5ExprNodeTest_NOT(pExpr, pNode); } + if( rc!=SQLITE_OK ){ + pNode->bNomatch = 0; + } return rc; } diff --git a/ext/fts5/test/fts5faultD.test b/ext/fts5/test/fts5faultD.test new file mode 100644 index 0000000000..e259cbf610 --- /dev/null +++ b/ext/fts5/test/fts5faultD.test @@ -0,0 +1,87 @@ +# 2016 February 2 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#************************************************************************* +# +# This file is focused on OOM errors. +# + +source [file join [file dirname [info script]] fts5_common.tcl] +source $testdir/malloc_common.tcl +set testprefix fts5faultA + +# If SQLITE_ENABLE_FTS3 is defined, omit this file. +ifcapable !fts5 { + finish_test + return +} + +foreach_detail_mode $testprefix { + if {"%DETAIL%"=="none"} continue + + do_execsql_test 1.0 { + CREATE VIRTUAL TABLE o1 USING fts5(a, b, c, detail=%DETAIL%); + INSERT INTO o1(o1, rank) VALUES('pgsz', 32); + + WITH s(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<60 ) + INSERT INTO o1 SELECT 'A', 'B', 'C' FROM s; + + WITH s(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<60 ) + INSERT INTO o1 SELECT 'C', 'A', 'B' FROM s; + + WITH s(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<60 ) + INSERT INTO o1 SELECT 'B', 'C', 'A' FROM s; + } + + do_faultsim_test 1 -faults int* -prep { + sqlite3 db test.db + } -body { + execsql { SELECT count(*) FROM o1('a') } + } -test { + faultsim_test_result {0 180} {1 {vtable constructor failed: o1}} + } + + do_faultsim_test 2 -faults int* -prep { + sqlite3 db test.db + } -body { + execsql { SELECT * FROM o1('a:a AND {b c}:b') ORDER BY rank } + expr 1 + } -test { + faultsim_test_result {0 1} {1 {vtable constructor failed: o1}} + } + + do_faultsim_test 3 -faults int* -prep { + sqlite3 db test.db + } -body { + execsql { SELECT * FROM o1('{b c}:b NOT a:a') ORDER BY rank } + expr 1 + } -test { + faultsim_test_result {0 1} {1 {vtable constructor failed: o1}} + } + + do_faultsim_test 4 -faults int* -prep { + sqlite3 db test.db + } -body { + execsql { SELECT * FROM o1('b:b OR a:a') } + expr 1 + } -test { + faultsim_test_result {0 1} {1 {vtable constructor failed: o1}} + } + + do_faultsim_test 5 -faults int* -prep { + sqlite3 db test.db + } -body { + execsql { SELECT count(*) FROM o1('c:b') } + expr 1 + } -test { + faultsim_test_result {0 1} {1 {vtable constructor failed: o1}} + } +} + +finish_test diff --git a/manifest b/manifest index ec707ac5ad..c5dbc5dfad 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Very\ssmall\senhancement\sto\sdispatch\sspeed\sfor\sSQL\sfunctions. -D 2017-02-21T15:27:22.044 +C Fix\san\sFTS5\sproblem\sthat\scould\scause\sa\scrash\swhen\scertain\squeries\swere\ninterrupted\susing\ssqlite3_interrupt(). +D 2017-02-21T17:52:58.643 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 @@ -102,7 +102,7 @@ F ext/fts5/fts5Int.h c629b24d2b92b99596f3b8e82289fddca06df6e1 F ext/fts5/fts5_aux.c 67acf8d51723cf28ffc3828210ba662df4b8d267 F ext/fts5/fts5_buffer.c 4c1502d4c956cd092c89ce4480867f9d8bf325cd F ext/fts5/fts5_config.c 5af9c360e99669d29f06492c370892394aba0857 -F ext/fts5/fts5_expr.c 33f0e8063ac7360bcd71c0ff0dcbacdc05fffe50 +F ext/fts5/fts5_expr.c c6ecc2280162a3714d15dce2a8f2299f748b627c F ext/fts5/fts5_hash.c 880998e596b60f078348d48732ca4ad9a90caad2 F ext/fts5/fts5_index.c f67032a9a529ba52a545e6e3ab970764199c05d4 F ext/fts5/fts5_main.c f85281445dcf8be32d18841c93a6f90fe27dbfe2 @@ -160,6 +160,7 @@ F ext/fts5/test/fts5fault8.test 6785af34bd1760de74e2824ea9c161965af78f85 F ext/fts5/test/fts5fault9.test e10e395428a9ea0596ebe752ff7123d16ab78e08 F ext/fts5/test/fts5faultA.test fa5d59c0ff62b7125cd14eee38ded1c46e15a7ea F ext/fts5/test/fts5faultB.test 7f3bba790fa172073ac314f9b8ed197390b61eca +F ext/fts5/test/fts5faultD.test cc5d1225556e356615e719c612e845d41bff7d5a F ext/fts5/test/fts5full.test 6f6143af0c6700501d9fd597189dfab1555bb741 F ext/fts5/test/fts5fuzz1.test bece4695fc169b61ab236ada7931c6e4942cbef9 F ext/fts5/test/fts5hash.test 06f9309ccb4d5050a131594e9e47d0b21456837d @@ -1556,7 +1557,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 1589db012ef1389bf84399fccf96d143b2ac4c0f -R e3362d21e61dd042dd5284f17843c5d9 -U drh -Z 12602c247389d019265df8c626a67cf1 +P 3c3228ed16ed8a72630bd56bb9192ee3c7f82093 +R c2d6d6c70c7c0d8b681ef9ca8535c3a3 +U dan +Z 2a4ed498ce9ed73234b51fb6f9a899a9 diff --git a/manifest.uuid b/manifest.uuid index 451bfd624c..94de19d8f1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3c3228ed16ed8a72630bd56bb9192ee3c7f82093 \ No newline at end of file +e400909f313c317b7b67be6eb867ed61df7383dc \ No newline at end of file From 1325adf5e9d6745c9e00a85e294025ceda0691e9 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 21 Feb 2017 21:24:05 +0000 Subject: [PATCH 1360/1484] In sqlite3VdbeHalt(), return as soon as possible if Vdbe.magic!=VDBE_MAGIC_RUN. This makes sqlite3_reset() slightly faster in some cases. FossilOrigin-Name: 80adc0cb4ed7bacc54b15ac8b5b205403939c8c4 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbeaux.c | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index c5dbc5dfad..0c80aaffba 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\sFTS5\sproblem\sthat\scould\scause\sa\scrash\swhen\scertain\squeries\swere\ninterrupted\susing\ssqlite3_interrupt(). -D 2017-02-21T17:52:58.643 +C In\ssqlite3VdbeHalt(),\sreturn\sas\ssoon\sas\spossible\sif\nVdbe.magic!=VDBE_MAGIC_RUN.\sThis\smakes\ssqlite3_reset()\sslightly\sfaster\sin\ssome\ncases. +D 2017-02-21T21:24:05.029 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 @@ -466,7 +466,7 @@ F src/vdbe.c 16542e327eb38763490473dc0e9e9396924f30b2 F src/vdbe.h 59998ffd71d7caa8886bc78dafaf8caeccd4c13c F src/vdbeInt.h 4e4b15b2e1330e1636e4e01974eab2b0b985092f F src/vdbeapi.c 3e4a8893feeb78620f4aac4ac5b85d92255b97e1 -F src/vdbeaux.c 4122458d33318ab039c4b5da1ca4e7c9221c38e4 +F src/vdbeaux.c 2f48204a0f2875b098ee046bba9265907297b0b5 F src/vdbeblob.c 359891617358deefc85bef7bcf787fa6b77facb9 F src/vdbemem.c 3b5a9a5b375458d3e12a50ae1aaa41eeec2175fd F src/vdbesort.c eda25cb2d1727efca6f7862fea32b8aa33c0face @@ -1557,7 +1557,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 3c3228ed16ed8a72630bd56bb9192ee3c7f82093 -R c2d6d6c70c7c0d8b681ef9ca8535c3a3 +P e400909f313c317b7b67be6eb867ed61df7383dc +R 5434ea5a08220297aa4d56dd68f46447 U dan -Z 2a4ed498ce9ed73234b51fb6f9a899a9 +Z 68cf5c57f26344b5e30f88013a5c9e52 diff --git a/manifest.uuid b/manifest.uuid index 94de19d8f1..2ace79cb16 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e400909f313c317b7b67be6eb867ed61df7383dc \ No newline at end of file +80adc0cb4ed7bacc54b15ac8b5b205403939c8c4 \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index cf062cf01d..292ff2bdd2 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -2609,13 +2609,13 @@ int sqlite3VdbeHalt(Vdbe *p){ ** one, or the complete transaction if there is no statement transaction. */ + if( p->magic!=VDBE_MAGIC_RUN ){ + return SQLITE_OK; + } if( db->mallocFailed ){ p->rc = SQLITE_NOMEM_BKPT; } closeAllCursors(p); - if( p->magic!=VDBE_MAGIC_RUN ){ - return SQLITE_OK; - } checkActiveVdbeCnt(db); /* No commit or rollback needed if the program never started or if the From 8a284dcefe85c88be8f07997931cb8b208087a9b Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 22 Feb 2017 14:15:37 +0000 Subject: [PATCH 1361/1484] Enhance "PRAGMA integrity_check" so that it verifies CHECK constraints. FossilOrigin-Name: 549bae0856004ff65b505175460abd598b30fe57 --- manifest | 19 +++++++++++-------- manifest.uuid | 2 +- src/pragma.c | 27 ++++++++++++++++++++++++++- test/check.test | 8 ++++++-- 4 files changed, 44 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 0c80aaffba..7e7a9e3e8a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\ssqlite3VdbeHalt(),\sreturn\sas\ssoon\sas\spossible\sif\nVdbe.magic!=VDBE_MAGIC_RUN.\sThis\smakes\ssqlite3_reset()\sslightly\sfaster\sin\ssome\ncases. -D 2017-02-21T21:24:05.029 +C Enhance\s"PRAGMA\sintegrity_check"\sso\sthat\sit\sverifies\sCHECK\sconstraints. +D 2017-02-22T14:15:37.561 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 @@ -388,7 +388,7 @@ F src/parse.y af8830094f4aecb91cb69721f3601ad10c36abc4 F src/pcache.c 62835bed959e2914edd26afadfecce29ece0e870 F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 F src/pcache1.c e3967219b2a92b9edcb9324a4ba75009090d3953 -F src/pragma.c 7831956012f5d764761fbd023e59b0ffc08f5e8d +F src/pragma.c aa4af3d8c4d9086cbceeafcbb8a5e75605a1207d F src/pragma.h 61aa5389118594bebb28120a6720401aee34ce1a F src/prepare.c b1140c3d0cf59bc85ace00ce363153041b424b7a F src/printf.c 67427bbee66d891fc6f6f5aada857e9cdb368c1c @@ -576,7 +576,7 @@ F test/capi3d.test 485048dc5cd07bc68011e4917ad035ad6047ab82 F test/capi3e.test 3d49c01ef2a1a55f41d73cba2b23b5059ec460fe F test/cast.test 4c275cbdc8202d6f9c54a3596701719868ac7dc3 F test/cffault.test 9d6b20606afe712374952eec4f8fd74b1a8097ef -F test/check.test 85a84bfc4be0e83f668747211c7cd45a6721d485 +F test/check.test 92b23a91fb7be12fba7ee9ce518217e2919a21da F test/close.test 83947daf3b700631f90f4850ddaab455be4af73d F test/closure01.test b1703ba40639cfc9b295cf478d70739415eec6a4 F test/coalesce.test cee0dccb9fbd2d494b77234bccf9dc6c6786eb91 @@ -1557,7 +1557,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e400909f313c317b7b67be6eb867ed61df7383dc -R 5434ea5a08220297aa4d56dd68f46447 -U dan -Z 68cf5c57f26344b5e30f88013a5c9e52 +P 80adc0cb4ed7bacc54b15ac8b5b205403939c8c4 +R b17279d0fcfdb924feca449c6ae8dc40 +T *branch * integrity-check-improvements +T *sym-integrity-check-improvements * +T -sym-trunk * +U drh +Z 83b8ae4f812a6d4117d2cc9c8ae430b2 diff --git a/manifest.uuid b/manifest.uuid index 2ace79cb16..8a2cc1e157 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -80adc0cb4ed7bacc54b15ac8b5b205403939c8c4 \ No newline at end of file +549bae0856004ff65b505175460abd598b30fe57 \ No newline at end of file diff --git a/src/pragma.c b/src/pragma.c index b1775a4082..c7d092b30d 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -1481,7 +1481,7 @@ void sqlite3Pragma( int iDataCur, iIdxCur; int r1 = -1; - if( pTab->pIndex==0 ) continue; + if( pTab->pIndex==0 && pTab->pCheck==0 ) continue; pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab); addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1); /* Stop if out of errors */ VdbeCoverage(v); @@ -1517,6 +1517,31 @@ void sqlite3Pragma( sqlite3VdbeJumpHere(v, jmp2); sqlite3VdbeJumpHere(v, jmp3); } + /* Verify CHECK constraints */ + if( pTab->pCheck && (db->flags & SQLITE_IgnoreChecks)==0 ){ + int addrCkFault = sqlite3VdbeMakeLabel(v); + int addrCkOk = sqlite3VdbeMakeLabel(v); + ExprList *pCheck = pTab->pCheck; + char *zErr; + int k; + pParse->iSelfTab = iDataCur; + sqlite3ExprCachePush(pParse); + for(k=pCheck->nExpr-1; k>0; k--){ + sqlite3ExprIfFalse(pParse, pCheck->a[k].pExpr, addrCkFault, 0); + } + sqlite3ExprIfTrue(pParse, pCheck->a[0].pExpr, addrCkOk, + SQLITE_JUMPIFNULL); + sqlite3VdbeResolveLabel(v, addrCkFault); + sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); /* Decrement error limit */ + zErr = sqlite3MPrintf(db, "CHECK constraint failed in %s", + pTab->zName); + sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC); + sqlite3VdbeAddOp2(v, OP_ResultRow, 3, 1); + sqlite3VdbeAddOp2(v, OP_IfPos, 1, addrCkOk); VdbeCoverage(v); + sqlite3VdbeAddOp0(v, OP_Halt); + sqlite3VdbeResolveLabel(v, addrCkOk); + sqlite3ExprCachePop(pParse); + } /* Validate index entries for the current row */ for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ int jmp2, jmp3, jmp4, jmp5; diff --git a/test/check.test b/test/check.test index 43e447f70d..19f252677c 100644 --- a/test/check.test +++ b/test/check.test @@ -309,11 +309,15 @@ do_test check-4.8 { PRAGMA ignore_check_constraints=ON; UPDATE t4 SET x=0, y=1; SELECT * FROM t4; + PRAGMA integrity_check; } -} {0 1} +} {0 1 ok} +do_execsql_test check-4.8.1 { + PRAGMA ignore_check_constraints=OFF; + PRAGMA integrity_check; +} {{CHECK constraint failed in t4}} do_test check-4.9 { catchsql { - PRAGMA ignore_check_constraints=OFF; UPDATE t4 SET x=0, y=2; } } {1 {CHECK constraint failed: t4}} From 8b174f2916c16fc66c8b0248056011e2c5104e36 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 22 Feb 2017 15:11:36 +0000 Subject: [PATCH 1362/1484] Fix integrity_check so that it verifies NOT NULL constraints even for tables that have no indexes. Enhance quick_check so that it verifies NOT NULL and CHECK constraints. FossilOrigin-Name: 5264844b069cdc20f456acee9f5b2b97c986120d --- manifest | 19 ++++++++---------- manifest.uuid | 2 +- src/build.c | 1 + src/pragma.c | 51 ++++++++++++++++++++++++++++++++----------------- src/sqliteInt.h | 17 +++++++++-------- 5 files changed, 52 insertions(+), 38 deletions(-) diff --git a/manifest b/manifest index 7e7a9e3e8a..7776d07ac7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\s"PRAGMA\sintegrity_check"\sso\sthat\sit\sverifies\sCHECK\sconstraints. -D 2017-02-22T14:15:37.561 +C Fix\sintegrity_check\sso\sthat\sit\sverifies\sNOT\sNULL\sconstraints\seven\sfor\stables\nthat\shave\sno\sindexes.\s\sEnhance\squick_check\sso\sthat\sit\sverifies\sNOT\sNULL\sand\nCHECK\sconstraints. +D 2017-02-22T15:11:36.862 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 @@ -341,7 +341,7 @@ F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca F src/btree.c 3ae66974881e74df9909093818b4c3428f8d7982 F src/btree.h e6d352808956ec163a17f832193a3e198b3fb0ac F src/btreeInt.h cd55d39d9916270837a88c12e701047cba0729b0 -F src/build.c 9e799f1edd910dfa8a0bc29bd390d35d310596af +F src/build.c 51b473eec465f471d607b54e8dbc00751c3f8a1f F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c a9984df73898c042a5cfc8f9d8e7723d02bc35c9 @@ -388,7 +388,7 @@ F src/parse.y af8830094f4aecb91cb69721f3601ad10c36abc4 F src/pcache.c 62835bed959e2914edd26afadfecce29ece0e870 F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 F src/pcache1.c e3967219b2a92b9edcb9324a4ba75009090d3953 -F src/pragma.c aa4af3d8c4d9086cbceeafcbb8a5e75605a1207d +F src/pragma.c ec83a3cb496d6d6d24f9de78ccbb24369dcedf48 F src/pragma.h 61aa5389118594bebb28120a6720401aee34ce1a F src/prepare.c b1140c3d0cf59bc85ace00ce363153041b424b7a F src/printf.c 67427bbee66d891fc6f6f5aada857e9cdb368c1c @@ -400,7 +400,7 @@ F src/shell.c bf976d5301be9d8a4c52852c97909cc9a41ee20d F src/sqlite.h.in 751ff125eb159c8f92c182b8df980a5e4f50e966 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae -F src/sqliteInt.h 46fe8e5aee3825d77fa771216ef263dc947030e7 +F src/sqliteInt.h a23e18aebdd0d851c2956a74a3a4f12ff202b472 F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 @@ -1557,10 +1557,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 80adc0cb4ed7bacc54b15ac8b5b205403939c8c4 -R b17279d0fcfdb924feca449c6ae8dc40 -T *branch * integrity-check-improvements -T *sym-integrity-check-improvements * -T -sym-trunk * +P 549bae0856004ff65b505175460abd598b30fe57 +R ca36fe65b7e723d2451bfac8ac59f0b7 U drh -Z 83b8ae4f812a6d4117d2cc9c8ae430b2 +Z 40e14a5b2e43e016c602364a556c9a0b diff --git a/manifest.uuid b/manifest.uuid index 8a2cc1e157..e0226c546a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -549bae0856004ff65b505175460abd598b30fe57 \ No newline at end of file +5264844b069cdc20f456acee9f5b2b97c986120d \ No newline at end of file diff --git a/src/build.c b/src/build.c index cd9c81be82..6e1e2177be 100644 --- a/src/build.c +++ b/src/build.c @@ -1115,6 +1115,7 @@ void sqlite3AddNotNull(Parse *pParse, int onError){ p = pParse->pNewTable; if( p==0 || NEVER(p->nCol<1) ) return; p->aCol[p->nCol-1].notNull = (u8)onError; + p->tabFlags |= TF_HasNotNull; } /* diff --git a/src/pragma.c b/src/pragma.c index c7d092b30d..8a2b3de21e 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -1377,9 +1377,17 @@ void sqlite3Pragma( #endif #ifndef SQLITE_OMIT_INTEGRITY_CHECK - /* Pragma "quick_check" is reduced version of + /* PRAGMA integrity_check + ** PRAGMA integrity_check(N) + ** PRAGMA quick_check + ** PRAGMA quick_check(N) + ** + ** Verify the integrity of the database. + ** + ** The "quick_check" is reduced version of ** integrity_check designed to detect most database corruption - ** without most of the overhead of a full integrity-check. + ** without the overhead of cross-checking indexes. Quick_check + ** is linear time wherease integrity_check is O(NlogN). */ case PragTyp_INTEGRITY_CHECK: { int i, j, addr, mxErr; @@ -1473,7 +1481,7 @@ void sqlite3Pragma( /* Make sure all the indices are constructed correctly. */ - for(x=sqliteHashFirst(pTbls); x && !isQuick; x=sqliteHashNext(x)){ + for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){ Table *pTab = sqliteHashData(x); Index *pIdx, *pPk; Index *pPrior = 0; @@ -1481,7 +1489,12 @@ void sqlite3Pragma( int iDataCur, iIdxCur; int r1 = -1; - if( pTab->pIndex==0 && pTab->pCheck==0 ) continue; + if( pTab->pCheck==0 + && (pTab->tabFlags & TF_HasNotNull)==0 + && (pTab->pIndex==0 || isQuick) + ){ + continue; /* No additional checks needed for this table */ + } pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab); addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1); /* Stop if out of errors */ VdbeCoverage(v); @@ -1543,7 +1556,7 @@ void sqlite3Pragma( sqlite3ExprCachePop(pParse); } /* Validate index entries for the current row */ - for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ + for(j=0, pIdx=pTab->pIndex; pIdx && !isQuick; pIdx=pIdx->pNext, j++){ int jmp2, jmp3, jmp4, jmp5; int ckUniq = sqlite3VdbeMakeLabel(v); if( pPk==pIdx ) continue; @@ -1595,19 +1608,21 @@ void sqlite3Pragma( sqlite3VdbeAddOp2(v, OP_Next, iDataCur, loopTop); VdbeCoverage(v); sqlite3VdbeJumpHere(v, loopTop-1); #ifndef SQLITE_OMIT_BTREECOUNT - sqlite3VdbeLoadString(v, 2, "wrong # of entries in index "); - for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ - if( pPk==pIdx ) continue; - addr = sqlite3VdbeCurrentAddr(v); - sqlite3VdbeAddOp2(v, OP_IfPos, 1, addr+2); VdbeCoverage(v); - sqlite3VdbeAddOp2(v, OP_Halt, 0, 0); - sqlite3VdbeAddOp2(v, OP_Count, iIdxCur+j, 3); - sqlite3VdbeAddOp3(v, OP_Eq, 8+j, addr+8, 3); VdbeCoverage(v); - sqlite3VdbeChangeP5(v, SQLITE_NOTNULL); - sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); - sqlite3VdbeLoadString(v, 3, pIdx->zName); - sqlite3VdbeAddOp3(v, OP_Concat, 3, 2, 7); - sqlite3VdbeAddOp2(v, OP_ResultRow, 7, 1); + if( !isQuick ){ + sqlite3VdbeLoadString(v, 2, "wrong # of entries in index "); + for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ + if( pPk==pIdx ) continue; + addr = sqlite3VdbeCurrentAddr(v); + sqlite3VdbeAddOp2(v, OP_IfPos, 1, addr+2); VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_Halt, 0, 0); + sqlite3VdbeAddOp2(v, OP_Count, iIdxCur+j, 3); + sqlite3VdbeAddOp3(v, OP_Eq, 8+j, addr+8, 3); VdbeCoverage(v); + sqlite3VdbeChangeP5(v, SQLITE_NOTNULL); + sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); + sqlite3VdbeLoadString(v, 3, pIdx->zName); + sqlite3VdbeAddOp3(v, OP_Concat, 3, 2, 7); + sqlite3VdbeAddOp2(v, OP_ResultRow, 7, 1); + } } #endif /* SQLITE_OMIT_BTREECOUNT */ } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 9a53d33626..d9ec8c5bc9 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1879,14 +1879,15 @@ struct Table { ** the TF_OOOHidden attribute would apply in this case. Such tables require ** special handling during INSERT processing. */ -#define TF_Readonly 0x01 /* Read-only system table */ -#define TF_Ephemeral 0x02 /* An ephemeral table */ -#define TF_HasPrimaryKey 0x04 /* Table has a primary key */ -#define TF_Autoincrement 0x08 /* Integer primary key is autoincrement */ -/* available for reuse: 0x10 */ -#define TF_WithoutRowid 0x20 /* No rowid. PRIMARY KEY is the key */ -#define TF_NoVisibleRowid 0x40 /* No user-visible "rowid" column */ -#define TF_OOOHidden 0x80 /* Out-of-Order hidden columns */ +#define TF_Readonly 0x0001 /* Read-only system table */ +#define TF_Ephemeral 0x0002 /* An ephemeral table */ +#define TF_HasPrimaryKey 0x0004 /* Table has a primary key */ +#define TF_Autoincrement 0x0008 /* Integer primary key is autoincrement */ +/* available for reuse: 0x0010 */ +#define TF_WithoutRowid 0x0020 /* No rowid. PRIMARY KEY is the key */ +#define TF_NoVisibleRowid 0x0040 /* No user-visible "rowid" column */ +#define TF_OOOHidden 0x0080 /* Out-of-Order hidden columns */ +#define TF_HasNotNull 0x0100 /* Contains NOT NULL constraints */ /* From 66accfc56b51387b241ba2e27e7364ea1a01f37b Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 22 Feb 2017 18:04:42 +0000 Subject: [PATCH 1363/1484] Cleanup and simplification of the output row count limit control of PRAGMA integrity_check. FossilOrigin-Name: 5af7d72ed9ec758283d78ceb46627d72021c1c60 --- manifest | 14 ++++++------ manifest.uuid | 2 +- src/pragma.c | 60 +++++++++++++++++++++++---------------------------- src/vdbe.c | 6 +++--- 4 files changed, 38 insertions(+), 44 deletions(-) diff --git a/manifest b/manifest index 7776d07ac7..677bc6001d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sintegrity_check\sso\sthat\sit\sverifies\sNOT\sNULL\sconstraints\seven\sfor\stables\nthat\shave\sno\sindexes.\s\sEnhance\squick_check\sso\sthat\sit\sverifies\sNOT\sNULL\sand\nCHECK\sconstraints. -D 2017-02-22T15:11:36.862 +C Cleanup\sand\ssimplification\sof\sthe\soutput\srow\scount\slimit\scontrol\sof\nPRAGMA\sintegrity_check. +D 2017-02-22T18:04:42.473 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 @@ -388,7 +388,7 @@ F src/parse.y af8830094f4aecb91cb69721f3601ad10c36abc4 F src/pcache.c 62835bed959e2914edd26afadfecce29ece0e870 F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 F src/pcache1.c e3967219b2a92b9edcb9324a4ba75009090d3953 -F src/pragma.c ec83a3cb496d6d6d24f9de78ccbb24369dcedf48 +F src/pragma.c b127edeb54c744a101b371cfa2e221fd741bcd72 F src/pragma.h 61aa5389118594bebb28120a6720401aee34ce1a F src/prepare.c b1140c3d0cf59bc85ace00ce363153041b424b7a F src/printf.c 67427bbee66d891fc6f6f5aada857e9cdb368c1c @@ -462,7 +462,7 @@ F src/update.c 456d4a4656f8a03c2abc88a51b19172197400e58 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c ca8440ede81e155d15cff7c101654f60b55a9ae6 F src/vacuum.c 1fe4555cd8c9b263afb85b5b4ee3a4a4181ad569 -F src/vdbe.c 16542e327eb38763490473dc0e9e9396924f30b2 +F src/vdbe.c 83f387d9e6842b1dc99f6e85bb577c5bbc4e397d F src/vdbe.h 59998ffd71d7caa8886bc78dafaf8caeccd4c13c F src/vdbeInt.h 4e4b15b2e1330e1636e4e01974eab2b0b985092f F src/vdbeapi.c 3e4a8893feeb78620f4aac4ac5b85d92255b97e1 @@ -1557,7 +1557,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 549bae0856004ff65b505175460abd598b30fe57 -R ca36fe65b7e723d2451bfac8ac59f0b7 +P 5264844b069cdc20f456acee9f5b2b97c986120d +R 46f90a15a015e3c65c6378dae6f8ff19 U drh -Z 40e14a5b2e43e016c602364a556c9a0b +Z ac3f9bd06db21fa3e22e700d592b007d diff --git a/manifest.uuid b/manifest.uuid index e0226c546a..de6e14387f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5264844b069cdc20f456acee9f5b2b97c986120d \ No newline at end of file +5af7d72ed9ec758283d78ceb46627d72021c1c60 \ No newline at end of file diff --git a/src/pragma.c b/src/pragma.c index 8a2b3de21e..151a7a2e82 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -295,6 +295,22 @@ static const PragmaName *pragmaLocate(const char *zName){ return lwr>upr ? 0 : &aPragmaName[mid]; } +/* +** Helper subroutine for PRAGMA integrity_check: +** +** Generate code to output a single-column result row with the result +** held in register regResult. Decrement the result count and halt if +** the maximum number of result rows have been issued. +*/ +static int integrityCheckResultRow(Vdbe *v, int regResult){ + int addr; + sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, 1); + addr = sqlite3VdbeAddOp3(v, OP_IfPos, 1, sqlite3VdbeCurrentAddr(v)+2, 1); + VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_Halt, 0, 0); + return addr; +} + /* ** Process a pragma statement. ** @@ -1418,7 +1434,7 @@ void sqlite3Pragma( mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX; } } - sqlite3VdbeAddOp2(v, OP_Integer, mxErr, 1); /* reg[1] holds errors left */ + sqlite3VdbeAddOp2(v, OP_Integer, mxErr-1, 1); /* reg[1] holds errors left */ /* Do an integrity check on each database file */ for(i=0; inDb; i++){ @@ -1433,10 +1449,6 @@ void sqlite3Pragma( if( iDb>=0 && i!=iDb ) continue; sqlite3CodeVerifySchema(pParse, i); - addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1); /* Halt if out of errors */ - VdbeCoverage(v); - sqlite3VdbeAddOp2(v, OP_Halt, 0, 0); - sqlite3VdbeJumpHere(v, addr); /* Do an integrity check of the B-Tree ** @@ -1476,7 +1488,7 @@ void sqlite3Pragma( P4_DYNAMIC); sqlite3VdbeAddOp3(v, OP_Move, 2, 4, 1); sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 2); - sqlite3VdbeAddOp2(v, OP_ResultRow, 2, 1); + integrityCheckResultRow(v, 2); sqlite3VdbeJumpHere(v, addr); /* Make sure all the indices are constructed correctly. @@ -1496,10 +1508,6 @@ void sqlite3Pragma( continue; /* No additional checks needed for this table */ } pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab); - addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1); /* Stop if out of errors */ - VdbeCoverage(v); - sqlite3VdbeAddOp2(v, OP_Halt, 0, 0); - sqlite3VdbeJumpHere(v, addr); sqlite3ExprCacheClear(pParse); sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenRead, 0, 1, 0, &iDataCur, &iIdxCur); @@ -1514,21 +1522,17 @@ void sqlite3Pragma( /* Verify that all NOT NULL columns really are NOT NULL */ for(j=0; jnCol; j++){ char *zErr; - int jmp2, jmp3; + int jmp2; if( j==pTab->iPKey ) continue; if( pTab->aCol[j].notNull==0 ) continue; sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, j, 3); sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG); jmp2 = sqlite3VdbeAddOp1(v, OP_NotNull, 3); VdbeCoverage(v); - sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); /* Decrement error limit */ zErr = sqlite3MPrintf(db, "NULL value in %s.%s", pTab->zName, pTab->aCol[j].zName); sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC); - sqlite3VdbeAddOp2(v, OP_ResultRow, 3, 1); - jmp3 = sqlite3VdbeAddOp1(v, OP_IfPos, 1); VdbeCoverage(v); - sqlite3VdbeAddOp0(v, OP_Halt); + integrityCheckResultRow(v, 3); sqlite3VdbeJumpHere(v, jmp2); - sqlite3VdbeJumpHere(v, jmp3); } /* Verify CHECK constraints */ if( pTab->pCheck && (db->flags & SQLITE_IgnoreChecks)==0 ){ @@ -1545,13 +1549,10 @@ void sqlite3Pragma( sqlite3ExprIfTrue(pParse, pCheck->a[0].pExpr, addrCkOk, SQLITE_JUMPIFNULL); sqlite3VdbeResolveLabel(v, addrCkFault); - sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); /* Decrement error limit */ zErr = sqlite3MPrintf(db, "CHECK constraint failed in %s", pTab->zName); sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC); - sqlite3VdbeAddOp2(v, OP_ResultRow, 3, 1); - sqlite3VdbeAddOp2(v, OP_IfPos, 1, addrCkOk); VdbeCoverage(v); - sqlite3VdbeAddOp0(v, OP_Halt); + integrityCheckResultRow(v, 3); sqlite3VdbeResolveLabel(v, addrCkOk); sqlite3ExprCachePop(pParse); } @@ -1567,16 +1568,13 @@ void sqlite3Pragma( /* Verify that an index entry exists for the current table row */ jmp2 = sqlite3VdbeAddOp4Int(v, OP_Found, iIdxCur+j, ckUniq, r1, pIdx->nColumn); VdbeCoverage(v); - sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); /* Decrement error limit */ sqlite3VdbeLoadString(v, 3, "row "); sqlite3VdbeAddOp3(v, OP_Concat, 7, 3, 3); sqlite3VdbeLoadString(v, 4, " missing from index "); sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3); jmp5 = sqlite3VdbeLoadString(v, 4, pIdx->zName); sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3); - sqlite3VdbeAddOp2(v, OP_ResultRow, 3, 1); - jmp4 = sqlite3VdbeAddOp1(v, OP_IfPos, 1); VdbeCoverage(v); - sqlite3VdbeAddOp0(v, OP_Halt); + jmp4 = integrityCheckResultRow(v, 3); sqlite3VdbeJumpHere(v, jmp2); /* For UNIQUE indexes, verify that only one entry exists with the ** current key. The entry is unique if (1) any column is NULL @@ -1597,7 +1595,6 @@ void sqlite3Pragma( sqlite3VdbeJumpHere(v, jmp6); sqlite3VdbeAddOp4Int(v, OP_IdxGT, iIdxCur+j, uniqOk, r1, pIdx->nKeyCol); VdbeCoverage(v); - sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); /* Decrement error limit */ sqlite3VdbeLoadString(v, 3, "non-unique entry in index "); sqlite3VdbeGoto(v, jmp5); sqlite3VdbeResolveLabel(v, uniqOk); @@ -1612,16 +1609,13 @@ void sqlite3Pragma( sqlite3VdbeLoadString(v, 2, "wrong # of entries in index "); for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ if( pPk==pIdx ) continue; - addr = sqlite3VdbeCurrentAddr(v); - sqlite3VdbeAddOp2(v, OP_IfPos, 1, addr+2); VdbeCoverage(v); - sqlite3VdbeAddOp2(v, OP_Halt, 0, 0); sqlite3VdbeAddOp2(v, OP_Count, iIdxCur+j, 3); - sqlite3VdbeAddOp3(v, OP_Eq, 8+j, addr+8, 3); VdbeCoverage(v); + addr = sqlite3VdbeAddOp3(v, OP_Eq, 8+j, 0, 3); VdbeCoverage(v); sqlite3VdbeChangeP5(v, SQLITE_NOTNULL); - sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); sqlite3VdbeLoadString(v, 3, pIdx->zName); sqlite3VdbeAddOp3(v, OP_Concat, 3, 2, 7); - sqlite3VdbeAddOp2(v, OP_ResultRow, 7, 1); + integrityCheckResultRow(v, 7); + sqlite3VdbeJumpHere(v, addr); } } #endif /* SQLITE_OMIT_BTREECOUNT */ @@ -1631,7 +1625,7 @@ void sqlite3Pragma( static const int iLn = VDBE_OFFSET_LINENO(2); static const VdbeOpList endCode[] = { { OP_AddImm, 1, 0, 0}, /* 0 */ - { OP_If, 1, 4, 0}, /* 1 */ + { OP_IfNotZero, 1, 4, 0}, /* 1 */ { OP_String8, 0, 3, 0}, /* 2 */ { OP_ResultRow, 3, 1, 0}, /* 3 */ }; @@ -1639,7 +1633,7 @@ void sqlite3Pragma( aOp = sqlite3VdbeAddOpList(v, ArraySize(endCode), endCode, iLn); if( aOp ){ - aOp[0].p2 = -mxErr; + aOp[0].p2 = 1-mxErr; aOp[2].p4type = P4_STATIC; aOp[2].p4.z = "ok"; } diff --git a/src/vdbe.c b/src/vdbe.c index 97aa519df1..fabe98ae57 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -5611,7 +5611,7 @@ case OP_DropTrigger: { ** register P1 the text of an error message describing any problems. ** If no problems are found, store a NULL in register P1. ** -** The register P3 contains the maximum number of allowed errors. +** The register P3 contains one less than the maximum number of allowed errors. ** At most reg(P3) errors will be reported. ** In other words, the analysis stops as soon as reg(P1) errors are ** seen. Reg(P1) is updated with the number of errors remaining. @@ -5644,14 +5644,14 @@ case OP_IntegrityCk: { assert( pOp->p5nDb ); assert( DbMaskTest(p->btreeMask, pOp->p5) ); z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p5].pBt, aRoot, nRoot, - (int)pnErr->u.i, &nErr); - pnErr->u.i -= nErr; + (int)pnErr->u.i+1, &nErr); sqlite3VdbeMemSetNull(pIn1); if( nErr==0 ){ assert( z==0 ); }else if( z==0 ){ goto no_mem; }else{ + pnErr->u.i -= nErr-1; sqlite3VdbeMemSetStr(pIn1, z, -1, SQLITE_UTF8, sqlite3_free); } UPDATE_MAX_BLOBSIZE(pIn1); From bd1d270ec9909d48c8e5b14ee03be6600877fa9c Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 22 Feb 2017 19:27:51 +0000 Subject: [PATCH 1364/1484] Improve the performance of ANALYZE when SQLITE_ENABLE_STAT4 is defined. FossilOrigin-Name: 737a82444065752785c643b1d29ca097c828effb --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/analyze.c | 24 +++++++++++++++++++++--- 3 files changed, 29 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 061f9eb07e..5a5647725b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improvements\sto\sPRAGMA\sintegrity_check.\nVerify\sCHECK\sconstraints.\nVerify\sNOT\sNULL\sconstraints\seven\son\stable\sthat\slack\sindexes.\nVerify\sCHECK\sand\sNOT\sNULL\sconstraints\swith\sPRAGMA\squick_check. -D 2017-02-22T18:53:13.913 +C Improve\sthe\sperformance\sof\sANALYZE\swhen\sSQLITE_ENABLE_STAT4\sis\sdefined. +D 2017-02-22T19:27:51.768 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 @@ -332,7 +332,7 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F src/alter.c 3b23977620ce9662ac54443f65b87ba996e36121 -F src/analyze.c ac7a5d7e3cee07d074697904e00e4a8ab7b2b4f5 +F src/analyze.c 844359e720d1116592234f2f7938432bdc5b6238 F src/attach.c 8c476f8bd5d2afe11d925f890d30e527e5b0ce43 F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792 F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b @@ -1557,7 +1557,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 80adc0cb4ed7bacc54b15ac8b5b205403939c8c4 5af7d72ed9ec758283d78ceb46627d72021c1c60 -R 46f90a15a015e3c65c6378dae6f8ff19 -U drh -Z 9fac49478b578adef606b235c8c223db +P aa02bd3c95e374008b930d296c88dfafaf11c65a +R 767bcf2e23bb391de45c0ed55772662f +U dan +Z 11a6abc8e262f46553fa08a6e318d405 diff --git a/manifest.uuid b/manifest.uuid index f457c0397d..cfc91dee69 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -aa02bd3c95e374008b930d296c88dfafaf11c65a \ No newline at end of file +737a82444065752785c643b1d29ca097c828effb \ No newline at end of file diff --git a/src/analyze.c b/src/analyze.c index 890ae7c3b2..79c27d06ab 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -290,6 +290,7 @@ struct Stat4Accum { Stat4Sample *aBest; /* Array of nCol best samples */ int iMin; /* Index in a[] of entry with minimum score */ int nSample; /* Current number of samples */ + int nMaxEqZero; /* Max leading 0 in anEq[] for any a[] entry */ int iGet; /* Index of current sample accessed by stat_get() */ Stat4Sample *a; /* Array of mxSample Stat4Sample objects */ sqlite3 *db; /* Database connection, for malloc() */ @@ -551,7 +552,14 @@ static void sampleInsert(Stat4Accum *p, Stat4Sample *pNew, int nEqZero){ Stat4Sample *pSample = 0; int i; + /* Stat4Accum.nMaxEqZero is set to the maximum number of leading 0 + ** values in the anEq[] array of any sample in Stat4Accum.a[]. In + ** other words, if nMaxEqZero is n, then it is guaranteed that there + ** are no samples with Stat4Sample.anEq[m]==0 for (m>=n). */ assert( IsStat4 || nEqZero==0 ); + if( nEqZero>p->nMaxEqZero ){ + p->nMaxEqZero = nEqZero; + } #ifdef SQLITE_ENABLE_STAT4 if( pNew->isPSample==0 ){ @@ -651,12 +659,22 @@ static void samplePushPrevious(Stat4Accum *p, int iChng){ } } - /* Update the anEq[] fields of any samples already collected. */ + /* Check that no sample contains an anEq[] entry with an index of + ** p->nMaxEqZero or greater set to zero. */ for(i=p->nSample-1; i>=0; i--){ int j; - for(j=iChng; jnCol; j++){ - if( p->a[i].anEq[j]==0 ) p->a[i].anEq[j] = p->current.anEq[j]; + for(j=p->nMaxEqZero; jnCol; j++) assert( p->a[i].anEq[j]>0 ); + } + + /* Update the anEq[] fields of any samples already collected. */ + if( iChngnMaxEqZero ){ + for(i=p->nSample-1; i>=0; i--){ + int j; + for(j=iChng; jnCol; j++){ + if( p->a[i].anEq[j]==0 ) p->a[i].anEq[j] = p->current.anEq[j]; + } } + p->nMaxEqZero = iChng; } #endif From 24d772cc277cf831ef890495e72c2c9000137b5c Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 22 Feb 2017 19:41:16 +0000 Subject: [PATCH 1365/1484] Move a branch condition in analyze.c inside an #ifdef SQLITE_ENABLE_STAT4 block. FossilOrigin-Name: d6afd98de3ee8b714dfd6477ead955096f623972 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/analyze.c | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 5a5647725b..7980c45c8d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improve\sthe\sperformance\sof\sANALYZE\swhen\sSQLITE_ENABLE_STAT4\sis\sdefined. -D 2017-02-22T19:27:51.768 +C Move\sa\sbranch\scondition\sin\sanalyze.c\sinside\san\s#ifdef\sSQLITE_ENABLE_STAT4\sblock. +D 2017-02-22T19:41:16.947 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 @@ -332,7 +332,7 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F src/alter.c 3b23977620ce9662ac54443f65b87ba996e36121 -F src/analyze.c 844359e720d1116592234f2f7938432bdc5b6238 +F src/analyze.c 8a2af8a16e4d95ec2327d3f180cb0bab4b2074c1 F src/attach.c 8c476f8bd5d2afe11d925f890d30e527e5b0ce43 F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792 F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b @@ -1557,7 +1557,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P aa02bd3c95e374008b930d296c88dfafaf11c65a -R 767bcf2e23bb391de45c0ed55772662f +P 737a82444065752785c643b1d29ca097c828effb +R 36d1036d6c004868a4b3899253e892b2 U dan -Z 11a6abc8e262f46553fa08a6e318d405 +Z b9298378d570f055da46d519ad41197c diff --git a/manifest.uuid b/manifest.uuid index cfc91dee69..69e4a7f8b9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -737a82444065752785c643b1d29ca097c828effb \ No newline at end of file +d6afd98de3ee8b714dfd6477ead955096f623972 \ No newline at end of file diff --git a/src/analyze.c b/src/analyze.c index 79c27d06ab..098b6c7e37 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -552,16 +552,16 @@ static void sampleInsert(Stat4Accum *p, Stat4Sample *pNew, int nEqZero){ Stat4Sample *pSample = 0; int i; + assert( IsStat4 || nEqZero==0 ); + +#ifdef SQLITE_ENABLE_STAT4 /* Stat4Accum.nMaxEqZero is set to the maximum number of leading 0 ** values in the anEq[] array of any sample in Stat4Accum.a[]. In ** other words, if nMaxEqZero is n, then it is guaranteed that there ** are no samples with Stat4Sample.anEq[m]==0 for (m>=n). */ - assert( IsStat4 || nEqZero==0 ); if( nEqZero>p->nMaxEqZero ){ p->nMaxEqZero = nEqZero; } - -#ifdef SQLITE_ENABLE_STAT4 if( pNew->isPSample==0 ){ Stat4Sample *pUpgrade = 0; assert( pNew->anEq[pNew->iCol]>0 ); From 2ead47cb49d28ead0ea67825bc66a5c360867201 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 22 Feb 2017 20:24:10 +0000 Subject: [PATCH 1366/1484] Change the name of the analyze_as_needed pragma to "optimize". Enhance the comment (which will become documentation, assuming these changes land on trunk) to explain that the optimize pragma is likely to be enhanced in various ways in future releases and that applications should not depend upon the current behavior. FossilOrigin-Name: 9fced545a6f80c55d6dc4a6106cb2d3569566b3e --- manifest | 16 +++++------ manifest.uuid | 2 +- src/pragma.c | 30 ++++++++++++++++----- src/pragma.h | 64 +++++++++++++++++++++++--------------------- tool/mkpragmatab.tcl | 2 +- 5 files changed, 66 insertions(+), 48 deletions(-) diff --git a/manifest b/manifest index 392b3afc29..508790c7bd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sintegrity_check\sand\sother\simprovements\sfrom\strunk. -D 2017-02-22T19:49:54.795 +C Change\sthe\sname\sof\sthe\sanalyze_as_needed\spragma\sto\s"optimize".\s\sEnhance\sthe\ncomment\s(which\swill\sbecome\sdocumentation,\sassuming\sthese\schanges\sland\son\strunk)\nto\sexplain\sthat\sthe\soptimize\spragma\sis\slikely\sto\sbe\senhanced\sin\svarious\sways\nin\sfuture\sreleases\sand\sthat\sapplications\sshould\snot\sdepend\supon\sthe\scurrent\nbehavior. +D 2017-02-22T20:24:10.705 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 @@ -388,8 +388,8 @@ F src/parse.y af8830094f4aecb91cb69721f3601ad10c36abc4 F src/pcache.c 62835bed959e2914edd26afadfecce29ece0e870 F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 F src/pcache1.c e3967219b2a92b9edcb9324a4ba75009090d3953 -F src/pragma.c 97742aae32e645926f6f8fc426169fb5ef97c268 -F src/pragma.h 065e184494f12e94111da1ab6984faa7b6142e68 +F src/pragma.c 46202f2f5ee6957ff5cba581ee3c36507685def0 +F src/pragma.h d97dd835c7f4dfb6857487707313385d44fa76c0 F src/prepare.c b1140c3d0cf59bc85ace00ce363153041b424b7a F src/printf.c 67427bbee66d891fc6f6f5aada857e9cdb368c1c F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 @@ -1496,7 +1496,7 @@ F tool/mkmsvcmin.tcl 95b37e202cbed873aa8ffdbb493b9db45927be2b F tool/mkopcodec.tcl d1b6362bd3aa80d5520d4d6f3765badf01f6c43c F tool/mkopcodeh.tcl a01d2c1d8a6205b03fc635adf3735b4c523befd3 F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e -F tool/mkpragmatab.tcl 6fd5ecb4a8debee39e3bb4e63f0634f69edfb861 +F tool/mkpragmatab.tcl 9b499f7301fadeddeae52b95f962ef7e5a718f50 F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 F tool/mksqlite3c-noext.tcl fef88397668ae83166735c41af99d79f56afaabb F tool/mksqlite3c.tcl 06b2e6a0f21cc0a5d70fbbd136b3e0a96470645e @@ -1558,7 +1558,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ff213f2ef5bf96754a2264685d25546d8b5ccf0a d6afd98de3ee8b714dfd6477ead955096f623972 -R c12096fa1c0a2878a437d029e47aff9d +P fe073905081b421405ca425ca03c5b8b0ff5f2c8 +R b1ce2ff126387ffc06c8537ddbfa9731 U drh -Z 3c7beae38049bf1fe67e75122f4d0189 +Z 5165d34a54df32aa272e95c6a5e5953c diff --git a/manifest.uuid b/manifest.uuid index 54b7ffb813..8e0845a1c4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fe073905081b421405ca425ca03c5b8b0ff5f2c8 \ No newline at end of file +9fced545a6f80c55d6dc4a6106cb2d3569566b3e \ No newline at end of file diff --git a/src/pragma.c b/src/pragma.c index 7ff76d02d1..714fb413b6 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -1863,16 +1863,29 @@ void sqlite3Pragma( } /* - ** PRAGMA analyze_as_needed - ** PRAGMA schema.analyze_as_needed + ** PRAGMA optimize + ** PRAGMA schema.optimize ** - ** This pragma runs ANALYZE on any tables which would have benefitted - ** from having recent statistics at some point since the start of the - ** current connection. Only tables in "schema" are analyzed in the + ** Attempt to optimize the database. All schemas are optimized in the first + ** form, and only the specified schema is optimized in the second form. + ** + ** The details of optimizations performed by this pragma does are expected + ** to change and improve over time. Applications should anticipate that + ** this pragma will perform new optimizations in future releases. + ** + ** Argments to this pragma are currently ignored, but future enhancements + ** might make use of arguments to control which optimizations are allowed + ** or to suggest limits on how much CPU time and I/O should be expended + ** in the optimization effort. + ** + ** The current implementation runs ANALYZE on any tables which might have + ** benefitted from having recent statistics at some point since the start + ** of the current connection. Only tables in "schema" are analyzed in the ** second form. In the first form, all tables except TEMP tables are ** checked. ** - ** A table is analyzed only if both of the following are true: + ** In the current implementation, a table is analyzed only if both of + ** the following are true: ** ** (1) The query planner used sqlite_stat1-style statistics for one or ** more indexes of the table at some point during the lifetime of @@ -1881,8 +1894,11 @@ void sqlite3Pragma( ** (2) One or more indexes of the table are currently unanalyzed OR ** the number of rows in the table has increased by 25 times or more ** since the last time ANALYZE was run. + ** + ** The rules for when tables are analyzed are likely to change in + ** future releases. */ - case PragTyp_ANALYZE_AS_NEEDED: { + case PragTyp_OPTIMIZE: { int iDbLast; /* Loop termination point for the schema loop */ int iTabCur; /* Cursor for a table whose size needs checking */ HashElem *k; /* Loop over tables of a schema */ diff --git a/src/pragma.h b/src/pragma.h index ba107ec07e..363975df55 100644 --- a/src/pragma.h +++ b/src/pragma.h @@ -5,32 +5,32 @@ */ /* The various pragma types */ -#define PragTyp_ANALYZE_AS_NEEDED 0 -#define PragTyp_HEADER_VALUE 1 -#define PragTyp_AUTO_VACUUM 2 -#define PragTyp_FLAG 3 -#define PragTyp_BUSY_TIMEOUT 4 -#define PragTyp_CACHE_SIZE 5 -#define PragTyp_CACHE_SPILL 6 -#define PragTyp_CASE_SENSITIVE_LIKE 7 -#define PragTyp_COLLATION_LIST 8 -#define PragTyp_COMPILE_OPTIONS 9 -#define PragTyp_DATA_STORE_DIRECTORY 10 -#define PragTyp_DATABASE_LIST 11 -#define PragTyp_DEFAULT_CACHE_SIZE 12 -#define PragTyp_ENCODING 13 -#define PragTyp_FOREIGN_KEY_CHECK 14 -#define PragTyp_FOREIGN_KEY_LIST 15 -#define PragTyp_INCREMENTAL_VACUUM 16 -#define PragTyp_INDEX_INFO 17 -#define PragTyp_INDEX_LIST 18 -#define PragTyp_INTEGRITY_CHECK 19 -#define PragTyp_JOURNAL_MODE 20 -#define PragTyp_JOURNAL_SIZE_LIMIT 21 -#define PragTyp_LOCK_PROXY_FILE 22 -#define PragTyp_LOCKING_MODE 23 -#define PragTyp_PAGE_COUNT 24 -#define PragTyp_MMAP_SIZE 25 +#define PragTyp_HEADER_VALUE 0 +#define PragTyp_AUTO_VACUUM 1 +#define PragTyp_FLAG 2 +#define PragTyp_BUSY_TIMEOUT 3 +#define PragTyp_CACHE_SIZE 4 +#define PragTyp_CACHE_SPILL 5 +#define PragTyp_CASE_SENSITIVE_LIKE 6 +#define PragTyp_COLLATION_LIST 7 +#define PragTyp_COMPILE_OPTIONS 8 +#define PragTyp_DATA_STORE_DIRECTORY 9 +#define PragTyp_DATABASE_LIST 10 +#define PragTyp_DEFAULT_CACHE_SIZE 11 +#define PragTyp_ENCODING 12 +#define PragTyp_FOREIGN_KEY_CHECK 13 +#define PragTyp_FOREIGN_KEY_LIST 14 +#define PragTyp_INCREMENTAL_VACUUM 15 +#define PragTyp_INDEX_INFO 16 +#define PragTyp_INDEX_LIST 17 +#define PragTyp_INTEGRITY_CHECK 18 +#define PragTyp_JOURNAL_MODE 19 +#define PragTyp_JOURNAL_SIZE_LIMIT 20 +#define PragTyp_LOCK_PROXY_FILE 21 +#define PragTyp_LOCKING_MODE 22 +#define PragTyp_PAGE_COUNT 23 +#define PragTyp_MMAP_SIZE 24 +#define PragTyp_OPTIMIZE 25 #define PragTyp_PAGE_SIZE 26 #define PragTyp_SECURE_DELETE 27 #define PragTyp_SHRINK_MEMORY 28 @@ -133,11 +133,6 @@ static const PragmaName aPragmaName[] = { /* ColNames: */ 0, 0, /* iArg: */ 0 }, #endif - {/* zName: */ "analyze_as_needed", - /* ePragTyp: */ PragTyp_ANALYZE_AS_NEEDED, - /* ePragFlg: */ PragFlg_NoColumns, - /* ColNames: */ 0, 0, - /* iArg: */ 0 }, #if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) {/* zName: */ "application_id", /* ePragTyp: */ PragTyp_HEADER_VALUE, @@ -419,6 +414,13 @@ static const PragmaName aPragmaName[] = { /* ePragFlg: */ 0, /* ColNames: */ 0, 0, /* iArg: */ 0 }, +#endif + {/* zName: */ "optimize", + /* ePragTyp: */ PragTyp_OPTIMIZE, + /* ePragFlg: */ PragFlg_NoColumns, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) {/* zName: */ "page_count", /* ePragTyp: */ PragTyp_PAGE_COUNT, /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq, diff --git a/tool/mkpragmatab.tcl b/tool/mkpragmatab.tcl index 2201ea1306..f0ba49b545 100644 --- a/tool/mkpragmatab.tcl +++ b/tool/mkpragmatab.tcl @@ -362,7 +362,7 @@ set pragma_def { NAME: threads FLAG: Result0 - NAME: analyze_as_needed + NAME: optimize FLAG: NoColumns } From bce0414844b9ed5a99c6c2462a92d6db095b9bf2 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 23 Feb 2017 00:58:36 +0000 Subject: [PATCH 1367/1484] Do a single OP_Expire at the very end of "PRAGMA optimize", and omit the OP_Expire on ANALYZE commands invoked by the pragma. FossilOrigin-Name: 188300a337c87b7ee0dd1f4b9a4f1bd80e70cca4 --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/analyze.c | 30 +++++++++--------------------- src/pragma.c | 1 + src/sqliteInt.h | 1 + src/vdbe.c | 2 ++ 6 files changed, 23 insertions(+), 31 deletions(-) diff --git a/manifest b/manifest index 508790c7bd..9a9acb5caa 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sthe\sname\sof\sthe\sanalyze_as_needed\spragma\sto\s"optimize".\s\sEnhance\sthe\ncomment\s(which\swill\sbecome\sdocumentation,\sassuming\sthese\schanges\sland\son\strunk)\nto\sexplain\sthat\sthe\soptimize\spragma\sis\slikely\sto\sbe\senhanced\sin\svarious\sways\nin\sfuture\sreleases\sand\sthat\sapplications\sshould\snot\sdepend\supon\sthe\scurrent\nbehavior. -D 2017-02-22T20:24:10.705 +C Do\sa\ssingle\sOP_Expire\sat\sthe\svery\send\sof\s"PRAGMA\soptimize",\sand\somit\sthe\nOP_Expire\son\sANALYZE\scommands\sinvoked\sby\sthe\spragma. +D 2017-02-23T00:58:36.868 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 @@ -332,7 +332,7 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F src/alter.c 3b23977620ce9662ac54443f65b87ba996e36121 -F src/analyze.c b4857ec5b46b66049e5a3cec53c071c4902a8e8b +F src/analyze.c 6d8234916c29be943e6ea28b5bef67dff98d9905 F src/attach.c 8c476f8bd5d2afe11d925f890d30e527e5b0ce43 F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792 F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b @@ -388,7 +388,7 @@ F src/parse.y af8830094f4aecb91cb69721f3601ad10c36abc4 F src/pcache.c 62835bed959e2914edd26afadfecce29ece0e870 F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 F src/pcache1.c e3967219b2a92b9edcb9324a4ba75009090d3953 -F src/pragma.c 46202f2f5ee6957ff5cba581ee3c36507685def0 +F src/pragma.c 4b32b014bb4b460bbf0103e4631809428c1ce16b F src/pragma.h d97dd835c7f4dfb6857487707313385d44fa76c0 F src/prepare.c b1140c3d0cf59bc85ace00ce363153041b424b7a F src/printf.c 67427bbee66d891fc6f6f5aada857e9cdb368c1c @@ -400,7 +400,7 @@ F src/shell.c bf976d5301be9d8a4c52852c97909cc9a41ee20d F src/sqlite.h.in 751ff125eb159c8f92c182b8df980a5e4f50e966 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae -F src/sqliteInt.h bdc181e371ea618c85f30b4c5ee4d80f4ada6ad7 +F src/sqliteInt.h df268ce1d04df042cf43b557d2309eb0b71e86c4 F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 @@ -462,7 +462,7 @@ F src/update.c 456d4a4656f8a03c2abc88a51b19172197400e58 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c ca8440ede81e155d15cff7c101654f60b55a9ae6 F src/vacuum.c 1fe4555cd8c9b263afb85b5b4ee3a4a4181ad569 -F src/vdbe.c 37e95d52675bd839cc6c209f6b8d907582a27d44 +F src/vdbe.c f520378e510fd36bbf289921798dbc8f2b3dc30d F src/vdbe.h 59998ffd71d7caa8886bc78dafaf8caeccd4c13c F src/vdbeInt.h 4e4b15b2e1330e1636e4e01974eab2b0b985092f F src/vdbeapi.c 3e4a8893feeb78620f4aac4ac5b85d92255b97e1 @@ -1558,7 +1558,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P fe073905081b421405ca425ca03c5b8b0ff5f2c8 -R b1ce2ff126387ffc06c8537ddbfa9731 +P 9fced545a6f80c55d6dc4a6106cb2d3569566b3e +R 5ab35d2cee04a5e705af62d3884bb598 U drh -Z 5165d34a54df32aa272e95c6a5e5953c +Z d17aa4a4e286313b851b7686a8b74646 diff --git a/manifest.uuid b/manifest.uuid index 8e0845a1c4..7b7c25203c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9fced545a6f80c55d6dc4a6106cb2d3569566b3e \ No newline at end of file +188300a337c87b7ee0dd1f4b9a4f1bd80e70cca4 \ No newline at end of file diff --git a/src/analyze.c b/src/analyze.c index a9893826e2..d1df000943 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -1388,27 +1388,14 @@ void sqlite3Analyze(Parse *pParse, Token *pName1, Token *pName2){ if( i==1 ) continue; /* Do not analyze the TEMP database */ analyzeDatabase(pParse, i); } - }else if( pName2->n==0 ){ - /* Form 2: Analyze the database or table named */ - iDb = sqlite3FindDb(db, pName1); - if( iDb>=0 ){ - analyzeDatabase(pParse, iDb); - }else{ - z = sqlite3NameFromToken(db, pName1); - if( z ){ - if( (pIdx = sqlite3FindIndex(db, z, 0))!=0 ){ - analyzeTable(pParse, pIdx->pTable, pIdx); - }else if( (pTab = sqlite3LocateTable(pParse, 0, z, 0))!=0 ){ - analyzeTable(pParse, pTab, 0); - } - sqlite3DbFree(db, z); - } - } + }else if( pName2->n==0 && (iDb = sqlite3FindDb(db, pName1))>=0 ){ + /* Analyze the schema named as the argument */ + analyzeDatabase(pParse, iDb); }else{ - /* Form 3: Analyze the fully qualified table name */ + /* Form 3: Analyze the table or index named as an argument */ iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pTableName); if( iDb>=0 ){ - zDb = db->aDb[iDb].zDbSName; + zDb = pName2->n ? db->aDb[iDb].zDbSName : 0; z = sqlite3NameFromToken(db, pTableName); if( z ){ if( (pIdx = sqlite3FindIndex(db, z, zDb))!=0 ){ @@ -1418,10 +1405,11 @@ void sqlite3Analyze(Parse *pParse, Token *pName1, Token *pName2){ } sqlite3DbFree(db, z); } - } + } + } + if( db->nSqlExec==0 && (v = sqlite3GetVdbe(pParse))!=0 ){ + sqlite3VdbeAddOp0(v, OP_Expire); } - v = sqlite3GetVdbe(pParse); - if( v ) sqlite3VdbeAddOp0(v, OP_Expire); } /* diff --git a/src/pragma.c b/src/pragma.c index 714fb413b6..916ed4aa57 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -1940,6 +1940,7 @@ void sqlite3Pragma( sqlite3VdbeAddOp4(v, OP_SqlExec, 0, 0, 0, zSubSql, P4_DYNAMIC); } } + sqlite3VdbeAddOp0(v, OP_Expire); break; } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index fddfe2a57f..e95d63ec35 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1333,6 +1333,7 @@ struct sqlite3 { u8 isTransactionSavepoint; /* True if the outermost savepoint is a TS */ u8 mTrace; /* zero or more SQLITE_TRACE flags */ u8 skipBtreeMutex; /* True if no shared-cache backends */ + u8 nSqlExec; /* Number of pending OP_SqlExec opcodes */ int nextPagesize; /* Pagesize after VACUUM if >0 */ u32 magic; /* Magic number for detect library misuse */ int nChange; /* Value returned by sqlite3_changes() */ diff --git a/src/vdbe.c b/src/vdbe.c index 59e401937f..5901ba0eb5 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -5523,7 +5523,9 @@ case OP_CreateTable: { /* out2 */ ** Run the SQL statement or statements specified in the P4 string. */ case OP_SqlExec: { + db->nSqlExec++; rc = sqlite3_exec(db, pOp->p4.z, 0, 0, 0); + db->nSqlExec--; if( rc ) goto abort_due_to_error; break; } From 555227bec07e99dddb8b9113d329e48caeba5131 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 23 Feb 2017 02:15:33 +0000 Subject: [PATCH 1368/1484] Add two NEVER() operators in the sqlite3BtreeRowCountEst() routine. FossilOrigin-Name: 7a959f6d1ea038988cdb4c02d6f37abaec2580a0 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btree.c | 9 +++++++-- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 9a9acb5caa..39c4d8e77a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Do\sa\ssingle\sOP_Expire\sat\sthe\svery\send\sof\s"PRAGMA\soptimize",\sand\somit\sthe\nOP_Expire\son\sANALYZE\scommands\sinvoked\sby\sthe\spragma. -D 2017-02-23T00:58:36.868 +C Add\stwo\sNEVER()\soperators\sin\sthe\ssqlite3BtreeRowCountEst()\sroutine. +D 2017-02-23T02:15:33.201 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 @@ -338,7 +338,7 @@ F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792 F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca -F src/btree.c a4ab1fb5cdeea88c4f76216e41cfecfa505c8c43 +F src/btree.c 19746a7db19308053ff6cb2ac002834822809e54 F src/btree.h bf64dfeeddeebdb775a5eba0098bbc00d073290d F src/btreeInt.h cd55d39d9916270837a88c12e701047cba0729b0 F src/build.c 43f903c9082040ced2b421543cb0300c2973647d @@ -1558,7 +1558,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 9fced545a6f80c55d6dc4a6106cb2d3569566b3e -R 5ab35d2cee04a5e705af62d3884bb598 +P 188300a337c87b7ee0dd1f4b9a4f1bd80e70cca4 +R ea4c0d1070247cd8f7e1aa7ed210345c U drh -Z d17aa4a4e286313b851b7686a8b74646 +Z 01ff8d763fbc7e4c3e39020edd5b116b diff --git a/manifest.uuid b/manifest.uuid index 7b7c25203c..1e1b04c82c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -188300a337c87b7ee0dd1f4b9a4f1bd80e70cca4 \ No newline at end of file +7a959f6d1ea038988cdb4c02d6f37abaec2580a0 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 4d31661f10..788a2d4d03 100644 --- a/src/btree.c +++ b/src/btree.c @@ -5330,8 +5330,13 @@ i64 sqlite3BtreeRowCountEst(BtCursor *pCur){ assert( cursorOwnsBtShared(pCur) ); assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); - if( pCur->eState!=CURSOR_VALID ) return -1; - if( pCur->apPage[pCur->iPage]->leaf==0 ) return -1; + + /* Currently this interface is only called by the OP_IfSmaller + ** opcode, and it that case the cursor will always be valid and + ** will always point to a leaf node. */ + if( NEVER(pCur->eState!=CURSOR_VALID) ) return -1; + if( NEVER(pCur->apPage[pCur->iPage]->leaf==0) ) return -1; + for(n=1, i=0; i<=pCur->iPage; i++){ n *= pCur->apPage[i]->nCell; } From bda4cb876c9636d67a04781aac795b07a39ae965 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 23 Feb 2017 16:30:16 +0000 Subject: [PATCH 1369/1484] Save a few bytes and a few cycles by setting Vdbe.expmask to zero for statements prepared using legacy interface sqlite3_prepare(). FossilOrigin-Name: a8fd705258643863493476f8b42ee981608a339f --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/vdbeapi.c | 14 ++++++++------ src/vdbeaux.c | 1 + 4 files changed, 17 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index 7980c45c8d..c20fd94d76 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Move\sa\sbranch\scondition\sin\sanalyze.c\sinside\san\s#ifdef\sSQLITE_ENABLE_STAT4\sblock. -D 2017-02-22T19:41:16.947 +C Save\sa\sfew\sbytes\sand\sa\sfew\scycles\sby\ssetting\sVdbe.expmask\sto\szero\sfor\nstatements\sprepared\susing\slegacy\sinterface\ssqlite3_prepare(). +D 2017-02-23T16:30:16.521 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 @@ -465,8 +465,8 @@ F src/vacuum.c 1fe4555cd8c9b263afb85b5b4ee3a4a4181ad569 F src/vdbe.c 83f387d9e6842b1dc99f6e85bb577c5bbc4e397d F src/vdbe.h 59998ffd71d7caa8886bc78dafaf8caeccd4c13c F src/vdbeInt.h 4e4b15b2e1330e1636e4e01974eab2b0b985092f -F src/vdbeapi.c 3e4a8893feeb78620f4aac4ac5b85d92255b97e1 -F src/vdbeaux.c 2f48204a0f2875b098ee046bba9265907297b0b5 +F src/vdbeapi.c 70aabe108c411e529a59d8800445513965334062 +F src/vdbeaux.c 031422c66e272c7f1027070e7f0858f4c418dfbc F src/vdbeblob.c 359891617358deefc85bef7bcf787fa6b77facb9 F src/vdbemem.c 3b5a9a5b375458d3e12a50ae1aaa41eeec2175fd F src/vdbesort.c eda25cb2d1727efca6f7862fea32b8aa33c0face @@ -1557,7 +1557,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 737a82444065752785c643b1d29ca097c828effb -R 36d1036d6c004868a4b3899253e892b2 +P d6afd98de3ee8b714dfd6477ead955096f623972 +R d82d78a185c578681c4bad1233af7bd3 U dan -Z b9298378d570f055da46d519ad41197c +Z 013ae364526d4d7cd1569b7a9709f5c0 diff --git a/manifest.uuid b/manifest.uuid index 69e4a7f8b9..36ee9348a9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d6afd98de3ee8b714dfd6477ead955096f623972 \ No newline at end of file +a8fd705258643863493476f8b42ee981608a339f \ No newline at end of file diff --git a/src/vdbeapi.c b/src/vdbeapi.c index 6eb97f1d1d..3d9bcca99f 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -154,7 +154,8 @@ int sqlite3_clear_bindings(sqlite3_stmt *pStmt){ sqlite3VdbeMemRelease(&p->aVar[i]); p->aVar[i].flags = MEM_Null; } - if( p->isPrepareV2 && p->expmask ){ + assert( p->isPrepareV2 || p->expmask==0 ); + if( p->expmask ){ p->expired = 1; } sqlite3_mutex_leave(mutex); @@ -1258,9 +1259,8 @@ static int vdbeUnbind(Vdbe *p, int i){ ** as if there had been a schema change, on the first sqlite3_step() call ** following any change to the bindings of that parameter. */ - if( p->isPrepareV2 && - ((i<32 && p->expmask & ((u32)1 << i)) || p->expmask==0xffffffff) - ){ + assert( p->isPrepareV2 || p->expmask==0 ); + if( p->expmask & ((u32)1 << (i&0x001F)) && (i<32 || p->expmask==0xffffffff) ){ p->expired = 1; } return SQLITE_OK; @@ -1523,10 +1523,12 @@ int sqlite3_transfer_bindings(sqlite3_stmt *pFromStmt, sqlite3_stmt *pToStmt){ if( pFrom->nVar!=pTo->nVar ){ return SQLITE_ERROR; } - if( pTo->isPrepareV2 && pTo->expmask ){ + assert( pTo->isPrepareV2 || pTo->expmask==0 ); + if( pTo->expmask ){ pTo->expired = 1; } - if( pFrom->isPrepareV2 && pFrom->expmask ){ + assert( pFrom->isPrepareV2 || pFrom->expmask==0 ); + if( pFrom->expmask ){ pFrom->expired = 1; } return sqlite3TransferBindings(pFromStmt, pToStmt); diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 292ff2bdd2..67e0f63ef6 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -57,6 +57,7 @@ void sqlite3VdbeError(Vdbe *p, const char *zFormat, ...){ void sqlite3VdbeSetSql(Vdbe *p, const char *z, int n, int isPrepareV2){ assert( isPrepareV2==1 || isPrepareV2==0 ); if( p==0 ) return; + if( !isPrepareV2 ) p->expmask = 0; #if defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_ENABLE_SQLLOG) if( !isPrepareV2 ) return; #endif From e6d065a81e6bd7be15c778c3a103d94bf1ad3e0f Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 24 Feb 2017 19:58:22 +0000 Subject: [PATCH 1370/1484] Optimize defragmentPage() in the case where the page contains either one or two free-blocks and a small number of fragmented bytes. FossilOrigin-Name: 202b1c0276aec6b8da64d3277de1ad91c9d62d80 --- manifest | 15 ++++++++----- manifest.uuid | 2 +- src/btree.c | 62 ++++++++++++++++++++++++++++++++++++++++----------- 3 files changed, 59 insertions(+), 20 deletions(-) diff --git a/manifest b/manifest index c20fd94d76..77cbf1aa41 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Save\sa\sfew\sbytes\sand\sa\sfew\scycles\sby\ssetting\sVdbe.expmask\sto\szero\sfor\nstatements\sprepared\susing\slegacy\sinterface\ssqlite3_prepare(). -D 2017-02-23T16:30:16.521 +C Optimize\sdefragmentPage()\sin\sthe\scase\swhere\sthe\spage\scontains\seither\sone\sor\ntwo\sfree-blocks\sand\sa\ssmall\snumber\sof\sfragmented\sbytes. +D 2017-02-24T19:58:22.394 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 @@ -338,7 +338,7 @@ F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792 F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca -F src/btree.c 3ae66974881e74df9909093818b4c3428f8d7982 +F src/btree.c 1763e0ec3a6cbda48d3a5cb5a7451e46fbc8784d F src/btree.h e6d352808956ec163a17f832193a3e198b3fb0ac F src/btreeInt.h cd55d39d9916270837a88c12e701047cba0729b0 F src/build.c 51b473eec465f471d607b54e8dbc00751c3f8a1f @@ -1557,7 +1557,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d6afd98de3ee8b714dfd6477ead955096f623972 -R d82d78a185c578681c4bad1233af7bd3 +P a8fd705258643863493476f8b42ee981608a339f +R c55510e117c3384aa955b9dc66959921 +T *branch * defragmentpage-opt +T *sym-defragmentpage-opt * +T -sym-trunk * U dan -Z 013ae364526d4d7cd1569b7a9709f5c0 +Z a194b2944e8972170f1e898920de81d2 diff --git a/manifest.uuid b/manifest.uuid index 36ee9348a9..6d120aa8df 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a8fd705258643863493476f8b42ee981608a339f \ No newline at end of file +202b1c0276aec6b8da64d3277de1ad91c9d62d80 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index e78ffef1be..6276a850a0 100644 --- a/src/btree.c +++ b/src/btree.c @@ -1317,17 +1317,18 @@ static void ptrmapPutOvflPtr(MemPage *pPage, u8 *pCell, int *pRC){ /* -** Defragment the page given. All Cells are moved to the -** end of the page and all free space is collected into one -** big FreeBlk that occurs in between the header and cell -** pointer array and the cell content area. +** Defragment the page given. This routine reorganizes cells within the +** page so that there are no free-blocks on the free-block list. +** +** Parameter nMaxFrag is the maximum amount of fragmented space that may be +** present in the page after this routine returns. ** ** EVIDENCE-OF: R-44582-60138 SQLite may from time to time reorganize a ** b-tree page so that there are no freeblocks or fragment bytes, all ** unused bytes are contained in the unallocated space region, and all ** cells are packed tightly at the end of the page. */ -static int defragmentPage(MemPage *pPage){ +static int defragmentPage(MemPage *pPage, int nMaxFrag){ int i; /* Loop counter */ int pc; /* Address of the i-th cell */ int hdr; /* Offset to the page header */ @@ -1342,7 +1343,6 @@ static int defragmentPage(MemPage *pPage){ int iCellFirst; /* First allowable cell index */ int iCellLast; /* Last possible cell index */ - assert( sqlite3PagerIswriteable(pPage->pDbPage) ); assert( pPage->pBt!=0 ); assert( pPage->pBt->usableSize <= SQLITE_MAX_PAGE_SIZE ); @@ -1354,10 +1354,44 @@ static int defragmentPage(MemPage *pPage){ cellOffset = pPage->cellOffset; nCell = pPage->nCell; assert( nCell==get2byte(&data[hdr+3]) ); + iCellFirst = cellOffset + 2*nCell; + + /* This block handles pages with two or fewer free blocks and nMaxFrag + ** or fewer fragmented bytes. In this case it is faster to move the + ** two (or one) blocks of cells using memmove() and add the required + ** offsets to each pointer in the cell-pointer array than it is to + ** reconstruct the entire page. */ + if( (int)data[hdr+7]<=nMaxFrag ){ + int iFree = get2byte(&data[hdr+1]); + if( iFree ){ + int iFree2 = get2byte(&data[iFree]); + if( 0==iFree2 || (data[iFree2]==0 && data[iFree2+1]==0) ){ + u8 *pEnd = &data[cellOffset + nCell*2]; + u8 *pAddr; + int sz2 = 0; + int sz = get2byte(&data[iFree+2]); + int top = get2byte(&data[hdr+5]); + if( iFree2 ){ + sz2 = get2byte(&data[iFree2+2]); + memmove(&data[iFree+sz+sz2], &data[iFree+sz], iFree2-(iFree+sz)); + sz += sz2; + } + cbrk = top+sz; + memmove(&data[cbrk], &data[top], iFree-top); + for(pAddr=&data[cellOffset]; pAddrpBt->usableSize; cbrk = usableSize; - iCellFirst = cellOffset + 2*nCell; iCellLast = usableSize - 4; + for(i=0; inFree ){ + return SQLITE_CORRUPT_BKPT; + } + + defragment_out: assert( cbrk>=iCellFirst ); put2byte(&data[hdr+5], cbrk); data[hdr+1] = 0; data[hdr+2] = 0; - data[hdr+7] = 0; memset(&data[iCellFirst], 0, cbrk-iCellFirst); assert( sqlite3PagerIswriteable(pPage->pDbPage) ); - if( cbrk-iCellFirst!=pPage->nFree ){ - return SQLITE_CORRUPT_BKPT; - } return SQLITE_OK; } @@ -1537,7 +1573,7 @@ static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){ testcase( gap+2+nByte==top ); if( gap+2+nByte>top ){ assert( pPage->nCell>0 || CORRUPT_DB ); - rc = defragmentPage(pPage); + rc = defragmentPage(pPage, MIN(4, pPage->nFree - (2+nByte))); if( rc ) return rc; top = get2byteNotZero(&data[hdr+5]); assert( gap+nByte<=top ); @@ -7689,7 +7725,7 @@ static int balance_nonroot( ** free space needs to be up front. */ assert( nNew==1 || CORRUPT_DB ); - rc = defragmentPage(apNew[0]); + rc = defragmentPage(apNew[0], 0); testcase( rc!=SQLITE_OK ); assert( apNew[0]->nFree == (get2byte(&apNew[0]->aData[5])-apNew[0]->cellOffset-apNew[0]->nCell*2) From 3b2ede1f035a86195df4b23c11cd445d6361818e Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 25 Feb 2017 16:24:02 +0000 Subject: [PATCH 1371/1484] Tweak the code on this branch to detect b-tree page corruption in the same cases as the trunk. FossilOrigin-Name: f9863b39d96dce6cb5e49a5f3a445ff3d897a951 --- manifest | 15 ++++++--------- manifest.uuid | 2 +- src/btree.c | 10 +++++----- 3 files changed, 12 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index 77cbf1aa41..c6196d9c48 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Optimize\sdefragmentPage()\sin\sthe\scase\swhere\sthe\spage\scontains\seither\sone\sor\ntwo\sfree-blocks\sand\sa\ssmall\snumber\sof\sfragmented\sbytes. -D 2017-02-24T19:58:22.394 +C Tweak\sthe\scode\son\sthis\sbranch\sto\sdetect\sb-tree\spage\scorruption\sin\sthe\ssame\scases\sas\sthe\strunk. +D 2017-02-25T16:24:02.032 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 @@ -338,7 +338,7 @@ F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792 F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca -F src/btree.c 1763e0ec3a6cbda48d3a5cb5a7451e46fbc8784d +F src/btree.c 03149b0f3fec3c1aa3c50a17e997bb442b867632 F src/btree.h e6d352808956ec163a17f832193a3e198b3fb0ac F src/btreeInt.h cd55d39d9916270837a88c12e701047cba0729b0 F src/build.c 51b473eec465f471d607b54e8dbc00751c3f8a1f @@ -1557,10 +1557,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a8fd705258643863493476f8b42ee981608a339f -R c55510e117c3384aa955b9dc66959921 -T *branch * defragmentpage-opt -T *sym-defragmentpage-opt * -T -sym-trunk * +P 202b1c0276aec6b8da64d3277de1ad91c9d62d80 +R 7a56121f7b6bd4c4a315ae4d10cd07e6 U dan -Z a194b2944e8972170f1e898920de81d2 +Z 0eab51f3ee55bc511deac00d1a02232c diff --git a/manifest.uuid b/manifest.uuid index 6d120aa8df..190b38aa89 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -202b1c0276aec6b8da64d3277de1ad91c9d62d80 \ No newline at end of file +f9863b39d96dce6cb5e49a5f3a445ff3d897a951 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 6276a850a0..bf65852fe6 100644 --- a/src/btree.c +++ b/src/btree.c @@ -1425,11 +1425,11 @@ static int defragmentPage(MemPage *pPage, int nMaxFrag){ memcpy(&data[cbrk], &src[pc], size); } data[hdr+7] = 0; - if( cbrk-iCellFirst!=pPage->nFree ){ - return SQLITE_CORRUPT_BKPT; - } defragment_out: + if( data[hdr+7]+cbrk-iCellFirst!=pPage->nFree ){ + return SQLITE_CORRUPT_BKPT; + } assert( cbrk>=iCellFirst ); put2byte(&data[hdr+5], cbrk); data[hdr+1] = 0; @@ -1576,7 +1576,7 @@ static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){ rc = defragmentPage(pPage, MIN(4, pPage->nFree - (2+nByte))); if( rc ) return rc; top = get2byteNotZero(&data[hdr+5]); - assert( gap+nByte<=top ); + assert( gap+2+nByte<=top ); } @@ -7725,7 +7725,7 @@ static int balance_nonroot( ** free space needs to be up front. */ assert( nNew==1 || CORRUPT_DB ); - rc = defragmentPage(apNew[0], 0); + rc = defragmentPage(apNew[0], -1); testcase( rc!=SQLITE_OK ); assert( apNew[0]->nFree == (get2byte(&apNew[0]->aData[5])-apNew[0]->cellOffset-apNew[0]->nCell*2) From 70cdf382323dcc97c8eacdad658e58739c6adc2d Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 25 Feb 2017 20:57:46 +0000 Subject: [PATCH 1372/1484] Add an 'extern "C"' block to header file sqlite3userauth.h. FossilOrigin-Name: ffd61fb449a510b2fc90caf86b266733051cc365 --- ext/userauth/sqlite3userauth.h | 8 ++++++++ manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/ext/userauth/sqlite3userauth.h b/ext/userauth/sqlite3userauth.h index 619477cac9..c7d23b9399 100644 --- a/ext/userauth/sqlite3userauth.h +++ b/ext/userauth/sqlite3userauth.h @@ -21,6 +21,10 @@ */ #ifdef SQLITE_USER_AUTHENTICATION +#ifdef __cplusplus +extern "C" { +#endif + /* ** If a database contains the SQLITE_USER table, then the ** sqlite3_user_authenticate() interface must be invoked with an @@ -85,4 +89,8 @@ int sqlite3_user_delete( const char *zUsername /* Username to remove */ ); +#ifdef __cplusplus +} /* end of the 'extern "C"' block */ +#endif + #endif /* SQLITE_USER_AUTHENTICATION */ diff --git a/manifest b/manifest index ffaf3dbb28..706934adb3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Optimize\sdefragmentPage()\sin\sthe\scase\swhere\sthe\spage\scontains\seither\sone\sor\ntwo\sfree-blocks\sand\sa\ssmall\snumber\sof\sfragmented\sbytes. -D 2017-02-25T17:47:31.387 +C Add\san\s'extern\s"C"'\sblock\sto\sheader\sfile\ssqlite3userauth.h. +D 2017-02-25T20:57:46.730 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 @@ -313,7 +313,7 @@ F ext/session/sessionwor.test 2f3744236dc8b170a695b7d8ddc8c743c7e79fdc F ext/session/sqlite3session.c 13642d9c754cc18f17e141f82860d269e2adf920 F ext/session/sqlite3session.h d4db650adfcc7a4360e9f12a09c2d117b1db6b53 F ext/session/test_session.c eb0bd6c1ea791c1d66ee4ef94c16500dad936386 -F ext/userauth/sqlite3userauth.h 19cb6f0e31316d0ee4afdfb7a85ef9da3333a220 +F ext/userauth/sqlite3userauth.h 7f3ea8c4686db8e40b0a0e7a8e0b00fac13aa7a3 F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04 F ext/userauth/userauth.c 3410be31283abba70255d71fd24734e017a4497f F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x @@ -1557,7 +1557,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a8fd705258643863493476f8b42ee981608a339f f9863b39d96dce6cb5e49a5f3a445ff3d897a951 -R 7a56121f7b6bd4c4a315ae4d10cd07e6 +P 4cd2a9672c59ea4b3b4cf3d2f139af3c18a8e833 +R 16a6968419b5f6c02a1445afca8164e1 U dan -Z 1f9c94a7513412f3add97a95f1a8ec80 +Z e669ffb28fd5f6d2e359df5fca2d3400 diff --git a/manifest.uuid b/manifest.uuid index 15d62e357c..604dc67407 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4cd2a9672c59ea4b3b4cf3d2f139af3c18a8e833 \ No newline at end of file +ffd61fb449a510b2fc90caf86b266733051cc365 \ No newline at end of file From 2efd3488ba12c6d36763a9ef732647c33c56913c Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 27 Feb 2017 12:23:52 +0000 Subject: [PATCH 1373/1484] Remove references to special handling in virtual table methods from the documentation for sqlite3_last_insert_rowid(). FossilOrigin-Name: 660f9569d76e4ff1f5bd4f37f640e6a4fc2cf87d --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/sqlite.h.in | 10 ++++------ 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 706934adb3..1efcbbbcf0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\san\s'extern\s"C"'\sblock\sto\sheader\sfile\ssqlite3userauth.h. -D 2017-02-25T20:57:46.730 +C Remove\sreferences\sto\sspecial\shandling\sin\svirtual\stable\smethods\sfrom\sthe\ndocumentation\sfor\ssqlite3_last_insert_rowid(). +D 2017-02-27T12:23:52.119 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 @@ -397,7 +397,7 @@ F src/resolve.c f9bc0de45a30a450da47b3766de00be89bf9be79 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c d12f3539f80db38b09015561b569e0eb1c4b6c5f F src/shell.c bf976d5301be9d8a4c52852c97909cc9a41ee20d -F src/sqlite.h.in 751ff125eb159c8f92c182b8df980a5e4f50e966 +F src/sqlite.h.in 154b80d215289fb9b845a6f4f9b67ea4fcf049f8 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae F src/sqliteInt.h a23e18aebdd0d851c2956a74a3a4f12ff202b472 @@ -1557,7 +1557,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 4cd2a9672c59ea4b3b4cf3d2f139af3c18a8e833 -R 16a6968419b5f6c02a1445afca8164e1 +P ffd61fb449a510b2fc90caf86b266733051cc365 +R 8aa5e89f1f59df441ed610ff04b07915 U dan -Z e669ffb28fd5f6d2e359df5fca2d3400 +Z e6ccfdfcae6209cec3abae13f87bf4f8 diff --git a/manifest.uuid b/manifest.uuid index 604dc67407..d173449ff7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ffd61fb449a510b2fc90caf86b266733051cc365 \ No newline at end of file +660f9569d76e4ff1f5bd4f37f640e6a4fc2cf87d \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index eaa75fc249..79b9996848 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -2048,12 +2048,10 @@ int sqlite3_extended_result_codes(sqlite3*, int onoff); ** have ever occurred on the database connection D, ** then sqlite3_last_insert_rowid(D) returns zero. ** -** ^(If an [INSERT] occurs within a trigger or within a [virtual table] -** method, then this routine will return the [rowid] of the inserted -** row as long as the trigger or virtual table method is running. -** But once the trigger or virtual table method ends, the value returned -** by this routine reverts to what it was before the trigger or virtual -** table method began.)^ +** ^(If an [INSERT] occurs within a trigger then this routine will +** return the [rowid] of the inserted row as long as the trigger is +** running. Once the trigger program ends, the value returned +** by this routine reverts to what it was before the trigger was fired.)^ ** ** ^An [INSERT] that fails due to a constraint violation is not a ** successful [INSERT] and does not change the value returned by this From 9c58b63c18938a9bdbcc2f774de45747eec74fbc Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 27 Feb 2017 14:52:48 +0000 Subject: [PATCH 1374/1484] Add an sqlite3_set_last_insert_rowid() method. Use it to work around fts4 and fts5 modifying the last-insert-rowid unintuitively from within commit processing. FossilOrigin-Name: fe41bb5632a5d438acfd682809f1bd12315b970a --- ext/fts3/fts3.c | 5 ++- ext/fts5/fts5_storage.c | 11 +++-- ext/fts5/test/fts5lastrowid.test | 73 ++++++++++++++++++++++++++++++++ manifest | 23 ++++++---- manifest.uuid | 2 +- src/main.c | 15 +++++++ src/sqlite.h.in | 36 +++++++++++++--- test/fts4lastrowid.test | 73 ++++++++++++++++++++++++++++++++ 8 files changed, 217 insertions(+), 21 deletions(-) create mode 100644 ext/fts5/test/fts5lastrowid.test create mode 100644 test/fts4lastrowid.test diff --git a/ext/fts3/fts3.c b/ext/fts3/fts3.c index 7c931c42d4..8af62cda45 100644 --- a/ext/fts3/fts3.c +++ b/ext/fts3/fts3.c @@ -3408,8 +3408,10 @@ static int fts3SyncMethod(sqlite3_vtab *pVtab){ const u32 nMinMerge = 64; /* Minimum amount of incr-merge work to do */ Fts3Table *p = (Fts3Table*)pVtab; - int rc = sqlite3Fts3PendingTermsFlush(p); + int rc; + i64 iLastRowid = sqlite3_last_insert_rowid(p->db); + rc = sqlite3Fts3PendingTermsFlush(p); if( rc==SQLITE_OK && p->nLeafAdd>(nMinMerge/16) && p->nAutoincrmerge && p->nAutoincrmerge!=0xff @@ -3424,6 +3426,7 @@ static int fts3SyncMethod(sqlite3_vtab *pVtab){ if( A>(int)nMinMerge ) rc = sqlite3Fts3Incrmerge(p, A, p->nAutoincrmerge); } sqlite3Fts3SegmentsClose(p); + sqlite3_set_last_insert_rowid(p->db, iLastRowid); return rc; } diff --git a/ext/fts5/fts5_storage.c b/ext/fts5/fts5_storage.c index a695887458..1f8ad2f434 100644 --- a/ext/fts5/fts5_storage.c +++ b/ext/fts5/fts5_storage.c @@ -1092,12 +1092,17 @@ int sqlite3Fts5StorageRowCount(Fts5Storage *p, i64 *pnRow){ ** Flush any data currently held in-memory to disk. */ int sqlite3Fts5StorageSync(Fts5Storage *p, int bCommit){ + int rc = SQLITE_OK; + i64 iLastRowid = sqlite3_last_insert_rowid(p->pConfig->db); if( bCommit && p->bTotalsValid ){ - int rc = fts5StorageSaveTotals(p); + rc = fts5StorageSaveTotals(p); p->bTotalsValid = 0; - if( rc!=SQLITE_OK ) return rc; } - return sqlite3Fts5IndexSync(p->pIndex, bCommit); + if( rc==SQLITE_OK ){ + rc = sqlite3Fts5IndexSync(p->pIndex, bCommit); + } + sqlite3_set_last_insert_rowid(p->pConfig->db, iLastRowid); + return rc; } int sqlite3Fts5StorageRollback(Fts5Storage *p){ diff --git a/ext/fts5/test/fts5lastrowid.test b/ext/fts5/test/fts5lastrowid.test new file mode 100644 index 0000000000..0f7628b233 --- /dev/null +++ b/ext/fts5/test/fts5lastrowid.test @@ -0,0 +1,73 @@ +# 2017 Feb 27 +# +# 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. +# +#*********************************************************************** +# +# Tests of the last_insert_rowid functionality with fts5. +# + +source [file join [file dirname [info script]] fts5_common.tcl] +set testprefix fts5lastrowid + +# If SQLITE_ENABLE_FTS5 is defined, omit this file. +ifcapable !fts5 { + finish_test + return +} + +do_execsql_test 1.0 { + CREATE VIRTUAL TABLE t1 USING fts5(str); +} + +do_execsql_test 1.1 { + INSERT INTO t1 VALUES('one string'); + INSERT INTO t1 VALUES('two string'); + INSERT INTO t1 VALUES('three string'); + SELECT last_insert_rowid(); +} {3} + +do_execsql_test 1.2 { + BEGIN; + INSERT INTO t1 VALUES('one string'); + INSERT INTO t1 VALUES('two string'); + INSERT INTO t1 VALUES('three string'); + COMMIT; + SELECT last_insert_rowid(); +} {6} + +do_execsql_test 1.3 { + INSERT INTO t1(rowid, str) VALUES(-22, 'some more text'); + SELECT last_insert_rowid(); +} {-22} + +do_execsql_test 1.4 { + BEGIN; + INSERT INTO t1(rowid, str) VALUES(45, 'some more text'); + INSERT INTO t1(rowid, str) VALUES(46, 'some more text'); + INSERT INTO t1(rowid, str) VALUES(222, 'some more text'); + SELECT last_insert_rowid(); + COMMIT; + SELECT last_insert_rowid(); +} {222 222} + +do_execsql_test 1.5 { + CREATE TABLE x1(x); + INSERT INTO x1 VALUES('john'), ('paul'), ('george'), ('ringo'); + INSERT INTO t1 SELECT x FROM x1; + SELECT last_insert_rowid(); +} {226} + +do_execsql_test 1.6 { + INSERT INTO t1(rowid, str) SELECT rowid+10, x FROM x1; + SELECT last_insert_rowid(); +} {14} + + +finish_test + diff --git a/manifest b/manifest index 1efcbbbcf0..e571698523 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sreferences\sto\sspecial\shandling\sin\svirtual\stable\smethods\sfrom\sthe\ndocumentation\sfor\ssqlite3_last_insert_rowid(). -D 2017-02-27T12:23:52.119 +C Add\san\ssqlite3_set_last_insert_rowid()\smethod.\sUse\sit\sto\swork\saround\sfts4\sand\nfts5\smodifying\sthe\slast-insert-rowid\sunintuitively\sfrom\swithin\scommit\nprocessing. +D 2017-02-27T14:52:48.644 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 @@ -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 c4d7eecb12de9749851bcab6e5ca616a5803047a +F ext/fts3/fts3.c 95c7041ea75d82d2d9a4cd058904ba889751f5b8 F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe F ext/fts3/fts3Int.h eb2502000148e80913b965db3e59f29251266d0a F ext/fts3/fts3_aux.c 9edc3655fcb287f0467d0a4b886a01c6185fe9f1 @@ -106,7 +106,7 @@ F ext/fts5/fts5_expr.c c6ecc2280162a3714d15dce2a8f2299f748b627c F ext/fts5/fts5_hash.c 880998e596b60f078348d48732ca4ad9a90caad2 F ext/fts5/fts5_index.c f67032a9a529ba52a545e6e3ab970764199c05d4 F ext/fts5/fts5_main.c f85281445dcf8be32d18841c93a6f90fe27dbfe2 -F ext/fts5/fts5_storage.c de0ed8a06738bde433afe11e92295ceaffbc4e58 +F ext/fts5/fts5_storage.c 1db0b6f859ce910027245cf41e8a32c7aaed0042 F ext/fts5/fts5_tcl.c 4a901f00c8553740dba63511603f5527d741c26a F ext/fts5/fts5_test_mi.c 783b86697ebf773c18fc109992426c0173a055bc F ext/fts5/fts5_test_tok.c db08af63673c3a7d39f053b36fd6e065017706be @@ -165,6 +165,7 @@ F ext/fts5/test/fts5full.test 6f6143af0c6700501d9fd597189dfab1555bb741 F ext/fts5/test/fts5fuzz1.test bece4695fc169b61ab236ada7931c6e4942cbef9 F ext/fts5/test/fts5hash.test 06f9309ccb4d5050a131594e9e47d0b21456837d F ext/fts5/test/fts5integrity.test f5e4f8d284385875068ad0f3e894ce43e9de835d +F ext/fts5/test/fts5lastrowid.test 4fac1aba696dd6c956e03b0cf91f6f1f3aaec494 F ext/fts5/test/fts5matchinfo.test f7dde99697bcb310ea8faa8eb2714d9f4dfc0e1b F ext/fts5/test/fts5merge.test 9f65f090d214ff865c56bef4f864aaa1182af6e3 F ext/fts5/test/fts5merge2.test a6da3c16d694235938d1939f503cfa53f0943d75 @@ -360,7 +361,7 @@ F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 F src/insert.c 3ed64afc49c0a2221e397b9f65d231ffbef506fe F src/legacy.c e88ed13c2d531decde75d42c2e35623fb9ce3cb0 F src/loadext.c a68d8d1d14cf7488bb29dc5311cb1ce9a4404258 -F src/main.c e207b81542d13b9f13d61e78ca441f9781f055b0 +F src/main.c 158326243c5ddc8b98a1e983fa488650cf76d760 F src/malloc.c d0a1474236486165bcb349af82e2a6560178bf7b F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c fd7cd6fe21d46fe0a4186367dd8dc26d87b787eb @@ -397,7 +398,7 @@ F src/resolve.c f9bc0de45a30a450da47b3766de00be89bf9be79 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c d12f3539f80db38b09015561b569e0eb1c4b6c5f F src/shell.c bf976d5301be9d8a4c52852c97909cc9a41ee20d -F src/sqlite.h.in 154b80d215289fb9b845a6f4f9b67ea4fcf049f8 +F src/sqlite.h.in 4d0c08f8640c586564a7032b259c5f69bf397850 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae F src/sqliteInt.h a23e18aebdd0d851c2956a74a3a4f12ff202b472 @@ -806,6 +807,7 @@ F test/fts4growth.test e5390da74619cacc389711bac9349640b32c4f9a F test/fts4growth2.test 13ad4e76451af6e6906c95cdc725d01b00044269 F test/fts4incr.test 4e353a0bd886ea984e56fce9e77724fc923b8d0d F test/fts4langid.test 65a7332c9bc257919e259a304aa8a38c41655b9d +F test/fts4lastrowid.test fa5e157955a3121615ef3e16ff5196e96c9e1e64 F test/fts4merge.test d2b39f6b1bd4a9738a13540e2d044cba11c43d47 F test/fts4merge2.test 5faa558d1b672f82b847d2a337465fa745e46891 F test/fts4merge3.test 8d9ccb4a3d41c4c617a149d6c4b13ad02de797d0 @@ -1557,7 +1559,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ffd61fb449a510b2fc90caf86b266733051cc365 -R 8aa5e89f1f59df441ed610ff04b07915 +P 660f9569d76e4ff1f5bd4f37f640e6a4fc2cf87d +R 882d86f84a56568be3256ca713764e4e +T *branch * set-last-insert-rowid +T *sym-set-last-insert-rowid * +T -sym-trunk * U dan -Z e6ccfdfcae6209cec3abae13f87bf4f8 +Z 68fc9fa30db7c037a3f29bd13a0c709d diff --git a/manifest.uuid b/manifest.uuid index d173449ff7..ab91f005ae 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -660f9569d76e4ff1f5bd4f37f640e6a4fc2cf87d \ No newline at end of file +fe41bb5632a5d438acfd682809f1bd12315b970a \ No newline at end of file diff --git a/src/main.c b/src/main.c index 9aad8fdd4c..4ac5327e4f 100644 --- a/src/main.c +++ b/src/main.c @@ -921,6 +921,21 @@ sqlite_int64 sqlite3_last_insert_rowid(sqlite3 *db){ return db->lastRowid; } +/* +** Set the value returned by the sqlite3_last_insert_rowid() API function. +*/ +void sqlite3_set_last_insert_rowid(sqlite3 *db, sqlite3_int64 iRowid){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + (void)SQLITE_MISUSE_BKPT; + return; + } +#endif + sqlite3_mutex_enter(db->mutex); + db->lastRowid = iRowid; + sqlite3_mutex_leave(db->mutex); +} + /* ** Return the number of changes in the most recent call to sqlite3_exec(). */ diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 79b9996848..076a011319 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -2040,13 +2040,25 @@ int sqlite3_extended_result_codes(sqlite3*, int onoff); ** the table has a column of type [INTEGER PRIMARY KEY] then that column ** is another alias for the rowid. ** -** ^The sqlite3_last_insert_rowid(D) interface returns the [rowid] of the -** most recent successful [INSERT] into a rowid table or [virtual table] -** on database connection D. -** ^Inserts into [WITHOUT ROWID] tables are not recorded. -** ^If no successful [INSERT]s into rowid tables -** have ever occurred on the database connection D, -** then sqlite3_last_insert_rowid(D) returns zero. +** ^The sqlite3_last_insert_rowid(D) interface usually returns the [rowid] of +** the most recent successful [INSERT] into a rowid table or [virtual table] +** on database connection D. ^Inserts into [WITHOUT ROWID] tables are not +** recorded. ^If no successful [INSERT]s into rowid tables have ever occurred +** on the database connection D, then sqlite3_last_insert_rowid(D) returns +** zero. +** +** As well as being set automatically as rows are inserted into database +** tables, the value returned by this function may be set explicitly by +** [sqlite3_set_last_insert_rowid()] +** +** Some virtual table implementations may INSERT rows into rowid tables as +** part of committing a transaction (e.g. to flush data accumulated in memory +** to disk). In this case subsequent calls to this function return the rowid +** associated with these internal INSERT operations, which leads to +** unintuitive results. Virtual table implementations that do write to rowid +** tables in this way can avoid this problem by restoring the original +** rowid value using [sqlite3_set_last_insert_rowid()] before returning +** control to the user. ** ** ^(If an [INSERT] occurs within a trigger then this routine will ** return the [rowid] of the inserted row as long as the trigger is @@ -2078,6 +2090,16 @@ int sqlite3_extended_result_codes(sqlite3*, int onoff); */ sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*); +/* +** CAPI3REF: Set the Last Insert Rowid value. +** METHOD: sqlite3 +** +** The sqlite3_set_last_insert_rowid(D, R) method allows the application to +** set the value returned by calling sqlite3_last_insert_rowid(D) to R +** without inserting a row into the database. +*/ +void sqlite3_set_last_insert_rowid(sqlite3*,sqlite3_int64); + /* ** CAPI3REF: Count The Number Of Rows Modified ** METHOD: sqlite3 diff --git a/test/fts4lastrowid.test b/test/fts4lastrowid.test new file mode 100644 index 0000000000..b5720a2ef3 --- /dev/null +++ b/test/fts4lastrowid.test @@ -0,0 +1,73 @@ +# 2017 Feb 27 +# +# 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. +# +#*********************************************************************** +# +# Tests of the last_insert_rowid functionality with fts4. +# + +set testdir [file dirname $argv0] +source [file join [file dirname [info script]] tester.tcl] +set testprefix fts4lastrowid + +ifcapable !fts3 { + finish_test + return +} + +do_execsql_test 1.0 { + CREATE VIRTUAL TABLE t1 USING fts4(str); +} + +do_execsql_test 1.1 { + INSERT INTO t1 VALUES('one string'); + INSERT INTO t1 VALUES('two string'); + INSERT INTO t1 VALUES('three string'); + SELECT last_insert_rowid(); +} {3} + +do_execsql_test 1.2 { + BEGIN; + INSERT INTO t1 VALUES('one string'); + INSERT INTO t1 VALUES('two string'); + INSERT INTO t1 VALUES('three string'); + COMMIT; + SELECT last_insert_rowid(); +} {6} + +do_execsql_test 1.3 { + INSERT INTO t1(rowid, str) VALUES(-22, 'some more text'); + SELECT last_insert_rowid(); +} {-22} + +do_execsql_test 1.4 { + BEGIN; + INSERT INTO t1(rowid, str) VALUES(45, 'some more text'); + INSERT INTO t1(rowid, str) VALUES(46, 'some more text'); + INSERT INTO t1(rowid, str) VALUES(222, 'some more text'); + SELECT last_insert_rowid(); + COMMIT; + SELECT last_insert_rowid(); +} {222 222} + +do_execsql_test 1.5 { + CREATE TABLE x1(x); + INSERT INTO x1 VALUES('john'), ('paul'), ('george'), ('ringo'); + INSERT INTO t1 SELECT x FROM x1; + SELECT last_insert_rowid(); +} {226} + +do_execsql_test 1.6 { + INSERT INTO t1(rowid, str) SELECT rowid+10, x FROM x1; + SELECT last_insert_rowid(); +} {14} + + +finish_test + From 81415257ec6bdfc97ff5073e7f80bda09abef774 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 27 Feb 2017 17:06:56 +0000 Subject: [PATCH 1375/1484] Improve performance of fts5 writes by writing the "averages" record once at the end of each transaction instead of every time the table is updated. FossilOrigin-Name: 2b210d691462b463796e7948399133c296e89ebf --- ext/fts5/fts5_storage.c | 14 ++------------ manifest | 13 ++++++------- manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 20 deletions(-) diff --git a/ext/fts5/fts5_storage.c b/ext/fts5/fts5_storage.c index 1f8ad2f434..c8c26bd1b6 100644 --- a/ext/fts5/fts5_storage.c +++ b/ext/fts5/fts5_storage.c @@ -545,11 +545,6 @@ int sqlite3Fts5StorageDelete(Fts5Storage *p, i64 iDel, sqlite3_value **apVal){ } } - /* Write the averages record */ - if( rc==SQLITE_OK ){ - rc = fts5StorageSaveTotals(p); - } - return rc; } @@ -753,11 +748,6 @@ int sqlite3Fts5StorageIndexInsert( } sqlite3_free(buf.p); - /* Write the averages record */ - if( rc==SQLITE_OK ){ - rc = fts5StorageSaveTotals(p); - } - return rc; } @@ -1094,9 +1084,9 @@ int sqlite3Fts5StorageRowCount(Fts5Storage *p, i64 *pnRow){ int sqlite3Fts5StorageSync(Fts5Storage *p, int bCommit){ int rc = SQLITE_OK; i64 iLastRowid = sqlite3_last_insert_rowid(p->pConfig->db); - if( bCommit && p->bTotalsValid ){ + if( p->bTotalsValid ){ rc = fts5StorageSaveTotals(p); - p->bTotalsValid = 0; + if( bCommit ) p->bTotalsValid = 0; } if( rc==SQLITE_OK ){ rc = sqlite3Fts5IndexSync(p->pIndex, bCommit); diff --git a/manifest b/manifest index 089fbab958..f842047291 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\san\ssqlite3_set_last_insert_rowid()\smethod.\sUse\sit\sto\swork\saround\sfts4\sand\nfts5\smodifying\sthe\slast-insert-rowid\sunintuitively\sfrom\swithin\scommit\nprocessing. -D 2017-02-27T16:15:29.690 +C Improve\sperformance\sof\sfts5\swrites\sby\swriting\sthe\s"averages"\srecord\sonce\sat\nthe\send\sof\seach\stransaction\sinstead\sof\severy\stime\sthe\stable\sis\supdated. +D 2017-02-27T17:06:56.850 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 @@ -106,7 +106,7 @@ F ext/fts5/fts5_expr.c c6ecc2280162a3714d15dce2a8f2299f748b627c F ext/fts5/fts5_hash.c 880998e596b60f078348d48732ca4ad9a90caad2 F ext/fts5/fts5_index.c f67032a9a529ba52a545e6e3ab970764199c05d4 F ext/fts5/fts5_main.c f85281445dcf8be32d18841c93a6f90fe27dbfe2 -F ext/fts5/fts5_storage.c 1db0b6f859ce910027245cf41e8a32c7aaed0042 +F ext/fts5/fts5_storage.c 8f0e65cb33bde8f449e1c9b4be4600d18b4da6e9 F ext/fts5/fts5_tcl.c 4a901f00c8553740dba63511603f5527d741c26a F ext/fts5/fts5_test_mi.c 783b86697ebf773c18fc109992426c0173a055bc F ext/fts5/fts5_test_tok.c db08af63673c3a7d39f053b36fd6e065017706be @@ -1559,8 +1559,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 660f9569d76e4ff1f5bd4f37f640e6a4fc2cf87d fe41bb5632a5d438acfd682809f1bd12315b970a -R 882d86f84a56568be3256ca713764e4e -T +closed fe41bb5632a5d438acfd682809f1bd12315b970a +P 952a3906b30a818e4574bb85f57150577d04f74e +R 84bac8b8e25067f97464b8201fd688d3 U dan -Z 5437a317a211c2826dc04cbed3f42658 +Z 50f45fcec707e33cc33fa8432e53c9b6 diff --git a/manifest.uuid b/manifest.uuid index c4e0be71d1..a89a664ddf 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -952a3906b30a818e4574bb85f57150577d04f74e \ No newline at end of file +2b210d691462b463796e7948399133c296e89ebf \ No newline at end of file From 6e5688d37502f62f7a55bd35c072546d1f78d82e Mon Sep 17 00:00:00 2001 From: mistachkin Date: Mon, 27 Feb 2017 17:16:27 +0000 Subject: [PATCH 1376/1484] Make PATH handling more robust in the batch tools for MSVC. FossilOrigin-Name: 23a8917e848a999533bc66467f7cb2f4f3d45bc1 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- tool/GetTclKit.bat | 14 +++++++++++++- tool/build-all-msvc.bat | 6 +++++- 4 files changed, 27 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index f842047291..c06c866121 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improve\sperformance\sof\sfts5\swrites\sby\swriting\sthe\s"averages"\srecord\sonce\sat\nthe\send\sof\seach\stransaction\sinstead\sof\severy\stime\sthe\stable\sis\supdated. -D 2017-02-27T17:06:56.850 +C Make\sPATH\shandling\smore\srobust\sin\sthe\sbatch\stools\sfor\sMSVC. +D 2017-02-27T17:16:27.906 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 @@ -1469,10 +1469,10 @@ F test/wordcount.c 06efb84b7c48a4973c2c24ea06c93d00bce24389 F test/zeroblob.test 3857870fe681b8185654414a9bccfde80b62a0fa F test/zerodamage.test e59a56443d6298ecf7435f618f0b27654f0c849e F tool/GetFile.cs a15e08acb5dd7539b75ba23501581d7c2b462cb5 -F tool/GetTclKit.bat f94784e3bdc2f50c539266f5467cbf1f27612cb3 +F tool/GetTclKit.bat 6afa640edc7810725aec61c3076ac617c4aaf0b7 F tool/Replace.cs 02c67258801c2fb5f63231e0ac0f220b4b36ba91 F tool/addopcodes.tcl 10c889c4a65ec6c5604e4a47306fa77ff57ae189 -F tool/build-all-msvc.bat 018c1b273458a90c8ba633c6f0c5654cfcb138bf x +F tool/build-all-msvc.bat c12328d06c45fec8baada5949e3d5af54bf8c887 x F tool/build-shell.sh 950f47c6174f1eea171319438b93ba67ff5bf367 F tool/cg_anno.tcl f95b0006c52cf7f0496b506343415b6ee3cdcdd3 x F tool/checkSpacing.c 810e51703529a204fc4e1eb060e9ab663e3c06d2 @@ -1559,7 +1559,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 952a3906b30a818e4574bb85f57150577d04f74e -R 84bac8b8e25067f97464b8201fd688d3 -U dan -Z 50f45fcec707e33cc33fa8432e53c9b6 +P 2b210d691462b463796e7948399133c296e89ebf +R 2fadaa28e86ebe3a08aafa06769bc23f +U mistachkin +Z 6b968b4fe877e63444beda0443031271 diff --git a/manifest.uuid b/manifest.uuid index a89a664ddf..af9a30ac81 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2b210d691462b463796e7948399133c296e89ebf \ No newline at end of file +23a8917e848a999533bc66467f7cb2f4f3d45bc1 \ No newline at end of file diff --git a/tool/GetTclKit.bat b/tool/GetTclKit.bat index 8764b195dd..1c9f92bc12 100644 --- a/tool/GetTclKit.bat +++ b/tool/GetTclKit.bat @@ -124,7 +124,7 @@ IF NOT EXIST "%FRAMEWORKDIR%\csc.exe" ( GOTO errors ) -SET PATH=%FRAMEWORKDIR%;%PATH% +CALL :fn_PrependToPath FRAMEWORKDIR :skip_addToPath @@ -246,6 +246,18 @@ GOTO no_errors ENDLOCAL && SET %1=%VALUE% GOTO :EOF +:fn_PrependToPath + IF NOT DEFINED %1 GOTO :EOF + SETLOCAL + SET __ECHO_CMD=ECHO %%%1%% + FOR /F "delims=" %%V IN ('%__ECHO_CMD%') DO ( + SET VALUE=%%V + ) + SET VALUE=%VALUE:"=% + REM " + ENDLOCAL && SET PATH=%VALUE%;%PATH% + GOTO :EOF + :fn_ResetErrorLevel VERIFY > NUL GOTO :EOF diff --git a/tool/build-all-msvc.bat b/tool/build-all-msvc.bat index 497b05e316..aaeb67bdfb 100755 --- a/tool/build-all-msvc.bat +++ b/tool/build-all-msvc.bat @@ -460,7 +460,7 @@ FOR %%P IN (%PLATFORMS%) DO ( REM REM NOTE: Reset the PATH here to the absolute bare minimum required. REM - SET PATH=%TOOLPATH%;%SystemRoot%\System32;%SystemRoot% + CALL :fn_ResetPath REM REM NOTE: This is the inner loop. There are normally two iterations, one @@ -818,6 +818,10 @@ GOTO no_errors CALL :fn_ResetErrorLevel GOTO :EOF +:fn_ResetPath + SET PATH=%TOOLPATH%;%SystemRoot%\System32;%SystemRoot% + GOTO :EOF + :fn_AppendVariable SET __ECHO_CMD=ECHO %%%1%% IF DEFINED %1 ( From 2147221c36ca4f5067e6e2ea0dd0b8eac4a18f37 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 1 Mar 2017 11:30:27 +0000 Subject: [PATCH 1377/1484] Fix a use-after-free problem in the shell tool code that could occur if an SQL statement were executed after an ".open" command with invalid options. FossilOrigin-Name: ac760db0727209db0a816e112ea5f47e54d54dac --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/shell.c | 1 + 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index c06c866121..f194990812 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\sPATH\shandling\smore\srobust\sin\sthe\sbatch\stools\sfor\sMSVC. -D 2017-02-27T17:16:27.906 +C Fix\sa\suse-after-free\sproblem\sin\sthe\sshell\stool\scode\sthat\scould\soccur\sif\san\sSQL\nstatement\swere\sexecuted\safter\san\s".open"\scommand\swith\sinvalid\soptions. +D 2017-03-01T11:30:27.730 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 @@ -397,7 +397,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c f9bc0de45a30a450da47b3766de00be89bf9be79 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c d12f3539f80db38b09015561b569e0eb1c4b6c5f -F src/shell.c bf976d5301be9d8a4c52852c97909cc9a41ee20d +F src/shell.c 27d2b31099fd2cd749e44d025ef9b54ca26692cb F src/sqlite.h.in 4d0c08f8640c586564a7032b259c5f69bf397850 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae @@ -1559,7 +1559,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 2b210d691462b463796e7948399133c296e89ebf -R 2fadaa28e86ebe3a08aafa06769bc23f -U mistachkin -Z 6b968b4fe877e63444beda0443031271 +P 23a8917e848a999533bc66467f7cb2f4f3d45bc1 +R 6f5948ee4f1d68e0584e854f4c330a6f +U dan +Z 4914d52d58dfba6bed9b5d6006acef82 diff --git a/manifest.uuid b/manifest.uuid index af9a30ac81..a3f75430ae 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -23a8917e848a999533bc66467f7cb2f4f3d45bc1 \ No newline at end of file +ac760db0727209db0a816e112ea5f47e54d54dac \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index f1c7f3c157..2dcf915f28 100644 --- a/src/shell.c +++ b/src/shell.c @@ -4344,6 +4344,7 @@ static int do_meta_command(char *zLine, ShellState *p){ session_close_all(p); sqlite3_close(p->db); p->db = 0; + p->zDbFilename = 0; sqlite3_free(p->zFreeOnClose); p->zFreeOnClose = 0; /* Check for command-line arguments */ From 76adb239805a543742232090cd4399db3f8f46f6 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 2 Mar 2017 13:13:30 +0000 Subject: [PATCH 1378/1484] Make sure the Vdbe.expmask value is set correctly in sqlite3VdbeSwap(). This fixes a problem introduced by [a8fd7052]. FossilOrigin-Name: 29f54b899e5cf22ece98ab41c39c41d75a4b228d --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/vdbeaux.c | 1 + 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index f194990812..646adca563 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\suse-after-free\sproblem\sin\sthe\sshell\stool\scode\sthat\scould\soccur\sif\san\sSQL\nstatement\swere\sexecuted\safter\san\s".open"\scommand\swith\sinvalid\soptions. -D 2017-03-01T11:30:27.730 +C Make\ssure\sthe\sVdbe.expmask\svalue\sis\sset\scorrectly\sin\ssqlite3VdbeSwap().\nThis\sfixes\sa\sproblem\sintroduced\sby\s[a8fd7052]. +D 2017-03-02T13:13:30.327 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 @@ -467,7 +467,7 @@ F src/vdbe.c 83f387d9e6842b1dc99f6e85bb577c5bbc4e397d F src/vdbe.h 59998ffd71d7caa8886bc78dafaf8caeccd4c13c F src/vdbeInt.h 4e4b15b2e1330e1636e4e01974eab2b0b985092f F src/vdbeapi.c 70aabe108c411e529a59d8800445513965334062 -F src/vdbeaux.c 031422c66e272c7f1027070e7f0858f4c418dfbc +F src/vdbeaux.c b632f9151a296c5eb22a2cc955c487ebc2347cb6 F src/vdbeblob.c 359891617358deefc85bef7bcf787fa6b77facb9 F src/vdbemem.c 3b5a9a5b375458d3e12a50ae1aaa41eeec2175fd F src/vdbesort.c eda25cb2d1727efca6f7862fea32b8aa33c0face @@ -1559,7 +1559,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 23a8917e848a999533bc66467f7cb2f4f3d45bc1 -R 6f5948ee4f1d68e0584e854f4c330a6f -U dan -Z 4914d52d58dfba6bed9b5d6006acef82 +P ac760db0727209db0a816e112ea5f47e54d54dac +R be25bb329cc9311f7d92b42176424b6a +U drh +Z eb983447910676b385a2c6496a637326 diff --git a/manifest.uuid b/manifest.uuid index a3f75430ae..9f406e4ffa 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ac760db0727209db0a816e112ea5f47e54d54dac \ No newline at end of file +29f54b899e5cf22ece98ab41c39c41d75a4b228d \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 67e0f63ef6..8a19c26003 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -86,6 +86,7 @@ void sqlite3VdbeSwap(Vdbe *pA, Vdbe *pB){ pA->zSql = pB->zSql; pB->zSql = zTmp; pB->isPrepareV2 = pA->isPrepareV2; + pB->expmask = pA->expmask; } /* From 1cfaf8eafb11a7f2a0ab8dbc47c99dd333667a19 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 2 Mar 2017 14:17:21 +0000 Subject: [PATCH 1379/1484] Add an optional bitmask of allowed optimizations on the "PRAGMA optimize" command. The 0x01 bit is Debug Mode. FossilOrigin-Name: a35388eef4096c1856b025dbd90143409d4a72d3 --- manifest | 16 ++++++------ manifest.uuid | 2 +- src/pragma.c | 60 +++++++++++++++++++++++++++++++++----------- src/pragma.h | 2 +- tool/mkpragmatab.tcl | 2 +- 5 files changed, 56 insertions(+), 26 deletions(-) diff --git a/manifest b/manifest index bbbb0936a4..fb60f9c239 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\srecent\strunk\senhancements. -D 2017-03-02T13:22:04.261 +C Add\san\soptional\sbitmask\sof\sallowed\soptimizations\son\sthe\s"PRAGMA\soptimize"\ncommand.\s\sThe\s0x01\sbit\sis\sDebug\sMode. +D 2017-03-02T14:17:21.291 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 @@ -389,8 +389,8 @@ F src/parse.y af8830094f4aecb91cb69721f3601ad10c36abc4 F src/pcache.c 62835bed959e2914edd26afadfecce29ece0e870 F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 F src/pcache1.c e3967219b2a92b9edcb9324a4ba75009090d3953 -F src/pragma.c 4b32b014bb4b460bbf0103e4631809428c1ce16b -F src/pragma.h d97dd835c7f4dfb6857487707313385d44fa76c0 +F src/pragma.c 75fdb05838c303cf0ce5846ca011b8103531c42c +F src/pragma.h c9c763958fec92b04125571472c9500b351c5f7f F src/prepare.c b1140c3d0cf59bc85ace00ce363153041b424b7a F src/printf.c 67427bbee66d891fc6f6f5aada857e9cdb368c1c F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 @@ -1498,7 +1498,7 @@ F tool/mkmsvcmin.tcl 95b37e202cbed873aa8ffdbb493b9db45927be2b F tool/mkopcodec.tcl d1b6362bd3aa80d5520d4d6f3765badf01f6c43c F tool/mkopcodeh.tcl a01d2c1d8a6205b03fc635adf3735b4c523befd3 F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e -F tool/mkpragmatab.tcl 9b499f7301fadeddeae52b95f962ef7e5a718f50 +F tool/mkpragmatab.tcl 2ffe6d5fdc2d3381621d6c77978ba054466e757f F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 F tool/mksqlite3c-noext.tcl fef88397668ae83166735c41af99d79f56afaabb F tool/mksqlite3c.tcl 06b2e6a0f21cc0a5d70fbbd136b3e0a96470645e @@ -1560,7 +1560,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 7a959f6d1ea038988cdb4c02d6f37abaec2580a0 29f54b899e5cf22ece98ab41c39c41d75a4b228d -R 6bb37f552ece3665cee38d0fc37ff06c +P c60cdb47612c05c252613e50a8ac10635469fdfe +R dbee345c7724a1e9049a9032bbb0a60b U drh -Z 8ce562b5567814952b66c349d10ab9fa +Z f9893159b19aa2a55c1ddc2fbced30b3 diff --git a/manifest.uuid b/manifest.uuid index e6cd24f62f..3384381146 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c60cdb47612c05c252613e50a8ac10635469fdfe \ No newline at end of file +a35388eef4096c1856b025dbd90143409d4a72d3 \ No newline at end of file diff --git a/src/pragma.c b/src/pragma.c index 916ed4aa57..c5f2a77eef 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -1864,34 +1864,51 @@ void sqlite3Pragma( /* ** PRAGMA optimize + ** PRAGMA optimize(MASK) ** PRAGMA schema.optimize + ** PRAGMA schema.optimize(MASK) ** ** Attempt to optimize the database. All schemas are optimized in the first - ** form, and only the specified schema is optimized in the second form. + ** two forms, and only the specified schema is optimized in the latter two. ** ** The details of optimizations performed by this pragma does are expected ** to change and improve over time. Applications should anticipate that ** this pragma will perform new optimizations in future releases. ** - ** Argments to this pragma are currently ignored, but future enhancements - ** might make use of arguments to control which optimizations are allowed - ** or to suggest limits on how much CPU time and I/O should be expended - ** in the optimization effort. + ** The optional argument is a bitmask of optimizations to perform: ** - ** The current implementation runs ANALYZE on any tables which might have - ** benefitted from having recent statistics at some point since the start - ** of the current connection. Only tables in "schema" are analyzed in the - ** second form. In the first form, all tables except TEMP tables are - ** checked. + ** 0x0001 Debugging mode. Do not actually perform any optimizations + ** but instead return one line of text for each optimization + ** that would have been done. Off by default. ** - ** In the current implementation, a table is analyzed only if both of + ** 0x0002 Run ANALYZE on tables that might benefit. On by default. + ** See below for additional information. + ** + ** 0x0004 (Not yet implemented) Record usage and performance + ** information from the current session in the + ** database file so that it will be available to "optimize" + ** pragmas run by future database connections. + ** + ** 0x0008 (Not yet implemented) Create indexes that might have + ** been helpful to recent queries + ** + ** The default MASK is 0x000e, which means perform all of the optimizations + ** listed above except do not set Debug Mode. New optimizations may be + ** added in future releases but they will be turned off by default. The + ** default MASK will always be 0x0e. + ** + ** DETERMINATION OF WHEN TO RUN ANALYZE + ** + ** In the current implementation, a table is analyzed if only if all of ** the following are true: ** - ** (1) The query planner used sqlite_stat1-style statistics for one or + ** (1) MASK bit 0x02 is set. + ** + ** (2) The query planner used sqlite_stat1-style statistics for one or ** more indexes of the table at some point during the lifetime of ** the current connection. ** - ** (2) One or more indexes of the table are currently unanalyzed OR + ** (3) One or more indexes of the table are currently unanalyzed OR ** the number of rows in the table has increased by 25 times or more ** since the last time ANALYZE was run. ** @@ -1907,7 +1924,14 @@ void sqlite3Pragma( Index *pIdx; /* An index of the table */ LogEst szThreshold; /* Size threshold above which reanalysis is needd */ char *zSubSql; /* SQL statement for the OP_SqlExec opcode */ + u32 opMask; /* Mask of operations to perform */ + if( zRight ){ + opMask = (u32)sqlite3Atoi(zRight); + if( (opMask & 0x02)==0 ) break; + }else{ + opMask = 0xe; + } iTabCur = pParse->nTab++; for(iDbLast = zDb?iDb:db->nDb-1; iDb<=iDbLast; iDb++){ if( iDb==1 ) continue; @@ -1932,12 +1956,18 @@ void sqlite3Pragma( if( szThreshold ){ sqlite3OpenTable(pParse, iTabCur, iDb, pTab, OP_OpenRead); sqlite3VdbeAddOp3(v, OP_IfSmaller, iTabCur, - sqlite3VdbeCurrentAddr(v)+2, szThreshold); + sqlite3VdbeCurrentAddr(v)+2+(opMask&1), szThreshold); VdbeCoverage(v); } zSubSql = sqlite3MPrintf(db, "ANALYZE \"%w\".\"%w\"", db->aDb[iDb].zDbSName, pTab->zName); - sqlite3VdbeAddOp4(v, OP_SqlExec, 0, 0, 0, zSubSql, P4_DYNAMIC); + if( opMask & 0x01 ){ + int r1 = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp4(v, OP_String8, 0, r1, 0, zSubSql, P4_DYNAMIC); + sqlite3VdbeAddOp2(v, OP_ResultRow, r1, 1); + }else{ + sqlite3VdbeAddOp4(v, OP_SqlExec, 0, 0, 0, zSubSql, P4_DYNAMIC); + } } } sqlite3VdbeAddOp0(v, OP_Expire); diff --git a/src/pragma.h b/src/pragma.h index 363975df55..9b1c723b3e 100644 --- a/src/pragma.h +++ b/src/pragma.h @@ -417,7 +417,7 @@ static const PragmaName aPragmaName[] = { #endif {/* zName: */ "optimize", /* ePragTyp: */ PragTyp_OPTIMIZE, - /* ePragFlg: */ PragFlg_NoColumns, + /* ePragFlg: */ PragFlg_Result1, /* ColNames: */ 0, 0, /* iArg: */ 0 }, #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) diff --git a/tool/mkpragmatab.tcl b/tool/mkpragmatab.tcl index f0ba49b545..59b245cc76 100644 --- a/tool/mkpragmatab.tcl +++ b/tool/mkpragmatab.tcl @@ -363,7 +363,7 @@ set pragma_def { FLAG: Result0 NAME: optimize - FLAG: NoColumns + FLAG: Result1 } # Open the output file From cb1b0a693ac7aef2f05c65dba4d4bf5d78d4cf3b Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 2 Mar 2017 14:51:47 +0000 Subject: [PATCH 1380/1484] When saving the state of an RBU update in the incremental-checkpoint phase, sync the database file. Otherwise, if a power failure occurs and the RBU update resumed following system recovery, the database may become corrupt. FossilOrigin-Name: edee6a80e1cc7e6a2b8c3c7f76dd794fc8ab9a72 --- ext/rbu/rbucrash2.test | 101 +++++++++++++++++++++++++++++++++++++++++ ext/rbu/sqlite3rbu.c | 12 +++++ manifest | 19 ++++---- manifest.uuid | 2 +- src/test6.c | 17 ++++--- test/tester.tcl | 6 ++- 6 files changed, 139 insertions(+), 18 deletions(-) create mode 100644 ext/rbu/rbucrash2.test diff --git a/ext/rbu/rbucrash2.test b/ext/rbu/rbucrash2.test new file mode 100644 index 0000000000..89c2535a93 --- /dev/null +++ b/ext/rbu/rbucrash2.test @@ -0,0 +1,101 @@ +# 2017 March 02 +# +# 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. +# +#*********************************************************************** +# + +if {![info exists testdir]} { + set testdir [file join [file dirname [info script]] .. .. test] +} +source $testdir/tester.tcl +set ::testprefix rbucrash2 + +db close +forcedelete test.db-oal rbu.db +sqlite3_shutdown +sqlite3_config_uri 1 +reset_db + +# Set up a target database and an rbu update database. The target +# db is the usual "test.db", the rbu db is "test.db2". +# +forcedelete test.db2 +do_execsql_test 1.0 { + CREATE TABLE t1(a, b, c, PRIMARY KEY(a), UNIQUE(b)); + INSERT INTO t1 VALUES(1, 2, 3); + INSERT INTO t1 VALUES(4, 5, 6); + INSERT INTO t1 VALUES(7, 8, 9); + + ATTACH 'test.db2' AS rbu; + CREATE TABLE rbu.data_t1(a, b, c, rbu_control); + INSERT INTO data_t1 VALUES('one', randomblob(3500), NULL, 0); + INSERT INTO data_t1 VALUES('two', randomblob(3500), NULL, 0); + INSERT INTO data_t1 VALUES('three', randomblob(3500), NULL, 0); + INSERT INTO data_t1 VALUES('four', randomblob(3500), NULL, 0); + INSERT INTO data_t1 VALUES('five', randomblob(3500), NULL, 0); + INSERT INTO data_t1 VALUES('six', randomblob(3500), NULL, 0); +} +db_save_and_close + +proc do_rbu_crash_test2 {tn script} { + + foreach f {test.db test.db2} { + set bDone 0 + for {set iDelay 1} {$bDone==0} {incr iDelay} { + forcedelete test.db2 test.db2-journal test.db test.db-oal test.db-wal + db_restore + + set res [ + crashsql -file $f -delay $iDelay -tclbody $script -dflt 1 -opendb {} \ + -blocksize 512 {} + ] + + set bDone 1 + if {$res == "1 {child process exited abnormally}"} { + set bDone 0 + } elseif {$res != "0 {}"} { + error "unexected catchsql result: $res" + } + + sqlite3rbu rbu test.db test.db2 + while {[rbu step]=="SQLITE_OK"} {} + rbu close + + sqlite3 db test.db + do_execsql_test $tn.delay=$iDelay.f=$f { + PRAGMA integrity_check; + } {ok} + db close + } + } +} + +for {set x 1} {$x < 10} {incr x} { + do_rbu_crash_test2 1.$x { + sqlite3rbu rbu test.db test.db2 + while {[rbu step]=="SQLITE_OK"} { + rbu savestate + } + rbu close + } +} + +for {set x 1} {$x < 2} {incr x} { + do_rbu_crash_test2 2.$x { + sqlite3rbu rbu test.db test.db2 + while {[rbu step]=="SQLITE_OK"} { + rbu close + sqlite3rbu rbu test.db test.db2 + } + rbu close + } +} + +finish_test + diff --git a/ext/rbu/sqlite3rbu.c b/ext/rbu/sqlite3rbu.c index 48c69115ee..262f96ea3c 100644 --- a/ext/rbu/sqlite3rbu.c +++ b/ext/rbu/sqlite3rbu.c @@ -3718,6 +3718,12 @@ int sqlite3rbu_close(sqlite3rbu *p, char **pzErrmsg){ p->rc = sqlite3_exec(p->dbMain, "COMMIT", 0, 0, &p->zErrmsg); } + /* Sync the db file if currently doing an incremental checkpoint */ + if( p->rc==SQLITE_OK && p->eStage==RBU_STAGE_CKPT ){ + sqlite3_file *pDb = p->pTargetFd->pReal; + p->rc = pDb->pMethods->xSync(pDb, SQLITE_SYNC_NORMAL); + } + rbuSaveState(p, p->eStage); if( p->rc==SQLITE_OK && p->eStage==RBU_STAGE_OAL ){ @@ -3842,6 +3848,12 @@ int sqlite3rbu_savestate(sqlite3rbu *p){ if( rc==SQLITE_OK ) rc = sqlite3_exec(p->dbMain, "COMMIT", 0, 0, 0); } + /* Sync the db file */ + if( rc==SQLITE_OK && p->eStage==RBU_STAGE_CKPT ){ + sqlite3_file *pDb = p->pTargetFd->pReal; + rc = pDb->pMethods->xSync(pDb, SQLITE_SYNC_NORMAL); + } + p->rc = rc; rbuSaveState(p, p->eStage); rc = p->rc; diff --git a/manifest b/manifest index 646adca563..4ab87a35ed 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\ssure\sthe\sVdbe.expmask\svalue\sis\sset\scorrectly\sin\ssqlite3VdbeSwap().\nThis\sfixes\sa\sproblem\sintroduced\sby\s[a8fd7052]. -D 2017-03-02T13:13:30.327 +C When\ssaving\sthe\sstate\sof\san\sRBU\supdate\sin\sthe\sincremental-checkpoint\sphase,\nsync\sthe\sdatabase\sfile.\sOtherwise,\sif\sa\spower\sfailure\soccurs\sand\sthe\sRBU\nupdate\sresumed\sfollowing\ssystem\srecovery,\sthe\sdatabase\smay\sbecome\scorrupt. +D 2017-03-02T14:51:47.379 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 @@ -250,6 +250,7 @@ F ext/rbu/rbuB.test c25bc325b8072a766e56bb76c001866b405925c2 F ext/rbu/rbuC.test efe47db508a0269b683cb2a1913a425ffd39a831 F ext/rbu/rbu_common.tcl a38e8e2d4a50fd6aaf151633714c1b1d2fae3ead F ext/rbu/rbucrash.test 8d2ed5d4b05fef6c00c2a6b5f7ead71fa172a695 +F ext/rbu/rbucrash2.test 7f3fe5d6d930be0965f27b49bdcdc8d4a078b73c F ext/rbu/rbudiff.test 3e605cf624d00d04d0fb1316a3acec4fbe3b3ac5 F ext/rbu/rbudor.test 99b05cc0df613e962c2c8085cfb05686a09cf315 F ext/rbu/rbufault.test cc0be8d5d392d98b0c2d6a51be377ea989250a89 @@ -262,7 +263,7 @@ F ext/rbu/rburesume.test 8acb77f4a422ff55acfcfc9cc15a5cb210b1de83 F ext/rbu/rbusave.test 0f43b6686084f426ddd040b878426452fd2c2f48 F ext/rbu/rbuvacuum.test 4a977447c15c2581ab668781d9ef4294382530e0 F ext/rbu/rbuvacuum2.test 2074ab14fe66e1c7e7210c62562650dcd215bbaa -F ext/rbu/sqlite3rbu.c bb0de6cdbdb14a7d55a097238a434b7e99caf318 +F ext/rbu/sqlite3rbu.c 3c2dfd3f27a3ecc5f017ecf82d563b522bbc341a F ext/rbu/sqlite3rbu.h 6fb6294c34a9ca93b5894a33bca530c6f08decba F ext/rbu/test_rbu.c 5aa22616afac6f71ebd3d9bc9bf1006cfabcca88 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 @@ -411,7 +412,7 @@ F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5 F src/test3.c d03f5b5da9a2410b7a91c64b0d3306ed28ab6fee F src/test4.c 18ec393bb4d0ad1de729f0b94da7267270f3d8e6 F src/test5.c 328aae2c010c57a9829d255dc099d6899311672d -F src/test6.c 121060d2e79a4f5047eb12b5135b23a6a7a5af01 +F src/test6.c 004ad42f121f693b8cbe060d1a330678abc61620 F src/test7.c 5612e9aecf934d6df7bba6ce861fdf5ba5456010 F src/test8.c 4f4904721167b32f7a4fa8c7b32a07a673d6cc86 F src/test9.c 12e5ba554d2d1cbe0158f6ab3f7ffcd7a86ee4e5 @@ -1173,7 +1174,7 @@ F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30 F test/temptable2.test cd396beb41117a5302fff61767c35fa4270a0d5e F test/temptable3.test d11a0974e52b347e45ee54ef1923c91ed91e4637 F test/temptrigger.test 38f0ca479b1822d3117069e014daabcaacefffcc -F test/tester.tcl 67835ac17e90055f24a9cf52e5c5bce0dd511c74 +F test/tester.tcl 581f0185434daf7026ccede4c07e8d1479186ec5 F test/thread001.test 9f22fd3525a307ff42a326b6bc7b0465be1745a5 F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58 F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7 @@ -1559,7 +1560,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ac760db0727209db0a816e112ea5f47e54d54dac -R be25bb329cc9311f7d92b42176424b6a -U drh -Z eb983447910676b385a2c6496a637326 +P 29f54b899e5cf22ece98ab41c39c41d75a4b228d +R fd6b0917cff6359266006d6c00dd0a12 +U dan +Z 1a59570e49a3b7cf84dd8025330375c8 diff --git a/manifest.uuid b/manifest.uuid index 9f406e4ffa..f24ae9a62a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -29f54b899e5cf22ece98ab41c39c41d75a4b228d \ No newline at end of file +edee6a80e1cc7e6a2b8c3c7f76dd794fc8ab9a72 \ No newline at end of file diff --git a/src/test6.c b/src/test6.c index a103b9619e..849cdeb3b9 100644 --- a/src/test6.c +++ b/src/test6.c @@ -315,8 +315,9 @@ static int writeListSync(CrashFile *pFile, int isCrash){ assert(pWrite->zBuf); #ifdef TRACE_CRASHTEST - printf("Trashing %d sectors @ %lld (sector %d) (%s)\n", - 1+iLast-iFirst, pWrite->iOffset, iFirst, pWrite->pFile->zName + printf("Trashing %d sectors (%d bytes) @ %lld (sector %d) (%s)\n", + 1+iLast-iFirst, (1+iLast-iFirst)*g.iSectorSize, + pWrite->iOffset, iFirst, pWrite->pFile->zName ); #endif @@ -827,7 +828,7 @@ static int SQLITE_TCLAPI crashNowCmd( } /* -** tclcmd: sqlite_crash_enable ENABLE +** tclcmd: sqlite_crash_enable ENABLE ?DEFAULT? ** ** Parameter ENABLE must be a boolean value. If true, then the "crash" ** vfs is added to the system. If false, it is removed. @@ -839,6 +840,7 @@ static int SQLITE_TCLAPI crashEnableCmd( Tcl_Obj *CONST objv[] ){ int isEnable; + int isDefault = 0; static sqlite3_vfs crashVfs = { 2, /* iVersion */ 0, /* szOsFile */ @@ -862,14 +864,17 @@ static int SQLITE_TCLAPI crashEnableCmd( 0, /* xCurrentTimeInt64 */ }; - if( objc!=2 ){ - Tcl_WrongNumArgs(interp, 1, objv, "ENABLE"); + if( objc!=2 && objc!=3 ){ + Tcl_WrongNumArgs(interp, 1, objv, "ENABLE ?DEFAULT?"); return TCL_ERROR; } if( Tcl_GetBooleanFromObj(interp, objv[1], &isEnable) ){ return TCL_ERROR; } + if( objc==3 && Tcl_GetBooleanFromObj(interp, objv[2], &isDefault) ){ + return TCL_ERROR; + } if( (isEnable && crashVfs.pAppData) || (!isEnable && !crashVfs.pAppData) ){ return TCL_OK; @@ -880,7 +885,7 @@ static int SQLITE_TCLAPI crashEnableCmd( crashVfs.mxPathname = pOriginalVfs->mxPathname; crashVfs.pAppData = (void *)pOriginalVfs; crashVfs.szOsFile = sizeof(CrashFile) + pOriginalVfs->szOsFile; - sqlite3_vfs_register(&crashVfs, 0); + sqlite3_vfs_register(&crashVfs, isDefault); }else{ crashVfs.pAppData = 0; sqlite3_vfs_unregister(&crashVfs); diff --git a/test/tester.tcl b/test/tester.tcl index 1da89fec26..dc6547d033 100644 --- a/test/tester.tcl +++ b/test/tester.tcl @@ -1533,6 +1533,7 @@ proc crashsql {args} { set tclbody {} set crashfile "" set dc "" + set dfltvfs 0 set sql [lindex $args end] for {set ii 0} {$ii < [llength $args]-1} {incr ii 2} { @@ -1546,7 +1547,8 @@ proc crashsql {args} { elseif {$n>1 && [string first $z -file]==0} {set crashfile $z2} \ elseif {$n>1 && [string first $z -tclbody]==0} {set tclbody $z2} \ elseif {$n>1 && [string first $z -blocksize]==0} {set blocksize "-s $z2" } \ - elseif {$n>1 && [string first $z -characteristics]==0} {set dc "-c {$z2}" } \ + elseif {$n>1 && [string first $z -characteristics]==0} {set dc "-c {$z2}" }\ + elseif {$n>1 && [string first $z -dfltvfs]==0} {set dfltvfs $z2 }\ else { error "Unrecognized option: $z" } } @@ -1560,7 +1562,7 @@ proc crashsql {args} { set cfile [string map {\\ \\\\} [file nativename [file join [get_pwd] $crashfile]]] set f [open crash.tcl w] - puts $f "sqlite3_crash_enable 1" + puts $f "sqlite3_crash_enable 1 $dfltvfs" puts $f "sqlite3_crashparams $blocksize $dc $crashdelay $cfile" puts $f "sqlite3_test_control_pending_byte $::sqlite_pending_byte" From 1d62a66230ddf0320d918283141b32bb8a3926ff Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 2 Mar 2017 16:56:48 +0000 Subject: [PATCH 1381/1484] Fix another RBU case similar to the previous. This one for systems where the sector-size is larger than the page-size. FossilOrigin-Name: 4012bb3aa91927156ba149caa4e5c622b0729d79 --- ext/rbu/rbucrash2.test | 11 ++++++++--- ext/rbu/rbuprogress.test | 2 ++ ext/rbu/sqlite3rbu.c | 34 +++++++++++++++++++++++++++++++--- manifest | 16 ++++++++-------- manifest.uuid | 2 +- 5 files changed, 50 insertions(+), 15 deletions(-) diff --git a/ext/rbu/rbucrash2.test b/ext/rbu/rbucrash2.test index 89c2535a93..5f2ba604d1 100644 --- a/ext/rbu/rbucrash2.test +++ b/ext/rbu/rbucrash2.test @@ -45,7 +45,12 @@ db_save_and_close proc do_rbu_crash_test2 {tn script} { - foreach f {test.db test.db2} { + foreach {f blksz} { + test.db 512 + test.db2 512 + test.db 4096 + test.db2 4096 + } { set bDone 0 for {set iDelay 1} {$bDone==0} {incr iDelay} { forcedelete test.db2 test.db2-journal test.db test.db-oal test.db-wal @@ -53,7 +58,7 @@ proc do_rbu_crash_test2 {tn script} { set res [ crashsql -file $f -delay $iDelay -tclbody $script -dflt 1 -opendb {} \ - -blocksize 512 {} + -blocksize $blksz {} ] set bDone 1 @@ -68,7 +73,7 @@ proc do_rbu_crash_test2 {tn script} { rbu close sqlite3 db test.db - do_execsql_test $tn.delay=$iDelay.f=$f { + do_execsql_test $tn.delay=$iDelay.f=$f.blksz=$blksz { PRAGMA integrity_check; } {ok} db close diff --git a/ext/rbu/rbuprogress.test b/ext/rbu/rbuprogress.test index af202829c1..078b3b0d30 100644 --- a/ext/rbu/rbuprogress.test +++ b/ext/rbu/rbuprogress.test @@ -40,6 +40,7 @@ proc create_rbu1 {filename} { do_execsql_test 1.0 { + PRAGMA page_size = 4096; CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c); } @@ -266,6 +267,7 @@ foreach bReopen {0 1} { do_test 3.$bReopen.1.0 { reset_db execsql { + PRAGMA page_size = 4096; CREATE TABLE t1(a INTEGER PRIMARY KEY, b); CREATE TABLE t2(a INTEGER PRIMARY KEY, b); CREATE TABLE t3(a INTEGER PRIMARY KEY, b); diff --git a/ext/rbu/sqlite3rbu.c b/ext/rbu/sqlite3rbu.c index 262f96ea3c..163a544259 100644 --- a/ext/rbu/sqlite3rbu.c +++ b/ext/rbu/sqlite3rbu.c @@ -356,6 +356,7 @@ struct sqlite3rbu { RbuObjIter objiter; /* Iterator for skipping through tbl/idx */ const char *zVfsName; /* Name of automatically created rbu vfs */ rbu_file *pTargetFd; /* File handle open on target db */ + int nPagePerSector; /* Pages per sector for pTargetFd */ i64 iOalSz; i64 nPhaseOneStep; @@ -2620,6 +2621,16 @@ static void rbuSetupCheckpoint(sqlite3rbu *p, RbuState *pState){ if( p->nFrame==0 || (pState && pState->iWalCksum!=p->iWalCksum) ){ p->rc = SQLITE_DONE; p->eStage = RBU_STAGE_DONE; + }else{ + int nSectorSize; + sqlite3_file *pDb = p->pTargetFd->pReal; + assert( p->nPagePerSector==0 ); + nSectorSize = pDb->pMethods->xSectorSize(pDb); + if( nSectorSize>p->pgsz ){ + p->nPagePerSector = nSectorSize / p->pgsz; + }else{ + p->nPagePerSector = 1; + } } } } @@ -3275,9 +3286,26 @@ int sqlite3rbu_step(sqlite3rbu *p){ p->rc = SQLITE_DONE; } }else{ - RbuFrame *pFrame = &p->aFrame[p->nStep]; - rbuCheckpointFrame(p, pFrame); - p->nStep++; + /* At one point the following block copied a single frame from the + ** wal file to the database file. So that one call to sqlite3rbu_step() + ** checkpointed a single frame. + ** + ** However, if the sector-size is larger than the page-size, and the + ** application calls sqlite3rbu_savestate() or close() immediately + ** after this step, then rbu_step() again, then a power failure occurs, + ** then the database page written here may be damaged. Work around + ** this by checkpointing frames until the next page in the aFrame[] + ** lies on a different disk sector to the current one. */ + u32 iSector; + do{ + RbuFrame *pFrame = &p->aFrame[p->nStep]; + iSector = (pFrame->iDbPage-1) / p->nPagePerSector; + rbuCheckpointFrame(p, pFrame); + p->nStep++; + }while( p->nStepnFrame + && iSector==((p->aFrame[p->nStep].iDbPage-1) / p->nPagePerSector) + && p->rc==SQLITE_OK + ); } p->nProgress++; } diff --git a/manifest b/manifest index 4ab87a35ed..ff786aa1dc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C When\ssaving\sthe\sstate\sof\san\sRBU\supdate\sin\sthe\sincremental-checkpoint\sphase,\nsync\sthe\sdatabase\sfile.\sOtherwise,\sif\sa\spower\sfailure\soccurs\sand\sthe\sRBU\nupdate\sresumed\sfollowing\ssystem\srecovery,\sthe\sdatabase\smay\sbecome\scorrupt. -D 2017-03-02T14:51:47.379 +C Fix\sanother\sRBU\scase\ssimilar\sto\sthe\sprevious.\sThis\sone\sfor\ssystems\swhere\sthe\nsector-size\sis\slarger\sthan\sthe\spage-size. +D 2017-03-02T16:56:48.085 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 @@ -250,7 +250,7 @@ F ext/rbu/rbuB.test c25bc325b8072a766e56bb76c001866b405925c2 F ext/rbu/rbuC.test efe47db508a0269b683cb2a1913a425ffd39a831 F ext/rbu/rbu_common.tcl a38e8e2d4a50fd6aaf151633714c1b1d2fae3ead F ext/rbu/rbucrash.test 8d2ed5d4b05fef6c00c2a6b5f7ead71fa172a695 -F ext/rbu/rbucrash2.test 7f3fe5d6d930be0965f27b49bdcdc8d4a078b73c +F ext/rbu/rbucrash2.test b2ecbdd7bb72c88bd217c65bd00dafa07f7f2d4d F ext/rbu/rbudiff.test 3e605cf624d00d04d0fb1316a3acec4fbe3b3ac5 F ext/rbu/rbudor.test 99b05cc0df613e962c2c8085cfb05686a09cf315 F ext/rbu/rbufault.test cc0be8d5d392d98b0c2d6a51be377ea989250a89 @@ -258,12 +258,12 @@ F ext/rbu/rbufault2.test 9a7f19edd6ea35c4c9f807d8a3db0a03a5670c06 F ext/rbu/rbufault3.test 54a399888ac4af44c68f9f58afbed23149428bca F ext/rbu/rbufault4.test 34e70701cbec51571ffbd9fbf9d4e0f2ec495ca7 F ext/rbu/rbufts.test 828cd689da825f0a7b7c53ffc1f6f7fdb6fa5bda -F ext/rbu/rbuprogress.test e3e25fb7622641b8f2df7c6b7a7eb6fddfc46a4b +F ext/rbu/rbuprogress.test 1849d4e0e50616edf5ce75ce7db86622e656b5cf F ext/rbu/rburesume.test 8acb77f4a422ff55acfcfc9cc15a5cb210b1de83 F ext/rbu/rbusave.test 0f43b6686084f426ddd040b878426452fd2c2f48 F ext/rbu/rbuvacuum.test 4a977447c15c2581ab668781d9ef4294382530e0 F ext/rbu/rbuvacuum2.test 2074ab14fe66e1c7e7210c62562650dcd215bbaa -F ext/rbu/sqlite3rbu.c 3c2dfd3f27a3ecc5f017ecf82d563b522bbc341a +F ext/rbu/sqlite3rbu.c cba23db39792175295b94ad0086825894b617921 F ext/rbu/sqlite3rbu.h 6fb6294c34a9ca93b5894a33bca530c6f08decba F ext/rbu/test_rbu.c 5aa22616afac6f71ebd3d9bc9bf1006cfabcca88 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 @@ -1560,7 +1560,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 29f54b899e5cf22ece98ab41c39c41d75a4b228d -R fd6b0917cff6359266006d6c00dd0a12 +P edee6a80e1cc7e6a2b8c3c7f76dd794fc8ab9a72 +R f72d0ed562c179232e2d4d139b6c6946 U dan -Z 1a59570e49a3b7cf84dd8025330375c8 +Z a85a6fd6f15328765626feb0d9a72fd7 diff --git a/manifest.uuid b/manifest.uuid index f24ae9a62a..b44fc2cacb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -edee6a80e1cc7e6a2b8c3c7f76dd794fc8ab9a72 \ No newline at end of file +4012bb3aa91927156ba149caa4e5c622b0729d79 \ No newline at end of file From 9715f7f033887a2c4ec09592e3668d5fc0d737bd Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 2 Mar 2017 23:40:21 +0000 Subject: [PATCH 1382/1484] Fix a bug in the 'start of ...' date/time modifiers when they follow a julian day number. Fix for ticket [6097cb92745327a1]. FossilOrigin-Name: 081dbcfb6d82528cefecb36c4491fa6e1a790b17 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/date.c | 1 + test/date.test | 10 ++++++++++ 4 files changed, 20 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index ff786aa1dc..8ace7675fd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sanother\sRBU\scase\ssimilar\sto\sthe\sprevious.\sThis\sone\sfor\ssystems\swhere\sthe\nsector-size\sis\slarger\sthan\sthe\spage-size. -D 2017-03-02T16:56:48.085 +C Fix\sa\sbug\sin\sthe\s'start\sof\s...'\sdate/time\smodifiers\swhen\sthey\sfollow\sa\njulian\sday\snumber.\s\sFix\sfor\sticket\s[6097cb92745327a1]. +D 2017-03-02T23:40:21.740 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 @@ -347,7 +347,7 @@ F src/build.c 51b473eec465f471d607b54e8dbc00751c3f8a1f F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c a9984df73898c042a5cfc8f9d8e7723d02bc35c9 -F src/date.c dc3f1391d9297f8c748132813aaffcb117090d6e +F src/date.c bb4db348be17903f4bbf2ef3cb208add874deab9 F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c 0d9d5549d42e79ce4d82ff1db1e6c81e36d2f67c F src/expr.c 8a29e9b72d4b642189999c41782cd6c5bc43512f @@ -637,7 +637,7 @@ F test/csv01.test e0ba3caaa57e4c667a0b45977689fb8082f14348 F test/ctime.test ff6c38e822459d6ca743c34901caf57740b08b54 F test/cursorhint.test 7bc346788390475e77a345da2b92270d04d35856 F test/cursorhint2.test 8457e93d97f665f23f97cdbc8477d16e3480331b -F test/date.test a6a5a48b90907bca9fbcc79a30be5a715c1ab2fc +F test/date.test e6da60d8ec399de43c076425fbe2eecbc90a31a4 F test/dbfuzz.c 73047c920d6210e5912c87cdffd9a1c281d4252e F test/dbselftest.c b2e6cfac59066dbcb7334b66304bb15a5508dd42 F test/dbstatus.test 73149851b3aff14fc6db478e58f9083a66422cf5 @@ -1560,7 +1560,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P edee6a80e1cc7e6a2b8c3c7f76dd794fc8ab9a72 -R f72d0ed562c179232e2d4d139b6c6946 -U dan -Z a85a6fd6f15328765626feb0d9a72fd7 +P 4012bb3aa91927156ba149caa4e5c622b0729d79 +R 106d75876c31ad808988639b89376fd6 +U drh +Z d7eafab06f2b8ece511ab9317c8fe2f8 diff --git a/manifest.uuid b/manifest.uuid index b44fc2cacb..9e61a74210 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4012bb3aa91927156ba149caa4e5c622b0729d79 \ No newline at end of file +081dbcfb6d82528cefecb36c4491fa6e1a790b17 \ No newline at end of file diff --git a/src/date.c b/src/date.c index a08248ce2f..6fc66385c5 100644 --- a/src/date.c +++ b/src/date.c @@ -748,6 +748,7 @@ static int parseModifier( p->validHMS = 1; p->h = p->m = 0; p->s = 0.0; + p->rawS = 0; p->validTZ = 0; p->validJD = 0; if( sqlite3_stricmp(z,"month")==0 ){ diff --git a/test/date.test b/test/date.test index 2d336e6c00..a9694f18ca 100644 --- a/test/date.test +++ b/test/date.test @@ -596,5 +596,15 @@ datetest 16.29 {datetime(5373484,'-176546 months')} NULL datetest 16.30 {datetime(5373484,'-14712 years')} {-4713-12-31 12:00:00} datetest 16.31 {datetime(5373484,'-14713 years')} NULL +# 2017-03-02: Wrong 'start of day' computation. +# https://www.sqlite.org/src/info/6097cb92745327a1 +# +datetest 17.1 {datetime(2457754, 'start of day')} {2016-12-31 00:00:00} +datetest 17.2 {datetime(2457828)} {2017-03-15 12:00:00} +datetest 17.3 {datetime(2457828,'start of day')} {2017-03-15 00:00:00} +datetest 17.4 {datetime(2457828,'start of month')} {2017-03-01 00:00:00} +datetest 17.5 {datetime(2457828,'start of year')} {2017-01-01 00:00:00} + + finish_test From 0e9b43ff853afe97b416e4bd3866f0d27ea985d8 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 3 Mar 2017 16:51:46 +0000 Subject: [PATCH 1383/1484] Before beginning an incremental checkpoint in RBU, sync the directory containing the target database file. This ensures that the new directory entry created by renaming the *-oal file to *-wal is synced to disk. FossilOrigin-Name: 915a9a28783fbb2f4c0794eb4264ce8c0b9d42f7 --- ext/rbu/sqlite3rbu.c | 7 +++++++ manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/ext/rbu/sqlite3rbu.c b/ext/rbu/sqlite3rbu.c index 163a544259..7dd232b4b5 100644 --- a/ext/rbu/sqlite3rbu.c +++ b/ext/rbu/sqlite3rbu.c @@ -2624,6 +2624,7 @@ static void rbuSetupCheckpoint(sqlite3rbu *p, RbuState *pState){ }else{ int nSectorSize; sqlite3_file *pDb = p->pTargetFd->pReal; + sqlite3_file *pWal = p->pTargetFd->pWalFd->pReal; assert( p->nPagePerSector==0 ); nSectorSize = pDb->pMethods->xSectorSize(pDb); if( nSectorSize>p->pgsz ){ @@ -2631,6 +2632,12 @@ static void rbuSetupCheckpoint(sqlite3rbu *p, RbuState *pState){ }else{ p->nPagePerSector = 1; } + + /* Call xSync() on the wal file. This causes SQLite to sync the + ** directory in which the target database and the wal file reside, in + ** case it has not been synced since the rename() call in + ** rbuMoveOalFile(). */ + p->rc = pWal->pMethods->xSync(pWal, SQLITE_SYNC_NORMAL); } } } diff --git a/manifest b/manifest index 8ace7675fd..b06ed90284 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sbug\sin\sthe\s'start\sof\s...'\sdate/time\smodifiers\swhen\sthey\sfollow\sa\njulian\sday\snumber.\s\sFix\sfor\sticket\s[6097cb92745327a1]. -D 2017-03-02T23:40:21.740 +C Before\sbeginning\san\sincremental\scheckpoint\sin\sRBU,\ssync\sthe\sdirectory\ncontaining\sthe\starget\sdatabase\sfile.\sThis\sensures\sthat\sthe\snew\sdirectory\sentry\ncreated\sby\srenaming\sthe\s*-oal\sfile\sto\s*-wal\sis\ssynced\sto\sdisk. +D 2017-03-03T16:51:46.903 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 @@ -263,7 +263,7 @@ F ext/rbu/rburesume.test 8acb77f4a422ff55acfcfc9cc15a5cb210b1de83 F ext/rbu/rbusave.test 0f43b6686084f426ddd040b878426452fd2c2f48 F ext/rbu/rbuvacuum.test 4a977447c15c2581ab668781d9ef4294382530e0 F ext/rbu/rbuvacuum2.test 2074ab14fe66e1c7e7210c62562650dcd215bbaa -F ext/rbu/sqlite3rbu.c cba23db39792175295b94ad0086825894b617921 +F ext/rbu/sqlite3rbu.c 2a89efba9eeba8e6c89a498dc195e8efbdde2694 F ext/rbu/sqlite3rbu.h 6fb6294c34a9ca93b5894a33bca530c6f08decba F ext/rbu/test_rbu.c 5aa22616afac6f71ebd3d9bc9bf1006cfabcca88 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 @@ -1560,7 +1560,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 4012bb3aa91927156ba149caa4e5c622b0729d79 -R 106d75876c31ad808988639b89376fd6 -U drh -Z d7eafab06f2b8ece511ab9317c8fe2f8 +P 081dbcfb6d82528cefecb36c4491fa6e1a790b17 +R c49d10bdecee819ceb83b85a5e3f8244 +U dan +Z 0d48f0e17be43a572b386c16c35f7b42 diff --git a/manifest.uuid b/manifest.uuid index 9e61a74210..91442ae413 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -081dbcfb6d82528cefecb36c4491fa6e1a790b17 \ No newline at end of file +915a9a28783fbb2f4c0794eb4264ce8c0b9d42f7 \ No newline at end of file From 30741eb0d3fb13221aab418d6c8c8922308be290 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 3 Mar 2017 20:02:53 +0000 Subject: [PATCH 1384/1484] Fix a case introduced by [4cd2a967] where a corrupt database could cause a buffer overwrite. FossilOrigin-Name: 5d0455fece514552ad7f283d56526f53d7c688bd --- manifest | 13 +++--- manifest.uuid | 2 +- src/btree.c | 17 ++++++- test/corruptK.test | 113 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 136 insertions(+), 9 deletions(-) create mode 100644 test/corruptK.test diff --git a/manifest b/manifest index b06ed90284..05070243d5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Before\sbeginning\san\sincremental\scheckpoint\sin\sRBU,\ssync\sthe\sdirectory\ncontaining\sthe\starget\sdatabase\sfile.\sThis\sensures\sthat\sthe\snew\sdirectory\sentry\ncreated\sby\srenaming\sthe\s*-oal\sfile\sto\s*-wal\sis\ssynced\sto\sdisk. -D 2017-03-03T16:51:46.903 +C Fix\sa\scase\sintroduced\sby\s[4cd2a967]\swhere\sa\scorrupt\sdatabase\scould\scause\sa\sbuffer\soverwrite. +D 2017-03-03T20:02:53.439 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 @@ -340,7 +340,7 @@ F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792 F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca -F src/btree.c 03149b0f3fec3c1aa3c50a17e997bb442b867632 +F src/btree.c 91baade79832becb44d85cd7c39b5ebe170666d8 F src/btree.h e6d352808956ec163a17f832193a3e198b3fb0ac F src/btreeInt.h cd55d39d9916270837a88c12e701047cba0729b0 F src/build.c 51b473eec465f471d607b54e8dbc00751c3f8a1f @@ -618,6 +618,7 @@ F test/corruptG.test adf79b669cbfd19e28c8191a610d083ae53a6d51 F test/corruptH.test 79801d97ec5c2f9f3c87739aa1ec2eb786f96454 F test/corruptI.test 075fe1d75aa1d84e2949be56b6264376c41502e4 F test/corruptJ.test 4d5ccc4bf959464229a836d60142831ef76a5aa4 +F test/corruptK.test 814a59ec699d8546b4e29005fba3d16e933ef2fe F test/cost.test 1eedbfd868f806f3fa08ff072b04cf270dcf61c8 F test/count.test cb2e0f934c6eb33670044520748d2ecccd46259c F test/coveridxscan.test b629e896b14df2f000a99b8d170d80589c46562c @@ -1560,7 +1561,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 081dbcfb6d82528cefecb36c4491fa6e1a790b17 -R c49d10bdecee819ceb83b85a5e3f8244 +P 915a9a28783fbb2f4c0794eb4264ce8c0b9d42f7 +R 87fee79fc77f11db6d08a83e962c36d1 U dan -Z 0d48f0e17be43a572b386c16c35f7b42 +Z d96b298a9dab6e01e07206495b42117b diff --git a/manifest.uuid b/manifest.uuid index 91442ae413..a7791d4715 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -915a9a28783fbb2f4c0794eb4264ce8c0b9d42f7 \ No newline at end of file +5d0455fece514552ad7f283d56526f53d7c688bd \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index bf65852fe6..e942dbce03 100644 --- a/src/btree.c +++ b/src/btree.c @@ -1355,6 +1355,7 @@ static int defragmentPage(MemPage *pPage, int nMaxFrag){ nCell = pPage->nCell; assert( nCell==get2byte(&data[hdr+3]) ); iCellFirst = cellOffset + 2*nCell; + usableSize = pPage->pBt->usableSize; /* This block handles pages with two or fewer free blocks and nMaxFrag ** or fewer fragmented bytes. In this case it is faster to move the @@ -1365,6 +1366,17 @@ static int defragmentPage(MemPage *pPage, int nMaxFrag){ int iFree = get2byte(&data[hdr+1]); if( iFree ){ int iFree2 = get2byte(&data[iFree]); + + /* pageFindSlot() has already verified that free blocks are sorted + ** in order of offset within the page, and that no block extends + ** past the end of the page. Provided the two free slots do not + ** overlap, this guarantees that the memmove() calls below will not + ** overwrite the usableSize byte buffer, even if the database page + ** is corrupt. */ + assert( iFree2==0 || iFree2>iFree ); + assert( iFree+get2byte(&data[iFree+2]) <= usableSize ); + assert( iFree2==0 || iFree2+get2byte(&data[iFree2+2]) <= usableSize ); + if( 0==iFree2 || (data[iFree2]==0 && data[iFree2+1]==0) ){ u8 *pEnd = &data[cellOffset + nCell*2]; u8 *pAddr; @@ -1372,11 +1384,14 @@ static int defragmentPage(MemPage *pPage, int nMaxFrag){ int sz = get2byte(&data[iFree+2]); int top = get2byte(&data[hdr+5]); if( iFree2 ){ + if( iFree+sz>iFree2 ) return SQLITE_CORRUPT_BKPT; sz2 = get2byte(&data[iFree2+2]); + assert( iFree+sz+sz2+iFree2-(iFree+sz) <= usableSize ); memmove(&data[iFree+sz+sz2], &data[iFree+sz], iFree2-(iFree+sz)); sz += sz2; } cbrk = top+sz; + assert( cbrk+(iFree-top) <= usableSize ); memmove(&data[cbrk], &data[top], iFree-top); for(pAddr=&data[cellOffset]; pAddrpBt->usableSize; cbrk = usableSize; iCellLast = usableSize - 4; - for(i=0; i Date: Fri, 3 Mar 2017 20:43:43 +0000 Subject: [PATCH 1385/1484] Fix another corner-case for the 'start of ...' modifier in the date/time functions. Related to ticket [6097cb92745327a1]. FossilOrigin-Name: 8831f4393dda42b3434e7767968caea84bbca2af --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/date.c | 1 + test/date.test | 2 ++ 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 05070243d5..30c7196c3f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\scase\sintroduced\sby\s[4cd2a967]\swhere\sa\scorrupt\sdatabase\scould\scause\sa\sbuffer\soverwrite. -D 2017-03-03T20:02:53.439 +C Fix\sanother\scorner-case\sfor\sthe\s'start\sof\s...'\smodifier\sin\sthe\sdate/time\nfunctions.\s\sRelated\sto\sticket\s[6097cb92745327a1]. +D 2017-03-03T20:43:43.649 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 @@ -347,7 +347,7 @@ F src/build.c 51b473eec465f471d607b54e8dbc00751c3f8a1f F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c a9984df73898c042a5cfc8f9d8e7723d02bc35c9 -F src/date.c bb4db348be17903f4bbf2ef3cb208add874deab9 +F src/date.c 499343d9cd97fb0c13ec299dbd1ff3d787b1cdac F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c 0d9d5549d42e79ce4d82ff1db1e6c81e36d2f67c F src/expr.c 8a29e9b72d4b642189999c41782cd6c5bc43512f @@ -638,7 +638,7 @@ F test/csv01.test e0ba3caaa57e4c667a0b45977689fb8082f14348 F test/ctime.test ff6c38e822459d6ca743c34901caf57740b08b54 F test/cursorhint.test 7bc346788390475e77a345da2b92270d04d35856 F test/cursorhint2.test 8457e93d97f665f23f97cdbc8477d16e3480331b -F test/date.test e6da60d8ec399de43c076425fbe2eecbc90a31a4 +F test/date.test 9b73bbeb1b82d9c1f44dec5cf563bf7da58d2373 F test/dbfuzz.c 73047c920d6210e5912c87cdffd9a1c281d4252e F test/dbselftest.c b2e6cfac59066dbcb7334b66304bb15a5508dd42 F test/dbstatus.test 73149851b3aff14fc6db478e58f9083a66422cf5 @@ -1561,7 +1561,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 915a9a28783fbb2f4c0794eb4264ce8c0b9d42f7 -R 87fee79fc77f11db6d08a83e962c36d1 -U dan -Z d96b298a9dab6e01e07206495b42117b +P 5d0455fece514552ad7f283d56526f53d7c688bd +R 7ede60c220c81f4f24b446e38f3b85e3 +U drh +Z 2f7d593b5303445a6b7dc1a2027118f1 diff --git a/manifest.uuid b/manifest.uuid index a7791d4715..74049a1b57 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5d0455fece514552ad7f283d56526f53d7c688bd \ No newline at end of file +8831f4393dda42b3434e7767968caea84bbca2af \ No newline at end of file diff --git a/src/date.c b/src/date.c index 6fc66385c5..c3ce4248c2 100644 --- a/src/date.c +++ b/src/date.c @@ -743,6 +743,7 @@ static int parseModifier( ** or month or year. */ if( sqlite3_strnicmp(z, "start of ", 9)!=0 ) break; + if( !p->validJD && !p->validYMD && !p->validHMS ) break; z += 9; computeYMD(p); p->validHMS = 1; diff --git a/test/date.test b/test/date.test index a9694f18ca..f002334d17 100644 --- a/test/date.test +++ b/test/date.test @@ -604,6 +604,8 @@ datetest 17.2 {datetime(2457828)} {2017-03-15 12:00:00} datetest 17.3 {datetime(2457828,'start of day')} {2017-03-15 00:00:00} datetest 17.4 {datetime(2457828,'start of month')} {2017-03-01 00:00:00} datetest 17.5 {datetime(2457828,'start of year')} {2017-01-01 00:00:00} +datetest 17.6 {datetime(37,'start of year')} NULL +datetest 17.7 {datetime(38,'start of year')} {-4712-01-01 00:00:00} From f3f883fcd735b65bdf5f29790512276e5d7746ba Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 3 Mar 2017 21:36:26 +0000 Subject: [PATCH 1386/1484] Remove an redundant function call from the date/time function implementation. FossilOrigin-Name: 4a04c48a311b19ba5e566877dc5baff543c41aba --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/date.c | 1 - 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 30c7196c3f..7865de9c71 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sanother\scorner-case\sfor\sthe\s'start\sof\s...'\smodifier\sin\sthe\sdate/time\nfunctions.\s\sRelated\sto\sticket\s[6097cb92745327a1]. -D 2017-03-03T20:43:43.649 +C Remove\san\sredundant\sfunction\scall\sfrom\sthe\sdate/time\sfunction\simplementation. +D 2017-03-03T21:36:26.906 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 @@ -347,7 +347,7 @@ F src/build.c 51b473eec465f471d607b54e8dbc00751c3f8a1f F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c a9984df73898c042a5cfc8f9d8e7723d02bc35c9 -F src/date.c 499343d9cd97fb0c13ec299dbd1ff3d787b1cdac +F src/date.c ee676e7694dfadbdd2fde1a258a71be8360ba5ae F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c 0d9d5549d42e79ce4d82ff1db1e6c81e36d2f67c F src/expr.c 8a29e9b72d4b642189999c41782cd6c5bc43512f @@ -1561,7 +1561,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 5d0455fece514552ad7f283d56526f53d7c688bd -R 7ede60c220c81f4f24b446e38f3b85e3 +P 8831f4393dda42b3434e7767968caea84bbca2af +R d8b3a18d4fd999381a3209784f6b834e U drh -Z 2f7d593b5303445a6b7dc1a2027118f1 +Z 55613e922149954b91d38c0de9685f66 diff --git a/manifest.uuid b/manifest.uuid index 74049a1b57..637cd06ca0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8831f4393dda42b3434e7767968caea84bbca2af \ No newline at end of file +4a04c48a311b19ba5e566877dc5baff543c41aba \ No newline at end of file diff --git a/src/date.c b/src/date.c index c3ce4248c2..b49d506bc4 100644 --- a/src/date.c +++ b/src/date.c @@ -756,7 +756,6 @@ static int parseModifier( p->D = 1; rc = 0; }else if( sqlite3_stricmp(z,"year")==0 ){ - computeYMD(p); p->M = 1; p->D = 1; rc = 0; From 2996796dcf2a01df4cacf94f3c8efd430db9a82d Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 3 Mar 2017 21:51:40 +0000 Subject: [PATCH 1387/1484] If a reprepare is needed after binding to a variable with a number larger than 32, set only the high-order bit of the Vdbe.expmask rather than setting all bits. This could potentially result in fewer false-positive reprepares. FossilOrigin-Name: 45797feefe90cb7da53256b0c42fdaa1221d0a27 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/vdbeapi.c | 2 +- src/vdbeaux.c | 4 ++-- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 7865de9c71..084b50ff08 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\san\sredundant\sfunction\scall\sfrom\sthe\sdate/time\sfunction\simplementation. -D 2017-03-03T21:36:26.906 +C If\sa\sreprepare\sis\sneeded\safter\sbinding\sto\sa\svariable\swith\sa\snumber\slarger\nthan\s32,\sset\sonly\sthe\shigh-order\sbit\sof\sthe\sVdbe.expmask\srather\sthan\ssetting\nall\sbits.\s\sThis\scould\spotentially\sresult\sin\sfewer\sfalse-positive\sreprepares. +D 2017-03-03T21:51:40.099 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 @@ -467,8 +467,8 @@ F src/vacuum.c 1fe4555cd8c9b263afb85b5b4ee3a4a4181ad569 F src/vdbe.c 83f387d9e6842b1dc99f6e85bb577c5bbc4e397d F src/vdbe.h 59998ffd71d7caa8886bc78dafaf8caeccd4c13c F src/vdbeInt.h 4e4b15b2e1330e1636e4e01974eab2b0b985092f -F src/vdbeapi.c 70aabe108c411e529a59d8800445513965334062 -F src/vdbeaux.c b632f9151a296c5eb22a2cc955c487ebc2347cb6 +F src/vdbeapi.c 5b08d82592bcff4470601fe78aaabebd50837860 +F src/vdbeaux.c 57361f2e761d92a254638bdbfc03fc68ae6aebc6 F src/vdbeblob.c 359891617358deefc85bef7bcf787fa6b77facb9 F src/vdbemem.c 3b5a9a5b375458d3e12a50ae1aaa41eeec2175fd F src/vdbesort.c eda25cb2d1727efca6f7862fea32b8aa33c0face @@ -1561,7 +1561,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 8831f4393dda42b3434e7767968caea84bbca2af -R d8b3a18d4fd999381a3209784f6b834e +P 4a04c48a311b19ba5e566877dc5baff543c41aba +R 637ce5713001d3d9ffad62c9c4caff88 U drh -Z 55613e922149954b91d38c0de9685f66 +Z 435b5c3ba7edfd2dba5c4b61417da7dd diff --git a/manifest.uuid b/manifest.uuid index 637cd06ca0..9ee7804d61 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4a04c48a311b19ba5e566877dc5baff543c41aba \ No newline at end of file +45797feefe90cb7da53256b0c42fdaa1221d0a27 \ No newline at end of file diff --git a/src/vdbeapi.c b/src/vdbeapi.c index 3d9bcca99f..1f2699dc4d 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -1260,7 +1260,7 @@ static int vdbeUnbind(Vdbe *p, int i){ ** following any change to the bindings of that parameter. */ assert( p->isPrepareV2 || p->expmask==0 ); - if( p->expmask & ((u32)1 << (i&0x001F)) && (i<32 || p->expmask==0xffffffff) ){ + if( p->expmask!=0 && (p->expmask & (i>=31 ? 0x80000000 : (u32)1<expired = 1; } return SQLITE_OK; diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 8a19c26003..ab4aad7a0f 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -4552,8 +4552,8 @@ sqlite3_value *sqlite3VdbeGetBoundValue(Vdbe *v, int iVar, u8 aff){ */ void sqlite3VdbeSetVarmask(Vdbe *v, int iVar){ assert( iVar>0 ); - if( iVar>32 ){ - v->expmask = 0xffffffff; + if( iVar>=32 ){ + v->expmask |= 0x80000000; }else{ v->expmask |= ((u32)1 << (iVar-1)); } From e1f1c0802cb9644cdb23df28a7b76fe71095f492 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 6 Mar 2017 20:44:13 +0000 Subject: [PATCH 1388/1484] Fix a typo in a comment. No changes to code. FossilOrigin-Name: ec529bf11b16c801ea438e57d208ff7e4cedf1f9 --- manifest | 13 ++++++------- manifest.uuid | 2 +- src/pragma.c | 2 +- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 6e1234fc69..98be82eb72 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\san\sinitial\simplementation\sof\sthe\s"PRAGMA\soptimize"\scommand. -D 2017-03-06T17:33:58.293 +C Fix\sa\stypo\sin\sa\scomment.\s\sNo\schanges\sto\scode. +D 2017-03-06T20:44:13.809 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 @@ -390,7 +390,7 @@ F src/parse.y af8830094f4aecb91cb69721f3601ad10c36abc4 F src/pcache.c 62835bed959e2914edd26afadfecce29ece0e870 F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 F src/pcache1.c e3967219b2a92b9edcb9324a4ba75009090d3953 -F src/pragma.c 75fdb05838c303cf0ce5846ca011b8103531c42c +F src/pragma.c d4aef42083d2d60760a736f758276638b976b702 F src/pragma.h c9c763958fec92b04125571472c9500b351c5f7f F src/prepare.c b1140c3d0cf59bc85ace00ce363153041b424b7a F src/printf.c 67427bbee66d891fc6f6f5aada857e9cdb368c1c @@ -1562,8 +1562,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 45797feefe90cb7da53256b0c42fdaa1221d0a27 5f7fc79aa06ca9b79664c50c3c277c98a74ff9a0 -R d076238fa06701bd917c02e95912d525 -T +closed 5f7fc79aa06ca9b79664c50c3c277c98a74ff9a0 +P 137aeb2b160888100bc1e871b00860149e5f6196 +R f69eaa0284279e87544348aa447b8b6c U drh -Z 60608bb3fd59af1c228de2bc78db17f1 +Z 0247be1d8d37c820f7663badba92934a diff --git a/manifest.uuid b/manifest.uuid index c68e3d13a8..75989adcda 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -137aeb2b160888100bc1e871b00860149e5f6196 \ No newline at end of file +ec529bf11b16c801ea438e57d208ff7e4cedf1f9 \ No newline at end of file diff --git a/src/pragma.c b/src/pragma.c index c5f2a77eef..aa7ebc8793 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -1871,7 +1871,7 @@ void sqlite3Pragma( ** Attempt to optimize the database. All schemas are optimized in the first ** two forms, and only the specified schema is optimized in the latter two. ** - ** The details of optimizations performed by this pragma does are expected + ** The details of optimizations performed by this pragma are expected ** to change and improve over time. Applications should anticipate that ** this pragma will perform new optimizations in future releases. ** From 59dbe3a5efcd5ea47ef6038a861dc4d76838a43f Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 6 Mar 2017 23:51:16 +0000 Subject: [PATCH 1389/1484] Make the default MASK argument for "PRAGMA optimize" be 0xfffe, to allow for future expansion of up to 14 new default-on optimizations. FossilOrigin-Name: 73019a8bba29fd07f73559cd00d5346fa822b439 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/pragma.c | 10 +++++----- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 98be82eb72..6a2079f2af 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\stypo\sin\sa\scomment.\s\sNo\schanges\sto\scode. -D 2017-03-06T20:44:13.809 +C Make\sthe\sdefault\sMASK\sargument\sfor\s"PRAGMA\soptimize"\sbe\s0xfffe,\sto\sallow\sfor\nfuture\sexpansion\sof\sup\sto\s14\snew\sdefault-on\soptimizations. +D 2017-03-06T23:51:16.804 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 @@ -390,7 +390,7 @@ F src/parse.y af8830094f4aecb91cb69721f3601ad10c36abc4 F src/pcache.c 62835bed959e2914edd26afadfecce29ece0e870 F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 F src/pcache1.c e3967219b2a92b9edcb9324a4ba75009090d3953 -F src/pragma.c d4aef42083d2d60760a736f758276638b976b702 +F src/pragma.c b7bf4f1dd9cdcdd3f72f0bdbce3502d69d0f48ba F src/pragma.h c9c763958fec92b04125571472c9500b351c5f7f F src/prepare.c b1140c3d0cf59bc85ace00ce363153041b424b7a F src/printf.c 67427bbee66d891fc6f6f5aada857e9cdb368c1c @@ -1562,7 +1562,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 137aeb2b160888100bc1e871b00860149e5f6196 -R f69eaa0284279e87544348aa447b8b6c +P ec529bf11b16c801ea438e57d208ff7e4cedf1f9 +R 299bd0d883e4720337a781b64978238c U drh -Z 0247be1d8d37c820f7663badba92934a +Z 84b44db3e09ed739373a73b84fb9456e diff --git a/manifest.uuid b/manifest.uuid index 75989adcda..94998487fc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ec529bf11b16c801ea438e57d208ff7e4cedf1f9 \ No newline at end of file +73019a8bba29fd07f73559cd00d5346fa822b439 \ No newline at end of file diff --git a/src/pragma.c b/src/pragma.c index aa7ebc8793..2901f4bdc5 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -1892,10 +1892,10 @@ void sqlite3Pragma( ** 0x0008 (Not yet implemented) Create indexes that might have ** been helpful to recent queries ** - ** The default MASK is 0x000e, which means perform all of the optimizations - ** listed above except do not set Debug Mode. New optimizations may be - ** added in future releases but they will be turned off by default. The - ** default MASK will always be 0x0e. + ** The default MASK is and always shall be 0xfffe. 0xfffe means perform all ** of the optimizations listed above except Debug Mode, including new + ** optimizations that have not yet been invented. If new optimizations are + ** ever added that should be off by default, those off-by-default + ** optimizations will have bitmasks of 0x10000 or larger. ** ** DETERMINATION OF WHEN TO RUN ANALYZE ** @@ -1930,7 +1930,7 @@ void sqlite3Pragma( opMask = (u32)sqlite3Atoi(zRight); if( (opMask & 0x02)==0 ) break; }else{ - opMask = 0xe; + opMask = 0xfffe; } iTabCur = pParse->nTab++; for(iDbLast = zDb?iDb:db->nDb-1; iDb<=iDbLast; iDb++){ From 3cf48e3e89ff34d61436751d5a47f15eba570b8a Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 7 Mar 2017 03:25:52 +0000 Subject: [PATCH 1390/1484] Small size reduction and performance increase in the name resolver routine for expressions. FossilOrigin-Name: 1a3554e1d71b666325ff377fae5329d79ce5c05f --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/parse.y | 2 +- src/resolve.c | 39 ++++++++++++++++++++++----------------- 4 files changed, 31 insertions(+), 26 deletions(-) diff --git a/manifest b/manifest index 6a2079f2af..7a5b12b81f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\sthe\sdefault\sMASK\sargument\sfor\s"PRAGMA\soptimize"\sbe\s0xfffe,\sto\sallow\sfor\nfuture\sexpansion\sof\sup\sto\s14\snew\sdefault-on\soptimizations. -D 2017-03-06T23:51:16.804 +C Small\ssize\sreduction\sand\sperformance\sincrease\sin\sthe\sname\sresolver\sroutine\nfor\sexpressions. +D 2017-03-07T03:25:52.677 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 @@ -386,7 +386,7 @@ F src/os_win.c 2a6c73eef01c51a048cc4ddccd57f981afbec18a F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c ff1232b3088a39806035ecfac4fffeb22717d80b F src/pager.h f2a99646c5533ffe11afa43e9e0bea74054e4efa -F src/parse.y af8830094f4aecb91cb69721f3601ad10c36abc4 +F src/parse.y 48b03113704ee8bd78ee6996d81de7fbee22e105 F src/pcache.c 62835bed959e2914edd26afadfecce29ece0e870 F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 F src/pcache1.c e3967219b2a92b9edcb9324a4ba75009090d3953 @@ -395,7 +395,7 @@ F src/pragma.h c9c763958fec92b04125571472c9500b351c5f7f F src/prepare.c b1140c3d0cf59bc85ace00ce363153041b424b7a F src/printf.c 67427bbee66d891fc6f6f5aada857e9cdb368c1c F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 -F src/resolve.c f9bc0de45a30a450da47b3766de00be89bf9be79 +F src/resolve.c 3fd6fdb3666f24bbcc15039031d0b19a5e53c901 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c d12f3539f80db38b09015561b569e0eb1c4b6c5f F src/shell.c 27d2b31099fd2cd749e44d025ef9b54ca26692cb @@ -1562,7 +1562,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ec529bf11b16c801ea438e57d208ff7e4cedf1f9 -R 299bd0d883e4720337a781b64978238c +P 73019a8bba29fd07f73559cd00d5346fa822b439 +R 1209553f688221f7757a0938ef904e6c U drh -Z 84b44db3e09ed739373a73b84fb9456e +Z 582428290c16e3af0ac541cc18ae2bc9 diff --git a/manifest.uuid b/manifest.uuid index 94998487fc..7407f18c83 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -73019a8bba29fd07f73559cd00d5346fa822b439 \ No newline at end of file +1a3554e1d71b666325ff377fae5329d79ce5c05f \ No newline at end of file diff --git a/src/parse.y b/src/parse.y index 0949e97d16..ef9d3dd0ec 100644 --- a/src/parse.y +++ b/src/parse.y @@ -899,7 +899,7 @@ term(A) ::= INTEGER(X). { A.pExpr = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &X, 1); A.zStart = X.z; A.zEnd = X.z + X.n; - if( A.pExpr ) A.pExpr->flags |= EP_Leaf; + if( A.pExpr ) A.pExpr->flags |= EP_Leaf|EP_Resolved; } expr(A) ::= VARIABLE(X). { if( !(X.z[0]=='#' && sqlite3Isdigit(X.z[1])) ){ diff --git a/src/resolve.c b/src/resolve.c index 7d89b6fec5..59157996c5 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -608,33 +608,38 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ #endif /* defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY) */ - /* A lone identifier is the name of a column. - */ - case TK_ID: { - return lookupName(pParse, 0, 0, pExpr->u.zToken, pNC, pExpr); - } - - /* A table name and column name: ID.ID + /* A column name: ID + ** Or table name and column name: ID.ID ** Or a database, table and column: ID.ID.ID + ** + ** The TK_ID and TK_OUT cases are combined so that there will only + ** be one call to lookupName(). Then the compiler will in-line + ** lookupName() for a size reduction and performance increase. */ + case TK_ID: case TK_DOT: { const char *zColumn; const char *zTable; const char *zDb; Expr *pRight; - /* if( pSrcList==0 ) break; */ - notValid(pParse, pNC, "the \".\" operator", NC_IdxExpr); - pRight = pExpr->pRight; - if( pRight->op==TK_ID ){ + if( pExpr->op==TK_ID ){ zDb = 0; - zTable = pExpr->pLeft->u.zToken; - zColumn = pRight->u.zToken; + zTable = 0; + zColumn = pExpr->u.zToken; }else{ - assert( pRight->op==TK_DOT ); - zDb = pExpr->pLeft->u.zToken; - zTable = pRight->pLeft->u.zToken; - zColumn = pRight->pRight->u.zToken; + notValid(pParse, pNC, "the \".\" operator", NC_IdxExpr); + pRight = pExpr->pRight; + if( pRight->op==TK_ID ){ + zDb = 0; + zTable = pExpr->pLeft->u.zToken; + zColumn = pRight->u.zToken; + }else{ + assert( pRight->op==TK_DOT ); + zDb = pExpr->pLeft->u.zToken; + zTable = pRight->pLeft->u.zToken; + zColumn = pRight->pRight->u.zToken; + } } return lookupName(pParse, zDb, zTable, zColumn, pNC, pExpr); } From a92b81f487d8f71ef460817be8f4838e9f13816b Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 7 Mar 2017 03:40:48 +0000 Subject: [PATCH 1391/1484] More size and speed improvements in the expression name resolver. FossilOrigin-Name: e0a3d39f51a50420bae97e2bc9a8c01a5b0d3db8 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/resolve.c | 13 +++++++------ 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 7a5b12b81f..e3370f8805 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Small\ssize\sreduction\sand\sperformance\sincrease\sin\sthe\sname\sresolver\sroutine\nfor\sexpressions. -D 2017-03-07T03:25:52.677 +C More\ssize\sand\sspeed\simprovements\sin\sthe\sexpression\sname\sresolver. +D 2017-03-07T03:40:48.199 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 @@ -395,7 +395,7 @@ F src/pragma.h c9c763958fec92b04125571472c9500b351c5f7f F src/prepare.c b1140c3d0cf59bc85ace00ce363153041b424b7a F src/printf.c 67427bbee66d891fc6f6f5aada857e9cdb368c1c F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 -F src/resolve.c 3fd6fdb3666f24bbcc15039031d0b19a5e53c901 +F src/resolve.c 3e518b962d932a997fae373366880fc028c75706 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c d12f3539f80db38b09015561b569e0eb1c4b6c5f F src/shell.c 27d2b31099fd2cd749e44d025ef9b54ca26692cb @@ -1562,7 +1562,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 73019a8bba29fd07f73559cd00d5346fa822b439 -R 1209553f688221f7757a0938ef904e6c +P 1a3554e1d71b666325ff377fae5329d79ce5c05f +R 5deac8a39ddd88b8493847a75a8da44a U drh -Z 582428290c16e3af0ac541cc18ae2bc9 +Z bf228925fa0c3d0f27c143e7173a6889 diff --git a/manifest.uuid b/manifest.uuid index 7407f18c83..9f3f1bbd0a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1a3554e1d71b666325ff377fae5329d79ce5c05f \ No newline at end of file +e0a3d39f51a50420bae97e2bc9a8c01a5b0d3db8 \ No newline at end of file diff --git a/src/resolve.c b/src/resolve.c index 59157996c5..6b3caa625a 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -229,7 +229,8 @@ static int lookupName( } /* Start at the inner-most context and move outward until a match is found */ - while( pNC && cnt==0 ){ + assert( pNC && cnt==0 ); + do{ ExprList *pEList; SrcList *pSrcList = pNC->pSrcList; @@ -414,11 +415,11 @@ static int lookupName( /* Advance to the next name context. The loop will exit when either ** we have a match (cnt>0) or when we run out of name contexts. */ - if( cnt==0 ){ - pNC = pNC->pNext; - nSubquery++; - } - } + if( cnt ) break; + pNC = pNC->pNext; + nSubquery++; + }while( pNC ); + /* ** If X and Y are NULL (in other words if only the column name Z is From 567bd44917bd5e7553d6a38b6eb51429422f5b37 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 7 Mar 2017 12:18:23 +0000 Subject: [PATCH 1392/1484] Minor comment typo fixes. No changes to code. FossilOrigin-Name: 01cd9fb176cde30658233e36aad44e4a5519612e --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/walker.c | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index e3370f8805..a4690fef93 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C More\ssize\sand\sspeed\simprovements\sin\sthe\sexpression\sname\sresolver. -D 2017-03-07T03:40:48.199 +C Minor\scomment\stypo\sfixes.\s\sNo\schanges\sto\scode. +D 2017-03-07T12:18:23.791 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 @@ -477,7 +477,7 @@ F src/vtab.c 007513c2ef52472fcdea6a741683d50662e82790 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 40c543f0a2195d1b0dc88ef12142bea690009344 F src/wal.h 06b2a0b599cc0f53ea97f497cf8c6b758c999f71 -F src/walker.c 91a6df7435827e41cff6bb7df50ea00934ee78b0 +F src/walker.c b71a992b413b3a022572eccf29ef4b4890223791 F src/where.c 1a3a8adb717a20f17c186f3baa22b0b5f3a5ab13 F src/whereInt.h 2d50c2b74a33be44cb68fdecee30b4d93552f1f4 F src/wherecode.c 677e95413c472c0b413023b6b69a47f40fce1b04 @@ -1562,7 +1562,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 1a3554e1d71b666325ff377fae5329d79ce5c05f -R 5deac8a39ddd88b8493847a75a8da44a +P e0a3d39f51a50420bae97e2bc9a8c01a5b0d3db8 +R 3a57497a1a3fd47f649c0fa2a10dc005 U drh -Z bf228925fa0c3d0f27c143e7173a6889 +Z 8979ee765002edd7cbb3fe90b0cd803b diff --git a/manifest.uuid b/manifest.uuid index 9f3f1bbd0a..daf8551ff8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e0a3d39f51a50420bae97e2bc9a8c01a5b0d3db8 \ No newline at end of file +01cd9fb176cde30658233e36aad44e4a5519612e \ No newline at end of file diff --git a/src/walker.c b/src/walker.c index d1b1e96a2d..a7123d8ab0 100644 --- a/src/walker.c +++ b/src/walker.c @@ -27,11 +27,11 @@ ** ** WRC_Continue Continue descending down the tree. ** -** WRC_Prune Do not descend into child nodes. But allow +** WRC_Prune Do not descend into child nodes, but allow ** the walk to continue with sibling nodes. ** ** WRC_Abort Do no more callbacks. Unwind the stack and -** return the top-level walk call. +** return from the top-level walk call. ** ** The return value from this routine is WRC_Abort to abandon the tree walk ** and WRC_Continue to continue. From 9b38d6660f08c01afc8f6fcc86548ce3167acf21 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 7 Mar 2017 14:38:52 +0000 Subject: [PATCH 1393/1484] Performance optimization in the tokenizer/parser loop. FossilOrigin-Name: 2cb71583d631cd417acbeebbb4ee950573a9deef --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/tokenize.c | 23 ++++++++++++----------- 3 files changed, 19 insertions(+), 18 deletions(-) diff --git a/manifest b/manifest index a4690fef93..11e8d7020b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Minor\scomment\stypo\sfixes.\s\sNo\schanges\sto\scode. -D 2017-03-07T12:18:23.791 +C Performance\soptimization\sin\sthe\stokenizer/parser\sloop. +D 2017-03-07T14:38:52.463 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 @@ -457,7 +457,7 @@ F src/test_windirent.c 17f91f5f2aa1bb7328abb49414c363b5d2a9d3ff F src/test_windirent.h 5d67483a55442e31e1bde0f4a230e6e932ad5906 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c -F src/tokenize.c 25ccc63ae2c4163933221f3181c9982b47cd08d2 +F src/tokenize.c dc748c5afcb9e5beb3ef5651bc99a4622e30f6a1 F src/treeview.c 4e44ade3bfe59d82005039f72e09333ce2b4162c F src/trigger.c c9f0810043b265724fdb1bdd466894f984dfc182 F src/update.c 456d4a4656f8a03c2abc88a51b19172197400e58 @@ -1562,7 +1562,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e0a3d39f51a50420bae97e2bc9a8c01a5b0d3db8 -R 3a57497a1a3fd47f649c0fa2a10dc005 +P 01cd9fb176cde30658233e36aad44e4a5519612e +R 71cd7c04663535bedf446cdfbe42cd2c U drh -Z 8979ee765002edd7cbb3fe90b0cd803b +Z ad71d7ac120da8173e9f5ee4d75c7bc4 diff --git a/manifest.uuid b/manifest.uuid index daf8551ff8..8791cf4146 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -01cd9fb176cde30658233e36aad44e4a5519612e \ No newline at end of file +2cb71583d631cd417acbeebbb4ee950573a9deef \ No newline at end of file diff --git a/src/tokenize.c b/src/tokenize.c index 7bb1179e20..578ddc4f00 100644 --- a/src/tokenize.c +++ b/src/tokenize.c @@ -475,8 +475,8 @@ int sqlite3GetToken(const unsigned char *z, int *tokenType){ */ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){ int nErr = 0; /* Number of errors encountered */ - int i; /* Loop counter */ void *pEngine; /* The LEMON-generated LALR(1) parser */ + int n = 0; /* Length of the next token token */ int tokenType; /* type of the next token */ int lastTokenParsed = -1; /* type of the previous token */ sqlite3 *db = pParse->db; /* The database connection */ @@ -492,7 +492,6 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){ } pParse->rc = SQLITE_OK; pParse->zTail = zSql; - i = 0; assert( pzErrMsg!=0 ); /* sqlite3ParserTrace(stdout, "parser: "); */ #ifdef sqlite3Parser_ENGINEALWAYSONSTACK @@ -510,12 +509,10 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){ assert( pParse->nVar==0 ); assert( pParse->pVList==0 ); while( 1 ){ - assert( i>=0 ); - if( zSql[i]!=0 ){ - pParse->sLastToken.z = &zSql[i]; - pParse->sLastToken.n = sqlite3GetToken((u8*)&zSql[i],&tokenType); - i += pParse->sLastToken.n; - if( i>mxSqlLen ){ + if( zSql[0]!=0 ){ + n = sqlite3GetToken((u8*)zSql, &tokenType); + mxSqlLen -= n; + if( mxSqlLen<0 ){ pParse->rc = SQLITE_TOOBIG; break; } @@ -529,6 +526,7 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){ }else{ tokenType = TK_SEMI; } + zSql -= n; } if( tokenType>=TK_SPACE ){ assert( tokenType==TK_SPACE || tokenType==TK_ILLEGAL ); @@ -537,18 +535,21 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){ break; } if( tokenType==TK_ILLEGAL ){ - sqlite3ErrorMsg(pParse, "unrecognized token: \"%T\"", - &pParse->sLastToken); + sqlite3ErrorMsg(pParse, "unrecognized token: \"%.*s\"", n, zSql); break; } + zSql += n; }else{ + pParse->sLastToken.z = zSql; + pParse->sLastToken.n = n; sqlite3Parser(pEngine, tokenType, pParse->sLastToken, pParse); lastTokenParsed = tokenType; + zSql += n; if( pParse->rc!=SQLITE_OK || db->mallocFailed ) break; } } assert( nErr==0 ); - pParse->zTail = &zSql[i]; + pParse->zTail = zSql; #ifdef YYTRACKMAXSTACKDEPTH sqlite3_mutex_enter(sqlite3MallocMutex()); sqlite3StatusHighwater(SQLITE_STATUS_PARSER_STACK, From 5cc95ebf37cc7b307e02fd6471d7342af5b24226 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 7 Mar 2017 20:03:25 +0000 Subject: [PATCH 1394/1484] Add test script ext/rbu/rbu_round_trip.tcl. Uses "dbselftest" to test that "rbu" and "sqldiff" work together. FossilOrigin-Name: 961e79da73b4550b3e5b0f9a617133a76485db67 --- ext/rbu/rbu_round_trip.tcl | 205 +++++++++++++++++++++++++++++++++++++ manifest | 13 +-- manifest.uuid | 2 +- 3 files changed, 213 insertions(+), 7 deletions(-) create mode 100644 ext/rbu/rbu_round_trip.tcl diff --git a/ext/rbu/rbu_round_trip.tcl b/ext/rbu/rbu_round_trip.tcl new file mode 100644 index 0000000000..a4f5d579a1 --- /dev/null +++ b/ext/rbu/rbu_round_trip.tcl @@ -0,0 +1,205 @@ +########################################################################## +# 2016 Mar 8 +# +# 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. +# +proc process_cmdline {} { + cmdline::process ::A $::argv { + {make "try to build missing tools"} + {verbose "make more noise"} + database + database2 + } { + This script uses/tests the following tools: + + dbselftest + rbu + sqldiff + sqlite3 + + The user passes the names of two database files - a.db and b.db below - as + arguments. This program: + + 1. Runs [dbselftest --init] against both databases. + 2. Runs [sqldiff --rbu --vtab a.db b.db | sqlite3 .db] to create an + RBU database. + 3. Runs [rbu b.db .db] to patch b.db to a.db. + 4. Runs [sqldiff --table selftest a.db b.db] to check that the selftest + tables are now identical. + 5. Runs [dbselftest] against both databases. + } +} + +########################################################################### +########################################################################### +# Command line options processor. This is generic code that can be copied +# between scripts. +# +namespace eval cmdline { + proc cmdline_error {O E {msg ""}} { + if {$msg != ""} { + puts stderr "Error: $msg" + puts stderr "" + } + + set L [list] + foreach o $O { + if {[llength $o]==1} { + lappend L [string toupper $o] + } + } + + puts stderr "Usage: $::argv0 ?SWITCHES? $L" + puts stderr "" + puts stderr "Switches are:" + foreach o $O { + if {[llength $o]==3} { + foreach {a b c} $o {} + puts stderr [format " -%-15s %s (default \"%s\")" "$a VAL" $c $b] + } elseif {[llength $o]==2} { + foreach {a b} $o {} + puts stderr [format " -%-15s %s" $a $b] + } + } + puts stderr "" + puts stderr $E + exit -1 + } + + proc process {avar lArgs O E} { + upvar $avar A + set zTrailing "" ;# True if ... is present in $O + set lPosargs [list] + + # Populate A() with default values. Also, for each switch in the command + # line spec, set an entry in the idx() array as follows: + # + # {tblname t1 "table name to use"} + # -> [set idx(-tblname) {tblname t1 "table name to use"} + # + # For each position parameter, append its name to $lPosargs. If the ... + # specifier is present, set $zTrailing to the name of the prefix. + # + foreach o $O { + set nm [lindex $o 0] + set nArg [llength $o] + switch -- $nArg { + 1 { + if {[string range $nm end-2 end]=="..."} { + set zTrailing [string range $nm 0 end-3] + } else { + lappend lPosargs $nm + } + } + 2 { + set A($nm) 0 + set idx(-$nm) $o + } + 3 { + set A($nm) [lindex $o 1] + set idx(-$nm) $o + } + default { + error "Error in command line specification" + } + } + } + + # Set explicitly specified option values + # + set nArg [llength $lArgs] + for {set i 0} {$i < $nArg} {incr i} { + set opt [lindex $lArgs $i] + if {[string range $opt 0 0]!="-" || $opt=="--"} break + set c [array names idx "${opt}*"] + if {[llength $c]==0} { cmdline_error $O $E "Unrecognized option: $opt"} + if {[llength $c]>1} { cmdline_error $O $E "Ambiguous option: $opt"} + + if {[llength $idx($c)]==3} { + if {$i==[llength $lArgs]-1} { + cmdline_error $O $E "Option requires argument: $c" + } + incr i + set A([lindex $idx($c) 0]) [lindex $lArgs $i] + } else { + set A([lindex $idx($c) 0]) 1 + } + } + + # Deal with position arguments. + # + set nPosarg [llength $lPosargs] + set nRem [expr $nArg - $i] + if {$nRem < $nPosarg || ($zTrailing=="" && $nRem > $nPosarg)} { + cmdline_error $O $E + } + for {set j 0} {$j < $nPosarg} {incr j} { + set A([lindex $lPosargs $j]) [lindex $lArgs [expr $j+$i]] + } + if {$zTrailing!=""} { + set A($zTrailing) [lrange $lArgs [expr $j+$i] end] + } + } +} ;# namespace eval cmdline +# End of command line options processor. +########################################################################### +########################################################################### + +process_cmdline + +# Check that the specified tool is present. +# +proc check_for_tool {tool} { + if {[file exists $tool]==0 || [file executable $tool]==0} { + puts stderr "Missing $tool... exiting. (run \[make $tool\])" + exit -1 + } +} + +if {$A(make)} { + if {$A(verbose)} { puts "building tools..." } + exec make dbselftest rbu sqlite3 sqldiff +} + +check_for_tool dbselftest +check_for_tool rbu +check_for_tool sqlite3 +check_for_tool sqldiff + +exec ./sqlite3 $A(database) "DROP TABLE selftest;" +exec ./sqlite3 $A(database2) "DROP TABLE selftest;" + +# Run [dbselftest --init] on both databases +if {$A(verbose)} { puts "Running \[dbselftest --init\]" } +exec ./dbselftest --init $A(database) +exec ./dbselftest --init $A(database2) + +# Create an RBU patch. +set tmpname "./rrt-[format %x [expr int(rand()*0x7FFFFFFF)]].db" +if {$A(verbose)} { puts "rbu database is $tmpname" } +exec ./sqldiff --rbu --vtab $A(database2) $A(database) | ./sqlite3 $tmpname + +# Run the [rbu] patch. +if {$A(verbose)} { puts "Running \[rbu]" } +exec ./rbu $A(database2) $tmpname + +set selftest_diff [exec ./sqldiff --table selftest $A(database) $A(database2)] +if {$selftest_diff != ""} { + puts stderr "patching table \"selftest\" failed: $selftest_diff" + exit -1 +} + +# Run [dbselftest] on both databases +if {$A(verbose)} { puts "Running \[dbselftest]" } +exec ./dbselftest $A(database) +exec ./dbselftest $A(database2) + +# Remove the RBU database +file delete $tmpname +puts "round trip test successful." + diff --git a/manifest b/manifest index 11e8d7020b..a3944b0665 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Performance\soptimization\sin\sthe\stokenizer/parser\sloop. -D 2017-03-07T14:38:52.463 +C Add\stest\sscript\sext/rbu/rbu_round_trip.tcl.\sUses\s"dbselftest"\sto\stest\sthat\n"rbu"\sand\s"sqldiff"\swork\stogether. +D 2017-03-07T20:03:25.030 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 @@ -249,6 +249,7 @@ F ext/rbu/rbuA.test c1a7b3e2d926b8f8448bb3b4ae787e314ee4b2b3 F ext/rbu/rbuB.test c25bc325b8072a766e56bb76c001866b405925c2 F ext/rbu/rbuC.test efe47db508a0269b683cb2a1913a425ffd39a831 F ext/rbu/rbu_common.tcl a38e8e2d4a50fd6aaf151633714c1b1d2fae3ead +F ext/rbu/rbu_round_trip.tcl f3216836bbaeb10d76a2c70b89c13f59eabbd117 F ext/rbu/rbucrash.test 8d2ed5d4b05fef6c00c2a6b5f7ead71fa172a695 F ext/rbu/rbucrash2.test b2ecbdd7bb72c88bd217c65bd00dafa07f7f2d4d F ext/rbu/rbudiff.test 3e605cf624d00d04d0fb1316a3acec4fbe3b3ac5 @@ -1562,7 +1563,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 01cd9fb176cde30658233e36aad44e4a5519612e -R 71cd7c04663535bedf446cdfbe42cd2c -U drh -Z ad71d7ac120da8173e9f5ee4d75c7bc4 +P 2cb71583d631cd417acbeebbb4ee950573a9deef +R ee3baff0fd57ede16b35b4777ef32cf9 +U dan +Z 9c10ed94bada1b1224e7c4aff135f1d6 diff --git a/manifest.uuid b/manifest.uuid index 8791cf4146..744c25a1e5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2cb71583d631cd417acbeebbb4ee950573a9deef \ No newline at end of file +961e79da73b4550b3e5b0f9a617133a76485db67 \ No newline at end of file From e611f1447132d3d34c7cf83e66a2a5a3abdf518e Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 8 Mar 2017 11:44:00 +0000 Subject: [PATCH 1395/1484] Add the --preserve-rowids option to the ".dump" command in the CLI. FossilOrigin-Name: c60aee24714a47ce12ee2a4dcefb9f55211d3761 --- manifest | 16 +-- manifest.uuid | 2 +- src/shell.c | 352 ++++++++++++++++++++++++++++++++--------------- test/shell1.test | 48 ++++++- 4 files changed, 295 insertions(+), 123 deletions(-) diff --git a/manifest b/manifest index a3944b0665..4a60c5aefa 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\stest\sscript\sext/rbu/rbu_round_trip.tcl.\sUses\s"dbselftest"\sto\stest\sthat\n"rbu"\sand\s"sqldiff"\swork\stogether. -D 2017-03-07T20:03:25.030 +C Add\sthe\s--preserve-rowids\soption\sto\sthe\s".dump"\scommand\sin\sthe\sCLI. +D 2017-03-08T11:44:00.069 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 @@ -399,7 +399,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 3e518b962d932a997fae373366880fc028c75706 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c d12f3539f80db38b09015561b569e0eb1c4b6c5f -F src/shell.c 27d2b31099fd2cd749e44d025ef9b54ca26692cb +F src/shell.c c42c3031f715712a0cd47d8f08bd2d1dfec8baa0 F src/sqlite.h.in 4d0c08f8640c586564a7032b259c5f69bf397850 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae @@ -1110,7 +1110,7 @@ F test/sharedA.test 0cdf1a76dfa00e6beee66af5b534b1e8df2720f5 F test/sharedB.test 16cc7178e20965d75278f410943109b77b2e645e F test/shared_err.test 2f2aee20db294b9924e81f6ccbe60f19e21e8506 F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304 -F test/shell1.test 52ac23a345772ab0d6d3241a21a633fdaa3ed581 +F test/shell1.test 5df739ee2fe5c9dbbb2f9a0158b9723bda0910b8 F test/shell2.test e242a9912f44f4c23c3d1d802a83e934e84c853b F test/shell3.test 9b95ba643eaa228376f06a898fb410ee9b6e57c1 F test/shell4.test 89ad573879a745974ff2df20ff97c5d6ffffbd5d @@ -1563,7 +1563,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 2cb71583d631cd417acbeebbb4ee950573a9deef -R ee3baff0fd57ede16b35b4777ef32cf9 -U dan -Z 9c10ed94bada1b1224e7c4aff135f1d6 +P 961e79da73b4550b3e5b0f9a617133a76485db67 +R c754df2de2ef21ae6643ebeaf45e8d82 +U drh +Z bce538a1e35be638681ea14d388ad037 diff --git a/manifest.uuid b/manifest.uuid index 744c25a1e5..7002a8bc75 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -961e79da73b4550b3e5b0f9a617133a76485db67 \ No newline at end of file +c60aee24714a47ce12ee2a4dcefb9f55211d3761 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 2dcf915f28..07f977d46a 100644 --- a/src/shell.c +++ b/src/shell.c @@ -455,28 +455,6 @@ static int isNumber(const char *z, int *realnum){ return *z==0; } -/* -** A global char* and an SQL function to access its current value -** from within an SQL statement. This program used to use the -** sqlite_exec_printf() API to substitue a string into an SQL statement. -** The correct way to do this with sqlite3 is to use the bind API, but -** since the shell is built around the callback paradigm it would be a lot -** of work. Instead just use this hack, which is quite harmless. -*/ -static const char *zShellStatic = 0; -static void shellstaticFunc( - sqlite3_context *context, - int argc, - sqlite3_value **argv -){ - assert( 0==argc ); - assert( zShellStatic ); - UNUSED_PARAMETER(argc); - UNUSED_PARAMETER(argv); - sqlite3_result_text(context, zShellStatic, -1, SQLITE_STATIC); -} - - /* ** Compute a string length that is limited to what can be stored in ** lower 30 bits of a 32-bit signed integer. @@ -618,6 +596,7 @@ struct ShellState { int countChanges; /* True to display change counts */ int backslashOn; /* Resolve C-style \x escapes in SQL input text */ int outCount; /* Revert to stdout when reaching zero */ + int preserveRowid; /* Preserver ROWID values on a ".dump" command */ int cnt; /* Number of records displayed so far */ FILE *out; /* Write results here */ FILE *traceOut; /* Output for sqlite3_trace() */ @@ -1333,6 +1312,16 @@ static void set_table_name(ShellState *p, const char *zName){ z[n] = 0; } +/* +** A variable length string to which one can append text. +*/ +typedef struct ShellString ShellString; +struct ShellString { + char *z; + int n; + int nAlloc; +}; + /* zIn is either a pointer to a NULL-terminated string in memory obtained ** from malloc(), or a NULL pointer. The string pointed to by zAppend is ** added to zIn, and the result returned in memory obtained from malloc(). @@ -1341,13 +1330,12 @@ static void set_table_name(ShellState *p, const char *zName){ ** If the third argument, quote, is not '\0', then it is used as a ** quote character for zAppend. */ -static char *appendText(char *zIn, char const *zAppend, char quote){ +static void appendText(ShellString *p, char const *zAppend, char quote){ int len; int i; int nAppend = strlen30(zAppend); - int nIn = (zIn?strlen30(zIn):0); - len = nAppend+nIn+1; + len = nAppend+p->n+1; if( quote ){ len += 2; for(i=0; in+len>=p->nAlloc ){ + p->nAlloc = p->nAlloc*2 + len + 20; + p->z = realloc(p->z, p->nAlloc); + if( p->z==0 ){ + memset(p, 0, sizeof(*p)); + return; + } } if( quote ){ - char *zCsr = &zIn[nIn]; + char *zCsr = p->z+p->n; *zCsr++ = quote; for(i=0; in = (int)(zCsr - p->z); + *zCsr = '\0'; }else{ - memcpy(&zIn[nIn], zAppend, nAppend); - zIn[len-1] = '\0'; + memcpy(p->z+p->n, zAppend, nAppend); + p->n += nAppend; + p->z[p->n] = '\0'; } - - return zIn; } @@ -2024,6 +2015,124 @@ static int shell_exec( return rc; } +/* +** Release memory previously allocated by tableColumnList(). +*/ +static void freeColumnList(char **azCol){ + int i; + for(i=1; azCol[i]; i++){ + sqlite3_free(azCol[i]); + } + /* azCol[0] is a static string */ + sqlite3_free(azCol); +} + +/* +** Return a list of pointers to strings which are the names of all +** columns in table zTab. The memory to hold the names is dynamically +** allocated and must be released by the caller using a subsequent call +** to freeColumnList(). +** +** The azCol[0] entry is usually NULL. However, if zTab contains a rowid +** value that needs to be preserved, then azCol[0] is filled in with the +** name of the rowid column. +** +** The first regular column in the table is azCol[1]. The list is terminated +** by an entry with azCol[i]==0. +*/ +static char **tableColumnList(ShellState *p, const char *zTab){ + char **azCol = 0; + sqlite3_stmt *pStmt; + char *zSql; + int nCol = 0; + int nAlloc = 0; + int nPK = 0; /* Number of PRIMARY KEY columns seen */ + int isIPK = 0; /* True if one PRIMARY KEY column of type INTEGER */ + int preserveRowid = p->preserveRowid; + int rc; + + zSql = sqlite3_mprintf("PRAGMA table_info=%Q", zTab); + rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); + sqlite3_free(zSql); + if( rc ) return 0; + while( sqlite3_step(pStmt)==SQLITE_ROW ){ + if( nCol>=nAlloc-2 ){ + nAlloc = nAlloc*2 + nCol + 10; + azCol = sqlite3_realloc(azCol, nAlloc*sizeof(azCol[0])); + if( azCol==0 ){ + raw_printf(stderr, "Error: out of memory\n"); + exit(1); + } + } + azCol[++nCol] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 1)); + if( sqlite3_column_int(pStmt, 5) ){ + nPK++; + if( nPK==1 + && sqlite3_stricmp((const char*)sqlite3_column_text(pStmt,2), + "INTEGER")==0 + ){ + isIPK = 1; + }else{ + isIPK = 0; + } + } + } + sqlite3_finalize(pStmt); + azCol[0] = 0; + azCol[nCol+1] = 0; + + /* The decision of whether or not a rowid really needs to be preserved + ** is tricky. We never need to preserve a rowid for a WITHOUT ROWID table + ** or a table with an INTEGER PRIMARY KEY. We are unable to preserve + ** rowids on tables where the rowid is inaccessible because there are other + ** columns in the table named "rowid", "_rowid_", and "oid". + */ + if( preserveRowid && isIPK ){ + /* If a single PRIMARY KEY column with type INTEGER was seen, then it + ** might be an alise for the ROWID. But it might also be a WITHOUT ROWID + ** table or a INTEGER PRIMARY KEY DESC column, neither of which are + ** ROWID aliases. To distinguish these cases, check to see if + ** there is a "pk" entry in "PRAGMA index_list". There will be + ** no "pk" index if the PRIMARY KEY really is an alias for the ROWID. + */ + zSql = sqlite3_mprintf("SELECT 1 FROM pragma_index_list(%Q)" + " WHERE origin='pk'", zTab); + rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); + sqlite3_free(zSql); + if( rc ){ + freeColumnList(azCol); + return 0; + } + rc = sqlite3_step(pStmt); + sqlite3_finalize(pStmt); + preserveRowid = rc==SQLITE_ROW; + } + if( preserveRowid ){ + /* Only preserve the rowid if we can find a name to use for the + ** rowid */ + static char *azRowid[] = { "rowid", "_rowid_", "oid" }; + int i, j; + for(j=0; j<3; j++){ + for(i=1; i<=nCol; i++){ + if( sqlite3_stricmp(azRowid[j],azCol[i])==0 ) break; + } + if( i>nCol ){ + /* At this point, we know that azRowid[j] is not the name of any + ** ordinary column in the table. Verify that azRowid[j] is a valid + ** name for the rowid before adding it to azCol[0]. WITHOUT ROWID + ** tables will fail this last check */ + int rc; + rc = sqlite3_table_column_metadata(p->db,0,zTab,azRowid[j],0,0,0,0,0); + if( rc==SQLITE_OK ) azCol[0] = azRowid[j]; + break; + } + } + } + return azCol; +} + + + /* ** This is a different callback routine used for dumping the database. @@ -2036,7 +2145,6 @@ static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){ const char *zTable; const char *zType; const char *zSql; - const char *zPrepStmt = 0; ShellState *p = (ShellState *)pArg; UNUSED_PARAMETER(azCol); @@ -2046,7 +2154,7 @@ static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){ zSql = azArg[2]; if( strcmp(zTable, "sqlite_sequence")==0 ){ - zPrepStmt = "DELETE FROM sqlite_sequence;\n"; + raw_printf(p->out, "DELETE FROM sqlite_sequence;\n"); }else if( sqlite3_strglob("sqlite_stat?", zTable)==0 ){ raw_printf(p->out, "ANALYZE sqlite_master;\n"); }else if( strncmp(zTable, "sqlite_", 7)==0 ){ @@ -2069,58 +2177,64 @@ static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){ } if( strcmp(zType, "table")==0 ){ - sqlite3_stmt *pTableInfo = 0; - char *zSelect = 0; - char *zTableInfo = 0; - char *zTmp = 0; - int nRow = 0; + ShellString sSelect; + ShellString sTable; + char **azCol; + int i; + char *savedDestTable; + int savedMode; - zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0); - zTableInfo = appendText(zTableInfo, zTable, '"'); - zTableInfo = appendText(zTableInfo, ");", 0); - - rc = sqlite3_prepare_v2(p->db, zTableInfo, -1, &pTableInfo, 0); - free(zTableInfo); - if( rc!=SQLITE_OK || !pTableInfo ){ - return 1; + azCol = tableColumnList(p, zTable); + if( azCol==0 ){ + p->nErr++; + return 0; } - zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0); /* Always quote the table name, even if it appears to be pure ascii, ** in case it is a keyword. Ex: INSERT INTO "table" ... */ - zTmp = appendText(zTmp, zTable, '"'); - if( zTmp ){ - zSelect = appendText(zSelect, zTmp, '\''); - free(zTmp); - } - zSelect = appendText(zSelect, " || ' VALUES(' || ", 0); - rc = sqlite3_step(pTableInfo); - while( rc==SQLITE_ROW ){ - const char *zText = (const char *)sqlite3_column_text(pTableInfo, 1); - zSelect = appendText(zSelect, "quote(", 0); - zSelect = appendText(zSelect, zText, '"'); - rc = sqlite3_step(pTableInfo); - if( rc==SQLITE_ROW ){ - zSelect = appendText(zSelect, "), ", 0); - }else{ - zSelect = appendText(zSelect, ") ", 0); + memset(&sTable, 0, sizeof(sTable)); + appendText(&sTable, zTable, '"'); + /* If preserving the rowid, add a column list after the table name. + ** In other words: "INSERT INTO tab(rowid,a,b,c,...) VALUES(...)" + ** instead of the usual "INSERT INTO tab VALUES(...)". + */ + if( azCol[0] ){ + appendText(&sTable, "(", 0); + appendText(&sTable, azCol[0], 0); + for(i=1; azCol[i]; i++){ + appendText(&sTable, ",", 0); + appendText(&sTable, azCol[i], '"'); } - nRow++; + appendText(&sTable, ")", 0); } - rc = sqlite3_finalize(pTableInfo); - if( rc!=SQLITE_OK || nRow==0 ){ - free(zSelect); - return 1; - } - zSelect = appendText(zSelect, "|| ')' FROM ", 0); - zSelect = appendText(zSelect, zTable, '"'); - rc = run_table_dump_query(p, zSelect, zPrepStmt); - if( rc==SQLITE_CORRUPT ){ - zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0); - run_table_dump_query(p, zSelect, 0); + /* Build an appropriate SELECT statement */ + memset(&sSelect, 0, sizeof(sSelect)); + appendText(&sSelect, "SELECT ", 0); + if( azCol[0] ){ + appendText(&sSelect, azCol[0], 0); + appendText(&sSelect, ",", 0); } - free(zSelect); + for(i=1; azCol[i]; i++){ + appendText(&sSelect, azCol[i], 0); + if( azCol[i+1] ){ + appendText(&sSelect, ",", 0); + } + } + freeColumnList(azCol); + appendText(&sSelect, " FROM ", 0); + appendText(&sSelect, zTable, '"'); + + savedDestTable = p->zDestTable; + savedMode = p->mode; + p->zDestTable = sTable.z; + p->mode = p->cMode = MODE_Insert; + rc = shell_exec(p->db, sSelect.z, shell_callback, p, 0); + p->zDestTable = savedDestTable; + p->mode = savedMode; + free(sTable.z); + free(sSelect.z); + if( rc ) p->nErr++; } return 0; } @@ -2425,10 +2539,6 @@ static void open_db(ShellState *p, int keepAlive){ sqlite3_initialize(); sqlite3_open(p->zDbFilename, &p->db); globalDb = p->db; - if( p->db && sqlite3_errcode(p->db)==SQLITE_OK ){ - sqlite3_create_function(p->db, "shellstatic", 0, SQLITE_UTF8, 0, - shellstaticFunc, 0, 0); - } if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){ utf8_printf(stderr,"Error: unable to open database \"%s\": %s\n", p->zDbFilename, sqlite3_errmsg(p->db)); @@ -3722,21 +3832,42 @@ static int do_meta_command(char *zLine, ShellState *p){ }else if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){ + const char *zLike = 0; + int i; + p->preserveRowid = 0; + for(i=1; ipreserveRowid = 1; + }else + { + raw_printf(stderr, "Unknown option \"%s\" on \".dump\"\n", azArg[i]); + rc = 1; + goto meta_command_exit; + } + }else if( zLike ){ + raw_printf(stderr, "Usage: .dump ?--preserve-rowids? ?LIKE-PATTERN?\n"); + rc = 1; + goto meta_command_exit; + }else{ + zLike = azArg[i]; + } + } open_db(p, 0); /* When playing back a "dump", the content might appear in an order ** which causes immediate foreign key constraints to be violated. ** So disable foreign-key constraint enforcement to prevent problems. */ - if( nArg!=1 && nArg!=2 ){ - raw_printf(stderr, "Usage: .dump ?LIKE-PATTERN?\n"); - rc = 1; - goto meta_command_exit; - } raw_printf(p->out, "PRAGMA foreign_keys=OFF;\n"); raw_printf(p->out, "BEGIN TRANSACTION;\n"); p->writableSchema = 0; + /* Set writable_schema=ON since doing so forces SQLite to initialize + ** as much of the schema as it can even if the sqlite_master table is + ** corrupt. */ sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0); p->nErr = 0; - if( nArg==1 ){ + if( zLike==0 ){ run_schema_dump_query(p, "SELECT name, type, sql FROM sqlite_master " "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'" @@ -3750,21 +3881,20 @@ static int do_meta_command(char *zLine, ShellState *p){ "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0 ); }else{ - int i; - for(i=1; iwritableSchema ){ raw_printf(p->out, "PRAGMA writable_schema=OFF;\n"); @@ -4574,17 +4704,17 @@ static int do_meta_command(char *zLine, ShellState *p){ callback(&data, 1, new_argv, new_colv); rc = SQLITE_OK; }else{ - zShellStatic = azArg[1]; - rc = sqlite3_exec(p->db, + char *zSql; + zSql = sqlite3_mprintf( "SELECT sql FROM " " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x" " FROM sqlite_master UNION ALL" " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) " - "WHERE lower(tbl_name) LIKE shellstatic()" + "WHERE lower(tbl_name) LIKE %Q" " AND type!='meta' AND sql NOTNULL " - "ORDER BY rowid", - callback, &data, &zErrMsg); - zShellStatic = 0; + "ORDER BY rowid", azArg[1]); + rc = sqlite3_exec(p->db, zSql, callback, &data, &zErrMsg); + sqlite3_free(zSql); } }else if( nArg==1 ){ rc = sqlite3_exec(p->db, diff --git a/test/shell1.test b/test/shell1.test index 95c3130bdd..0912fa4240 100644 --- a/test/shell1.test +++ b/test/shell1.test @@ -300,7 +300,7 @@ do_test shell1-3.4.2 { do_test shell1-3.4.3 { # too many arguments catchcmd "test.db" ".dump FOO BAD" -} {1 {Usage: .dump ?LIKE-PATTERN?}} +} {1 {Usage: .dump ?--preserve-rowids? ?LIKE-PATTERN?}} # .echo ON|OFF Turn command echo on or off do_test shell1-3.5.1 { @@ -745,16 +745,58 @@ INSERT INTO "t1" VALUES(''); INSERT INTO "t1" VALUES(1); INSERT INTO "t1" VALUES(2.25); INSERT INTO "t1" VALUES('hello'); -INSERT INTO "t1" VALUES(X'807F'); +INSERT INTO "t1" VALUES(X'807f'); CREATE TABLE t3(x,y); INSERT INTO "t3" VALUES(1,NULL); INSERT INTO "t3" VALUES(2,''); INSERT INTO "t3" VALUES(3,1); INSERT INTO "t3" VALUES(4,2.25); INSERT INTO "t3" VALUES(5,'hello'); -INSERT INTO "t3" VALUES(6,X'807F'); +INSERT INTO "t3" VALUES(6,X'807f'); COMMIT;}} +do_test shell1-4.1.1 { + catchcmd test.db {.dump --preserve-rowids} +} {0 {PRAGMA foreign_keys=OFF; +BEGIN TRANSACTION; +CREATE TABLE t1(x); +INSERT INTO "t1"(rowid,"x") VALUES(1,NULL); +INSERT INTO "t1"(rowid,"x") VALUES(2,''); +INSERT INTO "t1"(rowid,"x") VALUES(3,1); +INSERT INTO "t1"(rowid,"x") VALUES(4,2.25); +INSERT INTO "t1"(rowid,"x") VALUES(5,'hello'); +INSERT INTO "t1"(rowid,"x") VALUES(6,X'807f'); +CREATE TABLE t3(x,y); +INSERT INTO "t3"(rowid,"x","y") VALUES(1,1,NULL); +INSERT INTO "t3"(rowid,"x","y") VALUES(2,2,''); +INSERT INTO "t3"(rowid,"x","y") VALUES(3,3,1); +INSERT INTO "t3"(rowid,"x","y") VALUES(4,4,2.25); +INSERT INTO "t3"(rowid,"x","y") VALUES(5,5,'hello'); +INSERT INTO "t3"(rowid,"x","y") VALUES(6,6,X'807f'); +COMMIT;}} + +do_test shell1-4.1.2 { + db close + forcedelete test2.db + sqlite3 db test2.db + db eval { + CREATE TABLE t1(x INTEGER PRIMARY KEY, y); + INSERT INTO t1 VALUES(1,null), (2,''), (3,1), + (4,2.25), (5,'hello'), (6,x'807f'); + } + catchcmd test2.db {.dump --preserve-rowids} +} {0 {PRAGMA foreign_keys=OFF; +BEGIN TRANSACTION; +CREATE TABLE t1(x INTEGER PRIMARY KEY, y); +INSERT INTO "t1" VALUES(1,NULL); +INSERT INTO "t1" VALUES(2,''); +INSERT INTO "t1" VALUES(3,1); +INSERT INTO "t1" VALUES(4,2.25); +INSERT INTO "t1" VALUES(5,'hello'); +INSERT INTO "t1" VALUES(6,X'807f'); +COMMIT;}} + + # Test the output of ".mode insert" # do_test shell1-4.2.1 { From f42d31800240fd332de77a7c65e4863dea0dd84a Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 8 Mar 2017 12:25:18 +0000 Subject: [PATCH 1396/1484] In the CLI, avoid unnecessary identifier quoting in the ".dump" output. Also add new ".dump" test cases. FossilOrigin-Name: de65f907610a59e64cbf2214789c11f7117a86a6 --- manifest | 14 +-- manifest.uuid | 2 +- src/shell.c | 217 +++++++++++++++++++++++++++++------------------ test/shell1.test | 131 +++++++++++++++++++++------- 4 files changed, 244 insertions(+), 120 deletions(-) diff --git a/manifest b/manifest index 4a60c5aefa..92484569a1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\s--preserve-rowids\soption\sto\sthe\s".dump"\scommand\sin\sthe\sCLI. -D 2017-03-08T11:44:00.069 +C In\sthe\sCLI,\savoid\sunnecessary\sidentifier\squoting\sin\sthe\s".dump"\soutput.\nAlso\sadd\snew\s".dump"\stest\scases. +D 2017-03-08T12:25:18.771 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 @@ -399,7 +399,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 3e518b962d932a997fae373366880fc028c75706 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c d12f3539f80db38b09015561b569e0eb1c4b6c5f -F src/shell.c c42c3031f715712a0cd47d8f08bd2d1dfec8baa0 +F src/shell.c d1ba571e8325f727f0c9571079e27b8a4595d6fd F src/sqlite.h.in 4d0c08f8640c586564a7032b259c5f69bf397850 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae @@ -1110,7 +1110,7 @@ F test/sharedA.test 0cdf1a76dfa00e6beee66af5b534b1e8df2720f5 F test/sharedB.test 16cc7178e20965d75278f410943109b77b2e645e F test/shared_err.test 2f2aee20db294b9924e81f6ccbe60f19e21e8506 F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304 -F test/shell1.test 5df739ee2fe5c9dbbb2f9a0158b9723bda0910b8 +F test/shell1.test bc1ca4161e1f459c9cd412d3f21f4ee635cf2322 F test/shell2.test e242a9912f44f4c23c3d1d802a83e934e84c853b F test/shell3.test 9b95ba643eaa228376f06a898fb410ee9b6e57c1 F test/shell4.test 89ad573879a745974ff2df20ff97c5d6ffffbd5d @@ -1563,7 +1563,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 961e79da73b4550b3e5b0f9a617133a76485db67 -R c754df2de2ef21ae6643ebeaf45e8d82 +P c60aee24714a47ce12ee2a4dcefb9f55211d3761 +R b3f6f7a6c1a0fc140ee14b2a6ca3bfe0 U drh -Z bce538a1e35be638681ea14d388ad037 +Z f9eff36eb51a780bc84edce006ee1256 diff --git a/manifest.uuid b/manifest.uuid index 7002a8bc75..775616cedc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c60aee24714a47ce12ee2a4dcefb9f55211d3761 \ No newline at end of file +de65f907610a59e64cbf2214789c11f7117a86a6 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 07f977d46a..321a39f54b 100644 --- a/src/shell.c +++ b/src/shell.c @@ -555,6 +555,123 @@ static char *one_input_line(FILE *in, char *zPrior, int isContinuation){ } return zResult; } +/* +** A variable length string to which one can append text. +*/ +typedef struct ShellText ShellText; +struct ShellText { + char *z; + int n; + int nAlloc; +}; + +/* +** Initialize and destroy a ShellText object +*/ +static void initText(ShellText *p){ + memset(p, 0, sizeof(*p)); +} +static void freeText(ShellText *p){ + free(p->z); + initText(p); +} + +/* zIn is either a pointer to a NULL-terminated string in memory obtained +** from malloc(), or a NULL pointer. The string pointed to by zAppend is +** added to zIn, and the result returned in memory obtained from malloc(). +** zIn, if it was not NULL, is freed. +** +** If the third argument, quote, is not '\0', then it is used as a +** quote character for zAppend. +*/ +static void appendText(ShellText *p, char const *zAppend, char quote){ + int len; + int i; + int nAppend = strlen30(zAppend); + + len = nAppend+p->n+1; + if( quote ){ + len += 2; + for(i=0; in+len>=p->nAlloc ){ + p->nAlloc = p->nAlloc*2 + len + 20; + p->z = realloc(p->z, p->nAlloc); + if( p->z==0 ){ + memset(p, 0, sizeof(*p)); + return; + } + } + + if( quote ){ + char *zCsr = p->z+p->n; + *zCsr++ = quote; + for(i=0; in = (int)(zCsr - p->z); + *zCsr = '\0'; + }else{ + memcpy(p->z+p->n, zAppend, nAppend); + p->n += nAppend; + p->z[p->n] = '\0'; + } +} + +/* +** Attempt to determine if identifier zName needs to be quoted, either +** because it contains non-alphanumeric characters, or because it is an +** SQLite keyword. Be conservative in this estimate: When in doubt assume +** that quoting is required. +** +** Return '"' if quoting is required. Return 0 if no quoting is required. +*/ +static char quoteChar(const char *zName){ + /* All SQLite keywords, in alphabetical order */ + static const char *azKeywords[] = { + "ABORT", "ACTION", "ADD", "AFTER", "ALL", "ALTER", "ANALYZE", "AND", "AS", + "ASC", "ATTACH", "AUTOINCREMENT", "BEFORE", "BEGIN", "BETWEEN", "BY", + "CASCADE", "CASE", "CAST", "CHECK", "COLLATE", "COLUMN", "COMMIT", + "CONFLICT", "CONSTRAINT", "CREATE", "CROSS", "CURRENT_DATE", + "CURRENT_TIME", "CURRENT_TIMESTAMP", "DATABASE", "DEFAULT", "DEFERRABLE", + "DEFERRED", "DELETE", "DESC", "DETACH", "DISTINCT", "DROP", "EACH", + "ELSE", "END", "ESCAPE", "EXCEPT", "EXCLUSIVE", "EXISTS", "EXPLAIN", + "FAIL", "FOR", "FOREIGN", "FROM", "FULL", "GLOB", "GROUP", "HAVING", "IF", + "IGNORE", "IMMEDIATE", "IN", "INDEX", "INDEXED", "INITIALLY", "INNER", + "INSERT", "INSTEAD", "INTERSECT", "INTO", "IS", "ISNULL", "JOIN", "KEY", + "LEFT", "LIKE", "LIMIT", "MATCH", "NATURAL", "NO", "NOT", "NOTNULL", + "NULL", "OF", "OFFSET", "ON", "OR", "ORDER", "OUTER", "PLAN", "PRAGMA", + "PRIMARY", "QUERY", "RAISE", "RECURSIVE", "REFERENCES", "REGEXP", + "REINDEX", "RELEASE", "RENAME", "REPLACE", "RESTRICT", "RIGHT", + "ROLLBACK", "ROW", "SAVEPOINT", "SELECT", "SET", "TABLE", "TEMP", + "TEMPORARY", "THEN", "TO", "TRANSACTION", "TRIGGER", "UNION", "UNIQUE", + "UPDATE", "USING", "VACUUM", "VALUES", "VIEW", "VIRTUAL", "WHEN", "WHERE", + "WITH", "WITHOUT", + }; + int i, lwr, upr, mid, c; + if( !isalpha((unsigned char)zName[0]) && zName[0]!='_' ) return '"'; + for(i=0; zName[i]; i++){ + if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ) return '"'; + } + lwr = 0; + upr = sizeof(azKeywords)/sizeof(azKeywords[0]) - 1; + while( lwr<=upr ){ + mid = (lwr+upr)/2; + c = sqlite3_stricmp(azKeywords[mid], zName); + if( c==0 ) return '"'; + if( c<0 ){ + lwr = mid+1; + }else{ + upr = mid-1; + } + } + return 0; +} #if defined(SQLITE_ENABLE_SESSION) /* @@ -1274,6 +1391,7 @@ static int callback(void *pArg, int nArg, char **azArg, char **azCol){ return shell_callback(pArg, nArg, azArg, azCol, NULL); } + /* ** Set the destination table field of the ShellState structure to ** the name of the table given. Escape any quote characters in the @@ -1281,7 +1399,7 @@ static int callback(void *pArg, int nArg, char **azArg, char **azCol){ */ static void set_table_name(ShellState *p, const char *zName){ int i, n; - int needQuote; + int cQuote; char *z; if( p->zDestTable ){ @@ -1289,86 +1407,24 @@ static void set_table_name(ShellState *p, const char *zName){ p->zDestTable = 0; } if( zName==0 ) return; - needQuote = !isalpha((unsigned char)*zName) && *zName!='_'; - for(i=n=0; zName[i]; i++, n++){ - if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ){ - needQuote = 1; - if( zName[i]=='\'' ) n++; - } - } - if( needQuote ) n += 2; + cQuote = quoteChar(zName); + n = strlen30(zName); + if( cQuote ) n += 2; z = p->zDestTable = malloc( n+1 ); if( z==0 ){ raw_printf(stderr,"Error: out of memory\n"); exit(1); } n = 0; - if( needQuote ) z[n++] = '\''; + if( cQuote ) z[n++] = cQuote; for(i=0; zName[i]; i++){ z[n++] = zName[i]; - if( zName[i]=='\'' ) z[n++] = '\''; + if( zName[i]==cQuote ) z[n++] = cQuote; } - if( needQuote ) z[n++] = '\''; + if( cQuote ) z[n++] = cQuote; z[n] = 0; } -/* -** A variable length string to which one can append text. -*/ -typedef struct ShellString ShellString; -struct ShellString { - char *z; - int n; - int nAlloc; -}; - -/* zIn is either a pointer to a NULL-terminated string in memory obtained -** from malloc(), or a NULL pointer. The string pointed to by zAppend is -** added to zIn, and the result returned in memory obtained from malloc(). -** zIn, if it was not NULL, is freed. -** -** If the third argument, quote, is not '\0', then it is used as a -** quote character for zAppend. -*/ -static void appendText(ShellString *p, char const *zAppend, char quote){ - int len; - int i; - int nAppend = strlen30(zAppend); - - len = nAppend+p->n+1; - if( quote ){ - len += 2; - for(i=0; in+len>=p->nAlloc ){ - p->nAlloc = p->nAlloc*2 + len + 20; - p->z = realloc(p->z, p->nAlloc); - if( p->z==0 ){ - memset(p, 0, sizeof(*p)); - return; - } - } - - if( quote ){ - char *zCsr = p->z+p->n; - *zCsr++ = quote; - for(i=0; in = (int)(zCsr - p->z); - *zCsr = '\0'; - }else{ - memcpy(p->z+p->n, zAppend, nAppend); - p->n += nAppend; - p->z[p->n] = '\0'; - } -} - /* ** Execute a query statement that will generate SQL output. Print @@ -2131,9 +2187,6 @@ static char **tableColumnList(ShellState *p, const char *zTab){ return azCol; } - - - /* ** This is a different callback routine used for dumping the database. ** Each row received by this callback consists of a table name, @@ -2177,8 +2230,8 @@ static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){ } if( strcmp(zType, "table")==0 ){ - ShellString sSelect; - ShellString sTable; + ShellText sSelect; + ShellText sTable; char **azCol; int i; char *savedDestTable; @@ -2192,8 +2245,8 @@ static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){ /* Always quote the table name, even if it appears to be pure ascii, ** in case it is a keyword. Ex: INSERT INTO "table" ... */ - memset(&sTable, 0, sizeof(sTable)); - appendText(&sTable, zTable, '"'); + initText(&sTable); + appendText(&sTable, zTable, quoteChar(zTable)); /* If preserving the rowid, add a column list after the table name. ** In other words: "INSERT INTO tab(rowid,a,b,c,...) VALUES(...)" ** instead of the usual "INSERT INTO tab VALUES(...)". @@ -2203,27 +2256,27 @@ static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){ appendText(&sTable, azCol[0], 0); for(i=1; azCol[i]; i++){ appendText(&sTable, ",", 0); - appendText(&sTable, azCol[i], '"'); + appendText(&sTable, azCol[i], quoteChar(azCol[i])); } appendText(&sTable, ")", 0); } /* Build an appropriate SELECT statement */ - memset(&sSelect, 0, sizeof(sSelect)); + initText(&sSelect); appendText(&sSelect, "SELECT ", 0); if( azCol[0] ){ appendText(&sSelect, azCol[0], 0); appendText(&sSelect, ",", 0); } for(i=1; azCol[i]; i++){ - appendText(&sSelect, azCol[i], 0); + appendText(&sSelect, azCol[i], quoteChar(azCol[i])); if( azCol[i+1] ){ appendText(&sSelect, ",", 0); } } freeColumnList(azCol); appendText(&sSelect, " FROM ", 0); - appendText(&sSelect, zTable, '"'); + appendText(&sSelect, zTable, quoteChar(zTable)); savedDestTable = p->zDestTable; savedMode = p->mode; @@ -2232,8 +2285,8 @@ static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){ rc = shell_exec(p->db, sSelect.z, shell_callback, p, 0); p->zDestTable = savedDestTable; p->mode = savedMode; - free(sTable.z); - free(sSelect.z); + freeText(&sTable); + freeText(&sSelect); if( rc ) p->nErr++; } return 0; diff --git a/test/shell1.test b/test/shell1.test index 0912fa4240..7f282292c0 100644 --- a/test/shell1.test +++ b/test/shell1.test @@ -740,41 +740,46 @@ do_test shell1-4.1 { } {0 {PRAGMA foreign_keys=OFF; BEGIN TRANSACTION; CREATE TABLE t1(x); -INSERT INTO "t1" VALUES(NULL); -INSERT INTO "t1" VALUES(''); -INSERT INTO "t1" VALUES(1); -INSERT INTO "t1" VALUES(2.25); -INSERT INTO "t1" VALUES('hello'); -INSERT INTO "t1" VALUES(X'807f'); +INSERT INTO t1 VALUES(NULL); +INSERT INTO t1 VALUES(''); +INSERT INTO t1 VALUES(1); +INSERT INTO t1 VALUES(2.25); +INSERT INTO t1 VALUES('hello'); +INSERT INTO t1 VALUES(X'807f'); CREATE TABLE t3(x,y); -INSERT INTO "t3" VALUES(1,NULL); -INSERT INTO "t3" VALUES(2,''); -INSERT INTO "t3" VALUES(3,1); -INSERT INTO "t3" VALUES(4,2.25); -INSERT INTO "t3" VALUES(5,'hello'); -INSERT INTO "t3" VALUES(6,X'807f'); +INSERT INTO t3 VALUES(1,NULL); +INSERT INTO t3 VALUES(2,''); +INSERT INTO t3 VALUES(3,1); +INSERT INTO t3 VALUES(4,2.25); +INSERT INTO t3 VALUES(5,'hello'); +INSERT INTO t3 VALUES(6,X'807f'); COMMIT;}} +# The --preserve-rowids option to .dump +# do_test shell1-4.1.1 { catchcmd test.db {.dump --preserve-rowids} } {0 {PRAGMA foreign_keys=OFF; BEGIN TRANSACTION; CREATE TABLE t1(x); -INSERT INTO "t1"(rowid,"x") VALUES(1,NULL); -INSERT INTO "t1"(rowid,"x") VALUES(2,''); -INSERT INTO "t1"(rowid,"x") VALUES(3,1); -INSERT INTO "t1"(rowid,"x") VALUES(4,2.25); -INSERT INTO "t1"(rowid,"x") VALUES(5,'hello'); -INSERT INTO "t1"(rowid,"x") VALUES(6,X'807f'); +INSERT INTO t1(rowid,x) VALUES(1,NULL); +INSERT INTO t1(rowid,x) VALUES(2,''); +INSERT INTO t1(rowid,x) VALUES(3,1); +INSERT INTO t1(rowid,x) VALUES(4,2.25); +INSERT INTO t1(rowid,x) VALUES(5,'hello'); +INSERT INTO t1(rowid,x) VALUES(6,X'807f'); CREATE TABLE t3(x,y); -INSERT INTO "t3"(rowid,"x","y") VALUES(1,1,NULL); -INSERT INTO "t3"(rowid,"x","y") VALUES(2,2,''); -INSERT INTO "t3"(rowid,"x","y") VALUES(3,3,1); -INSERT INTO "t3"(rowid,"x","y") VALUES(4,4,2.25); -INSERT INTO "t3"(rowid,"x","y") VALUES(5,5,'hello'); -INSERT INTO "t3"(rowid,"x","y") VALUES(6,6,X'807f'); +INSERT INTO t3(rowid,x,y) VALUES(1,1,NULL); +INSERT INTO t3(rowid,x,y) VALUES(2,2,''); +INSERT INTO t3(rowid,x,y) VALUES(3,3,1); +INSERT INTO t3(rowid,x,y) VALUES(4,4,2.25); +INSERT INTO t3(rowid,x,y) VALUES(5,5,'hello'); +INSERT INTO t3(rowid,x,y) VALUES(6,6,X'807f'); COMMIT;}} +# If the table contains an INTEGER PRIMARY KEY, do not record a separate +# rowid column in the output. +# do_test shell1-4.1.2 { db close forcedelete test2.db @@ -788,14 +793,80 @@ do_test shell1-4.1.2 { } {0 {PRAGMA foreign_keys=OFF; BEGIN TRANSACTION; CREATE TABLE t1(x INTEGER PRIMARY KEY, y); -INSERT INTO "t1" VALUES(1,NULL); -INSERT INTO "t1" VALUES(2,''); -INSERT INTO "t1" VALUES(3,1); -INSERT INTO "t1" VALUES(4,2.25); -INSERT INTO "t1" VALUES(5,'hello'); -INSERT INTO "t1" VALUES(6,X'807f'); +INSERT INTO t1 VALUES(1,NULL); +INSERT INTO t1 VALUES(2,''); +INSERT INTO t1 VALUES(3,1); +INSERT INTO t1 VALUES(4,2.25); +INSERT INTO t1 VALUES(5,'hello'); +INSERT INTO t1 VALUES(6,X'807f'); COMMIT;}} +# Verify that the table named [table] is correctly quoted and that +# an INTEGER PRIMARY KEY DESC is not an alias for the rowid. +# +do_test shell1-4.1.3 { + db close + forcedelete test2.db + sqlite3 db test2.db + db eval { + CREATE TABLE [table](x INTEGER PRIMARY KEY DESC, y); + INSERT INTO [table] VALUES(1,null), (12,''), (23,1), + (34,2.25), (45,'hello'), (56,x'807f'); + } + catchcmd test2.db {.dump --preserve-rowids} +} {0 {PRAGMA foreign_keys=OFF; +BEGIN TRANSACTION; +CREATE TABLE [table](x INTEGER PRIMARY KEY DESC, y); +INSERT INTO "table"(rowid,x,y) VALUES(1,1,NULL); +INSERT INTO "table"(rowid,x,y) VALUES(2,12,''); +INSERT INTO "table"(rowid,x,y) VALUES(3,23,1); +INSERT INTO "table"(rowid,x,y) VALUES(4,34,2.25); +INSERT INTO "table"(rowid,x,y) VALUES(5,45,'hello'); +INSERT INTO "table"(rowid,x,y) VALUES(6,56,X'807f'); +COMMIT;}} + +# Do not record rowids for a WITHOUT ROWID table. Also check correct quoting +# of table names that contain odd characters. +# +do_test shell1-4.1.4 { + db close + forcedelete test2.db + sqlite3 db test2.db + db eval { + CREATE TABLE [ta<>ble](x INTEGER PRIMARY KEY, y) WITHOUT ROWID; + INSERT INTO [ta<>ble] VALUES(1,null), (12,''), (23,1), + (34,2.25), (45,'hello'), (56,x'807f'); + } + catchcmd test2.db {.dump --preserve-rowids} +} {0 {PRAGMA foreign_keys=OFF; +BEGIN TRANSACTION; +CREATE TABLE [ta<>ble](x INTEGER PRIMARY KEY, y) WITHOUT ROWID; +INSERT INTO "ta<>ble" VALUES(1,NULL); +INSERT INTO "ta<>ble" VALUES(12,''); +INSERT INTO "ta<>ble" VALUES(23,1); +INSERT INTO "ta<>ble" VALUES(34,2.25); +INSERT INTO "ta<>ble" VALUES(45,'hello'); +INSERT INTO "ta<>ble" VALUES(56,X'807f'); +COMMIT;}} + +# Do not record rowids if the rowid is inaccessible +# +do_test shell1-4.1.5 { + db close + forcedelete test2.db + sqlite3 db test2.db + db eval { + CREATE TABLE t1(_ROWID_,rowid,oid); + INSERT INTO t1 VALUES(1,null,'alpha'), (12,'',99), (23,1,x'b0b1b2'); + } + catchcmd test2.db {.dump --preserve-rowids} +} {0 {PRAGMA foreign_keys=OFF; +BEGIN TRANSACTION; +CREATE TABLE t1(_ROWID_,rowid,oid); +INSERT INTO t1 VALUES(1,NULL,'alpha'); +INSERT INTO t1 VALUES(12,'',99); +INSERT INTO t1 VALUES(23,1,X'b0b1b2'); +COMMIT;}} # Test the output of ".mode insert" # From acc83d2e4f7bc0f3674b1c761bdcd7dfea41d319 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 8 Mar 2017 13:50:40 +0000 Subject: [PATCH 1397/1484] Add the shathree.c extension for implementing SHA3() and SHA3_QUERY() SQL functions. FossilOrigin-Name: f7ca9193ddafd3676406bdfeb1b7d21182c2a3c1 --- ext/misc/shathree.c | 703 ++++++++++++++++++++++++++++++++++++++++++++ manifest | 11 +- manifest.uuid | 2 +- 3 files changed, 710 insertions(+), 6 deletions(-) create mode 100644 ext/misc/shathree.c diff --git a/ext/misc/shathree.c b/ext/misc/shathree.c new file mode 100644 index 0000000000..a27faedb3f --- /dev/null +++ b/ext/misc/shathree.c @@ -0,0 +1,703 @@ +/* +** 2017-03-08 +** +** 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 SQLite extension implements a functions that compute SHA1 hashes. +** Two SQL functions are implemented: +** +** sha3(X,SIZE) +** sha3_query(Y,SIZE) +** +** The sha3(X) function computes the SHA3 hash of the input X, or NULL if +** X is NULL. +** +** The sha3_query(Y) function evalutes all queries in the SQL statements of Y +** and returns a hash of their results. +*/ +#include "sqlite3ext.h" +SQLITE_EXTENSION_INIT1 +#include +#include +#include +typedef sqlite3_uint64 u64; + +/****************************************************************************** +** The Hash Engine +*/ +/* +** Macros to determine whether the machine is big or little endian, +** and whether or not that determination is run-time or compile-time. +** +** For best performance, an attempt is made to guess at the byte-order +** using C-preprocessor macros. If that is unsuccessful, or if +** -DSHA3_BYTEORDER=0 is set, then byte-order is determined +** at run-time. +*/ +#ifndef SHA3_BYTEORDER +# if defined(i386) || defined(__i386__) || defined(_M_IX86) || \ + defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \ + defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) || \ + defined(__arm__) +# define SHA3_BYTEORDER 1234 +# elif defined(sparc) || defined(__ppc__) +# define SHA3_BYTEORDER 4321 +# else +# define SHA3_BYTEORDER 0 +# endif +#endif + + +/* +** State structure for a SHA3 hash in progress +*/ +typedef struct SHA3Context SHA3Context; +struct SHA3Context { + union { + u64 s[25]; /* Keccak state. 5x5 lines of 64 bits each */ + unsigned char x[1600]; /* ... or 1600 bytes */ + } u; + unsigned nRate; /* Bytes of input accepted per Keccak iteration */ + unsigned nLoaded; /* Input bytes loaded into u.x[] so far this cycle */ + unsigned ixMask; /* Insert next input into u.x[nLoaded^ixMask]. */ +}; + +/* +** A single step of the Keccak mixing function for a 1600-bit state +*/ +static void KeccakF1600Step(SHA3Context *p){ + int i; + u64 B0, B1, B2, B3, B4; + u64 C0, C1, C2, C3, C4; + u64 D0, D1, D2, D3, D4; + static const u64 RC[] = { + 0x0000000000000001ULL, 0x0000000000008082ULL, + 0x800000000000808aULL, 0x8000000080008000ULL, + 0x000000000000808bULL, 0x0000000080000001ULL, + 0x8000000080008081ULL, 0x8000000000008009ULL, + 0x000000000000008aULL, 0x0000000000000088ULL, + 0x0000000080008009ULL, 0x000000008000000aULL, + 0x000000008000808bULL, 0x800000000000008bULL, + 0x8000000000008089ULL, 0x8000000000008003ULL, + 0x8000000000008002ULL, 0x8000000000000080ULL, + 0x000000000000800aULL, 0x800000008000000aULL, + 0x8000000080008081ULL, 0x8000000000008080ULL, + 0x0000000080000001ULL, 0x8000000080008008ULL + }; +# define A00 (p->u.s[0]) +# define A01 (p->u.s[1]) +# define A02 (p->u.s[2]) +# define A03 (p->u.s[3]) +# define A04 (p->u.s[4]) +# define A10 (p->u.s[5]) +# define A11 (p->u.s[6]) +# define A12 (p->u.s[7]) +# define A13 (p->u.s[8]) +# define A14 (p->u.s[9]) +# define A20 (p->u.s[10]) +# define A21 (p->u.s[11]) +# define A22 (p->u.s[12]) +# define A23 (p->u.s[13]) +# define A24 (p->u.s[14]) +# define A30 (p->u.s[15]) +# define A31 (p->u.s[16]) +# define A32 (p->u.s[17]) +# define A33 (p->u.s[18]) +# define A34 (p->u.s[19]) +# define A40 (p->u.s[20]) +# define A41 (p->u.s[21]) +# define A42 (p->u.s[22]) +# define A43 (p->u.s[23]) +# define A44 (p->u.s[24]) +# define ROL64(a,x) ((a<>(64-x))) + + for(i=0; i<24; i+=4){ + C0 = A00^A10^A20^A30^A40; + C1 = A01^A11^A21^A31^A41; + C2 = A02^A12^A22^A32^A42; + C3 = A03^A13^A23^A33^A43; + C4 = A04^A14^A24^A34^A44; + D0 = C4^ROL64(C1, 1); + D1 = C0^ROL64(C2, 1); + D2 = C1^ROL64(C3, 1); + D3 = C2^ROL64(C4, 1); + D4 = C3^ROL64(C0, 1); + + B0 = (A00^D0); + B1 = ROL64((A11^D1), 44); + B2 = ROL64((A22^D2), 43); + B3 = ROL64((A33^D3), 21); + B4 = ROL64((A44^D4), 14); + A00 = B0 ^((~B1)& B2 ); + A00 ^= RC[i]; + A11 = B1 ^((~B2)& B3 ); + A22 = B2 ^((~B3)& B4 ); + A33 = B3 ^((~B4)& B0 ); + A44 = B4 ^((~B0)& B1 ); + + B2 = ROL64((A20^D0), 3); + B3 = ROL64((A31^D1), 45); + B4 = ROL64((A42^D2), 61); + B0 = ROL64((A03^D3), 28); + B1 = ROL64((A14^D4), 20); + A20 = B0 ^((~B1)& B2 ); + A31 = B1 ^((~B2)& B3 ); + A42 = B2 ^((~B3)& B4 ); + A03 = B3 ^((~B4)& B0 ); + A14 = B4 ^((~B0)& B1 ); + + B4 = ROL64((A40^D0), 18); + B0 = ROL64((A01^D1), 1); + B1 = ROL64((A12^D2), 6); + B2 = ROL64((A23^D3), 25); + B3 = ROL64((A34^D4), 8); + A40 = B0 ^((~B1)& B2 ); + A01 = B1 ^((~B2)& B3 ); + A12 = B2 ^((~B3)& B4 ); + A23 = B3 ^((~B4)& B0 ); + A34 = B4 ^((~B0)& B1 ); + + B1 = ROL64((A10^D0), 36); + B2 = ROL64((A21^D1), 10); + B3 = ROL64((A32^D2), 15); + B4 = ROL64((A43^D3), 56); + B0 = ROL64((A04^D4), 27); + A10 = B0 ^((~B1)& B2 ); + A21 = B1 ^((~B2)& B3 ); + A32 = B2 ^((~B3)& B4 ); + A43 = B3 ^((~B4)& B0 ); + A04 = B4 ^((~B0)& B1 ); + + B3 = ROL64((A30^D0), 41); + B4 = ROL64((A41^D1), 2); + B0 = ROL64((A02^D2), 62); + B1 = ROL64((A13^D3), 55); + B2 = ROL64((A24^D4), 39); + A30 = B0 ^((~B1)& B2 ); + A41 = B1 ^((~B2)& B3 ); + A02 = B2 ^((~B3)& B4 ); + A13 = B3 ^((~B4)& B0 ); + A24 = B4 ^((~B0)& B1 ); + + C0 = A00^A20^A40^A10^A30; + C1 = A11^A31^A01^A21^A41; + C2 = A22^A42^A12^A32^A02; + C3 = A33^A03^A23^A43^A13; + C4 = A44^A14^A34^A04^A24; + D0 = C4^ROL64(C1, 1); + D1 = C0^ROL64(C2, 1); + D2 = C1^ROL64(C3, 1); + D3 = C2^ROL64(C4, 1); + D4 = C3^ROL64(C0, 1); + + B0 = (A00^D0); + B1 = ROL64((A31^D1), 44); + B2 = ROL64((A12^D2), 43); + B3 = ROL64((A43^D3), 21); + B4 = ROL64((A24^D4), 14); + A00 = B0 ^((~B1)& B2 ); + A00 ^= RC[i+1]; + A31 = B1 ^((~B2)& B3 ); + A12 = B2 ^((~B3)& B4 ); + A43 = B3 ^((~B4)& B0 ); + A24 = B4 ^((~B0)& B1 ); + + B2 = ROL64((A40^D0), 3); + B3 = ROL64((A21^D1), 45); + B4 = ROL64((A02^D2), 61); + B0 = ROL64((A33^D3), 28); + B1 = ROL64((A14^D4), 20); + A40 = B0 ^((~B1)& B2 ); + A21 = B1 ^((~B2)& B3 ); + A02 = B2 ^((~B3)& B4 ); + A33 = B3 ^((~B4)& B0 ); + A14 = B4 ^((~B0)& B1 ); + + B4 = ROL64((A30^D0), 18); + B0 = ROL64((A11^D1), 1); + B1 = ROL64((A42^D2), 6); + B2 = ROL64((A23^D3), 25); + B3 = ROL64((A04^D4), 8); + A30 = B0 ^((~B1)& B2 ); + A11 = B1 ^((~B2)& B3 ); + A42 = B2 ^((~B3)& B4 ); + A23 = B3 ^((~B4)& B0 ); + A04 = B4 ^((~B0)& B1 ); + + B1 = ROL64((A20^D0), 36); + B2 = ROL64((A01^D1), 10); + B3 = ROL64((A32^D2), 15); + B4 = ROL64((A13^D3), 56); + B0 = ROL64((A44^D4), 27); + A20 = B0 ^((~B1)& B2 ); + A01 = B1 ^((~B2)& B3 ); + A32 = B2 ^((~B3)& B4 ); + A13 = B3 ^((~B4)& B0 ); + A44 = B4 ^((~B0)& B1 ); + + B3 = ROL64((A10^D0), 41); + B4 = ROL64((A41^D1), 2); + B0 = ROL64((A22^D2), 62); + B1 = ROL64((A03^D3), 55); + B2 = ROL64((A34^D4), 39); + A10 = B0 ^((~B1)& B2 ); + A41 = B1 ^((~B2)& B3 ); + A22 = B2 ^((~B3)& B4 ); + A03 = B3 ^((~B4)& B0 ); + A34 = B4 ^((~B0)& B1 ); + + C0 = A00^A40^A30^A20^A10; + C1 = A31^A21^A11^A01^A41; + C2 = A12^A02^A42^A32^A22; + C3 = A43^A33^A23^A13^A03; + C4 = A24^A14^A04^A44^A34; + D0 = C4^ROL64(C1, 1); + D1 = C0^ROL64(C2, 1); + D2 = C1^ROL64(C3, 1); + D3 = C2^ROL64(C4, 1); + D4 = C3^ROL64(C0, 1); + + B0 = (A00^D0); + B1 = ROL64((A21^D1), 44); + B2 = ROL64((A42^D2), 43); + B3 = ROL64((A13^D3), 21); + B4 = ROL64((A34^D4), 14); + A00 = B0 ^((~B1)& B2 ); + A00 ^= RC[i+2]; + A21 = B1 ^((~B2)& B3 ); + A42 = B2 ^((~B3)& B4 ); + A13 = B3 ^((~B4)& B0 ); + A34 = B4 ^((~B0)& B1 ); + + B2 = ROL64((A30^D0), 3); + B3 = ROL64((A01^D1), 45); + B4 = ROL64((A22^D2), 61); + B0 = ROL64((A43^D3), 28); + B1 = ROL64((A14^D4), 20); + A30 = B0 ^((~B1)& B2 ); + A01 = B1 ^((~B2)& B3 ); + A22 = B2 ^((~B3)& B4 ); + A43 = B3 ^((~B4)& B0 ); + A14 = B4 ^((~B0)& B1 ); + + B4 = ROL64((A10^D0), 18); + B0 = ROL64((A31^D1), 1); + B1 = ROL64((A02^D2), 6); + B2 = ROL64((A23^D3), 25); + B3 = ROL64((A44^D4), 8); + A10 = B0 ^((~B1)& B2 ); + A31 = B1 ^((~B2)& B3 ); + A02 = B2 ^((~B3)& B4 ); + A23 = B3 ^((~B4)& B0 ); + A44 = B4 ^((~B0)& B1 ); + + B1 = ROL64((A40^D0), 36); + B2 = ROL64((A11^D1), 10); + B3 = ROL64((A32^D2), 15); + B4 = ROL64((A03^D3), 56); + B0 = ROL64((A24^D4), 27); + A40 = B0 ^((~B1)& B2 ); + A11 = B1 ^((~B2)& B3 ); + A32 = B2 ^((~B3)& B4 ); + A03 = B3 ^((~B4)& B0 ); + A24 = B4 ^((~B0)& B1 ); + + B3 = ROL64((A20^D0), 41); + B4 = ROL64((A41^D1), 2); + B0 = ROL64((A12^D2), 62); + B1 = ROL64((A33^D3), 55); + B2 = ROL64((A04^D4), 39); + A20 = B0 ^((~B1)& B2 ); + A41 = B1 ^((~B2)& B3 ); + A12 = B2 ^((~B3)& B4 ); + A33 = B3 ^((~B4)& B0 ); + A04 = B4 ^((~B0)& B1 ); + + C0 = A00^A30^A10^A40^A20; + C1 = A21^A01^A31^A11^A41; + C2 = A42^A22^A02^A32^A12; + C3 = A13^A43^A23^A03^A33; + C4 = A34^A14^A44^A24^A04; + D0 = C4^ROL64(C1, 1); + D1 = C0^ROL64(C2, 1); + D2 = C1^ROL64(C3, 1); + D3 = C2^ROL64(C4, 1); + D4 = C3^ROL64(C0, 1); + + B0 = (A00^D0); + B1 = ROL64((A01^D1), 44); + B2 = ROL64((A02^D2), 43); + B3 = ROL64((A03^D3), 21); + B4 = ROL64((A04^D4), 14); + A00 = B0 ^((~B1)& B2 ); + A00 ^= RC[i+3]; + A01 = B1 ^((~B2)& B3 ); + A02 = B2 ^((~B3)& B4 ); + A03 = B3 ^((~B4)& B0 ); + A04 = B4 ^((~B0)& B1 ); + + B2 = ROL64((A10^D0), 3); + B3 = ROL64((A11^D1), 45); + B4 = ROL64((A12^D2), 61); + B0 = ROL64((A13^D3), 28); + B1 = ROL64((A14^D4), 20); + A10 = B0 ^((~B1)& B2 ); + A11 = B1 ^((~B2)& B3 ); + A12 = B2 ^((~B3)& B4 ); + A13 = B3 ^((~B4)& B0 ); + A14 = B4 ^((~B0)& B1 ); + + B4 = ROL64((A20^D0), 18); + B0 = ROL64((A21^D1), 1); + B1 = ROL64((A22^D2), 6); + B2 = ROL64((A23^D3), 25); + B3 = ROL64((A24^D4), 8); + A20 = B0 ^((~B1)& B2 ); + A21 = B1 ^((~B2)& B3 ); + A22 = B2 ^((~B3)& B4 ); + A23 = B3 ^((~B4)& B0 ); + A24 = B4 ^((~B0)& B1 ); + + B1 = ROL64((A30^D0), 36); + B2 = ROL64((A31^D1), 10); + B3 = ROL64((A32^D2), 15); + B4 = ROL64((A33^D3), 56); + B0 = ROL64((A34^D4), 27); + A30 = B0 ^((~B1)& B2 ); + A31 = B1 ^((~B2)& B3 ); + A32 = B2 ^((~B3)& B4 ); + A33 = B3 ^((~B4)& B0 ); + A34 = B4 ^((~B0)& B1 ); + + B3 = ROL64((A40^D0), 41); + B4 = ROL64((A41^D1), 2); + B0 = ROL64((A42^D2), 62); + B1 = ROL64((A43^D3), 55); + B2 = ROL64((A44^D4), 39); + A40 = B0 ^((~B1)& B2 ); + A41 = B1 ^((~B2)& B3 ); + A42 = B2 ^((~B3)& B4 ); + A43 = B3 ^((~B4)& B0 ); + A44 = B4 ^((~B0)& B1 ); + } +} + +/* +** Initialize a new hash. iSize determines the size of the hash +** in bits and should be one of 224, 256, 384, or 512. Or iSize +** can be zero to use the default hash size of 256 bits. +*/ +static void SHA3Init(SHA3Context *p, int iSize){ + memset(p, 0, sizeof(*p)); + if( iSize>=128 && iSize<=512 ){ + p->nRate = (1600 - ((iSize + 31)&~31)*2)/8; + }else{ + p->nRate = (1600 - 2*256)/8; + } +#if SHA3_BYTEORDER==1234 + /* Known to be little-endian at compile-time. No-op */ +#elif SHA3_BYTEORDER==4321 + p->ixMask = 7; /* Big-endian */ +#else + { + static unsigned int one = 1; + if( 1==*(unsigned char*)&one ){ + /* Little endian. No byte swapping. */ + p->ixMask = 0; + }else{ + /* Big endian. Byte swap. */ + p->ixMask = 7; + } + } +#endif +} + +/* +** Make consecutive calls to the SHA3Update function to add new content +** to the hash +*/ +static void SHA3Update( + SHA3Context *p, + const unsigned char *aData, + unsigned int nData +){ + unsigned int i = 0; +#if SHA3_BYTEORDER==1234 + if( (p->nLoaded % 8)==0 && ((aData - (const unsigned char*)0)&7)==0 ){ + for(; i+7u.s[p->nLoaded/8] ^= *(u64*)&aData[i]; + p->nLoaded += 8; + if( p->nLoaded>=p->nRate ){ + KeccakF1600Step(p); + p->nLoaded = 0; + } + } + } +#endif + for(; iu.x[p->nLoaded] ^= aData[i]; +#elif SHA3_BYTEORDER==4321 + p->u.x[p->nLoaded^0x07] ^= aData[i]; +#else + p->u.x[p->nLoaded^p->ixMask] ^= aData[i]; +#endif + p->nLoaded++; + if( p->nLoaded==p->nRate ){ + KeccakF1600Step(p); + p->nLoaded = 0; + } + } +} + +/* +** After all content has been added, invoke SHA3Final() to compute +** the final hash. The function returns a pointer to the binary +** hash value. +*/ +static unsigned char *SHA3Final(SHA3Context *p){ + unsigned int i; + if( p->nLoaded==p->nRate-1 ){ + const unsigned char c1 = 0x86; + SHA3Update(p, &c1, 1); + }else{ + const unsigned char c2 = 0x06; + const unsigned char c3 = 0x80; + SHA3Update(p, &c2, 1); + p->nLoaded = p->nRate - 1; + SHA3Update(p, &c3, 1); + } + for(i=0; inRate; i++){ + p->u.x[i+p->nRate] = p->u.x[i^p->ixMask]; + } + return &p->u.x[p->nRate]; +} +/* End of the hashing logic +*****************************************************************************/ + +/* +** Implementation of the sha3(X,SIZE) function. +** +** Return a BLOB which is the SIZE-bit SHA3 hash of X. The default +** size is 256. If X is a BLOB, it is hashed as is. +** For all other non-NULL types of input, X is converted into a UTF-8 string +** and the string is hashed without the trailing 0x00 terminator. The hash +** of a NULL value is NULL. +*/ +static void sha3Func( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + SHA3Context cx; + int eType = sqlite3_value_type(argv[0]); + int nByte = sqlite3_value_bytes(argv[0]); + int iSize; + if( argc==1 ){ + iSize = 256; + }else{ + iSize = sqlite3_value_int(argv[1]); + if( iSize!=224 && iSize!=256 && iSize!=384 && iSize!=512 ){ + sqlite3_result_error(context, "SHA3 size should be one of: 224 256 " + "384 512", -1); + return; + } + } + if( eType==SQLITE_NULL ) return; + SHA3Init(&cx, iSize); + if( eType==SQLITE_BLOB ){ + SHA3Update(&cx, sqlite3_value_blob(argv[0]), nByte); + }else{ + SHA3Update(&cx, sqlite3_value_text(argv[0]), nByte); + } + sqlite3_result_blob(context, SHA3Final(&cx), iSize/8, SQLITE_TRANSIENT); +} + +/* Compute a string using sqlite3_vsnprintf() with a maximum length +** of 50 bytes and add it to the hash. +*/ +static void hash_step_vformat( + SHA3Context *p, /* Add content to this context */ + const char *zFormat, + ... +){ + va_list ap; + int n; + char zBuf[50]; + va_start(ap, zFormat); + sqlite3_vsnprintf(sizeof(zBuf),zBuf,zFormat,ap); + va_end(ap); + n = (int)strlen(zBuf); + SHA3Update(p, (unsigned char*)zBuf, n); +} + +/* +** Implementation of the sha3_query(SQL,SIZE) function. +** +** This function compiles and runs the SQL statement(s) given in the +** argument. The results are hashed using a SIZE-bit SHA3. The default +** size is 256. +** +** The format of the byte stream that is hashed is summarized as follows: +** +** S: +** R +** N +** I +** F +** B: +** T: +** +** is the original SQL text for each statement run and is +** the size of that text. A single R character occurs before the +** start of each row. N means a NULL value. I mean an 8-byte +** little-endian integer . F is a floating point number with +** an 8-byte little-endian IEEE floating point value . +** B means blobs of bytes. T means text rendered as +** bytes of UTF-8. +*/ +static void sha3QueryFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + sqlite3 *db = sqlite3_context_db_handle(context); + const char *zSql = (const char*)sqlite3_value_text(argv[0]); + sqlite3_stmt *pStmt = 0; + int nCol; /* Number of columns in the result set */ + int i; /* Loop counter */ + int rc; + int n; + const char *z; + SHA3Context cx; + int iSize; + + if( argc==1 ){ + iSize = 256; + }else{ + iSize = sqlite3_value_int(argv[1]); + if( iSize!=224 && iSize!=256 && iSize!=384 && iSize!=512 ){ + sqlite3_result_error(context, "SHA3 size should be one of: 224 256 " + "384 512", -1); + return; + } + } + if( zSql==0 ) return; + SHA3Init(&cx, iSize); + while( zSql[0] ){ + rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zSql); + if( rc ){ + char *zMsg = sqlite3_mprintf("error SQL statement [%s]: %s", + zSql, sqlite3_errmsg(db)); + sqlite3_finalize(pStmt); + sqlite3_result_error(context, zMsg, -1); + sqlite3_free(zMsg); + return; + } + if( !sqlite3_stmt_readonly(pStmt) ){ + char *zMsg = sqlite3_mprintf("non-query: [%s]", sqlite3_sql(pStmt)); + sqlite3_finalize(pStmt); + sqlite3_result_error(context, zMsg, -1); + sqlite3_free(zMsg); + return; + } + nCol = sqlite3_column_count(pStmt); + z = sqlite3_sql(pStmt); + n = (int)strlen(z); + hash_step_vformat(&cx,"S%d:",n); + SHA3Update(&cx,(unsigned char*)z,n); + + /* Compute a hash over the result of the query */ + while( SQLITE_ROW==sqlite3_step(pStmt) ){ + SHA3Update(&cx,(const unsigned char*)"R",1); + for(i=0; i=1; j--){ + x[j] = u & 0xff; + u >>= 8; + } + x[0] = 'I'; + SHA3Update(&cx, x, 9); + break; + } + case SQLITE_FLOAT: { + sqlite3_uint64 u; + int j; + unsigned char x[9]; + double r = sqlite3_column_double(pStmt,i); + memcpy(&u, &r, 8); + for(j=8; j>=1; j--){ + x[j] = u & 0xff; + u >>= 8; + } + x[0] = 'F'; + SHA3Update(&cx,x,9); + break; + } + case SQLITE_TEXT: { + int n2 = sqlite3_column_bytes(pStmt, i); + const unsigned char *z2 = sqlite3_column_text(pStmt, i); + hash_step_vformat(&cx,"T%d:",n2); + SHA3Update(&cx, z2, n2); + break; + } + case SQLITE_BLOB: { + int n2 = sqlite3_column_bytes(pStmt, i); + const unsigned char *z2 = sqlite3_column_blob(pStmt, i); + hash_step_vformat(&cx,"B%d:",n2); + SHA3Update(&cx, z2, n2); + break; + } + } + } + } + sqlite3_finalize(pStmt); + } + sqlite3_result_blob(context, SHA3Final(&cx), iSize/8, SQLITE_TRANSIENT); +} + + +#ifdef _WIN32 +__declspec(dllexport) +#endif +int sqlite3_shathree_init( + sqlite3 *db, + char **pzErrMsg, + const sqlite3_api_routines *pApi +){ + int rc = SQLITE_OK; + SQLITE_EXTENSION_INIT2(pApi); + (void)pzErrMsg; /* Unused parameter */ + rc = sqlite3_create_function(db, "sha3", 1, SQLITE_UTF8, 0, + sha3Func, 0, 0); + if( rc==SQLITE_OK ){ + rc = sqlite3_create_function(db, "sha3", 2, SQLITE_UTF8, 0, + sha3Func, 0, 0); + } + if( rc==SQLITE_OK ){ + rc = sqlite3_create_function(db, "sha3_query", 1, SQLITE_UTF8, 0, + sha3QueryFunc, 0, 0); + } + if( rc==SQLITE_OK ){ + rc = sqlite3_create_function(db, "sha3_query", 2, SQLITE_UTF8, 0, + sha3QueryFunc, 0, 0); + } + return rc; +} diff --git a/manifest b/manifest index 92484569a1..1056796a52 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\sthe\sCLI,\savoid\sunnecessary\sidentifier\squoting\sin\sthe\s".dump"\soutput.\nAlso\sadd\snew\s".dump"\stest\scases. -D 2017-03-08T12:25:18.771 +C Add\sthe\sshathree.c\sextension\sfor\simplementing\sSHA3()\sand\sSHA3_QUERY()\sSQL\nfunctions. +D 2017-03-08T13:50:40.092 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 @@ -225,6 +225,7 @@ F ext/misc/rot13.c 1ac6f95f99b575907b9b09c81a349114cf9be45a F ext/misc/scrub.c 1c5bfb8b0cd18b602fcb55755e84abf0023ac2fb F ext/misc/series.c e11e534ada797d5b816d7e7a93c022306563ca35 F ext/misc/sha1.c 0b9e9b855354910d3ca467bf39099d570e73db56 +F ext/misc/shathree.c 465f508eb588e6389a8403fc9cf1e9924dcbc581 w ext/misc/sha3b.c F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52 F ext/misc/spellfix.c a4723b6aff748a417b5091b68a46443265c40f0d F ext/misc/totype.c 4a167594e791abeed95e0a8db028822b5e8fe512 @@ -1563,7 +1564,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P c60aee24714a47ce12ee2a4dcefb9f55211d3761 -R b3f6f7a6c1a0fc140ee14b2a6ca3bfe0 +P de65f907610a59e64cbf2214789c11f7117a86a6 +R 23823589b279aa36324ed0cbad2b7a8d U drh -Z f9eff36eb51a780bc84edce006ee1256 +Z 7be543a90293390e2947c08c40f4663a diff --git a/manifest.uuid b/manifest.uuid index 775616cedc..43cc4100d3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -de65f907610a59e64cbf2214789c11f7117a86a6 \ No newline at end of file +f7ca9193ddafd3676406bdfeb1b7d21182c2a3c1 \ No newline at end of file From 4146b4e34a29a1710a343f585460f7372ea1af09 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 8 Mar 2017 15:03:12 +0000 Subject: [PATCH 1398/1484] Improved comments explaining the sha3_query() format. Fix a performance #ifdef error in the sha3 implementation. FossilOrigin-Name: 54ef7abd7f5b16f4b29c9519d283e142c9340fbf --- ext/misc/shathree.c | 19 +++++++++++++------ manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 20 insertions(+), 13 deletions(-) diff --git a/ext/misc/shathree.c b/ext/misc/shathree.c index a27faedb3f..52bfdb0363 100644 --- a/ext/misc/shathree.c +++ b/ext/misc/shathree.c @@ -442,7 +442,7 @@ static void SHA3Update( } #endif for(; iu.x[p->nLoaded] ^= aData[i]; #elif SHA3_BYTEORDER==4321 p->u.x[p->nLoaded^0x07] ^= aData[i]; @@ -556,12 +556,19 @@ static void hash_step_vformat( ** T: ** ** is the original SQL text for each statement run and is -** the size of that text. A single R character occurs before the -** start of each row. N means a NULL value. I mean an 8-byte -** little-endian integer . F is a floating point number with -** an 8-byte little-endian IEEE floating point value . +** the size of that text. The SQL text is UTF-8. A single R character +** occurs before the start of each row. N means a NULL value. +** I mean an 8-byte little-endian integer . F is a floating point +** number with an 8-byte little-endian IEEE floating point value . ** B means blobs of bytes. T means text rendered as -** bytes of UTF-8. +** bytes of UTF-8. The and values are expressed as an ASCII +** text integers. +** +** For each SQL statement in the X input, there is one S segment. Each +** S segment is followed by zero or more R segments, one for each row in the +** result set. After each R, there are one or more N, I, F, B, or T segments, +** one for each column in the result set. Segments are concatentated directly +** with no delimiters of any kind. */ static void sha3QueryFunc( sqlite3_context *context, diff --git a/manifest b/manifest index 1056796a52..a10092847b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sshathree.c\sextension\sfor\simplementing\sSHA3()\sand\sSHA3_QUERY()\sSQL\nfunctions. -D 2017-03-08T13:50:40.092 +C Improved\scomments\sexplaining\sthe\ssha3_query()\sformat.\s\sFix\sa\sperformance\s#ifdef\nerror\sin\sthe\ssha3\simplementation. +D 2017-03-08T15:03:12.217 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 @@ -225,7 +225,7 @@ F ext/misc/rot13.c 1ac6f95f99b575907b9b09c81a349114cf9be45a F ext/misc/scrub.c 1c5bfb8b0cd18b602fcb55755e84abf0023ac2fb F ext/misc/series.c e11e534ada797d5b816d7e7a93c022306563ca35 F ext/misc/sha1.c 0b9e9b855354910d3ca467bf39099d570e73db56 -F ext/misc/shathree.c 465f508eb588e6389a8403fc9cf1e9924dcbc581 w ext/misc/sha3b.c +F ext/misc/shathree.c 38aa4c3c3d3c3fc34b8ea367bed299d8d8a224b2 F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52 F ext/misc/spellfix.c a4723b6aff748a417b5091b68a46443265c40f0d F ext/misc/totype.c 4a167594e791abeed95e0a8db028822b5e8fe512 @@ -1564,7 +1564,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P de65f907610a59e64cbf2214789c11f7117a86a6 -R 23823589b279aa36324ed0cbad2b7a8d +P f7ca9193ddafd3676406bdfeb1b7d21182c2a3c1 +R 702b29708c528596102031b1a9ef3803 U drh -Z 7be543a90293390e2947c08c40f4663a +Z d26e763b8a8a90fd62d33b05211ec0e3 diff --git a/manifest.uuid b/manifest.uuid index 43cc4100d3..1a49212972 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f7ca9193ddafd3676406bdfeb1b7d21182c2a3c1 \ No newline at end of file +54ef7abd7f5b16f4b29c9519d283e142c9340fbf \ No newline at end of file From 1554bc8a2e7335ef39e39383710894942dcc9f54 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 8 Mar 2017 16:10:34 +0000 Subject: [PATCH 1399/1484] Add the ".sha3sum" command to the CLI - used to compute a cryptographic hash of the content of a database file or of individual tables with in that file. FossilOrigin-Name: fc663799075a22b0a61a6a114116bb2d1b96d4ab --- manifest | 12 +- manifest.uuid | 2 +- src/shell.c | 751 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 758 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index a10092847b..97d4af1fb1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improved\scomments\sexplaining\sthe\ssha3_query()\sformat.\s\sFix\sa\sperformance\s#ifdef\nerror\sin\sthe\ssha3\simplementation. -D 2017-03-08T15:03:12.217 +C Add\sthe\s".sha3sum"\scommand\sto\sthe\sCLI\s-\sused\sto\scompute\sa\scryptographic\shash\nof\sthe\scontent\sof\sa\sdatabase\sfile\sor\sof\sindividual\stables\swith\sin\nthat\sfile. +D 2017-03-08T16:10:34.827 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 @@ -400,7 +400,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 3e518b962d932a997fae373366880fc028c75706 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c d12f3539f80db38b09015561b569e0eb1c4b6c5f -F src/shell.c d1ba571e8325f727f0c9571079e27b8a4595d6fd +F src/shell.c 8cebab1fdfb7427216c63a46d9116d31ef06dd55 F src/sqlite.h.in 4d0c08f8640c586564a7032b259c5f69bf397850 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae @@ -1564,7 +1564,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P f7ca9193ddafd3676406bdfeb1b7d21182c2a3c1 -R 702b29708c528596102031b1a9ef3803 +P 54ef7abd7f5b16f4b29c9519d283e142c9340fbf +R 1784a0b42056ce37f7cf91782b133804 U drh -Z d26e763b8a8a90fd62d33b05211ec0e3 +Z 89ed86e3a2610bc780c3304d2a434090 diff --git a/manifest.uuid b/manifest.uuid index 1a49212972..c49a19c8c2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -54ef7abd7f5b16f4b29c9519d283e142c9340fbf \ No newline at end of file +fc663799075a22b0a61a6a114116bb2d1b96d4ab \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 321a39f54b..06cf36cccc 100644 --- a/src/shell.c +++ b/src/shell.c @@ -673,6 +673,658 @@ static char quoteChar(const char *zName){ return 0; } +/****************************************************************************** +** SHA3 hash implementation copied from ../ext/misc/shathree.c +*/ +typedef sqlite3_uint64 u64; +/* +** Macros to determine whether the machine is big or little endian, +** and whether or not that determination is run-time or compile-time. +** +** For best performance, an attempt is made to guess at the byte-order +** using C-preprocessor macros. If that is unsuccessful, or if +** -DSHA3_BYTEORDER=0 is set, then byte-order is determined +** at run-time. +*/ +#ifndef SHA3_BYTEORDER +# if defined(i386) || defined(__i386__) || defined(_M_IX86) || \ + defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \ + defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) || \ + defined(__arm__) +# define SHA3_BYTEORDER 1234 +# elif defined(sparc) || defined(__ppc__) +# define SHA3_BYTEORDER 4321 +# else +# define SHA3_BYTEORDER 0 +# endif +#endif + + +/* +** State structure for a SHA3 hash in progress +*/ +typedef struct SHA3Context SHA3Context; +struct SHA3Context { + union { + u64 s[25]; /* Keccak state. 5x5 lines of 64 bits each */ + unsigned char x[1600]; /* ... or 1600 bytes */ + } u; + unsigned nRate; /* Bytes of input accepted per Keccak iteration */ + unsigned nLoaded; /* Input bytes loaded into u.x[] so far this cycle */ + unsigned ixMask; /* Insert next input into u.x[nLoaded^ixMask]. */ +}; + +/* +** A single step of the Keccak mixing function for a 1600-bit state +*/ +static void KeccakF1600Step(SHA3Context *p){ + int i; + u64 B0, B1, B2, B3, B4; + u64 C0, C1, C2, C3, C4; + u64 D0, D1, D2, D3, D4; + static const u64 RC[] = { + 0x0000000000000001ULL, 0x0000000000008082ULL, + 0x800000000000808aULL, 0x8000000080008000ULL, + 0x000000000000808bULL, 0x0000000080000001ULL, + 0x8000000080008081ULL, 0x8000000000008009ULL, + 0x000000000000008aULL, 0x0000000000000088ULL, + 0x0000000080008009ULL, 0x000000008000000aULL, + 0x000000008000808bULL, 0x800000000000008bULL, + 0x8000000000008089ULL, 0x8000000000008003ULL, + 0x8000000000008002ULL, 0x8000000000000080ULL, + 0x000000000000800aULL, 0x800000008000000aULL, + 0x8000000080008081ULL, 0x8000000000008080ULL, + 0x0000000080000001ULL, 0x8000000080008008ULL + }; +# define A00 (p->u.s[0]) +# define A01 (p->u.s[1]) +# define A02 (p->u.s[2]) +# define A03 (p->u.s[3]) +# define A04 (p->u.s[4]) +# define A10 (p->u.s[5]) +# define A11 (p->u.s[6]) +# define A12 (p->u.s[7]) +# define A13 (p->u.s[8]) +# define A14 (p->u.s[9]) +# define A20 (p->u.s[10]) +# define A21 (p->u.s[11]) +# define A22 (p->u.s[12]) +# define A23 (p->u.s[13]) +# define A24 (p->u.s[14]) +# define A30 (p->u.s[15]) +# define A31 (p->u.s[16]) +# define A32 (p->u.s[17]) +# define A33 (p->u.s[18]) +# define A34 (p->u.s[19]) +# define A40 (p->u.s[20]) +# define A41 (p->u.s[21]) +# define A42 (p->u.s[22]) +# define A43 (p->u.s[23]) +# define A44 (p->u.s[24]) +# define ROL64(a,x) ((a<>(64-x))) + + for(i=0; i<24; i+=4){ + C0 = A00^A10^A20^A30^A40; + C1 = A01^A11^A21^A31^A41; + C2 = A02^A12^A22^A32^A42; + C3 = A03^A13^A23^A33^A43; + C4 = A04^A14^A24^A34^A44; + D0 = C4^ROL64(C1, 1); + D1 = C0^ROL64(C2, 1); + D2 = C1^ROL64(C3, 1); + D3 = C2^ROL64(C4, 1); + D4 = C3^ROL64(C0, 1); + + B0 = (A00^D0); + B1 = ROL64((A11^D1), 44); + B2 = ROL64((A22^D2), 43); + B3 = ROL64((A33^D3), 21); + B4 = ROL64((A44^D4), 14); + A00 = B0 ^((~B1)& B2 ); + A00 ^= RC[i]; + A11 = B1 ^((~B2)& B3 ); + A22 = B2 ^((~B3)& B4 ); + A33 = B3 ^((~B4)& B0 ); + A44 = B4 ^((~B0)& B1 ); + + B2 = ROL64((A20^D0), 3); + B3 = ROL64((A31^D1), 45); + B4 = ROL64((A42^D2), 61); + B0 = ROL64((A03^D3), 28); + B1 = ROL64((A14^D4), 20); + A20 = B0 ^((~B1)& B2 ); + A31 = B1 ^((~B2)& B3 ); + A42 = B2 ^((~B3)& B4 ); + A03 = B3 ^((~B4)& B0 ); + A14 = B4 ^((~B0)& B1 ); + + B4 = ROL64((A40^D0), 18); + B0 = ROL64((A01^D1), 1); + B1 = ROL64((A12^D2), 6); + B2 = ROL64((A23^D3), 25); + B3 = ROL64((A34^D4), 8); + A40 = B0 ^((~B1)& B2 ); + A01 = B1 ^((~B2)& B3 ); + A12 = B2 ^((~B3)& B4 ); + A23 = B3 ^((~B4)& B0 ); + A34 = B4 ^((~B0)& B1 ); + + B1 = ROL64((A10^D0), 36); + B2 = ROL64((A21^D1), 10); + B3 = ROL64((A32^D2), 15); + B4 = ROL64((A43^D3), 56); + B0 = ROL64((A04^D4), 27); + A10 = B0 ^((~B1)& B2 ); + A21 = B1 ^((~B2)& B3 ); + A32 = B2 ^((~B3)& B4 ); + A43 = B3 ^((~B4)& B0 ); + A04 = B4 ^((~B0)& B1 ); + + B3 = ROL64((A30^D0), 41); + B4 = ROL64((A41^D1), 2); + B0 = ROL64((A02^D2), 62); + B1 = ROL64((A13^D3), 55); + B2 = ROL64((A24^D4), 39); + A30 = B0 ^((~B1)& B2 ); + A41 = B1 ^((~B2)& B3 ); + A02 = B2 ^((~B3)& B4 ); + A13 = B3 ^((~B4)& B0 ); + A24 = B4 ^((~B0)& B1 ); + + C0 = A00^A20^A40^A10^A30; + C1 = A11^A31^A01^A21^A41; + C2 = A22^A42^A12^A32^A02; + C3 = A33^A03^A23^A43^A13; + C4 = A44^A14^A34^A04^A24; + D0 = C4^ROL64(C1, 1); + D1 = C0^ROL64(C2, 1); + D2 = C1^ROL64(C3, 1); + D3 = C2^ROL64(C4, 1); + D4 = C3^ROL64(C0, 1); + + B0 = (A00^D0); + B1 = ROL64((A31^D1), 44); + B2 = ROL64((A12^D2), 43); + B3 = ROL64((A43^D3), 21); + B4 = ROL64((A24^D4), 14); + A00 = B0 ^((~B1)& B2 ); + A00 ^= RC[i+1]; + A31 = B1 ^((~B2)& B3 ); + A12 = B2 ^((~B3)& B4 ); + A43 = B3 ^((~B4)& B0 ); + A24 = B4 ^((~B0)& B1 ); + + B2 = ROL64((A40^D0), 3); + B3 = ROL64((A21^D1), 45); + B4 = ROL64((A02^D2), 61); + B0 = ROL64((A33^D3), 28); + B1 = ROL64((A14^D4), 20); + A40 = B0 ^((~B1)& B2 ); + A21 = B1 ^((~B2)& B3 ); + A02 = B2 ^((~B3)& B4 ); + A33 = B3 ^((~B4)& B0 ); + A14 = B4 ^((~B0)& B1 ); + + B4 = ROL64((A30^D0), 18); + B0 = ROL64((A11^D1), 1); + B1 = ROL64((A42^D2), 6); + B2 = ROL64((A23^D3), 25); + B3 = ROL64((A04^D4), 8); + A30 = B0 ^((~B1)& B2 ); + A11 = B1 ^((~B2)& B3 ); + A42 = B2 ^((~B3)& B4 ); + A23 = B3 ^((~B4)& B0 ); + A04 = B4 ^((~B0)& B1 ); + + B1 = ROL64((A20^D0), 36); + B2 = ROL64((A01^D1), 10); + B3 = ROL64((A32^D2), 15); + B4 = ROL64((A13^D3), 56); + B0 = ROL64((A44^D4), 27); + A20 = B0 ^((~B1)& B2 ); + A01 = B1 ^((~B2)& B3 ); + A32 = B2 ^((~B3)& B4 ); + A13 = B3 ^((~B4)& B0 ); + A44 = B4 ^((~B0)& B1 ); + + B3 = ROL64((A10^D0), 41); + B4 = ROL64((A41^D1), 2); + B0 = ROL64((A22^D2), 62); + B1 = ROL64((A03^D3), 55); + B2 = ROL64((A34^D4), 39); + A10 = B0 ^((~B1)& B2 ); + A41 = B1 ^((~B2)& B3 ); + A22 = B2 ^((~B3)& B4 ); + A03 = B3 ^((~B4)& B0 ); + A34 = B4 ^((~B0)& B1 ); + + C0 = A00^A40^A30^A20^A10; + C1 = A31^A21^A11^A01^A41; + C2 = A12^A02^A42^A32^A22; + C3 = A43^A33^A23^A13^A03; + C4 = A24^A14^A04^A44^A34; + D0 = C4^ROL64(C1, 1); + D1 = C0^ROL64(C2, 1); + D2 = C1^ROL64(C3, 1); + D3 = C2^ROL64(C4, 1); + D4 = C3^ROL64(C0, 1); + + B0 = (A00^D0); + B1 = ROL64((A21^D1), 44); + B2 = ROL64((A42^D2), 43); + B3 = ROL64((A13^D3), 21); + B4 = ROL64((A34^D4), 14); + A00 = B0 ^((~B1)& B2 ); + A00 ^= RC[i+2]; + A21 = B1 ^((~B2)& B3 ); + A42 = B2 ^((~B3)& B4 ); + A13 = B3 ^((~B4)& B0 ); + A34 = B4 ^((~B0)& B1 ); + + B2 = ROL64((A30^D0), 3); + B3 = ROL64((A01^D1), 45); + B4 = ROL64((A22^D2), 61); + B0 = ROL64((A43^D3), 28); + B1 = ROL64((A14^D4), 20); + A30 = B0 ^((~B1)& B2 ); + A01 = B1 ^((~B2)& B3 ); + A22 = B2 ^((~B3)& B4 ); + A43 = B3 ^((~B4)& B0 ); + A14 = B4 ^((~B0)& B1 ); + + B4 = ROL64((A10^D0), 18); + B0 = ROL64((A31^D1), 1); + B1 = ROL64((A02^D2), 6); + B2 = ROL64((A23^D3), 25); + B3 = ROL64((A44^D4), 8); + A10 = B0 ^((~B1)& B2 ); + A31 = B1 ^((~B2)& B3 ); + A02 = B2 ^((~B3)& B4 ); + A23 = B3 ^((~B4)& B0 ); + A44 = B4 ^((~B0)& B1 ); + + B1 = ROL64((A40^D0), 36); + B2 = ROL64((A11^D1), 10); + B3 = ROL64((A32^D2), 15); + B4 = ROL64((A03^D3), 56); + B0 = ROL64((A24^D4), 27); + A40 = B0 ^((~B1)& B2 ); + A11 = B1 ^((~B2)& B3 ); + A32 = B2 ^((~B3)& B4 ); + A03 = B3 ^((~B4)& B0 ); + A24 = B4 ^((~B0)& B1 ); + + B3 = ROL64((A20^D0), 41); + B4 = ROL64((A41^D1), 2); + B0 = ROL64((A12^D2), 62); + B1 = ROL64((A33^D3), 55); + B2 = ROL64((A04^D4), 39); + A20 = B0 ^((~B1)& B2 ); + A41 = B1 ^((~B2)& B3 ); + A12 = B2 ^((~B3)& B4 ); + A33 = B3 ^((~B4)& B0 ); + A04 = B4 ^((~B0)& B1 ); + + C0 = A00^A30^A10^A40^A20; + C1 = A21^A01^A31^A11^A41; + C2 = A42^A22^A02^A32^A12; + C3 = A13^A43^A23^A03^A33; + C4 = A34^A14^A44^A24^A04; + D0 = C4^ROL64(C1, 1); + D1 = C0^ROL64(C2, 1); + D2 = C1^ROL64(C3, 1); + D3 = C2^ROL64(C4, 1); + D4 = C3^ROL64(C0, 1); + + B0 = (A00^D0); + B1 = ROL64((A01^D1), 44); + B2 = ROL64((A02^D2), 43); + B3 = ROL64((A03^D3), 21); + B4 = ROL64((A04^D4), 14); + A00 = B0 ^((~B1)& B2 ); + A00 ^= RC[i+3]; + A01 = B1 ^((~B2)& B3 ); + A02 = B2 ^((~B3)& B4 ); + A03 = B3 ^((~B4)& B0 ); + A04 = B4 ^((~B0)& B1 ); + + B2 = ROL64((A10^D0), 3); + B3 = ROL64((A11^D1), 45); + B4 = ROL64((A12^D2), 61); + B0 = ROL64((A13^D3), 28); + B1 = ROL64((A14^D4), 20); + A10 = B0 ^((~B1)& B2 ); + A11 = B1 ^((~B2)& B3 ); + A12 = B2 ^((~B3)& B4 ); + A13 = B3 ^((~B4)& B0 ); + A14 = B4 ^((~B0)& B1 ); + + B4 = ROL64((A20^D0), 18); + B0 = ROL64((A21^D1), 1); + B1 = ROL64((A22^D2), 6); + B2 = ROL64((A23^D3), 25); + B3 = ROL64((A24^D4), 8); + A20 = B0 ^((~B1)& B2 ); + A21 = B1 ^((~B2)& B3 ); + A22 = B2 ^((~B3)& B4 ); + A23 = B3 ^((~B4)& B0 ); + A24 = B4 ^((~B0)& B1 ); + + B1 = ROL64((A30^D0), 36); + B2 = ROL64((A31^D1), 10); + B3 = ROL64((A32^D2), 15); + B4 = ROL64((A33^D3), 56); + B0 = ROL64((A34^D4), 27); + A30 = B0 ^((~B1)& B2 ); + A31 = B1 ^((~B2)& B3 ); + A32 = B2 ^((~B3)& B4 ); + A33 = B3 ^((~B4)& B0 ); + A34 = B4 ^((~B0)& B1 ); + + B3 = ROL64((A40^D0), 41); + B4 = ROL64((A41^D1), 2); + B0 = ROL64((A42^D2), 62); + B1 = ROL64((A43^D3), 55); + B2 = ROL64((A44^D4), 39); + A40 = B0 ^((~B1)& B2 ); + A41 = B1 ^((~B2)& B3 ); + A42 = B2 ^((~B3)& B4 ); + A43 = B3 ^((~B4)& B0 ); + A44 = B4 ^((~B0)& B1 ); + } +} + +/* +** Initialize a new hash. iSize determines the size of the hash +** in bits and should be one of 224, 256, 384, or 512. Or iSize +** can be zero to use the default hash size of 256 bits. +*/ +static void SHA3Init(SHA3Context *p, int iSize){ + memset(p, 0, sizeof(*p)); + if( iSize>=128 && iSize<=512 ){ + p->nRate = (1600 - ((iSize + 31)&~31)*2)/8; + }else{ + p->nRate = (1600 - 2*256)/8; + } +#if SHA3_BYTEORDER==1234 + /* Known to be little-endian at compile-time. No-op */ +#elif SHA3_BYTEORDER==4321 + p->ixMask = 7; /* Big-endian */ +#else + { + static unsigned int one = 1; + if( 1==*(unsigned char*)&one ){ + /* Little endian. No byte swapping. */ + p->ixMask = 0; + }else{ + /* Big endian. Byte swap. */ + p->ixMask = 7; + } + } +#endif +} + +/* +** Make consecutive calls to the SHA3Update function to add new content +** to the hash +*/ +static void SHA3Update( + SHA3Context *p, + const unsigned char *aData, + unsigned int nData +){ + unsigned int i = 0; +#if SHA3_BYTEORDER==1234 + if( (p->nLoaded % 8)==0 && ((aData - (const unsigned char*)0)&7)==0 ){ + for(; i+7u.s[p->nLoaded/8] ^= *(u64*)&aData[i]; + p->nLoaded += 8; + if( p->nLoaded>=p->nRate ){ + KeccakF1600Step(p); + p->nLoaded = 0; + } + } + } +#endif + for(; iu.x[p->nLoaded] ^= aData[i]; +#elif SHA3_BYTEORDER==4321 + p->u.x[p->nLoaded^0x07] ^= aData[i]; +#else + p->u.x[p->nLoaded^p->ixMask] ^= aData[i]; +#endif + p->nLoaded++; + if( p->nLoaded==p->nRate ){ + KeccakF1600Step(p); + p->nLoaded = 0; + } + } +} + +/* +** After all content has been added, invoke SHA3Final() to compute +** the final hash. The function returns a pointer to the binary +** hash value. +*/ +static unsigned char *SHA3Final(SHA3Context *p){ + unsigned int i; + if( p->nLoaded==p->nRate-1 ){ + const unsigned char c1 = 0x86; + SHA3Update(p, &c1, 1); + }else{ + const unsigned char c2 = 0x06; + const unsigned char c3 = 0x80; + SHA3Update(p, &c2, 1); + p->nLoaded = p->nRate - 1; + SHA3Update(p, &c3, 1); + } + for(i=0; inRate; i++){ + p->u.x[i+p->nRate] = p->u.x[i^p->ixMask]; + } + return &p->u.x[p->nRate]; +} + +/* +** Implementation of the sha3(X,SIZE) function. +** +** Return a BLOB which is the SIZE-bit SHA3 hash of X. The default +** size is 256. If X is a BLOB, it is hashed as is. +** For all other non-NULL types of input, X is converted into a UTF-8 string +** and the string is hashed without the trailing 0x00 terminator. The hash +** of a NULL value is NULL. +*/ +static void sha3Func( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + SHA3Context cx; + int eType = sqlite3_value_type(argv[0]); + int nByte = sqlite3_value_bytes(argv[0]); + int iSize; + if( argc==1 ){ + iSize = 256; + }else{ + iSize = sqlite3_value_int(argv[1]); + if( iSize!=224 && iSize!=256 && iSize!=384 && iSize!=512 ){ + sqlite3_result_error(context, "SHA3 size should be one of: 224 256 " + "384 512", -1); + return; + } + } + if( eType==SQLITE_NULL ) return; + SHA3Init(&cx, iSize); + if( eType==SQLITE_BLOB ){ + SHA3Update(&cx, sqlite3_value_blob(argv[0]), nByte); + }else{ + SHA3Update(&cx, sqlite3_value_text(argv[0]), nByte); + } + sqlite3_result_blob(context, SHA3Final(&cx), iSize/8, SQLITE_TRANSIENT); +} + +/* Compute a string using sqlite3_vsnprintf() with a maximum length +** of 50 bytes and add it to the hash. +*/ +static void hash_step_vformat( + SHA3Context *p, /* Add content to this context */ + const char *zFormat, + ... +){ + va_list ap; + int n; + char zBuf[50]; + va_start(ap, zFormat); + sqlite3_vsnprintf(sizeof(zBuf),zBuf,zFormat,ap); + va_end(ap); + n = (int)strlen(zBuf); + SHA3Update(p, (unsigned char*)zBuf, n); +} + +/* +** Implementation of the sha3_query(SQL,SIZE) function. +** +** This function compiles and runs the SQL statement(s) given in the +** argument. The results are hashed using a SIZE-bit SHA3. The default +** size is 256. +** +** The format of the byte stream that is hashed is summarized as follows: +** +** S: +** R +** N +** I +** F +** B: +** T: +** +** is the original SQL text for each statement run and is +** the size of that text. The SQL text is UTF-8. A single R character +** occurs before the start of each row. N means a NULL value. +** I mean an 8-byte little-endian integer . F is a floating point +** number with an 8-byte little-endian IEEE floating point value . +** B means blobs of bytes. T means text rendered as +** bytes of UTF-8. The and values are expressed as an ASCII +** text integers. +** +** For each SQL statement in the X input, there is one S segment. Each +** S segment is followed by zero or more R segments, one for each row in the +** result set. After each R, there are one or more N, I, F, B, or T segments, +** one for each column in the result set. Segments are concatentated directly +** with no delimiters of any kind. +*/ +static void sha3QueryFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + sqlite3 *db = sqlite3_context_db_handle(context); + const char *zSql = (const char*)sqlite3_value_text(argv[0]); + sqlite3_stmt *pStmt = 0; + int nCol; /* Number of columns in the result set */ + int i; /* Loop counter */ + int rc; + int n; + const char *z; + SHA3Context cx; + int iSize; + + if( argc==1 ){ + iSize = 256; + }else{ + iSize = sqlite3_value_int(argv[1]); + if( iSize!=224 && iSize!=256 && iSize!=384 && iSize!=512 ){ + sqlite3_result_error(context, "SHA3 size should be one of: 224 256 " + "384 512", -1); + return; + } + } + if( zSql==0 ) return; + SHA3Init(&cx, iSize); + while( zSql[0] ){ + rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zSql); + if( rc ){ + char *zMsg = sqlite3_mprintf("error SQL statement [%s]: %s", + zSql, sqlite3_errmsg(db)); + sqlite3_finalize(pStmt); + sqlite3_result_error(context, zMsg, -1); + sqlite3_free(zMsg); + return; + } + if( !sqlite3_stmt_readonly(pStmt) ){ + char *zMsg = sqlite3_mprintf("non-query: [%s]", sqlite3_sql(pStmt)); + sqlite3_finalize(pStmt); + sqlite3_result_error(context, zMsg, -1); + sqlite3_free(zMsg); + return; + } + nCol = sqlite3_column_count(pStmt); + z = sqlite3_sql(pStmt); + n = (int)strlen(z); + hash_step_vformat(&cx,"S%d:",n); + SHA3Update(&cx,(unsigned char*)z,n); + + /* Compute a hash over the result of the query */ + while( SQLITE_ROW==sqlite3_step(pStmt) ){ + SHA3Update(&cx,(const unsigned char*)"R",1); + for(i=0; i=1; j--){ + x[j] = u & 0xff; + u >>= 8; + } + x[0] = 'I'; + SHA3Update(&cx, x, 9); + break; + } + case SQLITE_FLOAT: { + sqlite3_uint64 u; + int j; + unsigned char x[9]; + double r = sqlite3_column_double(pStmt,i); + memcpy(&u, &r, 8); + for(j=8; j>=1; j--){ + x[j] = u & 0xff; + u >>= 8; + } + x[0] = 'F'; + SHA3Update(&cx,x,9); + break; + } + case SQLITE_TEXT: { + int n2 = sqlite3_column_bytes(pStmt, i); + const unsigned char *z2 = sqlite3_column_text(pStmt, i); + hash_step_vformat(&cx,"T%d:",n2); + SHA3Update(&cx, z2, n2); + break; + } + case SQLITE_BLOB: { + int n2 = sqlite3_column_bytes(pStmt, i); + const unsigned char *z2 = sqlite3_column_blob(pStmt, i); + hash_step_vformat(&cx,"B%d:",n2); + SHA3Update(&cx, z2, n2); + break; + } + } + } + } + sqlite3_finalize(pStmt); + } + sqlite3_result_blob(context, SHA3Final(&cx), iSize/8, SQLITE_TRANSIENT); +} +/* End of SHA3 hashing logic copy/pasted from ../ext/misc/shathree.c +********************************************************************************/ + #if defined(SQLITE_ENABLE_SESSION) /* ** State information for a single open session @@ -2402,6 +3054,7 @@ static char zHelp[] = #if defined(SQLITE_ENABLE_SESSION) ".session CMD ... Create or control sessions\n" #endif + ".sha3sum ?OPTIONS...? Compute a SHA3 hash of database content\n" ".shell CMD ARGS... Run CMD ARGS... in a system shell\n" ".show Show the current values for various settings\n" ".stats ?on|off? Show stats or turn stats on or off\n" @@ -2605,6 +3258,14 @@ static void open_db(ShellState *p, int keepAlive){ readfileFunc, 0, 0); sqlite3_create_function(p->db, "writefile", 2, SQLITE_UTF8, 0, writefileFunc, 0, 0); + sqlite3_create_function(p->db, "sha3", 1, SQLITE_UTF8, 0, + sha3Func, 0, 0); + sqlite3_create_function(p->db, "sha3", 2, SQLITE_UTF8, 0, + sha3Func, 0, 0); + sqlite3_create_function(p->db, "sha3_query", 1, SQLITE_UTF8, 0, + sha3QueryFunc, 0, 0); + sqlite3_create_function(p->db, "sha3_query", 2, SQLITE_UTF8, 0, + sha3QueryFunc, 0, 0); } } @@ -5036,6 +5697,96 @@ static int do_meta_command(char *zLine, ShellState *p){ } }else + if( c=='s' && n>=4 && strncmp(azArg[0],"sha3sum",n)==0 ){ + const char *zLike = 0; /* Which table to checksum. 0 means everything */ + int i; /* Loop counter */ + int bSchema = 0; /* Also hash the schema */ + int iSize = 224; /* Hash algorithm to use */ + int bDebug = 0; /* Only show the query that would have run */ + sqlite3_stmt *pStmt; /* For querying tables names */ + char *zSql; /* SQL to be run */ + ShellText sQuery; /* Set of queries used to read all content */ + for(i=1; i1" + " UNION ALL SELECT 'sqlite_master'" + " ORDER BY 1 collate nocase"; + }else{ + zSql = "SELECT lower(name) FROM sqlite_master" + " WHERE type='table' AND coalesce(rootpage,0)>1" + " AND name NOT LIKE 'sqlite_%'" + " ORDER BY 1 collate nocase"; + } + sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); + initText(&sQuery); + while( SQLITE_ROW==sqlite3_step(pStmt) ){ + const char *zTab = (const char*)sqlite3_column_text(pStmt,0); + if( zLike && sqlite3_strlike(zLike, zTab, 0)!=0 ) continue; + if( strncmp(zTab, "sqlite_",7)!=0 ){ + appendText(&sQuery,"SELECT * FROM ", 0); + appendText(&sQuery,zTab,'"'); + appendText(&sQuery," NOT INDEXED;", 0); + }else if( strcmp(zTab, "sqlite_master")==0 ){ + appendText(&sQuery,"SELECT type,name,tbl_name,sql FROM sqlite_master" + " ORDER BY name;", 0); + }else if( strcmp(zTab, "sqlite_sequence")==0 ){ + appendText(&sQuery,"SELECT name,seq FROM sqlite_sequence" + " ORDER BY name;", 0); + }else if( strcmp(zTab, "sqlite_stat1")==0 ){ + appendText(&sQuery,"SELECT tbl,idx,stat FROM sqlite_stat1" + " ORDER BY tbl,idx;", 0); + }else if( strcmp(zTab, "sqlite_stat3")==0 + || strcmp(zTab, "sqlite_stat4")==0 ){ + appendText(&sQuery, "SELECT * FROM ", 0); + appendText(&sQuery, zTab, 0); + appendText(&sQuery, " ORDER BY tbl, idx, rowid;\n", 0); + } + } + sqlite3_finalize(pStmt); + zSql = sqlite3_mprintf("SELECT lower(hex(sha3_query(%Q,%d))) AS hash;", + sQuery.z, iSize); + freeText(&sQuery); + if( bDebug ){ + utf8_printf(p->out, "%s\n", zSql); + }else{ + shell_exec(p->db, zSql, shell_callback, p, 0); + } + sqlite3_free(zSql); + }else + if( c=='s' && (strncmp(azArg[0], "shell", n)==0 || strncmp(azArg[0],"system",n)==0) ){ From 3ee83efec1a5d12d1339b55f1e028a8db2641047 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 8 Mar 2017 17:56:54 +0000 Subject: [PATCH 1400/1484] In the ".sha3sum" command, if there is a LIKE pattern, show the hashes for each table separately. Without a LIKE pattern, show a single hash over the entire database. FossilOrigin-Name: 30f878832820ce7ccc4627c4f0f98fbe82f8b0f6 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/shell.c | 37 +++++++++++++++++++++++++++++++++---- 3 files changed, 40 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 97d4af1fb1..ab4ba0a547 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\s".sha3sum"\scommand\sto\sthe\sCLI\s-\sused\sto\scompute\sa\scryptographic\shash\nof\sthe\scontent\sof\sa\sdatabase\sfile\sor\sof\sindividual\stables\swith\sin\nthat\sfile. -D 2017-03-08T16:10:34.827 +C In\sthe\s".sha3sum"\scommand,\sif\sthere\sis\sa\sLIKE\spattern,\sshow\sthe\shashes\sfor\neach\stable\sseparately.\s\sWithout\sa\sLIKE\spattern,\sshow\sa\ssingle\shash\sover\sthe\nentire\sdatabase. +D 2017-03-08T17:56:54.566 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 @@ -400,7 +400,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 3e518b962d932a997fae373366880fc028c75706 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c d12f3539f80db38b09015561b569e0eb1c4b6c5f -F src/shell.c 8cebab1fdfb7427216c63a46d9116d31ef06dd55 +F src/shell.c bf10f16352e930e37d26813b5efbf57e89680922 F src/sqlite.h.in 4d0c08f8640c586564a7032b259c5f69bf397850 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae @@ -1564,7 +1564,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 54ef7abd7f5b16f4b29c9519d283e142c9340fbf -R 1784a0b42056ce37f7cf91782b133804 +P fc663799075a22b0a61a6a114116bb2d1b96d4ab +R ce49cf9f2aa65eda762d2f7f5e9b2cf0 U drh -Z 89ed86e3a2610bc780c3304d2a434090 +Z a6a2f37fa5651fb024df2d5d55e36e09 diff --git a/manifest.uuid b/manifest.uuid index c49a19c8c2..086a9494b1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fc663799075a22b0a61a6a114116bb2d1b96d4ab \ No newline at end of file +30f878832820ce7ccc4627c4f0f98fbe82f8b0f6 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 06cf36cccc..2beea32552 100644 --- a/src/shell.c +++ b/src/shell.c @@ -1260,6 +1260,10 @@ static void sha3QueryFunc( } nCol = sqlite3_column_count(pStmt); z = sqlite3_sql(pStmt); + if( z==0 ){ + sqlite3_finalize(pStmt); + continue; + } n = (int)strlen(z); hash_step_vformat(&cx,"S%d:",n); SHA3Update(&cx,(unsigned char*)z,n); @@ -5701,10 +5705,13 @@ static int do_meta_command(char *zLine, ShellState *p){ const char *zLike = 0; /* Which table to checksum. 0 means everything */ int i; /* Loop counter */ int bSchema = 0; /* Also hash the schema */ + int bSeparate = 0; /* Hash each table separately */ int iSize = 224; /* Hash algorithm to use */ int bDebug = 0; /* Only show the query that would have run */ sqlite3_stmt *pStmt; /* For querying tables names */ char *zSql; /* SQL to be run */ + char *zSep; /* Separator */ + ShellText sSql; /* Complete SQL for the query to run the hash */ ShellText sQuery; /* Set of queries used to read all content */ for(i=1; idb, zSql, -1, &pStmt, 0); initText(&sQuery); + initText(&sSql); + appendText(&sSql, "WITH [sha3sum$query](a,b) AS(",0); + zSep = "VALUES("; while( SQLITE_ROW==sqlite3_step(pStmt) ){ const char *zTab = (const char*)sqlite3_column_text(pStmt,0); if( zLike && sqlite3_strlike(zLike, zTab, 0)!=0 ) continue; @@ -5774,11 +5785,29 @@ static int do_meta_command(char *zLine, ShellState *p){ appendText(&sQuery, zTab, 0); appendText(&sQuery, " ORDER BY tbl, idx, rowid;\n", 0); } + appendText(&sSql, zSep, 0); + appendText(&sSql, sQuery.z, '\''); + sQuery.n = 0; + appendText(&sSql, ",", 0); + appendText(&sSql, zTab, '\''); + zSep = "),("; } sqlite3_finalize(pStmt); - zSql = sqlite3_mprintf("SELECT lower(hex(sha3_query(%Q,%d))) AS hash;", - sQuery.z, iSize); + if( bSeparate ){ + zSql = sqlite3_mprintf( + "%s))" + " SELECT lower(hex(sha3_query(a,%d))) AS hash, b AS label" + " FROM [sha3sum$query]", + sSql.z, iSize); + }else{ + zSql = sqlite3_mprintf( + "%s))" + " SELECT lower(hex(sha3_query(group_concat(a,''),%d))) AS hash" + " FROM [sha3sum$query]", + sSql.z, iSize); + } freeText(&sQuery); + freeText(&sSql); if( bDebug ){ utf8_printf(p->out, "%s\n", zSql); }else{ From f80d4ff59f114f58a49d56406875a8c95f900e54 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 8 Mar 2017 18:06:20 +0000 Subject: [PATCH 1401/1484] Make sure the database connection is open prior to running the ".sha3sum" command. FossilOrigin-Name: 2ea300fb8f7c497f3f092dc91f4305d8431c27d9 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/shell.c | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index ab4ba0a547..4b1051a011 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\sthe\s".sha3sum"\scommand,\sif\sthere\sis\sa\sLIKE\spattern,\sshow\sthe\shashes\sfor\neach\stable\sseparately.\s\sWithout\sa\sLIKE\spattern,\sshow\sa\ssingle\shash\sover\sthe\nentire\sdatabase. -D 2017-03-08T17:56:54.566 +C Make\ssure\sthe\sdatabase\sconnection\sis\sopen\sprior\sto\srunning\sthe\s".sha3sum"\ncommand. +D 2017-03-08T18:06:20.965 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 @@ -400,7 +400,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 3e518b962d932a997fae373366880fc028c75706 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c d12f3539f80db38b09015561b569e0eb1c4b6c5f -F src/shell.c bf10f16352e930e37d26813b5efbf57e89680922 +F src/shell.c 1160c054a483d15213ceb70fdbc383b07eebdf78 F src/sqlite.h.in 4d0c08f8640c586564a7032b259c5f69bf397850 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae @@ -1564,7 +1564,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P fc663799075a22b0a61a6a114116bb2d1b96d4ab -R ce49cf9f2aa65eda762d2f7f5e9b2cf0 +P 30f878832820ce7ccc4627c4f0f98fbe82f8b0f6 +R 15b9925a544b33052292bf7b7cba23e6 U drh -Z a6a2f37fa5651fb024df2d5d55e36e09 +Z d079eee20e78bccc69196e077d629480 diff --git a/manifest.uuid b/manifest.uuid index 086a9494b1..c9f050e5a9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -30f878832820ce7ccc4627c4f0f98fbe82f8b0f6 \ No newline at end of file +2ea300fb8f7c497f3f092dc91f4305d8431c27d9 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 2beea32552..f4d10ef767 100644 --- a/src/shell.c +++ b/src/shell.c @@ -5713,6 +5713,7 @@ static int do_meta_command(char *zLine, ShellState *p){ char *zSep; /* Separator */ ShellText sSql; /* Complete SQL for the query to run the hash */ ShellText sQuery; /* Set of queries used to read all content */ + open_db(p, 0); for(i=1; i Date: Thu, 9 Mar 2017 13:50:49 +0000 Subject: [PATCH 1402/1484] Begin moving separate boolean variables in the ShellState object of the CLI into the shellFlgs bitmask. FossilOrigin-Name: 50eec5d9aa38fab1a85d788356ffdaf6c35d9ece --- manifest | 12 +++++----- manifest.uuid | 2 +- src/shell.c | 63 +++++++++++++++++++++++++++++++++------------------ 3 files changed, 48 insertions(+), 29 deletions(-) diff --git a/manifest b/manifest index 4b1051a011..c8aad6cfb1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\ssure\sthe\sdatabase\sconnection\sis\sopen\sprior\sto\srunning\sthe\s".sha3sum"\ncommand. -D 2017-03-08T18:06:20.965 +C Begin\smoving\sseparate\sboolean\svariables\sin\sthe\sShellState\sobject\sof\sthe\sCLI\ninto\sthe\sshellFlgs\sbitmask. +D 2017-03-09T13:50:49.349 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 @@ -400,7 +400,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 3e518b962d932a997fae373366880fc028c75706 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c d12f3539f80db38b09015561b569e0eb1c4b6c5f -F src/shell.c 1160c054a483d15213ceb70fdbc383b07eebdf78 +F src/shell.c 397e51c3eeb3a9dc21667a0a384eb14403cc5eea F src/sqlite.h.in 4d0c08f8640c586564a7032b259c5f69bf397850 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae @@ -1564,7 +1564,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 30f878832820ce7ccc4627c4f0f98fbe82f8b0f6 -R 15b9925a544b33052292bf7b7cba23e6 +P 2ea300fb8f7c497f3f092dc91f4305d8431c27d9 +R 193fb708e3eeb9be14d6692d9fad8ed4 U drh -Z d079eee20e78bccc69196e077d629480 +Z 6ea8a21fbd5a369fc4273386c415b1f4 diff --git a/manifest.uuid b/manifest.uuid index c9f050e5a9..2f86d48c03 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2ea300fb8f7c497f3f092dc91f4305d8431c27d9 \ No newline at end of file +50eec5d9aa38fab1a85d788356ffdaf6c35d9ece \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index f4d10ef767..1de72f8997 100644 --- a/src/shell.c +++ b/src/shell.c @@ -1361,15 +1361,11 @@ struct SavedModeInfo { typedef struct ShellState ShellState; struct ShellState { sqlite3 *db; /* The database */ - int echoOn; /* True to echo input commands */ int autoExplain; /* Automatically turn on .explain mode */ int autoEQP; /* Run EXPLAIN QUERY PLAN prior to seach SQL stmt */ int statsOn; /* True to display memory stats before each finalize */ int scanstatsOn; /* True to display scan stats before each finalize */ - int countChanges; /* True to display change counts */ - int backslashOn; /* Resolve C-style \x escapes in SQL input text */ int outCount; /* Revert to stdout when reaching zero */ - int preserveRowid; /* Preserver ROWID values on a ".dump" command */ int cnt; /* Number of records displayed so far */ FILE *out; /* Write results here */ FILE *traceOut; /* Output for sqlite3_trace() */ @@ -1407,9 +1403,20 @@ struct ShellState { /* ** These are the allowed shellFlgs values */ -#define SHFLG_Scratch 0x00001 /* The --scratch option is used */ -#define SHFLG_Pagecache 0x00002 /* The --pagecache option is used */ -#define SHFLG_Lookaside 0x00004 /* Lookaside memory is used */ +#define SHFLG_Scratch 0x00000001 /* The --scratch option is used */ +#define SHFLG_Pagecache 0x00000002 /* The --pagecache option is used */ +#define SHFLG_Lookaside 0x00000004 /* Lookaside memory is used */ +#define SHFLG_Backslash 0x00000008 /* The --backslash option is used */ +#define SHFLG_PreserveRowid 0x00000010 /* .dump preserves rowid values */ +#define SHFLG_CountChanges 0x00000020 /* .changes setting */ +#define SHFLG_Echo 0x00000040 /* .echo or --echo setting */ + +/* +** Macros for testing and setting shellFlgs +*/ +#define ShellHasFlag(P,X) (((P)->shellFlgs & (X))!=0) +#define ShellSetFlag(P,X) ((P)->shellFlgs|=(X)) +#define ShellClearFlag(P,X) ((P)->shellFlgs&=(~(X))) /* ** These are the allowed modes. @@ -2639,7 +2646,7 @@ static int shell_exec( } /* echo the sql statement if echo on */ - if( pArg && pArg->echoOn ){ + if( pArg && ShellHasFlag(pArg, SHFLG_Echo) ){ utf8_printf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql); } @@ -2760,7 +2767,7 @@ static char **tableColumnList(ShellState *p, const char *zTab){ int nAlloc = 0; int nPK = 0; /* Number of PRIMARY KEY columns seen */ int isIPK = 0; /* True if one PRIMARY KEY column of type INTEGER */ - int preserveRowid = p->preserveRowid; + int preserveRowid = ShellHasFlag(p, SHFLG_PreserveRowid); int rc; zSql = sqlite3_mprintf("PRAGMA table_info=%Q", zTab); @@ -3394,7 +3401,7 @@ static sqlite3_int64 integerValue(const char *zArg){ ** Interpret zArg as either an integer or a boolean value. Return 1 or 0 ** for TRUE and FALSE. Return the integer value if appropriate. */ -static int booleanValue(char *zArg){ +static int booleanValue(const char *zArg){ int i; if( zArg[0]=='0' && zArg[1]=='x' ){ for(i=2; hexDigitValue(zArg[i])>=0; i++){} @@ -3413,6 +3420,17 @@ static int booleanValue(char *zArg){ return 0; } +/* +** Set or clear a shell flag according to a boolean value. +*/ +static void setOrClearFlag(ShellState *p, unsigned mFlag, const char *zArg){ + if( booleanValue(zArg) ){ + ShellSetFlag(p, mFlag); + }else{ + ShellClearFlag(p, mFlag); + } +} + /* ** Close an output file, assuming it is not stderr or stdout */ @@ -4486,7 +4504,7 @@ static int do_meta_command(char *zLine, ShellState *p){ if( c=='c' && n>=3 && strncmp(azArg[0], "changes", n)==0 ){ if( nArg==2 ){ - p->countChanges = booleanValue(azArg[1]); + setOrClearFlag(p, SHFLG_CountChanges, azArg[1]); }else{ raw_printf(stderr, "Usage: .changes on|off\n"); rc = 1; @@ -4552,13 +4570,13 @@ static int do_meta_command(char *zLine, ShellState *p){ if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){ const char *zLike = 0; int i; - p->preserveRowid = 0; + ShellClearFlag(p, SHFLG_PreserveRowid); for(i=1; ipreserveRowid = 1; + ShellSetFlag(p, SHFLG_PreserveRowid); }else { raw_printf(stderr, "Unknown option \"%s\" on \".dump\"\n", azArg[i]); @@ -4625,7 +4643,7 @@ static int do_meta_command(char *zLine, ShellState *p){ if( c=='e' && strncmp(azArg[0], "echo", n)==0 ){ if( nArg==2 ){ - p->echoOn = booleanValue(azArg[1]); + setOrClearFlag(p, SHFLG_Echo, azArg[1]); }else{ raw_printf(stderr, "Usage: .echo on|off\n"); rc = 1; @@ -5845,7 +5863,8 @@ static int do_meta_command(char *zLine, ShellState *p){ rc = 1; goto meta_command_exit; } - utf8_printf(p->out, "%12.12s: %s\n","echo", azBool[p->echoOn!=0]); + utf8_printf(p->out, "%12.12s: %s\n","echo", + azBool[ShellHasFlag(p, SHFLG_Echo)]); utf8_printf(p->out, "%12.12s: %s\n","eqp", azBool[p->autoEQP&3]); utf8_printf(p->out, "%12.12s: %s\n","explain", p->mode==MODE_Explain ? "on" : p->autoExplain ? "auto" : "off"); @@ -6410,7 +6429,7 @@ static int runOneSqlLine(ShellState *p, char *zSql, FILE *in, int startline){ char *zErrMsg = 0; open_db(p, 0); - if( p->backslashOn ) resolve_backslashes(zSql); + if( ShellHasFlag(p,SHFLG_Backslash) ) resolve_backslashes(zSql); BEGIN_TIMER; rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg); END_TIMER; @@ -6430,7 +6449,7 @@ static int runOneSqlLine(ShellState *p, char *zSql, FILE *in, int startline){ utf8_printf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db)); } return 1; - }else if( p->countChanges ){ + }else if( ShellHasFlag(p, SHFLG_CountChanges) ){ raw_printf(p->out, "changes: %3d total_changes: %d\n", sqlite3_changes(p->db), sqlite3_total_changes(p->db)); } @@ -6473,11 +6492,11 @@ static int process_input(ShellState *p, FILE *in){ } lineno++; if( nSql==0 && _all_whitespace(zLine) ){ - if( p->echoOn ) printf("%s\n", zLine); + if( ShellHasFlag(p, SHFLG_Echo) ) printf("%s\n", zLine); continue; } if( zLine && zLine[0]=='.' && nSql==0 ){ - if( p->echoOn ) printf("%s\n", zLine); + if( ShellHasFlag(p, SHFLG_Echo) ) printf("%s\n", zLine); rc = do_meta_command(zLine, p); if( rc==2 ){ /* exit requested */ break; @@ -6520,7 +6539,7 @@ static int process_input(ShellState *p, FILE *in){ p->outCount = 0; } }else if( nSql && _all_whitespace(zSql) ){ - if( p->echoOn ) printf("%s\n", zSql); + if( ShellHasFlag(p, SHFLG_Echo) ) printf("%s\n", zSql); nSql = 0; } } @@ -6989,7 +7008,7 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ }else if( strcmp(z,"-noheader")==0 ){ data.showHeader = 0; }else if( strcmp(z,"-echo")==0 ){ - data.echoOn = 1; + ShellSetFlag(&data, SHFLG_Echo); }else if( strcmp(z,"-eqp")==0 ){ data.autoEQP = 1; }else if( strcmp(z,"-eqpfull")==0 ){ @@ -7004,7 +7023,7 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ ** prior to sending the SQL into SQLite. Useful for injecting ** crazy bytes in the middle of SQL statements for testing and debugging. */ - data.backslashOn = 1; + ShellSetFlag(&data, SHFLG_Backslash); }else if( strcmp(z,"-bail")==0 ){ bail_on_error = 1; }else if( strcmp(z,"-version")==0 ){ From f8563c00b277ef39608148644660d697b7707f53 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 9 Mar 2017 18:13:52 +0000 Subject: [PATCH 1403/1484] Fix the ".dump" command to correctly extract tail data from corrupt WITHOUT ROWID tables. FossilOrigin-Name: 6c627e50622d8bcd25ec7d5503f3fafd725673a8 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/shell.c | 23 +++++++++++++++++++++++ 3 files changed, 30 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index c8aad6cfb1..bfcca0a0ba 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Begin\smoving\sseparate\sboolean\svariables\sin\sthe\sShellState\sobject\sof\sthe\sCLI\ninto\sthe\sshellFlgs\sbitmask. -D 2017-03-09T13:50:49.349 +C Fix\sthe\s".dump"\scommand\sto\scorrectly\sextract\stail\sdata\sfrom\scorrupt\nWITHOUT\sROWID\stables. +D 2017-03-09T18:13:52.322 F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 @@ -400,7 +400,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 3e518b962d932a997fae373366880fc028c75706 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c d12f3539f80db38b09015561b569e0eb1c4b6c5f -F src/shell.c 397e51c3eeb3a9dc21667a0a384eb14403cc5eea +F src/shell.c f4a7169ddfff73ba1ab2f06a4e97bd6d569cb984 F src/sqlite.h.in 4d0c08f8640c586564a7032b259c5f69bf397850 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae @@ -1564,7 +1564,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 2ea300fb8f7c497f3f092dc91f4305d8431c27d9 -R 193fb708e3eeb9be14d6692d9fad8ed4 +P 50eec5d9aa38fab1a85d788356ffdaf6c35d9ece +R a2e2297f06f9d9483ad6626d70cfa2bc U drh -Z 6ea8a21fbd5a369fc4273386c415b1f4 +Z 704977d7ee0085e38c9f718cc949a370 diff --git a/manifest.uuid b/manifest.uuid index 2f86d48c03..53f69764d4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -50eec5d9aa38fab1a85d788356ffdaf6c35d9ece \ No newline at end of file +6c627e50622d8bcd25ec7d5503f3fafd725673a8 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 1de72f8997..adc57481b8 100644 --- a/src/shell.c +++ b/src/shell.c @@ -2850,6 +2850,23 @@ static char **tableColumnList(ShellState *p, const char *zTab){ return azCol; } +/* +** Toggle the reverse_unordered_selects setting. +*/ +static void toggleSelectOrder(sqlite3 *db){ + sqlite3_stmt *pStmt = 0; + int iSetting = 0; + char zStmt[100]; + sqlite3_prepare_v2(db, "PRAGMA reverse_unordered_selects", -1, &pStmt, 0); + if( sqlite3_step(pStmt)==SQLITE_ROW ){ + iSetting = sqlite3_column_int(pStmt, 0); + } + sqlite3_finalize(pStmt); + sqlite3_snprintf(sizeof(zStmt), zStmt, + "PRAGMA reverse_unordered_selects(%d)", !iSetting); + sqlite3_exec(db, zStmt, 0, 0, 0); +} + /* ** This is a different callback routine used for dumping the database. ** Each row received by this callback consists of a table name, @@ -2946,6 +2963,12 @@ static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){ p->zDestTable = sTable.z; p->mode = p->cMode = MODE_Insert; rc = shell_exec(p->db, sSelect.z, shell_callback, p, 0); + if( (rc&0xff)==SQLITE_CORRUPT ){ + raw_printf(p->out, "/****** CORRUPTION ERROR *******/\n"); + toggleSelectOrder(p->db); + shell_exec(p->db, sSelect.z, shell_callback, p, 0); + toggleSelectOrder(p->db); + } p->zDestTable = savedDestTable; p->mode = savedMode; freeText(&sTable); From fb546afb4dfa625b657ecd48b55cd936be617f4f Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 9 Mar 2017 22:00:33 +0000 Subject: [PATCH 1404/1484] Remove the test/dbselftest.c program. In its place, add the ".selftest" command to the CLI. The new CLI version is .selftest is slightly different in that it uses SHA3 hashing instead of SHA1, so the new is subtly incompatible with the old. FossilOrigin-Name: f4fcd46f08ba59d2a3e772cad98383129f648386 --- Makefile.in | 5 - main.mk | 5 - manifest | 17 +- manifest.uuid | 2 +- src/shell.c | 161 ++++++++++ test/dbselftest.c | 786 ---------------------------------------------- 6 files changed, 170 insertions(+), 806 deletions(-) delete mode 100644 test/dbselftest.c diff --git a/Makefile.in b/Makefile.in index 740b49c08f..d5fa831e6b 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1185,11 +1185,6 @@ KV_OPT += -DSQLITE_DIRECT_OVERFLOW_READ kvtest$(TEXE): $(TOP)/test/kvtest.c sqlite3.c $(LTLINK) $(KV_OPT) -o $@ $(TOP)/test/kvtest.c sqlite3.c $(TLIBS) -DBSELFTEST_OPT += -DSQLITE_ENABLE_RTREE -DSQLITE_ENABLE_FTS4 - -dbselftest$(TEXE): $(TOP)/test/dbselftest.c sqlite3.c - $(LTLINK) $(DBSELFTEST_OPT) -o $@ $(TOP)/test/dbselftest.c sqlite3.c $(TLIBS) - rbu$(EXE): $(TOP)/ext/rbu/rbu.c $(TOP)/ext/rbu/sqlite3rbu.c sqlite3.lo $(LTLINK) -I. -o $@ $(TOP)/ext/rbu/rbu.c sqlite3.lo $(TLIBS) diff --git a/main.mk b/main.mk index 85ed76a143..57f09ff76c 100644 --- a/main.mk +++ b/main.mk @@ -479,8 +479,6 @@ FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1 FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 DBFUZZ_OPT = KV_OPT = -DSQLITE_THREADSAFE=0 -DSQLITE_DIRECT_OVERFLOW_READ -DBSELFTEST_OPT = -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -DBSELFTEST_OPT += -DSQLITE_ENABLE_RTREE -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS5 ST_OPT = -DSQLITE_THREADSAFE=0 # This is the default Makefile target. The objects listed here @@ -902,9 +900,6 @@ speedtest1$(EXE): $(TOP)/test/speedtest1.c sqlite3.c kvtest$(EXE): $(TOP)/test/kvtest.c sqlite3.c $(TCCX) -I. $(KV_OPT) -o kvtest$(EXE) $(TOP)/test/kvtest.c sqlite3.c $(THREADLIB) -dbselftest$(EXE): $(TOP)/test/dbselftest.c sqlite3.c - $(TCCX) -I. $(DBSELFTEST_OPT) -o dbselftest$(EXE) $(TOP)/test/dbselftest.c sqlite3.c $(THREADLIB) - rbu$(EXE): $(TOP)/ext/rbu/rbu.c $(TOP)/ext/rbu/sqlite3rbu.c sqlite3.o $(TCC) -I. -o rbu$(EXE) $(TOP)/ext/rbu/rbu.c sqlite3.o \ $(THREADLIB) diff --git a/manifest b/manifest index bfcca0a0ba..3b64809139 100644 --- a/manifest +++ b/manifest @@ -1,6 +1,6 @@ -C Fix\sthe\s".dump"\scommand\sto\scorrectly\sextract\stail\sdata\sfrom\scorrupt\nWITHOUT\sROWID\stables. -D 2017-03-09T18:13:52.322 -F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918 +C Remove\sthe\stest/dbselftest.c\sprogram.\s\sIn\sits\splace,\sadd\sthe\s".selftest"\ncommand\sto\sthe\sCLI.\s\sThe\snew\sCLI\sversion\sis\s.selftest\sis\sslightly\sdifferent\nin\sthat\sit\suses\sSHA3\shashing\sinstead\sof\sSHA1,\sso\sthe\snew\sis\ssubtly\s\nincompatible\swith\sthe\sold. +D 2017-03-09T22:00:33.842 +F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7 @@ -323,7 +323,7 @@ F ext/userauth/userauth.c 3410be31283abba70255d71fd24734e017a4497f F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60 -F main.mk 08e0b151abb46353c677ac4974b50c6077f85eee +F main.mk 98f9e673437e28b17f86d07d0749021bb140c152 F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 @@ -400,7 +400,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 3e518b962d932a997fae373366880fc028c75706 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c d12f3539f80db38b09015561b569e0eb1c4b6c5f -F src/shell.c f4a7169ddfff73ba1ab2f06a4e97bd6d569cb984 +F src/shell.c 2009654e24924b51a54afb925b49034f1c5460d4 F src/sqlite.h.in 4d0c08f8640c586564a7032b259c5f69bf397850 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae @@ -643,7 +643,6 @@ F test/cursorhint.test 7bc346788390475e77a345da2b92270d04d35856 F test/cursorhint2.test 8457e93d97f665f23f97cdbc8477d16e3480331b F test/date.test 9b73bbeb1b82d9c1f44dec5cf563bf7da58d2373 F test/dbfuzz.c 73047c920d6210e5912c87cdffd9a1c281d4252e -F test/dbselftest.c b2e6cfac59066dbcb7334b66304bb15a5508dd42 F test/dbstatus.test 73149851b3aff14fc6db478e58f9083a66422cf5 F test/dbstatus2.test e93ab03bfae6d62d4d935f20de928c19ca0ed0ab F test/default.test 0cb49b1c315a0d81c81d775e407f66906a2a604d @@ -1564,7 +1563,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 50eec5d9aa38fab1a85d788356ffdaf6c35d9ece -R a2e2297f06f9d9483ad6626d70cfa2bc +P 6c627e50622d8bcd25ec7d5503f3fafd725673a8 +R de6856f188fdc076241cbc67ee174b05 U drh -Z 704977d7ee0085e38c9f718cc949a370 +Z 85b6274077eac0b5500dd53648c9e848 diff --git a/manifest.uuid b/manifest.uuid index 53f69764d4..e2ef7d5abf 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6c627e50622d8bcd25ec7d5503f3fafd725673a8 \ No newline at end of file +f4fcd46f08ba59d2a3e772cad98383129f648386 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index adc57481b8..17048adb3d 100644 --- a/src/shell.c +++ b/src/shell.c @@ -2054,6 +2054,49 @@ static int callback(void *pArg, int nArg, char **azArg, char **azCol){ return shell_callback(pArg, nArg, azArg, azCol, NULL); } +/* +** This is the callback routine from sqlite3_exec() that appends all +** output onto the end of a ShellText object. +*/ +static int captureOutputCallback(void *pArg, int nArg, char **azArg, char **az){ + ShellText *p = (ShellText*)pArg; + int i; + if( p->n ) appendText(p, "|", 0); + for(i=0; idb, + "CREATE TABLE selftest(\n" + " tno INTEGER PRIMARY KEY,\n" /* Test number */ + " op TEXT,\n" /* Operator: memo run */ + " cmd TEXT,\n" /* Command text */ + " ans TEXT\n" /* Desired answer */ + ");" + "INSERT INTO selftest(op,cmd,ans)\n" + " SELECT 'run'," + " 'SELECT hex(sha3_query(''SELECT * FROM \"' ||" + " printf('%w',name) || '\" NOT INDEXED'',224))',\n" + " hex(sha3_query(printf('SELECT * FROM \"%w\" NOT INDEXED',name),224))\n" + " FROM (\n" + " SELECT name FROM sqlite_master\n" + " WHERE type='table'\n" + " AND name<>'selftest'\n" + " AND coalesce(rootpage,0)>0\n" + " )\n" + " ORDER BY name;\n" + "INSERT INTO selftest(op,cmd,ans)\n" + " VALUES('run','PRAGMA integrity_check','ok');\n" + ,0,0,0); +} + /* ** Set the destination table field of the ShellState structure to @@ -5727,6 +5770,124 @@ static int do_meta_command(char *zLine, ShellState *p){ }else #endif + if( c=='s' && n>=4 && strncmp(azArg[0],"selftest",n)==0 ){ + int bIsInit = 0; /* True to initialize the SELFTEST table */ + int bVerbose = 0; /* Verbose output */ + int bSelftestExists; /* True if SELFTEST already exists */ + char **azTest = 0; /* Content of the SELFTEST table */ + int nRow = 0; /* Number of rows in the SELFTEST table */ + int nCol = 4; /* Number of columns in the SELFTEST table */ + int i; /* Loop counter */ + int nTest = 0; /* Number of tests runs */ + int nErr = 0; /* Number of errors seen */ + ShellText str; /* Answer for a query */ + static char *azDefaultTest[] = { + 0, 0, 0, 0, + "0", "memo", "Missing SELFTEST table - default checks only", "", + "1", "run", "PRAGMA integrity_check", "ok" + }; + static const int nDefaultRow = 2; + + open_db(p,0); + for(i=1; idb,"main","selftest",0,0,0,0,0,0) + != SQLITE_OK ){ + bSelftestExists = 0; + }else{ + bSelftestExists = 1; + } + if( bIsInit ){ + if( bSelftestExists ){ + raw_printf(stderr, "The selftest table already exists\n"); + rc = 1; + goto meta_command_exit; + } + createSelftestTable(p); + bSelftestExists = 1; + } + if( bSelftestExists ){ + rc = sqlite3_get_table(p->db, + "SELECT tno,op,cmd,ans FROM selftest ORDER BY tno", + &azTest, &nRow, &nCol, 0); + if( rc ){ + raw_printf(stderr, "Error querying the selftest table\n"); + rc = 1; + sqlite3_free_table(azTest); + goto meta_command_exit; + }else if( nRow==0 ){ + sqlite3_free_table(azTest); + azTest = azDefaultTest; + nRow = nDefaultRow; + } + }else{ + azTest = azDefaultTest; + nRow = nDefaultRow; + } + initText(&str); + appendText(&str, "x", 0); + for(i=1; i<=nRow; i++){ + int tno = atoi(azTest[i*nCol]); + const char *zOp = azTest[i*nCol+1]; + const char *zSql = azTest[i*nCol+2]; + const char *zAns = azTest[i*nCol+3]; + + if( bVerbose>0 ){ + char *zQuote = sqlite3_mprintf("%q", zSql); + printf("%d: %s %s\n", tno, zOp, zSql); + sqlite3_free(zQuote); + } + if( strcmp(zOp,"memo")==0 ){ + utf8_printf(p->out, "%s\n", zSql); + }else + if( strcmp(zOp,"run")==0 ){ + char *zErrMsg = 0; + str.n = 0; + str.z[0] = 0; + rc = sqlite3_exec(p->db, zSql, captureOutputCallback, &str, &zErrMsg); + nTest++; + if( bVerbose ){ + utf8_printf(p->out, "Result: %s\n", str.z); + } + if( rc || zErrMsg ){ + nErr++; + rc = 1; + utf8_printf(p->out, "%d: error-code-%d: %s\n", tno, rc, zErrMsg); + sqlite3_free(zErrMsg); + }else if( strcmp(zAns,str.z)!=0 ){ + nErr++; + rc = 1; + utf8_printf(p->out, "%d: Expected: [%s]\n", tno, zAns); + utf8_printf(p->out, "%d: Got: [%s]\n", tno, str.z); + } + }else + { + utf8_printf(stderr, + "Unknown operation \"%s\" on selftest line %d\n", zOp, tno); + rc = 1; + break; + } + } + freeText(&str); + if( azTest!=azDefaultTest ) sqlite3_free_table(azTest); + utf8_printf(p->out, "%d errors out of %d tests\n", nErr, nTest); + }else + if( c=='s' && strncmp(azArg[0], "separator", n)==0 ){ if( nArg<2 || nArg>3 ){ raw_printf(stderr, "Usage: .separator COL ?ROW?\n"); diff --git a/test/dbselftest.c b/test/dbselftest.c deleted file mode 100644 index 3a238bce16..0000000000 --- a/test/dbselftest.c +++ /dev/null @@ -1,786 +0,0 @@ -/* -** 2017-02-07 -** -** 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 program implements an SQLite database self-verification utility. -** Usage: -** -** dbselftest DATABASE ... -** -** This program reads the "selftest" table in DATABASE, in rowid order, -** and runs each of the tests described there, reporting results at the -** end. -** -** The intent of this program is to have a set of test database files that -** can be run using future versions of SQLite in order to verify that -** legacy database files continue to be readable. In other words, the -** intent is to confirm that there have been no breaking changes in the -** file format. The program can also be used to verify that database files -** are fully compatible between different architectures. -** -** The selftest table looks like this: -** -** CREATE TABLE selftest ( -** id INTEGER PRIMARY KEY, -- Run tests in ascending order -** op TEXT, -- "test", "regexp", "print", etc. -** cmdtxt TEXT, -- Usually the SQL to be run -** expected TEXT -- Expected results -** ); -** -*/ -#include -#include -#include -#include -#include -#include "sqlite3.h" - -static const char zHelp[] = - "Usage: dbselftest [OPTIONS] DBFILE ...\n" - "\n" - " --init Create the selftest table\n" - " -q Suppress most output. Errors only\n" - " -v Show extra output\n" -; - - -/****************************************************************************** -** The following code from ext/misc/sha1.c -** -** Context for the SHA1 hash -*/ -typedef struct SHA1Context SHA1Context; -struct SHA1Context { - unsigned int state[5]; - unsigned int count[2]; - unsigned char buffer[64]; -}; - - -#if __GNUC__ && (defined(__i386__) || defined(__x86_64__)) -/* - * GCC by itself only generates left rotates. Use right rotates if - * possible to be kinder to dinky implementations with iterative rotate - * instructions. - */ -#define SHA_ROT(op, x, k) \ - ({ unsigned int y; asm(op " %1,%0" : "=r" (y) : "I" (k), "0" (x)); y; }) -#define rol(x,k) SHA_ROT("roll", x, k) -#define ror(x,k) SHA_ROT("rorl", x, k) - -#else -/* Generic C equivalent */ -#define SHA_ROT(x,l,r) ((x) << (l) | (x) >> (r)) -#define rol(x,k) SHA_ROT(x,k,32-(k)) -#define ror(x,k) SHA_ROT(x,32-(k),k) -#endif - - -#define blk0le(i) (block[i] = (ror(block[i],8)&0xFF00FF00) \ - |(rol(block[i],8)&0x00FF00FF)) -#define blk0be(i) block[i] -#define blk(i) (block[i&15] = rol(block[(i+13)&15]^block[(i+8)&15] \ - ^block[(i+2)&15]^block[i&15],1)) - -/* - * (R0+R1), R2, R3, R4 are the different operations (rounds) used in SHA1 - * - * Rl0() for little-endian and Rb0() for big-endian. Endianness is - * determined at run-time. - */ -#define Rl0(v,w,x,y,z,i) \ - z+=((w&(x^y))^y)+blk0le(i)+0x5A827999+rol(v,5);w=ror(w,2); -#define Rb0(v,w,x,y,z,i) \ - z+=((w&(x^y))^y)+blk0be(i)+0x5A827999+rol(v,5);w=ror(w,2); -#define R1(v,w,x,y,z,i) \ - z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=ror(w,2); -#define R2(v,w,x,y,z,i) \ - z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=ror(w,2); -#define R3(v,w,x,y,z,i) \ - z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=ror(w,2); -#define R4(v,w,x,y,z,i) \ - z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=ror(w,2); - -/* - * Hash a single 512-bit block. This is the core of the algorithm. - */ -void SHA1Transform(unsigned int state[5], const unsigned char buffer[64]){ - unsigned int qq[5]; /* a, b, c, d, e; */ - static int one = 1; - unsigned int block[16]; - memcpy(block, buffer, 64); - memcpy(qq,state,5*sizeof(unsigned int)); - -#define a qq[0] -#define b qq[1] -#define c qq[2] -#define d qq[3] -#define e qq[4] - - /* Copy p->state[] to working vars */ - /* - a = state[0]; - b = state[1]; - c = state[2]; - d = state[3]; - e = state[4]; - */ - - /* 4 rounds of 20 operations each. Loop unrolled. */ - if( 1 == *(unsigned char*)&one ){ - Rl0(a,b,c,d,e, 0); Rl0(e,a,b,c,d, 1); Rl0(d,e,a,b,c, 2); Rl0(c,d,e,a,b, 3); - Rl0(b,c,d,e,a, 4); Rl0(a,b,c,d,e, 5); Rl0(e,a,b,c,d, 6); Rl0(d,e,a,b,c, 7); - Rl0(c,d,e,a,b, 8); Rl0(b,c,d,e,a, 9); Rl0(a,b,c,d,e,10); Rl0(e,a,b,c,d,11); - Rl0(d,e,a,b,c,12); Rl0(c,d,e,a,b,13); Rl0(b,c,d,e,a,14); Rl0(a,b,c,d,e,15); - }else{ - Rb0(a,b,c,d,e, 0); Rb0(e,a,b,c,d, 1); Rb0(d,e,a,b,c, 2); Rb0(c,d,e,a,b, 3); - Rb0(b,c,d,e,a, 4); Rb0(a,b,c,d,e, 5); Rb0(e,a,b,c,d, 6); Rb0(d,e,a,b,c, 7); - Rb0(c,d,e,a,b, 8); Rb0(b,c,d,e,a, 9); Rb0(a,b,c,d,e,10); Rb0(e,a,b,c,d,11); - Rb0(d,e,a,b,c,12); Rb0(c,d,e,a,b,13); Rb0(b,c,d,e,a,14); Rb0(a,b,c,d,e,15); - } - R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); - R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); - R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); - R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); - R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); - R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); - R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); - R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); - R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); - R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); - R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); - R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); - R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); - R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); - R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); - R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); - - /* Add the working vars back into context.state[] */ - state[0] += a; - state[1] += b; - state[2] += c; - state[3] += d; - state[4] += e; - -#undef a -#undef b -#undef c -#undef d -#undef e -} - - -/* Initialize a SHA1 context */ -static void hash_init(SHA1Context *p){ - /* SHA1 initialization constants */ - p->state[0] = 0x67452301; - p->state[1] = 0xEFCDAB89; - p->state[2] = 0x98BADCFE; - p->state[3] = 0x10325476; - p->state[4] = 0xC3D2E1F0; - p->count[0] = p->count[1] = 0; -} - -/* Add new content to the SHA1 hash */ -static void hash_step( - SHA1Context *p, /* Add content to this context */ - const unsigned char *data, /* Data to be added */ - unsigned int len /* Number of bytes in data */ -){ - unsigned int i, j; - - j = p->count[0]; - if( (p->count[0] += len << 3) < j ){ - p->count[1] += (len>>29)+1; - } - j = (j >> 3) & 63; - if( (j + len) > 63 ){ - (void)memcpy(&p->buffer[j], data, (i = 64-j)); - SHA1Transform(p->state, p->buffer); - for(; i + 63 < len; i += 64){ - SHA1Transform(p->state, &data[i]); - } - j = 0; - }else{ - i = 0; - } - (void)memcpy(&p->buffer[j], &data[i], len - i); -} - -/* Compute a string using sqlite3_vsnprintf() and hash it */ -static void hash_step_vformat( - SHA1Context *p, /* Add content to this context */ - const char *zFormat, - ... -){ - va_list ap; - int n; - char zBuf[50]; - va_start(ap, zFormat); - sqlite3_vsnprintf(sizeof(zBuf),zBuf,zFormat,ap); - va_end(ap); - n = (int)strlen(zBuf); - hash_step(p, (unsigned char*)zBuf, n); -} - - -/* Add padding and compute the message digest. Render the -** message digest as lower-case hexadecimal and put it into -** zOut[]. zOut[] must be at least 41 bytes long. */ -static void hash_finish( - SHA1Context *p, /* The SHA1 context to finish and render */ - char *zOut /* Store hexadecimal hash here */ -){ - unsigned int i; - unsigned char finalcount[8]; - unsigned char digest[20]; - static const char zEncode[] = "0123456789abcdef"; - - for (i = 0; i < 8; i++){ - finalcount[i] = (unsigned char)((p->count[(i >= 4 ? 0 : 1)] - >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */ - } - hash_step(p, (const unsigned char *)"\200", 1); - while ((p->count[0] & 504) != 448){ - hash_step(p, (const unsigned char *)"\0", 1); - } - hash_step(p, finalcount, 8); /* Should cause a SHA1Transform() */ - for (i = 0; i < 20; i++){ - digest[i] = (unsigned char)((p->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); - } - for(i=0; i<20; i++){ - zOut[i*2] = zEncode[(digest[i]>>4)&0xf]; - zOut[i*2+1] = zEncode[digest[i] & 0xf]; - } - zOut[i*2]= 0; -} - -/* -** Implementation of the sha1(X) function. -** -** Return a lower-case hexadecimal rendering of the SHA1 hash of the -** argument X. If X is a BLOB, it is hashed as is. For all other -** types of input, X is converted into a UTF-8 string and the string -** is hash without the trailing 0x00 terminator. The hash of a NULL -** value is NULL. -*/ -static void sha1Func( - sqlite3_context *context, - int argc, - sqlite3_value **argv -){ - SHA1Context cx; - int eType = sqlite3_value_type(argv[0]); - int nByte = sqlite3_value_bytes(argv[0]); - char zOut[44]; - - assert( argc==1 ); - if( eType==SQLITE_NULL ) return; - hash_init(&cx); - if( eType==SQLITE_BLOB ){ - hash_step(&cx, sqlite3_value_blob(argv[0]), nByte); - }else{ - hash_step(&cx, sqlite3_value_text(argv[0]), nByte); - } - hash_finish(&cx, zOut); - sqlite3_result_text(context, zOut, 40, SQLITE_TRANSIENT); -} - -/* -** Run a prepared statement and compute the SHA1 hash on the -** result rows. -*/ -static void sha1RunStatement(SHA1Context *pCtx, sqlite3_stmt *pStmt){ - int nCol = sqlite3_column_count(pStmt); - const char *z = sqlite3_sql(pStmt); - int n = (int)strlen(z); - - hash_step_vformat(pCtx,"S%d:",n); - hash_step(pCtx,(unsigned char*)z,n); - - /* Compute a hash over the result of the query */ - while( SQLITE_ROW==sqlite3_step(pStmt) ){ - int i; - hash_step(pCtx,(const unsigned char*)"R",1); - for(i=0; i=1; j--){ - x[j] = u & 0xff; - u >>= 8; - } - x[0] = 'I'; - hash_step(pCtx, x, 9); - break; - } - case SQLITE_FLOAT: { - sqlite3_uint64 u; - int j; - unsigned char x[9]; - double r = sqlite3_column_double(pStmt,i); - memcpy(&u, &r, 8); - for(j=8; j>=1; j--){ - x[j] = u & 0xff; - u >>= 8; - } - x[0] = 'F'; - hash_step(pCtx,x,9); - break; - } - case SQLITE_TEXT: { - int n2 = sqlite3_column_bytes(pStmt, i); - const unsigned char *z2 = sqlite3_column_text(pStmt, i); - hash_step_vformat(pCtx,"T%d:",n2); - hash_step(pCtx, z2, n2); - break; - } - case SQLITE_BLOB: { - int n2 = sqlite3_column_bytes(pStmt, i); - const unsigned char *z2 = sqlite3_column_blob(pStmt, i); - hash_step_vformat(pCtx,"B%d:",n2); - hash_step(pCtx, z2, n2); - break; - } - } - } - } -} - -/* -** Run one or more statements of SQL. Compute a SHA1 hash of the output. -*/ -static int sha1Exec( - sqlite3 *db, /* Run against this database connection */ - const char *zSql, /* The SQL to be run */ - char *zOut /* Store the SHA1 hash as hexadecimal in this buffer */ -){ - sqlite3_stmt *pStmt = 0; /* A prepared statement */ - int rc; /* Result of an API call */ - SHA1Context cx; /* The SHA1 hash context */ - - hash_init(&cx); - while( zSql[0] ){ - rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zSql); - if( rc ){ - sqlite3_finalize(pStmt); - return rc; - } - sha1RunStatement(&cx, pStmt); - sqlite3_finalize(pStmt); - } - hash_finish(&cx, zOut); - return SQLITE_OK; -} - -/* -** Implementation of the sha1_query(SQL) function. -** -** This function compiles and runs the SQL statement(s) given in the -** argument. The results are hashed using SHA1 and that hash is returned. -** -** The original SQL text is included as part of the hash. -** -** The hash is not just a concatenation of the outputs. Each query -** is delimited and each row and value within the query is delimited, -** with all values being marked with their datatypes. -*/ -static void sha1QueryFunc( - sqlite3_context *context, - int argc, - sqlite3_value **argv -){ - sqlite3 *db = sqlite3_context_db_handle(context); - const char *zSql = (const char*)sqlite3_value_text(argv[0]); - sqlite3_stmt *pStmt = 0; - int rc; - SHA1Context cx; - char zOut[44]; - - assert( argc==1 ); - if( zSql==0 ) return; - hash_init(&cx); - while( zSql[0] ){ - rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zSql); - if( rc ){ - char *zMsg = sqlite3_mprintf("error SQL statement [%s]: %s", - zSql, sqlite3_errmsg(db)); - sqlite3_finalize(pStmt); - sqlite3_result_error(context, zMsg, -1); - sqlite3_free(zMsg); - return; - } - if( !sqlite3_stmt_readonly(pStmt) ){ - char *zMsg = sqlite3_mprintf("non-query: [%s]", sqlite3_sql(pStmt)); - sqlite3_finalize(pStmt); - sqlite3_result_error(context, zMsg, -1); - sqlite3_free(zMsg); - return; - } - sha1RunStatement(&cx, pStmt); - sqlite3_finalize(pStmt); - } - hash_finish(&cx, zOut); - sqlite3_result_text(context, zOut, 40, SQLITE_TRANSIENT); -} -/* End of ext/misc/sha1.c -******************************************************************************/ - -/* How much output to display */ -#define VOLUME_MIN 0 -#define VOLUME_OFF 0 -#define VOLUME_ERROR_ONLY 1 -#define VOLUME_LOW 2 -#define VOLUME_ECHO 3 -#define VOLUME_VERBOSE 4 -#define VOLUME_MAX 4 - -/* A string accumulator -*/ -typedef struct Str { - char *z; /* Accumulated text */ - int n; /* Bytes of z[] used so far */ - int nAlloc; /* Bytes allocated for z[] */ -} Str; - -/* Append text to the Str object -*/ -static void strAppend(Str *p, const char *z){ - int n = (int)strlen(z); - if( p->n+n >= p->nAlloc ){ - p->nAlloc += p->n+n + 100; - p->z = sqlite3_realloc(p->z, p->nAlloc); - if( z==0 ){ - printf("Could not allocate %d bytes\n", p->nAlloc); - exit(1); - } - } - memcpy(p->z+p->n, z, n+1); - p->n += n; -} - -/* This is an sqlite3_exec() callback that will capture all -** output in a Str. -** -** Columns are separated by ",". Rows are separated by "|". -*/ -static int execCallback(void *pStr, int argc, char **argv, char **colv){ - int i; - Str *p = (Str*)pStr; - if( p->n ) strAppend(p, "|"); - for(i=0; i0 ) strAppend(p, ","); - strAppend(p, z); - } - return 0; -} - -/* -** Run an SQL statement constructing using sqlite3_vmprintf(). -** Return the number of errors. -*/ -static int runSql(sqlite3 *db, const char *zFormat, ...){ - char *zSql; - char *zErr = 0; - int rc; - int nErr = 0; - va_list ap; - - va_start(ap, zFormat); - zSql = sqlite3_vmprintf(zFormat, ap); - va_end(ap); - if( zSql==0 ){ - printf("Out of memory\n"); - exit(1); - } - rc = sqlite3_exec(db, zSql, 0, 0, &zErr); - if( rc || zErr ){ - printf("SQL error in [%s]: code=%d: %s\n", zSql, rc, zErr); - nErr++; - } - sqlite3_free(zSql); - return nErr; -} - -/* -** Generate a prepared statement using a formatted string. -*/ -static sqlite3_stmt *prepareSql(sqlite3 *db, const char *zFormat, ...){ - char *zSql; - int rc; - sqlite3_stmt *pStmt = 0; - va_list ap; - - va_start(ap, zFormat); - zSql = sqlite3_vmprintf(zFormat, ap); - va_end(ap); - if( zSql==0 ){ - printf("Out of memory\n"); - exit(1); - } - rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); - if( rc ){ - printf("SQL error in [%s]: code=%d: %s\n", zSql, rc, sqlite3_errmsg(db)); - sqlite3_finalize(pStmt); - pStmt = 0; - } - sqlite3_free(zSql); - return pStmt; -} - -/* -** Construct the standard selftest configuration for the database. -*/ -static int buildSelftestTable(sqlite3 *db){ - int rc; - sqlite3_stmt *pStmt; - int tno = 110; - char *zSql; - char zHash[50]; - - rc = runSql(db, - "CREATE TABLE IF NOT EXISTS selftest(\n" - " tno INTEGER PRIMARY KEY, -- test number\n" - " op TEXT, -- what kind of test\n" - " sql TEXT, -- SQL text for the test\n" - " ans TEXT -- expected answer\n" - ");" - "INSERT INTO selftest" - " VALUES(100,'memo','Hashes generated using --init',NULL);" - ); - if( rc ) return 1; - tno = 110; - zSql = "SELECT type,name,tbl_name,sql FROM sqlite_master ORDER BY name"; - sha1Exec(db, zSql, zHash); - rc = runSql(db, - "INSERT INTO selftest(tno,op,sql,ans)" - " VALUES(%d,'sha1',%Q,%Q)", tno, zSql, zHash); - tno += 10; - pStmt = prepareSql(db, - "SELECT lower(name) FROM sqlite_master" - " WHERE type='table' AND sql NOT GLOB 'CREATE VIRTUAL*'" - " AND name<>'selftest'" - " ORDER BY 1"); - if( pStmt==0 ) return 1; - while( SQLITE_ROW==sqlite3_step(pStmt) ){ - zSql = sqlite3_mprintf("SELECT * FROM \"%w\" NOT INDEXED", - sqlite3_column_text(pStmt, 0)); - if( zSql==0 ){ - printf("Of of memory\n"); - exit(1); - } - sha1Exec(db, zSql, zHash); - rc = runSql(db, - "INSERT INTO selftest(tno,op,sql,ans)" - " VALUES(%d,'sha1',%Q,%Q)", tno, zSql, zHash); - tno += 10; - sqlite3_free(zSql); - if( rc ) break; - } - sqlite3_finalize(pStmt); - if( rc ) return 1; - rc = runSql(db, - "INSERT INTO selftest(tno,op,sql,ans)" - " VALUES(%d,'run','PRAGMA integrity_check','ok');", tno); - if( rc ) return 1; - return rc; -} - -/* -** Return true if the named table exists -*/ -static int tableExists(sqlite3 *db, const char *zTab){ - return sqlite3_table_column_metadata(db, "main", zTab, 0, 0, 0, 0, 0, 0) - == SQLITE_OK; -} - -/* -** Default selftest table content, for use when there is no selftest table -*/ -static char *azDefaultTest[] = { - 0, 0, 0, 0, - "0", "memo", "Missing SELFTEST table - default checks only", "", - "1", "run", "PRAGMA integrity_check", "ok" -}; - -int main(int argc, char **argv){ - int eVolume = VOLUME_LOW; /* How much output to display */ - const char **azDb = 0; /* Name of the database file */ - int nDb = 0; /* Number of database files to check */ - int doInit = 0; /* True if --init is present */ - sqlite3 *db = 0; /* Open database connection */ - int rc; /* Return code from API calls */ - char *zErrMsg = 0; /* An error message return */ - char **azTest; /* Content of the selftest table */ - int nRow = 0, nCol = 0; /* Rows and columns in azTest[] */ - int i; /* Loop counter */ - int nErr = 0; /* Number of errors */ - int iDb; /* Loop counter for databases */ - Str str; /* Result accumulator */ - int nTest = 0; /* Number of tests run */ - - for(i=1; iVOLUME_MIN) eVolume--; - }else - if( strcmp(z, "-v")==0 ){ - if( eVolume=VOLUME_LOW ){ - printf("SQLite %s\n", sqlite3_sourceid()); - } - memset(&str, 0, sizeof(str)); - strAppend(&str, "\n"); - for(iDb=0; iDb=VOLUME_ECHO ){ - char *zQuote = sqlite3_mprintf("%q", zSql); - printf("%d: %s %s\n", tno, zOp, zSql); - sqlite3_free(zQuote); - } - if( strcmp(zOp,"memo")==0 ){ - if( eVolume>=VOLUME_LOW ){ - printf("%s: %s\n", azDb[iDb], zSql); - } - }else - if( strcmp(zOp,"sha1")==0 ){ - char zOut[44]; - rc = sha1Exec(db, zSql, zOut); - nTest++; - if( eVolume>=VOLUME_VERBOSE ){ - printf("Result: %s\n", zOut); - } - if( rc ){ - nErr++; - if( eVolume>=VOLUME_ERROR_ONLY ){ - printf("%d: error-code-%d: %s\n", tno, rc, sqlite3_errmsg(db)); - } - }else if( strcmp(zAns,zOut)!=0 ){ - nErr++; - if( eVolume>=VOLUME_ERROR_ONLY ){ - printf("%d: Expected: [%s]\n", tno, zAns); - printf("%d: Got: [%s]\n", tno, zOut); - } - } - }else - if( strcmp(zOp,"run")==0 ){ - str.n = 0; - str.z[0] = 0; - zErrMsg = 0; - rc = sqlite3_exec(db, zSql, execCallback, &str, &zErrMsg); - nTest++; - if( eVolume>=VOLUME_VERBOSE ){ - printf("Result: %s\n", str.z); - } - if( rc || zErrMsg ){ - nErr++; - if( eVolume>=VOLUME_ERROR_ONLY ){ - printf("%d: error-code-%d: %s\n", tno, rc, zErrMsg); - } - sqlite3_free(zErrMsg); - }else if( strcmp(zAns,str.z)!=0 ){ - nErr++; - if( eVolume>=VOLUME_ERROR_ONLY ){ - printf("%d: Expected: [%s]\n", tno, zAns); - printf("%d: Got: [%s]\n", tno, str.z); - } - } - }else - { - printf("Unknown operation \"%s\" on selftest line %d\n", zOp, tno); - return 1; - } - } - if( azTest!=azDefaultTest ) sqlite3_free_table(azTest); - } - if( eVolume>=VOLUME_LOW || (nErr>0 && eVolume>=VOLUME_ERROR_ONLY) ){ - printf("%d errors out of %d tests on %d databases\n", nErr, nTest, nDb); - } - return nErr; -} From f157d10f9f557e4117d3267eba89d817141feead Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 10 Mar 2017 01:05:38 +0000 Subject: [PATCH 1405/1484] Improvements to ".selftest --init". Tests are number in increments of 10 starting with 100. The tests are generated inside a SAVEPOINT. Errors are reported during test generation. Tests can be appended to existing tests. Add a test case to verify the schema. FossilOrigin-Name: b044b152aac2ec606750940ea816ad4a4aef8eb6 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/shell.c | 33 ++++++++++++++++++++++++--------- 3 files changed, 31 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index 3b64809139..5ebdb5663f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sthe\stest/dbselftest.c\sprogram.\s\sIn\sits\splace,\sadd\sthe\s".selftest"\ncommand\sto\sthe\sCLI.\s\sThe\snew\sCLI\sversion\sis\s.selftest\sis\sslightly\sdifferent\nin\sthat\sit\suses\sSHA3\shashing\sinstead\sof\sSHA1,\sso\sthe\snew\sis\ssubtly\s\nincompatible\swith\sthe\sold. -D 2017-03-09T22:00:33.842 +C Improvements\sto\s".selftest\s--init".\s\sTests\sare\snumber\sin\sincrements\sof\s10\nstarting\swith\s100.\s\sThe\stests\sare\sgenerated\sinside\sa\sSAVEPOINT.\s\sErrors\sare\nreported\sduring\stest\sgeneration.\s\sTests\scan\sbe\sappended\sto\sexisting\stests.\nAdd\sa\stest\scase\sto\sverify\sthe\sschema. +D 2017-03-10T01:05:38.013 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 @@ -400,7 +400,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 3e518b962d932a997fae373366880fc028c75706 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c d12f3539f80db38b09015561b569e0eb1c4b6c5f -F src/shell.c 2009654e24924b51a54afb925b49034f1c5460d4 +F src/shell.c 0435e7ea18865e8bd435c9fbe018e1a8431964a7 F src/sqlite.h.in 4d0c08f8640c586564a7032b259c5f69bf397850 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae @@ -1563,7 +1563,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 6c627e50622d8bcd25ec7d5503f3fafd725673a8 -R de6856f188fdc076241cbc67ee174b05 +P f4fcd46f08ba59d2a3e772cad98383129f648386 +R 2a153e04b79acc8e7981c04d4b205835 U drh -Z 85b6274077eac0b5500dd53648c9e848 +Z c20519a5ebf6e7586b129dc9c77c4f4b diff --git a/manifest.uuid b/manifest.uuid index e2ef7d5abf..d8526f73db 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f4fcd46f08ba59d2a3e772cad98383129f648386 \ No newline at end of file +b044b152aac2ec606750940ea816ad4a4aef8eb6 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 17048adb3d..4912639dbc 100644 --- a/src/shell.c +++ b/src/shell.c @@ -2073,14 +2073,26 @@ static int captureOutputCallback(void *pArg, int nArg, char **azArg, char **az){ ** Generate an appropriate SELFTEST table in the main database. */ static void createSelftestTable(ShellState *p){ + char *zErrMsg = 0; sqlite3_exec(p->db, - "CREATE TABLE selftest(\n" + "SAVEPOINT selftest_init;\n" + "CREATE TABLE IF NOT EXISTS selftest(\n" " tno INTEGER PRIMARY KEY,\n" /* Test number */ " op TEXT,\n" /* Operator: memo run */ " cmd TEXT,\n" /* Command text */ " ans TEXT\n" /* Desired answer */ ");" - "INSERT INTO selftest(op,cmd,ans)\n" + "CREATE TEMP TABLE [_shell$self](op,cmd,ans);\n" + "INSERT INTO [_shell$self](rowid,op,cmd)\n" + " VALUES(coalesce((SELECT (max(tno)+100)/10 FROM selftest),10),\n" + " 'memo','Tests generated by --init');\n" + "INSERT INTO [_shell$self]\n" + " SELECT 'run',\n" + " 'SELECT hex(sha3_query(''SELECT type,name,tbl_name,sql " + "FROM sqlite_master ORDER BY 2'',224))',\n" + " hex(sha3_query('SELECT type,name,tbl_name,sql " + "FROM sqlite_master ORDER BY 2',224));\n" + "INSERT INTO [_shell$self]\n" " SELECT 'run'," " 'SELECT hex(sha3_query(''SELECT * FROM \"' ||" " printf('%w',name) || '\" NOT INDEXED'',224))',\n" @@ -2092,9 +2104,17 @@ static void createSelftestTable(ShellState *p){ " AND coalesce(rootpage,0)>0\n" " )\n" " ORDER BY name;\n" - "INSERT INTO selftest(op,cmd,ans)\n" + "INSERT INTO [_shell$self]\n" " VALUES('run','PRAGMA integrity_check','ok');\n" - ,0,0,0); + "INSERT INTO selftest(tno,op,cmd,ans)" + " SELECT rowid*10,op,cmd,ans FROM [_shell$self];\n" + "DROP TABLE [_shell$self];" + ,0,0,&zErrMsg); + if( zErrMsg ){ + utf8_printf(stderr, "SELFTEST initialization failure: %s\n", zErrMsg); + sqlite3_free(zErrMsg); + } + sqlite3_exec(p->db, "RELEASE selftest_init",0,0,0); } @@ -5813,11 +5833,6 @@ static int do_meta_command(char *zLine, ShellState *p){ bSelftestExists = 1; } if( bIsInit ){ - if( bSelftestExists ){ - raw_printf(stderr, "The selftest table already exists\n"); - rc = 1; - goto meta_command_exit; - } createSelftestTable(p); bSelftestExists = 1; } From a2df53bd619520ce4ea8be314bed25d998a13947 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 10 Mar 2017 14:36:10 +0000 Subject: [PATCH 1406/1484] Enhance the ".stats" dot-command in the CLI to use sqlite3_status64() instead of sqlite3_status(). FossilOrigin-Name: 118f5c0564fef70cbd06fc0d9dbb2baec162cc39 --- manifest | 12 +++---- manifest.uuid | 2 +- src/shell.c | 91 +++++++++++++++++++++++++-------------------------- 3 files changed, 52 insertions(+), 53 deletions(-) diff --git a/manifest b/manifest index 5ebdb5663f..5c43042028 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improvements\sto\s".selftest\s--init".\s\sTests\sare\snumber\sin\sincrements\sof\s10\nstarting\swith\s100.\s\sThe\stests\sare\sgenerated\sinside\sa\sSAVEPOINT.\s\sErrors\sare\nreported\sduring\stest\sgeneration.\s\sTests\scan\sbe\sappended\sto\sexisting\stests.\nAdd\sa\stest\scase\sto\sverify\sthe\sschema. -D 2017-03-10T01:05:38.013 +C Enhance\sthe\s".stats"\sdot-command\sin\sthe\sCLI\sto\suse\ssqlite3_status64()\sinstead\nof\ssqlite3_status(). +D 2017-03-10T14:36:10.584 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 @@ -400,7 +400,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 3e518b962d932a997fae373366880fc028c75706 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c d12f3539f80db38b09015561b569e0eb1c4b6c5f -F src/shell.c 0435e7ea18865e8bd435c9fbe018e1a8431964a7 +F src/shell.c 4d9be7f0622365029a1f2e0f9628b8e363700ff5 F src/sqlite.h.in 4d0c08f8640c586564a7032b259c5f69bf397850 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae @@ -1563,7 +1563,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P f4fcd46f08ba59d2a3e772cad98383129f648386 -R 2a153e04b79acc8e7981c04d4b205835 +P b044b152aac2ec606750940ea816ad4a4aef8eb6 +R da300103282ee8980f2e41cc2466def0 U drh -Z c20519a5ebf6e7586b129dc9c77c4f4b +Z 6dbad136ee05d7b8bc7f34310ddbaf47 diff --git a/manifest.uuid b/manifest.uuid index d8526f73db..f610b09f28 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b044b152aac2ec606750940ea816ad4a4aef8eb6 \ No newline at end of file +118f5c0564fef70cbd06fc0d9dbb2baec162cc39 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 4912639dbc..378729d09b 100644 --- a/src/shell.c +++ b/src/shell.c @@ -2259,6 +2259,31 @@ static void displayLinuxIoStats(FILE *out){ } #endif +/* +** Display a single line of status using 64-bit values. +*/ +static void displayStatLine( + ShellState *p, /* The shell context */ + char *zLabel, /* Label for this one line */ + char *zFormat, /* Format for the result */ + int iStatusCtrl, /* Which status to display */ + int bReset /* True to reset the stats */ +){ + sqlite3_int64 iCur = -1; + sqlite3_int64 iHiwtr = -1; + int i, nPercent; + char zLine[200]; + sqlite3_status64(iStatusCtrl, &iCur, &iHiwtr, bReset); + for(i=0, nPercent=0; zFormat[i]; i++){ + if( zFormat[i]=='%' ) nPercent++; + } + if( nPercent>1 ){ + sqlite3_snprintf(sizeof(zLine), zLine, zFormat, iCur, iHiwtr); + }else{ + sqlite3_snprintf(sizeof(zLine), zLine, zFormat, iHiwtr); + } + raw_printf(p->out, "%-36s %s\n", zLabel, zLine); +} /* ** Display memory stats. @@ -2272,57 +2297,31 @@ static int display_stats( int iHiwtr; if( pArg && pArg->out ){ - - iHiwtr = iCur = -1; - sqlite3_status(SQLITE_STATUS_MEMORY_USED, &iCur, &iHiwtr, bReset); - raw_printf(pArg->out, - "Memory Used: %d (max %d) bytes\n", - iCur, iHiwtr); - iHiwtr = iCur = -1; - sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &iCur, &iHiwtr, bReset); - raw_printf(pArg->out, "Number of Outstanding Allocations: %d (max %d)\n", - iCur, iHiwtr); + displayStatLine(pArg, "Memory Used:", + "%lld (max %lld) bytes", SQLITE_STATUS_MEMORY_USED, bReset); + displayStatLine(pArg, "Number of Outstanding Allocations:", + "%lld (max %lld)", SQLITE_STATUS_MALLOC_COUNT, bReset); if( pArg->shellFlgs & SHFLG_Pagecache ){ - iHiwtr = iCur = -1; - sqlite3_status(SQLITE_STATUS_PAGECACHE_USED, &iCur, &iHiwtr, bReset); - raw_printf(pArg->out, - "Number of Pcache Pages Used: %d (max %d) pages\n", - iCur, iHiwtr); + displayStatLine(pArg, "Number of Pcache Pages Used:", + "%lld (max %lld) pages", SQLITE_STATUS_PAGECACHE_USED, bReset); } - iHiwtr = iCur = -1; - sqlite3_status(SQLITE_STATUS_PAGECACHE_OVERFLOW, &iCur, &iHiwtr, bReset); - raw_printf(pArg->out, - "Number of Pcache Overflow Bytes: %d (max %d) bytes\n", - iCur, iHiwtr); + displayStatLine(pArg, "Number of Pcache Overflow Bytes:", + "%lld (max %lld) bytes", SQLITE_STATUS_PAGECACHE_OVERFLOW, bReset); if( pArg->shellFlgs & SHFLG_Scratch ){ - iHiwtr = iCur = -1; - sqlite3_status(SQLITE_STATUS_SCRATCH_USED, &iCur, &iHiwtr, bReset); - raw_printf(pArg->out, - "Number of Scratch Allocations Used: %d (max %d)\n", - iCur, iHiwtr); + displayStatLine(pArg, "Number of Scratch Allocations Used:", + "%lld (max %lld)", SQLITE_STATUS_SCRATCH_USED, bReset); } - iHiwtr = iCur = -1; - sqlite3_status(SQLITE_STATUS_SCRATCH_OVERFLOW, &iCur, &iHiwtr, bReset); - raw_printf(pArg->out, - "Number of Scratch Overflow Bytes: %d (max %d) bytes\n", - iCur, iHiwtr); - iHiwtr = iCur = -1; - sqlite3_status(SQLITE_STATUS_MALLOC_SIZE, &iCur, &iHiwtr, bReset); - raw_printf(pArg->out, "Largest Allocation: %d bytes\n", - iHiwtr); - iHiwtr = iCur = -1; - sqlite3_status(SQLITE_STATUS_PAGECACHE_SIZE, &iCur, &iHiwtr, bReset); - raw_printf(pArg->out, "Largest Pcache Allocation: %d bytes\n", - iHiwtr); - iHiwtr = iCur = -1; - sqlite3_status(SQLITE_STATUS_SCRATCH_SIZE, &iCur, &iHiwtr, bReset); - raw_printf(pArg->out, "Largest Scratch Allocation: %d bytes\n", - iHiwtr); + displayStatLine(pArg, "Number of Scratch Overflow Bytes:", + "%lld (max %lld) bytes", SQLITE_STATUS_SCRATCH_OVERFLOW, bReset); + displayStatLine(pArg, "Largest Allocation:", + "%lld bytes", SQLITE_STATUS_MALLOC_SIZE, bReset); + displayStatLine(pArg, "Largest Pcache Allocation:", + "%lld bytes", SQLITE_STATUS_PAGECACHE_SIZE, bReset); + displayStatLine(pArg, "Largest Scratch Allocation:", + "%lld bytes", SQLITE_STATUS_SCRATCH_SIZE, bReset); #ifdef YYTRACKMAXSTACKDEPTH - iHiwtr = iCur = -1; - sqlite3_status(SQLITE_STATUS_PARSER_STACK, &iCur, &iHiwtr, bReset); - raw_printf(pArg->out, "Deepest Parser Stack: %d (max %d)\n", - iCur, iHiwtr); + displayStatLine(pArg, "Deepest Parser Stack:", + "%lld (max %lld)", SQLITE_STATUS_PARSER_STACK, bReset); #endif } From e43d6aee45208884330cd23a64d2e38771b8f5e4 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 10 Mar 2017 15:55:54 +0000 Subject: [PATCH 1407/1484] Add the SQLITE_MAX_MEMORY compile-time option that provides a hard upper bound on the amount of memory that SQLite will use, per process. FossilOrigin-Name: 77dfe2abdae88dea81217f352d87e5ba2c822715 --- manifest | 15 +++++++++------ manifest.uuid | 2 +- src/malloc.c | 12 +++++++++--- 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 5c43042028..05fc15b13a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\sthe\s".stats"\sdot-command\sin\sthe\sCLI\sto\suse\ssqlite3_status64()\sinstead\nof\ssqlite3_status(). -D 2017-03-10T14:36:10.584 +C Add\sthe\sSQLITE_MAX_MEMORY\scompile-time\soption\sthat\sprovides\sa\shard\supper\sbound\non\sthe\samount\sof\smemory\sthat\sSQLite\swill\suse,\sper\sprocess. +D 2017-03-10T15:55:54.959 F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 @@ -365,7 +365,7 @@ F src/insert.c 3ed64afc49c0a2221e397b9f65d231ffbef506fe F src/legacy.c e88ed13c2d531decde75d42c2e35623fb9ce3cb0 F src/loadext.c a68d8d1d14cf7488bb29dc5311cb1ce9a4404258 F src/main.c 158326243c5ddc8b98a1e983fa488650cf76d760 -F src/malloc.c d0a1474236486165bcb349af82e2a6560178bf7b +F src/malloc.c 96f86a14b04fce2cb9559ccb3a2ae4534131094e F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c fd7cd6fe21d46fe0a4186367dd8dc26d87b787eb F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3 @@ -1563,7 +1563,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b044b152aac2ec606750940ea816ad4a4aef8eb6 -R da300103282ee8980f2e41cc2466def0 +P 118f5c0564fef70cbd06fc0d9dbb2baec162cc39 +R 32dd2e22d477f93aeae962c3294c4485 +T *branch * max-memory-option +T *sym-max-memory-option * +T -sym-trunk * U drh -Z 6dbad136ee05d7b8bc7f34310ddbaf47 +Z 9eb3e2d252d807f2c1277379e9be3f8a diff --git a/manifest.uuid b/manifest.uuid index f610b09f28..27ef1bc7b1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -118f5c0564fef70cbd06fc0d9dbb2baec162cc39 \ No newline at end of file +77dfe2abdae88dea81217f352d87e5ba2c822715 \ No newline at end of file diff --git a/src/malloc.c b/src/malloc.c index 0fdc8d73ff..b942f47b28 100644 --- a/src/malloc.c +++ b/src/malloc.c @@ -217,7 +217,7 @@ static void sqlite3MallocAlarm(int nByte){ ** Do a memory allocation with statistics and alarms. Assume the ** lock is already held. */ -static void mallocWithAlarm(int n, void **pp){ +static void *mallocWithAlarm(int n){ void *p; int nFull; assert( sqlite3_mutex_held(mem0.mutex) ); @@ -230,6 +230,12 @@ static void mallocWithAlarm(int n, void **pp){ ** following xRoundup() call. */ nFull = sqlite3GlobalConfig.m.xRoundup(n); +#ifdef SQLITE_MAX_MEMORY + if( sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED)+nFull>SQLITE_MAX_MEMORY ){ + return 0; + } +#endif + sqlite3StatusHighwater(SQLITE_STATUS_MALLOC_SIZE, n); if( mem0.alarmThreshold>0 ){ sqlite3_int64 nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED); @@ -252,7 +258,7 @@ static void mallocWithAlarm(int n, void **pp){ sqlite3StatusUp(SQLITE_STATUS_MEMORY_USED, nFull); sqlite3StatusUp(SQLITE_STATUS_MALLOC_COUNT, 1); } - *pp = p; + return p; } /* @@ -270,7 +276,7 @@ void *sqlite3Malloc(u64 n){ p = 0; }else if( sqlite3GlobalConfig.bMemstat ){ sqlite3_mutex_enter(mem0.mutex); - mallocWithAlarm((int)n, &p); + p = mallocWithAlarm((int)n); sqlite3_mutex_leave(mem0.mutex); }else{ p = sqlite3GlobalConfig.m.xMalloc((int)n); From a6bf20b5872cf8c8490c7efd1f908600a50ec34d Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 10 Mar 2017 17:03:11 +0000 Subject: [PATCH 1408/1484] Fix an error in the SQLITE_MAX_MEMORY implementation resulting from a bad merge. Update the OSSFuzz interface so that it times out after running the byte-code engine for 10 seconds. FossilOrigin-Name: f8560c60d10c0365b33342ab05b5a953987b0471 --- Makefile.in | 1 + Makefile.msc | 2 +- main.mk | 1 + manifest | 21 ++++++++++----------- manifest.uuid | 2 +- src/malloc.c | 3 ++- test/ossfuzz.c | 41 ++++++++++++++++++++++++++++++----------- 7 files changed, 46 insertions(+), 25 deletions(-) diff --git a/Makefile.in b/Makefile.in index d5fa831e6b..ba59b3723f 100644 --- a/Makefile.in +++ b/Makefile.in @@ -566,6 +566,7 @@ SHELL_OPT += -DSQLITE_ENABLE_EXPLAIN_COMMENTS SHELL_OPT += -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1 FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_OSS_FUZZ +FUZZCHECK_OPT += -DSQLITE_MAX_MEMORY=50000000 FUZZCHECK_SRC = $(TOP)/test/fuzzcheck.c $(TOP)/test/ossfuzz.c DBFUZZ_OPT = diff --git a/Makefile.msc b/Makefile.msc index 317f68fa9b..01307a3e92 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -1510,7 +1510,7 @@ SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_SHELL_JSON1 -DSQLITE_ENABLE_ # MPTESTER_COMPILE_OPTS = -DSQLITE_SHELL_JSON1 -DSQLITE_ENABLE_FTS5 FUZZERSHELL_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1 -FUZZCHECK_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_OSS_FUZZ +FUZZCHECK_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_OSS_FUZZ -DSQLITE_MAX_MEMORY=50000000 FUZZCHECK_SRC = $(TOP)\test\fuzzcheck.c $(TOP)\test\ossfuzz.c OSSSHELL_SRC = $(TOP)\test\ossshell.c $(TOP)\test\ossfuzz.c DBFUZZ_COMPILE_OPTS = -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION diff --git a/main.mk b/main.mk index 57f09ff76c..8815f0f701 100644 --- a/main.mk +++ b/main.mk @@ -477,6 +477,7 @@ SHELL_OPT += -DSQLITE_ENABLE_EXPLAIN_COMMENTS SHELL_OPT += -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1 FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 +FUZZCHECK_OPT += -DSQLITE_MAX_MEMORY=50000000 DBFUZZ_OPT = KV_OPT = -DSQLITE_THREADSAFE=0 -DSQLITE_DIRECT_OVERFLOW_READ ST_OPT = -DSQLITE_THREADSAFE=0 diff --git a/manifest b/manifest index 79971ae0b5..4b583d7f1f 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -C Add\sthe\s-DSQLITE_MAX_MEMORY=N\scompile-time\soption.\s\sThe\sdefault\sis\sno\slimit. -D 2017-03-10T16:22:40.639 -F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc +C Fix\san\serror\sin\sthe\sSQLITE_MAX_MEMORY\simplementation\sresulting\sfrom\sa\sbad\nmerge.\s\sUpdate\sthe\sOSSFuzz\sinterface\sso\sthat\sit\stimes\sout\safter\srunning\nthe\sbyte-code\sengine\sfor\s10\sseconds. +D 2017-03-10T17:03:11.362 +F Makefile.in 2dae2a56457c2885425a480e1053de8096aff924 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 -F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2 +F Makefile.msc 9020fa41eb91f657ae0cc44145d0a2f3af520860 F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7 F VERSION 3605fa447e4623f5ff4a6adc97b1fde9a257b8f2 F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 @@ -323,7 +323,7 @@ F ext/userauth/userauth.c 3410be31283abba70255d71fd24734e017a4497f F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60 -F main.mk 98f9e673437e28b17f86d07d0749021bb140c152 +F main.mk 0ec10b604f4668f7e85a358954babe75c94dc0d5 F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 @@ -365,7 +365,7 @@ F src/insert.c 3ed64afc49c0a2221e397b9f65d231ffbef506fe F src/legacy.c e88ed13c2d531decde75d42c2e35623fb9ce3cb0 F src/loadext.c a68d8d1d14cf7488bb29dc5311cb1ce9a4404258 F src/main.c 158326243c5ddc8b98a1e983fa488650cf76d760 -F src/malloc.c e2b75576ba5587555fa7146cedca437c3d947b9e +F src/malloc.c 89c98e3619d362dcffa5c1c639b364b65b474751 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c fd7cd6fe21d46fe0a4186367dd8dc26d87b787eb F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3 @@ -1007,7 +1007,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 e469138f4be3e92df6173b79b3b216ab6e17b407 +F test/ossfuzz.c f04b9f236e51d4db701bdebe8ac01318c83102a8 F test/ossshell.c d9f1a6f43e7bab45d6be857a5800f5d4a1861db3 F test/ovfl.test 199c482696defceacee8c8e0e0ef36da62726b2f F test/pager1.test 841868017e9dd3cb459b8d78862091a7d9cff21d @@ -1563,8 +1563,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 118f5c0564fef70cbd06fc0d9dbb2baec162cc39 77dfe2abdae88dea81217f352d87e5ba2c822715 -R 3b74d97e8af57ebd024f8ef03af4d96f -T +closed 77dfe2abdae88dea81217f352d87e5ba2c822715 +P eabd4ef498a0f0d97d65e321c4d06ab90523ed61 +R 69fed97a3de499803e89b1ea5d13a87c U drh -Z 08daf633daf073490979515612458ee1 +Z 0ae96bef0d12b3fb7ff36d9387e9c8a8 diff --git a/manifest.uuid b/manifest.uuid index dc82ffbe7a..221755c547 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -eabd4ef498a0f0d97d65e321c4d06ab90523ed61 \ No newline at end of file +f8560c60d10c0365b33342ab05b5a953987b0471 \ No newline at end of file diff --git a/src/malloc.c b/src/malloc.c index 2b903cc61e..6d49107790 100644 --- a/src/malloc.c +++ b/src/malloc.c @@ -232,7 +232,8 @@ static void mallocWithAlarm(int n, void **pp){ #ifdef SQLITE_MAX_MEMORY if( sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED)+nFull>SQLITE_MAX_MEMORY ){ - return 0; + *pp = 0; + return; } #endif diff --git a/test/ossfuzz.c b/test/ossfuzz.c index 3a3e852c34..91b3d1141e 100644 --- a/test/ossfuzz.c +++ b/test/ossfuzz.c @@ -6,12 +6,33 @@ #include #include "sqlite3.h" +/* Return the current real-world time in milliseconds since the +** Julian epoch (-4714-11-24). +*/ +static sqlite3_int64 timeOfDay(void){ + static sqlite3_vfs *clockVfs = 0; + sqlite3_int64 t; + if( clockVfs==0 ) clockVfs = sqlite3_vfs_find(0); + if( clockVfs->iVersion>=2 && clockVfs->xCurrentTimeInt64!=0 ){ + clockVfs->xCurrentTimeInt64(clockVfs, &t); + }else{ + double r; + clockVfs->xCurrentTime(clockVfs, &r); + t = (sqlite3_int64)(r*86400000.0); + } + return t; +} + #ifndef SQLITE_OMIT_PROGRESS_CALLBACK /* -** Progress handler callback +** Progress handler callback. +** +** The argument is the cutoff-time after which all processing should +** stop. So return non-zero if the cut-off time is exceeded. */ static int progress_handler(void *pReturn) { - return *(int*)pReturn; + sqlite3_int64 iCutoffTime = *(sqlite3_int64*)pReturn; + return timeOfDay()>=iCutoffTime; } #endif @@ -31,13 +52,13 @@ static int exec_handler(void *pCnt, int argc, char **argv, char **namev){ ** fuzzed input. */ int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { - int progressArg = 0; /* 1 causes progress handler abort */ int execCnt = 0; /* Abort row callback when count reaches zero */ char *zErrMsg = 0; /* Error message returned by sqlite_exec() */ sqlite3 *db; /* The database connection */ uint8_t uSelector; /* First byte of input data[] */ int rc; /* Return code from various interfaces */ char *zSql; /* Zero-terminated copy of data[] */ + sqlite3_int64 iCutoff; /* Cutoff timer */ if( size<3 ) return 0; /* Early out if unsufficient data */ @@ -56,16 +77,14 @@ int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { if( rc ) return 0; #ifndef SQLITE_OMIT_PROGRESS_CALLBACK - /* Bit 0 of the selector enables progress callbacks. Bit 1 is the - ** return code from progress callbacks */ - if( uSelector & 1 ){ - sqlite3_progress_handler(db, 4, progress_handler, (void*)&progressArg); - } + /* Invoke the progress handler every 500 thousand instructions (approximately + ** 20 to 40 times per second) to check to see if we are taking too long. + */ + iCutoff = timeOfDay() + 10000; /* Now + 10 seconds */ + sqlite3_progress_handler(db, 500000, progress_handler, (void*)&iCutoff); #endif - uSelector >>= 1; - progressArg = uSelector & 1; uSelector >>= 1; - /* Bit 2 of the selector enables foreign key constraints */ + /* Bit 1 of the selector enables foreign key constraints */ sqlite3_db_config(db, SQLITE_DBCONFIG_ENABLE_FKEY, uSelector&1, &rc); uSelector >>= 1; From 1ba30db8bddda42163962c75af059007e1efb9ed Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 10 Mar 2017 18:36:34 +0000 Subject: [PATCH 1409/1484] Remove the rbu_round_trip.tcl script. It is now part of project "test-dbs". FossilOrigin-Name: b5bf2957677e8f2acd7426b302229a966de08fd9 --- ext/rbu/rbu_round_trip.tcl | 205 ------------------------------------- manifest | 13 ++- manifest.uuid | 2 +- 3 files changed, 7 insertions(+), 213 deletions(-) delete mode 100644 ext/rbu/rbu_round_trip.tcl diff --git a/ext/rbu/rbu_round_trip.tcl b/ext/rbu/rbu_round_trip.tcl deleted file mode 100644 index a4f5d579a1..0000000000 --- a/ext/rbu/rbu_round_trip.tcl +++ /dev/null @@ -1,205 +0,0 @@ -########################################################################## -# 2016 Mar 8 -# -# 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. -# -proc process_cmdline {} { - cmdline::process ::A $::argv { - {make "try to build missing tools"} - {verbose "make more noise"} - database - database2 - } { - This script uses/tests the following tools: - - dbselftest - rbu - sqldiff - sqlite3 - - The user passes the names of two database files - a.db and b.db below - as - arguments. This program: - - 1. Runs [dbselftest --init] against both databases. - 2. Runs [sqldiff --rbu --vtab a.db b.db | sqlite3 .db] to create an - RBU database. - 3. Runs [rbu b.db .db] to patch b.db to a.db. - 4. Runs [sqldiff --table selftest a.db b.db] to check that the selftest - tables are now identical. - 5. Runs [dbselftest] against both databases. - } -} - -########################################################################### -########################################################################### -# Command line options processor. This is generic code that can be copied -# between scripts. -# -namespace eval cmdline { - proc cmdline_error {O E {msg ""}} { - if {$msg != ""} { - puts stderr "Error: $msg" - puts stderr "" - } - - set L [list] - foreach o $O { - if {[llength $o]==1} { - lappend L [string toupper $o] - } - } - - puts stderr "Usage: $::argv0 ?SWITCHES? $L" - puts stderr "" - puts stderr "Switches are:" - foreach o $O { - if {[llength $o]==3} { - foreach {a b c} $o {} - puts stderr [format " -%-15s %s (default \"%s\")" "$a VAL" $c $b] - } elseif {[llength $o]==2} { - foreach {a b} $o {} - puts stderr [format " -%-15s %s" $a $b] - } - } - puts stderr "" - puts stderr $E - exit -1 - } - - proc process {avar lArgs O E} { - upvar $avar A - set zTrailing "" ;# True if ... is present in $O - set lPosargs [list] - - # Populate A() with default values. Also, for each switch in the command - # line spec, set an entry in the idx() array as follows: - # - # {tblname t1 "table name to use"} - # -> [set idx(-tblname) {tblname t1 "table name to use"} - # - # For each position parameter, append its name to $lPosargs. If the ... - # specifier is present, set $zTrailing to the name of the prefix. - # - foreach o $O { - set nm [lindex $o 0] - set nArg [llength $o] - switch -- $nArg { - 1 { - if {[string range $nm end-2 end]=="..."} { - set zTrailing [string range $nm 0 end-3] - } else { - lappend lPosargs $nm - } - } - 2 { - set A($nm) 0 - set idx(-$nm) $o - } - 3 { - set A($nm) [lindex $o 1] - set idx(-$nm) $o - } - default { - error "Error in command line specification" - } - } - } - - # Set explicitly specified option values - # - set nArg [llength $lArgs] - for {set i 0} {$i < $nArg} {incr i} { - set opt [lindex $lArgs $i] - if {[string range $opt 0 0]!="-" || $opt=="--"} break - set c [array names idx "${opt}*"] - if {[llength $c]==0} { cmdline_error $O $E "Unrecognized option: $opt"} - if {[llength $c]>1} { cmdline_error $O $E "Ambiguous option: $opt"} - - if {[llength $idx($c)]==3} { - if {$i==[llength $lArgs]-1} { - cmdline_error $O $E "Option requires argument: $c" - } - incr i - set A([lindex $idx($c) 0]) [lindex $lArgs $i] - } else { - set A([lindex $idx($c) 0]) 1 - } - } - - # Deal with position arguments. - # - set nPosarg [llength $lPosargs] - set nRem [expr $nArg - $i] - if {$nRem < $nPosarg || ($zTrailing=="" && $nRem > $nPosarg)} { - cmdline_error $O $E - } - for {set j 0} {$j < $nPosarg} {incr j} { - set A([lindex $lPosargs $j]) [lindex $lArgs [expr $j+$i]] - } - if {$zTrailing!=""} { - set A($zTrailing) [lrange $lArgs [expr $j+$i] end] - } - } -} ;# namespace eval cmdline -# End of command line options processor. -########################################################################### -########################################################################### - -process_cmdline - -# Check that the specified tool is present. -# -proc check_for_tool {tool} { - if {[file exists $tool]==0 || [file executable $tool]==0} { - puts stderr "Missing $tool... exiting. (run \[make $tool\])" - exit -1 - } -} - -if {$A(make)} { - if {$A(verbose)} { puts "building tools..." } - exec make dbselftest rbu sqlite3 sqldiff -} - -check_for_tool dbselftest -check_for_tool rbu -check_for_tool sqlite3 -check_for_tool sqldiff - -exec ./sqlite3 $A(database) "DROP TABLE selftest;" -exec ./sqlite3 $A(database2) "DROP TABLE selftest;" - -# Run [dbselftest --init] on both databases -if {$A(verbose)} { puts "Running \[dbselftest --init\]" } -exec ./dbselftest --init $A(database) -exec ./dbselftest --init $A(database2) - -# Create an RBU patch. -set tmpname "./rrt-[format %x [expr int(rand()*0x7FFFFFFF)]].db" -if {$A(verbose)} { puts "rbu database is $tmpname" } -exec ./sqldiff --rbu --vtab $A(database2) $A(database) | ./sqlite3 $tmpname - -# Run the [rbu] patch. -if {$A(verbose)} { puts "Running \[rbu]" } -exec ./rbu $A(database2) $tmpname - -set selftest_diff [exec ./sqldiff --table selftest $A(database) $A(database2)] -if {$selftest_diff != ""} { - puts stderr "patching table \"selftest\" failed: $selftest_diff" - exit -1 -} - -# Run [dbselftest] on both databases -if {$A(verbose)} { puts "Running \[dbselftest]" } -exec ./dbselftest $A(database) -exec ./dbselftest $A(database2) - -# Remove the RBU database -file delete $tmpname -puts "round trip test successful." - diff --git a/manifest b/manifest index 4b583d7f1f..d235a22e79 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\serror\sin\sthe\sSQLITE_MAX_MEMORY\simplementation\sresulting\sfrom\sa\sbad\nmerge.\s\sUpdate\sthe\sOSSFuzz\sinterface\sso\sthat\sit\stimes\sout\safter\srunning\nthe\sbyte-code\sengine\sfor\s10\sseconds. -D 2017-03-10T17:03:11.362 +C Remove\sthe\srbu_round_trip.tcl\sscript.\sIt\sis\snow\spart\sof\sproject\s"test-dbs". +D 2017-03-10T18:36:34.515 F Makefile.in 2dae2a56457c2885425a480e1053de8096aff924 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 9020fa41eb91f657ae0cc44145d0a2f3af520860 @@ -250,7 +250,6 @@ F ext/rbu/rbuA.test c1a7b3e2d926b8f8448bb3b4ae787e314ee4b2b3 F ext/rbu/rbuB.test c25bc325b8072a766e56bb76c001866b405925c2 F ext/rbu/rbuC.test efe47db508a0269b683cb2a1913a425ffd39a831 F ext/rbu/rbu_common.tcl a38e8e2d4a50fd6aaf151633714c1b1d2fae3ead -F ext/rbu/rbu_round_trip.tcl f3216836bbaeb10d76a2c70b89c13f59eabbd117 F ext/rbu/rbucrash.test 8d2ed5d4b05fef6c00c2a6b5f7ead71fa172a695 F ext/rbu/rbucrash2.test b2ecbdd7bb72c88bd217c65bd00dafa07f7f2d4d F ext/rbu/rbudiff.test 3e605cf624d00d04d0fb1316a3acec4fbe3b3ac5 @@ -1563,7 +1562,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P eabd4ef498a0f0d97d65e321c4d06ab90523ed61 -R 69fed97a3de499803e89b1ea5d13a87c -U drh -Z 0ae96bef0d12b3fb7ff36d9387e9c8a8 +P f8560c60d10c0365b33342ab05b5a953987b0471 +R 01deb9b1ef259df8dc49773e784400ec +U dan +Z 416d02cdb56bde7d758b337f12e18e66 diff --git a/manifest.uuid b/manifest.uuid index 221755c547..45f57f4026 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f8560c60d10c0365b33342ab05b5a953987b0471 \ No newline at end of file +b5bf2957677e8f2acd7426b302229a966de08fd9 \ No newline at end of file From 891d6b4e9e50e45e732fb759f03088f34b85d604 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 11 Mar 2017 00:46:57 +0000 Subject: [PATCH 1410/1484] Increase the number of significant digits in floating point literals on ".dump" output from the shell. FossilOrigin-Name: 7359fcacaadc349f520536311dcd1d0b5cea7673 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/shell.c | 8 ++++++-- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index d235a22e79..20f373b96b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sthe\srbu_round_trip.tcl\sscript.\sIt\sis\snow\spart\sof\sproject\s"test-dbs". -D 2017-03-10T18:36:34.515 +C Increase\sthe\snumber\sof\ssignificant\sdigits\sin\sfloating\spoint\sliterals\son\n".dump"\soutput\sfrom\sthe\sshell. +D 2017-03-11T00:46:57.350 F Makefile.in 2dae2a56457c2885425a480e1053de8096aff924 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 9020fa41eb91f657ae0cc44145d0a2f3af520860 @@ -399,7 +399,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 3e518b962d932a997fae373366880fc028c75706 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c d12f3539f80db38b09015561b569e0eb1c4b6c5f -F src/shell.c 4d9be7f0622365029a1f2e0f9628b8e363700ff5 +F src/shell.c df29706f8b19e3b6f695b4f64d6c6963348ca8a4 F src/sqlite.h.in 4d0c08f8640c586564a7032b259c5f69bf397850 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae @@ -1562,7 +1562,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P f8560c60d10c0365b33342ab05b5a953987b0471 -R 01deb9b1ef259df8dc49773e784400ec -U dan -Z 416d02cdb56bde7d758b337f12e18e66 +P b5bf2957677e8f2acd7426b302229a966de08fd9 +R a3ca39ff602fd356af0fc62171a8021d +U drh +Z 21429fdf284b465374d1bf63bafb22c0 diff --git a/manifest.uuid b/manifest.uuid index 45f57f4026..61cc19af5e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b5bf2957677e8f2acd7426b302229a966de08fd9 \ No newline at end of file +7359fcacaadc349f520536311dcd1d0b5cea7673 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 378729d09b..04f37809cc 100644 --- a/src/shell.c +++ b/src/shell.c @@ -2007,9 +2007,13 @@ static int shell_callback( }else if( aiType && aiType[i]==SQLITE_TEXT ){ if( zSep[0] ) utf8_printf(p->out,"%s",zSep); output_quoted_string(p->out, azArg[i]); - }else if( aiType && (aiType[i]==SQLITE_INTEGER - || aiType[i]==SQLITE_FLOAT) ){ + }else if( aiType && aiType[i]==SQLITE_INTEGER ){ utf8_printf(p->out,"%s%s",zSep, azArg[i]); + }else if( aiType && aiType[i]==SQLITE_FLOAT ){ + char z[50]; + double r = sqlite3_column_double(p->pStmt, i); + sqlite3_snprintf(50,z,"%!.20g", r); + raw_printf(p->out, "%s%s", zSep, z); }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){ const void *pBlob = sqlite3_column_blob(p->pStmt, i); int nBlob = sqlite3_column_bytes(p->pStmt, i); From 708b22b1e37e0093355911861c192a21f17a7fa6 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 11 Mar 2017 01:56:41 +0000 Subject: [PATCH 1411/1484] The output of the ".dump" command in the CLI quotes newline and carriage-return characters using "char(10)" and "char(13)". FossilOrigin-Name: 8b2954dd8376e2de985cf5dedeb6eec32c430505 --- manifest | 15 +++++++++------ manifest.uuid | 2 +- src/shell.c | 52 +++++++++++++++++++++++++++++++++++---------------- 3 files changed, 46 insertions(+), 23 deletions(-) diff --git a/manifest b/manifest index 20f373b96b..a01f5a9680 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Increase\sthe\snumber\sof\ssignificant\sdigits\sin\sfloating\spoint\sliterals\son\n".dump"\soutput\sfrom\sthe\sshell. -D 2017-03-11T00:46:57.350 +C The\soutput\sof\sthe\s".dump"\scommand\sin\sthe\sCLI\squotes\snewline\sand\scarriage-return\ncharacters\susing\s"char(10)"\sand\s"char(13)". +D 2017-03-11T01:56:41.692 F Makefile.in 2dae2a56457c2885425a480e1053de8096aff924 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 9020fa41eb91f657ae0cc44145d0a2f3af520860 @@ -399,7 +399,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 3e518b962d932a997fae373366880fc028c75706 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c d12f3539f80db38b09015561b569e0eb1c4b6c5f -F src/shell.c df29706f8b19e3b6f695b4f64d6c6963348ca8a4 +F src/shell.c 353f3cebb938099577494326e2853010512e0625 F src/sqlite.h.in 4d0c08f8640c586564a7032b259c5f69bf397850 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae @@ -1562,7 +1562,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b5bf2957677e8f2acd7426b302229a966de08fd9 -R a3ca39ff602fd356af0fc62171a8021d +P 7359fcacaadc349f520536311dcd1d0b5cea7673 +R 21dd742a2e245e17ea4fce05d92294e6 +T *branch * string-quoting-dump +T *sym-string-quoting-dump * +T -sym-trunk * U drh -Z 21429fdf284b465374d1bf63bafb22c0 +Z 185539d207724f873d847ed122ae7c58 diff --git a/manifest.uuid b/manifest.uuid index 61cc19af5e..db4edcf339 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7359fcacaadc349f520536311dcd1d0b5cea7673 \ No newline at end of file +8b2954dd8376e2de985cf5dedeb6eec32c430505 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 04f37809cc..602415f8c9 100644 --- a/src/shell.c +++ b/src/shell.c @@ -1490,32 +1490,52 @@ static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){ /* ** Output the given string as a quoted string using SQL quoting conventions. +** +** The "\n" and "\r" characters are converted to char(10) and char(13) +** to prevent them from being transformed by end-of-line translators. */ static void output_quoted_string(FILE *out, const char *z){ int i; - int nSingle = 0; + char c; setBinaryMode(out, 1); - for(i=0; z[i]; i++){ - if( z[i]=='\'' ) nSingle++; - } - if( nSingle==0 ){ + for(i=0; (c = z[i])!=0 && c!='\'' && c!='\n' && c!='\r'; i++){} + if( c==0 ){ utf8_printf(out,"'%s'",z); }else{ - raw_printf(out,"'"); + int inQuote = 0; + int bStarted = 0; while( *z ){ - for(i=0; z[i] && z[i]!='\''; i++){} - if( i==0 ){ - raw_printf(out,"''"); - z++; - }else if( z[i]=='\'' ){ - utf8_printf(out,"%.*s''",i,z); - z += i+1; - }else{ - utf8_printf(out,"%s",z); + for(i=0; (c = z[i])!=0 && c!='\n' && c!='\r' && c!='\''; i++){} + if( c=='\'' ) i++; + if( i ){ + if( !inQuote ){ + if( bStarted ) raw_printf(out, "||"); + raw_printf(out, "'"); + inQuote = 1; + } + utf8_printf(out, "%.*s", i, z); + z += i; + bStarted = 1; + } + if( c=='\'' ){ + raw_printf(out, "'"); + continue; + } + if( inQuote ){ + raw_printf(out, "'"); + inQuote = 0; + } + if( c==0 ){ break; } + for(i=0; (c = z[i])=='\r' || c=='\n'; i++){ + if( bStarted ) raw_printf(out, "||"); + raw_printf(out, "char(%d)", c); + bStarted = 1; + } + z += i; } - raw_printf(out,"'"); + if( inQuote ) raw_printf(out, "'"); } setTextMode(out, 1); } From 202230ef5c7ba0eb584aa69be9bed9b8771e553e Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 11 Mar 2017 13:02:59 +0000 Subject: [PATCH 1412/1484] Make sure the translateColumnToCopy() routine in the query planner does not try to access an array that failed to be fully allocated due to a prior OOM. This fixes an issue discovered by OSSFuzz. FossilOrigin-Name: 3299a26160c239255608d1e2b15a221e28b18a3d --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/where.c | 13 +++++++++---- 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 20f373b96b..f5f93fedbc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Increase\sthe\snumber\sof\ssignificant\sdigits\sin\sfloating\spoint\sliterals\son\n".dump"\soutput\sfrom\sthe\sshell. -D 2017-03-11T00:46:57.350 +C Make\ssure\sthe\stranslateColumnToCopy()\sroutine\sin\sthe\squery\splanner\sdoes\snot\ntry\sto\saccess\san\sarray\sthat\sfailed\sto\sbe\sfully\sallocated\sdue\sto\sa\sprior\sOOM.\nThis\sfixes\san\sissue\sdiscovered\sby\sOSSFuzz. +D 2017-03-11T13:02:59.691 F Makefile.in 2dae2a56457c2885425a480e1053de8096aff924 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 9020fa41eb91f657ae0cc44145d0a2f3af520860 @@ -479,7 +479,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 40c543f0a2195d1b0dc88ef12142bea690009344 F src/wal.h 06b2a0b599cc0f53ea97f497cf8c6b758c999f71 F src/walker.c b71a992b413b3a022572eccf29ef4b4890223791 -F src/where.c 1a3a8adb717a20f17c186f3baa22b0b5f3a5ab13 +F src/where.c e815093e5ee039b6b4eb19b646d22deb1a3a523f F src/whereInt.h 2d50c2b74a33be44cb68fdecee30b4d93552f1f4 F src/wherecode.c 677e95413c472c0b413023b6b69a47f40fce1b04 F src/whereexpr.c 130cdd1a43af71b19755270fb1224874cf55158c @@ -1562,7 +1562,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b5bf2957677e8f2acd7426b302229a966de08fd9 -R a3ca39ff602fd356af0fc62171a8021d +P 7359fcacaadc349f520536311dcd1d0b5cea7673 +R b1f6c3d400d5c1eb17e51e0171dc7cb1 U drh -Z 21429fdf284b465374d1bf63bafb22c0 +Z 84001c734b11825e7e05194bb46aad97 diff --git a/manifest.uuid b/manifest.uuid index 61cc19af5e..8d84973a78 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7359fcacaadc349f520536311dcd1d0b5cea7673 \ No newline at end of file +3299a26160c239255608d1e2b15a221e28b18a3d \ No newline at end of file diff --git a/src/where.c b/src/where.c index 8d0dbb0979..4f65695a3f 100644 --- a/src/where.c +++ b/src/where.c @@ -517,14 +517,16 @@ static LogEst estLog(LogEst N){ ** value stored in its output register. */ static void translateColumnToCopy( - Vdbe *v, /* The VDBE containing code to translate */ + Parse *pParse, /* Parsing context */ int iStart, /* Translate from this opcode to the end */ int iTabCur, /* OP_Column/OP_Rowid references to this table */ int iRegister, /* The first column is in this register */ int bIncrRowid /* If non-zero, transform OP_rowid to OP_AddImm(1) */ ){ + Vdbe *v = pParse->pVdbe; VdbeOp *pOp = sqlite3VdbeGetOp(v, iStart); int iEnd = sqlite3VdbeCurrentAddr(v); + if( pParse->db->mallocFailed ) return; for(; iStartp1!=iTabCur ) continue; if( pOp->opcode==OP_Column ){ @@ -802,7 +804,9 @@ static void constructAutomaticIndex( if( pPartial ) sqlite3VdbeResolveLabel(v, iContinue); if( pTabItem->fg.viaCoroutine ){ sqlite3VdbeChangeP2(v, addrCounter, regBase+n); - translateColumnToCopy(v, addrTop, pLevel->iTabCur, pTabItem->regResult, 1); + testcase( pParse->db->mallocFailed ); + translateColumnToCopy(pParse, addrTop, pLevel->iTabCur, + pTabItem->regResult, 1); sqlite3VdbeGoto(v, addrTop); pTabItem->fg.viaCoroutine = 0; }else{ @@ -4920,8 +4924,9 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ ** the co-routine into OP_Copy of result contained in a register. ** OP_Rowid becomes OP_Null. */ - if( pTabItem->fg.viaCoroutine && !db->mallocFailed ){ - translateColumnToCopy(v, pLevel->addrBody, pLevel->iTabCur, + if( pTabItem->fg.viaCoroutine ){ + testcase( pParse->db->mallocFailed ); + translateColumnToCopy(pParse, pLevel->addrBody, pLevel->iTabCur, pTabItem->regResult, 0); continue; } From 1ed1e616f7930c919d7f7166a232389c2f28edc6 Mon Sep 17 00:00:00 2001 From: drh Date: Sun, 12 Mar 2017 19:39:00 +0000 Subject: [PATCH 1413/1484] Remove an obsolete assert() in the IN operator code generation. FossilOrigin-Name: 18bf6aca2ac86478fd12d5020f3a41cfd2bd2dc3defe2298411f79ad308a6f73 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/expr.c | 1 - 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index f5f93fedbc..29e9c47ab1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\ssure\sthe\stranslateColumnToCopy()\sroutine\sin\sthe\squery\splanner\sdoes\snot\ntry\sto\saccess\san\sarray\sthat\sfailed\sto\sbe\sfully\sallocated\sdue\sto\sa\sprior\sOOM.\nThis\sfixes\san\sissue\sdiscovered\sby\sOSSFuzz. -D 2017-03-11T13:02:59.691 +C Remove\san\sobsolete\sassert()\sin\sthe\sIN\soperator\scode\sgeneration. +D 2017-03-12T19:39:00.634 F Makefile.in 2dae2a56457c2885425a480e1053de8096aff924 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 9020fa41eb91f657ae0cc44145d0a2f3af520860 @@ -351,7 +351,7 @@ F src/ctime.c a9984df73898c042a5cfc8f9d8e7723d02bc35c9 F src/date.c ee676e7694dfadbdd2fde1a258a71be8360ba5ae F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c 0d9d5549d42e79ce4d82ff1db1e6c81e36d2f67c -F src/expr.c 8a29e9b72d4b642189999c41782cd6c5bc43512f +F src/expr.c 7eac40b592672a1f3e0565ac1e66fbb87218436c134d8b2460f989b550e2eb73 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 2e9aabe1aee76273aff8a84ee92c464e095400ae F src/func.c c67273e1ec08abbdcc14c189892a3ff6eeece86b @@ -1562,7 +1562,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 7359fcacaadc349f520536311dcd1d0b5cea7673 -R b1f6c3d400d5c1eb17e51e0171dc7cb1 +P 3299a26160c239255608d1e2b15a221e28b18a3d +R 0614fda50e45b1c812e74d7f5befdd87 U drh -Z 84001c734b11825e7e05194bb46aad97 +Z 926534de7c008338fc48290e21b48744 diff --git a/manifest.uuid b/manifest.uuid index 8d84973a78..64bc83d667 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3299a26160c239255608d1e2b15a221e28b18a3d \ No newline at end of file +18bf6aca2ac86478fd12d5020f3a41cfd2bd2dc3defe2298411f79ad308a6f73 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 2bf76eb0d7..e074f2f443 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2532,7 +2532,6 @@ int sqlite3CodeSubselect( int i; sqlite3SelectDestInit(&dest, SRT_Set, pExpr->iTable); dest.zAffSdst = exprINAffinity(pParse, pExpr); - assert( (pExpr->iTable&0x0000FFFF)==pExpr->iTable ); pSelect->iLimit = 0; testcase( pSelect->selFlags & SF_Distinct ); testcase( pKeyInfo==0 ); /* Caused by OOM in sqlite3KeyInfoAlloc() */ From ba28b5ab0a73e80522d279eb651ac92f4c861bfe Mon Sep 17 00:00:00 2001 From: drh Date: Sun, 12 Mar 2017 20:28:44 +0000 Subject: [PATCH 1414/1484] Fix a possible NULL pointer dereference in following an OOM error in sqlite3ExprIsInteger(). Problem found by OSS-Fuzz. FossilOrigin-Name: 5ec655e8e817c1ed3bfb2e576745a7cef441494ad7baf1bf9f8895e98ac19c5a --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/expr.c | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 29e9c47ab1..fe7c037a95 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\san\sobsolete\sassert()\sin\sthe\sIN\soperator\scode\sgeneration. -D 2017-03-12T19:39:00.634 +C Fix\sa\spossible\sNULL\spointer\sdereference\sin\sfollowing\san\sOOM\serror\nin\ssqlite3ExprIsInteger().\sProblem\sfound\sby\sOSS-Fuzz. +D 2017-03-12T20:28:44.701 F Makefile.in 2dae2a56457c2885425a480e1053de8096aff924 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 9020fa41eb91f657ae0cc44145d0a2f3af520860 @@ -351,7 +351,7 @@ F src/ctime.c a9984df73898c042a5cfc8f9d8e7723d02bc35c9 F src/date.c ee676e7694dfadbdd2fde1a258a71be8360ba5ae F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c 0d9d5549d42e79ce4d82ff1db1e6c81e36d2f67c -F src/expr.c 7eac40b592672a1f3e0565ac1e66fbb87218436c134d8b2460f989b550e2eb73 +F src/expr.c f12a581f342a6fd85d14c31e4fb84f16b3dd107f54d7728dddb62cebc79d7ce1 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 2e9aabe1aee76273aff8a84ee92c464e095400ae F src/func.c c67273e1ec08abbdcc14c189892a3ff6eeece86b @@ -1562,7 +1562,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 3299a26160c239255608d1e2b15a221e28b18a3d -R 0614fda50e45b1c812e74d7f5befdd87 +P 18bf6aca2ac86478fd12d5020f3a41cfd2bd2dc3defe2298411f79ad308a6f73 +R ca6b9859462ac91c5f6d6ceb39023c31 U drh -Z 926534de7c008338fc48290e21b48744 +Z af1824315a47164e92b4aa40f4d2923c diff --git a/manifest.uuid b/manifest.uuid index 64bc83d667..d832e1d80a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -18bf6aca2ac86478fd12d5020f3a41cfd2bd2dc3defe2298411f79ad308a6f73 \ No newline at end of file +5ec655e8e817c1ed3bfb2e576745a7cef441494ad7baf1bf9f8895e98ac19c5a \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index e074f2f443..ce948be69e 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1860,6 +1860,7 @@ int sqlite3ExprContainsSubquery(Expr *p){ */ int sqlite3ExprIsInteger(Expr *p, int *pValue){ int rc = 0; + if( p==0 ) return 0; /* Can only happen following on OOM */ /* If an expression is an integer literal that fits in a signed 32-bit ** integer, then the EP_IntValue flag will have already been set */ From bbc017746009e30bbac905bbd67dd1c7e1ac384c Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 13 Mar 2017 13:45:29 +0000 Subject: [PATCH 1415/1484] In the OSSFuzz test module, invoke the progress handler much more frequently so that timeouts are detected punctually even if the test script is running opcodes that individually take a long time (for example, an OP_Function opcode that invokes "randomblob(1.5e6)"). FossilOrigin-Name: f3b6959c04c4ef7b8ff03582b867012a869d52b4a90a0d7ab079ee4c21be5464 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/ossfuzz.c | 8 +++++--- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index fe7c037a95..ba1564ad2c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\spossible\sNULL\spointer\sdereference\sin\sfollowing\san\sOOM\serror\nin\ssqlite3ExprIsInteger().\sProblem\sfound\sby\sOSS-Fuzz. -D 2017-03-12T20:28:44.701 +C In\sthe\sOSSFuzz\stest\smodule,\sinvoke\sthe\sprogress\shandler\smuch\smore\sfrequently\nso\sthat\stimeouts\sare\sdetected\spunctually\seven\sif\sthe\stest\sscript\sis\srunning\nopcodes\sthat\sindividually\stake\sa\slong\stime\s(for\sexample,\san\sOP_Function\sopcode\nthat\sinvokes\s"randomblob(1.5e6)"). +D 2017-03-13T13:45:29.519 F Makefile.in 2dae2a56457c2885425a480e1053de8096aff924 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 9020fa41eb91f657ae0cc44145d0a2f3af520860 @@ -1006,7 +1006,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 f04b9f236e51d4db701bdebe8ac01318c83102a8 +F test/ossfuzz.c 6dc75478809cfbd4609409a87179ddc2ffaa092e8adb27c1982c5a944a7dd81f F test/ossshell.c d9f1a6f43e7bab45d6be857a5800f5d4a1861db3 F test/ovfl.test 199c482696defceacee8c8e0e0ef36da62726b2f F test/pager1.test 841868017e9dd3cb459b8d78862091a7d9cff21d @@ -1562,7 +1562,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 18bf6aca2ac86478fd12d5020f3a41cfd2bd2dc3defe2298411f79ad308a6f73 -R ca6b9859462ac91c5f6d6ceb39023c31 +P 5ec655e8e817c1ed3bfb2e576745a7cef441494ad7baf1bf9f8895e98ac19c5a +R 5ec7c17c414d77e4ccd9fef1ac3d681c U drh -Z af1824315a47164e92b4aa40f4d2923c +Z 5b49012ad9ab98ef47d2e1e6f7e9b1e7 diff --git a/manifest.uuid b/manifest.uuid index d832e1d80a..4616ab6ffc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5ec655e8e817c1ed3bfb2e576745a7cef441494ad7baf1bf9f8895e98ac19c5a \ No newline at end of file +f3b6959c04c4ef7b8ff03582b867012a869d52b4a90a0d7ab079ee4c21be5464 \ No newline at end of file diff --git a/test/ossfuzz.c b/test/ossfuzz.c index 91b3d1141e..97d101e17a 100644 --- a/test/ossfuzz.c +++ b/test/ossfuzz.c @@ -77,11 +77,13 @@ int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { if( rc ) return 0; #ifndef SQLITE_OMIT_PROGRESS_CALLBACK - /* Invoke the progress handler every 500 thousand instructions (approximately - ** 20 to 40 times per second) to check to see if we are taking too long. + /* Invoke the progress handler frequently to check to see if we + ** are taking too long. The progress handler will return true + ** (which will block further processing) if more than 10 seconds have + ** elapsed since the start of the test. */ iCutoff = timeOfDay() + 10000; /* Now + 10 seconds */ - sqlite3_progress_handler(db, 500000, progress_handler, (void*)&iCutoff); + sqlite3_progress_handler(db, 10, progress_handler, (void*)&iCutoff); #endif /* Bit 1 of the selector enables foreign key constraints */ From c3becddb75ad4d5cbf28881dad6bf559455ca0b7 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 13 Mar 2017 14:30:40 +0000 Subject: [PATCH 1416/1484] Fix a segfault that could occur following an OOM error in the flattenSubquery() routine. FossilOrigin-Name: c6dda3f752c184f441624c9993e77d5031063d79a0e177b6e25a9886514a742e --- manifest | 15 ++++++++------- manifest.uuid | 2 +- src/select.c | 4 +++- test/mallocM.test | 32 ++++++++++++++++++++++++++++++++ 4 files changed, 44 insertions(+), 9 deletions(-) create mode 100644 test/mallocM.test diff --git a/manifest b/manifest index ba1564ad2c..b7307e626a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\sthe\sOSSFuzz\stest\smodule,\sinvoke\sthe\sprogress\shandler\smuch\smore\sfrequently\nso\sthat\stimeouts\sare\sdetected\spunctually\seven\sif\sthe\stest\sscript\sis\srunning\nopcodes\sthat\sindividually\stake\sa\slong\stime\s(for\sexample,\san\sOP_Function\sopcode\nthat\sinvokes\s"randomblob(1.5e6)"). -D 2017-03-13T13:45:29.519 +C Fix\sa\ssegfault\sthat\scould\soccur\sfollowing\san\sOOM\serror\sin\sthe\nflattenSubquery()\sroutine. +D 2017-03-13T14:30:40.789 F Makefile.in 2dae2a56457c2885425a480e1053de8096aff924 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 9020fa41eb91f657ae0cc44145d0a2f3af520860 @@ -398,7 +398,7 @@ F src/printf.c 67427bbee66d891fc6f6f5aada857e9cdb368c1c F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 3e518b962d932a997fae373366880fc028c75706 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac -F src/select.c d12f3539f80db38b09015561b569e0eb1c4b6c5f +F src/select.c 2496d0cc6368dabe7ad2e4c7f5ed3ad9aa3b4d11cd90f33fa1d1ef72493f43aa F src/shell.c df29706f8b19e3b6f695b4f64d6c6963348ca8a4 F src/sqlite.h.in 4d0c08f8640c586564a7032b259c5f69bf397850 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -953,6 +953,7 @@ F test/mallocI.test 6c23a71df077fa5d387be90e7e669c5b368ca38a F test/mallocJ.test b5d1839da331d96223e5f458856f8ffe1366f62e F test/mallocK.test 27cb5566a6e5f2d76f9d4aa2eca45524401fd61e F test/mallocL.test fb311ff80afddf3b1a75e52289081f4754d901dc +F test/mallocM.test 491001d1e273233048d265ec6d38fdd23745b0284f0c93bc98c94b64451c9c28 F test/malloc_common.tcl aac62499b76be719fac31e7a3e54a7fd53272e7f F test/manydb.test 28385ae2087967aa05c38624cec7d96ec74feb3e F test/mem5.test c6460fba403c5703141348cd90de1c294188c68f @@ -1562,7 +1563,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 5ec655e8e817c1ed3bfb2e576745a7cef441494ad7baf1bf9f8895e98ac19c5a -R 5ec7c17c414d77e4ccd9fef1ac3d681c -U drh -Z 5b49012ad9ab98ef47d2e1e6f7e9b1e7 +P f3b6959c04c4ef7b8ff03582b867012a869d52b4a90a0d7ab079ee4c21be5464 +R 5476ff08c9b02210dda4864e54df5ab0 +U dan +Z 237b4d523d894c49cc7807017d798a94 diff --git a/manifest.uuid b/manifest.uuid index 4616ab6ffc..5bdba86213 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f3b6959c04c4ef7b8ff03582b867012a869d52b4a90a0d7ab079ee4c21be5464 \ No newline at end of file +c6dda3f752c184f441624c9993e77d5031063d79a0e177b6e25a9886514a742e \ No newline at end of file diff --git a/src/select.c b/src/select.c index d817ebd074..bb055c7894 100644 --- a/src/select.c +++ b/src/select.c @@ -3749,7 +3749,9 @@ static int flattenSubquery( }else{ pParent->pWhere = sqlite3ExprAnd(db, pWhere, pParent->pWhere); } - substSelect(pParse, pParent, iParent, pSub->pEList, 0); + if( db->mallocFailed==0 ){ + substSelect(pParse, pParent, iParent, pSub->pEList, 0); + } /* The flattened query is distinct if either the inner or the ** outer query is distinct. diff --git a/test/mallocM.test b/test/mallocM.test new file mode 100644 index 0000000000..85a38acf32 --- /dev/null +++ b/test/mallocM.test @@ -0,0 +1,32 @@ +# 2017 March 13 +# +# 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. +# +#*********************************************************************** +# Further OOM tests. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +source $testdir/malloc_common.tcl +set testprefix mallocM + +sqlite3_db_config_lookaside db 0 0 0 + +do_execsql_test 1.0 { + CREATE TABLE t1(x); +} +do_faultsim_test 1 -faults oom-t* -body { + execsql { + SELECT 'abc' FROM ( SELECT 'xyz' FROM t1 WHERE (SELECT 1) ) + } +} -test { + faultsim_test_result {0 {}} +} + +finish_test From 510b7ff53612658ff1a3c6a848779014b3668aeb Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 13 Mar 2017 17:37:13 +0000 Subject: [PATCH 1417/1484] Fix the sqlite3TreeViewSelect() routine so that it works with a null pointer to the Select object. FossilOrigin-Name: 9034cf7efc603864f51e931c7dc4fbbc2d01904e951e78c88d4d80f9936250e8 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/treeview.c | 4 ++++ 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index b7307e626a..cf51919ad1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\ssegfault\sthat\scould\soccur\sfollowing\san\sOOM\serror\sin\sthe\nflattenSubquery()\sroutine. -D 2017-03-13T14:30:40.789 +C Fix\sthe\ssqlite3TreeViewSelect()\sroutine\sso\sthat\sit\sworks\swith\sa\snull\spointer\nto\sthe\sSelect\sobject. +D 2017-03-13T17:37:13.752 F Makefile.in 2dae2a56457c2885425a480e1053de8096aff924 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 9020fa41eb91f657ae0cc44145d0a2f3af520860 @@ -459,7 +459,7 @@ F src/test_windirent.h 5d67483a55442e31e1bde0f4a230e6e932ad5906 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c dc748c5afcb9e5beb3ef5651bc99a4622e30f6a1 -F src/treeview.c 4e44ade3bfe59d82005039f72e09333ce2b4162c +F src/treeview.c 84d0ac737e1231702679f0289180021e19c5cc186ec413e8dcb704a887c76ec8 F src/trigger.c c9f0810043b265724fdb1bdd466894f984dfc182 F src/update.c 456d4a4656f8a03c2abc88a51b19172197400e58 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c @@ -1563,7 +1563,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P f3b6959c04c4ef7b8ff03582b867012a869d52b4a90a0d7ab079ee4c21be5464 -R 5476ff08c9b02210dda4864e54df5ab0 -U dan -Z 237b4d523d894c49cc7807017d798a94 +P c6dda3f752c184f441624c9993e77d5031063d79a0e177b6e25a9886514a742e +R 21d5fb07d70376e4a3754546b17385a3 +U drh +Z aeef669a336ea6338a3e27ef9df24400 diff --git a/manifest.uuid b/manifest.uuid index 5bdba86213..f701b94f3b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c6dda3f752c184f441624c9993e77d5031063d79a0e177b6e25a9886514a742e \ No newline at end of file +9034cf7efc603864f51e931c7dc4fbbc2d01904e951e78c88d4d80f9936250e8 \ No newline at end of file diff --git a/src/treeview.c b/src/treeview.c index 0ea512b5c6..61d4626a22 100644 --- a/src/treeview.c +++ b/src/treeview.c @@ -126,6 +126,10 @@ void sqlite3TreeViewWith(TreeView *pView, const With *pWith, u8 moreToFollow){ void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){ int n = 0; int cnt = 0; + if( p==0 ){ + sqlite3TreeViewLine(pView, "nil-SELECT"); + return; + } pView = sqlite3TreeViewPush(pView, moreToFollow); if( p->pWith ){ sqlite3TreeViewWith(pView, p->pWith, 1); From 688633cb9eb400d8c69cbbcd99a4410a810bf0fb Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 13 Mar 2017 19:26:34 +0000 Subject: [PATCH 1418/1484] Infrastructure for an extension C-library to implement sqlite3_db_dump() and a corresponding "dbdump" command-line utility - both of which do the same work as the ".dump" command of the CLI. FossilOrigin-Name: 74c5ace498f72d7f5495203678bedd0bc540211131a4e4db7b62115d5322a288 --- Makefile.in | 4 ++ ext/misc/dbdump.c | 103 ++++++++++++++++++++++++++++++++++++++++++++++ main.mk | 4 ++ manifest | 19 +++++---- manifest.uuid | 2 +- 5 files changed, 123 insertions(+), 9 deletions(-) create mode 100644 ext/misc/dbdump.c diff --git a/Makefile.in b/Makefile.in index ba59b3723f..0b40cb458b 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1154,6 +1154,10 @@ sqlite3_analyzer.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/spaceanal.tcl sqlite3_analyzer$(TEXE): sqlite3_analyzer.c $(LTLINK) sqlite3_analyzer.c -o $@ $(LIBTCL) $(TLIBS) +dbdump$(TEXE): $(TOP)/ext/misc/dbdump.c sqlite3.lo + $(LTLINK) -DDBDUMP_STANDALONE -o $@ \ + $(TOP)/ext/misc/dbdump.c sqlite3.lo $(TLIBS) + showdb$(TEXE): $(TOP)/tool/showdb.c sqlite3.lo $(LTLINK) -o $@ $(TOP)/tool/showdb.c sqlite3.lo $(TLIBS) diff --git a/ext/misc/dbdump.c b/ext/misc/dbdump.c new file mode 100644 index 0000000000..b7fe595e29 --- /dev/null +++ b/ext/misc/dbdump.c @@ -0,0 +1,103 @@ +/* +** 2016-03-13 +** +** 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 a C-language subroutine that converts the content +** of an SQLite database into UTF-8 text SQL statements that can be used +** to exactly recreate the original database. +** +** A prototype of the implemented subroutine is this: +** +** int sqlite3_db_dump( +** sqlite3 *db, +** const char *zSchema, +** const char *zTable, +** void (*xCallback)(void*, const char*), +** void *pArg +** ); +** +** The db parameter is the database connection. zSchema is the schema within +** that database which is to be dumped. Usually the zSchema is "main" but +** can also be "temp" or any ATTACH-ed database. If zTable is not NULL, then +** only the content of that one table is dumped. If zTable is NULL, then all +** tables are dumped. +** +** The generate text is passed to xCallback() in multiple calls. The second +** argument to xCallback() is a copy of the pArg parameter. The first +** argument is some of the output text that this routine generates. The +** signature to xCallback() is designed to make it compatible with fputs(). +** +** The sqlite3_db_dump() subroutine returns SQLITE_OK on success or some error +** code if it encounters a problem. +** +** If this file is compiled with -DDBDUMP_STANDALONE then a "main()" routine +** is included so that this routine becomes a command-line utility. The +** command-line utility takes two or three arguments which are the name +** of the database file, the schema, and optionally the table, forming the +** first three arguments of a single call to the library routine. +*/ +#include "sqlite3.h" + +/* +** Convert an SQLite database into SQL statements that will recreate that +** database. +*/ +int sqlite3_db_dump( + sqlite3 *db, /* The database connection */ + const char *zSchema, /* Which schema to dump. Usually "main". */ + const char *zTable, /* Which table to dump. NULL means everything. */ + int (*xCallback)(const char*,void*), /* Output sent to this callback */ + void *pArg /* Second argument of the callback */ +){ + return SQLITE_OK; +} + + + +/* The generic subroutine is above. The code the follows implements +** the command-line interface. +*/ +#ifdef DBDUMP_STANDALONE +#include + +/* +** Command-line interface +*/ +int main(int argc, char **argv){ + sqlite3 *db; + const char *zDb; + const char *zSchema; + const char *zTable = 0; + int rc; + + if( argc<2 || argc>4 ){ + fprintf(stderr, "Usage: %s DATABASE ?SCHEMA? ?TABLE?\n", argv[0]); + return 1; + } + zDb = argv[1]; + zSchema = argc>=3 ? argv[2] : "main"; + zTable = argc==4 ? argv[3] : 0; + + rc = sqlite3_open(zDb, &db); + if( rc ){ + fprintf(stderr, "Cannot open \"%s\": %s\n", zDb, sqlite3_errmsg(db)); + sqlite3_close(db); + return 1; + } + rc = sqlite3_db_dump(db, zSchema, zTable, + (int(*)(const char*,void*))fputs, (void*)stdout); + if( rc ){ + fprintf(stderr, "Error: sqlite3_db_dump() returns %d\n", rc); + } + sqlite3_close(db); + return rc!=SQLITE_OK; +} +#endif /* DBDUMP_STANDALONE */ diff --git a/main.mk b/main.mk index 8815f0f701..54f223bb56 100644 --- a/main.mk +++ b/main.mk @@ -761,6 +761,10 @@ sqlite3_analyzer.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/spaceanal.tcl sqlite3_analyzer$(EXE): sqlite3_analyzer.c $(TCCX) $(TCL_FLAGS) sqlite3_analyzer.c -o $@ $(LIBTCL) $(THREADLIB) +dbdump$(EXE): $(TOP)/ext/misc/dbdump.c sqlite3.o + $(TCCX) -DDBDUMP_STANDALONE -o dbdump$(EXE) \ + $(TOP)/ext/misc/dbdump.c sqlite3.o $(THREADLIB) + # Rules to build the 'testfixture' application. # TESTFIXTURE_FLAGS = -DSQLITE_TEST=1 -DSQLITE_CRASH_TEST=1 diff --git a/manifest b/manifest index b74ca835a2..4fc996e4ef 100644 --- a/manifest +++ b/manifest @@ -1,6 +1,6 @@ -C In\sthe\soutput\sof\sthe\s".dump"\scommand\sin\sthe\sCLI,\squote\snewline\sand\ncarriage-return\scharacters\susing\sthe\schar()\sfunction,\sso\sthat\sthey\sdo\snot\nget\seaten\sby\send-of-line\sprocessing\slogic\sin\sthe\sOS\sor\sin\sother\scommand-line\nutilities\sand/or\slibraries. -D 2017-03-13T18:24:06.748 -F Makefile.in 2dae2a56457c2885425a480e1053de8096aff924 +C Infrastructure\sfor\san\sextension\sC-library\sto\simplement\ssqlite3_db_dump()\sand\na\scorresponding\s"dbdump"\scommand-line\sutility\s-\sboth\sof\swhich\sdo\sthe\ssame\nwork\sas\sthe\s".dump"\scommand\sof\sthe\sCLI. +D 2017-03-13T19:26:34.140 +F Makefile.in 9605f4c49eace601d5c12c85dd6e037cc613a6d823e857614ba26b42f1285db0 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 9020fa41eb91f657ae0cc44145d0a2f3af520860 F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7 @@ -211,6 +211,7 @@ F ext/misc/carray.c 40c27641010a4dc67e3690bdb7c9d36ca58b3c2d F ext/misc/closure.c 0d2a038df8fbae7f19de42e7c7d71f2e4dc88704 F ext/misc/compress.c 122faa92d25033d6c3f07c39231de074ab3d2e83 F ext/misc/csv.c 531a46cbad789fca0aa9db69a0e6c8ac9e68767d +F ext/misc/dbdump.c 5777b95fe1797a7fce841f4cb88bc30f66b8a3c929e988b1d3b3cf4aab044739 F ext/misc/eval.c f971962e92ebb8b0a4e6b62949463ee454d88fa2 F ext/misc/fileio.c d4171c815d6543a9edef8308aab2951413cd8d0f F ext/misc/fuzzer.c 7c64b8197bb77b7d64eff7cac7848870235d4c25 @@ -322,7 +323,7 @@ F ext/userauth/userauth.c 3410be31283abba70255d71fd24734e017a4497f F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60 -F main.mk 0ec10b604f4668f7e85a358954babe75c94dc0d5 +F main.mk 9abb506e717887d57f754bae139b85c1a06d6f2ac25b589f3e792e310567f278 F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 @@ -1563,8 +1564,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 9034cf7efc603864f51e931c7dc4fbbc2d01904e951e78c88d4d80f9936250e8 8b2954dd8376e2de985cf5dedeb6eec32c430505 -R 73c5fbe608fb0e20ee39173a6198ea04 -T +closed 8b2954dd8376e2de985cf5dedeb6eec32c430505 +P 68f6dc7af1013f296a11db14c007cc13cc3fe56832848bfed835ed8f74dcc676 +R 26910a3d8e71b6c159f5bba8a9a5daac +T *branch * dbdump +T *sym-dbdump * +T -sym-trunk * U drh -Z 5e4a79f0eabba6013ee57f9716ad3797 +Z 0266a8ae90d3841510ebcee8fa626828 diff --git a/manifest.uuid b/manifest.uuid index 35073a3308..f9e622d35f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -68f6dc7af1013f296a11db14c007cc13cc3fe56832848bfed835ed8f74dcc676 \ No newline at end of file +74c5ace498f72d7f5495203678bedd0bc540211131a4e4db7b62115d5322a288 \ No newline at end of file From 473af4fe03643d1cc771a3e394eb8579c3fbf61a Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 13 Mar 2017 21:26:41 +0000 Subject: [PATCH 1419/1484] First draft of the complete dbdump.c library. FossilOrigin-Name: 84ea4fcc52d0af02648c52989c2e69f4961071e1620382555ec59a39161a7a7d --- ext/misc/dbdump.c | 614 +++++++++++++++++++++++++++++++++++++++++++++- manifest | 15 +- manifest.uuid | 2 +- 3 files changed, 619 insertions(+), 12 deletions(-) diff --git a/ext/misc/dbdump.c b/ext/misc/dbdump.c index b7fe595e29..ce51eba0a0 100644 --- a/ext/misc/dbdump.c +++ b/ext/misc/dbdump.c @@ -12,7 +12,7 @@ ** ** This file implements a C-language subroutine that converts the content ** of an SQLite database into UTF-8 text SQL statements that can be used -** to exactly recreate the original database. +** to exactly recreate the original database. ROWID values are preserved. ** ** A prototype of the implemented subroutine is this: ** @@ -45,6 +45,574 @@ ** first three arguments of a single call to the library routine. */ #include "sqlite3.h" +#include +#include +#include + +/* +** The state of the dump process. +*/ +typedef struct DState DState; +struct DState { + sqlite3 *db; /* The database connection */ + int nErr; /* Number of errors seen so far */ + int rc; /* Error code */ + int writableSchema; /* True if in writable_schema mode */ + int (*xCallback)(const char*,void*); /* Send output here */ + void *pArg; /* Argument to xCallback() */ +}; + +/* +** A variable length string to which one can append text. +*/ +typedef struct DText DText; +struct DText { + char *z; /* The text */ + int n; /* Number of bytes of content in z[] */ + int nAlloc; /* Number of bytes allocated to z[] */ +}; + +/* +** Initialize and destroy a DText object +*/ +static void initText(DText *p){ + memset(p, 0, sizeof(*p)); +} +static void freeText(DText *p){ + sqlite3_free(p->z); + initText(p); +} + +/* zIn is either a pointer to a NULL-terminated string in memory obtained +** from malloc(), or a NULL pointer. The string pointed to by zAppend is +** added to zIn, and the result returned in memory obtained from malloc(). +** zIn, if it was not NULL, is freed. +** +** If the third argument, quote, is not '\0', then it is used as a +** quote character for zAppend. +*/ +static void appendText(DText *p, char const *zAppend, char quote){ + int len; + int i; + int nAppend = (int)(strlen(zAppend) & 0x3fffffff); + + len = nAppend+p->n+1; + if( quote ){ + len += 2; + for(i=0; in+len>=p->nAlloc ){ + char *zNew; + p->nAlloc = p->nAlloc*2 + len + 20; + zNew = sqlite3_realloc(p->z, p->nAlloc); + if( zNew==0 ){ + freeText(p); + return; + } + p->z = zNew; + } + + if( quote ){ + char *zCsr = p->z+p->n; + *zCsr++ = quote; + for(i=0; in = (int)(zCsr - p->z); + *zCsr = '\0'; + }else{ + memcpy(p->z+p->n, zAppend, nAppend); + p->n += nAppend; + p->z[p->n] = '\0'; + } +} + +/* +** Attempt to determine if identifier zName needs to be quoted, either +** because it contains non-alphanumeric characters, or because it is an +** SQLite keyword. Be conservative in this estimate: When in doubt assume +** that quoting is required. +** +** Return '"' if quoting is required. Return 0 if no quoting is required. +*/ +static char quoteChar(const char *zName){ + /* All SQLite keywords, in alphabetical order */ + static const char *azKeywords[] = { + "ABORT", "ACTION", "ADD", "AFTER", "ALL", "ALTER", "ANALYZE", "AND", "AS", + "ASC", "ATTACH", "AUTOINCREMENT", "BEFORE", "BEGIN", "BETWEEN", "BY", + "CASCADE", "CASE", "CAST", "CHECK", "COLLATE", "COLUMN", "COMMIT", + "CONFLICT", "CONSTRAINT", "CREATE", "CROSS", "CURRENT_DATE", + "CURRENT_TIME", "CURRENT_TIMESTAMP", "DATABASE", "DEFAULT", "DEFERRABLE", + "DEFERRED", "DELETE", "DESC", "DETACH", "DISTINCT", "DROP", "EACH", + "ELSE", "END", "ESCAPE", "EXCEPT", "EXCLUSIVE", "EXISTS", "EXPLAIN", + "FAIL", "FOR", "FOREIGN", "FROM", "FULL", "GLOB", "GROUP", "HAVING", "IF", + "IGNORE", "IMMEDIATE", "IN", "INDEX", "INDEXED", "INITIALLY", "INNER", + "INSERT", "INSTEAD", "INTERSECT", "INTO", "IS", "ISNULL", "JOIN", "KEY", + "LEFT", "LIKE", "LIMIT", "MATCH", "NATURAL", "NO", "NOT", "NOTNULL", + "NULL", "OF", "OFFSET", "ON", "OR", "ORDER", "OUTER", "PLAN", "PRAGMA", + "PRIMARY", "QUERY", "RAISE", "RECURSIVE", "REFERENCES", "REGEXP", + "REINDEX", "RELEASE", "RENAME", "REPLACE", "RESTRICT", "RIGHT", + "ROLLBACK", "ROW", "SAVEPOINT", "SELECT", "SET", "TABLE", "TEMP", + "TEMPORARY", "THEN", "TO", "TRANSACTION", "TRIGGER", "UNION", "UNIQUE", + "UPDATE", "USING", "VACUUM", "VALUES", "VIEW", "VIRTUAL", "WHEN", "WHERE", + "WITH", "WITHOUT", + }; + int i, lwr, upr, mid, c; + if( !isalpha((unsigned char)zName[0]) && zName[0]!='_' ) return '"'; + for(i=0; zName[i]; i++){ + if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ) return '"'; + } + lwr = 0; + upr = sizeof(azKeywords)/sizeof(azKeywords[0]) - 1; + while( lwr<=upr ){ + mid = (lwr+upr)/2; + c = sqlite3_stricmp(azKeywords[mid], zName); + if( c==0 ) return '"'; + if( c<0 ){ + lwr = mid+1; + }else{ + upr = mid-1; + } + } + return 0; +} + + +/* +** Release memory previously allocated by tableColumnList(). +*/ +static void freeColumnList(char **azCol){ + int i; + for(i=1; azCol[i]; i++){ + sqlite3_free(azCol[i]); + } + /* azCol[0] is a static string */ + sqlite3_free(azCol); +} + +/* +** Return a list of pointers to strings which are the names of all +** columns in table zTab. The memory to hold the names is dynamically +** allocated and must be released by the caller using a subsequent call +** to freeColumnList(). +** +** The azCol[0] entry is usually NULL. However, if zTab contains a rowid +** value that needs to be preserved, then azCol[0] is filled in with the +** name of the rowid column. +** +** The first regular column in the table is azCol[1]. The list is terminated +** by an entry with azCol[i]==0. +*/ +static char **tableColumnList(DState *p, const char *zTab){ + char **azCol = 0; + sqlite3_stmt *pStmt = 0; + char *zSql; + int nCol = 0; + int nAlloc = 0; + int nPK = 0; /* Number of PRIMARY KEY columns seen */ + int isIPK = 0; /* True if one PRIMARY KEY column of type INTEGER */ + int preserveRowid = 1; + int rc; + + zSql = sqlite3_mprintf("PRAGMA table_info=%Q", zTab); + if( zSql==0 ) return 0; + rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); + sqlite3_free(zSql); + if( rc ) return 0; + azCol[0] = 0; + while( sqlite3_step(pStmt)==SQLITE_ROW ){ + if( nCol>=nAlloc-2 ){ + char **azNew; + nAlloc = nAlloc*2 + nCol + 10; + azNew = sqlite3_realloc(azCol, nAlloc*sizeof(azCol[0])); + if( azNew==0 ) goto col_oom; + azCol = azNew; + } + azCol[++nCol] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 1)); + if( azCol[nCol]==0 ) goto col_oom; + if( sqlite3_column_int(pStmt, 5) ){ + nPK++; + if( nPK==1 + && sqlite3_stricmp((const char*)sqlite3_column_text(pStmt,2), + "INTEGER")==0 + ){ + isIPK = 1; + }else{ + isIPK = 0; + } + } + } + sqlite3_finalize(pStmt); + pStmt = 0; + azCol[nCol+1] = 0; + + /* The decision of whether or not a rowid really needs to be preserved + ** is tricky. We never need to preserve a rowid for a WITHOUT ROWID table + ** or a table with an INTEGER PRIMARY KEY. We are unable to preserve + ** rowids on tables where the rowid is inaccessible because there are other + ** columns in the table named "rowid", "_rowid_", and "oid". + */ + if( isIPK ){ + /* If a single PRIMARY KEY column with type INTEGER was seen, then it + ** might be an alise for the ROWID. But it might also be a WITHOUT ROWID + ** table or a INTEGER PRIMARY KEY DESC column, neither of which are + ** ROWID aliases. To distinguish these cases, check to see if + ** there is a "pk" entry in "PRAGMA index_list". There will be + ** no "pk" index if the PRIMARY KEY really is an alias for the ROWID. + */ + zSql = sqlite3_mprintf("SELECT 1 FROM pragma_index_list(%Q)" + " WHERE origin='pk'", zTab); + if( zSql==0 ) goto col_oom; + rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); + sqlite3_free(zSql); + if( rc ){ + freeColumnList(azCol); + return 0; + } + rc = sqlite3_step(pStmt); + sqlite3_finalize(pStmt); + pStmt = 0; + preserveRowid = rc==SQLITE_ROW; + } + if( preserveRowid ){ + /* Only preserve the rowid if we can find a name to use for the + ** rowid */ + static char *azRowid[] = { "rowid", "_rowid_", "oid" }; + int i, j; + for(j=0; j<3; j++){ + for(i=1; i<=nCol; i++){ + if( sqlite3_stricmp(azRowid[j],azCol[i])==0 ) break; + } + if( i>nCol ){ + /* At this point, we know that azRowid[j] is not the name of any + ** ordinary column in the table. Verify that azRowid[j] is a valid + ** name for the rowid before adding it to azCol[0]. WITHOUT ROWID + ** tables will fail this last check */ + int rc; + rc = sqlite3_table_column_metadata(p->db,0,zTab,azRowid[j],0,0,0,0,0); + if( rc==SQLITE_OK ) azCol[0] = azRowid[j]; + break; + } + } + } + return azCol; + +col_oom: + sqlite3_finalize(pStmt); + freeColumnList(azCol); + p->nErr++; + p->rc = SQLITE_NOMEM; + return 0; +} + +/* +** Send mprintf-formatted content to the output callback. +*/ +static void output_formatted(DState *p, const char *zFormat, ...){ + va_list ap; + char *z; + va_start(ap, zFormat); + z = sqlite3_mprintf(zFormat, ap); + va_end(ap); + p->xCallback(z, p->pArg); + sqlite3_free(z); +} + +/* +** Output the given string as a quoted string using SQL quoting conventions. +** +** The "\n" and "\r" characters are converted to char(10) and char(13) +** to prevent them from being transformed by end-of-line translators. +*/ +static void output_quoted_string(DState *p, const unsigned char *z){ + int i; + char c; + int inQuote = 0; + int bStarted = 0; + + for(i=0; (c = z[i])!=0 && c!='\'' && c!='\n' && c!='\r'; i++){} + if( c==0 ){ + output_formatted(p, "'%s'", z); + return; + } + while( *z ){ + for(i=0; (c = z[i])!=0 && c!='\n' && c!='\r' && c!='\''; i++){} + if( c=='\'' ) i++; + if( i ){ + if( !inQuote ){ + if( bStarted ) p->xCallback("||", p->pArg); + p->xCallback("'", p->pArg); + inQuote = 1; + } + output_formatted(p, "%.*s", i, z); + z += i; + bStarted = 1; + } + if( c=='\'' ){ + p->xCallback("'", p->pArg); + continue; + } + if( inQuote ){ + p->xCallback("'", p->pArg); + inQuote = 0; + } + if( c==0 ){ + break; + } + for(i=0; (c = z[i])=='\r' || c=='\n'; i++){ + if( bStarted ) p->xCallback("||", p->pArg); + output_formatted(p, "char(%d)", c); + bStarted = 1; + } + z += i; + } + if( inQuote ) p->xCallback("'", p->pArg); +} + +/* +** This is an sqlite3_exec callback routine used for dumping the database. +** Each row received by this callback consists of a table name, +** the table type ("index" or "table") and SQL to create the table. +** This routine should print text sufficient to recreate the table. +*/ +static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){ + int rc; + const char *zTable; + const char *zType; + const char *zSql; + DState *p = (DState*)pArg; + sqlite3_stmt *pStmt; + + (void)azCol; + if( nArg!=3 ) return 1; + zTable = azArg[0]; + zType = azArg[1]; + zSql = azArg[2]; + + if( strcmp(zTable, "sqlite_sequence")==0 ){ + p->xCallback("DELETE FROM sqlite_sequence;\n", p->pArg); + }else if( sqlite3_strglob("sqlite_stat?", zTable)==0 ){ + p->xCallback("ANALYZE sqlite_master;\n", p->pArg); + }else if( strncmp(zTable, "sqlite_", 7)==0 ){ + return 0; + }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){ + if( !p->writableSchema ){ + p->xCallback("PRAGMA writable_schema=ON;\n", p->pArg); + p->writableSchema = 1; + } + output_formatted(p, + "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)" + "VALUES('table','%q','%q',0,'%q');", + zTable, zTable, zSql); + return 0; + }else{ + if( sqlite3_strglob("CREATE TABLE ['\"]*", zSql)==0 ){ + p->xCallback("CREATE TABLE IF NOT EXISTS ", p->pArg); + p->xCallback(zSql+13, p->pArg); + }else{ + p->xCallback(zSql, p->pArg); + } + p->xCallback(";\n", p->pArg); + } + + if( strcmp(zType, "table")==0 ){ + DText sSelect; + DText sTable; + char **azCol; + int i; + int nCol; + + azCol = tableColumnList(p, zTable); + if( azCol==0 ) return 0; + + /* Always quote the table name, even if it appears to be pure ascii, + ** in case it is a keyword. Ex: INSERT INTO "table" ... */ + initText(&sTable); + appendText(&sTable, zTable, quoteChar(zTable)); + /* If preserving the rowid, add a column list after the table name. + ** In other words: "INSERT INTO tab(rowid,a,b,c,...) VALUES(...)" + ** instead of the usual "INSERT INTO tab VALUES(...)". + */ + if( azCol[0] ){ + appendText(&sTable, "(", 0); + appendText(&sTable, azCol[0], 0); + for(i=1; azCol[i]; i++){ + appendText(&sTable, ",", 0); + appendText(&sTable, azCol[i], quoteChar(azCol[i])); + } + appendText(&sTable, ")", 0); + } + appendText(&sTable, " VALUES(", 0); + + /* Build an appropriate SELECT statement */ + initText(&sSelect); + appendText(&sSelect, "SELECT ", 0); + if( azCol[0] ){ + appendText(&sSelect, azCol[0], 0); + appendText(&sSelect, ",", 0); + } + for(i=1; azCol[i]; i++){ + appendText(&sSelect, azCol[i], quoteChar(azCol[i])); + if( azCol[i+1] ){ + appendText(&sSelect, ",", 0); + } + } + nCol = i-1; + freeColumnList(azCol); + appendText(&sSelect, " FROM ", 0); + appendText(&sSelect, zTable, quoteChar(zTable)); + + rc = sqlite3_prepare_v2(p->db, sSelect.z, -1, &pStmt, 0); + if( rc!=SQLITE_OK ){ + p->nErr++; + if( p->rc==SQLITE_OK ) p->rc = rc; + }else{ + while( SQLITE_ROW==sqlite3_step(pStmt) ){ + p->xCallback(sTable.z, p->pArg); + for(i=0; ixCallback(",", p->pArg); + switch( sqlite3_column_type(pStmt,i) ){ + case SQLITE_INTEGER: { + output_formatted(p, "%lld", sqlite3_column_int64(pStmt,i)); + break; + } + case SQLITE_FLOAT: { + double r = sqlite3_column_double(pStmt,i); + output_formatted(p, "%!.20g", r); + break; + } + case SQLITE_NULL: { + p->xCallback("NULL", p->pArg); + break; + } + case SQLITE_TEXT: { + output_quoted_string(p, sqlite3_column_text(pStmt,i)); + break; + } + case SQLITE_BLOB: { + int nByte = sqlite3_column_bytes(pStmt,i); + unsigned char *a = (unsigned char*)sqlite3_column_blob(pStmt,i); + int j; + p->xCallback("x'", p->pArg); + for(j=0; j>4)&15]; + zWord[1] = "0123456789abcdef"[a[j]&15]; + zWord[2] = 0; + p->xCallback(zWord, p->pArg); + } + p->xCallback("'", p->pArg); + break; + } + } + } + p->xCallback(");\n", p->pArg); + } + } + sqlite3_finalize(pStmt); + freeText(&sTable); + freeText(&sSelect); + } + return 0; +} + + +/* +** Execute a query statement that will generate SQL output. Print +** the result columns, comma-separated, on a line and then add a +** semicolon terminator to the end of that line. +** +** If the number of columns is 1 and that column contains text "--" +** then write the semicolon on a separate line. That way, if a +** "--" comment occurs at the end of the statement, the comment +** won't consume the semicolon terminator. +*/ +static void output_sql_from_query( + DState *p, /* Query context */ + const char *zSelect, /* SELECT statement to extract content */ + ... +){ + sqlite3_stmt *pSelect; + int rc; + int nResult; + int i; + const char *z; + char *zSql; + va_list ap; + va_start(ap, zSelect); + zSql = sqlite3_mprintf(zSelect, ap); + va_end(ap); + if( zSql==0 ){ + p->rc = SQLITE_NOMEM; + p->nErr++; + return; + } + rc = sqlite3_prepare_v2(p->db, zSql, -1, &pSelect, 0); + sqlite3_free(zSql); + if( rc!=SQLITE_OK || !pSelect ){ + output_formatted(p, "/**** ERROR: (%d) %s *****/\n", rc, + sqlite3_errmsg(p->db)); + p->nErr++; + return; + } + rc = sqlite3_step(pSelect); + nResult = sqlite3_column_count(pSelect); + while( rc==SQLITE_ROW ){ + z = (const char*)sqlite3_column_text(pSelect, 0); + p->xCallback(z, p->pArg); + for(i=1; ixCallback(",", p->pArg); + p->xCallback((const char*)sqlite3_column_text(pSelect,i), p->pArg); + } + if( z==0 ) z = ""; + while( z[0] && (z[0]!='-' || z[1]!='-') ) z++; + if( z[0] ){ + p->xCallback("\n;\n", p->pArg); + }else{ + p->xCallback(";\n", p->pArg); + } + rc = sqlite3_step(pSelect); + } + rc = sqlite3_finalize(pSelect); + if( rc!=SQLITE_OK ){ + output_formatted(p, "/**** ERROR: (%d) %s *****/\n", rc, + sqlite3_errmsg(p->db)); + if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++; + } +} + +/* +** Run zQuery. Use dump_callback() as the callback routine so that +** the contents of the query are output as SQL statements. +** +** If we get a SQLITE_CORRUPT error, rerun the query after appending +** "ORDER BY rowid DESC" to the end. +*/ +static void run_schema_dump_query( + DState *p, + const char *zQuery, + ... +){ + char *zErr = 0; + char *z; + va_list ap; + va_start(ap, zQuery); + z = sqlite3_mprintf(zQuery, ap); + va_end(ap); + sqlite3_exec(p->db, z, dump_callback, p, &zErr); + sqlite3_free(z); + if( zErr ){ + output_formatted(p, "/****** %s ******/\n", zErr); + sqlite3_free(zErr); + p->nErr++; + zErr = 0; + } +} /* ** Convert an SQLite database into SQL statements that will recreate that @@ -57,7 +625,49 @@ int sqlite3_db_dump( int (*xCallback)(const char*,void*), /* Output sent to this callback */ void *pArg /* Second argument of the callback */ ){ - return SQLITE_OK; + DState x; + memset(&x, 0, sizeof(x)); + x.rc = sqlite3_exec(db, "BEGIN", 0, 0, 0); + if( x.rc ) return x.rc; + x.db = db; + x.xCallback = xCallback; + x.pArg = pArg; + xCallback("PRAGMA foreign_keys=OFF;\nBEGIN TRANSACTION;\n", pArg); + if( zTable==0 ){ + run_schema_dump_query(&x, + "SELECT name, type, sql FROM \"%w\".sqlite_master " + "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'", + zSchema + ); + run_schema_dump_query(&x, + "SELECT name, type, sql FROM \"%w\".sqlite_master " + "WHERE name=='sqlite_sequence'", zSchema + ); + output_sql_from_query(&x, + "SELECT sql FROM sqlite_master " + "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0 + ); + }else{ + run_schema_dump_query(&x, + "SELECT name, type, sql FROM \"%w\".sqlite_master " + "WHERE tbl_name=%Q COLLATE nocase AND type=='table'" + " AND sql NOT NULL", + zSchema, zTable + ); + output_sql_from_query(&x, + "SELECT sql FROM \"%w\".sqlite_master " + "WHERE sql NOT NULL" + " AND type IN ('index','trigger','view')" + " AND tbl_name=%Q COLLATE nocase", + zSchema, zTable + ); + } + if( x.writableSchema ){ + xCallback("PRAGMA writable_schema=OFF;\n", pArg); + } + xCallback(x.nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n", pArg); + sqlite3_exec(db, "COMMIT", 0, 0, 0); + return x.rc; } diff --git a/manifest b/manifest index 4fc996e4ef..dfbee1c83e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Infrastructure\sfor\san\sextension\sC-library\sto\simplement\ssqlite3_db_dump()\sand\na\scorresponding\s"dbdump"\scommand-line\sutility\s-\sboth\sof\swhich\sdo\sthe\ssame\nwork\sas\sthe\s".dump"\scommand\sof\sthe\sCLI. -D 2017-03-13T19:26:34.140 +C First\sdraft\sof\sthe\scomplete\sdbdump.c\slibrary. +D 2017-03-13T21:26:41.643 F Makefile.in 9605f4c49eace601d5c12c85dd6e037cc613a6d823e857614ba26b42f1285db0 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 9020fa41eb91f657ae0cc44145d0a2f3af520860 @@ -211,7 +211,7 @@ F ext/misc/carray.c 40c27641010a4dc67e3690bdb7c9d36ca58b3c2d F ext/misc/closure.c 0d2a038df8fbae7f19de42e7c7d71f2e4dc88704 F ext/misc/compress.c 122faa92d25033d6c3f07c39231de074ab3d2e83 F ext/misc/csv.c 531a46cbad789fca0aa9db69a0e6c8ac9e68767d -F ext/misc/dbdump.c 5777b95fe1797a7fce841f4cb88bc30f66b8a3c929e988b1d3b3cf4aab044739 +F ext/misc/dbdump.c 819eb33f6ff788a466525557f7ea3742078853cc794b2eb0799a254dd6da81e2 F ext/misc/eval.c f971962e92ebb8b0a4e6b62949463ee454d88fa2 F ext/misc/fileio.c d4171c815d6543a9edef8308aab2951413cd8d0f F ext/misc/fuzzer.c 7c64b8197bb77b7d64eff7cac7848870235d4c25 @@ -1564,10 +1564,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 68f6dc7af1013f296a11db14c007cc13cc3fe56832848bfed835ed8f74dcc676 -R 26910a3d8e71b6c159f5bba8a9a5daac -T *branch * dbdump -T *sym-dbdump * -T -sym-trunk * +P 74c5ace498f72d7f5495203678bedd0bc540211131a4e4db7b62115d5322a288 +R dcbc2252d3d150af6e3faa70158994bd U drh -Z 0266a8ae90d3841510ebcee8fa626828 +Z 9a73382dae2ea2eb6bda6a3d74fd54dd diff --git a/manifest.uuid b/manifest.uuid index f9e622d35f..0597c414ba 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -74c5ace498f72d7f5495203678bedd0bc540211131a4e4db7b62115d5322a288 \ No newline at end of file +84ea4fcc52d0af02648c52989c2e69f4961071e1620382555ec59a39161a7a7d \ No newline at end of file From d3bc75fb941cdadf06bd8d5424ec8d856c89aabe Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 13 Mar 2017 21:49:48 +0000 Subject: [PATCH 1420/1484] Fixes to the dump logic. All appears to be working in preliminary tests. FossilOrigin-Name: 007b11e301d444361c8eff8734dc2fb968a64343c177ff30cec74a0cf76099e8 --- ext/misc/dbdump.c | 16 ++++++++++------ manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/ext/misc/dbdump.c b/ext/misc/dbdump.c index ce51eba0a0..db581a8325 100644 --- a/ext/misc/dbdump.c +++ b/ext/misc/dbdump.c @@ -224,7 +224,6 @@ static char **tableColumnList(DState *p, const char *zTab){ rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); sqlite3_free(zSql); if( rc ) return 0; - azCol[0] = 0; while( sqlite3_step(pStmt)==SQLITE_ROW ){ if( nCol>=nAlloc-2 ){ char **azNew; @@ -232,6 +231,7 @@ static char **tableColumnList(DState *p, const char *zTab){ azNew = sqlite3_realloc(azCol, nAlloc*sizeof(azCol[0])); if( azNew==0 ) goto col_oom; azCol = azNew; + azCol[0] = 0; } azCol[++nCol] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 1)); if( azCol[nCol]==0 ) goto col_oom; @@ -317,7 +317,7 @@ static void output_formatted(DState *p, const char *zFormat, ...){ va_list ap; char *z; va_start(ap, zFormat); - z = sqlite3_mprintf(zFormat, ap); + z = sqlite3_vmprintf(zFormat, ap); va_end(ap); p->xCallback(z, p->pArg); sqlite3_free(z); @@ -430,10 +430,13 @@ static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){ azCol = tableColumnList(p, zTable); if( azCol==0 ) return 0; + initText(&sTable); + appendText(&sTable, "INSERT INTO ", 0); + /* Always quote the table name, even if it appears to be pure ascii, ** in case it is a keyword. Ex: INSERT INTO "table" ... */ - initText(&sTable); appendText(&sTable, zTable, quoteChar(zTable)); + /* If preserving the rowid, add a column list after the table name. ** In other words: "INSERT INTO tab(rowid,a,b,c,...) VALUES(...)" ** instead of the usual "INSERT INTO tab VALUES(...)". @@ -462,7 +465,8 @@ static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){ appendText(&sSelect, ",", 0); } } - nCol = i-1; + nCol = i; + if( azCol[0]==0 ) nCol--; freeColumnList(azCol); appendText(&sSelect, " FROM ", 0); appendText(&sSelect, zTable, quoteChar(zTable)); @@ -545,7 +549,7 @@ static void output_sql_from_query( char *zSql; va_list ap; va_start(ap, zSelect); - zSql = sqlite3_mprintf(zSelect, ap); + zSql = sqlite3_vmprintf(zSelect, ap); va_end(ap); if( zSql==0 ){ p->rc = SQLITE_NOMEM; @@ -602,7 +606,7 @@ static void run_schema_dump_query( char *z; va_list ap; va_start(ap, zQuery); - z = sqlite3_mprintf(zQuery, ap); + z = sqlite3_vmprintf(zQuery, ap); va_end(ap); sqlite3_exec(p->db, z, dump_callback, p, &zErr); sqlite3_free(z); diff --git a/manifest b/manifest index dfbee1c83e..57159e7a5c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C First\sdraft\sof\sthe\scomplete\sdbdump.c\slibrary. -D 2017-03-13T21:26:41.643 +C Fixes\sto\sthe\sdump\slogic.\s\sAll\sappears\sto\sbe\sworking\sin\spreliminary\stests. +D 2017-03-13T21:49:48.351 F Makefile.in 9605f4c49eace601d5c12c85dd6e037cc613a6d823e857614ba26b42f1285db0 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 9020fa41eb91f657ae0cc44145d0a2f3af520860 @@ -211,7 +211,7 @@ F ext/misc/carray.c 40c27641010a4dc67e3690bdb7c9d36ca58b3c2d F ext/misc/closure.c 0d2a038df8fbae7f19de42e7c7d71f2e4dc88704 F ext/misc/compress.c 122faa92d25033d6c3f07c39231de074ab3d2e83 F ext/misc/csv.c 531a46cbad789fca0aa9db69a0e6c8ac9e68767d -F ext/misc/dbdump.c 819eb33f6ff788a466525557f7ea3742078853cc794b2eb0799a254dd6da81e2 +F ext/misc/dbdump.c 34174d537318027b159e3341105866c05a4149376ede59988c82280bed144e6d F ext/misc/eval.c f971962e92ebb8b0a4e6b62949463ee454d88fa2 F ext/misc/fileio.c d4171c815d6543a9edef8308aab2951413cd8d0f F ext/misc/fuzzer.c 7c64b8197bb77b7d64eff7cac7848870235d4c25 @@ -1564,7 +1564,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 74c5ace498f72d7f5495203678bedd0bc540211131a4e4db7b62115d5322a288 -R dcbc2252d3d150af6e3faa70158994bd +P 84ea4fcc52d0af02648c52989c2e69f4961071e1620382555ec59a39161a7a7d +R de364a9f85fa4899d644a897efb72e80 U drh -Z 9a73382dae2ea2eb6bda6a3d74fd54dd +Z 55e9f45d2725daddcac9a1569ce24da7 diff --git a/manifest.uuid b/manifest.uuid index 0597c414ba..db7f312b50 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -84ea4fcc52d0af02648c52989c2e69f4961071e1620382555ec59a39161a7a7d \ No newline at end of file +007b11e301d444361c8eff8734dc2fb968a64343c177ff30cec74a0cf76099e8 \ No newline at end of file From 4b34eb3bf5ad83be4ed86a4b5bef65945dfec95c Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 13 Mar 2017 22:02:01 +0000 Subject: [PATCH 1421/1484] Add dbdump.exe to the MSVC makefile. FossilOrigin-Name: 59241a50ad1d6fe9f5804b73b3467dcd407d359ccbdcb9d72f2f6d94c90c1f40 --- Makefile.msc | 4 ++++ manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/Makefile.msc b/Makefile.msc index 01307a3e92..ecaa837abb 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -2178,6 +2178,10 @@ sqlite3_analyzer.exe: sqlite3_analyzer.c $(LIBRESOBJS) $(LTLINK) $(NO_WARN) -DBUILD_sqlite -I$(TCLINCDIR) sqlite3_analyzer.c \ /link $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LTLIBS) $(TLIBS) +dbdump.exe: $(TOP)\ext\misc\dbdump.c sqlite3.c + $(LTLINK) $(NO_WARN) -DDBDUMP_STANDALONE $(TOP)\ext\misc\dbdump.c sqlite3.c \ + /link $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LTLIBS) + testloadext.lo: $(TOP)\src\test_loadext.c $(LTCOMPILE) $(NO_WARN) -c $(TOP)\src\test_loadext.c diff --git a/manifest b/manifest index 57159e7a5c..46a6ae6e2d 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -C Fixes\sto\sthe\sdump\slogic.\s\sAll\sappears\sto\sbe\sworking\sin\spreliminary\stests. -D 2017-03-13T21:49:48.351 +C Add\sdbdump.exe\sto\sthe\sMSVC\smakefile. +D 2017-03-13T22:02:01.034 F Makefile.in 9605f4c49eace601d5c12c85dd6e037cc613a6d823e857614ba26b42f1285db0 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 -F Makefile.msc 9020fa41eb91f657ae0cc44145d0a2f3af520860 +F Makefile.msc 5f1194a315c341c14870534652afd34bfa701219e5994fa0ee0bac91389fb740 F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7 F VERSION 3605fa447e4623f5ff4a6adc97b1fde9a257b8f2 F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 @@ -1564,7 +1564,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 84ea4fcc52d0af02648c52989c2e69f4961071e1620382555ec59a39161a7a7d -R de364a9f85fa4899d644a897efb72e80 +P 007b11e301d444361c8eff8734dc2fb968a64343c177ff30cec74a0cf76099e8 +R 6996c48c318cda176124bead4ce6093a U drh -Z 55e9f45d2725daddcac9a1569ce24da7 +Z a94f031011fffd33ab6cd5678ecde717 diff --git a/manifest.uuid b/manifest.uuid index db7f312b50..bf39e3c0d0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -007b11e301d444361c8eff8734dc2fb968a64343c177ff30cec74a0cf76099e8 \ No newline at end of file +59241a50ad1d6fe9f5804b73b3467dcd407d359ccbdcb9d72f2f6d94c90c1f40 \ No newline at end of file From 943d825b544efed6ff58bbfaf4b32d3c399c17d1 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Tue, 14 Mar 2017 15:27:56 +0000 Subject: [PATCH 1422/1484] Updates to the MSVC makefiles. FossilOrigin-Name: 1e4b9e7c9ee32b985c440bf3eb65bbdf28055566e66b6feba438143a3ad8dd07 --- Makefile.msc | 8 ++++---- autoconf/Makefile.msc | 1 + manifest | 17 ++++++++--------- manifest.uuid | 2 +- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/Makefile.msc b/Makefile.msc index ecaa837abb..1dfc6bc49d 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -2178,9 +2178,9 @@ sqlite3_analyzer.exe: sqlite3_analyzer.c $(LIBRESOBJS) $(LTLINK) $(NO_WARN) -DBUILD_sqlite -I$(TCLINCDIR) sqlite3_analyzer.c \ /link $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LTLIBS) $(TLIBS) -dbdump.exe: $(TOP)\ext\misc\dbdump.c sqlite3.c - $(LTLINK) $(NO_WARN) -DDBDUMP_STANDALONE $(TOP)\ext\misc\dbdump.c sqlite3.c \ - /link $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LTLIBS) +dbdump.exe: $(TOP)\ext\misc\dbdump.c $(SQLITE3C) $(SQLITE3H) + $(LTLINK) $(NO_WARN) -DDBDUMP_STANDALONE $(TOP)\ext\misc\dbdump.c $(SQLITE3C) \ + /link $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LTLIBS) testloadext.lo: $(TOP)\src\test_loadext.c $(LTCOMPILE) $(NO_WARN) -c $(TOP)\src\test_loadext.c @@ -2260,7 +2260,7 @@ clean: del /Q tclsqlite3.exe $(SQLITETCLH) $(SQLITETCLDECLSH) 2>NUL del /Q testloadext.dll 2>NUL del /Q testfixture.exe test.db 2>NUL - del /Q LogEst.exe fts3view.exe rollback-test.exe showdb.exe 2>NUL + del /Q LogEst.exe fts3view.exe rollback-test.exe showdb.exe dbdump.exe 2>NUL del /Q changeset.exe 2>NUL del /Q showjournal.exe showstat4.exe showwal.exe speedtest1.exe 2>NUL del /Q mptester.exe wordcount.exe rbu.exe srcck1.exe 2>NUL diff --git a/autoconf/Makefile.msc b/autoconf/Makefile.msc index 32ef1c5434..8c13778fc8 100644 --- a/autoconf/Makefile.msc +++ b/autoconf/Makefile.msc @@ -644,6 +644,7 @@ RCC = $(RCC) -DSQLITE_ENABLE_API_ARMOR=1 !IF $(DEBUG)>2 TCC = $(TCC) -DSQLITE_DEBUG=1 +TCC = $(TCC) -DSQLITE_ENABLE_WHERETRACE -DSQLITE_ENABLE_SELECTTRACE RCC = $(RCC) -DSQLITE_DEBUG=1 !ENDIF diff --git a/manifest b/manifest index a677fe2bf1..3813dabd09 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -C Add\sthe\sdbdump.c\sextension\sthat\simplements\sfunctionality\ssimilar\sto\sthe\n".dump"\scommand\sof\sthe\sCLI,\sthough\sin\sa\sseparate\slibrary. -D 2017-03-13T22:10:05.684 +C Updates\sto\sthe\sMSVC\smakefiles. +D 2017-03-14T15:27:56.153 F Makefile.in 9605f4c49eace601d5c12c85dd6e037cc613a6d823e857614ba26b42f1285db0 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 -F Makefile.msc 5f1194a315c341c14870534652afd34bfa701219e5994fa0ee0bac91389fb740 +F Makefile.msc 1faf9f06aadc9284c212dea7bbc7c0dea7e8337f0287c81001eff500912c790a F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7 F VERSION 3605fa447e4623f5ff4a6adc97b1fde9a257b8f2 F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 @@ -11,7 +11,7 @@ F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am 1a47d071e3d5435f8f7ebff7eb6703848bbd65d4 -F autoconf/Makefile.msc 3de603bcec5c07462801a20fd7dc1b871400af99 +F autoconf/Makefile.msc 92e3d7fd64dc5c23a23d33824ee4709aaea00a6331c4bb41a1aadcf6600a49f7 F autoconf/README.first 6c4f34fe115ff55d4e8dbfa3cecf04a0188292f7 F autoconf/README.txt 4f04b0819303aabaa35fff5f7b257fb0c1ef95f1 F autoconf/configure.ac cacf2616abf6e4a569bde2ef365c143caeec40bc @@ -1564,8 +1564,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 68f6dc7af1013f296a11db14c007cc13cc3fe56832848bfed835ed8f74dcc676 59241a50ad1d6fe9f5804b73b3467dcd407d359ccbdcb9d72f2f6d94c90c1f40 -R 6996c48c318cda176124bead4ce6093a -T +closed 59241a50ad1d6fe9f5804b73b3467dcd407d359ccbdcb9d72f2f6d94c90c1f40 -U drh -Z 2f55f00bb27f982c54090f39d62e41f0 +P 2b9980a292d7f0d995b77d9b3fb217bb2206f6d452e036ac502fa06561af4c12 +R 8e14f9dee9f474ef44485ac6e8f73fc9 +U mistachkin +Z b0310bb4b1f32ecae5a830c4ceeca98b diff --git a/manifest.uuid b/manifest.uuid index 52fbd6fac9..6341cc740e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2b9980a292d7f0d995b77d9b3fb217bb2206f6d452e036ac502fa06561af4c12 \ No newline at end of file +1e4b9e7c9ee32b985c440bf3eb65bbdf28055566e66b6feba438143a3ad8dd07 \ No newline at end of file From 9c4527e57d7f6a0cd2b108ea6fd1fdc5f3e851c1 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 15 Mar 2017 13:47:39 +0000 Subject: [PATCH 1423/1484] Improved header comment on the shathree.c extension. No changes to code. FossilOrigin-Name: 84f2e3d5f611b35de16684956d842df6c93d858e8187f17eb27452758a752c57 --- ext/misc/shathree.c | 4 ++++ manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/ext/misc/shathree.c b/ext/misc/shathree.c index 52bfdb0363..612e395ccb 100644 --- a/ext/misc/shathree.c +++ b/ext/misc/shathree.c @@ -21,6 +21,10 @@ ** ** The sha3_query(Y) function evalutes all queries in the SQL statements of Y ** and returns a hash of their results. +** +** The SIZE argument is optional. If omitted, the SHA3-256 hash algorithm +** is used. If SIZE is included it must be one of the integers 224, 256, +** 384, or 512, to determine SHA3 hash variant that is computed. */ #include "sqlite3ext.h" SQLITE_EXTENSION_INIT1 diff --git a/manifest b/manifest index 3813dabd09..ef98d84342 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Updates\sto\sthe\sMSVC\smakefiles. -D 2017-03-14T15:27:56.153 +C Improved\sheader\scomment\son\sthe\sshathree.c\sextension.\s\sNo\schanges\sto\scode. +D 2017-03-15T13:47:39.337 F Makefile.in 9605f4c49eace601d5c12c85dd6e037cc613a6d823e857614ba26b42f1285db0 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1faf9f06aadc9284c212dea7bbc7c0dea7e8337f0287c81001eff500912c790a @@ -226,7 +226,7 @@ F ext/misc/rot13.c 1ac6f95f99b575907b9b09c81a349114cf9be45a F ext/misc/scrub.c 1c5bfb8b0cd18b602fcb55755e84abf0023ac2fb F ext/misc/series.c e11e534ada797d5b816d7e7a93c022306563ca35 F ext/misc/sha1.c 0b9e9b855354910d3ca467bf39099d570e73db56 -F ext/misc/shathree.c 38aa4c3c3d3c3fc34b8ea367bed299d8d8a224b2 +F ext/misc/shathree.c fa185d7aee0ad0aca5e091b4a2db7baff11796170e5793b5de99e511a13af448 F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52 F ext/misc/spellfix.c a4723b6aff748a417b5091b68a46443265c40f0d F ext/misc/totype.c 4a167594e791abeed95e0a8db028822b5e8fe512 @@ -1564,7 +1564,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 2b9980a292d7f0d995b77d9b3fb217bb2206f6d452e036ac502fa06561af4c12 -R 8e14f9dee9f474ef44485ac6e8f73fc9 -U mistachkin -Z b0310bb4b1f32ecae5a830c4ceeca98b +P 1e4b9e7c9ee32b985c440bf3eb65bbdf28055566e66b6feba438143a3ad8dd07 +R 54add779c916bea2d103fd3d0493702d +U drh +Z 250a0bd95a8a1e19df805d19a289213d diff --git a/manifest.uuid b/manifest.uuid index 6341cc740e..a77693e8fa 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1e4b9e7c9ee32b985c440bf3eb65bbdf28055566e66b6feba438143a3ad8dd07 \ No newline at end of file +84f2e3d5f611b35de16684956d842df6c93d858e8187f17eb27452758a752c57 \ No newline at end of file From 7553c82894a86bcd0cdc6a1e8a3e334f5a761394 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 15 Mar 2017 14:04:03 +0000 Subject: [PATCH 1424/1484] Make "PRAGMA temp.synchronous=N" a no-op to ensure that the TEMP schema always has synchronous=OFF. This fixes an issue discovered by OSS-Fuzz. FossilOrigin-Name: bcf6bb08d8b07d3c4567bcd367f8d4011ce8baad28c25d4e8870bdf347dd48bd --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/pragma.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index ef98d84342..9b3d61974d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improved\sheader\scomment\son\sthe\sshathree.c\sextension.\s\sNo\schanges\sto\scode. -D 2017-03-15T13:47:39.337 +C Make\s"PRAGMA\stemp.synchronous=N"\sa\sno-op\sto\sensure\sthat\sthe\sTEMP\sschema\nalways\shas\ssynchronous=OFF.\s\sThis\sfixes\san\sissue\sdiscovered\sby\sOSS-Fuzz. +D 2017-03-15T14:04:03.559 F Makefile.in 9605f4c49eace601d5c12c85dd6e037cc613a6d823e857614ba26b42f1285db0 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1faf9f06aadc9284c212dea7bbc7c0dea7e8337f0287c81001eff500912c790a @@ -392,7 +392,7 @@ F src/parse.y 48b03113704ee8bd78ee6996d81de7fbee22e105 F src/pcache.c 62835bed959e2914edd26afadfecce29ece0e870 F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 F src/pcache1.c e3967219b2a92b9edcb9324a4ba75009090d3953 -F src/pragma.c b7bf4f1dd9cdcdd3f72f0bdbce3502d69d0f48ba +F src/pragma.c bfaa7e5cbfc8eacaa0f3611d5ec2dca1339d6d301f1e9b429b49ca460d794a60 F src/pragma.h c9c763958fec92b04125571472c9500b351c5f7f F src/prepare.c b1140c3d0cf59bc85ace00ce363153041b424b7a F src/printf.c 67427bbee66d891fc6f6f5aada857e9cdb368c1c @@ -1564,7 +1564,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 1e4b9e7c9ee32b985c440bf3eb65bbdf28055566e66b6feba438143a3ad8dd07 -R 54add779c916bea2d103fd3d0493702d +P 84f2e3d5f611b35de16684956d842df6c93d858e8187f17eb27452758a752c57 +R 6e100ddef7b1acc3bf828911d35ed937 U drh -Z 250a0bd95a8a1e19df805d19a289213d +Z 66f9c74ac924ecc8772889a54467a4f5 diff --git a/manifest.uuid b/manifest.uuid index a77693e8fa..b6378adfd0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -84f2e3d5f611b35de16684956d842df6c93d858e8187f17eb27452758a752c57 \ No newline at end of file +bcf6bb08d8b07d3c4567bcd367f8d4011ce8baad28c25d4e8870bdf347dd48bd \ No newline at end of file diff --git a/src/pragma.c b/src/pragma.c index 2901f4bdc5..488a1d194c 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -1015,7 +1015,7 @@ void sqlite3Pragma( if( !db->autoCommit ){ sqlite3ErrorMsg(pParse, "Safety level may not be changed inside a transaction"); - }else{ + }else if( iDb!=1 ){ int iLevel = (getSafetyLevel(zRight,0,1)+1) & PAGER_SYNCHRONOUS_MASK; if( iLevel==0 ) iLevel = 1; pDb->safety_level = iLevel; From a5d75ba9ead98c7721014019f5ff33a20dbbdfbb Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 15 Mar 2017 14:20:34 +0000 Subject: [PATCH 1425/1484] Mention the ".selftest" command in the ".help" output of the CLI. FossilOrigin-Name: 37f766dbad1f99ff86dd1b771bf443036e928e5b4d8abe55bbe4acf3362c7be2 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/shell.c | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 9b3d61974d..3d90b0cede 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\s"PRAGMA\stemp.synchronous=N"\sa\sno-op\sto\sensure\sthat\sthe\sTEMP\sschema\nalways\shas\ssynchronous=OFF.\s\sThis\sfixes\san\sissue\sdiscovered\sby\sOSS-Fuzz. -D 2017-03-15T14:04:03.559 +C Mention\sthe\s".selftest"\scommand\sin\sthe\s".help"\soutput\sof\sthe\sCLI. +D 2017-03-15T14:20:34.151 F Makefile.in 9605f4c49eace601d5c12c85dd6e037cc613a6d823e857614ba26b42f1285db0 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1faf9f06aadc9284c212dea7bbc7c0dea7e8337f0287c81001eff500912c790a @@ -400,7 +400,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 3e518b962d932a997fae373366880fc028c75706 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c 2496d0cc6368dabe7ad2e4c7f5ed3ad9aa3b4d11cd90f33fa1d1ef72493f43aa -F src/shell.c 353f3cebb938099577494326e2853010512e0625 +F src/shell.c 77054c021069ec0b65d3d620aab031f97c59b4e42ac7c31544ea68933b581104 F src/sqlite.h.in 4d0c08f8640c586564a7032b259c5f69bf397850 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae @@ -1564,7 +1564,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 84f2e3d5f611b35de16684956d842df6c93d858e8187f17eb27452758a752c57 -R 6e100ddef7b1acc3bf828911d35ed937 +P bcf6bb08d8b07d3c4567bcd367f8d4011ce8baad28c25d4e8870bdf347dd48bd +R 3a48c86458783a20973121829bd123da U drh -Z 66f9c74ac924ecc8772889a54467a4f5 +Z 148bc384ce73e7778d1614d5fa3b82a8 diff --git a/manifest.uuid b/manifest.uuid index b6378adfd0..3ea504fab7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bcf6bb08d8b07d3c4567bcd367f8d4011ce8baad28c25d4e8870bdf347dd48bd \ No newline at end of file +37f766dbad1f99ff86dd1b771bf443036e928e5b4d8abe55bbe4acf3362c7be2 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 602415f8c9..e7652f8e67 100644 --- a/src/shell.c +++ b/src/shell.c @@ -3169,6 +3169,7 @@ static char zHelp[] = ".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off\n" ".schema ?PATTERN? Show the CREATE statements matching PATTERN\n" " Add --indent for pretty-printing\n" + ".selftest ?--init? Run tests defined in the SELFTEST table\n" ".separator COL ?ROW? Change the column separator and optionally the row\n" " separator for both the output mode and .import\n" #if defined(SQLITE_ENABLE_SESSION) From 6295ff1d3eecfc746632b54b543771b97c6e2bab Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 15 Mar 2017 19:11:29 +0000 Subject: [PATCH 1426/1484] Add the "Obtaining The Code" subsection in the top-level README.md file. No changes to code. FossilOrigin-Name: b1b1aa8b69aa80c83aec3380565f0b4ec0b6a6e033537becee098872da362e9a --- README.md | 70 ++++++++++++++++++++++++++++++++++++++++----------- manifest | 12 ++++----- manifest.uuid | 2 +- 3 files changed, 63 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index dbc020574e..7b860c211e 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,48 @@ If you are reading this on a Git mirror someplace, you are doing it wrong. The [official repository](https://www.sqlite.org/src/) is better. Go there now. +## Obtaining The Code + +SQLite sources are managed using the +[Fossil](https://www.fossil-scm.org/), a distributed version control system +that was specifically designed to support SQLite development. +If you do not want to use Fossil, you can download tarballs or ZIP +archives as follows: + + * Lastest trunk check-in: + or + . + + * Latest release: + or + . + + * For other check-ins, substitute an appropriate branch name or + tag or hash prefix for "release" in the URLs of the previous + bullet. Or browse the [timeline](https://www.sqlite.org/src/timeline) + to locate the check-in desired, click on its information page link, + then click on the "Tarball" or "ZIP Archive" links on the information + page. + +If you do want to use Fossil to check out the source tree, +first install Fossil version 2.0 or later. +(Source tarballs and precompiled binaries available +[here](https://www.fossil-scm.org/fossil/uv/download.html).) +Then run commands like this: + + mkdir ~/sqlite + cd ~/sqlite + fossil clone https://www.sqlite.org/src sqlite.fossil + fossil open sqlite.fossil + +After setting up a repository using the steps above, you can always +update to the lastest version using: + + fossil update trunk ;# latest trunk check-in + fossil update release ;# latest official release + +Or type "fossil ui" to get a web-based user interface. + ## Compiling First create a directory in which to place @@ -18,13 +60,13 @@ script found at the root of the source tree. Then run "make". For example: - tar xzf sqlite.tar.gz ;# Unpack the source tree into "sqlite" - mkdir bld ;# Build will occur in a sibling directory - cd bld ;# Change to the build directory - ../sqlite/configure ;# Run the configure script - make ;# Run the makefile. - make sqlite3.c ;# Build the "amalgamation" source file - make test ;# Run some tests (requires Tcl) + tar xzf sqlite.tar.gz ;# Unpack the source tree into "sqlite" + mkdir bld ;# Build will occur in a sibling directory + cd bld ;# Change to the build directory + ../sqlite/configure ;# Run the configure script + make ;# Run the makefile. + make sqlite3.c ;# Build the "amalgamation" source file + make test ;# Run some tests (requires Tcl) See the makefile for additional targets. @@ -43,13 +85,13 @@ with the provided "Makefile.msc" to build one of the supported targets. For example: - mkdir bld - cd bld - nmake /f Makefile.msc TOP=..\sqlite - nmake /f Makefile.msc sqlite3.c TOP=..\sqlite - nmake /f Makefile.msc sqlite3.dll TOP=..\sqlite - nmake /f Makefile.msc sqlite3.exe TOP=..\sqlite - nmake /f Makefile.msc test TOP=..\sqlite + mkdir bld + cd bld + nmake /f Makefile.msc TOP=..\sqlite + nmake /f Makefile.msc sqlite3.c TOP=..\sqlite + nmake /f Makefile.msc sqlite3.dll TOP=..\sqlite + nmake /f Makefile.msc sqlite3.exe TOP=..\sqlite + nmake /f Makefile.msc test TOP=..\sqlite There are several build options that can be set via the NMAKE command line. For example, to build for WinRT, simply add "FOR_WINRT=1" argument diff --git a/manifest b/manifest index 3d90b0cede..7ebd38a5c1 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Mention\sthe\s".selftest"\scommand\sin\sthe\s".help"\soutput\sof\sthe\sCLI. -D 2017-03-15T14:20:34.151 +C Add\sthe\s"Obtaining\sThe\sCode"\ssubsection\sin\sthe\stop-level\sREADME.md\sfile.\nNo\schanges\sto\scode. +D 2017-03-15T19:11:29.617 F Makefile.in 9605f4c49eace601d5c12c85dd6e037cc613a6d823e857614ba26b42f1285db0 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1faf9f06aadc9284c212dea7bbc7c0dea7e8337f0287c81001eff500912c790a -F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7 +F README.md 2b15fae33852f2f53996774c21fb41e1d94181c4401a0e43ac93e11f2cc901b9 F VERSION 3605fa447e4623f5ff4a6adc97b1fde9a257b8f2 F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 @@ -1564,7 +1564,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P bcf6bb08d8b07d3c4567bcd367f8d4011ce8baad28c25d4e8870bdf347dd48bd -R 3a48c86458783a20973121829bd123da +P 37f766dbad1f99ff86dd1b771bf443036e928e5b4d8abe55bbe4acf3362c7be2 +R 2482a0aa4c5093969a8d8859e4856dc3 U drh -Z 148bc384ce73e7778d1614d5fa3b82a8 +Z 10bbbdac78940d7fca566277c18da714 diff --git a/manifest.uuid b/manifest.uuid index 3ea504fab7..72a98aae6c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -37f766dbad1f99ff86dd1b771bf443036e928e5b4d8abe55bbe4acf3362c7be2 \ No newline at end of file +b1b1aa8b69aa80c83aec3380565f0b4ec0b6a6e033537becee098872da362e9a \ No newline at end of file From 6f25936c9c12c93a95aad4277964a82b2f18b07a Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 15 Mar 2017 20:27:46 +0000 Subject: [PATCH 1427/1484] Updates to README files under the ext/ hierarchy. No changes to code. FossilOrigin-Name: 029bc5d224bcbdcca2307710539b133c39e2a27b971c28b294a1f517b80cb418 --- ext/README.md | 8 ++++++++ ext/README.txt | 2 -- ext/misc/README.md | 40 ++++++++++++++++++++++++++++++++++++++++ manifest | 13 +++++++------ manifest.uuid | 2 +- 5 files changed, 56 insertions(+), 9 deletions(-) create mode 100644 ext/README.md delete mode 100644 ext/README.txt create mode 100644 ext/misc/README.md diff --git a/ext/README.md b/ext/README.md new file mode 100644 index 0000000000..933a33d053 --- /dev/null +++ b/ext/README.md @@ -0,0 +1,8 @@ +## Loadable Extensions + +Various [loadable extensions](https://www.sqlite.org/loadext.html) for +SQLite are found in subfolders. + +Most subfolders are dedicated to a single loadable extension (for +example FTS5, or RTREE). But the misc/ subfolder contains a collection +of smaller single-file extensions. diff --git a/ext/README.txt b/ext/README.txt deleted file mode 100644 index 009495f59d..0000000000 --- a/ext/README.txt +++ /dev/null @@ -1,2 +0,0 @@ -Version loadable extensions to SQLite are found in subfolders -of this folder. diff --git a/ext/misc/README.md b/ext/misc/README.md new file mode 100644 index 0000000000..970a09c2e9 --- /dev/null +++ b/ext/misc/README.md @@ -0,0 +1,40 @@ +## Miscellaneous Extensions + +This folder contains a collection of smaller loadable extensions. +See for instructions on how +to compile and use loadable extensions. +Each extension in this folder is implemented in a single file of C code. + +Each source file contains a description in its header comment. See the +header comments for details about each extension. Additional notes are +as follows: + + * **carray.c** — This module implements the + [carray](https://www.sqlite.org/carray.html) table-valued function. + It is a good example of how to go about implementing a custom + [table-valued function](https://www.sqlite.org/vtab.html#tabfunc2). + + * **dbdump.c** — This is not actually a loadable extension, but + rather a library that implements an approximate equivalent to the + ".dump" command of the + [command-line shell](https://www.sqlite.org/cli.html). + + * **memvfs.c** — This file implements a custom + [VFS](https://www.sqlite.org/vfs.html) that stores an entire database + file in a single block of RAM. It serves as a good example of how + to implement a simple custom VFS. + + * **rot13.c** — This file implements the very simple rot13() + substitution function. This file makes a good template for implementing + new custom SQL functions for SQLite. + + * **series.c** — This is an implementation of the + "generate_series" [virtual table](https://www.sqlite.org/vtab.html). + It can make a good template for new custom virtual table implementations. + + * **shathree.c** — An implementation of the sha3() and + sha3_query() SQL functions. The file is named "shathree.c" instead + of "sha3.c" because the default entry point names in SQLite are based + on the source filename with digits removed, so if we used the name + "sha3.c" then the entry point would conflict with the prior "sha1.c" + extension. diff --git a/manifest b/manifest index 7ebd38a5c1..83da720fa0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\s"Obtaining\sThe\sCode"\ssubsection\sin\sthe\stop-level\sREADME.md\sfile.\nNo\schanges\sto\scode. -D 2017-03-15T19:11:29.617 +C Updates\sto\sREADME\sfiles\sunder\sthe\sext/\shierarchy.\s\sNo\schanges\sto\scode. +D 2017-03-15T20:27:46.132 F Makefile.in 9605f4c49eace601d5c12c85dd6e037cc613a6d823e857614ba26b42f1285db0 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1faf9f06aadc9284c212dea7bbc7c0dea7e8337f0287c81001eff500912c790a @@ -36,7 +36,7 @@ F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad F doc/lemon.html b5a3c07d33ecb8e019ce8f7660fe2dbbad9d7977 F doc/pager-invariants.txt 27fed9a70ddad2088750c4a2b493b63853da2710 F doc/vfs-shm.txt e101f27ea02a8387ce46a05be2b1a902a021d37a -F ext/README.txt 913a7bd3f4837ab14d7e063304181787658b14e1 +F ext/README.md fd5f78013b0a2bc6f0067afb19e6ad040e89a10179b4f6f03eee58fac5f169bd w ext/README.txt F ext/async/README.txt e12275968f6fde133a80e04387d0e839b0c51f91 F ext/async/sqlite3async.c 0f3070cc3f5ede78f2b9361fb3b629ce200d7d74 F ext/async/sqlite3async.h f489b080af7e72aec0e1ee6f1d98ab6cf2e4dcef @@ -206,6 +206,7 @@ F ext/fts5/tool/showfts5.tcl d54da0e067306663e2d5d523965ca487698e722c F ext/icu/README.txt d9fbbad0c2f647c3fdf715fc9fd64af53aedfc43 F ext/icu/icu.c 84900472a088a3a172c6c079f58a1d3a1952c332 F ext/icu/sqliteicu.h 728867a802baa5a96de7495e9689a8e01715ef37 +F ext/misc/README.md 8e008c8d2b02e09096b31dfba033253ac27c6c06a18aa5826e299fa7601d90b2 F ext/misc/amatch.c 211108e201105e4bb0c076527b8cfd34330fc234 F ext/misc/carray.c 40c27641010a4dc67e3690bdb7c9d36ca58b3c2d F ext/misc/closure.c 0d2a038df8fbae7f19de42e7c7d71f2e4dc88704 @@ -1564,7 +1565,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 37f766dbad1f99ff86dd1b771bf443036e928e5b4d8abe55bbe4acf3362c7be2 -R 2482a0aa4c5093969a8d8859e4856dc3 +P b1b1aa8b69aa80c83aec3380565f0b4ec0b6a6e033537becee098872da362e9a +R ed52dc66e6f47f5c1fac043513c8c66c U drh -Z 10bbbdac78940d7fca566277c18da714 +Z 7b77c481896e5fef2abe165dd1f4d320 diff --git a/manifest.uuid b/manifest.uuid index 72a98aae6c..b973ec5b0b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b1b1aa8b69aa80c83aec3380565f0b4ec0b6a6e033537becee098872da362e9a \ No newline at end of file +029bc5d224bcbdcca2307710539b133c39e2a27b971c28b294a1f517b80cb418 \ No newline at end of file From 116b56a2ccb5671bd6ff668ad3aec104d8b4b9a9 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 16 Mar 2017 12:11:07 +0000 Subject: [PATCH 1428/1484] Fix a crash that could follow an OOM condition in the instr() SQL function. FossilOrigin-Name: 6e59e903e4e956617bddef0b94e5cae02d724ac8145940b57ab5b0f628759736 --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/func.c | 6 ++++-- test/mallocM.test | 18 +++++++++++++++++- 4 files changed, 31 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 83da720fa0..e9aad067d4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Updates\sto\sREADME\sfiles\sunder\sthe\sext/\shierarchy.\s\sNo\schanges\sto\scode. -D 2017-03-15T20:27:46.132 +C Fix\sa\scrash\sthat\scould\sfollow\san\sOOM\scondition\sin\sthe\sinstr()\sSQL\sfunction. +D 2017-03-16T12:11:07.597 F Makefile.in 9605f4c49eace601d5c12c85dd6e037cc613a6d823e857614ba26b42f1285db0 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1faf9f06aadc9284c212dea7bbc7c0dea7e8337f0287c81001eff500912c790a @@ -36,7 +36,7 @@ F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad F doc/lemon.html b5a3c07d33ecb8e019ce8f7660fe2dbbad9d7977 F doc/pager-invariants.txt 27fed9a70ddad2088750c4a2b493b63853da2710 F doc/vfs-shm.txt e101f27ea02a8387ce46a05be2b1a902a021d37a -F ext/README.md fd5f78013b0a2bc6f0067afb19e6ad040e89a10179b4f6f03eee58fac5f169bd w ext/README.txt +F ext/README.md fd5f78013b0a2bc6f0067afb19e6ad040e89a10179b4f6f03eee58fac5f169bd F ext/async/README.txt e12275968f6fde133a80e04387d0e839b0c51f91 F ext/async/sqlite3async.c 0f3070cc3f5ede78f2b9361fb3b629ce200d7d74 F ext/async/sqlite3async.h f489b080af7e72aec0e1ee6f1d98ab6cf2e4dcef @@ -356,7 +356,7 @@ F src/delete.c 0d9d5549d42e79ce4d82ff1db1e6c81e36d2f67c F src/expr.c f12a581f342a6fd85d14c31e4fb84f16b3dd107f54d7728dddb62cebc79d7ce1 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 2e9aabe1aee76273aff8a84ee92c464e095400ae -F src/func.c c67273e1ec08abbdcc14c189892a3ff6eeece86b +F src/func.c 72ed1518f59951daca3b3480331006f074041b4753ab652b46bbdaedb77f6d6c F src/global.c 4a34512d82fc5aa13c802db06bcfff5e1d3de955 F src/hash.c 63d0ee752a3b92d4695b2b1f5259c4621b2cfebd F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4 @@ -955,7 +955,7 @@ F test/mallocI.test 6c23a71df077fa5d387be90e7e669c5b368ca38a F test/mallocJ.test b5d1839da331d96223e5f458856f8ffe1366f62e F test/mallocK.test 27cb5566a6e5f2d76f9d4aa2eca45524401fd61e F test/mallocL.test fb311ff80afddf3b1a75e52289081f4754d901dc -F test/mallocM.test 491001d1e273233048d265ec6d38fdd23745b0284f0c93bc98c94b64451c9c28 +F test/mallocM.test 78bbe9d3da84a5c679123cdb40d7b2010b18fc46e13897e4f253c6ba6fbff134 F test/malloc_common.tcl aac62499b76be719fac31e7a3e54a7fd53272e7f F test/manydb.test 28385ae2087967aa05c38624cec7d96ec74feb3e F test/mem5.test c6460fba403c5703141348cd90de1c294188c68f @@ -1565,7 +1565,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b1b1aa8b69aa80c83aec3380565f0b4ec0b6a6e033537becee098872da362e9a -R ed52dc66e6f47f5c1fac043513c8c66c -U drh -Z 7b77c481896e5fef2abe165dd1f4d320 +P 029bc5d224bcbdcca2307710539b133c39e2a27b971c28b294a1f517b80cb418 +R e125f692ae2203427c312740eb052007 +U dan +Z 43eef8b6f1a791e34b2b986222f188cc diff --git a/manifest.uuid b/manifest.uuid index b973ec5b0b..808a7701e3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -029bc5d224bcbdcca2307710539b133c39e2a27b971c28b294a1f517b80cb418 \ No newline at end of file +6e59e903e4e956617bddef0b94e5cae02d724ac8145940b57ab5b0f628759736 \ No newline at end of file diff --git a/src/func.c b/src/func.c index 885725bc6b..181032a5e3 100644 --- a/src/func.c +++ b/src/func.c @@ -204,9 +204,11 @@ static void instrFunc( if( typeHaystack==SQLITE_BLOB && typeNeedle==SQLITE_BLOB ){ zHaystack = sqlite3_value_blob(argv[0]); zNeedle = sqlite3_value_blob(argv[1]); - assert( zNeedle!=0 ); - assert( zHaystack!=0 || nHaystack==0 ); isText = 0; + /* The following condition may be true if the arguments passed to this + ** function are values returned by zeroblob() or similar and an OOM + ** occurs while expanding the blob value. */ + if( zNeedle==0 || (nHaystack && zHaystack==0) ) return; }else{ zHaystack = sqlite3_value_text(argv[0]); zNeedle = sqlite3_value_text(argv[1]); diff --git a/test/mallocM.test b/test/mallocM.test index 85a38acf32..4da3a9e112 100644 --- a/test/mallocM.test +++ b/test/mallocM.test @@ -21,7 +21,7 @@ sqlite3_db_config_lookaside db 0 0 0 do_execsql_test 1.0 { CREATE TABLE t1(x); } -do_faultsim_test 1 -faults oom-t* -body { +do_faultsim_test 1 -faults oom* -body { execsql { SELECT 'abc' FROM ( SELECT 'xyz' FROM t1 WHERE (SELECT 1) ) } @@ -29,4 +29,20 @@ do_faultsim_test 1 -faults oom-t* -body { faultsim_test_result {0 {}} } +do_execsql_test 2.0.1 { SELECT instr(x'', x'') } {1} +do_execsql_test 2.0.2 { SELECT instr(x'12345678', x'') } {1} +do_execsql_test 2.0.3 { SELECT instr(x'', x'1234') } {0} + +do_faultsim_test 2.1 -faults oom* -body { + execsql { SELECT instr (x'00', zeroblob(1)) } +} -test { + faultsim_test_result {0 1} +} + +do_faultsim_test 2.2 -faults oom* -body { + execsql { SELECT instr (zeroblob(1), x'00') } +} -test { + faultsim_test_result {0 1} +} + finish_test From 970ea372c41bf3fda4891740d74130a490809288 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 16 Mar 2017 13:14:03 +0000 Subject: [PATCH 1429/1484] Fix a problem in the "showdb" utility that prevents it from correctly decoding cells with no content beyond the record header. FossilOrigin-Name: eb7680a1c047b2a33d6a0c9733fafaee11272377c627af10bbd541b6b7ed952b --- manifest | 14 +++++++------- manifest.uuid | 2 +- tool/showdb.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index e9aad067d4..e0d90caf8e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\scrash\sthat\scould\sfollow\san\sOOM\scondition\sin\sthe\sinstr()\sSQL\sfunction. -D 2017-03-16T12:11:07.597 +C Fix\sa\sproblem\sin\sthe\s"showdb"\sutility\sthat\sprevents\sit\sfrom\scorrectly\ndecoding\scells\swith\sno\scontent\sbeyond\sthe\srecord\sheader. +D 2017-03-16T13:14:03.665 F Makefile.in 9605f4c49eace601d5c12c85dd6e037cc613a6d823e857614ba26b42f1285db0 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1faf9f06aadc9284c212dea7bbc7c0dea7e8337f0287c81001eff500912c790a @@ -1518,7 +1518,7 @@ F tool/replace.tcl 60f91e8dd06ab81f74d213ecbd9c9945f32ac048 F tool/restore_jrnl.tcl 6957a34f8f1f0f8285e07536225ec3b292a9024a F tool/rollback-test.c 9fc98427d1e23e84429d7e6d07d9094fbdec65a5 F tool/run-speed-test.sh f95d19fd669b68c4c38b6b475242841d47c66076 -F tool/showdb.c c695a5d5c8110640e0d9fadf5e254da90c79c36e +F tool/showdb.c e6bc9dba233bf1b57ca0a525a2bba762db4e223de84990739db3f09c46151b1e F tool/showjournal.c 5bad7ae8784a43d2b270d953060423b8bd480818 F tool/showlocks.c 9920bcc64f58378ff1118caead34147201f48c68 F tool/showstat4.c b14159aa062f661b394ba37b6b7b94bfb8012ab9 @@ -1565,7 +1565,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 029bc5d224bcbdcca2307710539b133c39e2a27b971c28b294a1f517b80cb418 -R e125f692ae2203427c312740eb052007 -U dan -Z 43eef8b6f1a791e34b2b986222f188cc +P 6e59e903e4e956617bddef0b94e5cae02d724ac8145940b57ab5b0f628759736 +R e2b1419a7c2797d673769ba867cc93d0 +U drh +Z 979d31964af3fe7c6823fdbe1eb4300f diff --git a/manifest.uuid b/manifest.uuid index 808a7701e3..8782dfa202 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6e59e903e4e956617bddef0b94e5cae02d724ac8145940b57ab5b0f628759736 \ No newline at end of file +eb7680a1c047b2a33d6a0c9733fafaee11272377c627af10bbd541b6b7ed952b \ No newline at end of file diff --git a/tool/showdb.c b/tool/showdb.c index d51a2fd83d..ba7a362258 100644 --- a/tool/showdb.c +++ b/tool/showdb.c @@ -535,7 +535,7 @@ static void decodeCell( j = i; nCol = 0; k = nHdr; - while( x+j Date: Thu, 16 Mar 2017 13:30:58 +0000 Subject: [PATCH 1430/1484] Fix an uninitialized variable reference in the text generator for "PRAGMA vdbe_trace=ON" output. Problem discovered by OSS-Fuzz. FossilOrigin-Name: e3d487162d1596ce125644f754ed9531ef4412f31f6837c3e31b7542b90602fe --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 8 ++------ 3 files changed, 9 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index e0d90caf8e..94d43a58ec 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\sin\sthe\s"showdb"\sutility\sthat\sprevents\sit\sfrom\scorrectly\ndecoding\scells\swith\sno\scontent\sbeyond\sthe\srecord\sheader. -D 2017-03-16T13:14:03.665 +C Fix\san\suninitialized\svariable\sreference\sin\sthe\stext\sgenerator\s\nfor\s"PRAGMA\svdbe_trace=ON"\soutput.\nProblem\sdiscovered\sby\sOSS-Fuzz. +D 2017-03-16T13:30:58.522 F Makefile.in 9605f4c49eace601d5c12c85dd6e037cc613a6d823e857614ba26b42f1285db0 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1faf9f06aadc9284c212dea7bbc7c0dea7e8337f0287c81001eff500912c790a @@ -467,7 +467,7 @@ F src/update.c 456d4a4656f8a03c2abc88a51b19172197400e58 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c ca8440ede81e155d15cff7c101654f60b55a9ae6 F src/vacuum.c 1fe4555cd8c9b263afb85b5b4ee3a4a4181ad569 -F src/vdbe.c f520378e510fd36bbf289921798dbc8f2b3dc30d +F src/vdbe.c 0e6e5e01aaa57f6d1784b7d6b6a352153e9d2c2ff395c67ca59aef54b8268cf6 F src/vdbe.h 59998ffd71d7caa8886bc78dafaf8caeccd4c13c F src/vdbeInt.h 4e4b15b2e1330e1636e4e01974eab2b0b985092f F src/vdbeapi.c 5b08d82592bcff4470601fe78aaabebd50837860 @@ -1565,7 +1565,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 6e59e903e4e956617bddef0b94e5cae02d724ac8145940b57ab5b0f628759736 -R e2b1419a7c2797d673769ba867cc93d0 +P eb7680a1c047b2a33d6a0c9733fafaee11272377c627af10bbd541b6b7ed952b +R 698ee80038f5639a9fb93e688b92867d U drh -Z 979d31964af3fe7c6823fdbe1eb4300f +Z 1c91cacf813bcc1311ca42c9e29c59cd diff --git a/manifest.uuid b/manifest.uuid index 8782dfa202..5411cb37d9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -eb7680a1c047b2a33d6a0c9733fafaee11272377c627af10bbd541b6b7ed952b \ No newline at end of file +e3d487162d1596ce125644f754ed9531ef4412f31f6837c3e31b7542b90602fe \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 5901ba0eb5..20bf09e3a4 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -403,9 +403,7 @@ void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf){ }else{ c = 's'; } - - sqlite3_snprintf(100, zCsr, "%c", c); - zCsr += sqlite3Strlen30(zCsr); + *(zCsr++) = c; sqlite3_snprintf(100, zCsr, "%d[", pMem->n); zCsr += sqlite3Strlen30(zCsr); for(i=0; i<16 && in; i++){ @@ -417,9 +415,7 @@ void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf){ if( z<32 || z>126 ) *zCsr++ = '.'; else *zCsr++ = z; } - - sqlite3_snprintf(100, zCsr, "]%s", encnames[pMem->enc]); - zCsr += sqlite3Strlen30(zCsr); + *(zCsr++) = ']'; if( f & MEM_Zero ){ sqlite3_snprintf(100, zCsr,"+%dz",pMem->u.nZero); zCsr += sqlite3Strlen30(zCsr); From b30574bcae87dd4efe6de37d47a215e112824fe2 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 16 Mar 2017 14:28:52 +0000 Subject: [PATCH 1431/1484] Simplified OOM detection in the instr() SQL function. FossilOrigin-Name: 6d85eb5736781b43aa674d9544c7523b849b4e634f371702f8764b33e22e1e9f --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/func.c | 6 +----- 3 files changed, 8 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 94d43a58ec..7d0466ed61 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\suninitialized\svariable\sreference\sin\sthe\stext\sgenerator\s\nfor\s"PRAGMA\svdbe_trace=ON"\soutput.\nProblem\sdiscovered\sby\sOSS-Fuzz. -D 2017-03-16T13:30:58.522 +C Simplified\sOOM\sdetection\sin\sthe\sinstr()\sSQL\sfunction. +D 2017-03-16T14:28:52.423 F Makefile.in 9605f4c49eace601d5c12c85dd6e037cc613a6d823e857614ba26b42f1285db0 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1faf9f06aadc9284c212dea7bbc7c0dea7e8337f0287c81001eff500912c790a @@ -356,7 +356,7 @@ F src/delete.c 0d9d5549d42e79ce4d82ff1db1e6c81e36d2f67c F src/expr.c f12a581f342a6fd85d14c31e4fb84f16b3dd107f54d7728dddb62cebc79d7ce1 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 2e9aabe1aee76273aff8a84ee92c464e095400ae -F src/func.c 72ed1518f59951daca3b3480331006f074041b4753ab652b46bbdaedb77f6d6c +F src/func.c 9d52522cc8ae7f5cdadfe14594262f1618bc1f86083c4cd6da861b4cf5af6174 F src/global.c 4a34512d82fc5aa13c802db06bcfff5e1d3de955 F src/hash.c 63d0ee752a3b92d4695b2b1f5259c4621b2cfebd F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4 @@ -1565,7 +1565,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P eb7680a1c047b2a33d6a0c9733fafaee11272377c627af10bbd541b6b7ed952b -R 698ee80038f5639a9fb93e688b92867d +P e3d487162d1596ce125644f754ed9531ef4412f31f6837c3e31b7542b90602fe +R 6130240157d02268edef1462c36002d9 U drh -Z 1c91cacf813bcc1311ca42c9e29c59cd +Z 5ff31e1a870d72447c943f18c5a0c832 diff --git a/manifest.uuid b/manifest.uuid index 5411cb37d9..eee2f53d07 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e3d487162d1596ce125644f754ed9531ef4412f31f6837c3e31b7542b90602fe \ No newline at end of file +6d85eb5736781b43aa674d9544c7523b849b4e634f371702f8764b33e22e1e9f \ No newline at end of file diff --git a/src/func.c b/src/func.c index 181032a5e3..3d5a059a9f 100644 --- a/src/func.c +++ b/src/func.c @@ -205,16 +205,12 @@ static void instrFunc( zHaystack = sqlite3_value_blob(argv[0]); zNeedle = sqlite3_value_blob(argv[1]); isText = 0; - /* The following condition may be true if the arguments passed to this - ** function are values returned by zeroblob() or similar and an OOM - ** occurs while expanding the blob value. */ - if( zNeedle==0 || (nHaystack && zHaystack==0) ) return; }else{ zHaystack = sqlite3_value_text(argv[0]); zNeedle = sqlite3_value_text(argv[1]); isText = 1; - if( zHaystack==0 || zNeedle==0 ) return; } + if( zNeedle==0 || (nHaystack && zHaystack==0) ) return; while( nNeedle<=nHaystack && memcmp(zHaystack, zNeedle, nNeedle)!=0 ){ N++; do{ From f5da7dbb0773facb0a6a12e25f4139a7c5087c74 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 16 Mar 2017 18:14:39 +0000 Subject: [PATCH 1432/1484] If the user has not set it explicitly, set the "PRAGMA synchronous" setting to SQLITE_DEFAULT_SYNCHRONOUS when a database connection changes from wal to rollback journal mode. FossilOrigin-Name: 78030c0f52aa39fb2ab32c75c56e6bcefe6382b8df28b1909e3c911e42dbeca3 --- manifest | 19 +++--- manifest.uuid | 2 +- src/btree.c | 42 ++++++++----- src/ctime.c | 6 ++ src/test_config.c | 2 + test/sync2.test | 153 ++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 200 insertions(+), 24 deletions(-) create mode 100644 test/sync2.test diff --git a/manifest b/manifest index 7d0466ed61..4d61ee44cb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Simplified\sOOM\sdetection\sin\sthe\sinstr()\sSQL\sfunction. -D 2017-03-16T14:28:52.423 +C If\sthe\suser\shas\snot\sset\sit\sexplicitly,\sset\sthe\s"PRAGMA\ssynchronous"\ssetting\sto\nSQLITE_DEFAULT_SYNCHRONOUS\swhen\sa\sdatabase\sconnection\schanges\sfrom\swal\sto\nrollback\sjournal\smode. +D 2017-03-16T18:14:39.798 F Makefile.in 9605f4c49eace601d5c12c85dd6e037cc613a6d823e857614ba26b42f1285db0 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1faf9f06aadc9284c212dea7bbc7c0dea7e8337f0287c81001eff500912c790a @@ -343,13 +343,13 @@ F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792 F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca -F src/btree.c e2bae0a03f73d119910fb35c9550987564065137 +F src/btree.c ace24955d01800acec28c79b038e1c291370f48a8955e8347cbd5339e39935de F src/btree.h bf64dfeeddeebdb775a5eba0098bbc00d073290d F src/btreeInt.h cd55d39d9916270837a88c12e701047cba0729b0 F src/build.c 43f903c9082040ced2b421543cb0300c2973647d F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e -F src/ctime.c a9984df73898c042a5cfc8f9d8e7723d02bc35c9 +F src/ctime.c 47d91a25ad8f199a71a5b1b7b169d6dd0d6e98c5719eca801568798743d1161c F src/date.c ee676e7694dfadbdd2fde1a258a71be8360ba5ae F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c 0d9d5549d42e79ce4d82ff1db1e6c81e36d2f67c @@ -425,7 +425,7 @@ F src/test_backup.c bf5da90c9926df0a4b941f2d92825a01bbe090a0 F src/test_bestindex.c d23f80d334c59662af69191854c76b8d3d0c8c96 F src/test_blob.c f65ac717da2618691cf9dad094e6da0219dcd208 F src/test_btree.c 8b2dc8b8848cf3a4db93f11578f075e82252a274 -F src/test_config.c 83179ea845479b5be9a651d014649e3f2722a1fe +F src/test_config.c edcba290248dc18736dd814c9b95863c6762e0b35753048d8cbe5bf65f7abfbb F src/test_delete.c af7eab5702f853fb1c62a5f7665e2234cf1ae17b F src/test_demovfs.c a0c3bdd45ed044115c2c9f7779e56eafff18741e F src/test_devsym.c 4e58dec2602d8e139ca08659f62a62450587cb58 @@ -1165,6 +1165,7 @@ F test/subtype1.test 7fe09496352f97053af1437150751be2d0a0cae8 F test/superlock.test ec94f0556b6488d97f71c79f9061ae08d9ab8f12 F test/symlink.test c9ebe7330d228249e447038276bfc8a7b22f4849 F test/sync.test 2f84bdbc2b2df1fcb0220575b4b9f8cea94b7529 +F test/sync2.test 5ecf56be4c187a191253a1ec0786fe2df975dbf3dc0f0140cdf5d3690c90651c F test/syscall.test f59ba4e25f7ba4a4c031026cc2ef8b6e4b4c639c F test/sysfault.test c9f2b0d8d677558f74de750c75e12a5454719d04 F test/tabfunc01.test 699251cb99651415218a891384510a685c7ab012 @@ -1565,7 +1566,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e3d487162d1596ce125644f754ed9531ef4412f31f6837c3e31b7542b90602fe -R 6130240157d02268edef1462c36002d9 -U drh -Z 5ff31e1a870d72447c943f18c5a0c832 +P 6d85eb5736781b43aa674d9544c7523b849b4e634f371702f8764b33e22e1e9f +R 549202c1b901efe7d78e47bd0d1adc7f +U dan +Z 959d77178fc349b2ba7589eca45f1aa2 diff --git a/manifest.uuid b/manifest.uuid index eee2f53d07..1973398254 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6d85eb5736781b43aa674d9544c7523b849b4e634f371702f8764b33e22e1e9f \ No newline at end of file +78030c0f52aa39fb2ab32c75c56e6bcefe6382b8df28b1909e3c911e42dbeca3 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index b99cab89ec..47bb460b0c 100644 --- a/src/btree.c +++ b/src/btree.c @@ -2861,6 +2861,31 @@ int sqlite3BtreeGetAutoVacuum(Btree *p){ #endif } +/* +** If the user has not set the safety-level for this database connection +** using "PRAGMA synchronous", and if the safety-level is not already +** set to the value passed to this function as the second parameter, +** set it so. +*/ +#if SQLITE_DEFAULT_SYNCHRONOUS!=SQLITE_DEFAULT_WAL_SYNCHRONOUS +static void setDefaultSyncFlag(BtShared *pBt, u8 safety_level){ + sqlite3 *db; + Db *pDb; + if( (db=pBt->db)!=0 && (pDb=db->aDb)!=0 ){ + while( pDb->pBt==0 || pDb->pBt->pBt!=pBt ){ pDb++; } + if( pDb->bSyncSet==0 + && pDb->safety_level!=safety_level + && pDb!=&db->aDb[1] + ){ + pDb->safety_level = safety_level; + sqlite3PagerSetFlags(pBt->pPager, + pDb->safety_level | (db->flags & PAGER_FLAGS_MASK)); + } + } +} +#else +# define setDefaultSyncFlag(pBt) +#endif /* ** Get a reference to pPage1 of the database file. This will @@ -2934,26 +2959,15 @@ static int lockBtree(BtShared *pBt){ if( rc!=SQLITE_OK ){ goto page1_init_failed; }else{ -#if SQLITE_DEFAULT_SYNCHRONOUS!=SQLITE_DEFAULT_WAL_SYNCHRONOUS - sqlite3 *db; - Db *pDb; - if( (db=pBt->db)!=0 && (pDb=db->aDb)!=0 ){ - while( pDb->pBt==0 || pDb->pBt->pBt!=pBt ){ pDb++; } - if( pDb->bSyncSet==0 - && pDb->safety_level==SQLITE_DEFAULT_SYNCHRONOUS+1 - ){ - pDb->safety_level = SQLITE_DEFAULT_WAL_SYNCHRONOUS+1; - sqlite3PagerSetFlags(pBt->pPager, - pDb->safety_level | (db->flags & PAGER_FLAGS_MASK)); - } - } -#endif + setDefaultSyncFlag(pBt, SQLITE_DEFAULT_WAL_SYNCHRONOUS+1); if( isOpen==0 ){ releasePage(pPage1); return SQLITE_OK; } } rc = SQLITE_NOTADB; + }else{ + setDefaultSyncFlag(pBt, SQLITE_DEFAULT_SYNCHRONOUS+1); } #endif diff --git a/src/ctime.c b/src/ctime.c index 3db3192095..20e94edba5 100644 --- a/src/ctime.c +++ b/src/ctime.c @@ -66,6 +66,12 @@ static const char * const azCompileOpt[] = { #if defined(SQLITE_DEFAULT_MMAP_SIZE) && !defined(SQLITE_DEFAULT_MMAP_SIZE_xc) "DEFAULT_MMAP_SIZE=" CTIMEOPT_VAL(SQLITE_DEFAULT_MMAP_SIZE), #endif +#if SQLITE_DEFAULT_SYNCHRONOUS + "DEFAULT_SYNCHRONOUS=" CTIMEOPT_VAL(SQLITE_DEFAULT_SYNCHRONOUS), +#endif +#if SQLITE_DEFAULT_WAL_SYNCHRONOUS + "DEFAULT_WAL_SYNCHRONOUS=" CTIMEOPT_VAL(SQLITE_DEFAULT_WAL_SYNCHRONOUS), +#endif #if SQLITE_DIRECT_OVERFLOW_READ "DIRECT_OVERFLOW_READ", #endif diff --git a/src/test_config.c b/src/test_config.c index f409b1ca6f..a25b0b3525 100644 --- a/src/test_config.c +++ b/src/test_config.c @@ -740,6 +740,8 @@ Tcl_SetVar2(interp, "sqlite_options", "mergesort", "1", TCL_GLOBAL_ONLY); LINKVAR( DEFAULT_CACHE_SIZE ); LINKVAR( DEFAULT_PAGE_SIZE ); LINKVAR( DEFAULT_FILE_FORMAT ); + LINKVAR( DEFAULT_SYNCHRONOUS ); + LINKVAR( DEFAULT_WAL_SYNCHRONOUS ); LINKVAR( MAX_ATTACHED ); LINKVAR( MAX_DEFAULT_PAGE_SIZE ); LINKVAR( MAX_WORKER_THREADS ); diff --git a/test/sync2.test b/test/sync2.test new file mode 100644 index 0000000000..5f9c9aba93 --- /dev/null +++ b/test/sync2.test @@ -0,0 +1,153 @@ +# 2017 March 16 +# +# 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 regression tests for SQLite library. +# +# Specificly, it tests that "PRAGMA synchronous" appears to work. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix sync2 + +# +# These tests are only applicable when pager pragma are +# enabled. Also, since every test uses an ATTACHed database, they +# are only run when ATTACH is enabled. +# +ifcapable !pager_pragmas||!attach { + finish_test + return +} + +proc execsql_sync {sql} { + set s $::sqlite_sync_count + set res [execsql $sql] + concat [expr $::sqlite_sync_count-$s] $res +} + +proc do_execsql_sync_test {tn sql res} { + uplevel [list do_test $tn [list execsql_sync $sql] [list {*}$res]] +} + +#----------------------------------------------------------------------- +# Tests for journal mode. +# +sqlite3 db test.db +do_execsql_test 1.0 { + CREATE TABLE t1(a, b); + INSERT INTO t1 VALUES(1, 2); +} + +do_execsql_sync_test 1.1 { INSERT INTO t1 VALUES(3, 4) } 4 + +# synchronous=normal. So, 1 sync on the directory, 1 on the journal, 1 +# on the db file. 3 in total. +do_execsql_test 1.2.1 { PRAGMA main.synchronous = NORMAL } +do_execsql_test 1.2.2 { PRAGMA main.synchronous } 1 +do_execsql_sync_test 1.2.3 { INSERT INTO t1 VALUES(5, 6) } 3 + +# synchronous=off. No syncs. +do_execsql_test 1.3.1 { PRAGMA main.synchronous = OFF } +do_execsql_test 1.3.2 { PRAGMA main.synchronous } 0 +do_execsql_sync_test 1.3.3 { INSERT INTO t1 VALUES(7, 8) } 0 + +# synchronous=full, journal_mode=delete. So, 1 sync on the directory, +# 2 on the journal, 1 on the db file. 4 in total. +do_execsql_test 1.4.1 { PRAGMA main.synchronous = FULL } +do_execsql_test 1.4.2 { PRAGMA main.synchronous } 2 +do_execsql_sync_test 1.4.3 { INSERT INTO t1 VALUES(9, 10) } 4 + +#----------------------------------------------------------------------- +# Tests for wal mode. +# +do_execsql_test 1.5 { PRAGMA journal_mode = wal } {wal} + +# sync=full, journal_mode=wal. One sync on the directory, two on the +# wal file. +do_execsql_sync_test 1.6 { INSERT INTO t1 VALUES(11, 12) } 3 + +# One sync on the wal file. +do_execsql_sync_test 1.7 { INSERT INTO t1 VALUES(13, 14) } 1 + +# No syncs. +do_execsql_test 1.8.1 { PRAGMA main.synchronous = NORMAL } +do_execsql_test 1.8.2 { PRAGMA main.synchronous } 1 +do_execsql_sync_test 1.8.3 { INSERT INTO t1 VALUES(15, 16) } 0 + +# One sync on wal file, one on the db file. +do_execsql_sync_test 1.9 { PRAGMA wal_checkpoint } {2 0 3 3} + +# No syncs. +do_execsql_test 1.10.1 { PRAGMA main.synchronous = OFF } +do_execsql_test 1.10.2 { PRAGMA main.synchronous } 0 +do_execsql_sync_test 1.10.3 { INSERT INTO t1 VALUES(17, 18) } 0 + +#----------------------------------------------------------------------- +# Tests for the compile time settings SQLITE_DEFAULT_SYNCHRONOUS and +# SQLITE_DEFAULT_WAL_SYNCHRONOUS. These tests only run if the former +# is set to "2" and the latter to "1". This is not the default, but +# it is currently the recommended configuration. +# +# https://sqlite.org/compile.html#recommended_compile_time_options +# +if {$SQLITE_DEFAULT_SYNCHRONOUS==2 && $SQLITE_DEFAULT_WAL_SYNCHRONOUS==1} { + + db close + sqlite3 db test.db + + # Wal mode, sync=normal. The first transaction does one sync on directory, + # one on the wal file. The second does no syncs. + do_execsql_sync_test 1.11.1 { INSERT INTO t1 VALUES(19, 20) } 2 + do_execsql_sync_test 1.11.2 { INSERT INTO t1 VALUES(21, 22) } 0 + do_execsql_test 1.11.3 { PRAGMA main.synchronous } 1 + + # One sync on wal file, one on the db file. + do_execsql_sync_test 1.12 { PRAGMA wal_checkpoint } {2 0 2 2} + + # First transaction syncs the wal file once, the second not at all. + # one on the wal file. The second does no syncs. + do_execsql_sync_test 1.13.1 { INSERT INTO t1 VALUES(22, 23) } 1 + do_execsql_sync_test 1.13.2 { INSERT INTO t1 VALUES(24, 25) } 0 + + do_execsql_test 1.14 { PRAGMA journal_mode = delete } {delete} + + # Delete mode, sync=full. The first transaction does one sync on + # directory, two on the journal file, one on the db. The second does + # the same. + do_execsql_sync_test 1.15.1 { INSERT INTO t1 VALUES(26, 27) } 4 + do_execsql_sync_test 1.15.2 { INSERT INTO t1 VALUES(28, 29) } 4 + do_execsql_test 1.15.3 { PRAGMA main.synchronous } 2 + + # Switch back to wal mode. + do_execsql_test 1.16 { PRAGMA journal_mode = wal } {wal} + + do_execsql_sync_test 1.17.1 { INSERT INTO t1 VALUES(30, 31) } 2 + do_execsql_sync_test 1.17.2 { INSERT INTO t1 VALUES(32, 33) } 0 + do_execsql_test 1.17.3 { PRAGMA main.synchronous } 1 + + # Now set synchronous=off, then switch back to delete mode. Check + # that the db handle is still using synchronous=off. + do_execsql_test 1.18.3 { PRAGMA main.synchronous=off } + do_execsql_test 1.18 { PRAGMA journal_mode = delete } {delete} + + do_execsql_sync_test 1.19.1 { INSERT INTO t1 VALUES(34, 35) } 0 + do_execsql_sync_test 1.19.2 { INSERT INTO t1 VALUES(36, 37) } 0 + do_execsql_test 1.19.3 { PRAGMA main.synchronous } 0 + + # Close and reopen the db. Back to synchronous=normal. + db close + sqlite3 db test.db + do_execsql_sync_test 1.20.1 { INSERT INTO t1 VALUES(38, 39) } 4 + do_execsql_sync_test 1.20.2 { INSERT INTO t1 VALUES(40, 41) } 4 + do_execsql_test 1.20.3 { PRAGMA main.synchronous } 2 +} + +finish_test From fc8f4b658ccf5ee626b21115f336e6068623827d Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 16 Mar 2017 18:54:42 +0000 Subject: [PATCH 1433/1484] Fix a typo causing the build to fail if SQLITE_DEFAULT_SYNCHRONOUS==SQLITE_DEFAULT_WAL_SYNCHRONOUS. FossilOrigin-Name: df39adeaa4d73a3d4ec831843b8ec7fd449f8b2137bdc7d7c320958d00e98db6 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btree.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 4d61ee44cb..27d666d7ff 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C If\sthe\suser\shas\snot\sset\sit\sexplicitly,\sset\sthe\s"PRAGMA\ssynchronous"\ssetting\sto\nSQLITE_DEFAULT_SYNCHRONOUS\swhen\sa\sdatabase\sconnection\schanges\sfrom\swal\sto\nrollback\sjournal\smode. -D 2017-03-16T18:14:39.798 +C Fix\sa\stypo\scausing\sthe\sbuild\sto\sfail\sif\sSQLITE_DEFAULT_SYNCHRONOUS==SQLITE_DEFAULT_WAL_SYNCHRONOUS. +D 2017-03-16T18:54:42.504 F Makefile.in 9605f4c49eace601d5c12c85dd6e037cc613a6d823e857614ba26b42f1285db0 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1faf9f06aadc9284c212dea7bbc7c0dea7e8337f0287c81001eff500912c790a @@ -343,7 +343,7 @@ F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792 F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca -F src/btree.c ace24955d01800acec28c79b038e1c291370f48a8955e8347cbd5339e39935de +F src/btree.c ae0e0397e6ad58465bbf932239ee7539ca22f257c97b16c9d0960a1f5de743a3 F src/btree.h bf64dfeeddeebdb775a5eba0098bbc00d073290d F src/btreeInt.h cd55d39d9916270837a88c12e701047cba0729b0 F src/build.c 43f903c9082040ced2b421543cb0300c2973647d @@ -1566,7 +1566,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 6d85eb5736781b43aa674d9544c7523b849b4e634f371702f8764b33e22e1e9f -R 549202c1b901efe7d78e47bd0d1adc7f +P 78030c0f52aa39fb2ab32c75c56e6bcefe6382b8df28b1909e3c911e42dbeca3 +R ce97b08e421fd719736eea9dd091c75c U dan -Z 959d77178fc349b2ba7589eca45f1aa2 +Z dc5f7c52928823522e8c3e89a1ed9d18 diff --git a/manifest.uuid b/manifest.uuid index 1973398254..57ec040514 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -78030c0f52aa39fb2ab32c75c56e6bcefe6382b8df28b1909e3c911e42dbeca3 \ No newline at end of file +df39adeaa4d73a3d4ec831843b8ec7fd449f8b2137bdc7d7c320958d00e98db6 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 47bb460b0c..52c0c47dd5 100644 --- a/src/btree.c +++ b/src/btree.c @@ -2884,7 +2884,7 @@ static void setDefaultSyncFlag(BtShared *pBt, u8 safety_level){ } } #else -# define setDefaultSyncFlag(pBt) +# define setDefaultSyncFlag(pBt,safety_level) #endif /* From a3b2da9889ceb5ca041ca0eb2bc8d35190aae94c Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 17 Mar 2017 03:21:14 +0000 Subject: [PATCH 1434/1484] Fix a problem in the enhanced PRAGMA integrity_check where it verifies CHECK constraints: Do not be confused by the reuse of the Table.pCheck field by VIEWs with named columns. Problem discovered by OSS-Fuzz. FossilOrigin-Name: 019dd3d5ba4a596c4ec3b5f0de8402c72196af0faca9138edbc0f1f4957cae60 --- manifest | 17 ++++++++--------- manifest.uuid | 2 +- src/pragma.c | 1 + test/check.test | 11 ++++++++++- 4 files changed, 20 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index dde0392581..99c6df185c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C If\sthe\suser\shas\snot\sset\sit\sexplicitly,\sset\sthe\s"PRAGMA\ssynchronous"\ssetting\sto\nSQLITE_DEFAULT_SYNCHRONOUS\swhen\sa\sdatabase\sconnection\schanges\sfrom\swal\sto\nrollback\sjournal\smode. -D 2017-03-16T18:55:21.135 +C Fix\sa\sproblem\sin\sthe\senhanced\sPRAGMA\sintegrity_check\swhere\sit\sverifies\nCHECK\sconstraints:\sDo\snot\sbe\sconfused\sby\sthe\sreuse\sof\sthe\sTable.pCheck\sfield\nby\sVIEWs\swith\snamed\scolumns.\s\sProblem\sdiscovered\sby\sOSS-Fuzz. +D 2017-03-17T03:21:14.865 F Makefile.in 9605f4c49eace601d5c12c85dd6e037cc613a6d823e857614ba26b42f1285db0 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1faf9f06aadc9284c212dea7bbc7c0dea7e8337f0287c81001eff500912c790a @@ -393,7 +393,7 @@ F src/parse.y 48b03113704ee8bd78ee6996d81de7fbee22e105 F src/pcache.c 62835bed959e2914edd26afadfecce29ece0e870 F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 F src/pcache1.c e3967219b2a92b9edcb9324a4ba75009090d3953 -F src/pragma.c bfaa7e5cbfc8eacaa0f3611d5ec2dca1339d6d301f1e9b429b49ca460d794a60 +F src/pragma.c 2b244434e76c7075edbcfd9e4d634899af0944ff01183b126d4671f7407c2368 F src/pragma.h c9c763958fec92b04125571472c9500b351c5f7f F src/prepare.c b1140c3d0cf59bc85ace00ce363153041b424b7a F src/printf.c 67427bbee66d891fc6f6f5aada857e9cdb368c1c @@ -582,7 +582,7 @@ F test/capi3d.test 485048dc5cd07bc68011e4917ad035ad6047ab82 F test/capi3e.test 3d49c01ef2a1a55f41d73cba2b23b5059ec460fe F test/cast.test 4c275cbdc8202d6f9c54a3596701719868ac7dc3 F test/cffault.test 9d6b20606afe712374952eec4f8fd74b1a8097ef -F test/check.test 92b23a91fb7be12fba7ee9ce518217e2919a21da +F test/check.test fb823c1aee9d5187b4a474f1728bb65f2a77303255e294e250a2328ab7e72832 F test/close.test 83947daf3b700631f90f4850ddaab455be4af73d F test/closure01.test b1703ba40639cfc9b295cf478d70739415eec6a4 F test/coalesce.test cee0dccb9fbd2d494b77234bccf9dc6c6786eb91 @@ -1566,8 +1566,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 6d85eb5736781b43aa674d9544c7523b849b4e634f371702f8764b33e22e1e9f df39adeaa4d73a3d4ec831843b8ec7fd449f8b2137bdc7d7c320958d00e98db6 -R ce97b08e421fd719736eea9dd091c75c -T +closed df39adeaa4d73a3d4ec831843b8ec7fd449f8b2137bdc7d7c320958d00e98db6 -U dan -Z 3997e48cc61ec2c438e101b7960cfa80 +P 5c604479fda06714500959e121c719d1b6c8e54d1658eb9f560a4af95b7c5829 +R 5046d28129e3bd81658af4ffa15e3f46 +U drh +Z bf308f7cb4f4a256732c0018ceafc10b diff --git a/manifest.uuid b/manifest.uuid index 195d935585..3d54c9e4c6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5c604479fda06714500959e121c719d1b6c8e54d1658eb9f560a4af95b7c5829 \ No newline at end of file +019dd3d5ba4a596c4ec3b5f0de8402c72196af0faca9138edbc0f1f4957cae60 \ No newline at end of file diff --git a/src/pragma.c b/src/pragma.c index 488a1d194c..6c27fdc5c9 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -1505,6 +1505,7 @@ void sqlite3Pragma( int iDataCur, iIdxCur; int r1 = -1; + if( pTab->tnum<1 ) continue; /* Skip VIEWs or VIRTUAL TABLEs */ if( pTab->pCheck==0 && (pTab->tabFlags & TF_HasNotNull)==0 && (pTab->pIndex==0 || isQuick) diff --git a/test/check.test b/test/check.test index 19f252677c..2100aebb85 100644 --- a/test/check.test +++ b/test/check.test @@ -481,6 +481,15 @@ do_catchsql_test 9.3 { UPDATE t1 SET c=a*2 WHERE a=1; } {1 {CHECK constraint failed: c-check}} - +# Integrity check on a VIEW with columns. +# +db close +forcedelete test.db +sqlite3 db test.db +do_execsql_test 10.1 { + CREATE TABLE t1(x); + CREATE VIEW v1(y) AS SELECT x FROM t1; + PRAGMA integrity_check; +} {ok} finish_test From 1f9144ed41cfd73d32347b3be47cbca2e8c3fc4e Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 17 Mar 2017 13:59:06 +0000 Subject: [PATCH 1435/1484] Fix a buffer overread in debugging routine sqlite3VdbeMemPrettyPrint(). Problem discovered by OSS-Fuzz. FossilOrigin-Name: f336fba7d7d41b91a5000d01dddf785821fa79ea31dbd8d1f769d55f7e871896 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/vdbe.c | 9 +++++++-- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 99c6df185c..77a9eebb02 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\sin\sthe\senhanced\sPRAGMA\sintegrity_check\swhere\sit\sverifies\nCHECK\sconstraints:\sDo\snot\sbe\sconfused\sby\sthe\sreuse\sof\sthe\sTable.pCheck\sfield\nby\sVIEWs\swith\snamed\scolumns.\s\sProblem\sdiscovered\sby\sOSS-Fuzz. -D 2017-03-17T03:21:14.865 +C Fix\sa\sbuffer\soverread\sin\sdebugging\sroutine\ssqlite3VdbeMemPrettyPrint().\nProblem\sdiscovered\sby\sOSS-Fuzz. +D 2017-03-17T13:59:06.018 F Makefile.in 9605f4c49eace601d5c12c85dd6e037cc613a6d823e857614ba26b42f1285db0 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1faf9f06aadc9284c212dea7bbc7c0dea7e8337f0287c81001eff500912c790a @@ -467,7 +467,7 @@ F src/update.c 456d4a4656f8a03c2abc88a51b19172197400e58 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c ca8440ede81e155d15cff7c101654f60b55a9ae6 F src/vacuum.c 1fe4555cd8c9b263afb85b5b4ee3a4a4181ad569 -F src/vdbe.c 0e6e5e01aaa57f6d1784b7d6b6a352153e9d2c2ff395c67ca59aef54b8268cf6 +F src/vdbe.c 3b4221473438a047d85839129c5e71eab80d8d19487c71e0ac6802fb330ae834 F src/vdbe.h 59998ffd71d7caa8886bc78dafaf8caeccd4c13c F src/vdbeInt.h 4e4b15b2e1330e1636e4e01974eab2b0b985092f F src/vdbeapi.c 5b08d82592bcff4470601fe78aaabebd50837860 @@ -1566,7 +1566,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 5c604479fda06714500959e121c719d1b6c8e54d1658eb9f560a4af95b7c5829 -R 5046d28129e3bd81658af4ffa15e3f46 -U drh -Z bf308f7cb4f4a256732c0018ceafc10b +P 019dd3d5ba4a596c4ec3b5f0de8402c72196af0faca9138edbc0f1f4957cae60 +R 6b67c5433a6804d9ab2b5f747ce1957d +U dan +Z cc6693cd745156921be8476a07d72767 diff --git a/manifest.uuid b/manifest.uuid index 3d54c9e4c6..7fc9e0264a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -019dd3d5ba4a596c4ec3b5f0de8402c72196af0faca9138edbc0f1f4957cae60 \ No newline at end of file +f336fba7d7d41b91a5000d01dddf785821fa79ea31dbd8d1f769d55f7e871896 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 20bf09e3a4..7eb2b6f6f7 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2657,8 +2657,13 @@ case OP_Column: { ** 2. the length(X) function if X is a blob, and ** 3. if the content length is zero. ** So we might as well use bogus content rather than reading - ** content from disk. */ - static u8 aZero[8]; /* This is the bogus content */ + ** content from disk. + ** + ** Although sqlite3VdbeSerialGet() may read at most 8 bytes from the + ** buffer passed to it, debugging function VdbeMemPrettyPrint() may + ** read up to 16. So 16 bytes of bogus content is supplied. + */ + static u8 aZero[16]; /* This is the bogus content */ sqlite3VdbeSerialGet(aZero, t, pDest); }else{ rc = sqlite3VdbeMemFromBtree(pC->uc.pCursor, aOffset[p2], len, pDest); From 59d705ab808645ac865ad14e19d47f688064005f Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 17 Mar 2017 14:15:06 +0000 Subject: [PATCH 1436/1484] Fix the Makefile.in so that it builds the ossshell test program correctly. FossilOrigin-Name: 36f5602ec9fb8e404c5250e18b1db877ac7bee643918b94afd51808134ea7900 --- Makefile.in | 3 ++- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/Makefile.in b/Makefile.in index 0b40cb458b..9076ffc085 100644 --- a/Makefile.in +++ b/Makefile.in @@ -621,7 +621,8 @@ fuzzcheck$(TEXE): $(FUZZCHECK_SRC) sqlite3.c sqlite3.h $(LTLINK) -o $@ $(FUZZCHECK_OPT) $(FUZZCHECK_SRC) sqlite3.c $(TLIBS) ossshell$(TEXE): $(TOP)/test/ossfuzz.c $(TOP)/test/ossshell.c sqlite3.c sqlite3.h - $(LTLINK) -o $@ $(FUZZCHECK_OPT) $(TOP)/test/ossshell.c sqlite3.c sqlite3.h $(TLIBS) + $(LTLINK) -o $@ $(FUZZCHECK_OPT) $(TOP)/test/ossshell.c \ + $(TOP)/test/ossfuzz.c sqlite3.c $(TLIBS) dbfuzz$(TEXE): $(TOP)/test/dbfuzz.c sqlite3.c sqlite3.h $(LTLINK) -o $@ $(DBFUZZ_OPT) $(TOP)/test/dbfuzz.c sqlite3.c $(TLIBS) diff --git a/manifest b/manifest index 77a9eebb02..6f14fa4cca 100644 --- a/manifest +++ b/manifest @@ -1,6 +1,6 @@ -C Fix\sa\sbuffer\soverread\sin\sdebugging\sroutine\ssqlite3VdbeMemPrettyPrint().\nProblem\sdiscovered\sby\sOSS-Fuzz. -D 2017-03-17T13:59:06.018 -F Makefile.in 9605f4c49eace601d5c12c85dd6e037cc613a6d823e857614ba26b42f1285db0 +C Fix\sthe\sMakefile.in\sso\sthat\sit\sbuilds\sthe\sossshell\stest\sprogram\scorrectly. +D 2017-03-17T14:15:06.628 +F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1faf9f06aadc9284c212dea7bbc7c0dea7e8337f0287c81001eff500912c790a F README.md 2b15fae33852f2f53996774c21fb41e1d94181c4401a0e43ac93e11f2cc901b9 @@ -1566,7 +1566,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 019dd3d5ba4a596c4ec3b5f0de8402c72196af0faca9138edbc0f1f4957cae60 -R 6b67c5433a6804d9ab2b5f747ce1957d -U dan -Z cc6693cd745156921be8476a07d72767 +P f336fba7d7d41b91a5000d01dddf785821fa79ea31dbd8d1f769d55f7e871896 +R a0acb13b6691b2f29cdfa3d14a75a6b3 +U drh +Z a464f97090f56a22de007bae0707b7f9 diff --git a/manifest.uuid b/manifest.uuid index 7fc9e0264a..cdf2f41fac 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f336fba7d7d41b91a5000d01dddf785821fa79ea31dbd8d1f769d55f7e871896 \ No newline at end of file +36f5602ec9fb8e404c5250e18b1db877ac7bee643918b94afd51808134ea7900 \ No newline at end of file From f53524b4f72be7e7cf96fdec983000c9e4c5a85a Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 17 Mar 2017 14:59:40 +0000 Subject: [PATCH 1437/1484] Add the --show-errors and --show-max-delay command-line options to the ossshell test program. FossilOrigin-Name: 626bdca98e0cd78ae873d97e75bb7d544ca18759c9f1e67f4adf03daca7fe5bf --- manifest | 14 +++++------ manifest.uuid | 2 +- test/ossfuzz.c | 67 +++++++++++++++++++++++++++++++++++++++++-------- test/ossshell.c | 33 ++++++++++++++++++++++++ 4 files changed, 97 insertions(+), 19 deletions(-) diff --git a/manifest b/manifest index 6f14fa4cca..24baa432d0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\sMakefile.in\sso\sthat\sit\sbuilds\sthe\sossshell\stest\sprogram\scorrectly. -D 2017-03-17T14:15:06.628 +C Add\sthe\s--show-errors\sand\s--show-max-delay\scommand-line\soptions\sto\sthe\nossshell\stest\sprogram. +D 2017-03-17T14:59:40.532 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1faf9f06aadc9284c212dea7bbc7c0dea7e8337f0287c81001eff500912c790a @@ -1009,8 +1009,8 @@ F test/orderby7.test 3d1383d52ade5b9eb3a173b3147fdd296f0202da F test/orderby8.test 23ef1a5d72bd3adcc2f65561c654295d1b8047bd F test/orderby9.test 87fb9548debcc2cd141c5299002dd94672fa76a3 F test/oserror.test b32dc34f2363ef18532e3a0a7358e3e7e321974f -F test/ossfuzz.c 6dc75478809cfbd4609409a87179ddc2ffaa092e8adb27c1982c5a944a7dd81f -F test/ossshell.c d9f1a6f43e7bab45d6be857a5800f5d4a1861db3 +F test/ossfuzz.c 756ca4bede67ec22e3a700b1168bad767dc6fc69ede414c4ab87cfcfcceb4075 +F test/ossshell.c 296ab63067841bd1b1e97b46a0b2af48ee7f69d50d1a723008bee12dd7122622 F test/ovfl.test 199c482696defceacee8c8e0e0ef36da62726b2f F test/pager1.test 841868017e9dd3cb459b8d78862091a7d9cff21d F test/pager2.test 67b8f40ae98112bcdba1f2b2d03ea83266418c71 @@ -1566,7 +1566,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P f336fba7d7d41b91a5000d01dddf785821fa79ea31dbd8d1f769d55f7e871896 -R a0acb13b6691b2f29cdfa3d14a75a6b3 +P 36f5602ec9fb8e404c5250e18b1db877ac7bee643918b94afd51808134ea7900 +R 78dfbe98cc4f1c1387677674bd1f6a34 U drh -Z a464f97090f56a22de007bae0707b7f9 +Z 8d96b967fb72fb140eaa51fb70892dfa diff --git a/manifest.uuid b/manifest.uuid index cdf2f41fac..6144ff8028 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -36f5602ec9fb8e404c5250e18b1db877ac7bee643918b94afd51808134ea7900 \ No newline at end of file +626bdca98e0cd78ae873d97e75bb7d544ca18759c9f1e67f4adf03daca7fe5bf \ No newline at end of file diff --git a/test/ossfuzz.c b/test/ossfuzz.c index 97d101e17a..6790d194d5 100644 --- a/test/ossfuzz.c +++ b/test/ossfuzz.c @@ -4,8 +4,26 @@ */ #include #include +#include +#include #include "sqlite3.h" +/* Global debugging settings. OSS-Fuzz will have all debugging turned +** off. But if LLVMFuzzerTestOneInput() is called interactively from +** the ossshell utility program, then these flags might be set. +*/ +static unsigned mDebug = 0; +#define FUZZ_SQL_TRACE 0x0001 /* Set an sqlite3_trace() callback */ +#define FUZZ_SHOW_MAX_DELAY 0x0002 /* Show maximum progress callback delay */ +#define FUZZ_SHOW_ERRORS 0x0004 /* Print error messages from SQLite */ + +/* The ossshell utility program invokes this interface to see the +** debugging flags. Unused by OSS-Fuzz. +*/ +void ossfuzz_set_debug_flags(unsigned x){ + mDebug = x; +} + /* Return the current real-world time in milliseconds since the ** Julian epoch (-4714-11-24). */ @@ -23,6 +41,17 @@ static sqlite3_int64 timeOfDay(void){ return t; } +/* An instance of the following object is passed by pointer as the +** client data to various callbacks. +*/ +typedef struct FuzzCtx { + sqlite3 *db; /* The database connection */ + sqlite3_int64 iCutoffTime; /* Stop processing at this time. */ + sqlite3_int64 iLastCb; /* Time recorded for previous progress callback */ + sqlite3_int64 mxInterval; /* Longest interval between two progress calls */ + unsigned nCb; /* Number of progress callbacks */ +} FuzzCtx; + #ifndef SQLITE_OMIT_PROGRESS_CALLBACK /* ** Progress handler callback. @@ -30,9 +59,14 @@ static sqlite3_int64 timeOfDay(void){ ** The argument is the cutoff-time after which all processing should ** stop. So return non-zero if the cut-off time is exceeded. */ -static int progress_handler(void *pReturn) { - sqlite3_int64 iCutoffTime = *(sqlite3_int64*)pReturn; - return timeOfDay()>=iCutoffTime; +static int progress_handler(void *pClientData) { + FuzzCtx *p = (FuzzCtx*)pClientData; + sqlite3_int64 iNow = timeOfDay(); + int rc = iNow>=p->iCutoffTime; + sqlite3_int64 iDiff = iNow - p->iLastCb; + if( iDiff > p->mxInterval ) p->mxInterval = iDiff; + p->nCb++; + return rc; } #endif @@ -54,12 +88,12 @@ static int exec_handler(void *pCnt, int argc, char **argv, char **namev){ int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { int execCnt = 0; /* Abort row callback when count reaches zero */ char *zErrMsg = 0; /* Error message returned by sqlite_exec() */ - sqlite3 *db; /* The database connection */ uint8_t uSelector; /* First byte of input data[] */ int rc; /* Return code from various interfaces */ char *zSql; /* Zero-terminated copy of data[] */ - sqlite3_int64 iCutoff; /* Cutoff timer */ + FuzzCtx cx; /* Fuzzing context */ + memset(&cx, 0, sizeof(cx)); if( size<3 ) return 0; /* Early out if unsufficient data */ /* Extract the selector byte from the beginning of the input. But only @@ -72,7 +106,7 @@ int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { } /* Open the database connection. Only use an in-memory database. */ - rc = sqlite3_open_v2("fuzz.db", &db, + rc = sqlite3_open_v2("fuzz.db", &cx.db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_MEMORY, 0); if( rc ) return 0; @@ -82,12 +116,13 @@ int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { ** (which will block further processing) if more than 10 seconds have ** elapsed since the start of the test. */ - iCutoff = timeOfDay() + 10000; /* Now + 10 seconds */ - sqlite3_progress_handler(db, 10, progress_handler, (void*)&iCutoff); + cx.iLastCb = timeOfDay(); + cx.iCutoffTime = cx.iLastCb + 10000; /* Now + 10 seconds */ + sqlite3_progress_handler(cx.db, 10, progress_handler, (void*)&cx); #endif /* Bit 1 of the selector enables foreign key constraints */ - sqlite3_db_config(db, SQLITE_DBCONFIG_ENABLE_FKEY, uSelector&1, &rc); + sqlite3_db_config(cx.db, SQLITE_DBCONFIG_ENABLE_FKEY, uSelector&1, &rc); uSelector >>= 1; /* Remaining bits of the selector determine a limit on the number of @@ -97,11 +132,21 @@ int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { /* Run the SQL. The sqlite_exec() interface expects a zero-terminated ** string, so make a copy. */ zSql = sqlite3_mprintf("%.*s", (int)size, data); - sqlite3_exec(db, zSql, exec_handler, (void*)&execCnt, &zErrMsg); + sqlite3_exec(cx.db, zSql, exec_handler, (void*)&execCnt, &zErrMsg); + + /* Show any errors */ + if( (mDebug & FUZZ_SHOW_ERRORS)!=0 && zErrMsg ){ + printf("Error: %s\n", zErrMsg); + } /* Cleanup and return */ sqlite3_free(zErrMsg); sqlite3_free(zSql); - sqlite3_close(db); + sqlite3_close(cx.db); + + if( mDebug & FUZZ_SHOW_MAX_DELAY ){ + printf("Progress callback count....... %d\n", cx.nCb); + printf("Max time between callbacks.... %d ms\n", (int)cx.mxInterval); + } return 0; } diff --git a/test/ossshell.c b/test/ossshell.c index 15902a9122..00cc3391c8 100644 --- a/test/ossshell.c +++ b/test/ossshell.c @@ -9,6 +9,7 @@ #include #include #include +#include #include "sqlite3.h" /* @@ -16,6 +17,13 @@ */ int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size); +/* Must match equivalent #defines in ossfuzz.c */ +#define FUZZ_SQL_TRACE 0x0001 /* Set an sqlite3_trace() callback */ +#define FUZZ_SHOW_MAX_DELAY 0x0002 /* Show maximum progress callback delay */ +#define FUZZ_SHOW_ERRORS 0x0004 /* Show SQL errors */ +extern void ossfuzz_set_debug_flags(unsigned); + + /* ** Read files named on the command-line and invoke the fuzzer for @@ -27,9 +35,32 @@ int main(int argc, char **argv){ int nErr = 0; uint8_t *zBuf = 0; size_t sz; + unsigned mDebug = 0; for(i=1; i Date: Fri, 17 Mar 2017 22:50:16 +0000 Subject: [PATCH 1438/1484] Begin enforcing the SQLITE_LIMIT_VDBE_OP. The documentation warned that this day might come. FossilOrigin-Name: ef5914617088cbf89bfae88f63ea959a07f02dff387ddc2b43948ad99c6a97b8 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/sqlite.h.in | 8 +++++--- src/sqliteLimit.h | 2 +- src/vdbeaux.c | 6 ++++++ 5 files changed, 21 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 24baa432d0..db77af64f9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\s--show-errors\sand\s--show-max-delay\scommand-line\soptions\sto\sthe\nossshell\stest\sprogram. -D 2017-03-17T14:59:40.532 +C Begin\senforcing\sthe\sSQLITE_LIMIT_VDBE_OP.\s\sThe\sdocumentation\swarned\sthat\sthis\nday\smight\scome. +D 2017-03-17T22:50:16.704 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1faf9f06aadc9284c212dea7bbc7c0dea7e8337f0287c81001eff500912c790a @@ -402,11 +402,11 @@ F src/resolve.c 3e518b962d932a997fae373366880fc028c75706 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c 2496d0cc6368dabe7ad2e4c7f5ed3ad9aa3b4d11cd90f33fa1d1ef72493f43aa F src/shell.c 77054c021069ec0b65d3d620aab031f97c59b4e42ac7c31544ea68933b581104 -F src/sqlite.h.in 4d0c08f8640c586564a7032b259c5f69bf397850 +F src/sqlite.h.in 5f72af637ba0f35c2b25f8f97ea63bac6f4ea133eb904ee0b6d61450401507d3 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae F src/sqliteInt.h df268ce1d04df042cf43b557d2309eb0b71e86c4 -F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 +F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 F src/tclsqlite.c 6c2151b6d8d98e183a04466d40df8889c0574d79 @@ -471,7 +471,7 @@ F src/vdbe.c 3b4221473438a047d85839129c5e71eab80d8d19487c71e0ac6802fb330ae834 F src/vdbe.h 59998ffd71d7caa8886bc78dafaf8caeccd4c13c F src/vdbeInt.h 4e4b15b2e1330e1636e4e01974eab2b0b985092f F src/vdbeapi.c 5b08d82592bcff4470601fe78aaabebd50837860 -F src/vdbeaux.c 57361f2e761d92a254638bdbfc03fc68ae6aebc6 +F src/vdbeaux.c ecd0468611925d218e1eb4b3f538907904b136f0e15e333291a232b521bfcef1 F src/vdbeblob.c 359891617358deefc85bef7bcf787fa6b77facb9 F src/vdbemem.c 3b5a9a5b375458d3e12a50ae1aaa41eeec2175fd F src/vdbesort.c eda25cb2d1727efca6f7862fea32b8aa33c0face @@ -1566,7 +1566,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 36f5602ec9fb8e404c5250e18b1db877ac7bee643918b94afd51808134ea7900 -R 78dfbe98cc4f1c1387677674bd1f6a34 +P 626bdca98e0cd78ae873d97e75bb7d544ca18759c9f1e67f4adf03daca7fe5bf +R 577cbf1218e05c6f890fd56d3bd8c3f1 U drh -Z 8d96b967fb72fb140eaa51fb70892dfa +Z db7430243d899e77772ca775a4ab8f59 diff --git a/manifest.uuid b/manifest.uuid index 6144ff8028..0f60fb4ebb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -626bdca98e0cd78ae873d97e75bb7d544ca18759c9f1e67f4adf03daca7fe5bf \ No newline at end of file +ef5914617088cbf89bfae88f63ea959a07f02dff387ddc2b43948ad99c6a97b8 \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 076a011319..5dd4419f43 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -3424,9 +3424,10 @@ int sqlite3_limit(sqlite3*, int id, int newVal); ** ** [[SQLITE_LIMIT_VDBE_OP]] ^(
    SQLITE_LIMIT_VDBE_OP
    **
    The maximum number of instructions in a virtual machine program -** used to implement an SQL statement. This limit is not currently -** enforced, though that might be added in some future release of -** SQLite.
    )^ +** used to implement an SQL statement. If [sqlite3_prepare_v2()] or +** the equivalent tries to allocate space for more than this many opcodes +** in a single prepared statement, an SQLITE_NOMEM error is returned. +** A value of 0 means "unlimited".)^ ** ** [[SQLITE_LIMIT_FUNCTION_ARG]] ^(
    SQLITE_LIMIT_FUNCTION_ARG
    **
    The maximum number of arguments on a function.
    )^ @@ -3464,6 +3465,7 @@ int sqlite3_limit(sqlite3*, int id, int newVal); #define SQLITE_LIMIT_TRIGGER_DEPTH 10 #define SQLITE_LIMIT_WORKER_THREADS 11 + /* ** CAPI3REF: Compiling An SQL Statement ** KEYWORDS: {SQL statement compiler} diff --git a/src/sqliteLimit.h b/src/sqliteLimit.h index 0554e61581..28e7a41cc3 100644 --- a/src/sqliteLimit.h +++ b/src/sqliteLimit.h @@ -87,7 +87,7 @@ ** Not currently enforced. */ #ifndef SQLITE_MAX_VDBE_OP -# define SQLITE_MAX_VDBE_OP 25000 +# define SQLITE_MAX_VDBE_OP 250000000 #endif /* diff --git a/src/vdbeaux.c b/src/vdbeaux.c index ab4aad7a0f..a8f215420a 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -117,6 +117,12 @@ static int growOpArray(Vdbe *v, int nOp){ UNUSED_PARAMETER(nOp); #endif + /* Ensure that the size of a VDBE does not grow too large */ + if( nNew > p->db->aLimit[SQLITE_LIMIT_VDBE_OP] ){ + sqlite3OomFault(p->db); + return SQLITE_NOMEM; + } + assert( nOp<=(1024/sizeof(Op)) ); assert( nNew>=(p->nOpAlloc+nOp) ); pNew = sqlite3DbRealloc(p->db, v->aOp, nNew*sizeof(Op)); From 544cab7651100628ed290acc2a2fee394b7568aa Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 17 Mar 2017 22:51:28 +0000 Subject: [PATCH 1439/1484] Set a reasonable limit on the number of opcodes in a prepared statement for ossfuzz.c. This should prevent timeouts in OSS-Fuzz when it generates totally unreasonable queries. FossilOrigin-Name: f74899ed2c78019abb406432a74dcd42a0ff8d9add005f8544dc4a8905f232eb --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/ossfuzz.c | 3 +++ 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index db77af64f9..3396b9cc13 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Begin\senforcing\sthe\sSQLITE_LIMIT_VDBE_OP.\s\sThe\sdocumentation\swarned\sthat\sthis\nday\smight\scome. -D 2017-03-17T22:50:16.704 +C Set\sa\sreasonable\slimit\son\sthe\snumber\sof\sopcodes\sin\sa\sprepared\sstatement\nfor\sossfuzz.c.\s\sThis\sshould\sprevent\stimeouts\sin\sOSS-Fuzz\swhen\sit\sgenerates\ntotally\sunreasonable\squeries. +D 2017-03-17T22:51:28.665 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1faf9f06aadc9284c212dea7bbc7c0dea7e8337f0287c81001eff500912c790a @@ -1009,7 +1009,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 756ca4bede67ec22e3a700b1168bad767dc6fc69ede414c4ab87cfcfcceb4075 +F test/ossfuzz.c 8c4d62e156352ecb97eb868fcff20d828a279af67a1c1310779f63464d6f009f F test/ossshell.c 296ab63067841bd1b1e97b46a0b2af48ee7f69d50d1a723008bee12dd7122622 F test/ovfl.test 199c482696defceacee8c8e0e0ef36da62726b2f F test/pager1.test 841868017e9dd3cb459b8d78862091a7d9cff21d @@ -1566,7 +1566,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 626bdca98e0cd78ae873d97e75bb7d544ca18759c9f1e67f4adf03daca7fe5bf -R 577cbf1218e05c6f890fd56d3bd8c3f1 +P ef5914617088cbf89bfae88f63ea959a07f02dff387ddc2b43948ad99c6a97b8 +R 3a60b2fbebe94ced9367e16b751bb1ee U drh -Z db7430243d899e77772ca775a4ab8f59 +Z bc390a309335be50f7a4bf79ab7f90df diff --git a/manifest.uuid b/manifest.uuid index 0f60fb4ebb..e97c1e2b26 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ef5914617088cbf89bfae88f63ea959a07f02dff387ddc2b43948ad99c6a97b8 \ No newline at end of file +f74899ed2c78019abb406432a74dcd42a0ff8d9add005f8544dc4a8905f232eb \ No newline at end of file diff --git a/test/ossfuzz.c b/test/ossfuzz.c index 6790d194d5..0c2b1320e4 100644 --- a/test/ossfuzz.c +++ b/test/ossfuzz.c @@ -121,6 +121,9 @@ int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { sqlite3_progress_handler(cx.db, 10, progress_handler, (void*)&cx); #endif + /* Set a limit on the maximum size of a prepared statement */ + sqlite3_limit(cx.db, SQLITE_LIMIT_VDBE_OP, 25000); + /* Bit 1 of the selector enables foreign key constraints */ sqlite3_db_config(cx.db, SQLITE_DBCONFIG_ENABLE_FKEY, uSelector&1, &rc); uSelector >>= 1; From 46acfc2b4737258bf4af6f34f9ba88f0281d73bb Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 17 Mar 2017 23:08:11 +0000 Subject: [PATCH 1440/1484] Fix an error in the newly revised documentation for SQLITE_LIMIT_VDBE_OP. No changes to code. FossilOrigin-Name: f4cf8635e6fec6f04075cc067aaa71abc4f71739068e0ad2c44609dcb8691009 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/sqlite.h.in | 3 +-- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 3396b9cc13..0f47d77aec 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Set\sa\sreasonable\slimit\son\sthe\snumber\sof\sopcodes\sin\sa\sprepared\sstatement\nfor\sossfuzz.c.\s\sThis\sshould\sprevent\stimeouts\sin\sOSS-Fuzz\swhen\sit\sgenerates\ntotally\sunreasonable\squeries. -D 2017-03-17T22:51:28.665 +C Fix\san\serror\sin\sthe\snewly\srevised\sdocumentation\sfor\sSQLITE_LIMIT_VDBE_OP.\nNo\schanges\sto\scode. +D 2017-03-17T23:08:11.772 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1faf9f06aadc9284c212dea7bbc7c0dea7e8337f0287c81001eff500912c790a @@ -402,7 +402,7 @@ F src/resolve.c 3e518b962d932a997fae373366880fc028c75706 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c 2496d0cc6368dabe7ad2e4c7f5ed3ad9aa3b4d11cd90f33fa1d1ef72493f43aa F src/shell.c 77054c021069ec0b65d3d620aab031f97c59b4e42ac7c31544ea68933b581104 -F src/sqlite.h.in 5f72af637ba0f35c2b25f8f97ea63bac6f4ea133eb904ee0b6d61450401507d3 +F src/sqlite.h.in e992605a306ee4f58d2ecbbc665f71c0404a3c815fe90dd8e0c0e8f7b9b11166 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae F src/sqliteInt.h df268ce1d04df042cf43b557d2309eb0b71e86c4 @@ -1566,7 +1566,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ef5914617088cbf89bfae88f63ea959a07f02dff387ddc2b43948ad99c6a97b8 -R 3a60b2fbebe94ced9367e16b751bb1ee +P f74899ed2c78019abb406432a74dcd42a0ff8d9add005f8544dc4a8905f232eb +R 2c6af10e620c43369539bc210339bdfc U drh -Z bc390a309335be50f7a4bf79ab7f90df +Z 53bb8f51c26aa8f2582ebee07b281f74 diff --git a/manifest.uuid b/manifest.uuid index e97c1e2b26..5630824735 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f74899ed2c78019abb406432a74dcd42a0ff8d9add005f8544dc4a8905f232eb \ No newline at end of file +f4cf8635e6fec6f04075cc067aaa71abc4f71739068e0ad2c44609dcb8691009 \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 5dd4419f43..48e21e175b 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -3426,8 +3426,7 @@ int sqlite3_limit(sqlite3*, int id, int newVal); **
    The maximum number of instructions in a virtual machine program ** used to implement an SQL statement. If [sqlite3_prepare_v2()] or ** the equivalent tries to allocate space for more than this many opcodes -** in a single prepared statement, an SQLITE_NOMEM error is returned. -** A value of 0 means "unlimited".
    )^ +** in a single prepared statement, an SQLITE_NOMEM error is returned.)^ ** ** [[SQLITE_LIMIT_FUNCTION_ARG]] ^(
    SQLITE_LIMIT_FUNCTION_ARG
    **
    The maximum number of arguments on a function.
    )^ From a80e160634c95ab4d72ed0760d7a70eca458334a Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 18 Mar 2017 13:59:46 +0000 Subject: [PATCH 1441/1484] Only do the specialized MacOS single-core zone_malloc initialization if compiled with the SQLITE_MIGHT_BE_SINGLE_CORE flag. This avoids a (harmless) warning about OSAtomicCompareAndSwapPtrBarrier() being deprecated. FossilOrigin-Name: 4e6a03d9e12b120d15946b025f97a97697cb8e8af543c238ffda220c9e3f28f4 --- manifest | 12 +++++------ manifest.uuid | 2 +- src/mem1.c | 59 ++++++++++++++++++++++++++++++++------------------- 3 files changed, 44 insertions(+), 29 deletions(-) diff --git a/manifest b/manifest index 0f47d77aec..d7127e3e78 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\serror\sin\sthe\snewly\srevised\sdocumentation\sfor\sSQLITE_LIMIT_VDBE_OP.\nNo\schanges\sto\scode. -D 2017-03-17T23:08:11.772 +C Only\sdo\sthe\sspecialized\sMacOS\ssingle-core\szone_malloc\sinitialization\sif\ncompiled\swith\sthe\sSQLITE_MIGHT_BE_SINGLE_CORE\sflag.\s\sThis\savoids\sa\s(harmless)\nwarning\sabout\sOSAtomicCompareAndSwapPtrBarrier()\sbeing\sdeprecated. +D 2017-03-18T13:59:46.558 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1faf9f06aadc9284c212dea7bbc7c0dea7e8337f0287c81001eff500912c790a @@ -368,7 +368,7 @@ F src/loadext.c a68d8d1d14cf7488bb29dc5311cb1ce9a4404258 F src/main.c 158326243c5ddc8b98a1e983fa488650cf76d760 F src/malloc.c 89c98e3619d362dcffa5c1c639b364b65b474751 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 -F src/mem1.c fd7cd6fe21d46fe0a4186367dd8dc26d87b787eb +F src/mem1.c 79bf195f445bf7e66cadd121849837c3152fbd2f542326bbed3073b6902450c2 F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3 F src/mem3.c 8768ac94694f31ffaf8b4d0ea5dc08af7010a35a F src/mem5.c 9bf955937b07f8c32541c8a9991f33ce3173d944 @@ -1566,7 +1566,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P f74899ed2c78019abb406432a74dcd42a0ff8d9add005f8544dc4a8905f232eb -R 2c6af10e620c43369539bc210339bdfc +P f4cf8635e6fec6f04075cc067aaa71abc4f71739068e0ad2c44609dcb8691009 +R 07e88bce7a34b04a1e3a36ad2d4b6f58 U drh -Z 53bb8f51c26aa8f2582ebee07b281f74 +Z 906adb059f738e34206863c58e96feb3 diff --git a/manifest.uuid b/manifest.uuid index 5630824735..4d805efd7a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f4cf8635e6fec6f04075cc067aaa71abc4f71739068e0ad2c44609dcb8691009 \ No newline at end of file +4e6a03d9e12b120d15946b025f97a97697cb8e8af543c238ffda220c9e3f28f4 \ No newline at end of file diff --git a/src/mem1.c b/src/mem1.c index efc84c41d7..02ed59b4d4 100644 --- a/src/mem1.c +++ b/src/mem1.c @@ -57,7 +57,9 @@ */ #include #include +#ifdef SQLITE_MIGHT_BE_SINGLE_CORE #include +#endif /* SQLITE_MIGHT_BE_SINGLE_CORE */ static malloc_zone_t* _sqliteZone_; #define SQLITE_MALLOC(x) malloc_zone_malloc(_sqliteZone_, (x)) #define SQLITE_FREE(x) malloc_zone_free(_sqliteZone_, (x)); @@ -236,33 +238,46 @@ static int sqlite3MemRoundup(int n){ */ static int sqlite3MemInit(void *NotUsed){ #if defined(__APPLE__) && !defined(SQLITE_WITHOUT_ZONEMALLOC) - int cpuCount; - size_t len; if( _sqliteZone_ ){ return SQLITE_OK; } - len = sizeof(cpuCount); - /* One usually wants to use hw.acctivecpu for MT decisions, but not here */ - sysctlbyname("hw.ncpu", &cpuCount, &len, NULL, 0); - if( cpuCount>1 ){ - /* defer MT decisions to system malloc */ - _sqliteZone_ = malloc_default_zone(); - }else{ - /* only 1 core, use our own zone to contention over global locks, - ** e.g. we have our own dedicated locks */ - bool success; - malloc_zone_t* newzone = malloc_create_zone(4096, 0); - malloc_set_zone_name(newzone, "Sqlite_Heap"); - do{ - success = OSAtomicCompareAndSwapPtrBarrier(NULL, newzone, - (void * volatile *)&_sqliteZone_); - }while(!_sqliteZone_); - if( !success ){ - /* somebody registered a zone first */ - malloc_destroy_zone(newzone); +#ifndef SQLITE_MIGHT_BE_SINGLE_CORE + /* If not compiled with the SQLITE_MIGHT_BE_SINGLE_CORE flag, assume + ** that multiple cores are always available. This is the default case. + */ + _sqliteZone_ = malloc_default_zone(); +#else + /* With the SQLITE_MIGHT_BE_SINGLE_CORE compile-time option, check the + ** number of cores. Different malloc() strategies are used for single-core and + ** multi-core machines. + */ + { + int cpuCount; + size_t len; + len = sizeof(cpuCount); + /* One usually wants to use hw.acctivecpu for MT decisions, but not here */ + sysctlbyname("hw.ncpu", &cpuCount, &len, NULL, 0); + if( cpuCount>1 ){ + /* defer MT decisions to system malloc */ + _sqliteZone_ = malloc_default_zone(); + }else{ + /* only 1 core, use our own zone to contention over global locks, + ** e.g. we have our own dedicated locks */ + bool success; + malloc_zone_t* newzone = malloc_create_zone(4096, 0); + malloc_set_zone_name(newzone, "Sqlite_Heap"); + do{ + success = OSAtomicCompareAndSwapPtrBarrier(NULL, newzone, + (void * volatile *)&_sqliteZone_); + }while(!_sqliteZone_); + if( !success ){ + /* somebody registered a zone first */ + malloc_destroy_zone(newzone); + } } } -#endif +#endif /* SQLITE_MIGHT_BE_SINGLE_CORE */ +#endif /* defined(__APPLE__) && !defined(SQLITE_WITHOUT_ZONEMALLOC) */ UNUSED_PARAMETER(NotUsed); return SQLITE_OK; } From d3d52ef1471c670a1bb04c0dcf05cf7866c98cd7 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 20 Mar 2017 13:03:39 +0000 Subject: [PATCH 1442/1484] Documentation fix: SQLITE_SOURCE_ID is a now a SHA3-256 hash. FossilOrigin-Name: 2aa22509e7c8a1f09b16e4544c95d0b77503daed1f83106ccc18dee8bd9487a4 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/sqlite.h.in | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index d7127e3e78..5f21e2e7ce 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Only\sdo\sthe\sspecialized\sMacOS\ssingle-core\szone_malloc\sinitialization\sif\ncompiled\swith\sthe\sSQLITE_MIGHT_BE_SINGLE_CORE\sflag.\s\sThis\savoids\sa\s(harmless)\nwarning\sabout\sOSAtomicCompareAndSwapPtrBarrier()\sbeing\sdeprecated. -D 2017-03-18T13:59:46.558 +C Documentation\sfix:\s\sSQLITE_SOURCE_ID\sis\sa\snow\sa\sSHA3-256\shash. +D 2017-03-20T13:03:39.888 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1faf9f06aadc9284c212dea7bbc7c0dea7e8337f0287c81001eff500912c790a @@ -402,7 +402,7 @@ F src/resolve.c 3e518b962d932a997fae373366880fc028c75706 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c 2496d0cc6368dabe7ad2e4c7f5ed3ad9aa3b4d11cd90f33fa1d1ef72493f43aa F src/shell.c 77054c021069ec0b65d3d620aab031f97c59b4e42ac7c31544ea68933b581104 -F src/sqlite.h.in e992605a306ee4f58d2ecbbc665f71c0404a3c815fe90dd8e0c0e8f7b9b11166 +F src/sqlite.h.in 723107d97f2345a7c103632169dc61366121c4ab65d75a7d83c6dc0e5bbe5ca4 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae F src/sqliteInt.h df268ce1d04df042cf43b557d2309eb0b71e86c4 @@ -1566,7 +1566,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P f4cf8635e6fec6f04075cc067aaa71abc4f71739068e0ad2c44609dcb8691009 -R 07e88bce7a34b04a1e3a36ad2d4b6f58 +P 4e6a03d9e12b120d15946b025f97a97697cb8e8af543c238ffda220c9e3f28f4 +R 3e310c01c37c6ac62b74a767e914605e U drh -Z 906adb059f738e34206863c58e96feb3 +Z 061c837491d90260f4d8f777c55b50b5 diff --git a/manifest.uuid b/manifest.uuid index 4d805efd7a..611148833a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4e6a03d9e12b120d15946b025f97a97697cb8e8af543c238ffda220c9e3f28f4 \ No newline at end of file +2aa22509e7c8a1f09b16e4544c95d0b77503daed1f83106ccc18dee8bd9487a4 \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 48e21e175b..97294c3f81 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -114,8 +114,8 @@ extern "C" { ** system
    . ^The SQLITE_SOURCE_ID macro evaluates to ** a string which identifies a particular check-in of SQLite ** within its configuration management system. ^The SQLITE_SOURCE_ID -** string contains the date and time of the check-in (UTC) and an SHA1 -** hash of the entire source tree. +** string contains the date and time of the check-in (UTC) and a SHA1 +** or SHA3-256 hash of the entire source tree. ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], From 978896e0eb0a27354e3a19c195718a9e2e7a13ca Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 20 Mar 2017 14:44:07 +0000 Subject: [PATCH 1443/1484] Fix the check.test script so that it works on Windows. FossilOrigin-Name: 8822eb5d790bf8d4302c3f2dc05ab672193b309fb11771c4b3eea8a77f37e299 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/check.test | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 5f21e2e7ce..ad0fdedb4c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Documentation\sfix:\s\sSQLITE_SOURCE_ID\sis\sa\snow\sa\sSHA3-256\shash. -D 2017-03-20T13:03:39.888 +C Fix\sthe\scheck.test\sscript\sso\sthat\sit\sworks\son\sWindows. +D 2017-03-20T14:44:07.253 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1faf9f06aadc9284c212dea7bbc7c0dea7e8337f0287c81001eff500912c790a @@ -582,7 +582,7 @@ F test/capi3d.test 485048dc5cd07bc68011e4917ad035ad6047ab82 F test/capi3e.test 3d49c01ef2a1a55f41d73cba2b23b5059ec460fe F test/cast.test 4c275cbdc8202d6f9c54a3596701719868ac7dc3 F test/cffault.test 9d6b20606afe712374952eec4f8fd74b1a8097ef -F test/check.test fb823c1aee9d5187b4a474f1728bb65f2a77303255e294e250a2328ab7e72832 +F test/check.test 33a698e8c63613449d85d624a38ef669bf20331daabebe3891c9405dd6df463a F test/close.test 83947daf3b700631f90f4850ddaab455be4af73d F test/closure01.test b1703ba40639cfc9b295cf478d70739415eec6a4 F test/coalesce.test cee0dccb9fbd2d494b77234bccf9dc6c6786eb91 @@ -1566,7 +1566,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 4e6a03d9e12b120d15946b025f97a97697cb8e8af543c238ffda220c9e3f28f4 -R 3e310c01c37c6ac62b74a767e914605e +P 2aa22509e7c8a1f09b16e4544c95d0b77503daed1f83106ccc18dee8bd9487a4 +R 2a38f53db76a379174ef41cee348ccde U drh -Z 061c837491d90260f4d8f777c55b50b5 +Z 993304dc90b274b690e8ef820df2c963 diff --git a/manifest.uuid b/manifest.uuid index 611148833a..83f96a2ae7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2aa22509e7c8a1f09b16e4544c95d0b77503daed1f83106ccc18dee8bd9487a4 \ No newline at end of file +8822eb5d790bf8d4302c3f2dc05ab672193b309fb11771c4b3eea8a77f37e299 \ No newline at end of file diff --git a/test/check.test b/test/check.test index 2100aebb85..a6dbaa6171 100644 --- a/test/check.test +++ b/test/check.test @@ -484,6 +484,7 @@ do_catchsql_test 9.3 { # Integrity check on a VIEW with columns. # db close +db2 close forcedelete test.db sqlite3 db test.db do_execsql_test 10.1 { From 154cc746012d7fddd5436235e9f44ebd72a7ec6c Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 20 Mar 2017 15:11:40 +0000 Subject: [PATCH 1444/1484] Only run sync2.test on unix, as it depends on instrumentation in os_unix.c. FossilOrigin-Name: ecb9321e18dd72ea18d197c61c4d69500e9c4282c0eac67822cb40b2710a2815 --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/sync2.test | 4 ++++ 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index ad0fdedb4c..ed725cf65c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\scheck.test\sscript\sso\sthat\sit\sworks\son\sWindows. -D 2017-03-20T14:44:07.253 +C Only\srun\ssync2.test\son\sunix,\sas\sit\sdepends\son\sinstrumentation\sin\sos_unix.c. +D 2017-03-20T15:11:40.222 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1faf9f06aadc9284c212dea7bbc7c0dea7e8337f0287c81001eff500912c790a @@ -1165,7 +1165,7 @@ F test/subtype1.test 7fe09496352f97053af1437150751be2d0a0cae8 F test/superlock.test ec94f0556b6488d97f71c79f9061ae08d9ab8f12 F test/symlink.test c9ebe7330d228249e447038276bfc8a7b22f4849 F test/sync.test 2f84bdbc2b2df1fcb0220575b4b9f8cea94b7529 -F test/sync2.test 5ecf56be4c187a191253a1ec0786fe2df975dbf3dc0f0140cdf5d3690c90651c +F test/sync2.test c59ffd63e69854bf41ac407a9762ab5c128894b754253bf94db8a85d15de5444 F test/syscall.test f59ba4e25f7ba4a4c031026cc2ef8b6e4b4c639c F test/sysfault.test c9f2b0d8d677558f74de750c75e12a5454719d04 F test/tabfunc01.test 699251cb99651415218a891384510a685c7ab012 @@ -1566,7 +1566,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 2aa22509e7c8a1f09b16e4544c95d0b77503daed1f83106ccc18dee8bd9487a4 -R 2a38f53db76a379174ef41cee348ccde -U drh -Z 993304dc90b274b690e8ef820df2c963 +P 8822eb5d790bf8d4302c3f2dc05ab672193b309fb11771c4b3eea8a77f37e299 +R 9d22d8b55292860d95cad32e3b689bec +U dan +Z 532b84081e4fb29bc1e9b05f7d75c0ea diff --git a/manifest.uuid b/manifest.uuid index 83f96a2ae7..18bf16e13c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8822eb5d790bf8d4302c3f2dc05ab672193b309fb11771c4b3eea8a77f37e299 \ No newline at end of file +ecb9321e18dd72ea18d197c61c4d69500e9c4282c0eac67822cb40b2710a2815 \ No newline at end of file diff --git a/test/sync2.test b/test/sync2.test index 5f9c9aba93..1fd74ef89b 100644 --- a/test/sync2.test +++ b/test/sync2.test @@ -26,6 +26,10 @@ ifcapable !pager_pragmas||!attach { finish_test return } +if {$::tcl_platform(platform)!="unix"} { + finish_test + return +} proc execsql_sync {sql} { set s $::sqlite_sync_count From 7adbcffcb94531498c2e43b246c4e3e4368691ef Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 20 Mar 2017 15:29:28 +0000 Subject: [PATCH 1445/1484] Ensure that a "--" prefix is added to sqlite3_trace_v2() output for nested SQL statements. FossilOrigin-Name: 673a7b67c4828acaea3baebea500ef1f8ae763588b0d9c9f2ad6ed5ceb3cfee2 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/vdbe.c | 6 +++++- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index ed725cf65c..6e74d950bd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Only\srun\ssync2.test\son\sunix,\sas\sit\sdepends\son\sinstrumentation\sin\sos_unix.c. -D 2017-03-20T15:11:40.222 +C Ensure\sthat\sa\s"--"\sprefix\sis\sadded\sto\ssqlite3_trace_v2()\soutput\sfor\snested\nSQL\sstatements. +D 2017-03-20T15:29:28.021 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1faf9f06aadc9284c212dea7bbc7c0dea7e8337f0287c81001eff500912c790a @@ -467,7 +467,7 @@ F src/update.c 456d4a4656f8a03c2abc88a51b19172197400e58 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c ca8440ede81e155d15cff7c101654f60b55a9ae6 F src/vacuum.c 1fe4555cd8c9b263afb85b5b4ee3a4a4181ad569 -F src/vdbe.c 3b4221473438a047d85839129c5e71eab80d8d19487c71e0ac6802fb330ae834 +F src/vdbe.c 89a12451405a17c6e8d39b5826acb6999f1283e4e43d2e83a7ac7c9a7094a86a F src/vdbe.h 59998ffd71d7caa8886bc78dafaf8caeccd4c13c F src/vdbeInt.h 4e4b15b2e1330e1636e4e01974eab2b0b985092f F src/vdbeapi.c 5b08d82592bcff4470601fe78aaabebd50837860 @@ -1566,7 +1566,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 8822eb5d790bf8d4302c3f2dc05ab672193b309fb11771c4b3eea8a77f37e299 -R 9d22d8b55292860d95cad32e3b689bec -U dan -Z 532b84081e4fb29bc1e9b05f7d75c0ea +P ecb9321e18dd72ea18d197c61c4d69500e9c4282c0eac67822cb40b2710a2815 +R 5262e66ba51f0f0c41b35ecdd4289055 +U drh +Z 6393fe64153a32f9de418b09796f1e18 diff --git a/manifest.uuid b/manifest.uuid index 18bf16e13c..ca8dc248ab 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ecb9321e18dd72ea18d197c61c4d69500e9c4282c0eac67822cb40b2710a2815 \ No newline at end of file +673a7b67c4828acaea3baebea500ef1f8ae763588b0d9c9f2ad6ed5ceb3cfee2 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 7eb2b6f6f7..93c20c0aaa 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -6950,7 +6950,11 @@ case OP_Init: { /* jump */ sqlite3_free(z); }else #endif - { + if( db->nVdbeExec>1 ){ + char *z = sqlite3MPrintf(db, "-- %s", zTrace); + (void)db->xTrace(SQLITE_TRACE_STMT, db->pTraceArg, p, z); + sqlite3DbFree(db, z); + }else{ (void)db->xTrace(SQLITE_TRACE_STMT, db->pTraceArg, p, zTrace); } } From 5b3a3b359a4f31b3776044e864f35557d5dcb2fb Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 20 Mar 2017 16:06:48 +0000 Subject: [PATCH 1446/1484] Do not run sync2.test as part of the "journaltest" permutation, as it uses "PRAGMA synchronous = off". FossilOrigin-Name: 285005a9bcb210bb2a9aa9fed6a19d4b78641a6e7622d469bd0d2a365b2c0735 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/test_journal.c | 3 +++ test/sync2.test | 2 +- 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 6e74d950bd..1c7dda125d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Ensure\sthat\sa\s"--"\sprefix\sis\sadded\sto\ssqlite3_trace_v2()\soutput\sfor\snested\nSQL\sstatements. -D 2017-03-20T15:29:28.021 +C Do\snot\srun\ssync2.test\sas\spart\sof\sthe\s"journaltest"\spermutation,\sas\sit\suses\n"PRAGMA\ssynchronous\s=\soff". +D 2017-03-20T16:06:48.281 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1faf9f06aadc9284c212dea7bbc7c0dea7e8337f0287c81001eff500912c790a @@ -435,7 +435,7 @@ F src/test_hexio.c 1d4469ca61ab202a1fcec6543f584d2407205e8d F src/test_init.c 4413c211a94b62157ca4c145b3f27c497f03c664 F src/test_intarray.c 988fc61cb0ff539f4172c0d95f15287c92516f64 F src/test_intarray.h f3b7672f5d1056eac563c0d6ea8480a660b1475c -F src/test_journal.c d3b83f2bcb7792c709e57abddc456a2b1818643a +F src/test_journal.c 619f2aa10e0d7a5f87c0f06825bc61dfce1c6b9c7f3ad990fb13de6c3b8874a3 F src/test_loadext.c 337056bae59f80b9eb00ba82088b39d0f4fe6dfd F src/test_malloc.c c05f6c40bd6c8bfe5f1718212f81fd5687f91766 F src/test_multiplex.c e054459f7633f3ff8ce1245da724f9a8be189e4e @@ -1165,7 +1165,7 @@ F test/subtype1.test 7fe09496352f97053af1437150751be2d0a0cae8 F test/superlock.test ec94f0556b6488d97f71c79f9061ae08d9ab8f12 F test/symlink.test c9ebe7330d228249e447038276bfc8a7b22f4849 F test/sync.test 2f84bdbc2b2df1fcb0220575b4b9f8cea94b7529 -F test/sync2.test c59ffd63e69854bf41ac407a9762ab5c128894b754253bf94db8a85d15de5444 +F test/sync2.test b028aa9ca0bb4793e86140f777c6b88dcc6741f7a918381662e53bc5f2b97c74 F test/syscall.test f59ba4e25f7ba4a4c031026cc2ef8b6e4b4c639c F test/sysfault.test c9f2b0d8d677558f74de750c75e12a5454719d04 F test/tabfunc01.test 699251cb99651415218a891384510a685c7ab012 @@ -1566,7 +1566,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ecb9321e18dd72ea18d197c61c4d69500e9c4282c0eac67822cb40b2710a2815 -R 5262e66ba51f0f0c41b35ecdd4289055 -U drh -Z 6393fe64153a32f9de418b09796f1e18 +P 673a7b67c4828acaea3baebea500ef1f8ae763588b0d9c9f2ad6ed5ceb3cfee2 +R 547057b8e0709a92c08d29e340a54617 +U dan +Z c38b0bcff9e9a77e6d2ca931cd7486d0 diff --git a/manifest.uuid b/manifest.uuid index ca8dc248ab..7f9fef5671 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -673a7b67c4828acaea3baebea500ef1f8ae763588b0d9c9f2ad6ed5ceb3cfee2 \ No newline at end of file +285005a9bcb210bb2a9aa9fed6a19d4b78641a6e7622d469bd0d2a365b2c0735 \ No newline at end of file diff --git a/src/test_journal.c b/src/test_journal.c index 4e63bccf76..8a449e888c 100644 --- a/src/test_journal.c +++ b/src/test_journal.c @@ -557,6 +557,9 @@ static int jtWrite( u32 pgno = (u32)(iOfst/p->nPagesize + 1); assert( (iAmt==1||iAmt==(int)p->nPagesize) && ((iOfst+iAmt)%p->nPagesize)==0 ); + /* The following assert() statements may fail if this layer is used + ** with a connection in "PRAGMA synchronous=off" mode. If they + ** fail with sync=normal or sync=full, this may indicate problem. */ assert( pgno<=p->nPage || p->nSync>0 ); assert( pgno>p->nPage || sqlite3BitvecTest(p->pWritable, pgno) ); } diff --git a/test/sync2.test b/test/sync2.test index 1fd74ef89b..a88e4bed32 100644 --- a/test/sync2.test +++ b/test/sync2.test @@ -26,7 +26,7 @@ ifcapable !pager_pragmas||!attach { finish_test return } -if {$::tcl_platform(platform)!="unix"} { +if {$::tcl_platform(platform)!="unix" || [permutation] == "journaltest"} { finish_test return } From 5f42995a0a51be942cbb9095829767b175da0a87 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 20 Mar 2017 16:34:18 +0000 Subject: [PATCH 1447/1484] Avoid the possibility of signed integer overflow with oversized precisions in %d conversions in the printf() implementation. FossilOrigin-Name: ef3a7c877a7549b351aafd983cfa96c863eb2641b6218bdd5cb563f659f879d8 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/printf.c | 5 +++-- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 1c7dda125d..5c8fe10828 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Do\snot\srun\ssync2.test\sas\spart\sof\sthe\s"journaltest"\spermutation,\sas\sit\suses\n"PRAGMA\ssynchronous\s=\soff". -D 2017-03-20T16:06:48.281 +C Avoid\sthe\spossibility\sof\ssigned\sinteger\soverflow\swith\soversized\sprecisions\nin\s%d\sconversions\sin\sthe\sprintf()\simplementation. +D 2017-03-20T16:34:18.983 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1faf9f06aadc9284c212dea7bbc7c0dea7e8337f0287c81001eff500912c790a @@ -396,7 +396,7 @@ F src/pcache1.c e3967219b2a92b9edcb9324a4ba75009090d3953 F src/pragma.c 2b244434e76c7075edbcfd9e4d634899af0944ff01183b126d4671f7407c2368 F src/pragma.h c9c763958fec92b04125571472c9500b351c5f7f F src/prepare.c b1140c3d0cf59bc85ace00ce363153041b424b7a -F src/printf.c 67427bbee66d891fc6f6f5aada857e9cdb368c1c +F src/printf.c 8757834f1b54dae512fb25eb1acc8e94a0d15dd2290b58f2563f65973265adb2 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 3e518b962d932a997fae373366880fc028c75706 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac @@ -1566,7 +1566,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 673a7b67c4828acaea3baebea500ef1f8ae763588b0d9c9f2ad6ed5ceb3cfee2 -R 547057b8e0709a92c08d29e340a54617 -U dan -Z c38b0bcff9e9a77e6d2ca931cd7486d0 +P 285005a9bcb210bb2a9aa9fed6a19d4b78641a6e7622d469bd0d2a365b2c0735 +R d28630b090e29d249202016ad6a6d827 +U drh +Z dd88d1a97157edc79245fb3d73eca0b6 diff --git a/manifest.uuid b/manifest.uuid index 7f9fef5671..68447cc550 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -285005a9bcb210bb2a9aa9fed6a19d4b78641a6e7622d469bd0d2a365b2c0735 \ No newline at end of file +ef3a7c877a7549b351aafd983cfa96c863eb2641b6218bdd5cb563f659f879d8 \ No newline at end of file diff --git a/src/printf.c b/src/printf.c index 241338b266..a14e658875 100644 --- a/src/printf.c +++ b/src/printf.c @@ -400,12 +400,13 @@ void sqlite3VXPrintf( nOut = etBUFSIZE; zOut = buf; }else{ - nOut = precision + 10 + precision/3; - zOut = zExtra = sqlite3Malloc( nOut ); + u64 n = (u64)precision + 10 + precision/3; + zOut = zExtra = sqlite3Malloc( n ); if( zOut==0 ){ setStrAccumError(pAccum, STRACCUM_NOMEM); return; } + nOut = (int)n; } bufpt = &zOut[nOut-1]; if( xtype==etORDINAL ){ From 920c83f18fb8cd749774a63ce1a062d07ff56220 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 20 Mar 2017 18:53:32 +0000 Subject: [PATCH 1448/1484] Fix some problems in fts3 found by address-sanitizer. FossilOrigin-Name: 16a8e84fa7f67a467f824bdd7f72cbd6a6e95dab8cc7aa1e0e751720b98f3e31 --- ext/fts3/fts3.c | 5 +++-- ext/fts3/fts3_unicode.c | 26 +++++++++++++------------- ext/fts3/fts3_unicode2.c | 21 ++++++++++----------- ext/fts3/fts3_write.c | 5 ++++- ext/fts3/unicode/mkunicode.tcl | 2 +- manifest | 22 +++++++++++----------- manifest.uuid | 2 +- 7 files changed, 43 insertions(+), 40 deletions(-) diff --git a/ext/fts3/fts3.c b/ext/fts3/fts3.c index 8af62cda45..8abc338045 100644 --- a/ext/fts3/fts3.c +++ b/ext/fts3/fts3.c @@ -349,8 +349,9 @@ int sqlite3Fts3PutVarint(char *p, sqlite_int64 v){ ** Return the number of bytes read, or 0 on error. ** The value is stored in *v. */ -int sqlite3Fts3GetVarint(const char *p, sqlite_int64 *v){ - const char *pStart = p; +int sqlite3Fts3GetVarint(const char *pBuf, sqlite_int64 *v){ + const unsigned char *p = (const unsigned char*)pBuf; + const unsigned char *pStart = p; u32 a; u64 b; int shift; diff --git a/ext/fts3/fts3_unicode.c b/ext/fts3/fts3_unicode.c index 94fc27b5b4..dfb2680c50 100644 --- a/ext/fts3/fts3_unicode.c +++ b/ext/fts3/fts3_unicode.c @@ -136,16 +136,16 @@ static int unicodeAddExceptions( ){ const unsigned char *z = (const unsigned char *)zIn; const unsigned char *zTerm = &z[nIn]; - int iCode; + unsigned int iCode; int nEntry = 0; assert( bAlnum==0 || bAlnum==1 ); while( zi; j--) aNew[j] = aNew[j-1]; - aNew[i] = iCode; + aNew[i] = (int)iCode; nNew++; } } @@ -318,7 +318,7 @@ static int unicodeNext( ){ unicode_cursor *pCsr = (unicode_cursor *)pC; unicode_tokenizer *p = ((unicode_tokenizer *)pCsr->base.pTokenizer); - int iCode = 0; + unsigned int iCode = 0; char *zOut; const unsigned char *z = &pCsr->aInput[pCsr->iOff]; const unsigned char *zStart = z; @@ -330,7 +330,7 @@ static int unicodeNext( ** the input. */ while( z=zTerm ) return SQLITE_DONE; @@ -350,7 +350,7 @@ static int unicodeNext( /* Write the folded case of the last character read to the output */ zEnd = z; - iOut = sqlite3FtsUnicodeFold(iCode, p->bRemoveDiacritic); + iOut = sqlite3FtsUnicodeFold((int)iCode, p->bRemoveDiacritic); if( iOut ){ WRITE_UTF8(zOut, iOut); } @@ -358,8 +358,8 @@ static int unicodeNext( /* If the cursor is not at EOF, read the next character */ if( z>=zTerm ) break; READ_UTF8(z, zTerm, iCode); - }while( unicodeIsAlnum(p, iCode) - || sqlite3FtsUnicodeIsdiacritic(iCode) + }while( unicodeIsAlnum(p, (int)iCode) + || sqlite3FtsUnicodeIsdiacritic((int)iCode) ); /* Set the output variables and return. */ diff --git a/ext/fts3/fts3_unicode2.c b/ext/fts3/fts3_unicode2.c index 20b7a25dbf..da7251ed0c 100644 --- a/ext/fts3/fts3_unicode2.c +++ b/ext/fts3/fts3_unicode2.c @@ -127,9 +127,9 @@ int sqlite3FtsUnicodeIsalnum(int c){ 0xFFFFFFFF, 0xFC00FFFF, 0xF8000001, 0xF8000001, }; - if( c<128 ){ - return ( (aAscii[c >> 5] & (1 << (c & 0x001F)))==0 ); - }else if( c<(1<<22) ){ + if( (unsigned int)c<128 ){ + return ( (aAscii[c >> 5] & ((unsigned int)1 << (c & 0x001F)))==0 ); + }else if( (unsigned int)c<(1<<22) ){ unsigned int key = (((unsigned int)c)<<10) | 0x000003FF; int iRes = 0; int iHi = sizeof(aEntry)/sizeof(aEntry[0]) - 1; @@ -322,16 +322,17 @@ int sqlite3FtsUnicodeFold(int c, int bRemoveDiacritic){ int ret = c; - assert( c>=0 ); assert( sizeof(unsigned short)==2 && sizeof(unsigned char)==1 ); if( c<128 ){ if( c>='A' && c<='Z' ) ret = c + ('a' - 'A'); }else if( c<65536 ){ + const struct TableEntry *p; int iHi = sizeof(aEntry)/sizeof(aEntry[0]) - 1; int iLo = 0; int iRes = -1; + assert( c>aEntry[0].iCode ); while( iHi>=iLo ){ int iTest = (iHi + iLo) / 2; int cmp = (c - aEntry[iTest].iCode); @@ -342,14 +343,12 @@ int sqlite3FtsUnicodeFold(int c, int bRemoveDiacritic){ iHi = iTest-1; } } - assert( iRes<0 || c>=aEntry[iRes].iCode ); - if( iRes>=0 ){ - const struct TableEntry *p = &aEntry[iRes]; - if( c<(p->iCode + p->nRange) && 0==(0x01 & p->flags & (p->iCode ^ c)) ){ - ret = (c + (aiOff[p->flags>>1])) & 0x0000FFFF; - assert( ret>0 ); - } + assert( iRes>=0 && c>=aEntry[iRes].iCode ); + p = &aEntry[iRes]; + if( c<(p->iCode + p->nRange) && 0==(0x01 & p->flags & (p->iCode ^ c)) ){ + ret = (c + (aiOff[p->flags>>1])) & 0x0000FFFF; + assert( ret>0 ); } if( bRemoveDiacritic ) ret = remove_diacritic(ret); diff --git a/ext/fts3/fts3_write.c b/ext/fts3/fts3_write.c index 3ff481b0b0..d700c8403c 100644 --- a/ext/fts3/fts3_write.c +++ b/ext/fts3/fts3_write.c @@ -4956,11 +4956,14 @@ int sqlite3Fts3Incrmerge(Fts3Table *p, int nMerge, int nMin){ ** Convert the text beginning at *pz into an integer and return ** its value. Advance *pz to point to the first character past ** the integer. +** +** This function used for parameters to merge= and incrmerge= +** commands. */ static int fts3Getint(const char **pz){ const char *z = *pz; int i = 0; - while( (*z)>='0' && (*z)<='9' ) i = 10*i + *(z++) - '0'; + while( (*z)>='0' && (*z)<='9' && i<214748363 ) i = 10*i + *(z++) - '0'; *pz = z; return i; } diff --git a/ext/fts3/unicode/mkunicode.tcl b/ext/fts3/unicode/mkunicode.tcl index aafb4e9f9b..de89099122 100644 --- a/ext/fts3/unicode/mkunicode.tcl +++ b/ext/fts3/unicode/mkunicode.tcl @@ -227,7 +227,7 @@ proc print_isalnum {zFunc lRange} { an_print_ascii_bitmap $lRange puts { if( (unsigned int)c<128 ){ - return ( (aAscii[c >> 5] & (1 << (c & 0x001F)))==0 ); + return ( (aAscii[c >> 5] & ((unsigned int)1 << (c & 0x001F)))==0 ); }else if( (unsigned int)c<(1<<22) ){ unsigned int key = (((unsigned int)c)<<10) | 0x000003FF; int iRes = 0; diff --git a/manifest b/manifest index 5c8fe10828..882e3cc273 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sthe\spossibility\sof\ssigned\sinteger\soverflow\swith\soversized\sprecisions\nin\s%d\sconversions\sin\sthe\sprintf()\simplementation. -D 2017-03-20T16:34:18.983 +C Fix\ssome\sproblems\sin\sfts3\sfound\sby\saddress-sanitizer. +D 2017-03-20T18:53:32.346 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1faf9f06aadc9284c212dea7bbc7c0dea7e8337f0287c81001eff500912c790a @@ -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 95c7041ea75d82d2d9a4cd058904ba889751f5b8 +F ext/fts3/fts3.c df964dbcc7bb97b8871c53866eb6c4e9c05c0d8af42038fa6439fb411260dd2e F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe F ext/fts3/fts3Int.h eb2502000148e80913b965db3e59f29251266d0a F ext/fts3/fts3_aux.c 9edc3655fcb287f0467d0a4b886a01c6185fe9f1 @@ -86,15 +86,15 @@ F ext/fts3/fts3_tokenize_vtab.c a27593ab19657166f6fa5ec073b678cc29a75860 F ext/fts3/fts3_tokenizer.c a22bf311a71f3efa9d7012d8cc48fc9b0f3dace7 F ext/fts3/fts3_tokenizer.h 64c6ef6c5272c51ebe60fc607a896e84288fcbc3 F ext/fts3/fts3_tokenizer1.c 5c98225a53705e5ee34824087478cf477bdb7004 -F ext/fts3/fts3_unicode.c a93f5edc0aff44ef8b06d7cb55b52026541ca145 -F ext/fts3/fts3_unicode2.c c3d01968d497bd7001e7dc774ba75b372738c057 -F ext/fts3/fts3_write.c c3863f23b6b4623c8b9d5cf31c12ce4469f78ca9 +F ext/fts3/fts3_unicode.c 525a3bd9a7564603c5c061b7de55403a565307758a94600e8a2f6b00d1c40d9d +F ext/fts3/fts3_unicode2.c cc04fc672bfd42b1e650398cb0bf71f64f9aae032cfe75bbcfe75b9cf966029c +F ext/fts3/fts3_write.c a51d48d646974ee2fb4b17fcd5da0416a5759a32dcacc2cce2ba00d5a767848e F ext/fts3/fts3speed.tcl b54caf6a18d38174f1a6e84219950d85e98bb1e9 F ext/fts3/mkfts3amal.tcl 252ecb7fe6467854f2aa237bf2c390b74e71f100 F ext/fts3/tool/fts3view.c 202801a2056995b763864d60c2dee744d46f1677 F ext/fts3/unicode/CaseFolding.txt 8c678ca52ecc95e16bc7afc2dbf6fc9ffa05db8c F ext/fts3/unicode/UnicodeData.txt cd07314edb62d49fde34debdaf92fa2aa69011e7 -F ext/fts3/unicode/mkunicode.tcl 2debed3f582d77b3fdd0b8830880250021571fd8 +F ext/fts3/unicode/mkunicode.tcl ab0543a3b2399092ea2dd75df1bef333405b0d7f6b8c4951a0fbb60e780cb69f F ext/fts3/unicode/parseunicode.tcl da577d1384810fb4e2b209bf3313074353193e95 F ext/fts5/extract_api_docs.tcl a36e54ec777172ddd3f9a88daf593b00848368e0 F ext/fts5/fts5.h 62f3e33ceeb9a428db139f9c012186b371da1cc7 @@ -1566,7 +1566,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 285005a9bcb210bb2a9aa9fed6a19d4b78641a6e7622d469bd0d2a365b2c0735 -R d28630b090e29d249202016ad6a6d827 -U drh -Z dd88d1a97157edc79245fb3d73eca0b6 +P ef3a7c877a7549b351aafd983cfa96c863eb2641b6218bdd5cb563f659f879d8 +R 646761e50bb7679c40f23d2ddea8c902 +U dan +Z f4376c790f10e78888f80aca2d0f09f6 diff --git a/manifest.uuid b/manifest.uuid index 68447cc550..c4f06f22c9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ef3a7c877a7549b351aafd983cfa96c863eb2641b6218bdd5cb563f659f879d8 \ No newline at end of file +16a8e84fa7f67a467f824bdd7f72cbd6a6e95dab8cc7aa1e0e751720b98f3e31 \ No newline at end of file From 6b904f5e01bb2737b093b154b6ab39b393daa0f6 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 20 Mar 2017 19:26:27 +0000 Subject: [PATCH 1449/1484] Avoid a technically undefined right-shift of a signed value in rtree.c. FossilOrigin-Name: a144875fe44ff3a30bab299d50b7dbec2ee21f8c73e692a71ee1f7c54b5f0c76 --- ext/rtree/rtree.c | 18 +++++++++--------- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/ext/rtree/rtree.c b/ext/rtree/rtree.c index 63838a4eef..42f08a9628 100644 --- a/ext/rtree/rtree.c +++ b/ext/rtree/rtree.c @@ -458,15 +458,15 @@ static i64 readInt64(u8 *p){ memcpy(&x, p, 8); return x; #else - return ( - (((i64)p[0]) << 56) + - (((i64)p[1]) << 48) + - (((i64)p[2]) << 40) + - (((i64)p[3]) << 32) + - (((i64)p[4]) << 24) + - (((i64)p[5]) << 16) + - (((i64)p[6]) << 8) + - (((i64)p[7]) << 0) + return (i64)( + (((u64)p[0]) << 56) + + (((u64)p[1]) << 48) + + (((u64)p[2]) << 40) + + (((u64)p[3]) << 32) + + (((u64)p[4]) << 24) + + (((u64)p[5]) << 16) + + (((u64)p[6]) << 8) + + (((u64)p[7]) << 0) ); #endif } diff --git a/manifest b/manifest index 882e3cc273..180628583d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\ssome\sproblems\sin\sfts3\sfound\sby\saddress-sanitizer. -D 2017-03-20T18:53:32.346 +C Avoid\sa\stechnically\sundefined\sright-shift\sof\sa\ssigned\svalue\sin\srtree.c. +D 2017-03-20T19:26:27.669 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1faf9f06aadc9284c212dea7bbc7c0dea7e8337f0287c81001eff500912c790a @@ -270,7 +270,7 @@ F ext/rbu/sqlite3rbu.c 2a89efba9eeba8e6c89a498dc195e8efbdde2694 F ext/rbu/sqlite3rbu.h 6fb6294c34a9ca93b5894a33bca530c6f08decba F ext/rbu/test_rbu.c 5aa22616afac6f71ebd3d9bc9bf1006cfabcca88 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 -F ext/rtree/rtree.c 3f3a595dba485e340246fa2c8ba330a6b9768b00 +F ext/rtree/rtree.c 0acd285bfacc347579a5df9fe947212fb99e2775a40c43f027c3a16936c58e7e F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e F ext/rtree/rtree1.test 42dadfc7b44a436cd74a1bebc0b9b689e4eaf7ec F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba @@ -1566,7 +1566,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ef3a7c877a7549b351aafd983cfa96c863eb2641b6218bdd5cb563f659f879d8 -R 646761e50bb7679c40f23d2ddea8c902 +P 16a8e84fa7f67a467f824bdd7f72cbd6a6e95dab8cc7aa1e0e751720b98f3e31 +R 3866887b2e2a6895d2c139049fd577ac U dan -Z f4376c790f10e78888f80aca2d0f09f6 +Z 940954dc69a4e0a1139a0110a41a8583 diff --git a/manifest.uuid b/manifest.uuid index c4f06f22c9..97c8d21348 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -16a8e84fa7f67a467f824bdd7f72cbd6a6e95dab8cc7aa1e0e751720b98f3e31 \ No newline at end of file +a144875fe44ff3a30bab299d50b7dbec2ee21f8c73e692a71ee1f7c54b5f0c76 \ No newline at end of file From 74869e5e52c56bab031e190061afd5d531d88f36 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 20 Mar 2017 19:35:30 +0000 Subject: [PATCH 1450/1484] Avoid passing NULL as the second argument to memcpy() in fts3. FossilOrigin-Name: 49b93d972de9649abfd6235b65dda1c9d468956671e50704afde6181ffa56dea --- ext/fts3/fts3.c | 4 +++- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/ext/fts3/fts3.c b/ext/fts3/fts3.c index 8abc338045..6f059bc95d 100644 --- a/ext/fts3/fts3.c +++ b/ext/fts3/fts3.c @@ -1398,7 +1398,9 @@ static int fts3InitVtab( char *z; int n = 0; z = (char *)sqlite3Fts3NextToken(aCol[iCol], &n); - memcpy(zCsr, z, n); + if( n>0 ){ + memcpy(zCsr, z, n); + } zCsr[n] = '\0'; sqlite3Fts3Dequote(zCsr); p->azColumn[iCol] = zCsr; diff --git a/manifest b/manifest index 180628583d..9fbd812c57 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sa\stechnically\sundefined\sright-shift\sof\sa\ssigned\svalue\sin\srtree.c. -D 2017-03-20T19:26:27.669 +C Avoid\spassing\sNULL\sas\sthe\ssecond\sargument\sto\smemcpy()\sin\sfts3. +D 2017-03-20T19:35:30.725 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1faf9f06aadc9284c212dea7bbc7c0dea7e8337f0287c81001eff500912c790a @@ -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 df964dbcc7bb97b8871c53866eb6c4e9c05c0d8af42038fa6439fb411260dd2e +F ext/fts3/fts3.c f0d5de1bc2155ba7cd7c0c1a751779a3a8857fa34d5c12f3b233a23fa2e79ea2 F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe F ext/fts3/fts3Int.h eb2502000148e80913b965db3e59f29251266d0a F ext/fts3/fts3_aux.c 9edc3655fcb287f0467d0a4b886a01c6185fe9f1 @@ -1566,7 +1566,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 16a8e84fa7f67a467f824bdd7f72cbd6a6e95dab8cc7aa1e0e751720b98f3e31 -R 3866887b2e2a6895d2c139049fd577ac +P a144875fe44ff3a30bab299d50b7dbec2ee21f8c73e692a71ee1f7c54b5f0c76 +R bd3c42588251ebb6d9905386e3af9ca1 U dan -Z 940954dc69a4e0a1139a0110a41a8583 +Z a06ad4d721634b829ae52c87102c1626 diff --git a/manifest.uuid b/manifest.uuid index 97c8d21348..cd1cb6be7f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a144875fe44ff3a30bab299d50b7dbec2ee21f8c73e692a71ee1f7c54b5f0c76 \ No newline at end of file +49b93d972de9649abfd6235b65dda1c9d468956671e50704afde6181ffa56dea \ No newline at end of file From 16f0582c1b0f059e27df99bf3648d525a3d76dc7 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 20 Mar 2017 20:42:21 +0000 Subject: [PATCH 1451/1484] Fix the fuzzcheck program so that it can create new databases again. FossilOrigin-Name: 021e8874a7d1bb94debae3ae04f83056a8573148ffc872cd76a186a2d22d0296 --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/fuzzcheck.c | 4 +++- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 9fbd812c57..6ce523a998 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\spassing\sNULL\sas\sthe\ssecond\sargument\sto\smemcpy()\sin\sfts3. -D 2017-03-20T19:35:30.725 +C Fix\sthe\sfuzzcheck\sprogram\sso\sthat\sit\scan\screate\snew\sdatabases\sagain. +D 2017-03-20T20:42:21.876 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1faf9f06aadc9284c212dea7bbc7c0dea7e8337f0287c81001eff500912c790a @@ -833,7 +833,7 @@ F test/fuzz2.test 76dc35b32b6d6f965259508508abce75a6c4d7e1 F test/fuzz3.test b47377143f0c80f91ed29d722861077ff34415d5 F test/fuzz_common.tcl a87dfbb88c2a6b08a38e9a070dabd129e617b45b F test/fuzz_malloc.test 328f70aaca63adf29b4c6f06505ed0cf57ca7c26 -F test/fuzzcheck.c a87e6067a8d19844bade916841cb76150ecf24a2 +F test/fuzzcheck.c 0cfce51bd5b0b7ab5d2d2ecaf9a82d5962f90852348be6bf5f05a1fb2aaf40e0 F test/fuzzdata1.db 7ee3227bad0e7ccdeb08a9e6822916777073c664 F test/fuzzdata2.db f03a420d3b822cc82e4f894ca957618fbe9c4973 F test/fuzzdata3.db c6586d3e3cef0fbc18108f9bb649aa77bfc38aba @@ -1566,7 +1566,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a144875fe44ff3a30bab299d50b7dbec2ee21f8c73e692a71ee1f7c54b5f0c76 -R bd3c42588251ebb6d9905386e3af9ca1 -U dan -Z a06ad4d721634b829ae52c87102c1626 +P 49b93d972de9649abfd6235b65dda1c9d468956671e50704afde6181ffa56dea +R 26d368e43476d2b80e7af8c6d59964fd +U drh +Z 95628c590b2b14daadfe6003e34f6d94 diff --git a/manifest.uuid b/manifest.uuid index cd1cb6be7f..db25339f3b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -49b93d972de9649abfd6235b65dda1c9d468956671e50704afde6181ffa56dea \ No newline at end of file +021e8874a7d1bb94debae3ae04f83056a8573148ffc872cd76a186a2d22d0296 \ No newline at end of file diff --git a/test/fuzzcheck.c b/test/fuzzcheck.c index 75d519566f..2efe68440a 100644 --- a/test/fuzzcheck.c +++ b/test/fuzzcheck.c @@ -972,7 +972,7 @@ int main(int argc, char **argv){ /* Process each source database separately */ for(iSrcDb=0; iSrcDbzName); + SQLITE_OPEN_READWRITE, pDfltVfs->zName); if( rc ){ fatalError("cannot open source database %s - %s", azSrcDb[iSrcDb], sqlite3_errmsg(db)); @@ -1047,6 +1047,8 @@ int main(int argc, char **argv){ sqlite3_close(db); return 0; } + rc = sqlite3_exec(db, "PRAGMA query_only=1;", 0, 0, 0); + if( rc ) fatalError("cannot set database to query-only"); if( zExpDb!=0 || zExpSql!=0 ){ sqlite3_create_function(db, "writefile", 2, SQLITE_UTF8, 0, writefileFunc, 0, 0); From 174f8553068e086e2b7b62bee89d3a8eee6f087a Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 20 Mar 2017 22:58:27 +0000 Subject: [PATCH 1452/1484] Add the --native-malloc option to fuzzcheck. Fix ossfuzz.c and fuzzcheck.c so that they both deallocate the temp_store_directory before closing. FossilOrigin-Name: 0dd18ec882bb28a87629d6d8dfeb5ea5d82833634b3781a7d14b917272c4dfa0 --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/fuzzcheck.c | 22 ++++++++++++++++++---- test/ossfuzz.c | 1 + 4 files changed, 27 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 6ce523a998..e16247c45b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\sfuzzcheck\sprogram\sso\sthat\sit\scan\screate\snew\sdatabases\sagain. -D 2017-03-20T20:42:21.876 +C Add\sthe\s--native-malloc\soption\sto\sfuzzcheck.\s\sFix\sossfuzz.c\sand\sfuzzcheck.c\nso\sthat\sthey\sboth\sdeallocate\sthe\stemp_store_directory\sbefore\sclosing. +D 2017-03-20T22:58:27.453 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1faf9f06aadc9284c212dea7bbc7c0dea7e8337f0287c81001eff500912c790a @@ -833,7 +833,7 @@ F test/fuzz2.test 76dc35b32b6d6f965259508508abce75a6c4d7e1 F test/fuzz3.test b47377143f0c80f91ed29d722861077ff34415d5 F test/fuzz_common.tcl a87dfbb88c2a6b08a38e9a070dabd129e617b45b F test/fuzz_malloc.test 328f70aaca63adf29b4c6f06505ed0cf57ca7c26 -F test/fuzzcheck.c 0cfce51bd5b0b7ab5d2d2ecaf9a82d5962f90852348be6bf5f05a1fb2aaf40e0 +F test/fuzzcheck.c 2152602232c96d9c790eff3013e1369ce59de3203fa0b75bc613531448454e61 F test/fuzzdata1.db 7ee3227bad0e7ccdeb08a9e6822916777073c664 F test/fuzzdata2.db f03a420d3b822cc82e4f894ca957618fbe9c4973 F test/fuzzdata3.db c6586d3e3cef0fbc18108f9bb649aa77bfc38aba @@ -1009,7 +1009,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 8c4d62e156352ecb97eb868fcff20d828a279af67a1c1310779f63464d6f009f +F test/ossfuzz.c f5abed3177f719df3c3109901fcdd26b9fb7f581c8da50fc26f3a81ddfb2c2ae F test/ossshell.c 296ab63067841bd1b1e97b46a0b2af48ee7f69d50d1a723008bee12dd7122622 F test/ovfl.test 199c482696defceacee8c8e0e0ef36da62726b2f F test/pager1.test 841868017e9dd3cb459b8d78862091a7d9cff21d @@ -1566,7 +1566,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 49b93d972de9649abfd6235b65dda1c9d468956671e50704afde6181ffa56dea -R 26d368e43476d2b80e7af8c6d59964fd +P 021e8874a7d1bb94debae3ae04f83056a8573148ffc872cd76a186a2d22d0296 +R 694ec38d9cd79a3b1927a92dd170b999 U drh -Z 95628c590b2b14daadfe6003e34f6d94 +Z 6cb1e54838f3a51f8b4c2a137da28ce9 diff --git a/manifest.uuid b/manifest.uuid index db25339f3b..ad7fcf00b1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -021e8874a7d1bb94debae3ae04f83056a8573148ffc872cd76a186a2d22d0296 \ No newline at end of file +0dd18ec882bb28a87629d6d8dfeb5ea5d82833634b3781a7d14b917272c4dfa0 \ No newline at end of file diff --git a/test/fuzzcheck.c b/test/fuzzcheck.c index 2efe68440a..fd72273f34 100644 --- a/test/fuzzcheck.c +++ b/test/fuzzcheck.c @@ -805,6 +805,7 @@ static void showHelp(void){ " --load-db ARGS... Load template databases from files into SOURCE_DB\n" " -m TEXT Add a description to the database\n" " --native-vfs Use the native VFS for initially empty database files\n" +" --native-malloc Turn off MEMSYS3/5 and Lookaside\n" " --oss-fuzz Enable OSS-FUZZ testing\n" " --prng-seed N Seed value for the PRGN inside of SQLite\n" " --rebuild Rebuild and vacuum the database file\n" @@ -851,6 +852,7 @@ int main(int argc, char **argv){ void *pHeap = 0; /* Heap for use by SQLite */ int ossFuzz = 0; /* enable OSS-FUZZ testing */ int ossFuzzThisDb = 0; /* ossFuzz value for this particular database */ + int nativeMalloc = 0; /* Turn off MEMSYS3/5 and lookaside if true */ sqlite3_vfs *pDfltVfs; /* The default VFS */ iBegin = timeOfDay(); @@ -911,6 +913,9 @@ int main(int argc, char **argv){ if( i>=argc-1 ) fatalError("missing arguments on %s", argv[i]); zMsg = argv[++i]; }else + if( strcmp(z,"native-malloc")==0 ){ + nativeMalloc = 1; + }else if( strcmp(z,"native-vfs")==0 ){ nativeFlag = 1; }else @@ -1013,7 +1018,7 @@ int main(int argc, char **argv){ ossFuzzThisDb = sqlite3_column_int(pStmt,1); if( verboseFlag ) printf("Config: oss-fuzz=%d\n", ossFuzzThisDb); } - if( strcmp(zName, "limit-mem")==0 ){ + if( strcmp(zName, "limit-mem")==0 && !nativeMalloc ){ #if !defined(SQLITE_ENABLE_MEMSYS3) && !defined(SQLITE_ENABLE_MEMSYS5) fatalError("the limit-mem option requires -DSQLITE_ENABLE_MEMSYS5" " or _MEMSYS3"); @@ -1143,14 +1148,19 @@ int main(int argc, char **argv){ } /* Limit available memory, if requested */ - if( nMemThisDb>0 ){ - sqlite3_shutdown(); + sqlite3_shutdown(); + if( nMemThisDb>0 && !nativeMalloc ){ pHeap = realloc(pHeap, nMemThisDb); if( pHeap==0 ){ fatalError("failed to allocate %d bytes of heap memory", nMem); } sqlite3_config(SQLITE_CONFIG_HEAP, pHeap, nMemThisDb, 128); } + + /* Disable lookaside with the --native-malloc option */ + if( nativeMalloc ){ + sqlite3_config(SQLITE_CONFIG_LOOKASIDE, 0, 0); + } /* Reset the in-memory virtual filesystem */ formatVfs(); @@ -1207,9 +1217,13 @@ int main(int argc, char **argv){ runSql(db, (char*)pSql->a, runFlags); }while( timeoutTest ); setAlarm(0); + sqlite3_exec(db, "PRAGMA temp_store_directory=''", 0, 0, 0); sqlite3_close(db); } - if( sqlite3_memory_used()>0 ) fatalError("memory leak"); + if( sqlite3_memory_used()>0 ){ + fatalError("memory leak: %lld bytes outstanding", + sqlite3_memory_used()); + } reformatVfs(); nTest++; g.zTestName[0] = 0; diff --git a/test/ossfuzz.c b/test/ossfuzz.c index 0c2b1320e4..51983548b9 100644 --- a/test/ossfuzz.c +++ b/test/ossfuzz.c @@ -145,6 +145,7 @@ int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { /* Cleanup and return */ sqlite3_free(zErrMsg); sqlite3_free(zSql); + sqlite3_exec(cx.db, "PRAGMA temp_store_directory=''", 0, 0, 0); sqlite3_close(cx.db); if( mDebug & FUZZ_SHOW_MAX_DELAY ){ From a14b7e02e97aecc5712d826e1e7936e6a9219dd2 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 21 Mar 2017 10:45:38 +0000 Subject: [PATCH 1453/1484] Do not run sync2.test as part of the "inmemory_journal" permutation. FossilOrigin-Name: 9f680bc7c47f8391adba6ea2b4b2cb6a5a041e22753543d5224da6656c3762fe --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/sync2.test | 5 ++++- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index e16247c45b..f6d020fb32 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\s--native-malloc\soption\sto\sfuzzcheck.\s\sFix\sossfuzz.c\sand\sfuzzcheck.c\nso\sthat\sthey\sboth\sdeallocate\sthe\stemp_store_directory\sbefore\sclosing. -D 2017-03-20T22:58:27.453 +C Do\snot\srun\ssync2.test\sas\spart\sof\sthe\s"inmemory_journal"\spermutation. +D 2017-03-21T10:45:38.479 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1faf9f06aadc9284c212dea7bbc7c0dea7e8337f0287c81001eff500912c790a @@ -1165,7 +1165,7 @@ F test/subtype1.test 7fe09496352f97053af1437150751be2d0a0cae8 F test/superlock.test ec94f0556b6488d97f71c79f9061ae08d9ab8f12 F test/symlink.test c9ebe7330d228249e447038276bfc8a7b22f4849 F test/sync.test 2f84bdbc2b2df1fcb0220575b4b9f8cea94b7529 -F test/sync2.test b028aa9ca0bb4793e86140f777c6b88dcc6741f7a918381662e53bc5f2b97c74 +F test/sync2.test 29af00fe9e468a1e20315d1edced8f8a32ac156df983ae9b53802e7d472675d5 F test/syscall.test f59ba4e25f7ba4a4c031026cc2ef8b6e4b4c639c F test/sysfault.test c9f2b0d8d677558f74de750c75e12a5454719d04 F test/tabfunc01.test 699251cb99651415218a891384510a685c7ab012 @@ -1566,7 +1566,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 021e8874a7d1bb94debae3ae04f83056a8573148ffc872cd76a186a2d22d0296 -R 694ec38d9cd79a3b1927a92dd170b999 -U drh -Z 6cb1e54838f3a51f8b4c2a137da28ce9 +P 0dd18ec882bb28a87629d6d8dfeb5ea5d82833634b3781a7d14b917272c4dfa0 +R 8db91ad0b42e6ccb8a27a4c262ebc723 +U dan +Z 688065de24febc90cf37734d50aa7e01 diff --git a/manifest.uuid b/manifest.uuid index ad7fcf00b1..f7dfbdc10c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0dd18ec882bb28a87629d6d8dfeb5ea5d82833634b3781a7d14b917272c4dfa0 \ No newline at end of file +9f680bc7c47f8391adba6ea2b4b2cb6a5a041e22753543d5224da6656c3762fe \ No newline at end of file diff --git a/test/sync2.test b/test/sync2.test index a88e4bed32..4f6ed7754c 100644 --- a/test/sync2.test +++ b/test/sync2.test @@ -26,7 +26,10 @@ ifcapable !pager_pragmas||!attach { finish_test return } -if {$::tcl_platform(platform)!="unix" || [permutation] == "journaltest"} { +if {$::tcl_platform(platform)!="unix" + || [permutation] == "journaltest" + || [permutation] == "inmemory_journal" +} { finish_test return } From 119fc11eb0b746495df92698fce9696591293519 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 21 Mar 2017 17:19:31 +0000 Subject: [PATCH 1454/1484] Add short script ext/fts3/tool/fts3cov.sh. To help measure test-coverage of fts3 source code. FossilOrigin-Name: ee9588e873ffebcaa177957950cbb14924e154c391ed7f687116065064ff11b0 --- ext/fts3/tool/fts3cov.sh | 16 ++++++++++++++++ manifest | 13 +++++++------ manifest.uuid | 2 +- test/permutations.test | 34 ++++++++++++++++++---------------- 4 files changed, 42 insertions(+), 23 deletions(-) create mode 100644 ext/fts3/tool/fts3cov.sh diff --git a/ext/fts3/tool/fts3cov.sh b/ext/fts3/tool/fts3cov.sh new file mode 100644 index 0000000000..b1f34dce76 --- /dev/null +++ b/ext/fts3/tool/fts3cov.sh @@ -0,0 +1,16 @@ +#!/bin/sh + +set -e + +srcdir=`dirname $(dirname $(dirname $(dirname $0)))` +./testfixture $srcdir/test/fts3.test --output=fts3cov-out.txt + +echo "" + +for f in `ls $srcdir/ext/fts3/*.c` +do + f=`basename $f` + echo -ne "$f: " + gcov -b $f | grep Taken | sed 's/Taken at least once://' +done + diff --git a/manifest b/manifest index f6d020fb32..ec8ad84599 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Do\snot\srun\ssync2.test\sas\spart\sof\sthe\s"inmemory_journal"\spermutation. -D 2017-03-21T10:45:38.479 +C Add\sshort\sscript\sext/fts3/tool/fts3cov.sh.\sTo\shelp\smeasure\stest-coverage\sof\nfts3\ssource\scode. +D 2017-03-21T17:19:31.218 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1faf9f06aadc9284c212dea7bbc7c0dea7e8337f0287c81001eff500912c790a @@ -91,6 +91,7 @@ F ext/fts3/fts3_unicode2.c cc04fc672bfd42b1e650398cb0bf71f64f9aae032cfe75bbcfe75 F ext/fts3/fts3_write.c a51d48d646974ee2fb4b17fcd5da0416a5759a32dcacc2cce2ba00d5a767848e F ext/fts3/fts3speed.tcl b54caf6a18d38174f1a6e84219950d85e98bb1e9 F ext/fts3/mkfts3amal.tcl 252ecb7fe6467854f2aa237bf2c390b74e71f100 +F ext/fts3/tool/fts3cov.sh c331d006359456cf6f8f953e37f2b9c7d568f3863f00bb5f7eb87fea4ac01b73 F ext/fts3/tool/fts3view.c 202801a2056995b763864d60c2dee744d46f1677 F ext/fts3/unicode/CaseFolding.txt 8c678ca52ecc95e16bc7afc2dbf6fc9ffa05db8c F ext/fts3/unicode/UnicodeData.txt cd07314edb62d49fde34debdaf92fa2aa69011e7 @@ -1025,7 +1026,7 @@ F test/parser1.test 391b9bf9a229547a129c61ac345ed1a6f5eb1854 F test/pcache.test c8acbedd3b6fd0f9a7ca887a83b11d24a007972b F test/pcache2.test af7f3deb1a819f77a6d0d81534e97d1cf62cd442 F test/percentile.test 4243af26b8f3f4555abe166f723715a1f74c77ff -F test/permutations.test 46ad98770d3c04ce2418cab2cc527647bfe961a7 +F test/permutations.test af720e7d139e7e5417341d0f0eef2b911c0b067852138dc2f5b6a451b5725118 F test/pragma.test 1e94755164a3a3264cd39836de4bebcb7809e5f8 F test/pragma2.test e5d5c176360c321344249354c0c16aec46214c9f F test/pragma3.test 14c12bc5352b1e100e0b6b44f371053a81ccf8ed @@ -1566,7 +1567,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 0dd18ec882bb28a87629d6d8dfeb5ea5d82833634b3781a7d14b917272c4dfa0 -R 8db91ad0b42e6ccb8a27a4c262ebc723 +P 9f680bc7c47f8391adba6ea2b4b2cb6a5a041e22753543d5224da6656c3762fe +R 6048d4479132e9b80b95aca588407d4c U dan -Z 688065de24febc90cf37734d50aa7e01 +Z d545083811aa9af855b84bbadd9a61dc diff --git a/manifest.uuid b/manifest.uuid index f7dfbdc10c..c60120ecbc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9f680bc7c47f8391adba6ea2b4b2cb6a5a041e22753543d5224da6656c3762fe \ No newline at end of file +ee9588e873ffebcaa177957950cbb14924e154c391ed7f687116065064ff11b0 \ No newline at end of file diff --git a/test/permutations.test b/test/permutations.test index 7f81dcbb27..628e7ba44e 100644 --- a/test/permutations.test +++ b/test/permutations.test @@ -247,22 +247,24 @@ test_suite "threads" -prefix "" -description { test_suite "fts3" -prefix "" -description { All FTS3 tests except fts3rnd.test. } -files { - fts3aa.test fts3ab.test fts3ac.test fts3ad.test fts3ae.test - fts3af.test fts3ag.test fts3ah.test fts3ai.test fts3aj.test - fts3ak.test fts3al.test fts3am.test fts3an.test fts3ao.test - fts3atoken.test fts3b.test fts3c.test fts3cov.test fts3d.test - fts3defer.test fts3defer2.test fts3e.test fts3expr.test fts3expr2.test - fts3expr3.test - fts3near.test fts3query.test fts3shared.test fts3snippet.test - fts3sort.test - fts3fault.test fts3malloc.test fts3matchinfo.test - fts3aux1.test fts3comp1.test fts3auto.test - fts4aa.test fts4content.test - fts3conf.test fts3prefix.test fts3fault2.test fts3corrupt.test - fts3corrupt2.test fts3first.test fts4langid.test fts4merge.test - fts4check.test fts4unicode.test fts4noti.test - fts3varint.test - fts4growth.test fts4growth2.test + fts3aa.test fts3ab.test fts3ac.test fts3ad.test + fts3ae.test fts3af.test fts3ag.test fts3ah.test + fts3ai.test fts3aj.test fts3ak.test fts3al.test + fts3am.test fts3an.test fts3ao.test fts3atoken.test + fts3auto.test fts3aux1.test fts3aux2.test fts3b.test + fts3comp1.test fts3conf.test fts3corrupt2.test fts3corrupt.test + fts3cov.test fts3c.test fts3defer2.test fts3defer3.test + fts3defer.test fts3drop.test fts3d.test fts3e.test + fts3expr2.test fts3expr3.test fts3expr4.test fts3expr5.test + fts3expr.test fts3fault2.test fts3fault.test fts3first.test + fts3join.test fts3malloc.test fts3matchinfo.test fts3near.test + fts3offsets.test fts3prefix2.test fts3prefix.test fts3query.test + fts3shared.test fts3snippet.test fts3sort.test fts3tok1.test + fts3tok_err.test fts3varint.test fts4aa.test fts4check.test + fts4content.test fts4docid.test fts4growth2.test fts4growth.test + fts4incr.test fts4langid.test fts4lastrowid.test fts4merge2.test + fts4merge4.test fts4merge.test fts4noti.test fts4onepass.test + fts4opt.test fts4unicode.test } test_suite "fts5" -prefix "" -description { From 49297c86d2f9db1944fd84d00f5cfbfa56fdb1bf Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 21 Mar 2017 18:56:52 +0000 Subject: [PATCH 1455/1484] Fix an incorrect assert in the ANALYZE logic for STAT4 on WITHOUT ROWID tables. FossilOrigin-Name: ad741976c8c29bcc94f9ea9ed7deb580bb00c8a81d1a7fba1a4e03849728433d --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/analyze.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index ec8ad84599..75a4357e21 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sshort\sscript\sext/fts3/tool/fts3cov.sh.\sTo\shelp\smeasure\stest-coverage\sof\nfts3\ssource\scode. -D 2017-03-21T17:19:31.218 +C Fix\san\sincorrect\sassert\sin\sthe\sANALYZE\slogic\sfor\sSTAT4\son\sWITHOUT\sROWID\ntables. +D 2017-03-21T18:56:52.218 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1faf9f06aadc9284c212dea7bbc7c0dea7e8337f0287c81001eff500912c790a @@ -338,7 +338,7 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F src/alter.c 3b23977620ce9662ac54443f65b87ba996e36121 -F src/analyze.c 6d8234916c29be943e6ea28b5bef67dff98d9905 +F src/analyze.c 0d0ccf7520a201d8747ea2f02c92c26e26f801bc161f714f27b9f7630dde0421 F src/attach.c 8c476f8bd5d2afe11d925f890d30e527e5b0ce43 F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792 F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b @@ -1567,7 +1567,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 9f680bc7c47f8391adba6ea2b4b2cb6a5a041e22753543d5224da6656c3762fe -R 6048d4479132e9b80b95aca588407d4c -U dan -Z d545083811aa9af855b84bbadd9a61dc +P ee9588e873ffebcaa177957950cbb14924e154c391ed7f687116065064ff11b0 +R 5a75fd33dd28f00ec2c9a64301b362e9 +U drh +Z a2519e8e7a444d8c646c2457bd4b758f diff --git a/manifest.uuid b/manifest.uuid index c60120ecbc..e7b01a944f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ee9588e873ffebcaa177957950cbb14924e154c391ed7f687116065064ff11b0 \ No newline at end of file +ad741976c8c29bcc94f9ea9ed7deb580bb00c8a81d1a7fba1a4e03849728433d \ No newline at end of file diff --git a/src/analyze.c b/src/analyze.c index d1df000943..495cc954ac 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -1204,7 +1204,7 @@ static void analyzeOneTable( regKey = sqlite3GetTempRange(pParse, pPk->nKeyCol); for(j=0; jnKeyCol; j++){ k = sqlite3ColumnOfIndex(pIdx, pPk->aiColumn[j]); - assert( k>=0 && knCol ); + assert( k>=0 && knColumn ); sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k, regKey+j); VdbeComment((v, "%s", pTab->aCol[pPk->aiColumn[j]].zName)); } From 918938f9c205b7fc99b6abd66bfaad1d1895d694 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 21 Mar 2017 20:17:24 +0000 Subject: [PATCH 1456/1484] New simplified memory initialization for MacOS. FossilOrigin-Name: 055b36f1c1593bb123f7319a07c476143d71af052b5b8d34afcd0d500f197882 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/mem1.c | 48 +++++++++++++----------------------------------- 3 files changed, 20 insertions(+), 42 deletions(-) diff --git a/manifest b/manifest index 75a4357e21..834fc1ba0f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\sincorrect\sassert\sin\sthe\sANALYZE\slogic\sfor\sSTAT4\son\sWITHOUT\sROWID\ntables. -D 2017-03-21T18:56:52.218 +C New\ssimplified\smemory\sinitialization\sfor\sMacOS. +D 2017-03-21T20:17:24.121 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1faf9f06aadc9284c212dea7bbc7c0dea7e8337f0287c81001eff500912c790a @@ -369,7 +369,7 @@ F src/loadext.c a68d8d1d14cf7488bb29dc5311cb1ce9a4404258 F src/main.c 158326243c5ddc8b98a1e983fa488650cf76d760 F src/malloc.c 89c98e3619d362dcffa5c1c639b364b65b474751 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 -F src/mem1.c 79bf195f445bf7e66cadd121849837c3152fbd2f542326bbed3073b6902450c2 +F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3 F src/mem3.c 8768ac94694f31ffaf8b4d0ea5dc08af7010a35a F src/mem5.c 9bf955937b07f8c32541c8a9991f33ce3173d944 @@ -1567,7 +1567,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ee9588e873ffebcaa177957950cbb14924e154c391ed7f687116065064ff11b0 -R 5a75fd33dd28f00ec2c9a64301b362e9 +P ad741976c8c29bcc94f9ea9ed7deb580bb00c8a81d1a7fba1a4e03849728433d +R c272fa429602630b64ee19437bd8d503 U drh -Z a2519e8e7a444d8c646c2457bd4b758f +Z a3a73b80a262fb4daeb6a94d5a29c210 diff --git a/manifest.uuid b/manifest.uuid index e7b01a944f..e5a19cd1b9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ad741976c8c29bcc94f9ea9ed7deb580bb00c8a81d1a7fba1a4e03849728433d \ No newline at end of file +055b36f1c1593bb123f7319a07c476143d71af052b5b8d34afcd0d500f197882 \ No newline at end of file diff --git a/src/mem1.c b/src/mem1.c index 02ed59b4d4..512ab3747f 100644 --- a/src/mem1.c +++ b/src/mem1.c @@ -238,45 +238,23 @@ static int sqlite3MemRoundup(int n){ */ static int sqlite3MemInit(void *NotUsed){ #if defined(__APPLE__) && !defined(SQLITE_WITHOUT_ZONEMALLOC) + int cpuCount; + size_t len; if( _sqliteZone_ ){ return SQLITE_OK; } -#ifndef SQLITE_MIGHT_BE_SINGLE_CORE - /* If not compiled with the SQLITE_MIGHT_BE_SINGLE_CORE flag, assume - ** that multiple cores are always available. This is the default case. - */ - _sqliteZone_ = malloc_default_zone(); -#else - /* With the SQLITE_MIGHT_BE_SINGLE_CORE compile-time option, check the - ** number of cores. Different malloc() strategies are used for single-core and - ** multi-core machines. - */ - { - int cpuCount; - size_t len; - len = sizeof(cpuCount); - /* One usually wants to use hw.acctivecpu for MT decisions, but not here */ - sysctlbyname("hw.ncpu", &cpuCount, &len, NULL, 0); - if( cpuCount>1 ){ - /* defer MT decisions to system malloc */ - _sqliteZone_ = malloc_default_zone(); - }else{ - /* only 1 core, use our own zone to contention over global locks, - ** e.g. we have our own dedicated locks */ - bool success; - malloc_zone_t* newzone = malloc_create_zone(4096, 0); - malloc_set_zone_name(newzone, "Sqlite_Heap"); - do{ - success = OSAtomicCompareAndSwapPtrBarrier(NULL, newzone, - (void * volatile *)&_sqliteZone_); - }while(!_sqliteZone_); - if( !success ){ - /* somebody registered a zone first */ - malloc_destroy_zone(newzone); - } - } + len = sizeof(cpuCount); + /* One usually wants to use hw.acctivecpu for MT decisions, but not here */ + sysctlbyname("hw.ncpu", &cpuCount, &len, NULL, 0); + if( cpuCount>1 ){ + /* defer MT decisions to system malloc */ + _sqliteZone_ = malloc_default_zone(); + }else{ + /* only 1 core, use our own zone to contention over global locks, + ** e.g. we have our own dedicated locks */ + _sqliteZone_ = malloc_create_zone(4096, 0); + malloc_set_zone_name(_sqliteZone_, "Sqlite_Heap"); } -#endif /* SQLITE_MIGHT_BE_SINGLE_CORE */ #endif /* defined(__APPLE__) && !defined(SQLITE_WITHOUT_ZONEMALLOC) */ UNUSED_PARAMETER(NotUsed); return SQLITE_OK; From 701ff6ad2d00fe7f05a4de4e946a2a4893b1c722 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 22 Mar 2017 12:51:34 +0000 Subject: [PATCH 1457/1484] Fix harmless compiler warnings in the shell. FossilOrigin-Name: a786829783ef65ef270ca360712364cbd47a540d31ed1547d50808aad698bea7 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/shell.c | 5 ++--- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 834fc1ba0f..560760071c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C New\ssimplified\smemory\sinitialization\sfor\sMacOS. -D 2017-03-21T20:17:24.121 +C Fix\sharmless\scompiler\swarnings\sin\sthe\sshell. +D 2017-03-22T12:51:34.759 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1faf9f06aadc9284c212dea7bbc7c0dea7e8337f0287c81001eff500912c790a @@ -402,7 +402,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 3e518b962d932a997fae373366880fc028c75706 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c 2496d0cc6368dabe7ad2e4c7f5ed3ad9aa3b4d11cd90f33fa1d1ef72493f43aa -F src/shell.c 77054c021069ec0b65d3d620aab031f97c59b4e42ac7c31544ea68933b581104 +F src/shell.c ce39c4bbbaa02484cb45141034fd363c3bac80a6aa22b0bb3cecea1c6a4c0979 F src/sqlite.h.in 723107d97f2345a7c103632169dc61366121c4ab65d75a7d83c6dc0e5bbe5ca4 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae @@ -1567,7 +1567,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ad741976c8c29bcc94f9ea9ed7deb580bb00c8a81d1a7fba1a4e03849728433d -R c272fa429602630b64ee19437bd8d503 +P 055b36f1c1593bb123f7319a07c476143d71af052b5b8d34afcd0d500f197882 +R 1f280e53b7c950d24565e873ae0276ec U drh -Z a3a73b80a262fb4daeb6a94d5a29c210 +Z a154993c25ee99ce8fe87b6f82cb272d diff --git a/manifest.uuid b/manifest.uuid index e5a19cd1b9..6c408aa251 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -055b36f1c1593bb123f7319a07c476143d71af052b5b8d34afcd0d500f197882 \ No newline at end of file +a786829783ef65ef270ca360712364cbd47a540d31ed1547d50808aad698bea7 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index e7652f8e67..e71c34e6df 100644 --- a/src/shell.c +++ b/src/shell.c @@ -2926,7 +2926,6 @@ static char **tableColumnList(ShellState *p, const char *zTab){ ** ordinary column in the table. Verify that azRowid[j] is a valid ** name for the rowid before adding it to azCol[0]. WITHOUT ROWID ** tables will fail this last check */ - int rc; rc = sqlite3_table_column_metadata(p->db,0,zTab,azRowid[j],0,0,0,0,0); if( rc==SQLITE_OK ) azCol[0] = azRowid[j]; break; @@ -2959,14 +2958,14 @@ static void toggleSelectOrder(sqlite3 *db){ ** the table type ("index" or "table") and SQL to create the table. ** This routine should print text sufficient to recreate the table. */ -static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){ +static int dump_callback(void *pArg, int nArg, char **azArg, char **azNotUsed){ int rc; const char *zTable; const char *zType; const char *zSql; ShellState *p = (ShellState *)pArg; - UNUSED_PARAMETER(azCol); + UNUSED_PARAMETER(azNotUsed); if( nArg!=3 ) return 1; zTable = azArg[0]; zType = azArg[1]; From 633647af75b3e680abe57922a8f1ec495b4150c6 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 22 Mar 2017 21:24:31 +0000 Subject: [PATCH 1458/1484] Initial implementation of the json_mergepatch(A,B) SQL function. FossilOrigin-Name: a267444039af519f088dd8f8ee33f686cc3071c087677075af2364ebc2587514 --- ext/misc/json1.c | 138 +++++++++++++++++++++++++++++++++++++++------- manifest | 16 ++++-- manifest.uuid | 2 +- test/json104.test | 63 +++++++++++++++++++++ 4 files changed, 192 insertions(+), 27 deletions(-) create mode 100644 test/json104.test diff --git a/ext/misc/json1.c b/ext/misc/json1.c index 3063f9f261..0db946fdc6 100644 --- a/ext/misc/json1.c +++ b/ext/misc/json1.c @@ -138,9 +138,10 @@ static const char * const jsonType[] = { #define JNODE_RAW 0x01 /* Content is raw, not JSON encoded */ #define JNODE_ESCAPE 0x02 /* Content is text with \ escapes */ #define JNODE_REMOVE 0x04 /* Do not output */ -#define JNODE_REPLACE 0x08 /* Replace with JsonNode.iVal */ -#define JNODE_APPEND 0x10 /* More ARRAY/OBJECT entries at u.iAppend */ -#define JNODE_LABEL 0x20 /* Is a label of an object */ +#define JNODE_REPLACE 0x08 /* Replace with JsonNode.u.iReplace */ +#define JNODE_PATCH 0x10 /* Patch with JsonNode.u.pPatch */ +#define JNODE_APPEND 0x20 /* More ARRAY/OBJECT entries at u.iAppend */ +#define JNODE_LABEL 0x40 /* Is a label of an object */ /* A single node of parsed JSON @@ -148,12 +149,13 @@ static const char * const jsonType[] = { struct JsonNode { u8 eType; /* One of the JSON_ type values */ u8 jnFlags; /* JNODE flags */ - u8 iVal; /* Replacement value when JNODE_REPLACE */ u32 n; /* Bytes of content, or number of sub-nodes */ union { const char *zJContent; /* Content for INT, REAL, and STRING */ u32 iAppend; /* More terms for ARRAY and OBJECT */ u32 iKey; /* Key for ARRAY objects in json_tree() */ + u32 iReplace; /* Replacement content for JNODE_REPLACE */ + JsonNode *pPatch; /* Node chain of patch for JNODE_PATCH */ } u; }; @@ -410,6 +412,13 @@ static void jsonRenderNode( JsonString *pOut, /* Write JSON here */ sqlite3_value **aReplace /* Replacement values */ ){ + if( pNode->jnFlags & (JNODE_REPLACE|JNODE_PATCH) ){ + if( pNode->jnFlags & JNODE_REPLACE ){ + jsonAppendValue(pOut, aReplace[pNode->u.iReplace]); + return; + } + pNode = pNode->u.pPatch; + } switch( pNode->eType ){ default: { assert( pNode->eType==JSON_NULL ); @@ -441,12 +450,7 @@ static void jsonRenderNode( jsonAppendChar(pOut, '['); for(;;){ while( j<=pNode->n ){ - if( pNode[j].jnFlags & (JNODE_REMOVE|JNODE_REPLACE) ){ - if( pNode[j].jnFlags & JNODE_REPLACE ){ - jsonAppendSeparator(pOut); - jsonAppendValue(pOut, aReplace[pNode[j].iVal]); - } - }else{ + if( (pNode[j].jnFlags & JNODE_REMOVE)==0 ){ jsonAppendSeparator(pOut); jsonRenderNode(&pNode[j], pOut, aReplace); } @@ -468,11 +472,7 @@ static void jsonRenderNode( jsonAppendSeparator(pOut); jsonRenderNode(&pNode[j], pOut, aReplace); jsonAppendChar(pOut, ':'); - if( pNode[j+1].jnFlags & JNODE_REPLACE ){ - jsonAppendValue(pOut, aReplace[pNode[j+1].iVal]); - }else{ - jsonRenderNode(&pNode[j+1], pOut, aReplace); - } + jsonRenderNode(&pNode[j+1], pOut, aReplace); } j += 1 + jsonNodeSize(&pNode[j+1]); } @@ -699,7 +699,6 @@ static int jsonParseAddNode( p = &pParse->aNode[pParse->nNode]; p->eType = (u8)eType; p->jnFlags = 0; - p->iVal = 0; p->n = n; p->u.zJContent = zContent; return pParse->nNode++; @@ -1357,6 +1356,104 @@ static void jsonExtractFunc( jsonParseReset(&x); } +/* This is the RFC 7396 MergePatch algorithm. +*/ +static JsonNode *jsonMergePatch( + JsonParse *pParse, /* The JSON parser that contains the TARGET */ + int iTarget, /* Node of the TARGET in pParse */ + JsonNode *pPatch /* The PATCH */ +){ + int i, j; + int iApnd; + JsonNode *pTarget; + if( pPatch->eType!=JSON_OBJECT ){ + return pPatch; + } + assert( iTarget>=0 && iTargetnNode ); + pTarget = &pParse->aNode[iTarget]; + assert( (pPatch->jnFlags & JNODE_APPEND)==0 ); + if( pTarget->eType!=JSON_OBJECT ){ + for(i=2; in; i += jsonNodeSize(&pPatch[i])+1){ + if( pPatch[i].eType==JSON_NULL ){ + pPatch[i-1].jnFlags |= JNODE_REMOVE; + } + } + return pPatch; + } + iApnd = iTarget; + for(i=1; in; i += jsonNodeSize(&pPatch[i+1])+1){ + int nKey; + const char *zKey; + assert( pPatch[i].eType==JSON_STRING ); + assert( pPatch[i].jnFlags & JNODE_LABEL ); + nKey = pPatch[i].n; + zKey = pPatch[i].u.zJContent; + if( (pPatch[i].jnFlags & JNODE_RAW)==0 ){ + assert( nKey>=2 && zKey[0]=='"' && zKey[nKey-1]=='"' ); + nKey -= 2; + zKey ++; + } + for(j=1; jn; j += jsonNodeSize(&pTarget[j+1])+1 ){ + assert( pTarget[j].eType==JSON_STRING ); + assert( pTarget[j].jnFlags & JNODE_LABEL ); + if( jsonLabelCompare(&pTarget[j], zKey, nKey) + && (pTarget[j+1].jnFlags & (JNODE_REMOVE|JNODE_PATCH))==0 + ){ + if( pPatch[i+1].eType==JSON_NULL ){ + pTarget[j+1].jnFlags |= JNODE_REMOVE; + }else{ + JsonNode *pNew = jsonMergePatch(pParse, j+1, &pPatch[i+1]); + if( pNew==0 ) return 0; + pTarget = &pParse->aNode[iTarget]; + if( pNew!=&pTarget[j+1] ){ + pTarget[j+1].u.pPatch = pNew; + pTarget[j+1].jnFlags |= JNODE_PATCH; + } + } + break; + } + } + if( j>=pTarget->n ){ + int iStart, iPatch; + iStart = jsonParseAddNode(pParse, JSON_OBJECT, 2, 0); + jsonParseAddNode(pParse, JSON_STRING, nKey, zKey); + iPatch = jsonParseAddNode(pParse, JSON_TRUE, 0, 0); + if( pParse->oom ) return 0; + pTarget = &pParse->aNode[iTarget]; + pParse->aNode[iApnd].jnFlags |= JNODE_APPEND; + pParse->aNode[iApnd].u.iAppend = iStart; + iApnd = iStart; + pParse->aNode[iPatch].jnFlags |= JNODE_PATCH; + pParse->aNode[iPatch].u.pPatch = &pPatch[i+1]; + } + } + return pTarget; +} + +/* +** Implementation of the json_mergepatch(JSON1,JSON2) function. Return a JSON +** object that is the result of running the RFC 7396 MergePatch() algorithm +** on the two arguments. +*/ +static void jsonMergePatchFunc( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv +){ + JsonParse x; /* The JSON that is being patched */ + JsonParse y; /* The patch */ + + if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return; + if( jsonParse(&y, ctx, (const char*)sqlite3_value_text(argv[1])) ){ + jsonParseReset(&x); + return; + } + jsonReturnJson(jsonMergePatch(&x, 0, y.aNode), ctx, 0); + jsonParseReset(&x); + jsonParseReset(&y); +} + + /* ** Implementation of the json_object(NAME,VALUE,...) function. Return a JSON ** object that contains all name/value given in arguments. Or if any name @@ -1460,11 +1557,11 @@ static void jsonReplaceFunc( if( x.nErr ) goto replace_err; if( pNode ){ pNode->jnFlags |= (u8)JNODE_REPLACE; - pNode->iVal = (u8)(i+1); + pNode->u.iReplace = i + 1; } } if( x.aNode[0].jnFlags & JNODE_REPLACE ){ - sqlite3_result_value(ctx, argv[x.aNode[0].iVal]); + sqlite3_result_value(ctx, argv[x.aNode[0].u.iReplace]); }else{ jsonReturnJson(x.aNode, ctx, argv); } @@ -1514,11 +1611,11 @@ static void jsonSetFunc( goto jsonSetDone; }else if( pNode && (bApnd || bIsSet) ){ pNode->jnFlags |= (u8)JNODE_REPLACE; - pNode->iVal = (u8)(i+1); + pNode->u.iReplace = i + 1; } } if( x.aNode[0].jnFlags & JNODE_REPLACE ){ - sqlite3_result_value(ctx, argv[x.aNode[0].iVal]); + sqlite3_result_value(ctx, argv[x.aNode[0].u.iReplace]); }else{ jsonReturnJson(x.aNode, ctx, argv); } @@ -2160,6 +2257,7 @@ int sqlite3Json1Init(sqlite3 *db){ { "json_array_length", 2, 0, jsonArrayLengthFunc }, { "json_extract", -1, 0, jsonExtractFunc }, { "json_insert", -1, 0, jsonSetFunc }, + { "json_mergepatch", 2, 0, jsonMergePatchFunc }, { "json_object", -1, 0, jsonObjectFunc }, { "json_quote", 1, 0, jsonQuoteFunc }, { "json_remove", -1, 0, jsonRemoveFunc }, diff --git a/manifest b/manifest index 834fc1ba0f..cceedf00d1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C New\ssimplified\smemory\sinitialization\sfor\sMacOS. -D 2017-03-21T20:17:24.121 +C Initial\simplementation\sof\sthe\sjson_mergepatch(A,B)\sSQL\sfunction. +D 2017-03-22T21:24:31.714 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1faf9f06aadc9284c212dea7bbc7c0dea7e8337f0287c81001eff500912c790a @@ -218,7 +218,7 @@ F ext/misc/eval.c f971962e92ebb8b0a4e6b62949463ee454d88fa2 F ext/misc/fileio.c d4171c815d6543a9edef8308aab2951413cd8d0f F ext/misc/fuzzer.c 7c64b8197bb77b7d64eff7cac7848870235d4c25 F ext/misc/ieee754.c f190d0cc5182529acb15babd177781be1ac1718c -F ext/misc/json1.c 552a7d730863419e05dc947265b28bd411680e2e +F ext/misc/json1.c ca27a98c0a7a90fcbaccd3157204e19afc7eec0ba3f4c08ed06bb638b773f523 F ext/misc/memvfs.c e5225bc22e79dde6b28380f3a068ddf600683a33 F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342 F ext/misc/percentile.c 92699c8cd7d517ff610e6037e56506f8904dae2e @@ -913,6 +913,7 @@ F test/jrnlmode3.test 556b447a05be0e0963f4311e95ab1632b11c9eaa F test/json101.test c0897616f32d95431f37fd291cb78742181980ac F test/json102.test bf3fe7a706d30936a76a0f7a0375e1e8e73aff5a F test/json103.test c5f6b85e69de05f6b3195f9f9d5ce9cd179099a0 +F test/json104.test 83fd7a15eadb0cde34a37200842318d1cd98abe908e2847fb93d337d969815cc F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff F test/kvtest.c b9a9822dda05a1aa481215a52e2fc93cd8b22ee5 F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63 @@ -1567,7 +1568,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ad741976c8c29bcc94f9ea9ed7deb580bb00c8a81d1a7fba1a4e03849728433d -R c272fa429602630b64ee19437bd8d503 +P 055b36f1c1593bb123f7319a07c476143d71af052b5b8d34afcd0d500f197882 +R 1d5a57aea0e07c508840a776caf26b14 +T *branch * json_mergepatch +T *sym-json_mergepatch * +T -sym-trunk * U drh -Z a3a73b80a262fb4daeb6a94d5a29c210 +Z 2961dcef6bde9e861663934a25c90d24 diff --git a/manifest.uuid b/manifest.uuid index e5a19cd1b9..980cac0acf 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -055b36f1c1593bb123f7319a07c476143d71af052b5b8d34afcd0d500f197882 \ No newline at end of file +a267444039af519f088dd8f8ee33f686cc3071c087677075af2364ebc2587514 \ No newline at end of file diff --git a/test/json104.test b/test/json104.test new file mode 100644 index 0000000000..fc2e0e38b4 --- /dev/null +++ b/test/json104.test @@ -0,0 +1,63 @@ +# 2017-03-22 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements tests for json_mergepatch(A,B) SQL function. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +ifcapable !json1 { + finish_test + return +} + +# This is the example from pages 2 and 3 of RFC-7396 +do_execsql_test json104-100 { + SELECT json_mergepatch( + json('{ + "a": "b", + "c": { + "d": "e", + "f": "g" + } + }'), + json('{ + "a":"z", + "c": { + "f": null + } + }')); +} {{{"a":"z","c":{"d":"e"}}}} + + +# This is the example from pages 4 and 5 of RFC-7396 +do_execsql_test json104-110 { + SELECT json_mergepatch( + json('{ + "title": "Goodbye!", + "author" : { + "givenName" : "John", + "familyName" : "Doe" + }, + "tags":[ "example", "sample" ], + "content": "This will be unchanged" + }'), + json('{ + "title": "Hello!", + "phoneNumber": "+01-123-456-7890", + "author": { + "familyName": null + }, + "tags": [ "example" ] + }')); +} {{{"title":"Hello!","author":{"givenName":"John"},"tags":["example"],"content":"This will be unchanged",phoneNumber:"+01-123-456-7890"}}} + +finish_test From f07b249f92fb1d0a37b1444657d14ed7042bafa7 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 22 Mar 2017 21:45:20 +0000 Subject: [PATCH 1459/1484] Change the name of the new function to "json_merge_patch()". FossilOrigin-Name: 53bf70f37bbca319ea35f70849e2a34ae628a504486158fdad5c4bb7431c68e0 --- ext/misc/json1.c | 2 +- manifest | 17 +++++++---------- manifest.uuid | 2 +- test/json104.test | 16 ++++++---------- 4 files changed, 15 insertions(+), 22 deletions(-) diff --git a/ext/misc/json1.c b/ext/misc/json1.c index 0db946fdc6..c037525c45 100644 --- a/ext/misc/json1.c +++ b/ext/misc/json1.c @@ -2257,7 +2257,7 @@ int sqlite3Json1Init(sqlite3 *db){ { "json_array_length", 2, 0, jsonArrayLengthFunc }, { "json_extract", -1, 0, jsonExtractFunc }, { "json_insert", -1, 0, jsonSetFunc }, - { "json_mergepatch", 2, 0, jsonMergePatchFunc }, + { "json_merge_patch", 2, 0, jsonMergePatchFunc }, { "json_object", -1, 0, jsonObjectFunc }, { "json_quote", 1, 0, jsonQuoteFunc }, { "json_remove", -1, 0, jsonRemoveFunc }, diff --git a/manifest b/manifest index cceedf00d1..8c6f009d42 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Initial\simplementation\sof\sthe\sjson_mergepatch(A,B)\sSQL\sfunction. -D 2017-03-22T21:24:31.714 +C Change\sthe\sname\sof\sthe\snew\sfunction\sto\s"json_merge_patch()". +D 2017-03-22T21:45:20.759 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1faf9f06aadc9284c212dea7bbc7c0dea7e8337f0287c81001eff500912c790a @@ -218,7 +218,7 @@ F ext/misc/eval.c f971962e92ebb8b0a4e6b62949463ee454d88fa2 F ext/misc/fileio.c d4171c815d6543a9edef8308aab2951413cd8d0f F ext/misc/fuzzer.c 7c64b8197bb77b7d64eff7cac7848870235d4c25 F ext/misc/ieee754.c f190d0cc5182529acb15babd177781be1ac1718c -F ext/misc/json1.c ca27a98c0a7a90fcbaccd3157204e19afc7eec0ba3f4c08ed06bb638b773f523 +F ext/misc/json1.c be1032c54498ae8d884b7c430da876a0f895dfc734ac3255336014ce79e3f219 F ext/misc/memvfs.c e5225bc22e79dde6b28380f3a068ddf600683a33 F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342 F ext/misc/percentile.c 92699c8cd7d517ff610e6037e56506f8904dae2e @@ -913,7 +913,7 @@ F test/jrnlmode3.test 556b447a05be0e0963f4311e95ab1632b11c9eaa F test/json101.test c0897616f32d95431f37fd291cb78742181980ac F test/json102.test bf3fe7a706d30936a76a0f7a0375e1e8e73aff5a F test/json103.test c5f6b85e69de05f6b3195f9f9d5ce9cd179099a0 -F test/json104.test 83fd7a15eadb0cde34a37200842318d1cd98abe908e2847fb93d337d969815cc +F test/json104.test 66d3dfc9f76e413c7c957d897325b17b9d1bbdf471225310dbf47279e36f1937 F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff F test/kvtest.c b9a9822dda05a1aa481215a52e2fc93cd8b22ee5 F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63 @@ -1568,10 +1568,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 055b36f1c1593bb123f7319a07c476143d71af052b5b8d34afcd0d500f197882 -R 1d5a57aea0e07c508840a776caf26b14 -T *branch * json_mergepatch -T *sym-json_mergepatch * -T -sym-trunk * +P a267444039af519f088dd8f8ee33f686cc3071c087677075af2364ebc2587514 +R f0982f12ae9e098efe5bc17c4edc8338 U drh -Z 2961dcef6bde9e861663934a25c90d24 +Z 17fdf70c56513cf2488f301085ed16e1 diff --git a/manifest.uuid b/manifest.uuid index 980cac0acf..ea9e24d51d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a267444039af519f088dd8f8ee33f686cc3071c087677075af2364ebc2587514 \ No newline at end of file +53bf70f37bbca319ea35f70849e2a34ae628a504486158fdad5c4bb7431c68e0 \ No newline at end of file diff --git a/test/json104.test b/test/json104.test index fc2e0e38b4..be041c5da8 100644 --- a/test/json104.test +++ b/test/json104.test @@ -21,27 +21,24 @@ ifcapable !json1 { # This is the example from pages 2 and 3 of RFC-7396 do_execsql_test json104-100 { - SELECT json_mergepatch( - json('{ + SELECT json_merge_patch('{ "a": "b", "c": { "d": "e", "f": "g" } - }'), - json('{ + }','{ "a":"z", "c": { "f": null } - }')); + }'); } {{{"a":"z","c":{"d":"e"}}}} # This is the example from pages 4 and 5 of RFC-7396 do_execsql_test json104-110 { - SELECT json_mergepatch( - json('{ + SELECT json_merge_patch('{ "title": "Goodbye!", "author" : { "givenName" : "John", @@ -49,15 +46,14 @@ do_execsql_test json104-110 { }, "tags":[ "example", "sample" ], "content": "This will be unchanged" - }'), - json('{ + }','{ "title": "Hello!", "phoneNumber": "+01-123-456-7890", "author": { "familyName": null }, "tags": [ "example" ] - }')); + }'); } {{{"title":"Hello!","author":{"givenName":"John"},"tags":["example"],"content":"This will be unchanged",phoneNumber:"+01-123-456-7890"}}} finish_test From bb7aa2d85e684d0db13c93c1e6dbb0e2f3bfb1ab Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 23 Mar 2017 00:13:52 +0000 Subject: [PATCH 1460/1484] Various fixes to the json_merge_patch() function. FossilOrigin-Name: f49fd2554b0723eb7cf2fd765d655c6820833ee7e5f7d7629d98c27a6fffa1d9 --- ext/misc/json1.c | 39 ++++++++++++++++++++++----------------- manifest | 14 +++++++------- manifest.uuid | 2 +- test/json104.test | 9 ++++++++- 4 files changed, 38 insertions(+), 26 deletions(-) diff --git a/ext/misc/json1.c b/ext/misc/json1.c index c037525c45..f03bdc6652 100644 --- a/ext/misc/json1.c +++ b/ext/misc/json1.c @@ -1364,7 +1364,7 @@ static JsonNode *jsonMergePatch( JsonNode *pPatch /* The PATCH */ ){ int i, j; - int iApnd; + int iRoot; JsonNode *pTarget; if( pPatch->eType!=JSON_OBJECT ){ return pPatch; @@ -1373,14 +1373,14 @@ static JsonNode *jsonMergePatch( pTarget = &pParse->aNode[iTarget]; assert( (pPatch->jnFlags & JNODE_APPEND)==0 ); if( pTarget->eType!=JSON_OBJECT ){ - for(i=2; in; i += jsonNodeSize(&pPatch[i])+1){ + for(i=2; i<=pPatch->n; i += jsonNodeSize(&pPatch[i])+1){ if( pPatch[i].eType==JSON_NULL ){ - pPatch[i-1].jnFlags |= JNODE_REMOVE; + pPatch[i].jnFlags |= JNODE_REMOVE; } } return pPatch; } - iApnd = iTarget; + iRoot = iTarget; for(i=1; in; i += jsonNodeSize(&pPatch[i+1])+1){ int nKey; const char *zKey; @@ -1388,21 +1388,19 @@ static JsonNode *jsonMergePatch( assert( pPatch[i].jnFlags & JNODE_LABEL ); nKey = pPatch[i].n; zKey = pPatch[i].u.zJContent; - if( (pPatch[i].jnFlags & JNODE_RAW)==0 ){ - assert( nKey>=2 && zKey[0]=='"' && zKey[nKey-1]=='"' ); - nKey -= 2; - zKey ++; - } + assert( (pPatch[i].jnFlags & JNODE_RAW)==0 ); for(j=1; jn; j += jsonNodeSize(&pTarget[j+1])+1 ){ assert( pTarget[j].eType==JSON_STRING ); assert( pTarget[j].jnFlags & JNODE_LABEL ); - if( jsonLabelCompare(&pTarget[j], zKey, nKey) - && (pTarget[j+1].jnFlags & (JNODE_REMOVE|JNODE_PATCH))==0 + assert( (pPatch[i].jnFlags & JNODE_RAW)==0 ); + if( (pTarget[j+1].jnFlags & (JNODE_REMOVE|JNODE_PATCH))==0 + && pTarget[j].n==nKey + && strncmp(pTarget[j].u.zJContent, zKey, nKey)==0 ){ if( pPatch[i+1].eType==JSON_NULL ){ pTarget[j+1].jnFlags |= JNODE_REMOVE; }else{ - JsonNode *pNew = jsonMergePatch(pParse, j+1, &pPatch[i+1]); + JsonNode *pNew = jsonMergePatch(pParse, iTarget+j+1, &pPatch[i+1]); if( pNew==0 ) return 0; pTarget = &pParse->aNode[iTarget]; if( pNew!=&pTarget[j+1] ){ @@ -1413,16 +1411,16 @@ static JsonNode *jsonMergePatch( break; } } - if( j>=pTarget->n ){ + if( j>=pTarget->n && pPatch[i+1].eType!=JSON_NULL ){ int iStart, iPatch; iStart = jsonParseAddNode(pParse, JSON_OBJECT, 2, 0); jsonParseAddNode(pParse, JSON_STRING, nKey, zKey); iPatch = jsonParseAddNode(pParse, JSON_TRUE, 0, 0); if( pParse->oom ) return 0; pTarget = &pParse->aNode[iTarget]; - pParse->aNode[iApnd].jnFlags |= JNODE_APPEND; - pParse->aNode[iApnd].u.iAppend = iStart; - iApnd = iStart; + pParse->aNode[iRoot].jnFlags |= JNODE_APPEND; + pParse->aNode[iRoot].u.iAppend = iStart - iRoot; + iRoot = iStart; pParse->aNode[iPatch].jnFlags |= JNODE_PATCH; pParse->aNode[iPatch].u.pPatch = &pPatch[i+1]; } @@ -1442,13 +1440,20 @@ static void jsonMergePatchFunc( ){ JsonParse x; /* The JSON that is being patched */ JsonParse y; /* The patch */ + JsonNode *pResult; /* The result of the merge */ if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return; if( jsonParse(&y, ctx, (const char*)sqlite3_value_text(argv[1])) ){ jsonParseReset(&x); return; } - jsonReturnJson(jsonMergePatch(&x, 0, y.aNode), ctx, 0); + pResult = jsonMergePatch(&x, 0, y.aNode); + assert( pResult!=0 || x.oom ); + if( pResult ){ + jsonReturnJson(pResult, ctx, 0); + }else{ + sqlite3_result_error_nomem(ctx); + } jsonParseReset(&x); jsonParseReset(&y); } diff --git a/manifest b/manifest index 8c6f009d42..31881bdb35 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sthe\sname\sof\sthe\snew\sfunction\sto\s"json_merge_patch()". -D 2017-03-22T21:45:20.759 +C Various\sfixes\sto\sthe\sjson_merge_patch()\sfunction. +D 2017-03-23T00:13:52.903 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1faf9f06aadc9284c212dea7bbc7c0dea7e8337f0287c81001eff500912c790a @@ -218,7 +218,7 @@ F ext/misc/eval.c f971962e92ebb8b0a4e6b62949463ee454d88fa2 F ext/misc/fileio.c d4171c815d6543a9edef8308aab2951413cd8d0f F ext/misc/fuzzer.c 7c64b8197bb77b7d64eff7cac7848870235d4c25 F ext/misc/ieee754.c f190d0cc5182529acb15babd177781be1ac1718c -F ext/misc/json1.c be1032c54498ae8d884b7c430da876a0f895dfc734ac3255336014ce79e3f219 +F ext/misc/json1.c 8a8ba23a0715858ff393aa890e379912759712518afa4d28de6308a79287cb61 F ext/misc/memvfs.c e5225bc22e79dde6b28380f3a068ddf600683a33 F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342 F ext/misc/percentile.c 92699c8cd7d517ff610e6037e56506f8904dae2e @@ -913,7 +913,7 @@ F test/jrnlmode3.test 556b447a05be0e0963f4311e95ab1632b11c9eaa F test/json101.test c0897616f32d95431f37fd291cb78742181980ac F test/json102.test bf3fe7a706d30936a76a0f7a0375e1e8e73aff5a F test/json103.test c5f6b85e69de05f6b3195f9f9d5ce9cd179099a0 -F test/json104.test 66d3dfc9f76e413c7c957d897325b17b9d1bbdf471225310dbf47279e36f1937 +F test/json104.test 9f8358fd4ec94eca27b31d4ad7f75482edf24c865df378e5129c0b3107c9664e F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff F test/kvtest.c b9a9822dda05a1aa481215a52e2fc93cd8b22ee5 F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63 @@ -1568,7 +1568,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a267444039af519f088dd8f8ee33f686cc3071c087677075af2364ebc2587514 -R f0982f12ae9e098efe5bc17c4edc8338 +P 53bf70f37bbca319ea35f70849e2a34ae628a504486158fdad5c4bb7431c68e0 +R 7c38ec8ac02c81967ed35b7b062ffaf6 U drh -Z 17fdf70c56513cf2488f301085ed16e1 +Z e95ab9d86e57fcad88a27a5fb020f800 diff --git a/manifest.uuid b/manifest.uuid index ea9e24d51d..23d86ab688 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -53bf70f37bbca319ea35f70849e2a34ae628a504486158fdad5c4bb7431c68e0 \ No newline at end of file +f49fd2554b0723eb7cf2fd765d655c6820833ee7e5f7d7629d98c27a6fffa1d9 \ No newline at end of file diff --git a/test/json104.test b/test/json104.test index be041c5da8..b5a45bc525 100644 --- a/test/json104.test +++ b/test/json104.test @@ -54,6 +54,13 @@ do_execsql_test json104-110 { }, "tags": [ "example" ] }'); -} {{{"title":"Hello!","author":{"givenName":"John"},"tags":["example"],"content":"This will be unchanged",phoneNumber:"+01-123-456-7890"}}} +} {{{"title":"Hello!","author":{"givenName":"John"},"tags":["example"],"content":"This will be unchanged","phoneNumber":"+01-123-456-7890"}}} + +do_execsql_test json104-200 { + SELECT json_merge_patch('[1,2,3]','{"x":null}'); +} {{{}}} +do_execsql_test json104-210 { + SELECT json_merge_patch('[1,2,3]','{"x":null,"y":1,"z":null}'); +} {{{"y":1}}} finish_test From 0002d246a94f03b7947c0fe4156f2dcc31cd722b Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 23 Mar 2017 00:46:15 +0000 Subject: [PATCH 1461/1484] Fix harmless compiler warnings in the new json_merge_patch() logic. FossilOrigin-Name: 5d2cf5a2f8afd88d041d89b3936042ce5a43629d23c48738cb2791b24da3e6af --- ext/misc/json1.c | 4 ++-- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/ext/misc/json1.c b/ext/misc/json1.c index f03bdc6652..31e03d1e7d 100644 --- a/ext/misc/json1.c +++ b/ext/misc/json1.c @@ -1363,8 +1363,8 @@ static JsonNode *jsonMergePatch( int iTarget, /* Node of the TARGET in pParse */ JsonNode *pPatch /* The PATCH */ ){ - int i, j; - int iRoot; + u32 i, j; + u32 iRoot; JsonNode *pTarget; if( pPatch->eType!=JSON_OBJECT ){ return pPatch; diff --git a/manifest b/manifest index 31881bdb35..a21f45f4f1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Various\sfixes\sto\sthe\sjson_merge_patch()\sfunction. -D 2017-03-23T00:13:52.903 +C Fix\sharmless\scompiler\swarnings\sin\sthe\snew\sjson_merge_patch()\slogic. +D 2017-03-23T00:46:15.319 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1faf9f06aadc9284c212dea7bbc7c0dea7e8337f0287c81001eff500912c790a @@ -218,7 +218,7 @@ F ext/misc/eval.c f971962e92ebb8b0a4e6b62949463ee454d88fa2 F ext/misc/fileio.c d4171c815d6543a9edef8308aab2951413cd8d0f F ext/misc/fuzzer.c 7c64b8197bb77b7d64eff7cac7848870235d4c25 F ext/misc/ieee754.c f190d0cc5182529acb15babd177781be1ac1718c -F ext/misc/json1.c 8a8ba23a0715858ff393aa890e379912759712518afa4d28de6308a79287cb61 +F ext/misc/json1.c bae7cfb49cda81be573fb159919b502a906940ccc1688dbaab33688489c9cf26 F ext/misc/memvfs.c e5225bc22e79dde6b28380f3a068ddf600683a33 F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342 F ext/misc/percentile.c 92699c8cd7d517ff610e6037e56506f8904dae2e @@ -1568,7 +1568,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 53bf70f37bbca319ea35f70849e2a34ae628a504486158fdad5c4bb7431c68e0 -R 7c38ec8ac02c81967ed35b7b062ffaf6 +P f49fd2554b0723eb7cf2fd765d655c6820833ee7e5f7d7629d98c27a6fffa1d9 +R b4e56917a91a0ee0d4fc1a8a4b3db16b U drh -Z e95ab9d86e57fcad88a27a5fb020f800 +Z 39d1ac0a1922cab73356f035d8da0baa diff --git a/manifest.uuid b/manifest.uuid index 23d86ab688..19e8a627a7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f49fd2554b0723eb7cf2fd765d655c6820833ee7e5f7d7629d98c27a6fffa1d9 \ No newline at end of file +5d2cf5a2f8afd88d041d89b3936042ce5a43629d23c48738cb2791b24da3e6af \ No newline at end of file From 1fe162fd0ce451dacee29c9d7164415c8815ca7b Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 23 Mar 2017 12:56:44 +0000 Subject: [PATCH 1462/1484] Avoid redundant edits in the json_merge_patch() function. FossilOrigin-Name: 4a8e6437dd610c5376a07867a73e5a7e2ea90357a018e1788ecce6f4e10bc939 --- ext/misc/json1.c | 6 ++---- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/ext/misc/json1.c b/ext/misc/json1.c index 31e03d1e7d..80b654d68d 100644 --- a/ext/misc/json1.c +++ b/ext/misc/json1.c @@ -1393,10 +1393,8 @@ static JsonNode *jsonMergePatch( assert( pTarget[j].eType==JSON_STRING ); assert( pTarget[j].jnFlags & JNODE_LABEL ); assert( (pPatch[i].jnFlags & JNODE_RAW)==0 ); - if( (pTarget[j+1].jnFlags & (JNODE_REMOVE|JNODE_PATCH))==0 - && pTarget[j].n==nKey - && strncmp(pTarget[j].u.zJContent, zKey, nKey)==0 - ){ + if( pTarget[j].n==nKey && strncmp(pTarget[j].u.zJContent,zKey,nKey)==0 ){ + if( pTarget[j+1].jnFlags & (JNODE_REMOVE|JNODE_PATCH) ) break; if( pPatch[i+1].eType==JSON_NULL ){ pTarget[j+1].jnFlags |= JNODE_REMOVE; }else{ diff --git a/manifest b/manifest index a21f45f4f1..0c77a3ba53 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\scompiler\swarnings\sin\sthe\snew\sjson_merge_patch()\slogic. -D 2017-03-23T00:46:15.319 +C Avoid\sredundant\sedits\sin\sthe\sjson_merge_patch()\sfunction. +D 2017-03-23T12:56:44.298 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1faf9f06aadc9284c212dea7bbc7c0dea7e8337f0287c81001eff500912c790a @@ -218,7 +218,7 @@ F ext/misc/eval.c f971962e92ebb8b0a4e6b62949463ee454d88fa2 F ext/misc/fileio.c d4171c815d6543a9edef8308aab2951413cd8d0f F ext/misc/fuzzer.c 7c64b8197bb77b7d64eff7cac7848870235d4c25 F ext/misc/ieee754.c f190d0cc5182529acb15babd177781be1ac1718c -F ext/misc/json1.c bae7cfb49cda81be573fb159919b502a906940ccc1688dbaab33688489c9cf26 +F ext/misc/json1.c dbb168b0a7640a896a565c647dcabb7c7d116c9d2b1a23b963b1d177edc0ddba F ext/misc/memvfs.c e5225bc22e79dde6b28380f3a068ddf600683a33 F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342 F ext/misc/percentile.c 92699c8cd7d517ff610e6037e56506f8904dae2e @@ -1568,7 +1568,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P f49fd2554b0723eb7cf2fd765d655c6820833ee7e5f7d7629d98c27a6fffa1d9 -R b4e56917a91a0ee0d4fc1a8a4b3db16b +P 5d2cf5a2f8afd88d041d89b3936042ce5a43629d23c48738cb2791b24da3e6af +R 76e620c002fc08a86767847f533fe70a U drh -Z 39d1ac0a1922cab73356f035d8da0baa +Z 538e213b7e95dcafcfcd2e7dd4b1a792 diff --git a/manifest.uuid b/manifest.uuid index 19e8a627a7..da2d4e0201 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5d2cf5a2f8afd88d041d89b3936042ce5a43629d23c48738cb2791b24da3e6af \ No newline at end of file +4a8e6437dd610c5376a07867a73e5a7e2ea90357a018e1788ecce6f4e10bc939 \ No newline at end of file From a77edc69eebe610d309f62234f4d5b277a80102a Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 23 Mar 2017 17:03:35 +0000 Subject: [PATCH 1463/1484] Remove an invalid assert() statement failing when VACUUMing a database that contains an index on a column explicitly declared "COLLATE BINARY". FossilOrigin-Name: 9f2e04d3c3526b5ff60d941aa6d5446f602cab37cb93972937f39eefabd6868d --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/insert.c | 2 -- test/collateB.test | 14 ++++++++++++++ 4 files changed, 23 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 560760071c..a838663224 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\scompiler\swarnings\sin\sthe\sshell. -D 2017-03-22T12:51:34.759 +C Remove\san\sinvalid\sassert()\sstatement\sfailing\swhen\sVACUUMing\sa\sdatabase\sthat\ncontains\san\sindex\son\sa\scolumn\sexplicitly\sdeclared\s"COLLATE\sBINARY". +D 2017-03-23T17:03:35.684 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1faf9f06aadc9284c212dea7bbc7c0dea7e8337f0287c81001eff500912c790a @@ -363,7 +363,7 @@ F src/hash.c 63d0ee752a3b92d4695b2b1f5259c4621b2cfebd F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4 F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 -F src/insert.c 3ed64afc49c0a2221e397b9f65d231ffbef506fe +F src/insert.c d4bb3a135948553d18cf992f76f7ed7b18aa0327f250607b5a6671e55d9947d5 F src/legacy.c e88ed13c2d531decde75d42c2e35623fb9ce3cb0 F src/loadext.c a68d8d1d14cf7488bb29dc5311cb1ce9a4404258 F src/main.c 158326243c5ddc8b98a1e983fa488650cf76d760 @@ -597,7 +597,7 @@ F test/collate7.test 8ec29d98f3ee4ccebce6e16ce3863fb6b8c7b868 F test/collate8.test cd9b3d3f999b8520ffaa7cc1647061fc5bab1334 F test/collate9.test 3adcc799229545940df2f25308dd1ad65869145a F test/collateA.test b8218ab90d1fa5c59dcf156efabb1b2599c580d6 -F test/collateB.test 8ec2accd2d7166c1eff0d2a39bc90262c6f89632 +F test/collateB.test 1e68906951b846570f29f20102ed91d29e634854ee47454d725f2151ecac0b95 F test/colmeta.test 2c765ea61ee37bc43bbe6d6047f89004e6508eb1 F test/colname.test 08948a4809d22817e0e5de89c7c0a8bd90cb551b F test/conflict.test 029faa2d81a0d1cafb5f88614beb663d972c01db @@ -1567,7 +1567,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 055b36f1c1593bb123f7319a07c476143d71af052b5b8d34afcd0d500f197882 -R 1f280e53b7c950d24565e873ae0276ec -U drh -Z a154993c25ee99ce8fe87b6f82cb272d +P a786829783ef65ef270ca360712364cbd47a540d31ed1547d50808aad698bea7 +R 85624f613e7e3af447c83f8947d69a8d +U dan +Z 3c9d547950272a881cd381bfe4f2d9b9 diff --git a/manifest.uuid b/manifest.uuid index 6c408aa251..1f6f43e2c5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a786829783ef65ef270ca360712364cbd47a540d31ed1547d50808aad698bea7 \ No newline at end of file +9f2e04d3c3526b5ff60d941aa6d5446f602cab37cb93972937f39eefabd6868d \ No newline at end of file diff --git a/src/insert.c b/src/insert.c index f1f3807244..a1f5442515 100644 --- a/src/insert.c +++ b/src/insert.c @@ -2227,8 +2227,6 @@ static int xferOptimization( ** sorted order. */ for(i=0; inColumn; i++){ const char *zColl = pSrcIdx->azColl[i]; - assert( sqlite3_stricmp(sqlite3StrBINARY, zColl)!=0 - || sqlite3StrBINARY==zColl ); if( sqlite3_stricmp(sqlite3StrBINARY, zColl) ) break; } if( i==pSrcIdx->nColumn ){ diff --git a/test/collateB.test b/test/collateB.test index 4815de83ee..3c8d50d8e6 100644 --- a/test/collateB.test +++ b/test/collateB.test @@ -13,6 +13,7 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl +set testprefix collateB do_execsql_test collateB-1.1 { CREATE TABLE t1(a INTEGER PRIMARY KEY); @@ -60,4 +61,17 @@ do_execsql_test collateB-1.17 { SELECT *,'|' FROM t1, t2, t3 WHERE b=x2 AND a=x1 AND 1=a; } {1 11 1 11 |} +#------------------------------------------------------------------------- +# Test an assert() failure that was occuring if an index were created +# on a column explicitly declared "COLLATE binary". +reset_db +do_execsql_test 2.1 { + CREATE TABLE t4(a COLLATE binary); + CREATE INDEX i4 ON t4(a); + INSERT INTO t4 VALUES('one'), ('two'), ('three'); + VACUUM; +} + +integrity_check 2.2 + finish_test From 8fe3e9d882c8e667ac20e3b090687b1fc5c23003 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 23 Mar 2017 17:22:09 +0000 Subject: [PATCH 1464/1484] Do not run test file autoanalyze1.test if OMIT_VIRTUALTABLE is defined. FossilOrigin-Name: e1d06a573ee56bf6a14e4dc8086d6a4df1464f2914834cf4596a0a406688f608 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/autoanalyze1.test | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index a838663224..24dc30b166 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\san\sinvalid\sassert()\sstatement\sfailing\swhen\sVACUUMing\sa\sdatabase\sthat\ncontains\san\sindex\son\sa\scolumn\sexplicitly\sdeclared\s"COLLATE\sBINARY". -D 2017-03-23T17:03:35.684 +C Do\snot\srun\stest\sfile\sautoanalyze1.test\sif\sOMIT_VIRTUALTABLE\sis\sdefined. +D 2017-03-23T17:22:09.188 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1faf9f06aadc9284c212dea7bbc7c0dea7e8337f0287c81001eff500912c790a @@ -528,7 +528,7 @@ F test/attachmalloc.test 3a4bfca9545bfe906a8d2e622de10fbac5b711b0 F test/auth.test c6ede04bee65637ff354b43fc1235aa560c0863e F test/auth2.test 9eb7fce9f34bf1f50d3f366fb3e606be5a2000a1 F test/auth3.test 0d48b901cf111c14b4b1b5205c7d28f1a278190f -F test/autoanalyze1.test 1ba80d5e1412d46503566b70741a5eea060da929 +F test/autoanalyze1.test b9cc3f32a990fa56669b668d237c6d53e983554ae80c0604992e18869a0b2dec F test/autoinc.test 6ae8fb69c9f656962464ae4e6667045d0dfc3b46 F test/autoindex1.test 14b63a9f1e405fe6d5bfc8c8d00249c2ebaf13ea F test/autoindex2.test 12ef578928102baaa0dc23ad397601a2f4ecb0df @@ -1567,7 +1567,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a786829783ef65ef270ca360712364cbd47a540d31ed1547d50808aad698bea7 -R 85624f613e7e3af447c83f8947d69a8d +P 9f2e04d3c3526b5ff60d941aa6d5446f602cab37cb93972937f39eefabd6868d +R c389878b6e059490204890f1ea916f73 U dan -Z 3c9d547950272a881cd381bfe4f2d9b9 +Z b2d2e5c74dc6093684311a4bed08a5d2 diff --git a/manifest.uuid b/manifest.uuid index 1f6f43e2c5..aed4b7d66c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9f2e04d3c3526b5ff60d941aa6d5446f602cab37cb93972937f39eefabd6868d \ No newline at end of file +e1d06a573ee56bf6a14e4dc8086d6a4df1464f2914834cf4596a0a406688f608 \ No newline at end of file diff --git a/test/autoanalyze1.test b/test/autoanalyze1.test index 77e767a89e..71e5d6c163 100644 --- a/test/autoanalyze1.test +++ b/test/autoanalyze1.test @@ -29,7 +29,7 @@ source $testdir/tester.tcl # These tests also use "PRAGMA stats" which are only enabled for # debugging builds. # -ifcapable {!debug || !analyze} { +ifcapable {!debug || !analyze || !vtab} { finish_test return } From db528529bf9b1524c5d31c52ee04aaaa6466b0e5 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 23 Mar 2017 19:51:38 +0000 Subject: [PATCH 1465/1484] Improvement to the amalgamation configure.ac file contributed by Bob Friesenhahn. FossilOrigin-Name: bf28a55d8185e370fea39de297c37387f852f43fac0a316e5900e633f99b367f --- autoconf/configure.ac | 4 ++-- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/autoconf/configure.ac b/autoconf/configure.ac index b9a11aac8f..5a607de054 100644 --- a/autoconf/configure.ac +++ b/autoconf/configure.ac @@ -55,9 +55,9 @@ AS_IF([ test x"$enable_editline" != xno ],[ LIBS="" AC_SEARCH_LIBS([readline],[edit],[ AC_DEFINE([HAVE_EDITLINE],1,Define to use BSD editline) - READLINE_LIBS=$LIBS + READLINE_LIBS="$LIBS -ltinfo" enable_readline=no - ]) + ],[],[-ltinfo]) AS_UNSET(ac_cv_search_readline) LIBS=$sLIBS ]) diff --git a/manifest b/manifest index 24dc30b166..c5b123ea51 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Do\snot\srun\stest\sfile\sautoanalyze1.test\sif\sOMIT_VIRTUALTABLE\sis\sdefined. -D 2017-03-23T17:22:09.188 +C Improvement\sto\sthe\samalgamation\sconfigure.ac\sfile\scontributed\sby\nBob\sFriesenhahn. +D 2017-03-23T19:51:38.579 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1faf9f06aadc9284c212dea7bbc7c0dea7e8337f0287c81001eff500912c790a @@ -14,7 +14,7 @@ F autoconf/Makefile.am 1a47d071e3d5435f8f7ebff7eb6703848bbd65d4 F autoconf/Makefile.msc 92e3d7fd64dc5c23a23d33824ee4709aaea00a6331c4bb41a1aadcf6600a49f7 F autoconf/README.first 6c4f34fe115ff55d4e8dbfa3cecf04a0188292f7 F autoconf/README.txt 4f04b0819303aabaa35fff5f7b257fb0c1ef95f1 -F autoconf/configure.ac cacf2616abf6e4a569bde2ef365c143caeec40bc +F autoconf/configure.ac 2893b823ecc86cea13739f6c8109a41392254d1db08235c5615e0af5722c8578 F autoconf/tea/Makefile.in b438a7020446c8a8156e8d97c8914a04833da6fd F autoconf/tea/README 3e9a3c060f29a44344ab50aec506f4db903fb873 F autoconf/tea/aclocal.m4 52c47aac44ce0ddb1f918b6993e8beb8eee88f43 @@ -1567,7 +1567,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 9f2e04d3c3526b5ff60d941aa6d5446f602cab37cb93972937f39eefabd6868d -R c389878b6e059490204890f1ea916f73 -U dan -Z b2d2e5c74dc6093684311a4bed08a5d2 +P e1d06a573ee56bf6a14e4dc8086d6a4df1464f2914834cf4596a0a406688f608 +R 05b216864be03a3eba3ef1e51323e9ca +U drh +Z 5c18c26b109b1904b072f9a45f7157f5 diff --git a/manifest.uuid b/manifest.uuid index aed4b7d66c..d40ca490c9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e1d06a573ee56bf6a14e4dc8086d6a4df1464f2914834cf4596a0a406688f608 \ No newline at end of file +bf28a55d8185e370fea39de297c37387f852f43fac0a316e5900e633f99b367f \ No newline at end of file From 37f03dfb1f1f0c5668ef9d8ab61352712d368c96 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 23 Mar 2017 20:33:49 +0000 Subject: [PATCH 1466/1484] Change the name of the json_merge_patch() function to just json_patch(). FossilOrigin-Name: 04d4100445a3373986ee962618bc03ec304f6ba2f867c8e9eee415daffb593fc --- ext/misc/json1.c | 4 ++-- manifest | 14 +++++++------- manifest.uuid | 2 +- test/json104.test | 10 +++++----- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/ext/misc/json1.c b/ext/misc/json1.c index 80b654d68d..acec87c1b8 100644 --- a/ext/misc/json1.c +++ b/ext/misc/json1.c @@ -1431,7 +1431,7 @@ static JsonNode *jsonMergePatch( ** object that is the result of running the RFC 7396 MergePatch() algorithm ** on the two arguments. */ -static void jsonMergePatchFunc( +static void jsonPatchFunc( sqlite3_context *ctx, int argc, sqlite3_value **argv @@ -2260,8 +2260,8 @@ int sqlite3Json1Init(sqlite3 *db){ { "json_array_length", 2, 0, jsonArrayLengthFunc }, { "json_extract", -1, 0, jsonExtractFunc }, { "json_insert", -1, 0, jsonSetFunc }, - { "json_merge_patch", 2, 0, jsonMergePatchFunc }, { "json_object", -1, 0, jsonObjectFunc }, + { "json_patch", 2, 0, jsonPatchFunc }, { "json_quote", 1, 0, jsonQuoteFunc }, { "json_remove", -1, 0, jsonRemoveFunc }, { "json_replace", -1, 0, jsonReplaceFunc }, diff --git a/manifest b/manifest index 0c77a3ba53..d5d959a6f4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sredundant\sedits\sin\sthe\sjson_merge_patch()\sfunction. -D 2017-03-23T12:56:44.298 +C Change\sthe\sname\sof\sthe\sjson_merge_patch()\sfunction\sto\sjust\sjson_patch(). +D 2017-03-23T20:33:49.228 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1faf9f06aadc9284c212dea7bbc7c0dea7e8337f0287c81001eff500912c790a @@ -218,7 +218,7 @@ F ext/misc/eval.c f971962e92ebb8b0a4e6b62949463ee454d88fa2 F ext/misc/fileio.c d4171c815d6543a9edef8308aab2951413cd8d0f F ext/misc/fuzzer.c 7c64b8197bb77b7d64eff7cac7848870235d4c25 F ext/misc/ieee754.c f190d0cc5182529acb15babd177781be1ac1718c -F ext/misc/json1.c dbb168b0a7640a896a565c647dcabb7c7d116c9d2b1a23b963b1d177edc0ddba +F ext/misc/json1.c c065914b126b5f4696b824286fca153da8035bb8c660a15193ea2711668f1d14 F ext/misc/memvfs.c e5225bc22e79dde6b28380f3a068ddf600683a33 F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342 F ext/misc/percentile.c 92699c8cd7d517ff610e6037e56506f8904dae2e @@ -913,7 +913,7 @@ F test/jrnlmode3.test 556b447a05be0e0963f4311e95ab1632b11c9eaa F test/json101.test c0897616f32d95431f37fd291cb78742181980ac F test/json102.test bf3fe7a706d30936a76a0f7a0375e1e8e73aff5a F test/json103.test c5f6b85e69de05f6b3195f9f9d5ce9cd179099a0 -F test/json104.test 9f8358fd4ec94eca27b31d4ad7f75482edf24c865df378e5129c0b3107c9664e +F test/json104.test b6808a3efb973235331c274ebe251bfbf75c6fff0ff12956fb9719cc227a9f5b F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff F test/kvtest.c b9a9822dda05a1aa481215a52e2fc93cd8b22ee5 F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63 @@ -1568,7 +1568,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 5d2cf5a2f8afd88d041d89b3936042ce5a43629d23c48738cb2791b24da3e6af -R 76e620c002fc08a86767847f533fe70a +P 4a8e6437dd610c5376a07867a73e5a7e2ea90357a018e1788ecce6f4e10bc939 +R d0e9240b8b29f168e87723d2f33d4c1f U drh -Z 538e213b7e95dcafcfcd2e7dd4b1a792 +Z bc4bcd04349b5b8bc6712e6bdee5b622 diff --git a/manifest.uuid b/manifest.uuid index da2d4e0201..7097a2526e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4a8e6437dd610c5376a07867a73e5a7e2ea90357a018e1788ecce6f4e10bc939 \ No newline at end of file +04d4100445a3373986ee962618bc03ec304f6ba2f867c8e9eee415daffb593fc \ No newline at end of file diff --git a/test/json104.test b/test/json104.test index b5a45bc525..ff17147723 100644 --- a/test/json104.test +++ b/test/json104.test @@ -8,7 +8,7 @@ # May you share freely, never taking more than you give. # #*********************************************************************** -# This file implements tests for json_mergepatch(A,B) SQL function. +# This file implements tests for json_patch(A,B) SQL function. # set testdir [file dirname $argv0] @@ -21,7 +21,7 @@ ifcapable !json1 { # This is the example from pages 2 and 3 of RFC-7396 do_execsql_test json104-100 { - SELECT json_merge_patch('{ + SELECT json_patch('{ "a": "b", "c": { "d": "e", @@ -38,7 +38,7 @@ do_execsql_test json104-100 { # This is the example from pages 4 and 5 of RFC-7396 do_execsql_test json104-110 { - SELECT json_merge_patch('{ + SELECT json_patch('{ "title": "Goodbye!", "author" : { "givenName" : "John", @@ -57,10 +57,10 @@ do_execsql_test json104-110 { } {{{"title":"Hello!","author":{"givenName":"John"},"tags":["example"],"content":"This will be unchanged","phoneNumber":"+01-123-456-7890"}}} do_execsql_test json104-200 { - SELECT json_merge_patch('[1,2,3]','{"x":null}'); + SELECT json_patch('[1,2,3]','{"x":null}'); } {{{}}} do_execsql_test json104-210 { - SELECT json_merge_patch('[1,2,3]','{"x":null,"y":1,"z":null}'); + SELECT json_patch('[1,2,3]','{"x":null,"y":1,"z":null}'); } {{{"y":1}}} finish_test From 29c996987114728518feb15903b5366c00023164 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 24 Mar 2017 12:35:17 +0000 Subject: [PATCH 1467/1484] Fix an error in the new json_patch() routine discovered by Ralf Junker. FossilOrigin-Name: 9d5350418b2f6113e0b50c57e8a872006f27753067baf08ffdfa7943c0c9a148 --- ext/misc/json1.c | 26 +++++++++++++++++++++----- manifest | 15 +++++++-------- manifest.uuid | 2 +- test/json104.test | 10 ++++++++++ 4 files changed, 39 insertions(+), 14 deletions(-) diff --git a/ext/misc/json1.c b/ext/misc/json1.c index acec87c1b8..2689726302 100644 --- a/ext/misc/json1.c +++ b/ext/misc/json1.c @@ -1164,6 +1164,25 @@ static void jsonWrongNumArgs( sqlite3_free(zMsg); } +/* +** Mark all NULL entries in the Object passed in as JNODE_REMOVE. +*/ +static void jsonRemoveAllNulls(JsonNode *pNode){ + int i, n; + assert( pNode->eType==JSON_OBJECT ); + n = pNode->n; + for(i=2; i<=n; i += jsonNodeSize(&pNode[i])+1){ + switch( pNode[i].eType ){ + case JSON_NULL: + pNode[i].jnFlags |= JNODE_REMOVE; + break; + case JSON_OBJECT: + jsonRemoveAllNulls(&pNode[i]); + break; + } + } +} + /**************************************************************************** ** SQL functions used for testing and debugging @@ -1373,11 +1392,7 @@ static JsonNode *jsonMergePatch( pTarget = &pParse->aNode[iTarget]; assert( (pPatch->jnFlags & JNODE_APPEND)==0 ); if( pTarget->eType!=JSON_OBJECT ){ - for(i=2; i<=pPatch->n; i += jsonNodeSize(&pPatch[i])+1){ - if( pPatch[i].eType==JSON_NULL ){ - pPatch[i].jnFlags |= JNODE_REMOVE; - } - } + jsonRemoveAllNulls(pPatch); return pPatch; } iRoot = iTarget; @@ -1415,6 +1430,7 @@ static JsonNode *jsonMergePatch( jsonParseAddNode(pParse, JSON_STRING, nKey, zKey); iPatch = jsonParseAddNode(pParse, JSON_TRUE, 0, 0); if( pParse->oom ) return 0; + jsonRemoveAllNulls(pPatch); pTarget = &pParse->aNode[iTarget]; pParse->aNode[iRoot].jnFlags |= JNODE_APPEND; pParse->aNode[iRoot].u.iAppend = iStart - iRoot; diff --git a/manifest b/manifest index b843ff3c58..b1f0b85dcc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sjson_patch()\sSQL\sfunction\sto\sthe\sJSON1\sextension. -D 2017-03-23T23:44:55.894 +C Fix\san\serror\sin\sthe\snew\sjson_patch()\sroutine\sdiscovered\sby\sRalf\sJunker. +D 2017-03-24T12:35:17.534 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1faf9f06aadc9284c212dea7bbc7c0dea7e8337f0287c81001eff500912c790a @@ -218,7 +218,7 @@ F ext/misc/eval.c f971962e92ebb8b0a4e6b62949463ee454d88fa2 F ext/misc/fileio.c d4171c815d6543a9edef8308aab2951413cd8d0f F ext/misc/fuzzer.c 7c64b8197bb77b7d64eff7cac7848870235d4c25 F ext/misc/ieee754.c f190d0cc5182529acb15babd177781be1ac1718c -F ext/misc/json1.c c065914b126b5f4696b824286fca153da8035bb8c660a15193ea2711668f1d14 +F ext/misc/json1.c 52f93b91b8bbbfcd84dca34be383974137e83a1673c71d5f728b16b68bb57d9c F ext/misc/memvfs.c e5225bc22e79dde6b28380f3a068ddf600683a33 F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342 F ext/misc/percentile.c 92699c8cd7d517ff610e6037e56506f8904dae2e @@ -913,7 +913,7 @@ F test/jrnlmode3.test 556b447a05be0e0963f4311e95ab1632b11c9eaa F test/json101.test c0897616f32d95431f37fd291cb78742181980ac F test/json102.test bf3fe7a706d30936a76a0f7a0375e1e8e73aff5a F test/json103.test c5f6b85e69de05f6b3195f9f9d5ce9cd179099a0 -F test/json104.test b6808a3efb973235331c274ebe251bfbf75c6fff0ff12956fb9719cc227a9f5b +F test/json104.test 2966101e14463655546eb8f639db25382957e9b7136de717e17db945a6f539fb F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff F test/kvtest.c b9a9822dda05a1aa481215a52e2fc93cd8b22ee5 F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63 @@ -1568,8 +1568,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P bf28a55d8185e370fea39de297c37387f852f43fac0a316e5900e633f99b367f 04d4100445a3373986ee962618bc03ec304f6ba2f867c8e9eee415daffb593fc -R 114c4ffb4ff05c31b0d61e7341b119eb -T +closed 04d4100445a3373986ee962618bc03ec304f6ba2f867c8e9eee415daffb593fc +P 476088482024e411e2549b1697cdaf0124294c79d43f508c71c4eb66906a56fc +R 08d6f399deb89f284d166c511d46a6ea U drh -Z 015dcf3dd857377b8513b610e324274e +Z 437a93d0f27334776c018af18840b42a diff --git a/manifest.uuid b/manifest.uuid index 4f00615e01..4ff617a710 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -476088482024e411e2549b1697cdaf0124294c79d43f508c71c4eb66906a56fc \ No newline at end of file +9d5350418b2f6113e0b50c57e8a872006f27753067baf08ffdfa7943c0c9a148 \ No newline at end of file diff --git a/test/json104.test b/test/json104.test index ff17147723..5d93991eb1 100644 --- a/test/json104.test +++ b/test/json104.test @@ -62,5 +62,15 @@ do_execsql_test json104-200 { do_execsql_test json104-210 { SELECT json_patch('[1,2,3]','{"x":null,"y":1,"z":null}'); } {{{"y":1}}} +do_execsql_test json104-220 { + SELECT json_patch('{}','{"a":{"bb":{"ccc":null}}}'); +} {{{"a":{"bb":{}}}}} +do_execsql_test json104-221 { + SELECT json_patch('{}','{"a":{"bb":{"ccc":[1,null,3]}}}'); +} {{{"a":{"bb":{"ccc":[1,null,3]}}}}} +do_execsql_test json104-222 { + SELECT json_patch('{}','{"a":{"bb":{"ccc":[1,{"dddd":null},3]}}}'); +} {{{"a":{"bb":{"ccc":[1,{"dddd":null},3]}}}}} + finish_test From f9e91972c94e198a5c6406eeccb7068c35779211 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 24 Mar 2017 13:31:47 +0000 Subject: [PATCH 1468/1484] Add the RFC-7396 Appendix A test cases for json_patch(). FossilOrigin-Name: c5441d2df2526723f72610cc14dd243223663979e67ecdd76fe06fcd366f2b29 --- manifest | 12 +++++------ manifest.uuid | 2 +- test/json104.test | 54 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 61 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index b1f0b85dcc..cfdc624046 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\serror\sin\sthe\snew\sjson_patch()\sroutine\sdiscovered\sby\sRalf\sJunker. -D 2017-03-24T12:35:17.534 +C Add\sthe\sRFC-7396\sAppendix\sA\stest\scases\sfor\sjson_patch(). +D 2017-03-24T13:31:47.314 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1faf9f06aadc9284c212dea7bbc7c0dea7e8337f0287c81001eff500912c790a @@ -913,7 +913,7 @@ F test/jrnlmode3.test 556b447a05be0e0963f4311e95ab1632b11c9eaa F test/json101.test c0897616f32d95431f37fd291cb78742181980ac F test/json102.test bf3fe7a706d30936a76a0f7a0375e1e8e73aff5a F test/json103.test c5f6b85e69de05f6b3195f9f9d5ce9cd179099a0 -F test/json104.test 2966101e14463655546eb8f639db25382957e9b7136de717e17db945a6f539fb +F test/json104.test 877d5845f6303899b7889ea5dd1bea99076e3100574d5c536082245c5805dcaa F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff F test/kvtest.c b9a9822dda05a1aa481215a52e2fc93cd8b22ee5 F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63 @@ -1568,7 +1568,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 476088482024e411e2549b1697cdaf0124294c79d43f508c71c4eb66906a56fc -R 08d6f399deb89f284d166c511d46a6ea +P 9d5350418b2f6113e0b50c57e8a872006f27753067baf08ffdfa7943c0c9a148 +R f5d3be53ea90768240f7c6616a0ecd20 U drh -Z 437a93d0f27334776c018af18840b42a +Z c6323f1875b7921e440a4d008ab9c650 diff --git a/manifest.uuid b/manifest.uuid index 4ff617a710..40296ca7c1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9d5350418b2f6113e0b50c57e8a872006f27753067baf08ffdfa7943c0c9a148 \ No newline at end of file +c5441d2df2526723f72610cc14dd243223663979e67ecdd76fe06fcd366f2b29 \ No newline at end of file diff --git a/test/json104.test b/test/json104.test index 5d93991eb1..b5313f01b5 100644 --- a/test/json104.test +++ b/test/json104.test @@ -72,5 +72,59 @@ do_execsql_test json104-222 { SELECT json_patch('{}','{"a":{"bb":{"ccc":[1,{"dddd":null},3]}}}'); } {{{"a":{"bb":{"ccc":[1,{"dddd":null},3]}}}}} +# Example test cases at the end of the RFC-7396 document +do_execsql_test json104-300 { + SELECT json_patch('{"a":"b"}','{"a":"c"}'); +} {{{"a":"c"}}} +do_execsql_test json104-300a { + SELECT coalesce(json_patch(null,'{"a":"c"}'), 'real-null'); +} {{real-null}} +do_execsql_test json104-301 { + SELECT json_patch('{"a":"b"}','{"b":"c"}'); +} {{{"a":"b","b":"c"}}} +do_execsql_test json104-302 { + SELECT json_patch('{"a":"b"}','{"a":null}'); +} {{{}}} +do_execsql_test json104-303 { + SELECT json_patch('{"a":"b","b":"c"}','{"a":null}'); +} {{{"b":"c"}}} +do_execsql_test json104-304 { + SELECT json_patch('{"a":["b"]}','{"a":"c"}'); +} {{{"a":"c"}}} +do_execsql_test json104-305 { + SELECT json_patch('{"a":"c"}','{"a":["b"]}'); +} {{{"a":["b"]}}} +do_execsql_test json104-306 { + SELECT json_patch('{"a":{"b":"c"}}','{"a":{"b":"d","c":null}}'); +} {{{"a":{"b":"d"}}}} +do_execsql_test json104-307 { + SELECT json_patch('{"a":[{"b":"c"}]}','{"a":[1]}'); +} {{{"a":[1]}}} +do_execsql_test json104-308 { + SELECT json_patch('["a","b"]','["c","d"]'); +} {{["c","d"]}} +do_execsql_test json104-309 { + SELECT json_patch('{"a":"b"}','["c"]'); +} {{["c"]}} +do_execsql_test json104-310 { + SELECT json_patch('{"a":"foo"}','null'); +} {{null}} +do_execsql_test json104-310a { + SELECT coalesce(json_patch('{"a":"foo"}',null), 'real-null'); +} {{real-null}} +do_execsql_test json104-311 { + SELECT json_patch('{"a":"foo"}','"bar"'); +} {{"bar"}} +do_execsql_test json104-312 { + SELECT json_patch('{"e":null}','{"a":1}'); +} {{{"e":null,"a":1}}} +do_execsql_test json104-313 { + SELECT json_patch('[1,2]','{"a":"b","c":null}'); +} {{{"a":"b"}}} +do_execsql_test json104-314 { + SELECT json_patch('{}','{"a":{"bb":{"ccc":null}}}'); +} {{{"a":{"bb":{}}}}} + + finish_test From ab087d4e67077e80b30caa34bae869af55773647 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 24 Mar 2017 17:59:56 +0000 Subject: [PATCH 1469/1484] Fix the OP_Once opcode so that it works correctly for recursive triggers. Ticket [06796225f59c057cd120f1]. FossilOrigin-Name: 2556014514f36808e6d18b25722eae0daeeb8fbb5d18af13a9698ea6c6db1679 --- manifest | 17 +++++++++-------- manifest.uuid | 2 +- src/vdbe.c | 40 ++++++++++++++++++++++++++++++--------- src/vdbe.h | 1 + src/vdbeInt.h | 1 + test/triggerG.test | 47 ++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 90 insertions(+), 18 deletions(-) create mode 100644 test/triggerG.test diff --git a/manifest b/manifest index cfdc624046..f9ac9232e6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sRFC-7396\sAppendix\sA\stest\scases\sfor\sjson_patch(). -D 2017-03-24T13:31:47.314 +C Fix\sthe\sOP_Once\sopcode\sso\sthat\sit\sworks\scorrectly\sfor\srecursive\striggers.\nTicket\s[06796225f59c057cd120f1]. +D 2017-03-24T17:59:56.312 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1faf9f06aadc9284c212dea7bbc7c0dea7e8337f0287c81001eff500912c790a @@ -468,9 +468,9 @@ F src/update.c 456d4a4656f8a03c2abc88a51b19172197400e58 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c ca8440ede81e155d15cff7c101654f60b55a9ae6 F src/vacuum.c 1fe4555cd8c9b263afb85b5b4ee3a4a4181ad569 -F src/vdbe.c 89a12451405a17c6e8d39b5826acb6999f1283e4e43d2e83a7ac7c9a7094a86a -F src/vdbe.h 59998ffd71d7caa8886bc78dafaf8caeccd4c13c -F src/vdbeInt.h 4e4b15b2e1330e1636e4e01974eab2b0b985092f +F src/vdbe.c e59bd3416627d11f76da18ed5a85e93b3c6172892a9d44371d05a7c7183d7b94 +F src/vdbe.h caa5346d52bae2a3c8c1dcfa60a7a4dc878a9e3865cb8239da55808b316c8158 +F src/vdbeInt.h 5db089ce18c4feff8820ec6e4cac2d2c82e03d4b1d96f10a6e43832147b8dffe F src/vdbeapi.c 5b08d82592bcff4470601fe78aaabebd50837860 F src/vdbeaux.c ecd0468611925d218e1eb4b3f538907904b136f0e15e333291a232b521bfcef1 F src/vdbeblob.c 359891617358deefc85bef7bcf787fa6b77facb9 @@ -1360,6 +1360,7 @@ F test/triggerC.test 302d8995f5ffe63bbc15053abb3ef7a39cf5a092 F test/triggerD.test 8e7f3921a92a5797d472732108109e44575fa650 F test/triggerE.test 15fa63f1097db1f83dd62d121616006978063d1f F test/triggerF.test 55b1eb13433997faac3a4948c1d8252f6c8c636b +F test/triggerG.test 6eb0dbb4ce35df990034e54951e882c69ffbc3462e9c33a021edf66464f8b91b F test/tt3_checkpoint.c 9e75cf7c1c364f52e1c47fd0f14c4340a9db0fe1 F test/tt3_index.c 39eec10a35f57672225be4d182862152896dee4a F test/tt3_lookaside1.c 0377e202c3c2a50d688cb65ba203afeda6fafeb9 @@ -1568,7 +1569,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 9d5350418b2f6113e0b50c57e8a872006f27753067baf08ffdfa7943c0c9a148 -R f5d3be53ea90768240f7c6616a0ecd20 +P c5441d2df2526723f72610cc14dd243223663979e67ecdd76fe06fcd366f2b29 +R 06e33989e2f9f8999f70d02209e735fb U drh -Z c6323f1875b7921e440a4d008ab9c650 +Z d9ba825914c037a52e49ea53bb54865f diff --git a/manifest.uuid b/manifest.uuid index 40296ca7c1..1ba0445ee1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c5441d2df2526723f72610cc14dd243223663979e67ecdd76fe06fcd366f2b29 \ No newline at end of file +2556014514f36808e6d18b25722eae0daeeb8fbb5d18af13a9698ea6c6db1679 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 93c20c0aaa..5e99366b2d 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2332,19 +2332,39 @@ case OP_BitNot: { /* same as TK_BITNOT, in1, out2 */ /* Opcode: Once P1 P2 * * * ** -** If the P1 value is equal to the P1 value on the OP_Init opcode at -** instruction 0, then jump to P2. If the two P1 values differ, then -** set the P1 value on this opcode to equal the P1 value on the OP_Init -** and fall through. +** Fall through to the next instruction the first time this opcode is +** encountered on each invocation of the byte-code program. Jump to P2 +** on the second and all subsequent encounters during the same invocation. +** +** Top-level programs determine first invocation by comparing the P1 +** operand against the P1 operand on the OP_Init opcode at the beginning +** of the program. If the P1 values differ, then fall through and make +** the P1 of this opcode equal to the P1 of OP_Init. If P1 values are +** the same then take the jump. +** +** For subprograms, there is a bitmask in the VdbeFrame that determines +** whether or not the jump should be taken. The bitmask is necessary +** because the self-altering code trick does not work for recursive +** triggers. */ case OP_Once: { /* jump */ + u32 iAddr; /* Address of this instruction */ assert( p->aOp[0].opcode==OP_Init ); - VdbeBranchTaken(p->aOp[0].p1==pOp->p1, 2); - if( p->aOp[0].p1==pOp->p1 ){ - goto jump_to_p2; + if( p->pFrame ){ + iAddr = (int)(pOp - p->aOp); + if( (p->pFrame->aOnce[iAddr/8] & (1<<(iAddr & 7)))!=0 ){ + VdbeBranchTaken(1, 2); + p->pFrame->aOnce[iAddr/8] |= 1<<(iAddr & 7); + goto jump_to_p2; + } }else{ - pOp->p1 = p->aOp[0].p1; + if( p->aOp[0].p1==pOp->p1 ){ + VdbeBranchTaken(1, 2); + goto jump_to_p2; + } } + VdbeBranchTaken(0, 2); + pOp->p1 = p->aOp[0].p1; break; } @@ -5870,7 +5890,8 @@ case OP_Program: { /* jump */ if( pProgram->nCsr==0 ) nMem++; nByte = ROUND8(sizeof(VdbeFrame)) + nMem * sizeof(Mem) - + pProgram->nCsr * sizeof(VdbeCursor *); + + pProgram->nCsr * sizeof(VdbeCursor*) + + (pProgram->nOp + 7)/8; pFrame = sqlite3DbMallocZero(db, nByte); if( !pFrame ){ goto no_mem; @@ -5921,6 +5942,7 @@ case OP_Program: { /* jump */ p->nMem = pFrame->nChildMem; p->nCursor = (u16)pFrame->nChildCsr; p->apCsr = (VdbeCursor **)&aMem[p->nMem]; + pFrame->aOnce = (u8*)&p->apCsr[pProgram->nCsr]; p->aOp = aOp = pProgram->aOp; p->nOp = pProgram->nOp; #ifdef SQLITE_ENABLE_STMT_SCANSTATUS diff --git a/src/vdbe.h b/src/vdbe.h index a35f3be344..be19bc5316 100644 --- a/src/vdbe.h +++ b/src/vdbe.h @@ -87,6 +87,7 @@ struct SubProgram { int nOp; /* Elements in aOp[] */ int nMem; /* Number of memory cells required */ int nCsr; /* Number of cursors required */ + u8 *aOnce; /* Array of OP_Once flags */ void *token; /* id that may be used to recursive triggers */ SubProgram *pNext; /* Next sub-program already visited */ }; diff --git a/src/vdbeInt.h b/src/vdbeInt.h index 989cdfd346..c0435a5a79 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -164,6 +164,7 @@ struct VdbeFrame { i64 *anExec; /* Event counters from parent frame */ Mem *aMem; /* Array of memory cells for parent frame */ VdbeCursor **apCsr; /* Array of Vdbe cursors for parent frame */ + u8 *aOnce; /* Bitmask used by OP_Once */ void *token; /* Copy of SubProgram.token */ i64 lastRowid; /* Last insert rowid (sqlite3.lastRowid) */ AuxData *pAuxData; /* Linked list of auxdata allocations */ diff --git a/test/triggerG.test b/test/triggerG.test new file mode 100644 index 0000000000..9faa898dc3 --- /dev/null +++ b/test/triggerG.test @@ -0,0 +1,47 @@ +# 2017-03-24 +# +# 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. +# +#*********************************************************************** +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix triggerG +ifcapable {!trigger} { + finish_test + return +} + +# Test cases for ticket +# https://www.sqlite.org/src/tktview/06796225f59c057cd120f +# +# The OP_Once opcode was not working correctly for recursive triggers. +# +do_execsql_test 100 { + PRAGMA recursive_triggers = 1; + + CREATE TABLE t1(a); + CREATE INDEX i1 ON t1(a); + INSERT INTO t1(a) VALUES(0),(2),(3),(8),(9); + CREATE TABLE t2(b); + CREATE TABLE t3(c); + + CREATE TRIGGER tr AFTER INSERT ON t3 BEGIN + INSERT INTO t3 SELECT new.c+1 WHERE new.c<5; + INSERT INTO t2 SELECT new.c*100+a FROM t1 WHERE a IN (1, 2, 3, 4); + END; + + INSERT INTO t3 VALUES(2); + SELECT c FROM t3 ORDER BY c;; +} {2 3 4 5} +do_execsql_test 110 { + SELECT b FROM t2 ORDER BY b; +} {202 203 302 303 402 403 502 503} + +finish_test From 18333efd51814cecb3af5718abfbd867b10cd6a6 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 24 Mar 2017 18:38:41 +0000 Subject: [PATCH 1470/1484] Previous check-in was not correct. This is a better fix for the OP_Once problem of ticket [06796225f59c057cd120f1]. FossilOrigin-Name: 8194dd2814b0b3f8cffbcb16306f55aabf1c1508b9d27fa806f92f0e6ecd7631 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/vdbe.c | 3 ++- test/triggerG.test | 18 ++++++++++++++++++ 4 files changed, 28 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index f9ac9232e6..e0db435a03 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\sOP_Once\sopcode\sso\sthat\sit\sworks\scorrectly\sfor\srecursive\striggers.\nTicket\s[06796225f59c057cd120f1]. -D 2017-03-24T17:59:56.312 +C Previous\scheck-in\swas\snot\scorrect.\s\sThis\sis\sa\sbetter\sfix\sfor\sthe\sOP_Once\nproblem\sof\sticket\s[06796225f59c057cd120f1]. +D 2017-03-24T18:38:41.822 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1faf9f06aadc9284c212dea7bbc7c0dea7e8337f0287c81001eff500912c790a @@ -468,7 +468,7 @@ F src/update.c 456d4a4656f8a03c2abc88a51b19172197400e58 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c ca8440ede81e155d15cff7c101654f60b55a9ae6 F src/vacuum.c 1fe4555cd8c9b263afb85b5b4ee3a4a4181ad569 -F src/vdbe.c e59bd3416627d11f76da18ed5a85e93b3c6172892a9d44371d05a7c7183d7b94 +F src/vdbe.c f1acf5744cef62cbfd0b503d84289f840b6cdc980ac47b0d9632dfdb89cc79eb F src/vdbe.h caa5346d52bae2a3c8c1dcfa60a7a4dc878a9e3865cb8239da55808b316c8158 F src/vdbeInt.h 5db089ce18c4feff8820ec6e4cac2d2c82e03d4b1d96f10a6e43832147b8dffe F src/vdbeapi.c 5b08d82592bcff4470601fe78aaabebd50837860 @@ -1360,7 +1360,7 @@ F test/triggerC.test 302d8995f5ffe63bbc15053abb3ef7a39cf5a092 F test/triggerD.test 8e7f3921a92a5797d472732108109e44575fa650 F test/triggerE.test 15fa63f1097db1f83dd62d121616006978063d1f F test/triggerF.test 55b1eb13433997faac3a4948c1d8252f6c8c636b -F test/triggerG.test 6eb0dbb4ce35df990034e54951e882c69ffbc3462e9c33a021edf66464f8b91b +F test/triggerG.test 175cafdc6399d85231a09e82e051b0e45a2fd1f23dd08ae715bc359716149ab6 F test/tt3_checkpoint.c 9e75cf7c1c364f52e1c47fd0f14c4340a9db0fe1 F test/tt3_index.c 39eec10a35f57672225be4d182862152896dee4a F test/tt3_lookaside1.c 0377e202c3c2a50d688cb65ba203afeda6fafeb9 @@ -1569,7 +1569,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P c5441d2df2526723f72610cc14dd243223663979e67ecdd76fe06fcd366f2b29 -R 06e33989e2f9f8999f70d02209e735fb +P 2556014514f36808e6d18b25722eae0daeeb8fbb5d18af13a9698ea6c6db1679 +R 0d4df4a8a9e2796f99d4dab5fea97642 U drh -Z d9ba825914c037a52e49ea53bb54865f +Z 19353cf9e153b27d983c51cfd380c21a diff --git a/manifest.uuid b/manifest.uuid index 1ba0445ee1..71e1d00f96 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2556014514f36808e6d18b25722eae0daeeb8fbb5d18af13a9698ea6c6db1679 \ No newline at end of file +8194dd2814b0b3f8cffbcb16306f55aabf1c1508b9d27fa806f92f0e6ecd7631 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 5e99366b2d..406394c5be 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2354,9 +2354,9 @@ case OP_Once: { /* jump */ iAddr = (int)(pOp - p->aOp); if( (p->pFrame->aOnce[iAddr/8] & (1<<(iAddr & 7)))!=0 ){ VdbeBranchTaken(1, 2); - p->pFrame->aOnce[iAddr/8] |= 1<<(iAddr & 7); goto jump_to_p2; } + p->pFrame->aOnce[iAddr/8] |= 1<<(iAddr & 7); }else{ if( p->aOp[0].p1==pOp->p1 ){ VdbeBranchTaken(1, 2); @@ -5943,6 +5943,7 @@ case OP_Program: { /* jump */ p->nCursor = (u16)pFrame->nChildCsr; p->apCsr = (VdbeCursor **)&aMem[p->nMem]; pFrame->aOnce = (u8*)&p->apCsr[pProgram->nCsr]; + memset(pFrame->aOnce, 0, (pProgram->nOp + 7)/8); p->aOp = aOp = pProgram->aOp; p->nOp = pProgram->nOp; #ifdef SQLITE_ENABLE_STMT_SCANSTATUS diff --git a/test/triggerG.test b/test/triggerG.test index 9faa898dc3..c770b5bd76 100644 --- a/test/triggerG.test +++ b/test/triggerG.test @@ -44,4 +44,22 @@ do_execsql_test 110 { SELECT b FROM t2 ORDER BY b; } {202 203 302 303 402 403 502 503} +do_execsql_test 200 { + DELETE FROM t1; + INSERT INTO t1(a) VALUES(0),(2),(3),(8),(9); + DELETE FROM t2; + DELETE FROM t3; + DROP TRIGGER tr; + CREATE TRIGGER tr AFTER INSERT ON t3 BEGIN + INSERT INTO t3 SELECT new.c+1 WHERE new.c<5; + INSERT INTO t2 SELECT new.c*10000+xx.a*100+yy.a + FROM t1 AS xx, t1 AS yy + WHERE xx.a IN (1,2,3,4) + AND yy.a IN (2,3,4,5); + END; + + INSERT INTO t3 VALUES(2); + SELECT b FROM t2 ORDER BY b; +} {20202 20203 20302 20303 30202 30203 30302 30303 40202 40203 40302 40303 50202 50203 50302 50303} + finish_test From ba7cce317bd8da97f01096fc3f0993d2f5c577f9 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 24 Mar 2017 19:45:05 +0000 Subject: [PATCH 1471/1484] Fix a harmless compiler warning in the JSON1 extension. FossilOrigin-Name: c2c3dd84534bb5ea81c974847b74a166c9cba1545fc749ce625929f303bf22e4 --- ext/misc/json1.c | 2 +- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/ext/misc/json1.c b/ext/misc/json1.c index 2689726302..7563229136 100644 --- a/ext/misc/json1.c +++ b/ext/misc/json1.c @@ -1397,7 +1397,7 @@ static JsonNode *jsonMergePatch( } iRoot = iTarget; for(i=1; in; i += jsonNodeSize(&pPatch[i+1])+1){ - int nKey; + u32 nKey; const char *zKey; assert( pPatch[i].eType==JSON_STRING ); assert( pPatch[i].jnFlags & JNODE_LABEL ); diff --git a/manifest b/manifest index e0db435a03..909b15bb9f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Previous\scheck-in\swas\snot\scorrect.\s\sThis\sis\sa\sbetter\sfix\sfor\sthe\sOP_Once\nproblem\sof\sticket\s[06796225f59c057cd120f1]. -D 2017-03-24T18:38:41.822 +C Fix\sa\sharmless\scompiler\swarning\sin\sthe\sJSON1\sextension. +D 2017-03-24T19:45:05.590 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1faf9f06aadc9284c212dea7bbc7c0dea7e8337f0287c81001eff500912c790a @@ -218,7 +218,7 @@ F ext/misc/eval.c f971962e92ebb8b0a4e6b62949463ee454d88fa2 F ext/misc/fileio.c d4171c815d6543a9edef8308aab2951413cd8d0f F ext/misc/fuzzer.c 7c64b8197bb77b7d64eff7cac7848870235d4c25 F ext/misc/ieee754.c f190d0cc5182529acb15babd177781be1ac1718c -F ext/misc/json1.c 52f93b91b8bbbfcd84dca34be383974137e83a1673c71d5f728b16b68bb57d9c +F ext/misc/json1.c f963c2b86201c4a91a40b8e1a36e9ae8b9787435be09e0a77f4af3366a21b8e5 F ext/misc/memvfs.c e5225bc22e79dde6b28380f3a068ddf600683a33 F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342 F ext/misc/percentile.c 92699c8cd7d517ff610e6037e56506f8904dae2e @@ -1569,7 +1569,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 2556014514f36808e6d18b25722eae0daeeb8fbb5d18af13a9698ea6c6db1679 -R 0d4df4a8a9e2796f99d4dab5fea97642 +P 8194dd2814b0b3f8cffbcb16306f55aabf1c1508b9d27fa806f92f0e6ecd7631 +R 62e08e896f8ca109e8d6d3c509082b9a U drh -Z 19353cf9e153b27d983c51cfd380c21a +Z 05f31e3559927efd389ed5e57c4ee57c diff --git a/manifest.uuid b/manifest.uuid index 71e1d00f96..c8b35554c2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8194dd2814b0b3f8cffbcb16306f55aabf1c1508b9d27fa806f92f0e6ecd7631 \ No newline at end of file +c2c3dd84534bb5ea81c974847b74a166c9cba1545fc749ce625929f303bf22e4 \ No newline at end of file From 2fb79e9b046209dd03530c3729fcc999b0ffd639 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 25 Mar 2017 12:08:11 +0000 Subject: [PATCH 1472/1484] Fix two harmless compiler warnings. FossilOrigin-Name: 32be9c3faaafd736da3f49d475dc9279af4e4ba38070b60033d898345080acf0 --- ext/misc/json1.c | 1 + manifest | 14 +++++++------- manifest.uuid | 2 +- src/shell.c | 1 + 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/ext/misc/json1.c b/ext/misc/json1.c index 7563229136..bad5cd9b53 100644 --- a/ext/misc/json1.c +++ b/ext/misc/json1.c @@ -1456,6 +1456,7 @@ static void jsonPatchFunc( JsonParse y; /* The patch */ JsonNode *pResult; /* The result of the merge */ + UNUSED_PARAM(argc); if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return; if( jsonParse(&y, ctx, (const char*)sqlite3_value_text(argv[1])) ){ jsonParseReset(&x); diff --git a/manifest b/manifest index 909b15bb9f..2808a2dabb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sharmless\scompiler\swarning\sin\sthe\sJSON1\sextension. -D 2017-03-24T19:45:05.590 +C Fix\stwo\sharmless\scompiler\swarnings. +D 2017-03-25T12:08:11.283 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1faf9f06aadc9284c212dea7bbc7c0dea7e8337f0287c81001eff500912c790a @@ -218,7 +218,7 @@ F ext/misc/eval.c f971962e92ebb8b0a4e6b62949463ee454d88fa2 F ext/misc/fileio.c d4171c815d6543a9edef8308aab2951413cd8d0f F ext/misc/fuzzer.c 7c64b8197bb77b7d64eff7cac7848870235d4c25 F ext/misc/ieee754.c f190d0cc5182529acb15babd177781be1ac1718c -F ext/misc/json1.c f963c2b86201c4a91a40b8e1a36e9ae8b9787435be09e0a77f4af3366a21b8e5 +F ext/misc/json1.c 92b9e404bd79cc76d3ef2b3a9e37bf775700f7d645466fd41d2e8742e3fa16fb F ext/misc/memvfs.c e5225bc22e79dde6b28380f3a068ddf600683a33 F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342 F ext/misc/percentile.c 92699c8cd7d517ff610e6037e56506f8904dae2e @@ -402,7 +402,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 3e518b962d932a997fae373366880fc028c75706 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c 2496d0cc6368dabe7ad2e4c7f5ed3ad9aa3b4d11cd90f33fa1d1ef72493f43aa -F src/shell.c ce39c4bbbaa02484cb45141034fd363c3bac80a6aa22b0bb3cecea1c6a4c0979 +F src/shell.c 042b74d5ad2fd38a7f0c2c0d13f77740f25fba5d33468e75d4648f865ffed4a5 F src/sqlite.h.in 723107d97f2345a7c103632169dc61366121c4ab65d75a7d83c6dc0e5bbe5ca4 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae @@ -1569,7 +1569,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 8194dd2814b0b3f8cffbcb16306f55aabf1c1508b9d27fa806f92f0e6ecd7631 -R 62e08e896f8ca109e8d6d3c509082b9a +P c2c3dd84534bb5ea81c974847b74a166c9cba1545fc749ce625929f303bf22e4 +R 00c481e82c70ac112e4dd5eb0771ef19 U drh -Z 05f31e3559927efd389ed5e57c4ee57c +Z 8a616016b0f4c387418de171c88a7e3f diff --git a/manifest.uuid b/manifest.uuid index c8b35554c2..0fe8e18ce7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c2c3dd84534bb5ea81c974847b74a166c9cba1545fc749ce625929f303bf22e4 \ No newline at end of file +32be9c3faaafd736da3f49d475dc9279af4e4ba38070b60033d898345080acf0 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index e71c34e6df..456fde5fbe 100644 --- a/src/shell.c +++ b/src/shell.c @@ -2085,6 +2085,7 @@ static int callback(void *pArg, int nArg, char **azArg, char **azCol){ static int captureOutputCallback(void *pArg, int nArg, char **azArg, char **az){ ShellText *p = (ShellText*)pArg; int i; + UNUSED_PARAMETER(az); if( p->n ) appendText(p, "|", 0); for(i=0; i Date: Sat, 25 Mar 2017 18:03:26 +0000 Subject: [PATCH 1473/1484] Make the default value for SQLITE_DEFAULT_SYNCHRONOUS a simple integer literal, so that it does not show up goofy in the output of "PRAGMA compile_options;". FossilOrigin-Name: 833ab3212addc340ca8004e8d6a06cc5e51bf256f43dc73d87fbe67518a4891b --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/sqliteInt.h | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 2808a2dabb..67eade98ba 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\stwo\sharmless\scompiler\swarnings. -D 2017-03-25T12:08:11.283 +C Make\sthe\sdefault\svalue\sfor\sSQLITE_DEFAULT_SYNCHRONOUS\sa\ssimple\sinteger\nliteral,\sso\sthat\sit\sdoes\snot\sshow\sup\sgoofy\sin\sthe\soutput\sof\n"PRAGMA\scompile_options;". +D 2017-03-25T18:03:26.758 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1faf9f06aadc9284c212dea7bbc7c0dea7e8337f0287c81001eff500912c790a @@ -406,7 +406,7 @@ F src/shell.c 042b74d5ad2fd38a7f0c2c0d13f77740f25fba5d33468e75d4648f865ffed4a5 F src/sqlite.h.in 723107d97f2345a7c103632169dc61366121c4ab65d75a7d83c6dc0e5bbe5ca4 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae -F src/sqliteInt.h df268ce1d04df042cf43b557d2309eb0b71e86c4 +F src/sqliteInt.h a530e5baf5e559154d5c2e5cc57471bc780a7af4cd0a5d72750b1d850fef1e22 F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 @@ -1569,7 +1569,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P c2c3dd84534bb5ea81c974847b74a166c9cba1545fc749ce625929f303bf22e4 -R 00c481e82c70ac112e4dd5eb0771ef19 +P 32be9c3faaafd736da3f49d475dc9279af4e4ba38070b60033d898345080acf0 +R f2f2293b380c103d1313beba2f4189cc U drh -Z 8a616016b0f4c387418de171c88a7e3f +Z 533fb94c090ecb58ff1b57331e8e6d3d diff --git a/manifest.uuid b/manifest.uuid index 0fe8e18ce7..b258a1fad8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -32be9c3faaafd736da3f49d475dc9279af4e4ba38070b60033d898345080acf0 \ No newline at end of file +833ab3212addc340ca8004e8d6a06cc5e51bf256f43dc73d87fbe67518a4891b \ No newline at end of file diff --git a/src/sqliteInt.h b/src/sqliteInt.h index e95d63ec35..271ea9a3ef 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1127,7 +1127,7 @@ typedef int VList; ** and the one-based values are used internally. */ #ifndef SQLITE_DEFAULT_SYNCHRONOUS -# define SQLITE_DEFAULT_SYNCHRONOUS (PAGER_SYNCHRONOUS_FULL-1) +# define SQLITE_DEFAULT_SYNCHRONOUS 2 #endif #ifndef SQLITE_DEFAULT_WAL_SYNCHRONOUS # define SQLITE_DEFAULT_WAL_SYNCHRONOUS SQLITE_DEFAULT_SYNCHRONOUS From 34ad36bf81d0eae64891cc57ba6aee669321eb58 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 25 Mar 2017 18:15:05 +0000 Subject: [PATCH 1474/1484] Disable the new --preserve-rowids option on the CLI ".dump" command if compiled with SQLITE_OMIT_VIRTUALTABLE. FossilOrigin-Name: bd5bbe4eece9051cc8c27d834d22fb243d34f261641984555d02a27b7038d4f6 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/shell.c | 7 +++++++ 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 67eade98ba..9626fae018 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\sthe\sdefault\svalue\sfor\sSQLITE_DEFAULT_SYNCHRONOUS\sa\ssimple\sinteger\nliteral,\sso\sthat\sit\sdoes\snot\sshow\sup\sgoofy\sin\sthe\soutput\sof\n"PRAGMA\scompile_options;". -D 2017-03-25T18:03:26.758 +C Disable\sthe\snew\s--preserve-rowids\soption\son\sthe\sCLI\s".dump"\scommand\sif\ncompiled\swith\sSQLITE_OMIT_VIRTUALTABLE. +D 2017-03-25T18:15:05.701 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1faf9f06aadc9284c212dea7bbc7c0dea7e8337f0287c81001eff500912c790a @@ -402,7 +402,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 3e518b962d932a997fae373366880fc028c75706 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c 2496d0cc6368dabe7ad2e4c7f5ed3ad9aa3b4d11cd90f33fa1d1ef72493f43aa -F src/shell.c 042b74d5ad2fd38a7f0c2c0d13f77740f25fba5d33468e75d4648f865ffed4a5 +F src/shell.c ceb2b2f1f958ea2c47a7f37972d0f715fbf9dcf6a34a5e98c886b85e3ce6a238 F src/sqlite.h.in 723107d97f2345a7c103632169dc61366121c4ab65d75a7d83c6dc0e5bbe5ca4 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae @@ -1569,7 +1569,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 32be9c3faaafd736da3f49d475dc9279af4e4ba38070b60033d898345080acf0 -R f2f2293b380c103d1313beba2f4189cc +P 833ab3212addc340ca8004e8d6a06cc5e51bf256f43dc73d87fbe67518a4891b +R 5b5c15828c2f2dcb9cc85dadb80ff440 U drh -Z 533fb94c090ecb58ff1b57331e8e6d3d +Z add0f65c09d0d29a2f7424a8d8e55df8 diff --git a/manifest.uuid b/manifest.uuid index b258a1fad8..598099fcb1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -833ab3212addc340ca8004e8d6a06cc5e51bf256f43dc73d87fbe67518a4891b \ No newline at end of file +bd5bbe4eece9051cc8c27d834d22fb243d34f261641984555d02a27b7038d4f6 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 456fde5fbe..1236b12a0e 100644 --- a/src/shell.c +++ b/src/shell.c @@ -4686,7 +4686,14 @@ static int do_meta_command(char *zLine, ShellState *p){ const char *z = azArg[i]+1; if( z[0]=='-' ) z++; if( strcmp(z,"preserve-rowids")==0 ){ +#ifdef SQLITE_OMIT_VIRTUALTABLE + raw_printf(stderr, "The --preserve-rowids option is not compatible" + " with SQLITE_OMIT_VIRTUALTABLE\n"); + rc = 1; + goto meta_command_exit; +#else ShellSetFlag(p, SHFLG_PreserveRowid); +#endif }else { raw_printf(stderr, "Unknown option \"%s\" on \".dump\"\n", azArg[i]); From b9cd86a09140d6c607716dd724721d7dc5b0a218 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 25 Mar 2017 18:31:42 +0000 Subject: [PATCH 1475/1484] Do not run tests for ".dump --preserve-rowids" when testing SQLITE_OMIT_VIRTUALTABLE builds. FossilOrigin-Name: 55df410b2cd27dc4c7670bcc1196fa3a0e9e601fc24c42e53d6b0a26ee3e4b45 --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/shell1.test | 20 ++++++++++++++++++++ 3 files changed, 28 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 9626fae018..dbc499389a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Disable\sthe\snew\s--preserve-rowids\soption\son\sthe\sCLI\s".dump"\scommand\sif\ncompiled\swith\sSQLITE_OMIT_VIRTUALTABLE. -D 2017-03-25T18:15:05.701 +C Do\snot\srun\stests\sfor\s".dump\s--preserve-rowids"\swhen\stesting\nSQLITE_OMIT_VIRTUALTABLE\sbuilds. +D 2017-03-25T18:31:42.178 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1faf9f06aadc9284c212dea7bbc7c0dea7e8337f0287c81001eff500912c790a @@ -1114,7 +1114,7 @@ F test/sharedA.test 0cdf1a76dfa00e6beee66af5b534b1e8df2720f5 F test/sharedB.test 16cc7178e20965d75278f410943109b77b2e645e F test/shared_err.test 2f2aee20db294b9924e81f6ccbe60f19e21e8506 F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304 -F test/shell1.test bc1ca4161e1f459c9cd412d3f21f4ee635cf2322 +F test/shell1.test 50226a3a66bbd42a902e9f7698f768927eb33a56e9cfc55b7c157c38eb3e80ac F test/shell2.test e242a9912f44f4c23c3d1d802a83e934e84c853b F test/shell3.test 9b95ba643eaa228376f06a898fb410ee9b6e57c1 F test/shell4.test 89ad573879a745974ff2df20ff97c5d6ffffbd5d @@ -1569,7 +1569,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 833ab3212addc340ca8004e8d6a06cc5e51bf256f43dc73d87fbe67518a4891b -R 5b5c15828c2f2dcb9cc85dadb80ff440 -U drh -Z add0f65c09d0d29a2f7424a8d8e55df8 +P bd5bbe4eece9051cc8c27d834d22fb243d34f261641984555d02a27b7038d4f6 +R 3c7487a050e499b6e6904332fc259f35 +U dan +Z 8bd1e4f61c15057f31029e76e86683dd diff --git a/manifest.uuid b/manifest.uuid index 598099fcb1..7b58a3bd78 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bd5bbe4eece9051cc8c27d834d22fb243d34f261641984555d02a27b7038d4f6 \ No newline at end of file +55df410b2cd27dc4c7670bcc1196fa3a0e9e601fc24c42e53d6b0a26ee3e4b45 \ No newline at end of file diff --git a/test/shell1.test b/test/shell1.test index 7f282292c0..ac3403f810 100644 --- a/test/shell1.test +++ b/test/shell1.test @@ -755,6 +755,9 @@ INSERT INTO t3 VALUES(5,'hello'); INSERT INTO t3 VALUES(6,X'807f'); COMMIT;}} + +ifcapable vtab { + # The --preserve-rowids option to .dump # do_test shell1-4.1.1 { @@ -868,6 +871,23 @@ INSERT INTO t1 VALUES(12,'',99); INSERT INTO t1 VALUES(23,1,X'b0b1b2'); COMMIT;}} +} else { + +do_test shell1-4.1.6 { + db close + forcedelete test2.db + sqlite3 db test2.db + db eval { + CREATE TABLE t1(x INTEGER PRIMARY KEY, y); + INSERT INTO t1 VALUES(1,null), (2,''), (3,1), + (4,2.25), (5,'hello'), (6,x'807f'); + } + catchcmd test2.db {.dump --preserve-rowids} +} {1 {The --preserve-rowids option is not compatible with SQLITE_OMIT_VIRTUALTABLE}} + +} + + # Test the output of ".mode insert" # do_test shell1-4.2.1 { From 0d8d9c9effb312c71998446df64bcc133031acde Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 25 Mar 2017 19:16:41 +0000 Subject: [PATCH 1476/1484] Add the new sqlite3_set_last_insert_rowid() interface to the extension loader thunk. FossilOrigin-Name: 8469fc0d48d6af0accef9b8a84e08ad2ca32351907510d177b4ca4815c1ea7cb --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/loadext.c | 4 +++- src/sqlite3ext.h | 4 ++++ 4 files changed, 16 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index dbc499389a..65dae1b276 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Do\snot\srun\stests\sfor\s".dump\s--preserve-rowids"\swhen\stesting\nSQLITE_OMIT_VIRTUALTABLE\sbuilds. -D 2017-03-25T18:31:42.178 +C Add\sthe\snew\ssqlite3_set_last_insert_rowid()\sinterface\sto\sthe\sextension\nloader\sthunk. +D 2017-03-25T19:16:41.259 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1faf9f06aadc9284c212dea7bbc7c0dea7e8337f0287c81001eff500912c790a @@ -365,7 +365,7 @@ F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 F src/insert.c d4bb3a135948553d18cf992f76f7ed7b18aa0327f250607b5a6671e55d9947d5 F src/legacy.c e88ed13c2d531decde75d42c2e35623fb9ce3cb0 -F src/loadext.c a68d8d1d14cf7488bb29dc5311cb1ce9a4404258 +F src/loadext.c a72909474dadce771d3669bf84bf689424f6f87d471fee898589c3ef9b2acfd9 F src/main.c 158326243c5ddc8b98a1e983fa488650cf76d760 F src/malloc.c 89c98e3619d362dcffa5c1c639b364b65b474751 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 @@ -405,7 +405,7 @@ F src/select.c 2496d0cc6368dabe7ad2e4c7f5ed3ad9aa3b4d11cd90f33fa1d1ef72493f43aa F src/shell.c ceb2b2f1f958ea2c47a7f37972d0f715fbf9dcf6a34a5e98c886b85e3ce6a238 F src/sqlite.h.in 723107d97f2345a7c103632169dc61366121c4ab65d75a7d83c6dc0e5bbe5ca4 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 -F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae +F src/sqlite3ext.h 58fd0676d3111d02e62e5a35992a7d3da5d3f88753acc174f2d37b774fbbdd28 F src/sqliteInt.h a530e5baf5e559154d5c2e5cc57471bc780a7af4cd0a5d72750b1d850fef1e22 F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 @@ -1569,7 +1569,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P bd5bbe4eece9051cc8c27d834d22fb243d34f261641984555d02a27b7038d4f6 -R 3c7487a050e499b6e6904332fc259f35 -U dan -Z 8bd1e4f61c15057f31029e76e86683dd +P 55df410b2cd27dc4c7670bcc1196fa3a0e9e601fc24c42e53d6b0a26ee3e4b45 +R e1b145e92e118b2bc2de7100fb7561b5 +U drh +Z e401f4d2ca1590406e5405bb5cd2850e diff --git a/manifest.uuid b/manifest.uuid index 7b58a3bd78..6ed302dbe3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -55df410b2cd27dc4c7670bcc1196fa3a0e9e601fc24c42e53d6b0a26ee3e4b45 \ No newline at end of file +8469fc0d48d6af0accef9b8a84e08ad2ca32351907510d177b4ca4815c1ea7cb \ No newline at end of file diff --git a/src/loadext.c b/src/loadext.c index 3296be60dd..1fee4260ab 100644 --- a/src/loadext.c +++ b/src/loadext.c @@ -421,7 +421,9 @@ static const sqlite3_api_routines sqlite3Apis = { sqlite3_system_errno, /* Version 3.14.0 and later */ sqlite3_trace_v2, - sqlite3_expanded_sql + sqlite3_expanded_sql, + /* Version 3.18.0 and later */ + sqlite3_set_last_insert_rowid }; /* diff --git a/src/sqlite3ext.h b/src/sqlite3ext.h index ce87e74690..f25084a1f5 100644 --- a/src/sqlite3ext.h +++ b/src/sqlite3ext.h @@ -282,6 +282,8 @@ struct sqlite3_api_routines { /* Version 3.14.0 and later */ int (*trace_v2)(sqlite3*,unsigned,int(*)(unsigned,void*,void*,void*),void*); char *(*expanded_sql)(sqlite3_stmt*); + /* Version 3.18.0 and later */ + void (*set_last_insert_rowid)(sqlite3*,sqlite3_int64); }; /* @@ -540,6 +542,8 @@ typedef int (*sqlite3_loadext_entry)( /* Version 3.14.0 and later */ #define sqlite3_trace_v2 sqlite3_api->trace_v2 #define sqlite3_expanded_sql sqlite3_api->expanded_sql +/* Version 3.18.0 and later */ +#define sqlite3_set_last_insert_rowid sqlite3_api->set_last_insert_rowid #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) From bf96228754b6582cf7f023cadafd69580e00988d Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 29 Mar 2017 15:18:40 +0000 Subject: [PATCH 1477/1484] Fix the sqlite3_release_memory() interface so that it works even if SQLITE_DEFAULT_PCACHE_INITSZ is non-zero. FossilOrigin-Name: 5d902b7fea3144bf57f02aca87b9795fdcec4774310ade6ef01f37d206c3d74f --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/pcache1.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 65dae1b276..54f5ea0353 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\snew\ssqlite3_set_last_insert_rowid()\sinterface\sto\sthe\sextension\nloader\sthunk. -D 2017-03-25T19:16:41.259 +C Fix\sthe\ssqlite3_release_memory()\sinterface\sso\sthat\sit\sworks\seven\sif\nSQLITE_DEFAULT_PCACHE_INITSZ\sis\snon-zero. +D 2017-03-29T15:18:40.905 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1faf9f06aadc9284c212dea7bbc7c0dea7e8337f0287c81001eff500912c790a @@ -393,7 +393,7 @@ F src/pager.h f2a99646c5533ffe11afa43e9e0bea74054e4efa F src/parse.y 48b03113704ee8bd78ee6996d81de7fbee22e105 F src/pcache.c 62835bed959e2914edd26afadfecce29ece0e870 F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 -F src/pcache1.c e3967219b2a92b9edcb9324a4ba75009090d3953 +F src/pcache1.c 7eaf916c98e8201aba67a907bbd122a1e476049156e1f507b00d4fd8b730eea7 F src/pragma.c 2b244434e76c7075edbcfd9e4d634899af0944ff01183b126d4671f7407c2368 F src/pragma.h c9c763958fec92b04125571472c9500b351c5f7f F src/prepare.c b1140c3d0cf59bc85ace00ce363153041b424b7a @@ -1569,7 +1569,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 55df410b2cd27dc4c7670bcc1196fa3a0e9e601fc24c42e53d6b0a26ee3e4b45 -R e1b145e92e118b2bc2de7100fb7561b5 +P 8469fc0d48d6af0accef9b8a84e08ad2ca32351907510d177b4ca4815c1ea7cb +R 723c73ce75ba5d602a30ca6a02a92d57 U drh -Z e401f4d2ca1590406e5405bb5cd2850e +Z 0cd616785f0e67ca6b1ab11d9b71f146 diff --git a/manifest.uuid b/manifest.uuid index 6ed302dbe3..55ed560015 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8469fc0d48d6af0accef9b8a84e08ad2ca32351907510d177b4ca4815c1ea7cb \ No newline at end of file +5d902b7fea3144bf57f02aca87b9795fdcec4774310ade6ef01f37d206c3d74f \ No newline at end of file diff --git a/src/pcache1.c b/src/pcache1.c index 110d7ec656..94f7a87714 100644 --- a/src/pcache1.c +++ b/src/pcache1.c @@ -1211,7 +1211,7 @@ int sqlite3PcacheReleaseMemory(int nReq){ int nFree = 0; assert( sqlite3_mutex_notheld(pcache1.grp.mutex) ); assert( sqlite3_mutex_notheld(pcache1.mutex) ); - if( sqlite3GlobalConfig.nPage==0 ){ + if( sqlite3GlobalConfig.pPage==0 ){ PgHdr1 *p; pcache1EnterMutex(&pcache1.grp); while( (nReq<0 || nFree Date: Wed, 29 Mar 2017 16:55:23 +0000 Subject: [PATCH 1478/1484] Fix some tests in malloc5.test to account for the sqlite3_release_memory() change in the previous commit. FossilOrigin-Name: d336858dfcfb9539c43582b1443911df825f9af7146957734bc6f01c8f4d98e3 --- manifest | 14 ++++++------ manifest.uuid | 2 +- test/malloc5.test | 58 ++++++++++++++++++++++++----------------------- 3 files changed, 38 insertions(+), 36 deletions(-) diff --git a/manifest b/manifest index 54f5ea0353..fc63c25b56 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\ssqlite3_release_memory()\sinterface\sso\sthat\sit\sworks\seven\sif\nSQLITE_DEFAULT_PCACHE_INITSZ\sis\snon-zero. -D 2017-03-29T15:18:40.905 +C Fix\ssome\stests\sin\smalloc5.test\sto\saccount\sfor\sthe\ssqlite3_release_memory()\nchange\sin\sthe\sprevious\scommit. +D 2017-03-29T16:55:23.235 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1faf9f06aadc9284c212dea7bbc7c0dea7e8337f0287c81001eff500912c790a @@ -939,7 +939,7 @@ F test/make-where7.tcl 05c16b5d4f5d6512881dfec560cb793915932ef9 F test/malloc.test 21c213365f2cca95ab2d7dc078dc8525f96065f8 F test/malloc3.test e3b32c724b5a124b57cb0ed177f675249ad0c66a F test/malloc4.test 957337613002b7058a85116493a262f679f3a261 -F test/malloc5.test 192d0b5ee1d023a07d5164c34cf47d010da73da1 +F test/malloc5.test a591be066ebc6ad34adaa4b38939a037a59ebd80ad681e79dedac7b4a9e7bc09 F test/malloc6.test 2f039d9821927eacae43e1831f815e157659a151 F test/malloc7.test 7c68a32942858bc715284856c5507446bba88c3a F test/malloc8.test 9b7a3f8cb9cf0b12fff566e80a980b1767bd961d @@ -1569,7 +1569,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 8469fc0d48d6af0accef9b8a84e08ad2ca32351907510d177b4ca4815c1ea7cb -R 723c73ce75ba5d602a30ca6a02a92d57 -U drh -Z 0cd616785f0e67ca6b1ab11d9b71f146 +P 5d902b7fea3144bf57f02aca87b9795fdcec4774310ade6ef01f37d206c3d74f +R b34a64973f50dfefc35323bb58d30845 +U dan +Z 6677e2c642118fa2c5f8a791ca8e31e4 diff --git a/manifest.uuid b/manifest.uuid index 55ed560015..62f3d88fd9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5d902b7fea3144bf57f02aca87b9795fdcec4774310ade6ef01f37d206c3d74f \ No newline at end of file +d336858dfcfb9539c43582b1443911df825f9af7146957734bc6f01c8f4d98e3 \ No newline at end of file diff --git a/test/malloc5.test b/test/malloc5.test index 8114005e8b..e529874b51 100644 --- a/test/malloc5.test +++ b/test/malloc5.test @@ -39,11 +39,27 @@ ifcapable !memorymanage { return } +# The sizes of memory allocations from system malloc() might vary, +# depending on the memory allocator algorithms used. The following +# routine is designed to support answers that fall within a range +# of values while also supplying easy-to-understand "expected" values +# when errors occur. +# +proc value_in_range {target x args} { + set v [lindex $args 0] + if {$v!=""} { + if {$v<$target*$x} {return $v} + if {$v>$target/$x} {return $v} + } + return "number between [expr {int($target*$x)}] and [expr {int($target/$x)}]" +} +set mrange 0.98 ;# plus or minus 2% + test_set_config_pagecache 0 100 sqlite3_soft_heap_limit 0 sqlite3 db test.db -db eval {PRAGMA cache_size=1} +# db eval {PRAGMA cache_size=1} do_test malloc5-1.1 { # Simplest possible test. Call sqlite3_release_memory when there is exactly @@ -71,24 +87,8 @@ do_test malloc5-1.3 { # in the cache belonging to db2. # set ::pgalloc [sqlite3_release_memory] -} {0} - -# The sizes of memory allocations from system malloc() might vary, -# depending on the memory allocator algorithms used. The following -# routine is designed to support answers that fall within a range -# of values while also supplying easy-to-understand "expected" values -# when errors occur. -# -proc value_in_range {target x args} { - set v [lindex $args 0] - if {$v!=""} { - if {$v<$target*$x} {return $v} - if {$v>$target/$x} {return $v} - } - return "number between [expr {int($target*$x)}] and [expr {int($target/$x)}]" -} -set mrange 0.98 ;# plus or minus 2% - + value_in_range 1288 0.75 +} [value_in_range 1288 0.75] do_test malloc5-1.4 { # Commit the transaction and open a new one. Read 1 page into the cache. @@ -117,12 +117,12 @@ do_test malloc5-1.6 { db2 close execsql { BEGIN; - SELECT * FROM abc; CREATE TABLE def(d, e, f); + SELECT * FROM abc; } + breakpoint value_in_range $::pgalloc $::mrange [sqlite3_release_memory 500] } [value_in_range $::pgalloc $::mrange] - do_test malloc5-1.7 { # Database should not be locked this time. sqlite3 db2 test.db @@ -346,7 +346,7 @@ do_test malloc5-6.2.2 { # If we now try to reclaim some memory, it should come from the db2 cache. sqlite3_release_memory 3000 expr [nPage db] + [nPage db2] -} {4} +} {1} do_test malloc5-6.2.3 { # Access the db2 cache again, so that all the db2 pages have been used # more recently than all the db pages. Then try to reclaim 3000 bytes. @@ -354,7 +354,7 @@ do_test malloc5-6.2.3 { execsql { SELECT * FROM abc } db2 sqlite3_release_memory 3000 expr [nPage db] + [nPage db2] -} {4} +} {0} do_test malloc5-6.3.1 { # Now open a transaction and update 2 pages in the db2 cache. Then @@ -364,6 +364,8 @@ do_test malloc5-6.3.1 { # sync() to free up the dirty db2 pages. The only page that cannot be # freed is page1 of db2. Because there is an open transaction, the # btree layer holds a reference to page 1 in the db2 cache. + # + # UPDATE: No longer. As release_memory() does not cause a sync() execsql { BEGIN; UPDATE abc SET c = randstr(100,100) @@ -377,13 +379,13 @@ do_test malloc5-6.3.2 { # non-dirty pages held by db2. sqlite3_release_memory [expr 7*1132] list [nPage db] [nPage db2] -} {1 3} +} {0 3} do_test malloc5-6.3.3 { # Try to release another 1000 bytes. This should come fromt the db # cache, since all three pages held by db2 are either in-use or diry. sqlite3_release_memory 1000 list [nPage db] [nPage db2] -} {1 3} +} {0 3} do_test malloc5-6.3.4 { # Now release 9900 more (about 9 pages worth). This should expunge # the rest of the db cache. But the db2 cache remains intact, because @@ -394,20 +396,20 @@ do_test malloc5-6.3.4 { sqlite3_release_memory 9900 } list [nPage db] [nPage db2] -} {1 3} +} {0 3} do_test malloc5-6.3.5 { # But if we are really insistent, SQLite will consent to call sync() # if there is no other option. UPDATE: As of 3.6.2, SQLite will not # call sync() in this scenario. So no further memory can be reclaimed. sqlite3_release_memory 1000 list [nPage db] [nPage db2] -} {1 3} +} {0 3} do_test malloc5-6.3.6 { # The referenced page (page 1 of the db2 cache) will not be freed no # matter how much memory we ask for: sqlite3_release_memory 31459 list [nPage db] [nPage db2] -} {1 3} +} {0 3} db2 close From 4eb8d7fa891a8d9379726e5b798a9f4a7b2dcf16 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 29 Mar 2017 17:06:14 +0000 Subject: [PATCH 1479/1484] Slightly smaller and faster implementation of pcache1InitBulk(). FossilOrigin-Name: 06c2b685e15b3ee045a3e7ea018701392771c7664e59a51c9aba87cdefeb37af --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/pcache1.c | 5 ++--- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index fc63c25b56..a96fd8a952 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\ssome\stests\sin\smalloc5.test\sto\saccount\sfor\sthe\ssqlite3_release_memory()\nchange\sin\sthe\sprevious\scommit. -D 2017-03-29T16:55:23.235 +C Slightly\ssmaller\sand\sfaster\simplementation\sof\spcache1InitBulk(). +D 2017-03-29T17:06:14.960 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1faf9f06aadc9284c212dea7bbc7c0dea7e8337f0287c81001eff500912c790a @@ -393,7 +393,7 @@ F src/pager.h f2a99646c5533ffe11afa43e9e0bea74054e4efa F src/parse.y 48b03113704ee8bd78ee6996d81de7fbee22e105 F src/pcache.c 62835bed959e2914edd26afadfecce29ece0e870 F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 -F src/pcache1.c 7eaf916c98e8201aba67a907bbd122a1e476049156e1f507b00d4fd8b730eea7 +F src/pcache1.c 1195a21fe28e223e024f900b2011e80df53793f0356a24caace4188b098540dc F src/pragma.c 2b244434e76c7075edbcfd9e4d634899af0944ff01183b126d4671f7407c2368 F src/pragma.h c9c763958fec92b04125571472c9500b351c5f7f F src/prepare.c b1140c3d0cf59bc85ace00ce363153041b424b7a @@ -1569,7 +1569,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 5d902b7fea3144bf57f02aca87b9795fdcec4774310ade6ef01f37d206c3d74f -R b34a64973f50dfefc35323bb58d30845 -U dan -Z 6677e2c642118fa2c5f8a791ca8e31e4 +P d336858dfcfb9539c43582b1443911df825f9af7146957734bc6f01c8f4d98e3 +R 21af04338e0846af1da53b948e484a63 +U drh +Z 526769a24dc035fa5d0eca71a01d1d0b diff --git a/manifest.uuid b/manifest.uuid index 62f3d88fd9..ffd1193763 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d336858dfcfb9539c43582b1443911df825f9af7146957734bc6f01c8f4d98e3 \ No newline at end of file +06c2b685e15b3ee045a3e7ea018701392771c7664e59a51c9aba87cdefeb37af \ No newline at end of file diff --git a/src/pcache1.c b/src/pcache1.c index 94f7a87714..fa0c6a79f2 100644 --- a/src/pcache1.c +++ b/src/pcache1.c @@ -285,8 +285,7 @@ static int pcache1InitBulk(PCache1 *pCache){ sqlite3EndBenignMalloc(); if( zBulk ){ int nBulk = sqlite3MallocSize(zBulk)/pCache->szAlloc; - int i; - for(i=0; iszPage]; pX->page.pBuf = zBulk; pX->page.pExtra = &pX[1]; @@ -295,7 +294,7 @@ static int pcache1InitBulk(PCache1 *pCache){ pX->pNext = pCache->pFree; pCache->pFree = pX; zBulk += pCache->szAlloc; - } + }while( --nBulk ); } return pCache->pFree!=0; } From 9ca431aef8ed0f6a231ae7badc6ddedfad9e0374 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 29 Mar 2017 18:03:50 +0000 Subject: [PATCH 1480/1484] Avoid unnecessary blob handle invalidation when changes are made to an unrelated table. FossilOrigin-Name: 4a01880b62706c12d6f16f7c2b5c8b0dc67a9a8a0a48c5b42451e1a133e85611 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btree.c | 11 ++++++----- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index a96fd8a952..64c572f805 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Slightly\ssmaller\sand\sfaster\simplementation\sof\spcache1InitBulk(). -D 2017-03-29T17:06:14.960 +C Avoid\sunnecessary\sblob\shandle\sinvalidation\swhen\schanges\sare\smade\sto\san\nunrelated\stable. +D 2017-03-29T18:03:50.123 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1faf9f06aadc9284c212dea7bbc7c0dea7e8337f0287c81001eff500912c790a @@ -344,7 +344,7 @@ F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792 F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca -F src/btree.c ae0e0397e6ad58465bbf932239ee7539ca22f257c97b16c9d0960a1f5de743a3 +F src/btree.c 64ff65a01851a34c8145e5bc767df9e57d2f3c1acdc6aba334794b7c40c684e6 F src/btree.h bf64dfeeddeebdb775a5eba0098bbc00d073290d F src/btreeInt.h cd55d39d9916270837a88c12e701047cba0729b0 F src/build.c 43f903c9082040ced2b421543cb0300c2973647d @@ -1569,7 +1569,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d336858dfcfb9539c43582b1443911df825f9af7146957734bc6f01c8f4d98e3 -R 21af04338e0846af1da53b948e484a63 +P 06c2b685e15b3ee045a3e7ea018701392771c7664e59a51c9aba87cdefeb37af +R 00d70d109b5d75b80d2e30f02fdc5c97 U drh -Z 526769a24dc035fa5d0eca71a01d1d0b +Z db6af2895adafefdbb1e0ee439bd7656 diff --git a/manifest.uuid b/manifest.uuid index ffd1193763..29922069fb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -06c2b685e15b3ee045a3e7ea018701392771c7664e59a51c9aba87cdefeb37af \ No newline at end of file +4a01880b62706c12d6f16f7c2b5c8b0dc67a9a8a0a48c5b42451e1a133e85611 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 52c0c47dd5..aecf06e63f 100644 --- a/src/btree.c +++ b/src/btree.c @@ -499,6 +499,7 @@ static void invalidateAllOverflowCache(BtShared *pBt){ */ static void invalidateIncrblobCursors( Btree *pBtree, /* The database file to check */ + Pgno pgnoRoot, /* The table that might be changing */ i64 iRow, /* The rowid that might be changing */ int isClearTable /* True if all rows are being deleted */ ){ @@ -509,7 +510,7 @@ static void invalidateIncrblobCursors( for(p=pBtree->pBt->pCursor; p; p=p->pNext){ if( (p->curFlags & BTCF_Incrblob)!=0 ){ pBtree->hasIncrblobCur = 1; - if( isClearTable || p->info.nKey==iRow ){ + if( p->pgnoRoot==pgnoRoot && (isClearTable || p->info.nKey==iRow) ){ p->eState = CURSOR_INVALID; } } @@ -518,7 +519,7 @@ static void invalidateIncrblobCursors( #else /* Stub function when INCRBLOB is omitted */ - #define invalidateIncrblobCursors(x,y,z) + #define invalidateIncrblobCursors(w,x,y,z) #endif /* SQLITE_OMIT_INCRBLOB */ /* @@ -8110,7 +8111,7 @@ int sqlite3BtreeInsert( assert( pX->pKey==0 ); /* If this is an insert into a table b-tree, invalidate any incrblob ** cursors open on the row being replaced */ - invalidateIncrblobCursors(p, pX->nKey, 0); + invalidateIncrblobCursors(p, pCur->pgnoRoot, pX->nKey, 0); /* If BTREE_SAVEPOSITION is set, the cursor must already be pointing ** to a row with the same key as the new entry being inserted. */ @@ -8340,7 +8341,7 @@ int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){ /* If this is a delete operation to remove a row from a table b-tree, ** invalidate any incrblob cursors open on the row being deleted. */ if( pCur->pKeyInfo==0 ){ - invalidateIncrblobCursors(p, pCur->info.nKey, 0); + invalidateIncrblobCursors(p, pCur->pgnoRoot, pCur->info.nKey, 0); } /* Make the page containing the entry to be deleted writable. Then free any @@ -8667,7 +8668,7 @@ int sqlite3BtreeClearTable(Btree *p, int iTable, int *pnChange){ /* Invalidate all incrblob cursors open on table iTable (assuming iTable ** is the root of a table b-tree - if it is not, the following call is ** a no-op). */ - invalidateIncrblobCursors(p, 0, 1); + invalidateIncrblobCursors(p, (Pgno)iTable, 0, 1); rc = clearDatabasePage(pBt, (Pgno)iTable, 0, pnChange); } sqlite3BtreeLeave(p); From b3d3bea31d9d4d14b48982e550729255f2b379eb Mon Sep 17 00:00:00 2001 From: mistachkin Date: Wed, 29 Mar 2017 23:22:18 +0000 Subject: [PATCH 1481/1484] When compiling with MSVC, disable extra SELECT/WHERE tracing for dynamically built shells. FossilOrigin-Name: a68919425c528b887e66b588a73a619f0506cb06855350e0ec8f844acf64d8f7 --- Makefile.msc | 5 ++++- autoconf/Makefile.msc | 5 ++++- manifest | 16 ++++++++-------- manifest.uuid | 2 +- 4 files changed, 17 insertions(+), 11 deletions(-) diff --git a/Makefile.msc b/Makefile.msc index 1dfc6bc49d..7e700afea2 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -745,8 +745,11 @@ RCC = $(RCC) -DSQLITE_ENABLE_API_ARMOR=1 !IF $(DEBUG)>2 TCC = $(TCC) -DSQLITE_DEBUG=1 -TCC = $(TCC) -DSQLITE_ENABLE_WHERETRACE -DSQLITE_ENABLE_SELECTTRACE RCC = $(RCC) -DSQLITE_DEBUG=1 +!IF $(DYNAMIC_SHELL)==0 +TCC = $(TCC) -DSQLITE_ENABLE_WHERETRACE -DSQLITE_ENABLE_SELECTTRACE +RCC = $(RCC) -DSQLITE_ENABLE_WHERETRACE -DSQLITE_ENABLE_SELECTTRACE +!ENDIF !ENDIF !IF $(DEBUG)>4 || $(OSTRACE)!=0 diff --git a/autoconf/Makefile.msc b/autoconf/Makefile.msc index 8c13778fc8..ad88504be8 100644 --- a/autoconf/Makefile.msc +++ b/autoconf/Makefile.msc @@ -644,8 +644,11 @@ RCC = $(RCC) -DSQLITE_ENABLE_API_ARMOR=1 !IF $(DEBUG)>2 TCC = $(TCC) -DSQLITE_DEBUG=1 -TCC = $(TCC) -DSQLITE_ENABLE_WHERETRACE -DSQLITE_ENABLE_SELECTTRACE RCC = $(RCC) -DSQLITE_DEBUG=1 +!IF $(DYNAMIC_SHELL)==0 +TCC = $(TCC) -DSQLITE_ENABLE_WHERETRACE -DSQLITE_ENABLE_SELECTTRACE +RCC = $(RCC) -DSQLITE_ENABLE_WHERETRACE -DSQLITE_ENABLE_SELECTTRACE +!ENDIF !ENDIF !IF $(DEBUG)>4 || $(OSTRACE)!=0 diff --git a/manifest b/manifest index 64c572f805..8bf3b9e785 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -C Avoid\sunnecessary\sblob\shandle\sinvalidation\swhen\schanges\sare\smade\sto\san\nunrelated\stable. -D 2017-03-29T18:03:50.123 +C When\scompiling\swith\sMSVC,\sdisable\sextra\sSELECT/WHERE\stracing\sfor\sdynamically\sbuilt\sshells. +D 2017-03-29T23:22:18.563 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 -F Makefile.msc 1faf9f06aadc9284c212dea7bbc7c0dea7e8337f0287c81001eff500912c790a +F Makefile.msc a4c0613a18663bda56d8cf76079ab6590a7c3602e54befb4bbdef76bcaa38b6a F README.md 2b15fae33852f2f53996774c21fb41e1d94181c4401a0e43ac93e11f2cc901b9 F VERSION 3605fa447e4623f5ff4a6adc97b1fde9a257b8f2 F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 @@ -11,7 +11,7 @@ F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am 1a47d071e3d5435f8f7ebff7eb6703848bbd65d4 -F autoconf/Makefile.msc 92e3d7fd64dc5c23a23d33824ee4709aaea00a6331c4bb41a1aadcf6600a49f7 +F autoconf/Makefile.msc 1fba0d762d115509d4fce7e333305cee172d521aaacec8bbf7aad5503605d3fb F autoconf/README.first 6c4f34fe115ff55d4e8dbfa3cecf04a0188292f7 F autoconf/README.txt 4f04b0819303aabaa35fff5f7b257fb0c1ef95f1 F autoconf/configure.ac 2893b823ecc86cea13739f6c8109a41392254d1db08235c5615e0af5722c8578 @@ -1569,7 +1569,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 06c2b685e15b3ee045a3e7ea018701392771c7664e59a51c9aba87cdefeb37af -R 00d70d109b5d75b80d2e30f02fdc5c97 -U drh -Z db6af2895adafefdbb1e0ee439bd7656 +P 4a01880b62706c12d6f16f7c2b5c8b0dc67a9a8a0a48c5b42451e1a133e85611 +R 3adffbd2ee409684adfb0dddf60b32b6 +U mistachkin +Z 8f5b8ec1599d13d0314f838adb184b49 diff --git a/manifest.uuid b/manifest.uuid index 29922069fb..f2f9b29f93 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4a01880b62706c12d6f16f7c2b5c8b0dc67a9a8a0a48c5b42451e1a133e85611 \ No newline at end of file +a68919425c528b887e66b588a73a619f0506cb06855350e0ec8f844acf64d8f7 \ No newline at end of file From ecc0f84d0883731c72226f5c7bbb407f745a8911 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 30 Mar 2017 16:37:05 +0000 Subject: [PATCH 1482/1484] Ensure that the stack space used to hold the Lemon-generated parser object is always 8-byte aligned. FossilOrigin-Name: 1279de0b70cabf39899d92ece8852a780fd800bf3154971537b3427e5bd3ca50 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/tokenize.c | 3 ++- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 8bf3b9e785..46218e908b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C When\scompiling\swith\sMSVC,\sdisable\sextra\sSELECT/WHERE\stracing\sfor\sdynamically\sbuilt\sshells. -D 2017-03-29T23:22:18.563 +C Ensure\sthat\sthe\sstack\sspace\sused\sto\shold\sthe\sLemon-generated\sparser\sobject\nis\salways\s8-byte\saligned. +D 2017-03-30T16:37:05.021 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a4c0613a18663bda56d8cf76079ab6590a7c3602e54befb4bbdef76bcaa38b6a @@ -461,7 +461,7 @@ F src/test_windirent.c 17f91f5f2aa1bb7328abb49414c363b5d2a9d3ff F src/test_windirent.h 5d67483a55442e31e1bde0f4a230e6e932ad5906 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c -F src/tokenize.c dc748c5afcb9e5beb3ef5651bc99a4622e30f6a1 +F src/tokenize.c d62a8f879807d100e681a039778ca1bcb018b6a0fc3c1b4173549ee61ee4b5cf F src/treeview.c 84d0ac737e1231702679f0289180021e19c5cc186ec413e8dcb704a887c76ec8 F src/trigger.c c9f0810043b265724fdb1bdd466894f984dfc182 F src/update.c 456d4a4656f8a03c2abc88a51b19172197400e58 @@ -1569,7 +1569,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 4a01880b62706c12d6f16f7c2b5c8b0dc67a9a8a0a48c5b42451e1a133e85611 -R 3adffbd2ee409684adfb0dddf60b32b6 -U mistachkin -Z 8f5b8ec1599d13d0314f838adb184b49 +P a68919425c528b887e66b588a73a619f0506cb06855350e0ec8f844acf64d8f7 +R 82cf7572a7c54f3566dc03bfc0762992 +U drh +Z a2cdaa19784e815fd6dc9c68b48174fe diff --git a/manifest.uuid b/manifest.uuid index f2f9b29f93..cf9b333b31 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a68919425c528b887e66b588a73a619f0506cb06855350e0ec8f844acf64d8f7 \ No newline at end of file +1279de0b70cabf39899d92ece8852a780fd800bf3154971537b3427e5bd3ca50 \ No newline at end of file diff --git a/src/tokenize.c b/src/tokenize.c index 578ddc4f00..60df70c3c4 100644 --- a/src/tokenize.c +++ b/src/tokenize.c @@ -482,7 +482,8 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){ sqlite3 *db = pParse->db; /* The database connection */ int mxSqlLen; /* Max length of an SQL string */ #ifdef sqlite3Parser_ENGINEALWAYSONSTACK - unsigned char zSpace[sizeof(yyParser)]; /* Space for parser engine object */ + /* Space to hold the Lemon-generated Parser object */ + sqlite3_uint64 zSpace[(sizeof(yyParser)+7)/sizeof(sqlite_uint64)]; #endif assert( zSql!=0 ); From 52105783fd164c7c982351a5ce71c4e44ca8305e Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 30 Mar 2017 16:51:35 +0000 Subject: [PATCH 1483/1484] Increase the version number for the next development cycle. FossilOrigin-Name: 9e550ccc29f317422dae3a4bb89a78b839330825fecd40a01d1a2acc719cef79 --- VERSION | 2 +- configure | 18 +++++++++--------- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/VERSION b/VERSION index c5b45eb7b1..419f300965 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.18.0 +3.19.0 diff --git a/configure b/configure index 628e23f2d0..84422d3343 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.18.0. +# Generated by GNU Autoconf 2.69 for sqlite 3.19.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.18.0' -PACKAGE_STRING='sqlite 3.18.0' +PACKAGE_VERSION='3.19.0' +PACKAGE_STRING='sqlite 3.19.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.18.0 to adapt to many kinds of systems. +\`configure' configures sqlite 3.19.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.18.0:";; + short | recursive ) echo "Configuration of sqlite 3.19.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.18.0 +sqlite configure 3.19.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.18.0, which was +It was created by sqlite $as_me 3.19.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.18.0, which was +This file was extended by sqlite $as_me 3.19.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.18.0 +sqlite config.status 3.19.0 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/manifest b/manifest index 46218e908b..a6d06256d5 100644 --- a/manifest +++ b/manifest @@ -1,10 +1,10 @@ -C Ensure\sthat\sthe\sstack\sspace\sused\sto\shold\sthe\sLemon-generated\sparser\sobject\nis\salways\s8-byte\saligned. -D 2017-03-30T16:37:05.021 +C Increase\sthe\sversion\snumber\sfor\sthe\snext\sdevelopment\scycle. +D 2017-03-30T16:51:35.655 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a4c0613a18663bda56d8cf76079ab6590a7c3602e54befb4bbdef76bcaa38b6a F README.md 2b15fae33852f2f53996774c21fb41e1d94181c4401a0e43ac93e11f2cc901b9 -F VERSION 3605fa447e4623f5ff4a6adc97b1fde9a257b8f2 +F VERSION 0a0e02e16b44ea735b40118fc844311b2ab0d35b25fbeda5120aee62f973f663 F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 @@ -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 b15d030a8ae2e672d76c97b6667dacb98934a467 x +F configure cea63449647267beb335e899fd8a79778912ffa55d6b179730267b8ef84aa1aa x F configure.ac 605173e829ab64514ed89f9b53d0da1739d7b0a0 F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad F doc/lemon.html b5a3c07d33ecb8e019ce8f7660fe2dbbad9d7977 @@ -1569,7 +1569,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a68919425c528b887e66b588a73a619f0506cb06855350e0ec8f844acf64d8f7 -R 82cf7572a7c54f3566dc03bfc0762992 +P 1279de0b70cabf39899d92ece8852a780fd800bf3154971537b3427e5bd3ca50 +R 8c59842ddd3a3383c068f53bcfd4477a U drh -Z a2cdaa19784e815fd6dc9c68b48174fe +Z 6ac757072538aac0ef24b8822be39d2a diff --git a/manifest.uuid b/manifest.uuid index cf9b333b31..4c50a4ed46 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1279de0b70cabf39899d92ece8852a780fd800bf3154971537b3427e5bd3ca50 \ No newline at end of file +9e550ccc29f317422dae3a4bb89a78b839330825fecd40a01d1a2acc719cef79 \ No newline at end of file From 53b2459a364e312d2501f4cc366a710c52e340a3 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 30 Mar 2017 17:13:37 +0000 Subject: [PATCH 1484/1484] Declare the Lemon-generated parser object as itself. (Duh) FossilOrigin-Name: c8000e94cca59dabf83d6cb75b40441aaf793d29880582dc4baa17246449b5fe --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/tokenize.c | 5 ++--- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index a6d06256d5..eee647a65b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Increase\sthe\sversion\snumber\sfor\sthe\snext\sdevelopment\scycle. -D 2017-03-30T16:51:35.655 +C Declare\sthe\sLemon-generated\sparser\sobject\sas\sitself.\s\s(Duh) +D 2017-03-30T17:13:37.978 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a4c0613a18663bda56d8cf76079ab6590a7c3602e54befb4bbdef76bcaa38b6a @@ -461,7 +461,7 @@ F src/test_windirent.c 17f91f5f2aa1bb7328abb49414c363b5d2a9d3ff F src/test_windirent.h 5d67483a55442e31e1bde0f4a230e6e932ad5906 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c -F src/tokenize.c d62a8f879807d100e681a039778ca1bcb018b6a0fc3c1b4173549ee61ee4b5cf +F src/tokenize.c de2ec4fed5aa9770791be7528a08597a77a36b2ffbbeb0c2cb6951e80357730b F src/treeview.c 84d0ac737e1231702679f0289180021e19c5cc186ec413e8dcb704a887c76ec8 F src/trigger.c c9f0810043b265724fdb1bdd466894f984dfc182 F src/update.c 456d4a4656f8a03c2abc88a51b19172197400e58 @@ -1569,7 +1569,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 1279de0b70cabf39899d92ece8852a780fd800bf3154971537b3427e5bd3ca50 -R 8c59842ddd3a3383c068f53bcfd4477a +P 9e550ccc29f317422dae3a4bb89a78b839330825fecd40a01d1a2acc719cef79 +R 288166ae6bc74f6b9a15fa169ea78182 U drh -Z 6ac757072538aac0ef24b8822be39d2a +Z 81f3770fca5082b63e34ff795f3d141f diff --git a/manifest.uuid b/manifest.uuid index 4c50a4ed46..5037f50129 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9e550ccc29f317422dae3a4bb89a78b839330825fecd40a01d1a2acc719cef79 \ No newline at end of file +c8000e94cca59dabf83d6cb75b40441aaf793d29880582dc4baa17246449b5fe \ No newline at end of file diff --git a/src/tokenize.c b/src/tokenize.c index 60df70c3c4..7f5f298987 100644 --- a/src/tokenize.c +++ b/src/tokenize.c @@ -482,8 +482,7 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){ sqlite3 *db = pParse->db; /* The database connection */ int mxSqlLen; /* Max length of an SQL string */ #ifdef sqlite3Parser_ENGINEALWAYSONSTACK - /* Space to hold the Lemon-generated Parser object */ - sqlite3_uint64 zSpace[(sizeof(yyParser)+7)/sizeof(sqlite_uint64)]; + yyParser sEngine; /* Space to hold the Lemon-generated Parser object */ #endif assert( zSql!=0 ); @@ -496,7 +495,7 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){ assert( pzErrMsg!=0 ); /* sqlite3ParserTrace(stdout, "parser: "); */ #ifdef sqlite3Parser_ENGINEALWAYSONSTACK - pEngine = zSpace; + pEngine = &sEngine; sqlite3ParserInit(pEngine); #else pEngine = sqlite3ParserAlloc(sqlite3Malloc);